EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CbmRichTrainAnnSelect.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CbmRichTrainAnnSelect.cxx
1 
9 
10 #include "CbmRichHit.h"
11 #include "CbmRichRing.h"
12 #include "CbmTrackMatch.h"
13 #include "CbmMCTrack.h"
14 #include "CbmRichRingFitterCOP.h"
15 #include "CbmRichRingSelectImpl.h"
16 #include "FairRootManager.h"
17 #include "CbmDrawHist.h"
18 #include "CbmRichConverter.h"
19 
20 #include "TMultiLayerPerceptron.h"
21 #include "TCanvas.h"
22 #include "TH1D.h"
23 #include "TClonesArray.h"
24 
25 #include <boost/assign/list_of.hpp>
26 
27 #include <vector>
28 #include <iostream>
29 #include <sstream>
30 
31 using std::cout;
32 using std::endl;
33 using std::vector;
34 using boost::assign::list_of;
35 
37  fRichRings(NULL),
38  fMcTracks(NULL),
39  fRichRingMatches(NULL),
40 
41  fEventNumber(0),
42  fQuota(0.6),
43  fMaxNofTrainSamples(5000),
44  fNofFakeLikeTrue(0),
45  fNofTrueLikeFake(0),
46  fAnnCut(-0.5),
47 
48  fhNofHits(),
49  fhAngle(),
50  fhNofHitsOnRing(),
51  fhChi2(),
52  fhRadPos(),
53  fhRadius(),
54 
55  fhAnnOutput(),
56  fhCumProb(),
57 
58  fRSParams(),
59 
60  fFitCOP(NULL),
61  fSelectImpl(NULL),
62 
63  fHists()
64 {
65  fhNofHits.resize(2);
66  fhAngle.resize(2);
67  fhNofHitsOnRing.resize(2);
68  fhChi2.resize(2);
69  fhRadPos.resize(2);
70  fhRadius.resize(2);
71  fhAnnOutput.resize(2);
72  fhCumProb.resize(2);
73  string ss;
74  for (int i = 0; i < 2; i++){
75  if (i == 0) ss = "True";
76  if (i == 1) ss = "Fake";
77  // Difference Fake and True rings histograms BEGIN
78  fhNofHits[i] = new TH1D(string("fhNofHits"+ss).c_str(),"Number of hits in ring;Nof hits in ring;Counter",50, 0, 50);
79  fHists.push_back(fhNofHits[i]);
80  fhAngle[i] = new TH1D(string("fhAngle"+ss).c_str(),"Biggest angle in ring;Angle [rad];Counter",50, 0, 6.5);
81  fHists.push_back(fhAngle[i]);
82  fhNofHitsOnRing[i] = new TH1D(string("fhNofHitsOnRing"+ss).c_str(),"Number of hits on ring;Nof hits on ring;Counter",50, 0, 50);
83  fHists.push_back(fhNofHitsOnRing[i]);
84  fhChi2[i] = new TH1D(string("fhFakeChi2"+ss).c_str(),"Chi2;Chi2;Counter", 100, 0., 1.0);
85  fHists.push_back(fhChi2[i]);
86  fhRadPos[i] = new TH1D(string("fhRadPos"+ss).c_str(),"Radial position;Radial position [cm];Counter",150, 0, 150);
87  fHists.push_back(fhRadPos[i]);
88  fhRadius[i] = new TH1D(string("fhRadius"+ss).c_str(),"Radius;Radius [cm];Counter",80, 0., 9.);
89  fHists.push_back(fhRadius[i]);
90  // ANN outputs
91  fhAnnOutput[i] = new TH1D(string("fhAnnOutput"+ss).c_str(),"ANN output;ANN output;Counter",100, -1.2, 1.2);
92  fHists.push_back(fhAnnOutput[i]);
93  fhCumProb[i] = new TH1D(string("fhCumProb"+ss).c_str(),"ANN output;ANN output;Cumulative probability",100, -1.2, 1.2);
94  fHists.push_back(fhCumProb[i]);
95  }
96 
97  fRSParams.resize(2);
98 }
99 
101 {
102 
103 }
104 
106 {
107  cout << "InitStatus CbmRichTrainAnnSelect::Init()" << endl;
109  if (NULL == ioman) { Fatal("CbmRichRingQa::Init","CbmRootManager is not instantiated"); }
110 
111  fRichRings = (TClonesArray*) ioman->GetObject("RichRing");
112  if (NULL == fRichRings) { Fatal("CbmRichTrainAnnSelect::Init","No RichRing array!"); }
113 
114  fMcTracks = (TClonesArray*) ioman->GetObject("MCTrack");
115  if (NULL == fMcTracks) { Fatal("CbmRichTrainAnnSelect::Init","No MCTrack array!");}
116 
117  fRichRingMatches = (TClonesArray*) ioman->GetObject("RichRingMatch");
118  if (NULL == fRichRingMatches) { Fatal("CbmRichTrainAnnSelect::Init","No RichRingMatch array!");}
119 
123 
124  return kSUCCESS;
125 }
126 
128  Option_t* option)
129 {
130  fEventNumber++;
131  cout<<"CbmRichRingQa Event No. "<< fEventNumber << endl;
132 
133  SetRecFlag();
135 
136  cout << "nof trues = " << fRSParams[0].size() << endl;
137  cout << "nof fakes = " << fRSParams[1].size() << endl;
138 }
139 
141 {
142  Int_t nMatches = fRichRingMatches->GetEntriesFast();
143  vector<Int_t> clone;
144  clone.clear();
145 
146  for (Int_t iMatches = 0; iMatches < nMatches; iMatches++){
147  CbmTrackMatch* match = (CbmTrackMatch*)fRichRingMatches->At(iMatches);
148  if (NULL == match) continue;
149 
150  CbmRichRing* ring = (CbmRichRing*)fRichRings->At(iMatches);
151  if (NULL == ring) continue;
152 
153  Int_t lTrueHits = match->GetNofTrueHits();
154  Int_t lWrongHits = match->GetNofWrongHits();
155  Int_t lFakeHits = match->GetNofFakeHits();
156 // Int_t lMCHits = match->GetNofMCHits();
157  Int_t lFoundHits = lTrueHits + lWrongHits + lFakeHits;
158  Double_t lPercTrue = 0.;
159  if (lFoundHits >= 1){
160  lPercTrue = (Double_t)lTrueHits / (Double_t)lFoundHits;
161  }
162 
163  Int_t trackID = match->GetMCTrackId();
164  if (trackID > fMcTracks->GetEntriesFast() || trackID < 0) continue;
165  CbmMCTrack* track = (CbmMCTrack*) fMcTracks->At(trackID);
166  if (NULL == track) continue;
167 
168  Int_t gcode = TMath::Abs(track->GetPdgCode());
169  //Double_t momentum = track->GetP();
170  Int_t motherId = track->GetMotherId();
171 
172  ring->SetRecFlag(-1);
173 
174  if (lPercTrue < fQuota){ // fake ring
175  ring->SetRecFlag(1);
176  }else{ // true rings
177  if (gcode == 11 && motherId == -1){ // select primary electrons
178  ring->SetRecFlag(3);
179  }
180  }
181  }// iMatches
182 }
183 
185 {
186  Int_t nMatches = fRichRingMatches->GetEntriesFast();
187 
188  for (Int_t iMatches = 0; iMatches < nMatches; iMatches++) {
189  CbmTrackMatch* match = (CbmTrackMatch*) fRichRingMatches->At(iMatches);
190  if (NULL == match) continue;
191 
192  CbmRichRing* ring = (CbmRichRing*) fRichRings->At(iMatches);
193  if (NULL == ring) continue;
194 
195  CbmRichRingLight ringLight;
196  CbmRichConverter::CopyHitsToRingLight(ring, &ringLight);
197  fFitCOP->DoFit(&ringLight);
198 
199  Int_t recFlag = ring->GetRecFlag();
200  Double_t angle = fSelectImpl->GetAngle(&ringLight);
201  Int_t hitsOnRing = fSelectImpl->GetNofHitsOnRingCircle(&ringLight);
202  Double_t chi2 = ringLight.GetChi2() / ringLight.GetNofHits();
203  Int_t nHits = ringLight.GetNofHits();
204  Double_t radPos = ringLight.GetRadialPosition();
205  Double_t radius = ringLight.GetRadius();
206 
208  p.fAngle = angle;
209  p.fChi2 = chi2;
210  p.fHitsOnRing = hitsOnRing;
211  p.fNofHits = nHits;
212  p.fRadPos = radPos;
213  p.fRadius = radius;
214 
215  if (recFlag == 1){
216  fhNofHits[1]->Fill(nHits);
217  fhAngle[1]->Fill(angle);
218  fhNofHitsOnRing[1]->Fill(hitsOnRing);
219  fhRadPos[1]->Fill(radPos);
220  fhRadius[1]->Fill(radius);
221  fhChi2[1]->Fill(chi2);
222  fRSParams[1].push_back(p);
223  }
224 
225  if (recFlag == 3){
226  fhNofHits[0]->Fill(nHits);
227  fhAngle[0]->Fill(angle);
228  fhNofHitsOnRing[0]->Fill(hitsOnRing);
229  fhRadPos[0]->Fill(radPos);
230  fhRadius[0]->Fill(radius);
231  fhChi2[0]->Fill(chi2);
232  fRSParams[0].push_back(p);
233  }
234  }// iMatches
235 }
236 
238 {
239  TTree *simu = new TTree ("MonteCarlo","MontecarloData");
240  Double_t x[6];
241  Double_t xOut;
242 
243  simu->Branch("x0", &x[0],"x0/D");
244  simu->Branch("x1", &x[1],"x1/D");
245  simu->Branch("x2", &x[2],"x2/D");
246  simu->Branch("x3", &x[3],"x3/D");
247  simu->Branch("x4", &x[4],"x4/D");
248  simu->Branch("x5", &x[5],"x5/D");
249  simu->Branch("xOut", &xOut,"xOut/D");
250 
251  for (int j = 0; j < 2; j++){
252  for (int i = 0; i < fRSParams[j].size(); i++){
253  x[0] = fRSParams[j][i].fNofHits / 45.;
254  x[1] = fRSParams[j][i].fAngle / 6.28;
255  x[2] = fRSParams[j][i].fHitsOnRing / 45.;
256  x[3] = fRSParams[j][i].fRadPos / 110.;
257  x[4] = fRSParams[j][i].fRadius / 10.;
258  x[5] = fRSParams[j][i].fChi2 / 0.4;
259 
260  for (int k = 0; k < 6; k++){
261  if (x[k] < 0.) x[k] = 0.;
262  if (x[k] > 1.) x[k] = 1.;
263  }
264 
265  if (j == 0) xOut = 1.;
266  if (j == 1) xOut = -1.;
267  simu->Fill();
268  if (i >= fMaxNofTrainSamples) break;
269  }
270  }
271 
272  TMultiLayerPerceptron network("x0,x1,x2,x3,x4,x5:10:xOut",simu,"Entry$+1");
273  //network.LoadWeights("/u/slebedev/JUL09/trunk/parameters/rich/NeuralNet_RingSelection_Weights_Compact.txt");
274  network.Train(300,"text,update=10");
275  network.DumpWeights("rich_select_ann_weights.txt");
276  //network.Export();
277 
278  Double_t params[6];
279 
280  fNofFakeLikeTrue = 0;
281  fNofTrueLikeFake = 0;
282 
283  for (int j = 0; j < 2; j++){
284  for (int i = 0; i < fRSParams[j].size(); i++){
285  params[0] = fRSParams[j][i].fNofHits / 45.;
286  params[1] = fRSParams[j][i].fAngle / 6.28;
287  params[2] = fRSParams[j][i].fHitsOnRing / 45.;
288  params[3] = fRSParams[j][i].fRadPos / 110.;
289  params[4] = fRSParams[j][i].fRadius / 10.;
290  params[5] = fRSParams[j][i].fChi2 / 0.4;
291 
292  for (int k = 0; k < 6; k++){
293  if (params[k] < 0.) params[k] = 0.;
294  if (params[k] > 1.) params[k] = 1.;
295  }
296 
297  Double_t netEval = network.Evaluate(0, params);
298 
299  //if (netEval > maxEval) netEval = maxEval - 0.01;
300  // if (netEval < minEval) netEval = minEval + 0.01;
301 
302  fhAnnOutput[j]->Fill(netEval);
303  if (netEval >= fAnnCut && j == 1) fNofFakeLikeTrue++;
304  if (netEval < fAnnCut && j == 0) fNofTrueLikeFake++;
305  }
306  }
307 }
308 
310 {
311  cout <<"nof Trues = " << fRSParams[0].size() << endl;
312  cout <<"nof Fakes = " << fRSParams[1].size() << endl;
313  cout <<"Fake like True = " << fNofFakeLikeTrue << ", fake remain = " << (double)fNofFakeLikeTrue/fRSParams[1].size() << endl;
314  cout <<"True like Fake = " << fNofTrueLikeFake << ", true loss = " << (double)fNofTrueLikeFake/fRSParams[0].size() << endl;
315  cout << "ANN cut = " << fAnnCut << endl;
316 
317  Double_t cumProbFake = 0.;
318  Double_t cumProbTrue = 0.;
319  Int_t nofFake = (Int_t)fhAnnOutput[1]->GetEntries();
320  Int_t nofTrue = (Int_t)fhAnnOutput[0]->GetEntries();
321  for (Int_t i = 1; i <= fhAnnOutput[1]->GetNbinsX(); i++){
322  cumProbFake += fhAnnOutput[1]->GetBinContent(i);
323  fhCumProb[1]->SetBinContent(i, (Double_t)cumProbFake/nofFake);
324 
325  cumProbTrue += fhAnnOutput[0]->GetBinContent(i);
326  fhCumProb[0]->SetBinContent(i, 1. - (Double_t)cumProbTrue / nofTrue);
327  }
328 
329  TCanvas* c1 = new TCanvas("ann_select_ann_output", "ann_select_ann_output", 500, 500);
330  fhAnnOutput[0]->Scale(1./fhAnnOutput[0]->Integral());
331  fhAnnOutput[1]->Scale(1./fhAnnOutput[1]->Integral());
332  DrawH1(list_of(fhAnnOutput[0])(fhAnnOutput[1]), list_of("True")("Fake"), kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
333 
334  TCanvas* c2 = new TCanvas("ann_select_cum_prob", "ann_select_cum_prob", 500, 500);
335  DrawH1(list_of(fhCumProb[0])(fhCumProb[1]), list_of("True")("Fake"), kLinear, kLinear, true, 0.8, 0.8, 0.99, 0.99);
336 
337  TCanvas* c3 = new TCanvas("ann_select_params", "ann_select_params", 900, 600);
338  c3->Divide(3, 2);
339  c3->cd(1);
340  DrawH1(list_of(fhNofHits[0])(fhNofHits[1]), list_of("True")("Fake"), kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
341  c3->cd(2);
342  DrawH1(list_of(fhAngle[0])(fhAngle[1]), list_of("True")("Fake"), kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
343  c3->cd(3);
344  DrawH1(list_of(fhNofHitsOnRing[0])(fhNofHitsOnRing[1]), list_of("True")("Fake"), kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
345  c3->cd(4);
346  DrawH1(list_of(fhRadPos[0])(fhRadPos[1]), list_of("True")("Fake"), kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
347  c3->cd(5);
348  DrawH1(list_of(fhChi2[0])(fhChi2[1]), list_of("True")("Fake"), kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
349  c3->cd(6);
350  DrawH1(list_of(fhRadius[0])(fhRadius[1]), list_of("True")("Fake"), kLinear, kLog, true, 0.8, 0.8, 0.99, 0.99);
351 }
352 
354 {
355  TrainAndTestAnn();
356  Draw();
357 
358  TDirectory *current = gDirectory;
359  TDirectory *rich = current->mkdir("CbmRichTrainAnnSelect");
360  rich->cd();
361 
362  for (int i = 0; i < fHists.size(); i++ ){
363  fHists[i]->Write();
364  }
365 
366  rich->cd();
367  current->cd();
368 
369  delete fFitCOP;
370  delete fSelectImpl;
371 }
372