Mantid
Loading...
Searching...
No Matches
ConvToMDEventsWS.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
8
9#include "MantidAPI/Run.h"
11
12namespace Mantid::MDAlgorithms {
15template <class T> size_t ConvToMDEventsWS::convertEventList(size_t workspaceIndex) {
16
17 const Mantid::DataObjects::EventList &el = m_EventWS->getSpectrum(workspaceIndex);
18 size_t numEvents = el.getNumberEvents();
19 if (numEvents == 0)
20 return 0;
21
22 // create local unit conversion class
24
25 uint32_t detID = m_detID[workspaceIndex];
26 uint16_t expInfoIndexLoc = m_ExpInfoIndex;
27
28 std::vector<coord_t> locCoord(m_Coord);
29 // set up unit conversion and calculate up all coordinates, which depend on
30 // spectra index only
31 if (!m_QConverter->calcYDepCoordinates(locCoord, workspaceIndex))
32 return 0; // skip if any y outsize of the range of interest;
33 localUnitConv.updateConversion(workspaceIndex);
34 //
35 // allocate temporary buffers for MD Events data
36 // MD events coordinates buffer
37 std::vector<coord_t> allCoord;
38 std::vector<float> sig_err; // array for signal and error.
39 std::vector<uint16_t> expInfoIndex; // Buffer for associated experiment-info index for each event
40 std::vector<uint16_t> goniometer_index; // Buffer for goniometer index for each event
41 std::vector<uint32_t> det_ids; // Buffer of det Id-s for each event
42
43 allCoord.reserve(this->m_NDims * numEvents);
44 sig_err.reserve(2 * numEvents);
45 expInfoIndex.reserve(numEvents);
46 goniometer_index.reserve(numEvents);
47 det_ids.reserve(numEvents);
48
49 // This little dance makes the getting vector of events more general (since
50 // you can't overload by return type).
51 typename std::vector<T> const *events_ptr;
52 getEventsFrom(el, events_ptr);
53 const typename std::vector<T> &events = *events_ptr;
54
55 // Iterators to start/end
56 for (auto it = events.cbegin(); it != events.cend(); it++) {
57 double val = localUnitConv.convertUnits(it->tof());
58 double signal = it->weight();
59 double errorSq = it->errorSquared();
61 continue; // skip if log value is NaN
62 if (!m_QConverter->calcMatrixCoord(val, locCoord, signal, errorSq))
63 continue; // skip ND outside the range
64
65 sig_err.emplace_back(static_cast<float>(signal));
66 sig_err.emplace_back(static_cast<float>(errorSq));
67 expInfoIndex.emplace_back(expInfoIndexLoc);
68 goniometer_index.emplace_back(0); // default value
69 det_ids.emplace_back(detID);
70 allCoord.insert(allCoord.end(), locCoord.begin(), locCoord.end());
71 }
72
73 // Add them to the MDEW
74 size_t n_added_events = expInfoIndex.size();
75 m_OutWSWrapper->addMDData(sig_err, expInfoIndex, goniometer_index, det_ids, allCoord, n_added_events);
76 return n_added_events;
77}
78
81size_t ConvToMDEventsWS::conversionChunk(size_t workspaceIndex) {
82
83 switch (m_EventWS->getSpectrum(workspaceIndex).getEventType()) {
85 return this->convertEventList<Mantid::Types::Event::TofEvent>(workspaceIndex);
87 return this->convertEventList<Mantid::DataObjects::WeightedEvent>(workspaceIndex);
89 return this->convertEventList<Mantid::DataObjects::WeightedEventNoTime>(workspaceIndex);
90 default:
91 throw std::runtime_error("EventList had an unexpected data type!");
92 }
93}
94
105size_t ConvToMDEventsWS::initialize(const MDWSDescription &WSD, std::shared_ptr<MDEventWSWrapper> inWSWrapper,
106 bool ignoreZeros, bool useLogTimes) {
107 size_t numSpec = ConvToMDBase::initialize(WSD, inWSWrapper, ignoreZeros, useLogTimes);
108
109 m_EventWS = std::dynamic_pointer_cast<const DataObjects::EventWorkspace>(m_InWS2D);
110 if (!m_EventWS)
111 throw(std::logic_error(" ConvertToMDEventWS should work with defined event workspace"));
112
113 // Record any special coordinate system known to the description.
115
116 // Look up required logs is using log times
117 if (m_useLogTimes) {
118 // Saves the Q-cartesian transformation
119 m_Wtransf = WSD.m_Wtransf;
120 // Log values for Gonios
121 const Mantid::API::Run &run = WSD.getInWS()->run();
123 for (size_t n = 0; n < m_Goniometer.getNumberAxes(); n++) {
125 if (run.hasProperty(ax.name)) {
126 m_Logs.push_back(
127 std::unique_ptr<Kernel::TimeSeriesProperty<double>>(run.getTimeSeriesProperty<double>(ax.name)->clone()));
128 m_GonioIndex.push_back(n);
129 }
130 }
132 }
133
134 return numSpec;
135}
136
138
139 // Get the box controller
140 Mantid::API::BoxController_sptr bc = m_OutWSWrapper->pWorkspace()->getBoxController();
141
142 // if any property dimension is outside of the data range requested, the job
143 // is done;
144 if (!m_QConverter->calcGenericVariables(m_Coord, m_NDims))
145 return;
146
147 appendEventsFromInputWS(pProgress, bc);
148
149 pProgress->report();
150
152 m_OutWSWrapper->pWorkspace()->setCoordinateSystem(m_coordinateSystem);
153}
154
156 // Is the access to input events thread-safe?
157 // bool MultiThreadedAdding = m_EventWS->threadSafe();
158 // preprocessed detectors insure that each detector has its own spectra
159 size_t lastNumBoxes = bc->getTotalNumMDBoxes();
160 size_t nEventsInWS = m_OutWSWrapper->pWorkspace()->getNPoints();
161 //--->>> Thread control stuff
162 Kernel::ThreadSchedulerFIFO *ts(nullptr);
163
164 int nThreads(m_NumThreads);
165 if (nThreads < 0)
166 nThreads = 0; // negative m_NumThreads correspond to all cores used, 0 no
167 // threads and positive number -- nThreads requested;
168 bool runMultithreaded = false;
169 if (m_NumThreads != 0) {
170 runMultithreaded = true;
171 // Create the thread pool that will run all of these. It will be deleted by
172 // the threadpool
174 // it will initiate thread pool with number threads or machine's cores (0 in
175 // tp constructor)
176 pProgress->resetNumSteps(m_NSpectra, 0, 1);
177 }
178 Kernel::ThreadPool tp(ts, nThreads, new API::Progress(*pProgress));
179 //<<<-- Thread control stuff
180
181 size_t eventsAdded = 0;
182 for (size_t wi = 0; wi < m_NSpectra; wi++) {
183
184 size_t nConverted = conversionChunk(wi);
185 eventsAdded += nConverted;
186 nEventsInWS += nConverted;
187 // Keep a running total of how many events we've added
188 if (bc->shouldSplitBoxes(nEventsInWS, eventsAdded, lastNumBoxes)) {
189 if (runMultithreaded) {
190 // Now do all the splitting tasks
191 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(ts);
192 if (ts->size() > 0)
193 tp.joinAll();
194 } else {
195 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(nullptr); // it is done this way as it is possible trying to do
196 // single
197 // threaded split more efficiently
198 }
199 // Count the new # of boxes.
200 lastNumBoxes = m_OutWSWrapper->pWorkspace()->getBoxController()->getTotalNumMDBoxes();
201 eventsAdded = 0;
202 pProgress->report(wi);
203 }
204 }
205 // Do a final splitting of everything
206 if (runMultithreaded) {
207 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(ts);
208 tp.joinAll();
209 } else {
210 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(nullptr);
211 }
212
213 // Recount totals at the end.
214 m_OutWSWrapper->pWorkspace()->refreshCache();
215}
216
217} // namespace Mantid::MDAlgorithms
static std::unique_ptr< QThreadPool > tp
bool hasProperty(const std::string &name) const
Does the property exist on the object.
Kernel::TimeSeriesProperty< T > * getTimeSeriesProperty(const std::string &name) const
Returns a property as a time series property.
Helper class for reporting progress from algorithms.
Definition Progress.h:25
This class stores information regarding an experimental run as a series of log entries.
Definition Run.h:35
const Geometry::Goniometer & getGoniometer() const
Return reference to the first const Goniometer object for this run.
Definition Run.cpp:525
A class for holding :
Definition EventList.h:57
std::size_t getNumberEvents() const override
Return the number of events in the list.
const GoniometerAxis & getAxis(size_t axisnumber) const
Get GoniometerAxis obfject using motor number.
void resetNumSteps(int64_t nsteps, double start, double end)
Change the number of steps between start/end.
void report()
Increments the loop counter by 1, then sends the progress notification on behalf of its algorithm.
A Thread Pool implementation that keeps a certain number of threads running (normally,...
Definition ThreadPool.h:36
A First-In-First-Out Thread Scheduler.
size_t size() override
Returns the size of the queue.
A specialised Property class for holding a series of time-value pairs.
API::MatrixWorkspace_const_sptr m_InWS2D
virtual size_t initialize(const MDWSDescription &WSD, std::shared_ptr< MDEventWSWrapper > inWSWrapper, bool ignoreZeros, bool useLogTimes=false)
method which initiates all main class variables
std::vector< int32_t > m_detID
Mantid::Kernel::SpecialCoordinateSystem m_coordinateSystem
Any special coordinate system used.
bool m_useLogTimes
Flag to use log values corresponding to event pulse time instead of average values.
std::vector< coord_t > m_Coord
size_t m_NDims
number of target ws dimensions
std::shared_ptr< MDEventWSWrapper > m_OutWSWrapper
UnitsConversionHelper m_UnitConversion
std::vector< std::unique_ptr< Kernel::TimeSeriesProperty< double > > > m_Logs
size_t initialize(const MDWSDescription &WSD, std::shared_ptr< MDEventWSWrapper > inWSWrapper, bool ignoreZeros, bool useLogTimes) override
method sets up all internal variables necessary to convert from Event Workspace to MDEvent workspace
size_t convertEventList(size_t workspaceIndex)
function converts particular type of events into MD space and add these events to the workspace itsel...
size_t conversionChunk(size_t workspaceIndex) override
The method runs conversion for a single event list, corresponding to a particular workspace index.
DataObjects::EventWorkspace_const_sptr m_EventWS
virtual void appendEventsFromInputWS(API::Progress *pProgress, const API::BoxController_sptr &bc)
void runConversion(API::Progress *pProgress) override
method which starts the conversion procedure
helper class describes the properties of target MD workspace, which should be obtained as the result ...
API::MatrixWorkspace_const_sptr getInWS() const
Mantid::Kernel::SpecialCoordinateSystem getCoordinateSystem() const
void updateConversion(size_t i)
Method updates unit conversion given the index of detector parameters in the array of detectors.
double convertUnits(double val) const
do actual unit conversion from input to oputput data
std::shared_ptr< BoxController > BoxController_sptr
Shared ptr to BoxController.
std::size_t numEvents(Nexus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix)
Get the number of events in the currently opened group.
DLLExport void getEventsFrom(EventList &el, std::vector< Types::Event::TofEvent > *&events)
Mantid::Kernel::Matrix< double > DblMatrix
Definition Matrix.h:206
Counter clockwise rotation.
Definition Goniometer.h:38