QDaq  0.2.6
Qt-based Data Aqcuisition
 All Classes Functions Variables Typedefs Enumerations Enumerator Properties Groups Pages
qdaqh5file.cpp
1 #include "qdaqh5file.h"
2 
3 #include "QDaqObject.h"
4 #include "QDaqRoot.h"
5 #include "QDaqDataBuffer.h"
6 
7 #include <QDebug>
8 
9 #include "h5helper_v1_1.h"
10 
11 #define CLASS_ATTR_NAME "Class"
12 
13 QDaqH5File::QDaqH5File() : helper_(0)
14 {
15 
16 }
17 
18 QDaqH5File::~QDaqH5File()
19 {
20  if (helper_) delete helper_;
21 }
22 
23 bool QDaqH5File::h5write(const QDaqObject* obj, const QString& filename)
24 {
25  QString S;
26  H5File *file = 0;
27 
28  // Try block to detect exceptions raised by any of the calls inside it
29  try
30  {
31  /*
32  * Turn off the auto-printing when failure occurs so that we can
33  * handle the errors appropriately
34  */
35  Exception::dontPrint();
36 
37  /*
38  * Create the named file, truncating the existing one if any,
39  * using default create and access property lists.
40  */
41  file = new H5File( filename.toLatin1(), H5F_ACC_TRUNC );
42 
43  // get a last version helper
44  newHelper(V_LAST);
45  warnings_.clear();
46 
47  helper()->write(file, "Timestamp", QDateTime::currentDateTime().toString(Qt::ISODate));
48  helper()->write(file, "FileType", "QDaq");
49  helper()->write(file, "FileVersionMajor", QString::number(helper()->major()));
50  helper()->write(file, "FileVersionMinor", QString::number(helper()->minor()));
51 
52  top_ = obj;
53  writeRecursive(file,obj);
54 
55  } // end of try block
56 
57  // catch failure caused by the H5File operations
58  catch( FileIException error )
59  {
60  S = "HDF5 File Error.";
61  S += " In function ";
62  S += error.getCFuncName();
63  S += ". ";
64  S += error.getCDetailMsg();
65  }
66 
67  // catch failure caused by the DataSet operations
68  catch( DataSetIException error )
69  {
70  S = "HDF5 DataSet Error.";
71  S += " In function ";
72  S += error.getCFuncName();
73  S += ". ";
74  S += error.getCDetailMsg();
75  }
76 
77  // catch failure caused by the DataSpace operations
78  catch( DataSpaceIException error )
79  {
80  S = "HDF5 DataSpace Error.";
81  S += " In function ";
82  S += error.getCFuncName();
83  S += ". ";
84  S += error.getCDetailMsg();
85  }
86 
87  // catch failure caused by the Attribute operations
88  catch( AttributeIException error )
89  {
90  S = "HDF5 Attribute Error.";
91  S += " In function ";
92  S += error.getCFuncName();
93  S += ". ";
94  S += error.getCDetailMsg();
95  }
96 
97  // catch failure caused by the DataType operations
98  catch( DataTypeIException error )
99  {
100  S = "HDF5 DataType Error.";
101  S += " In function ";
102  S += error.getCFuncName();
103  S += ". ";
104  S += error.getCDetailMsg();
105  }
106 
107  // catch failure caused by the DataType operations
108  catch( PropListIException error )
109  {
110  S = "HDF5 PropList Error.";
111  S += " In function ";
112  S += error.getCFuncName();
113  S += ". ";
114  S += error.getCDetailMsg();
115  }
116 
117  // catch failure caused by the DataType operations
118  catch( GroupIException error )
119  {
120  S = "HDF5 Group Error.";
121  S += " In function ";
122  S += error.getCFuncName();
123  S += ". ";
124  S += error.getCDetailMsg();
125  }
126 
127  if (file) delete file;
128 
129  if (!S.isEmpty())
130  {
131  qDebug() << S;
132  lastError_ = S;
133  return false;
134  }
135 
136  return true;
137 }
138 
139 QDaqObject *QDaqH5File::h5read(const QString& filename)
140 {
141  QString S;
142  H5File *file = 0;
143  QDaqObject* obj(0);
144 
145  // Try block to detect exceptions raised by any of the calls inside it
146  try
147  {
148  /*
149  * Turn off the auto-printing when failure occurs so that we can
150  * handle the errors appropriately
151  */
152  Exception::dontPrint();
153 
154  /*
155  * Open the named file with read-only access
156  */
157  file = new H5File( filename.toLatin1(), H5F_ACC_RDONLY );
158 
159  newHelper(V_LAST);
160  warnings_.clear();
161 
162  QString fileType, vMajor, vMinor;
163 
164  bool ret = helper()->read(file,"FileType",fileType);
165  if (!ret) {
166  lastError_ = "Error reading file: 'FileType' field not found";
167  return 0;
168  }
169  if (fileType!="QDaq") {
170  lastError_ = "Error reading file: 'FileType' is not 'QDaq'";
171  return 0;
172  }
173  ret = helper()->read(file,"FileVersionMajor",vMajor);
174  if (!ret) {
175  lastError_ = "Error reading file: 'FileVersionMajor' field not found";
176  return 0;
177  }
178  ret = helper()->read(file,"FileVersionMinor",vMinor);
179  if (!ret) {
180  lastError_ = "Error reading file: 'FileVersionMinor' field not found";
181  return 0;
182  }
183  Version fileVersion = toVersion(vMajor.toInt(),vMinor.toInt());
184  if (fileVersion==V_INVALID) {
185  lastError_ = QString("Error reading file: Not a valid version, vMajor = %1, vMinor = %2").arg(vMajor).arg(vMinor);
186  return 0;
187  }
188 
189  newHelper(fileVersion);
190  readRecursive(file,obj);
191 
192  } // end of try block
193 
194  // catch failure caused by the H5File operations
195  catch( FileIException error )
196  {
197  S = "HDF5 File Error.";
198  S += " In function ";
199  S += error.getCFuncName();
200  S += ". ";
201  S += error.getCDetailMsg();
202  }
203 
204  // catch failure caused by the DataSet operations
205  catch( DataSetIException error )
206  {
207  S = "HDF5 DataSet Error.";
208  S += " In function ";
209  S += error.getCFuncName();
210  S += ". ";
211  S += error.getCDetailMsg();
212  }
213 
214  // catch failure caused by the DataSpace operations
215  catch( DataSpaceIException error )
216  {
217  S = "HDF5 DataSpace Error.";
218  S += " In function ";
219  S += error.getCFuncName();
220  S += ". ";
221  S += error.getCDetailMsg();
222  }
223 
224  // catch failure caused by the Attribute operations
225  catch( AttributeIException error )
226  {
227  S = "HDF5 Attribute Error.";
228  S += " In function ";
229  S += error.getCFuncName();
230  S += ". ";
231  S += error.getCDetailMsg();
232  }
233 
234  // catch failure caused by the DataType operations
235  catch( DataTypeIException error )
236  {
237  S = "HDF5 DataType Error.";
238  S += " In function ";
239  S += error.getCFuncName();
240  S += ". ";
241  S += error.getCDetailMsg();
242  }
243 
244  // catch failure caused by the DataType operations
245  catch( PropListIException error )
246  {
247  S = "HDF5 PropList Error.";
248  S += " In function ";
249  S += error.getCFuncName();
250  S += ". ";
251  S += error.getCDetailMsg();
252  }
253 
254  // catch failure caused by the DataType operations
255  catch( GroupIException error )
256  {
257  S = "HDF5 Group Error.";
258  S += " In function ";
259  S += error.getCFuncName();
260  S += ". ";
261  S += error.getCDetailMsg();
262  }
263 
264  if (file) delete file;
265 
266  if (!S.isEmpty())
267  {
268  qDebug() << S;
269  lastError_ = S;
270  }
271 
272  return obj;
273 }
274 
275 void QDaqH5File::writeRecursive(CommonFG* h5g, const QDaqObject* obj)
276 {
277  H5::Group objGroup = helper()->createGroup(h5g, obj->objectName().toLatin1().constData());
278 
279  obj->writeh5(&objGroup, this);
280 
281  foreach(const QDaqObject* ch, obj->children()) writeRecursive(&objGroup, ch);
282 }
283 
284 void QDaqH5File::readRecursive(CommonFG* h5g, QDaqObject* &parent_obj)
285 {
286  bool isRoot = parent_obj==0;
287  QByteArrayList groups = helper()->getGroupNames(h5g, isRoot);
288 
289  foreach(QByteArray groupName, groups) {
290  Group g = h5g->openGroup(groupName);
291  QString className;
292  if (helper()->read(&g,CLASS_ATTR_NAME,className))
293  {
294  if (className=="QDaqRoot") className = "QDaqObject";
295  QDaqObject* obj = QDaqObject::root()->createObject(groupName,className);
296  if (obj)
297  {
298  if (parent_obj) parent_obj->appendChild(obj);
299  else {
300  parent_obj = obj;
301  top_ = obj;
302  }
303 
304  obj->readh5(&g,this);
305  readRecursive(&g, obj);
306  }
307  else delete obj;
308  }
309  }
310 
311  if (isRoot) helper()->connectDeferedPointers();
312 }
313 
314 void QDaqH5File::newHelper(Version v)
315 {
316  if (helper_) {
317  delete helper_;
318  helper_ = 0;
319  }
320 
321  switch (v) {
322  case V_1_0:
323  helper_ = new h5helper_v1_0(this); return;
324  case V_1_1:
325  helper_ = new h5helper_v1_1(this); return;
326  default:
327  helper_ = new h5helper_v1_1(this); return;
328  }
329 
330 }
331 
332 // Check if a dataset "name" exists in H5 file/group
333 bool h5helper::h5exist_ds(CommonFG* h5obj, const char* name)
334 {
335  H5O_info_t info;
336  return H5Lexists(h5obj->getLocId(),name,0) &&
337  H5Oget_info_by_name(h5obj->getLocId(),name,&info,0)>=0 &&
338  info.type==H5O_TYPE_DATASET;
339 }
340 
341 QString h5helper::groupName(CommonFG* h5obj)
342 {
343  int sz = H5Iget_name(h5obj->getLocId(),0,0);
344  if (sz) {
345  QByteArray ba(sz+1,char(0));
346  H5Iget_name(h5obj->getLocId(),ba.data(),sz+1);
347  return QString(ba);
348  } else return QString();
349 }
350 
351 void h5helper::deferObjPtrRead(QDaqObject *obj, const char *name, const QString &path)
352 {
353  deferedPtrData d(obj,name,path);
354  deferedPtrs << d;
355 }
356 
357 void h5helper::deferObjPtrRead(QDaqObject *obj, const char *name, const QStringList &paths)
358 {
359  deferedPtrData d(obj,name,paths);
360  deferedPtrs << d;
361 }
Base class of all QDaq objects.
Definition: QDaqObject.h:108
QDaqObject * createObject(const QString &name, const QString &className)
Create a QDaqObject with name name and class className.
Definition: QDaqRoot.cpp:98
static QDaqRoot * root()
Obtain a pointer to the one-and-only QDaqRoot object.
Definition: QDaqObject.h:168
QDaqObjectList children() const
Return a list of children of this object.
Definition: QDaqObject.h:258
virtual void writeh5(H5::Group *g, QDaqH5File *f) const
Write contents of the object to a H5 group.
QDaqObject * appendChild(QDaqObject *obj)
Adds a new child QDaqObject, as the last child and returns a pointer to it.
Definition: QDaqObject.cpp:321
virtual void readh5(H5::Group *g, QDaqH5File *f)
Read contents of the object from a H5 group.