diff --git a/Framework/API/src/IMDWorkspace.cpp b/Framework/API/src/IMDWorkspace.cpp index 944da88b66a6a7468da5d5db654e988bfeb5565e..3adef955ad3a01989ffe7bb14f0328aee87aa0f7 100644 --- a/Framework/API/src/IMDWorkspace.cpp +++ b/Framework/API/src/IMDWorkspace.cpp @@ -1,6 +1,7 @@ #include "MantidAPI/IMDWorkspace.h" #include "MantidKernel/Exception.h" #include "MantidKernel/IPropertyManager.h" +#include "MantidKernel/ConfigService.h" #include "MantidKernel/VMD.h" #include <sstream> @@ -88,6 +89,14 @@ const std::string IMDWorkspace::toString() const { os << "Binned from '" << getOriginalWorkspace()->getName(); } os << "\n"; + std::string convention = + Kernel::ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + os << "Crystallography: ki-kf"; + else + os << "Inelastic: kf-ki"; + os << "\n"; + return os.str(); } diff --git a/Framework/API/src/MDGeometry.cpp b/Framework/API/src/MDGeometry.cpp index 00a8f284dfd1a9215d4929e98df18b7c170a9dfb..fac8f0cfd003edbfdf987cedc80e349f40b42de3 100644 --- a/Framework/API/src/MDGeometry.cpp +++ b/Framework/API/src/MDGeometry.cpp @@ -379,7 +379,10 @@ void MDGeometry::transformDimensions(std::vector<double> &scaling, static_cast<coord_t>(offset[d]); coord_t max = (dim->getMaximum() * static_cast<coord_t>(scaling[d])) + static_cast<coord_t>(offset[d]); - dim->setRange(dim->getNBins(), min, max); + if (min < max) + dim->setRange(dim->getNBins(), min, max); + else + dim->setRange(dim->getNBins(), max, min); } // Clear the original workspace setOriginalWorkspace(boost::shared_ptr<Workspace>()); diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h index 1ecb3c3c954cc50d4c6bdf35e63a4a2d53148943..4ea4de97af84216aba5933991197e191cddabec1 100644 --- a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h +++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h @@ -59,7 +59,7 @@ private: /// Read a single peak from peaks file DataObjects::Peak readPeak(DataObjects::PeaksWorkspace_sptr outWS, std::string &lastStr, std::ifstream &in, - int &seqNum, std::string bankName); + int &seqNum, std::string bankName, double qSign); int findPixelID(Geometry::Instrument_const_sptr inst, std::string bankName, int col, int row); diff --git a/Framework/Crystal/src/LoadHKL.cpp b/Framework/Crystal/src/LoadHKL.cpp index f58e8609a8352212dd4accaea248ea35c4c30f5e..c9ecad34a84444ce09a81b78702b2e336cb68a02 100644 --- a/Framework/Crystal/src/LoadHKL.cpp +++ b/Framework/Crystal/src/LoadHKL.cpp @@ -33,9 +33,11 @@ LoadHKL::~LoadHKL() {} /** Initialize the algorithm's properties. */ void LoadHKL::init() { - declareProperty( - new FileProperty("Filename", "", FileProperty::Load, {".hkl"}), - "Path to an hkl file to save."); + std::vector<std::string> exts; + exts.push_back(".hkl"); + + declareProperty(new FileProperty("Filename", "", FileProperty::Load, exts), + "Path to an hkl file to save."); declareProperty(new WorkspaceProperty<PeaksWorkspace>("OutputWorkspace", "", Direction::Output), @@ -58,6 +60,11 @@ void LoadHKL::exec() { // % (H, K, L, FSQ, SIGFSQ, hstnum, WL, TBAR, CURHST, SEQNUM, TRANSMISSION, // DN, TWOTH, DSP)) // HKL is flipped by -1 due to different q convention in ISAW vs mantid. + // Default for kf-ki has -q + double qSign = -1.0; + std::string convention = ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + qSign = 1.0; Instrument_sptr inst(new Geometry::Instrument); Detector *detector = new Detector("det1", -1, 0); detector->setPos(0.0, 0.0, 0.0); @@ -105,7 +112,7 @@ void LoadHKL::exec() { } Peak peak(inst, scattering, wl); - peak.setHKL(-h, -k, -l); + peak.setHKL(qSign * h, qSign * k, qSign * l); peak.setIntensity(Inti); peak.setSigmaIntensity(SigI); peak.setRunNumber(run); diff --git a/Framework/Crystal/src/LoadIsawPeaks.cpp b/Framework/Crystal/src/LoadIsawPeaks.cpp index 839acbadf6f0ee3e9d089e73f28288a94b3d9e69..ddcf35096274e9757bf48135e28545dd11c420eb 100644 --- a/Framework/Crystal/src/LoadIsawPeaks.cpp +++ b/Framework/Crystal/src/LoadIsawPeaks.cpp @@ -328,12 +328,13 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS, * @param in :: input stream * @param seqNum [out] :: the sequence number of the peak * @param bankName :: the bank number from the ISAW file. + * @param qSign :: For inelastic this is 1; for crystallography this is -1 * @return the Peak the Peak object created */ DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS, std::string &lastStr, std::ifstream &in, int &seqNum, - std::string bankName) { + std::string bankName, double qSign) { double h; double k; double l; @@ -406,8 +407,7 @@ DataObjects::Peak LoadIsawPeaks::readPeak(PeaksWorkspace_sptr outWS, // Create the peak object Peak peak(outWS->getInstrument(), pixelID, wl); - // HKL's are flipped by -1 because of the internal Q convention - peak.setHKL(-h, -k, -l); + peak.setHKL(qSign * h, qSign * k, qSign * l); peak.setIntensity(Inti); peak.setSigmaIntensity(SigI); peak.setBinCount(IPK); @@ -504,7 +504,12 @@ std::string LoadIsawPeaks::readPeakBlockHeader(std::string lastStr, */ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS, std::string filename) { - + // HKL's are flipped by -1 because of the internal Q convention + // unless Crystallography convention + double qSign = -1.0; + std::string convention = ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + qSign = 1.0; // Open the file std::ifstream in(filename.c_str()); @@ -564,7 +569,7 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS, try { // Read the peak - Peak peak = readPeak(outWS, s, in, seqNum, bankName); + Peak peak = readPeak(outWS, s, in, seqNum, bankName, qSign); // Get the calculated goniometer matrix Matrix<double> gonMat = uniGonio.getR(); diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp index 35cc554271270b77ebae900db3d65a08523513bf..51eddf20ef8f46a5f2c725650ffaff4fb95e8b3e 100644 --- a/Framework/Crystal/src/SaveHKL.cpp +++ b/Framework/Crystal/src/SaveHKL.cpp @@ -126,6 +126,12 @@ void SaveHKL::exec() { int runSequence = 0; int bankold = -1; int runold = -1; + // HKL is flipped by -1 due to different q convention in ISAW vs mantid. + // Default for kf-ki has -q + double qSign = -1.0; + std::string convention = ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + qSign = 1.0; std::fstream out; bool append = getProperty("AppendFile"); @@ -308,14 +314,14 @@ void SaveHKL::exec() { // hklFile.write('%4d%4d%4d%8.2f%8.2f%4d%8.4f%7.4f%7d%7d%7.4f%4d%9.5f%9.4f\n' // % (H, K, L, FSQ, SIGFSQ, hstnum, WL, TBAR, CURHST, SEQNUM, // TRANSMISSION, DN, TWOTH, DSP)) - // HKL is flipped by -1 due to different q convention in ISAW vs mantid. if (p.getH() == 0 && p.getK() == 0 && p.getL() == 0) { banned.push_back(wi); continue; } if (decimalHKL == EMPTY_INT()) - out << std::setw(4) << Utils::round(-p.getH()) << std::setw(4) - << Utils::round(-p.getK()) << std::setw(4) << Utils::round(-p.getL()); + out << std::setw(4) << Utils::round(qSign * p.getH()) << std::setw(4) + << Utils::round(qSign * p.getK()) << std::setw(4) + << Utils::round(qSign * p.getL()); else out << std::setw(5 + decimalHKL) << std::fixed << std::setprecision(decimalHKL) << -p.getH() diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp index 957dc07f27a19753b15793e2b95d5de093d26ad0..9e09c3d107db26065eb205ba7a74f493665f4ce0 100644 --- a/Framework/Crystal/src/SaveIsawPeaks.cpp +++ b/Framework/Crystal/src/SaveIsawPeaks.cpp @@ -247,7 +247,12 @@ void SaveIsawPeaks::exec() { } } } - + // HKL's are flipped by -1 because of the internal Q convention + // unless Crystallography convention + double qSign = -1.0; + std::string convention = ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + qSign = 1.0; // ============================== Save all Peaks // ========================================= // Sequence number @@ -305,11 +310,11 @@ void SaveIsawPeaks::exec() { // Sequence (run) number out << "3" << std::setw(7) << seqNum; - // HKL is flipped by -1 due to different q convention in ISAW vs - // mantid. - out << std::setw(5) << Utils::round(-p.getH()) << std::setw(5) - << Utils::round(-p.getK()) << std::setw(5) - << Utils::round(-p.getL()); + // HKL's are flipped by -1 because of the internal Q convention + // unless Crystallography convention + out << std::setw(5) << Utils::round(qSign * p.getH()) << std::setw(5) + << Utils::round(qSign * p.getK()) << std::setw(5) + << Utils::round(qSign * p.getL()); // Row/column out << std::setw(8) << std::fixed << std::setprecision(2) diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp index 339c05f661de42f35bec75af98fde98ee01a4000..e74a2a5ea9313eeedd88f78e8cccabb1533caf64 100644 --- a/Framework/Crystal/src/SaveLauenorm.cpp +++ b/Framework/Crystal/src/SaveLauenorm.cpp @@ -111,6 +111,12 @@ void SaveLauenorm::exec() { // ============================== Save all Peaks // ========================================= + // HKL is flipped by -1 due to different q convention in ISAW vs mantid. + // Default for kf-ki has -q + double qSign = -1.0; + std::string convention = ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + qSign = 1.0; // Go through each peak at this run / bank for (int wi = 0; wi < ws->getNumberPeaks(); wi++) { @@ -170,10 +176,12 @@ void SaveLauenorm::exec() { // h k l lambda theta intensity and sig(intensity) in format // (3I5,2F10.5,2I10) // HKL is flipped by -1 due to different q convention in ISAW vs mantid. + // unless Crystallography convention if (p.getH() == 0 && p.getK() == 0 && p.getL() == 0) continue; - out << std::setw(5) << Utils::round(-p.getH()) << std::setw(5) - << Utils::round(-p.getK()) << std::setw(5) << Utils::round(-p.getL()); + out << std::setw(5) << Utils::round(qSign * p.getH()) << std::setw(5) + << Utils::round(qSign * p.getK()) << std::setw(5) + << Utils::round(qSign * p.getL()); out << std::setw(10) << std::fixed << std::setprecision(5) << lambda; // Assume that want theta not two-theta out << std::setw(10) << std::fixed << std::setprecision(5) diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp index f7b3c20e71aaa366148e78e1aa5840ba38933e26..9b988daed4c4ef9edee41ce3197b086977b61053 100644 --- a/Framework/DataHandling/src/LoadNexusProcessed.cpp +++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp @@ -1071,6 +1071,14 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { // peaks_workspace m_cppFile->closeGroup(); + // HKL is flipped by -1 due to different q convention in Crystallography. + // Always write out in ki-kf so consistent with old files + double qSign = 1.0; + std::string convention = + ConfigService::Instance().getString("default.convention"); + if (convention == "Crystallography") + qSign = -1.0; + for (int r = 0; r < numberPeaks; r++) { Kernel::V3D v3d; v3d[2] = 1.0; @@ -1097,7 +1105,7 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { nxDouble.load(); for (int r = 0; r < numberPeaks; r++) { - double val = nxDouble[r]; + double val = qSign * nxDouble[r]; peakWS->getPeak(r).setH(val); } } @@ -1107,7 +1115,7 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { nxDouble.load(); for (int r = 0; r < numberPeaks; r++) { - double val = nxDouble[r]; + double val = qSign * nxDouble[r]; peakWS->getPeak(r).setK(val); } } @@ -1117,7 +1125,7 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) { nxDouble.load(); for (int r = 0; r < numberPeaks; r++) { - double val = nxDouble[r]; + double val = qSign * nxDouble[r]; peakWS->getPeak(r).setL(val); } } @@ -1629,20 +1637,11 @@ void LoadNexusProcessed::readInstrumentGroup( // Now build the spectra list int index = 0; - bool haveSpectraAxis = local_workspace->getAxis(1)->isSpectra(); for (int i = 1; i <= spectraInfo.nSpectra; ++i) { int spectrum(-1); - // prefer the spectra number from the instrument section - // over anything else. If not there then use a spectra axis - // number if we have one, else make one up as nothing was - // written to the file. We should always set it so that - // CompareWorkspaces gives the expected answer on a Save/Load - // round trip. if (spectraInfo.hasSpectra) { spectrum = spectraInfo.spectraNumbers[i - 1]; - } else if (haveSpectraAxis && !m_axis1vals.empty()) { - spectrum = static_cast<specid_t>(m_axis1vals[i - 1]); } else { spectrum = i + 1; } @@ -1652,7 +1651,11 @@ void LoadNexusProcessed::readInstrumentGroup( find(m_spec_list.begin(), m_spec_list.end(), i) != m_spec_list.end())) { ISpectrum *spec = local_workspace->getSpectrum(index); - spec->setSpectrumNo(spectrum); + if (m_axis1vals.empty()) { + spec->setSpectrumNo(spectrum); + } else { + spec->setSpectrumNo(static_cast<specid_t>(m_axis1vals[i - 1])); + } ++index; int start = spectraInfo.detectorIndex[i - 1]; diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc index 2b9ca29de1b3af05929c6e08526cbd8475e61b89..bdcdfe3e2c4dd5d9433208a261464cab727d6562 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc +++ b/Framework/DataObjects/inc/MantidDataObjects/MDBox.tcc @@ -690,6 +690,7 @@ TMDE(void MDBox)::centroidSphere(Mantid::API::CoordTransform &radiusTransform, TMDE(void MDBox)::transformDimensions(std::vector<double> &scaling, std::vector<double> &offset) { MDBoxBase<MDE, nd>::transformDimensions(scaling, offset); + this->calculateCentroid(this->m_centroid); std::vector<MDE> &events = this->getEvents(); typename std::vector<MDE>::iterator it; typename std::vector<MDE>::iterator it_end = events.end(); diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc index fabb4d85c77d76247462e3ccebae607825a0aaed..6727acdd4be60473491d1b026dc8d3f9142c3e1d 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc +++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc @@ -16,6 +16,8 @@ #include "MantidDataObjects/MDFramesToSpecialCoordinateSystem.h" #include "MantidDataObjects/MDGridBox.h" #include "MantidDataObjects/MDLeanEvent.h" +#include "MantidKernel/ConfigService.h" + #include <iomanip> #include <functional> #include <algorithm> @@ -327,6 +329,7 @@ TMDE(signal_t MDEventWorkspace)::getSignalWithMaskAtCoord( } // Check if masked const API::IMDNode *box = data->getBoxAtCoord(coords); + if (!box) return MDMaskValue; if (box->getIsMasked()) { return MDMaskValue; } @@ -376,6 +379,7 @@ TMDE(std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> TMDE(std::vector<std::string> MDEventWorkspace)::getBoxControllerStats() const { std::vector<std::string> out; std::ostringstream mess; + size_t mem; mem = (this->m_BoxController->getTotalNumMDBoxes() * sizeof(MDBox<MDE, nd>)) / 1024; diff --git a/Framework/DataObjects/inc/MantidDataObjects/Peak.h b/Framework/DataObjects/inc/MantidDataObjects/Peak.h index 313ddb6d90a6efd95ac3740606cbd97ea7bdee41..b6d0ccfa09bf7677d6312491dec31d812d19efc2 100644 --- a/Framework/DataObjects/inc/MantidDataObjects/Peak.h +++ b/Framework/DataObjects/inc/MantidDataObjects/Peak.h @@ -9,6 +9,7 @@ #include "MantidKernel/PhysicalConstants.h" #include "MantidKernel/System.h" #include "MantidGeometry/Crystal/PeakShape.h" +#include "MantidKernel/ConfigService.h" #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> @@ -214,6 +215,10 @@ private: /// Static logger static Mantid::Kernel::Logger g_log; + + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string convention = + Kernel::ConfigService::Instance().getString("Q.convention"); }; } // namespace Mantid diff --git a/Framework/DataObjects/src/MDBoxFlatTree.cpp b/Framework/DataObjects/src/MDBoxFlatTree.cpp index 145e24246674856d2e1cfe7bc1d55293ee572f4a..d4b7d418f05c5b7a8784e5c989e93c4d04533d49 100644 --- a/Framework/DataObjects/src/MDBoxFlatTree.cpp +++ b/Framework/DataObjects/src/MDBoxFlatTree.cpp @@ -749,6 +749,12 @@ void MDBoxFlatTree::saveWSGenericInfo(::NeXus::File *const file, file->writeData("coordinate_system", static_cast<uint32_t>(ws->getSpecialCoordinateSystem())); + // Write out the Qconvention + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string m_QConvention = + Kernel::ConfigService::Instance().getString("Q.convention"); + file->writeData("QConvention", m_QConvention); + // Write out the set display normalization file->writeData("visual_normalization", static_cast<uint32_t>(ws->displayNormalization())); @@ -808,6 +814,8 @@ void MDBoxFlatTree::saveAffineTransformMatricies( void MDBoxFlatTree::saveAffineTransformMatrix( ::NeXus::File *const file, API::CoordTransform const *transform, std::string entry_name) { + if (!transform) + return; Kernel::Matrix<coord_t> matrix = transform->makeAffineMatrix(); g_log.debug() << "TRFM: " << matrix.str() << std::endl; saveMatrix<coord_t>(file, entry_name, matrix, ::NeXus::FLOAT32, diff --git a/Framework/DataObjects/src/Peak.cpp b/Framework/DataObjects/src/Peak.cpp index 412f64c13970708fd6ccd14dc2a77cccc4e3e955..fea8ff8399c47bd57f4d3d80f6be5a555786f552 100644 --- a/Framework/DataObjects/src/Peak.cpp +++ b/Framework/DataObjects/src/Peak.cpp @@ -452,7 +452,11 @@ Mantid::Kernel::V3D Peak::getQLabFrame() const { // Now calculate the wavevector of the scattered neutron double wvf = (2.0 * M_PI) / this->getWavelength(); // And Q in the lab frame - return beamDir * wvi - detDir * wvf; + // Default for ki-kf is positive + double qSign = 1.0; + if (convention == "Crystallography") + qSign = -1.0; + return (beamDir * wvi - detDir * wvf) * qSign; } //---------------------------------------------------------------------------------------------- @@ -528,7 +532,11 @@ void Peak::setQLabFrame(Mantid::Kernel::V3D QLabFrame, boost::shared_ptr<const ReferenceFrame> refFrame = this->m_inst->getReferenceFrame(); const V3D refBeamDir = refFrame->vecPointingAlongBeam(); - const double qBeam = q.scalar_prod(refBeamDir); + // Default for ki-kf has -q + double qSign = 1.0; + if (convention == "Crystallography") + qSign = -1.0; + const double qBeam = q.scalar_prod(refBeamDir) * qSign; if (norm_q == 0.0) throw std::invalid_argument("Peak::setQLabFrame(): Q cannot be 0,0,0."); @@ -548,7 +556,12 @@ void Peak::setQLabFrame(Mantid::Kernel::V3D QLabFrame, // Save the wavelength this->setWavelength(wl); - V3D detectorDir = q * -1.0; + // Default for ki-kf has -q + qSign = -1.0; + if (convention == "Crystallography") + qSign = 1.0; + + V3D detectorDir = q * qSign; detectorDir[refFrame->pointingAlongBeam()] = one_over_wl - qBeam; detectorDir.normalize(); diff --git a/Framework/DataObjects/src/PeaksWorkspace.cpp b/Framework/DataObjects/src/PeaksWorkspace.cpp index 5f60d4dd27b2d85681491721f7ee737bdefb5355..e8789ecd492ca45bdfbc1643ddc89a33ea697752 100644 --- a/Framework/DataObjects/src/PeaksWorkspace.cpp +++ b/Framework/DataObjects/src/PeaksWorkspace.cpp @@ -605,14 +605,21 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const { std::vector<double> goniometerMatrix(9 * np); std::vector<std::string> shapes(np); + // HKL is flipped by -1 due to different q convention in Crystallography. + // Always write out in ki-kf so consistent with old files + double qSign = 1.0; + std::string convention = ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + qSign = -1.0; + // Populate column vectors from Peak Workspace size_t maxShapeJSONLength = 0; for (size_t i = 0; i < np; i++) { Peak p = peaks[i]; detectorID[i] = p.getDetectorID(); - H[i] = p.getH(); - K[i] = p.getK(); - L[i] = p.getL(); + H[i] = qSign * p.getH(); + K[i] = qSign * p.getK(); + L[i] = qSign * p.getL(); intensity[i] = p.getIntensity(); sigmaIntensity[i] = p.getSigmaIntensity(); binCount[i] = p.getBinCount(); diff --git a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h index 4960525bd89a8b8ac183af9118005a9303c79f89..0ff5e834ca339fb202c473fc82af66abc2b00007 100644 --- a/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h +++ b/Framework/Geometry/inc/MantidGeometry/MDGeometry/MDDimensionExtents.h @@ -58,6 +58,12 @@ public: min = static_cast<T>(min * scaling + offset); max = static_cast<T>(max * scaling + offset); m_size = static_cast<T>(m_size * scaling); + if (max < min) { + T tmp = max; + max = min; + min = tmp; + m_size = std::fabs(m_size); + } } // it looks like this loses accuracy? void expand(MDDimensionExtents &other) { diff --git a/Framework/Kernel/src/ConfigService.cpp b/Framework/Kernel/src/ConfigService.cpp index 943bfe6415faea2a7ead5db0bbfa1675cd059a4e..f6330235d517b60be3f96252a4511569326da1ad 100644 --- a/Framework/Kernel/src/ConfigService.cpp +++ b/Framework/Kernel/src/ConfigService.cpp @@ -673,10 +673,15 @@ void ConfigServiceImpl::createUserPropertiesFile() const { filestr << "## e.g.: ISIS, SNS, ILL" << std::endl; filestr << "default.facility=" << std::endl; filestr << std::endl; - filestr << "## Stes the default instrument" << std::endl; + filestr << "## Sets the default instrument" << std::endl; filestr << "## e.g. IRIS, HET, NIMROD" << std::endl; filestr << "default.instrument=" << std::endl; filestr << std::endl; + filestr << std::endl; + filestr << "## Sets the Q.convention" << std::endl; + filestr << "## Set to Crystallography for kf-ki instead of default " + "Inelastic which is ki-kf" << std::endl; + filestr << "#Q.convention=Crystallography" << std::endl; filestr << "##" << std::endl; filestr << "## DIRECTORIES" << std::endl; filestr << "##" << std::endl; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h index c27d40674a83b6b84dd546cdebcba17b6abd7647..b8d05117f485dfb26b42a6b5cb746d2bfd516997 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CalculateCoverageDGS.h @@ -46,6 +46,9 @@ private: void init(); void exec(); + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string convention = + Kernel::ConfigService::Instance().getString("Q.convention"); /// limits for h,k,l,dE dimensions coord_t m_hmin, m_hmax, m_kmin, m_kmax, m_lmin, m_lmax, m_dEmin, m_dEmax; /// cached values for incident energy and momentum, final momentum min/max diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h index 2d696925f79d13e41f66ce9450bac5dae76264fb..ead3c69d6e3d0d4121d7e1103dfa0bbc7bc34253 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h @@ -66,6 +66,10 @@ private: /// Run the algorithm void exec(); + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string convention = + Kernel::ConfigService::Instance().getString("Q.convention"); + /// Helper method template <typename MDE, size_t nd> void doLoad(typename DataObjects::MDEventWorkspace<MDE, nd>::sptr ws); @@ -84,6 +88,8 @@ private: void loadCoordinateSystem(); + void loadQConvention(); + void loadVisualNormalization( const std::string &key, boost::optional<Mantid::API::MDNormalization> &normalization); @@ -114,6 +120,8 @@ private: std::vector<Mantid::Geometry::IMDDimension_sptr> m_dims; /// Coordinate system Kernel::SpecialCoordinateSystem m_coordSystem; + /// QConvention + std::string m_QConvention; /// load only the box structure with empty boxes but do not tload boxes events bool m_BoxStructureAndMethadata; diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h index 375dea557814745e6daab6a00e8116651f5ee0ad..232723120d92fe7003425cf34ada76b348cf0d00 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h @@ -88,6 +88,9 @@ private: Kernel::V3D m_samplePos; /// Beam direction Kernel::V3D m_beamDir; + /// ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string convention = + Kernel::ConfigService::Instance().getString("Q.convention"); }; } // namespace MDAlgorithms diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h index a0c1a0ed9d66e176118196357774d42e7e2f6ff9..092f86fed045cba75d9da35ece64d60c87316c6f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h @@ -91,6 +91,9 @@ private: Kernel::V3D m_samplePos; /// Beam direction Kernel::V3D m_beamDir; + /// ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string convention = + Kernel::ConfigService::Instance().getString("Q.convention"); }; } // namespace MDAlgorithms diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h index 8c63d3573d746cea5370cba35f0db997f17e2e8e..c5971198784c5adaa4e2a1d6c591910383cc510f 100644 --- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDTransfQ3D.h @@ -4,6 +4,7 @@ #include "MantidMDAlgorithms/MDTransfInterface.h" #include "MantidMDAlgorithms/MDTransfFactory.h" #include "MantidMDAlgorithms/MDTransfModQ.h" +#include "MantidKernel/ConfigService.h" // namespace Mantid { namespace MDAlgorithms { @@ -98,6 +99,9 @@ protected: // current value of Sin(Theta)^2 corresponding to the current detector value // and used to calculate Lorentz corrections double m_SinThetaSq; + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string convention = + Kernel::ConfigService::Instance().getString("Q.convention"); // all other variables are the same as in ModQ // hole near origin of Q double m_AbsMin; diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp index 314e164716b3e9d5fe7bb3da0486358ab3b8567f..2394ac3c37955b9ae5385fe14bb4076c708c9774 100644 --- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp +++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp @@ -456,8 +456,13 @@ CalculateCoverageDGS::calculateIntersections(const double theta, const double phi) { V3D qout(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)), qin(0., 0., m_ki); + qout = m_rubw * qout; qin = m_rubw * qin; + if (convention == "Crystallography") { + qout *= -1; + qin *= -1; + } double hStart = qin.X() - qout.X() * m_kfmin, hEnd = qin.X() - qout.X() * m_kfmax; double kStart = qin.Y() - qout.Y() * m_kfmin, diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp index 4f6bf32e23452dd2ec1d8b6ba2a0ed9ec04cddb4..0dfce62de24cd82a3e37aa9e0bb94d790d69409e 100644 --- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp +++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp @@ -19,6 +19,7 @@ #include "MantidDataObjects/MDEventWorkspace.h" #include "MantidAPI/MemoryManager.h" #include "MantidKernel/ListValidator.h" +#include "MantidKernel/ConfigService.h" using namespace Mantid; using namespace Mantid::Kernel; @@ -215,6 +216,12 @@ void ConvertToDiffractionMDWorkspace::convertEventList(int workspaceIndex, // = input beam direction (normalized to 1) - output beam direction // (normalized to 1) V3D Q_dir_lab_frame = beamDir - detDir; + double qSign = -1.0; + std::string convention = + ConfigService::Instance().getString("Q.convention"); + if (convention == "Crystallography") + qSign = 1.0; + Q_dir_lab_frame *= qSign; // Multiply by the rotation matrix to convert to Q in the sample frame (take // out goniometer rotation) diff --git a/Framework/MDAlgorithms/src/LoadMD.cpp b/Framework/MDAlgorithms/src/LoadMD.cpp index 81158d0064b724131d98aaefcbdff284b8e03bb6..4a30585b717f35867217c4d4096716c62765037d 100644 --- a/Framework/MDAlgorithms/src/LoadMD.cpp +++ b/Framework/MDAlgorithms/src/LoadMD.cpp @@ -1,6 +1,7 @@ #include "MantidAPI/ExperimentInfo.h" #include "MantidAPI/FileProperty.h" #include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/IMDWorkspace.h" #include "MantidAPI/RegisterFileLoader.h" #include "MantidGeometry/MDGeometry/IMDDimension.h" #include "MantidGeometry/MDGeometry/IMDDimensionFactory.h" @@ -22,6 +23,7 @@ #include "MantidDataObjects/MDHistoWorkspace.h" #include "MantidDataObjects/BoxControllerNeXusIO.h" #include "MantidDataObjects/CoordTransformAffine.h" +#include "MantidKernel/ConfigService.h" #include <nexus/NeXusException.hpp> #include <boost/algorithm/string.hpp> #include <vector> @@ -186,6 +188,9 @@ void LoadMD::exec() { // Coordinate system this->loadCoordinateSystem(); + // QConvention (Inelastic or Crystallography) + this->loadQConvention(); + // Display normalization settting if (levelEntries.find(VISUAL_NORMALIZATION_KEY) != levelEntries.end()) { this->loadVisualNormalization(VISUAL_NORMALIZATION_KEY, @@ -226,6 +231,25 @@ void LoadMD::exec() { if (m_requiresMDFrameCorrection) { setMDFrameOnWorkspaceFromLegacyFile(ws); } + // Write out the Qconvention + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string pref_QConvention = + Kernel::ConfigService::Instance().getString("Q.convention"); + g_log.information() << "Convention for Q in Preferences is " + << pref_QConvention + << "; Convention of Q in NeXus file is " + << m_QConvention << std::endl; + + if (pref_QConvention != m_QConvention) { + g_log.information() << "Transforming Q" << std::endl; + Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD"); + transform_alg->setProperty("InputWorkspace", + boost::dynamic_pointer_cast<IMDWorkspace>(ws)); + transform_alg->setProperty("Scaling", "-1.0"); + transform_alg->executeAsChildAlg(); + IMDWorkspace_sptr tmp = transform_alg->getProperty("OutputWorkspace"); + ws = boost::dynamic_pointer_cast<IMDEventWorkspace>(tmp); + } // Save to output setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(ws)); @@ -314,6 +338,26 @@ void LoadMD::loadHisto() { setMDFrameOnWorkspaceFromLegacyFile(ws); } + // Write out the Qconvention + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string pref_QConvention = + Kernel::ConfigService::Instance().getString("Q.convention"); + g_log.information() << "Convention for Q in Preferences is " + << pref_QConvention + << "; Convention of Q in NeXus file is " << m_QConvention + << std::endl; + + if (pref_QConvention != m_QConvention) { + g_log.information() << "Transforming Q" << std::endl; + Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD"); + transform_alg->setProperty("InputWorkspace", + boost::dynamic_pointer_cast<IMDWorkspace>(ws)); + transform_alg->setProperty("Scaling", "-1.0"); + transform_alg->executeAsChildAlg(); + IMDWorkspace_sptr tmp = transform_alg->getProperty("OutputWorkspace"); + ws = boost::dynamic_pointer_cast<MDHistoWorkspace>(tmp); + } + // Save to output setProperty("OutputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(ws)); } @@ -420,6 +464,15 @@ void LoadMD::loadCoordinateSystem() { } } +/** Load the convention for Q **/ +void LoadMD::loadQConvention() { + try { + m_file->readData("QConvention", m_QConvention); + } catch (::NeXus::Exception &) { + m_QConvention = "Inelastic"; + } +} + //---------------------------------------------------------------------------------------------- /** Do the loading. * diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp index efc710413ea131fd80af16c803aac3de848021df..551d0f5bdfac5aeddf6f5b678b145928d835b476 100644 --- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp +++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp @@ -8,6 +8,7 @@ #include "MantidKernel/CompositeValidator.h" #include "MantidKernel/TimeSeriesProperty.h" #include "MantidKernel/VectorHelper.h" +#include "MantidKernel/ConfigService.h" namespace Mantid { namespace MDAlgorithms { @@ -606,8 +607,13 @@ std::vector<Kernel::VMD> MDNormDirectSC::calculateIntersections(const double theta, const double phi) { V3D qout(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)), qin(0., 0., m_ki); + qout = m_rubw * qout; qin = m_rubw * qin; + if (convention != "Crystallography") { + qout *= -1; + qin *= -1; + } double hStart = qin.X() - qout.X() * m_kfmin, hEnd = qin.X() - qout.X() * m_kfmax; double kStart = qin.Y() - qout.Y() * m_kfmin, diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp index 665807725fa4ce720c79046990b032f45b559e0e..60f66f91755027f74d80af51e14ff8ce2f20f822 100644 --- a/Framework/MDAlgorithms/src/MDNormSCD.cpp +++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp @@ -642,6 +642,10 @@ std::vector<Kernel::VMD> MDNormSCD::calculateIntersections(const double theta, const double phi) { V3D q(-sin(theta) * cos(phi), -sin(theta) * sin(phi), 1. - cos(theta)); q = m_rubw * q; + if (convention != "Crystallography") { + q *= -1; + } + double hStart = q.X() * m_kiMin, hEnd = q.X() * m_kiMax; double kStart = q.Y() * m_kiMin, kEnd = q.Y() * m_kiMax; double lStart = q.Z() * m_kiMin, lEnd = q.Z() * m_kiMax; diff --git a/Framework/MDAlgorithms/src/MDTransfQ3D.cpp b/Framework/MDAlgorithms/src/MDTransfQ3D.cpp index 3a79ff96bc4584f006cd49ae3803944af1e2ac36..507bb342b132e736555c8741d30afe0653d331b7 100644 --- a/Framework/MDAlgorithms/src/MDTransfQ3D.cpp +++ b/Framework/MDAlgorithms/src/MDTransfQ3D.cpp @@ -80,6 +80,12 @@ bool MDTransfQ3D::calcMatrixCoord3DInelastic( double qy = -m_ey * k_tr; double qz = m_Ki - m_ez * k_tr; + if (convention == "Crystallography") { + qx = -qx; + qy = -qy; + qz = -qz; + } + Coord[0] = (coord_t)(m_RotMat[0] * qx + m_RotMat[1] * qy + m_RotMat[2] * qz); if (Coord[0] < m_DimMin[0] || Coord[0] >= m_DimMax[0]) return false; @@ -120,6 +126,12 @@ bool MDTransfQ3D::calcMatrixCoord3DElastic(const double &k0, double qx = -m_ex * k0; double qy = -m_ey * k0; double qz = (1 - m_ez) * k0; + if (convention == "Crystallography") { + qx = -qx; + qy = -qy; + qz = -qz; + } + Coord[0] = (coord_t)(m_RotMat[0] * qx + m_RotMat[1] * qy + m_RotMat[2] * qz); if (Coord[0] < m_DimMin[0] || Coord[0] >= m_DimMax[0]) return false; diff --git a/Framework/MDAlgorithms/src/SaveMD2.cpp b/Framework/MDAlgorithms/src/SaveMD2.cpp index 3cf980d9286fd7348ae528bf989911cc1216eb30..c521bf1df27f17033fe9cd76436250001f50cf17 100644 --- a/Framework/MDAlgorithms/src/SaveMD2.cpp +++ b/Framework/MDAlgorithms/src/SaveMD2.cpp @@ -14,6 +14,7 @@ #include "MantidDataObjects/MDHistoWorkspace.h" #include "MantidDataObjects/MDBoxFlatTree.h" #include "MantidDataObjects/BoxControllerNeXusIO.h" +#include "MantidKernel/ConfigService.h" // clang-format off #if defined(__GLIBCXX__) && __GLIBCXX__ >= 20100121 // libstdc++-4.4.3 @@ -105,6 +106,12 @@ void SaveMD2::doSaveHisto(Mantid::DataObjects::MDHistoWorkspace_sptr ws) { file->writeData("coordinate_system", static_cast<uint32_t>(ws->getSpecialCoordinateSystem())); + // Write out the Qconvention + // ki-kf for Inelastic convention; kf-ki for Crystallography convention + std::string m_QConvention = + Kernel::ConfigService::Instance().getString("Q.convention"); + file->writeData("QConvention", m_QConvention); + // Write out the visual normalization file->writeData("visual_normalization", static_cast<uint32_t>(ws->displayNormalization())); diff --git a/Framework/MDAlgorithms/src/TransformMD.cpp b/Framework/MDAlgorithms/src/TransformMD.cpp index cb4f2fed3ff3ca4ade2b2639d73b3b212f29d05d..6588c30bee462dfb38a59db37ae80b912806f1d0 100644 --- a/Framework/MDAlgorithms/src/TransformMD.cpp +++ b/Framework/MDAlgorithms/src/TransformMD.cpp @@ -5,6 +5,7 @@ #include "MantidAPI/IMDEventWorkspace.h" #include "MantidDataObjects/MDEventWorkspace.h" #include "MantidDataObjects/MDEventFactory.h" +#include "MantidGeometry/MDGeometry/IMDDimension.h" using namespace Mantid::Kernel; using namespace Mantid::API; @@ -101,6 +102,7 @@ void TransformMD::exec() { inWS = getProperty("InputWorkspace"); outWS = getProperty("OutputWorkspace"); + std::string outName = getPropertyValue("OutputWorkspace"); if (boost::dynamic_pointer_cast<MatrixWorkspace>(inWS)) throw std::runtime_error("TransformMD can only transform a " @@ -147,12 +149,64 @@ void TransformMD::exec() { if (histo) { // Recalculate all the values since the dimensions changed. histo->cacheValues(); + this->setProperty("OutputWorkspace", histo); } else if (event) { // Call the method for this type of MDEventWorkspace. CALL_MDEVENT_FUNCTION(this->doTransform, outWS); + Progress *prog2 = NULL; + ThreadScheduler *ts = new ThreadSchedulerFIFO(); + ThreadPool tp(ts, 0, prog2); + event->splitAllIfNeeded(ts); + // prog2->resetNumSteps( ts->size(), 0.4, 0.6); + tp.joinAll(); + event->refreshCache(); + // Set the special coordinate system. + IMDEventWorkspace_sptr inEvent = + boost::dynamic_pointer_cast<IMDEventWorkspace>(inWS); + event->setCoordinateSystem(inEvent->getSpecialCoordinateSystem()); + + if (m_scaling[0] < 0) { + // Only need these 2 algorithms for transforming with negative number + std::vector<double> extents; + std::vector<std::string> names, units; + for (size_t d = 0; d < nd; d++) { + Geometry::IMDDimension_const_sptr dim = event->getDimension(d); + // Find the extents + extents.push_back(dim->getMinimum()); + extents.push_back(dim->getMaximum()); + names.push_back(std::string(dim->getName())); + units.push_back(dim->getUnits()); + } + Algorithm_sptr create_alg = createChildAlgorithm("CreateMDWorkspace"); + create_alg->setProperty("Dimensions", static_cast<int>(nd)); + create_alg->setProperty("EventType", event->getEventTypeName()); + create_alg->setProperty("Extents", extents); + create_alg->setProperty("Names", names); + create_alg->setProperty("Units", units); + create_alg->setPropertyValue("OutputWorkspace", "__none"); + create_alg->executeAsChildAlg(); + Workspace_sptr none = create_alg->getProperty("OutputWorkspace"); + + AnalysisDataService::Instance().addOrReplace(outName, event); + AnalysisDataService::Instance().addOrReplace("__none", none); + Mantid::API::BoxController_sptr boxController = event->getBoxController(); + std::vector<int> splits; + for (size_t d = 0; d < nd; d++) { + splits.push_back(static_cast<int>(boxController->getSplitInto(d))); + } + Algorithm_sptr merge_alg = createChildAlgorithm("MergeMD"); + merge_alg->setPropertyValue("InputWorkspaces", outName + ",__none"); + merge_alg->setProperty("SplitInto", splits); + merge_alg->setProperty( + "SplitThreshold", + static_cast<int>(boxController->getSplitThreshold())); + merge_alg->setProperty("MaxRecursionDepth", 13); + merge_alg->executeAsChildAlg(); + event = merge_alg->getProperty("OutputWorkspace"); + AnalysisDataService::Instance().remove("__none"); + } + this->setProperty("OutputWorkspace", event); } - - this->setProperty("OutputWorkspace", outWS); } } // namespace Mantid diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template index 8b00a1f10274348bc64560905e6bc82d9b034e85..5ec631d5008b300ca3550642a690e6ee167f9631 100644 --- a/Framework/Properties/Mantid.properties.template +++ b/Framework/Properties/Mantid.properties.template @@ -15,6 +15,10 @@ default.facility = ISIS # Set a default instrument default.instrument = +# This flag controls the convention for converting to Q. Default is ki-kf +# Change to Crystallography for kf-ki +Q.convention = Inelastic + # Set of PyQt interfaces to add to the Interfaces menu, separated by a space. Interfaces are seperated from their respective categories by a "/". mantidqt.python_interfaces = Direct/DGS_Reduction.py Direct/DGSPlanner.py SANS/ORNL_SANS.py Reflectometry/REFL_Reduction.py Reflectometry/REFL_SF_Calculator.py Reflectometry/REFM_Reduction.py Utility/TofConverter.py Reflectometry/ISIS_Reflectometry.py Diffraction/Powder_Diffraction_Reduction.py Utility/FilterEvents.py Diffraction/HFIR_Powder_Diffraction_Reduction.py Diffraction/HFIR_4Circle_Reduction.py diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp index 87e74e4ea83cab6eb72537345019aeadb92dc4f3..7d2b76c1949f031beb7210661341118f58ee4bc1 100644 --- a/MantidPlot/src/ConfigDialog.cpp +++ b/MantidPlot/src/ConfigDialog.cpp @@ -690,6 +690,14 @@ void ConfigDialog::initMantidPage() ckIgnoreParaView->setChecked(ignoreParaView); grid->addWidget(ckIgnoreParaView, 3, 0); + //Change to Crystallography Convention + ckQconvention = new QCheckBox("Crystallography Convention"); + ckQconvention->setToolTip("Change from default ki-kf to kf-ki."); + const std::string QconventionProperty = "Q.convention"; + bool Qconvention = cfgSvc.hasProperty(QconventionProperty) && bool(cfgSvc.getString(QconventionProperty) == "Crystallography"); + ckQconvention->setChecked(Qconvention); + grid->addWidget(ckQconvention, 4, 0); + // Populate boxes auto faclist = cfgSvc.getFacilityNames(); for ( auto it = faclist.begin(); it != faclist.end(); ++it ) @@ -2464,6 +2472,10 @@ void ConfigDialog::apply() cfgSvc.setString("default.facility", facility->currentText().toStdString()); cfgSvc.setString("default.instrument", defInstr->currentText().toStdString()); cfgSvc.setString("paraview.ignore", QString::number(ckIgnoreParaView->isChecked()).toStdString()); + if (ckQconvention->isChecked()) + cfgSvc.setString("Q.convention", "Crystallography"); + else + cfgSvc.setString("Q.convention", "Inelastic"); updateDirSearchSettings(); diff --git a/MantidPlot/src/ConfigDialog.h b/MantidPlot/src/ConfigDialog.h index 64f80367c2e9aa5119081d709160ca78fdd0591a..d8122326fc17d458599aac7eb33e9a718270f0d7 100644 --- a/MantidPlot/src/ConfigDialog.h +++ b/MantidPlot/src/ConfigDialog.h @@ -188,6 +188,7 @@ private: QComboBox *facility; MantidQt::MantidWidgets::InstrumentSelector *defInstr; QCheckBox* ckIgnoreParaView; + QCheckBox* ckQconvention; /// Mantid tab for setting directories QWidget *directoriesPage; diff --git a/MantidQt/SliceViewer/src/SliceViewer.cpp b/MantidQt/SliceViewer/src/SliceViewer.cpp index 4c5a8db6be421861df08e00b16de7e7ca216df41..028a7a0d39227147646fd0526a133079a20d9527 100644 --- a/MantidQt/SliceViewer/src/SliceViewer.cpp +++ b/MantidQt/SliceViewer/src/SliceViewer.cpp @@ -701,6 +701,12 @@ void SliceViewer::setWorkspace(Mantid::API::IMDWorkspace_sptr ws) { // MDEWs) coord_t min = m_ws->getDimension(d)->getMinimum(); coord_t max = m_ws->getDimension(d)->getMaximum(); + if (max < min) + { + coord_t tmp = max; + max = min; + min = tmp; + } if (boost::math::isnan(min) || boost::math::isinf(min) || boost::math::isnan(max) || boost::math::isinf(max)) { mess << "Dimension " << m_ws->getDimension(d)->getName() diff --git a/docs/source/concepts/PropertiesFile.rst b/docs/source/concepts/PropertiesFile.rst index 41e0caf18671dffc0579bcdf180063be2adc5803..8961e803ae109b2aa3506adb16210620eae0d7f4 100644 --- a/docs/source/concepts/PropertiesFile.rst +++ b/docs/source/concepts/PropertiesFile.rst @@ -43,19 +43,23 @@ General properties Facility and instrument properties ********************************** -+------------------------------+---------------------------------------------------+-------------+ -|Property |Description |Example value| -+==============================+===================================================+=============+ -|default.facility |The name of the default facility. The facility must| ISIS | -| |be defined within the facilites.xml file to be | | -| |considered valid. The file is described here. | | -| |:ref:`here <Facilities file>`. | | -+------------------------------+---------------------------------------------------+-------------+ -|default.instrument |The name of the default instrument. The instrument | WISH | -| |must be defined within the facilities.xml file to | | -| |be valid. The file is described | | -| |:ref:`here <Facilities file>`. | | -+------------------------------+---------------------------------------------------+-------------+ ++------------------------------+---------------------------------------------------+-----------------+ +|Property |Description |Example value | ++==============================+===================================================+=================+ +|default.facility |The name of the default facility. The facility must| ISIS | +| |be defined within the facilites.xml file to be | | +| |considered valid. The file is described here. | | +| |:ref:`here <Facilities file>`. | | ++------------------------------+---------------------------------------------------+-----------------+ +|default.instrument |The name of the default instrument. The instrument | WISH | +| |must be defined within the facilities.xml file to | | +| |be valid. The file is described | | +| |:ref:`here <Facilities file>`. | | ++------------------------------+---------------------------------------------------+-----------------+ +|Q.convention |The convention for converting to Q. For inelastic | Crystallography | +| |the convention is ki-kf. For Crystallography the | | +| |convention is kf-ki. | | ++------------------------------+---------------------------------------------------+-----------------+ Directory Properties ******************** diff --git a/tools/DefaultConfigFiles/Mantid.user.properties b/tools/DefaultConfigFiles/Mantid.user.properties index 41c121da74ccbbf296af05679a6b0a17a285f97b..3bebfafb771c9a58963dac9b46c4503aa5313ade 100644 --- a/tools/DefaultConfigFiles/Mantid.user.properties +++ b/tools/DefaultConfigFiles/Mantid.user.properties @@ -31,6 +31,10 @@ default.facility= ## e.g. IRIS, HET, NIMROD default.instrument= +# This flag controls the convention for converting to Q. Default is ki-kf +# Change to Crystallography for kf-ki +Q.convention = Inelastic + ## ## DIRECTORIES ##