This is the documentation for the general producer

This is the documentation for the general producer

1 General producer

These are short notes for ParticleProducer.

1.1 General descriptions

The ParticleProducer is a general edm::EDProducer to reconstruct any type of particles as long as proper daughter particles collections are available (like tracks, muons, electrons and jets). The output of ParticleProducer consist of pat::GenericParticleCollection objects of reconstructed particles and their decay products (daughters and granddaughters if any) and a collection of primary vertices. An example is illustrated.

Type                              Module                      Label         Process
----------------------------------------------------------------------------------------------
vector<pat::GenericParticle>      "generalD0CandidatesNew"    ""            "D0PbPb2018SKIM"
vector<pat::GenericParticle>      "generalD0CandidatesNew"    "daughters"   "D0PbPb2018SKIM"
vector<reco::Vertex>              "generalD0CandidatesNew"    "vertices"    "D0PbPb2018SKIM"

1.1.1 How it works

The ParticleProducer make use of several sub-modules to produce target edm format objects. It has two private member variables – ParticleFitter fiter_ and ParticleDaughter daughter_. fitter_ help user to reconstructed particles via their decay products (stored in daughter_). If there is no vector of daughter PSet, it will save input collection as pat::GenericParticleCollection (just take the input as the target).

In practice, this producer will do following things in order:

  • Reserve edm products (reco::VertexCollection) of vertices. Primary vertex collection are sent into the producer via ParticleFitter::setVertex.
  • If the vector of daughter PSet is available, the producer will reserve edm products for daughter collection storage. Further, the producer fill ParticleDaughter vector following the configurations. Once the vector of daughter collections is ready, this producer will fit candidates via ParticleFitter::fitAll.
  • Everything will be moved to output AOD file. Vertex collection and daughter collection are filled in the reserved edm product created in previous steps. The target decay particles will be stored in the pat::GenericParticleCollection.

1.1.2 How ParticleFitter::setVertex and ParticleFitter::fitAll work

  1. ParticleFitter::setVertex

    It will take primary vertex collection and beam spot as input. If there is no valid PV collection, a vertex will be constructed from beam spot. PVs in the collection are ordered by track size (need to update for backward compatibility).

  2. ParticleFitter::fitAll

    It will call ParticleFitter::fillDaughters and ParticleFitter::makeCandidates.

    • ParticleFitter::fillDaughters It will call ParticleDaughter::init and ParticleDaughter::addParticles. The first one is intended for muons (further studies needed). The second one is to convert input daughter collection (could be tracks, muons etc.) with pat::GenericParticle.
    • ParticleFitter::makecandidates Decay particles are reconstructed here using the daughter collections obtained in the previous step. Candidates will have the total four-momenta of daughters. Combinations of daughters are done via make_combinations. User can use several string cut parsers (preSelection, preMassSelection, pocaSelection, postSelection and finalSelection) to do simple selections.

1.2 Configurations

1.2.1 Examples

  • \(\Lambda_c \to K_s+p\)

    # Add the VertexComposite producer
    from VertexCompositeAnalysis.VertexCompositeProducer.generalParticles_cff import generalParticles
    process.kShort = generalParticles.clone(
        pdgId = cms.int32(310),
        charge = cms.int32(0),
        doSwap = cms.bool(False),
        width = cms.double(0.2),
    
        preSelection = cms.string(""),
        pocaSelection = cms.string("pt >= 1.0 && abs(rapidity) < 2.4"),
        postSelection = cms.string(""),
        preMassSelection = cms.string(""),
        finalSelection = cms.string( " "),
        # daughter information
        daughterInfo = cms.VPSet([
            cms.PSet(pdgId = cms.int32(211), charge = cms.int32(-1),
                  selection = cms.string(
                  "pt>1.0 && abs(eta)<2.4"
                  "&& quality('loose')"" && ptError/pt<0.1"
                  "&& normalizedChi2<7.0"
                  "&& numberOfValidHits >=4")
                ),
            cms.PSet(pdgId = cms.int32(211), charge = cms.int32(+1),
                  selection = cms.string(
                  "pt>1.0 && abs(eta)<2.4"
                  "&& quality('loose')"" && ptError/pt<0.1"
                  "&& normalizedChi2<7.0"
                  "&& numberOfValidHits >=4")
                ),
        ]),
    )
    
    process.LambdaC = generalParticles.clone(
        pdgId = cms.int32(4122),
        doSwap = cms.bool(False),
        preMassSelection = cms.string("abs(charge)==1"),
        finalSelection = cms.string(''),
        # daughter information
        daughterInfo = cms.VPSet([
            cms.PSet(pdgId = cms.int32(310), source = cms.InputTag('kShort'),
                     selection = cms.string('')),
            cms.PSet(pdgId = cms.int32(2212), #charge = cms.int32(+1),
                     selection = cms.string("pt>1.0 && abs(eta)<2.4"
                     "&& quality('highPurity') && ptError/pt<0.1"
                     "&& normalizedChi2<7.0"
                     "&& numberOfValidHits >=11")),
        ]),
    )
    
    # Add ntrack map
    process.load("VertexCompositeAnalysis.VertexCompositeProducer.nTracks_cfi")
    process.ntrack_seq = cms.Sequence(process.nTracks)
    
    # Define the analysis steps
    process.rereco_step = cms.Path(process.ntrack_seq * process.kShort * process.LambdaC)
    
  • \(D^0 \to K\pi\)

    # D0 candidate rereco
    process.load("VertexCompositeAnalysis.VertexCompositeProducer.generalParticles_cff")
    process.generalD0CandidatesNew = process.generalParticles.clone(
        pdgId = cms.int32(421),
        doSwap = cms.bool(True),
        width = cms.double(0.15),
    
        preSelection = cms.string(""
           "charge==0"
           "&& userFloat('dauPtSum') >= 1.6 && userFloat('dauEtaDiff') <= 1.0"
           ),
        pocaSelection = cms.string(""
           "userFloat('bestMass') >= 1.71 && userFloat('bestMass') <= 2.02 && pt >= 1.0"
           "&& userFloat('dca') >= 0 && userFloat('dca') <= 9999."
           ),
        postSelection = cms.string(""
           "userFloat('vertexProb') >= 0.02"
           "&& userFloat('normChi2') <= 9999.0"
           ),
        finalSelection = cms.string(""
           "userFloat('rVtxMag') >= 0.0 && userFloat('rVtxSig') >= 2.0"
           "&& userFloat('lVtxMag') >= 0.0 && userFloat('lVtxSig') >= 3.0"
           "&& cos(userFloat('angle3D')) >= -2.0 && cos(userFloat('angle2D')) >= -2.0"
           "&& abs(userFloat('angle3D')) <= 0.2 && abs(userFloat('angle2D')) <= 0.2"
           "&& abs(rapidity) < 2.0"
           ),
        dEdxInputs = cms.vstring('dedxHarmonic2', 'dedxPixelHarmonic2'),
    #
        # daughter information
        daughterInfo = cms.VPSet([
            cms.PSet(pdgId = cms.int32(321), charge = cms.int32(-1),
               selection = cms.string(
                  "pt>1.0 && abs(eta)<2.4"
                  "&& quality('highPurity') && ptError/pt<0.1"
                  "&& (normalizedChi2/hitPattern.trackerLayersWithMeasurement)<0.18"
                  "&& numberOfValidHits >=11"
                  ),
               finalSelection = cms.string(''
                  'abs(userFloat("dzSig")) < 3.0 && abs(userFloat("dxySig")) < 3.0'
                  '&& (track.algo!=6 || userFloat("mva")>=0.98)'
                  )
               ),
            cms.PSet(pdgId = cms.int32(211), charge = cms.int32(+1),
               selection = cms.string(
                  "pt>1.0 && abs(eta)<2.4"
                  "&& quality('highPurity') && ptError/pt<0.1"
                  "&& (normalizedChi2/hitPattern.trackerLayersWithMeasurement)<0.18"
                  "&& numberOfValidHits >=11"
                  ),
               finalSelection = cms.string(''
                  'abs(userFloat("dzSig")) < 3.0 && abs(userFloat("dxySig")) < 3.0'
                  '&& (track.algo!=6 || userFloat("mva")>=0.98)'
                  )
               )
        ])
      )
    process.generalD0CandidatesNew.mva = cms.InputTag("generalTracks","MVAValues") ###cesar:to change iter6 tracking mva cut
    

1.2.2 Options

Table 1: This is the table of configurable parameters.
Name Descriptions Type Default values
pdgId   cms.int32  
doSwap Save time to avoid fit the decay vertex multiple times cms.bool False
width   cms.double  
daughterInfo Configurations for daughters cms.VPSet  
fitAlgo Fit algorithms cms.vuint32 [0]
matchVertex Further documentation needed. cms.bool False
puMap Further documentation needed. cms.vdouble  
primaryVertices   cms.InputTag offlinePrimaryVertices
electrons The pdgId need to be 11 cms.InputTag  
muons The pdgId need to be 13 cms.InputTag patMuons
taus The pdgId need to be 15 cms.InputTag  
photons The pdgId need to be 22 cms.InputTag  
tracks The pdgId need to be different from numbers listed in this table and charge!=0 cms.InputTag generalTracks
pfParticles The pdgId need to be 0 cms.InputTag  
jets The pdgId need to be <= 6 cms.InputTag  
conversions Converted photons, pdgId need to be -22 cms.InputTag  
mva MVA ValueMap for the track collection cms.InputTag  
dEdxInputs Module names of dEdx ValueMap cms.vstring  

Table 2: This is the summary of available fit algos.
Name Index Default parameters (currently not configurable)
Unconstrained kinematic fitter 0 maxDistance=0.01, maxNbrOfIterations=100
Kinematic fitter with MultiTrackPointingKinematicConstraint 1 maxDelta=0.01, maxNbrOfIterations=1000, maxReducedChiSq=225, minChiSqImprovement=50
Kinematic fitter with MultiTrackMassKinematicConstraint 2 world-average mass, and further documentation needed.
Kalman vertex fitter 3 maxDistance=0.01, maxNbrOfIterations=10
Adaptive vertex fitter 4 maxshift=0.0001, maxlpshift=0.1, maxstep=30, weightthreshold=0.001, further documentation needed.
Gsf vertex Fitter 5 maxDistance=0.01, maxNbrOfIterations=10, limitComponents=false, smoothTracks=true
Adaptive Gsf vertex fitter 6 maxshift=0.0001, maxlpshift=0.1, maxstep=30, weightthreshold=0.001, limitComponents=false

Table 3: This is the table of general configurable parameters for daughters
Name Descriptions Type Default values
pdgId Used to label the particles and determine the input collection cms.int32  
mass   cms.double  
charge   cms.int32  
width   cms.double  
selection   cms.string  
finalSelection   cms.string  
source Input source of daughter particles. Determined by pdgId if not specified. cms.InputTag  

Table 4: This is the table of muon specified parameters for dauhgters
Name Descriptions Type Default values
propToMuon   cms.bool  
useSimpleGeometry   cms.bool True
useTrack   cms.string none
useState   cms.string atVertex
fallbackToME1   cms.bool True
useMB2InOverlap   cms.bool True
useStation2   cms.bool True

Table 5: This is the table of available variables in selections.
Selection userFloat
preselection dauPtSum, dauEtaDiff (when having 2 daughters)
preMassselection bestMass (when having doSwap true)
pocaSelection dca (when having 2 tracks as daugthers), bestMass
postSelection normChi2 (chi2/ndf), vertexProb
finalselection lVtxMag (3D decay length), rVtxMag (2D decay length), lVtxSig (3D decay length significance), rVtxSig, angle3D (3D pointing angle), angle2D
finalSelection (daughter PSet) dz, dxy, dzSig, dxySig, mva, dEdx_* (* means input tag of dedx), if they are available

1.3 Class member functions and variables

1.3.1 ParticleComparator

Compare particles using their pT, eta, phi, charge (order follows their precedence).

1.3.2 ParticleMassComparator

Compare particles using their mass, pT, eta, phi, charge (order follows their precedence).

1.3.3 ParticleTreeComparator

Compare particles using their mass, charge, pT, eta, phi (order follows their precedence).

1.3.4 ParticleDaughter

