From 6dab661ded9c2c7b555ccb05913a55db0f89bef6 Mon Sep 17 00:00:00 2001 From: Wenduo Zhou Date: Mon, 9 Mar 2015 07:22:14 -0400 Subject: [PATCH 1/5] Refs #11282. Fixed some issues related to reduce HFIR data. 1. LoadSpiceAscii has date time format with default to SPICE's current standard 2. ConvertCWPDMDToSpectra is explained in the sumary; 3. Binning parameters can accept bin size only in ConvertCWPDMDToSpectra. Xmin and Xmax will be searched automatically. - modified: ../Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp - modified: ../Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h - modified: ../Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp - modified: ../Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h --- .../DataHandling/src/LoadSpiceAscii.cpp | 18 +- .../ConvertCWPDMDToSpectra.h | 14 +- .../src/ConvertCWPDMDToSpectra.cpp | 159 +++++++++++++++++- .../test/ConvertCWPDMDToSpectraTest.h | 49 +++++- 4 files changed, 224 insertions(+), 16 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp index 55c0d34ca3a5..879dbb975bc0 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp @@ -129,8 +129,16 @@ void LoadSpiceAscii::init() { "Otherwise, any log name is not listed will be treated as " "string property."); - declareProperty(new ArrayProperty("DateAndTimeLog"), - "Name and format for date and time"); + // date: MM/DD/YYYY,time: HH:MM:SS AM is the standard SPICE date time log name + // and format + std::vector defaultlogformat(4); + defaultlogformat[0] = "date"; + defaultlogformat[1] = "MM/DD/YYYY"; + defaultlogformat[2] = "time"; + defaultlogformat[3] = "HH:MM:SS AM"; + declareProperty( + new ArrayProperty("DateAndTimeLog", defaultlogformat), + "Name and format for date and time"); // Output declareProperty(new WorkspaceProperty("OutputWorkspace", "", @@ -461,8 +469,10 @@ void LoadSpiceAscii::setupRunStartTime( runinfows->run().hasProperty(timelogname))) { std::stringstream errss; errss << "Unable to locate user specified date and time sample logs " - << datelogname << " and " << timelogname << "."; - throw std::runtime_error(errss.str()); + << datelogname << " and " << timelogname << "." + << "run_start will not be set up."; + g_log.error(errss.str()); + return; } const std::string &rawdatestring = diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h index 453b48e60951..b2176621470c 100644 --- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h +++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h @@ -108,8 +108,12 @@ class DLLExport ConvertCWPDMDToSpectra : public API::Algorithm { /// Summary of algorithms purpose virtual const std::string summary() const { - return "Binning the constant wavelength powder diffracton data stored in " - "MDWorkspaces to single spectrum."; + return "Convert constant wavelength (CW) powder diffraction (PD) data in " + "MDEventWorksapces " + " to a single-spectrum MatrixWorkspace, i.e., binning the " + "diffraction data " + " to single spectrum according to neutron's scattering angle, " + "d-spacing or Q. "; } /// Algorithm's version @@ -134,6 +138,12 @@ class DLLExport ConvertCWPDMDToSpectra : public API::Algorithm { const std::map &map_runwavelength, const double xmin, const double xmax, const double binsize, bool dolinearinterpolation); + /// Find the binning boundary according to detectors' positions + void findXBoundary(API::IMDEventWorkspace_const_sptr dataws, + const std::string &targetunit, + const std::map &map_runwavelength, + double &xmin, double &xmax); + /// Bin signals to its 2theta position void binMD(API::IMDEventWorkspace_const_sptr mdws, const char &unitbit, const std::map &map_runlambda, diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp index 6edfe95bb132..7812c2705115 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp @@ -15,6 +15,8 @@ using namespace Mantid::MDAlgorithms; DECLARE_ALGORITHM(ConvertCWPDMDToSpectra) +const double BIGNUMBER = 1.0E100; + //---------------------------------------------------------------------------------------------- /** Constructor */ @@ -140,16 +142,33 @@ void ConvertCWPDMDToSpectra::exec() { } // bin parameters - if (binParams.size() != 3) - throw std::runtime_error("Binning parameters must have 3 items."); - if (binParams[0] >= binParams[2]) + double xmin, xmax, binsize; + xmin = xmax = binsize = -1; + if (binParams.size() == 1) { + binsize = binParams[0]; + g_log.warning() + << "Only bin size " << binParams[0] + << " is specified. Xmin and Xmax " + " will be calcualted from motor positions and wavelength. " + "More CPU time will be used." + << "\n"; + } else if (binParams.size() == 3) { + xmin = binParams[0]; + binsize = binParams[1]; + xmax = binParams[2]; + if (xmin >= xmax) + throw std::runtime_error( + "Min value of the bin must be smaller than maximum value."); + } else { + // Either 1 or 3 parameters. Throw exception throw std::runtime_error( - "Min value of the bin must be smaller than maximum value."); + "Binning parameters must have either 1 or 3 items."); + } // Rebin API::MatrixWorkspace_sptr outws = reducePowderData( - inputDataWS, inputMonitorWS, outputunit, map_runWavelength, binParams[0], - binParams[2], binParams[1], doLinearInterpolation); + inputDataWS, inputMonitorWS, outputunit, map_runWavelength, xmin, xmax, + binsize, doLinearInterpolation); // Scale scaleMatrixWorkspace(outws, scaleFactor, m_infitesimal); @@ -188,9 +207,24 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( // Get some information int64_t numevents = dataws->getNEvents(); + // check xmin and xmax + double lowerboundary, upperboundary; + if (xmin < 0 || xmax < 0) { + // xmin or xmax cannot be negative (2theta, dspace and q are always + // positive) + findXBoundary(dataws, targetunit, map_runwavelength, lowerboundary, + upperboundary); + } else { + lowerboundary = xmin; + upperboundary = xmax; + } + + g_log.notice() << "[DB] Binning from " << lowerboundary << " to " + << upperboundary << "\n"; + // Create bins in 2theta (degree) size_t sizex, sizey; - sizex = static_cast((xmax - xmin) / binsize + 0.5); + sizex = static_cast((upperboundary - lowerboundary) / binsize + 0.5); sizey = sizex - 1; g_log.debug() << "Number of events = " << numevents << "bin size = " << binsize << ", SizeX = " << sizex << ", " @@ -199,7 +233,7 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( vece(sizex - 1, 0); for (size_t i = 0; i < sizex; ++i) { - vecx[i] = xmin + static_cast(i) * binsize; + vecx[i] = lowerboundary + static_cast(i) * binsize; } // Convert unit to unit char bit @@ -270,6 +304,115 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( return pdws; } +//---------------------------------------------------------------------------------------------- +/** Find the binning boundaries for 2theta (det position), d-spacing or Q. + * @brief ConvertCWPDMDToSpectra::findXBoundary + * @param dataws + * @param targetunit + * @param wavelength + * @param xmin :: (output) lower binning boundary + * @param xmax :: (output) upper binning boundary + */ +void ConvertCWPDMDToSpectra::findXBoundary( + API::IMDEventWorkspace_const_sptr dataws, const std::string &targetunit, + const std::map &map_runwavelength, double &xmin, + double &xmax) { + // Go through all instruments + uint16_t numruns = dataws->getNumExperimentInfo(); + g_log.notice() << "[DB] Tota number of ExperimentInfo = " << numruns << "\n"; + + xmin = BIGNUMBER; + xmax = -1; + + for (uint16_t irun = 0; irun < numruns; ++irun) { + // Skip the Experiment Information does not have run + if (!dataws->getExperimentInfo(irun)->getInstrument()) { + g_log.warning() << "iRun = " << irun << " of total " << numruns + << " does not have instrument associated" + << "\n"; + continue; + } + + // Get run number + int runnumber = dataws->getExperimentInfo(irun)->getRunNumber(); + g_log.notice() << "Run " << runnumber << ": "; + std::map::const_iterator miter = + map_runwavelength.find(runnumber); + double wavelength = -1; + if (miter != map_runwavelength.end()) { + wavelength = miter->second; + g_log.notice() << " wavelength = " << wavelength << "\n"; + } else { + g_log.notice() << " no matched wavelength." + << "\n"; + } + + // Get source and sample position + std::vector vec_detid = + dataws->getExperimentInfo(irun)->getInstrument()->getDetectorIDs(true); + if (vec_detid.size() == 0) { + g_log.notice() << "[DB] Run " << runnumber << " has no detectors." + << "\n"; + continue; + } + const V3D samplepos = + dataws->getExperimentInfo(irun)->getInstrument()->getSample()->getPos(); + const V3D sourcepos = + dataws->getExperimentInfo(irun)->getInstrument()->getSource()->getPos(); + + // Get all detectors + // std::vector vec_detid = + // dataws->getExperimentInfo(irun)->getInstrument()->getDetectorIDs(true); + std::vector vec_det = + dataws->getExperimentInfo(irun)->getInstrument()->getDetectors( + vec_detid); + size_t numdets = vec_det.size(); + g_log.notice() << "[DB] Run = " << runnumber + << ": Number of detectors = " << numdets << "\n"; + + // Scan all the detectors to get Xmin and Xmax + for (size_t idet = 0; idet < numdets; ++idet) { + Geometry::IDetector_const_sptr tmpdet = vec_det[idet]; + const V3D detpos = tmpdet->getPos(); + + double R, theta, phi; + detpos.getSpherical(R, theta, phi); + if (R < 0.0001) + g_log.error("Invalid detector position"); + + Kernel::V3D v_det_sample = detpos - samplepos; + Kernel::V3D v_sample_src = samplepos - sourcepos; + double twotheta = + calculate2Theta(v_det_sample, v_sample_src) / M_PI * 180.; + + // convert unit optionally + double outx = -1; + if (targetunit.compare("2tehta") == 0) + outx = twotheta; + else { + if (wavelength <= 0) + throw std::runtime_error("Wavelength is not defined!"); + + if (targetunit.compare("dSpacing") == 0) + outx = calculateDspaceFrom2Theta(twotheta, wavelength); + else if (targetunit.compare("Q") == 0) + outx = calculateQFrom2Theta(twotheta, wavelength); + else + throw std::runtime_error("Unrecognized unit."); + } + + // Compare with xmin and xmax + if (outx < xmin) + xmin = outx; + else if (outx > xmax) + xmax = outx; + } + } + + g_log.notice() << "[DB] Auto boundary: [" << xmin << ", " << xmax << "]" + << "\n"; +} + //---------------------------------------------------------------------------------------------- /** Bin MD Workspace for detector's position at 2theta * @brief ConvertCWPDMDToSpectra::binMD diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h index a88676e9c523..57d2922c12b7 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h @@ -38,7 +38,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { /** Unit test to reduce/bin the HB2A data * @brief test_ReduceHB2AData */ - void test_ReduceHB2AData() { + void Ptest_ReduceHB2AData() { // Init ConvertCWPDMDToSpectra alg; alg.initialize(); @@ -100,7 +100,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { /** Unit test to reduce/bin the HB2A data with more options * @brief test_ReduceHB2AData */ - void test_ReduceHB2ADataMoreOptions() { + void Ptest_ReduceHB2ADataMoreOptions() { // Init ConvertCWPDMDToSpectra alg; alg.initialize(); @@ -139,6 +139,51 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { // Check statistics + // Clean + AnalysisDataService::Instance().remove("ReducedData"); + } + + //---------------------------------------------------------------------------------------------- + /** Unit test to reduce/bin the HB2A data with more options + * @brief test_ReduceHB2AData + */ + void test_ReduceHB2ADataAutoBinBoundary() { + // Init + ConvertCWPDMDToSpectra alg; + alg.initialize(); + + // Set properties + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("InputWorkspace", m_dataMD->name())); + TS_ASSERT_THROWS_NOTHING( + alg.setPropertyValue("InputMonitorWorkspace", m_monitorMD->name())); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("UnitOutput", "dSpacing")); + TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("BinningParams", "0.01")); + TS_ASSERT_THROWS_NOTHING( + alg.setProperty("LinearInterpolateZeroCounts", true)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("ScaleFactor", 10.0)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("NeutronWaveLength", 2.41)); + TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "ReducedData")); + + // Execute + TS_ASSERT_THROWS_NOTHING(alg.execute()); + TS_ASSERT(alg.isExecuted()); + + // Get ouput + MatrixWorkspace_sptr outws = boost::dynamic_pointer_cast( + AnalysisDataService::Instance().retrieve("ReducedData")); + TS_ASSERT(outws); + + // Check unit and range of X + std::string unit = outws->getAxis(0)->unit()->unitID(); + TS_ASSERT_EQUALS(unit, "dSpacing"); + + const Mantid::MantidVec &vecX = outws->readX(0); + TS_ASSERT_DELTA(vecX.front(), 0.5, 0.0001); + TS_ASSERT_DELTA(vecX.back(), 4.99, 0.0001); + + // Check statistics + // Clean AnalysisDataService::Instance().remove("ReducedData"); From efe1ecf9736de56e43736b48833a36c77a0ff7f4 Mon Sep 17 00:00:00 2001 From: Wenduo Zhou Date: Mon, 9 Mar 2015 13:05:51 -0400 Subject: [PATCH 2/5] Refs #11282. Implemented unit Degrees. And added unit test for it. Fixed a bug about MomentumTransfer in ConvertCWPDMDToSpectra. Use Degrees for output workspace if target unit is 2theta for ConvertCWPDMDToSpectra. --- .../Framework/Kernel/inc/MantidKernel/Unit.h | 12 ++++++--- Code/Mantid/Framework/Kernel/src/Unit.cpp | 26 +++++++++++++++++++ Code/Mantid/Framework/Kernel/test/UnitTest.h | 6 +++++ .../src/ConvertCWPDMDToSpectra.cpp | 15 ++++------- .../test/ConvertCWPDMDToSpectraTest.h | 6 ++--- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h index f29c7b254576..6f563faea76b 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h @@ -616,11 +616,17 @@ class MANTID_KERNEL_DLL Time : public Unit { class MANTID_KERNEL_DLL Degrees : public Empty { public: Degrees(); - const std::string unitID() const { return ""; } - virtual const std::string caption() const { return "Scattering angle"; } + const std::string unitID() const; /// < Degrees + const std::string caption() const { return "Scattering angle"; } const UnitLabel label() const; - virtual Unit *clone() const { return new Degrees(*this); } + virtual void init(); + virtual Unit *clone() const; + + virtual double singleToTOF(const double x) const; + virtual double singleFromTOF(const double tof) const; + virtual double conversionTOFMin() const; + virtual double conversionTOFMax() const; private: UnitLabel m_label; diff --git a/Code/Mantid/Framework/Kernel/src/Unit.cpp b/Code/Mantid/Framework/Kernel/src/Unit.cpp index c9e0c0ead29f..82e3541bc80d 100644 --- a/Code/Mantid/Framework/Kernel/src/Unit.cpp +++ b/Code/Mantid/Framework/Kernel/src/Unit.cpp @@ -1122,10 +1122,36 @@ Unit *Time::clone() const { return new Time(*this); } * Degrees prints degrees as a label */ +DECLARE_UNIT(Degrees) + Degrees::Degrees() : Empty(), m_label("degrees") {} const UnitLabel Degrees::label() const { return m_label; } +void Degrees::init() {} + +double Degrees::singleToTOF(const double x) const { + UNUSED_ARG(x); + throw std::runtime_error("Degrees is not allowed to be convert to TOF. "); + return 0.0; +} + +double Degrees::singleFromTOF(const double tof) const { + UNUSED_ARG(tof); + throw std::runtime_error("Degrees is not allwed to be converted from TOF. "); + return 0.0; +} + +double Degrees::conversionTOFMax() const { + return std::numeric_limits::quiet_NaN(); +} + +double Degrees::conversionTOFMin() const { + return std::numeric_limits::quiet_NaN(); +} + +Unit *Degrees::clone() const { return new Degrees(*this); } + } // namespace Units } // namespace Kernel diff --git a/Code/Mantid/Framework/Kernel/test/UnitTest.h b/Code/Mantid/Framework/Kernel/test/UnitTest.h index 6439181b2c1e..cfa80847cb10 100644 --- a/Code/Mantid/Framework/Kernel/test/UnitTest.h +++ b/Code/Mantid/Framework/Kernel/test/UnitTest.h @@ -1325,6 +1325,11 @@ class UnitTest : public CxxTest::TestSuite } + /// Test unit Degress + void testDegress() { + TS_ASSERT_EQUALS(degrees.caption(), "Scattering angle"); + TS_ASSERT_EQUALS(degrees.unitID(), "Degrees"); + } private: Units::Label label; @@ -1340,6 +1345,7 @@ class UnitTest : public CxxTest::TestSuite Units::Momentum k_i; Units::SpinEchoLength delta; Units::SpinEchoTime tau; + Units::Degrees degrees; }; #endif /*UNITTEST_H_*/ diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp index 7812c2705115..fac8f3dbfeca 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp @@ -55,7 +55,7 @@ void ConvertCWPDMDToSpectra::init() { std::vector vecunits; vecunits.push_back("2theta"); vecunits.push_back("dSpacing"); - vecunits.push_back("Momenum Transfer (Q)"); + vecunits.push_back("Momentum Transfer (Q)"); auto unitval = boost::make_shared >(vecunits); declareProperty("UnitOutput", "2theta", unitval, "Unit of the output workspace."); @@ -240,7 +240,7 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( char unitchar = 't'; // default 2theta if (targetunit.compare("dSpacing") == 0) unitchar = 'd'; - else if (targetunit.compare("Momenum Transfer (Q)") == 0) + else if (targetunit.compare("Momentum Transfer (Q)") == 0) unitchar = 'q'; binMD(dataws, unitchar, map_runwavelength, vecx, vecy); @@ -277,12 +277,7 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( pdws->getAxis(0)->setUnit("MomentumTransfer"); else { // Twotheta - Unit_sptr xUnit = pdws->getAxis(0)->unit(); - if (xUnit) { - g_log.warning("Unable to set unit to an Unit::Empty object."); - } else { - throw std::runtime_error("Unable to get unit from Axis(0)"); - } + pdws->getAxis(0)->setUnit("Degrees"); } MantidVec &dataX = pdws->dataX(0); @@ -387,7 +382,7 @@ void ConvertCWPDMDToSpectra::findXBoundary( // convert unit optionally double outx = -1; - if (targetunit.compare("2tehta") == 0) + if (targetunit.compare("2theta") == 0) outx = twotheta; else { if (wavelength <= 0) @@ -395,7 +390,7 @@ void ConvertCWPDMDToSpectra::findXBoundary( if (targetunit.compare("dSpacing") == 0) outx = calculateDspaceFrom2Theta(twotheta, wavelength); - else if (targetunit.compare("Q") == 0) + else if (targetunit.compare("Momentum Transfer (Q)") == 0) outx = calculateQFrom2Theta(twotheta, wavelength); else throw std::runtime_error("Unrecognized unit."); diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h index 57d2922c12b7..36bbb7886a48 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h @@ -38,7 +38,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { /** Unit test to reduce/bin the HB2A data * @brief test_ReduceHB2AData */ - void Ptest_ReduceHB2AData() { + void test_ReduceHB2AData() { // Init ConvertCWPDMDToSpectra alg; alg.initialize(); @@ -100,7 +100,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { /** Unit test to reduce/bin the HB2A data with more options * @brief test_ReduceHB2AData */ - void Ptest_ReduceHB2ADataMoreOptions() { + void test_ReduceHB2ADataMoreOptions() { // Init ConvertCWPDMDToSpectra alg; alg.initialize(); @@ -147,7 +147,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { /** Unit test to reduce/bin the HB2A data with more options * @brief test_ReduceHB2AData */ - void test_ReduceHB2ADataAutoBinBoundary() { + void Ttest_ReduceHB2ADataAutoBinBoundary() { // Init ConvertCWPDMDToSpectra alg; alg.initialize(); From a067b1b8d38540e7685854e567daffb96aa0a6ba Mon Sep 17 00:00:00 2001 From: Wenduo Zhou Date: Mon, 9 Mar 2015 16:24:44 -0400 Subject: [PATCH 3/5] Fixed a bug in LoadSpiceAscii's doc. Refs #11282. --- .../source/algorithms/LoadSpiceAscii-v1.rst | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst b/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst index ddbdd07345bf..4f91c1e8c1bd 100644 --- a/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst +++ b/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst @@ -55,7 +55,10 @@ Usage print "Number of measuring points = %d" % (datatbws.rowCount()) print "Number of columns in data workspace = %d" % (datatbws.columnCount()) - print "Number of run information = %d" % (len(infows.getRun().getProperties())) + propertylist = infows.getRun().getProperties() + print "Number of run information = %d" % (len(propertylist)) + for i in xrange(len(propertylist)): + print "Property %d: Name = %-20s." % (i, propertylist[i].name) print "Sum of Counts = %d" % (infows.getRun().getProperty("Sum of Counts").value) print "Center of Mass = %.5f +/- %.5f" % (infows.getRun().getProperty("Center of Mass").value, infows.getRun().getProperty("Center of Mass.error").value) @@ -71,7 +74,42 @@ Output: Number of measuring points = 61 Number of columns in data workspace = 70 - Number of run information = 34 + Number of run information = 35 + Property 0: Name = Center of Mass . + Property 1: Name = Center of Mass.error. + Property 2: Name = Full Width Half-Maximum. + Property 3: Name = Full Width Half-Maximum.error. + Property 4: Name = Sum of Counts . + Property 5: Name = analyzer . + Property 6: Name = builtin_command . + Property 7: Name = col_headers . + Property 8: Name = collimation . + Property 9: Name = command . + Property 10: Name = date . + Property 11: Name = def_x . + Property 12: Name = def_y . + Property 13: Name = experiment . + Property 14: Name = experiment_number . + Property 15: Name = latticeconstants . + Property 16: Name = local_contact . + Property 17: Name = mode . + Property 18: Name = monochromator . + Property 19: Name = preset_channel . + Property 20: Name = preset_type . + Property 21: Name = preset_value . + Property 22: Name = proposal . + Property 23: Name = runend . + Property 24: Name = samplemosaic . + Property 25: Name = samplename . + Property 26: Name = sampletype . + Property 27: Name = scan . + Property 28: Name = scan_title . + Property 29: Name = sense . + Property 30: Name = time . + Property 31: Name = ubconf . + Property 32: Name = ubmatrix . + Property 33: Name = users . + Property 34: Name = run_start . Sum of Counts = 1944923 Center of Mass = 9.00076 +/- 0.00921 From 3614b9afa19f52e8080963e116f5a0e07aba5e81 Mon Sep 17 00:00:00 2001 From: Wenduo Zhou Date: Thu, 12 Mar 2015 16:23:21 -0400 Subject: [PATCH 4/5] Refs #11282. Fixed some issue on bin boundary. --- .../src/ConvertCWPDMDToSpectra.cpp | 126 ++++++++++++++---- .../test/ConvertCWPDMDToSpectraTest.h | 10 +- 2 files changed, 102 insertions(+), 34 deletions(-) diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp index fac8f3dbfeca..14897539f81d 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp @@ -224,11 +224,16 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( // Create bins in 2theta (degree) size_t sizex, sizey; - sizex = static_cast((upperboundary - lowerboundary) / binsize + 0.5); + sizex = static_cast((upperboundary - lowerboundary) / binsize + 1); + if (lowerboundary + static_cast(sizex)*binsize < upperboundary) + ++ lowerboundary; + sizey = sizex - 1; - g_log.debug() << "Number of events = " << numevents - << "bin size = " << binsize << ", SizeX = " << sizex << ", " - << ", SizeY = " << sizey << "\n"; + g_log.notice() << "[DB] Number of events = " << numevents + << ", bin size = " << binsize << ", SizeX = " << sizex << ", " + << ", SizeY = " << sizey << ", Delta = " << upperboundary - lowerboundary + << ", Bin size = " << binsize << ", sizex_d = " + << (upperboundary - lowerboundary) / binsize + 2 << "\n"; std::vector vecx(sizex), vecy(sizex - 1, 0), vecm(sizex - 1, 0), vece(sizex - 1, 0); @@ -330,15 +335,15 @@ void ConvertCWPDMDToSpectra::findXBoundary( // Get run number int runnumber = dataws->getExperimentInfo(irun)->getRunNumber(); - g_log.notice() << "Run " << runnumber << ": "; + g_log.debug() << "Run " << runnumber << ": "; std::map::const_iterator miter = map_runwavelength.find(runnumber); double wavelength = -1; if (miter != map_runwavelength.end()) { wavelength = miter->second; - g_log.notice() << " wavelength = " << wavelength << "\n"; + g_log.debug() << " wavelength = " << wavelength << "\n"; } else { - g_log.notice() << " no matched wavelength." + g_log.debug() << " no matched wavelength." << "\n"; } @@ -362,8 +367,8 @@ void ConvertCWPDMDToSpectra::findXBoundary( dataws->getExperimentInfo(irun)->getInstrument()->getDetectors( vec_detid); size_t numdets = vec_det.size(); - g_log.notice() << "[DB] Run = " << runnumber - << ": Number of detectors = " << numdets << "\n"; + g_log.debug() << "Run = " << runnumber + << ": Number of detectors = " << numdets << "\n"; // Scan all the detectors to get Xmin and Xmax for (size_t idet = 0; idet < numdets; ++idet) { @@ -396,15 +401,23 @@ void ConvertCWPDMDToSpectra::findXBoundary( throw std::runtime_error("Unrecognized unit."); } + if (runnumber == 1 && (idet == 1 || idet == 0)) + { + g_log.notice() << "[DB] run = " << runnumber << ", ID = " << idet + << ", Pos = " << detpos.X() << ", " << detpos.Y() << ", " + << detpos.Z() << ", d = " << outx << "\n"; + } + // Compare with xmin and xmax if (outx < xmin) xmin = outx; - else if (outx > xmax) + if (outx > xmax) xmax = outx; } } - g_log.notice() << "[DB] Auto boundary: [" << xmin << ", " << xmax << "]" + + g_log.debug() << "Find boundary for unit " << targetunit << ": [" << xmin << ", " << xmax << "]" << "\n"; } @@ -497,27 +510,82 @@ void ConvertCWPDMDToSpectra::binMD(API::IMDEventWorkspace_const_sptr mdws, } // get signal and assign signal to bin - double signal = mditer->getInnerSignal(iev); - std::vector::const_iterator vfiter = - std::lower_bound(vecx.begin(), vecx.end(), outx); - int xindex = static_cast(vfiter - vecx.begin()); + int xindex; + const double SMALL = 1.0E-5; + if (outx+SMALL < vecx.front()) + { + // Significantly out of left boundary + xindex = -1; + } + else if (fabs(outx - vecx.front()) < SMALL) + { + // Almost on the left boundary + xindex = 0; + } + else if (outx-SMALL > vecx.back()) + { + // Significantly out of right boundary + xindex = static_cast(vecx.size()); + } + else if (fabs(outx-vecx.back()) < SMALL) + { + // Right on the right boundary + xindex = static_cast(vecy.size())-1; + } + else + { + // Other situation + std::vector::const_iterator vfiter = + std::lower_bound(vecx.begin(), vecx.end(), outx); + xindex = static_cast(vfiter - vecx.begin()); + if ( (xindex < static_cast(vecx.size())) && (outx + 1.0E-5 < vecx[xindex]) ) + { + // assume the bin's boundaries are of [...) and consider numerical error + xindex -= 1; + } + else + { + g_log.notice() << "[DB] .. almost same. Event X = " << outx << ", Boundary = " << vecx[xindex] << "\n"; + } + if (xindex < 0 || xindex >= static_cast(vecy.size())) + { + g_log.notice() << "[DB] ... weird...... Event X = " << outx << ", Boundary = " << vecx[xindex] << "\n"; + } + } + + // add signal if (xindex < 0) - g_log.warning("xindex < 0"); - if (xindex >= static_cast(vecy.size()) - 1) { - // If the Xmax is set too narrow, then - g_log.information() << "Event is out of user-specified range " - << "xindex = " << xindex << ", " << unitbit << " = " - << outx << " out of [" << vecx.front() << ", " - << vecx.back() << "]. dep pos = " << detpos.X() - << ", " << detpos.Y() << ", " << detpos.Z() - << "; sample pos = " << samplepos.X() << ", " - << samplepos.Y() << ", " << samplepos.Z() << "\n"; + { + // Out of left boundary + int32_t detid = mditer->getInnerDetectorID(iev); + uint16_t runid = mditer->getInnerRunIndex(iev); + g_log.debug() << "Event is out of user-specified range by " << (outx-vecx.front()) + << ", xindex = " << xindex << ", " << unitbit << " = " + << outx << " out of left boundeary [" << vecx.front() << ", " + << vecx.back() << "]. dep pos = " << detpos.X() + << ", " << detpos.Y() << ", " << detpos.Z() + << ", Run = " << runid << ", DetectorID = " << detid << "\n"; continue; } - - if (xindex > 0 && outx < *vfiter) - xindex -= 1; - vecy[xindex] += signal; + else if (xindex >= static_cast(vecy.size())) { + // Out of right boundary + int32_t detid = mditer->getInnerDetectorID(iev); + uint16_t runid = mditer->getInnerRunIndex(iev); + g_log.debug() << "Event is out of user-specified range " + << "xindex = " << xindex << ", " << unitbit << " = " + << outx << " out of [" << vecx.front() << ", " + << vecx.back() << "]. dep pos = " << detpos.X() + << ", " << detpos.Y() << ", " << detpos.Z() + << "; sample pos = " << samplepos.X() << ", " + << samplepos.Y() << ", " << samplepos.Z() + << ", Run = " << runid << ", DetectorID = " << detid << "\n"; + continue; + } + else + { + double signal = mditer->getInnerSignal(iev); + vecy[xindex] += signal; + } } // Advance to next cell diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h index 36bbb7886a48..990a75d4299a 100644 --- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h +++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h @@ -73,7 +73,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { const Mantid::MantidVec &vecE = outws->readE(0); TS_ASSERT_DELTA(vecX.front(), 0.0, 0.0001); - TS_ASSERT_DELTA(vecX.back(), 120.0 - 0.1, 0.0001); + TS_ASSERT_DELTA(vecX.back(), 120.0, 0.0001); double y1101 = vecY[1101]; double e1101 = vecE[1101]; @@ -135,7 +135,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { const Mantid::MantidVec &vecX = outws->readX(0); TS_ASSERT_DELTA(vecX.front(), 0.5, 0.0001); - TS_ASSERT_DELTA(vecX.back(), 4.99, 0.0001); + TS_ASSERT_DELTA(vecX.back(), 5.00, 0.0001); // Check statistics @@ -147,7 +147,7 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { /** Unit test to reduce/bin the HB2A data with more options * @brief test_ReduceHB2AData */ - void Ttest_ReduceHB2ADataAutoBinBoundary() { + void test_ReduceHB2ADataAutoBinBoundary() { // Init ConvertCWPDMDToSpectra alg; alg.initialize(); @@ -179,8 +179,8 @@ class ConvertCWPDMDToSpectraTest : public CxxTest::TestSuite { TS_ASSERT_EQUALS(unit, "dSpacing"); const Mantid::MantidVec &vecX = outws->readX(0); - TS_ASSERT_DELTA(vecX.front(), 0.5, 0.0001); - TS_ASSERT_DELTA(vecX.back(), 4.99, 0.0001); + TS_ASSERT_DELTA(vecX.front(), 1.3416, 0.0001); + TS_ASSERT_DELTA(vecX.back(), 23.0216, 0.001); // Check statistics From 2265ef043d4ef4f1a28c12ba8794a01a7eab02f4 Mon Sep 17 00:00:00 2001 From: Wenduo Zhou Date: Mon, 16 Mar 2015 10:53:26 -0400 Subject: [PATCH 5/5] Cleaned the codes for log output. Refs #11282. --- .../src/ConvertCWPDMDToSpectra.cpp | 33 ++++++++----------- .../algorithms/ConvertCWPDMDToSpectra-v1.rst | 5 +++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp index 14897539f81d..590bc5dbc27e 100644 --- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp +++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp @@ -219,8 +219,8 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( upperboundary = xmax; } - g_log.notice() << "[DB] Binning from " << lowerboundary << " to " - << upperboundary << "\n"; + g_log.debug() << "Binning from " << lowerboundary << " to " << upperboundary + << "\n"; // Create bins in 2theta (degree) size_t sizex, sizey; @@ -229,11 +229,12 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData( ++ lowerboundary; sizey = sizex - 1; - g_log.notice() << "[DB] Number of events = " << numevents - << ", bin size = " << binsize << ", SizeX = " << sizex << ", " - << ", SizeY = " << sizey << ", Delta = " << upperboundary - lowerboundary - << ", Bin size = " << binsize << ", sizex_d = " - << (upperboundary - lowerboundary) / binsize + 2 << "\n"; + g_log.debug() << "Number of events = " << numevents + << ", bin size = " << binsize << ", SizeX = " << sizex << ", " + << ", SizeY = " << sizey + << ", Delta = " << upperboundary - lowerboundary + << ", Bin size = " << binsize << ", sizex_d = " + << (upperboundary - lowerboundary) / binsize + 2 << "\n"; std::vector vecx(sizex), vecy(sizex - 1, 0), vecm(sizex - 1, 0), vece(sizex - 1, 0); @@ -319,7 +320,6 @@ void ConvertCWPDMDToSpectra::findXBoundary( double &xmax) { // Go through all instruments uint16_t numruns = dataws->getNumExperimentInfo(); - g_log.notice() << "[DB] Tota number of ExperimentInfo = " << numruns << "\n"; xmin = BIGNUMBER; xmax = -1; @@ -351,8 +351,8 @@ void ConvertCWPDMDToSpectra::findXBoundary( std::vector vec_detid = dataws->getExperimentInfo(irun)->getInstrument()->getDetectorIDs(true); if (vec_detid.size() == 0) { - g_log.notice() << "[DB] Run " << runnumber << " has no detectors." - << "\n"; + g_log.information() << "Run " << runnumber << " has no detectors." + << "\n"; continue; } const V3D samplepos = @@ -401,13 +401,6 @@ void ConvertCWPDMDToSpectra::findXBoundary( throw std::runtime_error("Unrecognized unit."); } - if (runnumber == 1 && (idet == 1 || idet == 0)) - { - g_log.notice() << "[DB] run = " << runnumber << ", ID = " << idet - << ", Pos = " << detpos.X() << ", " << detpos.Y() << ", " - << detpos.Z() << ", d = " << outx << "\n"; - } - // Compare with xmin and xmax if (outx < xmin) xmin = outx; @@ -545,11 +538,13 @@ void ConvertCWPDMDToSpectra::binMD(API::IMDEventWorkspace_const_sptr mdws, } else { - g_log.notice() << "[DB] .. almost same. Event X = " << outx << ", Boundary = " << vecx[xindex] << "\n"; + g_log.debug() << "Case for almost same. Event X = " << outx + << ", Boundary = " << vecx[xindex] << "\n"; } if (xindex < 0 || xindex >= static_cast(vecy.size())) { - g_log.notice() << "[DB] ... weird...... Event X = " << outx << ", Boundary = " << vecx[xindex] << "\n"; + g_log.warning() << "Case unexpected: Event X = " << outx + << ", Boundary = " << vecx[xindex] << "\n"; } } diff --git a/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst b/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst index 58bbefcd73e4..adc45fcce602 100644 --- a/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst +++ b/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst @@ -13,6 +13,11 @@ This algorithms is to collect the all the counts on the detectors among a set of measurements, which belong to a same experiment run, and bin them according to detector's position, i.e., :math:`2\theta`. +In this algorithm's name, ConvertCWPDMDToSpectra, *CW* stands for constant wave +(reactor-source instrument); *PD* stands for powder diffraction; and *MD* +stands for MDEventWorkspace because the input of this algorithms are two +MDEventWorkspaces. + This algorithm takes 2 MDEventWorkspaces as inputs. One stores the detectors' counts; and the other stores the monitors' counts.