Report problems to ATLAS LXR Team (with time and IP address indicated)

The LXR Cross Referencer

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Architecture: linux ]
Version: head ] [ nightly ] [ GaudiDev ]
  Links to LXR source navigation pages for stable releases [ 12.*.* ]   [ 13.*.* ]   [ 14.*.* ]   [ 15.*.* ] 

001 /********************************************************************
002 
003 NAME:     SoftElectronTag.cxx
004 PACKAGE:  offline/PhysicsAnalysis/JetTagging/JetTagTools
005 
006 AUTHORS:  F. Derue, A. Kaczmarska, M.Wolter
007 CREATED:  Jan 2005
008 
009 PURPOSE:  b-tagging based on soft lepton identification
010 
011 COMMENTS: evolved from LifetimeTag
012 
013 UPDATE: AK,MW - 10.02.2006 - some track quality cuts added
014         FD    - 06.02.2008 - migration to COOL
015         FD    - 10.04.2008 - track quality cuts + m_Db m_Du normalized
016         FD    - 17.05.2008 - add access to Photons (for conversions)
017         FD    - 23.06.2008 - m_originalElCollection absent  = warning only + d0
018         FD    - 27.10.2008 - reorder calls of weights, pTrel and d0
019         FD    - 15.01.2009 - use of AthAlgTool and other changes +
020                              adapt to log10(weight) given by egamma
021 ********************************************************************/
022 #include "JetTagTools/SoftElectronTag.h"
023 
024 #include "JetEvent/Jet.h"
025 #include "Particle/TrackParticle.h"
026 #include "JetTagInfo/SoftElectronInfo.h"
027 #include "Navigation/NavigationToken.h" 
028 
029 #include "egammaEvent/Photon.h"
030 #include "egammaEvent/Electron.h"
031 #include "egammaEvent/ElectronAssociation.h"
032 #include "egammaEvent/PhotonAssociation.h"
033 
034 #include "JetTagTools/TrackSelector.h"
035 #include "JetTagTools/SVForIPTool.h"
036 #include "JetTagTools/ITrackGradeFactory.h"
037 #include "Navigation/NavigationToken.h"
038 #include "ITrackToVertex/ITrackToVertex.h"
039 #include "TrkVertexFitterInterfaces/ITrackToVertexIPEstimator.h"
040 
041 #include "ParticleTruth/TrackParticleTruth.h"
042 #include "ParticleTruth/TrackParticleTruthCollection.h"
043 #include "GeneratorObjects/HepMcParticleLink.h"
044 #include "HepMC/GenParticle.h"
045 #include "HepMC/GenVertex.h"
046 
047 #include "JetTagInfo/TruthInfo.h"
048 #include "JetTagInfo/SoftLeptonTruthInfo.h"
049 #include "JetTagInfo/SLTrueInfo.h"
050 
051 #include "JetTagTools/HistoHelperRoot.h"
052 #include "JetTagTools/NewLikelihoodTool.h"
053 #include "JetTagCalibration/CalibrationBroker.h"
054 
055 #include "GaudiKernel/ITHistSvc.h"
056 #include "TH1.h"
057 
058 namespace Analysis 
059 {
060   
061 SoftElectronTag::SoftElectronTag(const std::string& t, const std::string& n, const IInterface* p)
062   : AthAlgTool(t,n,p),
063     m_trackToVertexTool("Reco::TrackToVertex"),
064     m_trackSelectorTool("Analysis::TrackSelector"),
065     m_trackToVertexIPEstimator("Trk::TrackToVertexIPEstimator"),
066     m_SVForIPTool("Analysis::SVForIPTool"),
067     m_unbiasIPEstimation(false),
068     m_likelihoodTool("Analysis::NewLikelihoodTool"),
069     m_secVxFinderNameForV0Removal("InDetVKalVxInJetTool"),
070     m_secVxFinderNameForIPSign("InDetVKalVxInJetTool"),
071     m_histoHelper(0),
072     m_calibrationTool("BTagCalibrationBroker")
073 {
074 
075   // declare interface
076   declareInterface<ITagTool>(this);
077   
078   //
079   declareProperty("Runmodus",     m_runModus     = "analysis");
080   //
081   declareProperty("writeInfoPlus", m_writeInfoPlus = false);
082 
083   // Name of the electron input collection
084   declareProperty("originalElCollectionName", 
085                   m_originalElCollectionName = "ElectronAODCollection",
086                   "Name of the electron input collection");
087   // Boolean to use photon collection
088   declareProperty("usePhoton", m_usePhoton = true);
089   // Name of the photon input collection
090   declareProperty("originalPhCollectionName", 
091                   m_originalPhCollectionName = "PhotonAODCollection",
092                   "Name of the photon input collection");
093   // Name of the jet input collection
094   declareProperty("jetCollectionList", m_jetCollectionList,
095                   "Name of the jet input collection");
096   // Name of the track particle container
097   declareProperty("TPContainer",        
098                   m_TPContainerName      = "TrackParticleCandidate",
099                   "Name of the track particle container");
100   // Name of the track particle truth container
101   declareProperty("TPTruthContainer",
102                   m_TPTruthContainerName = "TrackParticleTruthCollection",
103                   "Name of the track particle truth container");
104   // Type of data to analyse in reference mode (B, UDSG, ALL)
105   declareProperty("referenceType",      m_referenceType        = "B",
106                   "Type of data to analyse in reference mode (B, UDSG, ALL)"); 
107   // Distance for purification
108   declareProperty("purificationDeltaR", m_purificationDeltaR   = 0.8,
109                   "Distance for purification");
110   // Distance of isolation to electrons
111   declareProperty("elecIsolDeltaR",     m_elecIsolDeltaR      = 0.7,
112                   "Distance of isolation to electrons");
113   // Cut on minimum pT for jets
114   declareProperty("jetPtMinRef",        m_jetPtMinRef          = 15.*GeV,
115                   "Cut on minimum pT for jets");
116   // Cut on maximum eta for jets
117   declareProperty("jetEtaMaxRef",       m_jetEtaMaxRef         = 2.5,
118                   "Cut on maximum eta for jets");
119 
120   // global configuration:
121   declareProperty("SVForIPTool", m_SVForIPTool);
122   // tools:
123   declareProperty("trackSelectorTool", m_trackSelectorTool);
124   declareProperty("trackToVertexTool", m_trackToVertexTool);
125   // Threshold for high-threshold hits in TRT
126   declareProperty("HTRTThr", m_thrTRT=0.05);
127   declareProperty("LikelihoodTool", m_likelihoodTool);
128   // Tools for calibration
129   declareProperty("calibrationTool",    m_calibrationTool);
130   declareProperty("useForcedCalibration",  m_doForcedCalib   = false);
131   declareProperty("ForcedCalibrationName", m_ForcedCalibName = "Cone4H1Tower");
132   // Boolean to use transverse impact parameter
133   declareProperty("UseTransverseIP", m_useTransverseIP = true,
134                   "Boolean to use transverse impact parameter");
135   // Boolean to have unbiased IP estimator
136   declareProperty("unbiasIPEstimation",m_unbiasIPEstimation,
137                   "Boolean to have unbiased IP estimator");
138   // tool for IP estimator
139   declareProperty("TrackToVertexIPEstimator",m_trackToVertexIPEstimator,
140                   "tool for IP estimator");
141   // Boolean to use cut-based identification of electrons
142   // if not use ratio of likelihood (default)
143   declareProperty("UseCutBased", m_useCutBased = false,
144                   "Boolean to use cut-based identification of electrons - if not use ratio of likelihood (default)");
145   
146   // hypotheses 
147   m_hypotheses.push_back("Sig");
148   m_hypotheses.push_back("Bkg");
149 }
150 
151   
152 SoftElectronTag::~SoftElectronTag()
153 {
154 }
155 
156 // ==================================================
157 StatusCode SoftElectronTag::initialize()
158 {
159   // retrieving ToolSvc: 
160   IToolSvc* toolSvc;
161   StatusCode sc = service("ToolSvc", toolSvc);
162   if (StatusCode::SUCCESS != sc) {
163     ATH_MSG_ERROR(" Can't get ToolSvc");
164     return StatusCode::FAILURE;
165   }
166     
167   // retrieving TrackToVertex: 
168   if (m_runModus == "reference" || m_writeInfoPlus) {
169     if ( m_trackToVertexTool.retrieve().isFailure() ) {
170       ATH_MSG_FATAL("Failed to retrieve tool " << m_trackToVertexTool);
171       return StatusCode::FAILURE;
172     } else {
173       ATH_MSG_DEBUG("Retrieved tool " << m_trackToVertexTool);
174     }
175   } 
176 
177   // retrieving trackToVertexIPEstimator
178   if (m_trackToVertexIPEstimator.retrieve().isFailure() ) {
179     ATH_MSG_FATAL("Failed to retrieve tool " << m_trackToVertexIPEstimator);
180   } else {
181     ATH_MSG_DEBUG("Retrieved tool " << m_trackToVertexIPEstimator);
182   }
183 
184   // creation of TrackSelector: (private instance) 
185   if ( m_trackSelectorTool.retrieve().isFailure() ) {
186     ATH_MSG_FATAL("Failed to retrieve tool " << m_trackSelectorTool);
187     return StatusCode::FAILURE;
188   } else {
189     ATH_MSG_DEBUG("Retrieved tool " << m_trackSelectorTool);
190   }
191   
192   // retrieving calibrationTool
193   if ( m_calibrationTool.retrieve().isFailure() ) {
194     ATH_MSG_FATAL("Failed to retrieve tool " << m_calibrationTool);
195     return StatusCode::FAILURE;
196   } else {
197     ATH_MSG_DEBUG("Retrieved tool " << m_calibrationTool);
198   }
199 
200   // If the jet author is not known (or one wants a calibration not 
201   // corresponding to the author), can force the calibration. 
202   // Check that this calibration has been loaded
203   if (m_doForcedCalib) {
204     if (std::find( m_jetCollectionList.begin(), 
205                    m_jetCollectionList.end(), 
206                    m_ForcedCalibName ) == m_jetCollectionList.end()) {
207       ATH_MSG_ERROR("Error, forced calibration to an unloaded one");
208       return StatusCode::FAILURE;
209     }
210   }
211   
212   // book histograms in reference mode 
213   if (m_runModus == "reference") {
214     sc = InitReferenceMode();
215   }
216   
217   // read in calibration histograms 
218   if( m_runModus == "analysis" ) {
219     sc = InitAnalysisMode();
220     if (sc==StatusCode::FAILURE) return StatusCode::FAILURE;
221   }
222 
223   return StatusCode::SUCCESS;
224 }
225 
226 // ==================================================================
227 StatusCode SoftElectronTag::InitReferenceMode() 
228 {
229   // ===========================================
230   // Booking of histograms in reference mode
231   // ===========================================
232   
233   StatusCode sc = StatusCode::SUCCESS;
234 
235   ITHistSvc* myHistoSvc;
236   if( service( "THistSvc", myHistoSvc ).isSuccess() ) {
237     ATH_MSG_DEBUG("HistoSvc loaded successfully."); 
238     // define Histo Helper
239     m_histoHelper = new HistoHelperRoot(myHistoSvc);
240     // Check for overflows ?
241     m_histoHelper->setCheckOverflows(false);
242     // loop on all Jet collection
243     for(uint ijc=0;ijc<m_jetCollectionList.size();ijc++) {
244       // loop on hypotheses
245       for(uint ih=0;ih<m_hypotheses.size();ih++) {
246         std::string hName = "/RefFileSoftEl"+m_jetCollectionList[ijc]+"/"+
247           m_hypotheses[ih]+"/";
248         
249         m_histoHelper->bookHisto(hName+"d0","|Transverse Impact Parameter|",
250                                  100,0.,1.);
251         m_histoHelper->bookHisto(hName+"pTrel","Electron pT wrt jet axis",
252                                  100,0.,5.);
253         m_histoHelper->bookHisto(hName+"D","Discriminant",
254                                  50,-30.,20.);
255         m_histoHelper->bookHisto(hName+"DpT","Discriminant vs pTrel",
256                                  25,0.,5.,25,-30.,20.);
257       }
258     }
259     m_histoHelper->print();
260   } else {
261     ATH_MSG_ERROR("HistoSvc could NOT bo loaded.");
262   }
263   
264   return sc;
265 }
266 
267 // ==================================================================
268 StatusCode SoftElectronTag::InitAnalysisMode() 
269 {
270   // ===========================================
271   // Retrieve histograms in analysis mode
272   // ===========================================
273 
274   StatusCode sc = StatusCode::SUCCESS;
275    
276   // configure likelihood
277   if ( m_likelihoodTool.retrieve().isFailure() ) {
278     ATH_MSG_FATAL("Failed to retrieve tool " << m_likelihoodTool);
279     return StatusCode::FAILURE;
280   } else {
281     ATH_MSG_DEBUG("Retrieved tool " << m_likelihoodTool);
282   }
283   
284   m_likelihoodTool->defineHypotheses(m_hypotheses);
285   std::string hDir;
286 
287   // loop on hypotheses
288   for(uint ih=0;ih<m_hypotheses.size();ih++) {
289     
290     //hDir="/RefFile"+m_jetCollectionList[ijc]+"/"+m_hypotheses[ih]+"/";
291     hDir=m_hypotheses[ih]+"/";
292     
293     // use of pTrel
294     m_likelihoodTool->defineHistogram(hDir+"pTrel");
295     
296     // use of transverse impact parameter
297     if (m_useTransverseIP) 
298       m_likelihoodTool->defineHistogram(hDir+"d0");
299     
300     // Weight of the likelihood (from electron-id only)
301     //m_likelihoodTool->defineHistogram(hDir+"D");
302     
303     // Weight of the likelihood vs pTrel
304     //m_likelihoodTool->defineHistogram(hDir+"DpT");
305     
306     // }
307   }
308   m_likelihoodTool->printStatus();
309 
310   return sc;
311 }
312 
313 // ==========================================================
314 StatusCode SoftElectronTag::finalize()
315 {
316   return StatusCode::SUCCESS;
317 }
318 
319 // ==========================================================
320 void SoftElectronTag::tagJet(Jet& jetToTag)
321 {
322   // If one wants to add a pointer to the best Electron, needs the container. 
323   // Retrieved for each jet. Does another way to do this exist ? 
324   if(m_writeInfoPlus) {
325     bool ppb = true;
326     StatusCode sc = evtStore()->retrieve(m_originalElCollection, m_originalElCollectionName);
327     
328     if (sc.isFailure()) {
329       ATH_MSG_WARNING("Electron collection " << m_originalElCollectionName 
330                       << " not found");
331     } else {
332       ATH_MSG_VERBOSE("Electron collection " << m_originalElCollectionName 
333                       << " found");
334       ppb = false;
335     }
336     if(ppb) {
337       ATH_MSG_VERBOSE("Not able to persistify electron infos ! Exiting...");
338       return;
339     }
340     
341     // retrieve the photon collection
342     if (m_usePhoton) {
343       sc = evtStore()->retrieve(m_originalPhCollection, m_originalPhCollectionName);
344       if (sc.isFailure()) {
345         ATH_MSG_WARNING("Photon collection " << m_originalPhCollectionName 
346                         << " not found");
347       } else {
348         ATH_MSG_VERBOSE("Photon collection " << m_originalPhCollectionName 
349                         << " found");
350         ppb = false;
351       }
352     }
353   
354     if(ppb) {
355       ATH_MSG_VERBOSE("Not able to persistify photon infos ! Exiting...");
356       return;
357     }
358   }
359 
360   // author to know which jet algorithm: 
361   m_author = jetToTag.jetAuthor();
362   if (m_doForcedCalib) {
363     m_author = m_ForcedCalibName;
364   } else { 
365     //Check that this author is known in the calibration
366     if (std::find( m_jetCollectionList.begin(), 
367                    m_jetCollectionList.end(), 
368                    m_author ) == m_jetCollectionList.end()) {
369       ATH_MSG_DEBUG("Jet Algorithm not found in the standard list"); 
370       ATH_MSG_DEBUG("Trying to find a similar one...");
371       if      (m_author.find("Cone4",0) != std::string::npos) 
372         m_author = "Cone4H1Tower";
373       else if (m_author.find("Cone7",0) != std::string::npos) 
374         m_author = "Cone7H1Tower";
375       else if (m_author.find("Kt4",0)   != std::string::npos) 
376         m_author = "Kt4H1Tower";
377       else if (m_author.find("Kt6",0)   != std::string::npos) 
378         m_author = "Kt6H1Tower";
379       else {
380         ATH_MSG_DEBUG("None found, taking " << m_ForcedCalibName << " calibration");
381         m_author = m_ForcedCalibName;
382       }
383     }
384   }
385   
386   // Create the info class and append it to the Jet 
387   m_softeInfo = 0;
388   m_bestSoftE = 0;
389 
390   // look for the best electron candidate
391   LookForBestElectron(jetToTag);
392   // Return if there are not enough electrons left after preselection
393   if (m_eleCounter<1) {
394     ATH_MSG_VERBOSE("Jet does not contain any good electrons");
395     return;
396   }
397   ATH_MSG_DEBUG(" Max. probability for jet: "  << m_totalproMax);
398   
399   // retrieve information from the best electron
400   RetrieveInfoBestElectron(jetToTag);
401   
402   // run the part of the tagging algorithm done only in analysis mode
403   if (m_runModus == "analysis") 
404     JetTagAnalysisMode(jetToTag);
405 
406   // run the part of the tagging algorithm done only in reference mode
407   if (m_runModus == "reference" && m_bestSoftE) 
408     JetTagReferenceMode(jetToTag);
409   
410   return;
411 }
412 
413 
414 // ======================================================
415 void SoftElectronTag::LookForBestElectron(Jet& jetToTag)
416 {
417   //
418   // Extract the Electrons from the jet and apply preselection on the track.
419   // Ignore other constituents for now
420   //
421 
422   m_eleCounter       = 0;
423   m_bestSoftIsPhoton = false;
424   m_totalproMax      = 0.;
425 
426   // initialisation
427   m_d0wrtPvx    = 0.;
428   m_d0ErrwrtPvx = 0.;
429   m_signOfIP    = 1.;
430   m_ptrel       = 0.;
431   m_Db          = 0.; 
432   m_Du          = 0.;
433 
434   // retrieve the electron associated to the jet
435   UseElectrons(jetToTag);
436 
437   // Is the softE misidentified as a member of photon conversion
438   if (m_usePhoton) UsePhotons(jetToTag);
439 }
440 
441 // ======================================================
442 void SoftElectronTag::UseElectrons(Jet& jetToTag)
443 {
444   //
445   // Extract the Electrons from the jet
446   //
447   
448   // retrieve the electron associated to the jet
449   const ElectronAssociation *ec = jetToTag.getAssociation<ElectronAssociation>("Electrons");
450   if (ec == 0) {
451     ATH_MSG_DEBUG("No electron assocation");
452   } else {
453     // loop on objects
454     for(Navigable<ElectronContainer,double>::object_iter j = ec->begin(); j!= ec->end(); ++j) {
455       const Electron *eTemp = *j;
456       ATH_MSG_DEBUG("eTemp = " << eTemp 
457                     << " author " << eTemp->author() 
458                     << " pt = " << eTemp->pt() 
459                     << " eta = " << eTemp->eta() 
460                     << " phi = " << eTemp->phi());
461       if (eTemp) {
462         // if no track is associated
463         if (!eTemp->trackParticle()) {
464           //ATH_MSG_WARNING("Electron without a track ! This should not exist !");
465         } else {
466           if ( m_preselect(eTemp->trackParticle()) && 
467                eTemp->author(egammaParameters::AuthorSofte)) {
468             m_eleCounter++;
469             ATH_MSG_DEBUG("Looking at " << m_eleCounter 
470                           << " electron, isemse " << eTemp->isemse() 
471                           <<" author "<<eTemp->author());
472             
473             // in case of use of the electron-id based on weights
474             double totalpro = 0.;
475             if (!m_useCutBased) {
476               // combine electron weights + pTrel + d0
477               totalpro = CombineWeights(jetToTag,eTemp,1);
478             } else
479               // in case of use of the cut based selection 
480               if (eTemp->isemse()&&egammaPID::ElectronTight) {
481                 // combine weights of pTrel + d0
482                 totalpro = CombineWeights(jetToTag,eTemp,2);
483               }
484             ATH_MSG_DEBUG(" total prob "<<totalpro);
485             // use by default the ratio of likelihood selection
486             m_totalproVector.push_back(totalpro);
487             if ( totalpro > m_totalproMax ) {
488               m_totalproMax = totalpro;           
489               m_isemse    = eTemp->isemse();
490               m_bestSoftE = eTemp;
491             }
492           }
493         }
494       }
495     }
496   }
497 }
498 
499 // ======================================================
500 void SoftElectronTag::UsePhotons(Jet& jetToTag)
501 {
502   //
503   // Extract the Photons from the jet to use electrons from conversions
504   // or electrons mis-identififed as photons
505   //
506 
507   // retrieve association between photons and jets
508   const PhotonAssociation *ph = jetToTag.getAssociation<PhotonAssociation>("Photons");
509   if (ph == 0) {
510     ATH_MSG_DEBUG("No photon assocation");
511     return;
512   }
513   ATH_MSG_DEBUG("Now looking for photons in the photon container");
514   // loop on photons in jet container
515   for(Navigable<PhotonContainer,double>::object_iter j = ph->begin(); j!= ph->end(); ++j) {
516     const Photon *eTemp = *j;
517     ATH_MSG_DEBUG("eTemp = " << eTemp 
518                   << " author " << eTemp->author() 
519                   << " pt = " << eTemp->pt() 
520                   << " eta = " << eTemp->eta() 
521                   << " phi = " << eTemp->phi() 
522                   << " TrackMatch = " << eTemp->trackParticle());
523     //
524     if (eTemp) {
525       // if no track is associated it cannot be an electron from conversion
526       if (eTemp->trackParticle()) {
527         if ( m_preselect(eTemp->trackParticle()) && 
528              eTemp->author(egammaParameters::AuthorSofte)) {
529           m_eleCounter++;
530           ATH_MSG_DEBUG("Looking at " << m_eleCounter 
531                         << " photon, isemse " << eTemp->isemse() 
532                         <<" author "<<eTemp->author());
533           
534           double totalpro = 0.;
535           // in case of use of the electron-id based on weights
536           if (!m_useCutBased) {
537             // combine electron weights + pTrel + d0
538             totalpro = CombineWeights(jetToTag,eTemp,1);
539           } else
540             // in case of use of the cut based selection 
541             if (eTemp->isemse()&&egammaPID::ElectronTight) {
542               // combine weights of pTrel + d0
543               totalpro = CombineWeights(jetToTag,eTemp,2);
544             }
545           ATH_MSG_DEBUG(" total prob "<<totalpro);
546           // use by default the ratio of likelihood selection
547           m_totalproVector.push_back(totalpro);
548           if ( totalpro > m_totalproMax ) {
549             m_totalproMax = totalpro;             
550             m_isemse    = eTemp->isemse();
551             m_bestSoftE = eTemp;
552             m_bestSoftIsPhoton = true;
553           }
554         }
555       }
556     }
557   }
558 }
559 
560 // ======================================================
561 double SoftElectronTag::CombineWeights(Jet& jetToTag, const egamma *eTemp, int choice)
562 {
563   //
564   // Combine weights filled at electron level + pT rel + d0
565   // eTemp = Electron or Photon
566   // choice = 1 combine all
567   //        = 2 use only pTrel and d0 (no electron weight but use "isem")
568   //
569 
570   double totalpro = 0.;
571 
572   //std::cout << " CombineWeights : " << choice << std::endl;
573 
574   /** jet direction: */
575   Hep3Vector jetDirection(jetToTag.px(),jetToTag.py(),jetToTag.pz());
576   Hep3Vector unit = jetDirection.unit();
577 
578   // weight to be signal from electron pid
579   // NB: SofteElectronWeight is a log10(weight) !
580   double s = eTemp->egammaID(egammaPID::SofteElectronWeight);
581   // weight to be background from electron pid
582   double b = eTemp->egammaID(egammaPID::SofteBgWeight);
583   //std::cout << " s1 = " << s << " b = " << b << std::endl;
584   s = pow(10.,s);
585   b = pow(10.,b);
586   // NB: SofteBgWeight is a log10(weight) !
587   //std::cout << " s = " << s << " b = " << b << std::endl;
588   
589   if ( s+b != 0.) { 
590     // weight to be signal
591     m_Db   = s/(s+b);
592     // weight to be background
593     m_Du   = b/(s+b);
594   } else {
595     ATH_MSG_DEBUG("Info for Soft E : both hypotheses with 0 weight"); 
596   }
597 
598   //std::cout << " m_Db = " << m_Db << " " << m_Du << std::endl;
599   
600   std::vector<Slice> slices;
601   // pT of electron relative to jet axis
602   m_ptrel = eTemp->hlv().perp(jetToTag.hlv().vect());
603   AtomicProperty atom1(m_ptrel/1.e3,"pTrel");
604   std::string compoName(m_author+"#");
605   Composite compo1(compoName+"pTrel");
606   compo1.atoms.push_back(atom1);
607   Slice slice1("SoftEl");
608   slice1.composites.push_back(compo1);
609   
610   //std::cout << " pTrel = " << m_ptrel << std::endl;
611   // transverse impact parameter at perigee
612   /* use new Tool for "unbiased" IP estimation */
613   const Trk::ImpactParametersAndSigma* myIPandSigma(0);
614   if (m_trackToVertexIPEstimator) { 
615     myIPandSigma = m_trackToVertexIPEstimator->estimate(eTemp->trackParticle(),m_priVtx,m_unbiasIPEstimation);
616   }
617   if(0==myIPandSigma) {
618     ATH_MSG_WARNING("SET: trackToVertexIPEstimator failed !");
619   } else {
620     m_d0wrtPvx=myIPandSigma->IPd0;
621     m_d0ErrwrtPvx=myIPandSigma->sigmad0;
622     delete myIPandSigma;
623     myIPandSigma=0;
624   }
625 
626 
627   //std::cout << " m_d0 = " << m_d0wrtPvx << " " << m_d0ErrwrtPvx << std::endl;
628   // sign of the impact parameter 
629   if (m_trackToVertexIPEstimator) { 
630     m_signOfIP=m_trackToVertexIPEstimator->get2DLifetimeSignOfTrack(eTemp->trackParticle()->definingParameters(),unit,m_priVtx->recVertex());
631   }
632   //std::cout << " m_signOfIP = " << m_signOfIP << std::endl;
633   // signed ip and significances 
634   //double sd0             = m_signOfIP*fabs(m_d0wrtPvx);
635   //double sd0significance = m_signOfIP*fabs(m_d0wrtPvx/m_d0ErrwrtPvx);
636   //std::cout << " sd0 = " << sd0 << " " << sd0significance << std::endl;
637   
638   /*m_d0wrtPvx = eTemp->trackParticle()->measuredPerigee()->parameters()[Trk::d0];
639   const Trk::MeasuredPerigee* perigee = m_trackToVertexTool->perigeeAtVertex(*(m_bestSoftE->trackParticle()), m_priVtx->position());
640   if (perigee) {
641     m_d0wrtPvx = perigee->parameters()[Trk::d0];
642     delete perigee;
643     }*/
644   // if transverse impact parameter is used
645   if (m_useTransverseIP) {
646     AtomicProperty atom2(fabs(m_d0wrtPvx),"d0");
647     Composite compo2(compoName+"d0");
648     compo2.atoms.push_back(atom2);
649     slice1.composites.push_back(compo2);
650   }
651   slices.push_back(slice1);
652   // fill the likelihood method
653   m_likelihoodTool->setLhVariableValue(slices);
654   //std::cout << " ici 0" << std::endl;
655   // retrieve the weights
656   //m_Weight[0] = 0.;
657   //m_Weight[1] = 0.;
658   m_Weight = m_likelihoodTool->calculateLikelihood();
659   // add to tmp the weights to be electrons 
660   // only if not use a cut based analysis
661   if (choice==1) {
662     // std::cout << " m_Weight.size() " << m_Weight.size() << std::endl;
663 
664     if (m_Weight.size() >= 2) {
665       m_Weight[0] *= m_Db;
666       m_Weight[1] *= m_Du;
667     }
668   }
669 
670   //std::cout << " m_Weight = " << m_Weight[0] << " " << m_Weight[1] << std::endl;
671   // calculate totalpro as the "electron" hypothesis
672   totalpro = m_Weight[0];
673 
674   //std::cout << " totalpro = " << totalpro << std::endl;
675   return totalpro;
676 }
677 
678 // ======================================================
679 void SoftElectronTag::RetrieveInfoBestElectron(Jet& jetToTag)
680 {
681   //
682   // retrieve information (pTrel,d0,weights) from best electron
683   //  
684   // initialisation
685   m_d0wrtPvx = 0.;
686   m_ptrel    = 0.;
687   m_Db       = 0; 
688   m_Du       = 0;
689 
690   if (m_bestSoftE && (m_runModus == "reference" || m_writeInfoPlus)) {
691     // transverse impact parameter at perigee
692     m_d0wrtPvx = m_bestSoftE->trackParticle()->measuredPerigee()->parameters()[Trk::d0];
693     const Trk::MeasuredPerigee* perigee = m_trackToVertexTool->perigeeAtVertex(*(m_bestSoftE->trackParticle()), m_priVtx->recVertex().position());
694     if (perigee) {
695       m_d0wrtPvx = perigee->parameters()[Trk::d0];
696       delete perigee;
697     }
698     // pT relative to jet axis
699     m_ptrel = m_bestSoftE->hlv().perp(jetToTag.hlv().vect());
700     //
701     double s = m_bestSoftE->egammaID(egammaPID::SofteElectronWeight);
702     double b = m_bestSoftE->egammaID(egammaPID::SofteBgWeight);
703     s = pow(10.,s);
704     b = pow(10.,b);
705     if ( s+b != 0.) { 
706       // weight to be signal
707       m_Db   = s/(s+b);
708       // weight to be background
709       m_Du   = b/(s+b);
710     } else {
711       ATH_MSG_DEBUG("Info for best Soft E : both hypotheses with 0 weight"); 
712     }
713   }
714   ATH_MSG_VERBOSE("Info for bestSoftE " << m_d0wrtPvx 
715                   << " " << m_ptrel << " " << m_Db << " " << m_Du);
716 }
717 
718 // ======================================================
719 void SoftElectronTag::JetTagReferenceMode(Jet& jetToTag)
720 {
721   // ===============================================================
722   // part of the jet tagging algorithm done only in reference mode
723   // ===============================================================
724 
725   // check value of pT and eta of the jet
726   if ( jetToTag.pt()<=m_jetPtMinRef ) return;
727   if ( fabs(jetToTag.eta())>=m_jetEtaMaxRef ) return;
728 
729   ATH_MSG_VERBOSE("A jet " << jetToTag.pt() 
730                   << " " << jetToTag.eta());
731 
732   // check for a truth match
733   const TruthInfo* mcinfo = jetToTag.tagInfo<TruthInfo>("TruthInfo");
734   double deltaRmin(0.);
735   double deltaRminC(0.);
736   std::string label = "N/A";
737   if( mcinfo ) {
738     label = mcinfo->jetTruthLabel();
739     // for purification: require no b or c quark closer than dR=m_purificationDeltaR
740     double deltaRtoClosestB = mcinfo->deltaRMinTo("B");
741     double deltaRtoClosestC = mcinfo->deltaRMinTo("C");
742     deltaRmin = deltaRtoClosestB < deltaRtoClosestC ? deltaRtoClosestB : deltaRtoClosestC;
743     double deltaRtoClosestT = mcinfo->deltaRMinTo("T");
744     deltaRmin = deltaRtoClosestT < deltaRmin ? deltaRtoClosestT : deltaRmin;
745     deltaRminC = deltaRtoClosestB;
746   } else {
747     ATH_MSG_ERROR("No TruthInfo ! Cannot run on reference mode !");
748     return;
749   }
750 
751   //
752   ATH_MSG_VERBOSE("A jet " << label);
753   if ( (    "B"==m_referenceType &&   "B"==label ) ||  // b-jets    
754        ( "UDSG"==m_referenceType && "N/A"==label ) ||  // light jets
755        (  "ALL"==m_referenceType && // all jets: b + purified light jets
756           ( ( "B"==label ) || 
757             ( "N/A"==label && deltaRmin > m_purificationDeltaR ) ||
758             ( "C"==label   && deltaRminC > m_purificationDeltaR ) ) ) ) {
759     ATH_MSG_VERBOSE("Will add to calibration ! for a " << label << " jet");;
760     std::string pref = "N/A";
761     if ("N/A"==label) pref = m_hypotheses[1];
762     if ("B"==label) {
763       const SoftLeptonTruthInfo* sltinfo = 
764         jetToTag.tagInfo<SoftLeptonTruthInfo>("SoftLeptonTruthInfo");
765       if (sltinfo) {
766         ATH_MSG_VERBOSE("SLT info exist "); 
767         int nslt = sltinfo->numSLTrueInfo();
768         bool gotSLT = false;
769         if (nslt > 0) {
770           ATH_MSG_VERBOSE("lepton(s) in the jets :" << nslt);
771           // Get StoreGate to match the bestSoftE and the true lepton... seems complicated !
772           //StoreGateSvc* m_storeGate;
773           //StatusCode sc = service("StoreGateSvc", m_storeGate);
774           //if (sc.isFailure()) {
775           //ATH_MSG_ERROR("StoreGate service not found ! Cannot build calibration");
776           //return;
777           //}
778           const Rec::TrackParticleContainer * tpContainer(0);
779           const TrackParticleTruthCollection* tpTruthColl(0);
780           //sc = m_storeGate->retrieve(tpContainer,m_TPContainerName);
781           StatusCode sc = evtStore()->retrieve(tpContainer,m_TPContainerName);
782           if ( sc.isFailure() ) {
783             ATH_MSG_DEBUG("No TrackParticleCandidate ! Cannot build calibration");
784             return;
785           }
786           //sc = m_storeGate->retrieve(tpTruthColl,m_TPTruthContainerName);
787           sc = evtStore()->retrieve(tpTruthColl,m_TPTruthContainerName);
788           if (sc.isFailure() ) {
789             ATH_MSG_DEBUG("No TrackParticleTruthCollection ! Cannot build calibration");
790             return;
791           }
792           long theBarcode = 0;
793           ElementLink<Rec::TrackParticleContainer> trackPrtlink;
794           trackPrtlink.setElement(const_cast<Rec::TrackParticle*>(m_bestSoftE->trackParticle()));
795           trackPrtlink.setStorableObject(*tpContainer);
796           TrackParticleTruthCollection::const_iterator tempTrackPrtTruthItr = tpTruthColl->find(Rec::TrackParticleTruthKey(trackPrtlink));
797           if (tempTrackPrtTruthItr != tpTruthColl->end()) {
798             const HepMcParticleLink & temHepMcLink = (*tempTrackPrtTruthItr).second.particleLink();
799             if (temHepMcLink.eventIndex()==0) theBarcode=temHepMcLink.barcode();
800             const HepMC::GenParticle * thePart(0);
801             if (theBarcode!=0 && theBarcode<100000) {
802               ATH_MSG_VERBOSE("The barcode of the match for the bestSoftE " << theBarcode);
803               thePart = temHepMcLink.cptr();
804               if (thePart) {
805                 for (int islt = 0; islt < nslt; islt++) {
806                   const SLTrueInfo slt = sltinfo->getSLTrueInfo(islt);
807                   int barc = slt.barcode();
808                   if (barc == theBarcode && abs(slt.pdgId()) == 11) {
809                     if ("B"==label) {
810                       int pdgM = slt.pdgIdMother();
811                       if (  isBMeson(pdgM) || isDMeson(pdgM) || isBBaryon(pdgM) || isDBaryon(pdgM) ) {gotSLT = true; pref = m_hypotheses[0];} 
812                       if ( slt.FromB() && !slt.FromD()) {gotSLT = true; }
813                       if ( slt.FromB() &&  slt.FromD()) {gotSLT = true; } 
814                       if (!slt.FromB() &&  slt.FromD()) {gotSLT = true; } // What is this ??
815                     }
816                     ATH_MSG_VERBOSE("Found a truth match in the SLT info" << slt);
817                   }
818                 }
819               }
820             } else {
821               ATH_MSG_VERBOSE("The barcode of the match for the bestSoftE is too high " << theBarcode);
822             }
823           }
824         }
825         if (!gotSLT) pref = m_hypotheses[1];
826       }
827     }
828     if (pref == m_hypotheses[0] || pref == m_hypotheses[1]) {
829       std::string hDir = "/RefFileSoftEl"+m_author+"/"+pref+"/";
830       m_histoHelper->fillHisto(hDir+"d0",fabs(m_d0wrtPvx));
831       m_histoHelper->fillHisto(hDir+"pTrel",m_ptrel/1.e3);
832       m_histoHelper->fillHisto(hDir+"D",m_totalproMax);
833       m_histoHelper->fillHisto(hDir+"DpT",m_ptrel/1.e3,m_totalproMax);
834     }
835   }
836 }
837 
838 // ======================================================
839 bool SoftElectronTag::IsHardEle(Jet& jetToTag) 
840 {
841 
842   std::vector<Hep3Vector> hardMus;
843   bool hasHardEle(false);
844 
845   const SoftLeptonTruthInfo* sltinfo = jetToTag.tagInfo<SoftLeptonTruthInfo>("SoftLeptonTruthInfo");
846 
847   if (sltinfo) {
848     int nslt = sltinfo->numSLTrueInfo();
849     ATH_MSG_DEBUG("SL truth info exist. Found " << nslt << " true leptons in jet"); 
850     for (int islt = 0; islt < nslt; islt++) {
851       const SLTrueInfo slt = sltinfo->getSLTrueInfo(islt);
852       ATH_MSG_DEBUG("SLT info " << slt.pdgId() 
853                     << " " << slt.momentum().perp() 
854                     << " " << slt.FromB() << " " << slt.FromD() << " " << slt.FromGH());
855       if ( (abs(slt.pdgId()) == 13 || abs(slt.pdgId()) == 11 || abs(slt.pdgId()) == 15) && // Lepton from direct decay of W/Z/H
856           !(slt.FromB()) &&
857           !(slt.FromD()) &&
858       (abs(slt.pdgIdMother())<100) && // not from light hadron decay-in-flight
859           slt.FromGH()
860 
861            //if ( abs(slt.pdgId()) == 11 && // Electron from direct decay of W/Z/H
862            //!(slt.FromB()) &&
863            //!(slt.FromD()) &&
864            //slt.FromGH()
865            ) {
866         Hep3Vector v(slt.momentum());
867         hardMus.push_back(v);
868         double dR = v.deltaR(jetToTag.hlv());
869         ATH_MSG_DEBUG("DR info " 
870                       << v.eta() << " " << jetToTag.eta() << " "
871                       << v.phi() << " " << jetToTag.phi() << " "
872                       << dR);
873         if(dR<m_elecIsolDeltaR) {           
874           hasHardEle = true;
875         }
876       }
877     }
878   }
879   return hasHardEle;
880 }
881 
882 // ======================================================
883 void SoftElectronTag::JetTagAnalysisMode(Jet& jetToTag)
884 {
885   // ===============================================================
886   // part of the jet tagging algorithm done only in analysis mode
887   // ===============================================================
888   
889   std::string instanceName(name());
890   // Create the Info only if there is at least one electron (or photon)
891   if (m_bestSoftE && m_softeInfo == 0) {
892     m_softeInfo = new SoftElectronInfo(instanceName.erase(0,8));
893     jetToTag.addInfo(m_softeInfo);
894     
895     // Store maximum probability as Weight and NTrackProb 
896     // and a vector of probabilities as TrackProb
897     m_softeInfo->setNTrackProb(m_totalproMax);
898     m_softeInfo->setWeight(m_totalproMax);
899     m_softeInfo->setTrackProb(m_totalproVector);
900       
901     // Add the SETrackInfo
902     if (m_writeInfoPlus) {
903       if (m_bestSoftE) {
904         if (!m_bestSoftIsPhoton) {
905           // if best candidate is an electron
906           SETrackInfo tinfo(m_originalElCollection,dynamic_cast<const Electron *>(m_bestSoftE),
907                             m_d0wrtPvx,m_ptrel,m_totalproVector);
908           m_softeInfo->addTrackInfo(tinfo);
909         } else {
910           // if best candidate is a photon
911           SETrackInfo tinfo(m_originalPhCollection,dynamic_cast<const Photon*>(m_bestSoftE),
912                             m_d0wrtPvx,m_ptrel,m_totalproVector);
913           m_softeInfo->addTrackInfo(tinfo);
914         }
915       }
916     }
917   }
918 
919   if (m_bestSoftE) {
920     if(m_softeInfo) m_softeInfo->setTagLikelihood(m_Weight);
921     // Tagging done. Make info object valid, i.e. tag was ok. 
922     // Fill the JetTag and return ... 
923     m_softeInfo->makeValid();
924     
925     ATH_MSG_DEBUG("Weight of the jet (max. probability): " 
926                   <<m_softeInfo->nTrackProb());
927     for (unsigned jj=0; jj< (m_softeInfo->vectorTrackProb()).size(); jj++){
928       ATH_MSG_DEBUG("Probability of track "<<jj<<" "
929                     <<(m_softeInfo->vectorTrackProb())[jj]);
930     }
931   }
932   m_likelihoodTool->clear();
933   m_totalproVector.clear();
934 }
935 
936 // ===================================================
937 void SoftElectronTag::finalizeHistos()
938 {
939 }
940 
941 
942 /* ------------------------------------------------------------------- */
943 /*                        Private Helper Functions                     */
944 /* ------------------------------------------------------------------- */
945 bool SoftElectronTag::m_preselect(const Rec::TrackParticle *t)
946 {
947   // 
948   // performs track selection 
949   // NB: should be similar to what is done in Reconstruction/egamma/egammaRec
950   // softeBuilder.cxx
951   // But some extra-cuts can be applied like on the transverse impact parameter
952   //
953   
954   ATH_MSG_DEBUG("m_preselect(): trkPrt->pt(): " << t->pt());
955   
956   m_trackSelectorTool->primaryVertex(m_priVtx->recVertex().position());
957   m_trackSelectorTool->prepare();
958   // apply track selection
959   if( m_trackSelectorTool->selectTrack(t) ) {
960     // apply further cuts like on TRT high threshold
961     // pseudo-rapidity
962     double eta = fabs(t->measuredPerigee()->eta());
963     // retrieve summary
964     const Trk::TrackSummary* summary = (*t).trackSummary();
965     // fraction of high threshold hits in TRT (with outliers)
966     int nTRThigh          = summary->get(Trk::numberOfTRTHighThresholdHits);
967     int nTRThighOutliers  = summary->get(Trk::numberOfTRTHighThresholdOutliers);
968     int nTRT         = summary->get(Trk::numberOfTRTHits);
969     int nTRTOutliers = summary->get(Trk::numberOfTRTOutliers);
970   //int nTRTTotal = 0;
971     double rTRT = (nTRT+nTRTOutliers) > 0 ? ((double) (nTRThigh+nTRThighOutliers)/(nTRT+nTRTOutliers) ) : 0.;
972     
973     //std::cout << " tTRT = " << rTRT << std::endl;
974     if ((rTRT>m_thrTRT && eta<2.) || eta>=2.) return true;
975   }
976   return false;
977 }
978 
979 // =============================================================
980 bool SoftElectronTag::isBBaryon(const int pID) const 
981 {
982   //
983   // PdgID of B-baryon is of form ...xxx5xxx
984   //
985   std::string idStr = longToStr( abs(pID) );
986   char digit4 = idStr[ idStr.length() - 4 ];
987   if( (digit4=='5') ) 
988     return true;
989   else 
990     return false;
991 }
992 
993 // ============================================================
994 bool SoftElectronTag::isBMeson(const int pID) const 
995 {
996   //
997   // PdgID of B-meson is of form ...xxx05xx
998   //
999   std::string idStr = longToStr( abs(pID) );
1000   char digit3 = idStr[ idStr.length() - 3 ];
1001   char digit4;
1002   if( idStr.length() < 4 ) { digit4 = '0'; }
1003   else { digit4 = idStr[ idStr.length() - 4 ]; };
1004   if( (digit4=='0') && (digit3=='5') ) 
1005     return true;
1006   else 
1007     return false;
1008 }
1009 
1010 // ============================================================
1011 bool SoftElectronTag::isDBaryon(const int pID) const 
1012 {
1013   //
1014   // PdgID of D-baryon is of form ...xxx4xxx
1015   //
1016   std::string idStr = longToStr( abs(pID) );
1017   char digit4 = idStr[ idStr.length() - 4 ];
1018   if( (digit4=='4') ) 
1019     return true;
1020   else 
1021     return false;
1022 }
1023 
1024 // =============================================================
1025 bool SoftElectronTag::isDMeson(const int pID) const 
1026 {
1027   //
1028   // PdgID of D-meson is of form ...xxx04xx
1029   //
1030   std::string idStr = longToStr( abs(pID) );
1031   char digit3 = idStr[ idStr.length() - 3 ];
1032   char digit4;
1033   if( idStr.length() < 4 ) { digit4 = '0'; }
1034   else { digit4 = idStr[ idStr.length() - 4 ]; };
1035   if( (digit4=='0') && (digit3=='4') ) 
1036     return true;
1037   else 
1038     return false;
1039 }
1040 
1041 // ==============================================================
1042 std::string SoftElectronTag::longToStr( const long n ) const 
1043 {
1044   if (0==n) return "0"; 
1045   std::string str = "";
1046   for ( long m = n; m!=0; m/=10 )
1047     str = char( '0' + abs(m%10) ) + str;
1048   if ( n<0 )
1049     str = "-" + str;
1050   return str;
1051 }
1052 
1053 
1054 }

source navigation ] diff markup ] identifier search ] general search ]

Due to the LXR bug, the updates fail sometimes to remove references to deleted files. The Saturday's full rebuilds fix these problems
This page was automatically generated by the LXR engine. Valid HTML 4.01!