12 #include "TObjString.h"
17 const TString &jetAlgo,
const TString &calibAreaTag,
const TString & forceCalibFile,
19 const TString &generatorsInfo)
21 m_config(
config), m_jetAlgo(jetAlgo), m_calibAreaTag(calibAreaTag), m_correctionType(correctionType),
22 m_simFlavour(simFlavour), m_mcDSID(mcDSID), m_generatorsInfo(generatorsInfo), m_mcCampaign(
mcCampaign), m_forceCalibFile(forceCalibFile), m_skipCorrection(false), m_correctionFilePath(
"")
27 m_config(nullptr), m_jetAlgo(
""), m_calibAreaTag(
""), m_correctionType(
JET_CORRTYPE::
UNKNOWN),
28 m_simFlavour(
""), m_mcDSID(0), m_generatorsInfo(
""), m_mcCampaign(
""), m_forceCalibFile(
""), m_skipCorrection(true), m_correctionFilePath(
"")
36 ATH_MSG_INFO(
"Initializing Generic4VecCorrection correction tool.");
40 return StatusCode::FAILURE;
44 std::string algo_type, default_OutJetScale;
46 algo_type =
"JPS_PtResidual";
47 default_OutJetScale =
"JetPtResidualScaleMomentum";
53 algo_type =
"JPS_MC2MC";
54 default_OutJetScale =
"JetMC2MCScaleMomentum";
57 ATH_MSG_WARNING(
"No simFlavour metadata available for this sample! Assuming it is MC, but this could cause an error if your sample is not listed in MC2MC_exceptions_DSID.json");
62 ATH_MSG_INFO(
"Will not apply JPS_MC2MC to this Data file.");
64 return StatusCode::SUCCESS;
66 ATH_MSG_WARNING(
"Metadata does not indicate this is MC (assuming data), but ForceCalibFile is set so will apply JPS_MC2MC correction anyway.");
72 algo_type =
"JPS_FastSim";
73 default_OutJetScale =
"JetFastSimScaleMomentum";
75 bool isAF3 = TString(
m_simFlavour).Contains(
"ATLFAST3",TString::kIgnoreCase);
78 ATH_MSG_INFO(
"Will not apply JPS_FastSim to this Data or FullSim file.");
80 return StatusCode::SUCCESS;
82 ATH_MSG_WARNING(
"ForceCalibFile is set for a data or FullSim file, will apply JPS_FastSim correction anyway.");
88 ATH_MSG_FATAL(
"Generic4VecCorrection is incorrectly configured. Aborting.");
89 return StatusCode::FAILURE;
100 return StatusCode::SUCCESS;
107 const float minX = h_correction_2D->GetXaxis()->GetBinLowEdge(1);
108 const float maxX = h_correction_2D->GetXaxis()->GetBinLowEdge(h_correction_2D->GetNbinsX()+1);
109 const float minY = h_correction_2D->GetYaxis()->GetBinLowEdge(1);
110 const float maxY = h_correction_2D->GetYaxis()->GetBinLowEdge(h_correction_2D->GetNbinsY()+1);
113 else if (
x <= minX )
117 else if (
y <= minY )
121 correctionFactor = h_correction_2D->Interpolate(
x,
y);
123 return StatusCode::SUCCESS;
133 return StatusCode::SUCCESS;
137 calibP4 =
jet.jetP4();
141 float correctionFactor = 1.0;
143 TH2* h_correction_2D =
nullptr;
144 float this_pt, this_eta;
146 this_pt =
jet.pt()/1000.;
148 this_eta = DetectorEtaAcc(
jet);
156 this_pt =
jet.pt()/1000.;
157 this_eta = fabs(
jet.rapidity());
160 this_pt =
jet.pt()/1000.;
161 this_eta = fabs(
jet.rapidity());
165 return StatusCode::SUCCESS;
166 int jet_PID = abs(PartonTruthLabelIDAcc(
jet));
171 h_correction_2D = correction_from_map->second;
175 if (h_correction_2D){
179 calibP4 *= correctionFactor;
181 jet.setJetP4(calibP4);
183 return StatusCode::SUCCESS;
188 std::string algo_type, calibFilePrepend, corrHistName;
190 algo_type =
"JPS_PtResidual";
191 calibFilePrepend =
"PtResidual";
192 corrHistName =
"h_respMap_recoPt_DetEta";
194 algo_type =
"JPS_FastSim";
195 calibFilePrepend =
"AF3";
196 corrHistName =
"h_respMap_recoPt_recoY";
208 TString CalibFileTag =
m_config->GetValue( (algo_type+
".CalibFileTag").c_str(),
"");
210 ATH_MSG_FATAL(
"At least one of the required parameters is not set, please check m_mcCampaign (" <<
m_mcCampaign <<
"), m_jetAlgo (" <<
m_jetAlgo <<
"), and " << algo_type <<
".CalibFileTag (" << CalibFileTag <<
")");
211 return StatusCode::FAILURE;
218 ATH_MSG_FATAL(
"PathResolverFindCalibFile cannot find path to " << CalibFile);
219 return StatusCode::FAILURE;
223 ATH_MSG_FATAL(
"Cannot open " << algo_type <<
"'s CalibFile, even though the m_correctionFilePath exists: " << CalibFile);
224 return StatusCode::FAILURE;
229 ATH_MSG_FATAL(
"Failed to retrieve histogram: " << corrHistName);
230 return StatusCode::FAILURE;
235 return StatusCode::SUCCESS;
241 std::ifstream json_stream(full_path);
242 if( json_stream.peek() == std::ifstream::traits_type::eof() )
243 return StatusCode::FAILURE;
245 json_stream >> json_object;
246 return StatusCode::SUCCESS;
258 TString MC2MC_CalibFile;
264 TObjArray *CalibFile_fields = MC2MC_CalibFile.Tokenize(
"_");
265 float n_fields = CalibFile_fields->GetEntries();
266 std::string new_showerModel = ((TObjString *)(CalibFile_fields->At(n_fields-1)))->String().Data();
267 new_showerModel.resize(new_showerModel.find(
".root"));
268 showerModel = new_showerModel;
272 TString MC2MC_CalibFileTag =
m_config->GetValue(
"JPS_MC2MC.CalibFileTag",
"");
274 ATH_MSG_FATAL(
"At least one of the required parameters is not set, please check m_mcCampaign (" <<
m_mcCampaign <<
"), m_jetAlgo (" <<
m_jetAlgo <<
"), JPS_MC2MC.CalibFileTag (" << MC2MC_CalibFileTag <<
"), and showerModel (" << showerModel <<
")");
275 return StatusCode::FAILURE;
280 if (showerModel(0,6) ==
"Pythia" || showerModel(0,4) ==
"None"){
282 ATH_MSG_INFO(
"Will not perform MC2MC correction for this sample (Pythia or forced to None), but will write out the redundant jet scale " <<
m_outJetScale.Data());
283 return StatusCode::SUCCESS;
287 ATH_MSG_FATAL(
"PathResolverFindCalibFile cannot find path to MC2MC CalibFile: " << MC2MC_CalibFile);
288 return StatusCode::FAILURE;
292 ATH_MSG_FATAL(
"Cannot open MC2MC CalibFile, even though the m_correctionFilePath exists: " << MC2MC_CalibFile);
293 return StatusCode::FAILURE;
296 std::vector<int> considered_PIDs = {1,2,3,21};
297 bool doCjetCorrection =
m_config->GetValue(
"JPS_MC2MC.doCjetCorrection",
true);
299 considered_PIDs.push_back(4);
300 bool doBjetCorrection =
m_config->GetValue(
"JPS_MC2MC.doBjetCorrection",
true);
302 considered_PIDs.push_back(5);
305 for (
auto this_PID : considered_PIDs){
306 TString this_hist_name;
307 if(this_PID == 1 || this_PID == 2 || this_PID == 3){
308 this_hist_name =
"h_respMap_recoPt_recoY_q";
309 }
else if(this_PID == 4){
310 this_hist_name =
"h_respMap_recoPt_recoY_c";
311 }
else if(this_PID == 5){
312 this_hist_name =
"h_respMap_recoPt_recoY_b";
313 }
else if(this_PID == 21){
314 this_hist_name =
"h_respMap_recoPt_recoY_g";
316 ATH_MSG_FATAL(
"Requested PID " << this_PID <<
" is not supported for MC2MC correction, please contact JetETMiss.");
317 return StatusCode::FAILURE;
319 TH2* this_hist = (TH2*)
inputFile->Get(this_hist_name);
321 ATH_MSG_FATAL(
"Failed to retrieve histogram: " << this_hist_name);
322 return StatusCode::FAILURE;
324 this_hist->SetName( (
"h_respMap_recoPt_recoY_"+
std::to_string(this_PID)).c_str() );
325 this_hist->SetDirectory(0);
330 return StatusCode::SUCCESS;
339 ATH_CHECK(
load_json(MC2MC_exceptions_DSID,
"JetCalibTools/MC2MC_exceptions_DSID.json") );
342 ATH_MSG_INFO(
"Sample DSID " << mcDSID <<
" is in the MC2MC_exceptions_DSID list, will be forcing the showerModel " << showerModel);
343 return StatusCode::SUCCESS;
346 if(generatorsInfo ==
""){
348 ATH_MSG_DEBUG(
"No generatorsInfo string provided, cannot parse showerModel.");
349 return StatusCode::SUCCESS;
353 TObjArray *generatorsInfo_fields = generatorsInfo.Tokenize(
"+");
354 float n_fields = generatorsInfo_fields->GetEntries();
355 std::string this_substr = ((TObjString *)(generatorsInfo_fields->At(n_fields-1)))->String().Data();
358 while( n_fields > 0 &&
359 (this_substr.starts_with(
"EvtGen") ||
360 this_substr.starts_with(
"Photos") ||
361 this_substr.starts_with(
"Tauola") ) ) {
362 generatorsInfo_fields->RemoveAt(n_fields-1);
365 if ( n_fields == 0 ){
366 ATH_MSG_FATAL(
"No valid PS/Had model found in generatorsInfo string: " << generatorsInfo);
367 return StatusCode::FAILURE;
370 this_substr = ((TObjString *)(generatorsInfo_fields->At(n_fields-1)))->String().Data();
372 std::string full_pshadInfo = this_substr;
375 std::string genType =
"";
376 std::string psType =
"";
377 std::string hadType =
"";
379 if (this_substr.starts_with(
"Herwigpp")){
380 genType =
"Herwigpp";
383 }
else if (this_substr.starts_with(
"Herwig")){
387 }
else if (this_substr.starts_with(
"Sherpa")){
391 }
else if (this_substr.starts_with(
"Pythia8B")){
396 }
else if (this_substr.starts_with(
"Pythia")){
401 ATH_MSG_FATAL(
"No valid generator type found in generatorsInfo string: " << generatorsInfo);
402 return StatusCode::FAILURE;
406 this_substr = this_substr.substr(this_substr.find(
"(v.") + 3);
407 if( full_pshadInfo.starts_with(
"Pythia8") && !this_substr.starts_with(
"8")){
412 std::vector<std::string> version_exceptions = {
"alpha",
"p",
"bbb",
"atlas",
"beta",
")"};
413 for (
const auto&
exception : version_exceptions) {
414 if (this_substr.find(
exception) != std::string::npos) {
415 this_substr.resize(this_substr.find(
exception));
420 this_substr.erase(
std::remove(this_substr.begin(), this_substr.end(),
'.'), this_substr.end());
426 showerModel = genType+
"-"+
version+
"-"+psType+
"-"+hadType;
433 if( MC2MC_showerRemap.contains( genType+
"-"+
version+
"-"+psType+
"-"+hadType ) ){
434 std::string replaced_showerModel = MC2MC_showerRemap[ genType+
"-"+
version+
"-"+psType+
"-"+hadType ];
435 ATH_MSG_INFO(
"Sample with identified showerModel " << genType+
"-"+
version+
"-"+psType+
"-"+hadType <<
" is in the MC2MC_showerRemap list, will be forcing the showerModel " << replaced_showerModel);
436 showerModel = replaced_showerModel;
437 }
else if (MC2MC_showerRemap.contains( genType+
"-"+
version ) ){
438 std::string replaced_showerModel = MC2MC_showerRemap[ genType+
"-"+
version ];
439 replaced_showerModel +=
"-"+psType+
"-"+hadType;
440 ATH_MSG_INFO(
"Sample with identified showerModel " << genType+
"-"+
version+
"-"+psType+
"-"+hadType <<
" is in the MC2MC_showerRemap list, will be forcing the showerModel " << replaced_showerModel);
441 showerModel = replaced_showerModel;
444 return StatusCode::SUCCESS;