24#include <boost/math/special_functions/round.hpp>
54 auto ws_valid = std::make_shared<CompositeValidator>();
57 auto mustBePositive = std::make_shared<BoundedValidator<double>>();
58 mustBePositive->setLower(0.0);
62 "An input MatrixWorkspace with time-of-flight units along "
63 "X-axis and defined instrument with defined sample");
66 "Workspace with peaks to be integrated. Each peak must already have an "
67 "ellipsoidal shape set, e.g. from a previous IntegrateEllipsoids run.");
70 "Only events at most this distance from a peak will be considered when "
71 "integrating. Must be at least as large as the largest background outer "
72 "radius among the peaks being integrated, or the background shell will be "
76 "If this options is enabled, then the top 1% of the background will be "
77 "removed before the background subtraction.");
80 "If true, integrate by maximizing the Poisson log-likelihood of a Gaussian "
81 "peak plus a flat background rate fit against the raw events, instead of "
82 "counting events inside/outside ellipsoidal boundaries. In this mode the "
83 "peak radii are interpreted as the Gaussian's standard deviations (1-sigma), "
84 "and the background radii are unused.");
87 "Only used if ProfileFit is true. If true, also refine each peak's center by "
88 "a bounded Gauss-Newton correction (capped at one standard deviation from the "
89 "peak's stored Q) as part of the profile fit, instead of keeping it fixed at "
90 "the peak's stored Q. The peak's stored Q is not modified; the correction is "
91 "used only for this integration.");
94 "The output PeaksWorkspace will be a copy of the input PeaksWorkspace "
95 "with the peaks' integrated intensities.");
109 Workspace2D_sptr histoWS = std::dynamic_pointer_cast<Workspace2D>(input_ws);
110 if (!eventWS && !histoWS) {
111 throw std::runtime_error(
"IntegratePeaksShapeMD needs either an "
112 "EventWorkspace or Workspace2D as input.");
116 if (peak_ws != input_peak_ws) {
117 peak_ws = input_peak_ws->clone();
120 std::vector<Peak> &peaks = peak_ws->getPeaks();
121 size_t n_peaks = peak_ws->getNumberPeaks();
126 std::vector<V3D> peak_q_list;
127 std::vector<V3D> hkl_vectors;
128 std::vector<std::pair<std::pair<double, double>,
V3D>> qList;
129 for (
size_t i = 0; i < n_peaks; i++) {
130 const auto *shape =
dynamic_cast<const PeakShapeEllipsoid *
>(&peaks[i].getPeakShape());
133 " does not have an ellipsoidal shape. Integrate the "
134 "PeaksWorkspace first, e.g. with IntegrateEllipsoids, "
135 "so that every peak has a shape to reuse.");
137 throw std::runtime_error(
"Peak " +
std::to_string(i) +
" has an ellipsoidal shape that is not in QLab.");
139 V3D hkl(peaks[i].getH(), peaks[i].getK(), peaks[i].getL());
141 peak_q_list.emplace_back(peaks[i].getQLabFrame());
142 hkl_vectors.emplace_back(
static_cast<double>(boost::math::iround<double>(hkl[0])),
143 static_cast<double>(boost::math::iround<double>(hkl[1])),
144 static_cast<double>(boost::math::iround<double>(hkl[2])));
146 qList.emplace_back(std::pair<double, double>(1.0, 1.0),
V3D(peaks[i].getQLabFrame()));
149 if (peak_q_list.size() < 3)
150 throw std::runtime_error(
"At least three linearly independent indexed peaks are needed.");
156 UBinv *= (1.0 / (2.0 * M_PI));
158 const bool useOnePercentBackgroundCorrection =
getProperty(
"UseOnePercentBackgroundCorrection");
161 Progress prog(
this, 0.0, 1.0, input_ws->getNumberHistograms());
169 const bool adjustCenter =
getProperty(
"AdjustCenter");
171 for (
size_t i = 0; i < n_peaks; i++) {
172 auto &peak = peaks[i];
184 if (adjustCenter && center != shape->translation()) {
186 shape->directions(), shape->abcRadii(), shape->abcRadiiBackgroundInner(), shape->abcRadiiBackgroundOuter(),
187 shape->frame(), shape->algorithmName(), shape->algorithmVersion(), center));
193 peak.setIntensity(inti);
194 peak.setSigmaIntensity(sigi);
199 peak_ws->mutableRun().addProperty(
"PeaksIntegrated", 1,
true);
204 const std::string
ELASTIC(
"Elastic");
205 const std::string
Q3D(
"Q3D");
206 const std::size_t
DIMS(3);
209 m_targWSDescr.
setMinMax(std::vector<double>(3, -2000.), std::vector<double>(3, 2000.));
214 childAlg->setProperty(
"InputWorkspace", wksp);
215 childAlg->executeAsChildAlg();
219 throw(std::runtime_error(
"Can not retrieve results of \"PreprocessDetectorsToMD\""));
223 auto numSpectra =
static_cast<int>(wksp->getNumberHistograms());
225 for (
int i = 0; i < numSpectra; ++i) {
229 unitConverter.
initialize(m_targWSDescr,
"Momentum");
234 std::vector<double> buffer(
DIMS);
240 if (events.
empty()) {
245 std::vector<Mantid::coord_t> locCoord(
DIMS, 0.);
246 unitConverter.updateConversion(i);
252 std::vector<std::pair<std::pair<double, double>,
V3D>> qList;
253 for (
const auto &raw_event : raw_events) {
254 double val = unitConverter.convertUnits(raw_event.tof());
256 for (
size_t dim = 0; dim <
DIMS; ++dim) {
257 buffer[dim] = locCoord[dim];
259 V3D qVec(buffer[0], buffer[1], buffer[2]);
260 qList.emplace_back(std::pair<double, double>(raw_event.m_weight, raw_event.m_errorSquared), qVec);
282 const std::string
ELASTIC(
"Elastic");
283 const std::string
Q3D(
"Q3D");
284 const std::size_t
DIMS(3);
287 m_targWSDescr.
setMinMax(std::vector<double>(3, -2000.), std::vector<double>(3, 2000.));
292 childAlg->setProperty(
"InputWorkspace", wksp);
293 childAlg->executeAsChildAlg();
297 throw(std::runtime_error(
"Can not retrieve results of \"PreprocessDetectorsToMD\""));
300 auto numSpectra =
static_cast<int>(wksp->getNumberHistograms());
302 for (
int i = 0; i < numSpectra; ++i) {
306 unitConverter.
initialize(m_targWSDescr,
"Momentum");
311 const auto &xVals = wksp->points(i);
312 const auto &yVals = wksp->y(i);
313 const auto &eVals = wksp->e(i);
315 std::vector<Mantid::coord_t> locCoord(
DIMS, 0.);
316 unitConverter.updateConversion(i);
322 std::vector<std::pair<std::pair<double, double>,
V3D>> qList;
324 for (
size_t j = 0; j < yVals.size(); ++j) {
325 const double &yVal = yVals[j];
326 const double &esqVal = eVals[j] * eVals[j];
328 double val = unitConverter.convertUnits(xVals[j]);
330 V3D qVec(locCoord[0], locCoord[1], locCoord[2]);
332 if (std::isnan(qVec[0]) || std::isnan(qVec[1]) || std::isnan(qVec[2]))
334 qList.emplace_back(std::pair<double, double>(yVal, esqVal), qVec);
#define DECLARE_ALGORITHM(classname)
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_CRITICAL(name)
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
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.
A validator which checks that a workspace has a valid instrument.
Helper class for reporting progress from algorithms.
A property class for workspaces.
void compressEvents(double tolerance, EventList *destination)
Compress the event list by grouping events with the same TOF (within a given tolerance).
std::vector< WeightedEventNoTime > & getWeightedEventsNoTime()
Return the list of WeightedEvent contained.
void switchTo(Mantid::API::EventType newType) override
Switch the EventList to use the given EventType (TOF, WEIGHTED, or WEIGHTED_NOTIME)
bool empty() const
Much like stl containers, returns true if there is nothing in the event list.
PeakShapeEllipsoid : PeakShape representing a 3D ellipsoid.
static double Optimize_UB(Kernel::DblMatrix &UB, const std::vector< Kernel::V3D > &hkl_vectors, const std::vector< Kernel::V3D > &q_vectors, std::vector< double > &sigabc)
Find the UB matrix that most nearly maps hkl to qxyz for 3 or more peaks.
static bool ValidIndex(const Kernel::V3D &hkl, double tolerance)
Check is hkl is within tolerance of integer (h,k,l) non-zero values.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
T Invert()
LU inversion routine.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
This is a low-level class to construct a map with lists of events near each peak Q-vector,...
void integrateUsingShapeProfileFit(const Mantid::DataObjects::PeakShapeEllipsoid &shape, const Mantid::Kernel::V3D &peak_q, bool adjustCenter, Mantid::Kernel::V3D ¢er, double &inti, double &sigi)
Integrate a peak using a shape supplied by the caller, by maximizing the Poisson log-likelihood of a ...
void integrateUsingShape(const Mantid::DataObjects::PeakShapeEllipsoid &shape, const Mantid::Kernel::V3D &peak_q, double &inti, double &sigi)
Integrate a peak using a shape supplied by the caller (e.g.
void addEvents(std::vector< std::pair< std::pair< double, double >, Mantid::Kernel::V3D > > const &event_qs, bool hkl_integ)
Add event Q's to lists of events near peaks.
IntegratePeaksShapeMD integrates single crystal Bragg peaks using the ellipsoidal peak shape already ...
int version() const override
Gets the algorithm version.
const std::string category() const override
Get the category of this algorithm.
void init() override
Defines the input, integration, fitting, and output properties for the algorithm.
void exec() override
Integrates peak intensities from an event or histogram workspace using QLab ellipsoidal peak shapes.
void qListFromEventWS(Integrate3DEvents &integrator, API::Progress &prog, DataObjects::EventWorkspace_sptr &wksp)
void qListFromHistoWS(Integrate3DEvents &integrator, API::Progress &prog, DataObjects::Workspace2D_sptr &wksp)
Converts histogram workspace data to Q-space events for integration.
Class responsible for conversion of input workspace data into proper number of output dimensions for ...
bool calcMatrixCoord(const double &deltaEOrK0, std::vector< coord_t > &Coord, double &s, double &err) const override
Calculates 3D transformation of the variable coordinates and (if applicable) signal and error dependi...
void initialize(const MDWSDescription &ConvParams) override
function initalizes all variables necessary for converting workspace variables into MD variables in M...
bool calcYDepCoordinates(std::vector< coord_t > &Coord, size_t i) override
Method updates the value of preprocessed detector coordinates in Q-space, used by other functions.
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
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,...
DataObjects::TableWorkspace_const_sptr m_PreprDetTable
void setLorentsCorr(bool On=false)
do we need to perform Lorentz corrections
void initialize(const MDWSDescription &targetWSDescr, const std::string &unitsTo, bool forceViaTOF=false)
Initialize unit conversion helper This method is interface to internal initialize method,...
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
std::shared_ptr< PeaksWorkspace > PeaksWorkspace_sptr
Typedef for a shared pointer to a peaks workspace.
std::shared_ptr< Workspace2D > Workspace2D_sptr
shared pointer to Mantid::DataObjects::Workspace2D
std::shared_ptr< TableWorkspace > TableWorkspace_sptr
shared pointer to Mantid::DataObjects::TableWorkspace
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
const std::string Q3D("Q3D")
Only convert to Q-vector.
const std::size_t DIMS(3)
Q-vector is always three dimensional.
const std::string ELASTIC("Elastic")
This only works for diffraction.
std::string to_string(const wide_integer< Bits, Signed > &n)
@ InOut
Both an input & output workspace.
@ Input
An input workspace.
@ Output
An output workspace.