CMS 3D CMS Logo

CSCSegAlgoTC Class Reference

This is an alternative algorithm for building endcap muon track segments out of the rechit's in a CSCChamber. More...

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

Inheritance diagram for CSCSegAlgoTC:

CSCSegmentAlgorithm

List of all members.

Public Types

typedef std::deque< boolBoolContainer
typedef std::vector< const
CSCRecHit2D * > 
ChamberHitContainer
typedef
ChamberHitContainer::const_iterator 
ChamberHitContainerCIt
typedef std::vector< intLayerIndex
 Typedefs.

Public Member Functions

std::vector< CSCSegmentbuildSegments (ChamberHitContainer rechits)
 Build track segments in this chamber (this is where the actual segment-building algorithm hides.
 CSCSegAlgoTC (const edm::ParameterSet &ps)
 Constructor.
std::vector< CSCSegmentrun (const CSCChamber *aChamber, ChamberHitContainer rechits)
 Here we must implement the algorithm.
virtual ~CSCSegAlgoTC ()
 Destructor.

Private Member Functions

bool addHit (const CSCRecHit2D *aHit, int layer)
 Utility functions.
bool areHitsCloseInGlobalPhi (const CSCRecHit2D *h1, const CSCRecHit2D *h2) const
 Return true if the difference in (global) phi of two hits is < dPhiMax.
bool areHitsCloseInLocalX (const CSCRecHit2D *h1, const CSCRecHit2D *h2) const
 Return true if the difference in (local) x of two hits is < dRPhiMax.
AlgebraicSymMatrix calculateError () const
void compareProtoSegment (const CSCRecHit2D *h, int layer)
HepMatrix derivativeMatrix () const
void dumpHits (const ChamberHitContainer &rechits) const
 Dump global and local coordinate of each rechit in chamber after sort in z.
void fillChiSquared ()
void fillLocalDirection ()
void fitSlopes ()
void flagHitsAsUsed (std::vector< ChamberHitContainer >::iterator is, const ChamberHitContainer &rechitsInChamber, BoolContainer &used) const
 Flag hits on segment as used.
void flipErrors (AlgebraicSymMatrix &) const
bool hasHitOnLayer (int layer) const
void increaseProtoSegment (const CSCRecHit2D *h, int layer)
bool isHitNearSegment (const CSCRecHit2D *h) const
 Return true if hit is near segment.
bool isSegmentGood (std::vector< ChamberHitContainer >::iterator is, std::vector< double >::iterator ichi, const ChamberHitContainer &rechitsInChamber, BoolContainer &used) const
 Return true if segment is good.
float phiAtZ (float z) const
void pruneTheSegments (const ChamberHitContainer &rechitsInChamber)
 Order segments by quality (chi2/hits) and select the best, requiring that they have unique hits.
bool replaceHit (const CSCRecHit2D *h, int layer)
void segmentSort ()
 Sort criterion for segment quality, for use in pruneTheSegments.
void tryAddingHitsToSegment (const ChamberHitContainer &rechits, const ChamberHitContainerCIt i1, const ChamberHitContainerCIt i2)
 Try adding non-used hits to segment.
void updateParameters ()
AlgebraicSymMatrix weightMatrix () const

Private Attributes

std::vector< ChamberHitContainercandidates
float chi2Max
 max segment chi squared
float chi2ndfProbMin
 min segment chi squared probability.
std::vector< double > chi2s
bool debugInfo
std::vector< LocalVectordirections
float dPhiFineMax
 max hit deviation in global phi from the segment axis.
float dPhiMax
 max distance in global phi between hits in one segment
float dRPhiFineMax
 max hit deviation in r-phi from the segment axis.
float dRPhiMax
 max distance in local x between hits in one segment @ The name is historical!
std::vector< AlgebraicSymMatrixerrors
int minLayersApart
 Require end-points of segment are at least minLayersApart.
const std::string myName
 Name of this class.
std::vector< LocalPointorigins
ChamberHitContainer proto_segment
int SegmentSorting
 Select which segment sorting to use (the higher the segment is in the list, the better the segment is supposed to be): if value is ==1: Sort segments by Chi2/(hits on segment) if value is ==2: Sort segments first by hits on segment, then by Chi2Probability(Chi2/ndf).
const CSCChambertheChamber
 Member variables.
double theChi2
LocalVector theDirection
LocalPoint theOrigin
float uz
float vz


Detailed Description

This is an alternative algorithm for building endcap muon track segments out of the rechit's in a CSCChamber.

cf. CSCSegmentizerSK.
'TC' = 'Tim Cox' = Try (all) Combinations

A CSCSegment isa BasicRecHit4D, and is built from CSCRhit objects, each of which isa BasicRecHit2D.

This class is used by the CSCSegmentRecDet.
Alternative algorithms can be used for the segment building by writing classes like this, and then selecting which one is actually used via the CSCSegmentizerBuilder in CSCDetector.

Ported to CMSSW 2006-04-03: Matteo.Sani@cern.ch

Date
2006/11/22 22:59:10
Revision
1.6
Author:
M. Sani

Definition at line 35 of file CSCSegAlgoTC.h.


Member Typedef Documentation

typedef std::deque<bool> CSCSegAlgoTC::BoolContainer

Definition at line 59 of file CSCSegAlgoTC.h.

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

Definition at line 51 of file CSCSegAlgoTC.h.

typedef ChamberHitContainer::const_iterator CSCSegAlgoTC::ChamberHitContainerCIt

Definition at line 52 of file CSCSegAlgoTC.h.

typedef std::vector<int> CSCSegAlgoTC::LayerIndex

Typedefs.

Definition at line 50 of file CSCSegAlgoTC.h.


Constructor & Destructor Documentation

CSCSegAlgoTC::CSCSegAlgoTC ( const edm::ParameterSet ps  )  [explicit]

Constructor.

Definition at line 29 of file CSCSegAlgoTC.cc.

References chi2Max, chi2ndfProbMin, debugInfo, dPhiFineMax, dPhiMax, dRPhiFineMax, dRPhiMax, lat::endl(), edm::ParameterSet::getParameter(), edm::ParameterSet::getUntrackedParameter(), LogDebug, minLayersApart, myName, and SegmentSorting.

00029                                                     : CSCSegmentAlgorithm(ps),
00030                                                           myName("CSCSegAlgoTC") {
00031   
00032   debugInfo = ps.getUntrackedParameter<bool>("verboseInfo");
00033   
00034   dRPhiMax       = ps.getParameter<double>("dRPhiMax");
00035   dPhiMax        = ps.getParameter<double>("dPhiMax");
00036   dRPhiFineMax   = ps.getParameter<double>("dRPhiFineMax");
00037   dPhiFineMax    = ps.getParameter<double>("dPhiFineMax");
00038   chi2Max        = ps.getParameter<double>("chi2Max");
00039   chi2ndfProbMin = ps.getParameter<double>("chi2ndfProbMin");
00040   minLayersApart = ps.getParameter<int>("minLayersApart");
00041   SegmentSorting = ps.getParameter<int>("SegmentSorting");
00042   
00043   LogDebug("CSC") << myName << " has algorithm cuts set to: \n"
00044                   << "--------------------------------------------------------------------\n"
00045                   << "dRPhiMax     = " << dRPhiMax << '\n'
00046                   << "dPhiMax      = " << dPhiMax << '\n'
00047                   << "dRPhiFineMax = " << dRPhiFineMax << '\n'
00048                   << "dPhiFineMax  = " << dPhiFineMax << '\n'
00049                   << "chi2Max      = " << chi2Max << '\n'
00050                   << "chi2ndfProbMin = " << chi2ndfProbMin << '\n'
00051                   << "minLayersApart = " << minLayersApart << '\n'
00052                   << "SegmentSorting = " << SegmentSorting << std::endl;
00053 }

virtual CSCSegAlgoTC::~CSCSegAlgoTC (  )  [inline, virtual]

Destructor.

Definition at line 64 of file CSCSegAlgoTC.h.

00064 {};


Member Function Documentation

bool CSCSegAlgoTC::addHit ( const CSCRecHit2D aHit,
int  layer 
) [private]

Utility functions.

Definition at line 250 of file CSCSegAlgoTC.cc.

References it, proto_segment, and updateParameters().

Referenced by buildSegments(), increaseProtoSegment(), and replaceHit().

00250                                                             {
00251   
00252   // Return true if hit was added successfully 
00253   // (and then parameters are updated).
00254   // Return false if there is already a hit on the same layer, or insert failed.
00255   bool ok = true;
00256   ChamberHitContainer::const_iterator it;
00257   
00258   for(it = proto_segment.begin(); it != proto_segment.end(); it++)
00259     if (((*it)->cscDetId().layer() == layer) && (aHit != *it))
00260       return false; 
00261   
00262   if (ok) {
00263     proto_segment.push_back(aHit);
00264     updateParameters();
00265   }     
00266   return ok;
00267 }

bool CSCSegAlgoTC::areHitsCloseInGlobalPhi ( const CSCRecHit2D h1,
const CSCRecHit2D h2 
) const [private]

Return true if the difference in (global) phi of two hits is < dPhiMax.

Definition at line 641 of file CSCSegAlgoTC.cc.

References CSCRecHit2D::cscDetId(), dPhiMax, gp1, l1, l2, CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), LogDebug, PV3DBase< T, PVType, FrameType >::phi(), theChamber, and GeomDet::toGlobal().

