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();
186 bool makeWS =
getProperty(PropertyNames::MAKE_GRP);
188 g_log.
information(
"Not loading GroupingWorkspace from the calibration file");
193 if (!
isDefault(PropertyNames::GROUP_FILE)) {
198 size_t numDet = detids.size();
203 wksp->mutableRun().addProperty(
"Filename",
m_filename);
205 for (
size_t i = 0; i < numDet; ++i) {
206 auto detid =
static_cast<detid_t>(detids[i]);
207 wksp->setValue(detid, groups[i]);
215 bool makeWS =
getProperty(PropertyNames::MAKE_MSK);
221 size_t numDet = detids.size();
226 wksp->mutableRun().addProperty(
"Filename",
m_filename);
228 for (
size_t i = 0; i < numDet; ++i) {
229 bool shouldUse = (use[i] > 0);
230 auto detid =
static_cast<detid_t>(detids[i]);
232 wksp->setMasked(detid, !shouldUse);
234 wksp->setValue(detid, (shouldUse ? 0. : 1.));
242 const std::vector<double> &
difa,
const std::vector<double> &
tzero,
243 const std::vector<int32_t> &dasids,
const std::vector<double> &offsets,
244 const std::vector<int32_t> &use) {
245 bool makeWS =
getProperty(PropertyNames::MAKE_CAL);
251 size_t numDet = detids.size();
254 bool haveDasids = !dasids.empty();
255 bool haveOffsets = !offsets.empty();
256 bool fixIssues =
getProperty(
"FixConversionIssues");
260 bool useTofMax = !
isEmpty(tofMax);
264 wksp->addColumn(
"int",
"detid");
265 wksp->addColumn(
"double",
"difc");
266 wksp->addColumn(
"double",
"difa");
267 wksp->addColumn(
"double",
"tzero");
270 wksp->addColumn(
"int",
"dasid");
272 wksp->addColumn(
"double",
"offset");
275 wksp->addColumn(
"double",
"tofmin");
277 wksp->addColumn(
"double",
"tofmax");
280 for (
size_t i = 0; i < numDet; ++i) {
289 newrow << offsets[i];
294 std::stringstream msg;
295 if (tofMinRow != tofMin) {
296 msg <<
"TofMin shifted from " << tofMin <<
" to " << tofMinRow <<
" ";
303 if (tofMaxRow != tofMax) {
304 msg <<
"TofMax shifted from " << tofMax <<
" to " << tofMaxRow;
307 if (!msg.str().empty()) {
309 std::stringstream longMsg;
310 longMsg <<
"[detid=" << detids[i];
312 longMsg <<
", dasid=" << dasids[i];
313 longMsg <<
"] " << msg.str();
316 if (fixIssues && (!use[i])) {
317 longMsg <<
" pixel is masked, ";
318 longMsg <<
" changing difa (" << wksp->
cell<
double>(i, 2) <<
" to 0.)";
319 wksp->cell<
double>(i, 2) = 0.;
321 longMsg <<
" and tzero (" << wksp->cell<
double>(i, 3) <<
" to 0.)";
322 wksp->cell<
double>(i, 3) = 0.;
330 wksp->cell<
double>(i,
index) = tofMin;
332 wksp->cell<
double>(i,
index + 1) = tofMax;
341 this->
g_log.
warning() << badCount <<
" rows have reduced time-of-flight range\n";
348 bool makeWS =
getProperty(PropertyNames::MAKE_GRP);
352 if (
isDefault(PropertyNames::GROUP_FILE))
357 throw std::runtime_error(
"Cannot load alternate grouping: the instrument is not defined.");
364 g_log.
information() <<
"Override grouping with information from \"" << filename <<
"\"\n";
367 std::string filenameExtension = std::filesystem::path(filename).extension().string();
368 GroupingFilenameExtension enFilenameExtension(
370 switch (enFilenameExtension) {
371 case GroupingFilenameExtensionEnum::XML: {
373 alg->setProperty(
"InputWorkspace", groupingWorkspace);
374 alg->setProperty(
"InputFile", filename);
375 alg->executeAsChildAlg();
376 groupingWorkspace = alg->getProperty(
"OutputWorkspace");
378 case GroupingFilenameExtensionEnum::H5:
379 case GroupingFilenameExtensionEnum::HD5:
380 case GroupingFilenameExtensionEnum::HDF:
381 case GroupingFilenameExtensionEnum::CAL: {
383 alg->setPropertyValue(PropertyNames::CAL_FILE, filename);
384 alg->setProperty(
"InputWorkspace", groupingWorkspace);
385 alg->setProperty<
bool>(PropertyNames::MAKE_CAL,
false);
386 alg->setProperty<
bool>(PropertyNames::MAKE_GRP,
true);
387 alg->setProperty<
bool>(PropertyNames::MAKE_MSK,
false);
389 alg->executeAsChildAlg();
390 groupingWorkspace = alg->getProperty(
"OutputGroupingWorkspace");
393 std::ostringstream os;
394 os <<
"Alternate grouping file has an invalid extension: "
395 <<
"\"" << filenameExtension <<
"\"";
396 throw std::runtime_error(os.str());
403 bool makeCalWS =
getProperty(PropertyNames::MAKE_CAL);
404 bool makeMaskWS =
getProperty(PropertyNames::MAKE_MSK);
405 bool makeGroupWS =
getProperty(PropertyNames::MAKE_GRP);
408 bool haveGroupingFile = !
isDefault(PropertyNames::GROUP_FILE);
411 alg->setPropertyValue(
"CalFilename",
m_filename);
412 alg->setProperty(
"InputWorkspace", inputWs);
413 alg->setPropertyValue(
"InstrumentName",
getPropertyValue(
"InstrumentName"));
414 alg->setPropertyValue(
"InstrumentFilename",
getPropertyValue(
"InstrumentFilename"));
415 alg->setProperty<
bool>(
"MakeOffsetsWorkspace", makeCalWS);
416 alg->setProperty<
bool>(
"MakeGroupingWorkspace", makeGroupWS);
417 alg->setProperty<
bool>(
"MakeMaskWorkspace", makeMaskWS);
419 alg->executeAsChildAlg();
428 setMaskWSProperty(
this,
m_workspaceName, std::dynamic_pointer_cast<DataObjects::MaskWorkspace>(wksp));
433 if (haveGroupingFile) {
452 std::string filenameExtension = std::filesystem::path(
m_filename).extension().string();
453 CalibFilenameExtension enFilenameExtension(
455 if (enFilenameExtension == CalibFilenameExtensionEnum::CAL) {
461 H5::Exception::dontPrint();
465 }
catch (FileIException &) {
471 Group calibrationGroup;
473 calibrationGroup = file.openGroup(
"calibration");
474 }
catch (FileIException &e) {
475#if H5_VERSION_GE(1, 8, 13)
477 H5::Exception::printErrorStack();
479 e.printError(stderr);
486 std::vector<int32_t> detids = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"detid");
488 std::vector<int32_t> dasids = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"dasid");
490 std::vector<int32_t> groups = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"group");
492 std::vector<int32_t> use = H5Util::readArray1DCoerce<int32_t>(calibrationGroup,
"use");
495 std::vector<double>
difc = H5Util::readArray1DCoerce<double>(calibrationGroup,
"difc");
497 std::vector<double>
difa = H5Util::readArray1DCoerce<double>(calibrationGroup,
"difa");
499 std::vector<double>
tzero = H5Util::readArray1DCoerce<double>(calibrationGroup,
"tzero");
501 std::vector<double> offset = H5Util::readArray1DCoerce<double>(calibrationGroup,
"offset");
506 if (detids.empty()) {
507 throw std::runtime_error(
"File was missing required field \"/calibraion/detid\"");
510 throw std::runtime_error(
"File was missing required field \"/calibraion/difc\"");
515 groups.assign(detids.size(), 1);
517 use.assign(detids.size(), 1);
519 difa.assign(detids.size(), 0.);
521 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.