Skip to content

Commit 8828eb6

Browse files
committed
feat: port of IronCylinder to python as test/example
1 parent 19e30c3 commit 8828eb6

3 files changed

Lines changed: 172 additions & 1 deletion

File tree

examples/ClientTests/CMakeLists.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ install(TARGETS testLoad RUNTIME DESTINATION bin)
4949
#
5050
#
5151
set(ClientTestsEx_INSTALL ${CMAKE_INSTALL_PREFIX}/examples/ClientTests)
52-
dd4hep_install_dir( compact scripts ref eve DESTINATION ${ClientTestsEx_INSTALL} )
52+
dd4hep_install_dir( compact scripts python ref eve DESTINATION ${ClientTestsEx_INSTALL} )
5353
#--------------------------------------------------------------------------
5454

5555
#--------------------------------------------------------------------------
@@ -335,6 +335,21 @@ foreach (test Assemblies BoxTrafos CaloEndcapReflection IronCylinder LheD_tracke
335335
endforeach()
336336
#
337337
#
338+
# Test DD4hep_PythonDetector: a Python port of the IronCylinder geometry.
339+
# DD4hep_PythonDetector is only available when DDPythonPlugins is built,
340+
# which requires ROOT to include Python/TPython support.
341+
if(TARGET ROOT::ROOTTPython)
342+
dd4hep_add_test_reg( ClientTests_volume_materials_IronCylinder_python
343+
COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
344+
EXEC_ARGS geoPluginRun -print WARNING -volmgr -destroy
345+
-input file:${ClientTestsEx_INSTALL}/compact/IronCylinder_python.xml
346+
-plugin DD4hep_VolumeDump -materials
347+
REGEX_PASS "\\+\\+\\+ Checked [1-9][0-9]* materials in volume placements. 0 are BAD."
348+
REGEX_FAIL "Exception"
349+
REGEX_FAIL "FAILED" )
350+
endif(TARGET ROOT::ROOTTPython)
351+
#
352+
#
338353
# Note:
339354
# IronCylinder has no segmentation!
340355
# MaterialTester no geometry
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<lccdd>
3+
<!-- #==========================================================================
4+
# AIDA Detector description implementation
5+
#==========================================================================
6+
# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
7+
# All rights reserved.
8+
#
9+
# For the licensing terms see $DD4hepINSTALL/LICENSE.
10+
# For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
11+
#
12+
#==========================================================================
13+
#
14+
# IronCylinder_python.xml
15+
#
16+
# Mirrors IronCylinder.xml but uses the DD4hep_PythonDetector factory to
17+
# delegate geometry construction to IronCylinder_python_geo.py. This
18+
# exercises the python-geo-plugin in DDCore/src/python/PythonPlugin.cpp.
19+
#
20+
#==========================================================================
21+
-->
22+
23+
<includes>
24+
<gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/>
25+
<gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/>
26+
</includes>
27+
28+
<define>
29+
<constant name="world_size" value="30*m"/>
30+
<constant name="world_x" value="world_size"/>
31+
<constant name="world_y" value="world_size"/>
32+
<constant name="world_z" value="world_size"/>
33+
<constant name="HcalBarrel_rmin" value="300*cm"/>
34+
<constant name="HcalBarrel_rmax" value="500*cm"/>
35+
<constant name="HcalBarrel_zmax" value="600*cm"/>
36+
</define>
37+
38+
<display>
39+
<vis name="Invisible" showDaughters="false" visible="false"/>
40+
<vis name="InvisibleWithChildren" showDaughters="true" visible="false"/>
41+
<vis name="VisibleGreen" alpha="1.0" r="0.0" g="1.0" b="0.0" drawingStyle="solid" lineStyle="solid" showDaughters="true" visible="true"/>
42+
</display>
43+
44+
<limits>
45+
<limitset name="cal_limits">
46+
<limit name="step_length_max" particles="*" value="5.0" unit="mm" />
47+
</limitset>
48+
</limits>
49+
50+
<detectors>
51+
<detector id="1" name="HcalBarrel"
52+
type="DD4hep_PythonDetector"
53+
module="IronCylinder_python_geo"
54+
function="create_detector"
55+
pythonpath="${DD4hepExamplesINSTALL}/examples/ClientTests/python"
56+
readout="HcalBarrelHits" vis="VisibleGreen" limits="cal_limits">
57+
<comment>Iron cylinder calorimeter built by the Python geometry plugin.</comment>
58+
<dimensions rmin="HcalBarrel_rmin" rmax="HcalBarrel_rmax" z="HcalBarrel_zmax" phiBins="64"/>
59+
</detector>
60+
</detectors>
61+
62+
<readouts>
63+
<readout name="HcalBarrelHits">
64+
<id>system:8,barrel:3,module:7,layer:5,slice:10,eta:10,phi:5</id>
65+
</readout>
66+
</readouts>
67+
68+
<fields>
69+
<field name="GlobalSolenoid" type="solenoid"
70+
inner_field="5.0*tesla"
71+
outer_field="-1.5*tesla"
72+
zmax="2*m"
73+
outer_radius="3*m">
74+
</field>
75+
</fields>
76+
77+
</lccdd>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# ==========================================================================
2+
# AIDA Detector description implementation
3+
# --------------------------------------------------------------------------
4+
# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
5+
# All rights reserved.
6+
#
7+
# For the licensing terms see $DD4hepINSTALL/LICENSE.
8+
# For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
9+
#
10+
# ==========================================================================
11+
#
12+
# IronCylinder_python_geo.py — Python port of IronCylinder_geo.cpp.
13+
#
14+
# Demonstrates the DD4hep_PythonDetector factory:
15+
# - Reads detector dimensions from the compact XML.
16+
# - Builds an iron tube sensitive calorimeter volume.
17+
# - Places it inside the world volume.
18+
#
19+
# ==========================================================================
20+
21+
from dd4hep_geo_plugin import Assembly, DetElement, Tube, Volume, TMath, xml_det_t
22+
23+
24+
def create_detector(description, xml_h, sens):
25+
"""Build an iron cylindrical calorimeter.
26+
27+
Parameters
28+
----------
29+
description : dd4hep.Detector
30+
The top-level detector description object.
31+
xml_h : dd4hep.xml.Handle_t
32+
Handle to the ``<detector>`` XML element.
33+
sens : dd4hep.SensitiveDetector
34+
Sensitive detector assigned to this sub-detector.
35+
36+
Returns
37+
-------
38+
dd4hep.DetElement
39+
The fully placed detector element.
40+
"""
41+
x_det = xml_det_t(xml_h)
42+
name = x_det.nameStr()
43+
44+
d_det = DetElement(name, x_det.id())
45+
46+
# Read dimensions from the compact XML.
47+
x_dim = x_det.dimensions()
48+
inner_r = x_dim.rmin()
49+
outer_r = x_dim.rmax()
50+
z_half = x_dim.z() / 2.0
51+
52+
# Envelope assembly volume.
53+
calo_vol = Assembly(name + "_envelope")
54+
calo_vol.setAttributes(description,
55+
x_det.regionStr(),
56+
x_det.limitsStr(),
57+
x_det.visStr())
58+
59+
# Sensitive iron tube.
60+
tub = Tube(inner_r, outer_r, z_half, 0.0, TMath.TwoPi())
61+
tub_vol = Volume(name + "_tube", tub,
62+
description.material("Iron"))
63+
calo_vol.placeVolume(tub_vol).addPhysVolID("module", 1)
64+
65+
sens.setType("calorimeter")
66+
tub_vol.setSensitiveDetector(sens)
67+
d_det.setAttributes(description, tub_vol,
68+
x_det.regionStr(),
69+
x_det.limitsStr(),
70+
x_det.visStr())
71+
72+
# Place the envelope inside the world / mother volume.
73+
mother = description.pickMotherVolume(d_det)
74+
calo_plv = mother.placeVolume(calo_vol)
75+
calo_plv.addPhysVolID("system", x_det.id())
76+
calo_plv.addPhysVolID("barrel", 0)
77+
d_det.setPlacement(calo_plv)
78+
79+
return d_det

0 commit comments

Comments
 (0)