CMS 3D CMS Logo

CSCAnodeLCTAnalyzer.cc
Go to the documentation of this file.
1 
12 
15 
19 
20 using namespace std;
21 
22 //-----------------
23 // Static variables
24 //-----------------
25 
26 bool CSCAnodeLCTAnalyzer::debug = true;
27 bool CSCAnodeLCTAnalyzer::doME1A = true;
28 
29 vector<CSCAnodeLayerInfo> CSCAnodeLCTAnalyzer::getSimInfo(
30  const CSCALCTDigi& alct, const CSCDetId& alctId,
31  const CSCWireDigiCollection* wiredc,
32  const edm::PSimHitContainer* allSimHits) {
33  // Fills vector of CSCAnodeLayerInfo objects. There can be up to 6 such
34  // objects (one per layer); they contain the list of wire digis used to
35  // build a given ALCT, and the list of associated (closest) SimHits.
36  // Filling is done in two steps: first, we construct the list of wire
37  // digis; next, find associated SimHits.
38  vector<CSCAnodeLayerInfo> alctInfo = lctDigis(alct, alctId, wiredc);
39 
40  // Sanity checks.
41  if (alctInfo.size() > CSCConstants::NUM_LAYERS) {
42  throw cms::Exception("CSCAnodeLCTAnalyzer")
43  << "+++ Number of CSCAnodeLayerInfo objects, " << alctInfo.size()
44  << ", exceeds max expected, " << CSCConstants::NUM_LAYERS << " +++\n";
45  }
46  // not a good check for high PU
47  //if (alctInfo.size() != (unsigned)alct.getQuality()+3) {
48  // edm::LogWarning("L1CSCTPEmulatorWrongValues")
49  // << "+++ Warning: mismatch between ALCT quality, " << alct.getQuality()
50  // << ", and the number of layers with digis, " << alctInfo.size()
51  // << ", in alctInfo! +++\n";
52  //}
53 
54  // Find the closest SimHit to each Digi.
55  vector<CSCAnodeLayerInfo>::iterator pali;
56  for (pali = alctInfo.begin(); pali != alctInfo.end(); pali++) {
57  digiSimHitAssociator(*pali, allSimHits);
58  }
59 
60  return alctInfo;
61 }
62 
63 vector<CSCAnodeLayerInfo> CSCAnodeLCTAnalyzer::lctDigis(
64  const CSCALCTDigi& alct, const CSCDetId& alctId,
65  const CSCWireDigiCollection* wiredc) {
66  // Function to find a list of WireDigis used to create an LCT.
67  // The list of WireDigis is stored in a class called CSCLayerInfo which
68  // contains the layerId's of the stored WireDigis as well as the actual digis
69  // themselves.
70  CSCAnodeLayerInfo tempInfo;
71  vector<CSCAnodeLayerInfo> vectInfo;
72 
73  // Inquire the alct for its pattern and key wiregroup.
74  int alct_pattern = 0;
75  if (!alct.getAccelerator()) alct_pattern = alct.getCollisionB() + 1;
76  int alct_keywire = alct.getKeyWG();
77  int alct_bx = alct.getBX();
78 
79  // Choose pattern envelope.
80  int MESelection = (alctId.station() < 3) ? 0 : 1;
81 
82  if (debug) {
83  LogDebug("lctDigis")
84  << "\nlctDigis: ALCT keywire = " << alct_keywire << "; alctId:"
85  << " endcap " << alctId.endcap() << ", station " << alctId.station()
86  << ", ring " << alctId.ring() << ", chamber " << alctId.chamber();
87  }
88 
89  for (int i_layer = 0; i_layer < CSCConstants::NUM_LAYERS; i_layer++) {
90  map<int, CSCWireDigi> digiMap;
91  // Clear tempInfo values every iteration before using.
92  tempInfo.clear();
93 
94  // ALCTs belong to a chamber, so their layerId is 0. Wire digis belong
95  // to layers, so in order to access them we need to add layer number to
96  // ALCT's endcap, chamber, etc.
97  CSCDetId layerId(alctId.endcap(), alctId.station(), alctId.ring(),
98  alctId.chamber(), i_layer+1);
99  // Preselection of Digis: right layer and bx.
100  preselectDigis(alct_bx, layerId, wiredc, digiMap);
101 
102  // In case of ME1/1, one can also look for digis in ME1/A.
103  // Keep "on" by defailt since the resolution should not be different
104  // from that in ME1/B.
105  if (doME1A) {
106  if (alctId.station() == 1 && alctId.ring() == 1) {
107  CSCDetId layerId_me1a(alctId.endcap(), alctId.station(), 4,
108  alctId.chamber(), i_layer+1);
109  preselectDigis(alct_bx, layerId_me1a, wiredc, digiMap);
110  }
111  }
112 
113  // Loop over all the wires in a pattern.
114  int mask;
115  for (int i_wire = 0; i_wire < CSCConstants::MAX_WIRES_IN_PATTERN;
116  i_wire++) {
117  if (CSCAnodeLCTProcessor::pattern_envelope[0][i_wire] == i_layer) {
118  mask = CSCAnodeLCTProcessor::pattern_mask_open[alct_pattern][i_wire];
119  if (mask == 1) {
120  int wire = alct_keywire +
121  CSCAnodeLCTProcessor::pattern_envelope[1+MESelection][i_wire];
122  if (wire >= 0 && wire < CSCConstants::MAX_NUM_WIRES) {
123  // Check if there is a "good" Digi on this wire.
124  if (digiMap.count(wire) > 0) {
125  tempInfo.setId(layerId); // store the layer of this object
126  tempInfo.addComponent(digiMap[wire]); // and the RecDigi
127  if (debug) LogDebug("lctDigis")
128  << " Digi on ALCT: wire group " << digiMap[wire].getWireGroup();
129  }
130  }
131  }
132  }
133  }
134 
135  // Save results for each non-empty layer.
136  if (tempInfo.getId().layer() != 0) {
137  vectInfo.push_back(tempInfo);
138  }
139  }
140  return vectInfo;
141 }
142 
143 void CSCAnodeLCTAnalyzer::preselectDigis(const int alct_bx,
144  const CSCDetId& layerId, const CSCWireDigiCollection* wiredc,
145  map<int, CSCWireDigi>& digiMap) {
146  // Preselection of Digis: right layer and bx.
147 
148  // Parameters defining time window for accepting hits; should come from
149  // configuration file eventually.
150  const int fifo_tbins = 16;
151  const int drift_delay = 2;
152  const int hit_persist = 6; // not a config. parameter, just const
153 
154  const CSCWireDigiCollection::Range rwired = wiredc->get(layerId);
155  for (CSCWireDigiCollection::const_iterator digiIt = rwired.first;
156  digiIt != rwired.second; ++digiIt) {
157  if (debug) LogDebug("lctDigis")
158  << "Wire digi: layer " << layerId.layer()-1 << (*digiIt);
159  int bx_time = (*digiIt).getTimeBin();
160  if (bx_time >= 0 && bx_time < fifo_tbins) {
161 
162  // Do not use digis which could not have contributed to a given ALCT.
163  int latch_bx = alct_bx + drift_delay;
164  if (bx_time <= latch_bx-hit_persist || bx_time > latch_bx) {
165  if (debug) LogDebug("lctDigis")
166  << "Late wire digi: layer " << layerId.layer()-1
167  << " " << (*digiIt) << " skipping...";
168  continue;
169  }
170 
171  int i_wire = (*digiIt).getWireGroup() - 1;
172 
173  // If there is more than one digi on the same wire, pick the one
174  // which occurred earlier.
175  if (digiMap.count(i_wire) > 0) {
176  if (digiMap[i_wire].getTimeBin() > bx_time) {
177  if (debug) {
178  LogDebug("lctDigis")
179  << " Replacing good wire digi on wire " << i_wire;
180  }
181  digiMap.erase(i_wire);
182  }
183  }
184 
185  digiMap[i_wire] = *digiIt;
186  if (debug) {
187  LogDebug("lctDigis") << " Good wire digi: wire group " << i_wire;
188  }
189  }
190  }
191 }
192 
194  const edm::PSimHitContainer* allSimHits) {
195  // This routine matches up the closest simHit to every digi on a given layer.
196  // Iit is possible to have up to 3 digis contribute to an LCT on a given
197  // layer. In a primitive algorithm used now more than one digi on a layer
198  // can be associated with the same simHit.
199  vector<PSimHit> simHits;
200 
201  vector<CSCWireDigi> thisLayerDigis = info.getRecDigis();
202  if (!thisLayerDigis.empty()) {
203  CSCDetId layerId = info.getId();
204  bool me11 = (layerId.station() == 1) && (layerId.ring() == 1);
205 
206  // Get simHits in this layer.
207  for (edm::PSimHitContainer::const_iterator simHitIt = allSimHits->begin();
208  simHitIt != allSimHits->end(); simHitIt++) {
209 
210  // Find detId where simHit is located.
211  CSCDetId hitId = (CSCDetId)(*simHitIt).detUnitId();
212  if (hitId == layerId)
213  simHits.push_back(*simHitIt);
214  if (me11) {
215  CSCDetId layerId_me1a(layerId.endcap(), layerId.station(), 4,
216  layerId.chamber(), layerId.layer());
217  if (hitId == layerId_me1a)
218  simHits.push_back(*simHitIt);
219  }
220  }
221 
222  if (!simHits.empty()) {
223  ostringstream strstrm;
224  if (debug) {
225  strstrm << "\nLayer " << layerId.layer()
226  << " has " << simHits.size() << " SimHit(s); eta value(s) = ";
227  }
228 
229  // Get the wire number for every digi and convert to eta.
230  for (vector<CSCWireDigi>::const_iterator prd = thisLayerDigis.begin();
231  prd != thisLayerDigis.end(); prd++) {
232  double deltaEtaMin = 999.;
233  double bestHitEta = 999.;
234  PSimHit* bestHit = 0;
235 
236  int wiregroup = prd->getWireGroup(); // counted from 1
237  double digiEta = getWGEta(layerId, wiregroup-1);
238 
239  const CSCLayer* csclayer = geom_->layer(layerId);
240  for (vector <PSimHit>::iterator psh = simHits.begin();
241  psh != simHits.end(); psh++) {
242  // Get the local eta for the simHit.
243  LocalPoint hitLP = psh->localPosition();
244  GlobalPoint hitGP = csclayer->toGlobal(hitLP);
245  double hitEta = hitGP.eta();
246  if (debug)
247  strstrm << hitEta << " ";
248  // Find the lowest deltaEta and store the associated simHit.
249  double deltaEta = fabs(hitEta - digiEta);
250  if (deltaEta < deltaEtaMin) {
251  deltaEtaMin = deltaEta;
252  bestHit = &(*psh);
253  bestHitEta = hitEta;
254  }
255  }
256  if (debug) {
257  strstrm << "\nDigi eta: " << digiEta
258  << ", closest SimHit eta: " << bestHitEta
259  << ", particle type: " << bestHit->particleType();
260  //strstrm << "\nlocal position:" << bestHit->localPosition();
261  }
262  info.addComponent(*bestHit);
263  }
264  if (debug) {
265  LogDebug("digiSimHitAssociator") << strstrm.str();
266  }
267  }
268  }
269 }
270 
272  const vector<CSCAnodeLayerInfo>& allLayerInfo,
273  double& closestPhi, double& closestEta) {
274  // Function to set the simulated values for comparison to the reconstructed.
275  // It first tries to look for the SimHit in the key layer. If it is
276  // unsuccessful, it loops over all layers and looks for an associated
277  // hit in any one of the layers. First instance of a hit gives a calculation
278  // for eta.
279  int nearestWG = -999;
280  PSimHit matchedHit;
281  bool hit_found = false;
282  CSCDetId layerId;
283 
284  vector<CSCAnodeLayerInfo>::const_iterator pli;
285  for (pli = allLayerInfo.begin(); pli != allLayerInfo.end(); pli++) {
286  // For ALCT search, the key layer is the 3rd one, counting from 1.
287  if (pli->getId().layer() == CSCConstants::KEY_ALCT_LAYER) {
288  vector<PSimHit> thisLayerHits = pli->getSimHits();
289  if (thisLayerHits.size() > 0) {
290  // There can be only one RecDigi (and therefore only one SimHit)
291  // in a key layer.
292  if (thisLayerHits.size() != 1) {
293  edm::LogWarning("L1CSCTPEmulatorWrongValues")
294  << "+++ Warning: " << thisLayerHits.size()
295  << " SimHits in key layer " << CSCConstants::KEY_ALCT_LAYER
296  << "! +++ \n";
297  for (unsigned i = 0; i < thisLayerHits.size(); i++) {
298  edm::LogWarning("L1CSCTPEmulatorWrongValues")
299  << " SimHit # " << i << thisLayerHits[i] << "\n";
300  }
301  }
302  matchedHit = thisLayerHits[0];
303  layerId = pli->getId();
304  hit_found = true;
305  break;
306  }
307  }
308  }
309 
310  if (!hit_found) {
311  for (pli = allLayerInfo.begin(); pli != allLayerInfo.end(); pli++) {
312  // if there is any occurrence of simHit size greater that zero, use this.
313  if ((pli->getRecDigis()).size() > 0 && (pli->getSimHits()).size() > 0) {
314  // Always use the first SimHit for now.
315  vector<PSimHit> thisLayerHits = pli->getSimHits();
316  matchedHit = thisLayerHits[0];
317  layerId = pli->getId();
318  hit_found = true;
319  break;
320  }
321  }
322  }
323 
324  // Set the eta if there were any hits found.
325  if (hit_found) {
326  const CSCLayer* csclayer = geom_->layer(layerId);
327  const CSCLayerGeometry* layerGeom = csclayer->geometry();
328  int nearestW = layerGeom->nearestWire(matchedHit.localPosition());
329  nearestWG = layerGeom->wireGroup(nearestW);
330  // Wire groups in ALCTs are counted starting from 0, whereas they
331  // are counted from 1 in MC-related info.
332  nearestWG -= 1;
333  if (nearestWG < 0 || nearestWG >= CSCConstants::MAX_NUM_WIRES) {
334  edm::LogWarning("L1CSCTPEmulatorWrongInput")
335  << "+++ Warning: nearest wire group, " << nearestWG
336  << ", is not in [0-" << CSCConstants::MAX_NUM_WIRES
337  << ") interval +++\n";
338  }
339 
340  GlobalPoint thisPoint = csclayer->toGlobal(matchedHit.localPosition());
341  closestPhi = thisPoint.phi();
342  closestEta = thisPoint.eta();
343  ostringstream strstrm;
344  if (debug)
345  strstrm << "Matched anode phi: " << closestPhi;
346  if (closestPhi < 0.) {
347  closestPhi += 2.*M_PI;
348  if (debug)
349  strstrm << " (" << closestPhi << ")";
350  }
351  if (debug) {
352  strstrm << " eta: " << closestEta
353  << " on a layer " << layerId.layer() << " (1-6);"
354  << " nearest wire group: " << nearestWG;
355  LogDebug("nearestWG") << strstrm.str();
356  }
357  }
358 
359  return nearestWG;
360 }
361 
363  geom_ = geom;
364 }
365 
367  const int wiregroup) {
368  // Returns eta position of a given wiregroup.
369  if (wiregroup < 0 || wiregroup >= CSCConstants::MAX_NUM_WIRES) {
370  edm::LogWarning("L1CSCTPEmulatorWrongInput")
371  << "+++ Warning: wire group, " << wiregroup
372  << ", is not in [0-" << CSCConstants::MAX_NUM_WIRES
373  << ") interval +++\n";
374  }
375 
376  const CSCLayer* csclayer = geom_->layer(layerId);
377  const CSCLayerGeometry* layerGeom = csclayer->geometry();
378  LocalPoint digiLP = layerGeom->localCenterOfWireGroup(wiregroup+1);
379  //int wirePerWG = layerGeom->numberOfWiresPerGroup(wiregroup+1);
380  //float middleW = layerGeom->middleWireOfGroup(wiregroup+1);
381  //float ywire = layerGeom->yOfWire(middleW, 0.);
382  //digiLP = LocalPoint(0., ywire);
383  GlobalPoint digiGP = csclayer->toGlobal(digiLP);
384  double eta = digiGP.eta();
385 
386  return eta;
387 }
#define LogDebug(id)
size
Write out results.
int nearestWire(const LocalPoint &lp) const
int chamber() const
Definition: CSCDetId.h:68
std::vector< TYPE > getRecDigis() const
Definition: CSCLayerInfo.h:46
static const TGPicture * info(bool iBackgroundIsBlack)
void digiSimHitAssociator(CSCAnodeLayerInfo &info, const edm::PSimHitContainer *allSimHits)
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
int nearestWG(const std::vector< CSCAnodeLayerInfo > &allLayerInfo, double &closestPhi, double &closestEta)
void addComponent(const TYPE digi)
Definition: CSCLayerInfo.h:37
int layer() const
Definition: CSCDetId.h:61
std::vector< CSCAnodeLayerInfo > getSimInfo(const CSCALCTDigi &alct, const CSCDetId &alctId, const CSCWireDigiCollection *wiredc, const edm::PSimHitContainer *allSimHits)
static const double deltaEta
Definition: CaloConstants.h:8
int endcap() const
Definition: CSCDetId.h:93
int wireGroup(int wire) const
static const int pattern_envelope[CSCConstants::NUM_ALCT_PATTERNS][CSCConstants::MAX_WIRES_IN_PATTERN]
void preselectDigis(const int alct_bx, const CSCDetId &layerId, const CSCWireDigiCollection *wiredc, std::map< int, CSCWireDigi > &digiMap)
Local3DPoint localPosition() const
Definition: PSimHit.h:52
void clear()
Definition: CSCLayerInfo.h:69
double getWGEta(const CSCDetId &layerId, const int wiregroup)
int getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:65
#define M_PI
LocalPoint localCenterOfWireGroup(int wireGroup) const
int ring() const
Definition: CSCDetId.h:75
static const int pattern_mask_open[CSCConstants::NUM_ALCT_PATTERNS][CSCConstants::MAX_WIRES_IN_PATTERN]
#define debug
Definition: HDRShower.cc:19
void setId(const CSCDetId id)
Definition: CSCLayerInfo.h:34
void setGeometry(const CSCGeometry *geom)
int getAccelerator() const
Definition: CSCALCTDigi.h:45
std::vector< CSCAnodeLayerInfo > lctDigis(const CSCALCTDigi &alct, const CSCDetId &alctId, const CSCWireDigiCollection *wiredc)
std::vector< DigiType >::const_iterator const_iterator
T eta() const
Definition: PV3DBase.h:76
int particleType() const
Definition: PSimHit.h:89
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 getKeyWG() const
return key wire group
Definition: CSCALCTDigi.h:59
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:47
int getCollisionB() const
Definition: CSCALCTDigi.h:53