A class for daughter particle storage.

  1. pdgId()

    Return PDG ID of the particle.

  2. charge()

    Return charge of the specie of particle.

  3. mass()

    Return mass.

  4. width()

    Return the width of mass window during the candidate selection.

  5. particles()

    Return the particle collection for the ParticleDaughter object.

  6. useSource()

    Return if user give any source input to the ParticleDaughter object.

  7. addParticles(const edm::Event& event, const edm::EDGetTokenT<std::vector<T> >& token, const reco::Vertex& vertex, const bool embedInfo=true);

    Add particles to the ParticleDaughter object. The GenericParticle object will be filled via addData and addInfo. If track info is available, userFloat variables: dz, dxy, dzSig and dxySig will be available. dEdx and track MVA info (if any) will be saved as userFloat via ParticleDaughter::setDeDx and ParticleDaughter::setMVA. Users can apply cuts via selction and finalSelection. Cuts implemented via member functions can be applied via selection. Cuts on userFloat variables need to be done via finalSelection.

  8. addParticles(const edm::Event& event)

    Add particles to the ParticleDaughter object. This function will read from source rather than other collections like reco::TrackCollection.

  9. fillInfo(const edm::ParameterSet& pSet, const edm::ParameterSet& config, edm::ConsumesCollector& iC)

    Fill info based on configurations of daughter PSet.

  10. init(const edm::EventSetup& iSetup)

    A function for muon setup (further documentations needed).

  11. addInfo(pat::GenericParticle& c, const T& p)

    Set four-momentum, charge and corresponding vertex.

  12. addInfo(pat::GenericParticle& c, const reco::Conversion& p)

    Not very clear, need to explore more. Refit the vertex of the track collection and save it as a GenericParticle. Set four-momentum, charge, vertex position and track references.

  13. addData(pat::GenericParticle& c, const edm::Ref<std::vector<T> >& p, const bool& embedInfo)

    c.addUserData<T>("src", *p);

  14. addData(pat::GenericParticle& c, const reco::TrackRef& p, const bool& embedInfo)

    Add track info and set sourceID (a userInt for checking duplicate daughters) to 1.

  15. addData(pat::GenericParticle& c, const reco::PFCandidateRef& p, const bool& embedInfo)

    Set info from PFCandidate. A userData called src will be added. Track reference info will be added as well if available.

  16. addData(pat::GenericParticle& c, const pat::MuonRef& p, const bool& embedInfo)

    Add muon info. userData called src will be added. Optional user data may exist including:

    • userData: trackRef
    • userFloat: l1Eta, l1Phi
    • userInt: prop -> 1
  17. addData(pat::GenericParticle& c, const pat::ElectronRef& p, const bool& embedInfo)

    Set info for electron. Add src (userData) and track reference (maybe).

  18. setMVA (pat::GenericParticle& c, const size_t& i, const edm::Handle<std::vector<float> >& m)

    Set MVA value for tracks.

  19. setDeDx(pat::GenericParticle& c, const std::map<std::string, edm::Handle<edm::ValueMap<reco::DeDxData> > >& m)

    Set dEdx info for daughters if available.

  20. addMuonL1Info(pat::GenericParticle& c, const edm::Handle<pat::TriggerObjectStandAloneMatch>& m)

    Further documentation needed.

1.3.5 ParticleFitter

  1. void addParticles(ParticleDaughter& d, const edm::Event& iEvent)

    Add particles depending on pdgId of ParticleDaughter.

  2. const reco::VertexCollection& vertices()

    Return primary vertices associated with decay products.

  3. const pat::GenericParticleCollection& particles()

    Return candidate collection of decay particles.

  4. const pat::GenericParticleCollection& daughters()

    Return daughter collection of decay particles, including both daughters and granddaughters.

  5. const bool hasNoDaughters()

    Check whether daughter collection is empty.

  6. reco::VertexRef getVertexRef(const reco::Vertex& vertex)

    It generate reco::VertexRef taking the vertices_ variable as the associated collection and using the index of each element in vertices_ as key_value. It compares the input vertex with position, multiplicity and isFake with saved ones to avoid duplication.

  7. math::XYZTLorentzVector getP4(const GlobalVector& p, const double& m)

    Return the p4.

  8. pat::GenericParticleRef addParticle(const pat::GenericParticle& particle)

    It generate pat::Genericparticle taking the particles_ variable as the associated collection and using the index of each element in particles_ as key_value. Particles are identified via their pT, eta, phi, mass and charge. It recursively store daughters of daughters into the particles_ and change their primary vertices reference to the collection with new product ID. The trick used here is const_cast. Examples are here.

    if (particle.hasUserData("daughters")) {
      auto& daughters = *const_cast<pat::GenericParticleRefVector*>(particle.userData<pat::GenericParticleRefVector>("daughters"));
      pat::GenericParticleRefVector dauColl(dauProd_.id());
      for (const auto& dau : daughters) { dauColl.push_back(addParticle(*dau)); }
      daughters = dauColl;
    }
    if (particle.hasUserData("primaryVertex")) {
      auto& priVtx = *const_cast<reco::VertexRef*>(particle.userData<reco::VertexRef>("primaryVertex"));
      priVtx = getVertexRef(*priVtx);
    }
    
  9. void matchPrimaryVertex(pat::GenericParticle& cand, const TransTrackColl& tracks={}, FreeTrajectoryState fts={}, const double& thr=1.E-9)

    This function associate the candidate to a vertex using pat::addUserData<reco::VertexRef>. It is customized via the option matchVertex in the configuration.

    • matchVertex == False: In this case, the VetexRef is set to be the same as vertex_ and this value is set in ParticleFitter::setVertex,

      vertex_ = (priVertices_.empty() ? beamSpotVertex : priVertices_[0]);
      

      And whether the first one is the one with leading pT2 or the highest multiplicity depends on the configuration. For the Run2 backward compatibility, keep matchVertex == False.

    • matchVertex == True: This case is not used in analyses before 2020. Personally I do not use it yet (say, 2021) and am not very clear about the details. I document my thinking here.
      • It will at first check whether the value of userFloat("vertexProb") is larger than thr and whether the size of primary vertex collection is larger than 1. If either of them is not satisfied, this function will return the value in vertex_.
      • If the conditions above are satisfied, then it will try to give the point of the closet approach (PCA). It will give two tries.
        1. If the input of FreeTrajectoryState fts has no error, the function will try to construct the FreeTrajectoryState of the candidate via the candidate information, userData("kinematicParametersError") and other kinematic information, p4, mass and decay point position. And PCA will be computed via the constructed via this fts. Moreover, if the probability of PCA extrapolation is larger than thr, PCA is set to the extrapolated value (a non-null value). If any step discussed above failed, PCA will be a null value. This function will try the second way to compute PCA.
        2. If the track collection is not empty, this function will try to fit a vertex constrained to beam spot with KalmanVertexFitter. And PCA is computed if the vertex probability is larger than thr.
        3. If 1 or 2 succeed, the function will try to find whether the isGoodPV condition is satisfied, and further check distance conditions,

          const bool& isGoodPV = (pv.position() == vertex_.position() || pv.tracksSize() >= puMap_.size() || fabs(pv.z()-vertex_.z()) > puMap_[pv.tracksSize()]);
          if (isGoodPV && std::abs(pv.z()-pca.z()) < std::abs(candPV.z()-pca.z())-0.4) { candPV = pv; }
          

          Here puMap_ is the map of dz tolerance and specified via puMap in the configuration. If the conditions are not satisfied, value in vertex_ will be used.

  10. RefCountedKinematicTree fitVertex(const ParticleInfo& parInfo, const int& fitAlgo, GlobalPoint decP, const reco::Vertex& priVtx={})

    This function can do three kind of fit.

    • fitAlgo == 0, unconstrained fit
    • fitAlgo == 1, make use of MultiTrackPointingKinematicConstraint, primary vertex and decay vertex information (currently obtained from prior fit) will be used.
    • fitAlgo == 2, make use of MultiTrackMassKinematicConstraint, the PDG mass of reconstructed particles and number of daughters are used.
  11. RefCountedKinematicTree fitVertex(const ParticleInfo& parInfo, const int& fitAlgo)

    This function fit the vertex with fitAlgo from 3 to 6. After vertex is reconstructed, it will be converted to kinematic particle vertex. They are not tested yet.

  12. bool ParticleFitter::fitCandidate(pat::GenericParticle& cand, const pat::GenericParticleCollection& dauColl)

    This function tries to fit a candidate. It does following things:

    • Get the daughters transient tracks. Converted photons will have multiple tracks, otherwise, each daughter has one track, constructed by its track or userData("kineamticParametersError").
    • Measure distance between daughter tracks at their point of closest approach, if each candidate has two daughters. I do not know why it does not work when one daughter is an intermediate particle (for instance \(K_s\)). If the DCA between two particles cannot be calculated, this fit will be labeled as failure and return. Also, userFloat("bestMass") is available for case of number of daughter equal to 2.
    • Prepare particles for decay vertex fit. The variable ParticleInfo parInfo will be sent to ParticleFitter::fitVertex. parInfo will carry the information of std::vector<RefCountedKinematicParticle>, std::vector<reco::TransientTrack> and std::map<ParticleTuple, size_t>>. The first parameter is the collection of the kinematic particles (for converted photons they are decay particles of photons and for others they are themselves.) The second one contains the corresponding transient tracks of kinematic particles. The third one stores the map between each particle dynamics and the corresponding index in the first parameter.
    • Fir the decay vertex through a few algorithms which are stored in fitAlgoV_. If there are multiple fit algorithms users want to use, then they are saved as userData("decayVertex") (the main one, the first one in the fitAlgoV_) and userData("decayVertex_label") where label is each element in the fitAlgoV_ except the main one. This step does the following things
      • Loop over all the algorithms
        • Check whether the algorithm is the kinematic fit (with or without constraints). If true, call fitVertex(const ParticleInfo& parInfo, const int& fitAlgo, GlobalPoint decP, const reco::Vertex& priVtx={}). It will perform a prior fit if users want the kinematic fit with constraints and then fit again with the obtained decay vertex from prior fit. Otherwise the fit result will be the prior one.
        • If the algorithm is not kinematic one, the fit result will be given through fitVertex(const ParticleInfo& parInfo, const int& fitAlgo).
        • If the main fit fails, it will not perform fit any more and return false.
        • Other information like userFloat("normaChi2"), userFloat("vertexProb"), vertex (a member function), p4 info, userData("daughtersP4") and userData("kinematicParametersError") are saved only for the main fit.
      • matchPrimaryvertex will be called if everything works fine above.
      • Return true, this means the fit succeeds!
  13. void setVtxProd(const reco::VertexRefProd& prod)

    { vtxProd_ = prod; };

  14. setDauProd(const GenericParticleRefProd& prod)

    { dauProd_ = prod; }

  15. void getNTracks(const edm::Event& iEvent)

    Seems not implemented.

  16. void fillDaughters(const edm::Event& iEvent, const edm::EventSetup& iSetup)

    Call ParticleFitter::addParticles to fill the collection of ParticleDaughter.

  17. bool isUniqueDaughter(ParticleSet& set, const pat::GenericParticle& dau)

    Check whether dau is in set. If so, return false since dau is a duplicate in set, the daughter is not unique. If not, dau will be inserted to set and this function return true.

  18. void makeCandidates()

    This function defines how the fitter works.

    • It will generate daughter collection from the collection, dauColls, of ParticleDaughter, daughters_.
    • With the dauColls, combinations of daughters are generated via makecombinations.
    • Loop over combinations.
      • The candidate charge, p4 are set by the sum of daughters'. The PDG ID is set to the same as input configuration and the status of the candidate is set to 3. A tuple of each candidate is also inserted to the set of candidates to avoid duplication. Only those particles without any duplicate daughter will be kept.
      • Some userFloat variables will be calculated. userData("daughtersP4") will be filled with daughters' original p4 but will change later in fitCandidate. preSelection_ is done.
      • Daughters will be reordered if doSwap_ == true, via swapDaughters.
      • The masses of each candidate and its corresponding swap candidate with reordered daughters will be computed and the one closet to PDG mass has to be in the region |mass_ - bestMass| < width. If not, the candidate and its swap counterparts will not be saved. Best mass will be overwrite in fitCandidate if the number of daughters is two.
      • preMassSelection_ is done.
      • fitCandidate is called.
      • Extra information are added via addExtraInfo. pocaSelection_ is done there.
      • Candidate collection pat::GenericParticleCollection candidates is created.
      • pat::GenericParticleCollection swapCandColl is created via addSwapCandidates. swapCandColl will be empty if doSwap_ == false.
      • candidates and swapCandColl are combined.
      • Daughter collection is reordered following ParticleTreeComparator. References to daughter collection are saved.
    • The collection of candidates is reordered via ParticleMassComparator.
  19. void swapDaughters(DoubleMap& swapDauColls, const pat::GenericParticle& cand, const pat::GenericParticleCollection& dauColl)

    This function works only when doSwap_ == true. This function will do permutation based on ParticleComparator. Moreover, there are two conditions need to be considered.

    • Each candidate have daughters with opposite charges and candidate is neutral. Taking the \(D^0\) as an example, the reconstructed channel is \(D^0 \to K^- \pi^+\). We assume that the negative tracks are $K^-$s and positive tracks are $π^+$s. But if we assume vice verse, then we are trying to reconstruct \(\bar{D}^0 \to K^+ \pi^-\). They are reconstructed with the same track pair but different mass assumptions. If the fitter will not use the charge or mass information of tracks, then we do not need to fit twice with the same pair. We just make a swapped \(D^0\) (it is an assumption) which is a \(\bar{D}^0\) (it is also an assumption).
    • Each candidate have more than two daughters. Taking the \(\Lambda_c^+ \to \pi^+ K^- p\) as an example, we assume that the positive tracks are (\(\pi^+\), \(p\)) pair. We can also assume that the track pair is (\(p\), \(\pi^+\)). Again, if the fitter does not consider the charge information or mass information of particles, we are not necessary to fit twice. Just swap the \(pi^+\) and \(p\) and assign a new mass to the candidate. This is the sense of swap, which is different from the case of \(D^0\), where a charge conjugate is obtained.

    The daughters to swap are necessary to have the same userInt("sourceID") (if not have this userInt, source ID is set to 0; if source ID is 1, they are tracks, 2 for pf candidates). If sourceID == 0, does not do swap. If the daughter and permutated daughter share the same PDGID, then does not do swap.

  20. void setBestMass(pat::GenericParticle& cand, const DoubleMap& swapDauColls)

    Works only when doSwap_ == true. Choose the mass value closet to the PDG value from candidates and their swap counterparts.

  21. void addSwapCandidates(pat::GenericParticleCollection& swapCandColl, const pat::GenericParticle& cand, const DoubleMap& swapDauColls)

    Works only when doSwap_ == true. Fill swapped candidates to swapCandColl.

  22. void addExtraInfo(pat::GenericParticle& cand)

    userData("decayVertex"), userData("primaryVertex"), userFloat("lVtxMag"), userFloat("rVtxMag"), userFloat("lVtxSig"), userFloat("rVtxSig"), userFloat("angle3D") and userFloat("angle2D") are saved.

  23. void clear()
    vertex_ = reco::Vertex();
    beamSpot2D_ = reco::Vertex();
    beamSpot_ = reco::BeamSpot();
    clear(candidates_);
    clear(particles_);
    clear(vertices_);
    clear(priVertices_);
    vertexRefMap_.clear();
    particleRefMap_.clear();
    std::for_each(daughters_.begin(), daughters_.end(), [](ParticleDaughter &d){ d.clear(); });
    
  24. template<class T> void clear(std::vector<T>& v)

    { std::vector<T>().swap(v); };

