Extracting Dxy and NDf for secondary vertices from the class "reco::VertexCompositePtrCandidate"

I want to extract a root file containing all the variables (i.e. NumberofDaughters, sv_mass) for secondary vertices from a MiniAOD root file from /QCD_Pt_300to470_TuneCUETP8M1_13TeV_pythia8/RunIISummer16MiniAODv2-PUMoriond17_80X_mcRun2_asymptotic_2016_TrancheIV_v6-v1/MINIAODSIM | CERN Open Data Portal

I have added all the necessary lines such as,

      std::vector<float> svEta;
      std::vector<float> svMass;
      std::vector<int> svNumDaughters

,
However, I am unable to extract sv_dxy, sv_dxysig, sv_ntracks, sv_ndf,

my error is,

/code/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins/MiniAnalyzer.cc: In member function 'virtual void MiniAnalyzer::analyze(const edm::Event&, const edm::EventSetup&)':
/code/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins/MiniAnalyzer.cc:182:34: error: 'const Point {aka const class ROOT::Math::PositionVector3D<ROOT::Math::Cartesian3D<double>, ROOT::Math::DefaultCoordinateSystemTag>}' has no member named 'dXY'
      svDxy.push_back(sv.vertex().dXY());
                                  ^~~
/code/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins/MiniAnalyzer.cc:184:37: error: 'const class reco::VertexCompositePtrCandidate' has no member named 'dxysig'
      svDxySignificance.push_back(sv.dxysig());
                                     ^~~~~~
/code/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins/MiniAnalyzer.cc:185:6: error: 'svndf' was not declared in this scope
      svndf.push_back(sv.Ndf());
      ^~~~~
/code/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins/MiniAnalyzer.cc:185:6: note: suggested alternative: 'svNdf'
      svndf.push_back(sv.Ndf());
      ^~~~~
      svNdf
/code/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins/MiniAnalyzer.cc:185:25: error: 'const class reco::VertexCompositePtrCandidate' has no member named 'Ndf'
      svndf.push_back(sv.Ndf());

Is it possible that the class doesn’t have those variables? In that case, can I calculate them using some formula?

Hi Swasti,

Can you share your analyzer? I can take a look.

You can always visit GitHub - cms-sw/cmssw: CMS Offline Software and navigate to the 10_6_X branch to explore what member functions exist. Searching the class name should help identify the files that define its member functions and any inheritance structures (ex: statements like “class ThisOne = public OtherOne”).

Thanks,
Julie

1 Like

Hi,

I’m realizing that this particular QCD sample is actually using an older Pythia tune from CMS and doesn’t match the processing of most other 2016 simulation samples (thanks for sharing the dataset name, we might remove this older version!).

I would recommend instead this QCD_Pt_370to470 dataset:
Mini: /QCD_Pt_300to470_TuneCP5_13TeV_pythia8/RunIISummer20UL16MiniAODv2-106X_mcRun2_asymptotic_v17-v1/MINIAODSIM | CERN Open Data Portal
Nano: /QCD_Pt_300to470_TuneCP5_13TeV_pythia8/RunIISummer20UL16NanoAODv9-106X_mcRun2_asymptotic_v17-v1/NANOAODSIM | CERN Open Data Portal

The NanoAOD is a flat ROOT tree that is much simpler to process and has the secondary vertex information you’re looking for stored:
https://opendata.cern.ch/eos/opendata/cms/dataset-semantics/NanoAODSIM/63194/QCD_Pt_300to470_TuneCP5_13TeV_pythia8_doc.html#SV

More info about NanoAOD lives here: Getting Started with CMS NanoAOD Open Data | CERN Open Data Portal

If NanoAOD doesn’t have what your analysis needs, I believe the branch names in NanoAOD copy pretty closely the member function names from MiniAOD. So if you have loaded “slimmedSecondaryVertices”, then I would expect “.ndof()” to work, rather than “.Ndf”, and similar.

