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 const &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);
114 }
else if (i + 1 > MinPeaks) {
120 peaksW->removePeaks(std::move(badPeaks));
121 NumberPeaks = peaksW->getNumberPeaks();
122 if (NumberPeaks <= 0) {
123 g_log.
error(
"RunNumbers of InPeaksWorkspace and InputWorkspace do not match");
127 Progress prog(
this, MinPeaks, 1.0, NumberPeaks);
129 for (
int i = MinPeaks; i < NumberPeaks; i++) {
134 Peak &peak = peaksW->getPeaks()[i];
136 double col = peak.
getCol();
137 double row = peak.getRow();
140 int XPeak = boost::math::iround(col);
141 int YPeak = boost::math::iround(row);
143 double TOFPeakd = peak.getTOF();
144 std::string bankName = peak.getBankName();
146 std::shared_ptr<const IComponent> parent =
inputW->getInstrument()->getComponentByName(bankName);
151 int TOFPeak = 0, TOFmin = 0, TOFmax = 0;
152 TOFmax =
fitneighbours(i, bankName, XPeak, YPeak, i, qspan, peaksW, pixel_to_wi);
154 double I = 0., sigI = 0.;
160 auto numbins =
static_cast<int>(
Y.size());
161 if (TOFmin > numbins)
163 if (TOFmax > numbins)
167 const double peakLoc =
X[TOFPeak];
169 for (iTOF = TOFmin; iTOF < TOFmax; iTOF++) {
170 if (
Y[iTOF] > 0.0 &&
Y[iTOF + 1] > 0.0)
174 for (iTOF = TOFmax; iTOF > TOFmin; iTOF--) {
175 if (
Y[iTOF] > 0.0 &&
Y[iTOF - 1] > 0.0)
179 if (TOFmax <= TOFmin)
181 const int n = TOFmax - TOFmin + 1;
188 for (iTOF = TOFmin; iTOF <= TOFmax; iTOF++) {
189 if (((
Y[iTOF] -
Y[TOFPeak] / 2.) * (
Y[iTOF + 1] -
Y[TOFPeak] / 2.)) < 0.)
192 double Gamma =
fabs(
X[TOFPeak] -
X[iTOF]);
193 double SigmaSquared = Gamma * Gamma;
194 const double peakHeight =
Y[TOFPeak] * Gamma;
208 std::ostringstream fun_str;
209 fun_str <<
"name=IkedaCarpenterPV,I=" << peakHeight <<
",Alpha0=" << Alpha0 <<
",Alpha1=" << Alpha1
210 <<
",Beta0=" << Beta0 <<
",Kappa=" << Kappa <<
",SigmaSquared=" << SigmaSquared <<
",Gamma=" << Gamma
211 <<
",X0=" << peakLoc;
212 fit_alg->setPropertyValue(
"Function", fun_str.str());
213 if (Alpha0 != 1.6 || Alpha1 != 1.5 || Beta0 != 31.9 || Kappa != 46.0) {
214 std::ostringstream tie_str;
215 tie_str <<
"Alpha0=" << Alpha0 <<
",Alpha1=" << Alpha1 <<
",Beta0=" << Beta0 <<
",Kappa=" << Kappa;
216 fit_alg->setProperty(
"Ties", tie_str.str());
218 fit_alg->setProperty(
"InputWorkspace",
outputW);
219 fit_alg->setProperty(
"WorkspaceIndex", i);
220 fit_alg->setProperty(
"StartX",
X[TOFmin]);
221 fit_alg->setProperty(
"EndX",
X[TOFmax]);
222 fit_alg->setProperty(
"MaxIterations", 5000);
223 fit_alg->setProperty(
"CreateOutput",
true);
224 fit_alg->setProperty(
"Output",
"fit");
225 fit_alg->executeAsChildAlg();
243 const auto &
y = fitWS->y(1);
246 for (iTOF = 0; iTOF <
n; iTOF++)
247 if (std::isfinite(
y[iTOF]))
250 for (iTOF = TOFmin; iTOF <= TOFmax; iTOF++)
254 sigI = peak.getSigmaIntensity();
257 for (iTOF = TOFmin; iTOF <= TOFmax; iTOF++)
258 sigI += E[iTOF] * E[iTOF];
262 peak.setIntensity(I);
263 peak.setSigmaIntensity(sigI);
277 if (
inputW->y(0).size() <= 1)
278 throw std::runtime_error(
"Must Rebin data with more than 1 bin");
281 std::shared_ptr<RectangularDetector> det;
282 for (
int i = 0; i < inst->nelements(); i++) {
283 det = std::dynamic_pointer_cast<RectangularDetector>((*inst)[i]);
294 Peak &peak = Peaks->getPeak(ipeak);
300 std::ostringstream tab_str;
301 tab_str <<
"LogTable" << ipeak;
303 slice_alg->setPropertyValue(
"OutputWorkspace", tab_str.str());
305 slice_alg->setProperty(
"PeakIndex", ipeak);
306 slice_alg->setProperty(
"PeakQspan", qspan);
308 int nPixels = std::max<int>(0,
getProperty(
"NBadEdgePixels"));
310 slice_alg->setProperty(
"NBadEdgePixels", nPixels);
311 slice_alg->executeAsChildAlg();
313 auto &Xout =
outputW->mutableX(idet);
314 auto &Yout =
outputW->mutableY(idet);
315 auto &Eout =
outputW->mutableE(idet);
321 TOFmax =
static_cast<int>(logtable->rowCount());
322 for (
int iTOF = 0; iTOF < TOFmax; iTOF++) {
323 Xout[iTOF] = logtable->getRef<
double>(std::string(
"Time"), iTOF);
326 Yout[iTOF] = logtable->getRef<
double>(std::string(
"TotIntensity"), iTOF);
327 Eout[iTOF] = logtable->getRef<
double>(std::string(
"TotIntensityError"), iTOF);
329 Yout[iTOF] = logtable->getRef<
double>(std::string(
"ISAWIntensity"), iTOF);
330 Eout[iTOF] = logtable->getRef<
double>(std::string(
"ISAWIntensityError"), iTOF);
334 outputW->getSpectrum(idet).clearDetectorIDs();
339 auto wiEntry = pixel_to_wi.find(pixelID);
340 if (wiEntry != pixel_to_wi.end()) {
341 size_t wi = wiEntry->second;
343 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 override
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.