Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include "MantidDataHandling/SavePHX.h"
#include "MantidAPI/FileProperty.h"
#include "MantidGeometry/Instrument/Detector.h"
#include "MantidGeometry/Instrument/ObjComponent.h"
#include "MantidGeometry/Objects/Object.h"
#include <cstdio>
#include <fstream>
#include <iomanip>
namespace Mantid {
namespace DataHandling {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM( SavePHX);
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::Geometry;
// A reference to the logger is provided by the base class, it is called g_log.
// It is used to print out information, warning and error messages
void SavePHX::init() {
declareProperty(new WorkspaceProperty<> ("InputWorkspace", "",
Direction::Input), "The input workspace");
declareProperty(new FileProperty("Filename", "", FileProperty::Save),
"The filename to use for the saved data");
}
void SavePHX::exec() {
const double rad2deg = 180.0 / M_PI;
// Get the input workspace
MatrixWorkspace_sptr inputWorkspace = getProperty("InputWorkspace");
// Get the sample position
const Geometry::V3D samplePos =
inputWorkspace->getInstrument()->getSample()->getPos();
// Retrieve the filename from the properties
const std::string filename = getProperty("Filename");
// Get the number of spectra
const size_t nHist = inputWorkspace->getNumberHistograms();
// Get a pointer to the sample
IObjComponent_const_sptr sample =
inputWorkspace->getInstrument()->getSample();
std::ofstream outPHX_file(filename.c_str());
if (!outPHX_file) {
g_log.error("Failed to open (PHX) file:" + filename);
throw Kernel::Exception::FileError("Failed to open (PHX) file:",
filename);
}
int nDetectors = 0;
// Quick loop through the detectors to see how many we have that aren't monitors
for (int i = 0; i < nHist; ++i) {
IDetector_sptr det = inputWorkspace->getDetector(i);
if (!det->isMonitor()) {
++nDetectors;
}
}
// Write the number of detectors to the file.
outPHX_file << nDetectors << std::endl;
double twoTheta = 0.0;
double phi = 0.0;
double delta_twoTheta = 0.0;
double delta_phi = 0.0;
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
for (int i = 0; i < nHist; ++i) {
// Now get the detector object for this histogram
IDetector_sptr det = inputWorkspace->getDetector(i);
// boost::shared_ptr<GeometryHandler> handler;
// handler = const_cast<Object>(shape)->getGeometryHandler();
//
// handler->GetObjectGeom(type, geometry_vectors, radius, height);
if (!det->isMonitor()) {
// Get a pointer to the object.
// const boost::shared_ptr<const Object> shape = det->Shape();
// What is the distance from the sample to the detector (L2) ?
double distance = det->getDistance(*sample);
// Get the scattering angle (Polar) for this detector (in radians).
twoTheta = inputWorkspace->detectorTwoTheta(det);
// And also the Azimuthal angle (also in radians)
phi = det->getPhi();
// Convert to degrees
twoTheta = twoTheta * rad2deg;
phi = phi * rad2deg;
// int type(0);
// std::vector<Mantid::Geometry::V3D> geometry_vectors(0);
// double height(0.0), radius(0.0);
// shape->GetObjectGeom(type, geometry_vectors, radius, height);
// std::cout << "Pixel 1: " << std::endl;
// std::cout << "Height = " << height << std::endl;
// std::cout << "Radius = " << radius << std::endl;
// Initialise to large values
double xmin = -1000.0;
double xmax = 1000.0;
double ymin = -1000.0;
double ymax = 1000.0;
double zmin = -1000.0;
double zmax = 1000.0;
// Get the bounding box
det->getBoundingBox(xmax, ymax, zmax, xmin, ymin, zmin);
// g_log.information("X:(" + boost::lexical_cast<std::string>(xmin) + "," + boost::lexical_cast<
// std::string>(xmax) + ")");
// g_log.information("Y:(" + boost::lexical_cast<std::string>(ymin) + "," + boost::lexical_cast<
// std::string>(ymax) + ")");
// g_log.information("Z:(" + boost::lexical_cast<std::string>(zmin) + "," + boost::lexical_cast<
// std::string>(zmax) + ")");
double xsize = xmax - xmin;
double ysize = ymax - ymin;
double zsize = zmax - zmin;
g_log.debug() << "L2 : " << distance << std::endl;
g_log.debug() << "Width : " << xsize << std::endl;
g_log.debug() << "Height : " << ysize << std::endl;
g_log.debug() << "Depth : " << zsize << std::endl;
// IObjComponent_sptr detcomp = det->getComponent();
// Object shape = detcomp->Shape();
// double theta_min = acos(zmin/sqrt((xmin*xmin)+(ymin*ymin)+(zmin*zmin)));
// double theta_max = acos(zmax/sqrt((xmax*xmax)+(ymax*ymax)+(zmax*zmax)));
//
// double phi_min = atan2(ymin,xmin);
// double phi_max = atan2(ymax,xmax);
//
// delta_twoTheta = ((theta_max-theta_min)*(180.0/PI));
// delta_phi = ((phi_max-phi_min)*(180.0/PI));
//
// delta_twoTheta = atan2(xsize,distance)*(180.0/PI);
// delta_phi = atan2(ysize,distance)*(180.0/PI);
// ang=(y>0)?atan2(y,x):2.*M_PI+atan2(y,x);
// delta_twoTheta = comp->getPos();
delta_phi = atan2((ysize / 2.0), distance) * rad2deg;
delta_twoTheta = atan2((xsize / 2.0), distance) * rad2deg;
// Now write all the detector info.
outPHX_file << std::fixed << std::setprecision(3);
outPHX_file << "1\t0\t" << twoTheta << "\t" << phi << "\t"
<< delta_twoTheta << "\t" << delta_phi << "\t0\t"
<< det->getID() << std::endl;
}
}
// Close the file
outPHX_file.close();
}
} // namespace DataHandling
} // namespace Mantid