CMS 3D CMS Logo

V0Fitter.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    V0Producer
00004 // Class:      V0Fitter
00005 // 
00013 //
00014 // Original Author:  Brian Drell
00015 //         Created:  Fri May 18 22:57:40 CEST 2007
00016 // $Id: V0Fitter.cc,v 1.24 2008/04/28 23:32:42 drell Exp $
00017 //
00018 //
00019 
00020 #include "RecoVertex/V0Producer/interface/V0Fitter.h"
00021 #include "PhysicsTools/CandUtils/interface/AddFourMomenta.h"
00022 
00023 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
00024 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
00025 #include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h"
00026 
00027 #include <typeinfo>
00028 
00029 // Constants
00030 
00031 const double piMass = 0.13957018;
00032 const double piMassSquared = piMass*piMass;
00033 
00034 // Constructor and (empty) destructor
00035 V0Fitter::V0Fitter(const edm::ParameterSet& theParameters,
00036                    const edm::Event& iEvent, const edm::EventSetup& iSetup) :
00037   recoAlg(theParameters.getUntrackedParameter("trackRecoAlgorithm",
00038                                    std::string("ctfWithMaterialTracks"))) {
00039   using std::string;
00040 
00041   // ------> Initialize parameters from PSet. ALL TRACKED, so no defaults.
00042   // First set bits to do various things:
00043   //  -decide whether to use the KVF track smoother, and whether to store those
00044   //     tracks in the reco::Vertex
00045   useRefTrax = theParameters.getParameter<bool>(string("useSmoothing"));
00046   storeRefTrax = theParameters.getParameter<bool>(
00047                                 string("storeSmoothedTracksInRecoVertex"));
00048 
00049   //  -whether to reconstruct K0s
00050   doKshorts = theParameters.getParameter<bool>(string("selectKshorts"));
00051   //  -whether to reconstruct Lambdas
00052   doLambdas = theParameters.getParameter<bool>(string("selectLambdas"));
00053 
00054   //  -whether to do cuts or store all found V0 
00055   doPostFitCuts = theParameters.getParameter<bool>(string("doPostFitCuts"));
00056   doTkQualCuts = 
00057     theParameters.getParameter<bool>(string("doTrackQualityCuts"));
00058 
00059   // Second, initialize post-fit cuts
00060   chi2Cut = theParameters.getParameter<double>(string("vtxChi2Cut"));
00061   tkChi2Cut = theParameters.getParameter<double>(string("tkChi2Cut"));
00062   tkNhitsCut = theParameters.getParameter<int>(string("tkNhitsCut"));
00063   rVtxCut = theParameters.getParameter<double>(string("rVtxCut"));
00064   vtxSigCut = theParameters.getParameter<double>(string("vtxSignificanceCut"));
00065   collinCut = theParameters.getParameter<double>(string("collinearityCut"));
00066   kShortMassCut = theParameters.getParameter<double>(string("kShortMassCut"));
00067   lambdaMassCut = theParameters.getParameter<double>(string("lambdaMassCut"));
00068 
00069   // FOR DEBUG:
00070   //initFileOutput();
00071   //--------------------
00072 
00073   //std::cout << "Entering V0Producer" << std::endl;
00074 
00075   fitAll(iEvent, iSetup);
00076 
00077   // FOR DEBUG:
00078   //cleanupFileOutput();
00079   //--------------------
00080 
00081 }
00082 
00083 V0Fitter::~V0Fitter() {
00084 }
00085 
00086 // Method containing the algorithm for vertex reconstruction
00087 void V0Fitter::fitAll(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
00088 
00089   using std::vector;
00090   using reco::Track;
00091   using reco::TransientTrack;
00092   using reco::TrackRef;
00093   using namespace edm;
00094 
00095   // Create std::vectors for Tracks and TrackRefs (required for
00096   //  passing to the KalmanVertexFitter)
00097   vector<TrackRef> theTrackRefs_;//temporary, for pre-cut TrackRefs
00098   vector<Track> theTracks;
00099   vector<TrackRef> theTrackRefs;
00100   vector<TransientTrack> theTransTracks;
00101 
00102   // Handles for tracks, B-field, and tracker geometry
00103   Handle<reco::TrackCollection> theTrackHandle;
00104   ESHandle<MagneticField> bFieldHandle;
00105   ESHandle<TrackerGeometry> trackerGeomHandle;
00106   ESHandle<GlobalTrackingGeometry> globTkGeomHandle;
00107 
00108 
00109   // Get the tracks from the event, and get the B-field record
00110   //  from the EventSetup
00111   iEvent.getByLabel(recoAlg, theTrackHandle);
00112   if( !theTrackHandle->size() ) return;
00113   iSetup.get<IdealMagneticFieldRecord>().get(bFieldHandle);
00114   iSetup.get<TrackerDigiGeometryRecord>().get(trackerGeomHandle);
00115   iSetup.get<GlobalTrackingGeometryRecord>().get(globTkGeomHandle);
00116 
00117   //edm::ESHandle<TransientTrackBuilder> transTkBuilder;
00118   //iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", transTkBuilder);
00119 
00120   trackerGeom = trackerGeomHandle.product();
00121   magField = bFieldHandle.product();
00122 
00123   // Create a vector of TrackRef objects to store in reco::Vertex later
00124   for(unsigned int indx = 0; indx < theTrackHandle->size(); indx++) {
00125     TrackRef tmpRef( theTrackHandle, indx );
00126     theTrackRefs_.push_back( tmpRef );
00127   }
00128 
00129   // Beam spot.  I'm hardcoding to (0,0,0) right now, but will use 
00130   //  reco::BeamSpot later.
00131   reco::TrackBase::Point beamSpot(0,0,0);
00132 
00133   //
00134   //----->> Preselection cuts on tracks.
00135   //
00136 
00137   // Check track refs, look at closest approach point to beam spot,
00138   //  and fill track vector with ones that pass the cut (> 1 cm).
00139 
00140 
00141   // REMOVE THIS CUT, AND MAKE A SCATTER PLOT OF MASS VS. LARGEST IMPACT
00142   //  PARAMETER OF CHARGED DAUGHTER TRACK.
00143 
00144   for( unsigned int indx2 = 0; indx2 < theTrackRefs_.size(); indx2++ ) {
00145     TransientTrack tmpTk( *(theTrackRefs_[indx2]), &(*bFieldHandle), globTkGeomHandle );
00146     //TransientTrack tmpTk( transTkBuilder->build( theTrackRefs_[indx2] ) );
00147     /*TrajectoryStateClosestToBeamLine
00148       tscb( tmpTk.stateAtBeamLine() );
00149       std::cout << "Didn't fail on tscb creation." << std::endl;*/
00150     //if( tscb.transverseImpactParameter().value() > 0.1 ) {
00151   //    if(tscb.transverseImpactParameter().value() > 0.) {//This removes the cut.
00152       theTrackRefs.push_back( theTrackRefs_[indx2] );
00153       theTracks.push_back( *(theTrackRefs_[indx2]) );
00154       theTransTracks.push_back( tmpTk );
00155       //    }
00156   }
00157 
00158   //----->> Initial cuts finished.
00159 
00160   // Loop over tracks and vertex good charged track pairs
00161   for(unsigned int trdx1 = 0; trdx1 < theTracks.size(); trdx1++) {
00162 
00163     if( doTkQualCuts 
00164         && theTrackRefs[trdx1]->normalizedChi2() > tkChi2Cut )
00165       continue;
00166 
00167     if( doTkQualCuts && theTrackRefs[trdx1]->recHitsSize() ) {
00168       trackingRecHit_iterator tk1HitIt = theTrackRefs[trdx1]->recHitsBegin();
00169       int nHits1 = 0;
00170       for( ; tk1HitIt < theTrackRefs[trdx1]->recHitsEnd(); tk1HitIt++) {
00171         if( (*tk1HitIt)->isValid() ) nHits1++;
00172       }
00173       if( nHits1 < tkNhitsCut ) continue;
00174     }
00175     
00176     for(unsigned int trdx2 = trdx1 + 1; trdx2 < theTracks.size(); trdx2++) {
00177 
00178       if( doTkQualCuts 
00179           && theTrackRefs[trdx2]->normalizedChi2() > tkChi2Cut ) continue;
00180 
00181       if( doTkQualCuts && theTrackRefs[trdx2]->recHitsSize() ) {
00182         trackingRecHit_iterator tk2HitIt = theTrackRefs[trdx2]->recHitsBegin();
00183         int nHits2 = 0;
00184         for( ; tk2HitIt < theTrackRefs[trdx2]->recHitsEnd(); tk2HitIt++) {
00185           if( (*tk2HitIt)->isValid() ) nHits2++;
00186         }
00187         if( nHits2 < tkNhitsCut ) continue;
00188       }
00189 
00190       vector<TransientTrack> transTracks;
00191 
00192       TrackRef positiveTrackRef;
00193       TrackRef negativeTrackRef;
00194       Track* positiveIter = 0;
00195       Track* negativeIter = 0;
00196       TransientTrack* posTransTkPtr = 0;
00197       TransientTrack* negTransTkPtr = 0;
00198 
00199       // Look at the two tracks we're looping over.  If they're oppositely
00200       //  charged, load them into the hypothesized positive and negative tracks
00201       //  and references to be sent to the KalmanVertexFitter
00202       if(theTrackRefs[trdx1]->charge() < 0. && 
00203          theTrackRefs[trdx2]->charge() > 0.) {
00204         negativeTrackRef = theTrackRefs[trdx1];
00205         positiveTrackRef = theTrackRefs[trdx2];
00206         negativeIter = &theTracks[trdx1];
00207         positiveIter = &theTracks[trdx2];
00208         negTransTkPtr = &theTransTracks[trdx1];
00209         posTransTkPtr = &theTransTracks[trdx2];
00210       }
00211       else if(theTrackRefs[trdx1]->charge() > 0. &&
00212               theTrackRefs[trdx2]->charge() < 0.) {
00213         negativeTrackRef = theTrackRefs[trdx2];
00214         positiveTrackRef = theTrackRefs[trdx1];
00215         negativeIter = &theTracks[trdx2];
00216         positiveIter = &theTracks[trdx1];
00217         negTransTkPtr = &theTransTracks[trdx2];
00218         posTransTkPtr = &theTransTracks[trdx1];
00219       }
00220       // If they're not 2 oppositely charged tracks, loop back to the
00221       //  beginning and try the next pair.
00222       else continue;
00223 
00224       //
00225       //----->> Carry out in-loop preselection cuts on tracks.
00226       //
00227 
00228       // Assume pion masses and do a wide mass cut.  First, we need the
00229       //  track momenta.
00230       /*      double posESq = positiveIter->momentum().Mag2() + piMassSquared;
00231       double negESq = negativeIter->momentum().Mag2() + piMassSquared;
00232       double posE = sqrt(posESq);
00233       double negE = sqrt(negESq);
00234       double totalE = posE + negE;
00235       double totalESq = totalE*totalE;
00236       double totalPSq = 
00237         (positiveIter->momentum() + negativeIter->momentum()).Mag2();
00238       double mass = sqrt( totalESq - totalPSq);
00239 
00240       TrajectoryStateClosestToBeamLine
00241         tscbPos( posTransTkPtr->stateAtBeamLine() );
00242       double d0_pos = tscbPos.transverseImpactParameter().value();
00243       TrajectoryStateClosestToBeamLine
00244         tscbNeg( negTransTkPtr->stateAtBeamLine() );
00245       double d0_neg = tscbNeg.transverseImpactParameter().value();
00246       */
00247 
00248       //std::cout << "Calculated m-pi-pi: " << mass << std::endl;
00249       /*mPiPiMassOut << mass << " "
00250         << (d0_neg < d0_pos? d0_pos : d0_neg) << std::endl;*/
00251       //if( mass > 0.7 ) continue;
00252 
00253       //----->> Finished making cuts.
00254 
00255       // Create TransientTrack objects.  They're needed for the KVF.
00256 
00257       // Fill the vector of TransientTracks to send to KVF
00258       transTracks.push_back(*posTransTkPtr);
00259       transTracks.push_back(*negTransTkPtr);
00260 
00261       //posTransTkPtr = negTransTkPtr = 0;
00262       positiveIter = negativeIter = 0;
00263 
00264       // Create the vertex fitter object
00265       KalmanVertexFitter theFitter(useRefTrax == 0 ? false : true);
00266 
00267       // Vertex the tracks
00268       //CachingVertex theRecoVertex;
00269       TransientVertex theRecoVertex;
00270       theRecoVertex = theFitter.vertex(transTracks);
00271 
00272       bool continue_ = true;
00273     
00274       // If the vertex is valid, make a VertexCompositeCandidate with it
00275       //  to be stored in the Event if the vertex Chi2 < 20
00276 
00277       if( !theRecoVertex.isValid() ) {
00278         continue_ = false;
00279       }
00280 
00281       if( continue_ ) {
00282         if(theRecoVertex.totalChiSquared() > 20. 
00283            || theRecoVertex.totalChiSquared() < 0.) {
00284           continue_ = false;
00285         }
00286       }
00287 
00288 
00289       if( continue_ ) {
00290         // Create reco::Vertex object to be put into the Event
00291         reco::Vertex theVtx = theRecoVertex;
00292         /*
00293         std::cout << "bef: reco::Vertex: " << theVtx.tracksSize() 
00294                   << " " << theVtx.hasRefittedTracks() << std::endl;
00295         std::cout << "bef: reco::TransientVertex: " 
00296                   << theRecoVertex.originalTracks().size() 
00297                   << " " << theRecoVertex.hasRefittedTracks() << std::endl;
00298         */
00299         // Create and fill vector of refitted TransientTracks
00300         //  (iff they've been created by the KVF)
00301         vector<TransientTrack> refittedTrax;
00302         if( theRecoVertex.hasRefittedTracks() ) {
00303           refittedTrax = theRecoVertex.refittedTracks();
00304         }
00305         // Need an iterator over the refitted tracks for below
00306         vector<TransientTrack>::iterator traxIter = refittedTrax.begin(),
00307           traxEnd = refittedTrax.end();
00308 
00309         // TransientTrack objects to hold the positive and negative
00310         //  refitted tracks
00311         TransientTrack* thePositiveRefTrack = 0;
00312         TransientTrack* theNegativeRefTrack = 0;
00313         
00314         // Store track info in reco::Vertex object.  If the option is set,
00315         //  store the refitted ones as well.
00316         //if(storeRefTrax) {
00317         for( ; traxIter != traxEnd; traxIter++) {
00318           if( traxIter->track().charge() > 0. ) {
00319             thePositiveRefTrack = new TransientTrack(*traxIter);
00320           }
00321           else if (traxIter->track().charge() < 0.) {
00322             theNegativeRefTrack = new TransientTrack(*traxIter);
00323           }
00324         }
00325         //}
00326         /*else {
00327           theVtx.add( positiveTrackRef );
00328           theVtx.add( negativeTrackRef );
00329           }*/
00330         /*
00331         std::cout << "aft: reco::Vertex: " << theVtx.tracksSize() 
00332                   << " " << theVtx.hasRefittedTracks() << std::endl;
00333         std::cout << "aft: reco::TransientVertex: " 
00334                   << theRecoVertex.originalTracks().size() 
00335                   << " " << theRecoVertex.hasRefittedTracks() << std::endl
00336                   << std::endl;
00337         */
00338         // Calculate momentum vectors for both tracks at the vertex
00339         GlobalPoint vtxPos(theVtx.x(), theVtx.y(), theVtx.z());
00340 
00341         TrajectoryStateClosestToPoint* trajPlus;
00342         TrajectoryStateClosestToPoint* trajMins;
00343 
00344         if(useRefTrax && refittedTrax.size() > 1) {
00345           trajPlus = new TrajectoryStateClosestToPoint(
00346                   thePositiveRefTrack->trajectoryStateClosestToPoint(vtxPos));
00347           trajMins = new TrajectoryStateClosestToPoint(
00348                   theNegativeRefTrack->trajectoryStateClosestToPoint(vtxPos));
00349         }
00350         else {
00351           trajPlus = new TrajectoryStateClosestToPoint(
00352                          posTransTkPtr->trajectoryStateClosestToPoint(vtxPos));
00353           trajMins = new TrajectoryStateClosestToPoint(
00354                          negTransTkPtr->trajectoryStateClosestToPoint(vtxPos));
00355 
00356         }
00357 
00358         posTransTkPtr = negTransTkPtr = 0;
00359 
00360         //  Just fixed this to make candidates for all 3 V0 particle types.
00361         // 
00362         //   We'll also need to make sure we're not writing candidates
00363         //    for all 3 types for a single event.  This could be problematic..
00364         GlobalVector positiveP(trajPlus->momentum());
00365         GlobalVector negativeP(trajMins->momentum());
00366         GlobalVector totalP(positiveP + negativeP);
00367         double piMassSq = 0.019479835;
00368         double protonMassSq = 0.880354402;
00369 
00370         //cleanup stuff we don't need anymore
00371         delete trajPlus;
00372         delete trajMins;
00373         trajPlus = trajMins = 0;
00374         delete thePositiveRefTrack;
00375         delete theNegativeRefTrack;
00376         thePositiveRefTrack = theNegativeRefTrack = 0;
00377 
00378         // calculate total energy of V0 3 ways:
00379         //  Assume it's a kShort, a Lambda, or a LambdaBar.
00380         double piPlusE = sqrt(positiveP.x()*positiveP.x()
00381                               + positiveP.y()*positiveP.y()
00382                               + positiveP.z()*positiveP.z()
00383                               + piMassSq);
00384         double piMinusE = sqrt(negativeP.x()*negativeP.x()
00385                                + negativeP.y()*negativeP.y()
00386                                + negativeP.z()*negativeP.z()
00387                                + piMassSq);
00388         double protonE = sqrt(positiveP.x()*positiveP.x()
00389                               + positiveP.y()*positiveP.y()
00390                               + positiveP.z()*positiveP.z()
00391                               + protonMassSq);
00392         double antiProtonE = sqrt(negativeP.x()*negativeP.x()
00393                                   + negativeP.y()*negativeP.y()
00394                                   + negativeP.z()*negativeP.z()
00395                                   + protonMassSq);
00396         double kShortETot = piPlusE + piMinusE;
00397         double lambdaEtot = protonE + piMinusE;
00398         double lambdaBarEtot = antiProtonE + piPlusE;
00399 
00400         using namespace reco;
00401 
00402         // Create momentum 4-vectors for the 3 candidate types
00403         const Particle::LorentzVector kShortP4(totalP.x(), 
00404                                          totalP.y(), totalP.z(), 
00405                                          kShortETot);
00406         const Particle::LorentzVector lambdaP4(totalP.x(), 
00407                                          totalP.y(), totalP.z(), 
00408                                          lambdaEtot);
00409         const Particle::LorentzVector lambdaBarP4(totalP.x(), 
00410                                          totalP.y(), totalP.z(), 
00411                                          lambdaBarEtot);
00412         Particle::Point vtx(theVtx.x(), theVtx.y(), theVtx.z());
00413         const Vertex::CovarianceMatrix vtxCov(theVtx.covariance());
00414         double vtxChi2(theVtx.chi2());
00415         double vtxNdof(theVtx.ndof());
00416 
00417         // Create the VertexCompositeCandidate object that will be stored in the Event
00418         VertexCompositeCandidate 
00419           theKshort(0, kShortP4, vtx, vtxCov, vtxChi2, vtxNdof);
00420         VertexCompositeCandidate 
00421           theLambda(0, lambdaP4, vtx, vtxCov, vtxChi2, vtxNdof);
00422         VertexCompositeCandidate 
00423           theLambdaBar(0, lambdaBarP4, vtx, vtxCov, vtxChi2, vtxNdof);
00424 
00425         // Create daughter candidates for the VertexCompositeCandidates
00426         RecoChargedCandidate 
00427           thePiPlusCand(1, Particle::LorentzVector(positiveP.x(), 
00428                                                 positiveP.y(), positiveP.z(),
00429                                                 piPlusE), vtx);
00430         thePiPlusCand.setTrack(positiveTrackRef);
00431 
00432         RecoChargedCandidate
00433           thePiMinusCand(-1, Particle::LorentzVector(negativeP.x(), 
00434                                                  negativeP.y(), negativeP.z(),
00435                                                  piMinusE), vtx);
00436         thePiMinusCand.setTrack(negativeTrackRef);
00437 
00438  
00439         RecoChargedCandidate
00440           theProtonCand(1, Particle::LorentzVector(positiveP.x(),
00441                                                  positiveP.y(), positiveP.z(),
00442                                                  protonE), vtx);
00443         theProtonCand.setTrack(positiveTrackRef);
00444 
00445         RecoChargedCandidate
00446           theAntiProtonCand(-1, Particle::LorentzVector(negativeP.x(),
00447                                                  negativeP.y(), negativeP.z(),
00448                                                  antiProtonE), vtx);
00449         theAntiProtonCand.setTrack(negativeTrackRef);
00450 
00451 
00452         // Store the daughter Candidates in the VertexCompositeCandidates
00453         theKshort.addDaughter(thePiPlusCand);
00454         theKshort.addDaughter(thePiMinusCand);
00455 
00456         theLambda.addDaughter(theProtonCand);
00457         theLambda.addDaughter(thePiMinusCand);
00458 
00459         theLambdaBar.addDaughter(theAntiProtonCand);
00460         theLambdaBar.addDaughter(thePiPlusCand);
00461 
00462         theKshort.setPdgId(310);
00463         theLambda.setPdgId(3122);
00464         theLambdaBar.setPdgId(-3122);
00465 
00466         AddFourMomenta addp4;
00467         addp4.set( theKshort );
00468         addp4.set( theLambda );
00469         addp4.set( theLambdaBar );
00470 
00471         // Store the candidates in a temporary STL vector
00472         if(doKshorts)
00473           preCutCands.push_back(theKshort);
00474         if(doLambdas) {
00475           preCutCands.push_back(theLambda);
00476           preCutCands.push_back(theLambdaBar);
00477         }
00478 
00479 
00480       }
00481     }
00482   }
00483 
00484   // If we have any candidates, clean and sort them into proper collections
00485   //  using the cuts specified in the EventSetup.
00486   if( preCutCands.size() )
00487     applyPostFitCuts();
00488 
00489 }
00490 
00491 
00492 // Get methods
00493 const reco::VertexCompositeCandidateCollection& V0Fitter::getKshorts() const {
00494   return theKshorts;
00495 }
00496 
00497 const reco::VertexCompositeCandidateCollection& V0Fitter::getLambdas() const {
00498   return theLambdas;
00499 }
00500 
00501 const reco::VertexCompositeCandidateCollection& V0Fitter::getLambdaBars() const {
00502   return theLambdaBars;
00503 }
00504 
00505 
00506 // Method that applies cuts to the vector of pre-cut candidates.
00507 void V0Fitter::applyPostFitCuts() {
00508   //static int eventCounter = 1;
00509   //std::cout << "Doing applyPostFitCuts()" << std::endl;
00510   /*std::cout << "Starting post fit cuts with " << preCutCands.size()
00511     << " preCutCands" << std::endl;*/
00512   //std::cout << "!1" << std::endl;
00513   for(reco::VertexCompositeCandidateCollection::iterator theIt = preCutCands.begin();
00514       theIt != preCutCands.end(); theIt++) {
00515     bool writeVee = false;
00516     double rVtxMag = sqrt( theIt->vertex().x()*theIt->vertex().x() +
00517                            theIt->vertex().y()*theIt->vertex().y() );
00518                            //theIt->vertex().z()*theIt->vertex().z() );
00519 
00520     double x_ = theIt->vertex().x();
00521     double y_ = theIt->vertex().y();
00522     //double z_ = theIt->vertex().z();
00523     double sig00 = theIt->vertexCovariance(0,0);
00524     double sig11 = theIt->vertexCovariance(1,1);
00525     //double sig22 = theIt->vertexCovariance(2,2);
00526     double sig01 = theIt->vertexCovariance(0,1);
00527     //double sig02 = theIt->vertexCovariance(0,2);
00528     //double sig12 = theIt->vertexCovariance(1,2);
00529 
00530     /*double sigmaRvtxMag =
00531       sqrt( sig00*(x_*x_) + sig11*(y_*y_) + sig22*(z_*z_)
00532             + 2*(sig01*(x_*y_) + sig02*(x_*z_) + sig12*(y_*z_)) ) 
00533             / rVtxMag;*/
00534     double sigmaRvtxMag =
00535       sqrt( sig00*(x_*x_) + sig11*(y_*y_) + 2*sig01*(x_*y_) ) / rVtxMag;
00536 
00537     //std::cout << "!2" << std::endl;
00538     // Get the tracks from the candidates.
00539     std::vector<reco::RecoChargedCandidate> v0daughters;
00540     std::vector<reco::TrackRef> theVtxTrax;
00541     for(unsigned int ii = 0; ii < theIt->numberOfDaughters(); ii++) {
00542       v0daughters.push_back( *(dynamic_cast<reco::RecoChargedCandidate *>
00543                                (theIt->daughter(ii))) );
00544     }
00545     for(unsigned int jj = 0; jj < v0daughters.size(); jj++) {
00546       theVtxTrax.push_back(v0daughters[jj].track());
00547     }
00548     /*    if(theIt->vertex().hasRefittedTracks()) {
00549       theVtxTrax = theIt->vertex().refittedTracks();
00550     }
00551     else {
00552       reco::Vertex::trackRef_iterator theTkIt = theIt->vertex().tracks_begin();
00553       for( ; theTkIt < theIt->vertex().tracks_end(); theTkIt++) {
00554         reco::TrackRef theRef1 = theTkIt->castTo<reco::TrackRef>();
00555         theVtxTrax.push_back(*theRef1);
00556       }
00557       }*/
00558 
00559     //std::cout << "!3" << std::endl;
00560     using namespace reco;
00561 
00562     // If the position of the innermost hit on either of the daughter
00563     //   tracks is less than the radial vertex position (minus 4 sigmaRvtx)
00564     //   then don't keep the vee.
00565     bool hitsOkay = true;
00566     //std::cout << "theVtxTrax.size = " << theVtxTrax.size() << std::endl;
00567     if( theVtxTrax.size() == 2 && doPostFitCuts) {
00568       if( theVtxTrax[0]->innerOk() ) {
00569         reco::Vertex::Point tk1HitPosition = theVtxTrax[0]->innerPosition();
00570         if( sqrt(tk1HitPosition.Perp2()) < (rVtxMag - sigmaRvtxMag*4.0) ) {
00571           hitsOkay = false;
00572         }
00573       }
00574       if( theVtxTrax[1]->innerOk() && hitsOkay) {
00575         reco::Vertex::Point tk2HitPosition = theVtxTrax[1]->innerPosition();
00576         if( sqrt(tk2HitPosition.Perp2()) < (rVtxMag - sigmaRvtxMag*4.0) ) {
00577           hitsOkay = false;
00578         }
00579       }
00580       /*if( theVtxTrax[0]->recHitsSize() && theVtxTrax[1]->recHitsSize() ) {
00581 
00582         trackingRecHit_iterator tk1HitIt = theVtxTrax[0]->recHitsBegin();
00583         trackingRecHit_iterator tk2HitIt = theVtxTrax[1]->recHitsBegin();
00584 
00585         for( ; tk1HitIt < theVtxTrax[0]->recHitsEnd(); tk1HitIt++) {
00586           if( (*tk1HitIt)->isValid() && hitsOkay) {
00587             const TrackingRecHit* tk1HitPtr = (*tk1HitIt).get();
00588             GlobalPoint tk1HitPosition
00589               = trackerGeom->idToDet(tk1HitPtr->
00590                                      geographicalId())->
00591               surface().toGlobal(tk1HitPtr->localPosition());
00592             //std::cout << typeid(*tk1HitPtr).name();
00593 
00594             if( tk1HitPosition.perp() < (rVtxMag - 4.*sigmaRvtxMag) ) {
00595               hitsOkay = false;
00596             }
00597           }
00598         }
00599 
00600         for( ; tk2HitIt < theVtxTrax[1]->recHitsEnd(); tk2HitIt++) {
00601           if( (*tk2HitIt)->isValid() && hitsOkay) {
00602             const TrackingRecHit* tk2HitPtr = (*tk2HitIt).get();
00603             GlobalPoint tk2HitPosition
00604               = trackerGeom->idToDet(tk2HitPtr->
00605                                      geographicalId())->
00606               surface().toGlobal(tk2HitPtr->localPosition());
00607 
00608             if( tk2HitPosition.perp() < (rVtxMag - 4.*sigmaRvtxMag) ) {
00609               hitsOkay = false;
00610             }
00611           }
00612         }
00613         }*/
00614     }
00615 
00616 
00617     if( theIt->vertexChi2() < chi2Cut &&
00618         rVtxMag > rVtxCut &&
00619         rVtxMag/sigmaRvtxMag > vtxSigCut &&
00620         hitsOkay) {
00621       writeVee = true;
00622     }
00623     const double kShortMass = 0.49767;
00624     const double lambdaMass = 1.1156;
00625 
00626     if( theIt->mass() < kShortMass + kShortMassCut && 
00627         theIt->mass() > kShortMass - kShortMassCut && writeVee &&
00628         doKshorts && doPostFitCuts) {
00629       if(theIt->pdgId() == 310) {
00630         theKshorts.push_back( *theIt );
00631       }
00632     }
00633     else if( !doPostFitCuts && theIt->pdgId() == 310 && doKshorts ) {
00634       theKshorts.push_back( *theIt );
00635     }
00636 
00637     //3122
00638     else if( theIt->mass() < lambdaMass + lambdaMassCut &&
00639         theIt->mass() > lambdaMass - lambdaMassCut && writeVee &&
00640              doLambdas && doPostFitCuts ) {
00641       if(theIt->pdgId() == 3122) {
00642         theLambdas.push_back( *theIt );
00643       }
00644       else if(theIt->pdgId() == -3122) {
00645         theLambdaBars.push_back( *theIt );
00646       }
00647     }
00648     else if ( !doPostFitCuts && theIt->pdgId() == 3122 && doLambdas ) {
00649       theLambdas.push_back( *theIt );
00650     }
00651     else if ( !doPostFitCuts && theIt->pdgId() == -3122 && doLambdas ) {
00652       theLambdaBars.push_back( *theIt );
00653     }
00654   }
00655 
00656   /*static int numkshorts = 0;
00657   numkshorts += theKshorts.size();
00658   std::cout << "Ending cuts with " << theKshorts.size() << " K0s, "
00659   << numkshorts << " total." << std::endl;*/
00660   //std::cout << "Finished applyPostFitCuts() for event "
00661   //    << eventCounter << std::endl;
00662   //eventCounter++;
00663 
00664 
00665 }
00666 

Generated on Tue Jun 9 17:46:12 2009 for CMSSW by  doxygen 1.5.4