Newer
Older
#ifndef MANTID_DATAOBJECTS_BOXCONTROLLER_NEXUSS_IO_H
#define MANTID_DATAOBJECTS_BOXCONTROLLER_NEXUSS_IO_H
#include "MantidAPI/IBoxControllerIO.h"
#include "MantidAPI/BoxController.h"
#include "MantidKernel/DiskBuffer.h"
namespace DataObjects {
//===============================================================================================
/** The class responsible for saving events into nexus file using generic box
controller interface
* Expected to provide thread-safe file access.
@date March 15, 2013
Copyright © 2008-2010 ISIS Rutherford Appleton Laboratory, NScD Oak
Ridge National Laboratory & European Spallation Source
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>.
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport BoxControllerNeXusIO : public API::IBoxControllerIO {
public:
Lamar Moore
committed
BoxControllerNeXusIO(API::BoxController *const bc);
///@return true if the file to write events is opened and false otherwise
bool isOpened() const override { return m_File != nullptr; }
/// get the full file name of the file used for IO operations
const std::string &getFileName() const override { return m_fileName; }
/**Return the size of the NeXus data block used in NeXus data array*/
size_t getDataChunk() const override { return m_dataChunk; }
bool openFile(const std::string &fileName, const std::string &mode) override;
void saveBlock(const std::vector<float> & /* DataBlock */,
void loadBlock(std::vector<float> & /* Block */,
const uint64_t /*blockPosition*/,
const size_t /*BlockSize*/) const override;
void saveBlock(const std::vector<double> & /* DataBlock */,
void loadBlock(std::vector<double> & /* Block */,
const uint64_t /*blockPosition*/,
const size_t /*BlockSize*/) const override;
void flushData() const override;
void closeFile() override;
~BoxControllerNeXusIO() override;
// Auxiliary functions. Used to change default state of this object which is
// not fully supported. Should be replaced by some IBoxControllerIO factory
Lamar Moore
committed
void setDataType(const size_t blockSize,
Lamar Moore
committed
void getDataType(size_t &CoordSize, std::string &typeName) const override;
//------------------------------------------------------------------------------------------------------------------------
// Auxiliary functions (non-virtual, used for testing)
int64_t getNDataColums() const { return m_BlockSize[1]; }
// get pointer to the Nexus file --> compatribility testing only.
::NeXus::File *getFile() { return m_File; }
private:
/// Default size of the events block which can be written in the NeXus array
/// at once identified by efficiency or some other external reasons
enum { DATA_CHUNK = 10000 };
/// full file name (with path) of the Nexis file responsible for the IO
/// operations (as NeXus filename has very strange properties and often
/// truncated to 64 bytes)
std::string m_fileName;
/// the file Handler responsible for Nexus IO operations;
::NeXus::File *m_File;
/// identifier if the file open only for reading or is in read/write
bool m_ReadOnly;
/// The size of the events block which can be written in the neXus array at
/// once (continious part of the data block)
size_t m_dataChunk;
/// shared pointer to the box controller, which is repsoponsible for this IO
API::BoxController *const m_bc;
//------
/// the start of the current data block to read from. It related to current
/// physical representation of the data in NeXus file
std::vector<int64_t> m_BlockStart;
/// the vector, which describes the event specific data size, namely how many
/// column an event is composed into and this class reads/writres
std::vector<int64_t> m_BlockSize;
/// lock Nexus file operations as Nexus is not thread safe
mutable std::mutex m_fileMutex;
// Mainly static information which may be split into different IO classes
// selected through chein of responsibility.
/// number of bytes in the event coorinates (coord_t length). Set by
/// setDataType but can be defined statically with coord_t
unsigned int m_CoordSize;
/// possible event types this class understands. The enum numbers have to
/// correspond to the numbers of symbolic event types,
/// defined in EVENT_TYPES_SUPPORTED vector
enum EventType {
LeanEvent = 0, //< the event consisting of signal error and event coordinate
FatEvent =
1 //< the event having the same as lean event plus RunID and detID
/// the type of event (currently MD event or MDLean event this class deals
/// with. )
} m_EventType;
/// The version of the md events data block
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
std::string m_EventsVersion;
/// the symblolic description of the event types currently supported by the
/// class
std::vector<std::string> m_EventsTypesSupported;
/// data headers used for different events types
std::vector<std::string> m_EventsTypeHeaders;
/// the name of the Nexus data group for saving the events
static std::string g_EventGroupName;
/// the group name to save disk buffer data
static std::string g_DBDataName;
// helper functions:
// prepare to write event nexus data in current data version format
void CreateEventGroup();
void OpenAndCheckEventGroup();
void getDiskBufferFileData();
void prepareNxSToWrite_CurVersion();
void prepareNxSdata_CurVersion();
// get the event type from event name
static EventType
TypeFromString(const std::vector<std::string> &typesSupported,
const std::string typeName);
/// the enum, which suggests the way (currently)two possible data types are
/// converted to each other
enum CoordConversion {
noConversion,
floatToDouble,
doubleToFolat
/// conversion btween fload/double requested by the client
} m_ReadConversion;
template <typename Type>
void saveGenericBlock(const std::vector<Type> &DataBlock,
const uint64_t blockPosition) const;
template <typename Type>
void loadGenericBlock(std::vector<Type> &Block, const uint64_t blockPosition,
Lamar Moore
committed
const size_t nPoints) const;
}
}