00001
00010
00011 #include "RecoLocalMuon/DTSegment/src/DTMeantimerPatternReco.h"
00012
00013
00014 #include "FWCore/Framework/interface/ESHandle.h"
00015 #include "FWCore/Framework/interface/EventSetup.h"
00016 #include "DataFormats/Common/interface/OwnVector.h"
00017 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00018 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00019 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00020 #include "Geometry/DTGeometry/interface/DTLayer.h"
00021 #include "Geometry/DTGeometry/interface/DTSuperLayer.h"
00022 #include "DataFormats/DTRecHit/interface/DTSLRecSegment2D.h"
00023 #include "RecoLocalMuon/DTSegment/src/DTSegmentUpdator.h"
00024 #include "RecoLocalMuon/DTSegment/src/DTSegmentCleaner.h"
00025 #include "RecoLocalMuon/DTSegment/src/DTHitPairForFit.h"
00026 #include "RecoLocalMuon/DTSegment/src/DTSegmentCand.h"
00027
00028
00029 #include <iterator>
00030 using namespace std;
00031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00032
00033
00034
00035
00037 DTMeantimerPatternReco::DTMeantimerPatternReco(const edm::ParameterSet& pset) :
00038 DTRecSegment2DBaseAlgo(pset), theAlgoName("DTMeantimerPatternReco")
00039 {
00040
00041 theMaxAllowedHits = pset.getParameter<unsigned int>("MaxAllowedHits");
00042 theAlphaMaxTheta = pset.getParameter<double>("AlphaMaxTheta");
00043 theAlphaMaxPhi = pset.getParameter<double>("AlphaMaxPhi");
00044 theMaxT0 = pset.getParameter<double>("MaxT0");
00045 theMinT0 = pset.getParameter<double>("MinT0");
00046 theMaxChi2 = pset.getParameter<double>("MaxChi2");
00047 debug = pset.getUntrackedParameter<bool>("debug");
00048 theUpdator = new DTSegmentUpdator(pset);
00049 theCleaner = new DTSegmentCleaner(pset);
00050 }
00051
00053 DTMeantimerPatternReco::~DTMeantimerPatternReco() {
00054 delete theUpdator;
00055 delete theCleaner;
00056 }
00057
00058
00059 edm::OwnVector<DTSLRecSegment2D>
00060 DTMeantimerPatternReco::reconstruct(const DTSuperLayer* sl,
00061 const std::vector<DTRecHit1DPair>& pairs){
00062
00063 edm::OwnVector<DTSLRecSegment2D> result;
00064 vector<DTHitPairForFit*> hitsForFit = initHits(sl, pairs);
00065
00066 vector<DTSegmentCand*> candidates = buildSegments(sl, hitsForFit);
00067
00068 vector<DTSegmentCand*>::const_iterator cand=candidates.begin();
00069 while (cand<candidates.end()) {
00070
00071 DTSLRecSegment2D *segment = (**cand);
00072
00073 theUpdator->update(segment);
00074
00075 if (debug)
00076 cout<<"Reconstructed 2D segments "<<*segment<<endl;
00077 result.push_back(segment);
00078
00079 delete *(cand++);
00080 }
00081
00082 return result;
00083 }
00084
00085 void DTMeantimerPatternReco::setES(const edm::EventSetup& setup){
00086
00087 setup.get<MuonGeometryRecord>().get(theDTGeometry);
00088 theUpdator->setES(setup);
00089 }
00090
00091 vector<DTHitPairForFit*>
00092 DTMeantimerPatternReco::initHits(const DTSuperLayer* sl,
00093 const std::vector<DTRecHit1DPair>& hits){
00094
00095 vector<DTHitPairForFit*> result;
00096 for (vector<DTRecHit1DPair>::const_iterator hit=hits.begin();
00097 hit!=hits.end(); ++hit) {
00098 result.push_back(new DTHitPairForFit(*hit, *sl, theDTGeometry));
00099 }
00100 return result;
00101 }
00102
00103 vector<DTSegmentCand*>
00104 DTMeantimerPatternReco::buildSegments(const DTSuperLayer* sl,
00105 const std::vector<DTHitPairForFit*>& hits){
00106
00107 typedef vector<DTHitPairForFit*> hitCont;
00108 typedef hitCont::const_iterator hitIter;
00109 vector<DTSegmentCand*> result;
00110 DTEnums::DTCellSide codes[2]={DTEnums::Right, DTEnums::Left};
00111
00112 if(debug) {
00113 cout << "buildSegments: " << sl->id() << " nHits " << hits.size() << endl;
00114 for (hitIter hit=hits.begin(); hit!=hits.end(); ++hit) cout << **hit<< " wire: " << (*hit)->id() << endl;
00115 }
00116
00117
00118
00119
00120 if (hits.size() > theMaxAllowedHits ) {
00121 if(debug) {
00122 cout << "Warning: this SuperLayer " << sl->id() << " has too many hits : "
00123 << hits.size() << " max allowed is " << theMaxAllowedHits << endl;
00124 cout << "Skipping segment reconstruction... " << endl;
00125 }
00126 return result;
00127 }
00128
00129 GlobalPoint IP;
00130 float DAlphaMax;
00131 if ((sl->id()).superlayer()==2)
00132 DAlphaMax=theAlphaMaxTheta;
00133 else
00134 DAlphaMax=theAlphaMaxPhi;
00135
00136 vector<AssPoint> usedHits;
00137
00138
00139
00140 for (hitCont::const_iterator firstHit=hits.begin(); firstHit!=hits.end();
00141 ++firstHit) {
00142 for (hitCont::const_reverse_iterator lastHit=hits.rbegin();
00143 (*lastHit)!=(*firstHit); ++lastHit) {
00144
00145
00146 if (!geometryFilter((*firstHit)->id(),(*lastHit)->id())) continue;
00147
00148
00149 hitCont hitsForFit;
00150 for (hitCont::const_iterator tmpHit=firstHit+1; (*tmpHit)!=(*lastHit); tmpHit++)
00151 if ((geometryFilter((*tmpHit)->id(),(*lastHit)->id()))
00152 && (geometryFilter((*tmpHit)->id(),(*firstHit)->id()))) hitsForFit.push_back(*tmpHit);
00153
00154 for (int firstLR=0; firstLR<2; ++firstLR) {
00155 for (int lastLR=0; lastLR<2; ++lastLR) {
00156
00157
00158
00159 GlobalPoint gposFirst=sl->toGlobal( (*firstHit)->localPosition(codes[firstLR]) );
00160 GlobalPoint gposLast= sl->toGlobal( (*lastHit)->localPosition(codes[lastLR]) );
00161 GlobalVector gvec=gposLast-gposFirst;
00162 GlobalVector gvecIP=gposLast-IP;
00163
00164
00165 float DAlpha=fabs(gvec.theta()-gvecIP.theta());
00166 if (DAlpha>DAlphaMax) continue;
00167
00168 if(debug) {
00169 cout << "Selected hit pair:" << endl;
00170 cout << " First " << *(*firstHit) << " Layer Id: " << (*firstHit)->id().layerId() << " Side: " << firstLR << endl;
00171 cout << " Last " << *(*lastHit) << " Layer Id: " << (*lastHit)->id().layerId() << " Side: " << lastLR << endl;
00172 }
00173
00174 vector<AssPoint> assHits;
00175
00176 assHits.push_back(AssPoint(*firstHit,codes[firstLR]));
00177 assHits.push_back(AssPoint(*lastHit,codes[lastLR]));
00178
00179
00180 maxfound = 3;
00181 addHits(sl,assHits,hitsForFit,result, usedHits);
00182 }
00183 }
00184 }
00185 }
00186
00187
00188 if (debug) {
00189 cout << "Result (before cleaning): " << result.size() << endl;
00190 for (vector<DTSegmentCand*>::const_iterator seg=result.begin(); seg!=result.end(); ++seg)
00191 cout << *(*seg) << endl;
00192 }
00193 result = theCleaner->clean(result);
00194 if (debug) {
00195 cout << "Result (after cleaning): " << result.size() << endl;
00196 for (vector<DTSegmentCand*>::const_iterator seg=result.begin();
00197 seg!=result.end(); ++seg)
00198 cout << *(*seg) << endl;
00199 }
00200
00201 return result;
00202 }
00203
00204
00205
00206 void
00207 DTMeantimerPatternReco::addHits(const DTSuperLayer* sl, vector<AssPoint>& assHits, const vector<DTHitPairForFit*>& hits,
00208 vector<DTSegmentCand*> &result, vector<AssPoint>& usedHits) {
00209
00210 typedef vector<DTHitPairForFit*> hitCont;
00211 double chi2l,chi2r,t0_corrl,t0_corrr;
00212 bool foundSomething = false;
00213
00214
00215
00216
00217
00218 if (assHits.size()+hits.size()<maxfound) return;
00219
00220
00221 for (hitCont::const_iterator hit=hits.begin(); hit!=hits.end(); ++hit) {
00222 if (debug)
00223 cout << " Trying B: " << **hit<< " wire: " << (*hit)->id() << endl;
00224
00225 assHits.push_back(AssPoint(*hit, DTEnums::Left));
00226 bool left_ok=fitWithT0(assHits, chi2l, t0_corrl,0);
00227 assHits.pop_back();
00228
00229 assHits.push_back(AssPoint(*hit, DTEnums::Right));
00230 bool right_ok=fitWithT0(assHits, chi2r, t0_corrr,0);
00231 assHits.pop_back();
00232
00233 if (debug) {
00234 int nHits=assHits.size()+1;
00235 cout << " Left: t0_corr = " << t0_corrl << "ns chi2/nHits = " << chi2l << "/" << nHits << " " << left_ok << endl;
00236 cout << " Right: t0_corr = " << t0_corrr << "ns chi2/nHits = " << chi2r << "/" << nHits << " " << right_ok << endl;
00237 }
00238
00239 if (!left_ok && !right_ok) continue;
00240
00241 foundSomething = true;
00242
00243
00244 hitCont hitsForFit;
00245 for (hitCont::const_iterator tmpHit=hit+1; tmpHit!=hits.end(); tmpHit++)
00246 if (geometryFilter((*tmpHit)->id(),(*hit)->id())) hitsForFit.push_back(*tmpHit);
00247
00248 reverse(hitsForFit.begin(),hitsForFit.end());
00249
00250
00251 if (left_ok && right_ok) {
00252 if (chi2l<chi2r-0.1) right_ok=false; else
00253 if (chi2r<chi2l-0.1) left_ok=false;
00254 }
00255 if (left_ok) {
00256 assHits.push_back(AssPoint(*hit, DTEnums::Left));
00257 addHits(sl,assHits,hitsForFit,result,usedHits);
00258 assHits.pop_back();
00259 }
00260 if (right_ok) {
00261 assHits.push_back(AssPoint(*hit, DTEnums::Right));
00262 addHits(sl,assHits,hitsForFit,result,usedHits);
00263 assHits.pop_back();
00264 }
00265 }
00266
00267 if (foundSomething) return;
00268
00269
00270 if (assHits.size()<maxfound) return;
00271
00272
00273 if (!fitWithT0(assHits, chi2l, t0_corrl,debug)) return;
00274
00275
00276
00277 DTSegmentCand::AssPointCont pointsSet;
00278 pointsSet.insert(assHits.begin(),assHits.end());
00279 DTSegmentCand* seg = new DTSegmentCand(pointsSet,sl);
00280 theUpdator->fit(seg);
00281
00282 if (seg) {
00283 for (vector<AssPoint>::const_iterator hiti = assHits.begin()+1; hiti != assHits.end()-1; hiti++)
00284 usedHits.push_back(*hiti);
00285
00286 if (assHits.size()>maxfound) maxfound = assHits.size();
00287 seg->setChi2(chi2l);
00288 if (debug) cout << "Segment built: " << *seg<< endl;
00289 if (checkDoubleCandidates(result,seg)) {
00290 result.push_back(seg);
00291 if (debug) cout << " Result is now " << result.size() << endl;
00292 } else {
00293 if (debug) cout << " Exists - skipping" << endl;
00294 delete seg;
00295 }
00296 }
00297 }
00298
00299
00300 bool
00301 DTMeantimerPatternReco::geometryFilter( const DTWireId first, const DTWireId second ) const
00302 {
00303
00304
00305 const int layerLowerCut[4]={0,-1,-2,-2};
00306 const int layerUpperCut[4]={0, 2, 2, 3};
00307
00308
00309
00310
00311 if (first.layerId().superlayerId().superLayer()!=second.layerId().superlayerId().superLayer())
00312 return true;
00313
00314 int deltaLayer=abs(first.layerId().layer()-second.layerId().layer());
00315
00316
00317 if (!deltaLayer) return false;
00318
00319
00320 if (deltaLayer>3) {
00321 cout << "*** WARNING! DT Layer numbers differ by more than 3! for hits: " << endl;
00322 cout << " " << first << endl;
00323 cout << " " << second << endl;
00324 return false;
00325 }
00326
00327
00328 int deltaWire=first.wire()-second.wire();
00329 if (second.layerId().layer()%2==0) deltaWire=-deltaWire;
00330 if ((deltaWire<=layerLowerCut[deltaLayer]) || (deltaWire>=layerUpperCut[deltaLayer])) return false;
00331
00332 return true;
00333 }
00334
00335
00336 bool
00337 DTMeantimerPatternReco::fitWithT0(const vector<AssPoint> &assHits, double &chi2, double &t0_corr, const bool fitdebug)
00338 {
00339 typedef vector < pair<double,double> > hitCoord;
00340 double a,b,coordError,x,y;
00341 double sx=0,sy=0,sxy=0,sxx=0,ssx=0,ssy=0,s=0,ss=0;
00342 int leftHits=0,rightHits=0;
00343
00344 if (assHits.size()<3) return false;
00345
00346
00347 coordError=((*(assHits.begin())).first)->localPositionError().xx();
00348
00349 for (vector<AssPoint>::const_iterator assHit=assHits.begin(); assHit!=assHits.end(); ++assHit) {
00350 if (coordError!=((*(assHits.begin())).first)->localPositionError().xx())
00351 cout << " DTMeantimerPatternReco: Warning! Hit errors different within one segment!" << endl;
00352
00353 x=((*assHit).first)->localPosition((*assHit).second).z();
00354 y=((*assHit).first)->localPosition((*assHit).second).x();
00355
00356 sx+=x;
00357 sy+=y;
00358 sxy+=x*y;
00359 sxx+=x*x;
00360 s++;
00361
00362 if ((*assHit).second==DTEnums::Left) {
00363 leftHits++;
00364 ssx+=x;
00365 ssy+=y;
00366 ss++;
00367 } else {
00368 rightHits++;
00369 ssx-=x;
00370 ssy-=y;
00371 ss--;
00372 }
00373 }
00374
00375 if (fitdebug && debug)
00376 cout << " DTMeantimerPatternReco::fitWithT0 Left hits: " << leftHits << " Right hits: " << rightHits << endl;
00377
00378 if (leftHits && rightHits) {
00379
00380 double delta = ss*ss*sxx+s*sx*sx+s*ssx*ssx-s*s*sxx-2*ss*sx*ssx;
00381 t0_corr=0.;
00382
00383 if (delta) {
00384 a=(ssy*s*ssx+sxy*ss*ss+sy*sx*s-sy*ss*ssx-ssy*sx*ss-sxy*s*s)/delta;
00385 b=(ssx*sy*ssx+sxx*ssy*ss+sx*sxy*s-sxx*sy*s-ssx*sxy*ss-sx*ssy*ssx)/delta;
00386 t0_corr=(ssx*s*sxy+sxx*ss*sy+sx*sx*ssy-sxx*s*ssy-sx*ss*sxy-ssx*sx*sy)/delta;
00387 } else return false;
00388 } else {
00389 double d = s*sxx - sx*sx;
00390 b = (sxx*sy- sx*sxy)/ d;
00391 a = (s*sxy - sx*sy) / d;
00392 t0_corr=0;
00393 }
00394
00395
00396
00397 double chi,chi2_not0;
00398 chi2=0;
00399 chi2_not0=0;
00400
00401 for (vector<AssPoint>::const_iterator assHit=assHits.begin(); assHit!=assHits.end(); ++assHit) {
00402 x=((*assHit).first)->localPosition((*assHit).second).z();
00403 y=((*assHit).first)->localPosition((*assHit).second).x();
00404
00405 chi=y-a*x-b;
00406 chi2_not0+=chi*chi/coordError;
00407
00408 if ((*assHit).second==DTEnums::Left) chi-=t0_corr;
00409 else chi+=t0_corr;
00410
00411 chi2+=chi*chi/coordError;
00412 }
00413
00414
00415 if (assHits.size()<4) {
00416 chi2=chi2_not0;
00417 if (chi2/(assHits.size()-2)<theMaxChi2) return true;
00418 else return false;
00419 }
00420
00421 t0_corr/=-0.00543;
00422
00423 if (debug && fitdebug)
00424 {
00425 cout << " t0_corr = " << t0_corr << "ns chi2/nHits = " << chi2 << "/" << assHits.size() << endl;
00426
00427 if (((chi2/(assHits.size()-2)<theMaxChi2) && (t0_corr<theMaxT0) && (t0_corr>theMinT0)) || (assHits.size()==4)) {
00428 cout << " a = " << a << " b = " << b << endl;
00429 for (vector<AssPoint>::const_iterator assHit=assHits.begin(); assHit!=assHits.end(); ++assHit) {
00430 x=((*assHit).first)->localPosition((*assHit).second).z();
00431 y=((*assHit).first)->localPosition((*assHit).second).x();
00432 cout << " z= " << x << " x= " << y;
00433 if ((*assHit).second==DTEnums::Left) cout << " x_corr= " << y+t0_corr*0.00543;
00434 else cout << " x_corr= " << y-t0_corr*0.00543;
00435 cout << " seg= " << a*x+b << endl;
00436 }
00437 }
00438 }
00439
00440 if ((chi2/(assHits.size()-2)<theMaxChi2) && (t0_corr<theMaxT0) && (t0_corr>theMinT0)) return true;
00441 else return false;
00442 }
00443
00444 void
00445 DTMeantimerPatternReco::rawFit(double &a, double &b, const vector< pair<double,double> > &hits) {
00446
00447 double s=0,sx=0,sy=0,x,y;
00448 double sxx=0,sxy=0;
00449
00450 a=b=0;
00451 if (hits.size()==0) return;
00452
00453 if (hits.size()==1) {
00454 b=(*(hits.begin())).second;
00455 } else {
00456 for (unsigned int i = 0; i != hits.size(); i++) {
00457 x=hits[i].first;
00458 y=hits[i].second;
00459 sy += y;
00460 sxy+= x*y;
00461 s += 1.;
00462 sx += x;
00463 sxx += x*x;
00464 }
00465
00466
00467 double d = s*sxx - sx*sx;
00468 b = (sxx*sy- sx*sxy)/ d;
00469 a = (s*sxy - sx*sy) / d;
00470 }
00471 }
00472
00473 bool
00474 DTMeantimerPatternReco::checkDoubleCandidates(vector<DTSegmentCand*>& cands,
00475 DTSegmentCand* seg) {
00476 for (vector<DTSegmentCand*>::iterator cand=cands.begin();
00477 cand!=cands.end(); ++cand) {
00478 if (*(*cand)==*seg) return false;
00479 if (((*cand)->nHits()>=seg->nHits()) && ((*cand)->chi2ndof()<seg->chi2ndof()))
00480 if ((*cand)->nSharedHitPairs(*seg)>int(seg->nHits()-2)) return false;
00481 }
00482 return true;
00483 }