2 General tree producer

2.1 Configurations

2.1.1 Examples

  • \(D^{0} \to K\pi\), tree producer

    # tree producer
    from VertexCompositeAnalysis.VertexCompositeAnalyzer.particle_tree_cff import particleAna
    process.generalanaNew = particleAna.clone(
      recoParticles = cms.InputTag("generalD0CandidatesNew"),
      triggerInfo = cms.untracked.VPSet([
        cms.PSet(path = cms.string('HLT_HIMinimumBias_*')), # Minimum bias
      ]),
      selectEvents = cms.string("eventFilter_HM"),
    )
    process.generalanaNewSeq = cms.Sequence(process.generalanaNew)
    process.generalana_step = cms.EndPath( process.generalanaNewSeq )
    
  • \(\Lambda_{c} \to K_{s}+p\), ntuple producer

    # Add the VertexComposite tree
    from VertexCompositeAnalysis.VertexCompositeAnalyzer.particle_tree_cff import particleAna_mc
    process.lambdacAna_mc = particleAna_mc.clone(
      recoParticles = cms.InputTag("LambdaC"),
      genParticles = cms.untracked.InputTag("genParticles"),
      selectEvents = cms.string(""),
      addSource    = cms.untracked.bool(False),
      genPdgId     = cms.untracked.vuint32([4122, 310, 2212, 211]),
      saveTree = cms.untracked.bool(False)
    )
    process.p = cms.EndPath(process.lambdacAna_mc)
    

2.1.2 Options

Check sections for tokens.

Name Descriptions Type Default values
beamSpot   cms.InputTag offlineBeamSpot
primaryVertices   cms.InputTag offlinePrimaryVertices
recoParticles The pat::GenericParticleCollection user want to save as tree cms.InputTag generalParticles
nTracksVMap The ValueMap of number of offline tracks cms.untracked.InputTag generalParticles:nTracks
triggerResults   cms.untracked.InputTag TriggerResults::HLT
triggerEvent   cms.untracked.InputTag hltTriggerSummaryAOD::HLT
triggerInfo Further documentation needed cms.untracked.VPSet  
matchInfo trigger-reco matching information, further documentation needed cms.untracked.VPSet  
eventFilterResults   cms.untracked.InputTag TriggerResults
eventFilterNames   cms.untracked.vstring Please check corresponding branch
selectEvents   cms.string Please check corresponding branch
centralityBin   cms.untrakced.InputTag InputTag("centralityBin","HFtowers")
centrality   cms.untracked.InputTag hiCentrality
eventPlane   cms.untracked.InputTag hiEvtPlaneFlat
lumiInfo   cms.untracked.InputTag InputTag("lumiInfo", "brilcalc")
lumiScalers   cms.untracked.InputTag scalersRawToDigi
lumiRecord   cms.untracked.InputTag onlineMetaDataDigis
saveTree If True then save tree else save ntuple cms.untracked.bool True
addTrgObj   cms.untracked.bool False
genParticles Input tag for reco::GenParticleCollection. Work when dealing with MC samples cms.untracked.InputTag genParticles
genInfo Further documentation needed cms.untracked.InputTag generator
genPdgId The vector saving pdgId of decay particles, their decay products and other particles users want to match gen cms.untracked.vuint32 left as empty
lhInfo   cms.untracked.InputTag externalLHEProducer
maxGenIter   cms.untracked.int32 0
maxGenDeltaR   cms.untracked.double 0.03
maxGenDeltaPtRel   cms.untracked.double 0.5

2.2 Short descriptions

The tree producer will generate analyzing tree or ntuple with the minimal setup and configurations. It will save the trigger info, event info, lumi info and the particle info. It will make use of two containers, called Container and ParticleContainer, and two helper classes, TriggerInfo and MatchInfo. It will execute the following in order:

  1. Take the elements in triggerInfo, and set up the token for trigger lumi info for each element if it has, other set null. Lumi info for each element will be saved in tok_triggerLumiInfo_, a one-to-one map to triggerInfo_. (See its constructor.)
  2. Create an entry "trgObj" in addInfo_. The value will be taken from the configuration parameter addTrgObj or be false if the parameter does not exist. (See its constructor.)
  3. Get the trigger results out from toktriggerResults_ and save the collection into trigger results label. (See beginRun.)
  4. Initialize the hltPrescaleProvider_ with the labels in last step. (See beginRun.)
  5. Fill the l1PrescaleTable_. (See beginRun.)
  6. Get the configuration of reconstructed particles via getConfiguration. (See beginRun.)
  7. Extract the information from the configuration in last step via loadConfiguration. (See beginRun.)
  8. Select events via selectEvents_, it is not null, read the corresponding trigger results stored in tok_filterResults_. (See analyze.)
  9. Clear all containers for later usage, for instance, genParticlesToKeep_, genParticlesToMatch_, eventInfo_, triggerData_, triggerObjectMap_, particleInfo_. (See analyze.)
  10. Get the event data out via getEventData and trigger data via getTriggerData. (See analyze.)
  11. Fill event information via fillEventInfo. (See analyze.)
  12. Fill trigger information via fillTriggerInfo. (See analyze.)
  13. Fill lumi information via fillLumiInfo. (See analyze.)
  14. Fill reconstructed particle information via fillRecoParticleInfo. (See analyze.)
  15. Fill generated particle information via fillGenParticleInfo. (See analyze.)
  16. Fill entry into output tree:
    • If tree is wanted, initialize it via initTree. And then fill it.
    • If n-tuple is wanted, call fillNtuple.

2.3 Class member functions and variables

