CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoTracker/TkDetLayers/src/TIBRing.cc

Go to the documentation of this file.
00001 #include "TIBRing.h"
00002 
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 #include "TrackingTools/DetLayers/interface/DetLayerException.h"
00006 #include "TrackingTools/DetLayers/interface/CylinderBuilderFromDet.h"
00007 #include "TrackingTools/DetLayers/interface/simple_stat.h"
00008 #include "TrackingTools/DetLayers/interface/PhiLess.h"
00009 #include "TrackingTools/GeomPropagators/interface/HelixBarrelPlaneCrossing2OrderLocal.h"
00010 #include "TrackingTools/GeomPropagators/interface/HelixBarrelCylinderCrossing.h"
00011 #include "TrackingTools/PatternTools/interface/MeasurementEstimator.h"
00012 
00013 #include "LayerCrossingSide.h"
00014 #include "DetGroupMerger.h"
00015 #include "CompatibleDetToGroupAdder.h"
00016 
00017 using namespace std;
00018 
00019 typedef GeometricSearchDet::DetWithState DetWithState;
00020 
00021 TIBRing::TIBRing(vector<const GeomDet*>& theGeomDets):
00022   theDets(theGeomDets.begin(),theGeomDets.end())
00023 {
00024   //checkRadius( first, last);
00025   //sort( theDets.begin(), theDets.end(), DetLessPhi());
00026   //checkPeriodicity( theDets.begin(), theDets.end());
00027 
00028   theBinFinder = BinFinderType( theDets.front()->surface().position().phi(),
00029                                 theDets.size());
00030 
00031   theCylinder = CylinderBuilderFromDet()( theDets.begin(), theDets.end());
00032 
00033   computeHelicity();
00034 
00035   
00036   LogDebug("TkDetLayers") << "==== DEBUG TIBRing =====" ; 
00037   LogDebug("TkDetLayers") << "radius, thickness, lenght: " 
00038                           << theCylinder->radius() << " , "
00039                           << theCylinder->bounds().thickness() << " , "
00040                           << theCylinder->bounds().length() ;
00041 
00042   for (vector<const GeomDet*>::const_iterator i=theDets.begin();
00043        i != theDets.end(); i++){
00044     LogDebug("TkDetLayers") << "Ring's Det pos z,perp,eta,phi: " 
00045          << (**i).position().z() << " , " 
00046          << (**i).position().perp() << " , " 
00047          << (**i).position().eta() << " , " 
00048          << (**i).position().phi() ;
00049   }
00050   LogDebug("TkDetLayers") << "==== end DEBUG TIBRing =====" ; 
00051  
00052   
00053 }
00054 
00055 
00056 const vector<const GeometricSearchDet*>& 
00057 TIBRing::components() const 
00058 {
00059   throw DetLayerException("TIBRing doesn't have GeometricSearchDet components");
00060 }
00061 
00062 void TIBRing::checkRadius(vector<const GeomDet*>::const_iterator first,
00063                           vector<const GeomDet*>::const_iterator last)
00064 {
00065   // check radius range
00066   float rMin = 10000.;
00067   float rMax = 0.;
00068   for (vector<const GeomDet*>::const_iterator i=first; i!=last; i++) {
00069     float r = (**i).surface().position().perp();
00070     if (r < rMin) rMin = r;
00071     if (r > rMax) rMax = r;
00072   }
00073   if (rMax - rMin > 0.1) throw DetLayerException(
00074     "TIBRing construction failed: detectors not at constant radius");
00075 }
00076 
00077 
00078 void TIBRing::checkPeriodicity(vector<const GeomDet*>::const_iterator first,
00079                                vector<const GeomDet*>::const_iterator last)
00080 {
00081   vector<double> adj_diff(last-first-1);
00082   for (int i=0; i < static_cast<int>(adj_diff.size()); i++) {
00083     vector<const GeomDet*>::const_iterator curent = first + i;
00084     adj_diff[i] = (**(curent+1)).surface().position().phi() - 
00085                   (**curent).surface().position().phi();
00086   }
00087   double step = stat_mean( adj_diff);
00088   double phi_step = 2.*Geom::pi()/(last-first);  
00089 
00090   if ( fabs(step-phi_step)/phi_step > 0.01) {
00091     int ndets = last-first;
00092     edm::LogError("TkDetLayers") << "TIBRing Warning: not periodic. ndets=" << ndets ;
00093     for (int j=0; j<ndets; j++) {
00094       edm::LogError("TkDetLayers") << "Dets(r,phi): (" << theDets[j]->surface().position().perp() 
00095                                  << "," << theDets[j]->surface().position().phi() << ") " ;
00096     }
00097     throw DetLayerException( "Error: TIBRing is not periodic");
00098   }
00099 }
00100 
00101 void TIBRing::computeHelicity() {
00102 
00103   const GeomDet& det = *theDets.front();
00104   GlobalVector radial = det.surface().position() - GlobalPoint(0,0,0);
00105   GlobalVector normal = det.surface().toGlobal( LocalVector(0,0,1));
00106   if(normal.dot(radial)<=0)normal*=-1;
00107 //   edm::LogInfo(TkDetLayers) << "BarrelDetRing::computeHelicity: phi(normal) " << normal.phi()
00108 //        << " phi(radial) " << radial.phi() ;
00109   if (PhiLess()( normal.phi(), radial.phi())) {
00110     theHelicity = 1;  // smaller phi angles mean "inner" group
00111   }
00112   else {
00113     theHelicity = 0;  // smaller phi angles mean "outer" group
00114   }
00115 }
00116 
00117 
00118 TIBRing::~TIBRing(){
00119 
00120 } 
00121 
00122   
00123 pair<bool, TrajectoryStateOnSurface>
00124 TIBRing::compatible( const TrajectoryStateOnSurface& ts, const Propagator&, 
00125                   const MeasurementEstimator&) const{
00126   edm::LogError("TkDetLayers") << "temporary dummy implementation of TIBRing::compatible()!!" ;
00127   return pair<bool,TrajectoryStateOnSurface>();
00128 }
00129 
00130 
00131 void
00132 TIBRing::groupedCompatibleDetsV( const TrajectoryStateOnSurface& tsos,
00133                                 const Propagator& prop,
00134                                  const MeasurementEstimator& est,
00135                                  vector<DetGroup> & result) const
00136 {
00137   vector<DetGroup> closestResult;
00138   SubRingCrossings  crossings; 
00139   crossings = computeCrossings( tsos, prop.propagationDirection());
00140   if(! crossings.isValid_) return;
00141 
00142   typedef CompatibleDetToGroupAdder Adder;
00143   Adder::add( *theDets[theBinFinder.binIndex(crossings.closestIndex)], 
00144              tsos, prop, est, closestResult);
00145   
00146   if(closestResult.empty()){
00147     Adder::add( *theDets[theBinFinder.binIndex(crossings.nextIndex)], 
00148                tsos, prop, est, result);
00149     return;
00150   }      
00151 
00152   DetGroupElement closestGel( closestResult.front().front());
00153   float window = computeWindowSize( closestGel.det(), closestGel.trajectoryState(), est);
00154 
00155   //vector<DetGroup> result;
00156   float detWidth = closestGel.det()->surface().bounds().width();
00157   if (crossings.nextDistance < detWidth + window) {
00158     vector<DetGroup> nextResult;
00159     if (Adder::add( *theDets[theBinFinder.binIndex(crossings.nextIndex)], 
00160                    tsos, prop, est, nextResult)) {
00161       int crossingSide = LayerCrossingSide().barrelSide( tsos, prop);
00162       if (crossings.closestIndex < crossings.nextIndex) {
00163         DetGroupMerger::orderAndMergeTwoLevels( closestResult, nextResult,
00164                                                 result,
00165                                                 theHelicity, crossingSide);
00166       }
00167       else {
00168         DetGroupMerger::orderAndMergeTwoLevels( nextResult, closestResult,
00169                                                 result,
00170                                                 theHelicity, crossingSide);
00171       }
00172     }
00173     else {
00174       result.swap(closestResult);
00175     } 
00176   }else{
00177     result.swap(closestResult);
00178   }
00179   
00180   // only loop over neighbors (other than closest and next) if window is BIG
00181   if (window > 0.5*detWidth) {
00182     searchNeighbors( tsos, prop, est, crossings, window, result);
00183   } 
00184 }
00185 
00186 void TIBRing::searchNeighbors( const TrajectoryStateOnSurface& tsos,
00187                                const Propagator& prop,
00188                                const MeasurementEstimator& est,
00189                                const SubRingCrossings& crossings,
00190                                float window, 
00191                                vector<DetGroup>& result) const
00192 {
00193   typedef CompatibleDetToGroupAdder Adder;
00194   int crossingSide = LayerCrossingSide().barrelSide( tsos, prop);
00195   typedef DetGroupMerger Merger;
00196   
00197   int negStart = min( crossings.closestIndex, crossings.nextIndex) - 1;
00198   int posStart = max( crossings.closestIndex, crossings.nextIndex) + 1;
00199   
00200   int quarter = theDets.size()/4;
00201   vector<DetGroup> tmp;
00202   vector<DetGroup> newResult;
00203   for (int idet=negStart; idet >= negStart - quarter+1; idet--) {
00204     const GeomDet* neighbor = theDets[theBinFinder.binIndex(idet)];
00205     // if (!overlap( gCrossingPos, *neighbor, window)) break; // mybe not needed?
00206     // maybe also add shallow crossing angle test here???
00207     tmp.clear();
00208     newResult.clear();
00209     if (!Adder::add( *neighbor, tsos, prop, est, tmp)) break;
00210     Merger::orderAndMergeTwoLevels( tmp, result, newResult, theHelicity, crossingSide);
00211     result.swap(newResult);
00212   }
00213   for (int idet=posStart; idet < posStart + quarter-1; idet++) {
00214     const GeomDet* neighbor = theDets[theBinFinder.binIndex(idet)];
00215     // if (!overlap( gCrossingPos, *neighbor, window)) break; // mybe not needed?
00216     // maybe also add shallow crossing angle test here???
00217     tmp.clear();
00218     newResult.clear();
00219     if (!Adder::add( *neighbor, tsos, prop, est, tmp)) break;
00220     Merger::orderAndMergeTwoLevels( result, tmp, newResult, theHelicity, crossingSide);
00221     result.swap(newResult);
00222   }
00223 }
00224 
00225 
00226 TIBRing::SubRingCrossings 
00227 TIBRing::computeCrossings( const TrajectoryStateOnSurface& startingState,
00228     PropagationDirection propDir) const
00229 {
00230   typedef HelixBarrelPlaneCrossing2OrderLocal    Crossing;
00231   typedef MeasurementEstimator::Local2DVector Local2DVector;
00232 
00233   GlobalPoint startPos( startingState.globalPosition());
00234   GlobalVector startDir( startingState.globalMomentum());
00235   double rho( startingState.transverseCurvature());
00236 
00237   HelixBarrelCylinderCrossing cylCrossing( startPos, startDir, rho,
00238                                            propDir,specificSurface());
00239 
00240   if (!cylCrossing.hasSolution()) return SubRingCrossings();
00241 
00242   GlobalPoint  cylPoint( cylCrossing.position());
00243   GlobalVector cylDir( cylCrossing.direction());
00244   int closestIndex = theBinFinder.binIndex(cylPoint.phi());
00245 
00246   const BoundPlane& closestPlane( theDets[closestIndex]->surface());
00247 
00248   LocalPoint closestPos = Crossing( cylPoint, cylDir, rho, closestPlane).position();
00249   float closestDist = closestPos.x(); // use fact that local X perp to global Z 
00250 
00251   //int next = cylPoint.phi() - closestPlane.position().phi() > 0 ? closest+1 : closest-1;
00252   int nextIndex = PhiLess()( closestPlane.position().phi(), cylPoint.phi()) ? 
00253     closestIndex+1 : closestIndex-1;
00254 
00255   const BoundPlane& nextPlane( theDets[ theBinFinder.binIndex(nextIndex)]->surface());
00256   LocalPoint nextPos = Crossing( cylPoint, cylDir, rho, nextPlane).position();
00257   float nextDist = nextPos.x();
00258 
00259   if (fabs(closestDist) < fabs(nextDist)) {
00260     return SubRingCrossings( closestIndex, nextIndex, nextDist);
00261   }
00262   else {
00263     return SubRingCrossings( nextIndex, closestIndex, closestDist);
00264   }
00265 }
00266 
00267 float TIBRing::computeWindowSize( const GeomDet* det, 
00268                                   const TrajectoryStateOnSurface& tsos, 
00269                                   const MeasurementEstimator& est) const
00270 {
00271   return est.maximalLocalDisplacement(tsos, det->surface()).x();
00272 }
00273 
00274 
00275