24using namespace Kernel;
26using namespace Algorithms::PeakParameterHelper;
29using namespace DataObjects;
38 "A 2D workspace with X values of d-spacing");
40 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
41 mustBePositive->setLower(0);
43 declareProperty(
"Step", 0.001, mustBePositive,
"Step size used to bin d-spacing data");
44 declareProperty(
"DReference", 2.0, mustBePositive,
"Center of reference peak in d-space");
45 declareProperty(
"XMin", 0.0,
"Minimum of CrossCorrelation data to search for peak, usually negative");
46 declareProperty(
"XMax", 0.0,
"Maximum of CrossCorrelation data to search for peak, usually positive");
49 "Optional: The name of the output CalFile to save the "
50 "generated OffsetsWorkspace.");
52 "An output workspace containing the offsets.");
58 "Mask workspace (optional input / output workspace):"
59 " when specified, if the workspace already exists, any incoming masked detectors will be combined"
60 " with any additional outgoing masked detectors detected by the algorithm");
64 std::make_shared<StringListValidator>(FunctionFactory::Instance().getFunctionNames<IPeakFunction>()),
65 "The function type for fitting the peaks.");
67 "Whether to esimate FWHM of peak function when estimating fit parameters");
68 declareProperty(
"MaxOffset", 1.0,
"Maximum absolute value of offsets; default is 1");
71 std::vector<std::string> modes{
"Relative",
"Absolute",
"Signed"};
73 declareProperty(
"OffsetMode",
"Relative", std::make_shared<StringListValidator>(modes),
74 "Whether to calculate a relative, absolute, or signed offset");
76 "The known peak centre value from the NIST standard "
77 "information, this is only used in Absolute OffsetMode.");
81 std::map<std::string, std::string> result;
85 result[
"InputWorkspace"] =
"The InputWorkspace must be a MatrixWorkspace.";
89 const auto unit = inputWS->getAxis(0)->unit()->caption();
90 if (unit !=
"Bins of Shift" && unit !=
"d-Spacing") {
91 const auto unitErrorMsg =
"GetDetectorOffsets only supports input workspaces with units 'Bins of Shift' or "
92 "'d-Spacing', your unit was : " +
94 result[
"InputWorkspace"] = unitErrorMsg;
100 if (maskWS->getInstrument()->getNumberDetectors(
true) != inputWS->getInstrument()->getNumberDetectors(
true)) {
101 result[
"MaskWorkspace"] =
"incoming mask workspace must have the same instrument as the input workspace";
102 }
else if (maskWS->getNumberHistograms() != inputWS->getInstrument()->getNumberDetectors(
true)) {
103 result[
"MaskWorkspace"] =
"incoming mask workspace must have one spectrum per detector";
120 throw std::runtime_error(
"Must specify m_Xmin<m_Xmax");
127 if (mode_str ==
"Absolute") {
131 else if (mode_str ==
"Relative") {
135 else if (mode_str ==
"Signed") {
141 int64_t nspec =
static_cast<int64_t
>(
inputW->getNumberHistograms());
144 auto outputW = std::make_shared<OffsetsWorkspace>(
inputW->getInstrument());
145 size_t N_d = outputW->getNumberHistograms();
146 for (
size_t di = 0; di < N_d; ++di)
147 outputW->mutableY(di) = 0.0;
155 g_log.
debug() <<
"[GetDetectorOffsets]: CREATING new MaskWorkspace.\n";
157 maskWS = std::make_shared<MaskWorkspace>(
inputW->getInstrument());
159 g_log.
debug() <<
"[GetDetectorOffsets]: Using EXISTING MaskWorkspace.\n";
162 maskWS->combineFromDetectorMasks(
inputW->detectorInfo());
165 Progress prog(
this, 0.0, 1.0, nspec);
167 for (int64_t wi = 0; wi < nspec; ++wi) {
170 const auto &dets =
inputW->getSpectrum(
static_cast<size_t>(wi)).getDetectorIDs();
173 if (maskWS->isMasked(dets))
177 double offset =
fitSpectra(
static_cast<size_t>(wi));
178 bool spectrumIsMasked =
false;
180 g_log.
debug() <<
"[GetDetectorOffsets]: fit failure: offset: " << std::abs(offset)
181 <<
" is greater than maximum allowed: " <<
m_maxOffset <<
".\n";
182 spectrumIsMasked =
true;
189 for (
const auto &det : dets) {
190 if (spectrumIsMasked) {
191 maskWS->setMasked(det,
true);
195 if (!maskWS->isMasked(det))
196 outputW->setValue(det, offset);
204 maskWS->combineToDetectorMasks();
205 maskWS->combineToDetectorMasks(outputW->mutableDetectorInfo());
209 trace <<
"[GetDetectorOffsets]: Computed offsets:\n" << std::endl;
210 for (
size_t ns = 0; ns <
inputW->getNumberHistograms(); ++ns) {
211 const auto dets =
inputW->getSpectrum(ns).getDetectorIDs();
212 for (
const auto &det : dets)
213 trace <<
" " << outputW->getValue(det) << (maskWS->isMasked(det) ?
"*" :
"") <<
"\n";
224 std::string filename =
getProperty(
"GroupingFileName");
225 if (!filename.empty()) {
228 childAlg->setProperty(
"OffsetsWorkspace", outputW);
229 childAlg->setProperty(
"MaskWorkspace", maskWS);
230 childAlg->setPropertyValue(
"Filename", filename);
231 childAlg->executeAsChildAlg();
242 constexpr double FIT_FAILURE = DBL_MAX;
245 const auto &yValues =
inputW->y(wksp_index);
246 auto it = std::max_element(yValues.cbegin(), yValues.cend());
249 double peakHeight = *it;
250 const double peakLoc =
inputW->x(wksp_index)[
static_cast<size_t>(it - yValues.cbegin())];
254 if (std::isnan(peakHeight))
255 return (FIT_FAILURE);
260 const auto &histogram =
inputW->histogram(wksp_index);
261 const auto &vector_x = histogram.points();
265 if (start_index != stop_index) {
267 auto bkgdFunction = std::dynamic_pointer_cast<IBackgroundFunction>(fun_ptr->getFunction(0));
268 auto peakFunction = std::dynamic_pointer_cast<IPeakFunction>(fun_ptr->getFunction(1));
269 int result =
estimatePeakParameters(histogram, std::pair<size_t, size_t>(start_index, stop_index), peakFunction,
271 if (result != PeakFitResult::GOOD) {
273 <<
" bad result for estimating peak parameters, using default peak height and loc\n";
277 <<
" range size is zero when estimating peak parameters, using default peak height and loc\n";
289 fit_alg->setProperty(
"Function", fun_ptr);
291 fit_alg->setProperty(
"InputWorkspace",
inputW);
292 fit_alg->setProperty<
int>(
"WorkspaceIndex",
293 static_cast<int>(wksp_index));
294 fit_alg->setProperty(
"StartX",
m_Xmin);
295 fit_alg->setProperty(
"EndX",
m_Xmax);
296 fit_alg->setProperty(
"MaxIterations", 100);
298 fit_alg->executeAsChildAlg();
299 std::string fitStatus = fit_alg->getProperty(
"OutputStatus");
301 if (fitStatus !=
"success") {
302 g_log.
debug() <<
"[GetDetectorOffsets]: Fit algorithm failure: " << fitStatus <<
"\n";
303 return (FIT_FAILURE);
309 double offset = function->getParameter(3);
345 peak->setHeight(peakHeight);
346 peak->setCentre(peakLoc);
347 const double sigma(10.0);
348 peak->setFwhm(2.0 * std::sqrt(2.0 * M_LN2) *
sigma);
351 fitFunc->addFunction(background);
352 fitFunc->addFunction(peak);
354 return std::shared_ptr<IFunction>(fitFunc);
#define DECLARE_ALGORITHM(classname)
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_CRITICAL(name)
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
bool isDefault(const std::string &name) const
A composite function is a function containing other functions.
@ OptionalSave
to specify a file to write to but an empty string is
The FunctionFactory class is in charge of the creation of concrete instances of fitting functions.
std::shared_ptr< IFunction > createFunction(const std::string &type) const
Creates an instance of a function.
Helper class for reporting progress from algorithms.
A property class for workspaces.
API::MatrixWorkspace_sptr inputW
A pointer to the input workspace.
double m_Xmax
The end of the X range for fitting.
API::IFunction_sptr createFunction(const double peakHeight, const double peakLoc)
Create a function string from the given parameters and the algorithm inputs.
double m_dreference
The expected peak position in d-spacing (?)
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
double fitSpectra(const size_t wksp_index)
Call Gaussian as a Child Algorithm to fit the peak in a spectrum.
void init() override
Initialisation method.
bool m_estimateFWHM
Flag to estimate fwhm fit parameter.
void exec() override
Executes the algorithm.
double m_Xmin
The start of the X range for fitting.
double m_dideal
The known peak centre value from the NIST standard.
double m_maxOffset
The maximum absolute value of offsets.
Exception for when an item is not found in a collection.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
The Logger class is in charge of the publishing messages from the framework through various channels.
void debug(const std::string &msg)
Logs at debug level.
void notice(const std::string &msg)
Logs at notice level.
void error(const std::string &msg)
Logs at error level.
std::ostream & getLogStream(const Priority &priority)
gets the correct log stream for a priority
int getLevel() const
Returns the Logger's log level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
The concrete, templated class for properties.
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
MANTID_ALGORITHMS_DLL size_t findXIndex(const vector_like &vecx, const double x, const size_t startindex=0)
Get an index of a value in a sorted vector.
MANTID_ALGORITHMS_DLL int estimatePeakParameters(const HistogramData::Histogram &histogram, const std::pair< size_t, size_t > &peak_window, const API::IPeakFunction_sptr &peakfunction, const API::IBackgroundFunction_sptr &bkgdfunction, bool observe_peak_width, const EstimatePeakWidth peakWidthEstimateApproach, const double peakWidthPercentage, const double minPeakHeight)
Estimate peak parameters by 'observation'.
std::shared_ptr< const MaskWorkspace > MaskWorkspace_const_sptr
shared pointer to a const MaskWorkspace
std::shared_ptr< MaskWorkspace > MaskWorkspace_sptr
shared pointer to the MaskWorkspace class
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.