Referenced by buildSegments().

00641                                                                                              {
00642   
00643   const CSCLayer* l1 = theChamber->layer(h1->cscDetId().layer());
00644   GlobalPoint gp1 = l1->toGlobal(h1->localPosition());  
00645   const CSCLayer* l2 = theChamber->layer(h2->cscDetId().layer());
00646   GlobalPoint gp2 = l2->toGlobal(h2->localPosition());  
00647   
00648   float h1p = gp1.phi();
00649   float h2p = gp2.phi();
00650   float dphi12 = h1p - h2p;
00651   
00652   // Into range [-pi, pi) (phi() returns values in this range)
00653   if (dphi12 < -M_PI) 
00654     dphi12 += 2.*M_PI;  
00655   if (dphi12 >  M_PI) 
00656     dphi12 -= 2.*M_PI;
00657   LogDebug("CSC") << "    Hits at global phi= " << h1p << ", " 
00658                   << h2p << " have separation= " << dphi12;
00659   return (fabs(dphi12) < dPhiMax)? true:false;  // +v
00660 }

bool CSCSegAlgoTC::areHitsCloseInLocalX ( const CSCRecHit2D h1,
const CSCRecHit2D h2 
) const [private]

Return true if the difference in (local) x of two hits is < dRPhiMax.

Definition at line 632 of file CSCSegAlgoTC.cc.

References dRPhiMax, CSCRecHit2D::localPosition(), LogDebug, PV3DBase< T, PVType, FrameType >::x(), and x.

Referenced by buildSegments().

00632                                                                                           {
00633   float h1x = h1->localPosition().x();
00634   float h2x = h2->localPosition().x();
00635   float deltaX = (h1->localPosition()-h2->localPosition()).x();
00636   LogDebug("CSC") << "    Hits at local x= " << h1x << ", " 
00637                   << h2x << " have separation= " << deltaX;
00638   return (fabs(deltaX) < (dRPhiMax))? true:false;   // +v
00639 }

std::vector< CSCSegment > CSCSegAlgoTC::buildSegments ( ChamberHitContainer  rechits  ) 

Build track segments in this chamber (this is where the actual segment-building algorithm hides.

)

Definition at line 60 of file CSCSegAlgoTC.cc.

References funct::abs(), addHit(), areHitsCloseInGlobalPhi(), areHitsCloseInLocalX(), calculateError(), candidates, CSCChamberSpecs::chamberTypeName(), chi2s, CSCRecHit2D::cscDetId(), debugInfo, dumpHits(), errors, flipErrors(), gp1, h1, h2, i, i1, i2, l1, l2, CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), LogDebug, minLayersApart, myName, origins, GeomDet::position(), proto_segment, pruneTheSegments(), CSCChamber::specs(), pyDBSRunClass::temp, theChamber, theChi2, theDirection, theOrigin, GeomDet::toGlobal(), tryAddingHitsToSegment(), and PV3DBase< T, PVType, FrameType >::z().

Referenced by run().

00060                                                                              {
00061   
00062   // Reimplementation of original algorithm of CSCSegmentizer, Mar-06
00063 
00064   LogDebug("CSC") << "*********************************************";
00065   LogDebug("CSC") << "Start segment building in the new chamber: " << theChamber->specs()->chamberTypeName();
00066   LogDebug("CSC") << "*********************************************";
00067   
00068   LayerIndex layerIndex(rechits.size());
00069   
00070   for(unsigned int i = 0; i < rechits.size(); i++) {
00071     
00072     layerIndex[i] = rechits[i]->cscDetId().layer();
00073   }
00074   
00075   double z1 = theChamber->layer(1)->position().z();
00076   double z6 = theChamber->layer(6)->position().z();
00077   
00078   if ( z1 > 0. ) {
00079     if ( z1 > z6 ) { 
00080       reverse(layerIndex.begin(), layerIndex.end());
00081       reverse(rechits.begin(), rechits.end());
00082     }    
00083   }
00084   else if ( z1 < 0. ) {
00085     if ( z1 < z6 ) {
00086       reverse(layerIndex.begin(), layerIndex.end());
00087       reverse(rechits.begin(), rechits.end());
00088     }    
00089   }
00090 
00091   if (debugInfo) {
00092     // dump after sorting
00093     dumpHits(rechits);
00094   }
00095 
00096   if (rechits.size() < 2) {
00097     LogDebug("CSC") << myName << ": " << rechits.size() << 
00098       "  hit(s) in chamber is not enough to build a segment.\n";
00099     return std::vector<CSCSegment>(); 
00100   }
00101   
00102   // We have at least 2 hits. We intend to try all possible pairs of hits to start 
00103   // segment building. 'All possible' means each hit lies on different layers in the chamber.
00104   // For now we don't care whether a hit has already been allocated to another segment;
00105   // we'll sort that out after building all possible segments.
00106   
00107   // Choose first hit (as close to IP as possible) h1 and 
00108   // second hit (as far from IP as possible) h2
00109   // To do this we iterate over hits in the chamber by layer - pick two layers.
00110   // @@ Require the two layers are at least 3 layers apart. May need tuning?
00111   // Then we iterate over hits within each of these layers and pick h1 and h2 from these.
00112   // If they are 'close enough' we build an empty segment.
00113   // Then try adding hits to this segment.
00114   
00115   // Define buffer for segments we build (at the end we'll sort them somehow, and remove
00116   // those which share hits with better-quality segments.
00117   
00118   
00119   std::vector<CSCSegment> segments;
00120   
00121   ChamberHitContainerCIt ib = rechits.begin();
00122   ChamberHitContainerCIt ie = rechits.end();
00123   
00124   for (ChamberHitContainerCIt i1 = ib; i1 != ie; ++i1) {
00125     
00126     int layer1 = layerIndex[i1-ib];
00127     const CSCRecHit2D* h1 = *i1;
00128     
00129     for (ChamberHitContainerCIt i2 = ie-1; i2 != i1; --i2) {
00130       
00131       int layer2 = layerIndex[i2-ib];
00132       
00133       if (abs(layer2 - layer1) < minLayersApart)
00134         break;
00135       
00136       const CSCRecHit2D* h2 = *i2;
00137       
00138       if (areHitsCloseInLocalX(h1, h2) && areHitsCloseInGlobalPhi(h1, h2)) {
00139         
00140         proto_segment.clear();
00141         
00142         const CSCLayer* l1 = theChamber->layer(h1->cscDetId().layer());
00143         GlobalPoint gp1 = l1->toGlobal(h1->localPosition());                                    
00144         const CSCLayer* l2 = theChamber->layer(h2->cscDetId().layer());
00145         GlobalPoint gp2 = l2->toGlobal(h2->localPosition());                                    
00146         LogDebug("CSC") << "start new segment from hits " << "h1: " << gp1 << " - h2: " << gp2 << "\n";
00147         
00148         if (!addHit(h1, layer1)) { 
00149           LogDebug("CSC") << "  failed to add hit h1\n";
00150           continue;
00151         }
00152         
00153         if (!addHit(h2, layer2)) { 
00154           LogDebug("CSC") << "  failed to add hit h2\n";
00155           continue;
00156         }
00157         
00158         tryAddingHitsToSegment(rechits, i1, i2); // changed seg 
00159         
00160         // if a segment has been found push back it into the segment collection
00161         if (proto_segment.empty()) {
00162           
00163           LogDebug("CSC") << "No segment has been found !!!\n";
00164         }       
00165         else {
00166           
00167           // calculate error matrix               
00168           AlgebraicSymMatrix error_matrix = calculateError();   
00169 
00170           // but reorder components to match what's required by TrackingRecHit interface
00171           // i.e. slopes first, then positions          
00172           flipErrors( error_matrix );
00173 
00174           candidates.push_back(proto_segment);
00175           origins.push_back(theOrigin);
00176           directions.push_back(theDirection);
00177           errors.push_back(error_matrix);
00178           chi2s.push_back(theChi2);
00179           LogDebug("CSC") << "Found a segment !!!\n";
00180         }
00181       }
00182     }
00183   }
00184   
00185   // We've built all possible segments. Now pick the best, non-overlapping subset.
00186   pruneTheSegments(rechits);
00187   
00188   // Copy the selected proto segments into the CSCSegment vector
00189   for(unsigned int i=0; i < candidates.size(); i++) {
00190     
00191     CSCSegment temp(candidates[i], origins[i], directions[i], errors[i], chi2s[i]); 
00192     segments.push_back(temp);   
00193   }
00194   
00195   candidates.clear();
00196   origins.clear();
00197   directions.clear();
00198   errors.clear();
00199   chi2s.clear();
00200   
00201   // Give the segments to the CSCChamber
00202   return segments;
00203 }

