CMS 3D CMS Logo

CSCSegAlgoHitPruning Class Reference

#include <RecoLocalMuon/CSCSegment/src/CSCSegAlgoHitPruning.h>

List of all members.

Public Types

typedef std::vector< const
CSCRecHit2D * > 
ChamberHitContainer

Public Member Functions

 CSCSegAlgoHitPruning (const edm::ParameterSet &ps)
 constructor
std::vector< CSCSegmentpruneBadHits (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 CSCChambertheChamber


Detailed Description

Definition at line 23 of file CSCSegAlgoHitPruning.h.


Member Typedef Documentation

typedef std::vector<const CSCRecHit2D*> CSCSegAlgoHitPruning::ChamberHitContainer

Definition at line 27 of file CSCSegAlgoHitPruning.h.


Constructor & Destructor Documentation

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 (  ) 

destructor

Definition at line 41 of file CSCSegAlgoHitPruning.cc.

00041                                            {
00042 
00043 }


Member Function Documentation

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 }

void CSCSegAlgoHitPruning::fillChiSquared ( void   )  [private]

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 }

void CSCSegAlgoHitPruning::fillLocalDirection ( void   )  [private]

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 }

void CSCSegAlgoHitPruning::fitSlopes ( void   )  [private]

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 }


Member Data Documentation

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().

LocalVector CSCSegAlgoHitPruning::protoDirection [private]

Definition at line 54 of file CSCSegAlgoHitPruning.h.

Referenced by fillLocalDirection(), and pruneBadHits().

LocalPoint CSCSegAlgoHitPruning::protoIntercept [private]

Definition at line 52 of file CSCSegAlgoHitPruning.h.

Referenced by fillChiSquared(), fillLocalDirection(), fitSlopes(), and pruneBadHits().

ChamberHitContainer CSCSegAlgoHitPruning::protoSegment [private]

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().


The documentation for this class was generated from the following files:
Generated on Tue Jun 9 18:17:25 2009 for CMSSW by  doxygen 1.5.4