Mantid
Loading...
Searching...
No Matches
SaveToSNSHistogramNexus.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 +
7// SaveToSNSHistogramNexus
8// @author Freddie Akeroyd, STFC ISIS Faility
9// @author Ronald Fowler, STFC eScience. Modified to fit with
10// SaveToSNSHistogramNexusProcessed
13#include "MantidAPI/Progress.h"
19#include "MantidKernel/Memory.h"
20#include "MantidKernel/Timer.h"
21
22#include <Poco/File.h>
23#include <boost/scoped_array.hpp>
24#include <cmath>
25#include <memory>
26#include <numeric>
27
28#include <cstdlib>
29#include <cstring>
30#include <ctime>
31
32namespace Mantid::DataHandling {
33
34// Register the algorithm into the algorithm factory
35DECLARE_ALGORITHM(SaveToSNSHistogramNexus)
36
37using namespace Kernel;
38using namespace API;
39using namespace DataObjects;
40using namespace Geometry;
41
44 : Algorithm(), m_progress(), m_compress(false), links_count(0), inId(), outId() {}
45
50 // Declare required parameters, filename with ext {.nx,.nx5,xml} and input
51 // workspac
52 std::initializer_list<std::string> exts = {".nxs"};
53
54 declareProperty(std::make_unique<FileProperty>("InputFilename", "", FileProperty::Load, exts),
55 "The name of the original Nexus file for this data,\n"
56 "as a full or relative path");
57
58 declareProperty(std::make_unique<WorkspaceProperty<MatrixWorkspace>>("InputWorkspace", "", Direction::Input),
59 "Name of the workspace to be saved");
60
61 declareProperty(std::make_unique<FileProperty>("OutputFilename", "", FileProperty::Save, exts),
62 "The name of the Nexus file to write, as a full or relative\n"
63 "path");
64
65 declareProperty(std::make_unique<PropertyWithValue<bool>>("Compress", false, Direction::Input),
66 "Will the output NXS file data be compressed?");
67}
68
69// /** Execute the algorithm.
70// *
71// * @throw runtime_error Thrown if algorithm cannot execute
72// */
73// void SaveToSNSHistogramNexus::exec()
74// {
75// throw std::runtime_error("Temporarily disabled because it does not work on
76// RHEL5.\n");
77// }
78
79//------------------------------------------------------------------------
81int SaveToSNSHistogramNexus::add_path(const char *path) {
82 size_t i;
83 i = strlen(current_path);
84 sprintf(current_path + i, "/%s", path);
85 return 0;
86}
87
88//------------------------------------------------------------------------
91 char *tstr;
92 tstr = strrchr(current_path, '/');
93 if (tstr != nullptr && !strcmp(path, tstr + 1)) {
94 *tstr = '\0';
95 } else {
96 printf("path error\n");
97 }
98 return 0;
99}
100
101//------------------------------------------------------------------------
105int SaveToSNSHistogramNexus::copy_file(const char *inFile, int nx__access, const char *outFile, int nx_write_access) {
106 int nx_is_definition = 0;
107 links_count = 0;
108 current_path[0] = '\0';
109 NXlink link;
110
111 /* Open NeXus input file and NeXus output file */
112 if (NXopen(inFile, nx__access, &inId) != NX_OK) {
113 printf("NX_ERROR: Can't open %s\n", inFile);
114 return NX_ERROR;
115 }
116
117 if (NXopen(outFile, nx_write_access, &outId) != NX_OK) {
118 printf("NX_ERROR: Can't open %s\n", outFile);
119 return NX_ERROR;
120 }
121
122 /* Output global attributes */
123 if (WriteAttributes(nx_is_definition) != NX_OK) {
124 return NX_ERROR;
125 }
126 /* Recursively cycle through the groups printing the contents */
127 if (WriteGroup(nx_is_definition) != NX_OK) {
128 return NX_ERROR;
129 }
130 /* close input */
131 if (NXclose(&inId) != NX_OK) {
132 return NX_ERROR;
133 }
134
135 // HDF5 only
136 {
137 /* now create any required links */
138 for (int i = 0; i < links_count; i++) {
139 if (NXopenpath(outId, links_to_make[i].to) != NX_OK)
140 return NX_ERROR;
141 if (NXgetdataID(outId, &link) == NX_OK || NXgetgroupID(outId, &link) == NX_OK) {
142 if (NXopenpath(outId, links_to_make[i].from) != NX_OK)
143 return NX_ERROR;
144 char *tstr = strrchr(links_to_make[i].to, '/');
145 if (!strcmp(links_to_make[i].name, tstr + 1)) {
146 if (NXmakelink(outId, &link) != NX_OK)
147 return NX_ERROR;
148 } else {
149 if (NXmakenamedlink(outId, links_to_make[i].name, &link) != NX_OK)
150 return NX_ERROR;
151 }
152 } else {
153 return NX_ERROR;
154 }
155 }
156 }
157 /* Close the input and output files */
158 if (NXclose(&outId) != NX_OK) {
159 return NX_ERROR;
160 }
161 return NX_OK;
162}
163
164//------------------------------------------------------------------------
181 const char *field_name, const char *errors_field_name, bool doErrors,
182 bool doBoth, int is_definition, const std::string &bank) {
183 int dataRank, dataDimensions[NX_MAXRANK];
184 int slabDimensions[NX_MAXRANK], slabStartIndices[NX_MAXRANK];
185
186 dataRank = 3;
187
188 // Dimension 0 = the X pixels
189 dataDimensions[0] = det->xpixels();
190 // Dimension 1 = the Y pixels
191 dataDimensions[1] = det->ypixels();
192 // Dimension 2 = time of flight bins
193 dataDimensions[2] = static_cast<int>(m_inputWorkspace->blocksize());
194
195 // ---- Determine slab size -----
196 // Number of pixels to collect in X before slabbing
197 slabDimensions[0] = x_pixel_slab;
198 slabDimensions[1] = dataDimensions[1];
199 slabDimensions[2] = dataDimensions[2];
200
201 if (doBoth)
202 slabDimensions[0] = dataDimensions[0];
203
204 std::cout << "RectangularDetector " << det->getName() << " being copied. Dimensions : " << dataDimensions[0] << ", "
205 << dataDimensions[1] << ", " << dataDimensions[2] << ".\n";
206
207 // ----- Open the data field -----------------------
208 if (m_compress) {
209 if (NXcompmakedata(outId, field_name, NX_FLOAT32, dataRank, dataDimensions, NX_COMP_LZW, slabDimensions) != NX_OK)
210 return NX_ERROR;
211 } else {
212 if (NXmakedata(outId, field_name, NX_FLOAT32, dataRank, dataDimensions) != NX_OK)
213 return NX_ERROR;
214 }
215 if (NXopendata(outId, field_name) != NX_OK)
216 return NX_ERROR;
217 if (WriteAttributes(is_definition) != NX_OK)
218 return NX_ERROR;
219 if (!doErrors) {
220 // Add an attribute called "errors" with value = the name of the data_errors
221 // field.
222 NXname attrName = "errors";
223 std::string attrBuffer = errors_field_name;
224 if (NXputattr(outId, attrName, attrBuffer.c_str(), static_cast<int>(attrBuffer.size()), NX_CHAR) != NX_OK)
225 return NX_ERROR;
226 }
227
228 // ---- Errors field -----
229 if (doBoth) {
230 if (NXclosedata(outId) != NX_OK)
231 return NX_ERROR;
232
233 if (m_compress) {
234 if (NXcompmakedata(outId, errors_field_name, NX_FLOAT32, dataRank, dataDimensions, NX_COMP_LZW, slabDimensions) !=
235 NX_OK)
236 return NX_ERROR;
237 } else {
238 if (NXmakedata(outId, errors_field_name, NX_FLOAT32, dataRank, dataDimensions) != NX_OK)
239 return NX_ERROR;
240 }
241 if (NXopendata(outId, errors_field_name) != NX_OK)
242 return NX_ERROR;
243
244 // NXlink * link = new NXlink;
245 // link->linkType = 1; /* SDS data link */
246 // NXgetdataID(outId, link);
247 // std::string targetPath = "/entry/" + bank + "/" + errors_field_name;
248 // strcpy(link->targetPath, targetPath.c_str());
249 // if (NXmakelink(outId,link) != NX_OK)
250 // g_log.debug() << "Error while making link to " << targetPath <<
251 // '\n';
252
253 if (WriteAttributes(is_definition) != NX_OK)
254 return NX_ERROR;
255 if (NXclosedata(outId) != NX_OK)
256 return NX_ERROR;
257 }
258
259 double fillTime = 0;
260 double saveTime = 0;
261
262 // Make a buffer of floats will all the counts in that bank.
263 auto data = new float[slabDimensions[0] * slabDimensions[1] * slabDimensions[2]];
264
265 // Only allocate an array for errors if it is needed
266 float *errors = nullptr;
267 if (doBoth)
268 errors = new float[slabDimensions[0] * slabDimensions[1] * slabDimensions[2]];
269
270 for (int x = 0; x < det->xpixels(); x++) {
271 // Which slab are we in?
272 int slabnum = x / x_pixel_slab;
273
274 // X index into the slabbed output array
275 int slabx = x % x_pixel_slab;
276
277 Timer tim1;
278 auto ypixels = static_cast<int>(det->ypixels());
279
281 for (int y = 0; y < ypixels; y++) {
283 // Get the workspace index for the detector ID at this spot
284 size_t wi = 0;
285 try {
286 wi = m_map.find(det->getAtXY(x, y)->getID())->second;
287 } catch (...) {
288 std::cout << "Error finding " << bank << " x " << x << " y " << y << "\n";
289 }
290
291 // Offset into array.
292 size_t index =
293 size_t(slabx) * size_t(dataDimensions[1]) * size_t(dataDimensions[2]) + size_t(y) * size_t(dataDimensions[2]);
294
295 const auto &Y = m_inputWorkspace->y(wi);
296 const auto &E = m_inputWorkspace->e(wi);
297
298 for (size_t i = 0; i < Y.size(); ++i) {
299 if (doErrors) {
300 data[i + index] = static_cast<float>(E[i]);
301 } else {
302 data[i + index] = static_cast<float>(Y[i]);
303 if (doBoth) {
304 errors[i + index] = static_cast<float>(E[i]);
305 }
306 }
307 }
308
310 }
312
313 fillTime += tim1.elapsed();
314
315 // Is this the last pixel in the slab?
316 if (!doBoth && (x % x_pixel_slab == x_pixel_slab - 1)) {
317 Timer tim2;
318 // std::cout << "starting slab " << x << "\n";
319 // This is where the slab is in the greater data array.
320 slabStartIndices[0] = slabnum * x_pixel_slab;
321 slabStartIndices[1] = 0;
322 slabStartIndices[2] = 0;
323 if (NXputslab(outId, data, slabStartIndices, slabDimensions) != NX_OK)
324 return NX_ERROR;
325 saveTime += tim2.elapsed();
326
327 std::ostringstream mess;
328 mess << det->getName() << ", " << field_name << " slab " << slabnum << " of " << det->xpixels() / x_pixel_slab;
329 this->m_progress->reportIncrement(x_pixel_slab * det->ypixels(), mess.str());
330 }
331
332 } // X loop
333
334 if (doBoth) {
335 bool returnerror = false;
336
337 Timer tim2;
338 if (NXopendata(outId, field_name) != NX_OK)
339 returnerror = true;
340 else if (NXputdata(outId, data) != NX_OK)
341 returnerror = true;
342 else if (NXclosedata(outId) != NX_OK)
343 returnerror = true;
344 else {
345 this->m_progress->reportIncrement(det->xpixels() * det->ypixels() * 1, det->getName() + " data");
346
347 if (NXopendata(outId, errors_field_name) != NX_OK)
348 returnerror = true;
349 else if (NXputdata(outId, errors) != NX_OK)
350 returnerror = true;
351 else if (NXclosedata(outId) != NX_OK)
352 returnerror = true;
353 else {
354 this->m_progress->reportIncrement(det->xpixels() * det->ypixels() * 1, det->getName() + " errors");
355 saveTime += tim2.elapsed();
356 }
357 }
358
359 if (returnerror) {
360 delete[] data;
361 delete[] errors;
362
363 return NX_ERROR;
364 }
365
366 } else {
367 if (NXclosedata(outId) != NX_OK) {
368 delete[] data;
369 return NX_ERROR;
370 }
371 }
372
373 std::cout << "Filling out " << det->getName() << " took " << fillTime << " sec.\n";
374 std::cout << "Saving " << det->getName() << " took " << saveTime << " sec.\n";
375
376 delete[] data;
377 if (doBoth)
378 delete[] errors;
379
380 return NX_OK;
381}
382
383//=================================================================================================
390int SaveToSNSHistogramNexus::WriteDataGroup(const std::string &bank, int is_definition) {
391 int dataType, dataRank, dataDimensions[NX_MAXRANK];
392 NXname name;
393 void *dataBuffer;
394
395 if (NXgetinfo(inId, &dataRank, dataDimensions, &dataType) != NX_OK)
396 return NX_ERROR;
397
398 // Get the rectangular detector
399 IComponent_const_sptr det_comp = m_inputWorkspace->getInstrument()->getComponentByName(std::string(bank));
400 RectangularDetector_const_sptr det = std::dynamic_pointer_cast<const RectangularDetector>(det_comp);
401 if (!det) {
402 g_log.information() << "Detector '" + bank + "' not found, or it is not a rectangular detector!\n";
403 // Just copy that then.
404 if (NXmalloc(&dataBuffer, dataRank, dataDimensions, dataType) != NX_OK)
405 return NX_ERROR;
406 if (NXgetdata(inId, dataBuffer) != NX_OK)
407 return NX_ERROR;
408 if (NXcompmakedata(outId, name, dataType, dataRank, dataDimensions, NX_COMP_LZW, dataDimensions) != NX_OK)
409 return NX_ERROR;
410 if (NXopendata(outId, name) != NX_OK)
411 return NX_ERROR;
412 if (WriteAttributes(is_definition) != NX_OK)
413 return NX_ERROR;
414 if (NXputdata(outId, dataBuffer) != NX_OK)
415 return NX_ERROR;
416 if (NXfree(&dataBuffer) != NX_OK)
417 return NX_ERROR;
418 if (NXclosedata(outId) != NX_OK)
419 return NX_ERROR;
420 } else {
421 // YES it is a rectangular detector.
422
423 // --- Memory requirements ----
424 size_t memory_required =
425 size_t(det->xpixels() * det->ypixels()) * size_t(m_inputWorkspace->blocksize()) * 2 * sizeof(float);
427 mem.update();
428 size_t memory_available = mem.availMem() * 1024;
429
430 std::cout << "Memory available: " << memory_available / 1024 << " kb. ";
431 std::cout << "Memory required: " << memory_required / 1024 << " kb. ";
432
433 // Give a 50% margin of error in allocating the memory
434 memory_available = memory_available / 2;
435 if (memory_available > static_cast<size_t>(5e9))
436 memory_available = static_cast<size_t>(5e9);
437
438 if (memory_available < memory_required) {
439 // Compute how large of a slab you can still use.
440 int x_slab;
441 x_slab =
442 static_cast<int>(memory_available / (det->ypixels() * m_inputWorkspace->blocksize() * 2 * sizeof(float)));
443 if (x_slab <= 0)
444 x_slab = 1;
445 // Look for a slab size that evenly divides the # of pixels.
446 while (x_slab > 1) {
447 if ((det->xpixels() % x_slab) == 0)
448 break;
449 x_slab--;
450 }
451
452 std::cout << "Saving in slabs of " << x_slab << " X pixels.\n";
453 if (this->WriteOutDataOrErrors(det, x_slab, "data", "data_errors", false, false, is_definition, bank) != NX_OK)
454 return NX_ERROR;
455 if (this->WriteOutDataOrErrors(det, x_slab, "errors", "", true, false, is_definition, bank) != NX_OK)
456 return NX_ERROR;
457 } else {
458 std::cout << "Saving in one block.\n";
459 if (this->WriteOutDataOrErrors(det, det->xpixels(), "data", "data_errors", false, true, is_definition, bank) !=
460 NX_OK)
461 return NX_ERROR;
462 }
463 }
464
465 return NX_OK;
466}
467
468//------------------------------------------------------------------------
471 int status, dataType, dataRank, dataDimensions[NX_MAXRANK];
472 NXname name, theClass;
473 void *dataBuffer;
474 NXlink link;
475
476 do {
477 status = NXgetnextentry(inId, name, theClass, &dataType);
478 // std::cout << name << "(" << theClass << ")\n";
479
480 if (status == NX_ERROR)
481 return NX_ERROR;
482 if (status == NX_OK) {
483 if (!strncmp(theClass, "NX", 2)) {
484 if (NXopengroup(inId, name, theClass) != NX_OK)
485 return NX_ERROR;
486 add_path(name);
487
488 if (NXgetgroupID(inId, &link) != NX_OK)
489 return NX_ERROR;
490 if (!strcmp(current_path, link.targetPath)) {
491 // Create a copy of the group
492 if (NXmakegroup(outId, name, theClass) != NX_OK)
493 return NX_ERROR;
494 if (NXopengroup(outId, name, theClass) != NX_OK)
495 return NX_ERROR;
496 if (WriteAttributes(is_definition) != NX_OK)
497 return NX_ERROR;
498 if (WriteGroup(is_definition) != NX_OK)
499 return NX_ERROR;
501 } else {
504 strcpy(links_to_make[links_count].to, link.targetPath);
506 links_count++;
507 if (NXclosegroup(inId) != NX_OK)
508 return NX_ERROR;
509 }
510 } else if (!strncmp(theClass, "SDS", 3)) {
511 add_path(name);
512 if (NXopendata(inId, name) != NX_OK)
513 return NX_ERROR;
514 if (NXgetdataID(inId, &link) != NX_OK)
515 return NX_ERROR;
516
517 std::string data_label(name);
518
519 if (!strcmp(current_path, link.targetPath)) {
520 // Look for the bank name
521 std::string path(current_path);
522 std::string bank;
523
524 size_t a = path.rfind('/');
525 if (a != std::string::npos && a > 0) {
526 size_t b = path.rfind('/', a - 1);
527 if (b != std::string::npos && (b < a) && (a - b - 1) > 0) {
528 bank = path.substr(b + 1, a - b - 1);
529 // std::cout << current_path << ":bank " << bank << "\n";
530 }
531 }
532
533 //---------------------------------------------------------------------------------------
534 if (data_label == "data" && (!bank.empty())) {
535 if (this->WriteDataGroup(bank, is_definition) != NX_OK)
536 return NX_ERROR;
537 ;
538 }
539 //---------------------------------------------------------------------------------------
540 else if (data_label == "time_of_flight" && (!bank.empty())) {
541 // Get the original info
542 if (NXgetinfo(inId, &dataRank, dataDimensions, &dataType) != NX_OK)
543 return NX_ERROR;
544
545 // Get the X bins
546 const auto &X = m_inputWorkspace->y(0);
547 // 1 dimension, with that number of bin boundaries
548 dataDimensions[0] = static_cast<int>(X.size());
549 // The output TOF axis will be whatever size in the workspace.
550 std::vector<float> tof_data(dataDimensions[0]);
551
552 // And fill it with the X data
553 std::transform(X.cbegin(), X.cend(), tof_data.begin(), [](double x) { return static_cast<float>(x); });
554
555 if (NXcompmakedata(outId, name, dataType, dataRank, dataDimensions, NX_COMP_LZW, dataDimensions) != NX_OK)
556 return NX_ERROR;
557 if (NXopendata(outId, name) != NX_OK)
558 return NX_ERROR;
559 if (WriteAttributes(is_definition) != NX_OK)
560 return NX_ERROR;
561 if (NXputdata(outId, tof_data.data()) != NX_OK)
562 return NX_ERROR;
563 if (NXclosedata(outId) != NX_OK)
564 return NX_ERROR;
565
566 }
567
568 //---------------------------------------------------------------------------------------
569 else {
570 // Everything else gets copies
571 if (NXgetinfo(inId, &dataRank, dataDimensions, &dataType) != NX_OK)
572 return NX_ERROR;
573 if (NXmalloc(&dataBuffer, dataRank, dataDimensions, dataType) != NX_OK)
574 return NX_ERROR;
575 if (NXgetdata(inId, dataBuffer) != NX_OK)
576 return NX_ERROR;
577 if (NXcompmakedata(outId, name, dataType, dataRank, dataDimensions, NX_COMP_LZW, dataDimensions) != NX_OK)
578 return NX_ERROR;
579 if (NXopendata(outId, name) != NX_OK)
580 return NX_ERROR;
581 if (WriteAttributes(is_definition) != NX_OK)
582 return NX_ERROR;
583 if (NXputdata(outId, dataBuffer) != NX_OK)
584 return NX_ERROR;
585 if (NXfree(&dataBuffer) != NX_OK)
586 return NX_ERROR;
587 if (NXclosedata(outId) != NX_OK)
588 return NX_ERROR;
589 }
590
592 } else {
593 // Make a link
596 strcpy(links_to_make[links_count].to, link.targetPath);
598 links_count++;
599 }
600 if (NXclosedata(inId) != NX_OK)
601 return NX_ERROR;
602 }
603 } else if (status == NX_EOD) {
604 if (NXclosegroup(inId) != NX_OK)
605 return NX_ERROR;
606 if (NXclosegroup(outId) != NX_OK)
607 return NX_ERROR;
608 return NX_OK;
609 }
610 } while (status == NX_OK);
611 return NX_OK;
612}
613
614//------------------------------------------------------------------------
617 (void)is_definition;
618
619 int status, attrLen, attrType;
620#ifndef NEXUS43
621 int rank;
622 int dims[4];
623#endif
624 NXname attrName;
625 void *attrBuffer;
626
627 std::array<const char *, 6> attrs = {
628 {"NeXus_version", "XML_version", "HDF_version", "HDF5_Version", "file_name", "file_time"}};
629
630 do {
631#ifdef NEXUS43
632 status = NXgetnextattr(inId, attrName, &attrLen, &attrType);
633#else
634 status = NXgetnextattra(inId, attrName, &rank, dims, &attrType);
635#endif
636 if (status == NX_ERROR)
637 return NX_ERROR;
638 if (status == NX_OK) {
639#ifndef NEXUS43
640 if (rank != 1)
641 return NX_ERROR;
642 attrLen = dims[0];
643#endif
644 if (std::none_of(attrs.cbegin(), attrs.cend(),
645 [&attrName](const char *name) { return strcmp(attrName, name) == 0; })) {
646 attrLen++; /* Add space for string termination */
647 if (NXmalloc(&attrBuffer, 1, &attrLen, attrType) != NX_OK)
648 return NX_ERROR;
649 if (NXgetattr(inId, attrName, attrBuffer, &attrLen, &attrType) != NX_OK)
650 return NX_ERROR;
651 if (NXputattr(outId, attrName, attrBuffer, attrLen, attrType) != NX_OK)
652 return NX_ERROR;
653 if (NXfree(&attrBuffer) != NX_OK)
654 return NX_ERROR;
655 }
656 }
657 } while (status != NX_EOD);
658 return NX_OK;
659}
660
661void nexus_print_error(void *pD, char *text) {
662 (void)pD;
663 std::cout << "Nexus Error: " << text << "\n";
664}
665
666//------------------------------------------------------------------------
672 // NXMSetError(NULL, nexus_print_error);
673 NXMEnableErrorReporting();
674
675 // Retrieve the filename from the properties
676 m_inputFilename = getPropertyValue("InputFileName");
677 m_outputFilename = getPropertyValue("OutputFileName");
678 m_compress = getProperty("Compress");
679
680 m_inputWorkspace = getProperty("InputWorkspace");
681
682 // We'll need to get workspace indices
683 m_map = m_inputWorkspace->getDetectorIDToWorkspaceIndexMap();
684
685 // Start the progress bar. 3 reports per histogram.
686 m_progress = std::make_unique<Progress>(this, 0.0, 1.0, m_inputWorkspace->getNumberHistograms() * 3);
687
688 EventWorkspace_const_sptr eventWorkspace = std::dynamic_pointer_cast<const EventWorkspace>(m_inputWorkspace);
689 if (eventWorkspace) {
690 eventWorkspace->sortAll(TOF_SORT, m_progress.get());
691 }
692
693 int ret;
694 ret = this->copy_file(m_inputFilename.c_str(), NXACC_READ, m_outputFilename.c_str(), NXACC_CREATE5);
695
696 if (ret == NX_ERROR)
697 throw std::runtime_error("Nexus error while copying the file.");
698}
699
700} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition: Algorithm.h:576
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
#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...
Definition: MultiThreaded.h:94
#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_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:85
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
Definition: Algorithm.cpp:1913
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
Definition: Algorithm.cpp:2026
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
Definition: Algorithm.cpp:2076
Kernel::Logger & g_log
Definition: Algorithm.h:451
@ Save
to specify a file to write to, the file may or may not exist
Definition: FileProperty.h:49
@ Load
allowed here which will be passed to the algorithm
Definition: FileProperty.h:52
A property class for workspaces.
int add_path(const char *path)
Append to current_path.
void init() override
Overwrites Algorithm method.
API::MatrixWorkspace_const_sptr m_inputWorkspace
Pointer to the local workspace.
std::string m_outputFilename
The name and path of the output file.
int remove_path(const char *path)
Remove the last part of the path.
int copy_file(const char *inFile, int nx_read_access, const char *outFile, int nx_write_access)
Performs the copying from the input to the output file, while modifying the data and time_of_flight f...
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
void exec() override
Overwrites Algorithm method.
int WriteDataGroup(const std::string &bank, int is_definition)
Write the group labeled "data".
std::string m_inputFilename
The name and path of the input file.
int WriteGroup(int is_definition)
Prints the contents of each group as XML tags and values.
int WriteOutDataOrErrors(const Geometry::RectangularDetector_const_sptr &det, int x_pixel_slab, const char *field_name, const char *errors_field_name, bool doErrors, bool doBoth, int is_definition, const std::string &bank)
Utility function to write out the data or errors to a field in the group.
int WriteAttributes(int is_definition)
Copy the attributes from input to output.
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
This class is responsible for memory statistics.
Definition: Memory.h:28
void update()
Update the structure with current information, taking into account what is to be ignored.
Definition: Memory.cpp:343
std::size_t availMem() const
Returns the available memory of the system in kiB.
Definition: Memory.cpp:398
The concrete, templated class for properties.
A simple class that provides a wall-clock (not processor time) timer.
Definition: Timer.h:27
float elapsed(bool reset=true)
Returns the wall-clock time elapsed in seconds since the Timer object's creation, or the last call to...
Definition: Timer.cpp:28
void nexus_print_error(void *pD, char *text)
std::shared_ptr< const EventWorkspace > EventWorkspace_const_sptr
shared pointer to a const Workspace2D
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition: IComponent.h:161
std::shared_ptr< const RectangularDetector > RectangularDetector_const_sptr
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
Definition: MultiThreaded.h:22
@ Input
An input workspace.
Definition: Property.h:53