/* ------------------------------------------------------------------ This file is part of the Open Ephys GUI Copyright (C) 2013 Florian Franzen ------------------------------------------------------------------ This program 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. This program 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/>. */ #ifndef HDF5FILEFORMAT_H_INCLUDED #define HDF5FILEFORMAT_H_INCLUDED #include "../../JuceLibraryCode/JuceHeader.h" class HDF5RecordingData; namespace H5 { class DataSet; class H5File; class DataType; } struct HDF5RecordingInfo { String name; int64 start_time; uint32 start_sample; float sample_rate; uint32 bit_depth; }; class HDF5FileBase { public: HDF5FileBase(); ~HDF5FileBase(); int open(); void close(); virtual String getFileName() = 0; bool isOpen() const; typedef enum DataTypes { U8, U16, U32, U64, I8, I16, I32, I64, F32} DataTypes; static H5::DataType getNativeType(DataTypes type); static H5::DataType getH5Type(DataTypes type); protected: virtual int createFileStructure() = 0; int setAttribute(DataTypes type, void* data, String path, String name); int setAttributeStr(String value, String path, String name); int createGroup(String path); HDF5RecordingData* getDataSet(String path); //aliases for createDataSet HDF5RecordingData* createDataSet(DataTypes type, int sizeX, int chunkX, String path); HDF5RecordingData* createDataSet(DataTypes type, int sizeX, int sizeY, int chunkX, String path); HDF5RecordingData* createDataSet(DataTypes type, int sizeX, int sizeY, int sizeZ, int chunkX, String path); HDF5RecordingData* createDataSet(DataTypes type, int sizeX, int sizeY, int sizeZ, int chunkX, int chunkY, String path); bool readyToOpen; private: //create an extendable dataset HDF5RecordingData* createDataSet(DataTypes type, int dimension, int* size, int* chunking, String path); int open(bool newfile); ScopedPointer<H5::H5File> file; bool opened; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HDF5FileBase); }; class HDF5RecordingData { public: HDF5RecordingData(H5::DataSet* data); ~HDF5RecordingData(); int writeDataBlock(int xDataSize, HDF5FileBase::DataTypes type, void* data); int writeDataBlock(int xDataSize, int yDataSize, HDF5FileBase::DataTypes type, void* data); int prepareDataBlock(int xDataSize); int writeDataRow(int yPos, int xDataSize, HDF5FileBase::DataTypes type, void* data); private: int xPos; int xChunkSize; int size[3]; int dimension; int rowXPos; int rowDataSize; ScopedPointer<H5::DataSet> dSet; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HDF5RecordingData); }; class KWDFile : public HDF5FileBase { public: KWDFile(int processorNumber, String basename); KWDFile(); ~KWDFile(); void initFile(int processorNumber, String basename); void startNewRecording(int recordingNumber, int nChannels, HDF5RecordingInfo* info); void stopRecording(); void writeBlockData(int16* data, int nSamples); void writeRowData(int16* data, int nSamples); String getFileName(); protected: int createFileStructure(); private: int recordingNumber; int nChannels; int curChan; String filename; ScopedPointer<HDF5RecordingData> recdata; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWDFile); }; class KWIKFile : public HDF5FileBase { public: KWIKFile(String basename); KWIKFile(); ~KWIKFile(); void initFile(String basename); void startNewRecording(int recordingNumber, HDF5RecordingInfo* info); void stopRecording(); void writeEvent(int type, uint8 id, uint8 processor, uint8 channel, uint64 timestamp); void addKwdFile(String filename); void addEventType(String name); String getFileName(); protected: int createFileStructure(); private: int recordingNumber; String filename; OwnedArray<HDF5RecordingData> timeStamps; OwnedArray<HDF5RecordingData> recordings; OwnedArray<HDF5RecordingData> eventID; OwnedArray<HDF5RecordingData> nodeID; OwnedArray<HDF5RecordingData> channelID; Array<String> eventNames; int kwdIndex; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWIKFile); }; class KWXFile : public HDF5FileBase { public: KWXFile(String basename); KWXFile(); ~KWXFile(); void initFile(String basename); void startNewRecording(int recordingNumber); void stopRecording(); void addChannelGroup(int nChannels); void resetChannels(); void writeSpike(int groupIndex, int nSamples, const uint16* data, uint64 timestamp); String getFileName(); protected: int createFileStructure(); private: int createChannelGroup(int index); int recordingNumber; String filename; OwnedArray<HDF5RecordingData> spikeArray; OwnedArray<HDF5RecordingData> recordingArray; OwnedArray<HDF5RecordingData> timeStamps; Array<int> channelArray; int numElectrodes; int16* transformVector; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(KWXFile); }; #endif // HDF5FILEFORMAT_H_INCLUDED