Mantid
Loading...
Searching...
No Matches
MDBox.hxx
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 +
13#include <algorithm>
14#include <boost/math/special_functions/round.hpp>
15#include <cmath>
16#include <numeric>
17
18namespace Mantid {
19namespace DataObjects {
20
23 if (m_Saveable) {
24 // tell disk buffer that there are no point of tracking this box any more.
25 // BAD!!! TODO: make correct destructors order.
26 if (this->m_BoxController) // it is destructor, in tests everything may fall
27 // apart, though it should not be issue for a
28 // workspace
29 {
30 if (this->m_BoxController->isFileBacked()) {
31 this->m_BoxController->getFileIO()->objectDeleted(m_Saveable.get());
32 }
33 }
34 }
35}
36//-----------------------------------------------------------------------------------------------
44TMDE(MDBox)::MDBox(API::BoxController_sptr &splitter, const uint32_t depth, const size_t nBoxEvents, const size_t boxID)
45 : MDBoxBase<MDE, nd>(splitter.get(), depth, boxID), m_Saveable(nullptr), m_bIsMasked(false) {
46 initMDBox(nBoxEvents);
48
49//-----------------------------------------------------------------------------------------------
56TMDE(MDBox)::MDBox(API::BoxController *const splitter, const uint32_t depth, const size_t nBoxEvents,
57 const size_t boxID)
58 : MDBoxBase<MDE, nd>(splitter, depth, boxID), m_Saveable(nullptr), m_bIsMasked(false) {
59 initMDBox(nBoxEvents);
60}
62//-----------------------------------------------------------------------------------------------
71TMDE(MDBox)::MDBox(API::BoxController_sptr &splitter, const uint32_t depth,
72 const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> &extentsVector,
73 const size_t nBoxEvents, const size_t boxID)
74 : MDBoxBase<MDE, nd>(splitter.get(), depth, boxID, extentsVector), m_Saveable(nullptr), m_bIsMasked(false) {
75 initMDBox(nBoxEvents);
76}
77//-----------------------------------------------------------------------------------------------
86TMDE(MDBox)::MDBox(API::BoxController *const splitter, const uint32_t depth,
87 const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> &extentsVector,
88 const size_t nBoxEvents, const size_t boxID)
89 : MDBoxBase<MDE, nd>(splitter, depth, boxID, extentsVector), m_Saveable(nullptr), m_bIsMasked(false) {
90 initMDBox(nBoxEvents);
92
102template <typename MDE, size_t nd>
103MDBox<MDE, nd>::MDBox(Mantid::API::BoxController *const bc, const uint32_t depth,
104 const std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>> &extentsVector,
105 EventIterator begin, EventIterator end)
106 : MDBoxBase<MDE, nd>(bc, depth, 0, extentsVector), m_Saveable(nullptr), data(std::vector<MDE>(begin, end)),
107 m_bIsMasked(false) {
109 if (this->m_BoxController->isFileBacked())
111}
112
114TMDE(void MDBox)::initMDBox(const size_t nBoxEvents) {
115 if (this->m_BoxController->getNDims() != nd)
116 throw std::invalid_argument("MDBox::ctor(): controller passed has the wrong number of dimensions.");
117
118 if (nBoxEvents != UNDEF_SIZET)
119 data.reserve(nBoxEvents);
120
121 if (this->m_BoxController->isFileBacked())
122 this->setFileBacked();
123}
124
125//-----------------------------------------------------------------------------------------------
131TMDE(MDBox)::MDBox(const MDBox<MDE, nd> &other, Mantid::API::BoxController *const otherBC)
132 : MDBoxBase<MDE, nd>(other, otherBC), m_Saveable(nullptr), data(other.data), m_bIsMasked(other.m_bIsMasked) {
133 if (otherBC) // may be absent in some tests but generally have to be present
134 {
135 if (otherBC->isFileBacked())
136 this->setFileBacked();
137 }
138}
139// unhide MDBoxBase method
140TMDE(size_t MDBox)::addEventsUnsafe(const std::vector<MDE> &events) {
143
144//-----------------------------------------------------------------------------------------------
146TMDE(void MDBox)::clear() {
147 // Make sure the object is not in any of the disk MRUs, and mark any space it
148 // used as free
149 // if (this->m_BoxController->useWriteBuffer())
150 if (m_Saveable)
151 this->m_BoxController->getFileIO()->objectDeleted(m_Saveable.get());
152
153 // Clear all contents
154 this->m_signal = 0.0;
155 this->m_errorSquared = 0.0;
156
157 this->clearDataFromMemory();
158}
159
160TMDE(Kernel::ISaveable *MDBox)::getISaveable() { return m_Saveable.get(); }
161TMDE(Kernel::ISaveable *MDBox)::getISaveable() const { return m_Saveable.get(); }
163//-----------------------------------------------------------------------------------------------
167TMDE(void MDBox)::clearDataFromMemory() {
168 data.clear();
169 vec_t().swap(data); // Linux trick to really free the memory
170 // mark data unchanged
171 if (m_Saveable) {
172 m_Saveable->setLoaded(false);
173 m_Saveable->setBusy(false);
174 m_Saveable->clearDataChanged();
176}
178//-----------------------------------------------------------------------------------------------
180TMDE(size_t MDBox)::getNumDims() const { return nd; }
181
182//-----------------------------------------------------------------------------------------------
185TMDE(size_t MDBox)::getNumMDBoxes() const { return 1; }
186
187//-----------------------------------------------------------------------------------------------
189TMDE(void MDBox)::getBoxes(std::vector<MDBoxBase<MDE, nd> *> &boxes, size_t /*maxDepth*/, bool /*leafOnly*/) {
190 boxes.emplace_back(this);
192TMDE(void MDBox)::getBoxes(std::vector<API::IMDNode *> &boxes, size_t /*maxDepth*/, bool /*leafOnly*/) {
193 boxes.emplace_back(this);
194}
195
196//-----------------------------------------------------------------------------------------------
198TMDE(void MDBox)::getBoxes(std::vector<MDBoxBase<MDE, nd> *> &boxes, size_t /*maxDepth*/, bool /*leafOnly*/,
199 Mantid::Geometry::MDImplicitFunction * /*function*/) {
200 boxes.emplace_back(this);
201}
202TMDE(void MDBox)::getBoxes(std::vector<API::IMDNode *> &boxes, size_t /*maxDepth*/, bool /*leafOnly*/,
203 Mantid::Geometry::MDImplicitFunction * /*function*/) {
204 boxes.emplace_back(this);
205}
206
207//-----------------------------------------------------------------------------------------------
213TMDE(uint64_t MDBox)::getNPoints() const {
214 if (!m_Saveable)
215 return data.size();
216
217 if (m_Saveable->wasSaved()) {
218 if (m_Saveable->isLoaded())
219 return data.size();
220 else // m_fileNumEvents
221 return m_Saveable->getFileSize() + data.size();
222 } else
223 return data.size();
224}
225
226//-----------------------------------------------------------------------------------------------
231TMDE(std::vector<MDE> &MDBox)::getEvents() {
232 if (!m_Saveable)
233 return data;
234 else {
235 if (m_Saveable->wasSaved()) { // Load and concatenate the events if needed
236 m_Saveable->load(); // this will set isLoaded to true if not already loaded;
237 }
238 // The data vector is busy - can't release the memory yet
239 m_Saveable->setBusy(true);
240 // the non-const access to events assumes that the data will be modified;
241 m_Saveable->setDataChanged();
242
243 // Tell the to-write buffer to discard the object (when no longer busy) as
244 // it has not been modified
245 this->m_BoxController->getFileIO()->toWrite(m_Saveable.get());
246 // else: do nothing if the events are already in memory.
247 return data;
248 }
249}
250
251TMDE(const std::vector<MDE> &MDBox)::getEvents() const { return getConstEvents(); }
252//-----------------------------------------------------------------------------------------------
257TMDE(const std::vector<MDE> &MDBox)::getConstEvents() const {
258 if (!m_Saveable)
259 return data;
260 else {
261 if (m_Saveable->wasSaved()) {
262 // Load and concatenate the events if needed
263 m_Saveable->load(); // this will set isLoaded to true if not already loaded;
264 // This access to data was const. Don't change the m_dataModified flag.
265 }
266 // The data vector is busy - can't release the memory yet
267 m_Saveable->setBusy(true);
268
269 // Tell the to-write buffer to discard the object (when no longer busy) as
270 // it has not been modified
271 this->m_BoxController->getFileIO()->toWrite(m_Saveable.get());
272 // else: do nothing if the events are already in memory.
273 return data;
274 }
275}
276
277//-----------------------------------------------------------------------------------------------
282TMDE(void MDBox)::releaseEvents() {
283 // Data vector is no longer busy.
284 if (m_Saveable)
285 m_Saveable->setBusy(false);
286}
287
295TMDE(void MDBox)::getEventsData(std::vector<coord_t> &coordTable, size_t &nColumns) const {
296 double signal, errorSq;
297 MDE::eventsToData(this->data, coordTable, nColumns, signal, errorSq);
298 this->m_signal = static_cast<signal_t>(signal);
299 this->m_errorSquared = static_cast<signal_t>(errorSq);
300
301#ifdef MDBOX_TRACK_CENTROID
302 this->calculateCentroid(this->m_centroid);
303#endif
304}
311TMDE(void MDBox)::setEventsData(const std::vector<coord_t> &coordTable) { MDE::dataToEvents(coordTable, this->data); }
312
313//-----------------------------------------------------------------------------------------------
316TMDE(std::vector<MDE> *MDBox)::getEventsCopy() {
317 if (m_Saveable) {
318 }
319 auto out = new std::vector<MDE>();
320 // Make the copy
321 out->insert(out->begin(), data.begin(), data.end());
322 return out;
323}
324
325//-----------------------------------------------------------------------------------------------
338TMDE(void MDBox)::refreshCache(Kernel::ThreadScheduler * /*ts*/) {
339
340 // Use the cached value if it is on disk
341
342 // Convert floats to doubles to preserve precision when adding them.
343 double signalSum{0};
344 double errorSum{0};
345
346 if (m_Saveable) {
347 if (m_Saveable->wasSaved()) // There are possible problems with disk
348 // buffered events, as saving calculates
349 // averages and these averages has to be added
350 // to memory contents
351 {
352 if (!m_Saveable->isLoaded()) // events were saved, averages calculated
353 // and stored
354 {
355 // the partial data were not loaded from HDD but their averages should
356 // be calculated when loaded. Add them
357 signalSum = this->m_signal;
358 errorSum = this->m_errorSquared;
359 }
360 }
361 }
362
363 // calculate all averages from memory
364 signalSum = std::accumulate(data.cbegin(), data.cend(), signalSum,
365 [](const double &sum, const MDE &event) { return sum + event.getSignal(); });
366 errorSum = std::accumulate(data.cbegin(), data.cend(), errorSum,
367 [](const double &sum, const MDE &event) { return sum + event.getErrorSquared(); });
368
369 this->m_signal = signal_t(signalSum);
370 this->m_errorSquared = signal_t(errorSum);
371#ifdef MDBOX_TRACK_CENTROID
372 this->calculateCentroid(this->m_centroid);
373#endif
374
376 this->m_totalWeight = static_cast<double>(this->getNPoints());
377}
378
381TMDE(bool MDBox)::isDataAdded() const {
382 if (m_Saveable) {
383 if (m_Saveable->isLoaded())
384 return data.size() != m_Saveable->getFileSize();
385 }
386 return (!data.empty());
387}
388
389//-----------------------------------------------------------------------------------------------
393TMDE(void MDBox)::calculateCentroid(coord_t *centroid) const {
394 std::fill_n(centroid, nd, 0.0f);
395
396 // Signal was calculated before (when adding)
397 // Keep 0.0 if the signal is null. This avoids dividing by 0.0
398 if (this->m_signal == 0)
399 return;
400
401 for (const MDE &Evnt : data) {
402 double signal = Evnt.getSignal();
403 for (size_t d = 0; d < nd; d++) {
404 // Total up the coordinate weighted by the signal.
405 centroid[d] += Evnt.getCenter(d) * static_cast<coord_t>(signal);
406 }
407 }
408
409 // Normalize by the total signal
410 const coord_t reciprocal = 1.0f / static_cast<coord_t>(this->m_signal);
411 for (size_t d = 0; d < nd; ++d) {
412 centroid[d] *= reciprocal;
413 }
414}
415
416//-----------------------------------------------------------------------------------------------
421TMDE(void MDBox)::calculateCentroid(coord_t *centroid, const int expInfoIndex) const {
422
423 std::fill_n(centroid, nd, 0.0f);
424
425 // Signal was calculated before (when adding)
426 // Keep 0.0 if the signal is null. This avoids dividing by 0.0
427 if (this->m_signal == 0)
428 return;
429
430 for (const MDE &Evnt : data) {
431 coord_t signal = Evnt.getSignal();
432 if (Evnt.getExpInfoIndex() == expInfoIndex) {
433 for (size_t d = 0; d < nd; d++) {
434 // Total up the coordinate weighted by the signal.
435 centroid[d] += Evnt.getCenter(d) * signal;
436 }
437 }
438 }
439
440 // Normalize by the total signal
441 const coord_t reciprocal = 1.0f / static_cast<coord_t>(this->m_signal);
442 for (size_t d = 0; d < nd; ++d) {
443 centroid[d] *= reciprocal;
444 }
445}
446
447//-----------------------------------------------------------------------------------------------
453TMDE(void MDBox)::calculateDimensionStats(MDDimensionStats *stats) const {
454 for (const MDE &Evnt : data) {
455 for (size_t d = 0; d < nd; d++) {
456 stats[d].addPoint(Evnt.getCenter(d));
457 }
458 }
459}
460
476TMDE(void MDBox)::integrateSphere(Mantid::API::CoordTransform &radiusTransform, const coord_t radiusSquared,
477 signal_t &integratedSignal, signal_t &errorSquared, const coord_t innerRadiusSquared,
478 const bool useOnePercentBackgroundCorrection) const {
479 // If the box is cached to disk, you need to retrieve it
480 const std::vector<MDE> &events = this->getConstEvents();
481 if (innerRadiusSquared == 0.0) {
482 // For each MDLeanEvent
483 for (const auto &it : events) {
484 coord_t out[nd];
485 radiusTransform.apply(it.getCenter(), out);
486 if (out[0] < radiusSquared) {
487 integratedSignal += static_cast<signal_t>(it.getSignal());
488 errorSquared += static_cast<signal_t>(it.getErrorSquared());
489 }
490 }
491 } else {
492 // For each MDLeanEvent
493 using valAndErrorPair = std::pair<signal_t, signal_t>;
494 std::vector<valAndErrorPair> vals;
495 for (const auto &it : events) {
496 coord_t out[nd];
497 radiusTransform.apply(it.getCenter(), out);
498 if (out[0] < radiusSquared && out[0] > innerRadiusSquared) {
499 const auto signal = static_cast<signal_t>(it.getSignal());
500 const auto errSquared = static_cast<signal_t>(it.getErrorSquared());
501 vals.emplace_back(signal, errSquared);
502 }
503 }
504 // Sort based on signal values
505 std::sort(vals.begin(), vals.end(),
506 [](const valAndErrorPair &a, const valAndErrorPair &b) { return a.first < b.first; });
507
508 // Remove top 1% of background
509 const size_t endIndex =
510 useOnePercentBackgroundCorrection ? static_cast<size_t>(0.99 * static_cast<double>(vals.size())) : vals.size();
511
512 for (size_t k = 0; k < endIndex; k++) {
513 integratedSignal += vals[k].first;
514 errorSquared += vals[k].second;
515 }
516 }
517 // it is constant access, so no saving or fiddling with the buffer is needed.
518 // Events just can be dropped if necessary
519 // m_Saveable->releaseEvents();
520 if (m_Saveable) {
521 m_Saveable->setBusy(false);
522 }
523}
524
540TMDE(void MDBox)::integrateCylinder(Mantid::API::CoordTransform &radiusTransform, const coord_t radius,
541 const coord_t length, signal_t &signal, signal_t &errorSquared,
542 std::vector<signal_t> &signal_fit) const {
543 // If the box is cached to disk, you need to retrieve it
544 const std::vector<MDE> &events = this->getConstEvents();
545 size_t numSteps = signal_fit.size();
546 double deltaQ = length / static_cast<double>(numSteps - 1);
547
548 // For each MDLeanEvent
549 for (const auto &evnt : events) {
550 coord_t out[2]; // radius and length of cylinder
551 radiusTransform.apply(evnt.getCenter(), out);
552 if (out[0] < radius && std::fabs(out[1]) < 0.5 * length + deltaQ) {
553 // add event to appropriate y channel
554 size_t xchannel = static_cast<size_t>(std::floor(out[1] / deltaQ)) + numSteps / 2;
555 if (xchannel < numSteps)
556 signal_fit[xchannel] += static_cast<signal_t>(evnt.getSignal());
557
558 signal += static_cast<signal_t>(evnt.getSignal());
559 errorSquared += static_cast<signal_t>(evnt.getErrorSquared());
560 }
561 }
562 // it is constant access, so no saving or fiddling with the buffer is needed.
563 // Events just can be dropped if necessary
564 // m_Saveable->releaseEvents();
565 if (m_Saveable) {
566 m_Saveable->setBusy(false);
567 }
568}
569
570//-----------------------------------------------------------------------------------------------
573TMDE(coord_t *MDBox)::getCentroid() const { return this->m_centroid; }
574
575//-----------------------------------------------------------------------------------------------
586TMDE(void MDBox)::centroidSphere(Mantid::API::CoordTransform &radiusTransform, const coord_t radiusSquared,
587 coord_t *centroid, signal_t &signal) const {
588 // If the box is cached to disk, you need to retrieve it
589 const std::vector<MDE> &events = this->getConstEvents();
590
591 // For each MDLeanEvent
592 for (const auto &evnt : events) {
593 coord_t out[nd];
594 radiusTransform.apply(evnt.getCenter(), out);
595 if (out[0] < radiusSquared) {
596 coord_t eventSignal = static_cast<coord_t>(evnt.getSignal());
597 signal += eventSignal;
598 for (size_t d = 0; d < nd; d++)
599 centroid[d] += evnt.getCenter(d) * eventSignal;
600 }
601 }
602 // it is constant access, so no saving or fiddling with the buffer is needed.
603 // Events just can be dropped if necessary
604 if (m_Saveable)
605 m_Saveable->setBusy(false);
606}
607
608//-----------------------------------------------------------------------------------------------
615TMDE(void MDBox)::transformDimensions(std::vector<double> &scaling, std::vector<double> &offset) {
617 this->calculateCentroid(this->m_centroid);
618 std::vector<MDE> &events = this->getEvents();
619 for (auto &evnt : events) {
620 coord_t *center = evnt.getCenterNonConst();
621 for (size_t d = 0; d < nd; d++)
622 center[d] = (center[d] * static_cast<coord_t>(scaling[d])) + static_cast<coord_t>(offset[d]);
623 }
624 if (m_Saveable)
625 m_Saveable->setBusy(false);
626}
627
629TMDE(void MDBox)::mask() {
630 this->setSignal(API::MDMaskValue);
631 this->setErrorSquared(API::MDMaskValue);
632 m_bIsMasked = true;
633}
634
636TMDE(void MDBox)::unmask() { m_bIsMasked = false; }
637//------------------------------------------------------------------------------------------------------------------------------------------------------------
638
643TMDE(size_t MDBox)::buildAndAddEvents(const std::vector<signal_t> &sigErrSq, const std::vector<coord_t> &Coord,
644 const std::vector<uint16_t> &expInfoIndex,
645 const std::vector<uint16_t> &goniometerIndex,
646 const std::vector<uint32_t> &detectorId) {
647
648 size_t nEvents = sigErrSq.size() / 2;
649 size_t nExisiting = data.size();
650 data.reserve(nExisiting + nEvents);
651 std::lock_guard<std::mutex> _lock(this->m_dataMutex);
652 IF<MDE, nd>::EXEC(this->data, sigErrSq, Coord, expInfoIndex, goniometerIndex, detectorId, nEvents);
653
654 return 0;
655}
656
666TMDE(void MDBox)::buildAndAddEvent(const signal_t Signal, const signal_t errorSq, const std::vector<coord_t> &point,
667 uint16_t expInfoIndex, uint16_t goniometerIndex, uint32_t detectorId) {
668 std::lock_guard<std::mutex> _lock(this->m_dataMutex);
669 this->data.emplace_back(
670 IF<MDE, nd>::BUILD_EVENT(Signal, errorSq, &point[0], expInfoIndex, goniometerIndex, detectorId));
671}
672
673//-----------------------------------------------------------------------------------------------
686TMDE(void MDBox)::buildAndAddEventUnsafe(const signal_t Signal, const signal_t errorSq,
687 const std::vector<coord_t> &point, uint16_t expInfoIndex,
688 uint16_t goniometerIndex, uint32_t detectorId) {
689 this->data.emplace_back(
690 IF<MDE, nd>::BUILD_EVENT(Signal, errorSq, &point[0], expInfoIndex, goniometerIndex, detectorId));
691}
692
693//-----------------------------------------------------------------------------------------------
698TMDE(size_t MDBox)::addEvent(const MDE &Evnt) {
699 std::lock_guard<std::mutex> _lock(this->m_dataMutex);
700 this->data.emplace_back(Evnt);
701 return 1;
702}
703
704//-----------------------------------------------------------------------------------------------
712TMDE(size_t MDBox)::addEventUnsafe(const MDE &Evnt) {
713 this->data.emplace_back(Evnt);
714 return 1;
715}
716
717//-----------------------------------------------------------------------------------------------
724TMDE(size_t MDBox)::addEvents(const std::vector<MDE> &events) {
725 std::lock_guard<std::mutex> _lock(this->m_dataMutex);
726 // Copy all the events
727 this->data.insert(this->data.end(), events.cbegin(), events.cend());
728 return 0;
729}
730
739TMDE(void MDBox)::setFileBacked(const uint64_t fileLocation, const size_t fileSize, const bool markSaved) {
740 if (!m_Saveable)
741 m_Saveable = std::make_unique<MDBoxSaveable>(this);
742
743 m_Saveable->setFilePosition(fileLocation, fileSize, markSaved);
744}
747TMDE(void MDBox)::setFileBacked() {
748 if (!m_Saveable)
749 this->setFileBacked(UNDEF_UINT64, this->getDataInMemorySize(), false);
750}
751
759TMDE(void MDBox)::saveAt(API::IBoxControllerIO *const FileSaver, uint64_t position) const {
760 if (data.empty())
761 return;
762
763 if (!FileSaver)
764 throw(std::invalid_argument(" Needs defined file saver to save data to it"));
765 if (!FileSaver->isOpened())
766 throw(std::invalid_argument(" The data file has to be opened to use box SaveAt function"));
767
768 std::vector<coord_t> TabledData;
769 size_t nDataColumns;
770 double totalSignal, totalErrSq;
771
772 MDE::eventsToData(this->data, TabledData, nDataColumns, totalSignal, totalErrSq);
773
774 this->m_signal = static_cast<signal_t>(totalSignal);
775 this->m_errorSquared = static_cast<signal_t>(totalErrSq);
776#ifdef MDBOX_TRACK_CENTROID
777 this->calculateCentroid(this->m_centroid);
778#endif
779
780 FileSaver->saveBlock(TabledData, position);
781}
782
788TMDE(void MDBox)::reserveMemoryForLoad(uint64_t size) { this->data.reserve(size); }
789
800TMDE(void MDBox)::loadAndAddFrom(API::IBoxControllerIO *const FileSaver, uint64_t filePosition, size_t nEvents,
801 std::vector<coord_t> &tableDataTemp) {
802 if (nEvents == 0)
803 return;
804
805 if (!FileSaver)
806 throw(std::invalid_argument(" Needs defined file saver to load data using it"));
807 if (!FileSaver->isOpened())
808 throw(std::invalid_argument(" The data file has to be opened to use box loadAndAddFrom function"));
809
810 std::lock_guard<std::mutex> _lock(this->m_dataMutex);
811
812 tableDataTemp.clear();
813 FileSaver->loadBlock(tableDataTemp, filePosition, nEvents);
814
815 // convert data to events appending new events to existing
816 MDE::dataToEvents(tableDataTemp, data, false);
817}
818
828TMDE(void MDBox)::loadAndAddFrom(API::IBoxControllerIO *const FileSaver, uint64_t filePosition, size_t nEvents) {
829 if (nEvents == 0)
830 return;
831
832 if (!FileSaver)
833 throw(std::invalid_argument(" Needs defined file saver to load data using it"));
834 if (!FileSaver->isOpened())
835 throw(std::invalid_argument(" The data file has to be opened to use box loadAndAddFrom function"));
836
837 std::lock_guard<std::mutex> _lock(this->m_dataMutex);
838
839 m_tableData.clear();
840 FileSaver->loadBlock(m_tableData, filePosition, nEvents);
841
842 // convert data to events appending new events to existing
843 MDE::dataToEvents(m_tableData, data, false);
844}
855TMDE(void MDBox)::clearFileBacked(bool loadDiskBackedData) {
856 if (m_Saveable) {
857 if (loadDiskBackedData)
858 m_Saveable->load();
859 // tell disk buffer that there are no point of tracking this box any more.
860 this->m_BoxController->getFileIO()->objectDeleted(m_Saveable.get());
861 m_Saveable = nullptr;
862 }
863}
864
865} // namespace DataObjects
866
867} // namespace Mantid
double position
Definition GetAllEi.cpp:154
#define UNDEF_UINT64
Definition MDTypes.h:63
#define UNDEF_SIZET
Definition MDTypes.h:61
#define TMDE(decl)
Macro TMDE to make declaring template functions faster.
Definition MDTypes.h:52
This class is used by MDBox and MDGridBox in order to intelligently determine optimal behavior.
bool isFileBacked() const
Returns if current box controller is file backed.
Unique SingleValueParameter Declaration for InputNDimensions.
The header describes interface to IO Operations perfomed by the box controller May be replaced by a b...
Templated super-class of a multi-dimensional event "box".
Definition MDBoxBase.h:49
void calcCaches(const EventIterator &begin, const EventIterator &end)
Calculates caches if the events are known.
Definition MDBoxBase.h:357
virtual size_t addEventsUnsafe(const std::vector< MDE > &events)
Add all of the events contained in a vector, with:
Mantid::API::BoxController *const m_BoxController
The box splitting controller, shared with all boxes in the hierarchy.
Definition MDBoxBase.h:325
Templated class for a multi-dimensional event "box".
Definition MDBox.h:45
std::vector< MDE > vec_t
Typedef for a vector of the conatined events.
Definition MDBox.h:217
MDBox(Mantid::API::BoxController_sptr &splitter, const uint32_t depth=0, const size_t nBoxEvents=UNDEF_SIZET, const size_t boxID=UNDEF_SIZET)
Convenience Constructor/default constructor for accepting shared pointer.
Definition MDBox.hxx:44
std::vector< MDE > data
Vector of MDEvent's, in no particular order.
Definition MDBox.h:198
typename std::vector< MDE >::const_iterator EventIterator
Definition MDBox.h:60
void setFileBacked() override
Make this box file-backed but its place on the file is not identified yet.
Definition MDBox.hxx:747
A simple class holding some statistics on the distribution of events in a particular dimension.
Simple class that holds the extents (min/max) of a given dimension in a MD workspace or MDBox.
An "ImplicitFunction" defining a hyper-cuboid-shaped region in N dimensions.
An interface for objects that can be cached or saved to disk.
Definition ISaveable.h:28
The ThreadScheduler object defines how tasks are allocated to threads and in what order.
std::shared_ptr< BoxController > BoxController_sptr
Shared ptr to BoxController.
Helper class which provides the Collimation Length for SANS instruments.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition MDTypes.h:27
double signal_t
Typedef for the signal recorded in a MDBox, etc.
Definition MDTypes.h:36
STL namespace.