00001 #include "RecoTracker/TkDetLayers/interface/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 "RecoTracker/TkDetLayers/interface/LayerCrossingSide.h"
00014 #include "RecoTracker/TkDetLayers/interface/DetGroupMerger.h"
00015 #include "RecoTracker/TkDetLayers/interface/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
00025
00026
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
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
00108
00109 if (PhiLess()( normal.phi(), radial.phi())) {
00110 theHelicity = 1;
00111 }
00112 else {
00113 theHelicity = 0;
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
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 }
00177
00178
00179 if (window > 0.5*detWidth) {
00180 searchNeighbors( tsos, prop, est, crossings, window, result);
00181 }
00182 }
00183
00184 void TIBRing::searchNeighbors( const TrajectoryStateOnSurface& tsos,
00185 const Propagator& prop,
00186 const MeasurementEstimator& est,
00187 const SubRingCrossings& crossings,
00188 float window,
00189 vector<DetGroup>& result) const
00190 {
00191 typedef CompatibleDetToGroupAdder Adder;
00192 int crossingSide = LayerCrossingSide().barrelSide( tsos, prop);
00193 typedef DetGroupMerger Merger;
00194
00195 int negStart = min( crossings.closestIndex, crossings.nextIndex) - 1;
00196 int posStart = max( crossings.closestIndex, crossings.nextIndex) + 1;
00197
00198 int quarter = theDets.size()/4;
00199 vector<DetGroup> tmp;
00200 vector<DetGroup> newResult;
00201 for (int idet=negStart; idet >= negStart - quarter+1; idet--) {
00202 const GeomDet* neighbor = theDets[theBinFinder.binIndex(idet)];
00203
00204
00205 tmp.clear();
00206 newResult.clear();
00207 if (!Adder::add( *neighbor, tsos, prop, est, tmp)) break;
00208 Merger::orderAndMergeTwoLevels( tmp, result, newResult, theHelicity, crossingSide);
00209 result.swap(newResult);
00210 }
00211 for (int idet=posStart; idet < posStart + quarter-1; idet++) {
00212 const GeomDet* neighbor = theDets[theBinFinder.binIndex(idet)];
00213
00214
00215 tmp.clear();
00216 newResult.clear();
00217 if (!Adder::add( *neighbor, tsos, prop, est, tmp)) break;
00218 Merger::orderAndMergeTwoLevels( result, tmp, newResult, theHelicity, crossingSide);
00219 result.swap(newResult);
00220 }
00221 }
00222
00223
00224 TIBRing::SubRingCrossings
00225 TIBRing::computeCrossings( const TrajectoryStateOnSurface& startingState,
00226 PropagationDirection propDir) const
00227 {
00228 typedef HelixBarrelPlaneCrossing2OrderLocal Crossing;
00229 typedef MeasurementEstimator::Local2DVector Local2DVector;
00230
00231 GlobalPoint startPos( startingState.globalPosition());
00232 GlobalVector startDir( startingState.globalMomentum());
00233 double rho( startingState.transverseCurvature());
00234
00235 HelixBarrelCylinderCrossing cylCrossing( startPos, startDir, rho,
00236 propDir,specificSurface());
00237
00238 if (!cylCrossing.hasSolution()) return SubRingCrossings();
00239
00240 GlobalPoint cylPoint( cylCrossing.position());
00241 GlobalVector cylDir( cylCrossing.direction());
00242 int closestIndex = theBinFinder.binIndex(cylPoint.phi());
00243
00244 const BoundPlane& closestPlane( theDets[closestIndex]->surface());
00245
00246 LocalPoint closestPos = Crossing( cylPoint, cylDir, rho, closestPlane).position();
00247 float closestDist = closestPos.x();
00248
00249
00250 int nextIndex = PhiLess()( closestPlane.position().phi(), cylPoint.phi()) ?
00251 closestIndex+1 : closestIndex-1;
00252
00253 const BoundPlane& nextPlane( theDets[ theBinFinder.binIndex(nextIndex)]->surface());
00254 LocalPoint nextPos = Crossing( cylPoint, cylDir, rho, nextPlane).position();
00255 float nextDist = nextPos.x();
00256
00257 if (fabs(closestDist) < fabs(nextDist)) {
00258 return SubRingCrossings( closestIndex, nextIndex, nextDist);
00259 }
00260 else {
00261 return SubRingCrossings( nextIndex, closestIndex, closestDist);
00262 }
00263 }
00264
00265 float TIBRing::computeWindowSize( const GeomDet* det,
00266 const TrajectoryStateOnSurface& tsos,
00267 const MeasurementEstimator& est) const
00268 {
00269 return est.maximalLocalDisplacement(tsos, det->surface()).x();
00270 }
00271
00272
00273