Mantid
Loading...
Searching...
No Matches
BoxControllerNeXusIO.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
16
17#include <H5Cpp.h>
18#include <Poco/File.h>
19
20#include <algorithm>
21#include <string>
22
23namespace Mantid::DataObjects {
24// Default headers(attributes) describing the contents of the data, written by
25// this class
26const char *EventHeaders[] = {"signal, errorSquared, center (each dim.)",
27 "signal, errorSquared, expInfoIndex, goniometerIndex, detectorId, center (each "
28 "dim.)"};
29
30std::string BoxControllerNeXusIO::g_EventGroupName("event_data");
31std::string BoxControllerNeXusIO::g_DBDataName("free_space_blocks");
32
37 : m_File(nullptr), m_ReadOnly(true), m_dataChunk(DATA_CHUNK), m_bc(bc), m_BlockStart(2, 0), m_BlockSize(2, 0),
38 m_CoordSize(sizeof(coord_t)), m_EventType(FatEvent), m_EventsVersion("1.0"),
39 m_EventDataVersion(EventDataVersion::EDVGoniometer), m_ReadConversion(noConversion) {
40 m_BlockSize[1] = 5 + m_bc->getNDims();
41
42 std::copy(std::cbegin(EventHeaders), std::cend(EventHeaders), std::back_inserter(m_EventsTypeHeaders));
43
44 m_EventsTypesSupported.resize(2);
47}
49BoxControllerNeXusIO::EventType BoxControllerNeXusIO::TypeFromString(const std::vector<std::string> &typesSupported,
50 const std::string &typeName) {
51 auto it = std::find(typesSupported.begin(), typesSupported.end(), typeName);
52 if (it == typesSupported.end())
53 throw std::invalid_argument("Unsupported event type: " + typeName + " provided ");
54
55 return static_cast<EventType>(std::distance(typesSupported.begin(), it));
56}
71void BoxControllerNeXusIO::setDataType(const size_t blockSize, const std::string &typeName) {
72 if (blockSize == 4 || blockSize == 8) {
73
74 m_CoordSize = static_cast<unsigned int>(blockSize);
76
77 switch (m_EventType) {
78 case (LeanEvent):
79 m_BlockSize[1] = 2 + m_bc->getNDims();
81 break;
82 case (FatEvent):
83 m_BlockSize[1] = 5 + m_bc->getNDims();
85 break;
86 default:
87 throw std::invalid_argument(" Unsupported event kind Identified ");
88 }
89 } else
90 throw std::invalid_argument("The class currently supports 4(float) and "
91 "8(double) event coordinates only");
92}
93
105void BoxControllerNeXusIO::getDataType(size_t &CoordSize, std::string &typeName) const {
106 CoordSize = m_CoordSize;
108}
109
118bool BoxControllerNeXusIO::openFile(const std::string &fileName, const std::string &mode) {
119 // file already opened
120 if (m_File)
121 return false;
122
123 std::lock_guard<std::mutex> _lock(m_fileMutex);
124 m_ReadOnly = true;
125 if (mode.find('w') != std::string::npos || mode.find('W') != std::string::npos) {
126 m_ReadOnly = false;
127 }
128
129 // open file if it exists or create it if not in the mode requested
130 m_fileName = API::FileFinder::Instance().getFullPath(fileName);
131 if (m_fileName.empty()) {
132 if (!m_ReadOnly) {
133 std::string filePath = Kernel::ConfigService::Instance().getString("defaultsave.directory");
134 if (filePath.empty())
135 m_fileName = fileName;
136 else
137 m_fileName = filePath + "/" + fileName;
138 } else
139 throw Kernel::Exception::FileError("Can not open file to read ", m_fileName);
140 }
141
142 auto nDims = static_cast<int>(this->m_bc->getNDims());
143
144 bool group_exists;
145 m_File = std::unique_ptr<::NeXus::File>(MDBoxFlatTree::createOrOpenMDWSgroup(
147
148 // we are in MD workspace Class group now
149 std::map<std::string, std::string> groupEntries;
150 m_File->getEntries(groupEntries);
151 if (groupEntries.find(g_EventGroupName) != groupEntries.end()) // yes, open it
153 else // create and open it
155 // we are in MDEvent group now (either created or opened)
156
157 // read if exist and create if not the group, which is responsible for saving
158 // DiskBuffer information;
160
161 if (m_ReadOnly)
163 else
165
166 return true;
167}
168
174void BoxControllerNeXusIO::copyFileTo(const std::string &destFilename) {
175 // Some OSs (observed on Windows) take an exclusive lock on the file
176 // To copy the file must be closed, copied and reopened. To avoid
177 // paying for this where not necessary first try without closing first
178 try {
179 Poco::File(this->getFileName()).copyTo(destFilename);
180 return;
181 } catch (const Poco::Exception &) {
182 try {
183 this->closeFile();
184 Poco::File(this->getFileName()).copyTo(destFilename);
185 } catch (...) {
186 // if an exception happened during the copy attempt to reopen the original
187 this->openFile(this->getFileName(), m_ReadOnly ? "r" : "w");
188 throw;
189 }
190 this->openFile(this->getFileName(), m_ReadOnly ? "r" : "w");
191 }
192}
193
197 if (m_ReadOnly)
199 "The NXdata group: " + g_EventGroupName + " does not exist in the file opened for read", m_fileName);
200
201 try {
202 m_File->makeGroup(g_EventGroupName, "NXdata", true);
203 m_File->putAttr("version", m_EventsVersion);
204 } catch (...) {
205 throw Kernel::Exception::FileError("Can not create new NXdata group: " + g_EventGroupName, m_fileName);
206 }
207}
208
212
213 m_File->openGroup(g_EventGroupName, "NXdata");
214 std::string fileGroupVersion;
215 m_File->getAttr("version", fileGroupVersion);
216
217 if (fileGroupVersion != m_EventsVersion)
218 throw Kernel::Exception::FileError("Trying to open existing data grop to write new event data but the "
219 "group with differetn version: " +
220 fileGroupVersion + " already exists ",
221 m_fileName);
222}
225
226 // Are data already there?
227 std::string EventData("event_data");
228 std::map<std::string, std::string> groupEntries;
229 m_File->getEntries(groupEntries);
230 if (groupEntries.find(EventData) != groupEntries.end()) // yes, open it
231 {
233 } else // no, create it
234 {
235 // Prepare the event data array for writing operations:
236 m_BlockSize[0] = NX_UNLIMITED;
237
238 // Now the chunk size.
239 // m_Blocksize == (number_events_to_write_at_a_time, data_items_per_event)
240 std::vector<int64_t> chunk(m_BlockSize);
241 chunk[0] = static_cast<int64_t>(m_dataChunk);
242
243 // Make and open the data
244 if (m_CoordSize == 4)
245 m_File->makeCompData("event_data", ::NeXus::FLOAT32, m_BlockSize, ::NeXus::NONE, chunk, true);
246 else
247 m_File->makeCompData("event_data", ::NeXus::FLOAT64, m_BlockSize, ::NeXus::NONE, chunk, true);
248
249 // A little bit of description for humans to read later
250 m_File->putAttr("description", m_EventsTypeHeaders[m_EventType]);
251 // disk buffer knows that the file has no events
252 this->setFileLength(0);
253 }
254}
258 // Open the data
259 m_File->openData("event_data");
260 // There are rummors that this is faster. Not sure if it is important
261 // int type = ::NeXus::FLOAT32;
262 // int rank = 0;
263 // NXgetinfo(file->getHandle(), &rank, dims, &type);
264
265 NeXus::Info info = m_File->getInfo();
266 int Type = info.type;
267
269 switch (Type) {
270 case (::NeXus::FLOAT64):
271 if (m_CoordSize == 4)
273 break;
274 case (::NeXus::FLOAT32):
275 if (m_CoordSize == 8)
277 break;
278
279 default:
280 throw Kernel::Exception::FileError("Unknown events data format ", m_fileName);
281 }
282
283 auto ndim2 = static_cast<size_t>(info.dims[1]); // number of columns
285
286 // HACK -- there is no difference between empty event dataset and the dataset
287 // with 1 event.
288 // It is unclear how to deal with this stuff but the situations, where the
289 // dataset was created and closed without writing there anything
290 // and then opened again to write data into it are probably rare.
291 uint64_t nFilePoints = info.dims[0];
292 this->setFileLength(nFilePoints);
293}
297 std::vector<uint64_t> freeSpaceBlocks;
298 this->getFreeSpaceVector(freeSpaceBlocks);
299 if (freeSpaceBlocks.empty())
300 freeSpaceBlocks.resize(2, 0); // Needs a minimum size
301
302 // // Get a vector of the free space blocks to save to the file
303 std::vector<int64_t> free_dims(2, 2);
304 free_dims[0] = int64_t(freeSpaceBlocks.size() / 2);
305 std::vector<int64_t> free_chunk(2, 2);
306 free_chunk[0] = int64_t(m_dataChunk);
307
308 std::map<std::string, std::string> groupEntries;
309 m_File->getEntries(groupEntries);
310 if (groupEntries.find(g_DBDataName) != groupEntries.end()) // data exist, open it
311 {
312 // Read the free space blocks in from the existing file
313 m_File->readData(g_DBDataName, freeSpaceBlocks);
314 this->setFreeSpaceVector(freeSpaceBlocks);
315 } else // create and open the group
316 {
317 if (m_ReadOnly)
318 throw Kernel::Exception::FileError("Attempt to create new DB group in the read-only file", m_fileName);
319 m_File->writeExtendibleData(g_DBDataName, freeSpaceBlocks, free_dims, free_chunk);
320 }
321}
322
323//-------------------------------------------------------------------------------------------------------------------------------------
328template <typename Type>
329void BoxControllerNeXusIO::saveGenericBlock(const std::vector<Type> &DataBlock, const uint64_t blockPosition) const {
330 std::vector<int64_t> start(2, 0);
331 // Specify the dimensions
332 std::vector<int64_t> dims(m_BlockSize);
333
334 std::lock_guard<std::mutex> _lock(m_fileMutex);
335 start[0] = int64_t(blockPosition);
336 dims[0] = int64_t(DataBlock.size() / this->getNDataColums());
337
338 // ugly cast but why would putSlab change the data?. This is NeXus bug which
339 // makes putSlab method non-constant
340 auto &mData = const_cast<std::vector<Type> &>(DataBlock);
341
342 {
343 m_File->putSlab<Type>(mData, start, dims);
344
345 if (blockPosition + dims[0] > this->getFileLength())
346 this->setFileLength(blockPosition + dims[0]);
347 }
348}
349
354void BoxControllerNeXusIO::saveBlock(const std::vector<float> &DataBlock, const uint64_t blockPosition) const {
355 this->saveGenericBlock(DataBlock, blockPosition);
356}
361void BoxControllerNeXusIO::saveBlock(const std::vector<double> &DataBlock, const uint64_t blockPosition) const {
362 this->saveGenericBlock(DataBlock, blockPosition);
363}
364
367
368 // Is the event of type MDLeanEvent of MDEvent
369 size_t coordSize;
370 std::string typeName;
371 getDataType(coordSize, typeName);
372
373 // Cross-validation implemented in a not very elegant way, but does the job
374 // MDLeanEvent only accepts EDVLean
375 if (typeName == MDLeanEvent<1>::getTypeName() && version != EDV::EDVLean)
376 throw std::invalid_argument("Cannot set the event data version to other than EDVLean");
377 // MDEvent cannot accept EDVLean
378 if (typeName == MDEvent<1>::getTypeName() && version == EDV::EDVLean)
379 throw std::invalid_argument("Cannot set the event data version to EDVLean");
380
381 m_EventDataVersion = version;
382}
383
384void BoxControllerNeXusIO::setEventDataVersion(const size_t &traitsCount) {
385 using EDV = EventDataVersion;
386 auto edv = static_cast<EventDataVersion>(traitsCount);
387 // sucks I couldn't create this list dynamically
388 std::initializer_list<EDV> valid_versions = {EDV::EDVLean, EDV::EDVOriginal, EDV::EDVGoniometer};
389 const auto valid_edv = std::find(std::cbegin(valid_versions), std::cend(valid_versions), edv);
390 if (valid_edv != std::cend(valid_versions)) {
391 setEventDataVersion(*valid_edv);
392 return;
393 } else {
394 // should not reach here
395 throw std::invalid_argument("Could not find a valid version");
396 }
397}
398
400 // m_BlockSize[1] is the number of data events associated to an MDLeanEvent
401 // or MDEvent object.
402 int64_t size(m_BlockSize[1]);
403 switch (m_EventDataVersion) {
405 break; // no adjusting is necessary
406 case (EventDataVersion::EDVOriginal): // we're dealing with an old Nexus file
407 size -= 1; // old Nexus file doesn't have goniometer index info
408 break;
410 break; // no adjusting is necessary
411 default:
412 throw std::runtime_error("Unknown event data version");
413 }
414 return size;
415}
416
417template <typename FloatOrDouble>
418void BoxControllerNeXusIO::adjustEventDataBlock(std::vector<FloatOrDouble> &Block,
419 const std::string &accessMode) const {
420 // check the validity of accessMode
421 const std::vector<std::string> validAccessModes{"READ", "WRITE"};
422 if (std::find(validAccessModes.begin(), validAccessModes.end(), accessMode) == validAccessModes.end())
423 throw std::runtime_error("Unknown access mode");
424
425 switch (m_EventDataVersion) {
427 break; // no adjusting is necessary
428 // we're dealing with and old Nexus file
430 size_t blockSize(static_cast<size_t>(Block.size()));
431 // number of data items in the old Nexus file associated to a single event
432 size_t eventSize(dataEventCount());
433
434 // we just read event data from an old Nexus file. Goniometer index must
435 // be inserted
436 if (accessMode == "READ") {
437 // Block size is a multiple of eventSize
438 size_t eventCount = blockSize / eventSize;
439 if (eventCount * eventSize != blockSize) // this shouldn't happen
440 throw std::runtime_error("Data block does not represent an integer number of events");
441 // Loop to insert goniometer index
442 std::vector<FloatOrDouble> backupBlock(Block);
443 Block.resize(eventCount * (eventSize + 1));
444 size_t blockCounter(0);
445 size_t backupBlockCounter(0);
446 for (size_t i = 0; i < eventCount; i++) {
447 // signal, error, and expInfoIndex occupy the first three data items
448 for (size_t j = 0; j < 3; j++) {
449 Block[blockCounter] = backupBlock[backupBlockCounter];
450 blockCounter++;
451 backupBlockCounter++;
452 }
453 Block[blockCounter] = 0; // here's the goniometer index!
454 blockCounter++;
455 for (size_t j = 3; j < eventSize; j++) {
456 Block[blockCounter] = backupBlock[backupBlockCounter];
457 blockCounter++;
458 backupBlockCounter++;
459 }
460 }
461 }
462 // we want to write the Block to an old Nexus file. Goniometer info must
463 // be removed
464 else if (accessMode == "WRITE") {
465 // Block size is a multiple of (eventSize + 1)
466 size_t eventCount = blockSize / (eventSize + 1);
467 if (eventCount * (eventSize + 1) != blockSize) // this shouldn't happen
468 throw std::runtime_error("Data block does not represent an integer number of events");
469 // Loop to remove goniometer index
470 std::vector<FloatOrDouble> backupBlock(Block);
471 Block.resize(eventCount * eventSize);
472 size_t blockCounter(0);
473 size_t backupBlockCounter(0);
474 for (size_t i = 0; i < eventCount; i++) {
475 // signal, error, and expInfoIndex occupy the first three data items
476 for (size_t j = 0; j < 3; j++) {
477 Block[blockCounter] = backupBlock[backupBlockCounter];
478 blockCounter++;
479 backupBlockCounter++;
480 }
481 backupBlockCounter++; // skip the goniometer index
482 for (size_t j = 3; j < eventSize; j++) {
483 Block[blockCounter] = backupBlock[backupBlockCounter];
484 blockCounter++;
485 backupBlockCounter++;
486 }
487 }
488 }
489 break;
490 }
492 break; // no adjusting is necessary
493 default:
494 throw std::runtime_error("Unknown event data version");
495 }
496}
497
498// explicit instantiations
499template DLLExport void BoxControllerNeXusIO::adjustEventDataBlock<float>(std::vector<float> &Block,
500 const std::string &accessMode) const;
501template DLLExport void BoxControllerNeXusIO::adjustEventDataBlock<double>(std::vector<double> &Block,
502 const std::string &accessMode) const;
503
504template <typename Type>
505void BoxControllerNeXusIO::loadGenericBlock(std::vector<Type> &Block, const uint64_t blockPosition,
506 const size_t nPoints) const {
507 if (blockPosition + nPoints > this->getFileLength())
508 throw Kernel::Exception::FileError("Attemtp to read behind the file end", m_fileName);
509
510 std::vector<int64_t> start(2, 0);
511 start[0] = static_cast<int64_t>(blockPosition);
512
513 std::vector<int64_t> size(m_BlockSize);
514 size[0] = static_cast<int64_t>(nPoints);
515 size[1] = dataEventCount(); // data item count per event in the Nexus file
516
517 std::lock_guard<std::mutex> _lock(m_fileMutex);
518
519 Block.resize(size[0] * size[1]);
520 m_File->getSlab(&Block[0], start, size);
521
522 adjustEventDataBlock(Block, "READ"); // insert goniometer info if necessary
523}
524
526template <typename FROM, typename TO> void convertFormats(const std::vector<FROM> &inData, std::vector<TO> &outData) {
527 outData.reserve(inData.size());
528 for (size_t i = 0; i < inData.size(); i++) {
529 outData.emplace_back(static_cast<TO>(inData[i]));
530 }
531}
540void BoxControllerNeXusIO::loadBlock(std::vector<float> &Block, const uint64_t blockPosition,
541 const size_t nPoints) const {
542 std::vector<double> tmp;
543 switch (m_ReadConversion) {
544 case (noConversion):
545 loadGenericBlock(Block, blockPosition, nPoints);
546 break;
547 case (doubleToFolat):
548 loadGenericBlock(tmp, blockPosition, nPoints);
549 convertFormats(tmp, Block);
550 break;
551 default:
552 throw Kernel::Exception::FileError(" Attempt to read float data from unsupported file format", m_fileName);
553 }
554}
563void BoxControllerNeXusIO::loadBlock(std::vector<double> &Block, const uint64_t blockPosition,
564 const size_t nPoints) const {
565 std::vector<float> tmp;
566 switch (m_ReadConversion) {
567 case (noConversion):
568 loadGenericBlock(Block, blockPosition, nPoints);
569 break;
570 case (floatToDouble):
571 loadGenericBlock(tmp, blockPosition, nPoints);
572 convertFormats(tmp, Block);
573 break;
574 default:
575 throw Kernel::Exception::FileError(" Attempt to read double data from unsupported file format", m_fileName);
576 }
577}
578
579//-------------------------------------------------------------------------------------------------------------------------------------
580
583 std::lock_guard<std::mutex> _lock(m_fileMutex);
584 m_File->flush();
585}
588 if (m_File) {
589 // write all file-backed data still stack in the data buffer into the file.
590 this->flushCache();
591 // lock file
592 std::lock_guard<std::mutex> _lock(m_fileMutex);
593
594 m_File->closeData(); // close events data
595 if (!m_ReadOnly) // write free space groups from the disk buffer
596 {
597 std::vector<uint64_t> freeSpaceBlocks;
598 this->getFreeSpaceVector(freeSpaceBlocks);
599 if (!freeSpaceBlocks.empty()) {
600 std::vector<int64_t> free_dims(2, 2);
601 free_dims[0] = int64_t(freeSpaceBlocks.size() / 2);
602
603 m_File->writeUpdatedData(g_DBDataName, freeSpaceBlocks, free_dims);
604 }
605 }
606
607 m_File->closeGroup(); // close events group
608 m_File->closeGroup(); // close workspace group
609 m_File->close(); // close NeXus file
610 m_File = nullptr;
611 }
612}
613
615} // namespace Mantid::DataObjects
gsl_vector * tmp
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
Definition: System.h:53
This class is used by MDBox and MDGridBox in order to intelligently determine optimal behavior.
Definition: BoxController.h:33
size_t getNDims() const
Get # of dimensions.
Definition: BoxController.h:70
DataBlock: The DataBlock class holds information about a contiguous block of spectrum numbers.
Definition: DataBlock.h:26
void setEventDataVersion(const EventDataVersion &version)
void prepareNxSdata_CurVersion()
Open the NXS data blocks for loading/saving.
EventDataVersion
The version of the "event_data" Nexus dataset.
void prepareNxSToWrite_CurVersion()
Helper function which prepares NeXus event structure to accept events
void flushData() const override
Clear NeXus internal cache.
void saveBlock(const std::vector< float > &, const uint64_t) const override
Save float data block on specific position within properly opened NeXus data array.
bool m_ReadOnly
identifier if the file open only for reading or is in read/write
std::vector< std::string > m_EventsTypeHeaders
data headers used for different events types
void loadBlock(std::vector< float > &, const uint64_t, const size_t) const override
Load float data block from the opened NeXus file.
BoxControllerNeXusIO(API::BoxController *const bc)
Constructor.
void getDataType(size_t &CoordSize, std::string &typeName) const override
As save/load operations use void data type, these function allow set up/get the type name provided fo...
static EventType TypeFromString(const std::vector< std::string > &typesSupported, const std::string &typeName)
get event type form its string representation
EventDataVersion m_EventDataVersion
"data_event" dataset version in the current Nexus file
@ doubleToFolat
conversion btween fload/double requested by the client
std::string m_fileName
full file name (with path) of the Nexis file responsible for the IO operations (as NeXus filename has...
std::unique_ptr<::NeXus::File > m_File
the file Handler responsible for Nexus IO operations;
int64_t dataEventCount(void) const
Number of data items in Nexus dataset "data_event" associated with the particular event data version.
enum Mantid::DataObjects::BoxControllerNeXusIO::EventType m_EventType
size_t m_dataChunk
The size of the events block which can be written in the neXus array at once (continuous part of the ...
const std::string & getFileName() const override
get the full file name of the file used for IO operations
void setDataType(const size_t blockSize, const std::string &typeName) override
The optional method to set up the event type and the size of the event coordinate As save/load operat...
static std::string g_DBDataName
the group name to save disk buffer data
EventType
possible event types this class understands.
enum Mantid::DataObjects::BoxControllerNeXusIO::CoordConversion m_ReadConversion
std::string m_EventsVersion
The version of the md events data block.
void OpenAndCheckEventGroup()
Open existing Event group and check the attributes necessary for this algorithm to work.
bool openFile(const std::string &fileName, const std::string &mode) override
Open the file to use in IO operations with events.
void adjustEventDataBlock(std::vector< FloatOrDouble > &Block, const std::string &accessMode) const
Insert goniometer info in a block of event data, if necessary.
void saveGenericBlock(const std::vector< Type > &DataBlock, const uint64_t blockPosition) const
Save generc data block on specific position within properly opened NeXus data array.
static std::string g_EventGroupName
the name of the Nexus data group for saving the events
void CreateEventGroup()
Create group responsible for keeping events and add necessary attributes to it.
API::BoxController *const m_bc
shared pointer to the box controller, which is repsoponsible for this IO
void getDiskBufferFileData()
Load free space blocks from the data file or create the NeXus place to read/write them.
unsigned int m_CoordSize
number of bytes in the event coordinates (coord_t length).
void copyFileTo(const std::string &destFilename) override
Copy the file contents to a new location.
std::vector< std::string > m_EventsTypesSupported
the symbolic description of the event types currently supported by the class
std::vector< int64_t > m_BlockSize
the vector, which describes the event specific data size, namely how many column an event is composed...
std::mutex m_fileMutex
lock Nexus file operations as Nexus is not thread safe
void closeFile() override
flush disk buffer data from memory and close underlying NeXus file
void loadGenericBlock(std::vector< Type > &Block, const uint64_t blockPosition, const size_t nPoints) const
Load generic data block from the opened NeXus file.
::NeXus::File * createOrOpenMDWSgroup(const std::string &fileName, int &nDims, const std::string &WSEventType, bool readOnly, bool &alreadyExists)
The function to create a NeXus MD workspace group with specified events type and number of dimensions...
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition: MDEvent.h:36
static std::string getTypeName()
Definition: MDEvent.h:199
Templated class holding data about a neutron detection event in N-dimensions (for example,...
Definition: MDLeanEvent.h:60
static std::string getTypeName()
Definition: MDLeanEvent.h:305
uint64_t getFileLength() const
Definition: DiskBuffer.h:106
void flushCache()
Flush out all the data in the memory; and writes out everything in the to-write cache.
Definition: DiskBuffer.cpp:192
void setFileLength(const uint64_t length) const
Set the length of the file that this MRU writes to.
Definition: DiskBuffer.h:111
void getFreeSpaceVector(std::vector< uint64_t > &free) const
Returns a vector with two entries per free block: position and size.
Definition: DiskBuffer.cpp:352
void setFreeSpaceVector(std::vector< uint64_t > &free)
Sets the free space map.
Definition: DiskBuffer.cpp:364
Records the filename and the description of failure.
Definition: Exception.h:98
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
void convertFormats(const std::vector< FROM > &inData, std::vector< TO > &outData)
Helper funcion which allows to convert one data fomat into another.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition: MDTypes.h:27