From c6e84894a199c5ddc25dd8d81bfe987d91c0d691 Mon Sep 17 00:00:00 2001 From: Nazar Bartosik Date: Thu, 30 Jan 2020 17:48:19 +0100 Subject: [PATCH 1/2] Added a modified version of the Generic Cal Endcap without cutout --- .../GenericCalEndcap_o2_v01_geo.cpp | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp diff --git a/detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp b/detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp new file mode 100644 index 000000000..ba44512d8 --- /dev/null +++ b/detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp @@ -0,0 +1,253 @@ +//==================================================================== +// Modified Generic Endcap Driver for the CLIC detector +//-------------------------------------------------------------------- +// +// Author : N.Nikiforou +// Adapted from PolyhedraBarrel Calorimeter by M. Frank +// Note: This driver supports conical inner shape in the endcap controlled by rmin and rmin2 +// +//==================================================================== +#include "DD4hep/DetFactoryHelper.h" +#include "XML/Layering.h" +#include "XML/Utilities.h" +#include "DDRec/DetectorData.h" +#include "DDSegmentation/Segmentation.h" + + +using namespace std; + +using dd4hep::BUILD_ENVELOPE; +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::Layering; +using dd4hep::Material; +using dd4hep::PlacedVolume; +using dd4hep::Cone; +using dd4hep::PolyhedraRegular; +using dd4hep::Position; +using dd4hep::Readout; +using dd4hep::Ref_t; +using dd4hep::RotationZYX; +using dd4hep::Segmentation; +using dd4hep::SensitiveDetector; +using dd4hep::SubtractionSolid; +using dd4hep::Transform3D; +using dd4hep::Volume; +using dd4hep::_toString; + +using dd4hep::rec::LayeredCalorimeterData; + +// workaround for DD4hep v00-14 (and older) +#ifndef DD4HEP_VERSION_GE +#define DD4HEP_VERSION_GE(a,b) 0 +#endif + +static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + DetElement sdet (det_name,det_id); + + // --- create an envelope volume and position it into the world --------------------- + + Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector, e , sdet ) ; + dd4hep::xml::setDetectorTypeFlag( e, sdet ) ; + + if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ; + + //----------------------------------------------------------------------------------- + + xml_dim_t dim = x_det.dimensions(); + Material air = theDetector.air(); + int nsides_inner = dim.nsides_inner(); + int nsides_outer = dim.nsides_outer(); + double rmin = dim.rmin(); + double rmax = dim.rmax(); /// FIXME: IS THIS RIGHT? + double zmin = dim.zmin(); + // Second internal radius for the conical cutout + double rmin2 = dim.hasAttr(_U(rmin2)) ? dim.rmin2() : rmin; + + Layering layering(x_det); + double totalThickness = layering.totalThickness(); + int n_layers = layering.layers().size(); + Readout readout = sens.readout(); + Segmentation seg = readout.segmentation(); + + std::vector cellSizeVector = seg.segmentation()->cellDimensions(0); //Assume uniform cell sizes, provide dummy cellID + double cell_sizeX = cellSizeVector[0]; + double cell_sizeY = cellSizeVector[1]; + + + PolyhedraRegular polyVolume(nsides_outer,0,rmax,totalThickness); + Volume endcapVol("endcap",polyVolume,air); + + + if(rmin2 != rmin){ + Cone cutoutPolyVolume(totalThickness/1.99, 0,rmin, 0,rmin2); + endcapVol=Volume("endcap", SubtractionSolid(polyVolume, cutoutPolyVolume, Position(0,0,0)), air); + + } + + + DetElement endcapA(sdet,"endcap",det_id); + Ref_t(endcapA)->SetName((det_name+"_A").c_str()); + + int layer_num = 0; + int layerType = 0; + double layerZ = -totalThickness/2; + + //Create caloData object to extend driver with data required for reconstruction + LayeredCalorimeterData* caloData = new LayeredCalorimeterData ; + caloData->layoutType = LayeredCalorimeterData::EndcapLayout ; + caloData->inner_symmetry = nsides_inner; + caloData->outer_symmetry = nsides_outer; + + /** NOTE: phi0=0 means lower face flat parallel to experimental floor + * This is achieved by rotating the modules with respect to the envelope + * which is assumed to be a Polyhedron and has its axes rotated with respect + * to the world by 180/nsides. In any other case (e.g. if you want to have + * a tip of the calorimeter touching the ground) this value needs to be computed + */ + + caloData->inner_phi0 = 0.; + caloData->outer_phi0 = 0.; + caloData->gap0 = 0.; //FIXME + caloData->gap1 = 0.; //FIXME + caloData->gap2 = 0.; //FIXME + + + /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm. + caloData->extent[0] = rmin ; + caloData->extent[1] = rmax ; ///FIXME: CHECK WHAT IS NEEDED (EXSCRIBED?) + caloData->extent[2] = zmin ; + caloData->extent[3] = zmin + totalThickness; + + endcapVol.setAttributes(theDetector,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 layer_thick = layering.layer(layer_num)->thickness(); + string layer_type_name = _toString(layerType,"layerType%d"); + int layer_repeat = x_layer.repeat(); + double layer_rmin = x_layer.rmin(); + + std::cout<<"Number of layers in group "< Invalid repeat value"); + + for(int j=0; jlayers.push_back( caloLayer ); + + layerZ += layer_thick/2; + DetElement layer_elt(endcapA, phys_lay, layer_num); + PlacedVolume pv = endcapVol.placeVolume(layer_vol,Position(0,0,layerZ)); + pv.addPhysVolID("layer", layer_num); + layer_elt.setPlacement(pv); + + layerZ += layer_thick/2; + ++layer_num; + } + ++layerType; + } + + double z_pos = zmin+totalThickness/2; + PlacedVolume pv; + // Reflect it. + + DetElement endcapB = endcapA.clone(det_name+"_B",x_det.id()); + + //Removed rotations to align with envelope + //NOTE: If the envelope is not a polyhedron (eg. if you use a tube) + //you may need to rotate so the axes match + + pv = envelope.placeVolume(endcapVol,Transform3D(RotationZYX(0,0,0), + Position(0,0,z_pos))); + pv.addPhysVolID("side", 1); + endcapA.setPlacement(pv); + + //Removed rotations + pv = envelope.placeVolume(endcapVol,Transform3D(RotationZYX(0,M_PI,0), + Position(0,0,-z_pos))); + pv.addPhysVolID("side", 2); + endcapB.setPlacement(pv); + + sdet.add(endcapB); + + sdet.addExtension< LayeredCalorimeterData >( caloData ) ; + + return sdet; + +} + +DECLARE_DETELEMENT(GenericCalEndcap_o2_v01,create_detector) + From 549064d33335acc50c9a54fe8e530f0b706a1f49 Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Tue, 26 Nov 2024 12:11:12 +0100 Subject: [PATCH 2/2] Remove unused variable --- detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp b/detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp index ba44512d8..d5410e9d6 100644 --- a/detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp +++ b/detector/calorimeter/GenericCalEndcap_o2_v01_geo.cpp @@ -69,7 +69,6 @@ static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector s Layering layering(x_det); double totalThickness = layering.totalThickness(); - int n_layers = layering.layers().size(); Readout readout = sens.readout(); Segmentation seg = readout.segmentation();