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) {
130 m_fileName = API::FileFinder::Instance().getFullPath(fileName);
133 std::string filePath = Kernel::ConfigService::Instance().getString(
"defaultsave.directory");
134 if (filePath.empty())
149 std::map<std::string, std::string> groupEntries;
150 m_File->getEntries(groupEntries);
178 Poco::File(this->
getFileName()).copyTo(destFilename);
180 }
catch (
const Poco::Exception &) {
183 Poco::File(this->
getFileName()).copyTo(destFilename);
213 std::string fileGroupVersion;
214 m_File->getAttr(
"version", fileGroupVersion);
218 "group with differetn version: " +
219 fileGroupVersion +
" already exists ",
226 std::string EventData(
"event_data");
227 std::map<std::string, std::string> groupEntries;
228 m_File->getEntries(groupEntries);
229 if (groupEntries.find(EventData) != groupEntries.end())
258 m_File->openData(
"event_data");
278 auto ndim2 =
static_cast<size_t>(info.
dims[1]);
286 uint64_t nFilePoints = info.
dims[0];
292 std::vector<uint64_t> freeSpaceBlocks;
294 if (freeSpaceBlocks.empty())
295 freeSpaceBlocks.resize(2, 0);
299 free_dims[0] = int64_t(freeSpaceBlocks.size() / 2);
303 std::map<std::string, std::string> groupEntries;
304 m_File->getEntries(groupEntries);
305 if (groupEntries.find(
g_DBDataName) != groupEntries.end())
323template <
typename Type>
330 start[0] = blockPosition;
335 auto &mData =
const_cast<std::vector<Type> &
>(
DataBlock);
338 m_File->putSlab<Type>(mData, start, dims);
365 std::string typeName;
371 throw std::invalid_argument(
"Cannot set the event data version to other than EDVLean");
374 throw std::invalid_argument(
"Cannot set the event data version to EDVLean");
383 std::initializer_list<EDV> valid_versions = {EDV::EDVLean, EDV::EDVOriginal, EDV::EDVGoniometer};
384 const auto valid_edv = std::find(std::cbegin(valid_versions), std::cend(valid_versions), edv);
385 if (valid_edv != std::cend(valid_versions)) {
390 throw std::invalid_argument(
"Could not find a valid version");
407 throw std::runtime_error(
"Unknown event data version");
412template <
typename FloatOrDouble>
414 const std::string &accessMode)
const {
416 const std::vector<std::string> validAccessModes{
"READ",
"WRITE"};
417 if (std::find(validAccessModes.begin(), validAccessModes.end(), accessMode) == validAccessModes.end())
418 throw std::runtime_error(
"Unknown access mode");
425 size_t blockSize(
static_cast<size_t>(Block.size()));
431 if (accessMode ==
"READ") {
433 size_t eventCount = blockSize / eventSize;
434 if (eventCount * eventSize != blockSize)
435 throw std::runtime_error(
"Data block does not represent an integer number of events");
437 std::vector<FloatOrDouble> backupBlock(Block);
438 Block.resize(eventCount * (eventSize + 1));
439 size_t blockCounter(0);
440 size_t backupBlockCounter(0);
441 for (
size_t i = 0; i < eventCount; i++) {
443 for (
size_t j = 0; j < 3; j++) {
444 Block[blockCounter] = backupBlock[backupBlockCounter];
446 backupBlockCounter++;
448 Block[blockCounter] = 0;
450 for (
size_t j = 3; j < eventSize; j++) {
451 Block[blockCounter] = backupBlock[backupBlockCounter];
453 backupBlockCounter++;
459 else if (accessMode ==
"WRITE") {
461 size_t eventCount = blockSize / (eventSize + 1);
462 if (eventCount * (eventSize + 1) != blockSize)
463 throw std::runtime_error(
"Data block does not represent an integer number of events");
465 std::vector<FloatOrDouble> backupBlock(Block);
466 Block.resize(eventCount * eventSize);
467 size_t blockCounter(0);
468 size_t backupBlockCounter(0);
469 for (
size_t i = 0; i < eventCount; i++) {
471 for (
size_t j = 0; j < 3; j++) {
472 Block[blockCounter] = backupBlock[backupBlockCounter];
474 backupBlockCounter++;
476 backupBlockCounter++;
477 for (
size_t j = 3; j < eventSize; j++) {
478 Block[blockCounter] = backupBlock[backupBlockCounter];
480 backupBlockCounter++;
489 throw std::runtime_error(
"Unknown event data version");
494template DLLExport void BoxControllerNeXusIO::adjustEventDataBlock<float>(std::vector<float> &Block,
495 const std::string &accessMode)
const;
496template DLLExport void BoxControllerNeXusIO::adjustEventDataBlock<double>(std::vector<double> &Block,
497 const std::string &accessMode)
const;
499template <
typename Type>
501 const size_t nPoints)
const {
506 start[0] = blockPosition;
514 Block.resize(size[0] * size[1]);
515 m_File->getSlab(&Block[0], start, size);
521template <
typename FROM,
typename TO>
void convertFormats(
const std::vector<FROM> &inData, std::vector<TO> &outData) {
522 outData.reserve(inData.size());
523 for (
size_t i = 0; i < inData.size(); i++) {
524 outData.emplace_back(
static_cast<TO
>(inData[i]));
533 const size_t nPoints)
const {
534 std::vector<double>
tmp;
553 const size_t nPoints)
const {
554 std::vector<float>
tmp;
586 std::vector<uint64_t> freeSpaceBlocks;
588 if (!freeSpaceBlocks.empty()) {
constexpr Mantid::Nexus::dimsize_t NX_UNLIMITED(-1)
#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)
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 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 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::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.