Hope that helps,
Julie

Thanks a lot for sharing that.

I am sharing the cc file, just in case.

(base) rathodswasti@Swastis-Laptop14:~/cms_open_data_work/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins$ cat MiniAnalyzer.cc
// -*- C++ -*-
//
// Package:    Test/MiniAnalyzer
// Class:      MiniAnalyzer
//
/**\class MiniAnalyzer MiniAnalyzer.cc Test/MiniAnalyzer/plugins/MiniAnalyzer.cc

 Description: [one line class summary]

 Implementation:
     [Notes on implementation]
*/
//
// Original Author: Swasti
//         Created:  Thu, 01 Feb 2024 02:16:09 GMT
//
//


// system include files
#include <memory>

// user include files
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/one/EDAnalyzer.h"

#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"

#include "FWCore/Utilities/interface/InputTag.h"

#include "FWCore/ServiceRegistry/interface/Service.h"
#include "CommonTools/UtilAlgos/interface/TFileService.h"
#include "TH1.h"

#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "DataFormats/PatCandidates/interface/Jet.h"
#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h"
#include "DataFormats/Candidate/interface/LeafCandidate.h"
#include "DataFormats/Math/interface/LorentzVector.h"
#include "DataFormats/VertexReco/interface/VertexFwd.h"
#include "DataFormats/VertexReco/interface/Vertex.h"

#include "DataFormats/GeometryVector/interface/GlobalPoint.h"
#include "DataFormats/BeamSpot/interface/BeamSpot.h"

// ROOT includes
#include "TTree.h"
#include <TFile.h>
#include <TROOT.h>
#include "TBranch.h"
#include <string>
#include <vector>
#include "TSystem.h"
#include "TVector3.h"
#include "TLorentzVector.h"

//
// class declaration
//

class MiniAnalyzer : public edm::one::EDAnalyzer<edm::one::SharedResources>  {
   public:
      explicit MiniAnalyzer(const edm::ParameterSet&);
      ~MiniAnalyzer();

      static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);

   private:
      virtual void beginJob() override;
      virtual void analyze(const edm::Event&, const edm::EventSetup&) override;
      virtual void endJob() override;

      // ----------member data ---------------------------
      edm::EDGetTokenT<reco::VertexCollection> vtxToken_;
      edm::EDGetTokenT<std::vector<reco::VertexCompositePtrCandidate>> secondaryVertexToken_;

      TTree *tree;

      edm::RunNumber_t irun;
      edm::EventNumber_t ievent;
      edm::LuminosityBlockNumber_t ilumiblock;
      edm::Timestamp itime;

      size_t run, event, lumi, time;

      unsigned int npv;
      unsigned int nsv;

      std::vector<float> svPt;
      std::vector<float> svX;
      std::vector<float> svY;
      std::vector<float> svZ;
      std::vector<float> svNormalizedChi2;
      std::vector<float> svChi2;
      std::vector<float> svEta;
      std::vector<float> svMass;
      std::vector<int> svNumDaughters;
      std::vector<float> svDxyError; // New parameter
//      std::vector<float> svDxy;
 //     std::vector<float> svDxySig;
      std::vector<float> svNdf;
};

//
// constructors and destructor
//
MiniAnalyzer::MiniAnalyzer(const edm::ParameterSet& iConfig)
    : vtxToken_(consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))),
      secondaryVertexToken_(consumes<std::vector<reco::VertexCompositePtrCandidate>>(iConfig.getParameter<edm::InputTag>("secondaryVertices")))
{
   usesResource("TFileService");
   edm::Service<TFileService> file;

   tree = file->make<TTree>("tree","For QCD File");
   tree->Branch("npv", &npv, "npv/i");
   tree->Branch("nsv", &nsv, "nsv/i");

   tree->Branch("svPt", &svPt);
   tree->Branch("svX", &svX);
   tree->Branch("svY", &svY);
   tree->Branch("svZ", &svZ);
   tree->Branch("svNormalizedChi2", &svNormalizedChi2);
   tree->Branch("svChi2", &svChi2);
   tree->Branch("svEta", &svEta);
   tree->Branch("svMass", &svMass);
   tree->Branch("svNumDaughters", &svNumDaughters);
   tree->Branch("svDxyError", &svDxyError);
//tree->Branch("svDxy", &svDxy);
//tree->Branch("svDxySig", &svDxySig);
  tree->Branch("svNdf", &svNdf);

}