AlgebraicSymMatrix CSCSegAlgoTC::calculateError ( void   )  const [private]

Definition at line 924 of file CSCSegAlgoTC.cc.

References funct::A, derivativeMatrix(), HLT_VtxMuL3::result, weightMatrix(), and weights.

Referenced by buildSegments().

00924                                                       {
00925   
00926   AlgebraicSymMatrix weights = weightMatrix();
00927   AlgebraicMatrix A = derivativeMatrix();
00928   
00929   // (AT W A)^-1
00930   // from https://www.phys.ufl.edu/~avery/fitting.html, part I
00931   int ierr;
00932   AlgebraicSymMatrix result = weights.similarityT(A);
00933   result.invert(ierr);
00934   
00935   // blithely assuming the inverting never fails...
00936   return result;
00937 }

void CSCSegAlgoTC::compareProtoSegment ( const CSCRecHit2D h,
int  layer 
) [private]

Definition at line 579 of file CSCSegAlgoTC.cc.

References LogDebug, proto_segment, replaceHit(), theChi2, theDirection, and theOrigin.

Referenced by tryAddingHitsToSegment().

00579                                                                       {
00580   
00581   // compare the chi2 of two segments
00582   double oldChi2 = theChi2;
00583   LocalPoint oldOrigin = theOrigin;
00584   LocalVector oldDirection = theDirection;
00585   ChamberHitContainer oldSegment = proto_segment;
00586   
00587   bool ok = replaceHit(h, layer);
00588   
00589   if (ok) {
00590     LogDebug("CSC") << "    hit in same layer as a hit on segment; try replacing old one..." 
00591                     << " chi2 new: " << theChi2 << " old: " << oldChi2 << "\n";
00592   }
00593   
00594   if ((theChi2 < oldChi2) && (ok)) {
00595     LogDebug("CSC")  << "    segment with replaced hit is better.\n";
00596   }
00597   else {
00598     proto_segment = oldSegment;
00599     theChi2 = oldChi2;
00600     theOrigin = oldOrigin;
00601     theDirection = oldDirection;
00602   }
00603 }

HepMatrix CSCSegAlgoTC::derivativeMatrix ( void   )  const [private]

Definition at line 939 of file CSCSegAlgoTC.cc.

References CSCRecHit2D::cscDetId(), it, CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), lp, matrix, proto_segment, row, theChamber, GeomDet::toGlobal(), GeomDet::toLocal(), PV3DBase< T, PVType, FrameType >::z(), and z.

Referenced by calculateError().

00939                                                {
00940   
00941   ChamberHitContainer::const_iterator it;
00942   int nhits = proto_segment.size();
00943   HepMatrix matrix(2*nhits, 4);
00944   int row = 0;
00945   
00946   for(it = proto_segment.begin(); it != proto_segment.end(); ++it) {
00947     
00948     const CSCRecHit2D& hit = (**it);
00949     const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
00950     GlobalPoint gp = layer->toGlobal(hit.localPosition());      
00951     LocalPoint lp = theChamber->toLocal(gp); // FIX
00952     float z = lp.z();
00953     ++row;
00954     matrix(row, 1) = 1.;
00955     matrix(row, 3) = z;
00956     ++row;
00957     matrix(row, 2) = 1.;
00958     matrix(row, 4) = z;
00959   }
00960   return matrix;
00961 }

void CSCSegAlgoTC::dumpHits ( const ChamberHitContainer rechits  )  const [private]

Dump global and local coordinate of each rechit in chamber after sort in z.

Definition at line 704 of file CSCSegAlgoTC.cc.

References gp1, it, l1, CSCChamber::layer(), LogDebug, PV3DBase< T, PVType, FrameType >::phi(), theChamber, and GeomDet::toGlobal().

Referenced by buildSegments().

00704                                                                     {
00705   
00706   // Dump positions of RecHit's in each CSCChamber
00707   ChamberHitContainerCIt it;
00708   
00709   for(it=rechits.begin(); it!=rechits.end(); it++) {
00710     
00711     const CSCLayer* l1 = theChamber->layer((*it)->cscDetId().layer());
00712     GlobalPoint gp1 = l1->toGlobal((*it)->localPosition());     
00713     
00714     LogDebug("CSC") << "Global pos.: " << gp1 << ", phi: " << gp1.phi() << ". Local position: "
00715                     << (*it)->localPosition() << ", phi: "
00716                     << (*it)->localPosition().phi() << ". Layer: "
00717                     << (*it)->cscDetId().layer() << "\n";
00718   }     
00719 }

void CSCSegAlgoTC::fillChiSquared ( void   )  [private]

Definition at line 495 of file CSCSegAlgoTC.cc.

References CSCRecHit2D::cscDetId(), CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), CSCRecHit2D::localPositionError(), LogDebug, lp, proto_segment, theChamber, theChi2, theOrigin, GeomDet::toGlobal(), GeomDet::toLocal(), uz, vz, PV3DBase< T, PVType, FrameType >::x(), LocalError::xx(), LocalError::xy(), PV3DBase< T, PVType, FrameType >::y(), LocalError::yy(), and PV3DBase< T, PVType, FrameType >::z().

