-
Sergey Gorbunov authoredSergey Gorbunov authored
CbmL1Counters.h 5.76 KiB
/* Copyright (C) 2010-2017 Frankfurt Institute for Advanced Studies, Goethe-Universität Frankfurt, Frankfurt
SPDX-License-Identifier: GPL-3.0-only
Authors: Igor Kulakov [committer], Maksym Zyzak */
#ifndef CbmL1Counters_H
#define CbmL1Counters_H
#include "TString.h"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include "L1Vector.h"
/// counters used for efficiency calculation
template<typename T>
struct TL1TracksCatCounters // counters for different tracks categories
{
TL1TracksCatCounters() { counters.reserve(20); }
TL1TracksCatCounters(int nCounters) { counters.reset(nCounters, T(0)); };
int GetNcounters() const { return counters.size(); }
void AddCounter() { counters.push_back_no_warning(T(0)); };
void AddCounters(int nCounters) { counters.enlarge(GetNcounters() + nCounters, T(0)); };
TL1TracksCatCounters& operator+=(TL1TracksCatCounters& a)
{
if (GetNcounters() != a.GetNcounters()) {
std::cout << " TL1TracksCatCounters: Error. Addition of counters of "
"different sizes: "
<< GetNcounters() << " " << a.GetNcounters() << std::endl;
}
else {
for (int iC = 0; iC < GetNcounters(); iC++) {
counters[iC] += a.counters[iC];
}
}
return *this;
};
TL1TracksCatCounters operator+(TL1TracksCatCounters& a)
{
TL1TracksCatCounters res = *this;
res += a;
return res;
};
template<typename T2>
TL1TracksCatCounters<double> operator/(TL1TracksCatCounters<T2>& a)
{
TL1TracksCatCounters<double> b(GetNcounters());
if (GetNcounters() != a.GetNcounters()) {
std::cout << " TL1TracksCatCounters: Error. Addition of counters of "
"different sizes: "
<< GetNcounters() << " " << a.GetNcounters() << std::endl;
}
else {
for (int iC = 0; iC < GetNcounters(); iC++) {
b.counters[iC] = Div(counters[iC], a.counters[iC]);
}
}
return b;
};
template<typename T2>
TL1TracksCatCounters<T2> operator/(double a)
{
TL1TracksCatCounters<T2> b(GetNcounters());
for (int iC = 0; iC < GetNcounters(); iC++) {
b.counters[iC] = static_cast<T2>(Div(counters[iC], a));
}
return b;
};
friend std::fstream& operator<<(std::fstream& strm, const TL1TracksCatCounters<T>& a)
{
strm << a.GetNcounters() << " " << a.counters.size() << " ";
for (unsigned int iV = 0; iV < a.counters.size(); iV++)
strm << a.counters[iV] << " ";
strm << std::endl;
return strm;
}
friend std::ostream& operator<<(std::ostream& strm, const TL1TracksCatCounters<T>& a)
{
strm << a.counters.size() << " ";
for (unsigned int iV = 0; iV < a.counters.size(); iV++)
strm << a.counters[iV] << " ";
strm << std::endl;
return strm;
}
friend std::fstream& operator>>(std::fstream& strm, TL1TracksCatCounters<T>& a)
{
int tmp;
strm >> tmp;
a.counters.clear();
a.counters.reset(tmp, T(0));
for (int iV = 0; iV < tmp; iV++) {
T tmp1;
strm >> tmp1;
a.counters[iV] = tmp1;
}
return strm;
}
private:
double Div(double a, double b) { return (b > 0) ? a / b : -1.; };
public:
L1Vector<T> counters {"TL1TracksCatCounters::counters"};
};
struct TL1Efficiencies {
TL1Efficiencies()
: names()
, indices()
, ratio_reco()
, ratio_ghosts(0)
, ratio_clones(0)
, mc()
, reco()
, ghosts(0)
, clones(0)
, nEvents(0) {
// you should add counter with shortname="total" !!
};
virtual ~TL1Efficiencies() {};
virtual void AddCounter(TString shortname, TString name);
TL1Efficiencies& operator+=(TL1Efficiencies& a);
void CalcEff();
void Inc(bool isReco,
TString name); // increment counters according to parameters
void IncNEvents() { nEvents++; };
void PrintEff();
std::vector<TString> names; // names counters indexed by index of counter
std::map<TString, int> indices; // indices of counters indexed by a counter shortname
TL1TracksCatCounters<double> ratio_reco;
double ratio_ghosts;
double ratio_clones;
TL1TracksCatCounters<int> mc;
TL1TracksCatCounters<int> reco;
int ghosts;
int clones;
int nEvents;
};
inline void TL1Efficiencies::AddCounter(TString shortname, TString name)
{
indices[shortname] = names.size();
names.push_back(name);
ratio_reco.AddCounter();
mc.AddCounter();
reco.AddCounter();
}
inline void TL1Efficiencies::CalcEff()
{
ratio_reco = reco / mc;
const double total = reco.counters[indices["total"]] + ghosts + clones;
if (total > 0) {
ratio_clones = clones / total;
ratio_ghosts = ghosts / total;
}
else {
ratio_clones = -1;
ratio_ghosts = -1;
}
};
inline TL1Efficiencies& TL1Efficiencies::operator+=(TL1Efficiencies& a)
{
mc += a.mc;
reco += a.reco;
ghosts += a.ghosts;
clones += a.clones;
nEvents += a.nEvents;
return *this;
};
inline void TL1Efficiencies::Inc(bool isReco, TString name)
{
const int index = indices[name];
mc.counters[index]++;
if (isReco) reco.counters[index]++;
};
inline void TL1Efficiencies::PrintEff()
{
std::ios_base::fmtflags coutFlags(std::cout.flags());
std::cout.setf(std::ios::fixed);
std::cout.setf(std::ios::showpoint);
std::cout.precision(3);
std::cout.setf(std::ios::right);
std::cout << "Track category : "
<< " Eff "
<< " | "
<< "All MC" << std::endl;
int NCounters = mc.GetNcounters();
for (int iC = 0; iC < NCounters; iC++) {
std::cout << names[iC] << " : " << ratio_reco.counters[iC] << " | " << mc.counters[iC] << std::endl;
}
std::cout << "Clone probability : " << ratio_clones << " | " << clones << std::endl;
std::cout << "Ghost probability : " << ratio_ghosts << " | " << ghosts << std::endl;
std::cout.flags(coutFlags);
};
#endif