Book

match_name

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
#ifndef BOOK_FOR_ROOT_HISTOGRAMS
#define BOOK_FOR_ROOT_HISTOGRAMS

#include <map>
#include <string>
#include "poly.h"
#include "TDirectory.h"
#include "TH1.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TProfile.h"
#include "TH3D.h"
#include <boost/regex.hpp>
#include <boost/iterator/filter_iterator.hpp>

class Book {
  typedef const double double_t;
  typedef const unsigned long uint_t;
  typedef const std::string string_t;
  typedef std::map<std::string, TH1*> book_t;

  book_t book_;
  std::string title_;
  TDirectory* directory;

  struct match_name {
    match_name(string_t re) : expression(re) {}
    bool operator()(const book_t::const_iterator::value_type& p) { return regex_match(p.first, expression); }

  private:
    boost::regex expression;
  };

public:
  Book() : title_(""), directory(nullptr) {}
  Book(string_t t) : title_(t), directory(new TDirectory(t.c_str(), t.c_str())) {}

  string_t& title() const { return title_; }
  bool empty() const { return book_.empty(); }
  long size() const { return book_.size(); }

  TH1* book(string_t name, TH1* const hist) {
    book_[name] = hist;
    hist->SetDirectory(directory);
    if (!hist->GetSumw2N())
      hist->Sumw2();
    return hist;
  }
  TH1*& operator[](string_t name) { return book_[name]; }
  const TH1* operator[](string_t name) const {
    book_t::const_iterator it = book_.find(name);
    return it == book_.end() ? nullptr : it->second;
  }

  typedef boost::filter_iterator<match_name, book_t::iterator> iterator;
  typedef boost::filter_iterator<match_name, book_t::const_iterator> const_iterator;
  iterator begin(string_t re = ".*") {
    book_t::iterator b(book_.begin()), e(book_.end());
    return boost::make_filter_iterator(match_name(re), b, e);
  }
  const_iterator begin(string_t re = ".*") const {
    book_t::const_iterator b(book_.begin()), e(book_.end());
    return boost::make_filter_iterator(match_name(re), b, e);
  }
  iterator end(string_t re = ".*") {
    book_t::iterator e(book_.end());
    return boost::make_filter_iterator(match_name(re), e, e);
  }
  const_iterator end(string_t re = ".*") const {
    book_t::const_iterator e(book_.end());
    return boost::make_filter_iterator(match_name(re), e, e);
  }
  iterator find(string_t name, string_t re = ".*") {
    return boost::make_filter_iterator(match_name(re), book_.find(name), book_.end());
  }
  const_iterator find(string_t name, string_t re = ".*") const {
    return boost::make_filter_iterator(match_name(re), book_.find(name), book_.end());
  }
  std::pair<iterator, iterator> filter_range(string_t re = ".*") { return std::make_pair(begin(re), end(re)); }
  std::pair<const_iterator, const_iterator> filter_range(string_t re = ".*") const {
    return std::make_pair(begin(re), end(re));
  }

  void erase(string_t name) {
    book_t::iterator it = book_.find(name);
    if (it != book_.end()) {
      delete it->second;
      book_.erase(it);
    }
  }
  void erase(iterator it) {
    delete it->second;
    book_.erase(it.base());
  }

  void fill(double_t X, const char* name, uint_t NbinsX, double_t Xlow, double_t Xup, double_t W = 1) {
    fill(X, std::string(name), NbinsX, Xlow, Xup, W);
  }
  void fill(double_t X, const poly<std::string>& names, uint_t NbinsX, double_t Xlow, double_t Xup, double_t W = 1) {
    for (auto const& name : names) {
      book_t::const_iterator current = book_.find(name);
      if (current == book_.end())
        book(name, new TH1D(name.c_str(), "", NbinsX, Xlow, Xup))->Fill(X, W);
      else
        current->second->Fill(X, W);
    }
  }
  void fill(double_t X, double_t Y, const char* name, uint_t NbinsX, double_t Xlow, double_t Xup, double_t W = 1) {
    fill(X, Y, std::string(name), NbinsX, Xlow, Xup, W);
  }
  void fill(double_t X,
            double_t Y,
            const poly<std::string>& names,
            uint_t NbinsX,
            double_t Xlow,
            double_t Xup,
            double_t W = 1) {
    for (auto const& name : names) {
      book_t::const_iterator current = book_.find(name);
      if (current == book_.end())
        static_cast<TProfile*>(book(name, new TProfile(name.c_str(), "", NbinsX, Xlow, Xup)))->Fill(X, Y, W);
      else
        static_cast<TProfile*>(current->second)->Fill(X, Y, W);
    }
  }
  void fill(double_t X,
            double_t Y,
            const char* name,
            uint_t NbinsX,
            double_t Xlow,
            double_t Xup,
            uint_t NbinsY,
            double_t Ylow,
            double_t Yup,
            double_t W = 1) {
    fill(X, Y, std::string(name), NbinsX, Xlow, Xup, NbinsY, Ylow, Yup, W);
  }
  void fill(double_t X,
            double_t Y,
            const poly<std::string>& names,
            uint_t NbinsX,
            double_t Xlow,
            double_t Xup,
            uint_t NbinsY,
            double_t Ylow,
            double_t Yup,
            double_t W = 1) {
    for (auto const& name : names) {
      book_t::const_iterator current = book_.find(name);
      if (current == book_.end())
        static_cast<TH2*>(book(name, new TH2D(name.c_str(), "", NbinsX, Xlow, Xup, NbinsY, Ylow, Yup)))->Fill(X, Y, W);
      else
        static_cast<TH2*>(current->second)->Fill(X, Y, W);
    }
  }
  void fill(double_t X,
            double_t Y,
            double_t Z,
            const char* name,
            uint_t NbinsX,
            double_t Xlow,
            double_t Xup,
            uint_t NbinsY,
            double_t Ylow,
            double_t Yup,
            uint_t NbinsZ,
            double_t Zlow,
            double_t Zup,
            double_t W = 1) {
    fill(X, Y, Z, std::string(name), NbinsX, Xlow, Xup, NbinsY, Ylow, Yup, NbinsZ, Zlow, Zup);
  }
  void fill(double_t X,
            double_t Y,
            double_t Z,
            const poly<std::string>& names,
            uint_t NbinsX,
            double_t Xlow,
            double_t Xup,
            uint_t NbinsY,
            double_t Ylow,
            double_t Yup,
            uint_t NbinsZ,
            double_t Zlow,
            double_t Zup,
            double_t W = 1) {
    for (auto const& name : names) {
      book_t::const_iterator current = book_.find(name);
      if (current == book_.end())
        static_cast<TH3*>(
            book(name, new TH3D(name.c_str(), "", NbinsX, Xlow, Xup, NbinsY, Ylow, Yup, NbinsZ, Zlow, Zup)))
            ->Fill(X, Y, Z, W);
      else
        static_cast<TH3*>(current->second)->Fill(X, Y, Z, W);
    }
  }
};

#endif