|
YODA - Yet more Objects for Data Analysis 2.0.1
|
Go to the documentation of this file.
6#ifndef YODA_READERUTILS_H
7#define YODA_READERUTILS_H
35 static const std::regex regex_string_pat( "([\"\'])(?:(?=(\\\\?))\\2.)*?\\1");
43 class aistringstream {
46 aistringstream( const char* line=0) {
51 aistringstream( const string& line) {
59 bool peek( const std::string& s) const {
60 return s == std::string(_next, s.size());
64 void reset( const char* line=0) {
65 _next = const_cast<char* >(line);
70 void reset( const string& line) { reset(line.c_str()); }
74 aistringstream& operator >> (T& value) {
76 if (_new_next == _next) _error = true;
82 operator bool() const { return !_error; }
89 _locale_set = newlocale(LC_NUMERIC_MASK, "C", NULL);
90 _locale_prev = uselocale(_locale_set);
92 throw ReadError(std::string( "Error setting locale: ") + strerror(errno));
95 void _reset_locale() {
96 if (!uselocale(_locale_prev)) {
97 throw ReadError(std::string( "Error setting locale: ") + strerror(errno));
99 freelocale(_locale_set);
102 void _get( double& x) { x = std::strtod(_next, &_new_next); }
103 void _get( float& x) { x = std::strtof(_next, &_new_next); }
104 void _get( int& i) { i = std::strtol(_next, &_new_next, 10); }
105 void _get( long& i) { i = std::strtol(_next, &_new_next, 10); }
106 void _get( unsigned int& i) { i = std::strtoul(_next, &_new_next, 10); }
107 void _get( long unsigned int& i) { i = std::strtoul(_next, &_new_next, 10); }
108 void _get( string& x) {
110 while (std::isspace(*_next)) _next += 1;
112 while (!std::isspace(*_new_next)) _new_next += 1;
113 x = string(_next, _new_next-_next);
116 locale_t _locale_set, _locale_prev;
117 char *_next, *_new_next;
130 virtual void parse( const string& line) = 0;
136 if constexpr (std::is_same<T, std::string>::value) {
137 string::const_iterator initpos( line.cbegin() );
138 const string::const_iterator finpos( line.cend() );
140 while ( std::regex_search(initpos, finpos, m, regex_string_pat) ) {
142 std::stringstream ss(m[0].str());
143 ss >> std::quoted(label);
144 vec.push_back(label);
145 initpos = m.suffix().first;
149 std::string content = line.substr(line.find( ": [")+3);
151 for ( const std::string& item : Utils::split(content, ",")) {
155 vec.push_back(std::move(tmp));
181 double sumw(0), sumw2(0), n(0);
182 aiss >> sumw >> sumw2 >> n;
183 dbn = Dbn0D(n, sumw, sumw2);
199 vector<string> sources;
201 void readErrors(std::map< string,std::pair<double,double>>& errors) {
203 for ( size_t i = 0; i < sources.size(); ++i) {
205 if (eDn != "---" && eUp != "---") {
206 errors[sources[i]] = { Utils::toDbl(eDn), Utils::toDbl(eUp) };
214 if (!line.rfind( "ErrorLabels: ", 0)) {
215 extractVector<std::string>(line, sources);
222 std::map<string,std::pair<double,double>> errors;
241 vector<PointND<N>> points;
244 void readCoords(vector<double>& vals, vector<double>& errm, vector<double>& errp) {
245 if constexpr(I < N) {
246 double v(0), em(0), ep(0);
247 aiss >> v >> em >> ep;
251 readCoords<I+1>(vals, errm, errp);
259 vector<double> vals(N), errm(N), errp(N);
260 readCoords<0>(vals, errm, errp);
261 points.push_back( PointND<N>(vals, errm, errp));
267 ao->addPoints(points);
274 template < size_t DbnN, typename... AxisT>
280 using is_CAxis = typename std::is_floating_point< typename std::tuple_element_t<I, std::tuple<AxisT...>>>;
282 std::tuple<vector<AxisT> ...> edges;
284 vector<Dbn<DbnN>> dbns;
285 vector<size_t> maskedBins;
286 std::array<double,DbnN*(DbnN-1)/2> crossTerms;
287 bool isYODA1 = false;
288 size_t axisCheck = 0;
293 if constexpr(I < sizeof...(AxisT)) {
294 using EdgeT = std::tuple_element_t<I, std::tuple<AxisT...>>;
295 if constexpr (is_CAxis<I>::value) {
298 if constexpr (I == 0) {
299 if (isYODA1 && !std::isinf(lo)) {
300 auto& curr_edges = std::get<I>(edges);
301 if (curr_edges.empty()) curr_edges.push_back(lo);
304 if (!std::isinf(hi)) {
305 auto& curr_edges = std::get<I>(edges);
306 if (curr_edges.empty()) curr_edges.push_back(hi);
307 else if (curr_edges[ curr_edges.size() - 1 ] != hi) {
308 curr_edges.push_back(hi);
313 throw BinningError( "Discrete axes are not supported in this YODA1-style legacy format.");
320 void readEdges( const std::string& line) {
321 if constexpr(I < sizeof...(AxisT)) {
322 if (I == axisCheck) {
323 using EdgeT = std::tuple_element_t<I, std::tuple<AxisT...>>;
324 auto& curr_edges = std::get<I>(edges);
325 extractVector<EdgeT>(line, curr_edges);
327 readEdges<I+1>(line);
332 void readDbn(std::array<double,DbnN+1>& sumW, std::array<double,DbnN+1>& sumW2) {
333 if constexpr(I <= DbnN) {
338 readDbn<I+1>(sumW, sumW2);
342 template < class tupleT, size_t... Is>
343 BaseT* make_from_tuple(tupleT&& tuple, std::index_sequence<Is...> ) {
344 BaseT* rtn = new BaseT{std::get<Is>(std::forward<tupleT>(tuple))...};
349 template < class tupleT>
350 BaseT* make_from_tuple(tupleT&& tuple) {
351 return make_from_tuple(std::forward<tupleT>(tuple),
352 std::make_index_sequence< sizeof...(AxisT)+1>{});
357 if constexpr(I < sizeof...(AxisT)) {
358 std::get<I>(edges).clear();
366 if (line.find( "Total") != string::npos) {
370 if (!line.rfind( "Edges(A", 0)) {
375 if (!line.rfind( "MaskedBins: ", 0)) {
376 extractVector<size_t>(line, maskedBins);
380 if (line.find( "Underflow") != string::npos || line.find( "Overflow") != string::npos) {
382 if constexpr ( sizeof...(AxisT) == 1) {
384 aiss >> tmp1 >> tmp2;
387 else if (isYODA1) readEdges<0>();
388 std::array<double,DbnN+1> sumW, sumW2;
389 readDbn<0>(sumW, sumW2);
390 for ( size_t i = 0; i < crossTerms.size(); ++i) {
393 crossTerms.at(i) = tmp;
395 double numEntries(0);
397 if (line.find( "Overflow") != string::npos) {
398 if constexpr ( sizeof...(AxisT) == 1) {
399 if constexpr (DbnN < 2)
400 yoda1Overflow = Dbn<DbnN>(numEntries, sumW, sumW2);
402 yoda1Overflow = Dbn<DbnN>(numEntries, sumW, sumW2, crossTerms);
406 if constexpr (DbnN < 2) {
407 dbns.emplace_back(numEntries, sumW, sumW2);
410 dbns.emplace_back(numEntries, sumW, sumW2, crossTerms);
417 auto args = std::tuple_cat(edges, std::make_tuple(path));
418 BaseT* ao = make_from_tuple(std::move(args));
420 size_t global_index = 0;
421 if (isYODA1 && sizeof...(AxisT) == 2) ++global_index;
422 for ( auto&& d : dbns) {
423 ao-> bin(global_index++).set(std::move(d));
426 if constexpr ( sizeof...(AxisT) == 1) {
427 if (isYODA1) ao-> bin(global_index).set(yoda1Overflow);
442 template < typename... AxisT>
447 std::tuple<vector<AxisT> ...> edges;
448 vector<Estimate> estimates;
449 vector<size_t> maskedBins;
450 vector<string> sources;
451 size_t axisCheck = 0;
455 void readEdges( const std::string& line) {
456 if constexpr(I < sizeof...(AxisT)) {
457 if (I == axisCheck) {
458 using EdgeT = std::tuple_element_t<I, std::tuple<AxisT...>>;
459 auto& curr_edges = std::get<I>(edges);
460 extractVector<EdgeT>(line, curr_edges);
462 readEdges<I+1>(line);
466 void readErrors(std::map< string,std::pair<double,double>>& errors) {
468 for ( const std::string& src : sources) {
470 if (eDn != "---" && eUp != "---") {
471 errors[src] = { Utils::toDbl(eDn), Utils::toDbl(eUp) };
476 template < class tupleT, size_t... Is>
477 BaseT* make_from_tuple(tupleT&& tuple, std::index_sequence<Is...> ) {
478 BaseT* rtn = new BaseT{std::get<Is>(std::forward<tupleT>(tuple))...};
483 template < class tupleT>
484 BaseT* make_from_tuple(tupleT&& tuple) {
485 return make_from_tuple(std::forward<tupleT>(tuple),
486 std::make_index_sequence< sizeof...(AxisT)+1>{});
491 if constexpr(I < sizeof...(AxisT)) {
492 std::get<I>(edges).clear();
500 if (!line.rfind( "Edges(A", 0)) {
505 if (!line.rfind( "MaskedBins: ", 0)) {
506 extractVector<size_t>(line, maskedBins);
509 if (!line.rfind( "ErrorLabels: ", 0)) {
510 extractVector<std::string>(line, sources);
517 std::map<string,std::pair<double,double>> errors;
519 estimates.emplace_back(val, errors);
524 auto args = std::tuple_cat(edges, std::make_tuple(path));
525 BaseT* ao = make_from_tuple(std::move(args));
527 size_t global_index = 0;
528 for ( auto&& e : estimates) {
529 ao-> bin(global_index++) = std::move(e);
AOReaderBase() Default constructor.
virtual void parse(const string &line)=0
virtual ~AOReaderBase() Default destructor.
virtual AnalysisObject * assemble(const string &path="")=0
void extractVector(const std::string &line, std::vector< T > &vec)
void parse(const string &line)
AnalysisObject * assemble(const string &path="")
void parse(const string &line)
AnalysisObject * assemble(const string &path="")
void parse(const string &line)
AnalysisObject * assemble(const string &path="")
AnalysisObject * assemble(const string &path="")
void parse(const string &line)
void parse(const string &line)
AnalysisObject * assemble(const string &path="")
AnalysisObject is the base class for histograms and scatters.
User-facing BinnedDbn class in arbitrary dimension.
BinT & bin(size_t idx) noexcept Returns reference to the bin at idx.
void maskBins(const std::vector< size_t > &indicesToMask, const bool status=true) noexcept Mask a range of bins.
Error for general binning problems.
Partial template specialisation for Dbn0D.
User-facing Dbn class inheriting from DbnBase.
Error for file reading errors.
A generic data type which is just a collection of n-dim data points with errors.
Anonymous namespace to limit visibility.
Dbn< 0 > Dbn0D User-friendly aliases.
|