Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Head.hh
Go to the documentation of this file.
1 #ifndef HEAD_HH_INCLUDED
2 #define HEAD_HH_INCLUDED
3 
4 #include "Vec.hh"
5 #include "Exception.hh"
6 
7 #include "TObject.h"
8 
9 #include <string>
10 #include <sstream>
11 #include <iostream>
12 #include <map>
13 #include <algorithm>
14 
15 
16 
17 
18 /**
19  * Trim a string in place
20  *
21  * \param s input string
22  * \return list of tokens
23  */
24 static inline void trimstring(std::string &s)
25 {
26  // from the left
27  s.erase( s.begin(), std::find_if(s.begin(), s.end(), [](int ch) {
28  return !std::isspace(ch);
29  }));
30 
31  // from the right
32  s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) {
33  return !std::isspace(ch);
34  }).base(), s.end());
35 }
36 
37 /**
38  * Split string at delimiter. Trailing and leading whitespace is removed from each token.
39  * Empty tokens are not put in the output list.
40  *
41  * \param str input string
42  * \param delim token delimiter
43  * \return list of tokens
44  */
45 inline std::vector<std::string> splitstring(const std::string& str, char delim = ' ')
46 {
47  using namespace std;
48 
50 
51  stringstream ss(str);
52  string token;
53  while (getline(ss, token, delim))
54  {
55  trimstring(token);
56  if (token != "") r.push_back(token);
57  }
58 
59  return r;
60 }
61 
62 
63 /**
64  * The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred to as "tags") and values.
65  */
66 struct Head : public TObject, std::map<std::string, std::string>
67 {
68 
69  /**
70  * Check availability of data with the given key.
71  *
72  * \param key key
73  * \return true if data are available; else false
74  */
75  bool have_line (std::string key ) const
76  {
77  return count( key ) != 0;
78  }
79 
80  /**
81  * Get data with the given key.\n
82  * This method throws a run-time exception if no data are available.
83  *
84  * \param key key
85  * \return data
86  */
87  const std::string& get_line( std::string key ) const
88  {
89  return this->at(key);
90  }
91 
92  /**
93  * Get data with the given key.\n
94  * This method throws a run-time exception if no data are available.
95  *
96  * \param key key
97  * \return data
98  */
99  std::string& get_line( std::string key )
100  {
101  return this->at(key);
102  }
103 
104  /**
105  * Set data with the given key.
106  *
107  * \param key key
108  * \param line data
109  */
110  void set_line( std::string key, std::string line )
111  {
113  }
114 
115  /**
116  * Get data with the given key at given index.\n
117  * This method throws a run-time exception if no data are available.
118  *
119  * \param key key
120  * \param idx index
121  * \return data
122  */
123  std::string get_field( std::string key, int idx ) const
124  {
125  using namespace std;
126 
128 
129  if ( idx < 0 || idx >= int ( v.size() ) )
130  {
131  THROW(Exception, "Cannot find word number " << idx << " in line " << get_line(key) << " for key: " << key);
132  }
133  return v[idx];
134  }
135 
136  /**
137  * Get index of data with the given key at given field.\n
138  *
139  * Note that this method uses the dictionary define in method Head::_hdr_dict.
140  *
141  * \param key key
142  * \param field field
143  * \return index (-1 if not present)
144  */
145  int get_index_of_field(std::string key, std::string field) const
146  {
147  auto v = _hdr_dict()[key];
148  auto i = std::find (v.begin(), v.end(), field );
149  if (i == v.end()) return -1;
150  return i - v.begin();
151  }
152 
153  /**
154  * Get data with the given key at given field.\n
155  * This method throws a run-time exception if no field is available.
156  *
157  * Note that this method uses the dictionary define in method Head::_hdr_dict.
158  *
159  * \param key key
160  * \param field field
161  * \return data
162  */
163  std::string get_field( std::string key, std::string field ) const
164  {
165  int idx = get_index_of_field(key, field);
166 
167  if ( idx == -1 )
168  {
169  THROW(Exception, "Failed to find" << key << " " << field);
170  }
171 
172  return get_field( key, idx );
173  }
174 
175 
176  /**
177  * Set data with the given key at given field.\n
178  * This method throws a run-time exception if no field available.
179  *
180  * Note that this method uses the dictionary define in method Head::_hdr_dict.
181  *
182  * \param key key
183  * \param field field
184  * \param value vakue
185  */
186  void set_field( std::string key, std::string field, std::string value )
187  {
188  using namespace std;
189 
190  if ( field == "" ) get_line( key ) = value;
191 
192  int idx = get_index_of_field( key, field );
193 
194  if ( idx < 0 )
195  {
196  THROW(Exception, "GFailed to find field in header line: " << key << " " << field);
197  }
198 
199  vector<string> vals = splitstring( get_line( key ) );
200 
201  // if the fields before do not exist, add padding
202  while ( int( vals.size() ) <= idx ) vals.push_back("0");
203 
204  vals[idx] = value;
205  ostringstream ss;
206 
207  for (unsigned i = 0; i < vals.size() ; i++ )
208  {
209  ss << vals[i];
210  if ( i != vals.size() - 1) ss << " ";
211  }
212  set_line( key, ss.str() );
213 
214  }
215 
216  /**
217  * Print header.
218  *
219  * \param out output stream
220  */
221  void print ( std::ostream& out = std::cout ) const
222  {
223  if (count("start_run")) out << "start_run: " << at("start_run") << std::endl;
224 
225  for ( auto& p : *this )
226  {
227  if ( p.first == "start_run" || p.first == "end_event" ) continue;
228  out << p.first << ": " << p.second << std::endl ;
229  }
230  out << "end_event:" << std::endl;
231  }
232 
233  /**
234  * Get internal description of the known lines in header.
235  *
236  * \return internal dictionary
237  */
239  {
240  using namespace std;
241 
242  // map with, for each tag (key), a vector of field-names
243 
244  static map<string, vector<string> > r;
245  if ( r.size() > 0 ) return r;
246 
247  string desc =
248  "DAQ:livetime\n"
249  "cut_primary cut_seamuon cut_in cut_nu:Emin Emax cosTmin cosTmax\n"
250  "generator physics simul:program version date time\n"
251  "seed:program level iseed\n"
252  "PM1_type_area:type area TTS\n"
253  "PDF:i1 i2\n"
254  "model:interaction muon scattering numberOfEnergyBins\n"
255  "can:zmin zmax r\n"
256  "genvol:zmin zmax r volume numberOfEvents\n"
257  "merge:time gain\n"
258  "coord_origin:x y z\n"
259  "translate:x y z\n"
260  "genhencut:gDir Emin\n"
261  "k40:rate time\n"
262  "norma:primaryFlux numberOfPrimaries\n"
263  "livetime:numberOfSeconds errorOfSeconds\n"
264  "flux:type key file_1 file_2\n"
265  "spectrum:alpha\n"
266  "fixedcan:xcenter ycenter zmin zmax radius\n"
267  "start_run:run_id";
268 
269  for ( auto line : splitstring(desc, '\n') )
270  {
271  auto v = splitstring( line, ':');
272 
273  vector< string > fields = splitstring( v[1] );
274  for ( auto key : splitstring( v[0] ) )
275  {
276  r[key] = fields;
277  }
278  }
279  return r;
280  }
281 
282 
283  /**
284  * Get the number of generated events needed for computing event rates.
285  *
286  * \return number of events
287  */
288  double ngen() const
289  {
290  return stod ( get_field("genvol", "numberOfEvents") );
291  }
292 
293  /**
294  * Get the the live time provided by the DAQ sytstem (=number of processed timeslices * frametime).
295  *
296  * \return live time [s]
297  */
298  double daq_livetime() const
299  {
300  return stod ( get_field("DAQ", "livetime") );
301  }
302 
303 
304  /**
305  * Get the Monte Carlo live time
306  *
307  * \return live time [s]
308  */
309  double mc_livetime() const
310  {
311  return stod ( get_field("livetime", "numberOfSeconds") );
312  }
313 
314  /**
315  * Get coordinate origin.
316  *
317  * \return position
318  */
320  {
321  return Vec( stod( get_field("coord_origin", "x") ),
322  stod( get_field("coord_origin", "y") ),
323  stod( get_field("coord_origin", "z") ));
324  }
325 
326  /**
327  * Get coordinate translation.
328  *
329  * \return translation
330  */
331  Vec translate() const
332  {
333  return Vec( stod( get_field("translate", "x") ),
334  stod( get_field("translate", "y") ),
335  stod( get_field("translate", "z") ));
336  }
337 
338  virtual ~Head() {}
339  ClassDef(Head, 2 );
340 };
341 
342 
343 /**
344  * Print header.
345  *
346  * \param out output stream
347  * \param h header
348  * \return output stream
349  */
350 inline std::ostream& operator<<(std::ostream& out, const Head& h)
351 {
352  h.print(out);
353  return out;
354 }
355 
356 
357 #endif
virtual ~Head()
Definition: Head.hh:338
std::string & get_line(std::string key)
Get data with the given key.
Definition: Head.hh:99
void set_field(std::string key, std::string field, std::string value)
Set data with the given key at given field.
Definition: Head.hh:186
std::string get_field(std::string key, std::string field) const
Get data with the given key at given field.
Definition: Head.hh:163
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
bool have_line(std::string key) const
Check availability of data with the given key.
Definition: Head.hh:75
Definition: JRoot.hh:19
double mc_livetime() const
Get the Monte Carlo live time.
Definition: Head.hh:309
int get_index_of_field(std::string key, std::string field) const
Get index of data with the given key at given field.
Definition: Head.hh:145
data_type r[M+1]
Definition: JPolint.hh:742
ClassDef(Head, 2)
The Vec class is a straightforward 3-d vector, which also works in pyroot.
Definition: Vec.hh:12
void print(std::ostream &out=std::cout) const
Print header.
Definition: Head.hh:221
std::istream & getline(std::istream &in, JString &object)
Read string from input stream until end of line.
Definition: JString.hh:478
static void trimstring(std::string &s)
Trim a string in place.
Definition: Head.hh:24
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition: Head.hh:66
double ngen() const
Get the number of generated events needed for computing event rates.
Definition: Head.hh:288
General exception.
Definition: Exception.hh:13
std::vector< int > count
Definition: JAlgorithm.hh:184
void set_line(std::string key, std::string line)
Set data with the given key.
Definition: Head.hh:110
const std::string & get_line(std::string key) const
Get data with the given key.
Definition: Head.hh:87
std::ostream & operator<<(std::ostream &stream, const CLBCommonHeader &header)
double daq_livetime() const
Get the the live time provided by the DAQ sytstem (=number of processed timeslices * frametime)...
Definition: Head.hh:298
std::string get_field(std::string key, int idx) const
Get data with the given key at given index.
Definition: Head.hh:123
data_type v[N+1][M+1]
Definition: JPolint.hh:740
Vec translate() const
Get coordinate translation.
Definition: Head.hh:331
std::vector< std::string > splitstring(const std::string &str, char delim= ' ')
Split string at delimiter.
Definition: Head.hh:45
Vec coord_origin() const
Get coordinate origin.
Definition: Head.hh:319
static std::map< std::string, std::vector< std::string > > & _hdr_dict()
Get internal description of the known lines in header.
Definition: Head.hh:238