MiniAnalyzer::~MiniAnalyzer() {}

//
// member functions
//

void MiniAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
{
  using namespace edm;

  edm::Handle<reco::VertexCollection> vertices;
  iEvent.getByToken(vtxToken_, vertices);
  if (vertices->empty()) return;

  edm::Handle<std::vector<reco::VertexCompositePtrCandidate>> secondaryVertices;
  iEvent.getByToken(secondaryVertexToken_, secondaryVertices);

  irun       = iEvent.id().run();
  ievent     = iEvent.id().event();
  ilumiblock = iEvent.id().luminosityBlock();
  itime      = iEvent.time();

  run   = static_cast<size_t>(irun);
  event = static_cast<size_t>(ievent);
  lumi  = static_cast<size_t>(ilumiblock);
  time  = static_cast<size_t>((iEvent.time().value()) >> 32);

  svPt.clear();
  svX.clear();
  svY.clear();
  svZ.clear();
  svNormalizedChi2.clear();
  svChi2.clear();
  svEta.clear();
  svMass.clear();
  svNumDaughters.clear();
  svDxyError.clear();
//  svDxy.clear();
//  svDxySig.clear();
  svNdf.clear();

  for (const auto& sv : *secondaryVertices) {
     svPt.push_back(sv.pt());
     svX.push_back(sv.vertex().x());
     svY.push_back(sv.vertex().y());
     svZ.push_back(sv.vertex().z());
     svNormalizedChi2.push_back(sv.vertexNormalizedChi2());
     svChi2.push_back(sv.vertexChi2());
     svEta.push_back(sv.eta());
     svMass.push_back(sv.mass());
     svNumDaughters.push_back(sv.numberOfDaughters());
     svDxyError.push_back(sv.dxyError());
 svNdf.push_back(sv.vertexNdof());
//     svDxy.push_back(dxy);
//     svDxySig.push_back(dxySignificance);


}

  npv = vertices->size();
  nsv = vertices->size();
  tree->Fill();
}

void MiniAnalyzer::beginJob() {}

void MiniAnalyzer::endJob() {}

void MiniAnalyzer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
  edm::ParameterSetDescription desc;
  desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
  desc.add<edm::InputTag>("secondaryVertices", edm::InputTag("inclusiveSecondaryVertices"));
  descriptions.add("miniAnalyzer", desc);
}

DEFINE_FWK_MODULE(MiniAnalyzer);
(base) rathodswasti@Swastis-Laptop14:~/cms_open_data_work/CMSSW_10_6_30/src/Test/MiniAnalyzer/plugins$

this one got compiled successfully, Ndof works. However, I am more interested in getting dxy, so I am trying to calculate it using the x and y positions.

I am also extracting the same information from the Bulk Graviton simulation file - /BulkGravTohhTohbbhbb_narrow_M-600_13TeV-madgraph/RunIISummer16MiniAODv2-PUMoriond17_80X_mcRun2_asymptotic_2016_TrancheIV_v6_ext1-v1/MINIAODSIM | CERN Open Data Portal
Should I use that one?

Thanks for the reply again!

Hi,

Turns out this set of samples were released earlier than our other 2016 samples for machine learning studies. Is that what you are working on? Basically, If it’s possible for your analysis to update to the newer samples that have NanoAOD, then process-wise things are much simpler.

If you have to use MiniAOD, I think this is the best reference on how to compute all the distances you need. This is the source code used to produce the vertex information in NanoAOD:

Regards,
Julie