Mantid
Loading...
Searching...
No Matches
SaveMask.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 +
8
10#include "MantidAPI/ISpectrum.h"
12
13#include <Poco/DOM/AutoPtr.h>
14#include <Poco/DOM/DOMWriter.h>
15#include <Poco/DOM/Document.h>
16#include <Poco/DOM/Element.h>
17#include <Poco/DOM/Text.h>
18#include <Poco/XML/XMLWriter.h>
19
20#include <algorithm>
21#include <fstream>
22#include <memory>
23#include <sstream>
24
25using namespace Mantid::Kernel;
26using namespace Mantid::API;
27
28using namespace Poco::XML;
29
30namespace Mantid::DataHandling {
31
33
34
35void SaveMask::init() {
36
37 declareProperty(std::make_unique<API::WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
38 "Workspace to output masking to XML file");
39 declareProperty(std::make_unique<FileProperty>("OutputFile", "", FileProperty::Save, ".xml"),
40 "File to save the detectors mask in XML format");
41}
42
45 // 1. Get input
46 API::MatrixWorkspace_sptr userInputWS = this->getProperty("InputWorkspace");
47
48 DataObjects::SpecialWorkspace2D_sptr inpWS = std::dynamic_pointer_cast<DataObjects::SpecialWorkspace2D>(userInputWS);
49 if (!inpWS) {
50 // extract the masking and use that
51 Algorithm_sptr emAlg = this->createChildAlgorithm("ExtractMask", 0.0, 0.5, false);
52 emAlg->setProperty("InputWorkspace", userInputWS);
53 emAlg->setPropertyValue("OutputWorkspace", "tmp");
54 emAlg->setLogging(this->isLogging());
55 emAlg->execute();
56 API::MatrixWorkspace_sptr ws = emAlg->getProperty("OutputWorkspace");
57 inpWS = std::dynamic_pointer_cast<DataObjects::SpecialWorkspace2D>(ws);
58 if (!inpWS) {
59 throw std::runtime_error("Unable to extract masking data using ExtractMask");
60 }
61 }
62
63 std::string outxmlfilename = this->getPropertyValue("OutputFile");
64 if (!outxmlfilename.ends_with(".xml")) {
65 outxmlfilename += ".xml";
66 setPropertyValue("OutputFile", outxmlfilename);
67 }
68
69 // 2. Convert Workspace to ...
70 std::vector<detid_t> detid0s;
71 for (size_t i = 0; i < inpWS->getNumberHistograms(); i++) {
72 if (inpWS->y(i).front() > 0.1) {
73 // It is way from 0 but smaller than 1
74 const auto &ids = inpWS->getSpectrum(i).getDetectorIDs();
75 std::copy(ids.cbegin(), ids.cend(), std::back_inserter(detid0s));
76 }
77 }
78
79 // d) sort
80 g_log.debug() << "Number of detectors to be masked = " << detid0s.size() << '\n';
81
82 // 3. Count workspace to count 1 and 0
83 std::vector<detid_t> idx0sts; // starting point of the pair
84 std::vector<detid_t> idx0eds; // ending point of pair
85
86 if (!detid0s.empty()) {
87 std::sort(detid0s.begin(), detid0s.end());
88
89 detid_t i0st = detid0s[0];
90 detid_t i0ed = detid0s[0];
91
92 for (size_t i = 1; i < detid0s.size(); i++) {
93
94 if (detid0s[i] == detid0s[i - 1] + 1) {
95 // If it is continuous: record the current one
96 i0ed = detid0s[i];
97 } else {
98 // If skip: restart everything
99 // i) record previous result
100 idx0sts.emplace_back(i0st);
101 idx0eds.emplace_back(i0ed);
102 // ii) reset the register
103 i0st = detid0s[i];
104 i0ed = detid0s[i];
105 }
106
107 } // for
108
109 // Complete the registration
110 idx0sts.emplace_back(i0st);
111 idx0eds.emplace_back(i0ed);
112
113 for (size_t i = 0; i < idx0sts.size(); i++) {
114 g_log.information() << "Section " << i << " : " << idx0sts[i] << " , " << idx0eds[i]
115 << " to be masked and recorded.\n";
116 }
117 } // Only work for detid > 0
118
119 // 4. Write out to XML nodes
120 // a) Create document and root node
121 AutoPtr<Document> pDoc = new Document;
122 AutoPtr<Element> pRoot = pDoc->createElement("detector-masking");
123 pDoc->appendChild(pRoot);
124 // pRoot->setAttribute("default", "use");
125
126 // b) Append Group
127 AutoPtr<Element> pChildGroup = pDoc->createElement("group");
128 // pChildGroup->setAttribute("type", "notuse");
129 pRoot->appendChild(pChildGroup);
130
131 // c) Append detid
132 // c1. Generate text value
133 std::stringstream ss;
134 for (size_t i = 0; i < idx0sts.size(); i++) {
135 size_t ist = idx0sts[i];
136 size_t ied = idx0eds[i];
137
138 // a-b or a
139 bool writedata = true;
140 if (ist < ied) {
141 ss << ist << "-" << ied;
142 } else if (ist == ied) {
143 ss << ist;
144 } else {
145 writedata = false;
146 }
147 // add ","
148 if (writedata && i < idx0sts.size() - 1) {
149 ss << ",";
150 }
151
152 } // for
153 std::string textvalue = ss.str();
154 g_log.debug() << "SaveMask main text: available section = " << idx0sts.size() << "\n" << textvalue << '\n';
155
156 // c2. Create element
157 AutoPtr<Element> pDetid = pDoc->createElement("detids");
158 AutoPtr<Text> pText1 = pDoc->createTextNode(textvalue);
159 pDetid->appendChild(pText1);
160 pChildGroup->appendChild(pDetid);
161
162 // 4. Write
163 DOMWriter writer;
164 writer.setNewLine("\n");
165 writer.setOptions(XMLWriter::PRETTY_PRINT);
166
167 std::ofstream ofs;
168 ofs.open(outxmlfilename.c_str(), std::fstream::out);
169
170 ofs << "<?xml version=\"1.0\"?>\n";
171
172 writer.writeNode(std::cout, pDoc);
173 writer.writeNode(ofs, pDoc);
174 ofs.close();
175}
176
177} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
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
bool isLogging() const override
returns the status of logging, True = enabled
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
@ Save
to specify a file to write to, the file may or may not exist
A property class for workspaces.
SaveMaskingToFile : TODO: DESCRIPTION.
Definition SaveMask.h:19
void exec() override
Main body to execute algorithm.
Definition SaveMask.cpp:44
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
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< SpecialWorkspace2D > SpecialWorkspace2D_sptr
shared pointer to the SpecialWorkspace2D class
int32_t detid_t
Typedef for a detector ID.
@ Input
An input workspace.
Definition Property.h:53