Mantid
Loading...
Searching...
No Matches
SaveNexusProcessed.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// SaveNexusProcessed
8// @author Ronald Fowler, based on SaveNexus
24#include <memory>
25#include <utility>
26
27using namespace Mantid::API;
28
29namespace Mantid::DataHandling {
30
31using namespace Kernel;
32using namespace API;
33using namespace DataObjects;
35
37
38// Register the algorithm into the algorithm factory
40
41namespace {
42
58bool makeMappings(const MatrixWorkspace &ws, const std::vector<int> &ws_indices,
59 std::vector<int32_t> &out_detector_index, std::vector<int32_t> &out_detector_count,
60 std::vector<int32_t> &out_detector_list, int &numberSpec, size_t &numberDetectors) {
61
62 // Count the total number of detectors
63 numberDetectors =
64 std::accumulate(ws_indices.cbegin(), ws_indices.cend(), size_t(0), [&ws](size_t sum, const auto &index) {
65 return sum + ws.getSpectrum(static_cast<size_t>(index)).getDetectorIDs().size();
66 });
67 if (numberDetectors < 1) {
68 return false;
69 }
70 // Start the detector group
71
72 numberSpec = int(ws_indices.size());
73 // allocate space for the Nexus Muon format of spectra-detector mapping
74 // allow for writing one more than required
75 out_detector_index.resize(numberSpec + 1, 0);
76 out_detector_count.resize(numberSpec, 0);
77 out_detector_list.resize(numberDetectors, 0);
78 int id = 0;
79
80 // get data from map into Nexus Muon format
81 for (int i = 0; i < numberSpec; i++) {
82 // Workspace index
83 const int si = ws_indices[i];
84 // Spectrum there
85 const auto &spectrum = ws.getSpectrum(si);
86
87 // The detectors in this spectrum
88 const auto &detectorgroup = spectrum.getDetectorIDs();
89 const auto ndet1 = static_cast<int>(detectorgroup.size());
90
91 // points to start of detector list for the next spectrum
92 out_detector_index[i + 1] = int32_t(out_detector_index[i] + ndet1);
93 out_detector_count[i] = int32_t(ndet1);
94
95 std::set<detid_t>::const_iterator it;
96 for (it = detectorgroup.begin(); it != detectorgroup.end(); ++it) {
97 out_detector_list[id++] = int32_t(*it);
98 }
99 }
100 // Cut the extra entry at the end of detector_index
101 out_detector_index.resize(numberSpec);
102 return true;
103}
104
105} // namespace
106
111 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::Input),
112 "Name of the workspace to be saved");
113 // Declare required input parameters for algorithm
114 const std::vector<std::string> fileExts{".nxs", ".nx5", ".xml"};
115 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Save, fileExts),
116 "The name of the Nexus file to write, as a full or relative\n"
117 "path");
118
119 // Declare optional parameters (title now optional, was mandatory)
120 declareProperty("Title", "", std::make_shared<NullValidator>(), "A title to describe the saved workspace");
121 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
122 mustBePositive->setLower(0);
123
124 declareProperty("WorkspaceIndexMin", 0, mustBePositive,
125 "Index number of first spectrum to write, only for single\n"
126 "period data.");
127 declareProperty("WorkspaceIndexMax", Mantid::EMPTY_INT(), mustBePositive,
128 "Index of last spectrum to write, only for single period\n"
129 "data.");
130 declareProperty(std::make_unique<ArrayProperty<int>>("WorkspaceIndexList"),
131 "List of spectrum numbers to read, only for single period\n"
132 "data.");
133
134 declareProperty("Append", false,
135 "Determines whether .nxs file needs to be\n"
136 "over written or appended");
137
138 declareProperty("PreserveEvents", true,
139 "For EventWorkspaces, preserve the events when saving (default).\n"
140 "If false, will save the 2D histogram version of the workspace with the "
141 "current binning parameters.");
142 setPropertySettings("PreserveEvents",
143 std::make_unique<EnabledWhenWorkspaceIsType<EventWorkspace>>("InputWorkspace", true));
144
145 declareProperty("CompressNexus", false,
146 "For EventWorkspaces, compress the Nexus data field (default False).\n"
147 "This will make smaller files but takes much longer.");
148 setPropertySettings("CompressNexus",
149 std::make_unique<EnabledWhenWorkspaceIsType<EventWorkspace>>("InputWorkspace", true));
150}
151
157void SaveNexusProcessed::getWSIndexList(std::vector<int> &indices, const MatrixWorkspace_const_sptr &matrixWorkspace) {
158 const std::vector<int> spec_list = getProperty("WorkspaceIndexList");
159 int spec_min = getProperty("WorkspaceIndexMin");
160 int spec_max = getProperty("WorkspaceIndexMax");
161 const bool list = !spec_list.empty();
162 const bool interval = (spec_max != Mantid::EMPTY_INT());
163 if (spec_max == Mantid::EMPTY_INT())
164 spec_max = 0;
165 const auto numberOfHist = static_cast<int>(matrixWorkspace->getNumberHistograms());
166
167 if (interval) {
168 if (spec_max < spec_min || spec_max > numberOfHist - 1) {
169 g_log.error("Invalid WorkspaceIndex min/max properties");
170 throw std::invalid_argument("Inconsistent properties defined");
171 }
172 indices.reserve(1 + spec_max - spec_min);
173 for (int i = spec_min; i <= spec_max; i++)
174 indices.emplace_back(i);
175 if (list) {
176 for (auto s : spec_list) {
177 if (s < 0)
178 continue;
179 if (s < spec_min || s > spec_max)
180 indices.emplace_back(s);
181 }
182 }
183 } else if (list) {
184 spec_max = 0;
185 spec_min = numberOfHist - 1;
186 for (auto s : spec_list) {
187 if (s < 0)
188 continue;
189 indices.emplace_back(s);
190 if (s > spec_max)
191 spec_max = s;
192 if (s < spec_min)
193 spec_min = s;
194 }
195 } else {
196 spec_min = 0;
197 spec_max = numberOfHist - 1;
198 indices.reserve(1 + spec_max - spec_min);
199 for (int i = spec_min; i <= spec_max; i++)
200 indices.emplace_back(i);
201 }
202}
203
204void SaveNexusProcessed::doExec(const Workspace_sptr &inputWorkspace, std::shared_ptr<Nexus::NexusFileIO> &nexusFile,
205 const bool keepFile, optional_size_t entryNumber) {
206 //
207 //
208
209 // Retrieve the filename from the properties
210 const std::string filename = getPropertyValue("Filename");
211 std::string title = getPropertyValue("Title");
212 // Do we preserve events?
213 const bool PreserveEvents = getProperty("PreserveEvents");
214
215 MatrixWorkspace_const_sptr matrixWorkspace = std::dynamic_pointer_cast<const MatrixWorkspace>(inputWorkspace);
216 ITableWorkspace_const_sptr tableWorkspace = std::dynamic_pointer_cast<const ITableWorkspace>(inputWorkspace);
217 IPeaksWorkspace_const_sptr peaksWorkspace = std::dynamic_pointer_cast<const IPeaksWorkspace>(inputWorkspace);
218 OffsetsWorkspace_const_sptr offsetsWorkspace = std::dynamic_pointer_cast<const OffsetsWorkspace>(inputWorkspace);
219 MaskWorkspace_const_sptr maskWorkspace = std::dynamic_pointer_cast<const MaskWorkspace>(inputWorkspace);
220 if (peaksWorkspace)
221 g_log.debug("We have a peaks workspace");
222 // check if inputWorkspace is something we know how to save
223 if (!matrixWorkspace && !tableWorkspace) {
224 // get the workspace name for the error message
225 const std::string name = getProperty("InputWorkspace");
226
227 // md workspaces should be saved using SaveMD
228 if (bool(std::dynamic_pointer_cast<const IMDEventWorkspace>(inputWorkspace)) ||
229 bool(std::dynamic_pointer_cast<const IMDHistoWorkspace>(inputWorkspace)))
230 g_log.warning() << name << " can be saved using SaveMD\n";
231
232 // standard error message
233 std::stringstream msg;
234 msg << "Workspace \"" << name << "\" not saved because it is not of a type we can presently save.";
235
236 throw std::runtime_error(msg.str());
237 }
238 m_eventWorkspace = std::dynamic_pointer_cast<const EventWorkspace>(matrixWorkspace);
239 const std::string workspaceID = inputWorkspace->id();
240 if ((workspaceID.find("Workspace2D") == std::string::npos) &&
241 (workspaceID.find("RebinnedOutput") == std::string::npos) &&
242 (workspaceID.find("WorkspaceSingleValue") == std::string::npos) &&
243 (workspaceID.find("GroupingWorkspace") == std::string::npos) && !m_eventWorkspace && !tableWorkspace &&
244 !offsetsWorkspace && !maskWorkspace)
245 throw Exception::NotImplementedError("SaveNexusProcessed passed invalid workspaces. Must be Workspace2D, "
246 "EventWorkspace, ITableWorkspace, OffsetsWorkspace, "
247 "GroupingWorkspace, or MaskWorkspace.");
248
249 // Create progress object for initial part - depends on whether events are
250 // processed
251 if (PreserveEvents && m_eventWorkspace) {
252 m_timeProgInit = 0.07; // Events processed 0.05 to 1.0
253 } else {
254 m_timeProgInit = 1.0; // All work is done in the initial part
255 }
256 Progress prog_init(this, 0.0, m_timeProgInit, 7);
257
258 // If no title's been given, use the workspace title field
259 if (title.empty())
260 title = inputWorkspace->getTitle();
261
262 // get the workspace name to write to file
263 const std::string wsName = inputWorkspace->getName();
264
265 // If not append, openNexusWrite will open with _CREATES perm and overwrite
266 const bool append_to_file = getProperty("Append");
267
268 nexusFile->resetProgress(&prog_init);
269 nexusFile->openNexusWrite(filename, entryNumber, append_to_file || keepFile);
270
271 prog_init.reportIncrement(1, "Opening file");
272 if (nexusFile->writeNexusProcessedHeader(title, wsName) != 0)
273 throw Exception::FileError("Failed to write to file", filename);
274
275 prog_init.reportIncrement(1, "Writing header");
276
277 // write instrument data, if present and writer enabled
278 if (matrixWorkspace) {
279 // Save the instrument names, ParameterMap, sample, run
280 matrixWorkspace->saveExperimentInfoNexus(nexusFile->filehandle().get(), saveLegacyInstrument());
281 prog_init.reportIncrement(1, "Writing sample and instrument");
282
283 // check if all X() are in fact the same array
284 const bool uniformSpectra = matrixWorkspace->isCommonBins();
285 const bool raggedSpectra = matrixWorkspace->isRaggedWorkspace();
286
287 // Retrieve the workspace indices (from params)
288 std::vector<int> indices;
289 this->getWSIndexList(indices, matrixWorkspace);
290
291 prog_init.reportIncrement(1, "Writing data");
292 // Write out the data (2D or event)
293 if (m_eventWorkspace && PreserveEvents) {
294 this->execEvent(nexusFile.get(), uniformSpectra, raggedSpectra, indices);
295 } else {
296 std::string workspaceTypeGroupName;
297 if (offsetsWorkspace)
298 workspaceTypeGroupName = "offsets_workspace";
299 else if (maskWorkspace)
300 workspaceTypeGroupName = "mask_workspace";
301 else if (std::dynamic_pointer_cast<const GroupingWorkspace>(inputWorkspace))
302 workspaceTypeGroupName = "grouping_workspace";
303 else
304 workspaceTypeGroupName = "workspace";
305
306 nexusFile->writeNexusProcessedData2D(matrixWorkspace, uniformSpectra, raggedSpectra, indices,
307 workspaceTypeGroupName.c_str(), true);
308 }
309
310 if (saveLegacyInstrument()) {
311 nexusFile->filehandle()->openGroup("instrument", "NXinstrument");
312 nexusFile->filehandle()->makeGroup("detector", "NXdetector", true);
313
314 nexusFile->filehandle()->putAttr("version", 1);
315 saveSpectraDetectorMapNexus(*matrixWorkspace, nexusFile->filehandle().get(), indices, NXcompression::LZW);
316 saveSpectrumNumbersNexus(*matrixWorkspace, nexusFile->filehandle().get(), indices, NXcompression::LZW);
317 nexusFile->filehandle()->closeGroup();
318 nexusFile->filehandle()->closeGroup();
319 }
320
321 } // finish matrix workspace specifics
322
323 if (peaksWorkspace) {
324 // Save the instrument names, ParameterMap, sample, run
325 peaksWorkspace->saveExperimentInfoNexus(nexusFile->filehandle().get());
326 prog_init.reportIncrement(1, "Writing sample and instrument");
327 peaksWorkspace->saveNexus(nexusFile->filehandle().get());
328 } else if (tableWorkspace) {
329 nexusFile->writeNexusTableWorkspace(tableWorkspace, "table_workspace");
330 }
331
332 // Switch to the Cpp API for the algorithm history
333 if (trackingHistory()) {
334 m_history->fillAlgorithmHistory(this, Mantid::Types::Core::DateAndTime::getCurrentTime(), 0,
336 if (!isChild()) {
337 inputWorkspace->history().addHistory(m_history);
338 }
339 // this is a child algorithm, but we still want to keep the history.
341 m_parentHistory->addChildHistory(m_history);
342 }
343 }
344
345 inputWorkspace->history().saveNexus(nexusFile->filehandle().get());
346 nexusFile->closeGroup();
347}
348
349//-----------------------------------------------------------------------------------------------
355 Workspace_sptr inputWorkspace = getProperty("InputWorkspace");
356
357 // Then immediately open the file
358 auto nexusFile = std::make_shared<Mantid::Nexus::NexusFileIO>();
359
360 // Perform the execution.
361 doExec(inputWorkspace, nexusFile);
362
363 // nexusFile->closeNexusFile();
364}
365
366//-------------------------------------------------------------------------------------
375template <class T>
376void SaveNexusProcessed::appendEventListData(const std::vector<T> &events, size_t offset, double *tofs, float *weights,
377 float *errorSquareds, int64_t *pulsetimes) {
378 // Do nothing if there are no events.
379 if (events.empty())
380 return;
381
382 const auto it = events.cbegin();
383 const auto it_end = events.cend();
384
385 // Fill the C-arrays with the fields from all the events, as requested.
386 if (tofs) {
387 std::transform(it, it_end, std::next(tofs, offset), [](const T &event) { return event.tof(); });
388 }
389 if (weights) {
390 std::transform(it, it_end, std::next(weights, offset),
391 [](const T &event) { return static_cast<float>(event.weight()); });
392 }
393 if (errorSquareds) {
394 std::transform(it, it_end, std::next(errorSquareds, offset),
395 [](const T &event) { return static_cast<float>(event.errorSquared()); });
396 }
397 if (pulsetimes) {
398 std::transform(it, it_end, std::next(pulsetimes, offset),
399 [](const T &event) { return event.pulseTime().totalNanoseconds(); });
400 }
401}
402
403//-----------------------------------------------------------------------------------------------
407void SaveNexusProcessed::execEvent(const Mantid::Nexus::NexusFileIO *nexusFile, const bool uniformSpectra,
408 const bool raggedSpectra, const std::vector<int> &spec) {
409 m_progress = std::make_unique<Progress>(this, m_timeProgInit, 1.0, m_eventWorkspace->getNumberEvents() * 2);
410
411 // Start by writing out the axes and crap
412 nexusFile->writeNexusProcessedData2D(m_eventWorkspace, uniformSpectra, raggedSpectra, spec, "event_workspace", false);
413
414 // Make a super long list of tofs, weights, etc.
415 std::vector<int64_t> indices;
416 indices.reserve(m_eventWorkspace->getNumberHistograms() + 1);
417 // First we need to index the events in each spectrum
418 size_t index = 0;
419 for (int wi = 0; wi < static_cast<int>(m_eventWorkspace->getNumberHistograms()); wi++) {
420 indices.emplace_back(index);
421 // Track the total # of events
422 index += m_eventWorkspace->getSpectrum(wi).getNumberEvents();
423 }
424 indices.emplace_back(index);
425
426 // Initialize all the arrays
427 int64_t num = index;
428 double *tofs = nullptr;
429 float *weights = nullptr;
430 float *errorSquareds = nullptr;
431 int64_t *pulsetimes = nullptr;
432
433 // overall event type.
434 EventType type = m_eventWorkspace->getEventType();
435 bool writeTOF = true;
436 bool writePulsetime = false;
437 bool writeWeight = false;
438 bool writeError = false;
439
440 switch (type) {
441 case TOF:
442 writePulsetime = true;
443 break;
444 case WEIGHTED:
445 writePulsetime = true;
446 writeWeight = true;
447 writeError = true;
448 break;
449 case WEIGHTED_NOTIME:
450 writeWeight = true;
451 writeError = true;
452 break;
453 }
454
455 // --- Initialize the combined event arrays ----
456 if (writeTOF)
457 tofs = new double[num];
458 if (writeWeight)
459 weights = new float[num];
460 if (writeError)
461 errorSquareds = new float[num];
462 if (writePulsetime)
463 pulsetimes = new int64_t[num];
464
465 // --- Fill in the combined event arrays ----
467 for (int wi = 0; wi < static_cast<int>(m_eventWorkspace->getNumberHistograms()); wi++) {
469 const DataObjects::EventList &el = m_eventWorkspace->getSpectrum(wi);
470
471 // This is where it will land in the output array.
472 // It is okay to write in parallel since none should step on each other.
473 size_t offset = indices[wi];
474
475 switch (el.getEventType()) {
476 case TOF:
477 appendEventListData(el.getEvents(), offset, tofs, weights, errorSquareds, pulsetimes);
478 break;
479 case WEIGHTED:
480 appendEventListData(el.getWeightedEvents(), offset, tofs, weights, errorSquareds, pulsetimes);
481 break;
482 case WEIGHTED_NOTIME:
483 appendEventListData(el.getWeightedEventsNoTime(), offset, tofs, weights, errorSquareds, pulsetimes);
484 break;
485 }
486 m_progress->reportIncrement(el.getNumberEvents(), "Copying EventList");
487
489 }
491
492 /*Default = DONT compress - much faster*/
493 bool CompressNexus = getProperty("CompressNexus");
494
495 // Write out to the NXS file.
496 nexusFile->writeNexusProcessedDataEventCombined(m_eventWorkspace, indices, tofs, weights, errorSquareds, pulsetimes,
497 CompressNexus);
498
499 // Free mem.
500 delete[] tofs;
501 delete[] weights;
502 delete[] errorSquareds;
503 delete[] pulsetimes;
504}
505
506//-----------------------------------------------------------------------------------------------
513void SaveNexusProcessed::setOtherProperties(IAlgorithm *alg, const std::string &propertyName,
514 const std::string &propertyValue, int perioidNum) {
515 if (propertyName == "Append") {
516 if (perioidNum != 1) {
517 alg->setPropertyValue(propertyName, "1");
518 } else
519 alg->setPropertyValue(propertyName, propertyValue);
520 } else
521 Algorithm::setOtherProperties(alg, propertyName, propertyValue, perioidNum);
522}
523
528 // Then immediately open the file
529 auto nexusFile = std::make_shared<Mantid::Nexus::NexusFileIO>();
530
531 // If we have arrived here then a WorkspaceGroup was passed to the
532 // InputWorkspace property. Pull out the unrolled workspaces and append an
533 // entry for each one. We only have a single input workspace property declared
534 // so there will only be a single list of unrolled workspaces
535 const auto &workspaces = m_unrolledInputWorkspaces[0];
536 if (!workspaces.empty()) {
537 for (size_t entry = 0; entry < workspaces.size(); entry++) {
538 const Workspace_sptr ws = workspaces[entry];
539 if (ws->isGroup()) {
540 throw std::runtime_error("NeXus files do not "
541 "support nested groups of groups");
542 }
543 this->doExec(ws, nexusFile, entry > 0 /*keepFile*/, entry);
544 g_log.information() << "Saving group index " << entry << "\n";
545 }
546 }
547
548 nexusFile->closeNexusFile();
549
550 return true;
551}
552
560 const std::vector<int> &wsIndices,
561 const NXcompression compression) const {
562
563 std::vector<int32_t> detector_index;
564 std::vector<int32_t> detector_count;
565 std::vector<int32_t> detector_list;
566 int numberSpec = 0;
567 size_t nDetectors = 0;
568 /*Make the mappings needed for writing to disk*/
569 const bool mappingsToWrite =
570 makeMappings(ws, wsIndices, detector_index, detector_count, detector_list, numberSpec, nDetectors);
571 if (!mappingsToWrite)
572 return;
573
574 // write data as Nexus sections detector{index,count,list}
575 Nexus::DimVector dims(1, numberSpec);
576 file->writeCompData("detector_index", detector_index, dims, compression, dims);
577 file->writeCompData("detector_count", detector_count, dims, compression, dims);
578 dims.front() = static_cast<int>(nDetectors);
579 file->writeCompData("detector_list", detector_list, dims, compression, dims);
580 // Get all the positions
581 try {
582 std::vector<double> detPos(nDetectors * 3);
584 Geometry::IComponent_const_sptr sample = inst->getSample();
585 if (sample) {
586 Kernel::V3D sample_pos = sample->getPos();
587 for (size_t i = 0; i < nDetectors; i++) {
588 double R, Theta, Phi;
589 try {
590 Geometry::IDetector_const_sptr det = inst->getDetector(detector_list[i]);
591 Kernel::V3D pos = det->getPos() - sample_pos;
592 pos.getSpherical(R, Theta, Phi);
593 R = det->getDistance(*sample);
594 Theta = ws.detectorTwoTheta(*det) * Geometry::rad2deg;
595 } catch (...) {
596 R = 0.;
597 Theta = 0.;
598 Phi = 0.;
599 }
600 // Need to get R & Theta through these methods to be correct for grouped
601 // detectors
602 detPos[3 * i] = R;
603 detPos[3 * i + 1] = Theta;
604 detPos[3 * i + 2] = Phi;
605 }
606 } else
607 for (size_t i = 0; i < 3 * nDetectors; i++)
608 detPos[i] = 0.;
609
610 dims.front() = static_cast<int>(nDetectors);
611 dims.emplace_back(3);
612 file->writeCompData("detector_positions", detPos, dims, compression, dims);
613 } catch (...) {
614 g_log.error("Unknown error caught when saving detector positions.");
615 }
616}
617
625 const std::vector<int> &wsIndices,
626 const NXcompression compression) const {
627 const auto numberSpec = int(wsIndices.size());
628 std::vector<int32_t> spectra;
629 spectra.reserve(static_cast<size_t>(numberSpec));
630 for (const auto index : wsIndices) {
631 const auto &spectrum = ws.getSpectrum(static_cast<size_t>(index));
632 spectra.emplace_back(static_cast<int32_t>(spectrum.getSpectrumNo()));
633 }
634
635 const Nexus::DimVector dims(1, numberSpec);
636 file->writeCompData("spectra", spectra, dims, compression, dims);
637}
638
639} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:538
std::map< DeltaEMode::Type, std::string > index
#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.
NXcompression
The available compression types:
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.
std::shared_ptr< AlgorithmHistory > m_parentHistory
Pointer to the parent history object (if set)
Definition Algorithm.h:425
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
std::shared_ptr< AlgorithmHistory > m_history
Pointer to the history for the algorithm being executed.
Definition Algorithm.h:418
bool isChild() const override
To query whether algorithm is a child.
Kernel::Logger & g_log
Definition Algorithm.h:422
virtual void setOtherProperties(IAlgorithm *alg, const std::string &propertyName, const std::string &propertyValue, int periodNum)
Virtual method to set the non workspace properties for this algorithm.
bool trackingHistory()
get whether we are tracking the history for this algorithm,
std::vector< WorkspaceVector > m_unrolledInputWorkspaces
One vector of workspaces for each input workspace property.
Definition Algorithm.h:429
bool isRecordingHistoryForChild()
Definition Algorithm.h:225
static size_t g_execCount
Counter to keep track of algorithm execution order.
Definition Algorithm.h:410
Show a property as enabled when the workspace pointed to by another is of a given type.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
@ Save
to specify a file to write to, the file may or may not exist
IAlgorithm is the interface implemented by the Algorithm base class.
Definition IAlgorithm.h:45
const std::set< detid_t > & getDetectorIDs() const
Get a const reference to the detector IDs set.
Base MatrixWorkspace Abstract Class.
virtual ISpectrum & getSpectrum(const size_t index)=0
Return the underlying ISpectrum ptr at the given workspace index.
double detectorTwoTheta(const Geometry::IDetector &det) const
Returns the 2Theta scattering angle for a detector.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
A property class for workspaces.
DataHandling/SaveNexusProcessed.h.
static void appendEventListData(const std::vector< T > &events, size_t offset, double *tofs, float *weights, float *errorSquareds, int64_t *pulsetimes)
Append out each field of a vector of events to separate array.
DataObjects::EventWorkspace_const_sptr m_eventWorkspace
Pointer to the local workspace, cast to EventWorkspace.
void getWSIndexList(std::vector< int > &indices, const Mantid::API::MatrixWorkspace_const_sptr &matrixWorkspace)
Get the list of workspace indices to use.
void doExec(const Mantid::API::Workspace_sptr &inputWorkspace, std::shared_ptr< Mantid::Nexus::NexusFileIO > &nexusFile, const bool keepFile=false, std::optional< size_t > entryNumber=std::optional< size_t >())
void saveSpectraDetectorMapNexus(const API::MatrixWorkspace &ws, Nexus::File *file, const std::vector< int > &wsIndices, const NXcompression compression=NXcompression::LZW) const
Save the spectra detector map to an open NeXus file.
void init() override
Overwrites Algorithm method.
double m_timeProgInit
Proportion of progress time expected to write initial part.
bool processGroups() override
Override process groups.
void execEvent(const Mantid::Nexus::NexusFileIO *nexusFile, const bool uniformSpectra, const bool raggedSpectra, const std::vector< int > &spec)
Execute the saving of event data.
const std::string name() const override
Algorithm's name for identification overriding a virtual method.
void exec() override
Overwrites Algorithm method.
void setOtherProperties(IAlgorithm *alg, const std::string &propertyName, const std::string &propertyValue, int perioidNum) override
sets non workspace properties for the algorithm
std::unique_ptr< API::Progress > m_progress
Progress bar.
void saveSpectrumNumbersNexus(const API::MatrixWorkspace &ws, Nexus::File *file, const std::vector< int > &wsIndices, const NXcompression compression=NXcompression::LZW) const
Save the spectra numbers to an open NeXus file.
A class for holding :
Definition EventList.h:57
Support for a property that holds an array of values.
Records the filename and the description of failure.
Definition Exception.h:98
Marks code as not implemented yet.
Definition Exception.h:138
virtual void setPropertyValue(const std::string &name, const std::string &value)=0
Sets property value from a string.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void debug(const std::string &msg)
Logs at debug level.
Definition Logger.cpp:145
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
void reportIncrement(int inc, const std::string &msg="")
Sends the progress notification and increment the loop counter by more than one.
Class for 3D vectors.
Definition V3D.h:34
void getSpherical(double &R, double &theta, double &phi) const noexcept
Return the vector's position in spherical coordinates.
Definition V3D.cpp:116
Utility methods for saving Mantid Workspaces in NeXus format.
int writeNexusProcessedDataEventCombined(const DataObjects::EventWorkspace_const_sptr &ws, std::vector< int64_t > const &indices, double const *tofs, float const *weights, float const *errorSquareds, int64_t const *pulsetimes, bool compress) const
Write out a combined chunk of event data.
int writeNexusProcessedData2D(const API::MatrixWorkspace_const_sptr &localworkspace, const bool &uniformSpectra, const bool &raggedSpectra, const std::vector< int > &indices, const std::string &group_name, bool write2Ddata) const
write the workspace data
std::optional< size_t > optional_size_t
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< const ITableWorkspace > ITableWorkspace_const_sptr
shared pointer to Mantid::API::ITableWorkspace (const version)
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< const IPeaksWorkspace > IPeaksWorkspace_const_sptr
shared pointer to Mantid::API::IPeaksWorkspace (const version)
EventType
What kind of event list is being stored.
Definition IEventList.h:18
Nexus::NexusFileIO::optional_size_t optional_size_t
std::shared_ptr< const OffsetsWorkspace > OffsetsWorkspace_const_sptr
shared pointer to a const OffsetsWorkspace
std::shared_ptr< const MaskWorkspace > MaskWorkspace_const_sptr
shared pointer to a const MaskWorkspace
constexpr double rad2deg
Radians to degrees conversion factor.
Definition AngleUnits.h:23
std::shared_ptr< const IComponent > IComponent_const_sptr
Typdef of a shared pointer to a const IComponent.
Definition IComponent.h:167
std::shared_ptr< const Mantid::Geometry::IDetector > IDetector_const_sptr
Shared pointer to IDetector (const version)
Definition IDetector.h:102
std::shared_ptr< const Instrument > Instrument_const_sptr
Shared pointer to an const instrument object.
std::vector< dimsize_t > DimVector
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
Definition EmptyValues.h:24
@ Input
An input workspace.
Definition Property.h:53