Mantid
Loading...
Searching...
No Matches
FindDetectorsPar.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 +
8
15#include "MantidAPI/TableRow.h"
17
21
25
26#include <filesystem>
27#include <limits>
28
29namespace Mantid::DataHandling {
30// Register the algorithm into the algorithm factory
31DECLARE_ALGORITHM(FindDetectorsPar)
32
33using namespace Kernel;
34using namespace API;
35
37 auto wsValidator = std::make_shared<CompositeValidator>();
38 wsValidator->add<API::InstrumentValidator>();
39 wsValidator->add<API::CommonBinsValidator>();
40 // input workspace
41 declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input, wsValidator),
42 "The name of the workspace that will be used as input for the algorithm");
43 //
44 declareProperty("ReturnLinearRanges", false,
45 "if set to true, the algorithm would return linear "
46 "detector's ranges (dx,dy) rather then angular ranges "
47 "(dAzimuthal,dPolar)");
48 // optional par or phx file
49 const std::vector<std::string> fileExts{".par", ".phx"};
50
51 declareProperty(std::make_unique<FileProperty>("ParFile", "not_used.par", FileProperty::OptionalLoad, fileExts),
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");
56
57 //
58 declareProperty("OutputParTable", "",
59 "If not empty, a name of a table workspace which "
60 " will contain the calculated par or phx values for the detectors");
61}
62
64
65 // Get the input workspace
66 const MatrixWorkspace_sptr inputWS = this->getProperty("InputWorkspace");
67 // Number of spectra
68 const auto nHist = static_cast<int64_t>(inputWS->getNumberHistograms());
69
70 // try to load par file if one is availible
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";
75 throw(Kernel::Exception::FileError(" file not exist", fileName));
76 }
77 size_t nPars = loadParFile(fileName);
78 if (nPars == static_cast<size_t>(nHist)) {
79 this->populate_values_from_file(inputWS);
80 this->setOutputTable();
81 return;
82 } else {
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";
86 }
87 }
88 m_SizesAreLinear = this->getProperty("ReturnLinearRanges");
89
90 std::vector<DetParameters> Detectors(nHist);
91 this->m_nDetectors = 0;
92
93 Progress progress(this, 0.0, 1.0, 100);
94 const auto progStep = static_cast<int>(ceil(double(nHist) / 100.0));
95
96 const auto &spectrumInfo = inputWS->spectrumInfo();
97
98 // define the centre of coordinates:
99 Kernel::V3D Observer = spectrumInfo.samplePosition();
100
101 // Loop over the spectra
103 for (int64_t i = 0; i < nHist; i++) {
105 // Check that we aren't writing a monitor...
106 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
107 continue;
108
109 // valid detector has valid detID
110 Detectors[i].detID = spectrumInfo.detector(i).getID();
111
112 // calculate all parameters for current composite detector
113 calcDetPar(spectrumInfo.detector(i), Observer, Detectors[i]);
114
115 // make regular progress reports and check for canceling the algorithm
116
117 if (i % progStep == 0) {
118 progress.report();
119 }
121 }
123
124 this->extractAndLinearize(Detectors);
125 // if necessary set up table workspace with detectors parameters.
126 this->setOutputTable();
127}
128
131 std::string output = getProperty("OutputParTable");
132 if (output.empty())
133 return;
134 // Store the result in a table workspace
135 try {
137 std::make_unique<WorkspaceProperty<API::ITableWorkspace>>("OutputParTableWS", "", Direction::Output));
138 } catch (std::exception &err) {
139 g_log.information() << " findDetecotorsPar: unsuccessfully declaring "
140 "property: OutputParTableWS\n";
141 g_log.information() << " findDetecotorsPar: the reason is: " << err.what() << '\n';
142 }
143
144 // Set the name of the new workspace
145 setPropertyValue("OutputParTableWS", output);
146
147 Mantid::API::ITableWorkspace_sptr m_result = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
148 m_result->addColumn("double", "twoTheta");
149 m_result->addColumn("double", "azimuthal");
150 m_result->addColumn("double", "secondary_flightpath");
151 if (m_SizesAreLinear) {
152 m_result->addColumn("double", "det_width");
153 m_result->addColumn("double", "det_height");
154 } else {
155 m_result->addColumn("double", "polar_width");
156 m_result->addColumn("double", "azimuthal_width");
157 }
158 m_result->addColumn("long64", "detID");
159
160 for (size_t i = 0; i < m_nDetectors; i++) {
161 Mantid::API::TableRow row = m_result->appendRow();
162 row << polar[i] << azimuthal[i] << secondaryFlightpath[i] << polarWidth[i] << azimuthalWidth[i]
163 << int64_t(detID[i]);
164 }
165 setProperty("OutputParTableWS", m_result);
166 API::AnalysisDataService::Instance().addOrReplace(output, m_result);
167}
168
169// Constant for converting Radians to Degrees
170constexpr double rad2deg = 180.0 / M_PI;
171
180double AvrgDetector::nearAngle(const double &baseAngle, const double &anAngle) {
181 double dist = baseAngle - anAngle;
182 if (dist > 180.) {
183 return (anAngle + 360.);
184 } else if (dist < -180.) {
185 return (anAngle - 360.);
186 } else
187 return anAngle;
188}
189
198 Kernel::V3D detPos = det.getPos();
199 Kernel::V3D toDet = (detPos - Observer);
200
201 double dist2Det, Polar, Azimut, ringPolar, ringAzim;
202 // identify the detector' position in the beam coordinate system:
203 toDet.getSpherical(dist2Det, Polar, Azimut);
204 if (m_nComponents <= 1) {
205 m_FlightPathSum = dist2Det;
206 m_PolarSum = Polar;
207 m_AzimutSum = Azimut;
208
209 m_AzimBase = Polar;
210 m_PolarBase = Azimut;
211 ringPolar = Polar;
212 ringAzim = Azimut;
213 } else {
214 ringPolar = nearAngle(m_AzimBase, Polar);
215 ringAzim = nearAngle(m_PolarBase, Azimut);
216 m_FlightPathSum += dist2Det;
217 m_PolarSum += ringPolar;
218 m_AzimutSum += ringAzim;
219 }
220
221 // centre of the azimuthal ring (the ring detectors form around the beam)
222 Kernel::V3D ringCentre(0, 0, toDet.Z());
223
224 // Get the bounding box
226 std::vector<Kernel::V3D> coord(3);
227
228 // ez along beamline, which is always oz;
229 Kernel::V3D er(0, 1, 0), ez(0, 0, 1);
230 if (dist2Det != 0.0)
231 er = toDet / dist2Det; // direction to the detector
232 // tangential to the ring and anticlockwise.
233 Kernel::V3D e_tg = er.cross_prod(ez);
234 if (e_tg.nullVector(1e-12)) {
235 e_tg = V3D(1., 0., 0.);
236 } else {
237 e_tg.normalize();
238 }
239 // make orthogonal -- projections are calculated in this coordinate system
240 ez = e_tg.cross_prod(er);
241
242 coord[0] = er; // new X
243 coord[1] = ez; // new y
244 coord[2] = e_tg; // new z
245 bbox.setBoxAlignment(ringCentre, coord);
246
247 det.getBoundingBox(bbox);
248
249 // linear extensions of the bounding box orientied tangentially to the equal
250 // scattering angle circle
251 double azimMin = bbox.zMin();
252 double azimMax = bbox.zMax();
253 double polarMin = bbox.yMin(); // bounding box has been rotated according to
254 // coord above, so z is along e_tg
255 double polarMax = bbox.yMax();
256
258 if (dist2Det == 0)
259 dist2Det = 1;
260
261 // convert to angular units
262 double polarHalfSize = rad2deg * atan2(0.5 * (polarMax - polarMin), dist2Det);
263 double azimHalfSize = rad2deg * atan2(0.5 * (azimMax - azimMin), dist2Det);
264
265 polarMin = ringPolar - polarHalfSize;
266 polarMax = ringPolar + polarHalfSize;
267 azimMin = ringAzim - azimHalfSize;
268 azimMax = ringAzim + azimHalfSize;
269 }
270 if (m_AzimMin > azimMin)
271 m_AzimMin = azimMin;
272 if (m_AzimMax < azimMax)
273 m_AzimMax = azimMax;
274
275 if (m_PolarMin > polarMin)
276 m_PolarMin = polarMin;
277 if (m_PolarMax < polarMax)
278 m_PolarMax = polarMax;
279}
280
285
286 // return undefined detector parameters if no average detector is defined;
287 if (m_nComponents == 0)
288 return;
289
290 avrgDet.azimutAngle = m_AzimutSum / double(m_nComponents);
291 avrgDet.polarAngle = m_PolarSum / double(m_nComponents);
293
294 avrgDet.azimWidth = (m_AzimMax - m_AzimMin);
295 avrgDet.polarWidth = (m_PolarMax - m_PolarMin);
296}
308 DetParameters &detParameters) {
309
310 // get number of basic detectors within the composit detector
311 size_t nDetectors = detector.nDets();
312 // define summator
313 AvrgDetector detSum;
314 // do we want spherical or linear box sizes?
316
317 if (nDetectors == 1) {
318 detSum.addDetInfo(detector, observer);
319 } else {
320 // access contributing detectors;
321 auto detGroup = dynamic_cast<const Geometry::DetectorGroup *>(&detector);
322 if (!detGroup) {
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());
327 }
328 for (const auto &det : detGroup->getDetectors()) {
329 detSum.addDetInfo(*det, observer);
330 }
331 }
332 // calculate averages and return the detector parameters
333 detSum.returnAvrgDetPar(detParameters);
334}
338void FindDetectorsPar::extractAndLinearize(const std::vector<DetParameters> &detPar) {
339 size_t nDetectors;
340
341 // provisional number
342 nDetectors = detPar.size();
343
344 this->azimuthal.resize(nDetectors);
345 this->polar.resize(nDetectors);
346 this->azimuthalWidth.resize(nDetectors);
347 this->polarWidth.resize(nDetectors);
348 this->secondaryFlightpath.resize(nDetectors);
349 this->detID.resize(nDetectors);
350
351 nDetectors = 0;
352 for (const auto &parameter : detPar) {
353 if (parameter.detID < 0)
354 continue;
355
356 azimuthal[nDetectors] = parameter.azimutAngle;
357 polar[nDetectors] = parameter.polarAngle;
358 azimuthalWidth[nDetectors] = parameter.azimWidth;
359 polarWidth[nDetectors] = parameter.polarWidth;
360 secondaryFlightpath[nDetectors] = parameter.secondaryFlightPath;
361 detID[nDetectors] = static_cast<size_t>(parameter.detID);
362 nDetectors++;
363 }
364 // store caluclated value
365 m_nDetectors = nDetectors;
366
367 // resize to actual detector's number
368 this->azimuthal.resize(nDetectors);
369 this->polar.resize(nDetectors);
370 this->azimuthalWidth.resize(nDetectors);
371 this->polarWidth.resize(nDetectors);
372 this->secondaryFlightpath.resize(nDetectors);
373 this->detID.resize(nDetectors);
374}
375
376//
377size_t FindDetectorsPar::loadParFile(const std::string &fileName) {
378 // load ASCII par or phx file
379 std::ifstream dataStream;
380 std::vector<double> result;
381 this->current_ASCII_file = get_ASCII_header(fileName, dataStream);
382 load_plain(dataStream, result, current_ASCII_file);
383
385
386 dataStream.close();
387 // transfer par data into internal algorithm parameters;
388 azimuthal.resize(m_nDetectors);
389 polar.resize(m_nDetectors);
390 detID.resize(m_nDetectors);
391
392 int Block_size, shift;
393
395 m_SizesAreLinear = true;
396 Block_size = 5; // this value coinside with the value defined in load_plain
397 shift = 0;
399 polarWidth.resize(m_nDetectors);
400 secondaryFlightpath.resize(m_nDetectors, std::numeric_limits<double>::quiet_NaN());
401
402 for (size_t i = 0; i < m_nDetectors; i++) {
403 azimuthal[i] = result[shift + 2 + i * Block_size];
404 polar[i] = result[shift + 1 + i * Block_size];
405 azimuthalWidth[i] = -result[shift + 3 + i * Block_size];
406 polarWidth[i] = result[shift + 4 + i * Block_size];
407 secondaryFlightpath[i] = result[shift + 0 + i * Block_size];
408 detID[i] = i + 1;
409 }
410
411 } else if (current_ASCII_file.Type == PHX_type) {
412 m_SizesAreLinear = false;
413 Block_size = 6; // this value coinside with the value defined in load_plain
414 shift = 1;
416 polarWidth.resize(m_nDetectors);
417 for (size_t i = 0; i < m_nDetectors; i++) {
418 azimuthal[i] = result[shift + 2 + i * Block_size];
419 polar[i] = result[shift + 1 + i * Block_size];
420 azimuthalWidth[i] = result[shift + 4 + i * Block_size];
421 polarWidth[i] = result[shift + 3 + i * Block_size];
422 detID[i] = i + 1;
423 }
424 } else {
425 g_log.error() << " unsupported type of ASCII parameter file: " << fileName << '\n';
426 throw(std::invalid_argument("unsupported ASCII file type"));
427 }
428
429 return m_nDetectors;
430}
431//
433 size_t nHist = inputWS->getNumberHistograms();
434
435 if (this->current_ASCII_file.Type == PAR_type) {
436 // in this case data in azimuthal width and polar width are in fact real
437 // sizes in meters; have to transform it in into angular values
438 for (size_t i = 0; i < nHist; i++) {
441 }
442 m_SizesAreLinear = false;
443 } else {
444 const auto &spectrumInfo = inputWS->spectrumInfo();
445 secondaryFlightpath.resize(nHist);
446 for (size_t i = 0; i < nHist; i++) {
447 if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
448 continue;
451 secondaryFlightpath[i] = spectrumInfo.l2(i);
452 }
453 }
454}
455//
456int FindDetectorsPar::count_changes(const char *const Buf, size_t buf_size) {
457 bool is_space(true);
458 int space_to_symbol_change(0);
459 size_t symbols_start(0);
460 // supress leading spaces;
461 for (size_t i = 0; i < buf_size; i++) {
462 if (Buf[i] == 0)
463 break;
464 if (Buf[i] == ' ') {
465 continue;
466 } else {
467 symbols_start = i;
468 break;
469 }
470 }
471 // calculate number of changes from space to symbol assuming start from
472 // symbol;
473 for (size_t i = symbols_start; i < buf_size; i++) {
474 if (Buf[i] == 0)
475 break;
476 if (Buf[i] >= '+' && Buf[i] <= 'z') { // this is a symbol
477 if (is_space) {
478 is_space = false;
479 space_to_symbol_change++;
480 }
481 }
482 if (Buf[i] == ' ') { // this is a space
483 is_space = true;
484 }
485 }
486 return space_to_symbol_change;
487}
488
493size_t FindDetectorsPar::get_my_line(std::ifstream &in, char *buf, size_t buf_size, const char DELIM) {
494 size_t i;
495 for (i = 0; i < buf_size; i++) {
496 in.get(buf[i]);
497 if (buf[i] == DELIM) {
498 buf[i] = 0;
499 return i;
500 }
501 }
502 buf[buf_size - 1] = 0;
503 g_log.information() << " data obtained from ASCII data file trunkated to " << buf_size << " characters\n";
504 return buf_size;
505}
517FileTypeDescriptor FindDetectorsPar::get_ASCII_header(std::string const &fileName, std::ifstream &data_stream) {
518 std::vector<char> buffer(1024);
519 FileTypeDescriptor file_descriptor;
520 file_descriptor.Type = NumFileTypes; // set the autotype to invalid
521
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';
525 throw(Kernel::Exception::FileError(" Can not open existing input data file", fileName));
526 }
527 // let's identify the EOL symbol; As the file may have been prepared on
528 // different OS, from where you are reading it
529 // and no conversion have been performed;
530 char symbol;
531 data_stream.get(symbol);
532 while (symbol > 0x1F) {
533 data_stream.get(symbol);
534 }
535 char EOL;
536 if (symbol == 0x0D) { // Win or old Mac file
537 data_stream.get(symbol);
538 if (symbol == 0x0A) { // Windows file
539 EOL = 0x0A;
540 } else { // Mac
541 EOL = 0x0D;
542 data_stream.putback(symbol);
543 }
544 } else if (symbol == 0x0A) { // unix file.
545 EOL = 0x0A;
546 } else {
547 g_log.error() << " Error reading the first row of the input ASCII data file: " << fileName
548 << " as it contains unprintable characters\n";
549 throw(Kernel::Exception::FileError(" Error reading the first row of the "
550 "input ASCII data file, as it contains "
551 "unprintable characters",
552 fileName));
553 }
554
555 file_descriptor.line_end = EOL;
556 data_stream.seekg(0, std::ios::beg);
557
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";
562 throw(Kernel::Exception::FileError(" Error reading the first row of the "
563 "input data file, It may be bigger then "
564 "1024 symbols",
565 fileName));
566 }
567
568 // let's find if there is one or more groups of symbols inside of the buffer;
569 int space_to_symbol_change = count_changes(buffer.data(), buffer.size());
570 if (space_to_symbol_change > 1) { // more then one group of symbols in the string, spe file
571 int nData_records(0), nData_blocks(0);
572
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);
576 if (nDatas != 2) {
577 g_log.error() << " File " << fileName
578 << " iterpreted as SPE but does "
579 "not have two numbers in the "
580 "first row\n";
581 throw(Kernel::Exception::FileError(" File iterpreted as SPE but does not "
582 "have two numbers in the first row",
583 fileName));
584 }
585 file_descriptor.Type = SPE_type;
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";
589 throw(Kernel::Exception::FileError(" File iterpreted as SPE does not have symbol # in the second row", fileName));
590 }
591 file_descriptor.data_start_position = data_stream.tellg(); // if it is SPE file then the data begin after the
592 // second line;
593 } else {
594 file_descriptor.data_start_position = data_stream.tellg(); // if it is PHX or PAR file then the data begin
595 // after the first line;
596 file_descriptor.nData_records = std::stoi(buffer.data());
597 file_descriptor.nData_blocks = 0;
598
599 // let's ifendify now if is PHX or PAR file;
600 data_stream.getline(buffer.data(), buffer.size(), EOL);
601
602 space_to_symbol_change = count_changes(buffer.data(), buffer.size());
603 if (space_to_symbol_change == 6 || space_to_symbol_change == 5) { // PAR file
604 file_descriptor.Type = PAR_type;
605 file_descriptor.nData_blocks = space_to_symbol_change;
606 } else if (space_to_symbol_change == 7) { // PHX file
607 file_descriptor.Type = PHX_type;
608 file_descriptor.nData_blocks = space_to_symbol_change;
609 } else { // something unclear or damaged
610 g_log.error() << " can not identify format of the input data file " << fileName << '\n';
611 throw(Kernel::Exception::FileError(" can not identify format of the input data file", fileName));
612 }
613 }
614 return file_descriptor;
615}
616
622void FindDetectorsPar::load_plain(std::ifstream &stream, std::vector<double> &Data,
623 FileTypeDescriptor const &FILE_TYPE) {
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";
627 float data_buf[7];
628 const char *format;
629 int BlockSize;
630 char EOL = FILE_TYPE.line_end;
631
632 switch (FILE_TYPE.Type) {
633 case (PAR_type): {
634 format = par_format;
635 BlockSize = 5;
636 break;
637 }
638 case (PHX_type): {
639 format = phx_format;
640 BlockSize = 6;
641 break;
642 }
643 default: {
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"));
647 }
648 }
649 Data.resize(BlockSize * FILE_TYPE.nData_records);
650
651 stream.seekg(FILE_TYPE.data_start_position, std::ios_base::beg);
652 if (!stream.good()) {
653 g_log.error() << " can not rewind the file to the initial position where "
654 "the data begin\n";
655 throw(std::invalid_argument(" can not rewind the file to the initial "
656 "position where the data begin"));
657 }
658
659 int nRead_Data(0);
660 for (unsigned int i = 0; i < FILE_TYPE.nData_records; i++) {
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"));
665 }
666
667 switch (FILE_TYPE.Type) {
668 case (PAR_type): {
669 nRead_Data = sscanf(BUF.data(), format, data_buf, data_buf + 1, data_buf + 2, data_buf + 3, data_buf + 4);
670 break;
671 }
672 case (PHX_type): {
673 nRead_Data =
674 sscanf(BUF.data(), format, data_buf, data_buf + 1, data_buf + 2, data_buf + 3, data_buf + 4, data_buf + 5);
675 break;
676 }
677 default: {
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"));
680 }
681 }
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 "));
686 }
687 for (int j = 0; j < nRead_Data; j++) {
688 Data[i * BlockSize + j] = static_cast<double>(data_buf[j]);
689 }
690 }
691}
692
693} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
#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.
Kernel::Logger & g_log
Definition Algorithm.h:422
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.
Definition Progress.h:25
TableRow represents a row in a TableWorkspace.
Definition TableRow.h:39
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
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
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.
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.
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.
Definition BoundingBox.h:33
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.
Definition BoundingBox.h:85
double zMax() const
Return the maximum value of Z.
Definition BoundingBox.h:87
double yMax() const
Return the maximum value of Y.
Definition BoundingBox.h:83
double yMin() const
Return the minimum value of Y.
Definition BoundingBox.h:81
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.
Definition IDetector.h:43
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.
Definition Exception.h:98
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.
Definition Logger.cpp:108
void warning(const std::string &msg)
Logs at warning level.
Definition Logger.cpp:117
void information(const std::string &msg)
Logs at information level.
Definition Logger.cpp:136
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Class for 3D vectors.
Definition V3D.h:34
double normalize()
Make a normalized vector (return norm value)
Definition V3D.cpp:129
constexpr V3D cross_prod(const V3D &v) const noexcept
Cross product (this * argument)
Definition V3D.h:284
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
Definition V3D.cpp:116
constexpr double Z() const noexcept
Get z.
Definition V3D.h:240
bool nullVector(const double tolerance=1e-3) const noexcept
Determine if the point is null.
Definition V3D.cpp:238
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.
@ Input
An input workspace.
Definition Property.h:53
@ Output
An output workspace.
Definition Property.h:54