static Ref_t create_element(LCDD& lcdd, xml_h e, SensitiveDetector sens) { xml_det_t x_det = e; string det_name = x_det.nameStr(); Material air = lcdd.air(); //Detector envelope of SubDetector DetElement tracker(det_name, x_det.id()); //add Extension to Detlement for the RecoGeometry Det::DetExtension* ex = new Det::DetExtension(); tracker.addExtension<Det::IDetExtension> (ex); //Create the Volume of the Detector envelope DD4hep::XML::Dimension x_det_dim(x_det.dimensions()); double z = x_det_dim.z(); Tube tracker_shape(x_det_dim.rmin(),x_det_dim.rmax(),z); Volume tracker_vol(x_det.nameStr()+"_envelope",tracker_shape, air); //Vizualization tracker_vol.setVisAttributes(lcdd.invisible()); //Set sensitive type tracker sens.setType("tracker"); int layer_num = 0; //Go through layers for (xml_coll_t j(e,_U(layer)); j; ++j ) { xml_comp_t x_layer = j; double rmin = x_layer.inner_r(); double rmax = x_layer.outer_r(); double radius = (rmax+rmin)*0.5; double layer_z = x_layer.z(); //Create Volume and DetElement for Layer string layer_name = det_name + _toString(layer_num,"layer%d"); Volume layer_vol(layer_name,Tube(rmin,rmax,layer_z), lcdd.material(x_layer.materialStr())); DetElement lay_det (tracker,layer_name,layer_num); //Visualization layer_vol.setVisAttributes(lcdd.invisible()); //module in phi // later also loop through modules for different modules xml_comp_t x_module = x_layer.child(_U(module)); int repeat = x_module.repeat(); double deltaphi = 2.*M_PI/repeat; //slices in z xml_comp_t x_slice = x_layer.child(_U(slice)); int zrepeat = x_slice.repeat(); double dz = x_slice.z(); //add Extension to Detlement for the RecoGeometry Det::DetCylinderLayer* detcylinderlayer = new Det::DetCylinderLayer(); lay_det.addExtension<Det::IDetExtension>(detcylinderlayer); int module_num = 0; //Place the Modules in z for (int k = -zrepeat; k<=zrepeat; k++) { string zname = _toString(k,"z%d"); //Place the Modules in phi for (int i = 0; i < repeat; ++i) { //Create Module Volume Volume mod_vol("module", Box(x_module.length(), x_module.width(),x_module.thickness()), air); //Vizualization mod_vol.setVisAttributes(lcdd.invisible()); double phi = deltaphi/dd4hep::rad * i; string module_name = zname + _toString(i,"module%d"); Position trans(radius * cos(phi), radius * sin(phi), k*dz); //Create module Detelement DetElement mod_det(lay_det,module_name,module_num); //add Extension to Detlement for the RecoGeometry Det::DetModule* detmod = new Det::DetModule(); mod_det.addExtension<Det::IDetExtension> (detmod); int comp_num = 0; //go through module components for (xml_coll_t n(x_module,_U(module_component)); n; ++n) { xml_comp_t x_comp = n; Volume comp_vol("component " + x_comp.materialStr(), Box(x_comp.length(),x_comp.width(), x_comp.thickness()),lcdd.material(x_comp.materialStr())); // comp_vol.setVisAttributes(lcdd, x_comp.visStr()); //Set Sensitive Volmes sensitive if (x_comp.isSensitive()) { comp_vol.setSensitiveDetector(sens); } //Create DetElement DetElement comp_det(mod_det, "component, " + x_comp.materialStr(),comp_num); //add Extension comp_det.addExtension<Det::IDetExtension> (ex); //place component in Module xml_comp_t x_pos = x_comp.position(false); Position transComp (x_pos.x(),x_pos.y(),x_pos.z()); PlacedVolume placedcomp = mod_vol.placeVolume(comp_vol,transComp); //assign the placed Volume to the DetElement comp_det.setPlacement(placedcomp); placedcomp.addPhysVolID("component",comp_num); ++comp_num; } //Place Box Volumes in layer PlacedVolume placedmodule = layer_vol.placeVolume(mod_vol, Transform3D(RotationX(0.5*M_PI)*RotationZ(0.5*M_PI)*RotationX(phi-0.6*M_PI),trans)); placedmodule.addPhysVolID("module", module_num); // assign module DetElement to the placed Module volume mod_det.setPlacement(placedmodule); ++module_num; } ++module_num; } //Place Layervolume PlacedVolume placedLayer = tracker_vol.placeVolume(layer_vol); placedLayer.addPhysVolID("layer",layer_num); placedLayer.addPhysVolID("system",x_det.id()); //Assign Layer DetElement to LayerVolume lay_det.setPlacement(placedLayer); ++layer_num; } Volume mother_vol = lcdd.pickMotherVolume(tracker); //Place envelopevolume in mothervolume PlacedVolume placed_env = mother_vol.placeVolume(tracker_vol); //assign tracker DetElement to tracker volume tracker.setPlacement(placed_env); //fuer envelope moeglich return tracker; }
static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { typedef vector<PlacedVolume> Placements; xml_det_t x_det = e; Material vacuum = lcdd.vacuum(); int det_id = x_det.id(); string det_name = x_det.nameStr(); bool reflect = x_det.reflect(false); DetElement sdet (det_name,det_id); Assembly assembly (det_name); //Volume assembly (det_name,Box(10000,10000,10000),vacuum); Volume motherVol = lcdd.pickMotherVolume(sdet); int m_id=0, c_id=0, n_sensor=0; map<string,Volume> modules; map<string, Placements> sensitives; PlacedVolume pv; assembly.setVisAttributes(lcdd.invisible()); sens.setType("tracker"); for(xml_coll_t mi(x_det,_U(module)); mi; ++mi, ++m_id) { xml_comp_t x_mod = mi; string m_nam = x_mod.nameStr(); xml_comp_t trd = x_mod.trd(); double posY; double x1 = trd.x1(); double x2 = trd.x2(); double z = trd.z(); double y1, y2, total_thickness=0.; xml_coll_t ci(x_mod,_U(module_component)); for(ci.reset(), total_thickness=0.0; ci; ++ci) total_thickness += xml_comp_t(ci).thickness(); y1 = y2 = total_thickness / 2; Volume m_volume(m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum); m_volume.setVisAttributes(lcdd.visAttributes(x_mod.visStr())); for(ci.reset(), n_sensor=1, c_id=0, posY=-y1; ci; ++ci, ++c_id) { xml_comp_t c = ci; double c_thick = c.thickness(); Material c_mat = lcdd.material(c.materialStr()); string c_name = _toString(c_id,"component%d"); Volume c_vol(c_name, Trapezoid(x1,x2,c_thick/2e0,c_thick/2e0,z), c_mat); c_vol.setVisAttributes(lcdd.visAttributes(c.visStr())); pv = m_volume.placeVolume(c_vol,Position(0,posY+c_thick/2,0)); if ( c.isSensitive() ) { sdet.check(n_sensor > 2,"SiTrackerEndcap2::fromCompact: "+c_name+" Max of 2 modules allowed!"); pv.addPhysVolID("sensor",n_sensor); c_vol.setSensitiveDetector(sens); sensitives[m_nam].push_back(pv); ++n_sensor; } posY += c_thick; } modules[m_nam] = m_volume; } for(xml_coll_t li(x_det,_U(layer)); li; ++li) { xml_comp_t x_layer(li); int l_id = x_layer.id(); int mod_num = 1; for(xml_coll_t ri(x_layer,_U(ring)); ri; ++ri) { xml_comp_t x_ring = ri; double r = x_ring.r(); double phi0 = x_ring.phi0(0); double zstart = x_ring.zstart(); double dz = x_ring.dz(0); int nmodules = x_ring.nmodules(); string m_nam = x_ring.moduleStr(); Volume m_vol = modules[m_nam]; double iphi = 2*M_PI/nmodules; double phi = phi0; Placements& sensVols = sensitives[m_nam]; for(int k=0; k<nmodules; ++k) { string m_base = _toString(l_id,"layer%d") + _toString(mod_num,"_module%d"); double x = -r*std::cos(phi); double y = -r*std::sin(phi); DetElement module(sdet,m_base+"_pos",det_id); pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(0,-M_PI/2-phi,-M_PI/2),Position(x,y,zstart+dz))); pv.addPhysVolID("side",1).addPhysVolID("layer", l_id).addPhysVolID("module",mod_num); module.setPlacement(pv); for(size_t ic=0; ic<sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; DetElement comp_elt(module,sens_pv.volume().name(),mod_num); comp_elt.setPlacement(sens_pv); } if ( reflect ) { pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(M_PI,-M_PI/2-phi,-M_PI/2),Position(x,y,-zstart-dz))); pv.addPhysVolID("side",-1).addPhysVolID("layer",l_id).addPhysVolID("module",mod_num); DetElement r_module(sdet,m_base+"_neg",det_id); r_module.setPlacement(pv); for(size_t ic=0; ic<sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; DetElement comp_elt(r_module,sens_pv.volume().name(),mod_num); comp_elt.setPlacement(sens_pv); } } dz = -dz; phi += iphi; ++mod_num; } } } pv = motherVol.placeVolume(assembly); pv.addPhysVolID("system",det_id); sdet.setPlacement(pv); return sdet; }