Mantid
Loading...
Searching...
No Matches
ModifyDetectorDotDatFile.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 +
11#include "MantidAPI/Workspace.h"
15#include <fstream>
16
17using namespace Mantid::Kernel;
18using namespace Mantid::API;
19using namespace Mantid::Geometry;
20
21namespace Mantid::DataHandling {
22
23// Register the algorithm into the AlgorithmFactory
25
26//----------------------------------------------------------------------------------------------
30 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::Input),
31 "Workspace with detectors in the positions to be put into the detector "
32 "dot dat file");
33
34 std::initializer_list<std::string> exts = {".dat", ".txt"};
35
36 declareProperty(std::make_unique<FileProperty>("InputFilename", "", FileProperty::Load, exts),
37 "Path to a detector dot dat file. Must be of type .dat or .txt");
38
39 declareProperty(std::make_unique<FileProperty>("OutputFilename", "", FileProperty::Save, exts),
40 "Path to the modified detector dot dat file. Must be of type .dat or "
41 ".txt");
42}
43
44//----------------------------------------------------------------------------------------------
48 std::string inputFilename = getPropertyValue("InputFilename");
49 std::string outputFilename = getPropertyValue("OutputFilename");
50
51 Workspace_sptr ws1 = getProperty("InputWorkspace");
52 ExperimentInfo_sptr ws = std::dynamic_pointer_cast<ExperimentInfo>(ws1);
53
54 // Check instrument
55 Instrument_const_sptr inst = ws->getInstrument();
56 if (!inst)
57 throw std::runtime_error("No instrument in the Workspace. Cannot modify detector dot dat file");
58
59 // Open files
60 std::ifstream in;
61 in.open(inputFilename.c_str());
62 if (!in) {
63 throw Exception::FileError("Can't open input file", inputFilename);
64 }
65 std::ofstream out;
66 out.open(outputFilename.c_str());
67 if (!out) {
68 in.close();
69 throw Exception::FileError("Can't open output file", outputFilename);
70 }
71
72 // Read first line, modify it and put into output file
73 std::string str;
74 getline(in, str);
75 out << str << " and modified by MANTID algorithm ModifyDetectorDotDatFile \n";
76
77 // Read second line to check number of detectors and columns
78 int detectorCount, numColumns;
79 getline(in, str);
80 std::istringstream header2(str);
81 // what you get from the header is the Number_of_user_table_parameters
82 // while the number of columns must add the 5 required for the data format
83 header2 >> detectorCount >> numColumns;
84 numColumns += 5;
85 out << str << "\n";
86 // check that we have at least 1 detector and six columns
87 // and a reasonable number of columns. This is because, if there is not column
88 // specified, he will get a very large number of columns.
89 if (detectorCount < 1 || numColumns < 5 || numColumns > 1000) {
90 out.close();
91 in.close();
92 throw Exception::FileError("Incompatible file format found when reading line 2 in the input file", inputFilename);
93 }
94
95 // Copy column title line
96 getline(in, str);
97 out << str << "\n";
98 // Format details
99 int pOffset = 3; // Precision of Offset
100 int pOther = 5; // Precision of Other floats
101 int wDet = 9; // Field width of Detector ID
102 int wOff = 8; // Field width of Offset
103 int wRad = 10; // Field width of Radius
104 int wCode = 6; // Field width of Code
105 int wAng = 12; // Field width of angles
106
107 const auto &detectorInfo = ws->detectorInfo();
108
109 // Read input file line by line, modify line as necessary and put line into
110 // output file
111 while (getline(in, str)) {
112
113 std::istringstream istr(str);
114
115 detid_t detID;
116 double offset;
117 int code;
118 float dump; // ignored data
119
120 if (str.empty() || str[0] == '#') { // comments and empty lines are allowed and just copied
121 out << str << "\n";
122 continue;
123 }
124
125 // First five columns in the file, the detector ID and a code for the type
126 // of detector CODE = 3 (psd gas tube)
127 istr >> detID >> offset >> dump >> code >> dump;
128 if (numColumns > 5)
129 istr >> dump; // get phi
130
131 if (code == 3) {
132 try {
133 // indexOf throws for invalided detID
134 V3D pos = detectorInfo.position(detectorInfo.indexOf(detID));
135 double l2;
136 double theta;
137 double phi;
138 pos.getSpherical(l2, theta, phi);
139 std::streampos width = istr.tellg(); // Amount of string to replace
140 // Some experimenting with line manipulation
141 std::ostringstream oss;
142 oss << std::fixed << std::right;
143 oss.precision(pOffset);
144 oss << std::setw(wDet) << detID << std::setw(wOff) << offset;
145 oss.precision(pOther);
146 oss << std::setw(wRad) << l2 << std::setw(wCode) << code << std::setw(wAng) << theta << std::setw(wAng);
147 if (numColumns > 5)
148 oss << phi; // insert phi
149 std::string prefix = oss.str();
150 std::string suffix = str.substr(width, std::string::npos);
151 out << prefix << suffix << "\n";
152 } catch (std::out_of_range &) { // Detector not found, don't modify
153 out << str << "\n";
154 }
155 } else {
156 // We do not modify any other type of line
157 out << str << "\n";
158 }
159 }
160
161 out.close();
162 in.close();
163}
164
165} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
IntArray detectorCount
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.
@ Save
to specify a file to write to, the file may or may not exist
@ Load
allowed here which will be passed to the algorithm
A property class for workspaces.
Modifies an ISIS detector dot data file, so that the detector positions are as in the given workspace...
Records the filename and the description of failure.
Definition Exception.h:98
Class for 3D vectors.
Definition V3D.h:34
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
Definition V3D.cpp:116
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
int32_t detid_t
Typedef for a detector ID.
@ Input
An input workspace.
Definition Property.h:53