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 
28 
29 #include <vector>
30 #include <utility>
31 
32 namespace {
33 
34  bool equivalent(const TrajectorySeed &s1, const TrajectorySeed &s2) {
35  if (s1.nHits() != s2.nHits())
36  return false;
37 
40  for (auto i1 = r1.begin(), i2 = r2.begin(); i1 != r1.end(); ++i1, ++i2) {
41  if (!i1->isValid() || !i2->isValid())
42  return false;
43  if (i1->geographicalId() != i2->geographicalId())
44  return false;
45  if (!(i1->localPosition() == i2->localPosition()))
46  return false;
47  }
48 
49  return true;
50  }
51 
52  void addSeed(reco::ElectronSeed &seed, const SeedWithInfo *info, bool positron, reco::ElectronSeedCollection &out) {
53  if (!info) {
54  out.emplace_back(seed);
55  return;
56  }
57 
58  if (positron) {
59  seed.setPosAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
60  } else {
61  seed.setNegAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
62  }
63  for (auto &res : out) {
64  if ((seed.caloCluster().key() == res.caloCluster().key()) && (seed.hitsMask() == res.hitsMask()) &&
65  equivalent(seed, res)) {
66  if (positron) {
67  if (res.dRZPos(1) == std::numeric_limits<float>::infinity() &&
69  res.setPosAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
70  seed.setNegAttributes(res.dRZNeg(1), res.dPhiNeg(1), res.dRZNeg(0), res.dPhiNeg(0));
71  break;
72  } else {
73  if (res.dRZPos(1) != std::numeric_limits<float>::infinity()) {
74  if (res.dRZPos(1) != seed.dRZPos(1)) {
75  edm::LogWarning("ElectronSeedGenerator|BadValue")
76  << "this similar old seed already has another dRz2Pos"
77  << "\nold seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)res.hitsMask() << "/"
78  << res.dRZNeg(1) << "/" << res.dPhiNeg(1) << "/" << res.dRZPos(1) << "/" << res.dPhiPos(1)
79  << "\nnew seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)seed.hitsMask() << "/"
80  << seed.dRZNeg(1) << "/" << seed.dPhiNeg(1) << "/" << seed.dRZPos(1) << "/" << seed.dPhiPos(1);
81  }
82  }
83  }
84  } else {
85  if (res.dRZNeg(1) == std::numeric_limits<float>::infinity() &&
87  res.setNegAttributes(info->dRz2, info->dPhi2, info->dRz1, info->dPhi1);
88  seed.setPosAttributes(res.dRZPos(1), res.dPhiPos(1), res.dRZPos(0), res.dPhiPos(0));
89  break;
90  } else {
91  if (res.dRZNeg(1) != std::numeric_limits<float>::infinity()) {
92  if (res.dRZNeg(1) != seed.dRZNeg(1)) {
93  edm::LogWarning("ElectronSeedGenerator|BadValue")
94  << "this old seed already has another dRz2"
95  << "\nold seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)res.hitsMask() << "/"
96  << res.dRZNeg(1) << "/" << res.dPhiNeg(1) << "/" << res.dRZPos(1) << "/" << res.dPhiPos(1)
97  << "\nnew seed mask/dRz2/dPhi2/dRz2Pos/dPhi2Pos: " << (unsigned int)seed.hitsMask() << "/"
98  << seed.dRZNeg(1) << "/" << seed.dPhiNeg(1) << "/" << seed.dRZPos(1) << "/" << seed.dPhiPos(1);
99  }
100  }
101  }
102  }
103  }
104  }
105 
106  out.emplace_back(seed);
107  }
108 
109  void seedsFromTrajectorySeeds(const std::vector<SeedWithInfo> &pixelSeeds,
110  const reco::ElectronSeed::CaloClusterRef &cluster,
112  bool positron) {
113  if (!pixelSeeds.empty()) {
114  LogDebug("ElectronSeedGenerator") << "Compatible " << (positron ? "positron" : "electron") << " seeds found.";
115  }
116 
117  std::vector<SeedWithInfo>::const_iterator s;
118  for (s = pixelSeeds.begin(); s != pixelSeeds.end(); s++) {
119  reco::ElectronSeed seed(s->seed);
120  seed.setCaloCluster(cluster);
121  seed.initTwoHitSeed(s->hitsMask);
122  addSeed(seed, &*s, positron, out);
123  }
124  }
125 
126 } // namespace
127 
131  : dynamicPhiRoad_(pset.getParameter<bool>("dynamicPhiRoad")),
132  verticesTag_(ts.token_vtx),
133  beamSpotTag_(ts.token_bs),
134  magFieldToken_{cc.esConsumes()},
135  trackerGeometryToken_{cc.esConsumes()},
136  lowPtThresh_(pset.getParameter<double>("LowPtThreshold")),
137  highPtThresh_(pset.getParameter<double>("HighPtThreshold")),
138  nSigmasDeltaZ1_(pset.getParameter<double>("nSigmasDeltaZ1")),
139  deltaZ1WithVertex_(pset.getParameter<double>("deltaZ1WithVertex")),
140  sizeWindowENeg_(pset.getParameter<double>("SizeWindowENeg")),
141  deltaPhi1Low_(pset.getParameter<double>("DeltaPhi1Low")),
142  deltaPhi1High_(pset.getParameter<double>("DeltaPhi1High")),
143  // so that deltaPhi1 = dPhi1Coef1_ + dPhi1Coef2_/clusterEnergyT
144  dPhi1Coef2_(dynamicPhiRoad_ ? (deltaPhi1Low_ - deltaPhi1High_) / (1. / lowPtThresh_ - 1. / highPtThresh_) : 0.),
145  dPhi1Coef1_(dynamicPhiRoad_ ? deltaPhi1Low_ - dPhi1Coef2_ / lowPtThresh_ : 0.),
146  // use of reco vertex
147  useRecoVertex_(pset.getParameter<bool>("useRecoVertex")),
148  // new B/F configurables
149  deltaPhi2B_(pset.getParameter<double>("DeltaPhi2B")),
150  deltaPhi2F_(pset.getParameter<double>("DeltaPhi2F")),
151  phiMin2B_(-pset.getParameter<double>("PhiMax2B")),
152  phiMin2F_(-pset.getParameter<double>("PhiMax2F")),
153  phiMax2B_(pset.getParameter<double>("PhiMax2B")),
154  phiMax2F_(pset.getParameter<double>("PhiMax2F")),
155  matcher_(pset.getParameter<double>("ePhiMin1"),
156  pset.getParameter<double>("ePhiMax1"),
157  phiMin2B_,
158  phiMax2B_,
159  phiMin2F_,
160  phiMax2F_,
161  pset.getParameter<double>("z2MaxB"),
162  pset.getParameter<double>("r2MaxF"),
163  pset.getParameter<double>("rMaxI"),
164  useRecoVertex_) {}
165 
167  auto newMagField = magneticFieldWatcher_.check(setup);
168  auto newTrackerGeom = trackerGeometryWatcher_.check(setup);
169  if (newMagField || newTrackerGeom) {
171  }
172 }
173 
175  const reco::SuperClusterRefVector &sclRefs,
176  const std::vector<const TrajectorySeedCollection *> &seedsV,
179 
180  // get the beamspot from the Event:
181  auto const &beamSpot = e.get(beamSpotTag_);
182 
183  // if required get the vertices
184  std::vector<reco::Vertex> const *vertices = nullptr;
185  if (useRecoVertex_)
186  vertices = &e.get(verticesTag_);
187 
188  for (unsigned int i = 0; i < sclRefs.size(); ++i) {
189  // Find the seeds
190  LogDebug("ElectronSeedGenerator") << "new cluster, calling seedsFromThisCluster";
192  }
193 
194  LogDebug("ElectronSeedGenerator") << ": For event " << e.id();
195  LogDebug("ElectronSeedGenerator") << "Nr of superclusters after filter: " << sclRefs.size()
196  << ", no. of ElectronSeeds found = " << out.size();
197 }
198 
200  reco::BeamSpot const &beamSpot,
201  std::vector<reco::Vertex> const *vertices,
203  float clusterEnergy = seedCluster->energy();
204  GlobalPoint clusterPos(seedCluster->position().x(), seedCluster->position().y(), seedCluster->position().z());
205  reco::ElectronSeed::CaloClusterRef caloCluster(seedCluster);
206 
207  if (dynamicPhiRoad_) {
208  float clusterEnergyT = clusterEnergy / cosh(EleRelPoint(clusterPos, beamSpot.position()).eta());
209 
210  float deltaPhi1;
211  if (clusterEnergyT < lowPtThresh_) {
212  deltaPhi1 = deltaPhi1Low_;
213  } else if (clusterEnergyT > highPtThresh_) {
214  deltaPhi1 = deltaPhi1High_;
215  } else {
216  deltaPhi1 = dPhi1Coef1_ + dPhi1Coef2_ / clusterEnergyT;
217  }
218 
219  matcher_.set1stLayer(-deltaPhi1 * sizeWindowENeg_, deltaPhi1 * (1. - sizeWindowENeg_));
221  }
222 
223  if (!useRecoVertex_) // here use the beam spot position
224  {
225  double sigmaZ = beamSpot.sigmaZ();
226  double sigmaZ0Error = beamSpot.sigmaZ0Error();
227  double sq = sqrt(sigmaZ * sigmaZ + sigmaZ0Error * sigmaZ0Error);
228  double myZmin1 = beamSpot.position().z() - nSigmasDeltaZ1_ * sq;
229  double myZmax1 = beamSpot.position().z() + nSigmasDeltaZ1_ * sq;
230 
231  GlobalPoint vertexPos;
232  ele_convert(beamSpot.position(), vertexPos);
233 
234  matcher_.set1stLayerZRange(myZmin1, myZmax1);
235 
236  // try electron
237  auto elePixelSeeds = matcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, -1.);
238  seedsFromTrajectorySeeds(elePixelSeeds, caloCluster, out, false);
239  // try positron
240  auto posPixelSeeds = matcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, 1.);
241  seedsFromTrajectorySeeds(posPixelSeeds, caloCluster, out, true);
242 
243  } else if (vertices) // here we use the reco vertices
244  {
245  for (auto const &vertex : *vertices) {
246  GlobalPoint vertexPos(vertex.position().x(), vertex.position().y(), vertex.position().z());
247  double myZmin1, myZmax1;
248  if (vertexPos.z() == beamSpot.position().z()) { // in case vetex not found
249  double sigmaZ = beamSpot.sigmaZ();
250  double sigmaZ0Error = beamSpot.sigmaZ0Error();
251  double sq = sqrt(sigmaZ * sigmaZ + sigmaZ0Error * sigmaZ0Error);
252  myZmin1 = beamSpot.position().z() - nSigmasDeltaZ1_ * sq;
253  myZmax1 = beamSpot.position().z() + nSigmasDeltaZ1_ * sq;
254  } else { // a vertex has been recoed
255  myZmin1 = vertex.position().z() - deltaZ1WithVertex_;
256  myZmax1 = vertex.position().z() + deltaZ1WithVertex_;
257  }
258 
259  matcher_.set1stLayerZRange(myZmin1, myZmax1);
260 
261  // try electron
262  auto elePixelSeeds = matcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, -1.);
263  seedsFromTrajectorySeeds(elePixelSeeds, caloCluster, out, false);
264  // try positron
265  auto posPixelSeeds = matcher_(*initialSeedCollectionVector_, clusterPos, vertexPos, clusterEnergy, 1.);
266  seedsFromTrajectorySeeds(posPixelSeeds, caloCluster, out, true);
267  }
268  }
269 }
void run(edm::Event &, const reco::SuperClusterRefVector &, const std::vector< const TrajectorySeedCollection *> &seedsV, reco::ElectronSeedCollection &)
void seedsFromThisCluster(edm::Ref< reco::SuperClusterCollection > seedCluster, reco::BeamSpot const &beamSpot, std::vector< reco::Vertex > const *vertices, reco::ElectronSeedCollection &out)
static const TGPicture * info(bool iBackgroundIsBlack)
const edm::EDGetTokenT< std::vector< reco::Vertex > > verticesTag_
void setupES(const edm::EventSetup &setup)
RecHitRange recHits() const
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > trackerGeometryToken_
uint32_t cc[maxCellsPerHit]
Definition: gpuFishbone.h:49
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magFieldToken_
Definition: Electron.h:6
void set2ndLayer(float dummyphi2minB, float dummyphi2maxB, float dummyphi2minF, float dummyphi2maxF)
const std::vector< const TrajectorySeedCollection * > * initialSeedCollectionVector_
void set1stLayerZRange(float zmin1, float zmax1)
unsigned int nHits() const
const edm::EDGetTokenT< reco::BeamSpot > beamSpotTag_
T sqrt(T t)
Definition: SSEVec.h:19
const double infinity
std::vector< ElectronSeed > ElectronSeedCollection
collection of ElectronSeed objects
size_type size() const
Size of the RefVector.
Definition: RefVector.h:102
void set1stLayer(float dummyphi1min, float dummyphi1max)
void ele_convert(const Type1 &obj1, Type2 &obj2)
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
ElectronSeedGenerator(const edm::ParameterSet &, const Tokens &, edm::ConsumesCollector &&)
Log< level::Warning, false > LogWarning
edm::ESWatcher< TrackerDigiGeometryRecord > trackerGeometryWatcher_
edm::ESWatcher< IdealMagneticFieldRecord > magneticFieldWatcher_
void setES(MagneticField const &, TrackerGeometry const &trackerGeometry)
#define LogDebug(id)