diff --git a/Ntupliser/plugins/helper.cc b/Ntupliser/plugins/helper.cc
index cabae7dd9fe073fb6b0723b4264e093141ecc33d..a431cbb9ee729e38f9bbcbf1e1c03c1e71b6ad3b 100644
--- a/Ntupliser/plugins/helper.cc
+++ b/Ntupliser/plugins/helper.cc
@@ -204,21 +204,28 @@ DAS::RecPhoton DAS::Helper::GetRecPhoton (const pat::Photon &photon)
 
     // kinematics
     dasPhoton.p4 = photon.p4();
-    const auto raw_energy = dasPhoton.p4.E();
-    dasPhoton.scales = decltype(dasPhoton.scales){{
-        photon.userFloat("ecalEnergyPostCorr") / raw_energy,
-        photon.userFloat("energyScaleUp")      / raw_energy,
-        photon.userFloat("energyScaleDown")    / raw_energy,
-        photon.userFloat("energySigmaPhiUp")   / raw_energy,
-        photon.userFloat("energySigmaPhiDown") / raw_energy,
-        photon.userFloat("energySigmaRhoUp")   / raw_energy,
-        photon.userFloat("energySigmaRhoDown") / raw_energy,
-    }};
-    dasPhoton.ecalEnergyErrPostCorr = photon.userFloat("ecalEnergyErrPostCorr");
+
+    if (photon.hasUserFloat("ecalEnergyPostCorr")) {
+        // Only for MiniAODv2 (Run 2). In Run 3 we need to use correctionlib.
+        const auto raw_energy = dasPhoton.p4.E();
+        dasPhoton.scales = decltype(dasPhoton.scales){{
+            photon.userFloat("ecalEnergyPostCorr") / raw_energy,
+            photon.userFloat("energyScaleUp")      / raw_energy,
+            photon.userFloat("energyScaleDown")    / raw_energy,
+            photon.userFloat("energySigmaPhiUp")   / raw_energy,
+            photon.userFloat("energySigmaPhiDown") / raw_energy,
+            photon.userFloat("energySigmaRhoUp")   / raw_energy,
+            photon.userFloat("energySigmaRhoDown") / raw_energy,
+        }};
+        dasPhoton.ecalEnergyErrPostCorr = photon.userFloat("ecalEnergyErrPostCorr");
+    }
 
     // supercluster
+    dasPhoton.r9 = photon.full5x5_r9();
     dasPhoton.scEta = photon.superCluster()->eta();
     dasPhoton.sigmaIEtaIEta = photon.full5x5_sigmaIetaIeta();
+    dasPhoton.seedCrystalGain =
+        photon.hasUserFloat("seedGain") ? photon.userInt("seedGain") : -1;
 
     // ID
     dasPhoton.hOverE = photon.hadronicOverEm();
