Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:49

0001 //Framework Headers
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 
0005 //CMSSW Headers
0006 #include "DataFormats/GeometrySurface/interface/Surface.h"
0007 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
0008 #include "DataFormats/GeometrySurface/interface/SimpleCylinderBounds.h"
0009 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
0010 #include "DataFormats/GeometrySurface/interface/SimpleDiskBounds.h"
0011 
0012 // Tracker/Tracking Headers
0013 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
0014 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
0015 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
0016 
0017 //FAMOS Headers
0018 #include "FastSimulation/TrackerSetup/interface/TrackerInteractionGeometry.h"
0019 
0020 #include <iostream>
0021 
0022 TrackerInteractionGeometry::TrackerInteractionGeometry(const edm::ParameterSet& trackerMaterial,
0023                                                        const GeometricSearchTracker* theGeomSearchTracker) {
0024   use_hardcoded = trackerMaterial.getParameter<bool>("use_hardcoded_geometry");
0025 
0026   if (!use_hardcoded) {
0027     std::vector<double> disk_thickness = trackerMaterial.getParameter<std::vector<double> >("disk_thickness");
0028     std::vector<double> disk_inner_radius = trackerMaterial.getParameter<std::vector<double> >("disk_inner_radius");
0029     std::vector<double> disk_outer_radius = trackerMaterial.getParameter<std::vector<double> >("disk_outer_radius");
0030     std::vector<double> disk_z = trackerMaterial.getParameter<std::vector<double> >("disk_z");
0031 
0032     assert(disk_inner_radius.size() == disk_outer_radius.size() && disk_inner_radius.size() == disk_z.size() &&
0033            disk_inner_radius.size() == disk_thickness.size());
0034     std::cout << "number of disk layers = " << disk_z.size() << std::endl;
0035 
0036     const Surface::RotationType theRotation2(1., 0., 0., 0., 1., 0., 0., 0., 1.);
0037 
0038     std::vector<double> barrel_thickness = trackerMaterial.getParameter<std::vector<double> >("barrel_thickness");
0039     std::vector<double> barrel_radius = trackerMaterial.getParameter<std::vector<double> >("barrel_radius");
0040     std::vector<double> barrel_length = trackerMaterial.getParameter<std::vector<double> >("barrel_length");
0041 
0042     assert(barrel_length.size() == barrel_radius.size() && barrel_length.size() == barrel_thickness.size());
0043     std::cout << "number of barrel layers = " << barrel_length.size() << std::endl;
0044 
0045     const Surface::PositionType thePosition(0., 0., 0.);
0046     const Surface::RotationType theRotation(1., 0., 0., 0., 1., 0., 0., 0., 1.);
0047 
0048     for (unsigned int i = 0, j = 0; i < barrel_length.size() || j < disk_z.size();) {
0049       bool add_disk = false;
0050       if (i < barrel_length.size() && j < disk_z.size()) {
0051         if (disk_outer_radius[j] < barrel_radius[i])
0052           add_disk = true;
0053         else
0054           add_disk = false;
0055       } else if (i < barrel_length.size() && !(j < disk_z.size()))
0056         add_disk = false;
0057       else if (!(i < barrel_length.size()) && j < disk_z.size())
0058         add_disk = true;
0059       else
0060         assert(0);
0061 
0062       if (add_disk) {
0063         _mediumProperties.push_back(new MediumProperties(disk_thickness[j], 0.0001));
0064 
0065         const SimpleDiskBounds diskBounds(disk_inner_radius[j], disk_outer_radius[j], -0.0150, +0.0150);
0066         const Surface::PositionType positionType(0., 0., disk_z[j]);
0067 
0068         unsigned layerNr = i + j;
0069         BoundDisk* theDisk = new BoundDisk(positionType, theRotation2, diskBounds);
0070         theDisk->setMediumProperties(*_mediumProperties[_mediumProperties.size() - 1]);
0071         if (theDisk->mediumProperties().radLen() > 0.)
0072           _theCylinders.push_back(TrackerLayer(
0073               theDisk, true, layerNr, std::vector<double>(), std::vector<double>(), std::vector<double>()));
0074         else
0075           delete theDisk;
0076 
0077         j++;
0078 
0079       } else {
0080         // Create the nest of cylinders
0081 
0082         const SimpleCylinderBounds cylBounds(
0083             barrel_radius[i] - 0.0150, barrel_radius[i] + 0.0150, -barrel_length[i] / 2, +barrel_length[i] / 2);
0084 
0085         _mediumProperties.push_back(new MediumProperties(barrel_thickness[i], 0.0001));
0086 
0087         unsigned layerNr = i + j;
0088         BoundCylinder* theCylinder = new BoundCylinder(thePosition, theRotation, cylBounds);
0089         theCylinder->setMediumProperties(*_mediumProperties[_mediumProperties.size() - 1]);
0090         if (theCylinder->mediumProperties().radLen() > 0.)
0091           _theCylinders.push_back(TrackerLayer(
0092               theCylinder, false, layerNr, std::vector<double>(), std::vector<double>(), std::vector<double>()));
0093 
0094         else
0095           delete theCylinder;
0096 
0097         i++;
0098       }
0099     }
0100   } else {
0101     // Fraction of radiation length : had oc values to account
0102     // for detectors, cables, support, ...
0103     // Note : the second argument is not used in FAMOS
0104     // Note : the first argument is tuned to reproduce the CMSIM material
0105     //        in terms or radiation length.
0106 
0107     // Thickness of all layers
0108     // Version of the material description
0109     version = trackerMaterial.getParameter<unsigned int>("TrackerMaterialVersion");
0110     // Beam Pipe
0111     beamPipeThickness = trackerMaterial.getParameter<std::vector<double> >("BeamPipeThickness");
0112     // Pixel Barrel Layers 1-3
0113     pxbThickness = trackerMaterial.getParameter<std::vector<double> >("PXBThickness");
0114     // Pixel Barrel services at the end of layers 1-3
0115     pxb1CablesThickness = trackerMaterial.getParameter<std::vector<double> >("PXB1CablesThickness");
0116     pxb2CablesThickness = trackerMaterial.getParameter<std::vector<double> >("PXB2CablesThickness");
0117     pxb3CablesThickness = trackerMaterial.getParameter<std::vector<double> >("PXB3CablesThickness");
0118     // Pixel Barrel outside cables
0119     pxbOutCables1Thickness = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables1Thickness");
0120     pxbOutCables2Thickness = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables2Thickness");
0121     // Pixel Disks 1-2
0122     pxdThickness = trackerMaterial.getParameter<std::vector<double> >("PXDThickness");
0123     // Pixel Endcap outside cables
0124     pxdOutCables1Thickness = trackerMaterial.getParameter<std::vector<double> >("PXDOutCables1Thickness");
0125     pxdOutCables2Thickness = trackerMaterial.getParameter<std::vector<double> >("PXDOutCables2Thickness");
0126     // Tracker Inner barrel layers 1-4
0127     tibLayer1Thickness = trackerMaterial.getParameter<std::vector<double> >("TIBLayer1Thickness");
0128     tibLayer2Thickness = trackerMaterial.getParameter<std::vector<double> >("TIBLayer2Thickness");
0129     tibLayer3Thickness = trackerMaterial.getParameter<std::vector<double> >("TIBLayer3Thickness");
0130     tibLayer4Thickness = trackerMaterial.getParameter<std::vector<double> >("TIBLayer4Thickness");
0131     // TIB outside services (endcap)
0132     tibOutCables1Thickness = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables1Thickness");
0133     tibOutCables2Thickness = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables2Thickness");
0134     // Tracker Inner disks layers 1-3
0135     tidLayer1Thickness = trackerMaterial.getParameter<std::vector<double> >("TIDLayer1Thickness");
0136     tidLayer2Thickness = trackerMaterial.getParameter<std::vector<double> >("TIDLayer2Thickness");
0137     tidLayer3Thickness = trackerMaterial.getParameter<std::vector<double> >("TIDLayer3Thickness");
0138     // TID outside wall (endcap)
0139     tidOutsideThickness = trackerMaterial.getParameter<std::vector<double> >("TIDOutsideThickness");
0140     // TOB inside wall (barrel)
0141     tobInsideThickness = trackerMaterial.getParameter<std::vector<double> >("TOBInsideThickness");
0142     // Tracker Outer barrel layers 1-6
0143     tobLayer1Thickness = trackerMaterial.getParameter<std::vector<double> >("TOBLayer1Thickness");
0144     tobLayer2Thickness = trackerMaterial.getParameter<std::vector<double> >("TOBLayer2Thickness");
0145     tobLayer3Thickness = trackerMaterial.getParameter<std::vector<double> >("TOBLayer3Thickness");
0146     tobLayer4Thickness = trackerMaterial.getParameter<std::vector<double> >("TOBLayer4Thickness");
0147     tobLayer5Thickness = trackerMaterial.getParameter<std::vector<double> >("TOBLayer5Thickness");
0148     tobLayer6Thickness = trackerMaterial.getParameter<std::vector<double> >("TOBLayer6Thickness");
0149     // TOB services (endcap)
0150     tobOutsideThickness = trackerMaterial.getParameter<std::vector<double> >("TOBOutsideThickness");
0151     // Tracker EndCap disks layers 1-9
0152     tecLayerThickness = trackerMaterial.getParameter<std::vector<double> >("TECLayerThickness");
0153     // TOB outside wall (barrel)
0154     barrelCablesThickness = trackerMaterial.getParameter<std::vector<double> >("BarrelCablesThickness");
0155     // TEC outside wall (endcap)
0156     endcapCables1Thickness = trackerMaterial.getParameter<std::vector<double> >("EndcapCables1Thickness");
0157     endcapCables2Thickness = trackerMaterial.getParameter<std::vector<double> >("EndcapCables2Thickness");
0158 
0159     // Position of dead material layers (cables, services, etc.)
0160     // Beam pipe
0161     beamPipeRadius = trackerMaterial.getParameter<std::vector<double> >("BeamPipeRadius");
0162     beamPipeLength = trackerMaterial.getParameter<std::vector<double> >("BeamPipeLength");
0163     // Cables and Services at the end of PIXB1,2,3 ("disk")
0164     pxb1CablesInnerRadius = trackerMaterial.getParameter<std::vector<double> >("PXB1CablesInnerRadius");
0165     pxb2CablesInnerRadius = trackerMaterial.getParameter<std::vector<double> >("PXB2CablesInnerRadius");
0166     pxb3CablesInnerRadius = trackerMaterial.getParameter<std::vector<double> >("PXB3CablesInnerRadius");
0167     // Pixel Barrel Outside walls and cables
0168     pxbOutCables1InnerRadius = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables1InnerRadius");
0169     pxbOutCables1OuterRadius = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables1OuterRadius");
0170     pxbOutCables1ZPosition = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables1ZPosition");
0171     pxbOutCables2InnerRadius = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables2InnerRadius");
0172     pxbOutCables2OuterRadius = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables2OuterRadius");
0173     pxbOutCables2ZPosition = trackerMaterial.getParameter<std::vector<double> >("PXBOutCables2ZPosition");
0174     // Pixel Outside walls and cables (barrel and endcaps)
0175     pixelOutCablesRadius = trackerMaterial.getParameter<std::vector<double> >("PixelOutCablesRadius");
0176     pixelOutCablesLength = trackerMaterial.getParameter<std::vector<double> >("PixelOutCablesLength");
0177     pixelOutCablesInnerRadius = trackerMaterial.getParameter<std::vector<double> >("PixelOutCablesInnerRadius");
0178     pixelOutCablesOuterRadius = trackerMaterial.getParameter<std::vector<double> >("PixelOutCablesOuterRadius");
0179     pixelOutCablesZPosition = trackerMaterial.getParameter<std::vector<double> >("PixelOutCablesZPosition");
0180     // Tracker Inner Barrel Outside Cables and walls (endcap)
0181     tibOutCables1InnerRadius = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables1InnerRadius");
0182     tibOutCables1OuterRadius = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables1OuterRadius");
0183     tibOutCables1ZPosition = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables1ZPosition");
0184     tibOutCables2InnerRadius = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables2InnerRadius");
0185     tibOutCables2OuterRadius = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables2OuterRadius");
0186     tibOutCables2ZPosition = trackerMaterial.getParameter<std::vector<double> >("TIBOutCables2ZPosition");
0187     // Tracker outer barrel Inside wall (barrel)
0188     tobInCablesRadius = trackerMaterial.getParameter<std::vector<double> >("TOBInCablesRadius");
0189     tobInCablesLength = trackerMaterial.getParameter<std::vector<double> >("TOBInCablesLength");
0190     // Tracker Inner Disks Outside Cables and walls
0191     tidOutCablesInnerRadius = trackerMaterial.getParameter<std::vector<double> >("TIDOutCablesInnerRadius");
0192     tidOutCablesZPosition = trackerMaterial.getParameter<std::vector<double> >("TIDOutCablesZPosition");
0193     // Tracker Outer Barrel Outside Cables and walls (barrel and endcaps)
0194     tobOutCablesInnerRadius = trackerMaterial.getParameter<std::vector<double> >("TOBOutCablesInnerRadius");
0195     tobOutCablesOuterRadius = trackerMaterial.getParameter<std::vector<double> >("TOBOutCablesOuterRadius");
0196     tobOutCablesZPosition = trackerMaterial.getParameter<std::vector<double> >("TOBOutCablesZPosition");
0197     tobOutCablesRadius = trackerMaterial.getParameter<std::vector<double> >("TOBOutCablesRadius");
0198     tobOutCablesLength = trackerMaterial.getParameter<std::vector<double> >("TOBOutCablesLength");
0199     // Tracker Endcaps Outside Cables and walls
0200     tecOutCables1InnerRadius = trackerMaterial.getParameter<std::vector<double> >("TECOutCables1InnerRadius");
0201     tecOutCables1OuterRadius = trackerMaterial.getParameter<std::vector<double> >("TECOutCables1OuterRadius");
0202     tecOutCables1ZPosition = trackerMaterial.getParameter<std::vector<double> >("TECOutCables1ZPosition");
0203     tecOutCables2InnerRadius = trackerMaterial.getParameter<std::vector<double> >("TECOutCables2InnerRadius");
0204     tecOutCables2OuterRadius = trackerMaterial.getParameter<std::vector<double> >("TECOutCables2OuterRadius");
0205     tecOutCables2ZPosition = trackerMaterial.getParameter<std::vector<double> >("TECOutCables2ZPosition");
0206 
0207     // Fudge factors for tracker layer material inhomogeneities
0208     fudgeLayer = trackerMaterial.getParameter<std::vector<unsigned int> >("FudgeLayer");
0209     fudgeMin = trackerMaterial.getParameter<std::vector<double> >("FudgeMin");
0210     fudgeMax = trackerMaterial.getParameter<std::vector<double> >("FudgeMax");
0211     fudgeFactor = trackerMaterial.getParameter<std::vector<double> >("FudgeFactor");
0212 
0213     // The previous std::vector must have the same size!
0214     if (fudgeLayer.size() != fudgeMin.size() || fudgeLayer.size() != fudgeMax.size() ||
0215         fudgeLayer.size() != fudgeFactor.size()) {
0216       throw cms::Exception("FastSimulation/TrackerInteractionGeometry ")
0217           << " WARNING with fudge factors !  You have " << fudgeLayer.size() << " layers, but " << fudgeMin.size()
0218           << " min values, " << fudgeMax.size() << " max values and " << fudgeFactor.size() << " fudge factor values!"
0219           << std::endl
0220           << "Please make enter the same number of inputs "
0221           << "in FastSimulation/TrackerInteractionGeometry/data/TrackerMaterial.cfi" << std::endl;
0222     }
0223 
0224     // The Beam pipe
0225     _theMPBeamPipe = new MediumProperties(beamPipeThickness[version], 0.0001);
0226     // The pixel barrel layers
0227     _theMPPixelBarrel = new MediumProperties(pxbThickness[version], 0.0001);
0228     // Pixel Barrel services at the end of layers 1-3
0229     _theMPPixelOutside1 = new MediumProperties(pxb1CablesThickness[version], 0.0001);
0230     _theMPPixelOutside2 = new MediumProperties(pxb2CablesThickness[version], 0.0001);
0231     _theMPPixelOutside3 = new MediumProperties(pxb3CablesThickness[version], 0.0001);
0232     // Pixel Barrel outside cables
0233     _theMPPixelOutside4 = new MediumProperties(pxbOutCables1Thickness[version], 0.0001);
0234     _theMPPixelOutside = new MediumProperties(pxbOutCables2Thickness[version], 0.0001);
0235     // The pixel endcap disks
0236     _theMPPixelEndcap = new MediumProperties(pxdThickness[version], 0.0001);
0237     // Pixel Endcap outside cables
0238     _theMPPixelOutside5 = new MediumProperties(pxdOutCables1Thickness[version], 0.0001);
0239     _theMPPixelOutside6 = new MediumProperties(pxdOutCables2Thickness[version], 0.0001);
0240     // The tracker inner barrel layers 1-4
0241     _theMPTIB1 = new MediumProperties(tibLayer1Thickness[version], 0.0001);
0242     _theMPTIB2 = new MediumProperties(tibLayer2Thickness[version], 0.0001);
0243     _theMPTIB3 = new MediumProperties(tibLayer3Thickness[version], 0.0001);
0244     _theMPTIB4 = new MediumProperties(tibLayer4Thickness[version], 0.0001);
0245     // TIB outside services (endcap)
0246     _theMPTIBEOutside1 = new MediumProperties(tibOutCables1Thickness[version], 0.0001);
0247     _theMPTIBEOutside2 = new MediumProperties(tibOutCables2Thickness[version], 0.0001);
0248     // The tracker inner disks 1-3
0249     _theMPInner1 = new MediumProperties(tidLayer1Thickness[version], 0.0001);
0250     _theMPInner2 = new MediumProperties(tidLayer2Thickness[version], 0.0001);
0251     _theMPInner3 = new MediumProperties(tidLayer3Thickness[version], 0.0001);
0252     // TID outside wall (endcap)
0253     _theMPTIDEOutside = new MediumProperties(tidOutsideThickness[version], 0.0001);
0254     // TOB inside wall (barrel)
0255     _theMPTOBBInside = new MediumProperties(tobInsideThickness[version], 0.0001);
0256     // The tracker outer barrel layers 1-6
0257     _theMPTOB1 = new MediumProperties(tobLayer1Thickness[version], 0.0001);
0258     _theMPTOB2 = new MediumProperties(tobLayer2Thickness[version], 0.0001);
0259     _theMPTOB3 = new MediumProperties(tobLayer3Thickness[version], 0.0001);
0260     _theMPTOB4 = new MediumProperties(tobLayer4Thickness[version], 0.0001);
0261     _theMPTOB5 = new MediumProperties(tobLayer5Thickness[version], 0.0001);
0262     _theMPTOB6 = new MediumProperties(tobLayer6Thickness[version], 0.0001);
0263     // TOB services (endcap)
0264     _theMPTOBEOutside = new MediumProperties(tobOutsideThickness[version], 0.0001);
0265     // The tracker endcap disks 1-9
0266     _theMPEndcap = new MediumProperties(tecLayerThickness[version], 0.0001);
0267     // TOB outside wall (barrel)
0268     _theMPBarrelOutside = new MediumProperties(barrelCablesThickness[version], 0.0001);
0269     // TEC outside wall (endcap)
0270     _theMPEndcapOutside = new MediumProperties(endcapCables1Thickness[version], 0.0001);
0271     _theMPEndcapOutside2 = new MediumProperties(endcapCables2Thickness[version], 0.0001);
0272 
0273     // Check that the Reco Tracker Geometry has been loaded
0274     if (!theGeomSearchTracker)
0275       throw cms::Exception("FastSimulation/TrackerInteractionGeometry")
0276           << "The pointer to the GeometricSearchTracker was not set";
0277 
0278     // The vector of Barrel Tracker Layers
0279     auto const& barrelLayers = theGeomSearchTracker->barrelLayers();
0280 
0281     // The vector of Forward Tracker Layers (positive z)
0282     auto const& posForwardLayers = theGeomSearchTracker->posForwardLayers();
0283 
0284     // Local pointers
0285     BoundCylinder* theCylinder;
0286     BoundDisk* theDisk;
0287 
0288     // Create the nest of cylinders
0289     const Surface::PositionType thePosition(0., 0., 0.);
0290     const Surface::RotationType theRotation(1., 0., 0., 0., 1., 0., 0., 0., 1.);
0291     // Beam Pipe
0292     //  const SimpleCylinderBounds  PIPE( 0.997,   1.003,  -300., 300.);
0293     const SimpleCylinderBounds PIPE(beamPipeRadius[version] - 0.003,
0294                                     beamPipeRadius[version] + 0.003,
0295                                     -beamPipeLength[version],
0296                                     beamPipeLength[version]);
0297 
0298     // Take the active layer position from the Tracker Reco Geometry
0299     // Pixel barrel
0300     auto bl = barrelLayers.begin();
0301     double maxLength = (**bl).specificSurface().bounds().length() / 2. + 1.7;
0302     double maxRadius = (**bl).specificSurface().radius() + 0.01;
0303     // First pixel barrel layer: r=4.41058, l=53.38
0304     const SimpleCylinderBounds PIXB1(maxRadius - 0.005, maxRadius + 0.005, -maxLength, +maxLength);
0305     // "Cables"
0306     const SimpleDiskBounds PIXBOut1(pxb1CablesInnerRadius[version], maxRadius + 0.01, -0.5, 0.5);
0307     const Surface::PositionType PPIXBOut1(0.0, 0.0, maxLength);
0308 
0309     // Second pixel barrel layer: r=7.30732, l=53.38
0310     ++bl;
0311     maxLength = std::max((**bl).specificSurface().bounds().length() / 2. + 1.7, maxLength + 0.000);
0312     maxRadius = (**bl).specificSurface().radius();
0313     const SimpleCylinderBounds PIXB2(maxRadius - 0.005, maxRadius + 0.005, -maxLength, +maxLength);
0314 
0315     // "Cables"
0316     const SimpleDiskBounds PIXBOut2(pxb2CablesInnerRadius[version], maxRadius + 0.005, -0.5, 0.5);
0317     const Surface::PositionType PPIXBOut2(0.0, 0.0, maxLength);
0318 
0319     // More cables
0320     ++bl;
0321     maxRadius = (**bl).specificSurface().radius();
0322     const SimpleDiskBounds PIXBOut3(pxb3CablesInnerRadius[version], maxRadius, -0.5, 0.5);
0323     const Surface::PositionType PPIXBOut3(0.0, 0.0, maxLength);
0324 
0325     // Third pixel barrel layer: r=10.1726, l=53.38
0326     maxLength = std::max((**bl).specificSurface().bounds().length() / 2. + 1.7, maxLength + 0.000);
0327     const SimpleCylinderBounds PIXB3(maxRadius - 0.005, maxRadius + 0.005, -maxLength, +maxLength);
0328 
0329     // Pixel Barrel Outside walls and cables
0330     const SimpleDiskBounds PIXBOut4(pxbOutCables1InnerRadius[version], pxbOutCables1OuterRadius[version], -0.5, 0.5);
0331     const Surface::PositionType PPIXBOut4(0.0, 0.0, pxbOutCables1ZPosition[version]);
0332 
0333     const SimpleDiskBounds PIXBOut(pxbOutCables2InnerRadius[version], pxbOutCables2OuterRadius[version], -0.5, 0.5);
0334     const Surface::PositionType PPIXBOut(0.0, 0.0, pxbOutCables2ZPosition[version]);
0335 
0336     const SimpleCylinderBounds PIXBOut5(pixelOutCablesRadius[version] - 0.1,
0337                                         pixelOutCablesRadius[version] + 0.1,
0338                                         -pixelOutCablesLength[version],
0339                                         pixelOutCablesLength[version]);
0340 
0341     const SimpleDiskBounds PIXBOut6(pixelOutCablesInnerRadius[version], pixelOutCablesOuterRadius[version], -0.5, 0.5);
0342     const Surface::PositionType PPIXBOut6(0.0, 0.0, pixelOutCablesZPosition[version]);
0343 
0344     // Tracker Inner Barrel : thin detectors (300 microns)
0345     // First TIB layer: r=25.6786, l=130.04
0346     ++bl;
0347     maxRadius = (**bl).specificSurface().radius();
0348     maxLength = (**bl).specificSurface().bounds().length() / 2.;
0349     const SimpleCylinderBounds TIB1(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0350     // Second TIB layer: r=34.0341, l=131.999
0351     ++bl;
0352     maxRadius = (**bl).specificSurface().radius();
0353     maxLength = std::max((**bl).specificSurface().bounds().length() / 2., maxLength + 0.000);
0354     const SimpleCylinderBounds TIB2(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0355     // Third TIB layer: r=41.9599, l=131.628  !!!! Needs to be larger than TIB2
0356     ++bl;
0357     maxRadius = (**bl).specificSurface().radius();
0358     maxLength = std::max((**bl).specificSurface().bounds().length() / 2., maxLength + 0.000);
0359     const SimpleCylinderBounds TIB3(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0360     // Fourth TIB layer: r=49.8924, l=132.78
0361     ++bl;
0362     maxRadius = (**bl).specificSurface().radius();
0363     maxLength = std::max((**bl).specificSurface().bounds().length() / 2., maxLength + 0.000);
0364     const SimpleCylinderBounds TIB4(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0365 
0366     // Inner Barrel Cylinder & Ends : Cables and walls
0367     const SimpleDiskBounds TIBEOut(tibOutCables1InnerRadius[version], tibOutCables1OuterRadius[version], -0.05, 0.05);
0368     const Surface::PositionType PTIBEOut(0.0, 0.0, tibOutCables1ZPosition[version]);
0369 
0370     const SimpleDiskBounds TIBEOut2(tibOutCables2InnerRadius[version], tibOutCables2OuterRadius[version], -0.05, 0.05);
0371     const Surface::PositionType PTIBEOut2(0.0, 0.0, tibOutCables2ZPosition[version]);
0372 
0373     // Inner Tracker / Outer Barrel Wall
0374     const SimpleCylinderBounds TOBCIn(tobInCablesRadius[version] - 0.5,
0375                                       tobInCablesRadius[version] + 0.5,
0376                                       -tobInCablesLength[version],
0377                                       tobInCablesLength[version]);
0378 
0379     // First TOB layer: r=60.7671, l=216.576
0380     ++bl;
0381     maxRadius = (**bl).specificSurface().radius();
0382     maxLength = (**bl).specificSurface().bounds().length() / 2. + 0.0;
0383     const SimpleCylinderBounds TOB1(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0384     // Second TOB layer: r=69.3966, l=216.576
0385     ++bl;
0386     maxRadius = (**bl).specificSurface().radius();
0387     maxLength = std::max((**bl).specificSurface().bounds().length() / 2. + 0.0, maxLength + 0.000);
0388     const SimpleCylinderBounds TOB2(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0389     // Third TOB layer: r=78.0686, l=216.576
0390     ++bl;
0391     maxRadius = (**bl).specificSurface().radius();
0392     maxLength = std::max((**bl).specificSurface().bounds().length() / 2. + 0.0, maxLength + 0.000);
0393     const SimpleCylinderBounds TOB3(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0394     // Fourth TOB layer: r=86.8618, l=216.576
0395     ++bl;
0396     maxRadius = (**bl).specificSurface().radius();
0397     maxLength = std::max((**bl).specificSurface().bounds().length() / 2. + 0.0, maxLength + 0.000);
0398     const SimpleCylinderBounds TOB4(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0399     // Fifth TOB layer: r=96.5557, l=216.576
0400     ++bl;
0401     maxRadius = (**bl).specificSurface().radius();
0402     maxLength = std::max((**bl).specificSurface().bounds().length() / 2. + 0.0, maxLength + 0.000);
0403     const SimpleCylinderBounds TOB5(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0404     // Sixth TOB layer: r=108.05, l=216.576
0405     ++bl;
0406     maxRadius = (**bl).specificSurface().radius();
0407     maxLength = std::max((**bl).specificSurface().bounds().length() / 2. + 0.0, maxLength + 0.000);
0408     const SimpleCylinderBounds TOB6(maxRadius - 0.0150, maxRadius + 0.0150, -maxLength, +maxLength);
0409 
0410     const SimpleDiskBounds TOBEOut(tobOutCablesInnerRadius[version], tobOutCablesOuterRadius[version], -0.5, 0.5);
0411     const Surface::PositionType PTOBEOut(0.0, 0.0, tobOutCablesZPosition[version]);
0412 
0413     const Surface::RotationType theRotation2(1., 0., 0., 0., 1., 0., 0., 0., 1.);
0414 
0415     // Outside : Barrel
0416     const SimpleCylinderBounds TBOut(tobOutCablesRadius[version] - 0.5,
0417                                      tobOutCablesRadius[version] + 0.5,
0418                                      -tobOutCablesLength[version],
0419                                      tobOutCablesLength[version]);
0420 
0421     // And now the disks...
0422     auto fl = posForwardLayers.begin();
0423 
0424     // Pixel disks
0425     // First Pixel disk: Z pos 35.5 radii 5.42078, 16.0756
0426     double innerRadius = (**fl).specificSurface().innerRadius() - 1.0;
0427     double outerRadius = (**fl).specificSurface().outerRadius() + 2.0;
0428     const SimpleDiskBounds PIXD1(innerRadius, outerRadius, -0.0150, +0.0150);
0429     const Surface::PositionType PPIXD1(0.0, 0.0, (**fl).surface().position().z());
0430     // Second Pixel disk: Z pos 48.5 radii 5.42078, 16.0756
0431     ++fl;
0432     innerRadius = (**fl).specificSurface().innerRadius() - 1.0;
0433     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0434     const SimpleDiskBounds PIXD2(innerRadius, outerRadius, -0.0150, +0.0150);
0435     const Surface::PositionType PPIXD2(0.0, 0.0, (**fl).surface().position().z());
0436 
0437     // Tracker Inner disks (add 3 cm for the outer radius to simulate cables,
0438     // and remove 1cm to inner radius to allow for some extrapolation margin)
0439     // First TID : Z pos 78.445 radii 23.14, 50.4337
0440     ++fl;
0441     innerRadius = (**fl).specificSurface().innerRadius() - 0.5;
0442     outerRadius = (**fl).specificSurface().outerRadius() + 3.5;
0443     const SimpleDiskBounds TID1(innerRadius, outerRadius, -0.0150, +0.0150);
0444     const Surface::PositionType PTID1(0., 0., (**fl).surface().position().z());
0445     // Second TID : Z pos 90.445 radii 23.14, 50.4337
0446     ++fl;
0447     innerRadius = (**fl).specificSurface().innerRadius() - 0.5;
0448     outerRadius = std::max((**fl).specificSurface().outerRadius() + 3.5, outerRadius + 0.000);
0449     const SimpleDiskBounds TID2(innerRadius, outerRadius, -0.0150, +0.0150);
0450     const Surface::PositionType PTID2(0., 0., (**fl).surface().position().z());
0451     // Third TID : Z pos 105.445 radii 23.14, 50.4337
0452     ++fl;
0453     innerRadius = (**fl).specificSurface().innerRadius() - 0.5;
0454     outerRadius = std::max((**fl).specificSurface().outerRadius() + 3.5, outerRadius + 0.000);
0455     const SimpleDiskBounds TID3(innerRadius, outerRadius, -0.0150, +0.0150);
0456     const Surface::PositionType PTID3(0., 0., (**fl).surface().position().z());
0457 
0458     // TID Wall and cables
0459     const SimpleDiskBounds TIDEOut(tidOutCablesInnerRadius[version], outerRadius + 1.0, -0.5, 0.5);
0460     const Surface::PositionType PTIDEOut(0.0, 0.0, tidOutCablesZPosition[version]);
0461 
0462     // Tracker Endcaps : Add 11 cm to outer radius to correct for a bug, remove
0463     // 5cm to the inner radius (TEC7,8,9) to correct for a simular bug, and
0464     // remove other 2cm to inner radius to allow for some extrapolation margin
0465     // First TEC: Z pos 131.892 radii 23.3749, 99.1967
0466     ++fl;
0467     innerRadius = (**fl).specificSurface().innerRadius() - 1.5;
0468     outerRadius = (**fl).specificSurface().outerRadius() + 2.0;
0469     const SimpleDiskBounds TEC1(innerRadius, outerRadius, -0.0150, +0.0150);
0470     const Surface::PositionType PTEC1(0., 0, (**fl).surface().position().z());
0471     // Second TEC: Z pos 145.892 radii 23.3749, 99.1967
0472     ++fl;
0473     innerRadius = (**fl).specificSurface().innerRadius() - 1.5;
0474     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0475     const SimpleDiskBounds TEC2(innerRadius, outerRadius, -0.0150, +0.0150);
0476     const Surface::PositionType PTEC2(0., 0., (**fl).surface().position().z());
0477     // Third TEC: Z pos 159.892 radii 23.3749, 99.1967
0478     ++fl;
0479     innerRadius = (**fl).specificSurface().innerRadius() - 1.5;
0480     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0481     const SimpleDiskBounds TEC3(innerRadius, outerRadius, -0.0150, +0.0150);
0482     const Surface::PositionType PTEC3(0., 0., (**fl).surface().position().z());
0483     // Fourth TEC: Z pos 173.892 radii 32.1263, 99.1967
0484     ++fl;
0485     innerRadius = (**fl).specificSurface().innerRadius() - 2.5;
0486     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0487     const SimpleDiskBounds TEC4(innerRadius, outerRadius, -0.0150, +0.0150);
0488     const Surface::PositionType PTEC4(0., 0., (**fl).surface().position().z());
0489     // Fifth TEC: Z pos 187.892 radii 32.1263, 99.1967
0490     ++fl;
0491     innerRadius = (**fl).specificSurface().innerRadius() - 2.5;
0492     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0493     const SimpleDiskBounds TEC5(innerRadius, outerRadius, -0.0150, +0.0150);
0494     const Surface::PositionType PTEC5(0., 0., (**fl).surface().position().z());
0495     // Sixth TEC: Z pos 205.392 radii 32.1263, 99.1967
0496     ++fl;
0497     innerRadius = (**fl).specificSurface().innerRadius() - 2.5;
0498     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0499     const SimpleDiskBounds TEC6(innerRadius, outerRadius, -0.0150, +0.0150);
0500     const Surface::PositionType PTEC6(0., 0., (**fl).surface().position().z());
0501     // Seventh TEC: Z pos 224.121 radii 44.7432, 99.1967
0502     ++fl;
0503     innerRadius = (**fl).specificSurface().innerRadius() - 9.5;
0504     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0505     const SimpleDiskBounds TEC7(innerRadius, outerRadius, -0.0150, +0.0150);
0506     const Surface::PositionType PTEC7(0., 0., (**fl).surface().position().z());
0507     // Eighth TEC: Z pos 244.621 radii 44.7432, 99.1967
0508     ++fl;
0509     innerRadius = (**fl).specificSurface().innerRadius() - 9.5;
0510     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0511     const SimpleDiskBounds TEC8(innerRadius, outerRadius, -0.0150, +0.0150);
0512     const Surface::PositionType PTEC8(0., 0., (**fl).surface().position().z());
0513     // Nineth TEC: Z pos 266.121 radii 56.1781, 99.1967
0514     ++fl;
0515     innerRadius = (**fl).specificSurface().innerRadius() - 20.5;
0516     outerRadius = std::max((**fl).specificSurface().outerRadius() + 2.0, outerRadius + 0.000);
0517     const SimpleDiskBounds TEC9(innerRadius, outerRadius, -0.0150, +0.0150);
0518     const Surface::PositionType PTEC9(0., 0., (**fl).surface().position().z());
0519 
0520     // Outside : Endcap
0521     const SimpleDiskBounds TEOut(tecOutCables1InnerRadius[version], tecOutCables1OuterRadius[version], -0.5, 0.5);
0522     const Surface::PositionType PTEOut(0.0, 0.0, tecOutCables1ZPosition[version]);
0523 
0524     const SimpleDiskBounds TEOut2(tecOutCables2InnerRadius[version], tecOutCables2OuterRadius[version], -0.5, 0.5);
0525     const Surface::PositionType PTEOut2(0.0, 0.0, tecOutCables2ZPosition[version]);
0526 
0527     // The ordering of disks and cylinders is essential here
0528     // (from inside to outside)
0529     // Do not change it thoughtlessly.
0530 
0531     // Beam Pipe
0532 
0533     unsigned layerNr = 100;
0534     theCylinder = new BoundCylinder(thePosition, theRotation, PIPE);
0535     theCylinder->setMediumProperties(*_theMPBeamPipe);
0536     if (theCylinder->mediumProperties().radLen() > 0.)
0537       _theCylinders.push_back(
0538           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0539     else
0540       delete theCylinder;
0541 
0542     // Pixels
0543 
0544     layerNr = TrackerInteractionGeometry::PXB + 1;
0545     theCylinder = new BoundCylinder(thePosition, theRotation, PIXB1);
0546     theCylinder->setMediumProperties(*_theMPPixelBarrel);
0547     if (theCylinder->mediumProperties().radLen() > 0.)
0548       _theCylinders.push_back(
0549           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0550     else
0551       delete theCylinder;
0552 
0553     layerNr = 101;
0554     theDisk = new BoundDisk(PPIXBOut1, theRotation2, PIXBOut1);
0555     theDisk->setMediumProperties(*_theMPPixelOutside1);
0556     if (theDisk->mediumProperties().radLen() > 0.)
0557       _theCylinders.push_back(
0558           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0559     else
0560       delete theDisk;
0561 
0562     layerNr = TrackerInteractionGeometry::PXB + 2;
0563     theCylinder = new BoundCylinder(thePosition, theRotation, PIXB2);
0564     theCylinder->setMediumProperties(*_theMPPixelBarrel);
0565     if (theCylinder->mediumProperties().radLen() > 0.)
0566       _theCylinders.push_back(
0567           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0568     else
0569       delete theCylinder;
0570 
0571     layerNr = 102;
0572     theDisk = new BoundDisk(PPIXBOut2, theRotation2, PIXBOut2);
0573     theDisk->setMediumProperties(*_theMPPixelOutside2);
0574     if (theDisk->mediumProperties().radLen() > 0.)
0575       _theCylinders.push_back(
0576           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0577     else
0578       delete theDisk;
0579 
0580     layerNr = 103;
0581     theDisk = new BoundDisk(PPIXBOut3, theRotation2, PIXBOut3);
0582     theDisk->setMediumProperties(*_theMPPixelOutside3);
0583     if (theDisk->mediumProperties().radLen() > 0.)
0584       _theCylinders.push_back(
0585           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0586     else
0587       delete theDisk;
0588 
0589     layerNr = TrackerInteractionGeometry::PXB + 3;
0590     theCylinder = new BoundCylinder(thePosition, theRotation, PIXB3);
0591     theCylinder->setMediumProperties(*_theMPPixelBarrel);
0592     if (theCylinder->mediumProperties().radLen() > 0.)
0593       _theCylinders.push_back(
0594           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0595     else
0596       delete theCylinder;
0597 
0598     layerNr = 104;
0599     theDisk = new BoundDisk(PPIXBOut4, theRotation2, PIXBOut4);
0600     theDisk->setMediumProperties(*_theMPPixelOutside4);
0601     if (theDisk->mediumProperties().radLen() > 0.)
0602       _theCylinders.push_back(
0603           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0604     else
0605       delete theDisk;
0606 
0607     layerNr = 105;
0608     theDisk = new BoundDisk(PPIXBOut, theRotation2, PIXBOut);
0609     theDisk->setMediumProperties(*_theMPPixelOutside);
0610     if (theDisk->mediumProperties().radLen() > 0.)
0611       _theCylinders.push_back(
0612           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0613     else
0614       delete theDisk;
0615 
0616     layerNr = TrackerInteractionGeometry::PXD + 1;
0617     theDisk = new BoundDisk(PPIXD1, theRotation2, PIXD1);
0618     theDisk->setMediumProperties(*_theMPPixelEndcap);
0619     if (theDisk->mediumProperties().radLen() > 0.)
0620       _theCylinders.push_back(
0621           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0622     else
0623       delete theDisk;
0624 
0625     layerNr = TrackerInteractionGeometry::PXD + 2;
0626     theDisk = new BoundDisk(PPIXD2, theRotation2, PIXD2);
0627     theDisk->setMediumProperties(*_theMPPixelEndcap);
0628     if (theDisk->mediumProperties().radLen() > 0.)
0629       _theCylinders.push_back(
0630           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0631     else
0632       delete theDisk;
0633 
0634     layerNr = 106;
0635     theCylinder = new BoundCylinder(thePosition, theRotation, PIXBOut5);
0636     theCylinder->setMediumProperties(*_theMPPixelOutside5);
0637     if (theCylinder->mediumProperties().radLen() > 0.)
0638       _theCylinders.push_back(
0639           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0640     else
0641       delete theCylinder;
0642 
0643     layerNr = 107;
0644     theDisk = new BoundDisk(PPIXBOut6, theRotation2, PIXBOut6);
0645     theDisk->setMediumProperties(*_theMPPixelOutside6);
0646     if (theDisk->mediumProperties().radLen() > 0.)
0647       _theCylinders.push_back(
0648           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0649     else
0650       delete theDisk;
0651 
0652     // Inner Barrel
0653 
0654     layerNr = TrackerInteractionGeometry::TIB + 1;
0655     theCylinder = new BoundCylinder(thePosition, theRotation, TIB1);
0656     theCylinder->setMediumProperties(*_theMPTIB1);
0657     if (theCylinder->mediumProperties().radLen() > 0.)
0658       _theCylinders.push_back(
0659           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0660     else
0661       delete theCylinder;
0662 
0663     layerNr = TrackerInteractionGeometry::TIB + 2;
0664     theCylinder = new BoundCylinder(thePosition, theRotation, TIB2);
0665     theCylinder->setMediumProperties(*_theMPTIB2);
0666     if (theCylinder->mediumProperties().radLen() > 0.)
0667       _theCylinders.push_back(
0668           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0669     else
0670       delete theCylinder;
0671 
0672     layerNr = TrackerInteractionGeometry::TIB + 3;
0673     theCylinder = new BoundCylinder(thePosition, theRotation, TIB3);
0674     theCylinder->setMediumProperties(*_theMPTIB3);
0675     if (theCylinder->mediumProperties().radLen() > 0.)
0676       _theCylinders.push_back(
0677           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0678     else
0679       delete theCylinder;
0680 
0681     layerNr = TrackerInteractionGeometry::TIB + 4;
0682     theCylinder = new BoundCylinder(thePosition, theRotation, TIB4);
0683     theCylinder->setMediumProperties(*_theMPTIB4);
0684     if (theCylinder->mediumProperties().radLen() > 0.)
0685       _theCylinders.push_back(
0686           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0687     else
0688       delete theCylinder;
0689 
0690     layerNr = 108;
0691     theDisk = new BoundDisk(PTIBEOut, theRotation2, TIBEOut);
0692     theDisk->setMediumProperties(*_theMPTIBEOutside1);
0693     if (theDisk->mediumProperties().radLen() > 0.)
0694       _theCylinders.push_back(
0695           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0696     else
0697       delete theDisk;
0698 
0699     layerNr = 109;
0700     theDisk = new BoundDisk(PTIBEOut2, theRotation2, TIBEOut2);
0701     theDisk->setMediumProperties(*_theMPTIBEOutside2);
0702     if (theDisk->mediumProperties().radLen() > 0.)
0703       _theCylinders.push_back(
0704           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0705     else
0706       delete theDisk;
0707 
0708     // Inner Endcaps
0709 
0710     layerNr = TrackerInteractionGeometry::TID + 1;
0711     theDisk = new BoundDisk(PTID1, theRotation2, TID1);
0712     theDisk->setMediumProperties(*_theMPInner1);
0713     if (theDisk->mediumProperties().radLen() > 0.)
0714       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0715     else
0716       delete theDisk;
0717 
0718     layerNr = TrackerInteractionGeometry::TID + 2;
0719     theDisk = new BoundDisk(PTID2, theRotation2, TID2);
0720     theDisk->setMediumProperties(*_theMPInner2);
0721     if (theDisk->mediumProperties().radLen() > 0.)
0722       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0723 
0724     else
0725       delete theDisk;
0726 
0727     layerNr = TrackerInteractionGeometry::TID + 3;
0728     theDisk = new BoundDisk(PTID3, theRotation2, TID3);
0729     theDisk->setMediumProperties(*_theMPInner3);
0730     if (theDisk->mediumProperties().radLen() > 0.)
0731       _theCylinders.push_back(
0732           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0733     else
0734       delete theDisk;
0735 
0736     layerNr = 110;
0737     theDisk = new BoundDisk(PTIDEOut, theRotation2, TIDEOut);
0738     theDisk->setMediumProperties(*_theMPTIDEOutside);
0739     if (theDisk->mediumProperties().radLen() > 0.)
0740       _theCylinders.push_back(
0741           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0742     else
0743       delete theDisk;
0744 
0745     // Outer Barrel
0746 
0747     layerNr = 111;
0748     theCylinder = new BoundCylinder(thePosition, theRotation, TOBCIn);
0749     theCylinder->setMediumProperties(*_theMPTOBBInside);
0750     if (theCylinder->mediumProperties().radLen() > 0.)
0751       _theCylinders.push_back(
0752           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0753     else
0754       delete theCylinder;
0755 
0756     layerNr = TrackerInteractionGeometry::TOB + 1;
0757     theCylinder = new BoundCylinder(thePosition, theRotation, TOB1);
0758     theCylinder->setMediumProperties(*_theMPTOB1);
0759     if (theCylinder->mediumProperties().radLen() > 0.)
0760       _theCylinders.push_back(
0761           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0762     else
0763       delete theCylinder;
0764 
0765     layerNr = TrackerInteractionGeometry::TOB + 2;
0766     theCylinder = new BoundCylinder(thePosition, theRotation, TOB2);
0767     theCylinder->setMediumProperties(*_theMPTOB2);
0768     if (theCylinder->mediumProperties().radLen() > 0.)
0769       _theCylinders.push_back(
0770           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0771     else
0772       delete theCylinder;
0773 
0774     layerNr = TrackerInteractionGeometry::TOB + 3;
0775     theCylinder = new BoundCylinder(thePosition, theRotation, TOB3);
0776     theCylinder->setMediumProperties(*_theMPTOB3);
0777     if (theCylinder->mediumProperties().radLen() > 0.)
0778       _theCylinders.push_back(
0779           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0780     else
0781       delete theCylinder;
0782 
0783     layerNr = TrackerInteractionGeometry::TOB + 4;
0784     theCylinder = new BoundCylinder(thePosition, theRotation, TOB4);
0785     theCylinder->setMediumProperties(*_theMPTOB4);
0786     if (theCylinder->mediumProperties().radLen() > 0.)
0787       _theCylinders.push_back(
0788           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0789     else
0790       delete theCylinder;
0791 
0792     layerNr = TrackerInteractionGeometry::TOB + 5;
0793     theCylinder = new BoundCylinder(thePosition, theRotation, TOB5);
0794     theCylinder->setMediumProperties(*_theMPTOB5);
0795     if (theCylinder->mediumProperties().radLen() > 0.)
0796       _theCylinders.push_back(
0797           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0798     else
0799       delete theCylinder;
0800 
0801     layerNr = TrackerInteractionGeometry::TOB + 6;
0802     theCylinder = new BoundCylinder(thePosition, theRotation, TOB6);
0803     theCylinder->setMediumProperties(*_theMPTOB6);
0804     if (theCylinder->mediumProperties().radLen() > 0.)
0805       _theCylinders.push_back(
0806           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0807     else
0808       delete theCylinder;
0809 
0810     layerNr = 112;
0811     theDisk = new BoundDisk(PTOBEOut, theRotation2, TOBEOut);
0812     theDisk->setMediumProperties(*_theMPTOBEOutside);
0813     if (theDisk->mediumProperties().radLen() > 0.)
0814       _theCylinders.push_back(
0815           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0816     else
0817       delete theDisk;
0818 
0819     // Outer Endcaps
0820 
0821     layerNr = TrackerInteractionGeometry::TEC + 1;
0822     theDisk = new BoundDisk(PTEC1, theRotation2, TEC1);
0823     theDisk->setMediumProperties(*_theMPEndcap);
0824     if (theDisk->mediumProperties().radLen() > 0.)
0825       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0826     else
0827       delete theDisk;
0828 
0829     layerNr = TrackerInteractionGeometry::TEC + 2;
0830     theDisk = new BoundDisk(PTEC2, theRotation2, TEC2);
0831     theDisk->setMediumProperties(*_theMPEndcap);
0832     if (theDisk->mediumProperties().radLen() > 0.)
0833       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0834     else
0835       delete theDisk;
0836 
0837     layerNr = TrackerInteractionGeometry::TEC + 3;
0838     theDisk = new BoundDisk(PTEC3, theRotation2, TEC3);
0839     theDisk->setMediumProperties(*_theMPEndcap);
0840     if (theDisk->mediumProperties().radLen() > 0.)
0841       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0842     else
0843       delete theDisk;
0844 
0845     layerNr = TrackerInteractionGeometry::TEC + 4;
0846     theDisk = new BoundDisk(PTEC4, theRotation2, TEC4);
0847     theDisk->setMediumProperties(*_theMPEndcap);
0848     if (theDisk->mediumProperties().radLen() > 0.)
0849       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0850     else
0851       delete theDisk;
0852 
0853     layerNr = TrackerInteractionGeometry::TEC + 5;
0854     theDisk = new BoundDisk(PTEC5, theRotation2, TEC5);
0855     theDisk->setMediumProperties(*_theMPEndcap);
0856     if (theDisk->mediumProperties().radLen() > 0.)
0857       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0858     else
0859       delete theDisk;
0860 
0861     layerNr = TrackerInteractionGeometry::TEC + 6;
0862     theDisk = new BoundDisk(PTEC6, theRotation2, TEC6);
0863     theDisk->setMediumProperties(*_theMPEndcap);
0864     if (theDisk->mediumProperties().radLen() > 0.)
0865       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0866     else
0867       delete theDisk;
0868 
0869     layerNr = TrackerInteractionGeometry::TEC + 7;
0870     theDisk = new BoundDisk(PTEC7, theRotation2, TEC7);
0871     theDisk->setMediumProperties(*_theMPEndcap);
0872     if (theDisk->mediumProperties().radLen() > 0.)
0873       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0874     else
0875       delete theDisk;
0876 
0877     layerNr = TrackerInteractionGeometry::TEC + 8;
0878     theDisk = new BoundDisk(PTEC8, theRotation2, TEC8);
0879     theDisk->setMediumProperties(*_theMPEndcap);
0880     if (theDisk->mediumProperties().radLen() > 0.)
0881       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0882     else
0883       delete theDisk;
0884 
0885     layerNr = TrackerInteractionGeometry::TEC + 9;
0886     theDisk = new BoundDisk(PTEC9, theRotation2, TEC9);
0887     theDisk->setMediumProperties(*_theMPEndcap);
0888     if (theDisk->mediumProperties().radLen() > 0.)
0889       _theCylinders.push_back(TrackerLayer(theDisk, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0890     else
0891       delete theDisk;
0892 
0893     // Tracker Outside
0894 
0895     layerNr = 113;
0896     theCylinder = new BoundCylinder(thePosition, theRotation, TBOut);
0897     theCylinder->setMediumProperties(*_theMPBarrelOutside);
0898     if (theCylinder->mediumProperties().radLen() > 0.)
0899       _theCylinders.push_back(
0900           TrackerLayer(theCylinder, false, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0901     else
0902       delete theCylinder;
0903 
0904     layerNr = 114;
0905     theDisk = new BoundDisk(PTEOut, theRotation2, TEOut);
0906     theDisk->setMediumProperties(*_theMPEndcapOutside);
0907     if (theDisk->mediumProperties().radLen() > 0.)
0908       _theCylinders.push_back(
0909           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0910     else
0911       delete theDisk;
0912 
0913     layerNr = 115;
0914     theDisk = new BoundDisk(PTEOut2, theRotation2, TEOut2);
0915     theDisk->setMediumProperties(*_theMPEndcapOutside2);
0916     if (theDisk->mediumProperties().radLen() > 0.)
0917       _theCylinders.push_back(
0918           TrackerLayer(theDisk, true, layerNr, minDim(layerNr), maxDim(layerNr), fudgeFactors(layerNr)));
0919     else
0920       delete theDisk;
0921   }
0922 
0923   // Check overall compatibility of cylinder dimensions
0924   // (must be nested cylinders)
0925   // Throw an exception if the test fails
0926   double zin, rin;
0927   double zout, rout;
0928   unsigned nCyl = 0;
0929   std::list<TrackerLayer>::const_iterator cyliterOut = cylinderBegin();
0930   // Inner cylinder dimensions
0931   if (cyliterOut->forward()) {
0932     zin = cyliterOut->disk()->position().z();
0933     rin = cyliterOut->disk()->outerRadius();
0934   } else {
0935     zin = cyliterOut->cylinder()->bounds().length() / 2.;
0936     rin = cyliterOut->cylinder()->bounds().width() / 2.;
0937   }
0938   // Go to the next cylinder
0939   ++cyliterOut;
0940 
0941   // And loop over all cylinders
0942   while (cyliterOut != cylinderEnd()) {
0943     // Outer cylinder dimensions
0944     if (cyliterOut->forward()) {
0945       zout = cyliterOut->disk()->position().z();
0946       rout = cyliterOut->disk()->outerRadius();
0947     } else {
0948       zout = cyliterOut->cylinder()->bounds().length() / 2.;
0949       rout = cyliterOut->cylinder()->bounds().width() / 2.;
0950     }
0951 
0952     nCyl++;
0953     if (zout < zin || rout < rin) {
0954       throw cms::Exception("FastSimulation/TrackerInteractionGeometry ")
0955           << " WARNING with cylinder number " << nCyl << " (Active Layer Number = " << cyliterOut->layerNumber()
0956           << " Forward ? " << cyliterOut->forward() << " ) "
0957           << " has dimensions smaller than previous cylinder : " << std::endl
0958           << " zout/zin = " << zout << " " << zin << std::endl
0959           << " rout/rin = " << rout << " " << rin << std::endl;
0960     } else {
0961       /*
0962       std::cout << " Cylinder number " << nCyl 
0963         << " (Active Layer Number = " <<  cyliterOut->layerNumber() 
0964         << " Forward ? " <<  cyliterOut->forward() << " ) "
0965         << " has dimensions of : " 
0966         << " zout = " << zout << "; " 
0967         << " rout = " << rout << std::endl;
0968       */
0969     }
0970 
0971     // Go to the next cylinder
0972     cyliterOut++;
0973     // Inner cylinder becomes outer cylinder
0974     zin = zout;
0975     rin = rout;
0976     // End test
0977   }
0978 }
0979 
0980 std::vector<double> TrackerInteractionGeometry::minDim(unsigned layerNr) {
0981   std::vector<double> min;
0982   for (unsigned iLayer = 0; iLayer < fudgeFactor.size(); ++iLayer) {
0983     if (layerNr != fudgeLayer[iLayer])
0984       continue;
0985     min.push_back(fudgeMin[iLayer]);
0986   }
0987   return min;
0988 }
0989 
0990 std::vector<double> TrackerInteractionGeometry::maxDim(unsigned layerNr) {
0991   std::vector<double> max;
0992   for (unsigned iLayer = 0; iLayer < fudgeFactor.size(); ++iLayer) {
0993     if (layerNr != fudgeLayer[iLayer])
0994       continue;
0995     max.push_back(fudgeMax[iLayer]);
0996   }
0997   return max;
0998 }
0999 
1000 std::vector<double> TrackerInteractionGeometry::fudgeFactors(unsigned layerNr) {
1001   std::vector<double> fudge;
1002   for (unsigned iLayer = 0; iLayer < fudgeFactor.size(); ++iLayer) {
1003     if (layerNr != fudgeLayer[iLayer])
1004       continue;
1005     fudge.push_back(fudgeFactor[iLayer]);
1006   }
1007   return fudge;
1008 }
1009 
1010 TrackerInteractionGeometry::~TrackerInteractionGeometry() {
1011   _theCylinders.clear();
1012   //  _theRings.clear();
1013 
1014   if (use_hardcoded) {
1015     // The Beam pipe
1016     delete _theMPBeamPipe;
1017     // The pixel barrel layers
1018     delete _theMPPixelBarrel;
1019     // The pixel endcap disks
1020     delete _theMPPixelEndcap;
1021     // The various cables thicnesses for each layer / disks
1022     delete _theMPPixelOutside1;
1023     delete _theMPPixelOutside2;
1024     delete _theMPPixelOutside3;
1025     delete _theMPPixelOutside4;
1026     delete _theMPPixelOutside;
1027     delete _theMPPixelOutside5;
1028     delete _theMPPixelOutside6;
1029     // The tracker inner barrel layers
1030     delete _theMPTIB1;
1031     delete _theMPTIB2;
1032     delete _theMPTIB3;
1033     delete _theMPTIB4;
1034     // The tracker outer barrel layers
1035     delete _theMPTOB1;
1036     delete _theMPTOB2;
1037     delete _theMPTOB3;
1038     delete _theMPTOB4;
1039     delete _theMPTOB5;
1040     delete _theMPTOB6;
1041     // The tracker inner disks
1042     delete _theMPInner1;
1043     delete _theMPInner2;
1044     delete _theMPInner3;
1045     // The tracker endcap disks
1046     delete _theMPEndcap;
1047     // Various cable thicknesses
1048     delete _theMPTOBBInside;
1049     delete _theMPTIBEOutside1;
1050     delete _theMPTIBEOutside2;
1051     delete _theMPTIDEOutside;
1052     delete _theMPTOBEOutside;
1053     delete _theMPBarrelOutside;
1054     delete _theMPEndcapOutside;
1055     delete _theMPEndcapOutside2;
1056 
1057   } else {
1058     for (unsigned int i = 0; i < _mediumProperties.size(); i++) {
1059       delete _mediumProperties[i];
1060     }
1061   }
1062 }