CMS 3D CMS Logo

MuonPathAnalyzerInChamber.cc
Go to the documentation of this file.
2 #include <cmath>
3 #include <memory>
4 
5 using namespace edm;
6 using namespace std;
7 using namespace cmsdt;
8 // ============================================================================
9 // Constructors and destructor
10 // ============================================================================
13  std::shared_ptr<GlobalCoordsObtainer> &globalcoordsobtainer)
14  : MuonPathAnalyzer(pset, iC),
15  debug_(pset.getUntrackedParameter<bool>("debug")),
16  chi2Th_(pset.getParameter<double>("chi2Th")),
17  shift_filename_(pset.getParameter<edm::FileInPath>("shift_filename")),
18  bxTolerance_(30),
19  minQuality_(LOWQ),
20  chiSquareThreshold_(50),
21  minHits4Fit_(pset.getParameter<int>("minHits4Fit")),
22  splitPathPerSL_(pset.getParameter<bool>("splitPathPerSL")) {
23  // Obtention of parameters
24 
25  if (debug_)
26  LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzer: constructor";
27 
29 
30  //shift
31  int rawId;
32  std::ifstream ifin3(shift_filename_.fullPath());
33  double shift;
34  if (ifin3.fail()) {
35  throw cms::Exception("Missing Input File")
36  << "MuonPathAnalyzerInChamber::MuonPathAnalyzerInChamber() - Cannot find " << shift_filename_.fullPath();
37  }
38  while (ifin3.good()) {
39  ifin3 >> rawId >> shift;
40  shiftinfo_[rawId] = shift;
41  }
42 
44  globalcoordsobtainer_ = globalcoordsobtainer;
45 }
46 
48  if (debug_)
49  LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzer: destructor";
50 }
51 
52 // ============================================================================
53 // Main methods (initialise, run, finish)
54 // ============================================================================
56  if (debug_)
57  LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzerInChamber::initialiase";
58 
59  auto geom = iEventSetup.getHandle(dtGeomH);
60  dtGeo_ = geom.product();
61 }
62 
64  const edm::EventSetup &iEventSetup,
65  MuonPathPtrs &muonpaths,
66  MuonPathPtrs &outmuonpaths) {
67  if (debug_)
68  LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzerInChamber: run";
69 
70  // fit per SL (need to allow for multiple outputs for a single mpath)
71  int nMuonPath_counter = 0;
72  for (auto muonpath = muonpaths.begin(); muonpath != muonpaths.end(); ++muonpath) {
73  if (debug_) {
74  LogDebug("MuonPathAnalyzerInChamber")
75  << "Full path: " << nMuonPath_counter << " , " << muonpath->get()->nprimitives() << " , "
76  << muonpath->get()->nprimitivesUp() << " , " << muonpath->get()->nprimitivesDown();
77  }
78  ++nMuonPath_counter;
79 
80  // Define muonpaths for up/down SL only
81  MuonPathPtr muonpathUp_ptr = std::make_shared<MuonPath>();
82  muonpathUp_ptr->setNPrimitives(8);
83  muonpathUp_ptr->setNPrimitivesUp(muonpath->get()->nprimitivesUp());
84  muonpathUp_ptr->setNPrimitivesDown(0);
85 
86  MuonPathPtr muonpathDown_ptr = std::make_shared<MuonPath>();
87  muonpathDown_ptr->setNPrimitives(8);
88  muonpathDown_ptr->setNPrimitivesUp(0);
89  muonpathDown_ptr->setNPrimitivesDown(muonpath->get()->nprimitivesDown());
90 
91  for (int n = 0; n < muonpath->get()->nprimitives(); ++n) {
92  DTPrimitivePtr prim = muonpath->get()->primitive(n);
93  // UP
94  if (prim->superLayerId() == 3) {
95  muonpathUp_ptr->setPrimitive(prim, n);
96  }
97  // DOWN
98  else if (prim->superLayerId() == 1) {
99  muonpathDown_ptr->setPrimitive(prim, n);
100  }
101  // NOT UP NOR DOWN
102  else
103  continue;
104  }
105 
106  analyze(*muonpath, outmuonpaths);
107 
108  if (splitPathPerSL_) {
109  if (muonpathUp_ptr->nprimitivesUp() > 1 && muonpath->get()->nprimitivesDown() > 0)
110  analyze(muonpathUp_ptr, outmuonpaths);
111 
112  if (muonpathDown_ptr->nprimitivesDown() > 1 && muonpath->get()->nprimitivesUp() > 0)
113  analyze(muonpathDown_ptr, outmuonpaths);
114  }
115  }
116 }
117 
119  if (debug_)
120  LogDebug("MuonPathAnalyzerInChamber") << "MuonPathAnalyzer: finish";
121 };
122 
123 //------------------------------------------------------------------
124 //--- Private method
125 //------------------------------------------------------------------
127  if (debug_)
128  LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t starts";
129 
130  // Clone the analyzed object
131  if (debug_)
132  LogDebug("MuonPathAnalyzerInChamber") << inMPath->nprimitives();
133  auto mPath = std::make_shared<MuonPath>(inMPath);
134 
135  if (debug_) {
136  LogDebug("MuonPathAnalyzerInChamber") << "DTp2::analyze, looking at mPath: ";
137  for (int i = 0; i < mPath->nprimitives(); i++)
138  LogDebug("MuonPathAnalyzerInChamber")
139  << mPath->primitive(i)->layerId() << " , " << mPath->primitive(i)->superLayerId() << " , "
140  << mPath->primitive(i)->channelId() << " , " << mPath->primitive(i)->laterality();
141  }
142 
143  if (debug_)
144  LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t\t is Analyzable? ";
145  if (!mPath->isAnalyzable())
146  return;
147  if (debug_)
148  LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t\t yes it is analyzable " << mPath->isAnalyzable();
149 
150  // first of all, get info from primitives, so we can reduce the number of latereralities:
151  buildLateralities(mPath);
152  setWirePosAndTimeInMP(mPath);
153 
154  std::shared_ptr<MuonPath> mpAux;
155  int bestI = -1;
156  float best_chi2 = 99999.;
157  int added_lat = 0;
158 
159  // LOOP for all lateralities:
160  for (int i = 0; i < (int)lateralities_.size(); i++) {
161  if (debug_)
162  LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analyze \t\t\t\t\t Start with combination " << i;
163 
164  int NTotalHits = NUM_LAYERS_2SL;
165  float xwire[NUM_LAYERS_2SL];
166  int present_layer[NUM_LAYERS_2SL];
167  for (int ii = 0; ii < 8; ii++) {
168  xwire[ii] = mPath->xWirePos(ii);
169  if (xwire[ii] == 0) {
170  present_layer[ii] = 0;
171  NTotalHits--;
172  } else {
173  present_layer[ii] = 1;
174  }
175  }
176 
177  while (NTotalHits >= minHits4Fit_) {
178  mPath->setChiSquare(0);
179  calculateFitParameters(mPath, lateralities_[i], present_layer, added_lat);
180  if (mPath->chiSquare() != 0)
181  break;
182  NTotalHits--;
183  }
184 
185  if (mPath->chiSquare() > chiSquareThreshold_)
186  continue;
187 
188  evaluateQuality(mPath);
189 
190  if (mPath->quality() < minQuality_)
191  continue;
192 
193  double z = 0;
194  double jm_x = (mPath->horizPos());
195  int selected_Id = 0;
196  for (int i = 0; i < mPath->nprimitives(); i++) {
197  if (mPath->primitive(i)->isValidTime()) {
198  selected_Id = mPath->primitive(i)->cameraId();
199  mPath->setRawId(selected_Id);
200  break;
201  }
202  }
203  DTLayerId thisLId(selected_Id);
204  DTChamberId ChId(thisLId.wheel(), thisLId.station(), thisLId.sector());
205 
206  if (thisLId.station() >= 3)
207  z += Z_SHIFT_MB4;
208 
209  DTSuperLayerId MuonPathSLId(thisLId.wheel(), thisLId.station(), thisLId.sector(), thisLId.superLayer());
210 
211  // Count hits in each SL
212  int hits_in_SL1 = 0;
213  int hits_in_SL3 = 0;
214  for (int i = 0; i < mPath->nprimitives(); i++) {
215  if (mPath->primitive(i)->isValidTime()) {
216  if (i <= 3)
217  ++hits_in_SL1;
218  else if (i > 3)
219  ++hits_in_SL3;
220  }
221  }
222 
223  int SL_for_LUT = 0;
224  // Depending on which SL has hits, propagate jm_x to SL1, SL3, or to the center of the chamber
225  GlobalPoint jm_x_cmssw_global;
226  if (hits_in_SL1 > 2 && hits_in_SL3 <= 2) {
227  // Uncorrelated or confirmed with 3 or 4 hits in SL1: propagate to SL1
228  jm_x += mPath->tanPhi() * (11.1 + 0.65);
229  jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal(LocalPoint(jm_x, 0., z + 11.75));
230  SL_for_LUT = 1;
231  } else if (hits_in_SL1 <= 2 && hits_in_SL3 > 2) {
232  // Uncorrelated or confirmed with 3 or 4 hits in SL3: propagate to SL3
233  jm_x -= mPath->tanPhi() * (11.1 + 0.65);
234  jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal(LocalPoint(jm_x, 0., z - 11.75));
235  SL_for_LUT = 3;
236  } else if (hits_in_SL1 > 2 && hits_in_SL3 > 2) {
237  // Correlated: stay at chamber center
238  jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal(LocalPoint(jm_x, 0., z));
239  } else {
240  // Not interesting
241  continue;
242  }
243 
244  // Protection against non-converged fits
245  if (isnan(jm_x))
246  continue;
247 
248  // Updating muon-path horizontal position
249  mPath->setHorizPos(jm_x);
250 
251  // Adjusting sector names for MB4
252  int thisec = MuonPathSLId.sector();
253  if (thisec == 13)
254  thisec = 4;
255  if (thisec == 14)
256  thisec = 10;
257 
258  // Global coordinates from CMSSW
259  double phi_cmssw = jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1);
260  double psi = atan(mPath->tanPhi());
261  mPath->setPhiCMSSW(phi_cmssw);
262  mPath->setPhiBCMSSW(hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? psi - phi_cmssw : -psi - phi_cmssw);
263 
264  // Global coordinates from LUTs (firmware-like)
265  double phi = -999.;
266  double phiB = -999.;
267  double x_lut, slope_lut;
268  DTSuperLayerId MuonPathSLId1(thisLId.wheel(), thisLId.station(), thisLId.sector(), 1);
269  DTSuperLayerId MuonPathSLId3(thisLId.wheel(), thisLId.station(), thisLId.sector(), 3);
270  DTWireId wireId1(MuonPathSLId1, 2, 1);
271  DTWireId wireId3(MuonPathSLId3, 2, 1);
272 
273  // use SL_for_LUT to decide the shift: x-axis origin for LUTs is left chamber side
274  double shift_for_lut = 0.;
275  if (SL_for_LUT == 1) {
276  shift_for_lut = int(10 * shiftinfo_[wireId1.rawId()] * INCREASED_RES_POS_POW);
277  } else if (SL_for_LUT == 3) {
278  shift_for_lut = int(10 * shiftinfo_[wireId3.rawId()] * INCREASED_RES_POS_POW);
279  } else {
280  int shift_sl1 = int(round(shiftinfo_[wireId1.rawId()] * INCREASED_RES_POS_POW * 10));
281  int shift_sl3 = int(round(shiftinfo_[wireId3.rawId()] * INCREASED_RES_POS_POW * 10));
282  if (shift_sl1 < shift_sl3) {
283  shift_for_lut = shift_sl1;
284  } else
285  shift_for_lut = shift_sl3;
286  }
287  x_lut = double(jm_x) * 10. * INCREASED_RES_POS_POW - shift_for_lut; // position in cm * precision in JM RF
288  slope_lut = -(double(mPath->tanPhi()) * INCREASED_RES_SLOPE_POW);
289 
290  auto global_coords = globalcoordsobtainer_->get_global_coordinates(ChId.rawId(), SL_for_LUT, x_lut, slope_lut);
291  phi = global_coords[0];
292  phiB = global_coords[1];
293  mPath->setPhi(phi);
294  mPath->setPhiB(phiB);
295 
296  if (mPath->chiSquare() < best_chi2 && mPath->chiSquare() > 0) {
297  mpAux = std::make_shared<MuonPath>(mPath);
298  bestI = i;
299  best_chi2 = mPath->chiSquare();
300  }
301  }
302  if (mpAux != nullptr) {
303  outMPath.push_back(std::move(mpAux));
304  if (debug_)
305  LogDebug("MuonPathAnalyzerInChamber")
306  << "DTp2:analize \t\t\t\t\t Laterality " << bestI << " is the one with smaller chi2";
307  } else {
308  if (debug_)
309  LogDebug("MuonPathAnalyzerInChamber")
310  << "DTp2:analize \t\t\t\t\t No Laterality found with chi2 smaller than threshold";
311  }
312  if (debug_)
313  LogDebug("MuonPathAnalyzerInChamber") << "DTp2:analize \t\t\t\t\t Ended working with this set of lateralities";
314 }
315 
317  for (int i = 0; i <= mpath->nprimitives(); i++) {
318  if (mpath->primitive(i)->isValidTime())
319  cellLayout_[i] = mpath->primitive(i)->channelId();
320  else
321  cellLayout_[i] = -99;
322  }
323 
324  // putting info back into the mpath:
325  mpath->setCellHorizontalLayout(cellLayout_);
326  for (int i = 0; i <= mpath->nprimitives(); i++) {
327  if (cellLayout_[i] >= 0) {
328  mpath->setBaseChannelId(cellLayout_[i]);
329  break;
330  }
331  }
332 }
333 
338  if (debug_)
339  LogDebug("MuonPathAnalyzerInChamber") << "MPAnalyzer::buildLateralities << setLateralitiesFromPrims ";
340  mpath->setLateralCombFromPrimitives();
341 
343  lateralities_.clear();
344  latQuality_.clear();
345 
346  /* We generate all the possible laterality combinations compatible with the built
347  group in the previous step*/
348  lateralities_.push_back(TLateralities());
349  for (int ilat = 0; ilat < cmsdt::NUM_LAYERS_2SL; ilat++) {
350  // Get value from input
351  LATERAL_CASES lr = (mpath->lateralComb())[ilat];
352  if (debug_)
353  LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] Input[" << ilat << "]: " << lr;
354 
355  // If left/right fill number
356  if (lr != NONE) {
357  if (debug_)
358  LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] - Adding it to " << lateralities_.size() << " lists...";
359  for (unsigned int iall = 0; iall < lateralities_.size(); iall++) {
360  lateralities_[iall][ilat] = lr;
361  }
362  }
363  // both possibilites
364  else {
365  // Get the number of possible options now
366  auto ncurrentoptions = lateralities_.size();
367 
368  // Duplicate them
369  if (debug_)
370  LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] - Duplicating " << ncurrentoptions << " lists...";
371  copy(lateralities_.begin(), lateralities_.end(), back_inserter(lateralities_));
372  if (debug_)
373  LogDebug("MuonPathAnalyzerInChamber") << "[DEBUG_] - Now we have " << lateralities_.size() << " lists...";
374 
375  // Asign LEFT to first ncurrentoptions and RIGHT to the last
376  for (unsigned int iall = 0; iall < ncurrentoptions; iall++) {
377  lateralities_[iall][ilat] = LEFT;
378  lateralities_[iall + ncurrentoptions][ilat] = RIGHT;
379  }
380  } // else
381  } // Iterate over input array
382 
384  if (totalNumValLateralities_ > 128) {
385  // ADD PROTECTION!
386  LogDebug("MuonPathAnalyzerInChamber") << "[WARNING]: TOO MANY LATERALITIES TO CHECK !!";
387  LogDebug("MuonPathAnalyzerInChamber") << "[WARNING]: skipping this muon";
388  lateralities_.clear();
389  latQuality_.clear();
391  }
392 
393  // Dump values
394  if (debug_) {
395  for (unsigned int iall = 0; iall < lateralities_.size(); iall++) {
396  LogDebug("MuonPathAnalyzerInChamber") << iall << " -> [";
397  for (int ilat = 0; ilat < cmsdt::NUM_LAYERS_2SL; ilat++) {
398  if (ilat != 0)
399  LogDebug("MuonPathAnalyzerInChamber") << ",";
400  LogDebug("MuonPathAnalyzerInChamber") << lateralities_[iall][ilat];
401  }
402  LogDebug("MuonPathAnalyzerInChamber") << "]";
403  }
404  }
405 }
406 
408  for (int i = 0; i < 8; i++)
409  mpath->primitive(i)->setLaterality(lat[i]);
410 }
411 
413  int selected_Id = 0;
414  for (int i = 0; i < mpath->nprimitives(); i++) {
415  if (mpath->primitive(i)->isValidTime()) {
416  selected_Id = mpath->primitive(i)->cameraId();
417  mpath->setRawId(selected_Id);
418  break;
419  }
420  }
421  DTLayerId thisLId(selected_Id);
422  DTChamberId chId(thisLId.wheel(), thisLId.station(), thisLId.sector());
423  if (debug_)
424  LogDebug("MuonPathAnalyzerInChamber")
425  << "Id " << chId.rawId() << " Wh " << chId.wheel() << " St " << chId.station() << " Se " << chId.sector();
426  mpath->setRawId(chId.rawId());
427 
428  DTSuperLayerId MuonPathSLId1(thisLId.wheel(), thisLId.station(), thisLId.sector(), 1);
429  DTSuperLayerId MuonPathSLId3(thisLId.wheel(), thisLId.station(), thisLId.sector(), 3);
430  DTWireId wireId1(MuonPathSLId1, 2, 1);
431  DTWireId wireId3(MuonPathSLId3, 2, 1);
432 
433  if (debug_)
434  LogDebug("MuonPathAnalyzerInChamber")
435  << "shift1=" << shiftinfo_[wireId1.rawId()] << " shift3=" << shiftinfo_[wireId3.rawId()];
436 
437  float delta = 42000; //um
438  float zwire[NUM_LAYERS_2SL] = {-13.7, -12.4, -11.1, -9.8002, 9.79999, 11.1, 12.4, 13.7}; // mm
439  for (int i = 0; i < mpath->nprimitives(); i++) {
440  if (mpath->primitive(i)->isValidTime()) {
441  if (i < 4)
442  mpath->setXWirePos(10000 * shiftinfo_[wireId1.rawId()] +
443  (mpath->primitive(i)->channelId() + 0.5 * (double)((i + 1) % 2)) * delta,
444  i);
445  if (i >= 4)
446  mpath->setXWirePos(10000 * shiftinfo_[wireId3.rawId()] +
447  (mpath->primitive(i)->channelId() + 0.5 * (double)((i + 1) % 2)) * delta,
448  i);
449  mpath->setZWirePos(zwire[i] * 1000, i); // in um
450  mpath->setTWireTDC(mpath->primitive(i)->tdcTimeStamp() * DRIFT_SPEED, i);
451  } else {
452  mpath->setXWirePos(0., i);
453  mpath->setZWirePos(0., i);
454  mpath->setTWireTDC(-1 * DRIFT_SPEED, i);
455  }
456  if (debug_)
457  LogDebug("MuonPathAnalyzerInChamber") << mpath->primitive(i)->tdcTimeStamp() << " ";
458  }
459  if (debug_)
460  LogDebug("MuonPathAnalyzerInChamber");
461 }
462 
464  TLateralities laterality,
465  int present_layer[NUM_LAYERS_2SL],
466  int &lat_added) {
467  // Get number of hits in current muonPath
468  int n_hits = 0;
469  for (int l = 0; l < 8; ++l) {
470  if (present_layer[l] == 1)
471  n_hits++;
472  }
473 
474  // First prepare mpath for fit:
475  float xwire[NUM_LAYERS_2SL], zwire[NUM_LAYERS_2SL], tTDCvdrift[NUM_LAYERS_2SL];
476  double b[NUM_LAYERS_2SL];
477  for (int i = 0; i < 8; i++) {
478  xwire[i] = mpath->xWirePos(i);
479  zwire[i] = mpath->zWirePos(i);
480  tTDCvdrift[i] = mpath->tWireTDC(i);
481  b[i] = 1;
482  }
483 
485 
486  // fill hit position
487  float xhit[NUM_LAYERS_2SL];
488  for (int lay = 0; lay < 8; lay++) {
489  if (debug_)
490  LogDebug("MuonPathAnalyzerInChamber") << "In fitPerLat " << lay << " xwire " << xwire[lay] << " zwire "
491  << zwire[lay] << " tTDCvdrift " << tTDCvdrift[lay];
492  xhit[lay] = xwire[lay] + (-1 + 2 * laterality[lay]) * 1000 * tTDCvdrift[lay];
493  if (debug_)
494  LogDebug("MuonPathAnalyzerInChamber") << "In fitPerLat " << lay << " xhit " << xhit[lay];
495  }
496 
497  //Proceed with calculation of fit parameters
498  double cbscal = 0.0;
499  double zbscal = 0.0;
500  double czscal = 0.0;
501  double bbscal = 0.0;
502  double zzscal = 0.0;
503  double ccscal = 0.0;
504 
505  for (int lay = 0; lay < 8; lay++) {
506  if (present_layer[lay] == 0)
507  continue;
508  if (debug_)
509  LogDebug("MuonPathAnalyzerInChamber")
510  << " For layer " << lay + 1 << " xwire[lay] " << xwire[lay] << " zwire " << zwire[lay] << " b " << b[lay];
511  if (debug_)
512  LogDebug("MuonPathAnalyzerInChamber") << " xhit[lat][lay] " << xhit[lay];
513  cbscal = (-1 + 2 * laterality[lay]) * b[lay] + cbscal;
514  zbscal = zwire[lay] * b[lay] + zbscal; //it actually does not depend on laterality
515  czscal = (-1 + 2 * laterality[lay]) * zwire[lay] + czscal;
516 
517  bbscal = b[lay] * b[lay] + bbscal; //it actually does not depend on laterality
518  zzscal = zwire[lay] * zwire[lay] + zzscal; //it actually does not depend on laterality
519  ccscal = (-1 + 2 * laterality[lay]) * (-1 + 2 * laterality[lay]) + ccscal;
520  }
521 
522  double cz = 0.0;
523  double cb = 0.0;
524  double zb = 0.0;
525  double zc = 0.0;
526  double bc = 0.0;
527  double bz = 0.0;
528 
529  cz = (cbscal * zbscal - czscal * bbscal) / (zzscal * bbscal - zbscal * zbscal);
530  cb = (czscal * zbscal - cbscal * zzscal) / (zzscal * bbscal - zbscal * zbscal);
531 
532  zb = (czscal * cbscal - zbscal * ccscal) / (bbscal * ccscal - cbscal * cbscal);
533  zc = (zbscal * cbscal - czscal * bbscal) / (bbscal * ccscal - cbscal * cbscal);
534 
535  bc = (zbscal * czscal - cbscal * zzscal) / (ccscal * zzscal - czscal * czscal);
536  bz = (cbscal * czscal - zbscal * ccscal) / (ccscal * zzscal - czscal * czscal);
537 
538  double c_tilde[NUM_LAYERS_2SL];
539  double z_tilde[NUM_LAYERS_2SL];
540  double b_tilde[NUM_LAYERS_2SL];
541 
542  for (int lay = 0; lay < 8; lay++) {
543  if (present_layer[lay] == 0)
544  continue;
545  if (debug_)
546  LogDebug("MuonPathAnalyzerInChamber")
547  << " For layer " << lay + 1 << " xwire[lay] " << xwire[lay] << " zwire " << zwire[lay] << " b " << b[lay];
548  c_tilde[lay] = (-1 + 2 * laterality[lay]) + cz * zwire[lay] + cb * b[lay];
549  z_tilde[lay] = zwire[lay] + zb * b[lay] + zc * (-1 + 2 * laterality[lay]);
550  b_tilde[lay] = b[lay] + bc * (-1 + 2 * laterality[lay]) + bz * zwire[lay];
551  }
552 
553  //Calculate results per lat
554  double xctilde = 0.0;
555  double xztilde = 0.0;
556  double xbtilde = 0.0;
557  double ctildectilde = 0.0;
558  double ztildeztilde = 0.0;
559  double btildebtilde = 0.0;
560 
561  double rect0vdrift = 0.0;
562  double recslope = 0.0;
563  double recpos = 0.0;
564 
565  for (int lay = 0; lay < 8; lay++) {
566  if (present_layer[lay] == 0)
567  continue;
568  xctilde = xhit[lay] * c_tilde[lay] + xctilde;
569  ctildectilde = c_tilde[lay] * c_tilde[lay] + ctildectilde;
570  xztilde = xhit[lay] * z_tilde[lay] + xztilde;
571  ztildeztilde = z_tilde[lay] * z_tilde[lay] + ztildeztilde;
572  xbtilde = xhit[lay] * b_tilde[lay] + xbtilde;
573  btildebtilde = b_tilde[lay] * b_tilde[lay] + btildebtilde;
574  }
575 
576  // Results for t0vdrift (BX), slope and position per lat
577  rect0vdrift = xctilde / ctildectilde;
578  recslope = xztilde / ztildeztilde;
579  recpos = xbtilde / btildebtilde;
580  if (debug_) {
581  LogDebug("MuonPathAnalyzerInChamber") << " In fitPerLat Reconstructed values per lat "
582  << " rect0vdrift " << rect0vdrift;
583  LogDebug("MuonPathAnalyzerInChamber")
584  << "rect0 " << rect0vdrift / DRIFT_SPEED << " recBX " << rect0vdrift / DRIFT_SPEED / 25 << " recslope "
585  << recslope << " recpos " << recpos;
586  }
587 
588  //Get t*v and residuals per layer, and chi2 per laterality
589  double rectdriftvdrift[NUM_LAYERS_2SL];
590  double recres[NUM_LAYERS_2SL];
591  double recchi2 = 0.0;
592  int sign_tdriftvdrift = {0};
593  int incell_tdriftvdrift = {0};
594  int physical_slope = {0};
595 
596  // Select the worst hit in order to get rid of it
597  // Also, check if any hits are close to the wire (rectdriftvdrift[lay] < 0.3 cm)
598  // --> in that case, try also changing laterality of such hit
599  double maxDif = -1;
600  int maxInt = -1;
601  int swap_laterality[8] = {0};
602 
603  for (int lay = 0; lay < 8; lay++) {
604  if (present_layer[lay] == 0)
605  continue;
606  rectdriftvdrift[lay] = tTDCvdrift[lay] - rect0vdrift / 1000;
607  if (debug_)
608  LogDebug("MuonPathAnalyzerInChamber") << rectdriftvdrift[lay];
609  recres[lay] = xhit[lay] - zwire[lay] * recslope - b[lay] * recpos - (-1 + 2 * laterality[lay]) * rect0vdrift;
610 
611  // If a hit is too close to the wire, set its corresponding "swap" flag to 1
612  if (abs(rectdriftvdrift[lay]) < 3) {
613  swap_laterality[lay] = 1;
614  }
615 
616  if ((present_layer[lay] == 1) && (rectdriftvdrift[lay] < -0.1)) {
617  sign_tdriftvdrift = -1;
618  if (-0.1 - rectdriftvdrift[lay] > maxDif) {
619  maxDif = -0.1 - rectdriftvdrift[lay];
620  maxInt = lay;
621  }
622  }
623  if ((present_layer[lay] == 1) && (abs(rectdriftvdrift[lay]) > 21.1)) {
624  incell_tdriftvdrift = -1; //Changed to 2.11 to account for resolution effects
625  if (rectdriftvdrift[lay] - 21.1 > maxDif) {
626  maxDif = rectdriftvdrift[lay] - 21.1;
627  maxInt = lay;
628  }
629  }
630  }
631 
632  // Now consider all possible alternative lateralities and push to lateralities_ those
633  // we aren't considering yet
634  if (lat_added == 0) {
635  std::vector<TLateralities> additional_lateralities;
636  additional_lateralities.clear();
637  additional_lateralities.push_back(laterality);
638  // Everytime the swap flag is 1, duplicate all the current elements
639  // of additional_lateralities and swap their laterality
640  for (int swap = 0; swap < 8; ++swap) {
641  if (swap_laterality[swap] == 1) {
642  int add_lat_size = int(additional_lateralities.size());
643  for (int ll = 0; ll < add_lat_size; ++ll) {
644  TLateralities tmp_lat = additional_lateralities[ll];
645  if (tmp_lat[swap] == LEFT)
646  tmp_lat[swap] = RIGHT;
647  else if (tmp_lat[swap] == RIGHT)
648  tmp_lat[swap] = LEFT;
649  else
650  continue;
651  additional_lateralities.push_back(tmp_lat);
652  }
653  }
654  }
655  // Now compare all the additional lateralities with the lateralities we are considering:
656  // if they are not there, add them
657  int already_there = 0;
658  for (int k = 0; k < int(additional_lateralities.size()); ++k) {
659  already_there = 0;
660  for (int j = 0; j < int(lateralities_.size()); ++j) {
661  if (additional_lateralities[k] == lateralities_[j])
662  already_there = 1;
663  }
664  if (already_there == 0) {
665  lateralities_.push_back(additional_lateralities[k]);
666  }
667  }
668  additional_lateralities.clear();
669  lat_added = 1;
670  }
671 
672  if (fabs(recslope / 10) > 1.3)
673  physical_slope = -1;
674 
675  if (physical_slope == -1 && debug_)
676  LogDebug("MuonPathAnalyzerInChamber") << "Combination with UNPHYSICAL slope ";
677  if (sign_tdriftvdrift == -1 && debug_)
678  LogDebug("MuonPathAnalyzerInChamber") << "Combination with negative tdrift-vdrift ";
679  if (incell_tdriftvdrift == -1 && debug_)
680  LogDebug("MuonPathAnalyzerInChamber") << "Combination with tdrift-vdrift larger than half cell ";
681 
682  for (int lay = 0; lay < 8; lay++) {
683  if (present_layer[lay] == 0)
684  continue;
685  recchi2 = recres[lay] * recres[lay] + recchi2;
686  }
687  // Chi2/ndof
688  if (n_hits > 4)
689  recchi2 = recchi2 / (n_hits - 3);
690 
691  if (debug_)
692  LogDebug("MuonPathAnalyzerInChamber")
693  << "In fitPerLat Chi2 " << recchi2 << " with sign " << sign_tdriftvdrift << " within cell "
694  << incell_tdriftvdrift << " physical_slope " << physical_slope;
695 
696  //LATERALITY IS NOT VALID
697  if (true && maxInt != -1) {
698  present_layer[maxInt] = 0;
699  if (debug_)
700  LogDebug("MuonPathAnalyzerInChamber") << "We get rid of hit in layer " << maxInt;
701  }
702 
703  // LATERALITY IS VALID...
704  if (!(sign_tdriftvdrift == -1) && !(incell_tdriftvdrift == -1) && !(physical_slope == -1)) {
705  mpath->setBxTimeValue((rect0vdrift / DRIFT_SPEED) / 1000);
706  mpath->setTanPhi(-1 * recslope / 10);
707  mpath->setHorizPos(recpos / 10000);
708  mpath->setChiSquare(recchi2 / 100000000);
709  setLateralitiesInMP(mpath, laterality);
710  if (debug_)
711  LogDebug("MuonPathAnalyzerInChamber")
712  << "In fitPerLat "
713  << "t0 " << mpath->bxTimeValue() << " slope " << mpath->tanPhi() << " pos " << mpath->horizPos() << " chi2 "
714  << mpath->chiSquare() << " rawId " << mpath->rawId();
715  }
716 }
718  mPath->setQuality(NOPATH);
719 
720  int validHits(0), nPrimsUp(0), nPrimsDown(0);
721  for (int i = 0; i < NUM_LAYERS_2SL; i++) {
722  if (mPath->primitive(i)->isValidTime()) {
723  validHits++;
724  if (i < 4)
725  nPrimsDown++;
726  else if (i >= 4)
727  nPrimsUp++;
728  }
729  }
730 
731  mPath->setNPrimitivesUp(nPrimsUp);
732  mPath->setNPrimitivesDown(nPrimsDown);
733 
734  if (mPath->nprimitivesUp() >= 4 && mPath->nprimitivesDown() >= 4) {
735  mPath->setQuality(HIGHHIGHQ);
736  } else if ((mPath->nprimitivesUp() == 4 && mPath->nprimitivesDown() == 3) ||
737  (mPath->nprimitivesUp() == 3 && mPath->nprimitivesDown() == 4)) {
738  mPath->setQuality(HIGHLOWQ);
739  } else if ((mPath->nprimitivesUp() == 4 && mPath->nprimitivesDown() <= 2 && mPath->nprimitivesDown() > 0) ||
740  (mPath->nprimitivesUp() <= 2 && mPath->nprimitivesUp() > 0 && mPath->nprimitivesDown() == 4)) {
741  mPath->setQuality(CHIGHQ);
742  } else if ((mPath->nprimitivesUp() == 3 && mPath->nprimitivesDown() == 3)) {
743  mPath->setQuality(LOWLOWQ);
744  } else if ((mPath->nprimitivesUp() == 3 && mPath->nprimitivesDown() <= 2 && mPath->nprimitivesDown() > 0) ||
745  (mPath->nprimitivesUp() <= 2 && mPath->nprimitivesUp() > 0 && mPath->nprimitivesDown() == 3) ||
746  (mPath->nprimitivesUp() == 2 && mPath->nprimitivesDown() == 2)) {
747  mPath->setQuality(CLOWQ);
748  } else if (mPath->nprimitivesUp() >= 4 || mPath->nprimitivesDown() >= 4) {
749  mPath->setQuality(HIGHQ);
750  } else if (mPath->nprimitivesUp() == 3 || mPath->nprimitivesDown() == 3) {
751  mPath->setQuality(LOWQ);
752  }
753 }
int station() const
Return the station number.
Definition: DTChamberId.h:42
def isnan(num)
void setChiSquareThreshold(float ch2Thr)
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
MuonPathAnalyzerInChamber(const edm::ParameterSet &pset, edm::ConsumesCollector &iC, std::shared_ptr< GlobalCoordsObtainer > &globalcoordsobtainer)
int superLayer() const
Return the superlayer number.
void setCellLayout(MuonPathPtr &mpath)
std::string fullPath() const
Definition: FileInPath.cc:161
LATERAL_CASES
Definition: constants.h:45
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
std::vector< MuonPathPtr > MuonPathPtrs
Definition: MuonPath.h:128
void setWirePosAndTimeInMP(MuonPathPtr &mpath)
edm::ESGetToken< DTGeometry, MuonGeometryRecord > dtGeomH
std::map< std::string, int, std::less< std::string > > psi
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
void evaluateQuality(MuonPathPtr &mPath)
int iEvent
Definition: GenABIO.cc:224
constexpr int INCREASED_RES_SLOPE_POW
Definition: constants.h:277
void buildLateralities(MuonPathPtr &mpath)
constexpr float Z_SHIFT_MB4
Definition: constants.h:258
void setLateralitiesInMP(MuonPathPtr &mpath, TLateralities lat)
std::map< int, float > shiftinfo_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void initialise(const edm::EventSetup &iEventSetup) override
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:130
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
ii
Definition: cuy.py:589
std::vector< TLateralities > lateralities_
constexpr double PHI_CONV
Definition: constants.h:255
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
void calculateFitParameters(MuonPathPtr &mpath, TLateralities lat, int present_layer[cmsdt::NUM_LAYERS_2SL], int &lat_added)
constexpr int NUM_LAYERS_2SL
Definition: constants.h:254
double b
Definition: hdecay.h:118
std::vector< cmsdt::LATQ_TYPE > latQuality_
void analyze(MuonPathPtr &inMPath, MuonPathPtrs &outMPaths)
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:39
HLT enums.
int sector() const
Definition: DTChamberId.h:49
std::shared_ptr< MuonPath > MuonPathPtr
Definition: MuonPath.h:127
static unsigned int const shift
std::shared_ptr< GlobalCoordsObtainer > globalcoordsobtainer_
constexpr int INCREASED_RES_POS_POW
Definition: constants.h:276
Definition: TkAlStyle.h:43
const DTChamber * chamber(const DTChamberId &id) const
Return a DTChamber given its id.
Definition: DTGeometry.cc:90
def move(src, dest)
Definition: eostools.py:511
void run(edm::Event &iEvent, const edm::EventSetup &iEventSetup, MuonPathPtrs &inMpath, std::vector< cmsdt::metaPrimitive > &metaPrimitives) override
std::shared_ptr< DTPrimitive > DTPrimitivePtr
Definition: DTprimitive.h:54
constexpr float DRIFT_SPEED
Definition: constants.h:189
int cellLayout_[cmsdt::NUM_LAYERS_2SL]
#define LogDebug(id)