33using namespace Kernel;
37 auto wsValidator = std::make_shared<CompositeValidator>();
42 "The name of the workspace that will be used as input for the algorithm");
45 "if set to true, the algorithm would return linear "
46 "detector's ranges (dx,dy) rather then angular ranges "
47 "(dAzimuthal,dPolar)");
49 const std::vector<std::string> fileExts{
".par",
".phx"};
52 "An optional file that contains of the list of angular "
53 "parameters for the detectors and detectors groups;\n"
54 "If specified, will use data from file instead of the data, "
55 "calculated from the instument description");
59 "If not empty, a name of a table workspace which "
60 " will contain the calculated par or phx values for the detectors");
68 const auto nHist =
static_cast<int64_t
>(inputWS->getNumberHistograms());
71 std::string fileName = this->
getProperty(
"ParFile");
72 if (!(fileName.empty() || fileName ==
"not_used.par")) {
73 if (!std::filesystem::exists(fileName)) {
74 g_log.
error() <<
" FindDetectorsPar: attempting to load par file: " << fileName <<
" but it does not exist\n";
78 if (nPars ==
static_cast<size_t>(nHist)) {
83 g_log.
warning() <<
" number of parameters in the file: " << fileName
84 <<
" not equal to the number of histograms in the workspace" << inputWS->getName() <<
'\n';
85 g_log.
warning() <<
" calculating detector parameters algorithmically\n";
90 std::vector<DetParameters> Detectors(nHist);
94 const auto progStep =
static_cast<int>(ceil(
double(nHist) / 100.0));
96 const auto &spectrumInfo = inputWS->spectrumInfo();
103 for (int64_t i = 0; i < nHist; i++) {
106 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
110 Detectors[i].detID = spectrumInfo.detector(i).getID();
117 if (i % progStep == 0) {
131 std::string output =
getProperty(
"OutputParTable");
138 }
catch (std::exception &err) {
140 "property: OutputParTableWS\n";
141 g_log.
information() <<
" findDetecotorsPar: the reason is: " << err.what() <<
'\n';
148 m_result->addColumn(
"double",
"twoTheta");
149 m_result->addColumn(
"double",
"azimuthal");
150 m_result->addColumn(
"double",
"secondary_flightpath");
152 m_result->addColumn(
"double",
"det_width");
153 m_result->addColumn(
"double",
"det_height");
155 m_result->addColumn(
"double",
"polar_width");
156 m_result->addColumn(
"double",
"azimuthal_width");
158 m_result->addColumn(
"long64",
"detID");
163 << int64_t(
detID[i]);
166 API::AnalysisDataService::Instance().addOrReplace(output, m_result);
181 double dist = baseAngle - anAngle;
183 return (anAngle + 360.);
184 }
else if (dist < -180.) {
185 return (anAngle - 360.);
201 double dist2Det, Polar, Azimut, ringPolar, ringAzim;
226 std::vector<Kernel::V3D> coord(3);
231 er = toDet / dist2Det;
235 e_tg =
V3D(1., 0., 0.);
251 double azimMin = bbox.
zMin();
252 double azimMax = bbox.
zMax();
253 double polarMin = bbox.
yMin();
255 double polarMax = bbox.
yMax();
262 double polarHalfSize =
rad2deg * atan2(0.5 * (polarMax - polarMin), dist2Det);
263 double azimHalfSize =
rad2deg * atan2(0.5 * (azimMax - azimMin), dist2Det);
265 polarMin = ringPolar - polarHalfSize;
266 polarMax = ringPolar + polarHalfSize;
267 azimMin = ringAzim - azimHalfSize;
268 azimMax = ringAzim + azimHalfSize;
311 size_t nDetectors = detector.
nDets();
317 if (nDetectors == 1) {
323 g_log.
error() <<
"calc_cylDetPar: can not downcast IDetector_sptr to "
324 "detector group for detector->ID: "
325 << detector.
getID() <<
'\n';
326 throw(std::bad_cast());
328 for (
const auto &det : detGroup->getDetectors()) {
342 nDetectors = detPar.size();
345 this->
polar.resize(nDetectors);
349 this->
detID.resize(nDetectors);
352 for (
const auto ¶meter : detPar) {
353 if (parameter.detID < 0)
356 azimuthal[nDetectors] = parameter.azimutAngle;
357 polar[nDetectors] = parameter.polarAngle;
359 polarWidth[nDetectors] = parameter.polarWidth;
361 detID[nDetectors] =
static_cast<size_t>(parameter.detID);
369 this->
polar.resize(nDetectors);
373 this->
detID.resize(nDetectors);
379 std::ifstream dataStream;
380 std::vector<double> result;
392 int Block_size, shift;
403 azimuthal[i] = result[shift + 2 + i * Block_size];
404 polar[i] = result[shift + 1 + i * Block_size];
406 polarWidth[i] = result[shift + 4 + i * Block_size];
418 azimuthal[i] = result[shift + 2 + i * Block_size];
419 polar[i] = result[shift + 1 + i * Block_size];
421 polarWidth[i] = result[shift + 3 + i * Block_size];
425 g_log.
error() <<
" unsupported type of ASCII parameter file: " << fileName <<
'\n';
426 throw(std::invalid_argument(
"unsupported ASCII file type"));
433 size_t nHist = inputWS->getNumberHistograms();
438 for (
size_t i = 0; i < nHist; i++) {
444 const auto &spectrumInfo = inputWS->spectrumInfo();
446 for (
size_t i = 0; i < nHist; i++) {
447 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
458 int space_to_symbol_change(0);
459 size_t symbols_start(0);
461 for (
size_t i = 0; i < buf_size; i++) {
473 for (
size_t i = symbols_start; i < buf_size; i++) {
476 if (Buf[i] >=
'+' && Buf[i] <=
'z') {
479 space_to_symbol_change++;
486 return space_to_symbol_change;
495 for (i = 0; i < buf_size; i++) {
497 if (buf[i] == DELIM) {
502 buf[buf_size - 1] = 0;
503 g_log.
information() <<
" data obtained from ASCII data file trunkated to " << buf_size <<
" characters\n";
518 std::vector<char> buffer(1024);
522 data_stream.open(fileName.c_str(), std::ios_base::in | std::ios_base::binary);
523 if (!data_stream.is_open()) {
524 g_log.
error() <<
" can not open existing ASCII data file: " << fileName <<
'\n';
531 data_stream.get(symbol);
532 while (symbol > 0x1F) {
533 data_stream.get(symbol);
536 if (symbol == 0x0D) {
537 data_stream.get(symbol);
538 if (symbol == 0x0A) {
542 data_stream.putback(symbol);
544 }
else if (symbol == 0x0A) {
547 g_log.
error() <<
" Error reading the first row of the input ASCII data file: " << fileName
548 <<
" as it contains unprintable characters\n";
550 "input ASCII data file, as it contains "
551 "unprintable characters",
556 data_stream.seekg(0, std::ios::beg);
558 get_my_line(data_stream, buffer.data(), buffer.size(), EOL);
559 if (!data_stream.good()) {
560 g_log.
error() <<
" Error reading the first row of the input data file " << fileName
561 <<
", It may be bigger then 1024 symbols\n";
563 "input data file, It may be bigger then "
569 int space_to_symbol_change =
count_changes(buffer.data(), buffer.size());
570 if (space_to_symbol_change > 1) {
571 int nData_records(0), nData_blocks(0);
573 int nDatas = sscanf(buffer.data(),
" %d %d ", &nData_records, &nData_blocks);
574 file_descriptor.
nData_records =
static_cast<size_t>(nData_records);
575 file_descriptor.
nData_blocks =
static_cast<size_t>(nData_blocks);
578 <<
" iterpreted as SPE but does "
579 "not have two numbers in the "
582 "have two numbers in the first row",
586 get_my_line(data_stream, buffer.data(), buffer.size(), EOL);
587 if (buffer.front() !=
'#') {
588 g_log.
error() <<
" File " << fileName <<
"iterpreted as SPE does not have symbol # in the second row\n";
600 data_stream.getline(buffer.data(), buffer.size(), EOL);
602 space_to_symbol_change =
count_changes(buffer.data(), buffer.size());
603 if (space_to_symbol_change == 6 || space_to_symbol_change == 5) {
606 }
else if (space_to_symbol_change == 7) {
610 g_log.
error() <<
" can not identify format of the input data file " << fileName <<
'\n';
614 return file_descriptor;
624 std::vector<char> BUF(1024, 0);
625 char par_format[] =
" %g %g %g %g %g";
626 char phx_format[] =
" %g %g %g %g %g %g";
632 switch (FILE_TYPE.
Type) {
644 g_log.
error() <<
" trying to load data in FindDetectorsPar::load_plain but "
645 "the data type is not recognized\n";
646 throw(std::invalid_argument(
" trying to load data but the data type is not recognized"));
652 if (!stream.good()) {
653 g_log.
error() <<
" can not rewind the file to the initial position where "
655 throw(std::invalid_argument(
" can not rewind the file to the initial "
656 "position where the data begin"));
661 stream.getline(BUF.data(), BUF.size(), EOL);
662 if (!stream.good()) {
663 g_log.
error() <<
" error reading input file\n";
664 throw(std::invalid_argument(
" error reading input file"));
667 switch (FILE_TYPE.
Type) {
669 nRead_Data = sscanf(BUF.data(), format, data_buf, data_buf + 1, data_buf + 2, data_buf + 3, data_buf + 4);
674 sscanf(BUF.data(), format, data_buf, data_buf + 1, data_buf + 2, data_buf + 3, data_buf + 4, data_buf + 5);
678 g_log.
error() <<
" unsupported value of FILE_TYPE.Type: " << FILE_TYPE.
Type <<
'\n';
679 throw(std::invalid_argument(
" unsupported value of FILE_TYPE.Type"));
682 if (nRead_Data != BlockSize) {
683 g_log.
error() <<
" Error reading data at file, row " << i + 1 <<
" column " << nRead_Data <<
" from total "
684 << FILE_TYPE.
nData_records <<
" rows, " << BlockSize <<
" columns\n";
685 throw(std::invalid_argument(
"error while interpreting data "));
687 for (
int j = 0; j < nRead_Data; j++) {
688 Data[i * BlockSize + j] =
static_cast<double>(data_buf[j]);
#define DECLARE_ALGORITHM(classname)
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_FOR_NO_WSP_CHECK()
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
A validator which provides a TENTATIVE check that a workspace contains common bins in each spectrum.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
A validator which checks that a workspace has a valid instrument.
Helper class for reporting progress from algorithms.
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
helper class-collection to keep together the parameters, which characterize average composite detecto...
void addDetInfo(const Geometry::IDetector &det, const Kernel::V3D &Observer)
method to cacluate the detectors parameters and add them to the detectors averages
static double nearAngle(const double &baseAngle, const double &anAngle)
method calculates an angle closest to the initial one taken on a ring e.g.
size_t m_nComponents
numbr of primary detectors, contributing into this detector
void returnAvrgDetPar(DetParameters &avrgDet)
Method processes accumulated averages and return them in preexistent avrgDet class.
void setUseSpherical(bool shouldWe=true)
Small helper class-holder used to precalculate the detectors parameters in spherical coordinate syste...
double azimWidth
linear or angular size of the bounding box encapsulating detector and alighned tangentially to the co...
double azimutAngle
azimuthal detector's angle in spherical coordinate system alighned with the beam
double secondaryFlightPath
scattering source – detector' distance
double polarAngle
polar detector's angle in spherical coordinate system alighned with the beam
size_t loadParFile(const std::string &fileName)
load data from par or phx file;
void populate_values_from_file(const API::MatrixWorkspace_sptr &inputWS)
functions used to populate data from the phx or par file
std::vector< size_t > detID
std::vector< double > polar
std::vector< double > secondaryFlightpath
void setOutputTable()
internal function which sets the output table according to the algorithms properties
void load_plain(std::ifstream &stream, std::vector< double > &Data, FileTypeDescriptor const &FILE_TYPE)
load PAR or PHX file
void extractAndLinearize(const std::vector< DetParameters > &detPar)
extract valid detectors parameters into vectors above
std::vector< double > azimuthalWidth
bool m_SizesAreLinear
the variable defines if algorithm needs to calculate linear ranges for the detectors (dX,...
void exec() override
Virtual method - must be overridden by concrete algorithm.
std::vector< double > azimuthal
void init() override
Virtual method - must be overridden by concrete algorithm.
int count_changes(const char *const Buf, size_t buf_size)
! function calculates number of colums in an ASCII file, assuming that colums are separated by spaces
size_t get_my_line(std::ifstream &in, char *buf, size_t buf_size, const char DELIM)
! The function reads line from input stream and puts it into buffer.
void calcDetPar(const Geometry::IDetector &detector, const Kernel::V3D &observer, DetParameters &detParameters)
Method calculates averaged polar coordinates of the detector's group (which may consist of one detect...
FileTypeDescriptor get_ASCII_header(std::string const &fileName, std::ifstream &data_stream)
load file header and identify which file (PHX,PAR or SPE) it belongs to.
std::vector< double > polarWidth
FileTypeDescriptor current_ASCII_file
if ASCII file is selected as the datasource, this structure describes the type of this file.
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
void setBoxAlignment(const Kernel::V3D &R0, const std::vector< Kernel::V3D > &orts)
change the BB alighnment, providing new coordinate system to alighn it to.
double zMin() const
Return the minimum value of Z.
double zMax() const
Return the maximum value of Z.
double yMax() const
Return the maximum value of Y.
double yMin() const
Return the minimum value of Y.
Holds a collection of detectors.
virtual Kernel::V3D getPos() const =0
Get the position of the IComponent. Tree structure is traverse through the.
virtual void getBoundingBox(BoundingBox &boundingBox) const =0
Get the bounding box for this component and store it in the given argument.
Interface class for detector objects.
virtual std::size_t nDets() const =0
Get the number of physical detectors this object represents.
virtual detid_t getID() const =0
Get the detector ID.
Records the filename and the description of failure.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
double normalize()
Make a normalized vector (return norm value)
constexpr V3D cross_prod(const V3D &v) const noexcept
Cross product (this * argument)
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
constexpr double Z() const noexcept
Get z.
bool nullVector(const double tolerance=1e-3) const noexcept
Determine if the point is null.
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
Description of the ASCII data header, common for all ASCII PAR and PHX files.
std::streampos data_start_position
@ Input
An input workspace.
@ Output
An output workspace.