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