CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoParticleFlow/PFTracking/plugins/PFConversionProducer.cc

Go to the documentation of this file.
00001 #include <memory>
00002 #include "RecoParticleFlow/PFTracking/plugins/PFConversionProducer.h"
00003 #include "RecoParticleFlow/PFTracking/interface/PFTrackTransformer.h"
00004 #include "DataFormats/ParticleFlowReco/interface/PFConversionFwd.h"
00005 #include "DataFormats/ParticleFlowReco/interface/PFConversion.h"
00006 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00007 #include "DataFormats/VertexReco/interface/Vertex.h"
00008 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00009 #include "FWCore/Framework/interface/ESHandle.h"
00010 #include "MagneticField/Engine/interface/MagneticField.h"
00011 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00012 #include "DataFormats/Common/interface/RefToBase.h"
00013 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00014 #include "RecoEgamma/EgammaTools/interface/ConversionLikelihoodCalculator.h"
00015 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionHitChecker.h"
00016 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00017 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00018 #include "TrackingTools/IPTools/interface/IPTools.h"
00019 
00020 typedef  std::multimap<unsigned, std::vector<unsigned> > BlockMap;
00021 using namespace std;
00022 using namespace edm;
00023 
00024 
00025 PFConversionProducer::PFConversionProducer(const ParameterSet& iConfig):
00026   pfTransformer_(0)
00027 {
00028   produces<reco::PFRecTrackCollection>();
00029   produces<reco::PFConversionCollection>();
00030 
00031   pfConversionContainer_ = 
00032     iConfig.getParameter< InputTag >("conversionCollection");
00033   vtx_h=iConfig.getParameter<edm::InputTag>("PrimaryVertexLabel");
00034 }
00035 
00036 PFConversionProducer::~PFConversionProducer()
00037 {
00038   delete pfTransformer_;
00039 }
00040 
00041 void
00042 PFConversionProducer::produce(Event& iEvent, const EventSetup& iSetup)
00043 {
00044   
00045   //create the empty collections 
00046   auto_ptr< reco::PFConversionCollection > 
00047     pfConversionColl (new reco::PFConversionCollection);
00048   auto_ptr< reco::PFRecTrackCollection > 
00049     pfRecTrackColl (new reco::PFRecTrackCollection);
00050   
00051   edm::ESHandle<TransientTrackBuilder> builder;
00052   iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", builder);
00053   TransientTrackBuilder thebuilder = *(builder.product());
00054   reco::PFRecTrackRefProd pfTrackRefProd = iEvent.getRefBeforePut<reco::PFRecTrackCollection>();
00055   Handle<reco::ConversionCollection> convCollH;
00056   iEvent.getByLabel(pfConversionContainer_, convCollH);
00057   
00058   const reco::ConversionCollection& convColl = *(convCollH.product());
00059   
00060   Handle<reco::TrackCollection> trackColl;
00061   iEvent.getByLabel(pfTrackContainer_, trackColl);
00062   Handle<reco::VertexCollection> vertex;
00063   iEvent.getByLabel(vtx_h, vertex);
00064   //Find PV for IP calculation, if there is no PV in collection than use dummy 
00065   reco::Vertex dummy;
00066   const reco::Vertex* pv=&dummy;    
00067   if (vertex.isValid()) 
00068     {
00069       pv = &*vertex->begin();
00070     } 
00071   else 
00072     { // create a dummy PV
00073       reco::Vertex::Error e;
00074       e(0, 0) = 0.0015 * 0.0015;
00075       e(1, 1) = 0.0015 * 0.0015;
00076       e(2, 2) = 15. * 15.;
00077       reco::Vertex::Point p(0, 0, 0);
00078       dummy = reco::Vertex(p, e, 0, 0, 0);   
00079     } 
00080   
00081   int idx = 0; //index of track in PFRecTrack collection 
00082   multimap<unsigned int, unsigned int> trackmap; //Map of Collections and tracks  
00083   std::vector<unsigned int> conv_coll(0);
00084    
00085   // CLEAN CONVERSION COLLECTION FOR DUPLICATES     
00086   for( unsigned int icoll1=0; icoll1 < convColl.size(); icoll1++) 
00087     { 
00088       if (( !convColl[icoll1].quality(reco::Conversion::arbitratedMergedEcalGeneral)) || (!convColl[icoll1].quality(reco::Conversion::highPurity))) continue;
00089       
00090       bool greater_prob=false;
00091       std::vector<edm::RefToBase<reco::Track> > tracksRefColl1 = convColl[icoll1].tracks();      
00092       for(unsigned it1 = 0; it1 < tracksRefColl1.size(); it1++)
00093         {
00094           reco::TrackRef trackRef1 = (tracksRefColl1[it1]).castTo<reco::TrackRef>();
00095          
00096           for( unsigned int icoll2=0; icoll2 < convColl.size(); icoll2++) 
00097             {
00098               if(icoll1==icoll2)continue;
00099               if (( !convColl[icoll2].quality(reco::Conversion::arbitratedMergedEcalGeneral)) || (!convColl[icoll2].quality(reco::Conversion::highPurity))) continue;
00100               std::vector<edm::RefToBase<reco::Track> > tracksRefColl2 = convColl[icoll2].tracks();     
00101               for(unsigned it2 = 0; it2 < tracksRefColl2.size(); it2++)
00102                 {
00103                   reco::TrackRef trackRef2 = (tracksRefColl2[it2]).castTo<reco::TrackRef>();
00104                   double like1=-999;
00105                   double like2=-999;
00106                   //number of shared hits
00107                   int shared=0;
00108                   for(trackingRecHit_iterator iHit1=trackRef1->recHitsBegin(); iHit1!=trackRef1->recHitsEnd(); iHit1++) 
00109                     {
00110                       const TrackingRecHit *h_1=iHit1->get();
00111                       if(h_1->isValid()){                 
00112                         for(trackingRecHit_iterator iHit2=trackRef2->recHitsBegin(); iHit2!=trackRef2->recHitsEnd(); iHit2++)
00113                           {
00114                             const TrackingRecHit *h_2=iHit2->get();
00115                             if(h_2->isValid() && h_1->sharesInput(h_2, TrackingRecHit::some))shared++;//count number of shared hits
00116                           }
00117                       }
00118                     }             
00119                   float frac=0;
00120                   //number of valid hits in tracks that are duplicates
00121                   float size1=trackRef1->found();
00122                   float size2=trackRef2->found();
00123                   //divide number of shared hits by the total number of hits for the track with less hits
00124                   if(size1>size2)frac=(double)shared/size2;
00125                   else frac=(double)shared/size1;
00126                   if(frac>0.9)
00127                     {
00128                       like1=ChiSquaredProbability(convColl[icoll1].conversionVertex().chi2(), convColl[icoll1].conversionVertex().ndof());
00129                       like2=ChiSquaredProbability(convColl[icoll2].conversionVertex().chi2(), convColl[icoll2].conversionVertex().ndof());
00130                     }
00131                   if(like2>like1)
00132                     {greater_prob=true;  break;}
00133                 }//end loop over tracks in collection 2
00134 
00135               if(greater_prob)break; //if a duplicate track is found in a collection with greater Chi^2 probability for Vertex fit then break out of comparison loop
00136             }//end loop over collection 2 checking
00137           if(greater_prob)break;//if a duplicate track is found in a collection with greater Chi^2 probability for Vertex fit then one does not need to check the other track the collection will not be stored
00138         } //end loop over tracks in collection 1
00139       if(!greater_prob)conv_coll.push_back(icoll1);
00140     }//end loop over collection 1
00141   
00142   //Finally fill empty collections
00143   for(unsigned iColl=0; iColl<conv_coll.size(); iColl++)
00144     {
00145       unsigned int collindex=conv_coll[iColl];
00146       //std::cout<<"Filling this collection"<<collindex<<endl;
00147       std::vector<reco::PFRecTrackRef> pfRecTkcoll;     
00148       
00149       std::vector<edm::RefToBase<reco::Track> > tracksRefColl = convColl[collindex].tracks();     
00150       // convert the secondary tracks
00151       for(unsigned it = 0; it < tracksRefColl.size(); it++)
00152         {
00153           reco::TrackRef trackRef = (tracksRefColl[it]).castTo<reco::TrackRef>();      
00154           reco::PFRecTrack pfRecTrack( trackRef->charge(), 
00155                                        reco::PFRecTrack::KF, 
00156                                        trackRef.key(), 
00157                                        trackRef );             
00158           //std::cout<<"Track Pt "<<trackRef->pt()<<std::endl;
00159           Trajectory FakeTraj;
00160           bool valid = pfTransformer_->addPoints( pfRecTrack, *trackRef, FakeTraj);
00161           if(valid) 
00162             {
00163               double stip=-999;
00164               const reco::PFTrajectoryPoint& atECAL=pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance);
00165               //if extrapolation to ECAL is valid then calculate STIP
00166               if(atECAL.isValid())
00167                 {
00168                   GlobalVector direction(pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance).position().x(),
00169                                          pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance).position().y(), 
00170                                          pfRecTrack.extrapolatedPoint(reco::PFTrajectoryPoint::ECALEntrance).position().z());
00171                   stip = IPTools::signedTransverseImpactParameter(thebuilder.build(*trackRef), direction, *pv).second.significance();
00172                 }
00173               pfRecTrack.setSTIP(stip);     
00174               pfRecTkcoll.push_back(reco::PFRecTrackRef( pfTrackRefProd, idx++));         
00175               pfRecTrackColl->push_back(pfRecTrack);        
00176             }
00177         }//end loop over tracks
00178       //store reference to the Conversion collection
00179       reco::ConversionRef niRef(convCollH, collindex);
00180       pfConversionColl->push_back( reco::PFConversion( niRef, pfRecTkcoll ));
00181     }//end loop over collections
00182   iEvent.put(pfRecTrackColl);
00183   iEvent.put(pfConversionColl);    
00184 }
00185   
00186 // ------------ method called once each job just before starting event loop  ------------
00187 void 
00188 PFConversionProducer::beginRun(edm::Run& run,
00189                                const EventSetup& iSetup)
00190 {
00191   ESHandle<MagneticField> magneticField;
00192   iSetup.get<IdealMagneticFieldRecord>().get(magneticField);
00193   pfTransformer_= new PFTrackTransformer(math::XYZVector(magneticField->inTesla(GlobalPoint(0,0,0))));
00194   pfTransformer_->OnlyProp();
00195 }
00196 
00197 // ------------ method called once each job just after ending the event loop  ------------
00198 void 
00199 PFConversionProducer::endRun() {
00200   delete pfTransformer_;
00201 }