Monarch  v3.8.2
Project 8 Data File Format Library
M3Header.hh
Go to the documentation of this file.
1 /*
2  * M3Header.hh
3  *
4  * Created on: Dec 4, 2014
5  * Author: nsoblath
6  */
7 
8 #ifndef M3HEADER_HH_
9 #define M3HEADER_HH_
10 
11 #include "M3Constants.hh"
12 #include "logger.hh"
13 #include "M3MemberVariable.hh"
14 #include "M3Types.hh"
15 
16 #include "H5Cpp.h"
17 
18 #include <string>
19 #include <vector>
20 
21 namespace monarch3
22 {
23  LOGGER( mlog_mheader, "M3Header.hh" );
24 
34  {
35  public:
37  M3StreamHeader( const std::string& aSource, uint32_t aNumber, uint32_t aNChannels, uint32_t aFirstChannel, uint32_t aFormat,
38  uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
39  uint32_t aDataTypeSize, uint32_t aDataFormat,
40  uint32_t aBitDepth, uint32_t aBitAlignment );
41  M3StreamHeader( const M3StreamHeader& orig );
42  ~M3StreamHeader();
43 
44  M3MEMBERVARIABLE_PTR( char, Label );
45 
46  M3MEMBERVARIABLE_NOSET( uint32_t, Number );
47  void SetNumber( uint32_t aNumber ) const;
48 
49  M3MEMBERVARIABLE_REF( std::string, Source );
50 
51  M3MEMBERVARIABLE( uint32_t, NChannels );
52 
53  M3MEMBERVARIABLE_REF_CONST( std::vector< uint32_t >, Channels );
54 
55  M3MEMBERVARIABLE( uint32_t, ChannelFormat );
56 
57  M3MEMBERVARIABLE( uint32_t, AcquisitionRate );
58 
59  M3MEMBERVARIABLE( uint32_t, RecordSize );
60 
61  M3MEMBERVARIABLE( uint32_t, SampleSize );
62 
63  M3MEMBERVARIABLE( uint32_t, DataTypeSize );
64 
65  M3MEMBERVARIABLE( uint32_t, DataFormat );
66 
67  M3MEMBERVARIABLE( uint32_t, BitDepth );
68 
69  M3MEMBERVARIABLE( uint32_t, BitAlignment );
70 
71  M3MEMBERVARIABLE( uint32_t, NAcquisitions );
72 
73  M3MEMBERVARIABLE( uint32_t, NRecords );
74 
75  public:
76  void WriteToHDF5( HAS_GRP_IFC* aParent );
77  void ReadFromHDF5( const HAS_GRP_IFC* aParent, const std::string& aLabel ) const;
78 
79  private:
80  void WriteChannels( HAS_ATTR_IFC* aLoc );
81  void ReadChannels( const HAS_ATTR_IFC* aLoc ) const;
82  };
83 
93  {
94  public:
96  M3ChannelHeader( const std::string& aSource, uint32_t aNumber,
97  uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
98  uint32_t aDataTypeSize, uint32_t aDataFormat,
99  uint32_t aBitDepth, uint32_t aBitAlignment );
100  M3ChannelHeader( const M3ChannelHeader& orig );
101  ~M3ChannelHeader();
102 
103  M3MEMBERVARIABLE_PTR( char, Label );
104 
105  M3MEMBERVARIABLE_NOSET( uint32_t, Number );
106  void SetNumber( uint32_t aNumber ) const;
107 
108  M3MEMBERVARIABLE_REF( std::string, Source );
109 
110  M3MEMBERVARIABLE( uint32_t, AcquisitionRate );
111 
112  M3MEMBERVARIABLE( uint32_t, RecordSize );
113 
114  M3MEMBERVARIABLE( uint32_t, SampleSize );
115 
116  M3MEMBERVARIABLE( uint32_t, DataTypeSize );
117 
118  M3MEMBERVARIABLE( uint32_t, DataFormat );
119 
120  M3MEMBERVARIABLE( uint32_t, BitDepth );
121 
122  M3MEMBERVARIABLE( uint32_t, BitAlignment );
123 
124  M3MEMBERVARIABLE( double, VoltageOffset );
125 
126  M3MEMBERVARIABLE( double, VoltageRange );
127 
128  M3MEMBERVARIABLE( double, DACGain );
129 
130  M3MEMBERVARIABLE( double, FrequencyMin );
131 
132  M3MEMBERVARIABLE( double, FrequencyRange );
133 
134  public:
135  void WriteToHDF5( HAS_GRP_IFC* aParent );
136  void ReadFromHDF5( const HAS_GRP_IFC* aParent, const std::string& aLabel ) const;
137 
138  };
139 
140 
153  {
154  public:
155  typedef std::vector< M3ChannelHeader > M3ChannelHeaders;
156  typedef std::vector< M3StreamHeader > M3StreamHeaders;
157 
158  public:
159  M3Header();
160  ~M3Header();
161 
162  void CopyBasicInfo( const M3Header& aOrig );
163 
164  M3MEMBERVARIABLE_REF( std::string, EggVersion );
165 
166  M3MEMBERVARIABLE_REF( std::string, Filename );
167 
168  M3MEMBERVARIABLE( uint32_t, RunDuration );
169 
170  M3MEMBERVARIABLE_REF( std::string, Timestamp );
171 
172  M3MEMBERVARIABLE_REF( std::string, Description );
173 
174  M3MEMBERVARIABLE( uint32_t, NChannels );
175 
176  M3MEMBERVARIABLE( uint32_t, NStreams );
177 
178  M3MEMBERVARIABLE_REF_CONST( std::vector< uint32_t >, ChannelStreams );
179 
180  M3MEMBERVARIABLE_REF_CONST( std::vector< std::vector< bool > >, ChannelCoherence );
181  void SetCoherence( unsigned aChanA, unsigned aChanB, bool aCoherence );
182 
183  M3MEMBERVARIABLE_REF_CONST( std::vector< M3ChannelHeader >, ChannelHeaders );
184  std::vector< M3ChannelHeader >& GetChannelHeaders();
185 
186  M3MEMBERVARIABLE_REF_CONST( std::vector< M3StreamHeader >, StreamHeaders );
187  std::vector< M3StreamHeader >& GetStreamHeaders();
188 
189  public:
192  unsigned AddStream( const std::string& aSource,
193  uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
194  uint32_t aDataTypeSize, uint32_t aDataFormat,
195  uint32_t aBitDepth, uint32_t aBitAlignment,
196  std::vector< unsigned >* aChanVec = NULL );
199  unsigned AddStream( const std::string& aSource, uint32_t aNChannels, uint32_t aFormat,
200  uint32_t anAcqRate, uint32_t aRecSize, uint32_t aSampleSize,
201  uint32_t aDataTypeSize, uint32_t aDataFormat,
202  uint32_t aBitDepth, uint32_t aBitAlignment,
203  std::vector< unsigned >* aChanVec = NULL );
204 
205  public:
206  void WriteToHDF5( H5::H5File* aFile );
207  void ReadFromHDF5( const H5::H5File* aFile ) const;
208 
209  const H5::Group* GetStreamsGroup() const;
210  H5::Group* GetStreamsGroup();
211 
212  const H5::Group* GetChannelsGroup() const;
213  H5::Group* GetChannelsGroup();
214 
215  private:
216  void WriteChannelStreams( HAS_ATTR_IFC* aLoc );
217  void ReadChannelStreams( const HAS_ATTR_IFC* aLoc ) const;
218 
219  void WriteChannelCoherence( HAS_ATTR_IFC* aLoc );
220  void ReadChannelCoherence( const HAS_ATTR_IFC* aLoc ) const;
221 
222  mutable H5::H5File* fFile;
223  mutable H5::Group* fStreamsGroup;
224  mutable H5::Group* fChannelsGroup;
225 
226  public:
227  static void WriteScalarToHDF5( HAS_ATTR_IFC* aLoc, const std::string& aName, const std::string& aValue );
228  template< typename XType >
229  static void WriteScalarToHDF5( HAS_ATTR_IFC* aLoc, const std::string& aName, XType aValue );
230 
231  //template< typename XArrayType >
232  //static void Write1DToHDF5( HAS_GRP_IFC* aLoc, const std::string& aName, const XArrayType& anArray );
233 
234  template< typename XType >
235  static XType ReadScalarFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName );
236 
237  template< typename XType >
238  static XType ReadScalarFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName, const XType& aDefault );
239 
240  //template< typename XArrayType >
241  //static void Read1DFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName, XArrayType& anArray );
242 
243  };
244 
245  inline const H5::Group* M3Header::GetStreamsGroup() const
246  {
247  return fStreamsGroup;
248  }
249 
250  inline H5::Group* M3Header::GetStreamsGroup()
251  {
252  return fStreamsGroup;
253  }
254 
255  inline const H5::Group* M3Header::GetChannelsGroup() const
256  {
257  return fChannelsGroup;
258  }
259 
260  inline H5::Group* M3Header::GetChannelsGroup()
261  {
262  return fChannelsGroup;
263  }
264 
265  inline std::vector< M3ChannelHeader >& M3Header::GetChannelHeaders()
266  {
267  return fChannelHeaders;
268  }
269 
270  inline std::vector< M3StreamHeader >& M3Header::GetStreamHeaders()
271  {
272  return fStreamHeaders;
273  }
274 
275 
276  inline void M3Header::WriteScalarToHDF5( HAS_ATTR_IFC* aLoc, const std::string& aName, const std::string& aValue )
277  {
278  LTRACE( mlog_mheader, "Writing string to new scalar metadata <" << aName << ">: " << aValue << "; size = " << aValue.size() );
279  // aName.c_str() and aValue.c_str() are used because while using the std::string itself, the value was getting mangled
280  H5::DataType tType = MH5Type< std::string >::H5( aValue );
281  aLoc->createAttribute( aName.c_str(), tType, H5::DataSpace( H5S_SCALAR ) ).write( tType, aValue.c_str() );
282  return;
283  }
284 
285  template< typename XType >
286  void M3Header::WriteScalarToHDF5( HAS_ATTR_IFC* aLoc, const std::string& aName, XType aValue )
287  {
288  LTRACE( mlog_mheader, "Writing value to new scalar metadata <" << aName << ">: " << aValue );
289  // aName.c_str() is used because while using the std::string itself, the value was getting mangled
290  aLoc->createAttribute( aName.c_str(), MH5Type< XType >::H5(), H5::DataSpace( H5S_SCALAR ) ).write( MH5Type< XType >::Native(), &aValue );
291  return;
292  }
293 /*
294  template< typename XArrayType >
295  void M3Header::Write1DToHDF5( HAS_GRP_IFC* aLoc, const std::string& aName, const XArrayType& anArray )
296  {
297  typedef typename XArrayType::value_type XValueType;
298  LDEBUG( mlog_mheader, "Writing vector to new 1-D metadata <" << aName << ">; size = " << anArray.size() );
299  hsize_t tDims[ 1 ] = { anArray.size() };
300  std::cout << "tDims[0] = " << tDims[0] << std::endl;
301  //H5::ArrayType tTypeNative( MH5Type< XValueType >::Native(), 1, tDims );
302  //H5::ArrayType tTypeH5( MH5Type< XValueType >::H5(), 1, tDims );
303  H5::DataSpace dspace( 1, tDims, tDims );
304  XValueType* buffer = new XValueType( anArray.size() );
305  for( unsigned i = 0; i < anArray.size(); ++i )
306  {
307  buffer[ i ] = anArray[ i ];
308  std::cout << "writing bin " << i << ": " << buffer[i] << " <-- " << anArray[i] << std::endl;
309  }
310  //aLoc->createAttribute( aName, MH5Type< XValueType >::H5(), dspace ).write( MH5Type< XValueType >::Native(), buffer );
311  aLoc->createDataSet( aName, MH5Type< XValueType >::H5(), dspace ).write( buffer, MH5Type< XValueType >::Native() );
312  delete [] buffer;
313  return;
314  }
315 */
316 
317  // Read functions
318 
319  // read specialization for strings
320  template<>
321  inline std::string M3Header::ReadScalarFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName )
322  {
323  //std::string tValue;
324  char tBuffer[ 65536 ]; // this array size matches the maximum standard attribute size according to the HDF5 documentation
325  H5::Attribute* tAttr = new H5::Attribute( aLoc->openAttribute( aName.c_str() ) );
326  //tAttr->read( tAttr->getDataType(), tValue );
327  tAttr->read( tAttr->getDataType(), tBuffer );
328  delete tAttr;
329  std::string tValue( tBuffer );
330  LTRACE( mlog_mheader, "Reading string <" << aName << ">: " << tValue << "; size = " << tValue.size() );
331  return tValue;
332  }
333 
334  // templated read function
335  template< typename XType >
336  XType M3Header::ReadScalarFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName )
337  {
338  XType tValue;
339  H5::Attribute* tAttr = new H5::Attribute( aLoc->openAttribute( aName.c_str() ) );
340  tAttr->read( tAttr->getDataType(), &tValue );
341  delete tAttr;
342  LTRACE( mlog_mheader, "Reading value <" << aName << ">: " << tValue );
343  return tValue;
344  }
345 
346 
347  // Read functions with default values
348 
349  // read specialization for strings
350  template<>
351  inline std::string M3Header::ReadScalarFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName, const std::string& aDefaultValue )
352  {
353  if( ! aLoc->attrExists( aName.c_str() ) ) return aDefaultValue;
354  //std::string tValue;
355  char tBuffer[ 65536 ]; // this array size matches the maximum standard attribute size according to the HDF5 documentation
356  H5::Attribute* tAttr = new H5::Attribute( aLoc->openAttribute( aName.c_str() ) );
357  //tAttr->read( tAttr->getDataType(), tValue );
358  tAttr->read( tAttr->getDataType(), tBuffer );
359  delete tAttr;
360  std::string tValue( tBuffer );
361  LTRACE( mlog_mheader, "Reading string <" << aName << ">: " << tValue << "; size = " << tValue.size() );
362  return tValue;
363  }
364 
365  // templated read function
366  template< typename XType >
367  XType M3Header::ReadScalarFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName, const XType& aDefaultValue )
368  {
369  if( ! aLoc->attrExists( aName.c_str() ) ) return aDefaultValue;
370  XType tValue;
371  H5::Attribute* tAttr = new H5::Attribute( aLoc->openAttribute( aName.c_str() ) );
372  tAttr->read( tAttr->getDataType(), &tValue );
373  delete tAttr;
374  LTRACE( mlog_mheader, "Reading value <" << aName << ">: " << tValue );
375  return tValue;
376  }
377 /*
378  template< typename XArrayType >
379  void M3Header::Read1DFromHDF5( const HAS_ATTR_IFC* aLoc, const std::string& aName, XArrayType& anArray )
380  {
381  typedef typename XArrayType::value_type XValueType;
382  H5::Attribute tAttr( aLoc->openAttribute( aName ) );
383  H5::DataSpace tDataspace( tAttr.getSpace() );
384  if( tDataspace.getSimpleExtentNdims() != 1 )
385  {
386  throw M3Exception() << "Attribute <" << aName << "> has " << tDataspace.getSimpleExtentNdims() << " dimensions; 1 dimension was expected";
387  }
388  hsize_t tDims[ 1 ];
389  tDataspace.getSimpleExtentDims( tDims );
390  XValueType* buffer = new XValueType( tDims[0] );
391  LDEBUG( mlog_mheader, "Reading 1-D metadata <" << aName << "> to vector; size = " << tDims[0] );
392  tAttr.read( tAttr.getDataType(), buffer );
393  for( unsigned i = 0; i < anArray.size(); ++i )
394  {
395  anArray[ i ] = buffer[ i ];
396  }
397  delete [] buffer;
398  return;
399  }
400 */
401 }
402 
403 // Pretty printing methods
404 M3_API std::ostream& operator<<( std::ostream& out, const monarch3::M3StreamHeader& hdr );
405 M3_API std::ostream& operator<<( std::ostream& out, const monarch3::M3ChannelHeader& hdr );
406 M3_API std::ostream& operator<<( std::ostream& out, const monarch3::M3Header& hdr );
407 
408 #endif
const H5::Group * GetChannelsGroup() const
Definition: M3Header.hh:255
static scarab::logger mlog_mheader("M3Header.hh")
static XType ReadScalarFromHDF5(const HAS_ATTR_IFC *aLoc, const std::string &aName)
Definition: M3Header.hh:336
#define M3MEMBERVARIABLE_PTR
std::vector< M3ChannelHeader > & GetChannelHeaders()
Definition: M3Header.hh:265
static void WriteScalarToHDF5(HAS_ATTR_IFC *aLoc, const std::string &aName, const std::string &aValue)
Definition: M3Header.hh:276
Egg file header information.
Definition: M3Header.hh:152
Single-channel header information.
Definition: M3Header.hh:92
const H5::Group * GetStreamsGroup() const
Definition: M3Header.hh:245
#define M3MEMBERVARIABLE
H5::Group * fStreamsGroup
Definition: M3Header.hh:223
std::vector< M3StreamHeader > M3StreamHeaders
Definition: M3Header.hh:156
Single-stream header information.
Definition: M3Header.hh:33
H5::H5File * fFile
Definition: M3Header.hh:222
#define M3MEMBERVARIABLE_REF
#define M3MEMBERVARIABLE_REF_CONST
std::ostream & operator<<(std::ostream &out, const monarch3::M3StreamHeader &hdr)
Definition: M3Header.cc:695
#define M3MEMBERVARIABLE_NOSET
std::vector< M3StreamHeader > & GetStreamHeaders()
Definition: M3Header.hh:270
#define M3_API
Definition: M3Constants.hh:21
H5::Group * fChannelsGroup
Definition: M3Header.hh:224
static H5::DataType H5(T)
Definition: M3Types.hh:52
std::vector< M3ChannelHeader > M3ChannelHeaders
Definition: M3Header.hh:155