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
10
11namespace Mantid::MDAlgorithms {
14template <class T> size_t ConvToMDEventsWS::convertEventList(size_t workspaceIndex) {
15
16 const Mantid::DataObjects::EventList &el = m_EventWS->getSpectrum(workspaceIndex);
17 size_t numEvents = el.getNumberEvents();
18 if (numEvents == 0)
19 return 0;
20
21 // create local unit conversion class
23
24 uint32_t detID = m_detID[workspaceIndex];
25 uint16_t expInfoIndexLoc = m_ExpInfoIndex;
26
27 std::vector<coord_t> locCoord(m_Coord);
28 // set up unit conversion and calculate up all coordinates, which depend on
29 // spectra index only
30 if (!m_QConverter->calcYDepCoordinates(locCoord, workspaceIndex))
31 return 0; // skip if any y outsize of the range of interest;
32 localUnitConv.updateConversion(workspaceIndex);
33 //
34 // allocate temporary buffers for MD Events data
35 // MD events coordinates buffer
36 std::vector<coord_t> allCoord;
37 std::vector<float> sig_err; // array for signal and error.
38 std::vector<uint16_t> expInfoIndex; // Buffer for associated experiment-info index for each event
39 std::vector<uint16_t> goniometer_index; // Buffer for goniometer index for each event
40 std::vector<uint32_t> det_ids; // Buffer of det Id-s for each event
41
42 allCoord.reserve(this->m_NDims * numEvents);
43 sig_err.reserve(2 * numEvents);
44 expInfoIndex.reserve(numEvents);
45 goniometer_index.reserve(numEvents);
46 det_ids.reserve(numEvents);
47
48 // This little dance makes the getting vector of events more general (since
49 // you can't overload by return type).
50 typename std::vector<T> const *events_ptr;
51 getEventsFrom(el, events_ptr);
52 const typename std::vector<T> &events = *events_ptr;
53
54 // Iterators to start/end
55 for (auto it = events.cbegin(); it != events.cend(); it++) {
56 double val = localUnitConv.convertUnits(it->tof());
57 double signal = it->weight();
58 double errorSq = it->errorSquared();
59 if (!m_QConverter->calcMatrixCoord(val, locCoord, signal, errorSq))
60 continue; // skip ND outside the range
61
62 sig_err.emplace_back(static_cast<float>(signal));
63 sig_err.emplace_back(static_cast<float>(errorSq));
64 expInfoIndex.emplace_back(expInfoIndexLoc);
65 goniometer_index.emplace_back(0); // default value
66 det_ids.emplace_back(detID);
67 allCoord.insert(allCoord.end(), locCoord.begin(), locCoord.end());
68 }
69
70 // Add them to the MDEW
71 size_t n_added_events = expInfoIndex.size();
72 m_OutWSWrapper->addMDData(sig_err, expInfoIndex, goniometer_index, det_ids, allCoord, n_added_events);
73 return n_added_events;
74}
75
78size_t ConvToMDEventsWS::conversionChunk(size_t workspaceIndex) {
79
80 switch (m_EventWS->getSpectrum(workspaceIndex).getEventType()) {
82 return this->convertEventList<Mantid::Types::Event::TofEvent>(workspaceIndex);
84 return this->convertEventList<Mantid::DataObjects::WeightedEvent>(workspaceIndex);
86 return this->convertEventList<Mantid::DataObjects::WeightedEventNoTime>(workspaceIndex);
87 default:
88 throw std::runtime_error("EventList had an unexpected data type!");
89 }
90}
91
100size_t ConvToMDEventsWS::initialize(const MDWSDescription &WSD, std::shared_ptr<MDEventWSWrapper> inWSWrapper,
101 bool ignoreZeros) {
102 size_t numSpec = ConvToMDBase::initialize(WSD, inWSWrapper, ignoreZeros);
103
104 m_EventWS = std::dynamic_pointer_cast<const DataObjects::EventWorkspace>(m_InWS2D);
105 if (!m_EventWS)
106 throw(std::logic_error(" ConvertToMDEventWS should work with defined event workspace"));
107
108 // Record any special coordinate system known to the description.
110 return numSpec;
111}
112
114
115 // Get the box controller
116 Mantid::API::BoxController_sptr bc = m_OutWSWrapper->pWorkspace()->getBoxController();
117
118 // if any property dimension is outside of the data range requested, the job
119 // is done;
120 if (!m_QConverter->calcGenericVariables(m_Coord, m_NDims))
121 return;
122
123 appendEventsFromInputWS(pProgress, bc);
124
125 pProgress->report();
126
128 m_OutWSWrapper->pWorkspace()->setCoordinateSystem(m_coordinateSystem);
129}
130
132 // Is the access to input events thread-safe?
133 // bool MultiThreadedAdding = m_EventWS->threadSafe();
134 // preprocessed detectors insure that each detector has its own spectra
135 size_t lastNumBoxes = bc->getTotalNumMDBoxes();
136 size_t nEventsInWS = m_OutWSWrapper->pWorkspace()->getNPoints();
137 //--->>> Thread control stuff
138 Kernel::ThreadSchedulerFIFO *ts(nullptr);
139
140 int nThreads(m_NumThreads);
141 if (nThreads < 0)
142 nThreads = 0; // negative m_NumThreads correspond to all cores used, 0 no
143 // threads and positive number -- nThreads requested;
144 bool runMultithreaded = false;
145 if (m_NumThreads != 0) {
146 runMultithreaded = true;
147 // Create the thread pool that will run all of these. It will be deleted by
148 // the threadpool
150 // it will initiate thread pool with number threads or machine's cores (0 in
151 // tp constructor)
152 pProgress->resetNumSteps(m_NSpectra, 0, 1);
153 }
154 Kernel::ThreadPool tp(ts, nThreads, new API::Progress(*pProgress));
155 //<<<-- Thread control stuff
156
157 size_t eventsAdded = 0;
158 for (size_t wi = 0; wi < m_NSpectra; wi++) {
159
160 size_t nConverted = conversionChunk(wi);
161 eventsAdded += nConverted;
162 nEventsInWS += nConverted;
163 // Keep a running total of how many events we've added
164 if (bc->shouldSplitBoxes(nEventsInWS, eventsAdded, lastNumBoxes)) {
165 if (runMultithreaded) {
166 // Now do all the splitting tasks
167 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(ts);
168 if (ts->size() > 0)
169 tp.joinAll();
170 } else {
171 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(nullptr); // it is done this way as it is possible trying to do
172 // single
173 // threaded split more efficiently
174 }
175 // Count the new # of boxes.
176 lastNumBoxes = m_OutWSWrapper->pWorkspace()->getBoxController()->getTotalNumMDBoxes();
177 eventsAdded = 0;
178 pProgress->report(wi);
179 }
180 }
181 // Do a final splitting of everything
182 if (runMultithreaded) {
183 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(ts);
184 tp.joinAll();
185 } else {
186 m_OutWSWrapper->pWorkspace()->splitAllIfNeeded(nullptr);
187 }
188
189 // Recount totals at the end.
190 m_OutWSWrapper->pWorkspace()->refreshCache();
191}
192
193} // namespace Mantid::MDAlgorithms
static std::unique_ptr< QThreadPool > tp
Helper class for reporting progress from algorithms.
Definition: Progress.h:25
A class for holding :
Definition: EventList.h:56
std::size_t getNumberEvents() const override
Return the number of events in the list.
Definition: EventList.cpp:1143
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.
Definition: ProgressBase.h:51
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.
API::MatrixWorkspace_const_sptr m_InWS2D
Definition: ConvToMDBase.h:57
std::vector< int32_t > m_detID
Definition: ConvToMDBase.h:72
Mantid::Kernel::SpecialCoordinateSystem m_coordinateSystem
Any special coordinate system used.
Definition: ConvToMDBase.h:90
std::vector< coord_t > m_Coord
Definition: ConvToMDBase.h:78
virtual size_t initialize(const MDWSDescription &WSD, std::shared_ptr< MDEventWSWrapper > inWSWrapper, bool ignoreZeros)
method which initiates all main class variables
size_t m_NDims
number of target ws dimensions
Definition: ConvToMDBase.h:65
std::shared_ptr< MDEventWSWrapper > m_OutWSWrapper
Definition: ConvToMDBase.h:60
UnitsConversionHelper m_UnitConversion
Definition: ConvToMDBase.h:80
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)
size_t initialize(const MDWSDescription &WSD, std::shared_ptr< MDEventWSWrapper > inWSWrapper, bool ignoreZeros) override
method sets up all internal variables necessary to convert from Event Workspace to MDEvent workspace
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 ...
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.
@ WEIGHTED_NOTIME
Definition: IEventList.h:18
std::size_t numEvents(::NeXus::File &file, bool &hasTotalCounts, bool &oldNeXusFileNames, const std::string &prefix, const NexusHDF5Descriptor &descriptor)
Get the number of events in the currently opened group.
DLLExport void getEventsFrom(EventList &el, std::vector< Types::Event::TofEvent > *&events)