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 (!Poco::File(fileName).
exists()) {
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]);
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;
312 size_t nDetectors = detector.
nDets();
318 if (nDetectors == 1) {
324 g_log.
error() <<
"calc_cylDetPar: can not downcast IDetector_sptr to "
325 "detector group for detector->ID: "
326 << detector.
getID() <<
'\n';
327 throw(std::bad_cast());
329 for (
const auto &det : detGroup->getDetectors()) {
343 nDetectors = detPar.size();
346 this->
polar.resize(nDetectors);
350 this->
detID.resize(nDetectors);
353 for (
const auto ¶meter : detPar) {
354 if (parameter.detID < 0)
357 azimuthal[nDetectors] = parameter.azimutAngle;
358 polar[nDetectors] = parameter.polarAngle;
360 polarWidth[nDetectors] = parameter.polarWidth;
362 detID[nDetectors] =
static_cast<size_t>(parameter.detID);
370 this->
polar.resize(nDetectors);
374 this->
detID.resize(nDetectors);
380 std::ifstream dataStream;
381 std::vector<double> result;
393 int Block_size, shift;
404 azimuthal[i] = result[shift + 2 + i * Block_size];
405 polar[i] = result[shift + 1 + i * Block_size];
407 polarWidth[i] = result[shift + 4 + i * Block_size];
419 azimuthal[i] = result[shift + 2 + i * Block_size];
420 polar[i] = result[shift + 1 + i * Block_size];
422 polarWidth[i] = result[shift + 3 + i * Block_size];
426 g_log.
error() <<
" unsupported type of ASCII parameter file: " << fileName <<
'\n';
427 throw(std::invalid_argument(
"unsupported ASCII file type"));
434 size_t nHist = inputWS->getNumberHistograms();
439 for (
size_t i = 0; i < nHist; i++) {
445 const auto &spectrumInfo = inputWS->spectrumInfo();
447 for (
size_t i = 0; i < nHist; i++) {
448 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
458 bool is_symbol(
false), is_space(
true);
459 int space_to_symbol_change(0), symbol_to_space_change(0);
460 size_t symbols_start(0);
462 for (
size_t i = 0; i < buf_size; i++) {
474 for (
size_t i = symbols_start; i < buf_size; i++) {
477 if (Buf[i] >=
'+' && Buf[i] <=
'z') {
480 space_to_symbol_change++;
487 symbol_to_space_change++;
492 return space_to_symbol_change;
501 for (i = 0; i < buf_size; i++) {
503 if (buf[i] == DELIM) {
508 buf[buf_size - 1] = 0;
509 g_log.
information() <<
" data obtained from ASCII data file trunkated to " << buf_size <<
" characters\n";
524 std::vector<char> buffer(1024);
528 data_stream.open(fileName.c_str(), std::ios_base::in | std::ios_base::binary);
529 if (!data_stream.is_open()) {
530 g_log.
error() <<
" can not open existing ASCII data file: " << fileName <<
'\n';
537 data_stream.get(symbol);
538 while (symbol > 0x1F) {
539 data_stream.get(symbol);
542 if (symbol == 0x0D) {
543 data_stream.get(symbol);
544 if (symbol == 0x0A) {
548 data_stream.putback(symbol);
550 }
else if (symbol == 0x0A) {
553 g_log.
error() <<
" Error reading the first row of the input ASCII data file: " << fileName
554 <<
" as it contains unprintable characters\n";
556 "input ASCII data file, as it contains "
557 "unprintable characters",
562 data_stream.seekg(0, std::ios::beg);
564 get_my_line(data_stream, buffer.data(), buffer.size(), EOL);
565 if (!data_stream.good()) {
566 g_log.
error() <<
" Error reading the first row of the input data file " << fileName
567 <<
", It may be bigger then 1024 symbols\n";
569 "input data file, It may be bigger then "
575 int space_to_symbol_change =
count_changes(buffer.data(), buffer.size());
576 if (space_to_symbol_change > 1) {
577 int nData_records(0), nData_blocks(0);
579 int nDatas = sscanf(buffer.data(),
" %d %d ", &nData_records, &nData_blocks);
580 file_descriptor.
nData_records =
static_cast<size_t>(nData_records);
581 file_descriptor.
nData_blocks =
static_cast<size_t>(nData_blocks);
584 <<
" iterpreted as SPE but does "
585 "not have two numbers in the "
588 "have two numbers in the first row",
592 get_my_line(data_stream, buffer.data(), buffer.size(), EOL);
593 if (buffer.front() !=
'#') {
594 g_log.
error() <<
" File " << fileName <<
"iterpreted as SPE does not have symbol # in the second row\n";
606 data_stream.getline(buffer.data(), buffer.size(), EOL);
608 space_to_symbol_change =
count_changes(buffer.data(), buffer.size());
609 if (space_to_symbol_change == 6 || space_to_symbol_change == 5) {
612 }
else if (space_to_symbol_change == 7) {
616 g_log.
error() <<
" can not identify format of the input data file " << fileName <<
'\n';
620 return file_descriptor;
630 std::vector<char> BUF(1024, 0);
631 char par_format[] =
" %g %g %g %g %g";
632 char phx_format[] =
" %g %g %g %g %g %g";
638 switch (FILE_TYPE.
Type) {
650 g_log.
error() <<
" trying to load data in FindDetectorsPar::load_plain but "
651 "the data type is not recognized\n";
652 throw(std::invalid_argument(
" trying to load data but the data type is not recognized"));
658 if (!stream.good()) {
659 g_log.
error() <<
" can not rewind the file to the initial position where "
661 throw(std::invalid_argument(
" can not rewind the file to the initial "
662 "position where the data begin"));
667 stream.getline(BUF.data(), BUF.size(), EOL);
668 if (!stream.good()) {
669 g_log.
error() <<
" error reading input file\n";
670 throw(std::invalid_argument(
" error reading input file"));
673 switch (FILE_TYPE.
Type) {
675 nRead_Data = sscanf(BUF.data(), format, data_buf, data_buf + 1, data_buf + 2, data_buf + 3, data_buf + 4);
680 sscanf(BUF.data(), format, data_buf, data_buf + 1, data_buf + 2, data_buf + 3, data_buf + 4, data_buf + 5);
684 g_log.
error() <<
" unsupported value of FILE_TYPE.Type: " << FILE_TYPE.
Type <<
'\n';
685 throw(std::invalid_argument(
" unsupported value of FILE_TYPE.Type"));
688 if (nRead_Data != BlockSize) {
689 g_log.
error() <<
" Error reading data at file, row " << i + 1 <<
" column " << nRead_Data <<
" from total "
690 << FILE_TYPE.
nData_records <<
" rows, " << BlockSize <<
" columns\n";
691 throw(std::invalid_argument(
"error while interpreting data "));
693 for (
int j = 0; j < nRead_Data; j++) {
694 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
bool exists(::NeXus::File &file, const std::string &name)
Based on the current group in the file, does the named sub-entry exist?
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.