CMS 3D CMS Logo

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 
9 
19 
24 
40 
46 
49 #include <TFormula.h>
50 
51 #include <memory>
52 
63 #include "TLorentzVector.h"
64 
66 
67 using namespace reco;
68 using namespace edm;
69 using namespace std;
70 using namespace tauImpactParameter;
71 
72 class PFTau3ProngReco : public EDProducer {
73  public:
74  enum Alg{useKalmanFit=0, useTrackHelix};
75 
76  struct DiscCutPair{
77  DiscCutPair():cutFormula_(nullptr){}
78  ~DiscCutPair(){delete cutFormula_;}
81  double cut_;
82  TFormula* cutFormula_;
83  };
84  typedef std::vector<DiscCutPair*> DiscCutPairVec;
85 
86  explicit PFTau3ProngReco(const edm::ParameterSet& iConfig);
87  ~PFTau3ProngReco() override;
88  void produce(edm::Event&,const edm::EventSetup&) override;
89  private:
93  DiscCutPairVec discriminators_;
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))
104 {
106  std::vector<edm::ParameterSet> discriminators =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") ) newCut->cutFormula_ = new TFormula("selectionCut", pset.getParameter<std::string>("selectionCut").data());
112  else newCut->cut_ = pset.getParameter<double>("selectionCut");
113  discriminators_.push_back(newCut);
114  }
115  // Build a string cut if desired
116  if (iConfig.exists("cut")) cut_ = std::make_unique<StringCutObjectSelector<reco::PFTau>>(iConfig.getParameter<std::string>("cut"));
118  produces<edm::AssociationVector<PFTauRefProd, std::vector<reco::PFTau3ProngSummaryRef> > >();
119  produces<PFTau3ProngSummaryCollection>("PFTau3ProngSummary");
120 }
121 
123 
124 }
125 
126 namespace {
127  inline const reco::Track* getTrack(const reco::Candidate& cand)
128  {
129  const reco::PFCandidate* pfCandPtr = dynamic_cast<const reco::PFCandidate*>(&cand);
130  if (pfCandPtr) {
131  if ( pfCandPtr->trackRef().isNonnull() ) return pfCandPtr->trackRef().get();
132  else if ( pfCandPtr->gsfTrackRef().isNonnull() ) return pfCandPtr->gsfTrackRef().get();
133  else return nullptr;
134  }
135  const pat::PackedCandidate* packedCand = dynamic_cast<const pat::PackedCandidate*>(&cand);
136  if (packedCand != nullptr)
137  return packedCand->bestTrack();
138 
139  return nullptr;
140  }
141 }
142 
144  // Obtain Collections
145  edm::ESHandle<TransientTrackBuilder> transTrackBuilder;
146  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",transTrackBuilder);
147 
149  iEvent.getByLabel(PFTauTag_,Tau);
150 
152  iEvent.getByLabel(PFTauTIPTag_,TIPAV);
153 
154  auto AVPFTau3PS = std::make_unique<edm::AssociationVector<PFTauRefProd, std::vector<reco::PFTau3ProngSummaryRef>>>(PFTauRefProd(Tau));
155  auto PFTau3PSCollection_out = std::make_unique<PFTau3ProngSummaryCollection>();
156  reco::PFTau3ProngSummaryRefProd PFTau3RefProd_out = iEvent.getRefBeforePut<reco::PFTau3ProngSummaryCollection>("PFTau3ProngSummary");
157 
158  // Load each discriminator
159  for(auto& disc : discriminators_) {iEvent.getByLabel(disc->inputTag_, disc->handle_);}
160 
161  // For each Tau Run Algorithim
162  if(Tau.isValid()){
163  for(reco::PFTauCollection::size_type iPFTau = 0; iPFTau < Tau->size(); iPFTau++) {
164  reco::PFTauRef tau(Tau, iPFTau);
165  reco::PFTau3ProngSummary PFTau3PS;
167  // Check if it passed all the discrimiantors
168  bool passed(true);
169  for(auto const& disc : discriminators_) {
170  // Check this discriminator passes
171  bool passedDisc = true;
172  if ( disc->cutFormula_ )passedDisc = (disc->cutFormula_->Eval((*disc->handle_)[tau]) > 0.5);
173  else passedDisc = ((*disc->handle_)[tau] > disc->cut_);
174  if ( !passedDisc ){passed = false; break;}
175  }
176  if (passed && cut_.get()){passed = (*cut_)(*tau);}
177  if (passed){
178  PDGInfo pdgInfo;
179  const reco::PFTauTransverseImpactParameterRef theTIP=TIPAV->value(tau.key());
180  const reco::VertexRef primaryVertex=theTIP->primaryVertex();
182  // Now compute the 3 prong Tau
183  bool SecondaryVtxOK(false);
185  if(theTIP->hasSecondaryVertex() && primaryVertex->ndof()>ndfPVT_){
186  const VertexRef secVtx=theTIP->secondaryVertex();
187  GlobalPoint sv(secVtx->position().x(),secVtx->position().y(),secVtx->position().z());
188  double vtxchi2(0), vtxndf(1);
190  vtxchi2=secVtx->chi2();
191  vtxndf=secVtx->ndof();
192  const std::vector<reco::Track>& selectedTracks=secVtx->refittedTracks();
193  std::vector<reco::TransientTrack> transTrkVect;
194  for(unsigned int i = 0; i!=selectedTracks.size();i++) transTrkVect.push_back(transTrackBuilder->build(selectedTracks[i]));
196  float piMassSigma(1.e-6), piChi(0.0), piNdf(0.0);
197  std::vector<RefCountedKinematicParticle> pions;
198  for(unsigned int i = 0; i<transTrkVect.size();i++) pions.push_back(kinFactory.particle(transTrkVect[i],pdgInfo.pi_mass(),piChi,piNdf,sv,piMassSigma));
199  RefCountedKinematicTree jpTree = kpvFitter_.fit(pions);
200  jpTree->movePointerToTheTop();
201  const KinematicParameters parameters = jpTree->currentParticle()->currentState().kinematicParameters();
202  AlgebraicSymMatrix77 cov=jpTree->currentParticle()->currentState().kinematicParametersError().matrix();
203  // get pions
204  double c(0);
205  std::vector<reco::Track> Tracks;
206  std::vector<LorentzVectorParticle> ReFitPions;
207  for(unsigned int i=0;i<transTrkVect.size();i++){
208  c+=transTrkVect[i].charge();
209  ReFitPions.push_back(ParticleBuilder::createLorentzVectorParticle(transTrkVect[i],*secVtx,true,true));
210  }
211  // now covert a1 into LorentzVectorParticle
212  TVectorT<double> a1_par(LorentzVectorParticle::NLorentzandVertexPar);
213  TMatrixTSym<double> a1_cov(LorentzVectorParticle::NLorentzandVertexPar);
214  for(int i = 0; i<LorentzVectorParticle::NLorentzandVertexPar; i++){
215  a1_par(i)=parameters(i);
216  for(int j = 0; j<LorentzVectorParticle::NLorentzandVertexPar; j++){
217  a1_cov(i,j)=cov(i,j);
218  }
219  }
220  a1=LorentzVectorParticle(a1_par,a1_cov,abs(PdtPdgMini::a_1_plus)*c,c,transTrackBuilder->field()->inInverseGeV(sv).z());
221  SecondaryVtxOK=true;
222  PFTau3PS=reco::PFTau3ProngSummary(theTIP,a1.p4(),vtxchi2,vtxndf);
223  }
224  else if(useTrackHelix==Algorithm_){
225  // use Track Helix
226  std::vector<TrackParticle> pions;
227  GlobalPoint pvpoint(primaryVertex->position().x(),primaryVertex->position().y(),primaryVertex->position().z());
228  const std::vector<edm::Ptr<reco::Candidate> > cands = tau->signalChargedHadrCands();
229  for (std::vector<edm::Ptr<reco::Candidate> >::const_iterator iter = cands.begin(); iter!=cands.end(); ++iter) {
230  const reco::Track* track = getTrack(**iter);
231  if (track != nullptr) {
232  reco::TransientTrack transTrk=transTrackBuilder->build(*track);
233  pions.push_back(ParticleBuilder::createTrackParticle(transTrk,pvpoint,true,true));
234  }
235 
236  }
237  TVector3 pv(secVtx->position().x(),secVtx->position().y(),secVtx->position().z());
238  Chi2VertexFitter chi2v(pions,pv);
239  SecondaryVtxOK=chi2v.fit();
240  double c(0); for(unsigned int i=0;i<pions.size();i++){c+=pions[i].charge();}
242  a1=chi2v.getMother(pdgid);
243  PFTau3PS =reco::PFTau3ProngSummary(theTIP,a1.p4(),vtxchi2,vtxndf);
244  }
245  }
246  if(SecondaryVtxOK){
247  // Tau Solver
248  TVector3 pv(primaryVertex->position().x(),primaryVertex->position().y(),primaryVertex->position().z());
249  TMatrixTSym<double> pvcov(LorentzVectorParticle::NVertex);
251  primaryVertex->fill(pvCov);
252  for(int i = 0; i<LorentzVectorParticle::NVertex; i++){
253  for(int j = 0; j<LorentzVectorParticle::NVertex; j++){
254  pvcov(i,j)=pvCov(i,j);
255  }
256  }
257  for(unsigned int i=0; i<PFTau3ProngSummary::nsolutions;i++){
258  TauA1NuConstrainedFitter TauA1NU(i,a1,pv,pvcov);
259  bool isFitOK=TauA1NU.fit();
260  if(isFitOK){
261  LorentzVectorParticle theTau=TauA1NU.getMother();
262  std::vector<LorentzVectorParticle> daughter=TauA1NU.getRefitDaughters();
263  std::vector<TLorentzVector> daughter_p4;
264  std::vector<int> daughter_charge,daughter_PDGID;
265  for(unsigned int d=0;d<daughter.size();d++){
266  daughter_p4.push_back(daughter[d].p4());
267  daughter_charge.push_back((int)daughter[d].charge());
268  daughter_PDGID.push_back(daughter[d].pdgId());
269  }
270  PFTau3PS.AddSolution(i,theTau.p4(),daughter_p4,daughter_charge,daughter_PDGID,(isFitOK),0.0,-999);
271  }
272  }
273  }
274  }
275  reco::PFTau3ProngSummaryRef PFTau3PSRef=reco::PFTau3ProngSummaryRef(PFTau3RefProd_out,PFTau3PSCollection_out->size());
276  PFTau3PSCollection_out->push_back(PFTau3PS);
277  AVPFTau3PS->setValue(iPFTau,PFTau3PSRef);
278  }
279  }
280  iEvent.put(std::move(PFTau3PSCollection_out),"PFTau3ProngSummary");
281  iEvent.put(std::move(AVPFTau3PS));
282 }
283 
std::vector< reco::PFTau3ProngSummary > PFTau3ProngSummaryCollection
collection of PFTau3ProngSummary objects
KinematicParticleVertexFitter kpvFitter_
T getParameter(std::string const &) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
PFTau3ProngReco(const edm::ParameterSet &iConfig)
std::unique_ptr< StringCutObjectSelector< reco::PFTau > > cut_
#define nullptr
reco::TransientTrack build(const reco::Track *p) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
edm::InputTag PFTauTIPTag_
ErrorD< N >::type type
Definition: Error.h:33
key_type key() const
Accessor for product key.
Definition: Ref.h:263
edm::RefProd< PFTauCollection > PFTauRefProd
references to PFTau collection
Definition: PFTauFwd.h:15
const reco::Track * bestTrack() const override
return a pointer to the track if present. otherwise, return a null pointer
uint16_t size_type
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:442
ROOT::Math::SMatrix< double, 7, 7, ROOT::Math::MatRepSym< double, 7 > > AlgebraicSymMatrix77
Definition: Matrices.h:9
GlobalVector inInverseGeV(const GlobalPoint &gp) const
Field value ad specified global point, in 1/Gev.
Definition: MagneticField.h:41
std::vector< LorentzVectorParticle > getRefitDaughters()
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
double p4[4]
Definition: TauolaWrapper.h:92
T z() const
Definition: PV3DBase.h:64
const MagneticField * field() const
def pv(vc)
Definition: MetAnalyzer.py:7
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:243
DiscCutPairVec discriminators_
bool isValid() const
Definition: HandleBase.h:74
RefCountedKinematicTree fit(const std::vector< RefCountedKinematicParticle > &particles) const
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:480
RefProd< PROD > getRefBeforePut()
Definition: Event.h:150
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)
std::vector< DiscCutPair * > DiscCutPairVec
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
fixed size matrix
HLT enums.
T get() const
Definition: EventSetup.h:71
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:480
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_
def move(src, dest)
Definition: eostools.py:511