Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:57

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 //
0014 // Specialized generic detector constructor
0015 // 
0016 //==========================================================================
0017 #include "XML/Layering.h"
0018 #include "DD4hep/DetFactoryHelper.h"
0019 
0020 using namespace std;
0021 using namespace dd4hep;
0022 using namespace dd4hep::detail;
0023 
0024 static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens)  {
0025   xml_det_t   x_det      = e;
0026   xml_dim_t   dim        = x_det.dimensions();
0027   bool        reflect    = x_det.reflect();
0028   xml_comp_t  beam       = x_det.beampipe();
0029   string      det_name   = x_det.nameStr();
0030   int         id         = x_det.id();
0031   Material    air        = description.air();
0032   DetElement  sdet       (det_name,id);
0033   Layering    layering   (x_det);
0034 
0035   Volume      motherVol  = description.pickMotherVolume(sdet);
0036 
0037   double      rmax       = dim.outer_r();
0038   double      rmin       = dim.inner_r();
0039   double      zinner     = dim.inner_z();
0040   double      outgoingR  = beam.outgoing_r();
0041   double      incomingR  = beam.incoming_r();
0042   double      xangle     = beam.crossing_angle();
0043   double      xangleHalf = xangle/2;
0044   double      thickness  = layering.totalThickness();
0045   double      zpos       = zinner + thickness/2;
0046   // Beampipe position in envelope.
0047   double      beamPosX   = std::tan(xangleHalf) * zpos;
0048 
0049   // Detector envelope solid. 
0050   Tube envelopeTube(rmin,rmax,thickness/2);
0051 
0052   // First envelope bool subtracion of outgoing beampipe.
0053   // Incoming beampipe solid.
0054   Tube beamInTube(0,outgoingR,thickness);
0055   // Position of incoming beampipe.
0056   Position beamInPos(beamPosX,0,0);
0057   /// Rotation of incoming beampipe.
0058   Rotation3D  beamInRot(RotationY(1.*xangleHalf));
0059   Transform3D beamInTrans(beamInRot,beamInPos);
0060 
0061   // Second envelope bool subtracion of outgoing beampipe.
0062   // Outgoing beampipe solid.
0063   Tube     beamOutTube(0,incomingR,thickness);
0064   // Position of outgoing beampipe.
0065   Position beamOutPos(-beamPosX,0,0);
0066   // Rotation of outgoing beampipe.
0067   Rotation3D  beamOutRot(RotationY(-xangleHalf));
0068   Transform3D beamOutTrans(beamOutRot,beamOutPos);
0069 
0070   // First envelope bool subtraction of incoming beampipe.
0071   SubtractionSolid envelopeSubtraction1(envelopeTube,beamInTube,beamInTrans);
0072   SubtractionSolid envelopeSubtraction2(envelopeSubtraction1,beamOutTube,beamOutTrans);
0073 
0074   // Final envelope bool volume.
0075   Volume envelopeVol(det_name+"_envelope", envelopeSubtraction2, air);
0076 
0077   // Process each layer element.
0078   double layerPosZ   = -thickness / 2;
0079   double layerDisplZ = 0;
0080 
0081   int layerCount = 1;
0082   for(xml_coll_t c(x_det,_U(layer)); c; ++c)  {
0083     xml_comp_t x_layer = c;
0084     double layerThickness = layering.singleLayerThickness(x_layer);
0085 
0086     // Create tube envelope for this layer, which can be reused in bool definition
0087     // in the repeat loop below.
0088     Tube layerTube(rmin,rmax,layerThickness);
0089 
0090     for(int i=0, repeat=x_layer.repeat(); i<repeat; ++i)  {
0091       string layer_nam = _toString(layerCount,"layer%d");
0092       // Increment to new layer position.
0093       layerDisplZ += layerThickness / 2;
0094       layerPosZ   += layerThickness / 2;
0095 
0096       // First layer subtraction solid.
0097       DetElement  layer(sdet,layer_nam,sdet.id());
0098       double      layerGlobalZ = zinner + layerDisplZ;
0099       double      layerPosX    = std::tan(xangleHalf) * layerGlobalZ;
0100       Position    layer1SubPos( layerPosX,0,0);
0101       Position    layer2SubPos(-layerPosX,0,0);
0102 
0103       SubtractionSolid layerSubtraction1(layerTube,beamInTube,Transform3D(beamInRot,layer1SubPos));
0104       // Second layer subtraction solid.
0105       SubtractionSolid layerSubtraction2(layerSubtraction1,beamOutTube,Transform3D(beamOutRot,layer2SubPos));
0106       // Layer LV.
0107       Volume layerVol(det_name+"_"+layer_nam,layerSubtraction2,air);
0108       
0109       // Slice loop.
0110       int sliceCount = 1;
0111       double slicePosZ = -layerThickness / 2;
0112       double sliceDisplZ = 0;
0113       for(xml_coll_t l(x_layer,_U(slice)); l; ++l)  {
0114         xml_comp_t x_slice = l;
0115         string slice_nam = _toString(sliceCount,"slice%d");
0116         /** Get slice parameters. */
0117         double sliceThickness = x_slice.thickness();
0118         Material slice_mat = description.material(x_slice.materialStr());
0119 
0120         // Go to mid of this slice.
0121         sliceDisplZ += sliceThickness / 2;
0122         slicePosZ   += sliceThickness / 2;
0123 
0124         // Slice's basic tube.
0125         Tube sliceTube(rmin,rmax,sliceThickness);
0126         DetElement slice(layer,slice_nam,sdet.id());
0127         double sliceGlobalZ = zinner + (layerDisplZ - layerThickness / 2) + sliceDisplZ;
0128         double slicePosX    = std::tan(xangleHalf) * sliceGlobalZ;
0129 
0130         // First slice subtraction solid.
0131         SubtractionSolid sliceSubtraction1(sliceTube,beamInTube,Transform3D(beamInRot,Position(slicePosX,0,0)));
0132         // Second slice subtraction solid.
0133         SubtractionSolid sliceSubtraction2(sliceSubtraction1,beamOutTube,Transform3D(beamOutRot,Position(-slicePosX,0,0))); 
0134         // Slice LV.
0135         Volume sliceVol(det_name+"_"+layer_nam+"_"+slice_nam, sliceSubtraction2, slice_mat);
0136 
0137         if ( x_slice.isSensitive() ) {
0138           sens.setType("calorimeter");
0139           sliceVol.setSensitiveDetector(sens);
0140         }
0141         // Set attributes of slice
0142         slice.setAttributes(description, sliceVol, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
0143 
0144         // Place volume in layer
0145         PlacedVolume pv = layerVol.placeVolume(sliceVol,Position(0,0,slicePosZ));
0146         pv.addPhysVolID("slice",sliceCount);
0147         slice.setPlacement(pv);
0148 
0149         // Start of next slice.
0150         sliceDisplZ += sliceThickness / 2;
0151         slicePosZ   += sliceThickness / 2;
0152         ++sliceCount;
0153       }
0154       // Set attributes of slice
0155       layer.setAttributes(description, layerVol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
0156 
0157       // Layer PV.
0158       PlacedVolume layerPV = envelopeVol.placeVolume(layerVol,Position(0,0,layerPosZ));
0159       layerPV.addPhysVolID("layer", layerCount);
0160       layer.setPlacement(layerPV);
0161 
0162       // Increment to start of next layer.
0163       layerDisplZ += layerThickness / 2;
0164       layerPosZ   += layerThickness / 2;
0165       ++layerCount;
0166     }
0167   }
0168   sdet.setVisAttributes(description, x_det.visStr(), envelopeVol);
0169   
0170   // Reflect it.
0171   if ( reflect )  {
0172     Assembly assembly(det_name+"_assembly");
0173     PlacedVolume pv = motherVol.placeVolume(assembly);
0174     pv.addPhysVolID("system", id);
0175     sdet.setPlacement(pv);
0176 
0177     DetElement   sdetA(sdet,det_name+"_A",x_det.id());
0178     pv = assembly.placeVolume(envelopeVol,Transform3D(RotationZ(M_PI),Position(0,0,zpos)));
0179     pv.addPhysVolID("barrel", 1);
0180     sdetA.setPlacement(pv);
0181 
0182     DetElement   sdetB = sdetA.clone(det_name+"_B",x_det.id());
0183     sdet.add(sdetB);
0184     pv = assembly.placeVolume(envelopeVol,Transform3D(RotationY(M_PI),Position(0,0,-zpos)));
0185     pv.addPhysVolID("barrel", 2);
0186     sdetB.setPlacement(pv);
0187   }
0188   else  {
0189     PlacedVolume pv = motherVol.placeVolume(envelopeVol,Transform3D(RotationZ(M_PI),Position(0,0,zpos)));
0190     pv.addPhysVolID("system", id);
0191     pv.addPhysVolID("barrel", 1);
0192     sdet.setPlacement(pv);
0193   }
0194   return sdet;
0195 }
0196 
0197 DECLARE_DETELEMENT(Lhe_ForwardDetector,create_detector)