CMS 3D CMS Logo

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