yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis  1.7.2
AnalysisObject.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // This file is part of YODA -- Yet more Objects for Data Analysis
4 // Copyright (C) 2008-2017 The YODA collaboration (see AUTHORS for details)
5 //
6 #ifndef YODA_AnalysisObject_h
7 #define YODA_AnalysisObject_h
8 
9 #include "YODA/Exceptions.h"
10 #include "YODA/Utils/StringUtils.h"
12 #include <iomanip>
13 #include <string>
14 #include <map>
15 
16 namespace YODA {
17 
18 
21 
22  public:
23 
25  typedef std::map<std::string, std::string> Annotations;
26 
27 
29 
30 
33 
35  AnalysisObject(const std::string& type, const std::string& path, const std::string& title="") {
36  setAnnotation("Type", type);
37  setPath(path);
38  setTitle(title);
39  }
40 
42  AnalysisObject(const std::string& type, const std::string& path,
43  const AnalysisObject& ao, const std::string& title="") {
44  for (const std::string& a : ao.annotations())
45  setAnnotation(a, ao.annotation(a));
46  setAnnotation("Type", type); // might override the copied ones
47  setPath(path);
48  setTitle(title);
49  }
50 
51  // /// Default copy constructor
52  // AnalysisObject(const AnalysisObject& ao) {
53  // if (ao.path().length() > 0) setPath(ao.path());
54  // if (ao.title().length() > 0) setTitle(ao.title());
55  // }
56 
58  virtual ~AnalysisObject() { }
59 
62  if (ao.path().length() > 0) setPath(ao.path());
63  if (ao.title().length() > 0) setTitle(ao.title());
64  return *this;
65  }
66 
68  virtual AnalysisObject* newclone() const = 0;
69 
71 
72 
73 
75 
76 
78  virtual void reset() = 0;
79 
81 
82 
83 
85 
86 
89  std::vector<std::string> annotations() const {
90  std::vector<std::string> rtn;
91  rtn.reserve(_annotations.size());
92  for (const Annotations::value_type& kv : _annotations) rtn.push_back(kv.first);
93  return rtn;
94  }
95 
96 
98  bool hasAnnotation(const std::string& name) const {
99  return _annotations.find(name) != _annotations.end();
100  }
101 
102 
104  const std::string& annotation(const std::string& name) const {
105  Annotations::const_iterator v = _annotations.find(name);
106  // If not found... written this way round on purpose
107  if (v == _annotations.end()) {
108  std::string missing = "YODA::AnalysisObject: No annotation named " + name;
109  throw AnnotationError(missing);
110  }
111  return v->second;
112  }
113 
114 
116  const std::string& annotation(const std::string& name, const std::string& defaultreturn) const {
117  Annotations::const_iterator v = _annotations.find(name);
118  if (v != _annotations.end()) return v->second;
119  return defaultreturn;
120  }
121 
122 
126  template <typename T>
127  const T annotation(const std::string& name) const {
128  std::string s = annotation(name);
129  return Utils::lexical_cast<T>(s);
130  }
131 
132 
136  template <typename T>
137  const T annotation(const std::string& name, const T& defaultreturn) const {
138  try {
139  std::string s = annotation(name);
140  return Utils::lexical_cast<T>(s);
141  } catch (const AnnotationError& ae) {
142  return defaultreturn;
143  }
144  }
145 
146 
148  void setAnnotation(const std::string& name, const std::string& value) {
149  _annotations[name] = value;
150  }
151 
154  void setAnnotation(const std::string& name, double value) {
155  // Recipe from Boost docs
156  std::stringstream ss;
157  ss << std::setprecision(std::numeric_limits<double>::max_digits10) << std::scientific << value;
158  setAnnotation(name, ss.str());
159  }
160 
163  void setAnnotation(const std::string& name, float value) {
164  // Recipe from Boost docs
165  std::stringstream ss;
166  ss << std::setprecision(std::numeric_limits<double>::max_digits10) << std::scientific << value;
167  setAnnotation(name, ss.str());
168  }
169 
172  void setAnnotation(const std::string& name, long double value) {
173  // Recipe from Boost docs
174  std::stringstream ss;
175  ss << std::setprecision(std::numeric_limits<double>::max_digits10) << std::scientific << value;
176  setAnnotation(name, ss.str());
177  }
178 
182  template <typename T>
183  void setAnnotation(const std::string& name, const T& value) {
184  setAnnotation(name, Utils::lexical_cast<std::string>(value));
185  }
186 
187 
189  void setAnnotations(const Annotations& anns) {
190  _annotations = anns;
191  }
192 
193 
197  template <typename T>
198  void addAnnotation(const std::string& name, const T& value) {
199  setAnnotation(name, value);
200  }
201 
202 
204  void rmAnnotation(const std::string& name) {
205  _annotations.erase(name);
206  }
207 
208 
211  _annotations.clear();
212  }
213 
215 
216 
218 
219 
223  const std::string title() const {
224  return annotation("Title", "");
225  }
226 
228  void setTitle(const std::string& title) {
229  setAnnotation("Title", title);
230  }
231 
236  const std::string path() const {
237  const std::string p = annotation("Path", "");
238  // If not set at all, return an empty string
239  if (p.empty()) return p;
240  // If missing a leading slash, one will be prepended
241  return p.find("/") == 0 ? p : ("/"+p);
242  }
243 
247  void setPath(const std::string& path) {
248  const std::string p = (path.find("/") == 0) ? path : "/"+path;
249  // if (path.length() > 0 && path.find("/") != 0) {
250  // throw AnnotationError("Histo paths must start with a slash (/) character.");
251  // }
252  setAnnotation("Path", p);
253  }
254 
255 
258  const std::string name() const {
259  const std::string p = path();
260  const size_t lastslash = p.rfind("/");
261  if (lastslash == std::string::npos) return p;
262  return p.substr(lastslash+1);
263  }
264 
266 
267 
268  public:
269 
271 
272 
274  virtual std::string type() const {
275  return annotation("Type");
276  }
277 
282  virtual size_t dim() const = 0;
283 
285 
286 
287  private:
288 
290  std::map<std::string,std::string> _annotations;
291 
292  };
293 
294 
295  // Convenience alias
297 
298 
299 }
300 
301 #endif // YODA_AnalysisObject_h
virtual size_t dim() const =0
Get the dimension of the analysis object type.
void rmAnnotation(const std::string &name)
Delete an annotation by name.
virtual void reset()=0
Reset this analysis object.
virtual AnalysisObject * newclone() const =0
Make a copy on the heap, via &#39;new&#39;.
AnalysisObject()
Default constructor.
void setAnnotation(const std::string &name, const T &value)
Add or set an annotation by name (templated for remaining types)
const std::string path() const
Get the AO path.
void setAnnotation(const std::string &name, long double value)
Add or set a long-double-valued annotation by name.
void setAnnotation(const std::string &name, double value)
Add or set a double-valued annotation by name.
void setPath(const std::string &path)
const T annotation(const std::string &name, const T &defaultreturn) const
Get an annotation by name (copied to another type) with a default in case the annotation is not found...
std::map< std::string, std::string > Annotations
Collection type for annotations, as a string-string map.
void clearAnnotations()
Delete an annotation by name.
void addAnnotation(const std::string &name, const T &value)
Add or set an annotation by name.
const T annotation(const std::string &name) const
Get an annotation by name (copied to another type)
const std::string & annotation(const std::string &name) const
Get an annotation by name (as a string)
Error for unfound or broken AnalysisObject annotations.
Definition: Exceptions.h:79
const std::string & annotation(const std::string &name, const std::string &defaultreturn) const
Get an annotation by name (as a string) with a default in case the annotation is not found...
const std::string title() const
Get the AO title.
AnalysisObject(const std::string &type, const std::string &path, const std::string &title="")
Constructor giving a type, a path and an optional title.
virtual ~AnalysisObject()
Default destructor.
AnalysisObject is the base class for histograms and scatters.
void setAnnotation(const std::string &name, float value)
Add or set a float-valued annotation by name.
virtual std::string type() const
Get name of the analysis object type.
bool hasAnnotation(const std::string &name) const
Check if an annotation is defined.
void setTitle(const std::string &title)
Set the AO title.
AnalysisObject(const std::string &type, const std::string &path, const AnalysisObject &ao, const std::string &title="")
Constructor giving a type, a path, another AO to copy annotation from, and an optional title...
void setAnnotation(const std::string &name, const std::string &value)
Add or set a string-valued annotation by name.
const std::string name() const
void setAnnotations(const Annotations &anns)
Set all annotations at once.
std::vector< std::string > annotations() const
virtual AnalysisObject & operator=(const AnalysisObject &ao)
Default copy assignment operator.