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