Jpp
JMeta.hh
Go to the documentation of this file.
1 #ifndef __JSUPPORT__JMETA__
2 #define __JSUPPORT__JMETA__
3 
4 #include <string>
5 #include <ostream>
6 #include <map>
7 
8 #include "RVersion.h"
9 #include "TFile.h"
10 #include "TNamed.h"
11 #include "TString.h"
12 
13 #include "JLang/JType.hh"
14 #include "JLang/JException.hh"
15 #include "JLang/JEquation.hh"
17 #include "JLang/Jpp.hh"
18 #include "JROOT/JRootFileReader.hh"
19 #include "JSystem/JUTSName.hh"
21 #include "Jeep/JComment.hh"
22 #include "Jeep/JeepToolkit.hh"
23 #include "Jeep/JPrint.hh"
24 
25 
26 /**
27  * \file
28  *
29  * ROOT I/O of application specific meta data.
30  * \author mdejong
31  */
32 
33 namespace JSUPPORT {}
34 namespace JPP { using namespace JSUPPORT; }
35 
36 namespace JSUPPORT {
37 
38  using JLANG::JType;
39  using JLANG::JException;
41  using JEEP::JComment;
42 
43 
44  /**
45  * ROOT name for meta data.
46  */
47  static const char* const META_NAME = "JMeta";
48 
49 
50  /**
51  * ROOT sub-directory for meta data.
52  */
53  static const char* const META_DIRECTORY = "META";
54 
55 
56  /**
57  * Definition of meta data parameters.
58  */
59  static const char* const application_t = "application"; //!< application name
60  static const char* const SVNrelease_t = "SVN"; //!< SVN release
61  static const char* const GITrelease_t = "GIT"; //!< GIT release
62  static const char* const ROOTrelease_t = "ROOT"; //!< ROOT release
63  static const char* const namespace_t = "namespace"; //!< name space
64  static const char* const command_t = "command"; //!< Linux command
65  static const char* const system_t = "system"; //!< system information
66 
67 
68  /**
69  * Auxiliary class for ROOT I/O of application specific meta data.
70  */
71  struct JMeta :
72  public std::map<std::string, std::string>
73  {
74  /**
75  * Default constructor.
76  */
78  {}
79 
80 
81  /**
82  * Constructor.
83  *
84  * \param argc number of command line arguments
85  * \param argv array of command line arguments
86  */
87  JMeta(const int argc, const char* const argv[])
88  {
89  using namespace std;
90  using namespace JPP;
91 
92  if (argc > 0) {
93 
94  (*this)[application_t] = getFilename(argv[0]);
95  (*this)[GITrelease_t] = getGITVersion();
96  (*this)[ROOTrelease_t] = ROOT_RELEASE;
97  (*this)[namespace_t] = getNamespace();
98  (*this)[command_t] = MAKE_STRING(getPath(PATH, argv[0]) << '/' << argv[0]);
99 
100  for (int i = 1; i != argc; ++i) {
101  if (get_number_of_tokens(argv[i]) == 1)
102  (*this)[command_t] += MAKE_STRING(' ' << argv[i]);
103  else
104  (*this)[command_t] += MAKE_STRING(' ' << "\\\"" << argv[i] << "\\\"");
105  }
106 
107  const JUTSName buffer;
108 
109  (*this)[system_t] = MAKE_STRING(""
110  << buffer.sysname << ' '
111  << buffer.nodename << ' '
112  << buffer.release << ' '
113  << buffer.version << ' '
114  << buffer.machine);
115  }
116  }
117 
118 
119  /**
120  * Type conversion operator.
121  *
122  * \return comment
123  */
124  operator JComment() const
125  {
126  JComment comment;
127 
128  for (const_iterator i = this->begin(); i != this->end(); ++i) {
129  comment.add(i->first + ' ' + i->second);
130  }
131 
132  return comment;
133  }
134 
135 
136  /**
137  * Copy meta data.
138  *
139  * \param file_name name of input file
140  * \param out output file
141  */
142  static void copy(const char* const file_name, TFile& out);
143 
144 
145  /**
146  * Get equation parameters.
147  *
148  * \return equation parameters
149  */
151  {
152  static const JEquationParameters parameters("=", "\n", "", "");
153 
154  return parameters;
155  }
156 
157 
158  /**
159  * Extract meta data.
160  *
161  * \param buffer meta data
162  * \return meta data
163  */
164  static JMeta valueOf(const std::string& buffer)
165  {
166  using namespace std;
167  using namespace JPP;
168 
169  JMeta meta;
170 
171  istringstream is(buffer);
172 
174 
175  for (JEquation equation; is >> equation; ) {
176  meta[equation.getKey()] = equation.getValue();
177  }
178 
179  return meta;
180  }
181 
182 
183  /**
184  * Convert meta data to string.
185  *
186  * \return string
187  */
188  std::string toString() const
189  {
190  using namespace std;
191  using namespace JPP;
192 
193  ostringstream os;
194 
196 
197  for (JMeta::const_iterator i = this->begin(); i != this->end(); ++i) {
198  os << JEquation::make_equation(i->first, i->second);
199  }
200 
201  return os.str();
202  }
203 
204 
205  /**
206  * Write meta data to output.
207  *
208  * \param out output stream
209  * \param meta meta data
210  * \return output stream
211  */
212  friend inline std::ostream& operator<<(std::ostream& out, const JMeta& meta)
213  {
214  using namespace std;
215 
216  const_iterator p = meta.find(application_t);
217 
218  if (p != meta.end()) {
219  for (const_iterator i = meta.begin(); i != meta.end(); ++i) {
220  if (i != p) {
221  out << p->second << ' ' << i->second << endl;
222  }
223  }
224  }
225 
226  return out;
227  }
228  };
229 
230 
231  /**
232  * Get ROOT name of given data type.
233  *
234  * \param type JMeta type
235  * \return name of object to be read
236  */
237  inline const char* getName(const JType<JMeta>& type)
238  {
239  return META_NAME;
240  }
241 
242 
243  /**
244  * Get number of cycles of named objects with same title as given key.
245  *
246  * \param file pointer to file
247  * \param key ROOT key (including possible directory)
248  * \return number of cycles
249  */
250  inline int getNumberOfCycles(TFile* file, const TString key)
251  {
252  using namespace std;
253 
254  int counter = 0;
255 
256  if (file != NULL) {
257 
258  TNamed* __p = NULL;
259 
260  file->GetObject(key, __p);
261 
262  if (__p != NULL) {
263 
264  ++counter;
265 
266  const TString title = __p->GetTitle();
267 
268  string buffer(key);
269 
270  const string::size_type pos = buffer.find(';');
271 
272  if (pos != string::npos) {
273 
274  int cycle = -1;
275 
276  istringstream(buffer.substr(pos + 1)) >> cycle;
277 
278  buffer = buffer.substr(0, pos);
279 
280  for (int i = 1; i < cycle; ++i) {
281 
282  file->GetObject(MAKE_CSTRING(buffer << ';' << i), __p);
283 
284  if (__p != NULL && __p->GetTitle() == title) {
285  ++counter;
286  }
287  }
288  }
289  }
290  }
291 
292  return counter;
293  }
294 
295 
296  /**
297  * Read object from ROOT file.
298  *
299  * \param file pointer to file
300  * \param key key of object to be read
301  * \param ps pointer to object
302  */
303  inline void getObject(TFile* file, const char* key, JMeta*& ps)
304  {
305  using namespace std;
306  using namespace JPP;
307 
308  if (ps != NULL) {
309 
310  delete ps;
311 
312  ps = NULL;
313  }
314 
315  if (file != NULL) {
316 
317  const int number_of_cycles = getNumberOfCycles(file, MAKE_CSTRING(META_DIRECTORY << '/' << key));
318 
319  if (number_of_cycles != 0) {
320 
321  TNamed* __p = NULL;
322 
323  file->GetObject(MAKE_CSTRING(META_DIRECTORY << '/' << key), __p);
324 
325  ps = new JMeta();
326 
327  (*ps)[application_t] = __p->GetTitle();
328 
329  file->GetObject(MAKE_CSTRING(META_DIRECTORY << '/' << (*ps)[application_t] << ';' << number_of_cycles), __p);
330 
331  if (__p != NULL) {
332  *ps = JMeta::valueOf(__p->GetTitle());
333  }
334  }
335  }
336  }
337 
338 
339  /**
340  * Write meta data as ROOT TNamed object.
341  *
342  * \param dir pointer to directory
343  * \param key ROOT key
344  * \param buffer user data
345  * \return true if OK; else false
346  */
347  inline bool putMeta(TDirectory* dir, const std::string key, const std::string buffer)
348  {
349  static TNamed object;
350 
351  if (dir != NULL) {
352 
353  if (dir->GetListOfKeys()->FindObject(META_DIRECTORY) == NULL) {
354  dir->mkdir(META_DIRECTORY);
355  }
356 
357  dir = dir->GetDirectory(META_DIRECTORY);
358 
359  object.SetName (key.c_str()); // ROOT key
360  object.SetTitle(buffer.c_str()); // user data
361 
362  return (dir->WriteTObject(&object) > 0);
363  }
364 
365  return false;
366  }
367 
368 
369  /**
370  * Write meta data to ROOT directory.
371  *
372  * \param dir pointer to directory
373  * \param meta meta data
374  * \return true if OK; else false
375  */
376  inline bool putObject(TDirectory* dir, const JMeta& meta)
377  {
378  JMeta::const_iterator p = meta.find(application_t);
379 
380  if (p != meta.end()) {
381  if (putMeta(dir, getName(JType<JMeta>()), p->second)) {
382  return putMeta(dir, p->second, meta.toString());
383  }
384  }
385 
386  return false;
387  }
388 
389 
390  /**
391  * Copy meta data.
392  *
393  * \param file_name name of input file
394  * \param out output file
395  */
396  void JMeta::copy(const char* const file_name, TFile& out)
397  {
398  using namespace JPP;
399 
400  JRootFileReader<JMeta> in(file_name);
401 
402  while (in.hasNext()) {
403 
404  const JMeta* p = in.next();
405 
406  putObject(&out, *p);
407  }
408  }
409 
410 
411  /**
412  * Type definition of old meta data.
413  */
414  struct JMetaOld_t : public JMeta {};
415 
416 
417  /**
418  * Get ROOT name of given data type.
419  *
420  * \param type JMetaOld_t type
421  * \return name of object to be read
422  */
423  inline const char* getName(const JType<JMetaOld_t>& type)
424  {
425  return META_NAME;
426  }
427 
428 
429  /**
430  * Read object from ROOT file.
431  *
432  * \param file pointer to file
433  * \param key key of object to be read
434  * \param ps pointer to object
435  */
436  inline void getObject(TFile* file, const char* key, JMetaOld_t*& ps)
437  {
438  enum JParameter_t {
439  JApplication_t = 0, //!< application name
440  JSVNRelease_t, //!< SVN release
441  JROOTRelease_t, //!< ROOT release
442  JNamespace_t, //!< name space
443  JCommand_t, //!< Linux command
444  JSystem_t, //!< system information
445  number_of_items //!< number of items
446  };
447 
448  const char* buffer[number_of_items] = {
450  SVNrelease_t,
452  namespace_t,
453  command_t,
454  system_t
455  };
456 
457  if (ps != NULL) {
458 
459  delete ps;
460 
461  ps = NULL;
462  }
463 
464  if (file != NULL) {
465 
466  const int number_of_cycles = getNumberOfCycles(file, key);
467 
468  if (number_of_cycles != 0) {
469 
470  TNamed* __p = NULL;
471 
472  file->GetObject(key, __p);
473 
474  ps = new JMetaOld_t();
475 
476  (*ps)[application_t] = __p->GetTitle();
477 
478  for (int i = 1; i != number_of_items; ++i) {
479 
480  file->GetObject(MAKE_CSTRING((*ps)[application_t] << ';' << ((number_of_cycles - 1) * (number_of_items - 1) + i)), __p);
481 
482  if (__p != NULL)
483  (*ps)[buffer[i]] = __p->GetTitle();
484  else
485  break;
486  }
487  }
488  }
489  }
490 
491 
492  /**
493  * Write meta data to ROOT directory.
494  *
495  * \param dir pointer to directory
496  * \param meta meta data
497  * \return true if OK; else false
498  */
499  inline bool putObject(TDirectory* dir, const JMetaOld_t& meta)
500  {
501  return putObject(dir, static_cast<const JMeta&>(meta));
502  }
503 }
504 
505 #endif
JException.hh
JSUPPORT::JMeta::operator<<
friend std::ostream & operator<<(std::ostream &out, const JMeta &meta)
Write meta data to output.
Definition: JMeta.hh:212
JRootFileReader.hh
JSUPPORT::getObject
void getObject(TFile *file, const char *key, JMetaOld_t *&ps)
Read object from ROOT file.
Definition: JMeta.hh:436
JUTSName.hh
JSUPPORT::META_DIRECTORY
static const char *const META_DIRECTORY
ROOT sub-directory for meta data.
Definition: JMeta.hh:53
JLANG::JType
Auxiliary class for a type holder.
Definition: JType.hh:19
JPrint.hh
JSUPPORT::putMeta
bool putMeta(TDirectory *dir, const std::string key, const std::string buffer)
Write meta data as ROOT TNamed object.
Definition: JMeta.hh:347
JSUPPORT::namespace_t
static const char *const namespace_t
name space
Definition: JMeta.hh:63
JSUPPORT::GITrelease_t
static const char *const GITrelease_t
GIT release.
Definition: JMeta.hh:61
JEEP::getPath
std::string getPath(const std::string &file_name)
Get path, i.e.
Definition: JeepToolkit.hh:106
JSUPPORT::getName
const char * getName(const JType< JMetaOld_t > &type)
Get ROOT name of given data type.
Definition: JMeta.hh:423
JSUPPORT::JMeta::JMeta
JMeta(const int argc, const char *const argv[])
Constructor.
Definition: JMeta.hh:87
MAKE_STRING
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:699
JEquationParameters.hh
JSUPPORT::JMeta::toString
std::string toString() const
Convert meta data to string.
Definition: JMeta.hh:188
JLANG::get_number_of_tokens
size_t get_number_of_tokens(const std::string &buffer)
Count number of white space separated tokens.
Definition: JLangToolkit.hh:269
JPP
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Definition: JAAnetToolkit.hh:37
MAKE_CSTRING
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:708
JSUPPORT::JMeta::getEquationParameters
static const JEquationParameters & getEquationParameters()
Get equation parameters.
Definition: JMeta.hh:150
JEEP::getNamespace
std::string getNamespace(const std::string &type_name)
Get name space, i.e.
Definition: JeepToolkit.hh:223
JSUPPORT::JMetaOld_t
Type definition of old meta data.
Definition: JMeta.hh:414
JSUPPORT::application_t
static const char *const application_t
Definition of meta data parameters.
Definition: JMeta.hh:59
JEEP::getFilename
std::string getFilename(const std::string &file_name)
Get file name part, i.e.
Definition: JeepToolkit.hh:86
JSUPPORT::system_t
static const char *const system_t
system information
Definition: JMeta.hh:65
JLANG::getGITVersion
const char * getGITVersion()
Get GIT version.
Definition: Jpp.hh:58
JSUPPORT::JMeta::JMeta
JMeta()
Default constructor.
Definition: JMeta.hh:77
std::map
Definition: JSTDTypes.hh:16
Jpp.hh
JEEP::JComment
Auxiliary class for comment.
Definition: JComment.hh:34
JEEP::PATH
static const char *const PATH
binary file paths
Definition: JeepToolkit.hh:30
JEquation.hh
JLANG::JEquationParameters
Simple data structure to support I/O of equations (see class JLANG::JEquation).
Definition: JEquationParameters.hh:20
JLANG::setequation
JLANG::JEquationFacet setequation
Type definition of stream manipulator for equational I/O.
Definition: JEquationFacet.hh:468
JSUPPORT::META_NAME
static const char *const META_NAME
ROOT name for meta data.
Definition: JMeta.hh:47
JSUPPORT::JMeta
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:71
std
Definition: jaanetDictionary.h:36
JSUPPORT
Support classes and methods for experiment specific I/O.
Definition: JDataWriter.cc:38
JSUPPORT::JMeta::valueOf
static JMeta valueOf(const std::string &buffer)
Extract meta data.
Definition: JMeta.hh:164
JeepToolkit.hh
JLANG::JEquation::make_equation
static equation_type< T > make_equation(const std::string &key, const T &value)
Auxiliary method to create equation type.
Definition: JEquation.hh:117
JSUPPORT::SVNrelease_t
static const char *const SVNrelease_t
SVN release.
Definition: JMeta.hh:60
JSUPPORT::ROOTrelease_t
static const char *const ROOTrelease_t
ROOT release.
Definition: JMeta.hh:62
JSUPPORT::getNumberOfCycles
int getNumberOfCycles(TFile *file, const TString key)
Get number of cycles of named objects with same title as given key.
Definition: JMeta.hh:250
JEEP::JComment::add
JComment & add(const std::string &comment)
Add comment.
Definition: JComment.hh:55
JType.hh
JSUPPORT::putObject
bool putObject(TDirectory *dir, const JMetaOld_t &meta)
Write meta data to ROOT directory.
Definition: JMeta.hh:499
JLANG::JException
General exception.
Definition: JException.hh:23
JSystemToolkit.hh
JComment.hh
JSUPPORT::JMeta::copy
static void copy(const char *const file_name, TFile &out)
Copy meta data.
Definition: JMeta.hh:396
JSUPPORT::command_t
static const char *const command_t
Linux command.
Definition: JMeta.hh:64