2.3.1 Member functions [0/9]

  1. virtual void ParticleAnalyzer::beginJob()

  2. virtual void ParticleAnalyzer::beginRun(const edm::Run&, const edm::EventSetup&)

    This function perform the followings:

  3. virtual void ParticleAnalyzer::analyze(const edm::Event&, const edm::EventSetup&)

    1. Select events via selectEvents_, it is not null, read the corresponding trigger results stored in tok_filterResults_.
    2. Clear all containers for later usage, for instance, genParticlesToKeep_, genParticlesToMatch_, eventInfo_, triggerData_, triggerObjectMap_, particleInfo_.
    3. Get the event data out via getEventData and trigger data via getTriggerData.
    4. Fill event information via fillEventInfo.
    5. Fill trigger information via fillTriggerInfo.
    6. Fill lumi information via fillLumiInfo.
    7. Fill reconstructed particle information via fillRecoParticleInfo.
    8. Fill generated particle information via fillGenParticleInfo.
    9. Fill entry into output tree:
      • If tree is wanted, initialize it via initTree. And then fill it.
      • If n-tuple is wanted, call fillNtuple.
  4. virtual void ParticleAnalyzer::getEventData(const edm::Event& iEvent, const edm::EventSetup& iSetup)

    This function will extract MC/data information from the ADO file. It will do the following in order: [0/0]

    1. Check whether the input file is for MC samples via isRealData in edm::Event.
    2. Get the magnetic field information.
    3. Get the Ntrkoffline value map if it exists.
    4. Extract the primary vertex from the PV collection.
      1. The vertex need to be !isFake() and is associated with at least two tracks.
      2. If none of vertices satisfies the criteria above, the beamspot is used instead.
      3. The primary vertex is selected among the collection based on sum over \(p_T^2\) or multiplicity. The default option vtxSortByTrkSize in the GeneralParticleProducer is true. Thus the vertex with highest multiplicity is selected.
    5. If MC samples are read, extract the generated particles' information.
      • The generated primary vertex information is saved in genVertex_. It is determined as the vertex of the first generate particle with status isLastCopy() == true (see more comments in the link, and an example is bremming electron will exists before and after photon emission) and absolute value of pdgId is less than or equal to 6 (quarks) or pdgId equal to 21 (gluon).
      • The container for generated particles is initialized via initParticleInfo with input parameter "gen".
      • The multiplicity of the generated particles is calculated. The result is saved in eventInfo_, with the attribute "Ntrkgen".
      • Generated particles used for reco-gen matching will be put to genParticlesToMatch_. The generated particles satisfying the followings will be used:
        • isLastCopy() is true; passGenStatus is true; the pdgId is contained in genPdgId_ (absolute value).
        • If the item above is satisfied, the analyzer will try to find the mother particles for stable particles via findGenMother. If the mother particle can be found and its pdgId can be found in genPdgId_, the stable particle (status()==1, not the mother particle) will be saved into genParticlesToMatch_.
      • Put the particles in genParticlesToMatch_ and their mothers (obtained via findGenMother), daughters (via findGenDaughter) into genParticlesToKeep_. The insertion is done via insert.
  5. TODO virtual void ParticleAnalyzer::getTriggerData(const edm::Event&, const edm::EventSetup&)

  6. virtual void ParticleAnalyzer::fillEventInfo(const edm::Event&)

    This function will create entries in eventInfo_. It will do the following:

  7. TODO virtual void ParticleAnalyzer::fillTriggerInfo(const edm::Event&)

  8. TODO virtual void ParticleAnalyzer::fillLumiInfo(const edm::Event&)

  9. virtual void ParticleAnalyzer::fillRecoParticleInfo(const edm::Event&)

    The reconstructed particles will be retrieved via tokrecParticle_. If succeeding, entries "cand" and "trk" will be initialized via initParticleInfo. And particles with IDs in sourceId_ will also be initialized via initParticleInfo with "src". After initialization, particles will be filled into particleInfo_["cand"]​ via fillRecoParticleInfo.

  10. virtual void ParticleAnalyzer::fillGenParticleInfo(const edm::Event&)

    It will fill the particles in genParticlesToKeep_ to particleInfo_["gen"]​ via fillGenParticleInfo. Particles which have already been filled during reco-gen matching won't be filled this time.

    And the generator weight, LHE weights will also be filled into eventInfo_.

  11. TODO virtual void ParticleAnalyzer::endJob()

  12. virtual void ParticleAnalyzer::initTree()

    Initialize tree_ via initTree of eventInfo_ and initTree of each entry in particleInfo_. The branches from particleInfo_ are named starting with the corresponding names of entries.

  13. virtual void ParticleAnalyzer::initNTuple()

    The tree pointed by ntuple_ will be initialized by ntupleInfo_ via initTree.

  14. virtual void ParticleAnalyzer::addParticleToNtuple(const size_t& i, const std::pair<int, int>& dau)

    This function has two parameters:

    i
    It is the index of the candidate (status == 3, see fillNTuple) in particleInfo_["cand"]​.
    dau
    It is map between the generation of particles and the index of the particle in the corresponding generation. The daughter of the main entry will have generation 1. Generation-1 particles will have the label "dau"; generation-2 particles (granddaughters) will have the label "gdau"; generation-3 particles will have "ggdau" and so on.

    After determining the label, candidate information will be retrieved by i, by get. Other information in particleInfo_ for type ({"trig", "gen", "trk"}) will by retrieved by typeIdx such as "trigIdx". And information for jet, electron, muon, tau and photons are retrieved by "srcIdx". Here is a trick that index need to be less than USHRT_MAX. The index used to retrieve particle information other than "cand" is initialized by UShort_t(-1).

    Now, the index has been obtained. Information will be copied to ntupleInfo_ via copyData.

    The daughter information will be added via recursively call addParticleToNtuple with the generation added by one each time.

  15. virtual void fillNTuple()

    Each entry in ntupleInfo_ will be filled here. It will loop over all candidates in particleInfo_["cand"]​. and then put every candidate with status == 3 (user-defined status. See GeneralParticleProducer) into ntupleInfo_. It will perform the followings:

    1. Copy event information in eventInfo_ to ntupleInfo_ via copyData.
    2. Copy particle information in particleInfo_["cand"]​ to ntupleInfo_ via addParticleToNtuple.
    3. Save information in ntupleInfo_ to ntuple_. If ntuple_ is not initialized, erase the entries containing {"Idx", "cand_matchTRG", "cand_momMatch", "lheWeight"} in ntupleInfo_ and then call initNtuple.
  16. TODO UShort_t ParticleAnalyzer::fillTriggerObjectInfo(const pat::TriggerObjectStandAlone&, const UShort_t&, const bool&, const UShort_t& candIdx=USHRT_MAX)

    This function will fill the trigger object to =particleInfo_["trig"]​=. It will make use of getIndex, or via push. The index of the filled object will be returned;

  17. UInt_t ParticleAnalyzer::fillRecoParticleInfo(const pat::GenericParticle& cand, const UShort_t& momIdx=USHRT_MAX) [0/1]

    There are two input parameters: cand for the candidate will be filled; momIdx for the index of the mother particle of cand in particleInfo_["cand"]​. momIdx is useful and meaningful when filling the daughters of a candidate. You will see it later, in a recursive call of this function.

    In the initialization processes, a null pat::GenericParticle.

    It will make use of getIndex to check whether cand has already been filled into particleInfo_["cand"]​. If the mother particle with index momIdx matches the gen-particle, the entry for momMatchGEN and momMatchIdx will be modified.

    And if the input particle has been put into particleInfo_["cand"]​, the corresponding index will be returned and this function stops. Otherwise the following content will be executed and the size_ will be returned (it is also the index for this unrecorded particle).

    If the particles has not been recorded, then information of the input cand will be saved into particleInfo_["cand"]​ via add (the setter of data_). It will fill the followings:

    Kinematic variables
    These variables of the input cand will be filled, such as momentum.
    Ntrkoffline
    It will be filled if nTracksVMap_ is not empty.
    mva
    It will be filled if addInfo_["mva"]​ is true.
    Trigger related information
    When the triggerData_ is not empty, trigger related information will be associated with the input cand via addTriggerObject. Entries matchTRG%d and trigIdx may be created.
    Track related information
    The corresponding track index in particleInfo_["trk"]​, obtained via fillTrackInfo.
    Information from "source"
    The corresponding index in particleInfo_["src"]​, obtained via fillSourceInfo.
    MC related information
    If the candidate does not have the pat::userInt("isGenMatched"), add the gen-particle information via addGenParticle with cand, p4 of cand and genParticlesToMatch_. The genIdx is obtained by fillGenParticleInfo.
    Daughter related information
    If no daughter found, empty vectors are placed. If daughters are found, the corresponding index of each daughter is obtained by fillRecoParticleInfo. Note, daughter info will be recursively retrieved.
  18. UShort_t ParticleAnalyzer::fillTrackInfo(const pat::GenericParticle& cand, const UShort_t& candIdx, const bool& force=false)

    There are three input parameters: cand for the candidate will be filled; candIdx for the index of cand in particleInfo_["cand"]​; force means whether force the particleInfo_["trk"]​ to create an entry, otherwise the USHRT_MAX will be returned as the track index.

    It will make use of getIndex to check whether cand has already been filled into particleInfo_["trk"]​. The candIdx for this track entry in particleInfo_["trk"]​ will be filled via push. If this candidate has been filled before, then an new element will be appended to the back of the particleInfo_["trk"].ushortVVM.at(candIdx).at("candIdx").

    And if the input particle has been put into particleInfo_["cand"]​, the corresponding index in particleInfo_["trk"]​ will be returned and this function stops. Otherwise the following content will be executed and the size_ of particleInfo_["trk"]​ will be returned (it is also the index for this unrecorded track info).

    If the track info has not been recorded, then the track info related to the input cand will be saved into particleInfo_["trk"]​ via add (the setter of data_). It will fill the kinematic variables and quality variables. See more in particleInfo_["trk"]​.

    For the initialization process, null GenericParticle, 0 and true are used. It will force the particleInfo_["trk"]​ to create entries in table since 0 is not less than size_ before initialization. After putting dummy values in particleInfo_["trk"]​, the values will be cleared via clear in initParticleInfo.

  19. UShort_t ParticleAnalyzer::fillSourceInfo(const pat::GenericParticle& cand, const UShort_t& candIdx, const bool& force=false)

    There are three parameters: the input cand, the index for cand in particleInfo_["cand"]​, and whether the candidate is forced to insert into container.

    It will call fillXXXXinfo depending on pdgId (absolute value).

    ==0
    call fillPFCandidateInfo.
    <=6
    call fillJetInfo.
    ==11
    call fillElectronInfo.
    ==13
    call fillMuonInfo.
    ==15
    call fillTauInfo.
    Otherwise
    call fillPFCandidateInfo.
  20. UShort_t ParticleAnalyzer::fillMuonInfo(const pat::GenericParticle& cand, const UShort_t&, const bool& force=false)

    There are three parameters: the input cand, the index for cand in particleInfo_["cand"]​, and whether the candidate is forced to insert into container.

    If force is not enabled, USHRT_MAX will be returned. After enabling force, this function will check whether there exists any userData<pat::Muon> in cand. If not, USHRT_MAX will be returned. Otherwise, followings will be evaluate. And please also check the paper.

    It will fill several types of information of muon into paticleInfo_["muon"]​. When generating bit-wise selector, it will make use of Selector. And it will also generate a bit-wise selection types map, via \(\sum_{i=0}^{29}2^i\). And muon ID will also be filled.

    For the initialization process, null GenericParticle with electron candidate pdgId (13), 0 and true are used. It will force the particleInfo_["muon"]​ to create entries in table since 0 is not less than size_ before initialization. After putting dummy values in particleInfo_["muon"]​, the values will be cleared via clear in initParticleInfo.

  21. UShort_t ParticleAnalyzer::fillElectronInfo(const pat::GenericParticle& cand, const UShort_t&, const bool& force=false)

    There are three parameters: the input cand, the index for cand in particleInfo_["cand"]​, and whether the candidate is forced to insert into container.

    If force is not enabled, USHRT_MAX will be returned. After enabling force, this function will check whether there exists any userData<pat::Electron> in cand. If not, USHRT_MAX will be returned. Otherwise, followings will be evaluate. And please also check the paper and paper.

    It will fill several types of information of electron into paticleInfo_["elec"]​.

    For the initialization process, null GenericParticle with electron candidate pdgId (11), 0 and true are used. It will force the particleInfo_["elec"]​ to create entries in table since 0 is not less than size_ before initialization. After putting dummy values in particleInfo_["elec"]​, the values will be cleared via clear in initParticleInfo.

  22. UShort_t ParticleAnalyzer::fillPhotonInfo(const pat::GenericParticle& cand, const UShort_t&, const bool& force=false)

    There are three parameters: the input cand, the index for cand in particleInfo_["cand"]​, and whether the candidate is forced to insert into container.

    If force is not enabled, USHRT_MAX will be returned. After enabling force, this function will check whether there exists any userData<pat::Photon> or userData<pat::Conversion> in cand. If not, USHRT_MAX will be returned. Otherwise, followings will be evaluate. And please also check the paper.

    It will fill several types of information of photons or gamma conversions into paticleInfo_["pho"]​. Photons are labeled by pdgId 22, while conversions are -22.

    For the initialization process, null GenericParticle with photon (conversion) candidate pdgId 22(-22), 0 and true are used. It will force the particleInfo_["pho"]​ to create entries in table since 0 is not less than size_ before initialization. After putting dummy values in particleInfo_["pho"]​, the values will be cleared via clear in initParticleInfo.

  23. TODO UShort_t ParticleAnalyzer::fillJetInfo(const pat::GenericParticle& cand, const UShort_t candIdx&, const bool& force=false)

    There are three parameters: the input cand, the index for cand in particleInfo_["cand"]​, and whether the candidate is forced to insert into container.

    If force is not enabled, USHRT_MAX will be returned. After enabling force, this function will check whether there exists any userData<pat::Jet> in cand. If not, USHRT_MAX will be returned. Otherwise, followings will be evaluated.

    It will fill several types of information of jet into paticleInfo_["jet"]​.

    Among these information, please note l2 is calculated via L2-corrected jet pT over raw pT; l3 is calculated via L3-corrected pT divided by L2-corrected pT; B-tag is calculated by \(\sum_{i} i^2\) The value of each tag is not included. Please see more in getPairDiscri and CMS-DAS by BTV-POG.

    For the initialization process, null GenericParticle with jet pdgId, 0 and true are used. It will force the particleInfo_["jet"]​ to create entries in table since 0 is not less than size_ before initialization. After putting dummy values in particleInfo_["jet"]​, the values will be cleared via clear in initParticleInfo.

  24. UShort_t ParticleAnalyzer::fillTauInfo(const pat::GenericParticle& cand, const UShort_t&, const bool& force=false)

    There are three parameters: the input cand, the index for cand in particleInfo_["cand"]​, and whether the candidate is forced to insert into container.

    If force is not enabled, USHRT_MAX will be returned. After enabling force, this function will check whether there exists any userData<pat::Tau> in cand. If not, USHRT_MAX will be returned. Otherwise, followings will be evaluate. And please also check the paper.

    It will fill several types of information of tau into paticleInfo_["tau"]​.

    For the initialization process, null GenericParticle with electron candidate pdgId (15), 0 and true are used. It will force the particleInfo_["tau"]​ to create entries in table since 0 is not less than size_ before initialization. After putting dummy values in particleInfo_["tau"]​, the values will be cleared via clear in initParticleInfo.

  25. UShort_t ParticleAnalyzer::fillPFCandidateInfo(const pat::GenericParticle& cand, const UShort_t&, const bool& force=false)

    There are three parameters: the input cand, the index for cand in particleInfo_["cand"]​, and whether the candidate is forced to insert into container.

    If force is not enabled, USHRT_MAX will be returned. After enabling force, this function will check whether there exists any userData<pat::PFCandidate> in cand. If not, USHRT_MAX will be returned. Otherwise, followings will be evaluated.

    It will fill several types of information of PF candidate into paticleInfo_["pf"]​. See more in paticleInfo_["pf"]​.

    For the initialization process, null GenericParticle with PF candidate pdgId, 0 and true are used. It will force the particleInfo_["pf"]​ to create entries in table since 0 is not less than size_ before initialization. After putting dummy values in particleInfo_["pf"]​, the values will be cleared via clear in initParticleInfo.

  26. UShort_t ParticleAnalyzer::fillGenParticleInfo(const reco::GenParticleRef& canR, const UShort_t& candIdx=USHRT_MAX, const bool& force=false)

    There are three parameters: the reference to the gen-particle candR, the index of the reco-particle matching candR, and whether the entry will be forced to create.

    It will fill several types of information of reco::GenParticle into paticleInfo_["gen"]​. See more in paticleInfo_["gen"]​.

  27. void ParticleAnalyzer::initParticleInfo(const std::string&, const int& pId=0)

    This function helps user initialize the entries in container particleInfo_. It has the following categories:

    "trig"
    It will save trigger objects, initialized by fillTriggerObjectInfo. The initialization will not be done if triggerData_ is empty or addInfo_["trgObj"] is false.
    "trk"
    It will save tracking information, initialized by fillTrackInfo. The initialization will not be done if addInfo_["track"] is false.
    "gen"
    It will save information related to generated particles, initialized by fillGenParticleInfo. The initialization will not be done if isMC_ is false.
    "src"
    The initialization will not be done if addInfo_["source"] is false.
    "cand"
    It will save the reconstructed particles, initialized by fillRecoParticleInfo.

    All the dummy values after fillXXXXInfo will be cleared via clear.

  28. TODO void ParticleAnalyzer::addTriggerObject(pat::GenericParticle&)

  29. TODO bool ParticleAnalyzer::addTriggerObject(pat::GenericParticle&, const math::XYZTLorentzVector&, const TriggerIndexMap&, const std::string&, const std::string&, const int&)

  30. TODO bool ParticleAnalyzer::addGenParticle(pat::GenericParticle& cand, const math::XYZTLorentzVector& p4, const reco::GenParticleRefVector& genColl)

    The return value will indicate whether a GenParticle will be added.

    If the input genColl is empty or the status (user-defined) of cand is 0, this function will return false.

    If cand.hasUserInt("isGenMatched") is true, then it will return the whether the genParticle associated with cand can be find in genColl.

    There won't be a userInt called "isGenMatched" if it is the first call of this function. Then the following will be evaluated.

    Initialization
    There will be a userInt called "isGenMatched" initialized with 1.
    Reco-gen matching
    In this step, compatible particles in genColl with cand will be used. It evolves two categories:
    • cand is a final state particle. Then cand will be directly compared with particles in genColl, using isMatched, starting from maxGenDeltaR_ and maxGenDeltaPtRel_. The particle in genColl having the closet pT to cand will be taken as the matched gen-particle. If the momenta matches but the mass does not, the particle is labeled as swap.
    • cand is a unstable particle. Then the daughters of cand (if they are final state particles) will be used to perform reco-gen matching. The collection (genDauColl) of generated-level daughter particles used in reco-gen matching is collected via findGenDaughters with empty collection to save genDauColl, genPar, daughter (dau) of cand and maxGenIter. And then calling addGenParticle will check whether dau has a gen-matched particle in genDauColl. If not, it is not necessary to check the remaining daughter particles. Swapped info is also obtained via the gen-matching result.

    The non-ideal case: supposing we have {Ks{1}, pi+{1}, pi-{1}, Ks{2}, pi+{2}, pi-{2}} in gen-level, and Ks(1) in reco-level. Ks(1) is identical Ks{2}. However, pi+(1) can be matched onto both pi+{1} and pi+{2}. At the beginning, particles above mentioned will be passed into this function. Later, the second category is triggered. It will try the following, creating a small collection {pi+{1}} and check whether it matching pi+(1). Yes it matches, pi+(1) is associated with pi{1}, but pi-{1} does not match pi-(1). Thus Ks{1} does not match Ks(1). The loop over the initial gen collection goes to next step. pi-(1) matches pi+{2}. However, pi+(1) now is associated with pi+{1}, not pi-{1}, the matching fails !

  31. void ParticleAnalyzer::findGenDaughters(reco::GenParticleRefVector& genColl, const reco::GenParticleRef& genPar, const pat::GenericParticle& cand, const short& iter=0)

    This function has four parameters:

    • genColl is used to save the matched gen-particles (daughters of input genPar). Its value might be modified by this function.
    • genPar is the input gen-particle. Its daughter particles will be compared with cand, checking whether reco-gen matching succeeds.
    • cand is the input reco-particle. It will be compared with daughters of genPar.
    • iter is the maximum times of recursive call of findGenDaughters.

    This function will behave like the following:

    • Do nothing during iter is negative
    • Loop over each daughter of genPar. Put the gen-particle compataible with cand into genColl.
    • Recursively call findGenDaughters, taking:
      • genColl as genColl
      • genPar daughter particle as genPar,
      • cand as cand
      • iter-1 as iter

    In other words, it will stop after search through a few generations. By default it will stop for the first generation (iter==0).

  32. reco::GenParticleRef ParticleAnalyzer::findGenDaughter(const reco::GenParticleRef& par, const size_t& idx)

    It will return the idx-th daughter of the input par via reco::GenParticle::daughterRef(). If the daughter has its daughter (granddaughter) with the same pdgId, the granddaughter will be returned. Similar check also works for the granddaughter.

    This function will return an null reference if one of the following satisfies:

    • The input par is null.
    • The number of daughterparticles of the input par is less than idx.
  33. reco::GenParticleRef ParticleAnalyzer::findGenMother(const reco::GenParticleRef par)&

    Find the mother particle of the input particle. It will return an empty reco::GenParticleRef() if one of the following satisfies:

    • The input par is null.
    • The number of mother particles of the input par is 0.
    • The mother particle ultimately has the same pdgId as the input par after a few iterations.
  34. Retrieve user int and float

    See codes (may be outdated) below:

    int   getInt  (const pat::GenericParticle& c, const std::string& n, const int&   d=-99  ) const { return (c.hasUserInt(n)   ? c.userInt(n)   : d); }
    float getFloat(const pat::GenericParticle& c, const std::string& n, const float& d=-99.9) const { return (c.hasUserFloat(n) ? c.userFloat(n) : d); }
    
  35. Convert numbers to values with shorter length

    See codes (may be outdated) below:

    template <class T> Char_t   getChar  (const T& n) const { if (!(n >= CHAR_MIN && n < CHAR_MAX )) { throw(cms::Exception("Overflow")<<"Invalid char: "  <<n); }; return Char_t(n);   }
    template <class T> UChar_t  getUChar (const T& n) const { if (!(n >= 0        && n < UCHAR_MAX)) { throw(cms::Exception("Overflow")<<"Invalid uchar: " <<n); }; return UChar_t(n);  }
    template <class T> Short_t  getShort (const T& n) const { if (!(n >= SHRT_MIN && n < SHRT_MAX )) { throw(cms::Exception("Overflow")<<"Invalid short: " <<n); }; return Short_t(n);  }
    template <class T> UShort_t getUShort(const T& n) const { if (!(n >= 0        && n < USHRT_MAX)) { throw(cms::Exception("Overflow")<<"Invalid ushort: "<<n); }; return UShort_t(n); }
    template <class T> Int_t    getInt   (const T& n) const { if (!(n >= INT_MIN  && n < INT_MAX  )) { throw(cms::Exception("Overflow")<<"Invalid int: "   <<n); }; return Int_t(n);    }
    template <class T> UInt_t   getUInt  (const T& n) const { if (!(n >= 0        && n < UINT_MAX )) { throw(cms::Exception("Overflow")<<"Invalid uint: "  <<n); }; return UInt_t(n);   }
    
  36. Helper functions

    contain

    Check whether the the input collection has the input element:

    template <class T1, class T2> bool contain (const T1& v, const T2& o) const { return (std::find(v.begin(), v.end(), o)!=v.end()); }

    insert

    Insert the input GenParticle to the input collection:

    void insert (reco::GenParticleRefVector& v, const reco::GenParticleRef& p) { if (p.isNonnull() && !contain(v, p)) { v.push_back(p); } }

    isCompatible

    Check the if we can compare these two input candidates, in the sense that

    • They are both stable; they have the same charge; they have the same pdgId (absolute value)
    • Neither of them are stable; they have the same charge.

    bool isCompatible(const reco::Candidate& p1, const reco::Candidate& p2) const

    deltaPt

    Return the relative difference of pT, taking the square root of product of two input as the denominator:

    double deltaPt(const double& pT1, const double& pT2) const

    isMatched

    Compare two Lorentz vectors (maybe not necessary to be Lorentz vector), depending on \(\Delta R\) and \(\Delta p_T\):

    bool isMatched(const math::XYZTLorentzVector& c1, const math::XYZTLorentzVector& c2, const double& maxDeltaR, const double& maxDeltaPtRel)

    isL1MuMatched

    Compare the if one is matched the other, depending on \(\Delta \eta\), \(\Delta R\) and \(\Delta \phi\):

    bool isL1MuMatched(const math::PtEtaPhiMLorentzVector& c, const math::XYZTLorentzVector& t, const double& maxDeltaR, const double& maxDeltaEta, const double& maxDeltaPhi)

    passGenStatus

    Check whether pass the gen status, see codes (might be outdated) below:

    bool passGenStatus(const reco::GenParticleRef& p) const
    {
      return (p->status()==1 || p->statusFlags().isDecayedLeptonHadron());
    }
    
  37. edm::ParameterSet ParticleAnalyzer::getConfiguration(const std::string& module, const std::string& process, const edm::Run& iRun)

    This function will return the parameter set corresponding to module and process via tools given by cmssw. Empty parameter set might be returned depending on the input.

  38. edm::ParameterSet ParticleAnalyzer::getConfiguration(const edm::EDGetToken&, const edm::Run&)

    It will pass the label of the input token. And then it pass the label and run to getConfiguration and return the results from getConfiguration.

  39. void ParticleAnalyzer::loadConfiguration(const edm::ParameterSet&, const edm::Run&)

    The following variables might be initialized or modified, depedning on the input and the times this function has been called.

    vtxSortByTrkSize_
    It will be set to the value in parameter set if "vtxSortByTrkSize" existed. Otherwise it becomes true.
    sourceId_
    The pdgId of parameter set (in provenance) will be inserted to sourceId_ if pdgId exists and it is in SOURCEPDGID_.
    Entries in addInfo_

    They will be true unless the corresponding criteria is satisfied:

    "source"
    The length is sourceId_ is positive.
    "track"
    The charge of the particle in the input parameter set is non-zero.
    "dEdxs"
    The string vector naming after "dEdxInputs" exists and the size of the vector is non-zero.
    "mva"
    The edm::InputTag mva (used for tracks) in parameter set exists and its label is not empty.
    "muonL1"
    The pdgId in the parameter set needs to be 13. If the parameter "propToMuon" does not exits, it is true. Otherwise it is set to the value of "propToMuon" in the input configuration set.

    The parameters above will keep true once the criteria satisfied. Before they become true, there might be several times loadConfiguration called and the checks above will be evaluated each time.

    This function will be recursively called by itself if "source" and "daughterInfo" exist in the input parameter set.

