/** * Counters for efficiency calculation **/ #ifndef PNDCACOUNTERSBASE_H #define PNDCACOUNTERSBASE_H #include using std::cout; using std::endl; using std::ios; #include #include #include using std::string; #include using std::vector; #include using std::map; /// counters used for efficiency calculation template struct TTracksCatCounters // counters for different tracks categories { int NCounters; vector counters; TTracksCatCounters():NCounters(0),counters(){ counters.clear(); }; TTracksCatCounters(int nCounters):NCounters(nCounters),counters(){ counters.resize( NCounters, T(0)); }; void AddCounter(){ NCounters++; counters.push_back(T(0)); }; void AddCounters(int nCounters){ NCounters += nCounters; counters.resize( NCounters, T(0)); }; TTracksCatCounters& operator+=(TTracksCatCounters& a){ if (NCounters != a.NCounters){ cout << " TTracksCatCounters: Error. Addition of counters of different sizes: " << NCounters << " " << a.NCounters << endl; } else{ for (int iC = 0; iC < NCounters; iC++){ counters[iC] += a.counters[iC]; } } return *this; }; TTracksCatCounters operator+(TTracksCatCounters& a){ TTracksCatCounters res = *this; res += a; return res; }; template TTracksCatCounters operator/(TTracksCatCounters& a){ TTracksCatCounters b(NCounters); if (NCounters != a.NCounters){ cout << " TTracksCatCounters: Error. Addition of counters of different sizes: " << NCounters << " " << a.NCounters << endl; } else{ for (int iC = 0; iC < NCounters; iC++){ b.counters[iC] = Div(counters[iC],a.counters[iC]); } } return b; } template TTracksCatCounters operator/(double a){ TTracksCatCounters b(NCounters); for (int iC = 0; iC < NCounters; iC++){ b.counters[iC] = static_cast( Div(counters[iC],a) ); } return b; } friend std::fstream & operator<<(std::fstream &strm, const TTracksCatCounters &a ){ strm << a.NCounters << " " << a.counters.size() << " "; for(unsigned int iV=0; iV &a ){ strm << a.NCounters << " " << a.counters.size() << " "; for(unsigned int iV=0; iV>(std::fstream &strm, TTracksCatCounters &a ){ int tmp; strm >> tmp; a.NCounters = tmp; strm >> tmp; a.counters.resize(tmp,T(0)); for(int iV=0; iV> tmp1; a.counters[iV] = tmp1; } return strm; } private: double Div(double a, double b){return (b > 0) ? a/b : -1.;}; }; struct TEfficiencies { TEfficiencies():ratio_ghosts(0),ratio_clones(0),ghosts(0),clones(0),nEvents(0){ // you should add counter with shortname="total" !! }; virtual void AddCounter(string shortname, string name); TEfficiencies& operator+=(TEfficiencies& a); void CalcEff(); void Inc(bool isReco, string name); // increment counters according to parameters void IncNEvents(){ nEvents++; }; void Print(); vector names; // names counters indexed by index of counter map indices; // indices of counters indexed by a counter shortname TTracksCatCounters ratio_reco; double ratio_ghosts; double ratio_clones; TTracksCatCounters mc; TTracksCatCounters reco; int ghosts; int clones; int nEvents; }; inline void TEfficiencies::AddCounter(string shortname, string name) { indices[shortname] = names.size(); names.push_back(name); ratio_reco.AddCounter(); mc.AddCounter(); reco.AddCounter(); } inline void TEfficiencies::CalcEff() { ratio_reco = reco/mc; if (mc.counters[indices["total"]] > 0){ ratio_clones = clones/double(mc.counters[indices["total"]]); } else{ ratio_clones = -1; } if (reco.counters[indices["total"]]+ghosts > 0){ ratio_ghosts = ghosts/double(reco.counters[indices["total"]]+ghosts); } else{ ratio_ghosts = -1; } } inline TEfficiencies& TEfficiencies::operator+=(TEfficiencies& a) { mc += a.mc; reco += a.reco; ghosts += a.ghosts; clones += a.clones; nEvents += a.nEvents; return *this; } inline void TEfficiencies::Inc(bool isReco, string name) { const int index = indices[name]; mc.counters[index]++; if (isReco) reco.counters[index]++; } inline void TEfficiencies::Print(){ cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(3); cout << "Track category : " << " Eff " <<" | "<< "All MC" << endl; int NCounters = mc.NCounters; for (int iC = 0; iC < NCounters; iC++){ cout << names[iC] << " : " << ratio_reco.counters[iC] << " | " << mc.counters[iC] << endl; } cout << "Clone probability : " << ratio_clones <<" | "<< clones << endl; cout << "Ghost probability : " << ratio_ghosts <<" | "<< ghosts << endl; } #endif