-
Notifications
You must be signed in to change notification settings - Fork 122
/
ApplyCalibration.cpp
126 lines (110 loc) · 5.59 KB
/
ApplyCalibration.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
// 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/ApplyCalibration.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidGeometry/Instrument/ComponentInfo.h"
#include "MantidGeometry/Instrument/DetectorInfo.h"
#include "MantidGeometry/Objects/IObject.h"
#include "MantidKernel/Logger.h"
namespace Mantid::Algorithms {
namespace {
Kernel::Logger logger("ApplyCalibration");
}
DECLARE_ALGORITHM(ApplyCalibration)
using namespace Kernel;
using namespace API;
/// Initialisation method.
void ApplyCalibration::init() {
declareProperty(std::make_unique<API::WorkspaceProperty<API::MatrixWorkspace>>("Workspace", "", Direction::InOut),
"The name of the input workspace to apply the calibration to");
declareProperty(std::make_unique<API::WorkspaceProperty<API::ITableWorkspace>>(
"CalibrationTable", "", Direction::Input, PropertyMode::Optional),
"The name of the table workspace containing the new "
"positions of detectors");
declareProperty(std::make_unique<API::WorkspaceProperty<API::ITableWorkspace>>("PositionTable", "", Direction::Input,
PropertyMode::Optional),
"Deprecated: Use Property 'CalibrationTable'");
}
/** Executes the algorithm. Moving detectors of input workspace to positions
*indicated in table workspace
*
* @throw FileError Thrown if unable to get instrument from workspace,
* table workspace is incompatible with instrument
*/
void ApplyCalibration::exec() {
// Get pointers to the workspace, parameter map and table
API::MatrixWorkspace_sptr inputWS = getProperty("Workspace");
API::ITableWorkspace_sptr CalTable = getProperty("CalibrationTable");
API::ITableWorkspace_sptr PosTable = getProperty("PositionTable");
// Elucidate if using property PositionTable table instead of CalibrationTable
if (!CalTable && !PosTable) {
throw std::runtime_error("Either CalibrationTable or PositionTable must be supplied");
}
if (PosTable && !CalTable) {
logger.notice("Property 'PositionTable' has been deprecated. Please use "
"'CalibrationTable' in its place\n");
CalTable = PosTable;
}
// initialize variables common to all calibrations
std::vector<std::string> columnNames = CalTable->getColumnNames();
size_t numDetector = CalTable->rowCount();
ColumnVector<int> detectorID = CalTable->getVector("Detector ID");
// Default calibration
if (std::find(columnNames.begin(), columnNames.end(), "Detector Position") != columnNames.end()) {
auto &detectorInfo = inputWS->mutableDetectorInfo();
ColumnVector<V3D> detPos = CalTable->getVector("Detector Position");
// PARALLEL_FOR_NO_WSP_CHECK()
for (size_t i = 0; i < numDetector; ++i) {
const auto index = detectorInfo.indexOf(detectorID[i]);
detectorInfo.setPosition(index, detPos[i]);
}
}
// Bar scan calibration: pixel Y-coordinate
if (std::find(columnNames.begin(), columnNames.end(), "Detector Y Coordinate") != columnNames.end()) {
// the detectorInfo index of a particular pixel detector is the same as the
// componentInfo index for the same pixel detector
auto &detectorInfo = inputWS->mutableDetectorInfo();
ColumnVector<double> yCoordinate = CalTable->getVector("Detector Y Coordinate");
// PARALLEL_FOR_NO_WSP_CHECK()
for (size_t i = 0; i < numDetector; ++i) {
const auto index = detectorInfo.indexOf(detectorID[i]);
V3D xyz = detectorInfo.position(index);
detectorInfo.setPosition(index, V3D(xyz.X(), yCoordinate[i], xyz.Z()));
}
}
// Apparent tube width calibration along X-coordinate
if (std::find(columnNames.begin(), columnNames.end(), "Detector Width") != columnNames.end()) {
auto &detectorInfo = inputWS->detectorInfo();
auto &componentInfo = inputWS->mutableComponentInfo();
ColumnVector<double> widths = CalTable->getVector("Detector Width");
// PARALLEL_FOR_NO_WSP_CHECK()
for (size_t i = 0; i < numDetector; ++i) {
const auto index = detectorInfo.indexOf(detectorID[i]);
double nominalWidth = componentInfo.shape(index).getBoundingBox().width().X();
V3D oldScaleFactor = componentInfo.scaleFactor(index);
componentInfo.setScaleFactor(index, V3D(widths[i] / nominalWidth, oldScaleFactor.Y(), oldScaleFactor.Z()));
}
}
// Bar scan calibration: pixel height
if (std::find(columnNames.begin(), columnNames.end(), "Detector Height") != columnNames.end()) {
// the detectorInfo index of a particular pixel detector is the same as the
// componentInfo index for the same pixel detector
auto &detectorInfo = inputWS->mutableDetectorInfo();
auto &componentInfo = inputWS->mutableComponentInfo();
ColumnVector<double> height = CalTable->getVector("Detector Height");
// PARALLEL_FOR_NO_WSP_CHECK()
for (size_t i = 0; i < numDetector; ++i) {
const auto index = detectorInfo.indexOf(detectorID[i]);
// update pixel height along Y coordinate
double nominalHeight = componentInfo.shape(index).getBoundingBox().width().Y();
V3D oldScaleFactor = componentInfo.scaleFactor(index);
componentInfo.setScaleFactor(index, V3D(oldScaleFactor.X(), height[i] / nominalHeight, oldScaleFactor.Z()));
}
}
}
} // namespace Mantid::Algorithms