Skip to content
Snippets Groups Projects
Commit e3b98944 authored by Gigg, Martyn Anthony's avatar Gigg, Martyn Anthony
Browse files

Merge remote-tracking branch 'origin/feature/9778_normToMonitorReturns'

parents 70d305b4 d0052bd3
No related merge requests found
......@@ -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; }
......
......@@ -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
......
......@@ -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()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment