Mantid
Loading...
Searching...
No Matches
RemovePromptPulse.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 +
12
13using std::string;
14namespace Mantid::Algorithms {
15
16// Register the algorithm into the AlgorithmFactory
17DECLARE_ALGORITHM(RemovePromptPulse)
18
19using namespace Mantid::Kernel;
20using namespace Mantid::API;
21
22//----------------------------------------------------------------------------------------------
23
24const string RemovePromptPulse::name() const { return "RemovePromptPulse"; }
25
26int RemovePromptPulse::version() const { return 1; }
27
28const string RemovePromptPulse::category() const { return "CorrectionFunctions\\BackgroundCorrections"; }
29
30//----------------------------------------------------------------------------------------------
34 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input,
35 std::make_shared<WorkspaceUnitValidator>("TOF")),
36 "An input workspace.");
37 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
38 "An output workspace.");
39
40 auto validator = std::make_shared<BoundedValidator<double>>();
41 validator->setLower(0.0);
42 declareProperty("Width", Mantid::EMPTY_DBL(), validator,
43 "The width of the time of flight (in microseconds) to remove from the data.");
44 declareProperty("Frequency", Mantid::EMPTY_DBL(), validator,
45 "The frequency of the source (in Hz) used to calculate the minimum time of flight to filter.");
47 "TMin", Mantid::EMPTY_DBL(),
48 "Minimum time of flight. "
49 "Execution will be faster if this is specified, but the value will be determined from the workspace if not.");
51 "TMax", Mantid::EMPTY_DBL(),
52 "Minimum time of flight. "
53 "Execution will be faster if this is specified, but the value will be determined from the workspace if not.");
54}
55
56//----------------------------------------------------------------------------------------------
57namespace { // anonymous namespace begin
58double getMedian(const API::Run &run, const std::string &name) {
59
60 if (!run.hasProperty(name)) {
61 return Mantid::EMPTY_DBL();
62 }
63 try {
65 } catch (const std::invalid_argument &) {
66 return Mantid::EMPTY_DBL(); // maybe one of the other names will work
67 }
68}
69} // namespace
70
71void RemovePromptPulse::getTofRange(const MatrixWorkspace_const_sptr &wksp, double &tmin, double &tmax) {
72 const auto timerStart = std::chrono::high_resolution_clock::now();
73
74 // first get the values from the properties
75 tmin = getProperty("TMin");
76 tmax = getProperty("TMax");
77
78 // only get the values that are not specified
79 const bool findTmin = isEmpty(tmin);
80 const bool findTmax = isEmpty(tmax);
81
82 if (findTmin && findTmax) {
83 if (const auto eventWksp = std::dynamic_pointer_cast<const DataObjects::EventWorkspace>(wksp)) {
84 eventWksp->getEventXMinMax(tmin, tmax);
85 } else {
86 wksp->getXMinMax(tmin, tmax);
87 }
88 } else if (findTmin) {
89 if (const auto eventWksp = std::dynamic_pointer_cast<const DataObjects::EventWorkspace>(wksp)) {
90 tmin = eventWksp->getEventXMin();
91 } else {
92 tmin = wksp->getXMin();
93 }
94 } else if (findTmax) {
95 if (const auto eventWksp = std::dynamic_pointer_cast<const DataObjects::EventWorkspace>(wksp)) {
96 tmax = eventWksp->getEventXMax();
97 } else {
98 tmax = wksp->getXMax();
99 }
100 }
101 // the fall-through case is to use the properties for both which was set at the top of the function
102
103 addTimer("getTofRange", timerStart, std::chrono::high_resolution_clock::now());
104}
105
109 // verify there is a width parameter specified
110 double width = this->getProperty("Width");
111 if (this->isEmpty(width)) {
112 throw std::runtime_error("Failed to specify \'Width\' parameter");
113 }
114
115 // need the input workspace in general
116 API::MatrixWorkspace_const_sptr inputWS = this->getProperty("InputWorkspace");
117
118 // get the frequency
119 double frequency = this->getProperty("Frequency");
120 if (this->isEmpty(frequency)) { // it wasn't specified so try divination
121 frequency = this->getFrequency(inputWS->run());
122 if (this->isEmpty(frequency)) {
123 throw std::runtime_error("Failed to determine the frequency");
124 }
125 }
126 g_log.information() << "Using frequency of " << frequency << "Hz\n";
127 double period = 1000000. / frequency; // period in microseconds
128
129 // determine the overall tof window for the data
130 double tmin;
131 double tmax;
132 getTofRange(inputWS, tmin, tmax);
133 g_log.information() << "Data tmin=" << tmin << ", tmax=" << tmax << ", period=" << period << " microseconds\n";
134
135 // calculate the times for the prompt pulse
136 std::vector<double> pulseTimes = this->calculatePulseTimes(tmin, tmax, period, width);
137 if (pulseTimes.empty()) {
138 g_log.notice() << "Not applying filter since prompt pulse is not in data "
139 "range (period = "
140 << period << ")\n";
141 setProperty("OutputWorkspace", std::const_pointer_cast<MatrixWorkspace>(inputWS));
142 return;
143 }
144 g_log.information() << "Calculated prompt pulses at ";
145 for (double pulseTime : pulseTimes)
146 g_log.information() << pulseTime << " ";
147 g_log.information() << " microseconds\n";
148
149 // loop through each prompt pulse
150 MatrixWorkspace_sptr outputWS;
151 auto algo = createChildAlgorithm("MaskBins");
152 for (const double &pulseTime : pulseTimes) {
153 const double right = pulseTime + width;
154
155 g_log.notice() << "Filtering tmin=" << pulseTime << ", tmax=" << right << " microseconds\n";
156
157 // run maskbins to do the work on the first prompt pulse
158 if (outputWS) {
159 algo->setProperty<MatrixWorkspace_sptr>("InputWorkspace", std::const_pointer_cast<MatrixWorkspace>(outputWS));
160 } else { // should only be first time
161 algo->setProperty<MatrixWorkspace_sptr>("InputWorkspace", std::const_pointer_cast<MatrixWorkspace>(inputWS));
162 outputWS = this->getProperty("OutputWorkspace");
163 }
164 // always write to correct output workspace
165 algo->setProperty<MatrixWorkspace_sptr>("OutputWorkspace", outputWS);
166 algo->setProperty<double>("XMin", pulseTime);
167 algo->setProperty<double>("XMax", right);
168 algo->executeAsChildAlg();
169
170 // copy over the output workspace
171 outputWS = algo->getProperty("OutputWorkspace");
172 }
173
174 setProperty("OutputWorkspace", outputWS);
175}
176
178 double candidate;
179
180 candidate = getMedian(run, "Frequency");
181 if (!(this->isEmpty(candidate)))
182 return candidate;
183
184 candidate = getMedian(run, "frequency");
185 if (!(this->isEmpty(candidate)))
186 return candidate;
187
188 candidate = getMedian(run, "FREQUENCY");
189 if (!(this->isEmpty(candidate)))
190 return candidate;
191
192 // give up
193 return Mantid::EMPTY_DBL();
194}
195
205std::vector<double> RemovePromptPulse::calculatePulseTimes(const double tmin, const double tmax, const double period,
206 const double width) {
207 std::vector<double> times;
208 double time = 0.;
209 // zero pulse should be taken into account
210 if (tmin > 0 && tmin < width)
211 times.emplace_back(time);
212 // find when the first prompt pulse would be
213 while (time < tmin)
214 time += period;
215
216 // calculate all times possible
217 while (time < tmax) {
218 times.emplace_back(time);
219 time += period;
220 }
221
222 return times;
223}
224} // namespace Mantid::Algorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double right
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:422
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
void addTimer(const std::string &name, const Kernel::time_point_ns &begin, const Kernel::time_point_ns &end)
bool hasProperty(const std::string &name) const
Does the property exist on the object.
double getPropertyAsSingleValue(const std::string &name, Kernel::Math::StatisticType statistic=Kernel::Math::Mean) const
Returns a property as a single double value from its name.
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:35
A property class for workspaces.
const std::string name() const override
Algorithm's name for identification.
int version() const override
Algorithm's version for identification.
const std::string category() const override
Algorithm's category for identification.
double getFrequency(const API::Run &run)
Try to get the frequency from a given name.
std::vector< double > calculatePulseTimes(const double tmin, const double tmax, const double period, const double width)
Calculate when all prompt pulses might be between the supplied times.
void getTofRange(const API::MatrixWorkspace_const_sptr &wksp, double &tmin, double &tmax)
void exec() override
Run the algorithm.
void init() override
Sets documentation strings for this algorithm.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void notice(const std::string &msg)
Logs at notice level.
Definition Logger.cpp:126
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
double getMedian(const vector< TYPE > &data)
There are enough special cases in determining the median where it useful to put it in a single functi...
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Definition EmptyValues.h:42
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54