CMS 3D CMS Logo

MLPFModel.cc
Go to the documentation of this file.
13 
14 namespace reco::mlpf {
15 
16  //Prepares the input array of floats for a single PFElement
17  std::array<float, NUM_ELEMENT_FEATURES> getElementProperties(const reco::PFBlockElement& orig) {
18  const auto type = orig.type();
19  float pt = 0.0;
20  float deltap = 0.0;
21  float sigmadeltap = 0.0;
22  float px = 0.0;
23  float py = 0.0;
24  float pz = 0.0;
25  float eta = 0.0;
26  float phi = 0.0;
27  float energy = 0.0;
28  float corr_energy = 0.0;
29  float trajpoint = 0.0;
30  float eta_ecal = 0.0;
31  float phi_ecal = 0.0;
32  float eta_hcal = 0.0;
33  float phi_hcal = 0.0;
34  float charge = 0;
35  float layer = 0;
36  float depth = 0;
37  float muon_dt_hits = 0.0;
38  float muon_csc_hits = 0.0;
39  float muon_type = 0.0;
40  float cluster_flags = 0.0;
41  float gsf_electronseed_trkorecal = 0.0;
42  float num_hits = 0.0;
43 
45  const auto& matched_pftrack = orig.trackRefPF();
46  if (matched_pftrack.isNonnull()) {
47  const auto& atECAL = matched_pftrack->extrapolatedPoint(reco::PFTrajectoryPoint::ECALShowerMax);
48  const auto& atHCAL = matched_pftrack->extrapolatedPoint(reco::PFTrajectoryPoint::HCALEntrance);
49  if (atHCAL.isValid()) {
50  eta_hcal = atHCAL.positionREP().eta();
51  phi_hcal = atHCAL.positionREP().phi();
52  }
53  if (atECAL.isValid()) {
54  eta_ecal = atECAL.positionREP().eta();
55  phi_ecal = atECAL.positionREP().phi();
56  }
57  }
58  const auto& ref = ((const reco::PFBlockElementTrack*)&orig)->trackRef();
59  pt = ref->pt();
60  px = ref->px();
61  py = ref->py();
62  pz = ref->pz();
63  eta = ref->eta();
64  phi = ref->phi();
65  energy = ref->p();
66  charge = ref->charge();
67  num_hits = ref->recHitsSize();
68 
69  reco::MuonRef muonRef = orig.muonRef();
70  if (muonRef.isNonnull()) {
71  reco::TrackRef standAloneMu = muonRef->standAloneMuon();
72  if (standAloneMu.isNonnull()) {
73  muon_dt_hits = standAloneMu->hitPattern().numberOfValidMuonDTHits();
74  muon_csc_hits = standAloneMu->hitPattern().numberOfValidMuonCSCHits();
75  }
76  muon_type = muonRef->type();
77  }
78 
79  } else if (type == reco::PFBlockElement::BREM) {
80  const auto* orig2 = (const reco::PFBlockElementBrem*)&orig;
81  const auto& ref = orig2->GsftrackRef();
82  trajpoint = orig2->indTrajPoint();
83  if (ref.isNonnull()) {
84  deltap = orig2->DeltaP();
85  sigmadeltap = orig2->SigmaDeltaP();
86  pt = ref->pt();
87  px = ref->px();
88  py = ref->py();
89  pz = ref->pz();
90  eta = ref->eta();
91  phi = ref->phi();
92  energy = ref->p();
93  charge = ref->charge();
94  }
95 
96  const auto& gsfextraref = ref->extra();
97  if (gsfextraref.isAvailable() && gsfextraref->seedRef().isAvailable()) {
98  reco::ElectronSeedRef seedref = gsfextraref->seedRef().castTo<reco::ElectronSeedRef>();
99  if (seedref.isAvailable()) {
100  if (seedref->isEcalDriven()) {
101  gsf_electronseed_trkorecal = 1.0;
102  } else if (seedref->isTrackerDriven()) {
103  gsf_electronseed_trkorecal = 2.0;
104  }
105  }
106  }
107 
108  } else if (type == reco::PFBlockElement::GSF) {
109  //requires to keep GsfPFRecTracks
110  const auto* orig2 = (const reco::PFBlockElementGsfTrack*)&orig;
111  const auto& vec = orig2->Pin();
112  pt = vec.pt();
113  px = vec.px();
114  py = vec.py();
115  pz = vec.pz();
116  eta = vec.eta();
117  phi = vec.phi();
118  energy = vec.energy();
119 
120  const auto& vec2 = orig2->Pout();
121  eta_ecal = vec2.eta();
122  phi_ecal = vec2.phi();
123 
124  if (!orig2->GsftrackRefPF().isNull()) {
125  charge = orig2->GsftrackRefPF()->charge();
126  num_hits = orig2->GsftrackRefPF()->PFRecBrem().size();
127  }
128 
129  const auto& ref = orig2->GsftrackRef();
130 
131  const auto& gsfextraref = ref->extra();
132  if (gsfextraref.isAvailable() && gsfextraref->seedRef().isAvailable()) {
133  reco::ElectronSeedRef seedref = gsfextraref->seedRef().castTo<reco::ElectronSeedRef>();
134  if (seedref.isAvailable()) {
135  if (seedref->isEcalDriven()) {
136  gsf_electronseed_trkorecal = 1.0;
137  } else if (seedref->isTrackerDriven()) {
138  gsf_electronseed_trkorecal = 2.0;
139  }
140  }
141  };
142 
147  const auto& ref = ((const reco::PFBlockElementCluster*)&orig)->clusterRef();
148  if (ref.isNonnull()) {
149  cluster_flags = ref->flags();
150  eta = ref->eta();
151  phi = ref->phi();
152  pt = ref->pt();
153  px = ref->position().x();
154  py = ref->position().y();
155  pz = ref->position().z();
156  energy = ref->energy();
157  corr_energy = ref->correctedEnergy();
158  layer = ref->layer();
159  depth = ref->depth();
160  num_hits = ref->recHitFractions().size();
161  }
162  } else if (type == reco::PFBlockElement::SC) {
163  const auto& clref = ((const reco::PFBlockElementSuperCluster*)&orig)->superClusterRef();
164  if (clref.isNonnull()) {
165  cluster_flags = clref->flags();
166  eta = clref->eta();
167  phi = clref->phi();
168  px = clref->position().x();
169  py = clref->position().y();
170  pz = clref->position().z();
171  energy = clref->energy();
172  num_hits = clref->clustersSize();
173  }
174  }
175 
176  float typ_idx = static_cast<float>(elem_type_encoding.at(orig.type()));
177 
178  //Must be the same order as in tf_model.py
179  return {{typ_idx,
180  pt,
181  eta,
182  phi,
183  energy,
184  layer,
185  depth,
186  charge,
187  trajpoint,
188  eta_ecal,
189  phi_ecal,
190  eta_hcal,
191  phi_hcal,
192  muon_dt_hits,
193  muon_csc_hits,
194  muon_type,
195  px,
196  py,
197  pz,
198  deltap,
199  sigmadeltap,
200  gsf_electronseed_trkorecal,
201  num_hits,
202  cluster_flags,
203  corr_energy}};
204  }
205 
206  //to make sure DNN inputs are within numerical bounds, use the same in training
207  float normalize(float in) {
208  if (std::abs(in) > 1e4f) {
209  return 0.0;
210  } else if (edm::isNotFinite(in)) {
211  return 0.0;
212  }
213  return in;
214  }
215 
216  int argMax(std::vector<float> const& vec) {
217  return static_cast<int>(std::distance(vec.begin(), max_element(vec.begin(), vec.end())));
218  }
219 
221  int pred_charge,
222  float pred_pt,
223  float pred_eta,
224  float pred_sin_phi,
225  float pred_cos_phi,
226  float pred_e) {
227  float pred_phi = std::atan2(pred_sin_phi, pred_cos_phi);
228 
229  //set the charge to +1 or -1 for PFCandidates that are charged, according to the sign of the predicted charge
231  if (pred_pid == 11 || pred_pid == 13 || pred_pid == 211) {
232  charge = pred_charge > 0 ? +1 : -1;
233  }
234 
235  math::PtEtaPhiELorentzVectorD p4(pred_pt, pred_eta, pred_phi, pred_e);
236 
238  if (pred_pid == 211)
240  else if (pred_pid == 130)
242  else if (pred_pid == 22)
244  else if (pred_pid == 11)
246  else if (pred_pid == 13)
248  else if (pred_pid == 1)
250  else if (pred_pid == 2)
252 
253  reco::PFCandidate cand(charge, math::XYZTLorentzVector(p4.X(), p4.Y(), p4.Z(), p4.E()), particleType);
254  cand.setMass(0.0);
255  if (pred_pid == 211)
256  cand.setMass(PI_MASS);
257  //cand.setPdgId(pred_pid);
258  //cand.setCharge(charge);
259 
260  return cand;
261  }
262 
263  const std::vector<const reco::PFBlockElement*> getPFElements(const reco::PFBlockCollection& blocks) {
264  std::vector<reco::PFCandidate> pOutputCandidateCollection;
265 
266  std::vector<const reco::PFBlockElement*> all_elements;
267  for (const auto& block : blocks) {
268  const auto& elems = block.elements();
269  for (const auto& elem : elems) {
270  if (all_elements.size() < NUM_MAX_ELEMENTS_BATCH) {
271  all_elements.push_back(&elem);
272  } else {
273  //model needs to be created with a bigger LSH codebook size
274  edm::LogError("MLPFProducer") << "too many input PFElements for predefined model size: " << elems.size();
275  break;
276  }
277  }
278  }
279  return all_elements;
280  }
281 
282  // [4] Calling method for module JetTracksAssociatorExplicit/'ak4JetTracksAssociatorExplicitAll' -> Ref is inconsistent with RefVectorid = (3:3546) should be (3:3559)
283  // [6] Calling method for module MuonProducer/'muons' -> muon::isTightMuon
285  const std::vector<const reco::PFBlockElement*> elems,
286  size_t ielem_originator) {
287  const reco::PFBlockElement* elem = elems[ielem_originator];
288 
289  //set the track ref in case the originating element was a track
290  if (std::abs(cand.pdgId()) == 211 && elem->type() == reco::PFBlockElement::TRACK && elem->trackRef().isNonnull()) {
291  const auto* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(elem);
292  cand.setTrackRef(eltTrack->trackRef());
293  cand.setVertex(eltTrack->trackRef()->vertex());
294  cand.setPositionAtECALEntrance(eltTrack->positionAtECALEntrance());
295  }
296 
297  //set the muon ref
298  if (std::abs(cand.pdgId()) == 13) {
299  const auto* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(elem);
300  const auto& muonRef = eltTrack->muonRef();
301  cand.setTrackRef(muonRef->track());
302  cand.setMuonTrackType(muonRef->muonBestTrackType());
303  cand.setVertex(muonRef->track()->vertex());
304  cand.setMuonRef(muonRef);
305  }
306 
307  if (std::abs(cand.pdgId()) == 11 && elem->type() == reco::PFBlockElement::GSF) {
308  const auto* eltTrack = dynamic_cast<const reco::PFBlockElementGsfTrack*>(elem);
309  const auto& ref = eltTrack->GsftrackRef();
310  cand.setGsfTrackRef(ref);
311  }
312  }
313 
314 }; // namespace reco::mlpf
Abstract base class for a PFBlock element (track, cluster...)
int Charge
electric charge type
Definition: Candidate.h:34
ParticleType
particle types
Definition: PFCandidate.h:44
std::array< float, NUM_ELEMENT_FEATURES > getElementProperties(const reco::PFBlockElement &orig)
Definition: MLPFModel.cc:17
int argMax(std::vector< float > const &vec)
Definition: MLPFModel.cc:216
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
virtual const reco::TrackRef & trackRef() const
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
const reco::GsfTrackRef & GsftrackRef() const
ALPAKA_FN_HOST_ACC ALPAKA_FN_INLINE constexpr float charge(ConstView const &tracks, int32_t i)
Definition: TracksSoA.h:73
Log< level::Error, false > LogError
virtual const PFRecTrackRef & trackRefPF() const
const std::vector< const reco::PFBlockElement * > getPFElements(const reco::PFBlockCollection &blocks)
Definition: MLPFModel.cc:263
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
bool isAvailable() const
Definition: Ref.h:541
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const reco::MuonRef & muonRef() const override
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiE4D< double > > PtEtaPhiELorentzVectorD
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:12
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
Definition: PFBlockFwd.h:10
reco::PFCandidate makeCandidate(int pred_pid, int pred_charge, float pred_pt, float pred_eta, float pred_sin_phi, float pred_cos_phi, float pred_e)
Definition: MLPFModel.cc:220
static const std::map< int, int > elem_type_encoding
Definition: MLPFModel.h:47
float normalize(float in)
Definition: MLPFModel.cc:207
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
static constexpr float PI_MASS
Definition: MLPFModel.h:39
void setCandidateRefs(reco::PFCandidate &cand, const std::vector< const reco::PFBlockElement *> elems, size_t ielem_originator)
Definition: MLPFModel.cc:284
std::vector< vec1 > vec2
Definition: HCALResponse.h:16
virtual const MuonRef & muonRef() const
static constexpr int NUM_MAX_ELEMENTS_BATCH
Definition: MLPFModel.h:15