Referenced by updateParameters().

00495                                   {
00496   
00497   // The chi-squared is (m-Ap)T E (m-Ap)
00498   // where T denotes transpose.
00499   // This collapses to a simple sum over contributions from each
00500   // pair of measurements.
00501   float u0 = theOrigin.x();
00502   float v0 = theOrigin.y();
00503   double chsq = 0.;
00504   
00505   ChamberHitContainer::const_iterator ih;
00506   for (ih = proto_segment.begin(); ih != proto_segment.end(); ++ih) {
00507     
00508     const CSCRecHit2D& hit = (**ih);
00509     const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
00510     GlobalPoint gp = layer->toGlobal(hit.localPosition());
00511     LocalPoint lp = theChamber->toLocal(gp);  // FIX !!
00512     
00513     double hu = lp.x();
00514     double hv = lp.y();
00515     double hz = lp.z();
00516     
00517     double du = u0 + uz * hz - hu;
00518     double dv = v0 + vz * hz - hv;
00519     
00520     HepMatrix IC(2,2);
00521     IC(1,1) = hit.localPositionError().xx();
00522     IC(1,2) = hit.localPositionError().xy();
00523     IC(2,1) = IC(1,2);
00524     IC(2,2) = hit.localPositionError().yy();
00525     
00526     // Invert covariance matrix
00527     int ierr = 0;
00528     IC.invert(ierr);
00529     if (ierr != 0) {
00530       LogDebug("CSC") << "CSCSegment::fillChiSquared: failed to invert covariance matrix=\n" << IC << "\n";
00531       
00532       // @@ NOW WHAT TO DO? Exception? Return? Ignore?
00533     }
00534     
00535     chsq += du*du*IC(1,1) + 2.*du*dv*IC(1,2) + dv*dv*IC(2,2);
00536   }
00537   theChi2 = chsq;
00538 }

void CSCSegAlgoTC::fillLocalDirection ( void   )  [private]

Definition at line 540 of file CSCSegAlgoTC.cc.

References funct::sqrt(), theChamber, theDirection, theOrigin, GeomDet::toGlobal(), uz, vz, and z.

Referenced by updateParameters().

00540                                       {
00541   
00542   // Always enforce direction of segment to point from IP outwards
00543   // (Incorrect for particles not coming from IP, of course.)
00544   
00545   double dxdz = uz;
00546   double dydz = vz;
00547   double dz = 1./sqrt(1. + dxdz*dxdz + dydz*dydz);
00548   double dx = dz*dxdz;
00549   double dy = dz*dydz;
00550   LocalVector localDir(dx,dy,dz);
00551   
00552   // localDir may need sign flip to ensure it points outward from IP
00553   // ptc: Examine its direction and origin in global z: to point outward
00554   // the localDir should always have same sign as global z...
00555   
00556   double globalZpos = ( theChamber->toGlobal( theOrigin ) ).z();
00557   double globalZdir = ( theChamber->toGlobal( localDir ) ).z();
00558   double directionSign = globalZpos * globalZdir;
00559   
00560   theDirection = (directionSign * localDir).unit();
00561 }

void CSCSegAlgoTC::fitSlopes ( void   )  [private]

Definition at line 345 of file CSCSegAlgoTC.cc.

References CSCRecHit2D::cscDetId(), CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), CSCRecHit2D::localPositionError(), LogDebug, lp, p, proto_segment, solve(), theChamber, theOrigin, GeomDet::toGlobal(), GeomDet::toLocal(), uz, v, vz, 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 updateParameters().

00345                              {
00346   
00347   // Update parameters of fit
00348   // ptc 13-Aug-02: This does a linear least-squares fit
00349   // to the hits associated with the segment, in the z projection.
00350   
00351   // In principle perhaps one could fit the strip and wire
00352   // measurements (u, v respectively), to
00353   // u = u0 + uz * z
00354   // v = v0 + vz * z
00355   // where u0, uz, v0, vz are the parameters resulting from the fit.
00356   // But what is actually done is fit to the local x, y coordinates 
00357   // of the RecHits. However the strip measurement controls the precision
00358   // of x, and the wire measurement controls that of y.
00359   // Precision in local coordinate:
00360   //       u (strip, sigma~200um), v (wire, sigma~1cm)
00361   
00362   // I have verified that this code agrees with the formulation given
00363   // on p246-247 of 'Data analysis techniques for high-energy physics
00364   // experiments' by Bock, Grote, Notz & Regler, and that on p111-113
00365   // of 'Statistics' by Barlow.
00366   
00367   // Formulate the matrix equation representing the least-squares fit
00368   // We have a vector of measurements m, which is a 2n x 1 dim matrix
00369   // The transpose mT is (u1, v1, u2, v2, ..., un, vn)
00370   // where ui is the strip-associated measurement and vi is the
00371   // wire-associated measurement for a given RecHit i.
00372   // The fit is to
00373   // u = u0 + uz * z
00374   // v = v0 + vz * z
00375   // where u0, uz, v0, vz are the parameters to be obtained from the fit.
00376   // These are contained in a vector p which is a 4x1 dim matrix, and
00377   // its transpose pT is (u0, v0, uz, vz). Note the ordering!
00378   // The covariance matrix for each pair of measurements is 2 x 2 and
00379   // the inverse of this is the error matrix E.
00380   // The error matrix for the whole set of n measurements is a diagonal
00381   // matrix with diagonal elements the individual 2 x 2 error matrices
00382   // (because the inverse of a diagonal matrix is a diagonal matrix
00383   // with each element the inverse of the original.)
00384   
00385   // The matrix 'matrix' in method 'CSCSegment::weightMatrix()' is this 
00386   // block-diagonal overall covariance matrix. It is inverted to the 
00387   // block-diagonal error matrix right before it is returned.
00388   
00389   // Use the matrix A defined by
00390   //    1   0   z1  0
00391   //    0   1   0   z1
00392   //    1   0   z2  0
00393   //    0   1   0   z2
00394   //    ..  ..  ..  ..
00395   //    1   0   zn  0
00396   //    0   1   0   zn
00397   
00398   // The matrix A is returned by 'CSCSegment::derivativeMatrix()'.
00399   
00400   // Then the normal equations are encapsulated in the matrix equation
00401   //
00402   //    (AT E A)p = (AT E)m
00403   //
00404   // where AT is the transpose of A.
00405   // We'll call the combined matrix on the LHS, M, and that on the RHS, B:
00406   //     M p = B
00407   
00408   // We solve this for the parameter vector, p.
00409   // The elements of M and B then involve sums over the hits
00410   
00411   // The 4 values in p are returned by 'CSCSegment::parameters()'
00412   // in the order uz, vz, u0, v0.
00413   // The error matrix of the parameters is obtained by 
00414   // (AT E A)^-1
00415   // calculated in 'CSCSegment::parametersErrors()'.
00416   
00417   // NOTE 1
00418   // It does the #hits = 2 case separately.
00419   // (I hope they're not on the same layer! They should not be, by construction.)
00420   
00421   // NOTE 2
00422   // We need local position of a RecHit w.r.t. the CHAMBER
00423   // and the RecHit itself only knows its local position w.r.t.
00424   // the LAYER, so we must explicitly transform global position.
00425   
00426   HepMatrix M(4,4,0);
00427   HepVector B(4,0);
00428   
00429   ChamberHitContainer::const_iterator ih = proto_segment.begin();
00430   
00431   for (ih = proto_segment.begin(); ih != proto_segment.end(); ++ih) {
00432     
00433     const CSCRecHit2D& hit = (**ih);
00434     const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
00435     GlobalPoint gp = layer->toGlobal(hit.localPosition());
00436     LocalPoint  lp  = theChamber->toLocal(gp); // FIX !!
00437     
00438     // ptc: Local position of hit w.r.t. chamber
00439     double u = lp.x();
00440     double v = lp.y();
00441     double z = lp.z();
00442     
00443     // ptc: Covariance matrix of local errors MUST BE CHECKED IF COMAPTIBLE
00444     HepMatrix IC(2,2);
00445     IC(1,1) = hit.localPositionError().xx();
00446     IC(1,2) = hit.localPositionError().xy();
00447     IC(2,1) = IC(1,2); // since Cov is symmetric
00448     IC(2,2) = hit.localPositionError().yy();
00449     
00450     // ptc: Invert covariance matrix (and trap if it fails!)
00451     int ierr = 0;
00452     IC.invert(ierr); // inverts in place
00453     if (ierr != 0) {
00454       LogDebug("CSC") << "CSCSegment::fitSlopes: failed to invert covariance matrix=\n" << IC << "\n";
00455       
00456       // @@ NOW WHAT TO DO? Exception? Return? Ignore?
00457     }
00458     
00459     // ptc: Note that IC is no longer Cov but Cov^-1
00460     M(1,1) += IC(1,1);
00461     M(1,2) += IC(1,2);
00462     M(1,3) += IC(1,1) * z;
00463     M(1,4) += IC(1,2) * z;
00464     B(1) += u * IC(1,1) + v * IC(1,2);
00465     
00466     M(2,1) += IC(2,1);
00467     M(2,2) += IC(2,2);
00468     M(2,3) += IC(2,1) * z;
00469     M(2,4) += IC(2,2) * z;
00470     B(2) += u * IC(2,1) + v * IC(2,2);
00471     
00472     M(3,1) += IC(1,1) * z;
00473     M(3,2) += IC(1,2) * z;
00474     M(3,3) += IC(1,1) * z * z;
00475     M(3,4) += IC(1,2) * z * z;
00476     B(3) += ( u * IC(1,1) + v * IC(1,2) ) * z;
00477     
00478     M(4,1) += IC(2,1) * z;
00479     M(4,2) += IC(2,2) * z;
00480     M(4,3) += IC(2,1) * z * z;
00481     M(4,4) += IC(2,2) * z * z;
00482     B(4) += ( u * IC(2,1) + v * IC(2,2) ) * z;
00483   }
00484   
00485   // Solve the matrix equation using CLHEP's 'solve'
00486   //@@ ptc: CAN solve FAIL?? UNCLEAR FROM (LACK OF) CLHEP DOC
00487   HepVector p = solve(M, B);
00488   
00489   // Update member variables uz, vz, theOrigin
00490   theOrigin = LocalPoint(p(1), p(2), 0.);
00491   uz = p(3);
00492   vz = p(4);
00493 }

