Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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/JShell.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 
99  try {
100 
101  JProcess proc(MAKE_STRING("uname -a;" <<
102  "which " << argv[0]));
103 
104  istream in(proc.getInputStreamBuffer());
105 
106  getline(in, (*this)[system_t]);
107  getline(in, (*this)[command_t]);
108 
109  for (int i = 1; i != argc; ++i) {
110  if (get_number_of_tokens(argv[i]) == 1)
111  (*this)[command_t] += MAKE_STRING(' ' << argv[i]);
112  else
113  (*this)[command_t] += MAKE_STRING(' ' << "\\\"" << argv[i] << "\\\"");
114  }
115  }
116  catch(const JException& error) {
117  (*this)[system_t] = error.what();
118  }
119  }
120  }
121 
122 
123  /**
124  * Type conversion operator.
125  *
126  * \return comment
127  */
128  operator JComment() const
129  {
130  JComment comment;
131 
132  for (const_iterator i = this->begin(); i != this->end(); ++i) {
133  comment.add(i->first + ' ' + i->second);
134  }
135 
136  return comment;
137  }
138 
139 
140  /**
141  * Copy meta data.
142  *
143  * \param file_name name of input file
144  * \param out output file
145  */
146  static void copy(const char* const file_name, TFile& out);
147 
148 
149  /**
150  * Get equation parameters.
151  *
152  * \return equation parameters
153  */
155  {
156  static const JEquationParameters parameters("=", "\n", "", "");
157 
158  return parameters;
159  }
160 
161 
162  /**
163  * Extract meta data.
164  *
165  * \param buffer meta data
166  * \return meta data
167  */
168  static JMeta valueOf(const std::string& buffer)
169  {
170  using namespace std;
171  using namespace JPP;
172 
173  JMeta meta;
174 
175  istringstream is(buffer);
176 
178 
179  for (JEquation equation; is >> equation; ) {
180  meta[equation.getKey()] = equation.getValue();
181  }
182 
183  return meta;
184  }
185 
186 
187  /**
188  * Convert meta data to string.
189  *
190  * \return string
191  */
192  std::string toString() const
193  {
194  using namespace std;
195  using namespace JPP;
196 
197  ostringstream os;
198 
200 
201  for (JMeta::const_iterator i = this->begin(); i != this->end(); ++i) {
202  os << JEquation::make_equation(i->first, i->second);
203  }
204 
205  return os.str();
206  }
207 
208 
209  /**
210  * Write meta data to output.
211  *
212  * \param out output stream
213  * \param meta meta data
214  * \return output stream
215  */
216  friend inline std::ostream& operator<<(std::ostream& out, const JMeta& meta)
217  {
218  using namespace std;
219 
220  const_iterator p = meta.find(application_t);
221 
222  if (p != meta.end()) {
223  for (const_iterator i = meta.begin(); i != meta.end(); ++i) {
224  if (i != p) {
225  out << p->second << ' ' << i->second << endl;
226  }
227  }
228  }
229 
230  return out;
231  }
232  };
233 
234 
235  /**
236  * Get ROOT name of given data type.
237  *
238  * \param type JMeta type
239  * \return name of object to be read
240  */
241  inline const char* getName(const JType<JMeta>& type)
242  {
243  return META_NAME;
244  }
245 
246 
247  /**
248  * Get number of cycles of named objects with same title as given key.
249  *
250  * \param file pointer to file
251  * \param key ROOT key (including possible directory)
252  * \return number of cycles
253  */
254  inline int getNumberOfCycles(TFile* file, const TString key)
255  {
256  using namespace std;
257 
258  int counter = 0;
259 
260  if (file != NULL) {
261 
262  TNamed* __p = NULL;
263 
264  file->GetObject(key, __p);
265 
266  if (__p != NULL) {
267 
268  ++counter;
269 
270  const TString title = __p->GetTitle();
271 
272  string buffer(key);
273 
274  const string::size_type pos = buffer.find(';');
275 
276  if (pos != string::npos) {
277 
278  int cycle = -1;
279 
280  istringstream(buffer.substr(pos + 1)) >> cycle;
281 
282  buffer = buffer.substr(0, pos);
283 
284  for (int i = 1; i < cycle; ++i) {
285 
286  file->GetObject(MAKE_CSTRING(buffer << ';' << i), __p);
287 
288  if (__p != NULL && __p->GetTitle() == title) {
289  ++counter;
290  }
291  }
292  }
293  }
294  }
295 
296  return counter;
297  }
298 
299 
300  /**
301  * Read object from ROOT file.
302  *
303  * \param file pointer to file
304  * \param key key of object to be read
305  * \param ps pointer to object
306  */
307  inline void getObject(TFile* file, const char* key, JMeta*& ps)
308  {
309  using namespace std;
310  using namespace JPP;
311 
312  if (ps != NULL) {
313 
314  delete ps;
315 
316  ps = NULL;
317  }
318 
319  if (file != NULL) {
320 
321  const int number_of_cycles = getNumberOfCycles(file, MAKE_CSTRING(META_DIRECTORY << '/' << key));
322 
323  if (number_of_cycles != 0) {
324 
325  TNamed* __p = NULL;
326 
327  file->GetObject(MAKE_CSTRING(META_DIRECTORY << '/' << key), __p);
328 
329  ps = new JMeta();
330 
331  (*ps)[application_t] = __p->GetTitle();
332 
333  file->GetObject(MAKE_CSTRING(META_DIRECTORY << '/' << (*ps)[application_t] << ';' << number_of_cycles), __p);
334 
335  if (__p != NULL) {
336  *ps = JMeta::valueOf(__p->GetTitle());
337  }
338  }
339  }
340  }
341 
342 
343  /**
344  * Write meta data as ROOT TNamed object.
345  *
346  * \param dir pointer to directory
347  * \param key ROOT key
348  * \param buffer user data
349  * \return true if OK; else false
350  */
351  inline bool putMeta(TDirectory* dir, const std::string key, const std::string buffer)
352  {
353  static TNamed object;
354 
355  if (dir != NULL) {
356 
357  if (dir->GetListOfKeys()->FindObject(META_DIRECTORY) == NULL) {
358  dir->mkdir(META_DIRECTORY);
359  }
360 
361  dir = dir->GetDirectory(META_DIRECTORY);
362 
363  object.SetName (key.c_str()); // ROOT key
364  object.SetTitle(buffer.c_str()); // user data
365 
366  return (dir->WriteTObject(&object) > 0);
367  }
368 
369  return false;
370  }
371 
372 
373  /**
374  * Write meta data to ROOT directory.
375  *
376  * \param dir pointer to directory
377  * \param meta meta data
378  * \return true if OK; else false
379  */
380  inline bool putObject(TDirectory* dir, const JMeta& meta)
381  {
382  JMeta::const_iterator p = meta.find(application_t);
383 
384  if (p != meta.end()) {
385  if (putMeta(dir, getName(JType<JMeta>()), p->second)) {
386  return putMeta(dir, p->second, meta.toString());
387  }
388  }
389 
390  return false;
391  }
392 
393 
394  /**
395  * Copy meta data.
396  *
397  * \param file_name name of input file
398  * \param out output file
399  */
400  void JMeta::copy(const char* const file_name, TFile& out)
401  {
402  using namespace JPP;
403 
404  JRootFileReader<JMeta> in(file_name);
405 
406  while (in.hasNext()) {
407 
408  const JMeta* p = in.next();
409 
410  putObject(&out, *p);
411  }
412  }
413 
414 
415  /**
416  * Type definition of old meta data.
417  */
418  struct JMetaOld_t : public JMeta {};
419 
420 
421  /**
422  * Get ROOT name of given data type.
423  *
424  * \param type JMetaOld_t type
425  * \return name of object to be read
426  */
427  inline const char* getName(const JType<JMetaOld_t>& type)
428  {
429  return META_NAME;
430  }
431 
432 
433  /**
434  * Read object from ROOT file.
435  *
436  * \param file pointer to file
437  * \param key key of object to be read
438  * \param ps pointer to object
439  */
440  inline void getObject(TFile* file, const char* key, JMetaOld_t*& ps)
441  {
442  enum JParameter_t {
443  JApplication_t = 0, //!< application name
444  JSVNRelease_t, //!< SVN release
445  JROOTRelease_t, //!< ROOT release
446  JNamespace_t, //!< name space
447  JCommand_t, //!< Linux command
448  JSystem_t, //!< system information
449  number_of_items //!< number of items
450  };
451 
452  const char* buffer[number_of_items] = {
454  SVNrelease_t,
456  namespace_t,
457  command_t,
458  system_t
459  };
460 
461  if (ps != NULL) {
462 
463  delete ps;
464 
465  ps = NULL;
466  }
467 
468  if (file != NULL) {
469 
470  const int number_of_cycles = getNumberOfCycles(file, key);
471 
472  if (number_of_cycles != 0) {
473 
474  TNamed* __p = NULL;
475 
476  file->GetObject(key, __p);
477 
478  ps = new JMetaOld_t();
479 
480  (*ps)[application_t] = __p->GetTitle();
481 
482  for (int i = 1; i != number_of_items; ++i) {
483 
484  file->GetObject(MAKE_CSTRING((*ps)[application_t] << ';' << ((number_of_cycles - 1) * (number_of_items - 1) + i)), __p);
485 
486  if (__p != NULL)
487  (*ps)[buffer[i]] = __p->GetTitle();
488  else
489  break;
490  }
491  }
492  }
493  }
494 
495 
496  /**
497  * Write meta data to ROOT directory.
498  *
499  * \param dir pointer to directory
500  * \param meta meta data
501  * \return true if OK; else false
502  */
503  inline bool putObject(TDirectory* dir, const JMetaOld_t& meta)
504  {
505  return putObject(dir, static_cast<const JMeta&>(meta));
506  }
507 }
508 
509 #endif
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:71
General exception.
Definition: JException.hh:40
static const char *const application_t
Definition of meta data parameters.
Definition: JMeta.hh:59
std::string toString() const
Convert meta data to string.
Definition: JMeta.hh:192
Exceptions.
TObject * getObject(const JRootObjectID &id)
Get TObject.
static const char *const GITrelease_t
GIT release.
Definition: JMeta.hh:61
JMeta(const int argc, const char *const argv[])
Constructor.
Definition: JMeta.hh:87
bool putMeta(TDirectory *dir, const std::string key, const std::string buffer)
Write meta data as ROOT TNamed object.
Definition: JMeta.hh:351
static void copy(const char *const file_name, TFile &out)
Copy meta data.
Definition: JMeta.hh:400
#define MAKE_CSTRING(A)
Make C-string.
Definition: JPrint.hh:611
static equation_type< T > make_equation(const std::string &key, const T &value)
Auxiliary method to create equation type.
Definition: JEquation.hh:117
Simple data structure to support I/O of equations (see class JLANG::JEquation).
Jpp meta data.
Auxiliary class for a type holder.
Definition: JType.hh:19
std::string getNamespace(const std::string &type_name)
Get name space, i.e.
Definition: JeepToolkit.hh:207
static const char *const ROOTrelease_t
ROOT release.
Definition: JMeta.hh:62
static const char *const SVNrelease_t
SVN release.
Definition: JMeta.hh:60
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:602
I/O formatting auxiliaries.
Auxiliary methods for handling file names, type names and environment.
friend std::ostream & operator<<(std::ostream &out, const JMeta &meta)
Write meta data to output.
Definition: JMeta.hh:216
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:468
const char * getGITVersion()
Get GIT version.
Definition: Jpp.hh:53
size_t get_number_of_tokens(const std::string &buffer)
Count number of white space separated tokens.
static const char *const system_t
system information
Definition: JMeta.hh:65
Auxiliary class for comment.
Definition: JComment.hh:34
static const char *const namespace_t
name space
Definition: JMeta.hh:63
Type definition of old meta data.
Definition: JMeta.hh:418
JMeta()
Default constructor.
Definition: JMeta.hh:77
JLANG::JEquationFacet setequation
Type definition of stream manipulator for equational I/O.
Shell interaction via I/O streams.
static const char *const META_NAME
ROOT name for meta data.
Definition: JMeta.hh:47
System calls via shell interactions.
static JMeta valueOf(const std::string &buffer)
Extract meta data.
Definition: JMeta.hh:168
std::string getFilename(const std::string &file_name)
Get file name part, i.e.
Definition: JeepToolkit.hh:85
const char * getName()
Get ROOT name of given data type.
JComment & add(const std::string &comment)
Add comment.
Definition: JComment.hh:55
virtual const char * what() const
Get error message.
Definition: JException.hh:65
static const char *const command_t
Linux command.
Definition: JMeta.hh:64
int getNumberOfCycles(TFile *file, const TString key)
Get number of cycles of named objects with same title as given key.
Definition: JMeta.hh:254
static const JEquationParameters & getEquationParameters()
Get equation parameters.
Definition: JMeta.hh:154
static const char *const META_DIRECTORY
ROOT sub-directory for meta data.
Definition: JMeta.hh:53
bool putObject(TDirectory *dir, const T &object)
Write object to ROOT directory.