This is the documentation for the general producer
Table of Contents
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 viaParticleFitter::setVertex
. - If the vector of daughter
PSet
is available, the producer will reserveedm
products for daughter collection storage. Further, the producer fillParticleDaughter
vector following the configurations. Once the vector of daughter collections is ready, this producer will fit candidates viaParticleFitter::fitAll
. - Everything will be moved to output
AOD
file. Vertex collection and daughter collection are filled in the reservededm
product created in previous steps. The target decay particles will be stored in thepat::GenericParticleCollection
.
1.1.2 How ParticleFitter::setVertex
and ParticleFitter::fitAll
work
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).
ParticleFitter::fitAll
It will call
ParticleFitter::fillDaughters
andParticleFitter::makeCandidates
.ParticleFitter::fillDaughters
It will callParticleDaughter::init
andParticleDaughter::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.) withpat::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 viamake_combinations
. User can use several string cut parsers (preSelection
,preMassSelection
,pocaSelection
,postSelection
andfinalSelection
) 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
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 |
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 |
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 |
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 |
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.
pdgId()
Return PDG ID of the particle.
charge()
Return charge of the specie of particle.
mass()
Return mass.
width()
Return the width of mass window during the candidate selection.
particles()
Return the particle collection for the
ParticleDaughter
object.useSource()
Return if user give any source input to the
ParticleDaughter
object.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. TheGenericParticle
object will be filled viaaddData
andaddInfo
. If track info is available,userFloat
variables:dz
,dxy
,dzSig
anddxySig
will be available.dEdx
and track MVA info (if any) will be saved asuserFloat
viaParticleDaughter::setDeDx
andParticleDaughter::setMVA
. Users can apply cuts viaselction
andfinalSelection
. Cuts implemented via member functions can be applied viaselection
. Cuts onuserFloat
variables need to be done viafinalSelection
.addParticles(const edm::Event& event)
Add particles to the
ParticleDaughter
object. This function will read fromsource
rather than other collections likereco::TrackCollection
.fillInfo(const edm::ParameterSet& pSet, const edm::ParameterSet& config, edm::ConsumesCollector& iC)
Fill info based on configurations of daughter
PSet
.init(const edm::EventSetup& iSetup)
A function for muon setup (further documentations needed).
addInfo(pat::GenericParticle& c, const T& p)
Set four-momentum, charge and corresponding vertex.
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.addData(pat::GenericParticle& c, const edm::Ref<std::vector<T> >& p, const bool& embedInfo)
c.addUserData<T>("src", *p);
addData(pat::GenericParticle& c, const reco::TrackRef& p, const bool& embedInfo)
Add track info and set
sourceID
(auserInt
for checking duplicate daughters) to 1.addData(pat::GenericParticle& c, const reco::PFCandidateRef& p, const bool& embedInfo)
Set info from
PFCandidate
. AuserData
calledsrc
will be added. Track reference info will be added as well if available.addData(pat::GenericParticle& c, const pat::MuonRef& p, const bool& embedInfo)
Add muon info.
userData
calledsrc
will be added. Optional user data may exist including:userData
:trackRef
userFloat
:l1Eta
,l1Phi
userInt
:prop
-> 1
addData(pat::GenericParticle& c, const pat::ElectronRef& p, const bool& embedInfo)
Set info for electron. Add
src
(userData
) and track reference (maybe).setMVA (pat::GenericParticle& c, const size_t& i, const edm::Handle<std::vector<float> >& m)
Set MVA value for tracks.
setDeDx(pat::GenericParticle& c, const std::map<std::string, edm::Handle<edm::ValueMap<reco::DeDxData> > >& m)
Set
dEdx
info for daughters if available.addMuonL1Info(pat::GenericParticle& c, const edm::Handle<pat::TriggerObjectStandAloneMatch>& m)
Further documentation needed.
1.3.5 ParticleFitter
void addParticles(ParticleDaughter& d, const edm::Event& iEvent)
Add particles depending on
pdgId
ofParticleDaughter
.const reco::VertexCollection& vertices()
Return primary vertices associated with decay products.
const pat::GenericParticleCollection& particles()
Return candidate collection of decay particles.
const pat::GenericParticleCollection& daughters()
Return daughter collection of decay particles, including both daughters and granddaughters.
const bool hasNoDaughters()
Check whether daughter collection is empty.
reco::VertexRef getVertexRef(const reco::Vertex& vertex)
It generate
reco::VertexRef
taking thevertices_
variable as the associated collection and using the index of each element invertices_
askey_value
. It compares the input vertex with position, multiplicity andisFake
with saved ones to avoid duplication.math::XYZTLorentzVector getP4(const GlobalVector& p, const double& m)
Return the p4.
pat::GenericParticleRef addParticle(const pat::GenericParticle& particle)
It generate
pat::Genericparticle
taking theparticles_
variable as the associated collection and using the index of each element inparticles_
askey_value
. Particles are identified via their pT, eta, phi, mass and charge. It recursively store daughters of daughters into theparticles_
and change their primary vertices reference to the collection with new product ID. The trick used here isconst_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); }
- 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 optionmatchVertex
in the configuration.matchVertex
: In this case, theFalse
VetexRef
is set to be the same asvertex_
and this value is set inParticleFitter::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
: 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.True
- It will at first check whether the value of
userFloat("vertexProb")
is larger thanthr
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 invertex_
. - If the conditions above are satisfied, then it will try to give the
point of the closet approach (PCA). It will give two tries.
- If the input of
FreeTrajectoryState fts
has no error, the function will try to construct theFreeTrajectoryState
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 thisfts
. Moreover, if the probability of PCA extrapolation is larger thanthr
, 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. - 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 thanthr
. 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 viapuMap
in the configuration. If the conditions are not satisfied, value invertex_
will be used.
- If the input of
- It will at first check whether the value of
RefCountedKinematicTree fitVertex(const ParticleInfo& parInfo, const int& fitAlgo, GlobalPoint decP, const reco::Vertex& priVtx={})
This function can do three kind of fit.
fitAlgo
, unconstrained fit0
fitAlgo
, make use of1
MultiTrackPointingKinematicConstraint
, primary vertex and decay vertex information (currently obtained from prior fit) will be used.fitAlgo
, make use of2
MultiTrackMassKinematicConstraint
, the PDG mass of reconstructed particles and number of daughters are used.
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.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 toParticleFitter::fitVertex
.parInfo
will carry the information ofstd::vector<RefCountedKinematicParticle>
,std::vector<reco::TransientTrack>
andstd::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 asuserData("decayVertex")
(the main one, the first one in thefitAlgoV_
) anduserData("decayVertex_label")
where label is each element in thefitAlgoV_
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")
anduserData("kinematicParametersError")
are saved only for the main fit.
- Check whether the algorithm is the kinematic fit (with or without
constraints). If true, call
matchPrimaryvertex
will be called if everything works fine above.- Return
true
, this means the fit succeeds!
- Loop over all the algorithms
- Get the daughters transient tracks. Converted photons will have multiple
tracks, otherwise, each daughter has one track, constructed by its track
or
void setVtxProd(const reco::VertexRefProd& prod)
{ vtxProd_ = prod; };
setDauProd(const GenericParticleRefProd& prod)
{ dauProd_ = prod; }
void getNTracks(const edm::Event& iEvent)
Seems not implemented.
void fillDaughters(const edm::Event& iEvent, const edm::EventSetup& iSetup)
Call
ParticleFitter::addParticles
to fill the collection ofParticleDaughter
.bool isUniqueDaughter(ParticleSet& set, const pat::GenericParticle& dau)
Check whether
dau
is inset
. If so, returnfalse
sincedau
is a duplicate inset
, the daughter is not unique. If not,dau
will be inserted toset
and this function returntrue
.void makeCandidates()
This function defines how the fitter works.
- It will generate daughter collection from the collection,
dauColls
, ofParticleDaughter
,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 infitCandidate
.preSelection_
is done. - Daughters will be reordered if
doSwap_
, viatrue
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 infitCandidate
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 viaaddSwapCandidates
.swapCandColl
will be empty ifdoSwap_
.false
candidates
andswapCandColl
are combined.- Daughter collection is reordered following
ParticleTreeComparator
. References to daughter collection are saved.
- The collection of candidates is reordered via
ParticleMassComparator
.
- It will generate daughter collection from the collection,
void swapDaughters(DoubleMap& swapDauColls, const pat::GenericParticle& cand, const pat::GenericParticleCollection& dauColl)
This function works only when
doSwap_
. This function will do permutation based ontrue
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 thisuserInt
, source ID is set to 0; if source ID is 1, they are tracks). IfsourceID
, swap daughter and original daughter must have "equal" (0
ParticleCompartor().isParticleEqual
).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
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 |