CMS 3D CMS Logo

OverlapValidation.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Alignment/OfflineValidation
4 // Class: OverlapValidation
5 //
11 //
12 // Original Authors: Wolfgang Adam, Keith Ulmer
13 // Created: Thu Oct 11 14:53:32 CEST 2007
14 // $Id: OverlapValidation.cc,v 1.16 2009/11/04 19:40:27 kaulmer Exp $
15 //
16 //
17 
18 // system include files
19 #include <memory>
20 
21 // user include files
24 
30 
38 
42 
48 
66 
76 #include "TFile.h"
77 #include "TTree.h"
78 
79 #include <vector>
80 #include <utility>
81 
82 using namespace std;
83 //
84 // class decleration
85 //
86 
88 public:
89  explicit OverlapValidation(const edm::ParameterSet&);
90  ~OverlapValidation() override;
91 
92 private:
93  typedef vector<Trajectory> TrajectoryCollection;
94 
97  void analyze(const edm::Event&, const edm::EventSetup&) override;
98  void endJob() override;
99 
100  virtual void analyze(const Trajectory&, const Propagator&, TrackerHitAssociator&, const TrackerTopology* const tTopo);
101  int layerFromId(const DetId&, const TrackerTopology* const tTopo) const;
102 
103  // ----------member data ---------------------------
107  bool doSimHit_;
110 
112  int overlapCounts_[3];
113 
114  TTree* rootTree_;
116  const bool addExtraBranches_;
117  const int minHitsCut_;
118  const float chi2ProbCut_;
119 
122  unsigned short hitCounts_[2];
123  float chi2_[2];
124  unsigned int overlapIds_[2];
125  float predictedPositions_[3][2];
126  float predictedLocalParameters_[5][2];
127  float predictedLocalErrors_[5][2];
132  float hitPositions_[2];
133  float hitErrors_[2];
134  float hitPositionsY_[2];
135  float hitErrorsY_[2];
136  float simHitPositions_[2];
137  float simHitPositionsY_[2];
138  float clusterWidthX_[2];
139  float clusterWidthY_[2];
140  float clusterSize_[2];
142  int edge_[2];
143 
144  vector<bool> acceptLayer;
145  float momentum_;
148 
149  //added by Heshy and Jared
150  float moduleX_[2];
151  float moduleY_[2];
152  float moduleZ_[2];
153  int subdetID;
157  //added by Jason
158  float localxdotglobalphi_[2];
159  float localxdotglobalr_[2];
160  float localxdotglobalz_[2];
161  float localxdotglobalx_[2];
162  float localxdotglobaly_[2];
163  float localydotglobalphi_[2];
164  float localydotglobalr_[2];
165  float localydotglobalz_[2];
166  float localydotglobalx_[2];
167  float localydotglobaly_[2];
168 };
169 
170 //
171 // constants, enums and typedefs
172 //
173 
174 //
175 // static data member definitions
176 //
177 
178 using std::vector;
179 //
180 // constructors and destructor
181 //
183  : config_(iConfig),
184  rootTree_(nullptr),
185  FileInPath_("CalibTracker/SiStripCommon/data/SiStripDetInfo.dat"),
186  addExtraBranches_(false),
187  minHitsCut_(6),
188  chi2ProbCut_(0.001) {
190  //now do what ever initialization is needed
191  trajectoryTag_ = iConfig.getParameter<edm::InputTag>("trajectories");
193  doSimHit_ = iConfig.getParameter<bool>("associateStrip");
195 
196  overlapCounts_[0] = 0; // #trajectories
197  overlapCounts_[1] = 0; // #hits
198  overlapCounts_[2] = 0; // #overlap hits
199  acceptLayer.resize(7, false);
200  acceptLayer[PixelSubdetector::PixelBarrel] = iConfig.getParameter<bool>("usePXB");
201  acceptLayer[PixelSubdetector::PixelEndcap] = iConfig.getParameter<bool>("usePXF");
202  acceptLayer[StripSubdetector::TIB] = iConfig.getParameter<bool>("useTIB");
203  acceptLayer[StripSubdetector::TOB] = iConfig.getParameter<bool>("useTOB");
204  acceptLayer[StripSubdetector::TID] = iConfig.getParameter<bool>("useTID");
205  acceptLayer[StripSubdetector::TEC] = iConfig.getParameter<bool>("useTEC");
206  barrelOnly_ = iConfig.getParameter<bool>("barrelOnly");
207 
209  //
210  // root output
211  //
212  rootTree_ = fs->make<TTree>("Overlaps", "Overlaps");
213  if (addExtraBranches_) {
214  rootTree_->Branch("hitCounts", hitCounts_, "found/s:lost/s");
215  rootTree_->Branch("chi2", chi2_, "chi2/F:ndf/F");
216  rootTree_->Branch("path", &overlapPath_, "path/F");
217  }
218  rootTree_->Branch("layer", &layer_, "layer/i");
219  rootTree_->Branch("detids", overlapIds_, "id[2]/i");
220  rootTree_->Branch("predPos", predictedPositions_, "gX[2]/F:gY[2]/F:gZ[2]/F");
221  rootTree_->Branch("predPar", predictedLocalParameters_, "predQP[2]/F:predDX[2]/F:predDY[2]/F:predX[2]/F:predY[2]/F");
222  rootTree_->Branch("predErr", predictedLocalErrors_, "predEQP[2]/F:predEDX[2]/F:predEDY[2]/F:predEX[2]/F:predEY[2]/F");
223  rootTree_->Branch("predEDeltaX", &predictedDeltaXError_, "sigDeltaX/F");
224  rootTree_->Branch("predEDeltaY", &predictedDeltaYError_, "sigDeltaY/F");
225  rootTree_->Branch("relSignX", &relativeXSign_, "relSignX/B");
226  rootTree_->Branch("relSignY", &relativeYSign_, "relSignY/B");
227  rootTree_->Branch("hitX", hitPositions_, "hitX[2]/F");
228  rootTree_->Branch("hitEX", hitErrors_, "hitEX[2]/F");
229  rootTree_->Branch("hitY", hitPositionsY_, "hitY[2]/F");
230  rootTree_->Branch("hitEY", hitErrorsY_, "hitEY[2]/F");
231  if (addExtraBranches_) {
232  rootTree_->Branch("simX", simHitPositions_, "simX[2]/F");
233  rootTree_->Branch("simY", simHitPositionsY_, "simY[2]/F");
234  rootTree_->Branch("clusterSize", clusterSize_, "clusterSize[2]/F");
235  rootTree_->Branch("clusterWidthX", clusterWidthX_, "clusterWidthX[2]/F");
236  rootTree_->Branch("clusterWidthY", clusterWidthY_, "clusterWidthY[2]/F");
237  rootTree_->Branch("clusterCharge", clusterCharge_, "clusterCharge[2]/i");
238  rootTree_->Branch("edge", edge_, "edge[2]/I");
239  }
240  rootTree_->Branch("momentum", &momentum_, "momentum/F");
241  rootTree_->Branch("run", &run_, "run/i");
242  rootTree_->Branch("event", &event_, "event/i");
243  rootTree_->Branch("subdetID", &subdetID, "subdetID/I");
244  rootTree_->Branch("moduleX", moduleX_, "moduleX[2]/F");
245  rootTree_->Branch("moduleY", moduleY_, "moduleY[2]/F");
246  rootTree_->Branch("moduleZ", moduleZ_, "moduleZ[2]/F");
247  rootTree_->Branch("localxdotglobalphi", localxdotglobalphi_, "localxdotglobalphi[2]/F");
248  rootTree_->Branch("localxdotglobalr", localxdotglobalr_, "localxdotglobalr[2]/F");
249  rootTree_->Branch("localxdotglobalz", localxdotglobalz_, "localxdotglobalz[2]/F");
250  rootTree_->Branch("localxdotglobalx", localxdotglobalx_, "localxdotglobalx[2]/F");
251  rootTree_->Branch("localxdotglobaly", localxdotglobaly_, "localxdotglobaly[2]/F");
252  rootTree_->Branch("localydotglobalphi", localydotglobalphi_, "localydotglobalphi[2]/F");
253  rootTree_->Branch("localydotglobalr", localydotglobalr_, "localydotglobalr[2]/F");
254  rootTree_->Branch("localydotglobalz", localydotglobalz_, "localydotglobalz[2]/F");
255  rootTree_->Branch("localydotglobalx", localydotglobalx_, "localydotglobalx[2]/F");
256  rootTree_->Branch("localydotglobaly", localydotglobaly_, "localydotglobaly[2]/F");
257 }
258 
260  edm::LogWarning w("Overlaps");
261  // do anything here that needs to be done at desctruction time
262  // (e.g. close files, deallocate resources etc.)
263 
264  w << "Counters =";
265  w << " Number of tracks: " << overlapCounts_[0];
266  w << " Number of valid hits: " << overlapCounts_[1];
267  w << " Number of overlaps: " << overlapCounts_[2];
268 }
269 
270 //
271 // member functions
272 //
273 
274 // ------------ method called to for each event ------------
276  using namespace edm;
277  //
278  // mag field & search tracker
279  //
280  edm::ESHandle<MagneticField> magFieldHandle;
281  iSetup.get<IdealMagneticFieldRecord>().get(magFieldHandle);
282  magField_ = magFieldHandle.product();
283  //
284  // propagator
285  //
287  //
288  // geometry
289 
290  //
291  edm::ESHandle<TrackerGeometry> geometryHandle;
292  iSetup.get<TrackerDigiGeometryRecord>().get(geometryHandle);
293  trackerGeometry_ = geometryHandle.product();
294  //
295  // make associator for SimHits
296  //
298  if (doSimHit_) {
300  associator = new TrackerHitAssociator(iEvent, hitassociatorconfig);
301  } else {
302  associator = nullptr;
303  }
304 
305  //if(doSimHit_) associator = new TrackerHitAssociator(iEvent, config_); else associator = 0;
306 
307  //
308  // trajectories (from refit)
309  //
310  //typedef vector<Trajectory> TrajectoryCollection;
311  edm::Handle<TrajectoryCollection> trajectoryCollectionHandle;
312  iEvent.getByToken(trajectoryToken_, trajectoryCollectionHandle);
313  const TrajectoryCollection* const trajectoryCollection = trajectoryCollectionHandle.product();
314 
315  //
316  // loop over trajectories from refit
317  edm::ESHandle<TrackerTopology> tTopoHandle;
318  iSetup.get<TrackerTopologyRcd>().get(tTopoHandle);
319  const TrackerTopology* const tTopo = tTopoHandle.product();
320  for (const auto& trajectory : *trajectoryCollection)
321  analyze(trajectory, propagator, *associator, tTopo);
322 
323  run_ = iEvent.id().run();
324  event_ = iEvent.id().event();
325 }
326 
327 void OverlapValidation::analyze(const Trajectory& trajectory,
328  const Propagator& propagator,
330  const TrackerTopology* const tTopo) {
331  typedef std::pair<const TrajectoryMeasurement*, const TrajectoryMeasurement*> Overlap;
332  typedef vector<Overlap> OverlapContainer;
333  ++overlapCounts_[0];
334 
335  OverlapContainer overlapHits;
336 
337  // quality cuts on trajectory
338  // min. # hits / matched hits
339 
340  if (trajectory.foundHits() < minHitsCut_)
341  return;
342  if (ChiSquaredProbability((double)(trajectory.chiSquared()), (double)(trajectory.ndof(false))) < chi2ProbCut_)
343  return;
344  //
345  // loop over measurements in the trajectory and calculate residuals
346  //
347 
348  vector<TrajectoryMeasurement> measurements(trajectory.measurements());
349  for (vector<TrajectoryMeasurement>::const_iterator itm = measurements.begin(); itm != measurements.end(); ++itm) {
350  //
351  // skip "invalid" (i.e. missing) hits
352  //
353  ConstRecHitPointer hit = itm->recHit();
354  DetId id = hit->geographicalId();
355  int layer(layerFromId(id, tTopo));
356  int subDet = id.subdetId();
357 
358  if (!hit->isValid()) {
359  edm::LogVerbatim("OverlapValidation") << "Invalid";
360  continue;
361  }
362  if (barrelOnly_ && (subDet == StripSubdetector::TID || subDet == StripSubdetector::TEC))
363  return;
364 
365  //edm::LogVerbatim("OverlapValidation") << "Check " <<subDet << ", layer = " << layer<<" stereo: "<< ((subDet > 2)?(SiStripDetId(id).stereo()):2);
366  //cout << "Check SubID " <<subDet << ", layer = " << layer<<" stereo: "<< ((subDet > 2)?(SiStripDetId(id).stereo()):2) << endl;
367 
368  //
369  // check for overlap: same subdet-id && layer number for
370  // two consecutive hits
371  //
372  ++overlapCounts_[1];
373  if ((layer != -1) && (acceptLayer[subDet])) {
374  for (vector<TrajectoryMeasurement>::const_iterator itmCompare = itm - 1;
375  itmCompare >= measurements.begin() && itmCompare > itm - 4;
376  --itmCompare) {
377  DetId compareId = itmCompare->recHit()->geographicalId();
378 
379  if (subDet != compareId.subdetId() || layer != layerFromId(compareId, tTopo))
380  break;
381  if (!itmCompare->recHit()->isValid())
382  continue;
383  if ((subDet == PixelSubdetector::PixelBarrel || subDet == PixelSubdetector::PixelEndcap) ||
384  (SiStripDetId(id).stereo() == SiStripDetId(compareId).stereo())) {
385  overlapHits.push_back(std::make_pair(&(*itmCompare), &(*itm)));
386  //edm::LogVerbatim("OverlapValidation") << "adding pair "<< ((subDet > 2)?(SiStripDetId(id).stereo()) : 2)
387  // << " from layer = " << layer;
388  //cout << "adding pair "<< ((subDet > 2)?(SiStripDetId(id).stereo()) : 2) << " from subDet = " << subDet << " and layer = " << layer;
389  //cout << " \t"<<run_<< "\t"<<event_<<"\t";
390  //cout << min(id.rawId(),compareId.rawId())<<"\t"<<max(id.rawId(),compareId.rawId())<<endl;
391  if (SiStripDetId(id).glued() == id.rawId())
392  edm::LogInfo("Overlaps") << "BAD GLUED: Have glued layer with id = " << id.rawId()
393  << " and glued id = " << SiStripDetId(id).glued()
394  << " and stereo = " << SiStripDetId(id).stereo() << endl;
395  if (SiStripDetId(compareId).glued() == compareId.rawId())
396  edm::LogInfo("Overlaps") << "BAD GLUED: Have glued layer with id = " << compareId.rawId()
397  << " and glued id = " << SiStripDetId(compareId).glued()
398  << " and stereo = " << SiStripDetId(compareId).stereo() << endl;
399  break;
400  }
401  }
402  }
403  }
404 
405  //
406  // Loop over all overlap pairs.
407  //
408  hitCounts_[0] = trajectory.foundHits();
409  hitCounts_[1] = trajectory.lostHits();
410  chi2_[0] = trajectory.chiSquared();
411  chi2_[1] = trajectory.ndof(false);
412 
413  for (const auto& overlapHit : overlapHits) {
414  //
415  // create reference state @ module 1 (no info from overlap hits)
416  //
417  ++overlapCounts_[2];
418  // backward predicted state at module 1
419  TrajectoryStateOnSurface bwdPred1 = overlapHit.first->backwardPredictedState();
420  if (!bwdPred1.isValid())
421  continue;
422  //cout << "momentum from backward predicted state = " << bwdPred1.globalMomentum().mag() << endl;
423  // forward predicted state at module 2
424  TrajectoryStateOnSurface fwdPred2 = overlapHit.second->forwardPredictedState();
425  //cout << "momentum from forward predicted state = " << fwdPred2.globalMomentum().mag() << endl;
426  if (!fwdPred2.isValid())
427  continue;
428  // extrapolate fwdPred2 to module 1
429  TrajectoryStateOnSurface fwdPred2At1 = propagator.propagate(fwdPred2, bwdPred1.surface());
430  if (!fwdPred2At1.isValid())
431  continue;
432  // combine fwdPred2At1 with bwdPred1 (ref. state, best estimate without hits 1 and 2)
433  TrajectoryStateOnSurface comb1 = combiner_.combine(bwdPred1, fwdPred2At1);
434  if (!comb1.isValid())
435  continue;
436  //
437  // propagation of reference parameters to module 2
438  //
439  std::pair<TrajectoryStateOnSurface, double> tsosWithS = propagator.propagateWithPath(comb1, fwdPred2.surface());
440  TrajectoryStateOnSurface comb1At2 = tsosWithS.first;
441  if (!comb1At2.isValid())
442  continue;
443  //distance of propagation from one surface to the next==could cut here
444  overlapPath_ = tsosWithS.second;
445  if (abs(overlapPath_) > 15)
446  continue; //cut to remove hit pairs > 15 cm apart
447  // global position on module 1
449  predictedPositions_[0][0] = position.x();
450  predictedPositions_[1][0] = position.y();
451  predictedPositions_[2][0] = position.z();
452  momentum_ = comb1.globalMomentum().mag();
453  //cout << "momentum from combination = " << momentum_ << endl;
454  //cout << "magnetic field from TSOS = " << comb1.magneticField()->inTesla(position).mag() << endl;
455  // local parameters and errors on module 1
456  AlgebraicVector5 pars = comb1.localParameters().vector();
457  AlgebraicSymMatrix55 errs = comb1.localError().matrix();
458  for (int i = 0; i < 5; ++i) {
459  predictedLocalParameters_[i][0] = pars[i];
460  predictedLocalErrors_[i][0] = sqrt(errs(i, i));
461  }
462  // global position on module 2
463  position = comb1At2.globalPosition();
464  predictedPositions_[0][1] = position.x();
465  predictedPositions_[1][1] = position.y();
466  predictedPositions_[2][1] = position.z();
467  // local parameters and errors on module 2
468  pars = comb1At2.localParameters().vector();
469  errs = comb1At2.localError().matrix();
470  for (int i = 0; i < 5; ++i) {
471  predictedLocalParameters_[i][1] = pars[i];
472  predictedLocalErrors_[i][1] = sqrt(errs(i, i));
473  }
474 
475  //print out local errors in X to check
476  //cout << "Predicted local error in X at 1 = " << predictedLocalErrors_[3][0] << " and predicted local error in X at 2 is = " << predictedLocalErrors_[3][1] << endl;
477  //cout << "Predicted local error in Y at 1 = " << predictedLocalErrors_[4][0] << " and predicted local error in Y at 2 is = " << predictedLocalErrors_[4][1] << endl;
478 
479  //
480  // jacobians (local-to-global@1,global 1-2,global-to-local@2)
481  //
482  JacobianLocalToCurvilinear jacLocToCurv(comb1.surface(), comb1.localParameters(), *magField_);
483  AnalyticalCurvilinearJacobian jacCurvToCurv(
484  comb1.globalParameters(), comb1At2.globalPosition(), comb1At2.globalMomentum(), tsosWithS.second);
485  JacobianCurvilinearToLocal jacCurvToLoc(comb1At2.surface(), comb1At2.localParameters(), *magField_);
486  // combined jacobian local-1-to-local-2
487  AlgebraicMatrix55 jacobian = jacLocToCurv.jacobian() * jacCurvToCurv.jacobian() * jacCurvToLoc.jacobian();
488  // covariance on module 1
489  AlgebraicSymMatrix55 covComb1 = comb1.localError().matrix();
490  // variance and correlations for predicted local_x on modules 1 and 2
491  double c00 = covComb1(3, 3);
492  double c10(0.);
493  double c11(0.);
494  for (int i = 1; i < 5; ++i) {
495  c10 += jacobian(3, i) * covComb1(i, 3);
496  for (int j = 1; j < 5; ++j)
497  c11 += jacobian(3, i) * covComb1(i, j) * jacobian(3, j);
498  }
499  // choose relative sign in order to minimize error on difference
500  double diff = c00 - 2 * fabs(c10) + c11;
501  diff = diff > 0 ? sqrt(diff) : -sqrt(-diff);
503  relativeXSign_ = c10 > 0 ? -1 : 1;
504  //
505  // now find variance and correlations for predicted local_y
506  double c00Y = covComb1(4, 4);
507  double c10Y(0.);
508  double c11Y(0.);
509  for (int i = 1; i < 5; ++i) {
510  c10Y += jacobian(4, i) * covComb1(i, 4);
511  for (int j = 1; j < 5; ++j)
512  c11Y += jacobian(4, i) * covComb1(i, j) * jacobian(4, j);
513  }
514  double diffY = c00Y - 2 * fabs(c10Y) + c11Y;
515  diffY = diffY > 0 ? sqrt(diffY) : -sqrt(-diffY);
516  predictedDeltaYError_ = diffY;
517  relativeYSign_ = c10Y > 0 ? -1 : 1;
518 
519  // information on modules and hits
520  overlapIds_[0] = overlapHit.first->recHit()->geographicalId().rawId();
521  overlapIds_[1] = overlapHit.second->recHit()->geographicalId().rawId();
522 
523  //added by Heshy and Jared
524  moduleX_[0] = overlapHit.first->recHit()->det()->surface().position().x();
525  moduleX_[1] = overlapHit.second->recHit()->det()->surface().position().x();
526  moduleY_[0] = overlapHit.first->recHit()->det()->surface().position().y();
527  moduleY_[1] = overlapHit.second->recHit()->det()->surface().position().y();
528  moduleZ_[0] = overlapHit.first->recHit()->det()->surface().position().z();
529  moduleZ_[1] = overlapHit.second->recHit()->det()->surface().position().z();
530  subdetID = overlapHit.first->recHit()->geographicalId().subdetId();
531  localxdotglobalphi_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(onezero).phi() -
532  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).phi();
533  localxdotglobalphi_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(onezero).phi() -
534  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).phi();
535  //added by Jason
536  localxdotglobalr_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(onezero).perp() -
537  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).perp();
538  localxdotglobalr_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(onezero).perp() -
539  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).perp();
540  localxdotglobalz_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(onezero).z() -
541  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).z();
542  localxdotglobalz_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(onezero).z() -
543  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).z();
544  localxdotglobalx_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(onezero).x() -
545  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).x();
546  localxdotglobalx_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(onezero).x() -
547  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).x();
548  localxdotglobaly_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(onezero).y() -
549  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).y();
550  localxdotglobaly_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(onezero).y() -
551  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).y();
552  localydotglobalr_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(zeroone).perp() -
553  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).perp();
554  localydotglobalr_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(zeroone).perp() -
555  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).perp();
556  localydotglobalz_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(zeroone).z() -
557  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).z();
558  localydotglobalz_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(zeroone).z() -
559  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).z();
560  localydotglobalx_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(zeroone).x() -
561  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).x();
562  localydotglobalx_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(zeroone).x() -
563  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).x();
564  localydotglobaly_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(zeroone).y() -
565  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).y();
566  localydotglobaly_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(zeroone).y() -
567  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).y();
568  localydotglobalphi_[0] = overlapHit.first->recHit()->det()->surface().toGlobal(zeroone).phi() -
569  overlapHit.first->recHit()->det()->surface().toGlobal(zerozero).phi();
570  localydotglobalphi_[1] = overlapHit.second->recHit()->det()->surface().toGlobal(zeroone).phi() -
571  overlapHit.second->recHit()->det()->surface().toGlobal(zerozero).phi();
572 
573  if (overlapHit.first->recHit()->geographicalId().subdetId() == StripSubdetector::TIB)
574  layer_ = layerFromId(overlapHit.first->recHit()->geographicalId().rawId(), tTopo);
575  else if (overlapHit.first->recHit()->geographicalId().subdetId() == StripSubdetector::TOB)
576  layer_ = layerFromId(overlapHit.first->recHit()->geographicalId().rawId(), tTopo) + 4;
577  else if (overlapHit.first->recHit()->geographicalId().subdetId() == StripSubdetector::TID)
578  layer_ = layerFromId(overlapHit.first->recHit()->geographicalId().rawId(), tTopo) + 10;
579  else if (overlapHit.first->recHit()->geographicalId().subdetId() == StripSubdetector::TEC)
580  layer_ = layerFromId(overlapHit.first->recHit()->geographicalId().rawId(), tTopo) + 13;
581  else if (overlapHit.first->recHit()->geographicalId().subdetId() == PixelSubdetector::PixelBarrel)
582  layer_ = layerFromId(overlapHit.first->recHit()->geographicalId().rawId(), tTopo) + 20;
583  else if (overlapHit.first->recHit()->geographicalId().subdetId() == PixelSubdetector::PixelEndcap)
584  layer_ = layerFromId(overlapHit.first->recHit()->geographicalId().rawId(), tTopo) + 30;
585  else
586  layer_ = 99;
587 
588  if (overlapIds_[0] == SiStripDetId(overlapHit.first->recHit()->geographicalId()).glued())
589  edm::LogWarning("Overlaps") << "BAD GLUED: First Id = " << overlapIds_[0] << " has glued = "
590  << SiStripDetId(overlapHit.first->recHit()->geographicalId()).glued()
591  << " and stereo = "
592  << SiStripDetId(overlapHit.first->recHit()->geographicalId()).stereo() << endl;
593  if (overlapIds_[1] == SiStripDetId(overlapHit.second->recHit()->geographicalId()).glued())
594  edm::LogWarning("Overlaps") << "BAD GLUED: Second Id = " << overlapIds_[1] << " has glued = "
595  << SiStripDetId(overlapHit.second->recHit()->geographicalId()).glued()
596  << " and stereo = "
597  << SiStripDetId(overlapHit.second->recHit()->geographicalId()).stereo() << endl;
598 
599  const TransientTrackingRecHit::ConstRecHitPointer firstRecHit = overlapHit.first->recHit();
600  const TransientTrackingRecHit::ConstRecHitPointer secondRecHit = overlapHit.second->recHit();
601  hitPositions_[0] = firstRecHit->localPosition().x();
602  hitErrors_[0] = sqrt(firstRecHit->localPositionError().xx());
603  hitPositions_[1] = secondRecHit->localPosition().x();
604  hitErrors_[1] = sqrt(secondRecHit->localPositionError().xx());
605 
606  hitPositionsY_[0] = firstRecHit->localPosition().y();
607  hitErrorsY_[0] = sqrt(firstRecHit->localPositionError().yy());
608  hitPositionsY_[1] = secondRecHit->localPosition().y();
609  hitErrorsY_[1] = sqrt(secondRecHit->localPositionError().yy());
610 
611  //cout << "printing local X hit position and error for the overlap hits. Hit 1 = " << hitPositions_[0] << "+-" << hitErrors_[0] << " and hit 2 is " << hitPositions_[1] << "+-" << hitErrors_[1] << endl;
612 
613  DetId id1 = overlapHit.first->recHit()->geographicalId();
614  DetId id2 = overlapHit.second->recHit()->geographicalId();
615  int layer1 = layerFromId(id1, tTopo);
616  int subDet1 = id1.subdetId();
617  int layer2 = layerFromId(id2, tTopo);
618  int subDet2 = id2.subdetId();
619  if (abs(hitPositions_[0]) > 5)
620  edm::LogInfo("Overlaps") << "BAD: Bad hit position: Id = " << id1.rawId()
621  << " stereo = " << SiStripDetId(id1).stereo()
622  << " glued = " << SiStripDetId(id1).glued() << " from subdet = " << subDet1
623  << " and layer = " << layer1 << endl;
624  if (abs(hitPositions_[1]) > 5)
625  edm::LogInfo("Overlaps") << "BAD: Bad hit position: Id = " << id2.rawId()
626  << " stereo = " << SiStripDetId(id2).stereo()
627  << " glued = " << SiStripDetId(id2).glued() << " from subdet = " << subDet2
628  << " and layer = " << layer2 << endl;
629 
630  // get track momentum
631  momentum_ = comb1.globalMomentum().mag();
632 
633  // get cluster size
634  if (!(subDet1 == PixelSubdetector::PixelBarrel || subDet1 == PixelSubdetector::PixelEndcap)) { //strip
635  const TransientTrackingRecHit::ConstRecHitPointer thit1 = overlapHit.first->recHit();
636  const SiStripRecHit1D* hit1 = dynamic_cast<const SiStripRecHit1D*>((*thit1).hit());
637  if (hit1) {
638  //check cluster width
639  const SiStripRecHit1D::ClusterRef& cluster1 = hit1->cluster();
640  clusterSize_[0] = (cluster1->amplitudes()).size();
641  clusterWidthX_[0] = (cluster1->amplitudes()).size();
642  clusterWidthY_[0] = -1;
643 
644  //check if cluster at edge of sensor
645  uint16_t firstStrip = cluster1->firstStrip();
646  uint16_t lastStrip = firstStrip + (cluster1->amplitudes()).size() - 1;
647  unsigned short Nstrips;
648  Nstrips = reader->getNumberOfApvsAndStripLength(id1).first * 128;
649  bool atEdge = false;
650  if (firstStrip == 0 || lastStrip == (Nstrips - 1))
651  atEdge = true;
652  if (atEdge)
653  edge_[0] = 1;
654  else
655  edge_[0] = -1;
656 
657  // get cluster total charge
658  const std::vector<uint8_t>& stripCharges = cluster1->amplitudes();
659  uint16_t charge = 0;
660  for (uint i = 0; i < stripCharges.size(); i++) {
661  charge += stripCharges.at(i);
662  }
663  clusterCharge_[0] = charge;
664  }
665 
666  const TransientTrackingRecHit::ConstRecHitPointer thit2 = overlapHit.second->recHit();
667  const SiStripRecHit1D* hit2 = dynamic_cast<const SiStripRecHit1D*>((*thit2).hit());
668  if (hit2) {
669  const SiStripRecHit1D::ClusterRef& cluster2 = hit2->cluster();
670  clusterSize_[1] = (cluster2->amplitudes()).size();
671  clusterWidthX_[1] = (cluster2->amplitudes()).size();
672  clusterWidthY_[1] = -1;
673 
674  uint16_t firstStrip = cluster2->firstStrip();
675  uint16_t lastStrip = firstStrip + (cluster2->amplitudes()).size() - 1;
676  unsigned short Nstrips;
677  Nstrips = reader->getNumberOfApvsAndStripLength(id2).first * 128;
678  bool atEdge = false;
679  if (firstStrip == 0 || lastStrip == (Nstrips - 1))
680  atEdge = true;
681  if (atEdge)
682  edge_[1] = 1;
683  else
684  edge_[1] = -1;
685 
686  // get cluster total charge
687  const std::vector<uint8_t>& stripCharges = cluster2->amplitudes();
688  uint16_t charge = 0;
689  for (uint i = 0; i < stripCharges.size(); i++) {
690  charge += stripCharges.at(i);
691  }
692  clusterCharge_[1] = charge;
693  }
694  //cout << "strip cluster size2 = " << clusterWidthX_[0] << " and size 2 = " << clusterWidthX_[1] << endl;
695  }
696 
697  if (subDet2 == PixelSubdetector::PixelBarrel || subDet2 == PixelSubdetector::PixelEndcap) { //pixel
698 
699  const TransientTrackingRecHit::ConstRecHitPointer thit1 = overlapHit.first->recHit();
700  const SiPixelRecHit* recHitPix1 = dynamic_cast<const SiPixelRecHit*>((*thit1).hit());
701  if (recHitPix1) {
702  // check for cluster size and width
703  SiPixelRecHit::ClusterRef const& cluster1 = recHitPix1->cluster();
704 
705  clusterSize_[0] = cluster1->size();
706  clusterWidthX_[0] = cluster1->sizeX();
707  clusterWidthY_[0] = cluster1->sizeY();
708 
709  // check for cluster at edge
710  const PixelGeomDetUnit* theGeomDet = dynamic_cast<const PixelGeomDetUnit*>((*trackerGeometry_).idToDet(id1));
711  const PixelTopology* topol = (&(theGeomDet->specificTopology()));
712 
713  int minPixelRow = cluster1->minPixelRow(); //x
714  int maxPixelRow = cluster1->maxPixelRow();
715  int minPixelCol = cluster1->minPixelCol(); //y
716  int maxPixelCol = cluster1->maxPixelCol();
717 
718  bool edgeHitX = (topol->isItEdgePixelInX(minPixelRow)) || (topol->isItEdgePixelInX(maxPixelRow));
719  bool edgeHitY = (topol->isItEdgePixelInY(minPixelCol)) || (topol->isItEdgePixelInY(maxPixelCol));
720  if (edgeHitX || edgeHitY)
721  edge_[0] = 1;
722  else
723  edge_[0] = -1;
724 
725  clusterCharge_[0] = (uint)cluster1->charge();
726 
727  } else {
728  edm::LogWarning("Overlaps") << "didn't find pixel cluster" << endl;
729  continue;
730  }
731 
732  const TransientTrackingRecHit::ConstRecHitPointer thit2 = overlapHit.second->recHit();
733  const SiPixelRecHit* recHitPix2 = dynamic_cast<const SiPixelRecHit*>((*thit2).hit());
734  if (recHitPix2) {
735  SiPixelRecHit::ClusterRef const& cluster2 = recHitPix2->cluster();
736 
737  clusterSize_[1] = cluster2->size();
738  clusterWidthX_[1] = cluster2->sizeX();
739  clusterWidthY_[1] = cluster2->sizeY();
740  //cout << "second pixel cluster is " << clusterSize_[1] << " pixels with x width = " << clusterWidthX_[1] << " and y width = " << clusterWidthY_[1] << endl;
741 
742  const PixelGeomDetUnit* theGeomDet = dynamic_cast<const PixelGeomDetUnit*>((*trackerGeometry_).idToDet(id2));
743  const PixelTopology* topol = (&(theGeomDet->specificTopology()));
744 
745  int minPixelRow = cluster2->minPixelRow(); //x
746  int maxPixelRow = cluster2->maxPixelRow();
747  int minPixelCol = cluster2->minPixelCol(); //y
748  int maxPixelCol = cluster2->maxPixelCol();
749 
750  bool edgeHitX = (topol->isItEdgePixelInX(minPixelRow)) || (topol->isItEdgePixelInX(maxPixelRow));
751  bool edgeHitY = (topol->isItEdgePixelInY(minPixelCol)) || (topol->isItEdgePixelInY(maxPixelCol));
752  if (edgeHitX || edgeHitY)
753  edge_[1] = 1;
754  else
755  edge_[1] = -1;
756 
757  clusterCharge_[1] = (uint)cluster2->charge();
758 
759  } else {
760  edm::LogWarning("Overlaps") << "didn't find pixel cluster" << endl;
761  continue;
762  }
763  }
764 
765  //also check for edge pixels
766 
767  //try writing out the SimHit info (for MC only)
768  if (doSimHit_) {
769  std::vector<PSimHit> psimHits1;
770  std::vector<PSimHit> psimHits2;
771  //calculate layer
772  DetId id = overlapHit.first->recHit()->geographicalId();
773  int layer(-1);
774  layer = layerFromId(id, tTopo);
775  int subDet = id.subdetId();
776  edm::LogVerbatim("OverlapValidation") << "Subdet = " << subDet << " ; layer = " << layer;
777 
778  psimHits1 = associator.associateHit(*(firstRecHit->hit()));
779  edm::LogVerbatim("OverlapValidation") << "single hit ";
780  edm::LogVerbatim("OverlapValidation") << "length of psimHits1: " << psimHits1.size();
781  if (!psimHits1.empty()) {
782  float closest_dist = 99999.9;
783  std::vector<PSimHit>::const_iterator closest_simhit = psimHits1.begin();
784  for (std::vector<PSimHit>::const_iterator m = psimHits1.begin(); m < psimHits1.end(); m++) {
785  //find closest simHit to the recHit
786  float simX = (*m).localPosition().x();
787  float dist = fabs(simX - (overlapHit.first->recHit()->localPosition().x()));
788  edm::LogVerbatim("OverlapValidation")
789  << "simHit1 simX = " << simX << " hitX = " << overlapHit.first->recHit()->localPosition().x()
790  << " distX = " << dist << " layer = " << layer;
791  if (dist < closest_dist) {
792  //cout << "found newest closest dist for simhit1" << endl;
793  closest_dist = dist;
794  closest_simhit = m;
795  }
796  }
797  //if glued layer, convert sim hit position to matchedhit surface
798  //layer index from 1-4 for TIB, 1-6 for TOB
799  // Are the sim hits on the glued layers or are they split???
800  if (subDet > 2 && !SiStripDetId(id).glued()) {
801  const GluedGeomDet* gluedDet =
802  (const GluedGeomDet*)(*trackerGeometry_).idToDet((*firstRecHit).hit()->geographicalId());
803  const StripGeomDetUnit* stripDet = (StripGeomDetUnit*)gluedDet->monoDet();
804  GlobalPoint gp = stripDet->surface().toGlobal((*closest_simhit).localPosition());
805  LocalPoint lp = gluedDet->surface().toLocal(gp);
806  LocalVector localdirection = (*closest_simhit).localDirection();
807  GlobalVector globaldirection = stripDet->surface().toGlobal(localdirection);
808  LocalVector direction = gluedDet->surface().toLocal(globaldirection);
809  float scale = -lp.z() / direction.z();
810  LocalPoint projectedPos = lp + scale * direction;
811  simHitPositions_[0] = projectedPos.x();
812  edm::LogVerbatim("OverlapValidation") << "simhit position from matched layer = " << simHitPositions_[0];
813  simHitPositionsY_[0] = projectedPos.y();
814  } else {
815  simHitPositions_[0] = (*closest_simhit).localPosition().x();
816  simHitPositionsY_[0] = (*closest_simhit).localPosition().y();
817  edm::LogVerbatim("OverlapValidation") << "simhit position from non-matched layer = " << simHitPositions_[0];
818  }
819  edm::LogVerbatim("OverlapValidation") << "hit position = " << hitPositions_[0];
820  } else {
821  simHitPositions_[0] = -99.;
822  simHitPositionsY_[0] = -99.;
823  //cout << " filling simHitX: " << -99 << endl;
824  }
825 
826  psimHits2 = associator.associateHit(*(secondRecHit->hit()));
827  if (!psimHits2.empty()) {
828  float closest_dist = 99999.9;
829  std::vector<PSimHit>::const_iterator closest_simhit = psimHits2.begin();
830  for (std::vector<PSimHit>::const_iterator m = psimHits2.begin(); m < psimHits2.end(); m++) {
831  float simX = (*m).localPosition().x();
832  float dist = fabs(simX - (overlapHit.second->recHit()->localPosition().x()));
833  if (dist < closest_dist) {
834  closest_dist = dist;
835  closest_simhit = m;
836  }
837  }
838  //if glued layer, convert sim hit position to matchedhit surface
839  // if no sim hits on matched layers then this section can be removed
840  if (subDet > 2 && !SiStripDetId(id).glued()) {
841  const GluedGeomDet* gluedDet =
842  (const GluedGeomDet*)(*trackerGeometry_).idToDet((*secondRecHit).hit()->geographicalId());
843  const StripGeomDetUnit* stripDet = (StripGeomDetUnit*)gluedDet->monoDet();
844  GlobalPoint gp = stripDet->surface().toGlobal((*closest_simhit).localPosition());
845  LocalPoint lp = gluedDet->surface().toLocal(gp);
846  LocalVector localdirection = (*closest_simhit).localDirection();
847  GlobalVector globaldirection = stripDet->surface().toGlobal(localdirection);
848  LocalVector direction = gluedDet->surface().toLocal(globaldirection);
849  float scale = -lp.z() / direction.z();
850  LocalPoint projectedPos = lp + scale * direction;
851  simHitPositions_[1] = projectedPos.x();
852  simHitPositionsY_[1] = projectedPos.y();
853  } else {
854  simHitPositions_[1] = (*closest_simhit).localPosition().x();
855  simHitPositionsY_[1] = (*closest_simhit).localPosition().y();
856  }
857  } else {
858  simHitPositions_[1] = -99.;
859  simHitPositionsY_[1] = -99.;
860  }
861  }
862  rootTree_->Fill();
863  }
864 }
865 
866 int OverlapValidation::layerFromId(const DetId& id, const TrackerTopology* const tTopo) const {
867  TrackerAlignableId aliid;
868  std::pair<int, int> subdetandlayer = aliid.typeAndLayerFromDetId(id, tTopo);
869  int layer = subdetandlayer.second;
870 
871  return layer;
872 }
873 
875  if (rootTree_) {
876  rootTree_->GetDirectory()->cd();
877  rootTree_->Write();
878  delete rootTree_;
879  }
880 }
881 
882 //define this as a plug-in
RunNumber_t run() const
Definition: EventID.h:38
ClusterRef cluster() const
edm::InputTag trajectoryTag_
size
Write out results.
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:81
const Point2DBase< float, LocalTag > zerozero
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:40
static constexpr auto TEC
int foundHits() const
Definition: Trajectory.h:206
int lostHits() const
Definition: Trajectory.h:217
TrajectoryStateCombiner combiner_
edm::EDGetTokenT< TrajectoryCollection > trajectoryToken_
unsigned int overlapIds_[2]
~OverlapValidation() override
std::pair< int, int > typeAndLayerFromDetId(const DetId &detId, const TrackerTopology *tTopo) const
void endJob() override
vector< bool > acceptLayer
const double w
Definition: UKUtility.cc:23
const GeomDetUnit * monoDet() const
Definition: GluedGeomDet.h:19
uint32_t stereo() const
Definition: SiStripDetId.h:168
const LocalTrajectoryParameters & localParameters() const
const bool addExtraBranches_
const std::pair< unsigned short, double > getNumberOfApvsAndStripLength(uint32_t detId) const
TSOS combine(const TSOS &pTsos1, const TSOS &pTsos2) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
float predictedPositions_[3][2]
virtual bool isItEdgePixelInX(int ixbin) const =0
const Point2DBase< float, LocalTag > onezero
#define nullptr
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
T y() const
Definition: PV3DBase.h:60
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepStd< double, 5, 5 > > AlgebraicMatrix55
GlobalPoint globalPosition() const
virtual bool isItEdgePixelInY(int iybin) const =0
const Point2DBase< float, LocalTag > zeroone
unsigned short hitCounts_[2]
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
example_stream void analyze(const edm::Event &, const edm::EventSetup &) override
void analyze(const edm::Event &, const edm::EventSetup &) override
const MagneticField * magField_
DataContainer const & measurements() const
Definition: Trajectory.h:178
AlgebraicVector5 vector() const
int iEvent
Definition: GenABIO.cc:224
const SurfaceType & surface() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
T mag() const
Definition: PV3DBase.h:64
int layerFromId(const DetId &, const TrackerTopology *const tTopo) const
std::shared_ptr< TrackingRecHit const > ConstRecHitPointer
vector< Trajectory > TrajectoryCollection
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
T sqrt(T t)
Definition: SSEVec.h:19
LocalPoint toLocal(const GlobalPoint &gp) const
T z() const
Definition: PV3DBase.h:61
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Surface &) const final
Definition: Propagator.cc:10
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ROOT::Math::SVector< double, 5 > AlgebraicVector5
float ChiSquaredProbability(double chiSquared, double nrDOF)
const AlgebraicSymMatrix55 & matrix() const
const TrackerGeometry * trackerGeometry_
float predictedLocalErrors_[5][2]
const LocalTrajectoryError & localError() const
static constexpr auto TOB
Detector identifier class for the strip tracker.
Definition: SiStripDetId.h:18
OverlapValidation(const edm::ParameterSet &)
TransientTrackingRecHit::ConstRecHitPointer ConstRecHitPointer
Definition: DetId.h:17
uint32_t glued() const
Definition: SiStripDetId.h:163
int ndof(bool bon=true) const
Definition: Trajectory.cc:97
float predictedLocalParameters_[5][2]
static const char clusterCharge_[]
static constexpr auto TIB
T const * product() const
Definition: Handle.h:69
const GlobalTrajectoryParameters & globalParameters() const
edm::FileInPath FileInPath_
ClusterRef cluster() const
Definition: SiPixelRecHit.h:47
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:50
SiStripDetInfoFileReader * reader
float chiSquared() const
Definition: Trajectory.h:241
edm::ParameterSet config_
edm::EventID id() const
Definition: EventBase.h:59
HLT enums.
GlobalVector globalMomentum() const
static int position[264][3]
Definition: ReadPGInfo.cc:289
T get() const
Definition: EventSetup.h:73
void event_()
const AlgebraicMatrix55 & jacobian() const
std::string fullPath() const
Definition: FileInPath.cc:163
std::vector< PSimHit > associateHit(const TrackingRecHit &thit) const
T x() const
Definition: PV3DBase.h:59
static constexpr auto TID
T const * product() const
Definition: ESHandle.h:86
Our base class.
Definition: SiPixelRecHit.h:23