2.3.2 class ParticleAnalyzer::Container

This is a container for each candidate.

  1. Getters

    These are fetters for different data types. Member variables for this container. See codes (might be outdated) below:

    // getters
    std::map<std::string, bool     > boolM()   const { return boolM_;   };
    std::map<std::string, Char_t   > charM()   const { return charM_;   };
    std::map<std::string, short    > shortM()  const { return shortM_;  };
    std::map<std::string, int      > intM()    const { return intM_;    };
    std::map<std::string, UChar_t  > ucharM()  const { return ucharM_;  };
    std::map<std::string, UShort_t > ushortM() const { return ushortM_; };
    std::map<std::string, UInt_t   > uintM()   const { return uintM_;   };
    std::map<std::string, float    > floatM()  const { return floatM_;  };
    std::map<std::string, std::vector<bool>     > boolVM()   const { return boolVM_;   };
    std::map<std::string, std::vector<Char_t>   > charVM()   const { return charVM_;   };
    std::map<std::string, std::vector<short>    > shortVM()  const { return shortVM_;  };
    std::map<std::string, std::vector<int>      > intVM()    const { return intVM_;    };
    std::map<std::string, std::vector<UChar_t>  > ucharVM()  const { return ucharVM_;  };
    std::map<std::string, std::vector<UShort_t> > ushortVM() const { return ushortVM_; };
    std::map<std::string, std::vector<UInt_t>   > uintVM()   const { return uintVM_;   };
    std::map<std::string, std::vector<float>    > floatVM()  const { return floatVM_;  };
    
  2. Setters

    These functions are for creating new entry n or modifying existing entry n of each map. The name add may be confusing. See code (might be outdated) below:

    template <class T>
    void add(const std::string& n, const T&        v) = delete; // avoid implicit conversion
    void add(const std::string& n, const bool&     v) { boolM_[n]   = v; };
    void add(const std::string& n, const Char_t&   v) { charM_[n]   = v; };
    void add(const std::string& n, const short&    v) { shortM_[n]  = v; };
    void add(const std::string& n, const int&      v) { intM_[n]    = v; };
    void add(const std::string& n, const UChar_t&  v) { ucharM_[n]  = v; };
    void add(const std::string& n, const UShort_t& v) { ushortM_[n] = v; };
    void add(const std::string& n, const UInt_t&   v) { uintM_[n]   = v; };
    void add(const std::string& n, const float&    v) { floatM_[n]  = v; };
    void add(const std::string& n, const double&   v) { floatM_[n]  = v; };
    void add(const std::string& n, const std::vector<bool>&     v) { boolVM_[n]   = v; };
    void add(const std::string& n, const std::vector<Char_t>&   v) { charVM_[n]   = v; };
    void add(const std::string& n, const std::vector<short>&    v) { shortVM_[n]  = v; };
    void add(const std::string& n, const std::vector<int>&      v) { intVM_[n]    = v; };
    void add(const std::string& n, const std::vector<UChar_t>&  v) { ucharVM_[n]  = v; };
    void add(const std::string& n, const std::vector<UShort_t>& v) { ushortVM_[n] = v; };
    void add(const std::string& n, const std::vector<UInt_t>&   v) { uintVM_[n]   = v; };
    void add(const std::string& n, const std::vector<float>&    v) { floatVM_[n]  = v; };
    
  3. void ParticleAnalyzer::Container::push

    This function is overridden many times. The basic functionality is to push the value v to the vector with the same type which is also identified by the key n. If c is true, then it will check whether v overflows. Please check the code below (may be outdated).

    template <class T>
    void push(const std::string& n, const T&        v, const bool& c=0) = delete; // avoid implicit conversion
    void push(const std::string& n, const bool&     v, const bool& c=0) { boolVM_[n].push_back(v);  };
    void push(const std::string& n, const Char_t&   v, const bool& c=0) { if(!c || v!=CHAR_MAX ) charVM_[n].push_back(v);   };
    void push(const std::string& n, const short&    v, const bool& c=0) { if(!c || v!=SHRT_MAX ) shortVM_[n].push_back(v);  };
    void push(const std::string& n, const int&      v, const bool& c=0) { if(!c || v!=INT_MAX  ) intVM_[n].push_back(v);    };
    void push(const std::string& n, const UChar_t&  v, const bool& c=0) { if(!c || v!=UCHAR_MAX) ucharVM_[n].push_back(v);  };
    void push(const std::string& n, const UShort_t& v, const bool& c=0) { if(!c || v!=USHRT_MAX) ushortVM_[n].push_back(v); };
    void push(const std::string& n, const UInt_t&   v, const bool& c=0) { if(!c || v!=UINT_MAX ) uintVM_[n].push_back(v);   };
    void push(const std::string& n, const float&    v, const bool& c=0) { floatVM_[n].push_back(v); };
    void push(const std::string& n, const double&   v, const bool& c=0) { push(n, float(v), c); }
    
  4. void ParticleAnalyzer::Container::copyData(Container& data, const std::string& n="") const

    The variables in this container will be copied to the input data. Each name of the entry in maps of data will start with n, then the name of corresponding entry in maps of this. Those vectors will be split to different entry ending with i-th in data. Say, intVM_ in this will become a series of intM_ in data.

  5. void Particle::Container::clear()

    Make each entry in maps of this become meaningless. Boolean will be false; signed numbers will be negative; unsigned numbers will be 0; vectors will be empty.

  6. template <class T> ParticleAnalyzer::Container::void erase(std::map<std::string, T>& c, const std::string& n)

    If finding the entry naming after n, erase it from the input map c.

  7. void ParticleAnalyzer::Container::erase(const std::string& n, const std::vector<std::string>& tv)

    Erase entries of maps of this. The erased entries names after n in types of type in tv.

  8. void initTree(TTree& tree, const std::string& n="")

    Initialize the input tree with branches corresponding to each entry in maps of this. Each branch will start with the input n and then the entry name in maps.

  9. Member variables for data storag

    These variables have the following naming convention. Every variable ending with M_ is a map between string and a c++ type. Every variable ending with VM_ is a map between string and a vector. In principle, these variables are for saving information of each candidate. See code (might be outdated) below:

    std::map<std::string, bool     > boolM_;
    std::map<std::string, Char_t   > charM_;
    std::map<std::string, short    > shortM_;
    std::map<std::string, int      > intM_;
    std::map<std::string, UChar_t  > ucharM_;
    std::map<std::string, UShort_t > ushortM_;
    std::map<std::string, UInt_t   > uintM_;
    std::map<std::string, float    > floatM_;
    std::map<std::string, std::vector<bool>     > boolVM_;
    std::map<std::string, std::vector<Char_t>   > charVM_;
    std::map<std::string, std::vector<short>    > shortVM_;
    std::map<std::string, std::vector<int>      > intVM_;
    std::map<std::string, std::vector<UChar_t>  > ucharVM_;
    std::map<std::string, std::vector<UShort_t> > ushortVM_;
    std::map<std::string, std::vector<UInt_t>   > uintVM_;
    std::map<std::string, std::vector<float>    > floatVM_;
    

