22#include <boost/math/special_functions/round.hpp>
30using namespace Kernel;
31using namespace Geometry;
33using namespace DataObjects;
41 "Name of the peaks workspace.");
43 std::make_shared<InstrumentValidator>()),
44 "A 2D workspace with X values of time of flight");
46 "Name of the output peaks workspace with integrated intensities.");
48 "Integrate TOF using IkedaCarpenter fit.\n"
49 "Default is false which is best for corrected data.");
51 "Integrate only peaks where run "
52 "number of peak matches run number of "
71 if (peaksW != inPeaksW)
72 peaksW = inPeaksW->clone();
77 if (peaksW->mutableSample().hasOrientedLattice()) {
79 qspan = 1. / std::max(latt.
a(), std::max(latt.
b(), latt.
c()));
86 const auto pixel_to_wi =
inputW->getDetectorIDToWorkspaceIndexMap();
95 const auto YLength =
static_cast<int>(
inputW->blocksize());
99 size_t Numberwi =
inputW->getNumberHistograms();
100 int NumberPeaks = peaksW->getNumberPeaks();
103 std::vector<int> badPeaks;
104 for (
int i = NumberPeaks - 1; i >= 0; i--) {
105 Peak &peak = peaksW->getPeaks()[i];
109 auto wiEntry = pixel_to_wi.find(pixelID);
110 if (wiEntry != pixel_to_wi.end()) {
111 size_t wi = wiEntry->second;
113 badPeaks.emplace_back(i);
116 if (i + 1 > MinPeaks)
119 peaksW->removePeaks(std::move(badPeaks));
120 NumberPeaks = peaksW->getNumberPeaks();
121 if (NumberPeaks <= 0) {
122 g_log.
error(
"RunNumbers of InPeaksWorkspace and InputWorkspace do not match");
126 Progress prog(
this, MinPeaks, 1.0, NumberPeaks);
128 for (
int i = MinPeaks; i < NumberPeaks; i++) {
133 Peak &peak = peaksW->getPeaks()[i];
135 double col = peak.
getCol();
136 double row = peak.getRow();
139 int XPeak = boost::math::iround(col);
140 int YPeak = boost::math::iround(row);
142 double TOFPeakd = peak.getTOF();
143 std::string bankName = peak.getBankName();
145 std::shared_ptr<const IComponent> parent =
inputW->getInstrument()->getComponentByName(bankName);
150 int TOFPeak = 0, TOFmin = 0, TOFmax = 0;
151 TOFmax =
fitneighbours(i, bankName, XPeak, YPeak, i, qspan, peaksW, pixel_to_wi);
153 double I = 0., sigI = 0.;
159 auto numbins =
static_cast<int>(
Y.size());
160 if (TOFmin > numbins)
162 if (TOFmax > numbins)
166 const double peakLoc =
X[TOFPeak];
168 for (iTOF = TOFmin; iTOF < TOFmax; iTOF++) {
169 if (
Y[iTOF] > 0.0 &&
Y[iTOF + 1] > 0.0)
173 for (iTOF = TOFmax; iTOF > TOFmin; iTOF--) {
174 if (
Y[iTOF] > 0.0 &&
Y[iTOF - 1] > 0.0)
178 if (TOFmax <= TOFmin)
180 const int n = TOFmax - TOFmin + 1;
187 for (iTOF = TOFmin; iTOF <= TOFmax; iTOF++) {
188 if (((
Y[iTOF] -
Y[TOFPeak] / 2.) * (
Y[iTOF + 1] -
Y[TOFPeak] / 2.)) < 0.)
191 double Gamma =
fabs(
X[TOFPeak] -
X[iTOF]);
192 double SigmaSquared = Gamma * Gamma;
193 const double peakHeight =
Y[TOFPeak] * Gamma;
207 std::ostringstream fun_str;
208 fun_str <<
"name=IkedaCarpenterPV,I=" << peakHeight <<
",Alpha0=" << Alpha0 <<
",Alpha1=" << Alpha1
209 <<
",Beta0=" << Beta0 <<
",Kappa=" << Kappa <<
",SigmaSquared=" << SigmaSquared <<
",Gamma=" << Gamma
210 <<
",X0=" << peakLoc;
211 fit_alg->setPropertyValue(
"Function", fun_str.str());
212 if (Alpha0 != 1.6 || Alpha1 != 1.5 || Beta0 != 31.9 || Kappa != 46.0) {
213 std::ostringstream tie_str;
214 tie_str <<
"Alpha0=" << Alpha0 <<
",Alpha1=" << Alpha1 <<
",Beta0=" << Beta0 <<
",Kappa=" << Kappa;
215 fit_alg->setProperty(
"Ties", tie_str.str());
217 fit_alg->setProperty(
"InputWorkspace",
outputW);
218 fit_alg->setProperty(
"WorkspaceIndex", i);
219 fit_alg->setProperty(
"StartX",
X[TOFmin]);
220 fit_alg->setProperty(
"EndX",
X[TOFmax]);
221 fit_alg->setProperty(
"MaxIterations", 5000);
222 fit_alg->setProperty(
"CreateOutput",
true);
223 fit_alg->setProperty(
"Output",
"fit");
224 fit_alg->executeAsChildAlg();
242 const auto &
y = fitWS->y(1);
245 for (iTOF = 0; iTOF <
n; iTOF++)
246 if (std::isfinite(
y[iTOF]))
249 for (iTOF = TOFmin; iTOF <= TOFmax; iTOF++)
253 sigI = peak.getSigmaIntensity();
256 for (iTOF = TOFmin; iTOF <= TOFmax; iTOF++)
257 sigI += E[iTOF] * E[iTOF];
261 peak.setIntensity(I);
262 peak.setSigmaIntensity(sigI);
276 if (
inputW->y(0).size() <= 1)
277 throw std::runtime_error(
"Must Rebin data with more than 1 bin");
280 std::shared_ptr<RectangularDetector> det;
281 for (
int i = 0; i < inst->nelements(); i++) {
282 det = std::dynamic_pointer_cast<RectangularDetector>((*inst)[i]);
293 Peak &peak = Peaks->getPeak(ipeak);
299 std::ostringstream tab_str;
300 tab_str <<
"LogTable" << ipeak;
302 slice_alg->setPropertyValue(
"OutputWorkspace", tab_str.str());
304 slice_alg->setProperty(
"PeakIndex", ipeak);
305 slice_alg->setProperty(
"PeakQspan", qspan);
307 int nPixels = std::max<int>(0,
getProperty(
"NBadEdgePixels"));
309 slice_alg->setProperty(
"NBadEdgePixels", nPixels);
310 slice_alg->executeAsChildAlg();
312 auto &Xout =
outputW->mutableX(idet);
313 auto &Yout =
outputW->mutableY(idet);
314 auto &Eout =
outputW->mutableE(idet);
320 TOFmax =
static_cast<int>(logtable->rowCount());
321 for (
int iTOF = 0; iTOF < TOFmax; iTOF++) {
322 Xout[iTOF] = logtable->getRef<
double>(std::string(
"Time"), iTOF);
325 Yout[iTOF] = logtable->getRef<
double>(std::string(
"TotIntensity"), iTOF);
326 Eout[iTOF] = logtable->getRef<
double>(std::string(
"TotIntensityError"), iTOF);
328 Yout[iTOF] = logtable->getRef<
double>(std::string(
"ISAWIntensity"), iTOF);
329 Eout[iTOF] = logtable->getRef<
double>(std::string(
"ISAWIntensityError"), iTOF);
333 outputW->getSpectrum(idet).clearDetectorIDs();
338 auto wiEntry = pixel_to_wi.find(pixelID);
339 if (wiEntry != pixel_to_wi.end()) {
340 size_t wi = wiEntry->second;
342 outputW->getSpectrum(idet).addDetectorIDs(
inputW->getSpectrum(wi).getDetectorIDs());
#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_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.
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
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.
Helper class for reporting progress from algorithms.
A property class for workspaces.
bool m_IC
Ikeida Carpenter fit of TOF.
void retrieveProperties()
Read in all the input parameters.
int fitneighbours(int ipeak, const std::string &det_name, int x0, int y0, int idet, double qspan, DataObjects::PeaksWorkspace_sptr &Peaks, const detid2index_map &pixel_to_wi)
API::MatrixWorkspace_sptr outputW
A pointer to the output workspace.
void exec() override
Executes the algorithm.
void init() override
Initialisation method.
API::MatrixWorkspace_sptr inputW
A pointer to the input workspace.
void setSigmaIntensity(double m_sigmaIntensity) override
Set the error on the integrated peak intensity.
int getRunNumber() const override
Return the run number this peak was measured at.
void setIntensity(double m_intensity) override
Set the integrated peak intensity.
Structure describing a single-crystal peak.
int getCol() const override
For RectangularDetectors only, returns the column (x) of the pixel of the detector or -1 if not found...
int getDetectorID() const
Get the ID of the detector at the center of the peak
Class to implement UB matrix.
double a(int nd) const
Get lattice parameter a1-a3 as function of index (0-2)
double c() const
Get lattice parameter.
double b() const
Get lattice parameter.
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.
void error(const std::string &msg)
Logs at error level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< const EventWorkspace > EventWorkspace_const_sptr
shared pointer to a const Workspace2D
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
MANTID_KERNEL_DLL int getBinIndex(const std::vector< double > &bins, const double value)
Return the index into a vector of bin boundaries for a particular X value.
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.
std::unordered_map< detid_t, size_t > detid2index_map
Map with key = detector ID, value = workspace index.
@ Input
An input workspace.
@ Output
An output workspace.