Mantid
Loading...
Searching...
No Matches
DeadTimeCorrection.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"
11#include "MantidAPI/Progress.h"
14#include "MantidKernel/Unit.h"
15
16#include <limits>
17
18namespace Mantid::Algorithms {
19
20using API::FileProperty;
22using API::Progress;
23using API::WorkspaceProperty;
24using Kernel::BoundedValidator;
25using Kernel::Direction;
26using Kernel::PropertyWithValue;
27
28// Register the algorithm into the AlgorithmFactory
29DECLARE_ALGORITHM(DeadTimeCorrection)
30
31//----------------------------------------------------------------------------------------------
32
33
34const std::string DeadTimeCorrection::name() const { return "DeadTimeCorrection"; }
35
37int DeadTimeCorrection::version() const { return 1; }
38
40const std::string DeadTimeCorrection::category() const { return "CorrectionFunctions"; }
41
43const std::string DeadTimeCorrection::summary() const { return "Performs a dead time correction based on count rate."; }
44
45//----------------------------------------------------------------------------------------------
49 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input), "An input workspace.");
50
51 declareProperty(std::make_unique<PropertyWithValue<std::string>>("GroupingPattern", "", Direction::Input),
52 "See the GroupingPattern documentation of GroupDetectors.");
53
54 auto positive = std::make_shared<BoundedValidator<double>>();
55 positive->setLower(0.);
56 declareProperty("Tau", 0., positive, "The count rate coefficient.");
57
58 declareProperty(std::make_unique<WorkspaceProperty<>>("OutputWorkspace", "", Direction::Output),
59 "An output workspace.");
60
61 declareProperty(std::make_unique<FileProperty>("MapFile", "", FileProperty::OptionalLoad,
62 std::vector<std::string>{".map", ".xml"}),
63 "A file that consists of lists of spectra numbers to group. See the "
64 "help of GroupDetectors for the file format");
65}
66
67//----------------------------------------------------------------------------------------------
71 MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
72 MatrixWorkspace_sptr outputWorkspace = getProperty("OutputWorkspace");
73 if (inputWorkspace != outputWorkspace) {
74 outputWorkspace = inputWorkspace->clone();
75 }
76 const auto map = outputWorkspace->getDetectorIDToWorkspaceIndexMap();
77 const double tau = getProperty("Tau");
78 MatrixWorkspace_sptr integrated = inputWorkspace;
79 auto xAxisUnitID = inputWorkspace->getAxis(0)->unit()->unitID();
80 if (outputWorkspace->blocksize() != 1 && xAxisUnitID != "Empty") {
81 auto integrator = createChildAlgorithm("Integration");
82 integrator->setProperty("InputWorkspace", inputWorkspace);
83 integrator->setPropertyValue("OutputWorkspace", "unused");
84 integrator->executeAsChildAlg();
85 integrated = integrator->getProperty("OutputWorkspace");
86 // after integration we end up with one bin
87 // however the bin edges might vary, which does not matter, we just need to
88 // group the counts, hence we need to do this before we can group the pixels
89 for (size_t index = 1; index < integrated->getNumberHistograms(); ++index) {
90 integrated->setSharedX(index, integrated->sharedX(0));
91 }
92 }
93 const std::string groupingPattern = getProperty("GroupingPattern");
94 MatrixWorkspace_sptr grouped = integrated;
95 if (!groupingPattern.empty()) {
96 auto grouper = createChildAlgorithm("GroupDetectors");
97 grouper->setProperty("InputWorkspace", integrated);
98 grouper->setPropertyValue("OutputWorkspace", "unused");
99 grouper->setPropertyValue("GroupingPattern", groupingPattern);
100 grouper->setPropertyValue("Behaviour", "Sum");
101 grouper->setProperty("KeepUngroupedSpectra", true);
102 grouper->executeAsChildAlg();
103 grouped = grouper->getProperty("OutputWorkspace");
104 } else {
105 const std::string filename = getProperty("MapFile");
106 if (!filename.empty()) {
107 auto grouper = createChildAlgorithm("GroupDetectors");
108 grouper->setProperty("InputWorkspace", integrated);
109 grouper->setPropertyValue("OutputWorkspace", "unused");
110 grouper->setPropertyValue("MapFile", filename);
111 grouper->setPropertyValue("Behaviour", "Sum");
112 grouper->setProperty("KeepUngroupedSpectra", true);
113 grouper->executeAsChildAlg();
114 grouped = grouper->getProperty("OutputWorkspace");
115 }
116 }
117 Progress progress(this, 0.0, 1.0, grouped->getNumberHistograms());
118 PARALLEL_FOR_IF(Kernel::threadSafe(*outputWorkspace))
119 for (int index = 0; index < static_cast<int>(grouped->getNumberHistograms()); ++index) {
121 progress.report("Performing the correction for the group at index " + std::to_string(index));
122 auto correction = grouped->y(index);
123 for (size_t bin = 0; bin < correction.size(); bin++) {
124 auto &y = correction[bin];
125 if (y >= 1.0 / tau) {
126 g_log.warning() << "Saturation count rate reached for grouped detector at index " << index << ", in bin " << bin
127 << ". Correction will be infinity. Check your tau or input "
128 "workspace, make sure it is normalised by acquisition time.\n";
129 y = std::numeric_limits<double>::infinity();
130 }
131 }
132 std::for_each(correction.begin(), correction.end(), [&tau](double &y) { y = 1.0 / (1.0 - y * tau); });
133
134 const auto detIDs = grouped->getSpectrum(index).getDetectorIDs();
135 for (const auto id : detIDs) {
136 const size_t originalIndex = map.at(id);
137 auto &spectrum = outputWorkspace->mutableY(originalIndex);
138 auto &errors = outputWorkspace->mutableE(originalIndex);
139 if (correction.size() == 1) {
140 spectrum *= correction[0];
141 errors *= correction[0];
142 } else {
143 spectrum *= correction;
144 errors *= correction.rawData();
145 }
146 }
148 }
150 setProperty("OutputWorkspace", outputWorkspace);
151}
152
153} // namespace Mantid::Algorithms
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:547
std::map< DeltaEMode::Type, std::string > index
#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.
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
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
DeadTimeCorrection : Performs dead time correction.
void exec() override
Execute the algorithm.
int version() const override
Algorithm's version for identification.
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
void init() override
Initialize the algorithm's properties.
const std::string category() const override
Algorithm's category for identification.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
The concrete, templated class for properties.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base 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.
STL namespace.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
Definition Property.h:54
@ Output
An output workspace.
Definition Property.h:55