diff --git a/Source/Processors/HDF5FileFormat.cpp b/Source/Processors/HDF5FileFormat.cpp index aa4713d33cc22dfa66880a1ffc67cfc973f85831..36cadc1a12d4718977b9784f9ad5a4362d87df27 100644 --- a/Source/Processors/HDF5FileFormat.cpp +++ b/Source/Processors/HDF5FileFormat.cpp @@ -146,21 +146,21 @@ int HDF5FileBase::setAttributeStr(String value, String path, String name) Attribute attr; if (!opened) return -1; - - StrType type(PredType::C_S1, H5T_VARIABLE); + + StrType type(PredType::C_S1, value.length()); try { loc = file->openGroup(path.toUTF8()); if (loc.attrExists(name.toUTF8())) { - attr = loc.openAttribute(name.toUTF8()); + //attr = loc.openAttribute(name.toUTF8()); + return -1; //string attributes cannot change size easily, better not allow overwritting. } else { DataSpace attr_dataspace(H5S_SCALAR); attr = loc.createAttribute(name.toUTF8(), type, attr_dataspace); } - attr.write(type,value.toUTF8()); } catch (GroupIException error) { @@ -474,13 +474,18 @@ void KWDFile::initFile(int processorNumber, String basename) readyToOpen=true; } -void KWDFile::startNewRecording(int recordingNumber, int nChannels) +void KWDFile::startNewRecording(int recordingNumber, int nChannels, HDF5RecordingInfo* info) { this->recordingNumber = recordingNumber; this->nChannels = nChannels; String recordPath = String("/recordings/")+String(recordingNumber); CHECK_ERROR(createGroup(recordPath)); + CHECK_ERROR(setAttributeStr(info->name,recordPath,String("name"))); + CHECK_ERROR(setAttribute(I64,&(info->start_time),recordPath,String("start_time"))); + CHECK_ERROR(setAttribute(U32,&(info->start_sample),recordPath,String("start_sample"))); + CHECK_ERROR(setAttribute(F32,&(info->sample_rate),recordPath,String("sample_rate"))); + CHECK_ERROR(setAttribute(F32,&(info->bit_depth),recordPath,String("bit_depth"))); recdata = createDataSet(I16,BLOCK_XSIZE,nChannels,CHUNK_XSIZE,recordPath+"/data"); if (!recdata.get()) std::cerr << "Error creating data set" << std::endl; diff --git a/Source/Processors/HDF5FileFormat.h b/Source/Processors/HDF5FileFormat.h index 6bfdf8ecb7e64e0fa82725dd71fbec492687ceee..003e5411b8842e0967db7fba26138b3fec7ce8d8 100644 --- a/Source/Processors/HDF5FileFormat.h +++ b/Source/Processors/HDF5FileFormat.h @@ -33,6 +33,14 @@ class H5File; class DataType; } +struct HDF5RecordingInfo { + String name; + int64 start_time; + uint32 start_sample; + float sample_rate; + float bit_depth; +}; + class HDF5FileBase { public: @@ -99,7 +107,7 @@ public: KWDFile(); ~KWDFile(); void initFile(int processorNumber, String basename); - void startNewRecording(int recordingNumber, int nChannels); + void startNewRecording(int recordingNumber, int nChannels, HDF5RecordingInfo* info); void stopRecording(); void writeBlockData(int16* data, int nSamples); void writeRowData(int16* data, int nSamples); diff --git a/Source/Processors/HDF5Recording.cpp b/Source/Processors/HDF5Recording.cpp index 10ecb7c9031fc478964fe15349242a4422b84f6f..673272fe5a7293d3747dd42b8e856de6b7ed7a01 100644 --- a/Source/Processors/HDF5Recording.cpp +++ b/Source/Processors/HDF5Recording.cpp @@ -26,6 +26,7 @@ HDF5Recording::HDF5Recording() : processorIndex(-1) { + timestamp = 0; scaledBuffer = new float[MAX_BUFFER_SIZE]; intBuffer = new int16[MAX_BUFFER_SIZE]; } @@ -36,8 +37,17 @@ HDF5Recording::~HDF5Recording() delete intBuffer; } +void HDF5Recording::updateTimeStamp(int64 timestamp) +{ + this->timestamp = timestamp; +} + void HDF5Recording::registerProcessor(GenericProcessor *proc) { + HDF5RecordingInfo* info = new HDF5RecordingInfo(); + info->sample_rate = proc->getSampleRate(); + info->bit_depth = proc->channels[0]->bitVolts; + infoArray.add(info); fileArray.add(new KWDFile()); activeChannelCount.add(0); processorIndex++; @@ -49,6 +59,7 @@ void HDF5Recording::resetChannels() fileArray.clear(); activeChannelCount.clear(); processorMap.clear(); + infoArray.clear(); } void HDF5Recording::addChannel(int index, Channel* chan) @@ -75,7 +86,10 @@ void HDF5Recording::openFiles(File rootFolder, int recordingNumber) { if (fileArray[i]->isOpen()) { - fileArray[i]->startNewRecording(recordingNumber,activeChannelCount[i]); + infoArray[i]->name = String("Open-Ephys Recording #") + String(recordingNumber); + infoArray[i]->start_time = timestamp; + infoArray[i]->start_sample = 0; + fileArray[i]->startNewRecording(recordingNumber,activeChannelCount[i],infoArray[i]); } } } diff --git a/Source/Processors/HDF5Recording.h b/Source/Processors/HDF5Recording.h index 1b6eff443151b9cf7cfcfd6d4c347cee01340d44..642482efaa2ab52846c728089eb7f28c2dfcb40d 100644 --- a/Source/Processors/HDF5Recording.h +++ b/Source/Processors/HDF5Recording.h @@ -41,6 +41,7 @@ public: void writeSpike(const SpikeObject& spike, int electrodeIndex); void registerProcessor(GenericProcessor* processor); void resetChannels(); + void updateTimeStamp(int64 timestamp); private: @@ -49,8 +50,10 @@ private: Array<int> processorMap; Array<int> activeChannelCount; OwnedArray<KWDFile> fileArray; + OwnedArray<HDF5RecordingInfo> infoArray; float* scaledBuffer; int16* intBuffer; + int64 timestamp; };