Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //====================================================================
0002 //  Simple tracking detector made from planar sensors that are parallel
0003 //  to the z-axis. There are two materials per ladder: one sensitive
0004 //  and one support.
0005 //--------------------------------------------------------------------
0006 //
0007 //  Author     : F.Gaede
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   // put the whole detector into an assembly
0026   //  - should be replaced by an envelope volume ...
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   //=========  loop over layer elements in xml  ======================================
0048 
0049   for(xml_coll_t c(e, _U(layer) ); c; ++c)  {
0050     
0051     xml_comp_t x_layer( c );
0052     
0053     // child elements: ladder and sensitive
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     // --- create an assembly and DetElement for the layer
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     //  store the data in an extension to be used for reconstruction 
0107     rec::ZPlanarData::LayerLayout thisLayer ;
0108 
0109     thisLayer.sensorsPerLadder =  1 ; // for now only one planar sensor
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     // -------- create a measurement plane for the tracking surface attched to the sensitive volume -----
0144     Vector3D u( 0. , 1. , 0. ) ;
0145     Vector3D v( 0. , 0. , 1. ) ;
0146     Vector3D n( 1. , 0. , 0. ) ;
0147     //    Vector3D o( 0. , 0. , 0. ) ;
0148 
0149     // compute the inner and outer thicknesses that need to be assigned to the tracking surface
0150     // depending on wether the support is above or below the sensor
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 ) ; //,o ) ;
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     //--------- loop over ladders ---------------------------
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       // --- place support -----
0182       double lthick = supp_thickness ;
0183       double radius = supp_distance ;
0184       double offset = supp_offset ;
0185       
0186       /* pv = */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       // --- place sensitive -----
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       //      pv.addPhysVolID("layer", layer_id ).addPhysVolID( "module" , j ).addPhysVolID("sensor", 0 )   ;
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     //    tracker.setVisAttributes(description, x_det.visStr(),laddervol);
0212     
0213 
0214     // is this needed ??
0215     layer_assembly->GetShape()->ComputeBBox() ;
0216 
0217   }
0218 
0219 #if 0  //-------- add an inscribing cylinder of air for tracking purposes -----------------
0220        //  this screw up the geometry and the material scan does not work anymore !!!!!?????
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)