28using namespace Kernel;
30using namespace Geometry;
41 std::vector<std::string>{
".sca",
".raw"}),
42 "The name of the scaling calibrations file to read, including its\n"
43 "full or relative path. The file extension must be either .sca or\n"
44 ".raw (filenames are case sensitive on linux)");
46 "The name of the workspace to apply the scaling to. This must be\n"
47 "associated with an instrument appropriate for the scaling file");
49 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
50 mustBePositive->setLower(0);
52 "Control scaling calculation - 0 => use average of left and right\n"
53 "scaling (default). 1 => use maximum scaling. 2 => maximum + 5%");
65 std::vector<Kernel::V3D> truepos;
84 std::map<int, Kernel::V3D> posMap;
85 std::map<int, double> scaleMap;
86 std::map<int, double>::iterator its;
88 const auto &detectorInfo =
m_workspace->detectorInfo();
89 if (scalingFile.find(
".sca") != std::string::npos || scalingFile.find(
".SCA") != std::string::npos) {
93 std::ifstream sFile(scalingFile.c_str());
95 g_log.
error() <<
"Unable to open scaling file " << scalingFile <<
'\n';
103 std::istringstream detCountStream(str);
106 g_log.
error(
"Bad detector count in scaling file");
107 throw std::runtime_error(
"Bad detector count in scaling file");
118 while (getline(sFile, str)) {
119 if (str.empty() || str[0] ==
'#')
121 std::istringstream istr(str);
125 double l2, theta, phi, offset;
126 istr >> detIndex >> offset >>
l2 >> code >> theta >> phi;
131 if (theta > 181.0 || theta < -1 || phi < -181 || phi > 181) {
132 g_log.
error(
"Position angle data out of range in .sca file");
133 throw std::runtime_error(
"Position angle data out of range in .sca file");
138 truePos.emplace_back(truPos);
141 size_t index = detectorInfo.indexOf(detIndex);
146 if (detIdLast == detIndex - 1 && !detectorInfo.isMonitor(
index)) {
149 double scale = diffT.
norm() / diffI.
norm();
153 scaleMap[detIndex] = scale;
154 its = scaleMap.find(detIndex - 1);
155 if (its == scaleMap.end())
156 scaleMap[detIndex - 1] = scale;
158 its->second = 0.5 * (its->second + scale);
160 detIdLast = detIndex;
163 posMap[detIndex] = shift;
165 }
catch (std::out_of_range &) {
169 }
else if (scalingFile.find(
".raw") != std::string::npos || scalingFile.find(
".RAW") != std::string::npos) {
170 std::vector<int> detID;
171 std::vector<Kernel::V3D> truepos;
176 g_log.
error(
"Failed to read any detectors from RAW file");
177 throw std::runtime_error(
"Failed to read any detectors from RAW file");
183 int detIndex = detID[i];
186 size_t index = detectorInfo.indexOf(detIndex);
190 if (detIdLast == detIndex - 1 && !detectorInfo.isMonitor(
index)) {
193 double scale = diffT.
norm() / diffI.
norm();
194 scaleMap[detIndex] = scale;
195 its = scaleMap.find(detIndex - 1);
196 if (its == scaleMap.end()) {
197 scaleMap[detIndex - 1] = scale;
200 its->second = 0.5 * (its->second + scale);
202 if (its->second < scale)
205 if (its->second < scale)
212 detIdLast = detID[i];
214 truPosLast = truepos[i];
215 posMap[detIndex] = shift;
217 }
catch (std::out_of_range &) {
234 std::map<int, double> &scaleMap) {
236 auto &detectorInfo = WS->mutableDetectorInfo();
237 auto &componentInfo = WS->mutableComponentInfo();
239 double maxScale = -1e6, minScale = 1e6, aveScale = 0.0;
241 Progress prog(
this, 0.5, 1.0,
static_cast<int>(detectorInfo.size()));
243 for (
size_t i = 0; i < detectorInfo.size(); ++i) {
244 int idet = detectorInfo.detectorIDs()[i];
247 auto itPos = posMap.find(idet);
248 if (itPos == posMap.end())
252 const auto newPosition = detectorInfo.position(i) + itPos->second;
253 detectorInfo.setPosition(i, newPosition);
256 auto itScale = scaleMap.find(idet);
257 if (itScale != scaleMap.end()) {
258 const double scale = itScale->second;
259 if (minScale > scale)
261 if (maxScale < scale)
263 aveScale +=
fabs(1.0 - scale);
264 componentInfo.setScaleFactor(i,
V3D(1.0, scale, 1.0));
269 g_log.
debug() <<
"Range of scaling factors is " << minScale <<
" to " << maxScale <<
"\n";
270 if (0 != scaleCount) {
271 g_log.
debug() <<
"Average abs scaling fraction is " << aveScale / scaleCount <<
"\n";
273 g_log.
debug() <<
"Average abs scaling fraction cannot ba calculated "
274 "because the scale count is 0! Its value before dividing "
286 std::vector<Kernel::V3D> &pos) {
296 const int numDetector = iraw.
i_det;
297 const int *
const rawDetID = iraw.
udet;
298 const float *
const r = iraw.
len2;
299 const float *
const angle = iraw.
tthe;
302 const float *
const phi = iraw.
ut;
305 bool phiPresent = iraw.
i_use > 0 && phi[0] != 1.0 && phi[0] != 2.0;
307 g_log.
error(
"Unable to get Phi values from the raw file");
309 detID.reserve(numDetector);
310 pos.reserve(numDetector);
312 for (
int i = 0; i < numDetector; ++i) {
314 pos.emplace_back(point);
315 detID.emplace_back(rawDetID[i]);
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
float * ut
nuse UT* user tables (total size NUSE*NDET) ut01=phi
int i_use
number of user defined UTn tables NUSE
int i_det
number of detectors NDET
int readFromFile(const char *filename, bool read_data=true)
stuff
int * udet
user detector number for each detector (size NDET)
float * tthe
2theta scattering angle (size NDET)
float * len2
L2 table (size NDET)
Base class from which all concrete algorithm classes should be derived.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
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.
@ Load
allowed here which will be passed to the algorithm
Helper class for reporting progress from algorithms.
A property class for workspaces.
void exec() override
Overwrites Algorithm method.
void getDetPositionsFromRaw(const std::string &rawfile, std::vector< int > &detID, std::vector< Kernel::V3D > &pos)
read the positions of detectors defined in the raw file
bool processScalingFile(const std::string &scalingFile, std::vector< Kernel::V3D > &truePos)
Read the scaling information from a file (e.g.
std::string m_filename
The name and path of the input file.
SetScalingPSD()
Default constructor.
void movePos(API::MatrixWorkspace_sptr &WS, std::map< int, Kernel::V3D > &posMap, std::map< int, double > &scaleMap)
apply the shifts in posMap to the detectors in WS
API::MatrixWorkspace_sptr m_workspace
Pointer to the workspace.
int m_scalingOption
An integer option controlling the scaling method.
void init() override
Overwrites Algorithm method.
Records the filename and the description of failure.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
void spherical(const double R, const double theta, const double phi) noexcept
Sets the vector position based on spherical coordinates.
double norm() const noexcept
ISIS VMS raw file definitions.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
@ InOut
Both an input & output workspace.