-
Notifications
You must be signed in to change notification settings - Fork 122
/
ResizeRectangularDetector.cpp
137 lines (118 loc) · 5.45 KB
/
ResizeRectangularDetector.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
// 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
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidAlgorithms/ResizeRectangularDetector.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/ResizeRectangularDetectorHelper.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidGeometry/IComponent.h"
#include "MantidGeometry/Instrument.h"
#include "MantidGeometry/Instrument/ComponentInfo.h"
#include "MantidGeometry/Instrument/RectangularDetector.h"
#include "MantidKernel/System.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;
namespace Mantid {
namespace Algorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(ResizeRectangularDetector)
//----------------------------------------------------------------------------------------------
/// Algorithm's name for identification. @see Algorithm::name
const std::string ResizeRectangularDetector::name() const {
return "ResizeRectangularDetector";
}
/// Algorithm's version for identification. @see Algorithm::version
int ResizeRectangularDetector::version() const { return 1; }
/// Algorithm's category for identification. @see Algorithm::category
const std::string ResizeRectangularDetector::category() const {
return "DataHandling\\Instrument";
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void ResizeRectangularDetector::init() {
// When used as a Child Algorithm the workspace name is not used - hence the
// "Anonymous" to satisfy the validator
declareProperty(make_unique<WorkspaceProperty<Workspace>>(
"Workspace", "Anonymous", Direction::InOut));
declareProperty("ComponentName", "",
"The name of the RectangularDetector to resize.");
declareProperty("ScaleX", 1.0,
"The scaling factor in the X direction. Default 1.0");
declareProperty("ScaleY", 1.0,
"The scaling factor in the Y direction. Default 1.0");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void ResizeRectangularDetector::exec() {
// Get the input workspace
Workspace_sptr ws = getProperty("Workspace");
MatrixWorkspace_sptr inputW =
boost::dynamic_pointer_cast<MatrixWorkspace>(ws);
DataObjects::PeaksWorkspace_sptr inputP =
boost::dynamic_pointer_cast<DataObjects::PeaksWorkspace>(ws);
// Get some stuff from the input workspace
Instrument_sptr inst;
if (inputW) {
inst = boost::const_pointer_cast<Instrument>(inputW->getInstrument());
if (!inst)
throw std::runtime_error("Could not get a valid instrument from the "
"MatrixWorkspace provided as input");
} else if (inputP) {
inst = boost::const_pointer_cast<Instrument>(inputP->getInstrument());
if (!inst)
throw std::runtime_error("Could not get a valid instrument from the "
"PeaksWorkspace provided as input");
} else {
if (!inst)
throw std::runtime_error("Could not get a valid instrument from the "
"workspace and it does not seem to be valid as "
"input (must be either MatrixWorkspace or "
"PeaksWorkspace");
}
std::string ComponentName = getPropertyValue("ComponentName");
double ScaleX = getProperty("ScaleX");
double ScaleY = getProperty("ScaleY");
if (ComponentName.empty())
throw std::runtime_error("You must specify a ComponentName.");
IComponent_const_sptr comp;
comp = inst->getComponentByName(ComponentName);
if (!comp)
throw std::runtime_error("Component with name " + ComponentName +
" was not found.");
RectangularDetector_const_sptr det =
boost::dynamic_pointer_cast<const RectangularDetector>(comp);
if (!det)
throw std::runtime_error("Component with name " + ComponentName +
" is not a RectangularDetector.");
auto input = boost::dynamic_pointer_cast<ExperimentInfo>(ws);
Geometry::ParameterMap &pmap = input->instrumentParameters();
auto oldscalex = pmap.getDouble(det->getName(), std::string("scalex"));
auto oldscaley = pmap.getDouble(det->getName(), std::string("scaley"));
// Add a parameter for the new scale factors
pmap.addDouble(det->getComponentID(), "scalex", ScaleX);
pmap.addDouble(det->getComponentID(), "scaley", ScaleY);
pmap.clearPositionSensitiveCaches();
// Positions of detectors are now stored in DetectorInfo, so we must update
// positions there.
// This algorithm is setting the absolute scale factor. Since there may be a
// previous scaling we have to factor that out.
double relscalex = ScaleX;
double relscaley = ScaleY;
if (!oldscalex.empty())
relscalex /= oldscalex[0];
if (!oldscaley.empty())
relscaley /= oldscaley[0];
applyRectangularDetectorScaleToComponentInfo(input->mutableComponentInfo(),
comp->getComponentID(),
relscalex, relscaley);
}
} // namespace Algorithms
} // namespace Mantid