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
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 }else{
00177 result.swap(closestResult);
00178 }
00179
00180
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
00206
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
00216
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();
00250
00251
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