CMS 3D CMS Logo

DTCombinatorialPatternReco.cc
Go to the documentation of this file.
1 
7 /* This Class Header */
9 
10 /* Collaborating Class Header */
24 
25 
26 /* C++ Headers */
27 #include <iterator>
28 using namespace std;
30 
31 /* ====================================================================== */
32 
35 DTRecSegment2DBaseAlgo(pset), theAlgoName("DTCombinatorialPatternReco")
36 {
37  theMaxAllowedHits = pset.getParameter<unsigned int>("MaxAllowedHits"); // 100
38  theAlphaMaxTheta = pset.getParameter<double>("AlphaMaxTheta");// 0.1 ;
39  theAlphaMaxPhi = pset.getParameter<double>("AlphaMaxPhi");// 1.0 ;
40  debug = pset.getUntrackedParameter<bool>("debug"); //true;
41  theUpdator = new DTSegmentUpdator(pset);
42  theCleaner = new DTSegmentCleaner(pset);
43  string theHitAlgoName = pset.getParameter<string>("recAlgo");
44  usePairs = !(theHitAlgoName=="DTNoDriftAlgo");
45 }
46 
49  delete theUpdator;
50  delete theCleaner;
51 }
52 
53 /* Operations */
56  const std::vector<DTRecHit1DPair>& pairs){
57 
59  vector<std::shared_ptr<DTHitPairForFit>> hitsForFit = initHits(sl, pairs);
60 
61  vector<DTSegmentCand*> candidates = buildSegments(sl, hitsForFit);
62 
63  vector<DTSegmentCand*>::const_iterator cand=candidates.begin();
64  while (cand<candidates.end()) {
65 
66  DTSLRecSegment2D *segment = (**cand);
67 
68  theUpdator->update(segment,false);
69 
70  result.push_back(segment);
71 
72  if (debug) {
73  cout<<"Reconstructed 2D segments "<< result.back() <<endl;
74  }
75 
76  delete *(cand++); // delete the candidate!
77  }
78 
79  return result;
80 }
81 
83  // Get the DT Geometry
84  setup.get<MuonGeometryRecord>().get(theDTGeometry);
85  theUpdator->setES(setup);
86 }
87 
88 vector<std::shared_ptr<DTHitPairForFit>>
90  const std::vector<DTRecHit1DPair>& hits){
91 
92  vector<std::shared_ptr<DTHitPairForFit>> result;
93  for (vector<DTRecHit1DPair>::const_iterator hit=hits.begin();
94  hit!=hits.end(); ++hit) {
95  result.push_back(std::make_shared<DTHitPairForFit>(*hit, *sl, theDTGeometry));
96  }
97  return result;
98 }
99 
100 vector<DTSegmentCand*>
102  const std::vector<std::shared_ptr<DTHitPairForFit>>& hits){
103  // clear the patterns tried
104  if (debug) {
105  cout << "theTriedPattern.size is " << theTriedPattern.size() << "\n";
106  }
107  theTriedPattern.clear();
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 << "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  //if ( (*lastHit)->id().layerId() == (*firstHit)->id().layerId() ) continue; // hits must be in different layers!
138  // hits must nor in the same nor in adiacent layers
139  if ( fabs((*lastHit)->id().layerId()-(*firstHit)->id().layerId())<=1 ) continue;
140  if(debug) {
141  cout << "Selected these two hits pair " << endl;
142  cout << "First " << *(*firstHit) << " Layer Id: " << (*firstHit)->id().layerId() << endl;
143  cout << "Last " << *(*lastHit) << " Layer Id: " << (*lastHit)->id().layerId() << endl;
144  }
145 
146  GlobalPoint IP;
147  float DAlphaMax;
148  if ((sl->id()).superlayer()==2) // Theta SL
149  DAlphaMax=theAlphaMaxTheta;
150  else // Phi SL
151  DAlphaMax=theAlphaMaxPhi;
152 
154  for (int firstLR=0; firstLR<2; ++firstLR) {
155  for (int lastLR=0; lastLR<2; ++lastLR) {
156  // TODO move the global transformation in the DTHitPairForFit class
157  // when it will be moved I will able to remove the sl from the input parameter
158  GlobalPoint gposFirst=sl->toGlobal( (*firstHit)->localPosition(codes[firstLR]) );
159  GlobalPoint gposLast= sl->toGlobal( (*lastHit)->localPosition(codes[lastLR]) );
160 
161  GlobalVector gvec=gposLast-gposFirst;
162  GlobalVector gvecIP=gposLast-IP;
163 
164  // difference in angle measured
165  float DAlpha=fabs(gvec.theta()-gvecIP.theta());
166 
167  // cout << "DAlpha " << DAlpha << endl;
168  if (DAlpha<DAlphaMax) {
169 
170  // create a segment hypotesis
171  // I don't need a true segment, just direction and position
172  LocalPoint posIni = (*firstHit)->localPosition(codes[firstLR]);
173  LocalVector dirIni =
174  ((*lastHit)->localPosition(codes[lastLR])-posIni).unit();
175 
176  // search for other compatible hits, with or without the L/R solved
177  vector<DTSegmentCand::AssPoint> assHits = findCompatibleHits(posIni, dirIni, hits);
178  if(debug)
179  cout << "compatible hits " << assHits.size() << endl;
180 
181  // get the best segment with these hits: it's just one!
182  // (is it correct?)
183  DTSegmentCand* seg = buildBestSegment(assHits, sl);
184 
185  if (seg) {
186  if(debug)
187  cout << "segment " << *seg<< endl;
188 
189  // check if the chi2 and #hits are ok
190  if (!seg->good()) {
191  delete seg;
192  } else {
193 
194  // remove duplicated segments (I know, would be better to do it before the
195  // fit...)
196  if (checkDoubleCandidates(result,seg)) {
197  // add to the vector of hypotesis
198  result.push_back(seg);
199  if(debug)
200  cout << "result is now " << result.size() << endl;
201  } else { // delete it!
202  delete seg;
203  if(debug)
204  cout << "already existing" << endl;
205  }
206  }
207  }
208  }
209  }
210  }
211  }
212  }
213  if (debug) {
214  for (vector<DTSegmentCand*>::const_iterator seg=result.begin();
215  seg!=result.end(); ++seg)
216  cout << *(*seg) << endl;
217  }
218 
219  // now I have a couple of segment hypotesis, should check for ghost
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  return result;
229 }
230 
231 
232 vector<DTSegmentCand::AssPoint>
234  const LocalVector& dirIni,
235  const vector<std::shared_ptr<DTHitPairForFit>>& hits) {
236  if (debug) cout << "Pos: " << posIni << " Dir: "<< dirIni << endl;
237  vector<DTSegmentCand::AssPoint> result;
238 
239  // counter to early-avoid double counting in hits pattern
241  int nCompatibleHits=0;
242 
243  typedef vector<std::shared_ptr<DTHitPairForFit>> hitCont;
244  typedef hitCont::const_iterator hitIter;
245  for (hitIter hit=hits.begin(); hit!=hits.end(); ++hit) {
246  pair<bool,bool> isCompatible = (*hit)->isCompatible(posIni, dirIni);
247  if (debug)
248  cout << "isCompatible " << isCompatible.first << " " <<
249  isCompatible.second << endl;
250 
251  // if only one of the two is compatible, then the LR is assigned,
252  // otherwise is undefined
253 
254  DTEnums::DTCellSide lrcode;
255  if (isCompatible.first && isCompatible.second) {
256  usePairs ? lrcode=DTEnums::undefLR : lrcode=DTEnums::Left ; // if not usePairs then only use single side
257  tried.push_back(3);
258  nCompatibleHits++;
259  }
260  else if (isCompatible.first) {
261  lrcode=DTEnums::Left;
262  tried.push_back(2);
263  nCompatibleHits++;
264  }
265  else if (isCompatible.second) {
266  lrcode=DTEnums::Right;
267  tried.push_back(1);
268  nCompatibleHits++;
269  }
270  else {
271  tried.push_back(0);
272  continue; // neither is compatible
273  }
274  result.push_back(DTSegmentCand::AssPoint(*hit, lrcode));
275  }
276 
277 
278  // check if too few associated hits or pattern already tried
279  // TODO: two different if for nCompatibleHits < 3 =>printout and find ->
280  // printour
281  if (nCompatibleHits < 3) {
282  if (debug) {
283  cout << "Less than 3 hits " ;
284  copy(tried.begin(), tried.end(), ostream_iterator<int>(std::cout));
285  cout << endl;
286  }
287  // No need to insert into the list of patterns, as you will never search for it.
288  //theTriedPattern.insert(tried);
289  } else {
290  // try to insert, return bool if already there
291  bool isnew = theTriedPattern.insert(tried).second;
292  if (isnew) {
293  if (debug) {
294  cout << "NOT Already tried " ;
295  copy(tried.begin(), tried.end(), ostream_iterator<int>(std::cout));
296  cout << endl;
297  }
298  } else {
299  if (debug) {
300  cout << "Already tried " ;
301  copy(tried.begin(), tried.end(), ostream_iterator<int>(std::cout));
302  cout << endl;
303 
304  }
305  // empty the result vector
306  result.clear();
307  }
308  }
309  return result;
310 }
311 
313 DTCombinatorialPatternReco::buildBestSegment(std::vector<DTSegmentCand::AssPoint>& hits,
314  const DTSuperLayer* sl) {
315  if (hits.size()<3) {
316  //cout << "buildBestSegment: hits " << hits.size()<< endl;
317  return nullptr; // a least 3 point
318  }
319 
320  // hits with defined LR
321  vector<DTSegmentCand::AssPoint> points;
322 
323  // without: I store both L and R, a deque since I need front insertion and
324  // deletion
325  deque<std::shared_ptr<DTHitPairForFit> > pointsNoLR;
326 
327  // first add only the hits with LR assigned
328  for (vector<DTSegmentCand::AssPoint>::const_iterator hit=hits.begin();
329  hit!=hits.end(); ++hit) {
330  if ((*hit).second != DTEnums::undefLR) {
331  points.push_back(*hit);
332  } else { // then also for the undef'd one
333  pointsNoLR.push_back((*hit).first);
334  }
335  }
336 
337  if(debug) {
338  cout << "points " << points.size() << endl;
339  cout << "pointsNoLR " << pointsNoLR.size() << endl;
340  }
341 
342  // build all possible candidates using L/R ambiguity
343  vector<DTSegmentCand*> candidates ;
344 
345  buildPointsCollection(points, pointsNoLR, candidates, sl);
346 
347  if(debug)
348  cout << "candidates " << candidates.size() << endl;
349 
350  // so now I have build a given number of segments, I should find the best one,
351  // by #hits and chi2.
352  vector<DTSegmentCand*>::const_iterator bestCandIter = candidates.end();
353  double minChi2=999999.;
354  unsigned int maxNumHits=0;
355  for (vector<DTSegmentCand*>::const_iterator iter=candidates.begin();
356  iter!=candidates.end(); ++iter) {
357  if ((*iter)->nHits()==maxNumHits && (*iter)->chi2()<minChi2) {
358  minChi2=(*iter)->chi2();
359  bestCandIter=iter;
360  } else if ((*iter)->nHits()>maxNumHits) {
361  maxNumHits=(*iter)->nHits();
362  minChi2=(*iter)->chi2();
363  bestCandIter=iter;
364  }
365  }
366 
367  // delete all candidates but the best one!
368  for (vector<DTSegmentCand*>::iterator iter=candidates.begin();
369  iter!=candidates.end(); ++iter) if (iter!=bestCandIter) delete *iter;
370 
371  // return the best candate if any
372  if (bestCandIter != candidates.end()) {
373  return (*bestCandIter);
374  }
375  return nullptr;
376 }
377 
378 void
380  deque<std::shared_ptr<DTHitPairForFit>>& pointsNoLR,
381  vector<DTSegmentCand*>& candidates,
382  const DTSuperLayer* sl) {
383 
384  if(debug) {
385  cout << "buildPointsCollection " << endl;
386  cout << "points: " << points.size() << " NOLR: " << pointsNoLR.size()<< endl;
387  }
388  if (!pointsNoLR.empty()) { // still unassociated points!
389  std::shared_ptr<DTHitPairForFit> unassHit = pointsNoLR.front();
390  // try with the right
391  if(debug)
392  cout << "Right hit" << endl;
393  points.push_back(DTSegmentCand::AssPoint(unassHit, DTEnums::Right));
394  pointsNoLR.pop_front();
395  buildPointsCollection(points, pointsNoLR, candidates, sl);
396  pointsNoLR.push_front((unassHit));
397  points.pop_back();
398 
399  // try with the left
400  if(debug)
401  cout << "Left hit" << endl;
402  points.push_back(DTSegmentCand::AssPoint(unassHit, DTEnums::Left));
403  pointsNoLR.pop_front();
404  buildPointsCollection(points, pointsNoLR, candidates, sl);
405  pointsNoLR.push_front((unassHit));
406  points.pop_back();
407  } else { // all associated
408 
409  if(debug) {
410  cout << "The Hits were" << endl;
411  copy(points.begin(), points.end(),
412  ostream_iterator<DTSegmentCand::AssPoint>(std::cout));
413  cout << "----" << endl;
414  cout << "All associated " << endl;
415  }
416  DTSegmentCand::AssPointCont pointsSet;
417 
418  // for (vector<DTSegmentCand::AssPoint>::const_iterator point=points.begin();
419  // point!=points.end(); ++point)
420  pointsSet.insert(points.begin(),points.end());
421 
422  if(debug) {
423  cout << "The Hits are" << endl;
424  copy(pointsSet.begin(), pointsSet.end(),
425  ostream_iterator<DTSegmentCand::AssPoint>(std::cout));
426  cout << "----" << endl;
427  }
428 
429  DTSegmentCand* newCand = new DTSegmentCand(pointsSet,sl);
430  if (theUpdator->fit(newCand,false,false)) candidates.push_back(newCand);
431  else delete newCand; // bad seg, too few hits
432  }
433 }
434 
435 bool
437  DTSegmentCand* seg) {
438  for (vector<DTSegmentCand*>::iterator cand=cands.begin();
439  cand!=cands.end(); ++cand)
440  if (*(*cand)==*seg) return false;
441  return true;
442 }
void buildPointsCollection(std::vector< DTSegmentCand::AssPoint > &points, std::deque< std::shared_ptr< DTHitPairForFit > > &pointsNoLR, std::vector< DTSegmentCand * > &candidates, const DTSuperLayer *sl)
std::pair< std::shared_ptr< DTHitPairForFit >, DTEnums::DTCellSide > AssPoint
Definition: DTSegmentCand.h:38
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
~DTCombinatorialPatternReco() override
Destructor.
reference back()
Definition: OwnVector.h:395
std::vector< std::shared_ptr< DTHitPairForFit > > initHits(const DTSuperLayer *sl, const std::vector< DTRecHit1DPair > &hits)
def copy(args, dbName)
edm::OwnVector< DTSLRecSegment2D > reconstruct(const DTSuperLayer *sl, const std::vector< DTRecHit1DPair > &hits) override
this function is called in the producer
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
DTCellSide
Which side of the DT cell.
Definition: DTEnums.h:15
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:1
std::vector< DTSegmentCand * > clean(const std::vector< DTSegmentCand * > &inputCands) const
do the cleaning
virtual bool good() const
std::vector< std::shared_ptr< DTHitPairForFit > > hitCont
bool checkDoubleCandidates(std::vector< DTSegmentCand * > &segs, DTSegmentCand *seg)
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
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
edm::ESHandle< DTGeometry > theDTGeometry
void push_back(short unsigned int i)
push back value, and update the hash
DTCombinatorialPatternReco(const edm::ParameterSet &pset)
Constructor.
std::set< AssPoint, AssPointLessZ > AssPointCont
Definition: DTSegmentCand.h:40
std::vector< DTSegmentCand * > buildSegments(const DTSuperLayer *sl, const std::vector< std::shared_ptr< DTHitPairForFit >> &hits)
hitCont::const_iterator hitIter
const T & get() const
Definition: EventSetup.h:59
DTSegmentCand * buildBestSegment(std::vector< DTSegmentCand::AssPoint > &assHits, const DTSuperLayer *sl)
std::vector< DTSegmentCand::AssPoint > findCompatibleHits(const LocalPoint &pos, const LocalVector &dir, const std::vector< std::shared_ptr< DTHitPairForFit >> &hits)
void update(DTRecSegment4D *seg, const bool calcT0, bool allow3par) const
recompute hits position and refit the segment4D
void setES(const edm::EventSetup &setup) override
bool fit(DTSegmentCand *seg, bool allow3par, const bool fitdebug) const