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 if (instrument ==
"HB3A" && !expInfo.run().hasProperty(
"azimuthal")) {
172 const auto &di = expInfo.detectorInfo();
173 for (
size_t x = 0;
x < 512;
x++) {
174 for (
size_t y = 0;
y < 512 * 3;
y++) {
175 size_t n =
x +
y * 512;
176 if (!di.isMonitor(
n)) {
177 twotheta.push_back(di.twoTheta(
n));
178 azimuthal.push_back(di.azimuthal(
n));
189 std::vector<double> minVals = this->
getProperty(
"MinValues");
190 std::vector<double> maxVals = this->
getProperty(
"MaxValues");
191 outputWS->addDimension(std::make_shared<Geometry::MDHistoDimension>(
192 "Q_sample_x",
"Q_sample_x", frame,
static_cast<coord_t>(minVals[0]),
static_cast<coord_t>(maxVals[0]), 1));
194 outputWS->addDimension(std::make_shared<Geometry::MDHistoDimension>(
195 "Q_sample_y",
"Q_sample_y", frame,
static_cast<coord_t>(minVals[1]),
static_cast<coord_t>(maxVals[1]), 1));
197 outputWS->addDimension(std::make_shared<Geometry::MDHistoDimension>(
198 "Q_sample_z",
"Q_sample_z", frame,
static_cast<coord_t>(minVals[2]),
static_cast<coord_t>(maxVals[2]), 1));
200 outputWS->initialize();
204 outputWS->splitBox();
206 auto mdws_mdevt_3 = std::dynamic_pointer_cast<MDEventWorkspace<MDEvent<3>, 3>>(outputWS);
209 double cop = this->
getProperty(
"ObliquityParallaxCoefficient");
210 float coeff =
static_cast<float>(cop);
212 float k = boost::math::float_constants::two_pi /
static_cast<float>(wavelength);
213 float inv_wl_cube =
static_cast<float>(1 / (wavelength * wavelength * wavelength));
215 std::string convention = Kernel::ConfigService::Instance().getString(
"Q.convention");
216 if (convention ==
"Crystallography") {
219 std::vector<Eigen::Vector3f> q_lab_pre;
220 std::vector<float> lorentz_pre;
221 q_lab_pre.reserve(azimuthal.size());
222 lorentz_pre.reserve(azimuthal.size());
223 for (
size_t m = 0;
m < azimuthal.size(); ++
m) {
224 auto twotheta_f =
static_cast<float>(twotheta[
m]);
225 auto azimuthal_f =
static_cast<float>(azimuthal[
m]);
226 q_lab_pre.push_back({-std::sin(twotheta_f) * std::cos(azimuthal_f) * k,
227 -std::sin(twotheta_f) * std::sin(azimuthal_f) * k * coeff, (1.f - std::cos(twotheta_f)) * k});
228 lorentz_pre.push_back(std::abs(std::sin(twotheta_f) * std::cos(azimuthal_f)) * inv_wl_cube);
231 const auto run = inputWS->getExperimentInfo(0)->run();
232 for (
size_t n = 0;
n < inputWS->getDimension(2)->getNBins();
n++) {
233 auto gon = run.getGoniometerMatrix(
n);
234 Eigen::Matrix3f goniometer;
235 for (
int i = 0; i < 3; i++)
236 for (
int j = 0; j < 3; j++)
237 goniometer(i, j) =
static_cast<float>(gon[i][j]);
238 goniometer = goniometer.inverse().eval();
239 auto goniometerIndex =
static_cast<uint16_t
>(
n);
240 for (
size_t m = 0;
m < azimuthal.size();
m++) {
241 size_t idx =
n * azimuthal.size() +
m;
243 if (signal > 0.f && std::isfinite(signal)) {
244 Eigen::Vector3f q_sample = goniometer * q_lab_pre[
m];
246 factor = lorentz_pre[
m];
248 inserter.insertMDEvent(signal * factor, signal * factor * factor, 0, goniometerIndex, 0, q_sample.data());
255 outputWS->splitAllIfNeeded(ts);
258 outputWS->refreshCache();
259 outputWS->copyExperimentInfos(*inputWS);
260 auto &outRun = outputWS->getExperimentInfo(0)->mutableRun();
261 if (outRun.hasProperty(
"wavelength")) {
262 outRun.removeLogData(
"wavelength");
265 outRun.getProperty(
"wavelength")->setUnits(
"Angstrom");
267 auto user_convention = Kernel::ConfigService::Instance().getString(
"Q.convention");
268 auto ws_convention = outputWS->getConvention();
269 if (user_convention != ws_convention) {
271 convention_alg->setProperty(
"InputWorkspace", outputWS);
272 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.