#include <RecoLocalMuon/CSCSegment/src/CSCSegAlgoHitPruning.h>
Public Types | |
typedef std::vector< const CSCRecHit2D * > | ChamberHitContainer |
Public Member Functions | |
CSCSegAlgoHitPruning (const edm::ParameterSet &ps) | |
constructor | |
std::vector< CSCSegment > | pruneBadHits (const CSCChamber *aChamber, std::vector< CSCSegment > segments) |
clusterize | |
~CSCSegAlgoHitPruning () | |
destructor | |
Private Member Functions | |
AlgebraicSymMatrix | calculateError (void) const |
HepMatrix | derivativeMatrix (void) const |
void | fillChiSquared (void) |
void | fillLocalDirection (void) |
void | fitSlopes (void) |
void | flipErrors (AlgebraicSymMatrix &) const |
AlgebraicSymMatrix | weightMatrix (void) const |
Private Attributes | |
bool | BrutePruning |
double | protoChi2 |
LocalVector | protoDirection |
LocalPoint | protoIntercept |
ChamberHitContainer | protoSegment |
float | protoSlope_u |
float | protoSlope_v |
const CSCChamber * | theChamber |
Definition at line 23 of file CSCSegAlgoHitPruning.h.
typedef std::vector<const CSCRecHit2D*> CSCSegAlgoHitPruning::ChamberHitContainer |
Definition at line 27 of file CSCSegAlgoHitPruning.h.
CSCSegAlgoHitPruning::CSCSegAlgoHitPruning | ( | const edm::ParameterSet & | ps | ) | [explicit] |
constructor
Definition at line 32 of file CSCSegAlgoHitPruning.cc.
References BrutePruning, and edm::ParameterSet::getUntrackedParameter().
00032 { 00033 BrutePruning = ps.getUntrackedParameter<bool>("BrutePruning"); 00034 00035 }
CSCSegAlgoHitPruning::~CSCSegAlgoHitPruning | ( | ) |
AlgebraicSymMatrix CSCSegAlgoHitPruning::calculateError | ( | void | ) | const [private] |
Definition at line 421 of file CSCSegAlgoHitPruning.cc.
References funct::A, derivativeMatrix(), HLT_VtxMuL3::result, weightMatrix(), and weights.
Referenced by pruneBadHits().
00421 { 00422 00423 AlgebraicSymMatrix weights = weightMatrix(); 00424 AlgebraicMatrix A = derivativeMatrix(); 00425 00426 // (AT W A)^-1 00427 // from https://www.phys.ufl.edu/~avery/fitting.html, part I 00428 int ierr; 00429 AlgebraicSymMatrix result = weights.similarityT(A); 00430 result.invert(ierr); 00431 00432 // blithely assuming the inverting never fails... 00433 return result; 00434 }
HepMatrix CSCSegAlgoHitPruning::derivativeMatrix | ( | void | ) | const [private] |
Definition at line 393 of file CSCSegAlgoHitPruning.cc.
References CSCRecHit2D::cscDetId(), it, CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), lp, matrix, protoSegment, row, theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), PV3DBase< T, PVType, FrameType >::z(), and z.
Referenced by calculateError().
00393 { 00394 00395 ChamberHitContainer::const_iterator it; 00396 int nhits = protoSegment.size(); 00397 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 }
Definition at line 298 of file CSCSegAlgoHitPruning.cc.
References CSCRecHit2D::cscDetId(), CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), CSCRecHit2D::localPositionError(), LogDebug, lp, protoChi2, protoIntercept, protoSegment, protoSlope_u, protoSlope_v, theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), v, PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), LocalError::xy(), PV3DBase< T, PVType, FrameType >::y(), LocalError::yy(), PV3DBase< T, PVType, FrameType >::z(), and z.
Referenced by pruneBadHits().
00298 { 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 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 // Invert covariance matrix 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 // std::cout << "CSCSegment::fillChiSquared: failed to invert covariance matrix=\n" << IC << "\n"; 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 }
Definition at line 342 of file CSCSegAlgoHitPruning.cc.
References protoDirection, protoIntercept, protoSlope_u, protoSlope_v, funct::sqrt(), theChamber, GeomDet::toGlobal(), and z.
Referenced by pruneBadHits().
00342 { 00343 // Always enforce direction of segment to point from IP outwards 00344 // (Incorrect for particles not coming from IP, of course.) 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 // localDir may need sign flip to ensure it points outward from IP 00354 // ptc: Examine its direction and origin in global z: to point outward 00355 // the localDir should always have same sign as global z... 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 }
Definition at line 232 of file CSCSegAlgoHitPruning.cc.
References CSCRecHit2D::cscDetId(), CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), CSCRecHit2D::localPositionError(), LogDebug, lp, p, protoIntercept, protoSegment, protoSlope_u, protoSlope_v, solve(), theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), v, PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), LocalError::xy(), PV3DBase< T, PVType, FrameType >::y(), LocalError::yy(), PV3DBase< T, PVType, FrameType >::z(), and z.
Referenced by pruneBadHits().
00232 { 00233 HepMatrix M(4,4,0); 00234 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 // ptc: Local position of hit w.r.t. chamber 00242 double u = lp.x(); 00243 double v = lp.y(); 00244 double z = lp.z(); 00245 // ptc: Covariance matrix of local errors 00246 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); // since Cov is symmetric 00251 // ptc: Invert covariance matrix (and trap if it fails!) 00252 int ierr = 0; 00253 IC.invert(ierr); // inverts in place 00254 if (ierr != 0) { 00255 LogDebug("CSC") << "CSCSegment::fitSlopes: failed to invert covariance matrix=\n" << IC << "\n"; 00256 // std::cout<< "CSCSegment::fitSlopes: failed to invert covariance matrix=\n" << IC << "\n"<<std::endl; 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 HepVector p = solve(M, B); 00284 00285 // Update member variables 00286 // Note that origin has local z = 0 00287 protoIntercept = LocalPoint(p(1), p(2), 0.); 00288 protoSlope_u = p(3); 00289 protoSlope_v = p(4); 00290 }
void CSCSegAlgoHitPruning::flipErrors | ( | AlgebraicSymMatrix & | a | ) | const [private] |
Definition at line 437 of file CSCSegAlgoHitPruning.cc.
References a.
Referenced by pruneBadHits().
00437 { 00438 00439 // The CSCSegment needs the error matrix re-arranged 00440 00441 AlgebraicSymMatrix hold( a ); 00442 00443 // errors on slopes into upper left 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 // errors on positions into lower right 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 // off-diagonal elements remain unchanged 00456 00457 }
std::vector< CSCSegment > CSCSegAlgoHitPruning::pruneBadHits | ( | const CSCChamber * | aChamber, | |
std::vector< CSCSegment > | segments | |||
) |
clusterize
Definition at line 49 of file CSCSegAlgoHitPruning.cc.
References begin, BrutePruning, calculateError(), CSCSegment::chi2(), ChiSquaredProbability(), e, fillChiSquared(), fillLocalDirection(), fitSlopes(), flipErrors(), it, CSCChamber::layer(), m, CSCSegment::nRecHits(), protoChi2, protoDirection, protoIntercept, protoSegment, radius(), pyDBSRunClass::temp, theChamber, GeomDet::toGlobal(), PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().
00049 { 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 int hit_nr_2ndworst = -1; 00062 00063 for (std::vector<CSCSegment>::iterator it=segments.begin(); it != segments.end(); it++) { 00064 00065 if ( !use_brute_force ) {// find worst hit 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 // find (rough) "residuals" (NOT excluding the hit from the fit - speed!) of hits on segment 00081 std::vector<CSCRecHit2D> theseRecHits = (*it).specificRecHits(); 00082 std::vector<CSCRecHit2D>::const_iterator iRH_worst; 00083 float xdist_local = -99999.; 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 hit_nr_2ndworst = -1; 00092 00093 for ( std::vector<CSCRecHit2D>::const_iterator iRH = theseRecHits.begin(); iRH != theseRecHits.end(); iRH++ ) { 00094 //mark "worst" hit: 00095 00096 float z_at_target ; 00097 float radius ; 00098 float loc_x_at_target ; 00099 float loc_y_at_target ; 00100 float loc_z_at_target ; 00101 00102 z_at_target = 0.; 00103 loc_x_at_target = 0.; 00104 loc_y_at_target = 0.; 00105 loc_z_at_target = 0.; 00106 radius = 0.; 00107 00108 // set the z target in CMS global coordinates: 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(); // target z position in cm (z pos of the hit) 00117 00118 loc_x_at_target = localPos.x() + (segDir.x()*( target_z - globZ )); 00119 loc_y_at_target = localPos.y() + (segDir.y()*( target_z - globZ )); 00120 loc_z_at_target = target_z; 00121 00122 // have to transform the segments coordinates back to the local frame... how?!!!!!!!!!!!! 00123 00124 xdist_local = fabs(localPositionRH.x() - loc_x_at_target); 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 hit_nr_2ndworst = hit_nr_worst; 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 hit_nr_2ndworst = hit_nr; 00137 } 00138 ++hit_nr; 00139 } 00140 00141 // reset worst hit number if certain criteria apply. 00142 // Criteria: 2nd worst hit must be at least a factor of 00143 // 1.5 better than the worst in terms of sigma: 00144 if ( xdist_local_worst_sig / xdist_local_2ndworst_sig < 1.5 ) { 00145 hit_nr_worst = -1; 00146 hit_nr_2ndworst = -1; 00147 } 00148 } 00149 } 00150 00151 // if worst hit was found, refit without worst hit and select if considerably better than original fit. 00152 // Can also use brute force: refit all n-1 hit segments and choose one over the n hit if considerably "better" 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 // usefor chi2 1 diff float best_red_seg_prob = 99999.; 00159 buffer.clear(); 00160 if( ChiSquaredProbability((double)(*it).chi2(),(double)((2*(*it).nRecHits())-4)) < chi2ndfProbMin ) { 00161 00162 buffer = theseRecHits; 00163 00164 // Dirty switch: here one can select to refit all possible subsets or just the one without the 00165 // tagged worst hit: 00166 if( use_brute_force ) { // Brute force method: loop over all possible segments: 00167 for(uint 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 { // More elegant but still biased: erase only worst hit 00173 // Comment: There is not a very strong correlation of the worst hit with the one that one should remove... 00174 if( hit_nr_worst >= 0 && hit_nr_worst <= int(buffer.size()) ) { 00175 // fill segment in buffer, delete worst hit 00176 buffer.erase(buffer.begin()+(hit_nr_worst),buffer.begin()+(hit_nr_worst+1)); 00177 reduced_segments.push_back(buffer); 00178 } 00179 else { 00180 // only fill segment in array, do not delete anything 00181 reduced_segments.push_back(buffer); 00182 } 00183 } 00184 } 00185 00186 // Loop over the subsegments and fit (only one segment if "use_brute_force" is false): 00187 for (uint iSegment=0; iSegment<reduced_segments.size(); iSegment++ ) { 00188 // loop over hits on given segment and push pointers to hits into protosegment 00189 protoSegment.clear(); 00190 for (uint m = 0; m<reduced_segments[iSegment].size(); ++m ) { 00191 protoSegment.push_back(&reduced_segments[iSegment][m]); 00192 } 00193 fitSlopes(); 00194 fillChiSquared(); 00195 fillLocalDirection(); 00196 // calculate error matrix 00197 AlgebraicSymMatrix protoErrors = calculateError(); 00198 // but reorder components to match what's required by TrackingRecHit interface 00199 // i.e. slopes first, then positions 00200 flipErrors( protoErrors ); 00201 // 00202 CSCSegment temp(protoSegment, protoIntercept, protoDirection, protoErrors, protoChi2); 00203 00204 // replace n hit segment with n-1 hit segment, if segment probability is 1e3 better: 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 // exchange current n hit segment (*it) with better n-1 hit segment: 00217 (*it) = temp; 00218 } 00219 } 00220 } 00221 00222 return segments; 00223 00224 }
AlgebraicSymMatrix CSCSegAlgoHitPruning::weightMatrix | ( | void | ) | const [private] |
Definition at line 367 of file CSCSegAlgoHitPruning.cc.
References it, CSCRecHit2D::localPositionError(), matrix, protoSegment, row, LocalError::xx(), LocalError::xy(), and LocalError::yy().
Referenced by calculateError().
00367 { 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 }
bool CSCSegAlgoHitPruning::BrutePruning [private] |
Definition at line 56 of file CSCSegAlgoHitPruning.h.
Referenced by CSCSegAlgoHitPruning(), and pruneBadHits().
double CSCSegAlgoHitPruning::protoChi2 [private] |
Definition at line 53 of file CSCSegAlgoHitPruning.h.
Referenced by fillChiSquared(), and pruneBadHits().
Definition at line 54 of file CSCSegAlgoHitPruning.h.
Referenced by fillLocalDirection(), and pruneBadHits().
Definition at line 52 of file CSCSegAlgoHitPruning.h.
Referenced by fillChiSquared(), fillLocalDirection(), fitSlopes(), and pruneBadHits().
Definition at line 49 of file CSCSegAlgoHitPruning.h.
Referenced by derivativeMatrix(), fillChiSquared(), fitSlopes(), pruneBadHits(), and weightMatrix().
float CSCSegAlgoHitPruning::protoSlope_u [private] |
Definition at line 50 of file CSCSegAlgoHitPruning.h.
Referenced by fillChiSquared(), fillLocalDirection(), and fitSlopes().
float CSCSegAlgoHitPruning::protoSlope_v [private] |
Definition at line 51 of file CSCSegAlgoHitPruning.h.
Referenced by fillChiSquared(), fillLocalDirection(), and fitSlopes().
const CSCChamber* CSCSegAlgoHitPruning::theChamber [private] |
Definition at line 47 of file CSCSegAlgoHitPruning.h.
Referenced by derivativeMatrix(), fillChiSquared(), fillLocalDirection(), fitSlopes(), and pruneBadHits().