Mantid
Loading...
Searching...
No Matches
SpecialWorkspace2D.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include "MantidDataObjects/DllConfig.h"
12
13#include <fstream>
14#include <sstream>
15
16using std::set;
17using std::size_t;
18
19namespace Mantid::DataObjects {
20
21namespace {
22Kernel::Logger g_log("SpecialWorkspace2D");
23}
24
25// Register the workspace
26DECLARE_WORKSPACE(SpecialWorkspace2D)
27
28//----------------------------------------------------------------------------------------------
34SpecialWorkspace2D::SpecialWorkspace2D(const Geometry::Instrument_const_sptr &inst, const bool includeMonitors) {
35 // Init the Workspace2D with one spectrum per detector, in the same order.
36 this->initialize(inst->getNumberDetectors(!includeMonitors), 1, 1);
37
38 // Copy the instrument
39 this->setInstrument(inst);
40
41 // Initialize the spectra-det-map, 1:1 between spectrum number and det ID
42 this->MatrixWorkspace::rebuildSpectraMapping(includeMonitors);
43
44 // Make the mapping, which will be used for speed later.
45 buildDetectorIDMapping();
46}
47
48//----------------------------------------------------------------------------------------------
54 this->initialize(parent->getNumberHistograms(), 1, 1);
55 API::WorkspaceFactory::Instance().initializeFromParent(*parent, *this, false);
56 // Make the mapping, which will be used for speed later.
58}
59
66SpecialWorkspace2D::SpecialWorkspace2D(const std::vector<detid_t> &detids) {
67 if (detids.empty()) // skip the full initialize method
68 this->init(0, 1, 1);
69 else
70 this->initialize(detids.size(), 1, 1);
71 // set the detector ids
72 for (size_t wi = 0; wi < detids.size(); ++wi) {
73 this->getSpectrum(wi).setDetectorID(detids[wi]);
74 }
75 // set up the rest of the mapping information
78}
79
80//----------------------------------------------------------------------------------------------
87void SpecialWorkspace2D::init(const size_t &NVectors, const size_t &XLength, const size_t &YLength) {
88 if ((XLength != 1) || (YLength != 1))
89 throw std::invalid_argument("SpecialWorkspace2D must have 'spectra' of length 1 only.");
90 // Continue with standard initialization
91 Workspace2D::init(NVectors, XLength, YLength);
92 // This method doesn't have an instrument to set the number of detectors, so set it here
93 this->setNumberOfDetectorGroups(NVectors);
94}
95
96void SpecialWorkspace2D::init(const HistogramData::Histogram &histogram) {
97 if (histogram.xMode() != HistogramData::Histogram::XMode::Points)
98 throw std::runtime_error("SpecialWorkspace2D can only be initialized with XMode::Points");
99 if (histogram.x().size() != 1)
100 throw std::runtime_error("SpecialWorkspace2D can only be initialized with length 1");
102}
103
107const std::string SpecialWorkspace2D::toString() const {
108 std::ostringstream os;
109 os << "Title: " << getTitle() << "\n";
110 os << "Histograms: " << getNumberHistograms() << "\n";
111 return os.str();
112}
113
115 detID_to_WI.clear();
116 for (size_t wi = 0; wi < getNumberHistograms(); wi++) {
117 set<detid_t> dets = this->getDetectorIDs(wi);
118 for (auto det : dets) {
119 detID_to_WI[det] = wi;
120 }
121 }
122}
123
124bool SpecialWorkspace2D::contains(const detid_t detectorID) const {
125 auto it = detID_to_WI.find(detectorID);
126 return it != detID_to_WI.end();
127}
128
129//----------------------------------------------------------------------------------------------
136double SpecialWorkspace2D::getValue(const detid_t detectorID) const {
137 auto it = detID_to_WI.find(detectorID);
138
139 if (it == detID_to_WI.end()) {
140 std::ostringstream os;
141 os << "SpecialWorkspace2D: " << this->getName() << " Detector ID = " << detectorID
142 << " Size(Map) = " << this->detID_to_WI.size() << '\n';
143 throw std::invalid_argument(os.str());
144 } else {
145 return this->y(it->second)[0];
146 }
147}
148
149//----------------------------------------------------------------------------------------------
157double SpecialWorkspace2D::getValue(const detid_t detectorID, const double defaultValue) const {
158 auto it = detID_to_WI.find(detectorID);
159 if (it == detID_to_WI.end())
160 return defaultValue;
161 else {
162 if (it->second < getNumberHistograms()) // don't let it generate an exception
163 {
164 return this->y(it->second)[0];
165 } else {
166 g_log.debug() << "getValue(" << detectorID << "->" << (it->second) << ", " << defaultValue
167 << ") index out of range\n";
168 return defaultValue;
169 }
170 }
171}
172
173//----------------------------------------------------------------------------------------------
181void SpecialWorkspace2D::setValue(const detid_t detectorID, const double value, const double error) {
182 auto it = detID_to_WI.find(detectorID);
183 if (it == detID_to_WI.end()) {
184 std::stringstream msg;
185 msg << "SpecialWorkspace2D::setValue(): Input Detector ID = " << detectorID << " Is Invalid";
186 throw std::invalid_argument(msg.str());
187 } else {
188 this->mutableY(it->second)[0] = value;
189 this->mutableE(it->second)[0] = error;
190 }
191}
192
203void SpecialWorkspace2D::setValue(const set<detid_t> &detectorIDs, const double value, const double error) {
204 for (auto detectorID : detectorIDs) {
205 this->setValue(detectorID, value, error);
206 }
207}
208
209//----------------------------------------------------------------------------------------------
216set<detid_t> SpecialWorkspace2D::getDetectorIDs(const std::size_t workspaceIndex) const {
217 if (size_t(workspaceIndex) > this->getNumberHistograms())
218 throw std::invalid_argument("SpecialWorkspace2D::getDetectorIDs(): Invalid workspaceIndex given.");
219 return this->getSpectrum(workspaceIndex).getDetectorIDs();
220}
221
222//--------------------------------------------------------------------------------------------
227void SpecialWorkspace2D::binaryOperation(const std::shared_ptr<const SpecialWorkspace2D> &ws,
228 const unsigned int operatortype) {
229
230 // 1. Check compatibility between this and input workspace
231 if (!this->isCompatible(ws)) {
232 throw std::invalid_argument("Two SpecialWorkspace2D objects are not compatible!");
233 }
234
235 switch (operatortype) {
237 this->binaryAND(ws);
238 break;
240 this->binaryOR(ws);
241 break;
243 this->binaryXOR(ws);
244 break;
245 default:
246 throw std::invalid_argument("Invalid Operator");
247 break;
248 }
249}
250
251//--------------------------------------------------------------------------------------------
256void SpecialWorkspace2D::binaryOperation(const unsigned int operatortype) {
257
258 switch (operatortype) {
260 this->binaryNOT();
261 break;
262 default:
263 g_log.error() << "Operator " << operatortype << " Is Not Valid In BinaryOperation(operatortype)\n";
264 throw std::invalid_argument("Invalid Operator");
265 break;
266 }
267}
268
272void SpecialWorkspace2D::binaryAND(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
273
274 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
275 double y1 = this->y(i)[0];
276 double y2 = ws->y(i)[0];
277
278 if (y1 < 1.0E-10 || y2 < 1.0E-10) {
279 this->mutableY(i)[0] = 0.0;
280 } else {
281 this->mutableY(i)[0] += y2;
282 }
283 }
284}
285
289void SpecialWorkspace2D::binaryOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
290
291 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
292 double y1 = this->y(i)[0];
293 double y2 = ws->y(i)[0];
294
295 double max = y1;
296 if (y2 > y1) {
297 max = y2;
298 }
299 this->mutableY(i)[0] = max;
300
301 /*
302if (y1 < 1.0E-10 && y2 < 1.0E-10){
303 this->mutableY(i)[0] = 0.0;
304} else {
305 this->mutableY(i)[0] += y2;
306}
307*/
308 }
309}
310
314void SpecialWorkspace2D::binaryXOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
315
316 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
317 double y1 = this->y(i)[0];
318 double y2 = ws->y(i)[0];
319 if (y1 < 1.0E-10 && y2 < 1.0E-10) {
320 this->mutableY(i)[0] = 0.0;
321 } else if (y1 > 1.0E-10 && y2 > 1.0E-10) {
322 this->mutableY(i)[0] = 0.0;
323 } else {
324 this->mutableY(i)[0] = 1.0;
325 }
326 }
327}
328
333
334 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
335 double y1 = this->y(i)[0];
336 if (y1 < 1.0E-10) {
337 this->mutableY(i)[0] = 1.0;
338 } else {
339 this->mutableY(i)[0] = 0.0;
340 }
341 }
342}
343
344//----------------------------------------------------------------------------------------------
345/* Check 2 SpecialWorkspace2D are compatible
346 * @ parameter
347 * @ return
348 */
349bool SpecialWorkspace2D::isCompatible(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
350
351 // 1. Check number of histogram
352 size_t numhist1 = this->getNumberHistograms();
353 size_t numhist2 = ws->getNumberHistograms();
354 if (numhist1 != numhist2) {
355 g_log.debug() << "2 Workspaces have different number of histograms: " << numhist1 << " vs. " << numhist2 << '\n';
356 return false;
357 }
358
359 // 2. Check detector ID
360 for (size_t ispec = 0; ispec < numhist1; ispec++) {
361 set<detid_t> ids1 = this->getSpectrum(ispec).getDetectorIDs();
362 set<detid_t> ids2 = ws->getSpectrum(ispec).getDetectorIDs();
363
364 if (ids1.size() != ids2.size()) {
365 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different number of detectors " << ids1.size()
366 << " vs. " << ids2.size() << '\n';
367 return false;
368 } else if (ids1.empty()) {
369 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces both have 0 detectors. \n";
370 return false;
371 } else if (*ids1.begin() != *ids2.begin()) {
372 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different Detector ID " << *ids1.begin() << " vs. "
373 << *ids2.begin() << '\n';
374 return false;
375 }
376 } // false
377
378 return true;
379}
380
381//----------------------------------------------------------------------------------------------
384void SpecialWorkspace2D::copyFrom(std::shared_ptr<const SpecialWorkspace2D> sourcews) {
385 // Check
386 if (this->getNumberHistograms() != sourcews->getNumberHistograms()) {
387 throw std::invalid_argument("Incompatible number of histograms");
388 }
389
390 // Copy data
391 for (size_t ispec = 0; ispec < this->getNumberHistograms(); ispec++) {
392
393 // 1.1 Check size
394 Mantid::HistogramData::HistogramX const &inx = sourcews->x(ispec);
395 Mantid::HistogramData::HistogramY const &iny = sourcews->y(ispec);
396 Mantid::HistogramData::HistogramE const &ine = sourcews->e(ispec);
397
398 Mantid::HistogramData::HistogramX &outx = this->mutableX(ispec);
399 Mantid::HistogramData::HistogramY &outy = this->mutableY(ispec);
400 Mantid::HistogramData::HistogramE &oute = this->mutableE(ispec);
401
402 if (inx.size() != outx.size() || iny.size() != outy.size() || ine.size() != oute.size()) {
403 throw std::invalid_argument("X, Y, E size different within spectrum");
404 }
405
406 // 1.2 Copy data
407 for (size_t i = 0; i < inx.size(); i++) {
408 outx[i] = inx[i];
409 }
410 for (size_t i = 0; i < iny.size(); i++) {
411 outy[i] = iny[i];
412 oute[i] = ine[i];
413 }
414 }
415
416 // Copy detector map
417 this->detID_to_WI = sourcews->detID_to_WI;
418}
419
420} // namespace Mantid::DataObjects
421
423
424namespace Mantid::Kernel {
425
426template <>
428IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_sptr>(const std::string &name) const {
429 auto *prop =
430 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
431 if (prop) {
432 return *prop;
433 } else {
434 std::string message =
435 "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<SpecialWorkspace2D>.";
436 throw std::runtime_error(message);
437 }
438}
439
440template <>
442IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_const_sptr>(const std::string &name) const {
443 auto const *prop =
444 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
445 if (prop) {
446 return prop->operator()();
447 } else {
448 std::string message =
449 "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<SpecialWorkspace2D>.";
450 throw std::runtime_error(message);
451 }
452}
453
454} // namespace Mantid::Kernel
455
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
double error
#define DECLARE_WORKSPACE(classname)
void setNumberOfDetectorGroups(const size_t count) const
Sets the number of detector groups.
void setDetectorID(const detid_t detID)
Clear the list of detector IDs, then add one.
Definition ISpectrum.cpp:84
const std::set< detid_t > & getDetectorIDs() const
Get a const reference to the detector IDs set.
void rebuildSpectraMapping(const bool includeMonitors=true, const specnum_t specNumOffset=1)
Build the default spectra mapping, most likely wanted after an instrument update.
HistogramData::HistogramX & mutableX(const size_t index) &
void initialize(const std::size_t &NVectors, const std::size_t &XLength, const std::size_t &YLength)
Initialize the workspace.
HistogramData::Histogram histogram(const size_t index) const
Returns the Histogram at the given workspace index.
const std::string getTitle() const override
Gets MatrixWorkspace title (same as Run object run_title property)
HistogramData::HistogramE & mutableE(const size_t index) &
HistogramData::HistogramY & mutableY(const size_t index) &
const std::string & getName() const override
Get the workspace name.
Definition Workspace.cpp:59
double getValue(const detid_t detectorID) const
Return the special value (Y) in the workspace at the given detector ID.
const std::string toString() const override
Return human-readable string.
bool contains(const detid_t detectorID) const
void init(const size_t &NVectors, const size_t &XLength, const size_t &YLength) override
Sets the size of the workspace and initializes arrays to zero.
bool isCompatible(const std::shared_ptr< const SpecialWorkspace2D > &ws)
std::set< detid_t > getDetectorIDs(const std::size_t workspaceIndex) const
Return the detector ID at the given workspace index (i.e., spectrum/histogram index)
void binaryOR(const std::shared_ptr< const SpecialWorkspace2D > &ws)
OR operator.
std::map< detid_t, std::size_t > detID_to_WI
Map with key = detector ID, and value = workspace index.
void binaryOperation(const std::shared_ptr< const SpecialWorkspace2D > &ws, const unsigned int operatortype)
Return the result of operator & @ parameter @ return.
virtual void copyFrom(std::shared_ptr< const SpecialWorkspace2D > sourcews)
Duplicate SpecialWorkspace2D.
void binaryXOR(const std::shared_ptr< const SpecialWorkspace2D > &ws)
Excluded Or operator.
void binaryAND(const std::shared_ptr< const SpecialWorkspace2D > &ws)
AND operator.
void setValue(const detid_t detectorID, const double value, const double error=0.)
Set the special value (Y) in the workspace at the given detector ID.
std::size_t getNumberHistograms() const override
Returns the histogram number.
void init(const std::size_t &NVectors, const std::size_t &XLength, const std::size_t &YLength) override
Called by initialize()
Histogram1D & getSpectrum(const size_t index) override
Return the underlying ISpectrum ptr at the given workspace index.
Definition Workspace2D.h:64
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< const SpecialWorkspace2D > SpecialWorkspace2D_const_sptr
shared pointer to a const SpecialWorkspace2D
std::shared_ptr< SpecialWorkspace2D > SpecialWorkspace2D_sptr
shared pointer to the SpecialWorkspace2D class
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.