CMS 3D CMS Logo

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