00001
00012 #include "RecoLocalMuon/CSCSegment/src/CSCSegAlgoHitPruning.h"
00013
00014 #include "Geometry/CSCGeometry/interface/CSCLayer.h"
00015 #include <DataFormats/CSCRecHit/interface/CSCRecHit2D.h>
00016 #include <DataFormats/CSCRecHit/interface/CSCSegment.h>
00017 #include <Geometry/CSCGeometry/interface/CSCChamber.h>
00018 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00019
00020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022
00023 #include <algorithm>
00024 #include <cmath>
00025 #include <iostream>
00026 #include <string>
00027
00028
00029
00030
00031
00032 CSCSegAlgoHitPruning::CSCSegAlgoHitPruning(const edm::ParameterSet& ps) {
00033 BrutePruning = ps.getParameter<bool>("BrutePruning");
00034
00035 }
00036
00037
00038
00039
00040
00041 CSCSegAlgoHitPruning::~CSCSegAlgoHitPruning(){
00042
00043 }
00044
00045
00046
00047
00048
00049 std::vector<CSCSegment> CSCSegAlgoHitPruning::pruneBadHits(const CSCChamber* aChamber, std::vector<CSCSegment> segments) {
00050
00051 theChamber = aChamber;
00052
00053 std::vector<CSCSegment> segments_temp;
00054 std::vector<ChamberHitContainer> rechits_clusters;
00055
00056 const float chi2ndfProbMin = 1.0e-4;
00057 bool use_brute_force = BrutePruning;
00058
00059 int hit_nr = 0;
00060 int hit_nr_worst = -1;
00061
00062
00063 for (std::vector<CSCSegment>::iterator it=segments.begin(); it != segments.end(); it++) {
00064
00065 if ( !use_brute_force ) {
00066
00067 float chisq = (*it).chi2();
00068 int nhits = (*it).nRecHits();
00069 LocalPoint localPos = (*it).localPosition();
00070 LocalVector segDir = (*it).localDirection();
00071 const CSCChamber* cscchamber = theChamber;
00072 float globZ ;
00073
00074 GlobalPoint globalPosition = cscchamber->toGlobal(localPos);
00075 globZ = globalPosition.z();
00076
00077
00078 if ( ChiSquaredProbability((double)chisq,(double)(2*nhits-4)) < chi2ndfProbMin ) {
00079
00080
00081 std::vector<CSCRecHit2D> theseRecHits = (*it).specificRecHits();
00082 std::vector<CSCRecHit2D>::const_iterator iRH_worst;
00083
00084
00085 float xdist_local_worst_sig = -99999.;
00086 float xdist_local_2ndworst_sig = -99999.;
00087 float xdist_local_sig = -99999.;
00088
00089 hit_nr = 0;
00090 hit_nr_worst = -1;
00091
00092
00093 for ( std::vector<CSCRecHit2D>::const_iterator iRH = theseRecHits.begin(); iRH != theseRecHits.end(); iRH++ ) {
00094
00095
00096
00097
00098 float loc_x_at_target ;
00099
00100
00101
00102
00103 loc_x_at_target = 0.;
00104
00105
00106
00107
00108
00109 const CSCLayer* csclayerRH = theChamber->layer((*iRH).cscDetId().layer());
00110 LocalPoint localPositionRH = (*iRH).localPosition();
00111 GlobalPoint globalPositionRH = csclayerRH->toGlobal(localPositionRH);
00112
00113 LocalError rerrlocal = (*iRH).localPositionError();
00114 float xxerr = rerrlocal.xx();
00115
00116 float target_z = globalPositionRH.z();
00117
00118 loc_x_at_target = localPos.x() + (segDir.x()*( target_z - globZ ));
00119
00120
00121
00122
00123
00124
00125 xdist_local_sig = fabs((localPositionRH.x() -loc_x_at_target)/(xxerr));
00126
00127 if( xdist_local_sig > xdist_local_worst_sig ) {
00128 xdist_local_2ndworst_sig = xdist_local_worst_sig;
00129 xdist_local_worst_sig = xdist_local_sig;
00130 iRH_worst = iRH;
00131
00132 hit_nr_worst = hit_nr;
00133 }
00134 else if(xdist_local_sig > xdist_local_2ndworst_sig) {
00135 xdist_local_2ndworst_sig = xdist_local_sig;
00136
00137 }
00138 ++hit_nr;
00139 }
00140
00141
00142
00143
00144 if ( xdist_local_worst_sig / xdist_local_2ndworst_sig < 1.5 ) {
00145 hit_nr_worst = -1;
00146
00147 }
00148 }
00149 }
00150
00151
00152
00153
00154 std::vector< CSCRecHit2D > buffer;
00155 std::vector< std::vector< CSCRecHit2D > > reduced_segments;
00156 std::vector< CSCRecHit2D > theseRecHits = (*it).specificRecHits();
00157 float best_red_seg_prob = 0.0;
00158
00159 buffer.clear();
00160 if( ChiSquaredProbability((double)(*it).chi2(),(double)((2*(*it).nRecHits())-4)) < chi2ndfProbMin ) {
00161
00162 buffer = theseRecHits;
00163
00164
00165
00166 if( use_brute_force ) {
00167 for(size_t bi = 0; bi < buffer.size(); bi++) {
00168 reduced_segments.push_back(buffer);
00169 reduced_segments[bi].erase(reduced_segments[bi].begin()+(bi),reduced_segments[bi].begin()+(bi+1));
00170 }
00171 }
00172 else {
00173
00174 if( hit_nr_worst >= 0 && hit_nr_worst <= int(buffer.size()) ) {
00175
00176 buffer.erase(buffer.begin()+(hit_nr_worst),buffer.begin()+(hit_nr_worst+1));
00177 reduced_segments.push_back(buffer);
00178 }
00179 else {
00180
00181 reduced_segments.push_back(buffer);
00182 }
00183 }
00184 }
00185
00186
00187 for (size_t iSegment=0; iSegment<reduced_segments.size(); iSegment++ ) {
00188
00189 protoSegment.clear();
00190 for (size_t m = 0; m<reduced_segments[iSegment].size(); ++m ) {
00191 protoSegment.push_back(&reduced_segments[iSegment][m]);
00192 }
00193 fitSlopes();
00194 fillChiSquared();
00195 fillLocalDirection();
00196
00197 AlgebraicSymMatrix protoErrors = calculateError();
00198
00199
00200 flipErrors( protoErrors );
00201
00202 CSCSegment temp(protoSegment, protoIntercept, protoDirection, protoErrors, protoChi2);
00203
00204
00205 if( ( ChiSquaredProbability((double)(*it).chi2(),(double)((2*(*it).nRecHits())-4))
00206 <
00207 (1.e-3)*(ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4))) )
00208 &&
00209 ( (ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4)))
00210 > best_red_seg_prob
00211 )
00212 &&
00213 ( (ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4))) > 1e-10 )
00214 ) {
00215 best_red_seg_prob = ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4));
00216
00217 (*it) = temp;
00218 }
00219 }
00220 }
00221
00222 return segments;
00223
00224 }
00225
00226
00227
00228
00229
00230
00231
00232 void CSCSegAlgoHitPruning::fitSlopes() {
00233 CLHEP::HepMatrix M(4,4,0);
00234 CLHEP::HepVector B(4,0);
00235 ChamberHitContainer::const_iterator ih = protoSegment.begin();
00236 for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
00237 const CSCRecHit2D& hit = (**ih);
00238 const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
00239 GlobalPoint gp = layer->toGlobal(hit.localPosition());
00240 LocalPoint lp = theChamber->toLocal(gp);
00241
00242 double u = lp.x();
00243 double v = lp.y();
00244 double z = lp.z();
00245
00246 CLHEP::HepMatrix IC(2,2);
00247 IC(1,1) = hit.localPositionError().xx();
00248 IC(1,2) = hit.localPositionError().xy();
00249 IC(2,2) = hit.localPositionError().yy();
00250 IC(2,1) = IC(1,2);
00251
00252 int ierr = 0;
00253 IC.invert(ierr);
00254 if (ierr != 0) {
00255 LogDebug("CSC") << "CSCSegment::fitSlopes: failed to invert covariance matrix=\n" << IC << "\n";
00256
00257 }
00258
00259 M(1,1) += IC(1,1);
00260 M(1,2) += IC(1,2);
00261 M(1,3) += IC(1,1) * z;
00262 M(1,4) += IC(1,2) * z;
00263 B(1) += u * IC(1,1) + v * IC(1,2);
00264
00265 M(2,1) += IC(2,1);
00266 M(2,2) += IC(2,2);
00267 M(2,3) += IC(2,1) * z;
00268 M(2,4) += IC(2,2) * z;
00269 B(2) += u * IC(2,1) + v * IC(2,2);
00270
00271 M(3,1) += IC(1,1) * z;
00272 M(3,2) += IC(1,2) * z;
00273 M(3,3) += IC(1,1) * z * z;
00274 M(3,4) += IC(1,2) * z * z;
00275 B(3) += ( u * IC(1,1) + v * IC(1,2) ) * z;
00276
00277 M(4,1) += IC(2,1) * z;
00278 M(4,2) += IC(2,2) * z;
00279 M(4,3) += IC(2,1) * z * z;
00280 M(4,4) += IC(2,2) * z * z;
00281 B(4) += ( u * IC(2,1) + v * IC(2,2) ) * z;
00282 }
00283 CLHEP::HepVector p = solve(M, B);
00284
00285
00286
00287 protoIntercept = LocalPoint(p(1), p(2), 0.);
00288 protoSlope_u = p(3);
00289 protoSlope_v = p(4);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 void CSCSegAlgoHitPruning::fillChiSquared() {
00299
00300 double chsq = 0.;
00301
00302 ChamberHitContainer::const_iterator ih;
00303 for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
00304
00305 const CSCRecHit2D& hit = (**ih);
00306 const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
00307 GlobalPoint gp = layer->toGlobal(hit.localPosition());
00308 LocalPoint lp = theChamber->toLocal(gp);
00309
00310 double u = lp.x();
00311 double v = lp.y();
00312 double z = lp.z();
00313
00314 double du = protoIntercept.x() + protoSlope_u * z - u;
00315 double dv = protoIntercept.y() + protoSlope_v * z - v;
00316
00317 CLHEP::HepMatrix IC(2,2);
00318 IC(1,1) = hit.localPositionError().xx();
00319 IC(1,2) = hit.localPositionError().xy();
00320 IC(2,2) = hit.localPositionError().yy();
00321 IC(2,1) = IC(1,2);
00322
00323
00324 int ierr = 0;
00325 IC.invert(ierr);
00326 if (ierr != 0) {
00327 LogDebug("CSC") << "CSCSegment::fillChiSquared: failed to invert covariance matrix=\n" << IC << "\n";
00328
00329
00330 }
00331
00332 chsq += du*du*IC(1,1) + 2.*du*dv*IC(1,2) + dv*dv*IC(2,2);
00333 }
00334
00335 protoChi2 = chsq;
00336 }
00337
00338
00339
00340
00341
00342 void CSCSegAlgoHitPruning::fillLocalDirection() {
00343
00344
00345
00346 double dxdz = protoSlope_u;
00347 double dydz = protoSlope_v;
00348 double dz = 1./sqrt(1. + dxdz*dxdz + dydz*dydz);
00349 double dx = dz*dxdz;
00350 double dy = dz*dydz;
00351 LocalVector localDir(dx,dy,dz);
00352
00353
00354
00355
00356
00357 double globalZpos = ( theChamber->toGlobal( protoIntercept ) ).z();
00358 double globalZdir = ( theChamber->toGlobal( localDir ) ).z();
00359 double directionSign = globalZpos * globalZdir;
00360 protoDirection = (directionSign * localDir).unit();
00361 }
00362
00363
00364
00365
00366
00367 AlgebraicSymMatrix CSCSegAlgoHitPruning::weightMatrix() const {
00368
00369 std::vector<const CSCRecHit2D*>::const_iterator it;
00370 int nhits = protoSegment.size();
00371 AlgebraicSymMatrix matrix(2*nhits, 0);
00372 int row = 0;
00373
00374 for (it = protoSegment.begin(); it != protoSegment.end(); ++it) {
00375
00376 const CSCRecHit2D& hit = (**it);
00377 ++row;
00378 matrix(row, row) = hit.localPositionError().xx();
00379 matrix(row, row+1) = hit.localPositionError().xy();
00380 ++row;
00381 matrix(row, row-1) = hit.localPositionError().xy();
00382 matrix(row, row) = hit.localPositionError().yy();
00383 }
00384 int ierr;
00385 matrix.invert(ierr);
00386 return matrix;
00387 }
00388
00389
00390
00391
00392
00393 CLHEP::HepMatrix CSCSegAlgoHitPruning::derivativeMatrix() const {
00394
00395 ChamberHitContainer::const_iterator it;
00396 int nhits = protoSegment.size();
00397 CLHEP::HepMatrix matrix(2*nhits, 4);
00398 int row = 0;
00399
00400 for(it = protoSegment.begin(); it != protoSegment.end(); ++it) {
00401
00402 const CSCRecHit2D& hit = (**it);
00403 const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
00404 GlobalPoint gp = layer->toGlobal(hit.localPosition());
00405 LocalPoint lp = theChamber->toLocal(gp);
00406 float z = lp.z();
00407 ++row;
00408 matrix(row, 1) = 1.;
00409 matrix(row, 3) = z;
00410 ++row;
00411 matrix(row, 2) = 1.;
00412 matrix(row, 4) = z;
00413 }
00414 return matrix;
00415 }
00416
00417
00418
00419
00420
00421 AlgebraicSymMatrix CSCSegAlgoHitPruning::calculateError() const {
00422
00423 AlgebraicSymMatrix weights = weightMatrix();
00424 AlgebraicMatrix A = derivativeMatrix();
00425
00426
00427
00428 int ierr;
00429 AlgebraicSymMatrix result = weights.similarityT(A);
00430 result.invert(ierr);
00431
00432
00433 return result;
00434 }
00435
00436
00437 void CSCSegAlgoHitPruning::flipErrors( AlgebraicSymMatrix& a ) const {
00438
00439
00440
00441 AlgebraicSymMatrix hold( a );
00442
00443
00444 a(1,1) = hold(3,3);
00445 a(1,2) = hold(3,4);
00446 a(2,1) = hold(4,3);
00447 a(2,2) = hold(4,4);
00448
00449
00450 a(3,3) = hold(1,1);
00451 a(3,4) = hold(1,2);
00452 a(4,3) = hold(2,1);
00453 a(4,4) = hold(2,2);
00454
00455
00456
00457 }
00458