From 96f504af3f3fbe1ed1f6f09a554976a6900e33d2 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 30 May 2018 17:29:06 +0200 Subject: [PATCH] Fix shape issues (bugs) for CMS --- DDCore/include/DD4hep/Shapes.h | 10 +- DDCore/include/Parsers/detail/Dimension.h | 12 ++ DDCore/include/Parsers/detail/Dimension.imp | 6 + DDCore/include/XML/UnicodeValues.h | 4 + DDCore/src/Shapes.cpp | 55 +++++---- DDDetectors/src/ConeSegment_geo.cpp | 54 ++++++++ examples/DDCodex/CMakeLists.txt | 34 +++++ examples/DDCodex/CODEX-b.jpg | Bin 0 -> 24567 bytes examples/DDCodex/README.txt | 77 ++++++++++++ examples/DDCodex/compact/CODEX-b.xml | 53 ++++++++ examples/DDCodex/src/CODEXb_geo.cpp | 130 ++++++++++++++++++++ 11 files changed, 408 insertions(+), 27 deletions(-) create mode 100644 DDDetectors/src/ConeSegment_geo.cpp create mode 100644 examples/DDCodex/CMakeLists.txt create mode 100644 examples/DDCodex/CODEX-b.jpg create mode 100644 examples/DDCodex/README.txt create mode 100644 examples/DDCodex/compact/CODEX-b.xml create mode 100644 examples/DDCodex/src/CODEXb_geo.cpp diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h index 4d7860a01..de932ffae 100644 --- a/DDCore/include/DD4hep/Shapes.h +++ b/DDCore/include/DD4hep/Shapes.h @@ -502,8 +502,8 @@ namespace dd4hep { template <typename Q> Trap(const Handle<Q>& e) : Solid_type<Object>(e) { } /// Constructor to create a new anonymous object with attribute initialization Trap(double z, double theta, double phi, - double y1, double x1, double x2, double alpha1, - double y2, double x3, double x4, double alpha2); + double h1, double bl1, double tl1, double alpha1, + double h2, double bl2, double tl2, double alpha2); /// Constructor to create a new anonymous object for right angular wedge from STEP (Se G4 manual for details) Trap(double pz, double py, double px, double pLTX) { make(pz,py,px,pLTX); } /// Constructor to create a new anonymous object with attribute initialization @@ -512,9 +512,9 @@ namespace dd4hep { /// Assignment operator Trap& operator=(const Trap& copy) = default; /// Set the trap dimensions - Trap& setDimensions(double z, double theta, double phi, - double y1, double x1, double x2, double alpha1, - double y2, double x3, double x4, double alpha2); + Trap& setDimensions(double z, double theta, double phi, + double h1, double bl1, double tl1, double alpha1, + double h2, double bl2, double tl2, double alpha2); }; /// Class describing a pseudo trap shape (CMS'ism) diff --git a/DDCore/include/Parsers/detail/Dimension.h b/DDCore/include/Parsers/detail/Dimension.h index 07166bbda..eba4aafbd 100644 --- a/DDCore/include/Parsers/detail/Dimension.h +++ b/DDCore/include/Parsers/detail/Dimension.h @@ -554,6 +554,16 @@ namespace dd4hep { Dimension position(bool throw_if_not_present = true) const; /// Child access: rotation Dimension rotation(bool throw_if_not_present = true) const; + /// Child access: cone + Dimension cone(bool throw_if_not_present = true) const; + /// Child access: sphere + Dimension sphere(bool throw_if_not_present = true) const; + /// Child access: torus + Dimension torus(bool throw_if_not_present = true) const; + /// Child access: trap + Dimension trap(bool throw_if_not_present = true) const; + /// Child access: trapezoid + Dimension trapezoid(bool throw_if_not_present = true) const; /// Child access: trd Dimension trd(bool throw_if_not_present = true) const; /// Child access: tubs @@ -562,6 +572,8 @@ namespace dd4hep { Dimension staves(bool throw_if_not_present = true) const; /// Child access: beampipe Dimension beampipe(bool throw_if_not_present = true) const; + /// Child access: beampipe + Dimension envelope(bool throw_if_not_present = true) const; /// Access "name" attribute as STL string std::string nameStr() const; diff --git a/DDCore/include/Parsers/detail/Dimension.imp b/DDCore/include/Parsers/detail/Dimension.imp index 1380c248c..411268fd0 100644 --- a/DDCore/include/Parsers/detail/Dimension.imp +++ b/DDCore/include/Parsers/detail/Dimension.imp @@ -184,9 +184,15 @@ XML_ATTR_ACCESSOR_DOUBLE(temperature) XML_CHILD_ACCESSOR_XML_DIM(dimensions) XML_CHILD_ACCESSOR_XML_DIM(position) XML_CHILD_ACCESSOR_XML_DIM(rotation) +XML_CHILD_ACCESSOR_XML_DIM(cone) +XML_CHILD_ACCESSOR_XML_DIM(sphere) +XML_CHILD_ACCESSOR_XML_DIM(torus) +XML_CHILD_ACCESSOR_XML_DIM(trap) +XML_CHILD_ACCESSOR_XML_DIM(trapezoid) XML_CHILD_ACCESSOR_XML_DIM(trd) XML_CHILD_ACCESSOR_XML_DIM(tubs) XML_CHILD_ACCESSOR_XML_DIM(staves) +XML_CHILD_ACCESSOR_XML_DIM(envelope) XML_CHILD_ACCESSOR_XML_DIM(beampipe) std::string dd4hep::DD4HEP_DIMENSION_NS::Dimension::padType() const { diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index e13a9ad5a..f5bf9f125 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -125,6 +125,7 @@ UNICODE (end_module); UNICODE (end_modules); UNICODE (endcap); UNICODE (endphi); +UNICODE (envelope); UNICODE (epsilon); UNICODE (eunit); UNICODE (end_x); @@ -387,6 +388,7 @@ UNICODE (sensor); UNICODE (sequence); UNICODE (setup); UNICODE (shape); +UNICODE (shield); UNICODE (show_daughters); UNICODE (showDaughters); UNICODE (size); @@ -399,6 +401,7 @@ UNICODE (solids); UNICODE (solidref); UNICODE (spacer); UNICODE (sphere); +UNICODE (station); UNICODE (status); UNICODE (start); UNICODE (start_x); @@ -430,6 +433,7 @@ UNICODE (tracker); UNICODE (tracking_cylinder); UNICODE (tracking_volume); UNICODE (trap); +UNICODE (trapezoid); UNICODE (trd); UNICODE (true); UNICODE (tube); diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index dafbadbaf..7fd78f314 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -452,7 +452,9 @@ Hyperboloid& Hyperboloid::setDimensions(double rin, double stin, double rout, do /// Constructor to be used when creating a new object with attribute initialization Sphere::Sphere(double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi) { - _assign(new TGeoSphere(rmin, rmax, theta/units::deg, delta_theta/units::deg, phi/units::deg, delta_phi/units::deg), "", "sphere", true); + _assign(new TGeoSphere(rmin, rmax, + theta/units::deg, delta_theta/units::deg, + phi/units::deg, delta_phi/units::deg), "", "sphere", true); } /// Set the Sphere dimensions @@ -475,42 +477,51 @@ Torus& Torus::setDimensions(double r, double rmin, double rmax, double phi, doub } /// Constructor to be used when creating a new anonymous object with attribute initialization -Trap::Trap(double z, double theta, double phi, double y1, double x1, double x2, double alpha1, double y2, double x3, double x4, - double alpha2) { - _assign(new TGeoTrap(z, theta, phi, y1, x1, x2, alpha1/units::deg, y2, x3, x4, alpha2/units::deg), "", "trap", true); +Trap::Trap(double z, double theta, double phi, + double h1, double bl1, double tl1, double alpha1, + double h2, double bl2, double tl2, double alpha2) { + _assign(new TGeoTrap(z, theta/units::deg, phi/units::deg, + h1, bl1, tl1, alpha1/units::deg, + h2, bl2, tl2, alpha2/units::deg), "", "trap", true); } /// Constructor to be used when creating a new anonymous object with attribute initialization void Trap::make(double pz, double py, double px, double pLTX) { - double z = pz / 2e0; - double theta = 0e0; - double phi = 0e0; - double y1 = py / 2e0; - double x1 = px / 2e0; - double x2 = pLTX / 2e0; + double z = pz / 2e0; + double theta = 0e0; + double phi = 0e0; + double h = py / 2e0; + double bl = px / 2e0; + double tl = pLTX / 2e0; double alpha1 = (pLTX - px) / py; - _assign(new TGeoTrap(z, theta, phi, y1, x1, x2, alpha1/units::deg, y1, x1, x2, alpha1/units::deg), "", "trap", true); + _assign(new TGeoTrap(z, theta, phi, + h, bl, tl, alpha1/units::deg, + h, bl, tl, alpha1/units::deg), "", "trap", true); } /// Set the trap dimensions -Trap& Trap::setDimensions(double z, double theta, double phi, double y1, double x1, double x2, double alpha1, double y2, - double x3, double x4, double alpha2) { - double params[] = { z, theta, phi, y1, x1, x2, alpha1/units::deg, y2, x3, x4, alpha2/units::deg }; +Trap& Trap::setDimensions(double z, double theta, double phi, + double h1, double bl1, double tl1, double alpha1, + double h2, double bl2, double tl2, double alpha2) { + double params[] = { z, theta/units::deg, phi/units::deg, + h1, bl1, tl1, alpha1/units::deg, + h2, bl2, tl2, alpha2/units::deg }; _setDimensions(params); return *this; } /// Internal helper method to support object construction void PseudoTrap::make(double x1, double x2, double y1, double y2, double z, double r, bool atMinusZ) { - double x = atMinusZ ? x1 : x2; - double h = 0; - bool intersec = false; // union or intersection solid - double halfOpeningAngle = std::asin( x / std::abs( r ))/units::deg; + double x = atMinusZ ? x1 : x2; + double h = 0; + bool intersec = false; // union or intersection solid double displacement = 0; - double startPhi = 0; - double halfZ = z/2.; - /* calculate the displacement of the tubs w.r.t. to the trap, determine the opening angle of the tubs */ - double delta = std::sqrt( r * r - x * x ); + double startPhi = 0; + double halfZ = z; + double halfOpeningAngle = std::asin( x / std::abs( r ))/units::deg; + + /// calculate the displacement of the tubs w.r.t. to the trap, determine the opening angle of the tubs + double delta = std::sqrt( r * r - x * x ); if( r < 0 && std::abs( r ) >= x ) { intersec = true; // intersection solid diff --git a/DDDetectors/src/ConeSegment_geo.cpp b/DDDetectors/src/ConeSegment_geo.cpp new file mode 100644 index 000000000..9b9f87826 --- /dev/null +++ b/DDDetectors/src/ConeSegment_geo.cpp @@ -0,0 +1,54 @@ +//========================================================================== +// 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" + +using namespace std; +using namespace dd4hep; +using namespace dd4hep::detail; + +static Ref_t create_element(Detector& description, xml_h e, Ref_t sens) { + xml_det_t x_det (e); + xml_comp_t x_cone = x_det.cone(); + xml_dim_t pos = x_det.position(); + xml_dim_t rot = x_det.rotation(); + string name = x_det.nameStr(); + Cone cone (x_cone.dz(),x_cone.rmin1(),x_cone.rmax1(),x_cone.rmin2(),x_cone.rmax2()); + Volume vol (name,cone,description.material(x_det.materialStr())); + + vol.setVisAttributes(description, x_det.visStr()); + vol.setLimitSet(description, x_det.limitsStr()); + vol.setRegion(description, x_det.regionStr()); + if ( x_det.isSensitive() ) { + SensitiveDetector sd = sens; + xml_dim_t sd_typ = x_det.child(_U(sensitive)); + vol.setSensitiveDetector(sens); + sd.setType(sd_typ.typeStr()); + } + + DetElement sdet(name,x_det.id()); + Volume mother = description.pickMotherVolume(sdet); + PlacedVolume phv = + mother.placeVolume(vol,Transform3D(RotationZYX(rot.z(),rot.y(),rot.x()),Position(-pos.x(),-pos.y(),pos.z()))); + if ( x_det.hasAttr(_U(id)) ) { + phv.addPhysVolID("system",x_det.id()); + } + sdet.setPlacement(phv); + return sdet; +} + +DECLARE_DETELEMENT(DD4hep_ConeSegment,create_element) + diff --git a/examples/DDCodex/CMakeLists.txt b/examples/DDCodex/CMakeLists.txt new file mode 100644 index 000000000..e61b4889c --- /dev/null +++ b/examples/DDCodex/CMakeLists.txt @@ -0,0 +1,34 @@ +#========================================================================== +# 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. +# +#========================================================================== +cmake_minimum_required(VERSION 3.3 FATAL_ERROR) +include ( ${DD4hep_DIR}/cmake/DD4hep.cmake ) + +#----------------------------------------------------------------------------------- +dd4hep_configure_output () +dd4hep_package ( DDCodex MAJOR 0 MINOR 0 PATCH 1 + USES [ROOT REQUIRED COMPONENTS Geom] + [DD4hep REQUIRED COMPONENTS DDCore] + ) +# +#---DDCodex plugin library ------------------------------------------------------- +dd4hep_add_plugin(DDCodexPlugins + SOURCES src/*.cpp + USES [ROOT REQUIRED COMPONENTS Geom GenVector] +) +# +# +dd4hep_install_dir( compact scripts DESTINATION ${DD4hep_DIR}/examples/DDCodex ) +#-------------------------------------------------------------------------- +# +dd4hep_configure_scripts ( DDCodex DEFAULT_SETUP WITH_TESTS ) +# +#---Testing------------------------------------------------------------------------- +# diff --git a/examples/DDCodex/CODEX-b.jpg b/examples/DDCodex/CODEX-b.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6998e2bd3618c8cd8976db3d364f32de5f285a18 GIT binary patch literal 24567 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 literal 0 HcmV?d00001 diff --git a/examples/DDCodex/README.txt b/examples/DDCodex/README.txt new file mode 100644 index 000000000..617ba4d5f --- /dev/null +++ b/examples/DDCodex/README.txt @@ -0,0 +1,77 @@ +CODEX starting kit +================== + + +Small geometry driver for CODEX-b sketch. + + +To execute: +---------------------------------------------------------------------------- +$> geoPluginRun -ui -inter +... +root [0] gDD4hepUI->importROOT("Upgrade.root") +root [1] gDD4hepUI->fromXML("checkout/examples/DDCodex/compact/CODEX-b.xml") +root [2] gDD4hepUI->draw() + + +Output: +---------------------------------------------------------------------------- +17:25:30-frankm~/SW/DD4hep_head_dbg.root_v6.12.06.g4_10.04.p01_MT/build$ geoPluginRun -ui -inter +PersistencyIO INFO +++ Set Streamer to dd4hep::OpaqueDataBlock +PersistencyIO INFO +++ Patching TGeoVolume.fUserExtension to persistent +PersistencyIO INFO +++ Patching TGeoNode.fUserExtension to persistent +Info in <TGeoManager::TGeoManager>: Geometry world, Detector Geometry created +geoPluginRun: No geometry input supplied. No geometry will be loaded. +DD4hepUI Use the ROOT interpreter variable gDD4hepUI to interact with the detector description. + ------------------------------------------------------------ + | Welcome to ROOT 6.12/06 http://root.cern.ch | + | (c) 1995-2017, The ROOT Team | + | Built for linuxx8664gcc | + | From tag v6-12-06, 9 February 2018 | + | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' | + ------------------------------------------------------------ + +root [0] gDD4hepUI->importROOT("Upgrade.root") +DD4hepRootLoader INFO +++ Read geometry from root file:Upgrade.root +Warning in <TGeoManager::Init>: Deleting previous geometry: world/Detector Geometry +Info in <TGeoManager::CloseGeometry>: Geometry loaded from file... +Info in <TGeoManager::SetTopVolume>: Top volume is world_volume. Master volume is world_volume +Info in <TGeoNavigator::BuildCache>: --- Maximum geometry depth set to 100 +Info in <TGeoManager::Voxelize>: Voxelizing... +Error in <TGeoVoxelFinder::SortAll>: Volume lvAsicGroup16: Cannot make slices on any axis +Error in <TGeoVoxelFinder::SortAll>: Volume lvAsicGroup4: Cannot make slices on any axis +Error in <TGeoVoxelFinder::SortAll>: Volume lvAsicGroup8: Cannot make slices on any axis +Info in <TGeoManager::CountLevels>: max level = 11, max placements = 171 +Info in <TGeoManager::CloseGeometry>: 18553873 nodes/ 2754 volume UID's in Detector Geometry +Info in <TGeoManager::CloseGeometry>: ----------------modeler ready---------------- +DD4hepRootPersistency +++ Fixed 0 segmentation objects. +DD4hepRootPersistency +++ Volume manager NOT restored. [Was it ever up when saved?] +DD4hepRootPersistency +++ Successfully loaded detector description from file:Upgrade.root [ 7.322 seconds] +(long) 1 +root [1] gDD4hepUI->fromXML("checkout/examples/DDCodex/compact/CODEX-b.xml") +CODEX-b INFO COBEXb Envelope: dz=2000 r1=0 r2=400 beam-angle=1.0472 atan(cone)=0.0996687 +CODEX-b INFO COBEXb Shield: Pb-shield-1 [Lead] z= 700 dz= 150 r1=69.6526 r2=84.5782 +CODEX-b INFO COBEXb Shield: Shield-veto [Si] z= 850 dz= 10 r1=84.5782 r2=85.5732 +CODEX-b INFO COBEXb Shield: Pb-shield-2 [Lead] z= 860 dz= 50 r1=85.5732 r2=90.5484 +CODEX-b INFO COBEXb X_tot= 532 +CODEX-b INFO COBEXb Module: 0 [Si] x=-307.15 y=0 z= 1732 Dist:22 dx:25.4034 dz:44 +CODEX-b INFO COBEXb Module: 1 [Si] x=-281.747 y=0 z= 1776 Dist:22 dx:25.4034 dz:44 +CODEX-b INFO COBEXb Module: 2 [Si] x=-256.344 y=0 z= 1820 Dist:22 dx:25.4034 dz:44 +CODEX-b INFO COBEXb Module: 3 [Si] x=-230.94 y=0 z= 1864 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 4 [Si] x=-193.99 y=0 z= 1928 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 5 [Si] x=-157.039 y=0 z= 1992 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 6 [Si] x=-120.089 y=0 z= 2056 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 7 [Si] x=-83.1384 y=0 z= 2120 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 8 [Si] x=-46.188 y=0 z= 2184 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 9 [Si] x=-9.2376 y=0 z= 2248 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 10 [Si] x=27.7128 y=0 z= 2312 Dist:32 dx:36.9504 dz:64 +CODEX-b INFO COBEXb Module: 11 [Si] x=64.6632 y=0 z= 2376 Dist:42 dx:48.4974 dz:84 +CODEX-b INFO COBEXb Module: 12 [Si] x=113.161 y=0 z= 2460 Dist:42 dx:48.4974 dz:84 +CODEX-b INFO COBEXb Module: 13 [Si] x=161.658 y=0 z= 2544 Dist:42 dx:48.4974 dz:84 +CODEX-b INFO COBEXb Module: 14 [Si] x=210.155 y=0 z= 2628 Dist:42 dx:48.4974 dz:84 +CODEX-b INFO COBEXb Module: 15 [Si] x=258.653 y=0 z= 2712 Dist:42 dx:48.4974 dz:84 +Compact INFO ++ Converted subdetector:COBEXb of type DD4hep_CODEXb +root [2] gDD4hepUI->draw() +Info in <TGeoManager::SetVisLevel>: Automatic visible depth disabled +Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1 +root [3] diff --git a/examples/DDCodex/compact/CODEX-b.xml b/examples/DDCodex/compact/CODEX-b.xml new file mode 100644 index 000000000..4a97c7da0 --- /dev/null +++ b/examples/DDCodex/compact/CODEX-b.xml @@ -0,0 +1,53 @@ +<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd"> +<!-- + <includes> + <gdmlFile ref="elements.xml"/> + <gdmlFile ref="materials.xml"/> + </includes> +--> + <define> + <constant name="COBEX_beam_angle" value="60*degree"/> + <constant name="COBEX_cone_len" value="40*m"/> + </define> + + <comment>Common Generic visualization attributes</comment> + <display> + <vis name="BlackVis" alpha="1" r="0.1" g="0.1" b="0.1" showDaughters="false" visible="true"/> + <vis name="Codex_Envelope_Vis" alpha=".3" r="0.7" g="0.7" b="0.7" showDaughters="true" visible="true"/> + <vis name="Codex_Module1_Vis" alpha="1" r="0.8" g="0.2" b="0.2" showDaughters="true" visible="true"/> + <vis name="Codex_Module2_Vis" alpha="1" r="0.2" g="0.8" b="0.2" showDaughters="true" visible="true"/> + <vis name="Codex_Module3_Vis" alpha="1" r="0.2" g="0.2" b="0.8" showDaughters="true" visible="true"/> + <vis name="Codex_Shield_Pb_Vis" alpha="1" r="0.4" g="0.4" b="0.4" showDaughters="false" visible="true"/> + <vis name="Codex_Shield_Veto_Vis" alpha="1" r="0.9" g="0.9" b="0.0" showDaughters="true" visible="true"/> + </display> + + <geometry open="false" close="false"/> + + <!-- Includes for sensitives and support --> + <detectors> + + <detector name="COBEXb" type="DD4hep_CODEXb" vis="Codex_Envelope_Vis"> + <envelope angle="COBEX_beam_angle" dz="COBEX_cone_len" rmax="4*m"/> + <shield name="Pb-shield-1" z="7*m" dz="1.5*m" material="Lead" sensitive="false" vis="Codex_Shield_Pb_Vis"/> + <shield name="Shield-veto" z="8.5*m" dz="0.1*m" material="Si" sensitive="true" vis="Codex_Shield_Veto_Vis"/> + <shield name="Pb-shield-2" z="8.6*m" dz="0.5*m" material="Lead" sensitive="false" vis="Codex_Shield_Pb_Vis"/> + + <station z="12*m" width="10*m" height="10*m" thickness="2*cm" + material="Si" sensitive="true" vis="Codex_Module1_Vis" + repeat="3" distance="20*cm"/> + <station width="10*m" height="10*m" thickness="2*cm" + material="Si" sensitive="true" vis="Codex_Module2_Vis" + repeat="8" distance="30*cm"/> + <station width="10*m" height="10*m" thickness="2*cm" + material="Si" sensitive="true" vis="Codex_Module3_Vis" + repeat="5" distance="40*cm"/> + + <position x="-sin(COBEX_beam_angle)*COBEX_cone_len/2" y="0" z="cos(COBEX_beam_angle)*COBEX_cone_len/2"/> + <rotation x="0" y="COBEX_beam_angle" z="0"/> + + </detector> + </detectors> + +</lccdd> diff --git a/examples/DDCodex/src/CODEXb_geo.cpp b/examples/DDCodex/src/CODEXb_geo.cpp new file mode 100644 index 000000000..7e104a07d --- /dev/null +++ b/examples/DDCodex/src/CODEXb_geo.cpp @@ -0,0 +1,130 @@ +//========================================================================== +// 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 "DD4hep/Printout.h" + +using namespace std; +using namespace dd4hep; +using namespace dd4hep::detail; + + +static Ref_t create_element(Detector& description, xml_h e, Ref_t sens) { + xml_det_t x_det (e); + xml_comp_t x_envelope = x_det.envelope(); + xml_dim_t pos = x_det.position(); + xml_dim_t rot = x_det.rotation(); + string det_name = x_det.nameStr(); + DetElement sdet(det_name,x_det.id()); + double env_angle = x_envelope.angle(); + double env_dz = x_envelope.dz()/2.0; + double sin_cone = std::sin(std::atan(x_envelope.rmax()/env_dz/2.0)); + double cos_beam = std::cos(env_angle); + double sin_beam = std::sin(env_angle); + Cone env_cone(env_dz,0,0.0001,x_envelope.rmax(),x_envelope.rmax()+0.0001); + Volume env_vol (det_name,env_cone,description.air()); + PlacedVolume pv; + + env_vol.setRegion(description, x_det.regionStr()); + env_vol.setLimitSet(description, x_det.limitsStr()); + env_vol.setVisAttributes(description, x_det.visStr()); + printout(INFO,"CODEX-b","%s Envelope: dz=%g r1=%g r2=%g beam-angle=%g atan(cone)=%g", + det_name.c_str(), env_cone->GetDz(), env_cone->GetRmin1(), env_cone->GetRmax2(), + env_angle, std::atan(x_envelope.rmax()/env_dz/2.0)); + + Tube tub(0, 3, x_envelope.dz()+500); + Volume tub_vol("Tube", tub, description.air()); + tub_vol.setVisAttributes(description, "BlackVis"); + pv = env_vol.placeVolume(tub_vol, Position(0,0,0)); + + int num_sensitive = 0; + for(xml_coll_t i(x_det,_U(shield)); i; ++i) { + xml_comp_t s = i; + double z = s.z(), dz = s.dz(); + double r1 = sin_cone*z, r2 = sin_cone*(z+dz); + string nam = s.nameStr(); + Cone con(dz/2., 0., r1, 0., r2); + Material mat(description.material(s.attr<string>(_U(material)))); + Volume vol(nam,con,mat); + + printout(INFO,"CODEX-b","%s Shield: %-12s %-12s z=%7g dz=%7g r1=%7g r2=%7g", + det_name.c_str(), vol.name(), ('['+string(mat.name())+']').c_str(), z, dz, r1, r2); + vol.setVisAttributes(description, s.visStr()); + pv = env_vol.placeVolume(vol, Position(0,0,-env_dz+z+dz/2.0)); + if ( s.isSensitive() ) { + DetElement det(sdet, "shield_"+nam, x_det.id()); + pv.addPhysVolID("type", 0); + pv.addPhysVolID("module", num_sensitive); + det.setPlacement(pv); + ++num_sensitive; + } + } + + int type_num = 0, station_number = 0; + double z0 = 0.0, x0 = 0.0, x_tot = 0.0; + for(xml_coll_t i(x_det,_U(station)); i; ++i, ++type_num) { + xml_comp_t s = i; + x_tot += double(s.repeat())*(s.distance()+s.thickness()); + } + printout(INFO,"CODEX-b","%s X_tot= %g",det_name.c_str(), x_tot); + for(xml_coll_t i(x_det,_U(station)); i; ++i, ++type_num) { + xml_comp_t s = i; + int repeat = s.repeat(); + string nam = _toString(station_number,"CODEX_station_type%d"); + Box box(s.width()/2., s.height()/2., s.thickness()/2.); + Material mat(description.material(s.attr<string>(_U(material)))); + Volume vol(nam,box,mat); + double dist = s.thickness()+s.distance(); + double dx = dist/sin_beam; + double dz = dist/cos_beam; + if ( s.hasAttr(_U(z)) ) { + z0 = s.z()+x_tot/2.0/cos_beam; + x0 = -x_tot/2.0/sin_beam; + } + vol.setVisAttributes(description, s.visStr()); + for(int j=0; j < repeat; ++j) { + DetElement det(sdet, _toString(station_number,"module%d"), station_number); + pv = env_vol.placeVolume(vol, Transform3D(RotationZYX(0,M_PI/2.0-env_angle,0), Position(x0,0,z0))); + pv.addPhysVolID("type", 1); + pv.addPhysVolID("module", station_number); + printout(INFO,"CODEX-b","%s Module: %2d %-12s x=%g y=%g z=%7g Dist:%g dx:%g dz:%g", + det_name.c_str(), station_number, ('['+string(mat.name())+']').c_str(), + x0, 0.0, z0, dist, dx, dz); + det.setPlacement(pv); + x0 += dx; + z0 += dz; + ++station_number; + } + } + + if ( x_det.isSensitive() ) { + SensitiveDetector sd = sens; + xml_dim_t sd_typ = x_det.child(_U(sensitive)); + env_vol.setSensitiveDetector(sens); + sd.setType(sd_typ.typeStr()); + } + + Volume mother = description.pickMotherVolume(sdet); + pv = mother.placeVolume(env_vol,Transform3D(RotationZYX(rot.z(),rot.y(),rot.x()),Position(-pos.x(),-pos.y(),pos.z()))); + if ( x_det.hasAttr(_U(id)) ) { + pv.addPhysVolID("system",x_det.id()); + } + sdet.setPlacement(pv); + return sdet; +} + +DECLARE_DETELEMENT(DD4hep_CODEXb,create_element) + -- GitLab