CMS 3D CMS Logo

CSCCathodeLCTAnalyzer.cc
Go to the documentation of this file.
1 
12 
15 
19 
20 using namespace std;
21 
22 //-----------------
23 // Static variables
24 //-----------------
25 
28 
29 vector<CSCCathodeLayerInfo> CSCCathodeLCTAnalyzer::getSimInfo(
30  const CSCCLCTDigi& clct, const CSCDetId& clctId,
31  const CSCComparatorDigiCollection* compdc,
32  const edm::PSimHitContainer* allSimHits) {
33  // Fills vector of CSCCathodeLayerInfo objects. There can be up to 6 such
34  // objects (one per layer); they contain the list of comparator digis used to
35  // build a given CLCT, and the list of associated (closest) SimHits.
36  // Filling is done in two steps: first, we construct the list of comparator
37  // digis; next, find associated SimHits.
38  vector<CSCCathodeLayerInfo> clctInfo = lctDigis(clct, clctId, compdc);
39 
40  // Sanity checks.
41  if (clctInfo.size() > CSCConstants::NUM_LAYERS) {
42  throw cms::Exception("CSCCathodeLCTAnalyzer")
43  << "+++ Number of CSCCathodeLayerInfo objects, " << clctInfo.size()
44  << ", exceeds max expected, " << CSCConstants::NUM_LAYERS << " +++\n";
45  }
46  // not a good check for high PU
47  //if (clctInfo.size() != (unsigned)clct.getQuality()) {
48  // edm::LogWarning("L1CSCTPEmulatorWrongValues")
49  // << "+++ Warning: mismatch between CLCT quality, " << clct.getQuality()
50  // << ", and the number of layers with digis, " << clctInfo.size()
51  // << ", in clctInfo! +++\n";
52  //}
53 
54  // Find the closest SimHit to each Digi.
55  vector<CSCCathodeLayerInfo>::iterator pcli;
56  for (pcli = clctInfo.begin(); pcli != clctInfo.end(); pcli++) {
57  digiSimHitAssociator(*pcli, allSimHits);
58  }
59 
60  return clctInfo;
61 }
62 
63 vector<CSCCathodeLayerInfo> CSCCathodeLCTAnalyzer::lctDigis(
64  const CSCCLCTDigi& clct, const CSCDetId& clctId,
65  const CSCComparatorDigiCollection* compdc) {
66  // Function to find a list of ComparatorDigis used to create an LCT.
67  // The list of ComparatorDigis is stored in a class called CSCLayerInfo which
68  // contains the layerId's of the stored ComparatorDigis as well as the actual
69  // digis themselves.
70  int hfstripDigis[CSCConstants::NUM_HALF_STRIPS];
72  int digiNum[CSCConstants::MAX_NUM_STRIPS];
73  int digiId = -999;
74  CSCCathodeLayerInfo tempInfo;
75  vector<CSCCathodeLayerInfo> vectInfo;
76 
77  // Inquire the clct for its key half-strip, strip type and pattern number.
78  int clct_keystrip = clct.getKeyStrip();
79  int clct_stripType = clct.getStripType();
80  int clct_pattern = clct.getPattern();
81  int clct_bx = clct.getBX();
82 
83  // Re-scale the key di-strip number to the count used in the search.
84  if (clct_stripType == 0) clct_keystrip /= 4;
85 
86  if (debug) {
87  char stype = (clct_stripType == 0) ? 'D' : 'H';
88  LogDebug("lctDigis")
89  << "\nlctDigis: CLCT keystrip = " << clct_keystrip
90  << " (" << stype << ")" << " pattern = " << clct_pattern << "; Id:"
91  << " endcap " << clctId.endcap() << ", station " << clctId.station()
92  << ", ring " << clctId.ring() << ", chamber " << clctId.chamber();
93  }
94 
95  // 'Staggering' for key layer. Needed for TMB07 version.
96  const int key_layer = 3; // counting from 1.
97  CSCDetId layerId(clctId.endcap(), clctId.station(), clctId.ring(),
98  clctId.chamber(), key_layer);
99  const CSCLayer* csclayer = geom_->layer(layerId);
100  int key_stagger = (csclayer->geometry()->stagger()+1)/2;
101 
102  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
103  // Clear tempInfo values every iteration before using.
104  tempInfo.clear();
105 
106  // @ Switch to maps eventually
107  vector<CSCComparatorDigi> digiMap;
108  int digi_num = 0;
109  for (int i_hstrip = 0; i_hstrip < CSCConstants::NUM_HALF_STRIPS;
110  i_hstrip++) {
111  hfstripDigis[i_hstrip] = -999;
112  }
113  for (int i_strip = 0; i_strip < CSCConstants::MAX_NUM_STRIPS; i_strip++) {
114  time[i_strip] = -999;
115  comp[i_strip] = 0;
116  digiNum[i_strip] = -999;
117  }
118 
119  // CLCTs belong to a chamber, so their layerId is 0. Comparator digis
120  // belong to layers, so in order to access them we need to add layer
121  // number to CLCT's endcap, chamber, etc.
122  CSCDetId layerId(clctId.endcap(), clctId.station(), clctId.ring(),
123  clctId.chamber(), i_layer+1);
124 
125  // Preselection of Digis: right layer and bx.
126  digi_num += preselectDigis(clct_bx, layerId, compdc, digiMap,
127  hfstripDigis,
128  time, comp, digiNum);
129 
130  // In case of ME1/1, one can also look for digis in ME1/A.
131  // Skip them for now since the resolution of CLCTs in ME1/A is
132  // terrible (strips are ganged; channel numbers translated to be
133  // in CFEB=4).
134  if (doME1A) {
135  if (clctId.station() == 1 && clctId.ring() == 1) {
136  CSCDetId layerId_me1a(clctId.endcap(), clctId.station(), 4,
137  clctId.chamber(), i_layer+1);
138  digi_num += preselectDigis(clct_bx, layerId_me1a, compdc, digiMap,
139  hfstripDigis,
140  time, comp, digiNum);
141  }
142  }
143 
144  // Loop over all the strips in a pattern.
145  int max_pattern_strips, layer, strip;
146  max_pattern_strips = CSCConstants::MAX_HALFSTRIPS_IN_PATTERN;
147  for (int i_strip = 0; i_strip < max_pattern_strips; i_strip++) {
148  layer = CSCCathodeLCTProcessor::pattern2007[clct_pattern][i_strip];
149  if (layer == i_layer) {
150  strip = clct_keystrip + key_stagger +
152  if (strip >= 0 && strip < CSCConstants::NUM_HALF_STRIPS) {
153  digiId = hfstripDigis[strip];
154  // halfstripDigis contains the digi numbers
155  // that were carried through the different transformations
156  // to keystrip. -999 means there was no Digi.
157  if (digiId >= 0) {
158  tempInfo.setId(layerId); // store the layer of this object
159  tempInfo.addComponent(digiMap[digiId]); // and the RecDigi
160  if (debug) LogTrace("lctDigis")
161  << " Digi on CLCT: strip/comp/time " << digiMap[digiId];
162  }
163  }
164  }
165  }
166 
167  // Save results for each non-empty layer.
168  if (tempInfo.getId().layer() != 0) {
169  vectInfo.push_back(tempInfo);
170  }
171  }
172  return vectInfo;
173 }
174 
176  const CSCDetId& layerId,
177  const CSCComparatorDigiCollection* compdc,
178  vector<CSCComparatorDigi>& digiMap,
179  int hfstripDigis[CSCConstants::NUM_HALF_STRIPS],
181  int comp[CSCConstants::MAX_NUM_STRIPS],
182  int digiNum[CSCConstants::MAX_NUM_STRIPS]) {
183  // Preselection of Digis: right layer and bx.
184  int digi_num = 0;
185 
186  // Parameters defining time window for accepting hits; should come from
187  // configuration file eventually.
188  const int fifo_tbins = 12;
189  const int hit_persist = 4;
190  const int drift_delay = 2;
191 
192  // 'Staggering' for this layer.
193  const CSCLayer* csclayer = geom_->layer(layerId);
194  int stagger = (csclayer->geometry()->stagger()+1)/2;
195 
196  bool me1a = (layerId.station() == 1) && (layerId.ring() == 4);
197 
198  const CSCComparatorDigiCollection::Range rcompd = compdc->get(layerId);
199  for (CSCComparatorDigiCollection::const_iterator digiIt = rcompd.first;
200  digiIt != rcompd.second; ++digiIt) {
201  if (debug) LogDebug("lctDigis")
202  << "Comparator digi: layer " << layerId.layer()-1
203  << " strip/comparator/time =" << (*digiIt);
204 
205  if ((*digiIt).getComparator() == 0 || (*digiIt).getComparator() == 1) {
206  int bx_time = (*digiIt).getTimeBin();
207  if (bx_time >= 0 && bx_time < fifo_tbins) {
208 
209  // Do not use digis which could not have contributed to a given CLCT.
210  int latch_bx = clct_bx + drift_delay;
211  if (bx_time <= latch_bx-hit_persist || bx_time > latch_bx) {
212  if (debug) LogDebug("lctDigis")
213  << "Late comparator digi: layer " << layerId.layer()-1
214  << " strip/comparator/time =" << (*digiIt) << " skipping...";
215  continue;
216  }
217 
218  // If there is more than one digi on the same strip, pick the one
219  // which occurred earlier.
220  int i_strip = (*digiIt).getStrip() - 1; // starting from 0
221  if (me1a && i_strip < 16) {
222  // Move ME1/A comparators from CFEB=0 to CFEB=4 if this has not
223  // been done already.
224  i_strip += 64;
225  }
226 
227  if (time[i_strip] <= 0 || time[i_strip] > bx_time) {
228 
229  // @ Switch to maps; check for match in time.
230  int i_hfstrip = 2*i_strip + (*digiIt).getComparator() + stagger;
231  hfstripDigis[i_hfstrip] = digi_num;
232 
233  // Arrays for distrip stagger
234  comp[i_strip] = (*digiIt).getComparator();
235  time[i_strip] = bx_time;
236  digiNum[i_strip] = digi_num;
237 
238  if (debug) LogDebug("lctDigis")
239  << "digi_num = " << digi_num << " half-strip = " << i_hfstrip
240  << " strip = " << i_strip;
241  }
242  }
243  }
244  digiMap.push_back(*digiIt);
245  digi_num++;
246  }
247 
248  return digi_num;
249 }
250 
252  const edm::PSimHitContainer* allSimHits) {
253  // This routine matches up the closest simHit to every digi on a given layer.
254  // Note that it is possible to have up to 2 digis contribute to an LCT
255  // on a given layer. In a primitive algorithm used now more than one digi on
256  // a layer can be associated with the same simHit.
257  vector<PSimHit> simHits;
258 
259  vector<CSCComparatorDigi> thisLayerDigis = info.getRecDigis();
260  if (!thisLayerDigis.empty()) {
261  CSCDetId layerId = info.getId();
262  bool me11 = (layerId.station() == 1) && (layerId.ring() == 1);
263 
264  // Get simHits in this layer.
265  for (edm::PSimHitContainer::const_iterator simHitIt = allSimHits->begin();
266  simHitIt != allSimHits->end(); simHitIt++) {
267 
268  // Find detId where simHit is located.
269  CSCDetId hitId = (CSCDetId)(*simHitIt).detUnitId();
270  if (hitId == layerId)
271  simHits.push_back(*simHitIt);
272  if (me11) {
273  CSCDetId layerId_me1a(layerId.endcap(), layerId.station(), 4,
274  layerId.chamber(), layerId.layer());
275  if (hitId == layerId_me1a)
276  simHits.push_back(*simHitIt);
277  }
278  }
279 
280  if (!simHits.empty()) {
281  ostringstream strstrm;
282  if (debug) {
283  strstrm << "\nLayer " << layerId.layer()
284  << " has " << simHits.size() << " SimHit(s); phi value(s) = ";
285  }
286 
287  // Get the strip number for every digi and convert to phi.
288  for (vector<CSCComparatorDigi>::iterator prd = thisLayerDigis.begin();
289  prd != thisLayerDigis.end(); prd++) {
290  double deltaPhiMin = 999.;
291  double bestHitPhi = 999.;
292  PSimHit* bestHit = 0;
293 
294  int strip = prd->getStrip();
295  double digiPhi = getStripPhi(layerId, strip-0.5);
296 
297  const CSCLayer* csclayer = geom_->layer(layerId);
298  for (vector <PSimHit>::iterator psh = simHits.begin();
299  psh != simHits.end(); psh++) {
300  // Get the local phi for the simHit.
301  LocalPoint hitLP = psh->localPosition();
302  GlobalPoint hitGP = csclayer->toGlobal(hitLP);
303  double hitPhi = hitGP.phi();
304  if (debug)
305  strstrm << hitPhi << " ";
306  // Find the lowest deltaPhi and store the associated simHit.
307  // Check to see if comparison is on pi border, and if so, make
308  // corrections.
309  double deltaPhi = 999.;
310  if (fabs(hitPhi - digiPhi) < M_PI) {
311  deltaPhi = fabs(hitPhi - digiPhi);
312  }
313  else {
314  if (debug) LogDebug("digiSimHitAssociator")
315  << "SimHit and Digi are close to edge!!!";
316  deltaPhi = fabs(fabs(hitPhi - digiPhi) - 2.*M_PI);
317  }
318  if (deltaPhi < deltaPhiMin) {
319  deltaPhiMin = deltaPhi;
320  bestHit = &(*psh);
321  bestHitPhi = hitPhi;
322  }
323  }
324  if (debug) {
325  strstrm <<"\nDigi Phi: " << digiPhi
326  << ", closest SimHit phi: " << bestHitPhi
327  << ", particle type: " << bestHit->particleType();
328  }
329  info.addComponent(*bestHit);
330  }
331  if (debug) {
332  LogTrace("digiSimHitAssociator") << strstrm.str();
333  }
334  }
335  }
336 }
337 
339  const vector<CSCCathodeLayerInfo>& allLayerInfo,
340  double& closestPhi, double& closestEta) {
341  // Function to set the simulated values for comparison to the reconstructed.
342  // It first tries to look for the SimHit in the key layer. If it is
343  // unsuccessful, it loops over all layers and looks for an associated
344  // hit in any one of the layers. First instance of a hit gives a calculation
345  // for phi.
346  int nearestHS = -999;
347  PSimHit matchedHit;
348  bool hit_found = false;
349  CSCDetId layerId;
350  static const int key_layer = CSCConstants::KEY_CLCT_LAYER;
351 
352  vector<CSCCathodeLayerInfo>::const_iterator pli;
353  for (pli = allLayerInfo.begin(); pli != allLayerInfo.end(); pli++) {
354  if (pli->getId().layer() == key_layer) {
355  vector<PSimHit> thisLayerHits = pli->getSimHits();
356  if (thisLayerHits.size() > 0) {
357  // There can be one RecDigi (and therefore only one SimHit)
358  // in a keylayer.
359  if (thisLayerHits.size() != 1) {
360  edm::LogWarning("L1CSCTPEmulatorWrongValues")
361  << "+++ Warning: " << thisLayerHits.size()
362  << " SimHits in key layer " << key_layer << "! +++ \n";
363  for (unsigned i = 0; i < thisLayerHits.size(); i++) {
364  edm::LogWarning("L1CSCTPEmulatorWrongValues")
365  << " SimHit # " << i << thisLayerHits[i] << "\n";
366  }
367  }
368  matchedHit = thisLayerHits[0];
369  layerId = pli->getId();
370  hit_found = true;
371  break;
372  }
373  }
374  }
375 
376  if (hit_found == false) {
377  for (pli = allLayerInfo.begin(); pli != allLayerInfo.end(); pli++) {
378  // if there is any occurrence of simHit size greater that zero, use this.
379  if ((pli->getRecDigis()).size() > 0 && (pli->getSimHits()).size() > 0) {
380  // Always use the first SimHit for now.
381  matchedHit = (pli->getSimHits())[0];
382  layerId = pli->getId();
383  hit_found = true;
384  break;
385  }
386  }
387  }
388 
389  // Set phi and eta if there were any hits found.
390  if (hit_found) {
391  const CSCLayer* csclayer = geom_->layer(layerId);
392  const CSCLayerGeometry* layerGeom = csclayer->geometry();
393  //nearestStrip = layerGeom->nearestStrip(matchedHit.localPosition());
394  // Float in units of the strip (angular) width. From RadialStripTopology
395  // comments: "Strip in which a given LocalPoint lies. This is a float
396  // which represents the fractional strip position within the detector.
397  // Returns zero if the LocalPoint falls at the extreme low edge of the
398  // detector or BELOW, and float(nstrips) if it falls at the extreme high
399  // edge or ABOVE."
400  float strip = layerGeom->topology()->strip(matchedHit.localPosition());
401 
402  // Should be in the interval [0-MAX_STRIPS). I see (rarely) cases when
403  // strip = nearestStrip = MAX_STRIPS; do not know how to handle them.
404  int nearestStrip = static_cast<int>(strip);
405  if (nearestStrip < 0 || nearestStrip >= CSCConstants::MAX_NUM_STRIPS) {
406  edm::LogWarning("L1CSCTPEmulatorWrongInput")
407  << "+++ Warning: nearest strip, " << nearestStrip
408  << ", is not in [0-" << CSCConstants::MAX_NUM_STRIPS
409  << ") interval; strip = " << strip << " +++\n";
410  }
411  // Left/right half of the strip.
412  int comp = ((strip - nearestStrip) < 0.5) ? 0 : 1;
413  nearestHS = 2*nearestStrip + comp;
414 
415  GlobalPoint thisPoint = csclayer->toGlobal(matchedHit.localPosition());
416  closestPhi = thisPoint.phi();
417  closestEta = thisPoint.eta();
418  ostringstream strstrm;
419  if (debug)
420  strstrm << "Matched cathode phi: " << closestPhi;
421  if (closestPhi < 0.) {
422  closestPhi += 2.*M_PI;
423  if (debug)
424  strstrm << "(" << closestPhi << ")";
425  }
426  if (debug) {
427  strstrm << " eta: " << closestEta
428  << " on a layer " << layerId.layer() << " (1-6);"
429  << " nearest strip: " << nearestStrip;
430  LogDebug("nearestHS") << strstrm.str();
431  }
432  }
433 
434  return nearestHS;
435 }
436 
438  geom_ = geom;
439 }
440 
442  const float strip) {
443  // Returns phi position of a given strip.
444  if (strip < 0. || strip >= CSCConstants::MAX_NUM_STRIPS) {
445  edm::LogWarning("L1CSCTPEmulatorWrongInput")
446  << "+++ Warning: strip, " << strip
447  << ", is not in [0-" << CSCConstants::MAX_NUM_STRIPS
448  << ") interval +++\n";
449  }
450 
451  const CSCLayer* csclayer = geom_->layer(layerId);
452  const CSCLayerGeometry* layerGeom = csclayer->geometry();
453 
454  // Position at the center of the strip.
455  LocalPoint digiLP = layerGeom->topology()->localPosition(strip);
456  // The alternative calculation gives exactly the same answer.
457  // double ystrip = 0.0;
458  // double xstrip = topology->xOfStrip(strip, ystrip);
459  // LocalPoint digiLP = LocalPoint(xstrip, ystrip);
460  GlobalPoint digiGP = csclayer->toGlobal(digiLP);
461  double phi = digiGP.phi();
462 
463  return phi;
464 }
#define LogDebug(id)
size
Write out results.
int chamber() const
Definition: CSCDetId.h:68
std::vector< TYPE > getRecDigis() const
Definition: CSCLayerInfo.h:46
static const TGPicture * info(bool iBackgroundIsBlack)
void digiSimHitAssociator(CSCCathodeLayerInfo &info, const edm::PSimHitContainer *allSimHits)
float strip(const LocalPoint &) const override
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
static const int pattern2007_offset[CSCConstants::MAX_HALFSTRIPS_IN_PATTERN]
void addComponent(const TYPE digi)
Definition: CSCLayerInfo.h:37
int layer() const
Definition: CSCDetId.h:61
void setGeometry(const CSCGeometry *geom)
int preselectDigis(const int clct_bx, const CSCDetId &layerId, const CSCComparatorDigiCollection *compdc, std::vector< CSCComparatorDigi > &digiMap, int hfstripDigis[CSCConstants::NUM_HALF_STRIPS], int time[CSCConstants::MAX_NUM_STRIPS], int comp[CSCConstants::MAX_NUM_STRIPS], int digiNum[CSCConstants::MAX_NUM_STRIPS])
int getStripType() const
return striptype
Definition: CSCCLCTDigi.h:53
std::vector< CSCCathodeLayerInfo > lctDigis(const CSCCLCTDigi &clct, const CSCDetId &clctId, const CSCComparatorDigiCollection *compdc)
int endcap() const
Definition: CSCDetId.h:93
Local3DPoint localPosition() const
Definition: PSimHit.h:52
static const int pattern2007[CSCConstants::NUM_CLCT_PATTERNS][CSCConstants::MAX_HALFSTRIPS_IN_PATTERN+2]
int getBX() const
return BX
Definition: CSCCLCTDigi.h:77
int nearestHS(const std::vector< CSCCathodeLayerInfo > &allLayerInfo, double &closestPhi, double &closestEta)
void clear()
Definition: CSCLayerInfo.h:69
#define LogTrace(id)
#define M_PI
int ring() const
Definition: CSCDetId.h:75
const CSCStripTopology * topology() const
int stagger() const
#define debug
Definition: HDRShower.cc:19
void setId(const CSCDetId id)
Definition: CSCLayerInfo.h:34
int getPattern() const
return pattern
Definition: CSCCLCTDigi.h:47
std::vector< DigiType >::const_iterator const_iterator
T eta() const
Definition: PV3DBase.h:76
double getStripPhi(const CSCDetId &layerId, const float strip)
int particleType() const
Definition: PSimHit.h:89
std::vector< CSCCathodeLayerInfo > getSimInfo(const CSCCLCTDigi &clct, const CSCDetId &clctId, const CSCComparatorDigiCollection *compdc, const edm::PSimHitContainer *allSimHits)
LocalPoint localPosition(float strip) const override
CSCDetId getId() const
Definition: CSCLayerInfo.h:43
int station() const
Definition: CSCDetId.h:86
std::pair< const_iterator, const_iterator > Range
std::vector< PSimHit > PSimHitContainer
int getKeyStrip() const
Definition: CSCCLCTDigi.h:94
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:47