38 LOGGER(
mlog,
"M3Stream" );
42 fDoReadRecord( NULL ),
43 fDoWriteRecord( NULL ),
44 fIsInitialized( false ),
45 fRecordsAccessed( false ),
46 fDataTypeSize( aHeader.GetDataTypeSize() ),
47 fSampleSize( aHeader.GetSampleSize() ),
48 fStrRecNBytes( aHeader.GetNChannels() * aHeader.GetRecordSize() * aHeader.GetSampleSize() * aHeader.GetDataTypeSize() ),
49 fStrRecSize( aHeader.GetNChannels() * aHeader.GetRecordSize() ),
50 fChanRecNBytes( aHeader.GetRecordSize() * aHeader.GetSampleSize() * aHeader.GetDataTypeSize() ),
51 fChanRecSize( aHeader.GetRecordSize() ),
52 fChanRecLength( (double)aHeader.GetRecordSize() / ((double)aHeader.GetAcquisitionRate() * 1.e-3) ),
54 fNChannels( aHeader.GetNChannels() ),
55 fChannelRecords( new
M3Record[ aHeader.GetNChannels() ] ),
58 fRecordCountInAcq( 0 ),
60 fAcqFirstRecTime( 0 ),
62 fAcqFirstRecTimes( NULL ),
63 fAcqFirstRecIds( NULL ),
64 fDataInterleaved( aHeader.GetChannelFormat() ==
sInterleaved ),
65 fAccessFormat( aAccessFormat ),
67 fRecordCountInFile( 0 ),
69 fFirstRecordInFile( 0 ),
70 fH5StreamParentLoc( new H5::Group( aH5StreamsLoc->openGroup( aHeader.GetLabel() ) ) ),
72 fH5CurrentAcqDataSet( NULL ),
73 fH5DataSpaceUser( NULL ),
74 fMutexPtr( new
std::mutex() )
76 LDEBUG(
mlog,
"Creating stream for <" << aHeader.GetLabel() <<
">" );
144 H5E_auto2_t tAutoPrintFunc;
153 H5::Exception::getAutoPrint( tAutoPrintFunc, &tClientData );
154 H5::Exception::dontPrint();
157 LDEBUG(
mlog,
"Opened acquisition group in <read> mode" );
160 H5::Exception::setAutoPrint( tAutoPrintFunc, tClientData );
170 catch( H5::Exception& )
172 throw M3Exception() <<
"Acquisitions group is not properly setup for reading\n";
178 catch( H5::Exception& )
183 H5::Exception::setAutoPrint( tAutoPrintFunc, tClientData );
188 LDEBUG(
mlog,
"Opened acquisition group in <write> mode" );
191 catch( H5::Exception& )
193 throw M3Exception() <<
"Unable to open new acquisitions group for writing\n";
212 LDEBUG(
mlog,
"Initializing stream" );
224 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
264 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
310 throw M3Exception() <<
"Channel <" << aChannel <<
"> requested; only " <<
fNChannels <<
" in this stream.";
317 std::unique_lock< std::mutex >( *
fMutexPtr.get() );
330 LDEBUG(
mlog,
"Requested offset would move is out of range for the file" );
341 bool tIsNewAcq =
false;
382 catch( H5::Exception& e )
384 throw M3Exception() <<
"HDF5 error while reading a record:\n\t" << e.getCDetailMsg() <<
" (function: " << e.getFuncName() <<
")";
409 throw M3Exception() <<
"Channel <" << aChannel <<
"> requested; only " <<
fNChannels <<
" in this stream.";
422 std::unique_lock< std::mutex >( *
fMutexPtr.get() );
424 if( aIsNewAcquisition )
433 H5::DSetCreatPropList tPropList;
456 catch( H5::Exception& e )
460 H5D_space_status_t t_status;
463 throw M3Exception() <<
"HDF5 error while writing a record:\n\t" << e.getCDetailMsg() <<
" (function: " << e.getFuncName() <<
")";
465 catch( std::exception& e )
495 if( aIsNewAcquisition )
509 catch( H5::Exception& )
513 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
524 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
537 if( aIsNewAcquisition )
546 catch( H5::Exception& )
552 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
565 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
576 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
583 if( aIsNewAcquisition )
587 for(
unsigned iChan = 0; iChan <
fNChannels; ++iChan )
605 if( aIsNewAcquisition )
619 unsigned iRecInFile = 0;
624 tAttr.read( tAttr.getDataType(), &tNRecInAcq );
625 LDEBUG(
mlog,
"Acquisition <" <<
fAcqNameBuffer <<
"> has " << tNRecInAcq <<
" records" );
626 for(
unsigned iRecInAcq = 0; iRecInAcq < tNRecInAcq; ++iRecInAcq )
630 LTRACE(
mlog,
"Record index: " << iRecInFile <<
" -- " << iAcq <<
" -- " << iRecInAcq );
RecordIdType fAcqFirstRecId
const M3Record * GetStreamRecord() const
Get the pointer to the stream record.
void Close() const
Close the file.
DoWriteRecordFunc fDoWriteRecord
static const uint32_t sSeparate
RecordIdType * fAcqFirstRecIds
hsize_t fDataOffset[N_DATA_DIMS]
TimeType * fAcqFirstRecTimes
static const uint32_t sDigitizedUS
H5::Group * fH5StreamParentLoc
hsize_t fDataStride[N_DATA_DIMS]
Contains the information that makes up a record.
M3Stream(const M3StreamHeader &aHeader, HAS_GRP_IFC *aH5StreamParentLoc, uint32_t aAccessFormat=sSeparate)
DoReadRecordFunc fDoReadRecord
AcquisitionIdType fAcquisitionId
virtual const char * what() const
hsize_t fDataBlock[N_DATA_DIMS]
hsize_t fStrMaxDataDims[N_DATA_DIMS]
void SetAccessFormat(uint32_t aFormat) const
Access format can be changed during read or write; must call Initialize() after this.
void Initialize()
Allocate no memory for the record; data pointer is to NULL.
void ReadRecordInterleavedToSeparate(bool aIsNewAcquisition) const
void ReadRecordAsIs(bool aIsNewAcquisition) const
TimeType * GetTimePtr() const
M3Record * fChannelRecords
bool ReadRecord(int anOffset=0, bool aIfNewAcqStartAtFirstRec=true) const
Read the next record from the file.
void SetRecordId(RecordIdType aId)
RecordIdType GetRecordId() const
static const uint32_t sDigitizedS
TimeType fAcqFirstRecTime
void SetTime(TimeType aTime)
static const uint32_t sInterleaved
Specifies whether the data channels are interleaved or separate in a stream.
const byte_type * GetData() const
void u32toa(uint32_t value, char *buffer)
Quickly convert a 32-bit unsigned integer to a char array (buffer should already be allocated) ...
Specialized exception class for Monarch3.
static scarab::logger mlog("M3Header")
RecordIdType * GetRecordIdPtr() const
const M3Record * GetChannelRecord(unsigned aChannel) const
Get the pointer to a particular channel record.
unsigned fRecordCountInFile
unsigned fRecordCountInAcq
H5::DataType fDataTypeUser
void WriteRecordSeparateToInterleaved(bool aIsNewAcquisition)
unsigned fFirstRecordInFile
H5::DataSpace * fH5DataSpaceUser
hsize_t fDataDims1Rec[N_DATA_DIMS]
std::vector< std::pair< unsigned, unsigned > > fRecordIndex
void WriteRecordAsIs(bool aIsNewAcquisition)
H5::DataType fDataTypeInFile
bool WriteRecord(bool aIsNewAcquisition)
Write the record contents to the file.
hsize_t fStrDataChunkDims[N_DATA_DIMS]
void Initialize() const
Setup to read/write data (called in constructor; only call this if read/write parameters change durin...
hsize_t fStrDataDims[N_DATA_DIMS]
H5::DataSet * fH5CurrentAcqDataSet
void FinalizeCurrentAcq()