Mantid
Loading...
Searching...
No Matches
EQSANSCorrectFrame.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 +
15
16#include <functional>
17#include <string>
18#include <vector>
19
20namespace Mantid::Algorithms {
21
22// Register the algorithm into the AlgorithmFactory
23DECLARE_ALGORITHM(EQSANSCorrectFrame)
24
25using namespace Kernel;
26using namespace API;
27using namespace DataObjects;
28using namespace Geometry;
29using Types::Event::TofEvent;
30
32
34 declareProperty(std::make_unique<WorkspaceProperty<EventWorkspace>>("InputWorkspace", "", Direction::Input,
35 std::make_shared<WorkspaceUnitValidator>("TOF")),
36 "Workspace to apply the TOF correction to");
37 declareProperty("PulsePeriod", 1.0E6 / 60.0, "Period of the neutron pulse, in micro-seconds", Direction::Input);
38 declareProperty("MinTOF", EMPTY_DBL(),
39 "Time of flight of fastest neutrons from the lead pulse, in "
40 "micro-seconds",
42 declareProperty("FrameWidth", 1.0E6 / 60.0, "Period of the chopper system, in micro-seconds", Direction::Input);
43 declareProperty("FrameSkipping", false, "If True, the data was taken in frame skipping mode", Direction::Input);
44 declareProperty("PathToPixel", true,
45 "If True, use path from moderator to individual pixel instead"
46 "of to center of the detector panel",
48 declareProperty("DetectorName", "detector1", "Name of the double panel");
49}
50
52 EventWorkspace_sptr inputWS = getProperty("InputWorkspace");
53 const size_t numHists = inputWS->getNumberHistograms();
54 Progress progress(this, 0.0, 1.0, numHists);
55
56 const double pulsePeriod = getProperty("PulsePeriod");
57 const double minTOF = getProperty("MinTOF");
58 const double frameWidth = getProperty("FrameWidth");
59 const bool isFrameSkipping = getProperty("FrameSkipping");
60 const bool pathToPixel = getProperty("PathToPixel");
61 const std::string detectorName = getProperty("DetectorName");
62
63 const auto &spectrumInfo = inputWS->spectrumInfo();
64 const auto msd = spectrumInfo.l1(); // moderator-sample-distance
65 auto ins = inputWS->getInstrument();
66 auto mdd = msd + ins->getComponentByName(detectorName)->getDistance(*(ins->getSample()));
67
68 // Creates a function that correct TOF values
69 struct correctTofFactory {
70
71 explicit correctTofFactory(double pulsePeriod, double minTOF, double frameWidth, bool isFrameSkipping)
72 : m_pulsePeriod(pulsePeriod), m_minTOF(minTOF), m_frameWidth(frameWidth), m_isFrameSkipping(isFrameSkipping) {
73 // Find how many frame widths elapsed from the time the neutrons of the
74 // lead pulse were emitted and the time the neutrons arrived to the
75 // detector bank. This time must be added to the stored TOF values
76 const double nf = std::floor(minTOF / frameWidth);
77 m_framesOffsetTime = frameWidth * nf;
78 }
79
80 double operator()(const double tof, const double pathToPixelFactor = 1.0) const {
81 // shift times to the correct frame
82 double newTOF = tof + m_framesOffsetTime;
83 // TOF values smaller than that of the fastest neutrons have been
84 // 'folded' by the data acquisition system. They must be shifted
85 double scaledMinTOF = m_minTOF * pathToPixelFactor;
86 if (newTOF < scaledMinTOF)
87 newTOF += m_frameWidth;
88 // Events from the skipped pulse are delayed by one pulse period
89 if (m_isFrameSkipping && newTOF > scaledMinTOF + m_pulsePeriod)
90 newTOF += m_pulsePeriod;
91 return newTOF;
92 }
93
94 double m_pulsePeriod;
95 double m_minTOF;
96 double m_frameWidth;
97 double m_framesOffsetTime;
98 bool m_isFrameSkipping;
99 };
100
101 auto correctTof = correctTofFactory(pulsePeriod, minTOF, frameWidth, isFrameSkipping);
102
103 // Loop through the spectra and apply correction
105 for (int64_t ispec = 0; ispec < int64_t(numHists); ++ispec) {
107 if (!spectrumInfo.hasDetectors(ispec)) {
108 g_log.warning() << "Workspace index " << ispec << " has no detector assigned to it - discarding\n";
109 continue;
110 }
111 EventList &evlist = inputWS->getSpectrum(ispec);
112 if (evlist.getNumberEvents() == 0)
113 continue; // no events recorded in this spectrum
114
115 // Determine the factor by which to enlarge the minimum time-of-flight
116 // if considering the path to the pixel instead of to the detector center
117 double pathToPixelFactor(1.0); // factor for path to detector center
118 if (pathToPixel) {
119 pathToPixelFactor = (msd + spectrumInfo.l2(ispec)) / mdd;
120 }
121 auto tofCorrector = std::bind(correctTof, std::placeholders::_1, pathToPixelFactor);
122
123 evlist.convertTof(tofCorrector);
124 progress.report("Correct TOF frame");
126 }
128 // Set bin boundaries to absolute minimum and maximum
129 inputWS->resetAllXToSingleBin();
130}
131
132} // namespace Mantid::Algorithms
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
#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...
Definition: MultiThreaded.h:94
#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.
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:85
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
Definition: Algorithm.cpp:231
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A property class for workspaces.
void exec() override
Execution code.
void init() override
Initialisation code.
A class for holding :
Definition: EventList.h:56
std::size_t getNumberEvents() const override
Return the number of events in the list.
Definition: EventList.cpp:1143
void convertTof(std::function< double(double)> func, const int sorting=0) override
Definition: EventList.cpp:2390
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace 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.
Definition: MultiThreaded.h:22
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition: EmptyValues.h:43
@ Input
An input workspace.
Definition: Property.h:53