12#include "MantidDataObjects/DllConfig.h"
27const char *
EventHeaders[] = {
"signal, errorSquared, center (each dim.)",
28 "signal, errorSquared, expInfoIndex, goniometerIndex, detectorId, center (each "
38 : m_File(nullptr), m_ReadOnly(true), m_dataChunk(DATA_CHUNK), m_bc(bc), m_BlockStart(2, 0), m_BlockSize(2, 0),
39 m_CoordSize(sizeof(
coord_t)), m_EventType(FatEvent), m_EventsVersion(
"1.0"),
40 m_EventDataVersion(
EventDataVersion::EDVGoniometer), m_ReadConversion(noConversion) {
51 const std::string &typeName) {
52 auto it = std::find(typesSupported.begin(), typesSupported.end(), typeName);
53 if (it == typesSupported.end())
54 throw std::invalid_argument(
"Unsupported event type: " + typeName +
" provided ");
56 return static_cast<EventType>(std::distance(typesSupported.begin(), it));
73 if (blockSize == 4 || blockSize == 8) {
88 throw std::invalid_argument(
" Unsupported event kind Identified ");
91 throw std::invalid_argument(
"The class currently supports 4(float) and "
92 "8(double) event coordinates only");
126 if (mode.find(
'w') != std::string::npos || mode.find(
'W') != std::string::npos) {
131 m_fileName = API::FileFinder::Instance().getFullPath(fileName).string();
134 std::string filePath = Kernel::ConfigService::Instance().getString(
"defaultsave.directory");
135 if (filePath.empty())
150 std::map<std::string, std::string> groupEntries;
151 m_File->getEntries(groupEntries);
179 std::filesystem::copy_file(this->
getFileName(), destFilename, std::filesystem::copy_options::overwrite_existing);
181 }
catch (
const std::filesystem::filesystem_error &) {
184 std::filesystem::copy_file(this->
getFileName(), destFilename, std::filesystem::copy_options::overwrite_existing);
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())
259 m_File->openData(
"event_data");
279 auto ndim2 =
static_cast<size_t>(info.
dims[1]);
287 uint64_t nFilePoints = info.
dims[0];
293 std::vector<uint64_t> freeSpaceBlocks;
295 if (freeSpaceBlocks.empty())
296 freeSpaceBlocks.resize(2, 0);
300 free_dims[0] = int64_t(freeSpaceBlocks.size() / 2);
304 std::map<std::string, std::string> groupEntries;
305 m_File->getEntries(groupEntries);
306 if (groupEntries.find(
g_DBDataName) != groupEntries.end())
324template <
typename Type>
331 start[0] = blockPosition;
336 auto &mData =
const_cast<std::vector<Type> &
>(
DataBlock);
339 m_File->putSlab<Type>(mData, start, dims);
366 std::string typeName;
372 throw std::invalid_argument(
"Cannot set the event data version to other than EDVLean");
375 throw std::invalid_argument(
"Cannot set the event data version to EDVLean");
384 std::initializer_list<EDV> valid_versions = {EDV::EDVLean, EDV::EDVOriginal, EDV::EDVGoniometer};
385 const auto valid_edv = std::find(std::cbegin(valid_versions), std::cend(valid_versions), edv);
386 if (valid_edv != std::cend(valid_versions)) {
391 throw std::invalid_argument(
"Could not find a valid version");
408 throw std::runtime_error(
"Unknown event data version");
413template <
typename FloatOrDouble>
415 const std::string &accessMode)
const {
417 const std::vector<std::string> validAccessModes{
"READ",
"WRITE"};
418 if (std::find(validAccessModes.begin(), validAccessModes.end(), accessMode) == validAccessModes.end())
419 throw std::runtime_error(
"Unknown access mode");
426 size_t blockSize(
static_cast<size_t>(Block.size()));
432 if (accessMode ==
"READ") {
434 size_t eventCount = blockSize / eventSize;
435 if (eventCount * eventSize != blockSize)
436 throw std::runtime_error(
"Data block does not represent an integer number of events");
438 std::vector<FloatOrDouble> backupBlock(Block);
439 Block.resize(eventCount * (eventSize + 1));
440 size_t blockCounter(0);
441 size_t backupBlockCounter(0);
442 for (
size_t i = 0; i < eventCount; i++) {
444 for (
size_t j = 0; j < 3; j++) {
445 Block[blockCounter] = backupBlock[backupBlockCounter];
447 backupBlockCounter++;
449 Block[blockCounter] = 0;
451 for (
size_t j = 3; j < eventSize; j++) {
452 Block[blockCounter] = backupBlock[backupBlockCounter];
454 backupBlockCounter++;
460 else if (accessMode ==
"WRITE") {
462 size_t eventCount = blockSize / (eventSize + 1);
463 if (eventCount * (eventSize + 1) != blockSize)
464 throw std::runtime_error(
"Data block does not represent an integer number of events");
466 std::vector<FloatOrDouble> backupBlock(Block);
467 Block.resize(eventCount * eventSize);
468 size_t blockCounter(0);
469 size_t backupBlockCounter(0);
470 for (
size_t i = 0; i < eventCount; i++) {
472 for (
size_t j = 0; j < 3; j++) {
473 Block[blockCounter] = backupBlock[backupBlockCounter];
475 backupBlockCounter++;
477 backupBlockCounter++;
478 for (
size_t j = 3; j < eventSize; j++) {
479 Block[blockCounter] = backupBlock[backupBlockCounter];
481 backupBlockCounter++;
490 throw std::runtime_error(
"Unknown event data version");
495template MANTID_DATAOBJECTS_DLL
void
496BoxControllerNeXusIO::adjustEventDataBlock<float>(std::vector<float> &Block,
const std::string &accessMode)
const;
497template MANTID_DATAOBJECTS_DLL
void
498BoxControllerNeXusIO::adjustEventDataBlock<double>(std::vector<double> &Block,
const std::string &accessMode)
const;
500template <
typename Type>
502 const size_t nPoints)
const {
507 start[0] = blockPosition;
515 Block.resize(size[0] * size[1]);
516 m_File->getSlab(&Block[0], start, size);
522template <
typename FROM,
typename TO>
void convertFormats(
const std::vector<FROM> &inData, std::vector<TO> &outData) {
523 outData.reserve(inData.size());
524 for (
size_t i = 0; i < inData.size(); i++) {
525 outData.emplace_back(
static_cast<TO
>(inData[i]));
534 const size_t nPoints)
const {
535 std::vector<double>
tmp;
554 const size_t nPoints)
const {
555 std::vector<float>
tmp;
587 std::vector<uint64_t> freeSpaceBlocks;
589 if (!freeSpaceBlocks.empty()) {
constexpr Mantid::Nexus::dimsize_t NX_UNLIMITED(-1)
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)
Nexus::DimVector m_BlockSize
the vector, which describes the event specific data size, namely how many column an event is composed...
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...
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 adjustEventDataBlock(std::vector< FloatOrDouble > &Block, const std::string &accessMode) const
Insert goniometer info in a block of event data, if necessary.
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
uint64_t dataEventCount(void) const
Number of data items in Nexus dataset "data_event" associated with the particular event data version.
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.
std::unique_ptr< Nexus::File > m_File
the file Handler responsible for Nexus IO operations;
bool openFile(const std::string &fileName, const std::string &mode) override
Open the file to use in IO operations with events.
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::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.
static Mantid::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 > const &free)
Sets the free space map.
Records the filename and the description of failure.
The primitive types published by this API.
static unsigned short constexpr FLOAT32
static unsigned short constexpr FLOAT64
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[]
std::vector< dimsize_t > DimVector
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
This structure holds the type and dimensions of a primative field/array.
DimVector dims
The dimensions of the file.
NXnumtype type
The primative type for the field.