CMS 3D CMS Logo

CandidateChargeBTagComputer.cc
Go to the documentation of this file.
2 
4  useCondDB_ (parameters.getParameter<bool>("useCondDB") ),
5  gbrForestLabel_(parameters.getParameter<std::string>("gbrForestLabel") ),
6  weightFile_ (parameters.getParameter<edm::FileInPath>("weightFile") ),
7  useAdaBoost_ (parameters.getParameter<bool>("useAdaBoost") ),
8  jetChargeExp_ (parameters.getParameter<double>("jetChargeExp") ),
9  svChargeExp_ (parameters.getParameter<double>("svChargeExp") )
10 {
11  uses(0, "pfImpactParameterTagInfos");
12  uses(1, "pfInclusiveSecondaryVertexFinderCvsLTagInfos");
13  uses(2, "softPFMuonsTagInfos");
14  uses(3, "softPFElectronsTagInfos");
15 
16  mvaID.reset(new TMVAEvaluator());
17 }
18 
20 {
21 }
22 
24 {
25  // Saving MVA variable names;
26  // names and order need to be the same as in the training
27  std::vector< std::string > variables ({"tr_ch_inc","sv_ch","mu_sip2d",/*"mu_sip3d",*/"mu_delR","mu_ptrel","mu_pfrac","mu_char",/*"el_sip2d","el_sip3d",*/"el_delR","el_ptrel","el_pfrac","el_mva","el_char","pt1_ch/j_pt","pt2_ch/j_pt","pt3_ch/j_pt"});
28  std::vector< std::string > spectators (0);
29 
30  if (useCondDB_)
31  {
32  const GBRWrapperRcd & gbrWrapperRecord = record.getRecord<GBRWrapperRcd>();
33  edm::ESHandle<GBRForest> gbrForestHandle;
34  gbrWrapperRecord.get(gbrForestLabel_.c_str(), gbrForestHandle);
35  mvaID->initializeGBRForest(gbrForestHandle.product(), variables, spectators, useAdaBoost_);
36  }
37  else
38  mvaID->initialize("Color:Silent:Error", "BDT", weightFile_.fullPath(), variables, spectators, true, useAdaBoost_);
39 }
40 
42 {
43  // get TagInfos
44  const reco::CandIPTagInfo & ip_info = tagInfo.get<reco::CandIPTagInfo>(0);
46  const reco::CandSoftLeptonTagInfo& sm_info = tagInfo.get<reco::CandSoftLeptonTagInfo>(2);
47  const reco::CandSoftLeptonTagInfo& se_info = tagInfo.get<reco::CandSoftLeptonTagInfo>(3);
48 
49  size_t n_ip_info = ip_info.jet()->getJetConstituents().size();
50  size_t n_sv_info = sv_info.nVertices();
51  size_t n_sm_info = sm_info.leptons();
52  size_t n_se_info = se_info.leptons();
53 
54  // default discriminator value
55  float value = -10.;
56 
57  // if no tag info is present, MVA not computed and default discriminator value returned
58  if ( n_ip_info + n_sv_info + n_sm_info + n_se_info > 0 ) {
59 
60  // default variable values
61  float tr_ch_inc = 0;
62  float pt_ratio1_ch = 0;
63  float pt_ratio2_ch = 0;
64  float pt_ratio3_ch = 0;
65 
66  float sv_ch = 0;
67 
68  float mu_sip2d = 0;
69  //float mu_sip3d = 0;
70  float mu_delR = 0;
71  float mu_ptrel = 0;
72  float mu_pfrac = 0;
73  int mu_char = 0;
74 
75  //float el_sip2d = 0;
76  //float el_sip3d = 0;
77  float el_delR = 0;
78  float el_ptrel = 0;
79  float el_pfrac = 0;
80  float el_mva = 0;
81  int el_char = 0;
82 
83  // compute jet-charge
84  float tr_ch_num = 0;
85  float tr_ch_den = 0;
86 
87  // loop over tracks associated to the jet
88  for (size_t i_ip=0; i_ip < n_ip_info; ++i_ip)
89  {
90  const reco::Candidate * trackPtr = ip_info.jet()->getJetConstituents().at(i_ip).get();
91  if ( trackPtr->charge() == 0 ) continue;
92 
93  float tr_ch_weight = pow(trackPtr->pt(),jetChargeExp_);
94  tr_ch_num += tr_ch_weight * trackPtr->charge();
95  tr_ch_den += tr_ch_weight;
96 
97  // find the three higher-pt tracks
98  if ( fabs(pt_ratio1_ch) < trackPtr->pt() ) {
99  pt_ratio3_ch = pt_ratio2_ch;
100  pt_ratio2_ch = pt_ratio1_ch;
101  pt_ratio1_ch = trackPtr->pt() * trackPtr->charge();
102  } else if ( fabs(pt_ratio2_ch) < trackPtr->pt() ) {
103  pt_ratio3_ch = pt_ratio2_ch;
104  pt_ratio2_ch = trackPtr->pt() * trackPtr->charge();
105  } else if ( fabs(pt_ratio3_ch) < trackPtr->pt() ) {
106  pt_ratio3_ch = trackPtr->pt() * trackPtr->charge();
107  }
108  }
109  if ( n_ip_info>0 ) {
110  float jet_pt = ip_info.jet()->pt();
111  if ( jet_pt>0 ) {
112  pt_ratio1_ch = pt_ratio1_ch / jet_pt;
113  pt_ratio2_ch = pt_ratio2_ch / jet_pt;
114  pt_ratio3_ch = pt_ratio3_ch / jet_pt;
115  }
116  }
117 
118  if ( tr_ch_den > 0 ) tr_ch_inc = tr_ch_num / tr_ch_den;
119 
120  // compute secondary vertex charge
121  if ( n_sv_info > 0 )
122  {
123  float jet_pt = sv_info.jet()->pt();
124 
125  float sv_ch_num = 0;
126  float sv_ch_den = 0;
127 
128  // find the selected secondary vertex with highest invariant mass
129  int vtx_idx = -1;
130  float max_mass = 0;
131  for (size_t i_vtx=0; i_vtx<n_sv_info; ++i_vtx)
132  {
133  float sv_mass = sv_info.secondaryVertex(i_vtx).p4().mass();
134  float sv_chi2 = sv_info.secondaryVertex(i_vtx).vertexNormalizedChi2();
135  float sv_pfrac = sv_info.secondaryVertex(i_vtx).pt()/jet_pt;
136  float sv_L = sv_info.flightDistance(i_vtx).value();
137  float sv_sL = sv_info.flightDistance(i_vtx).significance();
138  float delEta = sv_info.secondaryVertex(i_vtx).momentum().eta()-sv_info.flightDirection(i_vtx).eta();
139  float delPhi = sv_info.secondaryVertex(i_vtx).momentum().phi()-sv_info.flightDirection(i_vtx).phi();
140  if ( fabs(delPhi)>M_PI ) delPhi = 2*M_PI - fabs(delPhi);
141  float sv_delR = sqrt( delEta*delEta + delPhi*delPhi );
142 
143  if ( sv_mass>max_mass && sv_mass>1.4 && sv_chi2<3 && sv_chi2>0 && sv_pfrac>0.25 && sv_L<2.5 && sv_sL>4 && sv_delR<0.1 )
144  {
145  max_mass = sv_mass;
146  vtx_idx = i_vtx;
147  }
148  }
149 
150  if (vtx_idx>=0)
151  {
152  // loop over tracks associated to the vertex
153  size_t n_sv_tracks = sv_info.vertexTracks(vtx_idx).size();
154  for (size_t i_tr=0; i_tr < n_sv_tracks; ++i_tr)
155  {
156  const reco::CandidatePtr trackRef = sv_info.vertexTracks(vtx_idx)[i_tr];
157  const reco::Track * trackPtr = reco::btag::toTrack(trackRef);
158 
159  float sv_ch_weight = pow(trackPtr->pt(),svChargeExp_);
160  sv_ch_num += sv_ch_weight * trackPtr->charge();
161  sv_ch_den += sv_ch_weight;
162  }
163 
164  if ( sv_ch_den > 0 ) sv_ch = sv_ch_num / sv_ch_den;
165  }
166  }
167 
168  // fill soft muon variables
169  if ( n_sm_info > 0 )
170  {
171  // find the muon with higher transverse momentum
172  int lep_idx = 0;
173  float max_pt = 0;
174  for (size_t i_lep=0; i_lep<n_sm_info; ++i_lep)
175  {
176  float lep_pt = sm_info.lepton(0)->pt();
177  if ( lep_pt > max_pt )
178  {
179  max_pt = lep_pt;
180  lep_idx = i_lep;
181  }
182  }
183 
184  mu_sip2d = sm_info.properties(lep_idx).sip2d;
185  //mu_sip3d = sm_info.properties(lep_idx).sip3d;
186  mu_delR = sm_info.properties(lep_idx).deltaR;
187  mu_ptrel = sm_info.properties(lep_idx).ptRel;
188  mu_pfrac = sm_info.properties(lep_idx).ratio;
189  mu_char = sm_info.properties(lep_idx).charge;
190  }
191 
192  // fill soft electron variables
193  if ( n_se_info > 0 )
194  {
195  // find the electron with higher transverse momentum
196  int lep_idx = 0;
197  float max_pt = 0;
198  for (size_t i_lep=0; i_lep<n_se_info; ++i_lep)
199  {
200  float lep_pt = se_info.lepton(0)->pt();
201  if ( lep_pt > max_pt )
202  {
203  max_pt = lep_pt;
204  lep_idx = i_lep;
205  }
206  }
207 
208  //el_sip2d = se_info.properties(lep_idx).sip2d;
209  //el_sip3d = se_info.properties(lep_idx).sip3d;
210  el_delR = se_info.properties(lep_idx).deltaR;
211  el_ptrel = se_info.properties(lep_idx).ptRel;
212  el_pfrac = se_info.properties(lep_idx).ratio;
213  el_mva = se_info.properties(lep_idx).elec_mva;
214  el_char = se_info.properties(lep_idx).charge;
215  }
216 
217  std::map<std::string,float> inputs;
218  inputs["tr_ch_inc"] = tr_ch_inc;
219  inputs["pt1_ch/j_pt"] = pt_ratio1_ch;
220  inputs["pt2_ch/j_pt"] = pt_ratio2_ch;
221  inputs["pt3_ch/j_pt"] = pt_ratio3_ch;
222  inputs["sv_ch"] = sv_ch;
223  inputs["mu_sip2d"] = mu_sip2d;
224  //inputs["mu_sip3d"] = mu_sip3d;
225  inputs["mu_delR"] = mu_delR;
226  inputs["mu_ptrel"] = mu_ptrel;
227  inputs["mu_pfrac"] = mu_pfrac;
228  inputs["mu_char"] = mu_char;
229  //inputs["el_sip2d"] = el_sip2d;
230  //inputs["el_sip3d"] = el_sip3d;
231  inputs["el_delR"] = el_delR;
232  inputs["el_ptrel"] = el_ptrel;
233  inputs["el_pfrac"] = el_pfrac;
234  inputs["el_mva"] = el_mva;
235  inputs["el_char"] = el_char;
236 
237  // evaluate the MVA
238  value = mvaID->evaluate(inputs);
239  }
240 
241  // return the final discriminator value
242  return value;
243 }
244 
245 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
246 void
248 
250  desc.add<bool>("useCondDB",false);
251  desc.add<std::string>("gbrForestLabel","");
252  desc.add<edm::FileInPath>("weightFile",edm::FileInPath());
253  desc.add<bool>("useAdaBoost",true);
254  desc.add<double>("jetChargeExp",0.8);
255  desc.add<double>("svChargeExp",0.5);
256  descriptions.addDefault(desc);
257 }
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const T & get(unsigned int index=0) const
JetCorrectorParameters::Record record
Definition: classes.h:7
std::unique_ptr< TMVAEvaluator > mvaID
const reco::Track * toTrack(const reco::TrackBaseRef &t)
Definition: IPTagInfo.h:24
PRODUCT const & get(ESGetToken< PRODUCT, T > const &iToken) const
static double delPhi(const double phi1, const double phi2)
void addDefault(ParameterSetDescription const &psetDescription)
T sqrt(T t)
Definition: SSEVec.h:18
double pt() const
track transverse momentum
Definition: TrackBase.h:660
void uses(unsigned int id, const std::string &label)
Definition: value.py:1
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void initialize(const JetTagComputerRecord &record) override
#define M_PI
virtual double pt() const =0
transverse momentum
CandidateChargeBTagComputer(const edm::ParameterSet &parameters)
virtual int charge() const =0
electric charge
HLT enums.
float discriminator(const TagInfoHelper &tagInfo) const override
std::string fullPath() const
Definition: FileInPath.cc:163
int charge() const
track electric charge
Definition: TrackBase.h:606
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40