From 1745c657d83ec637c970a11eb7b3df107e4455d8 Mon Sep 17 00:00:00 2001 From: Martyn Gigg Date: Tue, 10 Dec 2013 21:41:59 +0000 Subject: [PATCH] Add support for DetectorGroups to Compton functions The parameters are averaged across the DetectorGroup when one is found Refs #8593 --- .../CalculateGammaBackground.h | 2 - .../inc/MantidCurveFitting/ComptonProfile.h | 8 +- .../src/CalculateGammaBackground.cpp | 58 +++++--------- .../CurveFitting/src/ComptonProfile.cpp | 78 ++++++++++++------- 4 files changed, 75 insertions(+), 71 deletions(-) diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateGammaBackground.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateGammaBackground.h index 2765d7ad0458..9bd2a19e11af 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateGammaBackground.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/CalculateGammaBackground.h @@ -81,8 +81,6 @@ namespace Mantid /// Compute the theta range for a given foil std::pair calculateThetaRange(const Geometry::IComponent_const_sptr & foilComp, const double radius, const unsigned int horizDir) const; - /// Retrieve parameter for given component - double getComponentParameter(const Geometry::IComponent & comp,const std::string &name) const; /// Input TOF data API::MatrixWorkspace_const_sptr m_inputWS; diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ComptonProfile.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ComptonProfile.h index f9fcebf7f5ec..fc076b667f8a 100644 --- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ComptonProfile.h +++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/ComptonProfile.h @@ -58,6 +58,10 @@ namespace CurveFitting class MANTID_CURVEFITTING_DLL ComptonProfile : public virtual API::ParamFunction, public virtual API::IFunction1D { public: + /// Retrieve a component parameter + static double getComponentParameter(const Geometry::IComponent_const_sptr & comp, const Geometry::ParameterMap &pmap, + const std::string &name); + /// Default constructor required for factory ComptonProfile(); @@ -116,10 +120,6 @@ namespace CurveFitting /// Logger Kernel::Logger & m_log; - private: - /// Retrieve a component parameter - double getComponentParameter(const Geometry::IComponent & comp,const std::string &name) const; - /// Current workspace index, required to access instrument parameters size_t m_wsIndex; /// Store the mass values diff --git a/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp b/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp index 1f3c7f718168..abb94f850f09 100644 --- a/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/CalculateGammaBackground.cpp @@ -218,6 +218,7 @@ namespace Mantid void CalculateGammaBackground::calculateSpectrumFromDetector(const size_t inputIndex, const size_t outputIndex) { auto det = m_inputWS->getDetector(inputIndex); + const auto & pmap = m_inputWS->constInstrumentParameters(); auto detPos = det->getPos(); // -- Setup detector & resolution parameters -- @@ -225,15 +226,15 @@ namespace Mantid detPar.l1 = m_l1; detPar.l2 = m_samplePos.distance(detPos); detPar.theta = m_inputWS->detectorTwoTheta(det); //radians - detPar.t0 = getComponentParameter(*det, "t0")*1e-6; // seconds - detPar.efixed = getComponentParameter(*det,"efixed"); + detPar.t0 = ComptonProfile::getComponentParameter(det, pmap, "t0")*1e-6; // seconds + detPar.efixed = ComptonProfile::getComponentParameter(det, pmap,"efixed"); ResolutionParams detRes; - detRes.dl1 = getComponentParameter(*det, "sigma_l1"); // DL0 - detRes.dl2 = getComponentParameter(*det, "sigma_l2"); // DL1 - detRes.dthe = getComponentParameter(*det, "sigma_theta"); //DTH in radians - detRes.dEnGauss = getComponentParameter(*det, "sigma_gauss"); - detRes.dEnLorentz = getComponentParameter(*det, "hwhm_lorentz"); + detRes.dl1 = ComptonProfile::getComponentParameter(det, pmap, "sigma_l1"); // DL0 + detRes.dl2 = ComptonProfile::getComponentParameter(det, pmap, "sigma_l2"); // DL1 + detRes.dthe = ComptonProfile::getComponentParameter(det, pmap, "sigma_theta"); //DTH in radians + detRes.dEnGauss = ComptonProfile::getComponentParameter(det, pmap, "sigma_gauss"); + detRes.dEnLorentz = ComptonProfile::getComponentParameter(det, pmap, "hwhm_lorentz"); // Compute a time of flight spectrum convolved with a Voigt resolution function for each mass // at the detector point & sum to a single spectrum @@ -255,6 +256,7 @@ namespace Mantid void CalculateGammaBackground::calculateBackgroundFromFoils(const size_t inputIndex, const size_t outputIndex) { auto det = m_inputWS->getDetector(inputIndex); + const auto & pmap = m_inputWS->constInstrumentParameters(); auto detPos = det->getPos(); // -- Setup detector & resolution parameters -- @@ -262,15 +264,15 @@ namespace Mantid detPar.l1 = m_l1; detPar.l2 = m_samplePos.distance(detPos); detPar.theta = m_inputWS->detectorTwoTheta(det); //radians - detPar.t0 = getComponentParameter(*det, "t0")*1e-6; // seconds - detPar.efixed = getComponentParameter(*det,"efixed"); + detPar.t0 = ComptonProfile::getComponentParameter(det, pmap, "t0")*1e-6; // seconds + detPar.efixed = ComptonProfile::getComponentParameter(det, pmap,"efixed"); ResolutionParams detRes; - detRes.dl1 = getComponentParameter(*det, "sigma_l1"); // DL0 - detRes.dl2 = getComponentParameter(*det, "sigma_l2"); // DL1 - detRes.dthe = getComponentParameter(*det, "sigma_theta"); //DTH in radians - detRes.dEnGauss = getComponentParameter(*det, "sigma_gauss"); - detRes.dEnLorentz = getComponentParameter(*det, "hwhm_lorentz"); + detRes.dl1 = ComptonProfile::getComponentParameter(det, pmap, "sigma_l1"); // DL0 + detRes.dl2 = ComptonProfile::getComponentParameter(det, pmap, "sigma_l2"); // DL1 + detRes.dthe = ComptonProfile::getComponentParameter(det, pmap, "sigma_theta"); //DTH in radians + detRes.dEnGauss = ComptonProfile::getComponentParameter(det, pmap, "sigma_gauss"); + detRes.dEnLorentz = ComptonProfile::getComponentParameter(det, pmap, "hwhm_lorentz"); const size_t nxvalues = m_backgroundWS->blocksize(); std::vector foilSpectrum(nxvalues); @@ -510,6 +512,7 @@ namespace Mantid // foil geometry // there should be the same number in each position + const auto & pmap = m_inputWS->constInstrumentParameters(); auto foils0 = inst->getAllComponentsWithName("foil-pos0"); auto foils1 = inst->getAllComponentsWithName("foil-pos1"); const size_t nfoils = foils0.size(); @@ -534,16 +537,16 @@ namespace Mantid FoilInfo descr; descr.thetaMin = thetaRng0.first; descr.thetaMax = thetaRng0.second; - descr.lorentzWidth = getComponentParameter(*foil0, "hwhm_lorentz"); - descr.gaussWidth = getComponentParameter(*foil0, "sigma_gauss"); + descr.lorentzWidth = ComptonProfile::getComponentParameter(foil0, pmap, "hwhm_lorentz"); + descr.gaussWidth = ComptonProfile::getComponentParameter(foil0, pmap, "sigma_gauss"); m_foils0[i] = descr; //copy const auto & foil1 = foils1[i]; auto thetaRng1 = calculateThetaRange(foil1, m_foilRadius,refFrame->pointingHorizontal()); descr.thetaMin = thetaRng1.first; descr.thetaMax = thetaRng1.second; - descr.lorentzWidth = getComponentParameter(*foil1, "hwhm_lorentz"); - descr.gaussWidth = getComponentParameter(*foil1, "sigma_gauss"); + descr.lorentzWidth = ComptonProfile::getComponentParameter(foil1, pmap, "hwhm_lorentz"); + descr.gaussWidth = ComptonProfile::getComponentParameter(foil1, pmap, "sigma_gauss"); m_foils1[i] = descr; //copy } @@ -596,24 +599,5 @@ namespace Mantid return std::make_pair(theta - dtheta, theta + dtheta); } - /** - * @param comp A reference to the component that should contain the parameter - * @param name The name of the parameter - * @returns The value of the parameter if it exists - * @throws A std::invalid_argument error if the parameter does not exist - */ - double CalculateGammaBackground::getComponentParameter(const Geometry::IComponent & comp,const std::string &name) const - { - std::vector pars = comp.getNumberParameter(name); - if(!pars.empty()) - { - return pars[0]; - } - else - { - throw std::invalid_argument("CalculateGammaBackground - Cannot find component parameter \"" + name + "\"."); - } - } - } // namespace CurveFitting } // namespace Mantid diff --git a/Code/Mantid/Framework/CurveFitting/src/ComptonProfile.cpp b/Code/Mantid/Framework/CurveFitting/src/ComptonProfile.cpp index 0e9d10b26d93..698e7fefbd32 100644 --- a/Code/Mantid/Framework/CurveFitting/src/ComptonProfile.cpp +++ b/Code/Mantid/Framework/CurveFitting/src/ComptonProfile.cpp @@ -3,7 +3,7 @@ //----------------------------------------------------------------------------- #include "MantidCurveFitting/ComptonProfile.h" #include "MantidAPI/FunctionFactory.h" - +#include "MantidGeometry/Instrument/DetectorGroup.h" #include namespace Mantid @@ -21,6 +21,47 @@ namespace CurveFitting ///@endcond } + /** + * If a DetectorGroup is encountered then the parameters are averaged over the group + * @param comp A pointer to the component that should contain the parameter + * @param pmap A reference to the ParameterMap that stores the parameters + * @param name The name of the parameter + * @returns The value of the parameter if it exists + * @throws A std::invalid_argument error if the parameter does not exist + */ + double ComptonProfile::getComponentParameter(const Geometry::IComponent_const_sptr & comp, const Geometry::ParameterMap &pmap, + const std::string &name) + { + if(!comp) throw std::invalid_argument("ComptonProfile - Cannot retrieve parameter from NULL component"); + + double result(0.0); + if(const auto group = boost::dynamic_pointer_cast(comp)) + { + const auto dets = group->getDetectors(); + double avg(0.0); + for(auto it = dets.begin(); it!= dets.end(); ++it) + { + auto param = pmap.getRecursive((*it)->getComponentID(), name); + if(param) avg += param->value(); + else throw std::invalid_argument("ComptonProfile - Unable to find DetectorGroup component parameter \"" + name + "\"."); + } + result = avg/static_cast(group->nDets()); + } + else + { + auto param = pmap.getRecursive(comp->getComponentID(), name); + if(param) + { + result = param->value(); + } + else + { + throw std::invalid_argument("ComptonProfile - Unable to find component parameter \"" + name + "\"."); + } + } + return result; + } + /** */ ComptonProfile::ComptonProfile() : API::ParamFunction(), API::IFunction1D(), @@ -89,18 +130,19 @@ namespace CurveFitting } DetectorParams detpar; + const auto & pmap = workspace->constInstrumentParameters(); detpar.l1 = sample->getDistance(*source); detpar.l2 = det->getDistance(*sample); detpar.theta = workspace->detectorTwoTheta(det); - detpar.t0 = getComponentParameter(*det,"t0")*1e-6; // Convert to seconds - detpar.efixed = getComponentParameter(*det,"efixed"); + detpar.t0 = getComponentParameter(det, pmap, "t0")*1e-6; // Convert to seconds + detpar.efixed = getComponentParameter(det, pmap, "efixed"); ResolutionParams respar; - respar.dl1 = getComponentParameter(*det, "sigma_l1"); - respar.dl2 = getComponentParameter(*det, "sigma_l2"); - respar.dthe = getComponentParameter(*det,"sigma_theta"); //radians - respar.dEnLorentz = getComponentParameter(*det, "hwhm_lorentz"); - respar.dEnGauss = getComponentParameter(*det, "sigma_gauss"); + respar.dl1 = getComponentParameter(det, pmap, "sigma_l1"); + respar.dl2 = getComponentParameter(det, pmap, "sigma_l2"); + respar.dthe = getComponentParameter(det, pmap, "sigma_theta"); //radians + respar.dEnLorentz = getComponentParameter(det, pmap, "hwhm_lorentz"); + respar.dEnGauss = getComponentParameter(det, pmap, "sigma_gauss"); this->cacheYSpaceValues(workspace->readX(m_wsIndex), workspace->isHistogramData(), detpar, respar); } @@ -304,25 +346,5 @@ namespace CurveFitting std::transform(voigt.begin(), voigt.end(), voigt.begin(), std::bind2nd(std::multiplies(), norm)); } - /** - * @param comp A reference to the component that should contain the parameter - * @param name The name of the parameter - * @returns The value of the parameter if it exists - * @throws A std::invalid_argument error if the parameter does not exist - */ - double ComptonProfile::getComponentParameter(const Geometry::IComponent & comp,const std::string &name) const - { - std::vector pars = comp.getNumberParameter(name); - if(!pars.empty()) - { - return pars[0]; - } - else - { - throw std::invalid_argument("ComptonProfile - Unable to find component parameter \"" + name + "\"."); - } - } - - } // namespace CurveFitting } // namespace Mantid