diff --git a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h index 43bc9dd14f6802c7933934931bb1baca327944fb..afb271ae28e2094293e4ec2bfbd186cf1d4fd3d1 100644 --- a/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h +++ b/Code/Mantid/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h @@ -11,14 +11,14 @@ namespace Mantid { namespace Algorithms { -/** Normalises a 2D workspace by a specified monitor spectrum. By default ,the - normalisation is done bin-by-bin following this formula: +/** Normalizes a 2D workspace by a specified monitor spectrum. By default ,the + normalization is done bin-by-bin following this formula: Norm(s_i)=(s_i/m_i)*Dlam_i*Sum(m_i)/Sum(Dlam_i) where s_i is the signal in bin i, m_i the count in the corresponding monitor bin, Dlam_i the width of the bin, Sum(m_i) is the integrated monitor count and Sum(Dlam_i) the sum of all bin widths (the full range). - Optionally, can instead normalise by the integrated monitor count over a specified + Optionally, can instead normalize by the integrated monitor count over a specified range in X. In this case all bins in all spectra will simply be divided by this integrated count. No bin width correction takes place in this case. @@ -30,12 +30,12 @@ namespace Algorithms <LI> InputWorkspace - The name of the input workspace. Must be a histogram and not a distribution.</LI> <LI> OutputWorkspace - The name of the output workspace. </LI> - <LI> MonitorSpectrum - The spectrum number for the monitor to normalise with. </LI> + <LI> MonitorSpectrum - The spectrum number for the monitor to normalize with. </LI> <LI> MonitorWorkspace - A workspace containing the monitor spectrum. </LI> </UL> Optional Properties: - These should be set to normalise by an integrated monitor count over the range given + These should be set to normalize by an integrated monitor count over the range given <UL> <LI> IntegrationRangeMin - The lower bound of the range to use. </LI> <LI> IntegrationRangeMax - The upper bound of the range to use. </LI> @@ -70,7 +70,7 @@ public: /// Algorithm's name for identification overriding a virtual method virtual const std::string name() const { return "NormaliseToMonitor"; } ///Summary of algorithms purpose - virtual const std::string summary() const {return "Normalises a 2D workspace by a specified spectrum, spectrum, described by a monitor ID or spectrun provided in a separate worskspace. ";} + virtual const std::string summary() const {return "Normalizes a 2D workspace by a specified spectrum, spectrum, described by a monitor ID or spectrun provided in a separate worskspace. ";} /// Algorithm's version for identification overriding a virtual method virtual int version() const { return 1; } diff --git a/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp b/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp index 8f715aa371b51bd7d54e22519ba177534fe75c61..68c44e598f5e29f8294dbffd33fa2fd6331dc041 100644 --- a/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp +++ b/Code/Mantid/Framework/Algorithms/src/NormaliseToMonitor.cpp @@ -30,7 +30,7 @@ namespace Algorithms bool MonIDPropChanger::isEnabled(const IPropertyManager * algo)const { int sp_id =algo->getProperty(SpectraNum); - // if there is spectra number set to norbalize by, nothing else can be selected; + // if there is spectra number set to normalize by, nothing else can be selected; if(sp_id>0){ is_enabled=false; return false; @@ -48,7 +48,7 @@ bool MonIDPropChanger::isEnabled(const IPropertyManager * algo)const return is_enabled; } -// method checks if other properties have chanded and these changes affected MonID property +// method checks if other properties have changed and these changes affected MonID property bool MonIDPropChanger::isConditionChanged(const IPropertyManager * algo)const { // is enabled is based on other properties: @@ -106,7 +106,7 @@ bool MonIDPropChanger::monitorIdReader(API::MatrixWorkspace_const_sptr inputWS)c } } // are these monitors really there? - // got the index of correspondent spectras . + // got the index of correspondent spectra. std::vector<size_t> indexList; inputWS->getIndicesFromDetectorIDs(mon,indexList); if(indexList.empty()){ @@ -174,7 +174,7 @@ void NormaliseToMonitor::init() // Can either set a spectrum within the workspace to be the monitor spectrum..... declareProperty(new WorkspaceProperty<>("OutputWorkspace","",Direction::Output), "Name to use for the output workspace"); - // should be any spectrum ID, but named this property MonitorSpectrum to keep compartibility with previous scripts + // should be any spectrum ID, but named this property MonitorSpectrum to keep compatibility with previous scripts // Can either set a spectrum within the workspace to be the monitor spectrum..... declareProperty("MonitorSpectrum",-1, "The spectrum number within the InputWorkspace you want to normalize by (It can be a monitor spectrum or a spectrum responsible for a group of detectors or monitors)", @@ -200,15 +200,19 @@ void NormaliseToMonitor::init() setPropertySettings("MonitorWorkspaceIndex",new Kernel::EnabledWhenProperty("MonitorSpectrum",IS_DEFAULT)); // If users set either of these optional properties two things happen - // 1) normalisation is by an integrated count instead of bin-by-bin + // 1) normalization is by an integrated count instead of bin-by-bin // 2) if the value is within the range of X's in the spectrum it crops the spectrum declareProperty( "IntegrationRangeMin", EMPTY_DBL(), - "If set, normalisation will be by integrated count from this minimum x value"); + "If set, normalization will be by integrated count from this minimum x value"); declareProperty( "IntegrationRangeMax", EMPTY_DBL(), - "If set, normalisation will be by integrated count up to this maximum x value"); + "If set, normalization will be by integrated count up to this maximum x value"); declareProperty("IncludePartialBins", false, "If true and an integration range is set then partial bins at either \n" "end of the integration range are also included"); + + declareProperty(new WorkspaceProperty<>("NormFactorWS","",Direction::Output,PropertyMode::Optional), + "Name of the workspace, containing the normalization factor.\n" + "If this name is empty, normalization workspace is not returned. If the name coincides with the output workspace name, _normFactor suffix is added to this name"); } void NormaliseToMonitor::exec() @@ -219,7 +223,7 @@ void NormaliseToMonitor::exec() // First check the inputs, throws std::runtime_error if a property is invalid this->checkProperties(inputWS); - // See if the normalisation with integration properties are set, + // See if the normalization with integration properties are set, // throws std::runtime_error if a property is invalid const bool integrate = this->setIntegrationProps(); @@ -233,6 +237,20 @@ void NormaliseToMonitor::exec() } setProperty("OutputWorkspace",outputWS); + std::string norm_ws_name = getPropertyValue("NormFactorWS"); + if(!norm_ws_name.empty()) + { + std::string out_name = getPropertyValue("OutputWorkspace"); + if(out_name == norm_ws_name) + { + // if the normalization factor workspace name coincides with output workspace name, add _normFactor suffix to this name + norm_ws_name = norm_ws_name+"_normFactor"; + auto pProp = (this->getPointerToProperty("NormFactorWS")); + pProp->setValue(norm_ws_name); + } + setProperty("NormFactorWS",m_monitor); + } + } /** Makes sure that the input properties are set correctly @@ -260,17 +278,17 @@ void NormaliseToMonitor::checkProperties(const API::MatrixWorkspace_sptr& inputW throw std::runtime_error(mess); } // One and only one of these properties should have been set - // input from separate workspace is owerwritten by monitor spectrum + // input from separate workspace is overwritten by monitor spectrum if ( inWS && sepWS ){ g_log.information("Both input workspace MonitorSpectrum number and monitor workspace are specified. Ignoring Monitor Workspace"); sepWS = false; } - // input from detector ID is rejected in favour of monitor sp + // input from detector ID is rejected in favor of monitor sp if ( inWS && monIDs ){ g_log.information("Both input workspace MonitorSpectrum number and detector ID are specified. Ignoring Detector ID"); monIDs = false; } - // separate ws takes over detectorID (this logic is dublicated within getInWSMonitorSpectrum) + // separate ws takes over detectorID (this logic is duplicated within getInWSMonitorSpectrum) if ( sepWS && monIDs ){ g_log.information("Both input MonitorWorkspace and detector ID are specified. Ignoring Detector ID"); } @@ -291,12 +309,12 @@ void NormaliseToMonitor::checkProperties(const API::MatrixWorkspace_sptr& inputW if ( !mon->isMonitor() ) { g_log.warning()<<"The spectrum N: "<<spec_num<<" in MonitorWorkspace does not refer to a monitor.\n" - <<"Continuing with normalisation regardless."; + <<"Continuing with normalization regardless."; } } catch (Kernel::Exception::NotFoundError &) { g_log.warning("Unable to check if the spectrum provided relates to a monitor - " "the instrument is not fully specified.\n" - "Continuing with normalisation regardless."); + "Continuing with normalization regardless."); } } @@ -309,9 +327,9 @@ void NormaliseToMonitor::checkProperties(const API::MatrixWorkspace_sptr& inputW */ API::MatrixWorkspace_sptr NormaliseToMonitor::getInWSMonitorSpectrum(const API::MatrixWorkspace_sptr& inputWorkspace,int &spectra_num) { - // this is the index of the spectra within the workspace and we need to indetnify it either from DetID or fron SpecID + // this is the index of the spectra within the workspace and we need to identify it either from DetID or from SpecID // size_t spectra_num(-1); -// try monitor spectrum. If it is specified, it overides everything +// try monitor spectrum. If it is specified, it overrides everything int monitorSpec = getProperty("MonitorSpectrum"); if(monitorSpec<0){ // Get hold of the monitor spectrum through detector ID @@ -321,14 +339,14 @@ API::MatrixWorkspace_sptr NormaliseToMonitor::getInWSMonitorSpectrum(const API:: } // set spectra of detector's ID of one selected monitor ID std::vector<detid_t> detID(1,monitorID); - // got the index of correspondent spectras (should be only one). + // got the index of correspondent spectra (should be only one). std::vector<size_t> indexList; inputWorkspace->getIndicesFromDetectorIDs(detID,indexList); if(indexList.empty()){ - throw std::runtime_error("Can not find spectra, coorespoinding to the requested monitor ID"); + throw std::runtime_error("Can not find spectra, corresponding to the requested monitor ID"); } if(indexList.size()>1){ - throw std::runtime_error("More then one spectra coorespods to the requested monitor ID, which is unheard of"); + throw std::runtime_error("More then one spectra corresponds to the requested monitor ID, which is unheard of"); } spectra_num = (int)indexList[0]; }else{ // monitor spectrum is specified. @@ -447,7 +465,7 @@ bool NormaliseToMonitor::setIntegrationProps() return true; } -/** Carries out a normalisation based on the integrated count of the monitor over a range +/** Carries out a normalization based on the integrated count of the monitor over a range * @param inputWorkspace The input workspace * @param outputWorkspace The result workspace */ @@ -478,7 +496,7 @@ void NormaliseToMonitor::normaliseByIntegratedCount(const API::MatrixWorkspace_s outputWorkspace = divide->getProperty("OutputWorkspace"); } -/** Carries out the bin-by-bin normalisation +/** Carries out the bin-by-bin normalization * @param inputWorkspace The input workspace * @param outputWorkspace The result workspace */ @@ -509,7 +527,7 @@ void NormaliseToMonitor::normaliseBinByBin(const API::MatrixWorkspace_sptr& inpu const MantidVec& monX = m_monitor->readX(0); MantidVec& monY = m_monitor->dataY(0); MantidVec& monE = m_monitor->dataE(0); - // Calculate the overall normalisation just the once if bins are all matching + // Calculate the overall normalization just the once if bins are all matching if (m_commonBins) this->normalisationFactor(m_monitor->readX(0),&monY,&monE); @@ -530,11 +548,11 @@ void NormaliseToMonitor::normaliseBinByBin(const API::MatrixWorkspace_sptr& inpu if (!m_commonBins) { - // ConvertUnits can give X vectors of all zeroes - skip these, they cause problems + // ConvertUnits can give X vectors of all zeros - skip these, they cause problems if (X.back() == 0.0 && X.front() == 0.0) continue; // Rebin the monitor spectrum to match the binning of the current data spectrum VectorHelper::rebinHistogram(monX,monY,monE,X,*Y,*E,false); - // Recalculate the overall normalisation factor + // Recalculate the overall normalization factor this->normalisationFactor(X,Y,E); } @@ -579,9 +597,12 @@ void NormaliseToMonitor::normaliseBinByBin(const API::MatrixWorkspace_sptr& inpu PARALLEL_END_INTERUPT_REGION } // end loop over spectra PARALLEL_CHECK_INTERUPT_REGION + + + } -/** Calculates the overall normalisation factor. +/** Calculates the overall normalization factor. * This multiplies result by (bin width * sum of monitor counts) / total frame width. * @param X The X vector * @param Y The data vector diff --git a/Code/Mantid/Framework/Algorithms/test/NormaliseToMonitorTest.h b/Code/Mantid/Framework/Algorithms/test/NormaliseToMonitorTest.h index 9dea3ac2185021c77de0a758e61888704aa337c3..20ea8af383fb4136385011ae98d14487d56200b3 100644 --- a/Code/Mantid/Framework/Algorithms/test/NormaliseToMonitorTest.h +++ b/Code/Mantid/Framework/Algorithms/test/NormaliseToMonitorTest.h @@ -99,6 +99,7 @@ public: if ( ! sameOutputWS ) outputWS.append("2"); TS_ASSERT_THROWS_NOTHING( norm.setPropertyValue("OutputWorkspace",outputWS) ) TS_ASSERT_THROWS_NOTHING( norm.setPropertyValue("MonitorSpectrum","0") ) + TS_ASSERT_THROWS_NOTHING( norm.setPropertyValue("NormFactorWS","NormFactor") ) TS_ASSERT_THROWS_NOTHING( norm.execute() ) TS_ASSERT( norm.isExecuted() ) @@ -129,6 +130,9 @@ public: EventWorkspace_const_sptr eventOut = boost::dynamic_pointer_cast<const EventWorkspace>(output); TS_ASSERT(eventOut); } + TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("NormFactor") ) + TS_ASSERT_EQUALS(output->getNumberHistograms(),1); + AnalysisDataService::Instance().remove("NormFactor"); } @@ -164,6 +168,7 @@ public: TS_ASSERT_THROWS_NOTHING( norm2.setPropertyValue("MonitorSpectrum","0") ) TS_ASSERT_THROWS_NOTHING( norm2.setPropertyValue("IntegrationRangeMin","5") ) TS_ASSERT_THROWS_NOTHING( norm2.setPropertyValue("IntegrationRangeMax","20") ) + TS_ASSERT_THROWS_NOTHING( norm2.setPropertyValue("NormFactorWS","normMon3") ) TS_ASSERT_THROWS_NOTHING( norm2.execute() ) TS_ASSERT( norm2.isExecuted() ) @@ -190,6 +195,10 @@ public: TS_ASSERT_EQUALS( output->readY(0)[k], 0.2 ) TS_ASSERT_DELTA( output->readE(0)[k], 0.0657, 0.0001 ) } + TS_ASSERT_THROWS_NOTHING( output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("normMon3_normFactor") ) + TS_ASSERT_EQUALS(output->getNumberHistograms(),1); + AnalysisDataService::Instance().remove("normMon3_normFactor"); + } void testNormaliseByIntegratedCountIncPartBins() @@ -229,18 +238,25 @@ public: TS_ASSERT_DELTA( output->readE(0)[k], 0.0518, 0.0001 ) } AnalysisDataService::Instance().remove("normMon4"); + TS_ASSERT(!AnalysisDataService::Instance().doesExist("NormWS") ); + } void testFailsOnSettingBothMethods() { NormaliseToMonitor norm3; norm3.initialize(); - TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("InputWorkspace","normMon") ) - TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("OutputWorkspace","normMon3") ) - TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("MonitorWorkspaceIndex","0") ) - TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("MonitorWorkspace","monWS") ) + TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("InputWorkspace","normMon") ); + TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("OutputWorkspace","normMon3") ); + TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("MonitorWorkspaceIndex","0") ); + TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("MonitorWorkspace","monWS") ); + TS_ASSERT_THROWS_NOTHING( norm3.setPropertyValue("NormFactorWS","NormWS") ); TS_ASSERT_THROWS_NOTHING( norm3.execute() ) - TS_ASSERT( norm3.isExecuted() ) + TS_ASSERT( norm3.isExecuted() ); + + TS_ASSERT( AnalysisDataService::Instance().doesExist("NormWS") ); + AnalysisDataService::Instance().remove("NormWS"); + } void testSeparateWorkspaceWithRebin() @@ -249,9 +265,16 @@ public: norm4.initialize(); TS_ASSERT_THROWS_NOTHING( norm4.setPropertyValue("InputWorkspace","normMon") ) TS_ASSERT_THROWS_NOTHING( norm4.setPropertyValue("OutputWorkspace","normMon4") ) - TS_ASSERT_THROWS_NOTHING( norm4.setPropertyValue("MonitorWorkspace","monWS") ) + TS_ASSERT_THROWS_NOTHING( norm4.setPropertyValue("MonitorWorkspace","monWS") ) + TS_ASSERT_THROWS_NOTHING( norm4.setPropertyValue("NormFactorWS","NormWS") ); + + TS_ASSERT_THROWS_NOTHING( norm4.execute() ) TS_ASSERT( norm4.isExecuted() ) + + TS_ASSERT( AnalysisDataService::Instance().doesExist("NormWS") ); + AnalysisDataService::Instance().remove("NormWS"); + } void testMonIDPropChangerEnabled()