27 m_config(nullptr), m_jetAlgo(
""), m_calibAreaTag(
""), m_dev(false)
33 m_config(
config), m_jetAlgo(std::move(jetAlgo)), m_calibAreaTag(std::move(calibAreaTag)), m_dev(dev)
40 if ( !
m_config ) {
ATH_MSG_FATAL(
"Config file not specified. Aborting.");
return StatusCode::FAILURE; }
49 if (
m_jetAlgo.EqualTo(
"") ) {
ATH_MSG_FATAL(
"No jet algorithm specified. Aborting.");
return StatusCode::FAILURE; }
68 JMSFile =
m_config->GetValue(
"MassCalibrationFile",
"empty");
69 if ( JMSFile.EqualTo(
"empty") ) {
71 return StatusCode::FAILURE;
75 JMSFile.Insert(0,
"JetCalibTools/");
82 return StatusCode::FAILURE;
92 while ( TKey *iterobj = (TKey*)ikeys() ) {
93 TString histoName = iterobj->GetName();
105 ATH_MSG_FATAL(
"Vector of mass correction histograms may be empty. Please check your mass calibration file: " << JMSFile);
106 return StatusCode::FAILURE;
110 ATH_MSG_FATAL(
"3D mass correction histogram may be missing. Please check your mass calibration file: " << JMSFile);
111 return StatusCode::FAILURE;
113 else ATH_MSG_INFO(
"JMS Tool has been initialized with binning and eta fit factors from: " <<
fileName);
118 ATH_MSG_INFO(
"Track Assisted Jet Mass will be calibrated");
119 TString JMS_TrackAssisted_File(
m_config->GetValue(
"TrackAssistedMassCalibrationFile",
"empty"));
120 if ( JMS_TrackAssisted_File.EqualTo(
"empty") ) {
121 ATH_MSG_FATAL(
"NO Track Assisted Mass Factors File specified. Aborting.");
122 return StatusCode::FAILURE;
125 JMS_TrackAssisted_File.Remove(0,33);
126 JMS_TrackAssisted_File.Insert(0,
"JetCalibTools/");
130 std::unique_ptr<TFile> inputFile_trkAssisted(TFile::Open(file_trkAssisted_Name));
131 if (!inputFile_trkAssisted){
133 return StatusCode::FAILURE;
137 inputFile_trkAssisted->cd();
138 TList *keys_trkAssisted = inputFile_trkAssisted->GetListOfKeys();
140 TIter ikeys_trkAssisted(keys_trkAssisted);
141 while ( TKey *iterobj = (TKey*)ikeys_trkAssisted() ) {
142 TString histoName = iterobj->GetName();
154 ATH_MSG_FATAL(
"Vector of track assisted mass correction histograms may be empty. Please check your track assisted mass calibration file: " << JMSFile);
155 return StatusCode::FAILURE;
159 ATH_MSG_FATAL(
"3D track assisted mass correction histogram may be missing. Please check your mass calibration file: " << JMSFile);
160 return StatusCode::FAILURE;
162 else ATH_MSG_INFO(
"JMS Tool has been initialized with binning and eta fit factors from: " << file_trkAssisted_Name);
169 TString Combination_File(
m_config->GetValue(
"CombinationFile",
"empty"));
170 if ( Combination_File.EqualTo(
"empty") ) {
172 return StatusCode::FAILURE;
175 Combination_File.Remove(0,33);
176 Combination_File.Insert(0,
"JetCalibTools/");
180 std::unique_ptr<TFile> inputFile_combination(TFile::Open(file_combination_Name));
182 ATH_MSG_FATAL(
"Cannot open Mass Combination file " << file_combination_Name);
183 return StatusCode::FAILURE;
190 TString combObj =
"";
197 return StatusCode::FAILURE;
201 inputFile_combination->cd();
202 TList *keys_combination = inputFile_combination->GetListOfKeys();
204 TIter ikeys_combination(keys_combination);
205 while ( TKey *iterobj = (TKey*)ikeys_combination() ) {
206 TString histoName = iterobj->GetName();
207 if ( histoName.Contains(
"CaloMass") && histoName.Contains(combObj.Data()) )
214 if ( histoName.Contains(
"TAMass") && histoName.Contains(combObj.Data()) )
221 if ( histoName.Contains(
"Correlation") && histoName.Contains(combObj.Data()) )
235 ATH_MSG_FATAL(
"Vector of mass combination histograms with calo factors may be empty. Please check your mass combination file: " << JMSFile);
236 return StatusCode::FAILURE;
239 ATH_MSG_FATAL(
"Vector of mass combination histograms with trk-assisted factors may be empty. Please check your mass combination file: " << JMSFile);
240 return StatusCode::FAILURE;
247 ATH_MSG_FATAL(
"Mass combination 3D histogram with calo factors was not filled. Please check your mass combination file: " << JMSFile);
248 return StatusCode::FAILURE;
252 ATH_MSG_FATAL(
"Mass combination 3D histogram with trk-assisted factors was not filled. Please check your mass combination file: " << JMSFile);
253 return StatusCode::FAILURE;
258 ATH_MSG_INFO(
"JMS Tool has been initialized with mass combination weights from: " << file_combination_Name);
267 TString binParamString =
m_config->GetValue(
"JMSBinningParam",
"");
268 if (binParamString ==
"")
271 ATH_MSG_INFO(
"JMS Tool will use the implied pt_mass_eta binning strategy");
276 if (!binParamString.CompareTo(
"pt_mass_eta",TString::kIgnoreCase))
278 else if (!binParamString.CompareTo(
"e_LOGmOe_eta",TString::kIgnoreCase))
280 else if (!binParamString.CompareTo(
"e_LOGmOet_eta",TString::kIgnoreCase))
282 else if (!binParamString.CompareTo(
"e_LOGmOpt_eta",TString::kIgnoreCase))
284 else if (!binParamString.CompareTo(
"et_LOGmOet_eta",TString::kIgnoreCase))
289 ATH_MSG_FATAL(
"JMSBinningParam was specified, but input was not understood: " << binParamString);
290 return StatusCode::FAILURE;
292 ATH_MSG_INFO(
"JMS Tool will use the " << binParamString <<
" binning strategy");
297 return StatusCode::SUCCESS;
309 if ( pT_uncorr >= pTMax) pT_uncorr = pTMax-1
e-6;
311 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
312 if ( std::isnan(mass_uncorr))
return 1;
313 if ( mass_uncorr >= massMax ) mass_uncorr = massMax-1
e-6;
314 if ( mass_uncorr <= massMin ) mass_uncorr = massMin+1
e-6;
330 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
332 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
333 if ( std::isnan(mass_uncorr))
return 1;
334 if ( mass_uncorr >= massMax ) mass_uncorr = massMax-1
e-6;
335 if ( mass_uncorr <= massMin ) mass_uncorr = massMin+1
e-6;
337 float mass_corr =
m_respFactorsMass[etabin]->Interpolate( pT_uncorr, mass_uncorr );
350 if ( pT_uncorr >= pTMax) pT_uncorr = pTMax-1
e-6;
352 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
353 if ( std::isnan(mass_uncorr))
return 1;
354 if ( mass_uncorr >= massMax ) mass_uncorr = massMax-1
e-6;
355 if ( mass_uncorr <= massMin ) mass_uncorr = massMin+1
e-6;
371 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
373 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
374 if ( std::isnan(
uncorr))
return 1;
392 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
393 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
394 if ( std::isnan(mass_over_pt_uncorr))
return 0;
395 if ( mass_over_pt_uncorr >= mass_over_pTMax ) mass_over_pt_uncorr = mass_over_pTMax-1
e-6;
396 if ( mass_over_pt_uncorr <= mass_over_pTMin ) mass_over_pt_uncorr = mass_over_pTMin+1
e-6;
412 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
413 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
414 if ( std::isnan(mass_over_pt_uncorr))
return 0;
415 if ( mass_over_pt_uncorr >= mass_over_pTMax ) mass_over_pt_uncorr = mass_over_pTMax-1
e-6;
416 if ( mass_over_pt_uncorr <= mass_over_pTMin ) mass_over_pt_uncorr = mass_over_pTMin+1
e-6;
433 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
434 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
435 if ( std::isnan(mass_over_pt_uncorr))
return 0;
436 if ( mass_over_pt_uncorr >= mass_over_pTMax ) mass_over_pt_uncorr = mass_over_pTMax-1
e-6;
437 if ( mass_over_pt_uncorr <= mass_over_pTMin ) mass_over_pt_uncorr = mass_over_pTMin+1
e-6;
453 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
454 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
455 if ( std::isnan(mass_over_pt_uncorr))
return 0;
456 if ( mass_over_pt_uncorr >= mass_over_pTMax ) mass_over_pt_uncorr = mass_over_pTMax-1
e-6;
457 if ( mass_over_pt_uncorr <= mass_over_pTMin ) mass_over_pt_uncorr = mass_over_pTMin+1
e-6;
473 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
474 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
475 if ( std::isnan(mass_over_pt_uncorr))
return 0;
476 if ( mass_over_pt_uncorr >= mass_over_pTMax ) mass_over_pt_uncorr = mass_over_pTMax-1
e-6;
477 if ( mass_over_pt_uncorr <= mass_over_pTMin ) mass_over_pt_uncorr = mass_over_pTMin+1
e-6;
493 if ( pT_uncorr >= pTMax ) pT_uncorr = pTMax-1
e-6 ;
494 if ( pT_uncorr <= pTMin ) pT_uncorr = pTMin+1
e-6;
495 if ( std::isnan(mass_over_pt_uncorr))
return 0;
496 if ( mass_over_pt_uncorr >= mass_over_pTMax ) mass_over_pt_uncorr = mass_over_pTMax-1
e-6;
497 if ( mass_over_pt_uncorr <= mass_over_pTMin ) mass_over_pt_uncorr = mass_over_pTMin+1
e-6;
510 float detectorEta =
jet.getAttribute<
float>(
"DetectorEta");
511 double absdetectorEta = fabs(detectorEta);
515 jetStartP4 =
jet.jetP4();
519 float mass_corr = jetStartP4.mass();
520 double pT_corr = jetStartP4.pt();
522 TLorentzVector caloCalibJet;
529 ATH_MSG_FATAL(
"Please check that the mass correction eta binning is properly set in your config file");
530 return StatusCode::FAILURE;
534 ATH_MSG_FATAL(
"Please check that the mass correction 3D histogram is provided");
535 return StatusCode::FAILURE;
547 ) && jetStartP4.mass() != 0 ) {
554 ATH_MSG_FATAL(
"There was a problem determining the eta bin to use for the mass correction");
555 return StatusCode::FAILURE;
560 double massFactor = 1;
570 if (jetStartP4.mass() / jetStartP4.e() > 0)
581 if (jetStartP4.mass() / jetStartP4.Et() > 0)
592 if (jetStartP4.mass() / jetStartP4.pt() > 0)
603 if (jetStartP4.mass() / jetStartP4.Et() > 0)
614 ATH_MSG_FATAL(
"This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the calo mass was not. Please contact the tool developer(s) to fix this.");
615 return StatusCode::FAILURE;
619 mass_corr = jetStartP4.mass() / massFactor;
620 if (mass_corr > jetStartP4.e()) {
621 mass_corr = jetStartP4.mass();
624 if(!
m_pTfixed) pT_corr = std::sqrt(jetStartP4.e()*jetStartP4.e()-mass_corr*mass_corr)/std::cosh( jetStartP4.eta() );
627 caloCalibJet.SetPtEtaPhiM(pT_corr, jetStartP4.eta(), jetStartP4.phi(), mass_corr);
630 calibP4.SetPxPyPzE( caloCalibJet.Px(), caloCalibJet.Py(), caloCalibJet.Pz(), caloCalibJet.E() );
634 jet.setJetP4( calibP4 );
640 double E_corr = jetStartP4.e();
647 ATH_MSG_FATAL(
"Please check that the mass correction eta binning is properly set in your config file");
653 ATH_MSG_FATAL(
"Please check that the track assisted mass correction 3D histogram is provided");
654 return StatusCode::FAILURE;
658 std::string TrackSumMassStr =
"TrackSumMass";
659 if(
m_jetAlgo==
"AntiKt4EMTopo" ||
m_jetAlgo==
"AntiKt4LCTopo") TrackSumMassStr =
"DFCommonJets_TrackSumMass";
660 std::string TrackSumPtStr =
"TrackSumPt";
661 if(
m_jetAlgo==
"AntiKt4EMTopo" ||
m_jetAlgo==
"AntiKt4LCTopo") TrackSumPtStr =
"DFCommonJets_TrackSumPt";
662 if( !
jet.getAttribute<
float>(TrackSumMassStr,trackSumMass) ) {
665 [[maybe_unused]]
static const bool warnedOnce = [&] {
666 ATH_MSG_WARNING(
"Failed to retrieve TrackSumMass! Track Assisted Mass Correction will NOT be applied");
669 return StatusCode::SUCCESS;
671 ATH_MSG_FATAL(
"Failed to retrieve TrackSumMass! Mass Combination can NOT be performed. Aborting.");
672 return StatusCode::FAILURE;
676 if( !
jet.getAttribute<
float>(TrackSumPtStr,trackSumPt) ) {
679 [[maybe_unused]]
static const bool warnedOnce = [&] {
680 ATH_MSG_WARNING(
"Failed to retrieve TrackSumPt! Track Assisted Mass Correction will NOT be applied");
683 return StatusCode::SUCCESS;
685 ATH_MSG_FATAL(
"Failed to retrieve TrackSumPt! Mass Combination can NOT be performed. Aborting.");
686 return StatusCode::FAILURE;
689 pT_corr = jetStartP4.pt();
691 if(trackSumPt==0)
mTA = 0;
692 else{
mTA = (jetStartP4.pt()/trackSumPt)*trackSumMass;}
693 if(mTA<0 || mTA > jetStartP4.e())
mTA = 0;
698 ) && jetStartP4.mass() != 0 ) {
705 ATH_MSG_FATAL(
"There was a problem determining the eta bin to use for the track assisted mass correction");
706 return StatusCode::FAILURE;
710 double mTAFactor = 1;
723 if (
mTA / jetStartP4.e() > 0)
734 if (
mTA / jetStartP4.Et() > 0)
745 if (
mTA / jetStartP4.pt() > 0)
756 if (
mTA / jetStartP4.Et() > 0)
767 ATH_MSG_FATAL(
"This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the TA mass was not. Please contact the tool developer(s) to fix this.");
768 return StatusCode::FAILURE;
773 if(mTAFactor!=0) mass_corr =
mTA/mTAFactor;
775 ATH_MSG_FATAL(
"The calibration histogram may have a bad filling bin that is causing mTAFactor to be zero. This value should be different from zero in order to take the ratio. Please contact the tool developer to fix this since the calibration histogram may be corrupted. ");
776 return StatusCode::FAILURE;
779 if(!
m_pTfixed) pT_corr = std::sqrt(jetStartP4.e()*jetStartP4.e()-mass_corr*mass_corr)/std::cosh( jetStartP4.eta() );
780 else{E_corr = std::sqrt(jetStartP4.P()*jetStartP4.P()+mass_corr*mass_corr);}
785 if(!
m_pTfixed) pT_corr = jetStartP4.e()/std::cosh( jetStartP4.eta() );
786 else{E_corr = jetStartP4.P();}
789 TLorentzVector TACalibJet;
792 TACalibJet.SetPtEtaPhiM(pT_corr, jetStartP4.eta(), jetStartP4.phi(), mass_corr);
794 TACalibJet_pTfixed.SetPxPyPzE( jetStartP4.Px(), jetStartP4.Py(), jetStartP4.Pz(), E_corr );}
797 jet.setAttribute<
float>(
"JetTrackAssistedMassUnCalibrated",
mTA);
798 jet.setAttribute<
float>(
"JetTrackAssistedMassCalibrated",mass_corr);
799 if(!
m_pTfixed)
jet.setAttribute<
float>(
"JetpTCorrByCalibratedTAMass",pT_corr);
800 else{
jet.setAttribute<
float>(
"JetECorrByCalibratedTAMass",E_corr);}
808 calibP4_calo.SetCoordinates( caloCalibJet.Pt(), jetStartP4.eta(), jetStartP4.phi(), caloCalibJet.M() );
814 calibP4_ta.SetCoordinates( TACalibJet.Pt(), jetStartP4.eta(), jetStartP4.phi(), TACalibJet.M() );
816 calibP4_ta.SetPxPyPzE( TACalibJet_pTfixed.Px(), TACalibJet_pTfixed.Py(), TACalibJet_pTfixed.Pz(), TACalibJet_pTfixed.E() );}
824 float Mass_comb = 0.;
835 calibP4Insitu_calo=jetInsituP4_calo;
837 ATH_MSG_FATAL(
"Cannot retrieve JetInsituScaleMomentumCalo jets" );
838 return StatusCode::FAILURE;
840 TLorentzVector TLVCaloInsituCalib;
841 TLVCaloInsituCalib.SetPtEtaPhiM(calibP4Insitu_calo.pt(), calibP4Insitu_calo.eta(), calibP4Insitu_calo.phi(), calibP4Insitu_calo.mass());
842 mass_calo = TLVCaloInsituCalib.M();
843 pT_calo = TLVCaloInsituCalib.Pt();
844 E_calo = TLVCaloInsituCalib.E();
845 Et_calo = TLVCaloInsituCalib.Et();
850 calibP4Insitu_ta=jetInsituP4_ta;
852 ATH_MSG_FATAL(
"Cannot retrieve JetInsituScaleMomentumTA jets" );
853 return StatusCode::FAILURE;
855 TLorentzVector TLVTAInsituCalib;
856 TLVTAInsituCalib.SetPtEtaPhiM(calibP4Insitu_ta.pt(), calibP4Insitu_ta.eta(), calibP4Insitu_ta.phi(), calibP4Insitu_ta.mass());
857 mass_ta = TLVTAInsituCalib.M();
859 mass_calo = caloCalibJet.M();
860 pT_calo = caloCalibJet.Pt();
861 E_calo = caloCalibJet.E();
862 Et_calo = caloCalibJet.Et();
867 if( (mass_calo==0) || (mass_ta==0) ) {
868 Mass_comb = mass_ta+mass_calo;
876 ATH_MSG_FATAL(
"Please check that the mass combination eta binning is properly set in your config file");
877 return StatusCode::FAILURE;
880 ATH_MSG_FATAL(
"Please check that the mass combination eta binning is properly set in your config file");
881 return StatusCode::FAILURE;
886 ATH_MSG_FATAL(
"Please check that the mass resolution 3D histogram is provided");
887 return StatusCode::FAILURE;
891 ATH_MSG_FATAL(
"Please check that the track assisted mass resolution 3D histogram is provided");
892 return StatusCode::FAILURE;
904 ATH_MSG_FATAL(
"There was a problem determining the eta bin to use for the mass combination");
905 return StatusCode::FAILURE;
996 ATH_MSG_FATAL(
"This should never be reached - if it happens, it's because a new BinningParam enum option was added, but how to handle it for the TA mass was not. Please contact the tool developer(s) to fix this.");
997 return StatusCode::FAILURE;
1003 ATH_MSG_ERROR(
"Encountered division by zero when calculating mass combination weight using correlated weights");
1004 return StatusCode::FAILURE;
1006 const double Weight = ( relTA*relTA -
rho *relCalo*relTA ) / ( relCalo*relCalo + relTA*relTA - 2 *
rho* relCalo * relTA );
1009 if(relCalo == 0 && relTA == 0)
1011 else if(relCalo == 0)
1012 Mass_comb = mass_ta;
1014 Mass_comb = mass_calo;
1016 Mass_comb = ( mass_calo * Weight ) + ( mass_ta * ( 1 - Weight) );
1018 if(Mass_comb>jetStartP4.e()) Mass_comb = mass_calo;
1019 else if(!
m_pTfixed) pT_calo = std::sqrt(jetStartP4.e()*jetStartP4.e()-mass_calo*mass_calo)/std::cosh( jetStartP4.eta() );
1023 TLorentzVector TLVjet;
1024 TLVjet.SetPtEtaPhiM( pT_calo, jetStartP4.eta(), jetStartP4.phi(), Mass_comb );
1025 calibP4.SetPxPyPzE( TLVjet.Px(), TLVjet.Py(), TLVjet.Pz(), TLVjet.E() );
1029 jet.setJetP4( calibP4 );
1033 return StatusCode::SUCCESS;