forked from mantidproject/mantid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCreateEPP.cpp
157 lines (140 loc) · 6.18 KB
/
CreateEPP.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "MantidAlgorithms/CreateEPP.h"
#include "MantidAPI/InstrumentValidator.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/SpectrumInfo.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidAPI/WorkspaceUnitValidator.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/CompositeValidator.h"
#include "MantidKernel/UnitConversion.h"
namespace Mantid {
namespace Algorithms {
using Mantid::Kernel::Direction;
using Mantid::API::WorkspaceProperty;
namespace {
/** A private namespace holding the property names.
*/
namespace PropertyNames {
const static std::string INPUT_WORKSPACE("InputWorkspace");
const static std::string OUTPUT_WORKSPACE("OutputWorkspace");
const static std::string SIGMA("Sigma");
} // namespace PropertyNames
/** A private namespace holding the column names of the EPP table.
*/
namespace ColumnNames {
const static std::string WS_INDEX("WorkspaceIndex");
const static std::string PEAK_CENTRE("PeakCentre");
const static std::string PEAK_CENTRE_ERR("PeakCentreError");
const static std::string SIGMA("Sigma");
const static std::string SIGMA_ERR("SigmaError");
const static std::string HEIGHT("Height");
const static std::string HEIGHT_ERR("HeightError");
const static std::string CHI_SQUARED("chiSq");
const static std::string STATUS("FitStatus");
}
/** Add standard EPP table columns to the input workspace.
*
* @param ws The TableWorkspace to add the columns to.
*/
void addEPPColumns(API::ITableWorkspace_sptr ws) {
ws->addColumn("int", ColumnNames::WS_INDEX);
ws->addColumn("double", ColumnNames::PEAK_CENTRE);
ws->addColumn("double", ColumnNames::PEAK_CENTRE_ERR);
ws->addColumn("double", ColumnNames::SIGMA);
ws->addColumn("double", ColumnNames::SIGMA_ERR);
ws->addColumn("double", ColumnNames::HEIGHT);
ws->addColumn("double", ColumnNames::HEIGHT_ERR);
ws->addColumn("double", ColumnNames::CHI_SQUARED);
ws->addColumn("str", ColumnNames::STATUS);
}
} // anonymous namespace
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(CreateEPP)
//----------------------------------------------------------------------------------------------
/// Algorithms name for identification. @see Algorithm::name
const std::string CreateEPP::name() const { return "CreateEPP"; }
/// Algorithm's version for identification. @see Algorithm::version
int CreateEPP::version() const { return 1; }
/// Algorithm's category for identification. @see Algorithm::category
const std::string CreateEPP::category() const { return "Utility"; }
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string CreateEPP::summary() const {
return "Creates a nominal EPP table compatible with what is returned by the "
"FindEPP algorithm.";
}
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void CreateEPP::init() {
auto inputWSValidator = boost::make_shared<Kernel::CompositeValidator>();
inputWSValidator->add(boost::make_shared<API::InstrumentValidator>());
inputWSValidator->add(boost::make_shared<API::WorkspaceUnitValidator>("TOF"));
declareProperty(Kernel::make_unique<WorkspaceProperty<API::MatrixWorkspace>>(
"InputWorkspace", "", Direction::Input, inputWSValidator),
"An input workspace.");
declareProperty(Kernel::make_unique<WorkspaceProperty<API::ITableWorkspace>>(
"OutputWorkspace", "", Direction::Output),
"The calculated output EPP table.");
auto mustBePositive = boost::make_shared<Kernel::BoundedValidator<double>>();
mustBePositive->setLower(0);
declareProperty(PropertyNames::SIGMA, 0.0, mustBePositive,
"The value to fill the Sigma column with.");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void CreateEPP::exec() {
API::MatrixWorkspace_sptr inputWS =
getProperty(PropertyNames::INPUT_WORKSPACE);
const auto &spectrumInfo = inputWS->spectrumInfo();
API::ITableWorkspace_sptr outputWS =
API::WorkspaceFactory::Instance().createTable("TableWorkspace");
addEPPColumns(outputWS);
const double sigma = getProperty(PropertyNames::SIGMA);
const size_t spectraCount = spectrumInfo.size();
outputWS->setRowCount(spectraCount);
const auto l1 = spectrumInfo.l1();
const double EFixed = inputWS->run().getPropertyAsSingleValue("Ei");
for (size_t i = 0; i < spectraCount; ++i) {
const auto l2 = spectrumInfo.l2(i);
const auto elasticTOF = Kernel::UnitConversion::run(
"Energy", "TOF", EFixed, l1, l2, 0, Kernel::DeltaEMode::Direct, EFixed);
outputWS->getRef<int>(ColumnNames::WS_INDEX, i) = static_cast<int>(i);
outputWS->getRef<double>(ColumnNames::PEAK_CENTRE, i) = elasticTOF;
outputWS->getRef<double>(ColumnNames::PEAK_CENTRE_ERR, i) = 0;
outputWS->getRef<double>(ColumnNames::SIGMA, i) = sigma;
outputWS->getRef<double>(ColumnNames::SIGMA_ERR, i) = 0;
double height = 0;
try {
const auto elasticIndex = inputWS->binIndexOf(elasticTOF, i);
height = inputWS->y(i)[elasticIndex];
} catch (std::out_of_range &) {
std::ostringstream sout;
sout << "EPP out of TOF range for workspace index " << i
<< ". Peak height set to zero.";
g_log.warning() << sout.str();
}
outputWS->getRef<double>(ColumnNames::HEIGHT, i) = height;
outputWS->getRef<double>(ColumnNames::CHI_SQUARED, i) = 1;
outputWS->getRef<std::string>(ColumnNames::STATUS, i) = "success";
}
setProperty(PropertyNames::OUTPUT_WORKSPACE, outputWS);
}
//----------------------------------------------------------------------------------------------
/** Validate the algorithm's properties.
*
* @return A map of porperty names and their issues.
*/
std::map<std::string, std::string> CreateEPP::validateInputs(void) {
std::map<std::string, std::string> issues;
API::MatrixWorkspace_sptr inputWS =
getProperty(PropertyNames::INPUT_WORKSPACE);
if (!inputWS->run().hasProperty("Ei")) {
issues[PropertyNames::INPUT_WORKSPACE] =
"Workspace is missing the 'Ei' sample log.";
}
return issues;
}
} // namespace Algorithms
} // namespace Mantid