Vertex fitting and finding in ROOT



Introduction

The following algorithms for constrained vertex fitting and finding are implemented within the d0root_analysis CVS ROOT-package.

VertexGlobalFitter

Implements a constrained vertex fit of a set tracks. The input is a list of GTracks and the output is an object of the class Vertex containing the position of the vertex and the re-fitted vertex-constrained tracks.

The fit consist of the minimization of a chi2 of 2 terms:

The ROOT algorithm is mathematically equivalent to the Kalman Filter algorithm implemented in the framework, but consist of a Global fit of position and momenta at the same time, instead of the recursive Kalman Filter/Smoother formalism.

Both charged and neutral tracks can be fitted.

Documentation

Example of Vertex fit
      
  VertexGlobalFitter* vFitter = new VertexGlobalFitter;
  vFitter->fit(listOfTracks);
  if(vFitter->status()) {
    Vertex* fittedVertex = new Vertex(* (Vertex*) vFitter->vertex());
  }

PrimaryVertexGlobalFinder

Finds the hard-scatter primary vertex of an event.
The input is the list of all reconstructed GTracks and the nominal beam position and the output is an object of the class Vertex.

It implements the following pattern recognition algorithm:

  1. Cluster tracks in z using a simple-cone track-jet algorithm of infinite radius in the transverse plane and 1cm radius in z.

  2. Select the highest multiplicity track-cluster (this assumes the hard-scatter vertex is the highest multiplicity vertex).

  3. Select tracks with pt> 0.5GeV/c, 11 or more hits and transverse DCA significance with respect to the nominal beam position smaller than 3. The beam spot error is assumed to be 30um in the transverse plane and 25cm in z

  4. Fit tracks to a common vertex using the VertexGlobalFitter algorithm.

  5. If the highest chi2 contribution of a track to the vertex is greater than 10, the track is excluded from the fit and step 4-5 are repeated until the chi2 contribution of all tracks to the vertex is smaller than 10.

    Example of Primary Vertex reconstruction
          
    
      /// define beam spot position 
      TVector3 IP(-0.025,-0.053,0.0);
    
      /// instantiate vertex finder 
      PrimaryVertexGlobalFinder* pvFinder = new PrimaryVertexGlobalFinder;
      pvFinder->SetIPposition(IP);
    
      /// read tracks 
      TObjArray tracks; _readEvent.readGTracks(tracks,"401");
    
      /// find primary vertex 
      pvFinder->FindVertex(tracks);
    
      /// get primary vertex and its attached tracks 
      Vertex* PV = vFinder->GetVertex();
      TObjArray PVtracks = PV->Particles();
    

    V0Finder

    Search for 2-track vertices assuming different mass hypothesis and kinematic cuts for K0, Lambda and Psi reconstruction. The V0Finder can be constructed by specifying a list of cuts/options or by using any of the default SetCut methods as the following examples show:

    Example of K0 finding specifying the list of cuts
          
      /// Instantiate Primary Vertex finder 
      TVector3 IP(-0.025,-0.053,0.0); //beam spot
      PrimaryVertexGlobalFinder* pvFinder = new PrimaryVertexGlobalFinder;
      pvFinder->SetIPposition(IP);
    
      /// Instantiate V0Finder 
      float cuts[12] = {11,    //hits
    		    0.3,   // track pT
    		    0.0,   // min. dca
    		    999.9, // max. dca
    		    0.0,   // min dca significance
    		    0.13956995, // mass track 1
    		    0.13956995, // mass track 2
    		    100,   // vertex chi2
    		    0.9999,// vertex collinearity angle
    		    0.0,   // vertex min. decay lenght
    		    0.15,  // min. vertex mass
    		    1.4   // max. vertex mass
      };
      V0Finder* K0Finder = new V0Finder(cuts);
    
      /// read tracks and find the primary vertex 
      TObjArray tracks; _readEvent.readGTracks(tracks,"401");
      pvFinder->FindVertex(tracks);
      Vertex* PV = vFinder->GetVertex();
    
      /// find K0s   
      K0Finder->SetPrimaryVertex(PV);
      K0Finder->Find(tracks);
      TObjArray K0s = K0Finder->GetVertices();
    
    Example of Psi finding using default constructor
          
       /// Instantiate Primary Vertex finder 
       TVector3 IP(-0.025,-0.053,0.0); //beam spot
       PrimaryVertexGlobalFinder* pvFinder = new PrimaryVertexGlobalFinder;
       pvFinder->SetIPposition(IP);
    
       /// Instantiate V0Finder 
       V0Finder* psiFinder = new V0Finder;
       psiFinder->SetJPsiCuts();
    
       /// read tracks and find the primary vertex 
       TObjArray tracks; _readEvent.readGTracks(tracks,"401");
       pvFinder->FindVertex(tracks);
       Vertex* PV = vFinder->GetVertex();
    
       /// find J/Psi's   
       psiFinder->SetPrimaryVertex(PV);
       psiFinder->Find(tracks);
       TObjArray JPsis = psiFinder->GetVertices();
    

    SecondaryVertexGlobalFinder

    Finds inclusive secondary vertices in jets for b-tagging.

    BjpsiXFinder

    Algorithm to search for B --> J/Psi + X vertex decays.

    It starts finding a JPsi vertex candidate using the V0Finder algorithm and, according to the X decay mode specified in the constructor, attaches additional tracks using different mass hypothesis and kinematic selections.

    Example of B -> JPsi + K finding
          
          BjpsiXFinder* BFinder = new BjpsiXFinder;
          BFinder->SetJPsi(jpsiVertex); //previously found with V0Finder
     
          BFinder->Input(tracks); 
          BFinder->FindX("K"); // X = K
    
          TObjArray Bs = BFinder->GetVertices();
    

    In addition to vertex fitting and finding algorithms, Track-Jet finding algorithms and flavor tagging methods are provided:

    TrackJetFinder

    Finds track-jets using a 3D cone (D0note 3919) or Kt jet algorithm.
    The input is a list of reconstructed GTracks and the output is a list of objects of the class ParticleCollection.
    Several methods for kinematic cuts are provided in the constructor.

    Example of track-jet finding and jet-charge tagging
          
      /// Instantiate 0.7 cone jet Finder 
      SimpleConeJetFinder* jetFinder = new SimpleConeJetFinder(0.7);
        
      /// read tracks 
      TObjArray tracks; _readEvent.readGTracks(tracks,"401");
    
      /// find jets 
      TObjArray jets;
      jetFinder->Input(selectedTracks);
      jetFinder->FindJets(jets);
    
      /// get jet-charge of found jets
      float kappa = 0.5;
    
      for(int i=0; i <  jets.GetEntries(); i++) {
        ParticleCollection* jet = (ParticleCollection*) jets[i];
        double jch = jet->JetCharge(kappa);
      }
    


    Example code: B lifetime

          
       TH1F*  h_life = new TH1F("h_life","",100,-0.3,0.3);
    
       float correctionFactor = 0.73
    
       /// Instantiate Vertex finders 
       TVector3 IP(-0.025,-0.053,0.0); //beam spot
       PrimaryVertexGlobalFinder* pvFinder = new PrimaryVertexGlobalFinder;
       pvFinder->SetIPposition(IP);
       V0Finder* psiFinder = new V0Finder;
       psiFinder->SetJPsiCuts();
    
    
       /// Loop over events 
       int nentries = _readEvent.GetEntries();
       for (int ii=0; ii < nentries; ii++) {
         if(!_readEvent.GetEntry(ii)) continue;
    
          /// read tracks matched to muons using Gavin's method 
          TObjArray muonTracks;
          TObjArray muList; _readEvent.readTrackMuons_p10(muList,"501");
          for(int y=0; y < muons.GetEntries(); y++) {
            Muon* mu = (Muon*) muons[y];
            Track* trk = (Track*) mu->GetTrack();
            if(trk) {
    	  //remove duplicated
    	  if(!trk->MatchId(muonTracks)) muonTracks.Add(trk);
            }
          }
    
          /// Find Primary Vertex
          pvFinder->FindVertex(tracks);
          Vertex* PV = vFinder->GetVertex();
    
          /// Find J/Psi's   
          psiFinder->SetPrimaryVertex(PV);
          psiFinder->Find(tracks);
          TObjArray JPsis = psiFinder->GetVertices();
    
          /// compute lifetime   
          for(int i=0; i < JPsis.GetEntries(); i++) {
            Vertex* vtx = (Vertex*) JPsis[i];
            if(vtx->chi2 < 10 && vtx->Pt() > 4.0) { 
              float lifetime = vtx->Lifetime2(PV,3.09688)/correctionFactor;
              h_life->Fill(lifetime);
            }
          }
    
          psiFinder->Clear();
          _readEvent.Clear();
       } //entries
    


    Instructions


    Mailing List

    There is a listserv D0ROOT_PACKAGES mailing list to discuss issues about d0root code, suggest new improvements/changes, and keep users informed about new versions and modifications.

    To subscribe to this list, please send an Email to listserv@fnal.gov with the following body:

     subscribe D0ROOT_PACKAGES your-first-name your-last-name


    p11 Results


    di-muon Invariant mass (opposite sign charged tracks)


    di-muon Invariant mass (opposite sign charged tracks)


    Invariant mass (same sign charged tracks)


    Lifetime (correction factor = 0.73)


    Lifetime for different PV multiplicities


    B -> JPsi K candidates

    Performance plots.


    FAQ

    Is it easy to modify my d0root code to run on TMB files instead of TMB-Trees? Is there an example macro that does that?

    I think that in a nutshell, what you need to do is:

    • add "Regd0rootPkg" to your OBJECTS file
    • add "RCP root = " (or however you want to refer
      to this RCP file) to your framework RCP file, and include the corresponding name in the framework RCP file's "Packages" line.

    Then, in your analysis (which must be called from a framework package called after the d0rootPkg conversion), simply "read" the information
    from the ReadEvent instance. You obtain this instance using FwkReadEvent::instance()
    A minimal CVS package that does just that is d0root_test (but I suppose that d0root_example would do equally well -- both provide examples of how
    to convert both from TMB/DST and from TMBTree).
    You will probably want to tailor d0rootPkg.rcp, as it affects the level of corrections applied to objects etc. I hope its accompanying documentation is sufficient.
    Frank Filthaut


    Last updated: 05-18-2004
    Ariel Schwartzman