Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7675b10
first draft
drkovalskyi Jan 31, 2026
0e55213
first working version
drkovalskyi Feb 1, 2026
d95908b
Add HLTSCOUT to PAT to NANO support
drkovalskyi Feb 3, 2026
fa59b31
Save scouting MET
drkovalskyi Feb 3, 2026
b347931
L1 object producers
drkovalskyi Feb 3, 2026
760a1d9
added rho producer
drkovalskyi Feb 3, 2026
c754247
pf candidate producer
drkovalskyi Feb 4, 2026
8af34e0
additional dependencies
drkovalskyi Feb 4, 2026
03d3bc0
set isolation properly
drkovalskyi Feb 4, 2026
d625d1b
moved convertion logic to the pat object contructors
drkovalskyi Feb 4, 2026
b4e3278
use standard collection names
drkovalskyi Feb 4, 2026
041f7eb
use standard collection names
drkovalskyi Feb 4, 2026
530219b
add missing config files
drkovalskyi Feb 4, 2026
ff23eb2
fill missing information
drkovalskyi Feb 4, 2026
9d15c7f
added new muon type
drkovalskyi Feb 4, 2026
1a2c143
added derived information from scouting muon
drkovalskyi Feb 4, 2026
f5572e8
fixed tests for 16_0_X
drkovalskyi Feb 18, 2026
133f8ea
added documentation
drkovalskyi Feb 18, 2026
1b09a9f
Add scouting electron support to pat::Electron
drkovalskyi Feb 19, 2026
d111409
Add scouting photon support to pat::Photon
Feb 25, 2026
a8e7c9a
Added support for jet constituents. Not very useful for Run2024 data,…
drkovalskyi Mar 4, 2026
6a788e1
unify inner track hitpattern information acccess
drkovalskyi Mar 4, 2026
e6bfba6
Added off-diagonal covariance terms (xyCov, xzCov, yzCov) to makeReco…
drkovalskyi Mar 4, 2026
1aeb044
added hit pattern information to the reco::Track collection and used …
drkovalskyi Mar 4, 2026
59fd069
added hit pattern information to the reco::Track collection and used …
drkovalskyi Mar 4, 2026
8ff4cca
bumped up version for Electron, Muon and Photon
drkovalskyi Mar 4, 2026
e829eee
fixed test
drkovalskyi Mar 4, 2026
2c78dbd
code-format
drkovalskyi Mar 4, 2026
5f52241
added slimmedMuonsNoVtx
drkovalskyi Mar 6, 2026
f40b6ca
added dimuon vertex collections
drkovalskyi Mar 6, 2026
35856e6
added missing producer
drkovalskyi Mar 19, 2026
c0cf916
exclude HF objects
drkovalskyi Mar 19, 2026
fa4c928
fixed formatting
drkovalskyi Mar 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Configuration/Applications/python/ConfigBuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,47 @@ def prepare_RECOBEFMIX(self, stepSpec = "reconstruction"):

def prepare_PAT(self, stepSpec = "patTask"):
''' Enrich the schedule with PAT '''

# Handle @-prefixed flavors (e.g., @Scout for scouting MiniAOD)
if '@' in stepSpec:
from PhysicsTools.PatFromScouting.autoPAT import autoPAT, expandPATMapping

_patSeq = stepSpec.split('+')
_patCustoms = stepSpec.split('+')
expandPATMapping(_patSeq, autoPAT, 'sequence')
expandPATMapping(_patCustoms, autoPAT, 'customize')

# Remove duplicates while preserving order
_patSeq = list(sorted(set(_patSeq), key=_patSeq.index))
_patCustoms = list(sorted(set(_patCustoms), key=_patCustoms.index))
# Remove empty strings
_patSeq = [s for s in _patSeq if s]
_patCustoms = [c for c in _patCustoms if c]

