Mantid
Loading...
Searching...
No Matches
LoadMD.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 +
28#include "MantidKernel/MDUnit.h"
30#include "MantidKernel/Memory.h"
32#include "MantidKernel/System.h"
34#include <boost/algorithm/string.hpp>
35#include <boost/regex.hpp>
36#include <nexus/NeXusException.hpp>
37#include <vector>
38
39using namespace Mantid::Kernel;
40using namespace Mantid::API;
41using namespace Mantid::Geometry;
42using namespace Mantid::DataObjects;
43
44using file_holder_type = std::unique_ptr<Mantid::DataObjects::BoxControllerNeXusIO>;
45
46namespace Mantid::MDAlgorithms {
47
49
50//----------------------------------------------------------------------------------------------
54 : m_numDims(0), // uninitialized incorrect value
55 m_coordSystem(None), m_BoxStructureAndMethadata(true), // this is faster but rarely needed.
56 m_saveMDVersion(false), m_requiresMDFrameCorrection(false) {}
57
65 int confidence = 0;
66 const std::map<std::string, std::set<std::string>> &allEntries = descriptor.getAllEntries();
67 if (allEntries.count("NXentry") == 1) {
68 if (descriptor.isEntry("/MDEventWorkspace") || descriptor.isEntry("/MDHistoWorkspace")) {
69 confidence = 95;
70 }
71 }
72
73 return confidence;
74}
75
76//----------------------------------------------------------------------------------------------
77
78//----------------------------------------------------------------------------------------------
82 declareProperty(std::make_unique<FileProperty>("Filename", "", FileProperty::Load, ".nxs"),
83 "The name of the Nexus file to load, as a full or relative path");
84
85 declareProperty(std::make_unique<Kernel::PropertyWithValue<bool>>("MetadataOnly", false),
86 "Load Box structure and other metadata without events. The "
87 "loaded workspace will be empty and not file-backed.");
88
89 declareProperty(std::make_unique<Kernel::PropertyWithValue<bool>>("BoxStructureOnly", false),
90 "Load partial information about the boxes and events. Redundant property "
91 "currently equivalent to MetadataOnly");
92
93 declareProperty(std::make_unique<PropertyWithValue<bool>>("FileBackEnd", false),
94 "Set to true to load the data only on demand.");
95 setPropertySettings("FileBackEnd", std::make_unique<EnabledWhenProperty>("MetadataOnly", IS_EQUAL_TO, "0"));
96
97 declareProperty(std::make_unique<PropertyWithValue<double>>("Memory", -1),
98 "For FileBackEnd only: the amount of memory (in MB) to allocate to the "
99 "in-memory cache.\n"
100 "If not specified, a default of 40% of free physical memory is used.");
101 setPropertySettings("Memory", std::make_unique<EnabledWhenProperty>("FileBackEnd", IS_EQUAL_TO, "1"));
102
103 declareProperty("LoadHistory", true, "If true, the workspace history will be loaded");
104
105 declareProperty(std::make_unique<WorkspaceProperty<IMDWorkspace>>("OutputWorkspace", "", Direction::Output),
106 "Name of the output MDEventWorkspace.");
107}
108
109//----------------------------------------------------------------------------------------------
113 m_filename = getPropertyValue("Filename");
114 convention = Kernel::ConfigService::Instance().getString("Q.convention");
115 // Start loading
116 bool fileBacked = this->getProperty("FileBackEnd");
117
118 m_BoxStructureAndMethadata = getProperty("MetadataOnly");
119
120 bool BoxAndEventInfoOnly = this->getProperty("BoxStructureOnly");
121 if (m_BoxStructureAndMethadata || BoxAndEventInfoOnly) {
123 }
124
125 // Nexus constructor/destructor throw, so can not be used with scoped pointers
126 // directly
127 //(do they lock file because of this and this code is useless?)
128 std::string for_access;
129 if (fileBacked) {
130
131 for_access = "for Read/Write access";
132 m_file.reset(new ::NeXus::File(m_filename, NXACC_RDWR));
133 } else {
134 for_access = "for Read access";
135 m_file.reset(new ::NeXus::File(m_filename, NXACC_READ));
136 }
137
138 if (!m_file)
139 throw Kernel::Exception::FileError("Can not open file " + for_access, m_filename);
140
141 // The main entry
142 const std::shared_ptr<Mantid::Kernel::NexusHDF5Descriptor> fileInfo = getFileInfo();
143
144 std::string entryName;
145 if (fileInfo->isEntry("/MDEventWorkspace", "NXentry")) {
146 entryName = "MDEventWorkspace";
147 } else if (fileInfo->isEntry("/MDHistoWorkspace", "NXentry")) {
148 entryName = "MDHistoWorkspace";
149 } else {
150 throw std::runtime_error("Unexpected NXentry name. Expected "
151 "'MDEventWorkspace' or 'MDHistoWorkspace'.");
152 }
153
154 // Open the entry
155 m_file->openGroup(entryName, "NXentry");
156
157 // Check is SaveMD version 2 was used
158 m_saveMDVersion = 0;
159 if (m_file->hasAttr("SaveMDVersion"))
160 m_file->getAttr("SaveMDVersion", m_saveMDVersion);
161
162 if (m_saveMDVersion == 2)
163 this->loadDimensions2();
164 else {
165 // How many dimensions?
166 std::vector<int32_t> vecDims;
167 m_file->readData("dimensions", vecDims);
168 if (vecDims.empty())
169 throw std::runtime_error("LoadMD:: Error loading number of dimensions.");
170 m_numDims = vecDims[0];
171 if (m_numDims == 0)
172 throw std::runtime_error("LoadMD:: number of dimensions == 0.");
173
174 // Now load all the dimension xml
175 this->loadDimensions();
176 }
177
178 // Coordinate system
179 this->loadCoordinateSystem();
180
181 // QConvention (Inelastic or Crystallography)
182 this->loadQConvention();
183
184 // Display normalization settting
185 if (fileInfo->isEntry("/" + entryName + "/" + VISUAL_NORMALIZATION_KEY)) {
187 }
188
189 if (entryName == "MDEventWorkspace") {
190 // The type of event
191 std::string eventType;
192 m_file->getAttr("event_type", eventType);
193
194 if (fileInfo->isEntry("/" + entryName + "/" + VISUAL_NORMALIZATION_KEY_HISTO)) {
196 }
197
198 // Use the factory to make the workspace of the right type
203 } else {
205 }
206
207 // Now the ExperimentInfo
208 bool lazyLoadExpt = fileBacked;
209 MDBoxFlatTree::loadExperimentInfos(m_file.get(), m_filename, ws, *fileInfo.get(), "MDEventWorkspace", lazyLoadExpt);
210
211 // Wrapper to cast to MDEventWorkspace then call the function
212 CALL_MDEVENT_FUNCTION(this->doLoad, ws);
213
214 // Check if a MDFrame adjustment is required
218 }
219 // Write out the Qconvention
220 // ki-kf for Inelastic convention; kf-ki for Crystallography convention
221 std::string pref_QConvention = Kernel::ConfigService::Instance().getString("Q.convention");
222 g_log.information() << "Convention for Q in Preferences is " << pref_QConvention
223 << "; Convention of Q in NeXus file is " << m_QConvention << '\n';
224
225 if (pref_QConvention != m_QConvention) {
226 std::vector<double> scaling(m_numDims);
227 scaling = qDimensions(ws);
228 g_log.information() << "Transforming Q\n";
229 Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
230 transform_alg->setProperty("InputWorkspace", std::dynamic_pointer_cast<IMDWorkspace>(ws));
231 transform_alg->setProperty("Scaling", scaling);
232 transform_alg->executeAsChildAlg();
233 IMDWorkspace_sptr tmp = transform_alg->getProperty("OutputWorkspace");
234 ws = std::dynamic_pointer_cast<IMDEventWorkspace>(tmp);
235 }
236 // Save to output
237 setProperty("OutputWorkspace", std::dynamic_pointer_cast<IMDWorkspace>(ws));
238 } else {
239 // MDHistoWorkspace case.
240 this->loadHisto();
241 }
242}
243
252void LoadMD::loadSlab(const std::string &name, void *data, const MDHistoWorkspace_sptr &ws,
253 ::NeXus::NXnumtype dataType) {
254 m_file->openData(name);
255 if (m_file->getInfo().type != dataType)
256 throw std::runtime_error("Unexpected data type for '" + name + "' data set.'");
257
258 int nPoints = 1;
259 size_t numDims = m_file->getInfo().dims.size();
260 std::vector<int> size(numDims);
261 for (size_t d = 0; d < numDims; d++) {
262 nPoints *= static_cast<int>(m_file->getInfo().dims[d]);
263 size[d] = static_cast<int>(m_file->getInfo().dims[d]);
264 }
265 if (nPoints != static_cast<int>(ws->getNPoints()))
266 throw std::runtime_error("Inconsistency between the number of points in '" + name +
267 "' and the number of bins defined by the dimensions.");
268 std::vector<int> start(numDims, 0);
269 try {
270 m_file->getSlab(data, start, size);
271 } catch (...) {
272 g_log.debug() << " start: " << start[0] << " size: " << size[0] << '\n';
273 }
274 m_file->closeData();
275}
276
277//----------------------------------------------------------------------------------------------
282 // Create the initial MDHisto.
284 // If display normalization has been provided. Use that.
286 ws = std::make_shared<MDHistoWorkspace>(m_dims, m_visualNormalization.get());
287 } else {
288 ws = std::make_shared<MDHistoWorkspace>(m_dims); // Whatever MDHistoWorkspace defaults to.
289 }
290
291 // Now the ExperimentInfo
293
294 // Coordinate system
295 ws->setCoordinateSystem(m_coordSystem);
296
297 // Load the WorkspaceHistory "process"
298 if (this->getProperty("LoadHistory")) {
299 ws->history().loadNexus(m_file.get());
300 }
301
302 this->loadAffineMatricies(std::dynamic_pointer_cast<IMDWorkspace>(ws));
303
304 if (m_saveMDVersion == 2)
305 m_file->openGroup("data", "NXdata");
306 // Load each data slab
307 this->loadSlab("signal", ws->mutableSignalArray(), ws, ::NeXus::FLOAT64);
308 this->loadSlab("errors_squared", ws->mutableErrorSquaredArray(), ws, ::NeXus::FLOAT64);
309 this->loadSlab("num_events", ws->mutableNumEventsArray(), ws, ::NeXus::FLOAT64);
310 this->loadSlab("mask", ws->mutableMaskArray(), ws, ::NeXus::INT8);
311
312 m_file->close();
313
314 // Check if a MDFrame adjustment is required
318 }
319
320 // Write out the Qconvention
321 // ki-kf for Inelastic convention; kf-ki for Crystallography convention
322 std::string pref_QConvention = Kernel::ConfigService::Instance().getString("Q.convention");
323 g_log.information() << "Convention for Q in Preferences is " << pref_QConvention
324 << "; Convention of Q in NeXus file is " << m_QConvention << '\n';
325
326 if (pref_QConvention != m_QConvention) {
327 std::vector<double> scaling(m_numDims);
328 scaling = qDimensions(ws);
329 g_log.information() << "Transforming Q\n";
330 Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
331 transform_alg->setProperty("InputWorkspace", std::dynamic_pointer_cast<IMDWorkspace>(ws));
332 transform_alg->setProperty("Scaling", scaling);
333 transform_alg->executeAsChildAlg();
334 IMDWorkspace_sptr tmp = transform_alg->getProperty("OutputWorkspace");
335 ws = std::dynamic_pointer_cast<MDHistoWorkspace>(tmp);
336 }
337
338 // Save to output
339 setProperty("OutputWorkspace", std::dynamic_pointer_cast<IMDWorkspace>(ws));
340}
341
342//----------------------------------------------------------------------------------------------
345 m_dims.clear();
346
347 // Load each dimension, as their XML representation
348 for (size_t d = 0; d < m_numDims; d++) {
349 std::ostringstream mess;
350 mess << "dimension" << d;
351 std::string dimXML;
352 m_file->getAttr(mess.str(), dimXML);
353 // Use the dimension factory to read the XML
354 m_dims.emplace_back(createDimension(dimXML));
355 }
356 // Since this is an old algorithm we will
357 // have to provide an MDFrame correction
359}
360
361//----------------------------------------------------------------------------------------------
365 using namespace Geometry;
366 m_dims.clear();
367
368 std::string axes;
369
370 m_file->openGroup("data", "NXdata");
371 m_file->openData("signal");
372 m_file->getAttr("axes", axes);
373 m_file->closeData();
374
375 std::vector<std::string> splitAxes;
376 boost::split(splitAxes, axes, boost::is_any_of(":"));
377 // Create each dimension from axes data
378 // We loop axes backwards because Mantid
379 for (size_t d = splitAxes.size(); d > 0; d--) {
380 std::string long_name;
381 std::string units;
382 std::string frame;
383 std::vector<double> axis;
384 m_file->openData(splitAxes[d - 1]);
385 m_file->getAttr("long_name", long_name);
386 m_file->getAttr("units", units);
387 try {
388 m_file->getAttr("frame", frame);
389 } catch (std::exception &) {
392 }
394 m_file->getData(axis);
395 m_file->closeData();
396 m_dims.emplace_back(std::make_shared<MDHistoDimension>(long_name, splitAxes[d - 1], *mdFrame,
397 static_cast<coord_t>(axis.front()),
398 static_cast<coord_t>(axis.back()), axis.size() - 1));
399 }
400 m_file->closeGroup();
401 m_numDims = m_dims.size();
402}
403
404void LoadMD::loadVisualNormalization(const std::string &key,
405 boost::optional<Mantid::API::MDNormalization> &normalization) {
406 try {
407 uint32_t readVisualNormalization(0);
408 m_file->readData(key, readVisualNormalization);
409 normalization = static_cast<Mantid::API::MDNormalization>(readVisualNormalization);
410 } catch (::NeXus::Exception &) {
411
412 } catch (std::exception &) {
413 }
414}
415
418 // Current version stores the coordinate system
419 // in its own field. The first version stored it
420 // as a log value so fallback on that if it can't
421 // be found.
422 try {
423 uint32_t readCoord(0);
424 m_file->readData("coordinate_system", readCoord);
425 m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord);
426 } catch (::NeXus::Exception &) {
427 auto pathOnEntry = m_file->getPath();
428 try {
429 m_file->openPath(pathOnEntry + "/experiment0/logs/CoordinateSystem");
430 int readCoord(0);
431 m_file->readData("value", readCoord);
432 m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord);
433 } catch (::NeXus::Exception &) {
434 }
435 // return to where we started
436 m_file->openPath(pathOnEntry);
437 }
438}
439
442 try {
443 m_file->getAttr("QConvention", m_QConvention);
444 } catch (std::exception &) {
445 m_QConvention = "Inelastic";
446 }
447}
448
449//----------------------------------------------------------------------------------------------
456template <typename MDE, size_t nd> void LoadMD::doLoad(typename MDEventWorkspace<MDE, nd>::sptr ws) {
457 // Are we using the file back end?
458 bool fileBackEnd = getProperty("FileBackEnd");
459
460 if (fileBackEnd && m_BoxStructureAndMethadata)
461 throw std::invalid_argument("Combination of BoxStructureOnly or "
462 "MetaDataOnly were set to TRUE with "
463 "fileBackEnd "
464 ": this is not possible.");
465
466 CPUTimer tim;
467 auto prog = std::make_unique<Progress>(this, 0.0, 1.0, 100);
468
469 prog->report("Opening file.");
470 std::string title;
471 try {
472 m_file->getAttr("title", title);
473 } catch (std::exception &) {
474 // Leave the title blank if error on loading
475 }
476 ws->setTitle(title);
477
478 // Load the WorkspaceHistory "process"
479 if (this->getProperty("LoadHistory")) {
480 ws->history().loadNexus(m_file.get());
481 }
482
483 this->loadAffineMatricies(std::dynamic_pointer_cast<IMDWorkspace>(ws));
484
485 m_file->closeGroup();
486 m_file->close();
487 // Add each of the dimension
488 for (size_t d = 0; d < nd; d++)
489 ws->addDimension(m_dims[d]);
490
491 // Coordinate system
493
494 // ----------------------------------------- Box Structure
495 // ------------------------------
496 prog->report("Reading box structure from HDD.");
497 MDBoxFlatTree FlatBoxTree;
498 auto nDims = static_cast<int>(nd); // should be safe
499 FlatBoxTree.loadBoxStructure(m_filename, nDims, MDE::getTypeName());
500
502 bc->fromXMLString(FlatBoxTree.getBCXMLdescr());
503
504 prog->report("Restoring box structure and connectivity");
505 std::vector<API::IMDNode *> boxTree;
506 FlatBoxTree.restoreBoxTree(boxTree, bc, fileBackEnd, m_BoxStructureAndMethadata);
507 size_t numBoxes = boxTree.size();
508
509 // ---------------------------------------- DEAL WITH BOXES
510 // ------------------------------------
511 if (fileBackEnd) { // TODO:: call to the file format factory
512 auto loader = std::shared_ptr<DataObjects::BoxControllerNeXusIO>(new DataObjects::BoxControllerNeXusIO(bc.get()));
513 loader->setDataType(sizeof(coord_t), MDE::getTypeName());
514 bc->setFileBacked(loader, m_filename);
515 // boxes have been already made file-backed when restoring the boxTree;
516 // How much memory for the cache?
517 {
518 // TODO: Clean up, only a write buffer now
519 double mb = getProperty("Memory");
520
521 // Defaults have changed, default disk buffer size should be 10 data
522 // chunks TODO: find optimal, 100 may be better.
523 if (mb <= 0)
524 mb = double(10 * loader->getDataChunk() * sizeof(MDE)) / double(1024 * 1024);
525
526 // Express the cache memory in units of number of events.
527 uint64_t cacheMemory = static_cast<uint64_t>((mb * 1024. * 1024.) / sizeof(MDE)) + 1;
528
529 // Set these values in the diskMRU
530 bc->getFileIO()->setWriteBufferSize(cacheMemory);
531
532 g_log.information() << "Setting a DiskBuffer cache size of " << mb << " MB, or " << cacheMemory << " events.\n";
533 }
534 } // Not file back end
535 else if (!m_BoxStructureAndMethadata) {
536 // ---------------------------------------- READ IN THE BOXES
537 // ------------------------------------
538 // TODO:: call to the file format factory
539 auto loader = file_holder_type(new DataObjects::BoxControllerNeXusIO(bc.get()));
540 loader->setDataType(sizeof(coord_t), MDE::getTypeName());
541 loader->openFile(m_filename, "r");
542
543 const std::vector<uint64_t> &BoxEventIndex = FlatBoxTree.getEventIndex();
544 prog->setNumSteps(numBoxes);
545 std::vector<coord_t> boxTemp;
546
547 for (size_t i = 0; i < numBoxes; i++) {
548 prog->report();
549 auto *box = dynamic_cast<MDBox<MDE, nd> *>(boxTree[i]);
550 if (!box)
551 continue;
552
553 if (BoxEventIndex[2 * i + 1] > 0) // Load in memory NOT using the file as the back-end,
554 {
555 boxTree[i]->reserveMemoryForLoad(BoxEventIndex[2 * i + 1]);
556 boxTree[i]->loadAndAddFrom(loader.get(), BoxEventIndex[2 * i], static_cast<size_t>(BoxEventIndex[2 * i + 1]),
557 boxTemp);
558 }
559 }
560 loader->closeFile();
561 } else // box structure and metadata only
562 {
563 }
564 g_log.debug() << tim << " to create all the boxes and fill them with events.\n";
565
566 // Box of ID 0 is the head box.
567 ws->setBox(boxTree[0]);
568 // Make sure the max ID is ok for later ID generation
569 bc->setMaxId(numBoxes);
570
571 // end-of bMetaDataOnly
572 // Refresh cache
573 // TODO:if(!fileBackEnd)ws->refreshCache();
574 ws->refreshCache();
575 g_log.debug() << tim << " to refreshCache(). " << ws->getNPoints() << " points after refresh.\n";
576
577 g_log.debug() << tim << " to finish up.\n";
578}
579
586 std::map<std::string, std::string> entries;
587 m_file->getEntries(entries);
588
589 if (entries.find("transform_to_orig") != entries.end()) {
590 CoordTransform *transform = this->loadAffineMatrix("transform_to_orig");
591 ws->setTransformToOriginal(transform);
592 }
593 if (entries.find("transform_from_orig") != entries.end()) {
594 CoordTransform *transform = this->loadAffineMatrix("transform_from_orig");
595 ws->setTransformFromOriginal(transform);
596 }
597}
598
606CoordTransform *LoadMD::loadAffineMatrix(const std::string &entry_name) {
607 m_file->openData(entry_name);
608 std::vector<coord_t> vec;
609 m_file->getData<coord_t>(vec);
610 std::string type;
611 int inD(0);
612 int outD(0);
613 m_file->getAttr("type", type);
614 m_file->getAttr<int>("rows", outD);
615 m_file->getAttr<int>("columns", inD);
616 m_file->closeData();
617 Matrix<coord_t> mat(vec, outD, inD);
618 // Adjust dimensions
619 inD--;
620 outD--;
621 CoordTransform *transform = nullptr;
622 if (("CoordTransformAffine" == type) || ("CoordTransformAligned" == type)) {
623 auto affine = new CoordTransformAffine(inD, outD);
624 affine->setMatrix(mat);
625 transform = affine;
626 } else {
627 g_log.information("Do not know how to process coordinate transform " + type);
628 }
629 return transform;
630}
631
637
638 g_log.information() << "LoadMD: Encountered a legacy file which has a mismatch between "
639 "its MDFrames and its Special Coordinate System. "
640 "Attempting to convert MDFrames.\n";
641 auto numberOfDimensions = ws->getNumDims();
642
643 // Select an MDFrame based on the special coordinates.
644 // Note that for None, we select a General Coordinate System,
645 // unless the name is "Unknown frame"
646 std::string selectedFrame;
647
648 switch (m_coordSystem) {
650 selectedFrame = Mantid::Geometry::QLab::QLabName;
651 break;
654 break;
656 selectedFrame = Mantid::Geometry::HKL::HKLName;
657 break;
658 default:
660 }
661
662 // Get the old frames just in case something goes wrong. In this case we
663 // reset the frames.
664
665 std::vector<std::string> oldFrames(numberOfDimensions, Mantid::Geometry::GeneralFrame::GeneralFrameName);
666 for (size_t index = 0; index < numberOfDimensions; ++index) {
667 oldFrames[index] = ws->getDimension(index)->getMDFrame().name();
668 }
669
670 // We want to set only up to the first three dimensions to the selected Frame;
671 // Everything else will be set to a General Frame
672 std::vector<std::string> framesToSet(numberOfDimensions, Mantid::Geometry::GeneralFrame::GeneralFrameName);
673 auto fillUpTo = numberOfDimensions > 3 ? 3 : numberOfDimensions;
674 std::fill_n(framesToSet.begin(), fillUpTo, selectedFrame);
675
676 try {
677 // Set the MDFrames for each axes
678 Algorithm_sptr setMDFrameAlg = this->createChildAlgorithm("SetMDFrame");
679 int axesCounter = 0;
680 for (auto &frame : framesToSet) {
681 setMDFrameAlg->setProperty("InputWorkspace", ws);
682 setMDFrameAlg->setProperty("MDFrame", frame);
683 setMDFrameAlg->setProperty("Axes", std::vector<int>(1, axesCounter));
684 ++axesCounter;
685 setMDFrameAlg->executeAsChildAlg();
686 }
687 } catch (...) {
688 g_log.warning() << "LoadMD: An issue occured while trying to correct "
689 "MDFrames. Trying to revert to original.\n";
690 // Revert to the old frames.
691 Algorithm_sptr setMDFrameAlg = this->createChildAlgorithm("SetMDFrame");
692 int axesCounter = 0;
693 for (auto &oldFrame : oldFrames) {
694 setMDFrameAlg->setProperty("InputWorkspace", ws);
695 setMDFrameAlg->setProperty("MDFrame", oldFrame);
696 setMDFrameAlg->setProperty("Axes", std::vector<int>(1, axesCounter));
697 ++axesCounter;
698 setMDFrameAlg->executeAsChildAlg();
699 }
700 }
701}
702
709 // Check if the special coordinate is not none
710 auto isQBasedSpecialCoordinateSystem = true;
712 isQBasedSpecialCoordinateSystem = false;
713 }
714
715 // Check if all MDFrames are of type Unknown frame
716 auto containsOnlyUnkownFrames = true;
717 for (size_t index = 0; index < ws->getNumDims(); ++index) {
718 if (ws->getDimension(index)->getMDFrame().name() != Mantid::Geometry::UnknownFrame::UnknownFrameName) {
719 containsOnlyUnkownFrames = false;
720 break;
721 }
722 }
723
724 // Check if a fix up is required
725 if (isQBasedSpecialCoordinateSystem && containsOnlyUnkownFrames) {
727 }
728}
729
733std::vector<double> LoadMD::qDimensions(const API::IMDWorkspace_sptr &ws) {
734 std::vector<double> scaling(m_numDims);
735 for (size_t d = 0; d < m_numDims; d++) {
736 std::string dimd = ws->getDimension(d)->getName();
737
738 // Assume the Q dimensions are those that have names starting with [
739 // such as [H,0.5H,0], or Q_ such as Q_sample_x.
740 // The change in sign should apply only to those.
741 boost::regex re("\\[.*|Q_");
742 if (boost::regex_search(dimd.begin(), dimd.begin() + 2, re))
743 scaling[d] = -1.0;
744 else
745 scaling[d] = 1.0;
746 }
747 return scaling;
748}
749const std::string LoadMD::VISUAL_NORMALIZATION_KEY = "visual_normalization";
750const std::string LoadMD::VISUAL_NORMALIZATION_KEY_HISTO = "visual_normalization_histo";
751
752} // namespace Mantid::MDAlgorithms
gsl_vector * tmp
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
std::unique_ptr<::NeXus::File > file_holder_type
#define CALL_MDEVENT_FUNCTION(funcname, workspace)
Macro that makes it possible to call a templated method for a MDEventWorkspace using a IMDEventWorksp...
#define DECLARE_NEXUS_HDF5_FILELOADER_ALGORITHM(classname)
DECLARE_NEXUS_HDF5_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM mac...
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
Unique SingleValueParameter Declaration for InputNDimensions.
@ Load
allowed here which will be passed to the algorithm
Definition: FileProperty.h:52
void addDimension(const std::shared_ptr< Mantid::Geometry::IMDDimension > &dim)
Add a dimension.
Definition: MDGeometry.cpp:234
virtual const std::shared_ptr< Mantid::Kernel::NexusHDF5Descriptor > getFileInfo() const noexcept
Required to pass m_fileInfo to static functions Keeping it shared_ptr to match setFileInfo signature ...
std::shared_ptr< Algorithm > createChildAlgorithm(const std::string &name, const double startProgress=-1., const double endProgress=-1., const bool enableLogging=true, const int &version=-1) override
Create a Child Algorithm.
void loadNexus(::NeXus::File *file)
Load the workspace history from a nexus file.
A property class for workspaces.
WorkspaceHistory & history()
Returns a reference to the WorkspaceHistory.
Definition: Workspace.h:82
virtual void setTitle(const std::string &)
Set the title of the workspace.
Definition: Workspace.cpp:28
The class responsible for saving events into nexus file using generic box controller interface Expect...
Generic class to transform from M input dimensions to N output dimensions.
The class responsible for saving/loading MD boxes structure to/from HDD and for flattening/restoring ...
Definition: MDBoxFlatTree.h:27
uint64_t restoreBoxTree(std::vector< API::IMDNode * > &Boxes, API::BoxController_sptr &bc, bool FileBackEnd, bool BoxStructureOnly=false)
Method recovers the interconnected box structure from the plain tree into box tree,...
const std::string & getBCXMLdescr() const
Definition: MDBoxFlatTree.h:33
void loadBoxStructure(const std::string &fileName, int &nDim, const std::string &EventType, bool onlyEventInfo=false, bool restoreExperimentInfo=false)
load box structure from the file, defined by file name
std::vector< uint64_t > & getEventIndex()
Definition: MDBoxFlatTree.h:45
static void loadExperimentInfos(::NeXus::File *const file, const std::string &filename, std::shared_ptr< API::MultipleExperimentInfos > mei, const Mantid::Kernel::NexusHDF5Descriptor &fileInfo, const std::string &currentGroup, bool lazy=false)
Templated class for a multi-dimensional event "box".
Definition: MDBox.h:45
void reserveMemoryForLoad(uint64_t) override
static API::IMDEventWorkspace_sptr CreateMDWorkspace(size_t nd, const std::string &eventType="MDLeanEvent", const Mantid::API::MDNormalization &preferredNormalization=Mantid::API::MDNormalization::VolumeNormalization, const Mantid::API::MDNormalization &preferredNormalizationHisto=Mantid::API::MDNormalization::VolumeNormalization)
Create a MDEventWorkspace of the given type.
uint64_t getNPoints() const override
std::shared_ptr< MDEventWorkspace< MDE, nd > > sptr
Typedef for a shared pointer of this kind of event workspace.
void setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordSystem) override
Set the coordinate system.
void refreshCache() override
Refresh the cache (integrated signal of each box)
Mantid::API::BoxController_sptr getBoxController() override
Returns the BoxController used in this workspace.
void setBox(API::IMDNode *box) override
Set the base-level box contained within.
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition: MDLeanEvent.h:60
static std::string getTypeName()
Definition: MDLeanEvent.h:305
static const std::string GeneralFrameName
Definition: GeneralFrame.h:25
static const std::string HKLName
Definition: HKL.h:27
Input argument type for MDFrameFactory chainable factory.
static const std::string QLabName
Definition: QLab.h:35
static const std::string QSampleName
Definition: QSample.h:23
static const std::string UnknownFrameName
Definition: UnknownFrame.h:35
CPUTimer : Timer that uses the CPU time, rather than wall-clock time to measure execution time.
Definition: CPUTimer.h:24
Records the filename and the description of failure.
Definition: Exception.h:98
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void setPropertySettings(const std::string &name, std::unique_ptr< IPropertySettings > settings)
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void warning(const std::string &msg)
Logs at warning level.
Definition: Logger.cpp:86
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
Numerical Matrix class.
Definition: Matrix.h:42
const std::map< std::string, std::set< std::string > > & getAllEntries() const noexcept
Returns a const reference of the internal map holding all entries in the NeXus HDF5 file.
bool isEntry(const std::string &entryName, const std::string &groupClass) const noexcept
Checks if a full-path entry exists for a particular groupClass in a Nexus dataset.
The concrete, templated class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Load a .nxs file into a MDEventWorkspace.
Definition: LoadMD.h:28
std::vector< double > qDimensions(const API::IMDWorkspace_sptr &ws)
Negative scaling for Q dimensions.
Definition: LoadMD.cpp:733
void loadDimensions()
Load all the dimensions into this->m_dims.
Definition: LoadMD.cpp:344
void checkForRequiredLegacyFixup(const API::IMDWorkspace_sptr &ws)
Checks if a worspace is a certain type of legacy file.
Definition: LoadMD.cpp:708
std::vector< Mantid::Geometry::IMDDimension_sptr > m_dims
Each dimension object loaded.
Definition: LoadMD.h:100
int confidence(Kernel::NexusHDF5Descriptor &descriptor) const override
Returns a confidence value that this algorithm can load a file.
Definition: LoadMD.cpp:64
API::CoordTransform * loadAffineMatrix(const std::string &entry_name)
Load a given affine matrix.
Definition: LoadMD.cpp:606
Kernel::SpecialCoordinateSystem m_coordSystem
Coordinate system.
Definition: LoadMD.h:102
void doLoad(typename DataObjects::MDEventWorkspace< MDE, nd >::sptr ws)
Helper method.
Definition: LoadMD.cpp:456
void loadSlab(const std::string &name, void *data, const DataObjects::MDHistoWorkspace_sptr &ws, ::NeXus::NXnumtype dataType)
Load a slab of double data into a bare array.
Definition: LoadMD.cpp:252
boost::optional< Mantid::API::MDNormalization > m_visualNormalizationHisto
Definition: LoadMD.h:113
void init() override
Initialise the properties.
Definition: LoadMD.cpp:81
std::string convention
Definition: LoadMD.h:53
bool m_requiresMDFrameCorrection
MDFrame correction flag.
Definition: LoadMD.h:120
void loadCoordinateSystem()
Load the coordinate system.
Definition: LoadMD.cpp:417
boost::scoped_ptr< ::NeXus::File > m_file
Open file handle.
Definition: LoadMD.h:90
std::string m_QConvention
QConvention.
Definition: LoadMD.h:104
std::string m_filename
Name of that file.
Definition: LoadMD.h:94
void loadHisto()
Perform loading for a MDHistoWorkspace.
Definition: LoadMD.cpp:281
int m_saveMDVersion
Version of SaveMD used to save the file.
Definition: LoadMD.h:109
void loadAffineMatricies(const API::IMDWorkspace_sptr &ws)
Load all the affine matricies.
Definition: LoadMD.cpp:585
bool m_BoxStructureAndMethadata
load only the box structure with empty boxes but do not tload boxes events
Definition: LoadMD.h:106
static const std::string VISUAL_NORMALIZATION_KEY_HISTO
Definition: LoadMD.h:117
static const std::string VISUAL_NORMALIZATION_KEY
Named entry.
Definition: LoadMD.h:116
void loadDimensions2()
Load all the dimensions into this->m_dims The dimensions are stored as an nxData array.
Definition: LoadMD.cpp:364
void loadVisualNormalization(const std::string &key, boost::optional< Mantid::API::MDNormalization > &normalization)
Definition: LoadMD.cpp:404
void execLoader() override
Run the algorithm.
Definition: LoadMD.cpp:112
void setMDFrameOnWorkspaceFromLegacyFile(const API::IMDWorkspace_sptr &ws)
Sets MDFrames for workspaces from legacy files.
Definition: LoadMD.cpp:636
boost::optional< Mantid::API::MDNormalization > m_visualNormalization
Visual normalization.
Definition: LoadMD.h:112
const std::string name() const override
Algorithm's name for identification.
Definition: LoadMD.h:33
size_t m_numDims
Number of dimensions in loaded file.
Definition: LoadMD.h:97
void loadQConvention()
Load the convention for Q
Definition: LoadMD.cpp:441
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
Definition: IMDWorkspace.h:146
std::shared_ptr< BoxController > BoxController_sptr
Shared ptr to BoxController.
MDNormalization
Enum describing different ways to normalize the signal in a MDWorkspace.
Definition: IMDIterator.h:25
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
Definition: Algorithm.h:61
std::shared_ptr< MDHistoWorkspace > MDHistoWorkspace_sptr
A shared pointer to a MDHistoWorkspace.
MANTID_GEOMETRY_DLL IMDDimension_sptr createDimension(const std::string &dimensionXMLString)
Creates IMDDimension objects based on input XML.
std::unique_ptr< const MDFrame > MDFrame_const_uptr
Definition: MDFrame.h:37
MDFrameFactory_uptr MANTID_GEOMETRY_DLL makeMDFrameFactoryChain()
Make a complete factory chain.
SpecialCoordinateSystem
Special coordinate systems for Q3D.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27
@ Output
An output workspace.
Definition: Property.h:54