2.3.3 class ParticleAnalyzer::ParticleContainer

This is a container for a series of candidates. The initialized number of candidates (size_) is 0.

  1. size_t size() const

    Return size_.

  2. bool ParticleAnalyzer::ParticleContainer::getIndex(size_t& index, const reco::Candidate& cand) const

    This function will modify the input index to:

    • the size of the container if not finding any identical element to cand, otherwise
    • the index of the element in container identical to the input cand.

    This function will return false if no element in the container is identical to cand, otherwise return true.

  3. Getters

    The i-th element of entry n in VM_ will be returned. If i is larger than the size_, return the default value d. See codes (might be outdated) below:

    template <class T>
    T        get(const size_t& i, const std::string& n, const T&        d) const = delete; // avoid implicit conversion
    bool     get(const size_t& i, const std::string& n, const bool&     d) const { return (i < size_ ? boolVM_.at(n)[i]   : d); };
    int      get(const size_t& i, const std::string& n, const Int_t&    d) const { return (i < size_ ? intVM_.at(n)[i]    : d); };
    UChar_t  get(const size_t& i, const std::string& n, const UChar_t&  d) const { return (i < size_ ? ucharVM_.at(n)[i]  : d); };
    UShort_t get(const size_t& i, const std::string& n, const UShort_t& d) const { return (i < size_ ? ushortVM_.at(n)[i] : d); };
    std::vector<UShort_t> get(const size_t& i, const std::string& n, const std::vector<UShort_t>& d) const { return (i < size_ ? ushortVVM_.at(n)[i] : d); };
    
  4. Setters for data_

    This function will set a value via add to data_.:

    template <class T> void add(const std::string& n, const T& v) { data_.add(n, v); }

  5. Setters for VM_ or data_

    This function will check whether the input i exceeds the size_. If not, it will set the i-th element of entry n in VM_ to value v; otherwise, it will set the entry n in data_ via add. See codes (might be outdated) below:

    template <class T>
    void add(const size_t& i, const std::string& n, const T&        v) = delete; // avoid implicit conversion
    void add(const size_t& i, const std::string& n, const bool&     v) { if (i < size_) { boolVM_[n][i]   = v; } else { add(n, v); } };
    void add(const size_t& i, const std::string& n, const UShort_t& v) { if (i < size_) { ushortVM_[n][i] = v; } else { add(n, v); } };
    
  6. void push(const size_t& i, const std::string& n, const T& v, const bool& c=0)

    If the i is smaller than size_, push the value to the i-th existing vector of the double vector via pushV; otherwise push a new entry to data_ via push.

  7. template <class T> void ParticleAnalyzer::ParticleContainer::push(const std::string& n, const T& v, const bool& c=0)

    It will push key and values to data_ via push.

  8. void ParticleAnalyzer::ParticleContainer::pushV

    This function is intended to push a value to the back of the i-th element in the double vector, via pushBack. It will not check whether v overflows, unless c is set to true. It is overridden many times. See codes (may be outdated) below:

    template <class T>
    void pushV(const size_t& i, const std::string& n, const T&        v, const bool& c=0) = delete; // avoid implicit conversion
    void pushV(const size_t& i, const std::string& n, const UChar_t&  v, const bool& c=0) { if(!c || v!=UCHAR_MAX) pushBack(ucharVVM_[n], i, n, v);  };
    void pushV(const size_t& i, const std::string& n, const UShort_t& v, const bool& c=0) { if(!c || v!=USHRT_MAX) pushBack(ushortVVM_[n], i, n, v); };
    void pushV(const size_t& i, const std::string& n, const UInt_t&   v, const bool& c=0) { if(!c || v!=UINT_MAX ) pushBack(uintVVM_[n], i, n, v);   };
    void pushV(const size_t& i, const std::string& n, const float&    v, const bool& c=0) { pushBack(floatVVM_[n], i, n, v); };
    void pushV(const size_t& i, const std::string& n, const double&   v, const bool& c=0) { pushV(i, n, float(v), c); };
    
  9. template <class T> void ParticleAnalyzer::ParticleContainer::pushBack(std::vector<std::vector<T> >& c, const size_t& i, const std::string& n, const T& v)

    Push the value v to the i-th element of the double vector c.

  10. void ParticleAnalyzer::ParticleContainer::pushData(const reco::Candidate& cand)

    This function will append data saved in data_ to variables for data storage associated with parM_. If the input cand can be found in parM_, an error will be thrown.

  11. void ParticleAnalyzer::ParticleContainer::copyData(Container& data, const size_t& i, const std::string& n="") const

    This function will copy i-th element from VM_ and VVM_ to the input data via add. If the input i is larger than current size of the this container, a default value will be set: false for Boolean; -99 for signed numbers; 0 for unsigned numbers; and no vector will be added in this case. The name of each entry in maps of data will start with n, and then the name of entries in VM_ and VVM_. For values in VVM_, the name of new entries ending with the index of each element in VVM_.

  12. void ParticleAnalyzer::ParticleContainer::clear()

    Clear information in this container. size_ will be 0; data_ will be empty; parM_ will be empty; VM_ and VVM_ will be empty.

  13. void ParticleAnalyzer::initTree(TTree& tree, const std::string& n="")

    Initialize the input tree using VM_ and VVM_. The branches will read values saved in VM_ and VVM_ each time a entry of tree is filled. The name of each branch will start will n and then name of keys in maps.

  14. A new type Particle and ParticleAnalyzer::ParticleContainer::getPar(const reco::Candidate& cand) const

    Characterize the particle via its 3-momentum, mass, charge and pdgId. See codes (might be outdated) below:

    typedef std::tuple<float, float, float, float, char, int> Particle;
    
    Particle getPar(const reco::Candidate& cand) const
    {
      return Particle(cand.pt(), cand.eta(), cand.phi(), cand.mass(), cand.charge(), cand.pdgId());
    };
    
  15. size_t ParticleAnalyzer::ParticleContainer::size_

    It is the current number of particles in ParticleContainer. It will increase by one each time pushData is executed successfully.

  16. Container ParticleAnalyzer::ParticleContainer::data_

    It is a container for each particle candidate. See Container.

  17. std::map<Particle, size_t> ParticleAnalyzer::ParticleContainer::parM_

    It is map between the particle (characterized by Particle) and its index in the ParticleContainer. Note, it is not for Container. The index is the key to retrieve values in other variables for data storage. parM_ share the same index with VM_ and VVM_ variables.

  18. Member variables for data storage

    These variables have the following naming convention. Every variable ending with VM_ is a map between string and vector. Every variable ending with VVM_ is a map between string and vector<vector>. See code (might be outdated) below:

    std::map<std::string, std::vector<bool>     > boolVM_;
    std::map<std::string, std::vector<Char_t>   > charVM_;
    std::map<std::string, std::vector<short>    > shortVM_;
    std::map<std::string, std::vector<int>      > intVM_;
    std::map<std::string, std::vector<UChar_t>  > ucharVM_;
    std::map<std::string, std::vector<UShort_t> > ushortVM_;
    std::map<std::string, std::vector<UInt_t>   > uintVM_;
    std::map<std::string, std::vector<float>    > floatVM_;
    std::map<std::string, std::vector<std::vector<bool> >     > boolVVM_;
    std::map<std::string, std::vector<std::vector<Char_t> >   > charVVM_;
    std::map<std::string, std::vector<std::vector<short> >    > shortVVM_;
    std::map<std::string, std::vector<std::vector<int> >      > intVVM_;
    std::map<std::string, std::vector<std::vector<UChar_t> >  > ucharVVM_;
    std::map<std::string, std::vector<std::vector<UShort_t> > > ushortVVM_;
    std::map<std::string, std::vector<std::vector<UInt_t> >   > uintVVM_;
    std::map<std::string, std::vector<std::vector<float> >    > floatVVM_;
    

    The index of each VM_ and the first index of each VVM_, together with parM_, share the same index, corresponding to each candidate.

