ATLAS Offline Software
SVTag.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /***************************************************************************
6  SVTag.cxx
7 ***************************************************************************/
8 #include "JetTagTools/SVTag.h"
9 
11 #include "GaudiKernel/ITHistSvc.h"
15 
17 
18 #include <string>
19 
21 
22 namespace Analysis
23 {
24 
25  SVTag::SVTag(const std::string& t, const std::string& n, const IInterface* p)
26  : base_class(t,n,p),
27  m_likelihoodTool("Analysis::NewLikelihoodTool", this),
28  m_histoHelper(0),
29  m_secVxFinderName("SV1"),
30  m_isFlipped(false)
31  {
32  declareProperty("Runmodus", m_runModus= "reference");
33  declareProperty("referenceType", m_refType = "ALL");
34  declareProperty("jetPtMinRef", m_pTjetmin = 15.*Gaudi::Units::GeV);
35  declareProperty("LikelihoodTool", m_likelihoodTool);
36  declareProperty("checkOverflows", m_checkOverflows = false);
37  declareProperty("purificationDeltaR", m_purificationDeltaR = 0.8);
38 
39  declareProperty("jetCollectionList", m_jetCollectionList);
40  declareProperty("useForcedCalibration", m_doForcedCalib = false);
41  declareProperty("ForcedCalibrationName", m_ForcedCalibName = "Cone4H1Tower");
42 
43  declareProperty("SecVxFinderName",m_secVxFinderName);
44  declareProperty("SVAlgType", m_SVmode);
45  declareProperty("xAODBaseName", m_xAODBaseName);
46 
47  declareProperty("UseDRJetPvSv", m_useDRJPVSV = true);
48  declareProperty("UseCHypo", m_useCHypo=true);
49  declareProperty("UseSV2Pt", m_usePtSV2=false);
50  declareProperty("SaveProbabilities", m_save_probabilities=false);
51 
52  }
53 
54  SVTag::~SVTag() {
55  delete m_histoHelper;
56  }
57 
60 
62  m_hypotheses.push_back("B");
63  m_hypotheses.push_back("U");
64  if(m_useCHypo){
65  m_hypotheses.push_back("C");
66  }
67 
69  ITHistSvc* myHistoSvc;
70  if( service( "THistSvc", myHistoSvc ).isSuccess() ) {
71  ATH_MSG_DEBUG("#BTAG#" << name() << ": HistoSvc loaded successfully.");
72  m_histoHelper = new HistoHelperRoot(myHistoSvc);
74  } else ATH_MSG_ERROR("#BTAG#" << name() << ": HistoSvc could NOT bo loaded.");
75 
77  if( m_runModus == "analysis" && m_SVmode != "SV0" && m_save_probabilities) {
78  if ( m_likelihoodTool.retrieve().isFailure() ) {
79  ATH_MSG_FATAL("#BTAG# Failed to retrieve tool " << m_likelihoodTool);
80  return StatusCode::FAILURE;
81  } else {
82  ATH_MSG_INFO("#BTAG# Retrieved tool " << m_likelihoodTool);
83  }
84  m_likelihoodTool->defineHypotheses(m_hypotheses);
85  m_likelihoodTool->printStatus();
86  }
87 
88 
89  /* ----------------------------------------------------------------------------------- */
90  /* BOOK HISTOS IF IN REFERENCE MODE */
91  /* ----------------------------------------------------------------------------------- */
92  if (m_runModus=="reference" && m_SVmode!="SV0") {
93  //
94  // Book the histos
95  //
96  ATH_MSG_VERBOSE("#BTAG# Booking histos...");
97  std::vector<double> xb;
98  double xbi[10] = {1., 2., 3., 4., 5., 6., 8., 10., 20., 50.};
99  for(const auto& jetColl : m_jetCollectionList) {
100  for(uint ih=0;ih<m_hypotheses.size();ih++) {
101  // SV1
102  if (m_SVmode == "SV1") {
103  std::string hDir = "/RefFile/SV1/"+jetColl+"/"+m_hypotheses[ih]+"/";
104  m_histoHelper->bookHisto(hDir+"N2T", "Number of Good Two Track Vertices",9,xbi);
105  m_histoHelper->bookHisto(hDir+"N2TEffSV1", "Number of Good Two Track Vertices",9,xbi);
106  m_histoHelper->bookHisto(hDir+"N2TNormSV1", "Number of Good Two Track Vertices",30,0.,30.);
107  m_histoHelper->bookHisto(hDir+"BidimME", "(E fraction)**0.7 vs Mass/(Mass+1)" ,50,0.218261406,1.,50,0.,1.);
108  m_histoHelper->bookHisto(hDir+"DRJPVSV", "DeltaR between jet axis and (PV,SV) axis",100,0.,0.5);
109  } else if (m_SVmode == "SV2") {
110  std::string hDir = "/RefFile/SV2/"+jetColl+"/"+m_hypotheses[ih]+"/";
111  // SV2
112  m_histoHelper->bookHisto(hDir+"N2TEffSV2", "Number of Good Two Track Vertices",9,xbi);
113  m_histoHelper->bookHisto(hDir+"N2TNormSV2", "Number of Good Two Track Vertices",30,0.,30.);
114  if(m_usePtSV2)m_histoHelper->bookHisto(hDir+"TridimMENPt","ln(Pt) vs (E fraction)**0.7 vs Mass/(Mass+1)",20,0.,1.,20,0.,1.,6,0.,4.8);
115  else m_histoHelper->bookHisto(hDir+"TridimMEN2T"," ln(N) vs (E fraction)**0.7 vs Mass/(Mass+1)",20,0.,1.,20,0.,1.,7,0.,3.8);
116  if(ih==0) {
117  // Control with SV2
118  hDir = "/RefFile/SV2/"+jetColl+"/controlSV/";
119  m_histoHelper->bookHisto(hDir+"eta","eta",60,-3.,3.);
120  m_histoHelper->bookHisto(hDir+"phi","phi",64,-3.2,3.2);
121  m_histoHelper->bookHisto(hDir+"pt","pt",50,0.,300.);
122  }
123  }
124  }
125  }
126  m_histoHelper->print();
127  }
128 
129  // Check if this instance of tagger is a flipped one:
130  std::string iname( this->name().substr(8) );
131  std::string::size_type pos = iname.find("Flip");
132  if ( pos!=std::string::npos ) {
133  m_isFlipped = true;
134  ATH_MSG_INFO("#BTAG# This instance of tagger has a flipped configuration. DRJPVSV computation will be adjusted.");
135  }
136 
137  //Conversion to GeV
138  m_c_mom = 1000.;
139  //
140  m_expos = 0.7;
141 
142  m_nbjet = 0;
143  m_ncjet = 0;
144  m_nljet = 0;
145  return StatusCode::SUCCESS;
146  }
147 
148 
150  {
151  if( m_runModus == "reference" ) {
152  ATH_MSG_INFO("#BTAG# Number of jets used for calibration for reference "
153  << m_refType << " : #b= " << m_nbjet << " #light= " << m_nljet << " #charm= " << m_ncjet
154  );
155  }
156  return StatusCode::SUCCESS;
157  }
158 
159  StatusCode SVTag::tagJet(const xAOD::Vertex& priVtx,
160  const xAOD::Jet& jetToTag,
162  const std::string &jetName) const
163  {
164 
166  std::string author = jetName;
168  ATH_MSG_VERBOSE("#BTAG# Using jet type " << author << " for calibrations.");
169 
170  /* The jet */
171  Amg::Vector3D jetDir(jetToTag.p4().Px(),jetToTag.p4().Py(),jetToTag.p4().Pz());
172  double jeteta = jetToTag.eta(), jetphi = jetToTag.phi(), jetpt = jetToTag.pt();
173  ATH_MSG_VERBOSE("#BTAG# Jet properties : eta = " << jeteta
174  << " phi = " << jetphi << " pT = " <<jetpt/m_c_mom);
175 
176  // Fill control histograms
177  if (m_runModus=="reference" && m_SVmode == "SV2") {
178  if (std::abs(jeteta) <= 2.5) {
179  m_histoHelper->fillHisto("/RefFile/SV2/"+author+"/controlSV/eta",(double)jeteta);
180  m_histoHelper->fillHisto("/RefFile/SV2/"+author+"/controlSV/phi",(double)jetphi);
181  m_histoHelper->fillHisto("/RefFile/SV2/"+author+"/controlSV/pt",(double)jetpt/m_c_mom);
182  }
183  }
184  //
185  // Get the SV info
186  //
187  float ambtot = -1., xratio = -1., distnrm = 0., drJPVSV = 0., Lxy = -100., L3d = -100.;
188  int NSVPair = -1;
189  float distnrmCorr=0.;
190 
191  //retrieving the secondary vertices
192  bool status = true;
193  std::vector< ElementLink< xAOD::VertexContainer > > myVertices;
194  // don't check the following status
195  BTag.variable<std::vector<ElementLink<xAOD::VertexContainer> > >(m_secVxFinderName, "vertices", myVertices);
196 
197  if (!myVertices.empty()) {
198 
199  status &= BTag.variable<float>(m_secVxFinderName, "masssvx", ambtot);// mass in MeV
200  ambtot/=m_c_mom;
201  status &= BTag.variable<float>(m_secVxFinderName, "efracsvx", xratio);
202  status &= BTag.variable<int>(m_secVxFinderName, "N2Tpair", NSVPair);
203 
204  if (!status) {
205  ATH_MSG_WARNING("Error retrieving variables for SV finder name " << m_secVxFinderName << ", result will be incorrect!");
206  }
207 
208  // DR between Jet axis and PV-SV axis
209  // For the time being computed only for Single Vertex...
210  if (myVertices[0].isValid()) {
211  const xAOD::Vertex* firstVertex = *(myVertices[0]);
212 
213  //FIXME ugly hack to get a Amg::Vector3D out of a CLHEP::HepLorentzVector
214  const Amg::Vector3D PVposition = priVtx.position();
215  const Amg::Vector3D position = firstVertex->position();
216  Amg::Vector3D PvSvDir( position.x() - PVposition.x(),
217  position.y() - PVposition.y(),
218  position.z() - PVposition.z() );
219  double drJPVSV_1 = Amg::deltaR(jetDir,PvSvDir);
220  drJPVSV = drJPVSV_1;
221  // for flipped taggers, use -jet direction:
222  double drJPVSV_2 = Amg::deltaR(-jetDir, PvSvDir); // for negative tags
223  if ( m_isFlipped ) drJPVSV = drJPVSV_2; // for negative tags
224  ATH_MSG_VERBOSE("#BTAG# DRJPVSV regular="<<drJPVSV_1<<" flipped="<<drJPVSV_2<<" chosen="<<drJPVSV);
225 
226  Lxy = std::hypot(PvSvDir(0,0), PvSvDir(1,0));
227  L3d = std::hypot(PvSvDir(0,0), PvSvDir(1,0), PvSvDir(2,0));
228  }else{
229  ATH_MSG_VERBOSE("#BTAG# No secondary vertex.");
230  }
231 
232  std::vector<const xAOD::Vertex*> vecVertices;
233  for (const auto& link : myVertices) {
234  if (!link.isValid()) {
235  ATH_MSG_WARNING("#BTAG# Secondary vertex from InDetVKalVxInJetFinder has zero pointer. Skipping... ");
236  continue;
237  }
238  vecVertices.push_back(*link);
239  }
240 
241  if (myVertices[0].isValid()) {
242  const xAOD::Vertex* myVert = *myVertices[0];
243  distnrm = get3DSignificance(priVtx, vecVertices, jetDir);
244  ATH_MSG_VERBOSE("#BTAG# SVX x = " << myVert->position().x() << " y = " << myVert->position().y() << " z = " << myVert->position().z());
245  distnrmCorr = get3DSignificanceCorr(priVtx, vecVertices, jetDir);
246  } else {
247  ATH_MSG_VERBOSE("#BTAG# No vertex. Cannot calculate normalized distance.");
248  distnrm=0.;
249  }
250 
251  ATH_MSG_VERBOSE("#BTAG# The SVX prop. sign3d: " << distnrm);
252  ATH_MSG_VERBOSE("#BTAG# Svx Mass = "<< ambtot << " Svx E frac = " << xratio << " NGood2TrackVertices = " << NSVPair);
253  } else {
254  //keepInfoPlus = false;
255  ATH_MSG_VERBOSE("#BTAG# No SVx !");
256  }
257 
258 
259  /* Give information to the info class. */
260  // define Info name based on tagger instance name
261  // (remove ToolSvc. in front and Tag inside name):
262  std::string iname(name().substr(8));
263  std::string instanceName(iname);
264  std::string::size_type pos = iname.find("Tag");
265  if (pos != std::string::npos) {
266  std::string prefix = iname.substr(0,pos);
267  std::string posfix = iname.substr(pos+3);
268  instanceName = prefix;
269  instanceName += posfix;
270  }
271 
272  //AA: Move to filling xAOD::BTagging
273  // note that this block is filling things other than likelihood,
274  // it should not be conditional on m_save_probabilities
275  if (m_runModus=="analysis") {
276  // -- fill extended info class ...
277 
278  if (m_xAODBaseName == "SV0") // just to be clear, specify enum explicitely
279  {
280  BTag.setTaggerInfo(distnrm, xAOD::BTagInfo::SV0_normdist);
281  BTag.setSV0_significance3D(distnrm);
282  }
283  else if (m_xAODBaseName == "SV1")
284  {
285  BTag.setTaggerInfo(distnrmCorr, xAOD::BTagInfo::SV1_normdist);
286  BTag.setVariable<float>(m_xAODBaseName, "significance3d", distnrm);
287  BTag.setVariable<float>(m_xAODBaseName, "correctSignificance3d", distnrmCorr);
288  BTag.setVariable<float>(m_xAODBaseName, "deltaR", drJPVSV);
289  BTag.setVariable<float>(m_xAODBaseName, "Lxy", Lxy);
290  BTag.setVariable<float>(m_xAODBaseName, "L3d", L3d);
291  }
292  else{
293  BTag.setVariable<float>(m_xAODBaseName, "normdist", distnrm);
294  if (m_xAODBaseName.find("SV1")!=std::string::npos) {
295  BTag.setVariable<float>(m_xAODBaseName, "significance3d", distnrm);
296  BTag.setVariable<float>(m_xAODBaseName, "correctSignificance3d", distnrmCorr);
297  BTag.setVariable<float>(m_xAODBaseName, "deltaR", drJPVSV);
298  BTag.setVariable<float>(m_xAODBaseName, "Lxy", Lxy);
299  BTag.setVariable<float>(m_xAODBaseName, "L3d", L3d);
300  }
301  }
302 
303  } // end "analysis" mode block
304 
305 
306  /* For SV1 & SV2, compute the weight (analysis) or fill histograms (reference) */
307  ATH_MSG_VERBOSE("#BTAG# SV mode = " << m_SVmode);
308 
309  if (m_SVmode != "SV0" ) {
310  float ambtotp = ambtot > 0. ? ambtot/(1.+ambtot) : 0.;
311  float xratiop = xratio > 0. ? (float)pow(xratio,m_expos) : 0.;
312  float trfJetPt = log(jetToTag.pt()/20000.);
313  if(trfJetPt<0.) trfJetPt=0.01;
314  if(trfJetPt>4.8) trfJetPt=4.79;
315  std::string pref = "";
316  if (m_runModus=="reference") {
317  if (jetpt >= m_pTjetmin && std::abs(jeteta) <= 2.5) {
318  int label = xAOD::jetFlavourLabel(&jetToTag);
319  double deltaRtoClosestB = 999.;//, deltaRtoClosestC = 999.;
320  if (jetToTag.getAttribute("TruthLabelDeltaR_B",deltaRtoClosestB)) {
321  ATH_MSG_VERBOSE("#BTAG# label found : " << label);
322  // for purification: require no b or c quark closer than dR=m_purificationDeltaR
323  double deltaRtoClosestC;
324  jetToTag.getAttribute("TruthLabelDeltaR_C", deltaRtoClosestC);//mcTrueInfo->deltaRMinTo("C");
325  double deltaRmin = deltaRtoClosestB < deltaRtoClosestC ? deltaRtoClosestB : deltaRtoClosestC;
326 
327  if ( ( "B"==m_refType && 5==label ) || // b-jets
328  ( "UDSG"==m_refType && 0==label ) || // light jets
329  ( "ALL"==m_refType && // all jets: b + purified light jets
330  ( 5==label || 4==label || ( 0==label && deltaRmin > m_purificationDeltaR ) ) )
331  ) {
332  if (5==label) {
333  pref = m_hypotheses[0];
334  m_nbjet++;
335  } else if (0==label) {
336  pref = m_hypotheses[1];
337  m_nljet++;
338  } else if (4==label && m_useCHypo) {
339  pref = m_hypotheses[2];
340  m_ncjet++;
341  }
342  }
343 
344  if (pref == "B" || pref == "C" || pref == "U") {
345  std::string hDir = "/RefFile/"+m_SVmode+"/"+author+"/"+pref+"/";
346  if (m_SVmode == "SV1") m_histoHelper->fillHisto(hDir+"N2TNormSV1",(float)NSVPair);
347  if (m_SVmode == "SV2") m_histoHelper->fillHisto(hDir+"N2TNormSV2",(float)NSVPair);
348  if (NSVPair > 0 && ambtot > 0.) {
349  if (xratiop == 1.) xratiop = 0.999999; //This is not an overflow...
350  if (m_SVmode == "SV1") {
351  m_histoHelper->fillHisto(hDir+"N2T",(float)NSVPair);
352  m_histoHelper->fillHisto(hDir+"N2TEffSV1",(float)NSVPair);
353  m_histoHelper->fillHisto(hDir+"BidimME",ambtotp,xratiop);
354  m_histoHelper->fillHisto(hDir+"DRJPVSV",(float)drJPVSV);
355  }
356  if (m_SVmode == "SV2") {
357  m_histoHelper->fillHisto(hDir+"N2TEffSV2",(float)NSVPair);
358  if(m_usePtSV2) m_histoHelper->fillHisto(hDir+"TridimMENPt",ambtotp,xratiop,trfJetPt);
359  else m_histoHelper->fillHisto(hDir+"TridimMEN2T",ambtotp,xratiop,log((float)NSVPair));
360  }
361  }
362  }
363  } else {
364  ATH_MSG_ERROR("#BTAG# No TruthInfo ! Cannot run in reference mode !");
365  return StatusCode::FAILURE;
366  }
367  }
368  } else if (m_runModus=="analysis" && m_save_probabilities) {
369  std::vector<double> probi;
370  // access efficiencies:
371  double effb = m_likelihoodTool->getEff(m_hypotheses[0], author+"#N2T", m_SVmode);
372  double effu = m_likelihoodTool->getEff(m_hypotheses[1], author+"#N2T", m_SVmode);
373  double effc = 1.e9;
374  if(m_useCHypo){
375  effc = m_likelihoodTool->getEff(m_hypotheses[2], author+"#N2T", m_SVmode);
376  }
377  ATH_MSG_DEBUG( "#BTAG# EFF b,u,c= " << effb << " " << effu << " " << effc);
378  if (NSVPair>0 && ambtot > 0.) {
379  std::vector<Slice> nslices;
380  AtomicProperty atom2(ambtotp,"SecVtx Transformed Mass");
381  AtomicProperty atom3(xratiop,"SecVtx Transformed Energy Fraction");
382  if (m_SVmode == "SV1") {
383  AtomicProperty atom1(NSVPair,"Number of Two Track Vertices");
384  std::string compoName(author+"#");
385  Composite compo1(compoName+"N2T");
386  Composite compo2(compoName+"BidimME");
387  compo1.atoms.push_back(atom1);
388  compo2.atoms.push_back(atom2);
389  compo2.atoms.push_back(atom3);
390  Slice slice1("SV1");
391  slice1.composites.push_back(compo1);
392  slice1.composites.push_back(compo2);
393  if(m_useDRJPVSV) {
394  AtomicProperty atom4(drJPVSV,"DeltaR between jet axis and (PV,SV) axis");
395  Composite compo3(compoName+"DRJPVSV");
396  compo3.atoms.push_back(atom4);
397  slice1.composites.push_back(compo3);
398  }
399  nslices.push_back(slice1);
400  } else if (m_SVmode == "SV2") {
401  std::string compoName(author+"#");
402  Slice slice1("SV2");
403  if(m_usePtSV2){
404  AtomicProperty atom1(trfJetPt,"log(JetPt/2e4)");
405  Composite compo(compoName+"TridimMENPt");
406  compo.atoms.push_back(atom2);
407  compo.atoms.push_back(atom3);
408  compo.atoms.push_back(atom1);
409  Composite compo1(compoName+"N2TEffSV2");
410  AtomicProperty atom4(NSVPair,"Number of Two Track Vertices");
411  compo1.atoms.push_back(atom4);
412  slice1.composites.push_back(compo);
413  slice1.composites.push_back(compo1);
414  }else{
415  AtomicProperty atom1(log((float)NSVPair),"log(Number of Two Track Vertices)");
416  Composite compo(compoName+"TridimMEN2T");
417  compo.atoms.push_back(atom2);
418  compo.atoms.push_back(atom3);
419  compo.atoms.push_back(atom1);
420  slice1.composites.push_back(compo);
421  }
422  nslices.push_back(slice1);
423  }
424  probi = m_likelihoodTool->calculateLikelihood(nslices);
425  ATH_MSG_DEBUG( "#BTAG# WEIGHT: pb, pu, pc= "
426  << probi[0] << " " << probi[1] << " " << probi[2]);
427  if (probi.size() >= 2) {
428  probi[0] *= effb;
429  probi[1] *= effu;
430  if(m_useCHypo){
431  probi[2] *= effc;
432  }
433  } else {
434  ATH_MSG_ERROR("#BTAG# Missing number in jet probabilities ! "<<probi.size());
435  }
436  } else {
437  // The SV weight is computed even if there is only one or no track !
438  // It may seem a little bit weird...
439  probi.push_back((1.-effb));
440  probi.push_back((1.-effu));
441  if(m_useCHypo){
442  probi.push_back((1.-effc));
443  }
444  }
445  if (probi.size()>=2){
446  BTag.setVariable<float>(m_xAODBaseName, "pb", probi[0]);
447  BTag.setVariable<float>(m_xAODBaseName, "pu", probi[1]);
448  }
449  if (m_useCHypo and (probi.size()>=3)) BTag.setVariable<float>(m_xAODBaseName, "pc", probi[2]);
450 
451  } // end analysis mode
452 
453  /* For SV0, put the signed 3D Lxy significance: */
454  } else {
455  ATH_MSG_VERBOSE("#BTAG# SV0 Lxy3D significance = " << distnrm);
456  BTag.setVariable<float>(m_xAODBaseName, "pb", exp(distnrm));
457  BTag.setVariable<float>(m_xAODBaseName, "pu", 1);
458  if (m_useCHypo) BTag.setVariable<float>(m_xAODBaseName, "pc", 1);
459  }
460 
461  ATH_MSG_VERBOSE("#BTAG# SVTag Finalizing... ");
462 
463  return StatusCode::SUCCESS;
464  }
465 
467  ATH_MSG_INFO("#BTAG# " << name() << "Parameter settings ");
468  ATH_MSG_INFO("#BTAG# I am in " << m_runModus << " modus.");
469  ATH_MSG_INFO("#BTAG# The method is " << m_SVmode);
470  if (m_runModus == "reference") ATH_MSG_INFO("#BTAG# Preparing "<< m_refType<< "-jet probability density functions...");
471  }
472 
473  double SVTag::get3DSignificance(const xAOD::Vertex& priVertex,
474  std::vector<const xAOD::Vertex*>& secVertex,
475  const Amg::Vector3D jetDirection) const {
476 
477  std::vector<Amg::Vector3D> positions;
478  std::vector<AmgSymMatrix(3)> weightMatrices;
479  // If multiple secondary vertices were reconstructed, then a common (weighted) position will be used
480  // in the signed decay length significance calculation
481  Amg::Vector3D weightTimesPosition(0.,0.,0.);
482  AmgSymMatrix(3) sumWeights;
483  sumWeights.setZero();
484 
485  for (const auto& vtx : secVertex) {
486  positions.push_back(vtx->position());
487  weightMatrices.push_back(vtx->covariancePosition().inverse());
488  weightTimesPosition += weightMatrices.back()*positions.back();
489  sumWeights += weightMatrices.back();
490  }
491 
492  // now we have the sum of the weights, let's invert this matrix to get the mean covariance matrix
493  bool invertible;
494  AmgSymMatrix(3) meanCovariance;
495  meanCovariance.setZero();
496  sumWeights.computeInverseWithCheck(meanCovariance, invertible);
497  if (!invertible) {
498  ATH_MSG_WARNING("#BTAG# Could not invert sum of sec vtx matrices");
499  return 0.;
500  }
501 
502  // calculate the weighted mean secondary vertex position
503  Amg::Vector3D meanPosition = meanCovariance*weightTimesPosition;
504 
505  // add the mean covariance matrix of the secondary vertices to that of the primary vertex
506  // this is the covariance matrix for the decay length
507  AmgSymMatrix(3) covariance = meanCovariance + priVertex.covariancePosition();
508 
509  // ********
510  // Calculate the signed decay length significance
511  // ********
512 
513  double Lx = meanPosition[0]-priVertex.position().x();
514  double Ly = meanPosition[1]-priVertex.position().y();
515  double Lz = meanPosition[2]-priVertex.position().z();
516 
517  const double decaylength = sqrt(Lx*Lx + Ly*Ly + Lz*Lz);
518  if(decaylength==0.) return 0.; //Safety
519  const double inv_decaylength = 1. / decaylength;
520 
521  double dLdLx = Lx * inv_decaylength;
522  double dLdLy = Ly * inv_decaylength;
523  double dLdLz = Lz * inv_decaylength;
524  double decaylength_err2 = (dLdLx*dLdLx*covariance(0,0) +
525  dLdLy*dLdLy*covariance(1,1) +
526  dLdLz*dLdLz*covariance(2,2) +
527  2.*dLdLx*dLdLy*covariance(0,1) +
528  2.*dLdLx*dLdLz*covariance(0,2) +
529  2.*dLdLy*dLdLz*covariance(1,2));
530  if(decaylength_err2<=0.) return 0.; //Something is wrong
531  double decaylength_err = sqrt(decaylength_err2);
532 
533  double decaylength_significance = 0.;
534  if (decaylength_err != 0.) decaylength_significance = decaylength/decaylength_err;
535 
536  // get sign from projection on jet axis
537  double L_proj_jetDir = jetDirection.x()*Lx + jetDirection.y()*Ly + jetDirection.z()*Lz;
538  if (L_proj_jetDir < 0.) decaylength_significance *= -1.;
539 
540  return decaylength_significance;
541  }
542 
543  double SVTag::get3DSignificanceCorr(const xAOD::Vertex& priVertex,
544  std::vector<const xAOD::Vertex*>& secVertex,
545  const Amg::Vector3D jetDirection) const {
546 
547  std::vector<double> Sig3D(0);
548  bool success=true;
549  AmgSymMatrix(3) Wgt;
550 
551  for (const auto & svrt : secVertex)
552  {
553  Amg::Vector3D SVmPV = svrt->position()-priVertex.position();
554  AmgSymMatrix(3) SVmPVCov = svrt->covariancePosition()+priVertex.covariancePosition();
555  SVmPVCov.computeInverseWithCheck(Wgt, success);
556  if( !success || Wgt(0,0)<=0. || Wgt(1,1)<=0. || Wgt(2,2)<=0. )continue; //Inversion failure
557  double significance = SVmPV.transpose()*Wgt*SVmPV;
558  if(significance <= 0.) continue; //Something is still wrong!
559  significance = std::sqrt(significance);
560  if(SVmPV.dot(jetDirection)<0.) significance *= -1.;
561  Sig3D.push_back(significance);
562  }
563 
564  if(Sig3D.size()==0) return 0.;
565 
566  return *std::max_element(Sig3D.begin(),Sig3D.end());
567  }
568 
569 }
570 
Analysis::Composite::atoms
std::vector< AtomicProperty > atoms
Definition: LikelihoodComponents.h:29
JetFlavourInfo.h
Analysis::SVTag::m_expos
float m_expos
Definition: SVTag.h:59
Analysis::SVTag::m_likelihoodTool
ToolHandle< NewLikelihoodTool > m_likelihoodTool
Definition: SVTag.h:55
HistoHelperRoot.h
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
module_driven_slicing.nslices
nslices
Definition: module_driven_slicing.py:575
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Analysis::HistoHelperRoot
Helper class for histograming.
Definition: HistoHelperRoot.h:36
PlotCalibFromCool.label
label
Definition: PlotCalibFromCool.py:78
Analysis::SVTag::m_ForcedCalibName
std::string m_ForcedCalibName
Definition: SVTag.h:83
Analysis::SVTag::m_histoHelper
HistoHelperRoot * m_histoHelper
Definition: SVTag.h:56
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
Analysis::SVTag::m_usePtSV2
bool m_usePtSV2
Definition: SVTag.h:77
Analysis::SVTag::tagJet
virtual StatusCode tagJet(const xAOD::Vertex &priVtx, const xAOD::Jet &jetToTag, xAOD::BTagging &BTag, const std::string &jetName) const override
Definition: SVTag.cxx:161
Analysis::HistoHelperRoot::setCheckOverflows
void setCheckOverflows(bool b)
Definition: HistoHelperRoot.h:71
xAOD::Jet_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
Definition: Jet_v1.cxx:54
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Analysis::SVTag::m_purificationDeltaR
double m_purificationDeltaR
Definition: SVTag.h:66
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
isValid
bool isValid(const T &p)
Definition: AtlasPID.h:214
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
Analysis::SVTag::printParameterSettings
void printParameterSettings()
just print some info at the beginning
Definition: SVTag.cxx:468
xAOD::SV1_normdist
@ SV1_normdist
SV1 : 3D vertex significance.
Definition: BTaggingEnums.h:41
xAOD::Jet_v1::getAttribute
bool getAttribute(AttributeID type, T &value) const
Retrieve attribute moment by enum.
Analysis::SVTag::SVTag
SVTag(const std::string &, const std::string &, const IInterface *)
Definition: SVTag.cxx:27
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
Analysis::HistoHelperRoot::print
void print()
Definition: HistoHelperRoot.cxx:178
SVTag.h
Analysis::Composite
Definition: LikelihoodComponents.h:26
Analysis::SVTag::m_ncjet
std::atomic< int > m_ncjet
Definition: SVTag.h:73
Analysis::SVTag::initialize
virtual StatusCode initialize() override
Definition: SVTag.cxx:60
uint
unsigned int uint
Definition: LArOFPhaseFill.cxx:20
Analysis::SVTag::get3DSignificance
double get3DSignificance(const xAOD::Vertex &priVertex, std::vector< const xAOD::Vertex * > &secVertex, const Amg::Vector3D jetDirection) const
Definition: SVTag.cxx:475
xAOD::jetFlavourLabel
int jetFlavourLabel(const xAOD::Jet *jet, JetFlavourLabelType=ExclConeHadron)
Definition: JetFlavourInfo.cxx:93
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Analysis::SVTag::m_nbjet
std::atomic< int > m_nbjet
Definition: SVTag.h:72
NewLikelihoodTool.h
beamspotman.n
n
Definition: beamspotman.py:731
Analysis::SVTag::m_SVmode
std::string m_SVmode
Definition: SVTag.h:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Analysis::HistoHelperRoot::bookHisto
void bookHisto(const std::string &histoName, const std::string &histoTitle, unsigned int bins, double minx, double maxx)
Definition: HistoHelperRoot.cxx:55
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Analysis::SVTag::m_isFlipped
bool m_isFlipped
Definition: SVTag.h:92
Analysis::SVTag::m_refType
std::string m_refType
Definition: SVTag.h:62
Analysis::SVTag::m_hypotheses
std::vector< std::string > m_hypotheses
Definition: SVTag.h:80
xAOD::SV0_normdist
@ SV0_normdist
SV0 : 3D vertex significance.
Definition: BTaggingEnums.h:28
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
Analysis::SVTag::m_c_mom
double m_c_mom
Definition: SVTag.h:58
Analysis::SVTag::~SVTag
virtual ~SVTag()
Definition: SVTag.cxx:56
xAOD::BTagging_v1
Definition: BTagging_v1.h:39
Analysis::SVTag::m_jetCollectionList
std::vector< std::string > m_jetCollectionList
Definition: SVTag.h:79
xAOD::Jet_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: Jet_v1.cxx:49
Analysis::AtomicProperty
Definition: LikelihoodComponents.h:19
Analysis
The namespace of all packages in PhysicsAnalysis/JetTagging.
Definition: BTaggingCnvAlg.h:20
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Analysis::SVTag::m_save_probabilities
bool m_save_probabilities
Definition: SVTag.h:93
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Analysis::SVTag::m_doForcedCalib
bool m_doForcedCalib
Definition: SVTag.h:82
DataModelTestDataCommonDict::xb
DMTest::CView::Pers_t xb
Definition: DataModelTestDataCommonDict.h:44
Analysis::SVTag::finalize
virtual StatusCode finalize() override
Definition: SVTag.cxx:151
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Analysis::SVTag::m_checkOverflows
bool m_checkOverflows
Definition: SVTag.h:65
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
Amg::deltaR
double deltaR(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
Definition: GeoPrimitivesHelpers.h:122
xAOD::Jet_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: Jet_v1.cxx:71
VertexContainer.h
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
Analysis::SVTag::get3DSignificanceCorr
double get3DSignificanceCorr(const xAOD::Vertex &priVertex, std::vector< const xAOD::Vertex * > &secVertex, const Amg::Vector3D jetDirection) const
Definition: SVTag.cxx:545
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Analysis::Slice::composites
std::vector< Composite > composites
Definition: LikelihoodComponents.h:35
GeoPrimitivesHelpers.h
CaloCondBlobAlgs_fillNoiseFromASCII.author
string author
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:26
Analysis::Slice
Definition: LikelihoodComponents.h:32
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
Analysis::SVTag::m_xAODBaseName
std::string m_xAODBaseName
Definition: SVTag.h:88
Analysis::SVTag::m_useDRJPVSV
bool m_useDRJPVSV
Definition: SVTag.h:91
Analysis::HistoHelperRoot::fillHisto
void fillHisto(const std::string &histoName, double) const
Definition: HistoHelperRoot.cxx:103
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
Analysis::SVTag::m_nljet
std::atomic< int > m_nljet
Definition: SVTag.h:74
Analysis::SVTag::m_secVxFinderName
std::string m_secVxFinderName
Definition: SVTag.h:87
merge.status
status
Definition: merge.py:17
xAODType::BTag
@ BTag
The object is a b-tagging object.
Definition: ObjectType.h:60
Analysis::SVTag::m_useCHypo
bool m_useCHypo
Definition: SVTag.h:76
xAOD::Jet_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
Definition: Jet_v1.cxx:44
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
Analysis::SVTag::m_pTjetmin
float m_pTjetmin
Definition: SVTag.h:64
readCCLHist.float
float
Definition: readCCLHist.py:83
Analysis::SVTag::m_runModus
std::string m_runModus
Definition: SVTag.h:61
LikelihoodComponents.h