14#include "TClonesArray.h"
19#include "TMVA/Config.h"
25#include <FairRootManager.h>
28#include <boost/assign/list_of.hpp>
35using boost::assign::list_of;
39using std::stringstream;
47 , fTrdTrackMatches(NULL)
56 , fOutputDir(
"results/")
65 , fNofTrdLayers(nofTrdLayers)
72 , fNofTrainSamples(2500)
73 , fElIdEfficiency(0.9)
79 fhMeanEloss.resize(2);
83 TH1::SetDefaultBufferSize(30000);
85 fhResults =
new TH1D(
"fhResults",
"fhResults", 2, 0, 2);
86 fHists.push_back(fhResults);
88 for (
int i = 0; i < 2; i++) {
91 fhMeanEloss[i] =
new TH1D((
"fhMeanEloss" + s).c_str(),
"fhMeanEloss;Mean energy loss [a.u.];Yield", 100, 0., 50e-6);
92 fHists.push_back(fhMeanEloss[i]);
93 fhEloss[i] =
new TH1D((
"fhEloss" + s).c_str(),
"fhEloss;Energy loss [a.u.];Yield", 100, 0., 50e-6);
94 fHists.push_back(fhEloss[i]);
97 Int_t nofSortBins = 200;
98 fhElossSort.resize(2);
99 for (
int j = 0; j < 2; j++) {
100 fhElossSort[j].resize(fNofTrdLayers);
101 for (Int_t i = 0; i < fNofTrdLayers; i++) {
102 std::stringstream ss1;
103 if (j == 0) ss1 <<
"fhElossSortEl" << i;
104 if (j == 1) ss1 <<
"fhElossSortPi" << i;
106 new TH1D(ss1.str().c_str(), (ss1.str() +
";Energy loss [a.u.];Counters").c_str(), nofSortBins, 0., 0.);
111 Int_t nofBins = 10000;
113 fhCumProbOutput.resize(2);
115 for (Int_t i = 0; i < 2; i++) {
116 s = (i == 0) ?
"El" :
"Pi";
117 fhOutput[i] =
new TH1D((
"fhOutput" + s).c_str(),
"fhOutput;Output;Counter", nofBins, fMinEval, fMaxEval);
118 fhCumProbOutput[i] =
new TH1D((
"fhCumProbOutput" + s).c_str(),
"fhCumProbOutput;Output;Cumulative probability",
119 nofBins, fMinEval, fMaxEval);
121 fhInput[i].resize(fNofTrdLayers);
122 for (Int_t j = 0; j < fNofTrdLayers; j++) {
125 fhInput[i][j] =
new TH1D((
"fhInput" + ss.str()).c_str(),
"fhInput", 100, 0.0, 0.0);
134 FairRootManager* ioman = FairRootManager::Instance();
136 LOG(fatal) << GetName() <<
"::Init: RootManager not instantised";
139 fMCTracks = (TClonesArray*) ioman->GetObject(
"MCTrack");
141 LOG(fatal) << GetName() <<
"::Init: No MCTrack array";
144 fTrdPoints = (TClonesArray*) ioman->GetObject(
"TrdPoint");
146 LOG(fatal) << GetName() <<
"::Init: No TRDPoint array";
149 fTrdTracks = (TClonesArray*) ioman->GetObject(
"TrdTrack");
151 LOG(fatal) << GetName() <<
"::Init: No TrdTrack array";
156 LOG(fatal) << GetName() <<
"::Init: No TrdTrackMatch array";
159 fTrdHits = (TClonesArray*) ioman->GetObject(
"TrdHit");
161 LOG(fatal) << GetName() <<
"::Init: No TrdHit array";
170 cout <<
"CbmTrdElectronsTrainAnn, event " <<
fEventNum << endl;
176 cout <<
"Nof electrons = " <<
fEloss[0].size() << endl;
177 cout <<
"Nof pions = " <<
fEloss[1].size() << endl;
192 TFile* oldFile = gFile;
193 TDirectory* oldDir = gDirectory;
195 TFile* f =
new TFile(
string(
fOutputDir +
"/trd_elid_hist.root").c_str(),
"RECREATE");
196 for (
unsigned int i = 0; i <
fHists.size(); i++) {
213 cout <<
"Nof electrons = " <<
fEloss[0].size() << endl;
214 cout <<
"Nof pions = " <<
fEloss[1].size() << endl;
222 LOG(fatal) << GetName() <<
"::FillElossVectorReal: Set input file for beam data and histogram names!";
226 TFile* oldFile = gFile;
227 TDirectory* oldDir = gDirectory;
230 LOG_IF(fatal, !file) <<
"Could not open file " <<
fBeamDataFile;
232 TH1F* hPion =
static_cast<TH1F*
>(file->Get<TH1F>(
fBeamDataPiHist.c_str())->Clone());
235 TH1F* hElectron =
static_cast<TH1F*
>(file->Get<TH1F>(
fBeamDataElHist.c_str())->Clone());
239 fhEloss[0]->GetXaxis()->GetBinUpEdge(
fhEloss[0]->GetNbinsX()) / hPion->GetXaxis()->GetBinUpEdge(hPion->GetNbinsX());
241 int nofSimulatedParticles = 1000000;
242 fEloss[0].resize(nofSimulatedParticles);
243 fEloss[1].resize(nofSimulatedParticles);
245 for (
int iP = 0; iP < 2; iP++) {
246 TH1F* hist = hElectron;
247 if (iP == 1) hist = hPion;
248 for (
int iT = 0; iT < nofSimulatedParticles; iT++) {
251 double eloss = scaleX * hist->GetRandom();
265 Int_t nofTrdTracks =
fTrdTracks->GetEntriesFast();
266 for (Int_t iTrdTrack = 0; iTrdTrack < nofTrdTracks; iTrdTrack++) {
273 if (iMC < 0 || iMC >
fMCTracks->GetEntriesFast())
continue;
276 Int_t pdg = TMath::Abs(mctrack->
GetPdgCode());
281 if (motherId != -1)
continue;
284 if (pdg == 211) iP = 1;
289 for (Int_t iHit = 0; iHit < nHits; iHit++) {
303 for (
int i = 0; i < 2; i++) {
304 for (
unsigned int iT = 0; iT <
fEloss[i].size(); iT++) {
305 Int_t nHits =
fEloss[i][iT].size();
306 double sumEloss = 0.;
307 for (
int iH = 0; iH < nHits; iH++) {
308 sumEloss +=
fEloss[i][iT][iH].fEloss;
320 for (
int iP = 0; iP < 2; iP++) {
321 for (
unsigned int iT = 0; iT <
fEloss[iP].size(); iT++) {
323 v[iH] =
fEloss[iP][iT][iH].fEloss;
325 std::sort(
v.begin(),
v.end());
363 Double_t ANNCoef1 = 1.06;
364 Double_t ANNCoef2 = 0.57;
367 for (UInt_t i = 0; i <
fAnnInput.size(); i++) {
372 for (UInt_t i = 0; i <
fAnnInput.size(); i++) {
382 for (Int_t j = 0; j <
size; j++) {
385 Double_t probEl =
fhElossSort[0][j]->GetBinContent(binNumEl);
389 Double_t probPi =
fhElossSort[1][j]->GetBinContent(binNumPi);
391 if (TMath::IsNaN(probPi / (probEl + probPi))) {
395 fAnnInput[j] = probPi / (probEl + probPi);
405 for (UInt_t j = 0; j <
fAnnInput.size(); j++) {
407 if (binNumEl >
fhEloss[0]->GetNbinsX()) binNumEl =
fhEloss[0]->GetNbinsX();
408 Double_t probEl =
fhEloss[0]->GetBinContent(binNumEl);
412 if (binNumPi >
fhEloss[1]->GetNbinsX()) binNumPi =
fhEloss[1]->GetNbinsX();
413 Double_t probPi =
fhEloss[1]->GetBinContent(binNumPi);
416 return lEl / (lEl + lPi);
429 double scaleX = 1. /
fhEloss[0]->GetXaxis()->GetBinUpEdge(
fhEloss[0]->GetNbinsX());
430 return eval * scaleX;
440 double scaleX = 1. /
fhEloss[0]->GetXaxis()->GetBinUpEdge(
fhEloss[0]->GetNbinsX());
441 return eval * scaleX;
447 return fReader->EvaluateMVA(
"BDT");
451 for (UInt_t i = 0; i <
fAnnInput.size(); i++)
453 return fNN->Evaluate(0, par);
474 for (Int_t i = 0; i < 2; i++) {
475 for (UInt_t iT = 0; iT <
fEloss[i].size() - 2; iT++) {
479 fXOut = (i == 0) ? 1. : -1.;
487 if (NULL !=
fNN)
delete fNN;
489 cout <<
"-I- Create ANN: " << mlpString << endl;
490 cout <<
"-I- Number of training epochs = " <<
fNofAnnEpochs << endl;
491 fNN =
new TMultiLayerPerceptron(mlpString, simu,
"(Entry$+1)");
495 fNN->DumpWeights(ss.str().c_str());
499 (TMVA::gConfig().GetIONames()).fWeightFileDir =
fOutputDir;
506 <<
":nTest_Signal=0:nTest_Background=0";
516 cout <<
"-I- Start pretesting " << endl;
518 cout <<
"-I- IdMethod = kBDT " << endl;
521 cout <<
"-I- IdMethod = kANN " << endl;
524 cout <<
"-I- IdMethod = kMEDIANA " << endl;
527 cout <<
"-I- IdMethod = kLIKELIHOOD " << endl;
538 if (
fNN != NULL)
delete fNN;
541 fNN =
new TMultiLayerPerceptron(mlpString, simu,
"(Entry$+1)");
544 fNN->LoadWeights(ss.str().c_str());
547 for (Int_t i = 0; i < 2; i++) {
548 for (UInt_t iT = 0; iT <
fEloss[i].size(); iT++) {
550 if (iT % 100000 == 0) cout <<
"-I- read number: " << iT << endl;
563 Bool_t isEl = (i == 0) ?
true :
false;
565 Double_t nnEval =
Eval(isEl);
581 cout <<
"-I- Optimal cut = " << cut <<
" for " << 100 *
fElIdEfficiency <<
"% electron efficiency" << endl;
582 cout <<
"-I- Start testing" << endl;
592 if (
fNN != NULL)
delete fNN;
595 fNN =
new TMultiLayerPerceptron(mlpString, simu,
"(Entry$+1)");
598 fNN->LoadWeights(ss.str().c_str());
606 for (Int_t i = 0; i < 2; i++) {
607 for (UInt_t iT = 0; iT <
fEloss[i].size(); iT++) {
609 if (iT % 100000 == 0) cout <<
"-I- Read number: " << iT << endl;
616 Bool_t isEl = (i == 0) ?
true :
false;
617 Double_t nnEval =
Eval(isEl);
622 if (nnEval < cut) nofElLikePi++;
626 if (nnEval > cut) nofPiLikeEl++;
631 if (nofPiLikeEl != 0) piSupp = (double) nofPiTest / nofPiLikeEl;
632 double elEff = (double) nofElLikePi / nofElTest * 100.;
634 cout <<
"Testing results:" << endl;
636 cout <<
"cut = " << cut << endl;
637 cout <<
"nof El = " << nofElTest << endl;
638 cout <<
"nof Pi = " << nofPiTest << endl;
639 cout <<
"nof Pi identified as El = " << nofPiLikeEl << endl;
640 cout <<
"nof El identified as Pi = " << nofElLikePi << endl;
641 cout <<
"pion suppression = " << nofPiTest <<
"/" << nofPiLikeEl <<
" = " << piSupp << endl;
642 cout <<
"electron efficiency loss in % = " << nofElLikePi <<
"/" << nofElTest <<
" = " << elEff << endl;
651 for (Int_t i = 0; i < 2; i++) {
652 Double_t cumProb = 0.;
653 Double_t nofTr =
fhOutput[i]->GetEntries();
654 for (Int_t iH = 1; iH <=
fhOutput[i]->GetNbinsX(); iH++) {
655 cumProb +=
fhOutput[i]->GetBinContent(iH);
656 Double_t pr = (i == 0) ? 1. - cumProb / nofTr : cumProb / nofTr;
665 Double_t
x[nBins],
y[nBins];
667 for (Int_t i = 1; i <= nBins; i++) {
669 if (cpi == 100.) cpi = 100. - 0.0001;
670 y[i - 1] = 100. / (100. - cpi);
673 TGraph* rocGraph =
new TGraph(nBins,
x,
y);
674 rocGraph->SetTitle(
"ROC diagram");
675 rocGraph->GetXaxis()->SetTitle(
"Efficiency [%]");
676 rocGraph->GetYaxis()->SetTitle(
"Pion suppression");
677 rocGraph->SetLineWidth(3);
683 Double_t optimalCut = -1;
697 TTree* simu =
new TTree(
"MonteCarlo",
"MontecarloData");
698 size_t buf_size = 100;
699 char txt1[buf_size], txt2[buf_size];
701 snprintf(txt1, buf_size - 1,
"x%d", i);
702 snprintf(txt2, buf_size - 1,
"x%d/F", i);
705 simu->Branch(
"xOut", &
fXOut,
"xOut/F");
713 size_t buf_size = 50;
716 snprintf(txt, buf_size - 1,
"x%d", i);
722 st = st +
":" + txt +
":xOut";
729 TFile* outputFile = TFile::Open(
string(
fOutputDir +
"/tmva_output.root").c_str(),
"RECREATE");
731 TMVA::Factory* factory =
new TMVA::Factory(
"TMVAnalysis", outputFile);
733 TCut piCut =
"xOut<0";
734 TCut elCut =
"xOut>0";
737 size_t buf_size = 100;
740 snprintf(txt1, buf_size - 1,
"x%d", i);
755 TMVA::Reader* reader =
new TMVA::Reader();
757 size_t buf_size = 100;
760 snprintf(txt1, buf_size - 1,
"x%d", i);
761 reader->AddVariable(txt1, &
fAnnInput[i]);
768 for (UInt_t j = 0; j <
fAnnInput.size(); j++) {
781 TCanvas* cEloss =
new TCanvas(
"trd_elid_eloss",
"trd_elid_eloss", 1200, 600);
782 cEloss->Divide(2, 1);
789 TCanvas* cElossSort =
new TCanvas(
"trd_elid_eloss_sort",
"trd_elid_eloss_sort", 1200, 900);
790 cElossSort->Divide(4, 3);
792 cElossSort->cd(iL + 1);
798 TH1D* out0 = (TH1D*)
fhOutput[0]->Clone();
799 TH1D* out1 = (TH1D*)
fhOutput[1]->Clone();
802 DrawH1(list_of(out0)(out1), list_of(
"e^{#pm}")(
"#pi^{#pm}"),
kLinear,
kLog,
true, 0.8, 0.8, 0.99, 0.99);
803 out0->Scale(1. / out0->Integral());
804 out1->Scale(1. / out1->Integral());
814 TCanvas* cInput =
new TCanvas(
"trd_elid_input",
"trd_elid_ann_input", 10, 10, 800, 800);
815 cInput->Divide(4, 3);
ClassImp(CbmConverterManager)
void SetDefaultDrawStyle()
void DrawH1(TH1 *hist, HistScale logx, HistScale logy, const string &drawOpt, Int_t color, Int_t lineWidth, Int_t lineStyle, Int_t markerSize, Int_t markerStyle)
void DrawGraph(TGraph *graph, HistScale logx, HistScale logy, const string &drawOpt, Int_t color, Int_t lineWidth, Int_t lineStyle, Int_t markerSize, Int_t markerStyle)
Helper functions for drawing 1D and 2D histograms and graphs.
Class for hits in TRD detector.
static constexpr size_t size()
int32_t GetMotherId() const
int32_t GetPdgCode() const
const CbmLink & GetMatchedLink() const
virtual int32_t GetNofHits() const
int32_t GetHitIndex(int32_t iHit) const
virtual ~CbmTrdElectronsTrainAnn()
Destructor.
void FillElossHist()
Fill histograms with energy loss information.
void Draw(Option_t *="")
Draw results.
std::string fBeamDataFile
virtual InitStatus Init()
Inherited from FairTask.
TGraph * CreateRocDiagramm()
void CreateCumProbOutputHist()
TClonesArray * fTrdPoints
virtual void Finish()
Inherited from FairTask.
CbmTrdElectronsTrainAnn(int nofTrdLayers)
Default constructor.
void FillElossVectorSim()
Fill vector with energy loss information for simulated data.
void SortElossAndFillHist()
Sort energy losses and fill histograms.
std::vector< TH1 * > fhCumProbOutput
TMVA::Reader * CreateTmvaReader()
void FillElossVectorReal()
Fill vector with energy loss information simulated from real data spectra.
std::vector< std::vector< TH1 * > > fhInput
Double_t Eval(Bool_t isEl)
void FillAnnInputHist(Bool_t isEl)
std::vector< std::vector< std::vector< TrdEloss > > > fEloss
std::vector< TH1 * > fhOutput
TClonesArray * fTrdTrackMatches
TMVA::Factory * CreateFactory(TTree *simu)
Double_t FindOptimalCut()
std::string fBeamDataPiHist
std::vector< TH1 * > fhMeanEloss
std::vector< Float_t > fAnnInput
std::vector< TH1 * > fHists
std::string CreateAnnString()
virtual void Exec(Option_t *opt)
Inherited from FairTask.
TMultiLayerPerceptron * fNN
TClonesArray * fTrdTracks
std::vector< std::vector< TH1 * > > fhElossSort
std::vector< TH1 * > fhEloss
std::string fBeamDataElHist
data class for a reconstructed Energy-4D measurement in the TRD
Represents information about energy losses in one layer.