CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoTracker/TkDetLayers/src/TIDLayer.cc

Go to the documentation of this file.
00001 #include "RecoTracker/TkDetLayers/interface/TIDLayer.h"
00002 
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 #include "DataFormats/GeometrySurface/interface/SimpleDiskBounds.h"
00006 
00007 #include "TrackingTools/DetLayers/interface/DetLayerException.h"
00008 #include "TrackingTools/GeomPropagators/interface/HelixForwardPlaneCrossing.h"
00009 
00010 #include "RecoTracker/TkDetLayers/interface/DetGroupMerger.h"
00011 
00012 //#include "CommonDet/DetLayout/src/DetLessR.h"
00013 
00014 
00015 using namespace std;
00016 
00017 typedef GeometricSearchDet::DetWithState DetWithState;
00018 
00019 
00020 class TIDringLess : public binary_function< int, int, bool> {
00021   // z-position ordering of TID rings indices
00022 public:
00023   bool operator()( const pair<vector<DetGroup> const *,int> & a,const pair<vector<DetGroup>const *,int> & b) const {
00024     if(a.second==2) {return true;}
00025     else if(a.second==0) {
00026       if(b.second==2) return false;
00027       if(b.second==1) return true;
00028     }
00029     return false;    
00030   };
00031 };
00032 
00033 
00034 TIDLayer::TIDLayer(vector<const TIDRing*>& rings):
00035   theComps(rings.begin(),rings.end())
00036 {
00037   //They should be already R-ordered. TO BE CHECKED!!
00038   //sort( theRings.begin(), theRings.end(), DetLessR());
00039   setSurface( computeDisk( rings ) );
00040 
00041   if ( theComps.size() != 3) throw DetLayerException("Number of rings in TID layer is not equal to 3 !!");
00042 
00043   for(vector<const GeometricSearchDet*>::const_iterator it=theComps.begin();
00044       it!=theComps.end();it++){  
00045     theBasicComps.insert(theBasicComps.end(),   
00046                          (**it).basicComponents().begin(),
00047                          (**it).basicComponents().end());
00048   }
00049 
00050  
00051   LogDebug("TkDetLayers") << "==== DEBUG TIDLayer =====" ; 
00052   LogDebug("TkDetLayers") << "r,zed pos  , thickness, innerR, outerR: " 
00053                           << this->position().perp() << " , "
00054                           << this->position().z() << " , "
00055                           << this->specificSurface().bounds().thickness() << " , "
00056                           << this->specificSurface().innerRadius() << " , "
00057                           << this->specificSurface().outerRadius() ;
00058 }
00059 
00060 
00061 BoundDisk* 
00062 TIDLayer::computeDisk( const vector<const TIDRing*>& rings) const
00063 {
00064   float theRmin = rings.front()->specificSurface().innerRadius();
00065   float theRmax = rings.front()->specificSurface().outerRadius();
00066   float theZmin = rings.front()->position().z() -
00067     rings.front()->surface().bounds().thickness()/2;
00068   float theZmax = rings.front()->position().z() +
00069     rings.front()->surface().bounds().thickness()/2;
00070   
00071   for (vector<const TIDRing*>::const_iterator i = rings.begin(); i != rings.end(); i++) {
00072     float rmin = (**i).specificSurface().innerRadius();
00073     float rmax = (**i).specificSurface().outerRadius();
00074     float zmin = (**i).position().z() - (**i).surface().bounds().thickness()/2.;
00075     float zmax = (**i).position().z() + (**i).surface().bounds().thickness()/2.;
00076     theRmin = min( theRmin, rmin);
00077     theRmax = max( theRmax, rmax);
00078     theZmin = min( theZmin, zmin);
00079     theZmax = max( theZmax, zmax);
00080   }
00081   
00082   float zPos = (theZmax+theZmin)/2.;
00083   PositionType pos(0.,0.,zPos);
00084   RotationType rot;
00085 
00086   return new BoundDisk( pos, rot,SimpleDiskBounds(theRmin, theRmax,    
00087                                  theZmin-zPos, theZmax-zPos));
00088 
00089 }
00090 
00091 
00092 TIDLayer::~TIDLayer(){
00093   vector<const GeometricSearchDet*>::const_iterator i;
00094   for (i=theComps.begin(); i!=theComps.end(); i++) {
00095     delete *i;
00096   }
00097 
00098 } 
00099 
00100   
00101 
00102 void
00103 TIDLayer::groupedCompatibleDetsV( const TrajectoryStateOnSurface& startingState,
00104                                  const Propagator& prop,
00105                                  const MeasurementEstimator& est,
00106                                  std::vector<DetGroup> & result) const
00107 {
00108   vector<int> ringIndices = ringIndicesByCrossingProximity(startingState,prop);
00109   if ( ringIndices.size()!=3 ) {
00110     edm::LogError("TkDetLayers") << "TkRingedForwardLayer::groupedCompatibleDets : ringIndices.size() = "
00111                                  << ringIndices.size() << " and not =3!!" ;
00112     return;
00113   }
00114 
00115   vector<DetGroup> closestResult;
00116   vector<DetGroup> nextResult;
00117   vector<DetGroup> nextNextResult;
00118   vector<vector<DetGroup> > groupsAtRingLevel;
00119 
00120   theComps[ringIndices[0]]->groupedCompatibleDetsV( startingState, prop, est, closestResult);           
00121   if ( closestResult.empty() ){
00122     theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, result); 
00123     return;
00124   }
00125 
00126   groupsAtRingLevel.push_back(closestResult);
00127 
00128   DetGroupElement closestGel( closestResult.front().front());  
00129   float rWindow = computeWindowSize( closestGel.det(), closestGel.trajectoryState(), est); 
00130   if(!overlapInR(closestGel.trajectoryState(),ringIndices[1],rWindow)) {
00131     result.swap(closestResult);
00132     return;
00133   };
00134 
00135   nextResult.clear();
00136   theComps[ringIndices[1]]->groupedCompatibleDetsV( startingState, prop, est, nextResult);
00137   if(nextResult.empty()) {
00138     result.swap(closestResult);
00139     return;
00140   }
00141   groupsAtRingLevel.push_back(nextResult);
00142 
00143   if(!overlapInR(closestGel.trajectoryState(),ringIndices[2],rWindow) ) {
00144     //then merge 2 levels & return 
00145     orderAndMergeLevels(closestGel.trajectoryState(),prop,groupsAtRingLevel,ringIndices,result);      
00146     return;
00147   }
00148 
00149   theComps[ringIndices[2]]->groupedCompatibleDetsV( startingState, prop, est, nextNextResult);   
00150   if(nextNextResult.empty()) {
00151     // then merge 2 levels and return 
00152     orderAndMergeLevels(closestGel.trajectoryState(),prop,groupsAtRingLevel,ringIndices,result);
00153     return;
00154   }
00155 
00156   groupsAtRingLevel.push_back(nextNextResult);
00157   // merge 3 level and return merged   
00158   orderAndMergeLevels(closestGel.trajectoryState(),prop,groupsAtRingLevel,ringIndices, result);  
00159 }
00160 
00161 
00162 vector<int> 
00163 TIDLayer::ringIndicesByCrossingProximity(const TrajectoryStateOnSurface& startingState,
00164                                          const Propagator& prop ) const
00165 {
00166   typedef HelixForwardPlaneCrossing Crossing; 
00167   typedef MeasurementEstimator::Local2DVector Local2DVector;
00168 
00169   HelixPlaneCrossing::PositionType startPos( startingState.globalPosition());
00170   HelixPlaneCrossing::DirectionType startDir( startingState.globalMomentum());
00171   PropagationDirection propDir( prop.propagationDirection());
00172   float rho( startingState.transverseCurvature());
00173 
00174   // calculate the crossings with the ring surfaces
00175   // rings are assumed to be sorted in R !
00176   
00177   Crossing myXing(  startPos, startDir, rho, propDir );
00178 
00179   GlobalPoint   ringCrossings[3];
00180   // vector<GlobalVector>  ringXDirections;
00181 
00182   for (int i = 0; i < 3 ; i++ ) {
00183     const BoundDisk & theRing  = static_cast<const BoundDisk &>(theComps[i]->surface());
00184     pair<bool,double> pathlen = myXing.pathLength( theRing);
00185     if ( pathlen.first ) { 
00186       ringCrossings[i] = GlobalPoint( myXing.position(pathlen.second ));
00187       // ringXDirections.push_back( GlobalVector( myXing.direction(pathlen.second )));
00188     } else {
00189       // TO FIX.... perhaps there is something smarter to do
00190       //throw DetLayerException("trajectory doesn't cross TID rings");
00191       ringCrossings[i] = GlobalPoint( 0.,0.,0.);
00192       //  ringXDirections.push_back( GlobalVector( 0.,0.,0.));
00193     }
00194   }
00195 
00196   int closestIndex = findClosest(ringCrossings);
00197   int nextIndex    = findNextIndex(ringCrossings,closestIndex);
00198   if ( closestIndex<0 || nextIndex<0 )  return vector<int>();
00199   int nextNextIndex = -1;
00200   for(int i=0; i<3 ; i++){
00201     if(i!= closestIndex && i!=nextIndex) {
00202       nextNextIndex = i;
00203       break;
00204     }
00205   }
00206   
00207   vector<int> indices;
00208   indices.push_back(closestIndex);
00209   indices.push_back(nextIndex);
00210   indices.push_back(nextNextIndex);
00211   return indices;
00212 }
00213 
00214 
00215 
00216 
00217 float 
00218 TIDLayer::computeWindowSize( const GeomDet* det, 
00219                              const TrajectoryStateOnSurface& tsos, 
00220                              const MeasurementEstimator& est) const
00221 {
00222   const BoundPlane& startPlane = det->surface();  
00223   MeasurementEstimator::Local2DVector maxDistance = 
00224     est.maximalLocalDisplacement( tsos, startPlane);
00225   return maxDistance.y();
00226 }
00227 
00228 namespace {
00229   void mergeOutward(vector< pair<vector<DetGroup> const *,int> > const & groupPlusIndex, 
00230                     std::vector<DetGroup> & result ) {
00231     typedef DetGroupMerger Merger;
00232     Merger::orderAndMergeTwoLevels(*groupPlusIndex[0].first,
00233                                    *groupPlusIndex[1].first,result,1,1);
00234     int size = groupPlusIndex.size();
00235     if(size==3) {
00236       std::vector<DetGroup> tmp;
00237       tmp.swap(result);
00238       Merger::orderAndMergeTwoLevels(tmp,*groupPlusIndex[2].first,result,1,1);      
00239     }
00240     
00241   }
00242   
00243   void mergeInward(vector< pair<vector<DetGroup> const *,int> > const & groupPlusIndex, 
00244                    std::vector<DetGroup> & result ) {
00245     typedef DetGroupMerger Merger;
00246     int size = groupPlusIndex.size();
00247     
00248     if(size==2){
00249       Merger::orderAndMergeTwoLevels(*groupPlusIndex[1].first,
00250                                      *groupPlusIndex[0].first,result,1,1);
00251     }else if(size==3){  
00252       std::vector<DetGroup> tmp;
00253       Merger::orderAndMergeTwoLevels(*groupPlusIndex[2].first,
00254                                      *groupPlusIndex[1].first,tmp,1,1);
00255       Merger::orderAndMergeTwoLevels(tmp,*groupPlusIndex[0].first,result,1,1);      
00256     }      
00257   }
00258 }
00259 
00260 void
00261 TIDLayer::orderAndMergeLevels(const TrajectoryStateOnSurface& tsos,
00262                               const Propagator& prop,
00263                               const vector<vector<DetGroup> > & groups,
00264                               const vector<int> & indices,
00265                               std::vector<DetGroup> & result )
00266 {
00267   vector< pair<vector<DetGroup> const *,int> > groupPlusIndex;
00268 
00269   for(unsigned int i=0;i<groups.size();i++){
00270     groupPlusIndex.push_back(pair<vector<DetGroup> const *,int>(&groups[i],indices[i]) );
00271   }
00272   //order is ring3,ring1,ring2
00273   std::sort(groupPlusIndex.begin(),groupPlusIndex.end(),TIDringLess());
00274   
00275 
00276   float zpos = tsos.globalPosition().z();
00277   if(tsos.globalMomentum().z()*zpos>0){ // momentum points outwards
00278     if(prop.propagationDirection() == alongMomentum)
00279       mergeOutward(groupPlusIndex,result);
00280     else
00281       mergeInward(groupPlusIndex,result);
00282   }
00283   else{ //  momentum points inwards
00284     if(prop.propagationDirection() == oppositeToMomentum)
00285       mergeOutward(groupPlusIndex,result);
00286     else
00287       mergeInward(groupPlusIndex,result);    
00288   }  
00289   
00290 }
00291 
00292 int
00293 TIDLayer::findClosest(const GlobalPoint ringCrossing[3] ) const
00294 {
00295   int theBin = 0;
00296   const BoundDisk & theFrontRing  = static_cast<const BoundDisk &>(theComps[0]->surface());
00297   float initialR = 0.5*( theFrontRing.innerRadius() +
00298                          theFrontRing.outerRadius());
00299   float rDiff = fabs( ringCrossing[0].perp() - initialR);
00300   for (int i = 1; i < 3 ; i++){
00301     const BoundDisk & theRing  = static_cast<const BoundDisk &>(theComps[i]->surface());
00302     float ringR = 0.5*( theRing.innerRadius() + 
00303                         theRing.outerRadius());
00304     float testDiff = fabs( ringCrossing[i].perp() - ringR);
00305     if ( theBin<0 || testDiff<rDiff ) {
00306       rDiff = testDiff;
00307       theBin = i;
00308     }
00309   }
00310   return theBin;
00311 }
00312 
00313 int
00314 TIDLayer::findNextIndex(const GlobalPoint ringCrossing[3], int closest ) const
00315 {
00316 
00317   int firstIndexToCheck = (closest != 0)? 0 : 1; 
00318   const BoundDisk & theFrontRing  = static_cast<const BoundDisk &>(theComps[firstIndexToCheck]->surface());
00319   float initialR = ( theFrontRing.innerRadius() +
00320                      theFrontRing.outerRadius())/2.;         
00321 
00322   float rDiff = fabs( ringCrossing[0].perp() - initialR);
00323   int theBin = firstIndexToCheck;
00324   for (int i = firstIndexToCheck+1; i < 3 ; i++){
00325     if ( i != closest) {
00326       const BoundDisk & theRing  = static_cast<const BoundDisk &>(theComps[i]->surface());
00327       float ringR = ( theRing.innerRadius() + 
00328                       theRing.outerRadius())/2.;
00329       float testDiff = fabs( ringCrossing[i].perp() - ringR);
00330       if ( testDiff<rDiff ) {
00331         rDiff = testDiff;
00332         theBin = i;
00333       }
00334     }
00335   }
00336   return theBin;
00337 }
00338 
00339 
00340 
00341 bool
00342 TIDLayer::overlapInR( const TrajectoryStateOnSurface& tsos, int index, double ymax ) const 
00343 {
00344   // assume "fixed theta window", i.e. margin in local y = r is changing linearly with z
00345   float tsRadius = tsos.globalPosition().perp();
00346   float thetamin = ( max(0.,tsRadius-ymax))/(fabs(tsos.globalPosition().z())+10.); // add 10 cm contingency 
00347   float thetamax = ( tsRadius + ymax)/(fabs(tsos.globalPosition().z())-10.);
00348   
00349   const BoundDisk& ringDisk = static_cast<const BoundDisk&>(theComps[index]->surface());
00350   float ringMinZ = fabs( ringDisk.position().z()) - ringDisk.bounds().thickness()/2.;
00351   float ringMaxZ = fabs( ringDisk.position().z()) + ringDisk.bounds().thickness()/2.; 
00352   float thetaRingMin =  ringDisk.innerRadius()/ ringMaxZ;
00353   float thetaRingMax =  ringDisk.outerRadius()/ ringMinZ;
00354 
00355   // do the theta regions overlap ?
00356 
00357   return !( thetamin > thetaRingMax || thetaRingMin > thetamax);
00358 }
00359 
00360