HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hparticlepairmaker.cc
Go to the documentation of this file.
1 #include "hparticlepairmaker.h"
2 #include "hparticlepairdraw.h"
3 #include "hcategorymanager.h"
4 #include "hphysicsconstants.h"
5 #include "hades.h"
6 #include "hrecevent.h"
7 
8 
9 #include "TCanvas.h"
10 #include "TH1F.h"
11 #include "TLatex.h"
12 #include "TEllipse.h"
13 #include "TLine.h"
14 
15 // ROOT's IO and RTTI stuff is added here
17 
18 //_HADES_CLASS_DESCRIPTION
19 ////////////////////////////////////////////////////////////////////////////////
20 //
21 //
22 // HParticlePairMaker
23 //
24 // Build vectors of freference candidates, fothers candidates and fpairs
25 // for the current event. As reference candidates marked as kIsLepton
26 // will be used.
27 //
28 // nectEvent() to be called inside eventloop after HParticleSorter selection.
29 // 1. clear all internal structures
30 // 2. fill vector freference by candidates which are flagged kIsLepton ( or kIsUsed if it is setup)
31 // All other candidates (disregarding kIsLepton or kIsUsed) are added to vector fothers
32 // To avoid unneeded pairs the user can set a userFilter by set setUserFilter(Bool_t (*userfilter)(HParticleCand*))
33 // In this case only candidates passing this function (return kTRUE) will be taken into account
34 // for freference and fothers.
35 // 3. created all pair combinations between freference x freference (no double counting) and freference x fothers.
36 // If setDoSkippedFullCandPairs(kTRUE) is set (default) in addition all pairs of full reconstructed
37 // particles ( inner+outer MDC + META) of fOthers are build (ffullrecoOthers x ffullrecoOthers +
38 // ffullrecoOthers x fnofullrecoOthers ). All pairs with full reco candidates of the event are build
39 // this way for investigation, even the ones which are skipped from reference by any criteria or double hit
40 // rejection.
41 // a. pass the selectPID1 and selectPID2 functions
42 // will get pid1 or pid2 assigned. Otherwise pid is -2(fake+), -1(fake-) (see HPhysicsConstants).
43 // if pid2 fails it will get pid assigned opposite to reference cand in pairCase10.
44 // fakes for pid2 will be assigned by polarity or opposite to reference cand.
45 // b. eClosePairSelect flags will be set for each pair (see hparticledef.h).
46 // This flags can be used later to classify the pairs.
47 // c. pairs are inserted in fpairs vector. With static HParticlePair::setDoMomentumCorrection(Bool_t doit)
48 // the enegryloss correction can be swithced on/off
49 // d. secondary vertex and vertex cut vars are calulated. Which primary ebevnt vertex
50 // should be used has to be set by the user (default = kVertexParticle, see eVertex
51 // in hparticledef.h). The user can provide an own event vertex per event by calling setVertex().
52 //
53 //
54 // Bool_t HParticleTool::evalPairsFlags(UInt_t flag,HParticlePair& pair)
55 // can be used to classify the pair according to the predefined pair cases
56 // in ePairCase + eClosePairSelect (hparticledef.h). There are dedicated filter
57 // functions provided to select from the pairs vector
58 //
59 //BEGIN_HTML
60 // <img src="http://web-docs.gsi.de/~halo/docs/hydra/classDocumentation/docu_pics/hydra2/particle/lepton_pair_cases_1.png" alt="Lepton Pair Cases" width="750" >
61 // <img src="http://web-docs.gsi.de/~halo/docs/hydra/classDocumentation/docu_pics/hydra2/particle/lepton_pair_cases_2.png" alt="Lepton Pair Cases" width="750" >
62 //END_HTML
63 // Fig 1. All predefined pairCases for Leptons
64 //
65 //BEGIN_HTML
66 // <img src="http://web-docs.gsi.de/~halo/docs/hydra/classDocumentation/docu_pics/hydra2/particle/hadron_pair_cases.png" alt="Hadron Pair Cases" width="750" >
67 //END_HTML
68 // Fig 2. All predefined pairCases for Hadrons
69 //
70 //BEGIN_HTML
71 // <img src="http://web-docs.gsi.de/~halo/docs/hydra/classDocumentation/docu_pics/hydra2/particle/lepton_hadron_pair_cases.png" alt="Mixed Lepton Hadron Pair Cases" width="525" >
72 //END_HTML
73 // Fig 2. All predefined pairCases for mixed Lepton Hadrons
74 //
75  //
76  //-----------------------------------------------------------------------------
77  // USAGE:
78  // #include "hparticlepairmaker.h"
79  // #include "hparticledef.h"
80  // #include "hparticletool.h"
81  // #include <vector>
82  // using namespace std;
83  // ....
84  //
85  //
86  // {
87  // // setup HLoop etc ....
88  //
89  // ....
90  // HEnergyLossCorrPar enLossCorr;
91  // enLossCorr.setDefaultPar("apr12"); // "jan04","nov02","aug04","apr12"
92  //
93  // //---------------------------------------------
94  // // HPARTICLEPAIRMAKER SETUP :
95  // HParticlePairMaker pairmaker;
96  // // pairmaker.setPIDs(2,3,51) // default
97  // // pairmaker.setPIDsSelection(mySelectionPID1,mySelectionPID2) // set your own selection function for pid1+pid2 (signature : Bool_t myfunction(HParticleCand*) )
98  // // pairmaker.setUseLeptons(kTRUE);// kTRUE : use kIsLepton, kFALSE: kIsUsed for selection of reference (default kTRUE)
99  // // pairmake.setRequireRich(kFALSE); // do not ask for rich Hit in selection functions ( default = kTRUE)
100  // // pairmaker.setVertexCase(Particle::kVertexParticle); // select which event vertex to use (default = kVertexParticle)
101  // // HParticlePair::setDoMomentumCorrection(kTRUE); // default : kTRUE
102  // //---------------------------------------------
103  //
104  // vector<HParticlePair*> pairs;
105  //
106  // for (Int_t i=0; i < entries; i++) {
107  // Int_t nbytes = loop.nextEvent(i); // get next event. categories will be cleared before
108  // if(nbytes <= 0) { cout<<nbytes<<endl; break; } // last event reached
109  //
110  //
111  // //--------------------------------------------------------------------------
112  // // HPARTICLETRACKSORTER SETUP
113  // sorter.cleanUp();
114  // sorter.resetFlags(kTRUE,kTRUE,kTRUE,kTRUE); // reset all flags for flags (0-28) ,reject,used,lepton
115  // Int_t nCandLep = sorter.fill(HParticleTrackSorter::selectLeptons); // fill only good leptons
116  // Int_t nCandLepBest = sorter.selectBest(HParticleTrackSorter::kIsBestRKRKMETA,HParticleTrackSorter::kIsLepton);
117  // Int_t nCandHad = sorter.fill(HParticleTrackSorter::selectHadrons); // fill only good hadrons (already marked good leptons will be skipped)
118  // Int_t nCandHadBest = sorter.selectBest(HParticleTrackSorter::kIsBestRKRKMETA,HParticleTrackSorter::kIsHadron);
119  // //--------------------------------------------------------------------------
120  //
121  //
122  // //###########################################################################
123  // // HPARTICLEPAIRMAKER ACTION:
124  // pairmaker.nextEvent(); // call it after your HParticleSorter action!
125  //
126  //
127  //
128  // //--------------------------------------------------------------------------
129  // // example 1:
130  // // fill list of pairs for pairCase1 and require
131  // // fitted inner+out+RK for second leg in addition
132  // pairmaker.filterPairsVector(pairs,kPairCase1|kFittedInnerMDC2|kFittedInnerMDC2|kRK2);
133  //
134  // for(UInt_t j = 0; j < pairs.size(); j++ ){ // print the pairs
135  // pairs[j]->print();
136  // }
137  // //--------------------------------------------------------------------------
138  //
139  //
140  // //--------------------------------------------------------------------------
141  // // example 2:
142  // // get list of all pairs and loop over the list
143  // // plot different pairCases
144  //
145  // vector<HParticlePair>& pairsVec = pairmaker.getPairsVector();
146  // for(UInt_t l = 0; l < pairsVec.size(); l++ ){
147  // HParticlePair& pair = pairsVec[l];
148  //
149  // if(HParticleTool::evalPairsFlags(kPairCase1,pair)){
150  // cout<<"case1"<<endl;
151  // } else if(HParticleTool::evalPairsFlags(kPairCase2,pair)){
152  // cout<<"case2"<<endl;
153  // } else if(HParticleTool::evalPairsFlags(kPairCase3,pair)){
154  // cout<<"case3"<<endl;
155  // } else if(HParticleTool::evalPairsFlags(kPairCase4,pair)){
156  // cout<<"case4"<<endl;
157  // } else if(HParticleTool::evalPairsFlags(kPairCase5,pair)){
158  // cout<<"case5"<<endl;
159  // } else if(HParticleTool::evalPairsFlags(kPairCase6,pair)){
160  // cout<<"case6"<<endl;
161  // } else if(HParticleTool::evalPairsFlags(kPairCase7,pair)){
162  // cout<<"case7"<<endl;
163  // } else if(HParticleTool::evalPairsFlags(kPairCase8,pair)){
164  // cout<<"case8"<<endl;
165  // } else if(HParticleTool::evalPairsFlags(kPairCase9,pair)){
166  // cout<<"case9"<<endl;
167  // } else if(HParticleTool::evalPairsFlags(kPairCase10,pair)){
168  // cout<<"case10"<<endl;
169  // } else if(HParticleTool::evalPairsFlags(kPairCase11,pair)){
170  // cout<<"case11"<<endl;
171  // }
172  // }
173  // //--------------------------------------------------------------------------
174  // //###########################################################################
175  // } // end event loop
176  // }
177 ////////////////////////////////////////////////////////////////////////////////
178 
179 Bool_t HParticlePairMaker::frequireRich = kTRUE;
180 
182 {
183  fPID1 = HPhysicsConstants::pid("e+");
184  fPID2 = HPhysicsConstants::pid("e-");
185  fMotherPID = HPhysicsConstants::pid("dilepton");
186  fselectPID1 = 0;
187  fselectPID2 = 0;
188  fuserFilter = 0;
189  fuse_kIsLepton = kTRUE;
190  fVertexCase = kVertexParticle ;
191  fdoSkippedFullCandPairs = kTRUE;
192  fpairs .resize(10000);
193  fothers .resize(1000);
194  ffullrecoOthers .resize(100);
195  fnofullrecoOthers .resize(1000);
196  freference.resize(100);
197 
198 
199  fCaseVec.push_back(kPairCase1);
200  fCaseVec.push_back(kPairCase2);
201  fCaseVec.push_back(kPairCase3);
202  fCaseVec.push_back(kPairCase4);
203  fCaseVec.push_back(kPairCase5);
204  fCaseVec.push_back(kPairCase6);
205  fCaseVec.push_back(kPairCase7);
206  fCaseVec.push_back(kPairCase8);
207  fCaseVec.push_back(kPairCase9);
208  fCaseVec.push_back(kPairCase10);
209  fCaseVec.push_back(kPairCase11);
210  fCaseVec.push_back(kPairCase12);
211  fCaseVec.push_back(kPairCase13);
212  fCaseVec.push_back(kPairCase14);
213  fCaseVec.push_back(kPairCase15);
214 
215  for(UInt_t i=0;i<fCaseVec.size();i++) fCaseCt.push_back(0);
216  richCandCt = 0 ;
217 }
218 
220 {
221  clearVectors();
222 }
223 
225 {
226  // standard function for positrons
227  // require richmatch (broad window, frequireRich =kTRUE)
228  // Select positive polatity
229 
230  if(getRequireRich() && cand->getRichInd() == -1) return kFALSE;
231 
232  if( cand->getCharge() > 0 ) return kTRUE;
233  else return kFALSE;
234 }
235 
237 {
238  // standard function for electrons
239  // require richmatch (broad window, frequireRich =kTRUE)
240  // Select negative polatity
241 
242  if(getRequireRich() && cand->getRichInd() == -1) return kFALSE;
243 
244  if( cand->getCharge() < 0 ) return kTRUE;
245  else return kFALSE;
246 }
247 
249 {
250  // add candidate hits to maps
251 
252  if(cand1->getRichInd() !=-1 ) {
253  if(mRichtoCand.find(cand1->getRichInd()) == mRichtoCand.end()){
254  vector<HParticleCand*> v;
255  v.push_back(cand1);
256  mRichtoCand[cand1->getRichInd()] = v;
257  } else {
258  mRichtoCand[cand1->getRichInd()].push_back(cand1);
259  }
260  }
261 
262  if(cand1->getInnerSegInd() !=-1 ) {
263  if(mInnerMdctoCand.find(cand1->getInnerSegInd()) == mInnerMdctoCand.end()){
264  vector<HParticleCand*> v;
265  v.push_back(cand1);
266  mInnerMdctoCand[cand1->getInnerSegInd()] = v;
267  } else {
268  mInnerMdctoCand[cand1->getInnerSegInd()].push_back(cand1);
269  }
270  }
271 
272  if(cand1->getOuterSegInd() !=-1 ) {
273  if(mOuterMdctoCand.find(cand1->getOuterSegInd()) == mOuterMdctoCand.end()){
274  vector<HParticleCand*> v;
275  v.push_back(cand1);
276  mOuterMdctoCand[cand1->getOuterSegInd()] = v;
277  } else {
278  mOuterMdctoCand[cand1->getOuterSegInd()].push_back(cand1);
279  }
280  }
281 
282  if(cand1->getSystemUsed() != -1){
283  Int_t meta = cand1->getMetaHitInd();
284  if(cand1->isTofHitUsed()){
285  if(mTofHittoCand.find(meta) == mTofHittoCand.end()){
286  vector<HParticleCand*> v;
287  v.push_back(cand1);
288  mTofHittoCand[meta] = v;
289  } else {
290  mTofHittoCand[meta].push_back(cand1);
291  }
292  } else if (cand1->isTofClstUsed()){
293  if(mTofClsttoCand.find(meta) == mTofClsttoCand.end()){
294  vector<HParticleCand*> v;
295  v.push_back(cand1);
296  mTofClsttoCand[meta] = v;
297  } else {
298  mTofClsttoCand[meta].push_back(cand1);
299  }
300  } else if (cand1->isRpcClstUsed()){
301  if(mRpcClsttoCand.find(meta) == mRpcClsttoCand.end()){
302  vector<HParticleCand*> v;
303  v.push_back(cand1);
304  mRpcClsttoCand[meta] = v;
305  } else {
306  mRpcClsttoCand[meta].push_back(cand1);
307  }
308  } else if (cand1->isShowerUsed()){
309  if(mShowertoCand.find(meta) == mShowertoCand.end()){
310  vector<HParticleCand*> v;
311  v.push_back(cand1);
312  mShowertoCand[meta] = v;
313  } else {
314  mShowertoCand[meta].push_back(cand1);
315  }
316  } else if (cand1->isEmcUsed()){
317  if(mEmctoCand.find(meta) == mEmctoCand.end()){
318  vector<HParticleCand*> v;
319  v.push_back(cand1);
320  mEmctoCand[meta] = v;
321  } else {
322  mEmctoCand[meta].push_back(cand1);
323  }
324  }
325  }
326 }
327 void HParticlePairMaker::selectPID(HParticleCand* cand1,Int_t& pid1,Bool_t warn)
328 {
329  if( (*fselectPID1)(cand1) ) { pid1 = fPID1;} // one of the 2 functions should set the PID1 , take care about others!
330  else if ((*fselectPID2)(cand1) ) { pid1 = fPID2;}
331  else {
332  if(warn){
333  Warning("nextEvent()","Reference particle not labeled with PID! Should not happen. Check your selection functions. frequireRich = kTRUE but kIsLepton is not used as referencce this might cause empty pids.");
334  cand1->print();
335  }
336  }
337 }
338 
340 {
341  // to be called inside eventloop after HParticleSorter selection.
342  // 1. clear all internal structures
343  // 2. fill vector freference by candidates which are flagged kIsLepton
344  // All other candidates are added to vector fothers
345  // 3. created all pair combinations between freference and fothers which
346  // a. pass the selectPID1 and selectPID2 functions
347  // will get pid1 or pid2 assigned. Otherwise pid is -2(fake+), -1(fake-) (see HPhysicsConstants).
348  // if pid2 fails it will get pid assigend opposite to reference cand in pairCase10.
349  // fakes for pid2 will be assigned by polarity or opposite to reference cand.
350  // b. eClosePairSelect flags will be set for each pair.
351  // This flags can be used later to classify the pairs.
352  // c. pairs are inserted in fpairs vector.
353 
354 
355  clearVectors();
356 
359 
361  if(event){
362  if(fVertexCase != kVertexUser){
364  }
365 
366  HCategory* candCat = (HCategory*) event->getCategory(catParticleCand);
367  if(candCat){
368  UInt_t n = candCat->getEntries();
369  HParticleCand* cand1 = 0 ;
370  HParticleCand* cand2 = 0 ;
371  //-------------------------------------------------------
372  // fill lists for reference and others
373  for(UInt_t i=0; i < n; i++){
374  cand1 = HCategoryManager::getObject(cand1,candCat,i);
375 
376  //-------------------------------------------------------
377  // book the hits -> candiate lists
378  bookHits(cand1);
379  //-------------------------------------------------------
380 
381  if(cand1){
382 
383  if(fuserFilter && !(*fuserFilter)(cand1)) continue;
384 
385 
386  if(( fuse_kIsLepton && cand1->isFlagBit(Particle::kIsLepton)) ||
388  ){
389  freference.push_back(cand1);
390  } else {
391  fothers.push_back(cand1);
392  }
393  }
394  } // end fill list loop
395  //-------------------------------------------------------
396 
397 
398  //-------------------------------------------------------
399  // create pair combinations
400  Int_t pid1,pid2;
401  pid1 = pid2 = -10;
402 
403  //-------------------------------------------------------
404  // first do good pairs from reference x reference candidates
405 
406  n = freference.size();
407  if(n > 1){
408  for(UInt_t i = 0 ; i < n ; i++){
409  cand1 = freference[i];
410  pid1 = -10;
411 
412  selectPID(cand1,pid1,kTRUE);
413 
414  for(UInt_t j = i+1 ; j < n; j++){
415  cand2 = freference[j];
416  if(cand2->getRichInd()!=-1) richCandCt++;
417  UInt_t flag = 0;
418  HParticleTool::setPairFlags(flag,cand2,cand1);
419 
420  if(!fuse_kIsLepton) flag=flag|kNoUseRICH;
421 
422  pid2 = -10;
423 
424  selectPID(cand2,pid2,kTRUE);
425 
426  HParticlePair pair;
427  pair.setPair(cand1,pid1,cand2,pid2,fMotherPID,flag,fVertex);
428  fpairs.push_back(pair);
429 
430  } // end loop others
431  } // end loop reference x reference
432  }
433  //-------------------------------------------------------
434 
435  //-------------------------------------------------------
436  // now do all pairs reference x other candidates
437  for(UInt_t i = 0 ; i < freference.size(); i++){
438  cand1 = freference[i];
439  pid1 = -10;
440 
441  selectPID(cand1,pid1,kTRUE);
442 
443  for(UInt_t j = 0 ; j < fothers.size(); j++){
444  cand2 = fothers[j];
445  if(cand2->getRichInd()!=-1) richCandCt++;
446  UInt_t flag = 0;
447  HParticleTool::setPairFlags(flag,cand2,cand1);
448 
449  if(!fuse_kIsLepton) flag=flag|kNoUseRICH;
450 
451  pid2 = -10;
452  if( pid1 == fPID2 && (*fselectPID1)(cand2) ) { pid2 = fPID1;} // PID2 could fail no polarity is defined
453  else if ( pid1 == fPID1 && (*fselectPID2)(cand2) ) { pid2 = fPID2;}
454 
455  if(pid2 == -10){
456 
457  if((flag&kNoOuterMDC2) == kNoOuterMDC2) {
458  // in this case polarity is not defined
459  // selectPID will fail, but we want to set
460  // pid2 in this case
461 
462  if(pid1 == fPID1) pid2 = fPID2;
463  else pid2 = fPID1;
464  }
465  }
466 
467  if(pid2 == -10) { // all cases with no RICH
468  if(cand2->getCharge() != 0){
469  if(cand2->getCharge() > 0) pid2 = HPhysicsConstants::pid("fake+");
470  else pid2 = HPhysicsConstants::pid("fake-");
471  } else {
472  if(HPhysicsConstants::charge(pid1) < 0 ) pid2 = HPhysicsConstants::pid("fake+");
473  else pid2 = HPhysicsConstants::pid("fake-");
474  }
475 
476  }
477 
478  HParticlePair pair;
479  pair.setPair(cand1,pid1,cand2,pid2,fMotherPID,flag,fVertex);
480  fpairs.push_back(pair);
481  //#define dbug
482 #ifdef dbug
483  Int_t ct = 0 ;
484  for(UInt_t k = 0; k < fCaseVec.size(); k ++){ // fill statistics for pair cases
485  if(HParticleTool::evalPairsFlags(fCaseVec[k],pair) || cand2->getRichInd()==-1) {
486  good2=kTRUE;
487  if(cand2->getRichInd()!=-1) ct++;
488  }
489  }
490  if(!good2 || ct>1) pair.print();
491 #endif
492  } // end loop others
493  } // end loop reference
494  //-------------------------------------------------------
495 
496 
497 
498 
500  {
501 
502  //-------------------------------------------------------
503  // now do all pairs full reco of others x no full reco other candidates and fullreco others X full reco others
504  for(UInt_t j = 0 ; j < fothers.size(); j++){
505  HParticleCand* c = fothers[j];
506  if(c->isFlagAND(4, // Fully reconstructed
511  ffullrecoOthers.push_back(c);
512  } else {
513  fnofullrecoOthers.push_back(c);
514  }
515  }
516 
517  //-------------------------------------------------------
518  //fullreco others X full reco others
519  for(UInt_t i = 0 ; i < ffullrecoOthers.size(); i++){
520  cand1 = ffullrecoOthers[i];
521  pid1 = -10;
522 
523  selectPID(cand1,pid1,kTRUE);
524 
525  for(UInt_t j = i+1 ; j < ffullrecoOthers.size(); j++){
526  cand2 = ffullrecoOthers[j];
527  UInt_t flag = 0;
528  HParticleTool::setPairFlags(flag,cand2,cand1);
529 
530  if(!fuse_kIsLepton) flag=flag|kNoUseRICH;
531 
532  pid2 = -10;
533  if( pid1 == fPID2 && (*fselectPID1)(cand2) ) { pid2 = fPID1;} // PID2 could fail no polarity is defined
534  else if ( pid1 == fPID1 && (*fselectPID2)(cand2) ) { pid2 = fPID2;}
535 
536  if(pid2 == -10){
537 
538  if((flag&kNoOuterMDC2) == kNoOuterMDC2) {
539  // in this case polarity is not defined
540  // selectPID will fail, but we want to set
541  // pid2 in this case
542 
543  if(pid1 == fPID1) pid2 = fPID2;
544  else pid2 = fPID1;
545  }
546  }
547 
548  if(pid2 == -10) { // all cases with no RICH
549  if(cand2->getCharge() != 0){
550  if(cand2->getCharge() > 0) pid2 = HPhysicsConstants::pid("fake+");
551  else pid2 = HPhysicsConstants::pid("fake-");
552  } else {
553  if(HPhysicsConstants::charge(pid1) < 0 ) pid2 = HPhysicsConstants::pid("fake+");
554  else pid2 = HPhysicsConstants::pid("fake-");
555  }
556 
557  }
558 
559  HParticlePair pair;
560  pair.setPair(cand1,pid1,cand2,pid2,fMotherPID,flag,fVertex);
561  fpairs.push_back(pair);
562 
563  } // end loop fullreco
564  } // end loop fullreco
565  //-------------------------------------------------------
566 
567  //-------------------------------------------------------
568  //fullreco others X no full reco others
569  for(UInt_t i = 0 ; i < ffullrecoOthers.size(); i++){
570  cand1 = ffullrecoOthers[i];
571  pid1 = -10;
572 
573  selectPID(cand1,pid1,kTRUE);
574 
575  for(UInt_t j = 0 ; j < fnofullrecoOthers.size(); j++){
576  cand2 = fnofullrecoOthers[j];
577  UInt_t flag = 0;
578  HParticleTool::setPairFlags(flag,cand2,cand1);
579 
580  if(!fuse_kIsLepton) flag=flag|kNoUseRICH;
581 
582  pid2 = -10;
583  if( pid1 == fPID2 && (*fselectPID1)(cand2) ) { pid2 = fPID1;} // PID2 could fail no polarity is defined
584  else if ( pid1 == fPID1 && (*fselectPID2)(cand2) ) { pid2 = fPID2;}
585 
586  if(pid2 == -10){
587 
588  if((flag&kNoOuterMDC2) == kNoOuterMDC2) {
589  // in this case polarity is not defined
590  // selectPID will fail, but we want to set
591  // pid2 in this case
592 
593  if(pid1 == fPID1) pid2 = fPID2;
594  else pid2 = fPID1;
595  }
596  }
597 
598  if(pid2 == -10) { // all cases with no RICH
599  if(cand2->getCharge() != 0){
600  if(cand2->getCharge() > 0) pid2 = HPhysicsConstants::pid("fake+");
601  else pid2 = HPhysicsConstants::pid("fake-");
602  } else {
603  if(HPhysicsConstants::charge(pid1) < 0 ) pid2 = HPhysicsConstants::pid("fake+");
604  else pid2 = HPhysicsConstants::pid("fake-");
605  }
606 
607  }
608 
609  HParticlePair pair;
610  pair.setPair(cand1,pid1,cand2,pid2,fMotherPID,flag,fVertex);
611  fpairs.push_back(pair);
612 
613  } // end loop fullnoreco
614  } // end loop fullreco
615  //-------------------------------------------------------
616 
617  } // end fdoSkippedFullCandPairs
618 
619 
620  //-------------------------------------------------------
621  // book the candidate -> pair lists
622  for(UInt_t i = 0; i < fpairs.size(); i++){
623  HParticlePair* pair = &(fpairs[i]);
624  cand1 = dynamic_cast<HParticleCand*>(pair->getCand(0));
625  cand2 = dynamic_cast<HParticleCand*>(pair->getCand(1));
626 
627 
628  //-------------------------------------------------------
629  // fill statistics for pair cases
630  for(UInt_t k = 0; k < fCaseVec.size(); k ++){
632  fCaseCt[k]++;
633  }
634  }
635  //-------------------------------------------------------
636 
637 
638  if(mCandtoPair.find(cand1) == mCandtoPair.end()){
639  vector<HParticlePair*> pairs;
640  pairs.push_back(pair);
641  mCandtoPair[cand1] = pairs;
642  } else {
643  mCandtoPair[cand1].push_back(pair);
644  }
645  if(mCandtoPair.find(cand2) == mCandtoPair.end()){
646  vector<HParticlePair*> pairs;
647  pairs.push_back(pair);
648  mCandtoPair[cand2] = pairs;
649  } else {
650  mCandtoPair[cand2].push_back(pair);
651  }
652  }
653  //-------------------------------------------------------
654 
655  }
656 
657  }
658 }
659 
661 {
662  // clear all internal vectors etc
663  freference .clear();
664  fothers .clear();
665  fpairs .clear();
666  ffullrecoOthers.clear();
667  fnofullrecoOthers.clear();
668 
669  mTofHittoCand .clear();
670  mTofClsttoCand .clear();
671  mRpcClsttoCand .clear();
672  mShowertoCand .clear();
673  mEmctoCand .clear();
674  mInnerMdctoCand.clear();
675  mOuterMdctoCand.clear();
676  mRichtoCand .clear();
677  mCandtoPair .clear();
678 }
679 
680 void HParticlePairMaker::filterPairsVector(vector<HParticlePair*>& filterpairs,UInt_t flag)
681 {
682  // fill all pairs which fullfill the flag to filterspairs.
683  // filterpairs will be cleared automatically before filling.
684  filterpairs.clear();
685  for(UInt_t i = 0; i < fpairs.size(); i++){
686  HParticlePair& pair = fpairs[i];
687  if(HParticleTool::evalPairsFlags(flag,pair)){
688  filterpairs.push_back(&pair);
689  }
690  }
691 }
692 void HParticlePairMaker::filterPairsVector(vector<HParticlePair*>& filterpairs,vector<UInt_t>& flags)
693 {
694  // fill all pairs which fullfill the flags to filterspairs.
695  // filterpairs will be cleared automatically before filling.
696  filterpairs.clear();
697  for(UInt_t i = 0; i < fpairs.size(); i++){
698  HParticlePair& pair = fpairs[i];
699  if(HParticleTool::evalPairsFlags(flags,pair)){
700  filterpairs.push_back(&pair);
701  }
702  }
703 }
704 
705 Int_t HParticlePairMaker::filterCandidates(HVirtualCand* cand,vector<HVirtualCand*>& candidates,UInt_t flag,Float_t oAngle)
706 {
707  // vector candidates with all candidates which have been combined into pairs.
708  // if flag == 0 no filtering will be done. Filtering takes place on pairs.
709  // Flag can be used to filter for candidates which share 1 or more detector
710  // hits with the candidate (see flags eClosePairSelect+ ePairCase (hparticledef.h)).
711  // In addition a filter of opening Angle of the track can be applied (oAngle < 0 does no selection)
712  // The function returns the number of found candidates or -1 if the candidate
713  // has not been found at all (should not happen).
714 
715  candidates.clear();
716 
717  map<HVirtualCand*,vector<HParticlePair*> >::iterator it = mCandtoPair.find(cand);
718  if(it != mCandtoPair.end()){
719  vector<HParticlePair*>& v = it->second;
720 
721  for(UInt_t i = 0 ; i < v.size(); i++){
722  HParticlePair& pair = *(v[i]);
723  if(HParticleTool::evalPairsFlags(flag,pair) && (oAngle < 0 || pair.getOpeningAngle() < oAngle )){
724 
725  if(pair.getCand(0) == cand) candidates.push_back(pair.getCand(1));
726  else candidates.push_back(pair.getCand(0));
727  }
728  }
729 
730  return candidates.size();
731  }
732  return -1;
733 }
734 
735 Int_t HParticlePairMaker::filterCandidates (HVirtualCand* cand,vector<HParticlePair*>& filterpairs,UInt_t flag,Float_t oAngle)
736 {
737  // Fills vector filterpairs with all pairs which share cand.
738  // if flag == 0 no filtering will be done. Filtering takes place on pairs.
739  // Flag can be used to filter for candidates which share 1 or more detector
740  // hits with the candidate (see flags eClosePairSelect+ ePairCase (hparticledef.h)).
741  // In addition a filter of opening Angle of the track can be applied (oAngle < 0 does no selection)
742  // The function returns the number of found pairs or -1 if the candidate
743  // has not been found at all (should not happen).
744 
745  filterpairs.clear();
746  map<HVirtualCand*,vector<HParticlePair*> >::iterator it = mCandtoPair.find(cand);
747  if(it != mCandtoPair.end()){
748  vector<HParticlePair*>& v = it->second;
749  for(UInt_t i = 0 ; i < v.size(); i++){
750 
751  if(HParticleTool::evalPairsFlags(flag,*(v[i])) && ( oAngle < 0 || v[i]->getOpeningAngle() < oAngle) ){
752  filterpairs.push_back(v[i]);
753  }
754  }
755 
756  } else return -1;
757 
758  return filterpairs.size();
759 
760 }
761 
762 
763 Int_t HParticlePairMaker::getSameRich(HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag,Bool_t isReference)
764 {
765  // fills list of candidates which share the same RICH. If the RICH is not found
766  // at all -1 is returned, other wise the number of candidates found for the hit.
767  // The input candidate will be not included in candidates. Candidates can be filtered
768  // by flag ( 0 == no filter, see flags eClosePairSelect+ ePairCase (hparticledef.h)).
769  // The input candidate will be treated as refererence if isReference == kTRUE.
770 
771  candidates.clear();
772  if(cand->getRichInd() !=-1 ){
773  map<Int_t,vector<HParticleCand*> >::iterator it = mRichtoCand.find(cand->getRichInd());
774  if(it != mRichtoCand.end()){
775  vector<HParticleCand*>& v = it->second;
776  for(UInt_t i = 0 ; i < v.size(); i++){
777 
778  if(v[i] != cand) { // skip same cand
779  if(flag == 0 ) candidates.push_back(v[i]);
780  else {
781  Bool_t fl = kFALSE;
782  if(!isReference) fl=HParticleTool::evalPairsFlags(fl,cand,v[i]);
783  else fl=HParticleTool::evalPairsFlags(fl,v[i],cand);
784  if(fl){
785  candidates.push_back(v[i]);
786  }
787  }
788  }
789  } //end loop
790  } else return -1;
791  }
792  return candidates.size();
793 }
794 
795 Int_t HParticlePairMaker::getSameInnerMdc(HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag,Bool_t isReference)
796 {
797  // fills list of candidates which share the same inner MDC seg. If the seg is not found
798  // at all -1 is returned, other wise the number of candidates found for the hit.
799  // The input candidate will be not included in candidates. Candidates can be filtered
800  // by flag ( 0 == no filter, see flags eClosePairSelect+ ePairCase (hparticledef.h)).
801  // The input candidate will be treated as refererence if isReference == kTRUE.
802 
803  candidates.clear();
804  if(cand->getInnerSegInd() !=-1 ){
805  map<Int_t,vector<HParticleCand*> >::iterator it = mInnerMdctoCand.find(cand->getInnerSegInd());
806  if(it != mInnerMdctoCand.end()){
807  vector<HParticleCand*>& v = it->second;
808  for(UInt_t i = 0 ; i < v.size(); i++){
809 
810  if(v[i] != cand) { // skip same cand
811  if(flag == 0 ) candidates.push_back(v[i]);
812  else {
813  Bool_t fl = kFALSE;
814  if(!isReference) fl=HParticleTool::evalPairsFlags(fl,cand,v[i]);
815  else fl=HParticleTool::evalPairsFlags(fl,v[i],cand);
816  if(fl){
817  candidates.push_back(v[i]);
818  }
819  }
820  }
821  } //end loop
822  } else return -1;
823  }
824  return candidates.size();
825 }
826 
827 Int_t HParticlePairMaker::getSameOuterMdc(HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag,Bool_t isReference)
828 {
829  // fills list of candidates which share the same outer MDC seg. If the seg is not found
830  // at all -1 is returned, other wise the number of candidates found for the hit.
831  // The input candidate will be not included in candidates. Candidates can be filtered
832  // by flag ( 0 == no filter, see flags eClosePairSelect+ ePairCase (hparticledef.h)).
833  // The input candidate will be treated as refererence if isReference == kTRUE.
834 
835  candidates.clear();
836  if(cand->getOuterSegInd() !=-1 ){
837  map<Int_t,vector<HParticleCand*> >::iterator it = mOuterMdctoCand.find(cand->getOuterSegInd());
838  if(it != mOuterMdctoCand.end()){
839  vector<HParticleCand*>& v = it->second;
840  for(UInt_t i = 0 ; i < v.size(); i++){
841 
842  if(v[i] != cand) { // skip same cand
843  if(flag == 0 ) candidates.push_back(v[i]);
844  else {
845  Bool_t fl = kFALSE;
846  if(!isReference) fl=HParticleTool::evalPairsFlags(fl,cand,v[i]);
847  else fl=HParticleTool::evalPairsFlags(fl,v[i],cand);
848  if(fl){
849  candidates.push_back(v[i]);
850  }
851  }
852  }
853  } //end loop
854  } else return -1;
855  }
856  return candidates.size();
857 }
858 
859 Int_t HParticlePairMaker::getSameMeta(HParticleCand* cand,vector<HParticleCand*>& candidates,UInt_t flag,Bool_t isReference)
860 {
861  // fills list of candidates which share the same META hit. The number of candidates
862  // found for the hit is returned or -1 if the hit is not found at all..
863  // The input candidate will be not included in candidates. Candidates can be filtered
864  // by flag ( 0 == no filter, see flags eClosePairSelect+ ePairCase (hparticledef.h)).
865  // The input candidate will be treated as refererence if isReference == kTRUE.
866 
867  candidates.clear();
868 
869  Int_t metaind = cand->getMetaHitInd();
870  Int_t sel = cand->getSelectedMeta();
871 
872  if(metaind != -1 ){
873  map<Int_t,vector<HParticleCand*> >* mp =0;
874 
875  if (sel == kTofClst) mp = &mTofClsttoCand;
876  else if(sel == kTofHit1||sel==kTofHit2) mp = &mTofHittoCand;
877  else if(sel == kRpcClst) mp = &mRpcClsttoCand;
878  else if(sel == kShowerHit) mp = &mShowertoCand;
879  else if(sel == kEmcClst) mp = &mEmctoCand;
880  else {
881  Error("getSameMeta()","unknown Meta case!"); return 0;
882  }
883  map<Int_t,vector<HParticleCand*> >::iterator it = mp->find(metaind);
884 
885  if(it != mp->end()){
886  vector<HParticleCand*>& v = it->second;
887  for(UInt_t i = 0 ; i < v.size(); i++){
888 
889  if(v[i] != cand) { // skip same cand
890  if(flag == 0 ) candidates.push_back(v[i]);
891  else {
892  Bool_t fl = kFALSE;
893  if(!isReference) fl=HParticleTool::evalPairsFlags(fl,cand,v[i]);
894  else fl=HParticleTool::evalPairsFlags(fl,v[i],cand);
895  if(fl){
896  candidates.push_back(v[i]);
897  }
898  }
899  }
900  } //end loop
901  } else return -1;
902  }
903  return candidates.size();
904 }
905 
907 {
908  // draws the fraction of pair cases for
909  // the default pairCases1...12.
910 
911  TCanvas* c = new TCanvas("pairCase","pairCase",1500,800);
912  c->SetGridx();
913  c->SetGridy();
914  c->SetBottomMargin(0.15);
915 
916  UInt_t bins = fCaseVec.size();
917 
918  TH1F* h = new TH1F("h","",bins,0,bins);
919  h->SetLineColor(kRed);
920  h->SetLineWidth(3);
921  h->SetYTitle("Fraction of pairs [%]");
922  h->GetXaxis()->SetNdivisions(100+bins);
923  h->GetXaxis()->SetLabelSize(0);
924 
925  h->GetYaxis()->SetRangeUser(0.,50.);
926  Float_t sum = 0;
927  for(UInt_t i=0;i<bins;i++) sum+=fCaseCt[i];
928 
929  cout<<"Pairs Cases for Leptons :"<<endl;
930  for(UInt_t i=0;i<bins;i++){
931  Float_t frac = 0;
932  if(sum != 0) frac = (fCaseCt[i]/sum)*100.;
933  if(sum !=0 ) h->Fill(i,frac);
934  cout<<Form("case%2i : ",i+1)<<setw(15)<< frac << " cts "<<setw(15)<<fCaseCt[i]<<endl;
935 
936  }
937  h->Draw();
938 
939  Double_t offsetX = 0.25;
940  Double_t offsetY = -8;
941  Double_t scaleX = 1.;
942  Double_t scaleY = 1.;
943 
944  HParticlePairDraw pairdraw;
945 
946  for(UInt_t i=0; i < bins; i++){
947  pairdraw.drawPair(offsetX+i,offsetY,scaleX,scaleY,fCaseVec[i],Form("Case%i",i+1),"");
948  }
949  cout<<"sum "<<sum<< " check " <<richCandCt<<endl;
950 }
951 
void drawPair(Double_t xoff, Double_t yoff, Double_t scx, Double_t scy, UInt_t flag, TString nameCase, TString cuts="")
static Int_t charge(const Int_t id)
Bool_t isShowerUsed() const
void selectPID(HParticleCand *cand1, Int_t &pid1, Bool_t warn=kTRUE)
Short_t getCharge() const
Definition: hvirtualcand.h:58
Bool_t isTofHitUsed() const
vector< UInt_t > fCaseCt
void filterPairsVector(vector< HParticlePair * > &filterpairs, UInt_t flag=0)
Bool_t isFlagBit(eFlagBits bit)
Int_t getInnerSegInd() const
Int_t fPID1
user filter function to avoid unneeded combinatorics
Float_t getOpeningAngle()
Definition: hparticlepair.h:56
Int_t fVertexCase
ask for rich index in selctPos/selectNeg function
vector< HParticleCand * > ffullrecoOthers
other candidates (not KIsLepton flagged)
virtual void print(UInt_t selection=31)
HEvent *& getCurrentEvent(void)
Definition: hades.cc:422
map< Int_t, vector< HParticleCand * > > mInnerMdctoCand
EMC Cluster lookup detector hit ind -> list of candidates using this hit.
vector< HParticlePair > fpairs
not full reco cands (inner/outer MDC or META missing) inside others
Int_t n
void clearVectors()
counter for all pair cases with both candidates matching a Rich (check)
ClassImp(HDbColumn) HDbColumn
Definition: hdbcolumn.cc:18
static HGeomVector getGlobalVertex(Int_t v, Bool_t warn=kFALSE)
static Bool_t setPairFlags(UInt_t &flag, HParticleCand *cand2=0, HParticleCand *cand1=0)
map< Int_t, vector< HParticleCand * > > mShowertoCand
RPC cluster lookup detector hit ind -> list of candidates using this hit.
Bool_t setPair(HVirtualCand *cnd1, Int_t pid1, HVirtualCand *cnd2, Int_t pid2, Int_t motherpid, UInt_t pairflags, HGeomVector &vertex)
static T * getObject(T *pout, Short_t num=-1, Int_t index=-1, Bool_t silent=kFALSE)
map< Int_t, vector< HParticleCand * > > mRpcClsttoCand
TOF cluster lookup detector hit ind -> list of candidates using this hit.
HGeomVector fVertex
which eventvertex to use (see eVertex in hparticledef.h)
map< HVirtualCand *, vector< HParticlePair * > > mCandtoPair
RICH hit lookup detector hit ind -> list of candidates using this hit.
Int_t filterCandidates(HVirtualCand *cand, vector< HVirtualCand * > &candidates, UInt_t flag=0, Float_t oAngle=-1)
Int_t fMotherPID
pid2 (default electrons)
static Bool_t getRequireRich()
Double_t sum
Int_t getSameMeta(HParticleCand *cand, vector< HParticleCand * > &candidates, UInt_t flag=0, Bool_t isReference=kTRUE)
Int_t getRichInd() const
Int_t getSelectedMeta() const
map< Int_t, vector< HParticleCand * > > mRichtoCand
outer Seg lookup detector hit ind -> list of candidates using this hit
Int_t getOuterSegInd() const
static Bool_t selectNeg(HParticleCand *)
Hades * gHades
Definition: hades.cc:1213
Int_t getSameOuterMdc(HParticleCand *cand, vector< HParticleCand * > &candidates, UInt_t flag=0, Bool_t isReference=kTRUE)
Int_t richCandCt
vector for pair cases
void bookHits(HParticleCand *cand1)
Int_t getSameRich(HParticleCand *cand, vector< HParticleCand * > &candidates, UInt_t flag=0, Bool_t isReference=kTRUE)
Bool_t(* fselectPID1)(HParticleCand *)
candidate lookup candidate -> list of pairs using this candidate
Bool_t isEmcUsed() const
map< Int_t, vector< HParticleCand * > > mEmctoCand
SHOWER hit lookup detector hit ind -> list of candidates using this hit.
Bool_t(* fselectPID2)(HParticleCand *)
selection function pid1 (default positrons)
HVirtualCand * getCand(Int_t ind)
Definition: hparticlepair.h:51
Bool_t(* fuserFilter)(HParticleCand *)
selection function pid2 (default electrons)
map< Int_t, vector< HParticleCand * > > mTofClsttoCand
TOF hit lookup detector hit ind -> list of candidates using this hit.
Short_t getSystemUsed() const
Bool_t isTofClstUsed() const
Bool_t isRpcClstUsed() const
void print(UInt_t selection=63)
static Int_t pid(const Char_t *pidName)
Int_t fPID2
pid1 (default positrons)
vector< HParticleCand * > fothers
reference candidates (kIsLepton flagged)
Bool_t fdoSkippedFullCandPairs
== kTRUE use kIsLepton as refererence selection (default)
Int_t getSameInnerMdc(HParticleCand *cand, vector< HParticleCand * > &candidates, UInt_t flag=0, Bool_t isReference=kTRUE)
Int_t getMetaHitInd() const
vector< HParticleCand * > freference
map< Int_t, vector< HParticleCand * > > mOuterMdctoCand
inner Seg lookup detector hit ind -> list of candidates using this hit
map< Int_t, vector< HParticleCand * > > mTofHittoCand
all pair combinations freference x fothers
vector< HParticleCand * > fnofullrecoOthers
full reco cands (inner/outer MDC + META) inside others
Bool_t fuse_kIsLepton
default dilepton
vector< UInt_t > fCaseVec
counter array for cases
static Bool_t evalPairsFlags(UInt_t flag, UInt_t fl)
static Bool_t selectPos(HParticleCand *)
const Cat_t catParticleCand
Definition: hparticledef.h:9
Bool_t isFlagAND(Int_t num,...)