File indexing completed on 2025-01-18 09:14:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "DD4hep/DetFactoryHelper.h"
0011
0012 #include "DDRec/Surface.h"
0013 #include "DDRec/DetectorData.h"
0014 #include <exception>
0015
0016 using namespace dd4hep;
0017 using namespace dd4hep::detail;
0018 using namespace dd4hep::rec ;
0019
0020 static Ref_t create_element(Detector& description, xml_h e, SensitiveDetector sens) {
0021
0022 xml_det_t x_det = e;
0023 std::string name = x_det.nameStr();
0024
0025
0026
0027
0028 Assembly assembly( name+"_assembly" );
0029
0030 DetElement tracker( name, x_det.id() ) ;
0031
0032 PlacedVolume pv;
0033
0034 rec::ZPlanarData* zPlanarData = new rec::ZPlanarData ;
0035
0036
0037 double minRadius = 1e99 ;
0038 double minZhalf = 1e99 ;
0039
0040
0041 bool isStripDetector = false ;
0042 try {
0043 isStripDetector = x_det.attr<bool>( _Unicode(isStripDetector) ) ;
0044
0045 } catch(const std::runtime_error& ){}
0046
0047
0048
0049 for(xml_coll_t c(e, _U(layer) ); c; ++c) {
0050
0051 xml_comp_t x_layer( c );
0052
0053
0054 xml_comp_t x_sensitive( x_layer.child( _U(sensitive) ));
0055 xml_comp_t x_ladder( x_layer.child( _U(ladder) ));
0056
0057 int layer_id = x_layer.id();
0058 int nLadders = x_layer.attr<double>( _Unicode(nLadders) ) ;
0059
0060 double dphi = 2.*M_PI / double(nLadders);
0061
0062 std::string layername = name+_toString(layer_id,"_layer%d");
0063
0064
0065
0066
0067 Assembly layer_assembly( "layer_assembly" +_toString(layer_id,"_%d") );
0068
0069 DetElement layerDE( tracker , _toString(layer_id,"layer_%d"), x_det.id() );
0070
0071 pv = assembly.placeVolume( layer_assembly );
0072
0073 pv.addPhysVolID("layer", layer_id );
0074
0075 layerDE.setPlacement( pv ) ;
0076
0077
0078
0079 double supp_zhalf = x_ladder.length();
0080 double supp_offset = x_ladder.offset();
0081 double supp_distance = x_ladder.distance();
0082 double supp_thickness = x_ladder.thickness();
0083 double supp_width = x_ladder.width();
0084
0085 std::string supp_vis = x_ladder.visStr() ;
0086 std::string supp_matS = x_ladder.materialStr() ;
0087
0088 double sens_zhalf = x_sensitive.length();
0089 double sens_offset = x_sensitive.offset();
0090 double sens_distance = x_sensitive.distance();
0091 double sens_thickness = x_sensitive.thickness();
0092 double sens_width = x_sensitive.width();
0093
0094 std::string sens_vis = x_sensitive.visStr() ;
0095 std::string sens_matS = x_sensitive.materialStr() ;
0096
0097 double phi0 = x_layer.phi0() ;
0098
0099
0100 if( sens_distance < minRadius ) minRadius = sens_distance ;
0101 if( supp_distance < minRadius ) minRadius = supp_distance ;
0102 if( sens_zhalf < minZhalf ) minZhalf = sens_zhalf ;
0103 if( supp_zhalf < minZhalf ) minZhalf = supp_zhalf ;
0104
0105
0106
0107 rec::ZPlanarData::LayerLayout thisLayer ;
0108
0109 thisLayer.sensorsPerLadder = 1 ;
0110 thisLayer.lengthSensor = 2. * sens_zhalf ;
0111
0112 thisLayer.distanceSupport = supp_distance ;
0113 thisLayer.offsetSupport = supp_offset ;
0114 thisLayer.thicknessSupport = supp_thickness ;
0115 thisLayer.zHalfSupport = supp_zhalf ;
0116 thisLayer.widthSupport = supp_width ;
0117
0118 thisLayer.distanceSensitive = sens_distance ;
0119 thisLayer.offsetSensitive = sens_offset ;
0120 thisLayer.thicknessSensitive = sens_thickness ;
0121 thisLayer.zHalfSensitive = sens_zhalf ;
0122 thisLayer.widthSensitive = sens_width ;
0123
0124 thisLayer.ladderNumber = nLadders ;
0125 thisLayer.phi0 = phi0 ;
0126
0127 zPlanarData->layers.push_back( thisLayer ) ;
0128
0129
0130
0131 Material supp_mat = description.material( supp_matS ) ;
0132 Material sens_mat = description.material( sens_matS ) ;
0133
0134
0135
0136 Box sens_box( sens_thickness/2., sens_width/2., sens_zhalf );
0137 Box supp_box( supp_thickness/2., supp_width/2., supp_zhalf );
0138
0139 Volume supp_vol( layername+"_supp", supp_box, supp_mat );
0140 Volume sens_vol( layername+"_sens", sens_box, sens_mat );
0141
0142
0143
0144 Vector3D u( 0. , 1. , 0. ) ;
0145 Vector3D v( 0. , 0. , 1. ) ;
0146 Vector3D n( 1. , 0. , 0. ) ;
0147
0148
0149
0150
0151 double inner_thickness = ( sens_distance > supp_distance ? ( sens_distance - supp_distance ) + sens_thickness/2 : sens_thickness/2 ) ;
0152 double outer_thickness = ( sens_distance > supp_distance ? sens_thickness/2 : ( supp_distance - sens_distance ) + supp_thickness - sens_thickness/2 ) ;
0153
0154 SurfaceType type( SurfaceType::Sensitive ) ;
0155
0156 if( isStripDetector )
0157 type.setProperty( SurfaceType::Measurement1D , true ) ;
0158
0159 VolPlane surf( sens_vol , type , inner_thickness , outer_thickness , u,v,n ) ;
0160
0161
0162
0163 sens.setType("tracker");
0164 sens_vol.setSensitiveDetector(sens);
0165
0166 sens_vol.setAttributes( description, x_det.regionStr(), x_det.limitsStr(), sens_vis );
0167 supp_vol.setAttributes( description, x_det.regionStr(), x_det.limitsStr(), supp_vis );
0168
0169
0170
0171
0172 for(int j=0; j<nLadders; ++j) {
0173
0174 double phi = phi0 + j * dphi ;
0175
0176 std::string laddername = layername + _toString(j,"_ladder%d");
0177
0178 RotationZYX rot( phi , 0, 0 ) ;
0179
0180
0181
0182 double lthick = supp_thickness ;
0183 double radius = supp_distance ;
0184 double offset = supp_offset ;
0185
0186 layer_assembly.placeVolume(supp_vol,Transform3D(rot, Position((radius+lthick/2.)*cos(phi) - offset*sin(phi),
0187 (radius+lthick/2.)*sin(phi) + offset*cos(phi),
0188 0. ) ));
0189
0190
0191 lthick = sens_thickness ;
0192 radius = sens_distance ;
0193 offset = sens_offset ;
0194
0195 pv = layer_assembly.placeVolume( sens_vol,Transform3D(rot, Position((radius + lthick/2.0)*cos(phi) - offset*sin(phi),
0196 (radius + lthick/2.0)*sin(phi) + offset*cos(phi),
0197 0. ) ));
0198
0199
0200 pv.addPhysVolID( "module" , j ).addPhysVolID("sensor", 0 ) ;
0201
0202
0203 DetElement ladderDE( layerDE , laddername , x_det.id() );
0204 ladderDE.setPlacement( pv ) ;
0205
0206 volSurfaceList( ladderDE )->push_back( surf ) ;
0207
0208 }
0209
0210
0211
0212
0213
0214
0215 layer_assembly->GetShape()->ComputeBBox() ;
0216
0217 }
0218
0219 #if 0
0220
0221
0222 double tube_thick = 1.0 * dd4hep::mm ;
0223 double inner_r = minRadius - 1.1 * tube_thick ;
0224 double outer_r = inner_r + tube_thick ;
0225 double z_half = minZhalf ;
0226
0227 Tube tubeSolid (inner_r, outer_r, z_half ) ;
0228 Volume tube_vol( name+"_inner_cylinder_air", tubeSolid , description.material("Air") ) ;
0229
0230 assembly.placeVolume( tube_vol , Transform3D() ) ;
0231
0232 Vector3D ocyl( inner_r + 0.5*tube_thick , 0. , 0. ) ;
0233
0234 VolCylinder cylSurf( tube_vol , SurfaceType( SurfaceType::Helper ) , 0.5*tube_thick , 0.5*tube_thick , ocyl ) ;
0235
0236 volSurfaceList( tracker )->push_back( cylSurf ) ;
0237
0238 #endif
0239
0240
0241
0242 tracker.addExtension< rec::ZPlanarData >( zPlanarData ) ;
0243
0244 Volume mother = description.pickMotherVolume( tracker ) ;
0245
0246 pv = mother.placeVolume(assembly);
0247
0248 pv.addPhysVolID( "system", x_det.id() ).addPhysVolID("side",0 ) ;
0249
0250 tracker.setPlacement(pv);
0251
0252 assembly->GetShape()->ComputeBBox() ;
0253
0254 return tracker;
0255 }
0256
0257 DECLARE_DETELEMENT(ZPlanarTracker,create_element)