CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PFTau3ProngReco.cc
Go to the documentation of this file.
1 /* class PFTau3ProngReco
2  * EDProducer of the
3  * author: Ian M. Nugent
4  * The idea of the fully reconstructing the tau using a kinematic fit comes from
5  * Lars Perchalla and Philip Sauerland Theses under Achim Stahl supervision. This
6  * code is a result of the continuation of this work by Ian M. Nugent and Vladimir Cherepanov.
7  */
8 
18 
23 
39 
45 
48 #include <TFormula.h>
49 
50 #include <memory>
51 
62 #include "TLorentzVector.h"
63 
65 
66 using namespace reco;
67 using namespace edm;
68 using namespace std;
69 using namespace tauImpactParameter;
70 
71 class PFTau3ProngReco : public EDProducer {
72 public:
73  enum Alg { useKalmanFit = 0, useTrackHelix };
74 
75  struct DiscCutPair {
76  DiscCutPair() : cutFormula_(nullptr) {}
77  ~DiscCutPair() { delete cutFormula_; }
80  double cut_;
81  TFormula* cutFormula_;
82  };
83  typedef std::vector<DiscCutPair*> DiscCutPairVec;
84 
85  explicit PFTau3ProngReco(const edm::ParameterSet& iConfig);
86  ~PFTau3ProngReco() override;
87  void produce(edm::Event&, const edm::EventSetup&) override;
88 
89 private:
94  std::unique_ptr<StringCutObjectSelector<reco::PFTau>> cut_;
95  int ndfPVT_;
97 };
98 
100  : PFTauTag_(iConfig.getParameter<edm::InputTag>("PFTauTag")),
101  PFTauTIPTag_(iConfig.getParameter<edm::InputTag>("PFTauTIPTag")),
102  Algorithm_(iConfig.getParameter<int>("Algorithm")),
103  ndfPVT_(iConfig.getUntrackedParameter("ndfPVT", (int)5)) {
105  std::vector<edm::ParameterSet> discriminators =
106  iConfig.getParameter<std::vector<edm::ParameterSet>>("discriminators");
107  // Build each of our cuts
108  for (auto const& pset : discriminators) {
109  DiscCutPair* newCut = new DiscCutPair();
110  newCut->inputTag_ = pset.getParameter<edm::InputTag>("discriminator");
111  if (pset.existsAs<std::string>("selectionCut"))
112  newCut->cutFormula_ = new TFormula("selectionCut", pset.getParameter<std::string>("selectionCut").data());
113  else
114  newCut->cut_ = pset.getParameter<double>("selectionCut");
115  discriminators_.push_back(newCut);
116  }
117  // Build a string cut if desired
118  if (iConfig.exists("cut"))
119  cut_ = std::make_unique<StringCutObjectSelector<reco::PFTau>>(iConfig.getParameter<std::string>("cut"));
121  produces<edm::AssociationVector<PFTauRefProd, std::vector<reco::PFTau3ProngSummaryRef>>>();
122  produces<PFTau3ProngSummaryCollection>("PFTau3ProngSummary");
123 }
124 
126 
127 namespace {
128  inline const reco::Track* getTrack(const reco::Candidate& cand) {
129  const reco::PFCandidate* pfCandPtr = dynamic_cast<const reco::PFCandidate*>(&cand);
130  if (pfCandPtr) {
131  if (pfCandPtr->trackRef().isNonnull())
132  return pfCandPtr->trackRef().get();
133  else if (pfCandPtr->gsfTrackRef().isNonnull())
134  return pfCandPtr->gsfTrackRef().get();
135  else
136  return nullptr;
137  }
138  const pat::PackedCandidate* packedCand = dynamic_cast<const pat::PackedCandidate*>(&cand);
139  if (packedCand != nullptr)
140  return packedCand->bestTrack();
141 
142  return nullptr;
143  }
144 } // namespace
145 
147  // Obtain Collections
148  edm::ESHandle<TransientTrackBuilder> transTrackBuilder;
149  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", transTrackBuilder);
150 
152  iEvent.getByLabel(PFTauTag_, Tau);
153 
155  iEvent.getByLabel(PFTauTIPTag_, TIPAV);
156 
157  auto AVPFTau3PS = std::make_unique<edm::AssociationVector<PFTauRefProd, std::vector<reco::PFTau3ProngSummaryRef>>>(
158  PFTauRefProd(Tau));
159  auto PFTau3PSCollection_out = std::make_unique<PFTau3ProngSummaryCollection>();
160  reco::PFTau3ProngSummaryRefProd PFTau3RefProd_out =
161  iEvent.getRefBeforePut<reco::PFTau3ProngSummaryCollection>("PFTau3ProngSummary");
162 
163  // Load each discriminator
164  for (auto& disc : discriminators_) {
165  iEvent.getByLabel(disc->inputTag_, disc->handle_);
166  }
167 
168  // For each Tau Run Algorithim
169  if (Tau.isValid()) {
170  for (reco::PFTauCollection::size_type iPFTau = 0; iPFTau < Tau->size(); iPFTau++) {
171  reco::PFTauRef tau(Tau, iPFTau);
172  reco::PFTau3ProngSummary PFTau3PS;
174  // Check if it passed all the discrimiantors
175  bool passed(true);
176  for (auto const& disc : discriminators_) {
177  // Check this discriminator passes
178  bool passedDisc = true;
179  if (disc->cutFormula_)
180  passedDisc = (disc->cutFormula_->Eval((*disc->handle_)[tau]) > 0.5);
181  else
182  passedDisc = ((*disc->handle_)[tau] > disc->cut_);
183  if (!passedDisc) {
184  passed = false;
185  break;
186  }
187  }
188  if (passed && cut_.get()) {
189  passed = (*cut_)(*tau);
190  }
191  if (passed) {
192  PDGInfo pdgInfo;
193  const reco::PFTauTransverseImpactParameterRef theTIP = TIPAV->value(tau.key());
194  const reco::VertexRef primaryVertex = theTIP->primaryVertex();
196  // Now compute the 3 prong Tau
197  bool SecondaryVtxOK(false);
199  if (theTIP->hasSecondaryVertex() && primaryVertex->ndof() > ndfPVT_) {
200  const VertexRef secVtx = theTIP->secondaryVertex();
201  GlobalPoint sv(secVtx->position().x(), secVtx->position().y(), secVtx->position().z());
202  double vtxchi2(0), vtxndf(1);
203  if (useKalmanFit == Algorithm_) {
204  vtxchi2 = secVtx->chi2();
205  vtxndf = secVtx->ndof();
206  const std::vector<reco::Track>& selectedTracks = secVtx->refittedTracks();
207  std::vector<reco::TransientTrack> transTrkVect;
208  for (unsigned int i = 0; i != selectedTracks.size(); i++)
209  transTrkVect.push_back(transTrackBuilder->build(selectedTracks[i]));
211  float piMassSigma(1.e-6), piChi(0.0), piNdf(0.0);
212  std::vector<RefCountedKinematicParticle> pions;
213  for (unsigned int i = 0; i < transTrkVect.size(); i++)
214  pions.push_back(kinFactory.particle(transTrkVect[i], pdgInfo.pi_mass(), piChi, piNdf, sv, piMassSigma));
215  RefCountedKinematicTree jpTree = kpvFitter_.fit(pions);
216  jpTree->movePointerToTheTop();
217  const KinematicParameters parameters = jpTree->currentParticle()->currentState().kinematicParameters();
218  AlgebraicSymMatrix77 cov = jpTree->currentParticle()->currentState().kinematicParametersError().matrix();
219  // get pions
220  double c(0);
221  std::vector<reco::Track> Tracks;
222  std::vector<LorentzVectorParticle> ReFitPions;
223  for (unsigned int i = 0; i < transTrkVect.size(); i++) {
224  c += transTrkVect[i].charge();
225  ReFitPions.push_back(ParticleBuilder::createLorentzVectorParticle(transTrkVect[i], *secVtx, true, true));
226  }
227  // now covert a1 into LorentzVectorParticle
228  TVectorT<double> a1_par(LorentzVectorParticle::NLorentzandVertexPar);
229  TMatrixTSym<double> a1_cov(LorentzVectorParticle::NLorentzandVertexPar);
230  for (int i = 0; i < LorentzVectorParticle::NLorentzandVertexPar; i++) {
231  a1_par(i) = parameters(i);
232  for (int j = 0; j < LorentzVectorParticle::NLorentzandVertexPar; j++) {
233  a1_cov(i, j) = cov(i, j);
234  }
235  }
237  a1_par, a1_cov, abs(PdtPdgMini::a_1_plus) * c, c, transTrackBuilder->field()->inInverseGeV(sv).z());
238  SecondaryVtxOK = true;
239  PFTau3PS = reco::PFTau3ProngSummary(theTIP, a1.p4(), vtxchi2, vtxndf);
240  } else if (useTrackHelix == Algorithm_) {
241  // use Track Helix
242  std::vector<TrackParticle> pions;
243  GlobalPoint pvpoint(
244  primaryVertex->position().x(), primaryVertex->position().y(), primaryVertex->position().z());
245  const std::vector<edm::Ptr<reco::Candidate>> cands = tau->signalChargedHadrCands();
246  for (std::vector<edm::Ptr<reco::Candidate>>::const_iterator iter = cands.begin(); iter != cands.end();
247  ++iter) {
248  const reco::Track* track = getTrack(**iter);
249  if (track != nullptr) {
250  reco::TransientTrack transTrk = transTrackBuilder->build(*track);
251  pions.push_back(ParticleBuilder::createTrackParticle(transTrk, pvpoint, true, true));
252  }
253  }
254  TVector3 pv(secVtx->position().x(), secVtx->position().y(), secVtx->position().z());
255  Chi2VertexFitter chi2v(pions, pv);
256  SecondaryVtxOK = chi2v.fit();
257  double c(0);
258  for (unsigned int i = 0; i < pions.size(); i++) {
259  c += pions[i].charge();
260  }
261  int pdgid = abs(PdtPdgMini::a_1_plus) * c;
262  a1 = chi2v.getMother(pdgid);
263  PFTau3PS = reco::PFTau3ProngSummary(theTIP, a1.p4(), vtxchi2, vtxndf);
264  }
265  }
266  if (SecondaryVtxOK) {
267  // Tau Solver
268  TVector3 pv(primaryVertex->position().x(), primaryVertex->position().y(), primaryVertex->position().z());
269  TMatrixTSym<double> pvcov(LorentzVectorParticle::NVertex);
271  primaryVertex->fill(pvCov);
272  for (int i = 0; i < LorentzVectorParticle::NVertex; i++) {
273  for (int j = 0; j < LorentzVectorParticle::NVertex; j++) {
274  pvcov(i, j) = pvCov(i, j);
275  }
276  }
277  for (unsigned int i = 0; i < PFTau3ProngSummary::nsolutions; i++) {
278  TauA1NuConstrainedFitter TauA1NU(i, a1, pv, pvcov);
279  bool isFitOK = TauA1NU.fit();
280  if (isFitOK) {
281  LorentzVectorParticle theTau = TauA1NU.getMother();
282  std::vector<LorentzVectorParticle> daughter = TauA1NU.getRefitDaughters();
283  std::vector<TLorentzVector> daughter_p4;
284  std::vector<int> daughter_charge, daughter_PDGID;
285  for (unsigned int d = 0; d < daughter.size(); d++) {
286  daughter_p4.push_back(daughter[d].p4());
287  daughter_charge.push_back((int)daughter[d].charge());
288  daughter_PDGID.push_back(daughter[d].pdgId());
289  }
290  PFTau3PS.AddSolution(i, theTau.p4(), daughter_p4, daughter_charge, daughter_PDGID, (isFitOK), 0.0, -999);
291  }
292  }
293  }
294  }
295  reco::PFTau3ProngSummaryRef PFTau3PSRef =
296  reco::PFTau3ProngSummaryRef(PFTau3RefProd_out, PFTau3PSCollection_out->size());
297  PFTau3PSCollection_out->push_back(PFTau3PS);
298  AVPFTau3PS->setValue(iPFTau, PFTau3PSRef);
299  }
300  }
301  iEvent.put(std::move(PFTau3PSCollection_out), "PFTau3ProngSummary");
302  iEvent.put(std::move(AVPFTau3PS));
303 }
304 
std::vector< reco::PFTau3ProngSummary > PFTau3ProngSummaryCollection
collection of PFTau3ProngSummary objects
KinematicParticleVertexFitter kpvFitter_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
const edm::EventSetup & c
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
PFTau3ProngReco(const edm::ParameterSet &iConfig)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::unique_ptr< StringCutObjectSelector< reco::PFTau > > cut_
bool exists(std::string const &parameterName) const
checks if a parameter exists
edm::InputTag PFTauTIPTag_
ErrorD< N >::type type
Definition: Error.h:32
key_type key() const
Accessor for product key.
Definition: Ref.h:250
edm::RefProd< PFTauCollection > PFTauRefProd
references to PFTau collection
Definition: PFTauFwd.h:15
uint16_t size_type
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:430
tuple d
Definition: ztail.py:151
std::vector< LorentzVectorParticle > getRefitDaughters()
int iEvent
Definition: GenABIO.cc:224
def move
Definition: eostools.py:511
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::Handle< reco::PFTauDiscriminator > handle_
static double pi_mass()
Definition: PDGInfo.h:13
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
DiscCutPairVec discriminators_
bool isValid() const
Definition: HandleBase.h:70
RefCountedKinematicTree fit(const std::vector< RefCountedKinematicParticle > &particles) const
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:500
RefProd< PROD > getRefBeforePut()
Definition: Event.h:158
const reco::Track * bestTrack() const override
return a pointer to the track if present. otherwise, return a null pointer
edm::Ref< PFTau3ProngSummaryCollection > PFTau3ProngSummaryRef
presistent reference to a PFTau3ProngSummary
static const TrackGhostTrackState * getTrack(const BasicGhostTrackState *basic)
~PFTau3ProngReco() override
virtual bool AddSolution(unsigned int solution, const TLorentzVector &tau, const std::vector< TLorentzVector > &daughter_p4, const std::vector< int > &daughter_charge, const std::vector< int > &daughter_PDGID, bool has3ProngSolution, double solutionChi2, double thetaGJsig)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
ROOT::Math::SMatrix< double, 7, 7, ROOT::Math::MatRepSym< double, 7 > > AlgebraicSymMatrix77
Definition: Matrices.h:9
std::vector< DiscCutPair * > DiscCutPairVec
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
T get() const
Definition: EventSetup.h:82
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:462
RefCountedKinematicParticle particle(const reco::TransientTrack &initialTrack, const ParticleMass &massGuess, float chiSquared, float degreesOfFr, float &m_sigma) const
void produce(edm::Event &, const edm::EventSetup &) override
edm::InputTag PFTauTag_