12#include "Poco/NumberFormatter.h"
19using namespace Kernel;
21using namespace Geometry;
24 auto wsValidator = std::make_shared<WorkspaceUnitValidator>(
"Wavelength");
26 "Workspace to calculate I(qx,qy) from");
29 declareProperty(
"IQxQyLogBinning",
false,
"I(qx,qy) log binning when binning is not specified.",
38 return inputWS->run().getPropertyValueAsType<
double>(pname);
44 progress.report(
"Setting up I(qx,Qy) calculation");
52 if (outputWSName.empty()) {
53 outputWSName = inputWS->getName();
58 bool frame_skipping =
false;
59 const auto &run = inputWS->run();
60 if (run.hasProperty(
"is_frame_skipping")) {
61 auto prop = run.getProperty(
"is_frame_skipping");
62 const auto &typeInfo = *(prop->type_info());
63 if (typeInfo ==
typeid(int64_t)) {
64 frame_skipping = (run.getPropertyValueAsType<int64_t>(
"is_frame_skipping") == 1);
65 }
else if (typeInfo ==
typeid(int32_t)) {
66 frame_skipping = (run.getPropertyValueAsType<int32_t>(
"is_frame_skipping") == 1);
68 g_log.
warning() <<
"Unknown property type for is_frame_skipping\n";
73 double wavelength_min = 0.0;
74 if (inputWS->run().hasProperty(
"wavelength_min"))
76 else if (inputWS->dataX(0).size() > 1)
77 wavelength_min = (inputWS->dataX(1)[0] + inputWS->dataX(1)[1]) / 2.0;
78 else if (inputWS->dataX(0).size() == 1)
79 wavelength_min = inputWS->dataX(1)[0];
81 g_log.
error(
"Can't determine the minimum wavelength for the input workspace.");
82 throw std::invalid_argument(
"Can't determine the minimum wavelength for the input workspace.");
86 if (inputWS->run().hasProperty(
"qmax")) {
88 g_log.
debug() <<
"Using Qmax from run properties = " << qmax << std::endl;
92 const double sample_detector_distance =
getRunProperty(inputWS,
"sample_detector_distance");
94 const double nx_pixels = inputWS->getInstrument()->getNumberParameter(
"number-of-x-pixels")[0];
95 const double ny_pixels = inputWS->getInstrument()->getNumberParameter(
"number-of-y-pixels")[0];
96 const double pixel_size_x = inputWS->getInstrument()->getNumberParameter(
"x-pixel-size")[0];
97 const double pixel_size_y = inputWS->getInstrument()->getNumberParameter(
"y-pixel-size")[0];
99 const double beam_ctr_x =
getRunProperty(inputWS,
"beam_center_x");
100 const double beam_ctr_y =
getRunProperty(inputWS,
"beam_center_y");
102 double dxmax = pixel_size_x * std::max(beam_ctr_x, nx_pixels - beam_ctr_x);
103 double dymax = pixel_size_y * std::max(beam_ctr_y, ny_pixels - beam_ctr_y);
104 double maxdist = std::max(dxmax, dymax);
108 qmax = 4 * M_PI / wavelength_min * std::sin(0.5 * std::atan(maxdist / sample_detector_distance));
109 g_log.
debug() <<
"Using calculated Qmax = " << qmax << std::endl;
112 if (frame_skipping) {
114 const double wavelength_max =
getRunProperty(inputWS,
"wavelength_max");
115 const double wavelength_min_f2 =
getRunProperty(inputWS,
"wavelength_min_frame2");
116 const double wavelength_max_f2 =
getRunProperty(inputWS,
"wavelength_max_frame2");
120 Poco::NumberFormatter::format(wavelength_min, 2) +
",0.1," + Poco::NumberFormatter::format(wavelength_max, 2);
123 rebinAlg->setPropertyValue(
"Params", params);
124 rebinAlg->setProperty(
"PreserveEvents",
false);
125 rebinAlg->executeAsChildAlg();
127 const bool log_binning =
getProperty(
"IQxQyLogBinning");
129 qxyAlg->setProperty<
MatrixWorkspace_sptr>(
"InputWorkspace", rebinAlg->getProperty(
"OutputWorkspace"));
130 qxyAlg->setProperty<
double>(
"MaxQxy", qmax);
131 qxyAlg->setProperty<
double>(
"DeltaQ", qmax / nbins);
132 qxyAlg->setProperty<
bool>(
"SolidAngleWeighting",
false);
133 qxyAlg->setProperty<
bool>(
"IQxQyLogBinning", log_binning);
134 qxyAlg->executeAsChildAlg();
139 replaceAlg->setProperty<
double>(
"NaNValue", 0.0);
140 replaceAlg->setProperty<
double>(
"NaNError", 0.0);
141 replaceAlg->executeAsChildAlg();
143 std::string outputWSName_frame = outputWSName +
"_frame1_Iqxy";
150 params = Poco::NumberFormatter::format(wavelength_min_f2, 2) +
",0.1," +
151 Poco::NumberFormatter::format(wavelength_max_f2, 2);
154 rebinAlg->setPropertyValue(
"Params", params);
155 rebinAlg->setProperty(
"PreserveEvents",
false);
156 rebinAlg->executeAsChildAlg();
159 qxyAlg->setProperty<
MatrixWorkspace_sptr>(
"InputWorkspace", rebinAlg->getProperty(
"OutputWorkspace"));
160 qxyAlg->setProperty<
double>(
"MaxQxy", qmax);
161 qxyAlg->setProperty<
double>(
"DeltaQ", qmax / nbins);
162 qxyAlg->setProperty<
bool>(
"SolidAngleWeighting",
false);
163 qxyAlg->setProperty<
bool>(
"IQxQyLogBinning", log_binning);
164 qxyAlg->executeAsChildAlg();
166 qxy_output = qxyAlg->getProperty(
"OutputWorkspace");
169 replaceAlg->setProperty<
double>(
"NaNValue", 0.0);
170 replaceAlg->setProperty<
double>(
"NaNError", 0.0);
171 replaceAlg->executeAsChildAlg();
173 outputWSName_frame = outputWSName +
"_frame2_Iqxy";
176 result = replaceAlg->getProperty(
"OutputWorkspace");
178 setProperty(
"OutputMessage",
"I(Qx,Qy) computed for each frame");
181 const bool log_binning =
getProperty(
"IQxQyLogBinning");
184 qxyAlg->setProperty<
double>(
"MaxQxy", qmax);
185 qxyAlg->setProperty<
double>(
"DeltaQ", qmax / nbins);
186 qxyAlg->setProperty<
bool>(
"SolidAngleWeighting",
false);
187 qxyAlg->setProperty<
bool>(
"IQxQyLogBinning", log_binning);
188 qxyAlg->executeAsChildAlg();
193 replaceAlg->setProperty<
double>(
"NaNValue", 0.0);
194 replaceAlg->setProperty<
double>(
"NaNError", 0.0);
195 replaceAlg->executeAsChildAlg();
197 outputWSName +=
"_Iqxy";
201 setProperty(
"OutputMessage",
"I(Qx,Qy) computed for each frame");
#define DECLARE_ALGORITHM(classname)
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.
Helper class for reporting progress from algorithms.
A property class for workspaces.
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 init() override
Initialisation code.
void exec() override
Execution code.
std::shared_ptr< MatrixWorkspace > MatrixWorkspace_sptr
shared pointer to the matrix workspace base class
double getRunProperty(const MatrixWorkspace_sptr &inputWS, const std::string &pname)
Returns the value of a run property from a given workspace.
@ Input
An input workspace.
@ Output
An output workspace.