58 std::map<std::string, std::string> result;
61 std::stringstream inputWSmsg;
62 if (inputWS->getNumDims() != 3) {
63 inputWSmsg <<
"Incorrect number of dimensions";
64 }
else if (inputWS->getDimension(0)->getName() !=
"y" || inputWS->getDimension(1)->getName() !=
"x" ||
65 inputWS->getDimension(2)->getName() !=
"scanIndex") {
66 inputWSmsg <<
"Wrong dimensions";
67 }
else if (inputWS->getNumExperimentInfo() == 0) {
68 inputWSmsg <<
"Missing experiment info";
69 }
else if (inputWS->getExperimentInfo(0)->getInstrument()->getName() !=
"HB3A" &&
70 inputWS->getExperimentInfo(0)->getInstrument()->getName() !=
"WAND") {
71 inputWSmsg <<
"This only works for DEMAND (HB3A) or WAND (HB2C)";
72 }
else if (inputWS->getDimension(2)->getNBins() != inputWS->getExperimentInfo(0)->run().getNumGoniometers()) {
73 inputWSmsg <<
"goniometers not set correctly, did you run SetGoniometer "
76 std::string instrument = inputWS->getExperimentInfo(0)->getInstrument()->getName();
77 const auto run = inputWS->getExperimentInfo(0)->run();
78 size_t number_of_runs = inputWS->getDimension(2)->getNBins();
79 std::vector<std::string> logs;
80 if (instrument ==
"HB3A")
81 logs = {
"monitor",
"time"};
83 logs = {
"duration",
"monitor_count"};
84 for (
auto log : logs) {
85 if (run.hasProperty(log)) {
86 if (
static_cast<size_t>(run.getLogData(log)->size()) != number_of_runs)
87 inputWSmsg <<
"Log " << log <<
" has incorrect length, ";
89 inputWSmsg <<
"Missing required log " << log <<
", ";
93 if (!inputWSmsg.str().empty())
94 result[
"InputWorkspace"] = inputWSmsg.str();
96 std::vector<double> minVals = this->
getProperty(
"MinValues");
97 std::vector<double> maxVals = this->
getProperty(
"MaxValues");
99 if (minVals.size() != 3 || maxVals.size() != 3) {
100 std::stringstream msg;
101 msg <<
"Must provide 3 values, 1 for every dimension";
102 result[
"MinValues"] = msg.str();
103 result[
"MaxValues"] = msg.str();
105 std::stringstream msg;
107 size_t rank = minVals.size();
108 for (
size_t i = 0; i < rank; ++i) {
109 if (minVals[i] >= maxVals[i]) {
110 if (msg.str().empty())
111 msg <<
"max not bigger than min ";
114 msg <<
"at index=" << (i + 1) <<
" (" << minVals[i] <<
">=" << maxVals[i] <<
")";
118 if (!msg.str().empty()) {
119 result[
"MinValues"] = msg.str();
120 result[
"MaxValues"] = msg.str();
163 double wavelength = this->
getProperty(
"Wavelength");
167 auto &expInfo = *(inputWS->getExperimentInfo(
static_cast<uint16_t
>(0)));
168 std::string instrument = expInfo.getInstrument()->getName();
170 std::vector<double> twotheta, azimuthal;
171 std::vector<int> detectorID;
172 if (instrument ==
"HB3A" && !expInfo.run().hasProperty(
"azimuthal")) {
173 const auto &di = expInfo.detectorInfo();
174 for (
size_t x = 0;
x < 512;
x++) {
175 for (
size_t y = 0;
y < 512 * 3;
y++) {
176 size_t n =
x +
y * 512;
177 if (!di.isMonitor(
n)) {
178 twotheta.push_back(di.twoTheta(
n));
179 azimuthal.push_back(di.azimuthal(
n));
180 detectorID.push_back(
static_cast<int>(1 +
n));
187 if (expInfo.run().hasProperty(
"detectorID")) {
191 detectorID.assign(azimuthal.size(), 0);
197 std::vector<double> minVals = this->
getProperty(
"MinValues");
198 std::vector<double> maxVals = this->
getProperty(
"MaxValues");
199 outputWS->addDimension(std::make_shared<Geometry::MDHistoDimension>(
200 "Q_sample_x",
"Q_sample_x", frame,
static_cast<coord_t>(minVals[0]),
static_cast<coord_t>(maxVals[0]), 1));
202 outputWS->addDimension(std::make_shared<Geometry::MDHistoDimension>(
203 "Q_sample_y",
"Q_sample_y", frame,
static_cast<coord_t>(minVals[1]),
static_cast<coord_t>(maxVals[1]), 1));
205 outputWS->addDimension(std::make_shared<Geometry::MDHistoDimension>(
206 "Q_sample_z",
"Q_sample_z", frame,
static_cast<coord_t>(minVals[2]),
static_cast<coord_t>(maxVals[2]), 1));
208 outputWS->initialize();
212 outputWS->splitBox();
214 auto mdws_mdevt_3 = std::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(outputWS);
217 double cop = this->
getProperty(
"ObliquityParallaxCoefficient");
218 float coeff =
static_cast<float>(cop);
220 float k = boost::math::float_constants::two_pi /
static_cast<float>(wavelength);
221 float inv_wl_cube =
static_cast<float>(1 / (wavelength * wavelength * wavelength));
223 std::string convention = Kernel::ConfigService::Instance().getString(
"Q.convention");
224 if (convention ==
"Crystallography") {
227 std::vector<Eigen::Vector3f> q_lab_pre;
228 std::vector<float> lorentz_pre;
229 q_lab_pre.reserve(azimuthal.size());
230 lorentz_pre.reserve(azimuthal.size());
231 for (
size_t m = 0;
m < azimuthal.size(); ++
m) {
232 auto twotheta_f =
static_cast<float>(twotheta[
m]);
233 auto azimuthal_f =
static_cast<float>(azimuthal[
m]);
234 q_lab_pre.push_back({-std::sin(twotheta_f) * std::cos(azimuthal_f) * k,
235 -std::sin(twotheta_f) * std::sin(azimuthal_f) * k * coeff, (1.f - std::cos(twotheta_f)) * k});
236 lorentz_pre.push_back(std::abs(std::sin(twotheta_f) * std::cos(azimuthal_f)) * inv_wl_cube);
239 const auto run = inputWS->getExperimentInfo(0)->run();
240 for (
size_t n = 0;
n < inputWS->getDimension(2)->getNBins();
n++) {
241 auto gon = run.getGoniometerMatrix(
n);
242 Eigen::Matrix3f goniometer;
243 for (
int i = 0; i < 3; i++)
244 for (
int j = 0; j < 3; j++)
245 goniometer(i, j) =
static_cast<float>(gon[i][j]);
246 goniometer = goniometer.inverse().eval();
247 auto goniometerIndex =
static_cast<uint16_t
>(
n);
248 for (
size_t m = 0;
m < azimuthal.size();
m++) {
249 size_t idx =
n * azimuthal.size() +
m;
251 if (signal > 0.f && std::isfinite(signal)) {
252 Eigen::Vector3f q_sample = goniometer * q_lab_pre[
m];
254 factor = lorentz_pre[
m];
256 inserter.insertMDEvent(signal * factor, signal * factor * factor, 0, goniometerIndex, detectorID[
m],
264 outputWS->splitAllIfNeeded(ts);
267 outputWS->refreshCache();
268 outputWS->copyExperimentInfos(*inputWS);
269 auto &outRun = outputWS->getExperimentInfo(0)->mutableRun();
270 if (outRun.hasProperty(
"wavelength")) {
271 outRun.removeLogData(
"wavelength");
274 outRun.getProperty(
"wavelength")->setUnits(
"Angstrom");
276 auto user_convention = Kernel::ConfigService::Instance().getString(
"Q.convention");
277 auto ws_convention = outputWS->getConvention();
278 if (user_convention != ws_convention) {
280 convention_alg->setProperty(
"InputWorkspace", outputWS);
281 convention_alg->executeAsChildAlg();
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.
static API::IMDEventWorkspace_sptr CreateMDWorkspace(size_t nd, const std::string &eventType="MDLeanEvent", const Mantid::API::MDNormalization &preferredNormalization=Mantid::API::MDNormalization::VolumeNormalization, const Mantid::API::MDNormalization &preferredNormalizationHisto=Mantid::API::MDNormalization::VolumeNormalization)
Create a MDEventWorkspace of the given type.