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
58void 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
68 numberSpec = int(ws_indices.size());
69 // allocate space for the Nexus Muon format of spectra-detector mapping
70 // allow for writing one more than required
71 out_detector_index.resize(numberSpec + 1, 0);
72 out_detector_count.resize(numberSpec, 0);
73 out_detector_list.resize(numberDetectors, 0);
74 int id = 0;
75
76 // get data from map into Nexus Muon format
77 for (int i = 0; i < numberSpec; i++) {
78 // Workspace index
79 const int si = ws_indices[i];
80 // Spectrum there
81 const auto &spectrum = ws.getSpectrum(si);
82
83 // The detectors in this spectrum
84 const auto &detectorgroup = spectrum.getDetectorIDs();
85 const auto ndet1 = static_cast<int>(detectorgroup.size());
86
87 // points to start of detector list for the next spectrum
88 out_detector_index[i + 1] = int32_t(out_detector_index[i] + ndet1);
89 out_detector_count[i] = int32_t(ndet1);
90
91 std::set<detid_t>::const_iterator it;
92 for (it = detectorgroup.begin(); it != detectorgroup.end(); ++it) {
93 out_detector_list[id++] = int32_t(*it);
94 }
95 }
96 // Cut the extra entry at the end of detector_index
97 out_detector_index.resize(numberSpec);
98}
99
100} // namespace
101
106 declareProperty(std::make_unique<WorkspaceProperty<Workspace>>("InputWorkspace", "", Direction::Input),
107 "Name of the workspace to be saved");
108 // Declare required input parameters for algorithm
109 const std::vector<std::string> fileExts{".nxs", ".nx5", ".xml"};
110 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Save, fileExts),
111 "The name of the Nexus file to write, as a full or relative\n"
112 "path");
113
114 // Declare optional parameters (title now optional, was mandatory)
115 declareProperty("Title", "", std::make_shared<NullValidator>(), "A title to describe the saved workspace");
116 auto mustBePositive = std::make_shared<BoundedValidator<int>>();
117 mustBePositive->setLower(0);
118
119 declareProperty("WorkspaceIndexMin", 0, mustBePositive,
120 "Index number of first spectrum to write, only for single\n"
121 "period data.");
122 declareProperty("WorkspaceIndexMax", Mantid::EMPTY_INT(), mustBePositive,
123 "Index of last spectrum to write, only for single period\n"
124 "data.");
125 declareProperty(std::make_unique<ArrayProperty<int>>("WorkspaceIndexList"),
126 "List of spectrum numbers to write, only for single period\n"
127 "data.");
128
129 declareProperty("Append", false,
130 "Determines whether .nxs file needs to be\n"
131 "over written or appended");
132
133 declareProperty("PreserveEvents", true,
134 "For EventWorkspaces, preserve the events when saving (default).\n"
135 "If false, will save the 2D histogram version of the workspace with the "
136 "current binning parameters.");
137 setPropertySettings("PreserveEvents",
138 std::make_unique<EnabledWhenWorkspaceIsType<EventWorkspace>>("InputWorkspace", true));
139
140 declareProperty("CompressNexus", false,
141 "For EventWorkspaces, compress the Nexus data field (default False).\n"
142 "This will make smaller files but takes much longer.");
143 setPropertySettings("CompressNexus",
144 std::make_unique<EnabledWhenWorkspaceIsType<EventWorkspace>>("InputWorkspace", true));
145}
146
152void SaveNexusProcessed::getWSIndexList(std::vector<int> &indices, const MatrixWorkspace_const_sptr &matrixWorkspace) {
153 const std::vector<int> spec_list = getProperty("WorkspaceIndexList");
154 int spec_min = getProperty("WorkspaceIndexMin");
155 int spec_max = getProperty("WorkspaceIndexMax");
156 const bool list = !spec_list.empty();
157 const bool interval = (spec_max != Mantid::EMPTY_INT());
158 if (spec_max == Mantid::EMPTY_INT())
159 spec_max = 0;
160 const auto numberOfHist = static_cast<int>(matrixWorkspace->getNumberHistograms());
161
162 if (interval) {
163 if (spec_max < spec_min || spec_max > numberOfHist - 1) {
164 g_log.error("Invalid WorkspaceIndex min/max properties");
165 throw std::invalid_argument("Inconsistent properties defined");
166 }
167 indices.reserve(1 + spec_max - spec_min);
168 for (int i = spec_min; i <= spec_max; i++)
169 indices.emplace_back(i);
170 if (list) {
171 for (auto s : spec_list) {
172 if (s < 0)
173 continue;
174 if (s < spec_min || s > spec_max)
175 indices.emplace_back(s);
176 }
177 }
178 } else if (list) {
179 spec_max = 0;
180 spec_min = numberOfHist - 1;
181 for (auto s : spec_list) {
182 if (s < 0)
183 continue;
184 indices.emplace_back(s);
185 if (s > spec_max)
186 spec_max = s;
187 if (s < spec_min)
188 spec_min = s;
189 }
190 } else {
191 spec_min = 0;
192 spec_max = numberOfHist - 1;
193 indices.reserve(1 + spec_max - spec_min);
194 for (int i = spec_min; i <= spec_max; i++)
195 indices.emplace_back(i);
196 }
197}
198
199void SaveNexusProcessed::doExec(const Workspace_sptr &inputWorkspace, std::shared_ptr<Nexus::NexusFileIO> &nexusFile,
200 const bool keepFile, optional_size_t entryNumber) {
201 //
202 //
203
204 // Retrieve the filename from the properties
205 const std::string filename = getPropertyValue("Filename");
206 std::string title = getPropertyValue("Title");
207 // Do we preserve events?
208 const bool PreserveEvents = getProperty("PreserveEvents");
209
210 MatrixWorkspace_const_sptr matrixWorkspace = std::dynamic_pointer_cast<const MatrixWorkspace>(inputWorkspace);
211 ITableWorkspace_const_sptr tableWorkspace = std::dynamic_pointer_cast<const ITableWorkspace>(inputWorkspace);
212 IPeaksWorkspace_const_sptr peaksWorkspace = std::dynamic_pointer_cast<const IPeaksWorkspace>(inputWorkspace);
213 OffsetsWorkspace_const_sptr offsetsWorkspace = std::dynamic_pointer_cast<const OffsetsWorkspace>(inputWorkspace);
214 MaskWorkspace_const_sptr maskWorkspace = std::dynamic_pointer_cast<const MaskWorkspace>(inputWorkspace);
215 if (peaksWorkspace)
216 g_log.debug("We have a peaks workspace");
217 // check if inputWorkspace is something we know how to save
218 if (!matrixWorkspace && !tableWorkspace) {
219 // get the workspace name for the error message
220 const std::string name = getProperty("InputWorkspace");
221
222 // md workspaces should be saved using SaveMD
223 if (bool(std::dynamic_pointer_cast<const IMDEventWorkspace>(inputWorkspace)) ||
224 bool(std::dynamic_pointer_cast<const IMDHistoWorkspace>(inputWorkspace)))
225 g_log.warning() << name << " can be saved using SaveMD\n";
226
227 // standard error message
228 std::stringstream msg;
229 msg << "Workspace \"" << name << "\" not saved because it is not of a type we can presently save.";
230
231 throw std::runtime_error(msg.str());
232 }
233 m_eventWorkspace = std::dynamic_pointer_cast<const EventWorkspace>(matrixWorkspace);
234 const std::string workspaceID = inputWorkspace->id();
235 if ((workspaceID.find("Workspace2D") == std::string::npos) &&
236 (workspaceID.find("RebinnedOutput") == std::string::npos) &&
237 (workspaceID.find("WorkspaceSingleValue") == std::string::npos) &&
238 (workspaceID.find("GroupingWorkspace") == std::string::npos) && !m_eventWorkspace && !tableWorkspace &&
239 !offsetsWorkspace && !maskWorkspace)
240 throw Exception::NotImplementedError("SaveNexusProcessed passed invalid workspaces. Must be Workspace2D, "
241 "EventWorkspace, ITableWorkspace, OffsetsWorkspace, "
242 "GroupingWorkspace, or MaskWorkspace.");
243
244 // Create progress object for initial part - depends on whether events are
245 // processed
246 if (PreserveEvents && m_eventWorkspace) {
247 m_timeProgInit = 0.07; // Events processed 0.05 to 1.0
248 } else {
249 m_timeProgInit = 1.0; // All work is done in the initial part
250 }
251 Progress prog_init(this, 0.0, m_timeProgInit, 7);
252
253 // If no title's been given, use the workspace title field
254 if (title.empty())
255 title = inputWorkspace->getTitle();
256
257 // get the workspace name to write to file
258 const std::string wsName = inputWorkspace->getName();
259
260 // If not append, openNexusWrite will open with _CREATES perm and overwrite
261 const bool append_to_file = getProperty("Append");
262
263 nexusFile->resetProgress(&prog_init);
264 nexusFile->openNexusWrite(filename, entryNumber, append_to_file || keepFile);
265
266 prog_init.reportIncrement(1, "Opening file");
267 if (nexusFile->writeNexusProcessedHeader(title, wsName) != 0)
268 throw Exception::FileError("Failed to write to file", filename);
269
270 prog_init.reportIncrement(1, "Writing header");
271
272 // write instrument data, if present and writer enabled
273 if (matrixWorkspace) {
274 // Save the instrument names, ParameterMap, sample, run
275 matrixWorkspace->saveExperimentInfoNexus(nexusFile->filehandle().get(), saveLegacyInstrument());
276 prog_init.reportIncrement(1, "Writing sample and instrument");
277
278 // check if all X() are in fact the same array
279 const bool uniformSpectra = matrixWorkspace->isCommonBins();
280 const bool raggedSpectra = matrixWorkspace->isRaggedWorkspace();
281
282 // Retrieve the workspace indices (from params)
283 std::vector<int> indices;
284 this->getWSIndexList(indices, matrixWorkspace);
285
286 prog_init.reportIncrement(1, "Writing data");
287 // Write out the data (2D or event)
288 if (m_eventWorkspace && PreserveEvents) {
289 this->execEvent(nexusFile.get(), uniformSpectra, raggedSpectra, indices);
290 } else {
291 std::string workspaceTypeGroupName;
292 if (offsetsWorkspace)
293 workspaceTypeGroupName = "offsets_workspace";
294 else if (maskWorkspace)
295 workspaceTypeGroupName = "mask_workspace";
296 else if (std::dynamic_pointer_cast<const GroupingWorkspace>(inputWorkspace))
297 workspaceTypeGroupName = "grouping_workspace";
298 else
299 workspaceTypeGroupName = "workspace";
300
301 nexusFile->writeNexusProcessedData2D(matrixWorkspace, uniformSpectra, raggedSpectra, indices,
302 workspaceTypeGroupName.c_str(), true);
303 }
304
305 if (saveLegacyInstrument()) {
306 nexusFile->filehandle()->openGroup("instrument", "NXinstrument");
307 nexusFile->filehandle()->makeGroup("detector", "NXdetector", true);
308
309 nexusFile->filehandle()->putAttr("version", 1);
310 saveSpectraDetectorMapNexus(*matrixWorkspace, nexusFile->filehandle().get(), indices, NXcompression::LZW);
311 saveSpectrumNumbersNexus(*matrixWorkspace, nexusFile->filehandle().get(), indices, NXcompression::LZW);
312 nexusFile->filehandle()->closeGroup();
313 nexusFile->filehandle()->closeGroup();
314 }
315
316 } // finish matrix workspace specifics
317
318 if (peaksWorkspace) {
319 // Save the instrument names, ParameterMap, sample, run
320 peaksWorkspace->saveExperimentInfoNexus(nexusFile->filehandle().get());
321 prog_init.reportIncrement(1, "Writing sample and instrument");
322 peaksWorkspace->saveNexus(nexusFile->filehandle().get());
323 } else if (tableWorkspace) {
324 nexusFile->writeNexusTableWorkspace(tableWorkspace, "table_workspace");
325 }
326
327 // Switch to the Cpp API for the algorithm history
328 if (trackingHistory()) {
329 m_history->fillAlgorithmHistory(this, Mantid::Types::Core::DateAndTime::getCurrentTime(), 0,
331 if (!isChild()) {
332 inputWorkspace->history().addHistory(m_history);
333 }
334 // this is a child algorithm, but we still want to keep the history.
336 m_parentHistory->addChildHistory(m_history);
337 }
338 }
339
340 inputWorkspace->history().saveNexus(nexusFile->filehandle().get());
341 nexusFile->closeGroup();
342}
343
344//-----------------------------------------------------------------------------------------------
350 Workspace_sptr inputWorkspace = getProperty("InputWorkspace");
351
352 // Then immediately open the file
353 auto nexusFile = std::make_shared<Mantid::Nexus::NexusFileIO>();
354
355 // Perform the execution.
356 doExec(inputWorkspace, nexusFile);
357
358 // nexusFile->closeNexusFile();
359}
360
361//-------------------------------------------------------------------------------------
370template <class T>
371void SaveNexusProcessed::appendEventListData(const std::vector<T> &events, size_t offset, double *tofs, float *weights,
372 float *errorSquareds, int64_t *pulsetimes) {
373 // Do nothing if there are no events.
374 if (events.empty())
375 return;
376
377 const auto it = events.cbegin();
378 const auto it_end = events.cend();
379
380 // Fill the C-arrays with the fields from all the events, as requested.
381 if (tofs) {
382 std::transform(it, it_end, std::next(tofs, offset), [](const T &event) { return event.tof(); });
383 }
384 if (weights) {
385 std::transform(it, it_end, std::next(weights, offset),
386 [](const T &event) { return static_cast<float>(event.weight()); });
387 }
388 if (errorSquareds) {
389 std::transform(it, it_end, std::next(errorSquareds, offset),
390 [](const T &event) { return static_cast<float>(event.errorSquared()); });
391 }
392 if (pulsetimes) {
393 std::transform(it, it_end, std::next(pulsetimes, offset),
394 [](const T &event) { return event.pulseTime().totalNanoseconds(); });
395 }
396}
397
398//-----------------------------------------------------------------------------------------------
402void SaveNexusProcessed::execEvent(const Mantid::Nexus::NexusFileIO *nexusFile, const bool uniformSpectra,
403 const bool raggedSpectra, const std::vector<int> &spec) {
404 std::vector<int64_t> indices;
405 indices.reserve(spec.size() + 1);
406 // First we need to index the events in each spectrum
407 size_t index = 0;
408 for (auto s : spec) {
409 indices.emplace_back(index);
410 index += m_eventWorkspace->getSpectrum(s).getNumberEvents();
411 }
412 indices.emplace_back(index);
413
414 m_progress = std::make_unique<Progress>(this, m_timeProgInit, 1.0, index * 2);
415
416 // Start by writing out the axes and crap
417 nexusFile->writeNexusProcessedData2D(m_eventWorkspace, uniformSpectra, raggedSpectra, spec, "event_workspace", false);
418
419 // Make a super long list of tofs, weights, etc.
420
421 // Initialize all the arrays
422 int64_t num = index;
423 double *tofs = nullptr;
424 float *weights = nullptr;
425 float *errorSquareds = nullptr;
426 int64_t *pulsetimes = nullptr;
427
428 // overall event type.
429 EventType type = m_eventWorkspace->getEventType();
430 bool writeTOF = true;
431 bool writePulsetime = false;
432 bool writeWeight = false;
433 bool writeError = false;
434
435 switch (type) {
436 case TOF:
437 writePulsetime = true;
438 break;
439 case WEIGHTED:
440 writePulsetime = true;
441 writeWeight = true;
442 writeError = true;
443 break;
444 case WEIGHTED_NOTIME:
445 writeWeight = true;
446 writeError = true;
447 break;
448 }
449
450 // --- Initialize the combined event arrays ----
451 if (writeTOF)
452 tofs = new double[num];
453 if (writeWeight)
454 weights = new float[num];
455 if (writeError)
456 errorSquareds = new float[num];
457 if (writePulsetime)
458 pulsetimes = new int64_t[num];
459
460 // --- Fill in the combined event arrays ----
462 for (int wi = 0; wi < static_cast<int>(spec.size()); wi++) {
464 const DataObjects::EventList &el = m_eventWorkspace->getSpectrum(spec[wi]);
465
466 // This is where it will land in the output array.
467 // It is okay to write in parallel since none should step on each other.
468 size_t offset = indices[wi];
469
470 switch (el.getEventType()) {
471 case TOF:
472 appendEventListData(el.getEvents(), offset, tofs, weights, errorSquareds, pulsetimes);
473 break;
474 case WEIGHTED:
475 appendEventListData(el.getWeightedEvents(), offset, tofs, weights, errorSquareds, pulsetimes);
476 break;
477 case WEIGHTED_NOTIME:
478 appendEventListData(el.getWeightedEventsNoTime(), offset, tofs, weights, errorSquareds, pulsetimes);
479 break;
480 }
481 m_progress->reportIncrement(el.getNumberEvents(), "Copying EventList");
482
484 }
486
487 /*Default = DONT compress - much faster*/
488 bool CompressNexus = getProperty("CompressNexus");
489
490 // Write out to the NXS file.
491 nexusFile->writeNexusProcessedDataEventCombined(m_eventWorkspace, indices, tofs, weights, errorSquareds, pulsetimes,
492 CompressNexus);
493
494 // Free mem.
495 delete[] tofs;
496 delete[] weights;
497 delete[] errorSquareds;
498 delete[] pulsetimes;
499}
500
501//-----------------------------------------------------------------------------------------------
508void SaveNexusProcessed::setOtherProperties(IAlgorithm *alg, const std::string &propertyName,
509 const std::string &propertyValue, int perioidNum) {
510 if (propertyName == "Append") {
511 if (perioidNum != 1) {
512 alg->setPropertyValue(propertyName, "1");
513 } else
514 alg->setPropertyValue(propertyName, propertyValue);
515 } else
516 Algorithm::setOtherProperties(alg, propertyName, propertyValue, perioidNum);
517}
518
523 // Then immediately open the file
524 auto nexusFile = std::make_shared<Mantid::Nexus::NexusFileIO>();
525
526 // If we have arrived here then a WorkspaceGroup was passed to the
527 // InputWorkspace property. Pull out the unrolled workspaces and append an
528 // entry for each one. We only have a single input workspace property declared
529 // so there will only be a single list of unrolled workspaces
530 const auto &workspaces = m_unrolledInputWorkspaces[0];
531 if (!workspaces.empty()) {
532 for (size_t entry = 0; entry < workspaces.size(); entry++) {
533 const Workspace_sptr ws = workspaces[entry];
534 if (ws->isGroup()) {
535 throw std::runtime_error("NeXus files do not "
536 "support nested groups of groups");
537 }
538 this->doExec(ws, nexusFile, entry > 0 /*keepFile*/, entry);
539 g_log.information() << "Saving group index " << entry << "\n";
540 }
541 }
542
543 nexusFile->closeNexusFile();
544
545 return true;
546}
547
555 const std::vector<int> &wsIndices,
556 const NXcompression compression) const {
557
558 std::vector<int32_t> detector_index;
559 std::vector<int32_t> detector_count;
560 std::vector<int32_t> detector_list;
561 int numberSpec = 0;
562 size_t nDetectors = 0;
563 /*Make the mappings needed for writing to disk*/
564 makeMappings(ws, wsIndices, detector_index, detector_count, detector_list, numberSpec, nDetectors);
565 if (nDetectors == 0)
566 return;
567
568 // write data as Nexus sections detector{index,count,list}
569 Nexus::DimVector dims(1, numberSpec);
570 file->writeCompData("detector_index", detector_index, dims, compression, dims);
571 file->writeCompData("detector_count", detector_count, dims, compression, dims);
572 dims.front() = static_cast<int>(nDetectors);
573 file->writeCompData("detector_list", detector_list, dims, compression, dims);
574 // Get all the positions
575 try {
576 std::vector<double> detPos(nDetectors * 3);
578 Geometry::IComponent_const_sptr sample = inst->getSample();
579 if (sample) {
580 Kernel::V3D sample_pos = sample->getPos();
581 for (size_t i = 0; i < nDetectors; i++) {
582 double R, Theta, Phi;
583 try {
584 Geometry::IDetector_const_sptr det = inst->getDetector(detector_list[i]);
585 Kernel::V3D pos = det->getPos() - sample_pos;
586 pos.getSpherical(R, Theta, Phi);
587 R = det->getDistance(*sample);
588 Theta = ws.detectorTwoTheta(*det) * Geometry::rad2deg;
589 } catch (...) {
590 R = 0.;
591 Theta = 0.;
592 Phi = 0.;
593 }
594 // Need to get R & Theta through these methods to be correct for grouped
595 // detectors
596 detPos[3 * i] = R;
597 detPos[3 * i + 1] = Theta;
598 detPos[3 * i + 2] = Phi;
599 }
600 } else
601 for (size_t i = 0; i < 3 * nDetectors; i++)
602 detPos[i] = 0.;
603
604 dims.front() = static_cast<int>(nDetectors);
605 dims.emplace_back(3);
606 file->writeCompData("detector_positions", detPos, dims, compression, dims);
607 } catch (...) {
608 g_log.error("Unknown error caught when saving detector positions.");
609 }
610}
611
619 const std::vector<int> &wsIndices,
620 const NXcompression compression) const {
621 const auto numberSpec = int(wsIndices.size());
622 std::vector<int32_t> spectra;
623 spectra.reserve(static_cast<size_t>(numberSpec));
624 for (const auto index : wsIndices) {
625 const auto &spectrum = ws.getSpectrum(static_cast<size_t>(index));
626 spectra.emplace_back(static_cast<int32_t>(spectrum.getSpectrumNo()));
627 }
628
629 const Nexus::DimVector dims(1, numberSpec);
630 file->writeCompData("spectra", spectra, dims, compression, dims);
631}
632
633} // namespace Mantid::DataHandling
#define DECLARE_ALGORITHM(classname)
Definition Algorithm.h:542
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:426
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:419
bool isChild() const override
To query whether algorithm is a child.
Kernel::Logger & g_log
Definition Algorithm.h:423
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:430
bool isRecordingHistoryForChild()
Definition Algorithm.h:226
static size_t g_execCount
Counter to keep track of algorithm execution order.
Definition Algorithm.h:411
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 const > settings)
Add a PropertySettings instance to the chain of settings for a given property.
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