Mantid
Loading...
Searching...
No Matches
WorkspaceBoundingBox.cpp
Go to the documentation of this file.
3
4namespace Mantid::Algorithms {
5
6namespace {
7constexpr int HISTOGRAM_INDEX{0};
8}
9
11 const double integrationRadius, const double beamRadius,
12 const bool ignoreDirectBeam, const double cenX, const double cenY)
13 : m_workspace(workspace), m_integrationRadiusSq(integrationRadius * integrationRadius),
14 m_beamRadiusSq(beamRadius * beamRadius), m_ignoreDirectBeam(ignoreDirectBeam) {
15 if (m_workspace->y(0).size() != 1)
16 throw std::runtime_error("This object only works with integrated workspaces");
17
18 m_spectrumInfo = &workspace->spectrumInfo();
19 m_numSpectra = m_workspace->getNumberHistograms();
20
21 this->setCenterPrev(cenX, cenY);
23}
24
26
28 if (!m_spectrumInfo)
29 throw std::runtime_error("SpectrumInfo object is not initialized");
30
32}
33
34// find the min/max for x/y coords in set of valid spectra, update position of bounding box
36 // reset temporary place for the calculation
38 double totalCount = 0;
39
40 for (std::size_t i = 0; i < m_numSpectra; i++) {
41 if (!isValidIndex(i))
42 continue;
43
44 updateMinMax(i);
45
47 totalCount += updatePositionAndReturnCount(i);
48 }
49 this->normalizePosition(totalCount);
50}
51
52// In subsequent iterations check if spectra fits in the normalized bounding box(generated by previous iterations)
53// If so, update position
55 // reset temporary place for the calculation
57 double totalCount = 0;
58
59 const auto &spectrumInfo = m_workspace->spectrumInfo();
60 for (std::size_t i = 0; i < m_numSpectra; i++) {
61 if (!isValidIndex(i))
62 continue;
63
64 const V3D pos = spectrumInfo.position(i);
65
66 if (this->symmetricRegionContainsPoint(pos.X(), pos.Y()) && includeInIntegration(pos)) {
67 totalCount += updatePositionAndReturnCount(i);
68 }
69 }
70 this->normalizePosition(totalCount);
71}
72
73double WorkspaceBoundingBox::countsValue(const std::size_t index) const {
74 return m_workspace->y(index)[HISTOGRAM_INDEX];
75}
76
81
82void WorkspaceBoundingBox::setCenterPrev(const double x, const double y) {
83 this->m_centerXPosPrev = x;
84 this->m_centerYPosPrev = y;
85}
86
90void WorkspaceBoundingBox::setBounds(const double xMin, const double xMax, const double yMin, const double yMax) {
91 this->m_xBoxMin = xMin;
92 this->m_xBoxMax = xMax;
93 this->m_yBoxMin = yMin;
94 this->m_yBoxMax = yMax;
95}
96
103bool WorkspaceBoundingBox::isValidIndex(const std::size_t index) const {
104 if (!m_spectrumInfo)
105 throw std::runtime_error("SpectrumInfo object is not initialized");
107 g_log.warning() << "Workspace index " << index << " has no detector assigned to it - discarding\n";
108 return false;
109 }
110 // Skip if we have a monitor or if the detector is masked.
111 if (this->m_spectrumInfo->isMonitor(index) || this->m_spectrumInfo->isMasked(index))
112 return false;
113
114 // Get the current spectrum
115 const auto YIn = this->countsValue(index);
116 // Skip if NaN of inf
117 if (std::isnan(YIn) || std::isinf(YIn))
118 return false;
119 return true;
120}
121
129 const auto counts = this->countsValue(index);
130 const auto &pos = this->position(index);
131
132 this->m_centerXPosCurr += counts * pos.X();
133 this->m_centerYPosCurr += counts * pos.Y();
134
135 return counts;
136}
137
144 const auto &pos = this->position(index);
145 const double x = pos.X();
146 const double y = pos.Y();
147
148 this->m_xPosMin = std::min(x, this->m_xPosMin);
149 this->m_xPosMax = std::max(x, this->m_xPosMax);
150 this->m_yPosMin = std::min(y, this->m_yPosMin);
151 this->m_yPosMax = std::max(y, this->m_yPosMax);
152}
153
159 return this->includeInIntegration(this->position(index));
160}
161
163 const double dx = position.X() - this->m_centerXPosPrev;
164 const double dy = position.Y() - this->m_centerYPosPrev;
165 const double distanceFromCenterSq = dx * dx + dy * dy;
166
167 if (m_ignoreDirectBeam) {
168 if (distanceFromCenterSq < m_beamRadiusSq)
169 return false;
170 }
171
172 return bool(distanceFromCenterSq < m_integrationRadiusSq);
173}
174
176 const auto xExtent = (m_centerXPosPrev - m_centerXPosCurr);
177 const auto yExtent = (m_centerYPosPrev - m_centerYPosCurr);
178 return sqrt(xExtent * xExtent + yExtent * yExtent);
179}
180
185 if (m_ignoreDirectBeam) {
186 const double radiusX = this->calculateRadiusX();
187 const double radiusY = this->calculateRadiusY();
188 if (radiusX * radiusX <= m_beamRadiusSq || radiusY * radiusY <= m_beamRadiusSq) {
189 return true;
190 }
191 }
192 return false;
193}
194
200
201 const double radiusX = this->calculateRadiusX();
202 const double radiusY = this->calculateRadiusY();
203 this->setBounds(m_centerXPosCurr - radiusX, m_centerXPosCurr + radiusX, m_centerYPosCurr - radiusY,
204 m_centerYPosCurr + radiusY);
205}
206
210
214
218void WorkspaceBoundingBox::normalizePosition(const double totalCounts) {
219 this->m_centerXPosCurr /= std::fabs(totalCounts);
220 this->m_centerYPosCurr /= std::fabs(totalCounts);
221}
222
230 return (x <= this->m_xBoxMax && x >= this->m_xBoxMin && y <= m_yBoxMax && y >= m_yBoxMin);
231}
232
233} // namespace Mantid::Algorithms
double position
Definition GetAllEi.cpp:154
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
bool isMonitor(const size_t index) const
Returns true if the detector(s) associated with the spectrum are monitors.
bool hasDetectors(const size_t index) const
Returns true if the spectrum is associated with detectors in the instrument.
Kernel::V3D position(const size_t index) const
Returns the position of the spectrum with given index.
bool centerOfMassWithinBeamCenter()
This only has effect if the integral is ignoring the beam center as a whole.
API::MatrixWorkspace_const_sptr m_workspace
bool symmetricRegionContainsPoint(double x, double y)
Checks if a given x/y coord is within the bounding box.
void updateMinMax(const std::size_t index)
Compare current mins and maxs to the coordinates of the spectrum at index expnd mins and maxs to incl...
void prepareCenterCalculation()
Copy the current center to the previous and update the x/y range for overall integration.
void normalizePosition(const double totalCounts)
Perform normalization on x/y coords over given values.
void setBounds(const double xMin, const double xMax, const double yMin, const double yMax)
Update the symmetric (in x and y separately) range of space that is symmetric around the beam center.
bool includeInIntegration(const std::size_t index)
Checks to see if spectrum at index should be included in the integration.
double updatePositionAndReturnCount(const std::size_t index)
Sets member variables x/y to new x/y based on spectrum info and historgram data at the given index.
bool isValidIndex(const std::size_t index) const
Performs checks on the spectrum located at index to determine if it is acceptable to be operated on.
Kernel::V3D position(const std::size_t index) const
void setCenterPrev(const double x, const double y)
WorkspaceBoundingBox(const API::MatrixWorkspace_const_sptr &workspace, const double integrationRadius, const double beamRadius, const bool ignoreDirectBeam, const double cenX, const double cenY)
double countsValue(const std::size_t index) const
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
Class for 3D vectors.
Definition V3D.h:34
constexpr double X() const noexcept
Get x.
Definition V3D.h:238
constexpr double Y() const noexcept
Get y.
Definition V3D.h:239
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
Kernel::Logger g_log("DetermineSpinStateOrder")