CMS 3D CMS Logo

DTEfficiencyTask.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author G. Mila - INFN Torino
5  */
6 
7 #include "DTEfficiencyTask.h"
8 
9 // Framework
15 
17 
18 //Geometry
21 
22 //RecHit
24 
27 
28 #include <iterator>
29 
30 using namespace edm;
31 using namespace std;
32 
34  : muonGeomToken_(esConsumes<edm::Transition::BeginRun>()), dtGeomToken_(esConsumes()) {
35  debug = pset.getUntrackedParameter<bool>("debug", false);
36  // the name of the 4D rec hits collection
37  recHits4DToken_ = consumes<DTRecSegment4DCollection>(edm::InputTag(pset.getParameter<string>("recHits4DLabel")));
38  // the name of the rechits collection
39  recHitToken_ = consumes<DTRecHitCollection>(edm::InputTag(pset.getParameter<string>("recHitLabel")));
40 
41  parameters = pset;
42 }
43 
45 
47  // Get the geometry
48  muonGeom = &context.getData(muonGeomToken_);
49 }
50 
52  edm::Run const& iRun,
53  edm::EventSetup const& context) {
54  ibooker.setCurrentFolder("DT/DTEfficiencyTask");
55 
56  cout << "[DTTestPulseTask]: booking" << endl;
57 
58  //here put the static booking loop
59 
60  // Loop over all the chambers
61  vector<const DTChamber*>::const_iterator ch_it = muonGeom->chambers().begin();
62  vector<const DTChamber*>::const_iterator ch_end = muonGeom->chambers().end();
63 
64  for (; ch_it != ch_end; ++ch_it) {
65  // Loop over the SLs
66  vector<const DTSuperLayer*>::const_iterator sl_it = (*ch_it)->superLayers().begin();
67  vector<const DTSuperLayer*>::const_iterator sl_end = (*ch_it)->superLayers().end();
68 
69  for (; sl_it != sl_end; ++sl_it) {
70  DTSuperLayerId sl = (*sl_it)->id();
71  stringstream superLayer;
72  superLayer << sl.superlayer();
73 
74  // Loop over the Ls
75  vector<const DTLayer*>::const_iterator l_it = (*sl_it)->layers().begin();
76  vector<const DTLayer*>::const_iterator l_end = (*sl_it)->layers().end();
77 
78  for (; l_it != l_end; ++l_it) {
79  DTLayerId layerId = (*l_it)->id();
80  if (debug)
81  cout << " Booking histos for L: " << layerId << endl;
82 
83  // Compose the chamber name
84  stringstream layer;
85  layer << layerId.layer();
86  stringstream superLayer;
87  superLayer << layerId.superlayer();
88  stringstream station;
89  station << layerId.superlayerId().chamberId().station();
90  stringstream sector;
91  sector << layerId.superlayerId().chamberId().sector();
92  stringstream wheel;
93  wheel << layerId.superlayerId().chamberId().wheel();
94 
95  const int firstWire = (*l_it)->specificTopology().firstChannel();
96  const int lastWire = (*l_it)->specificTopology().lastChannel();
97 
98  string lHistoName = "_W" + wheel.str() + "_St" + station.str() + "_Sec" + sector.str() + "_SL" +
99  superLayer.str() + "_L" + layer.str();
100 
101  ibooker.setCurrentFolder("DT/DTEfficiencyTask/Wheel" + wheel.str() + "/Station" + station.str() + "/Sector" +
102  sector.str() + "/SuperLayer" + superLayer.str());
103 
104  // Create the monitor elements
105  vector<MonitorElement*> histos;
106  // histo for hits associated to the 4D reconstructed segment
107  histos.push_back(ibooker.book1D("hEffOccupancy" + lHistoName,
108  "4D segments recHits occupancy",
109  lastWire - firstWire + 1,
110  firstWire - 0.5,
111  lastWire + 0.5));
112  // histo for hits not associated to the segment
113  histos.push_back(ibooker.book1D("hEffUnassOccupancy" + lHistoName,
114  "4D segments recHits and Hits not associated occupancy",
115  lastWire - firstWire + 1,
116  firstWire - 0.5,
117  lastWire + 0.5));
118  // histo for cells associated to the 4D reconstructed segment
119  histos.push_back(ibooker.book1D("hRecSegmOccupancy" + lHistoName,
120  "4D segments cells occupancy",
121  lastWire - firstWire + 1,
122  firstWire - 0.5,
123  lastWire + 0.5));
124 
125  histosPerL[layerId] = histos;
126 
127  } // layer
128  } // superlayer
129  } // chambers
130 }
131 
133  if (lumiSeg.id().luminosityBlock() % parameters.getUntrackedParameter<int>("ResetCycle", 3) == 0) {
134  for (map<DTLayerId, vector<MonitorElement*> >::const_iterator histo = histosPerL.begin(); histo != histosPerL.end();
135  histo++) {
136  int size = (*histo).second.size();
137  for (int i = 0; i < size; i++) {
138  (*histo).second[i]->Reset();
139  }
140  }
141  }
142 }
143 
145  if (debug)
146  cout << "[DTEfficiencyTask] Analyze #Run: " << event.id().run() << " #Event: " << event.id().event() << endl;
147 
148  // Get the 4D segment collection from the event
150  event.getByToken(recHits4DToken_, all4DSegments);
151 
152  // Get the rechit collection from the event
153  Handle<DTRecHitCollection> dtRecHits;
154  event.getByToken(recHitToken_, dtRecHits);
155 
156  // Get the DT Geometry
157  dtGeom = &setup.getData(dtGeomToken_);
158 
159  // Loop over all chambers containing a segment
161  for (chamberId = all4DSegments->id_begin(); chamberId != all4DSegments->id_end(); ++chamberId) {
162  // Get the chamber
163  const DTChamber* chamber = dtGeom->chamber(*chamberId);
164 
165  // Get all 1D RecHits to be used for searches of hits not associated to segments and map them by wire
166  const vector<const DTSuperLayer*>& SLayers = chamber->superLayers();
167  map<DTWireId, int> wireAnd1DRecHits;
168  for (vector<const DTSuperLayer*>::const_iterator superlayer = SLayers.begin(); superlayer != SLayers.end();
169  superlayer++) {
170  DTRecHitCollection::range range = dtRecHits->get(DTRangeMapAccessor::layersBySuperLayer((*superlayer)->id()));
171  // Loop over the rechits of this ChamberId
172  for (DTRecHitCollection::const_iterator rechit = range.first; rechit != range.second; ++rechit) {
173  wireAnd1DRecHits[(*rechit).wireId()] = (*rechit).wireId().wire();
174  }
175  }
176 
177  // Get the 4D segment range for the corresponding ChamerId
178  DTRecSegment4DCollection::range range = all4DSegments->get(*chamberId);
179  int nsegm = distance(range.first, range.second);
180  if (debug)
181  cout << " Chamber: " << *chamberId << " has " << nsegm << " 4D segments" << endl;
182 
183  // Loop over the rechits of this ChamerId
184  for (DTRecSegment4DCollection::const_iterator segment4D = range.first; segment4D != range.second; ++segment4D) {
185  if (debug)
186  cout << " == RecSegment dimension: " << (*segment4D).dimension() << endl;
187 
188  // If Station != 4 skip RecHits with dimension != 4
189  // For the Station 4 consider 2D RecHits
190  if ((*chamberId).station() != 4 && (*segment4D).dimension() != 4) {
191  if (debug)
192  cout << "[DTEfficiencyTask]***Warning: RecSegment dimension is not 4 but " << (*segment4D).dimension()
193  << ", skipping!" << endl;
194  continue;
195  } else if ((*chamberId).station() == 4 && (*segment4D).dimension() != 2) {
196  if (debug)
197  cout << "[DTEfficiencyTask]***Warning: RecSegment dimension is not 2 but " << (*segment4D).dimension()
198  << ", skipping!" << endl;
199  continue;
200  }
201 
202  vector<DTRecHit1D> recHits1D;
203  bool rPhi = false;
204  bool rZ = false;
205 
206  // Get 1D RecHits and select only events with 7 or 8 hits in phi and 3 or 4 hits in theta (if any)
207  const DTChamberRecSegment2D* phiSeg = (*segment4D).phiSegment();
208  vector<DTRecHit1D> phiRecHits = phiSeg->specificRecHits();
209  rPhi = true;
210  if (phiRecHits.size() < 7 || phiRecHits.size() > 8) {
211  if (debug)
212  cout << "[DTEfficiencyTask] Phi segments has: " << phiRecHits.size() << " hits, skipping"
213  << endl; // FIXME: info output
214  continue;
215  }
216  copy(phiRecHits.begin(), phiRecHits.end(), back_inserter(recHits1D));
217  const DTSLRecSegment2D* zSeg = nullptr;
218  if ((*segment4D).dimension() == 4) {
219  rZ = true;
220  zSeg = (*segment4D).zSegment();
221  vector<DTRecHit1D> zRecHits = zSeg->specificRecHits();
222  if (zRecHits.size() < 3 || zRecHits.size() > 4) {
223  if (debug)
224  cout << "[DTEfficiencyTask] Theta segments has: " << zRecHits.size() << " hits, skipping"
225  << endl; // FIXME: info output
226  continue;
227  }
228  copy(zRecHits.begin(), zRecHits.end(), back_inserter(recHits1D));
229  }
230 
231  // Skip the segment if it has more than 1 hit on the same layer
232  vector<DTWireId> wireMap;
233  for (vector<DTRecHit1D>::const_iterator recHit1D = recHits1D.begin(); recHit1D != recHits1D.end(); recHit1D++) {
234  wireMap.push_back((*recHit1D).wireId());
235  }
236 
237  bool hitsOnSameLayer = false;
238  for (vector<DTWireId>::const_iterator channelId = wireMap.begin(); channelId != wireMap.end(); channelId++) {
239  vector<DTWireId>::const_iterator next = channelId;
240  next++;
241  for (vector<DTWireId>::const_iterator ite = next; ite != wireMap.end(); ite++) {
242  if ((*channelId).layerId() == (*ite).layerId()) {
243  hitsOnSameLayer = true;
244  }
245  }
246  }
247  if (hitsOnSameLayer) {
248  if (debug)
249  cout << "[DTEfficiencyTask] This RecHit has 2 hits on the same layer, skipping!" << endl;
250  continue;
251  }
252 
253  // Select 2D segments with angle smaller than 45 deg
254  LocalVector phiDirectionInChamber = (*phiSeg).localDirection();
255  if (rPhi && fabs(phiDirectionInChamber.x() / phiDirectionInChamber.z()) > 1) {
256  if (debug) {
257  cout << " RPhi segment has angle > 45 deg, skipping! " << endl;
258  cout << " Theta = " << phiDirectionInChamber.theta() << endl;
259  }
260  continue;
261  }
262  if (rZ) {
263  LocalVector zDirectionInChamber = (*zSeg).localDirection();
264  if (fabs(zDirectionInChamber.y() / zDirectionInChamber.z()) > 1) {
265  if (debug) {
266  cout << " RZ segment has angle > 45 deg, skipping! " << endl;
267  cout << " Theta = " << zDirectionInChamber.theta() << endl;
268  }
269  continue;
270  }
271  }
272 
273  // Skip if the 4D segment has only 10 hits
274  if (recHits1D.size() == 10) {
275  if (debug)
276  cout << "[DTEfficiencyTask] 4D Segment with only 10 hits, skipping!" << endl;
277  continue;
278  }
279 
280  // Analyse the case of 11 recHits for MB1,MB2,MB3 and of 7 recHits for MB4
281  if ((rPhi && recHits1D.size() == 7) || (rZ && recHits1D.size() == 11)) {
282  if (debug) {
283  if (rPhi && recHits1D.size() == 7)
284  cout << "[DTEfficiencyTask] MB4 Segment with only 7 hits!" << endl;
285  if (rZ && recHits1D.size() == 11)
286  cout << "[DTEfficiencyTask] 4D Segment with only 11 hits!" << endl;
287  }
288 
289  // Find the layer without RecHits ----------------------------------------
290  const vector<const DTSuperLayer*>& SupLayers = chamber->superLayers();
291  map<DTLayerId, bool> layerMap;
292  map<DTWireId, float> wireAndPosInChamberAtLayerZ;
293  // Loop over layers and wires to fill a map
294  for (vector<const DTSuperLayer*>::const_iterator superlayer = SupLayers.begin(); superlayer != SupLayers.end();
295  superlayer++) {
296  const vector<const DTLayer*> Layers = (*superlayer)->layers();
297  for (vector<const DTLayer*>::const_iterator layer = Layers.begin(); layer != Layers.end(); layer++) {
298  layerMap.insert(make_pair((*layer)->id(), false));
299  const int firstWire = dtGeom->layer((*layer)->id())->specificTopology().firstChannel();
300  const int lastWire = dtGeom->layer((*layer)->id())->specificTopology().lastChannel();
301  for (int i = firstWire; i - lastWire <= 0; i++) {
302  DTWireId wireId((*layer)->id(), i);
303  float wireX = (*layer)->specificTopology().wirePosition(wireId.wire());
304  LocalPoint wirePosInLay(wireX, 0, 0);
305  GlobalPoint wirePosGlob = (*layer)->toGlobal(wirePosInLay);
306  LocalPoint wirePosInChamber = chamber->toLocal(wirePosGlob);
307  if ((*superlayer)->id().superlayer() == 1 || (*superlayer)->id().superlayer() == 3) {
308  wireAndPosInChamberAtLayerZ.insert(make_pair(wireId, wirePosInChamber.x()));
309  } else {
310  wireAndPosInChamberAtLayerZ.insert(make_pair(wireId, wirePosInChamber.y()));
311  }
312  }
313  }
314  }
315 
316  // Loop over segment 1D RecHit
317  map<DTLayerId, int> NumWireMap;
318  for (vector<DTRecHit1D>::const_iterator recHit = recHits1D.begin(); recHit != recHits1D.end(); recHit++) {
319  layerMap[(*recHit).wireId().layerId()] = true;
320  NumWireMap[(*recHit).wireId().layerId()] = (*recHit).wireId().wire();
321  }
322 
323  DTLayerId missLayerId;
324  //Loop over the map and find the layer without hits
325  for (map<DTLayerId, bool>::const_iterator iter = layerMap.begin(); iter != layerMap.end(); iter++) {
326  if (!(*iter).second)
327  missLayerId = (*iter).first;
328  }
329  if (debug)
330  cout << "[DTEfficiencyTask] Layer without recHits is: " << missLayerId << endl;
331  // -------------------------------------------------------
332 
333  const DTLayer* missLayer = chamber->layer(missLayerId);
334 
335  LocalPoint missLayerPosInChamber = chamber->toLocal(missLayer->toGlobal(LocalPoint(0, 0, 0)));
336 
337  // Segment position at Wire z in chamber local frame
338  LocalPoint segPosAtZLayer = (*segment4D).localPosition() + (*segment4D).localDirection() *
339  missLayerPosInChamber.z() /
340  cos((*segment4D).localDirection().theta());
341 
342  DTWireId missWireId;
343 
344  // Find the id of the cell without hit ---------------------------------------------------
345  for (map<DTWireId, float>::const_iterator wireAndPos = wireAndPosInChamberAtLayerZ.begin();
346  wireAndPos != wireAndPosInChamberAtLayerZ.end();
347  wireAndPos++) {
348  DTWireId wireId = (*wireAndPos).first;
349  if (wireId.layerId() == missLayerId) {
350  if (missLayerId.superlayerId().superlayer() == 1 || missLayerId.superlayerId().superlayer() == 3) {
351  if (fabs(segPosAtZLayer.x() - (*wireAndPos).second) < 2.1)
352  missWireId = wireId;
353  } else {
354  if (fabs(segPosAtZLayer.y() - (*wireAndPos).second) < 2.1)
355  missWireId = wireId;
356  }
357  }
358  }
359  if (debug)
360  cout << "[DTEfficiencyTask] Cell without hit is: " << missWireId << endl;
361  // ----------------------------------------------------------
362 
363  bool foundUnAssRechit = false;
364 
365  // Look for unassociated hits in this cell
366  if (wireAnd1DRecHits.find(missWireId) != wireAnd1DRecHits.end()) {
367  if (debug)
368  cout << "[DTEfficiencyTask] Unassociated Hit found!" << endl;
369  foundUnAssRechit = true;
370  }
371 
372  for (map<DTLayerId, bool>::const_iterator iter = layerMap.begin(); iter != layerMap.end(); iter++) {
373  if ((*iter).second)
374  fillHistos((*iter).first,
375  dtGeom->layer((*iter).first)->specificTopology().firstChannel(),
376  dtGeom->layer((*iter).first)->specificTopology().lastChannel(),
377  NumWireMap[(*iter).first]);
378  else
379  fillHistos((*iter).first,
380  dtGeom->layer((*iter).first)->specificTopology().firstChannel(),
381  dtGeom->layer((*iter).first)->specificTopology().lastChannel(),
382  missWireId.wire(),
383  foundUnAssRechit);
384  }
385 
386  } // End of the loop for segment with 7 or 11 recHits
387 
388  if ((rPhi && recHits1D.size() == 8) || (rZ && recHits1D.size() == 12)) {
389  map<DTLayerId, int> NumWireMap;
390  DTLayerId LayerID;
391  for (vector<DTRecHit1D>::const_iterator recHit = recHits1D.begin(); recHit != recHits1D.end(); recHit++) {
392  LayerID = (*recHit).wireId().layerId();
393  NumWireMap[LayerID] = (*recHit).wireId().wire();
394  }
395  for (map<DTLayerId, int>::const_iterator iter = NumWireMap.begin(); iter != NumWireMap.end(); iter++) {
396  fillHistos((*iter).first,
397  dtGeom->layer((*iter).first)->specificTopology().firstChannel(),
398  dtGeom->layer((*iter).first)->specificTopology().lastChannel(),
399  NumWireMap[(*iter).first]);
400  }
401  }
402 
403  } // End of loop over the 4D segments inside a sigle chamber
404  } // End of loop over all tha chamber with at least a 4D segment in the event
405 }
406 
407 // Fill a set of histograms for a given Layer
408 void DTEfficiencyTask::fillHistos(DTLayerId lId, int firstWire, int lastWire, int numWire) {
409  vector<MonitorElement*> histos = histosPerL[lId];
410  histos[0]->Fill(numWire);
411  histos[1]->Fill(numWire);
412  histos[2]->Fill(numWire);
413 }
414 
415 // Fill a set of histograms for a given Layer
416 void DTEfficiencyTask::fillHistos(DTLayerId lId, int firstWire, int lastWire, int missingWire, bool unassHit) {
417  vector<MonitorElement*> histos = histosPerL[lId];
418  if (unassHit)
419  histos[1]->Fill(missingWire);
420  histos[2]->Fill(missingWire);
421 }
422 
423 // Local Variables:
424 // show-trailing-whitespace: t
425 // truncate-lines: t
426 // End:
size
Write out results.
int station() const
Return the station number.
Definition: DTChamberId.h:42
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
LuminosityBlockNumber_t luminosityBlock() const
void dqmBeginRun(const edm::Run &, const edm::EventSetup &) override
BeginRun.
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
void beginLuminosityBlock(edm::LuminosityBlock const &lumiSeg, edm::EventSetup const &context) override
To reset the MEs.
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
T z() const
Definition: PV3DBase.h:61
static std::pair< DTLayerId, DTSuperLayerIdComparator > layersBySuperLayer(DTSuperLayerId slId)
Access by SL objects written into a RangeMap by layer.
identifier iterator
Definition: RangeMap.h:130
std::map< DTLayerId, std::vector< MonitorElement * > > histosPerL
void fillHistos(DTLayerId lId, int firstWire, int lastWire, int numWire)
constexpr std::array< uint8_t, layerIndexSize > layer
T getUntrackedParameter(std::string const &, T const &) const
int firstChannel() const
Returns the wire number of the first wire.
Definition: DTTopology.h:79
edm::EDGetTokenT< DTRecHitCollection > recHitToken_
edm::EDGetTokenT< DTRecSegment4DCollection > recHits4DToken_
C::const_iterator const_iterator
constant access iterator type
Definition: RangeMap.h:43
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
DTChamberId chamberId() const
Return the corresponding ChamberId.
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Transition
Definition: Transition.h:12
const DTGeometry * dtGeom
const DTTopology & specificTopology() const
Definition: DTLayer.cc:37
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
void analyze(const edm::Event &event, const edm::EventSetup &setup) override
~DTEfficiencyTask() override
Destructor.
int superlayer() const
Return the superlayer number (deprecated method name)
LuminosityBlockID id() const
std::vector< DTRecHit1D > specificRecHits() const
Access to specific components.
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
int layer() const
Return the layer number.
Definition: DTLayerId.h:42
const DTGeometry * muonGeom
edm::ESGetToken< DTGeometry, MuonGeometryRecord > dtGeomToken_
histos
Definition: combine.py:4
DTEfficiencyTask(const edm::ParameterSet &pset)
Constructor.
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:39
HLT enums.
int sector() const
Definition: DTChamberId.h:49
int lastChannel() const
Returns the wire number of the last wire.
Definition: DTTopology.h:81
DTSuperLayerId superlayerId() const
Return the corresponding SuperLayerId.
Definition: DTLayerId.h:45
const std::vector< const DTChamber * > & chambers() const
Return a vector of all Chamber.
Definition: DTGeometry.cc:84
DTLayerId layerId() const
Return the corresponding LayerId.
Definition: DTWireId.h:45
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
edm::ESGetToken< DTGeometry, MuonGeometryRecord > muonGeomToken_
const DTChamber * chamber(const DTChamberId &id) const
Return a DTChamber given its id.
Definition: DTGeometry.cc:90
Definition: event.py:1
Definition: Run.h:45
Geom::Theta< T > theta() const
Definition: PV3DBase.h:72
edm::ParameterSet parameters
const DTLayer * layer(const DTLayerId &id) const
Return a layer given its id.
Definition: DTGeometry.cc:96