CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/TrackingTools/DetLayers/src/CylinderBuilderFromDet.cc

Go to the documentation of this file.
00001 #include "TrackingTools/DetLayers/interface/CylinderBuilderFromDet.h"
00002 #include "DataFormats/GeometrySurface/interface/SimpleCylinderBounds.h"
00003 #include "DataFormats/GeometrySurface/interface/BoundingBox.h"
00004 #include <algorithm>
00005 
00006 using namespace std;
00007 
00008 BoundCylinder* 
00009 CylinderBuilderFromDet::operator()( vector<const Det*>::const_iterator first,
00010                                     vector<const Det*>::const_iterator last) const
00011 {
00012   // find mean position and radius
00013   typedef PositionType::BasicVectorType Vector;
00014   Vector posSum(0,0,0);
00015   float rSum = 0;
00016   for (vector<const Det*>::const_iterator i=first; i!=last; i++) {
00017     posSum += (**i).surface().position().basicVector();
00018     rSum += (**i).surface().position().perp();
00019   }
00020   float div(1/float(last-first));
00021   PositionType meanPos( div*posSum);
00022   float meanR( div*rSum);
00023 
00024   // find max deviations from mean pos in Z and from mean R
00025   float rmin = meanR;
00026   float rmax = meanR;
00027   float zmin = meanPos.z();
00028   float zmax = meanPos.z();
00029   for (vector<const Det*>::const_iterator i=first; i!=last; i++) {
00030     vector<GlobalPoint> corners = 
00031       BoundingBox::corners( dynamic_cast<const Plane&>((**i).surface()));
00032     for (vector<GlobalPoint>::const_iterator ic = corners.begin();
00033          ic != corners.end(); ic++) {
00034       float r = ic->perp();
00035       float z = ic->z();
00036       rmin = min( rmin, r);
00037       rmax = max( rmax, r);
00038       zmin = min( zmin, z);
00039       zmax = max( zmax, z);
00040     }
00041     // in addition to the corners we have to check the middle of the 
00042     // det +/- thickness/2
00043     // , since the min  radius for some barrel dets is reached there
00044     float rdet = (**i).surface().position().perp();
00045     float halfThick = (**i).surface().bounds().thickness() / 2.F;
00046     rmin = min( rmin, rdet-halfThick);
00047     rmax = max( rmax, rdet+halfThick);
00048   }
00049 
00050   // the transverse position is zero by construction.
00051   // the Z position is the average between zmin and zmax, since the bounds 
00052   // are symmetric
00053   // for the same reason the R is the average between rmin and rmax,
00054   // but this is done by the Bounds anyway.
00055 
00056   PositionType pos( 0, 0, 0.5*(zmin+zmax));
00057   RotationType rot;      // only "barrel" orientation supported
00058   
00059   auto scp = new SimpleCylinderBounds( rmin, rmax, 
00060                                        zmin-pos.z(), zmax-pos.z());
00061   return new Cylinder(Cylinder::computeRadius(*scp), pos, rot, scp);
00062 
00063 }
00064 
00065 void CylinderBuilderFromDet::operator()(const Det& det) {
00066   BoundingBox bb( dynamic_cast<const Plane&>(det.surface()));
00067   for (int nc=0; nc<8; ++nc) {
00068     float r = bb[nc].perp();
00069     float z = bb[nc].z();
00070     rmin = std::min( rmin, r);
00071     rmax = std::max( rmax, r);
00072     zmin = std::min( zmin, z);
00073     zmax = std::max( zmax, z);
00074   }
00075   // in addition to the corners we have to check the middle of the 
00076   // det +/- thickness/2
00077   // , since the min  radius for some barrel dets is reached there
00078   float rdet = det.surface().position().perp();
00079   float halfThick = det.surface().bounds().thickness() / 2.F;
00080   rmin = std::min( rmin, rdet-halfThick);
00081   rmax = std::max( rmax, rdet+halfThick);
00082 }
00083 
00084 BoundCylinder* CylinderBuilderFromDet::build() const {
00085   
00086   PositionType pos( 0, 0, 0.5*(zmin+zmax));
00087   RotationType rot;      // only "barrel" orientation supported
00088 
00089   auto scp = new SimpleCylinderBounds( rmin, rmax,
00090                                        zmin-pos.z(), zmax-pos.z());
00091   return new Cylinder(Cylinder::computeRadius(*scp), pos, rot, scp);
00092 
00093 }