diff --git a/Ntupliser/python/Ntupliser_cfg.py b/Ntupliser/python/Ntupliser_cfg.py
index 88003c34d8ab49532d40556c812aaab4895c3f30..070b99fe86fb636b7fc2f7dde4c377549e07fed9 100644
--- a/Ntupliser/python/Ntupliser_cfg.py
+++ b/Ntupliser/python/Ntupliser_cfg.py
@@ -113,9 +113,9 @@ process.MessageLogger = cms.Service("MessageLogger",
 from Configuration.AlCa.GlobalTag import GlobalTag
 process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff')
 
-# See summary table from PdmV:
-# https://twiki.cern.ch/twiki/bin/viewauth/CMS/PdmVAnalysisSummaryTable
-# https://twiki.cern.ch/twiki/bin/view/CMS/PdmVRun2LegacyAnalysisSummaryTable
+# See summary tables from PdmV:
+# Run 2: https://twiki.cern.ch/twiki/bin/viewauth/CMS/PdmVAnalysisSummaryTable
+# Run 3: https://twiki.cern.ch/twiki/bin/viewauth/CMS/PdmVRun3Analysis
 if isMC:
     if year == 2016:
         if 'HIPM' in inputFiles[0] or 'VFP' in inputFiles[0]:
@@ -128,7 +128,16 @@ if isMC:
         GT = '106X_mc2017_realistic_v10'
     elif year == 2018:
         GT = '106X_upgrade2018_realistic_v16_L1v1'
-    # \todo 2022 and 2023
+    elif year == 2022:
+        if 'EE' in labels:
+            GT = '130X_mcRun3_2022_realistic_postEE_v6'
+        else:
+            GT = '130X_mcRun3_2022_realistic_v5'
+    elif year == 2023:
+        if 'BPix' in labels:
+            GT = '130X_mcRun3_2023_realistic_postBPix_v2'
+        else:
+            GT = '130X_mcRun3_2023_realistic_v14'
     elif year == 2024:
         GT = '133X_mcRun3_2024_realistic_v10' # \todo TBC
     else:
@@ -136,7 +145,13 @@ if isMC:
 else:
     if year > 2015 and year < 2019:
         GT = '106X_dataRun2_v37'
-    # \todo 2022 and 2023
+    elif year == 2022:
+        if set(labels) & {'RunC', 'RunD', 'RunE'}:
+            GT = '130X_dataRun3_v2'
+        else:
+            GT = '130X_dataRun3_PromptAnalysis_v1'
+    elif year == 2023:
+        GT = '130X_dataRun3_PromptAnalysis_v1'
     elif year == 2024:
         GT = '141X_dataRun3_Prompt_v4' # \todo TBC
     else:
@@ -320,15 +335,15 @@ process.ntupliser = cms.EDAnalyzer('Ntupliser',
     recphotons      = cms.InputTag('slimmedPhotons'),
 # trigger
     triggerNames    = cms.vstring(triggerNames),
-    triggerPrescales      = cms.InputTag('patTrigger', ''     , 'PAT' if run == 2 or isMC else 'RECO'),
-    triggerPrescalesl1min = cms.InputTag('patTrigger', 'l1min', 'PAT' if run == 2 or isMC else 'RECO'),
-    triggerPrescalesl1max = cms.InputTag('patTrigger', 'l1max', 'PAT' if run == 2 or isMC else 'RECO'),
+    triggerPrescales      = cms.InputTag('patTrigger', ''     , 'PAT' if year < 2024 or isMC else 'RECO'),
+    triggerPrescalesl1min = cms.InputTag('patTrigger', 'l1min', 'PAT' if year < 2024 or isMC else 'RECO'),
+    triggerPrescalesl1max = cms.InputTag('patTrigger', 'l1max', 'PAT' if year < 2024 or isMC else 'RECO'),
     triggerResults   = cms.InputTag('TriggerResults','','HLT'),
-    triggerObjects  = cms.InputTag('slimmedPatTrigger', '', 'PAT' if run == 2 or isMC else 'RECO'),
+    triggerObjects  = cms.InputTag('slimmedPatTrigger', '', 'PAT' if year < 2024 or isMC else 'RECO'),
 # MET
     met              = cms.InputTag('slimmedMETs'),
     metNames         = cms.vstring(metNames),
-    metResults       = cms.InputTag('TriggerResults','', 'PAT' if run == 2 or isMC else 'RECO'),
+    metResults       = cms.InputTag('TriggerResults','', 'PAT' if year < 2024 or isMC else 'RECO'),
 )
 
 if dump:
diff --git a/Objects/interface/Photon.h b/Objects/interface/Photon.h
index bfbe3b3f723ec9d9ae8c556011edb0a7ba2ed4b8..eb7413b217408abc0c580e424e741814aa8d5ace 100644
--- a/Objects/interface/Photon.h
+++ b/Objects/interface/Photon.h
@@ -55,7 +55,8 @@ struct RecPhoton : public GenPhoton {
         PixelSeedVeto              = 0b1000000, //!< Pixel seed veto
     };
 
-    float scEta, //!< Super cluster eta, used to veto the barrel/endcap transition region
+    float r9, //!< R9 of the supercluster, calculated with full 5x5 region
+          scEta, //!< Super cluster eta, used to veto the barrel/endcap transition region
           sigmaIEtaIEta, //!< Width of the ECAL deposit along the eta axis
           hOverE, //!< Ratio of HCAL to ECAL energy
           chargedIsolation, //!< Recomputed isolation from charged particles
@@ -63,6 +64,9 @@ struct RecPhoton : public GenPhoton {
           photonIsolation, //!< Recomputed isolation from other photons 
           worstChargedIsolation; //!< Recomputed charged isolation with the vertex chosen to maximize this value used for the ID 
 
+    /// Amplifier gain of the ECAL crystal used to seed the supercluster.
+    int seedCrystalGain;
+
     /// \brief Energy scale and smearing variations, indexed with the \ref EnergyVariation enum.
     /// \see \ref CorrP4
     float ecalEnergyErrPostCorr = -1; //!< resolution estimate on the ecalEnergy after scale & smearing corrections