CMS 3D CMS Logo

ElectronSeedGenerator.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: EgammaElectronAlgos
4 // Class: ElectronSeedGenerator.
5 //
13 //
14 // Original Author: Ursula Berthon, Claude Charlot
15 // Created: Mon Mar 27 13:22:06 CEST 2006
16 //
17 
33 
34 #include <vector>
35 #include <utility>
36 
37 namespace {
38 
39  bool equivalent(const TrajectorySeed &s1, const TrajectorySeed &s2) {
40  if (s1.nHits() != s2.nHits())
41  return false;
42 
43  unsigned int nHits;
44  TrajectorySeed::range r1 = s1.recHits(), r2 = s2.recHits();
46  for (i1 = r1.first, i2 = r2.first, nHits = 0; i1 != r1.second; ++i1, ++i2, ++nHits) {
47  if (!i1->isValid() || !i2->isValid())
48  return false;
49  if (i1->geographicalId() != i2->geographicalId())
50  return false;
51  if (!(i1->localPosition() == i2->localPosition()))
52  return false;
53  }
54 
55  return true;
56  }
57 
58  void addSeed(reco::ElectronSeed &seed, const SeedWithInfo *info, bool positron, reco::ElectronSeedCollection &out) {
59  if (!info) {
60  out.emplace_back(seed);
61  return;
62  }
63 
64  if (positron) {
65  seed.setPosAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
66  } else {
67  seed.setNegAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
68  }
69  for (auto &res : out) {
70  if ((seed.caloCluster().key() == res.caloCluster().key()) && (seed.hitsMask() == res.hitsMask()) &&
71  equivalent(seed, res)) {
72  if (positron) {
73  if (res.dRZPos(1) == std::numeric_limits<float>::infinity() &&
75  res.setPosAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
76  seed.setNegAttributes(res.dRZNeg(1), res.dPhiNeg(1), res.dRZNeg(0), res.dPhiNeg(0));
77  break;
78  } else {
79  if (res.dRZPos(1) != std::numeric_limits<float>::infinity()) {
80  if (res.dRZPos(1) != seed.dRZPos(1)) {
81  edm::LogWarning("ElectronSeedGenerator|BadValue")
82  << "this similar old seed already has another dRz2Pos"
83  << "\nold seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)res.hitsMask() << "/"
84  << res.dRZNeg(1) << "/" << res.dPhiNeg(1) << "/" << res.dRZPos(1) << "/" << res.dPhiPos(1)
85  << "\nnew seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)seed.hitsMask() << "/"
86  << seed.dRZNeg(1) << "/" << seed.dPhiNeg(1) << "/" << seed.dRZPos(1) << "/" << seed.dPhiPos(1);
87  }
88  }
89  }
90  } else {
91  if (res.dRZNeg(1) == std::numeric_limits<float>::infinity() &&
93  res.setNegAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
94  seed.setPosAttributes(res.dRZPos(1), res.dPhiPos(1), res.dRZPos(0), res.dPhiPos(0));
95  break;
96  } else {
97  if (res.dRZNeg(1) != std::numeric_limits<float>::infinity()) {
98  if (res.dRZNeg(1) != seed.dRZNeg(1)) {
99  edm::LogWarning("ElectronSeedGenerator|BadValue")
100  << "this old seed already has another dRz2"
101  << "\nold seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)res.hitsMask() << "/"
102  << res.dRZNeg(1) << "/" << res.dPhiNeg(1) << "/" << res.dRZPos(1) << "/" << res.dPhiPos(1)
103  << "\nnew seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)seed.hitsMask() << "/"
104  << seed.dRZNeg(1) << "/" << seed.dPhiNeg(1) << "/" << seed.dRZPos(1) << "/" << seed.dPhiPos(1);
105  }
106  }
107  }
108  }
109  }
110  }
111 
112  out.emplace_back(seed);
113  }
114 
115  void seedsFromTrajectorySeeds(const std::vector<SeedWithInfo> &pixelSeeds,
116  const reco::ElectronSeed::CaloClusterRef &cluster,
118  bool positron) {
119  if (!pixelSeeds.empty()) {
120  LogDebug("ElectronSeedGenerator") << "Compatible " << (positron ? "positron" : "electron") << " seeds found.";
121  }
122 
123  std::vector<SeedWithInfo>::const_iterator s;
124  for (s = pixelSeeds.begin(); s != pixelSeeds.end(); s++) {
125  reco::ElectronSeed seed(s->seed);
126  seed.setCaloCluster(cluster);
127  seed.initTwoHitSeed(s->hitsMask);
128  addSeed(seed, &*s, positron, out);
129  }
130  }
131 
132 } // namespace
133 
135  : dynamicPhiRoad_(pset.getParameter<bool>("dynamicPhiRoad")),
136  verticesTag_(ts.token_vtx),
137  beamSpotTag_(ts.token_bs),
138  lowPtThresh_(pset.getParameter<double>("LowPtThreshold")),
139  highPtThresh_(pset.getParameter<double>("HighPtThreshold")),
140  nSigmasDeltaZ1_(pset.getParameter<double>("nSigmasDeltaZ1")),
141  deltaZ1WithVertex_(pset.getParameter<double>("deltaZ1WithVertex")),
142  sizeWindowENeg_(pset.getParameter<double>("SizeWindowENeg")),
143  deltaPhi1Low_(pset.getParameter<double>("DeltaPhi1Low")),
144  deltaPhi1High_(pset.getParameter<double>("DeltaPhi1High")),
145  // so that deltaPhi1 = dPhi1Coef1_ + dPhi1Coef2_/clusterEnergyT
146  dPhi1Coef2_(dynamicPhiRoad_ ? (deltaPhi1Low_ - deltaPhi1High_) / (1. / lowPtThresh_ - 1. / highPtThresh_) : 0.),
147  dPhi1Coef1_(dynamicPhiRoad_ ? deltaPhi1Low_ - dPhi1Coef2_ / lowPtThresh_ : 0.),
148  propagator_(nullptr),
149  // use of reco vertex
150  useRecoVertex_(pset.getParameter<bool>("useRecoVertex")),
151  // new B/F configurables
152  deltaPhi2B_(pset.getParameter<double>("DeltaPhi2B")),
153  deltaPhi2F_(pset.getParameter<double>("DeltaPhi2F")),
154  phiMin2B_(pset.getParameter<double>("PhiMin2B")),
155  phiMin2F_(pset.getParameter<double>("PhiMin2F")),
156  phiMax2B_(pset.getParameter<double>("PhiMax2B")),
157  phiMax2F_(pset.getParameter<double>("PhiMax2F")),
158  electronMatcher_(pset.getParameter<double>("ePhiMin1"),
159  pset.getParameter<double>("ePhiMax1"),
160  phiMin2B_,
161  phiMax2B_,
162  phiMin2F_,
163  phiMax2F_,
164  pset.getParameter<double>("z2MinB"),
165  pset.getParameter<double>("z2MaxB"),
166  pset.getParameter<double>("r2MinF"),
167  pset.getParameter<double>("r2MaxF"),
168  pset.getParameter<double>("rMinI"),
169  pset.getParameter<double>("rMaxI"),
170  useRecoVertex_),
171  positronMatcher_(pset.getParameter<double>("pPhiMin1"),
172  pset.getParameter<double>("pPhiMax1"),
173  phiMin2B_,
174  phiMax2B_,
175  phiMin2F_,
176  phiMax2F_,
177  pset.getParameter<double>("z2MinB"),
178  pset.getParameter<double>("z2MaxB"),
179  pset.getParameter<double>("r2MinF"),
180  pset.getParameter<double>("r2MaxF"),
181  pset.getParameter<double>("rMinI"),
182  pset.getParameter<double>("rMaxI"),
183  useRecoVertex_) {}
184 
186  // get records if necessary (called once per event)
187  bool tochange = false;
188 
190  setup.get<IdealMagneticFieldRecord>().get(magField_);
191  cacheIDMagField_ = setup.get<IdealMagneticFieldRecord>().cacheIdentifier();
192  propagator_ = std::make_unique<PropagatorWithMaterial>(alongMomentum, .000511, &(*magField_));
193  tochange = true;
194  }
195 
197  cacheIDTrkGeom_ = setup.get<TrackerDigiGeometryRecord>().cacheIdentifier();
199  tochange = true; //FIXME
200  }
201 
202  if (tochange) {
205  }
206 }
207 
209  const edm::EventSetup &setup,
210  const reco::SuperClusterRefVector &sclRefs,
211  const std::vector<const TrajectorySeedCollection *> &seedsV,
214 
215  // get the beamspot from the Event:
216  auto const &beamSpot = e.get(beamSpotTag_);
217 
218  // if required get the vertices
219  std::vector<reco::Vertex> const *vertices = nullptr;
220  if (useRecoVertex_)
221  vertices = &e.get(verticesTag_);
222 
223  for (unsigned int i = 0; i < sclRefs.size(); ++i) {
224  // Find the seeds
225  LogDebug("ElectronSeedGenerator") << "new cluster, calling seedsFromThisCluster";
226  seedsFromThisCluster(sclRefs[i], beamSpot, vertices, out);
227  }
228 
229  LogDebug("ElectronSeedGenerator") << ": For event " << e.id();
230  LogDebug("ElectronSeedGenerator") << "Nr of superclusters after filter: " << sclRefs.size()
231  << ", no. of ElectronSeeds found = " << out.size();
232 }
233 
235  reco::BeamSpot const &beamSpot,
236  std::vector<reco::Vertex> const *vertices,
238  float clusterEnergy = seedCluster->energy();
239  GlobalPoint clusterPos(seedCluster->position().x(), seedCluster->position().y(), seedCluster->position().z());
240  reco::ElectronSeed::CaloClusterRef caloCluster(seedCluster);
241 
242  if (dynamicPhiRoad_) {
243  float clusterEnergyT = clusterEnergy / cosh(EleRelPoint(clusterPos, beamSpot.position()).eta());
244 
245  float deltaPhi1;
246  if (clusterEnergyT < lowPtThresh_) {
247  deltaPhi1 = deltaPhi1Low_;
248  } else if (clusterEnergyT > highPtThresh_) {
249  deltaPhi1 = deltaPhi1High_;
250  } else {
251  deltaPhi1 = dPhi1Coef1_ + dPhi1Coef2_ / clusterEnergyT;
252  }
253 
254  float ephimin1 = -deltaPhi1 * sizeWindowENeg_;
255  float ephimax1 = deltaPhi1 * (1. - sizeWindowENeg_);
256  float pphimin1 = -deltaPhi1 * (1. - sizeWindowENeg_);
257  float pphimax1 = deltaPhi1 * sizeWindowENeg_;
258 
259  float phimin2B = -deltaPhi2B_ / 2.;
260  float phimax2B = deltaPhi2B_ / 2.;
261  float phimin2F = -deltaPhi2F_ / 2.;
262  float phimax2F = deltaPhi2F_ / 2.;
263 
264  electronMatcher_.set1stLayer(ephimin1, ephimax1);
265  positronMatcher_.set1stLayer(pphimin1, pphimax1);
266  electronMatcher_.set2ndLayer(phimin2B, phimax2B, phimin2F, phimax2F);
267  positronMatcher_.set2ndLayer(phimin2B, phimax2B, phimin2F, phimax2F);
268  }
269 
270  if (!useRecoVertex_) // here use the beam spot position
271  {
272  double sigmaZ = beamSpot.sigmaZ();
273  double sigmaZ0Error = beamSpot.sigmaZ0Error();
274  double sq = sqrt(sigmaZ * sigmaZ + sigmaZ0Error * sigmaZ0Error);
275  double myZmin1 = beamSpot.position().z() - nSigmasDeltaZ1_ * sq;
276  double myZmax1 = beamSpot.position().z() + nSigmasDeltaZ1_ * sq;
277 
278  GlobalPoint vertexPos;
279  ele_convert(beamSpot.position(), vertexPos);
280 
281  electronMatcher_.set1stLayerZRange(myZmin1, myZmax1);
282  positronMatcher_.set1stLayerZRange(myZmin1, myZmax1);
283 
284  // try electron
285  auto elePixelSeeds = electronMatcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, -1.);
286  seedsFromTrajectorySeeds(elePixelSeeds, caloCluster, out, false);
287  // try positron
288  auto posPixelSeeds = positronMatcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, 1.);
289  seedsFromTrajectorySeeds(posPixelSeeds, caloCluster, out, true);
290 
291  } else if (vertices) // here we use the reco vertices
292  {
293  for (auto const &vertex : *vertices) {
294  GlobalPoint vertexPos(vertex.position().x(), vertex.position().y(), vertex.position().z());
295  double myZmin1, myZmax1;
296  if (vertexPos.z() == beamSpot.position().z()) { // in case vetex not found
297  double sigmaZ = beamSpot.sigmaZ();
298  double sigmaZ0Error = beamSpot.sigmaZ0Error();
299  double sq = sqrt(sigmaZ * sigmaZ + sigmaZ0Error * sigmaZ0Error);
300  myZmin1 = beamSpot.position().z() - nSigmasDeltaZ1_ * sq;
301  myZmax1 = beamSpot.position().z() + nSigmasDeltaZ1_ * sq;
302  } else { // a vertex has been recoed
303  myZmin1 = vertex.position().z() - deltaZ1WithVertex_;
304  myZmax1 = vertex.position().z() + deltaZ1WithVertex_;
305  }
306 
307  electronMatcher_.set1stLayerZRange(myZmin1, myZmax1);
308  positronMatcher_.set1stLayerZRange(myZmin1, myZmax1);
309 
310  // try electron
311  auto elePixelSeeds = electronMatcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, -1.);
312  seedsFromTrajectorySeeds(elePixelSeeds, caloCluster, out, false);
313  // try positron
314  auto posPixelSeeds = positronMatcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, 1.);
315  seedsFromTrajectorySeeds(posPixelSeeds, caloCluster, out, true);
316  }
317  }
318 }
#define LogDebug(id)
unsigned long long cacheIdentifier() const
std::pair< const_iterator, const_iterator > range
void seedsFromThisCluster(edm::Ref< reco::SuperClusterCollection > seedCluster, reco::BeamSpot const &beamSpot, std::vector< reco::Vertex > const *vertices, reco::ElectronSeedCollection &out)
double sigmaZ0Error() const
error on sigma z
Definition: BeamSpot.h:92
static const TGPicture * info(bool iBackgroundIsBlack)
const edm::EDGetTokenT< std::vector< reco::Vertex > > verticesTag_
void setupES(const edm::EventSetup &setup)
void setPosAttributes(const float dRZ2=std::numeric_limits< float >::infinity(), const float dPhi2=std::numeric_limits< float >::infinity(), const float dRZ1=std::numeric_limits< float >::infinity(), const float dPhi1=std::numeric_limits< float >::infinity())
Definition: ElectronSeed.cc:99
#define nullptr
edm::ESHandle< TrackerGeometry > trackerGeometry_
const CaloClusterRef & caloCluster() const
Definition: ElectronSeed.h:94
unsigned long long cacheIDMagField_
Definition: Electron.h:6
unsigned long long cacheIDTrkGeom_
float dRZPos(size_t hitNr) const
Definition: ElectronSeed.h:106
void set2ndLayer(float dummyphi2minB, float dummyphi2maxB, float dummyphi2minF, float dummyphi2maxF)
const std::vector< const TrajectorySeedCollection * > * initialSeedCollectionVector_
void set1stLayerZRange(float zmin1, float zmax1)
void run(edm::Event &, const edm::EventSetup &setup, const reco::SuperClusterRefVector &, const std::vector< const TrajectorySeedCollection * > &seedsV, reco::ElectronSeedCollection &)
size_t key() const
Definition: RefToBase.h:219
recHitContainer::const_iterator const_iterator
const edm::EDGetTokenT< reco::BeamSpot > beamSpotTag_
T sqrt(T t)
Definition: SSEVec.h:19
const double infinity
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:334
std::vector< ElectronSeed > ElectronSeedCollection
collection of ElectronSeed objects
const float dPhi1
const float dRz1
const float dRz2
std::unique_ptr< PropagatorWithMaterial > propagator_
const float dPhi2
PixelHitMatcher electronMatcher_
void set1stLayer(float dummyphi1min, float dummyphi1max)
PixelHitMatcher positronMatcher_
void setNegAttributes(const float dRZ2=std::numeric_limits< float >::infinity(), const float dPhi2=std::numeric_limits< float >::infinity(), const float dRZ1=std::numeric_limits< float >::infinity(), const float dPhi1=std::numeric_limits< float >::infinity())
Definition: ElectronSeed.cc:86
double sigmaZ() const
sigma z
Definition: BeamSpot.h:76
range recHits() const
ElectronSeedGenerator(const edm::ParameterSet &, const Tokens &)
void ele_convert(const Type1 &obj1, Type2 &obj2)
void setCaloCluster(const CaloClusterRef &clus)
Definition: ElectronSeed.h:86
edm::EventID id() const
Definition: EventBase.h:59
unsigned int nHits() const
T get() const
Definition: EventSetup.h:73
unsigned int hitsMask() const
Definition: ElectronSeed.cc:47
float dRZNeg(size_t hitNr) const
Definition: ElectronSeed.h:107
size_type size() const
Size of the RefVector.
Definition: RefVector.h:102
const Point & position() const
position
Definition: BeamSpot.h:59
edm::ESHandle< MagneticField > magField_
float dPhiNeg(size_t hitNr) const
Definition: ElectronSeed.h:103
T const * product() const
Definition: ESHandle.h:86
void setES(const MagneticField *, const TrackerGeometry *trackerGeometry)
float dPhiPos(size_t hitNr) const
Definition: ElectronSeed.h:104
void initTwoHitSeed(const unsigned char hitMask)
Definition: ElectronSeed.cc:60