26const char *
EventHeaders[] = {
"signal, errorSquared, center (each dim.)",
27 "signal, errorSquared, expInfoIndex, goniometerIndex, detectorId, center (each "
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) {
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 ");
55 return static_cast<EventType>(std::distance(typesSupported.begin(), it));
72 if (blockSize == 4 || blockSize == 8) {
87 throw std::invalid_argument(
" Unsupported event kind Identified ");
90 throw std::invalid_argument(
"The class currently supports 4(float) and "
91 "8(double) event coordinates only");
125 if (mode.find(
'w') != std::string::npos || mode.find(
'W') != std::string::npos) {
134 if (filePath.empty())
149 std::map<std::string, std::string> groupEntries;
150 m_File->getEntries(groupEntries);
179 Poco::File(this->
getFileName()).copyTo(destFilename);
181 }
catch (
const Poco::Exception &) {
184 Poco::File(this->
getFileName()).copyTo(destFilename);
214 std::string fileGroupVersion;
215 m_File->getAttr(
"version", fileGroupVersion);
219 "group with differetn version: " +
220 fileGroupVersion +
" already exists ",
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())
245 m_File->makeCompData(
"event_data", ::NeXus::FLOAT32,
m_BlockSize, ::NeXus::NONE, chunk,
true);
247 m_File->makeCompData(
"event_data", ::NeXus::FLOAT64,
m_BlockSize, ::NeXus::NONE, chunk,
true);
259 m_File->openData(
"event_data");
265 NeXus::Info info =
m_File->getInfo();
266 int Type = info.type;
270 case (::NeXus::FLOAT64):
274 case (::NeXus::FLOAT32):
283 auto ndim2 =
static_cast<size_t>(info.dims[1]);
291 uint64_t nFilePoints = info.dims[0];
297 std::vector<uint64_t> freeSpaceBlocks;
299 if (freeSpaceBlocks.empty())
300 freeSpaceBlocks.resize(2, 0);
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);
308 std::map<std::string, std::string> groupEntries;
309 m_File->getEntries(groupEntries);
310 if (groupEntries.find(
g_DBDataName) != groupEntries.end())
328template <
typename Type>
330 std::vector<int64_t> start(2, 0);
335 start[0] = int64_t(blockPosition);
336 dims[0] = int64_t(
DataBlock.size() / this->getNDataColums());
340 auto &mData =
const_cast<std::vector<Type> &
>(
DataBlock);
343 m_File->putSlab<Type>(mData, start, dims);
370 std::string typeName;
376 throw std::invalid_argument(
"Cannot set the event data version to other than EDVLean");
379 throw std::invalid_argument(
"Cannot set the event data version to EDVLean");
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)) {
395 throw std::invalid_argument(
"Could not find a valid version");
412 throw std::runtime_error(
"Unknown event data version");
417template <
typename FloatOrDouble>
419 const std::string &accessMode)
const {
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");
430 size_t blockSize(
static_cast<size_t>(Block.size()));
436 if (accessMode ==
"READ") {
438 size_t eventCount = blockSize / eventSize;
439 if (eventCount * eventSize != blockSize)
440 throw std::runtime_error(
"Data block does not represent an integer number of events");
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++) {
448 for (
size_t j = 0; j < 3; j++) {
449 Block[blockCounter] = backupBlock[backupBlockCounter];
451 backupBlockCounter++;
453 Block[blockCounter] = 0;
455 for (
size_t j = 3; j < eventSize; j++) {
456 Block[blockCounter] = backupBlock[backupBlockCounter];
458 backupBlockCounter++;
464 else if (accessMode ==
"WRITE") {
466 size_t eventCount = blockSize / (eventSize + 1);
467 if (eventCount * (eventSize + 1) != blockSize)
468 throw std::runtime_error(
"Data block does not represent an integer number of events");
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++) {
476 for (
size_t j = 0; j < 3; j++) {
477 Block[blockCounter] = backupBlock[backupBlockCounter];
479 backupBlockCounter++;
481 backupBlockCounter++;
482 for (
size_t j = 3; j < eventSize; j++) {
483 Block[blockCounter] = backupBlock[backupBlockCounter];
485 backupBlockCounter++;
494 throw std::runtime_error(
"Unknown event data version");
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;
504template <
typename Type>
506 const size_t nPoints)
const {
510 std::vector<int64_t> start(2, 0);
511 start[0] =
static_cast<int64_t
>(blockPosition);
514 size[0] =
static_cast<int64_t
>(nPoints);
519 Block.resize(size[0] * size[1]);
520 m_File->getSlab(&Block[0], start, size);
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]));
541 const size_t nPoints)
const {
542 std::vector<double>
tmp;
564 const size_t nPoints)
const {
565 std::vector<float>
tmp;
597 std::vector<uint64_t> freeSpaceBlocks;
599 if (!freeSpaceBlocks.empty()) {
600 std::vector<int64_t> free_dims(2, 2);
601 free_dims[0] = int64_t(freeSpaceBlocks.size() / 2);
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
This class is used by MDBox and MDGridBox in order to intelligently determine optimal behavior.
size_t getNDims() const
Get # of dimensions.
DataBlock: The DataBlock class holds information about a contiguous block of spectrum numbers.
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
~BoxControllerNeXusIO() override
@ 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,...
static std::string getTypeName()
Templated class holding data about a neutron detection event in N-dimensions (for example,...
static std::string getTypeName()
uint64_t getFileLength() const
void flushCache()
Flush out all the data in the memory; and writes out everything in the to-write cache.
void setFileLength(const uint64_t length) const
Set the length of the file that this MRU writes to.
void getFreeSpaceVector(std::vector< uint64_t > &free) const
Returns a vector with two entries per free block: position and size.
void setFreeSpaceVector(std::vector< uint64_t > &free)
Sets the free space map.
Records the filename and the description of failure.
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.
const char * EventHeaders[]
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...