void CSCSegAlgoTC::flagHitsAsUsed ( std::vector< ChamberHitContainer >::iterator  is,
const ChamberHitContainer rechitsInChamber,
BoolContainer used 
) const [private]

Flag hits on segment as used.

Definition at line 767 of file CSCSegAlgoTC.cc.

Referenced by pruneTheSegments().

00768                                                              {
00769 
00770   // Flag hits on segment as used
00771 
00772   ChamberHitContainerCIt ib = rechitsInChamber.begin();
00773    
00774   for(unsigned int ish = 0; ish < seg->size(); ish++) {
00775 
00776     for(ChamberHitContainerCIt iu = ib; iu != rechitsInChamber.end(); ++iu)
00777       if((*seg)[ish] == (*iu)) 
00778         used[iu-ib] = true;
00779   }
00780 }

void CSCSegAlgoTC::flipErrors ( AlgebraicSymMatrix a  )  const [private]

Definition at line 986 of file CSCSegAlgoTC.cc.

References a.

Referenced by buildSegments().

00986                                                            { 
00987     
00988  // The CSCSegment needs the error matrix re-arranged 
00989    
00990  AlgebraicSymMatrix hold( a ); 
00991     
00992  // errors on slopes into upper left 
00993  a(1,1) = hold(3,3); 
00994  a(1,2) = hold(3,4); 
00995  a(2,1) = hold(4,3); 
00996  a(2,2) = hold(4,4); 
00997     
00998  // errors on positions into lower right 
00999  a(3,3) = hold(1,1); 
01000  a(3,4) = hold(1,2); 
01001  a(4,3) = hold(2,1); 
01002  a(4,4) = hold(2,2); 
01003     
01004  // off-diagonal elements remain unchanged 
01005     
01006 } 

bool CSCSegAlgoTC::hasHitOnLayer ( int  layer  )  const [private]

Definition at line 692 of file CSCSegAlgoTC.cc.

References it, and proto_segment.

Referenced by tryAddingHitsToSegment().

00692                                                 {
00693   
00694   // Is there is already a hit on this layer?
00695   ChamberHitContainerCIt it;
00696   
00697   for(it = proto_segment.begin(); it != proto_segment.end(); it++)
00698     if ((*it)->cscDetId().layer() == layer)
00699       return true; 
00700   
00701   return false;
00702 }

void CSCSegAlgoTC::increaseProtoSegment ( const CSCRecHit2D h,
int  layer 
) [private]

Definition at line 605 of file CSCSegAlgoTC.cc.

References addHit(), chi2Max, LogDebug, proto_segment, theChi2, theDirection, and theOrigin.

Referenced by tryAddingHitsToSegment().

00605                                                                        {
00606   
00607   double oldChi2 = theChi2;
00608   LocalPoint oldOrigin = theOrigin;
00609   LocalVector oldDirection = theDirection;
00610   ChamberHitContainer oldSegment = proto_segment;
00611   
00612   bool ok = addHit(h, layer);
00613   
00614   if (ok) {
00615     LogDebug("CSC") << "    hit in new layer: added to segment, new chi2: " 
00616                     << theChi2 << "\n";
00617   }
00618   
00619   int ndf = 2*proto_segment.size() - 4;
00620   
00621   if (ok && ((ndf <= 0) || (theChi2/ndf < chi2Max))) {
00622     LogDebug("CSC") << "    segment with added hit is good.\n" ;                
00623   }     
00624   else {
00625     proto_segment = oldSegment;
00626     theChi2 = oldChi2;
00627     theOrigin = oldOrigin;
00628     theDirection = oldDirection;
00629   }                     
00630 }               

bool CSCSegAlgoTC::isHitNearSegment ( const CSCRecHit2D h  )  const [private]

Return true if hit is near segment.

'Near' means deltaphi and rxy*deltaphi are within ranges specified by orcarc parameters dPhiFineMax and dRPhiFineMax, where rxy = sqrt(x**2+y**2) of the hit in global coordinates.

Definition at line 662 of file CSCSegAlgoTC.cc.

References CSCRecHit2D::cscDetId(), dPhiFineMax, dRPhiFineMax, l1, CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), LogDebug, PV3DBase< T, PVType, FrameType >::perp(), PV3DBase< T, PVType, FrameType >::phi(), phiAtZ(), theChamber, GeomDet::toGlobal(), and PV3DBase< T, PVType, FrameType >::z().

Referenced by tryAddingHitsToSegment().

