Mantid
Loading...
Searching...
No Matches
GetAllEi.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8#include "MantidAPI/Axis.h"
10#include "MantidAPI/Run.h"
17#include "MantidIndexing/Extract.h"
18#include "MantidIndexing/IndexInfo.h"
22#include "MantidKernel/Unit.h"
25
26#include <boost/algorithm/string.hpp>
27#include <boost/format.hpp>
28
29#include <string>
30
31namespace Mantid::Algorithms {
32
33using namespace Mantid::DataObjects;
34using namespace Mantid::HistogramData;
35DECLARE_ALGORITHM(GetAllEi)
36
37
39 : Algorithm(), m_FilterWithDerivative(true),
40 // minimal resolution for all instruments
41 m_min_Eresolution(0.08),
42 // half maximal resolution for LET
43 m_max_Eresolution(0.5e-3), m_peakEnergyRatio2reject(0.1), m_phase(0), m_chopper(), m_pFilterLog(nullptr) {}
44
47
50 "The input workspace containing the monitor's spectra "
51 "measured after the last chopper");
52 auto nonNegative = std::make_shared<Kernel::BoundedValidator<int>>();
53 nonNegative->setLower(0);
54
55 declareProperty("Monitor1SpecID", EMPTY_INT(), nonNegative,
56 "The workspace index (ID) of the spectra, containing first monitor's"
57 " signal to analyze.");
58 declareProperty("Monitor2SpecID", EMPTY_INT(), nonNegative,
59 "The workspace index (ID) of the spectra, containing second monitor's"
60 " signal to analyze.");
61
62 declareProperty("ChopperSpeedLog", "Defined in IDF",
63 "Name of the instrument log, "
64 "containing chopper angular velocity. If 'Defined in IDF' "
65 "option is specified, "
66 "the log name is obtained from the IDF");
67 declareProperty("ChopperDelayLog", "Defined in IDF",
68 "Name of the instrument log, "
69 "containing chopper delay time or chopper phase v.r.t. the pulse time. "
70 "If 'Defined in IDF' option is specified, "
71 "the log name is obtained from IDF");
72 declareProperty("FilterBaseLog", "Defined in IDF",
73 "Name of the instrument log, "
74 "with positive values indicating that instrument is running\n "
75 "and 0 or negative that it is not.\n"
76 "The log is used to identify time interval to evaluate"
77 " chopper speed and chopper delay which matter.\n"
78 "If such log is not present, average log values are calculated "
79 "within experiment start&end time range.");
80 declareProperty("FilterWithDerivative", true,
81 "Use derivative of 'FilterBaseLog' "
82 "rather then log values itself to filter invalid time intervals.\n"
83 "Invalid values are then the "
84 "values where the derivative of the log turns zero.\n"
85 "E.g. the 'proton_chage' log grows for each frame "
86 "when instrument is counting and is constant otherwise.");
87 setPropertySettings("FilterWithDerivative",
88 std::make_unique<Kernel::EnabledWhenProperty>(
89 "FilterBaseLog", Kernel::ePropertyCriterion::IS_EQUAL_TO, "Defined in IDF"));
90
91 auto maxInRange = std::make_shared<Kernel::BoundedValidator<double>>();
92 maxInRange->setLower(1.e-6);
93 maxInRange->setUpper(0.1);
94
95 declareProperty("MaxInstrResolution", 0.0005, maxInRange,
96 "The maximal energy resolution possible for an "
97 "instrument at working energies (full width at half "
98 "maximum). \nPeaks, sharper then "
99 "this width are rejected. Accepted limits are: 1e^(-6)-0.1");
100
101 auto minInRange = std::make_shared<Kernel::BoundedValidator<double>>();
102 minInRange->setLower(0.001);
103 minInRange->setUpper(0.5);
104 declareProperty("MinInstrResolution", 0.08, minInRange,
105 "The minimal energy resolution possible for an "
106 "instrument at working energies (full width at half maximum).\n"
107 "Peaks broader then this width are rejected. Accepted limits are: "
108 "0.001-0.5");
109
110 auto peakInRange = std::make_shared<Kernel::BoundedValidator<double>>();
111 peakInRange->setLower(0.0);
112 minInRange->setUpper(1.);
113 declareProperty("PeaksRatioToReject", 0.1, peakInRange,
114 "Ratio of a peak energy to the maximal energy among all peaks. "
115 "If the ratio is lower then the value specified here, "
116 "peak is treated as insignificant and rejected.\n"
117 "Accepted limits are:0.0 (All accepted) to 1 -- only one peak \n"
118 "(or peaks with max and equal intensity) are accepted.");
119 declareProperty("IgnoreSecondMonitor", false,
120 "Usually peaks are analyzed and accepted "
121 "only if identified on both monitors. If this property is set to true, "
122 "only first monitor peaks are analyzed.\n"
123 "This is debugging option as getEi has to use both monitors.");
124
126 std::make_unique<API::WorkspaceProperty<API::Workspace>>("OutputWorkspace", "", Kernel::Direction::Output),
127 "Name of the output matrix workspace, containing single spectra with"
128 " monitor peaks energies\n"
129 "together with total intensity within each peak.");
130}
131
132// unnamed namespace for auxiliary file-based compilation units
133namespace {
134
141template <class T> void removeInvalidValues(const std::vector<bool> &guessValid, std::vector<T> &guess) {
142 std::vector<T> new_guess;
143 new_guess.reserve(guess.size());
144
145 for (size_t i = 0; i < guessValid.size(); i++) {
146 if (guessValid[i]) {
147 new_guess.emplace_back(guess[i]);
148 }
149 }
150 new_guess.swap(guess);
151}
153struct peakKeeper {
154 double position;
155 double height;
156 double sigma;
157 double energy;
158
159 peakKeeper(double pos, double heigh, double sig) : position(pos), height(heigh), sigma(sig) {
160 this->energy = std::sqrt(2 * M_PI) * height * sigma;
161 }
162 // to sort peaks
163 bool operator<(const peakKeeper &str) const { return (energy > str.energy); }
164};
165
166} // namespace
167
170 // Get pointers to the workspace, parameter map and table
171 API::MatrixWorkspace_sptr inputWS = getProperty("Workspace");
172 m_min_Eresolution = getProperty("MinInstrResolution");
173 m_max_Eresolution = getProperty("MaxInstrResolution");
174 m_peakEnergyRatio2reject = getProperty("PeaksRatioToReject");
175
177 auto pInstrument = inputWS->getInstrument();
178 // auto lastChopPositionComponent =
179 // pInstrument->getComponentByName("chopper-position");
180 // auto chopPoint1 = pInstrument->getChopperPoint(0); ->TODO: BUG! this
181 // operation loses parameters map.
182 m_chopper = pInstrument->getComponentByName("chopper-position");
183 if (!m_chopper)
184 throw std::runtime_error("Instrument " + inputWS->getInstrumentName() +
185 " does not have 'chopper-position' component");
186
187 auto phase = m_chopper->getNumberParameter("initial_phase");
188
189 if (phase.empty()) {
190 throw std::runtime_error("Can not find initial_phase parameter"
191 " attached to the chopper-position component");
192 }
193 if (phase.size() > 1) {
194 throw std::runtime_error("Can not deal with multiple phases for initial_phase"
195 " parameter attached to the chopper-position component");
196 }
197 m_phase = phase[0];
198
199 this->setFilterLog(inputWS);
200
201 // auto chopPoint1 = pInstrument->getComponentByName("fermi-chopper");
202 // auto par = chopPoint1->getDoubleParameter("Delay (us)");
203 double chopSpeed, chopDelay;
204 findChopSpeedAndDelay(inputWS, chopSpeed, chopDelay);
205 g_log.debug() << boost::str(boost::format("*Identified avrg ChopSpeed: %8.2f and Delay: %8.2f\n") % chopSpeed %
206 chopDelay);
207
208 auto moderator = pInstrument->getSource();
209 double chopDistance = m_chopper->getDistance(*moderator); // location[0].distance(moderator->getPos());
210 double velocity = chopDistance / chopDelay;
211
212 // build workspace to find monitor's peaks
213 size_t det1WSIndex;
214 auto monitorWS = buildWorkspaceToFit(inputWS, det1WSIndex);
215
216 // recalculate delay time from chopper position to monitor position
217 const auto &detector1 = inputWS->spectrumInfo().detector(det1WSIndex);
218 double mon1Distance = detector1.getDistance(*moderator);
219 double TOF0 = mon1Distance / velocity;
220
221 //--->> below is reserved until full chopper's implementation is available;
222 // auto nChoppers = pInstrument->getNumberOfChopperPoints();
223 // get last chopper.
224 /*
225 if( nChoppers==0)throw std::runtime_error("Instrument does not have any
226 choppers defined");
227
228 auto lastChopper = pInstrument->getChopperPoint(nChoppers-1);
230 */
231 auto &baseSpectrum = inputWS->getSpectrum(det1WSIndex);
232 std::pair<double, double> TOF_range = baseSpectrum.getXDataRange();
233
234 double Period = (0.5 * 1.e+6) / chopSpeed; // 0.5 because some choppers open twice.
235 // Would be nice to have it 1 or 0.5 depending on chopper type, but
236 // it looks like not enough information on what chopper is available on ws;
237 auto destUnit = Kernel::UnitFactory::Instance().create("Energy");
238
239 std::vector<double> guess_opening;
240
241 this->findGuessOpeningTimes(TOF_range, TOF0, Period, guess_opening);
242 if (guess_opening.empty()) {
243 throw std::runtime_error(
244 "Can not find any chopper opening time within TOF range: " + boost::lexical_cast<std::string>(TOF_range.first) +
245 ':' + boost::lexical_cast<std::string>(TOF_range.second));
246 } else {
247 destUnit->initialize(mon1Distance, static_cast<int>(Kernel::DeltaEMode::Elastic), {{Kernel::UnitParams::l2, 0.}});
248 printDebugModeInfo(guess_opening, TOF_range, destUnit);
249 }
250 std::pair<double, double> Mon1_Erange = monitorWS->getSpectrum(0).getXDataRange();
251 std::pair<double, double> Mon2_Erange = monitorWS->getSpectrum(1).getXDataRange();
252 double eMin = std::max(Mon1_Erange.first, Mon2_Erange.first);
253 double eMax = std::min(Mon1_Erange.second, Mon2_Erange.second);
254 g_log.debug() << boost::str(boost::format("Monitors record data in energy range Emin=%8.2f; Emax=%8.2f\n") % eMin %
255 eMax);
256
257 // convert to energy
258 std::vector<double> guess_ei;
259 guess_ei.reserve(guess_opening.size());
260 destUnit->initialize(mon1Distance, static_cast<int>(Kernel::DeltaEMode::Elastic), {{Kernel::UnitParams::l2, 0.}});
261 for (double time : guess_opening) {
262 double eGuess = destUnit->singleFromTOF(time);
263 if (eGuess > eMin && eGuess < eMax) {
264 guess_ei.emplace_back(eGuess);
265 }
266 }
267 g_log.debug() << "*From all chopper opening only: " + std::to_string(guess_ei.size()) +
268 " fell within both monitor's recording energy range\n";
269 g_log.debug() << " Guess Energies are:\n";
270 for (double ei : guess_ei) {
271 g_log.debug() << boost::str(boost::format(" %8.2f; ") % ei);
272 }
273 g_log.debug() << '\n';
274
275 std::sort(guess_ei.begin(), guess_ei.end());
276
277 std::vector<size_t> irange_min, irange_max;
278 std::vector<bool> guessValid;
279 // preprocess first monitors peaks;
280 g_log.debug() << "*Looking for real energy peaks on first monitor\n";
281 findBinRanges(monitorWS->x(0), monitorWS->y(0), guess_ei, this->m_min_Eresolution / (2. * std::sqrt(2. * M_LN2)),
282 irange_min, irange_max, guessValid);
283
284 // remove invalid guess values
285 removeInvalidValues<double>(guessValid, guess_ei);
286
287 // preprocess second monitors peaks
288 std::vector<size_t> irange1_min, irange1_max;
289 if (!this->getProperty("IgnoreSecondMonitor")) {
290 g_log.debug() << "*Looking for real energy peaks on second monitor\n";
291 findBinRanges(monitorWS->x(1), monitorWS->y(1), guess_ei, this->m_min_Eresolution / (2. * std::sqrt(2. * M_LN2)),
292 irange1_min, irange1_max, guessValid);
293 removeInvalidValues<double>(guessValid, guess_ei);
294 removeInvalidValues<size_t>(guessValid, irange_min);
295 removeInvalidValues<size_t>(guessValid, irange_max);
296 } else {
297 // this is wrong but will not be used anyway
298 // (except formally looping through vector)
299 irange1_min.assign(irange_min.begin(), irange_min.end());
300 irange1_max.assign(irange_max.begin(), irange_max.end());
301 }
302 g_log.debug() << "*Identified: " + std::to_string(guess_ei.size()) +
303 " peaks with sufficient signal around guess chopper opening\n";
304
305 std::vector<peakKeeper> peaks;
306
307 double maxPeakEnergy(0);
308 std::vector<size_t> monsRangeMin(2), monsRangeMax(2);
309 for (size_t i = 0; i < guess_ei.size(); i++) {
310 monsRangeMin[0] = irange_min[i];
311 monsRangeMax[0] = irange_max[i];
312 monsRangeMin[1] = irange1_min[i];
313 monsRangeMax[1] = irange1_max[i];
314
315 double energy, height, twoSigma;
316 bool found = findMonitorPeak(monitorWS, guess_ei[i], monsRangeMin, monsRangeMax, energy, height, twoSigma);
317 if (found) {
318 peaks.emplace_back(energy, height, 0.5 * twoSigma);
319 if (peaks.back().energy > maxPeakEnergy)
320 maxPeakEnergy = peaks.back().energy;
321 }
322 }
323 monitorWS.reset();
324
325 size_t nPeaks = peaks.size();
326 if (nPeaks == 0) {
327 throw std::runtime_error("Can not identify any energy peaks");
328 }
329 // sort peaks and remove invalid one
330 guessValid.resize(nPeaks);
331 bool needsRemoval(false);
332 for (size_t i = 0; i < nPeaks; i++) {
333 peaks[i].energy /= maxPeakEnergy;
334 if (peaks[i].energy < m_peakEnergyRatio2reject) {
335 guessValid[i] = false;
336 g_log.debug() << "*Rejecting peak at Ei=" + boost::lexical_cast<std::string>(peaks[i].position) +
337 " as its total energy lower then the threshold\n";
338 needsRemoval = true;
339 } else {
340 guessValid[i] = true;
341 }
342 }
343 if (needsRemoval)
344 removeInvalidValues<peakKeeper>(guessValid, peaks);
345 nPeaks = peaks.size();
346 // sort by energy decreasing -- see class definition
347 std::sort(peaks.begin(), peaks.end());
348
349 // finalize output
350 auto result_ws = create<Workspace2D>(1, Points(nPeaks));
351
352 HistogramX peaks_positions(peaks.size());
353 std::transform(peaks.cbegin(), peaks.cend(), peaks_positions.begin(),
354 [](const peakKeeper &peak) { return peak.position; });
355 auto &Signal = result_ws->mutableY(0);
356 std::transform(peaks.cbegin(), peaks.cend(), Signal.begin(), [](const peakKeeper &peak) { return peak.height; });
357
358 auto &Error = result_ws->mutableE(0);
359 std::transform(peaks.cbegin(), peaks.cend(), Error.begin(), [](const peakKeeper &peak) { return peak.sigma; });
360
361 result_ws->setPoints(0, peaks_positions);
362
363 setProperty("OutputWorkspace", std::move(result_ws));
364}
374void GetAllEi::printDebugModeInfo(const std::vector<double> &guess_opening, const std::pair<double, double> &TOF_range,
375 std::shared_ptr<Kernel::Unit> &destUnit) {
376
377 g_log.debug() << "*Found : " << guess_opening.size()
378 << " chopper prospective opening within time frame: " << TOF_range.first << " to: " << TOF_range.second
379 << '\n';
380 g_log.debug() << " Timings are:\n";
381 for (double time : guess_opening) {
382 g_log.debug() << boost::str(boost::format(" %8.2f; ") % time);
383 }
384 g_log.debug() << '\n';
385 g_log.debug() << " Corresponding to energies:\n";
386 for (double time : guess_opening) {
387 double ei = destUnit->singleFromTOF(time);
388 g_log.debug() << boost::str(boost::format(" %8.2f; ") % ei);
389 }
390 g_log.debug() << '\n';
391}
392
393// unnamed namespace for auxiliary file-based functions, converted from lambda
394// as not all Mantid compilers support lambda yet.
395
402
403 std::string filerLogName;
404 std::string filterBase = getProperty("FilterBaseLog");
405 if (boost::iequals(filterBase, "Defined in IDF")) {
406 filerLogName = m_chopper->getStringParameter("FilterBaseLog")[0];
407 m_FilterWithDerivative = m_chopper->getBoolParameter("filter_with_derivative")[0];
408 } else {
409 filerLogName = filterBase;
410 m_FilterWithDerivative = getProperty("FilterWithDerivative");
411 }
412 try {
413 m_pFilterLog = dynamic_cast<Kernel::TimeSeriesProperty<double> *>(inputWS->run().getProperty(filerLogName));
414 } catch (std::runtime_error &) {
415 g_log.warning() << " Can not retrieve (double) filtering log: " + filerLogName +
416 " from current workspace\n"
417 " Using total experiment range to "
418 "find logs averages for chopper parameters\n";
420 }
421}
437bool GetAllEi::peakGuess(const API::MatrixWorkspace_sptr &inputWS, size_t index, double Ei,
438 const std::vector<size_t> &monsRangeMin, const std::vector<size_t> &monsRangeMax,
439 double &peakPos, double &peakHeight, double &peakTwoSigma) {
440
441 // calculate sigma from half-width parameters
442 double maxSigma = Ei * m_min_Eresolution / (2. * std::sqrt(2. * M_LN2));
443
444 double sMin(std::numeric_limits<double>::max());
445 double sMax(-sMin);
446 double xOfMax(0), dXmax(0);
447 double Intensity(0);
448
449 const auto &X = inputWS->x(index);
450 const auto &S = inputWS->y(index);
451 size_t ind_min = monsRangeMin[index];
452 size_t ind_max = monsRangeMax[index];
453 // interval too small -- not interested in a peak there
454 if (std::fabs(double(ind_max - ind_min)) < 5)
455 return false;
456
457 // double xMin = X[ind_min];
458 // double xMax = X[ind_max];
459 // size_t ind_Ofmax(ind_min);
460
461 for (size_t i = ind_min; i < ind_max; i++) {
462 double dX = X[i + 1] - X[i];
463 double signal = S[i] / dX;
464 if (signal < sMin)
465 sMin = signal;
466 if (signal > sMax) {
467 sMax = signal;
468 dXmax = dX;
469 xOfMax = X[i];
470 // ind_Ofmax=i;
471 }
472 Intensity += S[i];
473 }
474 // monitor peak should not have just two counts in it.
475 if (sMax * dXmax <= 2)
476 return false;
477 //
478 // size_t SearchAreaSize = ind_max - ind_min;
479
480 double SmoothRange = 2 * maxSigma;
481
482 std::vector<double> SAvrg, binsAvrg;
483 Kernel::VectorHelper::smoothInRange(S, SAvrg, SmoothRange, X, ind_min, ind_max, &binsAvrg);
484
485 double realPeakPos(xOfMax); // this position is less shifted
486 // due to the skew in averaging formula
487 bool foundRealPeakPos(false);
488 std::vector<double> der1Avrg, der2Avrg, peaks, hillsPos, SAvrg1, binsAvrg1;
489 size_t nPeaks = this->calcDerivativeAndCountZeros(binsAvrg, SAvrg, der1Avrg, peaks);
490 size_t nHills = this->calcDerivativeAndCountZeros(binsAvrg, der1Avrg, der2Avrg, hillsPos);
491 if (nPeaks == 1) {
492 foundRealPeakPos = true;
493 realPeakPos = peaks[0];
494 }
495
496 size_t ic(0), stay_still_count(0);
497 bool iterations_fail(false);
498 while ((nPeaks > 1 || nHills > 2) && (!iterations_fail)) {
499 Kernel::VectorHelper::smoothInRange(SAvrg, SAvrg1, SmoothRange, binsAvrg, 0, ind_max - ind_min, &binsAvrg1);
500 const auto nPrevHills = nHills;
501
502 nPeaks = this->calcDerivativeAndCountZeros(binsAvrg1, SAvrg1, der1Avrg, peaks);
503 nHills = this->calcDerivativeAndCountZeros(binsAvrg1, der1Avrg, der2Avrg, hillsPos);
504 SAvrg.swap(SAvrg1);
505 binsAvrg.swap(binsAvrg1);
506 if (nPeaks == 1 && !foundRealPeakPos) { // fix first peak position found
507 foundRealPeakPos = true; // as averaging shift peaks on
508 realPeakPos = peaks[0]; // irregular grid.
509 }
510 ic++;
511 if (nPrevHills <= nHills) {
512 stay_still_count++;
513 } else {
514 stay_still_count = 0;
515 }
516 if (ic > 50 || stay_still_count > 3)
517 iterations_fail = true;
518 }
519 if (iterations_fail) {
520 g_log.information() << "*No peak search convergence after " + std::to_string(ic) +
521 " smoothing iterations at still_count: " + std::to_string(stay_still_count) +
522 " Wrong energy or noisy peak at Ei=" + boost::lexical_cast<std::string>(Ei)
523 << '\n';
524 }
525 g_log.debug() << "*Performed: " + std::to_string(ic) + " averages for spectra " + std::to_string(index) +
526 " at energy: " + boost::lexical_cast<std::string>(Ei) +
527 "\n and found: " + std::to_string(nPeaks) + "peaks and " + std::to_string(nHills) + " hills\n";
528 if (nPeaks != 1) {
529 g_log.debug() << "*Peak rejected as n-peaks !=1 after averaging\n";
530 return false;
531 }
532
533 peakPos = peaks[0];
534 if (nHills > 2) {
535 auto peakIndex = std::size_t(Kernel::VectorHelper::getBinIndex(hillsPos, peaks[0]));
536 peakTwoSigma = hillsPos[peakIndex + 1] - hillsPos[peakIndex];
537 } else {
538 if (hillsPos.size() == 2) {
539 peakTwoSigma = hillsPos[1] - hillsPos[0];
540 } else {
541 g_log.debug() << "*Peak rejected as averaging gives: " + std::to_string(nPeaks) + " peaks and " +
542 std::to_string(nHills) + " heals\n";
543
544 return false;
545 }
546 }
547 // assuming that averaging conserves intensity and removing linear
548 // background:
549 peakHeight = Intensity / (0.5 * std::sqrt(2. * M_PI) * peakTwoSigma) - sMin;
550 peakPos = realPeakPos;
551
552 return true;
553}
554
568 const std::vector<size_t> &monsRangeMin, const std::vector<size_t> &monsRangeMax,
569 double &position, double &height, double &twoSigma) {
570 // calculate sigma from half-width parameters
571 double maxSigma = Ei * m_min_Eresolution / (2. * std::sqrt(2. * M_LN2));
572 double minSigma = Ei * m_max_Eresolution / (2. * std::sqrt(2. * M_LN2));
573 //--------------------------------------------------------------------
574 double peak1Pos, peak1TwoSigma, peak1Height;
575 if (!peakGuess(inputWS, 0, Ei, monsRangeMin, monsRangeMax, peak1Pos, peak1Height, peak1TwoSigma))
576 return false;
577 if (0.25 * peak1TwoSigma > maxSigma || peak1TwoSigma < minSigma) {
578 g_log.debug() << "*Rejecting due to width: Peak at mon1 Ei=" + boost::lexical_cast<std::string>(peak1Pos) +
579 " with Height:" + boost::lexical_cast<std::string>(peak1Height) +
580 " and 2*Sigma: " + boost::lexical_cast<std::string>(peak1TwoSigma)
581 << '\n';
582 return false;
583 }
584
585 if (!this->getProperty("IgnoreSecondMonitor")) {
586 double peak2Pos, peak2TwoSigma, peak2Height;
587 if (!peakGuess(inputWS, 1, Ei, monsRangeMin, monsRangeMax, peak2Pos, peak2Height, peak2TwoSigma))
588 return false;
589 // Let's not check anything except peak position for monitor2, as
590 // its intensity may be very low for some instruments.
591 // if(0.25*peak2TwoSigma>maxSigma||peak2TwoSigma<minSigma)return false;
592
593 // peak in first and second monitors are too far from each other. May be the
594 // instrument
595 // is ill-calibrated but GetEi will probably not find this peak anyway.
596 if (std::fabs(peak1Pos - peak2Pos) > 0.25 * (peak1TwoSigma + peak2TwoSigma)) {
597 g_log.debug() << "*Rejecting due to displacement between Peak at mon1: Ei=" +
598 boost::lexical_cast<std::string>(peak1Pos) +
599 " with Height:" + boost::lexical_cast<std::string>(peak1Height) +
600 " and 2*Sigma: " + boost::lexical_cast<std::string>(peak1TwoSigma) +
601 "\n and Peak at mon2: Ei= " + boost::lexical_cast<std::string>(peak2Pos) +
602 "and height: " + boost::lexical_cast<std::string>(peak1Height)
603 << '\n';
604
605 return false;
606 }
607 }
608
609 position = peak1Pos;
610 twoSigma = peak1TwoSigma;
611 height = peak1Height;
612
613 return true;
614}
615namespace { // for lambda extracted from calcDerivativeAndCountZeros
621bool signChanged(double val, int &prevSign) {
622 int curSign = (val >= 0 ? 1 : -1);
623 bool changed = curSign != prevSign;
624 prevSign = curSign;
625 return changed;
626}
627} // namespace
628
641size_t GetAllEi::calcDerivativeAndCountZeros(const std::vector<double> &bins, const std::vector<double> &signal,
642 std::vector<double> &deriv, std::vector<double> &zeros) {
643 size_t nPoints = signal.size();
644 deriv.resize(nPoints);
645 zeros.resize(0);
646
647 std::list<double> funVal;
648 double bin0 = bins[1] - bins[0];
649 double f0 = signal[0] / bin0;
650 double bin1 = bins[2] - bins[1];
651 double f1 = signal[1] / bin1;
652
653 size_t nZeros(0);
654
655 funVal.push_front(f1);
656 deriv[0] = 2 * (f1 - f0) / (bin0 + bin1);
657 int prevSign = (deriv[0] >= 0 ? 1 : -1);
658
659 for (size_t i = 1; i < nPoints - 1; i++) {
660 bin1 = (bins[i + 2] - bins[i + 1]);
661 f1 = signal[i + 1] / bin1;
662 deriv[i] = (f1 - f0) / (bins[i + 2] - bins[i]);
663 f0 = funVal.back();
664 funVal.pop_back();
665 funVal.push_front(f1);
666
667 if (signChanged(deriv[i], prevSign)) {
668 nZeros++;
669 zeros.emplace_back(0.5 * (bins[i - 1] + bins[i]));
670 }
671 }
672 deriv[nPoints - 1] = 2 * (f1 - f0) / (bin1 + bin0);
673 if (signChanged(deriv[nPoints - 1], prevSign)) {
674 zeros.emplace_back(bins[nPoints - 1]);
675 nZeros++;
676 }
677
678 return nZeros;
679}
680namespace { // for lambda extracted from findBinRanges
681// get bin range corresponding to the energy range
682void getBinRange(const HistogramData::HistogramX &eBins, double eMin, double eMax, size_t &index_min,
683 size_t &index_max) {
684
685 const auto &bins = eBins;
686 const size_t nBins = bins.size();
687 if (eMin <= bins[0]) {
688 index_min = 0;
689 } else {
690 index_min = std::size_t(Kernel::VectorHelper::getBinIndex(bins, eMin));
691 }
692
693 if (eMax >= eBins[nBins - 1]) {
694 index_max = nBins - 1;
695 } else {
696 index_max = std::size_t(Kernel::VectorHelper::getBinIndex(bins, eMax)) + 1;
697 if (index_max >= nBins)
698 index_max = nBins - 1; // last bin range anyway. Should not happen
699 }
700}
701
702// refine bin range. May need better procedure for this.
703bool refineEGuess(const HistogramX &eBins, const HistogramY &signal, double &eGuess, size_t index_min,
704 size_t index_max) {
705
706 size_t ind_Emax = index_min;
707 double SMax(0);
708 for (size_t i = index_min; i < index_max; i++) {
709 double dX = eBins[i + 1] - eBins[i];
710 double sig = signal[i] / dX;
711 if (sig > SMax) {
712 SMax = sig;
713 ind_Emax = i;
714 }
715 }
716 if (ind_Emax == index_min || ind_Emax == index_max) {
717 return false;
718 }
719 eGuess = 0.5 * (eBins[ind_Emax] + eBins[ind_Emax + 1]);
720 return true;
721}
722
723struct peakKeeper2 {
724 double left_rng;
725 double right_rng;
726 peakKeeper2() : left_rng(.0), right_rng(.0) {};
727 peakKeeper2(double left, double right) : left_rng(left), right_rng(right) {}
728};
729} // namespace
730
743void GetAllEi::findBinRanges(const HistogramX &eBins, const HistogramY &signal, const std::vector<double> &guess_energy,
744 double eResolution, std::vector<size_t> &irangeMin, std::vector<size_t> &irangeMax,
745 std::vector<bool> &guessValid) {
746
747 // size_t nBins = eBins.size();
748 guessValid.resize(guess_energy.size());
749
750 // Do the job
751 size_t ind_min, ind_max;
752 irangeMin.resize(0);
753 irangeMax.resize(0);
754
755 // identify guess bin ranges
756 std::vector<peakKeeper2> guess_peak(guess_energy.size());
757 for (size_t nGuess = 0; nGuess < guess_energy.size(); nGuess++) {
758 double eGuess = guess_energy[nGuess];
759 getBinRange(eBins, eGuess * (1 - 4 * eResolution), eGuess * (1 + 4 * eResolution), ind_min, ind_max);
760 guess_peak[nGuess] = peakKeeper2(eBins[ind_min], eBins[ind_max]);
761 }
762 // verify that the ranges not intercept and refine interceptions
763 for (size_t i = 1; i < guess_energy.size(); i++) {
764 if (guess_peak[i - 1].right_rng > guess_peak[i].left_rng) {
765 double mid_pnt = 0.5 * (guess_peak[i - 1].right_rng + guess_peak[i].left_rng);
766 guess_peak[i - 1].right_rng = mid_pnt;
767 guess_peak[i].left_rng = mid_pnt;
768 }
769 }
770 // identify final bin ranges
771 for (size_t nGuess = 0; nGuess < guess_energy.size(); nGuess++) {
772
773 double eGuess = guess_energy[nGuess];
774 getBinRange(eBins, guess_peak[nGuess].left_rng, guess_peak[nGuess].right_rng, ind_min, ind_max);
775
776 if (refineEGuess(eBins, signal, eGuess, ind_min, ind_max)) {
777 getBinRange(eBins, std::max(guess_peak[nGuess].left_rng, eGuess * (1 - 3 * eResolution)),
778 std::max(guess_peak[nGuess].right_rng, eGuess * (1 + 3 * eResolution)), ind_min, ind_max);
779 irangeMin.emplace_back(ind_min);
780 irangeMax.emplace_back(ind_max);
781 guessValid[nGuess] = true;
782 } else {
783 guessValid[nGuess] = false;
784 g_log.debug() << "*Incorrect guess energy: " << boost::lexical_cast<std::string>(eGuess)
785 << " no energy peak found in 4*Sigma range\n";
786 }
787 }
788 // if array decreasing rather then increasing, indexes behave differently.
789 // Will it still work?
790 if (!irangeMax.empty()) {
791 if (irangeMax[0] < irangeMin[0]) {
792 irangeMax.swap(irangeMin);
793 }
794 }
795}
796
805
806 // at this stage all properties are validated so its safe to access them
807 // without
808 // additional checks.
809 specnum_t specNum1 = getProperty("Monitor1SpecID");
810 wsIndex0 = inputWS->getIndexFromSpectrumNumber(specNum1);
811 specnum_t specNum2 = getProperty("Monitor2SpecID");
812 size_t wsIndex1 = inputWS->getIndexFromSpectrumNumber(specNum2);
813
814 // assuming equally binned ws.
815 std::shared_ptr<API::HistoWorkspace> working_ws = DataObjects::create<API::HistoWorkspace>(
816 *inputWS, Indexing::extract(inputWS->indexInfo(), std::vector<size_t>{wsIndex0, wsIndex1}),
817 inputWS->histogram(wsIndex0));
818
819 // signal 1
820 working_ws->setSharedY(0, inputWS->sharedY(wsIndex0));
821 // signal 2
822 working_ws->setSharedY(1, inputWS->sharedY(wsIndex1));
823 // error 1
824 working_ws->setSharedE(0, inputWS->sharedE(wsIndex0));
825 // error 2
826 working_ws->setSharedE(1, inputWS->sharedE(wsIndex1));
827
828 if (inputWS->getAxis(0)->unit()->caption() != "Energy") {
829 auto conv = createChildAlgorithm("ConvertUnits");
830 conv->initialize();
831 conv->setProperty("InputWorkspace", working_ws);
832 conv->setProperty("OutputWorkspace", working_ws);
833 conv->setPropertyValue("Target", "Energy");
834 conv->setPropertyValue("EMode", "Elastic");
835 // conv->setProperty("AlignBins",true); --> throws due to bug in
836 // ConvertUnits
837 conv->execute();
838 }
839
840 return working_ws;
841}
852void GetAllEi::findGuessOpeningTimes(const std::pair<double, double> &TOF_range, double ChopDelay, double Period,
853 std::vector<double> &guess_opening_times) {
854
855 if (ChopDelay >= TOF_range.second) {
856 std::string chop = boost::str(boost::format("%.2g") % ChopDelay);
857 std::string t_min = boost::str(boost::format("%.2g") % TOF_range.first);
858 std::string t_max = boost::str(boost::format("%.2g") % TOF_range.second);
859 throw std::runtime_error("Logical error: Chopper opening time: " + chop + " is outside of time interval: " + t_min +
860 ":" + t_max + " of the signal, measured on monitors.");
861 }
862
863 // number of times chopper with specified rotation period opens.
864 size_t n_openings = static_cast<size_t>((TOF_range.second - ChopDelay) / Period) + 1;
865 // number of periods falling outside of the time period, measuring on monitor.
866 size_t n_start(0);
867 if (ChopDelay < TOF_range.first) {
868 n_start = static_cast<size_t>((TOF_range.first - ChopDelay) / Period) + 1;
869 n_openings -= n_start;
870 }
871
872 guess_opening_times.resize(n_openings);
873 for (size_t i = n_start; i < n_openings + n_start; i++) {
874 guess_opening_times[i - n_start] = ChopDelay + static_cast<double>(i) * Period;
875 }
876}
885 const std::string &propertyName) {
886
887 std::string LogName = this->getProperty(propertyName);
888 if (boost::iequals(LogName, "Defined in IDF")) {
889 auto AllNames = m_chopper->getStringParameter(propertyName);
890 if (AllNames.size() != 1)
891 return nullptr;
892 LogName = AllNames[0];
893 }
894 auto pIProperty = (inputWS->run().getProperty(LogName));
895
896 return pIProperty;
897}
898
906double GetAllEi::getAvrgLogValue(const API::MatrixWorkspace_sptr &inputWS, const std::string &propertyName,
907 const Kernel::TimeROI &timeroi) {
908
909 auto pIProperty = getPLogForProperty(inputWS, propertyName);
910
911 // this will always provide a defined pointer as this has been verified in
912 // validator.
913 const auto *pTimeSeries = dynamic_cast<Kernel::TimeSeriesProperty<double> *>(pIProperty);
914
915 if (!pTimeSeries) {
916 throw std::runtime_error("Could not retrieve a time series property for the property name " + propertyName);
917 }
918
919 double value;
920 if (timeroi.useAll()) {
921 const auto timeStart = inputWS->run().startTime();
922 const auto timeStop = inputWS->run().endTime();
923 if (timeStart < timeStop) {
924 Kernel::TimeROI localROI(timeStart, timeStop);
925 value = pTimeSeries->getStatistics(&localROI).mean;
926 } else {
927 // all values in pTimeSeries will be used
928 value = pTimeSeries->getStatistics().mean;
929 }
930 } else {
931 value = pTimeSeries->getStatistics(&timeroi).mean;
932 }
933 // statistics returns nan as mean of empty vector
934 if (std::isnan(value)) {
935 throw std::runtime_error("Can not find average value for log defined by property" + propertyName +
936 " As no valid log values are found.");
937 }
938
939 return value;
940}
941namespace { // former lambda function for findChopSpeedAndDelay
942
957bool SelectInterval(const Types::Core::DateAndTime &t_beg, const Types::Core::DateAndTime &t_end, double value,
958 bool &inSelection, Types::Core::DateAndTime &startTime, Types::Core::DateAndTime &endTime) {
959
960 if (value > 0) {
961 if (!inSelection) {
962 startTime = t_beg;
963 }
964 inSelection = true;
965 } else {
966 if (inSelection) {
967 inSelection = false;
968 if (endTime > startTime)
969 return true;
970 }
971 }
972 endTime = t_end;
973 return false;
974}
975} // namespace
981void GetAllEi::findChopSpeedAndDelay(const API::MatrixWorkspace_sptr &inputWS, double &chop_speed, double &chop_delay) {
982
983 // TODO: Make it dependent on inputWS time range
984
985 Kernel::TimeROI timeroi;
986 if (m_pFilterLog) {
987 std::unique_ptr<Kernel::TimeSeriesProperty<double>> pDerivative;
988
989 // Define selecting function
990 bool inSelection(false);
991 // time interval to select (start-end)
992 Types::Core::DateAndTime startTime, endTime;
993 //
994 // Analyze filtering log
995 auto dateAndTimes = m_pFilterLog->valueAsCorrectMap();
996 auto it = dateAndTimes.begin();
997 auto next = it;
998 next++;
999 std::map<Types::Core::DateAndTime, double> derivMap;
1000 auto itder = it;
1002 pDerivative = m_pFilterLog->getDerivative();
1003 derivMap = pDerivative->valueAsCorrectMap();
1004 itder = derivMap.begin();
1005 }
1006
1007 // initialize selection log
1008 if (dateAndTimes.size() <= 1) {
1009 SelectInterval(it->first, it->first, itder->second, inSelection, startTime, endTime);
1010 if (inSelection) {
1011 startTime = inputWS->run().startTime();
1012 endTime = inputWS->run().endTime();
1013 timeroi.addROI(startTime, endTime);
1014 } else {
1015 throw std::runtime_error("filtered all data points. Nothing to do");
1016 }
1017 } else {
1018 SelectInterval(it->first, next->first, itder->second, inSelection, startTime, endTime);
1019 }
1020
1021 // if its filtered using log, both iterator walk through the same values
1022 // if use derivative, derivative's values are used for filtering
1023 // and derivative assumed in a center of an interval
1024 for (; next != dateAndTimes.end(); ++next, ++itder) {
1025 if (SelectInterval(it->first, next->first, itder->second, inSelection, startTime, endTime)) {
1026 timeroi.addROI(startTime, endTime);
1027 }
1028 it = next;
1029 }
1030 // final interval
1031 if (inSelection && (endTime > startTime)) {
1032 timeroi.addROI(startTime, endTime);
1033 }
1034 } // End of USE filter log.
1035
1036 chop_speed = this->getAvrgLogValue(inputWS, "ChopperSpeedLog", timeroi);
1037 chop_speed = std::fabs(chop_speed);
1038 if (chop_speed < 1.e-7) {
1039 throw std::runtime_error("Chopper speed can not be zero ");
1040 }
1041 chop_delay = std::fabs(this->getAvrgLogValue(inputWS, "ChopperDelayLog", timeroi));
1042
1043 // process chopper delay in the units of degree (phase)
1044 const auto *pProperty = getPLogForProperty(inputWS, "ChopperDelayLog");
1045 if (!pProperty)
1046 throw std::runtime_error("ChopperDelayLog has been removed from workspace "
1047 "during the algorithm execution");
1048 std::string units = pProperty->units();
1049 // its chopper phase provided
1050 if (units == "deg" || units.c_str()[0] == -80) { //<- userd in ISIS ASCII representation of o(deg)
1051 chop_delay *= 1.e+6 / (360. * chop_speed); // convert in uSec
1052 }
1053 chop_delay += m_phase / chop_speed;
1054}
1055
1056namespace { // namespace for lambda functions, used in validators
1057
1058/* former Lambda to validate if appropriate log is present in workspace
1059and if it's present, it is a time-series property
1060* @param prop_name -- the name of the log to check
1061* @param err_presence -- core error message to return if no log found
1062* @param err_type -- core error message to return if
1063* log is of incorrect type
1064* @param fail -- fail or warn if appropriate log is not available.
1065*
1066* @param result -- map to add the result of check for errors
1067* if no error found the map is not modified and remains
1068* empty.
1069
1070
1071* @return -- false if all checks are fine, or true if check is
1072* failed
1073*/
1074bool check_time_series_property(const GetAllEi *algo, const API::MatrixWorkspace_sptr &inputWS,
1075 const std::shared_ptr<const Geometry::IComponent> &chopper,
1076 const std::string &prop_name, const std::string &err_presence,
1077 const std::string &err_type, bool fail, std::map<std::string, std::string> &result) {
1078
1079 std::string LogName = algo->getProperty(prop_name);
1080 if (boost::iequals(LogName, "Defined in IDF")) {
1081 try {
1082 auto theLogs = chopper->getStringParameter(prop_name);
1083 if (theLogs.empty()) {
1084 if (fail)
1085 result[prop_name] = "Can not retrieve parameter " + prop_name + " from the instrument definition file.";
1086 return true;
1087 }
1088 LogName = theLogs[0];
1089 } catch (...) {
1090 result[prop_name] = "Can not retrieve parameter " + prop_name + " from the instrument definition file.";
1091 return true;
1092 }
1093 }
1094 try {
1095 Kernel::Property *pProp = inputWS->run().getProperty(LogName);
1096 const auto *pTSProp = dynamic_cast<Kernel::TimeSeriesProperty<double> *>(pProp);
1097 if (!pTSProp) {
1098 if (fail)
1099 result[prop_name] = "Workspace contains " + err_type + LogName + " But its type is not a timeSeries property";
1100 return true;
1101 }
1102 } catch (std::runtime_error &) {
1103 if (fail)
1104 result[prop_name] = "Workspace has to contain " + err_presence + LogName;
1105 return true;
1106 }
1107 return false;
1108}
1109} // namespace
1110
1115std::map<std::string, std::string> GetAllEi::validateInputs() {
1116
1117 // Do Validation
1118 std::map<std::string, std::string> result;
1119
1120 API::MatrixWorkspace_sptr inputWS = getProperty("Workspace");
1121 if (!inputWS) {
1122 result["Workspace"] = "Input workspace can not be identified";
1123 return result;
1124 }
1125 if (!inputWS->isHistogramData()) {
1126 result["Workspace"] = "Only histogram workspaces are currently supported. "
1127 "Rebin input workspace first.";
1128 }
1129
1130 specnum_t specNum1 = getProperty("Monitor1SpecID");
1131 try {
1132 inputWS->getIndexFromSpectrumNumber(specNum1);
1133 } catch (std::runtime_error &) {
1134 result["Monitor1SpecID"] = "Input workspace does not contain spectra with ID: " + std::to_string(specNum1);
1135 }
1136 specnum_t specNum2 = getProperty("Monitor2SpecID");
1137 try {
1138 inputWS->getIndexFromSpectrumNumber(specNum2);
1139 } catch (std::runtime_error &) {
1140 result["Monitor2SpecID"] = "Input workspace does not contain spectra with ID: " + std::to_string(specNum2);
1141 }
1142 // check chopper and initiate it if present (for debugging)
1143 m_chopper = inputWS->getInstrument()->getComponentByName("chopper-position");
1144 if (!m_chopper) {
1145 result["Workspace_chopper"] = " For this algorithm to work workspace has"
1146 " to contain well defined 'chopper-position' component";
1147 return result;
1148 }
1149
1150 check_time_series_property(this, inputWS, m_chopper, "ChopperSpeedLog",
1151 "chopper speed log with name: ", "chopper speed log ", true, result);
1152 check_time_series_property(this, inputWS, m_chopper, "ChopperDelayLog",
1153 "property related to chopper delay log with name: ", "chopper delay log ", true, result);
1154 bool failed = check_time_series_property(this, inputWS, m_chopper, "FilterBaseLog",
1155 "filter base log named: ", "filter base log: ", false, result);
1156 if (failed) {
1157 g_log.warning() << " Can not find a log to identify good DAE operations.\n"
1158 " Assuming that good operations start from experiment time=0";
1159 } else {
1160 this->setFilterLog(inputWS);
1161 }
1162 return result;
1163}
1164
1165} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
double value
The value of the point.
Definition FitMW.cpp:51
double energy
Definition GetAllEi.cpp:157
double height
Definition GetAllEi.cpp:155
double left_rng
Definition GetAllEi.cpp:724
double position
Definition GetAllEi.cpp:154
double right_rng
Definition GetAllEi.cpp:725
std::map< DeltaEMode::Type, std::string > index
double left
double right
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:76
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.
Kernel::Logger & g_log
Definition Algorithm.h:426
A property class for workspaces.
Estimate all incident energies, used by chopper instrument.
Definition GetAllEi.h:26
Kernel::TimeSeriesProperty< double > * m_pFilterLog
Definition GetAllEi.h:100
void findGuessOpeningTimes(const std::pair< double, double > &TOF_range, double ChopDelay, double Period, std::vector< double > &guess_opening_times)
function calculates list of provisional chopper opening times.
Definition GetAllEi.cpp:852
bool findMonitorPeak(const API::MatrixWorkspace_sptr &inputWS, double Ei, const std::vector< size_t > &monsRangeMin, const std::vector< size_t > &monsRangeMax, double &position, double &height, double &twoSigma)
Get energy of monitor peak if one is present.
Definition GetAllEi.cpp:567
double getAvrgLogValue(const API::MatrixWorkspace_sptr &inputWS, const std::string &propertyName, const Kernel::TimeROI &timeroi)
Return average time series log value for the appropriately filtered log.
Definition GetAllEi.cpp:906
Kernel::Property * getPLogForProperty(const API::MatrixWorkspace_sptr &inputWS, const std::string &propertyName)
Finds pointer to log value for the property with the name provided.
Definition GetAllEi.cpp:884
std::shared_ptr< const Geometry::IComponent > m_chopper
Definition GetAllEi.h:98
API::MatrixWorkspace_sptr buildWorkspaceToFit(const API::MatrixWorkspace_sptr &inputWS, size_t &wsIndex0)
Build 2-spectra workspace in units of energy, used as source to identify actual monitors spectra.
Definition GetAllEi.cpp:804
void exec() override
Executes the algorithm – found all existing monitor peaks.
Definition GetAllEi.cpp:169
void findChopSpeedAndDelay(const API::MatrixWorkspace_sptr &inputWS, double &chop_speed, double &chop_delay)
process logs and retrieve chopper speed and chopper delay
Definition GetAllEi.cpp:981
std::map< std::string, std::string > validateInputs() override
Cross-check properties with each other.
bool peakGuess(const API::MatrixWorkspace_sptr &inputWS, size_t index, double Ei, const std::vector< size_t > &monsRangeMin, const std::vector< size_t > &monsRangeMax, double &peakPos, double &peakHeight, double &peakTwoSigma)
Former lambda to identify guess values for a peak at given index and set up these parameters as input...
Definition GetAllEi.cpp:437
void findBinRanges(const HistogramData::HistogramX &eBins, const HistogramData::HistogramY &signal, const std::vector< double > &guess_energy, double eResolution, std::vector< size_t > &irangeMin, std::vector< size_t > &irangeMax, std::vector< bool > &guessValid)
Find indexes of each expected peak intervals.
Definition GetAllEi.cpp:743
size_t calcDerivativeAndCountZeros(const std::vector< double > &bins, const std::vector< double > &signal, std::vector< double > &deriv, std::vector< double > &zeros)
Bare-bone function to calculate numerical derivative, and estimate number of zeros this derivative ha...
Definition GetAllEi.cpp:641
bool m_FilterWithDerivative
if true, take derivate of the filter log to identify interval when instrument is running.
Definition GetAllEi.h:86
void printDebugModeInfo(const std::vector< double > &guess_opening, const std::pair< double, double > &TOF_range, std::shared_ptr< Kernel::Unit > &destUnit)
Auxiliary method to print guess chopper energies in debug mode.
Definition GetAllEi.cpp:374
void init() override
Initialization method.
Definition GetAllEi.cpp:46
void setFilterLog(const API::MatrixWorkspace_sptr &inputWS)
The internal procedure to set filter log from properties, defining it.
Definition GetAllEi.cpp:401
double m_min_Eresolution
maximal relative peak width to consider acceptable.
Definition GetAllEi.h:90
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings const > settings)
Add a PropertySettings instance to the chain of settings for a given property.
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
Base class for properties.
Definition Property.h:95
TimeROI : Object that holds information about when the time measurement was active.
Definition TimeROI.h:18
void addROI(const std::string &startTime, const std::string &stopTime)
Definition TimeROI.cpp:76
bool useAll() const
TimeROI selects all time to be used.
Definition TimeROI.cpp:693
A specialised Property class for holding a series of time-value pairs.
std::map< Types::Core::DateAndTime, TYPE > valueAsCorrectMap() const
Return the time series as a correct C++ map<DateAndTime, TYPE>.
std::unique_ptr< TimeSeriesProperty< double > > getDerivative() const
Return time series property, containing time derivative of current property.
@ Error
Background thread reported an exception.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
MANTID_KERNEL_DLL void smoothInRange(std::span< double const > input, std::vector< double > &output, double avrgInterval, std::span< double const > binBndrs={}, size_t startIndex=0, size_t endIndex=0, std::vector< double > *const outBins=nullptr)
Basic running average of input vector within specified range, considering variable bin-boundaries if ...
MANTID_KERNEL_DLL int getBinIndex(std::span< double const > bins, const double value)
Return the index into a vector of bin boundaries for a particular X value.
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition EmptyValues.h:24
int32_t specnum_t
Typedef for a spectrum Number.
Definition IDTypes.h:14
std::string to_string(const wide_integer< Bits, Signed > &n)
constexpr bool operator<(const wide_integer< Bits, Signed > &lhs, const wide_integer< Bits2, Signed2 > &rhs)
@ Input
An input workspace.
Definition Property.h:54
@ Output
An output workspace.
Definition Property.h:55