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