00662                                                               {
00663   
00664   // Is hit near segment? 
00665   // Requires deltaphi and rxy*deltaphi within ranges specified
00666   // in orcarc, or by default, where rxy=sqrt(x**2+y**2) of hit itself.
00667   // Note that to make intuitive cuts on delta(phi) one must work in
00668   // phi range (-pi, +pi] not [0, 2pi
00669   
00670   const CSCLayer* l1 = theChamber->layer(h->cscDetId().layer());
00671   GlobalPoint hp = l1->toGlobal(h->localPosition());    
00672   
00673   float hphi = hp.phi();                  // in (-pi, +pi]
00674   if (hphi < 0.) 
00675     hphi += 2.*M_PI;     // into range [0, 2pi)
00676   float sphi = phiAtZ(hp.z());   // in [0, 2*pi)
00677   float phidif = sphi-hphi;
00678   if (phidif < 0.) 
00679     phidif += 2.*M_PI; // into range [0, 2pi)
00680   if (phidif > M_PI) 
00681     phidif -= 2.*M_PI; // into range (-pi, pi]
00682   
00683   float dRPhi = fabs(phidif)*hp.perp();
00684   LogDebug("CSC") << "    is hit at phi_h= " << hphi << " near segment phi_seg= " << sphi 
00685                   << "? is " << dRPhi << "<" << dRPhiFineMax << " ? " 
00686                   << " and is |" << phidif << "|<" << dPhiFineMax << " ?";
00687   
00688   return ((dRPhi < dRPhiFineMax) && 
00689           (fabs(phidif) < dPhiFineMax))? true:false;  // +v
00690 }

bool CSCSegAlgoTC::isSegmentGood ( std::vector< ChamberHitContainer >::iterator  is,
std::vector< double >::iterator  ichi,
const ChamberHitContainer rechitsInChamber,
BoolContainer used 
) const [private]

Return true if segment is good.

In this algorithm, this means it shares no hits with any other segment. If "SegmentSort=2" also require a minimal chi2 probability of "chi2ndfProbMin".

Definition at line 722 of file CSCSegAlgoTC.cc.

References chi2ndfProbMin, ChiSquaredProbability(), and SegmentSorting.

Referenced by pruneTheSegments().

00723                                                                                                          {
00724   
00725   // Apply any selection cuts to segment
00726   
00727   // 1) Require a minimum no. of hits
00728   //   (@@ THESE VALUES SHOULD BECOME PARAMETERS?)
00729   
00730   // 2) Ensure no hits on segment are already assigned to another segment
00731   //    (typically of higher quality)
00732   
00733   unsigned int iadd = (rechitsInChamber.size() > 20 )? iadd = 1 : 0;  
00734   
00735   if (seg->size() < 3 + iadd)
00736     return false;
00737   
00738   // Additional part of alternative segment selection scheme: reject
00739   // segments with a chi2 probability of less than chi2ndfProbMin. Relies on list 
00740   // being sorted with "SegmentSorting == 2", that is first by nrechits and then 
00741   // by chi2prob in subgroups of same nr of rechits.
00742 
00743   if( SegmentSorting == 2 ){
00744     if( (*chi2) != 0 && ((2*seg->size())-4) >0 )  {
00745       if ( ChiSquaredProbability((*chi2),(double)(2*seg->size()-4)) < chi2ndfProbMin ) { 
00746         return false;
00747       }
00748     }
00749     if((*chi2) == 0 ) return false;
00750   }
00751   
00752 
00753   for(unsigned int ish = 0; ish < seg->size(); ++ish) {
00754     
00755     ChamberHitContainerCIt ib = rechitsInChamber.begin();
00756     
00757     for(ChamberHitContainerCIt ic = ib; ic != rechitsInChamber.end(); ++ic) {
00758 
00759       if(((*seg)[ish] == (*ic)) && used[ic-ib])
00760         return false;
00761     }
00762   }
00763   
00764   return true;
00765 }

float CSCSegAlgoTC::phiAtZ ( float  z  )  const [private]

Definition at line 563 of file CSCSegAlgoTC.cc.

References f, l1, CSCChamber::layer(), phi, theChamber, theDirection, theOrigin, GeomDet::toGlobal(), PV3DBase< T, PVType, FrameType >::x(), x, PV3DBase< T, PVType, FrameType >::y(), y, and PV3DBase< T, PVType, FrameType >::z().

Referenced by isHitNearSegment().

00563                                         {
00564   
00565   // Returns a phi in [ 0, 2*pi )
00566   const CSCLayer* l1 = theChamber->layer(1);
00567   GlobalPoint gp = l1->toGlobal(theOrigin);     
00568   GlobalVector gv = l1->toGlobal(theDirection); 
00569   
00570   float x = gp.x() + (gv.x()/gv.z())*(z - gp.z());
00571   float y = gp.y() + (gv.y()/gv.z())*(z - gp.z());
00572   float phi = atan2(y, x);
00573   if (phi < 0.f) 
00574     phi += 2. * M_PI;
00575   
00576   return phi ;
00577 }

void CSCSegAlgoTC::pruneTheSegments ( const ChamberHitContainer rechitsInChamber  )  [private]

Order segments by quality (chi2/hits) and select the best, requiring that they have unique hits.

Definition at line 782 of file CSCSegAlgoTC.cc.

References candidates, chi2s, errors, flagHitsAsUsed(), isSegmentGood(), LogDebug, origins, and segmentSort().

Referenced by buildSegments().

00782                                                                                {
00783   
00784   // Sort the segment store according to segment 'quality' (chi2/#hits ?) and
00785   // remove any segments which contain hits assigned to higher-quality segments.
00786   
00787   if (candidates.empty()) 
00788     return;
00789   
00790   // Initialize flags that a given hit has been allocated to a segment
00791   BoolContainer used(rechitsInChamber.size(), false);
00792   
00793   // Sort by chi2/#hits
00794   segmentSort();
00795   
00796   // Select best quality segments, requiring hits are assigned to just one segment
00797   // Because I want to erase the bad segments, the iterator must be incremented
00798   // inside the loop, and only when the erase is not called
00799 
00800   std::vector<ChamberHitContainer>::iterator is;
00801   std::vector<double>::iterator ichi = chi2s.begin();
00802   std::vector<AlgebraicSymMatrix>::iterator iErr = errors.begin();
00803   std::vector<LocalPoint>::iterator iOrig = origins.begin();
00804   std::vector<LocalVector>::iterator iDir = directions.begin();
00805 
00806   for (is = candidates.begin();  is !=  candidates.end(); ) {
00807     
00808     bool goodSegment = isSegmentGood(is, ichi, rechitsInChamber, used);
00809     
00810     if (goodSegment) {
00811       LogDebug("CSC") << "Accepting segment: ";
00812       
00813       flagHitsAsUsed(is, rechitsInChamber, used);
00814       ++is;
00815       ++ichi;
00816       ++iErr;
00817       ++iOrig;
00818       ++iDir;
00819     }
00820     else {
00821       LogDebug("CSC") << "Rejecting segment: ";
00822       is = candidates.erase(is);
00823       ichi = chi2s.erase(ichi);
00824       iErr = errors.erase(iErr);
00825       iOrig = origins.erase(iOrig);
00826       iDir = directions.erase(iDir);
00827     }
00828   }
00829 }

bool CSCSegAlgoTC::replaceHit ( const CSCRecHit2D h,
int  layer 
) [private]

Definition at line 269 of file CSCSegAlgoTC.cc.

References addHit(), it, and proto_segment.

Referenced by compareProtoSegment().

00269                                                              {
00270   
00271   // replace a hit from a layer 
00272   ChamberHitContainer::iterator it;
00273   for (it = proto_segment.begin(); it != proto_segment.end();) {
00274     if ((*it)->cscDetId().layer() == layer)
00275       it = proto_segment.erase(it);
00276     else
00277       ++it;   
00278   }
00279   
00280   return addHit(h, layer);                                  
00281 }

std::vector< CSCSegment > CSCSegAlgoTC::run ( const CSCChamber aChamber,
ChamberHitContainer  rechits 
)

Here we must implement the algorithm.

Definition at line 55 of file CSCSegAlgoTC.cc.

References buildSegments(), and theChamber.

00055                                                                                                {
00056   theChamber = aChamber; 
00057   return buildSegments(rechits); 
00058 }

void CSCSegAlgoTC::segmentSort (  )  [private]

