9 #include "TClonesArray.h"
14 #include "TMVA/Config.h"
22 #include <boost/assign/list_of.hpp>
29 using boost::assign::list_of;
33 using std::stringstream;
41 , fTrdTrackMatches(NULL)
50 , fOutputDir(
"results/")
59 , fNofTrdLayers(nofTrdLayers)
66 , fNofTrainSamples(2500)
67 , fElIdEfficiency(0.9)
72 fhMeanEloss.resize(2);
76 TH1::SetDefaultBufferSize(30000);
78 fhResults =
new TH1D(
"fhResults",
"fhResults", 2, 0, 2);
79 fHists.push_back(fhResults);
81 for (
int i = 0;
i < 2;
i++) {
84 fhMeanEloss[
i] =
new TH1D((
"fhMeanEloss" + s).c_str(),
85 "fhMeanEloss;Mean energy loss [a.u.];Yield",
89 fHists.push_back(fhMeanEloss[
i]);
90 fhEloss[
i] =
new TH1D((
"fhEloss" + s).c_str(),
91 "fhEloss;Energy loss [a.u.];Yield",
95 fHists.push_back(fhEloss[
i]);
98 Int_t nofSortBins = 200;
99 fhElossSort.resize(2);
100 for (
int j = 0; j < 2; j++) {
101 fhElossSort[j].resize(fNofTrdLayers);
102 for (Int_t
i = 0;
i < fNofTrdLayers;
i++) {
103 std::stringstream ss1;
104 if (j == 0) ss1 <<
"fhElossSortEl" <<
i;
105 if (j == 1) ss1 <<
"fhElossSortPi" <<
i;
107 new TH1D(ss1.str().c_str(),
108 (ss1.str() +
";Energy loss [a.u.];Counters").c_str(),
116 Int_t nofBins = 10000;
118 fhCumProbOutput.resize(2);
120 for (Int_t
i = 0;
i < 2;
i++) {
121 s = (
i == 0) ?
"El" :
"Pi";
122 fhOutput[
i] =
new TH1D((
"fhOutput" + s).c_str(),
123 "fhOutput;Output;Counter",
128 new TH1D((
"fhCumProbOutput" + s).c_str(),
129 "fhCumProbOutput;Output;Cumulative probability",
134 fhInput[
i].resize(fNofTrdLayers);
135 for (Int_t j = 0; j < fNofTrdLayers; j++) {
139 new TH1D((
"fhInput" + ss.str()).c_str(),
"fhInput", 100, 0.0, 0.0);
147 FairRootManager* ioman = FairRootManager::Instance();
149 Fatal(
"-E- CbmTrdElectronsTrainAnn::Init",
"RootManager not instantised!");
152 fMCTracks = (TClonesArray*) ioman->GetObject(
"MCTrack");
154 Fatal(
"-E- CbmTrdElectronsTrainAnn::Init",
"No MCTrack array!");
157 fTrdPoints = (TClonesArray*) ioman->GetObject(
"TrdPoint");
159 Fatal(
"-E- CbmTrdElectronsTrainAnn::Init",
"No TRDPoint array!");
162 fTrdTracks = (TClonesArray*) ioman->GetObject(
"TrdTrack");
164 Fatal(
"-E- CbmTrdElectronsTrainAnn::Init",
"No TrdTrack array!");
169 Fatal(
"-E- CbmTrdElectronsTrainAnn::Init",
"No TrdTrackMatch array!");
172 fTrdHits = (TClonesArray*) ioman->GetObject(
"TrdHit");
174 Fatal(
"-E- CbmTrdElectronsTrainAnn::Init",
"No TRDHit array!");
182 cout <<
"CbmTrdElectronsTrainAnn, event " <<
fEventNum << endl;
188 cout <<
"Nof electrons = " <<
fEloss[0].size() << endl;
189 cout <<
"Nof pions = " <<
fEloss[1].size() << endl;
200 new TFile(
string(
fOutputDir +
"/trd_elid_hist.root").c_str(),
"RECREATE");
201 for (
unsigned int i = 0;
i <
fHists.size();
i++) {
212 cout <<
"Nof electrons = " <<
fEloss[0].size() << endl;
213 cout <<
"Nof pions = " <<
fEloss[1].size() << endl;
220 Fatal(
"-E- CbmTrdElectronsTrainAnn::FillElossVectorReal()",
221 "Set input file for beam data and histogram names!");
228 double scaleX =
fhEloss[0]->GetXaxis()->GetBinUpEdge(
fhEloss[0]->GetNbinsX())
229 / hPion->GetXaxis()->GetBinUpEdge(hPion->GetNbinsX());
231 int nofSimulatedParticles = 1000000;
232 fEloss[0].resize(nofSimulatedParticles);
233 fEloss[1].resize(nofSimulatedParticles);
235 for (
int iP = 0; iP < 2; iP++) {
236 TH1F* hist = hElectron;
237 if (iP == 1) hist = hPion;
238 for (
int iT = 0; iT < nofSimulatedParticles; iT++) {
241 double eloss = scaleX * hist->GetRandom();
250 Int_t nofTrdTracks =
fTrdTracks->GetEntries();
251 for (Int_t iTrdTrack = 0; iTrdTrack < nofTrdTracks; iTrdTrack++) {
259 if (iMC < 0 || iMC >
fMCTracks->GetEntriesFast())
continue;
262 Int_t pdg = TMath::Abs(mctrack->
GetPdgCode());
267 if (motherId != -1)
continue;
270 if (pdg == 211) iP = 1;
275 for (Int_t iHit = 0; iHit < nHits; iHit++) {
290 for (
int i = 0;
i < 2;
i++) {
291 for (
unsigned int iT = 0; iT <
fEloss[
i].size(); iT++) {
292 Int_t nHits =
fEloss[
i][iT].size();
293 double sumEloss = 0.;
294 for (
int iH = 0; iH < nHits; iH++) {
295 sumEloss +=
fEloss[
i][iT][iH].fEloss;
306 for (
int iP = 0; iP < 2; iP++) {
307 for (
unsigned int iT = 0; iT <
fEloss[iP].size(); iT++) {
309 v[iH] =
fEloss[iP][iT][iH].fEloss;
311 std::sort(
v.begin(),
v.end());
345 Double_t ANNCoef1 = 1.06;
346 Double_t ANNCoef2 = 0.57;
363 for (Int_t j = 0; j < size; j++) {
367 Double_t probEl =
fhElossSort[0][j]->GetBinContent(binNumEl);
372 Double_t probPi =
fhElossSort[1][j]->GetBinContent(binNumPi);
374 if (TMath::IsNaN(probPi / (probEl + probPi))) {
377 fAnnInput[j] = probPi / (probEl + probPi);
386 for (UInt_t j = 0; j <
fAnnInput.size(); j++) {
388 if (binNumEl >
fhEloss[0]->GetNbinsX()) binNumEl =
fhEloss[0]->GetNbinsX();
389 Double_t probEl =
fhEloss[0]->GetBinContent(binNumEl);
393 if (binNumPi >
fhEloss[1]->GetNbinsX()) binNumPi =
fhEloss[1]->GetNbinsX();
394 Double_t probPi =
fhEloss[1]->GetBinContent(binNumPi);
397 return lEl / (lEl + lPi);
410 1. /
fhEloss[0]->GetXaxis()->GetBinUpEdge(
fhEloss[0]->GetNbinsX());
411 return eval * scaleX;
421 1. /
fhEloss[0]->GetXaxis()->GetBinUpEdge(
fhEloss[0]->GetNbinsX());
422 return eval * scaleX;
427 return fReader->EvaluateMVA(
"BDT");
432 return fNN->Evaluate(0, par);
449 for (Int_t
i = 0;
i < 2;
i++) {
450 for (UInt_t iT = 0; iT <
fEloss[
i].size() - 2; iT++) {
454 fXOut = (
i == 0) ? 1. : -1.;
462 if (NULL !=
fNN)
delete fNN;
464 cout <<
"-I- Create ANN: " << mlpString << endl;
465 cout <<
"-I- Number of training epochs = " <<
fNofAnnEpochs << endl;
466 fNN =
new TMultiLayerPerceptron(mlpString, simu,
"(Entry$+1)");
470 fNN->DumpWeights(ss.str().c_str());
473 (TMVA::gConfig().GetIONames()).fWeightFileDir =
fOutputDir;
481 <<
":nTest_Signal=0:nTest_Background=0";
490 cout <<
"-I- Start pretesting " << endl;
492 cout <<
"-I- IdMethod = kBDT " << endl;
494 cout <<
"-I- IdMethod = kANN " << endl;
496 cout <<
"-I- IdMethod = kMEDIANA " << endl;
498 cout <<
"-I- IdMethod = kLIKELIHOOD " << endl;
508 if (
fNN != NULL)
delete fNN;
511 fNN =
new TMultiLayerPerceptron(mlpString, simu,
"(Entry$+1)");
514 fNN->LoadWeights(ss.str().c_str());
517 for (Int_t
i = 0;
i < 2;
i++) {
518 for (UInt_t iT = 0; iT <
fEloss[
i].size(); iT++) {
520 if (iT % 100000 == 0) cout <<
"-I- read number: " << iT << endl;
534 Bool_t isEl = (
i == 0) ?
true :
false;
536 Double_t nnEval =
Eval(isEl);
551 cout <<
"-I- Optimal cut = " << cut <<
" for " << 100 *
fElIdEfficiency
552 <<
"% electron efficiency" << endl;
553 cout <<
"-I- Start testing" << endl;
562 if (
fNN != NULL)
delete fNN;
565 fNN =
new TMultiLayerPerceptron(mlpString, simu,
"(Entry$+1)");
568 fNN->LoadWeights(ss.str().c_str());
576 for (Int_t
i = 0;
i < 2;
i++) {
577 for (UInt_t iT = 0; iT <
fEloss[
i].size(); iT++) {
579 if (iT % 100000 == 0) cout <<
"-I- Read number: " << iT << endl;
586 Bool_t isEl = (
i == 0) ?
true :
false;
587 Double_t nnEval =
Eval(isEl);
592 if (nnEval < cut) nofElLikePi++;
595 if (nnEval > cut) nofPiLikeEl++;
600 if (nofPiLikeEl != 0) piSupp = (double) nofPiTest / nofPiLikeEl;
601 double elEff = (double) nofElLikePi / nofElTest * 100.;
603 cout <<
"Testing results:" << endl;
605 cout <<
"cut = " << cut << endl;
606 cout <<
"nof El = " << nofElTest << endl;
607 cout <<
"nof Pi = " << nofPiTest << endl;
608 cout <<
"nof Pi identified as El = " << nofPiLikeEl << endl;
609 cout <<
"nof El identified as Pi = " << nofElLikePi << endl;
610 cout <<
"pion suppression = " << nofPiTest <<
"/" << nofPiLikeEl <<
" = "
612 cout <<
"electron efficiency loss in % = " << nofElLikePi <<
"/" << nofElTest
613 <<
" = " << elEff << endl;
621 for (Int_t
i = 0;
i < 2;
i++) {
622 Double_t cumProb = 0.;
623 Double_t nofTr =
fhOutput[
i]->GetEntries();
624 for (Int_t iH = 1; iH <=
fhOutput[
i]->GetNbinsX(); iH++) {
625 cumProb +=
fhOutput[
i]->GetBinContent(iH);
626 Double_t pr = (
i == 0) ? 1. - cumProb / nofTr : cumProb / nofTr;
634 Double_t
x[nBins],
y[nBins];
636 for (Int_t
i = 1;
i <= nBins;
i++) {
638 if (cpi == 100.) cpi = 100. - 0.0001;
639 y[
i - 1] = 100. / (100. - cpi);
642 TGraph* rocGraph =
new TGraph(nBins,
x,
y);
643 rocGraph->SetTitle(
"ROC diagram");
644 rocGraph->GetXaxis()->SetTitle(
"Efficiency [%]");
645 rocGraph->GetYaxis()->SetTitle(
"Pion suppression");
646 rocGraph->SetLineWidth(3);
651 Double_t optimalCut = -1;
664 TTree* simu =
new TTree(
"MonteCarlo",
"MontecarloData");
665 char txt1[100], txt2[100];
667 sprintf(txt1,
"x%d",
i);
668 sprintf(txt2,
"x%d/F",
i);
671 simu->Branch(
"xOut", &
fXOut,
"xOut/F");
680 sprintf(txt,
"x%d",
i);
686 st = st +
":" + txt +
":xOut";
693 TFile::Open(
string(
fOutputDir +
"/tmva_output.root").c_str(),
"RECREATE");
695 TMVA::Factory* factory =
new TMVA::Factory(
"TMVAnalysis", outputFile);
697 TCut piCut =
"xOut<0";
698 TCut elCut =
"xOut>0";
703 sprintf(txt1,
"x%d",
i);
717 TMVA::Reader* reader =
new TMVA::Reader();
721 sprintf(txt1,
"x%d",
i);
728 for (UInt_t j = 0; j <
fAnnInput.size(); j++) {
739 TCanvas* cEloss =
new TCanvas(
"trd_elid_eloss",
"trd_elid_eloss", 1200, 600);
740 cEloss->Divide(2, 1);
743 list_of(
"e^{#pm}")(
"#pi^{#pm}"),
753 list_of(
"e^{#pm}")(
"#pi^{#pm}"),
763 TCanvas* cElossSort =
764 new TCanvas(
"trd_elid_eloss_sort",
"trd_elid_eloss_sort", 1200, 900);
765 cElossSort->Divide(4, 3);
767 cElossSort->cd(iL + 1);
769 list_of(
"e^{#pm}")(
"#pi^{#pm}"),
780 TH1D* out0 = (TH1D*)
fhOutput[0]->Clone();
781 TH1D* out1 = (TH1D*)
fhOutput[1]->Clone();
784 DrawH1(list_of(out0)(out1),
785 list_of(
"e^{#pm}")(
"#pi^{#pm}"),
793 out0->Scale(1. / out0->Integral());
794 out1->Scale(1. / out1->Integral());
798 list_of(
"e^{#pm}")(
"#pi^{#pm}"),
813 new TCanvas(
"trd_elid_input",
"trd_elid_ann_input", 10, 10, 800, 800);
814 cInput->Divide(4, 3);
818 list_of(
"e^{#pm}")(
"#pi^{#pm}"),