DataMap.h
Go to the documentation of this file.
1 // DataMap.h
2 
3 #ifndef DataMap_H
4 #define DataMap_H
5 
6 // Class to store results of a calculation in maps indexed
7 // by name. Different types of results are supported:
8 // Int: int
9 // Float: float
10 // String: std::string
11 // IntVector: vector<Int>
12 // FloatVector: vector<Float>
13 // Hist: TH1*
14 // Graph: TGraph*
15 //
16 // Supports automatic conversion from int:
17 // DataMap myfun() { return 3; }
18 // and automatic conversion to int or bool.
19 // DataMap res = myfun();
20 // if ( res ) cout << "Failed with error " << res.status() << endl;
21 // if ( res > 10 ) cout << "Failed badly." << endl;
22 // if ( ! res ) cout << "Success!" << endl;
23 // Explicit comparisons require conversion:
24 // if ( res.status() == 2 ) cout << "Error 2: File not found." << endl;
25 // if ( int(res) == 3 ) cout << "Error three" << endl;
26 // Example draw of histogram:
27 // if ( res.hasHist("myhist") ) res.getHist("myhist")->Draw();
28 //
29 // This class manages (i.e. deletes) its graphs and optionally manages
30 // its histograms. Any copies of the result share in that management.
31 // If a histogram is not managed, the caller should ensure that it has
32 // appropriate lifetime.
33 
34 #include <vector>
35 #include <map>
36 #include <string>
37 #include <iostream>
38 #include <sstream>
39 
40 #include "TH1.h"
41 #include "TGraph.h"
42 
43 class DataMap {
44 
45 public:
46 
47  using Name = std::string;
49  using StringMap = std::map<Name, String>;
50  using IntVector = std::vector<int>;
51  using IntMap = std::map<Name,int>;
52  using IntVectorMap = std::map<Name,IntVector>;
53  using Float = float;
54  using FloatVector = std::vector<float>;
55  using FloatMap = std::map<Name,Float>;
56  using FloatVectorMap = std::map<Name,FloatVector>;
57  using HistVector = std::vector<TH1*>;
58  using HistMap = std::map<Name,TH1*>;
59  using HistVectorMap = std::map<Name,HistVector>;
60  using GraphPtr = std::shared_ptr<TGraph>;
61  using GraphMap = std::map<Name,GraphPtr>;
62  using SharedHistPtr = std::shared_ptr<TH1>;
63  using SharedHistVector = std::vector<SharedHistPtr>;
64 
65 public:
66 
67  // Set/fetch debug level.
68  // 0 - silent
69  // 1 - report when a non-existent name is requested
70  // 2 - report all access
71  static int dbg(int setDbg =-1) {
72  static int val = 0;
73  if ( setDbg >= 0 ) {
74  val = setDbg;
75  }
76  return val;
77  }
78 
79  // Class to manage map entry objects.
80  template<typename T>
81  struct MapEntry {
82  using Value = T;
83  using Map = typename std::map<Name,Value>;
84  using Iterator = typename Map::const_iterator;
85  using Entry = typename Map::value_type;
86  const Entry& m_ent;
87  MapEntry(Iterator ient) : m_ent(*ient) { }
89  std::ostringstream sout;
90  sout << m_ent.first << ": " << m_ent.second;
91  return sout.str();
92  }
93  };
94 
95  // Specialization to handle vectors.
96  template<typename T>
97  struct MapEntry<std::vector<T>> {
98  using Value = typename std::vector<T>;
99  using Map = typename std::map<Name,Value>;
100  using Iterator = typename Map::const_iterator;
101  using Entry = typename Map::value_type;
102  const Entry& m_ent;
103  MapEntry(Iterator ient) : m_ent(*ient) { }
105  std::ostringstream sout;
106  sout << m_ent.first << "[" << m_ent.second.size() << "]";
107  return sout.str();
108  }
109  };
110 
111 public:
112 
113  // Ctor from status flag.
114  explicit DataMap(int stat =0) : m_stat(stat) { }
115 
116  // Dtor.
118  const std::string myname = "DataMap::dtor: ";
119  //std::cout << myname << "@" << this << std::endl;
120  }
121 
122  // Setters.
123  // If own is true, the result has owns the histogram(s).
124  // If results are copied to other results, then this ownership
125  // is shared so that the histogram is deleted when the last of
126  // these results is deleted.
127  // NOTE: Code should be fixed to remove shared pointers when a
128  // histogram is overwritten (i.e. another added with the same name).
129  // Graphs are always owned in this same sense.
130  DataMap& setStatus(int stat) { m_stat = stat; return *this; }
131  void setInt(Name name, int val) { m_ints[name] = val; }
133  void setFloat(Name name, float val) { m_flts[name] = val; }
136  void setHist(Name name, TH1* ph, bool own =false) {
137  m_hsts[name] = ph;
138  if ( own && ph != nullptr ) {
139  ph->SetDirectory(nullptr);
140  m_sharedHsts.push_back(std::shared_ptr<TH1>(ph));
141  }
142  }
143  void setHist(TH1* ph, bool own =false) {
144  if ( ph != nullptr ) setHist(ph->GetName(), ph, own);
145  }
146  void setHist(std::shared_ptr<TH1> ph) {
147  m_hsts[ph->GetName()] = ph.get();
148  m_sharedHsts.push_back(ph);
149  }
150  void setHistVector(Name name, const HistVector& hsts, bool own =false) {
151  const std::string myname = "DataMap::setHistVector: ";
152  m_hstvecs[name] = hsts;
153  if ( own ) {
154  for ( TH1* ph : hsts ) {
155  bool manage = true;
156  for ( std::shared_ptr<TH1>& phShared : m_sharedHsts ) {
157  if ( phShared.get() == ph ) {
158  std::cout << myname << "Ignoring duplicate attempt to manage a histogram." << std::endl;
159  manage = false;
160  break;
161  }
162  }
163  if ( manage ) {
164  ph->SetDirectory(nullptr);
165  m_sharedHsts.push_back(std::shared_ptr<TH1>(ph));
166  }
167  }
168  }
169  }
171  const std::string myname = "DataMap::setHistVector: ";
172  m_hstvecs[name].clear();
173  for ( SharedHistPtr ph : hsts ) {
174  m_hstvecs[name].push_back(ph.get());
175  m_sharedHsts.push_back(ph);
176  }
177  }
178  void setGraph(Name name, TGraph* pg) {
179  m_grfs[name] = GraphPtr(pg);
180  }
181  void setGraph(TGraph* pg) {
182  if ( pg != nullptr ) setGraph(pg->GetName(), pg);
183  }
184 
185  // Extend this map with another.
186  void extend(const DataMap& rhs) {
187  m_stat += rhs.status();
188  mapextend<int>(m_ints, rhs.m_ints);
189  mapextend<IntVector>(m_intvecs, rhs.m_intvecs);
190  mapextend<Float>(m_flts, rhs.m_flts);
191  mapextend<FloatVector>(m_fltvecs, rhs.m_fltvecs);
192  mapextend<String>(m_strs, rhs.m_strs);
193  mapextend<TH1*>(m_hsts, rhs.m_hsts);
194  mapextend<HistVector>(m_hstvecs, rhs.m_hstvecs);
195  m_sharedHsts.insert(m_sharedHsts.end(), rhs.m_sharedHsts.begin(), rhs.m_sharedHsts.end());
196  mapextend<GraphPtr>(m_grfs, rhs.m_grfs);
197  }
198  DataMap& operator+=(const DataMap& rhs) { extend(rhs); return *this; }
199 
200  // Status.
201  // Typically 0 indicates success.
202  int status() const { return m_stat; }
203  operator int() const { return m_stat; }
204  explicit operator bool() const { return m_stat; }
205 
206  // Return if a result is stored for a given name.
207  bool haveInt(Name name) const { return maphas<int>(m_ints, name); }
208  bool haveIntVector(Name name) const { return maphas<IntVector>(m_intvecs, name); }
209  bool haveFloat(Name name) const { return maphas<Float>(m_flts, name); }
210  bool haveFloatVector(Name name) const { return maphas<FloatVector>(m_fltvecs, name); }
211  bool haveString(Name name) const { return maphas<String>(m_strs, name); }
212  bool haveHist(Name name) const { return maphas<TH1*>(m_hsts, name); }
213  bool haveHistVector(Name name) const { return maphas<HistVector>(m_hstvecs, name); }
214  bool haveGraph(Name name) const { return maphas<GraphPtr>(m_grfs, name); }
215 
216  // Return a result for a given name.
217  // The indicated default is returned if a value is not stored.
218  int getInt(Name name, int def =0) const { return mapget<int>(m_ints, name, def); }
219  const IntVector& getIntVector(Name name) const { return mapgetobj<IntVector>(m_intvecs, name); }
220  Float getFloat(Name name, Float def =0.0) const { return mapget<Float>(m_flts, name, def); }
221  const FloatVector& getFloatVector(Name name) const { return mapgetobj<FloatVector>(m_fltvecs, name); }
222  String getString(Name name, String def ="") const { return mapget<String>(m_strs, name, def); }
223  TH1* getHist(Name name, TH1* def =nullptr) const { return mapget<TH1*>(m_hsts, name, def); }
224  const HistVector& getHistVector(Name name) const { return mapgetobj<HistVector>(m_hstvecs, name); }
225  TGraph* getGraph(Name name) const { return mapgetobj<GraphPtr>(m_grfs, name).get(); }
226 
227  // Return the maps holding the results.
228  const IntMap& getIntMap() const { return m_ints; }
229  const IntVectorMap& getIntVectorMap() const { return m_intvecs; }
230  const FloatMap& getFloatMap() const { return m_flts; }
231  const FloatVectorMap& getFloatVectorMap() const { return m_fltvecs; }
232  const StringMap& getStringMap() const { return m_strs; }
233  const HistMap& getHistMap() const { return m_hsts; }
234  const HistVectorMap& getHistVectorMap() const { return m_hstvecs; }
235  const GraphMap& getGraphMap() const { return m_grfs; }
236 
237  // Return the named histograms in a vector.
239  HistVector hsts;
240  for ( HistMap::value_type ihst : m_hsts ) hsts.push_back(ihst.second);
241  return hsts;
242  }
243 
244  // Display contents.
245  void print(std::ostream* pout) const {
246  print("", pout);
247  }
248  void print(std::string prefix ="", std::ostream* pout=&std::cout) const {
249  if ( pout == nullptr ) return;
250  std::ostream& sout = *pout;
251  using std::endl;
252  sout << prefix << "Status: " << status() << endl;
253  if ( m_ints.size() ) {
254  sout << prefix << "Integers:" << endl;
255  for ( typename IntMap::value_type ient : m_ints ) {
256  sout << prefix << " " << ient.first << ": " << ient.second << endl;
257  }
258  }
259  if ( m_intvecs.size() ) {
260  sout << prefix << "Int vectors:" << endl;
261  unsigned int maxval = 20;
262  for ( typename IntVectorMap::value_type ient : m_intvecs ) {
263  unsigned nval = ient.second.size();
264  sout << prefix << " " << ient.first << "[" << nval << "]:";
265  for ( unsigned int ival=0; ival<nval; ++ival ) {
266  if ( ival ) sout << ",";
267  sout << " " << ient.second[ival];
268  if ( ival > maxval ) {
269  sout << ", ...";
270  break;
271  }
272  }
273  sout << endl;
274  }
275  }
276  if ( m_flts.size() ) {
277  sout << prefix << "Floats:" << endl;
278  for ( typename FloatMap::value_type ient : m_flts ) {
279  sout << prefix << " " << ient.first << ": " << ient.second << endl;
280  }
281  }
282  if ( m_fltvecs.size() ) {
283  sout << prefix << "Float vectors:" << endl;
284  unsigned int maxval = 20;
285  for ( typename FloatVectorMap::value_type ient : m_fltvecs ) {
286  unsigned nval = ient.second.size();
287  sout << prefix << " " << ient.first << "[" << nval << "]:";
288  for ( unsigned int ival=0; ival<nval; ++ival ) {
289  if ( ival ) sout << ",";
290  sout << " " << ient.second[ival];
291  if ( ival > maxval ) {
292  sout << ", ...";
293  break;
294  }
295  }
296  sout << endl;
297  }
298  }
299  if ( m_strs.size() ) {
300  sout << prefix << "Strings:" << endl;
301  for ( typename StringMap::value_type ient : m_strs ) {
302  sout << prefix << " " << ient.first << ": " << ient.second << endl;
303  }
304  }
305  if ( m_hsts.size() ) {
306  sout << prefix << "Histograms:" << endl;
307  for ( typename HistMap::value_type ient : m_hsts ) {
308  TH1* ph = ient.second;
309  //Name hnam = ph == nullptr ? "NULL" : ph->GetName();
310  sout << prefix << " " << ient.first << ": " << ph << endl;
311  }
312  }
313  if ( m_hstvecs.size() ) {
314  sout << prefix << "Histogram vectors:" << endl;
315  for ( typename HistVectorMap::value_type ient : m_hstvecs ) {
316  unsigned nhst = ient.second.size();
317  sout << prefix << " " << ient.first << "[" << nhst << "]" << endl;
318  }
319  }
320  if ( m_grfs.size() ) {
321  sout << prefix << "Graphs:" << endl;
322  for ( typename GraphMap::value_type ient : m_grfs ) {
323  GraphPtr pg = ient.second;
324  //Name hnam = ph == nullptr ? "NULL" : ph->GetName();
325  sout << prefix << " " << ient.first << ": " << pg.get() << endl;
326  }
327  }
328  }
329 
330 private:
331 
332  int m_stat;
342 
343  // Return if a map has key.
344  template<typename T>
345  bool maphas(const std::map<Name,T>& vals, Name name) const {
346  typename std::map<Name,T>::const_iterator ival = vals.find(name);
347  return ival != vals.end();
348  }
349 
350  // Return a map's value for a key or default if key is not present.
351  template<typename T>
352  T mapget(const std::map<Name,T>& vals, Name name, T def) const {
353  const std::string myname = "DataMap::mapget: ";
354  typename std::map<Name,T>::const_iterator ival = vals.find(name);
355  if ( ival == vals.end() ) {
356  if ( dbg() ) std::cout << myname << "Unknown entry: " << name << std::endl;
357  return def;
358  }
359  //if ( dbg() == 2 ) std::cout << myname << ient->first << std::endl;
360  if ( dbg() == 2 ) std::cout << myname << MapEntry<T>(ival).toString() << std::endl;
361  return ival->second;
362  }
363 
364  // Return a map's value for a key or default ctor object if key is not present.
365  template<typename T>
366  const T& mapgetobj(const std::map<Name,T>& vals, Name name) const {
367  const std::string myname = "DataMap::mapgetobj: ";
368  static T def;
369  typename std::map<Name,T>::const_iterator ival = vals.find(name);
370  if ( ival == vals.end() ) {
371  if ( dbg() ) std::cout << myname << "Unknown entry: " << name << std::endl;
372  return def;
373  }
374  //if ( dbg() == 2 ) std::cout << myname << ient->first << std::endl;
375  if ( dbg() == 2 ) std::cout << myname << MapEntry<T>(ival).toString() << std::endl;
376  return ival->second;
377  }
378 
379  // Extend or overwrite the entries in a map with those from another.
380  template<typename T>
381  void mapextend(std::map<Name,T>& lhs, const std::map<Name,T>& rhs) {
382  for ( typename std::map<Name,T>::value_type ient : rhs ) {
383  Name key = ient.first;
384  T val = ient.second;
385  lhs[key] = val;
386  }
387  }
388 
389 };
390 
391 #endif
static QCString name
Definition: declinfo.cpp:673
std::vector< float > FloatVector
Definition: DataMap.h:54
DataMap(int stat=0)
Definition: DataMap.h:114
typename std::vector< T > Value
Definition: DataMap.h:98
std::string toString() const
Definition: DataMap.h:104
void setFloat(Name name, float val)
Definition: DataMap.h:133
const IntVectorMap & getIntVectorMap() const
Definition: DataMap.h:229
std::map< Name, int > IntMap
Definition: DataMap.h:51
IntMap m_ints
Definition: DataMap.h:333
DataMap & setStatus(int stat)
Definition: DataMap.h:130
std::string string
Definition: nybbler.cc:12
Definition: entry.h:63
std::map< Name, GraphPtr > GraphMap
Definition: DataMap.h:61
std::map< Name, IntVector > IntVectorMap
Definition: DataMap.h:52
std::map< Name, TH1 * > HistMap
Definition: DataMap.h:58
bool haveHist(Name name) const
Definition: DataMap.h:212
bool haveInt(Name name) const
Definition: DataMap.h:207
const IntVector & getIntVector(Name name) const
Definition: DataMap.h:219
STL namespace.
TGraph * getGraph(Name name) const
Definition: DataMap.h:225
StringMap m_strs
Definition: DataMap.h:337
void setHist(Name name, TH1 *ph, bool own=false)
Definition: DataMap.h:136
bool haveString(Name name) const
Definition: DataMap.h:211
intermediate_table::const_iterator const_iterator
const FloatVector & getFloatVector(Name name) const
Definition: DataMap.h:221
T mapget(const std::map< Name, T > &vals, Name name, T def) const
Definition: DataMap.h:352
static int dbg(int setDbg=-1)
Definition: DataMap.h:71
void print(std::ostream *pout) const
Definition: DataMap.h:245
void setHistVector(Name name, const SharedHistVector &hsts)
Definition: DataMap.h:170
void setGraph(TGraph *pg)
Definition: DataMap.h:181
std::string toString() const
Definition: DataMap.h:88
std::vector< int > IntVector
Definition: DataMap.h:50
const FloatVectorMap & getFloatVectorMap() const
Definition: DataMap.h:231
const Entry & m_ent
Definition: DataMap.h:86
const HistVector & getHistVector(Name name) const
Definition: DataMap.h:224
MapEntry(Iterator ient)
Definition: DataMap.h:87
int status() const
Definition: DataMap.h:202
void setIntVector(Name name, const IntVector &val)
Definition: DataMap.h:132
const T & mapgetobj(const std::map< Name, T > &vals, Name name) const
Definition: DataMap.h:366
void mapextend(std::map< Name, T > &lhs, const std::map< Name, T > &rhs)
Definition: DataMap.h:381
HistVectorMap m_hstvecs
Definition: DataMap.h:339
void setHistVector(Name name, const HistVector &hsts, bool own=false)
Definition: DataMap.h:150
String getString(Name name, String def="") const
Definition: DataMap.h:222
void extend(const DataMap &rhs)
Definition: DataMap.h:186
std::string String
Definition: DataMap.h:48
void setString(Name name, String val)
Definition: DataMap.h:135
def key(type, name=None)
Definition: graph.py:13
const GraphMap & getGraphMap() const
Definition: DataMap.h:235
std::shared_ptr< TGraph > GraphPtr
Definition: DataMap.h:60
GraphMap m_grfs
Definition: DataMap.h:341
~DataMap()
Definition: DataMap.h:117
std::map< Name, String > StringMap
Definition: DataMap.h:49
std::map< Name, Float > FloatMap
Definition: DataMap.h:55
const IntMap & getIntMap() const
Definition: DataMap.h:228
void setInt(Name name, int val)
Definition: DataMap.h:131
const FloatMap & getFloatMap() const
Definition: DataMap.h:230
FloatMap m_flts
Definition: DataMap.h:335
int m_stat
Definition: DataMap.h:332
typename std::map< Name, Value > Map
Definition: DataMap.h:83
DataMap & operator+=(const DataMap &rhs)
Definition: DataMap.h:198
float Float
Definition: DataMap.h:53
Float getFloat(Name name, Float def=0.0) const
Definition: DataMap.h:220
bool maphas(const std::map< Name, T > &vals, Name name) const
Definition: DataMap.h:345
typename std::map< Name, Value > Map
Definition: DataMap.h:99
const HistVectorMap & getHistVectorMap() const
Definition: DataMap.h:234
typename Map::const_iterator Iterator
Definition: DataMap.h:100
HistVector getHists() const
Definition: DataMap.h:238
std::string Name
Definition: DataMap.h:47
int getInt(Name name, int def=0) const
Definition: DataMap.h:218
const StringMap & getStringMap() const
Definition: DataMap.h:232
std::map< Name, FloatVector > FloatVectorMap
Definition: DataMap.h:56
HistMap m_hsts
Definition: DataMap.h:338
bool haveFloat(Name name) const
Definition: DataMap.h:209
bool haveGraph(Name name) const
Definition: DataMap.h:214
void print(std::string prefix="", std::ostream *pout=&std::cout) const
Definition: DataMap.h:248
void setGraph(Name name, TGraph *pg)
Definition: DataMap.h:178
SharedHistVector m_sharedHsts
Definition: DataMap.h:340
TH1 * getHist(Name name, TH1 *def=nullptr) const
Definition: DataMap.h:223
bool haveHistVector(Name name) const
Definition: DataMap.h:213
void setFloatVector(Name name, const FloatVector &val)
Definition: DataMap.h:134
void setHist(TH1 *ph, bool own=false)
Definition: DataMap.h:143
const HistMap & getHistMap() const
Definition: DataMap.h:233
std::vector< TH1 * > HistVector
Definition: DataMap.h:57
void setHist(std::shared_ptr< TH1 > ph)
Definition: DataMap.h:146
int bool
Definition: qglobal.h:345
FloatVectorMap m_fltvecs
Definition: DataMap.h:336
bool haveFloatVector(Name name) const
Definition: DataMap.h:210
std::map< Name, HistVector > HistVectorMap
Definition: DataMap.h:59
IntVectorMap m_intvecs
Definition: DataMap.h:334
bool haveIntVector(Name name) const
Definition: DataMap.h:208
std::shared_ptr< TH1 > SharedHistPtr
Definition: DataMap.h:62
QTextStream & endl(QTextStream &s)
typename Map::const_iterator Iterator
Definition: DataMap.h:84
std::vector< SharedHistPtr > SharedHistVector
Definition: DataMap.h:63