Sort criterion for segment quality, for use in pruneTheSegments.

Definition at line 831 of file CSCSegAlgoTC.cc.

References candidates, chi2s, ChiSquaredProbability(), errors, i, j, LogDebug, origins, s1, s2, SegmentSorting, and pyDBSRunClass::temp.

Referenced by pruneTheSegments().

00831                                {
00832   
00833   // The segment collection is sorted according chi2/#hits 
00834   
00835   for(unsigned int i=0; i<candidates.size()-1; i++) {
00836     for(unsigned int j=i+1; j<candidates.size(); j++) {
00837       
00838       ChamberHitContainer s1 = candidates[i];
00839       ChamberHitContainer s2 = candidates[j];
00840       if (i == j)
00841         continue;
00842       
00843       int n1 = candidates[i].size();
00844       int n2 = candidates[j].size();
00845       
00846       if( SegmentSorting == 2 ){ // Sort criterion: first sort by Nr of rechits, then in groups of rechits by chi2prob:
00847         if ( n2 > n1 ) { // sort by nr of rechits
00848           ChamberHitContainer temp = candidates[j];
00849           candidates[j] = candidates[i];
00850           candidates[i] = temp;
00851           
00852           double temp1 = chi2s[j];
00853           chi2s[j] = chi2s[i];
00854           chi2s[i] = temp1;
00855           
00856           AlgebraicSymMatrix temp2 = errors[j];
00857           errors[j] = errors[i];
00858           errors[i] = temp2;
00859           
00860           LocalPoint temp3 = origins[j];
00861           origins[j] = origins[i];
00862           origins[i] = temp3;
00863           
00864           LocalVector temp4 = directions[j];
00865           directions[j] = directions[i];
00866           directions[i] = temp4;
00867         }
00868         // sort by chi2 probability in subgroups with equal nr of rechits
00869         if(chi2s[i] != 0. && 2*n2-4 > 0 ) {
00870           if( n2 == n1 && (ChiSquaredProbability( chi2s[i],(double)(2*n1-4)) < ChiSquaredProbability(chi2s[j],(double)(2*n2-4))) ){
00871           ChamberHitContainer temp = candidates[j];
00872           candidates[j] = candidates[i];
00873           candidates[i] = temp;
00874           
00875           double temp1 = chi2s[j];
00876           chi2s[j] = chi2s[i];
00877           chi2s[i] = temp1;
00878           
00879           AlgebraicSymMatrix temp2 = errors[j];
00880           errors[j] = errors[i];
00881           errors[i] = temp2;
00882           
00883           LocalPoint temp3 = origins[j];
00884           origins[j] = origins[i];
00885           origins[i] = temp3;
00886           
00887           LocalVector temp4 = directions[j];
00888           directions[j] = directions[i];
00889           directions[i] = temp4;
00890           }
00891         }
00892       }
00893       else if( SegmentSorting == 1 ){
00894         if ((chi2s[i]/n1) > (chi2s[j]/n2)) {
00895           
00896           ChamberHitContainer temp = candidates[j];
00897           candidates[j] = candidates[i];
00898           candidates[i] = temp;
00899           
00900           double temp1 = chi2s[j];
00901           chi2s[j] = chi2s[i];
00902           chi2s[i] = temp1;
00903           
00904           AlgebraicSymMatrix temp2 = errors[j];
00905           errors[j] = errors[i];
00906           errors[i] = temp2;
00907           
00908           LocalPoint temp3 = origins[j];
00909           origins[j] = origins[i];
00910           origins[i] = temp3;
00911           
00912           LocalVector temp4 = directions[j];
00913           directions[j] = directions[i];
00914           directions[i] = temp4;
00915         }
00916       }
00917       else{
00918           LogDebug("CSC") << "No valid segment sorting specified - BAD !!!\n";
00919       }
00920     }
00921   }     
00922 }

void CSCSegAlgoTC::tryAddingHitsToSegment ( const ChamberHitContainer rechits,
const ChamberHitContainerCIt  i1,
const ChamberHitContainerCIt  i2 
) [private]

Try adding non-used hits to segment.

Definition at line 205 of file CSCSegAlgoTC.cc.

References compareProtoSegment(), CSCRecHit2D::cscDetId(), gp1, h, hasHitOnLayer(), i, increaseProtoSegment(), isHitNearSegment(), l1, CSCDetId::layer(), CSCChamber::layer(), CSCRecHit2D::localPosition(), LogDebug, proto_segment, theChamber, and GeomDet::toGlobal().

Referenced by buildSegments().

00206                                                                                                             {
00207   
00208   // Iterate over the layers with hits in the chamber
00209   // Skip the layers containing the segment endpoints
00210   // Test each hit on the other layers to see if it is near the segment
00211   // If it is, see whether there is already a hit on the segment from the same layer
00212   //    - if so, and there are more than 2 hits on the segment, copy the segment,
00213   //      replace the old hit with the new hit. If the new segment chi2 is better
00214   //      then replace the original segment with the new one (by swap)
00215   //    - if not, copy the segment, add the hit. If the new chi2/dof is still satisfactory
00216   //      then replace the original segment with the new one (by swap)
00217   
00218   ChamberHitContainerCIt ib = rechits.begin();
00219   ChamberHitContainerCIt ie = rechits.end();
00220   
00221   for (ChamberHitContainerCIt i = ib; i != ie; ++i) {
00222     
00223     if ( i == i1 || i == i2 ) 
00224       continue;
00225     
00226     int layer = (*i)->cscDetId().layer();
00227     const CSCRecHit2D* h = *i;
00228     
00229     if (isHitNearSegment(h)) {
00230       
00231       const CSCLayer* l1 = theChamber->layer(h->cscDetId().layer());
00232       GlobalPoint gp1 = l1->toGlobal(h->localPosition());               
00233       LogDebug("CSC") << "    hit at global " << gp1 << " is near segment\n.";
00234       
00235       if (hasHitOnLayer(layer)) {
00236         if (proto_segment.size() <= 2) {
00237           LogDebug("CSC") << "    " << proto_segment.size() 
00238                           << " hits on segment...skip hit on same layer.\n";
00239           continue;
00240         }
00241         
00242         compareProtoSegment(h, layer);
00243       } 
00244       else
00245         increaseProtoSegment(h, layer);
00246     }   // h & seg close
00247   }   // i
00248 }

void CSCSegAlgoTC::updateParameters ( void   )  [private]

Definition at line 283 of file CSCSegAlgoTC.cc.

References fillChiSquared(), fillLocalDirection(), fitSlopes(), h1, h2, CSCChamber::layer(), CSCRecHit2D::localPosition(), proto_segment, theChamber, theChi2, theOrigin, GeomDet::toGlobal(), GeomDet::toLocal(), uz, vz, PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().

Referenced by addHit().

