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