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 auto &dets = getSpectrum(wi).getDetectorIDs();
95 for (auto det : dets) {
96 detID_to_WI[det] = wi;
97 }
98 }
99}
100
101//----------------------------------------------------------------------------------------------
108double SpecialWorkspace2D::getValue(const detid_t detectorID) const {
109 auto it = detID_to_WI.find(detectorID);
110
111 if (it == detID_to_WI.end()) {
112 std::ostringstream os;
113 os << "SpecialWorkspace2D: " << this->getName() << " Detector ID = " << detectorID
114 << " Size(Map) = " << this->detID_to_WI.size() << '\n';
115 throw std::invalid_argument(os.str());
116 } else {
117 return this->dataY(it->second)[0];
118 }
119}
120
121//----------------------------------------------------------------------------------------------
129double SpecialWorkspace2D::getValue(const detid_t detectorID, const double defaultValue) const {
130 auto it = detID_to_WI.find(detectorID);
131 if (it == detID_to_WI.end())
132 return defaultValue;
133 else {
134 if (it->second < getNumberHistograms()) // don't let it generate an exception
135 {
136 return this->dataY(it->second)[0];
137 } else {
138 g_log.debug() << "getValue(" << detectorID << "->" << (it->second) << ", " << defaultValue
139 << ") index out of range\n";
140 return defaultValue;
141 }
142 }
143}
144
145//----------------------------------------------------------------------------------------------
153void SpecialWorkspace2D::setValue(const detid_t detectorID, const double value, const double error) {
154 auto it = detID_to_WI.find(detectorID);
155 if (it == detID_to_WI.end()) {
156 std::stringstream msg;
157 msg << "SpecialWorkspace2D::setValue(): Input Detector ID = " << detectorID << " Is Invalid";
158 throw std::invalid_argument(msg.str());
159 } else {
160 this->dataY(it->second)[0] = value;
161 this->dataE(it->second)[0] = error;
162 }
163}
164
175void SpecialWorkspace2D::setValue(const set<detid_t> &detectorIDs, const double value, const double error) {
176 for (auto detectorID : detectorIDs) {
177 this->setValue(detectorID, value, error);
178 }
179}
180
181//----------------------------------------------------------------------------------------------
188set<detid_t> SpecialWorkspace2D::getDetectorIDs(const std::size_t workspaceIndex) const {
189 if (size_t(workspaceIndex) > this->getNumberHistograms())
190 throw std::invalid_argument("SpecialWorkspace2D::getDetectorIDs(): Invalid workspaceIndex given.");
191 return this->getSpectrum(workspaceIndex).getDetectorIDs();
192}
193
194//--------------------------------------------------------------------------------------------
199void SpecialWorkspace2D::binaryOperation(const std::shared_ptr<const SpecialWorkspace2D> &ws,
200 const unsigned int operatortype) {
201
202 // 1. Check compatibility between this and input workspace
203 if (!this->isCompatible(ws)) {
204 throw std::invalid_argument("Two SpecialWorkspace2D objects are not compatible!");
205 }
206
207 switch (operatortype) {
209 this->binaryAND(ws);
210 break;
212 this->binaryOR(ws);
213 break;
215 this->binaryXOR(ws);
216 break;
217 default:
218 throw std::invalid_argument("Invalid Operator");
219 break;
220 }
221}
222
223//--------------------------------------------------------------------------------------------
228void SpecialWorkspace2D::binaryOperation(const unsigned int operatortype) {
229
230 switch (operatortype) {
232 this->binaryNOT();
233 break;
234 default:
235 g_log.error() << "Operator " << operatortype << " Is Not Valid In BinaryOperation(operatortype)\n";
236 throw std::invalid_argument("Invalid Operator");
237 break;
238 }
239}
240
244void SpecialWorkspace2D::binaryAND(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
245
246 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
247 double y1 = this->dataY(i)[0];
248 double y2 = ws->dataY(i)[0];
249
250 if (y1 < 1.0E-10 || y2 < 1.0E-10) {
251 this->dataY(i)[0] = 0.0;
252 } else {
253 this->dataY(i)[0] += y2;
254 }
255 }
256}
257
261void SpecialWorkspace2D::binaryOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
262
263 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
264 double y1 = this->dataY(i)[0];
265 double y2 = ws->dataY(i)[0];
266
267 double max = y1;
268 if (y2 > y1) {
269 max = y2;
270 }
271 this->dataY(i)[0] = max;
272
273 /*
274if (y1 < 1.0E-10 && y2 < 1.0E-10){
275 this->dataY(i)[0] = 0.0;
276} else {
277 this->dataY(i)[0] += y2;
278}
279*/
280 }
281}
282
286void SpecialWorkspace2D::binaryXOR(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
287
288 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
289 double y1 = this->dataY(i)[0];
290 double y2 = ws->dataY(i)[0];
291 if (y1 < 1.0E-10 && y2 < 1.0E-10) {
292 this->dataY(i)[0] = 0.0;
293 } else if (y1 > 1.0E-10 && y2 > 1.0E-10) {
294 this->dataY(i)[0] = 0.0;
295 } else {
296 this->dataY(i)[0] = 1.0;
297 }
298 }
299}
300
305
306 for (size_t i = 0; i < this->getNumberHistograms(); i++) {
307 double y1 = this->dataY(i)[0];
308 if (y1 < 1.0E-10) {
309 this->dataY(i)[0] = 1.0;
310 } else {
311 this->dataY(i)[0] = 0.0;
312 }
313 }
314}
315
316//----------------------------------------------------------------------------------------------
317/* Check 2 SpecialWorkspace2D are compatible
318 * @ parameter
319 * @ return
320 */
321bool SpecialWorkspace2D::isCompatible(const std::shared_ptr<const SpecialWorkspace2D> &ws) {
322
323 // 1. Check number of histogram
324 size_t numhist1 = this->getNumberHistograms();
325 size_t numhist2 = ws->getNumberHistograms();
326 if (numhist1 != numhist2) {
327 g_log.debug() << "2 Workspaces have different number of histograms: " << numhist1 << " vs. " << numhist2 << '\n';
328 return false;
329 }
330
331 // 2. Check detector ID
332 for (size_t ispec = 0; ispec < numhist1; ispec++) {
333 set<detid_t> ids1 = this->getSpectrum(ispec).getDetectorIDs();
334 set<detid_t> ids2 = ws->getSpectrum(ispec).getDetectorIDs();
335
336 if (ids1.size() != ids2.size()) {
337 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different number of detectors " << ids1.size()
338 << " vs. " << ids2.size() << '\n';
339 return false;
340 } else if (ids1.empty()) {
341 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces both have 0 detectors. \n";
342 return false;
343 } else if (*ids1.begin() != *ids2.begin()) {
344 g_log.debug() << "Spectra " << ispec << ": 2 Workspaces have different Detector ID " << *ids1.begin() << " vs. "
345 << *ids2.begin() << '\n';
346 return false;
347 }
348 } // false
349
350 return true;
351}
352
353//----------------------------------------------------------------------------------------------
356void SpecialWorkspace2D::copyFrom(std::shared_ptr<const SpecialWorkspace2D> sourcews) {
357 // Check
358 if (this->getNumberHistograms() != sourcews->getNumberHistograms()) {
359 throw std::invalid_argument("Incompatible number of histograms");
360 }
361
362 // Copy data
363 for (size_t ispec = 0; ispec < this->getNumberHistograms(); ispec++) {
364
365 // 1.1 Check size
366 const MantidVec &inx = sourcews->readX(ispec);
367 const MantidVec &iny = sourcews->readY(ispec);
368 const MantidVec &ine = sourcews->readE(ispec);
369
370 MantidVec &outx = this->dataX(ispec);
371 MantidVec &outy = this->dataY(ispec);
372 MantidVec &oute = this->dataE(ispec);
373
374 if (inx.size() != outx.size() || iny.size() != outy.size() || ine.size() != oute.size()) {
375 throw std::invalid_argument("X, Y, E size different within spectrum");
376 }
377
378 // 1.2 Copy data
379 for (size_t i = 0; i < inx.size(); i++) {
380 outx[i] = inx[i];
381 }
382 for (size_t i = 0; i < iny.size(); i++) {
383 outy[i] = iny[i];
384 oute[i] = ine[i];
385 }
386 }
387
388 // Copy detector map
389 this->detID_to_WI = sourcews->detID_to_WI;
390}
391
392} // namespace Mantid::DataObjects
393
395
396namespace Mantid::Kernel {
397
398template <>
400IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_sptr>(const std::string &name) const {
401 auto *prop =
402 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
403 if (prop) {
404 return *prop;
405 } else {
406 std::string message =
407 "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<SpecialWorkspace2D>.";
408 throw std::runtime_error(message);
409 }
410}
411
412template <>
414IPropertyManager::getValue<Mantid::DataObjects::SpecialWorkspace2D_const_sptr>(const std::string &name) const {
415 auto const *prop =
416 dynamic_cast<PropertyWithValue<Mantid::DataObjects::SpecialWorkspace2D_sptr> *>(getPointerToProperty(name));
417 if (prop) {
418 return prop->operator()();
419 } else {
420 std::string message =
421 "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<SpecialWorkspace2D>.";
422 throw std::runtime_error(message);
423 }
424}
425
426} // namespace Mantid::Kernel
427
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.
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:62
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