27bool isOne(
int i) {
return (i == 1); }
31using namespace Kernel;
33using namespace DataObjects;
58 "Input workspace loaded from file (e.g. by LoadMuonNexus)");
60 std::vector<std::string> allowedModes{
"CorrectAndGroup",
"Analyse",
"Combined"};
61 auto modeVal = std::make_shared<CompositeValidator>();
62 modeVal->add(std::make_shared<StringListValidator>(allowedModes));
64 declareProperty(
"Mode",
"Combined", modeVal,
65 "Mode to run in. CorrectAndGroup applies dead time "
66 "correction and grouping; Analyse changes bin offset, "
67 "crops, rebins and calculates asymmetry; Combined does all "
71 "Comma-separated list of periods to be summed");
74 "Comma-separated list of periods to be subtracted from the "
77 declareProperty(
"ApplyDeadTimeCorrection",
false,
78 "Whether dead time correction should be applied to loaded workspace");
81 "Table with dead time information, e.g. from LoadMuonNexus."
82 "Must be specified if ApplyDeadTimeCorrection is set true.");
85 "Table with detector grouping information, e.g. from LoadMuonNexus.");
87 declareProperty(
"TimeZero",
EMPTY_DBL(),
"Value used for Time Zero correction");
89 "Time Zero value loaded from file, e.g. from LoadMuonNexus.");
91 "Params used for rebinning. If empty - rebinning is not done.");
92 declareProperty(
"Xmin",
EMPTY_DBL(),
"Minimal X value to include");
93 declareProperty(
"Xmax",
EMPTY_DBL(),
"Maximal X value to include");
95 std::vector<std::string> allowedTypes{
"PairAsymmetry",
"GroupAsymmetry",
"GroupCounts"};
96 declareProperty(
"OutputType",
"PairAsymmetry", std::make_shared<StringListValidator>(allowedTypes),
97 "What kind of workspace required for analysis.");
99 declareProperty(
"PairFirstIndex",
EMPTY_INT(),
"Workspace index of the first pair group");
100 declareProperty(
"PairSecondIndex",
EMPTY_INT(),
"Workspace index of the second pair group");
101 declareProperty(
"Alpha", 1.0,
"Alpha value of the pair");
103 declareProperty(
"GroupIndex",
EMPTY_INT(),
"Workspace index of the group");
106 "An output workspace.");
108 declareProperty(
"CropWorkspace",
true,
109 "Determines if the input workspace "
110 "should be cropped at Xmax, Xmin is "
113 declareProperty(
"WorkspaceName",
"",
"The name of the input workspace");
121 Progress progress(
this, 0.0, 1.0, 5);
126 std::vector<int> summedPeriods =
getProperty(
"SummedPeriodSet");
127 std::vector<int> subtractedPeriods =
getProperty(
"SubtractedPeriodSet");
128 auto allPeriodsWS = std::make_shared<WorkspaceGroup>();
132 if (
auto ws = std::dynamic_pointer_cast<MatrixWorkspace>(inputWS)) {
133 allPeriodsWS->addWorkspace(ws);
136 else if (
auto group = std::dynamic_pointer_cast<WorkspaceGroup>(inputWS)) {
137 allPeriodsWS = group;
146 if (mode !=
"Analyse") {
147 bool applyDtc =
getProperty(
"ApplyDeadTimeCorrection");
151 allPeriodsWS =
applyDTC(allPeriodsWS, deadTimes);
166 if (mode !=
"CorrectAndGroup") {
168 double loadedTimeZero =
getProperty(
"LoadedTimeZero");
172 std::string outputType =
getProperty(
"OutputType");
174 std::unique_ptr<IMuonAsymmetryCalculator> asymCalc;
175 if (outputType ==
"GroupCounts") {
177 std::make_unique<MuonGroupCountsCalculator>(allPeriodsWS, summedPeriods, subtractedPeriods, groupIndex);
178 }
else if (outputType ==
"GroupAsymmetry") {
179 asymCalc = std::make_unique<MuonGroupAsymmetryCalculator>(allPeriodsWS, summedPeriods, subtractedPeriods,
182 }
else if (outputType ==
"PairAsymmetry") {
186 asymCalc = std::make_unique<MuonPairAsymmetryCalculator>(allPeriodsWS, summedPeriods, subtractedPeriods, first,
190 outWS = asymCalc->calculate();
193 setProperty(
"OutputWorkspace", outWS);
206 for (
int i = 0; i < wsGroup->getNumberOfEntries(); i++) {
207 auto ws = std::dynamic_pointer_cast<MatrixWorkspace>(wsGroup->getItem(i));
211 group->setProperty(
"InputWorkspace", ws);
212 group->setProperty(
"DetectorGroupingTable", grouping);
214 result = group->getProperty(
"OutputWorkspace");
215 outWS->addWorkspace(result);
229 for (
int i = 0; i < wsGroup->getNumberOfEntries(); i++) {
230 auto ws = std::dynamic_pointer_cast<MatrixWorkspace>(wsGroup->getItem(i));
234 dtc->setProperty(
"InputWorkspace", ws);
235 dtc->setProperty(
"DeadTimeTable", dt);
237 result = dtc->getProperty(
"OutputWorkspace");
239 outWS->addWorkspace(result);
241 throw std::runtime_error(
"ApplyDeadTimeCorr failed to apply dead time "
242 "correction in MuonProcess");
259 for (
int i = 0; i < wsGroup->getNumberOfEntries(); i++) {
260 auto ws = std::dynamic_pointer_cast<MatrixWorkspace>(wsGroup->getItem(i));
264 outWS->addWorkspace(result);
281 double offset = loadedTimeZero - timeZero;
284 changeOffset->setProperty(
"InputWorkspace", ws);
285 changeOffset->setProperty(
"Offset", offset);
286 changeOffset->execute();
288 ws = changeOffset->getProperty(
"OutputWorkspace");
295 crop->setProperty(
"InputWorkspace", ws);
298 crop->setProperty(
"Xmin", Xmin);
302 crop->setProperty(
"Xmax", Xmax);
306 ws = crop->getProperty(
"OutputWorkspace");
310 std::vector<double> rebinParams =
getProperty(
"RebinParams");
311 if (!rebinParams.empty()) {
313 rebin->setProperty(
"InputWorkspace", ws);
314 rebin->setProperty(
"Params", rebinParams);
315 rebin->setProperty(
"FullBinsOnly",
true);
318 ws = rebin->getProperty(
"OutputWorkspace");
335 std::map<std::string, std::string> errors;
338 const std::string propInputWS(
"InputWorkspace"), propSummedPeriodSet(
"SummedPeriodSet"),
339 propSubtractedPeriodSet(
"SubtractedPeriodSet");
341 std::vector<int> summedPeriods =
getProperty(propSummedPeriodSet);
342 std::vector<int> subtractedPeriods =
getProperty(propSubtractedPeriodSet);
345 if (
auto ws = std::dynamic_pointer_cast<MatrixWorkspace>(inputWS)) {
346 if (std::find_if_not(summedPeriods.begin(), summedPeriods.end(), isOne) != summedPeriods.end()) {
347 errors[propSummedPeriodSet] =
"Single period data but set of periods to "
348 "sum contains invalid values.";
350 if (!subtractedPeriods.empty()) {
351 errors[propSubtractedPeriodSet] =
"Single period data but second set of periods specified";
355 auto group = std::dynamic_pointer_cast<WorkspaceGroup>(inputWS);
356 if (group ==
nullptr) {
357 errors[propInputWS] =
"Input workspace is of invalid type";
359 auto numPeriods = group->getNumberOfEntries();
360 if (numPeriods < 1) {
361 errors[propInputWS] =
"Input workspace contains no periods";
364 std::vector<int> invalidPeriods;
365 std::copy_if(summedPeriods.cbegin(), summedPeriods.cend(), std::back_inserter(invalidPeriods),
366 [numPeriods](
auto period) { return period < 1 || period > numPeriods; });
367 if (!invalidPeriods.empty()) {
369 invalidPeriods.clear();
372 std::copy_if(subtractedPeriods.cbegin(), subtractedPeriods.cend(), std::back_inserter(invalidPeriods),
373 [numPeriods](
auto period) { return period < 1 || period > numPeriods; });
374 if (!invalidPeriods.empty()) {
381 const std::string propMode(
"Mode"), propApplyDTC(
"ApplyDeadTimeCorrection"), propDeadTime(
"DeadTimeTable"),
382 propDetGroup(
"DetectorGroupingTable");
385 if (mode !=
"CorrectAndGroup") {
386 if (summedPeriods.empty()) {
387 errors[propSummedPeriodSet] =
"Cannot analyse: list of periods to sum was empty";
391 if (mode !=
"Analyse") {
393 if (grouping ==
nullptr) {
394 errors[propDetGroup] =
"No detector grouping table supplied";
402 errors[propDeadTime] =
"Cannot apply dead time correction as no dead times were supplied";
415 std::stringstream message;
416 message <<
"Invalid periods specified: ";
417 for (
auto it = invalidPeriods.begin(); it != invalidPeriods.end(); it++) {
419 if (it != invalidPeriods.end() - 1) {
423 return message.str();
#define DECLARE_ALGORITHM(classname)
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) override
Create a Child Algorithm.
Kernel::IPropertyManager::TypedValue getProperty(const std::string &name) const override
Get the property held by this object.
Helper class for reporting progress from algorithms.
A property class for workspaces.
Support for a property that holds an array of values.
Validator to check that a property is not left empty.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
MuonProcess : Processes and analyses Muon workspace.
API::MatrixWorkspace_sptr correctWorkspace(API::MatrixWorkspace_sptr ws, double loadedTimeZero)
Applies offset, crops and rebin the workspace according to specified params.
std::map< std::string, std::string > validateInputs() override
Perform validation of inputs to the algorithm.
API::WorkspaceGroup_sptr applyDTC(const API::WorkspaceGroup_sptr &wsGroup, const DataObjects::TableWorkspace_sptr &dt)
Applies dead time correction to the workspace group.
std::string buildErrorString(const std::vector< int > &invalidPeriods) const
Builds an error message from a list of invalid periods.
API::WorkspaceGroup_sptr correctWorkspaces(const API::WorkspaceGroup_sptr &wsGroup, double loadedTimeZero)
Applies offset, crops and rebins all workspaces in the group.
const std::string category() const override
Algorithm's category for identification.
int version() const override
Algorithm's version for identification.
void exec() override
Execute the algorithm.
API::WorkspaceGroup_sptr groupWorkspaces(const API::WorkspaceGroup_sptr &wsGroup, const DataObjects::TableWorkspace_sptr &grouping)
Groups specified workspace group according to specified DetectorGroupingTable.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
constexpr int EMPTY_INT() noexcept
Returns what we consider an "empty" integer within a property.
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
@ Input
An input workspace.
@ Output
An output workspace.