CMS 3D CMS Logo

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