All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
LikelihoodPIDProcessor.cc
Go to the documentation of this file.
1 #include <vector>
2 #include <string>
3 
4 #include <EVENT/LCCollection.h>
5 #include <IMPL/ParticleIDImpl.h>
6 #include <IMPL/ReconstructedParticleImpl.h>
7 #include <UTIL/PIDHandler.h>
8 
9 #include "TLorentzVector.h"
10 
12 #include "LikelihoodPID.hh"
14 
16 
18  : Processor("LikelihoodPIDProcessor") {
19 
20  // Processor description
21  _description = "Particle ID code using Bayesian Classifier" ;
22 
23  std::vector< std::string > xmlfiles;
24  xmlfiles.push_back( "TMVAClassification_BDTG_02GeVP_clusterinfo.weights.xml" );
25  xmlfiles.push_back( "TMVAClassification_BDTG_03GeVP_clusterinfo.weights.xml" );
26  xmlfiles.push_back( "TMVAClassification_BDTG_04GeVP_clusterinfo.weights.xml" );
27  xmlfiles.push_back( "TMVAClassification_BDTG_05GeVP_clusterinfo.weights.xml" );
28  xmlfiles.push_back( "TMVAClassification_BDTG_06GeVP_clusterinfo.weights.xml" );
29  xmlfiles.push_back( "TMVAClassification_BDTG_07GeVP_clusterinfo.weights.xml" );
30  xmlfiles.push_back( "TMVAClassification_BDTG_08GeVP_clusterinfo.weights.xml" );
31  xmlfiles.push_back( "TMVAClassification_BDTG_09GeVP_clusterinfo.weights.xml" );
32  xmlfiles.push_back( "TMVAClassification_BDTG_10GeVP_clusterinfo.weights.xml" );
33  xmlfiles.push_back( "TMVAClassification_BDTG_11GeVP_clusterinfo.weights.xml" );
34  xmlfiles.push_back( "TMVAClassification_BDTG_12GeVP_clusterinfo.weights.xml" );
35  xmlfiles.push_back( "TMVAClassification_BDTG_13GeVP_clusterinfo.weights.xml" );
36  xmlfiles.push_back( "TMVAClassification_BDTG_14GeVP_clusterinfo.weights.xml" );
37  xmlfiles.push_back( "TMVAClassification_BDTG_15GeVP_clusterinfo.weights.xml" );
38  xmlfiles.push_back( "TMVAClassification_BDTG_16GeVP_clusterinfo.weights.xml" );
39  xmlfiles.push_back( "TMVAClassification_BDTG_17GeVP_clusterinfo.weights.xml" );
40  xmlfiles.push_back( "TMVAClassification_BDTG_18GeVP_clusterinfo.weights.xml" );
41  xmlfiles.push_back( "TMVAClassification_BDTG_19GeVP_clusterinfo.weights.xml" );
42  xmlfiles.push_back( "TMVAClassification_BDTG_20GeVP_clusterinfo.weights.xml" );
43 
44  registerInputCollection( LCIO::RECONSTRUCTEDPARTICLE,
45  "RecoParticleCollection" ,
46  "Input collection of Reconstrcuted Particle",
48  std::string("PandoraPFOs"));
49 
50  registerProcessorParameter( "EnergyBoundaries" ,
51  "Boundaries for energy",
53  EVENT::FloatVec(0,1.0e+07));
54 
55  registerProcessorParameter( "FilePDFName" ,
56  "rootfile of PDF",
57  _PDFName,
58  std::string("pdf_ParticleID_ok.root") );
59 
60  registerProcessorParameter( "FileWeightFormupiSeparationName" ,
61  "weight file for low momentum mu pi separation",
63  xmlfiles );
64 
65  std::vector< float > parselectron,parsmuon,parspion,parskaon,parsproton;
66  parselectron.push_back(-2.40638e-03);
67  parselectron.push_back(7.10337e-01);
68  parselectron.push_back(2.87718e-01);
69  parselectron.push_back(-1.71591e+00);
70  parselectron.push_back(0.0);
71  registerProcessorParameter( "dEdxParameter_electron" ,
72  "dEdx Parameters for electron",
74  parselectron);
75 
76  parsmuon.push_back(8.11408e-02);
77  parsmuon.push_back(9.92207e-01);
78  parsmuon.push_back(7.58509e+05);
79  parsmuon.push_back(-1.70167e-01);
80  parsmuon.push_back(4.63670e-04);
81  registerProcessorParameter( "dEdxParameter_muon" ,
82  "dEdx Parameters for muon",
84  parsmuon);
85 
86  parspion.push_back(8.10756e-02);
87  parspion.push_back(-1.45051e+06);
88  parspion.push_back(-3.09843e+04);
89  parspion.push_back(2.84056e-01);
90  parspion.push_back(3.38131e-04);
91  registerProcessorParameter( "dEdxParameter_pion" ,
92  "dEdx Parameters for pion",
94  parspion);
95 
96  parskaon.push_back(7.96117e-02);
97  parskaon.push_back(4.13335e+03);
98  parskaon.push_back(1.13577e+06);
99  parskaon.push_back(1.80555e-01);
100  parskaon.push_back(-3.15083e-04);
101  registerProcessorParameter( "dEdxParameter_kaon" ,
102  "dEdx Parameters for Kaon",
104  parskaon);
105 
106  parsproton.push_back(7.78772e-02);
107  parsproton.push_back(4.49300e+04);
108  parsproton.push_back(9.13778e+04);
109  parsproton.push_back(1.50088e-01);
110  parsproton.push_back(-6.64184e-04);
111  registerProcessorParameter( "dEdxParameter_proton" ,
112  "dEdx Parameters for proton",
114  parsproton);
115 
116  registerProcessorParameter( "dEdxNormalization" ,
117  "dEdx Normalization",
119  float(1.350e-7));
120 
121  registerProcessorParameter( "dEdxErrorFactor" ,
122  "dEdx Error factor",
124  float(7.55));
125 
126  registerProcessorParameter( "UseBayesian" ,
127  "PID is based on Bayesian or Likelihood",
128  _UseBayes,
129  int(2) );
130 
131  std::vector< float > costmat;
132  costmat.push_back(0.0);
133  costmat.push_back(1.0);
134  costmat.push_back(1.0);
135  costmat.push_back(1.0);
136  costmat.push_back(1.0);
137 
138  costmat.push_back(1.0);
139  costmat.push_back(0.0);
140  costmat.push_back(9.0);
141  costmat.push_back(1.0);
142  costmat.push_back(1.0);
143 
144  costmat.push_back(1.0);
145  costmat.push_back(1.0);
146  costmat.push_back(0.0);
147  costmat.push_back(1.0);
148  costmat.push_back(1.0);
149 
150  costmat.push_back(1.0);
151  costmat.push_back(1.0);
152  costmat.push_back(30.0);
153  costmat.push_back(0.0);
154  costmat.push_back(1.0);
155 
156  costmat.push_back(1.0);
157  costmat.push_back(1.0);
158  costmat.push_back(1.0);
159  costmat.push_back(10.0);
160  costmat.push_back(0.0);
161 
162  registerProcessorParameter( "CostMatrix" ,
163  "cost matrix for risk based bayesian classifier",
164  _cost,
165  costmat);
166 
167 
168  registerProcessorParameter( "UseLowMomentumMuPiSeparation" ,
169  "MVA mu/pi separation should be used or not",
170  _UseMVA,
171  bool(true) );
172 
173 
174  std::vector< std::string > methods_to_run;
175  methods_to_run.push_back( "BasicVariablePID" );
176  methods_to_run.push_back( "LowMomMuID" );
177  methods_to_run.push_back( "ShowerShapesPID" );
178  methods_to_run.push_back( "dEdxPID" );
179  methods_to_run.push_back( "LikelihoodPID" );
180 
181  registerProcessorParameter( "PIDMethodsToRun" ,
182  "methods to be run, default: BasicVariablePID LowMomMuID ShowerShapesPID dEdxPID LikelihoodPID",
184  methods_to_run );
185 
186 
187  std::string methods_to_run_version="";
188  registerProcessorParameter( "PIDMethodsToRun_version" ,
189  "version of the methods (for rerunning purposes)",
191  methods_to_run_version );
192 
193 }
194 
196  streamlog_out(DEBUG) << " init called " << std::endl ;
197 
198  //dEdx parameters
199  double pars[28];
200  for(int i=0;i<5;i++) pars[i]=_dEdxParamsElectron[i];
201  for(int i=0;i<5;i++) pars[i+5]=_dEdxParamsMuon[i];
202  for(int i=0;i<5;i++) pars[i+10]=_dEdxParamsPion[i];
203  for(int i=0;i<5;i++) pars[i+15]=_dEdxParamsKaon[i];
204  for(int i=0;i<5;i++) pars[i+20]=_dEdxParamsProton[i];
205  pars[25] =(double) _UseBayes;
206  pars[26] =(double) _dEdxNormalization;
207  pars[27] =(double) _dEdxErrorFactor;
208 
209  _pdgTable.push_back(11);
210  _pdgTable.push_back(13);
211  _pdgTable.push_back(211);
212  _pdgTable.push_back(321);
213  _pdgTable.push_back(2212);
214 
215  //for parameters except for dEdxPID
216  _particleNames.push_back("electronLikelihood");
217  _particleNames.push_back("muonLikelihood");
218  _particleNames.push_back("pionLikelihood");
219  _particleNames.push_back("kaonLikelihood");
220  _particleNames.push_back("protonLikelihood");
221  _particleNames.push_back("hadronLikelihood");
222  _particleNames.push_back("MVAOutput_mupiSeparation");
223  _particleNames.push_back("electronProbability");
224  _particleNames.push_back("muonProbability");
225  _particleNames.push_back("pionProbability");
226  _particleNames.push_back("kaonProbability");
227  _particleNames.push_back("protonProbability");
228  _particleNames.push_back("hadronProbability");
229  _particleNames.push_back("electron_dEdxdistance");
230  _particleNames.push_back("muon_dEdxdistance");
231  _particleNames.push_back("pion_dEdxdistance");
232  _particleNames.push_back("kaon_dEdxdistance");
233  _particleNames.push_back("proton_dEdxdistance");
234 
235  //for parameters of dEdxPID
236  _dEdxNames.push_back("electronLikelihood");
237  _dEdxNames.push_back("muonLikelihood");
238  _dEdxNames.push_back("pionLikelihood");
239  _dEdxNames.push_back("kaonLikelihood");
240  _dEdxNames.push_back("protonLikelihood");
241  _dEdxNames.push_back("hadronLikelihood");
242  _dEdxNames.push_back("MVAOutput_mupiSeparation");
243  _dEdxNames.push_back("electronProbability");
244  _dEdxNames.push_back("muonProbability");
245  _dEdxNames.push_back("pionProbability");
246  _dEdxNames.push_back("kaonProbability");
247  _dEdxNames.push_back("protonProbability");
248  _dEdxNames.push_back("hadronProbability");
249  _dEdxNames.push_back("electron_dEdxdistance");
250  _dEdxNames.push_back("muon_dEdxdistance");
251  _dEdxNames.push_back("pion_dEdxdistance");
252  _dEdxNames.push_back("kaon_dEdxdistance");
253  _dEdxNames.push_back("proton_dEdxdistance");
254 
255  _myPID = new LikelihoodPID(_PDFName, pars, _cost);
256 
257  //mupi separation class
259 
260  printParameters();
261 
262 
263  //CHECK that init settings are correct
264  bool allnamecorrect=false;
265  for(size_t i=0; i<_methodstorun.size(); i++) {
266  {
267  if( _methodstorun.at(i).compare("dEdxPID")==0
268  || _methodstorun.at(i).compare("LowMomMuID")==0
269  || _methodstorun.at(i).compare("BasicVariablePID")==0
270  || _methodstorun.at(i).compare("ShowerShapesPID")==0
271  || _methodstorun.at(i).compare("LikelihoodPID")==0 ) allnamecorrect=true;
272 
273  if(allnamecorrect==false) {
274  throw EVENT::Exception(_methodstorun.at(i) + std::string(" is not in the list of valid methods: BasicVariablePID LowMomMuID ShowerShapesPID dEdxPID LikelihoodPID"));
275  }
276  allnamecorrect=false;
277  }
278  }
279 
280 }
281 
282 void LikelihoodPIDProcessor::processRunHeader( LCRunHeader* /*run*/) {
283 }
284 
285 void LikelihoodPIDProcessor::processEvent( LCEvent * evt ) {
286  _pfoCol = evt->getCollection( _inputPFOsCollection ) ;
287 
288  int npfo = _pfoCol->getNumberOfElements();
289  PIDHandler pidh(_pfoCol); //BasicPID
290 
291  int algoID[10];
292  for(size_t i=0; i<_methodstorun.size(); i++) {
293  if(_methodstorun.at(i).compare("dEdxPID")==0) algoID[i] = pidh.addAlgorithm(_methodstorun.at(i)+_methodstorun_version,_dEdxNames);
294  else algoID[i] = pidh.addAlgorithm(_methodstorun.at(i)+_methodstorun_version, _particleNames);
295  }
296 
297  for (int i = 0; i < npfo; i++ ) {
298  ReconstructedParticleImpl* part = dynamic_cast<ReconstructedParticleImpl*>( _pfoCol->getElementAt(i) );
299 
300  if(part->getCharge()==0) continue; //avoid neutral particle
301 
302  EVENT::ClusterVec clu=part->getClusters();
303  lcio::Track* trk = part->getTracks()[0];
304  TLorentzVector pp(part->getMomentum()[0],
305  part->getMomentum()[1],
306  part->getMomentum()[2],
307  part->getEnergy());
308 
309  Int_t parttype=-1;
310 //////////////////////////////////////////////////////////////////////////////////
311  for(size_t ialgo=0; ialgo<_methodstorun.size(); ialgo++) {
312  if(_methodstorun.at(ialgo) == "LowMomMuID") {
313  //Low momentum Muon identification
314  // (from 0.2 GeV until 2 GeV)
315  if(_UseMVA){
316  Float_t MVAoutput = -100.0;
317  parttype = -1;
318  if(pp.P()<2.5){
319  parttype=_mupiPID->MuPiSeparation(pp, trk, clu);
320  MVAoutput = _mupiPID->getMVAOutput();
321  }
322  //create PIDHandler
323  createParticleIDClass(parttype, part, pidh, algoID[ialgo], MVAoutput);
324  }
325  } else {
326  //several partivle IDs performed
327  //use just basic variables
328  if(_methodstorun.at(ialgo) == "BasicVariablePID") {
329  _myPID->setBasicFlg(true);
330  _myPID->setdEdxFlg(false);
331  _myPID->setShowerShapesFlg(false);
332  }
333 
334  if(_methodstorun.at(ialgo).compare("dEdxPID")==0) {
335  _myPID->setBasicFlg(false);
336  _myPID->setdEdxFlg(true);
337  _myPID->setShowerShapesFlg(false);
338  }
339 
340  if(_methodstorun.at(ialgo).compare("ShowerShapesPID")==0) {
341  _myPID->setBasicFlg(false);
342  _myPID->setdEdxFlg(false);
343  _myPID->setShowerShapesFlg(true);
344  }
345 
346  if(_methodstorun.at(ialgo).compare("LikelihoodPID")==0) {
347  _myPID->setBasicFlg(true);
348  _myPID->setdEdxFlg(true);
349  _myPID->setShowerShapesFlg(true);
350  }
351 
352  parttype = _myPID->Classification(pp, trk, clu);
353  if(parttype<0) parttype=2;
354 
355  //mu-pi Separation for very low momentum tracks (from 0.2 GeV until 2 GeV)
356  Float_t MVAoutput = -100.0;
357  if((parttype==1 || parttype==2) && (_UseMVA && pp.P()<2.0 && clu.size()!=0)){
358  int tmpparttype = _mupiPID->MuPiSeparation(pp, trk, clu);
359  if(_mupiPID->isValid()) parttype = tmpparttype;
360  MVAoutput = _mupiPID->getMVAOutput();
361  }
362 
363  //create PIDHandler
364  createParticleIDClass(parttype, part, pidh, algoID[ialgo], MVAoutput);
365  }
366  }
367 
368 
369 
370  /*ParticleIDImpl *PIDImpl=new ParticleIDImpl();
371  if(parttype==0){
372  PIDImpl->setType(11);
373  PIDImpl->setLikelihood((float) posterior[0]);
374  }
375  if(parttype==1){
376  PIDImpl->setType(13);
377  PIDImpl->setLikelihood((float) posterior[1]);
378  }
379  if(parttype==2){
380  PIDImpl->setType(211);
381  PIDImpl->setLikelihood((float) posterior[2]);
382  }
383  if(parttype==3){
384  PIDImpl->setType(321);
385  PIDImpl->setLikelihood((float) posterior[3]);
386  }
387  if(parttype==4){
388  PIDImpl->setType(2212);
389  PIDImpl->setLikelihood((float) posterior[4]);
390  }
391 
392  //posterior probability
393  PIDImpl->addParameter((float) posterior[0]); //electron
394  PIDImpl->addParameter((float) posterior[1]); //muon
395  PIDImpl->addParameter((float) posterior[2]); //pion
396  PIDImpl->addParameter((float) posterior[3]); //kaon
397  PIDImpl->addParameter((float) posterior[4]); //proton
398 
399  //add particle ID
400  part->addParticleID(PIDImpl);
401  //FloatVec chk=part->getParticleIDs()[0]->getParameters();
402  //std::cout << chk[0] << std::endl;
403  //add to PFO collection(so far, this is only PID)
404  part->setParticleIDUsed(PIDImpl);
405  part->setGoodnessOfPID(PIDImpl->getLikelihood());*/
406 
407  }
408 
409 }
410 
411 void LikelihoodPIDProcessor::check( LCEvent * /*evt*/ ) {
412 }
413 
415  delete _myPID;
416  delete _mupiPID;
417 }
418 
419 void LikelihoodPIDProcessor::createParticleIDClass(int parttype, ReconstructedParticle *part, PIDHandler &pidh, int algoID, float MVAoutput){
420 
421  Double_t *posterior = _myPID->GetPosterior();
422  Double_t *likelihood = _myPID->GetLikelihood();
423  std::vector<float> likelihoodProb;
424 
425  if(pidh.getAlgorithmName(algoID).find("LowMomMuID") == std::string::npos){
426  for(int j=0;j<6;j++) likelihoodProb.push_back(likelihood[j]);
427  likelihoodProb.push_back(MVAoutput);
428  for(int j=0;j<6;j++) likelihoodProb.push_back(posterior[j]);
429  }else{
430  for(int j=0;j<6;j++) likelihoodProb.push_back(999.0);
431  likelihoodProb.push_back(MVAoutput);
432  for(int j=0;j<6;j++) likelihoodProb.push_back(0.0);
433  for(int j=0;j<6;j++){
434  likelihood[j]=999.0;
435  posterior[j]=0.0;
436  }
437  }
438 
439  //for dEdx PID
440  if(pidh.getAlgorithmName(algoID).find("dEdxPID")!= std::string::npos || pidh.getAlgorithmName(algoID).find("LikelihoodPID")!= std::string::npos){
441  likelihoodProb.push_back((float)_myPID->get_dEdxDist(0)); //electron hypothesis
442  likelihoodProb.push_back((float)_myPID->get_dEdxDist(1)); //muon hypothesis
443  likelihoodProb.push_back((float)_myPID->get_dEdxDist(2)); //pion hypothesis
444  likelihoodProb.push_back((float)_myPID->get_dEdxDist(3)); //kaon hypothesis
445  likelihoodProb.push_back((float)_myPID->get_dEdxDist(4)); //proton hypothesis
446 
447  //std::cout << "check dedx: " << parttype << " " << algoID << " "
448  // << likelihoodProb[11] << " " << likelihoodProb[12] << " " << likelihoodProb[13] << " " << likelihoodProb[14] << " " << likelihoodProb[15] << std::endl;
449  }else{
450  likelihoodProb.push_back((float)0.0); //electron hypothesis
451  likelihoodProb.push_back((float)0.0); //muon hypothesis
452  likelihoodProb.push_back((float)0.0); //pion hypothesis
453  likelihoodProb.push_back((float)0.0); //kaon hypothesis
454  likelihoodProb.push_back((float)0.0); //proton hypothesis
455  }
456 
457  //std::cout << "check posterior: " << posterior[0] << " "
458  // << posterior[1] << " "
459  // << posterior[2] << " "
460  // << posterior[3] << " "
461  // << posterior[4] << " " << std::endl;
462 
463  //set pid results
464  //set each hadron type
465  if(pidh.getAlgorithmName(algoID).find("dEdxPID")!= std::string::npos || pidh.getAlgorithmName(algoID).find("LikelihoodPID")!= std::string::npos)
466  pidh.setParticleID(part, 0, _pdgTable[parttype], (float)likelihood[parttype], algoID, likelihoodProb);
467  else{ //ignore each hadron type
468  int tmppart=parttype;
469  parttype = std::min(2,parttype);
470  if(parttype==2) tmppart=5;
471  pidh.setParticleID(part, 0, _pdgTable[parttype], (float)likelihood[tmppart], algoID, likelihoodProb);
472  }
473 
474  return;
475 }
std::vector< float > _dEdxParamsMuon
double get_dEdxDist(int parttype)
virtual void processEvent(LCEvent *evt)
virtual void processRunHeader(LCRunHeader *run)
double * GetLikelihood()
std::vector< std::string > _methodstorun
double * GetPosterior()
std::vector< float > _dEdxParamsPion
LikelihoodPIDProcessor aLikelihoodPIDProcessor
void setBasicFlg(bool flg)
std::vector< std::string > _dEdxNames
std::vector< float > _dEdxParamsProton
void setdEdxFlg(bool flg)
void setShowerShapesFlg(bool flg)
std::vector< float > _dEdxParamsKaon
static const float e
std::vector< float > _dEdxParamsElectron
std::vector< float > _cost
std::vector< std::string > _particleNames
int Classification(TLorentzVector pp, EVENT::Track *trk, EVENT::ClusterVec &cluvec)
virtual void check(LCEvent *evt)
LowMomentumMuPiSeparationPID_BDTG * _mupiPID
void createParticleIDClass(int parttype, ReconstructedParticle *part, PIDHandler &pidh, int algoID, float MVAoutput)
Int_t MuPiSeparation(TLorentzVector pp, EVENT::Track *trk, EVENT::ClusterVec &cluvec)
std::vector< std::string > _weightFileName