CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/src/CommonTools/RecoUtils/src/PF_PU_AssoMapAlgos.cc

Go to the documentation of this file.
00001 #include "CommonTools/RecoUtils/interface/PF_PU_AssoMapAlgos.h"
00002 
00003 #include <vector>
00004 #include <string>
00005 #include <sstream> 
00006 #include <algorithm>
00007 
00008 #include "DataFormats/Common/interface/AssociationMap.h"
00009 #include "DataFormats/Common/interface/Handle.h"
00010 #include "DataFormats/Common/interface/OneToManyWithQuality.h"
00011 #include "DataFormats/Common/interface/OneToManyWithQualityGeneric.h"
00012 #include "DataFormats/Common/interface/View.h"
00013 #include "DataFormats/Math/interface/deltaR.h"
00014 
00015 #include "DataFormats/TrackReco/interface/Track.h"
00016 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00017 #include "DataFormats/TrackReco/interface/TrackBase.h"
00018 #include "DataFormats/VertexReco/interface/Vertex.h"
00019 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00020 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00021 #include "DataFormats/EgammaReco/interface/ElectronSeedFwd.h"
00022 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00023 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
00024 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
00025 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00026 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
00027 #include "DataFormats/EgammaCandidates/interface/ConversionFwd.h"
00028 #include "DataFormats/Candidate/interface/VertexCompositeCandidate.h"
00029 #include "DataFormats/Candidate/interface/VertexCompositeCandidateFwd.h"
00030 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertex.h"
00031 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertexFwd.h"
00032 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
00033 
00034 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00035 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
00036 #include "RecoVertex/VertexTools/interface/VertexDistance3D.h"
00037 #include "RecoVertex/VertexTools/interface/VertexDistanceXY.h"
00038 #include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h"
00039 
00040 
00041 #include "TrackingTools/IPTools/interface/IPTools.h"
00042 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00043 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00044 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00045 #include "RecoEgamma/EgammaTools/interface/ConversionTools.h"
00046 #include "RecoVertex/KinematicFit/interface/KinematicParticleVertexFitter.h"
00047 #include "RecoVertex/KinematicFit/interface/KinematicParticleFitter.h"
00048 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicParticle.h"
00049 #include "RecoVertex/KinematicFitPrimitives/interface/KinematicParticleFactoryFromTransientTrack.h"
00050 #include "RecoVertex/KinematicFitPrimitives/interface/RefCountedKinematicParticle.h"
00051 
00052 #include "TMath.h"
00053    
00054 using namespace edm;
00055 using namespace std;
00056 using namespace reco;
00057 
00058 const double kMass = 0.49765;
00059 const double lamMass = 1.11568;
00060 
00061   typedef AssociationMap<OneToManyWithQuality< VertexCollection, TrackCollection, float> > TrackVertexAssMap;
00062 
00063   typedef pair<TrackRef, float> TrackQualityPair;
00064   typedef vector< TrackQualityPair > TrackQualityPairVector;
00065   typedef pair<VertexRef, TrackQualityPair> VertexTrackQuality;
00066 
00067   typedef pair <VertexRef, float>  VertexPtsumPair;
00068   typedef vector< VertexPtsumPair > VertexPtsumVector;
00069 
00070   typedef math::XYZTLorentzVector LorentzVector;
00071 
00072 /*************************************************************************************/
00073 /* dedicated constructor for the algorithms                                          */ 
00074 /*************************************************************************************/
00075 
00076 PF_PU_AssoMapAlgos::PF_PU_AssoMapAlgos(const edm::ParameterSet& iConfig)
00077   : maxNumWarnings_(3),
00078     numWarnings_(0)
00079 {
00080 
00081         input_VertexCollection_= iConfig.getParameter<InputTag>("VertexCollection");
00082 
00083         input_PtCut_ = iConfig.getParameter<double>("TrackPtCut");
00084 
00085         input_BeamSpot_= iConfig.getParameter<InputTag>("BeamSpot");
00086 
00087         input_doReassociation_= iConfig.getParameter<bool>("doReassociation");
00088         cleanedColls_ = iConfig.getParameter<bool>("GetCleanedCollections");
00089   
00090         ConversionsCollection_= iConfig.getParameter<InputTag>("ConversionsCollection");
00091 
00092         KshortCollection_= iConfig.getParameter<InputTag>("V0KshortCollection");
00093         LambdaCollection_= iConfig.getParameter<InputTag>("V0LambdaCollection");
00094 
00095         NIVertexCollection_= iConfig.getParameter<InputTag>("NIVertexCollection");
00096 
00097         UseBeamSpotCompatibility_= iConfig.getUntrackedParameter<bool>("UseBeamSpotCompatibility", false);
00098         input_BSCut_ = iConfig.getParameter<double>("BeamSpotCompatibilityCut");
00099 
00100         input_FinalAssociation_= iConfig.getUntrackedParameter<int>("FinalAssociation", 0);
00101 
00102         ignoremissingpfcollection_ = iConfig.getParameter<bool>("ignoreMissingCollection");
00103 
00104         input_nTrack_ = iConfig.getParameter<double>("nTrackWeight");
00105 
00106 
00107         /****************************************/
00108         /* Printing the configuration of the AM */
00109         /****************************************/
00110 
00111 
00112         string logOutput;
00113         ostringstream convert;  
00114 
00115         logOutput+= "0. Step: PT-Cut is ";
00116         convert << input_PtCut_;        
00117         logOutput+= convert.str();
00118 
00119         logOutput+= "\n1. Step: Track weight association\n";
00120 
00121         if ( UseBeamSpotCompatibility_ ){
00122           logOutput+= "With BSCompatibility check\n";
00123           goto ending;
00124         }else{
00125           logOutput+= "Without BSCompatibility check\n";
00126         }
00127         if ( input_doReassociation_ ){
00128           logOutput+= "With Reassociation\n";
00129         }else{
00130           logOutput+= "Without Reassociation\n";
00131         }
00132         logOutput+= "The final association is: ";
00133         switch (input_FinalAssociation_) {
00134         
00135           case 1:{
00136             logOutput+= "ClosestInZ with weight ";
00137             convert << input_nTrack_;
00138             logOutput+= convert.str();
00139             logOutput+= "\n";
00140             goto ending;
00141           }
00142           
00143           case 2:{
00144             logOutput+= "ClosestIn3D with weight ";
00145             convert << input_nTrack_;
00146             logOutput+= convert.str();
00147             logOutput+= "\n";
00148             goto ending;
00149           }
00150           
00151           default:{
00152             logOutput+= "AlwaysFirst\n";
00153             goto ending;
00154           }
00155 
00156         }
00157 
00158         ending:
00159         logOutput+="\n";
00160 
00161         LogInfo("PF_PU_AssoMap::PF_PU_AssoMapAlgos")
00162           << logOutput << endl; 
00163 
00164 }
00165 
00166 /*************************************************************************************/
00167 /* get all needed collections at the beginning                                       */ 
00168 /*************************************************************************************/
00169 
00170 bool 
00171 PF_PU_AssoMapAlgos::GetInputCollections(edm::Event& iEvent, const edm::EventSetup& iSetup)
00172 {
00173   
00174         //get the offline beam spot
00175         iEvent.getByLabel(input_BeamSpot_, beamspotH);
00176 
00177         //get the conversion collection for the gamma conversions
00178         iEvent.getByLabel(ConversionsCollection_, convCollH);
00179         cleanedConvCollP = PF_PU_AssoMapAlgos::GetCleanedConversions(convCollH,beamspotH,cleanedColls_);
00180 
00181         //get the vertex composite candidate collection for the Kshort's
00182         iEvent.getByLabel(KshortCollection_, vertCompCandCollKshortH);
00183         cleanedKshortCollP = PF_PU_AssoMapAlgos::GetCleanedKshort(vertCompCandCollKshortH,beamspotH,cleanedColls_);
00184   
00185         //get the vertex composite candidate collection for the Lambda's
00186         iEvent.getByLabel(LambdaCollection_, vertCompCandCollLambdaH);
00187         cleanedLambdaCollP = PF_PU_AssoMapAlgos::GetCleanedLambda(vertCompCandCollLambdaH,beamspotH,cleanedColls_);
00188   
00189         //get the displaced vertex collection for nuclear interactions
00190         //create a new bool, false if no displaced vertex collection is in the event, mostly for AOD
00191         missingColls = false;
00192         if(!iEvent.getByLabel(NIVertexCollection_,displVertexCollH)){
00193           if (ignoremissingpfcollection_){
00194 
00195             missingColls = true; 
00196 
00197             if ( numWarnings_ < maxNumWarnings_ ) {
00198               edm::LogWarning("PF_PU_AssoMap::GetInputCollections")
00199                 << "No Extra objects available in input file --> skipping reconstruction of photon conversions && displaced vertices !!" << std::endl;
00200               ++numWarnings_;
00201             }
00202 
00203           }
00204         } else {
00205 
00206             cleanedNICollP = PF_PU_AssoMapAlgos::GetCleanedNI(displVertexCollH,beamspotH,true);
00207 
00208         }
00209           
00210         //get the input vertex collection
00211         iEvent.getByLabel(input_VertexCollection_, vtxcollH);
00212 
00213         iSetup.get<IdealMagneticFieldRecord>().get(bFieldH);
00214 
00215         //return true if there is at least one reconstructed vertex in the collection
00216         return (vtxcollH->size()!=0);
00217 
00218 }
00219 
00220 /*************************************************************************************/
00221 /* do the association for a certain track                                            */ 
00222 /*************************************************************************************/
00223 
00224 VertexTrackQuality 
00225 PF_PU_AssoMapAlgos::DoTrackAssociation(const TrackRef& trackref, const edm::EventSetup& iSetup)
00226 {
00227 
00228         TransientTrack transtrk(trackref, &(*bFieldH) );
00229         transtrk.setBeamSpot(*beamspotH);
00230         transtrk.setES(iSetup);
00231 
00232         VertexTrackQuality VtxTrkQualAss;
00233 
00234         //Step 0:
00235         //Check for high pt tracks and associate to first vertex
00236         if ( trackref->pt()>=input_PtCut_ ){
00237         
00238             pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *(VertexRef(vtxcollH, 0)) );
00239             VtxTrkQualAss = make_pair(VertexRef(vtxcollH, 0), make_pair(trackref, IpPair.second.value()));
00240             return VtxTrkQualAss;
00241 
00242         }
00243 
00244         // Step 1: First round of association:
00245         // Find the vertex with the highest track-to-vertex association weight 
00246         VtxTrkQualAss = PF_PU_AssoMapAlgos::TrackWeightAssociation(trackref, vtxcollH);
00247 
00248         if ( VtxTrkQualAss.second.second == 0. ) return VtxTrkQualAss;
00249 
00250         //Step 1/2: Check for BeamSpot comptibility
00251         //If a track's vertex is compatible with the BeamSpot
00252         //look for the closest vertex in z, 
00253         //if not associate the track always to the first vertex
00254         if ( UseBeamSpotCompatibility_ ){
00255 
00256           if (PF_PU_AssoMapAlgos::CheckBeamSpotCompability(transtrk, input_BSCut_) ){
00257             VtxTrkQualAss = PF_PU_AssoMapAlgos::AssociateClosestZ(trackref, vtxcollH, input_nTrack_);
00258           } else {
00259             pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *(VertexRef(vtxcollH, 0)) );
00260             VtxTrkQualAss = make_pair(VertexRef(vtxcollH, 0), make_pair(trackref, IpPair.second.value()));
00261           }
00262 
00263           return VtxTrkQualAss;
00264 
00265         }
00266 
00267         // Step 2: Reassociation
00268         // Second round of association:
00269         // In case no vertex with track-to-vertex association weight > 1.e-5 is found,
00270         // check the track originates from a neutral hadron decay, photon conversion or nuclear interaction
00271 
00272         if ((input_doReassociation_) && (!missingColls)) {
00273 
00274           // Test if the track comes from a photon conversion:
00275           // If so, try to find the vertex of the mother particle
00276           Conversion gamma;
00277           if ( PF_PU_AssoMapAlgos::ComesFromConversion(trackref, *cleanedConvCollP, &gamma) ){
00278             VtxTrkQualAss = PF_PU_AssoMapAlgos::FindConversionVertex(trackref, gamma, bFieldH, iSetup, beamspotH, vtxcollH, input_nTrack_);
00279             return VtxTrkQualAss;
00280           }
00281 
00282           // Test if the track comes from a Kshort or Lambda decay:
00283           // If so, reassociate the track to the vertex of the V0
00284           VertexCompositeCandidate V0;
00285           if ( PF_PU_AssoMapAlgos::ComesFromV0Decay(trackref, *cleanedKshortCollP, *cleanedLambdaCollP, &V0) ) {
00286             VtxTrkQualAss = PF_PU_AssoMapAlgos::FindV0Vertex(trackref, V0, bFieldH, iSetup, beamspotH, vtxcollH, input_nTrack_);        
00287             return VtxTrkQualAss;
00288           }
00289 
00290           // Test if the track comes from a nuclear interaction:
00291           // If so, reassociate the track to the vertex of the incoming particle 
00292           PFDisplacedVertex displVtx;
00293           if ( PF_PU_AssoMapAlgos::ComesFromNI(trackref, *cleanedNICollP, &displVtx) ){
00294             VtxTrkQualAss = PF_PU_AssoMapAlgos::FindNIVertex(trackref, displVtx, bFieldH, iSetup, beamspotH, vtxcollH, input_nTrack_);
00295             return VtxTrkQualAss;
00296           }
00297 
00298         }
00299 
00300         // Step 3: Final association
00301         // If no vertex is found with track-to-vertex association weight > 1.e-5
00302         // and no reassociation was done do the final association 
00303         // look for the closest vertex in 3D or in z/longitudinal distance
00304         // or associate the track always to the first vertex (default)
00305 
00306         switch (input_FinalAssociation_) {
00307           
00308           case 1:{
00309             return PF_PU_AssoMapAlgos::AssociateClosestZ(trackref, vtxcollH, input_nTrack_);
00310           }
00311           
00312           case 2:{
00313             return PF_PU_AssoMapAlgos::AssociateClosest3D(trackref, vtxcollH, bFieldH, iSetup, beamspotH, input_nTrack_);
00314           }
00315           
00316           default:{
00317             pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *(VertexRef(vtxcollH, 0)) );
00318             VtxTrkQualAss = make_pair(VertexRef(vtxcollH, 0), make_pair(trackref, IpPair.second.value()));
00319           }
00320 
00321         }
00322 
00323         return VtxTrkQualAss;
00324 
00325 }
00326 
00327 /*************************************************************************************/
00328 /* returns the first vertex of the vertex collection                                 */ 
00329 /*************************************************************************************/
00330 
00331 VertexRef  
00332 PF_PU_AssoMapAlgos::GetFirstVertex() 
00333 {
00334 
00335         VertexRef vtxref_tmp(vtxcollH,0);
00336 
00337         return vtxref_tmp;
00338 
00339 }
00340 
00341 /****************************************************************************************/
00342 /* function to calculate the deltaR between a vector and a vector connecting two points */ 
00343 /****************************************************************************************/
00344 
00345 double
00346 PF_PU_AssoMapAlgos::dR(math::XYZPoint vtx_pos, math::XYZVector vtx_mom, edm::Handle<reco::BeamSpot> bsH)
00347 {
00348 
00349         double bs_x = bsH->x0();
00350         double bs_y = bsH->y0();
00351         double bs_z = bsH->z0();
00352 
00353         double connVec_x = vtx_pos.x() - bs_x;
00354         double connVec_y = vtx_pos.y() - bs_y;
00355         double connVec_z = vtx_pos.z() - bs_z;
00356 
00357         double connVec_r = sqrt(connVec_x*connVec_x + connVec_y*connVec_y + connVec_z*connVec_z);
00358         double connVec_theta = acos(connVec_z*1./connVec_r);
00359 
00360         double connVec_eta = -1.*log(tan(connVec_theta*1./2.));
00361         double connVec_phi = atan2(connVec_y,connVec_x);
00362 
00363         return deltaR(vtx_mom.eta(),vtx_mom.phi(),connVec_eta,connVec_phi);
00364     
00365 }
00366 
00367 /*************************************************************************************/
00368 /* function to find the vertex with the highest TrackWeight for a certain track      */ 
00369 /*************************************************************************************/
00370 
00371 VertexTrackQuality 
00372 PF_PU_AssoMapAlgos::TrackWeightAssociation(const TrackRef&  trackRef, Handle<VertexCollection> vtxcollH) 
00373 {
00374 
00375         VertexRef bestvertexref(vtxcollH,0);            
00376         float bestweight = 0.;
00377 
00378         const TrackBaseRef& trackbaseRef = TrackBaseRef(trackRef);
00379 
00380         //loop over all vertices in the vertex collection
00381         for(unsigned int index_vtx=0;  index_vtx<vtxcollH->size(); ++index_vtx){
00382 
00383           VertexRef vertexref(vtxcollH,index_vtx);
00384 
00385           //get the most probable vertex for the track
00386           float weight = vertexref->trackWeight(trackbaseRef);
00387           if(weight>bestweight){
00388             bestweight = weight;
00389             bestvertexref = vertexref;
00390           } 
00391 
00392         }
00393 
00394         if ( bestweight>1.e-5 ){ 
00395           //found a vertex with a track weight
00396           //return weight == 0., so that all following steps won't be applied
00397           return make_pair(bestvertexref,make_pair(trackRef,0.));
00398         } else { 
00399           //found no vertex with a track weight
00400           //return weight == 1., so that secondary and final association will be applied
00401           return make_pair(bestvertexref,make_pair(trackRef,1.));
00402         }
00403 
00404 }
00405 
00406 
00407 /*******************************************************************************************/
00408 /* function to associate the track to the closest vertex in z/longitudinal distance        */ 
00409 /*******************************************************************************************/
00410 
00411 VertexTrackQuality
00412 PF_PU_AssoMapAlgos::AssociateClosestZ(TrackRef trackref, Handle<VertexCollection> vtxcollH, double tWeight)
00413 {
00414 
00415         double ztrack = trackref->vertex().z();
00416 
00417         VertexRef bestvertexref(vtxcollH, 0);
00418 
00419         double dzmin = 1e5;
00420         double realDistance = 1e5;
00421           
00422         //loop over all vertices with a good quality in the vertex collection
00423         for(unsigned int index_vtx=0;  index_vtx<vtxcollH->size(); ++index_vtx){
00424 
00425           VertexRef vertexref(vtxcollH,index_vtx);
00426 
00427           int nTracks = vertexref->tracksSize();
00428 
00429           double z_distance = fabs(ztrack - vertexref->z());
00430           double dz = z_distance-tWeight*nTracks;       
00431 
00432           if(dz<dzmin) {
00433             dzmin = dz; 
00434             realDistance = z_distance; 
00435             bestvertexref = vertexref;
00436           }
00437         
00438         }       
00439 
00440         return make_pair(bestvertexref, make_pair(trackref, realDistance));
00441 }
00442 
00443 
00444 /*************************************************************************************/
00445 /* function to find the closest vertex in 3D for a certain track                     */ 
00446 /*************************************************************************************/
00447 
00448 VertexRef 
00449 PF_PU_AssoMapAlgos::FindClosest3D(TransientTrack transtrk, Handle<VertexCollection> vtxcollH, double tWeight)
00450 {
00451 
00452         VertexRef foundVertexRef(vtxcollH, 0);
00453 
00454         double d3min = 1e5;
00455           
00456         //loop over all vertices with a good quality in the vertex collection
00457         for(unsigned int index_vtx=0;  index_vtx<vtxcollH->size(); ++index_vtx){
00458 
00459           VertexRef vertexref(vtxcollH,index_vtx);
00460 
00461           double nTracks = sqrt(vertexref->tracksSize());
00462 
00463           double distance = 1e5;                
00464           pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *vertexref);
00465  
00466           if(IpPair.first)
00467             distance = IpPair.second.value();
00468 
00469           double weightedDistance = distance-tWeight*nTracks;   
00470 
00471           if(weightedDistance<d3min) {
00472             d3min = weightedDistance; 
00473             foundVertexRef = vertexref;
00474           }
00475         
00476         }
00477 
00478         return foundVertexRef;
00479 }
00480 
00481 
00482 /*******************************************************************************************/
00483 /* function to associate the track to the closest vertex in 3D                             */ 
00484 /*******************************************************************************************/
00485 
00486 VertexTrackQuality
00487 PF_PU_AssoMapAlgos::AssociateClosest3D(TrackRef trackref, Handle<VertexCollection> vtxcollH, ESHandle<MagneticField> bFieldH, const EventSetup& iSetup, Handle<BeamSpot> bsH, double tWeight)
00488 {
00489 
00490         TransientTrack transtrk(trackref, &(*bFieldH) );
00491         transtrk.setBeamSpot(*bsH);
00492         transtrk.setES(iSetup);
00493 
00494         VertexRef bestvertexref = FindClosest3D(transtrk, vtxcollH, tWeight);
00495 
00496         pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *bestvertexref); 
00497 
00498         return make_pair(bestvertexref, make_pair(trackref, IpPair.second.value()));
00499 }
00500 
00501 
00502 /*************************************************************************************/
00503 /* function to filter the conversion collection                                      */ 
00504 /*************************************************************************************/
00505 
00506 auto_ptr<ConversionCollection> 
00507 PF_PU_AssoMapAlgos::GetCleanedConversions(edm::Handle<reco::ConversionCollection> convCollH, Handle<BeamSpot> bsH, bool cleanedColl)
00508 {
00509         auto_ptr<ConversionCollection> cleanedConvColl(new ConversionCollection() );
00510 
00511         for (unsigned int convcoll_idx=0; convcoll_idx<convCollH->size(); convcoll_idx++){
00512 
00513           ConversionRef convref(convCollH,convcoll_idx);
00514 
00515           if(!cleanedColl){   
00516             cleanedConvColl->push_back(*convref);
00517             continue;
00518           }
00519 
00520           if( (convref->nTracks()==2) &&
00521               (fabs(convref->pairInvariantMass())<=0.1) ){
00522     
00523             cleanedConvColl->push_back(*convref);
00524 
00525           }
00526 
00527         }
00528 
00529         return cleanedConvColl;
00530 
00531 }
00532 
00533 
00534 /*************************************************************************************/
00535 /* function to find out if the track comes from a gamma conversion                   */ 
00536 /*************************************************************************************/
00537 
00538 bool
00539 PF_PU_AssoMapAlgos::ComesFromConversion(const TrackRef trackref, ConversionCollection cleanedConvColl, Conversion* gamma)
00540 {
00541 
00542         for(unsigned int convcoll_ite=0; convcoll_ite<cleanedConvColl.size(); convcoll_ite++){
00543 
00544           if(ConversionTools::matchesConversion(trackref,cleanedConvColl.at(convcoll_ite))){
00545         
00546             *gamma = cleanedConvColl.at(convcoll_ite);
00547             return true;
00548 
00549           }
00550 
00551         }
00552 
00553         return false;
00554 }
00555 
00556 
00557 /*************************************************************************************/
00558 /* function to find the closest vertex in z for a track from a conversion            */ 
00559 /*************************************************************************************/
00560 
00561 VertexTrackQuality
00562 PF_PU_AssoMapAlgos::FindConversionVertex(const reco::TrackRef trackref, reco::Conversion gamma, ESHandle<MagneticField> bFieldH, const EventSetup& iSetup, edm::Handle<reco::BeamSpot> bsH, edm::Handle<reco::VertexCollection> vtxcollH, double tWeight)
00563 { 
00564 
00565         math::XYZPoint conv_pos = gamma.conversionVertex().position();
00566 
00567         math::XYZVector conv_mom(gamma.refittedPair4Momentum().x(),
00568                                  gamma.refittedPair4Momentum().y(),
00569                                  gamma.refittedPair4Momentum().z());
00570 
00571         Track photon(trackref->chi2(), trackref->ndof(), conv_pos, conv_mom, 0, trackref->covariance());
00572 
00573         TransientTrack transpho(photon, &(*bFieldH) );
00574         transpho.setBeamSpot(*bsH);
00575         transpho.setES(iSetup);
00576 
00577         VertexRef foundVertexRef = FindClosest3D(transpho, vtxcollH, tWeight);
00578 
00579         TransientTrack transtrk(trackref, &(*bFieldH) );
00580         transtrk.setBeamSpot(*bsH);
00581         transtrk.setES(iSetup);
00582 
00583         pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *foundVertexRef);        
00584 
00585         return make_pair(foundVertexRef, make_pair(trackref, -1.*IpPair.second.value()));
00586 
00587 }
00588 
00589 
00590 /*************************************************************************************/
00591 /* function to filter the Kshort collection                                          */ 
00592 /*************************************************************************************/
00593 
00594 auto_ptr<VertexCompositeCandidateCollection>
00595 PF_PU_AssoMapAlgos::GetCleanedKshort(Handle<VertexCompositeCandidateCollection> KshortsH, Handle<BeamSpot> bsH, bool cleanedColl)
00596 {
00597 
00598         auto_ptr<VertexCompositeCandidateCollection> cleanedKaonColl(new VertexCompositeCandidateCollection() );
00599 
00600         for (unsigned int kscoll_idx=0; kscoll_idx<KshortsH->size(); kscoll_idx++){
00601 
00602           VertexCompositeCandidateRef ksref(KshortsH,kscoll_idx);
00603 
00604           if(!cleanedColl){   
00605             cleanedKaonColl->push_back(*ksref);
00606             continue;
00607           }
00608 
00609           VertexDistance3D distanceComputer;
00610 
00611           GlobalPoint dec_pos = RecoVertex::convertPos(ksref->vertex());    
00612 
00613           GlobalError decayVertexError = GlobalError(ksref->vertexCovariance(0,0), ksref->vertexCovariance(0,1), ksref->vertexCovariance(1,1), ksref->vertexCovariance(0,2), ksref->vertexCovariance(1,2), ksref->vertexCovariance(2,2));
00614         
00615           math::XYZVector dec_mom(ksref->momentum().x(),
00616                                   ksref->momentum().y(),
00617                                   ksref->momentum().z());    
00618 
00619           GlobalPoint bsPosition = RecoVertex::convertPos(bsH->position());
00620           GlobalError bsError = RecoVertex::convertError(bsH->covariance3D());
00621       
00622           double kaon_significance = (distanceComputer.distance(VertexState(bsPosition,bsError), VertexState(dec_pos, decayVertexError))).significance();
00623 
00624           if ((ksref->vertex().rho()>=3.) &&
00625               (ksref->vertexNormalizedChi2()<=3.) &&
00626               (fabs(ksref->mass() - kMass)<=0.01) &&
00627               (kaon_significance>15.) &&
00628               (PF_PU_AssoMapAlgos::dR(ksref->vertex(),dec_mom,bsH)<=0.3) ){
00629   
00630             cleanedKaonColl->push_back(*ksref);
00631 
00632           }
00633 
00634         }
00635 
00636         return cleanedKaonColl;
00637 
00638 }
00639 
00640 
00641 /*************************************************************************************/
00642 /* function to filter the Lambda collection                                          */ 
00643 /*************************************************************************************/
00644 
00645 auto_ptr<VertexCompositeCandidateCollection>
00646 PF_PU_AssoMapAlgos::GetCleanedLambda(Handle<VertexCompositeCandidateCollection> LambdasH, Handle<BeamSpot> bsH, bool cleanedColl)
00647 {
00648 
00649         auto_ptr<VertexCompositeCandidateCollection> cleanedLambdaColl(new VertexCompositeCandidateCollection() );
00650 
00651         for (unsigned int lambdacoll_idx=0; lambdacoll_idx<LambdasH->size(); lambdacoll_idx++){
00652 
00653           VertexCompositeCandidateRef lambdaref(LambdasH,lambdacoll_idx);
00654 
00655           if(!cleanedColl){   
00656             cleanedLambdaColl->push_back(*lambdaref);
00657             continue;
00658           }
00659 
00660           VertexDistance3D distanceComputer;
00661 
00662           GlobalPoint dec_pos = RecoVertex::convertPos(lambdaref->vertex());    
00663 
00664           GlobalError decayVertexError = GlobalError(lambdaref->vertexCovariance(0,0), lambdaref->vertexCovariance(0,1), lambdaref->vertexCovariance(1,1), lambdaref->vertexCovariance(0,2), lambdaref->vertexCovariance(1,2), lambdaref->vertexCovariance(2,2));
00665         
00666           math::XYZVector dec_mom(lambdaref->momentum().x(),
00667                                   lambdaref->momentum().y(),
00668                                   lambdaref->momentum().z());    
00669 
00670           GlobalPoint bsPosition = RecoVertex::convertPos(bsH->position());
00671           GlobalError bsError = RecoVertex::convertError(bsH->covariance3D());
00672       
00673           double lambda_significance = (distanceComputer.distance(VertexState(bsPosition,bsError), VertexState(dec_pos, decayVertexError))).significance();
00674 
00675           if ((lambdaref->vertex().rho()>=3.) &&
00676               (lambdaref->vertexNormalizedChi2()<=3.) &&
00677               (fabs(lambdaref->mass() - lamMass)<=0.005) &&
00678               (lambda_significance>15.) &&
00679               (PF_PU_AssoMapAlgos::dR(lambdaref->vertex(),dec_mom,bsH)<=0.3) ){
00680   
00681             cleanedLambdaColl->push_back(*lambdaref);
00682 
00683           }
00684 
00685         }
00686 
00687         return cleanedLambdaColl;
00688 
00689 }
00690 
00691 /*************************************************************************************/
00692 /* function to find out if the track comes from a V0 decay                           */ 
00693 /*************************************************************************************/
00694 
00695 bool
00696 PF_PU_AssoMapAlgos::ComesFromV0Decay(const TrackRef trackref, VertexCompositeCandidateCollection cleanedKshort, VertexCompositeCandidateCollection cleanedLambda, VertexCompositeCandidate* V0)
00697 {
00698 
00699         //the part for the reassociation of particles from Kshort decays
00700         for(VertexCompositeCandidateCollection::const_iterator iKS=cleanedKshort.begin(); iKS!=cleanedKshort.end(); iKS++){
00701 
00702           const RecoChargedCandidate *dauCand1 = dynamic_cast<const RecoChargedCandidate*>(iKS->daughter(0));
00703           TrackRef dauTk1 = dauCand1->track();
00704           const RecoChargedCandidate *dauCand2 = dynamic_cast<const RecoChargedCandidate*>(iKS->daughter(1));
00705           TrackRef dauTk2 = dauCand2->track();
00706 
00707           if((trackref==dauTk1) || (trackref==dauTk2)){
00708           
00709             *V0 = *iKS; 
00710             return true;
00711 
00712           }
00713 
00714         }
00715 
00716         //the part for the reassociation of particles from Lambda decays
00717         for(VertexCompositeCandidateCollection::const_iterator iLambda=cleanedLambda.begin(); iLambda!=cleanedLambda.end(); iLambda++){
00718 
00719           const RecoChargedCandidate *dauCand1 = dynamic_cast<const RecoChargedCandidate*>(iLambda->daughter(0));
00720           TrackRef dauTk1 = dauCand1->track();
00721           const RecoChargedCandidate *dauCand2 = dynamic_cast<const RecoChargedCandidate*>(iLambda->daughter(1));
00722           TrackRef dauTk2 = dauCand2->track();
00723 
00724           if((trackref==dauTk1) || (trackref==dauTk2)){
00725           
00726             *V0 = *iLambda; 
00727             return true;
00728 
00729           }
00730 
00731         }
00732 
00733         return false;
00734 }
00735 
00736 
00737 /*************************************************************************************/
00738 /* function to find the closest vertex in z for a track from a V0                    */ 
00739 /*************************************************************************************/
00740 
00741 VertexTrackQuality
00742 PF_PU_AssoMapAlgos::FindV0Vertex(const TrackRef trackref, VertexCompositeCandidate V0_vtx, ESHandle<MagneticField> bFieldH, const EventSetup& iSetup, Handle<BeamSpot> bsH, Handle<VertexCollection> vtxcollH, double tWeight)
00743 { 
00744 
00745         math::XYZPoint dec_pos = V0_vtx.vertex();
00746 
00747         math::XYZVector dec_mom(V0_vtx.momentum().x(),
00748                                 V0_vtx.momentum().y(),
00749                                 V0_vtx.momentum().z());
00750 
00751         Track V0(trackref->chi2(), trackref->ndof(), dec_pos, dec_mom, 0, trackref->covariance());
00752 
00753         TransientTrack transV0(V0, &(*bFieldH) );
00754         transV0.setBeamSpot(*bsH);
00755         transV0.setES(iSetup);
00756 
00757         VertexRef foundVertexRef = FindClosest3D(transV0, vtxcollH, tWeight); 
00758 
00759         TransientTrack transtrk(trackref, &(*bFieldH) );
00760         transtrk.setBeamSpot(*bsH);
00761         transtrk.setES(iSetup);
00762 
00763         pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *foundVertexRef);        
00764 
00765         return make_pair(foundVertexRef, make_pair(trackref, -1.*IpPair.second.value()));
00766 
00767 }
00768 
00769 
00770 /*************************************************************************************/
00771 /* function to filter the nuclear interaction collection                             */ 
00772 /*************************************************************************************/
00773 
00774 auto_ptr<PFDisplacedVertexCollection>
00775 PF_PU_AssoMapAlgos::GetCleanedNI(Handle<PFDisplacedVertexCollection> NuclIntH, Handle<BeamSpot> bsH, bool cleanedColl)
00776 {
00777 
00778         auto_ptr<PFDisplacedVertexCollection> cleanedNIColl(new PFDisplacedVertexCollection() );
00779 
00780         for (PFDisplacedVertexCollection::const_iterator niref=NuclIntH->begin(); niref!=NuclIntH->end(); niref++){
00781 
00782 
00783           if( (niref->isFake()) || !(niref->isNucl()) ) continue;
00784 
00785           if(!cleanedColl){
00786             cleanedNIColl->push_back(*niref);
00787             continue;
00788           }
00789 
00790           VertexDistance3D distanceComputer;
00791 
00792           GlobalPoint ni_pos = RecoVertex::convertPos(niref->position());    
00793           GlobalError interactionVertexError = RecoVertex::convertError(niref->error());
00794 
00795           math::XYZVector ni_mom(niref->primaryMomentum().x(),
00796                                  niref->primaryMomentum().y(),
00797                                  niref->primaryMomentum().z());
00798 
00799           GlobalPoint bsPosition = RecoVertex::convertPos(bsH->position());
00800           GlobalError bsError = RecoVertex::convertError(bsH->covariance3D());
00801       
00802           double nuclint_significance = (distanceComputer.distance(VertexState(bsPosition,bsError), VertexState(ni_pos, interactionVertexError))).significance();
00803 
00804           if ((niref->position().rho()>=3.) &&
00805               (nuclint_significance>15.) &&
00806               (PF_PU_AssoMapAlgos::dR(niref->position(),ni_mom,bsH)<=0.3) ){
00807   
00808             cleanedNIColl->push_back(*niref);
00809 
00810           }
00811 
00812         }
00813 
00814         return cleanedNIColl;
00815 
00816 }
00817 
00818 
00819 /*************************************************************************************/
00820 /* function to find out if the track comes from a nuclear interaction                */ 
00821 /*************************************************************************************/
00822 
00823 bool
00824 PF_PU_AssoMapAlgos::ComesFromNI(const TrackRef trackref, PFDisplacedVertexCollection cleanedNI, PFDisplacedVertex* displVtx)
00825 {
00826 
00827         //the part for the reassociation of particles from nuclear interactions
00828         for(PFDisplacedVertexCollection::const_iterator iDisplV=cleanedNI.begin(); iDisplV!=cleanedNI.end(); iDisplV++){
00829 
00830           if(iDisplV->trackWeight(trackref)>1.e-5){
00831           
00832             *displVtx = *iDisplV; 
00833             return true;
00834 
00835           }
00836 
00837         }
00838 
00839         return false;
00840 }
00841 
00842 
00843 /*************************************************************************************/
00844 /* function to find the closest vertex in z for a track from a nuclear interaction   */ 
00845 /*************************************************************************************/
00846 
00847 VertexTrackQuality
00848 PF_PU_AssoMapAlgos::FindNIVertex(const TrackRef trackref, PFDisplacedVertex displVtx, ESHandle<MagneticField> bFieldH, const EventSetup& iSetup, Handle<BeamSpot> bsH, Handle<VertexCollection> vtxcollH, double tWeight)
00849 {
00850 
00851         TrackCollection refittedTracks = displVtx.refittedTracks();
00852 
00853         if((displVtx.isTherePrimaryTracks()) || (displVtx.isThereMergedTracks())){
00854 
00855           for(TrackCollection::const_iterator trkcoll_ite=refittedTracks.begin(); trkcoll_ite!=refittedTracks.end(); trkcoll_ite++){
00856         
00857             const TrackBaseRef retrackbaseref = displVtx.originalTrack(*trkcoll_ite); 
00858 
00859             if(displVtx.isIncomingTrack(retrackbaseref)){
00860 
00861               VertexTrackQuality VOAssociation = PF_PU_AssoMapAlgos::TrackWeightAssociation(retrackbaseref.castTo<TrackRef>(), vtxcollH);
00862 
00863               if(VOAssociation.second.second>1.e-5) 
00864                 return make_pair(VOAssociation.first, make_pair(trackref, 2.));
00865 
00866               TransientTrack transIncom(*retrackbaseref, &(*bFieldH) );
00867               transIncom.setBeamSpot(*bsH);
00868               transIncom.setES(iSetup);
00869 
00870               VertexRef foundVertexRef = FindClosest3D(transIncom, vtxcollH, tWeight); 
00871 
00872               TransientTrack transtrk(trackref, &(*bFieldH) );
00873               transtrk.setBeamSpot(*bsH);
00874               transtrk.setES(iSetup);
00875 
00876               pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *foundVertexRef);  
00877 
00878               return make_pair(foundVertexRef, make_pair(trackref, -1.*IpPair.second.value()));
00879 
00880             }
00881 
00882           }
00883 
00884         }
00885 
00886         math::XYZPoint ni_pos = displVtx.position();
00887 
00888         math::XYZVector ni_mom(displVtx.primaryMomentum().x(),
00889                                displVtx.primaryMomentum().y(),
00890                                displVtx.primaryMomentum().z());
00891 
00892         Track incom(trackref->chi2(), trackref->ndof(), ni_pos, ni_mom, 0, trackref->covariance());
00893 
00894         TransientTrack transIncom(incom, &(*bFieldH) );
00895         transIncom.setBeamSpot(*bsH);
00896         transIncom.setES(iSetup);
00897 
00898         VertexRef foundVertexRef = FindClosest3D(transIncom, vtxcollH, tWeight); 
00899 
00900         TransientTrack transtrk(trackref, &(*bFieldH) );
00901         transtrk.setBeamSpot(*bsH);
00902         transtrk.setES(iSetup);
00903 
00904         pair<bool,Measurement1D> IpPair = IPTools::absoluteImpactParameter3D(transtrk, *foundVertexRef);        
00905 
00906         return make_pair(foundVertexRef, make_pair(trackref, -1.*IpPair.second.value()));
00907 
00908 }
00909 
00910 
00911 /*************************************************************************************/
00912 /* function to check if a candidate is compatible with the BeamSpot                  */ 
00913 /*************************************************************************************/
00914 
00915 bool
00916 PF_PU_AssoMapAlgos::CheckBeamSpotCompability(TransientTrack transtrk, double cut)
00917 {
00918 
00919         double relative_distance = transtrk.stateAtBeamLine().transverseImpactParameter().significance();
00920 
00921         return (relative_distance<=cut);
00922 
00923 }
00924 
00925 
00926 /*****************************************************************************************/
00927 /* function to sort the vertices in the AssociationMap by the sum of (pT - pT_Error)**2  */ 
00928 /*****************************************************************************************/
00929 
00930 auto_ptr<TrackVertexAssMap>  
00931 PF_PU_AssoMapAlgos::SortAssociationMap(TrackVertexAssMap* trackvertexassInput) 
00932 {
00933         //create a new TrackVertexAssMap for the Output which will be sorted
00934         auto_ptr<TrackVertexAssMap> trackvertexassOutput(new TrackVertexAssMap() );
00935 
00936         //Create and fill a vector of pairs of vertex and the summed (pT-pT_Error)**2 of the tracks associated to the vertex 
00937         VertexPtsumVector vertexptsumvector;
00938 
00939         //loop over all vertices in the association map
00940         for(TrackVertexAssMap::const_iterator assomap_ite=trackvertexassInput->begin(); assomap_ite!=trackvertexassInput->end(); assomap_ite++){
00941 
00942           const VertexRef assomap_vertexref = assomap_ite->key;
00943           const TrackQualityPairVector trckcoll = assomap_ite->val;
00944 
00945           float ptsum = 0;
00946  
00947           TrackRef trackref;
00948 
00949           //get the tracks associated to the vertex and calculate the manipulated pT**2
00950           for(unsigned int trckcoll_ite=0; trckcoll_ite<trckcoll.size(); trckcoll_ite++){
00951 
00952             trackref = trckcoll[trckcoll_ite].first;
00953             double man_pT = trackref->pt() - trackref->ptError();
00954             if(man_pT>0.) ptsum+=man_pT*man_pT;
00955 
00956           }
00957 
00958           vertexptsumvector.push_back(make_pair(assomap_vertexref,ptsum));
00959 
00960         }
00961 
00962         while (vertexptsumvector.size()!=0){
00963 
00964           VertexRef vertexref_highestpT;
00965           float highestpT = 0.;
00966           int highestpT_index = 0;
00967 
00968           for(unsigned int vtxptsumvec_ite=0; vtxptsumvec_ite<vertexptsumvector.size(); vtxptsumvec_ite++){
00969  
00970             if(vertexptsumvector[vtxptsumvec_ite].second>highestpT){
00971 
00972               vertexref_highestpT = vertexptsumvector[vtxptsumvec_ite].first;
00973               highestpT = vertexptsumvector[vtxptsumvec_ite].second;
00974               highestpT_index = vtxptsumvec_ite;
00975         
00976             }
00977 
00978           }
00979           
00980           //loop over all vertices in the association map
00981           for(TrackVertexAssMap::const_iterator assomap_ite=trackvertexassInput->begin(); assomap_ite!=trackvertexassInput->end(); assomap_ite++){
00982 
00983             const VertexRef assomap_vertexref = assomap_ite->key;
00984             const TrackQualityPairVector trckcoll = assomap_ite->val;
00985 
00986             //if the vertex from the association map the vertex with the highest manipulated pT 
00987             //insert all associated tracks in the output Association Map
00988             if(assomap_vertexref==vertexref_highestpT) 
00989               for(unsigned int trckcoll_ite=0; trckcoll_ite<trckcoll.size(); trckcoll_ite++) 
00990                 trackvertexassOutput->insert(assomap_vertexref,trckcoll[trckcoll_ite]);
00991  
00992           }
00993 
00994           vertexptsumvector.erase(vertexptsumvector.begin()+highestpT_index);   
00995 
00996         }
00997 
00998         return trackvertexassOutput;
00999 
01000 }