14#include <Poco/DOM/AutoPtr.h>
15#include <Poco/DOM/DOMWriter.h>
16#include <Poco/DOM/Document.h>
17#include <Poco/DOM/Element.h>
18#include <Poco/DOM/Text.h>
19#include <Poco/XML/XMLWriter.h>
37 "GroupingWorkspace to output to XML file (GroupingWorkspace)");
38 declareProperty(std::make_unique<FileProperty>(
"OutputFile",
"",
FileProperty::Save,
".xml"),
39 "File to save the detectors mask in XML format");
46 const std::string xmlfilename = this->
getProperty(
"OutputFile");
50 std::map<int, std::vector<detid_t>> groupIDwkspIDMap;
52 g_log.
debug() <<
"Size of map = " << groupIDwkspIDMap.size() <<
'\n';
55 std::map<int, std::vector<detid_t>> groupIDdetectorRangeMap;
59 this->
printToXML(groupIDdetectorRangeMap, xmlfilename);
69 for (
size_t iws = 0; iws <
mGroupWS->getNumberHistograms(); iws++) {
71 auto groupid =
static_cast<int>(
mGroupWS->y(iws)[0]);
74 auto it = groupwkspmap.find(groupid);
75 if (it == groupwkspmap.end()) {
76 std::vector<detid_t> tempvector;
77 groupwkspmap[groupid] = tempvector;
79 it = groupwkspmap.find(groupid);
80 if (it == groupwkspmap.end()) {
81 throw std::invalid_argument(
"Could not find group ID the after creating it in the map.");
85 const auto &mspec =
mGroupWS->getSpectrum(iws);
86 auto &detids = mspec.getDetectorIDs();
87 if (detids.size() != 1) {
88 throw std::invalid_argument(
"Each spectrum should only have one detector. Spectrum " +
92 it->second.insert(it->second.end(), detids.begin(), detids.end());
100 std::map<
int, std::vector<detid_t>> &groupdetidrangemap) {
102 for (
auto &groupdetids : groupdetidsmap) {
105 const int groupid = groupdetids.first;
106 sort(groupdetids.second.begin(), groupdetids.second.end());
108 g_log.
debug() <<
"Group " << groupid <<
" has " << groupdetids.second.size() <<
" detectors. \n";
111 std::vector<detid_t> detranges;
112 detid_t st = groupdetids.second[0];
114 for (
size_t i = 1; i < groupdetids.second.size(); i++) {
115 detid_t detid = groupdetids.second[i];
116 if (detid == ed + 1) {
121 detranges.emplace_back(st);
122 detranges.emplace_back(ed);
129 detranges.emplace_back(st);
130 detranges.emplace_back(ed);
133 groupdetidrangemap[groupid] = detranges;
139 const std::string &xmlfilename) {
142 const auto &instrument =
mGroupWS->getInstrument();
143 const std::string
name = instrument->getName();
147 AutoPtr<Document> pDoc =
new Document;
148 AutoPtr<Element> pRoot = pDoc->createElement(
"detector-grouping");
149 pDoc->appendChild(pRoot);
150 pRoot->setAttribute(
"instrument",
name);
151 pRoot->setAttribute(
"idf-date", instrument->getValidFromDate().toISO8601String());
154 if (
mGroupWS->run().hasProperty(
"Description")) {
155 const std::string description =
mGroupWS->run().getProperty(
"Description")->value();
156 pRoot->setAttribute(
"description", description);
160 for (
const auto &groupdetidrange : groupdetidrangemap) {
163 const int groupid = groupdetidrange.first;
164 std::stringstream sid;
167 AutoPtr<Element> pChildGroup = pDoc->createElement(
"group");
168 pChildGroup->setAttribute(
"ID", sid.str());
170 std::string groupNameProp =
"GroupName_" + sid.str();
171 if (
mGroupWS->run().hasProperty(groupNameProp)) {
172 const std::string groupName =
mGroupWS->run().getProperty(groupNameProp)->value();
173 pChildGroup->setAttribute(
"name", groupName);
176 pRoot->appendChild(pChildGroup);
178 g_log.
debug() <<
"Group ID = " << groupid <<
'\n';
181 std::stringstream ss;
183 for (
size_t i = 0; i < groupdetidrange.second.size() / 2; i++) {
186 detid_t ist = groupdetidrange.second[i * 2];
187 detid_t ied = groupdetidrange.second[i * 2 + 1];
190 ss << ist <<
"-" << ied;
191 }
else if (ist == ied) {
194 throw std::invalid_argument(
"Impossible to have this sitaution!");
197 if (i < groupdetidrange.second.size() / 2 - 1) {
201 g_log.
debug() <<
"Detectors: " << groupdetidrange.second[i * 2] <<
", " << groupdetidrange.second[i * 2 + 1]
205 const std::string textvalue = ss.str();
207 g_log.
debug() <<
"Detector IDs Node: " << textvalue <<
'\n';
210 AutoPtr<Element> pDetid = pDoc->createElement(
"detids");
211 AutoPtr<Text> pText1 = pDoc->createTextNode(textvalue);
212 pDetid->appendChild(pText1);
213 pChildGroup->appendChild(pDetid);
219 writer.setNewLine(
"\n");
220 writer.setOptions(XMLWriter::PRETTY_PRINT);
223 ofs.open(xmlfilename.c_str(), std::fstream::out);
225 ofs <<
"<?xml version=\"1.0\"?>\n";
227 writer.writeNode(std::cout, pDoc);
228 writer.writeNode(ofs, pDoc);
#define DECLARE_ALGORITHM(classname)
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
@ Save
to specify a file to write to, the file may or may not exist
A property class for workspaces.
SaveDetectorsGrouping : TODO: DESCRIPTION.
void convertToDetectorsRanges(std::map< int, std::vector< detid_t > > groupdetidsmap, std::map< int, std::vector< detid_t > > &groupdetidrangemap)
Convert vector of detector ID to range of Detector ID.
void createGroupDetectorIDMap(std::map< int, std::vector< detid_t > > &groupwkspmap)
Create map for GroupID – vector<detector ID>
DataObjects::GroupingWorkspace_const_sptr mGroupWS
void exec() override
Main body to execute algorithm.
const std::string name() const override
Algorithm's name for identification.
void printToXML(const std::map< int, std::vector< detid_t > > &groupdetidrangemap, const std::string &xmlfilename)
Print Grouping to XML file.
void debug(const std::string &msg)
Logs at debug level.
int32_t detid_t
Typedef for a detector ID.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ Input
An input workspace.