File indexing completed on 2026-09-27 09:14:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef LAGER_CORE_HISTOGRAMMER_LOADED
0021 #define LAGER_CORE_HISTOGRAMMER_LOADED
0022
0023
0024
0025
0026 #include <functional>
0027 #include <memory>
0028 #include <vector>
0029
0030 #include <TFile.h>
0031 #include <TH1D.h>
0032 #include <TH2D.h>
0033
0034 #include <lager/core/configuration.hh>
0035 #include <lager/core/interval.hh>
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 namespace lager {
0047 template <class... Data> struct histogram_variable {
0048 using getter_type = std::function<Double_t(Data...)>;
0049
0050 const std::string name;
0051 const getter_type getter;
0052 const Int_t n_bins;
0053 const interval<Double_t> range;
0054
0055 histogram_variable(const std::string& name, const getter_type& getter,
0056 const Int_t n_bins, const interval<Double_t> range)
0057 : name{name}, getter{getter}, n_bins{n_bins}, range{range} {}
0058 };
0059 }
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 namespace lager {
0072 namespace histogrammer_impl {
0073
0074 template <class... Data> class histo1D;
0075 template <class... Data> class histo2D;
0076 }
0077
0078 template <class... Data> class histogrammer {
0079 public:
0080 using histo1D_type = histogrammer_impl::histo1D<Data...>;
0081 using histo2D_type = histogrammer_impl::histo2D<Data...>;
0082 using histo_var_type = histogram_variable<Data...>;
0083
0084 histogrammer(const string_path& path, std::string name, std::string title)
0085 : path_{path.str()}, name_{std::move(name)}, title_{std::move(title)} {}
0086 histogrammer(const std::string& name) : histogrammer("", name, name) {}
0087 histogrammer(const histogrammer&) = delete;
0088 histogrammer& operator=(const histogrammer&) = delete;
0089
0090
0091 void add_histo(std::shared_ptr<TFile> file, const std::string& name,
0092 const std::string& title, const histo_var_type& var) {
0093 histos_1D_.push_back(
0094 std::move(histo1D_type{std::move(file), path_, format_name(name_, name),
0095 format_title(title_, title), var}));
0096 }
0097 void add_histo(std::shared_ptr<TFile> file, const std::string& name,
0098 const histo_var_type& var) {
0099 add_histo(std::move(file), name, name, var);
0100 }
0101
0102 void add_histo(std::shared_ptr<TFile> file, const std::string& name,
0103 const std::string& title, const histo_var_type& var_x,
0104 const histo_var_type& var_y) {
0105 histos_2D_.push_back(
0106 std::move(histo2D_type{std::move(file), path_, format_name(name_, name),
0107 format_title(title_, title), var_x, var_y}));
0108 }
0109 void add_histo(std::shared_ptr<TFile> file, const std::string& name,
0110 const histo_var_type& var_x, const histo_var_type& var_y) {
0111 add_histo(std::move(file), name, name, var_x, var_y);
0112 }
0113
0114
0115 void fill(Data... d, Double_t weight = 1.) {
0116 for (auto& h : histos_1D_) {
0117 h.fill(d..., weight);
0118 }
0119 for (auto& h : histos_2D_) {
0120 h.fill(d..., weight);
0121 }
0122 }
0123
0124 private:
0125 const std::string path_;
0126 const std::string name_;
0127 const std::string title_;
0128 std::vector<histo1D_type> histos_1D_;
0129 std::vector<histo2D_type> histos_2D_;
0130 };
0131
0132 }
0133
0134
0135
0136
0137 namespace lager {
0138 namespace histogrammer_impl {
0139 template <class... Data> class histo1D
0140 {
0141 public:
0142 using var_type = histogram_variable<Data...>;
0143 using getter_type = typename var_type::getter_type;
0144
0145 histo1D(std::shared_ptr<TFile> file, const std::string& path,
0146 const std::string& name, const std::string& title,
0147 const var_type& var)
0148 : file_{std::move(file)}
0149 , path_{path}
0150 , getter_{var.getter}
0151 , histo_{nullptr} {
0152 if (file_) {
0153 file_->cd();
0154 if (path.size() && !file_->GetDirectory(path.c_str())) {
0155 file_->mkdir(path.c_str());
0156 }
0157 file_->cd(path.c_str());
0158 histo_ = new TH1D{name.c_str(), title.c_str(), var.n_bins, var.range.min,
0159 var.range.max};
0160 histo_->GetXaxis()->SetTitle(var.name.c_str());
0161 histo_->GetYaxis()->SetTitle("#");
0162 file_->cd();
0163 }
0164 }
0165 histo1D(std::shared_ptr<TFile> file, const std::string& name,
0166 const var_type& var)
0167 : histo1D(std::move(file), "", name, name, var) {}
0168
0169
0170 histo1D(const histo1D&) = delete;
0171 histo1D& operator=(const histo1D&) = delete;
0172
0173
0174 histo1D(histo1D&& rhs)
0175 : file_{std::move(rhs.file_)}
0176 , path_{rhs.path_}
0177 , getter_{rhs.getter_}
0178 , histo_{rhs.histo_} {
0179 rhs.file_.reset();
0180 rhs.histo_ = nullptr;
0181 }
0182
0183 ~histo1D() {
0184 if (file_ && histo_) {
0185 if (path_.size()) {
0186 file_->cd(path_.c_str());
0187 }
0188 histo_->Write();
0189 file_->cd();
0190 }
0191 }
0192
0193 Int_t fill(Data... d, Double_t weight = 1.) {
0194 if (file_ && histo_) {
0195 return histo_->Fill(getter_(d...), weight);
0196 }
0197 return -1;
0198 }
0199
0200 TH1D* histo() { return histo_; }
0201
0202 private:
0203 std::shared_ptr<TFile> file_;
0204 const std::string path_;
0205 const getter_type getter_;
0206 TH1D* histo_;
0207 };
0208
0209 template <class... Data> class histo2D {
0210 public:
0211 using var_type = histogram_variable<Data...>;
0212 using getter_type = typename var_type::getter_type;
0213
0214 histo2D(std::shared_ptr<TFile> file, const std::string& path,
0215 const std::string& name, const std::string& title,
0216 const var_type& var_x, const var_type& var_y)
0217 : file_{std::move(file)}
0218 , path_{path}
0219 , getter_x_{var_x.getter}
0220 , getter_y_{var_y.getter}
0221 , histo_{nullptr} {
0222 if (file_) {
0223 file_->cd();
0224 if (path.size() && !file_->GetDirectory(path.c_str())) {
0225 file_->mkdir(path.c_str());
0226 }
0227 file_->cd(path.c_str());
0228 histo_ = new TH2D{name.c_str(), title.c_str(), var_x.n_bins,
0229 var_x.range.min, var_x.range.max, var_y.n_bins,
0230 var_y.range.min, var_y.range.max};
0231
0232 histo_->SetOption("colz");
0233 histo_->GetXaxis()->SetTitle(var_x.name.c_str());
0234 histo_->GetYaxis()->SetTitle(var_y.name.c_str());
0235 }
0236 }
0237 histo2D(std::shared_ptr<TFile> file, const std::string& name,
0238 const var_type& var_x, const var_type& var_y)
0239 : histo2D(std::move(file), "", name, name, var_x, var_y) {}
0240
0241
0242 histo2D(const histo2D&) = delete;
0243 histo2D& operator=(const histo2D&) = delete;
0244
0245
0246 histo2D(histo2D&& rhs)
0247 : file_{std::move(rhs.file_)}
0248 , path_{rhs.path_}
0249 , getter_x_{rhs.getter_x_}
0250 , getter_y_{rhs.getter_y_}
0251 , histo_{rhs.histo_} {
0252 rhs.file_.reset();
0253 rhs.histo_ = nullptr;
0254 }
0255
0256 ~histo2D() {
0257 if (file_ && histo_) {
0258 if (path_.size()) {
0259 file_->cd(path_.c_str());
0260 }
0261 histo_->Write();
0262 file_->cd();
0263 }
0264 }
0265
0266 Int_t fill(Data... d, Double_t weight = 1.) {
0267 if (file_ && histo_) {
0268 return histo_->Fill(getter_x_(d...), getter_y_(d...), weight);
0269 }
0270 return -1;
0271 }
0272
0273 TH2D* histo() { return histo_; }
0274
0275 private:
0276 std::shared_ptr<TFile> file_;
0277 const std::string& path_;
0278 const getter_type getter_x_;
0279 const getter_type getter_y_;
0280 TH2D* histo_;
0281 };
0282 }
0283 }
0284
0285 #endif