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  int mask;
99  for (int i_wire = 0; i_wire < CSCConstants::MAX_WIRES_IN_PATTERN; i_wire++) {
100  if (CSCPatternBank::alct_pattern_envelope[i_wire] == i_layer) {
101  mask = CSCPatternBank::alct_pattern_mask_open[alct_pattern][i_wire];
102  if (mask == 1) {
103  int wire = alct_keywire + CSCPatternBank::alct_keywire_offset[MESelection][i_wire];
104  if (wire >= 0 && wire < CSCConstants::MAX_NUM_WIRES) {
105  // Check if there is a "good" Digi on this wire.
106  if (digiMap.count(wire) > 0) {
107  tempInfo.setId(layerId); // store the layer of this object
108  tempInfo.addComponent(digiMap[wire]); // and the RecDigi
109  if (debug)
110  LogDebug("lctDigis") << " Digi on ALCT: wire group " << digiMap[wire].getWireGroup();
111  }
112  }
113  }
114  }
115  }
116 
117  // Save results for each non-empty layer.
118  if (tempInfo.getId().layer() != 0) {
119  vectInfo.push_back(tempInfo);
120  }
121  }
122  return vectInfo;
123 }
124 
125 void CSCAnodeLCTAnalyzer::preselectDigis(const int alct_bx,
126  const CSCDetId& layerId,
127  const CSCWireDigiCollection* wiredc,
128  map<int, CSCWireDigi>& digiMap) {
129  // Preselection of Digis: right layer and bx.
130 
131  // Parameters defining time window for accepting hits; should come from
132  // configuration file eventually.
133  const int fifo_tbins = 16;
134  const int drift_delay = 2;
135  const int hit_persist = 6; // not a config. parameter, just const
136 
137  const CSCWireDigiCollection::Range rwired = wiredc->get(layerId);
138  for (CSCWireDigiCollection::const_iterator digiIt = rwired.first; digiIt != rwired.second; ++digiIt) {
139  if (debug)
140  LogDebug("lctDigis") << "Wire digi: layer " << layerId.layer() - 1 << (*digiIt);
141  int bx_time = (*digiIt).getTimeBin();
142  if (bx_time >= 0 && bx_time < fifo_tbins) {
143  // Do not use digis which could not have contributed to a given ALCT.
144  int latch_bx = alct_bx + drift_delay;
145  if (bx_time <= latch_bx - hit_persist || bx_time > latch_bx) {
146  if (debug)
147  LogDebug("lctDigis") << "Late wire digi: layer " << layerId.layer() - 1 << " " << (*digiIt) << " skipping...";
148  continue;
149  }
150 
151  int i_wire = (*digiIt).getWireGroup() - 1;
152 
153  // If there is more than one digi on the same wire, pick the one
154  // which occurred earlier.
155  if (digiMap.count(i_wire) > 0) {
156  if (digiMap[i_wire].getTimeBin() > bx_time) {
157  if (debug) {
158  LogDebug("lctDigis") << " Replacing good wire digi on wire " << i_wire;
159  }
160  digiMap.erase(i_wire);
161  }
162  }
163 
164  digiMap[i_wire] = *digiIt;
165  if (debug) {
166  LogDebug("lctDigis") << " Good wire digi: wire group " << i_wire;
167  }
168  }
169  }
170 }
171 
173  // This routine matches up the closest simHit to every digi on a given layer.
174  // Iit is possible to have up to 3 digis contribute to an LCT on a given
175  // layer. In a primitive algorithm used now more than one digi on a layer
176  // can be associated with the same simHit.
177  vector<PSimHit> simHits;
178 
179  vector<CSCWireDigi> thisLayerDigis = info.getRecDigis();
180  if (!thisLayerDigis.empty()) {
181  CSCDetId layerId = info.getId();
182  bool me11 = (layerId.station() == 1) && (layerId.ring() == 1);
183 
184  // Get simHits in this layer.
185  for (edm::PSimHitContainer::const_iterator simHitIt = allSimHits->begin(); simHitIt != allSimHits->end();
186  simHitIt++) {
187  // Find detId where simHit is located.
188  CSCDetId hitId = (CSCDetId)(*simHitIt).detUnitId();
189  if (hitId == layerId)
190  simHits.push_back(*simHitIt);
191  if (me11) {
192  CSCDetId layerId_me1a(layerId.endcap(), layerId.station(), 4, layerId.chamber(), layerId.layer());
193  if (hitId == layerId_me1a)
194  simHits.push_back(*simHitIt);
195  }
196  }
197 
198  if (!simHits.empty()) {
199  ostringstream strstrm;
200  if (debug) {
201  strstrm << "\nLayer " << layerId.layer() << " has " << simHits.size() << " SimHit(s); eta value(s) = ";
202  }
203 
204  // Get the wire number for every digi and convert to eta.
205  for (vector<CSCWireDigi>::const_iterator prd = thisLayerDigis.begin(); prd != thisLayerDigis.end(); prd++) {
206  double deltaEtaMin = 999.;
207  double bestHitEta = 999.;
208  PSimHit* bestHit = nullptr;
209 
210  int wiregroup = prd->getWireGroup(); // counted from 1
211  double digiEta = getWGEta(layerId, wiregroup - 1);
212 
213  const CSCLayer* csclayer = geom_->layer(layerId);
214  for (vector<PSimHit>::iterator psh = simHits.begin(); psh != simHits.end(); psh++) {
215  // Get the local eta for the simHit.
216  LocalPoint hitLP = psh->localPosition();
217  GlobalPoint hitGP = csclayer->toGlobal(hitLP);
218  double hitEta = hitGP.eta();
219  if (debug)
220  strstrm << hitEta << " ";
221  // Find the lowest deltaEta and store the associated simHit.
222  double deltaEta = fabs(hitEta - digiEta);
223  if (deltaEta < deltaEtaMin) {
224  deltaEtaMin = deltaEta;
225  bestHit = &(*psh);
226  bestHitEta = hitEta;
227  }
228  }
229  if (debug) {
230  strstrm << "\nDigi eta: " << digiEta << ", closest SimHit eta: " << bestHitEta
231  << ", particle type: " << bestHit->particleType();
232  //strstrm << "\nlocal position:" << bestHit->localPosition();
233  }
234  info.addComponent(*bestHit);
235  }
236  if (debug) {
237  LogDebug("digiSimHitAssociator") << strstrm.str();
238  }
239  }
240  }
241 }
242 
243 int CSCAnodeLCTAnalyzer::nearestWG(const vector<CSCAnodeLayerInfo>& allLayerInfo,
244  double& closestPhi,
245  double& closestEta) {
246  // Function to set the simulated values for comparison to the reconstructed.
247  // It first tries to look for the SimHit in the key layer. If it is
248  // unsuccessful, it loops over all layers and looks for an associated
249  // hit in any one of the layers. First instance of a hit gives a calculation
250  // for eta.
251  int nearestWG = -999;
252  PSimHit matchedHit;
253  bool hit_found = false;
254  CSCDetId layerId;
255 
256  vector<CSCAnodeLayerInfo>::const_iterator pli;
257  for (pli = allLayerInfo.begin(); pli != allLayerInfo.end(); pli++) {
258  // For ALCT search, the key layer is the 3rd one, counting from 1.
259  if (pli->getId().layer() == CSCConstants::KEY_ALCT_LAYER) {
260  vector<PSimHit> thisLayerHits = pli->getSimHits();
261  if (!thisLayerHits.empty()) {
262  // There can be only one RecDigi (and therefore only one SimHit)
263  // in a key layer.
264  if (thisLayerHits.size() != 1) {
265  edm::LogWarning("L1CSCTPEmulatorWrongValues")
266  << "+++ Warning: " << thisLayerHits.size() << " SimHits in key layer " << CSCConstants::KEY_ALCT_LAYER
267  << "! +++ \n";
268  for (unsigned i = 0; i < thisLayerHits.size(); i++) {
269  edm::LogWarning("L1CSCTPEmulatorWrongValues") << " SimHit # " << i << thisLayerHits[i] << "\n";
270  }
271  }
272  matchedHit = thisLayerHits[0];
273  layerId = pli->getId();
274  hit_found = true;
275  break;
276  }
277  }
278  }
279 
280  if (!hit_found) {
281  for (pli = allLayerInfo.begin(); pli != allLayerInfo.end(); pli++) {
282  // if there is any occurrence of simHit size greater that zero, use this.
283  if (!(pli->getRecDigis()).empty() && !(pli->getSimHits()).empty()) {
284  // Always use the first SimHit for now.
285  vector<PSimHit> thisLayerHits = pli->getSimHits();
286  matchedHit = thisLayerHits[0];
287  layerId = pli->getId();
288  hit_found = true;
289  break;
290  }
291  }
292  }
293 
294  // Set the eta if there were any hits found.
295  if (hit_found) {
296  const CSCLayer* csclayer = geom_->layer(layerId);
297  const CSCLayerGeometry* layerGeom = csclayer->geometry();
298  int nearestW = layerGeom->nearestWire(matchedHit.localPosition());
299  nearestWG = layerGeom->wireGroup(nearestW);
300  // Wire groups in ALCTs are counted starting from 0, whereas they
301  // are counted from 1 in MC-related info.
302  nearestWG -= 1;
303  if (nearestWG < 0 || nearestWG >= CSCConstants::MAX_NUM_WIRES) {
304  edm::LogWarning("L1CSCTPEmulatorWrongInput")
305  << "+++ Warning: nearest wire group, " << nearestWG << ", is not in [0-" << CSCConstants::MAX_NUM_WIRES
306  << ") interval +++\n";
307  }
308 
309  GlobalPoint thisPoint = csclayer->toGlobal(matchedHit.localPosition());
310  closestPhi = thisPoint.phi();
311  closestEta = thisPoint.eta();
312  ostringstream strstrm;
313  if (debug)
314  strstrm << "Matched anode phi: " << closestPhi;
315  if (closestPhi < 0.) {
316  closestPhi += 2. * M_PI;
317  if (debug)
318  strstrm << " (" << closestPhi << ")";
319  }
320  if (debug) {
321  strstrm << " eta: " << closestEta << " on a layer " << layerId.layer() << " (1-6);"
322  << " nearest wire group: " << nearestWG;
323  LogDebug("nearestWG") << strstrm.str();
324  }
325  }
326 
327  return nearestWG;
328 }
329 
331 
332 double CSCAnodeLCTAnalyzer::getWGEta(const CSCDetId& layerId, const int wiregroup) {
333  // Returns eta position of a given wiregroup.
334  if (wiregroup < 0 || wiregroup >= CSCConstants::MAX_NUM_WIRES) {
335  edm::LogWarning("L1CSCTPEmulatorWrongInput") << "+++ Warning: wire group, " << wiregroup << ", is not in [0-"
336  << CSCConstants::MAX_NUM_WIRES << ") interval +++\n";
337  }
338 
339  const CSCLayer* csclayer = geom_->layer(layerId);
340  const CSCLayerGeometry* layerGeom = csclayer->geometry();
341  LocalPoint digiLP = layerGeom->localCenterOfWireGroup(wiregroup + 1);
342  //int wirePerWG = layerGeom->numberOfWiresPerGroup(wiregroup+1);
343  //float middleW = layerGeom->middleWireOfGroup(wiregroup+1);
344  //float ywire = layerGeom->yOfWire(middleW, 0.);
345  //digiLP = LocalPoint(0., ywire);
346  GlobalPoint digiGP = csclayer->toGlobal(digiLP);
347  double eta = digiGP.eta();
348 
349  return eta;
350 }
CSCLayerGeometry::nearestWire
int nearestWire(const LocalPoint &lp) const
Definition: CSCLayerGeometry.h:101
CSCConstants::MAX_NUM_WIRES
Definition: CSCConstants.h:22
CSCPatternBank::alct_pattern_envelope
static const int alct_pattern_envelope[CSCConstants::MAX_WIRES_IN_PATTERN]
Definition: CSCPatternBank.h:21
CSCALCTDigi::getBX
uint16_t getBX() const
return BX - five low bits of BXN counter tagged by the ALCT
Definition: CSCALCTDigi.h:70
CSCLayerInfo::getId
CSCDetId getId() const
Definition: CSCLayerInfo.h:42
mps_fire.i
i
Definition: mps_fire.py:355
CSCLayerInfo::clear
void clear()
Definition: CSCLayerInfo.h:70
MessageLogger.h
CSCPatternBank::alct_pattern_mask_open
static const ALCTPatterns alct_pattern_mask_open
Definition: CSCPatternBank.h:29
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:330
CSCPatternBank::alct_keywire_offset
static const int alct_keywire_offset[2][CSCConstants::MAX_WIRES_IN_PATTERN]
Definition: CSCPatternBank.h:25
CSCDetId::ring
int ring() const
Definition: CSCDetId.h:68
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:152
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:125
create_new_empty_test_file_cfg.prd
prd
Definition: create_new_empty_test_file_cfg.py:14
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:64
debug
#define debug
Definition: HDRShower.cc:19
CSCAnodeLCTAnalyzer::nearestWG
int nearestWG(const std::vector< CSCAnodeLayerInfo > &allLayerInfo, double &closestPhi, double &closestEta)
Definition: CSCAnodeLCTAnalyzer.cc:243
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:69
CSCLayerGeometry
Definition: CSCLayerGeometry.h:25
CSCConstants::MAX_WIRES_IN_PATTERN
Definition: CSCConstants.h:54
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:58
edm::LogWarning
Definition: MessageLogger.h:141
CSCLayerInfo::setId
void setId(const CSCDetId id)
Definition: CSCLayerInfo.h:33
std::empty
constexpr auto empty(const C &c) -> decltype(c.empty())
Definition: cuda_cxx17.h:24
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:670
CSCDetId
Definition: CSCDetId.h:26
PV3DBase::eta
T eta() const
Definition: PV3DBase.h:73
M_PI
#define M_PI
Definition: BXVectorInputProducer.cc:50
CSCAnodeLCTAnalyzer::digiSimHitAssociator
void digiSimHitAssociator(CSCAnodeLayerInfo &info, const edm::PSimHitContainer *allSimHits)
Definition: CSCAnodeLCTAnalyzer.cc:172
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:50
CSCDetId::endcap
int endcap() const
Definition: CSCDetId.h:85
CSCAnodeLCTAnalyzer::getWGEta
double getWGEta(const CSCDetId &layerId, const int wiregroup)
Definition: CSCAnodeLCTAnalyzer.cc:332
Exception
Definition: hltDiff.cc:246
CSCALCTDigi
Definition: CSCALCTDigi.h:16
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
CSCGeometry.h
CSCAnodeLCTAnalyzer::doME1A
static bool doME1A
Definition: CSCAnodeLCTAnalyzer.h:56