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 +
11
12#include <fstream>
13#include <sstream>
14
15using std::set;
16using std::size_t;
17
18namespace Mantid::DataObjects {
19
20namespace {
21Kernel::Logger g_log("SpecialWorkspace2D");
22}
23
24// Register the workspace
25DECLARE_WORKSPACE(SpecialWorkspace2D)
26
27//----------------------------------------------------------------------------------------------
33SpecialWorkspace2D::SpecialWorkspace2D(const Geometry::Instrument_const_sptr &inst, const bool includeMonitors) {
34 // Init the Workspace2D with one spectrum per detector, in the same order.
35 this->initialize(inst->getNumberDetectors(!includeMonitors), 1, 1);
36
37 // Copy the instrument
38 this->setInstrument(inst);
39
40 // Initialize the spectra-det-map, 1:1 between spectrum number and det ID
41 this->MatrixWorkspace::rebuildSpectraMapping(includeMonitors);
42
43 // Make the mapping, which will be used for speed later.
44 buildDetectorIDMapping();
45}
46
47//----------------------------------------------------------------------------------------------
53 this->initialize(parent->getNumberHistograms(), 1, 1);
54 API::WorkspaceFactory::Instance().initializeFromParent(*parent, *this, false);
55 // Make the mapping, which will be used for speed later.
57}
58
65SpecialWorkspace2D::SpecialWorkspace2D(const std::vector<detid_t> &detids) {
66 if (detids.empty()) // skip the full initialize method
67 this->init(0, 1, 1);
68 else
69 this->initialize(detids.size(), 1, 1);
70 // set the detector ids
71 for (size_t wi = 0; wi < detids.size(); ++wi) {
72 this->getSpectrum(wi).setDetectorID(detids[wi]);
73 }
74 // set up the rest of the mapping information
77}
78
79//----------------------------------------------------------------------------------------------
86void SpecialWorkspace2D::init(const size_t &NVectors, const size_t &XLength, const size_t &YLength) {
87 if ((XLength != 1) || (YLength != 1))
88 throw std::invalid_argument("SpecialWorkspace2D must have 'spectra' of length 1 only.");
89 // Continue with standard initialization
90 Workspace2D::init(NVectors, XLength, YLength);
91 // This method doesn't have an instrument to set the number of detectors, so set it here
92 this->setNumberOfDetectorGroups(NVectors);
93}
94
95void SpecialWorkspace2D::init(const HistogramData::Histogram &histogram) {
96 if (histogram.xMode() != HistogramData::Histogram::XMode::Points)
97 throw std::runtime_error("SpecialWorkspace2D can only be initialized with XMode::Points");
98 if (histogram.x().size() != 1)
99 throw std::runtime_error("SpecialWorkspace2D can only be initialized with length 1");
101}
102
106const std::string SpecialWorkspace2D::toString() const {
107 std::ostringstream os;
108 os << "Title: " << getTitle() << "\n";
109 os << "Histograms: " << getNumberHistograms() << "\n";
110 return os.str();
111}
112
114 detID_to_WI.clear();
115 for (size_t wi = 0; wi < getNumberHistograms(); wi++) {
116 set<detid_t> dets = this->getDetectorIDs(wi);
117 for (auto det : dets) {
118 detID_to_WI[det] = wi;
119 }
120 }
121}
122
123bool SpecialWorkspace2D::contains(const detid_t detectorID) const {
124 auto it = detID_to_WI.find(detectorID);
125 return it != detID_to_WI.end();
126}
127
128//----------------------------------------------------------------------------------------------
135double SpecialWorkspace2D::getValue(const detid_t detectorID) const {
136 auto it = detID_to_WI.find(detectorID);
137
138 if (it == detID_to_WI.end()) {
139 std::ostringstream os;
140 os << "SpecialWorkspace2D: " << this->getName() << " Detector ID = " << detectorID
141 << " Size(Map) = " << this->detID_to_WI.size() << '\n';
142 throw std::invalid_argument(os.str());
143 } else {
144 return this->dataY(it->second)[0];
145 }
146}
147
148//----------------------------------------------------------------------------------------------
156double SpecialWorkspace2D::getValue(const detid_t detectorID, const double defaultValue) const {
157 auto it = detID_to_WI.find(detectorID);
158 if (it == detID_to_WI.end())
159 return defaultValue;
160 else {
161 if (it->second < getNumberHistograms()) // don't let it generate an exception
162 {
163 return this->dataY(it->second)[0];
164 } else {
165 g_log.debug() << "getValue(" << detectorID << "->" << (it->second) << ", " << defaultValue
166 << ") index out of range\n";
167 return defaultValue;
168 }
169 }
170}
171
172//----------------------------------------------------------------------------------------------
180void SpecialWorkspace2D::setValue(const detid_t detectorID, const double value, const double error) {
181 auto it = detID_to_WI.find(detectorID);
182 if (it == detID_to_WI.end()) {
183 std::stringstream msg;
184 msg << "SpecialWorkspace2D::setValue(): Input Detector ID = " << detectorID << " Is Invalid";
185 throw std::invalid_argument(msg.str());
186 } else {
187 this->dataY(it->second)[0] = value;
188 this->dataE(it->second)[0] = error;
189 }
190}
191
202void SpecialWorkspace2D::setValue(const set<detid_t> &detectorIDs, const double value, const double error) {
203 for (auto detectorID : detectorIDs) {
204 this->setValue(detectorID, value, error);
205 }
206}
207
208//----------------------------------------------------------------------------------------------
215set<detid_t> SpecialWorkspace2D::getDetectorIDs(const std::size_t workspaceIndex) const {
216 if (size_t(workspaceIndex) > this->getNumberHistograms())
217 throw std::invalid_argument("SpecialWorkspace2D::getDetectorIDs(): Invalid workspaceIndex given.");
218 return this->getSpectrum(workspaceIndex).getDetectorIDs();
219}
220
221//--------------------------------------------------------------------------------------------
226void SpecialWorkspace2D::binaryOperation(const std::shared_ptr<const SpecialWorkspace2D> &ws,
227 const unsigned int operatortype) {
228
229 // 1. Check compatibility between this and input workspace
230 if (!this->isCompatible(ws)) {
231 throw std::invalid_argument("Two SpecialWorkspace2D objects are not compatible!");
232 }
233
234 switch (operatortype) {
236 this->binaryAND(ws);
237 break;
239 this->binaryOR(ws);
240 break;
242 this->binaryXOR(ws);
243 break;
244 default:
245 throw std::invalid_argument("Invalid Operator");
246 break;
247 }
248}
249
250//--------------------------------------------------------------------------------------------
255void SpecialWorkspace2D::binaryOperation(const unsigned int operatortype) {
256
257 switch (operatortype) {
259 this->binaryNOT();
260 break;
261 default:
262 g_log.error() << "Operator " << operatortype << " Is Not Valid In BinaryOperation(operatortype)\n";
263 throw std::invalid_argument("Invalid Operator");
264 break;
265 }
266}
267
271void SpecialWorkspace2D::binaryAND(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
272
273 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
274 double y1 = this->dataY(i)[0];
275 double y2 = ws->dataY(i)[0];
276
277 if (y1 < 1.0E-10 || y2 < 1.0E-10) {
278 this->dataY(i)[0] = 0.0;
279 } else {
280 this->dataY(i)[0] += y2;
281 }
282 }
283}
284
288void SpecialWorkspace2D::binaryOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
289
290 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
291 double y1 = this->dataY(i)[0];
292 double y2 = ws->dataY(i)[0];
293
294 double max = y1;
295 if (y2 > y1) {
296 max = y2;
297 }
298 this->dataY(i)[0] = max;
299
300 /*
301if (y1 < 1.0E-10 && y2 < 1.0E-10){
302 this->dataY(i)[0] = 0.0;
303} else {
304 this->dataY(i)[0] += y2;
305}
306*/
307 }
308}
309
313void SpecialWorkspace2D::binaryXOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
314
315 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
316 double y1 = this->dataY(i)[0];
317 double y2 = ws->dataY(i)[0];
318 if (y1 < 1.0E-10 && y2 < 1.0E-10) {
319 this->dataY(i)[0] = 0.0;
320 } else if (y1 > 1.0E-10 && y2 > 1.0E-10) {
321 this->dataY(i)[0] = 0.0;
322 } else {
323 this->dataY(i)[0] = 1.0;
324 }
325 }
326}
327
332
333 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
334 double y1 = this->dataY(i)[0];
335 if (y1 < 1.0E-10) {
336 this->dataY(i)[0] = 1.0;
337 } else {
338 this->dataY(i)[0] = 0.0;
339 }
340 }
341}
342
343//----------------------------------------------------------------------------------------------
344/* Check 2 SpecialWorkspace2D are compatible
345 * @ parameter
346 * @ return
347 */
348bool SpecialWorkspace2D::isCompatible(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
349
350 // 1. Check number of histogram
351 size_t numhist1 = this->getNumberHistograms();
352 size_t numhist2 = ws->getNumberHistograms();
353 if (numhist1 != numhist2) {
354 g_log.debug() << "2 Workspaces have different number of histograms: " << numhist1 << " vs. " << numhist2 << '\n';
355 return false;
356 }
357
358 // 2. Check detector ID
359 for (size_t ispec = 0; ispec < numhist1; ispec++) {
360 set<detid_t> ids1 = this->getSpectrum(ispec).getDetectorIDs();
361 set<detid_t> ids2 = ws->getSpectrum(ispec).getDetectorIDs();
362
363 if (ids1.size() != ids2.size()) {
364 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different number of detectors " << ids1.size()
365 << " vs. " << ids2.size() << '\n';
366 return false;
367 } else if (ids1.empty()) {
368 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces both have 0 detectors. \n";
369 return false;
370 } else if (*ids1.begin() != *ids2.begin()) {
371 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different Detector ID " << *ids1.begin() << " vs. "
372 << *ids2.begin() << '\n';
373 return false;
374 }
375 } // false
376
377 return true;
378}
379
380//----------------------------------------------------------------------------------------------
383void SpecialWorkspace2D::copyFrom(std::shared_ptr<const SpecialWorkspace2D> sourcews) {
384 // Check
385 if (this->getNumberHistograms() != sourcews->getNumberHistograms()) {
386 throw std::invalid_argument("Incompatible number of histograms");
387 }
388
389 // Copy data
390 for (size_t ispec = 0; ispec < this->getNumberHistograms(); ispec++) {
391
392 // 1.1 Check size
393 const MantidVec &inx = sourcews->readX(ispec);
394 const MantidVec &iny = sourcews->readY(ispec);
395 const MantidVec &ine = sourcews->readE(ispec);
396
397 MantidVec &outx = this->dataX(ispec);
398 MantidVec &outy = this->dataY(ispec);
399 MantidVec &oute = this->dataE(ispec);
400
401 if (inx.size() != outx.size() || iny.size() != outy.size() || ine.size() != oute.size()) {
402 throw std::invalid_argument("X, Y, E size different within spectrum");
403 }
404
405 // 1.2 Copy data
406 for (size_t i = 0; i < inx.size(); i++) {
407 outx[i] = inx[i];
408 }
409 for (size_t i = 0; i < iny.size(); i++) {
410 outy[i] = iny[i];
411 oute[i] = ine[i];
412 }
413 }
414
415 // Copy detector map
416 this->detID_to_WI = sourcews->detID_to_WI;
417}
418
419} // namespace Mantid::DataObjects
420
422
423namespace Mantid::Kernel {
424
425template <>
427IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_sptr>(const std::string &name) const {
428 auto *prop =
429 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
430 if (prop) {
431 return *prop;
432 } else {
433 std::string message =
434 "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<SpecialWorkspace2D>.";
435 throw std::runtime_error(message);
436 }
437}
438
439template <>
441IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_const_sptr>(const std::string &name) const {
442 auto const *prop =
443 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
444 if (prop) {
445 return prop->operator()();
446 } else {
447 std::string message =
448 "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<SpecialWorkspace2D>.";
449 throw std::runtime_error(message);
450 }
451}
452
453} // namespace Mantid::Kernel
454
std::string name
Definition Run.cpp:60
double value
The value of the point.
Definition FitMW.cpp:51
double error
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
Definition System.h:33
#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.
void initialize(const std::size_t &NVectors, const std::size_t &XLength, const std::size_t &YLength)
Initialize the workspace.
virtual MantidVec & dataX(const std::size_t index)
Deprecated, use mutableX() instead. Returns the x data.
virtual MantidVec & dataE(const std::size_t index)
Deprecated, use mutableE() instead. Returns the error data.
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)
virtual MantidVec & dataY(const std::size_t index)
Deprecated, use mutableY() instead. Returns the y data.
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:63
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.
std::vector< double > MantidVec
typedef for the data storage used in Mantid matrix workspaces
Definition cow_ptr.h:172