CMS 3D CMS Logo

DTCalibValidation.cc
Go to the documentation of this file.
1 
2 /*
3  * See header file for a description of this class.
4  *
5  * \author G. Mila - INFN Torino
6  */
7 
9 
10 // Framework
17 
18 //Geometry
20 
21 //RecHit
24 
25 #include <iterator>
26 
27 using namespace edm;
28 using namespace std;
29 
31  : muonGeomToken_(esConsumes<edm::Transition::BeginRun>()) {
32  parameters = pset;
33 
34  //FR the following was previously in the beginJob
35 
36  // the name of the rechits collection at step 1
38  consumes<DTRecHitCollection>(edm::InputTag(parameters.getUntrackedParameter<string>("recHits1DLabel")));
39  // the name of the 2D segments
41  consumes<DTRecSegment2DCollection>(edm::InputTag(parameters.getUntrackedParameter<string>("segment2DLabel")));
42  // the name of the 4D segments
44  consumes<DTRecSegment4DCollection>(edm::InputTag(parameters.getUntrackedParameter<string>("segment4DLabel")));
45  // the counter of segments not used to compute residuals
46  wrongSegment = 0;
47  // the counter of segments used to compute residuals
48  rightSegment = 0;
49  // the analysis type
50  detailedAnalysis = parameters.getUntrackedParameter<bool>("detailedAnalysis", false);
51 
52  nevent = 0;
53 }
54 
56  //FR the following was previously in the endJob
57 
58  LogVerbatim("DTCalibValidation") << "Segments used to compute residuals: " << rightSegment;
59  LogVerbatim("DTCalibValidation") << "Segments not used to compute residuals: " << wrongSegment;
60 }
61 
63  // get the geometry
64  dtGeom = &setup.getData(muonGeomToken_);
65 }
66 
68  ++nevent;
69  LogTrace("DTCalibValidation") << "[DTCalibValidation] Analyze #Run: " << event.id().run() << " #Event: " << nevent;
70 
71  // RecHit mapping at Step 1 -------------------------------
72  map<DTWireId, vector<DTRecHit1DPair> > recHitsPerWire_1S;
73 
74  // RecHit mapping at Step 2 ------------------------------
75  map<DTWireId, vector<DTRecHit1D> > recHitsPerWire_2S;
76 
77  if (detailedAnalysis) {
78  LogTrace("DTCalibValidation") << " -- DTRecHit S1: begin analysis:";
79  // Get the rechit collection from the event
81  event.getByToken(recHits1DToken_, dtRecHits);
82  recHitsPerWire_1S = map1DRecHitsPerWire(dtRecHits.product());
83 
84  LogTrace("DTCalibValidation") << " -- DTRecHit S2: begin analysis:";
85  // Get the 2D rechits from the event
87  event.getByToken(segment2DToken_, segment2Ds);
88  recHitsPerWire_2S = map1DRecHitsPerWire(segment2Ds.product());
89  }
90 
91  // RecHit mapping at Step 3 ---------------------------------
92  LogTrace("DTCalibValidation") << " -- DTRecHit S3: begin analysis:";
93  // Get the 4D rechits from the event
95  event.getByToken(segment4DToken_, segment4Ds);
96  map<DTWireId, vector<DTRecHit1D> > recHitsPerWire_3S = map1DRecHitsPerWire(segment4Ds.product());
97 
98  // Loop over all 4D segments
99  for (DTRecSegment4DCollection::const_iterator segment = segment4Ds->begin(); segment != segment4Ds->end();
100  ++segment) {
101  if (detailedAnalysis) {
102  LogTrace("DTCalibValidation") << "Anlysis on recHit at step 1";
103  compute(dtGeom, (*segment), recHitsPerWire_1S, 1);
104 
105  LogTrace("DTCalibValidation") << "Anlysis on recHit at step 2";
106  compute(dtGeom, (*segment), recHitsPerWire_2S, 2);
107  }
108 
109  LogTrace("DTCalibValidation") << "Anlysis on recHit at step 3";
110  compute(dtGeom, (*segment), recHitsPerWire_3S, 3);
111  }
112 }
113 
114 // Return a map between DTRecHit1DPair and wireId
115 map<DTWireId, vector<DTRecHit1DPair> > DTCalibValidation::map1DRecHitsPerWire(
116  const DTRecHitCollection* dt1DRecHitPairs) {
117  map<DTWireId, vector<DTRecHit1DPair> > ret;
118 
119  for (DTRecHitCollection::const_iterator rechit = dt1DRecHitPairs->begin(); rechit != dt1DRecHitPairs->end();
120  ++rechit) {
121  ret[(*rechit).wireId()].push_back(*rechit);
122  }
123 
124  return ret;
125 }
126 
127 // Return a map between DTRecHit1D at S2 and wireId
128 map<DTWireId, vector<DTRecHit1D> > DTCalibValidation::map1DRecHitsPerWire(const DTRecSegment2DCollection* segment2Ds) {
129  map<DTWireId, vector<DTRecHit1D> > ret;
130 
131  // Loop over all 2D segments
132  for (DTRecSegment2DCollection::const_iterator segment = segment2Ds->begin(); segment != segment2Ds->end();
133  ++segment) {
134  vector<DTRecHit1D> component1DHits = (*segment).specificRecHits();
135  // Loop over all component 1D hits
136  for (vector<DTRecHit1D>::const_iterator hit = component1DHits.begin(); hit != component1DHits.end(); ++hit) {
137  ret[(*hit).wireId()].push_back(*hit);
138  }
139  }
140  return ret;
141 }
142 
143 // Return a map between DTRecHit1D at S3 and wireId
144 map<DTWireId, std::vector<DTRecHit1D> > DTCalibValidation::map1DRecHitsPerWire(
145  const DTRecSegment4DCollection* segment4Ds) {
146  map<DTWireId, vector<DTRecHit1D> > ret;
147  // Loop over all 4D segments
148  for (DTRecSegment4DCollection::const_iterator segment = segment4Ds->begin(); segment != segment4Ds->end();
149  ++segment) {
150  // Get component 2D segments
151  vector<const TrackingRecHit*> segment2Ds = (*segment).recHits();
152  // Loop over 2D segments:
153  for (vector<const TrackingRecHit*>::const_iterator segment2D = segment2Ds.begin(); segment2D != segment2Ds.end();
154  ++segment2D) {
155  // Get 1D component rechits
156  vector<const TrackingRecHit*> hits = (*segment2D)->recHits();
157  // Loop over them
158  for (vector<const TrackingRecHit*>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
159  const DTRecHit1D* hit1D = dynamic_cast<const DTRecHit1D*>(*hit);
160  ret[hit1D->wireId()].push_back(*hit1D);
161  }
162  }
163  }
164 
165  return ret;
166 }
167 
168 // Find the RecHit closest to the segment4D
169 template <typename type>
171  DTWireId wireId,
172  const vector<type>& recHits,
173  const float segmDist) {
174  float res = 99999;
175  const type* theBestRecHit = nullptr;
176  // Loop over RecHits within the cell
177  for (typename vector<type>::const_iterator recHit = recHits.begin(); recHit != recHits.end(); ++recHit) {
178  float distTmp = recHitDistFromWire(*recHit, layer);
179  if (fabs(distTmp - segmDist) < res) {
180  res = fabs(distTmp - segmDist);
181  theBestRecHit = &(*recHit);
182  }
183  } // End of loop over RecHits within the cell
184 
185  return theBestRecHit;
186 }
187 
188 // Compute the distance from wire (cm) of a hits in a DTRecHit1DPair
190  return fabs(hitPair.localPosition(DTEnums::Left).x() - hitPair.localPosition(DTEnums::Right).x()) / 2.;
191 }
192 
193 // Compute the distance from wire (cm) of a hits in a DTRecHit1D
195  return fabs(recHit.localPosition().x() - layer->specificTopology().wirePosition(recHit.wireId().wire()));
196 }
197 
198 // Compute the position (cm) of a hits in a DTRecHit1DPair
200  const DTRecHit1DPair& hitPair, const DTLayer* layer, const DTChamber* chamber, float segmentPos, int sl) {
201  // Get the layer and the wire position
202  GlobalPoint hitPosGlob_right = layer->toGlobal(hitPair.localPosition(DTEnums::Right));
203  LocalPoint hitPosInChamber_right = chamber->toLocal(hitPosGlob_right);
204  GlobalPoint hitPosGlob_left = layer->toGlobal(hitPair.localPosition(DTEnums::Left));
205  LocalPoint hitPosInChamber_left = chamber->toLocal(hitPosGlob_left);
206 
207  float recHitPos = -1;
208  if (sl != 2) {
209  if (fabs(hitPosInChamber_left.x() - segmentPos) < fabs(hitPosInChamber_right.x() - segmentPos))
210  recHitPos = hitPosInChamber_left.x();
211  else
212  recHitPos = hitPosInChamber_right.x();
213  } else {
214  if (fabs(hitPosInChamber_left.y() - segmentPos) < fabs(hitPosInChamber_right.y() - segmentPos))
215  recHitPos = hitPosInChamber_left.y();
216  else
217  recHitPos = hitPosInChamber_right.y();
218  }
219 
220  return recHitPos;
221 }
222 
223 // Compute the position (cm) of a hits in a DTRecHit1D
225  const DTRecHit1D& recHit, const DTLayer* layer, const DTChamber* chamber, float segmentPos, int sl) {
226  // Get the layer and the wire position
227  GlobalPoint recHitPosGlob = layer->toGlobal(recHit.localPosition());
228  LocalPoint recHitPosInChamber = chamber->toLocal(recHitPosGlob);
229 
230  float recHitPos = -1;
231  if (sl != 2)
232  recHitPos = recHitPosInChamber.x();
233  else
234  recHitPos = recHitPosInChamber.y();
235 
236  return recHitPos;
237 }
238 
239 // Compute the residuals
240 template <typename type>
242  const DTRecSegment4D& segment,
243  const std::map<DTWireId, std::vector<type> >& recHitsPerWire,
244  int step) {
245  bool computeResidual = true;
246 
247  // Get all 1D RecHits at step 3 within the 4D segment
248  vector<DTRecHit1D> recHits1D_S3;
249 
250  // Get 1D RecHits at Step 3 and select only events with
251  // 8 hits in phi and 4 hits in theta (if any)
252  const DTChamberRecSegment2D* phiSeg = segment.phiSegment();
253  if (phiSeg) {
254  vector<DTRecHit1D> phiRecHits = phiSeg->specificRecHits();
255  if (phiRecHits.size() != 8) {
256  LogTrace("DTCalibValidation") << "[DTCalibValidation] Phi segments has: " << phiRecHits.size()
257  << " hits, skipping"; // FIXME: info output
258  computeResidual = false;
259  }
260  copy(phiRecHits.begin(), phiRecHits.end(), back_inserter(recHits1D_S3));
261  }
262  if (!phiSeg) {
263  LogTrace("DTCalibValidation") << " [DTCalibValidation] 4D segment has not the phi segment! ";
264  computeResidual = false;
265  }
266 
267  if (segment.dimension() == 4) {
268  const DTSLRecSegment2D* zSeg = segment.zSegment();
269  if (zSeg) {
270  vector<DTRecHit1D> zRecHits = zSeg->specificRecHits();
271  if (zRecHits.size() != 4) {
272  LogTrace("DTCalibValidation") << "[DTCalibValidation] Theta segments has: " << zRecHits.size()
273  << " hits, skipping"; // FIXME: info output
274  computeResidual = false;
275  }
276  copy(zRecHits.begin(), zRecHits.end(), back_inserter(recHits1D_S3));
277  }
278  if (!zSeg) {
279  LogTrace("DTCalibValidation") << " [DTCalibValidation] 4D segment has not the z segment! ";
280  computeResidual = false;
281  }
282  }
283 
284  if (!computeResidual)
285  ++wrongSegment;
286  if (computeResidual) {
287  ++rightSegment;
288  // Loop over 1D RecHit inside 4D segment
289  for (vector<DTRecHit1D>::const_iterator recHit1D = recHits1D_S3.begin(); recHit1D != recHits1D_S3.end();
290  ++recHit1D) {
291  const DTWireId wireId = (*recHit1D).wireId();
292 
293  // Get the layer and the wire position
294  const DTLayer* layer = dtGeom->layer(wireId);
295  float wireX = layer->specificTopology().wirePosition(wireId.wire());
296 
297  // Extrapolate the segment to the z of the wire
298  // Get wire position in chamber RF
299  // (y and z must be those of the hit to be coherent in the transf. of RF in case of rotations of the layer alignment)
300  LocalPoint wirePosInLay(wireX, (*recHit1D).localPosition().y(), (*recHit1D).localPosition().z());
301  GlobalPoint wirePosGlob = layer->toGlobal(wirePosInLay);
302  const DTChamber* chamber = dtGeom->chamber((*recHit1D).wireId().layerId().chamberId());
303  LocalPoint wirePosInChamber = chamber->toLocal(wirePosGlob);
304 
305  // Segment position at Wire z in chamber local frame
306  LocalPoint segPosAtZWire = segment.localPosition() + segment.localDirection() * wirePosInChamber.z() /
307  cos(segment.localDirection().theta());
308 
309  // Compute the distance of the segment from the wire
310  int sl = wireId.superlayer();
311  float SegmDistance = -1;
312  if (sl == 1 || sl == 3) {
313  // RPhi SL
314  SegmDistance = fabs(wirePosInChamber.x() - segPosAtZWire.x());
315  LogTrace("DTCalibValidation") << "SegmDistance: " << SegmDistance;
316  } else if (sl == 2) {
317  // RZ SL
318  SegmDistance = fabs(segPosAtZWire.y() - wirePosInChamber.y());
319  LogTrace("DTCalibValidation") << "SegmDistance: " << SegmDistance;
320  }
321  if (SegmDistance > 2.1)
322  LogTrace("DTCalibValidation") << " Warning: dist segment-wire: " << SegmDistance;
323 
324  // Look for RecHits in the same cell
325  if (recHitsPerWire.find(wireId) == recHitsPerWire.end()) {
326  LogTrace("DTCalibValidation") << " No RecHit found at Step: " << step << " in cell: " << wireId;
327  } else {
328  const vector<type>& recHits = recHitsPerWire.at(wireId);
329  LogTrace("DTCalibValidation") << " " << recHits.size() << " RecHits, Step " << step
330  << " in channel: " << wireId;
331 
332  // Get the layer
333  const DTLayer* layer = dtGeom->layer(wireId);
334  // Find the best RecHits
335  const type* theBestRecHit = findBestRecHit(layer, wireId, recHits, SegmDistance);
336  // Compute the distance of the recHit from the wire
337  float recHitWireDist = recHitDistFromWire(*theBestRecHit, layer);
338  LogTrace("DTCalibValidation") << "recHitWireDist: " << recHitWireDist;
339 
340  // Compute the residuals
341  float residualOnDistance = recHitWireDist - SegmDistance;
342  LogTrace("DTCalibValidation") << "WireId: " << wireId << " ResidualOnDistance: " << residualOnDistance;
343  float residualOnPosition = -1;
344  float recHitPos = -1;
345  if (sl == 1 || sl == 3) {
346  recHitPos = recHitPosition(*theBestRecHit, layer, chamber, segPosAtZWire.x(), sl);
347  residualOnPosition = recHitPos - segPosAtZWire.x();
348  } else {
349  recHitPos = recHitPosition(*theBestRecHit, layer, chamber, segPosAtZWire.y(), sl);
350  residualOnPosition = recHitPos - segPosAtZWire.y();
351  }
352  LogTrace("DTCalibValidation") << "WireId: " << wireId << " ResidualOnPosition: " << residualOnPosition;
353 
354  // Fill the histos
355  if (sl == 1 || sl == 3)
356  fillHistos(wireId.superlayerId(),
357  SegmDistance,
358  residualOnDistance,
359  (wirePosInChamber.x() - segPosAtZWire.x()),
360  residualOnPosition,
361  step);
362  else
363  fillHistos(wireId.superlayerId(),
364  SegmDistance,
365  residualOnDistance,
366  (wirePosInChamber.y() - segPosAtZWire.y()),
367  residualOnPosition,
368  step);
369  }
370  }
371  }
372 }
373 
375  edm::Run const& iRun,
376  edm::EventSetup const& iSetup) {
377  //FR substitute the DQMStore instance by ibooker
378  ibooker.setCurrentFolder("DT/DTCalibValidation");
379 
380  DTSuperLayerId slId;
381 
382  // Loop over all the chambers
383  vector<const DTChamber*>::const_iterator ch_it = dtGeom->chambers().begin();
384  vector<const DTChamber*>::const_iterator ch_end = dtGeom->chambers().end();
385  for (; ch_it != ch_end; ++ch_it) {
386  vector<const DTSuperLayer*>::const_iterator sl_it = (*ch_it)->superLayers().begin();
387  vector<const DTSuperLayer*>::const_iterator sl_end = (*ch_it)->superLayers().end();
388  // Loop over the SLs
389  for (; sl_it != sl_end; ++sl_it) {
390  slId = (*sl_it)->id();
391 
392  int firstStep = 1;
393  if (!detailedAnalysis)
394  firstStep = 3;
395  // Loop over the 3 steps
396  for (int step = firstStep; step <= 3; ++step) {
397  LogTrace("DTCalibValidation") << " Booking histos for SL: " << slId;
398 
399  // Compose the chamber name
400  stringstream wheel;
401  wheel << slId.wheel();
402  stringstream station;
403  station << slId.station();
404  stringstream sector;
405  sector << slId.sector();
406  stringstream superLayer;
407  superLayer << slId.superlayer();
408  // Define the step
409  stringstream Step;
410  Step << step;
411 
412  string slHistoName = "_STEP" + Step.str() + "_W" + wheel.str() + "_St" + station.str() + "_Sec" + sector.str() +
413  "_SL" + superLayer.str();
414 
415  ibooker.setCurrentFolder("DT/DTCalibValidation/Wheel" + wheel.str() + "/Station" + station.str() + "/Sector" +
416  sector.str());
417  // Create the monitor elements
418  vector<MonitorElement*> histos;
419  // Note the order matters
420  histos.push_back(ibooker.book1D(
421  "hResDist" + slHistoName, "Residuals on the distance from wire (rec_hit - segm_extr) (cm)", 200, -0.4, 0.4));
422  histos.push_back(
423  ibooker.book2D("hResDistVsDist" + slHistoName,
424  "Residuals on the distance (cm) from wire (rec_hit - segm_extr) vs distance (cm)",
425  100,
426  0,
427  2.5,
428  200,
429  -0.4,
430  0.4));
431  if (detailedAnalysis) {
432  histos.push_back(ibooker.book1D("hResPos" + slHistoName,
433  "Residuals on the position from wire (rec_hit - segm_extr) (cm)",
434  200,
435  -0.4,
436  0.4));
437  histos.push_back(
438  ibooker.book2D("hResPosVsPos" + slHistoName,
439  "Residuals on the position (cm) from wire (rec_hit - segm_extr) vs distance (cm)",
440  200,
441  -2.5,
442  2.5,
443  200,
444  -0.4,
445  0.4));
446  }
447 
448  histosPerSL[make_pair(slId, step)] = histos;
449  }
450  }
451  }
452 }
453 
454 // Fill a set of histograms for a given SL
456  DTSuperLayerId slId, float distance, float residualOnDistance, float position, float residualOnPosition, int step) {
457  // FIXME: optimization of the number of searches
458  vector<MonitorElement*> histos = histosPerSL[make_pair(slId, step)];
459  histos[0]->Fill(residualOnDistance);
460  histos[1]->Fill(distance, residualOnDistance);
461  if (detailedAnalysis) {
462  histos[2]->Fill(residualOnPosition);
463  histos[3]->Fill(position, residualOnPosition);
464  }
465 }
466 
467 // Local Variables:
468 // show-trailing-whitespace: t
469 // truncate-lines: t
470 // End:
Log< level::Info, true > LogVerbatim
int station() const
Return the station number.
Definition: DTChamberId.h:45
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const DTGeometry * dtGeom
float recHitDistFromWire(const DTRecHit1DPair &hitPair, const DTLayer *layer)
int wire() const
Return the wire number.
Definition: DTWireId.h:45
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
T z() const
Definition: PV3DBase.h:61
ret
prodAgent to be discontinued
T const * product() const
Definition: Handle.h:70
LocalVector localDirection() const override
Local direction in Chamber frame.
LocalPoint localPosition() const override
int dimension() const override
Dimension (in parameter space)
LocalPoint localPosition() const override
Local position in Chamber frame.
const DTSLRecSegment2D * zSegment() const
The Z segment: 0 if not zed projection available.
Definition: Electron.h:6
#define LogTrace(id)
T getUntrackedParameter(std::string const &, T const &) const
void compute(const DTGeometry *dtGeom, const DTRecSegment4D &segment, const std::map< DTWireId, std::vector< type > > &recHitsPerWire, int step)
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
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
edm::EDGetTokenT< DTRecSegment4DCollection > segment4DToken_
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Transition
Definition: Transition.h:12
std::map< DTWireId, std::vector< DTRecHit1DPair > > map1DRecHitsPerWire(const DTRecHitCollection *dt1DRecHitPairs)
void fillHistos(DTSuperLayerId slId, float distance, float residualOnDistance, float position, float residualOnPosition, int step)
~DTCalibValidation() override
Destructor.
int superlayer() const
Return the superlayer number (deprecated method name)
void analyze(const edm::Event &event, const edm::EventSetup &setup) override
const DTChamberRecSegment2D * phiSegment() const
The superPhi segment: 0 if no phi projection available.
std::vector< DTRecHit1D > specificRecHits() const
Access to specific components.
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:221
edm::EDGetTokenT< DTRecHitCollection > recHits1DToken_
edm::ESGetToken< DTGeometry, MuonGeometryRecord > muonGeomToken_
histos
Definition: combine.py:4
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:42
HLT enums.
DTWireId wireId() const
Return the wireId.
Definition: DTRecHit1D.h:76
int sector() const
Definition: DTChamberId.h:52
void dqmBeginRun(const edm::Run &r, const edm::EventSetup &c) override
BeginRun.
static int position[264][3]
Definition: ReadPGInfo.cc:289
std::map< std::pair< DTSuperLayerId, int >, std::vector< MonitorElement * > > histosPerSL
DTCalibValidation(const edm::ParameterSet &pset)
Constructor.
edm::ParameterSet parameters
const std::vector< const DTChamber * > & chambers() const
Return a vector of all Chamber.
Definition: DTGeometry.cc:84
step
Definition: StallMonitor.cc:83
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
float recHitPosition(const DTRecHit1DPair &hitPair, const DTLayer *layer, const DTChamber *chamber, float segmPos, int sl)
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
const type * findBestRecHit(const DTLayer *layer, DTWireId wireId, const std::vector< type > &recHits, const float simHitDist)
edm::EDGetTokenT< DTRecSegment2DCollection > segment2DToken_
const DTLayer * layer(const DTLayerId &id) const
Return a layer given its id.
Definition: DTGeometry.cc:96