23 using std::stringstream;
28 LOGGER(
mlog,
"M3Header" );
41 fAcquisitionRate( 0 ),
54 uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
55 uint32_t aDataTypeSize, uint32_t aDataFormat,
56 uint32_t aBitDepth, uint32_t aBitAlignment ) :
60 fNChannels( aNChannels ),
61 fChannels( aNChannels ),
62 fChannelFormat( aFormat ),
63 fAcquisitionRate( anAcqRate ),
64 fRecordSize( aRecSize ),
65 fSampleSize( aSampleSize ),
66 fDataTypeSize( aDataTypeSize ),
67 fDataFormat( aDataFormat ),
68 fBitDepth( aBitDepth ),
69 fBitAlignment( aBitAlignment ),
74 for(
unsigned iChannel = 0; iChannel < fNChannels; ++iChannel )
76 fChannels[ iChannel ] = aFirstChannel + iChannel;
83 fSource( orig.fSource ),
84 fNChannels( orig.fNChannels ),
85 fChannels( orig.fChannels ),
86 fChannelFormat( orig.fChannelFormat ),
87 fAcquisitionRate( orig.fAcquisitionRate ),
88 fRecordSize( orig.fRecordSize ),
89 fSampleSize( orig.fSampleSize ),
90 fDataTypeSize( orig.fDataTypeSize ),
91 fDataFormat( orig.fDataFormat ),
92 fBitDepth( orig.fBitDepth ),
93 fBitAlignment( orig.fBitAlignment ),
94 fNAcquisitions( orig.fNAcquisitions ),
95 fNRecords( orig.fNRecords )
109 static const size_t prefixSize = 6;
111 fLabel =
new char[ prefixSize + 10 ];
112 strcpy( fLabel,
"stream" );
113 u32toa( aNumber, fLabel + prefixSize );
120 LDEBUG(
mlog,
"Writing stream <" << fLabel <<
">" );
121 H5::Group tThisStreamGroup = aParent->createGroup( fLabel );
144 LDEBUG(
mlog,
"Reading stream <" << aLabel <<
">" );
145 H5::Group tThisStreamGroup = aParent->openGroup( aLabel.c_str() );
147 SetNumber( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"number" ) );
148 Source() = M3Header::ReadScalarFromHDF5< string >( &tThisStreamGroup,
"source" );
149 SetNChannels( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"n_channels" ) );
150 SetChannelFormat( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"channel_format" ) );
151 SetAcquisitionRate( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"acquisition_rate" ) );
152 SetRecordSize( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"record_size" ) );
153 SetSampleSize( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"sample_size" ) );
154 SetDataTypeSize( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"data_type_size" ) );
155 SetDataFormat( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"data_format" ) );
156 SetBitDepth( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"bit_depth" ) );
157 SetBitAlignment( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"bit_alignment", fBitAlignment ) );
158 SetNAcquisitions( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"n_acquisitions" ) );
159 SetNRecords( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisStreamGroup,
"n_records" ) );
168 const unsigned tNDims = 1;
169 hsize_t tDims[ tNDims ] = { fNChannels };
171 H5::DataSpace tDataspace( tNDims, tDims );
175 uint32_t* tCSBuffer =
new uint32_t[ fNChannels ];
176 for(
unsigned i = 0; i < fNChannels; ++i )
178 tCSBuffer[ i ] = fChannels[ i ];
191 const unsigned tNDims = 1;
192 hsize_t tDims[ tNDims ];
195 H5::Attribute tAttr = aLoc->openAttribute(
"channels" );
197 H5::DataSpace tDataspace( tAttr.getSpace() );
198 tDataspace.getSimpleExtentDims( tDims );
200 if( tDims[ 0 ] != fNChannels )
202 LERROR(
mlog,
"Channels dataset dimensions (" << tDims[ 0 ] <<
") do not match number of channels, " << fNChannels );
206 uint32_t* tCSBuffer =
new uint32_t[ fNChannels ];
211 fChannels.resize( fNChannels );
212 for(
unsigned i = 0; i < fNChannels; ++i )
214 fChannels[ i ] = tCSBuffer[ i ];
230 fAcquisitionRate( 0 ),
237 fVoltageOffset( 0. ),
241 fFrequencyRange( 0. )
246 uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
247 uint32_t aDataTypeSize, uint32_t aDataFormat,
248 uint32_t aBitDepth, uint32_t aBitAlignment ) :
252 fAcquisitionRate( anAcqRate ),
253 fRecordSize( aRecSize ),
254 fSampleSize( aSampleSize ),
255 fDataTypeSize( aDataTypeSize ),
256 fDataFormat( aDataFormat ),
257 fBitDepth( aBitDepth ),
258 fBitAlignment( aBitAlignment ),
259 fVoltageOffset( 0. ),
263 fFrequencyRange( 0. )
271 fSource( orig.fSource ),
272 fAcquisitionRate( orig.fAcquisitionRate ),
273 fRecordSize( orig.fRecordSize ),
274 fSampleSize( orig.fSampleSize ),
275 fDataTypeSize( orig.fDataTypeSize ),
276 fDataFormat( orig.fDataFormat ),
277 fBitDepth( orig.fBitDepth ),
278 fBitAlignment( orig.fBitAlignment ),
279 fVoltageOffset( orig.fVoltageOffset ),
280 fVoltageRange( orig.fVoltageRange ),
281 fDACGain( orig.fDACGain ),
282 fFrequencyMin( orig.fFrequencyMin ),
283 fFrequencyRange( orig.fFrequencyRange )
297 static const size_t prefixSize = 7;
299 fLabel =
new char[ prefixSize + 10 ];
300 strcpy( fLabel,
"channel" );
301 u32toa( aNumber, fLabel + prefixSize );
308 LDEBUG(
mlog,
"Writing channel <" << fLabel <<
">" );
309 H5::Group tThisChannelGroup = aParent->createGroup( fLabel );
331 LDEBUG(
mlog,
"Reading channel <" << aLabel <<
">" );
332 H5::Group tThisChannelGroup = aParent->openGroup( aLabel.c_str() );
334 SetNumber( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"number" ) );
335 Source() = M3Header::ReadScalarFromHDF5< string >( &tThisChannelGroup,
"source" );
336 SetAcquisitionRate( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"acquisition_rate" ) );
337 SetRecordSize( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"record_size" ) );
338 SetSampleSize( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"sample_size" ) );
339 SetDataTypeSize( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"data_type_size" ) );
340 SetDataFormat( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"data_format" ) );
341 SetBitDepth( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"bit_depth" ) );
342 SetBitAlignment( M3Header::ReadScalarFromHDF5< uint32_t >( &tThisChannelGroup,
"bit_alignment", fBitAlignment ) );
343 SetVoltageOffset( M3Header::ReadScalarFromHDF5< double >( &tThisChannelGroup,
"voltage_offset" ) );
344 SetVoltageRange( M3Header::ReadScalarFromHDF5< double >( &tThisChannelGroup,
"voltage_range" ) );
345 SetDACGain( M3Header::ReadScalarFromHDF5< double >( &tThisChannelGroup,
"dac_gain" ) );
346 SetFrequencyMin( M3Header::ReadScalarFromHDF5< double >( &tThisChannelGroup,
"frequency_min" ) );
347 SetFrequencyRange( M3Header::ReadScalarFromHDF5< double >( &tThisChannelGroup,
"frequency_range" ) );
358 fEggVersion( TOSTRING(Egg_VERSION) ),
368 fStreamsGroup( NULL ),
369 fChannelsGroup( NULL )
381 fEggVersion = aOrig.fEggVersion;
382 fFilename = aOrig.fFilename;
383 fRunDuration = aOrig.fRunDuration;
384 fTimestamp = aOrig.fTimestamp;
385 fDescription = aOrig.fDescription;
391 if( aChanA >= fNChannels || aChanB >= fNChannels )
393 throw M3Exception() <<
"Channel out of bounds: " << aChanA <<
" or " << aChanB <<
" >= " << fNChannels;
395 fChannelCoherence[ aChanA ][ aChanB ] = aCoherence;
396 fChannelCoherence[ aChanB ][ aChanA ] = aCoherence;
401 uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
402 uint32_t aDataTypeSize, uint32_t aDataFormat,
403 uint32_t aBitDepth, uint32_t aBitAlignment,
404 std::vector< unsigned >* aChanVec )
406 LDEBUG(
mlog,
"Adding stream " << fNStreams <<
" for channel " << fNChannels <<
" with record size " << aRecSize );
407 if( aChanVec != NULL ) aChanVec->push_back( fNChannels );
408 fChannelStreams.push_back( fNStreams );
409 fChannelHeaders.push_back(
M3ChannelHeader( aSource, fNChannels, anAcqRate, aRecSize, aSampleSize, aDataTypeSize, aDataFormat, aBitDepth, aBitAlignment ) );
410 fStreamHeaders.push_back(
M3StreamHeader( aSource, fNStreams, 1, fNChannels,
sSeparate, anAcqRate, aRecSize, aSampleSize, aDataTypeSize, aDataFormat, aBitDepth, aBitAlignment ) );
413 fChannelCoherence.resize( fNChannels );
414 for(
unsigned i = 0; i < fNChannels; ++i )
416 fChannelCoherence[ i ].resize( fNChannels,
false );
418 fChannelCoherence.back().back() =
true;
423 uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
424 uint32_t aDataTypeSize, uint32_t aDataFormat,
425 uint32_t aBitDepth, uint32_t aBitAlignment,
426 std::vector< unsigned >* aChanVec )
428 LDEBUG(
mlog,
"Adding stream " << fNStreams <<
" for multiple channels with record size " << aRecSize );
429 unsigned tFirstNewChannel = fNChannels;
430 for( uint32_t iNewChannel = 0; iNewChannel < aNChannels; ++iNewChannel )
432 LDEBUG(
mlog,
"Adding channel " << fNChannels );
433 if( aChanVec != NULL ) aChanVec->push_back( fNChannels );
434 fChannelStreams.push_back( fNStreams );
435 fChannelHeaders.push_back(
M3ChannelHeader( aSource, fNChannels, anAcqRate, aRecSize, aSampleSize, aDataTypeSize, aDataFormat, aBitDepth, aBitAlignment ) );
437 fChannelCoherence.resize( fNChannels );
438 for(
unsigned i = 0; i < fNChannels; ++i )
440 fChannelCoherence[ i ].resize( fNChannels,
false );
442 fChannelCoherence.back().back() =
true;
445 for(
unsigned i = tFirstNewChannel; i < fNChannels - 1; ++i )
447 fChannelCoherence[ fNChannels - 1 ][ i ] =
true;
448 fChannelCoherence[ i ][ fNChannels - 1 ] =
true;
452 fStreamHeaders.push_back(
M3StreamHeader( aSource, fNStreams, aNChannels, tFirstNewChannel, aFormat, anAcqRate, aRecSize, aSampleSize, aDataTypeSize, aDataFormat, aBitDepth, aBitAlignment ) );
460 LDEBUG(
mlog,
"Writing run header" );
473 LDEBUG(
mlog,
"Writing stream headers" );
475 for( uint32_t iStream = 0; iStream < fNStreams; ++iStream )
480 LDEBUG(
mlog,
"Writing channel headers" );
482 for( uint32_t iChan = 0; iChan < fNChannels; ++iChan )
487 catch( H5::Exception& e )
489 throw M3Exception() <<
"HDF5 error while writing header: " << e.getCDetailMsg();
493 LDEBUG(
mlog,
"M3Exception: " << e.
what() );
504 LDEBUG(
mlog,
"Reading run header" );
505 fFile =
const_cast< H5::H5File*
>( aFile );
506 EggVersion() = ReadScalarFromHDF5< string >(
fFile, string(
"egg_version") );
507 Filename() = ReadScalarFromHDF5< string >(
fFile,
"filename" );
508 SetNChannels( ReadScalarFromHDF5< uint32_t >( fFile,
"n_channels" ) );
509 SetNStreams( ReadScalarFromHDF5< uint32_t >( fFile,
"n_streams" ) );
510 SetRunDuration( ReadScalarFromHDF5< uint32_t >( fFile,
"run_duration" ) );
511 Timestamp() = ReadScalarFromHDF5< string >(
fFile,
"timestamp" );
512 Description() = ReadScalarFromHDF5< string >(
fFile,
"description" );
531 const unsigned tBuffSize = 256;
532 char tBuffer[ tBuffSize ];
534 LDEBUG(
mlog,
"Reading stream headers" );
535 fStreamHeaders.clear();
536 fStreamsGroup =
new H5::Group( fFile->openGroup(
"streams" ) );
538 if( nStreams != fNStreams )
540 throw M3Exception() <<
"Number of streams <" << fNStreams <<
"> disagrees with the number of objects in the stream group <" << nStreams <<
">";
542 for( hsize_t iStream = 0; iStream < nStreams; ++iStream )
545 unsigned tLabelSize =
fStreamsGroup->getObjnameByIdx( iStream, tBuffer, tBuffSize );
546 std::string tStreamLabel( tBuffer, tLabelSize );
547 LDEBUG(
mlog,
"Attempting to read stream header #" << iStream <<
"; label <" << tStreamLabel <<
">" );
549 LDEBUG(
mlog,
"Testing if we can access the last header: " << fStreamHeaders.back().GetLabel() );
550 fStreamHeaders.back().ReadFromHDF5(
fStreamsGroup, tStreamLabel );
553 LDEBUG(
mlog,
"Reading channel headers" );
554 fChannelHeaders.clear();
557 for( hsize_t iChan = 0; iChan < nChannels; ++iChan )
560 unsigned tLabelSize =
fChannelsGroup->getObjnameByIdx( iChan, tBuffer, tBuffSize );
561 std::string tChannelLabel( tBuffer, tLabelSize );
563 fChannelHeaders.back().ReadFromHDF5(
fChannelsGroup, tChannelLabel );
566 catch( H5::Exception& e )
569 throw M3Exception() <<
"Unable to open header group or find header data\n";
576 const unsigned tNDims = 1;
577 hsize_t tDims[ tNDims ] = { fNChannels };
579 H5::DataSpace tDataspace( tNDims, tDims );
583 uint32_t* tCSBuffer =
new uint32_t[ fNChannels ];
584 for(
unsigned i = 0; i < fNChannels; ++i )
586 tCSBuffer[ i ] = fChannelStreams[ i ];
599 const unsigned tNDims = 1;
600 hsize_t tDims[ tNDims ];
603 H5::Attribute tAttr = aLoc->openAttribute(
"channel_streams" );
605 H5::DataSpace tDataspace( tAttr.getSpace() );
606 tDataspace.getSimpleExtentDims( tDims );
608 if( tDims[ 0 ] != fNChannels )
610 LERROR(
mlog,
"Channel-streams dataset dimensions (" << tDims[ 0 ] <<
") do not match number of channels, " << fNChannels );
614 uint32_t* tCSBuffer =
new uint32_t[ fNChannels ];
618 fChannelStreams.clear();
619 fChannelStreams.resize( fNChannels );
620 for(
unsigned i = 0; i < fNChannels; ++i )
622 fChannelStreams[ i ] = tCSBuffer[ i ];
632 const unsigned tNDims = 2;
633 hsize_t tDims[ tNDims ] = { fNChannels, fNChannels };
635 H5::DataSpace tDataspace( tNDims, tDims );
637 H5::Attribute tAttr = aLoc->createAttribute(
"channel_coherence",
MH5Type< bool >::H5(), tDataspace );
639 uint8_t* tCCBuffer =
new uint8_t[ fNChannels * fNChannels ];
640 for(
unsigned i = 0; i < fNChannels; ++i )
642 for(
unsigned j = 0; j < fNChannels; ++j )
644 tCCBuffer[ i * fNChannels + j ] = (uint8_t)fChannelCoherence[ i ][ j ];
658 const unsigned tNDims = 2;
659 hsize_t tDims[ tNDims ];
662 H5::Attribute tAttr = aLoc->openAttribute(
"channel_coherence" );
664 H5::DataSpace tDataspace( tAttr.getSpace() );
665 tDataspace.getSimpleExtentDims( tDims );
667 if( tDims[ 0 ] != fNChannels || tDims[ 1 ] != fNChannels )
669 LERROR(
mlog,
"Channel coherence dataset dimensions (" << tDims[ 0 ] <<
", " << tDims[ 1 ] <<
") do not match number of channels, " << fNChannels );
673 uint8_t* tCCBuffer =
new uint8_t[ fNChannels * fNChannels ];
677 fChannelCoherence.clear();
678 fChannelCoherence.resize( fNChannels );
679 for(
unsigned i = 0; i < fNChannels; ++i )
681 fChannelCoherence[ i ].resize( fNChannels );
682 for(
unsigned j = 0; j < fNChannels; ++j )
684 fChannelCoherence[ i ][ j ] = (bool)tCCBuffer[ i * fNChannels + j ];
697 out <<
"Stream Header Content:\n";
698 out <<
"\tStream Number: " << hdr.GetNumber() <<
'\n';
699 out <<
"\tSource: " << hdr.Source() <<
'\n';
700 out <<
"\tNumber of Channels: " << hdr.GetNChannels() <<
'\n';
701 out <<
"\tChannel Format: " << hdr.GetChannelFormat() <<
'\n';
702 out <<
"\tAcquisition Rate: " << hdr.GetAcquisitionRate() <<
" MHz\n";
703 out <<
"\tRecord Size: " << hdr.GetRecordSize() <<
" samples\n";
704 out <<
"\tSample Size: " << hdr.GetSampleSize() <<
" elements\n";
705 out <<
"\tData Type Size: " << hdr.GetDataTypeSize() <<
" bytes\n";
706 out <<
"\tData Format: " << hdr.GetDataFormat() <<
'\n';
707 out <<
"\tBit Depth: " << hdr.GetBitDepth() <<
" bits\n";
708 out <<
"\tBit Alignment: " << hdr.GetBitAlignment() <<
'\n';
709 out <<
"\tNumber of Acquisitions: " << hdr.GetNAcquisitions() <<
'\n';
710 out <<
"\tNumber of Records: " << hdr.GetNRecords() <<
'\n';
716 out <<
"Channel Header Content:\n";
717 out <<
"\tChannel Number: " << hdr.GetNumber() <<
'\n';
718 out <<
"\tSource: " << hdr.Source() <<
'\n';
719 out <<
"\tAcquisition Rate: " << hdr.GetAcquisitionRate() <<
" MHz\n";
720 out <<
"\tRecord Size: " << hdr.GetRecordSize() <<
" samples\n";
721 out <<
"\tSample Size: " << hdr.GetSampleSize() <<
" elements\n";
722 out <<
"\tData Type Size: " << hdr.GetDataTypeSize() <<
" bytes\n";
723 out <<
"\tData Format: " << hdr.GetDataFormat() <<
'\n';
724 out <<
"\tBit Depth: " << hdr.GetBitDepth() <<
" bits\n";
725 out <<
"\tBit Alignment: " << hdr.GetBitAlignment() <<
'\n';
726 out <<
"\tVoltage Offset: " << hdr.GetVoltageOffset() <<
" V\n";
727 out <<
"\tVoltage Range: " << hdr.GetVoltageRange() <<
" V\n";
728 out <<
"\tFrequency Min: " << hdr.GetFrequencyMin() <<
" Hz\n";
729 out <<
"\tFrequency Range: " << hdr.GetFrequencyRange() <<
" Hz\n";
735 out <<
"Monarch Header Content:\n";
736 out <<
"\tEgg Version: " << hdr.EggVersion() <<
"\n";
737 out <<
"\tFilename: " << hdr.Filename() <<
"\n";
738 out <<
"\tRun Duration: " << hdr.GetRunDuration() <<
" ms\n";
739 out <<
"\tTimestamp: " << hdr.Timestamp() <<
"\n";
740 out <<
"\tDescription: " << hdr.Description() <<
"\n";
741 out <<
"\tNumber of Channels: " << hdr.GetNChannels() <<
"\n";
742 out <<
"\tNumber of Streams: " << hdr.GetNStreams() <<
"\n";
743 out <<
"\tChannel-to-stream mapping:\n";
744 for( uint32_t iChan = 0; iChan < hdr.ChannelStreams().size(); ++iChan )
746 out <<
"\t\tChannel " << iChan <<
" --> Stream " << hdr.ChannelStreams()[ iChan ] <<
"\n";
748 out <<
"\tStream headers:\n";
749 for( uint32_t iStream = 0; iStream < hdr.StreamHeaders().size(); ++iStream )
751 out << hdr.StreamHeaders()[ iStream ];
753 out <<
"\tChannel headers:\n";
754 for( uint32_t iChan = 0; iChan < hdr.ChannelHeaders().size(); ++iChan )
756 out << hdr.ChannelHeaders()[ iChan ];
static const uint32_t sSeparate
static const uint32_t sDigitizedUS
virtual const char * what() 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")
static const uint32_t sBitsAlignedLeft