diff --git a/examples/ClientTests/compact/BoxOfStraws.xml b/examples/ClientTests/compact/BoxOfStraws.xml new file mode 100644 index 0000000000000000000000000000000000000000..243e4eaeee55b5ccf6be34eaf3938647c9070e9e --- /dev/null +++ b/examples/ClientTests/compact/BoxOfStraws.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lccdd> +<!-- #========================================================================== + # 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. + # + #========================================================================== +--> + + <info name="BoxOfStraws" + title="Test with silicon boxes" + author="Markus Frank" + url="http://www.cern.ch/frankm" + status="development" + version="1.0"> + <comment>Alignment test with 2 simple boxes</comment> + </info> + + <includes> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/> + </includes> + + <define> + <constant name="world_size" value="3*m"/> + <constant name="world_x" value="world_size"/> + <constant name="world_y" value="world_size"/> + <constant name="world_z" value="world_size"/> + </define> + + <display> + <vis name="Invisible" showDaughters="false" visible="false"/> + <vis name="InvisibleWithChildren" showDaughters="true" visible="false"/> + <vis name="VisibleRed" alpha="0.4" r="1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/> + <vis name="VisibleBlue" alpha="1.0" r="0.0" g="0.0" b="1.0" showDaughters="false" visible="true"/> + <vis name="VisibleGreen" alpha="1.0" r="0.0" g="1.0" b="0.0" drawingStyle="solid" lineStyle="solid" showDaughters="true" visible="true"/> + </display> + + <limits> + <limitset name="BoxOfStrawsLimitSet"> + <limit name="step_length_max" particles="*" value="1.0" unit="mm" /> + <limit name="track_length_max" particles="*" value="1.0" unit="mm" /> + </limitset> + </limits> + + <regions> + <region name="StrawRegion" eunit="MeV" lunit="mm" cut="0.001" threshold="0.001"> + <limitsetref name="BoxOfStrawsLimitSet"/> + </region> + </regions> + + <detectors> + <detector id="1" name="BoxOfStrawsDet" type="DD4hep_BoxOfStraws" readout="BoxOfStrawsHits" vis="VisibleGreen" region="StrawRegion" limits="BoxOfStrawsLimitSet"> + <box x="1*m" y="1*m" z="1000*mm" limits="BoxOfStrawsLimitSet" vis="VisibleRed"/> + <straw rmax="1*mm" y="1*m" vis="VisibleBlue"> + <material name="Iron"/> + <non_sensitive/> + </straw> + <position x="0*m" y="0*m" z="0*m"/> + <rotation x="0" y="0" z="0"/> + </detector> + </detectors> + + <readouts> + <readout name="BoxOfStrawsHits"> + <id>system:8,module:16,straw:16,y:-12</id> + </readout> + </readouts> + + <fields> + <field name="GlobalSolenoid" type="solenoid" + inner_field="5.0*tesla" + outer_field="-1.5*tesla" + zmax="2*m" + outer_radius="2*m"> + </field> + </fields> + +</lccdd> diff --git a/examples/ClientTests/scripts/BoxOfStraws.py b/examples/ClientTests/scripts/BoxOfStraws.py new file mode 100644 index 0000000000000000000000000000000000000000..1ea12406dc7de37ae8103456a7a78eb845470d79 --- /dev/null +++ b/examples/ClientTests/scripts/BoxOfStraws.py @@ -0,0 +1,118 @@ +# ========================================================================== +# 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. +# +# ========================================================================== +# +# +from __future__ import absolute_import, unicode_literals +import os +import time +import cmath +import DDG4 +from DDG4 import OutputLevel as Output +from g4units import GeV, MeV, m +# +# +""" + + dd4hep simulation example setup using the python configuration + + @author M.Frank + @version 1.0 + +""" + + +def run(): + args = DDG4.CommandLine() + kernel = DDG4.Kernel() + logger = DDG4.Logger('BoxOfStraws') + install_dir = os.environ['DD4hepExamplesINSTALL'] + kernel.loadGeometry(str("file:" + install_dir + "/examples/ClientTests/compact/BoxOfStraws.xml")) + + DDG4.importConstants(kernel.detectorDescription(), debug=False) + geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction') + geant4.printDetectors() + # Configure UI + if args.macro: + ui = geant4.setupCshUI(macro=args.macro) + else: + ui = geant4.setupCshUI() + if args.batch: + ui.Commands = ['/run/beamOn ' + str(args.events), '/ddg4/UI/terminate'] + + # Configure field + geant4.setupTrackingField(prt=True) + # Configure Event actions + prt = DDG4.EventAction(kernel, 'Geant4ParticlePrint/ParticlePrint') + prt.OutputLevel = Output.DEBUG + prt.OutputType = 3 + kernel.eventAction().adopt(prt) + + generator_output_level = Output.DEBUG + + # Configure G4 geometry setup + seq, act = geant4.addDetectorConstruction("Geant4DetectorGeometryConstruction/ConstructGeo") + act.DebugVolumes = True + # + # Assign sensitive detectors according to the declarations 'tracker' or 'calorimeter', etc + seq, act = geant4.addDetectorConstruction("Geant4DetectorSensitivesConstruction/ConstructSD") + # + # Assign sensitive detectors in Geant4 by matching a regular expression in the detector sub-tree + seq, act = geant4.addDetectorConstruction("Geant4RegexSensitivesConstruction/ConstructSDRegEx") + act.Detector = 'BoxOfStrawsDet' + act.Regex = '/world_volume_(.*)/BoxOfStrawsDet_(.*)/row_(.*)/straw_(.*)' + act.OutputLevel = Output.ALWAYS + act.enableUI() + + # Configure I/O + geant4.setupROOTOutput('RootOutput', 'BoxOfStraws_' + time.strftime('%Y-%m-%d_%H-%M')) + + # Setup particle gun + gun = geant4.setupGun("Gun", particle='e+', energy=10 * GeV, multiplicity=1) + gun.OutputLevel = Output.DEBUG + + # And handle the simulation particles. + part = DDG4.GeneratorAction(kernel, "Geant4ParticleHandler/ParticleHandler") + kernel.generatorAction().adopt(part) + part.SaveProcesses = ['Decay'] + part.MinimalKineticEnergy = 100 * MeV + part.OutputLevel = Output.DEBUG # generator_output_level + part.enableUI() + user = DDG4.Action(kernel, "Geant4TCUserParticleHandler/UserParticleHandler") + user.TrackingVolume_Zmax = 2.5 * m + user.TrackingVolume_Rmax = 2.5 * m + user.enableUI() + part.adopt(user) + + # Map sensitive detectors of type 'BoxOfStraws' to Geant4CalorimeterAction + sd = geant4.description.sensitiveDetector(str('BoxOfStrawsDet')) + logger.info(f'+++ BoxOfStraws: SD type: {str(sd.type())}') + seq, act = geant4.setupDetector(name='BoxOfStrawsDet', action='MyTrackerSDAction') + act.HaveCellID = False + + # Now build the physics list: + phys = geant4.setupPhysics(str('QGSP_BERT')) + ph = DDG4.PhysicsList(kernel, str('Geant4PhysicsList/Myphysics')) + # Add b osons to the model (redundant if already implemented by the model) + ph.addParticleGroup(str('G4BosonConstructor')) + ph.addParticleGroup(str('G4BaryonConstructor')) + ph.addParticleGroup(str('G4MesonConstructor')) + ph.addParticleGroup(str('G4LeptonConstructor')) + # Add multiple scattering in the material + ph.addParticleProcess(str('e[+-]'), str('G4eMultipleScattering'), -1, 1, 1) + # Interactivity + ph.enableUI() + phys.adopt(ph) + phys.dump() + geant4.execute() + + +if __name__ == "__main__": + run() diff --git a/examples/ClientTests/src/BoxOfStraws_geo.cpp b/examples/ClientTests/src/BoxOfStraws_geo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b6ce0e35250f654710a53a1aa3b3f769d0a2703f --- /dev/null +++ b/examples/ClientTests/src/BoxOfStraws_geo.cpp @@ -0,0 +1,85 @@ +//========================================================================== +// 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 +// +//========================================================================== +// +// +// Display using: +// $> geoDisplay examples/ClientTests/compact/BoxOfStraws.xml +// +//========================================================================== +#include <DD4hep/DetFactoryHelper.h> +#include <DD4hep/Printout.h> + +using namespace dd4hep; + +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { + double tol = 1e-2; + xml_det_t x_det = e; + xml_dim_t x_box = x_det.child(_U(box)); + xml_dim_t x_rot = x_det.child(_U(rotation)); + xml_dim_t x_pos = x_det.child(_U(position)); + xml_det_t x_straw = x_det.child(_Unicode(straw)); + std::string nam = x_det.nameStr(); + const double delta = 2e0*x_straw.rmax(); + const int num_x = int(2e0*x_box.x() / delta); + const int num_z = int(2e0*x_box.z() / delta); + + // Have box like straws: voxelization should be more efficient and for our test it does not matter. + Tube straw(0., x_straw.rmax()-tol, x_straw.y()-tol); + //Box straw(x_straw.rmax()-tol, x_straw.rmax()-tol, x_straw.y()-tol); + Volume straw_vol("straw", straw, description.material(x_straw.materialStr())); + + straw_vol.setAttributes(description, x_straw.regionStr(), x_straw.limitsStr(), x_straw.visStr()); + printout(INFO, "BoxOfStraws", "%s: Straw: rmax: %7.3f y: %7.3f mat: %s vis: %s solid: %s", + nam.c_str(), x_straw.rmax(), x_straw.y(), x_straw.materialStr().c_str(), + x_straw.visStr().c_str(), straw.type()); + if ( x_straw.hasChild(_U(sensitive)) ) { + sens.setType("tracker"); + straw_vol.setSensitiveDetector(sens); + } + + Box box(x_box.x(), x_box.y(), x_box.z()); + Volume box_vol(nam, box, description.air()); + box_vol.setAttributes(description, x_box.regionStr(), x_box.limitsStr(), x_box.visStr()); + + Box row(x_box.x(), x_box.y(), x_straw.rmax()); + Volume row_vol("row", row, description.air()); + row_vol.setVisAttributes(description.visAttributes("InvisibleWithChildren")); + + printout(INFO, "BoxOfStraws", "%s: Row: nx: %7d nz: %7d delta: %7.3f", nam.c_str(), num_x, num_z, delta); + for( int ix=0; ix < num_x; ++ix ) { + double x = -box.x() + (double(ix)+0.5) * delta; + PlacedVolume pv = row_vol.placeVolume(straw_vol, Position(x, 0e0, 0e0)); + pv.addPhysVolID("straw", ix); + } + + // Not terribly clever: better would be to place layers instead of single straws.... + Rotation3D rot(RotationZYX(0e0, 0e0, M_PI/2e0)); + for( int iz=0; iz < num_z; ++iz ) { + double z = -box.z() + (double(iz)+0.5) * delta; + PlacedVolume pv = box_vol.placeVolume(row_vol, Transform3D(rot, Position(0e0, 0e0, z))); + pv.addPhysVolID("module", iz); + } + printout(INFO, "BoxOfStraws", "%s: Created %d rows of %d straws each.", nam.c_str(), num_z, num_x); + + DetElement sdet (nam, x_det.id()); + Volume mother(description.pickMotherVolume(sdet)); + Rotation3D rot3D (RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0))); + Transform3D trafo (rot3D, Position(x_pos.x(0), x_pos.y(0), x_pos.z(0))); + PlacedVolume pv = mother.placeVolume(box_vol, trafo); + pv.addPhysVolID("system", x_det.id()); + sdet.setPlacement(pv); // associate the placed volume to the detector element + printout(INFO, "BoxOfStraws", "%s: Detector construction finished.", nam.c_str()); + return sdet; +} + +DECLARE_DETELEMENT(DD4hep_BoxOfStraws,create_detector)