CMS 3D CMS Logo

DTCombinatorialExtendedPatternReco.cc
Go to the documentation of this file.
1 
7 /* This Class Header */
9 
10 /* Collaborating Class Header */
25 
26 
27 /* C++ Headers */
28 #include <iterator>
29 using namespace std;
31 
32 /* ====================================================================== */
33 
36 DTRecSegment2DBaseAlgo(pset), theAlgoName("DTCombinatorialExtendedPatternReco")
37 {
38  theMaxAllowedHits = pset.getParameter<unsigned int>("MaxAllowedHits"); // 100
39  theAlphaMaxTheta = pset.getParameter<double>("AlphaMaxTheta");// 0.1 ;
40  theAlphaMaxPhi = pset.getParameter<double>("AlphaMaxPhi");// 1.0 ;
41  debug = pset.getUntrackedParameter<bool>("debug"); //true;
42  theUpdator = new DTSegmentUpdator(pset);
43  theCleaner = new DTSegmentCleaner(pset);
44  string theHitAlgoName = pset.getParameter<string>("recAlgo");
45  usePairs = !(theHitAlgoName=="DTNoDriftAlgo");
46 }
47 
50 }
51 
52 /* Operations */
55  const std::vector<DTRecHit1DPair>& pairs){
56 
57  if(debug) cout << "DTCombinatorialExtendedPatternReco::reconstruct" << endl;
58  theTriedPattern.clear();
60  vector<std::shared_ptr<DTHitPairForFit>> hitsForFit = initHits(sl, pairs);
61 
62  vector<DTSegmentCand*> candidates = buildSegments(sl, hitsForFit);
63 
64  vector<DTSegmentCand*>::const_iterator cand=candidates.begin();
65  while (cand<candidates.end()) {
66 
67  DTSLRecSegment2D *segment = (**cand);
68 
69  theUpdator->update(segment,false);
70 
71  result.push_back(segment);
72 
73  if (debug) {
74  cout<<"Reconstructed 2D extended segments "<< result.back() <<endl;
75  }
76 
77  delete *(cand++); // delete the candidate!
78  }
79 
80  return result;
81 }
82 
84  // Get the DT Geometry
85  setup.get<MuonGeometryRecord>().get(theDTGeometry);
86  theUpdator->setES(setup);
87 }
88 
89 void DTCombinatorialExtendedPatternReco::setClusters(const vector<DTSLRecCluster>& clusters) {
91 }
92 
93 vector<std::shared_ptr<DTHitPairForFit>>
95  const std::vector<DTRecHit1DPair>& hits){
96 
97  vector<std::shared_ptr<DTHitPairForFit>> result;
98  for (vector<DTRecHit1DPair>::const_iterator hit=hits.begin();
99  hit!=hits.end(); ++hit) {
100  result.push_back(std::make_shared<DTHitPairForFit>(*hit, *sl, theDTGeometry));
101  }
102  return result;
103 }
104 
105 vector<DTSegmentCand*>
107  const std::vector<std::shared_ptr<DTHitPairForFit>>& hits){
108 
109  typedef vector<std::shared_ptr<DTHitPairForFit>> hitCont;
110  typedef hitCont::const_iterator hitIter;
111  vector<DTSegmentCand*> result;
112 
113  if(debug) {
114  cout << "DTCombinatorialExtendedPatternReco::buildSegments: " << sl->id() << " nHits " << hits.size() << endl;
115  for (vector<std::shared_ptr<DTHitPairForFit>>::const_iterator hit=hits.begin();
116  hit!=hits.end(); ++hit) cout << **hit<< endl;
117  }
118 
119  // 10-Mar-2004 SL
120  // put a protection against heavily populated chambers, for which the segment
121  // building could lead to infinite memory usage...
122  if (hits.size() > theMaxAllowedHits ) {
123  if(debug) {
124  cout << "Warning: this SuperLayer " << sl->id() << " has too many hits : "
125  << hits.size() << " max allowed is " << theMaxAllowedHits << endl;
126  cout << "Skipping segment reconstruction... " << endl;
127  }
128  return result;
129  }
130 
132  // compatible with them
133  for (hitCont::const_iterator firstHit=hits.begin(); firstHit!=hits.end();
134  ++firstHit) {
135  for (hitCont::const_reverse_iterator lastHit=hits.rbegin();
136  (*lastHit)!=(*firstHit); ++lastHit) {
137  // hits must nor in the same nor in adiacent layers
138  if ( fabs((*lastHit)->id().layerId()-(*firstHit)->id().layerId())<=1 ) continue;
139  if(debug) {
140  cout << "Selected these two hits pair " << endl;
141  cout << "First " << *(*firstHit) << " Layer Id: " << (*firstHit)->id().layerId() << endl;
142  cout << "Last " << *(*lastHit) << " Layer Id: " << (*lastHit)->id().layerId() << endl;
143  }
144 
145  GlobalPoint IP;
146  float DAlphaMax;
147  if ((sl->id()).superlayer()==2) // Theta SL
148  DAlphaMax=theAlphaMaxTheta;
149  else // Phi SL
150  DAlphaMax=theAlphaMaxPhi;
151 
153  for (int firstLR=0; firstLR<2; ++firstLR) {
154  for (int lastLR=0; lastLR<2; ++lastLR) {
155  // TODO move the global transformation in the DTHitPairForFit class
156  // when it will be moved I will able to remove the sl from the input parameter
157  GlobalPoint gposFirst=sl->toGlobal( (*firstHit)->localPosition(codes[firstLR]) );
158  GlobalPoint gposLast= sl->toGlobal( (*lastHit)->localPosition(codes[lastLR]) );
159 
160  GlobalVector gvec=gposLast-gposFirst;
161  GlobalVector gvecIP=gposLast-IP;
162 
163  // difference in angle measured
164  float DAlpha=fabs(gvec.theta()-gvecIP.theta());
165 
166  // cout << "DAlpha " << DAlpha << endl;
167  if (DAlpha<DAlphaMax) {
168 
169  // create a segment hypotesis
170  // I don't need a true segment, just direction and position
171  LocalPoint posIni = (*firstHit)->localPosition(codes[firstLR]);
172  LocalVector dirIni =
173  ((*lastHit)->localPosition(codes[lastLR])-posIni).unit();
174 
175  // search for other compatible hits, with or without the L/R solved
176  vector<DTSegmentCand::AssPoint> assHits = findCompatibleHits(posIni, dirIni, hits);
177  if(debug)
178  cout << "compatible hits " << assHits.size() << endl;
179 
180  // here return an extended candidate (which _has_ the original
181  // segment)
182  DTSegmentExtendedCand* seg = buildBestSegment(assHits, sl);
183 
184  if (seg) {
185  if(debug)
186  cout << "segment " << *seg<< endl;
187 
188  // check if the chi2 and #hits are ok
189  if (!seg->good()) { // good is reimplmented in extended segment
190  delete seg;
191  } else {
192 
193  // remove duplicated segments
194  if (checkDoubleCandidates(result,seg)) {
195  // add to the vector of hypotesis
196  // still work with extended segments
197  result.push_back(seg);
198  if(debug)
199  cout << "result is now " << result.size() << endl;
200  } else { // delete it!
201  delete seg;
202  if(debug)
203  cout << "already existing" << endl;
204  }
205  }
206  }
207  }
208  }
209  }
210  }
211  }
212  if (debug) {
213  for (vector<DTSegmentCand*>::const_iterator seg=result.begin();
214  seg!=result.end(); ++seg)
215  cout << *(*seg) << endl;
216  }
217 
218  // now I have a couple of segment hypotesis, should check for ghost
219  // still with extended candidates
220  result = theCleaner->clean(result);
221  if (debug) {
222  cout << "result no ghost " << result.size() << endl;
223  for (vector<DTSegmentCand*>::const_iterator seg=result.begin();
224  seg!=result.end(); ++seg)
225  cout << *(*seg) << endl;
226  }
227 
228  // here, finally, I have to return the set of _original_ segments, not the
229  // extended ones.
230  return result;
231 }
232 
233 
234 vector<DTSegmentCand::AssPoint>
236  const LocalVector& dirIni,
237  const vector<std::shared_ptr<DTHitPairForFit>>& hits) {
238  if (debug) cout << "Pos: " << posIni << " Dir: "<< dirIni << endl;
239  vector<DTSegmentCand::AssPoint> result;
240 
241  // counter to early-avoid double counting in hits pattern
242  vector<int> tried;
243  int nCompatibleHits=0;
244 
245  typedef vector<std::shared_ptr<DTHitPairForFit>> hitCont;
246  typedef hitCont::const_iterator hitIter;
247  for (hitIter hit=hits.begin(); hit!=hits.end(); ++hit) {
248  pair<bool,bool> isCompatible = (*hit)->isCompatible(posIni, dirIni);
249  if (debug)
250  cout << "isCompatible " << isCompatible.first << " " <<
251  isCompatible.second << endl;
252 
253  // if only one of the two is compatible, then the LR is assigned,
254  // otherwise is undefined
255 
256  DTEnums::DTCellSide lrcode;
257  if (isCompatible.first && isCompatible.second) {
258  usePairs ? lrcode=DTEnums::undefLR : lrcode=DTEnums::Left ; // if not usePairs then only use single side
259  tried.push_back(3);
260  nCompatibleHits++;
261  }
262  else if (isCompatible.first) {
263  lrcode=DTEnums::Left;
264  tried.push_back(2);
265  nCompatibleHits++;
266  }
267  else if (isCompatible.second) {
268  lrcode=DTEnums::Right;
269  tried.push_back(1);
270  nCompatibleHits++;
271  }
272  else {
273  tried.push_back(0);
274  continue; // neither is compatible
275  }
276  result.push_back(DTSegmentCand::AssPoint(*hit, lrcode));
277  }
278 
279 
280  // check if too few associated hits or pattern already tried
281  if ( nCompatibleHits < 3 || find(theTriedPattern.begin(), theTriedPattern.end(),tried) == theTriedPattern.end()) {
282  theTriedPattern.push_back(tried);
283  } else {
284  if (debug) {
285  vector<vector<int> >::const_iterator t=find(theTriedPattern.begin(),
286  theTriedPattern.end(),
287  tried);
288  cout << "Already tried";
289  copy((*t).begin(), (*t).end(), ostream_iterator<int>(std::cout));
290  cout << endl;
291  }
292  // empty the result vector
293  result.clear();
294  }
295  return result;
296 }
297 
299 DTCombinatorialExtendedPatternReco::buildBestSegment(std::vector<DTSegmentCand::AssPoint>& hits,
300  const DTSuperLayer* sl) {
301  if (debug) cout << "DTCombinatorialExtendedPatternReco::buildBestSegment " <<
302  hits.size() << endl;
303  if (hits.size()<3) {
304  //cout << "buildBestSegment: hits " << hits.size()<< endl;
305  return nullptr; // a least 3 point
306  }
307 
308  // hits with defined LR
309  vector<DTSegmentCand::AssPoint> points;
310 
311  // without: I store both L and R, a deque since I need front insertion and
312  // deletion
313  deque<std::shared_ptr<DTHitPairForFit>> pointsNoLR;
314 
315  // first add only the hits with LR assigned
316  for (vector<DTSegmentCand::AssPoint>::const_iterator hit=hits.begin();
317  hit!=hits.end(); ++hit) {
318  if ((*hit).second != DTEnums::undefLR) {
319  points.push_back(*hit);
320  } else { // then also for the undef'd one
321  pointsNoLR.push_back((*hit).first);
322  }
323  }
324 
325  if(debug) {
326  cout << "points " << points.size() << endl;
327  cout << "pointsNoLR " << pointsNoLR.size() << endl;
328  }
329 
330  // build all possible candidates using L/R ambiguity
331  vector<DTSegmentCand*> candidates ;
332 
333  buildPointsCollection(points, pointsNoLR, candidates, sl);
334 
335  // here I try to add the external clusters and build a set of "extended
336  // segment candidate
337  vector<DTSegmentExtendedCand*> extendedCands = extendCandidates(candidates,
338  sl);
339  if (debug) cout << "extended candidates " << extendedCands.size() << endl;
340 
341  // so now I have build a given number of segments, I should find the best one,
342  // by #hits and chi2.
343  vector<DTSegmentExtendedCand*>::const_iterator bestCandIter = extendedCands.end();
344  double minChi2=999999.;
345  unsigned int maxNumHits=0;
346  for (vector<DTSegmentExtendedCand*>::const_iterator iter=extendedCands.begin();
347  iter!=extendedCands.end(); ++iter) {
348  if ((*iter)->nHits()==maxNumHits && (*iter)->chi2()<minChi2) {
349  minChi2=(*iter)->chi2();
350  bestCandIter=iter;
351  } else if ((*iter)->nHits()>maxNumHits) {
352  maxNumHits=(*iter)->nHits();
353  minChi2=(*iter)->chi2();
354  bestCandIter=iter;
355  }
356  }
357 
358  // delete all candidates but the best one!
359  for (vector<DTSegmentExtendedCand*>::iterator iter=extendedCands.begin();
360  iter!=extendedCands.end(); ++iter)
361  if (iter!=bestCandIter) delete (*iter);
362 
363  // return the best candate if any
364  if (bestCandIter != extendedCands.end()) {
365  return (*bestCandIter);
366  }
367  return nullptr;
368 }
369 
370 void
372  deque<std::shared_ptr<DTHitPairForFit>>& pointsNoLR,
373  vector<DTSegmentCand*>& candidates,
374  const DTSuperLayer* sl) {
375 
376  if(debug) {
377  cout << "DTCombinatorialExtendedPatternReco::buildPointsCollection " << endl;
378  cout << "points: " << points.size() << " NOLR: " << pointsNoLR.size()<< endl;
379  }
380  if (!pointsNoLR.empty()) { // still unassociated points!
381  std::shared_ptr<DTHitPairForFit> unassHit = pointsNoLR.front();
382  // try with the right
383  if(debug)
384  cout << "Right hit" << endl;
385  points.push_back(DTSegmentCand::AssPoint(unassHit, DTEnums::Right));
386  pointsNoLR.pop_front();
387  buildPointsCollection(points, pointsNoLR, candidates, sl);
388  pointsNoLR.push_front((unassHit));
389  points.pop_back();
390 
391  // try with the left
392  if(debug)
393  cout << "Left hit" << endl;
394  points.push_back(DTSegmentCand::AssPoint(unassHit, DTEnums::Left));
395  pointsNoLR.pop_front();
396  buildPointsCollection(points, pointsNoLR, candidates, sl);
397  pointsNoLR.push_front((unassHit));
398  points.pop_back();
399  } else { // all associated
400 
401  if(debug) {
402  cout << "The Hits were" << endl;
403  copy(points.begin(), points.end(),
404  ostream_iterator<DTSegmentCand::AssPoint>(std::cout));
405  cout << "----" << endl;
406  cout << "All associated " << endl;
407  }
408  DTSegmentCand::AssPointCont pointsSet;
409 
410  // for (vector<DTSegmentCand::AssPoint>::const_iterator point=points.begin();
411  // point!=points.end(); ++point)
412  pointsSet.insert(points.begin(),points.end());
413 
414  if(debug) {
415  cout << "The Hits are" << endl;
416  copy(pointsSet.begin(), pointsSet.end(),
417  ostream_iterator<DTSegmentCand::AssPoint>(std::cout));
418  cout << "----" << endl;
419  }
420 
421  DTSegmentCand* newCand = new DTSegmentCand(pointsSet,sl);
422  if (theUpdator->fit(newCand,false,false)) candidates.push_back(newCand);
423  else delete newCand; // bad seg, too few hits
424  }
425 }
426 
427 bool
429  DTSegmentCand* seg) {
430  for (vector<DTSegmentCand*>::iterator cand=cands.begin();
431  cand!=cands.end(); ++cand)
432  if (*(*cand)==*seg) return false;
433  return true;
434 }
435 
436 vector<DTSegmentExtendedCand*>
438  const DTSuperLayer* sl) {
439  if (debug) cout << "extendCandidates " << candidates.size() << endl;
440  vector<DTSegmentExtendedCand*> result;
441 
442  // in case of phi SL just return
443  if (sl->id().superLayer() != 2 ) {
444  for (vector<DTSegmentCand*>:: const_iterator cand=candidates.begin();
445  cand!=candidates.end(); ++cand) {
446  DTSegmentExtendedCand* extendedCand = new DTSegmentExtendedCand(*cand);
447  // and delete the original candidate
448  delete *cand;
449  result.push_back(extendedCand);
450  }
451  return result;
452  }
453 
454  // first I have to select the cluster which are compatible with the actual
455  // candidate, namely +/-1 sector/station/wheel
456  vector<DTSegmentExtendedCand::DTSLRecClusterForFit> clustersWithPos;
457  if (debug) cout << "AllClustersWithPos " << theClusters.size() << endl;
458  if(debug) cout << "SL: " << sl->id() << endl;
459  for (vector<DTSLRecCluster>::const_iterator clus=theClusters.begin();
460  clus!=theClusters.end(); ++clus) {
461  if(debug) cout << "CLUS: " << (*clus).superLayerId() << endl;
462  if ((*clus).superLayerId().superLayer()==2 && closeSL(sl->id(),(*clus).superLayerId())) {
463  // and then get their pos in the actual SL frame
464  const DTSuperLayer* clusSl =
465  theDTGeometry->superLayer((*clus).superLayerId());
466  LocalPoint pos=sl->toLocal(clusSl->toGlobal((*clus).localPosition()));
467  //LocalError err=sl->toLocal(clusSl->toGlobal((*clus).localPositionError()));
468  LocalError err=(*clus).localPositionError();
469  clustersWithPos.push_back(DTSegmentExtendedCand::DTSLRecClusterForFit(*clus, pos, err) );
470  }
471  }
472  if (debug) cout << "closeClustersWithPos " << clustersWithPos.size() << endl;
473 
474  for (vector<DTSegmentCand*>:: const_iterator cand=candidates.begin();
475  cand!=candidates.end(); ++cand) {
476  // create an extended candidate
477  DTSegmentExtendedCand* extendedCand = new DTSegmentExtendedCand(*cand);
478  // and delete the original candidate
479  delete *cand;
480  // do this only for theta SL
481  if (extendedCand->superLayer()->id().superLayer() == 2 ) {
482  // first check compatibility between cand and clusForFit
483  for (vector<DTSegmentExtendedCand::DTSLRecClusterForFit>::const_iterator
484  exClus=clustersWithPos.begin(); exClus!=clustersWithPos.end(); ++exClus) {
485  if (extendedCand->isCompatible(*exClus)) {
486  if (debug) cout << "is compatible " << endl;
487  // add compatible cluster
488  extendedCand->addClus(*exClus);
489  }
490  }
491  // fit the segment
492  if (debug) cout << "extended cands nHits: " << extendedCand->nHits() <<endl;
493  if (theUpdator->fit(extendedCand,false,false)) {
494  // add to result
495  result.push_back(extendedCand);
496  } else {
497  cout << "Bad fit" << endl;
498  delete extendedCand;
499  }
500  } else { // Phi SuperLayer
501  result.push_back(extendedCand);
502  }
503  }
504 
505  return result;
506 }
507 
509  const DTSuperLayerId& id2) {
510  if (id1==id2) return false;
511  if (abs(id1.wheel()-id2.wheel())>1 ) return false;
512  // take into account also sector 13 and 14
513  int sec1 = ( id1.sector()==13 ) ? 4: id1.sector();
514  sec1=(sec1==14)? 10: sec1;
515  int sec2 = ( id2.sector()==13 ) ? 4: id2.sector();
516  sec2=(sec2==14)? 10: sec2;
517  // take into account also sector 1/12
518  if (abs(sec1-sec2)>1 && abs(sec1-sec2)!=11 ) return false;
519  //if (abs(id1.station()-id2.station())>1 ) return false;
520  return true;
521 }
std::pair< std::shared_ptr< DTHitPairForFit >, DTEnums::DTCellSide > AssPoint
Definition: DTSegmentCand.h:38
T getParameter(std::string const &) const
edm::OwnVector< DTSLRecSegment2D > reconstruct(const DTSuperLayer *sl, const std::vector< DTRecHit1DPair > &hits) override
this function is called in the producer
void setClusters(const std::vector< DTSLRecCluster > &clusters)
T getUntrackedParameter(std::string const &, T const &) const
reference back()
Definition: OwnVector.h:395
def copy(args, dbName)
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
std::vector< DTSegmentCand * > buildSegments(const DTSuperLayer *sl, const std::vector< std::shared_ptr< DTHitPairForFit >> &hits)
DTCellSide
Which side of the DT cell.
Definition: DTEnums.h:15
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:2
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:69
std::vector< DTSegmentCand * > clean(const std::vector< DTSegmentCand * > &inputCands) const
do the cleaning
DTCombinatorialExtendedPatternReco(const edm::ParameterSet &pset)
Constructor.
bool checkDoubleCandidates(std::vector< DTSegmentCand * > &segs, DTSegmentCand *seg)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
std::vector< std::shared_ptr< DTHitPairForFit > > hitCont
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
bool good() const override
DTSuperLayerId id() const
Return the DetId of this SL.
Definition: DTSuperLayer.cc:36
void push_back(D *&d)
Definition: OwnVector.h:290
void setES(const edm::EventSetup &setup)
set the setup
void buildPointsCollection(std::vector< DTSegmentCand::AssPoint > &points, std::deque< std::shared_ptr< DTHitPairForFit >> &pointsNoLR, std::vector< DTSegmentCand * > &candidates, const DTSuperLayer *sl)
std::vector< std::shared_ptr< DTHitPairForFit > > initHits(const DTSuperLayer *sl, const std::vector< DTRecHit1DPair > &hits)
unsigned int nHits() const override
std::vector< std::vector< int > > theTriedPattern
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int superLayer() const
Return the superlayer number.
void addClus(const DTSegmentExtendedCand::DTSLRecClusterForFit &clus)
std::vector< DTSegmentExtendedCand * > extendCandidates(std::vector< DTSegmentCand * > &candidates, const DTSuperLayer *sl)
void setES(const edm::EventSetup &setup) override
const DTSuperLayer * superLayer() const
the super layer on which relies
Definition: DTSegmentCand.h:79
bool isCompatible(const DTSegmentExtendedCand::DTSLRecClusterForFit &clus)
std::set< AssPoint, AssPointLessZ > AssPointCont
Definition: DTSegmentCand.h:40
hitCont::const_iterator hitIter
bool closeSL(const DTSuperLayerId &id1, const DTSuperLayerId &id2)
int sector() const
Definition: DTChamberId.h:61
T get() const
Definition: EventSetup.h:71
void update(DTRecSegment4D *seg, const bool calcT0, bool allow3par) const
recompute hits position and refit the segment4D
DTSegmentExtendedCand * buildBestSegment(std::vector< DTSegmentCand::AssPoint > &assHits, const DTSuperLayer *sl)
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
std::vector< DTSegmentCand::AssPoint > findCompatibleHits(const LocalPoint &pos, const LocalVector &dir, const std::vector< std::shared_ptr< DTHitPairForFit >> &hits)
bool fit(DTSegmentCand *seg, bool allow3par, const bool fitdebug) const
const DTSuperLayer * superLayer(const DTSuperLayerId &id) const
Return a DTSuperLayer given its id.
Definition: DTGeometry.cc:122