yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis  1.9.0
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-2021 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 <limits>
15 #include <map>
16 #include <limits>
17 
18 namespace YODA {
19 
20 
23 
24  public:
25 
27  typedef std::map<std::string, std::string> Annotations;
28 
29 
32 
35 
37  AnalysisObject(const std::string& type, const std::string& path, const std::string& title="") {
38  setAnnotation("Type", type);
39  setPath(path);
40  setTitle(title);
41  }
42 
44  AnalysisObject(const std::string& type, const std::string& path,
45  const AnalysisObject& ao, const std::string& title="") {
46  for (const std::string& a : ao.annotations())
47  setAnnotation(a, ao.annotation(a));
48  setAnnotation("Type", type); // might override the copied ones
49  setPath(path);
50  setTitle(title);
51  }
52 
53  // /// Default copy constructor
54  // AnalysisObject(const AnalysisObject& ao) {
55  // if (ao.path().length() > 0) setPath(ao.path());
56  // if (ao.title().length() > 0) setTitle(ao.title());
57  // }
58 
60  virtual ~AnalysisObject() { }
61 
64  if (ao.path().length() > 0) setPath(ao.path());
65  if (ao.title().length() > 0) setTitle(ao.title());
66  return *this;
67  }
68 
70  virtual AnalysisObject* newclone() const = 0;
71 
73 
74 
75 
78 
80  virtual void reset() = 0;
81 
82  // variation parser
83  void parseVariations(){ return ; }
84 
86 
87 
88 
91 
94  std::vector<std::string> annotations() const {
95  std::vector<std::string> rtn;
96  rtn.reserve(_annotations.size());
97  for (const Annotations::value_type& kv : _annotations) rtn.push_back(kv.first);
98  return rtn;
99  }
100 
101 
103  bool hasAnnotation(const std::string& name) const {
104  return _annotations.find(name) != _annotations.end();
105  }
106 
107 
109  const std::string& annotation(const std::string& name) const {
110  Annotations::const_iterator v = _annotations.find(name);
111  // If not found... written this way round on purpose
112  if (v == _annotations.end()) {
113  std::string missing = "YODA::AnalysisObject: No annotation named " + name;
114  throw AnnotationError(missing);
115  }
116  return v->second;
117  }
118 
119 
121  const std::string& annotation(const std::string& name, const std::string& defaultreturn) const {
122  Annotations::const_iterator v = _annotations.find(name);
123  if (v != _annotations.end()) return v->second;
124  return defaultreturn;
125  }
126 
127 
131  template <typename T>
132  const T annotation(const std::string& name) const {
133  std::string s = annotation(name);
134  return Utils::lexical_cast<T>(s);
135  }
136 
137 
141  template <typename T>
142  const T annotation(const std::string& name, const T& defaultreturn) const {
143  try {
144  std::string s = annotation(name);
145  return Utils::lexical_cast<T>(s);
146  } catch (const AnnotationError& ae) {
147  return defaultreturn;
148  }
149  }
150 
151 
153  void setAnnotation(const std::string& name, const std::string& value) {
154  _annotations[name] = value;
155  }
156 
159  void setAnnotation(const std::string& name, double value) {
160  // Recipe from Boost docs
161  std::stringstream ss;
162  ss << std::setprecision(std::numeric_limits<double>::max_digits10) << std::scientific << value;
163  setAnnotation(name, ss.str());
164  }
165 
168  void setAnnotation(const std::string& name, float value) {
169  // Recipe from Boost docs
170  std::stringstream ss;
171  ss << std::setprecision(std::numeric_limits<double>::max_digits10) << std::scientific << value;
172  setAnnotation(name, ss.str());
173  }
174 
177  void setAnnotation(const std::string& name, long double value) {
178  // Recipe from Boost docs
179  std::stringstream ss;
180  ss << std::setprecision(std::numeric_limits<double>::max_digits10) << std::scientific << value;
181  setAnnotation(name, ss.str());
182  }
183 
187  template <typename T>
188  void setAnnotation(const std::string& name, const T& value) {
189  setAnnotation(name, Utils::lexical_cast<std::string>(value));
190  }
191 
192 
194  void setAnnotations(const Annotations& anns) {
195  _annotations = anns;
196  }
197 
198 
202  template <typename T>
203  void addAnnotation(const std::string& name, const T& value) {
204  setAnnotation(name, value);
205  }
206 
207 
209  void rmAnnotation(const std::string& name) {
210  _annotations.erase(name);
211  }
212 
213 
216  _annotations.clear();
217  }
218 
220 
221 
224 
228  const std::string title() const {
229  return annotation("Title", "");
230  }
231 
233  void setTitle(const std::string& title) {
234  setAnnotation("Title", title);
235  }
236 
241  const std::string path() const {
242  const std::string p = annotation("Path", "");
243  // If not set at all, return an empty string
244  if (p.empty()) return p;
245  // If missing a leading slash, one will be prepended
246  return p.find("/") == 0 ? p : ("/"+p);
247  }
248 
252  void setPath(const std::string& path) {
253  const std::string p = (path.find("/") == 0) ? path : "/"+path;
254  // if (path.length() > 0 && path.find("/") != 0) {
255  // throw AnnotationError("Histo paths must start with a slash (/) character.");
256  // }
257  setAnnotation("Path", p);
258  }
259 
260 
263  const std::string name() const {
264  const std::string p = path();
265  const size_t lastslash = p.rfind("/");
266  if (lastslash == std::string::npos) return p;
267  return p.substr(lastslash+1);
268  }
269 
271 
272 
273  public:
274 
277 
279  virtual std::string type() const {
280  return annotation("Type");
281  }
282 
289  virtual size_t dim() const = 0;
290 
292 
293 
294  private:
295 
297  std::map<std::string,std::string> _annotations;
298 
299  };
300 
301 
302  // Convenience alias
304 
305 
306 }
307 
308 #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.