2.3.4 TODO class ParticleAnalyzer::TriggerInfo [0/1]

A typedef is used here: typedef std::map<std::string, std::vector<size_t> > TriggerIndexMap.

  1. Getters

    See codes (might be outdated) below:

    // getters
    int                  triggerIndex()  const { return triggerIndex_;  }
    int                  filterIndex()   const { return filterIndex_;   }
    int                  minN()          const { return minN_;          }
    bool                 validPrescale() const { return validPrescale_; }
    UShort_t             hltPrescale()   const { return hltPrescale_;   }
    UShort_t             l1Prescale()    const { return l1Prescale_;    }
    UChar_t              hltPDs()        const { return hltPDs_;        }
    std::string          triggerName()   const { return triggerName_;   }
    std::string          filterName()    const { return filterName_;    }
    std::array<bool,4>   triggerBit()    const { return triggerBit_;    }
    bool                 triggerBit(const size_t& i) const { return (i<triggerBit_.size() ? triggerBit_[i] : false); }
    TriggerIndexMap      filterObjects() const { return filterObjects_; }
    bool                 validLumi()     const { return validLumi_;     }
    float                recordLumi()    const { return recordLumi_;    }
    float                totalLumi()     const { return totalLumi_;     }
    
  2. Setters

    See codes (might be outdated) below.

    // setters
    // triggerBit_ = bit; others are mapped by their names
    void setInfo(const int& triggerIndex, const int& filterIndex,
                 const std::string& triggerName, const std::string& filterName, const int& minN,
                 const bool& validPrescale, const UShort_t& hltPrescale, const UShort_t& l1Prescale,
                 const UChar_t& hltPDs, const std::array<bool,4>& bit, const TriggerIndexMap& filterObjects);
    // validLumi_ = true; others are mapped by their names
    void setLumiInfo(const double& recordLumi, const double& totalLumi);
    
  3. TODO Member variables

    I list the member variables here (might be outdated).

    Table 6: Member variables for TriggerInfo
    Name Type Descriptions Default values
    triggerIndex_ int   -1
    filterIndex_ int   -1
    triggerName_ std::string   ""
    filterName_ std::string   ""
    minN_ int   0
    validPrescale_ bool   0
    hltPrescale_ UShort_t   0
    l1Prescale_ UShort_t   0
    hltPDs_ UChar_t   0
    triggerBit_ std::array<bool, 4>   {}
    filterObjects_ TriggerIndexMap   {}
    recordLumi_ float   0
    totalLumi_ float   0
    validLumi_ bool   0

2.3.5 TODO class ParticleAnalyzer::MatchInfo [0/1]

  1. TODO Member Variables and Getters

    Table 7: Member variables and Getters
    Name Type Descriptions Default values Getter
    collection_ std::string   "" std::string collection()
    maxDeltaR_ double   0 double maxDeltaR()
    maxDeltaPtRel double   0 double maxDeltaPtRel
    maxDeltaEta_ double   0 double maxDeltaEta()
    maxDeltaPhi_ double   0 double maxDeltaPhi()
  2. Setters

    See codes (might be outdated) below:

    // setters
    void setInfo(const std::string& collection, const double& maxDeltaR, const double& maxDeltaPtRel,
                 const double& maxDeltaEta, const double& maxDeltaPhi)
    

2.3.6 Member variables for input tokens

See more in configuration parameters and codes (might be outdated) below:

// input tokens
const edm::EDGetTokenT<reco::BeamSpot> tok_offlineBS_;
const edm::EDGetTokenT<reco::VertexCollection> tok_offlinePV_;
const edm::EDGetTokenT<pat::GenericParticleCollection> tok_recParticle_;
const edm::EDGetTokenT<reco::GenParticleCollection> tok_genParticle_;
const edm::EDGetTokenT<GenEventInfoProduct> tok_genInfo_;
const edm::EDGetTokenT<LHEEventProduct> tok_lheInfo_;
const edm::EDGetTokenT<int> tok_centBin_;
const edm::EDGetTokenT<reco::Centrality> tok_centSrc_;
const edm::EDGetTokenT<reco::EvtPlaneCollection> tok_eventPlaneSrc_;
const edm::EDGetTokenT<edm::TriggerResults> tok_triggerResults_;
const edm::EDGetTokenT<trigger::TriggerEvent> tok_triggerEvent_;
const edm::EDGetTokenT<edm::TriggerResults> tok_filterResults_;
const edm::EDGetTokenT<LumiInfo> tok_lumiInfo_;
const edm::EDGetTokenT<LumiScalersCollection> tok_lumiScalers_;
const edm::EDGetTokenT<OnlineLuminosityRecord> tok_lumiRecord_;
std::vector< edm::EDGetTokenT<LumiInfo> > tok_triggerLumiInfo_;
const edm::EDGetTokenT<edm::ValueMap<int> > tok_nTracksVMap_;

2.3.7 Member variables for input data [0/5]

  1. TODO const std::vector<edm::ParameterSet> ParticleAnalyzer::triggerInfo_, ParticleAnalyzer::matchInfo_

  2. const std::vector<std::string> eventFilters_

    Event filter names will be saved in the tree.

  3. const std::string selectEvents_

    Names of filters used in event selection, used by analyze.

  4. const bool saveTree_

    true
    Save the event in TTree format. It will save space but user need to retrieve the information via several types of indices.
    false
    Save the event in general ntuple format. It is easier to use.
  5. const int maxGenIter_

    The max of generation used in addGenParticle in fillGenParticleInfo.

  6. TODO const double maxGenDeltaR_, maxGenDeltaPtRel_

  7. const std::vector<UInt_t> genPdgIdV_

    Container for the input python parameter "genPdgId". Its content will be further copied into genPdgId_.

  8. std::map<std::string, bool> ParticleAnalyzer::addInfo_

    Entries in addInfo_ will be true unless the corresponding criteria is satisfied:

    "source"
    The length is sourceId_ is positive.
    "track"
    The charge of the particle in this parameter set in provenance is non-zero.
    "dEdxs"
    The string vector naming after "dEdxInputs" in provenance exists and the size of the vector is non-zero.
    "mva"
    The edm::InputTag mva (used for tracks) in parameter set in provenance exists and its label is not empty.
    "muonL1"
    The pdgId in the parameter set in provenance needs to be 13. If the parameter "propToMuon" does not exits, it is true. Otherwise it is set to the value of "propToMuon" in the input configuration set.
    "trgObj"
    Determined by addTrgObj in the configurations.

    The parameters above (except "trgObj") will keep true once the criteria satisfied. Before they become true, there might be several times loadConfiguration called and the checks above will be evaluated each time.

    Entries in addInfo_ are used to determined whether fill related info into corresponding entries in particleInfo_.

  9. std::set<int> sourceId_, genPdgId_

    sourceId_
    The particle information with pdgId in this collection will be filled into corresponding entry in particleInfo_.
    genPdgId_
    Particles' pdgId used for reco-gen matching. Particles with genPdgId_ will be saved in genParticlesToMatch_. It contains the particles in genPdgIdV_ and pdgId in parameter set found in loadConfiguration.
  10. TODO std::vector<std::string> dedxInfo_

  11. TODO HLTPrescaleProvider hltPrescaleProvider_

  12. TODO std::vector<std::vector<int> > l1PrescaleTable_

2.3.8 Member variables for attributes [0/1]

  1. edm::Service<TFileService> fileService_

    Used for file service.

  2. TTree* tree_, ntuple_

    Used for retrieving the tree and n-tuple.

  3. bool isMC_

    Check whether the input samples is MC or not. Determined in getEventData.

  4. bool vtxSortByTrkSize_

    It determine whether the primary vertex collection will be sorted by multiplicity. It is initialized by loadConfiguration.

  5. reco::Vertex vertex_

    It denotes the primary vertex. The value is set in getEventData.

  6. reco::Particle::Point genVertex_

    It denotes the primary vertex among generated particles. The value is set in getEventData.

  7. reco::VertexCollection vertices_

    This collection is to save the primary vertices satisfying criteria described in getEventData.

  8. reco::GenParticleRefVector genParticlesToKeep__

    The variable used to save genParticle collection for reco-gen matching. It contains the particles in genParticlesToMatch_ and their mothers (obtained via findGenMother), daughters (via findGenDaughter).

  9. reco::GenParticleRefVector genParticlesToMatch_

    The variable used to save genParticle collection for reco-gen matching. The generated particles satisfying the followings will be used:

    • isLastCopy() is true; passGenStatus is true; the pdgId is contained in genPdgId_ (absolute value).
    • If the item above is satisfied, the analyzer will try to find the mother particles for stable particles via findGenMother. If the mother particle can be found and its pdgId can be found in genPdgId_, the stable particle (status()==1, not the mother particle) will be saved into genParticlesToMatch_.
  10. const MagneticField* magField_

    It denotes the magnetic field in experiment. Value is set in getEventData.

  11. TODO edm::ValueMap<int> nTracksVMap_

    edm::ValueMap for Ntrkoffline.

  12. const std::set<int> SOURCEPDG_

    It contains pdgId of pfCandidate, quarks jets, gluon jets, electrons, muons, taus and photons. These particles need their own (extra) input source, not limited to GenericParticleCollection. It is the superio of sourceId_. See codes (might be outdated) below:

    const std::set<int> SOURCEPDG_ = {0,1,2,3,4,5,6,11,13,15,22};
    