00283                                     {
00284   
00285   // Note that we need local position of a RecHit w.r.t. the CHAMBER
00286   // and the RecHit itself only knows its local position w.r.t.
00287   // the LAYER, so need to explicitly transform to global position.
00288   
00289   //  no. of hits in the RecHitsOnSegment
00290   //  By construction this is the no. of layers with hitsna parte รจ da inserirsi tra le Contrade aperte ad accettare quello che 
00291 
00292 
00293   //  since we allow just one hit per layer in a segment.
00294   
00295   int nh = proto_segment.size();
00296   
00297   // First hit added to a segment must always fail here
00298   if (nh < 2) 
00299     return;
00300   
00301   if (nh == 2) {
00302     
00303     // Once we have two hits we can calculate a straight line 
00304     // (or rather, a straight line for each projection in xz and yz.)
00305     ChamberHitContainer::const_iterator ih = proto_segment.begin();
00306     int il1 = (*ih)->cscDetId().layer();
00307     const CSCRecHit2D& h1 = (**ih);
00308     ++ih;    
00309     int il2 = (*ih)->cscDetId().layer();
00310     const CSCRecHit2D& h2 = (**ih);
00311     
00312     //@@ Skip if on same layer, but should be impossible
00313     if (il1 == il2) 
00314       return;
00315     
00316     const CSCLayer* layer1 = theChamber->layer(il1);
00317     const CSCLayer* layer2 = theChamber->layer(il2);
00318     
00319     GlobalPoint h1glopos = layer1->toGlobal(h1.localPosition());
00320     GlobalPoint h2glopos = layer2->toGlobal(h2.localPosition());
00321     
00322     // localPosition is position of hit wrt layer (so local z = 0)
00323     theOrigin = h1.localPosition();
00324     
00325     // We want hit wrt chamber (and local z will be != 0)
00326     LocalPoint h1pos = theChamber->toLocal(h1glopos);  // FIX !!
00327     LocalPoint h2pos = theChamber->toLocal(h2glopos);  // FIX !!
00328     
00329     float dz = h2pos.z()-h1pos.z();
00330     uz = (h2pos.x()-h1pos.x())/dz ;
00331     vz = (h2pos.y()-h1pos.y())/dz ;
00332     
00333     theChi2 = 0.;
00334   }
00335   else if (nh > 2) {
00336     
00337     // When we have more than two hits then we can fit projections to straight lines
00338     fitSlopes();  
00339     fillChiSquared();
00340   } // end of 'if' testing no. of hits
00341   
00342   fillLocalDirection(); 
00343 }

AlgebraicSymMatrix CSCSegAlgoTC::weightMatrix ( void   )  const [private]

Definition at line 964 of file CSCSegAlgoTC.cc.

References it, CSCRecHit2D::localPositionError(), matrix, proto_segment, row, LocalError::xx(), LocalError::xy(), and LocalError::yy().

Referenced by calculateError().

00964                                                     {
00965   
00966   std::vector<const CSCRecHit2D*>::const_iterator it;
00967   int nhits = proto_segment.size();
00968   AlgebraicSymMatrix matrix(2*nhits, 0);
00969   int row = 0;
00970   
00971   for (it = proto_segment.begin(); it != proto_segment.end(); ++it) {
00972     
00973     const CSCRecHit2D& hit = (**it);
00974     ++row;
00975     matrix(row, row)   = hit.localPositionError().xx();
00976     matrix(row, row+1) = hit.localPositionError().xy();
00977     ++row;
00978     matrix(row, row-1) = hit.localPositionError().xy();
00979     matrix(row, row)   = hit.localPositionError().yy();
00980   }
00981   int ierr;
00982   matrix.invert(ierr);
00983   return matrix;
00984 }


Member Data Documentation

std::vector<ChamberHitContainer> CSCSegAlgoTC::candidates [private]

Definition at line 158 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), pruneTheSegments(), and segmentSort().

float CSCSegAlgoTC::chi2Max [private]

max segment chi squared

Definition at line 172 of file CSCSegAlgoTC.h.

Referenced by CSCSegAlgoTC(), and increaseProtoSegment().

float CSCSegAlgoTC::chi2ndfProbMin [private]

min segment chi squared probability.

Used ONLY if SegmentSorting is chosen to be 2

Definition at line 177 of file CSCSegAlgoTC.h.

Referenced by CSCSegAlgoTC(), and isSegmentGood().

std::vector<double> CSCSegAlgoTC::chi2s [private]

Definition at line 162 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), pruneTheSegments(), and segmentSort().

bool CSCSegAlgoTC::debugInfo [private]

Definition at line 213 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), and CSCSegAlgoTC().

std::vector<LocalVector> CSCSegAlgoTC::directions [private]

Definition at line 160 of file CSCSegAlgoTC.h.

float CSCSegAlgoTC::dPhiFineMax [private]

max hit deviation in global phi from the segment axis.

Function hitNearSegment requires abs(deltaphi) < dPhiFineMax.

Definition at line 187 of file CSCSegAlgoTC.h.

Referenced by CSCSegAlgoTC(), and isHitNearSegment().

float CSCSegAlgoTC::dPhiMax [private]

max distance in global phi between hits in one segment

Definition at line 196 of file CSCSegAlgoTC.h.

Referenced by areHitsCloseInGlobalPhi(), and CSCSegAlgoTC().

float CSCSegAlgoTC::dRPhiFineMax [private]

max hit deviation in r-phi from the segment axis.

Function hitNearSegment requires rxy*abs(deltaphi) < dRPhiFineMax.

Definition at line 182 of file CSCSegAlgoTC.h.

Referenced by CSCSegAlgoTC(), and isHitNearSegment().

float CSCSegAlgoTC::dRPhiMax [private]

max distance in local x between hits in one segment @ The name is historical!

Definition at line 192 of file CSCSegAlgoTC.h.

Referenced by areHitsCloseInLocalX(), and CSCSegAlgoTC().

std::vector<AlgebraicSymMatrix> CSCSegAlgoTC::errors [private]

Definition at line 161 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), pruneTheSegments(), and segmentSort().

int CSCSegAlgoTC::minLayersApart [private]

Require end-points of segment are at least minLayersApart.

Definition at line 200 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), and CSCSegAlgoTC().

const std::string CSCSegAlgoTC::myName [private]

Name of this class.

Definition at line 212 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), and CSCSegAlgoTC().

std::vector<LocalPoint> CSCSegAlgoTC::origins [private]

Definition at line 159 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), pruneTheSegments(), and segmentSort().

ChamberHitContainer CSCSegAlgoTC::proto_segment [private]

Definition at line 164 of file CSCSegAlgoTC.h.

Referenced by addHit(), buildSegments(), compareProtoSegment(), derivativeMatrix(), fillChiSquared(), fitSlopes(), hasHitOnLayer(), increaseProtoSegment(), replaceHit(), tryAddingHitsToSegment(), updateParameters(), and weightMatrix().

int CSCSegAlgoTC::SegmentSorting [private]

Select which segment sorting to use (the higher the segment is in the list, the better the segment is supposed to be): if value is ==1: Sort segments by Chi2/(hits on segment) if value is ==2: Sort segments first by hits on segment, then by Chi2Probability(Chi2/ndf).

Definition at line 208 of file CSCSegAlgoTC.h.

Referenced by CSCSegAlgoTC(), isSegmentGood(), and segmentSort().

const CSCChamber* CSCSegAlgoTC::theChamber [private]

Member variables.

Definition at line 157 of file CSCSegAlgoTC.h.

Referenced by areHitsCloseInGlobalPhi(), buildSegments(), derivativeMatrix(), dumpHits(), fillChiSquared(), fillLocalDirection(), fitSlopes(), isHitNearSegment(), phiAtZ(), run(), tryAddingHitsToSegment(), and updateParameters().

double CSCSegAlgoTC::theChi2 [private]

Definition at line 165 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), compareProtoSegment(), fillChiSquared(), increaseProtoSegment(), and updateParameters().

LocalVector CSCSegAlgoTC::theDirection [private]

Definition at line 167 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), compareProtoSegment(), fillLocalDirection(), increaseProtoSegment(), and phiAtZ().

LocalPoint CSCSegAlgoTC::theOrigin [private]

Definition at line 166 of file CSCSegAlgoTC.h.

Referenced by buildSegments(), compareProtoSegment(), fillChiSquared(), fillLocalDirection(), fitSlopes(), increaseProtoSegment(), phiAtZ(), and updateParameters().

float CSCSegAlgoTC::uz [private]

Definition at line 168 of file CSCSegAlgoTC.h.

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

float CSCSegAlgoTC::vz [private]

Definition at line 168 of file CSCSegAlgoTC.h.

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


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