|
YODA - Yet more Objects for Data Analysis 2.0.2
|
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) {
109 while (std::isspace(*_next) && _next[0] != '\0') _next += 1;
111 while (!std::isspace(*_new_next) && _new_next[0] != '\0') _new_next += 1;
112 x = string(_next, _new_next-_next);
115 locale_t _locale_set, _locale_prev;
116 char *_next, *_new_next;
129 virtual void parse( const string& line) = 0;
135 if constexpr (std::is_same<T, std::string>::value) {
136 string::const_iterator initpos( line.cbegin() );
137 const string::const_iterator finpos( line.cend() );
139 while ( std::regex_search(initpos, finpos, m, regex_string_pat) ) {
141 std::stringstream ss(m[0].str());
142 ss >> std::quoted(label);
143 vec.push_back(label);
144 initpos = m.suffix().first;
148 std::string content = line.substr(line.find( ": [")+3);
150 for ( const std::string& item : Utils::split(content, ",")) {
154 vec.push_back(std::move(tmp));
180 double sumw(0), sumw2(0), n(0);
181 aiss >> sumw >> sumw2 >> n;
182 dbn = Dbn0D(n, sumw, sumw2);
198 vector<string> sources;
200 void readErrors(std::map< string,std::pair<double,double>>& errors) {
202 for ( size_t i = 0; i < sources.size(); ++i) {
204 if (eDn != "---" && eUp != "---") {
205 errors[sources[i]] = { Utils::toDbl(eDn), Utils::toDbl(eUp) };
213 if (!line.rfind( "ErrorLabels: ", 0)) {
214 extractVector<std::string>(line, sources);
221 std::map<string,std::pair<double,double>> errors;
240 vector<PointND<N>> points;
243 void readCoords(vector<double>& vals, vector<double>& errm, vector<double>& errp) {
244 if constexpr(I < N) {
245 double v(0), em(0), ep(0);
246 aiss >> v >> em >> ep;
250 readCoords<I+1>(vals, errm, errp);
258 vector<double> vals(N), errm(N), errp(N);
259 readCoords<0>(vals, errm, errp);
260 points.push_back( PointND<N>(vals, errm, errp));
266 ao->addPoints(points);
273 template < size_t DbnN, typename... AxisT>
279 using is_CAxis = typename std::is_floating_point< typename std::tuple_element_t<I, std::tuple<AxisT...>>>;
281 std::tuple<vector<AxisT> ...> edges;
283 vector<Dbn<DbnN>> dbns;
284 vector<size_t> maskedBins;
285 std::array<double,DbnN*(DbnN-1)/2> crossTerms;
286 bool isYODA1 = false;
287 size_t axisCheck = 0;
292 if constexpr(I < sizeof...(AxisT)) {
293 using EdgeT = std::tuple_element_t<I, std::tuple<AxisT...>>;
294 if constexpr (is_CAxis<I>::value) {
297 auto& curr_edges = std::get<I>(edges);
298 if (!std::isinf(lo)) {
299 if (curr_edges.empty()) curr_edges.push_back(lo);
301 if (!std::isinf(hi)) {
302 if (curr_edges.size() && curr_edges[ curr_edges.size() - 1 ] != hi) {
303 curr_edges.push_back(hi);
308 throw BinningError( "Discrete axes are not supported in this YODA1-style legacy format.");
315 void readEdges( const std::string& line) {
316 if constexpr(I < sizeof...(AxisT)) {
317 if (I == axisCheck) {
318 using EdgeT = std::tuple_element_t<I, std::tuple<AxisT...>>;
319 auto& curr_edges = std::get<I>(edges);
320 extractVector<EdgeT>(line, curr_edges);
322 readEdges<I+1>(line);
327 void readDbn(std::array<double,DbnN+1>& sumW, std::array<double,DbnN+1>& sumW2) {
328 if constexpr(I <= DbnN) {
333 readDbn<I+1>(sumW, sumW2);
337 template < class tupleT, size_t... Is>
338 BaseT* make_from_tuple(tupleT&& tuple, std::index_sequence<Is...> ) {
339 BaseT* rtn = new BaseT{std::get<Is>(std::forward<tupleT>(tuple))...};
344 template < class tupleT>
345 BaseT* make_from_tuple(tupleT&& tuple) {
346 return make_from_tuple(std::forward<tupleT>(tuple),
347 std::make_index_sequence< sizeof...(AxisT)+1>{});
352 if constexpr(I < sizeof...(AxisT)) {
353 std::get<I>(edges).clear();
361 if (line.find( "Total") != string::npos) {
365 if (!line.rfind( "Edges(A", 0)) {
370 if (!line.rfind( "MaskedBins: ", 0)) {
371 extractVector<size_t>(line, maskedBins);
375 if (line.find( "Underflow") != string::npos || line.find( "Overflow") != string::npos) {
377 if constexpr ( sizeof...(AxisT) == 1) {
379 aiss >> tmp1 >> tmp2;
382 else if (isYODA1) readEdges<0>();
383 std::array<double,DbnN+1> sumW, sumW2;
384 readDbn<0>(sumW, sumW2);
385 for ( size_t i = 0; i < crossTerms.size(); ++i) {
388 crossTerms.at(i) = tmp;
390 double numEntries(0);
392 if (line.find( "Overflow") != string::npos) {
393 if constexpr ( sizeof...(AxisT) == 1) {
394 if constexpr (DbnN < 2)
395 yoda1Overflow = Dbn<DbnN>(numEntries, sumW, sumW2);
397 yoda1Overflow = Dbn<DbnN>(numEntries, sumW, sumW2, crossTerms);
401 if constexpr (DbnN < 2) {
402 dbns.emplace_back(numEntries, sumW, sumW2);
405 dbns.emplace_back(numEntries, sumW, sumW2, crossTerms);
412 auto args = std::tuple_cat(edges, std::make_tuple(path));
413 BaseT* ao = make_from_tuple(std::move(args));
415 size_t global_index = 0;
416 if constexpr ( sizeof...(AxisT) == 2) {
418 for ( size_t ix = 1; ix < ao-> numBinsAt(0)+1; ++ix) {
419 for ( size_t iy = 1; iy < ao-> numBinsAt(1)+1; ++iy) {
420 ao-> bin(ix,iy).set(std::move(dbns[global_index++]));
425 if ( !(isYODA1 && sizeof...(AxisT) == 2) ) {
426 for ( auto&& d : dbns) {
427 ao-> bin(global_index++).set(std::move(d));
431 if constexpr ( sizeof...(AxisT) == 1) {
432 if (isYODA1) ao-> bin(global_index).set(yoda1Overflow);
447 template < typename... AxisT>
452 std::tuple<vector<AxisT> ...> edges;
453 vector<Estimate> estimates;
454 vector<size_t> maskedBins;
455 vector<string> sources;
456 size_t axisCheck = 0;
460 void readEdges( const std::string& line) {
461 if constexpr(I < sizeof...(AxisT)) {
462 if (I == axisCheck) {
463 using EdgeT = std::tuple_element_t<I, std::tuple<AxisT...>>;
464 auto& curr_edges = std::get<I>(edges);
465 extractVector<EdgeT>(line, curr_edges);
467 readEdges<I+1>(line);
471 void readErrors(std::map< string,std::pair<double,double>>& errors) {
473 for ( const std::string& src : sources) {
475 if (eDn != "---" && eUp != "---") {
476 errors[src] = { Utils::toDbl(eDn), Utils::toDbl(eUp) };
481 template < class tupleT, size_t... Is>
482 BaseT* make_from_tuple(tupleT&& tuple, std::index_sequence<Is...> ) {
483 BaseT* rtn = new BaseT{std::get<Is>(std::forward<tupleT>(tuple))...};
488 template < class tupleT>
489 BaseT* make_from_tuple(tupleT&& tuple) {
490 return make_from_tuple(std::forward<tupleT>(tuple),
491 std::make_index_sequence< sizeof...(AxisT)+1>{});
496 if constexpr(I < sizeof...(AxisT)) {
497 std::get<I>(edges).clear();
505 if (!line.rfind( "Edges(A", 0)) {
510 if (!line.rfind( "MaskedBins: ", 0)) {
511 extractVector<size_t>(line, maskedBins);
514 if (!line.rfind( "ErrorLabels: ", 0)) {
515 extractVector<std::string>(line, sources);
522 std::map<string,std::pair<double,double>> errors;
524 estimates.emplace_back(val, errors);
529 auto args = std::tuple_cat(edges, std::make_tuple(path));
530 BaseT* ao = make_from_tuple(std::move(args));
532 size_t global_index = 0;
533 for ( auto&& e : estimates) {
534 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.
size_t numBinsAt(const size_t axisN, const bool includeOverflows=false) const noexcept Number of bins in the BinnedStorage.
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.
|