Mantid
Loading...
Searching...
No Matches
LoadDetectorsGroupingFile.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 +
7#include <sstream>
8
11#include "MantidAPI/Run.h"
22
24
25#include <Poco/DOM/DOMParser.h>
26#include <Poco/DOM/Element.h>
27#include <Poco/DOM/NamedNodeMap.h>
28#include <Poco/DOM/NodeFilter.h>
29#include <Poco/DOM/NodeIterator.h>
30#include <Poco/DOM/NodeList.h>
31#include <Poco/Exception.h>
32#include <Poco/String.h>
33#include <filesystem>
34
35using namespace Mantid::Kernel;
36using namespace Mantid::API;
37
38namespace Mantid::DataHandling {
39
40namespace {
41namespace PropertyNames {
42const std::string INPUT_FILE("InputFile");
43const std::string INPUT_WKSP("InputWorkspace");
44const std::string OUTPUT_WKSP("OutputWorkspace");
45} // namespace PropertyNames
46} // namespace
47
49
52
53 const std::vector<std::string> exts{".xml", ".map"};
54 declareProperty(std::make_unique<FileProperty>(PropertyNames::INPUT_FILE, "", FileProperty::Load, exts),
55 "The XML or Map file with full path.");
56
57 declareProperty(
59 "Optional: An input workspace with the instrument we want to use. This "
60 "will override what is specified in the grouping file.");
61
64 "The output workspace containing the loaded grouping information.");
65}
66
69 std::filesystem::path inputFile(static_cast<std::string>(getProperty(PropertyNames::INPUT_FILE)));
70
71 std::string ext = Poco::toLower(inputFile.extension().string().substr(1)); // skip `.`
72
73 // The number of steps depends on the type of input file
74 // Set them to zero for the moment
75 Progress progress(this, 0.0, 1.0, 0);
76
77 if (ext == "xml") {
78 // Deal with file as xml
79
80 progress.setNumSteps(6);
81 progress.report("Parsing XML file");
82
83 // 1. Parse XML File
84 LoadGroupXMLFile loader;
85 loader.loadXMLFile(inputFile.string());
86
88 if (inputWS) {
89 // use the instrument from the input workspace
90 m_instrument = inputWS->getInstrument();
91 } else if (loader.isGivenInstrumentName()) {
92 // Load an instrument, if given
93 const std::string instrumentName = loader.getInstrumentName();
94
95 std::string date;
96
97 if (loader.isGivenDate())
98 date = loader.getDate();
99
100 // Get a relevant IDF for a given instrument name and date. If date is
101 // empty -
102 // the most recent will be used.
103 const std::string instrumentFilename = InstrumentFileFinder::getInstrumentFilename(instrumentName, date);
104
105 // Load an instrument
106 Algorithm_sptr childAlg = this->createChildAlgorithm("LoadInstrument");
108 childAlg->setProperty<MatrixWorkspace_sptr>("Workspace", tempWS);
109 childAlg->setPropertyValue("Filename", instrumentFilename);
110 childAlg->setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(false));
111 childAlg->executeAsChildAlg();
112 m_instrument = tempWS->getInstrument();
113 }
114
115 progress.report("Checking detector IDs");
116
117 // 2. Check if detector IDs are given
118 if (!m_instrument && std::any_of(m_groupDetectorsMap.cbegin(), m_groupDetectorsMap.cend(),
119 [](const auto &pair) { return !pair.second.empty(); })) {
120 throw std::invalid_argument("Grouping file specifies detector ID without instrument name");
121 }
122
126
127 progress.report("Creating output workspace");
128
129 // 3. Create output workspace
131 m_groupWS->mutableRun().addProperty("Filename", inputFile.string());
132 setProperty("OutputWorkspace", m_groupWS);
133
134 progress.report("Setting geometry");
135
136 // 4. Translate and set geometry
137 this->setByComponents();
138 this->setByDetectors();
139 this->setBySpectrumNos();
140
141 progress.report("Checking grouping description");
142
143 // 5. Add grouping description, if specified
144 if (loader.isGivenDescription()) {
145 std::string description = loader.getDescription();
146 m_groupWS->mutableRun().addProperty("Description", description);
147 }
148
149 progress.report("Checking group names");
150
151 // 6. Add group names, if user has specified any
152 std::map<int, std::string> groupNamesMap = loader.getGroupNamesMap();
153
154 for (auto &group : groupNamesMap) {
155 std::string groupIdStr = std::to_string(group.first);
156 m_groupWS->mutableRun().addProperty("GroupName_" + groupIdStr, group.second);
157 }
158 } else if (ext == "map") {
159 // Deal with file as map
160
161 progress.setNumSteps(3);
162 progress.report("Parsing map file");
163
164 // Load data from file
165 LoadGroupMapFile loader(inputFile.string(), g_log);
166 loader.parseFile();
167
168 progress.report("Setting spectra map");
169
170 // In .map files we are dealing with spectra numbers only.
172
173 progress.report("Creating output workspace");
174
175 // There is no way to specify instrument name in .map file
177
178 m_groupWS->mutableRun().addProperty("Filename", inputFile.string());
179 setProperty("OutputWorkspace", m_groupWS);
180
181 this->setBySpectrumNos();
182 } else {
183 // Unknown file type
184 throw std::invalid_argument("File type is not supported: " + ext);
185 }
186}
187
188/*
189 * Convert Componenet -> Detector IDs -> Workspace Indices -> set group ID
190 */
192
193 // 0. Check
194 if (!m_instrument) {
195 const auto it = std::find_if(m_groupComponentsMap.cbegin(), m_groupComponentsMap.cend(),
196 [](const auto &pair) { return !pair.second.empty(); });
197 if (it != m_groupComponentsMap.cend()) {
198 g_log.error() << "Instrument is not specified in XML file. "
199 << "But tag 'component' is used in XML file for Group " << it->first << " It is not allowed"
200 << std::endl;
201 throw std::invalid_argument("XML definition involving component causes error");
202 }
203 }
204
205 // 1. Prepare
206 const detid2index_map indexmap = m_groupWS->getDetectorIDToWorkspaceIndexMap(true);
207 const auto &componentInfo = m_groupWS->componentInfo();
208 const auto &detectorInfo = m_groupWS->detectorInfo();
209
210 // 2. Set
211 for (auto &componentMap : m_groupComponentsMap) {
212 g_log.debug() << "Group ID = " << componentMap.first << " With " << componentMap.second.size() << " Components\n";
213
214 for (auto &componentName : componentMap.second) {
215
216 // a) get component by name and find its index
217 const size_t componentIndex = componentInfo.indexOfAny(componentName);
218
219 // b) get all detectors in the subtree of this component
220 const auto detectorIndices = componentInfo.detectorsInSubtree(componentIndex);
221
222 g_log.debug() << "Component Name = " << componentName
223 << " Component ID = " << componentInfo.componentID(componentIndex)
224 << " Number of Children = " << detectorIndices.size() << '\n';
225
226 for (const auto &detIndex : detectorIndices) {
227 // c) get detector ID
228 const auto detid = detectorInfo.detectorIDs()[detIndex];
229 auto itx = indexmap.find(detid);
230 if (itx != indexmap.end()) {
231 size_t wsindex = itx->second;
232 m_groupWS->mutableY(wsindex)[0] = componentMap.first;
233 } else {
234 g_log.error() << "Pixel w/ ID = " << detid << " Cannot Be Located\n";
235 }
236
237 } // ENDFOR (children of component)
238 } // ENDFOR (component)
239
240 } // ENDFOR GroupID
241}
242
243/* Set workspace->group ID map by detectors (range)
244 *
245 */
247
248 // 0. Check
249 if (!m_instrument && !m_groupDetectorsMap.empty()) {
250 const auto it = std::find_if(m_groupDetectorsMap.cbegin(), m_groupDetectorsMap.cend(),
251 [](const auto &pair) { return !pair.second.empty(); });
252 if (it != m_groupDetectorsMap.cend()) {
253 g_log.error() << "Instrument is not specified in XML file. "
254 << "But tag 'detid' is used in XML file for Group " << it->first << " It is not allowed"
255 << std::endl;
256 throw std::invalid_argument("XML definition involving component causes error");
257 }
258 }
259
260 // 1. Prepare
261 const detid2index_map indexmap = m_groupWS->getDetectorIDToWorkspaceIndexMap(true);
262
263 // 2. Set GroupingWorkspace
264 for (const auto &detectorMap : m_groupDetectorsMap) {
265 g_log.debug() << "Group ID = " << detectorMap.first << '\n';
266
267 for (auto detid : detectorMap.second) {
268 auto itx = indexmap.find(detid);
269
270 if (itx != indexmap.end()) {
271 size_t wsindex = itx->second;
272 m_groupWS->mutableY(wsindex)[0] = detectorMap.first;
273 } else {
274 g_log.error() << "Pixel w/ ID = " << detid << " Cannot Be Located\n";
275 }
276 } // ENDFOR detid (in range)
277 } // ENDFOR each group ID
278}
279
280/*
281 * Set workspace index/group id by spectrum Nos
282 */
284 // 1. Get map
285 const spec2index_map s2imap = m_groupWS->getSpectrumToWorkspaceIndexMap();
286 spec2index_map::const_iterator s2iter;
287
288 // 2. Locate in loop
289 // std::map<int, std::vector<int> > m_groupSpectraMap;
290 std::map<int, std::vector<int>>::iterator gsiter;
291 for (gsiter = m_groupSpectraMap.begin(); gsiter != m_groupSpectraMap.end(); ++gsiter) {
292 int groupid = gsiter->first;
293 for (auto specNo : gsiter->second) {
294 s2iter = s2imap.find(specNo);
295 if (s2iter == s2imap.end()) {
296 g_log.error() << "Spectrum " << specNo << " does not have an entry in GroupWorkspace's spec2index map\n";
297 throw std::runtime_error("Logic error");
298 } else {
299 size_t wsindex = s2iter->second;
300 if (wsindex >= m_groupWS->getNumberHistograms()) {
301 g_log.error() << "Group workspace's spec2index map is set wrong: "
302 << " Found workspace index = " << wsindex << " for spectrum No " << specNo
303 << " with workspace size = " << m_groupWS->getNumberHistograms() << '\n';
304 } else {
305 // Finally set the group workspace
306 m_groupWS->mutableY(wsindex)[0] = groupid;
307 } // IF-ELSE: ws index out of range
308 } // IF-ELSE: spectrum No has an entry
309 } // FOR: each spectrum No
310 } // FOR: each group ID
311}
312
313/* Initialize a GroupingWorkspace
314 *
315 */
317
318 if (m_instrument) {
319 // Create GroupingWorkspace with instrument
321 } else {
322 // 1b. Create GroupingWorkspace w/o instrument
324 }
325}
326
327/*
328 * Generate a GroupingWorkspace without instrument information
329 */
331 // 1. Generate a map
332 std::map<int, int> spectrumidgroupmap;
333 std::map<int, std::vector<int>>::iterator groupspeciter;
334 std::vector<int> specids;
335 for (groupspeciter = m_groupSpectraMap.begin(); groupspeciter != m_groupSpectraMap.end(); ++groupspeciter) {
336 int groupid = groupspeciter->first;
337 for (auto specid : groupspeciter->second) {
338 spectrumidgroupmap.emplace(specid, groupid);
339 specids.emplace_back(specid);
340 }
341 }
342
343 std::sort(specids.begin(), specids.end());
344
345 if (specids.size() != spectrumidgroupmap.size()) {
346 g_log.warning() << "Duplicate spectrum No is defined in input XML file!\n";
347 }
348
349 // 2. Initialize group workspace and set the spectrum workspace map
350 size_t numvectors = spectrumidgroupmap.size();
352
353 for (size_t i = 0; i < m_groupWS->getNumberHistograms(); i++) {
354 m_groupWS->getSpectrum(i).setSpectrumNo(specids[i]);
355 }
356}
357
358/*
359 * Initialization
360 */
362 : m_instrumentName(""), m_userGiveInstrument(false), m_date(""), m_userGiveDate(false), m_description(""),
363 m_userGiveDescription(false), m_pDoc(), m_groupComponentsMap(), m_groupDetectorsMap(), m_groupSpectraMap(),
364 m_startGroupID(1), m_groupNamesMap() {}
365
366void LoadGroupXMLFile::loadXMLFile(const std::string &xmlfilename) {
367
368 this->initializeXMLParser(xmlfilename);
369 this->parseXML();
370}
371
372/*
373 * Initalize Poco XML Parser
374 */
375void LoadGroupXMLFile::initializeXMLParser(const std::string &filename) {
376 const std::string xmlText = Kernel::Strings::loadFile(filename);
377
378 // Set up the DOM parser and parse xml file
379 Poco::XML::DOMParser pParser;
380 try {
381 m_pDoc = pParser.parseString(xmlText);
382 } catch (Poco::Exception &exc) {
383 throw Kernel::Exception::FileError(exc.displayText() + ". Unable to parse File:", filename);
384 } catch (...) {
385 throw Kernel::Exception::FileError("Unable to parse File:", filename);
386 }
387 if (!m_pDoc->documentElement()->hasChildNodes()) {
388 throw Kernel::Exception::InstrumentDefinitionError("No root element in XML instrument file", filename);
389 }
390}
391
392/*
393 * Parse XML file
394 */
396 // 0. Check
397 if (!m_pDoc)
398 throw std::runtime_error("Call LoadDetectorsGroupingFile::initialize() before parseXML.");
399
400 // 1. Parse and create a structure
401 Poco::XML::NodeIterator it(m_pDoc, Poco::XML::NodeFilter::SHOW_ELEMENT);
402 Poco::XML::Node *pNode = it.nextNode();
403
404 int curgroupid = m_startGroupID - 1;
405 bool isfirstgroup = true;
406
407 // Add flag to figure out it is automatic group ID or user-defined group ID
408 bool autogroupid = true;
409
410 // While loop to go over all nodes!
411 while (pNode) {
412
413 const Poco::XML::XMLString value = pNode->innerText();
414
415 if (pNode->nodeName() == "detector-grouping") {
416 // Node "detector-grouping" (first level)
417
418 // Optional instrument name
420
421 // Optional date for which is relevant
422 m_date = getAttributeValueByName(pNode, "idf-date", m_userGiveDate);
423
424 // Optional grouping description
426
427 } // "detector-grouping"
428 else if (pNode->nodeName() == "group") {
429 // Group Node: get ID, set map
430 // a) Find group ID
431 bool foundid;
432 std::string idstr = getAttributeValueByName(pNode, "ID", foundid);
433
434 if (isfirstgroup && foundid)
435 autogroupid = false;
436 else if (!isfirstgroup && !autogroupid && foundid)
437 autogroupid = false;
438 else
439 autogroupid = true;
440
441 isfirstgroup = false;
442
443 if (autogroupid) {
444 curgroupid++;
445 } else {
446 curgroupid = std::stoi(idstr);
447 }
448
449 // b) Set in map
450 auto itc = m_groupComponentsMap.find(curgroupid);
451 if (itc != m_groupComponentsMap.end()) {
452 // Error! Duplicate Group ID defined in XML
453 std::stringstream ss;
454 ss << "Map (group ID, components) has group ID " << curgroupid << " already. Duplicate Group ID error!\n";
455 throw std::invalid_argument(ss.str());
456 } else {
457 // When group ID is sorted, check if user has specified a group name
458 bool foundName;
459 std::string name = getAttributeValueByName(pNode, "name", foundName);
460 if (foundName)
461 m_groupNamesMap[curgroupid] = name;
462
463 // Set map
464 std::vector<std::string> tempcomponents;
465 std::vector<detid_t> tempdetids;
466 std::vector<int> tempspectrumids;
467 m_groupComponentsMap[curgroupid] = tempcomponents;
468 m_groupDetectorsMap[curgroupid] = tempdetids;
469 m_groupSpectraMap[curgroupid] = tempspectrumids;
470 }
471 } // "group"
472 else if (pNode->nodeName() == "component") {
473 // Node "component" = value
474 auto groupIt = m_groupComponentsMap.find(curgroupid);
475 if (groupIt == m_groupComponentsMap.end()) {
476 std::stringstream ss;
477 ss << "XML File (component) heirachial error!"
478 << " Inner Text = " << pNode->innerText() << '\n';
479 throw std::invalid_argument(ss.str());
480 } else {
481 bool valfound;
482 std::string val_value = this->getAttributeValueByName(pNode, "val", valfound);
483 std::string finalvalue;
484 if (valfound && !value.empty())
485 finalvalue.append(value).append(", ").append(val_value);
486 else if (value.empty())
487 finalvalue = val_value;
488 else
489 finalvalue = value;
490 groupIt->second.emplace_back(finalvalue);
491 }
492
493 } // Component
494 else if (pNode->nodeName() == "detids") {
495 // Node "detids"
496 auto groupIt = m_groupDetectorsMap.find(curgroupid);
497 if (groupIt == m_groupDetectorsMap.end()) {
498 std::stringstream ss;
499 ss << "XML File (detids) hierarchal error!"
500 << " Inner Text = " << pNode->innerText() << '\n';
501 throw std::invalid_argument(ss.str());
502 } else {
503 bool valfound;
504 std::string val_value = this->getAttributeValueByName(pNode, "val", valfound);
505 std::string finalvalue;
506 if (valfound && !value.empty())
507 finalvalue.append(value).append(", ").append(val_value);
508 else if (value.empty())
509 finalvalue = val_value;
510 else
511 finalvalue = value;
512
513 std::vector<int> parsedRange = Strings::parseRange(finalvalue);
514 groupIt->second.insert(groupIt->second.end(), parsedRange.begin(), parsedRange.end());
515 }
516 } // "detids"
517 else if (pNode->nodeName() == "ids") {
518 // Node ids: for spectrum number
519 auto groupIt = m_groupSpectraMap.find(curgroupid);
520 if (groupIt == m_groupSpectraMap.end()) {
521 std::stringstream ss;
522 ss << "XML File (ids) hierarchal error! "
523 << " Inner Text = " << pNode->innerText() << '\n';
524 throw std::invalid_argument(ss.str());
525 } else {
526 bool valfound;
527 std::string val_value = this->getAttributeValueByName(pNode, "val", valfound);
528 std::string finalvalue;
529 if (valfound && !value.empty())
530 finalvalue.append(value).append(", ").append(val_value);
531 else if (value.empty())
532 finalvalue = val_value;
533 else
534 finalvalue = value;
535
536 std::vector<int> parsedRange = Strings::parseRange(finalvalue);
537 groupIt->second.insert(groupIt->second.end(), parsedRange.begin(), parsedRange.end());
538 }
539 }
540
541 // Next Node!
542 pNode = it.nextNode();
543
544 } // ENDWHILE
545}
546
547/*
548 * Get attribute's value by name from a Node
549 */
550std::string LoadGroupXMLFile::getAttributeValueByName(Poco::XML::Node *pNode, const std::string &attributename,
551 bool &found) {
552 // 1. Init
553 Poco::AutoPtr<Poco::XML::NamedNodeMap> att = pNode->attributes();
554 found = false;
555 std::string value;
556
557 // 2. Loop to find
558 for (unsigned long i = 0; i < att->length(); ++i) {
559 Poco::XML::Node *cNode = att->item(i);
560 if (cNode->localName() == attributename) {
561 value = cNode->getNodeValue();
562 found = true;
563 break;
564 }
565 } // ENDFOR
566
567 return value;
568}
569
570// -----------------------------------------------------------------------------------------------
571
577LoadGroupMapFile::LoadGroupMapFile(const std::string &fileName, Kernel::Logger &log)
578 : m_fileName(fileName), m_log(log), m_lastLineRead(0) {
579 m_file.open(m_fileName.c_str(), std::ifstream::in);
580
581 if (!m_file)
582 throw Exception::FileError("Couldn't open file for reading", fileName);
583}
584
589 // Close the file, if terminate was not called
590 if (m_file.is_open())
591 m_file.close();
592}
593
598 try {
599 // We don't use the total number of groups report at the top of the file but
600 // we'll tell them
601 // later if there is a problem with it for their diagnostic purposes
602 size_t givenNoOfGroups;
603 std::string line;
604
605 if (!nextDataLine(line))
606 throw std::invalid_argument("The input file doesn't appear to contain any data");
607
608 if (Kernel::Strings::convert(line, givenNoOfGroups) != 1)
609 throw std::invalid_argument("Expected a single int for the number of groups");
610
611 // Parse groups
612 int currentGroupNo = 1;
613 while (true) {
614 // Read next line ("group spectrum no.") -> ignore the number itself
615 if (!nextDataLine(line))
616 // If file ended -> no more groups to read, so exit the loop silently
617 break;
618
619 // Try to read number of spectra
620 size_t noOfGroupSpectra;
621
622 if (!nextDataLine(line))
623 throw std::invalid_argument("Premature end of file, expecting the number of group spectra");
624
625 if (Kernel::Strings::convert(line, noOfGroupSpectra) != 1)
626 throw std::invalid_argument("Expected a single int for the number of group spectra");
627
628 std::vector<int> &groupSpectra = m_groupSpectraMap[currentGroupNo];
629
630 groupSpectra.reserve(noOfGroupSpectra);
631
632 // While have not read all the group spectra
633 while (groupSpectra.size() < noOfGroupSpectra) {
634 if (!nextDataLine(line))
635 throw std::invalid_argument("Premature end of file, expecting spectra list");
636
637 // Parse line with range. Exceptions will be catched as all others.
638 std::vector<int> readSpectra = Kernel::Strings::parseRange(line, " ");
639
640 groupSpectra.insert(groupSpectra.end(), readSpectra.begin(), readSpectra.end());
641 }
642
643 if (groupSpectra.size() != noOfGroupSpectra)
644 throw std::invalid_argument("Bad number of spectra list");
645
646 currentGroupNo++;
647 }
648
649 if (m_groupSpectraMap.size() != givenNoOfGroups) {
650 m_log.warning() << "The input file header states there are " << givenNoOfGroups << ", but the file contains "
651 << m_groupSpectraMap.size() << " groups\n";
652 }
653 } catch (std::invalid_argument &e) {
655 }
656}
657
664bool LoadGroupMapFile::nextDataLine(std::string &line) {
665 while (m_file) {
666 std::getline(m_file, line);
668
669 if (!m_file)
670 return false;
671
672 line = Poco::trim(line);
673
674 if (!line.empty() && line[0] != '#')
675 return true;
676 }
677
678 return false;
679}
680
681} // namespace Mantid::DataHandling
std::string name
Definition Run.cpp:60
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
double value
The value of the point.
Definition FitMW.cpp:51
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
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
@ Load
allowed here which will be passed to the algorithm
static std::string getInstrumentFilename(const std::string &instrumentName, const std::string &date="")
Get the IDF using the instrument name and date.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
std::map< int, std::vector< int > > m_groupSpectraMap
DataObjects::GroupingWorkspace_sptr m_groupWS
Grouping Workspace.
void intializeGroupingWorkspace()
Initialize a Mask Workspace.
void setBySpectrumNos()
Set workspace index/group ID by spectrum Number.
void setByComponents()
Set workspace->group ID map by components.
std::map< int, std::vector< std::string > > m_groupComponentsMap
Data structures to store XML to Group/Detector conversion map.
void generateNoInstrumentGroupWorkspace()
Generate a GroupingWorkspace w/o instrument.
std::map< int, std::vector< detid_t > > m_groupDetectorsMap
void setByDetectors()
Set workspace->group ID map by detectors (range)
Geometry::Instrument_const_sptr m_instrument
Instrument to use if given by user.
Class used to load a grouping information from .map file.
void parseFile()
Parses grouping information from .map file.
const std::map< int, std::vector< int > > & getGroupSpectraMap() const
Return the map parsed from file.
LoadGroupMapFile(const std::string &fileName, Kernel::Logger &log)
Constructor. Opens a file.
std::map< int, std::vector< int > > m_groupSpectraMap
group_id -> [list of spectra]
const std::string m_fileName
The name of the file being parsed.
int m_lastLineRead
Number of the last line parsed.
std::ifstream m_file
The file being parsed.
bool nextDataLine(std::string &line)
Skips all the empty lines and comment lines, and returns next line with real data.
std::string m_description
Grouping description. Empty if not specified.
void loadXMLFile(const std::string &xmlfilename)
std::string m_date
Date in ISO 8601 for which this grouping is relevant.
const std::map< int, std::vector< detid_t > > & getGroupDetectorsMap() const
static std::string getAttributeValueByName(Poco::XML::Node *pNode, const std::string &attributename, bool &found)
Get attribute value from an XML node.
std::map< int, std::vector< std::string > > m_groupComponentsMap
Data structures to store XML to Group/Detector conversion map.
const std::map< int, std::vector< int > > & getGroupSpectraMap() const
bool m_userGiveDescription
Whether description is given by user.
const std::map< int, std::string > & getGroupNamesMap() const
Poco::AutoPtr< Poco::XML::Document > m_pDoc
XML document loaded.
const std::map< int, std::vector< std::string > > & getGroupComponentsMap() const
Data structures to store XML to Group/Detector conversion map.
bool m_userGiveDate
Whether date is given by user.
bool m_userGiveInstrument
User-define instrument name.
std::map< int, std::vector< detid_t > > m_groupDetectorsMap
std::map< int, std::string > m_groupNamesMap
Map of group names.
void initializeXMLParser(const std::string &filename)
Initialize XML parser.
std::map< int, std::vector< int > > m_groupSpectraMap
A GroupingWorkspace is a subclass of Workspace2D where each spectrum has a single number entry,...
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
Records the filename, the description of failure and the line on which it happened.
Definition Exception.h:115
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition Logger.h:51
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
OptionalBool : Tri-state bool.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
Definition Algorithm.h:52
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< GroupingWorkspace > GroupingWorkspace_sptr
shared pointer to the GroupingWorkspace class
MANTID_KERNEL_DLL std::vector< int > parseRange(const std::string &str, const std::string &elemSep=",", const std::string &rangeSep="-")
Parses a number range, e.g.
Definition Strings.cpp:1101
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
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition Strings.cpp:696
const std::string OUTPUT_WKSP("OutputWorkspace")
const std::string INPUT_WKSP("InputWorkspace")
std::unordered_map< specnum_t, size_t > spec2index_map
Map with key = spectrum number, value = workspace index.
std::unordered_map< detid_t, size_t > detid2index_map
Map with key = detector ID, value = workspace index.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54