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. TODO 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). If sourceID 0, swap daughter and original daughter must have "equal" (ParticleCompartor().isParticleEqual).

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

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

Table 6: This is the table of configurable parameters of general tree producer
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

Author: Yousen Zhang

Created: 2020-11-17 Tue 10:11

Validate

Edit | Attach | Watch | Print version | History: r1 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r1 - 2020-11-17 - 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-2023 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