# Load and schedule sequences
_seqToSchedule = []
for _subSeq in _patSeq:
if '.' in _subSeq:
_cff, _seq = _subSeq.rsplit('.', 1)
print(f"PAT: scheduling: {_seq} from {_cff}")
self.loadAndRemember(_cff)
_seqToSchedule.append(_seq)
elif '/' in _subSeq:
self.loadAndRemember(_subSeq)

if _seqToSchedule:
self.scheduleSequence('+'.join(_seqToSchedule), 'patMiniAOD_step')

# Add customizations
for custom in _patCustoms:
self._options.customisation_file.append(custom)

# cpu efficiency boost when running PAT by itself
if self.stepKeys[0] == 'PAT':
self._customise_coms.append( 'process.source.delayReadingEventProducts = cms.untracked.bool(False)')

return

_,pat_sequence,pat_cff = self.loadDefaultOrSpecifiedCFF(stepSpec,self.PATDefaultCFF)
## handle the noise filters as Flag_* path that were loaded
for existing_path,path_ in self.process.paths_().items():
Expand Down Expand Up @@ -1874,6 +1915,12 @@ def prepare_NANO(self, stepSpec = '' ):
print(_nanoSeq)
# create full specified sequence using autoNANO
from PhysicsTools.NanoAOD.autoNANO import autoNANO, expandNanoMapping
# Extend with scouting-specific NANO flavors if available
try:
from PhysicsTools.PatFromScouting.autoPAT import autoNANO_scouting
autoNANO.update(autoNANO_scouting)
except ImportError:
pass # PatFromScouting not available
# if not a autoNANO mapping, load an empty customization, which later will be converted into the default.
_nanoCustoms = _nanoSeq.split('+') if '@' in stepSpec else ['']
_nanoSeq = _nanoSeq.split('+')
Expand Down
2 changes: 2 additions & 0 deletions DataFormats/MuonReco/interface/Muon.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ namespace reco {
static const unsigned int RPCMuon = 1 << 6;
static const unsigned int GEMMuon = 1 << 7;
static const unsigned int ME0Muon = 1 << 8;
static const unsigned int ScoutingMuon = 1 << 9;

void setType(unsigned int type) { type_ = type; }
unsigned int type() const { return type_; }
Expand All @@ -308,6 +309,7 @@ namespace reco {
bool isRPCMuon() const { return type_ & RPCMuon; }
bool isGEMMuon() const { return type_ & GEMMuon; }
bool isME0Muon() const { return type_ & ME0Muon; }
bool isScoutingMuon() const { return type_ & ScoutingMuon; }

private:
/// check overlap with another candidate
Expand Down
1 change: 1 addition & 0 deletions DataFormats/PatCandidates/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<use name="DataFormats/ParticleFlowCandidate"/>
<use name="DataFormats/Provenance"/>
<use name="DataFormats/RecoCandidate"/>
<use name="DataFormats/Scouting"/>
<use name="DataFormats/SiPixelDetId"/>
<use name="DataFormats/SiStripDetId"/>
<use name="DataFormats/TauReco"/>
Expand Down
44 changes: 44 additions & 0 deletions DataFormats/PatCandidates/interface/Electron.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
#include "DataFormats/PatCandidates/interface/PackedCandidate.h"
#include "DataFormats/Common/interface/AtomicPtrCache.h"

// Forward declaration for scouting
class Run3ScoutingElectron;

// Define typedefs for convenience
namespace pat {
class Electron;
Expand Down Expand Up @@ -61,6 +64,8 @@ namespace pat {
Electron(const edm::RefToBase<reco::GsfElectron>& anElectronRef);
/// constructor from a Ptr to a reco::GsfElectron
Electron(const edm::Ptr<reco::GsfElectron>& anElectronRef);
/// constructor from Run3ScoutingElectron
Electron(const Run3ScoutingElectron& scoutingElectron);
/// destructor
~Electron() override;

Expand Down Expand Up @@ -269,6 +274,29 @@ namespace pat {
associatedPackedFCandidateIndices_.insert(associatedPackedFCandidateIndices_.end(), beginIndexItr, endIndexItr);
}

// ---- Scouting flag ----
bool isScoutingElectron() const { return isScoutingElectron_; }

// ---- Universal accessors with scouting dispatch ----
// Track-related: dispatches to gsfTrack() for standard, scouting members for scouting
float trkEta() const;
float trkPhi() const;
float trkpMode() const;
float trketaMode() const;
float trkphiMode() const;
float trkqoverpModeError() const;

// ECAL crystal-level: dispatches to superCluster() for standard, scouting members for scouting
uint32_t seedId() const;
uint32_t nClusters() const;
uint32_t nCrystals() const;

// ---- Scouting-only accessors (no standard equivalent) ----
std::vector<float> const& scoutingEnergyMatrix() const { return scoutingEnergyMatrix_; }
std::vector<float> const& scoutingTimingMatrix() const { return scoutingTimingMatrix_; }
std::vector<uint32_t> const& scoutingDetIds() const { return scoutingDetIds_; }
bool scoutingRechitZeroSuppression() const { return scoutingRechitZeroSuppression_; }

friend class PATElectronSlimmer;
friend class PATElectronCandidatesRekeyer;

Expand Down Expand Up @@ -377,6 +405,22 @@ namespace pat {
// ---- link to PackedPFCandidates
edm::RefProd<pat::PackedCandidateCollection> packedPFCandidates_;
std::vector<uint16_t> associatedPackedFCandidateIndices_;

// ---- scouting-specific members ----
bool isScoutingElectron_{false};
std::vector<float> scoutingTrkEta_;
std::vector<float> scoutingTrkPhi_;
std::vector<float> scoutingTrkpMode_;
std::vector<float> scoutingTrketaMode_;
std::vector<float> scoutingTrkphiMode_;
std::vector<float> scoutingTrkqoverpModeError_;
uint32_t scoutingSeedId_{0};
uint32_t scoutingNClusters_{0};
uint32_t scoutingNCrystals_{0};
std::vector<float> scoutingEnergyMatrix_;
std::vector<float> scoutingTimingMatrix_;
std::vector<uint32_t> scoutingDetIds_;
bool scoutingRechitZeroSuppression_{false};
};
} // namespace pat

Expand Down
5 changes: 5 additions & 0 deletions DataFormats/PatCandidates/interface/Jet.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@

#include <numeric>

// Forward declaration for scouting
class Run3ScoutingPFJet;

// Define typedefs for convenience
namespace pat {
class Jet;
Expand Down Expand Up @@ -95,6 +98,8 @@ namespace pat {
Jet(const edm::RefToBase<pat::Jet>& aJetRef);
/// constructure from ref to pat::Jet
Jet(const edm::Ptr<pat::Jet>& aJetRef);
/// constructor from Run3ScoutingPFJet
Jet(const Run3ScoutingPFJet& scoutingJet);
/// destructor
~Jet() override;
/// required reimplementation of the Candidate's clone method
Expand Down
61 changes: 61 additions & 0 deletions DataFormats/PatCandidates/interface/Muon.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@
#include "DataFormats/MuonReco/interface/MuonTimeExtra.h"

#include "DataFormats/TrackReco/interface/Track.h"
#include "DataFormats/TrackReco/interface/HitPattern.h"
#include "DataFormats/PatCandidates/interface/Lepton.h"
#include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidateFwd.h"
#include "DataFormats/ParticleFlowCandidate/interface/IsolatedPFCandidate.h"
#include "DataFormats/MuonReco/interface/MuonSimInfo.h"

// Define typedefs for convenience
class Run3ScoutingMuon;

namespace pat {
class Muon;
typedef std::vector<Muon> MuonCollection;
Expand Down Expand Up @@ -59,6 +62,8 @@ namespace pat {
Muon(const edm::RefToBase<reco::Muon>& aMuonRef);
/// constructor from a Ptr to a reco muon
Muon(const edm::Ptr<reco::Muon>& aMuonRef);
/// constructor from a scouting muon
Muon(const Run3ScoutingMuon& aMuon);
/// destructor
~Muon() override;

Expand Down Expand Up @@ -344,6 +349,46 @@ namespace pat {
}
bool triggered(const char* pathName) const { return triggerObjectMatchByPath(pathName, true, true) != nullptr; }

// ---- Methods that hide reco::Muon methods for scouting muon compatibility ----
// For ScoutingMuon, these return cached values; otherwise delegate to reco::Muon

/// Number of chambers (hides reco::Muon::numberOfChambers)
int numberOfChambers() const;
/// Number of chambers CSC or DT only (hides reco::Muon::numberOfChambersCSCorDT)
int numberOfChambersCSCorDT() const;
/// Number of muon stations with matches (hides reco::Muon::numberOfMatches)
int numberOfMatches(reco::Muon::ArbitrationType type = reco::Muon::SegmentAndTrackArbitration) const;
/// Number of matched stations (hides reco::Muon::numberOfMatchedStations)
int numberOfMatchedStations(reco::Muon::ArbitrationType type = reco::Muon::SegmentAndTrackArbitration) const;
/// Expected number of matched stations (hides reco::Muon::expectedNnumberOfMatchedStations)
unsigned int expectedNnumberOfMatchedStations(float minDistanceFromEdge = 10.0) const;
/// Muon station mask (hides reco::Muon::stationMask)
unsigned int stationMask(reco::Muon::ArbitrationType type = reco::Muon::SegmentAndTrackArbitration) const;
/// Number of matched RPC layers (hides reco::Muon::numberOfMatchedRPCLayers)
int numberOfMatchedRPCLayers(reco::Muon::ArbitrationType type = reco::Muon::RPCHitAndTrackArbitration) const;
/// RPC layer mask (hides reco::Muon::RPClayerMask)
unsigned int RPClayerMask(reco::Muon::ArbitrationType type = reco::Muon::RPCHitAndTrackArbitration) const;

// ---- Hit information accessors ----
// For scouting muons return cached values; for standard muons compute from tracks

/// Number of valid muon hits (from global track hitPattern for standard muons)
int numberOfValidMuonHits() const;
/// Number of valid standalone muon hits
int numberOfValidStandAloneMuonHits() const;
/// Number of standalone muon matched stations
int numberOfStandAloneMuonMatchedStations() const;
/// Number of valid pixel hits (from inner track hitPattern)
int numberOfValidPixelHits() const;
/// Number of valid strip hits (from inner track hitPattern)
int numberOfValidStripHits() const;
/// Number of pixel layers with measurement
int numberOfPixelLayersWithMeasurement() const;
/// Number of tracker layers with measurement
int numberOfTrackerLayersWithMeasurement() const;
/// Track hit pattern (from inner track for standard muons, from scouting data for scouting muons)
reco::HitPattern const& trkHitPattern() const;

protected:
// ---- for content embedding ----

Expand Down Expand Up @@ -439,6 +484,22 @@ namespace pat {
float simEta_;
float simPhi_;
float simMatchQuality_;

private:
// ---- Cached values for scouting muons ----
// Filled by constructor from Run3ScoutingMuon; accessors check isScoutingMuon()
int scoutingNChambers_{0};
int scoutingNChambersCSCorDT_{0};
int scoutingNMatches_{0};
int scoutingNMatchedStations_{0};
unsigned int scoutingExpectedMatchedStations_{0};
unsigned int scoutingStationMask_{0};
int scoutingNMatchedRPCLayers_{0};
unsigned int scoutingRPCLayerMask_{0};
int scoutingNValidMuonHits_{0};
int scoutingNValidStandAloneMuonHits_{0};
int scoutingNStandAloneMuonMatchedStations_{0};
reco::HitPattern scoutingTrkHitPattern_;
};

} // namespace pat
Expand Down
31 changes: 31 additions & 0 deletions DataFormats/PatCandidates/interface/Photon.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
\author Steven Lowette, Giovanni Petrucciani, Frederic Ronga
*/

#include <cstdint>
#include "DataFormats/PatCandidates/interface/PATObject.h"
#include "DataFormats/EgammaCandidates/interface/Photon.h"
#include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
Expand All @@ -26,6 +27,9 @@
#include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
#include "DataFormats/Common/interface/AtomicPtrCache.h"

// Forward declaration for scouting
class Run3ScoutingPhoton;

// Define typedefs for convenience
namespace pat {
class Photon;
Expand Down Expand Up @@ -56,6 +60,8 @@ namespace pat {
Photon(const edm::RefToBase<reco::Photon>& aPhotonRef);
/// constructor from a Ptr to a reco photon
Photon(const edm::Ptr<reco::Photon>& aPhotonRef);
/// constructor from Run3ScoutingPhoton
Photon(const Run3ScoutingPhoton& scoutingPhoton);
/// destructor
~Photon() override;

Expand Down Expand Up @@ -328,6 +334,21 @@ namespace pat {
/// get the source candidate pointer with index i
reco::CandidatePtr sourceCandidatePtr(size_type i) const override;

// ---- Scouting flag ----
bool isScoutingPhoton() const { return isScoutingPhoton_; }

// ---- Universal accessors with scouting dispatch ----
// ECAL crystal-level: dispatches to superCluster() for standard, scouting members for scouting
uint32_t seedId() const;
uint32_t nClusters() const;
uint32_t nCrystals() const;

// ---- Scouting-only accessors (no standard equivalent) ----
std::vector<float> const& scoutingEnergyMatrix() const { return scoutingEnergyMatrix_; }
std::vector<float> const& scoutingTimingMatrix() const { return scoutingTimingMatrix_; }
std::vector<uint32_t> const& scoutingDetIds() const { return scoutingDetIds_; }
bool scoutingRechitZeroSuppression() const { return scoutingRechitZeroSuppression_; }

friend class PATPhotonSlimmer;
friend class PATPhotonCandidatesRekeyer;

Expand Down Expand Up @@ -404,6 +425,16 @@ namespace pat {
// ---- link to PackedPFCandidates
edm::RefProd<pat::PackedCandidateCollection> packedPFCandidates_;
std::vector<uint16_t> associatedPackedFCandidateIndices_;

// ---- scouting-specific members ----
bool isScoutingPhoton_{false};
uint32_t scoutingSeedId_{0};
uint32_t scoutingNClusters_{0};
uint32_t scoutingNCrystals_{0};
std::vector<float> scoutingEnergyMatrix_;
std::vector<float> scoutingTimingMatrix_;
std::vector<uint32_t> scoutingDetIds_;
bool scoutingRechitZeroSuppression_{false};
};

} // namespace pat
Expand Down
28 changes: 28 additions & 0 deletions DataFormats/PatCandidates/interface/ScoutingDataHandling.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef DataFormats_PatCandidates_ScoutingDataHandling_h
#define DataFormats_PatCandidates_ScoutingDataHandling_h

#include "DataFormats/TrackReco/interface/Track.h"
#include "DataFormats/VertexReco/interface/Vertex.h"
#include "DataFormats/Scouting/interface/Run3ScoutingTrack.h"
#include "DataFormats/PatCandidates/interface/Muon.h"
#include "DataFormats/Scouting/interface/Run3ScoutingMuon.h"
#include "DataFormats/Scouting/interface/Run3ScoutingVertex.h"

namespace pat {
typedef reco::Candidate::LorentzVector LorentzVector;
typedef reco::Candidate::PolarLorentzVector PolarLorentzVector;

// Tracks
reco::Track makeRecoTrack(const Run3ScoutingTrack&);
reco::Track makeRecoTrack(const Run3ScoutingMuon&);
Run3ScoutingTrack makeScoutingTrack(const reco::Track&);
PolarLorentzVector makePolarLorentzVector(const Run3ScoutingTrack&, float mass);

// Muons
pat::Muon makePatMuon(const Run3ScoutingMuon&);

// Vertex
reco::Vertex makeRecoVertex(const Run3ScoutingVertex&);
} // namespace pat

#endif
Loading