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
59//----------------------------------------------------------------------------------------------
66void SpecialWorkspace2D::init(const size_t &NVectors, const size_t &XLength, const size_t &YLength) {
67 if ((XLength != 1) || (YLength != 1))
68 throw std::invalid_argument("SpecialWorkspace2D must have 'spectra' of length 1 only.");
69 // Continue with standard initialization
70 Workspace2D::init(NVectors, XLength, YLength);
71}
72
73void SpecialWorkspace2D::init(const HistogramData::Histogram &histogram) {
74 if (histogram.xMode() != HistogramData::Histogram::XMode::Points)
75 throw std::runtime_error("SpecialWorkspace2D can only be initialized with XMode::Points");
76 if (histogram.x().size() != 1)
77 throw std::runtime_error("SpecialWorkspace2D can only be initialized with length 1");
79}
80
84const std::string SpecialWorkspace2D::toString() const {
85 std::ostringstream os;
86 os << "Title: " << getTitle() << "\n";
87 os << "Histograms: " << getNumberHistograms() << "\n";
88 return os.str();
89}
90
92 detID_to_WI.clear();
93 for (size_t wi = 0; wi < getNumberHistograms(); wi++) {
94 set<detid_t> dets = this->getDetectorIDs(wi);
95 for (auto det : dets) {
96 detID_to_WI[det] = wi;
97 }
98 }
99}
100
101bool SpecialWorkspace2D::contains(const detid_t detectorID) const {
102 auto it = detID_to_WI.find(detectorID);
103 return it != detID_to_WI.end();
104}
105
106//----------------------------------------------------------------------------------------------
113double SpecialWorkspace2D::getValue(const detid_t detectorID) const {
114 auto it = detID_to_WI.find(detectorID);
115
116 if (it == detID_to_WI.end()) {
117 std::ostringstream os;
118 os << "SpecialWorkspace2D: " << this->getName() << " Detector ID = " << detectorID
119 << " Size(Map) = " << this->detID_to_WI.size() << '\n';
120 throw std::invalid_argument(os.str());
121 } else {
122 return this->dataY(it->second)[0];
123 }
124}
125
126//----------------------------------------------------------------------------------------------
134double SpecialWorkspace2D::getValue(const detid_t detectorID, const double defaultValue) const {
135 auto it = detID_to_WI.find(detectorID);
136 if (it == detID_to_WI.end())
137 return defaultValue;
138 else {
139 if (it->second < getNumberHistograms()) // don't let it generate an exception
140 {
141 return this->dataY(it->second)[0];
142 } else {
143 g_log.debug() << "getValue(" << detectorID << "->" << (it->second) << ", " << defaultValue
144 << ") index out of range\n";
145 return defaultValue;
146 }
147 }
148}
149
150//----------------------------------------------------------------------------------------------
158void SpecialWorkspace2D::setValue(const detid_t detectorID, const double value, const double error) {
159 auto it = detID_to_WI.find(detectorID);
160 if (it == detID_to_WI.end()) {
161 std::stringstream msg;
162 msg << "SpecialWorkspace2D::setValue(): Input Detector ID = " << detectorID << " Is Invalid";
163 throw std::invalid_argument(msg.str());
164 } else {
165 this->dataY(it->second)[0] = value;
166 this->dataE(it->second)[0] = error;
167 }
168}
169
180void SpecialWorkspace2D::setValue(const set<detid_t> &detectorIDs, const double value, const double error) {
181 for (auto detectorID : detectorIDs) {
182 this->setValue(detectorID, value, error);
183 }
184}
185
186//----------------------------------------------------------------------------------------------
193set<detid_t> SpecialWorkspace2D::getDetectorIDs(const std::size_t workspaceIndex) const {
194 if (size_t(workspaceIndex) > this->getNumberHistograms())
195 throw std::invalid_argument("SpecialWorkspace2D::getDetectorIDs(): Invalid workspaceIndex given.");
196 return this->getSpectrum(workspaceIndex).getDetectorIDs();
197}
198
199//--------------------------------------------------------------------------------------------
204void SpecialWorkspace2D::binaryOperation(const std::shared_ptr<const SpecialWorkspace2D> &ws,
205 const unsigned int operatortype) {
206
207 // 1. Check compatibility between this and input workspace
208 if (!this->isCompatible(ws)) {
209 throw std::invalid_argument("Two SpecialWorkspace2D objects are not compatible!");
210 }
211
212 switch (operatortype) {
214 this->binaryAND(ws);
215 break;
217 this->binaryOR(ws);
218 break;
220 this->binaryXOR(ws);
221 break;
222 default:
223 throw std::invalid_argument("Invalid Operator");
224 break;
225 }
226}
227
228//--------------------------------------------------------------------------------------------
233void SpecialWorkspace2D::binaryOperation(const unsigned int operatortype) {
234
235 switch (operatortype) {
237 this->binaryNOT();
238 break;
239 default:
240 g_log.error() << "Operator " << operatortype << " Is Not Valid In BinaryOperation(operatortype)\n";
241 throw std::invalid_argument("Invalid Operator");
242 break;
243 }
244}
245
249void SpecialWorkspace2D::binaryAND(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
250
251 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
252 double y1 = this->dataY(i)[0];
253 double y2 = ws->dataY(i)[0];
254
255 if (y1 < 1.0E-10 || y2 < 1.0E-10) {
256 this->dataY(i)[0] = 0.0;
257 } else {
258 this->dataY(i)[0] += y2;
259 }
260 }
261}
262
266void SpecialWorkspace2D::binaryOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
267
268 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
269 double y1 = this->dataY(i)[0];
270 double y2 = ws->dataY(i)[0];
271
272 double max = y1;
273 if (y2 > y1) {
274 max = y2;
275 }
276 this->dataY(i)[0] = max;
277
278 /*
279if (y1 < 1.0E-10 && y2 < 1.0E-10){
280 this->dataY(i)[0] = 0.0;
281} else {
282 this->dataY(i)[0] += y2;
283}
284*/
285 }
286}
287
291void SpecialWorkspace2D::binaryXOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
292
293 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
294 double y1 = this->dataY(i)[0];
295 double y2 = ws->dataY(i)[0];
296 if (y1 < 1.0E-10 && y2 < 1.0E-10) {
297 this->dataY(i)[0] = 0.0;
298 } else if (y1 > 1.0E-10 && y2 > 1.0E-10) {
299 this->dataY(i)[0] = 0.0;
300 } else {
301 this->dataY(i)[0] = 1.0;
302 }
303 }
304}
305
310
311 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
312 double y1 = this->dataY(i)[0];
313 if (y1 < 1.0E-10) {
314 this->dataY(i)[0] = 1.0;
315 } else {
316 this->dataY(i)[0] = 0.0;
317 }
318 }
319}
320
321//----------------------------------------------------------------------------------------------
322/* Check 2 SpecialWorkspace2D are compatible
323 * @ parameter
324 * @ return
325 */
326bool SpecialWorkspace2D::isCompatible(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
327
328 // 1. Check number of histogram
329 size_t numhist1 = this->getNumberHistograms();
330 size_t numhist2 = ws->getNumberHistograms();
331 if (numhist1 != numhist2) {
332 g_log.debug() << "2 Workspaces have different number of histograms: " << numhist1 << " vs. " << numhist2 << '\n';
333 return false;
334 }
335
336 // 2. Check detector ID
337 for (size_t ispec = 0; ispec < numhist1; ispec++) {
338 set<detid_t> ids1 = this->getSpectrum(ispec).getDetectorIDs();
339 set<detid_t> ids2 = ws->getSpectrum(ispec).getDetectorIDs();
340
341 if (ids1.size() != ids2.size()) {
342 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different number of detectors " << ids1.size()
343 << " vs. " << ids2.size() << '\n';
344 return false;
345 } else if (ids1.empty()) {
346 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces both have 0 detectors. \n";
347 return false;
348 } else if (*ids1.begin() != *ids2.begin()) {
349 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different Detector ID " << *ids1.begin() << " vs. "
350 << *ids2.begin() << '\n';
351 return false;
352 }
353 } // false
354
355 return true;
356}
357
358//----------------------------------------------------------------------------------------------
361void SpecialWorkspace2D::copyFrom(std::shared_ptr<const SpecialWorkspace2D> sourcews) {
362 // Check
363 if (this->getNumberHistograms() != sourcews->getNumberHistograms()) {
364 throw std::invalid_argument("Incompatible number of histograms");
365 }
366
367 // Copy data
368 for (size_t ispec = 0; ispec < this->getNumberHistograms(); ispec++) {
369
370 // 1.1 Check size
371 const MantidVec &inx = sourcews->readX(ispec);
372 const MantidVec &iny = sourcews->readY(ispec);
373 const MantidVec &ine = sourcews->readE(ispec);
374
375 MantidVec &outx = this->dataX(ispec);
376 MantidVec &outy = this->dataY(ispec);
377 MantidVec &oute = this->dataE(ispec);
378
379 if (inx.size() != outx.size() || iny.size() != outy.size() || ine.size() != oute.size()) {
380 throw std::invalid_argument("X, Y, E size different within spectrum");
381 }
382
383 // 1.2 Copy data
384 for (size_t i = 0; i < inx.size(); i++) {
385 outx[i] = inx[i];
386 }
387 for (size_t i = 0; i < iny.size(); i++) {
388 outy[i] = iny[i];
389 oute[i] = ine[i];
390 }
391 }
392
393 // Copy detector map
394 this->detID_to_WI = sourcews->detID_to_WI;
395}
396
397} // namespace Mantid::DataObjects
398
400
401namespace Mantid::Kernel {
402
403template <>
405IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_sptr>(const std::string &name) const {
406 auto *prop =
407 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
408 if (prop) {
409 return *prop;
410 } else {
411 std::string message =
412 "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<SpecialWorkspace2D>.";
413 throw std::runtime_error(message);
414 }
415}
416
417template <>
419IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_const_sptr>(const std::string &name) const {
420 auto const *prop =
421 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
422 if (prop) {
423 return prop->operator()();
424 } else {
425 std::string message =
426 "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<SpecialWorkspace2D>.";
427 throw std::runtime_error(message);
428 }
429}
430
431} // namespace Mantid::Kernel
432
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:37
#define DECLARE_WORKSPACE(classname)
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