diff --git a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp index 583264085f922631fb3505eb62e172d38e053824..5defd4a05be97697762812dec559c5e255ca7bf5 100644 --- a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp +++ b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp @@ -602,6 +602,9 @@ bool LoadSpiceXML2DDet::getHB3AWavelength(MatrixWorkspace_sptr dataws, if (fabs(m1pos - (-25.870000)) < 0.2) { wavelength = 1.003; haswavelength = true; + } else if (fabs(m1pos - (-39.17)) < 0.2) { + wavelength = 1.5424; + haswavelength = true; } else { g_log.warning() << "m1 position " << m1pos << " does not have defined mapping to " @@ -615,6 +618,9 @@ bool LoadSpiceXML2DDet::getHB3AWavelength(MatrixWorkspace_sptr dataws, if (fabs(m1pos - (-25.870000)) < 0.2) { wavelength = 1.003; haswavelength = true; + } else if (fabs(m1pos - (-39.17)) < 0.2) { + wavelength = 1.5424; + haswavelength = true; } else { g_log.warning() << "m1 position " << m1pos << " does not have defined mapping to " diff --git a/Framework/MDAlgorithms/CMakeLists.txt b/Framework/MDAlgorithms/CMakeLists.txt index d52d54087d1ee9ad8e3c019dbc931d490c2f9416..f3e9e4d04a2db2271f828af463f363f2364f2462 100644 --- a/Framework/MDAlgorithms/CMakeLists.txt +++ b/Framework/MDAlgorithms/CMakeLists.txt @@ -19,6 +19,7 @@ set ( SRC_FILES src/ConvToMDSelector.cpp src/ConvertCWPDMDToSpectra.cpp src/ConvertCWSDExpToMomentum.cpp + src/ConvertCWSDMDtoHKL.cpp src/ConvertMDHistoToMatrixWorkspace.cpp src/ConvertSpiceDataToRealSpace.cpp src/ConvertToDetectorFaceMD.cpp @@ -138,6 +139,7 @@ set ( INC_FILES inc/MantidMDAlgorithms/ConvToMDBase.h inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h + inc/MantidMDAlgorithms/ConvertCWSDMDtoHKL.h inc/MantidMDAlgorithms/ConvertMDHistoToMatrixWorkspace.h inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h inc/MantidMDAlgorithms/ConvertToDetectorFaceMD.h @@ -257,6 +259,7 @@ set ( TEST_FILES CompareMDWorkspacesTest.h ConvertCWPDMDToSpectraTest.h ConvertCWSDExpToMomentumTest.h + ConvertCWSDMDtoHKLTest.h ConvertEventsToMDTest.h ConvertMDHistoToMatrixWorkspaceTest.h ConvertSpiceDataToRealSpaceTest.h diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWSDMDtoHKL.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWSDMDtoHKL.h new file mode 100644 index 0000000000000000000000000000000000000000..6879be0456ee797b4df6442510d5ad6894024197 --- /dev/null +++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWSDMDtoHKL.h @@ -0,0 +1,107 @@ +#ifndef MANTID_MDALGORITHMS_CONVERTCWSDMDTOHKL_H_ +#define MANTID_MDALGORITHMS_CONVERTCWSDMDTOHKL_H_ + +#include "MantidMDAlgorithms/DllConfig.h" +#include "MantidKernel/System.h" +#include "MantidAPI/Algorithm.h" +#include "MantidAPI/IMDEventWorkspace_fwd.h" +#include "MantidDataObjects/PeaksWorkspace.h" +#include "MantidKernel/Matrix.h" +#include "MantidKernel/V3D.h" + +namespace Mantid { +namespace MDAlgorithms { + +/** ConvertCWSDMDtoHKL : TODO: DESCRIPTION + + Copyright © 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge + National Laboratory & European Spallation Source + + This file is part of Mantid. + + Mantid is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Mantid is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + File change history is stored at: <https://github.com/mantidproject/mantid> + Code Documentation is available at: <http://doxygen.mantidproject.org> +*/ +class MANTID_MDALGORITHMS_DLL ConvertCWSDMDtoHKL : public API::Algorithm { +public: + ConvertCWSDMDtoHKL(); + virtual ~ConvertCWSDMDtoHKL(); + + /// Algorithm's name + virtual const std::string name() const { return "ConvertCWSDMDtoHKL"; } + + /// Summary of algorithms purpose + virtual const std::string summary() const { + return "Convert constant wavelength single crystal diffractomer's data" + "in MDEventWorkspace and in unit of Q-sample to the HKL space " + "by UB matrix."; + } + + /// Algorithm's version + virtual int version() const { return (1); } + + /// Algorithm's category for identification + virtual const std::string category() const { + return "Diffraction;MDAlgorithms"; + } + +private: + /// Initialisation code + void init(); + + /// Execution code + void exec(); + + void exportEvents(API::IMDEventWorkspace_sptr mdws, + std::vector<Kernel::V3D> &vec_event_qsample, + std::vector<signal_t> &vec_event_signal, + std::vector<detid_t> &vec_event_det); + + void convertFromQSampleToHKL(const std::vector<Kernel::V3D> &q_vectors, + std::vector<Kernel::V3D> &miller_indices); + + API::IMDEventWorkspace_sptr + createHKLMDWorkspace(const std::vector<Kernel::V3D> &vec_hkl, + const std::vector<signal_t> &vec_signal, + const std::vector<detid_t> &vec_detid); + + void addMDEvents(std::vector<std::vector<coord_t>> &vec_q_sample, + std::vector<float> &vec_signal); + + void + saveMDToFile(std::vector<std::vector<Mantid::coord_t>> &vec_event_qsample, + std::vector<float> &vec_event_signal); + + void saveEventsToFile(const std::string &filename, + std::vector<Kernel::V3D> &vec_event_pos, + std::vector<signal_t> &vec_event_signal, + std::vector<detid_t> &vec_event_detid); + + void getUBMatrix(); + + void getRange(const std::vector<Kernel::V3D> vec_hkl, + std::vector<double> &extentMins, + std::vector<double> &extentMaxs); + + API::IMDEventWorkspace_sptr m_outputWS; + + Kernel::Matrix<double> m_UB; +}; + +} // namespace MDAlgorithms +} // namespace Mantid + +#endif /* MANTID_MDALGORITHMS_CONVERTCWSDMDTOHKL_H_ */ diff --git a/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ebee9b77c9e84a78b80ef741ee177271aab55475 --- /dev/null +++ b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp @@ -0,0 +1,403 @@ +#include "MantidMDAlgorithms/ConvertCWSDMDtoHKL.h" + +#include "MantidAPI/WorkspaceProperty.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/IMDIterator.h" + +#include "MantidGeometry/Crystal/IndexingUtils.h" +#include "MantidGeometry/Crystal/OrientedLattice.h" +#include "MantidKernel/BoundedValidator.h" +#include "MantidKernel/ArrayProperty.h" + +#include "MantidDataObjects/MDEventFactory.h" +#include "MantidAPI/ExperimentInfo.h" +#include "MantidGeometry/Instrument/ComponentHelper.h" +#include "MantidMDAlgorithms/MDWSDescription.h" +#include "MantidMDAlgorithms/MDWSTransform.h" +#include "MantidAPI/FileProperty.h" +#include "MantidDataObjects/MDBoxBase.h" +#include "MantidDataObjects/MDEventInserter.h" + +#include <fstream> + +namespace Mantid { +namespace MDAlgorithms { + +using namespace Mantid::API; +using namespace Mantid::Kernel; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::DataObjects; +using namespace Mantid::Geometry; + +DECLARE_ALGORITHM(ConvertCWSDMDtoHKL) + +//---------------------------------------------------------------------------------------------- +/** Constructor + */ +ConvertCWSDMDtoHKL::ConvertCWSDMDtoHKL() {} + +//---------------------------------------------------------------------------------------------- +/** Destructor + */ +ConvertCWSDMDtoHKL::~ConvertCWSDMDtoHKL() {} + +//---------------------------------------------------------------------------------------------- +/** Init + */ +void ConvertCWSDMDtoHKL::init() { + declareProperty(new WorkspaceProperty<IMDEventWorkspace>("InputWorkspace", "", + Direction::Input), + "Name of the input MDEventWorkspace that stores detectors " + "counts from a constant-wave powder diffraction experiment."); + + declareProperty(new WorkspaceProperty<PeaksWorkspace>("PeaksWorkspace", "", + Direction::Input, + PropertyMode::Optional), + "Input Peaks Workspace"); + + declareProperty( + new ArrayProperty<double>("UBMatrix"), + "A comma seperated list of doubles for UB matrix from (0,0), (0,1)" + "... (2,1),(2,2)"); + + declareProperty(new WorkspaceProperty<IMDEventWorkspace>( + "OutputWorkspace", "", Direction::Output), + "Name of the output MDEventWorkspace in HKL-space."); + + std::vector<std::string> exts; + exts.push_back(".dat"); + declareProperty( + new FileProperty("QSampleFileName", "", API::FileProperty::OptionalSave), + "Name of file for sample sample."); + + declareProperty( + new FileProperty("HKLFileName", "", API::FileProperty::OptionalSave), + "Name of file for HKL."); +} + +//---------------------------------------------------------------------------------------------- +/** Exec + */ +void ConvertCWSDMDtoHKL::exec() { + // Get inputs + IMDEventWorkspace_sptr inputWS = getProperty("InputWorkspace"); + if (inputWS->getSpecialCoordinateSystem() != Mantid::Kernel::QSample) { + std::stringstream errmsg; + errmsg << "Input MDEventWorkspace's coordinate system is not QSample but " + << inputWS->getSpecialCoordinateSystem() << "."; + throw std::invalid_argument(errmsg.str()); + } + + getUBMatrix(); + + // Test indexing. Will be delete soon + if (true) { + Kernel::V3D qsample; // [1.36639,-2.52888,-4.77349] + qsample.setX(1.36639); + qsample.setY(-2.52888); + qsample.setZ(-4.77349); + + std::vector<Kernel::V3D> vec_qsample; + vec_qsample.push_back(qsample); + std::vector<Kernel::V3D> vec_mindex(0); + + convertFromQSampleToHKL(vec_qsample, vec_mindex); + g_log.notice() << "[DB Number of returned Miller Index = " + << vec_mindex.size() << "\n"; + g_log.notice() << "[DB] Output HKL = " << vec_mindex[0].toString() << "\n"; + } + + // Get events information for future processing + std::vector<Kernel::V3D> vec_event_qsample; + std::vector<signal_t> vec_event_signal; + std::vector<detid_t> vec_event_det; + exportEvents(inputWS, vec_event_qsample, vec_event_signal, vec_event_det); + + std::string qsamplefilename = getPropertyValue("QSampleFileName"); + // Abort with an empty string + if (qsamplefilename.size() > 0) + saveEventsToFile(qsamplefilename, vec_event_qsample, vec_event_signal, + vec_event_det); + + // Convert to HKL + std::vector<Kernel::V3D> vec_event_hkl; + convertFromQSampleToHKL(vec_event_qsample, vec_event_hkl); + + // Get file name + std::string hklfilename = getPropertyValue("HKLFileName"); + // Abort mission if no file name is given + if (hklfilename.size() > 0) + saveEventsToFile(hklfilename, vec_event_hkl, vec_event_signal, + vec_event_det); + + // Create output workspace + m_outputWS = + createHKLMDWorkspace(vec_event_hkl, vec_event_signal, vec_event_det); + + setProperty("OutputWorkspace", m_outputWS); +} + +void ConvertCWSDMDtoHKL::getUBMatrix() { + std::string peakwsname = getPropertyValue("PeaksWorkspace"); + if (peakwsname.size() > 0 && + AnalysisDataService::Instance().doesExist(peakwsname)) { + // Get from peak works + DataObjects::PeaksWorkspace_sptr peakws = getProperty("PeaksWorkspace"); + m_UB = + Kernel::Matrix<double>(peakws->sample().getOrientedLattice().getUB()); + } else { + // Get from ... + std::vector<double> ub_array = getProperty("UBMatrix"); + if (ub_array.size() != 9) + throw std::invalid_argument("Input UB matrix must have 9 elements"); + + m_UB = Kernel::Matrix<double>(3, 3); + for (size_t i = 0; i < 3; ++i) { + for (size_t j = 0; j < 3; ++j) { + m_UB[i][j] = ub_array[i * 3 + j]; + } + } + } + + return; +} + +//-------------------------------------------------------------------------- +/** Export events from an MDEventWorkspace for future processing + * It is a convenient algorithm if number of events are few relative to + * number of detectors + */ +void ConvertCWSDMDtoHKL::exportEvents( + IMDEventWorkspace_sptr mdws, std::vector<Kernel::V3D> &vec_event_qsample, + std::vector<signal_t> &vec_event_signal, + std::vector<detid_t> &vec_event_det) { + // Set the size of the output vectors + size_t numevents = mdws->getNEvents(); + g_log.information() << "Number of events = " << numevents << "\n"; + + vec_event_qsample.resize(numevents); + vec_event_signal.resize(numevents); + vec_event_det.resize(numevents); + + // Go through to get value + IMDIterator *mditer = mdws->createIterator(); + size_t nextindex = 1; + bool scancell = true; + size_t currindex = 0; + while (scancell) { + size_t numevent_cell = mditer->getNumEvents(); + for (size_t iev = 0; iev < numevent_cell; ++iev) { + // Check + if (currindex >= vec_event_qsample.size()) + throw std::runtime_error("Logic error in event size!"); + + float tempx = mditer->getInnerPosition(iev, 0); + float tempy = mditer->getInnerPosition(iev, 1); + float tempz = mditer->getInnerPosition(iev, 2); + signal_t signal = mditer->getInnerSignal(iev); + detid_t detid = mditer->getInnerDetectorID(iev); + Kernel::V3D qsample(tempx, tempy, tempz); + vec_event_qsample[currindex] = qsample; + vec_event_signal[currindex] = signal; + vec_event_det[currindex] = detid; + + ++currindex; + } + + // Advance to next cell + if (mditer->next()) { + // advance to next cell + mditer->jumpTo(nextindex); + ++nextindex; + } else { + // break the loop + scancell = false; + } + } + + return; +} + +//-------------------------------------------------------------------------- +/** Save Q-sample to file + */ +void ConvertCWSDMDtoHKL::saveMDToFile( + std::vector<std::vector<coord_t>> &vec_event_qsample, + std::vector<float> &vec_event_signal) { + // Get file name + std::string filename = getPropertyValue("QSampleFileName"); + + // Abort with an empty string + if (filename.size() == 0) + return; + if (vec_event_qsample.size() != vec_event_signal.size()) + throw std::runtime_error( + "Input vectors of Q-sample and signal have different sizes."); + + // Write to file + std::ofstream ofile; + ofile.open(filename.c_str()); + + size_t numevents = vec_event_qsample.size(); + for (size_t i = 0; i < numevents; ++i) { + ofile << vec_event_qsample[i][0] << ", " << vec_event_qsample[i][1] << ", " + << vec_event_qsample[i][2] << ", " << vec_event_signal[i] << "\n"; + } + ofile.close(); + + return; +} + +//-------------------------------------------------------------------------- +/** Save HKL to file for 3D visualization + */ +void ConvertCWSDMDtoHKL::saveEventsToFile( + const std::string &filename, std::vector<Kernel::V3D> &vec_event_pos, + std::vector<signal_t> &vec_event_signal, + std::vector<detid_t> &vec_event_detid) { + // Check + if (vec_event_detid.size() != vec_event_pos.size() || + vec_event_pos.size() != vec_event_signal.size()) + throw std::invalid_argument( + "Input vectors for HKL, signal and detector ID have different size."); + + std::ofstream ofile; + ofile.open(filename.c_str()); + + size_t numevents = vec_event_pos.size(); + for (size_t i = 0; i < numevents; ++i) { + ofile << vec_event_pos[i].X() << ", " << vec_event_pos[i].Y() << ", " + << vec_event_pos[i].Z() << ", " << vec_event_signal[i] << ", " + << vec_event_detid[i] << "\n"; + } + ofile.close(); + + return; +} + +//-------------------------------------------------------------------------- +/** Convert from Q-sample to HKL + */ +void ConvertCWSDMDtoHKL::convertFromQSampleToHKL( + const std::vector<V3D> &q_vectors, std::vector<V3D> &miller_indices) { + + Matrix<double> tempUB(m_UB); + + int original_indexed = 0; + double original_error = 0; + double tolerance = 0.55; // to make sure no output is invalid + original_indexed = IndexingUtils::CalculateMillerIndices( + tempUB, q_vectors, tolerance, miller_indices, original_error); + + g_log.notice() << "[DB] " << original_indexed << " peaks are indexed." + << "\n"; + + return; +} + +//---------------------------------------------------------------------------------------------- +/** Create output workspace + * @brief ConvertCWSDExpToMomentum::createExperimentMDWorkspace + * @return + */ +API::IMDEventWorkspace_sptr ConvertCWSDMDtoHKL::createHKLMDWorkspace( + const std::vector<Kernel::V3D> &vec_hkl, + const std::vector<signal_t> &vec_signal, + const std::vector<detid_t> &vec_detid) { + // Check + if (vec_hkl.size() != vec_signal.size() || + vec_signal.size() != vec_detid.size()) + throw std::invalid_argument("Input vectors for HKL, signal and detector " + "IDs are of different size!"); + + // Create workspace in Q_sample with dimenion as 3 + size_t nDimension = 3; + IMDEventWorkspace_sptr mdws = + MDEventFactory::CreateMDWorkspace(nDimension, "MDEvent"); + + // Extract Dimensions and add to the output workspace. + std::vector<std::string> vec_ID(3); + vec_ID[0] = "H"; + vec_ID[1] = "K"; + vec_ID[2] = "L"; + + std::vector<std::string> dimensionNames(3); + dimensionNames[0] = "H"; + dimensionNames[1] = "K"; + dimensionNames[2] = "L"; + + Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = + Mantid::Kernel::HKL; + + // Add dimensions + std::vector<double> m_extentMins(3); + std::vector<double> m_extentMaxs(3); + std::vector<size_t> m_numBins(3, 100); + getRange(vec_hkl, m_extentMins, m_extentMaxs); + + for (size_t i = 0; i < nDimension; ++i) { + std::string id = vec_ID[i]; + std::string name = dimensionNames[i]; + // std::string units = "A^-1"; + std::string units = ""; + mdws->addDimension( + Geometry::MDHistoDimension_sptr(new Geometry::MDHistoDimension( + id, name, units, static_cast<coord_t>(m_extentMins[i]), + static_cast<coord_t>(m_extentMaxs[i]), m_numBins[i]))); + } + + // Set coordinate system + mdws->setCoordinateSystem(coordinateSystem); + + // Creates a new instance of the MDEventInserter to output workspace + MDEventWorkspace<MDEvent<3>, 3>::sptr mdws_mdevt_3 = + boost::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(mdws); + MDEventInserter<MDEventWorkspace<MDEvent<3>, 3>::sptr> inserter(mdws_mdevt_3); + + // Go though each spectrum to conver to MDEvent + for (size_t iq = 0; iq < vec_hkl.size(); ++iq) { + Kernel::V3D hkl = vec_hkl[iq]; + std::vector<Mantid::coord_t> millerindex(3); + millerindex[0] = static_cast<float>(hkl.X()); + millerindex[1] = static_cast<float>(hkl.Y()); + millerindex[2] = static_cast<float>(hkl.Z()); + + signal_t signal = vec_signal[iq]; + signal_t error = std::sqrt(signal); + uint16_t runnumber = 1; + detid_t detid = vec_detid[iq]; + + // Insert + inserter.insertMDEvent( + static_cast<float>(signal), static_cast<float>(error * error), + static_cast<uint16_t>(runnumber), detid, millerindex.data()); + } + + return mdws; +} + +void ConvertCWSDMDtoHKL::getRange(const std::vector<Kernel::V3D> vec_hkl, + std::vector<double> &extentMins, + std::vector<double> &extentMaxs) { + assert(extentMins.size() == 3); + assert(extentMaxs.size() == 3); + + for (size_t i = 0; i < 3; ++i) { + double minvalue = vec_hkl[0][i]; + double maxvalue = vec_hkl[0][i]; + for (size_t j = 1; j < vec_hkl.size(); ++j) { + double thisvalue = vec_hkl[j][i]; + if (thisvalue < minvalue) + minvalue = thisvalue; + else if (thisvalue > maxvalue) + maxvalue = thisvalue; + } + extentMins[i] = minvalue; + extentMaxs[i] = maxvalue; + } + + return; +} + +} // namespace MDAlgorithms +} // namespace Mantid diff --git a/Framework/MDAlgorithms/test/ConvertCWSDMDtoHKLTest.h b/Framework/MDAlgorithms/test/ConvertCWSDMDtoHKLTest.h new file mode 100644 index 0000000000000000000000000000000000000000..d4044fec95e162a24b7145d0c042364eebd9943a --- /dev/null +++ b/Framework/MDAlgorithms/test/ConvertCWSDMDtoHKLTest.h @@ -0,0 +1,131 @@ +#ifndef MANTID_MDALGORITHMS_CONVERTCWSDMDTOHKLTEST_H_ +#define MANTID_MDALGORITHMS_CONVERTCWSDMDTOHKLTEST_H_ + +#include <cxxtest/TestSuite.h> + +#include "MantidMDAlgorithms/ConvertCWSDMDtoHKL.h" +#include "MantidTestHelpers/ComponentCreationHelper.h" +#include "MantidTestHelpers/WorkspaceCreationHelper.h" +#include "MantidAPI/IMDEventWorkspace.h" +#include "MantidAPI/FrameworkManager.h" +#include "MantidGeometry/Instrument.h" + +using Mantid::MDAlgorithms::ConvertCWSDMDtoHKL; + +using namespace Mantid::API; +using namespace Mantid::MDAlgorithms; +using namespace Mantid::DataObjects; +using Mantid::Geometry::Instrument_sptr; +using Mantid::Kernel::PropertyWithValue; + +class ConvertCWSDMDtoHKLTest : public CxxTest::TestSuite { +public: + // This pair of boilerplate methods prevent the suite being created statically + // This means the constructor isn't called when running other tests + static ConvertCWSDMDtoHKLTest *createSuite() { + return new ConvertCWSDMDtoHKLTest(); + } + static void destroySuite(ConvertCWSDMDtoHKLTest *suite) { delete suite; } + + //------------------------------------------------------------------------------- + void test_init() { + createMDEW(); + + ConvertCWSDMDtoHKL alg; + alg.initialize(); + TS_ASSERT(alg.isInitialized()); + } + + //------------------------------------------------------------------------------- + void test_convertToHKL() { + ConvertCWSDMDtoHKL alg; + alg.initialize(); + + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("InputWorkspace", m_qsampleWS->name())); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue( + "UBMatrix", "1.0, 0.5, 0., -0.2, 2.0, 0.4, 0., 1.11, 3.9")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", "HKLMD")); + + alg.execute(); + TS_ASSERT(alg.isExecuted()); + + IMDEventWorkspace_sptr hklws = + boost::dynamic_pointer_cast<IMDEventWorkspace>( + AnalysisDataService::Instance().retrieve("HKLMD")); + TS_ASSERT(hklws); + + size_t numevents = hklws->getNEvents(); + TS_ASSERT_EQUALS(numevents, 100); + + TS_ASSERT_EQUALS(hklws->getSpecialCoordinateSystem(), + Mantid::Kernel::SpecialCoordinateSystem::HKL); + } + +private: + //------------------------------------------------------------------------------- + /** Create the (blank) MDEW */ + void createMDEW() { + // ---- Start with empty MDEW ---- + FrameworkManager::Instance().exec( + "CreateMDWorkspace", 18, "Dimensions", "3", "EventType", "MDEvent", + "Extents", "-10,10,-10,10,-10,10", "Names", + "Q_sample_x,Q_sample_y,Q_sample_z", "Units", + "Q_Sample_X,Q_Sample_Y,Q_Sample_Z", "SplitInto", "5", "SplitThreshold", + "20", "MaxRecursionDepth", "15", "OutputWorkspace", "MDEWS"); + + // Give it an instrument + Instrument_sptr inst = + ComponentCreationHelper::createTestInstrumentRectangular2(1, 100, 0.05); + + TS_ASSERT_THROWS_NOTHING( + m_qsampleWS = + AnalysisDataService::Instance().retrieveWS<IMDEventWorkspace>( + "MDEWS")); + ExperimentInfo_sptr ei(new ExperimentInfo()); + ei->setInstrument(inst); + // Give it a run number + ei->mutableRun().addProperty( + new PropertyWithValue<std::string>("run_number", "12345"), true); + m_qsampleWS->addExperimentInfo(ei); + + // Add events + size_t num_events = 100; + double peakcentre_x = 0.4; + double peakcentre_y = -1.2; + double peakcentre_z = -1.0; + double radius = 0.5; + + // Add half of the events + std::ostringstream mess; + mess << num_events / 2 << ", " << peakcentre_x << ", " << peakcentre_y + << ", " << peakcentre_z << ", " << radius; + std::cout << mess.str() << "\n"; + FrameworkManager::Instance().exec("FakeMDEventData", 4, "InputWorkspace", + "MDEWS", "PeakParams", + mess.str().c_str()); + + // Add a center with more events (half radius, half the total), to create a + // "peak" + std::ostringstream mess2; + mess2 << num_events / 2 << ", " << peakcentre_x << ", " << peakcentre_y + << ", " << peakcentre_z << ", " << radius * 0.25; + std::cout << mess2.str() << "\n"; + FrameworkManager::Instance().exec("FakeMDEventData", 4, "InputWorkspace", + "MDEWS", "PeakParams", + mess2.str().c_str()); + + // Check + size_t numevents = m_qsampleWS->getNEvents(); + TS_ASSERT_EQUALS(numevents, 100); + + m_qsampleWS->setCoordinateSystem( + Mantid::Kernel::SpecialCoordinateSystem::QSample); + + return; + } + + IMDEventWorkspace_sptr m_qsampleWS; +}; + +#endif /* MANTID_MDALGORITHMS_CONVERTCWSDMDTOHKLTEST_H_ */ diff --git a/Testing/Data/DocTest/HB3A_exp0406_scan0298.dat.md5 b/Testing/Data/DocTest/HB3A_exp0406_scan0298.dat.md5 new file mode 100644 index 0000000000000000000000000000000000000000..1d23995b3815a9e8457c03d0277dbe8457626dbe --- /dev/null +++ b/Testing/Data/DocTest/HB3A_exp0406_scan0298.dat.md5 @@ -0,0 +1 @@ +82a989552a9d6b41fb0d477b3e26b57a diff --git a/Testing/Data/DocTest/HB3A_exp406_scan0298_0022.xml.md5 b/Testing/Data/DocTest/HB3A_exp406_scan0298_0022.xml.md5 new file mode 100644 index 0000000000000000000000000000000000000000..b02a2cacffa806501e5c08426083152fa419e1f8 --- /dev/null +++ b/Testing/Data/DocTest/HB3A_exp406_scan0298_0022.xml.md5 @@ -0,0 +1 @@ +9891ad8c3a37213308ccb8ba9500989f diff --git a/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst new file mode 100644 index 0000000000000000000000000000000000000000..9c0672885f008b441c70c8aad1285801ff1aa9e5 --- /dev/null +++ b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst @@ -0,0 +1,108 @@ +.. algorithm:: + +.. summary:: + +.. alias:: + +.. properties:: + +Description +----------- + +This algorithms is to convert an MDEventWorkspace in Q-sample coordinate +to HKL coordindate for a reactor-based four-circle single crystal diffractometer. +Meanwhile, the algorithm is able to export the MDEvents to file. + +Outline of algorithm +#################### + +1. Convert MDEvent's coordinate system + +2. Export MDEvent in Q-sample coordinate and HKL coordinate. + + +Inputs +###### + +**InputWorkspace** is an MDEventWorkspace ???. + +**PeakWorkspace** is an optional input as in many cases especially after calculating UB matrix, ... + +**UBMatrix** is ???. + + +Outputs +####### + +The output is an MDEventWorkspace that... .. + +MDEvent ++++++++ + +Each MDEvent in output MDEventWorkspace contain +* *H* +* *K* +* *L* +* Signal +* Error +* Detector ID +* Run Number + +Compare with ConvertMD +====================== + +Comparing with ???? + +Usage +----- + +**Example - Convert detector counts of an HB3A's measurement to HKL.** + +.. testcode:: ExConvertHB3AToHKL + + # Create input table workspaces for experiment information and virtual instrument parameters + CollectHB3AExperimentInfo(ExperimentNumber='406', ScanList='298', PtLists='-1,22', + DataDirectory='', + GenerateVirtualInstrument=False, + OutputWorkspace='ExpInfoTable', DetectorTableWorkspace='VirtualInstrumentTable') + + # Convert to MDWorkspace + ConvertCWSDExpToMomentum(InputWorkspace='ExpInfoTable', CreateVirtualInstrument=False, + OutputWorkspace='QSampleMD', + Directory='') + + ConvertCWSDMDtoHKL(InputWorkspace='QSampleMD', + UBMatrix='0.13329061, 0.07152342, -0.04215966, 0.01084569, -0.1620849, 0.0007607, -0.14018499, -0.07841385, -0.04002737', + OutputWorkspace='HKLMD') + + + # Examine + mdws = mtd['QSampleMD'] + print 'Output MDEventWorkspace has %d events.'%(mdws.getNEvents()) + + hklws = mtd['HKLMD'] + print 'H: range from %.5f to %.5f.' % (hklws.getXDimension().getMinimum(), hklws.getXDimension().getMaximum()) + print 'K: range from %.5f to %.5f.' % (hklws.getYDimension().getMinimum(), hklws.getYDimension().getMaximum()) + print 'L: range from %.5f to %.5f.' % (hklws.getZDimension().getMinimum(), hklws.getZDimension().getMaximum()) + +.. testcleanup:: ExConvertHB3AToHKL + + DeleteWorkspace(Workspace='QSampleMD') + DeleteWorkspace(Workspace='ExpInfoTable') + DeleteWorkspace(Workspace='VirtualInstrumentTable') + DeleteWorkspace(Workspace='HKLMD') + DeleteWorkspace(Workspace='HB3A_exp0406_scan0298') + DeleteWorkspace(Workspace='spicematrixws') + +Output: + +.. testoutput:: ExConvertHB3AToHKL + + Output MDEventWorkspace has 1631 events. + H: range from -0.24012 to 0.29856. + K: range from -0.41417 to 0.42250. + L: range from 4.83863 to 7.23861. + +.. categories:: + +.. sourcelink::