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