Monarch  v3.8.2
Project 8 Data File Format Library
M3Monarch.cc
Go to the documentation of this file.
1 /*
2  * M3Monarch.cc
3  *
4  * Created on: Dec 4, 2014
5  * Author: nsoblath
6  */
7 #define M3_API_EXPORTS
8 
9 #include "M3Monarch.hh"
10 
11 #include "logger.hh"
12 
13 using std::string;
14 
15 namespace monarch3
16 {
17  LOGGER( mlog, "MMonarch3" );
18 
20  fState( eClosed ),
21  fFile( nullptr ),
22  fHeader( nullptr ),
23  fMutexPtr( new std::mutex() )
24  {
25  }
26 
28  {
31 
32  if( fHeader != nullptr )
33  {
34  delete fHeader;
35  fHeader = nullptr;
36  }
37 
38  while( ! fStreams.empty() )
39  {
40  delete fStreams.back();
41  fStreams.pop_back();
42  }
43 
44  if( fFile != nullptr )
45  {
46  delete fFile;
47  fFile = nullptr;
48  }
49  }
50 
52  {
53  return fState;
54  }
55 
56  const Monarch3* Monarch3::OpenForReading( const string& aFilename )
57  {
58  Monarch3* tMonarch3 = new Monarch3();
59 
60  try
61  {
62  tMonarch3->fFile = new H5::H5File( aFilename.c_str(), H5F_ACC_RDONLY );
63  }
64  catch( H5::Exception& e )
65  {
66  delete tMonarch3;
67  throw M3Exception() << "Could not open <" << aFilename << "> for reading; an H5::Exception was thrown: " << e.getCDetailMsg();
68  return nullptr;
69  }
70  catch( std::exception& e )
71  {
72  delete tMonarch3;
73  throw M3Exception() << "Could not open <" << aFilename << "> for reading; a std::exception was thrown: " << e.what();
74  return nullptr;
75  }
76  if( tMonarch3->fFile == nullptr )
77  {
78  delete tMonarch3;
79  throw M3Exception() << "Could not open <" << aFilename << "> for reading";
80  return nullptr;
81  }
82  LDEBUG( mlog, "Opened egg file <" << aFilename << "> for reading" );
83 
84  tMonarch3->fHeader = new M3Header();
85  tMonarch3->fHeader->Filename() = aFilename;
86 
87  tMonarch3->fState = eOpenToRead;
88 
89  return tMonarch3;
90  }
91 
92  Monarch3* Monarch3::OpenForWriting( const string& aFilename )
93  {
94  Monarch3* tMonarch3 = new Monarch3();
95 
96  try
97  {
98  tMonarch3->fFile = new H5::H5File( aFilename.c_str(), H5F_ACC_TRUNC );
99  }
100  catch( H5::Exception& e )
101  {
102  delete tMonarch3;
103  throw M3Exception() << "Could not open <" << aFilename << "> for writing; an H5::Exception was thrown: " << e.getCDetailMsg();
104  return nullptr;
105  }
106  catch( std::exception& e )
107  {
108  delete tMonarch3;
109  throw M3Exception() << "Could not open <" << aFilename << "> for writing; a std::exception was thrown: " << e.what();
110  return nullptr;
111  }
112  if( tMonarch3->fFile == nullptr )
113  {
114  delete tMonarch3;
115  throw M3Exception() << "Could not open <" << aFilename << "> for writing";
116  return nullptr;
117  }
118  LDEBUG( mlog, "Opened egg file <" << aFilename << "> for writing" );
119 
120  tMonarch3->fHeader = new M3Header();
121  tMonarch3->fHeader->Filename() = aFilename;
122 
123  tMonarch3->fState = eOpenToWrite;
124 
125  return tMonarch3;
126  }
127 
128  void Monarch3::ReadHeader() const
129  {
130  if( fState != eOpenToRead )
131  {
132  throw M3Exception() << "File not opened to read";
133  }
134 
135  // Read the header information from the file (run header, plus all stream and channel headers)
136  try
137  {
139  }
140  catch( H5::Exception& e )
141  {
142  throw M3Exception() << "HDF5 error while reading the header:\n\t" << e.getCDetailMsg() << " (function: " << e.getFuncName() << ")";
143  }
144  catch( M3Exception& e )
145  {
146  throw;
147  }
148 
149 
150  H5::Group* tStreamsGroup = fHeader->GetStreamsGroup();
151 
152  try
153  {
154  // Create the stream objects based on the configuration from the header
155  for( M3Header::M3StreamHeaders::const_iterator streamIt = fHeader->StreamHeaders().begin();
156  streamIt != fHeader->StreamHeaders().end();
157  ++streamIt )
158  {
159  fStreams.push_back( new M3Stream( *streamIt, tStreamsGroup ) );
160  fStreams.back()->SetMutex( fMutexPtr );
161  }
162  }
163  catch( H5::Exception& e )
164  {
165  throw M3Exception() << "HDF5 error while creating stream objects for reading:\n\t" << e.getDetailMsg() << " (function: " << e.getFuncName() << ")";
166  }
167  catch( M3Exception& e )
168  {
169  throw;
170  }
171 
173  return;
174  }
175 
177  {
178  if( fState != eOpenToWrite )
179  {
180  throw M3Exception() << "File not opened to write";
181  }
182 
183  // Write the header to the file
184  // This will create the following groups: run, streams, and channels
185  try
186  {
188  }
189  catch( H5::Exception& e )
190  {
191  throw M3Exception() << "HDF5 error while writing header:\n\t" << e.getDetailMsg() << " (function: " << e.getFuncName() << ")";
192  }
193  catch( M3Exception& e )
194  {
195  throw;
196  }
197 
198  H5::Group* tStreamsGroup = fHeader->GetStreamsGroup();
199 
200  try
201  {
202  // Create the stream objects based on the configuration from the header
203  for( M3Header::M3StreamHeaders::const_iterator streamIt = fHeader->StreamHeaders().begin();
204  streamIt != fHeader->StreamHeaders().end();
205  ++streamIt )
206  {
207  fStreams.push_back( new M3Stream( *streamIt, tStreamsGroup ) );
208  fStreams.back()->SetMutex( fMutexPtr );
209  }
210  }
211  catch( H5::Exception& e )
212  {
213  throw M3Exception() << "HDF5 error while creating stream objects:\n\t" << e.getDetailMsg() << " (function: " << e.getFuncName() << ")";
214  }
215  catch( M3Exception& e )
216  {
217  throw;
218  }
219 
221  return;
222  }
223 
225  {
226  LDEBUG( mlog, "Finishing reading <" << fHeader->Filename() << ">" );
227  try
228  {
229  if( fHeader != nullptr )
230  {
231  delete fHeader;
232  fHeader = nullptr;
233  }
234  for( std::vector< M3Stream* >::iterator streamIt = fStreams.begin(); streamIt != fStreams.end(); ++streamIt )
235  {
236  const_cast< const M3Stream* >(*streamIt)->Close();
237  delete *streamIt;
238  *streamIt = nullptr;
239  }
240  if( fFile != nullptr )
241  {
242  fFile->close();
243  delete fFile;
244  fFile = nullptr;
245  }
246  }
247  catch( H5::Exception& e )
248  {
249  throw M3Exception() << "Error while closing: " << e.getDetailMsg() << " (function: " << e.getFuncName() << ")";
250  }
251  fState = eClosed;
252  return;
253  }
254 
256  {
257  LINFO( mlog, "Finishing writing <" << fHeader->Filename() << ">" );
258  try
259  {
260  if( fHeader != nullptr )
261  {
262  delete fHeader;
263  fHeader = nullptr;
264  }
265  for( std::vector< M3Stream* >::iterator streamIt = fStreams.begin(); streamIt != fStreams.end(); ++streamIt )
266  {
267  (*streamIt)->Close();
268  delete *streamIt;
269  *streamIt = nullptr;
270  }
271  if( fFile != nullptr )
272  {
273  fFile->close();
274  delete fFile;
275  fFile = nullptr;
276  }
277  fFile = nullptr;
278  }
279  catch( H5::Exception& e )
280  {
281  throw M3Exception() << "Error while closing: " << e.getDetailMsg() << " (function: " << e.getFuncName() << ")";
282  }
283  fState = eClosed;
284  return;
285  }
286 
287 }
void FinishReading() const
Close the file.
Definition: M3Monarch.cc:224
M3Header * fHeader
Definition: M3Monarch.hh:125
void Close() const
Close the file.
Definition: M3Stream.cc:390
static const Monarch3 * OpenForReading(const std::string &filename)
Definition: M3Monarch.cc:56
void FinishWriting()
Close the file.
Definition: M3Monarch.cc:255
void ReadHeader() const
Definition: M3Monarch.cc:128
STL namespace.
virtual const char * what() const
Definition: M3Exception.cc:34
void ReadFromHDF5(const H5::H5File *aFile) const
Definition: M3Header.cc:500
Egg file header information.
Definition: M3Header.hh:152
const H5::Group * GetStreamsGroup() const
Definition: M3Header.hh:245
State GetState() const
Definition: M3Monarch.cc:51
Read/write access for a data stream.
Definition: M3Stream.hh:41
mutex_ptr fMutexPtr
Definition: M3Monarch.hh:131
Specialized exception class for Monarch3.
Definition: M3Exception.hh:28
H5::H5File * fFile
Definition: M3Monarch.hh:122
static scarab::logger mlog("M3Header")
std::vector< M3Stream *> fStreams
Definition: M3Monarch.hh:128
void WriteToHDF5(H5::H5File *aFile)
Definition: M3Header.cc:456
static Monarch3 * OpenForWriting(const std::string &filename)
Definition: M3Monarch.cc:92
Egg file read/write access.
Definition: M3Monarch.hh:40