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) { //XML detector object: DDCore/XML/XMLDetector.h DD4hep::XML::DetElement x_det = e; //Create the DetElement for DD4hep DetElement d_det(x_det.nameStr(),x_det.id()); //Pick the mothervolume Volume det_vol = lcdd.pickMotherVolume(d_det); //XML dimension object: DDCore/XML/XMLDimension.h DD4hep::XML::Dimension x_det_dim(x_det.dimensions()); //Tube: DDCore/DD4hep/Shapes.h Tube calo_shape(x_det_dim.rmin(),x_det_dim.rmax(),x_det_dim.z()); //Create the detector mother volume Volume calo_vol(x_det.nameStr()+"_envelope",calo_shape,lcdd.air()); //Set envelope volume attributes calo_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); //Place inside the mother volume PlacedVolume calo_plv = det_vol.placeVolume(calo_vol); calo_plv.addPhysVolID("system",x_det.id()); calo_plv.addPhysVolID("barrel",0); d_det.setPlacement(calo_plv); //Declare this sensitive detector as a calorimeter sens.setType("calorimeter"); int layer_num = 0; float layer_pos_z = 0; double tile_phi = 2*M_PI/x_det_dim.phiBins(); float r = x_det_dim.rmin(); bool debug = false; //Repeat layers until we reach the rmax while(r<x_det_dim.rmax()){ //Loop over layers of type: XML Collection_t object: DDCore/XML/XMLElements.h for(DD4hep::XML::Collection_t layerIt(x_det,_U(layer));layerIt; ++layerIt){ //Build a layer volume DD4hep::XML::Component x_det_layer = layerIt; float dr = x_det_layer.dr(); string layer_name = x_det.nameStr()+_toString(layer_num,"_layer%d"); float x1 = r * tan(tile_phi/2.); float x2 = (r+dr) * tan(tile_phi/2.); float y1 = x_det_dim.z(); float y2 = x_det_dim.z(); float z = x_det_layer.dr(); if(debug){ cout << " r:" << r << " dr:" << dr << " x1:" << x1 << " x2:" << x2 << " y1:" << y1 << " y2:" << y2 << " z:" << z << endl; } //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h Trapezoid layer_shape(x1,x2,y1,y2,z); //Create a volume with trapezoid shape Volume layer_vol(layer_name, layer_shape, lcdd.air()); layer_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det_layer.visStr()); //DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id()); //Fill the volume with tiles int tile_number = 0; vector<Volume> tiles; //Repeat slices until we reach the end of the calorimeter for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k) { DD4hep::XML::Component tile_xml = k; string tile_name = layer_name + _toString(tile_number,"_slice%d"); Material tile_material = lcdd.material(tile_xml.materialStr()); float tile_thickness = tile_xml.dz(); float tile_y1 = tile_thickness; float tile_y2 = tile_thickness; float tile_z = x_det_layer.dr(); //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z); //Create a volume with trapezoid shape Volume tile_vol(tile_name,tile_shape,tile_material); if ( tile_xml.isSensitive() ) { tile_vol.setSensitiveDetector(sens); } //Set region, limitset, and visibility settings tile_vol.setAttributes(lcdd,tile_xml.regionStr(),tile_xml.limitsStr(),tile_xml.visStr()); tiles.push_back(tile_vol); tile_number++; } //Place the same volumes inside the envelope float tile_pos_z = -x_det_dim.z()/2.; int slice_num = 0; while(tile_pos_z<x_det_dim.z()/2.){ tile_number=0; for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k) { DD4hep::XML::Component tile_xml = k; float tile_thickness = tile_xml.dz(); //Place the tile inside the layer PlacedVolume tile_plv = layer_vol.placeVolume(tiles.at(tile_number),Position(0,tile_pos_z,0)); tile_plv.addPhysVolID("layer",layer_num); tile_plv.addPhysVolID("slice",slice_num); //Increment the z pos of the tile tile_pos_z += tile_thickness; tile_number++; slice_num++; } } //Place the same layer around the beam axis phiBins times double mod_x_off = r; double mod_y_off = 0; for(int i=0;i<x_det_dim.phiBins();i++){ if(debug) cout << "Layer:" << i << " phi:" << tile_phi << " rotz:" << (tile_phi*i) << endl; double layer_pos_x = mod_x_off * cos(tile_phi*i) - mod_y_off * sin(tile_phi*i); double layer_pos_y = mod_x_off * sin(tile_phi*i) + mod_y_off * cos(tile_phi*i); Transform3D tr(RotationZYX(M_PI*0.5,M_PI*0.5,0)*RotationZYX(0,tile_phi*i,0), Translation3D(layer_pos_x,layer_pos_y,layer_pos_z)); PlacedVolume pv = calo_vol.placeVolume(layer_vol,tr); pv.addPhysVolID("system",x_det.id()); pv.addPhysVolID("barrel",0); pv.addPhysVolID("layer",layer_num); pv.addPhysVolID("module",i+1); //DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d")); } r += dr; layer_num += 1; } } //Place the calo inside the world return d_det; }
static Ref_t create_detector(LCDD& lcdd, xml_h element, SensitiveDetector sens) { xml_det_t x_det = element; Layering layering(x_det.child(_U(layers))); std::string det_name = x_det.nameStr(); std::string det_type = x_det.typeStr(); Material air = lcdd.air(); xml_dim_t dim = x_det.dimensions(); xml_dim_t x_pos (x_det.child(_U(position))); xml_dim_t x_rot (x_det.child(_U(rotation))); Translation3D det_pos(x_pos.x(),x_pos.y(),x_pos.z()); //Rotation is ROOT::Math::RotationZYX //The input is Rotation(z,y,x) RotationZYX det_rot(x_rot.z(),x_rot.y(),x_rot.x()); DetElement sdet(det_name,x_det.id()); Volume motherVol = lcdd.pickMotherVolume(sdet); // ========= Create Hcal Modules envelope ============================ // They will be the volume for placing the Hcal Layers. // Themselves will be placed into the world volume. // ========================================================================== // Hcal module shape double box_half_x = dim.x()/2.0; double box_half_y = dim.y()/2.0; double box_half_z = dim.z()/2.0; Box BoxModule(box_half_x,box_half_y,box_half_z); // define the name of Module std::string envelopeVol_name = det_name+_toString("_envelope"); Volume envelopeVol(envelopeVol_name,BoxModule,air); // Set envelope volume attributes. envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); // ========= Create Hcal Layers===== ============================== // It will be the sub volume for placing the slices. // Itself will be placed into the Hcal modules envelope. // ================================================================ // create Layer (air) and place the slices into it. // place the Layer into the Hcal Modules envelope. // Hcal layer start position double layer_pos_z = - box_half_z; // Create Hcal Chamber without radiator // Place into the Hcal module envelope int layer_num = 0; int module_num = 0; for(xml_coll_t c(x_det.child(_U(layers)),_U(layer)); c; ++c) { xml_comp_t x_layer = c; //Layering layering(x_layer); int repeat = x_layer.repeat(); const Layer* lay = layering.layer(layer_num); // Get the layer from the layering engine. std::string layer_name = det_name+ _toString(module_num,"_module%d_layer"); double layer_thickness = lay->thickness(); DetElement layer(layer_name,"layerModule",x_det.id()); // Layer box & volume double layer_dim_x = box_half_x; double layer_dim_y = box_half_y; double layer_dim_z = layer_thickness/2.0; // Build chamber including air gap // The Layer will be filled with slices, Volume layer_vol(layer_name, Box(layer_dim_x,layer_dim_y,layer_dim_z), air); // ========= Create sublayer slices ========================================= // Create and place the slices into Layer // ========================================================================== // Create the slices (sublayers) within the Hcal Chamber. double slice_pos_z = -(layer_thickness / 2.0); int slice_number = 0; for(xml_coll_t k(x_layer,_U(slice)); k; ++k) { xml_comp_t x_slice = k; std::string slice_name = layer_name + _toString(slice_number,"_slice%d"); double slice_thickness = x_slice.thickness(); Material slice_material = lcdd.material(x_slice.materialStr()); DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id()); slice_pos_z += slice_thickness / 2.0; // Slice volume & box Volume slice_vol(slice_name,Box(layer_dim_x,layer_dim_y,slice_thickness/2.0),slice_material); if ( x_slice.isSensitive() ) { sens.setType("calorimeter"); slice_vol.setSensitiveDetector(sens); } // Set region, limitset, and vis. slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr()); // slice PlacedVolume PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z)); slice_phv.addPhysVolID("slice",slice_number); slice.setPlacement(slice_phv); // Increment Z position for next slice. slice_pos_z += slice_thickness / 2.0; // Increment slice number. ++slice_number; } // Set region, limitset, and vis. layer_vol.setAttributes(lcdd,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr()); // ========= Place the Layer (i.e. Chamber) ================================= // Place the Layer into the Hcal module envelope. // with the right position, and registry the ID layer // ========================================================================== for (int j = 0; j < repeat; j++) { // Layer position in z within the Modules. layer_pos_z += layer_thickness / 2.0; PlacedVolume layer_phv = envelopeVol.placeVolume(layer_vol,Position(0,0,layer_pos_z)); // registry the ID of Layer layer_phv.addPhysVolID("layer",layer_num); layer_phv.addPhysVolID("module",j); // then setPlacement for it. layer.setPlacement(layer_phv); // Increment the layer_pos_z layer_pos_z += layer_thickness / 2.0; ++layer_num; } module_num++; } // for the alignment in the compact XML file Transform3D Tr3D = Transform3D(det_rot,det_pos); PlacedVolume env_phv = motherVol.placeVolume(envelopeVol,Tr3D); env_phv.addPhysVolID("system",x_det.id()); sdet.setPlacement(env_phv); return sdet; }
static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { //XML detector object: DDCore/XML/XMLDetector.h xml_dim_t x_det = e; //Create the DetElement for DD4hep DetElement d_det(x_det.nameStr(),x_det.id()); //XML dimension object: DDCore/XML/XMLDimension.h xml_dim_t x_det_dim(x_det.dimensions()); //double inner_r = x_det_dim.rmin(); //double outer_r = x_det_dim.rmax(); Assembly calo_vol(x_det.nameStr()+"_envelope"); PlacedVolume pv; //Set envelope volume attributes calo_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); #if 0 //Declare this sensitive detector as a calorimeter Tube tub(inner_r,outer_r,x_det_dim.z()/2.0,0.0,2*M_PI); //Volume tub_vol(x_det.nameStr()+"_tube",tub,lcdd.material("PyrexGlass")); Volume tub_vol(x_det.nameStr()+"_tube",tub,lcdd.material("Iron")); calo_vol.placeVolume(tub_vol); sens.setType("calorimeter"); tub_vol.setSensitiveDetector(sens); d_det.setAttributes(lcdd,tub_vol,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); #endif #if 1 int layer_num = 0; float layer_pos_z = 0; double tile_phi = 2*M_PI/x_det_dim.phiBins(); float r = x_det_dim.rmin(); bool debug = true; Assembly stave_vol(x_det.nameStr()+"_stave_0"); //Repeat layers until we reach the rmax while(r<x_det_dim.rmax()) { //Loop over layers of type: XML Collection_t object: DDCore/XML/XMLElements.h for(DD4hep::XML::Collection_t layerIt(x_det,_U(layer)); layerIt; ++layerIt, ++layer_num) { //Build a layer volume xml_comp_t x_det_layer = layerIt; float dr = x_det_layer.dr(); string layer_name = x_det.nameStr()+_toString(layer_num,"_layer%d"); float x1 = r * tan(tile_phi/2.); float x2 = (r+dr) * tan(tile_phi/2.); float y1 = x_det_dim.z(); float y2 = x_det_dim.z(); float z = x_det_layer.dr(); if(debug) { cout << " r:" << r << " dr:" << dr << " x1:" << x1 << " x2:" << x2 << " y1:" << y1 << " y2:" << y2 << " z:" << z << endl; } //Shape a Trapezoid (tile): DDCore/DD4hep/Shapes.h Trapezoid layer_shape(x1,x2,y1,y2,z); //Create a volume with trapezoid shape Volume layer_vol(layer_name, layer_shape, lcdd.air()); layer_vol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det_layer.visStr()); //DetElement layer(layer_name,_toString(layer_num,"layer%d"),x_det.id()); //Fill the volume with tiles vector<Volume> tiles; //Assembly tile_seq(layer_name+"_seq"); Trapezoid tile_seq_shape(x1,x2,x_det_layer.dz(),x_det_layer.dz(),x_det_layer.dr()); Volume tile_seq(layer_name + "_seq",tile_seq_shape,lcdd.air()); double total_thickness = 0; //Repeat slices until we reach the end of the calorimeter int slice_num = 0, tile_number = 0; tile_seq.setVisAttributes(lcdd.visAttributes("VisibleGreen")); for(xml_coll_t k(x_det_layer,_U(slice)); k; ++k, ++slice_num) { xml_comp_t tile_xml = k; string tile_name = layer_name + _toString(tile_number,"_slice%d"); Material tile_material = lcdd.material(tile_xml.materialStr()); float tile_thickness = tile_xml.dz(); float tile_y1 = tile_thickness; float tile_y2 = tile_thickness; float tile_z = x_det_layer.dr(); Trapezoid tile_shape(x1,x2,tile_y1,tile_y2,tile_z); Volume tile_vol(tile_name,tile_shape,tile_material); pv = tile_seq.placeVolume(tile_vol,Position(0,total_thickness,0)); pv.addPhysVolID("slice",slice_num); total_thickness += tile_thickness; if ( tile_xml.isSensitive() ) { cout << "Set volume " << tile_name << " sensitive...." << endl; tile_vol.setSensitiveDetector(sens); } // Set region, limitset, and visibility settings tile_vol.setAttributes(lcdd,tile_xml.regionStr(),tile_xml.limitsStr(),tile_xml.visStr()); tiles.push_back(tile_vol); tile_number++; } // Place the same volumes inside the envelope float tile_pos_z = -x_det_dim.z()/2.; int tile_num = 0; while(tile_pos_z<x_det_dim.z()/2.) { pv = layer_vol.placeVolume(tile_seq,Position(0,tile_pos_z,0)); pv.addPhysVolID("tile",tile_num); tile_pos_z += total_thickness; tile_num++; } // Place the same layer around the beam axis phiBins times Transform3D tr(RotationZYX(M_PI*0.5,M_PI*0.5,0),Translation3D(r,0,layer_pos_z)); pv = stave_vol.placeVolume(layer_vol,tr); pv.addPhysVolID("layer",layer_num); r += dr; cout << "+++ R=" << r << endl; } } //double mod_x_off = outer_r - (outer_r-inner_r)/2.0; //double mod_y_off = 0; int nphi_bins = x_det_dim.phiBins(); for(int i=0; i<nphi_bins; i++) { if(debug) cout << "Layer:" << i << " phi:" << tile_phi << " rotz:" << (tile_phi*i) << endl; double phi = tile_phi*i; //double pos_x = mod_x_off * cos(phi) - mod_y_off * sin(phi); //double pos_y = mod_x_off * sin(phi) + mod_y_off * cos(phi); Transform3D tr(RotationZYX(phi,0,0),Translation3D(0,0,0)); pv = calo_vol.placeVolume(stave_vol,tr); pv.addPhysVolID("stave",i+1); } cout << "Number of layers: " << layer_num << endl; #endif //Place the calo inside the world PlacedVolume calo_plv = lcdd.pickMotherVolume(d_det).placeVolume(calo_vol); calo_plv.addPhysVolID("system",x_det.id()); calo_plv.addPhysVolID("barrel",0); d_det.setPlacement(calo_plv); return d_det; }
static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens) { xml_det_t x_det = e; xml_dim_t dim = x_det.dimensions(); int det_id = x_det.id(); bool reflect = x_det.reflect(true); string det_name = x_det.nameStr(); Material air = lcdd.air(); int numsides = dim.numsides(); double rmin = dim.rmin(); double rmax = dim.rmax()*std::cos(M_PI/numsides); double zmin = dim.zmin(); Layering layering(x_det); double totalThickness = layering.totalThickness(); Volume endcapVol("endcap",PolyhedraRegular(numsides,rmin,rmax,totalThickness),air); DetElement endcap("endcap",det_id); int l_num = 1; int layerType = 0; double layerZ = -totalThickness/2; endcapVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); for(xml_coll_t c(x_det,_U(layer)); c; ++c) { xml_comp_t x_layer = c; double l_thick = layering.layer(l_num-1)->thickness(); string l_name = _toString(layerType,"layer%d"); int l_repeat = x_layer.repeat(); Volume l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air); vector<PlacedVolume> sensitives; int s_num = 1; double sliceZ = -l_thick/2; for(xml_coll_t s(x_layer,_U(slice)); s; ++s) { xml_comp_t x_slice = s; string s_name = _toString(s_num,"slice%d"); double s_thick = x_slice.thickness(); Material s_mat = lcdd.material(x_slice.materialStr()); Volume s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat); s_vol.setVisAttributes(lcdd.visAttributes(x_slice.visStr())); sliceZ += s_thick/2; PlacedVolume s_phv = l_vol.placeVolume(s_vol,Position(0,0,sliceZ)); s_phv.addPhysVolID("slice",s_num); if ( x_slice.isSensitive() ) { sens.setType("calorimeter"); s_vol.setSensitiveDetector(sens); sensitives.push_back(s_phv); } sliceZ += s_thick/2; s_num++; } l_vol.setVisAttributes(lcdd.visAttributes(x_layer.visStr())); if ( l_repeat <= 0 ) throw std::runtime_error(x_det.nameStr()+"> Invalid repeat value"); for(int j=0; j<l_repeat; ++j) { string phys_lay = _toString(l_num,"layer%d"); layerZ += l_thick/2; DetElement layer_elt(endcap, phys_lay, l_num); PlacedVolume pv = endcapVol.placeVolume(l_vol,Position(0,0,layerZ)); pv.addPhysVolID("layer", l_num); layer_elt.setPlacement(pv); for(size_t ic=0; ic<sensitives.size(); ++ic) { PlacedVolume sens_pv = sensitives[ic]; DetElement comp_elt(layer_elt,sens_pv.volume().name(),l_num); comp_elt.setPlacement(sens_pv); } layerZ += l_thick/2; ++l_num; } ++layerType; } double z_pos = zmin+totalThickness/2; PlacedVolume pv; // Reflect it. if ( reflect ) { Assembly assembly(det_name); DetElement both_endcaps(det_name,det_id); Volume motherVol = lcdd.pickMotherVolume(both_endcaps); DetElement sdetA = endcap; Ref_t(sdetA)->SetName((det_name+"_A").c_str()); DetElement sdetB = endcap.clone(det_name+"_B",x_det.id()); pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0), Position(0,0,z_pos))); pv.addPhysVolID("barrel", 1); sdetA.setPlacement(pv); pv = assembly.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,M_PI,0), Position(0,0,-z_pos))); pv.addPhysVolID("barrel", 2); sdetB.setPlacement(pv); pv = motherVol.placeVolume(assembly); pv.addPhysVolID("system", det_id); both_endcaps.setPlacement(pv); both_endcaps.add(sdetA); both_endcaps.add(sdetB); return both_endcaps; } Volume motherVol = lcdd.pickMotherVolume(endcap); pv = motherVol.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,0,0), Position(0,0,z_pos))); pv.addPhysVolID("system", det_id); pv.addPhysVolID("barrel", 1); endcap.setPlacement(pv); Ref_t(endcap)->SetName(det_name.c_str()); return endcap; }