diff --git a/src/GenericDetectors/CMakeLists.txt b/src/GenericDetectors/CMakeLists.txt index ab59bbda333f92c7161fce203249f9a9158efab3..a66ea81eea2ad45deaf709cb0e1d6a91067df544 100644 --- a/src/GenericDetectors/CMakeLists.txt +++ b/src/GenericDetectors/CMakeLists.txt @@ -26,9 +26,16 @@ dd4hep_add_plugin(GenDetectors trackers/src/SimpleRomanPot_geo.cpp calorimeters/src/CylindricalEndcapCalorimeter_geo.cpp calorimeters/src/EcalBarrel_geo.cpp + calorimeters/src/PolyhedraEndcapCalorimeter3_geo.cpp beamline/src/Beampipe_geo.cpp NOINSTALL ) +target_compile_features(GenDetectors + PUBLIC cxx_auto_type + PUBLIC cxx_trailing_return_types + PRIVATE cxx_variadic_templates + PRIVATE cxx_std_14 + ) install(TARGETS GenDetectors EXPORT NPDetTargets diff --git a/src/GenericDetectors/calorimeters/src/PolyhedraEndcapCalorimeter3_geo.cpp b/src/GenericDetectors/calorimeters/src/PolyhedraEndcapCalorimeter3_geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ede25859db338f911a109b45687f8a76b8eb470 --- /dev/null +++ b/src/GenericDetectors/calorimeters/src/PolyhedraEndcapCalorimeter3_geo.cpp @@ -0,0 +1,139 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +// +// Specialized generic detector constructor +// +//========================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "XML/Layering.h" + +using namespace std; +using namespace dd4hep; +using namespace dd4hep::detail; + +static Ref_t create_detector(Detector& description, 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 = description.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(description,x_det.regionStr(),x_det.limitsStr(),x_det.visStr()); + + for(xml_coll_t xc(x_det,_U(layer)); xc; ++xc) { + xml_comp_t x_layer = xc; + 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 xs(x_layer,_U(slice)); xs; ++xs) { + xml_comp_t x_slice = xs; + string s_name = _toString(s_num,"slice%d"); + double s_thick = x_slice.thickness(); + Material s_mat = description.material(x_slice.materialStr()); + Volume s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat); + + s_vol.setVisAttributes(description.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(description.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 = description.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; + //} + double ref_angle = 0.0; + double ref_zpos = 1.0; + if ( reflect ) { + ref_angle = M_PI; + ref_zpos = -1.0; + } + Volume motherVol = description.pickMotherVolume(endcap); + pv = motherVol.placeVolume(endcapVol,Transform3D(RotationZYX(M_PI/numsides,ref_angle,0), + Position(0,0,ref_zpos*z_pos))); + pv.addPhysVolID("system", det_id); + pv.addPhysVolID("barrel", 1); + endcap.setPlacement(pv); + Ref_t(endcap)->SetName(det_name.c_str()); + return endcap; +} + +DECLARE_DETELEMENT(DD4hep_PolyhedraEndcapCalorimeter3,create_detector)