Mantid
Loading...
Searching...
No Matches
ExperimentInfo.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 +
11#include "MantidAPI/Run.h"
12#include "MantidAPI/Sample.h"
14
28
29#include "MantidBeamline/ComponentInfo.h"
30#include "MantidBeamline/DetectorInfo.h"
31#include "MantidBeamline/SpectrumInfo.h"
32
41
42#include "MantidTypes/SpectrumDefinition.h"
43
44#include <boost/algorithm/string.hpp>
45#include <boost/lexical_cast.hpp>
46#include <boost/regex.hpp>
47
48#include <Poco/Path.h>
49#include <nexus/NeXusException.hpp>
50
51#include <algorithm>
52#include <memory>
53#include <tuple>
54
55using namespace Mantid::Geometry;
56using namespace Mantid::Kernel;
57using namespace Mantid::Types::Core;
58
59namespace Mantid::API {
60namespace {
62Kernel::Logger g_log("ExperimentInfo");
63
64} // namespace
65
68ExperimentInfo::ExperimentInfo() : m_parmap(new ParameterMap()), sptr_instrument(new Instrument()) {
69 m_parmap->setInstrument(sptr_instrument.get());
70}
71
77ExperimentInfo::ExperimentInfo(const ExperimentInfo &source) { *this = source; }
78
83 this->copyExperimentInfoFrom(&source);
85 return *this;
86}
87
88// Defined as default in source for forward declaration with std::unique_ptr.
90
96 m_sample = other->m_sample;
97 m_run = other->m_run;
98 this->setInstrument(other->getInstrument());
99 // We do not copy Beamline::SpectrumInfo (which contains detector grouping
100 // information) for now:
101 // - For MatrixWorkspace, grouping information is still stored in ISpectrum
102 // and should not be overridden (copy is done in ExperimentInfo ctor, but
103 // not here since we just copy the experiment data).
104 // - For cached groupings (for MDWorkspaces), grouping was not copied in the
105 // old implementation either.
106}
107
111
113const std::string ExperimentInfo::toString() const {
114 try {
116 } catch (std::exception &) {
117 // Catch any errors so that the string returned has as much information
118 // as possible
119 }
120
121 std::ostringstream out;
122
124 const auto instName = inst->getName();
125 out << "Instrument: ";
126 if (!instName.empty()) {
127 out << instName << " (" << inst->getValidFromDate().toFormattedString("%Y-%b-%d") << " to "
128 << inst->getValidToDate().toFormattedString("%Y-%b-%d") << ")";
129 const auto instFilename = inst->getFilename();
130 if (!instFilename.empty()) {
131 out << "Instrument from: " << instFilename;
132 out << "\n";
133 }
134 } else {
135 out << "None";
136 }
137 out << "\n";
138
139 // parameter files loaded
140 auto paramFileVector = this->constInstrumentParameters().getParameterFilenames();
141 for (auto &itFilename : paramFileVector) {
142 out << "Parameters from: " << itFilename;
143 out << "\n";
144 }
145
146 std::string runStart = getAvailableWorkspaceStartDate();
147 std::string runEnd = getAvailableWorkspaceEndDate();
148 std::string msgNA = "not available";
149 if (runStart.empty())
150 runStart = msgNA;
151 if (runEnd.empty())
152 runEnd = msgNA;
153 out << "Run start: " << runStart << "\n";
154 out << "Run end: " << runEnd << "\n"; // note extra space for pseudo/approx-alignment
155
156 if (this->sample().hasOrientedLattice()) {
158 out << "Sample: a " << std::fixed << std::setprecision(1) << latt.a() << ", b " << latt.b() << ", c " << latt.c();
159 out << "; alpha " << std::fixed << std::setprecision(0) << latt.alpha() << ", beta " << latt.beta() << ", gamma "
160 << latt.gamma();
161 out << "\n";
162 }
163 return out.str();
164}
165
166// Helpers for setInstrument and getInstrument
167namespace {
168void checkDetectorInfoSize(const Instrument &instr, const Geometry::DetectorInfo &detInfo) {
169 const auto numDets = instr.getNumberDetectors();
170 if (numDets != detInfo.size())
171 throw std::runtime_error("ExperimentInfo: size mismatch between "
172 "DetectorInfo and number of detectors in "
173 "instrument");
174}
175} // namespace
176
181 m_spectrumInfoWrapper = nullptr;
182
183 // Detector IDs that were previously dropped because they were not part of the
184 // instrument may now suddenly be valid, so we have to reinitialize the
185 // detector grouping. Also the index corresponding to specific IDs may have
186 // changed.
187 if (sptr_instrument != (instr->isParametrized() ? instr->baseInstrument() : instr))
189 if (instr->isParametrized()) {
190 sptr_instrument = instr->baseInstrument();
191 // We take a *copy* of the ParameterMap since we are modifying it by setting
192 // a pointer to our DetectorInfo, and in case it contains legacy parameters
193 // such as positions or rotations.
194 m_parmap = std::make_shared<ParameterMap>(*instr->getParameterMap());
195 } else {
196 sptr_instrument = instr;
197 m_parmap = std::make_shared<ParameterMap>();
198 }
199 m_parmap->setInstrument(sptr_instrument.get());
200}
201
209 checkDetectorInfoSize(*sptr_instrument, detectorInfo());
211}
212
218 return *m_parmap;
219}
220
226 return *m_parmap;
227}
228
234 return *m_parmap;
235}
236
237namespace {
239
243struct RTP {
244 RTP() : radius(0.0), haveRadius(false), theta(0.0), phi(0.0) {}
245 double radius;
246 bool haveRadius;
247 double theta;
248 double phi;
249};
250
251struct ParameterValue {
252 ParameterValue(const Geometry::XMLInstrumentParameter &paramInfo, const API::Run &run)
253 : info(paramInfo), runData(run) {}
254
255 operator double() {
256 if (info.m_logfileID.empty())
257 return boost::lexical_cast<double>(info.m_value);
258 else
259 return info.createParamValue(runData.getTimeSeriesProperty<double>(info.m_logfileID));
260 }
261 operator int() { return boost::lexical_cast<int>(info.m_value); }
262 operator bool() {
263 if (boost::iequals(info.m_value, "true"))
264 return true;
265 else if (boost::iequals(info.m_value, "yes"))
266 return true;
267 else
268 return false;
269 }
271 const Run &runData;
272};
274} // namespace
275
276namespace {
277bool isPositionParameter(const std::string &name) { return ParameterMap::pos() == name; }
278
279bool isRotationParameter(const std::string &name) { return ParameterMap::rot() == name; }
280
281bool isScaleParameter(const std::string &name) { return (name == "scalex" || name == "scaley"); }
282
283bool isRedundantPosOrRot(const std::string &name) {
284 // Check size first as a small optimization.
285 return (name.size() == 4) &&
286 (name == "posx" || name == "posy" || name == "posz" || name == "rotx" || name == "roty" || name == "rotz");
287}
288
289template <class T> T getParam(const std::string &paramType, const std::string &paramValue) {
290 const std::string name = "dummy";
291 auto param = ParameterFactory::create(paramType, name);
292 param->fromString(paramValue);
293 return param->value<T>();
294}
295
296void updatePosition(ComponentInfo &componentInfo, const IComponent *component, const V3D &newRelPos) {
297 const auto compIndex = componentInfo.indexOf(component->getComponentID());
298 V3D position = newRelPos;
299 if (componentInfo.hasParent(compIndex)) {
300 const auto parentIndex = componentInfo.parent(compIndex);
301 componentInfo.rotation(parentIndex).rotate(position);
302 position += componentInfo.position(parentIndex);
303 }
304 componentInfo.setPosition(compIndex, position);
305}
306
307void updateRotation(ComponentInfo &componentInfo, const IComponent *component, const Quat &newRelRot) {
308 const auto compIndex = componentInfo.indexOf(component->getComponentID());
309
310 auto rotation = newRelRot;
311 if (componentInfo.hasParent(compIndex)) {
312 const auto parentIndex = componentInfo.parent(compIndex);
313 rotation = componentInfo.rotation(parentIndex) * newRelRot;
314 }
315 componentInfo.setRotation(compIndex, rotation);
316}
317
318void adjustPositionsFromScaleFactor(ComponentInfo &componentInfo, const IComponent *component,
319 const std::string &paramName, double factor) {
320 double ScaleX = 1.0;
321 double ScaleY = 1.0;
322 if (paramName == "scalex")
323 ScaleX = factor;
324 else
325 ScaleY = factor;
326 applyRectangularDetectorScaleToComponentInfo(componentInfo, component->getComponentID(), ScaleX, ScaleY);
327}
328} // namespace
329
338
339 // Reference to the run
340 const auto &runData = run();
341
342 // Get pointer to parameter map that we may add parameters to and information
343 // about
344 // the parameters that my be specified in the instrument definition file (IDF)
346 Geometry::ParameterMap paramMapForPosAndRot;
347
348 // Get instrument and sample
350 const auto parInstrument = getInstrument();
351 const auto instrument = parInstrument->baseInstrument();
352 const auto &paramInfoFromIDF = instrument->getLogfileCache();
353
354 std::map<const IComponent *, RTP> rtpParams;
355
356 // In this loop position and rotation parameters are inserted into the
357 // temporary map paramMapForPosAndRot. In the subsequent loop, after all
358 // parameters have been parsed, we update positions and rotations in
359 // DetectorInfo and the temporary map goes out of scope. The main reason for
360 // this is that ParameterMap will then take care of assembling parameters for
361 // individual position or rotation components into a vector or quaternion. In
362 // particular, we cannot directly change DetectorInfo since the order of
363 // rotation components is not guaranteed.
364 for (const auto &item : paramInfoFromIDF) {
365 const auto &nameComp = item.first;
366 const auto &paramInfo = item.second;
367 const std::string &paramN = nameComp.first;
368
369 try {
370 // Special case where user has specified r-position,t-position, and/or
371 // p-position.
372 // We need to know all three first to calculate a set of X,Y,Z
373 if (paramN.compare(1, 9, "-position") == 0) {
374 auto &rtpValues = rtpParams[paramInfo->m_component]; // If not found,
375 // constructs
376 // default
377 double value = ParameterValue(*paramInfo, runData);
378 if (paramN.compare(0, 1, "r") == 0) {
379 rtpValues.radius = value;
380 rtpValues.haveRadius = true;
381 } else if (paramN.compare(0, 1, "t") == 0)
382 rtpValues.theta = value;
383 else if (paramN.compare(0, 1, "p") == 0)
384 rtpValues.phi = value;
385 if (rtpValues.haveRadius) {
386 V3D pos;
387 pos.spherical(rtpValues.radius, rtpValues.theta, rtpValues.phi);
388 paramMapForPosAndRot.addV3D(paramInfo->m_component, ParameterMap::pos(), pos);
389 }
390 } else {
391 populateWithParameter(paramMap, paramMapForPosAndRot, paramN, *paramInfo, runData);
392 }
393 } catch (std::exception &exc) {
394 g_log.information() << "Unable to add component parameter '" << nameComp.first << "'. Error: " << exc.what();
395 continue;
396 }
397 }
398 for (const auto &item : paramMapForPosAndRot) {
399 if (isPositionParameter(item.second->name())) {
400 const auto newRelPos = item.second->value<V3D>();
401 updatePosition(componentInfo, item.first, newRelPos);
402 } else if (isRotationParameter(item.second->name())) {
403 const auto newRelRot = item.second->value<Quat>();
404 updateRotation(componentInfo, item.first, newRelRot);
405 }
406 // Parameters for individual components (x,y,z) are ignored. ParameterMap
407 // did compute the correct compound positions and rotations internally.
408 }
409 // Special case RectangularDetector: Parameters scalex and scaley affect pixel
410 // positions.
411 for (const auto &item : paramMap) {
412 if (isScaleParameter(item.second->name()))
413 adjustPositionsFromScaleFactor(componentInfo, item.first, item.second->name(), item.second->value<double>());
414 }
415 // paramMapForPosAndRot goes out of scope, dropping all position and rotation
416 // parameters of detectors (parameters for non-detector components have been
417 // inserted into paramMap via DetectorInfo::setPosition(IComponent *)).
418}
419
427 if (m_spectrumInfo)
430 m_spectrumInfo = std::make_unique<Beamline::SpectrumInfo>(count);
431 m_spectrumInfoWrapper = nullptr;
432}
433
439
444void ExperimentInfo::setDetectorGrouping(const size_t index, const std::set<detid_t> &detIDs) const {
445 SpectrumDefinition specDef;
446 for (const auto detID : detIDs) {
447 try {
448 const size_t detIndex = detectorInfo().indexOf(detID);
449 specDef.add(detIndex);
450 } catch (std::out_of_range &) {
451 // Silently strip bad detector IDs
452 }
453 }
454 m_spectrumInfo->setSpectrumDefinition(index, std::move(specDef));
456}
457
465void ExperimentInfo::updateCachedDetectorGrouping(const size_t /*unused*/) const {
466 throw std::runtime_error("ExperimentInfo::updateCachedDetectorGrouping: "
467 "Cannot update -- grouping information not "
468 "available");
469}
470
476 return *m_sample;
477}
478
486 return m_sample.access();
487}
488
492const Run &ExperimentInfo::run() const {
494 return *m_run;
495}
496
504 return m_run.access();
505}
506
509
512
525Kernel::Property *ExperimentInfo::getLog(const std::string &log) const {
527 try {
528 return run().getProperty(log);
530 // No log with that name
531 }
532 // If the instrument has a parameter with that name then take the value as a
533 // log name
534 const std::string logName = constInstrumentParameters().getString(sptr_instrument.get(), log);
535 if (logName.empty()) {
536 throw std::invalid_argument("ExperimentInfo::getLog - No instrument parameter named \"" + log +
537 "\". Cannot access full log name");
538 }
539 return run().getProperty(logName);
540}
541
550double ExperimentInfo::getLogAsSingleValue(const std::string &log) const {
552 try {
553 return run().getPropertyAsSingleValue(log);
555 // No log with that name
556 }
557 // If the instrument has a parameter with that name then take the value as a
558 // log name
559 const std::string logName = constInstrumentParameters().getString(sptr_instrument.get(), log);
560 if (logName.empty()) {
561 throw std::invalid_argument("ExperimentInfo::getLog - No instrument parameter named \"" + log +
562 "\". Cannot access full log name");
563 }
564 return run().getPropertyAsSingleValue(logName);
565}
566
573 const Run &thisRun = run();
574 if (!thisRun.hasProperty("run_number")) {
575 // No run_number property, default to 0
576 return 0;
577 } else {
578 Property *prop = m_run->getProperty("run_number");
579 if (prop) {
580 // Use the string representation. That way both a string and a number
581 // property will work.
582 int val;
583 if (Strings::convert(prop->value(), val))
584 return val;
585 else
586 return 0;
587 }
588 }
589 return 0;
590}
591
602 static const char *emodeTag = "deltaE-mode";
603 std::string emodeStr;
604 if (run().hasProperty(emodeTag)) {
605 emodeStr = run().getPropertyValueAsType<std::string>(emodeTag);
606 } else if (sptr_instrument && constInstrumentParameters().contains(sptr_instrument.get(), emodeTag)) {
608 emodeStr = param->asString();
609 } else {
611 }
612 return Kernel::DeltaEMode::fromString(emodeStr);
613}
614
624double ExperimentInfo::getEFixed(const detid_t detID) const {
626 IDetector_const_sptr det = getInstrument()->getDetector(detID);
627 return getEFixed(det);
628}
629
636double ExperimentInfo::getEFixed(const std::shared_ptr<const Geometry::IDetector> &detector) const {
639 return getEFixedGivenEMode(detector, emode);
640}
641
642double ExperimentInfo::getEFixedForIndirect(const std::shared_ptr<const Geometry::IDetector> &detector,
643 const std::vector<std::string> &parameterNames) const {
644 double efixed = 0.;
645 for (auto &parameterName : parameterNames) {
646 Parameter_sptr par = constInstrumentParameters().getRecursive(detector.get(), parameterName);
647 if (par) {
648 efixed = par->value<double>();
649 } else {
650 std::vector<double> efixedVec = detector->getNumberParameter(parameterName);
651 if (efixedVec.empty()) {
652 int detid = detector->getID();
653 IDetector_const_sptr detectorSingle = getInstrument()->getDetector(detid);
654 efixedVec = detectorSingle->getNumberParameter(parameterName);
655 }
656 if (!efixedVec.empty()) {
657 efixed = efixedVec.at(0);
658 }
659 }
660 }
661 if (efixed == 0.) {
662 std::ostringstream os;
663 os << "ExperimentInfo::getEFixed - Indirect mode efixed requested but "
664 "detector has no Efixed parameter attached. ID="
665 << detector->getID();
666 throw std::runtime_error(os.str());
667 }
668 return efixed;
669}
670
678double ExperimentInfo::getEFixedGivenEMode(const std::shared_ptr<const Geometry::IDetector> &detector,
679 const Kernel::DeltaEMode::Type emode) const {
680 if (emode == Kernel::DeltaEMode::Direct) {
681 double efixed = 0.;
682 for (auto &parameterName : {"Ei", "EnergyRequested", "EnergyEstimate"}) {
683 if (run().hasProperty(parameterName)) {
684 efixed = run().getPropertyValueAsType<double>(parameterName);
685 break;
686 }
687 }
688 if (efixed == 0.) {
689 throw std::runtime_error("Experiment logs do not contain an Ei "
690 "value. Have you run GetEi?");
691 }
692 return efixed;
693 } else if (emode == Kernel::DeltaEMode::Indirect) {
694 if (!detector)
695 throw std::runtime_error("ExperimentInfo::getEFixed - Indirect mode "
696 "efixed requested without a valid detector.");
697 return getEFixedForIndirect(detector, {"Efixed", "EFixed-val"});
698 } else {
699 throw std::runtime_error("ExperimentInfo::getEFixed - EFixed requested for "
700 "elastic mode, don't know what to do!");
701 }
702}
703
704void ExperimentInfo::setEFixed(const detid_t detID, const double value) {
706 IDetector_const_sptr det = getInstrument()->getDetector(detID);
708 pmap.addDouble(det.get(), "Efixed", value);
709}
710
721 std::string date;
722 try {
723 date = run().startTime().toISO8601String();
724 } catch (std::runtime_error &) {
725 g_log.information("run_start/start_time not stored in workspace. Default "
726 "to current date.");
727 date = Types::Core::DateAndTime::getCurrentTime().toISO8601String();
728 }
729 return date;
730}
731
740 std::string date;
741 try {
742 date = run().startTime().toFormattedString();
743 } catch (std::runtime_error &) {
744 g_log.information("Note: run_start/start_time not stored in workspace.");
745 }
746 return date;
747}
748
757 std::string date;
758 try {
759 date = run().endTime().toFormattedString();
760 } catch (std::runtime_error &) {
761 g_log.information("Note: run_start/start_time not stored in workspace.");
762 }
763 return date;
764}
765
766//-----------------------------------------------------------------------------------------------------------------------
767
775 return m_parmap->detectorInfo();
776}
777
781 return m_parmap->mutableDetectorInfo();
782}
783
792 std::lock_guard<std::mutex> lock{m_spectrumInfoMutex};
793 if (!m_spectrumInfo) // this should happen only if not MatrixWorkspace
796 static_cast<void>(detectorInfo());
797 m_spectrumInfoWrapper = std::make_unique<SpectrumInfo>(*m_spectrumInfo, *this, m_parmap->mutableDetectorInfo());
798 }
799 }
800 // Rebuild any spectrum definitions that are out of date. Accessing
801 // `API::SpectrumInfo` will rebuild invalid spectrum definitions as it
802 // encounters them (if detector IDs in an `ISpectrum` are changed), however we
803 // need to deal with one special case here:
804 // If two algorithms (or two threads in the same algorithm) access the same
805 // workspace for reading at the same time, calls to
806 // `updateSpectrumDefinitionIfNecessary` done by `API::SpectrumInfo` break
807 // thread-safety. `Algorithm` sets a read-lock, but this lazy update method is
808 // `const` and will modify internals of the workspace nevertheless. We thus
809 // need explicit locking here. Note that we do not need extra locking in the
810 // case of `ExperimentInfo::mutableSpectrumInfo` or other calls to
811 // `updateSpectrumDefinitionIfNecessary` done by `API::SpectrumInfo`: If the
812 // workspace is only read-locked, this update will ensure that no updates will
813 // be triggered by SpectrumInfo, since changing detector IDs in an `ISpectrum`
814 // is not possible for a read-only workspace. If the workspace is write-locked
815 // detector IDs in ISpectrum may change, but the write-lock by `Algorithm`
816 // guarantees that there is no concurrent reader and thus updating is safe.
818 [](char i) { return i == 1; })) {
819 std::lock_guard<std::mutex> lock{m_spectrumInfoMutex};
821 [](char i) { return i == 1; })) {
822 auto size = static_cast<int64_t>(m_spectrumInfoWrapper->size());
823#pragma omp parallel for
824 for (int64_t i = 0; i < size; ++i) {
826 }
827 }
828 }
829 return *m_spectrumInfoWrapper;
830}
831
835 return const_cast<SpectrumInfo &>(static_cast<const ExperimentInfo &>(*this).spectrumInfo());
836}
837
838const Geometry::ComponentInfo &ExperimentInfo::componentInfo() const { return m_parmap->componentInfo(); }
839
840ComponentInfo &ExperimentInfo::mutableComponentInfo() { return m_parmap->mutableComponentInfo(); }
841
843void ExperimentInfo::setSpectrumDefinitions(Kernel::cow_ptr<std::vector<SpectrumDefinition>> spectrumDefinitions) {
844 if (spectrumDefinitions) {
845 m_spectrumInfo = std::make_unique<Beamline::SpectrumInfo>(std::move(spectrumDefinitions));
848 } else {
849 // Keep the old m_spectrumInfo which should have the correct size, but
850 // invalidate all definitions.
852 }
853 m_spectrumInfoWrapper = nullptr;
854}
855
862 // This uses a vector of char, such that flags for different indices can be
863 // set from different threads (std::vector<bool> is not thread-safe).
865}
866
870}
871
878 if (m_spectrumInfo && (m_spectrumInfo->size() != 0))
879 return;
880 const auto &detIDs = sptr_instrument->getDetectorIDs();
881 setNumberOfDetectorGroups(detIDs.size());
882 size_t specIndex = 0;
883 for (const auto detID : detIDs) {
884 m_det2group[detID] = specIndex;
885 const size_t detIndex = detectorInfo().indexOf(detID);
886 SpectrumDefinition specDef;
887 specDef.add(detIndex);
888 m_spectrumInfo->setSpectrumDefinition(specIndex, std::move(specDef));
889 m_spectrumDefinitionNeedsUpdate.at(specIndex) = 0;
890 specIndex++;
891 }
892}
893
898}
899
904void ExperimentInfo::saveExperimentInfoNexus(::NeXus::File *file, bool saveLegacyInstrument) const {
906 if (saveLegacyInstrument) {
907 instrument->saveNexus(file, "instrument");
908 }
909 sample().saveNexus(file, "sample");
910 run().saveNexus(file, "logs");
911}
912
919void ExperimentInfo::saveExperimentInfoNexus(::NeXus::File *file, bool saveInstrument, bool saveSample,
920 bool saveLogs) const {
922
923 if (saveInstrument)
924 instrument->saveNexus(file, "instrument");
925 if (saveSample)
926 sample().saveNexus(file, "sample");
927 if (saveLogs)
928 run().saveNexus(file, "logs");
929}
930
935 const std::string &prefix) {
936 // First, the sample and then the logs
937 int sampleVersion = mutableSample().loadNexus(file, "sample");
938 if (sampleVersion == 0) {
939 // Old-style (before Sep-9-2011) NXS processed
940 // sample field contains both the logs and the sample details
941 file->openGroup("sample", "NXsample");
942 this->mutableRun().loadNexus(file, "", fileInfo, prefix);
943 file->closeGroup();
944 } else {
945 // Newer style: separate "logs" field for the Run object
946 this->mutableRun().loadNexus(file, "logs", fileInfo, prefix);
947 }
948}
949
954 // First, the sample and then the logs
955 int sampleVersion = mutableSample().loadNexus(file, "sample");
956 if (sampleVersion == 0) {
957 // Old-style (before Sep-9-2011) NXS processed
958 // sample field contains both the logs and the sample details
959 file->openGroup("sample", "NXsample");
960 this->mutableRun().loadNexus(file, "");
961 file->closeGroup();
962 } else {
963 // Newer style: separate "logs" field for the Run object
964 this->mutableRun().loadNexus(file, "logs");
965 }
966}
967
968void ExperimentInfo::loadExperimentInfoNexus(const std::string &nxFilename, ::NeXus::File *file,
969 std::string &parameterStr,
971 const std::string &prefix) {
972 // TODO
973 // load sample and log info
974 loadSampleAndLogInfoNexus(file, fileInfo, prefix);
975
976 loadInstrumentInfoNexus(nxFilename, file, parameterStr);
977}
978
989void ExperimentInfo::loadExperimentInfoNexus(const std::string &nxFilename, ::NeXus::File *file,
990 std::string &parameterStr) {
991 // load sample and log info
993
994 loadInstrumentInfoNexus(nxFilename, file, parameterStr);
995}
996
1007void ExperimentInfo::loadInstrumentInfoNexus(const std::string &nxFilename, ::NeXus::File *file,
1008 std::string &parameterStr) {
1009
1010 // Open instrument group
1011 file->openGroup("instrument", "NXinstrument");
1012
1013 // Try to get the instrument embedded in the Nexus file
1014 std::string instrumentName;
1015 std::string instrumentXml;
1016 loadEmbeddedInstrumentInfoNexus(file, instrumentName, instrumentXml);
1017
1018 // load parameters if found
1019 loadInstrumentParametersNexus(file, parameterStr);
1020
1021 // Close the instrument group
1022 file->closeGroup();
1023
1024 // Set the instrument given the name and and XML obtained
1025 setInstumentFromXML(nxFilename, instrumentName, instrumentXml);
1026}
1027
1037void ExperimentInfo::loadInstrumentInfoNexus(const std::string &nxFilename, ::NeXus::File *file) {
1038
1039 // Open instrument group
1040 file->openGroup("instrument", "NXinstrument");
1041
1042 // Try to get the instrument embedded in the Nexus file
1043 std::string instrumentName;
1044 std::string instrumentXml;
1045 loadEmbeddedInstrumentInfoNexus(file, instrumentName, instrumentXml);
1046
1047 // Close the instrument group
1048 file->closeGroup();
1049
1050 // Set the instrument given the name and and XML obtained
1051 setInstumentFromXML(nxFilename, instrumentName, instrumentXml);
1052}
1053
1060void ExperimentInfo::loadEmbeddedInstrumentInfoNexus(::NeXus::File *file, std::string &instrumentName,
1061 std::string &instrumentXml) {
1062
1063 file->readData("name", instrumentName);
1064
1065 try {
1066 file->openGroup("instrument_xml", "NXnote");
1067 file->readData("data", instrumentXml);
1068 file->closeGroup();
1069 } catch (NeXus::Exception &ex) {
1070 g_log.debug(std::string("Unable to load instrument_xml: ") + ex.what());
1071 }
1072}
1073
1083void ExperimentInfo::setInstumentFromXML(const std::string &nxFilename, std::string &instrumentName,
1084 std::string &instrumentXml) {
1085
1086 instrumentXml = Strings::strip(instrumentXml);
1087 instrumentName = Strings::strip(instrumentName);
1088 std::string instrumentFilename;
1089 if (!instrumentXml.empty()) {
1090 // instrument xml is being loaded from the nxs file, set the
1091 // instrumentFilename
1092 // to identify the Nexus file as the source of the data
1093 instrumentFilename = nxFilename;
1094 g_log.debug() << "Using instrument IDF XML text contained in nexus file.\n";
1095 } else {
1096 // XML was not included or was empty
1097 // Use the instrument name to find the file
1098 instrumentFilename = InstrumentFileFinder::getInstrumentFilename(instrumentName, getWorkspaceStartDate());
1099 // And now load the contents
1100 instrumentXml = loadInstrumentXML(instrumentFilename);
1101 }
1102
1103 // ---------- Now parse that XML to make the instrument -------------------
1104 if (!instrumentXml.empty() && !instrumentName.empty()) {
1105 InstrumentDefinitionParser parser(instrumentFilename, instrumentName, instrumentXml);
1106
1107 std::string instrumentNameMangled = parser.getMangledName();
1108 Instrument_sptr instr;
1109 // Check whether the instrument is already in the InstrumentDataService
1110 if (InstrumentDataService::Instance().doesExist(instrumentNameMangled)) {
1111 // If it does, just use the one from the one stored there
1112 instr = InstrumentDataService::Instance().retrieve(instrumentNameMangled);
1113 } else {
1114 // Really create the instrument
1115 instr = parser.parseXML(nullptr);
1116 // Parse the instrument tree (internally create ComponentInfo and
1117 // DetectorInfo). This is an optimization that avoids duplicate parsing
1118 // of the instrument tree when loading multiple workspaces with the same
1119 // instrument. As a consequence less time is spent and less memory is
1120 // used. Note that this is only possible since the tree in `instrument`
1121 // will not be modified once we add it to the IDS.
1122 instr->parseTreeAndCacheBeamline();
1123
1124 // Add to data service for later retrieval
1125 InstrumentDataService::Instance().add(instrumentNameMangled, instr);
1126 }
1127 // Now set the instrument
1128 this->setInstrument(instr);
1129 }
1130}
1131
1138std::string ExperimentInfo::loadInstrumentXML(const std::string &filename) {
1139 try {
1140 return Strings::loadFile(filename);
1141 } catch (std::exception &e) {
1142 g_log.error() << "Error loading instrument IDF file: " << filename << ".\n";
1143 g_log.debug() << e.what() << '\n';
1144 throw;
1145 }
1146}
1147
1154void ExperimentInfo::loadInstrumentParametersNexus(::NeXus::File *file, std::string &parameterStr) {
1155 try {
1156 file->openGroup("instrument_parameter_map", "NXnote");
1157 file->readData("data", parameterStr);
1158 file->closeGroup();
1159 } catch (NeXus::Exception &ex) {
1160 g_log.debug(std::string("Unable to load instrument_parameter_map: ") + ex.what());
1161 g_log.information("Parameter map entry missing from NeXus file. Continuing without it.");
1162 }
1163}
1164
1171void ExperimentInfo::readParameterMap(const std::string &parameterStr) {
1173 auto &componentInfo = mutableComponentInfo();
1175 const auto parInstrument = getInstrument();
1176 const auto instr = parInstrument->baseInstrument();
1177
1180 Mantid::Kernel::StringTokenizer splitter(parameterStr, "|", options);
1181
1182 auto iend = splitter.end();
1183
1185 const std::string visibilityKey = "visible:"; // if visibility is defined, the value will follow this key
1186 // std::string prev_name;
1187 for (auto itr = splitter.begin(); itr != iend; ++itr) {
1188 tokens = Mantid::Kernel::StringTokenizer(*itr, ";");
1189 if (tokens.count() < 4)
1190 continue;
1191 std::string comp_name = tokens[0];
1192 // if( comp_name == prev_name ) continue; this blocks reading in different
1193 // parameters of the same component. RNT
1194 // prev_name = comp_name;
1195 const Geometry::IComponent *comp = nullptr;
1196 if (comp_name.find("detID:") != std::string::npos) {
1197 int detID = std::stoi(comp_name.substr(6));
1198 comp = instr->getDetector(detID).get();
1199 if (!comp) {
1200 g_log.warning() << "Cannot find detector " << detID << '\n';
1201 continue;
1202 }
1203 } else {
1204 comp = instr->getComponentByName(comp_name).get();
1205 if (!comp) {
1206 g_log.warning() << "Cannot find component " << comp_name << '\n';
1207 continue;
1208 }
1209 }
1210
1211 // create parameter's value as a sum of all tokens with index 3 or larger
1212 // this allow a parameter's value to contain ";"
1213 std::string paramValue = tokens[3];
1214 auto size = static_cast<int>(tokens.count());
1215 for (int i = 4; i < size; i++)
1216 paramValue += ";" + tokens[i];
1217 const auto &paramType = tokens[1];
1218 const auto &paramName = tokens[2];
1219 auto &paramVisibility = tokens[size - 1]; // parameter visibility, if defined, is the last token
1220 if (paramVisibility.find(visibilityKey) > paramVisibility.size())
1221 paramVisibility = "true"; // visibility not defined: default to visible
1222 else { // defined, the paramValue has one too many entries, -1 to remove also the semicolon
1223 paramVisibility =
1224 paramVisibility.substr(paramVisibility.find(visibilityKey) + visibilityKey.size(), paramVisibility.size());
1225 paramValue = paramValue.substr(0, paramValue.find(visibilityKey) - 1);
1226 }
1227 const auto paramDescr = std::string("");
1228 if (paramName == "masked") {
1229 auto value = getParam<bool>(paramType, paramValue);
1230 if (value) {
1231 // Do not add masking to ParameterMap, it is stored in DetectorInfo
1232 const auto componentIndex = componentInfo.indexOf(comp->getComponentID());
1233 if (!componentInfo.isDetector(componentIndex)) {
1234 throw std::runtime_error("Found masking for a non-detector "
1235 "component. This is not possible");
1236 } else
1237 detectorInfo.setMasked(componentIndex, value); // all detector indexes
1238 // have same component
1239 // index (guarantee)
1240 }
1241 } else if (isPositionParameter(paramName)) {
1242 // We are parsing a string obtained from a ParameterMap. The map may
1243 // contain posx, posy, and posz (in addition to pos). However, when these
1244 // component wise positions are set, 'pos' is updated accordingly. We are
1245 // thus ignoring position components below.
1246 const auto newRelPos = getParam<V3D>(paramType, paramValue);
1247 updatePosition(componentInfo, comp, newRelPos);
1248 } else if (isRotationParameter(paramName)) {
1249 // We are parsing a string obtained from a ParameterMap. The map may
1250 // contain rotx, roty, and rotz (in addition to rot). However, when these
1251 // component wise rotations are set, 'rot' is updated accordingly. We are
1252 // thus ignoring rotation components below.
1253 const auto newRelRot = getParam<Quat>(paramType, paramValue);
1254 updateRotation(componentInfo, comp, newRelRot);
1255 } else if (!isRedundantPosOrRot(paramName)) {
1256 // Special case RectangularDetector: Parameters scalex and scaley affect
1257 // pixel positions, but we must also add the parameter below.
1258 if (isScaleParameter(paramName))
1259 adjustPositionsFromScaleFactor(componentInfo, comp, paramName, getParam<double>(paramType, paramValue));
1260 pmap.add(paramType, comp, paramName, paramValue, &paramDescr, paramVisibility);
1261 }
1262 }
1263}
1264
1276 Geometry::ParameterMap &paramMapForPosAndRot, const std::string &name,
1277 const Geometry::XMLInstrumentParameter &paramInfo, const Run &runData) {
1278 const std::string &category = paramInfo.m_type;
1279 ParameterValue paramValue(paramInfo,
1280 runData); // Defines implicit conversion operator
1281
1282 const std::string *pDescription = nullptr;
1283 if (!paramInfo.m_description.empty())
1284 pDescription = &paramInfo.m_description;
1285 std::string pVisible = "true";
1286 if (!paramInfo.m_visible.empty())
1287 pVisible = paramInfo.m_visible;
1288
1289 // Some names are special. Values should be convertible to double
1290 if (name == "masked") {
1291 bool value(paramValue);
1292 if (value) {
1293 // Do not add masking to ParameterMap, it is stored in DetectorInfo
1294
1295 const auto componentIndex = componentInfo().indexOf(paramInfo.m_component->getComponentID());
1296 if (!componentInfo().isDetector(componentIndex))
1297 throw std::runtime_error("Found masking for a non-detector component. This is not possible");
1298 mutableDetectorInfo().setMasked(componentIndex,
1299 paramValue); // all detector indexes have
1300 // same component index
1301 // (guarantee)
1302 }
1303 } else if (name == "x" || name == "y" || name == "z") {
1304 paramMapForPosAndRot.addPositionCoordinate(paramInfo.m_component, name, paramValue);
1305 } else if (name == "rot" || name == "rotx" || name == "roty" || name == "rotz") {
1306 // Effectively this is dropping any parameters named 'rot'.
1307 paramMapForPosAndRot.addRotationParam(paramInfo.m_component, name, paramValue, pDescription);
1308 } else if (category == "fitting") {
1309 std::ostringstream str;
1310 str << paramInfo.m_value << " , " << paramInfo.m_fittingFunction << " , " << name << " , "
1311 << paramInfo.m_constraint[0] << " , " << paramInfo.m_constraint[1] << " , " << paramInfo.m_penaltyFactor
1312 << " , " << paramInfo.m_tie << " , " << paramInfo.m_formula << " , " << paramInfo.m_formulaUnit << " , "
1313 << paramInfo.m_resultUnit << " , " << (*(paramInfo.m_interpolation));
1314 paramMap.add("fitting", paramInfo.m_component, name, str.str(), pDescription, pVisible);
1315 } else if (category == "string") {
1316 paramMap.addString(paramInfo.m_component, name, paramInfo.m_value, pDescription, pVisible);
1317 } else if (category == "bool") {
1318 paramMap.addBool(paramInfo.m_component, name, paramValue, pDescription, pVisible);
1319 } else if (category == "int") {
1320 paramMap.addInt(paramInfo.m_component, name, paramValue, pDescription, pVisible);
1321 } else { // assume double
1322 paramMap.addDouble(paramInfo.m_component, name, paramValue, pDescription, pVisible);
1323 }
1324}
1325
1327 // The default implementation does nothing. Used by subclasses
1328 // (FileBackedExperimentInfo) to load content from files upon access.
1329}
1330
1331} // namespace Mantid::API
1332
1333namespace Mantid::Kernel {
1334
1335template <>
1337IPropertyManager::getValue<Mantid::API::ExperimentInfo_sptr>(const std::string &name) const {
1338 auto *prop = dynamic_cast<PropertyWithValue<Mantid::API::ExperimentInfo_sptr> *>(getPointerToProperty(name));
1339 if (prop) {
1340 return *prop;
1341 } else {
1342 std::string message =
1343 "Attempt to assign property " + name + " to incorrect type. Expected shared_ptr<ExperimentInfo>.";
1344 throw std::runtime_error(message);
1345 }
1346}
1347
1348template <>
1350IPropertyManager::getValue<Mantid::API::ExperimentInfo_const_sptr>(const std::string &name) const {
1351 auto *prop = dynamic_cast<PropertyWithValue<Mantid::API::ExperimentInfo_sptr> *>(getPointerToProperty(name));
1352 if (prop) {
1353 return prop->operator()();
1354 } else {
1355 std::string message =
1356 "Attempt to assign property " + name + " to incorrect type. Expected const shared_ptr<ExperimentInfo>.";
1357 throw std::runtime_error(message);
1358 }
1359}
1360
1361} // namespace Mantid::Kernel
double value
The value of the point.
Definition: FitMW.cpp:51
double position
Definition: GetAllEi.cpp:154
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
int count
counter
Definition: Matrix.cpp:37
Mantid::Kernel::Quat(ComponentInfo::* rotation)(const size_t) const
double radius
Definition: Rasterize.cpp:31
This class is shared by a few Workspace types and holds information related to a particular experimen...
Geometry::DetectorInfo & mutableDetectorInfo()
Return a non-const reference to the DetectorInfo object.
Run & mutableRun()
Writable version of the run object.
Kernel::cow_ptr< Sample > m_sample
The information on the sample environment.
const SpectrumInfo & spectrumInfo() const
Return a reference to the SpectrumInfo object.
std::shared_ptr< Geometry::ParameterMap > m_parmap
Parameters modifying the base instrument.
ExperimentInfo()
Default constructor.
void setInstumentFromXML(const std::string &nxFilename, std::string &instrumentName, std::string &instrumentXml)
Set the instrument given the name and XML leading from IDF file if XML string is empty.
Geometry::ComponentInfo & mutableComponentInfo()
const Geometry::DetectorInfo & detectorInfo() const
Return a const reference to the DetectorInfo object.
virtual ExperimentInfo * cloneExperimentInfo() const
Clone us.
std::unordered_map< detid_t, size_t > m_det2group
Detector grouping information.
double getEFixed(const detid_t detID) const
Easy access to the efixed value for this run & detector ID.
void readParameterMap(const std::string &parameterStr)
Populate the parameter map given a string.
virtual void populateIfNotLoaded() const
Called as the first operation of most public methods.
void invalidateSpectrumDefinition(const size_t index)
Notifies the ExperimentInfo that a spectrum definition has changed.
size_t numberOfDetectorGroups() const
Returns the number of detector groups.
void updateSpectrumDefinitionIfNecessary(const size_t index) const
std::string getAvailableWorkspaceStartDate() const
Return workspace start date as a formatted string (strftime, as returned by Types::Core::DateAndTime)...
std::string loadInstrumentXML(const std::string &filename)
Loads the contents of a file and returns the string The file is assumed to be an IDF,...
virtual ~ExperimentInfo()
Virtual destructor.
virtual void updateCachedDetectorGrouping(const size_t index) const
Update detector grouping for spectrum with given index.
void loadSampleAndLogInfoNexus(::NeXus::File *file, const Mantid::Kernel::NexusHDF5Descriptor &fileInfo, const std::string &prefix)
Load the sample and log info from an open NeXus file.
void loadInstrumentInfoNexus(const std::string &nxFilename, ::NeXus::File *file, std::string &parameterStr)
Load the instrument from an open NeXus file.
void cacheDefaultDetectorGrouping() const
Sets up a default detector grouping.
void copyExperimentInfoFrom(const ExperimentInfo *other)
Copy everything from the given experiment object.
const Run & run() const
Run details object access.
const Geometry::ParameterMap & constInstrumentParameters() const
Const version.
Geometry::Instrument_const_sptr getInstrument() const
Returns the parameterized instrument.
Kernel::DeltaEMode::Type getEMode() const
Returns the emode for this run.
void loadExperimentInfoNexus(const std::string &nxFilename, ::NeXus::File *file, std::string &parameterStr, const Mantid::Kernel::NexusHDF5Descriptor &fileInfo, const std::string &prefix)
std::unique_ptr< Beamline::SpectrumInfo > m_spectrumInfo
const Sample & sample() const
Sample accessors.
void setEFixed(const detid_t detID, const double value)
Set the efixed value for a given detector ID.
double getEFixedGivenEMode(const std::shared_ptr< const Geometry::IDetector > &detector, const Kernel::DeltaEMode::Type emode) const
Easy access to the efixed value for this run & detector.
double getEFixedForIndirect(const std::shared_ptr< const Geometry::IDetector > &detector, const std::vector< std::string > &parameterNames) const
const std::string toString() const
Returns a string description of the object.
const Geometry::ParameterMap & instrumentParameters() const
Returns the set of parameters modifying the base instrument (const-version)
int getRunNumber() const
Utility method to get the run number.
std::string getAvailableWorkspaceEndDate() const
Return workspace end date as a formatted string (strftime style, as returned by Kernel::DateAdnTime) ...
const Geometry::ComponentInfo & componentInfo() const
void loadInstrumentParametersNexus(::NeXus::File *file, std::string &parameterStr)
Load instrument parameters from an open Nexus file in Instument group if found there.
std::string getWorkspaceStartDate() const
Returns the start date for this experiment (or current time if no info available)
void loadEmbeddedInstrumentInfoNexus(::NeXus::File *file, std::string &instrumentName, std::string &instrumentXml)
Attempt to load instrument embedded in Nexus file.
void setInstrument(const Geometry::Instrument_const_sptr &instr)
Instrument accessors.
std::unique_ptr< SpectrumInfo > m_spectrumInfoWrapper
void setSharedRun(Kernel::cow_ptr< Run > run)
Set the run object. Use in particular to clear run without copying old run.
void saveExperimentInfoNexus(::NeXus::File *file, bool saveLegacyInstrument=true) const
Saves this experiment description to the open NeXus file.
void setDetectorGrouping(const size_t index, const std::set< detid_t > &detIDs) const
Sets the detector grouping for the spectrum with the given index.
Kernel::cow_ptr< Run > sharedRun()
Return the cow ptr of the run.
ExperimentInfo & operator=(const ExperimentInfo &)
Implements the copy assignment operator.
void setSpectrumDefinitions(Kernel::cow_ptr< std::vector< SpectrumDefinition > > spectrumDefinitions)
Sets the SpectrumDefinition for all spectra.
void populateWithParameter(Geometry::ParameterMap &paramMap, Geometry::ParameterMap &paramMapForPosAndRot, const std::string &name, const Geometry::XMLInstrumentParameter &paramInfo, const Run &runData)
Fill with given instrument parameter.
std::vector< char > m_spectrumDefinitionNeedsUpdate
double getLogAsSingleValue(const std::string &log) const
Access a single value from a log for this experiment.
SpectrumInfo & mutableSpectrumInfo()
Return a non-const reference to the SpectrumInfo object.
void setNumberOfDetectorGroups(const size_t count) const
Sets the number of detector groups.
Sample & mutableSample()
Writable version of the sample object.
Geometry::Instrument_const_sptr sptr_instrument
The base (unparametrized) instrument.
void populateInstrumentParameters()
Add parameters to the instrument parameter map that are defined in instrument definition file or para...
Kernel::Property * getLog(const std::string &log) const
Access a log for this experiment.
void invalidateAllSpectrumDefinitions()
Sets flags for all spectrum definitions indicating that they need to be updated.
Kernel::cow_ptr< Run > m_run
The run information.
static std::string getInstrumentFilename(const std::string &instrumentName, const std::string &date="")
Get the IDF using the instrument name and date.
const Types::Core::DateAndTime endTime() const
Return the run end time.
Definition: LogManager.cpp:165
bool hasProperty(const std::string &name) const
Does the property exist on the object.
Definition: LogManager.cpp:265
const Types::Core::DateAndTime startTime() const
Return the run start time.
Definition: LogManager.cpp:133
Kernel::Property * getProperty(const std::string &name) const
Returns the named property as a pointer.
Definition: LogManager.cpp:404
double getPropertyAsSingleValue(const std::string &name, Kernel::Math::StatisticType statistic=Kernel::Math::Mean) const
Returns a property as a single double value from its name.
Definition: LogManager.cpp:349
HeldType getPropertyValueAsType(const std::string &name) const
Get the value of a property as the given TYPE.
Definition: LogManager.cpp:332
This class stores information regarding an experimental run as a series of log entries.
Definition: Run.h:38
void saveNexus(::NeXus::File *file, const std::string &group, bool keepOpen=false) const override
Save the run to a NeXus file with a given group name.
Definition: Run.cpp:446
void loadNexus(::NeXus::File *file, const std::string &group, const Mantid::Kernel::NexusHDF5Descriptor &fileInfo, const std::string &prefix, bool keepOpen=false) override
Load the run from a NeXus file with a given group name.
Definition: Run.cpp:498
This class stores information about the sample used in particular run.
Definition: Sample.h:33
void saveNexus(::NeXus::File *file, const std::string &group) const
Save the object to an open NeXus file.
Definition: Sample.cpp:286
const Geometry::OrientedLattice & getOrientedLattice() const
Get a reference to the sample's OrientedLattice.
Definition: Sample.cpp:154
int loadNexus(::NeXus::File *file, const std::string &group)
Load the object from an open NeXus file.
Definition: Sample.cpp:327
API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is part of Instrument-2....
Definition: SpectrumInfo.h:53
const Kernel::cow_ptr< std::vector< SpectrumDefinition > > & sharedSpectrumDefinitions() const
std::shared_ptr< const IComponent > getComponentByName(const std::string &cname, int nlevels=0) const override
Returns a pointer to the first component of assembly encountered with the given name.
ComponentInfo : Provides a component centric view on to the instrument.
Definition: ComponentInfo.h:40
bool hasParent(const size_t componentIndex) const
void setRotation(size_t componentIndex, const Kernel::Quat &newRotation)
size_t parent(const size_t componentIndex) const
Kernel::Quat rotation(const size_t componentIndex) const
Kernel::V3D position(const size_t componentIndex) const
size_t indexOf(Geometry::IComponent *id) const
bool isDetector(const size_t componentIndex) const
const std::string & name(const size_t componentIndex) const
void setPosition(size_t componentIndex, const Kernel::V3D &newPosition)
Geometry::DetectorInfo is an intermediate step towards a DetectorInfo that is part of Instrument-2....
Definition: DetectorInfo.h:49
void setMasked(const size_t index, bool masked)
Set the mask flag of the detector with given index. Not thread safe.
size_t indexOf(const detid_t id) const
Returns the index of the detector with the given detector ID.
size_t size() const
Returns the size of the DetectorInfo, i.e., the number of detectors in the instrument.
base class for Geometric IComponent
Definition: IComponent.h:51
virtual ComponentID getComponentID() const =0
Returns the ComponentID - a unique identifier of the component.
Creates an instrument data from a XML instrument description file.
std::shared_ptr< Instrument > parseXML(Kernel::ProgressBase *progressReporter)
Parse XML contents.
std::string getMangledName()
Handle used in the singleton constructor for instrument file should append the value file sha-1 check...
Base Instrument Class.
Definition: Instrument.h:47
std::size_t getNumberDetectors(bool skipMonitors=false) const
Definition: Instrument.cpp:222
std::shared_ptr< const Instrument > baseInstrument() const
Pointer to the 'real' instrument, for parametrized instruments.
Definition: Instrument.cpp:124
IDetector_const_sptr getDetector(const detid_t &detector_id) const
Gets a pointer to the detector from its ID Note that for getting the detector associated with a spect...
Definition: Instrument.cpp:461
Class to implement UB matrix.
static std::shared_ptr< Instrument > createInstrument(const std::shared_ptr< const Instrument > &base, const std::shared_ptr< ParameterMap > &map)
Create a parameterized instrument from the given base and ParameterMap.
static std::shared_ptr< Parameter > create(const std::string &className, const std::string &name, const std::string &visible="true")
Creates an instance of a parameter.
Definition: Parameter.cpp:83
const std::vector< std::string > & getParameterFilenames() const
Returns a list of all the parameter files loaded.
bool contains(const IComponent *comp, const std::string &name, const std::string &type="") const
Does the named parameter exist for the given component and type (std::string version)
void addInt(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds an int value to the parameter map.
void addPositionCoordinate(const IComponent *comp, const std::string &name, const double value, const std::string *const pDescription=nullptr)
Create or adjust "pos" parameter for a component.
std::shared_ptr< Parameter > getRecursive(const IComponent *comp, const std::string &name, const std::string &type="") const
Use get() recursively to see if can find param in all parents of comp and given type (std::string ver...
static const std::string & rot()
std::string getString(const IComponent *comp, const std::string &name, bool recursive=false) const
Return the value of a parameter as a string.
void addString(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds a std::string value to the parameter map.
void addDouble(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds a double value to the parameter map.
static const std::string & pos()
Return string to be used in the map.
void addRotationParam(const IComponent *comp, const std::string &name, const double deg, const std::string *const pDescription=nullptr)
Create or adjust "rot" parameter for a component.
void add(const std::string &type, const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &visible="true")
Method for adding a parameter providing its value as a string.
void addV3D(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr)
Adds a Kernel::V3D value to the parameter map.
void addBool(const IComponent *comp, const std::string &name, const std::string &value, const std::string *const pDescription=nullptr, const std::string &pVisible="true")
Adds a bool value to the parameter map.
std::shared_ptr< Parameter > get(const IComponent *comp, const std::string &name, const std::string &type="") const
Get a parameter with a given name and type (std::string version)
double alpha() const
Get lattice parameter.
Definition: UnitCell.cpp:133
double a(int nd) const
Get lattice parameter a1-a3 as function of index (0-2)
Definition: UnitCell.cpp:94
double c() const
Get lattice parameter.
Definition: UnitCell.cpp:128
double beta() const
Get lattice parameter.
Definition: UnitCell.cpp:138
double b() const
Get lattice parameter.
Definition: UnitCell.cpp:123
double gamma() const
Get lattice parameter.
Definition: UnitCell.cpp:143
This class is used to store information about parameters in XML instrument definition files and instr...
const Geometry::IComponent * m_component
value from the log value
const std::string m_value
rather then extracting value from logfile,
const std::string m_type
type of the data, e.g. int, double or string
const std::string m_description
if present, contains help string, describing the parameter
const std::string m_visible
if present, describes whether the parameter shall be visible in InstrumentViewer
std::shared_ptr< Kernel::Interpolation > m_interpolation
evaluating the formula
const std::string m_fittingFunction
specific to fitting parameter
std::string m_penaltyFactor
parameter specify lower and upper bound in that order
const std::string m_formula
specify fitting function
const std::string m_resultUnit
expected result (output) unit from
const std::vector< std::string > m_constraint
specific to fitting
const std::string m_tie
specific to fitting parameter specify any tie
const std::string m_formulaUnit
formula to use for setting this parameter
Exception for when an item is not found in a collection.
Definition: Exception.h:145
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
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
The concrete, templated class for properties.
Base class for properties.
Definition: Property.h:94
virtual std::string value() const =0
Returns the value of the property as a string.
Class for quaternions.
Definition: Quat.h:39
void rotate(V3D &) const
Rotate a vector.
Definition: Quat.cpp:397
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Iterator begin()
Iterator referring to first element in the container.
@ TOK_IGNORE_EMPTY
ignore empty tokens
@ TOK_TRIM
remove leading and trailing whitespace from tokens
Iterator end()
Iterator referring to the past-the-end element in the container.
std::size_t count() const
Get the total number of tokens.
Class for 3D vectors.
Definition: V3D.h:34
void spherical(const double R, const double theta, const double phi) noexcept
Sets the vector position based on spherical coordinates.
Definition: V3D.cpp:57
Implements a copy on write data template.
Definition: cow_ptr.h:41
std::shared_ptr< const ExperimentInfo > ExperimentInfo_const_sptr
Shared pointer to const ExperimentInfo.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
MANTID_API_DLL void applyRectangularDetectorScaleToComponentInfo(Geometry::ComponentInfo &componentInfo, Geometry::IComponent *componentId, const double scaleX, const double scaleY)
Helpers for resizing RectangularDetectors.
std::shared_ptr< Parameter > Parameter_sptr
Typedef for the shared pointer.
Definition: Parameter.h:195
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::shared_ptr< Instrument > Instrument_sptr
Shared pointer to an instrument object.
MANTID_KERNEL_DLL std::string strip(const std::string &A)
strip pre/post spaces
Definition: Strings.cpp:397
MANTID_KERNEL_DLL std::string loadFile(const std::string &filename)
Loads the entire contents of a text file into a string.
Definition: Strings.cpp:28
int convert(const std::string &A, T &out)
Convert a string into a number.
Definition: Strings.cpp:665
int32_t detid_t
Typedef for a detector ID.
Definition: SpectrumInfo.h:21
Generate a tableworkspace to store the calibration results.
static Type fromString(const std::string &modeStr)
Returns the emode from the given string.
Definition: DeltaEMode.cpp:69
Type
Define the available energy transfer modes It is important to assign enums proper numbers,...
Definition: DeltaEMode.h:29