CMS 3D CMS Logo

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