Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:31:32

0001 #include "TrackingTools/DetLayers/interface/CylinderBuilderFromDet.h"
0002 #include "DataFormats/GeometrySurface/interface/SimpleCylinderBounds.h"
0003 #include "DataFormats/GeometrySurface/interface/BoundingBox.h"
0004 #include <algorithm>
0005 
0006 using namespace std;
0007 
0008 BoundCylinder* CylinderBuilderFromDet::operator()(vector<const Det*>::const_iterator first,
0009                                                   vector<const Det*>::const_iterator last) const {
0010   // find mean position and radius
0011   typedef PositionType::BasicVectorType Vector;
0012   Vector posSum(0, 0, 0);
0013   float rSum = 0;
0014   for (vector<const Det*>::const_iterator i = first; i != last; i++) {
0015     posSum += (**i).surface().position().basicVector();
0016     rSum += (**i).surface().position().perp();
0017   }
0018   float div(1 / float(last - first));
0019   PositionType meanPos(div * posSum);
0020   float meanR(div * rSum);
0021 
0022   // find max deviations from mean pos in Z and from mean R
0023   float rmin = meanR;
0024   float rmax = meanR;
0025   float zmin = meanPos.z();
0026   float zmax = meanPos.z();
0027   for (vector<const Det*>::const_iterator i = first; i != last; i++) {
0028     vector<GlobalPoint> corners = BoundingBox::corners(dynamic_cast<const Plane&>((**i).surface()));
0029     for (vector<GlobalPoint>::const_iterator ic = corners.begin(); ic != corners.end(); ic++) {
0030       float r = ic->perp();
0031       float z = ic->z();
0032       rmin = min(rmin, r);
0033       rmax = max(rmax, r);
0034       zmin = min(zmin, z);
0035       zmax = max(zmax, z);
0036     }
0037     // in addition to the corners we have to check the middle of the
0038     // det +/- thickness/2
0039     // , since the min  radius for some barrel dets is reached there
0040     float rdet = (**i).surface().position().perp();
0041     float halfThick = (**i).surface().bounds().thickness() / 2.F;
0042     rmin = min(rmin, rdet - halfThick);
0043     rmax = max(rmax, rdet + halfThick);
0044   }
0045 
0046   // the transverse position is zero by construction.
0047   // the Z position is the average between zmin and zmax, since the bounds
0048   // are symmetric
0049   // for the same reason the R is the average between rmin and rmax,
0050   // but this is done by the Bounds anyway.
0051 
0052   PositionType pos(0, 0, 0.5 * (zmin + zmax));
0053   RotationType rot;  // only "barrel" orientation supported
0054 
0055   auto scp = new SimpleCylinderBounds(rmin, rmax, zmin - pos.z(), zmax - pos.z());
0056   return new Cylinder(Cylinder::computeRadius(*scp), pos, rot, scp);
0057 }
0058 
0059 void CylinderBuilderFromDet::operator()(const Det& det) {
0060   BoundingBox bb(dynamic_cast<const Plane&>(det.surface()));
0061   for (int nc = 0; nc < 8; ++nc) {
0062     float r = bb[nc].perp();
0063     float z = bb[nc].z();
0064     rmin = std::min(rmin, r);
0065     rmax = std::max(rmax, r);
0066     zmin = std::min(zmin, z);
0067     zmax = std::max(zmax, z);
0068   }
0069   // in addition to the corners we have to check the middle of the
0070   // det +/- thickness/2
0071   // , since the min  radius for some barrel dets is reached there
0072   float rdet = det.surface().position().perp();
0073   float halfThick = det.surface().bounds().thickness() / 2.F;
0074   rmin = std::min(rmin, rdet - halfThick);
0075   rmax = std::max(rmax, rdet + halfThick);
0076 }
0077 
0078 BoundCylinder* CylinderBuilderFromDet::build() const {
0079   PositionType pos(0, 0, 0.5 * (zmin + zmax));
0080   RotationType rot;  // only "barrel" orientation supported
0081 
0082   auto scp = new SimpleCylinderBounds(rmin, rmax, zmin - pos.z(), zmax - pos.z());
0083   return new Cylinder(Cylinder::computeRadius(*scp), pos, rot, scp);
0084 }