-
Notifications
You must be signed in to change notification settings - Fork 121
/
ConvertDiffCal.cpp
158 lines (138 loc) · 5.88 KB
/
ConvertDiffCal.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
158
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidAlgorithms/ConvertDiffCal.h"
#include "MantidAPI/IAlgorithm.h"
#include "MantidAPI/SpectrumInfo.h"
#include "MantidAPI/TableRow.h"
#include "MantidDataObjects/OffsetsWorkspace.h"
#include "MantidDataObjects/TableWorkspace.h"
#include "MantidGeometry/IComponent.h"
#include "MantidGeometry/Instrument.h"
#include "MantidKernel/PhysicalConstants.h"
namespace Mantid {
namespace Algorithms {
using Mantid::API::IAlgorithm_sptr;
using Mantid::API::ITableWorkspace;
using Mantid::API::ITableWorkspace_sptr;
using Mantid::API::Progress;
using Mantid::API::WorkspaceProperty;
using Mantid::DataObjects::OffsetsWorkspace;
using Mantid::DataObjects::OffsetsWorkspace_const_sptr;
using Mantid::DataObjects::TableWorkspace;
using Mantid::DataObjects::TableWorkspace_sptr;
using Mantid::Geometry::Instrument_const_sptr;
using Mantid::Kernel::Direction;
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(ConvertDiffCal)
//----------------------------------------------------------------------------------------------
/// Algorithms name for identification. @see Algorithm::name
const std::string ConvertDiffCal::name() const { return "ConvertDiffCal"; }
/// Algorithm's version for identification. @see Algorithm::version
int ConvertDiffCal::version() const { return 1; }
/// Algorithm's category for identification. @see Algorithm::category
const std::string ConvertDiffCal::category() const { return "Diffraction\\Utility"; }
/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string ConvertDiffCal::summary() const { return "Convert diffraction calibration from old to new style"; }
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void ConvertDiffCal::init() {
declareProperty(std::make_unique<WorkspaceProperty<OffsetsWorkspace>>("OffsetsWorkspace", "", Direction::Input),
"OffsetsWorkspace containing the calibration offsets.");
declareProperty(std::make_unique<WorkspaceProperty<ITableWorkspace>>("OutputWorkspace", "", Direction::Output),
"An output workspace.");
}
/**
* @throws std::logic_error if there is more than one detector id
* for the spectrum.
* @param offsetsWS
* @param index
* @return The proper detector id.
*/
detid_t getDetID(const OffsetsWorkspace_const_sptr &offsetsWS, const size_t index) {
auto detIDs = offsetsWS->getSpectrum(index).getDetectorIDs();
if (detIDs.size() != 1) {
std::stringstream msg;
msg << "Encountered spectrum with multiple detector ids (size=" << detIDs.size() << ")";
throw std::logic_error(msg.str());
}
return (*(detIDs.begin()));
}
/**
* @throws std::logic_error if the offset found is non-physical.
* @param offsetsWS
* @param detid
* @return The offset value or zero if not specified.
*/
double getOffset(const OffsetsWorkspace_const_sptr &offsetsWS, const detid_t detid) {
const double offset = offsetsWS->getValue(detid, 0.0);
if (offset <= -1.) { // non-physical
std::stringstream msg;
msg << "Encountered offset of " << offset << " which converts data to negative d-spacing for detectorID " << detid
<< "\n";
throw std::logic_error(msg.str());
}
return offset;
}
/**
* @param offsetsWS
* @param index
* @param spectrumInfo
* @return The offset adjusted value of DIFC
*/
double calculateDIFC(const OffsetsWorkspace_const_sptr &offsetsWS, const size_t index,
const Mantid::API::SpectrumInfo &spectrumInfo) {
const detid_t detid = getDetID(offsetsWS, index);
const double offset = getOffset(offsetsWS, detid);
double twotheta;
try {
twotheta = spectrumInfo.twoTheta(index);
} catch (std::runtime_error &) {
// Choose an arbitrary angle if detector 2theta determination fails.
twotheta = 0.;
}
// the factor returned is what is needed to convert TOF->d-spacing
// the table is supposed to be filled with DIFC which goes the other way
const double factor =
Mantid::Geometry::Conversion::tofToDSpacingFactor(spectrumInfo.l1(), spectrumInfo.l2(index), twotheta, offset);
return 1. / factor;
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void ConvertDiffCal::exec() {
OffsetsWorkspace_const_sptr offsetsWS = getProperty("OffsetsWorkspace");
// initial setup of new style config
ITableWorkspace_sptr configWksp = std::make_shared<TableWorkspace>();
configWksp->addColumn("int", "detid");
configWksp->addColumn("double", "difc");
configWksp->addColumn("double", "difa");
configWksp->addColumn("double", "tzero");
// create values in the table
const size_t numberOfSpectra = offsetsWS->getNumberHistograms();
Progress progress(this, 0.0, 1.0, numberOfSpectra);
const Mantid::API::SpectrumInfo &spectrumInfo = offsetsWS->spectrumInfo();
for (size_t i = 0; i < numberOfSpectra; ++i) {
API::TableRow newrow = configWksp->appendRow();
newrow << static_cast<int>(getDetID(offsetsWS, i));
newrow << calculateDIFC(offsetsWS, i, spectrumInfo);
newrow << 0.; // difa
newrow << 0.; // tzero
progress.report();
}
// sort the results
IAlgorithm_sptr sortTable = createChildAlgorithm("SortTableWorkspace");
sortTable->setProperty("InputWorkspace", configWksp);
sortTable->setProperty("OutputWorkspace", configWksp);
sortTable->setPropertyValue("Columns", "detid");
sortTable->executeAsChildAlg();
// copy over the results
configWksp = sortTable->getProperty("OutputWorkspace");
setProperty("OutputWorkspace", configWksp);
}
} // namespace Algorithms
} // namespace Mantid