2.3.9 Member variables for containers [0/4]

  1. TODO Container eventInfo_

    Table 8: Key-value pairs in eventInfo_
    Name Descriptions Created by
    Ntrkgen Multiplicity of generated particles getEventData
    RunNb Run number fillEventInfo
    EventNb event number fillEventInfo
    LSNb Lumi block number fillEventInfo
    BXNb Number of valid bunch crossing fillEventInfo
    nPV number of valid vertices passing criteria fillEventInfo
    bestvtxX, bestvtxY, bestvtxZ Positions of the primary vertex fillEventInfo
    evtSel Boolean array for filter results fillEventInfo
    HFsumETPlus Sum over ET in HF+ fillEventInfo
    HFsumETMinus Sum over ET in HF- fillEventInfo
    Npixel Number of hits in silicon pixel fillEventInfo
    ZDCPlus Sum over energies in ZDC+ fillEventInfo
    ZDCMinus Sum over energies in ZDC- fillEventInfo
    Ntrkoffline Ntrkoffline in centrality producer, there is also one from user-defined way in particleInfo_["cand"]​ fillEventInfo
    centrality The bin number of corresponding centrality fillEventInfo
    ephfmAngle A vector of event plane angle by HF-, re-centered and flattened: elements are 1st, 2nd, 3rd order event plane info in order, see link. fillEventInfo
    ephpAngle A vector of event plane angle by HF+, re-centered and flattened: elements are 1st, 2nd, 3rd order event plane info in order, see link. fillEventInfo
    eptrackmidAngle A vector of event plane angle by tracker, re-centered and flattened: elements are 1st, 2nd, 3rd order event plane info in order, see link. fillEventInfo
    ephfmQ A vector of event plane Q-vector magnitude by HF-, re-centered and flattened: elements are 1st, 2nd, 3rd order event plane info in order, see link. fillEventInfo
    ephfpQ A vector of event plane Q-vector magnitude by HF+, re-centered and flattened: elements are 1st, 2nd, 3rd order event plane info in order, see link. fillEventInfo
    eptrackmidQ A vector of event plane Q-vector magnitude by tracker, re-centered and flattened: elements are 1st, 2nd, 3rd order event plane info in order, see link. fillEventInfo
    ephfmSumW The sum over weight of 2nd order event plane by HF-. See link. fillEventInfo
    ephfpSumW The sum over weight of 2nd order event plane by HF+. See link. fillEventInfo
    eptrackmidSumW The sum over weight of 2nd order event plane by tracker. See link. fillEventInfo
    genWeight genInfo->weight() from tok_genInfo_ fillGenParticleInfo
    pTHat   fillGenParticleInfo
    lheWeight A std::vector of genInfo->weight() * w.wgt / lheInfo->originalXWGTUP() where w is an element in lheInfo->weights() fillGenParticleInfo
  2. Container ntupleInfo_

    It is a container to save candidate information, for ntuple production. It can only hold one candidate's information. Each time before new values are copied to ntupleInfo_, clear need to be called.

  3. TODO TriggerContainer triggerData_

    Se codes (may be outdated) below:

    typedef std::vector<TriggerInfo> TriggerContainer;
    TriggerContainer triggerData_;
    
  4. TODO MatchContainer matchData_

    See codes (may be outdated) below:

    typedef std::map<std::string, MatchInfo> MatchContainer;
    MatchContainer matchData_;
    
  5. particleInfo_

    This is a map between the names of different candidates (trigger objects, reconstructed candidates, generated particles, etc.) and their containers. Possible entries are: {"cand", "trk", "elec", "muon", "tau", "pho", "jet", "pf", "gen", "trig"}. See codes (might be outdated) below:

    typedef std::map<std::string, ParticleContainer> ParticleContainerMap;
    ParticleContainerMap particleInfo_;
    

    The key-value pairs in each entry are listed in the following tables:

    Table 9: This table is for particleInfo_["cand"].
    Name Descriptions Value for place holder if not accessible
    p momentum  
    y rapidity  
    eta eta  
    phi phi  
    mass mass  
    charge charge  
    pdgId pdgId  
    status status for the candidate, 1: stable, 2: intermediate, 3:target, see GeneralParticleProducer  
    vtxChi2 Chi2 normalized by the number of degrees of freedom -1.
    vtxProb Fit probability of the vertex reconstruction -1.
    angle3D 3D pointing angle between the line segment from primary vertex to decay vertex and the momentum of decay particle -10.
    angle2D   -10.
    dca DCA between two daughters, valid when number of daughters equals 2 -99.9
    decayLength3D 3D decay length w.r.t. the primary vertex -99.9
    decayLengthError3D The error of decayLength3D -1.
    decayLength2D   -99.9
    decayLengthError2D   -1.
    pseudoDecayLengthError3D The error of 3D pseudo-proper-decay-length, defined by decay-length-3D * cos(angle3D) *m/p -99.9
    pseudodecaylengtherror2D   -99.9
    mva   -99.9
    Ntrkoffline Will be filled when nTracksVMap_ is not empty. 0
    matchTRG%d %d means the index of element in triggerData_. matchTRG will be true if the triggerObjects is not empty May not exist if triggerData_. is empty
    trigIdx std::vector of indices of trigger objects info. Only exists when addInfo_["trgObj"]​ is true. Empty std::vector
    trkIdx Index of the corresponding track. Only exists when addInfo_["track"]​ is true.  
    srcIdx Index of the corresponding source. Only exists when addInfo_["sourcej"]​ is true.  
    genIdx Index of the corresponding generated particles if matched  
    matchGEN reco-gen matching succeeds or not  
    isSwap whether it is a swap candidate, namely the momentum matches but mass not  
    genPdgId pdgId of the generated particle 0
    momMatchGEN whether the mother particle matches a generated particle  
    momMatchIdx The index of the mother particle which matches a generated particle UShort_t(-1)
    dauIdx A std::vector of the indices of daughter particles Empty
    pTDau A std::vector of daughter particle pT. The pT is the fit value.  
    etaDau A std::vector of daughter particle eta. The eta is the fit value.  
    phiDau A std::vector of daughter particle phi. The phi is the fit value.  
    massDau A std::vector of daughter particle mas. The mass is the fit value.  

    Table 10: particleInfo_["gen"]
    Name Descriptions Value for place holder if not accessible
    candIdx A vector of indices of candidates in particleInfo_["cand"]​ associated with current gen-particle Empty std::vector
    p momentum  
    y rapidity  
    eta eta  
    phi phi  
    mass mass  
    charge charge  
    pdgId pdgId  
    status status for the candidate, 1: stable, 2: intermediate, 3:target, see GeneralParticleProducer  
    statusBit Bit-wise mapper determined by reco::GenParticle.statusFlags, \(\sum_{i}2^i\) 0
    angle3D 3D pointing angle between the line segment from primary vertex to decay vertex and the momentum of decay particle -10.
    angle2D   -10.
    decayLength3D 3D decay length w.r.t. the primary vertex -99.9
    decayLength2D    
    dauIdx A std::vector of indices of daughter particles in particleInfo_["gen"]  
    momIdx A std::vector of indices of mother particle in particleInfo_["gen"]  

    Table 11: particleInfo_["trk"]
    Name Descriptions Value for place holder if not accessible
    candIdx A vector of indices of candidates in particleInfo_["cand"]​ associated with current track Empty std::vector
    isHP whether it is high purity track  
    nChi2 Chi2 normalized by the number of degrees of freedom  
    pTErr The error of the track pT  
    nHit The number of valid hits  
    zDCASignificance significance of DCA projected to z-direction w.r.t. the primary vertex  
    xyDCASignificance significance of DCA projected to xy-plane w.r.t. the primary vertex  
    dEdx_* dEdx info for this track, * means the input tags for dEdxs, see GeneralParticleProducer  

    Table 12: Muon stuffs (particleInfo_["muon"]) by partcielInfo_["src"]
    Name Descriptions Value for place holder if not accessible
    candIdx The candidate index for this electron in particleInfo_["cand"]​.  
    selector A bit-wise selector, see link 0
    selectionType A bit-wise map of selection types, via \(\sum_{i=0}^{29}2^i\) 0
    isGlobal Whether it is global muon  
    isPF Whether it is PF muon  
    glbTrkNChi2 The normalized chi2 of the global track 99.9
    nMuonHit Number of valid hits in global track -1
    nMatchedStation Number of matched stations  
    nPixelHit Number of valid pixel hits of inner track 1
    nTrackerLayer Number of tracker layers with OK-ed measurements -1
    bestTrkdXY DCA along XY plane of muon best track w.r.t. primary vertex associated with this muon (pat::userData) -99.9
    bestTrkdZ DCA along z-direction of muon best track w.r.t. primary vertex associated with this muon (pat::userData) -1
    tightID whether it is tight muon  
    isOneStTight ? require one well matched segment ?  
    nPixelLayer Number of pixel layers with OK-ed measurements -1
    dXY DCA along XY plane of muon inner track w.r.t. primary vertex associated with this muon (pat::userData)  
    dZ DCA along z-direction of muon inner track w.r.t. primary vertex associated with this muon (pat::userData)  
    softID whether it is soft muon  
    isTracker whether it is tracker muon  
    hybridSoftID hybrid soft ID from HIN PAG  
    nMatches Number of chambers with matched segments  
    hadMax maximal energy of HCAL tower in the 3x3 shape  
    dX_seg ? Segment between chambers ?  
    dY_seg    
    dXSig_seg    
    dYSig_seg    
    ddXdZ_seg    
    ddYdZ_seg    
    ddXdZSig_seg    
    ddYdZSig_seg    
    l1Eta muon L1 info: eta, available when triggerData_ is not empty, addInfo["trgObj"] and addInfo["muonL1"]​ are true -99.9

    Table 13: Electron info (particleInfo_["elec"]) by partcielInfo_["src"]
    Name Descriptions Value for place holder if not accessible
    candIdx The candidate index for this electron in particleInfo_["cand"]​.  
    sigmaIEtaIEta weighted cluster rms along eta and inside 5x5 (Xtal eta). See link. A value created by empty pat::Electron
    sigmaIPhiIPhi weighted cluster rms along phi and inside 5x5 (Xtal phi). See link. A value created by empty pat::Electron
    dEtaSeedAtVtx deltaEtaSeedClusterTrackAtVtx std::numeric_limits<float>::max() or -99.9
    dEtaAtVtx the supercluster eta - track eta position at calo extrapolated from innermost track state A value created by empty pat::Electron
    dPhiAtVtx the supercluster phi - track phi position at calo extrapolated from the innermost track state A value created by empty pat::Electron
    eOverPInv 1./electron.ecalEnergy() - 1./electron.trackMomentumAtVtx().R()  
    hOverEBc HCal over ECal seed cluster energy, see link and hcalOverEcalBc.  
    sCEta Eta of super cluster centroid -99.9
    sCPhi Phi of super cluster centroid -99.9
    ip3D Impact parameter w.r.t. the primary vertex associated with the electron (saved as pat) -99.9
    nLostHits Number of lost hits of the electron GSF track. -1

    Table 14: Tau info (particleInfo_["tau"]) by particleInfo_["src"]
    Name Descriptions Value for place holder if not accessible
    candIdx The candidate index for this electron in particleInfo_["cand"]​.  
    selector Determined by tau IDs. Each ID with float > 0.5 will be set a bit 1 otherwise 0.  
    isPF Whether it is PF candidate  

    Table 15: Photon info (particleInfo_["pho"]) by particleInfo_["src"]. Entries labeled by 22 are photon; while ones by -22 are gamma conversions.
    Name Descriptions Value for place holder if not accessible
    candIdx The candidate index for this electron in particleInfo_["cand"]​.  
    sigmaIEtaIEta (22)   -99.9
    hoverE (22) the total hadronic over electromagnetic fraction -99.9
    sCEta (22)   -99.9
    sCPhi (22)   -99.9
    swissCrx (22) SwissCross crystal ratio, see reco::HIPhotonIsolation::swissCrx -99.9
    seedTime (22) Ecal rechit seed time, see reco::HIPhotonIsolation::seedTime -99.9
    trackIsoR3PtCut20 (22) Track-based isolation, pt>2.0GeV, R = 0.3, see reco::HIPhotonIsolation::trackIsoR3PtCut20 99.9
    ecalClutsterIsoR3 (22) See reco::HIPhotonIsolation::ecalClusterIsoR3, Cluster-based isolation (ECAL) R = 0.3. 99.9
    hcalRechitIsoR3 (22) See reco::HIPhotonIsolation::hcalRechitIsoR3, Rechit-based isolation (HCAL) R = 0.3. 99.9
    nTracks (-22) Number of tracks= 0,1,2. See link.  
    quality See conversion quality. The qualities will be mapped into a bit-wise selector 0

    Table 16: Jet information (particleInfo_["jet"]) by particleInfo_["src"]
    Name Descriptions Value for place holder if not accessible
    candIdx A vector of indices of candidates in particleInfo_["cand"]​ associated with current jet Empty std::vector
    rawPt Raw pT of the jet A value created by empty pat::Jet()
    l2 Correction factor L2-corrected jet pT over raw pT
    l3 Correction factor (might be dummy value) L3-corrected Jet pT over L2-corrected ones
    area Jet area A value created by empty pat::Jet()
    pileup Pileup A value created by empty pat::Jet()
    hadronFlavour hadron-based flavour of the jet A value created by empty pat::Jet()
    partonFlavour the parton-based flavour of the jet A value created by empty pat::Jet()
    isPF Whether it is PF jet A value created by empty pat::Jet()
    CHF charged hadron energy fraction -1
    NHF Neutral hadron energy fraction -1
    CEF Charged EM energy fraction -1
    NEF Neutral EM energy fraction -1
    MUF Muon energy fraction -1
    CHM Charged hadron multiplicity 0
    NHM Neutral hadron multiplicity 0
    CEM Electron multiplicity 0
    NEM Photon multiplicity 0
    MUM Muon multiplicity 0
    bTagging Not really b-tag values, but a bit-wise record that how many types of tag available 0

    Table 17: PFCandidate info (particleInfo_["pf"]) by particleInfo_["src"]
    Name Descriptions Value for place holder if not accessible
    candIdx A vector of indices of candidates in particleInfo_["cand"]​ associated with current PF candidate Empty std::vector
    id Particle ID A value created by empty reco::PFCandidate
    ecalE ECal energy A value created by empty reco::PFCandidate
    rawEcalE Raw ECal energy A value created by empty reco::PFCandidate
    hcalE HCal energy A value created by empty reco::PFCandidate
    rawHcalE Raw HCal energy A value created by empty reco::PFCandidate
  6. TODO std::map<std::string, std::map<size_t, pat::TriggerObjectStandAlone> > triggerObjectMap_

Author: yousen

Created: 2021-02-04 Thu 19:23

Edit | Attach | Watch | Print version | History: r8 < r7 < r6 < r5 < r4 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r8 - 2021-02-05 - YousenZhang
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Sandbox All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback