40using Mantid::Kernel::compareStringsCaseInsensitive;
50enum class CalibFilenameExtensionEnum {
H5, HD5, HDF, CAL, enum_count };
51const std::vector<std::string> calibFilenameExtensions{
".h5",
".hd5",
".hdf",
".cal"};
52typedef EnumeratedString<CalibFilenameExtensionEnum, &calibFilenameExtensions, &compareStringsCaseInsensitive>
53 CalibFilenameExtension;
55enum class GroupingFilenameExtensionEnum { XML,
H5, HD5, HDF, CAL, enum_count };
56const std::vector<std::string> groupingFilenameExtensions{
".xml",
".h5",
".hd5",
".hdf",
".cal"};
57typedef EnumeratedString<GroupingFilenameExtensionEnum, &groupingFilenameExtensions, &compareStringsCaseInsensitive>
58 GroupingFilenameExtension;
61const std::string
CAL_FILE(
"Filename");
62const std::string GROUP_FILE(
"GroupFilename");
63const std::string MAKE_CAL(
"MakeCalWorkspace");
64const std::string MAKE_GRP(
"MakeGroupingWorkspace");
65const std::string MAKE_MSK(
"MakeMaskWorkspace");
82const std::string
LoadDiffCal::summary()
const {
return "Loads a calibration file for powder diffraction"; }
91 std::make_unique<FileProperty>(PropertyNames::CAL_FILE,
"",
FileProperty::Load, calibFilenameExtensions),
92 "Path to the input calibration file.");
95 groupingFilenameExtensions),
96 "Overrides grouping from CalFileName");
99 "Set to true to create a GroupingWorkspace with called "
100 "WorkspaceName_group.");
103 "Set to true to create a CalibrationWorkspace with called "
104 "WorkspaceName_cal.");
107 "Set to true to create a MaskWorkspace with called WorkspaceName_mask.");
110 "The base of the output workspace names. Names will have '_group', "
111 "'_cal', '_mask' appended to them.");
113 std::string grpName(
"Calibration Validation");
117 "Set DIFA and TZERO to zero if there is an error and the "
129 "Set the output GroupingWorkspace, if any.");
136 "Set the output MaskWorkspace, if any.");
140void setCalWSProperty(API::Algorithm *alg,
const std::string &prefix,
const ITableWorkspace_sptr &wksp) {
142 std::make_unique<WorkspaceProperty<ITableWorkspace>>(
"OutputCalWorkspace", prefix +
"_cal",
Direction::Output),
143 "Set the output Diffraction Calibration workspace, if any.");
144 alg->setProperty(
"OutputCalWorkspace", wksp);
151 bool makeMask =
getProperty(PropertyNames::MAKE_MSK);
152 bool makeGrouping =
getProperty(PropertyNames::MAKE_GRP);
153 if ((!makeMask) & (!makeGrouping))
162 std::string idf =
H5Util::readString(file,
"/calibration/instrument/instrument_source");
163 std::string instrumentName =
H5Util::readString(file,
"/calibration/instrument/name");
166 <<
"NAME: " << instrumentName <<
"\n";
172 childAlg->setPropertyValue(
"InstrumentName", instrumentName);
174 childAlg->setPropertyValue(
"Filename", idf);
177 childAlg->executeAsChildAlg();
178 if (childAlg->isExecuted()) {
184 g_log.
debug(
"LoadInstrument child algorithm did not execute successfully. No instrument will be associated with "
185 "the output workspaces.");
188 }
catch (
const std::exception &) {
189 g_log.
debug(
"LoadInstrument child algorithm threw an exception. No instrument will be associated with the output "
196 bool makeWS =
getProperty(PropertyNames::MAKE_GRP);
198 g_log.
information(
"Not loading GroupingWorkspace from the calibration file");
203 if (!
isDefault(PropertyNames::GROUP_FILE)) {
208 size_t numDet = detids.size();
213 wksp = std::make_shared<DataObjects::GroupingWorkspace>(
m_instrument);
215 wksp = std::make_shared<DataObjects::GroupingWorkspace>(detids);
218 wksp->mutableRun().addProperty(
"Filename",
m_filename);
220 for (
size_t i = 0; i < numDet; ++i) {
221 auto detid =
static_cast<detid_t>(detids[i]);
222 wksp->setValue(detid, groups[i]);
230 bool makeWS =
getProperty(PropertyNames::MAKE_MSK);
236 size_t numDet = detids.size();
241 wksp = std::make_shared<DataObjects::MaskWorkspace>(
m_instrument);
243 wksp = std::make_shared<DataObjects::MaskWorkspace>(detids);
246 wksp->mutableRun().addProperty(
"Filename",
m_filename);
248 for (
size_t i = 0; i < numDet; ++i) {
249 bool shouldUse = (use[i] > 0);
250 auto detid =
static_cast<detid_t>(detids[i]);
252 wksp->setMasked(detid, !shouldUse);
254 wksp->setValue(detid, (shouldUse ? 0. : 1.));
262 const std::vector<double> &
difa,
const std::vector<double> &
tzero,
263 const std::vector<int32_t> &dasids,
const std::vector<double> &offsets,
264 const std::vector<int32_t> &use) {
265 bool makeWS =
getProperty(PropertyNames::MAKE_CAL);
271 size_t numDet = detids.size();
274 bool haveDasids = !dasids.empty();
275 bool haveOffsets = !offsets.empty();
276 bool fixIssues =
getProperty(
"FixConversionIssues");
280 bool useTofMax = !
isEmpty(tofMax);
284 wksp->addColumn(
"int",
"detid");
285 wksp->addColumn(
"double",
"difc");
286 wksp->addColumn(
"double",
"difa");
287 wksp->addColumn(
"double",
"tzero");
290 wksp->addColumn(
"int",
"dasid");
292 wksp->addColumn(
"double",
"offset");
295 wksp->addColumn(
"double",
"tofmin");
297 wksp->addColumn(
"double",
"tofmax");
300 for (
size_t i = 0; i < numDet; ++i) {
309 newrow << offsets[i];
314 std::stringstream msg;
315 if (tofMinRow != tofMin) {
316 msg <<
"TofMin shifted from " << tofMin <<
" to " << tofMinRow <<
" ";
323 if (tofMaxRow != tofMax) {
324 msg <<
"TofMax shifted from " << tofMax <<
" to " << tofMaxRow;
327 if (!msg.str().empty()) {
329 std::stringstream longMsg;
330 longMsg <<
"[detid=" << detids[i];
332 longMsg <<
", dasid=" << dasids[i];
333 longMsg <<
"] " << msg.str();
336 if (fixIssues && (!use[i])) {
337 longMsg <<
" pixel is masked, ";
338 longMsg <<
" changing difa (" << wksp->
cell<
double>(i, 2) <<
" to 0.)";
339 wksp->cell<
double>(i, 2) = 0.;
341 longMsg <<
" and tzero (" << wksp->cell<
double>(i, 3) <<
" to 0.)";
342 wksp->cell<
double>(i, 3) = 0.;
350 wksp->cell<
double>(i,
index) = tofMin;
352 wksp->cell<
double>(i,
index + 1) = tofMax;
361 this->
g_log.
warning() << badCount <<
" rows have reduced time-of-flight range\n";
368 bool makeWS =
getProperty(PropertyNames::MAKE_GRP);
372 if (
isDefault(PropertyNames::GROUP_FILE))
377 throw std::runtime_error(
"Cannot load alternate grouping: the instrument is not defined.");
384 g_log.
information() <<
"Override grouping with information from \"" << filename <<
"\"\n";
387 std::string filenameExtension = std::filesystem::path(filename).extension().string();
388 GroupingFilenameExtension enFilenameExtension(
390 switch (enFilenameExtension) {
391 case GroupingFilenameExtensionEnum::XML: {
393 alg->setProperty(
"InputWorkspace", groupingWorkspace);
394 alg->setProperty(
"InputFile", filename);
395 alg->executeAsChildAlg();
396 groupingWorkspace = alg->getProperty(
"OutputWorkspace");
398 case GroupingFilenameExtensionEnum::H5:
399 case GroupingFilenameExtensionEnum::HD5:
400 case GroupingFilenameExtensionEnum::HDF:
401 case GroupingFilenameExtensionEnum::CAL: {
403 alg->setPropertyValue(PropertyNames::CAL_FILE, filename);
404 alg->setProperty(
"InputWorkspace", groupingWorkspace);
405 alg->setProperty<
bool>(PropertyNames::MAKE_CAL,
false);
406 alg->setProperty<
bool>(PropertyNames::MAKE_GRP,
true);
407 alg->setProperty<
bool>(PropertyNames::MAKE_MSK,
false);
409 alg->executeAsChildAlg();
410 groupingWorkspace = alg->getProperty(
"OutputGroupingWorkspace");
413 std::ostringstream os;
414 os <<
"Alternate grouping file has an invalid extension: "
415 <<
"\"" << filenameExtension <<
"\"";
416 throw std::runtime_error(os.str());
423 bool makeCalWS =
getProperty(PropertyNames::MAKE_CAL);
424 bool makeMaskWS =
getProperty(PropertyNames::MAKE_MSK);
425 bool makeGroupWS =
getProperty(PropertyNames::MAKE_GRP);
428 bool haveGroupingFile = !
isDefault(PropertyNames::GROUP_FILE);
431 alg->setPropertyValue(
"CalFilename",
m_filename);
432 alg->setProperty(
"InputWorkspace", inputWs);
433 alg->setPropertyValue(
"InstrumentName",
getPropertyValue(
"InstrumentName"));
434 alg->setPropertyValue(
"InstrumentFilename",
getPropertyValue(
"InstrumentFilename"));
435 alg->setProperty<
bool>(
"MakeOffsetsWorkspace", makeCalWS);
436 alg->setProperty<
bool>(
"MakeGroupingWorkspace", makeGroupWS);
437 alg->setProperty<
bool>(
"MakeMaskWorkspace", makeMaskWS);
439 alg->executeAsChildAlg();
448 setMaskWSProperty(
this,
m_workspaceName, std::dynamic_pointer_cast<DataObjects::MaskWorkspace>(wksp));
453 if (haveGroupingFile) {
472 std::string filenameExtension = std::filesystem::path(
m_filename).extension().string();
473 CalibFilenameExtension enFilenameExtension(
475 if (enFilenameExtension == CalibFilenameExtensionEnum::CAL) {
481 H5::Exception::dontPrint();
485 }
catch (FileIException &) {
492 Group calibrationGroup;
494 calibrationGroup = file.openGroup(
"calibration");
495 }
catch (FileIException &e) {
496#if H5_VERSION_GE(1, 8, 13)
498 H5::Exception::printErrorStack();
500 e.printError(stderr);
507 std::vector<int32_t> detids = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"detid");
509 std::vector<int32_t> dasids = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"dasid");
511 std::vector<int32_t> groups = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"group");
513 std::vector<int32_t> use = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"use");
516 std::vector<double>
difc = H5Util::readArray1DCoerce<double>(calibrationGroup,
"difc");
518 std::vector<double>
difa = H5Util::readArray1DCoerce<double>(calibrationGroup,
"difa");
520 std::vector<double>
tzero = H5Util::readArray1DCoerce<double>(calibrationGroup,
"tzero");
522 std::vector<double> offset = H5Util::readArray1DCoerce<double>(calibrationGroup,
"offset");
527 if (detids.empty()) {
528 throw std::runtime_error(
"File was missing required field \"/calibraion/detid\"");
531 throw std::runtime_error(
"File was missing required field \"/calibraion/difc\"");
536 groups.assign(detids.size(), 1);
538 use.assign(detids.size(), 1);
540 difa.assign(detids.size(), 0.);
542 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")
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.