27#include <boost/algorithm/string/classification.hpp>
28#include <boost/algorithm/string/split.hpp>
35using namespace Kernel;
37using namespace Geometry;
38using namespace DataObjects;
39using Types::Core::DateAndTime;
41namespace CorelliCalibration {
68 if (wsname.size() > 0) {
69 AnalysisDataService::Instance().addOrReplace(wsname, itablews);
76 tablews->addColumn(
"str",
"YYYMMDD");
78 tablews->addColumn(
"str",
"ComponentName");
83 tablews->addColumn(type, colname);
101 std::string &errormsg) {
103 std::vector<std::string> colNames = calibws->getColumnNames();
109 std::stringstream errorss;
111 <<
" columns. Input workspace " << calibws->getName() <<
" get " << calibws->getColumnNames().size()
113 errormsg = errorss.str();
118 for (
size_t i = 0; i < colNames.size(); ++i) {
120 std::stringstream errorss;
122 <<
", but instead in TableWorkspace " << calibws->getName() <<
" it is " << colNames[i];
123 errormsg = errorss.str();
145 throw std::runtime_error(
"Single component calibration table workspace is not correct.");
161 std::string errmsg{
""};
164 throw std::runtime_error(errmsg);
183 throw std::runtime_error(
"TableWorkspace contains a single component's "
184 "calibration in various dates");
186 std::vector<std::string> names =
mCalibWS->getColVector<std::string>(0);
200 throw std::runtime_error(
"Calibration workspace has not been set up yet.");
203 size_t row_number =
mCalibWS->rowCount();
204 for (
size_t i = 0; i < row_number; ++i) {
205 if (
mCalibWS->cell<std::string>(i, 0) == component) {
211 if (row_number ==
mCalibWS->rowCount())
212 throw std::runtime_error(
"Specified component does not exist");
216 pos.
x =
mCalibWS->cell<
double>(row_number, 1);
217 pos.
y =
mCalibWS->cell<
double>(row_number, 2);
218 pos.
z =
mCalibWS->cell<
double>(row_number, 3);
241 auto loadAsciiAlg = AlgorithmFactory::Instance().create(
"LoadAscii", 2);
244 throw std::runtime_error(
"Failed to load ASCII as OutputWorkspace name is empty string.");
246 loadAsciiAlg->initialize();
247 loadAsciiAlg->setPropertyValue(
"Filename", filename);
248 loadAsciiAlg->setPropertyValue(
"OutputWorkspace",
tablewsname);
249 loadAsciiAlg->setPropertyValue(
"Separator",
"CSV");
250 loadAsciiAlg->setPropertyValue(
"CommentIndicator",
"#");
251 loadAsciiAlg->execute();
254 std::dynamic_pointer_cast<TableWorkspace>(AnalysisDataService::Instance().retrieve(
tablewsname));
274 const std::string &component,
275 const std::string &filename) {
277 std::string
tablewsname = component +
"_" + datestamp;
282 if (std::filesystem::exists(filename)) {
296 auto saveAsciiAlg = AlgorithmFactory::Instance().create(
"SaveAscii", 2);
297 saveAsciiAlg->initialize();
298 saveAsciiAlg->setProperty(
"InputWorkspace", compcaltable);
299 saveAsciiAlg->setProperty(
"Filename", filename);
300 saveAsciiAlg->setPropertyValue(
"CommentIndicator",
"#");
301 saveAsciiAlg->setPropertyValue(
"Separator",
"CSV");
302 saveAsciiAlg->setProperty(
"ColumnHeader",
true);
303 saveAsciiAlg->setProperty(
"AppendToFile",
306 saveAsciiAlg->execute();
318 auto saveAsciiAlg = AlgorithmFactory::Instance().create(
"SaveAscii", 2);
319 saveAsciiAlg->initialize();
320 saveAsciiAlg->setProperty(
"InputWorkspace",
mCalibWS);
321 saveAsciiAlg->setProperty(
"Filename", filename);
322 saveAsciiAlg->setPropertyValue(
"CommentIndicator",
"#");
323 saveAsciiAlg->setPropertyValue(
"Separator",
"CSV");
324 saveAsciiAlg->setProperty(
"ColumnHeader",
true);
326 saveAsciiAlg->execute();
333 size_t num_rows = componentcaltable->rowCount();
346 pos.
x = componentcaltable->cell<
double>(rownumber, 1);
347 pos.
y = componentcaltable->cell<
double>(rownumber, 2);
348 pos.
z = componentcaltable->cell<
double>(rownumber, 3);
349 pos.
xCosine = componentcaltable->cell<
double>(rownumber, 4);
350 pos.
yCosine = componentcaltable->cell<
double>(rownumber, 5);
351 pos.
zCosine = componentcaltable->cell<
double>(rownumber, 6);
352 pos.
rotAngle = componentcaltable->cell<
double>(rownumber, 7);
365 auto wsValidator = std::make_shared<CompositeValidator>();
371 "Workspace containing the day-stamp of the calibration");
376 "Table workspace containing calibrated positions and "
377 "orientations for a subset of the banks");
381 "The directory that the database (csv) files are saved to");
385 "Table workspace containing calibrated positions and "
386 "orientations for all banks");
391 std::map<std::string, std::string> errors;
401 if (
mInputWS->getInstrument()->getName() !=
"CORELLI")
402 errors[
"InputWorkspace"] =
"This Algorithm will only work for Corelli.";
404 else if (!
mInputWS->run().hasProperty(
"start_time") && !
mInputWS->run().hasProperty(
"run_start"))
405 errors[
"InputWorkspace"] =
"Workspace is missing property start_time.";
410 errors[
"InputCalibrationPatchWorkspace"] =
"Input calibration patch workspace is not specified";
415 std::string error_msg{
""};
420 errors[
"InputCalibrationPatchWorkspace"] = error_msg;
433 throw std::runtime_error(
"input workspace not specified");
435 throw std::runtime_error(
"input calibration workspace not specified");
437 std::string calibDatabaseDir =
getProperty(
"DatabaseDirectory");
442 std::map<std::string, TableWorkspace_sptr> component_caibws_map;
459 for (
const auto &[compname, calibws] : component_caibws_map) {
461 g_log.
debug() <<
"Removing " << compname <<
"calibration table from ADS\n";
462 AnalysisDataService::Instance().remove(calibws->getName());
476 std::map<std::string, TableWorkspace_sptr> &calibwsmap) {
478 std::string timestampstr{
""};
479 if (
mInputWS->run().hasProperty(
"start_time")) {
481 timestampstr =
mInputWS->run().getProperty(
"start_time")->value();
486 timestampstr =
mInputWS->run().getProperty(
"run_start")->value();
498 for (
size_t i = 0; i < num_rows; ++i) {
506 calibwsmap[compname] = comptablews;
507 g_log.
debug() <<
"Component " << compname <<
" is updated to " << compdbname <<
" and saved to "
508 << comptablews->getName() <<
"\n";
518 const std::string &calibdbdir, std::map<std::string, TableWorkspace_sptr> &calibwsmap) {
520 for (
const auto &[componentname, componentcaltable] : calibwsmap) {
522 if (componentcaltable)
530 g_log.
debug() <<
"Component " << componentname <<
": No database file is found at " << compdbname <<
"\n";
536 compdbname, componentname +
"_" +
mDateStamp);
537 calibwsmap[componentname] = loaded_compcalibws;
539 g_log.
debug() <<
"Component " << componentname <<
" is loaded from " << compdbname <<
" and saved to "
540 << loaded_compcalibws->getName() <<
"\n";
547 const std::vector<std::string> &orderedcomponents) {
553 for (
const auto &componentname : orderedcomponents) {
554 const auto componentcaltable = calibwsmap[componentname];
555 if (componentcaltable) {
567 std::string filename =
"corelli_instrument_" +
mDateStamp +
".csv";
568 filename =
joinPath(calibdbdir, filename);
584 std::string date_str = run_start_time.substr(0, run_start_time.find(
"T"));
587 std::string year = date_str.substr(0, date_str.find(
"-"));
588 std::string monthday = date_str.substr(date_str.find(
"-") + 1, date_str.size());
589 std::string month = monthday.substr(0, monthday.find(
"-"));
590 std::string day = monthday.substr(monthday.find(
"-") + 1,
592 std::string datestamp = year + month + day;
609 const std::string &directory) {
612 std::string shortName = componentname;
613 std::string suffix{
"/sixteenpack"};
614 size_t pos = componentname.find(suffix);
615 if (pos != std::string::npos)
616 shortName.erase(pos, suffix.length());
618 std::string basename = shortName +
".csv";
619 std::string filename =
joinPath(directory, basename);
632 const std::string &directory) {
633 std::string basename = datestamp +
".csv";
634 std::string filename =
joinPath(directory, basename);
648 return std::filesystem::exists(filepath);
659 std::filesystem::path dir(directory);
660 std::filesystem::path file(basename);
661 std::filesystem::path fullpath = dir / file;
663 return fullpath.string();
675 std::map<std::string, DataObjects::TableWorkspace_sptr> &compmap) {
677 for (
const auto &compname : componentnames)
678 compmap[compname] =
nullptr;
693 const auto &component_info = ws->componentInfo();
696 std::vector<std::string> componentnames = {
"moderator",
"sample-position"};
699 const size_t num_components = component_info.size();
700 for (
size_t i = 0; i < num_components; ++i) {
701 std::string compname = component_info.name(i);
703 if (compname.compare(0, 4,
"bank") == 0) {
704 componentnames.push_back(compname +
"/sixteenpack");
708 return componentnames;
#define DECLARE_ALGORITHM(classname)
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
@ Directory
to specify a directory that must exist
A validator which checks that a workspace has a valid instrument.
TableRow represents a row in a TableWorkspace.
A property class for workspaces.
CorelliCalibrationDatabase: blablabla TODO.
static bool isFileExist(const std::string &filepath)
Check whether a given file does exist.
void saveCalibrationTable(const std::string &calibdbdir)
std::map< std::string, std::string > validateInputs() override
Method checking errors on ALL the inputs, before execution.
std::string mDateStamp
Date stamp: YYYYMMDD.
void exec() override
Execute the algorithm.
void loadNonCalibratedComponentDatabase(const std::string &calibddir, std::map< std::string, DataObjects::TableWorkspace_sptr > &calibwsmap)
Load data file if necessary and possible: component_caibws_map.
void setComponentMap(const std::vector< std::string > &componentnames, std::map< std::string, DataObjects::TableWorkspace_sptr > &compmap)
Set up a component name - TableWorkspace map for single component calibration.
DataObjects::TableWorkspace_sptr mInputCalibrationTableWS
Input calibration worksapce.
static std::string joinPath(const std::string &directory, const std::string &basename)
Join two string for a new path.
static std::string corelliComponentDatabaseName(const std::string &componentname, const std::string &directory)
get standard component calibration database (CSV) file name
DataObjects::TableWorkspace_sptr mOutputWS
Output calibration worksapce (merged with previous calibrated data)
API::MatrixWorkspace_sptr mInputWS
Input workspace where the calibration is from.
void createOutputCalibrationTable(std::map< std::string, DataObjects::TableWorkspace_sptr > &calibwsmap, const std::vector< std::string > &orderedcomponents)
Create output full set calibration workspace.
void updateComponentDatabaseFiles(const std::string &calibdbdir, std::map< std::string, DataObjects::TableWorkspace_sptr > &calibwsmap)
append the newly calibration to each component csv file
static std::string convertTimeStamp(const std::string &run_start_time)
A static method to convert Mantid datetime string to YYYYMMDD format.
static std::vector< std::string > retrieveInstrumentComponents(const API::MatrixWorkspace_sptr &ws)
Retrieve the bank level components names in order.
static std::string corelliCalibrationDatabaseName(const std::string &datestamp, const std::string &directory)
get standard date-base calibration database (CSV) file name
Class containing static and member methods to work with calibration table workspaces.
DataObjects::TableWorkspace_sptr mCalibWS
ComponentPosition getComponentCalibratedPosition(const std::string &component)
Get the calibration of a component.
static bool isValidCalibrationTableWorkspace(const DataObjects::TableWorkspace_sptr &calibws, std::string &errormsg)
Check whether a TableWorkspace is a valid Corelli geometry calibration table for all components.
static ComponentPosition getLatestCalibratedPosition(const DataObjects::TableWorkspace_sptr &componentcaltable)
Get the last entry (latest update) of a compoent calibrated position.
void setCalibrationTable(const DataObjects::TableWorkspace_sptr &calibws)
Set calibration table file.
static ComponentPosition getCalibratedPosition(const DataObjects::TableWorkspace_sptr &componentcaltable, size_t rownumber)
Get the calibration position in the table (component table or full calibration table)
static DataObjects::TableWorkspace_sptr loadComponentCalibrationTable(const std::string &filename, const std::string &tablewsname)
Load a single-component calibration table.
CalibrationTableHandler()
Constructor.
static DataObjects::TableWorkspace_sptr createCalibrationTableWorkspace(const std::string &wsname, bool iscomponent)
Create a calibration TableWorkspace from scratch for either single component or full set of component...
bool isSingleComponentTable
DataObjects::TableWorkspace_sptr saveCompomentDatabase(const std::string &datestamp, const std::string &component, const std::string &filename)
Save a single component in the calibration workspace.
void saveCalibrationTable(const std::string &filename)
Save the calibration table (of a single date)
static void appendCalibration(const DataObjects::TableWorkspace_sptr &tablews, const std::string &datestamp, const ComponentPosition &pos)
Append a new row to single component calibration table.
std::vector< std::string > getComponentNames()
Get component name from the table.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
static const std::vector< std::string > calibrationTableColumnTypes
static const std::vector< std::string > calibrationTableColumnNames
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
Load a single-component database file to a table workspace of history of positions for the component.
Structure to handle all the calibration component positions.
@ Input
An input workspace.
@ Output
An output workspace.