From 7ad663d3136b9dfaae318df5ede77401a9d4507c Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Wed, 26 Nov 2025 18:37:19 +0100 Subject: [PATCH 1/2] PWGEM/Dilepton: update norm001 table after #13971 --- PWGEM/Dilepton/Core/Dilepton.h | 7 +- PWGEM/Dilepton/Core/DileptonProducer.h | 6 +- PWGEM/Dilepton/DataModel/dileptonTables.h | 25 +++-- .../Converters/eventNormConverter1.cxx | 4 +- .../TableProducer/createEMEventDilepton.cxx | 16 ++- PWGEM/Dilepton/Tasks/dileptonPolarization.cxx | 97 ++++++++++--------- .../TableProducer/createEMEventPhoton.cxx | 14 ++- 7 files changed, 93 insertions(+), 76 deletions(-) diff --git a/PWGEM/Dilepton/Core/Dilepton.h b/PWGEM/Dilepton/Core/Dilepton.h index eada64f19ac..43ca4f026bc 100644 --- a/PWGEM/Dilepton/Core/Dilepton.h +++ b/PWGEM/Dilepton/Core/Dilepton.h @@ -514,6 +514,7 @@ struct Dilepton { if (doprocessNorm) { fRegistry.addClone("Event/before/hCollisionCounter", "Event/norm/hCollisionCounter"); + fRegistry.add("Event/norm/hZvtx", "hZvtx;Z_{vtx} (cm)", kTH1D, {{100, -50, +50}}, false); } if (doprocessTriggerAnalysis) { LOGF(info, "Trigger analysis is enabled. Desired trigger name = %s", cfg_swt_name.value.data()); @@ -1892,15 +1893,13 @@ struct Dilepton { } PROCESS_SWITCH(Dilepton, processTriggerAnalysis, "run dilepton analysis on triggered data", false); - Filter collisionFilter_centrality_norm = cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax; - using FilteredNormInfos = soa::Filtered; - - void processNorm(FilteredNormInfos const& collisions) + void processNorm(aod::EMEventNormInfos const& collisions) { for (const auto& collision : collisions) { if (collision.centFT0C() < cfgCentMin || cfgCentMax < collision.centFT0C()) { continue; } + fRegistry.fill(HIST("Event/norm/hZvtx"), collision.posZ()); fRegistry.fill(HIST("Event/norm/hCollisionCounter"), 1.0); if (collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { diff --git a/PWGEM/Dilepton/Core/DileptonProducer.h b/PWGEM/Dilepton/Core/DileptonProducer.h index d1492949a1b..b7150c1f275 100644 --- a/PWGEM/Dilepton/Core/DileptonProducer.h +++ b/PWGEM/Dilepton/Core/DileptonProducer.h @@ -758,16 +758,14 @@ struct DileptonProducer { } PROCESS_SWITCH(DileptonProducer, processAnalysis, "run dilepton analysis", true); - Filter collisionFilter_centrality_norm = cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax; - using FilteredNormInfos = soa::Filtered; - void processNorm(FilteredNormInfos const& collisions) + void processNorm(aod::EMEventNormInfos const& collisions) { for (const auto& collision : collisions) { if (collision.centFT0C() < cfgCentMin || cfgCentMax < collision.centFT0C()) { continue; } - normTable(collision.selection_raw(), collision.rct_raw(), collision.posZ(), collision.centFT0C()); + normTable(collision.selection_raw(), collision.rct_raw(), collision.posZint16(), collision.centFT0Cuint16()); } // end of collision loop } diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index 4132e765874..03cd152c68f 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -128,13 +128,15 @@ DECLARE_SOA_COLUMN(Q4yBTot, q4ybtot, float); //! DECLARE_SOA_COLUMN(SpherocityPtWeighted, spherocity_ptweighted, float); //! transverse spherocity DECLARE_SOA_COLUMN(SpherocityPtUnWeighted, spherocity_ptunweighted, float); //! transverse spherocity DECLARE_SOA_COLUMN(NtrackSpherocity, ntspherocity, int); -DECLARE_SOA_COLUMN(IsSelected, isSelected, bool); //! MB event selection info -DECLARE_SOA_COLUMN(IsEoI, isEoI, bool); //! lepton or photon exists in MB event (not for CEFP) -DECLARE_SOA_COLUMN(PosX, posX, float); //! only for treeCreatetorML.cxx -DECLARE_SOA_COLUMN(PosY, posY, float); //! only for treeCreatetorML.cxx -DECLARE_SOA_COLUMN(PosZint16, posZint16, int16_t); //! this is only to reduce data size -DECLARE_SOA_DYNAMIC_COLUMN(PosZ, posZ, [](int16_t posZint16) -> float { return static_cast(posZint16) * 0.1f; }); - +DECLARE_SOA_COLUMN(IsSelected, isSelected, bool); //! MB event selection info +DECLARE_SOA_COLUMN(IsEoI, isEoI, bool); //! lepton or photon exists in MB event (not for CEFP) +DECLARE_SOA_COLUMN(PosX, posX, float); //! only for treeCreatetorML.cxx +DECLARE_SOA_COLUMN(PosY, posY, float); //! only for treeCreatetorML.cxx +DECLARE_SOA_COLUMN(PosZint16, posZint16, int16_t); //! this is only to reduce data size +DECLARE_SOA_COLUMN(CentFT0Cuint16, centFT0Cuint16, uint16_t); //! this is only to reduce data size + +DECLARE_SOA_DYNAMIC_COLUMN(PosZ, posZ, [](int16_t posZint16) -> float { return (posZint16 < 0 ? std::nextafter(posZint16 * 0.01f, -std::numeric_limits::infinity()) : std::nextafter(posZint16 * 0.01f, std::numeric_limits::infinity())); }); //! poZ is multiplied by 100 in createEMEventDileton.cxx +DECLARE_SOA_DYNAMIC_COLUMN(CentFT0C, centFT0C, [](uint16_t centuint16) -> float { return std::nextafter(centuint16 * 0.002f, std::numeric_limits::infinity()); }); //! centrality is multiplied by 500 in createEMEventDilepton.cxx DECLARE_SOA_DYNAMIC_COLUMN(Sel8, sel8, [](uint64_t selection_bit) -> bool { return (selection_bit & BIT(o2::aod::evsel::kIsTriggerTVX)) && (selection_bit & BIT(o2::aod::evsel::kNoTimeFrameBorder)) && (selection_bit & BIT(o2::aod::evsel::kNoITSROFrameBorder)); }); DECLARE_SOA_DYNAMIC_COLUMN(EP2FT0M, ep2ft0m, [](float q2x, float q2y) -> float { return std::atan2(q2y, q2x) / 2.0; }); DECLARE_SOA_DYNAMIC_COLUMN(EP2FT0A, ep2ft0a, [](float q2x, float q2y) -> float { return std::atan2(q2y, q2x) / 2.0; }); @@ -295,7 +297,8 @@ DECLARE_SOA_TABLE_VERSIONED(EMEventNormInfos_000, "AOD", "EMEVENTNORMINFO", 0, / o2::soa::Index<>, evsel::Alias, evsel::Selection, evsel::Rct, emevent::PosZint16, cent::CentFT0C, emevent::PosZ, emevent::Sel8); DECLARE_SOA_TABLE_VERSIONED(EMEventNormInfos_001, "AOD", "EMEVENTNORMINFO", 1, //! event information for normalization - o2::soa::Index<>, evsel::Selection, evsel::Rct, collision::PosZ, cent::CentFT0C, emevent::Sel8); + o2::soa::Index<>, evsel::Selection, evsel::Rct, emevent::PosZint16, emevent::CentFT0Cuint16, + emevent::Sel8, emevent::PosZ, emevent::CentFT0C, o2::soa::Marker<1>); using EMEventNormInfos = EMEventNormInfos_001; using EMEventNormInfo = EMEventNormInfos::iterator; @@ -950,8 +953,10 @@ DECLARE_SOA_TABLE_VERSIONED(EMThinEvents_000, "AOD", "EMTHINEVENT", 0, //! Thin using EMThinEvents = EMThinEvents_000; using EMThinEvent = EMThinEvents::iterator; -DECLARE_SOA_TABLE(EMThinEventNormInfos, "AOD", "EMTHINEVENTNORM", //! event information for normalization - o2::soa::Index<>, evsel::Selection, evsel::Rct, collision::PosZ, cent::CentFT0C, emevent::Sel8, o2::soa::Marker<2>); +DECLARE_SOA_TABLE_VERSIONED(EMThinEventNormInfos_000, "AOD", "EMTHINEVENTNORM", 0, //! event information for normalization + o2::soa::Index<>, evsel::Selection, evsel::Rct, emevent::PosZint16, emevent::CentFT0Cuint16, + emevent::Sel8, emevent::PosZ, emevent::CentFT0C, o2::soa::Marker<2>); +using EMThinEventNormInfos = EMThinEventNormInfos_000; using EMThinEventNormInfo = EMThinEventNormInfos::iterator; namespace emdilepton diff --git a/PWGEM/Dilepton/TableProducer/Converters/eventNormConverter1.cxx b/PWGEM/Dilepton/TableProducer/Converters/eventNormConverter1.cxx index 634c0733d74..1d3bda9b55d 100644 --- a/PWGEM/Dilepton/TableProducer/Converters/eventNormConverter1.cxx +++ b/PWGEM/Dilepton/TableProducer/Converters/eventNormConverter1.cxx @@ -35,8 +35,8 @@ struct eventNormConverter1 { event_001( collision.selection_raw(), collision.rct_raw(), - collision.posZ(), - collision.centFT0C()); + static_cast(collision.posZ() * 100.f), + static_cast(collision.centFT0C() * 500.f)); } // end of collision loop } }; diff --git a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx index f658d14fb1d..299543874d8 100644 --- a/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx +++ b/PWGEM/Dilepton/TableProducer/createEMEventDilepton.cxx @@ -106,8 +106,6 @@ struct CreateEMEventDilepton { { for (const auto& bc : bcs) { if (bc.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { - // const auto& collisions_perBC = collisions.sliceBy(perBC, bc.globalIndex()); - // embc(bc.selection_bit(o2::aod::evsel::kIsTriggerTVX), bc.selection_bit(o2::aod::evsel::kNoTimeFrameBorder), bc.selection_bit(o2::aod::evsel::kNoITSROFrameBorder), static_cast(collisions_perBC.size() > 0)); // TVX is fired. embc(bc.selection_raw(), bc.rct_raw()); // TVX is fired. } } // end of bc loop @@ -123,12 +121,20 @@ struct CreateEMEventDilepton { auto bc = collision.template foundBC_as(); if (collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + int16_t posZint16 = static_cast(collision.posZ() * 100.f); + if (posZint16 == 0) { + if (collision.posZ() < 0.f) { + posZint16 = -1; + } else { + posZint16 = +1; + } + } if constexpr (eventtype == EMEventType::kEvent) { - event_norm_info(collision.selection_raw(), collision.rct_raw(), collision.posZ(), 105.f); + event_norm_info(collision.selection_raw(), collision.rct_raw(), posZint16, static_cast(105.f * 500.f)); } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec) { - event_norm_info(collision.selection_raw(), collision.rct_raw(), collision.posZ(), collision.centFT0C()); + event_norm_info(collision.selection_raw(), collision.rct_raw(), posZint16, static_cast(collision.centFT0C() * 500.f)); } else { - event_norm_info(collision.selection_raw(), collision.rct_raw(), collision.posZ(), 105.f); + event_norm_info(collision.selection_raw(), collision.rct_raw(), posZint16, static_cast(105.f * 500.f)); } } diff --git a/PWGEM/Dilepton/Tasks/dileptonPolarization.cxx b/PWGEM/Dilepton/Tasks/dileptonPolarization.cxx index 3e6da01168b..5961f229c00 100644 --- a/PWGEM/Dilepton/Tasks/dileptonPolarization.cxx +++ b/PWGEM/Dilepton/Tasks/dileptonPolarization.cxx @@ -18,7 +18,7 @@ #include "PWGEM/Dilepton/Utils/EMFwdTrack.h" #include "PWGEM/Dilepton/Utils/EMTrack.h" #include "PWGEM/Dilepton/Utils/EMTrackUtilities.h" -#include "PWGEM/Dilepton/Utils/EventHistograms.h" +// #include "PWGEM/Dilepton/Utils/EventHistograms.h" #include "PWGEM/Dilepton/Utils/EventMixingHandler.h" #include "PWGEM/Dilepton/Utils/PairUtilities.h" @@ -26,10 +26,10 @@ #include "CommonConstants/LHCConstants.h" #include "DataFormatsParameters/GRPECSObject.h" #include "DataFormatsParameters/GRPLHCIFData.h" -#include "DataFormatsParameters/GRPMagField.h" -#include "DataFormatsParameters/GRPObject.h" -#include "DetectorsBase/GeometryManager.h" -#include "DetectorsBase/Propagator.h" +// #include "DataFormatsParameters/GRPMagField.h" +// #include "DataFormatsParameters/GRPObject.h" +// #include "DetectorsBase/GeometryManager.h" +// #include "DetectorsBase/Propagator.h" #include "Framework/ASoAHelpers.h" #include "Framework/AnalysisTask.h" #include "Framework/runDataProcessing.h" @@ -64,19 +64,19 @@ using MyEMH_pair = o2::aod::pwgem::dilepton::utils::EventMixingHandler ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"}; - Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; - Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; - Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; - Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; + // Configurable grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"}; + // Configurable grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"}; + // Configurable skipGRPOquery{"skipGRPOquery", true, "skip grpo query"}; + // Configurable d_bz_input{"d_bz_input", -999, "bz field in kG, -999 is automatic"}; - Configurable cfgPairType{"cfgPairType", 0, "0:dielectron:0, 1:dimuon"}; + Configurable cfgPairType{"cfgPairType", 0, "0:dielectron, 1:dimuon"}; Configurable cfgOccupancyEstimator{"cfgOccupancyEstimator", 0, "FT0C:0, Track:1"}; Configurable cfgDoMix{"cfgDoMix", true, "flag for event mixing"}; - Configurable ndepth{"ndepth", 100, "depth for event mixing"}; + Configurable ndepth{"ndepth", 1000, "depth for event mixing"}; Configurable ndiff_bc_mix{"ndiff_bc_mix", 594, "difference in global BC required in mixed events"}; ConfigurableAxis ConfVtxBins{"ConfVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; - ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; - ConfigurableAxis ConfEPBins{"ConfEPBins", {16, -M_PI / 2, +M_PI / 2}, "Mixing bins - event plane angle"}; + ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.f, 999.f}, "Mixing bins - centrality"}; + ConfigurableAxis ConfEPBins{"ConfEPBins", {1, -M_PI / 2, +M_PI / 2}, "Mixing bins - event plane angle"}; ConfigurableAxis ConfOccupancyBins{"ConfOccupancyBins", {VARIABLE_WIDTH, -1, 1e+10}, "Mixing bins - occupancy"}; Configurable cfgPolarizationFrame{"cfgPolarizationFrame", 0, "frame of polarization. 0:CS, 1:HX, else:FATAL"}; @@ -134,7 +134,7 @@ struct DileptonPolarization { Service ccdb; int mRunNumber; - float d_bz; + // float d_bz; HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false}; // static constexpr std::string_view event_cut_types[2] = {"before/", "after/"}; @@ -163,7 +163,7 @@ struct DileptonPolarization { void init(InitContext& /*context*/) { mRunNumber = 0; - d_bz = 0; + // d_bz = 0; ccdb->setURL(ccdburl); ccdb->setCaching(true); @@ -334,39 +334,38 @@ struct DileptonPolarization { return; } - // In case override, don't proceed, please - no CCDB access required - if (d_bz_input > -990) { - d_bz = d_bz_input; - o2::parameters::GRPMagField grpmag; - if (std::fabs(d_bz) > 1e-5) { - grpmag.setL3Current(30000.f / (d_bz / 5.0f)); - } - o2::base::Propagator::initFieldFromGRP(&grpmag); - mRunNumber = collision.runNumber(); - return; - } - - auto run3grp_timestamp = collision.timestamp(); - o2::parameters::GRPObject* grpo = 0x0; - o2::parameters::GRPMagField* grpmag = 0x0; - if (!skipGRPOquery) - grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); - if (grpo) { - o2::base::Propagator::initFieldFromGRP(grpo); - // Fetch magnetic field from ccdb for current collision - d_bz = grpo->getNominalL3Field(); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; - } else { - grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); - if (!grpmag) { - LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; - } - o2::base::Propagator::initFieldFromGRP(grpmag); - // Fetch magnetic field from ccdb for current collision - d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); - LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; - } - mRunNumber = collision.runNumber(); + // // In case override, don't proceed, please - no CCDB access required + // if (d_bz_input > -990) { + // d_bz = d_bz_input; + // o2::parameters::GRPMagField grpmag; + // if (std::fabs(d_bz) > 1e-5) { + // grpmag.setL3Current(30000.f / (d_bz / 5.0f)); + // } + // o2::base::Propagator::initFieldFromGRP(&grpmag); + // mRunNumber = collision.runNumber(); + // return; + // } + + // auto run3grp_timestamp = collision.timestamp(); + // o2::parameters::GRPObject* grpo = 0x0; + // o2::parameters::GRPMagField* grpmag = 0x0; + // if (!skipGRPOquery) + // grpo = ccdb->getForTimeStamp(grpPath, run3grp_timestamp); + // if (grpo) { + // o2::base::Propagator::initFieldFromGRP(grpo); + // // Fetch magnetic field from ccdb for current collision + // d_bz = grpo->getNominalL3Field(); + // LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; + // } else { + // grpmag = ccdb->getForTimeStamp(grpmagPath, run3grp_timestamp); + // if (!grpmag) { + // LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp; + // } + // o2::base::Propagator::initFieldFromGRP(grpmag); + // // Fetch magnetic field from ccdb for current collision + // d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f); + // LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kG"; + // } auto grplhcif = ccdb->getForTimeStamp("GLO/Config/GRPLHCIF", collision.timestamp()); int beamZ1 = grplhcif->getBeamZ(o2::constants::lhc::BeamC); @@ -380,6 +379,8 @@ struct DileptonPolarization { beamP1 = std::sqrt(std::pow(beamE1, 2) - std::pow(beamM1, 2)); beamP2 = std::sqrt(std::pow(beamE2, 2) - std::pow(beamM2, 2)); LOGF(info, "beamZ1 = %d, beamZ2 = %d, beamA1 = %d, beamA2 = %d, beamE1 = %f (GeV), beamE2 = %f (GeV), beamM1 = %f (GeV), beamM2 = %f (GeV), beamP1 = %f (GeV), beamP2 = %f (GeV)", beamZ1, beamZ2, beamA1, beamA2, beamE1, beamE2, beamM1, beamM2, beamP1, beamP2); + + mRunNumber = collision.runNumber(); } ~DileptonPolarization() diff --git a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx index 1d58b5b8f68..5fbd30a30e2 100644 --- a/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx +++ b/PWGEM/PhotonMeson/TableProducer/createEMEventPhoton.cxx @@ -176,12 +176,20 @@ struct CreateEMEventPhoton { } if (collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) { + int16_t posZint16 = static_cast(collision.posZ() * 100.f); + if (posZint16 == 0.f) { + if (collision.posZ() < 0) { + posZint16 = -1; + } else { + posZint16 = +1; + } + } if constexpr (eventtype == EMEventType::kEvent) { - event_norm_info(collision.selection_raw(), collision.rct_raw(), collision.posZ(), 105.f); + event_norm_info(collision.selection_raw(), collision.rct_raw(), posZint16, static_cast(105.f * 500.f)); } else if constexpr (eventtype == EMEventType::kEvent_Cent || eventtype == EMEventType::kEvent_Cent_Qvec) { - event_norm_info(collision.selection_raw(), collision.rct_raw(), collision.posZ(), collision.centFT0C()); + event_norm_info(collision.selection_raw(), collision.rct_raw(), posZint16, static_cast(collision.centFT0C() * 500.f)); } else { - event_norm_info(collision.selection_raw(), collision.rct_raw(), collision.posZ(), 105.f); + event_norm_info(collision.selection_raw(), collision.rct_raw(), posZint16, static_cast(105.f * 500.f)); } } From b9227083a3c31ae75442635082961dfb43f84b20 Mon Sep 17 00:00:00 2001 From: Daiki Sekihata Date: Wed, 26 Nov 2025 18:46:30 +0100 Subject: [PATCH 2/2] Add limits header to dileptonTables.h --- PWGEM/Dilepton/DataModel/dileptonTables.h | 1 + 1 file changed, 1 insertion(+) diff --git a/PWGEM/Dilepton/DataModel/dileptonTables.h b/PWGEM/Dilepton/DataModel/dileptonTables.h index 03cd152c68f..74dcc4cfd0e 100644 --- a/PWGEM/Dilepton/DataModel/dileptonTables.h +++ b/PWGEM/Dilepton/DataModel/dileptonTables.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include