52 "Name of the output *MDEventWorkspace*.");
55 "By default (\"1\"), existing Output Workspace will be replaced. Select "
56 "false (\"0\") if you want to add new events to the workspace, which "
58 "\nChoosing \"0\" can be very inefficient for file-based workspaces");
61 "It has to be N comma separated values, where N is the "
62 "number of dimensions of the target workspace. Values "
63 "smaller then specified here will not be added to "
64 "workspace.\n Number N is defined by properties 4,6 and 7 "
66 "described on *MD Transformation factory* page. See also "
67 ":ref:`algm-ConvertToMDMinMaxLocal`");
73 "A list of the same size and the same units as MinValues "
74 "list. Values higher or equal to the specified by "
75 "this list will be ignored");
80 this->initBoxControllerProps(
"5" , 1000 , 20 );
82 auto mustBeMoreThan1 = std::make_shared<BoundedValidator<int>>();
83 mustBeMoreThan1->setLower(1);
86 "Optional. If specified, then all the boxes will be split to this "
87 "minimum recursion depth. 0 = no splitting, "
88 "1 = one level of splitting, etc. \n Be careful using this since it can "
89 "quickly create a huge number of :math:`boxes = "
90 "SplitInto^{MinRercursionDepth \\times NumDimensions}`. \n But setting "
91 "this property equal to MaxRecursionDepth "
92 "is necessary if one wants to generate multiple file based "
93 "workspaces in order to merge them later.");
94 setPropertyGroup(
"MinRecursionDepth", getBoxSettingsGroupName());
97 "This option causes a split of the top level, i.e. level0, of 50 for the "
98 "first four dimensions.");
101 "The name of the Nexus file to write, as a full or relative path.\n"
102 "Only used if FileBackEnd is true.");
103 setPropertySettings(
"Filename", std::make_unique<EnabledWhenProperty>(
"FileBackEnd",
IS_EQUAL_TO,
"1"));
105 declareProperty(
"FileBackEnd",
false,
106 "If true, Filename must also be specified. The algorithm "
107 "will create the specified file in addition to an output "
108 "workspace. The workspace will load data from the file on "
109 "demand in order to reduce memory use.");
111 std::vector<std::string> converterType{
"Default",
"Indexed"};
113 auto loadTypeValidator = std::make_shared<StringListValidator>(converterType);
114 declareProperty(
"ConverterType",
"Default", loadTypeValidator,
115 "[Default, Indexed], indexed is the experimental type that "
116 "can speedup the conversion process"
117 "for the big files using the indexing.");
126 std::map<std::string, std::string> result;
128 const std::string treeBuilderType = this->
getProperty(
"ConverterType");
129 const bool topLevelSplittingChecked = this->
getProperty(
"TopLevelSplitting");
130 std::vector<int> split_into = this->
getProperty(
"SplitInto");
131 const std::string filename = this->
getProperty(
"Filename");
132 const bool fileBackEnd = this->
getProperty(
"FileBackEnd");
133 const bool useLogTimes = this->
getProperty(
"UseLogTimes");
135 if (fileBackEnd && filename.empty()) {
136 result[
"Filename"] =
"Filename must be given if FileBackEnd is required.";
139 if (treeBuilderType.find(
"Indexed") != std::string::npos) {
141 result[
"ConverterType"] +=
"No file back end implemented "
142 "for indexed version of algorithm. ";
143 if (topLevelSplittingChecked)
144 result[
"ConverterType"] +=
"The usage of top level splitting is "
145 "not possible for indexed version of algorithm. ";
149 result[
"ConverterType"] +=
"The split parameter should be the same for"
150 " all dimensions and be equal the power of 2"
151 " (2 ,4, 8, 16,..) for indexed version of algorithm. ";
154 std::vector<double> minVals = this->
getProperty(
"MinValues");
155 std::vector<double> maxVals = this->
getProperty(
"MaxValues");
157 if (minVals.size() != maxVals.size()) {
158 std::stringstream msg;
159 msg <<
"Rank of MinValues != MaxValues (" << minVals.size() <<
"!=" << maxVals.size() <<
")";
160 result[
"MinValues"] = msg.str();
161 result[
"MaxValues"] = msg.str();
163 std::stringstream msg;
165 size_t rank = minVals.size();
166 for (
size_t i = 0; i < rank; ++i) {
167 if (minVals[i] >= maxVals[i]) {
168 if (msg.str().empty())
169 msg <<
"max not bigger than min ";
172 msg <<
"at index=" << (i + 1) <<
" (" << minVals[i] <<
">=" << maxVals[i] <<
")";
176 if (!msg.str().empty()) {
177 result[
"MinValues"] = msg.str();
178 result[
"MaxValues"] = msg.str();
184 const auto evWs = std::dynamic_pointer_cast<const DataObjects::EventWorkspace>(inWS);
186 result[
"UseLogTimes"] =
"UseLogTimes requires the input to be an EventWorkspace.";
188 const std::vector<std::string> otherDims =
getProperty(
"OtherDimensions");
189 for (
auto &nameDim : otherDims) {
190 if (!inWS->run().hasProperty(nameDim)) {
191 result[
"UseLogTimes"] =
"Input workspace does not have " + nameDim +
" property in its logs.";
195 result[
"UseLogTimes"] =
"Property " + nameDim +
" is not a time series property, log times can't be used.";
216 const std::string out_filename = this->
getProperty(
"Filename");
217 const bool fileBackEnd = this->
getProperty(
"FileBackEnd");
227 std::string dEModReq =
getProperty(
"dEAnalysisMode");
229 std::vector<std::string> otherDimNames =
getProperty(
"OtherDimensions");
235 std::string convertTo_ =
getProperty(
"QConversionScales");
238 std::vector<double> dimMin =
getProperty(
"MinValues");
239 std::vector<double> dimMax =
getProperty(
"MaxValues");
245 if (QFrame != autoSelect) {
250 if (convertTo_ != noScaling) {
252 convertTo_ = noScaling;
261 bool createNewTargetWs =
265 if (createNewTargetWs)
286 bool ignoreZeros =
getProperty(
"IgnoreZeroSignals");
295 m_Progress = std::make_unique<Progress>(
this, 0.0, 1.0, n_steps);
306 savemd->setProperty(
"InputWorkspace", spws);
307 savemd->setPropertyValue(
"Filename", out_filename);
308 savemd->setProperty(
"UpdateFileBackEnd",
true);
309 savemd->setProperty(
"MakeFileBacked",
false);
310 savemd->executeAsChildAlg();
313 if (
const auto logname =
m_Convertor->getTimeLogsName(); logname.size() > 0) {
314 std::string singlestring;
315 singlestring.reserve(2 * logname.size());
316 for (
auto string : logname) {
317 singlestring.append(
string).append(1,
',');
319 singlestring.pop_back();
320 spws->getExperimentInfo(0)->mutableRun().addProperty(
"useLogTimes", singlestring,
true);
324 setProperty(
"OutputWorkspace", std::dynamic_pointer_cast<IMDEventWorkspace>(spws));
344 ei->mutableRun().addProperty(
"W_MATRIX", targWSDescr.
getPropertyValueAsType<std::vector<double>>(
"W_MATRIX"),
true);
349 uint16_t expInfoIndex = mdEventWS->addExperimentInfo(ei);
353 targWSDescr.
addProperty(
"EXP_INFO_INDEX", expInfoIndex,
true);
366 size_t spectra_index(0);
367 bool detector_found(
false);
368 const auto &spectrumInfo =
m_InWS2D->spectrumInfo();
369 for (
size_t i = 0; i <
m_InWS2D->getNumberHistograms(); ++i) {
370 if (spectrumInfo.hasDetectors(i) && !spectrumInfo.isMonitor(i)) {
372 detector_found =
true;
374 <<
" as the source of the bin "
375 "boundaries for the resolution corrections \n";
379 if (!detector_found) {
380 g_log.
information() <<
"No spectra in the workspace have detectors associated "
381 "with them. Storing bin boundaries from first spectrum for"
382 "resolution calculation\n";
386 auto binBoundaries =
m_InWS2D->x(spectra_index);
389 if (
m_Convertor->getUnitConversionHelper().isUnitConverted()) {
393 "the bin boundaries are copied from the first "
394 "workspace spectra. The resolution estimates can "
395 "be incorrect if unit conversion depends on "
400 std::transform(binBoundaries.cbegin(), binBoundaries.cend(), binBoundaries.begin(),
401 [&unitConv](
const auto &binBoundary) { return unitConv.convertUnits(binBoundary); });
404 if (binBoundaries[0] > binBoundaries.back()) {
406 "Sorting performed\n";
407 std::sort(binBoundaries.begin(), binBoundaries.end());
414 uint16_t nexpts = mdEventWS->getNumExperimentInfo();
416 ExperimentInfo_sptr expt = mdEventWS->getExperimentInfo(
static_cast<uint16_t
>(nexpts - 1));
417 expt->mutableRun().storeHistogramBinBoundaries(binBoundaries.rawData());
441 const std::string &dEModReq,
const std::vector<std::string> &otherDimNames,
442 std::vector<double> &dimMin, std::vector<double> &dimMax,
443 const std::string &QFrame,
const std::string &convertTo_,
447 std::vector<int> split_into;
449 if (createNewTargetWs) {
453 this->
findMinMax(
m_InWS2D, QModReq, dEModReq, QFrame, convertTo_, otherDimNames, dimMin, dimMax);
459 size_t NDims = spws->getNumDims();
460 dimMin.resize(NDims);
461 dimMax.resize(NDims);
462 split_into.resize(NDims);
463 for (
size_t i = 0; i < NDims; i++) {
468 split_into[i] =
static_cast<int>(pDim->
getNBins());
478 bool LorentzCorrections =
getProperty(
"LorentzCorrection");
491 }
catch (std::invalid_argument &) {
492 g_log.
warning() <<
"The projections are coplanar. Will use defaults "
493 "[1,0,0],[0,1,0] and [0,0,1]\n";
496 auto warnIfSet = [
this](
const std::string &propName) {
502 for (
const auto &
name : {
"UProj",
"VProj",
"WProj"}) {
507 if (createNewTargetWs) {
531 targWSDescr = oldWSDescr;
533 return createNewTargetWs;
545 const bool filebackend,
const std::string &filename) {
550 g_log.
error() <<
"can not create target event workspace with :" << targWSDescr.
nDimensions() <<
" dimensions\n";
551 throw(std::invalid_argument(
"can not create target workspace"));
563 bool topLevelSplittingChecked = this->
getProperty(
"TopLevelSplitting");
565 if (topLevelSplittingChecked) {
574 int minDepth = this->
getProperty(
"MinRecursionDepth");
575 int maxDepth = this->
getProperty(
"MaxRecursionDepth");
576 if (minDepth > maxDepth)
577 throw std::invalid_argument(
"MinRecursionDepth must be >= MaxRecursionDepth ");
578 spws->setMinRecursionDepth(
size_t(minDepth));
589 const size_t topLevelSplitSetting = 50;
590 const size_t dimCutoff = 4;
593 for (
size_t dim = 0; dim < bc->getNDims(); dim++) {
594 if (dim < dimCutoff) {
595 bc->setSplitTopInto(dim, topLevelSplitSetting);
597 bc->setSplitTopInto(dim, bc->getSplitInto(dim));
611 bool createNewWs(
false);
615 bool shouldOverwrite =
getProperty(
"OverwriteExisting");
616 createNewWs = shouldOverwrite;
639 const std::string &dEMode,
const std::string &QFrame,
const std::string &ConvertTo,
640 const std::vector<std::string> &otherDim, std::vector<double> &minVal,
641 std::vector<double> &maxVal) {
652 size_t nDim = nMatrixDim + otherDim.size();
656 bool wellDefined(
true);
657 if ((nDim == minVal.size()) && (minVal.size() == maxVal.size())) {
659 for (
size_t i = 0; i < minVal.size(); i++) {
660 if (minVal[i] >= maxVal[i])
662 g_log.
information() <<
" Min Value: " << minVal[i] <<
" for dimension N: " << i
663 <<
" equal or exceeds max value:" << maxVal[i] <<
'\n';
676 throw(std::runtime_error(
"Can not create child ChildAlgorithm to found min/max values"));
678 childAlg->setProperty(
"InputWorkspace", inWS);
679 childAlg->setProperty(
"QDimensions", QMode);
680 childAlg->setProperty(
"dEAnalysisMode", dEMode);
681 childAlg->setProperty(
"Q3DFrames", QFrame);
682 childAlg->setProperty(
"OtherDimensions", otherDim);
683 childAlg->setProperty(
"QConversionScales", ConvertTo);
684 childAlg->setProperty(
"PreprocDetectorsWS", std::string(
getProperty(
"PreprocDetectorsWS")));
686 if (!childAlg->isExecuted())
687 throw(std::runtime_error(
"Can not properly execute child algorithm to find "
688 "min/max workspace values"));
690 minVal = childAlg->getProperty(
"MinValues");
691 maxVal = childAlg->getProperty(
"MaxValues");
695 for (
unsigned int i = 0; i < nDim; i++) {
696 if (minVal[i] >= maxVal[i]) {
697 g_log.
debug() <<
"identified min-max values for dimension N: " << i
698 <<
" are equal. Modifying min-max value to produce "
699 "dimension with 0.2*dimValue width\n";
703 }
else if (minVal[i] == 0) {
720 std::vector<double> minAlgValues = this->
getProperty(
"MinValues");
721 std::vector<double> maxAlgValues = this->
getProperty(
"MaxValues");
722 bool allMinDefined = (minAlgValues.size() == nDim);
723 bool allMaxDefined = (maxAlgValues.size() == nDim);
724 if (allMinDefined || allMaxDefined) {
725 for (
size_t i = 0; i < nDim; i++) {
727 minVal[i] = minAlgValues[i];
729 maxVal[i] = maxAlgValues[i];
744 savemd->setProperty(
"InputWorkspace", outputWS);
745 savemd->setPropertyValue(
"Filename", filebackPath);
746 savemd->setProperty(
"UpdateFileBackEnd",
false);
747 savemd->setProperty(
"MakeFileBacked",
false);
748 savemd->executeAsChildAlg();
751 auto boxControllerMem = outputWS->getBoxController();
752 auto boxControllerIO = std::make_shared<BoxControllerNeXusIO>(boxControllerMem.get());
753 boxControllerMem->setFileBacked(boxControllerIO, filebackPath);
754 outputWS->setFileBacked();
755 boxControllerMem->getFileIO()->setWriteBufferSize(1000000);
#define DECLARE_ALGORITHM(classname)
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 setBoxController(const Mantid::API::BoxController_sptr &bc, const Mantid::Geometry::Instrument_const_sptr &instrument)
Set the settings in the given box controller.
@ OptionalSave
to specify a file to write to but an empty string is
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
HeldType getPropertyValueAsType(const std::string &name) const
Get the value of a property as the given TYPE.
A property class for workspaces.
The class responsible for saving events into nexus file using generic box controller interface Expect...
This class is intended to fulfill the design specified in <https://github.com/mantidproject/documents...
The class describes one dimension of multidimensional dataset representing an orthogonal dimension an...
virtual coord_t getMaximum() const =0
virtual coord_t getMinimum() const =0
virtual size_t getNBins() const =0
MDHistoDimensionBuilder :
static void resizeToFitMDBox(CoordT &min, CoordT &max)
Push the min/max values out by a defined amount.
Support for a property that holds an array of values.
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.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
std::vector< T > getVector() const
The concrete, templated class for properties.
Base class for properties.
virtual bool isDefault() const =0
Overriden function that returns if property has the same value that it was initialised with,...
A specialised Property class for holding a series of time-value pairs.
static bool isSplitValid(const std::vector< T > &split_into)
small class to select proper solver as function of the workspace kind and (possibly,...
std::shared_ptr< ConvToMDBase > convSelector(const API::MatrixWorkspace_sptr &inputWS, std::shared_ptr< ConvToMDBase > ¤tSolver) const
function which selects the convertor depending on workspace type and (possibly, in a future) some wor...
std::shared_ptr< MDAlgorithms::ConvToMDBase > m_Convertor
pointer to the class, which does the particular conversion
DataObjects::TableWorkspace_const_sptr preprocessDetectorsPositions(const Mantid::API::MatrixWorkspace_const_sptr &InWS2D, const std::string &dEModeRequested, bool updateMasks, const std::string &OutWSName)
The method responsible for analyzing input workspace parameters and preprocessing detectors positions...
void init() override
Initialize the algorithm's properties.
ConvertToMD : Transform a workspace into MD workspace with components defined by user.
int version() const override
Algorithm's version for identification.
void findMinMax(const Mantid::API::MatrixWorkspace_sptr &inWS, const std::string &QMode, const std::string &dEMode, const std::string &QFrame, const std::string &ConvertTo, const std::vector< std::string > &otherDim, std::vector< double > &minVal, std::vector< double > &maxVal)
Method takes min-max values from algorithm parameters if they are present or calculates default min-m...
bool doWeNeedNewTargetWorkspace(const API::IMDEventWorkspace_sptr &spws)
Check if target workspace new or existing one and we need to create new workspace.
Mantid::API::MatrixWorkspace_sptr m_InWS2D
pointer to the input workspace;
void setupFileBackend(const std::string &filebackPath, const API::IMDEventWorkspace_sptr &outputWS)
Setup the filebackend for the output workspace.
void addExperimentInfo(API::IMDEventWorkspace_sptr &mdEventWS, MDAlgorithms::MDWSDescription &targWSDescr) const
par of store metadata routine which generate metadata necessary for initializing ConvertToMD plugin
const std::string name() const override
Algorithm's name for identification.
std::shared_ptr< MDAlgorithms::MDEventWSWrapper > m_OutWSWrapper
std::unique_ptr< API::Progress > m_Progress
progress reporter
void copyMetaData(API::IMDEventWorkspace_sptr &mdEventWS) const
Store metadata and set some metadata, needed for plugin to run on the target workspace description.
void exec() override
Virtual method - must be overridden by concrete algorithm.
void setupTopLevelSplitting(const Mantid::API::BoxController_sptr &bc)
Sets up the top level splitting, i.e. of level 0, for the box controller.
API::IMDEventWorkspace_sptr createNewMDWorkspace(const MDAlgorithms::MDWSDescription &targWSDescr, const bool filebackend, const std::string &filename)
Create new MD workspace using existing parameters for algorithm.
std::map< std::string, std::string > validateInputs() override
Perform validation of ALL the input properties of the algorithm.
bool buildTargetWSDescription(const API::IMDEventWorkspace_sptr &spws, const std::string &QModReq, const std::string &dEModReq, const std::vector< std::string > &otherDimNames, std::vector< double > &dimMin, std::vector< double > &dimMax, const std::string &QFrame, const std::string &convertTo_, MDAlgorithms::MDWSDescription &targWSDescr)
handle the input parameters and build target workspace description as function of input parameters
Interface to set of sub-classes used by ConvertToMD algorithm and responsible for conversion of input...
virtual unsigned int getNMatrixDimensions(Kernel::DeltaEMode::Type mode, API::MatrixWorkspace_const_sptr inWS) const =0
return the number of dimensions, calculated by the transformation from the workspace.
Class responsible for conversion of input workspace data into proper number of output dimensions for ...
helper class describes the properties of target MD workspace, which should be obtained as the result ...
void setMinMax(const std::vector< double > &minVal, const std::vector< double > &maxVal)
function sets up min-max values to the dimensions, described by the class
bool m_buildingNewWorkspace
void setUpMissingParameters(const MDWSDescription &SourceMatrWS)
copy some parameters from the input workspace, as target md WS do not have all information about the ...
void setNumBins(const std::vector< int > &nBins_toSplit)
sets number of bins each dimension is split
void buildFromMDWS(const API::IMDEventWorkspace_const_sptr &pWS)
method builds MD Event description from existing MD event workspace
void buildFromMatrixWS(const API::MatrixWorkspace_sptr &pWS, const std::string &QMode, const std::string &dEMode, const std::vector< std::string > &dimPropertyNames=std::vector< std::string >())
method builds MD Event ws description from a matrix workspace and the transformations,...
unsigned int nDimensions() const
void setAbsMin(double absMin)
Kernel::DblMatrix m_Wtransf
std::vector< double > m_RotMatrix
DataObjects::TableWorkspace_const_sptr m_PreprDetTable
void setLorentsCorr(bool On=false)
do we need to perform Lorentz corrections
void checkWSCorresponsMDWorkspace(const MDWSDescription &NewMDWorkspaceD)
compare two descriptions and select the complimentary result.
void updateConversion(size_t i)
Method updates unit conversion given the index of detector parameters in the array of detectors.
std::shared_ptr< IMDEventWorkspace > IMDEventWorkspace_sptr
Shared pointer to Mantid::API::IMDEventWorkspace.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< ExperimentInfo > ExperimentInfo_sptr
Shared pointer to ExperimentInfo.
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< BoxController > BoxController_sptr
Shared ptr to BoxController.
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
static Type fromString(const std::string &modeStr)
Returns the emode from the given string.
@ Input
An input workspace.
@ Output
An output workspace.