41using Mantid::Kernel::compareStringsCaseInsensitive;
51enum class CalibFilenameExtensionEnum {
H5, HD5, HDF, CAL, enum_count };
52const std::vector<std::string> calibFilenameExtensions{
".h5",
".hd5",
".hdf",
".cal"};
53typedef EnumeratedString<CalibFilenameExtensionEnum, &calibFilenameExtensions, &compareStringsCaseInsensitive>
54 CalibFilenameExtension;
56enum class GroupingFilenameExtensionEnum { XML,
H5, HD5, HDF, CAL, enum_count };
57const std::vector<std::string> groupingFilenameExtensions{
".xml",
".h5",
".hd5",
".hdf",
".cal"};
58typedef EnumeratedString<GroupingFilenameExtensionEnum, &groupingFilenameExtensions, &compareStringsCaseInsensitive>
59 GroupingFilenameExtension;
62const std::string
CAL_FILE(
"Filename");
64const std::string MAKE_CAL(
"MakeCalWorkspace");
65const std::string MAKE_GRP(
"MakeGroupingWorkspace");
66const std::string MAKE_MSK(
"MakeMaskWorkspace");
83const std::string
LoadDiffCal::summary()
const {
return "Loads a calibration file for powder diffraction"; }
92 std::make_unique<FileProperty>(PropertyNames::CAL_FILE,
"",
FileProperty::Load, calibFilenameExtensions),
93 "Path to the input calibration file.");
96 groupingFilenameExtensions),
97 "Overrides grouping from CalFileName");
100 "Set to true to create a GroupingWorkspace with called "
101 "WorkspaceName_group.");
104 "Set to true to create a CalibrationWorkspace with called "
105 "WorkspaceName_cal.");
108 "Set to true to create a MaskWorkspace with called WorkspaceName_mask.");
111 "The base of the output workspace names. Names will have '_group', "
112 "'_cal', '_mask' appended to them.");
114 std::string grpName(
"Calibration Validation");
118 "Set DIFA and TZERO to zero if there is an error and the "
130 "Set the output GroupingWorkspace, if any.");
137 "Set the output MaskWorkspace, if any.");
141void setCalWSProperty(API::Algorithm *alg,
const std::string &prefix,
const ITableWorkspace_sptr &wksp) {
143 std::make_unique<WorkspaceProperty<ITableWorkspace>>(
"OutputCalWorkspace", prefix +
"_cal",
Direction::Output),
144 "Set the output Diffraction Calibration workspace, if any.");
145 alg->setProperty(
"OutputCalWorkspace", wksp);
152 bool makeMask =
getProperty(PropertyNames::MAKE_MSK);
153 bool makeGrouping =
getProperty(PropertyNames::MAKE_GRP);
154 if ((!makeMask) & (!makeGrouping))
163 std::string idf =
H5Util::readString(file,
"/calibration/instrument/instrument_source");
164 std::string instrumentName =
H5Util::readString(file,
"/calibration/instrument/name");
167 <<
"NAME: " << instrumentName <<
"\n";
173 childAlg->setPropertyValue(
"InstrumentName", instrumentName);
175 childAlg->setPropertyValue(
"Filename", idf);
178 childAlg->executeAsChildAlg();
179 if (childAlg->isExecuted()) {
183 << tempWS->instrumentMetadata().filename() <<
"\"\n";
185 g_log.
debug(
"LoadInstrument child algorithm did not execute successfully. No instrument will be associated with "
186 "the output workspaces.");
189 }
catch (
const std::exception &) {
190 g_log.
debug(
"LoadInstrument child algorithm threw an exception. No instrument will be associated with the output "
197 bool makeWS =
getProperty(PropertyNames::MAKE_GRP);
199 g_log.
information(
"Not loading GroupingWorkspace from the calibration file");
204 if (!
isDefault(PropertyNames::GROUP_FILE)) {
209 size_t numDet = detids.size();
214 wksp = std::make_shared<DataObjects::GroupingWorkspace>(
m_instrument);
216 wksp = std::make_shared<DataObjects::GroupingWorkspace>(detids);
219 wksp->mutableRun().addProperty(
"Filename",
m_filename);
221 for (
size_t i = 0; i < numDet; ++i) {
222 auto detid =
static_cast<detid_t>(detids[i]);
223 wksp->setValue(detid, groups[i]);
231 bool makeWS =
getProperty(PropertyNames::MAKE_MSK);
237 size_t numDet = detids.size();
242 wksp = std::make_shared<DataObjects::MaskWorkspace>(
m_instrument);
244 wksp = std::make_shared<DataObjects::MaskWorkspace>(detids);
247 wksp->mutableRun().addProperty(
"Filename",
m_filename);
249 for (
size_t i = 0; i < numDet; ++i) {
250 bool shouldUse = (use[i] > 0);
251 auto detid =
static_cast<detid_t>(detids[i]);
253 wksp->setMasked(detid, !shouldUse);
255 wksp->setValue(detid, (shouldUse ? 0. : 1.));
263 const std::vector<double> &
difa,
const std::vector<double> &
tzero,
264 const std::vector<int32_t> &dasids,
const std::vector<double> &offsets,
265 const std::vector<int32_t> &use) {
266 bool makeWS =
getProperty(PropertyNames::MAKE_CAL);
272 size_t numDet = detids.size();
275 bool haveDasids = !dasids.empty();
276 bool haveOffsets = !offsets.empty();
277 bool fixIssues =
getProperty(
"FixConversionIssues");
281 bool useTofMax = !
isEmpty(tofMax);
285 wksp->addColumn(
"int",
"detid");
286 wksp->addColumn(
"double",
"difc");
287 wksp->addColumn(
"double",
"difa");
288 wksp->addColumn(
"double",
"tzero");
291 wksp->addColumn(
"int",
"dasid");
293 wksp->addColumn(
"double",
"offset");
296 wksp->addColumn(
"double",
"tofmin");
298 wksp->addColumn(
"double",
"tofmax");
301 for (
size_t i = 0; i < numDet; ++i) {
310 newrow << offsets[i];
315 std::stringstream msg;
316 if (tofMinRow != tofMin) {
317 msg <<
"TofMin shifted from " << tofMin <<
" to " << tofMinRow <<
" ";
324 if (tofMaxRow != tofMax) {
325 msg <<
"TofMax shifted from " << tofMax <<
" to " << tofMaxRow;
328 if (!msg.str().empty()) {
330 std::stringstream longMsg;
331 longMsg <<
"[detid=" << detids[i];
333 longMsg <<
", dasid=" << dasids[i];
334 longMsg <<
"] " << msg.str();
337 if (fixIssues && (!use[i])) {
338 longMsg <<
" pixel is masked, ";
339 longMsg <<
" changing difa (" << wksp->
cell<
double>(i, 2) <<
" to 0.)";
340 wksp->cell<
double>(i, 2) = 0.;
342 longMsg <<
" and tzero (" << wksp->cell<
double>(i, 3) <<
" to 0.)";
343 wksp->cell<
double>(i, 3) = 0.;
351 wksp->cell<
double>(i,
index) = tofMin;
353 wksp->cell<
double>(i,
index + 1) = tofMax;
362 this->
g_log.
warning() << badCount <<
" rows have reduced time-of-flight range\n";
369 bool makeWS =
getProperty(PropertyNames::MAKE_GRP);
373 if (
isDefault(PropertyNames::GROUP_FILE))
378 throw std::runtime_error(
"Cannot load alternate grouping: the instrument is not defined.");
385 g_log.
information() <<
"Override grouping with information from \"" << filename <<
"\"\n";
388 std::string filenameExtension = std::filesystem::path(filename).extension().string();
389 GroupingFilenameExtension enFilenameExtension(
391 switch (enFilenameExtension) {
392 case GroupingFilenameExtensionEnum::XML: {
394 alg->setProperty(
"InputWorkspace", groupingWorkspace);
395 alg->setProperty(
"InputFile", filename);
396 alg->executeAsChildAlg();
397 groupingWorkspace = alg->getProperty(
"OutputWorkspace");
399 case GroupingFilenameExtensionEnum::H5:
400 case GroupingFilenameExtensionEnum::HD5:
401 case GroupingFilenameExtensionEnum::HDF:
402 case GroupingFilenameExtensionEnum::CAL: {
404 alg->setPropertyValue(PropertyNames::CAL_FILE, filename);
405 alg->setProperty(
"InputWorkspace", groupingWorkspace);
406 alg->setProperty<
bool>(PropertyNames::MAKE_CAL,
false);
407 alg->setProperty<
bool>(PropertyNames::MAKE_GRP,
true);
408 alg->setProperty<
bool>(PropertyNames::MAKE_MSK,
false);
410 alg->executeAsChildAlg();
411 groupingWorkspace = alg->getProperty(
"OutputGroupingWorkspace");
414 std::ostringstream os;
415 os <<
"Alternate grouping file has an invalid extension: "
416 <<
"\"" << filenameExtension <<
"\"";
417 throw std::runtime_error(os.str());
424 bool makeCalWS =
getProperty(PropertyNames::MAKE_CAL);
425 bool makeMaskWS =
getProperty(PropertyNames::MAKE_MSK);
426 bool makeGroupWS =
getProperty(PropertyNames::MAKE_GRP);
429 bool haveGroupingFile = !
isDefault(PropertyNames::GROUP_FILE);
432 alg->setPropertyValue(
"CalFilename",
m_filename);
433 alg->setProperty(
"InputWorkspace", inputWs);
434 alg->setPropertyValue(
"InstrumentName",
getPropertyValue(
"InstrumentName"));
435 alg->setPropertyValue(
"InstrumentFilename",
getPropertyValue(
"InstrumentFilename"));
436 alg->setProperty<
bool>(
"MakeOffsetsWorkspace", makeCalWS);
437 alg->setProperty<
bool>(
"MakeGroupingWorkspace", makeGroupWS);
438 alg->setProperty<
bool>(
"MakeMaskWorkspace", makeMaskWS);
440 alg->executeAsChildAlg();
449 setMaskWSProperty(
this,
m_workspaceName, std::dynamic_pointer_cast<DataObjects::MaskWorkspace>(wksp));
454 if (haveGroupingFile) {
473 std::string filenameExtension = std::filesystem::path(
m_filename).extension().string();
474 CalibFilenameExtension enFilenameExtension(
476 if (enFilenameExtension == CalibFilenameExtensionEnum::CAL) {
482 H5::Exception::dontPrint();
486 }
catch (FileIException &) {
493 Group calibrationGroup;
495 calibrationGroup = file.openGroup(
"calibration");
496 }
catch (FileIException &e) {
497#if H5_VERSION_GE(1, 8, 13)
499 H5::Exception::printErrorStack();
501 e.printError(stderr);
508 std::vector<int32_t> detids = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"detid");
510 std::vector<int32_t> dasids = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"dasid");
512 std::vector<int32_t> groups = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"group");
514 std::vector<int32_t> use = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"use");
517 std::vector<double>
difc = H5Util::readArray1DCoerce<double>(calibrationGroup,
"difc");
519 std::vector<double>
difa = H5Util::readArray1DCoerce<double>(calibrationGroup,
"difa");
521 std::vector<double>
tzero = H5Util::readArray1DCoerce<double>(calibrationGroup,
"tzero");
523 std::vector<double> offset = H5Util::readArray1DCoerce<double>(calibrationGroup,
"offset");
528 if (detids.empty()) {
529 throw std::runtime_error(
"File was missing required field \"/calibraion/detid\"");
532 throw std::runtime_error(
"File was missing required field \"/calibraion/difc\"");
537 groups.assign(detids.size(), 1);
539 use.assign(detids.size(), 1);
541 difa.assign(detids.size(), 0.);
543 tzero.assign(detids.size(), 0.);
#define DECLARE_ALGORITHM(classname)
std::map< DeltaEMode::Type, std::string > index
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
Base class from which all concrete algorithm classes should be derived.
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.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
virtual 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)
Create a Child Algorithm.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
bool isDefault(const std::string &name) const
static bool isEmpty(const NumT toCheck)
checks that the value was not set by users, uses the value in empty double/int.
A specialized class for dealing with file properties.
@ OptionalLoad
to specify a file to read but the file doesn't have to exist
@ Load
allowed here which will be passed to the algorithm
ITableWorkspace is an implementation of Workspace in which the data are organised in columns of same ...
Helper class for reporting progress from algorithms.
TableRow represents a row in a TableWorkspace.
T & cell(size_t col)
Templated method to access the element col in the row.
A property class for workspaces.
static void getInstrument3WaysInit(Mantid::API::Algorithm *alg)
For use by getInstrument3Ways, initializes the properties.
static bool instrumentIsSpecified(API::Algorithm const *alg)
static Geometry::Instrument_const_sptr getInstrument3Ways(API::Algorithm *alg)
Get a pointer to an instrument in one of 3 ways: InputWorkspace, InstrumentName, InstrumentFilename.
LoadDiffCal : TODO: DESCRIPTION.
int version() const override
Algorithm's version for identification.
Geometry::Instrument_const_sptr m_instrument
std::string m_workspaceName
void init() override
Initialize the algorithm's properties.
void loadGroupingFromAlternateFile()
void getInstrument(H5::H5File &file)
const std::string summary() const override
Algorithm's summary for use in the GUI and help.
void exec() override
Execute the algorithm.
void makeGroupingWorkspace(const std::vector< int32_t > &detids, const std::vector< int32_t > &groups)
const std::string category() const override
Algorithm's category for identification.
void makeMaskWorkspace(const std::vector< int32_t > &detids, const std::vector< int32_t > &use)
void makeCalWorkspace(const std::vector< int32_t > &detids, const std::vector< double > &difc, const std::vector< double > &difa, const std::vector< double > &tzero, const std::vector< int32_t > &dasids, const std::vector< double > &offsets, const std::vector< int32_t > &use)
Concrete workspace implementation.
The class Group represents a set of symmetry operations (or symmetry group).
Records the filename and the description of failure.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
virtual void declareProperty(std::unique_ptr< Property > p, const std::string &doc="")=0
Function to declare properties (i.e. store them)
void setPropertyGroup(const std::string &name, const std::string &group)
Set the group for a given property.
void debug(const std::string &msg)
Logs at debug level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
OptionalBool : Tri-state bool.
The concrete, templated class for properties.
double calcTofMax(const double difc, const double difa, const double tzero, const double tofmax=0.)
double calcTofMin(const double difc, const double difa, const double tzero, const double tofmin=0.)
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< Algorithm > Algorithm_sptr
Typedef for a shared pointer to an Algorithm.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
const std::string CAL_FILE("CalFileName")
const std::string GROUP_FILE("GroupFilename")
std::shared_ptr< GroupingWorkspace > GroupingWorkspace_sptr
shared pointer to the GroupingWorkspace class
std::shared_ptr< MaskWorkspace > MaskWorkspace_sptr
shared pointer to the MaskWorkspace class
MANTID_NEXUS_DLL std::string readString(H5::H5File &file, const std::string &address)
MANTID_NEXUS_DLL H5::FileAccPropList defaultFileAcc()
Default file access is H5F_CLOSE_STRONG.
int32_t detid_t
Typedef for a detector ID.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
Describes the direction (within an algorithm) of a Property.
@ Input
An input workspace.
@ Output
An output workspace.