File indexing completed on 2025-01-18 09:14:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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
0047 double beamPosX = std::tan(xangleHalf) * zpos;
0048
0049
0050 Tube envelopeTube(rmin,rmax,thickness/2);
0051
0052
0053
0054 Tube beamInTube(0,outgoingR,thickness);
0055
0056 Position beamInPos(beamPosX,0,0);
0057
0058 Rotation3D beamInRot(RotationY(1.*xangleHalf));
0059 Transform3D beamInTrans(beamInRot,beamInPos);
0060
0061
0062
0063 Tube beamOutTube(0,incomingR,thickness);
0064
0065 Position beamOutPos(-beamPosX,0,0);
0066
0067 Rotation3D beamOutRot(RotationY(-xangleHalf));
0068 Transform3D beamOutTrans(beamOutRot,beamOutPos);
0069
0070
0071 SubtractionSolid envelopeSubtraction1(envelopeTube,beamInTube,beamInTrans);
0072 SubtractionSolid envelopeSubtraction2(envelopeSubtraction1,beamOutTube,beamOutTrans);
0073
0074
0075 Volume envelopeVol(det_name+"_envelope", envelopeSubtraction2, air);
0076
0077
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
0087
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
0093 layerDisplZ += layerThickness / 2;
0094 layerPosZ += layerThickness / 2;
0095
0096
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
0105 SubtractionSolid layerSubtraction2(layerSubtraction1,beamOutTube,Transform3D(beamOutRot,layer2SubPos));
0106
0107 Volume layerVol(det_name+"_"+layer_nam,layerSubtraction2,air);
0108
0109
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
0117 double sliceThickness = x_slice.thickness();
0118 Material slice_mat = description.material(x_slice.materialStr());
0119
0120
0121 sliceDisplZ += sliceThickness / 2;
0122 slicePosZ += sliceThickness / 2;
0123
0124
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
0131 SubtractionSolid sliceSubtraction1(sliceTube,beamInTube,Transform3D(beamInRot,Position(slicePosX,0,0)));
0132
0133 SubtractionSolid sliceSubtraction2(sliceSubtraction1,beamOutTube,Transform3D(beamOutRot,Position(-slicePosX,0,0)));
0134
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
0142 slice.setAttributes(description, sliceVol, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
0143
0144
0145 PlacedVolume pv = layerVol.placeVolume(sliceVol,Position(0,0,slicePosZ));
0146 pv.addPhysVolID("slice",sliceCount);
0147 slice.setPlacement(pv);
0148
0149
0150 sliceDisplZ += sliceThickness / 2;
0151 slicePosZ += sliceThickness / 2;
0152 ++sliceCount;
0153 }
0154
0155 layer.setAttributes(description, layerVol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr());
0156
0157
0158 PlacedVolume layerPV = envelopeVol.placeVolume(layerVol,Position(0,0,layerPosZ));
0159 layerPV.addPhysVolID("layer", layerCount);
0160 layer.setPlacement(layerPV);
0161
0162
0163 layerDisplZ += layerThickness / 2;
0164 layerPosZ += layerThickness / 2;
0165 ++layerCount;
0166 }
0167 }
0168 sdet.setVisAttributes(description, x_det.visStr(), envelopeVol);
0169
0170
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)