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