CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFBlockAlgo.cc
Go to the documentation of this file.
7 
9 
10 #include <stdexcept>
11 #include "TMath.h"
12 
13 using namespace std;
14 using namespace reco;
15 
16 //for debug only
17 //#define PFLOW_DEBUG
18 
20 
22  blocks_( new reco::PFBlockCollection ),
23  DPtovPtCut_(std::vector<double>(4,static_cast<double>(999.))),
24  NHitCut_(std::vector<unsigned int>(4,static_cast<unsigned>(0))),
25  useIterTracking_(true),
26  photonSelector_(0),
27  debug_(false) {}
28 
29 
30 
31 void PFBlockAlgo::setParameters( std::vector<double>& DPtovPtCut,
32  std::vector<unsigned int>& NHitCut,
33  bool useConvBremPFRecTracks,
34  bool useIterTracking,
35  int nuclearInteractionsPurity,
36  bool useEGPhotons,
37  std::vector<double>& photonSelectionCuts,
38  bool useSuperClusters,
39  bool superClusterMatchByRef
40  ) {
41 
42  DPtovPtCut_ = DPtovPtCut;
43  NHitCut_ = NHitCut;
44  useIterTracking_ = useIterTracking;
45  useConvBremPFRecTracks_ = useConvBremPFRecTracks;
46  nuclearInteractionsPurity_ = nuclearInteractionsPurity;
47  useEGPhotons_ = useEGPhotons;
48  // Pt cut; Track iso (constant + slope), Ecal iso (constant + slope), HCAL iso (constant+slope), H/E
49  if(useEGPhotons_)
50  photonSelector_ = new PhotonSelectorAlgo(photonSelectionCuts[0],
51  photonSelectionCuts[1], photonSelectionCuts[2],
52  photonSelectionCuts[3], photonSelectionCuts[4],
53  photonSelectionCuts[5], photonSelectionCuts[6],
54  photonSelectionCuts[7],
55  photonSelectionCuts[8],
56  photonSelectionCuts[9],
57  photonSelectionCuts[10]
58  );
59 
60 
61  useSuperClusters_ = useSuperClusters;
62  superClusterMatchByRef_ = superClusterMatchByRef;
63 }
64 
65 // Glowinski & Gouzevitch
66 void PFBlockAlgo::setUseOptimization(bool useKDTreeTrackEcalLinker)
67 {
68  useKDTreeTrackEcalLinker_ = useKDTreeTrackEcalLinker;
69 }
70 // !Glowinski & Gouzevitch
71 
72 
74 
75 #ifdef PFLOW_DEBUG
76  if(debug_)
77  cout<<"~PFBlockAlgo - number of remaining elements: "
78  <<elements_.size()<<endl;
79 #endif
80 
82 
83 }
84 
85 void
87 
88  // Glowinski & Gouzevitch
93  }
94  // !Glowinski & Gouzevitch
95 
96  // the blocks have not been passed to the event, and need to be cleared
97  if(blocks_.get() )blocks_->clear();
98  else
99  blocks_.reset( new reco::PFBlockCollection );
100 
101  blocks_->reserve(elements_.size());
102  for(IE ie = elements_.begin();
103  ie != elements_.end();) {
104 
105 #ifdef PFLOW_DEBUG
106  if(debug_) {
107  cout<<" PFBlockAlgo::findBlocks() ----------------------"<<endl;
108  cout<<" element "<<**ie<<endl;
109  cout<<" creating new block"<<endl;
110  }
111 #endif
112 
113  blocks_->push_back( PFBlock() );
114 
115  vector< PFBlockLink > links;
116 
117  // list< IE > used;
118  ie = associate( elements_.end() , ie, links );
119 
120  packLinks( blocks_->back(), links );
121  }
122 }
123 
124 
125 
126 
129  IE next,
130  vector<PFBlockLink>& links ) {
131 
132 
133 #ifdef PFLOW_DEBUG
134  if(debug_ ) cout<<"PFBlockAlgo::associate start ----"<<endl;
135 #endif
136 
137  if( last!= elements_.end() ) {
139  double dist = -1;
140  PFBlock::LinkTest linktest = PFBlock::LINKTEST_RECHIT;
141  link( *last, *next, linktype, linktest, dist );
142 
143 
144  if(dist<-0.5) {
145 #ifdef PFLOW_DEBUG
146  if(debug_ ) cout<<"link failed"<<endl;
147 #endif
148  return ++next; // association failed
149  }
150  else {
151  // add next element to the current pflowblock
152  blocks_->back().addElement( *next );
153 
154  // (*next)->setIndex( blocks_->back()->indexToLastElement() );
155 
156  // this is not necessary?
157  // next->setPFBlock(this);
158 
159  // create a link between next and last
160  links.push_back( PFBlockLink(linktype,
161  linktest,
162  dist,
163  (*last)->index(),
164  (*next)->index() ) );
165  // not necessary ?
166  // next->connect( links_.size()-1 );
167  // last->connect( links_.size()-1 );
168  }
169  }
170  else {
171  // add next element to this eflowblock
172 #ifdef PFLOW_DEBUG
173  if(debug_ ) cout<<"adding to block element "<<(**next)<<endl;
174 #endif
175  blocks_->back().addElement( *next );
176  // (*next)->setIndex( blocks_->back()->indexToLastElement() );
177  // next->setPFBlock(this);
178  }
179 
180  // recursive call: associate next and other unused elements
181 
182  // IE afterNext = next;
183  // ++afterNext;
184  // cout<<"last "<<**last<<" next "<<**next<<endl;
185 
186  for(IE ie = elements_.begin();
187  ie != elements_.end();) {
188 
189  if( ie == last || ie == next ) {
190  ++ie;
191  continue;
192  }
193  bool bTestLink = linkPrefilter(*next, *ie);
194 
195  if(!bTestLink) {
196  ++ie;
197  continue;
198  }
199 
200  // *ie already included to a block
201  if( (*ie)->locked() ) {
202 #ifdef PFLOW_DEBUG
203  if(debug_ ) cout<<"element "<<(**ie)<<"already used"<<endl;
204 #endif
205  ++ie;
206  continue;
207  }
208 
209 
210 #ifdef PFLOW_DEBUG
211  if(debug_ ) cout<<"calling associate "<<(**next)<<" & "<<(**ie)<<endl;
212 #endif
213  ie = associate(next, ie, links);
214  }
215 
216 #ifdef PFLOW_DEBUG
217  if(debug_ ) {
218  cout<<"**** deleting element "<<endl;
219  cout<<**next<<endl;
220  }
221 #endif
222  delete *next;
223 
224 #ifdef PFLOW_DEBUG
225  if(debug_ ) {
226  cout<<"**** removing element "<<endl;
227  }
228 #endif
229 
230  IE iteratorToNextFreeElement = elements_.erase( next );
231 
232 #ifdef PFLOW_DEBUG
233  if(debug_ ) cout<<"PFBlockAlgo::associate stop ----"<<endl;
234 #endif
235 
236  return iteratorToNextFreeElement;
237 }
238 
239 
240 
241 void
243  const vector<PFBlockLink>& links ) const {
244 
245 
247 
248  block.bookLinkData();
249  unsigned elsize = els.size();
250  unsigned ilStart = 0;
251  //First Loop: update all link data
252  for( unsigned i1=0; i1<elsize; ++i1 ) {
253  for( unsigned i2=0; i2<i1; ++i2 ) {
254 
255  // no reflexive link
256  //if( i1==i2 ) continue;
257 
258  double dist = -1;
259 
260  bool linked = false;
261  PFBlock::LinkTest linktest
262  = PFBlock::LINKTEST_RECHIT;
263 
264  // are these elements already linked ?
265  // this can be optimized
266  unsigned linksize = links.size();
267  for( unsigned il = ilStart; il<linksize; ++il ) {
268  // The following three lines exploits the increasing-element2 ordering of links.
269  if ( links[il].element2() < i1 ) ilStart = il;
270  if ( links[il].element2() > i1 ) break;
271  if( (links[il].element1() == i2 &&
272  links[il].element2() == i1) ) { // yes
273 
274  dist = links[il].dist();
275  linked = true;
276 
277  //modif-beg
278  //retrieve type of test used to get distance
279  linktest = links[il].test();
280 #ifdef PFLOW_DEBUG
281  if( debug_ )
282  cout << "Reading link vector: linktest used="
283  << linktest
284  << " distance = " << dist
285  << endl;
286 #endif
287  //modif-end
288 
289  break;
290  }
291  }
292 
293  if(!linked) {
295  bool bTestLink = linkPrefilter(&els[i1], &els[i2]);
296  if (bTestLink) link( & els[i1], & els[i2], linktype, linktest, dist);
297  }
298 
299  //loading link data according to link test used: RECHIT
300  //block.setLink( i1, i2, chi2, block.linkData() );
301 #ifdef PFLOW_DEBUG
302  if( debug_ )
303  cout << "Setting link between elements " << i1 << " and " << i2
304  << " of dist =" << dist << " computed from link test "
305  << linktest << endl;
306 #endif
307  block.setLink( i1, i2, dist, block.linkData(), linktest );
308  }
309  }
310 
311 }
312 
313 
314 
315 void
317  // loop on all blocks and create a big graph
318 }
319 
320 
321 
322 void
324  const reco::PFBlockElement* el2,
325  PFBlockLink::Type& linktype,
326  reco::PFBlock::LinkTest& linktest,
327  double& dist) const {
328 
329  // ACHTUNG!!!! If you introduce new links check that they are not desabled in linkPrefilter!!!!
330 
331 
332  dist=-1.;
333  linktest = PFBlock::LINKTEST_RECHIT; //rechit by default
334 
335  PFBlockElement::Type type1 = el1->type();
336  PFBlockElement::Type type2 = el2->type();
337 
338  linktype = static_cast<PFBlockLink::Type>
339  ((1<< (type1-1) ) | (1<< (type2-1) ));
340 
341  if(debug_ ) std::cout << " PFBlockAlgo links type1 " << type1 << " type2 " << type2 << std::endl;
342 
343  const PFBlockElement* lowEl = el1;
344  const PFBlockElement* highEl = el2;
345 
346  if(type1>type2) {
347  lowEl = el2;
348  highEl = el1;
349  }
350 
351  switch(linktype) {
352  // Track and preshower cluster links are not used for now - disable
355  {
356  // if(debug_ ) cout<< "PSandECAL" <<endl;
357  PFClusterRef psref = lowEl->clusterRef();
358  PFClusterRef ecalref = highEl->clusterRef();
359  assert( !psref.isNull() );
360  assert( !ecalref.isNull() );
361 
362  // Check if the linking has been done using the KDTree algo
363  // Glowinski & Gouzevitch
364  if ( useKDTreeTrackEcalLinker_ && lowEl->isMultilinksValide() ) { // KDTree algo
365  const reco::PFMultilinksType& multilinks = lowEl->getMultilinks();
366 
367  double ecalPhi = ecalref->positionREP().Phi();
368  double ecalEta = ecalref->positionREP().Eta();
369 
370  // Check if the link PS/Ecal exist
371  reco::PFMultilinksType::const_iterator mlit = multilinks.begin();
372  for (; mlit != multilinks.end(); ++mlit)
373  if ((mlit->first == ecalPhi) && (mlit->second == ecalEta))
374  break;
375 
376  // If the link exist, we fill dist and linktest. We use old algorithme method.
377  if (mlit != multilinks.end()){
378  double xPS = psref->position().X();
379  double yPS = psref->position().Y();
380  double xECAL = ecalref->position().X();
381  double yECAL = ecalref->position().Y();
382 
383  dist = LinkByRecHit::computeDist(xECAL/1000.,yECAL/1000.,xPS/1000. ,yPS/1000, false);
384  }
385 
386  } else { //Old algorithm
387  dist = LinkByRecHit::testECALAndPSByRecHit( *ecalref, *psref ,debug_);
388  }
389 
390  // linktest = PFBlock::LINKTEST_RECHIT;
391 
392  break;
393  }
395  {
396  if(debug_ ) cout<<"TRACKandECAL"<<endl;
397 
398  PFRecTrackRef trackref = lowEl->trackRefPF();
399  PFClusterRef clusterref = highEl->clusterRef();
400  assert( !trackref.isNull() );
401  assert( !clusterref.isNull() );
402 
403  if(debug_ ) std::cout << " Track pt " << trackref->trackRef()->pt() << std::endl;
404 
405  // Check if the linking has been done using the KDTree algo
406  // Glowinski & Gouzevitch
407  if ( useKDTreeTrackEcalLinker_ && lowEl->isMultilinksValide() ) { //KDTree Algo
408 
409  const reco::PFMultilinksType& multilinks = lowEl->getMultilinks();
410  double ecalphi = clusterref->positionREP().Phi();
411  double ecaleta = clusterref->positionREP().Eta();
412 
413  // Check if the link Track/Ecal exist
414  reco::PFMultilinksType::const_iterator mlit = multilinks.begin();
415  for (; mlit != multilinks.end(); ++mlit)
416  if ((mlit->first == ecalphi) && (mlit->second == ecaleta))
417  break;
418 
419 
420  // If the link exist, we fill dist and linktest. We use old algorithme method.
421  if (mlit != multilinks.end()){
422 
423 
424  //Should be something like this :
425  // const reco::PFRecTrack& track = *trackref;
426  //instead of this :
427  /*
428  reco::PFRecTrack track (*trackref);
429  const reco::PFTrajectoryPoint& atECAL_tmp =
430  (*trackref).extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax );
431  if(std::abs(atECAL_tmp.positionREP().Eta())<1E-9 &&
432  std::abs(atECAL_tmp.positionREP().Phi())<1E-9 &&
433  atECAL_tmp.positionREP().R()<1E-9)
434  track.calculatePositionREP();
435  */
436 
437  const reco::PFTrajectoryPoint& atECAL =
438  trackref->extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax );
439 
440  double tracketa = atECAL.positionREP().Eta();
441  double trackphi = atECAL.positionREP().Phi();
442 
443  dist = LinkByRecHit::computeDist(ecaleta, ecalphi, tracketa, trackphi);
444  }
445 
446  } else {// Old algorithm
447  if ( trackref->extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() )
448  dist = LinkByRecHit::testTrackAndClusterByRecHit( *trackref, *clusterref, false, debug_ );
449  else
450  dist = -1.;
451  }
452 
453  if ( debug_ ) {
454  if( dist > 0. ) {
455  std::cout << " Here a link has been established"
456  << " between a track an Ecal with dist "
457  << dist << std::endl;
458  } else
459  std::cout << " No link found " << std::endl;
460  }
461 
462  // linktest = PFBlock::LINKTEST_RECHIT;
463  break;
464  }
466  {
467  // if(debug_ ) cout<<"TRACKandHCAL"<<endl;
468 
469  PFRecTrackRef trackref = lowEl->trackRefPF();
470  PFClusterRef clusterref = highEl->clusterRef();
471  assert( !trackref.isNull() );
472  assert( !clusterref.isNull() );
473 
474  // Check if the linking has been done using the KDTree algo
475  // Glowinski & Gouzevitch
476  if ( useKDTreeTrackEcalLinker_ && highEl->isMultilinksValide() ) { //KDTree Algo
477 
478  const reco::PFMultilinksType& multilinks = highEl->getMultilinks();
479 
480  /*
481  reco::PFRecTrack track (*trackref);
482  const reco::PFTrajectoryPoint& atHCALEntrance_tmp =
483  (*trackref).extrapolatedPoint( reco::PFTrajectoryPoint::HCALEntrance);
484  if (std::abs(atHCALEntrance_tmp.positionREP().Eta())<1E-9 &&
485  std::abs(atHCALEntrance_tmp.positionREP().Phi())<1E-9 &&
486  atHCALEntrance_tmp.positionREP().R()<1E-9)
487  track.calculatePositionREP();
488  */
489 
490  const reco::PFTrajectoryPoint& atHCAL =
491  trackref->extrapolatedPoint(reco::PFTrajectoryPoint::HCALEntrance);
492 
493 
494  double tracketa = atHCAL.positionREP().Eta();
495  double trackphi = atHCAL.positionREP().Phi();
496 
497  // Check if the link Track/Ecal exist
498  reco::PFMultilinksType::const_iterator mlit = multilinks.begin();
499  for (; mlit != multilinks.end(); ++mlit)
500  if ((mlit->first == trackphi) && (mlit->second == tracketa))
501  break;
502 
503  // If the link exist, we fill dist and linktest. We use old algorithme method.
504  if (mlit != multilinks.end()){
505 
506  const reco::PFTrajectoryPoint& atHCALExit =
507  trackref->extrapolatedPoint(reco::PFTrajectoryPoint::HCALExit);
508  double dHEta = 0.0;
509  double dHPhi = 0.0;
510  if (atHCALExit.position().R()>atHCAL.position().R()) {
511  dHEta = atHCALExit.positionREP().Eta()-atHCAL.positionREP().Eta();
512  dHPhi = atHCALExit.positionREP().Phi()-atHCAL.positionREP().Phi();
513  if ( dHPhi > M_PI ) dHPhi = dHPhi - 2.*M_PI;
514  else if ( dHPhi < -M_PI ) dHPhi = dHPhi + 2.*M_PI;
515  } else {
516  std::cout << "Qu'est ce que c'est que ce gag ? "
517  << atHCALExit.position().R() << " is larger than "
518  << atHCAL.position().R() << " !" << std::endl;
519  }
520 
521  tracketa += 0.1 * dHEta;
522  trackphi += 0.1 * dHPhi;
523 
524  double clusterphi = clusterref->positionREP().Phi();
525  double clustereta = clusterref->positionREP().Eta();
526 
527  dist = LinkByRecHit::computeDist(clustereta, clusterphi, tracketa, trackphi);
528  }
529 
530  } else {// Old algorithm
531  if ( trackref->extrapolatedPoint( reco::PFTrajectoryPoint::HCALEntrance ).isValid() )
532  dist = LinkByRecHit::testTrackAndClusterByRecHit( *trackref, *clusterref, false, debug_ );
533  else
534  dist = -1.;
535  }
536 
537  // linktest = PFBlock::LINKTEST_RECHIT;
538  break;
539  }
541  {
542  if(debug_ ) cout<<"TRACKandHO"<<endl;
543 
544  PFRecTrackRef trackref = lowEl->trackRefPF();
545  PFClusterRef clusterref = highEl->clusterRef();
546 
547  assert( !trackref.isNull() );
548  assert( !clusterref.isNull() );
549 
550 
551  // Old algorithm
552  // cout<<"TRACKandHO1"<<trackref->pt()<<" "<<trackref->eta()<<" "<<trackref->phi()<<endl;
553  //Same value is used in PFTrackTransformer::addPoints() for HOLayer, but allow for some rounding precision
554  if ( lowEl->trackRef()->pt() > 3.00001 && trackref->extrapolatedPoint( reco::PFTrajectoryPoint::HOLayer ).isValid() ) {
555  // cout<<"TRACKandHO2"<<endl;
556  dist = LinkByRecHit::testTrackAndClusterByRecHit( *trackref, *clusterref, false, debug_ );
557 
558  // cout <<"dist TRACKandHO "<<dist<<endl;
559  } else {
560  dist = -1.;
561  }
562  // linktest = PFBlock::LINKTEST_RECHIT;
563  break;
564  }
566  {
567  // cout<<"ECALandHCAL"<<endl;
568  PFClusterRef ecalref = lowEl->clusterRef();
569  PFClusterRef hcalref = highEl->clusterRef();
570  assert( !ecalref.isNull() );
571  assert( !hcalref.isNull() );
572  // PJ - 14-May-09 : A link by rechit is needed here !
573  dist = testECALAndHCAL( *ecalref, *hcalref );
574  // dist = -1.;
575  // linktest = PFBlock::LINKTEST_RECHIT;
576  break;
577  }
579  {
580  // cout<<"HCALandH0"<<endl;
581  PFClusterRef hcalref = lowEl->clusterRef();
582  PFClusterRef horef = highEl->clusterRef();
583  assert( !hcalref.isNull() );
584  assert( !horef.isNull() );
585  // PJ - 14-May-09 : A link by rechit is needed here !
586  dist = testHCALAndHO( *hcalref, *horef );
587  // dist = -1.;
588  // cout <<"Dist "<<dist<<endl;
589  // linktest = PFBlock::LINKTEST_RECHIT;
590  break;
591  }
593  {
594  // cout<<"HFEMandHFHAD"<<endl;
595  PFClusterRef eref = lowEl->clusterRef();
596  PFClusterRef href = highEl->clusterRef();
597  assert( !eref.isNull() );
598  assert( !href.isNull() );
599  dist = LinkByRecHit::testHFEMAndHFHADByRecHit( *eref, *href, debug_ );
600  // linktest = PFBlock::LINKTEST_RECHIT;
601  break;
602  }
603 
605  {
606  if(debug_ )
607  cout<<"TRACKandTRACK"<<endl;
608  dist = testLinkByVertex(lowEl, highEl);
609  if(debug_ )
610  std::cout << " PFBlockLink::TRACKandTRACK dist " << dist << std::endl;
611  // linktest = PFBlock::LINKTEST_RECHIT;
612  break;
613  }
614 
616  {
617 
618  PFClusterRef ecal1ref = lowEl->clusterRef();
619  PFClusterRef ecal2ref = highEl->clusterRef();
620  assert( !ecal1ref.isNull() );
621  assert( !ecal2ref.isNull() );
622  if(debug_)
623  cout << " PFBlockLink::ECALandECAL" << endl;
624  dist = testLinkBySuperCluster(ecal1ref,ecal2ref);
625  break;
626  }
627 
629  {
630  PFClusterRef clusterref = lowEl->clusterRef();
631  assert( !clusterref.isNull() );
632  const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
633  const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
635  dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, false, debug_ );
636  else
637  dist = -1.;
638  // linktest = PFBlock::LINKTEST_RECHIT;
639 
640  if ( debug_ ) {
641  if ( dist > 0. ) {
642  std::cout << " Here a link has been established"
643  << " between a GSF track an Ecal with dist "
644  << dist << std::endl;
645  } else {
646  if(debug_ ) std::cout << " No link found " << std::endl;
647  }
648  }
649  break;
650  }
652  {
653  PFRecTrackRef trackref = lowEl->trackRefPF();
654  assert( !trackref.isNull() );
655  const reco::PFBlockElementGsfTrack * GsfEl =
656  dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
657  GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
658  reco::TrackRef kftrackref= (*trackref).trackRef();
659  assert( !gsfref.isNull() );
660  PFRecTrackRef refkf = (*gsfref).kfPFRecTrackRef();
661  if(refkf.isNonnull()) {
662  reco::TrackRef gsftrackref = (*refkf).trackRef();
663  if (gsftrackref.isNonnull()&&kftrackref.isNonnull()) {
664  if (kftrackref == gsftrackref) {
665  dist = 0.001;
666  } else {
667  dist = -1.;
668  }
669  } else {
670  dist = -1.;
671  }
672  } else {
673  dist = -1.;
674  }
675 
676 
678  if(lowEl->isLinkedToDisplacedVertex()){
679  vector<PFRecTrackRef> pfrectrack_vec = GsfEl->GsftrackRefPF()->convBremPFRecTrackRef();
680  if(pfrectrack_vec.size() > 0){
681  for(unsigned int iconv = 0; iconv < pfrectrack_vec.size(); ++iconv) {
683  // use track ref
684  if(kftrackref == (*pfrectrack_vec[iconv]).trackRef()) {
685  dist = 0.001;
686  }
687  }
688  else{
689  // use the track base ref
690  reco::TrackBaseRef newTrackBaseRef((*pfrectrack_vec[iconv]).trackRef());
691  reco::TrackBaseRef elemTrackBaseRef(kftrackref);
692  if(newTrackBaseRef == elemTrackBaseRef){
693  dist = 0.001;
694  }
695  }
696  }
697  }
698  }
699  }
700 
701 
702  break;
703  }
704 
706  {
707  const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(lowEl);
708  const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
709  GsfPFRecTrackRef gsfref = GsfEl->GsftrackRefPF();
710  GsfPFRecTrackRef bremref = BremEl->GsftrackRefPF();
711  assert( !gsfref.isNull() );
712  assert( !bremref.isNull() );
713  if (gsfref == bremref) {
714  dist = 0.001;
715  } else {
716  dist = -1.;
717  }
718  break;
719  }
721  {
722  const reco::PFBlockElementGsfTrack * lowGsfEl =
723  dynamic_cast<const reco::PFBlockElementGsfTrack*>(lowEl);
724  const reco::PFBlockElementGsfTrack * highGsfEl =
725  dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
726 
727  GsfPFRecTrackRef lowgsfref = lowGsfEl->GsftrackRefPF();
728  GsfPFRecTrackRef highgsfref = highGsfEl->GsftrackRefPF();
729  assert( !lowgsfref.isNull() );
730  assert( !highgsfref.isNull() );
731 
732  if( (lowGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false &&
734  (highGsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false &&
736  if(lowgsfref->trackId() == highgsfref->trackId()) {
737  dist = 0.001;
738  }
739  else {
740  dist = -1.;
741  }
742  }
743  break;
744  }
746  {
747  PFClusterRef clusterref = lowEl->clusterRef();
748  assert( !clusterref.isNull() );
749  const reco::PFBlockElementBrem * BremEl =
750  dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
751  const PFRecTrack * myTrack = &(BremEl->trackPF());
752  /*
753  double DP = (BremEl->DeltaP())*(-1.);
754  double SigmaDP = BremEl->SigmaDeltaP();
755  double SignBremDp = DP/SigmaDP;
756  */
757  bool isBrem = true;
759  dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, isBrem, debug_);
760  else
761  dist = -1.;
762  if( debug_ && dist > 0. )
763  std::cout << "ECALandBREM: dist testTrackAndClusterByRecHit "
764  << dist << std::endl;
765  // linktest = PFBlock::LINKTEST_RECHIT;
766  break;
767  }
769  {
770  PFClusterRef clusterref = lowEl->clusterRef();
771  assert( !clusterref.isNull() );
772  const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
773  const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
775  dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, false, debug_ );
776  else
777  dist = -1.;
778 
779  // linktest = PFBlock::LINKTEST_RECHIT;
780  break;
781  }
783  {
784  PFClusterRef clusterref = lowEl->clusterRef();
785  assert( !clusterref.isNull() );
786  const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
787  const PFRecTrack * myTrack = &(BremEl->trackPF());
788  bool isBrem = true;
790  dist = LinkByRecHit::testTrackAndClusterByRecHit( *myTrack, *clusterref, isBrem, debug_);
791  else
792  dist = -1.;
793  break;
794  }
796  {
797  PFClusterRef clusterref = lowEl->clusterRef();
798 
799  assert( !clusterref.isNull() );
800 
801  const reco::PFBlockElementSuperCluster * scEl =
802  dynamic_cast<const reco::PFBlockElementSuperCluster*>(highEl);
803  assert (!scEl->superClusterRef().isNull());
804  dist = testSuperClusterPFCluster(scEl->superClusterRef(),
805  clusterref);
806  break;
807  }
808  /*
809  // Links between the two preshower layers are not used for now - disable
810  case PFBlockLink::PS1andPS2:
811  {
812  PFClusterRef ps1ref = lowEl->clusterRef();
813  PFClusterRef ps2ref = highEl->clusterRef();
814  assert( !ps1ref.isNull() );
815  assert( !ps2ref.isNull() );
816  // PJ - 14-May-09 : A link by rechit is needed here !
817  // dist = testPS1AndPS2( *ps1ref, *ps2ref );
818  dist = -1.;
819  linktest = PFBlock::LINKTEST_RECHIT;
820  break;
821  }
822  case PFBlockLink::TRACKandPS1:
823  case PFBlockLink::TRACKandPS2:
824  {
825  //cout<<"TRACKandPS"<<endl;
826  PFRecTrackRef trackref = lowEl->trackRefPF();
827  PFClusterRef clusterref = highEl->clusterRef();
828  assert( !trackref.isNull() );
829  assert( !clusterref.isNull() );
830  // PJ - 14-May-09 : A link by rechit is needed here !
831  dist = testTrackAndPS( *trackref, *clusterref );
832  linktest = PFBlock::LINKTEST_RECHIT;
833  break;
834  }
835  // GSF Track/Brem Track and preshower cluster links are not used for now - disable
836  case PFBlockLink::PS1andGSF:
837  case PFBlockLink::PS2andGSF:
838  {
839  PFClusterRef psref = lowEl->clusterRef();
840  assert( !psref.isNull() );
841  const reco::PFBlockElementGsfTrack * GsfEl = dynamic_cast<const reco::PFBlockElementGsfTrack*>(highEl);
842  const PFRecTrack * myTrack = &(GsfEl->GsftrackPF());
843  // PJ - 14-May-09 : A link by rechit is needed here !
844  dist = testTrackAndPS( *myTrack, *psref );
845  linktest = PFBlock::LINKTEST_RECHIT;
846  break;
847  }
848  case PFBlockLink::PS1andBREM:
849  case PFBlockLink::PS2andBREM:
850  {
851  PFClusterRef psref = lowEl->clusterRef();
852  assert( !psref.isNull() );
853  const reco::PFBlockElementBrem * BremEl = dynamic_cast<const reco::PFBlockElementBrem*>(highEl);
854  const PFRecTrack * myTrack = &(BremEl->trackPF());
855  // PJ - 14-May-09 : A link by rechit is needed here !
856  dist = testTrackAndPS( *myTrack, *psref );
857  linktest = PFBlock::LINKTEST_RECHIT;
858  break;
859  }
860  */
861 
862  default:
863  dist = -1.;
864  // linktest = PFBlock::LINKTEST_RECHIT;
865  // cerr<<"link type not implemented yet: 0x"<<hex<<linktype<<dec<<endl;
866  // assert(0);
867  return;
868  }
869 }
870 
871 double
873  const PFCluster& ps) const {
874 
875 #ifdef PFLOW_DEBUG
876  // cout<<"entering testTrackAndPS"<<endl;
877  // resolution of PS cluster dxdx and dydy from strip pitch and length
878  double dx=0.;
879  double dy=0.;
880 
881  unsigned layerid =0;
882  // PS1: vertical strips PS2: horizontal strips
883  switch (ps.layer()) {
884  case PFLayer::PS1:
886 
887  // vertical strips in PS1, measure x with pitch precision
888  dx = resPSpitch_;
889  dy = resPSlength_;
890  break;
891  case PFLayer::PS2:
893  // horizontal strips in PS2, measure y with pitch precision
894  dy = resPSpitch_;
895  dx = resPSlength_;
896  break;
897  default:
898  break;
899  }
900  const reco::PFTrajectoryPoint& atPS
901  = track.extrapolatedPoint( layerid );
902  // did not reach PS, cannot be associated with a cluster.
903  if( ! atPS.isValid() ) return -1.;
904 
905  double trackx = atPS.position().X();
906  double tracky = atPS.position().Y();
907  double trackz = atPS.position().Z(); // MDN jan 09
908 
909  // ps position x, y
910  double psx = ps.position().X();
911  double psy = ps.position().Y();
912  // MDN Jan 09: check that trackz and psz have the same sign
913  double psz = ps.position().Z();
914  if( trackz*psz < 0.) return -1.;
915 
916  // double chi2 = (psx-trackx)*(psx-trackx)/(dx*dx + trackresolx*trackresolx)
917  // + (psy-tracky)*(psy-tracky)/(dy*dy + trackresoly*trackresoly);
918 
919  double dist = std::sqrt( (psx-trackx)*(psx-trackx)
920  + (psy-tracky)*(psy-tracky));
921  if(debug_) cout<<"testTrackAndPS "<< dist <<" "<<endl;
922  if(debug_){
923  cout<<" trackx " << trackx
924  <<" tracky " << tracky
925  <<" psx " << psx
926  <<" psy " << psy
927  << endl;
928  }
929 #endif
930 
931  // Return -1. as long as no link by rechit is available
932  return -1.;
933 }
934 
935 double
937  const PFCluster& hcal) const {
938 
939  // cout<<"entering testECALAndHCAL"<<endl;
940 
941  double dist = fabs(ecal.positionREP().Eta()) > 2.5 ?
943  ecal.positionREP().Phi(),
944  hcal.positionREP().Eta(),
945  hcal.positionREP().Phi() )
946  :
947  -1.;
948 
949 #ifdef PFLOW_DEBUG
950  if(debug_) cout<<"testECALAndHCAL "<< dist <<" "<<endl;
951  if(debug_){
952  cout<<" ecaleta " << ecal.positionREP().Eta()
953  <<" ecalphi " << ecal.positionREP().Phi()
954  <<" hcaleta " << hcal.positionREP().Eta()
955  <<" hcalphi " << hcal.positionREP().Phi()
956  }
957 #endif
958 
959  if ( dist < 0.2 ) return dist;
960 
961  // Need to implement a link by RecHit
962  return -1.;
963 }
964 
965 double
967  const PFCluster& ho) const {
968 
969  double dist = fabs(hcal.positionREP().Eta()) < 1.5 ?
971  hcal.positionREP().Phi(),
972  ho.positionREP().Eta(),
973  ho.positionREP().Phi() )
974  :
975  -1.;
976 
977 #ifdef PFLOW_DEBUG
978  if(debug_) cout<<"testHCALAndHO "<< dist <<" "<<endl;
979  if(debug_){
980  cout<<" hcaleta " << hcal.positionREP().Eta()
981  <<" hcalphi " << hcal.positionREP().Phi()
982  <<" hoeta " << ho.positionREP().Eta()
983  <<" hophi " << ho.positionREP().Phi()
984  <<" dist " << dist<<endl;
985  }
986 #endif
987 
988  if ( dist < 0.20 ) return dist;
989 
990  // Need to implement a link by RecHit
991  return -1.;
992 }
993 
994 
995 
996 double
998  const PFClusterRef& ecal2) const {
999 
1000  // cout<<"entering testECALAndECAL "<< pfcRefSCMap_.size() << endl;
1001 
1002  double dist = -1;
1003 
1004  // the first one is not in any super cluster
1005  int testindex=pfcSCVec_[ecal1.key()];
1006  if(testindex == -1.) return dist;
1007  // if(itcheck==pfcRefSCMap_.end()) return dist;
1008  // now retrieve the of PFclusters in this super cluster
1009 
1010  const std::vector<reco::PFClusterRef> & thePFClusters(scpfcRefs_[testindex]);
1011 
1012  unsigned npf=thePFClusters.size();
1013  for(unsigned i=0;i<npf;++i)
1014  {
1015  if(thePFClusters[i]==ecal2) // yes they are in the same SC
1016  {
1017  dist=LinkByRecHit::computeDist( ecal1->positionREP().Eta(),
1018  ecal1->positionREP().Phi(),
1019  ecal2->positionREP().Eta(),
1020  ecal2->positionREP().Phi() );
1021 // std::cout << " DETA " << fabs(ecal1->positionREP().Eta()-ecal2->positionREP().Eta()) << std::endl;
1022 // if(fabs(ecal1->positionREP().Eta()-ecal2->positionREP().Eta())>0.2)
1023 // {
1024 // std::cout << " Super Cluster " << *(superClusters_[testindex]) << std::endl;
1025 // std::cout << " Cluster1 " << *ecal1 << std::endl;
1026 // std::cout << " Cluster2 " << *ecal2 << std::endl;
1027 // ClusterClusterMapping::checkOverlap(*ecal1,superClusters_,0.01,true);
1028 // ClusterClusterMapping::checkOverlap(*ecal2,superClusters_,0.01,true);
1029 // }
1030  return dist;
1031  }
1032  }
1033  return dist;
1034 }
1035 
1036 
1037 double
1039  const PFClusterRef& ecal2) const {
1040 
1041  // cout<<"entering testECALAndECAL "<< pfcRefSCMap_.size() << endl;
1042 
1043  double dist = -1;
1044 
1046  //loop over supercluster CaloClusters, look up PFCluster ptrs in value map, and match by ref
1047  for (reco::CaloCluster_iterator caloclus = ecal1->clustersBegin(); caloclus!=ecal1->clustersEnd(); ++caloclus) {
1049  if (overlap) dist = 0.001;
1050  }
1051  }
1052  else {
1053  bool overlap=ClusterClusterMapping::overlap(*ecal1,*ecal2);
1054 
1055  if(overlap) {
1056  dist=LinkByRecHit::computeDist( ecal1->position().eta(),
1057  ecal1->position().phi(),
1058  ecal2->positionREP().Eta(),
1059  ecal2->positionREP().Phi() );
1060  }
1061  }
1062  return dist;
1063 }
1064 
1065 
1066 
1067 double
1069  const PFCluster& ps2) const {
1070 
1071 #ifdef PFLOW_DEBUG
1072  // cout<<"entering testPS1AndPS2"<<endl;
1073 
1074  // compute chi2 in y, z using swimming formulae
1075  // y2 = y1 * z2/z1 and x2 = x1 *z2/z1
1076 
1077  // ps position1 x, y, z
1078  double x1 = ps1.position().X();
1079  double y1 = ps1.position().Y();
1080  double z1 = ps1.position().Z();
1081  double x2 = ps2.position().X();
1082  double y2 = ps2.position().Y();
1083  double z2 = ps2.position().Z();
1084  // MDN Bug correction Jan 09: check that z1 and z2 have the same sign!
1085  if (z1*z2<0.) -1.;
1086  // swim to PS2
1087  double scale = z2/z1;
1088  double x1atPS2 = x1*scale;
1089  double y1atPS2 = y1*scale;
1090  // resolution of PS cluster dxdx and dydy from strip pitch and length
1091  // vertical strips in PS1, measure x with pitch precision
1092  double dx1dx1 = resPSpitch_*resPSpitch_*scale*scale;
1093  double dy1dy1 = resPSlength_*resPSlength_*scale*scale;
1094  // horizontal strips in PS2 , measure y with pitch precision
1095  double dy2dy2 = resPSpitch_*resPSpitch_;
1096  double dx2dx2 = resPSlength_*resPSlength_;
1097 
1098  // double chi2 = (x2-x1atPS2)*(x2-x1atPS2)/(dx1dx1 + dx2dx2)
1099  // + (y2-y1atPS2)*(y2-y1atPS2)/(dy1dy1 + dy2dy2);
1100 
1101  double dist = std::sqrt( (x2-x1atPS2)*(x2-x1atPS2)
1102  + (y2-y1atPS2)*(y2-y1atPS2));
1103 
1104  if(debug_) cout<<"testPS1AndPS2 "<<dist<<" "<<endl;
1105  if(debug_){
1106  cout<<" x1atPS2 "<< x1atPS2 << " dx1 "<<resPSpitch_*scale
1107  <<" y1atPS2 "<< y1atPS2 << " dy1 "<<resPSlength_*scale<< endl
1108  <<" x2 " <<x2 << " dx2 "<<resPSlength_
1109  <<" y2 " << y2 << " dy2 "<<resPSpitch_<< endl;
1110  }
1111 #endif
1112 
1113  // Need a link by rechit here
1114  return -1.;
1115 }
1116 
1117 
1118 
1119 double
1121  const reco::PFBlockElement* elt2) const {
1122 
1123  // cout << "Test link by vertex between" << endl << *elt1 << endl << " and " << endl << *elt2 << endl;
1124 
1125  double result=-1.;
1126 
1129  PFDisplacedTrackerVertexRef ni1_TO_DISP = elt1->displacedVertexRef(T_TO_DISP);
1130  PFDisplacedTrackerVertexRef ni2_TO_DISP = elt2->displacedVertexRef(T_TO_DISP);
1131  PFDisplacedTrackerVertexRef ni1_FROM_DISP = elt1->displacedVertexRef(T_FROM_DISP);
1132  PFDisplacedTrackerVertexRef ni2_FROM_DISP = elt2->displacedVertexRef(T_FROM_DISP);
1133 
1134  if( ni1_TO_DISP.isNonnull() && ni2_FROM_DISP.isNonnull())
1135  if( ni1_TO_DISP == ni2_FROM_DISP ) { result = 1.0; return result; }
1136 
1137  if( ni1_FROM_DISP.isNonnull() && ni2_TO_DISP.isNonnull())
1138  if( ni1_FROM_DISP == ni2_TO_DISP ) { result = 1.0; return result; }
1139 
1140  if( ni1_FROM_DISP.isNonnull() && ni2_FROM_DISP.isNonnull())
1141  if( ni1_FROM_DISP == ni2_FROM_DISP ) { result = 1.0; return result; }
1142 
1143 
1146 
1147  if(debug_ ) std::cout << " testLinkByVertex On Conversions " << std::endl;
1148 
1149  if ( elt1->convRef().isNonnull() && elt2->convRef().isNonnull() ) {
1150  if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex Cconversion Refs are non null " << std::endl;
1151  if ( elt1->convRef() == elt2->convRef() ) {
1152  result=1.0;
1153  if(debug_ ) std::cout << " testLinkByVertex Cconversion Refs are equal " << std::endl;
1154  return result;
1155  }
1156  }
1157 
1158  }
1159 
1162  if(debug_ ) std::cout << " testLinkByVertex On V0 " << std::endl;
1163  if ( elt1->V0Ref().isNonnull() && elt2->V0Ref().isNonnull() ) {
1164  if(debug_ ) std::cout << " PFBlockAlgo.cc testLinkByVertex V0 Refs are non null " << std::endl;
1165  if ( elt1->V0Ref() == elt2->V0Ref() ) {
1166  result=1.0;
1167  if(debug_ ) std::cout << " testLinkByVertex V0 Refs are equal " << std::endl;
1168  return result;
1169  }
1170  }
1171  }
1172 
1173  return result;
1174 }
1175 
1176 
1177 
1178 void
1180  const reco::GsfPFRecTrackCollection& gsftracks,
1181  const reco::PFClusterCollection& ecals,
1182  const reco::PFClusterCollection& hcals,
1183  const reco::PFClusterCollection& hos,
1184  const reco::PFClusterCollection& hfems,
1185  const reco::PFClusterCollection& hfhads,
1187  const reco::PhotonCollection& egphh,
1188  const reco::SuperClusterCollection& sceb,
1189  const reco::SuperClusterCollection& scee,
1190  const Mask& trackMask,
1191  const Mask& gsftrackMask,
1192  const Mask& ecalMask,
1193  const Mask& hcalMask,
1194  const Mask& hoMask,
1195  const Mask& hfemMask,
1196  const Mask& hfhadMask,
1197  const Mask& psMask,
1198  const Mask& phMask,
1199  const Mask& scMask) const {
1200 
1201  if( !trackMask.empty() &&
1202  trackMask.size() != tracks.size() ) {
1203  string err = "PFBlockAlgo::setInput: ";
1204  err += "The size of the track mask is different ";
1205  err += "from the size of the track vector.";
1206  throw std::length_error( err.c_str() );
1207  }
1208 
1209  if( !gsftrackMask.empty() &&
1210  gsftrackMask.size() != gsftracks.size() ) {
1211  string err = "PFBlockAlgo::setInput: ";
1212  err += "The size of the gsf track mask is different ";
1213  err += "from the size of the gsftrack vector.";
1214  throw std::length_error( err.c_str() );
1215  }
1216 
1217  if( !ecalMask.empty() &&
1218  ecalMask.size() != ecals.size() ) {
1219  string err = "PFBlockAlgo::setInput: ";
1220  err += "The size of the ecal mask is different ";
1221  err += "from the size of the ecal clusters vector.";
1222  throw std::length_error( err.c_str() );
1223  }
1224 
1225  if( !hcalMask.empty() &&
1226  hcalMask.size() != hcals.size() ) {
1227  string err = "PFBlockAlgo::setInput: ";
1228  err += "The size of the hcal mask is different ";
1229  err += "from the size of the hcal clusters vector.";
1230  throw std::length_error( err.c_str() );
1231  }
1232 
1233  if( !hoMask.empty() &&
1234  hoMask.size() != hos.size() ) {
1235  string err = "PFBlockAlgo::setInput: ";
1236  err += "The size of the ho mask is different ";
1237  err += "from the size of the ho clusters vector.";
1238  throw std::length_error( err.c_str() );
1239  }
1240 
1241 
1242  if( !hfemMask.empty() &&
1243  hfemMask.size() != hfems.size() ) {
1244  string err = "PFBlockAlgo::setInput: ";
1245  err += "The size of the hfem mask is different ";
1246  err += "from the size of the hfem clusters vector.";
1247  throw std::length_error( err.c_str() );
1248  }
1249 
1250  if( !hfhadMask.empty() &&
1251  hfhadMask.size() != hfhads.size() ) {
1252  string err = "PFBlockAlgo::setInput: ";
1253  err += "The size of the hfhad mask is different ";
1254  err += "from the size of the hfhad clusters vector.";
1255  throw std::length_error( err.c_str() );
1256  }
1257 
1258  if( !psMask.empty() &&
1259  psMask.size() != pss.size() ) {
1260  string err = "PFBlockAlgo::setInput: ";
1261  err += "The size of the ps mask is different ";
1262  err += "from the size of the ps clusters vector.";
1263  throw std::length_error( err.c_str() );
1264  }
1265 
1266  if( !phMask.empty() &&
1267  phMask.size() != egphh.size() ) {
1268  string err = "PFBlockAlgo::setInput: ";
1269  err += "The size of the photon mask is different ";
1270  err += "from the size of the photon vector.";
1271  throw std::length_error( err.c_str() );
1272  }
1273 
1274  if( !scMask.empty() &&
1275  scMask.size() != (sceb.size() + scee.size()) ) {
1276  string err = "PFBlockAlgo::setInput: ";
1277  err += "The size of the SC mask is different ";
1278  err += "from the size of the SC vectors.";
1279  throw std::length_error( err.c_str() );
1280  }
1281 
1282 }
1283 
1284 
1285 std::ostream& operator<<(std::ostream& out, const PFBlockAlgo& a) {
1286  if(! out) return out;
1287 
1288  out<<"====== Particle Flow Block Algorithm ======= ";
1289  out<<endl;
1290  out<<"number of unassociated elements : "<<a.elements_.size()<<endl;
1291  out<<endl;
1292 
1293  for(PFBlockAlgo::IEC ie = a.elements_.begin();
1294  ie != a.elements_.end(); ++ie) {
1295  out<<"\t"<<**ie <<endl;
1296  }
1297 
1298 
1299  // const PFBlockCollection& blocks = a.blocks();
1300 
1301  const std::auto_ptr< reco::PFBlockCollection >& blocks
1302  = a.blocks();
1303 
1304  if(!blocks.get() ) {
1305  out<<"blocks already transfered"<<endl;
1306  }
1307  else {
1308  out<<"number of blocks : "<<blocks->size()<<endl;
1309  out<<endl;
1310 
1311  for(PFBlockAlgo::IBC ib=blocks->begin();
1312  ib != blocks->end(); ++ib) {
1313  out<<(*ib)<<endl;
1314  }
1315  }
1316 
1317  return out;
1318 }
1319 
1320 bool
1322 
1323  double P = trackref->p();
1324  double Pt = trackref->pt();
1325  double DPt = trackref->ptError();
1326  unsigned int NHit = trackref->hitPattern().trackerLayersWithMeasurement();
1327  unsigned int NLostHit = trackref->hitPattern().trackerLayersWithoutMeasurement();
1328  unsigned int LostHits = trackref->numberOfLostHits();
1329  double sigmaHad = sqrt(1.20*1.20/P+0.06*0.06) / (1.+LostHits);
1330 
1331  // iteration 1,2,3,4,5 correspond to algo = 1/4,5,6,7,8,9
1332  unsigned int Algo = 0;
1333  switch (trackref->algo()) {
1334  case TrackBase::ctf:
1335  case TrackBase::iter0:
1336  case TrackBase::iter1:
1337  case TrackBase::iter2:
1338  Algo = 0;
1339  break;
1340  case TrackBase::iter3:
1341  Algo = 1;
1342  break;
1343  case TrackBase::iter4:
1344  Algo = 2;
1345  break;
1346  case TrackBase::iter5:
1347  Algo = 3;
1348  break;
1349  case TrackBase::iter6:
1350  Algo = 4;
1351  break;
1352  default:
1353  Algo = useIterTracking_ ? 5 : 0;
1354  break;
1355  }
1356 
1357  // Protection against 0 momentum tracks
1358  if ( P < 0.05 ) return false;
1359 
1360  // Temporary : Reject all tracking iteration beyond 5th step.
1361  if ( Algo > 4 ) return false;
1362 
1363  if (debug_) cout << " PFBlockAlgo: PFrecTrack->Track Pt= "
1364  << Pt << " DPt = " << DPt << endl;
1365  if ( ( DPtovPtCut_[Algo] > 0. &&
1366  DPt/Pt > DPtovPtCut_[Algo]*sigmaHad ) ||
1367  NHit < NHitCut_[Algo] ) {
1368  // (Algo >= 3 && LostHits != 0) ) {
1369  if (debug_) cout << " PFBlockAlgo: skip badly measured track"
1370  << ", P = " << P
1371  << ", Pt = " << Pt
1372  << " DPt = " << DPt
1373  << ", N(hits) = " << NHit << " (Lost : " << LostHits << "/" << NLostHit << ")"
1374  << ", Algo = " << Algo
1375  << endl;
1376  if (debug_) cout << " cut is DPt/Pt < " << DPtovPtCut_[Algo] * sigmaHad << endl;
1377  if (debug_) cout << " cut is NHit >= " << NHitCut_[Algo] << endl;
1378  /*
1379  std::cout << "Track REJECTED : ";
1380  std::cout << ", P = " << P
1381  << ", Pt = " << Pt
1382  << " DPt = " << DPt
1383  << ", N(hits) = " << NHit << " (Lost : " << LostHits << "/" << NLostHit << ")"
1384  << ", Algo = " << Algo
1385  << std::endl;
1386  */
1387  return false;
1388  }
1389 
1390  /*
1391  std::cout << "Track Accepted : ";
1392  std::cout << ", P = " << P
1393  << ", Pt = " << Pt
1394  << " DPt = " << DPt
1395  << ", N(hits) = " << NHit << " (Lost : " << LostHits << "/" << NLostHit << ")"
1396  << ", Algo = " << Algo
1397  << std::endl;
1398  */
1399  return true;
1400 }
1401 
1402 int
1404  const edm::Handle<reco::MuonCollection>& muonh) const {
1405  if(muonh.isValid() ) {
1406  for(unsigned j=0;j<muonh->size(); ++j) {
1407  reco::MuonRef muonref( muonh, j );
1408  if (muonref->track().isNonnull())
1409  if( muonref->track() == trackref ) return j;
1410  }
1411  }
1412  return -1; // not found
1413 }
1414 
1415 int
1417  const edm::OrphanHandle<reco::MuonCollection>& muonh) const {
1418  if(muonh.isValid() ) {
1419  for(unsigned j=0;j<muonh->size(); ++j) {
1420  reco::MuonRef muonref( muonh, j );
1421  if (muonref->track().isNonnull())
1422  if( muonref->track() == trackref ) return j;
1423  }
1424  }
1425  return -1; // not found
1426 }
1427 
1428 
1429 // This prefilter avoid to call associate when not necessary.
1430 // ACHTUNG!!!! If you introduce new links check that they are not desables here
1431 inline bool
1433 
1434  PFBlockElement::Type type1 = (last)->type();
1435  PFBlockElement::Type type2 = (next)->type();
1436 
1437  if( type1==type2 ) {
1438  // cannot link 2 elements of the same type.
1439  // except if the elements are 2 tracks or 2 ECAL
1440  if( type1!=PFBlockElement::TRACK && type1!=PFBlockElement::GSF &&
1441  type1!=PFBlockElement::ECAL) { // && type1!=PFBlockElement::HCAL) {
1442  return false;
1443  }
1444 
1445  if (type1==PFBlockElement::ECAL && bNoSuperclus_) return false;
1446 
1447  // cannot link two primary tracks (except if they come from a V0)
1448  if( type1 ==PFBlockElement::TRACK) {
1449  if ( !((last)->isLinkedToDisplacedVertex()) || !((next)->isLinkedToDisplacedVertex()))
1450  return false;
1451  }
1452  }
1453 
1454  if ((type1 == PFBlockElement::PS1 || type1 == PFBlockElement::PS2) && (type2 != PFBlockElement::ECAL)) return false;
1455  if ((type2 == PFBlockElement::PS1 || type2 == PFBlockElement::PS2) && (type1 != PFBlockElement::ECAL)) return false;
1456  if ((type1 == PFBlockElement::HFEM && type2 != PFBlockElement::HFHAD) || (type1 == PFBlockElement::HFHAD && type2 != PFBlockElement::HFEM)) return false;
1457 
1459 
1460  if ( type1 == PFBlockElement::TRACK && type2 == PFBlockElement::ECAL)
1461  if ( last->isMultilinksValide() && last->getMultilinks().size()==0 ) return false;
1462  if ( type2 == PFBlockElement::TRACK && type1 == PFBlockElement::ECAL)
1463  if ( next->isMultilinksValide() && next->getMultilinks().size()==0 ) return false;
1464  if ( type1 == PFBlockElement::PS1 || type1 == PFBlockElement::PS2)
1465  if ( last->isMultilinksValide() && last->getMultilinks().size()==0 ) return false;
1466  if ( type2 == PFBlockElement::PS1 || type2 == PFBlockElement::PS2)
1467  if ( next->isMultilinksValide() && next->getMultilinks().size()==0 ) return false;
1468 
1469  }
1470 
1471  return true;
1472 
1473 }
1474 
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Definition: PFCluster.cc:81
const std::auto_ptr< reco::PFBlockCollection > & blocks() const
Definition: PFBlockAlgo.h:194
const REPPoint & positionREP() const
trajectory position in (rho, eta, phi) base
type
Definition: HCALResponse.h:21
std::vector< std::pair< double, double > > PFMultilinksType
Abstract This class is used by the KDTree Track / Ecal Cluster linker to store all found links...
Abstract base class for a PFBlock element (track, cluster...)
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:124
reconstructed track used as an input to particle flow
Definition: PFRecTrack.h:22
int i
Definition: DBlmapReader.cc:9
static double computeDist(double eta1, double phi1, double eta2, double phi2, bool etaPhi=true)
computes a chisquare
static bool overlap(const reco::CaloCluster &sc1, const reco::CaloCluster &sc, float minfrac=0.01, bool debug=false)
std::pair< ALIstring, ALIstring > pss
Definition: Fit.h:27
int ib
Definition: cuy.py:660
double testECALAndHCAL(const reco::PFCluster &ecal, const reco::PFCluster &hcal) const
Definition: PFBlockAlgo.cc:936
bool useIterTracking_
Flag to turn off quality cuts which require iterative tracking (for heavy-ions)
Definition: PFBlockAlgo.h:335
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:43
GsfPFRecTrackRef GsftrackRefPF() const
double testSuperClusterPFCluster(const reco::SuperClusterRef &sct1, const reco::PFClusterRef &elt2) const
test association between SuperClusters and ECAL
KDTreeLinkerTrackEcal TELinker_
Definition: PFBlockAlgo.h:321
double testHCALAndHO(const reco::PFCluster &hcal, const reco::PFCluster &ho) const
Definition: PFBlockAlgo.cc:966
static double testECALAndPSByRecHit(const reco::PFCluster &clusterECAL, const reco::PFCluster &clusterPS, bool debug=false)
const math::XYZPoint & position() const
cartesian position (x, y, z)
KDTreeLinkerPSEcal PSELinker_
Definition: PFBlockAlgo.h:323
Type type() const
int nuclearInteractionsPurity_
Definition: PFBlockAlgo.h:357
size_type size() const
Definition: OwnVector.h:247
const edm::ValueMap< reco::CaloClusterPtr > * pfclusterassoc_
Definition: PFBlockAlgo.h:348
#define P
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
std::auto_ptr< reco::PFBlockCollection > blocks_
Definition: PFBlockAlgo.h:311
const LinkData & linkData() const
Definition: PFBlock.h:112
tuple els
Definition: asciidump.py:420
std::vector< double > DPtovPtCut_
DPt/Pt cut for creating atrack element.
Definition: PFBlockAlgo.h:329
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:187
virtual PFDisplacedTrackerVertexRef displacedVertexRef(TrackType trType) const
bool superClusterMatchByRef_
Definition: PFBlockAlgo.h:346
double testTrackAndPS(const reco::PFRecTrack &track, const reco::PFCluster &ps) const
Definition: PFBlockAlgo.cc:872
std::list< reco::PFBlockElement * >::const_iterator IEC
Definition: PFBlockAlgo.h:202
void setLink(unsigned i1, unsigned i2, double dist, LinkData &linkData, LinkTest test=LINKTEST_RECHIT) const
Definition: PFBlock.cc:26
bool overlap(const reco::Muon &muon1, const reco::Muon &muon2, double pullX=1.0, double pullY=1.0, bool checkAdjacentChambers=false)
Particle Flow Algorithm.
Definition: PFBlockAlgo.h:71
virtual VertexCompositeCandidateRef V0Ref() const
double testLinkBySuperCluster(const reco::PFClusterRef &elt1, const reco::PFClusterRef &elt2) const
test association by Supercluster between two ECAL
Definition: PFBlockAlgo.cc:997
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
bool isNull() const
Checks for null.
Definition: Ref.h:247
KDTreeLinkerTrackHcal THLinker_
Definition: PFBlockAlgo.h:322
double testPS1AndPS2(const reco::PFCluster &ps1, const reco::PFCluster &ps2) const
bool useSuperClusters_
Flag to turn off the import of SuperCluster collections.
Definition: PFBlockAlgo.h:341
std::vector< GsfPFRecTrack > GsfPFRecTrackCollection
collection of GsfPFRecTrack objects
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
T sqrt(T t)
Definition: SSEVec.h:48
virtual reco::TrackRef trackRef() const
bool useConvBremPFRecTracks_
switch on/off Conversions Brem Recovery with KF Tracks
Definition: PFBlockAlgo.h:360
tuple result
Definition: query.py:137
const REPPoint & positionREP() const
cluster position: rho, eta, phi
Definition: PFCluster.h:75
int muAssocToTrack(const reco::TrackRef &trackref, const edm::Handle< reco::MuonCollection > &muonh) const
void link(const reco::PFBlockElement *el1, const reco::PFBlockElement *el2, PFBlockLink::Type &linktype, reco::PFBlock::LinkTest &linktest, double &dist) const
check whether 2 elements are linked. Returns distance and linktype
Definition: PFBlockAlgo.cc:323
virtual PFClusterRef clusterRef() const
int j
Definition: DBlmapReader.cc:9
virtual PFRecTrackRef trackRefPF() const
const reco::PFTrajectoryPoint & extrapolatedPoint(unsigned layerid) const
Definition: PFTrack.cc:76
std::list< reco::PFBlockElement * >::iterator IE
define these in *Fwd files in DataFormats/ParticleFlowReco?
Definition: PFBlockAlgo.h:201
void buildGraph()
Definition: PFBlockAlgo.cc:316
std::list< reco::PFBlockElement * > elements_
actually, particles will be created by a separate producer
Definition: PFBlockAlgo.h:317
bool isValid() const
Definition: HandleBase.h:76
virtual bool trackType(TrackType trType) const
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
Definition: PFBlockFwd.h:11
void bookLinkData()
Definition: PFBlock.cc:20
std::vector< std::vector< reco::PFClusterRef > > scpfcRefs_
PF clusters corresponding to a given SC.
Definition: PFBlockAlgo.h:375
bool goodPtResolution(const reco::TrackRef &trackref)
open a resolution map
void packLinks(reco::PFBlock &block, const std::vector< PFBlockLink > &links) const
Definition: PFBlockAlgo.cc:242
tuple out
Definition: dbtoconf.py:99
static const Mask dummyMask_
Definition: PFBlockAlgo.h:326
reco::PFBlockCollection::const_iterator IBC
Definition: PFBlockAlgo.h:203
IE associate(IE next, IE last, std::vector< PFBlockLink > &links)
Definition: PFBlockAlgo.cc:128
const PhotonSelectorAlgo * photonSelector_
PhotonSelector.
Definition: PFBlockAlgo.h:363
void checkMaskSize(const reco::PFRecTrackCollection &tracks, const reco::GsfPFRecTrackCollection &gsftracks, const reco::PFClusterCollection &ecals, const reco::PFClusterCollection &hcals, const reco::PFClusterCollection &hos, const reco::PFClusterCollection &hfems, const reco::PFClusterCollection &hfhads, const reco::PFClusterCollection &pss, const reco::PhotonCollection &egphh, const reco::SuperClusterCollection &sceb, const reco::SuperClusterCollection &scee, const Mask &trackMask, const Mask &gsftrackMask, const Mask &ecalMask, const Mask &hcalMask, const Mask &hoMask, const Mask &hfemMask, const Mask &hfhadMask, const Mask &psMask, const Mask &phMask, const Mask &scMask) const
#define M_PI
Definition: BFit3D.cc:3
double testLinkByVertex(const reco::PFBlockElement *elt1, const reco::PFBlockElement *elt2) const
bool isValid() const
is this point valid ?
tuple tracks
Definition: testEve_cfg.py:39
list blocks
Definition: gather_cfg.py:90
static double testHFEMAndHFHADByRecHit(const reco::PFCluster &clusterHFEM, const reco::PFCluster &clusterHFHAD, bool debug=false)
test association between HFEM and HFHAD, by rechit
key_type key() const
Accessor for product key.
Definition: Ref.h:266
bool isMultilinksValide() const
bool linkPrefilter(const reco::PFBlockElement *last, const reco::PFBlockElement *next) const
Avoid to check links when not useful.
virtual bool trackType(TrackType trType) const
std::vector< Photon > PhotonCollection
collectin of Photon objects
Definition: PhotonFwd.h:9
void findBlocks()
build blocks
Definition: PFBlockAlgo.cc:86
std::vector< int > pfcSCVec_
SC corresponding to the PF cluster.
Definition: PFBlockAlgo.h:369
virtual void process()
virtual ConversionRef convRef() const
double a
Definition: hdecay.h:121
GsfPFRecTrackRef GsftrackRefPF() const
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
Definition: PFClusterFwd.h:9
tuple cout
Definition: gather_cfg.py:121
virtual bool isLinkedToDisplacedVertex() const
A PFTrack holds several trajectory points, which basically contain the position and momentum of a tra...
volatile std::atomic< bool > shutdown_flag false
std::vector< bool > Mask
Definition: PFBlockAlgo.h:95
void setUseOptimization(bool useKDTreeTrackEcalLinker)
Definition: PFBlockAlgo.cc:66
bool bNoSuperclus_
Definition: PFBlockAlgo.h:372
bool debug_
if true, debug printouts activated
Definition: PFBlockAlgo.h:377
static double testTrackAndClusterByRecHit(const reco::PFRecTrack &track, const reco::PFCluster &cluster, bool isBrem=false, bool debug=false)
Definition: LinkByRecHit.cc:10
void setParameters(std::vector< double > &DPtovPtCut, std::vector< unsigned > &NHitCut, bool useConvBremPFRecTracks, bool useIterTracking, int nuclearInteractionsPurity, bool useEGPhotons, std::vector< double > &photonSelectionCuts, bool useSuperClusters, bool superClusterMatchByRef)
Definition: PFBlockAlgo.cc:31
std::vector< PFRecTrack > PFRecTrackCollection
collection of PFRecTrack objects
Definition: PFRecTrackFwd.h:9
bool useEGPhotons_
Flag to turn off the import of EG Photons.
Definition: PFBlockAlgo.h:338
bool useKDTreeTrackEcalLinker_
Definition: PFBlockAlgo.h:320
Definition: fakeMenu.h:4
std::vector< unsigned > NHitCut_
Number of layers crossed cut for creating atrack element.
Definition: PFBlockAlgo.h:332
const PFMultilinksType & getMultilinks() const
Block of elements.
Definition: PFBlock.h:30