diff --git a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h index 9735c98abde7..2e2e8a177761 100644 --- a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h +++ b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks2D.h @@ -100,6 +100,9 @@ class MANTID_SINQ_DLL PoldiFitPeaks2D : public API::Algorithm { std::string profileFunctionName, const PoldiPeakCollection_sptr &peakCollection) const; + Poldi2DFunction_sptr + getFunctionCalibration(const PoldiPeakCollection_sptr &peakCollection) const; + Poldi2DFunction_sptr getFunctionPawley(std::string profileFunctionName, const PoldiPeakCollection_sptr &peakCollection); diff --git a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumCalibrationFunction.h b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumCalibrationFunction.h index 52ae599bd352..446947664a30 100644 --- a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumCalibrationFunction.h +++ b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumCalibrationFunction.h @@ -45,7 +45,12 @@ class MANTID_SINQ_DLL PoldiSpectrumCalibrationFunction protected: void init(); - void functionModificationHook(const Poldi2DHelper_sptr &poldi2DHelper) const; + void + functionModificationPreHook(const Poldi2DHelper_sptr &poldi2DHelper) const; + void + functionModificationPostHook(const Poldi2DHelper_sptr &poldi2DHelper) const; + + void setPeakCenter(double newCenter, double chopperOffset) const; }; } // namespace Poldi diff --git a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h index 1d4f4d84088b..a16f0dae2c3e 100644 --- a/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h +++ b/Code/Mantid/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiSpectrumDomainFunction.h @@ -262,7 +262,13 @@ class MANTID_SINQ_DLL PoldiSpectrumDomainFunction virtual void init(); virtual void - functionModificationHook(const Poldi2DHelper_sptr &poldi2DHelper) const; + functionModificationPreHook(const Poldi2DHelper_sptr &poldi2DHelper) const; + virtual void + functionModificationPostHook(const Poldi2DHelper_sptr &poldi2DHelper) const; + + virtual double getPeakCenter() const; + virtual void setPeakCenter(double newCenter, + double chopperOffset = 0.0) const; void initializeParametersFromWorkspace( const DataObjects::Workspace2D_const_sptr &workspace2D); diff --git a/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp b/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp index c063b625d4c4..b97635b7a25f 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp @@ -73,6 +73,12 @@ std::map PoldiFitPeaks2D::validateInputs() { "parameters must be supplied for " "PawleyFit."; } + + bool isCalibrationRun = getProperty("CalibrationRun"); + if (isCalibrationRun) { + errorMap["CalibrationRun"] = + "CalibrationRun can not be used in combination with PawleyFit."; + } } return errorMap; @@ -438,6 +444,11 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionFromPeakCollection( return getFunctionPawley(profileFunctionName, peakCollection); } + bool calibrationRun = getProperty("CalibrationRun"); + if (calibrationRun) { + return getFunctionCalibration(peakCollection); + } + return getFunctionIndividualPeaks(profileFunctionName, peakCollection); } @@ -448,6 +459,10 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionFromPeakCollection( * generates an IPeakFunction of the type given in the name parameter, wraps * them in a Poldi2DFunction and returns it. * + * If the profile function name is empty, it is assumed that a calibration + * function is to be created and does that. + * + * * @param profileFunctionName :: Profile function name. * @param peakCollection :: Peak collection with peaks to be used in the fit. * @return :: A Poldi2DFunction with peak profile functions. @@ -460,17 +475,24 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionIndividualPeaks( for (size_t i = 0; i < peakCollection->peakCount(); ++i) { PoldiPeak_sptr peak = peakCollection->peak(i); + std::string spectrumDomainFunctionName = "PoldiSpectrumDomainFunction"; + if (profileFunctionName == "") { + spectrumDomainFunctionName = "PoldiSpectrumCalibrationFunction"; + } + boost::shared_ptr peakFunction = boost::dynamic_pointer_cast( FunctionFactory::Instance().createFunction( - "PoldiSpectrumCalibrationFunction")); + spectrumDomainFunctionName)); if (!peakFunction) { throw std::invalid_argument( "Cannot process null pointer poldi function."); } - //peakFunction->setDecoratedFunction(profileFunctionName); + if (profileFunctionName != "") { + peakFunction->setDecoratedFunction(profileFunctionName); + } IPeakFunction_sptr wrappedProfile = boost::dynamic_pointer_cast( @@ -483,17 +505,26 @@ Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionIndividualPeaks( } mdFunction->addFunction(peakFunction); - - if (i > 0) { - std::string paramName = - "f" + boost::lexical_cast(i) + ".Slope"; - mdFunction->tie(paramName, paramName + "=f0.Slope"); - } } return mdFunction; } +/// Create a calibration function with +Poldi2DFunction_sptr PoldiFitPeaks2D::getFunctionCalibration( + const PoldiPeakCollection_sptr &peakCollection) const { + Poldi2DFunction_sptr calibrationFunction = + getFunctionIndividualPeaks("", peakCollection); + + for (size_t i = 1; i < calibrationFunction->nFunctions(); ++i) { + std::string paramName = + "f" + boost::lexical_cast(i) + ".Slope"; + calibrationFunction->tie(paramName, paramName + "=f0.Slope"); + } + + return calibrationFunction; +} + /** * Returns a Poldi2DFunction that encapsulates a PawleyFunction * @@ -1106,6 +1137,9 @@ void PoldiFitPeaks2D::init() { "Profile function to use for integrating the peak profiles " "before calculating the spectrum."); + declareProperty("CalibrationRun", false, + "This option is only for instrument calibration."); + declareProperty("PawleyFit", false, "Instead of refining individual peaks, " "refine a unit cell. Peaks must be " diff --git a/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumCalibrationFunction.cpp b/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumCalibrationFunction.cpp index 71243757524d..34591ea6fabb 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumCalibrationFunction.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumCalibrationFunction.cpp @@ -15,11 +15,26 @@ void PoldiSpectrumCalibrationFunction::init() { setDecoratedFunction("PoldiCalibrationProfile"); } -void PoldiSpectrumCalibrationFunction::functionModificationHook( +void PoldiSpectrumCalibrationFunction::functionModificationPreHook( const Poldi2DHelper_sptr &poldi2DHelper) const { m_profileFunction->setAttribute( "DeltaTheta", IFunction::Attribute(poldi2DHelper->deltaTwoTheta / 2.0)); } +void PoldiSpectrumCalibrationFunction::functionModificationPostHook( + const Poldi2DHelper_sptr &poldi2DHelper) const { + UNUSED_ARG(poldi2DHelper); + + m_profileFunction->setAttribute("DeltaTheta", IFunction::Attribute(0.0)); +} + +void +PoldiSpectrumCalibrationFunction::setPeakCenter(double newCenter, + double chopperOffset) const { + m_profileFunction->setCentre(newCenter); + m_profileFunction->setAttribute("ChopperOffset", + IFunction::Attribute(chopperOffset)); +} + } // namespace Poldi } // namespace Mantid diff --git a/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumDomainFunction.cpp b/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumDomainFunction.cpp index 53edf36c18c4..7cb99e85fb41 100644 --- a/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumDomainFunction.cpp +++ b/Code/Mantid/Framework/SINQ/src/PoldiUtilities/PoldiSpectrumDomainFunction.cpp @@ -60,7 +60,7 @@ void PoldiSpectrumDomainFunction::function1DSpectrum( Poldi2DHelper_sptr helper = m_2dHelpers[index]; if (helper) { - functionModificationHook(helper); + functionModificationPreHook(helper); int domainSize = static_cast(domain.size()); @@ -86,10 +86,10 @@ void PoldiSpectrumDomainFunction::function1DSpectrum( size_t baseOffset = static_cast(pos + helper->minTOFN); for (size_t i = 0; i < helper->dOffsets.size(); ++i) { - double newD = centre + helper->dFractionalOffsets[i]; size_t offset = static_cast(helper->dOffsets[i]) + baseOffset; - m_profileFunction->setCentre(newD); + setPeakCenter(centre, helper->dFractionalOffsets[i]); + m_profileFunction->functionLocal( &localOut[0], helper->domain->getPointerAt(pos), dWidthN); @@ -99,7 +99,8 @@ void PoldiSpectrumDomainFunction::function1DSpectrum( } } - m_profileFunction->setCentre(centre); + setPeakCenter(centre); + functionModificationPostHook(helper); } } @@ -118,7 +119,7 @@ void PoldiSpectrumDomainFunction::functionDeriv1DSpectrum( Poldi2DHelper_sptr helper = m_2dHelpers[index]; if (helper) { - functionModificationHook(helper); + functionModificationPreHook(helper); size_t domainSize = domain.size(); @@ -142,18 +143,18 @@ void PoldiSpectrumDomainFunction::functionDeriv1DSpectrum( size_t baseOffset = static_cast(pos + helper->minTOFN); for (size_t i = 0; i < helper->dOffsets.size(); ++i) { - double newD = centre + helper->dFractionalOffsets[i]; size_t offset = static_cast(helper->dOffsets[i]) + baseOffset; WrapAroundJacobian smallJ(jacobian, offset, helper->factors, pos, domainSize); - m_profileFunction->setCentre(newD); + setPeakCenter(m_profileFunction->centre(), helper->dFractionalOffsets[i]); m_profileFunction->functionDerivLocal( &smallJ, helper->domain->getPointerAt(pos), dWidthN); } - m_profileFunction->setCentre(centre); + setPeakCenter(centre); + functionModificationPostHook(helper); } } @@ -189,9 +190,23 @@ IPeakFunction_sptr PoldiSpectrumDomainFunction::getProfileFunction() const { /// Does nothing. void PoldiSpectrumDomainFunction::init() {} -void PoldiSpectrumDomainFunction::functionModificationHook( +void PoldiSpectrumDomainFunction::functionModificationPreHook( + const Poldi2DHelper_sptr &poldi2DHelper) const { + UNUSED_ARG(poldi2DHelper) +} + +void PoldiSpectrumDomainFunction::functionModificationPostHook( const Poldi2DHelper_sptr &poldi2DHelper) const { - UNUSED_ARG(poldi2DHelper) + UNUSED_ARG(poldi2DHelper) +} + +double PoldiSpectrumDomainFunction::getPeakCenter() const { + return m_profileFunction->centre(); +} + +void PoldiSpectrumDomainFunction::setPeakCenter(double newCenter, + double chopperOffset) const { + m_profileFunction->setCentre(newCenter + chopperOffset); } /** diff --git a/Code/Mantid/Framework/SINQ/test/PoldiSpectrumCalibrationFunctionTest.h b/Code/Mantid/Framework/SINQ/test/PoldiSpectrumCalibrationFunctionTest.h index 269803fba2a7..8d0af6f33557 100644 --- a/Code/Mantid/Framework/SINQ/test/PoldiSpectrumCalibrationFunctionTest.h +++ b/Code/Mantid/Framework/SINQ/test/PoldiSpectrumCalibrationFunctionTest.h @@ -5,7 +5,7 @@ #include "MantidSINQ/PoldiUtilities/PoldiSpectrumCalibrationFunction.h" -using Mantid::SINQ::PoldiSpectrumCalibrationFunction; +using Mantid::Poldi::PoldiSpectrumCalibrationFunction; using namespace Mantid::API; class PoldiSpectrumCalibrationFunctionTest : public CxxTest::TestSuite @@ -26,4 +26,4 @@ class PoldiSpectrumCalibrationFunctionTest : public CxxTest::TestSuite }; -#endif /* MANTID_SINQ_POLDISPECTRUMCALIBRATIONFUNCTIONTEST_H_ */ \ No newline at end of file +#endif /* MANTID_SINQ_POLDISPECTRUMCALIBRATIONFUNCTIONTEST_H_ */