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