00001 #include "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 "DetGroupMerger.h"
00011
00012
00013
00014
00015 using namespace std;
00016
00017 typedef GeometricSearchDet::DetWithState DetWithState;
00018
00019
00020 class TIDringLess : public binary_function< int, int, bool> {
00021
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
00038
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
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
00152 orderAndMergeLevels(closestGel.trajectoryState(),prop,groupsAtRingLevel,ringIndices,result);
00153 return;
00154 }
00155
00156 groupsAtRingLevel.push_back(nextNextResult);
00157
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
00175
00176
00177 Crossing myXing( startPos, startDir, rho, propDir );
00178
00179 GlobalPoint ringCrossings[3];
00180
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
00188 } else {
00189
00190
00191 ringCrossings[i] = GlobalPoint( 0.,0.,0.);
00192
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
00273 std::sort(groupPlusIndex.begin(),groupPlusIndex.end(),TIDringLess());
00274
00275
00276 float zpos = tsos.globalPosition().z();
00277 if(tsos.globalMomentum().z()*zpos>0){
00278 if(prop.propagationDirection() == alongMomentum)
00279 mergeOutward(groupPlusIndex,result);
00280 else
00281 mergeInward(groupPlusIndex,result);
00282 }
00283 else{
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
00345 float tsRadius = tsos.globalPosition().perp();
00346 float thetamin = ( max(0.,tsRadius-ymax))/(fabs(tsos.globalPosition().z())+10.);
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
00356
00357 return !( thetamin > thetaRingMax || thetaRingMin > thetamax);
00358 }
00359
00360