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
65 // 2. Convert Workspace to ...
66 std::vector<detid_t> detid0s;
67 for (size_t i = 0; i < inpWS->getNumberHistograms(); i++) {
68 if (inpWS->y(i).front() > 0.1) {
69 // It is way from 0 but smaller than 1
70 const auto &ids = inpWS->getSpectrum(i).getDetectorIDs();
71 std::copy(ids.cbegin(), ids.cend(), std::back_inserter(detid0s));
72 }
73 }
74
75 // d) sort
76 g_log.debug() << "Number of detectors to be masked = " << detid0s.size() << '\n';
77
78 // 3. Count workspace to count 1 and 0
79 std::vector<detid_t> idx0sts; // starting point of the pair
80 std::vector<detid_t> idx0eds; // ending point of pair
81
82 if (!detid0s.empty()) {
83 std::sort(detid0s.begin(), detid0s.end());
84
85 detid_t i0st = detid0s[0];
86 detid_t i0ed = detid0s[0];
87
88 for (size_t i = 1; i < detid0s.size(); i++) {
89
90 if (detid0s[i] == detid0s[i - 1] + 1) {
91 // If it is continuous: record the current one
92 i0ed = detid0s[i];
93 } else {
94 // If skip: restart everything
95 // i) record previous result
96 idx0sts.emplace_back(i0st);
97 idx0eds.emplace_back(i0ed);
98 // ii) reset the register
99 i0st = detid0s[i];
100 i0ed = detid0s[i];
101 }
102
103 } // for
104
105 // Complete the registration
106 idx0sts.emplace_back(i0st);
107 idx0eds.emplace_back(i0ed);
108
109 for (size_t i = 0; i < idx0sts.size(); i++) {
110 g_log.information() << "Section " << i << " : " << idx0sts[i] << " , " << idx0eds[i]
111 << " to be masked and recorded.\n";
112 }
113 } // Only work for detid > 0
114
115 // 4. Write out to XML nodes
116 // a) Create document and root node
117 AutoPtr<Document> pDoc = new Document;
118 AutoPtr<Element> pRoot = pDoc->createElement("detector-masking");
119 pDoc->appendChild(pRoot);
120 // pRoot->setAttribute("default", "use");
121
122 // b) Append Group
123 AutoPtr<Element> pChildGroup = pDoc->createElement("group");
124 // pChildGroup->setAttribute("type", "notuse");
125 pRoot->appendChild(pChildGroup);
126
127 // c) Append detid
128 // c1. Generate text value
129 std::stringstream ss;
130 for (size_t i = 0; i < idx0sts.size(); i++) {
131 size_t ist = idx0sts[i];
132 size_t ied = idx0eds[i];
133
134 // a-b or a
135 bool writedata = true;
136 if (ist < ied) {
137 ss << ist << "-" << ied;
138 } else if (ist == ied) {
139 ss << ist;
140 } else {
141 writedata = false;
142 }
143 // add ","
144 if (writedata && i < idx0sts.size() - 1) {
145 ss << ",";
146 }
147
148 } // for
149 std::string textvalue = ss.str();
150 g_log.debug() << "SaveMask main text: available section = " << idx0sts.size() << "\n" << textvalue << '\n';
151
152 // c2. Create element
153 AutoPtr<Element> pDetid = pDoc->createElement("detids");
154 AutoPtr<Text> pText1 = pDoc->createTextNode(textvalue);
155 pDetid->appendChild(pText1);
156 pChildGroup->appendChild(pDetid);
157
158 // 4. Write
159 DOMWriter writer;
160 writer.setNewLine("\n");
161 writer.setOptions(XMLWriter::PRETTY_PRINT);
162
163 std::ofstream ofs;
164 ofs.open(outxmlfilename.c_str(), std::fstream::out);
165
166 ofs << "<?xml version=\"1.0\"?>\n";
167
168 writer.writeNode(std::cout, pDoc);
169 writer.writeNode(ofs, pDoc);
170 ofs.close();
171}
172
173} // 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
@ 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