CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCComparatorDigiFitter.cc
Go to the documentation of this file.
4 
5 namespace {
6  // CSC LCT patterns
7  // the number quotes the distance to the center
8 
9  // pid=0: no pattern found
10  const std::vector<std::vector<int> > pat0delta(CSCConstants::NUM_LAYERS);
11 
12  // pid=1: layer-OR trigger
13  const std::vector<std::vector<int> > pat1delta{{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5},
14  {-2, -1, 0, 1, 2},
15  {0},
16  {-2, -1, 0, 1, 2},
17  {-4, -3, -2, -1, 0, 1, 2, 3, 4},
18  {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}};
19 
20  // pid=2: right-bending (large)
21  const std::vector<std::vector<int> > pat2delta{{3, 4, 5}, {1, 2}, {0}, {-2, -1, 0}, {-4, -3, -2}, {-5, -4, -3}};
22 
23  // pid=3: left-bending (large)
24  const std::vector<std::vector<int> > pat3delta{{-5, -4, -3}, {-2, -1}, {0}, {0, 1, 2}, {2, 3, 4}, {3, 4, 5}};
25 
26  // pid=4: right-bending (medium)
27  const std::vector<std::vector<int> > pat4delta{{2, 3, 4}, {1, 2}, {0}, {-2, -1}, {-4, -3, -2}, {-4, -3, -2}
28 
29  };
30 
31  // pid=5: left-bending (medium)
32  const std::vector<std::vector<int> > pat5delta{{-4, -3, -2}, {-2, -1}, {0}, {1, 2}, {2, 3, 4}, {2, 3, 4}
33 
34  };
35 
36  // pid=6: right-bending (medium)
37  const std::vector<std::vector<int> > pat6delta{{1, 2, 3}, {0, 1}, {0}, {-1, 0}, {-2, -1}, {-3, -2, -1}};
38 
39  // pid=7: left-bending (medium)
40  const std::vector<std::vector<int> > pat7delta{{-3, -2, -1}, {-1, 0}, {0}, {0, 1}, {1, 2}, {1, 2, 3}};
41 
42  // pid=8: right-bending (small)
43  const std::vector<std::vector<int> > pat8delta{{0, 1, 2}, {0, 1}, {0}, {-1, 0}, {-2, -1, 0}, {-2, -1, 0}};
44 
45  // pid=9: left-bending (small)
46  const std::vector<std::vector<int> > pat9delta{{-2, -1, 0}, {-1, 0}, {0}, {0, 1}, {0, 1, 2}, {0, 1, 2}};
47 
48  // pid=A: straight-through
49  const std::vector<std::vector<int> > patAdelta{{-1, 0, 1}, {0}, {0}, {0}, {-1, 0, 1}, {-1, 0, 1}};
50 
51  const std::vector<std::vector<std::vector<int> > > patIndexToPatternDelta{pat0delta,
52  pat1delta,
53  pat2delta,
54  pat3delta,
55  pat4delta,
56  pat5delta,
57  pat6delta,
58  pat7delta,
59  pat8delta,
60  pat9delta,
61  patAdelta};
62 } // namespace
63 
65  const CSCCorrelatedLCTDigi& stub,
66  const CSCComparatorDigiCollection& hCSCComparators) {
67  // fetch the CSC comparator digis in this chamber
68  for (int iLayer = 1; iLayer <= CSCConstants::NUM_LAYERS; ++iLayer) {
69  const CSCDetId layerId(ch_id.endcap(), ch_id.station(), ch_id.ring(), ch_id.chamber(), iLayer);
70 
71  // get the digis per layer
72  const auto& compRange = hCSCComparators.get(layerId);
74 
75  for (auto compDigiItr = compRange.first; compDigiItr != compRange.second; compDigiItr++) {
76  const auto& compDigi = *compDigiItr;
77 
78  //if (stub.getTimeBin() < 4 or stub.getTimeBin() > 8) continue;
79  const int stubHalfStrip(compDigi.getHalfStrip());
80 
81  // these comparator digis never fit the pattern anyway!
82  if (std::abs(stubHalfStrip - stub.getStrip()) > 5)
83  continue;
84 
85  // check if this comparator digi fits the pattern
86  if (comparatorInLCTPattern(stub.getStrip(), stub.getPattern(), iLayer, stubHalfStrip)) {
87  compDigis.push_back(compDigi);
88  }
89  }
90  compDigisIds_.emplace_back(layerId, compDigis);
91  }
92 }
93 
95  const auto& cscChamber = cscGeometry_->chamber(ch_id);
96 
97  // get the z and phi positions of the comparator digis
98  float radius_ = 0.0;
99 
100  // loop on all matching digis
101  for (const auto& p : compDigisIds_) {
102  const auto& detId = p.first;
103 
104  float phi_tmp = 0.0;
105  float radius_tmp = 0.0;
106  float z_tmp = 0.0;
107 
108  // ignore layers with no digis
109  if (p.second.empty())
110  continue;
111 
112  // loop on all matching digis in this layer
113  for (const auto& hit : p.second) {
114  const float fractional_strip = hit.getFractionalStrip();
115  const auto& layer_geo = cscChamber->layer(detId.layer())->geometry();
116  const float wire = layer_geo->middleWireOfGroup(stub.getKeyWG() + 1);
117 
118  // get the phi of each comparator digi
119  const LocalPoint& csc_intersect = layer_geo->intersectionOfStripAndWire(fractional_strip, wire);
120  const GlobalPoint& csc_gp = cscGeometry_->idToDet(detId)->surface().toGlobal(csc_intersect);
121  const float gpphi = csc_gp.phi();
122 
123  // normalize phi values according to first one
124  if (!phis_.empty() and gpphi > 0 and phis_[0] < 0 and (gpphi - phis_[0]) > M_PI)
125  phi_tmp += (gpphi - 2 * M_PI);
126  else if (!phis_.empty() and gpphi < 0 and phis_[0] > 0 and (gpphi - phis_[0]) < -M_PI)
127  phi_tmp += (gpphi + 2 * M_PI);
128  else
129  phi_tmp += (csc_gp.phi());
130 
131  z_tmp = csc_gp.z();
132  radius_tmp += csc_gp.perp();
133  }
134 
135  //in case there are more than one comparator digis in one layer
136  radius_tmp = radius_tmp / (p.second).size();
137  radius_ += radius_tmp;
138 
139  zs_.push_back(z_tmp);
140  ezs_.push_back(0);
141 
142  phi_tmp = phi_tmp / (p.second).size();
143  phis_.push_back(phi_tmp);
144  // assume that the charge is flat distributed across the half-strip
145  // this is only approximately valid, but good enough for now
146  ephis_.push_back(cscHalfStripWidth(detId) / sqrt(12));
147  }
148 }
149 
151  const CSCCorrelatedLCTDigi& stub,
152  const CSCComparatorDigiCollection& hCSCComparators,
153  std::vector<float>& fit_phi_layers,
154  std::vector<float>& fit_z_layers,
155  float& keyRadius) {
156  // clear fit results
157  fit_phi_layers.clear();
158  fit_z_layers.clear();
159  keyRadius = 0;
160 
161  // first, match the comparator digis to the LCT
162  matchingComparatorDigisLCT(ch_id, stub, hCSCComparators);
163 
164  // second, get the coordinates
165  getComparatorDigiCoordinates(ch_id, stub);
166 
167  // get radius of the stub from key layer
168  const CSCDetId key_id(ch_id.endcap(), ch_id.station(), ch_id.ring(), ch_id.chamber(), CSCConstants::KEY_CLCT_LAYER);
169  const float fractional_strip = stub.getFractionalStrip();
170 
171  const auto& cscChamber = cscGeometry_->chamber(ch_id);
172  const auto& layer_geo = cscChamber->layer(CSCConstants::KEY_CLCT_LAYER)->geometry();
173 
174  // LCT::getKeyWG() also starts from 0
175  const float wire = layer_geo->middleWireOfGroup(stub.getKeyWG() + 1);
176  const LocalPoint& csc_intersect = layer_geo->intersectionOfStripAndWire(fractional_strip, wire);
177  const GlobalPoint& csc_gp = cscGeometry_->idToDet(key_id)->surface().toGlobal(csc_intersect);
178 
179  // get radius from key layer
180  if (useKeyRadius_)
181  radius_ = radius_ / phis_.size();
182  else
183  radius_ = csc_gp.perp();
184 
185  float alpha = -99., beta = 0.;
186  // do a fit to the comparator digis
188  if (phis_.size() <= 2 or std::abs(alpha) >= 99) {
189  alpha = csc_gp.phi();
190  beta = 0.0;
191  }
192 
193  // determine the pitch of the chamber
194  // option to discretize the pitch
195  float stripPhiPitch = layer_geo->stripPhiPitch();
196  if (nStripBits_)
197  stripPhiPitch = stripPhiPitch / nStripBits_;
198 
199  // get the fit results
200  // option to discretize the fitted phi value
201  keyRadius = radius_;
202 
203  for (int i = 0; i < CSCConstants::NUM_LAYERS; i++) {
204  const float fit_z = cscChamber->layer(i + 1)->centerOfStrip(20).z();
205  const float fit_phi = normalizedPhi(alpha + beta * fit_z);
206  fit_z_layers.push_back(fit_z);
207  fit_phi_layers.push_back(fit_phi);
208  if (nStripBits_)
209  fit_phi_layers.push_back((std::floor(fit_phi / stripPhiPitch) + 0.5) * stripPhiPitch);
210  }
211 }
212 
214  // if there are at least 3 hits in the chamber, do a linear fit to the
215  // comparator digi positions with the chi2 method
216  if (phis_.size() >= 3) {
217  float Sxx = 0, Sxy = 0, Sx = 0, Sy = 0, S = 0;
218  for (unsigned i = 0; i < phis_.size(); ++i) {
219  float sigma2_inv = 1. / ephis_[i] * ephis_[i];
220  Sxx += zs_[i] * zs_[i] * sigma2_inv;
221  Sxy += zs_[i] * phis_[i] * sigma2_inv;
222  Sx += zs_[i] * zs_[i] * sigma2_inv;
223  Sy += phis_[i] * sigma2_inv;
224  S += sigma2_inv;
225  }
226  float delta = S * Sxx - Sx * Sx;
227  alpha = (Sxx * Sy - Sx * Sxy) / delta;
228  beta = (S * Sxy - Sx * Sy) / delta;
229  } else {
230  alpha = -99;
231  beta = 0.0;
232  }
233 }
234 
236  // what is the chamber type?
237  int index = id.iChamberType() - 1;
238 
239  // calculate the half strip width of this chamber
240  return degrees_[index] * M_PI / 180. / (2. * strips_[index]);
241 }
242 
243 bool CSCComparatorDigiFitter::comparatorInLCTPattern(int keyStrip, int pattern, int layer, int halfStrip) const {
244  // get the (sub)pattern
245  const std::vector<int>& subpat = patIndexToPatternDelta[pattern].at(layer - 1);
246 
247  // due to comparator digi time extension in the CLCT processor we need to
248  // search a bigger region around the key HS. +/-1, 0 should be sufficient
249  const int halfStripDelta = halfStrip - keyStrip;
250  return (std::find(subpat.begin(), subpat.end(), halfStripDelta + 1) != subpat.end() or
251  std::find(subpat.begin(), subpat.end(), halfStripDelta) != subpat.end() or
252  std::find(subpat.begin(), subpat.end(), halfStripDelta - 1) != subpat.end());
253 }
size
Write out results.
int chamber() const
Definition: CSCDetId.h:62
int getStrip() const
return the key halfstrip from 0,159
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:81
const std::vector< int > strips_
T perp() const
Definition: PV3DBase.h:69
void getComparatorDigiCoordinates(const CSCDetId &ch_id, const CSCCorrelatedLCTDigi &stub)
const GeomDet * idToDet(DetId) const override
Definition: CSCGeometry.cc:91
constexpr T normalizedPhi(T phi)
Definition: normalizedPhi.h:8
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
std::vector< CSCComparatorDigi > CSCComparatorDigiContainer
float cscHalfStripWidth(const CSCDetId &id) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
const std::vector< float > degrees_
int endcap() const
Definition: CSCDetId.h:85
float getFractionalStrip() const
return the fractional strip. counts from 0.25
T sqrt(T t)
Definition: SSEVec.h:19
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void fit(const CSCDetId &ch_id, const CSCCorrelatedLCTDigi &, const CSCComparatorDigiCollection &, std::vector< float > &fit_phi_layers, std::vector< float > &fit_z_layers, float &keyRadius)
T z() const
Definition: PV3DBase.h:61
float middleWireOfGroup(int wireGroup) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
CSCComparatorDigiContainerIds compDigisIds_
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:30
void matchingComparatorDigisLCT(const CSCDetId &ch_id, const CSCCorrelatedLCTDigi &, const CSCComparatorDigiCollection &)
#define M_PI
int ring() const
Definition: CSCDetId.h:68
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:100
ESHandle< TrackerGeometry > geometry
const CSCGeometry * cscGeometry_
bool comparatorInLCTPattern(int keyStrip, int pattern, int layer, int halfStrip) const
int getPattern() const
return pattern
int station() const
Definition: CSCDetId.h:79
void calculateSlopeIntercept(float &alpha, float &beta)
alpha
zGenParticlesMatch = cms.InputTag(""),
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:44
int getKeyWG() const
return the key wire group. counts from 0.