Mantid
Loading...
Searching...
No Matches
LoadMask.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 +
22
24
25#include <algorithm>
26#include <fstream>
27#include <map>
28#include <sstream>
29
30#include <Poco/DOM/DOMParser.h>
31#include <Poco/DOM/Element.h>
32#include <Poco/DOM/NodeFilter.h>
33#include <Poco/DOM/NodeIterator.h>
34#include <Poco/DOM/NodeList.h>
35#include <Poco/Exception.h>
36
37#include <boost/algorithm/string.hpp>
38
39using Poco::XML::DOMParser;
40using Poco::XML::Node;
41using Poco::XML::NodeFilter;
42using Poco::XML::NodeIterator;
43using Poco::XML::NodeList;
44
45using namespace Mantid::Kernel;
46using namespace Mantid::API;
47using namespace std;
48
49namespace {
50// service routines
51//-------------------------------------------------------------------------------------------
63template <typename T>
64void convertToVector(const std::vector<T> &singles, const std::vector<T> &ranges, std::vector<T> &tot_singles) {
65
66 // find the size of the final vector of masked values
67 size_t n_total(singles.size() + tot_singles.size());
68 for (size_t i = 0; i < ranges.size(); i += 2) {
69 n_total += ranges[i + 1] - ranges[i] + 1;
70 }
71 // reserve space for all masked spectra
72 // for efficient memory operations
73 tot_singles.reserve(n_total);
74 // add singles to the existing singles
75 tot_singles.insert(tot_singles.end(), singles.begin(), singles.end());
76 // expand pairs
77 for (size_t i = 0; i < ranges.size(); i += 2) {
78 for (T obj_id = ranges[i]; obj_id < ranges[i + 1] + 1; ++obj_id) {
79 tot_singles.emplace_back(obj_id);
80 }
81 }
82}
83
92template <typename T> void parseRangeText(const std::string &inputstr, std::vector<T> &singles, std::vector<T> &pairs) {
93 // 1. Split ','
94 std::vector<std::string> rawstrings;
95 boost::split(rawstrings, inputstr, boost::is_any_of(","), boost::token_compress_on);
96
97 for (auto &rawstring : rawstrings) {
98 // a) Find '-':
99 boost::trim(rawstring);
100 bool containDash(true);
101 if (rawstring.find_first_of('-') == std::string::npos) {
102 containDash = false;
103 }
104
105 // Process appropriately
106 if (containDash) { // 4. Treat pairs
107 std::vector<std::string> ptemp;
108 boost::split(ptemp, rawstring, boost::is_any_of("-"), boost::token_compress_on);
109 if (ptemp.size() != 2) {
110 std::string error = "Range string " + rawstring + " has a wrong format!";
111 throw std::invalid_argument(error);
112 }
113 // b) parse
114 auto intstart = boost::lexical_cast<T>(ptemp[0]);
115 auto intend = boost::lexical_cast<T>(ptemp[1]);
116 if (intstart >= intend) {
117 std::string error = "Range string " + rawstring + " has wrong order of detectors ID!";
118 throw std::invalid_argument(error);
119 }
120 pairs.emplace_back(intstart);
121 pairs.emplace_back(intend);
122
123 } else { // 3. Treat singles
124 auto itemp = boost::lexical_cast<T>(rawstring);
125 singles.emplace_back(itemp);
126 }
127 } // ENDFOR i
128}
129
130/*
131 * Parse a line in an ISIS mask file string to vector
132 * Combination of 5 types of format for unit
133 * (1) a (2) a-b (3) a - b (4) a- b (5) a -b
134 * separated by space(s)
135 * @param ins -- input string in ISIS ASCII format
136 * @return ranges -- vector of a,b pairs converted from input
137 */
138void parseISISStringToVector(const std::string &ins, std::vector<Mantid::specnum_t> &ranges) {
139 // 1. Split by space
140 std::vector<string> splitstrings;
141 boost::split(splitstrings, ins, boost::is_any_of(" "), boost::token_compress_on);
142
143 // 2. Replace a-b to a - b, remove a-b and insert a, -, b
144 bool tocontinue = true;
145 size_t index = 0;
146 while (tocontinue) {
147 // a) Determine end of loop. Note that loop size changes
148 if (index == splitstrings.size() - 1) {
149 tocontinue = false;
150 }
151
152 // b) Need to split?
153 vector<string> temps;
154 boost::split(temps, splitstrings[index], boost::is_any_of("-"), boost::token_compress_on);
155 if (splitstrings[index] == "-" || temps.size() == 1) {
156 // Nothing to split
157 index++;
158 } else if (temps.size() == 2) {
159 // Has a '-' inside. Delete and Replace
160 temps.insert(temps.begin() + 1, "-");
161 splitstrings.erase(splitstrings.begin() + index);
162 for (size_t ic = 0; ic < 3; ic++) {
163 if (!temps[ic].empty()) {
164 splitstrings.insert(splitstrings.begin() + index, temps[ic]);
165 index++;
166 }
167 }
168 } else {
169 // Exception
170 std::string err = "String " + splitstrings[index] + " has too many '-'";
171 throw std::invalid_argument(err);
172 }
173
174 if (index >= splitstrings.size())
175 tocontinue = false;
176
177 } // END WHILE
178
179 // 3. Put to output integer vector
180 tocontinue = true;
181 index = 0;
182 while (tocontinue) {
183 // i) push to the starting vector
184 ranges.emplace_back(boost::lexical_cast<Mantid::specnum_t>(splitstrings[index]));
185
186 // ii) push the ending vector
187 if (index == splitstrings.size() - 1 || splitstrings[index + 1] != "-") {
188 // the next one is not '-'
189 ranges.emplace_back(boost::lexical_cast<Mantid::specnum_t>(splitstrings[index]));
190 index++;
191 } else {
192 // the next one is '-', thus read '-', next
193 ranges.emplace_back(boost::lexical_cast<Mantid::specnum_t>(splitstrings[index + 2]));
194 index += 3;
195 }
196
197 if (index >= splitstrings.size())
198 tocontinue = false;
199 } // END-WHILE
200}
201/*
202* Load and parse an ISIS masking file
203@param isisfilename :: the string containing full path to an ISIS mask file
204@param SpectraMasks :: output list of the spectra numbers to mask.
205*/
206void loadISISMaskFile(const std::string &isisfilename, std::vector<Mantid::specnum_t> &spectraMasks) {
207
208 std::vector<Mantid::specnum_t> ranges;
209
210 std::ifstream ifs;
211 ifs.open(isisfilename, std::ios::in);
212 if (!ifs.is_open()) {
213 throw std::invalid_argument("Cannot open ISIS mask file" + isisfilename);
214 }
215
216 std::string isisline;
217 while (getline(ifs, isisline)) {
218 boost::trim(isisline);
219
220 // a. skip empty line
221 if (isisline.empty())
222 continue;
223
224 // b. skip comment line
225 if (isisline.c_str()[0] < '0' || isisline.c_str()[0] > '9')
226 continue;
227
228 // c. parse
229 parseISISStringToVector(isisline, ranges);
230 }
231
232 // dummy helper vector as ISIS mask is always processed as pairs.
233 std::vector<Mantid::specnum_t> dummy;
234 convertToVector(dummy, ranges, spectraMasks);
235}
236
237} // namespace
238
239namespace Mantid::DataHandling {
240
242
243
244void LoadMask::init() {
245
246 // 1. Declare property
247 declareProperty("Instrument", "", std::make_shared<MandatoryValidator<std::string>>(),
248 "The name of the instrument to apply the mask.");
249
250 declareProperty(std::make_unique<FileProperty>("InputFile", "", FileProperty::Load, validExtensions()),
251 "Masking file for masking. Supported file format is XML and "
252 "ISIS ASCII. ");
253 declareProperty(std::make_unique<WorkspaceProperty<API::MatrixWorkspace>>("RefWorkspace", "", Direction::Input,
255 "The name of the workspace wich defines instrument and spectra, "
256 "used as the source of the spectra-detector map for the mask to load. "
257 "The instrument, attached to this workspace has to be the same as the "
258 "one specified by 'Instrument' property");
259
260 declareProperty(
261 std::make_unique<WorkspaceProperty<DataObjects::MaskWorkspace>>("OutputWorkspace", "Masking", Direction::Output),
262 "Output Masking Workspace");
263}
264
265//----------------------------------------------------------------------------------------------
269 reset();
270
271 // 1. Load Instrument and create output Mask workspace
272 const std::string instrumentname = getProperty("Instrument");
273 m_sourceMapWS = getProperty("RefWorkspace");
274
275 m_instrumentPropValue = instrumentname;
276 setProperty("Instrument", instrumentname);
277
279
280 if (m_sourceMapWS) { // check if the instruments are compatible
281 auto t_inst_name = m_maskWS->getInstrument()->getName();
282 auto r_inst_name = m_sourceMapWS->getInstrument()->getName();
283 if (t_inst_name != r_inst_name) {
284 throw std::invalid_argument("If reference workspace is provided, it has "
285 "to have instrument with the same name as "
286 "specified by 'Instrument' property");
287 }
288 }
289
290 setProperty("OutputWorkspace", m_maskWS);
291
292 m_defaultToUse = true;
293
294 // 2. Parse Mask File
295 std::string filename = getProperty("InputFile");
296 if (filename.ends_with("l") || filename.ends_with("L")) {
297 // 2.1 XML File
298 this->initializeXMLParser(filename);
299 this->parseXML();
300 } else if (filename.ends_with("k") || filename.ends_with("K")) {
301 // 2.2 ISIS Masking file
302 loadISISMaskFile(filename, m_maskSpecID);
303 m_defaultToUse = true;
304 } else {
305 // we have already validated, so this should not occur
306 throw std::runtime_error("Error reading mask from file " + filename +
307 ". Supported formats are XML and ISIS mask files. No mask was loaded.");
308 }
309
310 // 3. Translate and set geometry
311 g_log.information() << "To Mask: \n";
312
314
315 // unmasking is not implemented
316 // g_log.information() << "To UnMask: \n";
317
318 // As m_uMaskCompIdSingle is empty, this never works
320
321 // convert spectra ID to corresponded det-id-s
323
324 // 4. Apply
325 this->initDetectors();
326 const detid2index_map indexmap = m_maskWS->getDetectorIDToWorkspaceIndexMap(true);
327
328 this->processMaskOnDetectors(indexmap, true, m_maskDetID);
329 // TODO: Not implemented, but should work as soon as m_unMask contains
330 // something
331 this->processMaskOnDetectors(indexmap, false, m_unMaskDetID);
332}
333
335
336 if (!m_defaultToUse) { // Default is to use all detectors
337 size_t numHist = m_maskWS->getNumberHistograms();
338 for (size_t wkspIndex = 0; wkspIndex < numHist; wkspIndex++) {
339 m_maskWS->setMaskedIndex(wkspIndex);
340 }
341 }
342}
343
344//----------------------------------------------------------------------------------------------
351void LoadMask::processMaskOnDetectors(const detid2index_map &indexmap, bool tomask,
352 const std::vector<detid_t> &singledetids) {
353 // 1. Get index map
354 // 2. Mask
355 g_log.debug() << "Mask = " << tomask << " Final Single IDs Size = " << singledetids.size() << '\n';
356
357 for (auto detid : singledetids) {
358 detid2index_map::const_iterator it;
359 it = indexmap.find(detid);
360 if (it != indexmap.end()) {
361 size_t index = it->second;
362 m_maskWS->mutableY(index)[0] = (tomask) ? 1 : 0;
363 } else {
364 g_log.warning() << "Pixel w/ ID = " << detid << " Cannot Be Located\n";
365 }
366 }
367}
368
369//----------------------------------------------------------------------------------------------
377void LoadMask::componentToDetectors(const std::vector<std::string> &componentnames, std::vector<detid_t> &detectors) {
378 const auto &componentInfo = m_maskWS->componentInfo();
379 const auto &detectorInfo = m_maskWS->detectorInfo();
380
381 for (auto &componentname : componentnames) {
382 g_log.debug() << "Component name = " << componentname << '\n';
383
384 // a) get component index
385 size_t componentIndex;
386 try {
387 componentIndex = componentInfo.indexOfAny(componentname);
388 g_log.debug() << "Component ID = " << componentInfo.componentID(componentIndex) << '\n';
389 } catch (const std::exception &) {
390 // A non-exiting component. Ignore
391 g_log.warning() << "Component " << componentname << " does not exist!\n";
392 continue;
393 }
394
395 // b) get all detectors in the subtree of this component
396 const auto detectorIndices = componentInfo.detectorsInSubtree(componentIndex);
397
398 g_log.debug() << "Number of Children = " << detectorIndices.size() << '\n';
399
400 size_t numdets(0);
401 detid_t id_min(std::numeric_limits<Mantid::detid_t>::max());
402 detid_t id_max(0);
403
404 for (const auto &detIndex : detectorIndices) {
405 detid_t detid = detectorInfo.detectorIDs()[detIndex];
406 detectors.emplace_back(detid);
407 numdets++;
408 if (detid < id_min)
409 id_min = detid;
410 if (detid > id_max)
411 id_max = detid;
412 }
413
414 g_log.debug() << "Number of Detectors in Children = " << numdets << " Range = " << id_min << ", " << id_max
415 << '\n';
416 } // for component
417}
418
419//----------------------------------------------------------------------------------------------
425void LoadMask::bankToDetectors(const std::vector<std::string> &singlebanks, std::vector<detid_t> &detectors) {
426 std::stringstream infoss;
427 infoss << "Bank IDs to be converted to detectors: \n";
428 for (const auto &singlebank : singlebanks) {
429 infoss << "Bank: " << singlebank << '\n';
430 }
431 g_log.debug(infoss.str());
432
433 Geometry::Instrument_const_sptr instrument = m_maskWS->getInstrument();
434
435 for (auto &singlebank : singlebanks) {
436 std::vector<Geometry::IDetector_const_sptr> idetectors;
437
438 instrument->getDetectorsInBank(idetectors, singlebank);
439 g_log.debug() << "Bank: " << singlebank << " has " << idetectors.size() << " detectors\n";
440
441 // a) get information
442 size_t numdets = idetectors.size();
443 detid_t detid_first = idetectors.front()->getID();
444 detid_t detid_last = idetectors.back()->getID();
445
446 // b) set detectors
447
448 for (const auto &det : idetectors) {
449 detid_t detid = det->getID();
450 detectors.emplace_back(detid);
451 }
452 g_log.debug() << "Number of Detectors in Bank " << singlebank << " is: " << numdets
453 << "\nRange From: " << detid_first << " To: " << detid_last << '\n';
454
455 } // ENDFOR
456}
457
458//----------------------------------------------------------------------------------------------
466void LoadMask::processMaskOnWorkspaceIndex(bool mask, std::vector<int32_t> &maskedSpecID,
467 std::vector<int32_t> &singleDetIds) {
468 // 1. Check
469 if (maskedSpecID.empty())
470 return;
471
472 if (m_sourceMapWS) {
473 // convert spectra masks into det-id mask using source workspace
474 convertSpMasksToDetIDs(*m_sourceMapWS, maskedSpecID, singleDetIds);
475 maskedSpecID.clear(); // spectra ID not needed any more as all converted to det-ids
476 return;
477 }
478 // 2. Get Map
479 const spec2index_map s2imap = m_maskWS->getSpectrumToWorkspaceIndexMap();
480
481 spec2index_map::const_iterator s2iter;
482
483 // 3. Set mask
484 auto spec0 = maskedSpecID[0];
485 auto prev_masks = spec0;
486 for (int spec2mask : maskedSpecID) {
487
488 s2iter = s2imap.find(spec2mask);
489 if (s2iter == s2imap.end()) {
490 // spectrum not found. bad branch
491 g_log.error() << "Spectrum " << spec2mask << " does not have an entry in GroupWorkspace's spec2index map\n";
492 throw std::runtime_error("Logic error");
493 } else {
494 size_t wsindex = s2iter->second;
495 if (wsindex >= m_maskWS->getNumberHistograms()) {
496 // workspace index is out of range. bad branch
497 g_log.error() << "Group workspace's spec2index map is set wrong: "
498 << " Found workspace index = " << wsindex << " for spectrum No " << spec2mask
499 << " with workspace size = " << m_maskWS->getNumberHistograms() << '\n';
500 } else {
501 // Finally set the masking;
502 m_maskWS->mutableY(wsindex)[0] = (mask) ? 1.0 : 0.0;
503 } // IF-ELSE: ws index out of range
504 } // IF-ELSE: spectrum No has an entry
505
506 if (spec2mask > prev_masks + 1) {
507 g_log.debug() << "Masked Spectrum " << spec0 << " To " << prev_masks << '\n';
508 spec0 = spec2mask;
509 }
510 } // FOR EACH SpecNo
511}
512
513//----------------------------------------------------------------------------------------------
517void LoadMask::initializeXMLParser(const std::string &filename) {
518 // const std::string instName
519 g_log.information() << "Load File " << filename << '\n';
520 const std::string xmlText = Kernel::Strings::loadFile(filename);
521 g_log.information("Successfully Load XML File");
522
523 // Set up the DOM parser and parse xml file
524 DOMParser pParser;
525 try {
526 m_pDoc = pParser.parseString(xmlText);
527 } catch (Poco::Exception &exc) {
528 throw Kernel::Exception::FileError(exc.displayText() + ". Unable to parse File:", filename);
529 } catch (...) {
530 throw Kernel::Exception::FileError("Unable to parse File:", filename);
531 }
532 // Get pointer to root element
533 m_pRootElem = m_pDoc->documentElement();
534 if (!m_pRootElem->hasChildNodes()) {
535 g_log.error("XML file: " + filename + "contains no root element.");
536 throw Kernel::Exception::InstrumentDefinitionError("No root element in XML instrument file", filename);
537 }
538}
539
540//----------------------------------------------------------------------------------------------
563 // 0. Check
564 if (!m_pDoc)
565 throw std::runtime_error("Call LoadMask::initialize() before parseXML.");
566
567 // 1. Parse and create a structure
568 Poco::AutoPtr<NodeList> pNL_type = m_pRootElem->getElementsByTagName("type");
569 g_log.information() << "Node Size = " << pNL_type->length() << '\n';
570
571 Poco::AutoPtr<NodeList> masking_nodes = m_pDoc->getElementsByTagName("detector-masking");
572 if (masking_nodes->length() == 0 && m_pRootElem->nodeName() != "detector-masking") {
573 throw std::runtime_error("No node with name 'detector-masking' is found in the mask file. Wrong format.");
574 }
575
576 Poco::XML::NodeIterator it(m_pDoc, Poco::XML::NodeFilter::SHOW_ELEMENT);
577 Poco::XML::Node *pNode = it.nextNode();
578
579 std::vector<specnum_t> singleSp, pairSp;
580 std::vector<detid_t> maskSingleDet, maskPairDet;
581
582 bool ingroup = false;
583 while (pNode) {
584 const Poco::XML::XMLString value = pNode->innerText();
585
586 if (pNode->nodeName() == "group") {
587 // Node "group"
588 ingroup = true;
589
590 } else if (pNode->nodeName() == "component") {
591 // Node "component"
592 if (ingroup) {
593 m_maskCompIdSingle.emplace_back(value);
594 } else {
595 g_log.error() << "XML File hierarchical (component) error!\n";
596 }
597
598 } else if (pNode->nodeName() == "ids") {
599 // Node "ids"
600 if (ingroup) {
601 parseRangeText(value, singleSp, pairSp);
602 } else {
603 g_log.error() << "XML File (ids) hierarchical error!"
604 << " Inner Text = " << pNode->innerText() << '\n';
605 }
606
607 } else if (pNode->nodeName() == "detids") {
608 // Node "detids"
609 if (ingroup) {
610 parseRangeText(value, maskSingleDet, maskPairDet);
611 } else {
612 g_log.error() << "XML File (detids) hierarchical error!\n";
613 }
614
615 } else if (pNode->nodeName() == "detector-masking") {
616 // Node "detector-masking". Check default value
617 m_defaultToUse = true;
618 } // END-IF-ELSE: pNode->nodeName()
619
620 pNode = it.nextNode();
621 } // ENDWHILE
622
623 convertToVector(singleSp, pairSp, m_maskSpecID);
624 convertToVector(maskSingleDet, maskPairDet, m_maskDetID);
625 // NOTE: -- TODO: NOT IMPLEMENTD -- if unmasking is implemented, should be
626 // enabled
627 // convertToVector(umaskSingleDet, umaskPairDet, m_unMaskDetID);
628}
629
630/* Convert spectra mask into det-id mask using workspace as source of
631 *spectra-detector maps
632 *
633 * @param sourceWS -- the workspace containing source spectra-detector map
634 * to use on masks
635 * @param maskedSpecID -- vector of spectra id to mask
636 * @param singleDetIds -- output vector of detector ids to mask
637 */
638void LoadMask::convertSpMasksToDetIDs(const API::MatrixWorkspace &sourceWS, const std::vector<int32_t> &maskedSpecID,
639 std::vector<int32_t> &singleDetIds) {
640
642 detid2index_map sourceDetMap = sourceWS.getDetectorIDToWorkspaceIndexMap(false);
643
644 std::multimap<size_t, Mantid::detid_t> spectr2index_map;
645 for (auto &it : sourceDetMap) {
646 spectr2index_map.insert(std::pair<size_t, Mantid::detid_t>(it.second, it.first));
647 }
648 for (int i : maskedSpecID) {
649 // find spectra number from spectra ID for the source workspace
650 const auto itSpec = s2imap.find(i);
651 if (itSpec == s2imap.end()) {
652 throw std::runtime_error("Can not find spectra with ID: " + boost::lexical_cast<std::string>(i) +
653 " in the workspace" + sourceWS.getName());
654 }
655 size_t specN = itSpec->second;
656
657 // find detector range related to this spectra id in the source workspace
658 const auto source_range = spectr2index_map.equal_range(specN);
659 if (source_range.first == spectr2index_map.end()) {
660 throw std::runtime_error("Can not find spectra N: " + boost::lexical_cast<std::string>(specN) +
661 " in the workspace" + sourceWS.getName());
662 }
663 // add detectors to the masked det-id list
664 for (auto it = source_range.first; it != source_range.second; ++it) {
665 singleDetIds.emplace_back(it->second);
666 }
667 }
668}
669
670//----------------------------------------------------------------------------------------------
674
675 if (m_sourceMapWS) {
677 } else {
679 const bool ignoreDirs(true);
680 const auto idfPath = API::FileFinder::Instance().getFullPath(m_instrumentPropValue, ignoreDirs);
681
682 auto loadInst = createChildAlgorithm("LoadInstrument");
683 loadInst->setProperty<MatrixWorkspace_sptr>("Workspace", tempWs);
684
685 if (idfPath.empty())
686 loadInst->setPropertyValue("InstrumentName", m_instrumentPropValue);
687 else
688 loadInst->setPropertyValue("Filename", m_instrumentPropValue);
689
690 loadInst->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(false));
691 loadInst->executeAsChildAlg();
692
693 if (!loadInst->isExecuted()) {
694 g_log.error() << "Unable to load Instrument " << m_instrumentPropValue << '\n';
695 throw std::invalid_argument("Incorrect instrument name or invalid IDF given.");
696 }
697
699 }
700 m_maskWS->setTitle("Mask");
701}
702
707std::map<std::string, std::string> LoadMask::validateInputs() {
708
709 std::map<std::string, std::string> result;
710
711 // check the extensions of the file
712 // NOTE the validator on the file property does not error if not correct
713 std::string filename = getProperty("InputFile");
714 std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower);
715 auto exts = validExtensions();
716 if (std::none_of(exts.cbegin(), exts.cend(),
717 [&filename](std::string const &ext) { return filename.ends_with(ext); })) {
718 result["InputFile"] =
719 "File " + filename + " is not in supported format. Supported formats are XML and ISIS mask files.";
720 }
721
722 API::MatrixWorkspace_sptr inputWS = getProperty("RefWorkspace");
723 std::string InstrName = getProperty("Instrument");
724 if (inputWS) {
725 boost::trim(InstrName);
726 boost::algorithm::to_lower(InstrName);
727 size_t len = InstrName.size();
730 bool IDF_provided{false};
731 // Check if the name ends up with .xml which means that idf file name
732 // is provided rather then an instrument name.
733 if (len > 4) {
734 if (InstrName.compare(len - 4, len, ".xml") == 0) {
735 IDF_provided = true;
736 } else {
737 IDF_provided = false;
738 }
739 } else {
740 IDF_provided = false;
741 }
742 try {
743 auto inst = inputWS->getInstrument();
744 std::string Name = inst->getName();
745 boost::algorithm::to_lower(Name);
746 if (Name != InstrName && !IDF_provided) {
747 result["RefWorkspace"] = "If both reference workspace and instrument name are defined, "
748 "workspace has to have the instrument with the same name\n"
749 "'Instrument' value: " +
750 InstrName + " Workspace Instrument name: " + Name;
751 }
753 result["RefWorkspace"] = "If reference workspace is defined, it mast have an instrument";
754 }
755 }
756
757 return result;
758}
759
761 // LoadMask instance may be reused, need to clear buffers.
762 m_maskDetID.clear();
763 m_unMaskDetID.clear();
764 m_maskSpecID.clear();
765 m_maskCompIdSingle.clear();
766 m_uMaskCompIdSingle.clear();
767}
768
769} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double value
The value of the point.
Definition FitMW.cpp:51
double error
std::map< DeltaEMode::Type, std::string > index
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1)
Create a Child Algorithm.
Kernel::Logger & g_log
Definition Algorithm.h:422
@ Load
allowed here which will be passed to the algorithm
Base MatrixWorkspace Abstract Class.
detid2index_map getDetectorIDToWorkspaceIndexMap(bool throwIfMultipleDets=false, bool ignoreIfNoValidDets=false) const
Return a map where: KEY is the DetectorID (pixel ID) VALUE is the Workspace Index.
spec2index_map getSpectrumToWorkspaceIndexMap() const
Return a map where: KEY is the Spectrum # VALUE is the Workspace Index.
A property class for workspaces.
const std::string & getName() const override
Get the workspace name.
Definition Workspace.cpp:59
LoadMask : Load masking file to generate a SpecialWorkspace2D object (masking workspace).
Definition LoadMask.h:34
DataObjects::MaskWorkspace_sptr m_maskWS
Mask Workspace.
Definition LoadMask.h:81
void processMaskOnWorkspaceIndex(bool mask, std::vector< specnum_t > &maskedSpecID, std::vector< detid_t > &singleDetIds)
Convert spectrum to detector.
Definition LoadMask.cpp:466
void processMaskOnDetectors(const detid2index_map &indexmap, bool tomask, const std::vector< detid_t > &singledetids)
Mask detectors or Unmask detectors.
Definition LoadMask.cpp:351
void convertSpMasksToDetIDs(const API::MatrixWorkspace &sourceWS, const std::vector< specnum_t > &maskedSpecID, std::vector< detid_t > &singleDetIds)
Definition LoadMask.cpp:638
std::vector< std::string > m_uMaskCompIdSingle
Definition LoadMask.h:105
Poco::XML::Element * m_pRootElem
Root element of the parsed XML.
Definition LoadMask.h:89
void componentToDetectors(const std::vector< std::string > &componentnames, std::vector< detid_t > &detectors)
Convert component to detectors.
Definition LoadMask.cpp:377
std::map< std::string, std::string > validateInputs() override
Validates if either input workspace or instrument name is defined.
Definition LoadMask.cpp:707
std::string m_instrumentPropValue
Instrument name.
Definition LoadMask.h:83
std::vector< std::string > m_maskCompIdSingle
Definition LoadMask.h:104
std::vector< detid_t > m_maskDetID
Definition LoadMask.h:95
bool m_defaultToUse
Default setup. If true, not masking, but use the pixel.
Definition LoadMask.h:92
void exec() override
Run the algorithm.
Definition LoadMask.cpp:268
Poco::AutoPtr< Poco::XML::Document > m_pDoc
XML document loaded.
Definition LoadMask.h:87
std::vector< specnum_t > m_maskSpecID
Definition LoadMask.h:100
void intializeMaskWorkspace()
Initialize a Mask Workspace.
Definition LoadMask.cpp:673
void initializeXMLParser(const std::string &filename)
Initialize XML parser.
Definition LoadMask.cpp:517
void bankToDetectors(const std::vector< std::string > &singlebanks, std::vector< detid_t > &detectors)
Convert bank to detector.
Definition LoadMask.cpp:425
std::vector< detid_t > m_unMaskDetID
Definition LoadMask.h:97
std::vector< std::string > validExtensions() const
Valudate inputs.
Definition LoadMask.h:56
API::MatrixWorkspace_sptr m_sourceMapWS
optional source workspace, containing spectra-detector mapping
Definition LoadMask.h:85
Concrete workspace implementation.
Definition Workspace2D.h:29
Records the filename and the description of failure.
Definition Exception.h:98
Exception for errors associated with the instrument definition.
Definition Exception.h:220
Exception for when an item is not found in a collection.
Definition Exception.h:145
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
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
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
Validator to check that a property is not left empty.
OptionalBool : Tri-state bool.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< MaskWorkspace > MaskWorkspace_sptr
shared pointer to the MaskWorkspace class
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
MANTID_KERNEL_DLL std::string loadFile(const std::string &filename)
Loads the entire contents of a text file into a string.
Definition Strings.cpp:26
std::unordered_map< specnum_t, size_t > spec2index_map
Map with key = spectrum number, value = workspace index.
int32_t detid_t
Typedef for a detector ID.
std::unordered_map< detid_t, size_t > detid2index_map
Map with key = detector ID, value = workspace index.
STL namespace.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54