From 2cfca4a274007f578394382a49e36497894b3924 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Mon, 1 Apr 2024 12:57:35 -0400 Subject: [PATCH 01/25] Use expr(1) for dawn views 12,14,15 to enable negative zpos (#688) The current code depends on `-$zpos` to expand to a negated value of $zpos, which doesn't work for negative values. --- scripts/view12/generate_eps | 4 ++-- scripts/view14/generate_eps | 8 ++++---- scripts/view15/generate_eps | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/view12/generate_eps b/scripts/view12/generate_eps index 3668d000c..cbb2b355f 100755 --- a/scripts/view12/generate_eps +++ b/scripts/view12/generate_eps @@ -72,8 +72,8 @@ make_slice(){ local zpos="$1" local tagnum=$(printf "%04d" ${zpos}) local FILE_TAG="${original_file_tag}a${tagnum}" - dawncut 0 0 1 ${zpos}1 ${INPUT_FILE} ${FILE_TAG}_temp0.prim - dawncut 0 0 -1 -${zpos}0 ${FILE_TAG}_temp0.prim ${FILE_TAG}.prim + dawncut 0 0 1 $(( 10 * ${zpos} + 1 )) ${INPUT_FILE} ${FILE_TAG}_temp0.prim + dawncut 0 0 -1 $(( -10 * ${zpos} )) ${FILE_TAG}_temp0.prim ${FILE_TAG}.prim dawn -d ${FILE_TAG}.prim ps2pdf ${FILE_TAG}.eps ${FILE_TAG}_full.pdf gs -o ${FILE_TAG}.pdf -sDEVICE=pdfwrite \ diff --git a/scripts/view14/generate_eps b/scripts/view14/generate_eps index 1f2c9afe9..b1fd92b03 100755 --- a/scripts/view14/generate_eps +++ b/scripts/view14/generate_eps @@ -75,10 +75,10 @@ make_slice(){ local zpos="$1" local tagnum=$(printf "%04d" ${zpos}) local FILE_TAG="${original_file_tag}a${tagnum}" - local z1=$(add ${zpos} 100) - local z2=$(add ${zpos} -100) - #dawncut 0 0 1 ${z1}1 ${INPUT_FILE} ${FILE_TAG}_temp0.prim - #dawncut 0 0 -1 -${z2}0 ${FILE_TAG}_temp0.prim ${FILE_TAG}.prim + local z1=$(( ${zpos} + 100 )) + local z2=$(( ${zpos} - 100 )) + #dawncut 0 0 1 $(( 10 * ${z1} + 1 )) ${INPUT_FILE} ${FILE_TAG}_temp0.prim + #dawncut 0 0 -1 $(( -10 * ${z2} )) ${FILE_TAG}_temp0.prim ${FILE_TAG}.prim ../../bin/dawn_tweak -z ${zpos}0 cp ${INPUT_FILE} ${FILE_TAG}.prim dawn -d ${FILE_TAG}.prim diff --git a/scripts/view15/generate_eps b/scripts/view15/generate_eps index 8bc18aaf5..1bf171575 100755 --- a/scripts/view15/generate_eps +++ b/scripts/view15/generate_eps @@ -91,10 +91,10 @@ make_slice(){ local zpos="$1" local tagnum=$(printf "%04d" ${zpos}) local FILE_TAG="${original_file_tag}a${tagnum}" - local z1=$(add ${zpos} 100) - local z2=$(add ${zpos} -100) - #dawncut 0 0 1 ${z1}1 ${INPUT_FILE} ${FILE_TAG}_temp0.prim - #dawncut 0 0 -1 -${z2}0 ${FILE_TAG}_temp0.prim ${FILE_TAG}.prim + local z1=$(( ${zpos} + 100 )) + local z2=$(( ${zpos} - 100 )) + #dawncut 0 0 1 $(( 10 * ${z1} + 1 )) ${INPUT_FILE} ${FILE_TAG}_temp0.prim + #dawncut 0 0 -1 $(( -10 * ${z2} )) ${FILE_TAG}_temp0.prim ${FILE_TAG}.prim ../../bin/dawn_tweak -z ${zpos}0 --draw 5 #cp ${INPUT_FILE} ${FILE_TAG}.prim dawncut -1 0 0 0 ${INPUT_FILE} ${FILE_TAG}.prim From c24a7e727d3b6c2b7ecf9999aedcd53cc1c5d4da Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Mon, 1 Apr 2024 12:57:53 -0400 Subject: [PATCH 02/25] bin/make_dawn_views: remove unused imports (#686) Those are not referenced. Likely, were copied from the `bin/generate_prim_file`. --- bin/make_dawn_views | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bin/make_dawn_views b/bin/make_dawn_views index c2ed66387..c27757b36 100755 --- a/bin/make_dawn_views +++ b/bin/make_dawn_views @@ -5,14 +5,9 @@ # C. Peng (ANL), translate to python and add flexible run time for simulation import os -import signal import subprocess import argparse -import atexit -import time -from datetime import datetime import fcntl -import psutil def readline_nonblocking(output): From 07df565368fe7cad21c6eb063c99960dea26d1b3 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 2 Apr 2024 18:41:21 -0500 Subject: [PATCH 03/25] fix: ignore gdml/ and calibrations/ (#692) ### Briefly, what does this PR introduce? This PR causes git to ignore the gdml/ and calibrations/ directories so they are not accidentally checked in. ### What kind of change does this PR introduce? - [x] Bug fix (issue #__) - [ ] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? No. --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index afb9d6591..16ecd1f1b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,9 @@ ip6_build *.swp -fieldmaps +fieldmaps/ +gdml/ +calibrations/ manifest.txt acts.txt From b033cf8a88551607e9c58a36de52c1f1d211dadb Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 2 Apr 2024 19:39:45 -0500 Subject: [PATCH 04/25] doc: update README.md with tgeo and step file links (#690) ### Briefly, what does this PR introduce? This PR updates the front-page README.md with the tgeo and step file links, and places the image 'above the fold' with links by side. Some poor alignments, but didn't want to shrink the image even further. ![image](https://github.com/eic/epic/assets/4656391/0de1b8f5-6ab7-4838-a613-1db9f48b2c90) ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [ ] New feature (issue #__) - [x] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? No. --- README.md | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index c3d5f5bfe..b26cf36ff 100644 --- a/README.md +++ b/README.md @@ -3,30 +3,26 @@ Overview -------- -**Detector geometry viewer:** -- [Viewer only](https://eic.github.io/epic/geoviewer) -- Main configurations: - - [CraterLake](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_craterlake.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) -- Additional viewers: - - [Inner detector (without calorimetry)](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_inner_detector.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) - - [Calorimetry](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_calorimeters.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) - - [Imaging](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_imaging_only.root&item=default;1&opt=clipx;clipy;transp30;zoom55;ROTY49;ROTZ350;trz0;trr0;ctrl;all) - - [PID](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_pid_only.root&item=default;1&opt=clipx;clipy;transp30;zoom75;ROTY320;ROTZ340;trz0;trr0;ctrl;all) - - [dRICH](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_drich_only.root&item=default;1&opt=clipx;clipy;transp30;zoom75;ROTY290;ROTZ350;trz0;trr0;ctrl;all) - - [pfRICH](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_pfrich_only.root&item=default;1&opt=clipx;clipy;transp30;zoom55;ROTY49;ROTZ350;trz0;trr0;ctrl;all) - - [DIRC](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_dirc_only.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) - - [Tracking](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_tracking_only.root&item=default;1&opt=clipx;clipy;transp30;zoom75;ROTY320;ROTZ340;trz0;trr0;ctrl;all) - - [Vertex](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_vertex_only.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) - - [ToF](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_tof_only.root&item=default;1&opt=clipx;clipy;transp30;zoom55;ROTY49;ROTZ350;trz0;trr0;ctrl;all) - - [Beamline](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_ip6.root&item=default;1&opt=clipx;clipy;transp30;zoom40;ROTY290;ROTZ350;trz0;trr0;ctrl;all) - -[](https://eic.github.io/epic/artifacts/epic_craterlake_views/view1_top.pdf) +craterlake + +**Detector geometry:** +- [Empty viewer](https://eic.github.io/epic/geoviewer) +- Craterlake: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_craterlake.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) [step](https://eic.github.io/epic//artifacts/epic_craterlake_no_bhcal.stp/epic_craterlake_no_bhcal.stp) +- Subsystems: + - Inner detector: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_inner_detector.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_inner_detector.root) + - Calorimetry: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_calorimeters.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_calorimeters.root) + - Imaging: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_imaging_only.root&item=default;1&opt=clipx;clipy;transp30;zoom55;ROTY49;ROTZ350;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_imaging.root) [step](https://eic.github.io/epic//artifacts/epic_imaging_only.stp/epic_imaging_only.stp) + - PID: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_pid_only.root&item=default;1&opt=clipx;clipy;transp30;zoom75;ROTY320;ROTZ340;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_pid_only.root) + - dRICH: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_drich_only.root&item=default;1&opt=clipx;clipy;transp30;zoom75;ROTY290;ROTZ350;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_drich_only.root) [step](https://eic.github.io/epic//artifacts/epic_drich_only.stp/epic_drich_only.stp) + - pfRICH: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_pfrich_only.root&item=default;1&opt=clipx;clipy;transp30;zoom55;ROTY49;ROTZ350;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_pfrich_only.root) + - DIRC: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_dirc_only.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_dirc_only.root) [step](https://eic.github.io/epic//artifacts/epic_dirc_only.stp/epic_dirc_only.stp) + - Tracking: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_tracking_only.root&item=default;1&opt=clipx;clipy;transp30;zoom75;ROTY320;ROTZ340;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_tracking_only.root) [step](https://eic.github.io/epic//artifacts/epic_craterlake_tracking_only.stp/epic_craterlake_tracking_only.stp) + - Vertex: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_vertex_only.root&item=default;1&opt=clipx;clipy;transp30;zoom120;ROTY320;ROTZ340;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_vertex_only.root) + - TOF: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_tof_only.root&item=default;1&opt=clipx;clipy;transp30;zoom55;ROTY49;ROTZ350;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_tof_only.root) + - Beamline: [viewer](https://eic.github.io/epic/geoviewer?nobrowser&file=artifacts/tgeo/epic_ip6.root&item=default;1&opt=clipx;clipy;transp30;zoom40;ROTY290;ROTZ350;trz0;trr0;ctrl;all) [tgeo](https://eic.github.io/epic//artifacts/tgeo/epic_ip6.root) [step](https://eic.github.io/epic//artifacts/epic_ip6.stp/epic_ip6.stp) **Detector parameters:** -- text: [CraterLake](https://eic.github.io/epic/artifacts/constants/epic_craterlake_constants.out) -- toml: [CraterLake](https://eic.github.io/epic/artifacts/constants/epic_craterlake_constants.toml) -- csv: [CraterLake](https://eic.github.io/epic/artifacts/DetectorParameterTable/epic_craterlake.csv) -- html: [CraterLake](https://eic.github.io/epic/artifacts/DetectorParameterTable/epic_craterlake.html) +- Craterlake: [text](https://eic.github.io/epic/artifacts/constants/epic_craterlake_constants.out) [toml](https://eic.github.io/epic/artifacts/constants/epic_craterlake_constants.toml) [csv](https://eic.github.io/epic/artifacts/DetectorParameterTable/epic_craterlake.csv) [html](https://eic.github.io/epic/artifacts/DetectorParameterTable/epic_craterlake.html) Getting Started --------------- @@ -48,10 +44,6 @@ To load the geometry, you can use the scripts in the `install` directory: ```bash source install/setup.sh ``` -or -```tcsh -source install/setup.csh -``` ### Adding/changing detector geometry From 007580fb18c6c4d66bba93155980b03a5e7ba016 Mon Sep 17 00:00:00 2001 From: Alex Jentsch Date: Thu, 4 Apr 2024 03:10:53 -0400 Subject: [PATCH 05/25] Add new ff vacuum structure (#665) ### Briefly, what does this PR introduce? This introduces a completely re-vamped far-forward beam pipe and vacuum system, which includes a neutral particle exit window, boxes to house the Roman pots, etc. and fills the volumes with vacuum. There are a few additional updates which will be needed once some other issues are resolved, but the overall layout will not drastically change. ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [x] Tests for the changes have been added - [ ] Documentation has been added / updated - [x] Changes have been communicated to collaborators I have run the overlap checker (no overlaps), and done a few additional visual checks + acceptance checks. There are still some comments and missing "dd4hep::" constants in the code - please ignore these for now. The comments are for my future updates, and the missing constants are intentional, as all of the drawings are in "mm", and i want to keep the exact numbers as they are to make it easier to make updates. ### Does this PR introduce breaking changes? What changes might users need to make to their code? Kind of - it drastically changes the behavior of particles which go to the ZDC (a proper exit window is now there), and it will alter the reconstruction of forward protons due to the shift of the RP planes (a PR in EICrecon will follow with updated matrices). It should be noted that the exit window really only covers up to about 3.8 mrad in neutral particle acceptance. This is due to the physical constraints of fitting the window alongside the proton beam line and not impacting the proton acceptance. ### Does this PR change default behavior? Yes, especially for neutrons and photons in the ZDC. --------- Co-authored-by: Alexander Jentsch Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Wouter Deconinck --- compact/far_forward/beampipe_hadron_B0.xml | 2 +- .../far_forward/roman_pots_eRD24_design.xml | 445 ++++++++-------- src/forwardBeamPipeBrazil.cpp | 499 ++++++++++++++++++ 3 files changed, 721 insertions(+), 225 deletions(-) create mode 100644 src/forwardBeamPipeBrazil.cpp diff --git a/compact/far_forward/beampipe_hadron_B0.xml b/compact/far_forward/beampipe_hadron_B0.xml index f02790921..e739fdf68 100644 --- a/compact/far_forward/beampipe_hadron_B0.xml +++ b/compact/far_forward/beampipe_hadron_B0.xml @@ -10,7 +10,7 @@ - + diff --git a/compact/far_forward/roman_pots_eRD24_design.xml b/compact/far_forward/roman_pots_eRD24_design.xml index 1fdf153d2..f3a393c62 100644 --- a/compact/far_forward/roman_pots_eRD24_design.xml +++ b/compact/far_forward/roman_pots_eRD24_design.xml @@ -2,241 +2,238 @@ - - - --------------------------------- - Roman Pots Implementation from eRD24 RD Effort - Author: Alex Jentsch - Date of first commit: June 15th, 2021 - --------------------------------- - + + + --------------------------------- + Roman Pots Implementation from eRD24 RD Effort + Author: Alex Jentsch + Date of first commit: June 15th, 2021 + --------------------------------- + - + - - - - + + + + - - + + - - + + - - + + - + - - + + - - - - - - - - - - - - - --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - system:8,assembly:3,layer:4,module:4,sensor:4,x:32:-16,y:-16 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:8,assembly:3,layer:4,module:4,sensor:4,x:32:-16,y:-16 + + diff --git a/src/forwardBeamPipeBrazil.cpp b/src/forwardBeamPipeBrazil.cpp new file mode 100644 index 000000000..0feb23991 --- /dev/null +++ b/src/forwardBeamPipeBrazil.cpp @@ -0,0 +1,499 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 Alex Jentsch + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/Printout.h" +#include "TMath.h" +#include + +using namespace std; +using namespace dd4hep; + +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) +{ + + using namespace ROOT::Math; + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + DetElement sdet(det_name, x_det.id()); + Assembly assembly(det_name + "_assembly"); + Material m_Al = det.material("Aluminum"); + Material m_Be = det.material("Beryllium"); + Material m_SS = det.material("StainlessSteel"); + Material m_vac = det.material("Vacuum"); + string vis_name = x_det.visStr(); + + PlacedVolume pv_assembly; + + double b0_hadron_tube_inner_r = 2.9 * dd4hep::cm; + double b0_hadron_tube_outer_r = 3.1 * dd4hep::cm; + double b0_hadron_tube_length = 120.0 * dd4hep::cm; + + double pipeThickness = 5.0 * dd4hep::mm; + + struct beampipe_dimensions_t { + Double_t length = 0.0; + Double_t innerXRadius = 0.0; + Double_t innerYRadius = 0.0; + Double_t outerXRadius = 0.0; + Double_t outerYRadius = 0.0; + Double_t xCenter = 0.0; + Double_t yCenter = 0.0; + Double_t zCenter = 0.0; + Double_t rotationAngle = 0.0; + }; + + std::vector beampipe_dimensions; + + double globRotationAngle = -0.0454486856; //This is the angle of the proton orbit from the end of B1APF to the beginning of B2PF + double crossingAngle = -0.025; //relevant for the neutral cone + + double b1APFEndPoint_z = 22062.3828 * dd4hep::mm; //location of proton orbit at b1APF exit -- in mm + double b1APFEndPoint_x = 654.3372 * dd4hep::mm; //location of proton orbit at b1APF exit -- in mm + + double tmp_endpoint_z = 0.0; + double tmp_endpoint_x = 0.0; + + //forumula -> Z = b1APFEndPoint_z+((0.5*elementLengt)*Cos(globRotationAngle)) + //forumula -> X = b1APFEndPoint_z+((0.5*elementLengt)*Sin(globRotationAngle)) + + //------------------------------------------------------------------------------------ + //Geometry extracted from version 0 VPC drawings shown at the FF preliminary + //design review in February 2024 -- CAD model not available as of April 1st, 2024 + //------------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------------ + //primary pipe after B1APF, before neutral exit window + transition to smaller pipe + //rectangular cross-section!!!!! + //------------------------------------------------------------------------------------ + + + beampipe_dimensions.push_back({ + .length = 7615.486 * dd4hep::mm, //from VPC drawings, in mm + .innerXRadius = 275.0 * dd4hep::mm, + .innerYRadius = 175.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + }); + + beampipe_dimensions[0].outerXRadius = beampipe_dimensions[0].innerXRadius + pipeThickness; + beampipe_dimensions[0].outerYRadius = beampipe_dimensions[0].innerYRadius + pipeThickness; + beampipe_dimensions[0].xCenter = -1*(b1APFEndPoint_x+((0.5*beampipe_dimensions[0].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[0].yCenter = 0.0; + beampipe_dimensions[0].zCenter = (b1APFEndPoint_z+((0.5*beampipe_dimensions[0].length)*TMath::Cos(-globRotationAngle))); + + tmp_endpoint_z = beampipe_dimensions[0].zCenter+((0.5*beampipe_dimensions[0].length)*TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1*beampipe_dimensions[0].xCenter+((0.5*beampipe_dimensions[0].length)*TMath::Sin(-globRotationAngle)); + + double windowRadius = 110.0 * dd4hep::mm; + + + //------------------------------------------------------------------------------------ + //first small pipe section, between primary vessel and RP station 1 + //rectangular cross-section!!!!! + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({ + .length = 2780.273 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + }); + + beampipe_dimensions[1].outerXRadius = beampipe_dimensions[1].innerXRadius + pipeThickness; + beampipe_dimensions[1].outerYRadius = beampipe_dimensions[1].innerYRadius + pipeThickness; + beampipe_dimensions[1].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[1].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[1].yCenter = 0.0; + beampipe_dimensions[1].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[1].length)*TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[1].zCenter+((0.5*beampipe_dimensions[1].length)*TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1*beampipe_dimensions[1].xCenter+((0.5*beampipe_dimensions[1].length)*TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + //First roman pots scattering chamber + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({ + .length = 200 * dd4hep::mm, // from VPC drawings + .innerXRadius = 200.0 * dd4hep::mm, + .innerYRadius = 125.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + }); + + beampipe_dimensions[2].outerXRadius = beampipe_dimensions[2].innerXRadius + pipeThickness; + beampipe_dimensions[2].outerYRadius = beampipe_dimensions[2].innerYRadius + pipeThickness; + beampipe_dimensions[2].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[2].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[2].yCenter = 0.0; + beampipe_dimensions[2].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[2].length)*TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[2].zCenter+((0.5*beampipe_dimensions[2].length)*TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1*beampipe_dimensions[2].xCenter+((0.5*beampipe_dimensions[2].length)*TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + //pipe between RP 1 and RP 2 stations + //rectangular cross-section!!!!! + //------------------------------------------------------------------------------------ + + + beampipe_dimensions.push_back({ + .length = 1500.0 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + }); + + beampipe_dimensions[3].outerXRadius = beampipe_dimensions[3].innerXRadius + pipeThickness; + beampipe_dimensions[3].outerYRadius = beampipe_dimensions[3].innerYRadius + pipeThickness; + beampipe_dimensions[3].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[3].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[3].yCenter = 0.0; + beampipe_dimensions[3].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[3].length)*TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[3].zCenter+((0.5*beampipe_dimensions[3].length)*TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1*beampipe_dimensions[3].xCenter+((0.5*beampipe_dimensions[3].length)*TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + //second roman pots scattering chamber + //------------------------------------------------------------------------------------ + + + beampipe_dimensions.push_back({ + .length = 200 * dd4hep::mm, // from VPC drawings + .innerXRadius = 200.0 * dd4hep::mm, + .innerYRadius = 125.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + }); + + beampipe_dimensions[4].outerXRadius = beampipe_dimensions[4].innerXRadius + pipeThickness; + beampipe_dimensions[4].outerYRadius = beampipe_dimensions[4].innerYRadius + pipeThickness; + beampipe_dimensions[4].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[4].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[4].yCenter = 0.0; + beampipe_dimensions[4].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[4].length)*TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[4].zCenter+((0.5*beampipe_dimensions[4].length)*TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1*beampipe_dimensions[4].xCenter+((0.5*beampipe_dimensions[4].length)*TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + // Pipe from second RP chamber to taper + //------------------------------------------------------------------------------------ + + + beampipe_dimensions.push_back({ + .length = 100.0 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + }); + + beampipe_dimensions[5].outerXRadius = beampipe_dimensions[5].innerXRadius + pipeThickness; + beampipe_dimensions[5].outerYRadius = beampipe_dimensions[5].innerYRadius + pipeThickness; + beampipe_dimensions[5].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[5].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[5].yCenter = 0.0; + beampipe_dimensions[5].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[5].length)*TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[5].zCenter+((0.5*beampipe_dimensions[5].length)*TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1*beampipe_dimensions[5].xCenter+((0.5*beampipe_dimensions[5].length)*TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + // taper near ZDC + //------------------------------------------------------------------------------------ + + + beampipe_dimensions.push_back({ + .length = 599.692 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + + }); + + beampipe_dimensions[6].outerXRadius = beampipe_dimensions[6].innerXRadius + pipeThickness; + beampipe_dimensions[6].outerYRadius = beampipe_dimensions[6].innerYRadius + pipeThickness; + beampipe_dimensions[6].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[6].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[6].yCenter = 0.0; + beampipe_dimensions[6].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[6].length)*TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[6].zCenter+((0.5*beampipe_dimensions[6].length)*TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1*beampipe_dimensions[6].xCenter+((0.5*beampipe_dimensions[6].length)*TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + // pipe connecting taper to B2PF magnet, just past ZDC + //------------------------------------------------------------------------------------ + + //numbers here are not really correct for the full taper, just for the opening + + beampipe_dimensions.push_back({ + .length = 3000.0 * dd4hep::mm, // from VPC drawings + .innerXRadius = 35.0 * dd4hep::mm, + .innerYRadius = 0.0, + .rotationAngle = globRotationAngle + }); + + beampipe_dimensions[7].outerXRadius = beampipe_dimensions[7].innerXRadius + pipeThickness; + beampipe_dimensions[7].outerYRadius = beampipe_dimensions[7].innerYRadius + pipeThickness; //NOT USED HERE + beampipe_dimensions[7].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[7].length)*TMath::Sin(-globRotationAngle))); + beampipe_dimensions[7].yCenter = 0.0; + beampipe_dimensions[7].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[7].length)*TMath::Cos(-globRotationAngle)); + + + //------------------------------------------ + //begin building main volumes here + //------------------------------------------ + + //------------------------------------------------------------------- + + int pieceIdx = 0; //Larger, rectangular pipe transporting proton and neutral envelopes (neutral exit window and transfer to smaller proton line at the end) + + Box pipeAfterB1APF_outer(beampipe_dimensions[pieceIdx].outerXRadius, beampipe_dimensions[pieceIdx].outerYRadius, beampipe_dimensions[pieceIdx].length/2); + Box pipeAfterB1APF_inner(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, (beampipe_dimensions[pieceIdx].length)/2); + Box pipeAfterB1APF_firstEndCap(beampipe_dimensions[pieceIdx].outerXRadius, beampipe_dimensions[pieceIdx].outerYRadius, 5.0/2.0); + Tube neutral_exit_window_cutout(0.0, windowRadius, 1.0); // 1.0cm thick + //FIXME: proton transfer window is done by hand right now - not a nicer way to do it until we get the CAD drawing + Box protonTransferWindow(155.0 * dd4hep::mm, beampipe_dimensions[1].outerYRadius, (5.0/2)); + + SubtractionSolid tmpAfterB1APF(pipeAfterB1APF_outer, pipeAfterB1APF_inner); //This gets rid of the inner portion of the pipe, but leaves the endcaps + tmpAfterB1APF = SubtractionSolid(tmpAfterB1APF, pipeAfterB1APF_firstEndCap, Position(0.0, 0.0, (-beampipe_dimensions[pieceIdx].length)/2)); + tmpAfterB1APF = SubtractionSolid(tmpAfterB1APF, protonTransferWindow, Position((-120.0 * dd4hep::mm), 0.0, (beampipe_dimensions[pieceIdx].length)/2 )); + tmpAfterB1APF = SubtractionSolid(tmpAfterB1APF, neutral_exit_window_cutout, Position(160.0 * dd4hep::mm, 0.0, 0.5*beampipe_dimensions[pieceIdx].length)); + + Volume v_pipeAfterB1APF(Form("v_pipeAfterB1APF_%d", pieceIdx), tmpAfterB1APF, m_SS); + sdet.setAttributes(det, v_pipeAfterB1APF, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_0 = assembly.placeVolume(v_pipeAfterB1APF, Transform3D(RotationY(crossingAngle), Position(beampipe_dimensions[pieceIdx].xCenter + 4.0, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); // 2353.06094))); + pv_pipe_0.addPhysVolID("sector", 1); + DetElement pipe_de_0(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_0.setPlacement(pv_pipe_0); + + //-------------------------------------------------------------------- + + double lengthDelta = 0.0; //over-length value to remove end-pieces for hollow rectangular pipes + + // 1 -- small pipe connecting big pipe to RP station 1 + // 2 -- roman pots scattering chamber 1 + // 3 -- small pipe connecting RP1 and RP2 + // 4 -- roman pots scattering chamber 2 + // 5 -- small pipe connecting RP2 to ZDC taper + + lengthDelta = 5.0; //for small beam pipes to remove endcaps + + for(int idx = 1; idx < 6; idx++){ //loop for the easier pieces to simplify + + if(idx == 2 || idx == 4){ continue;} + + Box outer(beampipe_dimensions[idx].outerXRadius, beampipe_dimensions[idx].outerYRadius, beampipe_dimensions[idx].length/2); + Box inner(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, (beampipe_dimensions[idx].length+lengthDelta)/2); + + SubtractionSolid hollow_pipe(outer, inner); + + Volume v_hollow_pipe(Form("v_pipe_%d", idx), hollow_pipe, m_SS); + sdet.setAttributes(det, v_hollow_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_final = assembly.placeVolume(v_hollow_pipe, Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, beampipe_dimensions[idx].zCenter))); + pv_final.addPhysVolID("sector", 1); + DetElement final_de(sdet, Form("sector_pipe_%d_de", idx), 1); + final_de.setPlacement(pv_final); + + } + + lengthDelta = 0.0; //not needed for scattering chambers + + for(int idx = 1; idx < 6; idx++){ //loop for the easier pieces to simplify + + if(idx == 1 || idx == 3 || idx == 5){ continue;} + + Box outer(beampipe_dimensions[idx].outerXRadius, beampipe_dimensions[idx].outerYRadius, beampipe_dimensions[idx].length/2); + Box inner(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, (beampipe_dimensions[idx].length+lengthDelta)/2); + Box RP_subtract_outer(beampipe_dimensions[1].outerXRadius, beampipe_dimensions[1].outerYRadius, (beampipe_dimensions[2].length+5.0)/2); + + SubtractionSolid hollow_pipe(outer, inner); + hollow_pipe = SubtractionSolid(hollow_pipe, RP_subtract_outer); + + Volume v_hollow_pipe(Form("v_pipe_%d", idx), hollow_pipe, m_SS); + sdet.setAttributes(det, v_hollow_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_final = assembly.placeVolume(v_hollow_pipe, Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, beampipe_dimensions[idx].zCenter))); + pv_final.addPhysVolID("sector", 1); + DetElement final_de(sdet, Form("sector_pipe_%d_de", idx), 1); + final_de.setPlacement(pv_final); + + } + + //---------------------------------------------------------------- + + pieceIdx = 6; + + Double_t trpVertices[16]; + Double_t trpVerticesInner[16]; + //(x0, y0, x1, y1, ... , x7, y7) + //opening side - larger size + trpVertices[0] = -beampipe_dimensions[6].outerXRadius; + trpVertices[1] = -beampipe_dimensions[6].outerYRadius; + + trpVertices[2] = -beampipe_dimensions[6].outerXRadius; + trpVertices[3] = beampipe_dimensions[6].outerYRadius; + + trpVertices[4] = beampipe_dimensions[6].outerXRadius; + trpVertices[5] = beampipe_dimensions[6].outerYRadius; + + trpVertices[6] = beampipe_dimensions[6].outerXRadius; + trpVertices[7] = -beampipe_dimensions[6].outerYRadius; + + //exiting side - smaller size + + trpVertices[8] = -beampipe_dimensions[6].outerYRadius; + trpVertices[9] = -beampipe_dimensions[6].outerYRadius; + + trpVertices[10] = -beampipe_dimensions[6].outerYRadius; + trpVertices[11] = beampipe_dimensions[6].outerYRadius; + + trpVertices[12] = beampipe_dimensions[6].outerYRadius; + trpVertices[13] = beampipe_dimensions[6].outerYRadius; + + trpVertices[14] = beampipe_dimensions[6].outerYRadius; + trpVertices[15] = -beampipe_dimensions[6].outerYRadius; + + for(int i = 0; i < 16; i++){ + + if(trpVertices[i] > 0.0){trpVerticesInner[i] = trpVertices[i]-(pipeThickness);} + if(trpVertices[i] < 0.0){trpVerticesInner[i] = trpVertices[i]+(pipeThickness);} + + } + + EightPointSolid taper_outer((0.5*beampipe_dimensions[pieceIdx].length), trpVertices); + EightPointSolid taper_inner((0.5*beampipe_dimensions[pieceIdx].length), trpVerticesInner); + + Box taper_entrance(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, (0.5*(pipeThickness + 5.0))); + Box taper_exit(beampipe_dimensions[pieceIdx].innerYRadius, beampipe_dimensions[pieceIdx].innerYRadius, (0.5*(pipeThickness + 5.0))); + SubtractionSolid hollowTaper(taper_outer, taper_inner); + hollowTaper = SubtractionSolid(hollowTaper, taper_entrance, Position(0.0, 0.0, (-0.5*beampipe_dimensions[pieceIdx].length))); + hollowTaper = SubtractionSolid(hollowTaper, taper_exit, Position(0.0, 0.0, (0.5*beampipe_dimensions[pieceIdx].length))); + + Volume v_taper(Form("v_taper_%d", pieceIdx), hollowTaper, m_SS); + sdet.setAttributes(det, v_taper, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_6 = assembly.placeVolume(v_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position(beampipe_dimensions[pieceIdx].xCenter, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); + pv_pipe_6.addPhysVolID("sector", 1); + DetElement pipe_de_6(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_6.setPlacement(pv_pipe_6); + + //--------------------------------------------------------------- + + pieceIdx = 7; //pipe between taper and B2PF + + Tube pipe_after_taper(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].outerXRadius, beampipe_dimensions[pieceIdx].length/2); + + Volume v_pipe_7(Form("v_pipe_7_%d", pieceIdx), pipe_after_taper, m_SS); + sdet.setAttributes(det, v_pipe_7, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_7 = assembly.placeVolume(v_pipe_7, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position(beampipe_dimensions[pieceIdx].xCenter, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); // 2353.06094))); + pv_pipe_7.addPhysVolID("sector", 1); + DetElement pipe_de_7(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_7.setPlacement(pv_pipe_7); + + + //-------------------------------------------------------------- + // This is the beam tube in the B0 magnet for the hadron beam + // doesn't use the slope information calculated before - it stands alone + + pieceIdx = 8; + + Tube b0_hadron_tube(b0_hadron_tube_inner_r, b0_hadron_tube_outer_r, b0_hadron_tube_length / 2.0); + Volume v_b0_hadron_tube("v_b0_hadron_tube", b0_hadron_tube, m_Be); + sdet.setAttributes(det, v_b0_hadron_tube, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_8 = assembly.placeVolume(v_b0_hadron_tube, Transform3D(RotationY(crossingAngle), Position(-16.5, 0.0, 640.0))); // 2353.06094))); + pv_pipe_8.addPhysVolID("sector", 1); + DetElement pipe_de_8(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_8.setPlacement(pv_pipe_6); + + //---------------------------------------------------------------- + + pieceIdx = 9; //neutral exit window + + Box pipeAfterB1APF_LARGE((beampipe_dimensions[0].outerXRadius+5.0), (beampipe_dimensions[0].outerYRadius+5.0), (beampipe_dimensions[0].length+5.0)/2); + Tube neutral_exit_window(0.0, windowRadius, 1.0); // 1.0cm thick + + IntersectionSolid finalWindow(pipeAfterB1APF_outer, neutral_exit_window, Position(160.0 * dd4hep::mm, 0.0, 0.5*beampipe_dimensions[0].length)); + + Volume v_neutral_exit_window("v_neutral_exit_window", finalWindow, m_Al); + sdet.setAttributes(det, v_neutral_exit_window, x_det.regionStr(), x_det.limitsStr(), "AnlRed"); + + auto pv_pipe_9 = assembly.placeVolume(v_neutral_exit_window, Transform3D(RotationY(crossingAngle), Position( beampipe_dimensions[0].xCenter + 4.0, 0.0, beampipe_dimensions[0].zCenter))); + pv_pipe_9.addPhysVolID("sector", 1); + DetElement pipe_de_9(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_9.setPlacement(pv_pipe_9); + + //----------------------------------------------------------------- + // Build vacuum volumes here + //----------------------------------------------------------------- + + pieceIdx = 0; + + Box vacuum_main_pipe(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, (beampipe_dimensions[pieceIdx].length-2.0)/2); + Box cutout_for_OMD_station(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, 2.0); + + SubtractionSolid final_vacuum_main_pipe(vacuum_main_pipe, cutout_for_OMD_station, Position(0.0, 0.0, (2251.0 - beampipe_dimensions[pieceIdx].zCenter))); + final_vacuum_main_pipe = SubtractionSolid(final_vacuum_main_pipe, cutout_for_OMD_station, Position(0.0, 0.0, (2451.0 - beampipe_dimensions[pieceIdx].zCenter))); + + Volume v_vacuum_main_pipe("v_vacuum_main_pipe", final_vacuum_main_pipe, m_vac); + sdet.setAttributes(det, v_vacuum_main_pipe, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_vacuum_0 = assembly.placeVolume(v_vacuum_main_pipe, Transform3D(RotationY(crossingAngle), Position( beampipe_dimensions[pieceIdx].xCenter + 4.0, 0.0, beampipe_dimensions[pieceIdx].zCenter))); + pv_vacuum_0.addPhysVolID("sector", 1); + DetElement vacuum_de_0(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); + vacuum_de_0.setPlacement(pv_vacuum_0); + + //------------------------------------------------------------------ + + for(int idx = 1; idx < 6; idx++){ //loop for the easier pieces to simplify + + if(idx == 2 || idx == 4){ continue;} //FIXME: don't fill RP chambers with vacuum yet - still an issue with RP geometry + + Box inner_vacuum(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, (beampipe_dimensions[idx].length)/2); + + Volume v_inner_vacuum(Form("v_vacuum_%d", idx), inner_vacuum, m_vac); + sdet.setAttributes(det, v_inner_vacuum, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_final = assembly.placeVolume(v_inner_vacuum, Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, beampipe_dimensions[idx].zCenter))); + pv_final.addPhysVolID("sector", 1); + DetElement final_de(sdet, Form("sector_FF_vacuum_%d_de", idx), 1); + final_de.setPlacement(pv_final); + + } + + //------------------------------------------------------------------ + + pieceIdx = 6; + + EightPointSolid vacuum_taper((0.5*beampipe_dimensions[pieceIdx].length), trpVerticesInner); + + Volume v_vacuum_taper("v_vacuum_taper", vacuum_taper, m_vac); + sdet.setAttributes(det, v_vacuum_taper, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_vacuum_6 = assembly.placeVolume(v_vacuum_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position( beampipe_dimensions[pieceIdx].xCenter, 0.0, beampipe_dimensions[pieceIdx].zCenter))); + pv_vacuum_6.addPhysVolID("sector", 1); + DetElement vacuum_de_6(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); + vacuum_de_6.setPlacement(pv_vacuum_6); + + //------------------------------------------------------------------- + + pieceIdx = 7; //vacuum between taper and B2PF + + Tube vacuum_pipe_after_taper(0.0, beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].length/2); + + Volume v_vacuum_pipe_after_taper("v_vacuum_pipe_after_taper", vacuum_pipe_after_taper, m_vac); + sdet.setAttributes(det, v_vacuum_pipe_after_taper, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_vacuum_7 = assembly.placeVolume(v_vacuum_pipe_after_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position(beampipe_dimensions[pieceIdx].xCenter, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); + pv_vacuum_7.addPhysVolID("sector", 1); + DetElement vacuum_de_7(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); + vacuum_de_7.setPlacement(pv_vacuum_7); + + //------------------------------------------------------------------- + + pv_assembly = det.pickMotherVolume(sdet).placeVolume(assembly); + pv_assembly.addPhysVolID("system", x_det.id()).addPhysVolID("barrel", 1); + sdet.setPlacement(pv_assembly); + assembly->GetShape()->ComputeBBox(); + return sdet; +} + +DECLARE_DETELEMENT(forwardBeamPipeBrazil, create_detector) From fc55362e8f6f20168bc39fede590aaf840199d93 Mon Sep 17 00:00:00 2001 From: Simon Gardner Date: Fri, 5 Apr 2024 00:16:58 +0100 Subject: [PATCH 06/25] Added definitions_craterlake to ip6 configurations (#696) ### Briefly, what does this PR introduce? The ip6 configurations were unable to be used to reconstruct tracks from the B0 surfaces without the DD4hep_SubdetectorAssembly which wraps around it which is defined in definitions_craterlake. ### What kind of change does this PR introduce? - [x] Bug fix (issue #__) - [ ] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No ### Does this PR change default behavior? No --- configurations/ip6.yml | 2 ++ configurations/ip6_extended.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/configurations/ip6.yml b/configurations/ip6.yml index 66fa680e6..cd9591e83 100644 --- a/configurations/ip6.yml +++ b/configurations/ip6.yml @@ -1,5 +1,7 @@ features: beampipe: + tracking: + definitions_craterlake: far_forward: default: far_backward: diff --git a/configurations/ip6_extended.yml b/configurations/ip6_extended.yml index d1a1f000c..5e4a172f9 100644 --- a/configurations/ip6_extended.yml +++ b/configurations/ip6_extended.yml @@ -1,5 +1,7 @@ features: beampipe: + tracking: + definitions_craterlake: far_forward: default: far_backward: From d17a5c7dba1ac54e1faf0be80f9f64a3ba1fa2a3 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Thu, 4 Apr 2024 22:01:59 -0500 Subject: [PATCH 07/25] feat: material map generation and validation scripts and pipeline job (#677) ### Briefly, what does this PR introduce? This PR adds automatic material map generation and validation (including comparison with what happens if we reuse the previous field map). It runs this in a pipeline job. All this is based on @ShujieL's scripts in https://github.com/eic/snippets/tree/main/Tracking/material_map. It adds: - automatic download of Acts source files, - less copied code, more calling of Acts source, - (therefore) less flexibility in file names. ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [x] Changes have been communicated to collaborators @ShujieL ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? No. --------- Co-authored-by: Dmitry Kalinkin --- .github/workflows/linux-eic-shell.yml | 31 +++++ scripts/material_map/.gitignore | 5 + scripts/material_map/epic.py | 49 +++++++ scripts/material_map/geometry_epic.py | 40 ++++++ scripts/material_map/material_mapping_epic.py | 51 +++++++ .../material_map/material_recording_epic.py | 77 +++++++++++ .../material_map/material_validation_epic.py | 54 ++++++++ scripts/material_map/materialmap_config.py | 70 ++++++++++ .../run_material_map_validation.sh | 127 ++++++++++++++++++ 9 files changed, 504 insertions(+) create mode 100644 scripts/material_map/.gitignore create mode 100644 scripts/material_map/epic.py create mode 100644 scripts/material_map/geometry_epic.py create mode 100644 scripts/material_map/material_mapping_epic.py create mode 100644 scripts/material_map/material_recording_epic.py create mode 100644 scripts/material_map/material_validation_epic.py create mode 100644 scripts/material_map/materialmap_config.py create mode 100755 scripts/material_map/run_material_map_validation.sh diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index fe7a81a42..c20fab6d2 100644 --- a/.github/workflows/linux-eic-shell.yml +++ b/.github/workflows/linux-eic-shell.yml @@ -189,6 +189,37 @@ jobs: root -b -q "scripts/test_ACTS.cxx+(\"${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml\")" | tee check_tracking_geometry.out bin/acts_geo_check check_tracking_geometry.out + validate-material-map: + runs-on: ubuntu-latest + needs: + - build + - check-tracking-geometry + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: build-gcc-full-eic-shell + path: install/ + - uses: cvmfs-contrib/github-action-cvmfs@v4 + - uses: eic/run-cvmfs-osg-eic-shell@main + with: + platform-release: "jug_xl:nightly" + setup: install/setup.sh + run: | + pushd scripts/material_map + export DETECTOR_CONFIG=epic_craterlake_material_map + ./run_material_map_validation.sh + popd + - uses: actions/upload-artifact@v4 + with: + name: material_map + path: | + "scripts/material_map/*.json" + "scripts/material_map/*.root" + scripts/material_map/Surfaces/ + scripts/material_map/Validation/ + if-no-files-found: error + convert-to-gdml: runs-on: ubuntu-latest needs: diff --git a/scripts/material_map/.gitignore b/scripts/material_map/.gitignore new file mode 100644 index 000000000..302d91010 --- /dev/null +++ b/scripts/material_map/.gitignore @@ -0,0 +1,5 @@ +Examples/ +Surfaces/ +Validation/ +calibrations/ +*.json diff --git a/scripts/material_map/epic.py b/scripts/material_map/epic.py new file mode 100644 index 000000000..4e8fc2858 --- /dev/null +++ b/scripts/material_map/epic.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2024 Shujie Li + +## Stand alone function to build ePIC geometry with ACTS python bindings +## for material mapping +## Shujie Li, 03, 2024 + +from pathlib import Path + +import acts +import acts.examples.dd4hep + +from acts import ( + Vector4, + MaterialMapJsonConverter +) + +import json + +def getDetector( + xmlFile, + jsonFile="", + logLevel=acts.logging.WARNING, +): + customLogLevel = acts.examples.defaultLogging(logLevel=logLevel) + logger = acts.logging.getLogger("epic.getDetector") + + matDeco = None + if len(jsonFile)>0: + file = Path(jsonFile) + logger.info("Adding material from %s", file.absolute()) + matDeco = acts.IMaterialDecorator.fromFile( + file, + level=customLogLevel(maxLevel=acts.logging.INFO), + ) + + dd4hepConfig = acts.examples.dd4hep.DD4hepGeometryService.Config( + xmlFileNames=[xmlFile], + logLevel=logLevel, + dd4hepLogLevel=customLogLevel(), + ) + detector = acts.examples.dd4hep.DD4hepDetector() + + config = acts.MaterialMapJsonConverter.Config() + + trackingGeometry, deco = detector.finalize(dd4hepConfig, matDeco) + + return detector, trackingGeometry, deco diff --git a/scripts/material_map/geometry_epic.py b/scripts/material_map/geometry_epic.py new file mode 100644 index 000000000..596afa6ca --- /dev/null +++ b/scripts/material_map/geometry_epic.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2024 Shujie Li + +import os +import argparse + +import acts + +import epic +from geometry import runGeometry + +if "__main__" == __name__: + p = argparse.ArgumentParser( + description="Script to generate geometry-map.json for ePIC geometry" + ) + p.add_argument( + "-i", + "--xmlFile", + default=( + os.environ.get("DETECTOR_PATH", "") + + "/" + + os.environ.get("DETECTOR_CONFIG", "") + + ".xml" + ), + help="Input xml file containing ePIC geometry", + ) + args = p.parse_args() + + detector, trackingGeometry, decorators = epic.getDetector(args.xmlFile) + + runGeometry( + trackingGeometry, + decorators, + outputDir=os.getcwd(), + outputObj=False, + outputCsv=False, + outputJson=True, + outputRoot=True, + ) diff --git a/scripts/material_map/material_mapping_epic.py b/scripts/material_map/material_mapping_epic.py new file mode 100644 index 000000000..ded6fc7d8 --- /dev/null +++ b/scripts/material_map/material_mapping_epic.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2024 Shujie Li + +import os +import argparse + +import acts +from acts.examples import JsonFormat + +import epic +from material_mapping import runMaterialMapping + +if "__main__" == __name__: + + p = argparse.ArgumentParser( + description="Script to generate material map for ePIC geometry" + ) + p.add_argument( + "--xmlFile", + default=os.environ.get("DETECTOR_PATH", "")+"epic_craterlake.xml", + help="input xml file containing ePIC geometry", + ) + p.add_argument( + "--geoFile", + type=str, + default="geometry-map.json", + help="input json file to define volumes and layers used in material mapping", + ) + p.add_argument( + "--matFile", + type=str, + default="material-map.json", + help="output filename for the generated material map, can be json and cbor formats", + ) + args = p.parse_args() + + mapName = args.matFile.split('.')[0] + + detector, trackingGeometry, decorators = epic.getDetector( + args.xmlFile, args.geoFile) + + runMaterialMapping( + trackingGeometry, + decorators, + outputDir = os.getcwd(), + inputDir = os.getcwd(), + readCachedSurfaceInformation=False, + mapVolume= False, + mapName = mapName, + ).run() diff --git a/scripts/material_map/material_recording_epic.py b/scripts/material_map/material_recording_epic.py new file mode 100644 index 000000000..85290e955 --- /dev/null +++ b/scripts/material_map/material_recording_epic.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2024 Shujie Li + +import os +import warnings +from pathlib import Path +import argparse + +import acts +from acts.examples import ( + GaussianVertexGenerator, + ParametricParticleGenerator, + FixedMultiplicityGenerator, + EventGenerator, + RandomNumbers, +) + +import acts.examples.dd4hep +import acts.examples.geant4 +import acts.examples.geant4.dd4hep + +import epic +from material_recording import runMaterialRecording + +u = acts.UnitConstants + +_material_recording_executed = False + + +def main(): + + p = argparse.ArgumentParser() + p.add_argument( + "-n", "--events", type=int, default=1000, help="Number of events to generate" + ) + p.add_argument( + "-t", "--tracks", type=int, default=100, help="Particle tracks per event" + ) + p.add_argument( + "-i", "--xmlFile", type=str, default=os.environ.get("DETECTOR_PATH", "") + os.environ.get("DETECTOR_CONFIG", "") + ".xml", help="DD4hep input file" + ) + p.add_argument( + "-o", "--outputName", type=str, default="geant4_material_tracks.root", help="Name of the output rootfile" + ) + p.add_argument( + "--eta_min", + type=float, + default=-8.0, + help="eta min (optional)", + ) + p.add_argument( + "--eta_max", + type=float, + default=8.0, + help="eta max (optional)", + ) + args = p.parse_args() + + detector, trackingGeometry, decorators = epic.getDetector( + args.xmlFile) + + detectorConstructionFactory = ( + acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) + ) + + runMaterialRecording( + detectorConstructionFactory=detectorConstructionFactory, + tracksPerEvent=args.tracks, + outputDir=os.getcwd(), + etaRange=(args.eta_min, args.eta_max), + s=acts.examples.Sequencer(events=args.events, numThreads=1), + ).run() + + +if "__main__" == __name__: + main() diff --git a/scripts/material_map/material_validation_epic.py b/scripts/material_map/material_validation_epic.py new file mode 100644 index 000000000..6317ba08f --- /dev/null +++ b/scripts/material_map/material_validation_epic.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2024 Shujie Li + +import os +import argparse + +import acts +import acts.examples.dd4hep +from acts.examples import Sequencer + +import epic +from material_validation import runMaterialValidation + + +if "__main__" == __name__: + + p = argparse.ArgumentParser( + description="Script to produce propogation validation for ePIC material mapping." + ) + p.add_argument( + "--xmlFile", + default=os.environ.get("DETECTOR_PATH", "") + os.environ.get("DETECTOR_CONFIG", "") + ".xml", + help="input xml file containing ePIC geometry", + ) + p.add_argument( + "--matFile", + type=str, + default="material-map.json", + help="input material map file, can be either Json or Cbor", + ) + p.add_argument( + "--outputName", + type=str, + default="propagation-material.root", + help="customized name of the output rootfile", + ) + p.add_argument( + "-n","--nevents", + type=int, + default=100, + help="number of events to run", + ) + args = p.parse_args() + + detector, trackingGeometry, decorators = epic.getDetector(args.xmlFile, args.matFile) + + field = acts.ConstantBField(acts.Vector3(0, 0, 0)) + + runMaterialValidation( + trackingGeometry, decorators, field, + outputDir=os.getcwd(), outputName=args.outputName, + s=Sequencer(events=args.nevents, numThreads=-1) + ).run() diff --git a/scripts/material_map/materialmap_config.py b/scripts/material_map/materialmap_config.py new file mode 100644 index 000000000..ead046234 --- /dev/null +++ b/scripts/material_map/materialmap_config.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-3.0-or-later +# Copyright (C) 2024 Shujie Li + +## Generate ePIC material map for ACTS +## read config-map.json and turn on mapping for approach 1 and 2 of each sensitive surface. +import pandas as pd +import numpy as np +import json +import os +import argparse + +if "__main__" == __name__: + p = argparse.ArgumentParser( + description="Script to turn on all approach 1 and 2, and also the beampipe surface in config json file for matieral mapping" + ) + p.add_argument( + "-i","--inputFile", + type=str, + default="config-map.json", + help=" input json file to be modified", + ) + p.add_argument( + "-o","--outputFile", + type=str, + default="config-map_new.json", + help=" output json file", + ) + +args = p.parse_args() +print(args) +fname = args.inputFile +out_name = args.outputFile + + +## load json file +f = open(fname) +dd = json.load(f) + +ee=dd['Volumes']['entries'] + +## print volume name and ID +print ("Volume ID Name Approaches") +for vv in np.arange(len(ee)): + nn = ee[vv]['value']['NAME'] + + if "|" not in nn and "Gap" not in nn: + print(ee[vv]['volume'], nn,"1, 2")#print(ee[vv]['value'])#['NAME']) + if "acts_beampipe_central::Barrel" in nn: + v_beampipe = vv+1 + print(v_beampipe, nn, "X") + +## find apporach 1 and 2 to turn on mapping +for vv in np.arange(1,1+len(dd['Surfaces'])): + for ii,tt in enumerate(dd['Surfaces'][str(vv)]): + if 'approach' in tt: + dd['Surfaces'][str(vv)][ii]['value']['material']['mapMaterial']=True + ## turn on beampipe surface and defind binning + elif vv==v_beampipe: + if tt['value']['bounds']['type']=='CylinderBounds': + # print (dd['Surfaces'][str(vv)][ii]) + dd['Surfaces'][str(vv)][ii]['value']['material']['mapMaterial']=True + dd['Surfaces'][str(vv)][ii]['value']['material']['binUtility']['binningdata'][0]['bins']=36 + dd['Surfaces'][str(vv)][ii]['value']['material']['binUtility']['binningdata'][1]['bins']=200 + + +with open(out_name, "w") as outfile: + json.dump(dd, outfile, indent=4) + +print("Done! Updated config file at "+out_name) diff --git a/scripts/material_map/run_material_map_validation.sh b/scripts/material_map/run_material_map_validation.sh new file mode 100755 index 000000000..3daafd1bd --- /dev/null +++ b/scripts/material_map/run_material_map_validation.sh @@ -0,0 +1,127 @@ +#!/bin/bash +set -e +# script for material map validation with ACTS python bindings +# run as : ./run_material_map_validation.sh --nevents 1000 +# Shujie Li, 03. 2024 (https://github.com/eic/snippets/pull/3) + +# Check if DETECTOR_PATH and DETECTOR_CONFIG are set +if [[ -z ${DETECTOR_PATH} || -z ${DETECTOR_CONFIG} ]] ; then + echo "You must set \$DETECTOR_PATH and \$DETECTOR_CONFIG before running this script." + exit -1 +fi + +# Download required Acts files +ACTS_VERSION="682d2080d36712ac15975340c92f860b25169213" +ACTS_URL="https://github.com/acts-project/acts/raw/" +ACTS_FILES=( + "Examples/Scripts/Python/geometry.py" + "Examples/Scripts/Python/material_mapping.py" + "Examples/Scripts/Python/material_recording.py" + "Examples/Scripts/Python/material_validation.py" + "Examples/Scripts/MaterialMapping/writeMapConfig.py" + "Examples/Scripts/MaterialMapping/configureMap.py" + "Examples/Scripts/MaterialMapping/Mat_map.C" + "Examples/Scripts/MaterialMapping/Mat_map_surface_plot.C" + "Examples/Scripts/MaterialMapping/Mat_map_surface_plot_ratio.C" + "Examples/Scripts/MaterialMapping/Mat_map_surface_plot_dist.C" + "Examples/Scripts/MaterialMapping/Mat_map_surface_plot_1D.C" + "Examples/Scripts/MaterialMapping/materialPlotHelper.cpp" + "Examples/Scripts/MaterialMapping/materialPlotHelper.hpp" +) +for file in ${ACTS_FILES[@]} ; do + if [ ! -f ${file} ] ; then + curl --silent --location --create-dirs --output ${file} ${ACTS_URL}/${ACTS_VERSION}/${file} + fi +done +export PYTHONPATH=$PWD/Examples/Scripts/Python:$PYTHONPATH + +# Default arguments +nevents=1000 +nparticles=1000 +while [[ $# -gt 1 ]] +do + key="$1" + case $key in + --nevents) + nevents=$2 + shift # past value + shift + ;; + --nparticles) + nparticles=$2 + shift # past value + shift + ;; + *) # unknown option + #POSITIONAL+=("$1") # save it in an array for later + echo "unknown option $1" + print_the_help + shift # past argument + ;; + esac +done +set -- "${POSITIONAL[@]}" # restore positional parameters + +recordingFile=geant4_material_tracks.root +geoFile=geometry-map.json +matFile=material-map.json +trackFile=material-map_tracks.root +propFile=propagation_material + +echo "::group::----GEANTINO SCAN------" +# output geant4_material_tracks.root +# The result of the geantino scan will be a root file containing material tracks. Those contain the direction and production vertex of the geantino, the total material accumulated and all the interaction points in the detector. +python material_recording_epic.py -i ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml -n ${nevents} -t ${nparticles} -o ${recordingFile} +echo "::endgroup::" + +echo "::group::-----MAPPING Configuration-----" +# map geometry to geometry-map.json +python geometry_epic.py -i ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml + +# take geometry-map.json and read out config-map.json +python Examples/Scripts/MaterialMapping/writeMapConfig.py ${geoFile} config-map.json + +# turn on approaches and beampipe surfaces for material mapping +# you can always manually adjust the mapmaterial flag and binnings in config-map.json +python materialmap_config.py -i config-map.json -o config-map_new.json + +# turn config-map.json into modified geometry-map.json +python Examples/Scripts/MaterialMapping/configureMap.py ${geoFile} config-map_new.json +echo "::endgroup::" + +echo "::group::----MAPPING------------" +# input: geant4_material_tracks.root, geometry-map.json +# output: material-maps.json or cbor. This is the material map that you want to provide to EICrecon, i.e. -Pacts:MaterialMap=XXX .Please --matFile to specify the name and type +# material-maps_tracks.root(recorded steps from geantino, for validation purpose) +python material_mapping_epic.py --xmlFile ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml --geoFile ${geoFile} --matFile ${matFile} +echo "::endgroup::" + +echo "::group::----Prepare validation rootfile--------" +# output propagation-material.root +python material_validation_epic.py --xmlFile ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml --outputName ${propFile}_new --matFile ${matFile} -n ${nevents} +python material_validation_epic.py --xmlFile ${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml --outputName ${propFile}_old --matFile "calibrations/materials-map.cbor" -n ${nevents} +echo "::endgroup::" + +echo "::group::-------Comparison plots---------" +rm -rf Validation/new +mkdir -p Validation/new +root -l -b -q Examples/Scripts/MaterialMapping/Mat_map.C'("'${propFile}_new'.root","'${trackFile}'","Validation/new")' +rm -rf Validation/old +mkdir -p Validation/old +root -l -b -q Examples/Scripts/MaterialMapping/Mat_map.C'("'${propFile}_old'.root","'${trackFile}'","Validation/old")' + +rm -rf Surfaces +mkdir -p Surfaces/new/ratio_plot +mkdir -p Surfaces/new/prop_plot +mkdir -p Surfaces/new/map_plot +mkdir -p Surfaces/old/ratio_plot +mkdir -p Surfaces/old/prop_plot +mkdir -p Surfaces/old/map_plot +mkdir -p Surfaces/dist_plot +mkdir -p Surfaces/1D_plot + +root -l -b -q Examples/Scripts/MaterialMapping/Mat_map_surface_plot_ratio.C'("'${propFile}_new'.root","'${trackFile}'",-1,"Surfaces/new/ratio_plot","Surfaces/new/prop_plot","Surfaces/new/map_plot")' +root -l -b -q Examples/Scripts/MaterialMapping/Mat_map_surface_plot_ratio.C'("'${propFile}_old'.root","'${trackFile}'",-1,"Surfaces/old/ratio_plot","Surfaces/old/prop_plot","Surfaces/old/map_plot")' +root -l -b -q Examples/Scripts/MaterialMapping/Mat_map_surface_plot_dist.C'("'${trackFile}'",-1,"Surfaces/dist_plot")' +root -l -b -q Examples/Scripts/MaterialMapping/Mat_map_surface_plot_1D.C'("'${trackFile}'",-1,"Surfaces/1D_plot")' +echo "::endgroup::" From 595c73537e4d0f33330a3af956b87b61c7bd408a Mon Sep 17 00:00:00 2001 From: Simon Gardner Date: Fri, 5 Apr 2024 16:50:07 +0100 Subject: [PATCH 08/25] Extended configs tested by check-tracking-geometry (#697) ### Briefly, what does this PR introduce? Adds tests to check if more configurations are pass the check-tracking-geometry check. Initially this is before the epic_ip6 has been updated so should fail the test but probably initially won't. This should be followed by a change to acts_geo_check to cover the case or a request to change the logger level of messages which should cause it to fail. ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No ### Does this PR change default behavior? No --- .github/workflows/linux-eic-shell.yml | 5 ++++- bin/acts_geo_check | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index c20fab6d2..52f32c9fa 100644 --- a/.github/workflows/linux-eic-shell.yml +++ b/.github/workflows/linux-eic-shell.yml @@ -173,6 +173,9 @@ jobs: check-tracking-geometry: runs-on: ubuntu-latest needs: build + strategy: + matrix: + detector_config: [epic_craterlake, epic_ip6] steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 @@ -186,7 +189,7 @@ jobs: network_types: "none" setup: install/setup.sh run: | - root -b -q "scripts/test_ACTS.cxx+(\"${DETECTOR_PATH}/${DETECTOR_CONFIG}.xml\")" | tee check_tracking_geometry.out + root -b -q "scripts/test_ACTS.cxx+(\"${DETECTOR_PATH}/${{matrix.detector_config}}.xml\")" | tee check_tracking_geometry.out bin/acts_geo_check check_tracking_geometry.out validate-material-map: diff --git a/bin/acts_geo_check b/bin/acts_geo_check index 697c415f6..fde323451 100755 --- a/bin/acts_geo_check +++ b/bin/acts_geo_check @@ -20,4 +20,11 @@ if [[ "$nlines" > "0" ]] ; then res="1" fi +nlines=$(grep -in inconsistent ${logfile} | grep -in acts | wc -l) +if [[ "$nlines" > "0" ]] ; then + echo " ACTS geometry error: " + grep -in inconsistent ${logfile} | grep -in acts + res="1" +fi + exit ${res} From 66d487e05b3810d279433af83603bad77b4e0629 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Fri, 5 Apr 2024 15:46:26 -0500 Subject: [PATCH 09/25] feat: install setup.sh as FHS compliant bin/thisepic.sh (#698) ### Briefly, what does this PR introduce? Installing `setup.sh` in the prefix is not consistent with the linux filesystem hierarchy standard and leads to `/usr/local/setup.sh`. This PR installs `setup.sh` into e.g. `/usr/local/bin/thisepic.sh`, which is FHS compliant. Next steps: - Transition to using FHS location - Add deprecation warning to old version (v24.MM++) - Remove old version (v24.MM++) ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? Not yet, but recommended default changes. --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfdbad6d9..0f8da16e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,6 +113,10 @@ configure_file(templates/setup.sh.in ${CMAKE_CURRENT_BINARY_DIR}/setup.sh @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/setup.sh DESTINATION ${CMAKE_INSTALL_PREFIX} ) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/setup.sh + DESTINATION ${CMAKE_INSTALL_BINDIR} + RENAME this${PROJECT_NAME}.sh +) # install programs install(PROGRAMS bin/g4MaterialScan_to_csv From cd40db4ffdb055d56da6e061cd70afa330ebdc2a Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 8 Apr 2024 17:31:46 -0500 Subject: [PATCH 10/25] feat: add barrel flux return (#694) ### Briefly, what does this PR introduce? This PR adds the barrel flux return backlegs and spacers per the info in #693. Needed for hall background radiation studies. Also adds forward endcap flux return. ![image](https://github.com/eic/epic/assets/4656391/162865d8-0b08-4ead-a33c-ade3a2dfc0df) ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [x] Changes have been communicated to collaborators @ajentsch ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? Not really for any detector behavior. --------- Co-authored-by: Dmitry Kalinkin --- compact/definitions.xml | 37 ++++++-- compact/display.xml | 8 +- compact/hcal/backward_endcap_flux.xml | 10 +-- compact/hcal/barrel_flux_return.xml | 110 ++++++++++++++++++++++++ compact/hcal/forward_endcap_flux.xml | 35 ++++++++ compact/hcal/lfhcal.xml | 7 +- compact/materials.xml | 12 +++ configurations/craterlake.yml | 2 + configurations/craterlake_10x100.yml | 2 + configurations/craterlake_10x275.yml | 2 + configurations/craterlake_18x110_Au.yml | 2 + configurations/craterlake_18x275.yml | 2 + configurations/craterlake_no_bhcal.yml | 2 + src/BarrelFluxReturn_geo.cpp | 52 +++++++++++ src/EndcapFluxReturn_geo.cpp | 7 +- src/LFHCAL_geo.cpp | 24 ++++-- 16 files changed, 285 insertions(+), 29 deletions(-) create mode 100644 compact/hcal/barrel_flux_return.xml create mode 100644 compact/hcal/forward_endcap_flux.xml create mode 100644 src/BarrelFluxReturn_geo.cpp diff --git a/compact/definitions.xml b/compact/definitions.xml index 952dfff09..cbb47ee99 100644 --- a/compact/definitions.xml +++ b/compact/definitions.xml @@ -630,17 +630,36 @@ Service gaps in FW direction (before endcapP ECAL) and BW direction (before endc - - + Lepton_Assy_21.stp, rwimmer, 2024-04-03 - - - - + + + + - - - + + + + + Hadron End Cap Assembly_North Half.stp, rwimmer, 2024-04-03 + + + + + + + + LFHCAL includes support, which is part of the flux return + + + STAR Asm for EPIC w cradle.stp, rwimmer, 2024-04-03 + + + + + + + These are used by ddsim, the region where we store all secondaries diff --git a/compact/display.xml b/compact/display.xml index 4b54d080b..e9f6adef9 100644 --- a/compact/display.xml +++ b/compact/display.xml @@ -105,9 +105,13 @@ - - + + + + + + Passive steel for flux return diff --git a/compact/hcal/backward_endcap_flux.xml b/compact/hcal/backward_endcap_flux.xml index 64595615c..a568e071f 100644 --- a/compact/hcal/backward_endcap_flux.xml +++ b/compact/hcal/backward_endcap_flux.xml @@ -6,7 +6,7 @@ #### Dimension constants - + @@ -15,9 +15,9 @@ - ### Backwards (Negative Z) Endcap Flux Return + ### Backward (Negative Z) Endcap Flux Return - + diff --git a/compact/hcal/barrel_flux_return.xml b/compact/hcal/barrel_flux_return.xml new file mode 100644 index 000000000..59249c545 --- /dev/null +++ b/compact/hcal/barrel_flux_return.xml @@ -0,0 +1,110 @@ + + + + + + + #### Dimension constants + + + + + Trapezoid for STAR backlegs + + + + + + + + + Box for spacers + + + + + + + + + + + + ### Barrel Flux Return + + + + + Trd1 is defined such that x1/x2 are equivalent with y at phi = 0 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compact/hcal/forward_endcap_flux.xml b/compact/hcal/forward_endcap_flux.xml new file mode 100644 index 000000000..e13745836 --- /dev/null +++ b/compact/hcal/forward_endcap_flux.xml @@ -0,0 +1,35 @@ + + + + + + + #### Dimension constants + + + + + + + + + + ### Forward (Positive Z) Endcap Flux Return + + + + + + + + + + + + diff --git a/compact/hcal/lfhcal.xml b/compact/hcal/lfhcal.xml index 3c18598e2..3a903e6c7 100644 --- a/compact/hcal/lfhcal.xml +++ b/compact/hcal/lfhcal.xml @@ -94,7 +94,12 @@ + rmax="LFHCAL_rmax" + x="3*EightM_OuterWidth" + y="6*EightM_OuterHeight" + x0="-FourM_OuterWidth"/> + + + + + SAE AISI 1008 cold-rolled low-carbon steel + https://www.azom.com/article.aspx?ArticleID=6538 + + + + + + + + diff --git a/configurations/craterlake.yml b/configurations/craterlake.yml index 050c73b00..2b9b241d1 100644 --- a/configurations/craterlake.yml +++ b/configurations/craterlake.yml @@ -28,6 +28,8 @@ features: lfhcal_with_space_for_insert: forward_insert: barrel_gdml: + barrel_flux_return: + forward_endcap_flux: backward: backward_endcap_flux: far_forward: diff --git a/configurations/craterlake_10x100.yml b/configurations/craterlake_10x100.yml index e2fefd19b..39bfe43ad 100644 --- a/configurations/craterlake_10x100.yml +++ b/configurations/craterlake_10x100.yml @@ -27,6 +27,8 @@ features: hcal: lfhcal_with_space_for_insert: forward_insert: + forward_endcap_flux: + barrel_flux_return: barrel_gdml: backward: backward_endcap_flux: diff --git a/configurations/craterlake_10x275.yml b/configurations/craterlake_10x275.yml index 760891776..c645a6926 100644 --- a/configurations/craterlake_10x275.yml +++ b/configurations/craterlake_10x275.yml @@ -28,6 +28,8 @@ features: lfhcal_with_space_for_insert: forward_insert: barrel_gdml: + barrel_flux_return: + forward_endcap_flux: backward: backward_endcap_flux: far_forward: diff --git a/configurations/craterlake_18x110_Au.yml b/configurations/craterlake_18x110_Au.yml index 53994b674..e9736a234 100644 --- a/configurations/craterlake_18x110_Au.yml +++ b/configurations/craterlake_18x110_Au.yml @@ -28,6 +28,8 @@ features: lfhcal_with_space_for_insert: forward_insert: barrel_gdml: + barrel_flux_return: + forward_endcap_flux: backward: backward_endcap_flux: far_forward: diff --git a/configurations/craterlake_18x275.yml b/configurations/craterlake_18x275.yml index 76721d71f..7f0972f1d 100644 --- a/configurations/craterlake_18x275.yml +++ b/configurations/craterlake_18x275.yml @@ -28,6 +28,8 @@ features: lfhcal_with_space_for_insert: forward_insert: barrel_gdml: + barrel_flux_return: + forward_endcap_flux: backward: backward_endcap_flux: far_forward: diff --git a/configurations/craterlake_no_bhcal.yml b/configurations/craterlake_no_bhcal.yml index 2ed315a8a..94223d402 100644 --- a/configurations/craterlake_no_bhcal.yml +++ b/configurations/craterlake_no_bhcal.yml @@ -27,6 +27,8 @@ features: hcal: lfhcal_with_space_for_insert: forward_insert: + barrel_flux_return: + forward_endcap_flux: backward: backward_endcap_flux: far_forward: diff --git a/src/BarrelFluxReturn_geo.cpp b/src/BarrelFluxReturn_geo.cpp new file mode 100644 index 000000000..9ea328d6d --- /dev/null +++ b/src/BarrelFluxReturn_geo.cpp @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2024 Wouter Deconinck + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/Printout.h" +#include "XML/Utilities.h" + +using namespace dd4hep; + +static dd4hep::Ref_t create_detector(dd4hep::Detector& description, xml_h e, [[maybe_unused]] dd4hep::SensitiveDetector sens) +{ + xml_det_t x_det = e; + xml_comp_t x_dim = x_det.dimensions(); + + // Create element + dd4hep::DetElement sdet(x_det.nameStr(), x_det.id()); + + // Create envelope + dd4hep::Material air = description.air(); + Tube env_solid(x_dim.rmin(), x_dim.rmax(), x_dim.z() / 2.0); + Volume env_vol(x_det.nameStr() + "_env", env_solid, air); + env_vol.setVisAttributes(description.visAttributes(x_det.visStr())); + + // Create volume map + std::map volumes_by_name; + for (xml_coll_t shape(e, _U(shape)); shape; ++shape) { + xml_comp_t x_shape = shape; + Solid solid = xml::createShape(description, x_shape.typeStr(), shape); + Material mat = description.material(x_shape.materialStr()); + volumes_by_name[x_shape.nameStr()] = + Volume(x_shape.nameStr(), solid, mat) + .setVisAttributes(description.visAttributes(x_shape.visStr())); + } + + // Replicate volumes + for (xml_coll_t repl(e, _U(replicate)); repl; ++repl) { + xml_comp_t x_repl = repl; + Volume& vol = volumes_by_name[x_repl.attr(_U(shape))]; + Transform3D tf = xml::createTransformation(x_repl); + for (int i = 0; i < x_repl.count(); ++i) { + double phi = x_repl.phi0() + i * x_repl.attr(_Unicode(dphi)); + env_vol.placeVolume(vol, Transform3D(RotationZ(phi)) * tf); + } + } + + // Get position and place volume + PlacedVolume pv = description.pickMotherVolume(sdet).placeVolume(env_vol); + sdet.setPlacement(pv); + return sdet; +} + +DECLARE_DETELEMENT(epic_BarrelFluxReturn, create_detector) diff --git a/src/EndcapFluxReturn_geo.cpp b/src/EndcapFluxReturn_geo.cpp index c17158e94..91cf9ef80 100644 --- a/src/EndcapFluxReturn_geo.cpp +++ b/src/EndcapFluxReturn_geo.cpp @@ -16,10 +16,9 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& description, xml_h e, [[m xml_det_t x_det = e; int det_id = x_det.id(); std::string det_name = x_det.nameStr(); + bool reflect = x_det.reflect(false); dd4hep::Material air = description.air(); xml_comp_t x_pos = x_det.position(); - - dd4hep::Assembly assembly(det_name); dd4hep::DetElement sdet(det_name, det_id); dd4hep::PlacedVolume pv; @@ -51,7 +50,7 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& description, xml_h e, [[m s_phv2.addPhysVolID("halfdisk", 1); - pv = assembly.placeVolume(disk, dd4hep::Position(0, 0, -layer_thickness/2-layer_zpos)); + pv = assembly.placeVolume(disk, dd4hep::Position(0, 0, (reflect ? -1.0 : 1.0) * (layer_thickness/2 + layer_zpos))); pv.addPhysVolID("layer", layer_id); disk_ele.setPlacement(pv); } @@ -63,4 +62,4 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& description, xml_h e, [[m return sdet; } -DECLARE_DETELEMENT(epic_EndcapFluxReturnN, create_detector) +DECLARE_DETELEMENT(epic_EndcapFluxReturn, create_detector) diff --git a/src/LFHCAL_geo.cpp b/src/LFHCAL_geo.cpp index e23dc7957..fef21b5d2 100644 --- a/src/LFHCAL_geo.cpp +++ b/src/LFHCAL_geo.cpp @@ -782,10 +782,18 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens // general detector dimensions xml_dim_t dim = detElem.dimensions(); double length = dim.z(); // Size along z-axis - xml_dim_t pos = detElem.position(); + // general detector position + xml_dim_t pos = detElem.position(); printout(DEBUG, "LFHCAL_geo", "global LFHCal position " + _toString(pos.x()) + "\t" + _toString(pos.y()) + "\t" + _toString(pos.z())); + // envelope volume + xml_comp_t x_env = detElem.child(_Unicode(envelope)); + Tube rmaxtube(0, dim.rmax(), dim.z() / 2); + Box beampipe(dim.x() / 2, dim.y() / 2, dim.z() / 2); + Solid env = SubtractionSolid(rmaxtube, beampipe, Position(dim.x0(),0,0)); + Volume env_vol(detName + "_env", env, desc.material(x_env.materialStr())); + bool renderComponents = getAttrOrDefault(detElem, _Unicode(renderComponents), 0.); bool allSensitive = getAttrOrDefault(detElem, _Unicode(allSensitive), 0.); if (renderComponents) { @@ -901,7 +909,7 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens moduleIDy = ((pos8M[e].y + 265) / 10); // Placing modules in world volume - auto tr8M = Transform3D(Position(pos.x()-pos8M[e].x-0.5*eightM_params.mod_width, pos.y() - pos8M[e].y, pos.z() + pos8M[e].z + length / 2.)); + auto tr8M = Transform3D(Position(-pos8M[e].x-0.5*eightM_params.mod_width, -pos8M[e].y, pos8M[e].z)); phv = assembly.placeVolume(eightMassembly, tr8M); phv.addPhysVolID("moduleIDx", moduleIDx).addPhysVolID("moduleIDy", moduleIDy).addPhysVolID("moduletype", 0); } @@ -929,16 +937,16 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens printout(DEBUG, "LFHCAL_geo", "LFHCAL WRONG ID FOR 4M module: " + _toString(f) + "/" + _toString((int)pos4M.size()) + "\t" + _toString(moduleIDx) + "\t" + _toString(moduleIDy)); } - auto tr4M = Transform3D(Position(pos.x()-pos4M[f].x-0.5*fourM_params.mod_width, pos.y()-pos4M[f].y, pos.z() + pos4M[f].z + length / 2.)); + auto tr4M = Transform3D(Position(-pos4M[f].x-0.5*fourM_params.mod_width, -pos4M[f].y, pos4M[f].z)); phv = assembly.placeVolume(fourMassembly, tr4M); phv.addPhysVolID("moduleIDx", moduleIDx).addPhysVolID("moduleIDy", moduleIDy).addPhysVolID("moduletype", 1); } - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr = Translation3D(0., 0., 0.) * RotationZYX(0.,0.,0.); - PlacedVolume envPV = motherVol.placeVolume(assembly, tr); - envPV.addPhysVolID("system", detID); - det.setPlacement(envPV); + Volume motherVol = desc.pickMotherVolume(det); + phv = env_vol.placeVolume(assembly); + phv = motherVol.placeVolume(env_vol, Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.))); + phv.addPhysVolID("system", detID); + det.setPlacement(phv); return det; } From c6992d0bd0a3c02541c722db3c30ec7f9d754f81 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:52:27 -0500 Subject: [PATCH 11/25] [pre-commit.ci] pre-commit autoupdate (#701) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v4.6.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8a6affb0..f25a40848 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ ci: skip: [clang-format] repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-yaml - id: end-of-file-fixer From cd216f657bfa71ca90fcc9a5714fa0e42852db52 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Thu, 11 Apr 2024 16:40:57 -0400 Subject: [PATCH 12/25] remove HybridCalorimeter (#703) This is unused. --- compact/ecal/backward_hybrid.xml | 76 ------------- src/HybridCalorimeter_geo.cpp | 187 ------------------------------- 2 files changed, 263 deletions(-) delete mode 100644 compact/ecal/backward_hybrid.xml delete mode 100644 src/HybridCalorimeter_geo.cpp diff --git a/compact/ecal/backward_hybrid.xml b/compact/ecal/backward_hybrid.xml deleted file mode 100644 index bee40e905..000000000 --- a/compact/ecal/backward_hybrid.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - Transition area. - The idea behind this parametrization is that: - one glass module with its wrap is always - a size of 4 crystal modules with its wraps. - Then the transition area (where glass meets crystals) has no gaps - - +----------------+----------------+ - | +----+ +----+ | +----------+ | - | | | | | | | | | - | +----+ +----+ | | | | - | +----+ +----+ | | | | - | | | | | | | | | - | +----+ +----+ | +----------+ | - +----------------+----------------+ - crystal glass - - This implies that: - GlassModule_wrap = 2*CrystalModule_wrap - GlassModule_sx = 2*CrystalModule_sx - GlassModule_sy = 2*CrystalModule_sy - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #### Backwards Endcap EM Calorimeter - - Backwards Endcap EM Calorimeter, placements generated by script - - - - - - - - Effectively no segmentation, the segmentation is used to provide cell dimension info - - - - - - system:8,sector:4,module:20,x:32:-16,y:-16 - - - diff --git a/src/HybridCalorimeter_geo.cpp b/src/HybridCalorimeter_geo.cpp deleted file mode 100644 index 0117e65bf..000000000 --- a/src/HybridCalorimeter_geo.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-License-Identifier: LGPL-3.0-or-later -// Copyright (C) 2022 Dmitry Romanov, Sylvester Joosten, Chao Peng - -//========================================================================== -// A general implementation for homogeneous calorimeter -// it supports three types of placements -// 1. Individual module placement with module dimensions and positions -// 2. Array placement with module dimensions and numbers of row and columns -// 3. Disk placement with module dimensions and (Rmin, Rmax), and (Phimin, Phimax) -// 4. Lines placement with module dimensions and (mirrorx, mirrory) -// (NOTE: anchor point is the 0th block of the line instead of line center) -//-------------------------------------------------------------------------- -// Author: Chao Peng (ANL) -// Date: 06/09/2021 -//========================================================================== - -#include "DD4hep/DetFactoryHelper.h" -#include "GeometryHelpers.h" -#include -#include -#include -#include -#include -#include - -using namespace dd4hep; - -// main -static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens) -{ - - using namespace std; - using namespace fmt; - - xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - DetElement det(detName, detID); - sens.setType("calorimeter"); - - auto glass_material = desc.material("SciGlass"); - auto crystal_material = desc.material("PbWO4"); - auto air_material = desc.material("Air"); - - double ROut = desc.constantAsDouble("EcalEndcapN_rmax"); - double RIn_el = desc.constantAsDouble("EcalEndcapN_rmin1"); - double ionCutout_dphi = desc.constantAsDouble("EcalEndcapNIonCutout_dphi"); - double RIn = desc.constantAsDouble("EcalEndcapN_rmin2"); - double SizeZ = desc.constantAsDouble("EcalEndcapN_thickness"); - double thickness = desc.constantAsDouble("EcalEndcapN_thickness"); - double trans_radius = desc.constantAsDouble("EcalEndcapNCrystal_rmax"); - double Glass_z0 = desc.constantAsDouble("GlassModule_z0"); - double Glass_Width = desc.constantAsDouble("GlassModule_width"); - double Glass_thickness = desc.constantAsDouble("GlassModule_length"); - double Glass_Gap = desc.constantAsDouble("GlassModule_wrap"); - double glass_distance = desc.constantAsDouble("GlassModule_distance"); - - double Crystal_Width = desc.constantAsDouble("CrystalModule_width"); - double Crystal_thickness = desc.constantAsDouble("CrystalModule_length"); - double crystal_distance = desc.constantAsDouble("CrystalModule_distance"); - double Crystal_z0 = desc.constantAsDouble("CrystalModule_z0"); - // FIXME Crystal_Gap is read but not used - // double Crystal_Gap = desc.constantAsDouble("CrystalModule_wrap"); - - // RIn and ROut will define outer tube embedding the calorimeter - // centers_rmin/out define the maximum radius of module centers - // so that modules are not overlapping with mother tube volume - const double glassHypotenuse = std::hypot(glass_distance, glass_distance) / 2; - const double crystalHypotenuse = glassHypotenuse / 2; - // Offset these values a bit so we don't miss edge-blocks - const double glassCenters_rmax = ROut - glassHypotenuse + 1 * mm; - const double crystalCenters_rmin = RIn + crystalHypotenuse - 1 * mm; - // Also limits of the inner crystal blocks fill - const double cutout_tan = tan(ionCutout_dphi / 2); - const double cutout_rmin = RIn_el + crystalHypotenuse - 1 * mm; - - // Offset to align the modules at the zmin of the endcap, - const double Crystal_offset = -0.5 * (Crystal_thickness - thickness); - const double Glass_offset = -0.5 * (Glass_thickness - thickness); - - // envelope - // consists of an glass tube of the full thickness, and a crystal inner tube - // for the crystal that allows us to get closet to the beampipe without - // overlaps, and a partial electron tube that allows us to get closer to the - // electron beampipe in the region where there is no ion beampipe - Tube glass_tube(min(RIn + glassHypotenuse * 2, trans_radius), ROut, SizeZ / 2.0, 0., 360.0 * deg); - Tube crystal_tube(RIn, min(RIn + glassHypotenuse * 2, trans_radius), Crystal_thickness / 2.0, 0., 360.0 * deg); - Tube electron_tube(RIn_el, RIn, Crystal_thickness / 2., ionCutout_dphi / 2., 360.0 * deg - ionCutout_dphi / 2); - UnionSolid outer_envelope(glass_tube, crystal_tube, Position(0, 0, Crystal_offset)); - UnionSolid envelope(outer_envelope, electron_tube, Position(0, 0, Crystal_offset)); - Volume ecal_vol("negative_ecal", envelope, air_material); - ecal_vol.setVisAttributes(desc.visAttributes("HybridEcalOuterVis")); - - // TODO why 1cm and not something else? - double Glass_OuterR = ROut - 1 * cm; - - // Geometry of modules - Box glass_box("glass_box", Glass_Width * 0.5, Glass_Width * 0.5, Glass_thickness * 0.5); - Volume glass_module("glass_module", glass_box, glass_material); - glass_module.setVisAttributes(desc.visAttributes("EcalEndcapNModuleVis")); - glass_module.setSensitiveDetector(sens); - - Box crystal_box("crystal_box", Crystal_Width * 0.5, Crystal_Width * 0.5, Crystal_thickness * 0.5); - Volume crystal_module("crystal_module", crystal_box, crystal_material); - crystal_module.setVisAttributes(desc.visAttributes("EcalEndcapNModuleVis")); - crystal_module.setSensitiveDetector(sens); - - // GLASS - double diameter = 2 * Glass_OuterR; - - // Can we fit an even or odd amount of glass blocks within our rmax? - // This determines the transition points between crystal and glass as we need the - // outer crystal arangement to be in multiples of 2 (aligned with glass) - const int towersInRow = std::ceil((diameter + Glass_Gap) / (Glass_Width + Glass_Gap)); - - // Is it odd or even number of towersInRow - double leftTowerPos, topTowerPos; - if (towersInRow % 2) { - // | - // [ ][ ][ ][ ][ ] - // ^ | - int towersInHalfRow = std::ceil(towersInRow / 2.0); - topTowerPos = leftTowerPos = -towersInHalfRow * (Glass_Width + Glass_Gap); - - } else { - // | - // [ ][ ][ ][ ][ ][ ] - // ^ | - int towersInHalfRow = towersInRow / 2; - topTowerPos = leftTowerPos = -(towersInHalfRow - 0.5) * (Glass_Width + Glass_Gap); - } - - int glass_module_index = 0; - int cryst_module_index = 0; - for (int rowIndex = 0; rowIndex < towersInRow; rowIndex++) { - for (int colIndex = 0; colIndex < towersInRow; colIndex++) { - const double glass_x = leftTowerPos + colIndex * (Glass_Width + Glass_Gap); - const double glass_y = topTowerPos + rowIndex * (Glass_Width + Glass_Gap); - const double r = std::hypot(glass_x, glass_y); - // crystal if within the transition radius (as defined by the equivalent glass - // block) - if (r < trans_radius) { - for (const auto dx : {-1, 1}) { - for (const auto& dy : {-1, 1}) { - const double crystal_x = glass_x + dx * crystal_distance / 2; - const double crystal_y = glass_y + dy * crystal_distance / 2; - const double crystal_r = std::hypot(crystal_x, crystal_y); - // check if crystal in the main crystal ring? - const bool mainRing = (crystal_r > crystalCenters_rmin); - const bool innerRing = !mainRing && crystal_r > cutout_rmin; - const bool ionCutout = crystal_x > 0 && fabs(crystal_y / crystal_x) < cutout_tan; - if (mainRing || (innerRing && !ionCutout)) { - auto placement = - ecal_vol.placeVolume(crystal_module, Position(crystal_x, crystal_y, Crystal_z0 + Crystal_offset)); - placement.addPhysVolID("sector", 1); - placement.addPhysVolID("module", cryst_module_index++); - } - } - } - // Glass block if within the rmax - } else if (r < glassCenters_rmax) { - // glass module - auto placement = ecal_vol.placeVolume(glass_module, Position(glass_x, glass_y, Glass_z0 + Glass_offset)); - placement.addPhysVolID("sector", 2); - placement.addPhysVolID("module", glass_module_index++); - } - } - } - - desc.add(Constant("EcalEndcapN_NModules_Sector1", std::to_string(cryst_module_index))); - desc.add(Constant("EcalEndcapN_NModules_Sector2", std::to_string(glass_module_index))); - // fmt::print("Total Glass modules: {}\n", towerIndex); - // fmt::print("CE EMCAL GLASS END\n\n"); - - // detector position and rotation - auto pos = detElem.position(); - auto rot = detElem.rotation(); - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); - PlacedVolume envPV = motherVol.placeVolume(ecal_vol, tr); - envPV.addPhysVolID("system", detID); - det.setPlacement(envPV); - return det; -} - -//@} -DECLARE_DETELEMENT(epic_HybridCalorimeter, create_detector) From a1ea91aa4836f3e44bd5d8faa160217468d7c20f Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 15 Apr 2024 19:49:49 -0500 Subject: [PATCH 13/25] feat: add calibrations.xml (#708) ### Briefly, what does this PR introduce? This PR adds a place to put calibrations artifacts in a place that allows them to be propagated to cached and other configurations. Yes, it's xml, not json, but at some point later we can switch that. ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? No. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- compact/calibrations.xml | 14 ++++++++++++++ templates/epic.xml.jinja2 | 2 ++ 2 files changed, 16 insertions(+) create mode 100644 compact/calibrations.xml diff --git a/compact/calibrations.xml b/compact/calibrations.xml new file mode 100644 index 000000000..07ba8aa2f --- /dev/null +++ b/compact/calibrations.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/templates/epic.xml.jinja2 b/templates/epic.xml.jinja2 index df408d9d2..ad376206d 100644 --- a/templates/epic.xml.jinja2 +++ b/templates/epic.xml.jinja2 @@ -58,6 +58,8 @@ + + From 2ffa142d0bd7055cfbfd9ab7838f5e0b7f6c551c Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 15 Apr 2024 19:50:01 -0500 Subject: [PATCH 14/25] feat(ci): change pre-commit clang-format to run in ci [skip pre-commit.ci] (#705) ### Briefly, what does this PR introduce? This PR lets the CI pre-commit job run automatic clang-format. ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No changes. ### Does this PR change default behavior? Yes, it might lead to developers seeing their code reformatted automatically. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .clang-format | 118 +- .devcontainer/devcontainer.json | 4 +- .pre-commit-config.yaml | 6 +- calibrations/calo_digi_default.json | 128 +- calibrations/emcal_barrel_calibration.json | 14 +- calibrations/ffi_zdc.json | 34 +- scripts/test_ACTS.cxx | 7 +- src/B0ECal_geo.cpp | 43 +- src/B0Preshower_geo.cpp | 133 +- src/B0Tracker_geo.cpp | 159 +- src/BackwardsBeamPipe_geo.cpp | 29 +- src/BackwardsCollimator.cpp | 31 +- src/BackwardsLumiVac_geo.cpp | 5 +- src/BackwardsTaggers_geo.cpp | 197 +-- src/BarrelBarDetectorWithSideFrame_geo.cpp | 68 +- src/BarrelCalorimeterImaging_geo.cpp | 301 ++-- src/BarrelCalorimeterScFi_geo.cpp | 182 +-- src/BarrelFluxReturn_geo.cpp | 16 +- src/BarrelHCalCalorimeter_geo.cpp | 293 ++-- src/BarrelPlanarMPGDTracker_geo.cpp | 107 +- src/BarrelTrackerWithFrame_geo.cpp | 132 +- src/BeamPipeChain_geo.cpp | 100 +- src/CompositeTracker_geo.cpp | 22 +- src/CylindricalDipoleMagnet_geo.cpp | 34 +- src/CylindricalMagnetChain_geo.cpp | 42 +- src/DD4hepDetectorHelper.h | 12 +- src/DD4hep_GdmlDetector.cpp | 38 +- src/DIRC_geo.cpp | 203 +-- src/DRICH_geo.cpp | 315 ++-- src/EcalLumiSpecWScFi_geo.cpp | 229 +-- src/EndcapCalorimeterWithInsertCutout_geo.cpp | 76 +- src/EndcapFluxReturn_geo.cpp | 53 +- src/EndcapTOF_geo.cpp | 91 +- src/FieldMapB.cpp | 223 ++- src/FileLoader.cpp | 21 +- src/FileLoaderHelper.h | 58 +- src/ForwardRomanPot_geo.cpp | 85 +- src/GeometryHelper.cpp | 301 ++-- src/GeometryHelper.h | 57 +- src/GeometryHelpers.cpp | 386 +++-- src/GeometryHelpers.h | 32 +- src/HomogeneousCalorimeter_geo.cpp | 315 ++-- src/IP6BeamPipe.cpp | 126 +- src/InsertCalorimeter_geo.cpp | 103 +- src/LFHCAL_geo.cpp | 1377 ++++++++++------- src/LumiCollimator_geo.cpp | 35 +- src/LumiDirectPC_geo.cpp | 47 +- src/LumiMagnets_geo.cpp | 114 +- src/LumiPhotonChamber_geo.cpp | 104 +- src/LumiSpecHomoCAL_geo.cpp | 71 +- src/LumiSpecTracker_geo.cpp | 75 +- src/LumiWindow_geo.cpp | 49 +- src/MRich_geo.cpp | 224 +-- src/OffMomentumTracker_geo.cpp | 101 +- src/PFRICH_geo.cpp | 987 ++++++------ src/PolyhedraEndcapCalorimeter2_geo.cpp | 73 +- src/ScFiCalorimeter_geo.cpp | 72 +- src/SimpleDiskDetector_geo.cpp | 54 +- src/Solenoid_geo.cpp | 43 +- src/SupportServiceMaterial_geo.cpp | 146 +- src/TaggerCalWSi_geo.cpp | 35 +- src/TrapEndcapTracker_geo.cpp | 203 +-- src/ZDC_Crystal_geo.cpp | 91 +- src/ZDC_ImagingCal_geo.cpp | 53 +- src/ZDC_SamplingCal_geo.cpp | 57 +- src/ZeroDegreeCalorimeterEcalWSciFi_geo.cpp | 58 +- src/ZeroDegreeCalorimeterEcal_geo.cpp | 43 +- src/ZeroDegreeCalorimeterSampling_geo.cpp | 51 +- src/ZeroDegreeCalorimeterSiPMonTile_geo.cpp | 106 +- src/forwardBeamPipeBrazil.cpp | 1017 ++++++------ src/hadronDownstreamBeamPipe.cpp | 262 ++-- src/magnetVacuumFF.cpp | 481 +++--- 72 files changed, 5702 insertions(+), 5256 deletions(-) diff --git a/.clang-format b/.clang-format index 48164f6bb..6041e2653 100644 --- a/.clang-format +++ b/.clang-format @@ -1,111 +1,17 @@ --- -Language: Cpp -BasedOnStyle: Chromium -AccessModifierOffset: -2 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true -AlignEscapedNewlines: Right -AlignOperands: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: true - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Custom -BreakBeforeInheritanceComma: false -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 +BasedOnStyle: LLVM +BreakConstructorInitializersBeforeComma: true +ConstructorInitializerAllOnOneLineOrOnePerLine: true Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH +Standard: c++20 +#SpaceBeforeParens: ControlStatements +SpaceAfterControlStatementKeyword: true +PointerBindsToType: true IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - - Regex: '.*' - Priority: 1 -IncludeIsMainRegex: '(Test)?$' -IndentCaseLabels: false -IndentPPDirectives: None -IndentWidth: 2 -IndentWrappedFunctionNames: false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: All -ObjCBlockIndentWidth: 2 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 60 -PointerAlignment: Left -ReflowComments: true -SortIncludes: true -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -#SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 8 UseTab: Never +ColumnLimit: 100 +NamespaceIndentation: Inner +AlignConsecutiveAssignments: true +SortIncludes: Never +ReflowComments: false ... diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 140ae12d0..c0eb14386 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,4 +1,4 @@ { - "name": "eic-shell", - "image": "ghcr.io/eic/jug_xl:nightly" + "name": "eic-shell", + "image": "ghcr.io/eic/jug_xl:nightly" } diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f25a40848..812231abd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,3 @@ -ci: - skip: [clang-format] repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 @@ -7,8 +5,8 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace -- repo: https://github.com/pocc/pre-commit-hooks - rev: v1.3.5 +- repo: https://github.com/pre-commit/mirrors-clang-format + rev: v18.1.3 hooks: - id: clang-format - repo: https://github.com/Lucas-C/pre-commit-hooks diff --git a/calibrations/calo_digi_default.json b/calibrations/calo_digi_default.json index 387f1a18e..6f39a7fe6 100644 --- a/calibrations/calo_digi_default.json +++ b/calibrations/calo_digi_default.json @@ -1,66 +1,66 @@ { - "ecal_neg_endcap": { - "readout": "module", - "dynamicRange": "20*GeV", - "capacityBitsADC": 14, - "pedestalMean": 100, - "pedestalSigma": 1, - "thresholdValue": 3 - }, - "hcal_neg_endcap": { - "readout": "tile", - "dynamicRange": "20*MeV", - "capacityBitsADC": 8, - "pedestalMean": 20, - "pedestalSigma": 0.3, - "thresholdValue": 1 - }, - "ecal_pos_endcap": { - "readout": "module", - "dynamicRange": "3*GeV", - "capacityBitsADC": 14, - "pedestalMean": 100, - "pedestalSigma": 0.7, - "thresholdValue": 2 - }, - "hcal_pos_endcap": { - "readout": "tile", - "dynamicRange": "3.6*GeV", - "capacityBitsADC": 10, - "pedestalMean": 20, - "pedestalSigma": 0.8, - "thresholdValue": 3 - }, - "hcal_pos_endcap_insert": { - "readout": "tile", - "dynamicRange": "200*MeV", - "capacityBitsADC": 15, - "pedestalMean": 400, - "pedestalSigma": 10, - "thresholdValue": 0 - }, - "ecal_barrel_imaging": { - "readout": "pixel", - "dynamicRange": "3*MeV", - "capacityBitsADC": 13, - "pedestalMean": 100, - "pedestalSigma": 14, - "thresholdValue": 50 - }, - "ecal_barrel_scfi": { - "readout": "light_guide", - "dynamicRange": "750*MeV", - "capacityBitsADC": 14, - "pedestalMean": 20, - "pedestalSigma": 0.3, - "thresholdValue": 1 - }, - "hcal_barrel": { - "readout": "tile", - "dynamicRange": "20*MeV", - "capacityBitsADC": 8, - "pedestalMean": 20, - "pedestalSigma": 0.3, - "thresholdValue": 1 - } + "ecal_neg_endcap": { + "readout": "module", + "dynamicRange": "20*GeV", + "capacityBitsADC": 14, + "pedestalMean": 100, + "pedestalSigma": 1, + "thresholdValue": 3 + }, + "hcal_neg_endcap": { + "readout": "tile", + "dynamicRange": "20*MeV", + "capacityBitsADC": 8, + "pedestalMean": 20, + "pedestalSigma": 0.3, + "thresholdValue": 1 + }, + "ecal_pos_endcap": { + "readout": "module", + "dynamicRange": "3*GeV", + "capacityBitsADC": 14, + "pedestalMean": 100, + "pedestalSigma": 0.7, + "thresholdValue": 2 + }, + "hcal_pos_endcap": { + "readout": "tile", + "dynamicRange": "3.6*GeV", + "capacityBitsADC": 10, + "pedestalMean": 20, + "pedestalSigma": 0.8, + "thresholdValue": 3 + }, + "hcal_pos_endcap_insert": { + "readout": "tile", + "dynamicRange": "200*MeV", + "capacityBitsADC": 15, + "pedestalMean": 400, + "pedestalSigma": 10, + "thresholdValue": 0 + }, + "ecal_barrel_imaging": { + "readout": "pixel", + "dynamicRange": "3*MeV", + "capacityBitsADC": 13, + "pedestalMean": 100, + "pedestalSigma": 14, + "thresholdValue": 50 + }, + "ecal_barrel_scfi": { + "readout": "light_guide", + "dynamicRange": "750*MeV", + "capacityBitsADC": 14, + "pedestalMean": 20, + "pedestalSigma": 0.3, + "thresholdValue": 1 + }, + "hcal_barrel": { + "readout": "tile", + "dynamicRange": "20*MeV", + "capacityBitsADC": 8, + "pedestalMean": 20, + "pedestalSigma": 0.3, + "thresholdValue": 1 + } } diff --git a/calibrations/emcal_barrel_calibration.json b/calibrations/emcal_barrel_calibration.json index a24a048aa..8a696b9bb 100644 --- a/calibrations/emcal_barrel_calibration.json +++ b/calibrations/emcal_barrel_calibration.json @@ -1,9 +1,9 @@ { - "electron": { - "particle_name": "electron", - "sampling_fraction": 0.10856976476514045, - "sampling_fraction_img": 0.00595078393326404, - "sampling_fraction_scfi": 0.10262666247845109, - "thrown_energy": 4.975791477972636 - } + "electron": { + "particle_name": "electron", + "sampling_fraction": 0.10856976476514045, + "sampling_fraction_img": 0.00595078393326404, + "sampling_fraction_scfi": 0.10262666247845109, + "thrown_energy": 4.975791477972636 + } } diff --git a/calibrations/ffi_zdc.json b/calibrations/ffi_zdc.json index 40ba1d697..543b04599 100644 --- a/calibrations/ffi_zdc.json +++ b/calibrations/ffi_zdc.json @@ -1,16 +1,22 @@ { - "ffi_zdc_ecal": { - "sampling_fraction": 1.0, - "minClusterCenterEdep": "3.*MeV", - "minClusterHitEdep": "0.1*MeV", - "localDistXY": ["50*mm", "50*mm"], - "splitCluster": true - }, - "ffi_zdc_hcal": { - "sampling_fraction": 1.0, - "minClusterCenterEdep": "1.*MeV", - "minClusterHitEdep": "0.1*MeV", - "localDistXY": ["200*mm", "200*mm"], - "splitCluster": false - } + "ffi_zdc_ecal": { + "sampling_fraction": 1.0, + "minClusterCenterEdep": "3.*MeV", + "minClusterHitEdep": "0.1*MeV", + "localDistXY": [ + "50*mm", + "50*mm" + ], + "splitCluster": true + }, + "ffi_zdc_hcal": { + "sampling_fraction": 1.0, + "minClusterCenterEdep": "1.*MeV", + "minClusterHitEdep": "0.1*MeV", + "localDistXY": [ + "200*mm", + "200*mm" + ], + "splitCluster": false + } } diff --git a/scripts/test_ACTS.cxx b/scripts/test_ACTS.cxx index a949db76c..26416f9c4 100644 --- a/scripts/test_ACTS.cxx +++ b/scripts/test_ACTS.cxx @@ -11,8 +11,7 @@ * * */ -void test_ACTS(const char* compact = "epic.xml") -{ +void test_ACTS(const char* compact = "epic.xml") { // ------------------------- // Get the DD4hep instance // Load the compact XML file @@ -20,9 +19,9 @@ void test_ACTS(const char* compact = "epic.xml") auto detector = dd4hep::Detector::make_unique(""); detector->fromCompact(compact); - auto logger = Acts::getDefaultLogger("Acts", Acts::Logging::Level::VERBOSE); + auto logger = Acts::getDefaultLogger("Acts", Acts::Logging::Level::VERBOSE); auto acts_tracking_geometry = Acts::convertDD4hepDetector(detector->world(), *logger); // Visit all surfaces - acts_tracking_geometry->visitSurfaces([](const Acts::Surface *surface) { }); + acts_tracking_geometry->visitSurfaces([](const Acts::Surface* surface) {}); } diff --git a/src/B0ECal_geo.cpp b/src/B0ECal_geo.cpp index 6a8ad9bc4..f5c271266 100644 --- a/src/B0ECal_geo.cpp +++ b/src/B0ECal_geo.cpp @@ -22,13 +22,13 @@ using std::tuple; using std::vector; using namespace dd4hep; -static tuple build_module(Detector& desc, xml_coll_t& plm, SensitiveDetector& sens); +static tuple build_module(Detector& desc, xml_coll_t& plm, + SensitiveDetector& sens); -static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) -{ - xml_det_t x_det = e; - string detName = x_det.nameStr(); - int detID = x_det.id(); +static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + string detName = x_det.nameStr(); + int detID = x_det.id(); DetElement det(detName, detID); sens.setType("calorimeter"); @@ -39,9 +39,9 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) xml_dim_t rot = x_det.rotation(); // module placement - xml_comp_t plm = x_det.child(_Unicode(placements)); + xml_comp_t plm = x_det.child(_Unicode(placements)); map sectorModuleNumbers; - auto addModuleNumbers = [§orModuleNumbers](int sector, int nmod) { + auto addModuleNumbers = [§orModuleNumbers](int sector, int nmod) { auto it = sectorModuleNumbers.find(sector); if (it != sectorModuleNumbers.end()) { it->second += nmod; @@ -53,7 +53,8 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) int sector_id = 1; for (xml_coll_t mod(plm, _Unicode(individuals)); mod; ++mod) { - auto [sector, nmod] = ip6::geo::add_individuals(build_module, desc, detVol, mod, sens, sector_id++); + auto [sector, nmod] = + ip6::geo::add_individuals(build_module, desc, detVol, mod, sens, sector_id++); addModuleNumbers(sector, nmod); } @@ -63,8 +64,8 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) } // position and rotation of parent volume - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume detPV = motherVol.placeVolume(detVol, tr); detPV.addPhysVolID("system", detID); det.setPlacement(detPV); @@ -72,14 +73,14 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) } // helper function to build module with or w/o wrapper -static tuple build_module(Detector& desc, xml::Collection_t& plm, SensitiveDetector& sens) -{ - auto mod = plm.child(_Unicode(module)); - auto sx = mod.attr(_Unicode(sizex)); - auto sy = mod.attr(_Unicode(sizey)); - auto sz = mod.attr(_Unicode(sizez)); - Box modShape(sx / 2., sy / 2., sz / 2.); - auto modMat = desc.material(mod.attr(_Unicode(material))); +static tuple build_module(Detector& desc, xml::Collection_t& plm, + SensitiveDetector& sens) { + auto mod = plm.child(_Unicode(module)); + auto sx = mod.attr(_Unicode(sizex)); + auto sy = mod.attr(_Unicode(sizey)); + auto sz = mod.attr(_Unicode(sizez)); + Box modShape(sx / 2., sy / 2., sz / 2.); + auto modMat = desc.material(mod.attr(_Unicode(material))); Volume modVol("module_vol", modShape, modMat); modVol.setSensitiveDetector(sens); modVol.setVisAttributes(desc.visAttributes(mod.attr(_Unicode(vis)))); @@ -94,8 +95,8 @@ static tuple build_module(Detector& desc, xml::Collection_t& p if (thickness < 1e-12 * mm) { return make_tuple(modVol, Position{sx, sy, sz}); } - auto wrpMat = desc.material(wrp.attr(_Unicode(material))); - Box wrpShape((sx + thickness) / 2., (sy + thickness) / 2., sz / 2.); + auto wrpMat = desc.material(wrp.attr(_Unicode(material))); + Box wrpShape((sx + thickness) / 2., (sy + thickness) / 2., sz / 2.); Volume wrpVol("wrapper_vol", wrpShape, wrpMat); wrpVol.placeVolume(modVol, Position(0., 0., 0.)); wrpVol.setVisAttributes(desc.visAttributes(wrp.attr(_Unicode(vis)))); diff --git a/src/B0Preshower_geo.cpp b/src/B0Preshower_geo.cpp index 27f8e49a9..f85e417fd 100644 --- a/src/B0Preshower_geo.cpp +++ b/src/B0Preshower_geo.cpp @@ -14,67 +14,66 @@ using namespace dd4hep::detail; * * This geometric element has been deprecated. ACTS tracking interface has also been removed. - Sakib Rahman (Dec 20, 2022) */ -static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetector sens) { typedef vector Placements; - xml_det_t x_det = e; - Material vacuum = description.vacuum(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - bool reflect = x_det.reflect(false); - DetElement sdet(det_name, det_id); - Assembly assembly(det_name); - xml::Component pos = x_det.position(); - xml::Component rot = x_det.rotation(); + xml_det_t x_det = e; + Material vacuum = description.vacuum(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + bool reflect = x_det.reflect(false); + DetElement sdet(det_name, det_id); + Assembly assembly(det_name); + xml::Component pos = x_det.position(); + xml::Component rot = x_det.rotation(); // Material air = description.material("Air"); // Volume assembly (det_name,Box(10000,10000,10000),vacuum); - Volume motherVol = description.pickMotherVolume(sdet); - int m_id = 0, c_id = 0, n_sensor = 0; - map modules; + Volume motherVol = description.pickMotherVolume(sdet); + int m_id = 0, c_id = 0, n_sensor = 0; + map modules; map sensitives; - PlacedVolume pv; + PlacedVolume pv; assembly.setVisAttributes(description.invisible()); sens.setType("tracker"); for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) { xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); + string m_nam = x_mod.nameStr(); xml_comp_t trd = x_mod.trd(); - double posY; - double x1 = trd.x1(); - double x2 = trd.x2(); - double z = trd.z(); - double y1, y2, total_thickness = 0.; + double posY; + double x1 = trd.x1(); + double x2 = trd.x2(); + double z = trd.z(); + double y1, y2, total_thickness = 0.; xml_coll_t ci(x_mod, _U(module_component)); for (ci.reset(), total_thickness = 0.0; ci; ++ci) total_thickness += xml_comp_t(ci).thickness(); y1 = y2 = total_thickness / 2; Trapezoid m_solid(x1, x2, y1, y2, z); - Volume m_volume(m_nam, m_solid, vacuum); + Volume m_volume(m_nam, m_solid, vacuum); m_volume.setVisAttributes(description.visAttributes(x_mod.visStr())); Solid frame_s; if (x_mod.hasChild(_U(frame))) { // build frame from trd (assumed to be smaller) - xml_comp_t m_frame = x_mod.child(_U(frame)); - xml_comp_t f_pos = m_frame.child(_U(position)); - xml_comp_t frame_trd = m_frame.trd(); - double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); - double frame_x1 = frame_trd.x1(); - double frame_x2 = frame_trd.x2(); - double frame_z = frame_trd.z(); + xml_comp_t m_frame = x_mod.child(_U(frame)); + xml_comp_t f_pos = m_frame.child(_U(position)); + xml_comp_t frame_trd = m_frame.trd(); + double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); + double frame_x1 = frame_trd.x1(); + double frame_x2 = frame_trd.x2(); + double frame_z = frame_trd.z(); // make the frame match the total thickness if thickness attribute is not given - Trapezoid f_solid1(x1, x2, frame_thickness / 2.0, frame_thickness / 2.0, z); - Trapezoid f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z); + Trapezoid f_solid1(x1, x2, frame_thickness / 2.0, frame_thickness / 2.0, z); + Trapezoid f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z); SubtractionSolid frame_shape(f_solid1, f_solid); frame_s = frame_shape; Material f_mat = description.material(m_frame.materialStr()); - Volume f_vol(m_nam + "_frame", frame_shape, f_mat); + Volume f_vol(m_nam + "_frame", frame_shape, f_mat); f_vol.setVisAttributes(description.visAttributes(m_frame.visStr())); // figure out how to best place @@ -82,17 +81,17 @@ static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetecto } for (ci.reset(), n_sensor = 1, c_id = 0, posY = -y1; ci; ++ci, ++c_id) { - xml_comp_t c = ci; - double c_thick = c.thickness(); - auto comp_x1 = getAttrOrDefault(c, _Unicode(x1), x1); - auto comp_x2 = getAttrOrDefault(c, _Unicode(x2), x2); - auto comp_height = getAttrOrDefault(c, _Unicode(height), z); + xml_comp_t c = ci; + double c_thick = c.thickness(); + auto comp_x1 = getAttrOrDefault(c, _Unicode(x1), x1); + auto comp_x2 = getAttrOrDefault(c, _Unicode(x2), x2); + auto comp_height = getAttrOrDefault(c, _Unicode(height), z); - Material c_mat = description.material(c.materialStr()); - string c_name = _toString(c_id, "component%d"); + Material c_mat = description.material(c.materialStr()); + string c_name = _toString(c_id, "component%d"); Trapezoid comp_s1(comp_x1, comp_x2, c_thick / 2e0, c_thick / 2e0, comp_height); - Solid comp_shape = comp_s1; + Solid comp_shape = comp_s1; if (frame_s.isValid()) { comp_shape = SubtractionSolid(comp_s1, frame_s); } @@ -102,7 +101,8 @@ static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetecto pv = m_volume.placeVolume(c_vol, Position(0, posY + c_thick / 2, 0)); if (c.isSensitive()) { // std::cout << " adding sensitive volume" << c_name << "\n"; - sdet.check(n_sensor > 2, "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); + sdet.check(n_sensor > 2, + "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); pv.addPhysVolID("sensor", n_sensor); sens.setType("tracker"); c_vol.setSensitiveDetector(sens); @@ -116,11 +116,11 @@ static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetecto for (xml_coll_t li(x_det, _U(layer)); li; ++li) { xml_comp_t x_layer(li); - int l_id = x_layer.id(); - int mod_num = 1; + int l_id = x_layer.id(); + int mod_num = 1; - xml_comp_t l_env = x_layer.child(_U(envelope)); - string layer_name = det_name + std::string("_layer") + std::to_string(l_id); + xml_comp_t l_env = x_layer.child(_U(envelope)); + string layer_name = det_name + std::string("_layer") + std::to_string(l_id); std::string layer_vis = l_env.attr(_Unicode(vis)); // double layer_rmin = l_env.attr(_Unicode(rmin)); @@ -140,8 +140,8 @@ static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetecto PlacedVolume layer_pv; if (reflect) { - layer_pv = - assembly.placeVolume(layer_vol, Transform3D(RotationZYX(0.0, -M_PI, 0.0), Position(0, 0, -layer_center_z))); + layer_pv = assembly.placeVolume( + layer_vol, Transform3D(RotationZYX(0.0, -M_PI, 0.0), Position(0, 0, -layer_center_z))); layer_pv.addPhysVolID("barrel", 3).addPhysVolID("layer", l_id); layer_name += "_N"; } else { @@ -153,17 +153,17 @@ static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetecto layer_element.setPlacement(layer_pv); for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) { - xml_comp_t x_ring = ri; - double r = x_ring.r(); - double phi0 = x_ring.phi0(0); - double zstart = x_ring.zstart(); - double dz = x_ring.dz(0); - int nmodules = x_ring.nmodules(); - string m_nam = x_ring.moduleStr(); - Volume m_vol = modules[m_nam]; - double iphi = 2 * M_PI / nmodules; - double dphi = dd4hep::getAttrOrDefault(x_ring, _Unicode(dphi), iphi); - double phi = phi0; + xml_comp_t x_ring = ri; + double r = x_ring.r(); + double phi0 = x_ring.phi0(0); + double zstart = x_ring.zstart(); + double dz = x_ring.dz(0); + int nmodules = x_ring.nmodules(); + string m_nam = x_ring.moduleStr(); + Volume m_vol = modules[m_nam]; + double iphi = 2 * M_PI / nmodules; + double dphi = dd4hep::getAttrOrDefault(x_ring, _Unicode(dphi), iphi); + double phi = phi0; Placements& sensVols = sensitives[m_nam]; for (int k = 0; k < nmodules; ++k) { @@ -173,27 +173,25 @@ static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetecto if (!reflect) { DetElement module(layer_element, m_base + "_pos", det_id); - pv = layer_vol.placeVolume( - m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, zstart + dz))); + pv = layer_vol.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), + Position(x, y, zstart + dz))); pv.addPhysVolID("barrel", 1).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num); module.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_elt(module, sens_pv.volume().name(), mod_num); + DetElement comp_elt(module, sens_pv.volume().name(), mod_num); comp_elt.setPlacement(sens_pv); - } } else { - pv = layer_vol.placeVolume( - m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, -zstart - dz))); + pv = layer_vol.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), + Position(x, y, -zstart - dz))); pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num); DetElement r_module(layer_element, m_base + "_neg", det_id); r_module.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_elt(r_module, sens_pv.volume().name(), mod_num); + DetElement comp_elt(r_module, sens_pv.volume().name(), mod_num); comp_elt.setPlacement(sens_pv); - } } dz = -dz; @@ -202,7 +200,8 @@ static Ref_t create_B0Preshower(Detector& description, xml_h e, SensitiveDetecto } } } - Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), + Position(pos.x(), pos.y(), pos.z())); pv = motherVol.placeVolume(assembly, posAndRot); pv.addPhysVolID("system", det_id); sdet.setPlacement(pv); diff --git a/src/B0Tracker_geo.cpp b/src/B0Tracker_geo.cpp index ab175d319..ac6a3dc9d 100644 --- a/src/B0Tracker_geo.cpp +++ b/src/B0Tracker_geo.cpp @@ -22,37 +22,35 @@ using namespace dd4hep::detail; * @author Whitney Armstrong * */ -static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector sens) { typedef vector Placements; - xml_det_t x_det = e; - Material vacuum = description.vacuum(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - DetElement sdet(det_name, det_id); - Assembly assembly(det_name); + xml_det_t x_det = e; + Material vacuum = description.vacuum(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + DetElement sdet(det_name, det_id); + Assembly assembly(det_name); xml::Component pos = x_det.position(); xml::Component rot = x_det.rotation(); - Volume motherVol = description.pickMotherVolume(sdet); - int m_id = 0, c_id = 0, n_sensor = 0; + Volume motherVol = description.pickMotherVolume(sdet); + int m_id = 0, c_id = 0, n_sensor = 0; PlacedVolume pv; - map modules; - map sensitives; + map modules; + map sensitives; map> volplane_surfaces; map> module_thicknesses; // Set detector type flag dd4hep::xml::setDetectorTypeFlag(x_det, sdet); - auto ¶ms = DD4hepDetectorHelper::ensureExtension( - sdet); + auto& params = DD4hepDetectorHelper::ensureExtension(sdet); // Add the volume boundary material if configured for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) { xml_comp_t x_boundary_material = bmat; DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, - "boundary_material"); + "boundary_material"); } assembly.setVisAttributes(description.invisible()); @@ -60,41 +58,41 @@ static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) { xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); + string m_nam = x_mod.nameStr(); xml_comp_t trd = x_mod.trd(); - double posY; - double x1 = trd.x1(); - double x2 = trd.x2(); - double z = trd.z(); - double y1, y2, total_thickness = 0.; + double posY; + double x1 = trd.x1(); + double x2 = trd.x2(); + double z = trd.z(); + double y1, y2, total_thickness = 0.; xml_coll_t ci(x_mod, _U(module_component)); for (ci.reset(), total_thickness = 0.0; ci; ++ci) total_thickness += xml_comp_t(ci).thickness(); y1 = y2 = total_thickness / 2; Trapezoid m_solid(x1, x2, y1, y2, z); - Volume m_volume(m_nam, m_solid, vacuum); + Volume m_volume(m_nam, m_solid, vacuum); m_volume.setVisAttributes(description.visAttributes(x_mod.visStr())); Solid frame_s; if (x_mod.hasChild(_U(frame))) { // build frame from trd (assumed to be smaller) - xml_comp_t m_frame = x_mod.child(_U(frame)); - xml_comp_t f_pos = m_frame.child(_U(position)); - xml_comp_t frame_trd = m_frame.trd(); - double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); - double frame_x1 = frame_trd.x1(); - double frame_x2 = frame_trd.x2(); - double frame_z = frame_trd.z(); + xml_comp_t m_frame = x_mod.child(_U(frame)); + xml_comp_t f_pos = m_frame.child(_U(position)); + xml_comp_t frame_trd = m_frame.trd(); + double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); + double frame_x1 = frame_trd.x1(); + double frame_x2 = frame_trd.x2(); + double frame_z = frame_trd.z(); // make the frame match the total thickness if thickness attribute is not given - Trapezoid f_solid1(x1, x2, frame_thickness / 2.0, frame_thickness / 2.0, z); - Trapezoid f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z); + Trapezoid f_solid1(x1, x2, frame_thickness / 2.0, frame_thickness / 2.0, z); + Trapezoid f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z); SubtractionSolid frame_shape(f_solid1, f_solid); frame_s = frame_shape; Material f_mat = description.material(m_frame.materialStr()); - Volume f_vol(m_nam + "_frame", frame_shape, f_mat); + Volume f_vol(m_nam + "_frame", frame_shape, f_mat); // f_vol.setVisAttributes(description.visAttributes(m_frame.visStr())); // figure out how to best place @@ -103,17 +101,17 @@ static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector double thickness_so_far = 0.0; for (ci.reset(), n_sensor = 1, c_id = 0, posY = -y1; ci; ++ci, ++c_id) { - xml_comp_t c = ci; - double c_thick = c.thickness(); - auto comp_x1 = getAttrOrDefault(c, _Unicode(x1), x1); - auto comp_x2 = getAttrOrDefault(c, _Unicode(x2), x2); - auto comp_height = getAttrOrDefault(c, _Unicode(height), z); + xml_comp_t c = ci; + double c_thick = c.thickness(); + auto comp_x1 = getAttrOrDefault(c, _Unicode(x1), x1); + auto comp_x2 = getAttrOrDefault(c, _Unicode(x2), x2); + auto comp_height = getAttrOrDefault(c, _Unicode(height), z); - Material c_mat = description.material(c.materialStr()); - string c_name = _toString(c_id, "component%d"); + Material c_mat = description.material(c.materialStr()); + string c_name = _toString(c_id, "component%d"); Trapezoid comp_s1(comp_x1, comp_x2, c_thick / 2e0, c_thick / 2e0, comp_height); - Solid comp_shape = comp_s1; + Solid comp_shape = comp_s1; if (frame_s.isValid()) { comp_shape = SubtractionSolid(comp_s1, frame_s); } @@ -123,7 +121,8 @@ static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector pv = m_volume.placeVolume(c_vol, Position(0, posY + c_thick / 2, 0)); if (c.isSensitive()) { // std::cout << " adding sensitive volume" << c_name << "\n"; - sdet.check(n_sensor > 2, "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); + sdet.check(n_sensor > 2, + "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); pv.addPhysVolID("sensor", n_sensor); c_vol.setSensitiveDetector(sens); sensitives[m_nam].push_back(pv); @@ -158,20 +157,20 @@ static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector for (xml_coll_t li(x_det, _U(layer)); li; ++li) { xml_comp_t x_layer(li); - int l_id = x_layer.id(); - int mod_num = 1; - - xml_comp_t l_env = x_layer.child(_U(envelope)); - string layer_name = det_name + std::string("_layer") + std::to_string(l_id); - - std::string layer_vis = l_env.attr(_Unicode(vis)); - double layer_rmin_tolerance = l_env.attr(_Unicode(rmin_tolerance)); - double layer_rmax_tolerance = l_env.attr(_Unicode(rmax_tolerance)); - double layer_zmin_tolerance = l_env.attr(_Unicode(zmin_tolerance)); - double layer_zmax_tolerance = l_env.attr(_Unicode(zmax_tolerance)); - double layer_length = l_env.attr(_Unicode(length)); - double layer_zstart = l_env.attr(_Unicode(zstart)); - double layer_center_z = layer_zstart + layer_length / 2.0; + int l_id = x_layer.id(); + int mod_num = 1; + + xml_comp_t l_env = x_layer.child(_U(envelope)); + string layer_name = det_name + std::string("_layer") + std::to_string(l_id); + + std::string layer_vis = l_env.attr(_Unicode(vis)); + double layer_rmin_tolerance = l_env.attr(_Unicode(rmin_tolerance)); + double layer_rmax_tolerance = l_env.attr(_Unicode(rmax_tolerance)); + double layer_zmin_tolerance = l_env.attr(_Unicode(zmin_tolerance)); + double layer_zmax_tolerance = l_env.attr(_Unicode(zmax_tolerance)); + double layer_length = l_env.attr(_Unicode(length)); + double layer_zstart = l_env.attr(_Unicode(zstart)); + double layer_center_z = layer_zstart + layer_length / 2.0; // printout(INFO,"ROOTGDMLParse","+++ Read geometry from GDML file file:%s",input.c_str()); // std::cout << "SiTracker Endcap layer " << l_id << " zstart = " << layer_zstart/dd4hep::mm << "mm ( " << // layer_length/dd4hep::mm << " mm thick )\n"; @@ -184,22 +183,21 @@ static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector DetElement layer_element(sdet, layer_name, l_id); layer_element.setPlacement(layer_pv); - auto &layerParams = - DD4hepDetectorHelper::ensureExtension( - layer_element); + auto& layerParams = + DD4hepDetectorHelper::ensureExtension(layer_element); for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) { - xml_comp_t x_ring = ri; - double r = x_ring.r(); - double phi0 = x_ring.phi0(0); - double zstart = x_ring.zstart(); - double dz = x_ring.dz(0); - int nmodules = x_ring.nmodules(); - string m_nam = x_ring.moduleStr(); - Volume m_vol = modules[m_nam]; - double iphi = 2 * M_PI / nmodules; - double dphi = dd4hep::getAttrOrDefault(x_ring, _Unicode(dphi), iphi); - double phi = phi0; + xml_comp_t x_ring = ri; + double r = x_ring.r(); + double phi0 = x_ring.phi0(0); + double zstart = x_ring.zstart(); + double dz = x_ring.dz(0); + int nmodules = x_ring.nmodules(); + string m_nam = x_ring.moduleStr(); + Volume m_vol = modules[m_nam]; + double iphi = 2 * M_PI / nmodules; + double dphi = dd4hep::getAttrOrDefault(x_ring, _Unicode(dphi), iphi); + double phi = phi0; Placements& sensVols = sensitives[m_nam]; for (int k = 0; k < nmodules; ++k) { @@ -209,15 +207,16 @@ static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector // if (!reflect) { DetElement module(layer_element, m_base + "_pos", det_id); - pv = layer_vol.placeVolume( - m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, zstart + dz))); + pv = layer_vol.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), + Position(x, y, zstart + dz))); pv.addPhysVolID("layer", l_id).addPhysVolID("module", mod_num); module.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_elt(module, sens_pv.volume().name(), mod_num); + DetElement comp_elt(module, sens_pv.volume().name(), mod_num); comp_elt.setPlacement(sens_pv); - auto &comp_elt_params = DD4hepDetectorHelper::ensureExtension(comp_elt); + auto& comp_elt_params = + DD4hepDetectorHelper::ensureExtension(comp_elt); comp_elt_params.set("axis_definitions", "XZY"); volSurfaceList(comp_elt)->push_back(volplane_surfaces[m_nam][ic]); } @@ -227,17 +226,19 @@ static Ref_t create_B0Tracker(Detector& description, xml_h e, SensitiveDetector } } layer_vol->GetShape()->ComputeBBox(); - layerParams.set("envelope_r_min", layer_rmin_tolerance/dd4hep::mm); - layerParams.set("envelope_r_max", layer_rmax_tolerance/dd4hep::mm); - layerParams.set("envelope_z_min", layer_zmin_tolerance/dd4hep::mm); - layerParams.set("envelope_z_max", layer_zmax_tolerance/dd4hep::mm); + layerParams.set("envelope_r_min", layer_rmin_tolerance / dd4hep::mm); + layerParams.set("envelope_r_max", layer_rmax_tolerance / dd4hep::mm); + layerParams.set("envelope_z_min", layer_zmin_tolerance / dd4hep::mm); + layerParams.set("envelope_z_max", layer_zmax_tolerance / dd4hep::mm); for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) { xml_comp_t x_layer_material = lmat; - DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, "layer_material"); + DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, + "layer_material"); } } - Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), + Position(pos.x(), pos.y(), pos.z())); pv = motherVol.placeVolume(assembly, posAndRot); pv.addPhysVolID("system", det_id); sdet.setPlacement(pv); diff --git a/src/BackwardsBeamPipe_geo.cpp b/src/BackwardsBeamPipe_geo.cpp index 54d12bfcb..127aa1c7d 100644 --- a/src/BackwardsBeamPipe_geo.cpp +++ b/src/BackwardsBeamPipe_geo.cpp @@ -20,26 +20,27 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) { using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Al = det.material("Aluminum"); - Material m_Vacuum = det.material("Vacuum"); - string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "BeamPipeVis"); + Assembly assembly(det_name + "_assembly"); + Material m_Al = det.material("Aluminum"); + Material m_Vacuum = det.material("Vacuum"); + string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "BeamPipeVis"); xml::Component Pipe_c = x_det.child(_Unicode(Pipe)); // Get pipe dimensions from xml double thickness = Pipe_c.attr(_Unicode(wall_thickness)); - double innerD1 = Pipe_c.hasAttr(_Unicode(innerD1)) ? Pipe_c.attr(_Unicode(innerD1)) - : Pipe_c.attr(_Unicode(outerD1)) - 2 * thickness; - double innerD2 = Pipe_c.hasAttr(_Unicode(innerD2)) ? Pipe_c.attr(_Unicode(innerD2)) - : Pipe_c.attr(_Unicode(outerD2)) - 2 * thickness; + double innerD1 = Pipe_c.hasAttr(_Unicode(innerD1)) + ? Pipe_c.attr(_Unicode(innerD1)) + : Pipe_c.attr(_Unicode(outerD1)) - 2 * thickness; + double innerD2 = Pipe_c.hasAttr(_Unicode(innerD2)) + ? Pipe_c.attr(_Unicode(innerD2)) + : Pipe_c.attr(_Unicode(outerD2)) - 2 * thickness; double end1z = Pipe_c.attr(_Unicode(end1z)); double end2z = Pipe_c.attr(_Unicode(end2z)); @@ -65,8 +66,8 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * // ----------------------------- // final placement - auto pv_assembly = - det.pickMotherVolume(sdet).placeVolume(assembly, Transform3D(RotationY(yrot), Position(end1x, 0.0, end1z))); + auto pv_assembly = det.pickMotherVolume(sdet).placeVolume( + assembly, Transform3D(RotationY(yrot), Position(end1x, 0.0, end1z))); pv_assembly.addPhysVolID("system", sdet.id()).addPhysVolID("barrel", 1); sdet.setPlacement(pv_assembly); assembly->GetShape()->ComputeBBox(); diff --git a/src/BackwardsCollimator.cpp b/src/BackwardsCollimator.cpp index d511e5cdc..d86a3aea0 100644 --- a/src/BackwardsCollimator.cpp +++ b/src/BackwardsCollimator.cpp @@ -31,30 +31,29 @@ using namespace dd4hep; * \endcode * */ -static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) { using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Steel = det.material("StainlessSteel"); - Material m_Vacuum = det.material("Vacuum"); - string vis_name = x_det.visStr(); + Assembly assembly(det_name + "_assembly"); + Material m_Steel = det.material("StainlessSteel"); + Material m_Vacuum = det.material("Vacuum"); + string vis_name = x_det.visStr(); xml::Component box_dim = x_det.child(_Unicode(dimensions)); - double height = box_dim.attr(_Unicode(height)); - double width = box_dim.attr(_Unicode(width)); - double depth = box_dim.attr(_Unicode(depth)); + double height = box_dim.attr(_Unicode(height)); + double width = box_dim.attr(_Unicode(width)); + double depth = box_dim.attr(_Unicode(depth)); - xml::Component col_XS = x_det.child(_Unicode(collimator)); - double colHeight = col_XS.attr(_Unicode(height)); - double colWidth = col_XS.attr(_Unicode(width)); - double colXOff = col_XS.attr(_Unicode(xOff)); + xml::Component col_XS = x_det.child(_Unicode(collimator)); + double colHeight = col_XS.attr(_Unicode(height)); + double colWidth = col_XS.attr(_Unicode(width)); + double colXOff = col_XS.attr(_Unicode(xOff)); xml::Component box_place = x_det.child(_Unicode(placement)); - double zOff = box_place.attr(_Unicode(z)); + double zOff = box_place.attr(_Unicode(z)); Box box_steel(width, height, depth); Box box_vacuum(colWidth, colHeight, depth); diff --git a/src/BackwardsLumiVac_geo.cpp b/src/BackwardsLumiVac_geo.cpp index e5d4974ff..fd89fa2fd 100644 --- a/src/BackwardsLumiVac_geo.cpp +++ b/src/BackwardsLumiVac_geo.cpp @@ -9,8 +9,7 @@ using namespace std; using namespace dd4hep; -static Ref_t createDetector(Detector& lccdd, xml_h e, SensitiveDetector /*sens*/) -{ +static Ref_t createDetector(Detector& lccdd, xml_h e, SensitiveDetector /*sens*/) { xml_det_t x_det = e; @@ -74,7 +73,7 @@ static Ref_t createDetector(Detector& lccdd, xml_h e, SensitiveDetector /*sens*/ DetElement det(x_det.nameStr(), x_det.id()); - Transform3D pos(RotationZYX(0, 0, 0), Position(0, 0, zcen)); + Transform3D pos(RotationZYX(0, 0, 0), Position(0, 0, zcen)); PlacedVolume pv = lccdd.pickMotherVolume(det).placeVolume(vol, pos); det.setPlacement(pv); diff --git a/src/BackwardsTaggers_geo.cpp b/src/BackwardsTaggers_geo.cpp index f10f53886..96745409d 100644 --- a/src/BackwardsTaggers_geo.cpp +++ b/src/BackwardsTaggers_geo.cpp @@ -7,7 +7,6 @@ #include "DDRec/DetectorData.h" #include "DDRec/Surface.h" - ////////////////////////////////////////////////// // Far backwards vacuum drift volume // Low Q2 tagger trackers placed either in or out of vacuum @@ -18,36 +17,35 @@ using namespace dd4hep; using namespace dd4hep::rec; // Helper function to make the tagger tracker detectors -static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetElement modElement, SensitiveDetector& sens); - +static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetElement modElement, + SensitiveDetector& sens); -static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) { - xml_det_t x_det = e; - string detName = x_det.nameStr(); - int detID = x_det.id(); + xml_det_t x_det = e; + string detName = x_det.nameStr(); + int detID = x_det.id(); DetElement det(detName, detID); string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "BackwardsBox"); // Dimensions of main beamline pipe - xml::Component dim = x_det.child(_Unicode(dimensions)); - double WidthL = dim.attr(_Unicode(xL)); - double WidthR = dim.attr(_Unicode(xR)); + xml::Component dim = x_det.child(_Unicode(dimensions)); + double WidthL = dim.attr(_Unicode(xL)); + double WidthR = dim.attr(_Unicode(xR)); double Width = (WidthL + WidthR) / 2; double Height = dim.y(); double Thickness = dim.z(); // Materials - Material Vacuum = desc.material("Vacuum"); - Material Steel = desc.material("StainlessSteel"); + Material Vacuum = desc.material("Vacuum"); + Material Steel = desc.material("StainlessSteel"); // Central focal point of the geometry xml::Component pos = x_det.child(_Unicode(focus)); - double off = pos.z(); + double off = pos.z(); // Beamline rotation xml_dim_t rot = x_det.rotation(); @@ -56,13 +54,13 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) double wall = dd4hep::getAttrOrDefault(x_det, _Unicode(wall), 1 * mm); // Make bounding box to make IntersectionSolid with other components - xml::Component BB = x_det.child(_Unicode(bounding)); - double BB_MinX = BB.xmin(); - double BB_MinY = BB.ymin(); - double BB_MinZ = BB.zmin(); - double BB_MaxX = BB.xmax(); - double BB_MaxY = BB.ymax(); - double BB_MaxZ = BB.zmax(); + xml::Component BB = x_det.child(_Unicode(bounding)); + double BB_MinX = BB.xmin(); + double BB_MinY = BB.ymin(); + double BB_MinZ = BB.zmin(); + double BB_MaxX = BB.xmax(); + double BB_MaxY = BB.ymax(); + double BB_MaxZ = BB.zmax(); double BB_X = abs(BB_MaxX - BB_MinX); double BB_Y = abs(BB_MaxY - BB_MinY); @@ -71,11 +69,11 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) Box Far_Backwards_Box(BB_X, BB_Y, BB_Z); // Entry box geometry description joining magnet, taggers and lumi - xml::Component EB = x_det.child(_Unicode(exitdim)); - double ED_X = EB.x(); - double ED_Y = EB.y(); - double ED_Z = off - EB.attr(_Unicode(lumiZ)); - double Lumi_R = EB.attr(_Unicode(lumiR)); + xml::Component EB = x_det.child(_Unicode(exitdim)); + double ED_X = EB.x(); + double ED_Y = EB.y(); + double ED_Z = off - EB.attr(_Unicode(lumiZ)); + double Lumi_R = EB.attr(_Unicode(lumiR)); // Maximum theta to exit the dipole from double exitTheta = EB.attr(_Unicode(maxTheta)); @@ -100,26 +98,28 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) Assembly DetAssembly("Tagger_vacuum_assembly"); Assembly DetAssemblyAir("Tagger_air_assembly"); - int nVacuum = 0; - int nAir = 0; + int nVacuum = 0; + int nAir = 0; //----------------------------------------------------------------- // Add Tagger box containers and vacuum box extension for modules //----------------------------------------------------------------- for (xml_coll_t mod(x_det, _Unicode(module)); mod; ++mod) { - int moduleID = dd4hep::getAttrOrDefault(mod, _Unicode(id), 0); + int moduleID = dd4hep::getAttrOrDefault(mod, _Unicode(id), 0); string moduleName = dd4hep::getAttrOrDefault(mod, _Unicode(name), "Tagger0"); // Offset from the electron beam - double tagoff = dd4hep::getAttrOrDefault(mod, _Unicode(offset_min), 50.0 * mm); + double tagoff = dd4hep::getAttrOrDefault(mod, _Unicode(offset_min), 50.0 * mm); // Overlap left beyond theta setting double overlap = dd4hep::getAttrOrDefault(mod, _Unicode(overlap), 0.0 * mm); // Theta coverage expected - double thetamin = dd4hep::getAttrOrDefault(mod, _Unicode(theta_min), 0.030 * rad) - rot.theta(); - double thetamax = dd4hep::getAttrOrDefault(mod, _Unicode(theta_max), 0.030 * rad) - rot.theta(); + double thetamin = + dd4hep::getAttrOrDefault(mod, _Unicode(theta_min), 0.030 * rad) - rot.theta(); + double thetamax = + dd4hep::getAttrOrDefault(mod, _Unicode(theta_max), 0.030 * rad) - rot.theta(); // Align box to max or minimum theta expected at the tagger from focal point bool max_align = dd4hep::getAttrOrDefault(mod, _Unicode(max_align), false); @@ -128,10 +128,10 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) bool extend_vacuum = dd4hep::getAttrOrDefault(mod, _Unicode(extend_vacuum), true); // Size f the actual tagger box, replicated in BackwardsTagger - xml_dim_t moddim = mod.child(_Unicode(dimensions)); - double w = moddim.x(); - double h = moddim.y(); - double tagboxL = moddim.z(); + xml_dim_t moddim = mod.child(_Unicode(dimensions)); + double w = moddim.x(); + double h = moddim.y(); + double tagboxL = moddim.z(); // Width and height of vacuum volume auto vac_w = w; @@ -142,8 +142,7 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) auto box_h = h + wall; // Angle in relation to the main beam - auto theta = thetamin; - + auto theta = thetamin; auto offsetx = -(box_w - wall) * (cos(theta)); auto offsetz = (box_w - wall) * (sin(theta)); @@ -151,18 +150,18 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) auto vacoffsetz = vac_w * (sin(theta)); auto l = (tagoff) / (sin(theta)) + tagboxL; - auto tagoffsetx = vacoffsetx - (l) * sin(theta); - auto tagoffsetz = vacoffsetz - (l) * cos(theta); + auto tagoffsetx = vacoffsetx - (l)*sin(theta); + auto tagoffsetz = vacoffsetz - (l)*cos(theta); if (max_align) { theta = thetamax; - offsetx = (overlap+box_w - wall) * (cos(theta)); - offsetz = -(overlap+box_w - wall) * (sin(theta)); - vacoffsetx = (overlap+vac_w) * (cos(theta)); - vacoffsetz = -(overlap+vac_w) * (sin(theta)); + offsetx = (overlap + box_w - wall) * (cos(theta)); + offsetz = -(overlap + box_w - wall) * (sin(theta)); + vacoffsetx = (overlap + vac_w) * (cos(theta)); + vacoffsetz = -(overlap + vac_w) * (sin(theta)); l = (2 * offsetx + tagoff) / sin(theta); - tagoffsetx = vacoffsetx - (l) * sin(theta); - tagoffsetz = vacoffsetz - (l) * cos(theta); + tagoffsetx = vacoffsetx - (l)*sin(theta); + tagoffsetz = vacoffsetz - (l)*cos(theta); } Box TagWallBox(box_w, box_h, l + wall); @@ -173,8 +172,10 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) Volume mother = DetAssemblyAir; if (extend_vacuum) { - Wall_Box = UnionSolid(Wall_Box, TagWallBox, Transform3D(rotate, Position(offsetx, 0, offsetz))); - Vacuum_Box = UnionSolid(Vacuum_Box, TagVacBox, Transform3D(rotate, Position(vacoffsetx, 0, vacoffsetz))); + Wall_Box = + UnionSolid(Wall_Box, TagWallBox, Transform3D(rotate, Position(offsetx, 0, offsetz))); + Vacuum_Box = UnionSolid(Vacuum_Box, TagVacBox, + Transform3D(rotate, Position(vacoffsetx, 0, vacoffsetz))); mother = DetAssembly; nVacuum++; } else { @@ -185,14 +186,16 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) PlacedVolume pv_mod2 = mother.placeVolume( TaggerAssembly, - Transform3D(rotate, Position(tagoffsetx, 0, - tagoffsetz))); // Very strange y is not centered and offset needs correcting for... - DetElement moddet(det,moduleName, moduleID); + Transform3D( + rotate, + Position( + tagoffsetx, 0, + tagoffsetz))); // Very strange y is not centered and offset needs correcting for... + DetElement moddet(det, moduleName, moduleID); pv_mod2.addPhysVolID("module", moduleID); moddet.setPlacement(pv_mod2); Make_Tagger(desc, mod, TaggerAssembly, moddet, sens); - } //----------------------------------------------------------------- @@ -230,23 +233,27 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) //----------------------------------------------------------------- double exitDist = BB_MinZ - off; double cutX = (ED_X - exitDist * tan(-rot.theta())) * cos(rot.theta()); - double cutZ = (ED_X - exitDist * tan(-rot.theta())) * sin(rot.theta()) + exitDist * cos(rot.theta()); + double cutZ = + (ED_X - exitDist * tan(-rot.theta())) * sin(rot.theta()) + exitDist * cos(rot.theta()); double cutXwall = (ED_X - wall - exitDist * tan(-rot.theta())) * cos(rot.theta()); - double cutZwall = (ED_X - wall - exitDist * tan(-rot.theta())) * sin(rot.theta()) + exitDist * cos(rot.theta()); + double cutZwall = + (ED_X - wall - exitDist * tan(-rot.theta())) * sin(rot.theta()) + exitDist * cos(rot.theta()); - Wall_Box = IntersectionSolid(Wall_Box, Cut_Box, Transform3D(RotationY(exitTheta), Position(xbox - cutX, 0, cutZ))); + Wall_Box = IntersectionSolid(Wall_Box, Cut_Box, + Transform3D(RotationY(exitTheta), Position(xbox - cutX, 0, cutZ))); Vacuum_Box = - IntersectionSolid(Vacuum_Box, Cut_Box, Transform3D(RotationY(exitTheta), Position(xbox - cutXwall, 0, cutZwall))); + IntersectionSolid(Vacuum_Box, Cut_Box, + Transform3D(RotationY(exitTheta), Position(xbox - cutXwall, 0, cutZwall))); //----------------------------------------------------------------- // Cut solids so they are only in the far backwards box //----------------------------------------------------------------- RotationY rotate2(-rot.theta()); - Position position(0, 0, (exitDist - BB_Z) / cos(rot.theta())); + Position position(0, 0, (exitDist - BB_Z) / cos(rot.theta())); IntersectionSolid Wall_Box_Sub(Wall_Box, Far_Backwards_Box, Transform3D(rotate2, position)); IntersectionSolid Vacuum_Box_Sub(Vacuum_Box, Far_Backwards_Box, Transform3D(rotate2, position)); - SubtractionSolid Wall_Box_Out(Wall_Box_Sub, Vacuum_Box_Sub); + SubtractionSolid Wall_Box_Out(Wall_Box_Sub, Vacuum_Box_Sub); Volume vacVol("TaggerStation_Vacuum", Vacuum_Box_Sub, Vacuum); vacVol.setVisAttributes(desc.visAttributes("BackwardsVac")); @@ -264,28 +271,27 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) backAssembly.placeVolume(DetAssemblyAir); // placement in mother volume - Transform3D tr(RotationY(rot.theta()), Position(pos.x(), pos.y(), pos.z())); + Transform3D tr(RotationY(rot.theta()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume detPV = desc.pickMotherVolume(det).placeVolume(backAssembly, tr); detPV.addPhysVolID("system", detID); det.setPlacement(detPV); - return det; } -static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetElement modElement, SensitiveDetector& sens) -{ +static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetElement modElement, + SensitiveDetector& sens) { sens.setType("tracker"); Material Air = desc.material("Air"); Material Silicon = desc.material("Silicon"); - xml_dim_t moddim = mod.child(_Unicode(dimensions)); - double tag_w = moddim.x(); - double tag_h = moddim.y(); - double tagboxL = moddim.z(); + xml_dim_t moddim = mod.child(_Unicode(dimensions)); + double tag_w = moddim.x(); + double tag_h = moddim.y(); + double tagboxL = moddim.z(); Volume Tagger_Air; @@ -295,12 +301,14 @@ static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetEleme // Add window layer and air-vacuum boxes for (xml_coll_t lay(mod, _Unicode(foilLayer)); lay; ++lay) { - string layerType = dd4hep::getAttrOrDefault(lay, _Unicode(type), "foil"); - string layerVis = dd4hep::getAttrOrDefault(lay, _Unicode(vis), "FFTrackerShieldingVis"); - double layerZ = dd4hep::getAttrOrDefault(lay, _Unicode(z), 0 * mm); - double layerRot = dd4hep::getAttrOrDefault(lay, _Unicode(angle), 45*deg); - double layerThickness = dd4hep::getAttrOrDefault(lay, _Unicode(sensor_thickness), 100 * um); - string layerMaterial = dd4hep::getAttrOrDefault(lay, _Unicode(material), "Copper"); + string layerType = dd4hep::getAttrOrDefault(lay, _Unicode(type), "foil"); + string layerVis = + dd4hep::getAttrOrDefault(lay, _Unicode(vis), "FFTrackerShieldingVis"); + double layerZ = dd4hep::getAttrOrDefault(lay, _Unicode(z), 0 * mm); + double layerRot = dd4hep::getAttrOrDefault(lay, _Unicode(angle), 45 * deg); + double layerThickness = + dd4hep::getAttrOrDefault(lay, _Unicode(sensor_thickness), 100 * um); + string layerMaterial = dd4hep::getAttrOrDefault(lay, _Unicode(material), "Copper"); Material FoilMaterial = desc.material(layerMaterial); @@ -313,11 +321,12 @@ static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetEleme Tagger_Air = Volume("AirVolume", Box_Air, Air); Tagger_Air.setVisAttributes(desc.visAttributes("BackwardsAir")); - Box Foil_Box(tag_w/cos(layerRot)-0.5*layerThickness*tan(layerRot), tag_h, layerThickness / 2); + Box Foil_Box(tag_w / cos(layerRot) - 0.5 * layerThickness * tan(layerRot), tag_h, + layerThickness / 2); Volume layVol("FoilVolume", Foil_Box, FoilMaterial); layVol.setVisAttributes(desc.visAttributes(layerVis)); - env.placeVolume(layVol, Transform3D(rotate,Position(0, 0, tagboxL+tag_w*tan(layerRot)))); + env.placeVolume(layVol, Transform3D(rotate, Position(0, 0, tagboxL + tag_w * tan(layerRot)))); // Currently only one "foil" layer implemented break; @@ -326,12 +335,14 @@ static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetEleme // Add window layer and air-vacuum boxes for (xml_coll_t lay(mod, _Unicode(windowLayer)); lay; ++lay) { - string layerType = dd4hep::getAttrOrDefault(lay, _Unicode(type), "window"); - string layerVis = dd4hep::getAttrOrDefault(lay, _Unicode(vis), "FFTrackerShieldingVis"); - double layerZ = dd4hep::getAttrOrDefault(lay, _Unicode(z), 0 * mm); - double layerRot = dd4hep::getAttrOrDefault(lay, _Unicode(angle), 0); - double layerThickness = dd4hep::getAttrOrDefault(lay, _Unicode(sensor_thickness), 1 * mm); - string layerMaterial = dd4hep::getAttrOrDefault(lay, _Unicode(material), "Copper"); + string layerType = dd4hep::getAttrOrDefault(lay, _Unicode(type), "window"); + string layerVis = + dd4hep::getAttrOrDefault(lay, _Unicode(vis), "FFTrackerShieldingVis"); + double layerZ = dd4hep::getAttrOrDefault(lay, _Unicode(z), 0 * mm); + double layerRot = dd4hep::getAttrOrDefault(lay, _Unicode(angle), 0); + double layerThickness = + dd4hep::getAttrOrDefault(lay, _Unicode(sensor_thickness), 1 * mm); + string layerMaterial = dd4hep::getAttrOrDefault(lay, _Unicode(material), "Copper"); Material WindowMaterial = desc.material(layerMaterial); @@ -344,7 +355,7 @@ static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetEleme Tagger_Air = Volume("AirVolume", Box_Air, Air); Tagger_Air.setVisAttributes(desc.visAttributes("BackwardsAir")); - Box Window_Box(tag_w, tag_h, layerThickness / 2); + Box Window_Box(tag_w, tag_h, layerThickness / 2); Volume layVol("WindowVolume", Window_Box, WindowMaterial); layVol.setVisAttributes(desc.visAttributes(layerVis)); @@ -360,12 +371,14 @@ static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetEleme int N_layers = 0; for (xml_coll_t lay(mod, _Unicode(trackLayer)); lay; ++lay, ++N_layers) { - int layerID = dd4hep::getAttrOrDefault(lay, _Unicode(id), 0); - string layerType = dd4hep::getAttrOrDefault(lay, _Unicode(type), "timepix"); - string layerVis = dd4hep::getAttrOrDefault(lay, _Unicode(vis), "FFTrackerLayerVis"); - double layerRot = dd4hep::getAttrOrDefault(lay, _Unicode(angle), 0); - double layerZ = dd4hep::getAttrOrDefault(lay, _Unicode(z), 0 * mm); - double layerThickness = dd4hep::getAttrOrDefault(lay, _Unicode(sensor_thickness), 200 * um); + int layerID = dd4hep::getAttrOrDefault(lay, _Unicode(id), 0); + string layerType = dd4hep::getAttrOrDefault(lay, _Unicode(type), "timepix"); + string layerVis = + dd4hep::getAttrOrDefault(lay, _Unicode(vis), "FFTrackerLayerVis"); + double layerRot = dd4hep::getAttrOrDefault(lay, _Unicode(angle), 0); + double layerZ = dd4hep::getAttrOrDefault(lay, _Unicode(z), 0 * mm); + double layerThickness = + dd4hep::getAttrOrDefault(lay, _Unicode(sensor_thickness), 200 * um); Volume mother = env; double MotherThickness = tagboxL; @@ -378,19 +391,17 @@ static void Make_Tagger(Detector& desc, xml_coll_t& mod, Assembly& env, DetEleme MotherThickness = airThickness / 2; } - Box Layer_Box(tag_w, tag_h, layerThickness / 2); + Box Layer_Box(tag_w, tag_h, layerThickness / 2); Volume layVol("Tagger_tracker_layer", Layer_Box, Silicon); layVol.setSensitiveDetector(sens); layVol.setVisAttributes(desc.visAttributes(layerVis)); - - PlacedVolume pv_layer = mother.placeVolume(layVol, Transform3D(rotate, Position(0, 0, MotherThickness - layerZ + layerThickness / 2))); + PlacedVolume pv_layer = mother.placeVolume( + layVol, Transform3D(rotate, Position(0, 0, MotherThickness - layerZ + layerThickness / 2))); pv_layer.addPhysVolID("layer", layerID); - DetElement laydet(modElement,"layerName"+std::to_string(layerID), layerID); + DetElement laydet(modElement, "layerName" + std::to_string(layerID), layerID); laydet.setPlacement(pv_layer); - - } } diff --git a/src/BarrelBarDetectorWithSideFrame_geo.cpp b/src/BarrelBarDetectorWithSideFrame_geo.cpp index aaf60b42a..61c3c634e 100644 --- a/src/BarrelBarDetectorWithSideFrame_geo.cpp +++ b/src/BarrelBarDetectorWithSideFrame_geo.cpp @@ -32,24 +32,24 @@ using namespace dd4hep; * for e.g. the DIRC * */ -static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h e, SensitiveDetector sens) -{ - typedef vector Placements; - xml_det_t x_det = e; - Material air = description.air(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - DetElement sdet(det_name, det_id); - map volumes; - map sensitives; +static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h e, + SensitiveDetector sens) { + typedef vector Placements; + xml_det_t x_det = e; + Material air = description.air(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + DetElement sdet(det_name, det_id); + map volumes; + map sensitives; map> volplane_surfaces; - PlacedVolume pv; - dd4hep::xml::Dimension dimensions(x_det.dimensions()); - xml_dim_t dirc_pos = x_det.position(); + PlacedVolume pv; + dd4hep::xml::Dimension dimensions(x_det.dimensions()); + xml_dim_t dirc_pos = x_det.position(); map> module_thicknesses; - Tube topVolumeShape(dimensions.rmin(), dimensions.rmax(), dimensions.length() * 0.5); + Tube topVolumeShape(dimensions.rmin(), dimensions.rmax(), dimensions.length() * 0.5); Volume assembly(det_name, topVolumeShape, air); sens.setType("tracker"); @@ -57,7 +57,7 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h // loop over the modules for (xml_coll_t mi(x_det, _U(module)); mi; ++mi) { xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); + string m_nam = x_mod.nameStr(); if (volumes.find(m_nam) != volumes.end()) { printout(ERROR, "BarrelBarDetectorWithSideFrame", @@ -65,7 +65,7 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h throw runtime_error("Logics error in building modules."); } - int ncomponents = 0; + int ncomponents = 0; double total_thickness = 0; // Compute module total thickness from components @@ -98,12 +98,12 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h double max_component_width = 0; for (xml_coll_t mci(x_mod, _U(module_component)); mci; ++mci, ++ncomponents) { xml_comp_t x_comp = mci; - string c_nam = _toString(ncomponents, "component%d"); + string c_nam = _toString(ncomponents, "component%d"); double box_width = x_comp.width() - 2 * frame_width; max_component_width = fmax(max_component_width, box_width); - Box c_box{box_width / 2, x_comp.length() / 2, x_comp.thickness() / 2}; + Box c_box{box_width / 2, x_comp.length() / 2, x_comp.thickness() / 2}; Volume c_vol{c_nam, c_box, description.material(x_comp.materialStr())}; pv = m_vol.placeVolume(c_vol, Position(0, 0, thickness_sum + x_comp.thickness() / 2.0)); @@ -136,8 +136,8 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h } // Now add-on the frame if (x_mod.hasChild(_U(frame))) { - xml_comp_t m_frame = x_mod.child(_U(frame)); - double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); + xml_comp_t m_frame = x_mod.child(_U(frame)); + double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); Box lframe_box{m_frame.width() / 2., m_frame.length() / 2., frame_thickness / 2.}; Box rframe_box{m_frame.width() / 2., m_frame.length() / 2., frame_thickness / 2.}; @@ -162,17 +162,17 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope)); xml_comp_t x_layout = x_layer.child(_U(rphi_layout)); xml_comp_t z_layout = x_layer.child(_U(z_layout)); // Get the element. - int lay_id = x_layer.id(); - string m_nam = x_layer.moduleStr(); - string lay_nam = _toString(x_layer.id(), "layer%d"); - Tube lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2.0); - Volume lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume. + int lay_id = x_layer.id(); + string m_nam = x_layer.moduleStr(); + string lay_nam = _toString(x_layer.id(), "layer%d"); + Tube lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2.0); + Volume lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume. lay_vol.setVisAttributes(description, x_layer.visStr()); double phi0 = x_layout.phi0(); // Starting phi of first module. double phi_tilt = x_layout.phi_tilt(); // Phi tilt of a module. double rc = x_layout.rc(); // Radius of the module center. - int nphi = x_layout.nphi(); // Number of modules in phi. + int nphi = x_layout.nphi(); // Number of modules in phi. double rphi_dr = x_layout.dr(); // The delta radius of every other module. double phi_incr = (M_PI * 2) / nphi; // Phi increment for one module. double phic = phi0; // Phi of the module center. @@ -180,8 +180,8 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h double nz = z_layout.nz(); // Number of modules to place in z. double z_dr = z_layout.dr(); // Radial displacement parameter, of every other module. - Volume module_env = volumes[m_nam]; - DetElement lay_elt(sdet, _toString(x_layer.id(), "layer%d"), lay_id); + Volume module_env = volumes[m_nam]; + DetElement lay_elt(sdet, _toString(x_layer.id(), "layer%d"), lay_id); Placements& sensVols = sensitives[m_nam]; // Z increment for module placement along Z axis. @@ -190,7 +190,7 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0; // Starting z for module placement along Z axis. double module_z = -z0; - int module = 1; + int module = 1; // Loop over the number of modules in phi. for (int ii = 0; ii < nphi; ii++) { @@ -201,10 +201,11 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h // Loop over the number of modules in z. for (int j = 0; j < nz; j++) { - string module_name = _toString(module, "module%d"); + string module_name = _toString(module, "module%d"); DetElement mod_elt(lay_elt, module_name, module); - Transform3D tr(RotationZYX(0, ((M_PI / 2) - phic - phi_tilt), -M_PI / 2), Position(x, y, module_z)); + Transform3D tr(RotationZYX(0, ((M_PI / 2) - phic - phi_tilt), -M_PI / 2), + Position(x, y, module_z)); pv = lay_vol.placeVolume(module_env, tr); pv.addPhysVolID("module", module); @@ -212,7 +213,7 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h mod_elt.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_de(mod_elt, std::string("de_") + sens_pv.volume().name(), module); + DetElement comp_de(mod_elt, std::string("de_") + sens_pv.volume().name(), module); comp_de.setPlacement(sens_pv); rec::volSurfaceList(comp_de)->push_back(volplane_surfaces[m_nam][ic]); } @@ -236,7 +237,8 @@ static Ref_t create_BarrelBarDetectorWithSideFrame(Detector& description, xml_h // Create the PhysicalVolume for the layer. pv = assembly.placeVolume(lay_vol); // Place layer in mother pv.addPhysVolID("layer", lay_id); // Set the layer ID. - lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr()); + lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), + x_layer.visStr()); lay_elt.setPlacement(pv); } sdet.setAttributes(description, assembly, x_det.regionStr(), x_det.limitsStr(), x_det.visStr()); diff --git a/src/BarrelCalorimeterImaging_geo.cpp b/src/BarrelCalorimeterImaging_geo.cpp index 190c14eb5..93bb7c737 100644 --- a/src/BarrelCalorimeterImaging_geo.cpp +++ b/src/BarrelCalorimeterImaging_geo.cpp @@ -33,25 +33,25 @@ static void buildSupport(Detector& desc, Volume& mother, xml_comp_t x_support, const std::tuple& dimensions); // barrel ecal layers contained in an assembly -static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) -{ - xml_det_t x_detector = e; - int detector_id = x_detector.id(); +static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) { + xml_det_t x_detector = e; + int detector_id = x_detector.id(); std::string detector_name = x_detector.nameStr(); - double offset = x_detector.attr(_Unicode(offset)); - xml_comp_t x_dimensions = x_detector.dimensions(); - int nsides = x_dimensions.numsides(); - double inner_r = x_dimensions.rmin(); - double dphi = (2 * M_PI / nsides); - double half_dphi = dphi / 2; + double offset = x_detector.attr(_Unicode(offset)); + xml_comp_t x_dimensions = x_detector.dimensions(); + int nsides = x_dimensions.numsides(); + double inner_r = x_dimensions.rmin(); + double dphi = (2 * M_PI / nsides); + double half_dphi = dphi / 2; DetElement sdet(detector_name, detector_id); - Volume mother_volume = desc.pickMotherVolume(sdet); + Volume mother_volume = desc.pickMotherVolume(sdet); Assembly detector_volume(detector_name); - detector_volume.setAttributes(desc, x_detector.regionStr(), x_detector.limitsStr(), x_detector.visStr()); + detector_volume.setAttributes(desc, x_detector.regionStr(), x_detector.limitsStr(), + x_detector.visStr()); - Transform3D detector_tr = Translation3D(0, 0, offset) * RotationZ(half_dphi); + Transform3D detector_tr = Translation3D(0, 0, offset) * RotationZ(half_dphi); PlacedVolume detector_physvol = mother_volume.placeVolume(detector_volume, detector_tr); sens.setType("calorimeter"); @@ -60,7 +60,7 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // build a single sector DetElement sector_element("sector0", detector_id); - Assembly sector_volume("sector"); + Assembly sector_volume("sector"); if (x_detector.hasChild(_Unicode(sectors))) { xml_comp_t x_sectors = x_detector.child(_Unicode(sectors)); sector_volume.setVisAttributes(desc.visAttributes(x_sectors.visStr())); @@ -75,21 +75,22 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Loop over the modules using dd4hep::rec::VolPlane; - std::map volumes; + std::map volumes; std::map> sensitives; - std::map> volplane_surfaces; - std::map> module_thicknesses; + std::map> volplane_surfaces; + std::map> module_thicknesses; for (xml_coll_t i_module(x_detector, _U(module)); i_module; ++i_module) { - xml_comp_t x_module = i_module; + xml_comp_t x_module = i_module; std::string module_name = x_module.nameStr(); if (volumes.find(module_name) != volumes.end()) { - printout(ERROR, "BarrelCalorimeterImaging", "Module with name %s already exists", module_name.c_str()); + printout(ERROR, "BarrelCalorimeterImaging", "Module with name %s already exists", + module_name.c_str()); throw std::runtime_error("Logics error in building modules."); } // Compute module total thickness from components - double total_thickness = 0; + double total_thickness = 0; xml_coll_t ci(x_module, _U(module_component)); for (ci.reset(), total_thickness = 0.0; ci; ++ci) { total_thickness += xml_comp_t(ci).thickness(); @@ -101,35 +102,40 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) module_volume.setVisAttributes(desc.visAttributes(x_module.visStr())); // Add components - int sensor_number = 1; - int ncomponents = 0; + int sensor_number = 1; + int ncomponents = 0; double thickness_so_far = 0.0; double thickness_sum = -total_thickness / 2.0; - for (xml_coll_t i_component(x_module, _U(module_component)); i_component; ++i_component, ++ncomponents) { - xml_comp_t x_component = i_component; - xml_comp_t x_component_pos = x_component.position(false); - xml_comp_t x_component_rot = x_component.rotation(false); - const std::string component_name = _toString(ncomponents, "component%d"); - Box component_box(x_component.width() / 2, x_component.length() / 2, x_component.thickness() / 2); - Volume component_volume(component_name, component_box, desc.material(x_component.materialStr())); - component_volume.setAttributes(desc, x_component.regionStr(), x_component.limitsStr(), x_component.visStr()); + for (xml_coll_t i_component(x_module, _U(module_component)); i_component; + ++i_component, ++ncomponents) { + xml_comp_t x_component = i_component; + xml_comp_t x_component_pos = x_component.position(false); + xml_comp_t x_component_rot = x_component.rotation(false); + const std::string component_name = _toString(ncomponents, "component%d"); + Box component_box(x_component.width() / 2, x_component.length() / 2, + x_component.thickness() / 2); + Volume component_volume(component_name, component_box, + desc.material(x_component.materialStr())); + component_volume.setAttributes(desc, x_component.regionStr(), x_component.limitsStr(), + x_component.visStr()); // Loop over the slices for this component - int slice_num = 1; + int slice_num = 1; double slice_pos_z = -x_component.thickness() / 2; for (xml_coll_t i_slice(x_component, _U(slice)); i_slice; ++i_slice) { - xml_comp_t x_slice = i_slice; - std::string slice_name = Form("slice%d", slice_num); - double slice_dim_x = x_component.width() / 2; - double slice_dim_y = x_component.length() / 2; - double slice_dim_z = x_slice.thickness() / 2; - Box slice_shape(slice_dim_x, slice_dim_y, slice_dim_z); - Volume slice_volume(slice_name, slice_shape, desc.material(x_slice.materialStr())); - slice_volume.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); + xml_comp_t x_slice = i_slice; + std::string slice_name = Form("slice%d", slice_num); + double slice_dim_x = x_component.width() / 2; + double slice_dim_y = x_component.length() / 2; + double slice_dim_z = x_slice.thickness() / 2; + Box slice_shape(slice_dim_x, slice_dim_y, slice_dim_z); + Volume slice_volume(slice_name, slice_shape, desc.material(x_slice.materialStr())); + slice_volume.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), + x_slice.visStr()); // Place slice - PlacedVolume slice_physvol = - component_volume.placeVolume(slice_volume, Position(0, 0, slice_pos_z + x_slice.thickness() / 2)); + PlacedVolume slice_physvol = component_volume.placeVolume( + slice_volume, Position(0, 0, slice_pos_z + x_slice.thickness() / 2)); // Set sensitive if (x_slice.isSensitive()) { @@ -147,15 +153,19 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) const double zoff = thickness_sum + x_component.thickness() / 2.0; PlacedVolume component_physvol; if (x_component_pos && x_component_rot) { - Position component_pos(x_component_pos.x(0), x_component_pos.y(0), x_component_pos.z(0) + zoff); + Position component_pos(x_component_pos.x(0), x_component_pos.y(0), + x_component_pos.z(0) + zoff); RotationZYX component_rot(x_component_rot.z(0), x_component_rot.y(0), x_component_rot.x(0)); - component_physvol = module_volume.placeVolume(component_volume, Transform3D(component_rot, component_pos)); + component_physvol = + module_volume.placeVolume(component_volume, Transform3D(component_rot, component_pos)); } else if (x_component_rot) { - Position component_pos(0, 0, zoff); + Position component_pos(0, 0, zoff); RotationZYX component_rot(x_component_rot.z(0), x_component_rot.y(0), x_component_rot.x(0)); - component_physvol = module_volume.placeVolume(component_volume, Transform3D(component_rot, component_pos)); + component_physvol = + module_volume.placeVolume(component_volume, Transform3D(component_rot, component_pos)); } else if (x_component_pos) { - Position component_pos(x_component_pos.x(0), x_component_pos.y(0), x_component_pos.z(0) + zoff); + Position component_pos(x_component_pos.x(0), x_component_pos.y(0), + x_component_pos.z(0) + zoff); component_physvol = module_volume.placeVolume(component_volume, component_pos); } else { Position component_pos(0, 0, zoff); @@ -167,7 +177,8 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) component_volume.setSensitiveDetector(sens); sensitives[module_name].push_back(component_physvol); module_thicknesses[module_name] = {thickness_so_far + x_component.thickness() / 2.0, - total_thickness - thickness_so_far - x_component.thickness() / 2.0}; + total_thickness - thickness_so_far - + x_component.thickness() / 2.0}; } thickness_sum += x_component.thickness(); @@ -181,35 +192,36 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) } } if (x_detector.hasChild(_Unicode(support))) { - buildSupport(desc, sector_volume, x_detector.child(_Unicode(support)), {inner_r, layer_pos_z, x_dimensions.z(), half_dphi}); + buildSupport(desc, sector_volume, x_detector.child(_Unicode(support)), + {inner_r, layer_pos_z, x_dimensions.z(), half_dphi}); } //Loop over the sets of layer elements in the detector. int layer_num = 1; for (xml_coll_t i_layer(x_detector, _U(layer)); i_layer; ++i_layer) { - xml_comp_t x_layer = i_layer; - int layer_repeat = x_layer.repeat(); - double layer_thickness = x_layer.thickness(); - bool layer_has_frame = x_layer.hasChild(_Unicode(frame)); - double layer_space_between = getAttrOrDefault(x_layer, _Unicode(space_between), 0.); - double layer_space_before = getAttrOrDefault(x_layer, _Unicode(space_before), 0.); + xml_comp_t x_layer = i_layer; + int layer_repeat = x_layer.repeat(); + double layer_thickness = x_layer.thickness(); + bool layer_has_frame = x_layer.hasChild(_Unicode(frame)); + double layer_space_between = getAttrOrDefault(x_layer, _Unicode(space_between), 0.); + double layer_space_before = getAttrOrDefault(x_layer, _Unicode(space_before), 0.); layer_pos_z += layer_space_before; // Loop over number of repeats for this layer. for (int layer_j = 0; layer_j < layer_repeat; layer_j++) { // Make an envelope for this layer - std::string layer_name = Form("layer%d", layer_num); - double layer_dim_x = tan_half_dphi * layer_pos_z; - auto layer_mat = desc.air(); - - Position layer_pos(0, 0, layer_pos_z + layer_thickness / 2.); - double layer_trd_x1 = layer_dim_x; - double layer_trd_x2 = layer_dim_x + layer_thickness * tan_half_dphi; - double layer_trd_y1 = layer_dim_y; - double layer_trd_y2 = layer_trd_y1; - double layer_trd_z = layer_thickness / 2; // account for frame - Trapezoid layer_shape(layer_trd_x1, layer_trd_x2, layer_trd_y1, layer_trd_y2, layer_trd_z); - Volume layer_volume(layer_name, layer_shape, layer_mat); + std::string layer_name = Form("layer%d", layer_num); + double layer_dim_x = tan_half_dphi * layer_pos_z; + auto layer_mat = desc.air(); + + Position layer_pos(0, 0, layer_pos_z + layer_thickness / 2.); + double layer_trd_x1 = layer_dim_x; + double layer_trd_x2 = layer_dim_x + layer_thickness * tan_half_dphi; + double layer_trd_y1 = layer_dim_y; + double layer_trd_y2 = layer_trd_y1; + double layer_trd_z = layer_thickness / 2; // account for frame + Trapezoid layer_shape(layer_trd_x1, layer_trd_x2, layer_trd_y1, layer_trd_y2, layer_trd_z); + Volume layer_volume(layer_name, layer_shape, layer_mat); DetElement layer_element(sector_element, layer_name, detector_id); // Set region, limitset, and vis of layer. @@ -218,25 +230,26 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Loop over the staves for this layer. int stave_num = 1; for (xml_coll_t i_stave(x_layer, _U(stave)); i_stave; ++i_stave) { - xml_comp_t x_stave = i_stave; - int stave_repeat = x_stave.repeat(); - double stave_thick = x_stave.thickness(); - double stave_dim_x = x_stave.width() / 2.0; - double stave_dim_y = x_stave.length() / 2.0; - double stave_dim_z = stave_thick / 2.0; - double stave_rot_y = getAttrOrDefault(x_stave, _Unicode(angle), 0.); - double stave_off_z = getAttrOrDefault(x_stave, _Unicode(offset), 0.); + xml_comp_t x_stave = i_stave; + int stave_repeat = x_stave.repeat(); + double stave_thick = x_stave.thickness(); + double stave_dim_x = x_stave.width() / 2.0; + double stave_dim_y = x_stave.length() / 2.0; + double stave_dim_z = stave_thick / 2.0; + double stave_rot_y = getAttrOrDefault(x_stave, _Unicode(angle), 0.); + double stave_off_z = getAttrOrDefault(x_stave, _Unicode(offset), 0.); // Arrange staves symmetrically around center of layer double stave_pos_x = -layer_dim_x + stave_dim_x; double stave_pitch = -2.0 * stave_pos_x / (stave_repeat - 1); // Make one stave - std::string stave_name = Form("stave%d", stave_num); - auto stave_material = desc.air(); - Box stave_shape(stave_dim_x, stave_dim_y, stave_dim_z); - Volume stave_volume(stave_name, stave_shape, stave_material); - stave_volume.setAttributes(desc, x_stave.regionStr(), x_stave.limitsStr(), x_stave.visStr()); + std::string stave_name = Form("stave%d", stave_num); + auto stave_material = desc.air(); + Box stave_shape(stave_dim_x, stave_dim_y, stave_dim_z); + Volume stave_volume(stave_name, stave_shape, stave_material); + stave_volume.setAttributes(desc, x_stave.regionStr(), x_stave.limitsStr(), + x_stave.visStr()); DetElement stave_element(layer_element, stave_name, detector_id); // Loop over the slices for this stave @@ -244,26 +257,26 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Place in xy_layout if (x_stave.hasChild(_Unicode(xy_layout))) { - auto module_str = x_stave.moduleStr(); + auto module_str = x_stave.moduleStr(); auto& module_volume = volumes[module_str]; auto& module_sensitives = sensitives[module_str]; // Get layout grid pitch xml_comp_t x_xy_layout = x_stave.child(_Unicode(xy_layout)); - auto dx = x_xy_layout.attr(_Unicode(dx)); - auto dy = x_xy_layout.attr(_Unicode(dy)); + auto dx = x_xy_layout.attr(_Unicode(dx)); + auto dy = x_xy_layout.attr(_Unicode(dy)); // Default to filling auto nx = getAttrOrDefault(x_xy_layout, _Unicode(nx), floor(2. * stave_dim_x / dx)); auto ny = getAttrOrDefault(x_xy_layout, _Unicode(ny), floor(2. * stave_dim_y / dy)); - printout(DEBUG, "BarrelCalorimeterImaging", "Stave %s layout with %d by %d modules", stave_name.c_str(), nx, - ny); + printout(DEBUG, "BarrelCalorimeterImaging", "Stave %s layout with %d by %d modules", + stave_name.c_str(), nx, ny); // Default to centered auto x0 = getAttrOrDefault(x_xy_layout, _Unicode(x0), -(nx - 1) * dx / 2.); auto y0 = getAttrOrDefault(x_xy_layout, _Unicode(x0), -(ny - 1) * dy / 2.); - printout(DEBUG, "BarrelCalorimeterImaging", "Stave %s modules starting at x=%f, y=%f", stave_name.c_str(), x0, - y0); + printout(DEBUG, "BarrelCalorimeterImaging", "Stave %s modules starting at x=%f, y=%f", + stave_name.c_str(), x0, y0); // Place modules int i_module = 0; @@ -272,23 +285,25 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Create module std::string module_name = _toString(i_module, "module%d"); - DetElement module_element(stave_element, module_name, i_module); + DetElement module_element(stave_element, module_name, i_module); // Place module - auto x = x0 + i_x * dx; - auto y = y0 + i_y * dy; - Position module_pos(x, y, 0); + auto x = x0 + i_x * dx; + auto y = y0 + i_y * dy; + Position module_pos(x, y, 0); PlacedVolume module_physvol = stave_volume.placeVolume(module_volume, module_pos); module_physvol.addPhysVolID("module", i_module); module_element.setPlacement(module_physvol); // Add sensitive volumes for (auto& sensitive_physvol : module_sensitives) { - DetElement sensitive_element(module_element, sensitive_physvol.volume().name(), i_module); + DetElement sensitive_element(module_element, sensitive_physvol.volume().name(), + i_module); sensitive_element.setPlacement(sensitive_physvol); auto& sensitive_element_params = - DD4hepDetectorHelper::ensureExtension(sensitive_element); + DD4hepDetectorHelper::ensureExtension( + sensitive_element); sensitive_element_params.set("axis_definitions", "XYZ"); } @@ -301,15 +316,16 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Loop over the slices for this stave int slice_num = 1; for (xml_coll_t i_slice(x_stave, _U(slice)); i_slice; ++i_slice) { - xml_comp_t x_slice = i_slice; - std::string slice_name = Form("slice%d", slice_num); - double slice_thick = x_slice.thickness(); - double slice_dim_x = stave_dim_x; - double slice_dim_y = stave_dim_y; - double slice_dim_z = slice_thick / 2.; - Box slice_shape(slice_dim_x, slice_dim_y, slice_dim_z); - Volume slice_volume(slice_name, slice_shape, desc.material(x_slice.materialStr())); - slice_volume.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); + xml_comp_t x_slice = i_slice; + std::string slice_name = Form("slice%d", slice_num); + double slice_thick = x_slice.thickness(); + double slice_dim_x = stave_dim_x; + double slice_dim_y = stave_dim_y; + double slice_dim_z = slice_thick / 2.; + Box slice_shape(slice_dim_x, slice_dim_y, slice_dim_z); + Volume slice_volume(slice_name, slice_shape, desc.material(x_slice.materialStr())); + slice_volume.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), + x_slice.visStr()); DetElement slice_element(stave_element, slice_name, detector_id); // Set sensitive @@ -332,9 +348,9 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) for (int stave_j = 0; stave_j < stave_repeat; stave_j++) { // Stave placement - Position stave_pos(stave_pos_x, 0, layer_j % 2 == 0 ? +stave_off_z : -stave_off_z); - RotationY stave_rot(layer_j % 2 == 0 ? +stave_rot_y : -stave_rot_y); - Transform3D stave_tr(stave_rot, stave_pos); + Position stave_pos(stave_pos_x, 0, layer_j % 2 == 0 ? +stave_off_z : -stave_off_z); + RotationY stave_rot(layer_j % 2 == 0 ? +stave_rot_y : -stave_rot_y); + Transform3D stave_tr(stave_rot, stave_pos); PlacedVolume stave_physvol = layer_volume.placeVolume(stave_volume, stave_tr); stave_physvol.addPhysVolID("stave", stave_num); stave_element.setPlacement(stave_physvol); @@ -347,32 +363,40 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Place frame if (layer_has_frame) { - xml_comp_t x_frame = x_layer.child(_Unicode(frame)); - double frame_height = x_frame.height(); - double frame_thickness = x_frame.thickness(); - auto frame_material = desc.material(x_frame.materialStr()); - - std::string frame1_name = Form("frame_inner%d", layer_num); - double frame1_thick = frame_thickness; - double frame1_trd_x1 = layer_dim_x + (layer_thickness / 2 - frame_height / 2) * tan_half_dphi; - double frame1_trd_x2 = layer_dim_x + (layer_thickness / 2 - frame_height / 2 + frame1_thick) * tan_half_dphi; - double frame1_trd_y1 = layer_trd_y1; - double frame1_trd_y2 = frame1_trd_y1; - double frame1_trd_z = frame1_thick / 2.; - Trapezoid frame1_shape(frame1_trd_x1, frame1_trd_x2, frame1_trd_y1, frame1_trd_y2, frame1_trd_z); - Volume frame1_volume(frame1_name, frame1_shape, frame_material); - layer_volume.placeVolume(frame1_volume, Position(0, 0, -frame_height / 2.0 + frame_thickness / 2.0)); - - std::string frame2_name = Form("frame_outer%d", layer_num); - double frame2_thick = frame_thickness; - double frame2_trd_x1 = layer_dim_x + (layer_thickness / 2 - frame_height / 2) * tan_half_dphi; - double frame2_trd_x2 = layer_dim_x + (layer_thickness / 2 - frame_height / 2 + frame2_thick) * tan_half_dphi; - double frame2_trd_y1 = layer_trd_y1; - double frame2_trd_y2 = frame2_trd_y1; - double frame2_trd_z = frame2_thick / 2.; - Trapezoid frame2_shape(frame2_trd_x1, frame2_trd_x2, frame2_trd_y1, frame2_trd_y2, frame2_trd_z); - Volume frame2_volume(frame2_name, frame2_shape, frame_material); - layer_volume.placeVolume(frame2_volume, Position(0, 0, +frame_height / 2.0 - frame_thickness / 2.0)); + xml_comp_t x_frame = x_layer.child(_Unicode(frame)); + double frame_height = x_frame.height(); + double frame_thickness = x_frame.thickness(); + auto frame_material = desc.material(x_frame.materialStr()); + + std::string frame1_name = Form("frame_inner%d", layer_num); + double frame1_thick = frame_thickness; + double frame1_trd_x1 = + layer_dim_x + (layer_thickness / 2 - frame_height / 2) * tan_half_dphi; + double frame1_trd_x2 = + layer_dim_x + (layer_thickness / 2 - frame_height / 2 + frame1_thick) * tan_half_dphi; + double frame1_trd_y1 = layer_trd_y1; + double frame1_trd_y2 = frame1_trd_y1; + double frame1_trd_z = frame1_thick / 2.; + Trapezoid frame1_shape(frame1_trd_x1, frame1_trd_x2, frame1_trd_y1, frame1_trd_y2, + frame1_trd_z); + Volume frame1_volume(frame1_name, frame1_shape, frame_material); + layer_volume.placeVolume(frame1_volume, + Position(0, 0, -frame_height / 2.0 + frame_thickness / 2.0)); + + std::string frame2_name = Form("frame_outer%d", layer_num); + double frame2_thick = frame_thickness; + double frame2_trd_x1 = + layer_dim_x + (layer_thickness / 2 - frame_height / 2) * tan_half_dphi; + double frame2_trd_x2 = + layer_dim_x + (layer_thickness / 2 - frame_height / 2 + frame2_thick) * tan_half_dphi; + double frame2_trd_y1 = layer_trd_y1; + double frame2_trd_y2 = frame2_trd_y1; + double frame2_trd_z = frame2_thick / 2.; + Trapezoid frame2_shape(frame2_trd_x1, frame2_trd_x2, frame2_trd_y1, frame2_trd_y2, + frame2_trd_z); + Volume frame2_volume(frame2_name, frame2_shape, frame_material); + layer_volume.placeVolume(frame2_volume, + Position(0, 0, +frame_height / 2.0 - frame_thickness / 2.0)); } // Place layer into sector @@ -394,7 +418,7 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Create nsides sectors. for (int i = 0; i < nsides; i++, phi -= dphi) { // i is sector number // Compute the sector position - Transform3D tr(RotationZYX(0, phi, M_PI * 0.5), Translation3D(0, 0, 0)); + Transform3D tr(RotationZYX(0, phi, M_PI * 0.5), Translation3D(0, 0, 0)); PlacedVolume sector_physvol = detector_volume.placeVolume(sector_volume, tr); sector_physvol.addPhysVolID("sector", i + 1); DetElement sd = (i == 0) ? sector_element : sector_element.clone(Form("sector%d", i)); @@ -408,17 +432,16 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // simple aluminum sheet cover // dimensions: (inner r, position in z, length, phi) static void buildSupport(Detector& desc, Volume& sector_volume, xml_comp_t x_support, - const std::tuple& dimensions) -{ + const std::tuple& dimensions) { auto [inner_r, pos_z, sector_length, hphi] = dimensions; - double support_thickness = getAttrOrDefault(x_support, _Unicode(thickness), 0.5 * cm); - auto material = desc.material(x_support.materialStr()); - double trd_y = sector_length / 2.; - double trd_x1_support = std::tan(hphi) * pos_z; - double trd_x2_support = std::tan(hphi) * (pos_z + support_thickness); + double support_thickness = getAttrOrDefault(x_support, _Unicode(thickness), 0.5 * cm); + auto material = desc.material(x_support.materialStr()); + double trd_y = sector_length / 2.; + double trd_x1_support = std::tan(hphi) * pos_z; + double trd_x2_support = std::tan(hphi) * (pos_z + support_thickness); Trapezoid s_shape(trd_x1_support, trd_x2_support, trd_y, trd_y, support_thickness / 2.); - Volume s_vol("support_layer", s_shape, material); + Volume s_vol("support_layer", s_shape, material); s_vol.setVisAttributes(desc.visAttributes(x_support.visStr())); sector_volume.placeVolume(s_vol, Position(0.0, 0.0, pos_z + support_thickness / 2.)); } diff --git a/src/BarrelCalorimeterScFi_geo.cpp b/src/BarrelCalorimeterScFi_geo.cpp index 18de3be83..e0a2fa468 100644 --- a/src/BarrelCalorimeterScFi_geo.cpp +++ b/src/BarrelCalorimeterScFi_geo.cpp @@ -25,14 +25,13 @@ using namespace dd4hep; typedef ROOT::Math::XYPoint Point; // fiber placement helpers, defined below struct FiberGrid { - int ix = 0, iy = 0; + int ix = 0, iy = 0; std::vector points; - Point mean_centroid = Point(0., 0.); - Assembly* assembly_ptr = nullptr; + Point mean_centroid = Point(0., 0.); + Assembly* assembly_ptr = nullptr; // initialize with grid id and points - FiberGrid(int i, int j, const std::vector& pts) : ix(i), iy(j), points(pts) - { + FiberGrid(int i, int j, const std::vector& pts) : ix(i), iy(j), points(pts) { if (pts.empty()) { return; } @@ -48,37 +47,36 @@ struct FiberGrid { }; }; -std::vector fiberPositions(double r, double sx, double sz, double trx, double trz, double phi, - bool shift_first = false, double stol = 1e-2); +std::vector fiberPositions(double r, double sx, double sz, double trx, double trz, + double phi, bool shift_first = false, double stol = 1e-2); std::vector gridPoints(int div_n_phi, double div_dr, double x, double z, double phi); // geometry helpers -void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& mother, int layer_nunber, xml_comp_t x_fiber, - const std::tuple& dimensions); +void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& mother, int layer_nunber, + xml_comp_t x_fiber, const std::tuple& dimensions); void buildSupport(Detector& desc, Volume& mother, xml_comp_t x_support, const std::tuple& dimensions); // barrel ecal layers contained in an assembly -static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) -{ - Layering layering(e); - xml_det_t x_det = e; - Material air = desc.air(); - int det_id = x_det.id(); - double offset = x_det.attr(_Unicode(offset)); - xml_comp_t x_dim = x_det.dimensions(); - int nsides = x_dim.numsides(); - double inner_r = x_dim.rmin(); - double dphi = (2 * M_PI / nsides); - double hphi = dphi / 2; +static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) { + Layering layering(e); + xml_det_t x_det = e; + Material air = desc.air(); + int det_id = x_det.id(); + double offset = x_det.attr(_Unicode(offset)); + xml_comp_t x_dim = x_det.dimensions(); + int nsides = x_dim.numsides(); + double inner_r = x_dim.rmin(); + double dphi = (2 * M_PI / nsides); + double hphi = dphi / 2; std::string det_name = x_det.nameStr(); DetElement sdet(det_name, det_id); - Volume motherVol = desc.pickMotherVolume(sdet); + Volume motherVol = desc.pickMotherVolume(sdet); - Assembly envelope(det_name); - Transform3D tr_global = Translation3D(0, 0, offset) * RotationZ(hphi); - PlacedVolume env_phv = motherVol.placeVolume(envelope, tr_global); + Assembly envelope(det_name); + Transform3D tr_global = Translation3D(0, 0, offset) * RotationZ(hphi); + PlacedVolume env_phv = motherVol.placeVolume(envelope, tr_global); sens.setType("calorimeter"); env_phv.addPhysVolID("system", det_id); @@ -86,7 +84,7 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // build a single sector DetElement sector_det("sector0", det_id); - Assembly mod_vol("sector"); + Assembly mod_vol("sector"); // keep tracking of the total thickness double l_pos_z = inner_r; @@ -98,47 +96,48 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Loop over the sets of layer elements in the detector. int l_num = 1; for (xml_coll_t li(x_det, _U(layer)); li; ++li) { - xml_comp_t x_layer = li; - int repeat = x_layer.repeat(); - double l_space_between = getAttrOrDefault(x_layer, _Unicode(space_between), 0.); - double l_space_before = getAttrOrDefault(x_layer, _Unicode(space_before), 0.); + xml_comp_t x_layer = li; + int repeat = x_layer.repeat(); + double l_space_between = getAttrOrDefault(x_layer, _Unicode(space_between), 0.); + double l_space_before = getAttrOrDefault(x_layer, _Unicode(space_before), 0.); l_pos_z += l_space_before; // Loop over number of repeats for this layer. for (int j = 0; j < repeat; j++) { - std::string l_name = Form("layer%d", l_num); - double l_thickness = layering.layer(l_num - 1)->thickness(); // Layer's thickness. - double l_dim_x = tan_hphi * l_pos_z; + std::string l_name = Form("layer%d", l_num); + double l_thickness = layering.layer(l_num - 1)->thickness(); // Layer's thickness. + double l_dim_x = tan_hphi * l_pos_z; l_pos_z += l_thickness; - Position l_pos(0, 0, l_pos_z - l_thickness / 2.); // Position of the layer. - double l_trd_x1 = l_dim_x; - double l_trd_x2 = l_dim_x + l_thickness * tan_hphi; - double l_trd_y1 = l_dim_y; - double l_trd_y2 = l_trd_y1; - double l_trd_z = l_thickness / 2; - Trapezoid l_shape(l_trd_x1, l_trd_x2, l_trd_y1, l_trd_y2, l_trd_z); - Volume l_vol(l_name, l_shape, air); + Position l_pos(0, 0, l_pos_z - l_thickness / 2.); // Position of the layer. + double l_trd_x1 = l_dim_x; + double l_trd_x2 = l_dim_x + l_thickness * tan_hphi; + double l_trd_y1 = l_dim_y; + double l_trd_y2 = l_trd_y1; + double l_trd_z = l_thickness / 2; + Trapezoid l_shape(l_trd_x1, l_trd_x2, l_trd_y1, l_trd_y2, l_trd_z); + Volume l_vol(l_name, l_shape, air); DetElement layer(sector_det, l_name, det_id); // Loop over the sublayers or slices for this layer. - int s_num = 1; + int s_num = 1; double s_pos_z = -(l_thickness / 2.); for (xml_coll_t si(x_layer, _U(slice)); si; ++si) { - xml_comp_t x_slice = si; - std::string s_name = Form("slice%d", s_num); - double s_thick = x_slice.thickness(); - double s_trd_x1 = l_dim_x + (s_pos_z + l_thickness / 2) * tan_hphi; - double s_trd_x2 = l_dim_x + (s_pos_z + l_thickness / 2 + s_thick) * tan_hphi; - double s_trd_y1 = l_trd_y1; - double s_trd_y2 = s_trd_y1; - double s_trd_z = s_thick / 2.; - Trapezoid s_shape(s_trd_x1, s_trd_x2, s_trd_y1, s_trd_y2, s_trd_z); - Volume s_vol(s_name, s_shape, desc.material(x_slice.materialStr())); - DetElement slice(layer, s_name, det_id); + xml_comp_t x_slice = si; + std::string s_name = Form("slice%d", s_num); + double s_thick = x_slice.thickness(); + double s_trd_x1 = l_dim_x + (s_pos_z + l_thickness / 2) * tan_hphi; + double s_trd_x2 = l_dim_x + (s_pos_z + l_thickness / 2 + s_thick) * tan_hphi; + double s_trd_y1 = l_trd_y1; + double s_trd_y2 = s_trd_y1; + double s_trd_z = s_thick / 2.; + Trapezoid s_shape(s_trd_x1, s_trd_x2, s_trd_y1, s_trd_y2, s_trd_z); + Volume s_vol(s_name, s_shape, desc.material(x_slice.materialStr())); + DetElement slice(layer, s_name, det_id); // build fibers if (x_slice.hasChild(_Unicode(fiber))) { - buildFibers(desc, sens, s_vol, l_num, x_slice.child(_Unicode(fiber)), {s_trd_x1, s_thick, l_dim_y, hphi}); + buildFibers(desc, sens, s_vol, l_num, x_slice.child(_Unicode(fiber)), + {s_trd_x1, s_thick, l_dim_y, hphi}); } if (x_slice.isSensitive()) { @@ -174,7 +173,7 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) // Create nsides sectors. for (int i = 0; i < nsides; i++, phi -= dphi) { // i is module number // Compute the sector position - Transform3D tr(RotationZYX(0, phi, M_PI * 0.5), Translation3D(0, 0, 0)); + Transform3D tr(RotationZYX(0, phi, M_PI * 0.5), Translation3D(0, 0, 0)); PlacedVolume pv = envelope.placeVolume(mod_vol, tr); pv.addPhysVolID("sector", i + 1); DetElement sd = (i == 0) ? sector_det : sector_det.clone(Form("sector%d", i)); @@ -196,18 +195,18 @@ static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) return sdet; } -void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int layer_number, xml_comp_t x_fiber, - const std::tuple& dimensions) -{ +void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int layer_number, + xml_comp_t x_fiber, const std::tuple& dimensions) { auto [s_trd_x1, s_thick, s_length, hphi] = dimensions; - double f_radius = getAttrOrDefault(x_fiber, _U(radius), 0.1 * cm); - double f_cladding_thickness = getAttrOrDefault(x_fiber, _Unicode(cladding_thickness), 0.0 * cm); - double f_spacing_x = getAttrOrDefault(x_fiber, _Unicode(spacing_x), 0.122 * cm); - double f_spacing_z = getAttrOrDefault(x_fiber, _Unicode(spacing_z), 0.134 * cm); - int grid_n_phi = getAttrOrDefault(x_fiber, _Unicode(grid_n_phi), 5); - double grid_dr = getAttrOrDefault(x_fiber, _Unicode(grid_dr), 2.0 * cm); - std::string f_id_grid = getAttrOrDefault(x_fiber, _Unicode(identifier_grid), "grid"); - std::string f_id_fiber = getAttrOrDefault(x_fiber, _Unicode(identifier_fiber), "fiber"); + double f_radius = getAttrOrDefault(x_fiber, _U(radius), 0.1 * cm); + double f_cladding_thickness = getAttrOrDefault(x_fiber, _Unicode(cladding_thickness), 0.0 * cm); + double f_spacing_x = getAttrOrDefault(x_fiber, _Unicode(spacing_x), 0.122 * cm); + double f_spacing_z = getAttrOrDefault(x_fiber, _Unicode(spacing_z), 0.134 * cm); + int grid_n_phi = getAttrOrDefault(x_fiber, _Unicode(grid_n_phi), 5); + double grid_dr = getAttrOrDefault(x_fiber, _Unicode(grid_dr), 2.0 * cm); + std::string f_id_grid = getAttrOrDefault(x_fiber, _Unicode(identifier_grid), "grid"); + std::string f_id_fiber = + getAttrOrDefault(x_fiber, _Unicode(identifier_fiber), "fiber"); // Set up the readout grid for the fiber layers // Trapezoid is divided into segments with equal dz and equal number of divisions in x @@ -218,9 +217,9 @@ void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int lay // fiber and its cladding double f_radius_core = f_radius - f_cladding_thickness; - Tube f_tube_clad(0, f_radius, s_length); + Tube f_tube_clad(0, f_radius, s_length); Volume f_vol_clad("fiber_vol", f_tube_clad, desc.material(x_fiber.materialStr())); - Tube f_tube_core(0, f_radius_core, s_length); + Tube f_tube_core(0, f_radius_core, s_length); Volume f_vol_core("fiber_core_vol", f_tube_core, desc.material(x_fiber.materialStr())); if (x_fiber.isSensitive()) { f_vol_core.setSensitiveDetector(sens); @@ -229,14 +228,15 @@ void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int lay f_vol_clad.placeVolume(f_vol_core); // calculate polygonal grid coordinates (vertices) - auto grids = gridPoints(grid_n_phi, grid_dr, s_trd_x1, s_thick, hphi); + auto grids = gridPoints(grid_n_phi, grid_dr, s_trd_x1, s_thick, hphi); std::vector f_id_count(grids.size(), 0); // use layer_number % 2 to add correct shifts for the adjacent fibers at layer boundary - auto f_pos = fiberPositions(f_radius, f_spacing_x, f_spacing_z, s_trd_x1, s_thick, hphi, (layer_number % 2 == 0)); + auto f_pos = fiberPositions(f_radius, f_spacing_x, f_spacing_z, s_trd_x1, s_thick, hphi, + (layer_number % 2 == 0)); // a helper struct to speed up searching struct Fiber { Point pos; - bool assigned = false; + bool assigned = false; Fiber(const Point& p) : pos(p){}; }; std::vector fibers(f_pos.begin(), f_pos.end()); @@ -253,7 +253,7 @@ void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int lay } // use TGeoPolygon to help check if fiber is inside a grid - TGeoPolygon poly(gr.points.size()); + TGeoPolygon poly(gr.points.size()); std::vector vx, vy; std::transform(gr.points.begin(), gr.points.end(), back_inserter(vx), std::mem_fn(&Point::x)); std::transform(gr.points.begin(), gr.points.end(), back_inserter(vy), std::mem_fn(&Point::y)); @@ -276,8 +276,9 @@ void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int lay // only add this if this grid has fibers if (f_id > 1) { // fiber is along y-axis of the layer volume, so grids are arranged on X-Z plane - Transform3D gr_tr(RotationZYX(0., 0., M_PI * 0.5), Position(gr.mean_centroid.x(), 0., gr.mean_centroid.y())); - auto grid_phv = s_vol.placeVolume(grid_vol, gr_tr); + Transform3D gr_tr(RotationZYX(0., 0., M_PI * 0.5), + Position(gr.mean_centroid.x(), 0., gr.mean_centroid.y())); + auto grid_phv = s_vol.placeVolume(grid_vol, gr_tr); grid_phv.addPhysVolID(f_id_grid, gr.ix + gr.iy * grid_n_phi + 1); grid_vol.ptr()->Voxelize(""); } @@ -299,25 +300,23 @@ void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int lay // simple aluminum sheet cover // dimensions: (inner r, position in z, length, phi) void buildSupport(Detector& desc, Volume& mod_vol, xml_comp_t x_support, - const std::tuple& dimensions) -{ + const std::tuple& dimensions) { auto [inner_r, pos_z, sector_length, hphi] = dimensions; - double support_thickness = getAttrOrDefault(x_support, _Unicode(thickness), 3. * cm); - auto material = desc.material(x_support.materialStr()); - double trd_y = sector_length / 2.; - double trd_x1_support = std::tan(hphi) * pos_z; - double trd_x2_support = std::tan(hphi) * (pos_z + support_thickness); + double support_thickness = getAttrOrDefault(x_support, _Unicode(thickness), 3. * cm); + auto material = desc.material(x_support.materialStr()); + double trd_y = sector_length / 2.; + double trd_x1_support = std::tan(hphi) * pos_z; + double trd_x2_support = std::tan(hphi) * (pos_z + support_thickness); Trapezoid s_shape(trd_x1_support, trd_x2_support, trd_y, trd_y, support_thickness / 2.); - Volume s_vol("support_layer", s_shape, material); + Volume s_vol("support_layer", s_shape, material); s_vol.setVisAttributes(desc.visAttributes(x_support.visStr())); mod_vol.placeVolume(s_vol, Position(0.0, 0.0, pos_z + support_thickness / 2.)); } // Fill fiber lattice into trapezoid starting from position (0,0) in x-z coordinate system -std::vector fiberPositions(double r, double sx, double sz, double trx, double trz, double phi, bool shift, - double stol) -{ +std::vector fiberPositions(double r, double sx, double sz, double trx, double trz, + double phi, bool shift, double stol) { // r - fiber radius // sx, sz - spacing between fibers in x, z // trx - half-length of the shorter (bottom) base of the trapezoid @@ -326,10 +325,10 @@ std::vector fiberPositions(double r, double sx, double sz, double trx, do // stol - spacing tolerance std::vector positions; - int z_layers = floor((trz / 2 - r - stol) / sz); // number of layers that fits in half trapezoid-z + int z_layers = floor((trz / 2 - r - stol) / sz); // number of layers that fits in half trapezoid-z double px = 0., pz = 0.; - int start_line = shift ? 1 : 0; + int start_line = shift ? 1 : 0; for (int l = -z_layers; l < z_layers + 1; l++) { std::vector xline; @@ -345,7 +344,8 @@ std::vector fiberPositions(double r, double sx, double sz, double trx, do } // Sort fiber IDs for a better organization - sort(xline.begin(), xline.end(), [](const Point& p1, const Point& p2) { return p1.x() < p2.x(); }); + sort(xline.begin(), xline.end(), + [](const Point& p1, const Point& p2) { return p1.x() < p2.x(); }); positions.insert(positions.end(), xline.begin(), xline.end()); } return positions; @@ -353,8 +353,8 @@ std::vector fiberPositions(double r, double sx, double sz, double trx, do // Determine the number of divisions for the readout grid for the fiber layers // Calculate dimensions of the polygonal grid -std::vector gridPoints(int div_n_phi, double div_dr, double trd_x1, double height, double phi) -{ +std::vector gridPoints(int div_n_phi, double div_dr, double trd_x1, double height, + double phi) { /* // TODO: move this test to xml file double SiPMsize = 13.0 * mm; @@ -377,7 +377,7 @@ std::vector gridPoints(int div_n_phi, double div_dr, double trd_x1, d // grid vertices std::vector results; - double dr = height / nr; + double dr = height / nr; for (int ir = 0; ir <= nr; ir++) { for (int iph = 0; iph <= nph; iph++) { diff --git a/src/BarrelFluxReturn_geo.cpp b/src/BarrelFluxReturn_geo.cpp index 9ea328d6d..9b4f644d1 100644 --- a/src/BarrelFluxReturn_geo.cpp +++ b/src/BarrelFluxReturn_geo.cpp @@ -7,8 +7,8 @@ using namespace dd4hep; -static dd4hep::Ref_t create_detector(dd4hep::Detector& description, xml_h e, [[maybe_unused]] dd4hep::SensitiveDetector sens) -{ +static dd4hep::Ref_t create_detector(dd4hep::Detector& description, xml_h e, + [[maybe_unused]] dd4hep::SensitiveDetector sens) { xml_det_t x_det = e; xml_comp_t x_dim = x_det.dimensions(); @@ -25,18 +25,18 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& description, xml_h e, [[m std::map volumes_by_name; for (xml_coll_t shape(e, _U(shape)); shape; ++shape) { xml_comp_t x_shape = shape; - Solid solid = xml::createShape(description, x_shape.typeStr(), shape); - Material mat = description.material(x_shape.materialStr()); + Solid solid = xml::createShape(description, x_shape.typeStr(), shape); + Material mat = description.material(x_shape.materialStr()); volumes_by_name[x_shape.nameStr()] = - Volume(x_shape.nameStr(), solid, mat) - .setVisAttributes(description.visAttributes(x_shape.visStr())); + Volume(x_shape.nameStr(), solid, mat) + .setVisAttributes(description.visAttributes(x_shape.visStr())); } // Replicate volumes for (xml_coll_t repl(e, _U(replicate)); repl; ++repl) { xml_comp_t x_repl = repl; - Volume& vol = volumes_by_name[x_repl.attr(_U(shape))]; - Transform3D tf = xml::createTransformation(x_repl); + Volume& vol = volumes_by_name[x_repl.attr(_U(shape))]; + Transform3D tf = xml::createTransformation(x_repl); for (int i = 0; i < x_repl.count(); ++i) { double phi = x_repl.phi0() + i * x_repl.attr(_Unicode(dphi)); env_vol.placeVolume(vol, Transform3D(RotationZ(phi)) * tf); diff --git a/src/BarrelHCalCalorimeter_geo.cpp b/src/BarrelHCalCalorimeter_geo.cpp index 3f53b5374..499080494 100644 --- a/src/BarrelHCalCalorimeter_geo.cpp +++ b/src/BarrelHCalCalorimeter_geo.cpp @@ -29,18 +29,17 @@ using namespace std; using namespace dd4hep; using namespace dd4hep::detail; -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { // printout(WARNING, "BarrelHCalCalorimeter", "called create_detector "); - xml_det_t x_det = e; - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - Material air = description.air(); + xml_det_t x_det = e; + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + Material air = description.air(); DetElement sdet(det_name, det_id); - Volume motherVol = description.pickMotherVolume(sdet); + Volume motherVol = description.pickMotherVolume(sdet); // Create envelope to hold HCAL barrel @@ -52,12 +51,16 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // 5mm buffer on inner radius to acount for comb angle/tilt // (allows the combs to be added in later) - std::vector rmins = {rmin2-0.5*cm, rmin2-0.5*cm, rmin1-1.5*cm, rmin1-1.5*cm, rmin2-0.5*cm, rmin2-0.5*cm}; + std::vector rmins = {rmin2 - 0.5 * cm, rmin2 - 0.5 * cm, rmin1 - 1.5 * cm, + rmin1 - 1.5 * cm, rmin2 - 0.5 * cm, rmin2 - 0.5 * cm}; // 1cm buffer on outer radius to acount for comb angle/tilt // (allows the combs to be added in later) - std::vector rmaxs = {rmax+1.0*cm, rmax+1.0*cm, rmax+1.0*cm, rmax+1.0*cm, rmax+1.0*cm, rmax+1.0*cm}; + std::vector rmaxs = {rmax + 1.0 * cm, rmax + 1.0 * cm, rmax + 1.0 * cm, + rmax + 1.0 * cm, rmax + 1.0 * cm, rmax + 1.0 * cm}; // leave room for dogbones at the ends (not part of det table) - std::vector zs = {-length2 / 2. - 8.2*cm, -length1 / 2., -length1 / 2., length1 / 2., length1 / 2., length2 / 2. + 8.2*cm}; + std::vector zs = { + -length2 / 2. - 8.2 * cm, -length1 / 2., -length1 / 2., length1 / 2., length1 / 2., + length2 / 2. + 8.2 * cm}; // printout(WARNING, "BarrelHCalCalorimeter", "%f %f %f %f %f", rmin1, rmin2, rmax, length1/2., length2/2.); @@ -72,40 +75,51 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // Pick up the constants - double tilePlaneRotate = 0.0; - double tile_tolerance = 0.2; // Tile tolerance in mm to avoid overlaps + double tilePlaneRotate = 0.0; + double tile_tolerance = 0.2; // Tile tolerance in mm to avoid overlaps // Sector steel tessellated shape gdml file info xml_comp_t x_det_sec_gdmlfile = x_det.child("sec_gdmlfile"); - std::string sec_gdml_file = getAttrOrDefault(x_det_sec_gdmlfile, _Unicode(file), " ");; - std::string sec_gdml_material = getAttrOrDefault(x_det_sec_gdmlfile, _Unicode(material), " "); + std::string sec_gdml_file = + getAttrOrDefault(x_det_sec_gdmlfile, _Unicode(file), " "); + ; + std::string sec_gdml_material = + getAttrOrDefault(x_det_sec_gdmlfile, _Unicode(material), " "); std::string sec_gdml_url = getAttrOrDefault(x_det_sec_gdmlfile, _Unicode(url), " "); - std::string sec_gdml_cache = getAttrOrDefault(x_det_sec_gdmlfile, _Unicode(cache), " "); + std::string sec_gdml_cache = + getAttrOrDefault(x_det_sec_gdmlfile, _Unicode(cache), " "); xml_comp_t x_det_csec_gdmlfile = x_det.child("csec_gdmlfile"); - std::string csec_gdml_file = getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(file), " ");; - std::string csec_gdml_material = getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(material), " "); - std::string csec_gdml_url = getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(url), " "); - std::string csec_gdml_cache = getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(cache), " "); + std::string csec_gdml_file = + getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(file), " "); + ; + std::string csec_gdml_material = + getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(material), " "); + std::string csec_gdml_url = + getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(url), " "); + std::string csec_gdml_cache = + getAttrOrDefault(x_det_csec_gdmlfile, _Unicode(cache), " "); xml_comp_t x_det_er_gdmlfile = x_det.child("er_gdmlfile"); - std::string er_gdml_file = getAttrOrDefault(x_det_er_gdmlfile, _Unicode(file), " ");; - std::string er_gdml_material = getAttrOrDefault(x_det_er_gdmlfile, _Unicode(material), " "); + std::string er_gdml_file = getAttrOrDefault(x_det_er_gdmlfile, _Unicode(file), " "); + ; + std::string er_gdml_material = + getAttrOrDefault(x_det_er_gdmlfile, _Unicode(material), " "); std::string er_gdml_url = getAttrOrDefault(x_det_er_gdmlfile, _Unicode(url), " "); - std::string er_gdml_cache = getAttrOrDefault(x_det_er_gdmlfile, _Unicode(cache), " "); + std::string er_gdml_cache = + getAttrOrDefault(x_det_er_gdmlfile, _Unicode(cache), " "); // Loop over the defines section and pick up the tile offsets, ref location and angles for (xml_coll_t i(det_define, _Unicode(constant)); i; ++i) { xml_comp_t x_const = i; - std::string const_name = getAttrOrDefault(x_const, _Unicode(name), " "); + std::string const_name = getAttrOrDefault(x_const, _Unicode(name), " "); - if (const_name == "tilePlaneRotate"){ + if (const_name == "tilePlaneRotate") { std::string const_value = getAttrOrDefault(x_const, _Unicode(value), " "); - tilePlaneRotate = atof(const_value.c_str()); - } - else + tilePlaneRotate = atof(const_value.c_str()); + } else printout(WARNING, "BarrelHCalCalorimeter", "unrecognized data!"); } @@ -150,7 +164,7 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s } std::string delimiter = " "; - size_t pos = 0; + size_t pos = 0; std::string token; while ((pos = mtrx_values.find(delimiter)) != std::string::npos) { token = mtrx_values.substr(0, pos); @@ -169,12 +183,13 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s EnsureFileFromURLExists(sec_gdml_url, sec_gdml_file, sec_gdml_cache); if (!fs::exists(fs::path(sec_gdml_file))) { printout(ERROR, "BarrelHCalCalorimeter_geo", "file " + sec_gdml_file + " does not exist"); - printout(ERROR, "BarrelHCalCalorimeter_geo", "use a FileLoader plugin before the field element"); + printout(ERROR, "BarrelHCalCalorimeter_geo", + "use a FileLoader plugin before the field element"); std::_Exit(EXIT_FAILURE); } Volume barrel_sector_vol = parser.GDMLReadFile(sec_gdml_file.c_str()); - if(!barrel_sector_vol.isValid()){ + if (!barrel_sector_vol.isValid()) { printout(WARNING, "BarrelHCalCalorimeter", "%s", sec_gdml_file.c_str()); printout(WARNING, "BarrelHCalCalorimeter", "barrel_sector_vol invalid, GDML parser failed!"); std::_Exit(EXIT_FAILURE); @@ -190,12 +205,13 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s EnsureFileFromURLExists(csec_gdml_url, csec_gdml_file, csec_gdml_cache); if (!fs::exists(fs::path(csec_gdml_file))) { printout(ERROR, "BarrelHCalCalorimeter_geo", "file " + csec_gdml_file + " does not exist"); - printout(ERROR, "BarrelHCalCalorimeter_geo", "use a FileLoader plugin before the field element"); + printout(ERROR, "BarrelHCalCalorimeter_geo", + "use a FileLoader plugin before the field element"); std::_Exit(EXIT_FAILURE); } Volume barrel_csector_vol = parser.GDMLReadFile(csec_gdml_file.c_str()); - if(!barrel_csector_vol.isValid()){ + if (!barrel_csector_vol.isValid()) { printout(WARNING, "BarrelHCalCalorimeter", "%s", csec_gdml_file.c_str()); printout(WARNING, "BarrelHCalCalorimeter", "barrel_csector_vol invalid, GDML parser failed!"); std::_Exit(EXIT_FAILURE); @@ -211,12 +227,13 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s EnsureFileFromURLExists(er_gdml_url, er_gdml_file, er_gdml_cache); if (!fs::exists(fs::path(er_gdml_file))) { printout(ERROR, "BarrelHCalCalorimeter_geo", "file " + er_gdml_file + " does not exist"); - printout(ERROR, "BarrelHCalCalorimeter_geo", "use a FileLoader plugin before the field element"); + printout(ERROR, "BarrelHCalCalorimeter_geo", + "use a FileLoader plugin before the field element"); std::_Exit(EXIT_FAILURE); } Volume barrel_er_vol = parser.GDMLReadFile(er_gdml_file.c_str()); - if(!barrel_er_vol.isValid()){ + if (!barrel_er_vol.isValid()) { printout(WARNING, "BarrelHCalCalorimeter", "%s", er_gdml_file.c_str()); printout(WARNING, "BarrelHCalCalorimeter", "barrel_er_vol invalid, GDML parser failed!"); std::_Exit(EXIT_FAILURE); @@ -230,61 +247,74 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // Place steel in envelope - double sec_rot_angle = 360.0/32.0; + double sec_rot_angle = 360.0 / 32.0; - for(int k=0; k<29; k++){ - BarrelHCAL.placeVolume(barrel_sector_vol, k, Transform3D(RotationZ(-k*sec_rot_angle*dd4hep::deg)*RotationY(180.0* dd4hep::deg),Translation3D(0, 0, 0))); + for (int k = 0; k < 29; k++) { + BarrelHCAL.placeVolume( + barrel_sector_vol, k, + Transform3D(RotationZ(-k * sec_rot_angle * dd4hep::deg) * RotationY(180.0 * dd4hep::deg), + Translation3D(0, 0, 0))); } - BarrelHCAL.placeVolume(barrel_csector_vol, 0, Transform3D(RotationZ(sec_rot_angle*dd4hep::deg)*RotationY(180.0* dd4hep::deg),Translation3D(0, 0, 0))); - BarrelHCAL.placeVolume(barrel_csector_vol, 1, Transform3D(RotationY(180.0* dd4hep::deg),Translation3D(0, 0, 0))); - BarrelHCAL.placeVolume(barrel_csector_vol, 2, Transform3D(RotationZ(-sec_rot_angle*dd4hep::deg)*RotationY(180.0* dd4hep::deg),Translation3D(0, 0, 0))); - BarrelHCAL.placeVolume(barrel_er_vol, 0, Transform3D(RotationY(180.0* dd4hep::deg),Translation3D(0, 0, 0))); - BarrelHCAL.placeVolume(barrel_er_vol, 1, Transform3D(RotationY(0.0* dd4hep::deg),Translation3D(0, 0, 0))); + BarrelHCAL.placeVolume( + barrel_csector_vol, 0, + Transform3D(RotationZ(sec_rot_angle * dd4hep::deg) * RotationY(180.0 * dd4hep::deg), + Translation3D(0, 0, 0))); + BarrelHCAL.placeVolume(barrel_csector_vol, 1, + Transform3D(RotationY(180.0 * dd4hep::deg), Translation3D(0, 0, 0))); + BarrelHCAL.placeVolume( + barrel_csector_vol, 2, + Transform3D(RotationZ(-sec_rot_angle * dd4hep::deg) * RotationY(180.0 * dd4hep::deg), + Translation3D(0, 0, 0))); + BarrelHCAL.placeVolume(barrel_er_vol, 0, + Transform3D(RotationY(180.0 * dd4hep::deg), Translation3D(0, 0, 0))); + BarrelHCAL.placeVolume(barrel_er_vol, 1, + Transform3D(RotationY(0.0 * dd4hep::deg), Translation3D(0, 0, 0))); // Loop over the tile solids, create them and add them to the detector volume Volume Tile[12]; Volume ChimneyTile[4]; - for(int j=1; j<17; j++){ + for (int j = 1; j < 17; j++) { std::string gdmlname; std::string solid_name; - if(j<13){ + if (j < 13) { // standard tiles - gdmlname = _toString(j,"tile%d_gdmlfile"); - solid_name = _toString(j,"OuterHCalTile%02d"); + gdmlname = _toString(j, "tile%d_gdmlfile"); + solid_name = _toString(j, "OuterHCalTile%02d"); - } - else{ + } else { // chimney tiles - gdmlname = _toString(j-4,"ctile%d_gdmlfile"); - solid_name = _toString(j-4,"OuterHCalChimneyTile%02d"); - + gdmlname = _toString(j - 4, "ctile%d_gdmlfile"); + solid_name = _toString(j - 4, "OuterHCalChimneyTile%02d"); } // tile shape gdml file info xml_comp_t x_det_tgdmlfile = x_det.child(gdmlname); - std::string tgdml_file = getAttrOrDefault(x_det_tgdmlfile, _Unicode(file), " ");; - std::string tgdml_material = getAttrOrDefault(x_det_tgdmlfile, _Unicode(material), " "); - std::string tgdml_url = getAttrOrDefault(x_det_tgdmlfile, _Unicode(url), " "); + std::string tgdml_file = getAttrOrDefault(x_det_tgdmlfile, _Unicode(file), " "); + ; + std::string tgdml_material = + getAttrOrDefault(x_det_tgdmlfile, _Unicode(material), " "); + std::string tgdml_url = getAttrOrDefault(x_det_tgdmlfile, _Unicode(url), " "); std::string tgdml_cache = getAttrOrDefault(x_det_tgdmlfile, _Unicode(cache), " "); EnsureFileFromURLExists(tgdml_url, tgdml_file, tgdml_cache); if (!fs::exists(fs::path(tgdml_file))) { printout(ERROR, "BarrelHCalCalorimeter_geo", "file " + tgdml_file + " does not exist"); - printout(ERROR, "BarrelHCalCalorimeter_geo", "use a FileLoader plugin before the field element"); + printout(ERROR, "BarrelHCalCalorimeter_geo", + "use a FileLoader plugin before the field element"); std::_Exit(EXIT_FAILURE); } Volume solidVolume = parser.GDMLReadFile(tgdml_file.c_str()); - if(!solidVolume.isValid()){ + if (!solidVolume.isValid()) { printout(WARNING, "BarrelHCalCalorimeter_geo", "%s", tgdml_file.c_str()); printout(WARNING, "BarrelHCalCalorimeter_geo", "solidVolume invalid, GDML parser failed!"); std::_Exit(EXIT_FAILURE); @@ -308,19 +338,17 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s if (type == "OuterHCalTile" || type == "OuterHCalChimneyTile") { std::string stnum = solid_name.substr(solid_name.size() - 2, solid_name.size()); - int tnum = atoi(stnum.c_str()) - 1; + int tnum = atoi(stnum.c_str()) - 1; // Tile numbers are indexed by the center (eta=0) out, we want them starting zero at one end. if (type == "OuterHCalTile") { - Tile[11-tnum] = solidVolume; - - } - else if ((tnum > 7) && (type == "OuterHCalChimneyTile")) { + Tile[11 - tnum] = solidVolume; - ChimneyTile[11-tnum] = solidVolume; + } else if ((tnum > 7) && (type == "OuterHCalChimneyTile")) { + ChimneyTile[11 - tnum] = solidVolume; } } else @@ -332,13 +360,13 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // Place the tiles into the calorimeter volume - double increment_angle = (360.0/320.0)*dd4hep::deg; - double increment_offset = -10.01*increment_angle; + double increment_angle = (360.0 / 320.0) * dd4hep::deg; + double increment_offset = -10.01 * increment_angle; DetElement tile_det("eta0 phi0", det_id); sens.setType("calorimeter"); - for (int i_eta = 0; i_eta < 12; i_eta++) { // eta ring + for (int i_eta = 0; i_eta < 12; i_eta++) { // eta ring int tnum = 11 - i_eta; @@ -349,117 +377,126 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // ordinary sector tiles PlacedVolume phv1 = BarrelHCAL.placeVolume( - Tile[i_eta], i_phi + i_eta * 320, - RotationZ(i_phi * increment_angle + increment_offset) * - Transform3D(RotationY(90.0 * dd4hep::deg), - Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * - RotationX(-tilePlaneRotate * dd4hep::deg) * - Transform3D(RotationY(180.0 * dd4hep::deg), - Translation3D(-(xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, - yposTile[tnum] * dd4hep::mm, -zposTile[tnum] * dd4hep::mm))); - - phv1.addPhysVolID("eta",i_eta).addPhysVolID("phi",i_phi); - DetElement sd1 = tile_det.clone(_toString(i_eta, "eta%d ")+_toString(i_phi, "phi%d")); + Tile[i_eta], i_phi + i_eta * 320, + RotationZ(i_phi * increment_angle + increment_offset) * + Transform3D( + RotationY(90.0 * dd4hep::deg), + Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * + RotationX(-tilePlaneRotate * dd4hep::deg) * + Transform3D( + RotationY(180.0 * dd4hep::deg), + Translation3D(-(xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, + yposTile[tnum] * dd4hep::mm, -zposTile[tnum] * dd4hep::mm))); + + phv1.addPhysVolID("eta", i_eta).addPhysVolID("phi", i_phi); + DetElement sd1 = tile_det.clone(_toString(i_eta, "eta%d ") + _toString(i_phi, "phi%d")); sd1.setPlacement(phv1); sdet.add(sd1); PlacedVolume phv0 = BarrelHCAL.placeVolume( - Tile[i_eta], i_phi + (12 + tnum) * 320, - RotationZ(i_phi * increment_angle + increment_offset) * - Transform3D(RotationY(90.0 * dd4hep::deg), - Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * - RotationX(-tilePlaneRotate * dd4hep::deg) * - Translation3D((xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, - yposTile[tnum] * dd4hep::mm, zposTile[tnum] * dd4hep::mm)); - - phv0.addPhysVolID("eta",(12+tnum)).addPhysVolID("phi", i_phi); - DetElement sd0 = tile_det.clone(_toString((12+tnum), "eta%d ")+_toString(i_phi, "phi%d")); + Tile[i_eta], i_phi + (12 + tnum) * 320, + RotationZ(i_phi * increment_angle + increment_offset) * + Transform3D( + RotationY(90.0 * dd4hep::deg), + Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * + RotationX(-tilePlaneRotate * dd4hep::deg) * + Translation3D((xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, + yposTile[tnum] * dd4hep::mm, zposTile[tnum] * dd4hep::mm)); + + phv0.addPhysVolID("eta", (12 + tnum)).addPhysVolID("phi", i_phi); + DetElement sd0 = + tile_det.clone(_toString((12 + tnum), "eta%d ") + _toString(i_phi, "phi%d")); sd0.setPlacement(phv0); sdet.add(sd0); - } else { // first three sectors are chimney sectors - if(i_phi>29){ + if (i_phi > 29) { // ordinary sector tiles PlacedVolume phv1 = BarrelHCAL.placeVolume( - Tile[i_eta], i_phi + i_eta * 320, - RotationZ(i_phi * increment_angle + increment_offset) * - Transform3D(RotationY(90.0 * dd4hep::deg), - Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * - RotationX(-tilePlaneRotate * dd4hep::deg) * - Translation3D((xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, - yposTile[tnum] * dd4hep::mm, zposTile[tnum] * dd4hep::mm)); + Tile[i_eta], i_phi + i_eta * 320, + RotationZ(i_phi * increment_angle + increment_offset) * + Transform3D( + RotationY(90.0 * dd4hep::deg), + Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * + RotationX(-tilePlaneRotate * dd4hep::deg) * + Translation3D((xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, + yposTile[tnum] * dd4hep::mm, zposTile[tnum] * dd4hep::mm)); phv1.addPhysVolID("eta", i_eta).addPhysVolID("phi", i_phi); - DetElement sd1 = tile_det.clone(_toString(i_eta, "eta%d ")+_toString(i_phi, "phi%d")); + DetElement sd1 = tile_det.clone(_toString(i_eta, "eta%d ") + _toString(i_phi, "phi%d")); sd1.setPlacement(phv1); sdet.add(sd1); PlacedVolume phv0 = BarrelHCAL.placeVolume( - Tile[i_eta], i_phi + (12 + tnum) * 320, - RotationZ(i_phi * increment_angle + increment_offset) * - Transform3D(RotationY(90.0 * dd4hep::deg), - Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * - RotationX(-tilePlaneRotate * dd4hep::deg) * - Transform3D(RotationY(180.0 * dd4hep::deg), - Translation3D(-(xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, - yposTile[tnum] * dd4hep::mm, -zposTile[tnum] * dd4hep::mm))); + Tile[i_eta], i_phi + (12 + tnum) * 320, + RotationZ(i_phi * increment_angle + increment_offset) * + Transform3D( + RotationY(90.0 * dd4hep::deg), + Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * + RotationX(-tilePlaneRotate * dd4hep::deg) * + Transform3D( + RotationY(180.0 * dd4hep::deg), + Translation3D(-(xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, + yposTile[tnum] * dd4hep::mm, -zposTile[tnum] * dd4hep::mm))); phv0.addPhysVolID("eta", (12 + tnum)).addPhysVolID("phi", i_phi); - DetElement sd0 = tile_det.clone(_toString((12+tnum), "eta%d ")+_toString(i_phi, "phi%d")); + DetElement sd0 = + tile_det.clone(_toString((12 + tnum), "eta%d ") + _toString(i_phi, "phi%d")); sd0.setPlacement(phv0); sdet.add(sd0); - } - else{ + } else { // chimney sector tile PlacedVolume phv1 = BarrelHCAL.placeVolume( - ChimneyTile[i_eta], i_phi + (12 + tnum) * 320, - RotationZ(i_phi * increment_angle + increment_offset) * - Transform3D(RotationY(90.0 * dd4hep::deg), - Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * - RotationX(-tilePlaneRotate * dd4hep::deg) * - Translation3D((xposChimneyTileS[tnum-8] + (tnum + 1) * tile_tolerance) * dd4hep::mm, - yposChimneyTileS[tnum-8] * dd4hep::mm, zposChimneyTileS[tnum-8] * dd4hep::mm)); - + ChimneyTile[i_eta], i_phi + (12 + tnum) * 320, + RotationZ(i_phi * increment_angle + increment_offset) * + Transform3D( + RotationY(90.0 * dd4hep::deg), + Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * + RotationX(-tilePlaneRotate * dd4hep::deg) * + Translation3D((xposChimneyTileS[tnum - 8] + (tnum + 1) * tile_tolerance) * + dd4hep::mm, + yposChimneyTileS[tnum - 8] * dd4hep::mm, + zposChimneyTileS[tnum - 8] * dd4hep::mm)); phv1.addPhysVolID("eta", (12 + tnum)).addPhysVolID("phi", i_phi); - DetElement sd1 = tile_det.clone(_toString((12+tnum), "eta%d ")+_toString(i_phi, "phi%d")); + DetElement sd1 = + tile_det.clone(_toString((12 + tnum), "eta%d ") + _toString(i_phi, "phi%d")); sd1.setPlacement(phv1); sdet.add(sd1); PlacedVolume phv0 = BarrelHCAL.placeVolume( - Tile[i_eta], i_phi + i_eta * 320, - RotationZ(i_phi * increment_angle + increment_offset) * - Transform3D(RotationY(90.0 * dd4hep::deg), - Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * - RotationX(-tilePlaneRotate * dd4hep::deg) * - Translation3D((xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, - yposTile[tnum] * dd4hep::mm, zposTile[tnum] * dd4hep::mm)); + Tile[i_eta], i_phi + i_eta * 320, + RotationZ(i_phi * increment_angle + increment_offset) * + Transform3D( + RotationY(90.0 * dd4hep::deg), + Translation3D(xposOuter[0] * dd4hep::mm, yposOuter[0] * dd4hep::mm, 0.0)) * + RotationX(-tilePlaneRotate * dd4hep::deg) * + Translation3D((xposTile[tnum] + (tnum + 1) * tile_tolerance) * dd4hep::mm, + yposTile[tnum] * dd4hep::mm, zposTile[tnum] * dd4hep::mm)); phv0.addPhysVolID("eta", i_eta).addPhysVolID("phi", i_phi); - DetElement sd0 = tile_det.clone(_toString(i_eta, "eta%d ")+_toString(i_phi, "phi%d")); + DetElement sd0 = tile_det.clone(_toString(i_eta, "eta%d ") + _toString(i_phi, "phi%d")); sd0.setPlacement(phv0); sdet.add(sd0); - } - } } } // Place the detector into the envelope - envelope.placeVolume(BarrelHCAL, 0, Transform3D(RotationZ(0.0),Translation3D(0, 0, 0))); + envelope.placeVolume(BarrelHCAL, 0, Transform3D(RotationZ(0.0), Translation3D(0, 0, 0))); - std::string env_vis = getAttrOrDefault(x_det, _Unicode(env_vis), "HcalBarrelEnvelopeVis"); + std::string env_vis = + getAttrOrDefault(x_det, _Unicode(env_vis), "HcalBarrelEnvelopeVis"); envelope.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), env_vis); return sdet; } diff --git a/src/BarrelPlanarMPGDTracker_geo.cpp b/src/BarrelPlanarMPGDTracker_geo.cpp index 02f75c7a8..23231b8cb 100644 --- a/src/BarrelPlanarMPGDTracker_geo.cpp +++ b/src/BarrelPlanarMPGDTracker_geo.cpp @@ -37,21 +37,21 @@ using namespace dd4hep::rec; * - Detector is setup as a "tracker" so we can use the hits * */ -static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, + SensitiveDetector sens) { typedef vector Placements; - xml_det_t x_det = e; + xml_det_t x_det = e; // Material air = description.air(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - DetElement sdet(det_name, det_id); - map volumes; - map sensitives; + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + DetElement sdet(det_name, det_id); + map volumes; + map sensitives; map> volplane_surfaces; - PlacedVolume pv; - dd4hep::xml::Dimension dimensions(x_det.dimensions()); - xml_dim_t mpgd_pos = x_det.position(); - Assembly assembly(det_name); + PlacedVolume pv; + dd4hep::xml::Dimension dimensions(x_det.dimensions()); + xml_dim_t mpgd_pos = x_det.position(); + Assembly assembly(det_name); // Set detector type flag dd4hep::xml::setDetectorTypeFlag(x_det, sdet); @@ -60,7 +60,8 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, // Add the volume boundary material if configured for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) { xml_comp_t x_boundary_material = bmat; - DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, "boundary_material"); + DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, + "boundary_material"); } map> module_thicknesses; @@ -69,7 +70,7 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, // loop over the modules for (xml_coll_t mi(x_det, _U(module)); mi; ++mi) { xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); + string m_nam = x_mod.nameStr(); if (volumes.find(m_nam) != volumes.end()) { printout(ERROR, "BarrelPlanarMPGDTracker_geo", @@ -77,8 +78,8 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, throw runtime_error("Logics error in building modules."); } - int ncomponents = 0; - int sensor_number = 1; + int ncomponents = 0; + int sensor_number = 1; double total_thickness = 0; // Compute module total thickness from components @@ -113,13 +114,13 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, double max_component_length = 0; double gas_thickness = 0.0; for (xml_coll_t mci(x_mod, _U(module_component)); mci; ++mci, ++ncomponents) { - xml_comp_t x_comp = mci; - string c_nam = _toString(ncomponents, "component%d"); - string comp_name = x_comp.nameStr(); + xml_comp_t x_comp = mci; + string c_nam = _toString(ncomponents, "component%d"); + string comp_name = x_comp.nameStr(); double box_width = x_comp.width(); double box_length = x_comp.length(); - Box c_box; + Box c_box; // Since MPGD frames are layed over the MPGD foils, the foil material is pressent under the frame as well. // The gas volumes are not present under the frames, so our frames must eat only the gas module areas // @@ -149,7 +150,8 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "Not gas: %s", comp_name.c_str()); printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "box_comp_width: %f", x_comp.width()); printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "box_comp_length: %f", x_comp.length()); - printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "box_comp_thickness: %f", x_comp.thickness()); + printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "box_comp_thickness: %f", + x_comp.thickness()); } Volume c_vol{c_nam, c_box, description.material(x_comp.materialStr())}; @@ -185,8 +187,8 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, } // Now add-on the frame if (x_mod.hasChild(_U(frame))) { - xml_comp_t m_frame = x_mod.child(_U(frame)); - double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); + xml_comp_t m_frame = x_mod.child(_U(frame)); + double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); Box lframe_box{m_frame.width() / 2.0, (max_component_length + 2.0 * m_frame.width()) / 2.0, frame_thickness / 2.0}; @@ -209,16 +211,21 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "frame_thickness: %f", frame_thickness); printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "total_thickness: %f", total_thickness); - printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "frame_thickness + total_thickness: %f", frame_thickness + total_thickness); + printout(DEBUG, "BarrelPlanarMPGDTracker_geo", "frame_thickness + total_thickness: %f", + frame_thickness + total_thickness); m_vol.placeVolume(lframe_vol, Position(frame_width / 2.0 + max_component_width / 2, 0.0, - frame_thickness / 2.0 - total_thickness / 2.0 - gas_thickness / 2.0)); + frame_thickness / 2.0 - total_thickness / 2.0 - + gas_thickness / 2.0)); m_vol.placeVolume(rframe_vol, Position(-frame_width / 2.0 - max_component_width / 2.0, 0.0, - frame_thickness / 2.0 - total_thickness / 2.0 - gas_thickness / 2.0)); + frame_thickness / 2.0 - total_thickness / 2.0 - + gas_thickness / 2.0)); m_vol.placeVolume(tframe_vol, Position(0.0, frame_width / 2.0 + max_component_length / 2, - frame_thickness / 2.0 - total_thickness / 2.0 - gas_thickness / 2.0)); + frame_thickness / 2.0 - total_thickness / 2.0 - + gas_thickness / 2.0)); m_vol.placeVolume(bframe_vol, Position(0.0, -frame_width / 2.0 - max_component_length / 2.0, - frame_thickness / 2.0 - total_thickness / 2.0 - gas_thickness / 2.0)); + frame_thickness / 2.0 - total_thickness / 2.0 - + gas_thickness / 2.0)); } } @@ -227,14 +234,14 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, xml_comp_t x_layer = li; xml_comp_t x_layout = x_layer.child(_U(rphi_layout)); xml_comp_t z_layout = x_layer.child(_U(z_layout)); - int lay_id = x_layer.id(); - string m_nam = x_layer.moduleStr(); - string lay_nam = det_name + _toString(x_layer.id(), "_layer%d"); + int lay_id = x_layer.id(); + string m_nam = x_layer.moduleStr(); + string lay_nam = det_name + _toString(x_layer.id(), "_layer%d"); xml_comp_t envelope_tolerance = x_layer.child(_Unicode(envelope_tolerance), false); - double envelope_r_min = 0; - double envelope_r_max = 0; - double envelope_z_min = 0; - double envelope_z_max = 0; + double envelope_r_min = 0; + double envelope_r_max = 0; + double envelope_z_min = 0; + double envelope_z_max = 0; if (envelope_tolerance) { envelope_r_min = getAttrOrDefault(envelope_tolerance, _Unicode(r_min), 0); envelope_r_max = getAttrOrDefault(envelope_tolerance, _Unicode(r_max), 0); @@ -245,7 +252,7 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, double phi0 = x_layout.phi0(); // starting phi of first module double phi_tilt = x_layout.phi_tilt(); // Phi tilit of module double rc = x_layout.rc(); // Radius of the module - int nphi = x_layout.nphi(); // Number of modules in phi + int nphi = x_layout.nphi(); // Number of modules in phi double rphi_dr = x_layout.dr(); // The delta radius of every other module double phi_incr = (2 * M_PI) / nphi; // Phi increment for one module double phic = phi0; // Phi of the module @@ -253,11 +260,12 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, double z_dr = z_layout.dr(); // Radial offest of modules in z double z0 = z_layout.z0(); // Sets how much overlap in z the nz modules have - Assembly layer_assembly(lay_nam); - Volume module_env = volumes[m_nam]; - DetElement lay_elt(sdet, lay_nam, lay_id); - Placements& sensVols = sensitives[m_nam]; - auto& layerParams = DD4hepDetectorHelper::ensureExtension(lay_elt); + Assembly layer_assembly(lay_nam); + Volume module_env = volumes[m_nam]; + DetElement lay_elt(sdet, lay_nam, lay_id); + Placements& sensVols = sensitives[m_nam]; + auto& layerParams = + DD4hepDetectorHelper::ensureExtension(lay_elt); pv = assembly.placeVolume(layer_assembly); pv.addPhysVolID("layer", lay_id); @@ -272,12 +280,14 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, double dy = z_dr * std::sin(phic + phi_tilt); // Deta y of module position // loop over the modules in z for (int j = 0; j < nz; j++) { - string module_name = _toString(module, "module%d"); + string module_name = _toString(module, "module%d"); DetElement mod_elt(lay_elt, module_name, module); - double mod_z = 0.5 * dimensions.length(); - double z_placement = mod_z - j * nz * mod_z; // z location for module placement - double z_offset = - z_placement > 0 ? -z0 / 2.0 : z0 / 2.0; // determine the amount of overlap in z the z nz modules have + double mod_z = 0.5 * dimensions.length(); + double z_placement = mod_z - j * nz * mod_z; // z location for module placement + double z_offset = + z_placement > 0 + ? -z0 / 2.0 + : z0 / 2.0; // determine the amount of overlap in z the z nz modules have Transform3D tr(RotationZYX(0.0, ((M_PI / 2) - phic - phi_tilt), -M_PI / 2), Position(xc, yc, mpgd_pos.z() + z_placement + z_offset)); // in x-y plane, @@ -286,7 +296,7 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, mod_elt.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_de(mod_elt, std::string("de_") + sens_pv.volume().name(), module); + DetElement comp_de(mod_elt, std::string("de_") + sens_pv.volume().name(), module); comp_de.setPlacement(sens_pv); } // increas module counter @@ -307,7 +317,8 @@ static Ref_t create_BarrelPlanarMPGDTracker_geo(Detector& description, xml_h e, for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) { xml_comp_t x_layer_material = lmat; - DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, "layer_material"); + DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, + "layer_material"); } } sdet.setAttributes(description, assembly, x_det.regionStr(), x_det.limitsStr(), x_det.visStr()); diff --git a/src/BarrelTrackerWithFrame_geo.cpp b/src/BarrelTrackerWithFrame_geo.cpp index c0d58bae5..e8fa910c0 100644 --- a/src/BarrelTrackerWithFrame_geo.cpp +++ b/src/BarrelTrackerWithFrame_geo.cpp @@ -44,17 +44,16 @@ using namespace dd4hep::detail; * * @author Whitney Armstrong */ -static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, SensitiveDetector sens) { typedef vector Placements; - xml_det_t x_det = e; - Material air = description.air(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - DetElement sdet(det_name, det_id); - - map volumes; - map sensitives; + xml_det_t x_det = e; + Material air = description.air(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + DetElement sdet(det_name, det_id); + + map volumes; + map sensitives; map> volplane_surfaces; map> module_thicknesses; @@ -62,14 +61,13 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi // Set detector type flag dd4hep::xml::setDetectorTypeFlag(x_det, sdet); - auto ¶ms = DD4hepDetectorHelper::ensureExtension( - sdet); + auto& params = DD4hepDetectorHelper::ensureExtension(sdet); // Add the volume boundary material if configured for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) { xml_comp_t x_boundary_material = bmat; DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, - "boundary_material"); + "boundary_material"); } // dd4hep::xml::Dimension dimensions(x_det.dimensions()); @@ -81,27 +79,29 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi // Loop over the suports for (xml_coll_t su(x_det, _U(support)); su; ++su) { - xml_comp_t x_support = su; - double support_thickness = getAttrOrDefault(x_support, _U(thickness), 2.0 * mm); - double support_length = getAttrOrDefault(x_support, _U(length), 2.0 * mm); - double support_rmin = getAttrOrDefault(x_support, _U(rmin), 2.0 * mm); - double support_zstart = getAttrOrDefault(x_support, _U(zstart), 2.0 * mm); - std::string support_name = getAttrOrDefault(x_support, _Unicode(name), "support_tube"); - std::string support_vis = getAttrOrDefault(x_support, _Unicode(vis), "AnlRed"); - xml_dim_t pos(x_support.child(_U(position), false)); - xml_dim_t rot(x_support.child(_U(rotation), false)); - Solid support_solid; + xml_comp_t x_support = su; + double support_thickness = getAttrOrDefault(x_support, _U(thickness), 2.0 * mm); + double support_length = getAttrOrDefault(x_support, _U(length), 2.0 * mm); + double support_rmin = getAttrOrDefault(x_support, _U(rmin), 2.0 * mm); + double support_zstart = getAttrOrDefault(x_support, _U(zstart), 2.0 * mm); + std::string support_name = + getAttrOrDefault(x_support, _Unicode(name), "support_tube"); + std::string support_vis = getAttrOrDefault(x_support, _Unicode(vis), "AnlRed"); + xml_dim_t pos(x_support.child(_U(position), false)); + xml_dim_t rot(x_support.child(_U(rotation), false)); + Solid support_solid; if (x_support.hasChild(_U(shape))) { xml_comp_t shape(x_support.child(_U(shape))); - string shape_type = shape.typeStr(); - support_solid = xml::createShape(description, shape_type, shape); + string shape_type = shape.typeStr(); + support_solid = xml::createShape(description, shape_type, shape); } else { support_solid = Tube(support_rmin, support_rmin + support_thickness, support_length / 2); } - Transform3D tr = Transform3D(Rotation3D(), Position(0, 0, (support_zstart + support_length / 2))); + Transform3D tr = + Transform3D(Rotation3D(), Position(0, 0, (support_zstart + support_length / 2))); if (pos.ptr() && rot.ptr()) { Rotation3D rot3D(RotationZYX(rot.z(0), rot.y(0), rot.x(0))); - Position pos3D(pos.x(0), pos.y(0), pos.z(0)); + Position pos3D(pos.x(0), pos.y(0), pos.z(0)); tr = Transform3D(rot3D, pos3D); } else if (pos.ptr()) { tr = Transform3D(Rotation3D(), Position(pos.x(0), pos.y(0), pos.z(0))); @@ -110,7 +110,7 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi tr = Transform3D(rot3D, Position()); } Material support_mat = description.material(x_support.materialStr()); - Volume support_vol(support_name, support_solid, support_mat); + Volume support_vol(support_name, support_solid, support_mat); support_vol.setVisAttributes(description.visAttributes(support_vis)); pv = assembly.placeVolume(support_vol, tr); // pv = assembly.placeVolume(support_vol, Position(0, 0, support_zstart + support_length / 2)); @@ -119,7 +119,7 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi // loop over the modules for (xml_coll_t mi(x_det, _U(module)); mi; ++mi) { xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); + string m_nam = x_mod.nameStr(); if (volumes.find(m_nam) != volumes.end()) { printout(ERROR, "BarrelTrackerWithFrame", @@ -127,8 +127,8 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi throw runtime_error("Logics error in building modules."); } - int ncomponents = 0; - int sensor_number = 1; + int ncomponents = 0; + int sensor_number = 1; double total_thickness = 0; // Compute module total thickness from components @@ -154,33 +154,38 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi double frame_width2 = 2.0 * frame_height2 / tanth; Trd1 moduleframe_part1(frame_width / 2, 0.001 * mm, m_frame.length() / 2, frame_height / 2); - Trd1 moduleframe_part2(frame_width2 / 2, 0.001 * mm, m_frame.length() / 2 + 0.01 * mm, frame_height2 / 2); + Trd1 moduleframe_part2(frame_width2 / 2, 0.001 * mm, m_frame.length() / 2 + 0.01 * mm, + frame_height2 / 2); - SubtractionSolid moduleframe(moduleframe_part1, moduleframe_part2, Position(0.0, frame_thickness, 0.0)); - Volume v_moduleframe(m_nam + "_vol", moduleframe, description.material(m_frame.materialStr())); + SubtractionSolid moduleframe(moduleframe_part1, moduleframe_part2, + Position(0.0, frame_thickness, 0.0)); + Volume v_moduleframe(m_nam + "_vol", moduleframe, + description.material(m_frame.materialStr())); v_moduleframe.setVisAttributes(description, m_frame.visStr()); - m_vol.placeVolume(v_moduleframe, Position(0.0, 0.0, frame_height / 2 + total_thickness / 2.0)); + m_vol.placeVolume(v_moduleframe, + Position(0.0, 0.0, frame_height / 2 + total_thickness / 2.0)); } double thickness_so_far = 0.0; double thickness_sum = -total_thickness / 2.0; for (xml_coll_t mci(x_mod, _U(module_component)); mci; ++mci, ++ncomponents) { - xml_comp_t x_comp = mci; - xml_comp_t x_pos = x_comp.position(false); - xml_comp_t x_rot = x_comp.rotation(false); - const string c_nam = _toString(ncomponents, "component%d"); - Box c_box(x_comp.width() / 2, x_comp.length() / 2, x_comp.thickness() / 2); - Volume c_vol(c_nam, c_box, description.material(x_comp.materialStr())); + xml_comp_t x_comp = mci; + xml_comp_t x_pos = x_comp.position(false); + xml_comp_t x_rot = x_comp.rotation(false); + const string c_nam = _toString(ncomponents, "component%d"); + Box c_box(x_comp.width() / 2, x_comp.length() / 2, x_comp.thickness() / 2); + Volume c_vol(c_nam, c_box, description.material(x_comp.materialStr())); // Utility variable for the relative z-offset based off the previous components const double zoff = thickness_sum + x_comp.thickness() / 2.0; if (x_pos && x_rot) { - Position c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff); + Position c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff); RotationZYX c_rot(x_rot.z(0), x_rot.y(0), x_rot.x(0)); pv = m_vol.placeVolume(c_vol, Transform3D(c_rot, c_pos)); } else if (x_rot) { Position c_pos(0, 0, zoff); - pv = m_vol.placeVolume(c_vol, Transform3D(RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)), c_pos)); + pv = m_vol.placeVolume(c_vol, + Transform3D(RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)), c_pos)); } else if (x_pos) { pv = m_vol.placeVolume(c_vol, Position(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff)); } else { @@ -233,18 +238,18 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi xml_comp_t x_barrel = x_layer.child(_U(barrel_envelope)); xml_comp_t x_layout = x_layer.child(_U(rphi_layout)); xml_comp_t z_layout = x_layer.child(_U(z_layout)); // Get the element. - int lay_id = x_layer.id(); - string m_nam = x_layer.moduleStr(); - string lay_nam = det_name + _toString(x_layer.id(), "_layer%d"); - Tube lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2.0); - Volume lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume. - Position lay_pos(0, 0, getAttrOrDefault(x_barrel, _U(z0), 0.)); + int lay_id = x_layer.id(); + string m_nam = x_layer.moduleStr(); + string lay_nam = det_name + _toString(x_layer.id(), "_layer%d"); + Tube lay_tub(x_barrel.inner_r(), x_barrel.outer_r(), x_barrel.z_length() / 2.0); + Volume lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume. + Position lay_pos(0, 0, getAttrOrDefault(x_barrel, _U(z0), 0.)); lay_vol.setVisAttributes(description.visAttributes(x_layer.visStr())); double phi0 = x_layout.phi0(); // Starting phi of first module. double phi_tilt = x_layout.phi_tilt(); // Phi tilt of a module. double rc = x_layout.rc(); // Radius of the module center. - int nphi = x_layout.nphi(); // Number of modules in phi. + int nphi = x_layout.nphi(); // Number of modules in phi. double rphi_dr = x_layout.dr(); // The delta radius of every other module. double phi_incr = (M_PI * 2) / nphi; // Phi increment for one module. double phic = phi0; // Phi of the module center. @@ -252,19 +257,19 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi double nz = z_layout.nz(); // Number of modules to place in z. double z_dr = z_layout.dr(); // Radial displacement parameter, of every other module. - Volume module_env = volumes[m_nam]; - DetElement lay_elt(sdet, lay_nam, lay_id); + Volume module_env = volumes[m_nam]; + DetElement lay_elt(sdet, lay_nam, lay_id); Placements& sensVols = sensitives[m_nam]; // the local coordinate systems of modules in dd4hep and acts differ // see http://acts.web.cern.ch/ACTS/latest/doc/group__DD4hepPlugins.html - auto &layerParams = - DD4hepDetectorHelper::ensureExtension( - lay_elt); + auto& layerParams = + DD4hepDetectorHelper::ensureExtension(lay_elt); for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) { xml_comp_t x_layer_material = lmat; - DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, "layer_material"); + DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, + "layer_material"); } // Z increment for module placement along Z axis. @@ -273,7 +278,7 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi double z_incr = nz > 1 ? (2.0 * z0) / (nz - 1) : 0.0; // Starting z for module placement along Z axis. double module_z = -z0; - int module = 1; + int module = 1; // Loop over the number of modules in phi. for (int ii = 0; ii < nphi; ii++) { @@ -284,20 +289,22 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi // Loop over the number of modules in z. for (int j = 0; j < nz; j++) { - string module_name = _toString(module, "module%d"); + string module_name = _toString(module, "module%d"); DetElement mod_elt(lay_elt, module_name, module); - Transform3D tr(RotationZYX(0, ((M_PI / 2) - phic - phi_tilt), -M_PI / 2), Position(x, y, module_z)); + Transform3D tr(RotationZYX(0, ((M_PI / 2) - phic - phi_tilt), -M_PI / 2), + Position(x, y, module_z)); pv = lay_vol.placeVolume(module_env, tr); pv.addPhysVolID("module", module); mod_elt.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_de(mod_elt, std::string("de_") + sens_pv.volume().name(), module); + DetElement comp_de(mod_elt, std::string("de_") + sens_pv.volume().name(), module); comp_de.setPlacement(sens_pv); - auto &comp_de_params = DD4hepDetectorHelper::ensureExtension(comp_de); + auto& comp_de_params = + DD4hepDetectorHelper::ensureExtension(comp_de); comp_de_params.set("axis_definitions", "XYZ"); // comp_de.setAttributes(description, sens_pv.volume(), x_layer.regionStr(), x_layer.limitsStr(), // xml_det_t(xmleles[m_nam]).visStr()); @@ -325,7 +332,8 @@ static Ref_t create_BarrelTrackerWithFrame(Detector& description, xml_h e, Sensi // Create the PhysicalVolume for the layer. pv = assembly.placeVolume(lay_vol, lay_pos); // Place layer in mother pv.addPhysVolID("layer", lay_id); // Set the layer ID. - lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr()); + lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), + x_layer.visStr()); lay_elt.setPlacement(pv); } sdet.setAttributes(description, assembly, x_det.regionStr(), x_det.limitsStr(), x_det.visStr()); diff --git a/src/BeamPipeChain_geo.cpp b/src/BeamPipeChain_geo.cpp index 61021384f..8da51d510 100644 --- a/src/BeamPipeChain_geo.cpp +++ b/src/BeamPipeChain_geo.cpp @@ -18,18 +18,17 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /* sens */) { using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Al = description.material("Aluminum"); - Material m_Vacuum = description.material("Vacuum"); - string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "BeamPipeVis"); - double thickness = getAttrOrDefault(x_det, _Unicode(wall_thickness), 0); + Assembly assembly(det_name + "_assembly"); + Material m_Al = description.material("Aluminum"); + Material m_Vacuum = description.material("Vacuum"); + string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "BeamPipeVis"); + double thickness = getAttrOrDefault(x_det, _Unicode(wall_thickness), 0); vector names; vector xCenters; @@ -40,67 +39,82 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector / vector rOuters2; // Grab info for beamline magnets - for( xml_coll_t pipe_coll(x_det, _Unicode(pipe)); pipe_coll; pipe_coll++ ) { // pipes + for (xml_coll_t pipe_coll(x_det, _Unicode(pipe)); pipe_coll; pipe_coll++) { // pipes - xml_comp_t pipe( pipe_coll ); + xml_comp_t pipe(pipe_coll); - names.push_back( getAttrOrDefault(pipe, _Unicode(name), "") ); + names.push_back(getAttrOrDefault(pipe, _Unicode(name), "")); // Vectors momentarily filled with zeros for pipes in between magnets - xCenters.push_back( getAttrOrDefault(pipe, _Unicode(xcenter), 0) ); - zCenters.push_back( getAttrOrDefault(pipe, _Unicode(zcenter), 0) ); - lengths.push_back( getAttrOrDefault(pipe, _Unicode(length), 0) ); - thetas.push_back( getAttrOrDefault(pipe, _Unicode(theta), 0) ); - rOuters1.push_back( getAttrOrDefault(pipe, _Unicode(rout1), 0) ); - rOuters2.push_back( getAttrOrDefault(pipe, _Unicode(rout2), 0) ); + xCenters.push_back(getAttrOrDefault(pipe, _Unicode(xcenter), 0)); + zCenters.push_back(getAttrOrDefault(pipe, _Unicode(zcenter), 0)); + lengths.push_back(getAttrOrDefault(pipe, _Unicode(length), 0)); + thetas.push_back(getAttrOrDefault(pipe, _Unicode(theta), 0)); + rOuters1.push_back(getAttrOrDefault(pipe, _Unicode(rout1), 0)); + rOuters2.push_back(getAttrOrDefault(pipe, _Unicode(rout2), 0)); } // Calculate parameters for connecting pipes in between magnets - for( uint pipeN = 0; pipeN < names.size(); pipeN++ ) { - - if( lengths[pipeN] > 0 ) { continue; } // pipe parameters already set to nonzero values - if( pipeN == 0 ) { continue; } // can't create pipe for an empty starting slot - if( (pipeN+1) == names.size() ) { continue; } // can't create pipe for an empty end slot - - double x = ( xCenters[pipeN-1] - lengths[pipeN-1]/2.*sin(thetas[pipeN-1]) + xCenters[pipeN+1] + lengths[pipeN+1]/2.*sin(thetas[pipeN+1]) ) / 2.; - double z = ( zCenters[pipeN-1] - lengths[pipeN-1]/2.*cos(thetas[pipeN-1]) + zCenters[pipeN+1] + lengths[pipeN+1]/2.*cos(thetas[pipeN+1]) ) / 2.; - double deltaX = (xCenters[pipeN-1] - lengths[pipeN-1]/2.*sin(thetas[pipeN-1])) - (xCenters[pipeN+1] + lengths[pipeN+1]/2.*sin(thetas[pipeN+1])); - double deltaZ = (zCenters[pipeN-1] - lengths[pipeN-1]/2.*cos(thetas[pipeN-1])) - (zCenters[pipeN+1] + lengths[pipeN+1]/2.*cos(thetas[pipeN+1])); - double l = sqrt( pow(deltaX, 2) + pow(deltaZ, 2) ); - double theta = atan( deltaX / deltaZ ); + for (uint pipeN = 0; pipeN < names.size(); pipeN++) { + + if (lengths[pipeN] > 0) { + continue; + } // pipe parameters already set to nonzero values + if (pipeN == 0) { + continue; + } // can't create pipe for an empty starting slot + if ((pipeN + 1) == names.size()) { + continue; + } // can't create pipe for an empty end slot + + double x = (xCenters[pipeN - 1] - lengths[pipeN - 1] / 2. * sin(thetas[pipeN - 1]) + + xCenters[pipeN + 1] + lengths[pipeN + 1] / 2. * sin(thetas[pipeN + 1])) / + 2.; + double z = (zCenters[pipeN - 1] - lengths[pipeN - 1] / 2. * cos(thetas[pipeN - 1]) + + zCenters[pipeN + 1] + lengths[pipeN + 1] / 2. * cos(thetas[pipeN + 1])) / + 2.; + double deltaX = (xCenters[pipeN - 1] - lengths[pipeN - 1] / 2. * sin(thetas[pipeN - 1])) - + (xCenters[pipeN + 1] + lengths[pipeN + 1] / 2. * sin(thetas[pipeN + 1])); + double deltaZ = (zCenters[pipeN - 1] - lengths[pipeN - 1] / 2. * cos(thetas[pipeN - 1])) - + (zCenters[pipeN + 1] + lengths[pipeN + 1] / 2. * cos(thetas[pipeN + 1])); + double l = sqrt(pow(deltaX, 2) + pow(deltaZ, 2)); + double theta = atan(deltaX / deltaZ); // Small air gap between connecting and magnet beam pipes to avoid G4 overlap errors - if( (theta != thetas[pipeN-1]) || (theta != thetas[pipeN+1]) ) { + if ((theta != thetas[pipeN - 1]) || (theta != thetas[pipeN + 1])) { l -= 0.5; } xCenters[pipeN] = x; zCenters[pipeN] = z; - lengths[pipeN] = l; - thetas[pipeN] = theta; - rOuters1[pipeN] = rOuters2[pipeN-1]; - rOuters2[pipeN] = rOuters1[pipeN+1]; + lengths[pipeN] = l; + thetas[pipeN] = theta; + rOuters1[pipeN] = rOuters2[pipeN - 1]; + rOuters2[pipeN] = rOuters1[pipeN + 1]; } // Add all pipes to the assembly - for( uint pipeN = 0; pipeN < xCenters.size(); pipeN++ ) { + for (uint pipeN = 0; pipeN < xCenters.size(); pipeN++) { - ConeSegment s_tube( lengths[pipeN] / 2.0, rOuters2[pipeN] - thickness, rOuters2[pipeN], rOuters1[pipeN] - thickness, rOuters1[pipeN] ); - ConeSegment s_vacuum( lengths[pipeN] / 2.0, 0, rOuters2[pipeN] - thickness, 0, rOuters1[pipeN] - thickness ); + ConeSegment s_tube(lengths[pipeN] / 2.0, rOuters2[pipeN] - thickness, rOuters2[pipeN], + rOuters1[pipeN] - thickness, rOuters1[pipeN]); + ConeSegment s_vacuum(lengths[pipeN] / 2.0, 0, rOuters2[pipeN] - thickness, 0, + rOuters1[pipeN] - thickness); Volume v_tube("v_tube_" + names[pipeN], s_tube, m_Al); Volume v_vacuum("v_vacuum_" + names[pipeN], s_vacuum, m_Vacuum); - v_tube.setVisAttributes(description.visAttributes( vis_name ) ); - - assembly.placeVolume(v_tube, Transform3D( RotationY(thetas[pipeN]), Position(xCenters[pipeN], 0, zCenters[pipeN]))); - assembly.placeVolume(v_vacuum, Transform3D( RotationY(thetas[pipeN]), Position(xCenters[pipeN], 0, zCenters[pipeN]))); + v_tube.setVisAttributes(description.visAttributes(vis_name)); + assembly.placeVolume(v_tube, Transform3D(RotationY(thetas[pipeN]), + Position(xCenters[pipeN], 0, zCenters[pipeN]))); + assembly.placeVolume(v_vacuum, Transform3D(RotationY(thetas[pipeN]), + Position(xCenters[pipeN], 0, zCenters[pipeN]))); } // Final placement auto pv_assembly = - description.pickMotherVolume(sdet).placeVolume( assembly, Position(0.0, 0.0, 0.0)); + description.pickMotherVolume(sdet).placeVolume(assembly, Position(0.0, 0.0, 0.0)); sdet.setPlacement(pv_assembly); diff --git a/src/CompositeTracker_geo.cpp b/src/CompositeTracker_geo.cpp index a9d8d75ab..6e9dafe54 100644 --- a/src/CompositeTracker_geo.cpp +++ b/src/CompositeTracker_geo.cpp @@ -18,26 +18,24 @@ using namespace dd4hep; using namespace dd4hep::detail; -static Ref_t create_element(Detector& description, xml_h e, Ref_t) -{ - xml_det_t x_det(e); +static Ref_t create_element(Detector& description, xml_h e, Ref_t) { + xml_det_t x_det(e); const std::string det_name = x_det.nameStr(); - DetElement sdet(det_name, x_det.id()); - Volume vol; - Position pos; + DetElement sdet(det_name, x_det.id()); + Volume vol; + Position pos; const bool usePos = x_det.hasChild(_U(position)); // Set detector type flag dd4hep::xml::setDetectorTypeFlag(x_det, sdet); - auto ¶ms = DD4hepDetectorHelper::ensureExtension( - sdet); + auto& params = DD4hepDetectorHelper::ensureExtension(sdet); // Add the volume boundary material if configured for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) { xml_comp_t x_boundary_material = bmat; DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, - "boundary_material"); + "boundary_material"); } if (usePos) { @@ -46,7 +44,7 @@ static Ref_t create_element(Detector& description, xml_h e, Ref_t) vol = Assembly(det_name); vol.setAttributes(description, x_det.regionStr(), x_det.limitsStr(), x_det.visStr()); - Volume mother = description.pickMotherVolume(sdet); + Volume mother = description.pickMotherVolume(sdet); PlacedVolume pv; if (usePos) { pv = mother.placeVolume(vol, pos); @@ -55,8 +53,8 @@ static Ref_t create_element(Detector& description, xml_h e, Ref_t) } sdet.setPlacement(pv); for (xml_coll_t c(x_det, _U(composite)); c; ++c) { - xml_dim_t component = c; - const std::string nam = component.nameStr(); + xml_dim_t component = c; + const std::string nam = component.nameStr(); description.declareParent(nam, sdet); } return sdet; diff --git a/src/CylindricalDipoleMagnet_geo.cpp b/src/CylindricalDipoleMagnet_geo.cpp index b8ea34dfc..33f931884 100644 --- a/src/CylindricalDipoleMagnet_geo.cpp +++ b/src/CylindricalDipoleMagnet_geo.cpp @@ -14,43 +14,41 @@ using namespace dd4hep; using namespace dd4hep::rec; using namespace ROOT::Math; -static Ref_t build_magnet(Detector& dtor, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t build_magnet(Detector& dtor, xml_h e, SensitiveDetector /* sens */) { xml_det_t x_det = e; - int det_id = x_det.id(); - string det_name = x_det.nameStr(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); xml_dim_t pos = x_det.child(_U(placement)); - double pos_x = pos.x(); - double pos_y = pos.y(); - double pos_z = pos.z(); - double pos_theta = pos.attr(_U(theta)); + double pos_x = pos.x(); + double pos_y = pos.y(); + double pos_z = pos.z(); + double pos_theta = pos.attr(_U(theta)); xml_dim_t dims = x_det.dimensions(); - double dim_r = dims.r(); - double dim_z = dims.z(); + double dim_r = dims.r(); + double dim_z = dims.z(); xml_dim_t apperture = x_det.child(_Unicode(apperture)); - double app_r = apperture.r(); - Material iron = dtor.material("Iron"); - + double app_r = apperture.r(); + Material iron = dtor.material("Iron"); DetElement sdet(det_name, det_id); - Assembly assembly(det_name + "_assembly"); + Assembly assembly(det_name + "_assembly"); const string module_name = "Quad_magnet"; - const string yoke_vis = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "FFMagnetVis"); + const string yoke_vis = + dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "FFMagnetVis"); sdet.setAttributes(dtor, assembly, x_det.regionStr(), x_det.limitsStr(), yoke_vis); // -- yoke - Tube yoke_tube(app_r, dim_r, 0.5 * dim_z); + Tube yoke_tube(app_r, dim_r, 0.5 * dim_z); Volume yoke_vol("yoke_vol", yoke_tube, iron); - auto yoke_pv = assembly.placeVolume(yoke_vol); + auto yoke_pv = assembly.placeVolume(yoke_vol); yoke_pv.addPhysVolID("element", 1); DetElement yoke_de(sdet, "yoke_de", 1); yoke_de.setPlacement(yoke_pv); yoke_de.setAttributes(dtor, yoke_vol, x_det.regionStr(), x_det.limitsStr(), yoke_vis); - // -- finishing steps auto final_pos = Transform3D(Translation3D(pos_x, pos_y, pos_z) * RotationY(pos_theta)); auto pv = dtor.pickMotherVolume(sdet).placeVolume(assembly, final_pos); diff --git a/src/CylindricalMagnetChain_geo.cpp b/src/CylindricalMagnetChain_geo.cpp index 57395b79a..607a575f9 100644 --- a/src/CylindricalMagnetChain_geo.cpp +++ b/src/CylindricalMagnetChain_geo.cpp @@ -20,41 +20,39 @@ using namespace dd4hep; using namespace dd4hep::rec; using namespace ROOT::Math; -static Ref_t create_magnet(Detector& description, xml_h e, SensitiveDetector /* sens */) -{ - xml_det_t x_det = e; - string det_name = x_det.nameStr(); +static Ref_t create_magnet(Detector& description, xml_h e, SensitiveDetector /* sens */) { + xml_det_t x_det = e; + string det_name = x_det.nameStr(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Iron = description.material("Iron"); - string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "FFMagnetVis"); + Assembly assembly(det_name + "_assembly"); + Material m_Iron = description.material("Iron"); + string vis_name = dd4hep::getAttrOrDefault(x_det, _Unicode(vis), "FFMagnetVis"); + for (xml_coll_t magnet_coll(x_det, _Unicode(magnet)); magnet_coll; magnet_coll++) { // magnets - for( xml_coll_t magnet_coll(x_det, _Unicode(magnet)); magnet_coll; magnet_coll++ ) { // magnets + xml_comp_t magnet(magnet_coll); - xml_comp_t magnet( magnet_coll ); - - string name = getAttrOrDefault(magnet, _Unicode(name), ""); - double x = getAttrOrDefault(magnet, _Unicode(x), 0); - double y = getAttrOrDefault(magnet, _Unicode(y), 0); - double z = getAttrOrDefault(magnet, _Unicode(z), 0); - double theta = getAttrOrDefault(magnet, _Unicode(theta), 0); + string name = getAttrOrDefault(magnet, _Unicode(name), ""); + double x = getAttrOrDefault(magnet, _Unicode(x), 0); + double y = getAttrOrDefault(magnet, _Unicode(y), 0); + double z = getAttrOrDefault(magnet, _Unicode(z), 0); + double theta = getAttrOrDefault(magnet, _Unicode(theta), 0); double length = getAttrOrDefault(magnet, _Unicode(length), 0); - double rin = getAttrOrDefault(magnet, _Unicode(rin), 0); - double rout = getAttrOrDefault(magnet, _Unicode(rout), 0); + double rin = getAttrOrDefault(magnet, _Unicode(rin), 0); + double rout = getAttrOrDefault(magnet, _Unicode(rout), 0); // -- yoke - Tube yoke_tube( rin, rout, 0.5 * length ); - Volume v_yoke( "v_yoke_" + name, yoke_tube, m_Iron ); + Tube yoke_tube(rin, rout, 0.5 * length); + Volume v_yoke("v_yoke_" + name, yoke_tube, m_Iron); - v_yoke.setVisAttributes(description.visAttributes( vis_name ) ); + v_yoke.setVisAttributes(description.visAttributes(vis_name)); - assembly.placeVolume(v_yoke, Transform3D( RotationY(theta), Position(x, y, z))); + assembly.placeVolume(v_yoke, Transform3D(RotationY(theta), Position(x, y, z))); } // Final placement auto pv_assembly = - description.pickMotherVolume(sdet).placeVolume( assembly, Position(0.0, 0.0, 0.0)); + description.pickMotherVolume(sdet).placeVolume(assembly, Position(0.0, 0.0, 0.0)); sdet.setPlacement(pv_assembly); diff --git a/src/DD4hepDetectorHelper.h b/src/DD4hepDetectorHelper.h index 0499c38b8..843c57619 100644 --- a/src/DD4hepDetectorHelper.h +++ b/src/DD4hepDetectorHelper.h @@ -10,11 +10,9 @@ #include "DD4hep/DetFactoryHelper.h" - namespace DD4hepDetectorHelper { -template -T& ensureExtension(dd4hep::DetElement& elt) { +template T& ensureExtension(dd4hep::DetElement& elt) { T* ext = elt.extension(false); if (ext == nullptr) { ext = new T(); @@ -39,11 +37,11 @@ inline void xmlToProtoSurfaceMaterial(const xml_comp_t& x_material, const auto n = std::distance(binTokens.begin(), binTokens.end()); if (n == 2) { // Fill the bins - auto bin = binTokens.begin(); + auto bin = binTokens.begin(); std::string bin0 = *(bin); std::string bin1 = *(++bin); - size_t nBins0 = x_material.attr("bins0"); - size_t nBins1 = x_material.attr("bins1"); + size_t nBins0 = x_material.attr("bins0"); + size_t nBins1 = x_material.attr("bins1"); // Add the material tags std::string btmSurface = baseTag + "_"s + mSurface; params.set(btmSurface, true); @@ -52,4 +50,4 @@ inline void xmlToProtoSurfaceMaterial(const xml_comp_t& x_material, } } -} // namespace DD4hepDetectorHelper +} // namespace DD4hepDetectorHelper diff --git a/src/DD4hep_GdmlDetector.cpp b/src/DD4hep_GdmlDetector.cpp index 707377b5e..be33c147d 100644 --- a/src/DD4hep_GdmlDetector.cpp +++ b/src/DD4hep_GdmlDetector.cpp @@ -39,40 +39,39 @@ using namespace dd4hep; #if ROOT_VERSION_CODE >= ROOT_VERSION(6, 13, 0) /// Factory to import subdetectors from GDML fragment -static Ref_t create_detector(Detector& description, xml_h e, Ref_t /* sens_det */) -{ +static Ref_t create_detector(Detector& description, xml_h e, Ref_t /* sens_det */) { using namespace dd4hep::detail; - xml_det_t x_det = e; - int id = x_det.hasAttr(_U(id)) ? x_det.id() : 0; - xml_dim_t x_pos(x_det.child(_U(position), false)); - xml_dim_t x_rot(x_det.child(_U(rotation), false)); - xml_dim_t x_gdml(x_det.child(_U(gdmlFile))); - xml_dim_t x_par(x_det.child(_U(parent))); - string name = x_det.nameStr(); - string par_nam = x_par.nameStr(); - string gdml = x_gdml.attr(_U(ref)); - string gdml_physvol = dd4hep::getAttrOrDefault(x_gdml, _Unicode(physvol), ""); - DetElement det_parent = description.detector(par_nam); + xml_det_t x_det = e; + int id = x_det.hasAttr(_U(id)) ? x_det.id() : 0; + xml_dim_t x_pos(x_det.child(_U(position), false)); + xml_dim_t x_rot(x_det.child(_U(rotation), false)); + xml_dim_t x_gdml(x_det.child(_U(gdmlFile))); + xml_dim_t x_par(x_det.child(_U(parent))); + string name = x_det.nameStr(); + string par_nam = x_par.nameStr(); + string gdml = x_gdml.attr(_U(ref)); + string gdml_physvol = dd4hep::getAttrOrDefault(x_gdml, _Unicode(physvol), ""); + DetElement det_parent = description.detector(par_nam); TGDMLParse parser; if (!gdml.empty() && gdml[0] == '/') { TUri uri(gdml.c_str()); gdml = uri.GetRelativePart(); } else { string path = xml::DocumentHandler::system_path(e, gdml); - TUri uri(path.c_str()); + TUri uri(path.c_str()); gdml = uri.GetRelativePart(); } if (!det_parent.isValid()) { except(name, "+++ Cannot access detector parent: %s", par_nam.c_str()); } DetElement sdet(name, id); - Volume volume = parser.GDMLReadFile(gdml.c_str()); + Volume volume = parser.GDMLReadFile(gdml.c_str()); if (!volume.isValid()) { except("ROOTGDMLParse", "+++ Failed to parse GDML file:%s", gdml.c_str()); } volume.import(); // We require the extensions in dd4hep. printout(INFO, "ROOTGDMLParse", "+++ Attach GDML volume %s", volume.name()); - Volume mother = det_parent.volume(); + Volume mother = det_parent.volume(); PlacedVolume pv; if (!gdml_physvol.empty()) { @@ -81,17 +80,18 @@ static Ref_t create_detector(Detector& description, xml_h e, Ref_t /* sens_det * printout(ERROR, "ROOTGDMLParse", "+++ Invalid gdml placed volume %s", gdml_physvol.c_str()); printout(ERROR, "ROOTGDMLParse", "+++ Valid top-level nodes are:"); volume->PrintNodes(); - except("ROOTGDMLParse", "+++ Failed to parse GDML file:%s for node:%s", gdml.c_str(), gdml_physvol.c_str()); + except("ROOTGDMLParse", "+++ Failed to parse GDML file:%s for node:%s", gdml.c_str(), + gdml_physvol.c_str()); } volume = node.volume(); } if (x_pos && x_rot) { - Rotation3D rot(RotationZYX(x_rot.z(), x_rot.y(), x_rot.x())); + Rotation3D rot(RotationZYX(x_rot.z(), x_rot.y(), x_rot.x())); Transform3D transform(rot, Position(x_pos.x(), x_pos.y(), x_pos.z())); pv = mother.placeVolume(volume, transform); } else if (x_rot) { - Rotation3D rot(RotationZYX(x_rot.z(), x_rot.y(), x_rot.x())); + Rotation3D rot(RotationZYX(x_rot.z(), x_rot.y(), x_rot.x())); Transform3D transform(rot, Position(0, 0, 0)); pv = mother.placeVolume(volume, transform); } else if (x_pos) { diff --git a/src/DIRC_geo.cpp b/src/DIRC_geo.cpp index d65bd9994..71af13add 100644 --- a/src/DIRC_geo.cpp +++ b/src/DIRC_geo.cpp @@ -15,23 +15,23 @@ using namespace std; using namespace dd4hep; -static dd4hep::Trap MakeTrap(const std::string& pName, double pZ, double pY, double pX, double pLTX); +static dd4hep::Trap MakeTrap(const std::string& pName, double pZ, double pY, double pX, + double pLTX); -static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) -{ +static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) { xml_det_t xml_det = e; // Detector element - string det_name = xml_det.nameStr(); - int det_id = xml_det.id(); + string det_name = xml_det.nameStr(); + int det_id = xml_det.id(); DetElement det(det_name, det_id); // Detector dimension, position, rotation xml_dim_t dirc_dim = xml_det.dimensions(); xml_dim_t dirc_pos = xml_det.position(); - double det_rmin = dirc_dim.rmin(); - double det_rmax = dirc_dim.rmax(); - double det_ravg = (det_rmin + det_rmax) / 2; + double det_rmin = dirc_dim.rmin(); + double det_rmax = dirc_dim.rmax(); + double det_ravg = (det_rmin + det_rmax) / 2; // Detector type sens.setType("tracker"); @@ -40,7 +40,8 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) Assembly det_volume("DIRC"); det_volume.setVisAttributes(desc.visAttributes(xml_det.visStr())); Transform3D det_tr(RotationY(0), Position(0.0, 0.0, dirc_pos.z())); - det.setPlacement(desc.pickMotherVolume(det).placeVolume(det_volume, det_tr).addPhysVolID("system", det_id)); + det.setPlacement( + desc.pickMotherVolume(det).placeVolume(det_volume, det_tr).addPhysVolID("system", det_id)); // Construct module xml_comp_t xml_module = xml_det.child(_U(module)); @@ -49,19 +50,19 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) dirc_module.setVisAttributes(desc.visAttributes(xml_module.visStr())); // Bar - xml_comp_t xml_bar = xml_module.child(_Unicode(bar)); - double bar_height = xml_bar.height(); - double bar_width = xml_bar.width(); - double bar_length = xml_bar.length(); - Box bar_box("bar_box", bar_height / 2, bar_width / 2, bar_length / 2); - Volume bar_vol("bar_vol", bar_box, desc.material(xml_bar.materialStr())); + xml_comp_t xml_bar = xml_module.child(_Unicode(bar)); + double bar_height = xml_bar.height(); + double bar_width = xml_bar.width(); + double bar_length = xml_bar.length(); + Box bar_box("bar_box", bar_height / 2, bar_width / 2, bar_length / 2); + Volume bar_vol("bar_vol", bar_box, desc.material(xml_bar.materialStr())); bar_vol.setVisAttributes(desc.visAttributes(xml_bar.visStr())); // Glue - xml_comp_t xml_glue = xml_module.child(_Unicode(glue)); - double glue_thickness = xml_glue.thickness(); - Box glue_box("glue_box", bar_height / 2, bar_width / 2, glue_thickness / 2); - Volume glue_vol("glue_vol", glue_box, desc.material(xml_glue.materialStr())); + xml_comp_t xml_glue = xml_module.child(_Unicode(glue)); + double glue_thickness = xml_glue.thickness(); + Box glue_box("glue_box", bar_height / 2, bar_width / 2, glue_thickness / 2); + Volume glue_vol("glue_vol", glue_box, desc.material(xml_glue.materialStr())); glue_vol.setVisAttributes(desc.visAttributes(xml_glue.visStr())); auto bar_repeat_y = xml_bar.attr(_Unicode(repeat_y)); @@ -71,31 +72,36 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) auto bar_assm_length = (bar_length + glue_thickness) * bar_repeat_z; // Mirror construction - xml_comp_t xml_mirror = xml_module.child(_Unicode(mirror)); - auto mirror_width = xml_mirror.width(); - auto mirror_height = xml_mirror.height(); - auto mirror_thickness = xml_mirror.thickness(); - Box mirror_box("mirror_box", mirror_height / 2, mirror_width / 2, mirror_thickness / 2); - Volume mirror_vol("mirror_vol", mirror_box, desc.material(xml_mirror.materialStr())); + xml_comp_t xml_mirror = xml_module.child(_Unicode(mirror)); + auto mirror_width = xml_mirror.width(); + auto mirror_height = xml_mirror.height(); + auto mirror_thickness = xml_mirror.thickness(); + Box mirror_box("mirror_box", mirror_height / 2, mirror_width / 2, mirror_thickness / 2); + Volume mirror_vol("mirror_vol", mirror_box, desc.material(xml_mirror.materialStr())); mirror_vol.setVisAttributes(desc.visAttributes(xml_mirror.visStr())); // Mirror optical surface - auto surfMgr = desc.surfaceManager(); - auto surf = surfMgr.opticalSurface("DIRC_MirrorOpticalSurface"); + auto surfMgr = desc.surfaceManager(); + auto surf = surfMgr.opticalSurface("DIRC_MirrorOpticalSurface"); SkinSurface skin(desc, det, Form("dirc_mirror_optical_surface"), surf, mirror_vol); skin.isValid(); // Envelope for bars + mirror - Box Envelope_box("Envelope_box", (mirror_height + 1*mm)/2, 5*(bar_width + 0.15*mm), 2*(bar_length + glue_thickness) + 0.5*mirror_thickness); + Box Envelope_box("Envelope_box", (mirror_height + 1 * mm) / 2, 5 * (bar_width + 0.15 * mm), + 2 * (bar_length + glue_thickness) + 0.5 * mirror_thickness); Volume Envelope_box_vol("Envelope_box_vol", Envelope_box, desc.material("AirOptical")); - dirc_module.placeVolume(Envelope_box_vol, Position(0, 0, 0.5*mirror_thickness)); + dirc_module.placeVolume(Envelope_box_vol, Position(0, 0, 0.5 * mirror_thickness)); for (int y_index = 0; y_index < bar_repeat_y; y_index++) { double y = 0.5 * bar_assm_width - 0.5 * bar_width - (bar_width + bar_gap) * y_index; for (int z_index = 0; z_index < bar_repeat_z; z_index++) { - double z = 0.5 * bar_assm_length - 0.5 * mirror_thickness - 0.5 * bar_length - (bar_length + glue_thickness) * z_index; - Envelope_box_vol.placeVolume(glue_vol, Position(0, y, z - 0.5 * (bar_length + glue_thickness))); - Envelope_box_vol.placeVolume(bar_vol, Position(0, y, z)).addPhysVolID("section", z_index).addPhysVolID("bar", y_index); + double z = 0.5 * bar_assm_length - 0.5 * mirror_thickness - 0.5 * bar_length - + (bar_length + glue_thickness) * z_index; + Envelope_box_vol.placeVolume(glue_vol, + Position(0, y, z - 0.5 * (bar_length + glue_thickness))); + Envelope_box_vol.placeVolume(bar_vol, Position(0, y, z)) + .addPhysVolID("section", z_index) + .addPhysVolID("bar", y_index); } } @@ -103,17 +109,17 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) Envelope_box_vol.placeVolume(mirror_vol, Position(0, 0, 0.5 * bar_assm_length)); // Prism variables - xml_comp_t xml_prism = xml_module.child(_Unicode(prism)); - double prism_angle = xml_prism.angle(); - double prism_width = xml_prism.width(); - double prism_length = xml_prism.length(); - double prism_short_edge = getAttrOrDefault(xml_prism, _Unicode(short_edge), 50 * mm); - double prism_long_edge = prism_short_edge + prism_length * tan(prism_angle); + xml_comp_t xml_prism = xml_module.child(_Unicode(prism)); + double prism_angle = xml_prism.angle(); + double prism_width = xml_prism.width(); + double prism_length = xml_prism.length(); + double prism_short_edge = getAttrOrDefault(xml_prism, _Unicode(short_edge), 50 * mm); + double prism_long_edge = prism_short_edge + prism_length * tan(prism_angle); // Lens variables - xml_comp_t xml_lens = xml_module.child(_Unicode(lens)); - double lens_shift = getAttrOrDefault(xml_lens, _Unicode(shift), 0 * mm); - double lens_width = getAttrOrDefault(xml_lens, _Unicode(width), 35 * mm); + xml_comp_t xml_lens = xml_module.child(_Unicode(lens)); + double lens_shift = getAttrOrDefault(xml_lens, _Unicode(shift), 0 * mm); + double lens_width = getAttrOrDefault(xml_lens, _Unicode(width), 35 * mm); double lens_thickness = getAttrOrDefault(xml_lens, _Unicode(thickness), 12 * mm); double lens_r1 = getAttrOrDefault(xml_lens, _Unicode(r1), 62 * mm); double lens_r2 = getAttrOrDefault(xml_lens, _Unicode(r2), 36 * mm); @@ -125,10 +131,13 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) double lens_min_thickness = 2.0 * mm; - double ztrans1 = -lens_thickness / 2. - sqrt(lens_r1 * lens_r1 - lens_radius * lens_radius) + lens_min_thickness; - double ztrans2 = -lens_thickness / 2. - sqrt(lens_r2 * lens_r2 - lens_radius * lens_radius) + lens_min_thickness * 2; + double ztrans1 = -lens_thickness / 2. - sqrt(lens_r1 * lens_r1 - lens_radius * lens_radius) + + lens_min_thickness; + double ztrans2 = -lens_thickness / 2. - sqrt(lens_r2 * lens_r2 - lens_radius * lens_radius) + + lens_min_thickness * 2; - Box lens_symm_box("lens_symm_box", 0.5 * prism_short_edge, 0.5 * lens_width, 0.5 * lens_thickness); + Box lens_symm_box("lens_symm_box", 0.5 * prism_short_edge, 0.5 * lens_width, + 0.5 * lens_thickness); Volume Envelope_lens_vol("Envelope_lens_vol", lens_symm_box, desc.material("AirOptical")); Tube lens_symm_tube(0, lens_radius, 0.5 * lens_thickness); @@ -136,15 +145,21 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) Sphere lens_sphere1(0, lens_r1); Sphere lens_sphere2(0, lens_r2); - IntersectionSolid lens_box("lens_box", lens_symm_box, lens_symm_box, Position(0, 0, -lens_min_thickness * 2)); - IntersectionSolid lens_tube("lens_tube", lens_symm_tube, lens_symm_box, Position(0, 0, lens_min_thickness * 2)); - UnionSolid lens_box_tube("lens_box_tube", lens_box, lens_tube); + IntersectionSolid lens_box("lens_box", lens_symm_box, lens_symm_box, + Position(0, 0, -lens_min_thickness * 2)); + IntersectionSolid lens_tube("lens_tube", lens_symm_tube, lens_symm_box, + Position(0, 0, lens_min_thickness * 2)); + UnionSolid lens_box_tube("lens_box_tube", lens_box, lens_tube); - IntersectionSolid lens_layer1_solid("lens_layer1_solid", lens_box_tube, lens_sphere1, Position(0, 0, -ztrans1)); - SubtractionSolid lens_layer23_solid("lens_layer23_solid", lens_box_tube, lens_sphere1, Position(0, 0, -ztrans1)); + IntersectionSolid lens_layer1_solid("lens_layer1_solid", lens_box_tube, lens_sphere1, + Position(0, 0, -ztrans1)); + SubtractionSolid lens_layer23_solid("lens_layer23_solid", lens_box_tube, lens_sphere1, + Position(0, 0, -ztrans1)); - IntersectionSolid lens_layer2_solid("lens_layer2_solid", lens_layer23_solid, lens_sphere2, Position(0, 0, -ztrans2)); - SubtractionSolid lens_layer3_solid("lens_layer3_solid", lens_layer23_solid, lens_sphere2, Position(0, 0, -ztrans2)); + IntersectionSolid lens_layer2_solid("lens_layer2_solid", lens_layer23_solid, lens_sphere2, + Position(0, 0, -ztrans2)); + SubtractionSolid lens_layer3_solid("lens_layer3_solid", lens_layer23_solid, lens_sphere2, + Position(0, 0, -ztrans2)); Volume lens_layer1_vol("lens_layer1_vol", lens_layer1_solid, desc.material(xml_lens.attr(_Unicode(material1)))); @@ -157,54 +172,57 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) lens_layer2_vol.setVisAttributes(desc.visAttributes(xml_lens.attr(_Unicode(vis2)))); lens_layer3_vol.setVisAttributes(desc.visAttributes(xml_lens.attr(_Unicode(vis3)))); - double lens_position_x = lens_shift; - double lens_position_z = -0.5 * (bar_assm_length + lens_thickness); + double lens_position_x = lens_shift; + double lens_position_z = -0.5 * (bar_assm_length + lens_thickness); - for(int y_index = 0; y_index < bar_repeat_y; y_index++) - { - double lens_position_y = y_index*lens_width - 0.5*(prism_width - lens_width); + for (int y_index = 0; y_index < bar_repeat_y; y_index++) { + double lens_position_y = y_index * lens_width - 0.5 * (prism_width - lens_width); - Position lens_position(lens_position_x, lens_position_y, lens_position_z); - dirc_module.placeVolume(Envelope_lens_vol, lens_position); - } + Position lens_position(lens_position_x, lens_position_y, lens_position_z); + dirc_module.placeVolume(Envelope_lens_vol, lens_position); + } Envelope_lens_vol.placeVolume(lens_layer1_vol); Envelope_lens_vol.placeVolume(lens_layer2_vol); Envelope_lens_vol.placeVolume(lens_layer3_vol); // Prism construction - Trap prism_trap = MakeTrap("prism_trap", prism_width, prism_length, prism_long_edge, prism_short_edge); + Trap prism_trap = + MakeTrap("prism_trap", prism_width, prism_length, prism_long_edge, prism_short_edge); Volume prism_vol("prism_vol", prism_trap, desc.material(xml_prism.materialStr())); prism_vol.setVisAttributes(desc.visAttributes(xml_prism.visStr())); - double prism_position_x = (prism_long_edge + prism_short_edge) / 4. - 0.5 * prism_short_edge + lens_shift; - double prism_position_z = -0.5 * (bar_assm_length + prism_length) - lens_thickness; + double prism_position_x = + (prism_long_edge + prism_short_edge) / 4. - 0.5 * prism_short_edge + lens_shift; + double prism_position_z = -0.5 * (bar_assm_length + prism_length) - lens_thickness; RotationX prism_rotation(M_PI / 2.); - Position prism_position(prism_position_x, 0, prism_position_z); + Position prism_position(prism_position_x, 0, prism_position_z); // Envelope for prism + mcp - double Envelope_trap_width = prism_width + 1*mm; - double Envelope_trap_length = prism_length + 1*mm; // mcp thickness is 1 mm - double Envelope_trap_short_edge = prism_short_edge + 1*mm; - double Envelope_trap_long_edge = Envelope_trap_short_edge + Envelope_trap_length * tan(prism_angle); + double Envelope_trap_width = prism_width + 1 * mm; + double Envelope_trap_length = prism_length + 1 * mm; // mcp thickness is 1 mm + double Envelope_trap_short_edge = prism_short_edge + 1 * mm; + double Envelope_trap_long_edge = + Envelope_trap_short_edge + Envelope_trap_length * tan(prism_angle); - Trap Envelope_trap = MakeTrap("Envelope_trap", Envelope_trap_width, Envelope_trap_length, Envelope_trap_long_edge, Envelope_trap_short_edge); - Position Envelope_trap_position(prism_position_x, 0, prism_position_z - 0.5*mm); + Trap Envelope_trap = MakeTrap("Envelope_trap", Envelope_trap_width, Envelope_trap_length, + Envelope_trap_long_edge, Envelope_trap_short_edge); + Position Envelope_trap_position(prism_position_x, 0, prism_position_z - 0.5 * mm); Volume Envelope_trap_vol("Envelope_trap_vol", Envelope_trap, desc.material("AirOptical")); dirc_module.placeVolume(Envelope_trap_vol, Transform3D(prism_rotation, Envelope_trap_position)); - Envelope_trap_vol.placeVolume(prism_vol, Position(0, 0.5*mm, 0)); + Envelope_trap_vol.placeVolume(prism_vol, Position(0, 0.5 * mm, 0)); // MCP variables - xml_comp_t xml_mcp = xml_module.child(_Unicode(mcp)); - double mcp_thickness = xml_mcp.thickness(); - double mcp_height = xml_mcp.height(); - double mcp_width = xml_mcp.width(); + xml_comp_t xml_mcp = xml_module.child(_Unicode(mcp)); + double mcp_thickness = xml_mcp.thickness(); + double mcp_height = xml_mcp.height(); + double mcp_width = xml_mcp.width(); // MCP construction - Box mcp_box("mcp_box", mcp_height / 2, mcp_width / 2, mcp_thickness / 2); + Box mcp_box("mcp_box", mcp_height / 2, mcp_width / 2, mcp_thickness / 2); Volume mcp_vol("mcp_vol", mcp_box, desc.material(xml_mcp.materialStr())); mcp_vol.setVisAttributes(desc.visAttributes(xml_mcp.visStr())).setSensitiveDetector(sens); @@ -215,8 +233,8 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) Envelope_trap_vol.placeVolume(mcp_vol, Transform3D(mcp_rotation, mcp_position)); // Place modules - const int module_repeat = xml_module.repeat(); - const double dphi = 2. * M_PI / module_repeat; + const int module_repeat = xml_module.repeat(); + const double dphi = 2. * M_PI / module_repeat; for (int i = 0; i < module_repeat; i++) { double phi = dphi * i; double x = det_ravg * cos(phi); @@ -232,18 +250,17 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) dirc_support.setVisAttributes(desc.visAttributes(xml_support.visStr())); // Rail - xml_comp_t xml_rail = xml_support.child(_Unicode(rail)); - xml_dim_t rail_pos = xml_rail.position(); - double rail_height = xml_rail.height(); - double rail_width2 = xml_rail.width(); - double rail_distance_to_chord2 = rail_width2/2 / tan(dphi/2); - double rail_distance_to_chord1 = rail_distance_to_chord2 - rail_height; - double rail_width1 = 2*rail_distance_to_chord1 * tan(dphi/2); - double rail_length = xml_rail.length(); - Trap rail_trap("rail_trap", rail_length / 2, 0, 0, - rail_height / 2, rail_width1 / 2, rail_width2 / 2, 0, - rail_height / 2, rail_width1 / 2, rail_width2 / 2, 0); - Volume rail_vol("rail_vol", rail_trap, desc.material(xml_rail.materialStr())); + xml_comp_t xml_rail = xml_support.child(_Unicode(rail)); + xml_dim_t rail_pos = xml_rail.position(); + double rail_height = xml_rail.height(); + double rail_width2 = xml_rail.width(); + double rail_distance_to_chord2 = rail_width2 / 2 / tan(dphi / 2); + double rail_distance_to_chord1 = rail_distance_to_chord2 - rail_height; + double rail_width1 = 2 * rail_distance_to_chord1 * tan(dphi / 2); + double rail_length = xml_rail.length(); + Trap rail_trap("rail_trap", rail_length / 2, 0, 0, rail_height / 2, rail_width1 / 2, + rail_width2 / 2, 0, rail_height / 2, rail_width1 / 2, rail_width2 / 2, 0); + Volume rail_vol("rail_vol", rail_trap, desc.material(xml_rail.materialStr())); rail_vol.setVisAttributes(desc.visAttributes(xml_rail.visStr())); // Place rail @@ -261,12 +278,11 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) det_volume.placeVolume(dirc_support, tr); } - return det; } -static dd4hep::Trap MakeTrap(const std::string& pName, double pZ, double pY, double pX, double pLTX) -{ +static dd4hep::Trap MakeTrap(const std::string& pName, double pZ, double pY, double pX, + double pLTX) { // Fixed Trap constructor. This function is a workaround of this bug: // https://github.com/AIDASoft/DD4hep/issues/850 // Should be used instead of dd4hep::Trap(pName, pZ, pY, pX, pLTX) constructor @@ -283,7 +299,8 @@ static dd4hep::Trap MakeTrap(const std::string& pName, double pZ, double pY, dou double fDx4 = fDx2; double fTalpha2 = fTalpha1; - return Trap(pName, fDz, fTthetaCphi, fTthetaSphi, fDy1, fDx1, fDx2, fTalpha1, fDy2, fDx3, fDx4, fTalpha2); + return Trap(pName, fDz, fTthetaCphi, fTthetaSphi, fDy1, fDx1, fDx2, fTalpha1, fDy2, fDx3, fDx4, + fTalpha2); } DECLARE_DETELEMENT(epic_DIRC, createDetector) diff --git a/src/DRICH_geo.cpp b/src/DRICH_geo.cpp index dccafaebf..afb889935 100644 --- a/src/DRICH_geo.cpp +++ b/src/DRICH_geo.cpp @@ -24,15 +24,14 @@ using namespace dd4hep; using namespace dd4hep::rec; // create the detector -static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens) -{ +static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens) { - xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - xml::Component dims = detElem.dimensions(); + xml::DetElement detElem = handle; + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + xml::Component dims = detElem.dimensions(); OpticalSurfaceManager surfMgr = desc.surfaceManager(); - DetElement det(detName, detID); + DetElement det(detName, detID); sens.setType("tracker"); // attributes, from compact file ============================================= @@ -158,7 +157,7 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec * - `cellMask` is defined such that a hit's `cellID & cellMask` is the corresponding sensor's unique ID */ std::vector sensorIDfields = {"pdu", "sipm", "sector"}; - const auto& readoutCoder = *desc.readout(readoutName).idSpec().decoder(); + const auto& readoutCoder = *desc.readout(readoutName).idSpec().decoder(); // determine `cellMask` based on `sensorIDfields` uint64_t cellMask = 0; for (const auto& idField : sensorIDfields) @@ -188,9 +187,9 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec // snout solids double boreDelta = vesselRmin1 - vesselRmin0; double snoutDelta = vesselRmax1 - vesselRmax0; - Cone vesselSnout(snoutLength / 2.0, vesselRmin0, vesselRmax0, vesselRmin0 + boreDelta * snoutLength / vesselLength, - vesselRmax1); - Cone gasvolSnout( + Cone vesselSnout(snoutLength / 2.0, vesselRmin0, vesselRmax0, + vesselRmin0 + boreDelta * snoutLength / vesselLength, vesselRmax1); + Cone gasvolSnout( /* note: `gasvolSnout` extends a bit into the tank, so it touches `gasvolTank` * - the extension distance is equal to the tank `windowThickness`, so the * length of `gasvolSnout` == length of `vesselSnout` @@ -203,39 +202,51 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec // tank solids: // - inner: cone along beamline // - outer: cone to back of sensor box, then fixed radius cylinder - Polycone vesselTank(0, 2 * M_PI, - /* rmin */ {vesselSnout.rMin2(), std::lerp(vesselSnout.rMin2(), vesselRmin1, (sensorboxLength - snoutLength) / tankLength), vesselRmin1}, - /* rmax */ {vesselSnout.rMax2(), vesselRmax2, vesselRmax2}, - /* z */ {-tankLength / 2.0, -tankLength / 2.0 + sensorboxLength - snoutLength, tankLength / 2.0}); - Polycone gasvolTank(0, 2 * M_PI, - /* rmin */ {gasvolSnout.rMin2(), std::lerp(gasvolSnout.rMin2(), vesselRmin1 + wallThickness, (sensorboxLength - snoutLength) / tankLength), vesselRmin1 + wallThickness}, - /* rmax */ {gasvolSnout.rMax2(), vesselRmax2 - wallThickness, vesselRmax2 - wallThickness}, - /* z */ {-tankLength / 2.0 + windowThickness, -tankLength / 2.0 + windowThickness + sensorboxLength - snoutLength, tankLength / 2.0 - windowThickness}); + Polycone vesselTank( + 0, 2 * M_PI, + /* rmin */ + {vesselSnout.rMin2(), + std::lerp(vesselSnout.rMin2(), vesselRmin1, (sensorboxLength - snoutLength) / tankLength), + vesselRmin1}, + /* rmax */ {vesselSnout.rMax2(), vesselRmax2, vesselRmax2}, + /* z */ + {-tankLength / 2.0, -tankLength / 2.0 + sensorboxLength - snoutLength, tankLength / 2.0}); + Polycone gasvolTank( + 0, 2 * M_PI, + /* rmin */ + {gasvolSnout.rMin2(), + std::lerp(gasvolSnout.rMin2(), vesselRmin1 + wallThickness, + (sensorboxLength - snoutLength) / tankLength), + vesselRmin1 + wallThickness}, + /* rmax */ {gasvolSnout.rMax2(), vesselRmax2 - wallThickness, vesselRmax2 - wallThickness}, + /* z */ + {-tankLength / 2.0 + windowThickness, + -tankLength / 2.0 + windowThickness + sensorboxLength - snoutLength, + tankLength / 2.0 - windowThickness}); // sensorbox solids double dphi = atan2(wallThickness, sensorboxRmax); // thickness only correct at Rmax - Tube vesselSensorboxTube(sensorboxRmin, sensorboxRmax, sensorboxLength / 2., - -sensorboxDphi / 2., sensorboxDphi / 2.); - Tube gasvolSensorboxTube(sensorboxRmin + wallThickness, sensorboxRmax - wallThickness, sensorboxLength / 2., - -sensorboxDphi / 2. + dphi, sensorboxDphi / 2. - dphi); + Tube vesselSensorboxTube(sensorboxRmin, sensorboxRmax, sensorboxLength / 2., -sensorboxDphi / 2., + sensorboxDphi / 2.); + Tube gasvolSensorboxTube(sensorboxRmin + wallThickness, sensorboxRmax - wallThickness, + sensorboxLength / 2., -sensorboxDphi / 2. + dphi, + sensorboxDphi / 2. - dphi); // union: snout + tank UnionSolid vesselUnion(vesselTank, vesselSnout, Position(0., 0., -vesselLength / 2.)); - UnionSolid gasvolUnion(gasvolTank, gasvolSnout, Position(0., 0., -vesselLength / 2. + windowThickness)); + UnionSolid gasvolUnion(gasvolTank, gasvolSnout, + Position(0., 0., -vesselLength / 2. + windowThickness)); // union: add sensorboxes for all sectors for (int isec = 0; isec < nSectors; isec++) { RotationZ sectorRotation((isec + 0.5) * 2 * M_PI / nSectors); - vesselUnion = UnionSolid(vesselUnion, vesselSensorboxTube, - Transform3D(sectorRotation, - Position(0., 0., -(snoutLength + sensorboxLength - 0.6) / 2.) - ) - ); - gasvolUnion = UnionSolid(gasvolUnion, gasvolSensorboxTube, - Transform3D(sectorRotation, - Position(0., 0., -(snoutLength + sensorboxLength) / 2. + windowThickness) - ) - ); + vesselUnion = UnionSolid( + vesselUnion, vesselSensorboxTube, + Transform3D(sectorRotation, Position(0., 0., -(snoutLength + sensorboxLength - 0.6) / 2.))); + gasvolUnion = UnionSolid( + gasvolUnion, gasvolSensorboxTube, + Transform3D(sectorRotation, + Position(0., 0., -(snoutLength + sensorboxLength) / 2. + windowThickness))); } // extra solids for `debugOptics` only @@ -279,12 +290,12 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec // place gas volume PlacedVolume gasvolPV = vesselVol.placeVolume(gasvolVol, Position(0, 0, 0)); - DetElement gasvolDE(det, "gasvol_de", 0); + DetElement gasvolDE(det, "gasvol_de", 0); gasvolDE.setPlacement(gasvolPV); // place mother volume (vessel) - Volume motherVol = desc.pickMotherVolume(det); - PlacedVolume vesselPV = motherVol.placeVolume(vesselVol, vesselPos); + Volume motherVol = desc.pickMotherVolume(det); + PlacedVolume vesselPV = motherVol.placeVolume(vesselVol, vesselPos); vesselPV.addPhysVolID("system", detID); det.setPlacement(vesselPV); @@ -298,10 +309,14 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec radiatorRmax + snoutDelta * aerogelThickness / snoutLength, radiatorRmin + boreDelta * (aerogelThickness + airgapThickness) / vesselLength, radiatorRmax + snoutDelta * (aerogelThickness + airgapThickness) / snoutLength); - Cone filterSolid(filterThickness / 2, radiatorRmin + boreDelta * (aerogelThickness + airgapThickness) / vesselLength, - radiatorRmax + snoutDelta * (aerogelThickness + airgapThickness) / snoutLength, - radiatorRmin + boreDelta * (aerogelThickness + airgapThickness + filterThickness) / vesselLength, - radiatorRmax + snoutDelta * (aerogelThickness + airgapThickness + filterThickness) / snoutLength); + Cone filterSolid( + filterThickness / 2, + radiatorRmin + boreDelta * (aerogelThickness + airgapThickness) / vesselLength, + radiatorRmax + snoutDelta * (aerogelThickness + airgapThickness) / snoutLength, + radiatorRmin + + boreDelta * (aerogelThickness + airgapThickness + filterThickness) / vesselLength, + radiatorRmax + + snoutDelta * (aerogelThickness + airgapThickness + filterThickness) / snoutLength); Volume aerogelVol(detName + "_aerogel", aerogelSolid, aerogelMat); Volume airgapVol(detName + "_airgap", airgapSolid, airgapMat); @@ -313,10 +328,10 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec // aerogel placement and surface properties // TODO [low-priority]: define skin properties for aerogel and filter // FIXME: radiatorPitch might not be working correctly (not yet used) - auto radiatorPos = Position(0., 0., radiatorFrontplane + 0.5 * aerogelThickness) + originFront; + auto radiatorPos = Position(0., 0., radiatorFrontplane + 0.5 * aerogelThickness) + originFront; auto aerogelPlacement = Translation3D(radiatorPos) * // re-center to originFront - RotationY(radiatorPitch); // change polar angle to specified pitch - auto aerogelPV = gasvolVol.placeVolume(aerogelVol, aerogelPlacement); + RotationY(radiatorPitch); // change polar angle to specified pitch + auto aerogelPV = gasvolVol.placeVolume(aerogelVol, aerogelPlacement); DetElement aerogelDE(det, "aerogel_de", 0); aerogelDE.setPlacement(aerogelPV); // SkinSurface aerogelSkin(desc, aerogelDE, "mirror_optical_surface", aerogelSurf, aerogelVol); @@ -326,18 +341,20 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec if (!debugOptics) { auto airgapPlacement = - Translation3D(radiatorPos) * // re-center to originFront - RotationY(radiatorPitch) * // change polar angle - Translation3D(0., 0., (aerogelThickness + airgapThickness) / 2.); // move to aerogel backplane + Translation3D(radiatorPos) * // re-center to originFront + RotationY(radiatorPitch) * // change polar angle + Translation3D(0., 0., + (aerogelThickness + airgapThickness) / 2.); // move to aerogel backplane auto airgapPV = gasvolVol.placeVolume(airgapVol, airgapPlacement); DetElement airgapDE(det, "airgap_de", 0); airgapDE.setPlacement(airgapPV); auto filterPlacement = - Translation3D(0., 0., airgapThickness) * // add an air gap - Translation3D(radiatorPos) * // re-center to originFront - RotationY(radiatorPitch) * // change polar angle - Translation3D(0., 0., (aerogelThickness + filterThickness) / 2.); // move to aerogel backplane + Translation3D(0., 0., airgapThickness) * // add an air gap + Translation3D(radiatorPos) * // re-center to originFront + RotationY(radiatorPitch) * // change polar angle + Translation3D(0., 0., + (aerogelThickness + filterThickness) / 2.); // move to aerogel backplane auto filterPV = gasvolVol.placeVolume(filterVol, filterPlacement); DetElement filterDE(det, "filter_de", 0); filterDE.setPlacement(filterPV); @@ -367,7 +384,7 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec continue; // sector rotation about z axis - RotationZ sectorRotation((isec + 0.5) * 2 * M_PI / nSectors); + RotationZ sectorRotation((isec + 0.5) * 2 * M_PI / nSectors); std::string secName = "sec" + std::to_string(isec); // BUILD MIRRORS ==================================================================== @@ -409,18 +426,19 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec // solid : create sphere at origin, with specified angular limits; // phi limits are increased to fill gaps (overlaps are cut away later) - Sphere mirrorSolid1(mirrorRadius, mirrorRadius + mirrorThickness, mirrorTheta1, mirrorTheta2, -40 * degree, - 40 * degree); + Sphere mirrorSolid1(mirrorRadius, mirrorRadius + mirrorThickness, mirrorTheta1, mirrorTheta2, + -40 * degree, 40 * degree); // mirror placement transformation (note: transformations are in reverse order) auto mirrorPos = Position(mirrorCenterX, 0., mirrorCenterZ) + originFront; - auto mirrorPlacement(Translation3D(mirrorPos) * // re-center to specified position - RotationY(-mirrorThetaRot) // rotate about vertical axis, to be within vessel radial walls + auto mirrorPlacement( + Translation3D(mirrorPos) * // re-center to specified position + RotationY(-mirrorThetaRot) // rotate about vertical axis, to be within vessel radial walls ); // cut overlaps with other sectors using "pie slice" wedges, to the extent specified // by `mirrorPhiw` - Tube pieSlice(0.01 * cm, vesselRmax2, tankLength / 2.0, -mirrorPhiw / 2.0, mirrorPhiw / 2.0); + Tube pieSlice(0.01 * cm, vesselRmax2, tankLength / 2.0, -mirrorPhiw / 2.0, mirrorPhiw / 2.0); IntersectionSolid mirrorSolid2(pieSlice, mirrorSolid1, mirrorPlacement); // mirror volume, attributes, and placement @@ -432,7 +450,8 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec // properties DetElement mirrorDE(det, "mirror_de_" + secName, isec); mirrorDE.setPlacement(mirrorPV); - SkinSurface mirrorSkin(desc, mirrorDE, "mirror_optical_surface_" + secName, mirrorSurf, mirrorVol); + SkinSurface mirrorSkin(desc, mirrorDE, "mirror_optical_surface_" + secName, mirrorSurf, + mirrorVol); mirrorSkin.isValid(); // reconstruction constants (w.r.t. IP) @@ -455,9 +474,12 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec // reconstruction constants auto sensorSphPos = Position(sensorSphCenterX, 0., sensorSphCenterZ) + originFront; auto sensorSphFinalCenter = sectorRotation * Position(xS, 0.0, zS); - desc.add(Constant("DRICH_sensor_sph_center_x_" + secName, std::to_string(sensorSphFinalCenter.x()))); - desc.add(Constant("DRICH_sensor_sph_center_y_" + secName, std::to_string(sensorSphFinalCenter.y()))); - desc.add(Constant("DRICH_sensor_sph_center_z_" + secName, std::to_string(sensorSphFinalCenter.z()))); + desc.add( + Constant("DRICH_sensor_sph_center_x_" + secName, std::to_string(sensorSphFinalCenter.x()))); + desc.add( + Constant("DRICH_sensor_sph_center_y_" + secName, std::to_string(sensorSphFinalCenter.y()))); + desc.add( + Constant("DRICH_sensor_sph_center_z_" + secName, std::to_string(sensorSphFinalCenter.z()))); if (isec == 0) desc.add(Constant("DRICH_sensor_sph_radius", std::to_string(sensorSphRadius))); @@ -543,8 +565,9 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec Box resinSolid(resinSide / 2., resinSide / 2., resinThickness / 2.); // embed pss solid in resin solid, by subtracting `pssSolid` from `resinSolid` - SubtractionSolid resinSolidEmbedded(resinSolid, pssSolid, - Transform3D(Translation3D(0., 0., (resinThickness - pssThickness) / 2. ))); + SubtractionSolid resinSolidEmbedded( + resinSolid, pssSolid, + Transform3D(Translation3D(0., 0., (resinThickness - pssThickness) / 2.))); /* NOTE: * Here we could add gaps (size=`DRICH_pixel_gap`) between the pixels @@ -590,20 +613,23 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec Assembly pduAssembly(detName + "_pdu_" + secName); double pduSensorPitch = resinSide + pduSensorGap; double pduSensorOffsetMax = pduSensorPitch * (pduNumSensors - 1) / 2.0; - int isipm = 0; - for(int sensorIx = 0; sensorIx < pduNumSensors; sensorIx++) { - for(int sensorIy = 0; sensorIy < pduNumSensors; sensorIy++) { + int isipm = 0; + for (int sensorIx = 0; sensorIx < pduNumSensors; sensorIx++) { + for (int sensorIy = 0; sensorIy < pduNumSensors; sensorIy++) { Assembly sensorAssembly(detName + "_sensor_" + secName); // placement transformations // - placement of objects in `sensorAssembly` - auto pssPlacement = Transform3D(Translation3D(0., 0., -pssThickness / 2.0)); // set assembly origin to pss outermost surface centroid + auto pssPlacement = Transform3D(Translation3D( + 0., 0., + -pssThickness / 2.0)); // set assembly origin to pss outermost surface centroid auto resinPlacement = Transform3D(Translation3D(0., 0., -resinThickness / 2.0)); // - placement of a `sensorAssembly` in `pduAssembly` - auto pduSensorOffsetX = sensorIx * pduSensorPitch - pduSensorOffsetMax; - auto pduSensorOffsetY = sensorIy * pduSensorPitch - pduSensorOffsetMax; - auto sensorAssemblyPlacement = Transform3D(Translation3D(pduSensorOffsetX, pduSensorOffsetY, 0.0)); + auto pduSensorOffsetX = sensorIx * pduSensorPitch - pduSensorOffsetMax; + auto pduSensorOffsetY = sensorIy * pduSensorPitch - pduSensorOffsetMax; + auto sensorAssemblyPlacement = + Transform3D(Translation3D(pduSensorOffsetX, pduSensorOffsetY, 0.0)); // placements auto pssPV = sensorAssembly.placeVolume(pssVol, pssPlacement); @@ -611,40 +637,50 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec pduAssembly.placeVolume(sensorAssembly, sensorAssemblyPlacement); // sensor readout // NOTE: follow `sensorIDfields` - pssPV.addPhysVolID("sector", isec).addPhysVolID("pdu", ipdu).addPhysVolID("sipm", isipm); + pssPV.addPhysVolID("sector", isec) + .addPhysVolID("pdu", ipdu) + .addPhysVolID("sipm", isipm); // sensor DetElement - auto sensorID = encodeSensorID(pssPV.volIDs()); - std::string sensorIDname = secName + "_pdu" + std::to_string(ipdu) + "_sipm" + std::to_string(isipm); + auto sensorID = encodeSensorID(pssPV.volIDs()); + std::string sensorIDname = + secName + "_pdu" + std::to_string(ipdu) + "_sipm" + std::to_string(isipm); DetElement pssDE(det, "sensor_de_" + sensorIDname, sensorID); pssDE.setPlacement(pssPV); // sensor surface properties if (!debugOptics || debugOpticsMode == 3) { - SkinSurface pssSkin(desc, pssDE, "sensor_optical_surface_" + sensorIDname, pssSurf, pssVol); + SkinSurface pssSkin(desc, pssDE, "sensor_optical_surface_" + sensorIDname, pssSurf, + pssVol); pssSkin.isValid(); } // obtain some parameters useful for optics, so we don't have to figure them out downstream // - sensor position: the centroid of the active SURFACE of the `pss` - auto pduOrigin = ROOT::Math::XYZPoint(0,0,0); - auto sensorPos = - Translation3D(vesselPos) * // position of vessel in world - pduAssemblyPlacement * // position of PDU in vessel - sensorAssemblyPlacement * // position of SiPM in PDU - pduOrigin; - auto pduPos = - Translation3D(vesselPos) * // position of vessel in world - pduAssemblyPlacement * // position of PDU in vessel - pduOrigin; + auto pduOrigin = ROOT::Math::XYZPoint(0, 0, 0); + auto sensorPos = Translation3D(vesselPos) * // position of vessel in world + pduAssemblyPlacement * // position of PDU in vessel + sensorAssemblyPlacement * // position of SiPM in PDU + pduOrigin; + auto pduPos = Translation3D(vesselPos) * // position of vessel in world + pduAssemblyPlacement * // position of PDU in vessel + pduOrigin; // - sensor surface basis: the orientation of the sensor surface // NOTE: all sensors of a single PDU have the same surface orientation, but to avoid // loss of generality downstream, define the basis for each sensor - auto normVector = [pduAssemblyPlacement] (Direction n) { + auto normVector = [pduAssemblyPlacement](Direction n) { return pduAssemblyPlacement * n; }; - auto sensorNormX = normVector(Direction{1., 0., 0.,}); - auto sensorNormY = normVector(Direction{0., 1., 0.,}); + auto sensorNormX = normVector(Direction{ + 1., + 0., + 0., + }); + auto sensorNormY = normVector(Direction{ + 0., + 1., + 0., + }); // geometry tests /* - to help ensure the optics geometry is correctly interpreted by the reconstruction, @@ -653,73 +689,89 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec * `sensorNormX`, `sensorNormY` is wrong and/or the tests need to be updated */ // - test: check if the sensor position is on the sensor sphere (corrected for PDU matrix offset) - auto distActual = std::sqrt((sensorPos-sensorSphFinalCenter).Mag2()); + auto distActual = std::sqrt((sensorPos - sensorSphFinalCenter).Mag2()); auto distExpected = std::hypot(pduSensorOffsetX, pduSensorOffsetY, sensorSphRadius); auto testOnSphere = distActual - distExpected; - if(std::abs(testOnSphere) > 1e-6) { - printout(ERROR, "DRICH_geo", "sensor %s failed on-sphere test; testOnSphere=%f", sensorIDname.c_str(), testOnSphere); + if (std::abs(testOnSphere) > 1e-6) { + printout(ERROR, "DRICH_geo", "sensor %s failed on-sphere test; testOnSphere=%f", + sensorIDname.c_str(), testOnSphere); throw std::runtime_error("dRICH sensor position test failed"); } // - test: check the orientation - Direction radialDir = Direction(pduPos) - sensorSphFinalCenter; // sensor sphere radius direction - auto sensorNormZ = sensorNormX.Cross(sensorNormY); // sensor surface normal - auto testOrtho = sensorNormX.Dot(sensorNormY); // zero, if x and y vectors are orthogonal - auto testRadial = radialDir.Cross(sensorNormZ).Mag2(); // zero, if surface normal is parallel to radial direction - auto testDirection = radialDir.Dot(sensorNormZ); // positive, if radial direction == sensor normal direction (outward) - if(std::abs(testOrtho)>1e-6 || std::abs(testRadial)>1e-6 || testDirection<=0) { - printout(ERROR, "DRICH_geo", "sensor %s failed orientation test", sensorIDname.c_str()); + Direction radialDir = + Direction(pduPos) - sensorSphFinalCenter; // sensor sphere radius direction + auto sensorNormZ = sensorNormX.Cross(sensorNormY); // sensor surface normal + auto testOrtho = + sensorNormX.Dot(sensorNormY); // zero, if x and y vectors are orthogonal + auto testRadial = + radialDir.Cross(sensorNormZ) + .Mag2(); // zero, if surface normal is parallel to radial direction + auto testDirection = radialDir.Dot( + sensorNormZ); // positive, if radial direction == sensor normal direction (outward) + if (std::abs(testOrtho) > 1e-6 || std::abs(testRadial) > 1e-6 || testDirection <= 0) { + printout(ERROR, "DRICH_geo", "sensor %s failed orientation test", + sensorIDname.c_str()); printout(ERROR, "DRICH_geo", " testOrtho = %f; should be zero", testOrtho); printout(ERROR, "DRICH_geo", " testRadial = %f; should be zero", testRadial); - printout(ERROR, "DRICH_geo", " testDirection = %f; should be positive", testDirection); + printout(ERROR, "DRICH_geo", " testDirection = %f; should be positive", + testDirection); throw std::runtime_error("dRICH sensor orientation test failed"); } // add these optics parameters to this sensor's parameter map auto pssVarMap = pssDE.extension(false); - if(pssVarMap == nullptr) { + if (pssVarMap == nullptr) { pssVarMap = new VariantParameters(); pssDE.addExtension(pssVarMap); } - auto addVecToMap = [pssVarMap] (std::string key, auto vec) { - pssVarMap->set(key+"_x", vec.x()); - pssVarMap->set(key+"_y", vec.y()); - pssVarMap->set(key+"_z", vec.z()); + auto addVecToMap = [pssVarMap](std::string key, auto vec) { + pssVarMap->set(key + "_x", vec.x()); + pssVarMap->set(key + "_y", vec.y()); + pssVarMap->set(key + "_z", vec.z()); }; addVecToMap("pos", sensorPos); addVecToMap("normX", sensorNormX); addVecToMap("normY", sensorNormY); printout(DEBUG, "DRICH_geo", "sensor %s:", sensorIDname.c_str()); - for(auto kv : pssVarMap->variantParameters) - printout(DEBUG, "DRICH_geo", " %s: %f", kv.first.c_str(), pssVarMap->get(kv.first)); + for (auto kv : pssVarMap->variantParameters) + printout(DEBUG, "DRICH_geo", " %s: %f", kv.first.c_str(), + pssVarMap->get(kv.first)); // increment SIPM number isipm++; - } } // end PDU SiPM matrix loop // front service volumes - Transform3D frontServiceTransformation = Transform3D(Translation3D(0., 0., -resinThickness)); - for(xml::Collection_t serviceElem(pduElem.child(_Unicode(frontservices)), _Unicode(service)); serviceElem; ++serviceElem) { + Transform3D frontServiceTransformation = + Transform3D(Translation3D(0., 0., -resinThickness)); + for (xml::Collection_t serviceElem(pduElem.child(_Unicode(frontservices)), + _Unicode(service)); + serviceElem; ++serviceElem) { auto serviceName = serviceElem.attr(_Unicode(name)); auto serviceSide = serviceElem.attr(_Unicode(side)); auto serviceThickness = serviceElem.attr(_Unicode(thickness)); - auto serviceMat = desc.material(serviceElem.attr(_Unicode(material))); - auto serviceVis = desc.visAttributes(serviceElem.attr(_Unicode(vis))); + auto serviceMat = desc.material(serviceElem.attr(_Unicode(material))); + auto serviceVis = desc.visAttributes(serviceElem.attr(_Unicode(vis))); Box serviceSolid(serviceSide / 2.0, serviceSide / 2.0, serviceThickness / 2.0); - Volume serviceVol(detName + "_" + serviceName + "_" + secName, serviceSolid, serviceMat); + Volume serviceVol(detName + "_" + serviceName + "_" + secName, serviceSolid, + serviceMat); serviceVol.setVisAttributes(serviceVis); - frontServiceTransformation = Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * frontServiceTransformation; + frontServiceTransformation = + Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * + frontServiceTransformation; pduAssembly.placeVolume(serviceVol, frontServiceTransformation); - frontServiceTransformation = Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * frontServiceTransformation; + frontServiceTransformation = + Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * + frontServiceTransformation; } // circuit board volumes auto boardsElem = pduElem.child(_Unicode(boards)); - auto boardsMat = desc.material(boardsElem.attr(_Unicode(material))); - auto boardsVis = desc.visAttributes(boardsElem.attr(_Unicode(vis))); + auto boardsMat = desc.material(boardsElem.attr(_Unicode(material))); + auto boardsVis = desc.visAttributes(boardsElem.attr(_Unicode(vis))); Transform3D backServiceTransformation; - for(xml::Collection_t boardElem(boardsElem, _Unicode(board)); boardElem; ++boardElem) { + for (xml::Collection_t boardElem(boardsElem, _Unicode(board)); boardElem; ++boardElem) { auto boardName = boardElem.attr(_Unicode(name)); auto boardWidth = boardElem.attr(_Unicode(width)); auto boardLength = boardElem.attr(_Unicode(length)); @@ -728,25 +780,34 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec Box boardSolid(boardWidth / 2.0, boardThickness / 2.0, boardLength / 2.0); Volume boardVol(detName + "_" + boardName + "+" + secName, boardSolid, boardsMat); boardVol.setVisAttributes(boardsVis); - auto boardTransformation = Translation3D(0., boardOffset, -boardLength / 2.0) * frontServiceTransformation; + auto boardTransformation = + Translation3D(0., boardOffset, -boardLength / 2.0) * frontServiceTransformation; pduAssembly.placeVolume(boardVol, boardTransformation); - if(boardName=="RDO") - backServiceTransformation = Translation3D(0., 0., -boardLength) * frontServiceTransformation; + if (boardName == "RDO") + backServiceTransformation = + Translation3D(0., 0., -boardLength) * frontServiceTransformation; } // back service volumes - for(xml::Collection_t serviceElem(pduElem.child(_Unicode(backservices)), _Unicode(service)); serviceElem; ++serviceElem) { + for (xml::Collection_t serviceElem(pduElem.child(_Unicode(backservices)), + _Unicode(service)); + serviceElem; ++serviceElem) { auto serviceName = serviceElem.attr(_Unicode(name)); auto serviceSide = serviceElem.attr(_Unicode(side)); auto serviceThickness = serviceElem.attr(_Unicode(thickness)); - auto serviceMat = desc.material(serviceElem.attr(_Unicode(material))); - auto serviceVis = desc.visAttributes(serviceElem.attr(_Unicode(vis))); + auto serviceMat = desc.material(serviceElem.attr(_Unicode(material))); + auto serviceVis = desc.visAttributes(serviceElem.attr(_Unicode(vis))); Box serviceSolid(serviceSide / 2.0, serviceSide / 2.0, serviceThickness / 2.0); - Volume serviceVol(detName + "_" + serviceName + "_" + secName, serviceSolid, serviceMat); + Volume serviceVol(detName + "_" + serviceName + "_" + secName, serviceSolid, + serviceMat); serviceVol.setVisAttributes(serviceVis); - backServiceTransformation = Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * backServiceTransformation; + backServiceTransformation = + Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * + backServiceTransformation; pduAssembly.placeVolume(serviceVol, backServiceTransformation); - backServiceTransformation = Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * backServiceTransformation; + backServiceTransformation = + Transform3D(Translation3D(0., 0., -serviceThickness / 2.0)) * + backServiceTransformation; } // place PDU assembly @@ -756,8 +817,8 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec ipdu++; } // end patch cuts - } // end phiGen loop - } // end thetaGen loop + } // end phiGen loop + } // end thetaGen loop // END SENSOR MODULE LOOP ------------------------ diff --git a/src/EcalLumiSpecWScFi_geo.cpp b/src/EcalLumiSpecWScFi_geo.cpp index 048ca9d78..db986e36a 100644 --- a/src/EcalLumiSpecWScFi_geo.cpp +++ b/src/EcalLumiSpecWScFi_geo.cpp @@ -15,34 +15,35 @@ using namespace std; using namespace dd4hep; // Definition of function to build the modules -static tuple build_specScFiCAL_module(const Detector& description, const xml::Component& mod_x, SensitiveDetector& sens); +static tuple build_specScFiCAL_module(const Detector& description, + const xml::Component& mod_x, + SensitiveDetector& sens); // Driver Function -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { sens.setType("calorimeter"); - xml_det_t x_det = e; - xml_comp_t x_mod = x_det.child( _Unicode(module) ); - string det_name = x_det.nameStr(); - int det_ID = x_det.id(); + xml_det_t x_det = e; + xml_comp_t x_mod = x_det.child(_Unicode(module)); + string det_name = x_det.nameStr(); + int det_ID = x_det.id(); - Material Air = description.material("Air"); + Material Air = description.material("Air"); // Create main detector element to be returned at the end - DetElement det( det_name, det_ID ); + DetElement det(det_name, det_ID); // Mother volume - Volume motherVol = description.pickMotherVolume( det ); + Volume motherVol = description.pickMotherVolume(det); // Detector assembly - Assembly assembly( det_name ); - assembly.setVisAttributes( description.visAttributes(x_det.attr(_Unicode(vis))) ); + Assembly assembly(det_name); + assembly.setVisAttributes(description.visAttributes(x_det.attr(_Unicode(vis)))); - double detSizeXY = getAttrOrDefault( x_det, _Unicode(sizeXY), 180*mm); - double detSizeZ = getAttrOrDefault( x_det, _Unicode(sizeZ), 180*mm); - int nmod_perlayer = getAttrOrDefault( x_det, _Unicode(nmod_perlayer), 3); - int nlayer = getAttrOrDefault( x_det, _Unicode(nlayer), 20); + double detSizeXY = getAttrOrDefault(x_det, _Unicode(sizeXY), 180 * mm); + double detSizeZ = getAttrOrDefault(x_det, _Unicode(sizeZ), 180 * mm); + int nmod_perlayer = getAttrOrDefault(x_det, _Unicode(nmod_perlayer), 3); + int nlayer = getAttrOrDefault(x_det, _Unicode(nlayer), 20); // Global detector position and resolution xml_comp_t pos = x_det.position(); @@ -51,59 +52,65 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s auto [modVol, modSize] = build_specScFiCAL_module(description, x_mod, sens); // Position of first module, layer from center of CAL - double mod_pos0 = -(detSizeXY/2.0) + (modSize.x()/2.0); - double layer_pos0 = -(detSizeZ/2.0) + (modSize.y()/2.0); + double mod_pos0 = -(detSizeXY / 2.0) + (modSize.x() / 2.0); + double layer_pos0 = -(detSizeZ / 2.0) + (modSize.y() / 2.0); - Box layerBox ( detSizeXY/2, modSize.y()/2, detSizeXY/2 ); - Volume layerVol( "layer", layerBox, Air); - layerVol.setVisAttributes( description.visAttributes(x_mod.attr(_Unicode(vis))) ); + Box layerBox(detSizeXY / 2, modSize.y() / 2, detSizeXY / 2); + Volume layerVol("layer", layerBox, Air); + layerVol.setVisAttributes(description.visAttributes(x_mod.attr(_Unicode(vis)))); //Fill layer with modules - for(int mod_id=0; mod_id< nmod_perlayer; mod_id++){ + for (int mod_id = 0; mod_id < nmod_perlayer; mod_id++) { //Build // to z-axis, then rotate - double mod_pos_z = 0.0*cm; - double mod_pos_y = 0.0*cm; - double mod_pos_x = mod_id*modSize.x() + mod_pos0; + double mod_pos_z = 0.0 * cm; + double mod_pos_y = 0.0 * cm; + double mod_pos_x = mod_id * modSize.x() + mod_pos0; - PlacedVolume modPV = layerVol.placeVolume( modVol, Position( mod_pos_x, mod_pos_y, mod_pos_z ) ); - modPV.addPhysVolID( "module", mod_id ); - }//imod-loop close + PlacedVolume modPV = layerVol.placeVolume(modVol, Position(mod_pos_x, mod_pos_y, mod_pos_z)); + modPV.addPhysVolID("module", mod_id); + } //imod-loop close - Box sectorBox( detSizeXY/2, detSizeXY/2, detSizeZ/2 ); - Volume sectorVol( det_name+"_sector", sectorBox, Air); - sectorVol.setVisAttributes( description.visAttributes(x_mod.attr(_Unicode(vis))) ); + Box sectorBox(detSizeXY / 2, detSizeXY / 2, detSizeZ / 2); + Volume sectorVol(det_name + "_sector", sectorBox, Air); + sectorVol.setVisAttributes(description.visAttributes(x_mod.attr(_Unicode(vis)))); //Fill sector with layers - for(int layer_id=0; layer_id< nlayer; layer_id++){ + for (int layer_id = 0; layer_id < nlayer; layer_id++) { - double lay_pos_z = -layer_id*modSize.y() - layer_pos0; - double lay_pos_y = 0.0*cm; - double lay_pos_x = 0.0*cm; - int orientation = layer_id%2==0; + double lay_pos_z = -layer_id * modSize.y() - layer_pos0; + double lay_pos_y = 0.0 * cm; + double lay_pos_x = 0.0 * cm; + int orientation = layer_id % 2 == 0; - RotationZYX lay_rot = RotationZYX( 0, 0, -90.0*degree); - if(orientation) lay_rot*=RotationY(-90.0*degree); + RotationZYX lay_rot = RotationZYX(0, 0, -90.0 * degree); + if (orientation) + lay_rot *= RotationY(-90.0 * degree); - PlacedVolume layPV = sectorVol.placeVolume( layerVol, Transform3D( lay_rot, Position( lay_pos_x, lay_pos_y, lay_pos_z ) ) ); - layPV.addPhysVolID( "layer", layer_id ).addPhysVolID( "orientation", orientation ); + PlacedVolume layPV = sectorVol.placeVolume( + layerVol, Transform3D(lay_rot, Position(lay_pos_x, lay_pos_y, lay_pos_z))); + layPV.addPhysVolID("layer", layer_id).addPhysVolID("orientation", orientation); - }//layer_id-loop close + } //layer_id-loop close // loop over sectors(top, bottom) - for( xml_coll_t si(x_det, _Unicode(sector)); si; si++) { + for (xml_coll_t si(x_det, _Unicode(sector)); si; si++) { - xml_comp_t x_sector( si ); - int sector_id = x_sector.id(); + xml_comp_t x_sector(si); + int sector_id = x_sector.id(); xml_comp_t sec_pos = x_sector.position(); xml_comp_t sec_rot = x_sector.rotation(); - PlacedVolume secPV = assembly.placeVolume( sectorVol, Transform3D( RotationZYX(sec_rot.z(), sec_rot.y(), sec_rot.x() ), Position( sec_pos.x(), sec_pos.y(), sec_pos.z() ) ) ); - secPV.addPhysVolID( "sector", sector_id ); - }// sectors + PlacedVolume secPV = assembly.placeVolume( + sectorVol, Transform3D(RotationZYX(sec_rot.z(), sec_rot.y(), sec_rot.x()), + Position(sec_pos.x(), sec_pos.y(), sec_pos.z()))); + secPV.addPhysVolID("sector", sector_id); + } // sectors // Place assembly into mother volume. Assembly is centered at origin - PlacedVolume detPV = motherVol.placeVolume( assembly, Transform3D( RotationZYX( rot.z(), rot.y(), rot.x() ), Position( pos.x(), pos.y(), pos.z() ) ) ); + PlacedVolume detPV = + motherVol.placeVolume(assembly, Transform3D(RotationZYX(rot.z(), rot.y(), rot.x()), + Position(pos.x(), pos.y(), pos.z()))); detPV.addPhysVolID("system", det_ID); // Connect to system ID det.setPlacement(detPV); @@ -111,87 +118,91 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s return det; } //Driver class close -static tuple build_specScFiCAL_module( const Detector& description, const xml::Component& mod_x, SensitiveDetector& sens){ +static tuple build_specScFiCAL_module(const Detector& description, + const xml::Component& mod_x, + SensitiveDetector& sens) { - //--------------------Module Setup--------------------------------------------------------------------- - double sx = mod_x.attr(_Unicode(sizex)); - double sy = mod_x.attr(_Unicode(sizey)); - double sz = mod_x.attr(_Unicode(sizez)); + //--------------------Module Setup--------------------------------------------------------------------- + double sx = mod_x.attr(_Unicode(sizex)); + double sy = mod_x.attr(_Unicode(sizey)); + double sz = mod_x.attr(_Unicode(sizez)); - Position modSize(sx, sy, sz); + Position modSize(sx, sy, sz); - Box modShape( modSize.x()/2.0, modSize.y()/2.0, modSize.z()/2.0 ); - auto modMat = description.material(mod_x.attr(_Unicode(material))); - Volume modVol("module_vol", modShape, modMat); + Box modShape(modSize.x() / 2.0, modSize.y() / 2.0, modSize.z() / 2.0); + auto modMat = description.material(mod_x.attr(_Unicode(material))); + Volume modVol("module_vol", modShape, modMat); - modVol.setVisAttributes(description.visAttributes(mod_x.attr(_Unicode(vis)))); - //----------------------------Scintillating fibers ----------------------------------------------------------- + modVol.setVisAttributes(description.visAttributes(mod_x.attr(_Unicode(vis)))); + //----------------------------Scintillating fibers ----------------------------------------------------------- - //fibers - auto fiber_tube = mod_x.child(_Unicode(fiber)); - auto fr = fiber_tube.attr(_Unicode(radius)); - auto fsx = fiber_tube.attr(_Unicode(spacex)); - auto fsy = fiber_tube.attr(_Unicode(spacey)); - auto fiberMat = description.material(fiber_tube.attr(_Unicode(material))); - Tube fiberShape(0., fr, modSize.z() / 2.0); - Volume fiberVol("fiber_vol", fiberShape, fiberMat); - fiberVol.setVisAttributes(description.visAttributes(fiber_tube.attr(_Unicode(vis)))); - fiberVol.setSensitiveDetector(sens); + //fibers + auto fiber_tube = mod_x.child(_Unicode(fiber)); + auto fr = fiber_tube.attr(_Unicode(radius)); + auto fsx = fiber_tube.attr(_Unicode(spacex)); + auto fsy = fiber_tube.attr(_Unicode(spacey)); + auto fiberMat = description.material(fiber_tube.attr(_Unicode(material))); + Tube fiberShape(0., fr, modSize.z() / 2.0); + Volume fiberVol("fiber_vol", fiberShape, fiberMat); + fiberVol.setVisAttributes(description.visAttributes(fiber_tube.attr(_Unicode(vis)))); + fiberVol.setSensitiveDetector(sens); - //double submod_sizexy = 2.0*fr; // size of square = diameter of tubes. - int num_submodX = int (modSize.x() / (2*fr + 2.0*fsx) ); - int num_submodY = int (modSize.y() / (2*fr + 2.0*fsy) ); + //double submod_sizexy = 2.0*fr; // size of square = diameter of tubes. + int num_submodX = int(modSize.x() / (2 * fr + 2.0 * fsx)); + int num_submodY = int(modSize.y() / (2 * fr + 2.0 * fsy)); - double submod_xpos0 = -modSize.x()/2.0 + fr + fsx; - double submod_ypos0 = -modSize.y()/2.0 + fr + fsy; - int nfibers = 0; + double submod_xpos0 = -modSize.x() / 2.0 + fr + fsx; + double submod_ypos0 = -modSize.y() / 2.0 + fr + fsy; + int nfibers = 0; - //Fiber Holder - auto fiberholder_x = mod_x.child(_Unicode(fiberholder)); - double fh_dz = 0.6*mm; //thickness of fiber holder + //Fiber Holder + auto fiberholder_x = mod_x.child(_Unicode(fiberholder)); + double fh_dz = 0.6 * mm; //thickness of fiber holder - double fh_outerbox_y = 2.0*fr + 2.0*fsy; - double fh_outerbox_x = 2.0*fr + 2.0*fsx; - Box fh_outerbox(fh_outerbox_x/2.0, fh_outerbox_y/2.0, fh_dz/2.0); + double fh_outerbox_y = 2.0 * fr + 2.0 * fsy; + double fh_outerbox_x = 2.0 * fr + 2.0 * fsx; + Box fh_outerbox(fh_outerbox_x / 2.0, fh_outerbox_y / 2.0, fh_dz / 2.0); - double fh_innerbox_y = 2.0*fr; - double fh_innerbox_x = 2.0*fr; - Box fh_innerbox(fh_innerbox_x/2.0, fh_innerbox_y/2.0, fh_dz/2.0); + double fh_innerbox_y = 2.0 * fr; + double fh_innerbox_x = 2.0 * fr; + Box fh_innerbox(fh_innerbox_x / 2.0, fh_innerbox_y / 2.0, fh_dz / 2.0); - SubtractionSolid fiberholder_solid(fh_outerbox, fh_innerbox, Position(0.0, 0.0,0.0)); - auto fiberholderMat = description.material(fiberholder_x.attr(_Unicode(material))); - Volume fiberholderVol("fiberholder_vol",fiberholder_solid, fiberholderMat); - fiberholderVol.setVisAttributes(description.visAttributes(fiberholder_x.attr(_Unicode(vis)))); + SubtractionSolid fiberholder_solid(fh_outerbox, fh_innerbox, Position(0.0, 0.0, 0.0)); + auto fiberholderMat = description.material(fiberholder_x.attr(_Unicode(material))); + Volume fiberholderVol("fiberholder_vol", fiberholder_solid, fiberholderMat); + fiberholderVol.setVisAttributes( + description.visAttributes(fiberholder_x.attr(_Unicode(vis)))); - int nfh = 0; + int nfh = 0; - //placement of fibers and fiberholder - for(int iy = 0; iy< num_submodY; iy++){ + //placement of fibers and fiberholder + for (int iy = 0; iy < num_submodY; iy++) { - for(int ix=0; ix< num_submodX; ix++){ + for (int ix = 0; ix < num_submodX; ix++) { - double submod_pos_x = submod_xpos0 + ix*(2.0*fr + 2.0*fsx); //mm - double submod_pos_y = submod_ypos0 + iy*(2.0*fr + 2.0*fsy); //mm - double submod_pos_z = 0*mm ; //mm + double submod_pos_x = submod_xpos0 + ix * (2.0 * fr + 2.0 * fsx); //mm + double submod_pos_y = submod_ypos0 + iy * (2.0 * fr + 2.0 * fsy); //mm + double submod_pos_z = 0 * mm; //mm - //placement of fiber - auto fiberPV = modVol.placeVolume(fiberVol, nfibers++, Position{submod_pos_x, submod_pos_y, submod_pos_z}); - fiberPV.addPhysVolID("fiber_x", ix+1).addPhysVolID("fiber_y", iy+1); + //placement of fiber + auto fiberPV = modVol.placeVolume(fiberVol, nfibers++, + Position{submod_pos_x, submod_pos_y, submod_pos_z}); + fiberPV.addPhysVolID("fiber_x", ix + 1).addPhysVolID("fiber_y", iy + 1); - //placement of fiber holder 6.6*cm apart c-to-c - int num_holders = 4; // which means 4 regions - double fh_pos_z0 = -1*(modSize.z()/2.0) + (fh_dz/2.0); + //placement of fiber holder 6.6*cm apart c-to-c + int num_holders = 4; // which means 4 regions + double fh_pos_z0 = -1 * (modSize.z() / 2.0) + (fh_dz / 2.0); - for(int iz=0; iz> module_thicknesses; @@ -43,7 +42,8 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // Add the volume boundary material if configured for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) { xml_comp_t x_boundary_material = bmat; - DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, "boundary_material"); + DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, + "boundary_material"); } Assembly assembly(det_name); @@ -54,11 +54,11 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // now build the envelope for the detector xml_comp_t x_layer = x_det.child(_Unicode(layer)); xml_comp_t envelope = x_layer.child(_Unicode(envelope), false); - int lay_id = x_layer.id(); - string l_nam = x_layer.moduleStr(); - string lay_nam = det_name + _toString(x_layer.id(), "_layer%d"); - Tube lay_tub(envelope.rmin(), envelope.rmax(), envelope.length() / 2.0); - Volume lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume. + int lay_id = x_layer.id(); + string l_nam = x_layer.moduleStr(); + string lay_nam = det_name + _toString(x_layer.id(), "_layer%d"); + Tube lay_tub(envelope.rmin(), envelope.rmax(), envelope.length() / 2.0); + Volume lay_vol(lay_nam, lay_tub, air); // Create the layer envelope volume. zPos = envelope.zstart(); Position lay_pos(0, 0, 0); lay_vol.setVisAttributes(description.visAttributes(x_layer.visStr())); @@ -67,11 +67,13 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // the local coordinate systems of modules in dd4hep and acts differ // see http://acts.web.cern.ch/ACTS/latest/doc/group__DD4hepPlugins.html - auto& layerParams = DD4hepDetectorHelper::ensureExtension(lay_elt); + auto& layerParams = + DD4hepDetectorHelper::ensureExtension(lay_elt); for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) { xml_comp_t x_layer_material = lmat; - DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, "layer_material"); + DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, + "layer_material"); } // dimensions of the modules (2x2 sensors) @@ -86,9 +88,9 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s xml_comp_t x_supp = x_det.child(_Unicode(support)); xml_comp_t x_supp_envelope = x_supp.child(_Unicode(envelope), false); - double total_thickness = 0; - xml_comp_t x_modFront = x_det.child(_Unicode(moduleFront)); - xml_comp_t x_modBack = x_det.child(_Unicode(moduleBack)); + double total_thickness = 0; + xml_comp_t x_modFront = x_det.child(_Unicode(moduleFront)); + xml_comp_t x_modBack = x_det.child(_Unicode(moduleBack)); // Compute module total thickness from components xml_coll_t ci(x_modFront, _U(module_component)); @@ -114,21 +116,23 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s float corner_x2 = xcoord - module_x / 2; float corner_y1 = ycoord + module_y / 2; float corner_y2 = ycoord - module_y / 2; - float maxRadius = std::max(std::max(std::hypot(corner_x1, corner_y1), std::hypot(corner_x2, corner_y2)), - std::max(std::hypot(corner_x1, corner_y2), std::hypot(corner_x2, corner_y1))); - float minRadius = std::min(std::min(std::hypot(corner_x1, corner_y1), std::hypot(corner_x2, corner_y2)), - std::min(std::hypot(corner_x1, corner_y2), std::hypot(corner_x2, corner_y1))); + float maxRadius = + std::max(std::max(std::hypot(corner_x1, corner_y1), std::hypot(corner_x2, corner_y2)), + std::max(std::hypot(corner_x1, corner_y2), std::hypot(corner_x2, corner_y1))); + float minRadius = + std::min(std::min(std::hypot(corner_x1, corner_y1), std::hypot(corner_x2, corner_y2)), + std::min(std::hypot(corner_x1, corner_y2), std::hypot(corner_x2, corner_y1))); if (maxRadius > envelope.rmax() || minRadius < envelope.rmin()) { continue; } - string module_name = Form("module%d_%d_%d", module, ix, iy); + string module_name = Form("module%d_%d_%d", module, ix, iy); DetElement mod_elt(lay_elt, module_name, module); // create individual sensor layers here string m_nam = Form("EndcapTOF_Module1_%d_%d", ix, iy); - int ncomponents = 0; + int ncomponents = 0; // the module assembly volume Assembly m_vol(m_nam); m_vol.setVisAttributes(description.visAttributes(x_modCurr.visStr())); @@ -137,24 +141,25 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s double thickness_sum = -total_thickness / 2.0; double thickness_carbonsupp = 0.0; for (xml_coll_t mci(x_modCurr, _U(module_component)); mci; ++mci, ++ncomponents) { - xml_comp_t x_comp = mci; - xml_comp_t x_pos = x_comp.position(false); - xml_comp_t x_rot = x_comp.rotation(false); - const string c_nam = Form("component_%d_%d", ix, iy); - Box c_box(x_comp.width() / 2, x_comp.length() / 2, x_comp.thickness() / 2); - Volume c_vol(c_nam, c_box, description.material(x_comp.materialStr())); + xml_comp_t x_comp = mci; + xml_comp_t x_pos = x_comp.position(false); + xml_comp_t x_rot = x_comp.rotation(false); + const string c_nam = Form("component_%d_%d", ix, iy); + Box c_box(x_comp.width() / 2, x_comp.length() / 2, x_comp.thickness() / 2); + Volume c_vol(c_nam, c_box, description.material(x_comp.materialStr())); if (x_comp.materialStr() == "CarbonFiber") { thickness_carbonsupp = x_comp.thickness(); } // Utility variable for the relative z-offset based off the previous components const double zoff = thickness_sum + x_comp.thickness() / 2.0; if (x_pos && x_rot) { - Position c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff); + Position c_pos(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff); RotationZYX c_rot(x_rot.z(0), x_rot.y(0), x_rot.x(0)); pv = m_vol.placeVolume(c_vol, Transform3D(c_rot, c_pos)); } else if (x_rot) { Position c_pos(0, 0, zoff); - pv = m_vol.placeVolume(c_vol, Transform3D(RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)), c_pos)); + pv = m_vol.placeVolume( + c_vol, Transform3D(RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)), c_pos)); } else if (x_pos) { pv = m_vol.placeVolume(c_vol, Position(x_pos.x(0), x_pos.y(0), x_pos.z(0) + zoff)); } else { @@ -168,7 +173,8 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s pv.addPhysVolID("idy", iy); c_vol.setSensitiveDetector(sens); module_thicknesses[m_nam] = {thickness_so_far + x_comp.thickness() / 2.0, - total_thickness - thickness_so_far - x_comp.thickness() / 2.0}; + total_thickness - thickness_so_far - + x_comp.thickness() / 2.0}; // -------- create a measurement plane for the tracking surface attched to the sensitive volume ----- Vector3D u(-1., 0., 0.); @@ -187,7 +193,8 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s DetElement comp_de(mod_elt, std::string("de_") + pv.volume().name(), module); comp_de.setPlacement(pv); - auto& comp_de_params = DD4hepDetectorHelper::ensureExtension(comp_de); + auto& comp_de_params = + DD4hepDetectorHelper::ensureExtension(comp_de); comp_de_params.set("axis_definitions", "XYZ"); volSurfaceList(comp_de)->push_back(surf); @@ -202,10 +209,13 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s } } - const string suppb_nam = Form("suppbar_%d_%d", ix, iy); //_toString(ncomponents, "component%d"); - Box suppb_box((module_x + module_spacing) / 2, thickness_carbonsupp / 2, x_supp_envelope.length() / 2); - Volume suppb_vol(suppb_nam, suppb_box, carbon); - Transform3D trsupp(RotationZYX(0, 0, 0), Position(xcoord, ycoord + module_y / 2 - module_overlap / 2, 0)); + const string suppb_nam = + Form("suppbar_%d_%d", ix, iy); //_toString(ncomponents, "component%d"); + Box suppb_box((module_x + module_spacing) / 2, thickness_carbonsupp / 2, + x_supp_envelope.length() / 2); + Volume suppb_vol(suppb_nam, suppb_box, carbon); + Transform3D trsupp(RotationZYX(0, 0, 0), + Position(xcoord, ycoord + module_y / 2 - module_overlap / 2, 0)); suppb_vol.setVisAttributes(description, "AnlGray"); pv = lay_vol.placeVolume(suppb_vol, trsupp); @@ -222,7 +232,8 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // Create the PhysicalVolume for the layer. pv = assembly.placeVolume(lay_vol, lay_pos); // Place layer in mother pv.addPhysVolID("layer", lay_id); // Set the layer ID. - lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr()); + lay_elt.setAttributes(description, lay_vol, x_layer.regionStr(), x_layer.limitsStr(), + x_layer.visStr()); lay_elt.setPlacement(pv); pv = description.pickMotherVolume(sdet).placeVolume(assembly, Position(0, 0, zPos)); diff --git a/src/FieldMapB.cpp b/src/FieldMapB.cpp index 377b0fe7a..9858da120 100644 --- a/src/FieldMapB.cpp +++ b/src/FieldMapB.cpp @@ -34,25 +34,21 @@ using namespace dd4hep; // implementation of the field map class FieldMapB : public dd4hep::CartesianField::Object { - enum FieldCoord { - BrBz, - BxByBz - }; - + enum FieldCoord { BrBz, BxByBz }; public: - FieldMapB(const std::string& field_type_str = "magnetic", const std::string& coord_type_str = "BrBz"); + FieldMapB(const std::string& field_type_str = "magnetic", + const std::string& coord_type_str = "BrBz"); void Configure(std::vector dimensions); void LoadMap(const std::string& map_file, float scale); - bool GetIndices(float R, float Z, int *idxR, int *idxZ, float *deltaR, float *deltaZ); - bool GetIndices(float X, float Y, float Z, int *idxX, int *idxY, int *idxZ, float *deltaX, float *deltaY, float *deltaZ); - void SetCoordTranslation(const Transform3D& tr) - { + bool GetIndices(float R, float Z, int* idxR, int* idxZ, float* deltaR, float* deltaZ); + bool GetIndices(float X, float Y, float Z, int* idxX, int* idxY, int* idxZ, float* deltaX, + float* deltaY, float* deltaZ); + void SetCoordTranslation(const Transform3D& tr) { coordTranslate = tr; coordTranslate_inv = tr.Inverse(); } - void SetFieldRotation(const Transform3D& tr) - { + void SetFieldRotation(const Transform3D& tr) { fieldRot = tr; fieldRot_inv = tr.Inverse(); } @@ -60,20 +56,20 @@ class FieldMapB : public dd4hep::CartesianField::Object { virtual void fieldComponents(const double* pos, double* field); private: - FieldCoord fieldCoord; // field coordinate type - Transform3D coordTranslate, coordTranslate_inv; // coord translation - Transform3D fieldRot, fieldRot_inv; // field rotation - std::vector steps, mins, maxs; // B map cell info - int ir, ix, iy, iz; // lookup indices - float idx_1_f, idx_2_f, idx_3_f; // transient float indicies - float dr, dx, dy, dz; // deltas for interpolation - std::vector>> Bvals_RZ; // B map values: {R}, {Z}, {Br,Bz} - std::vector>>> Bvals_XYZ; // B map values: {X}, {Y}, {Z}, {Bx,By,Bz} + FieldCoord fieldCoord; // field coordinate type + Transform3D coordTranslate, coordTranslate_inv; // coord translation + Transform3D fieldRot, fieldRot_inv; // field rotation + std::vector steps, mins, maxs; // B map cell info + int ir, ix, iy, iz; // lookup indices + float idx_1_f, idx_2_f, idx_3_f; // transient float indicies + float dr, dx, dy, dz; // deltas for interpolation + std::vector>> Bvals_RZ; // B map values: {R}, {Z}, {Br,Bz} + std::vector>>> + Bvals_XYZ; // B map values: {X}, {Y}, {Z}, {Bx,By,Bz} }; // constructor -FieldMapB::FieldMapB(const std::string& field_type_str, const std::string& coord_type_str) -{ +FieldMapB::FieldMapB(const std::string& field_type_str, const std::string& coord_type_str) { std::string ftype = field_type_str; for (auto& c : ftype) { c = tolower(c); @@ -86,42 +82,39 @@ FieldMapB::FieldMapB(const std::string& field_type_str, const std::string& coord field_type = CartesianField::ELECTRIC; } else { field_type = CartesianField::UNKNOWN; - printout(ERROR, "FieldMap","Unknown field type " + ftype); + printout(ERROR, "FieldMap", "Unknown field type " + ftype); } - if( coord_type_str.compare("BrBz") == 0 ) { // BrBz + if (coord_type_str.compare("BrBz") == 0) { // BrBz fieldCoord = FieldCoord::BrBz; - } - else { // BxByBz + } else { // BxByBz fieldCoord = FieldCoord::BxByBz; } } // fill field vector -void FieldMapB::Configure(std::vector dimensions) -{ +void FieldMapB::Configure(std::vector dimensions) { // Fill vectors with step size, min, max for each dimension - for( auto el : dimensions ) { - steps.push_back( el.step() ); - mins.push_back( getAttrOrDefault(el, _Unicode(min), 0) ); - maxs.push_back( getAttrOrDefault(el, _Unicode(max), 0) ); + for (auto el : dimensions) { + steps.push_back(el.step()); + mins.push_back(getAttrOrDefault(el, _Unicode(min), 0)); + maxs.push_back(getAttrOrDefault(el, _Unicode(max), 0)); } - if( fieldCoord == FieldCoord::BrBz ) { + if (fieldCoord == FieldCoord::BrBz) { // N bins increased by 1 beyond grid size to account for edge cases at upper limits - int nr = std::roundf( (maxs[0] - mins[0]) / steps[0] ) + 2; - int nz = std::roundf( (maxs[1] - mins[1]) / steps[1] ) + 2; + int nr = std::roundf((maxs[0] - mins[0]) / steps[0]) + 2; + int nz = std::roundf((maxs[1] - mins[1]) / steps[1]) + 2; Bvals_RZ.resize(nr); for (auto& B2 : Bvals_RZ) { B2.resize(nz); } - } - else { + } else { // N bins increased by 1 beyond grid size to account for edge cases at upper limits - int nx = std::roundf( (maxs[0] - mins[0]) / steps[0] ) + 2; - int ny = std::roundf( (maxs[1] - mins[1]) / steps[1] ) + 2; - int nz = std::roundf( (maxs[2] - mins[2]) / steps[2] ) + 2; + int nx = std::roundf((maxs[0] - mins[0]) / steps[0]) + 2; + int ny = std::roundf((maxs[1] - mins[1]) / steps[1]) + 2; + int nz = std::roundf((maxs[2] - mins[2]) / steps[2]) + 2; Bvals_XYZ.resize(nx); for (auto& B3 : Bvals_XYZ) { @@ -134,48 +127,46 @@ void FieldMapB::Configure(std::vector dimensions) } // get RZ cell indices corresponding to point of interest -bool FieldMapB::GetIndices(float R, float Z, int *idxR, int *idxZ, float *deltaR, float *deltaZ) -{ +bool FieldMapB::GetIndices(float R, float Z, int* idxR, int* idxZ, float* deltaR, float* deltaZ) { // boundary check - if( R > maxs[0] || R < mins[0] || Z > maxs[1] || Z < mins[1] ) { + if (R > maxs[0] || R < mins[0] || Z > maxs[1] || Z < mins[1]) { return false; } // get indices - *deltaR = std::modf( (R - mins[0]) / steps[0], &idx_1_f ); - *deltaZ = std::modf( (Z - mins[1]) / steps[1], &idx_2_f ); - *idxR = static_cast(idx_1_f); - *idxZ = static_cast(idx_2_f); + *deltaR = std::modf((R - mins[0]) / steps[0], &idx_1_f); + *deltaZ = std::modf((Z - mins[1]) / steps[1], &idx_2_f); + *idxR = static_cast(idx_1_f); + *idxZ = static_cast(idx_2_f); return true; } // get XYZ cell indices corresponding to point of interest -bool FieldMapB::GetIndices(float X, float Y, float Z, int *idxX, int *idxY, int *idxZ, float *deltaX, float *deltaY, float *deltaZ) -{ +bool FieldMapB::GetIndices(float X, float Y, float Z, int* idxX, int* idxY, int* idxZ, + float* deltaX, float* deltaY, float* deltaZ) { // boundary check - if( X > maxs[0] || X < mins[0] || Y > maxs[1] || Y < mins[1] || Z > maxs[2] || Z < mins[2] ) { + if (X > maxs[0] || X < mins[0] || Y > maxs[1] || Y < mins[1] || Z > maxs[2] || Z < mins[2]) { return false; } // get indices - *deltaX = std::modf( (X - mins[0]) / steps[0], &idx_1_f ); - *deltaY = std::modf( (Y - mins[1]) / steps[1], &idx_2_f ); - *deltaZ = std::modf( (Z - mins[2]) / steps[2], &idx_3_f ); - *idxX = static_cast(idx_1_f); - *idxY = static_cast(idx_2_f); - *idxZ = static_cast(idx_3_f); + *deltaX = std::modf((X - mins[0]) / steps[0], &idx_1_f); + *deltaY = std::modf((Y - mins[1]) / steps[1], &idx_2_f); + *deltaZ = std::modf((Z - mins[2]) / steps[2], &idx_3_f); + *idxX = static_cast(idx_1_f); + *idxY = static_cast(idx_2_f); + *idxZ = static_cast(idx_3_f); return true; } // load data -void FieldMapB::LoadMap(const std::string& map_file, float scale) -{ - std::string line; +void FieldMapB::LoadMap(const std::string& map_file, float scale) { + std::string line; std::ifstream input(map_file); - if( ! input ) { - printout(ERROR,"FieldMapB", "FieldMapB Error: file " + map_file + " cannot be read."); + if (!input) { + printout(ERROR, "FieldMapB", "FieldMapB Error: file " + map_file + " cannot be read."); } std::vector coord = {}; @@ -187,51 +178,45 @@ void FieldMapB::LoadMap(const std::string& map_file, float scale) coord.clear(); Bcomp.clear(); - if( fieldCoord == FieldCoord::BrBz) { + if (fieldCoord == FieldCoord::BrBz) { coord.resize(2); Bcomp.resize(2); iss >> coord[0] >> coord[1] >> Bcomp[0] >> Bcomp[1]; - if( ! GetIndices( coord[0], coord[1], &ir, &iz, &dr, &dz) ) { + if (!GetIndices(coord[0], coord[1], &ir, &iz, &dr, &dz)) { printout(WARNING, "FieldMapB", "coordinates out of range, skipped it."); + } else { // scale field + Bvals_RZ[ir][iz] = {Bcomp[0] * scale * float(tesla), Bcomp[1] * scale * float(tesla)}; } - else { // scale field - Bvals_RZ[ ir ][ iz ] = - { Bcomp[0] * scale * float(tesla), - Bcomp[1] * scale * float(tesla) }; - } - } - else { + } else { coord.resize(3); Bcomp.resize(3); iss >> coord[0] >> coord[1] >> coord[2] >> Bcomp[0] >> Bcomp[1] >> Bcomp[2]; - if( ! GetIndices(coord[0], coord[1], coord[2], &ix, &iy, &iz, &dx, &dy, &dz) ) { - printout(WARNING, "FieldMap","coordinates out of range, skipped it."); - } - else { // scale and rotate B field vector - auto B = ROOT::Math::XYZPoint( Bcomp[0], Bcomp[1], Bcomp[2] ); + if (!GetIndices(coord[0], coord[1], coord[2], &ix, &iy, &iz, &dx, &dy, &dz)) { + printout(WARNING, "FieldMap", "coordinates out of range, skipped it."); + } else { // scale and rotate B field vector + auto B = ROOT::Math::XYZPoint(Bcomp[0], Bcomp[1], Bcomp[2]); B *= scale * float(tesla); - B = fieldRot * B; - Bvals_XYZ[ ix ][ iy ][ iz ] = { float(B.x()), float(B.y()), float(B.z()) }; + B = fieldRot * B; + Bvals_XYZ[ix][iy][iz] = {float(B.x()), float(B.y()), float(B.z())}; } } } } // get field components -void FieldMapB::fieldComponents(const double* pos, double* field) -{ +void FieldMapB::fieldComponents(const double* pos, double* field) { // coordinate conversion auto p = coordTranslate_inv * ROOT::Math::XYZPoint(pos[0], pos[1], pos[2]); - if( fieldCoord == FieldCoord::BrBz ) { + if (fieldCoord == FieldCoord::BrBz) { // coordinates conversion const float r = sqrt(p.x() * p.x() + p.y() * p.y()); const float z = p.z(); const float phi = atan2(p.y(), p.x()); - if( ! GetIndices(r, z, &ir, &iz, &dr, &dz) ) { + if (!GetIndices(r, z, &ir, &iz, &dr, &dz)) { // out of range return; } @@ -239,42 +224,40 @@ void FieldMapB::fieldComponents(const double* pos, double* field) // p1 p3 // p // p0 p2 - auto& p0 = Bvals_RZ[ ir ][ iz ]; - auto& p1 = Bvals_RZ[ ir ][ iz + 1 ]; - auto& p2 = Bvals_RZ[ ir + 1 ][ iz ]; - auto& p3 = Bvals_RZ[ ir + 1 ][ iz + 1 ]; + auto& p0 = Bvals_RZ[ir][iz]; + auto& p1 = Bvals_RZ[ir][iz + 1]; + auto& p2 = Bvals_RZ[ir + 1][iz]; + auto& p3 = Bvals_RZ[ir + 1][iz + 1]; // Bilinear interpolation - float Br = p0[0] * (1 - dr) * (1 - dz) + p1[0] * (1 - dr) * dz - + p2[0] * dr * (1 - dz) + p3[0] * dr * dz; + float Br = p0[0] * (1 - dr) * (1 - dz) + p1[0] * (1 - dr) * dz + p2[0] * dr * (1 - dz) + + p3[0] * dr * dz; - float Bz = p0[1] * (1 - dr) * (1 - dz) + p1[1] * (1 - dr) * dz - + p2[1] * dr * (1 - dz) + p3[1] * dr * dz; + float Bz = p0[1] * (1 - dr) * (1 - dz) + p1[1] * (1 - dr) * dz + p2[1] * dr * (1 - dz) + + p3[1] * dr * dz; // convert Br Bz to Bx By Bz and rotate field auto B = fieldRot * ROOT::Math::XYZPoint(Br * cos(phi), Br * sin(phi), Bz); field[0] += B.x(); field[1] += B.y(); field[2] += B.z(); - } - else { // BxByBz + } else { // BxByBz - if( ! GetIndices(p.x(), p.y(), p.z(), &ix, &iy, &iz, &dx, &dy, &dz) ) { + if (!GetIndices(p.x(), p.y(), p.z(), &ix, &iy, &iz, &dx, &dy, &dz)) { return; // out of range } float b[3] = {0}; - for(int comp = 0; comp < 3; comp++) { // field component loop + for (int comp = 0; comp < 3; comp++) { // field component loop // Trilinear interpolation // First along X, along 4 lines - float b00 = Bvals_XYZ[ ix ][ iy ][ iz ][comp] * (1 - dx) - + Bvals_XYZ[ ix + 1 ][ iy ][ iz ][comp] * dx; - float b01 = Bvals_XYZ[ ix ][ iy ][ iz + 1 ][comp] * (1 - dx) - + Bvals_XYZ[ ix + 1 ][ iy ][ iz + 1 ][comp] * dx; - float b10 = Bvals_XYZ[ ix ][ iy + 1 ][ iz ][comp] * (1 - dx) - + Bvals_XYZ[ ix + 1 ][ iy + 1 ][ iz ][comp] * dx; - float b11 = Bvals_XYZ[ ix ][ iy + 1 ][ iz + 1 ][comp] * (1 - dx) - + Bvals_XYZ[ ix + 1 ][ iy + 1 ][ iz + 1 ][comp] * dx; + float b00 = Bvals_XYZ[ix][iy][iz][comp] * (1 - dx) + Bvals_XYZ[ix + 1][iy][iz][comp] * dx; + float b01 = + Bvals_XYZ[ix][iy][iz + 1][comp] * (1 - dx) + Bvals_XYZ[ix + 1][iy][iz + 1][comp] * dx; + float b10 = + Bvals_XYZ[ix][iy + 1][iz][comp] * (1 - dx) + Bvals_XYZ[ix + 1][iy + 1][iz][comp] * dx; + float b11 = Bvals_XYZ[ix][iy + 1][iz + 1][comp] * (1 - dx) + + Bvals_XYZ[ix + 1][iy + 1][iz + 1][comp] * dx; // Next along Y, along 2 lines float b0 = b00 * (1 - dy) + b10 * dy; float b1 = b01 * (1 - dy) + b11 * dy; @@ -292,18 +275,18 @@ void FieldMapB::fieldComponents(const double* pos, double* field) } // assign the field map to CartesianField -static Ref_t create_field_map_b(Detector& /*lcdd*/, xml::Handle_t handle) -{ +static Ref_t create_field_map_b(Detector& /*lcdd*/, xml::Handle_t handle) { xml_comp_t x_par(handle); if (!x_par.hasAttr(_Unicode(field_map))) { - throw std::runtime_error("FieldMapB Error: must have an xml attribute \"field_map\" for the field map."); + throw std::runtime_error( + "FieldMapB Error: must have an xml attribute \"field_map\" for the field map."); } CartesianField field; - std::string field_type = x_par.attr(_Unicode(field_type)); + std::string field_type = x_par.attr(_Unicode(field_type)); - std::string coord_type = x_par.attr(_Unicode(coord_type)); + std::string coord_type = x_par.attr(_Unicode(coord_type)); // dimensions xml_comp_t x_dim = x_par.dimensions(); @@ -311,16 +294,14 @@ static Ref_t create_field_map_b(Detector& /*lcdd*/, xml::Handle_t handle) // vector of dimension parameters: step, min, max std::vector dimensions; - if( coord_type.compare("BrBz") == 0 ) { - dimensions.push_back( x_dim.child(_Unicode(R)) ); - dimensions.push_back( x_dim.child(_Unicode(Z)) ); - } - else if( coord_type.compare("BxByBz") == 0 ) { - dimensions.push_back( x_dim.child(_Unicode(X)) ); - dimensions.push_back( x_dim.child(_Unicode(Y)) ); - dimensions.push_back( x_dim.child(_Unicode(Z)) ); - } - else { + if (coord_type.compare("BrBz") == 0) { + dimensions.push_back(x_dim.child(_Unicode(R))); + dimensions.push_back(x_dim.child(_Unicode(Z))); + } else if (coord_type.compare("BxByBz") == 0) { + dimensions.push_back(x_dim.child(_Unicode(X))); + dimensions.push_back(x_dim.child(_Unicode(Y))); + dimensions.push_back(x_dim.child(_Unicode(Z))); + } else { printout(ERROR, "FieldMapB", "Coordinate type: " + coord_type + ", is not BrBz nor BxByBz"); std::_Exit(EXIT_FAILURE); } @@ -340,11 +321,11 @@ static Ref_t create_field_map_b(Detector& /*lcdd*/, xml::Handle_t handle) } auto map = new FieldMapB(field_type, coord_type); - map->Configure( dimensions ); + map->Configure(dimensions); // translation, rotation static float deg2r = ROOT::Math::Pi() / 180.; - RotationZYX rot(0., 0., 0.); + RotationZYX rot(0., 0., 0.); if (x_dim.hasChild(_Unicode(rotationField))) { xml_comp_t rot_dim = x_dim.child(_Unicode(rotationField)); rot = RotationZYX(rot_dim.z() * deg2r, rot_dim.y() * deg2r, rot_dim.x() * deg2r); @@ -355,8 +336,8 @@ static Ref_t create_field_map_b(Detector& /*lcdd*/, xml::Handle_t handle) xml_comp_t trans_dim = x_dim.child(_Unicode(translationCoord)); trans = Translation3D(trans_dim.x(), trans_dim.y(), trans_dim.z()); } - map->SetCoordTranslation( Transform3D(trans) ); - map->SetFieldRotation( Transform3D(rot) ); + map->SetCoordTranslation(Transform3D(trans)); + map->SetFieldRotation(Transform3D(rot)); map->LoadMap(field_map_file, field_map_scale); field.assign(map, x_par.nameStr(), "FieldMapB"); diff --git a/src/FileLoader.cpp b/src/FileLoader.cpp index 13e1c3d82..39081b9a0 100644 --- a/src/FileLoader.cpp +++ b/src/FileLoader.cpp @@ -18,21 +18,20 @@ using namespace dd4hep; -void usage(int argc, char** argv) -{ - std::cerr << "Usage: -plugin -arg [-arg] \n" - " cache: cache location (may be read-only) \n" - " file: file location \n" - " url: url location \n" - " cmd: download command with {0} for url, {1} for output \n" - "\tArguments given: " - << arguments(argc, argv) << std::endl; +void usage(int argc, char** argv) { + std::cerr + << "Usage: -plugin -arg [-arg] \n" + " cache: cache location (may be read-only) \n" + " file: file location \n" + " url: url location \n" + " cmd: download command with {0} for url, {1} for output \n" + "\tArguments given: " + << arguments(argc, argv) << std::endl; std::exit(EINVAL); } // Plugin to download files -long load_file(Detector& /* desc */, int argc, char** argv) -{ +long load_file(Detector& /* desc */, int argc, char** argv) { // argument parsing std::string cache, file, url; for (int i = 0; i < argc && argv[i]; ++i) { diff --git a/src/FileLoaderHelper.h b/src/FileLoaderHelper.h index 001473f46..5680febc0 100644 --- a/src/FileLoaderHelper.h +++ b/src/FileLoaderHelper.h @@ -18,16 +18,15 @@ namespace fs = std::filesystem; -using dd4hep::printout; using dd4hep::ERROR, dd4hep::WARNING, dd4hep::INFO; +using dd4hep::printout; namespace FileLoaderHelper { - static constexpr const char* const kCommand = "curl --retry 5 --location --fail {0} --output {1}"; +static constexpr const char* const kCommand = "curl --retry 5 --location --fail {0} --output {1}"; } // Function to download files -inline void EnsureFileFromURLExists(std::string url, std::string file, std::string cache_str = "") -{ +inline void EnsureFileFromURLExists(std::string url, std::string file, std::string cache_str = "") { // parse cache for environment variables auto pos = std::string::npos; while ((pos = cache_str.find('$')) != std::string::npos) { @@ -39,7 +38,7 @@ inline void EnsureFileFromURLExists(std::string url, std::string file, std::stri if (after == std::string::npos) after = cache_str.size(); // cache ends on env var const std::string env_name(cache_str.substr(pos + 1, after - pos - 1)); - auto env_ptr = std::getenv(env_name.c_str()); + auto env_ptr = std::getenv(env_name.c_str()); const std::string env_value(env_ptr != nullptr ? env_ptr : ""); cache_str.erase(pos, after - pos); cache_str.insert(pos, env_value); @@ -47,16 +46,17 @@ inline void EnsureFileFromURLExists(std::string url, std::string file, std::stri } // tokenize cache on regex - std::regex cache_sep(":"); + std::regex cache_sep(":"); std::sregex_token_iterator cache_iter(cache_str.begin(), cache_str.end(), cache_sep, -1); std::sregex_token_iterator cache_end; - std::vector cache_vec(cache_iter, cache_end); + std::vector cache_vec(cache_iter, cache_end); // create file path fs::path file_path(file); // create hash from url, hex of unsigned long long - std::string hash = fmt::format("{:016x}", dd4hep::detail::hash64(url)); // TODO: Use c++20 std::fmt + std::string hash = + fmt::format("{:016x}", dd4hep::detail::hash64(url)); // TODO: Use c++20 std::fmt // create file parent path, if not exists fs::path parent_path = file_path.parent_path(); @@ -88,13 +88,14 @@ inline void EnsureFileFromURLExists(std::string url, std::string file, std::stri fs::path cache_path(cache); printout(INFO, "FileLoader", "cache " + cache_path.string()); if (fs::exists(cache_path)) { - auto check_path = [&](const fs::path &cache_dir_path) { + auto check_path = [&](const fs::path& cache_dir_path) { printout(INFO, "FileLoader", "checking " + cache_dir_path.string()); fs::path cache_hash_path = cache_dir_path / hash; if (fs::exists(cache_hash_path)) { // symlink hash to cache/.../hash printout(INFO, "FileLoader", - "file " + file + " with hash " + hash + " found in " + cache_hash_path.string()); + "file " + file + " with hash " + hash + " found in " + + cache_hash_path.string()); fs::path link_target; if (cache_hash_path.is_absolute()) { link_target = cache_hash_path; @@ -130,7 +131,8 @@ inline void EnsureFileFromURLExists(std::string url, std::string file, std::stri // if hash does not exist, we try to retrieve file from url if (!fs::exists(hash_path)) { - std::string cmd = fmt::format(FileLoaderHelper::kCommand, url, hash_path.c_str()); // TODO: Use c++20 std::fmt + std::string cmd = + fmt::format(FileLoaderHelper::kCommand, url, hash_path.c_str()); // TODO: Use c++20 std::fmt printout(INFO, "FileLoader", "downloading " + file + " as hash " + hash + " with " + cmd); // run cmd auto ret = std::system(cmd.c_str()); @@ -138,7 +140,8 @@ inline void EnsureFileFromURLExists(std::string url, std::string file, std::stri printout(ERROR, "FileLoader", "unable to run the download command " + cmd); printout(ERROR, "FileLoader", "the return value was ", ret); printout(ERROR, "FileLoader", "hint: check the command and try running manually"); - printout(ERROR, "FileLoader", "hint: allow insecure connections on some systems with the flag -k"); + printout(ERROR, "FileLoader", + "hint: allow insecure connections on some systems with the flag -k"); std::_Exit(EXIT_FAILURE); } } @@ -155,18 +158,24 @@ inline void EnsureFileFromURLExists(std::string url, std::string file, std::stri // link points to incorrect path if (fs::remove(file_path) == false) { printout(ERROR, "FileLoader", "unable to remove symlink " + file_path.string()); - printout(ERROR, "FileLoader", "we tried to create a symlink " + file_path.string() + " to the actual resource, " + - "but a symlink already exists there and points to an incorrect location"); - printout(ERROR, "FileLoader", "hint: this may be resolved by removing directory " + parent_path.string()); - printout(ERROR, "FileLoader", "hint: or in that directory removing the file or link " + file_path.string()); + printout(ERROR, "FileLoader", + "we tried to create a symlink " + file_path.string() + + " to the actual resource, " + + "but a symlink already exists there and points to an incorrect location"); + printout(ERROR, "FileLoader", + "hint: this may be resolved by removing directory " + parent_path.string()); + printout(ERROR, "FileLoader", + "hint: or in that directory removing the file or link " + file_path.string()); std::_Exit(EXIT_FAILURE); } } } else { // file exists but not symlink - printout(ERROR, "FileLoader", "file " + file_path.string() + " already exists but is not a symlink"); - printout(ERROR, "FileLoader", "we tried to create a symlink " + file_path.string() + " to the actual resource, " + - "but a file already exists there and we will not remove it automatically"); + printout(ERROR, "FileLoader", + "file " + file_path.string() + " already exists but is not a symlink"); + printout(ERROR, "FileLoader", + "we tried to create a symlink " + file_path.string() + " to the actual resource, " + + "but a file already exists there and we will not remove it automatically"); printout(ERROR, "FileLoader", "hint: backup the file, remove it manually, and retry"); std::_Exit(EXIT_FAILURE); } @@ -178,15 +187,20 @@ inline void EnsureFileFromURLExists(std::string url, std::string file, std::stri // use new path from hash so file link is local fs::create_symlink(fs::path(hash), file_path); } catch (const fs::filesystem_error&) { - printout(ERROR, "FileLoader", "unable to link from " + file_path.string() + " to " + hash_path.string()); + printout(ERROR, "FileLoader", + "unable to link from " + file_path.string() + " to " + hash_path.string()); printout(ERROR, "FileLoader", "check permissions and retry"); std::_Exit(EXIT_FAILURE); } // final check of the file size if (fs::file_size(file_path) == 0) { - printout(ERROR, "FileLoader", "zero file size of symlink from " + file_path.string() + " to (ultimately) " + fs::canonical(file_path).string()); - printout(ERROR, "FileLoader", "hint: check whether the file " + fs::canonical(file_path).string() + " has any content"); + printout(ERROR, "FileLoader", + "zero file size of symlink from " + file_path.string() + " to (ultimately) " + + fs::canonical(file_path).string()); + printout(ERROR, "FileLoader", + "hint: check whether the file " + fs::canonical(file_path).string() + + " has any content"); printout(ERROR, "FileLoader", "hint: check whether the URL " + url + " has any content"); std::_Exit(EXIT_FAILURE); } diff --git a/src/ForwardRomanPot_geo.cpp b/src/ForwardRomanPot_geo.cpp index 356f73bfb..f3e9e2b50 100644 --- a/src/ForwardRomanPot_geo.cpp +++ b/src/ForwardRomanPot_geo.cpp @@ -10,57 +10,56 @@ using namespace dd4hep::detail; using Placements = vector; -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { xml_det_t x_det = e; // Material air = description.air(); - Material vacuum = description.vacuum(); - string det_name = x_det.nameStr(); - xml::Component pos = x_det.position(); - xml::Component rot = x_det.rotation(); - DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name); + Material vacuum = description.vacuum(); + string det_name = x_det.nameStr(); + xml::Component pos = x_det.position(); + xml::Component rot = x_det.rotation(); + DetElement sdet(det_name, x_det.id()); + Assembly assembly(det_name); sens.setType("tracker"); PlacedVolume pv; - map modules; + map modules; map sensitives; - map module_assemblies; + map module_assemblies; int m_id = 0; // mi ~ module iterator for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) { - xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); - double mod_width = getAttrOrDefault(x_mod, _U(width), 3.2 * cm); - double mod_height = getAttrOrDefault(x_mod, _U(height), 3.2 * cm); - double mod_total_thickness = 0.; + xml_comp_t x_mod = mi; + string m_nam = x_mod.nameStr(); + double mod_width = getAttrOrDefault(x_mod, _U(width), 3.2 * cm); + double mod_height = getAttrOrDefault(x_mod, _U(height), 3.2 * cm); + double mod_total_thickness = 0.; xml_coll_t ci(x_mod, _U(module_component)); for (ci.reset(), mod_total_thickness = 0.0; ci; ++ci) mod_total_thickness += xml_comp_t(ci).thickness(); - Box m_solid(mod_width / 2.0, mod_height / 2.0, mod_total_thickness / 2.0); + Box m_solid(mod_width / 2.0, mod_height / 2.0, mod_total_thickness / 2.0); Volume m_volume(m_nam, m_solid, vacuum); //set to AnlGold temporarily for future RP troubleshooting //m_volume.setVisAttributes(description.visAttributes(x_mod.visStr())); m_volume.setVisAttributes(description.visAttributes("AnlGold")); double comp_z_pos = -mod_total_thickness / 2.0; - int n_sensor = 1; - int c_id; + int n_sensor = 1; + int c_id; for (ci.reset(), n_sensor = 1, c_id = 0; ci; ++ci, ++c_id) { - xml_comp_t c = ci; - double c_thick = c.thickness(); - double comp_x = getAttrOrDefault(c, _Unicode(width), mod_width); - double comp_y = getAttrOrDefault(c, _Unicode(height), mod_height); + xml_comp_t c = ci; + double c_thick = c.thickness(); + double comp_x = getAttrOrDefault(c, _Unicode(width), mod_width); + double comp_y = getAttrOrDefault(c, _Unicode(height), mod_height); - Material c_mat = description.material(c.materialStr()); - string c_name = _toString(c_id, "RP_component%d"); + Material c_mat = description.material(c.materialStr()); + string c_name = _toString(c_id, "RP_component%d"); - Box comp_s1(comp_x / 2.0, comp_y / 2.0, c_thick / 2.0); - Solid comp_shape = comp_s1; + Box comp_s1(comp_x / 2.0, comp_y / 2.0, c_thick / 2.0); + Solid comp_shape = comp_s1; Volume c_vol(c_name, comp_shape, c_mat); c_vol.setVisAttributes(description.visAttributes(c.visStr())); @@ -86,9 +85,9 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s std::map module_assembly_delements; // module assemblies for (xml_coll_t ma(x_det, _Unicode(module_assembly)); ma; ++ma) { - xml_comp_t x_ma = ma; - string ma_name = x_ma.nameStr(); - Assembly ma_vol(ma_name); + xml_comp_t x_ma = ma; + string ma_name = x_ma.nameStr(); + Assembly ma_vol(ma_name); DetElement ma_de(ma_name, x_det.id()); module_assemblies[ma_name] = ma_vol; module_assembly_delements[ma_name] = ma_de; @@ -96,15 +95,15 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s int i_mod = 0; // array of modules for (xml_coll_t ai(x_ma, _Unicode(array)); ai; ++ai) { - xml_comp_t x_array = ai; - double nx = getAttrOrDefault(x_array, _Unicode(nx), 1); - double ny = getAttrOrDefault(x_array, _Unicode(ny), 1); - double dz = getAttrOrDefault(x_array, _Unicode(dz), 0 * mm); - double arr_width = getAttrOrDefault(x_array, _Unicode(width), 3.2 * cm); - double arr_height = getAttrOrDefault(x_array, _Unicode(height), 3.2 * cm); + xml_comp_t x_array = ai; + double nx = getAttrOrDefault(x_array, _Unicode(nx), 1); + double ny = getAttrOrDefault(x_array, _Unicode(ny), 1); + double dz = getAttrOrDefault(x_array, _Unicode(dz), 0 * mm); + double arr_width = getAttrOrDefault(x_array, _Unicode(width), 3.2 * cm); + double arr_height = getAttrOrDefault(x_array, _Unicode(height), 3.2 * cm); std::string arr_module = getAttrOrDefault(x_array, _Unicode(module), ""); // TODO: add check here - auto arr_vol = modules[arr_module]; + auto arr_vol = modules[arr_module]; Placements& sensVols = sensitives[arr_module]; double arr_x_delta = arr_width / double(nx); @@ -127,7 +126,7 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s mod_de.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_de(mod_de, std::string("de_") + sens_pv.volume().name(), ic + 1); + DetElement comp_de(mod_de, std::string("de_") + sens_pv.volume().name(), ic + 1); comp_de.setPlacement(sens_pv); // Acts::ActsExtension* sensorExtension = new Acts::ActsExtension(); //// sensorExtension->addType("sensor", "detector"); @@ -144,9 +143,9 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s int l_num = 0; for (xml_coll_t i(x_det, _U(layer)); i; ++i, ++l_num) { xml_comp_t x_layer = i; - string l_nam = det_name + _toString(l_num, "_layer%d"); + string l_nam = det_name + _toString(l_num, "_layer%d"); xml_comp_t l_pos = x_layer.position(false); - Assembly l_vol(l_nam); //(l_nam, l_box, air); + Assembly l_vol(l_nam); //(l_nam, l_box, air); Position layer_pos(0, 0, 0); if (l_pos) { @@ -154,7 +153,7 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s } DetElement layer(sdet, l_nam + "_pos", l_num); - int i_assembly = 1; + int i_assembly = 1; xml_coll_t ci(x_layer, _U(component)); for (ci.reset(); ci; ++ci) { xml_comp_t x_comp = ci; @@ -165,7 +164,8 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s auto comp_vol = module_assemblies[comp_assembly]; // auto de = ; - auto comp_de = module_assembly_delements[comp_assembly].clone(comp_assembly + std::to_string(l_num)); + auto comp_de = + module_assembly_delements[comp_assembly].clone(comp_assembly + std::to_string(l_num)); if (c_pos) { pv = l_vol.placeVolume(comp_vol, Position(c_pos.x(), c_pos.y(), c_pos.z())); } else { @@ -190,7 +190,8 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s // pv = description.pickMotherVolume(sdet).placeVolume(assembly, // Position(pos.x(), pos.y(), pos.z())); - Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), + Position(pos.x(), pos.y(), pos.z())); // pv = description.pickMotherVolume(sdet).placeVolume(assembly, // Position(pos.x(), pos.y(), pos.z())); pv = description.pickMotherVolume(sdet).placeVolume(assembly, posAndRot); diff --git a/src/GeometryHelper.cpp b/src/GeometryHelper.cpp index eb3438e2f..c0208502a 100644 --- a/src/GeometryHelper.cpp +++ b/src/GeometryHelper.cpp @@ -5,168 +5,169 @@ namespace ip6::geo { - Position get_xml_xyz(xml_coll_t& comp, dd4hep::xml::Strng_t name) - { - Position pos(0., 0., 0.); - if (comp.hasChild(name)) { - auto child = comp.child(name); - pos.SetX(dd4hep::getAttrOrDefault(child, _Unicode(x), 0.)); - pos.SetY(dd4hep::getAttrOrDefault(child, _Unicode(y), 0.)); - pos.SetZ(dd4hep::getAttrOrDefault(child, _Unicode(z), 0.)); - } - return pos; +Position get_xml_xyz(xml_coll_t& comp, dd4hep::xml::Strng_t name) { + Position pos(0., 0., 0.); + if (comp.hasChild(name)) { + auto child = comp.child(name); + pos.SetX(dd4hep::getAttrOrDefault(child, _Unicode(x), 0.)); + pos.SetY(dd4hep::getAttrOrDefault(child, _Unicode(y), 0.)); + pos.SetZ(dd4hep::getAttrOrDefault(child, _Unicode(z), 0.)); } - - // place modules, id must be provided - tuple - add_individuals(function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, - Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int sid) - { - auto [modVol, modSize] = build_module(desc, plm, sens); - int sector_id = dd4hep::getAttrOrDefault(plm, _Unicode(sector), sid); - int nmodules = 0; - for (xml_coll_t pl(plm, _Unicode(placement)); pl; ++pl) { - Position pos(dd4hep::getAttrOrDefault(pl, _Unicode(x), 0.), - dd4hep::getAttrOrDefault(pl, _Unicode(y), 0.), - dd4hep::getAttrOrDefault(pl, _Unicode(z), 0.)); - Position rot(dd4hep::getAttrOrDefault(pl, _Unicode(rotx), 0.), - dd4hep::getAttrOrDefault(pl, _Unicode(roty), 0.), - dd4hep::getAttrOrDefault(pl, _Unicode(rotz), 0.)); - auto mid = pl.attr(_Unicode(id)); - Transform3D tr = Translation3D(pos.x(), pos.y(), pos.z()) * RotationZYX(rot.z(), rot.y(), rot.x()); - auto modPV = env.placeVolume(modVol, tr); - modPV.addPhysVolID("sector", sector_id).addPhysVolID("module", mid); - nmodules++; - } - - return {sector_id, nmodules}; + return pos; +} + +// place modules, id must be provided +tuple add_individuals( + function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, + Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int sid) { + auto [modVol, modSize] = build_module(desc, plm, sens); + int sector_id = dd4hep::getAttrOrDefault(plm, _Unicode(sector), sid); + int nmodules = 0; + for (xml_coll_t pl(plm, _Unicode(placement)); pl; ++pl) { + Position pos(dd4hep::getAttrOrDefault(pl, _Unicode(x), 0.), + dd4hep::getAttrOrDefault(pl, _Unicode(y), 0.), + dd4hep::getAttrOrDefault(pl, _Unicode(z), 0.)); + Position rot(dd4hep::getAttrOrDefault(pl, _Unicode(rotx), 0.), + dd4hep::getAttrOrDefault(pl, _Unicode(roty), 0.), + dd4hep::getAttrOrDefault(pl, _Unicode(rotz), 0.)); + auto mid = pl.attr(_Unicode(id)); + Transform3D tr = + Translation3D(pos.x(), pos.y(), pos.z()) * RotationZYX(rot.z(), rot.y(), rot.x()); + auto modPV = env.placeVolume(modVol, tr); + modPV.addPhysVolID("sector", sector_id).addPhysVolID("module", mid); + nmodules++; } - // place disk of modules - tuple add_disk(function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, - Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int sid) - { - auto [modVol, modSize] = build_module(desc, plm, sens); - int sector_id = dd4hep::getAttrOrDefault(plm, _Unicode(sector), sid); - int id_begin = dd4hep::getAttrOrDefault(plm, _Unicode(id_begin), 1); - double rmin = plm.attr(_Unicode(rmin)); - double rintermediate = plm.attr(_Unicode(rintermediate)); - double r_envelopeclearance = dd4hep::getAttrOrDefault(plm, _Unicode(r_envelopeclearance), 0); - double phi_envelopeclearance = dd4hep::getAttrOrDefault(plm, _Unicode(phi_envelopeclearance), 0); - double rmax = plm.attr(_Unicode(rmax)); - double phimin = dd4hep::getAttrOrDefault(plm, _Unicode(phimin), 0.); - double phimax = dd4hep::getAttrOrDefault(plm, _Unicode(phimax), 2. * M_PI); - - // placement inside mother - auto pos = get_xml_xyz(plm, _Unicode(position)); - auto rot = get_xml_xyz(plm, _Unicode(rotation)); - - // optional envelope volume - bool has_envelope = dd4hep::getAttrOrDefault(plm, _Unicode(envelope), false); - Material material = desc.material(dd4hep::getAttrOrDefault(plm, _U(material), "Air")); - Tube inner_solid(rmin, rintermediate + r_envelopeclearance, modSize.z() / 2.0, 0, 2. * M_PI); - Tube outer_solid(rintermediate, rmax + r_envelopeclearance, modSize.z() / 2.0, phimin - phi_envelopeclearance, - phimax + phi_envelopeclearance); - UnionSolid solid(inner_solid, outer_solid); - Volume env_vol(string(env.name()) + "_envelope", solid, material); - Transform3D tr_global = RotationZYX(rot.z(), rot.y(), rot.x()) * Translation3D(pos.x(), pos.y(), pos.z()); - if (has_envelope) { - env.placeVolume(env_vol, tr_global); - } - - // local placement of modules - int mid = 0; - auto points = fillRectangles({0., 0.}, modSize.x(), modSize.y(), rmin, rintermediate, rmax, phimin, phimax); - for (auto& p : points) { - Transform3D tr_local = RotationZYX(0.0, 0.0, 0.0) * Translation3D(p.x(), p.y(), 0.0); - auto modPV = - (has_envelope ? env_vol.placeVolume(modVol, tr_local) : env.placeVolume(modVol, tr_global * tr_local)); - modPV.addPhysVolID("sector", sector_id).addPhysVolID("module", id_begin + mid++); - } - return {sector_id, mid}; + return {sector_id, nmodules}; +} + +// place disk of modules +tuple +add_disk(function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, + Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int sid) { + auto [modVol, modSize] = build_module(desc, plm, sens); + int sector_id = dd4hep::getAttrOrDefault(plm, _Unicode(sector), sid); + int id_begin = dd4hep::getAttrOrDefault(plm, _Unicode(id_begin), 1); + double rmin = plm.attr(_Unicode(rmin)); + double rintermediate = plm.attr(_Unicode(rintermediate)); + double r_envelopeclearance = dd4hep::getAttrOrDefault(plm, _Unicode(r_envelopeclearance), 0); + double phi_envelopeclearance = + dd4hep::getAttrOrDefault(plm, _Unicode(phi_envelopeclearance), 0); + double rmax = plm.attr(_Unicode(rmax)); + double phimin = dd4hep::getAttrOrDefault(plm, _Unicode(phimin), 0.); + double phimax = dd4hep::getAttrOrDefault(plm, _Unicode(phimax), 2. * M_PI); + + // placement inside mother + auto pos = get_xml_xyz(plm, _Unicode(position)); + auto rot = get_xml_xyz(plm, _Unicode(rotation)); + + // optional envelope volume + bool has_envelope = dd4hep::getAttrOrDefault(plm, _Unicode(envelope), false); + Material material = desc.material(dd4hep::getAttrOrDefault(plm, _U(material), "Air")); + Tube inner_solid(rmin, rintermediate + r_envelopeclearance, modSize.z() / 2.0, 0, 2. * M_PI); + Tube outer_solid(rintermediate, rmax + r_envelopeclearance, modSize.z() / 2.0, + phimin - phi_envelopeclearance, phimax + phi_envelopeclearance); + UnionSolid solid(inner_solid, outer_solid); + Volume env_vol(string(env.name()) + "_envelope", solid, material); + Transform3D tr_global = + RotationZYX(rot.z(), rot.y(), rot.x()) * Translation3D(pos.x(), pos.y(), pos.z()); + if (has_envelope) { + env.placeVolume(env_vol, tr_global); } - // check if a 2d point is already in the container - bool already_placed(const Point& p, const vector& vec, double xs = 1.0, double ys = 1.0, double tol = 1e-6) - { - for (auto& pt : vec) { - if ((std::abs(pt.x() - p.x()) / xs < tol) && std::abs(pt.y() - p.y()) / ys < tol) { - return true; - } + // local placement of modules + int mid = 0; + auto points = + fillRectangles({0., 0.}, modSize.x(), modSize.y(), rmin, rintermediate, rmax, phimin, phimax); + for (auto& p : points) { + Transform3D tr_local = RotationZYX(0.0, 0.0, 0.0) * Translation3D(p.x(), p.y(), 0.0); + auto modPV = (has_envelope ? env_vol.placeVolume(modVol, tr_local) + : env.placeVolume(modVol, tr_global * tr_local)); + modPV.addPhysVolID("sector", sector_id).addPhysVolID("module", id_begin + mid++); + } + return {sector_id, mid}; +} + +// check if a 2d point is already in the container +bool already_placed(const Point& p, const vector& vec, double xs = 1.0, double ys = 1.0, + double tol = 1e-6) { + for (auto& pt : vec) { + if ((std::abs(pt.x() - p.x()) / xs < tol) && std::abs(pt.y() - p.y()) / ys < tol) { + return true; } - return false; + } + return false; +} + +// check if a point is in a ring +inline bool rec_in_ring(const Point& pt, double sx, double sy, double rmin, double rintermediate, + double rmax, double phmin, double phmax) { + + // check four corners + vector pts{ + Point(pt.x() - sx / 2., pt.y() - sy / 2.), + Point(pt.x() - sx / 2., pt.y() + sy / 2.), + Point(pt.x() + sx / 2., pt.y() - sy / 2.), + Point(pt.x() + sx / 2., pt.y() + sy / 2.), + }; + + bool inside = false; + int minindex = 0; + int i = 0; + + for (auto& p : pts) { + minindex = (p.r() < pts[minindex].r()) ? i : minindex; + i++; } - // check if a point is in a ring - inline bool rec_in_ring(const Point& pt, double sx, double sy, double rmin, double rintermediate, double rmax, - double phmin, double phmax) - { - - // check four corners - vector pts{ - Point(pt.x() - sx / 2., pt.y() - sy / 2.), - Point(pt.x() - sx / 2., pt.y() + sy / 2.), - Point(pt.x() + sx / 2., pt.y() - sy / 2.), - Point(pt.x() + sx / 2., pt.y() + sy / 2.), - }; - - bool inside = false; - int minindex = 0; - int i = 0; - - for (auto& p : pts) { - minindex = (p.r() < pts[minindex].r()) ? i : minindex; - i++; - } + double rmax_pacman = + (pts[minindex].phi() < phmin || pts[minindex].phi() > phmax) ? rintermediate : rmax; + inside = pts[minindex].r() <= rmax_pacman && pts[minindex].r() >= rmin; - double rmax_pacman = (pts[minindex].phi() < phmin || pts[minindex].phi() > phmax) ? rintermediate : rmax; - inside = pts[minindex].r() <= rmax_pacman && pts[minindex].r() >= rmin; + return inside; +} - return inside; +// a helper function to recursively fill square in a ring +void add_rectangle(Point p, vector& res, double sx, double sy, double rmin, + double rintermediate, double rmax, double phmin, double phmax, + int max_depth = 20, int depth = 0) { + // exceeds the maximum depth in searching or already placed + if ((depth > max_depth) || (already_placed(p, res, sx, sy))) { + return; } - // a helper function to recursively fill square in a ring - void add_rectangle(Point p, vector& res, double sx, double sy, double rmin, double rintermediate, double rmax, - double phmin, double phmax, int max_depth = 20, int depth = 0) - { - // exceeds the maximum depth in searching or already placed - if ((depth > max_depth) || (already_placed(p, res, sx, sy))) { - return; - } - - bool in_ring = rec_in_ring(p, sx, sy, rmin, rintermediate, rmax, phmin, phmax); - if (in_ring) { - res.emplace_back(p); - } - // continue search for a good placement or if no placement found yet - if (in_ring || res.empty()) { - // check adjacent squares - add_rectangle(Point(p.x() + sx, p.y()), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, max_depth, - depth + 1); - add_rectangle(Point(p.x() - sx, p.y()), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, max_depth, - depth + 1); - add_rectangle(Point(p.x(), p.y() + sy), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, max_depth, - depth + 1); - add_rectangle(Point(p.x(), p.y() - sy), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, max_depth, - depth + 1); - } + bool in_ring = rec_in_ring(p, sx, sy, rmin, rintermediate, rmax, phmin, phmax); + if (in_ring) { + res.emplace_back(p); } - - // fill squares - vector fillRectangles(Point ref, double sx, double sy, double rmin, double rintermediate, double rmax, - double phmin, double phmax) - { - // convert (0, 2pi) to (-pi, pi) - if (phmax > M_PI) { - phmin -= M_PI; - phmax -= M_PI; - } - // start with a seed square and find one in the ring - // move to center - ref = ref - Point(int(ref.x() / sx) * sx, int(ref.y() / sy) * sy); - vector res; - add_rectangle(ref, res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, - (int(rmax / sx) + 1) * (int(rmax / sy) + 1) * 2); - return res; + // continue search for a good placement or if no placement found yet + if (in_ring || res.empty()) { + // check adjacent squares + add_rectangle(Point(p.x() + sx, p.y()), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, + max_depth, depth + 1); + add_rectangle(Point(p.x() - sx, p.y()), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, + max_depth, depth + 1); + add_rectangle(Point(p.x(), p.y() + sy), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, + max_depth, depth + 1); + add_rectangle(Point(p.x(), p.y() - sy), res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, + max_depth, depth + 1); + } +} + +// fill squares +vector fillRectangles(Point ref, double sx, double sy, double rmin, double rintermediate, + double rmax, double phmin, double phmax) { + // convert (0, 2pi) to (-pi, pi) + if (phmax > M_PI) { + phmin -= M_PI; + phmax -= M_PI; } + // start with a seed square and find one in the ring + // move to center + ref = ref - Point(int(ref.x() / sx) * sx, int(ref.y() / sy) * sy); + vector res; + add_rectangle(ref, res, sx, sy, rmin, rintermediate, rmax, phmin, phmax, + (int(rmax / sx) + 1) * (int(rmax / sy) + 1) * 2); + return res; +} } // namespace ip6::geo diff --git a/src/GeometryHelper.h b/src/GeometryHelper.h index bb2f94490..33dcc95cf 100644 --- a/src/GeometryHelper.h +++ b/src/GeometryHelper.h @@ -15,26 +15,26 @@ // some utility functions that can be shared namespace ip6::geo { - using std::function; - using std::make_tuple; - using std::map; - using std::string; - using std::tuple; - using std::vector; - using Volume = dd4hep::Volume; - using Position = dd4hep::Position; - using Assembly = dd4hep::Assembly; - using Detector = dd4hep::Detector; - using SensitiveDetector = dd4hep::SensitiveDetector; - using Point = ROOT::Math::XYPoint; - using Transform3D = dd4hep::Transform3D; - using Translation3D = dd4hep::Translation3D; - using RotationZYX = dd4hep::RotationZYX; - using UnionSolid = dd4hep::UnionSolid; - using Material = dd4hep::Material; - using Tube = dd4hep::Tube; - - /* Fill rectangles in a pacman disk +using std::function; +using std::make_tuple; +using std::map; +using std::string; +using std::tuple; +using std::vector; +using Volume = dd4hep::Volume; +using Position = dd4hep::Position; +using Assembly = dd4hep::Assembly; +using Detector = dd4hep::Detector; +using SensitiveDetector = dd4hep::SensitiveDetector; +using Point = ROOT::Math::XYPoint; +using Transform3D = dd4hep::Transform3D; +using Translation3D = dd4hep::Translation3D; +using RotationZYX = dd4hep::RotationZYX; +using UnionSolid = dd4hep::UnionSolid; +using Material = dd4hep::Material; +using Tube = dd4hep::Tube; + +/* Fill rectangles in a pacman disk * * @param ref 2D reference point. * @param sx x side length @@ -48,16 +48,17 @@ namespace ip6::geo { * Outer radial bunds can be penetrated by internal modules on or near the boundary. */ - vector fillRectangles(Point ref, double sx, double sy, double rmin, double rintermediate, double rmax, - double phmin = -M_PI, double phmax = M_PI); +vector fillRectangles(Point ref, double sx, double sy, double rmin, double rintermediate, + double rmax, double phmin = -M_PI, double phmax = M_PI); - tuple - add_individuals(function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, - Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int id); +tuple add_individuals( + function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, + Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int id); - tuple add_disk(function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, - Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int id); +tuple +add_disk(function(Detector&, xml_coll_t&, SensitiveDetector&)> build_module, + Detector& desc, Assembly& env, xml_coll_t& plm, SensitiveDetector& sens, int id); - Position get_xml_xyz(xml_comp_t& comp, dd4hep::xml::Strng_t name); +Position get_xml_xyz(xml_comp_t& comp, dd4hep::xml::Strng_t name); } // namespace ip6::geo diff --git a/src/GeometryHelpers.cpp b/src/GeometryHelpers.cpp index 6fccaf331..e04680a73 100644 --- a/src/GeometryHelpers.cpp +++ b/src/GeometryHelpers.cpp @@ -6,230 +6,222 @@ // some utility functions that can be shared namespace epic::geo { - typedef ROOT::Math::XYPoint Point; - - // check if a 2d point is already in the container - bool already_placed(const Point& p, const std::vector& vec, double xs = 1.0, double ys = 1.0, - double tol = 1e-6) - { - for (auto& pt : vec) { - if ((std::abs(pt.x() - p.x()) / xs < tol) && std::abs(pt.y() - p.y()) / ys < tol) { - return true; - } +typedef ROOT::Math::XYPoint Point; + +// check if a 2d point is already in the container +bool already_placed(const Point& p, const std::vector& vec, double xs = 1.0, double ys = 1.0, + double tol = 1e-6) { + for (auto& pt : vec) { + if ((std::abs(pt.x() - p.x()) / xs < tol) && std::abs(pt.y() - p.y()) / ys < tol) { + return true; } + } + return false; +} + +// check if a square in a ring +inline bool rec_in_ring(const Point& pt, double sx, double sy, double rmin, double rmax, + double phmin, double phmax) { + if (pt.r() > rmax || pt.r() < rmin) { return false; } - // check if a square in a ring - inline bool rec_in_ring(const Point& pt, double sx, double sy, double rmin, double rmax, double phmin, double phmax) - { - if (pt.r() > rmax || pt.r() < rmin) { + // check four corners + std::vector pts{ + Point(pt.x() - sx / 2., pt.y() - sy / 2.), + Point(pt.x() - sx / 2., pt.y() + sy / 2.), + Point(pt.x() + sx / 2., pt.y() - sy / 2.), + Point(pt.x() + sx / 2., pt.y() + sy / 2.), + }; + for (auto& p : pts) { + if (p.r() > rmax || p.r() < rmin || p.phi() > phmax || p.phi() < phmin) { return false; } - - // check four corners - std::vector pts{ - Point(pt.x() - sx / 2., pt.y() - sy / 2.), - Point(pt.x() - sx / 2., pt.y() + sy / 2.), - Point(pt.x() + sx / 2., pt.y() - sy / 2.), - Point(pt.x() + sx / 2., pt.y() + sy / 2.), - }; - for (auto& p : pts) { - if (p.r() > rmax || p.r() < rmin || p.phi() > phmax || p.phi() < phmin) { - return false; - } - } - return true; } - - // a helper function to recursively fill square in a ring - void add_rectangle(Point p, std::vector& res, double sx, double sy, double rmin, double rmax, double phmin, - double phmax, int max_depth = 20, int depth = 0) - { - // std::cout << depth << "/" << max_depth << std::endl; - // exceeds the maximum depth in searching or already placed - if ((depth > max_depth) || (already_placed(p, res, sx, sy))) { - return; - } - - bool in_ring = rec_in_ring(p, sx, sy, rmin, rmax, phmin, phmax); - if (in_ring) { - res.emplace_back(p); - } - - // continue search for a good placement or if no placement found yet - if (in_ring || res.empty()) { - // check adjacent squares - add_rectangle(Point(p.x() + sx, p.y()), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, depth + 1); - add_rectangle(Point(p.x() - sx, p.y()), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, depth + 1); - add_rectangle(Point(p.x(), p.y() + sy), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, depth + 1); - add_rectangle(Point(p.x(), p.y() - sy), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, depth + 1); - } + return true; +} + +// a helper function to recursively fill square in a ring +void add_rectangle(Point p, std::vector& res, double sx, double sy, double rmin, double rmax, + double phmin, double phmax, int max_depth = 20, int depth = 0) { + // std::cout << depth << "/" << max_depth << std::endl; + // exceeds the maximum depth in searching or already placed + if ((depth > max_depth) || (already_placed(p, res, sx, sy))) { + return; } - // fill squares - std::vector fillRectangles(Point ref, double sx, double sy, double rmin, double rmax, double phmin, - double phmax) - { - // convert (0, 2pi) to (-pi, pi) - if (phmax > M_PI) { - phmin -= M_PI; - phmax -= M_PI; - } - // start with a seed square and find one in the ring - // move to center - ref = ref - Point(int(ref.x() / sx) * sx, int(ref.y() / sy) * sy); - - std::vector res; - add_rectangle(ref, res, sx, sy, rmin, rmax, phmin, phmax, (int(rmax / sx) + 1) * (int(rmax / sy) + 1) * 2); - return res; + bool in_ring = rec_in_ring(p, sx, sy, rmin, rmax, phmin, phmax); + if (in_ring) { + res.emplace_back(p); } - // check if a regular polygon is inside a ring - bool poly_in_ring(const Point& p, int nsides, double lside, double rmin, double rmax, double phmin, double phmax) - { - // outer radius is contained - if ((p.r() + lside <= rmax) && (p.r() - lside >= rmin)) { - return true; - } - - // inner radius is not contained - double rin = std::cos(M_PI / nsides) * lside; - if ((p.r() + rin > rmax) || (p.r() - rin < rmin)) { - return false; - } - - // in between, check every corner - for (int i = 0; i < nsides; ++i) { - double phi = (i + 0.5) * 2. * M_PI / static_cast(nsides); - Point p2(p.x() + 2. * lside * std::sin(phi), p.y() + 2. * lside * std::cos(phi)); - if ((p2.r() > rmax) || (p2.r() < rmin) || p.phi() > phmax || p.phi() < phmin) { - return false; - } - } + // continue search for a good placement or if no placement found yet + if (in_ring || res.empty()) { + // check adjacent squares + add_rectangle(Point(p.x() + sx, p.y()), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, + depth + 1); + add_rectangle(Point(p.x() - sx, p.y()), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, + depth + 1); + add_rectangle(Point(p.x(), p.y() + sy), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, + depth + 1); + add_rectangle(Point(p.x(), p.y() - sy), res, sx, sy, rmin, rmax, phmin, phmax, max_depth, + depth + 1); + } +} + +// fill squares +std::vector fillRectangles(Point ref, double sx, double sy, double rmin, double rmax, + double phmin, double phmax) { + // convert (0, 2pi) to (-pi, pi) + if (phmax > M_PI) { + phmin -= M_PI; + phmax -= M_PI; + } + // start with a seed square and find one in the ring + // move to center + ref = ref - Point(int(ref.x() / sx) * sx, int(ref.y() / sy) * sy); + + std::vector res; + add_rectangle(ref, res, sx, sy, rmin, rmax, phmin, phmax, + (int(rmax / sx) + 1) * (int(rmax / sy) + 1) * 2); + return res; +} + +// check if a regular polygon is inside a ring +bool poly_in_ring(const Point& p, int nsides, double lside, double rmin, double rmax, double phmin, + double phmax) { + // outer radius is contained + if ((p.r() + lside <= rmax) && (p.r() - lside >= rmin)) { return true; } - // recursively fill square (nside=4) or hexagon (nside=6) in a ring, other polygons won't work - void add_poly(Point p, std::vector& res, int nsides, double lside, double rmin, double rmax, double phmin, - double phmax, int max_depth = 20, int depth = 0) - { - // std::cout << depth << "/" << max_depth << std::endl; - // exceeds the maximum depth in searching or already placed - if ((depth > max_depth) || (already_placed(p, res, lside, lside))) { - return; - } + // inner radius is not contained + double rin = std::cos(M_PI / nsides) * lside; + if ((p.r() + rin > rmax) || (p.r() - rin < rmin)) { + return false; + } - bool in_ring = poly_in_ring(p, nsides, lside, rmin, rmax, phmin, phmax); - if (in_ring) { - res.emplace_back(p); + // in between, check every corner + for (int i = 0; i < nsides; ++i) { + double phi = (i + 0.5) * 2. * M_PI / static_cast(nsides); + Point p2(p.x() + 2. * lside * std::sin(phi), p.y() + 2. * lside * std::cos(phi)); + if ((p2.r() > rmax) || (p2.r() < rmin) || p.phi() > phmax || p.phi() < phmin) { + return false; } + } + return true; +} + +// recursively fill square (nside=4) or hexagon (nside=6) in a ring, other polygons won't work +void add_poly(Point p, std::vector& res, int nsides, double lside, double rmin, double rmax, + double phmin, double phmax, int max_depth = 20, int depth = 0) { + // std::cout << depth << "/" << max_depth << std::endl; + // exceeds the maximum depth in searching or already placed + if ((depth > max_depth) || (already_placed(p, res, lside, lside))) { + return; + } - // recursively add neigbors, continue if it was a good placement or no placement found yet - if (in_ring || res.empty()) { - for (int i = 0; i < nsides; ++i) { - double phi = i * 2. * M_PI / static_cast(nsides); - add_poly(Point(p.x() + 2. * lside * std::sin(phi), p.y() + 2. * lside * std::cos(phi)), res, nsides, lside, - rmin, rmax, phmin, phmax, max_depth, depth + 1); - } - } + bool in_ring = poly_in_ring(p, nsides, lside, rmin, rmax, phmin, phmax); + if (in_ring) { + res.emplace_back(p); } - std::vector fillHexagons(Point ref, double lside, double rmin, double rmax, double phmin, double phmax) - { - // convert (0, 2pi) to (-pi, pi) - if (phmax > M_PI) { - phmin -= M_PI; - phmax -= M_PI; + // recursively add neigbors, continue if it was a good placement or no placement found yet + if (in_ring || res.empty()) { + for (int i = 0; i < nsides; ++i) { + double phi = i * 2. * M_PI / static_cast(nsides); + add_poly(Point(p.x() + 2. * lside * std::sin(phi), p.y() + 2. * lside * std::cos(phi)), res, + nsides, lside, rmin, rmax, phmin, phmax, max_depth, depth + 1); } - // start with a seed and find one in the ring - // move to center - ref = ref - Point(int(ref.x() / lside) * lside, int(ref.y() / lside) * lside); - - std::vector res; - add_poly(ref, res, 6, lside, rmin, rmax, phmin, phmax, std::pow(int(rmax / lside) + 1, 2) * 2); - return res; } - - - bool isPointInsidePolygon(Point p, std::vector vertices) - { - int n = vertices.size(); - bool check = false; // check == false (outside the polygon), check == true (inside the polygon) - const double tolerance = 0.000001; - - // When the point overlaps with vertex in the tolerance. - // - for( int i = 0 ; i < n ; i++) - if( std::abs(p.x() - vertices[i].x()) < tolerance && std::abs(p.y() - vertices[i].y()) < tolerance ) - check = !check; - - - // When the point is on the line connected two vertices in the tolerance. - // - if( check == false ) - { - for( int i = 0, j = n-1 ; i < n ; j = i++) - if( std::abs(p.x() - vertices[i].x()) < tolerance && std::abs(p.x() - vertices[j].x()) < tolerance ) - if( (vertices[i].y() > p.y()) != (vertices[j].y() > p.y()) ) - check = !check; - } - if( check == false ) - { - for( int i = 0, j = n-1 ; i < n ; j = i++) - if( std::abs(p.y() - vertices[i].y()) < tolerance && std::abs(p.y() - vertices[j].y()) < tolerance ) - if( (vertices[i].x() > p.x()) != (vertices[j].x() > p.x()) ) - check = !check; - } - - - if( check == false ) - { - for( int i = 0, j = n-1 ; i < n ; j = i++) - { - double ver_i = vertices[i].y(); - double ver_j = vertices[j].y(); - double criteria = (vertices[j].x() - vertices[i].x()) * (p.y() - vertices[i].y()) / (vertices[j].y() - vertices[i].y()) + vertices[i].x(); - - if( ((ver_i > p.y()) != (ver_j > p.y())) && (p.x() < criteria || std::abs(p.x() - criteria) < tolerance) ) - check = !check; - } - } - - return check; +} + +std::vector fillHexagons(Point ref, double lside, double rmin, double rmax, double phmin, + double phmax) { + // convert (0, 2pi) to (-pi, pi) + if (phmax > M_PI) { + phmin -= M_PI; + phmax -= M_PI; } - - - bool isBoxTotalInsidePolygon(Point box[4], std::vector vertices) - { - bool pt_check = true; - for (int i = 0 ; i < 4 ; i++ ) - pt_check = pt_check && isPointInsidePolygon(box[i], vertices); - return pt_check; + // start with a seed and find one in the ring + // move to center + ref = ref - Point(int(ref.x() / lside) * lside, int(ref.y() / lside) * lside); + + std::vector res; + add_poly(ref, res, 6, lside, rmin, rmax, phmin, phmax, std::pow(int(rmax / lside) + 1, 2) * 2); + return res; +} + +bool isPointInsidePolygon(Point p, std::vector vertices) { + int n = vertices.size(); + bool check = false; // check == false (outside the polygon), check == true (inside the polygon) + const double tolerance = 0.000001; + + // When the point overlaps with vertex in the tolerance. + // + for (int i = 0; i < n; i++) + if (std::abs(p.x() - vertices[i].x()) < tolerance && + std::abs(p.y() - vertices[i].y()) < tolerance) + check = !check; + + // When the point is on the line connected two vertices in the tolerance. + // + if (check == false) { + for (int i = 0, j = n - 1; i < n; j = i++) + if (std::abs(p.x() - vertices[i].x()) < tolerance && + std::abs(p.x() - vertices[j].x()) < tolerance) + if ((vertices[i].y() > p.y()) != (vertices[j].y() > p.y())) + check = !check; } - - - bool isBoxPartialInsidePolygon(Point box[4], std::vector vertices) - { - bool pt_check = false; - for (int i = 0 ; i < 4 ; i++ ) - pt_check = pt_check || isPointInsidePolygon(box[i], vertices); - return pt_check; + if (check == false) { + for (int i = 0, j = n - 1; i < n; j = i++) + if (std::abs(p.y() - vertices[i].y()) < tolerance && + std::abs(p.y() - vertices[j].y()) < tolerance) + if ((vertices[i].x() > p.x()) != (vertices[j].x() > p.x())) + check = !check; } + if (check == false) { + for (int i = 0, j = n - 1; i < n; j = i++) { + double ver_i = vertices[i].y(); + double ver_j = vertices[j].y(); + double criteria = (vertices[j].x() - vertices[i].x()) * (p.y() - vertices[i].y()) / + (vertices[j].y() - vertices[i].y()) + + vertices[i].x(); - std::vector> getPolygonVertices(std::pair center, double radius, double angle_0, int numSides) - { - std::vector> vertices; - double angle = 2 * M_PI / numSides; // calculate the angle between adjacent vertices - for (int i = 0 ; i < numSides ; i++) - { - double x = center.first + radius * cos(i * angle + angle_0); - double y = center.second + radius * sin(i * angle + angle_0); - vertices.emplace_back(x, y); // add the vertex to the vector - } - return vertices; + if (((ver_i > p.y()) != (ver_j > p.y())) && + (p.x() < criteria || std::abs(p.x() - criteria) < tolerance)) + check = !check; + } } + return check; +} + +bool isBoxTotalInsidePolygon(Point box[4], std::vector vertices) { + bool pt_check = true; + for (int i = 0; i < 4; i++) + pt_check = pt_check && isPointInsidePolygon(box[i], vertices); + return pt_check; +} + +bool isBoxPartialInsidePolygon(Point box[4], std::vector vertices) { + bool pt_check = false; + for (int i = 0; i < 4; i++) + pt_check = pt_check || isPointInsidePolygon(box[i], vertices); + return pt_check; +} + +std::vector> +getPolygonVertices(std::pair center, double radius, double angle_0, int numSides) { + std::vector> vertices; + double angle = 2 * M_PI / numSides; // calculate the angle between adjacent vertices + for (int i = 0; i < numSides; i++) { + double x = center.first + radius * cos(i * angle + angle_0); + double y = center.second + radius * sin(i * angle + angle_0); + vertices.emplace_back(x, y); // add the vertex to the vector + } + return vertices; +} } // namespace epic::geo diff --git a/src/GeometryHelpers.h b/src/GeometryHelpers.h index 76f6b577f..5f4479437 100644 --- a/src/GeometryHelpers.h +++ b/src/GeometryHelpers.h @@ -8,9 +8,9 @@ // some utility functions that can be shared namespace epic::geo { - using Point = ROOT::Math::XYPoint; +using Point = ROOT::Math::XYPoint; - /** Fill rectangles in a ring (disk). +/** Fill rectangles in a ring (disk). * * @param ref 2D reference point. * @param sx x side length @@ -20,24 +20,24 @@ namespace epic::geo { * @param phmin phi min * @param phmax phi max */ - std::vector fillRectangles(Point ref, double sx, double sy, double rmin, double rmax, double phmin = -M_PI, - double phmax = M_PI); - // fill squares in a ring - inline std::vector fillSquares(Point ref, double size, double rmin, double rmax, double phmin = -M_PI, - double phmax = M_PI) - { - return fillRectangles(ref, size, size, rmin, rmax, phmin, phmax); - } +std::vector fillRectangles(Point ref, double sx, double sy, double rmin, double rmax, + double phmin = -M_PI, double phmax = M_PI); +// fill squares in a ring +inline std::vector fillSquares(Point ref, double size, double rmin, double rmax, + double phmin = -M_PI, double phmax = M_PI) { + return fillRectangles(ref, size, size, rmin, rmax, phmin, phmax); +} - std::vector fillHexagons(Point ref, double lside, double rmin, double rmax, double phmin = -M_PI, - double phmax = M_PI); +std::vector fillHexagons(Point ref, double lside, double rmin, double rmax, + double phmin = -M_PI, double phmax = M_PI); - bool isPointInsidePolygon(Point p, std::vector vertices); +bool isPointInsidePolygon(Point p, std::vector vertices); - bool isBoxTotalInsidePolygon(Point box[4], std::vector vertices); +bool isBoxTotalInsidePolygon(Point box[4], std::vector vertices); - bool isBoxPartialInsidePolygon(Point box[4], std::vector vertices); +bool isBoxPartialInsidePolygon(Point box[4], std::vector vertices); - std::vector> getPolygonVertices(std::pair center, double radius, double angle_0, int numSides); +std::vector> +getPolygonVertices(std::pair center, double radius, double angle_0, int numSides); } // namespace epic::geo diff --git a/src/HomogeneousCalorimeter_geo.cpp b/src/HomogeneousCalorimeter_geo.cpp index 80c89753a..28b915068 100644 --- a/src/HomogeneousCalorimeter_geo.cpp +++ b/src/HomogeneousCalorimeter_geo.cpp @@ -42,13 +42,12 @@ using namespace dd4hep; */ // headers -static std::tuple> add_12surface_disk(Detector& desc, Assembly& env, xml::Collection_t& plm, - SensitiveDetector& sens, int id); +static std::tuple> add_12surface_disk(Detector& desc, Assembly& env, + xml::Collection_t& plm, + SensitiveDetector& sens, int id); // helper function to get x, y, z if defined in a xml component -template -Position get_xml_xyz(XmlComp& comp, dd4hep::xml::Strng_t name) -{ +template Position get_xml_xyz(XmlComp& comp, dd4hep::xml::Strng_t name) { Position pos(0., 0., 0.); if (comp.hasChild(name)) { auto child = comp.child(name); @@ -60,142 +59,152 @@ Position get_xml_xyz(XmlComp& comp, dd4hep::xml::Strng_t name) } // main -static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens) { xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - DetElement det(detName, detID); + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + DetElement det(detName, detID); sens.setType("calorimeter"); // assembly Assembly assembly(detName); // module placement - xml::Component plm = detElem.child(_Unicode(placements)); - + xml::Component plm = detElem.child(_Unicode(placements)); std::map> sectorModuleRowsColumns; auto addRowColumnNumbers = [§orModuleRowsColumns](int sector, std::pair rowcolumn) { - auto it = sectorModuleRowsColumns.find(sector); - if (it != sectorModuleRowsColumns.end()) { - it->second = rowcolumn; - } else { - sectorModuleRowsColumns[sector] = rowcolumn; - } - }; - + auto it = sectorModuleRowsColumns.find(sector); + if (it != sectorModuleRowsColumns.end()) { + it->second = rowcolumn; + } else { + sectorModuleRowsColumns[sector] = rowcolumn; + } + }; int sector_id = 1; - for (xml::Collection_t disk_12surface(plm, _Unicode(disk_12surface)); disk_12surface; ++disk_12surface) { - auto [sector, rowcolumn] = add_12surface_disk(desc, assembly, disk_12surface, sens, sector_id++); + for (xml::Collection_t disk_12surface(plm, _Unicode(disk_12surface)); disk_12surface; + ++disk_12surface) { + auto [sector, rowcolumn] = + add_12surface_disk(desc, assembly, disk_12surface, sens, sector_id++); addRowColumnNumbers(sector, rowcolumn); } for (auto [sector, rowcolumn] : sectorModuleRowsColumns) { - desc.add(Constant(Form((detName + "_NModules_Sector%d").c_str(), sector), std::to_string((rowcolumn.first)), std::to_string((rowcolumn.second)) )); + desc.add(Constant(Form((detName + "_NModules_Sector%d").c_str(), sector), + std::to_string((rowcolumn.first)), std::to_string((rowcolumn.second)))); } - // detector position and rotation - auto pos = get_xml_xyz(detElem, _Unicode(position)); - auto rot = get_xml_xyz(detElem, _Unicode(rotation)); - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr = Translation3D(pos.x(), pos.y(), pos.z()) * RotationZYX(rot.z(), rot.y(), rot.x()); - PlacedVolume envPV = motherVol.placeVolume(assembly, tr); + auto pos = get_xml_xyz(detElem, _Unicode(position)); + auto rot = get_xml_xyz(detElem, _Unicode(rotation)); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr = + Translation3D(pos.x(), pos.y(), pos.z()) * RotationZYX(rot.z(), rot.y(), rot.x()); + PlacedVolume envPV = motherVol.placeVolume(assembly, tr); envPV.addPhysVolID("system", detID); det.setPlacement(envPV); return det; } // helper function to build module with or w/o wrapper -std::tuple build_module(Detector& desc, xml::Collection_t& plm, SensitiveDetector& sens) -{ - auto mod = plm.child(_Unicode(module)); - auto mx = mod.attr(_Unicode(modulex)); - auto my = mod.attr(_Unicode(moduley)); - auto mz = mod.attr(_Unicode(modulez)); - auto mdz = mod.attr(_Unicode(moduleshift)); - Box modshape(mx / 2., my / 2., mz / 2.); - auto modMat = desc.material(mod.attr(_Unicode(gmaterial))); +std::tuple build_module(Detector& desc, xml::Collection_t& plm, + SensitiveDetector& sens) { + auto mod = plm.child(_Unicode(module)); + auto mx = mod.attr(_Unicode(modulex)); + auto my = mod.attr(_Unicode(moduley)); + auto mz = mod.attr(_Unicode(modulez)); + auto mdz = mod.attr(_Unicode(moduleshift)); + Box modshape(mx / 2., my / 2., mz / 2.); + auto modMat = desc.material(mod.attr(_Unicode(gmaterial))); Volume modVol("module_vol", modshape, modMat); modVol.setVisAttributes(desc.visAttributes(mod.attr(_Unicode(vis)))); - auto cry = plm.child(_Unicode(crystal)); - auto cryx = cry.attr(_Unicode(sizex)); - auto cryy = cry.attr(_Unicode(sizey)); - auto cryz = cry.attr(_Unicode(sizez)); - auto roc = plm.child(_Unicode(readout)); - auto PCBx = roc.attr(_Unicode(PCB_sizex)); - auto PCBy = roc.attr(_Unicode(PCB_sizex)); - auto PCBz = roc.attr(_Unicode(PCB_thickness)); - auto sensorx = roc.attr(_Unicode(Sensor_sizex)); - auto sensory = roc.attr(_Unicode(Sensor_sizey)); - auto sensorz = roc.attr(_Unicode(Sensor_thickness)); - auto sensorspace = roc.attr(_Unicode(Sensor_space)); - auto sensorNx = roc.attr(_Unicode(Nsensor_X)); - auto sensorNy = roc.attr(_Unicode(Nsensor_Y)); - - Box crystalshape(cryx / 2., cryy / 2., cryz / 2.); - auto crystalMat = desc.material(cry.attr(_Unicode(material))); + auto cry = plm.child(_Unicode(crystal)); + auto cryx = cry.attr(_Unicode(sizex)); + auto cryy = cry.attr(_Unicode(sizey)); + auto cryz = cry.attr(_Unicode(sizez)); + auto roc = plm.child(_Unicode(readout)); + auto PCBx = roc.attr(_Unicode(PCB_sizex)); + auto PCBy = roc.attr(_Unicode(PCB_sizex)); + auto PCBz = roc.attr(_Unicode(PCB_thickness)); + auto sensorx = roc.attr(_Unicode(Sensor_sizex)); + auto sensory = roc.attr(_Unicode(Sensor_sizey)); + auto sensorz = roc.attr(_Unicode(Sensor_thickness)); + auto sensorspace = roc.attr(_Unicode(Sensor_space)); + auto sensorNx = roc.attr(_Unicode(Nsensor_X)); + auto sensorNy = roc.attr(_Unicode(Nsensor_Y)); + + Box crystalshape(cryx / 2., cryy / 2., cryz / 2.); + auto crystalMat = desc.material(cry.attr(_Unicode(material))); Volume crystalVol("crystal_vol", crystalshape, crystalMat); modVol.placeVolume(crystalVol, Position(0., 0., PCBz + sensorz + (cryz - mz) / 2.)); crystalVol.setVisAttributes(desc.visAttributes(cry.attr(_Unicode(cryvis)))); crystalVol.setSensitiveDetector(sens); - Box PCBshape(PCBx / 2., PCBy / 2., PCBz / 2.); - auto PCBMat = desc.material(roc.attr(_Unicode(material))); + Box PCBshape(PCBx / 2., PCBy / 2., PCBz / 2.); + auto PCBMat = desc.material(roc.attr(_Unicode(material))); Volume PCBVol("PCB_vol", PCBshape, PCBMat); modVol.placeVolume(PCBVol, Position(0., 0., (PCBz - mz) / 2.)); - Box sensorshape(sensorx / 2., sensory / 2., sensorz / 2.); - auto sensorMat = desc.material(roc.attr(_Unicode(material))); + Box sensorshape(sensorx / 2., sensory / 2., sensorz / 2.); + auto sensorMat = desc.material(roc.attr(_Unicode(material))); Volume sensorVol("sensor_vol", sensorshape, sensorMat); auto marginx = (PCBx - sensorNx * sensorx - (sensorNx - 1) * sensorspace) / 2.; auto marginy = (PCBy - sensorNy * sensory - (sensorNy - 1) * sensorspace) / 2.; - auto x0 = marginx + sensorx / 2. - PCBx / 2.; - auto y0 = marginy + sensory / 2. - PCBy / 2.; - for(int i = 0 ; i < sensorNx ; i++) - for(int j = 0 ; j < sensorNy ; j++) - modVol.placeVolume(sensorVol, Position(x0 + (sensorx + sensorspace) * i, y0 + (sensory + sensorspace) * j, PCBz + (sensorz - mz) / 2.)); - - - - if (!plm.hasChild(_Unicode(wrapper))){ // no wrapper + auto x0 = marginx + sensorx / 2. - PCBx / 2.; + auto y0 = marginy + sensory / 2. - PCBy / 2.; + for (int i = 0; i < sensorNx; i++) + for (int j = 0; j < sensorNy; j++) + modVol.placeVolume(sensorVol, + Position(x0 + (sensorx + sensorspace) * i, + y0 + (sensory + sensorspace) * j, PCBz + (sensorz - mz) / 2.)); + + if (!plm.hasChild(_Unicode(wrapper))) { // no wrapper printout(DEBUG, "HomogeneousCalorimeter", "without wrapper"); return std::make_tuple(modVol, Position{mx, my, mz}); - } - else{ // build wrapper - auto wrp = plm.child(_Unicode(wrapper)); // Read all the contents in the wrapper block + } else { // build wrapper + auto wrp = plm.child(_Unicode(wrapper)); // Read all the contents in the wrapper block auto wrapcfthickness = wrp.attr(_Unicode(carbonfiber_thickness)); auto wrapcflength = wrp.attr(_Unicode(carbonfiber_length)); auto wrapVMthickness = wrp.attr(_Unicode(VM2000_thickness)); - auto carbonMat = desc.material(wrp.attr(_Unicode(material_carbon))); - auto wrpMat = desc.material(wrp.attr(_Unicode(material_wrap))); - auto gapMat = desc.material(wrp.attr(_Unicode(material_gap))); + auto carbonMat = desc.material(wrp.attr(_Unicode(material_carbon))); + auto wrpMat = desc.material(wrp.attr(_Unicode(material_wrap))); + auto gapMat = desc.material(wrp.attr(_Unicode(material_gap))); if (wrapcfthickness < 1e-12 * mm) return std::make_tuple(modVol, Position{mx, my, mz}); Box carbonShape(mx / 2., my / 2., wrapcflength / 2.); - Box carbonShape_sub((mx - 2. * wrapcfthickness) / 2., (my - 2. * wrapcfthickness) / 2., wrapcflength / 2.); + Box carbonShape_sub((mx - 2. * wrapcfthickness) / 2., (my - 2. * wrapcfthickness) / 2., + wrapcflength / 2.); SubtractionSolid carbon_subtract(carbonShape, carbonShape_sub, Position(0., 0., 0.)); Box gapShape(mx / 2., my / 2., (cryz - 2. * wrapcflength) / 2.); - Box gapShape_sub((mx - 2. * wrapcfthickness) / 2., (my - 2. * wrapcfthickness) / 2., (cryz - 2. * wrapcflength) / 2.); + Box gapShape_sub((mx - 2. * wrapcfthickness) / 2., (my - 2. * wrapcfthickness) / 2., + (cryz - 2. * wrapcflength) / 2.); SubtractionSolid gap_subtract(gapShape, gapShape_sub, Position(0., 0., 0.)); - Box wrpVM2000((mx - 2. * wrapcfthickness) / 2., (my - 2. * wrapcfthickness) / 2., (cryz + mdz) / 2.); - Box wrpVM2000_sub((mx - 2. * wrapcfthickness - 2. * wrapVMthickness) / 2., (my - 2. * wrapcfthickness - 2. * wrapVMthickness) / 2., cryz / 2.); + Box wrpVM2000((mx - 2. * wrapcfthickness) / 2., (my - 2. * wrapcfthickness) / 2., + (cryz + mdz) / 2.); + Box wrpVM2000_sub((mx - 2. * wrapcfthickness - 2. * wrapVMthickness) / 2., + (my - 2. * wrapcfthickness - 2. * wrapVMthickness) / 2., cryz / 2.); SubtractionSolid wrpVM2000_subtract(wrpVM2000, wrpVM2000_sub, Position(0., 0., -mdz / 2.)); Volume carbonVol("carbon_vol", carbon_subtract, carbonMat); Volume gapVol("gap_vol", gap_subtract, gapMat); Volume wrpVol("wrapper_vol", wrpVM2000_subtract, wrpMat); - modVol.placeVolume(carbonVol, Position(0., 0., PCBz + sensorz + (wrapcflength - mz) / 2.)); // put the wrap in the both ends of crystal - modVol.placeVolume(carbonVol, Position(0., 0., PCBz + sensorz + cryz - (wrapcflength + mz) / 2.)); - modVol.placeVolume(gapVol, Position(0., 0., PCBz + sensorz + (cryz - mz) / 2. )); // put the gap between two carbon fiber + modVol.placeVolume(carbonVol, Position(0., 0., + PCBz + sensorz + + (wrapcflength - mz) / + 2.)); // put the wrap in the both ends of crystal + modVol.placeVolume(carbonVol, + Position(0., 0., PCBz + sensorz + cryz - (wrapcflength + mz) / 2.)); + modVol.placeVolume( + gapVol, + Position(0., 0., + PCBz + sensorz + (cryz - mz) / 2.)); // put the gap between two carbon fiber modVol.placeVolume(wrpVol, Position(0., 0., PCBz + sensorz + (cryz + mdz - mz) / 2.)); carbonVol.setVisAttributes(desc.visAttributes(wrp.attr(_Unicode(vis_carbon)))); @@ -209,56 +218,56 @@ std::tuple build_module(Detector& desc, xml::Collection_t& plm } // place 12 surface disk of modules -static std::tuple> add_12surface_disk(Detector& desc, Assembly& env, xml::Collection_t& plm, - SensitiveDetector& sens, int sid) -{ - auto [modVol, modSize] = build_module(desc, plm, sens); - int sector_id = dd4hep::getAttrOrDefault(plm, _Unicode(sector), sid); - double rmax = plm.attr(_Unicode(rmax)); - double r12min = plm.attr(_Unicode(r12min)); - double r12max = plm.attr(_Unicode(r12max)); - double structure_frame_length = plm.attr(_Unicode(outerringlength)); - double calo_module_length = plm.attr(_Unicode(modulelength)); - double Prot = plm.attr(_Unicode(protate)); - double Nrot = plm.attr(_Unicode(nrotate)); - double Oring_shift = plm.attr(_Unicode(outerringshift)); - double Innera = plm.attr(_Unicode(inneradiusa)); - double Innerb = plm.attr(_Unicode(inneradiusb)); - double phimin = dd4hep::getAttrOrDefault(plm, _Unicode(phimin), 0.); - double phimax = dd4hep::getAttrOrDefault(plm, _Unicode(phimax), 2. * M_PI); - - std::vector pt_innerframe_x; //The points information for inner supporting frame +static std::tuple> add_12surface_disk(Detector& desc, Assembly& env, + xml::Collection_t& plm, + SensitiveDetector& sens, int sid) { + auto [modVol, modSize] = build_module(desc, plm, sens); + int sector_id = dd4hep::getAttrOrDefault(plm, _Unicode(sector), sid); + double rmax = plm.attr(_Unicode(rmax)); + double r12min = plm.attr(_Unicode(r12min)); + double r12max = plm.attr(_Unicode(r12max)); + double structure_frame_length = plm.attr(_Unicode(outerringlength)); + double calo_module_length = plm.attr(_Unicode(modulelength)); + double Prot = plm.attr(_Unicode(protate)); + double Nrot = plm.attr(_Unicode(nrotate)); + double Oring_shift = plm.attr(_Unicode(outerringshift)); + double Innera = plm.attr(_Unicode(inneradiusa)); + double Innerb = plm.attr(_Unicode(inneradiusb)); + double phimin = dd4hep::getAttrOrDefault(plm, _Unicode(phimin), 0.); + double phimax = dd4hep::getAttrOrDefault(plm, _Unicode(phimax), 2. * M_PI); + + std::vector pt_innerframe_x; //The points information for inner supporting frame std::vector pt_innerframe_y; double half_modx = modSize.x() * 0.5, half_mody = modSize.y() * 0.5; - //========================================================= // Read the positions information from xml file //========================================================= xml_coll_t pts_extrudedpolygon(plm, _Unicode(points_extrudedpolygon)); - for (xml_coll_t position_i(pts_extrudedpolygon, _U(position)); position_i; ++position_i){ + for (xml_coll_t position_i(pts_extrudedpolygon, _U(position)); position_i; ++position_i) { xml_comp_t position_comp = position_i; pt_innerframe_x.push_back((position_comp.x())); pt_innerframe_y.push_back((position_comp.y())); } - //========================================================= // optional envelope volume and the supporting frame //========================================================= // Material for the structure and mother space // - Material outer_ring_material = desc.material(getAttrOrDefault(plm, _U(material), "StainlessSteel")); - Material inner_ring_material = desc.material(getAttrOrDefault(plm, _U(material), "Copper")); + Material outer_ring_material = + desc.material(getAttrOrDefault(plm, _U(material), "StainlessSteel")); + Material inner_ring_material = + desc.material(getAttrOrDefault(plm, _U(material), "Copper")); //============================== // Outer supporting frame //============================== PolyhedraRegular solid_ring12(12, r12min, r12max, structure_frame_length); - Volume ring12_vol("ring12", solid_ring12, outer_ring_material); - Transform3D tr_global_Oring = RotationZYX(Prot, 0., 0.) * Translation3D(0., 0., Oring_shift); + Volume ring12_vol("ring12", solid_ring12, outer_ring_material); + Transform3D tr_global_Oring = RotationZYX(Prot, 0., 0.) * Translation3D(0., 0., Oring_shift); ring12_vol.setVisAttributes(desc.visAttributes(plm.attr(_Unicode(vis_struc)))); //============================= @@ -272,90 +281,106 @@ static std::tuple> add_12surface_disk(Detector& desc, A std::vector sec_y = {0., 0.}; std::vector zscale = {1., 1.}; - ExtrudedPolygon inner_support_main(pt_innerframe_x, pt_innerframe_y, sec_z, sec_x, sec_y, zscale); - EllipticalTube subtract_a(Innera, Innerb, calo_module_length / 2.); + ExtrudedPolygon inner_support_main(pt_innerframe_x, pt_innerframe_y, sec_z, sec_x, sec_y, zscale); + EllipticalTube subtract_a(Innera, Innerb, calo_module_length / 2.); SubtractionSolid inner_support_substracta(inner_support_main, subtract_a, Position(0., 0., 0.)); - Volume inner_support_vol("inner_support_vol", inner_support_substracta, inner_ring_material); - inner_support_vol.setVisAttributes(desc.visAttributes(plm.attr(_Unicode(vis_struc)))); + Volume inner_support_vol("inner_support_vol", inner_support_substracta, inner_ring_material); + inner_support_vol.setVisAttributes( + desc.visAttributes(plm.attr(_Unicode(vis_struc)))); Transform3D tr_global_Iring_elli = RotationZYX(Nrot, 0., 0.) * Translation3D(0., 0., 0.); //============================= // The mother volume of modules //============================= - bool has_envelope = dd4hep::getAttrOrDefault(plm, _Unicode(envelope), false); + bool has_envelope = dd4hep::getAttrOrDefault(plm, _Unicode(envelope), false); PolyhedraRegular solid_world(12, 0., r12min, calo_module_length); - EllipticalTube solid_sub(Innera, Innerb, calo_module_length / 2.); - Transform3D subtract_pos = RotationZYX(Nrot, 0., 0.) * Translation3D(0., 0., 0.); + EllipticalTube solid_sub(Innera, Innerb, calo_module_length / 2.); + Transform3D subtract_pos = RotationZYX(Nrot, 0., 0.) * Translation3D(0., 0., 0.); SubtractionSolid calo_subtract(solid_world, solid_sub, subtract_pos); - Volume env_vol(std::string(env.name()) + "_envelope", calo_subtract, outer_ring_material); - Transform3D tr_global = RotationZYX(Prot, 0., 0.) * Translation3D(0., 0., 0.); + Volume env_vol(std::string(env.name()) + "_envelope", calo_subtract, outer_ring_material); + Transform3D tr_global = RotationZYX(Prot, 0., 0.) * Translation3D(0., 0., 0.); env_vol.setVisAttributes(desc.visAttributes(plm.attr(_Unicode(vis_steel_gap)))); // Place frames and mother volume of modules into the world volume // if (has_envelope) { - env.placeVolume(env_vol, tr_global); // Place the mother volume for all modules - env.placeVolume(ring12_vol, tr_global_Oring); // Place the outer supporting frame - env_vol.placeVolume(inner_support_vol, tr_global_Iring_elli); // Place the version3 inner supporting frame + env.placeVolume(env_vol, tr_global); // Place the mother volume for all modules + env.placeVolume(ring12_vol, tr_global_Oring); // Place the outer supporting frame + env_vol.placeVolume(inner_support_vol, + tr_global_Iring_elli); // Place the version3 inner supporting frame } - - //===================================================================== // Placing The Modules //===================================================================== - auto points = epic::geo::fillRectangles({half_modx, half_mody}, modSize.x(), modSize.y(), 0., (rmax/std::cos(Prot)), phimin, phimax); + auto points = epic::geo::fillRectangles({half_modx, half_mody}, modSize.x(), modSize.y(), 0., + (rmax / std::cos(Prot)), phimin, phimax); - std::pair c1 (0., 0.); - auto polyVertex = epic::geo::getPolygonVertices(c1, (rmax/std::cos(Prot)), M_PI/12., 12); + std::pair c1(0., 0.); + auto polyVertex = epic::geo::getPolygonVertices(c1, (rmax / std::cos(Prot)), M_PI / 12., 12); std::vector out_vertices, in_vertices; - for( auto p : polyVertex ){ + for (auto p : polyVertex) { epic::geo::Point a = {p.first, p.second}; out_vertices.push_back(a); } - for (xml_coll_t position_i(pts_extrudedpolygon, _U(position)); position_i; ++position_i){ + for (xml_coll_t position_i(pts_extrudedpolygon, _U(position)); position_i; ++position_i) { xml_comp_t position_comp = position_i; - epic::geo::Point inpt = {position_comp.x(), position_comp.y()}; + epic::geo::Point inpt = {position_comp.x(), position_comp.y()}; in_vertices.push_back(inpt); } double minX = 0., maxX = 0., minY = 0., maxY = 0.; - for (auto &square : points) { - epic::geo::Point box[4] = {{square.x() + half_modx, square.y() + half_mody}, {square.x() - half_modx, square.y() + half_mody}, {square.x() - half_modx, square.y() - half_mody}, {square.x() + half_modx, square.y() - half_mody}}; + for (auto& square : points) { + epic::geo::Point box[4] = {{square.x() + half_modx, square.y() + half_mody}, + {square.x() - half_modx, square.y() + half_mody}, + {square.x() - half_modx, square.y() - half_mody}, + {square.x() + half_modx, square.y() - half_mody}}; if (epic::geo::isBoxTotalInsidePolygon(box, out_vertices)) { - if( square.x() < minX ) minX = square.x(); - if( square.y() < minY ) minY = square.x(); - if( square.x() > maxX ) maxX = square.x(); - if( square.y() > maxY ) maxY = square.x(); + if (square.x() < minX) + minX = square.x(); + if (square.y() < minY) + minY = square.x(); + if (square.x() > maxX) + maxX = square.x(); + if (square.y() > maxY) + maxY = square.x(); } } int total_count = 0; int row = 0, column = 0; - int N_row = std::round((maxY - minY) / modSize.y()); - int N_column = std::round((maxX - minX) / modSize.x()); + int N_row = std::round((maxY - minY) / modSize.y()); + int N_column = std::round((maxX - minX) / modSize.x()); auto rowcolumn = std::make_pair(N_row, N_column); - for (auto &square : points) { - epic::geo::Point box[4] = {{square.x() + half_modx, square.y() + half_mody}, {square.x() - half_modx, square.y() + half_mody}, {square.x() - half_modx, square.y() - half_mody}, {square.x() + half_modx, square.y() - half_mody}}; + for (auto& square : points) { + epic::geo::Point box[4] = {{square.x() + half_modx, square.y() + half_mody}, + {square.x() - half_modx, square.y() + half_mody}, + {square.x() - half_modx, square.y() - half_mody}, + {square.x() + half_modx, square.y() - half_mody}}; if (epic::geo::isBoxTotalInsidePolygon(box, out_vertices)) { - if(!epic::geo::isBoxTotalInsidePolygon(box, in_vertices)) { + if (!epic::geo::isBoxTotalInsidePolygon(box, in_vertices)) { column = std::round((square.x() - minX) / modSize.x()); - row = std::round((maxY - square.y()) / modSize.y()); - Transform3D tr_local = RotationZYX(Nrot, 0.0, 0.0) * Translation3D(square.x(), square.y(), 0.0); - auto modPV = (has_envelope ? env_vol.placeVolume(modVol, tr_local) : env.placeVolume(modVol, tr_global * tr_local)); - modPV.addPhysVolID("sector", sector_id).addPhysVolID("row", row).addPhysVolID("column", column); + row = std::round((maxY - square.y()) / modSize.y()); + Transform3D tr_local = + RotationZYX(Nrot, 0.0, 0.0) * Translation3D(square.x(), square.y(), 0.0); + auto modPV = (has_envelope ? env_vol.placeVolume(modVol, tr_local) + : env.placeVolume(modVol, tr_global * tr_local)); + modPV.addPhysVolID("sector", sector_id) + .addPhysVolID("row", row) + .addPhysVolID("column", column); total_count++; } } } printout(DEBUG, "HomogeneousCalorimeter_geo", "Number of modules: %d", total_count); - printout(DEBUG, "HomogeneousCalorimeter_geo", "Min X, Y position of module: %.2f, %.2f", minX, minY); - printout(DEBUG, "HomogeneousCalorimeter_geo", "Max X, Y position of module: %.2f, %.2f", maxX, maxY); - + printout(DEBUG, "HomogeneousCalorimeter_geo", "Min X, Y position of module: %.2f, %.2f", minX, + minY); + printout(DEBUG, "HomogeneousCalorimeter_geo", "Max X, Y position of module: %.2f, %.2f", maxX, + maxY); return {sector_id, rowcolumn}; } diff --git a/src/IP6BeamPipe.cpp b/src/IP6BeamPipe.cpp index ae29929c9..d304da7eb 100644 --- a/src/IP6BeamPipe.cpp +++ b/src/IP6BeamPipe.cpp @@ -33,21 +33,20 @@ using namespace dd4hep; * \endcode * */ -static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) { using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); - xml_comp_t x_dettype = x_det.child(dd4hep::xml::Strng_t("type_flags")); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + xml_comp_t x_dettype = x_det.child(dd4hep::xml::Strng_t("type_flags")); unsigned int typeFlag = x_dettype.type(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Al = det.material("Aluminum"); - Material m_Be = det.material("Beryllium"); - Material m_Au = det.material("Gold"); - Material m_Vacuum = det.material("Vacuum"); - string vis_name = x_det.visStr(); + Assembly assembly(det_name + "_assembly"); + Material m_Al = det.material("Aluminum"); + Material m_Be = det.material("Beryllium"); + Material m_Au = det.material("Gold"); + Material m_Vacuum = det.material("Vacuum"); + string vis_name = x_det.visStr(); xml::Component IP_pipe_c = x_det.child(_Unicode(IP_pipe)); @@ -55,7 +54,8 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * double IP_beampipe_OD = IP_pipe_c.attr(_Unicode(OD)); double IP_beampipe_wall_thickness = IP_pipe_c.attr(_Unicode(wall_thickness)); double IP_beampipe_gold_thickness = IP_pipe_c.attr(_Unicode(gold_thickness)); - double IP_beampipe_ID = IP_beampipe_OD - 2.0 * IP_beampipe_gold_thickness - 2.0 * IP_beampipe_wall_thickness; + double IP_beampipe_ID = + IP_beampipe_OD - 2.0 * IP_beampipe_gold_thickness - 2.0 * IP_beampipe_wall_thickness; double IP_acts_beampipe_OD = IP_beampipe_ID - 5.0 * mm; double IP_acts_beampipe_ID = IP_acts_beampipe_OD - 1.0 * mm; @@ -63,17 +63,17 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * double downstream_straight_length = IP_pipe_c.attr(_Unicode(downstream_straight_length)); // central beampipe volume - Tube central_tube(0.5 * IP_acts_beampipe_ID, 0.5 * IP_acts_beampipe_OD, - 0.5 * (upstream_straight_length + downstream_straight_length)); - Volume central_volume("acts_central_beampipe_vol", central_tube, m_Vacuum); + Tube central_tube(0.5 * IP_acts_beampipe_ID, 0.5 * IP_acts_beampipe_OD, + 0.5 * (upstream_straight_length + downstream_straight_length)); + Volume central_volume("acts_central_beampipe_vol", central_tube, m_Vacuum); const double central_offset = -.5 * (upstream_straight_length - downstream_straight_length); - DetElement central_det(sdet, "acts_beampipe_central", 1); + DetElement central_det(sdet, "acts_beampipe_central", 1); // Set dd4hep variant parameters for conversion to ACTS tracking geometry central_det.setTypeFlag(typeFlag); - auto ¶ms = DD4hepDetectorHelper::ensureExtension(central_det); - int nBinPhi = 144; // fix later. Should take this from a xml tag - int nBinZ = 10; // fix later. Should take this from a xml tag + auto& params = DD4hepDetectorHelper::ensureExtension(central_det); + int nBinPhi = 144; // fix later. Should take this from a xml tag + int nBinZ = 10; // fix later. Should take this from a xml tag params.set("layer_material", true); params.set("layer_material_representing", true); params.set("layer_material_representing_binPhi", nBinPhi); @@ -93,28 +93,36 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * Tube downstream_IP_vacuum_fill(0.0, IP_acts_beampipe_ID / 2.0, downstream_straight_length / 2.0); Tube downstream_IP_acts_beampipe(IP_acts_beampipe_ID / 2.0, IP_acts_beampipe_OD / 2.0, downstream_straight_length / 2.0); - Tube downstream_IP_vacuum_padding(IP_acts_beampipe_OD / 2.0, IP_beampipe_ID / 2.0, downstream_straight_length / 2.0); + Tube downstream_IP_vacuum_padding(IP_acts_beampipe_OD / 2.0, IP_beampipe_ID / 2.0, + downstream_straight_length / 2.0); Tube downstream_IP_gold(IP_beampipe_ID / 2.0, IP_beampipe_ID / 2.0 + IP_beampipe_gold_thickness, downstream_straight_length / 2.0); Tube downstream_IP_tube(IP_beampipe_ID / 2.0 + IP_beampipe_gold_thickness, IP_beampipe_OD / 2.0, downstream_straight_length / 2.0); Tube upstream_IP_vacuum_fill(0.0, IP_acts_beampipe_ID / 2.0, upstream_straight_length / 2.0); - Tube upstream_IP_acts_beampipe(IP_acts_beampipe_ID / 2.0, IP_acts_beampipe_OD / 2.0, upstream_straight_length / 2.0); - Tube upstream_IP_vacuum_padding(IP_acts_beampipe_OD / 2.0, IP_beampipe_ID / 2.0, upstream_straight_length / 2.0); + Tube upstream_IP_acts_beampipe(IP_acts_beampipe_ID / 2.0, IP_acts_beampipe_OD / 2.0, + upstream_straight_length / 2.0); + Tube upstream_IP_vacuum_padding(IP_acts_beampipe_OD / 2.0, IP_beampipe_ID / 2.0, + upstream_straight_length / 2.0); Tube upstream_IP_gold(IP_beampipe_ID / 2.0, IP_beampipe_ID / 2.0 + IP_beampipe_gold_thickness, upstream_straight_length / 2.0); Tube upstream_IP_tube(IP_beampipe_ID / 2.0 + IP_beampipe_gold_thickness, IP_beampipe_OD / 2.0, upstream_straight_length / 2.0); - Volume v_downstream_IP_vacuum_fill("v_downstream_IP_vacuum_fill", downstream_IP_vacuum_fill, m_Vacuum); - Volume v_downstream_IP_acts_beampipe("v_downstream_IP_acts_beampipe", downstream_IP_acts_beampipe, m_Vacuum); - Volume v_downstream_IP_vacuum_padding("v_downstream_IP_vacuum_padding", downstream_IP_vacuum_padding, m_Vacuum); + Volume v_downstream_IP_vacuum_fill("v_downstream_IP_vacuum_fill", downstream_IP_vacuum_fill, + m_Vacuum); + Volume v_downstream_IP_acts_beampipe("v_downstream_IP_acts_beampipe", downstream_IP_acts_beampipe, + m_Vacuum); + Volume v_downstream_IP_vacuum_padding("v_downstream_IP_vacuum_padding", + downstream_IP_vacuum_padding, m_Vacuum); Volume v_downstream_IP_gold("v_downstream_IP_gold", downstream_IP_gold, m_Au); Volume v_downstream_IP_tube("v_downstream_IP_tube", downstream_IP_tube, m_Be); Volume v_upstream_IP_vacuum_fill("v_upstream_IP_vacuum_fill", upstream_IP_vacuum_fill, m_Vacuum); - Volume v_upstream_IP_acts_beampipe("v_upstream_IP_acts_beampipe", upstream_IP_acts_beampipe, m_Vacuum); - Volume v_upstream_IP_vacuum_padding("v_upstream_IP_vacuum_padding", upstream_IP_vacuum_padding, m_Vacuum); + Volume v_upstream_IP_acts_beampipe("v_upstream_IP_acts_beampipe", upstream_IP_acts_beampipe, + m_Vacuum); + Volume v_upstream_IP_vacuum_padding("v_upstream_IP_vacuum_padding", upstream_IP_vacuum_padding, + m_Vacuum); Volume v_upstream_IP_gold("v_upstream_IP_gold", upstream_IP_gold, m_Au); Volume v_upstream_IP_tube("v_upstream_IP_tube", upstream_IP_tube, m_Be); @@ -126,14 +134,17 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * assembly.placeVolume(v_upstream_IP_vacuum_fill, Position(0, 0, -upstream_straight_length / 2.0)); central_volume.placeVolume(v_upstream_IP_acts_beampipe, Position(0, 0, -upstream_straight_length / 2.0 - central_offset)); - assembly.placeVolume(v_upstream_IP_vacuum_padding, Position(0, 0, -upstream_straight_length / 2.0)); + assembly.placeVolume(v_upstream_IP_vacuum_padding, + Position(0, 0, -upstream_straight_length / 2.0)); assembly.placeVolume(v_upstream_IP_gold, Position(0, 0, -upstream_straight_length / 2.0)); assembly.placeVolume(v_upstream_IP_tube, Position(0, 0, -upstream_straight_length / 2.0)); - assembly.placeVolume(v_downstream_IP_vacuum_fill, Position(0, 0, downstream_straight_length / 2.0)); + assembly.placeVolume(v_downstream_IP_vacuum_fill, + Position(0, 0, downstream_straight_length / 2.0)); central_volume.placeVolume(v_downstream_IP_acts_beampipe, Position(0, 0, downstream_straight_length / 2.0 - central_offset)); - assembly.placeVolume(v_downstream_IP_vacuum_padding, Position(0, 0, downstream_straight_length / 2.0)); + assembly.placeVolume(v_downstream_IP_vacuum_padding, + Position(0, 0, downstream_straight_length / 2.0)); assembly.placeVolume(v_downstream_IP_gold, Position(0, 0, downstream_straight_length / 2.0)); assembly.placeVolume(v_downstream_IP_tube, Position(0, 0, downstream_straight_length / 2.0)); @@ -144,19 +155,21 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * auto zplane_to_polycones = [](xml::Component& x_pipe) { std::vector zero, rmax, rmin, z; for (xml_coll_t x_zplane_i(x_pipe, _Unicode(zplane)); x_zplane_i; ++x_zplane_i) { - xml_comp_t x_zplane = x_zplane_i; - auto thickness = getAttrOrDefault(x_zplane, _Unicode(thickness), x_pipe.thickness()); + xml_comp_t x_zplane = x_zplane_i; + auto thickness = getAttrOrDefault(x_zplane, _Unicode(thickness), x_pipe.thickness()); thickness += getAttrOrDefault(x_zplane, _Unicode(extra_thickness), 0.0); zero.push_back(0); rmax.push_back(x_zplane.attr(_Unicode(OD)) / 2.0); rmin.push_back(x_zplane.attr(_Unicode(OD)) / 2.0 - thickness); z.push_back(x_zplane.attr(_Unicode(z))); } - return std::make_pair({0, 2.0 * M_PI, rmin, rmax, z}, {0, 2.0 * M_PI, zero, rmin, z}); + return std::make_pair({0, 2.0 * M_PI, rmin, rmax, z}, + {0, 2.0 * M_PI, zero, rmin, z}); }; - auto create_volumes = [&](const std::string& name, xml::Component& x_pipe1, xml::Component& x_pipe2, - xml_coll_t& x_additional_subtraction_i, bool subtract_vacuum_from_matter = true, + auto create_volumes = [&](const std::string& name, xml::Component& x_pipe1, + xml::Component& x_pipe2, xml_coll_t& x_additional_subtraction_i, + bool subtract_vacuum_from_matter = true, bool subtract_matter_from_vacuum = false) { auto pipe1_polycones = zplane_to_polycones(x_pipe1); auto pipe2_polycones = zplane_to_polycones(x_pipe2); @@ -164,7 +177,8 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * auto crossing_angle = getAttrOrDefault(x_pipe2, _Unicode(crossing_angle), 0.0); auto axis_intersection = getAttrOrDefault(x_pipe2, _Unicode(axis_intersection), 0.0); - auto tf = Transform3D(Position(0, 0, axis_intersection)) * Transform3D(RotationY(crossing_angle)) * + auto tf = Transform3D(Position(0, 0, axis_intersection)) * + Transform3D(RotationY(crossing_angle)) * Transform3D(Position(0, 0, -axis_intersection)); // union of all matter and vacuum @@ -188,11 +202,13 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * // subtract additional vacuum from matter for (; x_additional_subtraction_i; ++x_additional_subtraction_i) { - xml_comp_t x_additional_subtraction = x_additional_subtraction_i; - auto additional_polycones = zplane_to_polycones(x_additional_subtraction); - auto additional_crossing_angle = getAttrOrDefault(x_additional_subtraction, _Unicode(crossing_angle), 0.0); - auto additional_axis_intersection = getAttrOrDefault(x_additional_subtraction, _Unicode(axis_intersection), 0.0); - auto additional_tf = Transform3D(Position(0, 0, additional_axis_intersection)) * + xml_comp_t x_additional_subtraction = x_additional_subtraction_i; + auto additional_polycones = zplane_to_polycones(x_additional_subtraction); + auto additional_crossing_angle = + getAttrOrDefault(x_additional_subtraction, _Unicode(crossing_angle), 0.0); + auto additional_axis_intersection = + getAttrOrDefault(x_additional_subtraction, _Unicode(axis_intersection), 0.0); + auto additional_tf = Transform3D(Position(0, 0, additional_axis_intersection)) * Transform3D(RotationY(additional_crossing_angle)) * Transform3D(Position(0, 0, -additional_axis_intersection)); matter = SubtractionSolid(matter, additional_polycones.second, additional_tf); @@ -210,12 +226,14 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * xml::Component upstream_c = x_det.child(_Unicode(upstream)); xml::Component incoming_hadron_c = upstream_c.child(_Unicode(incoming_hadron)); xml::Component outgoing_lepton_c = upstream_c.child(_Unicode(outgoing_lepton)); - xml_coll_t additional_subtractions_upstream(upstream_c, _Unicode(additional_subtraction)); - bool subtract_vacuum_upstream = getAttrOrDefault(upstream_c, _Unicode(subtract_vacuum), true); - bool subtract_matter_upstream = getAttrOrDefault(upstream_c, _Unicode(subtract_matter), true); - auto volumes_upstream = - create_volumes("upstream", outgoing_lepton_c, incoming_hadron_c, additional_subtractions_upstream, - subtract_vacuum_upstream, subtract_matter_upstream); + xml_coll_t additional_subtractions_upstream(upstream_c, _Unicode(additional_subtraction)); + bool subtract_vacuum_upstream = + getAttrOrDefault(upstream_c, _Unicode(subtract_vacuum), true); + bool subtract_matter_upstream = + getAttrOrDefault(upstream_c, _Unicode(subtract_matter), true); + auto volumes_upstream = create_volumes("upstream", outgoing_lepton_c, incoming_hadron_c, + additional_subtractions_upstream, subtract_vacuum_upstream, + subtract_matter_upstream); auto tf_upstream = Transform3D(RotationZYX(0, 0, 0)); if (getAttrOrDefault(upstream_c, _Unicode(reflect), true)) { @@ -235,12 +253,14 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * xml::Component downstream_c = x_det.child(_Unicode(downstream)); xml::Component incoming_lepton_c = downstream_c.child(_Unicode(incoming_lepton)); xml::Component outgoing_hadron_c = downstream_c.child(_Unicode(outgoing_hadron)); - xml_coll_t additional_subtractions_downstream(downstream_c, _Unicode(additional_subtraction)); - bool subtract_vacuum_downstream = getAttrOrDefault(downstream_c, _Unicode(subtract_vacuum), true); - bool subtract_matter_downstream = getAttrOrDefault(downstream_c, _Unicode(subtract_matter), true); - auto volumes_downstream = - create_volumes("downstream", incoming_lepton_c, outgoing_hadron_c, additional_subtractions_downstream, - subtract_vacuum_downstream, subtract_matter_downstream); + xml_coll_t additional_subtractions_downstream(downstream_c, _Unicode(additional_subtraction)); + bool subtract_vacuum_downstream = + getAttrOrDefault(downstream_c, _Unicode(subtract_vacuum), true); + bool subtract_matter_downstream = + getAttrOrDefault(downstream_c, _Unicode(subtract_matter), true); + auto volumes_downstream = create_volumes("downstream", incoming_lepton_c, outgoing_hadron_c, + additional_subtractions_downstream, + subtract_vacuum_downstream, subtract_matter_downstream); auto tf_downstream = Transform3D(RotationZYX(0, 0, 0)); if (getAttrOrDefault(downstream_c, _Unicode(reflect), true)) { diff --git a/src/InsertCalorimeter_geo.cpp b/src/InsertCalorimeter_geo.cpp index eb6df9549..5a7e8bfd0 100644 --- a/src/InsertCalorimeter_geo.cpp +++ b/src/InsertCalorimeter_geo.cpp @@ -15,16 +15,15 @@ using namespace dd4hep; -static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) -{ - xml_det_t detElem = handle; +static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) { + xml_det_t detElem = handle; std::string detName = detElem.nameStr(); - int detID = detElem.id(); + int detID = detElem.id(); - xml_dim_t dim = detElem.dimensions(); - double width = dim.x(); // Size along x-axis - double height = dim.y(); // Size along y-axis - double length = dim.z(); // Size along z-axis + xml_dim_t dim = detElem.dimensions(); + double width = dim.x(); // Size along x-axis + double height = dim.y(); // Size along y-axis + double length = dim.z(); // Size along z-axis xml_dim_t pos = detElem.position(); // Position in global coordinates @@ -32,23 +31,27 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens // Getting beampipe hole dimensions const xml::Component& beampipe_hole_xml = detElem.child(_Unicode(beampipe_hole)); - const double hole_radius_initial = - dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(initial_hole_radius), 14.61 * cm); + const double hole_radius_initial = dd4hep::getAttrOrDefault( + beampipe_hole_xml, _Unicode(initial_hole_radius), 14.61 * cm); const double hole_radius_final = dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(final_hole_radius), 17.17 * cm); const std::pair hole_radii_parameters(hole_radius_initial, hole_radius_final); // Subtract by pos.x() and pos.y() to convert from global to local coordinates const double hole_x_initial = - dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(initial_hole_x), -7.20 * cm) - pos.x(); + dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(initial_hole_x), -7.20 * cm) - + pos.x(); const double hole_x_final = - dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(final_hole_x), -10.44 * cm) - pos.x(); + dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(final_hole_x), -10.44 * cm) - + pos.x(); const std::pair hole_x_parameters(hole_x_initial, hole_x_final); const double hole_y_initial = - dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(initial_hole_y), 0. * cm) - pos.y(); + dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(initial_hole_y), 0. * cm) - + pos.y(); const double hole_y_final = - dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(final_hole_y), 0. * cm) - pos.y(); + dd4hep::getAttrOrDefault(beampipe_hole_xml, _Unicode(final_hole_y), 0. * cm) - + pos.y(); const std::pair hole_y_parameters(hole_y_initial, hole_y_final); // Getting thickness of backplate @@ -61,7 +64,9 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens Also has only one layer so don't have a backplate_thickness there (so set to 0) */ auto backplate_thickness = - detElem.hasChild(_Unicode(backplate)) ? detElem.child(_Unicode(backplate)).attr(_Unicode(thickness)) : 0.; + detElem.hasChild(_Unicode(backplate)) + ? detElem.child(_Unicode(backplate)).attr(_Unicode(thickness)) + : 0.; // Function that returns a linearly interpolated hole radius, x-position, and y-position at a given z auto get_hole_rxy = [hole_radii_parameters, hole_x_parameters, hole_y_parameters, length, @@ -73,17 +78,20 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens The radius is hole_radius_final at the beginning of the backplate, i.e. z = length - backplate_thickness */ - double hole_radius_slope = - (hole_radii_parameters.second - hole_radii_parameters.first) / (length - backplate_thickness); + double hole_radius_slope = (hole_radii_parameters.second - hole_radii_parameters.first) / + (length - backplate_thickness); double hole_radius_at_z = hole_radius_slope * z_pos + hole_radii_parameters.first; - double hole_xpos_slope = (hole_x_parameters.second - hole_x_parameters.first) / (length - backplate_thickness); - double hole_xpos_at_z = hole_xpos_slope * z_pos + hole_x_parameters.first; + double hole_xpos_slope = + (hole_x_parameters.second - hole_x_parameters.first) / (length - backplate_thickness); + double hole_xpos_at_z = hole_xpos_slope * z_pos + hole_x_parameters.first; - double hole_ypos_slope = (hole_y_parameters.second - hole_y_parameters.first) / (length - backplate_thickness); - double hole_ypos_at_z = hole_ypos_slope * z_pos + hole_y_parameters.first; + double hole_ypos_slope = + (hole_y_parameters.second - hole_y_parameters.first) / (length - backplate_thickness); + double hole_ypos_at_z = hole_ypos_slope * z_pos + hole_y_parameters.first; - std::tuple hole_rxy = std::make_tuple(hole_radius_at_z, hole_xpos_at_z, hole_ypos_at_z); + std::tuple hole_rxy = + std::make_tuple(hole_radius_at_z, hole_xpos_at_z, hole_ypos_at_z); return hole_rxy; }; @@ -101,42 +109,42 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens // Looping through all the different layer sections (W/Sc, Steel/Sc, backplate) for (xml_coll_t c(detElem, _U(layer)); c; c++) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - double layer_thickness = x_layer.thickness(); + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); + double layer_thickness = x_layer.thickness(); // Looping through the number of repeated layers in each section for (int i = 0; i < repeat; i++) { std::string layer_name = detName + _toString(layer_num, "_layer%d"); - Box layer(width / 2., height / 2., layer_thickness / 2.); + Box layer(width / 2., height / 2., layer_thickness / 2.); // Hole radius and position for each layer is determined from z position at the front of the layer const auto hole_rxy = get_hole_rxy(z_distance_traversed); - double hole_r = std::get<0>(hole_rxy); - double hole_x = std::get<1>(hole_rxy); - double hole_y = std::get<2>(hole_rxy); + double hole_r = std::get<0>(hole_rxy); + double hole_x = std::get<1>(hole_rxy); + double hole_y = std::get<2>(hole_rxy); // Removing beampipe shape from each layer - Tube layer_hole(0., hole_r, layer_thickness / 2.); + Tube layer_hole(0., hole_r, layer_thickness / 2.); SubtractionSolid layer_with_hole(layer, layer_hole, Position(hole_x, hole_y, 0.)); - Volume layer_vol(layer_name, layer_with_hole, air); + Volume layer_vol(layer_name, layer_with_hole, air); - int slice_num = 1; - double slice_z = -layer_thickness / 2.; // Keeps track of slices' z locations in each layer + int slice_num = 1; + double slice_z = -layer_thickness / 2.; // Keeps track of slices' z locations in each layer // Looping over each layer's slices for (xml_coll_t l(x_layer, _U(slice)); l; l++) { - xml_comp_t x_slice = l; - double slice_thickness = x_slice.thickness(); - std::string slice_name = layer_name + _toString(slice_num, "slice%d"); - Material slice_mat = desc.material(x_slice.materialStr()); + xml_comp_t x_slice = l; + double slice_thickness = x_slice.thickness(); + std::string slice_name = layer_name + _toString(slice_num, "slice%d"); + Material slice_mat = desc.material(x_slice.materialStr()); slice_z += slice_thickness / 2.; // Going to slice halfway point // Each slice within a layer has the same hole radius and x-y position - Box slice(width / 2., height / 2., slice_thickness / 2.); - Tube slice_hole(0., hole_r, slice_thickness / 2.); + Box slice(width / 2., height / 2., slice_thickness / 2.); + Tube slice_hole(0., hole_r, slice_thickness / 2.); SubtractionSolid slice_with_hole(slice, slice_hole, Position(hole_x, hole_y, 0.)); - Volume slice_vol(slice_name, slice_with_hole, slice_mat); + Volume slice_vol(slice_name, slice_with_hole, slice_mat); // Setting appropriate slices as sensitive if (x_slice.isSensitive()) { @@ -148,7 +156,8 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens slice_vol.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); // Placing slice within layer - pv = layer_vol.placeVolume(slice_vol, Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z))); + pv = layer_vol.placeVolume(slice_vol, + Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z))); pv.addPhysVolID("slice", slice_num); slice_z += slice_thickness / 2.; z_distance_traversed += slice_thickness; @@ -168,10 +177,10 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens Each loop over repeat will increases z_distance_traversed by layer_thickness */ pv = assembly.placeVolume( - layer_vol, - Transform3D( - RotationZYX(0, 0, 0), - Position(0., 0., -length / 2. + (z_distance_traversed - layer_thickness) + layer_thickness / 2.))); + layer_vol, Transform3D(RotationZYX(0, 0, 0), + Position(0., 0., + -length / 2. + (z_distance_traversed - layer_thickness) + + layer_thickness / 2.))); pv.addPhysVolID("layer", layer_num); layer_num++; @@ -179,10 +188,10 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens } DetElement det(detName, detID); - Volume motherVol = desc.pickMotherVolume(det); + Volume motherVol = desc.pickMotherVolume(det); // Placing insert in world volume - auto tr = Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.)); + auto tr = Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.)); PlacedVolume phv = motherVol.placeVolume(assembly, tr); phv.addPhysVolID("system", detID); det.setPlacement(phv); diff --git a/src/LFHCAL_geo.cpp b/src/LFHCAL_geo.cpp index fef21b5d2..d705263da 100644 --- a/src/LFHCAL_geo.cpp +++ b/src/LFHCAL_geo.cpp @@ -17,165 +17,163 @@ #include "XML/Utilities.h" using namespace dd4hep; -struct moduleParamsStrct{ - moduleParamsStrct(): mod_BIwidth(0.), mod_BIheight(0.), mod_SWThick(0.), mod_TWThick(0.), mod_FWThick (0.), - mod_BWThick(0.), mod_width(0.), mod_height(0.), - mod_notchDepth(0.), mod_notchHeight(0.), mod_foilThick(0.), mod_pcbLength(0.), mod_pcbThick(0.), mod_pcbWidth(0.), mod_visStr(""), mod_regStr(""), mod_limStr("") - {} - moduleParamsStrct( double BIwidth, double BIheight, double SWThick, double TWThick, double FWThick, double BWThick, double width, double height, - double notchDepth, double notchHeight, double foilThick, - double pcbLegth, double pcbThick, double pcbWidth, - std::string visStr, std::string regStr, std::string limStr){ - mod_BIwidth = BIwidth; - mod_BIheight = BIheight; - mod_SWThick = SWThick; - mod_TWThick = TWThick; - mod_FWThick = FWThick; - mod_BWThick = BWThick; - mod_width = width; - mod_height = height; - mod_notchDepth = notchDepth; - mod_notchHeight = notchHeight; - mod_foilThick = foilThick; - mod_pcbLength = pcbLegth; - mod_pcbThick = pcbThick; - mod_pcbWidth = pcbWidth; - mod_visStr = visStr; - mod_regStr = regStr; - mod_limStr = limStr; +struct moduleParamsStrct { + moduleParamsStrct() + : mod_BIwidth(0.) + , mod_BIheight(0.) + , mod_SWThick(0.) + , mod_TWThick(0.) + , mod_FWThick(0.) + , mod_BWThick(0.) + , mod_width(0.) + , mod_height(0.) + , mod_notchDepth(0.) + , mod_notchHeight(0.) + , mod_foilThick(0.) + , mod_pcbLength(0.) + , mod_pcbThick(0.) + , mod_pcbWidth(0.) + , mod_visStr("") + , mod_regStr("") + , mod_limStr("") {} + moduleParamsStrct(double BIwidth, double BIheight, double SWThick, double TWThick, double FWThick, + double BWThick, double width, double height, double notchDepth, + double notchHeight, double foilThick, double pcbLegth, double pcbThick, + double pcbWidth, std::string visStr, std::string regStr, std::string limStr) { + mod_BIwidth = BIwidth; + mod_BIheight = BIheight; + mod_SWThick = SWThick; + mod_TWThick = TWThick; + mod_FWThick = FWThick; + mod_BWThick = BWThick; + mod_width = width; + mod_height = height; + mod_notchDepth = notchDepth; + mod_notchHeight = notchHeight; + mod_foilThick = foilThick; + mod_pcbLength = pcbLegth; + mod_pcbThick = pcbThick; + mod_pcbWidth = pcbWidth; + mod_visStr = visStr; + mod_regStr = regStr; + mod_limStr = limStr; } - double mod_BIwidth = 0.; - double mod_BIheight = 0.; - double mod_SWThick = 0.; - double mod_TWThick = 0.; - double mod_FWThick = 0.; - double mod_BWThick = 0.; - double mod_width = 0.; - double mod_height = 0.; - double mod_notchDepth = 0.; - double mod_notchHeight = 0.; - double mod_foilThick = 0.; - double mod_pcbLength = 0.; - double mod_pcbThick = 0.; - double mod_pcbWidth = 0.; - std::string mod_visStr = ""; - std::string mod_regStr = ""; - std::string mod_limStr = ""; -} ; - -struct sliceParamsStrct{ - sliceParamsStrct(): layer_ID(0), slice_ID(0), slice_partID(0), slice_thick(0.), slice_offset(0.), slice_readoutLayer(0), slice_matStr(""), slice_visStr(""), slice_regStr(""), slice_limStr("") - {} - sliceParamsStrct( - int l_ID, int sl_ID, int sl_partID, double sl_thick, double sl_off, int l_rl, std::string sl_matStr, std::string sl_visStr, std::string sl_regStr, std::string sl_limStr ){ - layer_ID = l_ID; - slice_ID = sl_ID; - slice_partID = sl_partID; - slice_thick = sl_thick; - slice_offset = sl_off; - slice_readoutLayer = l_rl; - slice_matStr = sl_matStr; - slice_visStr = sl_visStr; - slice_regStr = sl_regStr; - slice_limStr = sl_limStr; + double mod_BIwidth = 0.; + double mod_BIheight = 0.; + double mod_SWThick = 0.; + double mod_TWThick = 0.; + double mod_FWThick = 0.; + double mod_BWThick = 0.; + double mod_width = 0.; + double mod_height = 0.; + double mod_notchDepth = 0.; + double mod_notchHeight = 0.; + double mod_foilThick = 0.; + double mod_pcbLength = 0.; + double mod_pcbThick = 0.; + double mod_pcbWidth = 0.; + std::string mod_visStr = ""; + std::string mod_regStr = ""; + std::string mod_limStr = ""; +}; +struct sliceParamsStrct { + sliceParamsStrct() + : layer_ID(0) + , slice_ID(0) + , slice_partID(0) + , slice_thick(0.) + , slice_offset(0.) + , slice_readoutLayer(0) + , slice_matStr("") + , slice_visStr("") + , slice_regStr("") + , slice_limStr("") {} + sliceParamsStrct(int l_ID, int sl_ID, int sl_partID, double sl_thick, double sl_off, int l_rl, + std::string sl_matStr, std::string sl_visStr, std::string sl_regStr, + std::string sl_limStr) { + layer_ID = l_ID; + slice_ID = sl_ID; + slice_partID = sl_partID; + slice_thick = sl_thick; + slice_offset = sl_off; + slice_readoutLayer = l_rl; + slice_matStr = sl_matStr; + slice_visStr = sl_visStr; + slice_regStr = sl_regStr; + slice_limStr = sl_limStr; } - int layer_ID = 0; - int slice_ID = 0; - int slice_partID = 0; - double slice_thick = 0.; - double slice_offset = 0.; - int slice_readoutLayer = 0; - std::string slice_matStr = ""; - std::string slice_visStr = ""; - std::string slice_regStr = ""; - std::string slice_limStr = ""; + int layer_ID = 0; + int slice_ID = 0; + int slice_partID = 0; + double slice_thick = 0.; + double slice_offset = 0.; + int slice_readoutLayer = 0; + std::string slice_matStr = ""; + std::string slice_visStr = ""; + std::string slice_regStr = ""; + std::string slice_limStr = ""; }; //************************************************************************************************************ //************************** Assembly for absorber plates *************************************************** //************************************************************************************************************ -Volume createAbsorberPlate(Detector& desc, - std::string basename, - double h_mod, - double w_mod, - double t_mod_tp, - double t_mod_sp, - double t_slice, - double w_notch, - double h_notch, - Material slice_mat, - std::string region, - std::string limit, - std::string vis, - bool renderComp -){ - - double w_plate = (w_mod/2-t_mod_sp)*2; - double l_A = -w_plate/2; - double l_B = -(w_plate/2-w_notch); - double r_A = w_plate/2; - // 0 1 2 3 4 - const std::vector xCoord = { l_A, r_A, r_A, l_A, l_A, - // 5 6 7 - l_B, l_B, l_A - }; - // 0 1 2 3 4 - - double topA = h_mod/2-t_mod_tp; - double topB = h_notch/2; - double botA = -(h_mod/2-t_mod_tp); - double botB = -(h_notch/2); - // 0 1 2 3 4 - const std::vector yCoord = { topA, topA, botA, botA, botB, - // 5 6 7 8 9 - botB, topB, topB - }; - - const std::vector zStep = {-t_slice/2, t_slice/2}; - const std::vector zStepX = {0., 0.}; - const std::vector zStepY = {0., 0.}; - const std::vector zStepScale = {1., 1.}; - - ExtrudedPolygon absplate = ExtrudedPolygon( xCoord, yCoord, zStep, zStepX, zStepY, zStepScale); - - Volume absplate_vol(basename, absplate, slice_mat); +Volume createAbsorberPlate(Detector& desc, std::string basename, double h_mod, double w_mod, + double t_mod_tp, double t_mod_sp, double t_slice, double w_notch, + double h_notch, Material slice_mat, std::string region, + std::string limit, std::string vis, bool renderComp) { + + double w_plate = (w_mod / 2 - t_mod_sp) * 2; + double l_A = -w_plate / 2; + double l_B = -(w_plate / 2 - w_notch); + double r_A = w_plate / 2; + // 0 1 2 3 4 + const std::vector xCoord = {l_A, r_A, r_A, l_A, l_A, + // 5 6 7 + l_B, l_B, l_A}; + // 0 1 2 3 4 + + double topA = h_mod / 2 - t_mod_tp; + double topB = h_notch / 2; + double botA = -(h_mod / 2 - t_mod_tp); + double botB = -(h_notch / 2); + // 0 1 2 3 4 + const std::vector yCoord = {topA, topA, botA, botA, botB, + // 5 6 7 8 9 + botB, topB, topB}; + + const std::vector zStep = {-t_slice / 2, t_slice / 2}; + const std::vector zStepX = {0., 0.}; + const std::vector zStepY = {0., 0.}; + const std::vector zStepScale = {1., 1.}; + + ExtrudedPolygon absplate = ExtrudedPolygon(xCoord, yCoord, zStep, zStepX, zStepY, zStepScale); + + Volume absplate_vol(basename, absplate, slice_mat); // Setting slice attributes - if (renderComp){ + if (renderComp) { absplate_vol.setAttributes(desc, region, limit, vis); } else { absplate_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters"); } - return absplate_vol; - } //************************************************************************************************************ //************************** Filler plate i.e. air & kapton & PCB & ESR //************************************************************************************************************ -Volume createFillerPlate( Detector& desc, - std::string basename, - double h_mod, - double w_mod, - double t_mod_tp, - double t_mod_sp, - double t_slice, - double w_notch, - Material slice_mat, - std::string region, - std::string limit, - std::string vis, - bool renderComp -){ - double w_plate = w_mod-2*t_mod_sp-w_notch; - double h_plate = h_mod-2*t_mod_tp; - - Box filler( w_plate / 2., h_plate / 2., t_slice / 2.); - Volume filler_vol(basename, filler, slice_mat); +Volume createFillerPlate(Detector& desc, std::string basename, double h_mod, double w_mod, + double t_mod_tp, double t_mod_sp, double t_slice, double w_notch, + Material slice_mat, std::string region, std::string limit, std::string vis, + bool renderComp) { + double w_plate = w_mod - 2 * t_mod_sp - w_notch; + double h_plate = h_mod - 2 * t_mod_tp; + + Box filler(w_plate / 2., h_plate / 2., t_slice / 2.); + Volume filler_vol(basename, filler, slice_mat); // Setting slice attributes - if (renderComp){ + if (renderComp) { filler_vol.setAttributes(desc, region, limit, vis); } else { filler_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters"); @@ -187,56 +185,35 @@ Volume createFillerPlate( Detector& desc, //************************************************************************************************************ //************************** single scintillator plate for tower ********************************************* //************************************************************************************************************ -Volume createScintillatorTower( Detector& desc, - std::string basename, - double w_tow, - double h_tow, - double t_slice, - Material slice_mat, - std::string region, - std::string limit, - std::string vis, - SensitiveDetector sens, - bool renderComp -){ - - Box scintplate( w_tow / 2., h_tow / 2., t_slice / 2.); - Volume slice_vol(basename, scintplate, slice_mat); - // Setting appropriate slices as sensitive +Volume createScintillatorTower(Detector& desc, std::string basename, double w_tow, double h_tow, + double t_slice, Material slice_mat, std::string region, + std::string limit, std::string vis, SensitiveDetector sens, + bool renderComp) { + + Box scintplate(w_tow / 2., h_tow / 2., t_slice / 2.); + Volume slice_vol(basename, scintplate, slice_mat); + // Setting appropriate slices as sensitive sens.setType("calorimeter"); slice_vol.setSensitiveDetector(sens); // Setting slice attributes - if (renderComp){ + if (renderComp) { slice_vol.setAttributes(desc, region, limit, vis); } else { slice_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters"); } return slice_vol; - } //************************************************************************************************************ //************************** create scintillator plate with separations for 8M ******************************* //************************************************************************************************************ -Assembly createScintillatorPlateEightM( Detector& desc, - std::string basename, -// int modID, - int layerID, - double h_mod, - double w_mod, - double t_mod_tp, - double t_mod_sp, - double t_slice, - double w_notch, - double t_foil, - Material slice_mat, - int roLayer, - std::string region, - std::string limit, - std::string vis, - SensitiveDetector sens, - bool renderComp -){ +Assembly createScintillatorPlateEightM(Detector& desc, std::string basename, + // int modID, + int layerID, double h_mod, double w_mod, double t_mod_tp, + double t_mod_sp, double t_slice, double w_notch, + double t_foil, Material slice_mat, int roLayer, + std::string region, std::string limit, std::string vis, + SensitiveDetector sens, bool renderComp) { // Tower placement in 8M module //====================================================================== //|| || || || || @@ -248,56 +225,59 @@ Assembly createScintillatorPlateEightM( Detector& desc, //|| || || || || //====================================================================== Assembly modScintAssembly(basename); - double w_plate = w_mod-w_notch-2*t_mod_sp-2*t_foil; - double h_plate = h_mod-2*t_mod_tp-2*t_foil; - double w_tow = (w_plate-6*t_foil)/4; - double h_tow = (h_plate-2*t_foil)/2; + double w_plate = w_mod - w_notch - 2 * t_mod_sp - 2 * t_foil; + double h_plate = h_mod - 2 * t_mod_tp - 2 * t_foil; + double w_tow = (w_plate - 6 * t_foil) / 4; + double h_tow = (h_plate - 2 * t_foil) / 2; // placement volumes PlacedVolume pvm; // foil separations // 0 1 2 3 4 - const std::vector xCoordTi = { -(w_plate/2.), -(w_tow+3*t_foil), -(w_tow+3*t_foil), -(w_tow+1*t_foil), -(w_tow+1*t_foil), - // 5 6 7 8 9 - -t_foil, -t_foil, t_foil, t_foil, w_tow+1*t_foil, - // 10 11 12 13 14 - w_tow+1*t_foil, w_tow+3*t_foil, w_tow+3*t_foil, w_plate/2., w_plate/2., - // 15 16 17 18 19 - w_tow+3*t_foil, w_tow+3*t_foil, w_tow+1*t_foil, w_tow+1*t_foil, t_foil, - // 20 21 22 23 24 - t_foil, -t_foil, -t_foil, -(w_tow+1*t_foil), -(w_tow+1*t_foil), - // 25 26 27 - -(w_tow+3*t_foil),-(w_tow+3*t_foil), -(w_plate/2.) - }; - // 0 1 2 3 4 - const std::vector yCoordTi = { t_foil, t_foil, (h_plate/2.), (h_plate/2.), t_foil, - // 5 6 7 8 9 - t_foil, (h_plate/2.), (h_plate/2.), t_foil, t_foil, - // 10 11 12 13 14 - (h_plate/2.), (h_plate/2.), t_foil, t_foil, -t_foil, - // 15 16 17 18 19 - -t_foil, -(h_plate/2.), -(h_plate/2.), -t_foil, -t_foil, - // 20 21 22 23 24 - -(h_plate/2.), -(h_plate/2.), -t_foil, -t_foil, -(h_plate/2.), - // 25 26 27 - -(h_plate/2.), -t_foil, -t_foil - }; - - const std::vector zStepTi = {-t_slice/2, t_slice/2}; - const std::vector zStepXTi = {0., 0.}; - const std::vector zStepYTi = {0., 0.}; - const std::vector zStepScaleTi = {1., 1.}; - - ExtrudedPolygon foilgrid = ExtrudedPolygon( xCoordTi, yCoordTi, zStepTi, zStepXTi, zStepYTi, zStepScaleTi); - Box foil_t( (w_plate+2*t_foil) / 2., t_foil / 2., t_slice / 2.); - Box foil_s( t_foil / 2., h_plate / 2., t_slice / 2.); - Volume foilgrid_vol(basename+"_ESRFoil_"+_toString(layerID, "_layer_%d"), foilgrid, slice_mat); - Volume foil_t_vol(basename+"_ESRFoilT_"+_toString(layerID, "_layer_%d"), foil_t, slice_mat); - Volume foil_b_vol(basename+"_ESRFoilB_"+_toString(layerID, "_layer_%d"), foil_t, slice_mat); - Volume foil_l_vol(basename+"_ESRFoilL_"+_toString(layerID, "_layer_%d"), foil_s, slice_mat); - Volume foil_r_vol(basename+"_ESRFoilR_"+_toString(layerID, "_layer_%d"), foil_s, slice_mat); + const std::vector xCoordTi = { + -(w_plate / 2.), -(w_tow + 3 * t_foil), -(w_tow + 3 * t_foil), -(w_tow + 1 * t_foil), + -(w_tow + 1 * t_foil), + // 5 6 7 8 9 + -t_foil, -t_foil, t_foil, t_foil, w_tow + 1 * t_foil, + // 10 11 12 13 14 + w_tow + 1 * t_foil, w_tow + 3 * t_foil, w_tow + 3 * t_foil, w_plate / 2., w_plate / 2., + // 15 16 17 18 19 + w_tow + 3 * t_foil, w_tow + 3 * t_foil, w_tow + 1 * t_foil, w_tow + 1 * t_foil, t_foil, + // 20 21 22 23 24 + t_foil, -t_foil, -t_foil, -(w_tow + 1 * t_foil), -(w_tow + 1 * t_foil), + // 25 26 27 + -(w_tow + 3 * t_foil), -(w_tow + 3 * t_foil), -(w_plate / 2.)}; + // 0 1 2 3 4 + const std::vector yCoordTi = { + t_foil, t_foil, (h_plate / 2.), (h_plate / 2.), t_foil, + // 5 6 7 8 9 + t_foil, (h_plate / 2.), (h_plate / 2.), t_foil, t_foil, + // 10 11 12 13 14 + (h_plate / 2.), (h_plate / 2.), t_foil, t_foil, -t_foil, + // 15 16 17 18 19 + -t_foil, -(h_plate / 2.), -(h_plate / 2.), -t_foil, -t_foil, + // 20 21 22 23 24 + -(h_plate / 2.), -(h_plate / 2.), -t_foil, -t_foil, -(h_plate / 2.), + // 25 26 27 + -(h_plate / 2.), -t_foil, -t_foil}; + + const std::vector zStepTi = {-t_slice / 2, t_slice / 2}; + const std::vector zStepXTi = {0., 0.}; + const std::vector zStepYTi = {0., 0.}; + const std::vector zStepScaleTi = {1., 1.}; + + ExtrudedPolygon foilgrid = + ExtrudedPolygon(xCoordTi, yCoordTi, zStepTi, zStepXTi, zStepYTi, zStepScaleTi); + Box foil_t((w_plate + 2 * t_foil) / 2., t_foil / 2., t_slice / 2.); + Box foil_s(t_foil / 2., h_plate / 2., t_slice / 2.); + Volume foilgrid_vol(basename + "_ESRFoil_" + _toString(layerID, "_layer_%d"), foilgrid, + slice_mat); + Volume foil_t_vol(basename + "_ESRFoilT_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat); + Volume foil_b_vol(basename + "_ESRFoilB_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat); + Volume foil_l_vol(basename + "_ESRFoilL_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat); + Volume foil_r_vol(basename + "_ESRFoilR_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat); // Setting slice attributes - if (renderComp){ + if (renderComp) { foilgrid_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis"); foil_t_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis"); foil_b_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis"); @@ -310,36 +290,45 @@ Assembly createScintillatorPlateEightM( Detector& desc, foil_l_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters"); foil_r_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters"); } - pvm = modScintAssembly.placeVolume(foilgrid_vol, Position(0, 0, 0 )); - pvm = modScintAssembly.placeVolume(foil_t_vol, Position(0, 1.5*t_foil+h_tow, 0 )); - pvm = modScintAssembly.placeVolume(foil_b_vol, Position(0, -(1.5*t_foil+h_tow), 0 )); - pvm = modScintAssembly.placeVolume(foil_l_vol, Position(-(3.5*t_foil+2*w_tow), 0, 0 )); - pvm = modScintAssembly.placeVolume(foil_r_vol, Position((3.5*t_foil+2*w_tow), 0, 0 )); + pvm = modScintAssembly.placeVolume(foilgrid_vol, Position(0, 0, 0)); + pvm = modScintAssembly.placeVolume(foil_t_vol, Position(0, 1.5 * t_foil + h_tow, 0)); + pvm = modScintAssembly.placeVolume(foil_b_vol, Position(0, -(1.5 * t_foil + h_tow), 0)); + pvm = modScintAssembly.placeVolume(foil_l_vol, Position(-(3.5 * t_foil + 2 * w_tow), 0, 0)); + pvm = modScintAssembly.placeVolume(foil_r_vol, Position((3.5 * t_foil + 2 * w_tow), 0, 0)); // 8M module placement of scintillator for tower - double rotZ[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - double rotY[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - double rotX[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - double posX[8] = {(w_tow*1.5+3*t_foil), (w_tow*0.5+t_foil), -(w_tow*0.5+t_foil), -(w_tow*1.5+3*t_foil), - (w_tow*1.5+3*t_foil), (w_tow*0.5+t_foil), -(w_tow*0.5+t_foil), -(w_tow*1.5+3*t_foil)}; - double posY[8] = {0.5*(h_tow)+t_foil, 0.5*(h_tow)+t_foil, 0.5*(h_tow)+t_foil, 0.5*(h_tow)+t_foil, - -(0.5*(h_tow)+t_foil), -(0.5*(h_tow)+t_foil), -(0.5*(h_tow)+t_foil), -(0.5*(h_tow)+t_foil)}; - double posZ[8] = {0, 0, 0, 0, - 0, 0, 0, 0}; - int towerx = 0; - int towery = 0; + double rotZ[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + double rotY[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + double rotX[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + double posX[8] = {(w_tow * 1.5 + 3 * t_foil), (w_tow * 0.5 + t_foil), + -(w_tow * 0.5 + t_foil), -(w_tow * 1.5 + 3 * t_foil), + (w_tow * 1.5 + 3 * t_foil), (w_tow * 0.5 + t_foil), + -(w_tow * 0.5 + t_foil), -(w_tow * 1.5 + 3 * t_foil)}; + double posY[8] = {0.5 * (h_tow) + t_foil, 0.5 * (h_tow) + t_foil, 0.5 * (h_tow) + t_foil, + 0.5 * (h_tow) + t_foil, -(0.5 * (h_tow) + t_foil), -(0.5 * (h_tow) + t_foil), + -(0.5 * (h_tow) + t_foil), -(0.5 * (h_tow) + t_foil)}; + double posZ[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int towerx = 0; + int towery = 0; // loop over all towers within same module - for (int i = 0; i < 8; i++){ + for (int i = 0; i < 8; i++) { // printout(DEBUG, "LFHCAL_geo", basename + _toString(i, "_tower_%d") + "\t" + _toString(modID) + "\t" + _toString(i) + "\t" + _toString(layerID)); - Volume modScintTowerAss = createScintillatorTower( desc, basename+ _toString(i, "_tower_%d"), - w_tow, h_tow, t_slice, - slice_mat, region, limit, vis, sens, renderComp); - pvm = modScintAssembly.placeVolume(modScintTowerAss, Transform3D(RotationZYX(rotZ[i], rotY[i], rotX[i]), Position(posX[i], posY[i], posZ[i] ))); - towerx = i%4; + Volume modScintTowerAss = + createScintillatorTower(desc, basename + _toString(i, "_tower_%d"), w_tow, h_tow, t_slice, + slice_mat, region, limit, vis, sens, renderComp); + pvm = modScintAssembly.placeVolume( + modScintTowerAss, + Transform3D(RotationZYX(rotZ[i], rotY[i], rotX[i]), Position(posX[i], posY[i], posZ[i]))); + towerx = i % 4; towery = 0; - if (i > 3) towery = 1; - pvm.addPhysVolID("towerx", towerx).addPhysVolID("towery", towery).addPhysVolID("layerz", layerID).addPhysVolID("passive", 0).addPhysVolID("rlayerz", roLayer); + if (i > 3) + towery = 1; + pvm.addPhysVolID("towerx", towerx) + .addPhysVolID("towery", towery) + .addPhysVolID("layerz", layerID) + .addPhysVolID("passive", 0) + .addPhysVolID("rlayerz", roLayer); } return modScintAssembly; } @@ -347,25 +336,13 @@ Assembly createScintillatorPlateEightM( Detector& desc, //************************************************************************************************************ //************************** create scintillator plate with separations for 4M ******************************* //************************************************************************************************************ -Assembly createScintillatorPlateFourM( Detector& desc, - std::string basename, -// int modID, - int layerID, - double h_mod, - double w_mod, - double t_mod_tp, - double t_mod_sp, - double t_slice, - double w_notch, - double t_foil, - Material slice_mat, - int roLayer, - std::string region, - std::string limit, - std::string vis, - SensitiveDetector sens, - bool renderComp -){ +Assembly createScintillatorPlateFourM(Detector& desc, std::string basename, + // int modID, + int layerID, double h_mod, double w_mod, double t_mod_tp, + double t_mod_sp, double t_slice, double w_notch, + double t_foil, Material slice_mat, int roLayer, + std::string region, std::string limit, std::string vis, + SensitiveDetector sens, bool renderComp) { // Tower placement in 4M module //-------------------------------- //| || | @@ -378,45 +355,57 @@ Assembly createScintillatorPlateFourM( Detector& desc, //-------------------------------- Assembly modScintAssembly(basename); - double w_plate = w_mod-w_notch-2*t_mod_sp-2*t_foil; - double h_plate = h_mod-2*t_mod_tp-2*t_foil; - double w_tow = (w_plate-2*t_foil)/2; - double h_tow = (h_plate-2*t_foil)/2; + double w_plate = w_mod - w_notch - 2 * t_mod_sp - 2 * t_foil; + double h_plate = h_mod - 2 * t_mod_tp - 2 * t_foil; + double w_tow = (w_plate - 2 * t_foil) / 2; + double h_tow = (h_plate - 2 * t_foil) / 2; // placement volumes PlacedVolume pvm; // foil separations - // 0 1 2 3 4 - const std::vector xCoordTi = { -(w_plate/2.), -t_foil, -t_foil, t_foil, t_foil, - // 5 6 7 8 9 - w_plate/2., w_plate/2., t_foil, t_foil, -t_foil, - // 10 11 - -t_foil, -(w_plate/2.) - }; - // 0 1 2 3 4 - const std::vector yCoordTi = { t_foil, t_foil, (h_plate/2.), (h_plate/2.), t_foil, - // 5 6 7 8 9 - t_foil, -t_foil, -t_foil, -(h_plate/2.), -(h_plate/2.), - // 10 11 - -t_foil, -t_foil, - }; - - const std::vector zStepTi = {-t_slice/2, t_slice/2}; - const std::vector zStepXTi = {0., 0.}; - const std::vector zStepYTi = {0., 0.}; - const std::vector zStepScaleTi = {1., 1.}; - - ExtrudedPolygon foilgrid = ExtrudedPolygon( xCoordTi, yCoordTi, zStepTi, zStepXTi, zStepYTi, zStepScaleTi); - Box foil_t( (w_plate+2*t_foil) / 2., t_foil / 2., t_slice / 2.); - Box foil_s( t_foil / 2., h_plate / 2., t_slice / 2.); - Volume foilgrid_vol(basename+"_ESRFoil_"+_toString(layerID, "_layer_%d"), foilgrid, slice_mat); - Volume foil_t_vol(basename+"_ESRFoilT_"+_toString(layerID, "_layer_%d"), foil_t, slice_mat); - Volume foil_b_vol(basename+"_ESRFoilB_"+_toString(layerID, "_layer_%d"), foil_t, slice_mat); - Volume foil_l_vol(basename+"_ESRFoilL_"+_toString(layerID, "_layer_%d"), foil_s, slice_mat); - Volume foil_r_vol(basename+"_ESRFoilR_"+_toString(layerID, "_layer_%d"), foil_s, slice_mat); + // 0 1 2 3 4 + const std::vector xCoordTi = { + -(w_plate / 2.), -t_foil, -t_foil, t_foil, t_foil, + // 5 6 7 8 9 + w_plate / 2., w_plate / 2., t_foil, t_foil, -t_foil, + // 10 11 + -t_foil, -(w_plate / 2.)}; + // 0 1 2 3 4 + const std::vector yCoordTi = { + t_foil, + t_foil, + (h_plate / 2.), + (h_plate / 2.), + t_foil, + // 5 6 7 8 9 + t_foil, + -t_foil, + -t_foil, + -(h_plate / 2.), + -(h_plate / 2.), + // 10 11 + -t_foil, + -t_foil, + }; + + const std::vector zStepTi = {-t_slice / 2, t_slice / 2}; + const std::vector zStepXTi = {0., 0.}; + const std::vector zStepYTi = {0., 0.}; + const std::vector zStepScaleTi = {1., 1.}; + + ExtrudedPolygon foilgrid = + ExtrudedPolygon(xCoordTi, yCoordTi, zStepTi, zStepXTi, zStepYTi, zStepScaleTi); + Box foil_t((w_plate + 2 * t_foil) / 2., t_foil / 2., t_slice / 2.); + Box foil_s(t_foil / 2., h_plate / 2., t_slice / 2.); + Volume foilgrid_vol(basename + "_ESRFoil_" + _toString(layerID, "_layer_%d"), foilgrid, + slice_mat); + Volume foil_t_vol(basename + "_ESRFoilT_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat); + Volume foil_b_vol(basename + "_ESRFoilB_" + _toString(layerID, "_layer_%d"), foil_t, slice_mat); + Volume foil_l_vol(basename + "_ESRFoilL_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat); + Volume foil_r_vol(basename + "_ESRFoilR_" + _toString(layerID, "_layer_%d"), foil_s, slice_mat); // Setting slice attributes - if (renderComp){ + if (renderComp) { foilgrid_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis"); foil_t_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis"); foil_b_vol.setAttributes(desc, region, limit, "LFHCALLayerSepVis"); @@ -429,37 +418,42 @@ Assembly createScintillatorPlateFourM( Detector& desc, foil_l_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters"); foil_r_vol.setAttributes(desc, region, limit, "InvisibleNoDaughters"); } - pvm = modScintAssembly.placeVolume(foilgrid_vol, Position(0, 0, 0 )); - pvm = modScintAssembly.placeVolume(foil_t_vol, Position(0, 1.5*t_foil+h_tow, 0 )); - pvm = modScintAssembly.placeVolume(foil_b_vol, Position(0, -(1.5*t_foil+h_tow), 0 )); - pvm = modScintAssembly.placeVolume(foil_l_vol, Position(-(1.5*t_foil+w_tow), 0, 0 )); - pvm = modScintAssembly.placeVolume(foil_r_vol, Position((1.5*t_foil+w_tow), 0, 0 )); - + pvm = modScintAssembly.placeVolume(foilgrid_vol, Position(0, 0, 0)); + pvm = modScintAssembly.placeVolume(foil_t_vol, Position(0, 1.5 * t_foil + h_tow, 0)); + pvm = modScintAssembly.placeVolume(foil_b_vol, Position(0, -(1.5 * t_foil + h_tow), 0)); + pvm = modScintAssembly.placeVolume(foil_l_vol, Position(-(1.5 * t_foil + w_tow), 0, 0)); + pvm = modScintAssembly.placeVolume(foil_r_vol, Position((1.5 * t_foil + w_tow), 0, 0)); // 4M module placement of scintillator for tower - double rotZ[4] = {0, 0, 0, 0 }; - double rotY[4] = {0, 0, 0, 0 }; - double rotX[4] = {0, 0, 0, 0 }; - double posX[4] = {(w_tow*0.5+t_foil), -(w_tow*0.5+t_foil), - (w_tow*0.5+t_foil), -(w_tow*0.5+t_foil)}; - double posY[4] = {0.5*(h_tow)+t_foil, 0.5*(h_tow)+t_foil, - -(0.5*(h_tow)+t_foil), -(0.5*(h_tow)+t_foil)}; - double posZ[4] = {0, 0, - 0, 0}; - int towerx = 0; - int towery = 0; + double rotZ[4] = {0, 0, 0, 0}; + double rotY[4] = {0, 0, 0, 0}; + double rotX[4] = {0, 0, 0, 0}; + double posX[4] = {(w_tow * 0.5 + t_foil), -(w_tow * 0.5 + t_foil), (w_tow * 0.5 + t_foil), + -(w_tow * 0.5 + t_foil)}; + double posY[4] = {0.5 * (h_tow) + t_foil, 0.5 * (h_tow) + t_foil, -(0.5 * (h_tow) + t_foil), + -(0.5 * (h_tow) + t_foil)}; + double posZ[4] = {0, 0, 0, 0}; + int towerx = 0; + int towery = 0; // loop over all towers within same module - for (int i = 0; i < 4; i++){ + for (int i = 0; i < 4; i++) { // printout(DEBUG, "LFHCAL_geo", basename + _toString(i, "_tower_%d") + "\t" + _toString(modID) + "\t" + _toString(i) + "\t" + _toString(layerID)); - Volume modScintTowerAss = createScintillatorTower( desc, basename+ _toString(i, "_tower_%d"), - w_tow, h_tow, t_slice, - slice_mat, region, limit, vis, sens, renderComp); - pvm = modScintAssembly.placeVolume(modScintTowerAss, Transform3D(RotationZYX(rotZ[i], rotY[i], rotX[i]), Position(posX[i], posY[i], posZ[i] ))); - towerx = i%2; + Volume modScintTowerAss = + createScintillatorTower(desc, basename + _toString(i, "_tower_%d"), w_tow, h_tow, t_slice, + slice_mat, region, limit, vis, sens, renderComp); + pvm = modScintAssembly.placeVolume( + modScintTowerAss, + Transform3D(RotationZYX(rotZ[i], rotY[i], rotX[i]), Position(posX[i], posY[i], posZ[i]))); + towerx = i % 2; towery = 0; - if (i > 1) towery = 1; - pvm.addPhysVolID("towerx", towerx).addPhysVolID("towery", towery).addPhysVolID("layerz", layerID).addPhysVolID("passive", 0).addPhysVolID("rlayerz", roLayer); + if (i > 1) + towery = 1; + pvm.addPhysVolID("towerx", towerx) + .addPhysVolID("towery", towery) + .addPhysVolID("layerz", layerID) + .addPhysVolID("passive", 0) + .addPhysVolID("rlayerz", roLayer); } return modScintAssembly; } @@ -467,20 +461,15 @@ Assembly createScintillatorPlateFourM( Detector& desc, //************************************************************************************************************ //************************** create 8M module assembly ****************************************************** //************************************************************************************************************ -Volume createEightMModule ( Detector& desc, - moduleParamsStrct mod_params, - std::vector sl_params, -// int modID, - double length, - SensitiveDetector sens, - bool renderComp, - bool allSen -){ +Volume createEightMModule(Detector& desc, moduleParamsStrct mod_params, + std::vector sl_params, + // int modID, + double length, SensitiveDetector sens, bool renderComp, bool allSen) { std::string baseName = "LFHCAL_8M"; // assembly definition - Box modBox( mod_params.mod_width / 2., mod_params.mod_height / 2., length / 2.); - Volume vol_mod(baseName,modBox,desc.material("Air")); + Box modBox(mod_params.mod_width / 2., mod_params.mod_height / 2., length / 2.); + Volume vol_mod(baseName, modBox, desc.material("Air")); vol_mod.setVisAttributes(desc.visAttributes(mod_params.mod_visStr.data())); // placement operator @@ -489,151 +478,229 @@ Volume createEightMModule ( Detector& desc, // Casing definition // ******************************************************************************** // geom definition 8M module casing - Box modFrontPlate( mod_params.mod_width / 2., mod_params.mod_height / 2., mod_params.mod_FWThick / 2.); - Box modSidePlateL( mod_params.mod_SWThick / 2., mod_params.mod_height / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modSidePlateR( mod_params.mod_SWThick / 2., mod_params.mod_height / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modTopPlate( (mod_params.mod_width-2*mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modBottomPlate( (mod_params.mod_width-2*mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modBackCutOut( mod_params.mod_BIwidth / 2., mod_params.mod_BIheight / 2., mod_params.mod_BWThick / 2.); - Box modBackPlateFull( mod_params.mod_width / 2., mod_params.mod_height / 2., mod_params.mod_BWThick / 2.); + Box modFrontPlate(mod_params.mod_width / 2., mod_params.mod_height / 2., + mod_params.mod_FWThick / 2.); + Box modSidePlateL(mod_params.mod_SWThick / 2., mod_params.mod_height / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modSidePlateR(mod_params.mod_SWThick / 2., mod_params.mod_height / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modTopPlate((mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., + mod_params.mod_TWThick / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modBottomPlate((mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., + mod_params.mod_TWThick / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modBackCutOut(mod_params.mod_BIwidth / 2., mod_params.mod_BIheight / 2., + mod_params.mod_BWThick / 2.); + Box modBackPlateFull(mod_params.mod_width / 2., mod_params.mod_height / 2., + mod_params.mod_BWThick / 2.); SubtractionSolid modBackPlate(modBackPlateFull, modBackCutOut); // volume definition 8M module casing - Volume vol_modFrontPlate(baseName+"_FrontPlate",modFrontPlate,desc.material("Steel235")); - Volume vol_modBackPlate(baseName+"_BackPlate",modBackPlate,desc.material("Steel235")); - Volume vol_modSidePlateL(baseName+"_LeftSidePlate",modSidePlateL,desc.material("Steel235")); - Volume vol_modSidePlateR(baseName+"_RightSidePlate",modSidePlateR,desc.material("Steel235")); - Volume vol_modTopPlate(baseName+"_TopPlate",modTopPlate,desc.material("Steel235")); - Volume vol_modBottomPlate(baseName+"_BottomPlate",modBottomPlate,desc.material("Steel235")); - - if (allSen){ - sens.setType("calorimeter"); - vol_modFrontPlate.setSensitiveDetector(sens); - vol_modBackPlate.setSensitiveDetector(sens); - vol_modSidePlateL.setSensitiveDetector(sens); - vol_modSidePlateR.setSensitiveDetector(sens); - vol_modTopPlate.setSensitiveDetector(sens); - vol_modBottomPlate.setSensitiveDetector(sens); + Volume vol_modFrontPlate(baseName + "_FrontPlate", modFrontPlate, desc.material("Steel235")); + Volume vol_modBackPlate(baseName + "_BackPlate", modBackPlate, desc.material("Steel235")); + Volume vol_modSidePlateL(baseName + "_LeftSidePlate", modSidePlateL, desc.material("Steel235")); + Volume vol_modSidePlateR(baseName + "_RightSidePlate", modSidePlateR, desc.material("Steel235")); + Volume vol_modTopPlate(baseName + "_TopPlate", modTopPlate, desc.material("Steel235")); + Volume vol_modBottomPlate(baseName + "_BottomPlate", modBottomPlate, desc.material("Steel235")); + + if (allSen) { + sens.setType("calorimeter"); + vol_modFrontPlate.setSensitiveDetector(sens); + vol_modBackPlate.setSensitiveDetector(sens); + vol_modSidePlateL.setSensitiveDetector(sens); + vol_modSidePlateR.setSensitiveDetector(sens); + vol_modTopPlate.setSensitiveDetector(sens); + vol_modBottomPlate.setSensitiveDetector(sens); } - if (renderComp){ - vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); + if (renderComp) { + vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); } else { - vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); + vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); } // ******************************************************************************** // long PCB // ******************************************************************************** - Box modPCB( mod_params.mod_pcbThick / 2., mod_params.mod_pcbWidth / 2., (mod_params.mod_pcbLength) / 2.); - Volume vol_modPCB(baseName+"_PCB",modPCB,desc.material("Fr4")); - if (renderComp){ + Box modPCB(mod_params.mod_pcbThick / 2., mod_params.mod_pcbWidth / 2., + (mod_params.mod_pcbLength) / 2.); + Volume vol_modPCB(baseName + "_PCB", modPCB, desc.material("Fr4")); + if (renderComp) { vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "LFHCALModPCB"); } else { - vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); + vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); } - int layer_num = 0; - double slice_z = -length/2+mod_params.mod_FWThick; // Keeps track of layers' local z locations + int layer_num = 0; + double slice_z = -length / 2 + mod_params.mod_FWThick; // Keeps track of layers' local z locations // Looping through the number of repeated layers & slices in each section - for (int i = 0; i < (int)sl_params.size(); i++){ - slice_z += sl_params[i].slice_offset + sl_params[i].slice_thick / 2.; // Going to halfway point in layer + for (int i = 0; i < (int)sl_params.size(); i++) { + slice_z += sl_params[i].slice_offset + + sl_params[i].slice_thick / 2.; // Going to halfway point in layer layer_num = sl_params[i].layer_ID; //************************************************* // absorber plates //************************************************* Material slice_mat = desc.material(sl_params[i].slice_matStr); - if (sl_params[i].slice_partID == 1 ){ - Volume modAbsAssembly = createAbsorberPlate( desc, - baseName+"_Abs"+_toString(sl_params[i].layer_ID, "_layer_%d"), - mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, mod_params.mod_SWThick, - sl_params[i].slice_thick, mod_params.mod_notchDepth, - mod_params.mod_notchHeight, - slice_mat, sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); + if (sl_params[i].slice_partID == 1) { + Volume modAbsAssembly = createAbsorberPlate( + desc, baseName + "_Abs" + _toString(sl_params[i].layer_ID, "_layer_%d"), + mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, + mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth, + mod_params.mod_notchHeight, slice_mat, sl_params[i].slice_regStr, + sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); // Placing slice within layer - if (allSen) modAbsAssembly.setSensitiveDetector(sens); - pvm = vol_mod.placeVolume(modAbsAssembly, Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z))); - if (allSen) pvm.addPhysVolID("towerx", 0).addPhysVolID("towery", 0).addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer).addPhysVolID("layerz", layer_num).addPhysVolID("passive", 1); - //************************************************* - // air & kapton & PCB & ESR - //************************************************* - } else if (sl_params[i].slice_partID == 2 ){ - Volume modFillAssembly = createFillerPlate( desc, - baseName+"_Fill"+_toString(sl_params[i].layer_ID, "_layer_%d")+_toString(sl_params[i].slice_ID, "slice_%d"), - mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, mod_params.mod_SWThick, - sl_params[i].slice_thick, mod_params.mod_notchDepth, - slice_mat, sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); + if (allSen) + modAbsAssembly.setSensitiveDetector(sens); + pvm = vol_mod.placeVolume(modAbsAssembly, + Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z))); + if (allSen) + pvm.addPhysVolID("towerx", 0) + .addPhysVolID("towery", 0) + .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer) + .addPhysVolID("layerz", layer_num) + .addPhysVolID("passive", 1); + //************************************************* + // air & kapton & PCB & ESR + //************************************************* + } else if (sl_params[i].slice_partID == 2) { + Volume modFillAssembly = + createFillerPlate(desc, + baseName + "_Fill" + _toString(sl_params[i].layer_ID, "_layer_%d") + + _toString(sl_params[i].slice_ID, "slice_%d"), + mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, + mod_params.mod_SWThick, sl_params[i].slice_thick, + mod_params.mod_notchDepth, slice_mat, sl_params[i].slice_regStr, + sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); // Placing slice within layer - if (allSen) modFillAssembly.setSensitiveDetector(sens); - pvm = vol_mod.placeVolume(modFillAssembly, Transform3D(RotationZYX(0, 0, 0), Position((mod_params.mod_notchDepth)/2., 0., slice_z))); - if (allSen) pvm.addPhysVolID("towerx", 1).addPhysVolID("towery", 0).addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer).addPhysVolID("layerz", layer_num).addPhysVolID("passive", 1); - //************************************************* - // scintillator - //************************************************* + if (allSen) + modFillAssembly.setSensitiveDetector(sens); + pvm = vol_mod.placeVolume( + modFillAssembly, Transform3D(RotationZYX(0, 0, 0), + Position((mod_params.mod_notchDepth) / 2., 0., slice_z))); + if (allSen) + pvm.addPhysVolID("towerx", 1) + .addPhysVolID("towery", 0) + .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer) + .addPhysVolID("layerz", layer_num) + .addPhysVolID("passive", 1); + //************************************************* + // scintillator + //************************************************* } else { - Assembly modScintAssembly = createScintillatorPlateEightM( desc, - baseName+"_ScintAssembly"+_toString(sl_params[i].layer_ID, "_layer_%d"), - layer_num, - mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, mod_params.mod_SWThick, - sl_params[i].slice_thick, mod_params.mod_notchDepth, mod_params.mod_foilThick, - slice_mat, sl_params[i].slice_readoutLayer ,sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, sens, renderComp); + Assembly modScintAssembly = createScintillatorPlateEightM( + desc, baseName + "_ScintAssembly" + _toString(sl_params[i].layer_ID, "_layer_%d"), + layer_num, mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, + mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth, + mod_params.mod_foilThick, slice_mat, sl_params[i].slice_readoutLayer, + sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, sens, + renderComp); // Placing slice within layer - pvm = vol_mod.placeVolume(modScintAssembly, Transform3D(RotationZYX(0, 0, 0), Position((mod_params.mod_notchDepth)/2., 0, slice_z))); + pvm = vol_mod.placeVolume( + modScintAssembly, Transform3D(RotationZYX(0, 0, 0), + Position((mod_params.mod_notchDepth) / 2., 0, slice_z))); } slice_z += sl_params[i].slice_thick / 2.; } // placement 8M module casing - pvm = vol_mod.placeVolume(vol_modFrontPlate, Position(0, 0, -( length-mod_params.mod_FWThick) / 2. )); - if (allSen) pvm.addPhysVolID("towerx", 2).addPhysVolID("towery", 0).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modBackPlate, Position(0, 0, ( length-mod_params.mod_BWThick) / 2. )); - if (allSen) pvm.addPhysVolID("towerx", 2).addPhysVolID("towery", 0).addPhysVolID("layerz", layer_num).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modSidePlateL, Position(-(mod_params.mod_width-mod_params.mod_SWThick)/2., 0, (mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 3).addPhysVolID("towery", 0).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modSidePlateR, Position((mod_params.mod_width-mod_params.mod_SWThick)/2., 0,(mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 0).addPhysVolID("towery", 1).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modTopPlate, Position(0, (mod_params.mod_height-mod_params.mod_TWThick)/2., (mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 1).addPhysVolID("towery", 1).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modBottomPlate, Position(0, -(mod_params.mod_height-mod_params.mod_TWThick)/2., (mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 2).addPhysVolID("towery", 1).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - - double lengthA = length-mod_params.mod_FWThick-mod_params.mod_BWThick; - double z_offSetPCB = (mod_params.mod_FWThick-mod_params.mod_BWThick)/2-(lengthA-mod_params.mod_pcbLength)/2.; - - pvm = vol_mod.placeVolume(vol_modPCB, Position(-(mod_params.mod_width-2*mod_params.mod_SWThick-mod_params.mod_notchDepth)/2., 0, z_offSetPCB)); + pvm = vol_mod.placeVolume(vol_modFrontPlate, + Position(0, 0, -(length - mod_params.mod_FWThick) / 2.)); + if (allSen) + pvm.addPhysVolID("towerx", 2) + .addPhysVolID("towery", 0) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = + vol_mod.placeVolume(vol_modBackPlate, Position(0, 0, (length - mod_params.mod_BWThick) / 2.)); + if (allSen) + pvm.addPhysVolID("towerx", 2) + .addPhysVolID("towery", 0) + .addPhysVolID("layerz", layer_num) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modSidePlateL, + Position(-(mod_params.mod_width - mod_params.mod_SWThick) / 2., 0, + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 3) + .addPhysVolID("towery", 0) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modSidePlateR, + Position((mod_params.mod_width - mod_params.mod_SWThick) / 2., 0, + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 0) + .addPhysVolID("towery", 1) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modTopPlate, + Position(0, (mod_params.mod_height - mod_params.mod_TWThick) / 2., + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 1) + .addPhysVolID("towery", 1) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modBottomPlate, + Position(0, -(mod_params.mod_height - mod_params.mod_TWThick) / 2., + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 2) + .addPhysVolID("towery", 1) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + + double lengthA = length - mod_params.mod_FWThick - mod_params.mod_BWThick; + double z_offSetPCB = (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2 - + (lengthA - mod_params.mod_pcbLength) / 2.; + + pvm = vol_mod.placeVolume( + vol_modPCB, + Position(-(mod_params.mod_width - 2 * mod_params.mod_SWThick - mod_params.mod_notchDepth) / + 2., + 0, z_offSetPCB)); return vol_mod; } - //************************************************************************************************************ //************************** create 8M module assembly ****************************************************** //************************************************************************************************************ -Volume createFourMModule ( Detector& desc, - moduleParamsStrct mod_params, - std::vector sl_params, -// int modID, - double length, - SensitiveDetector sens, - bool renderComp, - bool allSen -){ +Volume createFourMModule(Detector& desc, moduleParamsStrct mod_params, + std::vector sl_params, + // int modID, + double length, SensitiveDetector sens, bool renderComp, bool allSen) { std::string baseName = "LFHCAL_4M"; // assembly definition - Box modBox( mod_params.mod_width / 2., mod_params.mod_height / 2., length / 2.); - Volume vol_mod(baseName,modBox,desc.material("Air")); + Box modBox(mod_params.mod_width / 2., mod_params.mod_height / 2., length / 2.); + Volume vol_mod(baseName, modBox, desc.material("Air")); printout(DEBUG, "LFHCAL_geo", "visualization string module: " + mod_params.mod_visStr); vol_mod.setVisAttributes(desc.visAttributes(mod_params.mod_visStr.data())); @@ -643,126 +710,213 @@ Volume createFourMModule ( Detector& desc, // Casing definition // ******************************************************************************** // geom definition 8M module casing - Box modFrontPlate( mod_params.mod_width / 2., mod_params.mod_height / 2., mod_params.mod_FWThick / 2.); - Box modSidePlateL( mod_params.mod_SWThick / 2., mod_params.mod_height / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modSidePlateR( mod_params.mod_SWThick / 2., mod_params.mod_height / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modTopPlate( (mod_params.mod_width-2*mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modBottomPlate( (mod_params.mod_width-2*mod_params.mod_SWThick) / 2., mod_params.mod_TWThick / 2., (length-mod_params.mod_FWThick-mod_params.mod_BWThick) / 2.); - Box modBackCutOut( mod_params.mod_BIwidth / 2., mod_params.mod_BIheight / 2., mod_params.mod_BWThick / 2.); - Box modBackPlateFull( mod_params.mod_width / 2., mod_params.mod_height / 2., mod_params.mod_BWThick / 2.); + Box modFrontPlate(mod_params.mod_width / 2., mod_params.mod_height / 2., + mod_params.mod_FWThick / 2.); + Box modSidePlateL(mod_params.mod_SWThick / 2., mod_params.mod_height / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modSidePlateR(mod_params.mod_SWThick / 2., mod_params.mod_height / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modTopPlate((mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., + mod_params.mod_TWThick / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modBottomPlate((mod_params.mod_width - 2 * mod_params.mod_SWThick) / 2., + mod_params.mod_TWThick / 2., + (length - mod_params.mod_FWThick - mod_params.mod_BWThick) / 2.); + Box modBackCutOut(mod_params.mod_BIwidth / 2., mod_params.mod_BIheight / 2., + mod_params.mod_BWThick / 2.); + Box modBackPlateFull(mod_params.mod_width / 2., mod_params.mod_height / 2., + mod_params.mod_BWThick / 2.); SubtractionSolid modBackPlate(modBackPlateFull, modBackCutOut); // volume definition 8M module casing - Volume vol_modFrontPlate(baseName+"_FrontPlate",modFrontPlate,desc.material("Steel235")); - Volume vol_modBackPlate(baseName+"_BackPlate",modBackPlate,desc.material("Steel235")); - Volume vol_modSidePlateL(baseName+"_LeftSidePlate",modSidePlateL,desc.material("Steel235")); - Volume vol_modSidePlateR(baseName+"_RightSidePlate",modSidePlateR,desc.material("Steel235")); - Volume vol_modTopPlate(baseName+"_TopPlate",modTopPlate,desc.material("Steel235")); - Volume vol_modBottomPlate(baseName+"_BottomPlate",modBottomPlate,desc.material("Steel235")); - - if (allSen){ - sens.setType("calorimeter"); - vol_modFrontPlate.setSensitiveDetector(sens); - vol_modBackPlate.setSensitiveDetector(sens); - vol_modSidePlateL.setSensitiveDetector(sens); - vol_modSidePlateR.setSensitiveDetector(sens); - vol_modTopPlate.setSensitiveDetector(sens); - vol_modBottomPlate.setSensitiveDetector(sens); + Volume vol_modFrontPlate(baseName + "_FrontPlate", modFrontPlate, desc.material("Steel235")); + Volume vol_modBackPlate(baseName + "_BackPlate", modBackPlate, desc.material("Steel235")); + Volume vol_modSidePlateL(baseName + "_LeftSidePlate", modSidePlateL, desc.material("Steel235")); + Volume vol_modSidePlateR(baseName + "_RightSidePlate", modSidePlateR, desc.material("Steel235")); + Volume vol_modTopPlate(baseName + "_TopPlate", modTopPlate, desc.material("Steel235")); + Volume vol_modBottomPlate(baseName + "_BottomPlate", modBottomPlate, desc.material("Steel235")); + + if (allSen) { + sens.setType("calorimeter"); + vol_modFrontPlate.setSensitiveDetector(sens); + vol_modBackPlate.setSensitiveDetector(sens); + vol_modSidePlateL.setSensitiveDetector(sens); + vol_modSidePlateR.setSensitiveDetector(sens); + vol_modTopPlate.setSensitiveDetector(sens); + vol_modBottomPlate.setSensitiveDetector(sens); } - - if (renderComp){ - vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); - vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, mod_params.mod_visStr); + if (renderComp) { + vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); + vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + mod_params.mod_visStr); } else { - vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); - vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); + vol_modFrontPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modBackPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modSidePlateL.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modSidePlateR.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modTopPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); + vol_modBottomPlate.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); } // ******************************************************************************** // long PCB // ******************************************************************************** - Box modPCB( mod_params.mod_pcbThick / 2., mod_params.mod_pcbWidth / 2., (mod_params.mod_pcbLength) / 2.); - Volume vol_modPCB(baseName+"_PCB",modPCB,desc.material("Fr4")); - if (renderComp){ + Box modPCB(mod_params.mod_pcbThick / 2., mod_params.mod_pcbWidth / 2., + (mod_params.mod_pcbLength) / 2.); + Volume vol_modPCB(baseName + "_PCB", modPCB, desc.material("Fr4")); + if (renderComp) { vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "LFHCALModPCB"); } else { - vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, "InvisibleNoDaughters"); + vol_modPCB.setAttributes(desc, mod_params.mod_regStr, mod_params.mod_limStr, + "InvisibleNoDaughters"); } - int layer_num = 0; - double slice_z = -length/2+mod_params.mod_FWThick; // Keeps track of layers' local z locations + int layer_num = 0; + double slice_z = -length / 2 + mod_params.mod_FWThick; // Keeps track of layers' local z locations // Looping through the number of repeated layers & slices in each section - for (int i = 0; i < (int)sl_params.size(); i++){ - slice_z += sl_params[i].slice_offset + sl_params[i].slice_thick/2. ; // Going to halfway point in layer + for (int i = 0; i < (int)sl_params.size(); i++) { + slice_z += sl_params[i].slice_offset + + sl_params[i].slice_thick / 2.; // Going to halfway point in layer layer_num = sl_params[i].layer_ID; //************************************************* // absorber plates //************************************************* Material slice_mat = desc.material(sl_params[i].slice_matStr); - if (sl_params[i].slice_partID == 1 ){ - Volume modAbsAssembly = createAbsorberPlate( desc, baseName+"_Abs"+_toString(sl_params[i].layer_ID, "_layer_%d"), - mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, mod_params.mod_SWThick, - sl_params[i].slice_thick, mod_params.mod_notchDepth, mod_params.mod_notchHeight, - slice_mat, sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); + if (sl_params[i].slice_partID == 1) { + Volume modAbsAssembly = createAbsorberPlate( + desc, baseName + "_Abs" + _toString(sl_params[i].layer_ID, "_layer_%d"), + mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, + mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth, + mod_params.mod_notchHeight, slice_mat, sl_params[i].slice_regStr, + sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); // Placing slice within layer - if (allSen) modAbsAssembly.setSensitiveDetector(sens); - pvm = vol_mod.placeVolume(modAbsAssembly, Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z))); - if (allSen) pvm.addPhysVolID("towerx", 0).addPhysVolID("towery", 0).addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer).addPhysVolID("layerz", layer_num).addPhysVolID("passive", 1); - //************************************************* - // air & kapton & PCB & ESR - //************************************************* - } else if (sl_params[i].slice_partID == 2 ){ - Volume modFillAssembly = createFillerPlate( desc, - baseName+"_Fill"+_toString(sl_params[i].layer_ID, "_layer_%d")+_toString(sl_params[i].slice_ID, "slice_%d"), - mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, mod_params.mod_SWThick, - sl_params[i].slice_thick, mod_params.mod_notchDepth, - slice_mat, sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); + if (allSen) + modAbsAssembly.setSensitiveDetector(sens); + pvm = vol_mod.placeVolume(modAbsAssembly, + Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z))); + if (allSen) + pvm.addPhysVolID("towerx", 0) + .addPhysVolID("towery", 0) + .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer) + .addPhysVolID("layerz", layer_num) + .addPhysVolID("passive", 1); + //************************************************* + // air & kapton & PCB & ESR + //************************************************* + } else if (sl_params[i].slice_partID == 2) { + Volume modFillAssembly = + createFillerPlate(desc, + baseName + "_Fill" + _toString(sl_params[i].layer_ID, "_layer_%d") + + _toString(sl_params[i].slice_ID, "slice_%d"), + mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, + mod_params.mod_SWThick, sl_params[i].slice_thick, + mod_params.mod_notchDepth, slice_mat, sl_params[i].slice_regStr, + sl_params[i].slice_limStr, sl_params[i].slice_visStr, renderComp); // Placing slice within layer - if (allSen) modFillAssembly.setSensitiveDetector(sens); - pvm = vol_mod.placeVolume(modFillAssembly, Transform3D(RotationZYX(0, 0, 0), Position((mod_params.mod_notchDepth)/2.,0. , slice_z))); - if (allSen) pvm.addPhysVolID("towerx", 1).addPhysVolID("towery", 0).addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer).addPhysVolID("layerz", layer_num).addPhysVolID("passive", 1); - //************************************************* - // scintillator - //************************************************* + if (allSen) + modFillAssembly.setSensitiveDetector(sens); + pvm = vol_mod.placeVolume( + modFillAssembly, Transform3D(RotationZYX(0, 0, 0), + Position((mod_params.mod_notchDepth) / 2., 0., slice_z))); + if (allSen) + pvm.addPhysVolID("towerx", 1) + .addPhysVolID("towery", 0) + .addPhysVolID("rlayerz", sl_params[i].slice_readoutLayer) + .addPhysVolID("layerz", layer_num) + .addPhysVolID("passive", 1); + //************************************************* + // scintillator + //************************************************* } else { - Assembly modScintAssembly = createScintillatorPlateFourM( desc,baseName+"_ScintAssembly"+_toString(sl_params[i].layer_ID, "_layer_%d"), - layer_num, mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, mod_params.mod_SWThick, - sl_params[i].slice_thick, mod_params.mod_notchDepth, mod_params.mod_foilThick, - slice_mat, sl_params[i].slice_readoutLayer, sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, sens, renderComp); + Assembly modScintAssembly = createScintillatorPlateFourM( + desc, baseName + "_ScintAssembly" + _toString(sl_params[i].layer_ID, "_layer_%d"), + layer_num, mod_params.mod_height, mod_params.mod_width, mod_params.mod_TWThick, + mod_params.mod_SWThick, sl_params[i].slice_thick, mod_params.mod_notchDepth, + mod_params.mod_foilThick, slice_mat, sl_params[i].slice_readoutLayer, + sl_params[i].slice_regStr, sl_params[i].slice_limStr, sl_params[i].slice_visStr, sens, + renderComp); // Placing slice within layer - pvm = vol_mod.placeVolume(modScintAssembly, Transform3D(RotationZYX(0, 0, 0), Position((mod_params.mod_notchDepth)/2., 0, slice_z))); + pvm = vol_mod.placeVolume( + modScintAssembly, Transform3D(RotationZYX(0, 0, 0), + Position((mod_params.mod_notchDepth) / 2., 0, slice_z))); } - slice_z += sl_params[i].slice_thick/2.; + slice_z += sl_params[i].slice_thick / 2.; } // placement 4M module casing - pvm = vol_mod.placeVolume(vol_modFrontPlate, Position(0, 0, -( length-mod_params.mod_FWThick) / 2. )); - if (allSen) pvm.addPhysVolID("towerx", 2).addPhysVolID("towery", 0).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modBackPlate, Position(0, 0, ( length-mod_params.mod_BWThick) / 2. )); - if (allSen) pvm.addPhysVolID("towerx", 2).addPhysVolID("towery", 0).addPhysVolID("layerz", layer_num).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modSidePlateL, Position(-(mod_params.mod_width-mod_params.mod_SWThick)/2., 0, (mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 3).addPhysVolID("towery", 0).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modSidePlateR, Position((mod_params.mod_width-mod_params.mod_SWThick)/2., 0,(mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 0).addPhysVolID("towery", 1).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modTopPlate, Position(0, (mod_params.mod_height-mod_params.mod_TWThick)/2., (mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 1).addPhysVolID("towery", 1).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - pvm = vol_mod.placeVolume(vol_modBottomPlate, Position(0, -(mod_params.mod_height-mod_params.mod_TWThick)/2., (mod_params.mod_FWThick-mod_params.mod_BWThick)/2)); - if (allSen) pvm.addPhysVolID("towerx", 2).addPhysVolID("towery", 1).addPhysVolID("layerz", 0).addPhysVolID("passive", 1); - - double lengthA = length-mod_params.mod_FWThick-mod_params.mod_BWThick; - double z_offSetPCB = (mod_params.mod_FWThick-mod_params.mod_BWThick)/2-(lengthA-mod_params.mod_pcbLength)/2.; - - pvm = vol_mod.placeVolume(vol_modPCB, Position(-(mod_params.mod_width-2*mod_params.mod_SWThick-mod_params.mod_notchDepth)/2., 0, z_offSetPCB)); + pvm = vol_mod.placeVolume(vol_modFrontPlate, + Position(0, 0, -(length - mod_params.mod_FWThick) / 2.)); + if (allSen) + pvm.addPhysVolID("towerx", 2) + .addPhysVolID("towery", 0) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = + vol_mod.placeVolume(vol_modBackPlate, Position(0, 0, (length - mod_params.mod_BWThick) / 2.)); + if (allSen) + pvm.addPhysVolID("towerx", 2) + .addPhysVolID("towery", 0) + .addPhysVolID("layerz", layer_num) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modSidePlateL, + Position(-(mod_params.mod_width - mod_params.mod_SWThick) / 2., 0, + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 3) + .addPhysVolID("towery", 0) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modSidePlateR, + Position((mod_params.mod_width - mod_params.mod_SWThick) / 2., 0, + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 0) + .addPhysVolID("towery", 1) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modTopPlate, + Position(0, (mod_params.mod_height - mod_params.mod_TWThick) / 2., + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 1) + .addPhysVolID("towery", 1) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + pvm = vol_mod.placeVolume(vol_modBottomPlate, + Position(0, -(mod_params.mod_height - mod_params.mod_TWThick) / 2., + (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2)); + if (allSen) + pvm.addPhysVolID("towerx", 2) + .addPhysVolID("towery", 1) + .addPhysVolID("layerz", 0) + .addPhysVolID("passive", 1); + + double lengthA = length - mod_params.mod_FWThick - mod_params.mod_BWThick; + double z_offSetPCB = (mod_params.mod_FWThick - mod_params.mod_BWThick) / 2 - + (lengthA - mod_params.mod_pcbLength) / 2.; + + pvm = vol_mod.placeVolume( + vol_modPCB, + Position(-(mod_params.mod_width - 2 * mod_params.mod_SWThick - mod_params.mod_notchDepth) / + 2., + 0, z_offSetPCB)); return vol_mod; } @@ -772,26 +926,27 @@ Volume createFourMModule ( Detector& desc, //============================== MAIN FUNCTION ============================================= //* * //******************************************************************************************** -static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) -{ +static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) { // global detector variables - xml_det_t detElem = handle; + xml_det_t detElem = handle; std::string detName = detElem.nameStr(); - int detID = detElem.id(); + int detID = detElem.id(); // general detector dimensions - xml_dim_t dim = detElem.dimensions(); - double length = dim.z(); // Size along z-axis + xml_dim_t dim = detElem.dimensions(); + double length = dim.z(); // Size along z-axis // general detector position xml_dim_t pos = detElem.position(); - printout(DEBUG, "LFHCAL_geo", "global LFHCal position " + _toString(pos.x()) + "\t" + _toString(pos.y()) + "\t" + _toString(pos.z())); + printout(DEBUG, "LFHCAL_geo", + "global LFHCal position " + _toString(pos.x()) + "\t" + _toString(pos.y()) + "\t" + + _toString(pos.z())); // envelope volume xml_comp_t x_env = detElem.child(_Unicode(envelope)); Tube rmaxtube(0, dim.rmax(), dim.z() / 2); Box beampipe(dim.x() / 2, dim.y() / 2, dim.z() / 2); - Solid env = SubtractionSolid(rmaxtube, beampipe, Position(dim.x0(),0,0)); + Solid env = SubtractionSolid(rmaxtube, beampipe, Position(dim.x0(), 0, 0)); Volume env_vol(detName + "_env", env, desc.material(x_env.materialStr())); bool renderComponents = getAttrOrDefault(detElem, _Unicode(renderComponents), 0.); @@ -803,8 +958,8 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens } // 8M module specific loading - xml_comp_t eightM_xml = detElem.child(_Unicode(eightmodule)); - xml_dim_t eightMmod_dim = eightM_xml.dimensions(); + xml_comp_t eightM_xml = detElem.child(_Unicode(eightmodule)); + xml_dim_t eightMmod_dim = eightM_xml.dimensions(); moduleParamsStrct eightM_params(getAttrOrDefault(eightMmod_dim, _Unicode(widthBackInner), 0.), getAttrOrDefault(eightMmod_dim, _Unicode(heightBackInner), 0.), getAttrOrDefault(eightMmod_dim, _Unicode(widthSideWall), 0.), @@ -819,52 +974,50 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens getAttrOrDefault(eightMmod_dim, _Unicode(pcbLength), 0.), getAttrOrDefault(eightMmod_dim, _Unicode(pcbThick), 0.), getAttrOrDefault(eightMmod_dim, _Unicode(pcbWidth), 0.), - eightM_xml.visStr(), - eightM_xml.regionStr(), - eightM_xml.limitsStr() - ); + eightM_xml.visStr(), eightM_xml.regionStr(), + eightM_xml.limitsStr()); // 4M module specific loading - xml_comp_t fourM_xml = detElem.child(_Unicode(fourmodule)); - xml_dim_t fourMmod_dim = fourM_xml.dimensions(); - moduleParamsStrct fourM_params( getAttrOrDefault(fourMmod_dim, _Unicode(widthBackInner), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(heightBackInner), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(widthSideWall), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(widthTopWall), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(thicknessFrontWall), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(thicknessBackWall), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(width), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(height), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(notchDepth), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(notchHeight), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(foilThick), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(pcbLength), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(pcbThick), 0.), - getAttrOrDefault(fourMmod_dim, _Unicode(pcbWidth), 0.), - fourM_xml.visStr(), - fourM_xml.regionStr(), - fourM_xml.limitsStr()); + xml_comp_t fourM_xml = detElem.child(_Unicode(fourmodule)); + xml_dim_t fourMmod_dim = fourM_xml.dimensions(); + moduleParamsStrct fourM_params(getAttrOrDefault(fourMmod_dim, _Unicode(widthBackInner), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(heightBackInner), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(widthSideWall), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(widthTopWall), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(thicknessFrontWall), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(thicknessBackWall), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(width), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(height), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(notchDepth), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(notchHeight), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(foilThick), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(pcbLength), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(pcbThick), 0.), + getAttrOrDefault(fourMmod_dim, _Unicode(pcbWidth), 0.), + fourM_xml.visStr(), fourM_xml.regionStr(), fourM_xml.limitsStr()); std::vector slice_Params; - int layer_num = 0; - int readLayerC = 0; + int layer_num = 0; + int readLayerC = 0; for (xml_coll_t c(detElem, _U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - int readlayer = getAttrOrDefault(x_layer, _Unicode(readoutlayer), 0.); - if (readLayerC != readlayer){ - readLayerC = readlayer; - layer_num = 0; + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); + int readlayer = getAttrOrDefault(x_layer, _Unicode(readoutlayer), 0.); + if (readLayerC != readlayer) { + readLayerC = readlayer; + layer_num = 0; } // Looping through the number of repeated layers in each section for (int i = 0; i < repeat; i++) { - int slice_num = 1; + int slice_num = 1; // Looping over each layer's slices for (xml_coll_t l(x_layer, _U(slice)); l; ++l) { - xml_comp_t x_slice = l; - sliceParamsStrct slice_param( layer_num, slice_num, getAttrOrDefault(l, _Unicode(type), 0.), x_slice.thickness(), getAttrOrDefault(l, _Unicode(offset), 0.), readlayer, - x_slice.materialStr(), x_slice.visStr(), x_slice.regionStr(), x_slice.limitsStr()); + xml_comp_t x_slice = l; + sliceParamsStrct slice_param(layer_num, slice_num, getAttrOrDefault(l, _Unicode(type), 0.), + x_slice.thickness(), getAttrOrDefault(l, _Unicode(offset), 0.), + readlayer, x_slice.materialStr(), x_slice.visStr(), + x_slice.regionStr(), x_slice.limitsStr()); slice_Params.push_back(slice_param); ++slice_num; } @@ -880,71 +1033,93 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens int moduleIDx = -1; int moduleIDy = -1; - struct position { - double x,y,z; + double x, y, z; }; std::vector pos8M; xml_coll_t eightMPos(detElem, _Unicode(eightmodulepositions)); - for (xml_coll_t position_i(eightMPos, _U(position)); position_i; ++position_i){ + for (xml_coll_t position_i(eightMPos, _U(position)); position_i; ++position_i) { xml_comp_t position_comp = position_i; - if (! getAttrOrDefault(position_comp, _Unicode(if), true)) { - printout(DEBUG, "LFHCAL_geo", "skipping x = %.1f cm, y = %.1f cm", position_comp.x(), position_comp.y()); + if (!getAttrOrDefault(position_comp, _Unicode(if), true)) { + printout(DEBUG, "LFHCAL_geo", "skipping x = %.1f cm, y = %.1f cm", position_comp.x(), + position_comp.y()); continue; } pos8M.push_back({position_comp.x(), position_comp.y(), position_comp.z()}); } // create 8M modules - Volume eightMassembly = createEightMModule ( desc, eightM_params, slice_Params, length, sens, renderComponents, allSensitive); - for (int e = 0; e < (int)pos8M.size(); e++){ - if(e%20 == 0 ) printout(DEBUG, "LFHCAL_geo", "LFHCAL placing 8M module: " + _toString(e) + "/" + _toString((int)pos8M.size()) + "\t" + _toString(pos8M[e].x) + "\t" + _toString(pos8M[e].y) + "\t" + _toString(pos8M[e].z)); - if(moduleIDx<0 || moduleIDy<0){ - printout(DEBUG, "LFHCAL_geo", "LFHCAL WRONG ID FOR 8M module: " + _toString(e) + "/" + _toString((int)pos8M.size()) + "\t" + _toString(moduleIDx) + "\t" - + _toString(moduleIDy)); + Volume eightMassembly = createEightMModule(desc, eightM_params, slice_Params, length, sens, + renderComponents, allSensitive); + for (int e = 0; e < (int)pos8M.size(); e++) { + if (e % 20 == 0) + printout(DEBUG, "LFHCAL_geo", + "LFHCAL placing 8M module: " + _toString(e) + "/" + _toString((int)pos8M.size()) + + "\t" + _toString(pos8M[e].x) + "\t" + _toString(pos8M[e].y) + "\t" + + _toString(pos8M[e].z)); + if (moduleIDx < 0 || moduleIDy < 0) { + printout(DEBUG, "LFHCAL_geo", + "LFHCAL WRONG ID FOR 8M module: " + _toString(e) + "/" + + _toString((int)pos8M.size()) + "\t" + _toString(moduleIDx) + "\t" + + _toString(moduleIDy)); } - moduleIDx = ((pos8M[e].x + 270) / 10); - moduleIDy = ((pos8M[e].y + 265) / 10); + moduleIDx = ((pos8M[e].x + 270) / 10); + moduleIDy = ((pos8M[e].y + 265) / 10); // Placing modules in world volume - auto tr8M = Transform3D(Position(-pos8M[e].x-0.5*eightM_params.mod_width, -pos8M[e].y, pos8M[e].z)); + auto tr8M = + Transform3D(Position(-pos8M[e].x - 0.5 * eightM_params.mod_width, -pos8M[e].y, pos8M[e].z)); phv = assembly.placeVolume(eightMassembly, tr8M); - phv.addPhysVolID("moduleIDx", moduleIDx).addPhysVolID("moduleIDy", moduleIDy).addPhysVolID("moduletype", 0); + phv.addPhysVolID("moduleIDx", moduleIDx) + .addPhysVolID("moduleIDy", moduleIDy) + .addPhysVolID("moduletype", 0); } std::vector pos4M; xml_coll_t fourMPos(detElem, _Unicode(fourmodulepositions)); - for (xml_coll_t position_i(fourMPos, _U(position)); position_i; ++position_i){ + for (xml_coll_t position_i(fourMPos, _U(position)); position_i; ++position_i) { xml_comp_t position_comp = position_i; - if (! getAttrOrDefault(position_comp, _Unicode(if), true)) { - printout(DEBUG, "LFHCAL_geo", "skipping x = %.1f cm, y = %.1f cm", position_comp.x(), position_comp.y()); + if (!getAttrOrDefault(position_comp, _Unicode(if), true)) { + printout(DEBUG, "LFHCAL_geo", "skipping x = %.1f cm, y = %.1f cm", position_comp.x(), + position_comp.y()); continue; } pos4M.push_back({position_comp.x(), position_comp.y(), position_comp.z()}); } // create 4M modules - Volume fourMassembly = createFourMModule ( desc, fourM_params, slice_Params, length, sens, renderComponents, allSensitive); - for (int f = 0; f < (int)pos4M.size(); f++){ - if(f%20 == 0 ) printout(DEBUG, "LFHCAL_geo", "LFHCAL placing 4M module: " + _toString(f) + "/" + _toString((int)pos4M.size()) + "\t" + _toString(pos4M[f].x) + "\t" + _toString(pos4M[f].y) + "\t" + _toString(pos4M[f].z)); - - moduleIDx = ((pos4M[f].x + 265) / 10); - moduleIDy = ((pos4M[f].y + 265) / 10); - if(moduleIDx<0 || moduleIDy<0){ - printout(DEBUG, "LFHCAL_geo", "LFHCAL WRONG ID FOR 4M module: " + _toString(f) + "/" + _toString((int)pos4M.size()) + "\t" + _toString(moduleIDx) + "\t" - + _toString(moduleIDy)); + Volume fourMassembly = createFourMModule(desc, fourM_params, slice_Params, length, sens, + renderComponents, allSensitive); + for (int f = 0; f < (int)pos4M.size(); f++) { + if (f % 20 == 0) + printout(DEBUG, "LFHCAL_geo", + "LFHCAL placing 4M module: " + _toString(f) + "/" + _toString((int)pos4M.size()) + + "\t" + _toString(pos4M[f].x) + "\t" + _toString(pos4M[f].y) + "\t" + + _toString(pos4M[f].z)); + + moduleIDx = ((pos4M[f].x + 265) / 10); + moduleIDy = ((pos4M[f].y + 265) / 10); + if (moduleIDx < 0 || moduleIDy < 0) { + printout(DEBUG, "LFHCAL_geo", + "LFHCAL WRONG ID FOR 4M module: " + _toString(f) + "/" + + _toString((int)pos4M.size()) + "\t" + _toString(moduleIDx) + "\t" + + _toString(moduleIDy)); } - auto tr4M = Transform3D(Position(-pos4M[f].x-0.5*fourM_params.mod_width, -pos4M[f].y, pos4M[f].z)); + auto tr4M = + Transform3D(Position(-pos4M[f].x - 0.5 * fourM_params.mod_width, -pos4M[f].y, pos4M[f].z)); phv = assembly.placeVolume(fourMassembly, tr4M); - phv.addPhysVolID("moduleIDx", moduleIDx).addPhysVolID("moduleIDy", moduleIDy).addPhysVolID("moduletype", 1); + phv.addPhysVolID("moduleIDx", moduleIDx) + .addPhysVolID("moduleIDy", moduleIDy) + .addPhysVolID("moduletype", 1); } Volume motherVol = desc.pickMotherVolume(det); - phv = env_vol.placeVolume(assembly); - phv = motherVol.placeVolume(env_vol, Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.))); + phv = env_vol.placeVolume(assembly); + phv = motherVol.placeVolume(env_vol, + Transform3D(Position(pos.x(), pos.y(), pos.z() + length / 2.))); phv.addPhysVolID("system", detID); det.setPlacement(phv); diff --git a/src/LumiCollimator_geo.cpp b/src/LumiCollimator_geo.cpp index 2f48b98d1..4d3da4d02 100644 --- a/src/LumiCollimator_geo.cpp +++ b/src/LumiCollimator_geo.cpp @@ -13,44 +13,43 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /* sens */) { using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Steel = description.material("StainlessSteel"); - string vis_name = x_det.visStr(); + Assembly assembly(det_name + "_assembly"); + Material m_Steel = description.material("StainlessSteel"); + string vis_name = x_det.visStr(); // Create outer box xml::Component box_dim = x_det.child(_Unicode(dimensions_outer)); - double height = box_dim.attr(_Unicode(y)); - double width = box_dim.attr(_Unicode(x)); - double depth = box_dim.attr(_Unicode(z)); + double height = box_dim.attr(_Unicode(y)); + double width = box_dim.attr(_Unicode(x)); + double depth = box_dim.attr(_Unicode(z)); Box box_outer(width, height, depth); // Create inner box xml::Component box_dim_2 = x_det.child(_Unicode(dimensions_inner)); - double height_2 = box_dim_2.attr(_Unicode(y)); - double width_2 = box_dim_2.attr(_Unicode(x)); - double depth_2 = box_dim_2.attr(_Unicode(z)); + double height_2 = box_dim_2.attr(_Unicode(y)); + double width_2 = box_dim_2.attr(_Unicode(x)); + double depth_2 = box_dim_2.attr(_Unicode(z)); Box box_inner(width_2, height_2, depth_2); // Sets box positions xml::Component box_pos = x_det.child(_Unicode(position)); - double x = box_pos.attr(_Unicode(x)); - double y = box_pos.attr(_Unicode(y)); - double z = box_pos.attr(_Unicode(z)); + double x = box_pos.attr(_Unicode(x)); + double y = box_pos.attr(_Unicode(y)); + double z = box_pos.attr(_Unicode(z)); // Subtractes the volume of the inner box from the outer box - BooleanSolid collimator = SubtractionSolid(box_outer, box_inner); + BooleanSolid collimator = SubtractionSolid(box_outer, box_inner); // Assembles the collimator and sets its material - Volume v_collimator( det_name + "_vol_collimator", collimator , m_Steel); + Volume v_collimator(det_name + "_vol_collimator", collimator, m_Steel); sdet.setAttributes(description, v_collimator, x_det.regionStr(), x_det.limitsStr(), vis_name); diff --git a/src/LumiDirectPC_geo.cpp b/src/LumiDirectPC_geo.cpp index ebf738561..6438fcd40 100644 --- a/src/LumiDirectPC_geo.cpp +++ b/src/LumiDirectPC_geo.cpp @@ -12,39 +12,38 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml_h e, SensitiveDetector sens) { sens.setType("calorimeter"); - xml_det_t x_det = e; - xml_comp_t x_dim = x_det.dimensions(); - xml_comp_t x_pos = x_det.position(); - xml_comp_t x_rot = x_det.rotation(); + xml_det_t x_det = e; + xml_comp_t x_dim = x_det.dimensions(); + xml_comp_t x_pos = x_det.position(); + xml_comp_t x_rot = x_det.rotation(); // - string det_name = x_det.nameStr(); - string mat_name = dd4hep::getAttrOrDefault( x_det, _U(material), "PbWO4" ); - int det_ID =x_det.id(); + string det_name = x_det.nameStr(); + string mat_name = dd4hep::getAttrOrDefault(x_det, _U(material), "PbWO4"); + int det_ID = x_det.id(); DetElement det(det_name, det_ID); // - double sizeX = x_dim.x(); - double sizeY = x_dim.y(); - double sizeZ = x_dim.z(); - double posX = x_pos.x(); - double posY = x_pos.y(); - double posZ = x_pos.z(); - double rotX = x_rot.x(); - double rotY = x_rot.y(); - double rotZ = x_rot.z(); - - Box box( sizeX, sizeY, sizeZ ); - Volume vol( det_name + "_vol", box, desc.material( mat_name ) ); + double sizeX = x_dim.x(); + double sizeY = x_dim.y(); + double sizeZ = x_dim.z(); + double posX = x_pos.x(); + double posY = x_pos.y(); + double posZ = x_pos.z(); + double rotX = x_rot.x(); + double rotY = x_rot.y(); + double rotZ = x_rot.z(); + + Box box(sizeX, sizeY, sizeZ); + Volume vol(det_name + "_vol", box, desc.material(mat_name)); vol.setVisAttributes(desc.visAttributes(x_det.visStr())); vol.setSensitiveDetector(sens); - Transform3D pos( RotationZYX(rotX, rotY, rotZ), Position(posX, posY, posZ) ); + Transform3D pos(RotationZYX(rotX, rotY, rotZ), Position(posX, posY, posZ)); - Volume motherVol = desc.pickMotherVolume( det ); - PlacedVolume phv = motherVol.placeVolume( vol, pos ); + Volume motherVol = desc.pickMotherVolume(det); + PlacedVolume phv = motherVol.placeVolume(vol, pos); phv.addPhysVolID("system", det_ID); det.setPlacement(phv); return det; diff --git a/src/LumiMagnets_geo.cpp b/src/LumiMagnets_geo.cpp index 2b9d80f95..9ca0a33d2 100644 --- a/src/LumiMagnets_geo.cpp +++ b/src/LumiMagnets_geo.cpp @@ -9,125 +9,121 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) { using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Iron = det.material("Iron"); - Material m_Copper = det.material("Copper"); + Assembly assembly(det_name + "_assembly"); + Material m_Iron = det.material("Iron"); + Material m_Copper = det.material("Copper"); const string vis1 = getAttrOrDefault(x_det, _Unicode(vis_name1), "AnlGreen"); const string vis2 = getAttrOrDefault(x_det, _Unicode(vis_name2), "AnlRed"); const string vis3 = getAttrOrDefault(x_det, _Unicode(vis_name3), "AnlGray"); // Creates the outer box for the main body xml::Component box_dim = x_det.child(_Unicode(dimensions_mainbody_outer)); - double height = box_dim.attr(_Unicode(y)); - double width = box_dim.attr(_Unicode(x)); - double depth = box_dim.attr(_Unicode(z)); + double height = box_dim.attr(_Unicode(y)); + double width = box_dim.attr(_Unicode(x)); + double depth = box_dim.attr(_Unicode(z)); - Box box_outer(width/2., height/2., depth/2.); + Box box_outer(width / 2., height / 2., depth / 2.); // Creates the innner box for the main body xml::Component box_dim_2 = x_det.child(_Unicode(dimensions_mainbody_inner)); - double height_2 = box_dim_2.attr(_Unicode(y)); - double width_2 = box_dim_2.attr(_Unicode(x)); - double depth_2 = box_dim_2.attr(_Unicode(z)); + double height_2 = box_dim_2.attr(_Unicode(y)); + double width_2 = box_dim_2.attr(_Unicode(x)); + double depth_2 = box_dim_2.attr(_Unicode(z)); - Box box_inner(width_2/2., height_2/2., depth_2/2.); + Box box_inner(width_2 / 2., height_2 / 2., depth_2 / 2.); // Creates the outer box for the shape of the coils xml::Component box_dim_3 = x_det.child(_Unicode(dimensions_coils_outer)); - double height_3 = box_dim_3.attr(_Unicode(y)); - double width_3 = box_dim_3.attr(_Unicode(x)); - double depth_3 = box_dim_3.attr(_Unicode(z)); + double height_3 = box_dim_3.attr(_Unicode(y)); + double width_3 = box_dim_3.attr(_Unicode(x)); + double depth_3 = box_dim_3.attr(_Unicode(z)); - Box coils_outer(width_3/2., height_3/2., depth_3/2.); + Box coils_outer(width_3 / 2., height_3 / 2., depth_3 / 2.); // Creates the first inner box for the shape of the coils xml::Component box_dim_4 = x_det.child(_Unicode(dimensions_coils_inner_1)); - double height_4 = box_dim_4.attr(_Unicode(y)); - double width_4 = box_dim_4.attr(_Unicode(x)); - double depth_4 = box_dim_4.attr(_Unicode(z)); + double height_4 = box_dim_4.attr(_Unicode(y)); + double width_4 = box_dim_4.attr(_Unicode(x)); + double depth_4 = box_dim_4.attr(_Unicode(z)); - Box coils_inner_1(width_4/2., height_4/2., depth_4/2.); + Box coils_inner_1(width_4 / 2., height_4 / 2., depth_4 / 2.); // Creates the second inner box for the shape of the coils xml::Component box_dim_5 = x_det.child(_Unicode(dimensions_coils_inner_2)); - double height_5 = box_dim_5.attr(_Unicode(y)); - double width_5 = box_dim_5.attr(_Unicode(x)); - double depth_5 = box_dim_5.attr(_Unicode(z)); + double height_5 = box_dim_5.attr(_Unicode(y)); + double width_5 = box_dim_5.attr(_Unicode(x)); + double depth_5 = box_dim_5.attr(_Unicode(z)); - Box coils_inner_2(width_5/2., height_5/2., depth_5/2.); + Box coils_inner_2(width_5 / 2., height_5 / 2., depth_5 / 2.); // Creates the outer box for the shape of the yoke xml::Component box_dim_6 = x_det.child(_Unicode(dimensions_yoke_outer)); - double height_6 = box_dim_6.attr(_Unicode(y)); - double width_6 = box_dim_6.attr(_Unicode(x)); - double depth_6 = box_dim_6.attr(_Unicode(z)); + double height_6 = box_dim_6.attr(_Unicode(y)); + double width_6 = box_dim_6.attr(_Unicode(x)); + double depth_6 = box_dim_6.attr(_Unicode(z)); - Box yoke_outer(width_6/2., height_6/2., depth_6/2.); + Box yoke_outer(width_6 / 2., height_6 / 2., depth_6 / 2.); // Creates the first inner box for the shape of the coils xml::Component box_dim_7 = x_det.child(_Unicode(dimensions_yoke_inner)); - double height_7 = box_dim_7.attr(_Unicode(y)); - double width_7 = box_dim_7.attr(_Unicode(x)); - double depth_7 = box_dim_7.attr(_Unicode(z)); + double height_7 = box_dim_7.attr(_Unicode(y)); + double width_7 = box_dim_7.attr(_Unicode(x)); + double depth_7 = box_dim_7.attr(_Unicode(z)); - Box yoke_inner(width_7/2., height_7/2., depth_7/2.); + Box yoke_inner(width_7 / 2., height_7 / 2., depth_7 / 2.); // Creates the outer box for the shape of the legs xml::Component box_dim_8 = x_det.child(_Unicode(dimensions_leg_outer)); - double height_8 = box_dim_8.attr(_Unicode(y)); - double width_8 = box_dim_8.attr(_Unicode(x)); - double depth_8 = box_dim_8.attr(_Unicode(z)); + double height_8 = box_dim_8.attr(_Unicode(y)); + double width_8 = box_dim_8.attr(_Unicode(x)); + double depth_8 = box_dim_8.attr(_Unicode(z)); - Box leg_outer(width_8/2., height_8/2., depth_8/2.); + Box leg_outer(width_8 / 2., height_8 / 2., depth_8 / 2.); // Creates the inner box for the shape of the legs xml::Component box_dim_9 = x_det.child(_Unicode(dimensions_leg_inner)); - double height_9 = box_dim_9.attr(_Unicode(y)); - double width_9 = box_dim_9.attr(_Unicode(x)); - double depth_9 = box_dim_9.attr(_Unicode(z)); + double height_9 = box_dim_9.attr(_Unicode(y)); + double width_9 = box_dim_9.attr(_Unicode(x)); + double depth_9 = box_dim_9.attr(_Unicode(z)); - Box leg_inner(width_9/2., height_9/2., depth_9/2.); + Box leg_inner(width_9 / 2., height_9 / 2., depth_9 / 2.); // Sets box position xml::Component box_pos = x_det.child(_Unicode(position)); - double x = box_pos.attr(_Unicode(x)); - double y = box_pos.attr(_Unicode(y)); - double z = box_pos.attr(_Unicode(z)); - - + double x = box_pos.attr(_Unicode(x)); + double y = box_pos.attr(_Unicode(y)); + double z = box_pos.attr(_Unicode(z)); // Subtractes the volume of the inner box from the outer box for the main body - BooleanSolid main_body = SubtractionSolid(box_outer, box_inner); - Volume v_main_body( det_name + "_vol_main_body", main_body, m_Iron); + BooleanSolid main_body = SubtractionSolid(box_outer, box_inner); + Volume v_main_body(det_name + "_vol_main_body", main_body, m_Iron); sdet.setAttributes(det, v_main_body, x_det.regionStr(), x_det.limitsStr(), vis1); assembly.placeVolume(v_main_body, Position(x, y, z)); // Creates panels by subtracting the inner boxes of the coils from the outer box of the coilss - BooleanSolid coils_1 = SubtractionSolid(coils_outer, coils_inner_1); - BooleanSolid coils = SubtractionSolid(coils_1, coils_inner_2); - Volume v_coils( det_name + "_vol_coils", coils, m_Copper); + BooleanSolid coils_1 = SubtractionSolid(coils_outer, coils_inner_1); + BooleanSolid coils = SubtractionSolid(coils_1, coils_inner_2); + Volume v_coils(det_name + "_vol_coils", coils, m_Copper); sdet.setAttributes(det, v_coils, x_det.regionStr(), x_det.limitsStr(), vis2); assembly.placeVolume(v_coils, Position(x, y, z)); // Creates coils by subtracting the inner box of the yoke from the outer box of the yoke - BooleanSolid yoke = SubtractionSolid(yoke_outer, yoke_inner); - Volume v_yoke( det_name + "_vol_yoke", yoke, m_Iron); + BooleanSolid yoke = SubtractionSolid(yoke_outer, yoke_inner); + Volume v_yoke(det_name + "_vol_yoke", yoke, m_Iron); sdet.setAttributes(det, v_yoke, x_det.regionStr(), x_det.limitsStr(), vis1); assembly.placeVolume(v_yoke, Position(x, y, z)); // Creates the legs by subtracting the inner box of the legs from the outer box of the legs - BooleanSolid legs = SubtractionSolid(leg_outer, leg_inner); - Volume v_legs( det_name + "_vol_legs", legs, m_Iron); + BooleanSolid legs = SubtractionSolid(leg_outer, leg_inner); + Volume v_legs(det_name + "_vol_legs", legs, m_Iron); sdet.setAttributes(det, v_legs, x_det.regionStr(), x_det.limitsStr(), vis3); - assembly.placeVolume(v_legs, Position(x, y - height_9/2. - height/2., z)); - + assembly.placeVolume(v_legs, Position(x, y - height_9 / 2. - height / 2., z)); // Final placement auto pv_assembly = det.pickMotherVolume(sdet).placeVolume( diff --git a/src/LumiPhotonChamber_geo.cpp b/src/LumiPhotonChamber_geo.cpp index f4ffc50e1..5a698f52e 100644 --- a/src/LumiPhotonChamber_geo.cpp +++ b/src/LumiPhotonChamber_geo.cpp @@ -12,89 +12,89 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /*sens*/) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /*sens*/) { - xml_det_t x_det = e; - xml_comp_t x_dim = x_det.child( _Unicode(dimensions) ); - xml_comp_t x_pos = x_det.child( _Unicode(position) ); + xml_det_t x_det = e; + xml_comp_t x_dim = x_det.child(_Unicode(dimensions)); + xml_comp_t x_pos = x_det.child(_Unicode(position)); // - string det_name = x_det.nameStr(); - string mat_pipe = getAttrOrDefault( x_det, _Unicode(pipeMaterial), "Aluminum" ); - string mat_entrCap = getAttrOrDefault( x_det, _Unicode(entrCapMaterial), "Aluminum" ); - string mat_exitCap = getAttrOrDefault( x_det, _Unicode(exitCapMaterial), "Beryllium" ); - string mat_conv = getAttrOrDefault( x_det, _Unicode(convMaterial), "Aluminum" ); - string mat_fill = getAttrOrDefault( x_det, _Unicode(fillMaterial), "Vacuum" ); + string det_name = x_det.nameStr(); + string mat_pipe = getAttrOrDefault(x_det, _Unicode(pipeMaterial), "Aluminum"); + string mat_entrCap = getAttrOrDefault(x_det, _Unicode(entrCapMaterial), "Aluminum"); + string mat_exitCap = getAttrOrDefault(x_det, _Unicode(exitCapMaterial), "Beryllium"); + string mat_conv = getAttrOrDefault(x_det, _Unicode(convMaterial), "Aluminum"); + string mat_fill = getAttrOrDefault(x_det, _Unicode(fillMaterial), "Vacuum"); // - double posZ1 = x_pos.attr(_Unicode(z1)); - double posZ2 = x_pos.attr(_Unicode(z2)); - double posZconv = x_pos.attr(_Unicode(z_conv)); - double rmin = x_dim.attr(_Unicode(rmin)); - double pipe_DR = x_dim.attr(_Unicode(pipe_dr)); - double entrCap_DZ = x_dim.attr(_Unicode(entrCap_dz)); - double exitCap_DZ = x_dim.attr(_Unicode(exitCap_dz)); - double conv_DZ = x_dim.attr(_Unicode(conv_dz)); + double posZ1 = x_pos.attr(_Unicode(z1)); + double posZ2 = x_pos.attr(_Unicode(z2)); + double posZconv = x_pos.attr(_Unicode(z_conv)); + double rmin = x_dim.attr(_Unicode(rmin)); + double pipe_DR = x_dim.attr(_Unicode(pipe_dr)); + double entrCap_DZ = x_dim.attr(_Unicode(entrCap_dz)); + double exitCap_DZ = x_dim.attr(_Unicode(exitCap_dz)); + double conv_DZ = x_dim.attr(_Unicode(conv_dz)); // Create main detector element to be returned at the end - DetElement det(det_name, x_det.id()); + DetElement det(det_name, x_det.id()); // Mother volume - Volume motherVol = description.pickMotherVolume( det ); + Volume motherVol = description.pickMotherVolume(det); // chamber assembly - Assembly assembly( det_name ); - assembly.setVisAttributes( description.invisible() ); + Assembly assembly(det_name); + assembly.setVisAttributes(description.invisible()); //////////// // G4 solids // main tube - Tube tube( rmin, rmin + pipe_DR, fabs(posZ1 - posZ2)/2.0, 0, 2*TMath::Pi() ); + Tube tube(rmin, rmin + pipe_DR, fabs(posZ1 - posZ2) / 2.0, 0, 2 * TMath::Pi()); // vacuum regions inside tube - Tube vac1( 0, rmin, fabs(posZ1 - posZconv - conv_DZ/2.0)/2.0, 0, 2*TMath::Pi() ); - Tube vac2( 0, rmin, fabs(posZconv - posZ2 - conv_DZ/2.0)/2.0, 0, 2*TMath::Pi() ); + Tube vac1(0, rmin, fabs(posZ1 - posZconv - conv_DZ / 2.0) / 2.0, 0, 2 * TMath::Pi()); + Tube vac2(0, rmin, fabs(posZconv - posZ2 - conv_DZ / 2.0) / 2.0, 0, 2 * TMath::Pi()); // end cap closest to IP - Tube entrCap( 0, rmin + pipe_DR, entrCap_DZ/2.0, 0, 2*TMath::Pi() ); + Tube entrCap(0, rmin + pipe_DR, entrCap_DZ / 2.0, 0, 2 * TMath::Pi()); // end cap farthest from IP - Tube exitCap( 0, rmin + pipe_DR, exitCap_DZ/2.0, 0, 2*TMath::Pi() ); + Tube exitCap(0, rmin + pipe_DR, exitCap_DZ / 2.0, 0, 2 * TMath::Pi()); // conversion foil - Tube convFoil( 0, rmin, conv_DZ/2.0, 0, 2*TMath::Pi() ); + Tube convFoil(0, rmin, conv_DZ / 2.0, 0, 2 * TMath::Pi()); ////////// // volumes - Volume vol_vac1( det_name + "_vol_vac1", vac1, description.material( mat_fill ) ); - vol_vac1.setVisAttributes( description.invisible() ); - Volume vol_vac2( det_name + "_vol_vac2", vac2, description.material( mat_fill ) ); - vol_vac2.setVisAttributes( description.invisible() ); + Volume vol_vac1(det_name + "_vol_vac1", vac1, description.material(mat_fill)); + vol_vac1.setVisAttributes(description.invisible()); + Volume vol_vac2(det_name + "_vol_vac2", vac2, description.material(mat_fill)); + vol_vac2.setVisAttributes(description.invisible()); - Volume vol_tube( det_name + "_vol_tube", tube, description.material( mat_pipe ) ); - vol_tube.setVisAttributes( description.visAttributes(x_det.visStr()) ); + Volume vol_tube(det_name + "_vol_tube", tube, description.material(mat_pipe)); + vol_tube.setVisAttributes(description.visAttributes(x_det.visStr())); - Volume vol_entrCap( det_name + "_vol_entrCap", entrCap, description.material( mat_entrCap ) ); - vol_entrCap.setVisAttributes( description.visAttributes(x_det.visStr()) ); + Volume vol_entrCap(det_name + "_vol_entrCap", entrCap, description.material(mat_entrCap)); + vol_entrCap.setVisAttributes(description.visAttributes(x_det.visStr())); - Volume vol_exitCap( det_name + "_vol_exitCap", exitCap, description.material( mat_exitCap ) ); - vol_exitCap.setVisAttributes( description.visAttributes(x_det.visStr()) ); + Volume vol_exitCap(det_name + "_vol_exitCap", exitCap, description.material(mat_exitCap)); + vol_exitCap.setVisAttributes(description.visAttributes(x_det.visStr())); - Volume vol_conv( det_name + "_vol_conversionFoil", convFoil, description.material( mat_conv ) ); - vol_conv.setVisAttributes( description.visAttributes(x_det.visStr()) ); + Volume vol_conv(det_name + "_vol_conversionFoil", convFoil, description.material(mat_conv)); + vol_conv.setVisAttributes(description.visAttributes(x_det.visStr())); // place each volume into assembly + assembly.placeVolume(vol_tube, + Transform3D(RotationZYX(0, 0, 0), Position(0, 0, (posZ1 + posZ2) / 2.))); + assembly.placeVolume(vol_entrCap, + Transform3D(RotationZYX(0, 0, 0), Position(0, 0, posZ1 + entrCap_DZ / 2.))); + assembly.placeVolume(vol_exitCap, + Transform3D(RotationZYX(0, 0, 0), Position(0, 0, posZ2 - exitCap_DZ / 2.))); + assembly.placeVolume(vol_conv, Transform3D(RotationZYX(0, 0, 0), Position(0, 0, posZconv))); assembly.placeVolume( - vol_tube, Transform3D( RotationZYX(0, 0, 0), Position(0, 0, (posZ1 + posZ2)/2.)) ); + vol_vac1, + Transform3D(RotationZYX(0, 0, 0), Position(0, 0, (posZ1 + (posZconv + conv_DZ / 2.0)) / 2.))); assembly.placeVolume( - vol_entrCap, Transform3D( RotationZYX(0, 0, 0), Position(0, 0, posZ1 + entrCap_DZ/2.)) ); - assembly.placeVolume( - vol_exitCap, Transform3D( RotationZYX(0, 0, 0), Position(0, 0, posZ2 - exitCap_DZ/2.)) ); - assembly.placeVolume( - vol_conv, Transform3D( RotationZYX(0, 0, 0), Position(0, 0, posZconv)) ); - assembly.placeVolume( - vol_vac1, Transform3D( RotationZYX(0, 0, 0), Position(0, 0, (posZ1 + (posZconv+conv_DZ/2.0))/2.)) ); - assembly.placeVolume( - vol_vac2, Transform3D( RotationZYX(0, 0, 0), Position(0, 0, (posZ2 + (posZconv-conv_DZ/2.0))/2.)) ); + vol_vac2, + Transform3D(RotationZYX(0, 0, 0), Position(0, 0, (posZ2 + (posZconv - conv_DZ / 2.0)) / 2.))); // Place assembly into mother volume. Assembly is centered at origin - PlacedVolume phv = motherVol.placeVolume( assembly, Position(0.0, 0.0, 0.0) ); + PlacedVolume phv = motherVol.placeVolume(assembly, Position(0.0, 0.0, 0.0)); det.setPlacement(phv); diff --git a/src/LumiSpecHomoCAL_geo.cpp b/src/LumiSpecHomoCAL_geo.cpp index cfb9fdc6f..f33abdc4a 100644 --- a/src/LumiSpecHomoCAL_geo.cpp +++ b/src/LumiSpecHomoCAL_geo.cpp @@ -14,66 +14,67 @@ using namespace std; using namespace dd4hep; // Definition of function to build the modules -static tuple build_specHomoCAL_module(const Detector& description, const xml::Component& mod_x, SensitiveDetector& sens); +static tuple build_specHomoCAL_module(const Detector& description, + const xml::Component& mod_x, + SensitiveDetector& sens); // Driver Function -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { sens.setType("calorimeter"); - xml_det_t x_det = e; - xml_comp_t x_mod = x_det.child( _Unicode(module) ); - string det_name = x_det.nameStr(); - int det_ID = x_det.id(); + xml_det_t x_det = e; + xml_comp_t x_mod = x_det.child(_Unicode(module)); + string det_name = x_det.nameStr(); + int det_ID = x_det.id(); // Create main detector element to be returned at the end - DetElement det( det_name, det_ID ); + DetElement det(det_name, det_ID); // Mother volume - Volume motherVol = description.pickMotherVolume( det ); + Volume motherVol = description.pickMotherVolume(det); // Detector assembly - Assembly assembly( det_name ); - assembly.setVisAttributes( description.invisible() ); + Assembly assembly(det_name); + assembly.setVisAttributes(description.invisible()); // Create Modules auto [modVol, modSize] = build_specHomoCAL_module(description, x_mod, sens); - double detSizeXY = getAttrOrDefault( x_det, _Unicode(sizeXY), 20 ); - int nxy = int( detSizeXY / modSize.x() ); - double xypos0 = -nxy*modSize.x()/2.0 + modSize.x()/2.0; + double detSizeXY = getAttrOrDefault(x_det, _Unicode(sizeXY), 20); + int nxy = int(detSizeXY / modSize.x()); + double xypos0 = -nxy * modSize.x() / 2.0 + modSize.x() / 2.0; // Build detector components // loop over sectors - for( xml_coll_t si(x_det, _Unicode(sector)); si; si++) { // sectors (top,bottom) + for (xml_coll_t si(x_det, _Unicode(sector)); si; si++) { // sectors (top,bottom) - xml_comp_t x_sector( si ); + xml_comp_t x_sector(si); int sector_id = x_sector.id(); - int mod_id = 0; + int mod_id = 0; xml_comp_t x_pos = x_sector.position(); xml_comp_t x_rot = x_sector.rotation(); - for(int ix=0; ix< nxy; ix++){ - for(int iy=0; iy< nxy; iy++){ + for (int ix = 0; ix < nxy; ix++) { + for (int iy = 0; iy < nxy; iy++) { - double mod_pos_x = x_pos.x() + xypos0 + ix*modSize.x(); - double mod_pos_y = x_pos.y() + xypos0 + iy*modSize.y(); - double mod_pos_z = x_pos.z() + 0.0*cm; + double mod_pos_x = x_pos.x() + xypos0 + ix * modSize.x(); + double mod_pos_y = x_pos.y() + xypos0 + iy * modSize.y(); + double mod_pos_z = x_pos.z() + 0.0 * cm; - PlacedVolume modPV = assembly.placeVolume( - modVol, Transform3D( RotationZYX( x_rot.x(), x_rot.y(), x_rot.z()), Position( mod_pos_x, mod_pos_y, mod_pos_z ) ) ); + PlacedVolume modPV = + assembly.placeVolume(modVol, Transform3D(RotationZYX(x_rot.x(), x_rot.y(), x_rot.z()), + Position(mod_pos_x, mod_pos_y, mod_pos_z))); - modPV.addPhysVolID( "sector", sector_id ).addPhysVolID( "module", mod_id ); + modPV.addPhysVolID("sector", sector_id).addPhysVolID("module", mod_id); mod_id++; } } - } // sectors // Place assembly into mother volume. Assembly is centered at origin - PlacedVolume detPV = motherVol.placeVolume( assembly, Position(0.0, 0.0, 0.0) ); + PlacedVolume detPV = motherVol.placeVolume(assembly, Position(0.0, 0.0, 0.0)); detPV.addPhysVolID("system", det_ID); // Connect to system ID @@ -84,15 +85,17 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s //-------------------------------------------------------------------- //Function for building the module -static tuple build_specHomoCAL_module( const Detector& description, const xml::Component& mod_x, SensitiveDetector& sens){ +static tuple build_specHomoCAL_module(const Detector& description, + const xml::Component& mod_x, + SensitiveDetector& sens) { - double sx = mod_x.attr(_Unicode(sizex)); - double sy = mod_x.attr(_Unicode(sizey)); - double sz = mod_x.attr(_Unicode(sizez)); + double sx = mod_x.attr(_Unicode(sizex)); + double sy = mod_x.attr(_Unicode(sizey)); + double sz = mod_x.attr(_Unicode(sizez)); double frame_size = mod_x.attr(_Unicode(frameSize)); - Box modShape( (sx/2.0 -frame_size) , (sy/2.0 -frame_size) , sz/2.0 ); - auto modMat = description.material(mod_x.attr(_Unicode(material))); + Box modShape((sx / 2.0 - frame_size), (sy / 2.0 - frame_size), sz / 2.0); + auto modMat = description.material(mod_x.attr(_Unicode(material))); Volume modVol("module_vol", modShape, modMat); if (mod_x.hasAttr(_Unicode(vis))) { @@ -100,7 +103,7 @@ static tuple build_specHomoCAL_module( const Detector& descrip } modVol.setSensitiveDetector(sens); - return make_tuple(modVol, Position{sx, sy, sz} ); + return make_tuple(modVol, Position{sx, sy, sz}); } DECLARE_DETELEMENT(LumiSpecHomoCAL, create_detector) //(det_type, driver func) diff --git a/src/LumiSpecTracker_geo.cpp b/src/LumiSpecTracker_geo.cpp index 302469f0d..a8a7277d0 100644 --- a/src/LumiSpecTracker_geo.cpp +++ b/src/LumiSpecTracker_geo.cpp @@ -8,69 +8,68 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { sens.setType("tracker"); - xml_det_t x_det = e; - string det_name = x_det.nameStr(); - int det_ID = x_det.id(); - string vis_Si = getAttrOrDefault(x_det, _Unicode(vis), "TrackerVis"); - string vis_Cu = getAttrOrDefault(x_det, _Unicode(visCu), "TrackerServiceVis"); - string Si_name = getAttrOrDefault(x_det, _Unicode(materialSi), "SiliconOxide"); - string Cu_name = getAttrOrDefault(x_det, _Unicode(materialCu), "Copper"); - double Si_DZ = getAttrOrDefault(x_det, _Unicode(thicknessSi), 0.03/2.0); - double Cu_DZ = getAttrOrDefault(x_det, _Unicode(thicknessCu), 0.014/2.0); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + int det_ID = x_det.id(); + string vis_Si = getAttrOrDefault(x_det, _Unicode(vis), "TrackerVis"); + string vis_Cu = getAttrOrDefault(x_det, _Unicode(visCu), "TrackerServiceVis"); + string Si_name = getAttrOrDefault(x_det, _Unicode(materialSi), "SiliconOxide"); + string Cu_name = getAttrOrDefault(x_det, _Unicode(materialCu), "Copper"); + double Si_DZ = getAttrOrDefault(x_det, _Unicode(thicknessSi), 0.03 / 2.0); + double Cu_DZ = getAttrOrDefault(x_det, _Unicode(thicknessCu), 0.014 / 2.0); - Material m_Si = description.material( Si_name ); - Material m_Cu = description.material( Cu_name ); + Material m_Si = description.material(Si_name); + Material m_Cu = description.material(Cu_name); // Create main detector element to be returned at the end - DetElement det( det_name, det_ID ); + DetElement det(det_name, det_ID); // Mother volume - Volume motherVol = description.pickMotherVolume( det ); + Volume motherVol = description.pickMotherVolume(det); // Detector assembly - Assembly assembly( det_name ); - assembly.setVisAttributes( description.invisible() ); + Assembly assembly(det_name); + assembly.setVisAttributes(description.invisible()); // Build detector components // loop over modules - for( xml_coll_t mi(x_det, _Unicode(module)); mi; mi++) { // modules + for (xml_coll_t mi(x_det, _Unicode(module)); mi; mi++) { // modules - xml_comp_t x_mod( mi ); + xml_comp_t x_mod(mi); int module_id = x_mod.id(); // loop over sectors within each module - for( xml_coll_t si( mi, _Unicode(sector)); si; si++) { // sectors + for (xml_coll_t si(mi, _Unicode(sector)); si; si++) { // sectors - xml_comp_t x_sector( si ); + xml_comp_t x_sector(si); int sector_id = x_sector.id(); - string name = getAttrOrDefault(x_sector, _Unicode(name), ""); + string name = getAttrOrDefault(x_sector, _Unicode(name), ""); - double posX = x_sector.position().x(); - double posY = x_sector.position().y(); - double posZ = x_sector.position().z(); + double posX = x_sector.position().x(); + double posY = x_sector.position().y(); + double posZ = x_sector.position().z(); double sizeX = x_sector.dimensions().x(); double sizeY = x_sector.dimensions().y(); // Silicon sensor - Box box_Si( sizeX, sizeY, Si_DZ ); - Volume vol_Si( det_name + "_" + name, box_Si, m_Si ); - vol_Si.setVisAttributes( description.visAttributes( vis_Si ) ); - vol_Si.setSensitiveDetector( sens ); + Box box_Si(sizeX, sizeY, Si_DZ); + Volume vol_Si(det_name + "_" + name, box_Si, m_Si); + vol_Si.setVisAttributes(description.visAttributes(vis_Si)); + vol_Si.setSensitiveDetector(sens); // Cu layer to approximate ASICs/cooling - Box box_Cu( sizeX, sizeY, Cu_DZ ); - Volume vol_Cu( det_name + "_" + name + "_Cu", box_Cu, m_Cu ); - vol_Cu.setVisAttributes( description.visAttributes( vis_Cu ) ); + Box box_Cu(sizeX, sizeY, Cu_DZ); + Volume vol_Cu(det_name + "_" + name + "_Cu", box_Cu, m_Cu); + vol_Cu.setVisAttributes(description.visAttributes(vis_Cu)); // place into assembly PlacedVolume pv = assembly.placeVolume( - vol_Si, Transform3D( RotationZYX(0.0,0.0,0.0), Position( posX, posY, posZ ) ) ); - assembly.placeVolume( - vol_Cu, Transform3D( RotationZYX(0.0,0.0,0.0), Position( posX, posY, posZ - (Si_DZ+Cu_DZ) ) ) ); + vol_Si, Transform3D(RotationZYX(0.0, 0.0, 0.0), Position(posX, posY, posZ))); + assembly.placeVolume(vol_Cu, Transform3D(RotationZYX(0.0, 0.0, 0.0), + Position(posX, posY, posZ - (Si_DZ + Cu_DZ)))); // Connect sector and module IDs pv.addPhysVolID("sector", sector_id).addPhysVolID("module", module_id); @@ -79,12 +78,12 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s } // modules // Place assembly into mother volume. Assembly is centered at origin - PlacedVolume detPV = motherVol.placeVolume( assembly, Position(0.0, 0.0, 0.0) ); + PlacedVolume detPV = motherVol.placeVolume(assembly, Position(0.0, 0.0, 0.0)); // Connect system ID - detPV.addPhysVolID( "system", det_ID ); + detPV.addPhysVolID("system", det_ID); - det.setPlacement( detPV ); + det.setPlacement(detPV); return det; } diff --git a/src/LumiWindow_geo.cpp b/src/LumiWindow_geo.cpp index fa3f6dd1b..19f78f3b1 100644 --- a/src/LumiWindow_geo.cpp +++ b/src/LumiWindow_geo.cpp @@ -12,36 +12,35 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /*sens*/) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /*sens*/) { - xml_det_t x_det = e; - xml_comp_t x_dim = x_det.dimensions(); - xml_comp_t x_pos = x_det.position(); - xml_comp_t x_rot = x_det.rotation(); + xml_det_t x_det = e; + xml_comp_t x_dim = x_det.dimensions(); + xml_comp_t x_pos = x_det.position(); + xml_comp_t x_rot = x_det.rotation(); // - string det_name = x_det.nameStr(); - string mat_name = dd4hep::getAttrOrDefault( x_det, _U(material), "Aluminum" ); + string det_name = x_det.nameStr(); + string mat_name = dd4hep::getAttrOrDefault(x_det, _U(material), "Aluminum"); // - double sizeX = x_dim.x(); - double sizeY = x_dim.y(); - double sizeZ = x_dim.z(); - double posX = x_pos.x(); - double posY = x_pos.y(); - double posZ = x_pos.z(); - double rotX = x_rot.x(); - double rotY = x_rot.y(); - double rotZ = x_rot.z(); - - Box box( sizeX, sizeY, sizeZ ); - Volume vol( det_name + "_vol_ExitWindow", box, description.material( mat_name ) ); - vol.setVisAttributes( description.visAttributes(x_det.visStr()) ); - - Transform3D pos( RotationZYX(rotX, rotY, rotZ), Position(posX, posY, posZ) ); + double sizeX = x_dim.x(); + double sizeY = x_dim.y(); + double sizeZ = x_dim.z(); + double posX = x_pos.x(); + double posY = x_pos.y(); + double posZ = x_pos.z(); + double rotX = x_rot.x(); + double rotY = x_rot.y(); + double rotZ = x_rot.z(); + + Box box(sizeX, sizeY, sizeZ); + Volume vol(det_name + "_vol_ExitWindow", box, description.material(mat_name)); + vol.setVisAttributes(description.visAttributes(x_det.visStr())); + + Transform3D pos(RotationZYX(rotX, rotY, rotZ), Position(posX, posY, posZ)); DetElement det(det_name, x_det.id()); - Volume motherVol = description.pickMotherVolume( det ); - PlacedVolume phv = motherVol.placeVolume( vol, pos ); + Volume motherVol = description.pickMotherVolume(det); + PlacedVolume phv = motherVol.placeVolume(vol, pos); det.setPlacement(phv); diff --git a/src/MRich_geo.cpp b/src/MRich_geo.cpp index 566e6c1ac..36fd117fb 100644 --- a/src/MRich_geo.cpp +++ b/src/MRich_geo.cpp @@ -23,13 +23,12 @@ using namespace dd4hep::rec; using Placements = vector; -static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDetector sens) -{ - xml_det_t x_det = e; - Material air = description.material("AirOptical"); - string det_name = x_det.nameStr(); +static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDetector sens) { + xml_det_t x_det = e; + Material air = description.material("AirOptical"); + string det_name = x_det.nameStr(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name); + Assembly assembly(det_name); sens.setType("tracker"); OpticalSurfaceManager surfMgr = description.surfaceManager(); @@ -38,59 +37,59 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet PlacedVolume pv; - map modules; - map sensitives; - map module_assemblies; + map modules; + map sensitives; + map module_assemblies; std::map module_assembly_delements; int n_sensor = 1; // dimensions - xml::Component dims = x_det.dimensions(); - auto rmin = dims.rmin(); - auto rmax = dims.rmax(); - auto length = dims.length(); - auto zmin = dims.zmin(); - auto zpos = zmin + length / 2; + xml::Component dims = x_det.dimensions(); + auto rmin = dims.rmin(); + auto rmax = dims.rmax(); + auto length = dims.length(); + auto zmin = dims.zmin(); + auto zpos = zmin + length / 2; // envelope - Tube envShape(rmin, rmax, length / 2., 0., 2 * M_PI); + Tube envShape(rmin, rmax, length / 2., 0., 2 * M_PI); Volume envVol("MRICH_Envelope", envShape, air); envVol.setVisAttributes(description.visAttributes(x_det.visStr())); if (x_det.hasChild(_Unicode(envelope))) { - xml_comp_t x_envelope = x_det.child(_Unicode(envelope)); - double thickness = x_envelope.thickness(); - Material material = description.material(x_envelope.materialStr()); - Tube envInsideShape(rmin + thickness, rmax - thickness, length / 2. - thickness); + xml_comp_t x_envelope = x_det.child(_Unicode(envelope)); + double thickness = x_envelope.thickness(); + Material material = description.material(x_envelope.materialStr()); + Tube envInsideShape(rmin + thickness, rmax - thickness, length / 2. - thickness); SubtractionSolid envShellShape(envShape, envInsideShape); - Volume envShell("MRICH_Envelope_Inside", envShellShape, material); + Volume envShell("MRICH_Envelope_Inside", envShellShape, material); envVol.placeVolume(envShell); } // expect only one module (for now) - xml_comp_t x_mod = x_det.child(_U(module)); - string mod_name = x_mod.nameStr(); - double mod_width = getAttrOrDefault(x_mod, _U(width), 130.0 * mm); - double mod_height = getAttrOrDefault(x_mod, _U(height), 130.0 * mm); - double mod_length = getAttrOrDefault(x_mod, _U(length), 130.0 * mm); + xml_comp_t x_mod = x_det.child(_U(module)); + string mod_name = x_mod.nameStr(); + double mod_width = getAttrOrDefault(x_mod, _U(width), 130.0 * mm); + double mod_height = getAttrOrDefault(x_mod, _U(height), 130.0 * mm); + double mod_length = getAttrOrDefault(x_mod, _U(length), 130.0 * mm); // module - Box m_solid(mod_width / 2.0, mod_height / 2.0, mod_length / 2.0); + Box m_solid(mod_width / 2.0, mod_height / 2.0, mod_length / 2.0); Volume m_volume(mod_name, m_solid, air); m_volume.setVisAttributes(description.visAttributes(x_mod.visStr())); DetElement mod_de(mod_name + std::string("_mod_") + std::to_string(1), 1); - double z_placement = -mod_length / 2.0; + double z_placement = -mod_length / 2.0; // todo module frame if (x_mod.hasChild(_Unicode(frame))) { - xml_comp_t x_frame = x_mod.child(_Unicode(frame)); - double frame_thickness = getAttrOrDefault(x_frame, _U(thickness), 2.0 * mm); - Box frame_inside(mod_width / 2.0 - frame_thickness, mod_height / 2.0 - frame_thickness, - mod_length / 2.0 - frame_thickness); + xml_comp_t x_frame = x_mod.child(_Unicode(frame)); + double frame_thickness = getAttrOrDefault(x_frame, _U(thickness), 2.0 * mm); + Box frame_inside(mod_width / 2.0 - frame_thickness, mod_height / 2.0 - frame_thickness, + mod_length / 2.0 - frame_thickness); SubtractionSolid frame_solid(m_solid, frame_inside); - Material frame_mat = description.material(x_frame.materialStr()); - Volume frame_vol(mod_name + "_frame", frame_solid, frame_mat); - auto frame_vis = getAttrOrDefault(x_frame, _U(vis), std::string("GrayVis")); + Material frame_mat = description.material(x_frame.materialStr()); + Volume frame_vol(mod_name + "_frame", frame_solid, frame_mat); + auto frame_vis = getAttrOrDefault(x_frame, _U(vis), std::string("GrayVis")); frame_vol.setVisAttributes(description.visAttributes(frame_vis)); // update position z_placement += frame_thickness / 2.0; @@ -102,27 +101,29 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet // aerogel box if (x_mod.hasChild(_Unicode(aerogel))) { - xml_comp_t x_aerogel = x_mod.child(_Unicode(aerogel)); - double aerogel_width = getAttrOrDefault(x_aerogel, _U(width), 130.0 * mm); - double aerogel_length = getAttrOrDefault(x_aerogel, _U(length), 130.0 * mm); - Material aerogel_mat = description.material(x_aerogel.materialStr()); - auto aerogel_vis = getAttrOrDefault(x_aerogel, _U(vis), std::string("InvisibleWithDaughters")); + xml_comp_t x_aerogel = x_mod.child(_Unicode(aerogel)); + double aerogel_width = getAttrOrDefault(x_aerogel, _U(width), 130.0 * mm); + double aerogel_length = getAttrOrDefault(x_aerogel, _U(length), 130.0 * mm); + Material aerogel_mat = description.material(x_aerogel.materialStr()); + auto aerogel_vis = + getAttrOrDefault(x_aerogel, _U(vis), std::string("InvisibleWithDaughters")); xml_comp_t x_aerogel_frame = x_aerogel.child(_Unicode(frame)); - double foam_thickness = getAttrOrDefault(x_aerogel_frame, _U(thickness), 2.0 * mm); - Material foam_mat = description.material(x_aerogel_frame.materialStr()); - auto foam_vis = getAttrOrDefault(x_aerogel_frame, _U(vis), std::string("RedVis")); + double foam_thickness = getAttrOrDefault(x_aerogel_frame, _U(thickness), 2.0 * mm); + Material foam_mat = description.material(x_aerogel_frame.materialStr()); + auto foam_vis = getAttrOrDefault(x_aerogel_frame, _U(vis), std::string("RedVis")); // foam frame - Box foam_box(aerogel_width / 2.0 + foam_thickness, aerogel_width / 2.0 + foam_thickness, - (aerogel_length + foam_thickness) / 2.0); - Box foam_sub_box(aerogel_width / 2.0, aerogel_width / 2.0, (aerogel_length + foam_thickness) / 2.0); + Box foam_box(aerogel_width / 2.0 + foam_thickness, aerogel_width / 2.0 + foam_thickness, + (aerogel_length + foam_thickness) / 2.0); + Box foam_sub_box(aerogel_width / 2.0, aerogel_width / 2.0, + (aerogel_length + foam_thickness) / 2.0); SubtractionSolid foam_frame_solid(foam_box, foam_sub_box, Position(0, 0, foam_thickness)); - Volume foam_vol(mod_name + "_aerogel_frame", foam_frame_solid, foam_mat); + Volume foam_vol(mod_name + "_aerogel_frame", foam_frame_solid, foam_mat); foam_vol.setVisAttributes(description.visAttributes(foam_vis)); // aerogel - Box aerogel_box(aerogel_width / 2.0, aerogel_width / 2.0, (aerogel_length) / 2.0); + Box aerogel_box(aerogel_width / 2.0, aerogel_width / 2.0, (aerogel_length) / 2.0); Volume aerogel_vol(mod_name + "_aerogel", aerogel_box, aerogel_mat); aerogel_vol.setVisAttributes(description.visAttributes(aerogel_vis)); @@ -139,9 +140,10 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet z_placement += aerogel_length / 2.0; // optical surfaces - auto aerogel_surf = surfMgr.opticalSurface( - dd4hep::getAttrOrDefault(x_aerogel, _Unicode(surface), "MRICH_AerogelOpticalSurface")); - SkinSurface skin_surf(description, aerogel_de, Form("MRICH_aerogel_skin_surface_%d", 1), aerogel_surf, aerogel_vol); + auto aerogel_surf = surfMgr.opticalSurface(dd4hep::getAttrOrDefault( + x_aerogel, _Unicode(surface), "MRICH_AerogelOpticalSurface")); + SkinSurface skin_surf(description, aerogel_de, Form("MRICH_aerogel_skin_surface_%d", 1), + aerogel_surf, aerogel_vol); skin_surf.isValid(); } @@ -152,12 +154,13 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet // - The lens has a constant groove pitch (delta r) as opposed to fixing the groove height. // - The lens area outside of the effective diamtere is flat. // - The grooves are not curved, rather they are polycone shaped, ie a flat approximating the curvature. - auto lens_vis = getAttrOrDefault(x_lens, _U(vis), std::string("AnlBlue")); - double groove_pitch = getAttrOrDefault(x_lens, _Unicode(pitch), 0.2 * mm); // 0.5 * mm); - double lens_f = getAttrOrDefault(x_lens, _Unicode(focal_length), 6.0 * 2.54 * cm); - double eff_diameter = getAttrOrDefault(x_lens, _Unicode(effective_diameter), 152.4 * mm); - double lens_width = getAttrOrDefault(x_lens, _Unicode(width), 6.7 * 2.54 * cm); - double center_thickness = getAttrOrDefault(x_lens, _U(thickness), 0.068 * 2.54 * cm); // 2.0 * mm); + auto lens_vis = getAttrOrDefault(x_lens, _U(vis), std::string("AnlBlue")); + double groove_pitch = getAttrOrDefault(x_lens, _Unicode(pitch), 0.2 * mm); // 0.5 * mm); + double lens_f = getAttrOrDefault(x_lens, _Unicode(focal_length), 6.0 * 2.54 * cm); + double eff_diameter = getAttrOrDefault(x_lens, _Unicode(effective_diameter), 152.4 * mm); + double lens_width = getAttrOrDefault(x_lens, _Unicode(width), 6.7 * 2.54 * cm); + double center_thickness = + getAttrOrDefault(x_lens, _U(thickness), 0.068 * 2.54 * cm); // 2.0 * mm); double n_acrylic = 1.49; double lens_curvature = 1.0 / (lens_f * (n_acrylic - 1.0)); // confirmed @@ -167,27 +170,29 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet double groove_last_rmin = (N_grooves - 1) * groove_pitch; double groove_last_rmax = N_grooves * groove_pitch; - auto groove_sagitta = [&](double r) { return lens_curvature * std::pow(r, 2) / (1.0 + 1.0); }; - double lens_thickness = groove_sagitta(groove_last_rmax) - groove_sagitta(groove_last_rmin) + center_thickness; + auto groove_sagitta = [&](double r) { return lens_curvature * std::pow(r, 2) / (1.0 + 1.0); }; + double lens_thickness = + groove_sagitta(groove_last_rmax) - groove_sagitta(groove_last_rmin) + center_thickness; - Material lens_mat = description.material(x_lens.materialStr()); - Box lens_box(lens_width / 2.0, lens_width / 2.0, (center_thickness) / 2.0); + Material lens_mat = description.material(x_lens.materialStr()); + Box lens_box(lens_width / 2.0, lens_width / 2.0, (center_thickness) / 2.0); SubtractionSolid flat_lens(lens_box, Tube(0.0, full_ring_rmax, 2 * center_thickness)); Assembly lens_vol(mod_name + "_lens"); - Volume flatpart_lens_vol("flatpart_lens", flat_lens, lens_mat); + Volume flatpart_lens_vol("flatpart_lens", flat_lens, lens_mat); lens_vol.placeVolume(flatpart_lens_vol); - int i_groove = 0; + int i_groove = 0; double groove_rmax = groove_pitch; double groove_rmin = 0; while (groove_rmax <= full_ring_rmax) { - double dZ = groove_sagitta(groove_rmax) - groove_sagitta(groove_rmin); - Polycone groove_solid(0, 2.0 * M_PI, {groove_rmin, groove_rmin, groove_rmin}, - {groove_rmax, groove_rmax, groove_rmin}, - {-lens_thickness / 2.0, lens_thickness / 2.0 - dZ, lens_thickness / 2.0}); - Volume lens_groove_vol("lens_groove_" + std::to_string(i_groove), groove_solid, lens_mat); + double dZ = groove_sagitta(groove_rmax) - groove_sagitta(groove_rmin); + Polycone groove_solid( + 0, 2.0 * M_PI, {groove_rmin, groove_rmin, groove_rmin}, + {groove_rmax, groove_rmax, groove_rmin}, + {-lens_thickness / 2.0, lens_thickness / 2.0 - dZ, lens_thickness / 2.0}); + Volume lens_groove_vol("lens_groove_" + std::to_string(i_groove), groove_solid, lens_mat); lens_vol.placeVolume(lens_groove_vol); i_groove++; @@ -207,9 +212,10 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet z_placement += lens_thickness / 2.0; // optical surfaces - auto lens_surf = surfMgr.opticalSurface( - dd4hep::getAttrOrDefault(x_lens, _Unicode(surface), "MRICH_LensOpticalSurface")); - SkinSurface skin_surf(description, lens_de, Form("MRichFresnelLens_skin_surface_%d", 1), lens_surf, lens_vol); + auto lens_surf = surfMgr.opticalSurface(dd4hep::getAttrOrDefault( + x_lens, _Unicode(surface), "MRICH_LensOpticalSurface")); + SkinSurface skin_surf(description, lens_de, Form("MRichFresnelLens_skin_surface_%d", 1), + lens_surf, lens_vol); skin_surf.isValid(); } @@ -221,20 +227,20 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet // mirror if (x_mod.hasChild(_Unicode(mirror))) { - xml_comp_t x_mirror = x_mod.child(_Unicode(mirror)); - auto mirror_vis = getAttrOrDefault(x_mirror, _U(vis), std::string("AnlGray")); - double mirror_x1 = getAttrOrDefault(x_mirror, _U(x1), 100.0 * mm); - double mirror_x2 = getAttrOrDefault(x_mirror, _U(x2), 80.0 * mm); - double mirror_length = getAttrOrDefault(x_mirror, _U(length), 130.0 * mm); - double mirror_thickness = getAttrOrDefault(x_mirror, _U(thickness), 2.0 * mm); - double outer_x1 = (mirror_x1 + mirror_thickness) / 2.0; - double outer_x2 = (mirror_x2 + mirror_thickness) / 2.0; - Trd2 outer_mirror_trd(outer_x1, outer_x2, outer_x1, outer_x2, mirror_length / 2.0); - Trd2 inner_mirror_trd(mirror_x1 / 2.0, mirror_x2 / 2.0, mirror_x1 / 2.0, mirror_x2 / 2.0, - mirror_length / 2.0 + 0.1 * mm); + xml_comp_t x_mirror = x_mod.child(_Unicode(mirror)); + auto mirror_vis = getAttrOrDefault(x_mirror, _U(vis), std::string("AnlGray")); + double mirror_x1 = getAttrOrDefault(x_mirror, _U(x1), 100.0 * mm); + double mirror_x2 = getAttrOrDefault(x_mirror, _U(x2), 80.0 * mm); + double mirror_length = getAttrOrDefault(x_mirror, _U(length), 130.0 * mm); + double mirror_thickness = getAttrOrDefault(x_mirror, _U(thickness), 2.0 * mm); + double outer_x1 = (mirror_x1 + mirror_thickness) / 2.0; + double outer_x2 = (mirror_x2 + mirror_thickness) / 2.0; + Trd2 outer_mirror_trd(outer_x1, outer_x2, outer_x1, outer_x2, mirror_length / 2.0); + Trd2 inner_mirror_trd(mirror_x1 / 2.0, mirror_x2 / 2.0, mirror_x1 / 2.0, mirror_x2 / 2.0, + mirror_length / 2.0 + 0.1 * mm); SubtractionSolid mirror_solid(outer_mirror_trd, inner_mirror_trd); - Material mirror_mat = description.material(x_mirror.materialStr()); - Volume mirror_vol(mod_name + "_mirror", mirror_solid, mirror_mat); + Material mirror_mat = description.material(x_mirror.materialStr()); + Volume mirror_vol(mod_name + "_mirror", mirror_solid, mirror_mat); // update position z_placement += mirror_length / 2.0; @@ -246,21 +252,22 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet z_placement += mirror_length / 2.0; // optical surfaces - auto mirror_surf = surfMgr.opticalSurface( - dd4hep::getAttrOrDefault(x_mirror, _Unicode(surface), "MRICH_MirrorOpticalSurface")); - SkinSurface skin_surf(description, mirror_de, Form("MRICH_mirror_skin_surface_%d", 1), mirror_surf, mirror_vol); + auto mirror_surf = surfMgr.opticalSurface(dd4hep::getAttrOrDefault( + x_mirror, _Unicode(surface), "MRICH_MirrorOpticalSurface")); + SkinSurface skin_surf(description, mirror_de, Form("MRICH_mirror_skin_surface_%d", 1), + mirror_surf, mirror_vol); skin_surf.isValid(); } // photon detector if (x_mod.hasChild(_Unicode(photodet))) { - xml_comp_t x_photodet = x_mod.child(_Unicode(photodet)); - auto photodet_vis = getAttrOrDefault(x_photodet, _U(vis), std::string("AnlRed")); - double photodet_width = getAttrOrDefault(x_photodet, _U(width), 130.0 * mm); - double photodet_thickness = getAttrOrDefault(x_photodet, _U(thickness), 2.0 * mm); - Material photodet_mat = description.material(x_photodet.materialStr()); - Box window_box(photodet_width / 2.0, photodet_width / 2.0, photodet_thickness / 2.0); - Volume window_vol(mod_name + "_window", window_box, photodet_mat); + xml_comp_t x_photodet = x_mod.child(_Unicode(photodet)); + auto photodet_vis = getAttrOrDefault(x_photodet, _U(vis), std::string("AnlRed")); + double photodet_width = getAttrOrDefault(x_photodet, _U(width), 130.0 * mm); + double photodet_thickness = getAttrOrDefault(x_photodet, _U(thickness), 2.0 * mm); + Material photodet_mat = description.material(x_photodet.materialStr()); + Box window_box(photodet_width / 2.0, photodet_width / 2.0, photodet_thickness / 2.0); + Volume window_vol(mod_name + "_window", window_box, photodet_mat); // update position z_placement += photodet_thickness / 2.0; @@ -288,17 +295,18 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet // layers int i_layer = 1; for (xml_coll_t li(x_photodet, _Unicode(layer)); li; ++li) { - xml_comp_t x_layer = li; - Material layer_mat = description.material(x_layer.materialStr()); - double layer_thickness = x_layer.thickness(); - Box layer_box(photodet_width / 2.0, photodet_width / 2.0, layer_thickness / 2.0); - Volume layer_vol(mod_name + "_layer_" + std::to_string(i_layer), layer_box, layer_mat); + xml_comp_t x_layer = li; + Material layer_mat = description.material(x_layer.materialStr()); + double layer_thickness = x_layer.thickness(); + Box layer_box(photodet_width / 2.0, photodet_width / 2.0, layer_thickness / 2.0); + Volume layer_vol(mod_name + "_layer_" + std::to_string(i_layer), layer_box, layer_mat); // update position z_placement += layer_thickness / 2.0; // place volume pv = m_volume.placeVolume(layer_vol, Position(0, 0, z_placement)); - DetElement layer_de(mod_de, mod_name + std::string("_layer_de_") + std::to_string(i_layer), 1); + DetElement layer_de(mod_de, mod_name + std::string("_layer_de_") + std::to_string(i_layer), + 1); layer_de.setPlacement(pv); // update position z_placement += layer_thickness / 2.0; @@ -338,7 +346,8 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet for (xml_coll_t x_position_i(x_positions, _U(position)); x_position_i; ++x_position_i) { xml_comp_t x_position = x_position_i; positions.push_back(std::make_tuple(x_positions.scale() * x_position.x() * mm, - x_positions.scale() * x_position.y() * mm, -x_positions.z0())); + x_positions.scale() * x_position.y() * mm, + -x_positions.z0())); } } // if no positions, then autoplacement @@ -387,7 +396,8 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet pv = envVol.placeVolume(mod_v, tr); pv.addPhysVolID("module", i_mod); - auto mod_det_element = module_assembly_delements[mod_name].clone(mod_name + "__" + std::to_string(i_mod)); + auto mod_det_element = + module_assembly_delements[mod_name].clone(mod_name + "__" + std::to_string(i_mod)); mod_det_element.setPlacement(pv); sdet.add(mod_det_element); @@ -397,11 +407,11 @@ static Ref_t createDetector(Detector& description, xml::Handle_t e, SensitiveDet // additional layers if (x_det.hasChild(_Unicode(layer))) { - xml_comp_t x_layer = x_det.child(_Unicode(layer)); - double layer_thickness = x_layer.thickness(); - Material layer_mat = description.material(x_layer.materialStr()); - Tube frameShape(rmin, rmax, layer_thickness / 2., 0., 2 * M_PI); - Volume frameVol("MRICH_Frame", frameShape, layer_mat); + xml_comp_t x_layer = x_det.child(_Unicode(layer)); + double layer_thickness = x_layer.thickness(); + Material layer_mat = description.material(x_layer.materialStr()); + Tube frameShape(rmin, rmax, layer_thickness / 2., 0., 2 * M_PI); + Volume frameVol("MRICH_Frame", frameShape, layer_mat); pv = envVol.placeVolume(frameVol, Position(0, 0, (length - layer_thickness) / 2.0)); } diff --git a/src/OffMomentumTracker_geo.cpp b/src/OffMomentumTracker_geo.cpp index 3a2b2e1f5..6960eb7e4 100644 --- a/src/OffMomentumTracker_geo.cpp +++ b/src/OffMomentumTracker_geo.cpp @@ -17,60 +17,62 @@ using namespace dd4hep::detail; * * @author Whitney Armstrong */ -static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, SensitiveDetector sens) { typedef vector Placements; - xml_det_t x_det = e; - Material vacuum = description.vacuum(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - DetElement sdet(det_name, det_id); - Assembly assembly(det_name); - xml::Component pos = x_det.position(); - xml::Component rot = x_det.rotation(); + xml_det_t x_det = e; + Material vacuum = description.vacuum(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + DetElement sdet(det_name, det_id); + Assembly assembly(det_name); + xml::Component pos = x_det.position(); + xml::Component rot = x_det.rotation(); // Material air = description.material("Air"); // Volume assembly (det_name,Box(10000,10000,10000),vacuum); - Volume motherVol = description.pickMotherVolume(sdet); - int m_id = 0, c_id = 0, n_sensor = 0; - map modules; + Volume motherVol = description.pickMotherVolume(sdet); + int m_id = 0, c_id = 0, n_sensor = 0; + map modules; map sensitives; - PlacedVolume pv; + PlacedVolume pv; assembly.setVisAttributes(description.invisible()); sens.setType("tracker"); for (xml_coll_t su(x_det, _U(support)); su; ++su) { - xml_comp_t x_support = su; - double support_thickness = getAttrOrDefault(x_support, _U(thickness), 2.0 * mm); - double support_length = getAttrOrDefault(x_support, _U(length), 2.0 * mm); - double support_rmin = getAttrOrDefault(x_support, _U(rmin), 2.0 * mm); - double support_zstart = getAttrOrDefault(x_support, _U(zstart), 2.0 * mm); - std::string support_name = getAttrOrDefault(x_support, _Unicode(name), "support_tube"); - std::string support_vis = getAttrOrDefault(x_support, _Unicode(vis), "AnlRed"); - xml_dim_t support_pos(x_support.child(_U(position), false)); - xml_dim_t support_rot(x_support.child(_U(rotation), false)); - Solid support_solid; + xml_comp_t x_support = su; + double support_thickness = getAttrOrDefault(x_support, _U(thickness), 2.0 * mm); + double support_length = getAttrOrDefault(x_support, _U(length), 2.0 * mm); + double support_rmin = getAttrOrDefault(x_support, _U(rmin), 2.0 * mm); + double support_zstart = getAttrOrDefault(x_support, _U(zstart), 2.0 * mm); + std::string support_name = + getAttrOrDefault(x_support, _Unicode(name), "support_tube"); + std::string support_vis = getAttrOrDefault(x_support, _Unicode(vis), "AnlRed"); + xml_dim_t support_pos(x_support.child(_U(position), false)); + xml_dim_t support_rot(x_support.child(_U(rotation), false)); + Solid support_solid; if (x_support.hasChild(_U(shape))) { xml_comp_t shape(x_support.child(_U(shape))); - string shape_type = shape.typeStr(); - support_solid = xml::createShape(description, shape_type, shape); + string shape_type = shape.typeStr(); + support_solid = xml::createShape(description, shape_type, shape); } else { support_solid = Tube(support_rmin, support_rmin + support_thickness, support_length / 2); } - Transform3D tr = Transform3D(Rotation3D(), Position(0, 0, (support_zstart + support_length / 2))); + Transform3D tr = + Transform3D(Rotation3D(), Position(0, 0, (support_zstart + support_length / 2))); if (support_pos.ptr() && support_rot.ptr()) { Rotation3D rot3D(RotationZYX(support_rot.z(0), support_rot.y(0), support_rot.x(0))); - Position pos3D(support_pos.x(0), support_pos.y(0), support_pos.z(0)); + Position pos3D(support_pos.x(0), support_pos.y(0), support_pos.z(0)); tr = Transform3D(rot3D, pos3D); } else if (support_pos.ptr()) { - tr = Transform3D(Rotation3D(), Position(support_pos.x(0), support_pos.y(0), support_pos.z(0))); + tr = + Transform3D(Rotation3D(), Position(support_pos.x(0), support_pos.y(0), support_pos.z(0))); } else if (support_rot.ptr()) { Rotation3D rot3D(RotationZYX(support_rot.z(0), support_rot.y(0), support_rot.x(0))); tr = Transform3D(rot3D, Position()); } Material support_mat = description.material(x_support.materialStr()); - Volume support_vol(support_name, support_solid, support_mat); + Volume support_vol(support_name, support_solid, support_mat); support_vol.setVisAttributes(description.visAttributes(support_vis)); pv = assembly.placeVolume(support_vol, tr); // pv = assembly.placeVolume(support_vol, Position(0, 0, support_zstart + support_length / 2)); @@ -78,7 +80,7 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) { xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); + string m_nam = x_mod.nameStr(); xml_comp_t x_box = x_mod.shape(); double x1 = x_box.x(); @@ -91,7 +93,7 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive total_thickness += xml_comp_t(ci).thickness(); } - Box m_solid(x1 / 2.0, y1 / 2.0, total_thickness / 2.0); + Box m_solid(x1 / 2.0, y1 / 2.0, total_thickness / 2.0); Volume m_volume(m_nam, m_solid, vacuum); m_volume.setVisAttributes(description.visAttributes(x_mod.visStr())); @@ -122,15 +124,15 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive double posZ = -total_thickness / 2.0; for (ci.reset(), n_sensor = 1, c_id = 0, posZ = -total_thickness / 2.0; ci; ++ci, ++c_id) { - xml_comp_t c = ci; - double c_thick = c.thickness(); - auto comp_x = getAttrOrDefault(c, _Unicode(x), x1); - auto comp_y = getAttrOrDefault(c, _Unicode(y), y1); + xml_comp_t c = ci; + double c_thick = c.thickness(); + auto comp_x = getAttrOrDefault(c, _Unicode(x), x1); + auto comp_y = getAttrOrDefault(c, _Unicode(y), y1); - Material c_mat = description.material(c.materialStr()); - string c_name = _toString(c_id, "OMD_component%d"); + Material c_mat = description.material(c.materialStr()); + string c_name = _toString(c_id, "OMD_component%d"); - Box comp_s1(comp_x / 2.0, comp_y / 2.0, c_thick / 2e0); + Box comp_s1(comp_x / 2.0, comp_y / 2.0, c_thick / 2e0); Solid comp_shape = comp_s1; // if(frame_s.isValid()) { // comp_shape = SubtractionSolid( comp_s1, frame_s); @@ -141,7 +143,8 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive pv = m_volume.placeVolume(c_vol, Position(0, 0, posZ + c_thick / 2.0)); if (c.isSensitive()) { // std::cout << " adding sensitive volume" << c_name << "\n"; - sdet.check(n_sensor > 2, "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); + sdet.check(n_sensor > 2, + "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); pv.addPhysVolID("slice", n_sensor); sens.setType("tracker"); c_vol.setSensitiveDetector(sens); @@ -155,11 +158,11 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive for (xml_coll_t li(x_det, _U(layer)); li; ++li) { xml_comp_t x_layer(li); - int l_id = x_layer.id(); - int mod_num = 1; + int l_id = x_layer.id(); + int mod_num = 1; - xml_comp_t l_env = x_layer.child(_U(envelope)); - string layer_name = det_name + std::string("_layer") + std::to_string(l_id); + xml_comp_t l_env = x_layer.child(_U(envelope)); + string layer_name = det_name + std::string("_layer") + std::to_string(l_id); std::string layer_vis = l_env.attr(_Unicode(vis)); // double layer_x = l_env.attr(_Unicode(x)); @@ -191,8 +194,8 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive DetElement layer_element(sdet, layer_name, l_id); layer_element.setPlacement(layer_pv); - string m_nam = x_layer.moduleStr(); - Volume m_vol = modules[m_nam]; + string m_nam = x_layer.moduleStr(); + Volume m_vol = modules[m_nam]; Placements& sensVols = sensitives[m_nam]; DetElement module(layer_element, "module_", l_id); @@ -201,9 +204,8 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive module.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_elt(module, sens_pv.volume().name(), mod_num); + DetElement comp_elt(module, sens_pv.volume().name(), mod_num); comp_elt.setPlacement(sens_pv); - } // for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) { @@ -261,7 +263,8 @@ static Ref_t create_OffMomentumTracker(Detector& description, xml_h e, Sensitive //} ++mod_num; } - Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), + Position(pos.x(), pos.y(), pos.z())); pv = motherVol.placeVolume(assembly, posAndRot); pv.addPhysVolID("system", det_id); sdet.setPlacement(pv); diff --git a/src/PFRICH_geo.cpp b/src/PFRICH_geo.cpp index aba06b4f7..db9fbe1bc 100644 --- a/src/PFRICH_geo.cpp +++ b/src/PFRICH_geo.cpp @@ -31,679 +31,702 @@ using namespace dd4hep::detail; static Ref_t createDetector(Detector& description, xml_h e, SensitiveDetector sens) { - xml_det_t x_det = e; - int det_id = x_det.id(); + xml_det_t x_det = e; + int det_id = x_det.id(); - string det_name = x_det.nameStr(); - Material air = description.air(); + string det_name = x_det.nameStr(); + Material air = description.air(); - DetElement sdet(det_name, det_id); + DetElement sdet(det_name, det_id); - std::vector rmins = {100, 100}; - std::vector rmaxs = {1300, 1300}; - std::vector zs = {-5000, 5000}; + std::vector rmins = {100, 100}; + std::vector rmaxs = {1300, 1300}; + std::vector zs = {-5000, 5000}; - sens.setType("tracker"); - description.invisible(); + sens.setType("tracker"); + description.invisible(); - xml::DetElement detElem = e; - std::string detName = detElem.nameStr(); - xml::Component dims = detElem.dimensions(); + xml::DetElement detElem = e; + std::string detName = detElem.nameStr(); + xml::Component dims = detElem.dimensions(); - xml_dim_t x_par(x_det.child(_U(parent))); + xml_dim_t x_par(x_det.child(_U(parent))); - string name = x_det.nameStr(); - string par_nam = x_par.nameStr(); - DetElement det_parent = description.detector(par_nam); + string name = x_det.nameStr(); + string par_nam = x_par.nameStr(); + DetElement det_parent = description.detector(par_nam); - Volume mother = det_parent.volume(); - PlacedVolume pv; + Volume mother = det_parent.volume(); + PlacedVolume pv; - int id = x_det.hasAttr(_U(id)) ? x_det.id() : 0; - xml_dim_t x_pos(x_det.child(_U(position), false)); - xml_dim_t x_rot(x_det.child(_U(rotation), false)); + int id = x_det.hasAttr(_U(id)) ? x_det.id() : 0; + xml_dim_t x_pos(x_det.child(_U(position), false)); + xml_dim_t x_rot(x_det.child(_U(rotation), false)); - auto vesselMat = description.material("VacuumOptical"); + auto vesselMat = description.material("VacuumOptical"); - Tube pfRICH_air_volume(0.0, 65.0, 25.0); // dimension of the pfRICH world in cm + Tube pfRICH_air_volume(0.0, 65.0, 25.0); // dimension of the pfRICH world in cm - Rotation3D rot(RotationZYX(0, M_PI, 0)); - Transform3D transform(rot, Position(0, 0, -149)); + Rotation3D rot(RotationZYX(0, M_PI, 0)); + Transform3D transform(rot, Position(0, 0, -149)); - // BUILD SENSORS /////////////////////// - // solid and volume: single sensor module + // BUILD SENSORS /////////////////////// + // solid and volume: single sensor module - OpticalSurfaceManager surfMgr = description.surfaceManager(); + OpticalSurfaceManager surfMgr = description.surfaceManager(); - // - sensor module - auto sensorElem = detElem.child(_Unicode(sensors)).child(_Unicode(module)); - auto sensorMat = description.material(sensorElem.attr(_Unicode(material))); - auto sensorVis = description.visAttributes(sensorElem.attr(_Unicode(vis))); - auto sensorSurf = surfMgr.opticalSurface(sensorElem.attr(_Unicode(surface))); - double sensorSide = sensorElem.attr(_Unicode(side)); - double sensorThickness = sensorElem.attr(_Unicode(thickness)); - auto readoutName = detElem.attr(_Unicode(readout)); + // - sensor module + auto sensorElem = detElem.child(_Unicode(sensors)).child(_Unicode(module)); + auto sensorMat = description.material(sensorElem.attr(_Unicode(material))); + auto sensorVis = description.visAttributes(sensorElem.attr(_Unicode(vis))); + auto sensorSurf = surfMgr.opticalSurface(sensorElem.attr(_Unicode(surface))); + double sensorSide = sensorElem.attr(_Unicode(side)); + double sensorThickness = sensorElem.attr(_Unicode(thickness)); + auto readoutName = detElem.attr(_Unicode(readout)); - double vesselRmin0 = dims.attr(_Unicode(rmin0)); - double vesselRmin1 = dims.attr(_Unicode(rmin1)); - double vesselRmax0 = dims.attr(_Unicode(rmax0)); - double vesselRmax1 = dims.attr(_Unicode(rmax1)); + double vesselRmin0 = dims.attr(_Unicode(rmin0)); + double vesselRmin1 = dims.attr(_Unicode(rmin1)); + double vesselRmax0 = dims.attr(_Unicode(rmax0)); + double vesselRmax1 = dims.attr(_Unicode(rmax1)); - int imod = 0; // module number + int imod = 0; // module number - auto gasvolMat = description.material("C4F10_PFRICH"); - auto gasvolVis = description.visAttributes("DRICH_gas_vis"); - auto vesselVis = description.visAttributes("DRICH_gas_vis"); + auto gasvolMat = description.material("C4F10_PFRICH"); + auto gasvolVis = description.visAttributes("DRICH_gas_vis"); + auto vesselVis = description.visAttributes("DRICH_gas_vis"); - double windowThickness = dims.attr(_Unicode(window_thickness)); - double wallThickness = dims.attr(_Unicode(wall_thickness)); + double windowThickness = dims.attr(_Unicode(window_thickness)); + double wallThickness = dims.attr(_Unicode(wall_thickness)); - double proximityGap = dims.attr(_Unicode(proximity_gap)); + double proximityGap = dims.attr(_Unicode(proximity_gap)); - long debug_optics_mode = description.constantAsLong("PFRICH_debug_optics"); + long debug_optics_mode = description.constantAsLong("PFRICH_debug_optics"); - bool debug_optics = debug_optics_mode > 0; + bool debug_optics = debug_optics_mode > 0; - auto radiatorElem = detElem.child(_Unicode(radiator)); - double radiatorFrontplane = radiatorElem.attr(_Unicode(frontplane)); + auto radiatorElem = detElem.child(_Unicode(radiator)); + double radiatorFrontplane = radiatorElem.attr(_Unicode(frontplane)); - auto aerogelElem = radiatorElem.child(_Unicode(aerogel)); - double aerogelThickness = aerogelElem.attr(_Unicode(thickness)); + auto aerogelElem = radiatorElem.child(_Unicode(aerogel)); + double aerogelThickness = aerogelElem.attr(_Unicode(thickness)); - double radiatorRmin = radiatorElem.attr(_Unicode(rmin)); - double radiatorRmax = radiatorElem.attr(_Unicode(rmax)); + double radiatorRmin = radiatorElem.attr(_Unicode(rmin)); + double radiatorRmax = radiatorElem.attr(_Unicode(rmax)); - double airgapThickness = 0.1; - double filterThickness = 1; + double airgapThickness = 0.1; + double filterThickness = 1; - auto aerogelMat = description.material("C4F10_PFRICH"); - auto filterMat = description.material("C4F10_PFRICH"); + auto aerogelMat = description.material("C4F10_PFRICH"); + auto filterMat = description.material("C4F10_PFRICH"); - double vesselLength = dims.attr(_Unicode(length)); - auto originFront = Position(0., 0., vesselLength / 2.0); - double sensorZpos = radiatorFrontplane - aerogelThickness - proximityGap - 0.5 * sensorThickness; - auto sensorPlanePos = Position(0., 0., sensorZpos) + originFront; // reference position + double vesselLength = dims.attr(_Unicode(length)); + auto originFront = Position(0., 0., vesselLength / 2.0); + double sensorZpos = radiatorFrontplane - aerogelThickness - proximityGap - 0.5 * sensorThickness; + auto sensorPlanePos = Position(0., 0., sensorZpos) + originFront; // reference position - // readout coder <-> unique sensor ID - /* - `sensorIDfields` is a list of readout fields used to specify a unique sensor ID + // readout coder <-> unique sensor ID + /* - `sensorIDfields` is a list of readout fields used to specify a unique sensor ID * - `cellMask` is defined such that a hit's `cellID & cellMask` is the corresponding sensor's unique ID * - this redundant generalization is for future flexibility, and consistency with dRICH */ - std::vector sensorIDfields = {"module"}; - const auto& readoutCoder = *description.readout(readoutName).idSpec().decoder(); - // determine `cellMask` based on `sensorIDfields` - uint64_t cellMask = 0; - for (const auto& idField : sensorIDfields) - cellMask |= readoutCoder[idField].mask(); - description.add(Constant("PFRICH_cell_mask", std::to_string(cellMask))); - // create a unique sensor ID from a sensor's PlacedVolume::volIDs - auto encodeSensorID = [&readoutCoder](auto ids) { - uint64_t enc = 0; - for (const auto& [idField, idValue] : ids) - enc |= uint64_t(idValue) << readoutCoder[idField].offset(); - return enc; - }; - - auto mirrorElem = detElem.child(_Unicode(mirror)); - auto mirrorMat = description.material(mirrorElem.attr(_Unicode(material))); - auto mirrorVis = description.visAttributes(mirrorElem.attr(_Unicode(vis))); - - Cone mirror_cone(vesselLength / 2.0, vesselRmax1-7, vesselRmax1-7+0.3, vesselRmax1-13, vesselRmax1-13+0.3); - - // flange - - float _FLANGE_EPIPE_DIAMETER_ = 10.53; // in cm - float _FLANGE_HPIPE_DIAMETER_ = 4.47; // in cm - float _FLANGE_HPIPE_OFFSET_ = 6.76; // in cm - float clearance = 0.5; // in cm - - /// Inner mirror cone - // A wedge bridging two cylinders; - - Tube eflange(0.0, _FLANGE_EPIPE_DIAMETER_/2 + clearance, 25); - Tube hflange(0.0, _FLANGE_HPIPE_DIAMETER_/2 + clearance, 25); - - double r0 = _FLANGE_EPIPE_DIAMETER_/2 + clearance; - double r1 = _FLANGE_HPIPE_DIAMETER_/2 + clearance; - double L = _FLANGE_HPIPE_OFFSET_; - double a = r0*L/(r0-r1); - double b = r0*r0/a; - double c = r1*(a-b)/r0; - - // GEANT variables to define G4Trap; - double pDz = 25, pTheta = 0.0, pPhi = 0.0, pDy1 = (a - b - c)/2, pDy2 = pDy1; - double pDx1 = sqrt(r0*r0 - b*b), pDx2 = pDx1*r1/r0, pDx3 = pDx1, pDx4 = pDx2, pAlp1 = 0.0, pAlp2 = 0.0; - - Trap wedge(pDz, pTheta, pPhi, pDy1, pDx1, pDx2, pAlp1, pDy2, pDx3, pDx4, pAlp2); - - UnionSolid flange_shape(eflange, hflange, Position(-_FLANGE_HPIPE_OFFSET_, 0.0, 0.0)); - Rotation3D rZ(RotationZYX(M_PI/2.0, 0.0, 0.0)); - Transform3D transform_flange(rZ, Position(-b - pDy1, 0.0, 0.0)); - UnionSolid flange_final_shape(flange_shape, wedge, transform_flange); - - Volume flangeVol(detName + "_flange", flange_final_shape, mirrorMat); - flangeVol.setVisAttributes(mirrorVis); - - SubtractionSolid pfRICH_volume_shape(pfRICH_air_volume, flange_final_shape); - - Volume pfRICH_volume(detName +"_Vol", pfRICH_volume_shape, vesselMat); // dimension of the pfRICH world in cm + std::vector sensorIDfields = {"module"}; + const auto& readoutCoder = *description.readout(readoutName).idSpec().decoder(); + // determine `cellMask` based on `sensorIDfields` + uint64_t cellMask = 0; + for (const auto& idField : sensorIDfields) + cellMask |= readoutCoder[idField].mask(); + description.add(Constant("PFRICH_cell_mask", std::to_string(cellMask))); + // create a unique sensor ID from a sensor's PlacedVolume::volIDs + auto encodeSensorID = [&readoutCoder](auto ids) { + uint64_t enc = 0; + for (const auto& [idField, idValue] : ids) + enc |= uint64_t(idValue) << readoutCoder[idField].offset(); + return enc; + }; + + auto mirrorElem = detElem.child(_Unicode(mirror)); + auto mirrorMat = description.material(mirrorElem.attr(_Unicode(material))); + auto mirrorVis = description.visAttributes(mirrorElem.attr(_Unicode(vis))); + + Cone mirror_cone(vesselLength / 2.0, vesselRmax1 - 7, vesselRmax1 - 7 + 0.3, vesselRmax1 - 13, + vesselRmax1 - 13 + 0.3); + + // flange + + float _FLANGE_EPIPE_DIAMETER_ = 10.53; // in cm + float _FLANGE_HPIPE_DIAMETER_ = 4.47; // in cm + float _FLANGE_HPIPE_OFFSET_ = 6.76; // in cm + float clearance = 0.5; // in cm + + /// Inner mirror cone + // A wedge bridging two cylinders; + + Tube eflange(0.0, _FLANGE_EPIPE_DIAMETER_ / 2 + clearance, 25); + Tube hflange(0.0, _FLANGE_HPIPE_DIAMETER_ / 2 + clearance, 25); + + double r0 = _FLANGE_EPIPE_DIAMETER_ / 2 + clearance; + double r1 = _FLANGE_HPIPE_DIAMETER_ / 2 + clearance; + double L = _FLANGE_HPIPE_OFFSET_; + double a = r0 * L / (r0 - r1); + double b = r0 * r0 / a; + double c = r1 * (a - b) / r0; + + // GEANT variables to define G4Trap; + double pDz = 25, pTheta = 0.0, pPhi = 0.0, pDy1 = (a - b - c) / 2, pDy2 = pDy1; + double pDx1 = sqrt(r0 * r0 - b * b), pDx2 = pDx1 * r1 / r0, pDx3 = pDx1, pDx4 = pDx2, pAlp1 = 0.0, + pAlp2 = 0.0; + + Trap wedge(pDz, pTheta, pPhi, pDy1, pDx1, pDx2, pAlp1, pDy2, pDx3, pDx4, pAlp2); + + UnionSolid flange_shape(eflange, hflange, Position(-_FLANGE_HPIPE_OFFSET_, 0.0, 0.0)); + Rotation3D rZ(RotationZYX(M_PI / 2.0, 0.0, 0.0)); + Transform3D transform_flange(rZ, Position(-b - pDy1, 0.0, 0.0)); + UnionSolid flange_final_shape(flange_shape, wedge, transform_flange); + + Volume flangeVol(detName + "_flange", flange_final_shape, mirrorMat); + flangeVol.setVisAttributes(mirrorVis); + + SubtractionSolid pfRICH_volume_shape(pfRICH_air_volume, flange_final_shape); + + Volume pfRICH_volume(detName + "_Vol", pfRICH_volume_shape, + vesselMat); // dimension of the pfRICH world in cm + + pv = mother.placeVolume(pfRICH_volume, transform); + + if (id != 0) { + pv.addPhysVolID("system", id); + } + sdet.setPlacement(pv); + + /// tank solids + + double boreDelta = vesselRmin1 - vesselRmin0; + Cone vesselTank(vesselLength / 2.0, vesselRmin1, vesselRmax1, vesselRmin0, vesselRmax0); + Cone gasvolTank(vesselLength / 2.0 - windowThickness, vesselRmin1 + wallThickness, + vesselRmax1 - wallThickness, vesselRmin0 + wallThickness, + vesselRmax0 - wallThickness); + + Box gasvolBox(1000, 1000, 1000); + + Solid gasvolSolid; + gasvolSolid = gasvolTank; - pv = mother.placeVolume(pfRICH_volume, transform); + Solid vesselSolid; + vesselSolid = vesselTank; - if (id != 0) { - pv.addPhysVolID("system", id); - } - sdet.setPlacement(pv); - - /// tank solids - - double boreDelta = vesselRmin1 - vesselRmin0; - Cone vesselTank(vesselLength / 2.0, vesselRmin1, vesselRmax1, vesselRmin0, vesselRmax0); - Cone gasvolTank(vesselLength / 2.0 - windowThickness, vesselRmin1 + wallThickness, vesselRmax1 - wallThickness, - vesselRmin0 + wallThickness, vesselRmax0 - wallThickness); - - Box gasvolBox(1000, 1000, 1000); - - Solid gasvolSolid; - gasvolSolid = gasvolTank; - - Solid vesselSolid; - vesselSolid = vesselTank; - - Solid mirrorSolid; - mirrorSolid = mirror_cone; + Solid mirrorSolid; + mirrorSolid = mirror_cone; - Volume vesselVol(detName, vesselSolid, vesselMat); - Volume gasvolVol(detName + "_gas", gasvolSolid, gasvolMat); - vesselVol.setVisAttributes(vesselVis); - gasvolVol.setVisAttributes(gasvolVis); + Volume vesselVol(detName, vesselSolid, vesselMat); + Volume gasvolVol(detName + "_gas", gasvolSolid, gasvolMat); + vesselVol.setVisAttributes(vesselVis); + gasvolVol.setVisAttributes(gasvolVis); - Volume mirrorVol(detName, mirrorSolid, mirrorMat); - mirrorVol.setVisAttributes(mirrorVis); + Volume mirrorVol(detName, mirrorSolid, mirrorMat); + mirrorVol.setVisAttributes(mirrorVis); - // place gas volume - PlacedVolume gasvolPV = vesselVol.placeVolume(gasvolVol, Position(0, 0, 0)); - DetElement gasvolDE(sdet, "gasvol_de", 0); - gasvolDE.setPlacement(gasvolPV); + // place gas volume + PlacedVolume gasvolPV = vesselVol.placeVolume(gasvolVol, Position(0, 0, 0)); + DetElement gasvolDE(sdet, "gasvol_de", 0); + gasvolDE.setPlacement(gasvolPV); - // BUILD RADIATOR ////////////////////////////////////// + // BUILD RADIATOR ////////////////////////////////////// - // solid and volume: create aerogel and filter - Cone aerogelSolid(aerogelThickness / 2, radiatorRmin + boreDelta * aerogelThickness / vesselLength, /* at backplane */ - radiatorRmax, radiatorRmin, /* at frontplane */ - radiatorRmax); - Cone filterSolid(filterThickness / 2, - radiatorRmin + boreDelta * (aerogelThickness + airgapThickness + filterThickness) / - vesselLength, /* at backplane */ - radiatorRmax, - radiatorRmin + boreDelta * (aerogelThickness + airgapThickness) / vesselLength, /* at frontplane */ - radiatorRmax); - Volume aerogelVol(detName + "_aerogel", aerogelSolid, aerogelMat); - Volume filterVol(detName + "_filter", filterSolid, filterMat); + // solid and volume: create aerogel and filter + Cone aerogelSolid(aerogelThickness / 2, + radiatorRmin + boreDelta * aerogelThickness / vesselLength, /* at backplane */ + radiatorRmax, radiatorRmin, /* at frontplane */ + radiatorRmax); + Cone filterSolid(filterThickness / 2, + radiatorRmin + boreDelta * + (aerogelThickness + airgapThickness + filterThickness) / + vesselLength, /* at backplane */ + radiatorRmax, + radiatorRmin + boreDelta * (aerogelThickness + airgapThickness) / + vesselLength, /* at frontplane */ + radiatorRmax); + Volume aerogelVol(detName + "_aerogel", aerogelSolid, aerogelMat); + Volume filterVol(detName + "_filter", filterSolid, filterMat); - // radiator material names - description.add(Constant("PFRICH_aerogel_material", aerogelMat.ptr()->GetName(), "string")); - description.add(Constant("PFRICH_filter_material", filterMat.ptr()->GetName(), "string")); - description.add(Constant("PFRICH_gasvol_material", gasvolMat.ptr()->GetName(), "string")); + // radiator material names + description.add(Constant("PFRICH_aerogel_material", aerogelMat.ptr()->GetName(), "string")); + description.add(Constant("PFRICH_filter_material", filterMat.ptr()->GetName(), "string")); + description.add(Constant("PFRICH_gasvol_material", gasvolMat.ptr()->GetName(), "string")); - Box sensorSolid(sensorSide / 2., sensorSide / 2., sensorThickness / 2.); - Volume sensorVol(detName + "_sensor", sensorSolid, sensorMat); - sensorVol.setVisAttributes(sensorVis); + Box sensorSolid(sensorSide / 2., sensorSide / 2., sensorThickness / 2.); + Volume sensorVol(detName + "_sensor", sensorSolid, sensorMat); + sensorVol.setVisAttributes(sensorVis); - // -- Mirrors --------------------------------------------------------------------------------- - // Some "standard" value applied to all mirrors; - // At the downstream (sensor plane) location; upstream radii are calculated automatically; - double _CONICAL_MIRROR_INNER_RADIUS_ = 12.0; - double _CONICAL_MIRROR_OUTER_RADIUS_ = 57.0; + // -- Mirrors --------------------------------------------------------------------------------- + // Some "standard" value applied to all mirrors; + // At the downstream (sensor plane) location; upstream radii are calculated automatically; + double _CONICAL_MIRROR_INNER_RADIUS_ = 12.0; + double _CONICAL_MIRROR_OUTER_RADIUS_ = 57.0; - double _INNER_MIRROR_THICKNESS_ = 0.1; //0.29*_INCH - double _OUTER_MIRROR_THICKNESS_ = 0.2; //0.54*_INCH + double _INNER_MIRROR_THICKNESS_ = 0.1; //0.29*_INCH + double _OUTER_MIRROR_THICKNESS_ = 0.2; //0.54*_INCH - /// Detailed sensor description + /// Detailed sensor description - double _FIDUCIAL_VOLUME_LENGTH_ = 49.1; // cm - double _SENSOR_AREA_LENGTH_ = 5; // cm - double _HRPPD_CENTRAL_ROW_OFFSET_ = 4.0; // cm - double _HRPPD_WINDOW_THICKNESS_ = 0.38; // cm - double _HRPPD_CONTAINER_VOLUME_HEIGHT_ = 3.2; // cm - double _HRPPD_INSTALLATION_GAP_ = 0.25; // cm + double _FIDUCIAL_VOLUME_LENGTH_ = 49.1; // cm + double _SENSOR_AREA_LENGTH_ = 5; // cm + double _HRPPD_CENTRAL_ROW_OFFSET_ = 4.0; // cm + double _HRPPD_WINDOW_THICKNESS_ = 0.38; // cm + double _HRPPD_CONTAINER_VOLUME_HEIGHT_ = 3.2; // cm + double _HRPPD_INSTALLATION_GAP_ = 0.25; // cm - double _HRPPD_SUPPORT_GRID_BAR_HEIGHT_ = 0.2; + double _HRPPD_SUPPORT_GRID_BAR_HEIGHT_ = 0.2; - double _HRPPD_TILE_SIZE_ = 12.0; // cm - double _HRPPD_OPEN_AREA_SIZE_ = 11.4; // cm - double _HRPPD_ACTIVE_AREA_SIZE_ = 10.8; // cm - double _HRPPD_CERAMIC_BODY_THICKNESS_ = 0.9; // cm - double _HRPPD_BASEPLATE_THICKNESS_ = 0.3; // cm - double _HRPPD_PLATING_LAYER_THICKNESS_ = 0.006; // cm - double _EFFECTIVE_MCP_THICKNESS_ = 2*0.06*0.3; // cm + double _HRPPD_TILE_SIZE_ = 12.0; // cm + double _HRPPD_OPEN_AREA_SIZE_ = 11.4; // cm + double _HRPPD_ACTIVE_AREA_SIZE_ = 10.8; // cm + double _HRPPD_CERAMIC_BODY_THICKNESS_ = 0.9; // cm + double _HRPPD_BASEPLATE_THICKNESS_ = 0.3; // cm + double _HRPPD_PLATING_LAYER_THICKNESS_ = 0.006; // cm + double _EFFECTIVE_MCP_THICKNESS_ = 2 * 0.06 * 0.3; // cm - double _READOUT_PCB_THICKNESS_ = 0.2; - double _READOUT_PCB_SIZE_ = _HRPPD_OPEN_AREA_SIZE_ - 0.2; + double _READOUT_PCB_THICKNESS_ = 0.2; + double _READOUT_PCB_SIZE_ = _HRPPD_OPEN_AREA_SIZE_ - 0.2; - double _ASIC_SIZE_XY_ = 1.6; - double _ASIC_THICKNESS_ = 0.1; + double _ASIC_SIZE_XY_ = 1.6; + double _ASIC_THICKNESS_ = 0.1; - double xysize = _HRPPD_TILE_SIZE_, wndthick = _HRPPD_WINDOW_THICKNESS_; + double xysize = _HRPPD_TILE_SIZE_, wndthick = _HRPPD_WINDOW_THICKNESS_; - // HRPPD assembly container volume; - double hrppd_container_volume_thickness = _HRPPD_CONTAINER_VOLUME_HEIGHT_; + // HRPPD assembly container volume; + double hrppd_container_volume_thickness = _HRPPD_CONTAINER_VOLUME_HEIGHT_; - double _ACRYLIC_THICKNESS_ = 0.3; + double _ACRYLIC_THICKNESS_ = 0.3; - // HRPPD - Box hrppd_Solid(xysize/2, xysize/2, hrppd_container_volume_thickness/2); + // HRPPD + Box hrppd_Solid(xysize / 2, xysize / 2, hrppd_container_volume_thickness / 2); - Volume hrppdVol_air(detName + "_air_hrppd", hrppd_Solid, air); - Volume hrppdVol(detName + "_hrppd", hrppd_Solid, sensorMat); + Volume hrppdVol_air(detName + "_air_hrppd", hrppd_Solid, air); + Volume hrppdVol(detName + "_hrppd", hrppd_Solid, sensorMat); - hrppdVol_air.setVisAttributes(gasvolVis); - DetElement hrppdDE(sdet, "hrppd_de", 0); + hrppdVol_air.setVisAttributes(gasvolVis); + DetElement hrppdDE(sdet, "hrppd_de", 0); - // Quartz Window - Box wnd_Solid(xysize/2, xysize/2, wndthick/2); + // Quartz Window + Box wnd_Solid(xysize / 2, xysize / 2, wndthick / 2); - Volume wndVol(detName + "_wnd", wnd_Solid, gasvolMat); - wndVol.setVisAttributes(gasvolVis); + Volume wndVol(detName + "_wnd", wnd_Solid, gasvolMat); + wndVol.setVisAttributes(gasvolVis); - double accu = -hrppd_container_volume_thickness/2; + double accu = -hrppd_container_volume_thickness / 2; - PlacedVolume wndPV = hrppdVol_air.placeVolume(wndVol, Position(0, 0, accu + wndthick/2)); + PlacedVolume wndPV = hrppdVol_air.placeVolume(wndVol, Position(0, 0, accu + wndthick / 2)); - DetElement wndDE(hrppdDE, "wnd_de", 0); - wndDE.setPlacement(wndPV); + DetElement wndDE(hrppdDE, "wnd_de", 0); + wndDE.setPlacement(wndPV); - // double pitch = xysize + _HRPPD_INSTALLATION_GAP_; - double xyactive = _HRPPD_ACTIVE_AREA_SIZE_; - double xyopen = _HRPPD_OPEN_AREA_SIZE_; - double certhick = _HRPPD_CERAMIC_BODY_THICKNESS_;//, zcer = azOffset + wndthick + certhick/2; + // double pitch = xysize + _HRPPD_INSTALLATION_GAP_; + double xyactive = _HRPPD_ACTIVE_AREA_SIZE_; + double xyopen = _HRPPD_OPEN_AREA_SIZE_; + double certhick = _HRPPD_CERAMIC_BODY_THICKNESS_; //, zcer = azOffset + wndthick + certhick/2; - accu += wndthick; + accu += wndthick; - // Ceramic body - Box cerbox(xysize/2, xysize/2, certhick/2); - Box cut_box(xyopen/2, xyopen/2, certhick/2); + // Ceramic body + Box cerbox(xysize / 2, xysize / 2, certhick / 2); + Box cut_box(xyopen / 2, xyopen / 2, certhick / 2); - SubtractionSolid ceramic (cerbox, cut_box, Position(0,0, -_HRPPD_BASEPLATE_THICKNESS_)); + SubtractionSolid ceramic(cerbox, cut_box, Position(0, 0, -_HRPPD_BASEPLATE_THICKNESS_)); - Volume ceramicVol(detName + "_ceramic", ceramic, air); - ceramicVol.setVisAttributes(gasvolVis); + Volume ceramicVol(detName + "_ceramic", ceramic, air); + ceramicVol.setVisAttributes(gasvolVis); - PlacedVolume ceramicPV = hrppdVol_air.placeVolume(ceramicVol, Position(0.0, 0.0, accu + certhick/2)); - DetElement ceramicDE(sdet, "ceramic_de", 0); - ceramicDE.setPlacement(ceramicPV); + PlacedVolume ceramicPV = + hrppdVol_air.placeVolume(ceramicVol, Position(0.0, 0.0, accu + certhick / 2)); + DetElement ceramicDE(sdet, "ceramic_de", 0); + ceramicDE.setPlacement(ceramicPV); - // Plating body + // Plating body - Box plating_solid(xyopen/2, xyopen/2, _HRPPD_PLATING_LAYER_THICKNESS_/2); - Volume platingVol( detName + "_plating", plating_solid, air); + Box plating_solid(xyopen / 2, xyopen / 2, _HRPPD_PLATING_LAYER_THICKNESS_ / 2); + Volume platingVol(detName + "_plating", plating_solid, air); - platingVol.setVisAttributes(gasvolVis); - PlacedVolume platingPV = hrppdVol_air.placeVolume(platingVol, Position(0.0, 0.0, accu + certhick/2)); - DetElement platingDE(sdet, "plating_de", 0); - platingDE.setPlacement(platingPV); + platingVol.setVisAttributes(gasvolVis); + PlacedVolume platingPV = + hrppdVol_air.placeVolume(platingVol, Position(0.0, 0.0, accu + certhick / 2)); + DetElement platingDE(sdet, "plating_de", 0); + platingDE.setPlacement(platingPV); - // MCP body + // MCP body - Box mcp_solid( xyopen/2, xyopen/2, _EFFECTIVE_MCP_THICKNESS_/2); - Volume mcpVol( detName + "_mcp", mcp_solid, air); + Box mcp_solid(xyopen / 2, xyopen / 2, _EFFECTIVE_MCP_THICKNESS_ / 2); + Volume mcpVol(detName + "_mcp", mcp_solid, air); - mcpVol.setVisAttributes(gasvolVis); - PlacedVolume mcpPV = hrppdVol_air.placeVolume(mcpVol, Position(0.0, 0.0, accu + certhick/2 + - _HRPPD_PLATING_LAYER_THICKNESS_/2 + _EFFECTIVE_MCP_THICKNESS_/2)); - DetElement mcpDE(sdet, "mcp_de", 0); - mcpDE.setPlacement(mcpPV); + mcpVol.setVisAttributes(gasvolVis); + PlacedVolume mcpPV = hrppdVol_air.placeVolume( + mcpVol, Position(0.0, 0.0, + accu + certhick / 2 + _HRPPD_PLATING_LAYER_THICKNESS_ / 2 + + _EFFECTIVE_MCP_THICKNESS_ / 2)); + DetElement mcpDE(sdet, "mcp_de", 0); + mcpDE.setPlacement(mcpPV); - double pdthick = 0.001; + double pdthick = 0.001; - Box pdbox_solid(xyactive/2, xyactive/2, pdthick/2); - Volume pdboxVol( detName + "_pd", pdbox_solid, air); + Box pdbox_solid(xyactive / 2, xyactive / 2, pdthick / 2); + Volume pdboxVol(detName + "_pd", pdbox_solid, air); - pdboxVol.setVisAttributes(gasvolVis); - PlacedVolume pdboxPV = hrppdVol_air.placeVolume(pdboxVol, Position(0.0, 0.0, accu + pdthick + pdthick/2)); + pdboxVol.setVisAttributes(gasvolVis); + PlacedVolume pdboxPV = + hrppdVol_air.placeVolume(pdboxVol, Position(0.0, 0.0, accu + pdthick + pdthick / 2)); - DetElement pdboxDE(sdet, "pdbox_de", 0); - pdboxDE.setPlacement(pdboxPV); + DetElement pdboxDE(sdet, "pdbox_de", 0); + pdboxDE.setPlacement(pdboxPV); - Box qdbox_solid(xyactive/2, xyactive/2, pdthick/2); - Volume qdboxVol( detName + "_qd", qdbox_solid, air); + Box qdbox_solid(xyactive / 2, xyactive / 2, pdthick / 2); + Volume qdboxVol(detName + "_qd", qdbox_solid, air); - qdboxVol.setVisAttributes(gasvolVis); - PlacedVolume qdboxPV = hrppdVol_air.placeVolume(qdboxVol, Position(0.0, 0.0, accu + pdthick/2)); + qdboxVol.setVisAttributes(gasvolVis); + PlacedVolume qdboxPV = hrppdVol_air.placeVolume(qdboxVol, Position(0.0, 0.0, accu + pdthick / 2)); - DetElement qdboxDE(sdet, "qdbox_de", 0); - pdboxDE.setPlacement(qdboxPV); + DetElement qdboxDE(sdet, "qdbox_de", 0); + pdboxDE.setPlacement(qdboxPV); - accu += certhick + 1*mm; + accu += certhick + 1 * mm; - /// PCB Board + /// PCB Board - Box pcb_solid (_READOUT_PCB_SIZE_/2, _READOUT_PCB_SIZE_/2, _READOUT_PCB_THICKNESS_/2); - Volume pcbVol( detName + "_pcb", pcb_solid, air); + Box pcb_solid(_READOUT_PCB_SIZE_ / 2, _READOUT_PCB_SIZE_ / 2, _READOUT_PCB_THICKNESS_ / 2); + Volume pcbVol(detName + "_pcb", pcb_solid, air); - pcbVol.setVisAttributes(gasvolVis); - PlacedVolume pcbPV = hrppdVol_air.placeVolume(pcbVol, Position(0.0, 0.0, accu + _READOUT_PCB_THICKNESS_ /2)); + pcbVol.setVisAttributes(gasvolVis); + PlacedVolume pcbPV = + hrppdVol_air.placeVolume(pcbVol, Position(0.0, 0.0, accu + _READOUT_PCB_THICKNESS_ / 2)); - DetElement pcbDE(sdet, "pcb_de", 0); - pcbDE.setPlacement(pcbPV); + DetElement pcbDE(sdet, "pcb_de", 0); + pcbDE.setPlacement(pcbPV); - accu += _READOUT_PCB_THICKNESS_ + 0.001; + accu += _READOUT_PCB_THICKNESS_ + 0.001; - // ASIC Board + // ASIC Board - Box asic_solid( _ASIC_SIZE_XY_/2, _ASIC_SIZE_XY_/2, _ASIC_THICKNESS_/2); - Volume asicVol( detName + "_asic", asic_solid, mirrorMat); - asicVol.setVisAttributes(mirrorVis); + Box asic_solid(_ASIC_SIZE_XY_ / 2, _ASIC_SIZE_XY_ / 2, _ASIC_THICKNESS_ / 2); + Volume asicVol(detName + "_asic", asic_solid, mirrorMat); + asicVol.setVisAttributes(mirrorVis); - double asic_pitch = _READOUT_PCB_SIZE_/2; + double asic_pitch = _READOUT_PCB_SIZE_ / 2; - imod = 0; + imod = 0; - for(unsigned ix=0; ix<2; ix++) { - double xOffset = asic_pitch*(ix - (2-1)/2.); + for (unsigned ix = 0; ix < 2; ix++) { + double xOffset = asic_pitch * (ix - (2 - 1) / 2.); - for(unsigned iy=0; iy<2; iy++) { - double yOffset = asic_pitch*(iy - (2-1)/2.); + for (unsigned iy = 0; iy < 2; iy++) { + double yOffset = asic_pitch * (iy - (2 - 1) / 2.); - auto asicPV = hrppdVol_air.placeVolume(asicVol, Position(xOffset, yOffset, accu + _ASIC_THICKNESS_/2)); + auto asicPV = hrppdVol_air.placeVolume( + asicVol, Position(xOffset, yOffset, accu + _ASIC_THICKNESS_ / 2)); - DetElement asicDE(sdet, "asic_de_" + std::to_string(imod), 0); - asicDE.setPlacement(asicPV); + DetElement asicDE(sdet, "asic_de_" + std::to_string(imod), 0); + asicDE.setPlacement(asicPV); - imod++; + imod++; - } //for iy - } //for ix + } //for iy + } //for ix - accu += _ASIC_THICKNESS_ + 0.01*mm; + accu += _ASIC_THICKNESS_ + 0.01 * mm; - // Loading the coordinates + // Loading the coordinates - unsigned const hdim = 9; - const unsigned flags[hdim][hdim] = { - // NB: WYSIWIG fashion; well, it is top/ bottom and left/right symmetric; - {0, 0, 1, 1, 1, 1, 1, 0, 0}, - {0, 1, 1, 1, 1, 1, 1, 1, 0}, - {1, 1, 1, 1, 1, 1, 1, 1, 1}, - {1, 1, 1, 1, 2, 1, 1, 1, 1}, - {3, 3, 3, 4, 0, 2, 1, 1, 1}, - {1, 1, 1, 1, 2, 1, 1, 1, 1}, - {1, 1, 1, 1, 1, 1, 1, 1, 1}, - {0, 1, 1, 1, 1, 1, 1, 1, 0}, - {0, 0, 1, 1, 1, 1, 1, 0, 0} - }; + unsigned const hdim = 9; + const unsigned flags[hdim][hdim] = { + // NB: WYSIWIG fashion; well, it is top/ bottom and left/right symmetric; + {0, 0, 1, 1, 1, 1, 1, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {1, 1, 1, 1, 1, 1, 1, 1, 1}, + {1, 1, 1, 1, 2, 1, 1, 1, 1}, {3, 3, 3, 4, 0, 2, 1, 1, 1}, {1, 1, 1, 1, 2, 1, 1, 1, 1}, + {1, 1, 1, 1, 1, 1, 1, 1, 1}, {0, 1, 1, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 1, 1, 1, 1, 0, 0}}; - std::vector> coord; + std::vector> coord; - for(unsigned ix=0; ix= 3 ? -_HRPPD_CENTRAL_ROW_OFFSET_ : 0.0); - coord.push_back(std::make_pair(TVector2(qxOffset, yOffset), flag%2)); - } //for iy - } //for ix + double qxOffset = xOffset + (flag >= 3 ? -_HRPPD_CENTRAL_ROW_OFFSET_ : 0.0); + coord.push_back(std::make_pair(TVector2(qxOffset, yOffset), flag % 2)); + } //for iy + } //for ix - /// Set sensors into the coordinates - /// - for(auto xyptr: coord) { - auto &xy = xyptr.first; + /// Set sensors into the coordinates + /// + for (auto xyptr : coord) { + auto& xy = xyptr.first; - double sx = xy.X(); - double sy = xy.Y(); + double sx = xy.X(); + double sy = xy.Y(); - // placement (note: transformations are in reverse order) - auto sensorPlacement = Transform3D( - Translation3D(sensorPlanePos.x(), sensorPlanePos.y(), sensorPlanePos.z() + 34) * // move to reference position - Translation3D(sx, sy, 0.) // move to grid position - ); + // placement (note: transformations are in reverse order) + auto sensorPlacement = + Transform3D(Translation3D(sensorPlanePos.x(), sensorPlanePos.y(), + sensorPlanePos.z() + 34) * // move to reference position + Translation3D(sx, sy, 0.) // move to grid position + ); - auto sensorPV = pfRICH_volume.placeVolume(hrppdVol_air, sensorPlacement); + auto sensorPV = pfRICH_volume.placeVolume(hrppdVol_air, sensorPlacement); - // properties - sensorPV.addPhysVolID("module", imod); // NOTE: must be consistent with `sensorIDfields` - auto imodEnc = encodeSensorID(sensorPV.volIDs()); - DetElement sensorDE(sdet, "sensor_de_" + std::to_string(imod), imodEnc); - sensorDE.setPlacement(sensorPV); - if (!debug_optics) { - SkinSurface sensorSkin(description, sensorDE, "sensor_optical_surface_" + std::to_string(imod), sensorSurf, - sensorVol); - sensorSkin.isValid(); - }; - - // increment sensor module number - imod++; + // properties + sensorPV.addPhysVolID("module", imod); // NOTE: must be consistent with `sensorIDfields` + auto imodEnc = encodeSensorID(sensorPV.volIDs()); + DetElement sensorDE(sdet, "sensor_de_" + std::to_string(imod), imodEnc); + sensorDE.setPlacement(sensorPV); + if (!debug_optics) { + SkinSurface sensorSkin(description, sensorDE, + "sensor_optical_surface_" + std::to_string(imod), sensorSurf, + sensorVol); + sensorSkin.isValid(); + }; - } + // increment sensor module number + imod++; + } /// Aerogel - float _AEROGEL_INNER_WALL_THICKNESS_ = 0.01; - - float _VESSEL_INNER_WALL_THICKNESS_ = 0.29 * 2.54; - - float _VESSEL_OUTER_WALL_THICKNESS_ = 0.54 * 2.54;; + float _AEROGEL_INNER_WALL_THICKNESS_ = 0.01; - float _VESSEL_OUTER_RADIUS_ = 63.8; + float _VESSEL_INNER_WALL_THICKNESS_ = 0.29 * 2.54; - double _VESSEL_FRONT_SIDE_THICKNESS_ = 0.29*2.54; + float _VESSEL_OUTER_WALL_THICKNESS_ = 0.54 * 2.54; + ; - double m_gas_volume_length = _FIDUCIAL_VOLUME_LENGTH_ - _VESSEL_FRONT_SIDE_THICKNESS_ - _SENSOR_AREA_LENGTH_; - double m_gas_volume_radius = _VESSEL_OUTER_RADIUS_ - _VESSEL_OUTER_WALL_THICKNESS_; + float _VESSEL_OUTER_RADIUS_ = 63.8; - float _FLANGE_CLEARANCE_ = 0.5; - float _BUILDING_BLOCK_CLEARANCE_ = 0.1; + double _VESSEL_FRONT_SIDE_THICKNESS_ = 0.29 * 2.54; - const int _AEROGEL_BAND_COUNT_ = 3; + double m_gas_volume_length = + _FIDUCIAL_VOLUME_LENGTH_ - _VESSEL_FRONT_SIDE_THICKNESS_ - _SENSOR_AREA_LENGTH_; + double m_gas_volume_radius = _VESSEL_OUTER_RADIUS_ - _VESSEL_OUTER_WALL_THICKNESS_; - float _AEROGEL_SEPARATOR_WALL_THICKNESS_ = 0.05; + float _FLANGE_CLEARANCE_ = 0.5; + float _BUILDING_BLOCK_CLEARANCE_ = 0.1; - float _AEROGEL_OUTER_WALL_THICKNESS_ = 0.1; + const int _AEROGEL_BAND_COUNT_ = 3; - float m_r0min = _FLANGE_EPIPE_DIAMETER_/2 + _FLANGE_CLEARANCE_ + _VESSEL_INNER_WALL_THICKNESS_ + _BUILDING_BLOCK_CLEARANCE_; - float m_r0max = m_gas_volume_radius - _BUILDING_BLOCK_CLEARANCE_; + float _AEROGEL_SEPARATOR_WALL_THICKNESS_ = 0.05; - const unsigned adim[_AEROGEL_BAND_COUNT_] = {9, 14, 20}; - double rheight = (m_r0max - m_r0min - (_AEROGEL_BAND_COUNT_-1)*_AEROGEL_SEPARATOR_WALL_THICKNESS_ - - _AEROGEL_INNER_WALL_THICKNESS_ - _AEROGEL_OUTER_WALL_THICKNESS_) / _AEROGEL_BAND_COUNT_; + float _AEROGEL_OUTER_WALL_THICKNESS_ = 0.1; - double agthick = 2.5; // cm + float m_r0min = _FLANGE_EPIPE_DIAMETER_ / 2 + _FLANGE_CLEARANCE_ + _VESSEL_INNER_WALL_THICKNESS_ + + _BUILDING_BLOCK_CLEARANCE_; + float m_r0max = m_gas_volume_radius - _BUILDING_BLOCK_CLEARANCE_; - double m_gzOffset = m_gas_volume_length/2 + _BUILDING_BLOCK_CLEARANCE_ + agthick/2; + const unsigned adim[_AEROGEL_BAND_COUNT_] = {9, 14, 20}; + double rheight = + (m_r0max - m_r0min - (_AEROGEL_BAND_COUNT_ - 1) * _AEROGEL_SEPARATOR_WALL_THICKNESS_ - + _AEROGEL_INNER_WALL_THICKNESS_ - _AEROGEL_OUTER_WALL_THICKNESS_) / + _AEROGEL_BAND_COUNT_; - string aerogel_name = "a1040"; + double agthick = 2.5; // cm - int kkcounter = 0; + double m_gzOffset = m_gas_volume_length / 2 + _BUILDING_BLOCK_CLEARANCE_ + agthick / 2; - for(unsigned ir=0; ir<_AEROGEL_BAND_COUNT_; ir++) { - int counter = ir ? -1 : 0; - double apitch = 360*degree / adim[ir]; - double aerogel_r0 = m_r0min + _AEROGEL_INNER_WALL_THICKNESS_ + ir*(_AEROGEL_SEPARATOR_WALL_THICKNESS_ + rheight); - double aerogel_r1 = aerogel_r0 + rheight; - double rm = (aerogel_r0+aerogel_r1)/2; + string aerogel_name = "a1040"; - // Calculate angular space occupied by the spacers and by the tiles; no gas gaps for now; - // assume that a wegde shape is good enough (GEANT visualization does not like boolean objects), - // rather than creating constant thicjkess azimuthal spacers; just assume that spacer thickness is - // _AEROGEL_FRAME_WALL_THICKNESS_ at r=rm; - double l0 = 2*M_PI*rm/adim[ir]; - double l1 = _AEROGEL_SEPARATOR_WALL_THICKNESS_; - double lsum = l0 + l1; + int kkcounter = 0; - // FIXME: names overlap in several places!; - double wd0 = (l0/lsum)*(360*degree / adim[ir]); - double wd1 = (l1/lsum)*(360*degree / adim[ir]); - TString ag_name = "Tmp", sp_name = "Tmp"; + for (unsigned ir = 0; ir < _AEROGEL_BAND_COUNT_; ir++) { + int counter = ir ? -1 : 0; + double apitch = 360 * degree / adim[ir]; + double aerogel_r0 = m_r0min + _AEROGEL_INNER_WALL_THICKNESS_ + + ir * (_AEROGEL_SEPARATOR_WALL_THICKNESS_ + rheight); + double aerogel_r1 = aerogel_r0 + rheight; + double rm = (aerogel_r0 + aerogel_r1) / 2; - if (ir) ag_name.Form("%s-%d-00", aerogel_name.c_str(), ir); - if (ir) sp_name.Form("A-Spacer--%d-00", ir); + // Calculate angular space occupied by the spacers and by the tiles; no gas gaps for now; + // assume that a wegde shape is good enough (GEANT visualization does not like boolean objects), + // rather than creating constant thicjkess azimuthal spacers; just assume that spacer thickness is + // _AEROGEL_FRAME_WALL_THICKNESS_ at r=rm; + double l0 = 2 * M_PI * rm / adim[ir]; + double l1 = _AEROGEL_SEPARATOR_WALL_THICKNESS_; + double lsum = l0 + l1; - Tube agtube(aerogel_r0, aerogel_r1, agthick/2, 0*degree, wd0); - Tube sptube(aerogel_r0, aerogel_r1, agthick/2, wd0, wd0 + wd1); + // FIXME: names overlap in several places!; + double wd0 = (l0 / lsum) * (360 * degree / adim[ir]); + double wd1 = (l1 / lsum) * (360 * degree / adim[ir]); + TString ag_name = "Tmp", sp_name = "Tmp"; - for(unsigned ia=0; iathickness(); + double l_thick = layering.layer(l_num - 1)->thickness(); // std::cout << "xc = " << xc << "\n"; - 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); + 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 sensitives; - int s_num = 1; + 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); + 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; @@ -91,13 +90,13 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s 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); + 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); + DetElement comp_elt(layer_elt, sens_pv.volume().name(), l_num); comp_elt.setPlacement(sens_pv); } layerZ += l_thick / 2; @@ -106,19 +105,21 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s ++layerType; } - double z_pos = zmin + totalThickness / 2; + double z_pos = zmin + totalThickness / 2; PlacedVolume pv; // Reflect it. - Assembly assembly(det_name); + Assembly assembly(det_name); DetElement endcapAssyDE(det_name, det_id); - Volume motherVol = description.pickMotherVolume(endcapAssyDE); + Volume motherVol = description.pickMotherVolume(endcapAssyDE); if (reflect) { - pv = assembly.placeVolume(endcapVol, Transform3D(RotationZYX(M_PI / numsides, M_PI, 0), Position(0, 0, -z_pos))); + pv = assembly.placeVolume( + endcapVol, Transform3D(RotationZYX(M_PI / numsides, M_PI, 0), Position(0, 0, -z_pos))); pv.addPhysVolID("barrel", 2); Ref_t(endcap)->SetName((det_name + "_backward").c_str()); endcap.setPlacement(pv); } else { - pv = assembly.placeVolume(endcapVol, Transform3D(RotationZYX(M_PI / numsides, 0, 0), Position(0, 0, z_pos))); + pv = assembly.placeVolume( + endcapVol, Transform3D(RotationZYX(M_PI / numsides, 0, 0), Position(0, 0, z_pos))); pv.addPhysVolID("barrel", 1); Ref_t(endcap)->SetName((det_name + "_forward").c_str()); endcap.setPlacement(pv); diff --git a/src/ScFiCalorimeter_geo.cpp b/src/ScFiCalorimeter_geo.cpp index 6c9daca7b..e1823a0e9 100644 --- a/src/ScFiCalorimeter_geo.cpp +++ b/src/ScFiCalorimeter_geo.cpp @@ -21,12 +21,11 @@ using namespace dd4hep; using Point = ROOT::Math::XYPoint; -std::tuple build_module(const Detector& desc, const xml::Component& mod_x, SensitiveDetector& sens); +std::tuple build_module(const Detector& desc, const xml::Component& mod_x, + SensitiveDetector& sens); // helper function to get x, y, z if defined in a xml component -template -Position get_xml_xyz(const XmlComp& comp, dd4hep::xml::Strng_t name) -{ +template Position get_xml_xyz(const XmlComp& comp, dd4hep::xml::Strng_t name) { Position pos(0., 0., 0.); if (comp.hasChild(name)) { auto child = comp.child(name); @@ -38,12 +37,11 @@ Position get_xml_xyz(const XmlComp& comp, dd4hep::xml::Strng_t name) } // main -static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDetector sens) { xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - DetElement det(detName, detID); + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + DetElement det(detName, detID); sens.setType("calorimeter"); auto dim = detElem.dimensions(); auto rmin = dim.rmin(); @@ -52,21 +50,21 @@ static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDete auto phimin = dd4hep::getAttrOrDefault(dim, _Unicode(phimin), 0.); auto phimax = dd4hep::getAttrOrDefault(dim, _Unicode(phimax), 2. * M_PI); // envelope - Tube envShape(rmin, rmax, length / 2., phimin, phimax); + Tube envShape(rmin, rmax, length / 2., phimin, phimax); Volume env(detName + "_envelope", envShape, desc.material("Air")); env.setVisAttributes(desc.visAttributes(detElem.visStr())); // build module - auto [modVol, modSize] = build_module(desc, detElem.child(_Unicode(module)), sens); - double modSizeR = std::sqrt(modSize.x() * modSize.x() + modSize.y() * modSize.y()); - double assembly_rwidth = modSizeR * 2.; - int nas = int((rmax - rmin) / assembly_rwidth) + 1; + auto [modVol, modSize] = build_module(desc, detElem.child(_Unicode(module)), sens); + double modSizeR = std::sqrt(modSize.x() * modSize.x() + modSize.y() * modSize.y()); + double assembly_rwidth = modSizeR * 2.; + int nas = int((rmax - rmin) / assembly_rwidth) + 1; std::vector assemblies; // calorimeter block z-offsets (as blocks are shorter than the volume length) const double block_offset = -0.5 * (length - modSize.z()); for (int i = 0; i < nas; ++i) { Assembly assembly(detName + Form("_ring%d", i + 1)); - auto assemblyPV = env.placeVolume(assembly, Position{0., 0., block_offset}); + auto assemblyPV = env.placeVolume(assembly, Position{0., 0., block_offset}); assemblyPV.addPhysVolID("ring", i + 1); assemblies.emplace_back(std::move(assembly)); } @@ -79,9 +77,9 @@ static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDete double my = modSize.y() * iy - rmax; double mr = std::sqrt(mx * mx + my * my); if (mr - modSizeR >= rmin && mr + modSizeR <= rmax) { - int ias = int((mr - rmin) / assembly_rwidth); + int ias = int((mr - rmin) / assembly_rwidth); auto& assembly = assemblies[ias]; - auto modPV = assembly.placeVolume(modVol, Position(mx, my, 0.)); + auto modPV = assembly.placeVolume(modVol, Position(mx, my, 0.)); modPV.addPhysVolID("module", modid++); } } @@ -94,38 +92,39 @@ static Ref_t create_detector(Detector& desc, xml::Handle_t handle, SensitiveDete } // detector position and rotation - auto pos = get_xml_xyz(detElem, _Unicode(position)); - auto rot = get_xml_xyz(detElem, _Unicode(rotation)); - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr = Translation3D(pos.x(), pos.y(), pos.z()) * RotationZYX(rot.z(), rot.y(), rot.x()); - PlacedVolume envPV = motherVol.placeVolume(env, tr); + auto pos = get_xml_xyz(detElem, _Unicode(position)); + auto rot = get_xml_xyz(detElem, _Unicode(rotation)); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr = + Translation3D(pos.x(), pos.y(), pos.z()) * RotationZYX(rot.z(), rot.y(), rot.x()); + PlacedVolume envPV = motherVol.placeVolume(env, tr); envPV.addPhysVolID("system", detID); det.setPlacement(envPV); return det; } // helper function to build module with scintillating fibers -std::tuple build_module(const Detector& desc, const xml::Component& mod_x, SensitiveDetector& sens) -{ +std::tuple build_module(const Detector& desc, const xml::Component& mod_x, + SensitiveDetector& sens) { auto sx = mod_x.attr(_Unicode(sizex)); auto sy = mod_x.attr(_Unicode(sizey)); auto sz = mod_x.attr(_Unicode(sizez)); - Box modShape(sx / 2., sy / 2., sz / 2.); - auto modMat = desc.material(mod_x.attr(_Unicode(material))); + Box modShape(sx / 2., sy / 2., sz / 2.); + auto modMat = desc.material(mod_x.attr(_Unicode(material))); Volume modVol("module_vol", modShape, modMat); if (mod_x.hasAttr(_Unicode(vis))) { modVol.setVisAttributes(desc.visAttributes(mod_x.attr(_Unicode(vis)))); } if (mod_x.hasChild(_Unicode(fiber))) { - auto fiber_x = mod_x.child(_Unicode(fiber)); - auto fr = fiber_x.attr(_Unicode(radius)); - auto fsx = fiber_x.attr(_Unicode(spacex)); - auto fsy = fiber_x.attr(_Unicode(spacey)); - auto foff = dd4hep::getAttrOrDefault(fiber_x, _Unicode(offset), 0.5 * mm); - auto fiberMat = desc.material(fiber_x.attr(_Unicode(material))); - Tube fiberShape(0., fr, sz / 2.); + auto fiber_x = mod_x.child(_Unicode(fiber)); + auto fr = fiber_x.attr(_Unicode(radius)); + auto fsx = fiber_x.attr(_Unicode(spacex)); + auto fsy = fiber_x.attr(_Unicode(spacey)); + auto foff = dd4hep::getAttrOrDefault(fiber_x, _Unicode(offset), 0.5 * mm); + auto fiberMat = desc.material(fiber_x.attr(_Unicode(material))); + Tube fiberShape(0., fr, sz / 2.); Volume fiberVol("fiber_vol", fiberShape, fiberMat); fiberVol.setSensitiveDetector(sens); @@ -156,8 +155,8 @@ std::tuple build_module(const Detector& desc, const xml::Compo // std::cout << sx << ", " << sy << ", " << fr << ", " << nx << ", " << ny << std::endl; // place the fibers - double y0 = (foff + fside); - int nfibers = 0; + double y0 = (foff + fside); + int nfibers = 0; for (int iy = 0; iy < ny; ++iy) { double y = y0 + fdisty * iy; // about to touch the boundary @@ -171,7 +170,8 @@ std::tuple build_module(const Detector& desc, const xml::Compo if ((sx - x) < x0) { break; } - auto fiberPV = modVol.placeVolume(fiberVol, nfibers++, Position{x - sx / 2., y - sy / 2., 0}); + auto fiberPV = + modVol.placeVolume(fiberVol, nfibers++, Position{x - sx / 2., y - sy / 2., 0}); // std::cout << "(" << ix << ", " << iy << ", " << x - sx/2. << ", " << y - sy/2. << ", " << fr << "),\n"; fiberPV.addPhysVolID("fiber_x", ix + 1).addPhysVolID("fiber_y", iy + 1); } diff --git a/src/SimpleDiskDetector_geo.cpp b/src/SimpleDiskDetector_geo.cpp index 4e3b36b8e..49dc02e2d 100644 --- a/src/SimpleDiskDetector_geo.cpp +++ b/src/SimpleDiskDetector_geo.cpp @@ -23,35 +23,35 @@ using namespace std; using namespace dd4hep; using namespace dd4hep::detail; -static Ref_t SimpleDiskDetector_create_detector(Detector& description, xml_h e, SensitiveDetector sens) -{ - xml_det_t x_det = e; - Material air = description.air(); - string det_name = x_det.nameStr(); - bool reflect = x_det.reflect(); - DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name); - PlacedVolume pv; - int l_num = 0; - xml::Component pos = x_det.position(); +static Ref_t SimpleDiskDetector_create_detector(Detector& description, xml_h e, + SensitiveDetector sens) { + xml_det_t x_det = e; + Material air = description.air(); + string det_name = x_det.nameStr(); + bool reflect = x_det.reflect(); + DetElement sdet(det_name, x_det.id()); + Assembly assembly(det_name); + PlacedVolume pv; + int l_num = 0; + xml::Component pos = x_det.position(); for (xml_coll_t i(x_det, _U(layer)); i; ++i, ++l_num) { - xml_comp_t x_layer = i; - string l_nam = det_name + _toString(l_num, "_layer%d"); - double zmin = x_layer.inner_z(); - double rmin = x_layer.inner_r(); - double rmax = x_layer.outer_r(); - double layerWidth = 0.; - int s_num = 0; + xml_comp_t x_layer = i; + string l_nam = det_name + _toString(l_num, "_layer%d"); + double zmin = x_layer.inner_z(); + double rmin = x_layer.inner_r(); + double rmax = x_layer.outer_r(); + double layerWidth = 0.; + int s_num = 0; for (xml_coll_t j(x_layer, _U(slice)); j; ++j) { double thickness = xml_comp_t(j).thickness(); layerWidth += thickness; } - Tube l_tub(rmin, rmax, layerWidth / 2.0, 2 * M_PI); + Tube l_tub(rmin, rmax, layerWidth / 2.0, 2 * M_PI); Volume l_vol(l_nam, l_tub, air); l_vol.setVisAttributes(description, x_layer.visStr()); - DetElement layer; + DetElement layer; PlacedVolume layer_pv; if (!reflect) { layer = DetElement(sdet, l_nam + "_pos", l_num); @@ -60,7 +60,8 @@ static Ref_t SimpleDiskDetector_create_detector(Detector& description, xml_h e, layer.setPlacement(layer_pv); } else { layer = DetElement(sdet, l_nam + "_neg", l_num); - layer_pv = assembly.placeVolume(l_vol, Transform3D(RotationY(M_PI), Position(0, 0, -zmin - layerWidth / 2))); + layer_pv = assembly.placeVolume( + l_vol, Transform3D(RotationY(M_PI), Position(0, 0, -zmin - layerWidth / 2))); layer_pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_num); layer.setPlacement(layer_pv); // DetElement layerR = layer.clone(l_nam+"_neg"); @@ -70,10 +71,10 @@ static Ref_t SimpleDiskDetector_create_detector(Detector& description, xml_h e, double tot_thickness = -layerWidth / 2.0; for (xml_coll_t j(x_layer, _U(slice)); j; ++j, ++s_num) { xml_comp_t x_slice = j; - double thick = x_slice.thickness(); - Material mat = description.material(x_slice.materialStr()); - string s_nam = l_nam + _toString(s_num, "_slice%d"); - Volume s_vol(s_nam, Tube(rmin, rmax, thick / 2.0), mat); + double thick = x_slice.thickness(); + Material mat = description.material(x_slice.materialStr()); + string s_nam = l_nam + _toString(s_num, "_slice%d"); + Volume s_vol(s_nam, Tube(rmin, rmax, thick / 2.0), mat); if (!reflect) { s_nam += "_pos"; } else { @@ -94,7 +95,8 @@ static Ref_t SimpleDiskDetector_create_detector(Detector& description, xml_h e, if (x_det.hasAttr(_U(combineHits))) { sdet.setCombineHits(x_det.attr(_U(combineHits)), sens); } - pv = description.pickMotherVolume(sdet).placeVolume(assembly, Position(pos.x(), pos.y(), pos.z())); + pv = + description.pickMotherVolume(sdet).placeVolume(assembly, Position(pos.x(), pos.y(), pos.z())); pv.addPhysVolID("system", x_det.id()); // Set the subdetector system ID. sdet.setPlacement(pv); return sdet; diff --git a/src/Solenoid_geo.cpp b/src/Solenoid_geo.cpp index c8fcf86d8..4e49f8136 100644 --- a/src/Solenoid_geo.cpp +++ b/src/Solenoid_geo.cpp @@ -23,40 +23,43 @@ using namespace std; using namespace dd4hep; using namespace dd4hep::detail; -static Ref_t create_detector(Detector& description, xml_h e, [[maybe_unused]] SensitiveDetector sens) -{ - xml_det_t x_det = e; - string det_name = x_det.nameStr(); - Material air = description.air(); - DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); +static Ref_t create_detector(Detector& description, xml_h e, + [[maybe_unused]] SensitiveDetector sens) { + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + Material air = description.air(); + DetElement sdet(det_name, x_det.id()); + Assembly assembly(det_name + "_assembly"); PlacedVolume pv; int i_layer = 0; for (xml_coll_t l_iter(x_det, _U(layer)); l_iter; ++l_iter, ++i_layer) { xml_comp_t x_layer = l_iter; - string l_name = getAttrOrDefault(x_layer, _U(name), det_name + _toString(i_layer, "_layer%d")); - double outer_z = x_layer.outer_z(); - double inner_r = x_layer.inner_r(); - double outer_r = inner_r; + string l_name = + getAttrOrDefault(x_layer, _U(name), det_name + _toString(i_layer, "_layer%d")); + double outer_z = x_layer.outer_z(); + double inner_r = x_layer.inner_r(); + double outer_r = inner_r; DetElement layer(sdet, _toString(i_layer, "layer%d"), x_layer.id()); - Tube l_tub(inner_r, 2 * inner_r, outer_z); // outer_r will be updated - Volume l_vol(l_name, l_tub, air); + Tube l_tub(inner_r, 2 * inner_r, outer_z); // outer_r will be updated + Volume l_vol(l_name, l_tub, air); - int i_slice = 0; + int i_slice = 0; double l_thickness = 0.0; for (xml_coll_t s_iter(x_layer, _U(slice)); s_iter; ++s_iter, ++i_slice) { // If slices are only given a thickness attribute, they are radially concentric slices // If slices are given an inner_z attribute, they are longitudinal slices with equal rmin - xml_comp_t x_slice = s_iter; - Material mat = description.material(x_slice.materialStr()); - string s_name = getAttrOrDefault(x_slice, _U(name), l_name + _toString(i_slice, "_slice%d")); - double thickness = x_slice.thickness(); + xml_comp_t x_slice = s_iter; + Material mat = description.material(x_slice.materialStr()); + string s_name = + getAttrOrDefault(x_slice, _U(name), l_name + _toString(i_slice, "_slice%d")); + double thickness = x_slice.thickness(); if (thickness > l_thickness) l_thickness = thickness; double s_outer_z = dd4hep::getAttrOrDefault(x_slice, _Unicode(outer_z), outer_z); double s_inner_z = dd4hep::getAttrOrDefault(x_slice, _Unicode(inner_z), 0.0 * cm); - Tube s_tub(inner_r, inner_r + thickness, (s_inner_z > 0 ? 0.5 * (s_outer_z - s_inner_z) : s_outer_z)); + Tube s_tub(inner_r, inner_r + thickness, + (s_inner_z > 0 ? 0.5 * (s_outer_z - s_inner_z) : s_outer_z)); Volume s_vol(s_name, s_tub, mat); s_vol.setAttributes(description, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); @@ -82,7 +85,7 @@ static Ref_t create_detector(Detector& description, xml_h e, [[maybe_unused]] Se // Get position and place volume xml::Component x_pos = x_det.position(); - Position pos(x_pos.x(), x_pos.y(), x_pos.z()); + Position pos(x_pos.x(), x_pos.y(), x_pos.z()); pv = description.pickMotherVolume(sdet).placeVolume(assembly, pos); pv.addPhysVolID("system", sdet.id()).addPhysVolID("barrel", 0); sdet.setPlacement(pv); diff --git a/src/SupportServiceMaterial_geo.cpp b/src/SupportServiceMaterial_geo.cpp index 516519ad7..c476f888c 100644 --- a/src/SupportServiceMaterial_geo.cpp +++ b/src/SupportServiceMaterial_geo.cpp @@ -21,93 +21,93 @@ using namespace std; using namespace dd4hep; namespace { - std::pair build_shape(const Detector& descr, const xml_det_t& x_det, const xml_comp_t& x_support, - const xml_comp_t& x_child, const double offset = 0) - { - // Get Initial rotation/translation info - xml_dim_t x_pos(x_child.child(_U(position), false)); - xml_dim_t x_rot(x_child.child(_U(rotation), false)); - Position pos3D{0, 0, 0}; - Rotation3D rot3D; +std::pair build_shape(const Detector& descr, const xml_det_t& x_det, + const xml_comp_t& x_support, const xml_comp_t& x_child, + const double offset = 0) { + // Get Initial rotation/translation info + xml_dim_t x_pos(x_child.child(_U(position), false)); + xml_dim_t x_rot(x_child.child(_U(rotation), false)); + Position pos3D{0, 0, 0}; + Rotation3D rot3D; - if (x_rot) { - rot3D = RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)); - } - if (x_pos) { - pos3D = Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)); - } + if (x_rot) { + rot3D = RotationZYX(x_rot.z(0), x_rot.y(0), x_rot.x(0)); + } + if (x_pos) { + pos3D = Position(x_pos.x(0), x_pos.y(0), x_pos.z(0)); + } - // handle different known shapes and create solids - Solid solid; - const std::string type = x_support.attr(_U(type)); - if (type == "Tube" || type == "Cylinder") { - const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); - const double length = getAttrOrDefault(x_child, _U(length), x_support.length()); - const double rmin = getAttrOrDefault(x_child, _U(rmin), x_support.rmin()) + offset; - solid = Tube(rmin, rmin + thickness, length / 2); - } - // A disk is a cylinder, constructed differently - else if (type == "Disk") { - const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); - const double rmin = getAttrOrDefault(x_child, _U(rmin), x_support.rmin()); - const double rmax = getAttrOrDefault(x_child, _U(rmax), x_support.rmax()); - pos3D = pos3D + Position(0, 0, -x_support.thickness() / 2 + thickness / 2 + offset); - solid = Tube(rmin, rmax, thickness / 2); - } else if (type == "Cone") { - const double base_rmin1 = getAttrOrDefault(x_child, _U(rmin1), x_support.rmin1()); - const double base_rmin2 = getAttrOrDefault(x_child, _U(rmin2), x_support.rmin2()); - const double length = getAttrOrDefault(x_child, _U(length), x_support.length()); - // Account for the fact that the distance between base_rmin1 and rmax2 is the projection - // of the thickness on the transverse direction - const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); - const double transverse_thickness = thickness / cos(atan2(fabs(base_rmin2 - base_rmin1), length)); - // also account that the same is true for the offset - const double transverse_offset = offset / cos(atan2(fabs(base_rmin2 - base_rmin1), length)); - const double rmin1 = base_rmin1 + transverse_offset; - const double rmin2 = base_rmin2 + transverse_offset; - const double rmax1 = rmin1 + transverse_thickness; - const double rmax2 = rmin2 + transverse_thickness; - solid = Cone(length / 2, rmin1, rmax1, rmin2, rmax2); - } else { - printout(ERROR, x_det.nameStr(), "Unknown support type: %s", type.c_str()); - std::exit(1); - } - // Materials - Material mat = descr.material(getAttrOrDefault(x_child, _U(material), "Air")); - // Create our volume - Volume vol{getAttrOrDefault(x_child, _U(name), "support_vol"), solid, mat}; + // handle different known shapes and create solids + Solid solid; + const std::string type = x_support.attr(_U(type)); + if (type == "Tube" || type == "Cylinder") { + const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); + const double length = getAttrOrDefault(x_child, _U(length), x_support.length()); + const double rmin = getAttrOrDefault(x_child, _U(rmin), x_support.rmin()) + offset; + solid = Tube(rmin, rmin + thickness, length / 2); + } + // A disk is a cylinder, constructed differently + else if (type == "Disk") { + const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); + const double rmin = getAttrOrDefault(x_child, _U(rmin), x_support.rmin()); + const double rmax = getAttrOrDefault(x_child, _U(rmax), x_support.rmax()); + pos3D = pos3D + Position(0, 0, -x_support.thickness() / 2 + thickness / 2 + offset); + solid = Tube(rmin, rmax, thickness / 2); + } else if (type == "Cone") { + const double base_rmin1 = getAttrOrDefault(x_child, _U(rmin1), x_support.rmin1()); + const double base_rmin2 = getAttrOrDefault(x_child, _U(rmin2), x_support.rmin2()); + const double length = getAttrOrDefault(x_child, _U(length), x_support.length()); + // Account for the fact that the distance between base_rmin1 and rmax2 is the projection + // of the thickness on the transverse direction + const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); + const double transverse_thickness = + thickness / cos(atan2(fabs(base_rmin2 - base_rmin1), length)); + // also account that the same is true for the offset + const double transverse_offset = offset / cos(atan2(fabs(base_rmin2 - base_rmin1), length)); + const double rmin1 = base_rmin1 + transverse_offset; + const double rmin2 = base_rmin2 + transverse_offset; + const double rmax1 = rmin1 + transverse_thickness; + const double rmax2 = rmin2 + transverse_thickness; + solid = Cone(length / 2, rmin1, rmax1, rmin2, rmax2); + } else { + printout(ERROR, x_det.nameStr(), "Unknown support type: %s", type.c_str()); + std::exit(1); + } + // Materials + Material mat = descr.material(getAttrOrDefault(x_child, _U(material), "Air")); + // Create our volume + Volume vol{getAttrOrDefault(x_child, _U(name), "support_vol"), solid, mat}; - // Create full transformation - Transform3D tr(rot3D, pos3D); + // Create full transformation + Transform3D tr(rot3D, pos3D); - // visualization? - if (x_child.hasAttr(_U(vis))) { - vol.setVisAttributes(descr.visAttributes(x_child.visStr())); - } - return {vol, tr}; - } - std::pair build_shape(const Detector& descr, const xml_det_t& x_det, const xml_comp_t& x_support, - const double offset = 0) - { - return build_shape(descr, x_det, x_support, x_support, offset); + // visualization? + if (x_child.hasAttr(_U(vis))) { + vol.setVisAttributes(descr.visAttributes(x_child.visStr())); } + return {vol, tr}; +} +std::pair build_shape(const Detector& descr, const xml_det_t& x_det, + const xml_comp_t& x_support, const double offset = 0) { + return build_shape(descr, x_det, x_support, x_support, offset); +} } // namespace /** Generic tracker support implementation, can consist of arbitrary shapes * * @author Sylvester Joosten */ -static Ref_t create_SupportServiceMaterial(Detector& description, xml_h e, [[maybe_unused]] SensitiveDetector sens) -{ - const xml_det_t x_det = e; - const int det_id = x_det.id(); - const string det_name = x_det.nameStr(); +static Ref_t create_SupportServiceMaterial(Detector& description, xml_h e, + [[maybe_unused]] SensitiveDetector sens) { + const xml_det_t x_det = e; + const int det_id = x_det.id(); + const string det_name = x_det.nameStr(); // global z-offset for the entire support assembly const double offset = getAttrOrDefault(x_det, _U(offset), 0.); DetElement det(det_name, det_id); - Assembly assembly(det_name + "_assembly"); + Assembly assembly(det_name + "_assembly"); // Loop over the supports for (xml_coll_t su{x_det, _U(support)}; su; ++su) { @@ -125,8 +125,8 @@ static Ref_t create_SupportServiceMaterial(Detector& description, xml_h e, [[may } // final placement - Volume motherVol = description.pickMotherVolume(det); - Position pos(0, 0, offset); + Volume motherVol = description.pickMotherVolume(det); + Position pos(0, 0, offset); PlacedVolume pv = motherVol.placeVolume(assembly, pos); pv.addPhysVolID("system", det.id()); det.setPlacement(pv); diff --git a/src/TaggerCalWSi_geo.cpp b/src/TaggerCalWSi_geo.cpp index 31dcfff60..201c2066f 100644 --- a/src/TaggerCalWSi_geo.cpp +++ b/src/TaggerCalWSi_geo.cpp @@ -15,16 +15,15 @@ using namespace std; using namespace dd4hep; -static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) -{ - xml_det_t x_det = e; - string detName = x_det.nameStr(); - int detID = x_det.id(); +static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + string detName = x_det.nameStr(); + int detID = x_det.id(); - xml_dim_t dim = x_det.dimensions(); - double Width = dim.x(); - double Height = dim.y(); - double Thickness = dim.z() / 2; + xml_dim_t dim = x_det.dimensions(); + double Width = dim.x(); + double Height = dim.y(); + double Thickness = dim.z() / 2; xml_dim_t pos = x_det.position(); // xml_dim_t rot = x_det.rotation(); @@ -36,7 +35,7 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) sens.setType("calorimeter"); // Create Global Volume - Box Tagger_Box(Width, Height, Thickness); + Box Tagger_Box(Width, Height, Thickness); Volume detVol("Tagger_Box", Tagger_Box, Vacuum); detVol.setVisAttributes(desc.visAttributes(x_det.visStr())); @@ -48,30 +47,30 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) for (int i = 0; i < 20; i++) { // absorber - Box Abso_Box(Width, Height, abso_z / 2); + Box Abso_Box(Width, Height, abso_z / 2); Volume absoVol("AbsorberVolume", Abso_Box, Absorber); absoVol.setVisAttributes(desc.visAttributes("BlueVis")); detVol.placeVolume(absoVol, Position(0, 0, Thickness - (i) * (abso_z + sens_z) - abso_z / 2)); // sensitive layer - Box Cal_Box(Width, Height, sens_z / 2); + Box Cal_Box(Width, Height, sens_z / 2); Volume calVol("SensVolume", Cal_Box, Silicon); calVol.setSensitiveDetector(sens); calVol.setVisAttributes(desc.visAttributes("RedVis")); - PlacedVolume pv_mod = - detVol.placeVolume(calVol, Position(0, 0, Thickness - (i) * (abso_z + sens_z) - abso_z - sens_z / 2)); + PlacedVolume pv_mod = detVol.placeVolume( + calVol, Position(0, 0, Thickness - (i) * (abso_z + sens_z) - abso_z - sens_z / 2)); pv_mod.addPhysVolID("layer", i + 3); // leave room for tracking IDs } // mother volume for calorimeter - std::string mother_nam = dd4hep::getAttrOrDefault(x_det, _Unicode(place_into), ""); - VolumeManager man = VolumeManager::getVolumeManager(desc); - DetElement mdet = man.detector().child(mother_nam); + std::string mother_nam = dd4hep::getAttrOrDefault(x_det, _Unicode(place_into), ""); + VolumeManager man = VolumeManager::getVolumeManager(desc); + DetElement mdet = man.detector().child(mother_nam); // placement in envelope - Transform3D tr(RotationZYX(0, 0, 0), Position(pos.x(), pos.y(), pos.z())); + Transform3D tr(RotationZYX(0, 0, 0), Position(pos.x(), pos.y(), pos.z())); PlacedVolume detPV = mdet.volume().placeVolume(detVol, tr); detPV.addPhysVolID("system", detID); DetElement det(detName, detID); diff --git a/src/TrapEndcapTracker_geo.cpp b/src/TrapEndcapTracker_geo.cpp index 1872dd698..9cb9139d3 100644 --- a/src/TrapEndcapTracker_geo.cpp +++ b/src/TrapEndcapTracker_geo.cpp @@ -30,64 +30,64 @@ using namespace dd4hep::detail; * @author Whitney Armstrong * */ -static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { typedef vector Placements; - xml_det_t x_det = e; - Material vacuum = description.vacuum(); - int det_id = x_det.id(); - string det_name = x_det.nameStr(); - bool reflect = x_det.reflect(false); - DetElement sdet(det_name, det_id); - Assembly assembly(det_name); - - Material air = description.material("Air"); - Volume motherVol = description.pickMotherVolume(sdet); - int m_id = 0, c_id = 0, n_sensor = 0; - map modules; - map sensitives; + xml_det_t x_det = e; + Material vacuum = description.vacuum(); + int det_id = x_det.id(); + string det_name = x_det.nameStr(); + bool reflect = x_det.reflect(false); + DetElement sdet(det_name, det_id); + Assembly assembly(det_name); + + Material air = description.material("Air"); + Volume motherVol = description.pickMotherVolume(sdet); + int m_id = 0, c_id = 0, n_sensor = 0; + map modules; + map sensitives; map> volplane_surfaces; map> module_thicknesses; - PlacedVolume pv; + PlacedVolume pv; // Set detector type flag dd4hep::xml::setDetectorTypeFlag(x_det, sdet); - auto ¶ms = DD4hepDetectorHelper::ensureExtension( - sdet); + auto& params = DD4hepDetectorHelper::ensureExtension(sdet); // Add the volume boundary material if configured for (xml_coll_t bmat(x_det, _Unicode(boundary_material)); bmat; ++bmat) { xml_comp_t x_boundary_material = bmat; DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_boundary_material, params, - "boundary_material"); + "boundary_material"); } assembly.setVisAttributes(description.invisible()); sens.setType("tracker"); for (xml_coll_t su(x_det, _U(support)); su; ++su) { - xml_comp_t x_support = su; - double support_thickness = getAttrOrDefault(x_support, _U(thickness), 2.0 * mm); - double support_length = getAttrOrDefault(x_support, _U(length), 2.0 * mm); - double support_rmin = getAttrOrDefault(x_support, _U(rmin), 2.0 * mm); - double support_zstart = getAttrOrDefault(x_support, _U(zstart), 2.0 * mm); - std::string support_name = getAttrOrDefault(x_support, _Unicode(name), "support_tube"); - std::string support_vis = getAttrOrDefault(x_support, _Unicode(vis), "AnlRed"); - xml_dim_t pos(x_support.child(_U(position), false)); - xml_dim_t rot(x_support.child(_U(rotation), false)); - Solid support_solid; + xml_comp_t x_support = su; + double support_thickness = getAttrOrDefault(x_support, _U(thickness), 2.0 * mm); + double support_length = getAttrOrDefault(x_support, _U(length), 2.0 * mm); + double support_rmin = getAttrOrDefault(x_support, _U(rmin), 2.0 * mm); + double support_zstart = getAttrOrDefault(x_support, _U(zstart), 2.0 * mm); + std::string support_name = + getAttrOrDefault(x_support, _Unicode(name), "support_tube"); + std::string support_vis = getAttrOrDefault(x_support, _Unicode(vis), "AnlRed"); + xml_dim_t pos(x_support.child(_U(position), false)); + xml_dim_t rot(x_support.child(_U(rotation), false)); + Solid support_solid; if (x_support.hasChild(_U(shape))) { xml_comp_t shape(x_support.child(_U(shape))); - string shape_type = shape.typeStr(); - support_solid = xml::createShape(description, shape_type, shape); + string shape_type = shape.typeStr(); + support_solid = xml::createShape(description, shape_type, shape); } else { support_solid = Tube(support_rmin, support_rmin + support_thickness, support_length / 2); } Transform3D tr = - Transform3D(Rotation3D(), Position(0, 0, (reflect ? -1.0 : 1.0) * (support_zstart + support_length / 2))); + Transform3D(Rotation3D(), + Position(0, 0, (reflect ? -1.0 : 1.0) * (support_zstart + support_length / 2))); if (pos.ptr() && rot.ptr()) { Rotation3D rot3D(RotationZYX(rot.z(0), rot.y(0), rot.x(0))); - Position pos3D(pos.x(0), pos.y(0), pos.z(0)); + Position pos3D(pos.x(0), pos.y(0), pos.z(0)); tr = Transform3D(rot3D, pos3D); } else if (pos.ptr()) { tr = Transform3D(Rotation3D(), Position(pos.x(0), pos.y(0), pos.z(0))); @@ -96,7 +96,7 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s tr = Transform3D(rot3D, Position()); } Material support_mat = description.material(x_support.materialStr()); - Volume support_vol(support_name, support_solid, support_mat); + Volume support_vol(support_name, support_solid, support_mat); support_vol.setVisAttributes(description.visAttributes(support_vis)); pv = assembly.placeVolume(support_vol, tr); // pv = assembly.placeVolume(support_vol, Position(0, 0, support_zstart + support_length / 2)); @@ -104,43 +104,43 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) { xml_comp_t x_mod = mi; - string m_nam = x_mod.nameStr(); + string m_nam = x_mod.nameStr(); xml_comp_t trd = x_mod.trd(); - double posY; - double x1 = trd.x1(); - double x2 = trd.x2(); - double z = trd.z(); - double total_thickness = 0.; + double posY; + double x1 = trd.x1(); + double x2 = trd.x2(); + double z = trd.z(); + double total_thickness = 0.; xml_coll_t ci(x_mod, _U(module_component)); for (ci.reset(), total_thickness = 0.0; ci; ++ci) total_thickness += xml_comp_t(ci).thickness(); - double thickness_so_far = 0.0; - double y1 = total_thickness / 2; - double y2 = total_thickness / 2; + double thickness_so_far = 0.0; + double y1 = total_thickness / 2; + double y2 = total_thickness / 2; Trapezoid m_solid(x1, x2, y1, y2, z); - Volume m_volume(m_nam, m_solid, vacuum); + Volume m_volume(m_nam, m_solid, vacuum); m_volume.setVisAttributes(description.visAttributes(x_mod.visStr())); Solid frame_s; if (x_mod.hasChild(_U(frame))) { // build frame from trd (assumed to be smaller) - xml_comp_t m_frame = x_mod.child(_U(frame)); - xml_comp_t f_pos = m_frame.child(_U(position)); - xml_comp_t frame_trd = m_frame.trd(); - double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); - double frame_x1 = frame_trd.x1(); - double frame_x2 = frame_trd.x2(); - double frame_z = frame_trd.z(); + xml_comp_t m_frame = x_mod.child(_U(frame)); + xml_comp_t f_pos = m_frame.child(_U(position)); + xml_comp_t frame_trd = m_frame.trd(); + double frame_thickness = getAttrOrDefault(m_frame, _U(thickness), total_thickness); + double frame_x1 = frame_trd.x1(); + double frame_x2 = frame_trd.x2(); + double frame_z = frame_trd.z(); // make the frame match the total thickness if thickness attribute is not given - Trapezoid f_solid1(x1, x2, frame_thickness / 2.0, frame_thickness / 2.0, z); - Trapezoid f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z); + Trapezoid f_solid1(x1, x2, frame_thickness / 2.0, frame_thickness / 2.0, z); + Trapezoid f_solid(frame_x1, frame_x2, frame_thickness / 2.0, frame_thickness / 2.0, frame_z); SubtractionSolid frame_shape(f_solid1, f_solid); frame_s = frame_shape; Material f_mat = description.material(m_frame.materialStr()); - Volume f_vol(m_nam + "_frame", frame_shape, f_mat); + Volume f_vol(m_nam + "_frame", frame_shape, f_mat); f_vol.setVisAttributes(description.visAttributes(m_frame.visStr())); // figure out how to best place @@ -148,17 +148,17 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s } for (ci.reset(), n_sensor = 1, c_id = 0, posY = -y1; ci; ++ci, ++c_id) { - xml_comp_t c = ci; - double c_thick = c.thickness(); - auto comp_x1 = getAttrOrDefault(c, _Unicode(x1), x1); - auto comp_x2 = getAttrOrDefault(c, _Unicode(x2), x2); - auto comp_height = getAttrOrDefault(c, _Unicode(height), z); + xml_comp_t c = ci; + double c_thick = c.thickness(); + auto comp_x1 = getAttrOrDefault(c, _Unicode(x1), x1); + auto comp_x2 = getAttrOrDefault(c, _Unicode(x2), x2); + auto comp_height = getAttrOrDefault(c, _Unicode(height), z); - Material c_mat = description.material(c.materialStr()); - string c_name = _toString(c_id, "component%d"); + Material c_mat = description.material(c.materialStr()); + string c_name = _toString(c_id, "component%d"); Trapezoid comp_s1(comp_x1, comp_x2, c_thick / 2e0, c_thick / 2e0, comp_height); - Solid comp_shape = comp_s1; + Solid comp_shape = comp_s1; if (frame_s.isValid()) { comp_shape = SubtractionSolid(comp_s1, frame_s); } @@ -170,7 +170,8 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s module_thicknesses[m_nam] = {thickness_so_far + c_thick / 2.0, total_thickness - thickness_so_far - c_thick / 2.0}; // std::cout << " adding sensitive volume" << c_name << "\n"; - sdet.check(n_sensor > 2, "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); + sdet.check(n_sensor > 2, + "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!"); pv.addPhysVolID("sensor", n_sensor); c_vol.setSensitiveDetector(sens); sensitives[m_nam].push_back(pv); @@ -204,32 +205,32 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s for (xml_coll_t li(x_det, _U(layer)); li; ++li) { xml_comp_t x_layer(li); - int l_id = x_layer.id(); - int mod_num = 1; - - xml_comp_t l_env = x_layer.child(_U(envelope)); - string layer_name = det_name + std::string("_layer") + std::to_string(l_id); - - std::string layer_vis = l_env.attr(_Unicode(vis)); - double layer_rmin = l_env.attr(_Unicode(rmin)); - double layer_rmax = l_env.attr(_Unicode(rmax)); - double layer_length = l_env.attr(_Unicode(length)); - double layer_zstart = l_env.attr(_Unicode(zstart)); - double layer_center_z = layer_zstart + layer_length / 2.0; + int l_id = x_layer.id(); + int mod_num = 1; + + xml_comp_t l_env = x_layer.child(_U(envelope)); + string layer_name = det_name + std::string("_layer") + std::to_string(l_id); + + std::string layer_vis = l_env.attr(_Unicode(vis)); + double layer_rmin = l_env.attr(_Unicode(rmin)); + double layer_rmax = l_env.attr(_Unicode(rmax)); + double layer_length = l_env.attr(_Unicode(length)); + double layer_zstart = l_env.attr(_Unicode(zstart)); + double layer_center_z = layer_zstart + layer_length / 2.0; // printout(INFO,"ROOTGDMLParse","+++ Read geometry from GDML file file:%s",input.c_str()); // std::cout << "SiTracker Endcap layer " << l_id << " zstart = " << layer_zstart/dd4hep::mm << "mm ( " << // layer_length/dd4hep::mm << " mm thick )\n"; // Assembly layer_assembly(layer_name); // assembly.placeVolume(layer_assembly); - Tube layer_tub(layer_rmin, layer_rmax, layer_length / 2); + Tube layer_tub(layer_rmin, layer_rmax, layer_length / 2); Volume layer_vol(layer_name, layer_tub, air); // Create the layer envelope volume. layer_vol.setVisAttributes(description.visAttributes(layer_vis)); PlacedVolume layer_pv; if (reflect) { - layer_pv = - assembly.placeVolume(layer_vol, Transform3D(RotationZYX(0.0, -M_PI, 0.0), Position(0, 0, -layer_center_z))); + layer_pv = assembly.placeVolume( + layer_vol, Transform3D(RotationZYX(0.0, -M_PI, 0.0), Position(0, 0, -layer_center_z))); layer_pv.addPhysVolID("layer", l_id); layer_name += "_N"; } else { @@ -240,26 +241,26 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s DetElement layer_element(sdet, layer_name, l_id); layer_element.setPlacement(layer_pv); - auto &layerParams = - DD4hepDetectorHelper::ensureExtension( - layer_element); + auto& layerParams = + DD4hepDetectorHelper::ensureExtension(layer_element); for (xml_coll_t lmat(x_layer, _Unicode(layer_material)); lmat; ++lmat) { xml_comp_t x_layer_material = lmat; - DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, "layer_material"); + DD4hepDetectorHelper::xmlToProtoSurfaceMaterial(x_layer_material, layerParams, + "layer_material"); } for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) { - xml_comp_t x_ring = ri; - double r = x_ring.r(); - double phi0 = x_ring.phi0(0); - double zstart = x_ring.zstart(); - double dz = x_ring.dz(0); - int nmodules = x_ring.nmodules(); - string m_nam = x_ring.moduleStr(); - Volume m_vol = modules[m_nam]; - double iphi = 2 * M_PI / nmodules; - double phi = phi0; + xml_comp_t x_ring = ri; + double r = x_ring.r(); + double phi0 = x_ring.phi0(0); + double zstart = x_ring.zstart(); + double dz = x_ring.dz(0); + int nmodules = x_ring.nmodules(); + string m_nam = x_ring.moduleStr(); + Volume m_vol = modules[m_nam]; + double iphi = 2 * M_PI / nmodules; + double phi = phi0; Placements& sensVols = sensitives[m_nam]; for (int k = 0; k < nmodules; ++k) { @@ -269,28 +270,30 @@ static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector s if (!reflect) { DetElement module(layer_element, m_base + "_pos", det_id); - pv = layer_vol.placeVolume( - m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, zstart + dz))); + pv = layer_vol.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), + Position(x, y, zstart + dz))); pv.addPhysVolID("module", mod_num); module.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_elt(module, sens_pv.volume().name(), mod_num); - auto &comp_elt_params = DD4hepDetectorHelper::ensureExtension(comp_elt); + DetElement comp_elt(module, sens_pv.volume().name(), mod_num); + auto& comp_elt_params = + DD4hepDetectorHelper::ensureExtension(comp_elt); comp_elt_params.set("axis_definitions", "XZY"); comp_elt.setPlacement(sens_pv); volSurfaceList(comp_elt)->push_back(volplane_surfaces[m_nam][ic]); } } else { - pv = layer_vol.placeVolume( - m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, -zstart - dz))); + pv = layer_vol.placeVolume(m_vol, Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), + Position(x, y, -zstart - dz))); pv.addPhysVolID("module", mod_num); DetElement r_module(layer_element, m_base + "_neg", det_id); r_module.setPlacement(pv); for (size_t ic = 0; ic < sensVols.size(); ++ic) { PlacedVolume sens_pv = sensVols[ic]; - DetElement comp_elt(r_module, sens_pv.volume().name(), mod_num); - auto &comp_elt_params = DD4hepDetectorHelper::ensureExtension(comp_elt); + DetElement comp_elt(r_module, sens_pv.volume().name(), mod_num); + auto& comp_elt_params = + DD4hepDetectorHelper::ensureExtension(comp_elt); comp_elt_params.set("axis_definitions", "XZY"); comp_elt.setPlacement(sens_pv); volSurfaceList(comp_elt)->push_back(volplane_surfaces[m_nam][ic]); diff --git a/src/ZDC_Crystal_geo.cpp b/src/ZDC_Crystal_geo.cpp index 52daa9f49..e9e7185a3 100644 --- a/src/ZDC_Crystal_geo.cpp +++ b/src/ZDC_Crystal_geo.cpp @@ -20,73 +20,72 @@ using namespace std; using namespace dd4hep; // main -static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) { xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - DetElement det(detName, detID); + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + DetElement det(detName, detID); sens.setType("calorimeter"); - auto dim = detElem.dimensions(); - auto xwidth = dim.x(); - auto ywidth = dim.y(); - auto length = dim.z(); - xml_dim_t pos = detElem.position(); - xml_dim_t rot = detElem.rotation(); + auto dim = detElem.dimensions(); + auto xwidth = dim.x(); + auto ywidth = dim.y(); + auto length = dim.z(); + xml_dim_t pos = detElem.position(); + xml_dim_t rot = detElem.rotation(); // envelope - Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5); + Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5); Volume env(detName + "_envelope", envShape, desc.material("Air")); env.setVisAttributes(desc.visAttributes(detElem.visStr())); // build frame - xml_comp_t fr = detElem.child(_Unicode(support)); - auto fx = xwidth; - auto fy = ywidth; - auto fz = fr.attr(_Unicode(sizez)); - auto fthickness = fr.attr(_Unicode(thickness)); - - Box frShape(fx / 2., fy / 2., fz / 2.); - auto frMat = desc.material(fr.attr(_Unicode(material))); + xml_comp_t fr = detElem.child(_Unicode(support)); + auto fx = xwidth; + auto fy = ywidth; + auto fz = fr.attr(_Unicode(sizez)); + auto fthickness = fr.attr(_Unicode(thickness)); + + Box frShape(fx / 2., fy / 2., fz / 2.); + auto frMat = desc.material(fr.attr(_Unicode(material))); Volume frVol("frame_vol", frShape, frMat); frVol.setVisAttributes(desc.visAttributes(fr.visStr())); xml_comp_t mod_x = detElem.child(_Unicode(module)); - auto nx = mod_x.attr(_Unicode(nx)); - auto ny = mod_x.attr(_Unicode(ny)); + auto nx = mod_x.attr(_Unicode(nx)); + auto ny = mod_x.attr(_Unicode(ny)); // crystal tower - xml_comp_t twr = mod_x.child(_Unicode(tower)); - double tsx = twr.attr(_Unicode(cellx)); - double tsy = twr.attr(_Unicode(celly)); - double tsz = twr.thickness(); - Material t_mat = desc.material(twr.materialStr()); - string t_name = twr.nameStr(); - - Box t_Shape(tsx / 2., tsy / 2., tsz / 2.); + xml_comp_t twr = mod_x.child(_Unicode(tower)); + double tsx = twr.attr(_Unicode(cellx)); + double tsy = twr.attr(_Unicode(celly)); + double tsz = twr.thickness(); + Material t_mat = desc.material(twr.materialStr()); + string t_name = twr.nameStr(); + + Box t_Shape(tsx / 2., tsy / 2., tsz / 2.); Volume t_Vol("tower_vol", t_Shape, t_mat); t_Vol.setVisAttributes(desc.visAttributes(twr.visStr())); if (twr.isSensitive()) t_Vol.setSensitiveDetector(sens); // readout socket - xml_comp_t sct = mod_x.child(_Unicode(socket)); - double ssx = sct.attr(_Unicode(cellx)); - double ssy = sct.attr(_Unicode(celly)); - double ssz = sct.thickness(); - Material s_mat = desc.material(sct.materialStr()); - string s_name = sct.nameStr(); - - Box s_Shape(ssx / 2., ssy / 2., ssz / 2.); + xml_comp_t sct = mod_x.child(_Unicode(socket)); + double ssx = sct.attr(_Unicode(cellx)); + double ssy = sct.attr(_Unicode(celly)); + double ssz = sct.thickness(); + Material s_mat = desc.material(sct.materialStr()); + string s_name = sct.nameStr(); + + Box s_Shape(ssx / 2., ssy / 2., ssz / 2.); Volume s_Vol("socket_vol", s_Shape, s_mat); s_Vol.setVisAttributes(desc.visAttributes(sct.visStr())); PlacedVolume pv; - double x_pos_0 = -(nx * tsx + (nx - 1) * fthickness) / 2.; - double y_pos_0 = -(ny * tsy + (ny - 1) * fthickness) / 2.; - double twr_z_pos_in_fr = -fz / 2. + tsz / 2.; - double sct_z_pos_in_env = -length / 2. + tsz + ssz / 2.; - int mod_i = 0; + double x_pos_0 = -(nx * tsx + (nx - 1) * fthickness) / 2.; + double y_pos_0 = -(ny * tsy + (ny - 1) * fthickness) / 2.; + double twr_z_pos_in_fr = -fz / 2. + tsz / 2.; + double sct_z_pos_in_env = -length / 2. + tsz + ssz / 2.; + int mod_i = 0; for (int ix = 0; ix < nx; ix++) { double x_pos = x_pos_0 + ix * (tsx + fthickness) + tsx / 2.; @@ -104,13 +103,13 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen } } - double f_zpos = -length / 2. + fz / 2.; + double f_zpos = -length / 2. + fz / 2.; Position fr_pos(0, 0, f_zpos); pv = env.placeVolume(frVol, fr_pos); // detector position and rotation - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume envPV = motherVol.placeVolume(env, tr); envPV.addPhysVolID("system", detID); det.setPlacement(envPV); diff --git a/src/ZDC_ImagingCal_geo.cpp b/src/ZDC_ImagingCal_geo.cpp index 831bc85f7..d430eb7c0 100644 --- a/src/ZDC_ImagingCal_geo.cpp +++ b/src/ZDC_ImagingCal_geo.cpp @@ -20,47 +20,46 @@ using namespace std; using namespace dd4hep; // main -static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) { xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - DetElement det(detName, detID); + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + DetElement det(detName, detID); sens.setType("calorimeter"); - auto dim = detElem.dimensions(); - auto xwidth = dim.x(); - auto ywidth = dim.y(); - auto length = dim.z(); - xml_dim_t pos = detElem.position(); - xml_dim_t rot = detElem.rotation(); + auto dim = detElem.dimensions(); + auto xwidth = dim.x(); + auto ywidth = dim.y(); + auto length = dim.z(); + xml_dim_t pos = detElem.position(); + xml_dim_t rot = detElem.rotation(); // envelope - Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5); + Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5); Volume env(detName + "_envelope", envShape, desc.material("Air")); env.setVisAttributes(desc.visAttributes(detElem.visStr())); - int layerid = 0; - double zpos_0 = -length / 2.; + int layerid = 0; + double zpos_0 = -length / 2.; for (xml_coll_t li(detElem, _Unicode(layer)); li; ++li) { xml_comp_t x_lyr = li; - auto nlyr = x_lyr.attr(_Unicode(nlayer)); - auto gap_z = x_lyr.attr(_Unicode(gapspace)); + auto nlyr = x_lyr.attr(_Unicode(nlayer)); + auto gap_z = x_lyr.attr(_Unicode(gapspace)); - map v_sl_name; + map v_sl_name; map slices; map sl_thickness; - int nsl = 0; + int nsl = 0; xml_coll_t ci(x_lyr, _Unicode(slice)); for (ci.reset(); ci; ++ci) { - xml_comp_t x_sl = ci; - Material sl_mat = desc.material(x_sl.materialStr()); - string sl_name = x_sl.nameStr(); - double sl_z = x_sl.thickness(); + xml_comp_t x_sl = ci; + Material sl_mat = desc.material(x_sl.materialStr()); + string sl_name = x_sl.nameStr(); + double sl_z = x_sl.thickness(); - Box sl_Shape(xwidth / 2., ywidth / 2., sl_z / 2.); + Box sl_Shape(xwidth / 2., ywidth / 2., sl_z / 2.); Volume sl_Vol("slice_vol", sl_Shape, sl_mat); sl_Vol.setVisAttributes(desc.visAttributes(x_sl.visStr())); if (x_sl.isSensitive()) @@ -77,8 +76,8 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen for (int isl = 0; isl < nsl; isl++) { string sl_name = v_sl_name[isl + 1]; - double zpos = zpos_0 + sl_thickness[sl_name] / 2.; - Position sl_pos(0, 0, zpos); + double zpos = zpos_0 + sl_thickness[sl_name] / 2.; + Position sl_pos(0, 0, zpos); PlacedVolume pv = env.placeVolume(slices[sl_name], sl_pos); if (slices[sl_name].isSensitive()) pv.addPhysVolID(sl_name, layerid); @@ -91,8 +90,8 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen } // detector position and rotation - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume envPV = motherVol.placeVolume(env, tr); envPV.addPhysVolID("system", detID); det.setPlacement(envPV); diff --git a/src/ZDC_SamplingCal_geo.cpp b/src/ZDC_SamplingCal_geo.cpp index 78044b443..9ae8e8014 100644 --- a/src/ZDC_SamplingCal_geo.cpp +++ b/src/ZDC_SamplingCal_geo.cpp @@ -20,45 +20,44 @@ using namespace std; using namespace dd4hep; // main -static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) { xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - DetElement det(detName, detID); + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + DetElement det(detName, detID); sens.setType("calorimeter"); - auto dim = detElem.dimensions(); - auto xwidth = dim.x(); - auto ywidth = dim.y(); - auto length = dim.z(); - xml_dim_t pos = detElem.position(); - xml_dim_t rot = detElem.rotation(); + auto dim = detElem.dimensions(); + auto xwidth = dim.x(); + auto ywidth = dim.y(); + auto length = dim.z(); + xml_dim_t pos = detElem.position(); + xml_dim_t rot = detElem.rotation(); // envelope - Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5); + Box envShape(xwidth * 0.5, ywidth * 0.5, length * 0.5); Volume env(detName + "_envelope", envShape, desc.material("Air")); env.setVisAttributes(desc.visAttributes(detElem.visStr())); - xml_comp_t mod_x = detElem.child(_Unicode(module)); - auto nbox = mod_x.attr(_Unicode(nbox)); - auto boxgap = mod_x.attr(_Unicode(gapspace)); + xml_comp_t mod_x = detElem.child(_Unicode(module)); + auto nbox = mod_x.attr(_Unicode(nbox)); + auto boxgap = mod_x.attr(_Unicode(gapspace)); xml_comp_t x_lyr = mod_x.child(_Unicode(layer)); - auto nlyr = x_lyr.attr(_Unicode(nlayer)); + auto nlyr = x_lyr.attr(_Unicode(nlayer)); - map v_sl_name; + map v_sl_name; map slices; map sl_thickness; - int nsl = 0; + int nsl = 0; xml_coll_t ci(x_lyr, _Unicode(slice)); for (ci.reset(); ci; ++ci) { - xml_comp_t x_sl = ci; - Material sl_mat = desc.material(x_sl.materialStr()); - string sl_name = x_sl.nameStr(); - double sl_z = x_sl.thickness(); + xml_comp_t x_sl = ci; + Material sl_mat = desc.material(x_sl.materialStr()); + string sl_name = x_sl.nameStr(); + double sl_z = x_sl.thickness(); - Box sl_Shape(xwidth / 2., ywidth / 2., sl_z / 2.); + Box sl_Shape(xwidth / 2., ywidth / 2., sl_z / 2.); Volume sl_Vol("slice_vol", sl_Shape, sl_mat); sl_Vol.setVisAttributes(desc.visAttributes(x_sl.visStr())); if (x_sl.isSensitive()) @@ -70,16 +69,16 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen sl_thickness[sl_name] = sl_z; } - double zpos_0 = -length / 2.; - int layerid = 0; + double zpos_0 = -length / 2.; + int layerid = 0; for (int ibox = 0; ibox < nbox; ibox++) { for (int ilyr = 0; ilyr < nlyr; ilyr++) { layerid++; for (int isl = 0; isl < nsl; isl++) { string sl_name = v_sl_name[isl + 1]; - double zpos = zpos_0 + sl_thickness[sl_name] / 2.; - Position sl_pos(0, 0, zpos); + double zpos = zpos_0 + sl_thickness[sl_name] / 2.; + Position sl_pos(0, 0, zpos); PlacedVolume pv = env.placeVolume(slices[sl_name], sl_pos); if (slices[sl_name].isSensitive()) pv.addPhysVolID(sl_name, layerid); @@ -91,8 +90,8 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen } // detector position and rotation - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume envPV = motherVol.placeVolume(env, tr); envPV.addPhysVolID("system", detID); det.setPlacement(envPV); diff --git a/src/ZeroDegreeCalorimeterEcalWSciFi_geo.cpp b/src/ZeroDegreeCalorimeterEcalWSciFi_geo.cpp index 2188784fb..c519f1623 100644 --- a/src/ZeroDegreeCalorimeterEcalWSciFi_geo.cpp +++ b/src/ZeroDegreeCalorimeterEcalWSciFi_geo.cpp @@ -20,44 +20,43 @@ using namespace std; using namespace dd4hep; // main -static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) -{ +static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sens) { xml::DetElement detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); - DetElement det(detName, detID); + std::string detName = detElem.nameStr(); + int detID = detElem.id(); + DetElement det(detName, detID); sens.setType("calorimeter"); - auto dim = detElem.dimensions(); - auto width = dim.x(); - auto length = dim.z(); - xml_dim_t pos = detElem.position(); - xml_dim_t rot = detElem.rotation(); + auto dim = detElem.dimensions(); + auto width = dim.x(); + auto length = dim.z(); + xml_dim_t pos = detElem.position(); + xml_dim_t rot = detElem.rotation(); // envelope - Box envShape(width * 0.5, width * 0.5, length * 0.5); + Box envShape(width * 0.5, width * 0.5, length * 0.5); Volume env(detName + "_envelope", envShape, desc.material("Air")); env.setVisAttributes(desc.visAttributes(detElem.visStr())); // build module xml_comp_t mod_x = detElem.child(_Unicode(module)); - auto sx = mod_x.attr(_Unicode(sizex)); - auto sy = mod_x.attr(_Unicode(sizey)); - auto sz = mod_x.attr(_Unicode(sizez)); + auto sx = mod_x.attr(_Unicode(sizex)); + auto sy = mod_x.attr(_Unicode(sizey)); + auto sz = mod_x.attr(_Unicode(sizez)); - Box modShape(sx / 2., sy / 2., sz / 2.); - auto modMat = desc.material(mod_x.attr(_Unicode(material))); + Box modShape(sx / 2., sy / 2., sz / 2.); + auto modMat = desc.material(mod_x.attr(_Unicode(material))); Volume modVol("module_vol", modShape, modMat); modVol.setVisAttributes(desc.visAttributes(mod_x.visStr())); // modVol.setSensitiveDetector(sens); if (mod_x.hasChild(_Unicode(fiber))) { - auto fiber_x = mod_x.child(_Unicode(fiber)); - auto fr = fiber_x.attr(_Unicode(radius)); - auto fsx = fiber_x.attr(_Unicode(spacex)); - auto fsy = fiber_x.attr(_Unicode(spacey)); - auto foff = dd4hep::getAttrOrDefault(fiber_x, _Unicode(offset), 0.5 * mm); - auto fiberMat = desc.material(fiber_x.attr(_Unicode(material))); - Tube fiberShape(0., fr, sz / 2. - 1. * mm); + auto fiber_x = mod_x.child(_Unicode(fiber)); + auto fr = fiber_x.attr(_Unicode(radius)); + auto fsx = fiber_x.attr(_Unicode(spacex)); + auto fsy = fiber_x.attr(_Unicode(spacey)); + auto foff = dd4hep::getAttrOrDefault(fiber_x, _Unicode(offset), 0.5 * mm); + auto fiberMat = desc.material(fiber_x.attr(_Unicode(material))); + Tube fiberShape(0., fr, sz / 2. - 1. * mm); Volume fiberVol("fiber_vol", fiberShape, fiberMat); fiberVol.setSensitiveDetector(sens); @@ -73,8 +72,8 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen int ny = int(sy / (2. * fr)) + 1; // place the fibers - double y0 = (foff + fside); - int nfibers = 0; + double y0 = (foff + fside); + int nfibers = 0; for (int iy = 0; iy < ny; ++iy) { double y = y0 + fdisty * iy; // about to touch the boundary @@ -88,7 +87,8 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen if ((sx - x) < x0) { break; } - auto fiberPV = modVol.placeVolume(fiberVol, nfibers++, Position{x - sx / 2., y - sy / 2., 0}); + auto fiberPV = + modVol.placeVolume(fiberVol, nfibers++, Position{x - sx / 2., y - sy / 2., 0}); fiberPV.addPhysVolID("fiber_x", ix + 1).addPhysVolID("fiber_y", iy + 1); } } @@ -102,7 +102,7 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen double mod_y_pos = 0.0; double mod_z_pos = 0.0 * mm; double mgap = 0.000001 * mm; - int mNTowers = floor(width / (sx + mgap)); + int mNTowers = floor(width / (sx + mgap)); // std::cout << "mNTowers: " << mNTowers << std::endl; int k = 0; @@ -127,8 +127,8 @@ static Ref_t create_detector(Detector& desc, xml_h handle, SensitiveDetector sen } // detector position and rotation - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume envPV = motherVol.placeVolume(env, tr); envPV.addPhysVolID("system", detID); det.setPlacement(envPV); diff --git a/src/ZeroDegreeCalorimeterEcal_geo.cpp b/src/ZeroDegreeCalorimeterEcal_geo.cpp index 54004fda5..c8e0693bf 100644 --- a/src/ZeroDegreeCalorimeterEcal_geo.cpp +++ b/src/ZeroDegreeCalorimeterEcal_geo.cpp @@ -14,37 +14,36 @@ using namespace std; using namespace dd4hep; -static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) -{ - xml_det_t x_det = e; - string detName = x_det.nameStr(); - int detID = x_det.id(); +static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + string detName = x_det.nameStr(); + int detID = x_det.id(); - xml_dim_t dim = x_det.dimensions(); - double Width = dim.x(); - double Thickness = dim.z(); + xml_dim_t dim = x_det.dimensions(); + double Width = dim.x(); + double Thickness = dim.z(); xml_dim_t pos = x_det.position(); xml_dim_t rot = x_det.rotation(); Material Vacuum = desc.material("Vacuum"); - xml_comp_t mod = x_det.child(_Unicode(module)); - string modName = mod.nameStr(); - Material mPbWO4 = desc.material(mod.materialStr()); - double mThickness = mod.attr(_Unicode(thickness)); - double mWidth = mod.attr(_Unicode(width)); - double mGap = mod.attr(_Unicode(gap)); - int mNTowers = mod.attr(_Unicode(ntower)); + xml_comp_t mod = x_det.child(_Unicode(module)); + string modName = mod.nameStr(); + Material mPbWO4 = desc.material(mod.materialStr()); + double mThickness = mod.attr(_Unicode(thickness)); + double mWidth = mod.attr(_Unicode(width)); + double mGap = mod.attr(_Unicode(gap)); + int mNTowers = mod.attr(_Unicode(ntower)); // Create Global Volume - Box ffi_ZDC_GVol_Solid(Width * 0.5, Width * 0.5, Thickness * 0.5); + Box ffi_ZDC_GVol_Solid(Width * 0.5, Width * 0.5, Thickness * 0.5); Volume detVol("ffi_ZDC_GVol_Logic", ffi_ZDC_GVol_Solid, Vacuum); detVol.setVisAttributes(desc.visAttributes(x_det.visStr())); // Construct Tower // Single Module - Box ffi_ZDC_ECAL_Solid_Tower(mWidth * 0.5, mWidth * 0.5, mThickness * 0.5); + Box ffi_ZDC_ECAL_Solid_Tower(mWidth * 0.5, mWidth * 0.5, mThickness * 0.5); Volume modVol("ffi_ZDC_ECAL_Logic_Tower", ffi_ZDC_ECAL_Solid_Tower, mPbWO4); modVol.setVisAttributes(desc.visAttributes(mod.visStr())); sens.setType("calorimeter"); @@ -74,15 +73,15 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) if (abs(mod_x + mWidth / 2.0) > Width / 2.0) continue; k++; - string module_name = detName + _toString(k, "_ECAL_Phys_%d"); - PlacedVolume pv_mod = detVol.placeVolume(modVol, Position(mod_x, mod_y, mod_z)); + string module_name = detName + _toString(k, "_ECAL_Phys_%d"); + PlacedVolume pv_mod = detVol.placeVolume(modVol, Position(mod_x, mod_y, mod_z)); pv_mod.addPhysVolID("module", k + 1); } } - DetElement det(detName, detID); - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); + DetElement det(detName, detID); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume detPV = motherVol.placeVolume(detVol, tr); detPV.addPhysVolID("system", detID); det.setPlacement(detPV); diff --git a/src/ZeroDegreeCalorimeterSampling_geo.cpp b/src/ZeroDegreeCalorimeterSampling_geo.cpp index d3f0d6641..9dd394295 100644 --- a/src/ZeroDegreeCalorimeterSampling_geo.cpp +++ b/src/ZeroDegreeCalorimeterSampling_geo.cpp @@ -15,25 +15,24 @@ using namespace std; using namespace dd4hep; -static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) -{ - xml_det_t x_det = e; - string detName = x_det.nameStr(); - int detID = x_det.id(); - - xml_dim_t dim = x_det.dimensions(); - double Width = dim.x(); +static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + string detName = x_det.nameStr(); + int detID = x_det.id(); + + xml_dim_t dim = x_det.dimensions(); + double Width = dim.x(); // double Length = dim.z(); xml_dim_t pos = x_det.position(); - double z = pos.z(); + double z = pos.z(); xml_dim_t rot = x_det.rotation(); Material Vacuum = desc.material("Vacuum"); double totWidth = Layering(x_det).totalThickness(); - Box envelope(Width / 2.0, Width / 2.0, totWidth / 2.0); + Box envelope(Width / 2.0, Width / 2.0, totWidth / 2.0); Volume envelopeVol(detName + "_envelope", envelope, Vacuum); envelopeVol.setVisAttributes(desc.visAttributes(x_det.visStr())); PlacedVolume pv; @@ -41,9 +40,9 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) int layer_num = 1; // Read layers for (xml_coll_t c(x_det, _U(layer)); c; ++c) { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); - double layerWidth = 0; + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); + double layerWidth = 0; for (xml_coll_t l(x_layer, _U(slice)); l; ++l) layerWidth += xml_comp_t(l).thickness(); @@ -57,11 +56,11 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) int slice_num = 1; // Loop over slices for (xml_coll_t l(x_layer, _U(slice)); l; ++l) { - xml_comp_t x_slice = l; - double w = x_slice.thickness(); - string slice_name = layer_name + _toString(slice_num, "slice%d"); - Material slice_mat = desc.material(x_slice.materialStr()); - Volume slice_vol(slice_name, Box(Width / 2.0, Width / 2.0, w / 2.0), slice_mat); + xml_comp_t x_slice = l; + double w = x_slice.thickness(); + string slice_name = layer_name + _toString(slice_num, "slice%d"); + Material slice_mat = desc.material(x_slice.materialStr()); + Volume slice_vol(slice_name, Box(Width / 2.0, Width / 2.0, w / 2.0), slice_mat); if (x_slice.isSensitive()) { sens.setType("calorimeter"); @@ -70,25 +69,29 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) slice_vol.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); pv = layer_vol.placeVolume( - slice_vol, Transform3D(RotationZYX(0, 0, 0), Position(0.0, 0.0, z - zlayer - layerWidth / 2.0 + w / 2.0))); + slice_vol, Transform3D(RotationZYX(0, 0, 0), + Position(0.0, 0.0, z - zlayer - layerWidth / 2.0 + w / 2.0))); pv.addPhysVolID("slice", slice_num); z += w; ++slice_num; } - string layer_vis = dd4hep::getAttrOrDefault(x_layer, _Unicode(vis), "InvisibleWithDaughters"); + string layer_vis = + dd4hep::getAttrOrDefault(x_layer, _Unicode(vis), "InvisibleWithDaughters"); layer_vol.setAttributes(desc, x_layer.regionStr(), x_layer.limitsStr(), layer_vis); pv = envelopeVol.placeVolume( layer_vol, - Transform3D(RotationZYX(0, 0, 0), Position(0, 0, zlayer - pos.z() - totWidth / 2.0 + layerWidth / 2.0))); + Transform3D(RotationZYX(0, 0, 0), + Position(0, 0, zlayer - pos.z() - totWidth / 2.0 + layerWidth / 2.0))); pv.addPhysVolID("layer", layer_num); ++layer_num; } } - DetElement det(detName, detID); - Volume motherVol = desc.pickMotherVolume(det); - Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z() + totWidth / 2.0)); + DetElement det(detName, detID); + Volume motherVol = desc.pickMotherVolume(det); + Transform3D tr(RotationZYX(rot.z(), rot.y(), rot.x()), + Position(pos.x(), pos.y(), pos.z() + totWidth / 2.0)); PlacedVolume phv = motherVol.placeVolume(envelopeVol, tr); phv.addPhysVolID("system", detID); det.setPlacement(phv); diff --git a/src/ZeroDegreeCalorimeterSiPMonTile_geo.cpp b/src/ZeroDegreeCalorimeterSiPMonTile_geo.cpp index a13142d01..0e7396226 100644 --- a/src/ZeroDegreeCalorimeterSiPMonTile_geo.cpp +++ b/src/ZeroDegreeCalorimeterSiPMonTile_geo.cpp @@ -13,21 +13,20 @@ using namespace dd4hep; -static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) -{ - xml_det_t detElem = handle; - std::string detName = detElem.nameStr(); - int detID = detElem.id(); +static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens) { + xml_det_t detElem = handle; + std::string detName = detElem.nameStr(); + int detID = detElem.id(); - xml_dim_t dim = detElem.dimensions(); - double width = dim.x(); // Size along x-axis - double height = dim.y(); // Size along y-axis - double length = dim.z(); // Size along z-axis + xml_dim_t dim = detElem.dimensions(); + double width = dim.x(); // Size along x-axis + double height = dim.y(); // Size along y-axis + double length = dim.z(); // Size along z-axis - xml_dim_t pos = detElem.position(); // Position in global coordinates - xml_dim_t rot = detElem.rotation(); + xml_dim_t pos = detElem.position(); // Position in global coordinates + xml_dim_t rot = detElem.rotation(); - Material air = desc.material("Air"); + Material air = desc.material("Air"); // Defining envelope Box envelope(width / 2.0, height / 2.0, length / 2.0); @@ -35,12 +34,7 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens // Defining envelope volume Volume envelopeVol(detName, envelope, air); // Setting envelope attributes - envelopeVol.setAttributes( - desc, - detElem.regionStr(), - detElem.limitsStr(), - detElem.visStr() - ); + envelopeVol.setAttributes(desc, detElem.regionStr(), detElem.limitsStr(), detElem.visStr()); PlacedVolume pv; @@ -49,77 +43,54 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens int layer_num = 1; // Looping through all the different layer sections - for(xml_coll_t c(detElem,_U(layer)); c; ++c) - { - xml_comp_t x_layer = c; - int repeat = x_layer.repeat(); + for (xml_coll_t c(detElem, _U(layer)); c; ++c) { + xml_comp_t x_layer = c; + int repeat = x_layer.repeat(); double layer_thickness = x_layer.thickness(); // Looping through the number of repeated layers in each section - for(int i = 0; i < repeat; i++) - { + for (int i = 0; i < repeat; i++) { std::string layer_name = detName + _toString(layer_num, "_layer%d"); Box layer(width / 2., height / 2., layer_thickness / 2.); Volume layer_vol(layer_name, layer, air); - int slice_num = 1; + int slice_num = 1; double slice_z = -layer_thickness / 2.; // Keeps track of slices' z locations in each layer // Looping over each layer's slices - for(xml_coll_t l(x_layer,_U(slice)); l; ++l) - { - xml_comp_t x_slice = l; + for (xml_coll_t l(x_layer, _U(slice)); l; ++l) { + xml_comp_t x_slice = l; double slice_thickness = x_slice.thickness(); std::string slice_name = layer_name + _toString(slice_num, "slice%d"); - Material slice_mat = desc.material(x_slice.materialStr()); - slice_z += slice_thickness/2.; // Going to slice halfway point + Material slice_mat = desc.material(x_slice.materialStr()); + slice_z += slice_thickness / 2.; // Going to slice halfway point - Box slice(width/2., height/2., slice_thickness/2.); + Box slice(width / 2., height / 2., slice_thickness / 2.); - Volume slice_vol (slice_name, slice, slice_mat); + Volume slice_vol(slice_name, slice, slice_mat); // Setting appropriate slices as sensitive - if(x_slice.isSensitive()) - { + if (x_slice.isSensitive()) { sens.setType("calorimeter"); slice_vol.setSensitiveDetector(sens); } // Setting slice attributes - slice_vol.setAttributes( - desc, - x_slice.regionStr(), - x_slice.limitsStr(), - x_slice.visStr() - ); + slice_vol.setAttributes(desc, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr()); // Placing slice within layer - pv = layer_vol.placeVolume( - slice_vol, - Transform3D( - RotationZYX(0, 0, 0), - Position( - 0., - 0., - slice_z - ) - ) - ); + pv = layer_vol.placeVolume(slice_vol, + Transform3D(RotationZYX(0, 0, 0), Position(0., 0., slice_z))); pv.addPhysVolID("slice", slice_num); - slice_z += slice_thickness/2.; + slice_z += slice_thickness / 2.; z_distance_traversed += slice_thickness; ++slice_num; } // Setting layer attributes - layer_vol.setAttributes( - desc, - x_layer.regionStr(), - x_layer.limitsStr(), - x_layer.visStr() - ); + layer_vol.setAttributes(desc, x_layer.regionStr(), x_layer.limitsStr(), x_layer.visStr()); // Placing each layer inside the envelope volume // -length/2. is front of detector in global coordinate system // + (z_distance_traversed - layer_thickness) goes to the front of each layer @@ -129,26 +100,21 @@ static Ref_t createDetector(Detector& desc, xml_h handle, SensitiveDetector sens // Adding layer_thickness/2. goes to half the first layer thickness (proper place to put layer) // Each loop over repeat will increases z_distance_traversed by layer_thickness pv = envelopeVol.placeVolume( - layer_vol, - Transform3D( - RotationZYX(0, 0, 0), - Position( - 0., - 0., - -length/2. + (z_distance_traversed - layer_thickness) + layer_thickness/2. - ) - ) - ); + layer_vol, Transform3D(RotationZYX(0, 0, 0), + Position(0., 0., + -length / 2. + (z_distance_traversed - layer_thickness) + + layer_thickness / 2.))); pv.addPhysVolID("layer", layer_num); layer_num++; } } - DetElement det(detName, detID); + DetElement det(detName, detID); Volume motherVol = desc.pickMotherVolume(det); // Placing ZDC in world volume - auto tr = Transform3D(RotationZYX(rot.z(), rot.y(), rot.x()),Position(pos.x(), pos.y(), pos.z())); + auto tr = + Transform3D(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); PlacedVolume phv = motherVol.placeVolume(envelopeVol, tr); phv.addPhysVolID("system", detID); det.setPlacement(phv); diff --git a/src/forwardBeamPipeBrazil.cpp b/src/forwardBeamPipeBrazil.cpp index 0feb23991..122181474 100644 --- a/src/forwardBeamPipeBrazil.cpp +++ b/src/forwardBeamPipeBrazil.cpp @@ -9,491 +9,592 @@ using namespace std; using namespace dd4hep; -static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) -{ - - using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); - DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Al = det.material("Aluminum"); - Material m_Be = det.material("Beryllium"); - Material m_SS = det.material("StainlessSteel"); - Material m_vac = det.material("Vacuum"); - string vis_name = x_det.visStr(); - - PlacedVolume pv_assembly; - - double b0_hadron_tube_inner_r = 2.9 * dd4hep::cm; - double b0_hadron_tube_outer_r = 3.1 * dd4hep::cm; - double b0_hadron_tube_length = 120.0 * dd4hep::cm; - - double pipeThickness = 5.0 * dd4hep::mm; - - struct beampipe_dimensions_t { - Double_t length = 0.0; - Double_t innerXRadius = 0.0; - Double_t innerYRadius = 0.0; - Double_t outerXRadius = 0.0; - Double_t outerYRadius = 0.0; - Double_t xCenter = 0.0; - Double_t yCenter = 0.0; - Double_t zCenter = 0.0; - Double_t rotationAngle = 0.0; - }; - - std::vector beampipe_dimensions; - - double globRotationAngle = -0.0454486856; //This is the angle of the proton orbit from the end of B1APF to the beginning of B2PF - double crossingAngle = -0.025; //relevant for the neutral cone - - double b1APFEndPoint_z = 22062.3828 * dd4hep::mm; //location of proton orbit at b1APF exit -- in mm - double b1APFEndPoint_x = 654.3372 * dd4hep::mm; //location of proton orbit at b1APF exit -- in mm - - double tmp_endpoint_z = 0.0; - double tmp_endpoint_x = 0.0; - - //forumula -> Z = b1APFEndPoint_z+((0.5*elementLengt)*Cos(globRotationAngle)) - //forumula -> X = b1APFEndPoint_z+((0.5*elementLengt)*Sin(globRotationAngle)) - - //------------------------------------------------------------------------------------ - //Geometry extracted from version 0 VPC drawings shown at the FF preliminary - //design review in February 2024 -- CAD model not available as of April 1st, 2024 - //------------------------------------------------------------------------------------ - - //------------------------------------------------------------------------------------ - //primary pipe after B1APF, before neutral exit window + transition to smaller pipe - //rectangular cross-section!!!!! - //------------------------------------------------------------------------------------ - - - beampipe_dimensions.push_back({ - .length = 7615.486 * dd4hep::mm, //from VPC drawings, in mm - .innerXRadius = 275.0 * dd4hep::mm, - .innerYRadius = 175.0 * dd4hep::mm, - .rotationAngle = globRotationAngle - }); - - beampipe_dimensions[0].outerXRadius = beampipe_dimensions[0].innerXRadius + pipeThickness; - beampipe_dimensions[0].outerYRadius = beampipe_dimensions[0].innerYRadius + pipeThickness; - beampipe_dimensions[0].xCenter = -1*(b1APFEndPoint_x+((0.5*beampipe_dimensions[0].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[0].yCenter = 0.0; - beampipe_dimensions[0].zCenter = (b1APFEndPoint_z+((0.5*beampipe_dimensions[0].length)*TMath::Cos(-globRotationAngle))); - - tmp_endpoint_z = beampipe_dimensions[0].zCenter+((0.5*beampipe_dimensions[0].length)*TMath::Cos(-globRotationAngle)); - tmp_endpoint_x = -1*beampipe_dimensions[0].xCenter+((0.5*beampipe_dimensions[0].length)*TMath::Sin(-globRotationAngle)); - - double windowRadius = 110.0 * dd4hep::mm; - - - //------------------------------------------------------------------------------------ - //first small pipe section, between primary vessel and RP station 1 - //rectangular cross-section!!!!! - //------------------------------------------------------------------------------------ - - beampipe_dimensions.push_back({ - .length = 2780.273 * dd4hep::mm, // from VPC drawings - .innerXRadius = 150.0 * dd4hep::mm, - .innerYRadius = 30.0 * dd4hep::mm, - .rotationAngle = globRotationAngle - }); - - beampipe_dimensions[1].outerXRadius = beampipe_dimensions[1].innerXRadius + pipeThickness; - beampipe_dimensions[1].outerYRadius = beampipe_dimensions[1].innerYRadius + pipeThickness; - beampipe_dimensions[1].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[1].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[1].yCenter = 0.0; - beampipe_dimensions[1].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[1].length)*TMath::Cos(-globRotationAngle)); - - tmp_endpoint_z = beampipe_dimensions[1].zCenter+((0.5*beampipe_dimensions[1].length)*TMath::Cos(-globRotationAngle)); - tmp_endpoint_x = -1*beampipe_dimensions[1].xCenter+((0.5*beampipe_dimensions[1].length)*TMath::Sin(-globRotationAngle)); - - //------------------------------------------------------------------------------------ - //First roman pots scattering chamber - //------------------------------------------------------------------------------------ - - beampipe_dimensions.push_back({ - .length = 200 * dd4hep::mm, // from VPC drawings - .innerXRadius = 200.0 * dd4hep::mm, - .innerYRadius = 125.0 * dd4hep::mm, - .rotationAngle = globRotationAngle - }); - - beampipe_dimensions[2].outerXRadius = beampipe_dimensions[2].innerXRadius + pipeThickness; - beampipe_dimensions[2].outerYRadius = beampipe_dimensions[2].innerYRadius + pipeThickness; - beampipe_dimensions[2].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[2].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[2].yCenter = 0.0; - beampipe_dimensions[2].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[2].length)*TMath::Cos(-globRotationAngle)); - - tmp_endpoint_z = beampipe_dimensions[2].zCenter+((0.5*beampipe_dimensions[2].length)*TMath::Cos(-globRotationAngle)); - tmp_endpoint_x = -1*beampipe_dimensions[2].xCenter+((0.5*beampipe_dimensions[2].length)*TMath::Sin(-globRotationAngle)); - - //------------------------------------------------------------------------------------ - //pipe between RP 1 and RP 2 stations - //rectangular cross-section!!!!! - //------------------------------------------------------------------------------------ - - - beampipe_dimensions.push_back({ - .length = 1500.0 * dd4hep::mm, // from VPC drawings - .innerXRadius = 150.0 * dd4hep::mm, - .innerYRadius = 30.0 * dd4hep::mm, - .rotationAngle = globRotationAngle - }); - - beampipe_dimensions[3].outerXRadius = beampipe_dimensions[3].innerXRadius + pipeThickness; - beampipe_dimensions[3].outerYRadius = beampipe_dimensions[3].innerYRadius + pipeThickness; - beampipe_dimensions[3].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[3].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[3].yCenter = 0.0; - beampipe_dimensions[3].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[3].length)*TMath::Cos(-globRotationAngle)); - - tmp_endpoint_z = beampipe_dimensions[3].zCenter+((0.5*beampipe_dimensions[3].length)*TMath::Cos(-globRotationAngle)); - tmp_endpoint_x = -1*beampipe_dimensions[3].xCenter+((0.5*beampipe_dimensions[3].length)*TMath::Sin(-globRotationAngle)); - - //------------------------------------------------------------------------------------ - //second roman pots scattering chamber - //------------------------------------------------------------------------------------ - - - beampipe_dimensions.push_back({ - .length = 200 * dd4hep::mm, // from VPC drawings - .innerXRadius = 200.0 * dd4hep::mm, - .innerYRadius = 125.0 * dd4hep::mm, - .rotationAngle = globRotationAngle - }); - - beampipe_dimensions[4].outerXRadius = beampipe_dimensions[4].innerXRadius + pipeThickness; - beampipe_dimensions[4].outerYRadius = beampipe_dimensions[4].innerYRadius + pipeThickness; - beampipe_dimensions[4].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[4].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[4].yCenter = 0.0; - beampipe_dimensions[4].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[4].length)*TMath::Cos(-globRotationAngle)); - - tmp_endpoint_z = beampipe_dimensions[4].zCenter+((0.5*beampipe_dimensions[4].length)*TMath::Cos(-globRotationAngle)); - tmp_endpoint_x = -1*beampipe_dimensions[4].xCenter+((0.5*beampipe_dimensions[4].length)*TMath::Sin(-globRotationAngle)); - - //------------------------------------------------------------------------------------ - // Pipe from second RP chamber to taper - //------------------------------------------------------------------------------------ - - - beampipe_dimensions.push_back({ - .length = 100.0 * dd4hep::mm, // from VPC drawings - .innerXRadius = 150.0 * dd4hep::mm, - .innerYRadius = 30.0 * dd4hep::mm, - .rotationAngle = globRotationAngle - }); - - beampipe_dimensions[5].outerXRadius = beampipe_dimensions[5].innerXRadius + pipeThickness; - beampipe_dimensions[5].outerYRadius = beampipe_dimensions[5].innerYRadius + pipeThickness; - beampipe_dimensions[5].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[5].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[5].yCenter = 0.0; - beampipe_dimensions[5].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[5].length)*TMath::Cos(-globRotationAngle)); - - tmp_endpoint_z = beampipe_dimensions[5].zCenter+((0.5*beampipe_dimensions[5].length)*TMath::Cos(-globRotationAngle)); - tmp_endpoint_x = -1*beampipe_dimensions[5].xCenter+((0.5*beampipe_dimensions[5].length)*TMath::Sin(-globRotationAngle)); - - //------------------------------------------------------------------------------------ - // taper near ZDC - //------------------------------------------------------------------------------------ - - - beampipe_dimensions.push_back({ - .length = 599.692 * dd4hep::mm, // from VPC drawings - .innerXRadius = 150.0 * dd4hep::mm, - .innerYRadius = 30.0 * dd4hep::mm, - .rotationAngle = globRotationAngle - - }); - - beampipe_dimensions[6].outerXRadius = beampipe_dimensions[6].innerXRadius + pipeThickness; - beampipe_dimensions[6].outerYRadius = beampipe_dimensions[6].innerYRadius + pipeThickness; - beampipe_dimensions[6].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[6].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[6].yCenter = 0.0; - beampipe_dimensions[6].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[6].length)*TMath::Cos(-globRotationAngle)); - - tmp_endpoint_z = beampipe_dimensions[6].zCenter+((0.5*beampipe_dimensions[6].length)*TMath::Cos(-globRotationAngle)); - tmp_endpoint_x = -1*beampipe_dimensions[6].xCenter+((0.5*beampipe_dimensions[6].length)*TMath::Sin(-globRotationAngle)); - - //------------------------------------------------------------------------------------ - // pipe connecting taper to B2PF magnet, just past ZDC - //------------------------------------------------------------------------------------ - - //numbers here are not really correct for the full taper, just for the opening - - beampipe_dimensions.push_back({ - .length = 3000.0 * dd4hep::mm, // from VPC drawings - .innerXRadius = 35.0 * dd4hep::mm, - .innerYRadius = 0.0, - .rotationAngle = globRotationAngle - }); - - beampipe_dimensions[7].outerXRadius = beampipe_dimensions[7].innerXRadius + pipeThickness; - beampipe_dimensions[7].outerYRadius = beampipe_dimensions[7].innerYRadius + pipeThickness; //NOT USED HERE - beampipe_dimensions[7].xCenter = -1*(tmp_endpoint_x+((0.5*beampipe_dimensions[7].length)*TMath::Sin(-globRotationAngle))); - beampipe_dimensions[7].yCenter = 0.0; - beampipe_dimensions[7].zCenter = tmp_endpoint_z+((0.5*beampipe_dimensions[7].length)*TMath::Cos(-globRotationAngle)); - - - //------------------------------------------ - //begin building main volumes here - //------------------------------------------ - - //------------------------------------------------------------------- - - int pieceIdx = 0; //Larger, rectangular pipe transporting proton and neutral envelopes (neutral exit window and transfer to smaller proton line at the end) - - Box pipeAfterB1APF_outer(beampipe_dimensions[pieceIdx].outerXRadius, beampipe_dimensions[pieceIdx].outerYRadius, beampipe_dimensions[pieceIdx].length/2); - Box pipeAfterB1APF_inner(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, (beampipe_dimensions[pieceIdx].length)/2); - Box pipeAfterB1APF_firstEndCap(beampipe_dimensions[pieceIdx].outerXRadius, beampipe_dimensions[pieceIdx].outerYRadius, 5.0/2.0); - Tube neutral_exit_window_cutout(0.0, windowRadius, 1.0); // 1.0cm thick - //FIXME: proton transfer window is done by hand right now - not a nicer way to do it until we get the CAD drawing - Box protonTransferWindow(155.0 * dd4hep::mm, beampipe_dimensions[1].outerYRadius, (5.0/2)); - - SubtractionSolid tmpAfterB1APF(pipeAfterB1APF_outer, pipeAfterB1APF_inner); //This gets rid of the inner portion of the pipe, but leaves the endcaps - tmpAfterB1APF = SubtractionSolid(tmpAfterB1APF, pipeAfterB1APF_firstEndCap, Position(0.0, 0.0, (-beampipe_dimensions[pieceIdx].length)/2)); - tmpAfterB1APF = SubtractionSolid(tmpAfterB1APF, protonTransferWindow, Position((-120.0 * dd4hep::mm), 0.0, (beampipe_dimensions[pieceIdx].length)/2 )); - tmpAfterB1APF = SubtractionSolid(tmpAfterB1APF, neutral_exit_window_cutout, Position(160.0 * dd4hep::mm, 0.0, 0.5*beampipe_dimensions[pieceIdx].length)); - - Volume v_pipeAfterB1APF(Form("v_pipeAfterB1APF_%d", pieceIdx), tmpAfterB1APF, m_SS); - sdet.setAttributes(det, v_pipeAfterB1APF, x_det.regionStr(), x_det.limitsStr(), vis_name); - - auto pv_pipe_0 = assembly.placeVolume(v_pipeAfterB1APF, Transform3D(RotationY(crossingAngle), Position(beampipe_dimensions[pieceIdx].xCenter + 4.0, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); // 2353.06094))); - pv_pipe_0.addPhysVolID("sector", 1); - DetElement pipe_de_0(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); - pipe_de_0.setPlacement(pv_pipe_0); - - //-------------------------------------------------------------------- - - double lengthDelta = 0.0; //over-length value to remove end-pieces for hollow rectangular pipes - - // 1 -- small pipe connecting big pipe to RP station 1 - // 2 -- roman pots scattering chamber 1 - // 3 -- small pipe connecting RP1 and RP2 - // 4 -- roman pots scattering chamber 2 - // 5 -- small pipe connecting RP2 to ZDC taper - - lengthDelta = 5.0; //for small beam pipes to remove endcaps - - for(int idx = 1; idx < 6; idx++){ //loop for the easier pieces to simplify - - if(idx == 2 || idx == 4){ continue;} - - Box outer(beampipe_dimensions[idx].outerXRadius, beampipe_dimensions[idx].outerYRadius, beampipe_dimensions[idx].length/2); - Box inner(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, (beampipe_dimensions[idx].length+lengthDelta)/2); - - SubtractionSolid hollow_pipe(outer, inner); - - Volume v_hollow_pipe(Form("v_pipe_%d", idx), hollow_pipe, m_SS); - sdet.setAttributes(det, v_hollow_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); - - auto pv_final = assembly.placeVolume(v_hollow_pipe, Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, beampipe_dimensions[idx].zCenter))); - pv_final.addPhysVolID("sector", 1); - DetElement final_de(sdet, Form("sector_pipe_%d_de", idx), 1); - final_de.setPlacement(pv_final); - +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) { + + using namespace ROOT::Math; + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + DetElement sdet(det_name, x_det.id()); + Assembly assembly(det_name + "_assembly"); + Material m_Al = det.material("Aluminum"); + Material m_Be = det.material("Beryllium"); + Material m_SS = det.material("StainlessSteel"); + Material m_vac = det.material("Vacuum"); + string vis_name = x_det.visStr(); + + PlacedVolume pv_assembly; + + double b0_hadron_tube_inner_r = 2.9 * dd4hep::cm; + double b0_hadron_tube_outer_r = 3.1 * dd4hep::cm; + double b0_hadron_tube_length = 120.0 * dd4hep::cm; + + double pipeThickness = 5.0 * dd4hep::mm; + + struct beampipe_dimensions_t { + Double_t length = 0.0; + Double_t innerXRadius = 0.0; + Double_t innerYRadius = 0.0; + Double_t outerXRadius = 0.0; + Double_t outerYRadius = 0.0; + Double_t xCenter = 0.0; + Double_t yCenter = 0.0; + Double_t zCenter = 0.0; + Double_t rotationAngle = 0.0; + }; + + std::vector beampipe_dimensions; + + double globRotationAngle = + -0.0454486856; //This is the angle of the proton orbit from the end of B1APF to the beginning of B2PF + double crossingAngle = -0.025; //relevant for the neutral cone + + double b1APFEndPoint_z = + 22062.3828 * dd4hep::mm; //location of proton orbit at b1APF exit -- in mm + double b1APFEndPoint_x = 654.3372 * dd4hep::mm; //location of proton orbit at b1APF exit -- in mm + + double tmp_endpoint_z = 0.0; + double tmp_endpoint_x = 0.0; + + //forumula -> Z = b1APFEndPoint_z+((0.5*elementLengt)*Cos(globRotationAngle)) + //forumula -> X = b1APFEndPoint_z+((0.5*elementLengt)*Sin(globRotationAngle)) + + //------------------------------------------------------------------------------------ + //Geometry extracted from version 0 VPC drawings shown at the FF preliminary + //design review in February 2024 -- CAD model not available as of April 1st, 2024 + //------------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------------ + //primary pipe after B1APF, before neutral exit window + transition to smaller pipe + //rectangular cross-section!!!!! + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({.length = 7615.486 * dd4hep::mm, //from VPC drawings, in mm + .innerXRadius = 275.0 * dd4hep::mm, + .innerYRadius = 175.0 * dd4hep::mm, + .rotationAngle = globRotationAngle}); + + beampipe_dimensions[0].outerXRadius = beampipe_dimensions[0].innerXRadius + pipeThickness; + beampipe_dimensions[0].outerYRadius = beampipe_dimensions[0].innerYRadius + pipeThickness; + beampipe_dimensions[0].xCenter = + -1 * + (b1APFEndPoint_x + ((0.5 * beampipe_dimensions[0].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[0].yCenter = 0.0; + beampipe_dimensions[0].zCenter = + (b1APFEndPoint_z + ((0.5 * beampipe_dimensions[0].length) * TMath::Cos(-globRotationAngle))); + + tmp_endpoint_z = beampipe_dimensions[0].zCenter + + ((0.5 * beampipe_dimensions[0].length) * TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1 * beampipe_dimensions[0].xCenter + + ((0.5 * beampipe_dimensions[0].length) * TMath::Sin(-globRotationAngle)); + + double windowRadius = 110.0 * dd4hep::mm; + + //------------------------------------------------------------------------------------ + //first small pipe section, between primary vessel and RP station 1 + //rectangular cross-section!!!!! + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({.length = 2780.273 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle}); + + beampipe_dimensions[1].outerXRadius = beampipe_dimensions[1].innerXRadius + pipeThickness; + beampipe_dimensions[1].outerYRadius = beampipe_dimensions[1].innerYRadius + pipeThickness; + beampipe_dimensions[1].xCenter = + -1 * + (tmp_endpoint_x + ((0.5 * beampipe_dimensions[1].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[1].yCenter = 0.0; + beampipe_dimensions[1].zCenter = + tmp_endpoint_z + ((0.5 * beampipe_dimensions[1].length) * TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[1].zCenter + + ((0.5 * beampipe_dimensions[1].length) * TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1 * beampipe_dimensions[1].xCenter + + ((0.5 * beampipe_dimensions[1].length) * TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + //First roman pots scattering chamber + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({.length = 200 * dd4hep::mm, // from VPC drawings + .innerXRadius = 200.0 * dd4hep::mm, + .innerYRadius = 125.0 * dd4hep::mm, + .rotationAngle = globRotationAngle}); + + beampipe_dimensions[2].outerXRadius = beampipe_dimensions[2].innerXRadius + pipeThickness; + beampipe_dimensions[2].outerYRadius = beampipe_dimensions[2].innerYRadius + pipeThickness; + beampipe_dimensions[2].xCenter = + -1 * + (tmp_endpoint_x + ((0.5 * beampipe_dimensions[2].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[2].yCenter = 0.0; + beampipe_dimensions[2].zCenter = + tmp_endpoint_z + ((0.5 * beampipe_dimensions[2].length) * TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[2].zCenter + + ((0.5 * beampipe_dimensions[2].length) * TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1 * beampipe_dimensions[2].xCenter + + ((0.5 * beampipe_dimensions[2].length) * TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + //pipe between RP 1 and RP 2 stations + //rectangular cross-section!!!!! + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({.length = 1500.0 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle}); + + beampipe_dimensions[3].outerXRadius = beampipe_dimensions[3].innerXRadius + pipeThickness; + beampipe_dimensions[3].outerYRadius = beampipe_dimensions[3].innerYRadius + pipeThickness; + beampipe_dimensions[3].xCenter = + -1 * + (tmp_endpoint_x + ((0.5 * beampipe_dimensions[3].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[3].yCenter = 0.0; + beampipe_dimensions[3].zCenter = + tmp_endpoint_z + ((0.5 * beampipe_dimensions[3].length) * TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[3].zCenter + + ((0.5 * beampipe_dimensions[3].length) * TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1 * beampipe_dimensions[3].xCenter + + ((0.5 * beampipe_dimensions[3].length) * TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + //second roman pots scattering chamber + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({.length = 200 * dd4hep::mm, // from VPC drawings + .innerXRadius = 200.0 * dd4hep::mm, + .innerYRadius = 125.0 * dd4hep::mm, + .rotationAngle = globRotationAngle}); + + beampipe_dimensions[4].outerXRadius = beampipe_dimensions[4].innerXRadius + pipeThickness; + beampipe_dimensions[4].outerYRadius = beampipe_dimensions[4].innerYRadius + pipeThickness; + beampipe_dimensions[4].xCenter = + -1 * + (tmp_endpoint_x + ((0.5 * beampipe_dimensions[4].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[4].yCenter = 0.0; + beampipe_dimensions[4].zCenter = + tmp_endpoint_z + ((0.5 * beampipe_dimensions[4].length) * TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[4].zCenter + + ((0.5 * beampipe_dimensions[4].length) * TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1 * beampipe_dimensions[4].xCenter + + ((0.5 * beampipe_dimensions[4].length) * TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + // Pipe from second RP chamber to taper + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({.length = 100.0 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle}); + + beampipe_dimensions[5].outerXRadius = beampipe_dimensions[5].innerXRadius + pipeThickness; + beampipe_dimensions[5].outerYRadius = beampipe_dimensions[5].innerYRadius + pipeThickness; + beampipe_dimensions[5].xCenter = + -1 * + (tmp_endpoint_x + ((0.5 * beampipe_dimensions[5].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[5].yCenter = 0.0; + beampipe_dimensions[5].zCenter = + tmp_endpoint_z + ((0.5 * beampipe_dimensions[5].length) * TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[5].zCenter + + ((0.5 * beampipe_dimensions[5].length) * TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1 * beampipe_dimensions[5].xCenter + + ((0.5 * beampipe_dimensions[5].length) * TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + // taper near ZDC + //------------------------------------------------------------------------------------ + + beampipe_dimensions.push_back({.length = 599.692 * dd4hep::mm, // from VPC drawings + .innerXRadius = 150.0 * dd4hep::mm, + .innerYRadius = 30.0 * dd4hep::mm, + .rotationAngle = globRotationAngle + + }); + + beampipe_dimensions[6].outerXRadius = beampipe_dimensions[6].innerXRadius + pipeThickness; + beampipe_dimensions[6].outerYRadius = beampipe_dimensions[6].innerYRadius + pipeThickness; + beampipe_dimensions[6].xCenter = + -1 * + (tmp_endpoint_x + ((0.5 * beampipe_dimensions[6].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[6].yCenter = 0.0; + beampipe_dimensions[6].zCenter = + tmp_endpoint_z + ((0.5 * beampipe_dimensions[6].length) * TMath::Cos(-globRotationAngle)); + + tmp_endpoint_z = beampipe_dimensions[6].zCenter + + ((0.5 * beampipe_dimensions[6].length) * TMath::Cos(-globRotationAngle)); + tmp_endpoint_x = -1 * beampipe_dimensions[6].xCenter + + ((0.5 * beampipe_dimensions[6].length) * TMath::Sin(-globRotationAngle)); + + //------------------------------------------------------------------------------------ + // pipe connecting taper to B2PF magnet, just past ZDC + //------------------------------------------------------------------------------------ + + //numbers here are not really correct for the full taper, just for the opening + + beampipe_dimensions.push_back({.length = 3000.0 * dd4hep::mm, // from VPC drawings + .innerXRadius = 35.0 * dd4hep::mm, + .innerYRadius = 0.0, + .rotationAngle = globRotationAngle}); + + beampipe_dimensions[7].outerXRadius = beampipe_dimensions[7].innerXRadius + pipeThickness; + beampipe_dimensions[7].outerYRadius = + beampipe_dimensions[7].innerYRadius + pipeThickness; //NOT USED HERE + beampipe_dimensions[7].xCenter = + -1 * + (tmp_endpoint_x + ((0.5 * beampipe_dimensions[7].length) * TMath::Sin(-globRotationAngle))); + beampipe_dimensions[7].yCenter = 0.0; + beampipe_dimensions[7].zCenter = + tmp_endpoint_z + ((0.5 * beampipe_dimensions[7].length) * TMath::Cos(-globRotationAngle)); + + //------------------------------------------ + //begin building main volumes here + //------------------------------------------ + + //------------------------------------------------------------------- + + int pieceIdx = + 0; //Larger, rectangular pipe transporting proton and neutral envelopes (neutral exit window and transfer to smaller proton line at the end) + + Box pipeAfterB1APF_outer(beampipe_dimensions[pieceIdx].outerXRadius, + beampipe_dimensions[pieceIdx].outerYRadius, + beampipe_dimensions[pieceIdx].length / 2); + Box pipeAfterB1APF_inner(beampipe_dimensions[pieceIdx].innerXRadius, + beampipe_dimensions[pieceIdx].innerYRadius, + (beampipe_dimensions[pieceIdx].length) / 2); + Box pipeAfterB1APF_firstEndCap(beampipe_dimensions[pieceIdx].outerXRadius, + beampipe_dimensions[pieceIdx].outerYRadius, 5.0 / 2.0); + Tube neutral_exit_window_cutout(0.0, windowRadius, 1.0); // 1.0cm thick + //FIXME: proton transfer window is done by hand right now - not a nicer way to do it until we get the CAD drawing + Box protonTransferWindow(155.0 * dd4hep::mm, beampipe_dimensions[1].outerYRadius, (5.0 / 2)); + + SubtractionSolid tmpAfterB1APF( + pipeAfterB1APF_outer, + pipeAfterB1APF_inner); //This gets rid of the inner portion of the pipe, but leaves the endcaps + tmpAfterB1APF = SubtractionSolid(tmpAfterB1APF, pipeAfterB1APF_firstEndCap, + Position(0.0, 0.0, (-beampipe_dimensions[pieceIdx].length) / 2)); + tmpAfterB1APF = SubtractionSolid( + tmpAfterB1APF, protonTransferWindow, + Position((-120.0 * dd4hep::mm), 0.0, (beampipe_dimensions[pieceIdx].length) / 2)); + tmpAfterB1APF = SubtractionSolid( + tmpAfterB1APF, neutral_exit_window_cutout, + Position(160.0 * dd4hep::mm, 0.0, 0.5 * beampipe_dimensions[pieceIdx].length)); + + Volume v_pipeAfterB1APF(Form("v_pipeAfterB1APF_%d", pieceIdx), tmpAfterB1APF, m_SS); + sdet.setAttributes(det, v_pipeAfterB1APF, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_0 = assembly.placeVolume( + v_pipeAfterB1APF, + Transform3D(RotationY(crossingAngle), + Position(beampipe_dimensions[pieceIdx].xCenter + 4.0, + beampipe_dimensions[pieceIdx].yCenter, + beampipe_dimensions[pieceIdx].zCenter))); // 2353.06094))); + pv_pipe_0.addPhysVolID("sector", 1); + DetElement pipe_de_0(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_0.setPlacement(pv_pipe_0); + + //-------------------------------------------------------------------- + + double lengthDelta = 0.0; //over-length value to remove end-pieces for hollow rectangular pipes + + // 1 -- small pipe connecting big pipe to RP station 1 + // 2 -- roman pots scattering chamber 1 + // 3 -- small pipe connecting RP1 and RP2 + // 4 -- roman pots scattering chamber 2 + // 5 -- small pipe connecting RP2 to ZDC taper + + lengthDelta = 5.0; //for small beam pipes to remove endcaps + + for (int idx = 1; idx < 6; idx++) { //loop for the easier pieces to simplify + + if (idx == 2 || idx == 4) { + continue; } - lengthDelta = 0.0; //not needed for scattering chambers - - for(int idx = 1; idx < 6; idx++){ //loop for the easier pieces to simplify + Box outer(beampipe_dimensions[idx].outerXRadius, beampipe_dimensions[idx].outerYRadius, + beampipe_dimensions[idx].length / 2); + Box inner(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, + (beampipe_dimensions[idx].length + lengthDelta) / 2); - if(idx == 1 || idx == 3 || idx == 5){ continue;} + SubtractionSolid hollow_pipe(outer, inner); - Box outer(beampipe_dimensions[idx].outerXRadius, beampipe_dimensions[idx].outerYRadius, beampipe_dimensions[idx].length/2); - Box inner(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, (beampipe_dimensions[idx].length+lengthDelta)/2); - Box RP_subtract_outer(beampipe_dimensions[1].outerXRadius, beampipe_dimensions[1].outerYRadius, (beampipe_dimensions[2].length+5.0)/2); + Volume v_hollow_pipe(Form("v_pipe_%d", idx), hollow_pipe, m_SS); + sdet.setAttributes(det, v_hollow_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); - SubtractionSolid hollow_pipe(outer, inner); - hollow_pipe = SubtractionSolid(hollow_pipe, RP_subtract_outer); + auto pv_final = assembly.placeVolume( + v_hollow_pipe, + Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), + Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, + beampipe_dimensions[idx].zCenter))); + pv_final.addPhysVolID("sector", 1); + DetElement final_de(sdet, Form("sector_pipe_%d_de", idx), 1); + final_de.setPlacement(pv_final); + } - Volume v_hollow_pipe(Form("v_pipe_%d", idx), hollow_pipe, m_SS); - sdet.setAttributes(det, v_hollow_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); + lengthDelta = 0.0; //not needed for scattering chambers - auto pv_final = assembly.placeVolume(v_hollow_pipe, Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, beampipe_dimensions[idx].zCenter))); - pv_final.addPhysVolID("sector", 1); - DetElement final_de(sdet, Form("sector_pipe_%d_de", idx), 1); - final_de.setPlacement(pv_final); + for (int idx = 1; idx < 6; idx++) { //loop for the easier pieces to simplify + if (idx == 1 || idx == 3 || idx == 5) { + continue; } - //---------------------------------------------------------------- + Box outer(beampipe_dimensions[idx].outerXRadius, beampipe_dimensions[idx].outerYRadius, + beampipe_dimensions[idx].length / 2); + Box inner(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, + (beampipe_dimensions[idx].length + lengthDelta) / 2); + Box RP_subtract_outer(beampipe_dimensions[1].outerXRadius, beampipe_dimensions[1].outerYRadius, + (beampipe_dimensions[2].length + 5.0) / 2); - pieceIdx = 6; + SubtractionSolid hollow_pipe(outer, inner); + hollow_pipe = SubtractionSolid(hollow_pipe, RP_subtract_outer); - Double_t trpVertices[16]; - Double_t trpVerticesInner[16]; - //(x0, y0, x1, y1, ... , x7, y7) - //opening side - larger size - trpVertices[0] = -beampipe_dimensions[6].outerXRadius; - trpVertices[1] = -beampipe_dimensions[6].outerYRadius; + Volume v_hollow_pipe(Form("v_pipe_%d", idx), hollow_pipe, m_SS); + sdet.setAttributes(det, v_hollow_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); - trpVertices[2] = -beampipe_dimensions[6].outerXRadius; - trpVertices[3] = beampipe_dimensions[6].outerYRadius; + auto pv_final = assembly.placeVolume( + v_hollow_pipe, + Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), + Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, + beampipe_dimensions[idx].zCenter))); + pv_final.addPhysVolID("sector", 1); + DetElement final_de(sdet, Form("sector_pipe_%d_de", idx), 1); + final_de.setPlacement(pv_final); + } - trpVertices[4] = beampipe_dimensions[6].outerXRadius; - trpVertices[5] = beampipe_dimensions[6].outerYRadius; + //---------------------------------------------------------------- - trpVertices[6] = beampipe_dimensions[6].outerXRadius; - trpVertices[7] = -beampipe_dimensions[6].outerYRadius; + pieceIdx = 6; - //exiting side - smaller size + Double_t trpVertices[16]; + Double_t trpVerticesInner[16]; + //(x0, y0, x1, y1, ... , x7, y7) + //opening side - larger size + trpVertices[0] = -beampipe_dimensions[6].outerXRadius; + trpVertices[1] = -beampipe_dimensions[6].outerYRadius; - trpVertices[8] = -beampipe_dimensions[6].outerYRadius; - trpVertices[9] = -beampipe_dimensions[6].outerYRadius; + trpVertices[2] = -beampipe_dimensions[6].outerXRadius; + trpVertices[3] = beampipe_dimensions[6].outerYRadius; - trpVertices[10] = -beampipe_dimensions[6].outerYRadius; - trpVertices[11] = beampipe_dimensions[6].outerYRadius; + trpVertices[4] = beampipe_dimensions[6].outerXRadius; + trpVertices[5] = beampipe_dimensions[6].outerYRadius; - trpVertices[12] = beampipe_dimensions[6].outerYRadius; - trpVertices[13] = beampipe_dimensions[6].outerYRadius; - - trpVertices[14] = beampipe_dimensions[6].outerYRadius; - trpVertices[15] = -beampipe_dimensions[6].outerYRadius; - - for(int i = 0; i < 16; i++){ - - if(trpVertices[i] > 0.0){trpVerticesInner[i] = trpVertices[i]-(pipeThickness);} - if(trpVertices[i] < 0.0){trpVerticesInner[i] = trpVertices[i]+(pipeThickness);} - - } + trpVertices[6] = beampipe_dimensions[6].outerXRadius; + trpVertices[7] = -beampipe_dimensions[6].outerYRadius; - EightPointSolid taper_outer((0.5*beampipe_dimensions[pieceIdx].length), trpVertices); - EightPointSolid taper_inner((0.5*beampipe_dimensions[pieceIdx].length), trpVerticesInner); + //exiting side - smaller size - Box taper_entrance(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, (0.5*(pipeThickness + 5.0))); - Box taper_exit(beampipe_dimensions[pieceIdx].innerYRadius, beampipe_dimensions[pieceIdx].innerYRadius, (0.5*(pipeThickness + 5.0))); - SubtractionSolid hollowTaper(taper_outer, taper_inner); - hollowTaper = SubtractionSolid(hollowTaper, taper_entrance, Position(0.0, 0.0, (-0.5*beampipe_dimensions[pieceIdx].length))); - hollowTaper = SubtractionSolid(hollowTaper, taper_exit, Position(0.0, 0.0, (0.5*beampipe_dimensions[pieceIdx].length))); + trpVertices[8] = -beampipe_dimensions[6].outerYRadius; + trpVertices[9] = -beampipe_dimensions[6].outerYRadius; - Volume v_taper(Form("v_taper_%d", pieceIdx), hollowTaper, m_SS); - sdet.setAttributes(det, v_taper, x_det.regionStr(), x_det.limitsStr(), vis_name); + trpVertices[10] = -beampipe_dimensions[6].outerYRadius; + trpVertices[11] = beampipe_dimensions[6].outerYRadius; - auto pv_pipe_6 = assembly.placeVolume(v_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position(beampipe_dimensions[pieceIdx].xCenter, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); - pv_pipe_6.addPhysVolID("sector", 1); - DetElement pipe_de_6(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); - pipe_de_6.setPlacement(pv_pipe_6); + trpVertices[12] = beampipe_dimensions[6].outerYRadius; + trpVertices[13] = beampipe_dimensions[6].outerYRadius; - //--------------------------------------------------------------- + trpVertices[14] = beampipe_dimensions[6].outerYRadius; + trpVertices[15] = -beampipe_dimensions[6].outerYRadius; - pieceIdx = 7; //pipe between taper and B2PF - - Tube pipe_after_taper(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].outerXRadius, beampipe_dimensions[pieceIdx].length/2); - - Volume v_pipe_7(Form("v_pipe_7_%d", pieceIdx), pipe_after_taper, m_SS); - sdet.setAttributes(det, v_pipe_7, x_det.regionStr(), x_det.limitsStr(), vis_name); - - auto pv_pipe_7 = assembly.placeVolume(v_pipe_7, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position(beampipe_dimensions[pieceIdx].xCenter, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); // 2353.06094))); - pv_pipe_7.addPhysVolID("sector", 1); - DetElement pipe_de_7(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); - pipe_de_7.setPlacement(pv_pipe_7); - - - //-------------------------------------------------------------- - // This is the beam tube in the B0 magnet for the hadron beam - // doesn't use the slope information calculated before - it stands alone - - pieceIdx = 8; - - Tube b0_hadron_tube(b0_hadron_tube_inner_r, b0_hadron_tube_outer_r, b0_hadron_tube_length / 2.0); - Volume v_b0_hadron_tube("v_b0_hadron_tube", b0_hadron_tube, m_Be); - sdet.setAttributes(det, v_b0_hadron_tube, x_det.regionStr(), x_det.limitsStr(), vis_name); - - auto pv_pipe_8 = assembly.placeVolume(v_b0_hadron_tube, Transform3D(RotationY(crossingAngle), Position(-16.5, 0.0, 640.0))); // 2353.06094))); - pv_pipe_8.addPhysVolID("sector", 1); - DetElement pipe_de_8(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); - pipe_de_8.setPlacement(pv_pipe_6); - - //---------------------------------------------------------------- - - pieceIdx = 9; //neutral exit window - - Box pipeAfterB1APF_LARGE((beampipe_dimensions[0].outerXRadius+5.0), (beampipe_dimensions[0].outerYRadius+5.0), (beampipe_dimensions[0].length+5.0)/2); - Tube neutral_exit_window(0.0, windowRadius, 1.0); // 1.0cm thick - - IntersectionSolid finalWindow(pipeAfterB1APF_outer, neutral_exit_window, Position(160.0 * dd4hep::mm, 0.0, 0.5*beampipe_dimensions[0].length)); - - Volume v_neutral_exit_window("v_neutral_exit_window", finalWindow, m_Al); - sdet.setAttributes(det, v_neutral_exit_window, x_det.regionStr(), x_det.limitsStr(), "AnlRed"); - - auto pv_pipe_9 = assembly.placeVolume(v_neutral_exit_window, Transform3D(RotationY(crossingAngle), Position( beampipe_dimensions[0].xCenter + 4.0, 0.0, beampipe_dimensions[0].zCenter))); - pv_pipe_9.addPhysVolID("sector", 1); - DetElement pipe_de_9(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); - pipe_de_9.setPlacement(pv_pipe_9); - - //----------------------------------------------------------------- - // Build vacuum volumes here - //----------------------------------------------------------------- - - pieceIdx = 0; - - Box vacuum_main_pipe(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, (beampipe_dimensions[pieceIdx].length-2.0)/2); - Box cutout_for_OMD_station(beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].innerYRadius, 2.0); - - SubtractionSolid final_vacuum_main_pipe(vacuum_main_pipe, cutout_for_OMD_station, Position(0.0, 0.0, (2251.0 - beampipe_dimensions[pieceIdx].zCenter))); - final_vacuum_main_pipe = SubtractionSolid(final_vacuum_main_pipe, cutout_for_OMD_station, Position(0.0, 0.0, (2451.0 - beampipe_dimensions[pieceIdx].zCenter))); - - Volume v_vacuum_main_pipe("v_vacuum_main_pipe", final_vacuum_main_pipe, m_vac); - sdet.setAttributes(det, v_vacuum_main_pipe, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); - - auto pv_vacuum_0 = assembly.placeVolume(v_vacuum_main_pipe, Transform3D(RotationY(crossingAngle), Position( beampipe_dimensions[pieceIdx].xCenter + 4.0, 0.0, beampipe_dimensions[pieceIdx].zCenter))); - pv_vacuum_0.addPhysVolID("sector", 1); - DetElement vacuum_de_0(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); - vacuum_de_0.setPlacement(pv_vacuum_0); - - //------------------------------------------------------------------ - - for(int idx = 1; idx < 6; idx++){ //loop for the easier pieces to simplify - - if(idx == 2 || idx == 4){ continue;} //FIXME: don't fill RP chambers with vacuum yet - still an issue with RP geometry - - Box inner_vacuum(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, (beampipe_dimensions[idx].length)/2); - - Volume v_inner_vacuum(Form("v_vacuum_%d", idx), inner_vacuum, m_vac); - sdet.setAttributes(det, v_inner_vacuum, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); - - auto pv_final = assembly.placeVolume(v_inner_vacuum, Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, beampipe_dimensions[idx].zCenter))); - pv_final.addPhysVolID("sector", 1); - DetElement final_de(sdet, Form("sector_FF_vacuum_%d_de", idx), 1); - final_de.setPlacement(pv_final); + for (int i = 0; i < 16; i++) { + if (trpVertices[i] > 0.0) { + trpVerticesInner[i] = trpVertices[i] - (pipeThickness); } - - //------------------------------------------------------------------ - - pieceIdx = 6; - - EightPointSolid vacuum_taper((0.5*beampipe_dimensions[pieceIdx].length), trpVerticesInner); - - Volume v_vacuum_taper("v_vacuum_taper", vacuum_taper, m_vac); - sdet.setAttributes(det, v_vacuum_taper, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); - - auto pv_vacuum_6 = assembly.placeVolume(v_vacuum_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position( beampipe_dimensions[pieceIdx].xCenter, 0.0, beampipe_dimensions[pieceIdx].zCenter))); - pv_vacuum_6.addPhysVolID("sector", 1); - DetElement vacuum_de_6(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); - vacuum_de_6.setPlacement(pv_vacuum_6); - - //------------------------------------------------------------------- - - pieceIdx = 7; //vacuum between taper and B2PF - - Tube vacuum_pipe_after_taper(0.0, beampipe_dimensions[pieceIdx].innerXRadius, beampipe_dimensions[pieceIdx].length/2); - - Volume v_vacuum_pipe_after_taper("v_vacuum_pipe_after_taper", vacuum_pipe_after_taper, m_vac); - sdet.setAttributes(det, v_vacuum_pipe_after_taper, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); - - auto pv_vacuum_7 = assembly.placeVolume(v_vacuum_pipe_after_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), Position(beampipe_dimensions[pieceIdx].xCenter, beampipe_dimensions[pieceIdx].yCenter, beampipe_dimensions[pieceIdx].zCenter))); - pv_vacuum_7.addPhysVolID("sector", 1); - DetElement vacuum_de_7(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); - vacuum_de_7.setPlacement(pv_vacuum_7); - - //------------------------------------------------------------------- - - pv_assembly = det.pickMotherVolume(sdet).placeVolume(assembly); - pv_assembly.addPhysVolID("system", x_det.id()).addPhysVolID("barrel", 1); - sdet.setPlacement(pv_assembly); - assembly->GetShape()->ComputeBBox(); - return sdet; + if (trpVertices[i] < 0.0) { + trpVerticesInner[i] = trpVertices[i] + (pipeThickness); + } + } + + EightPointSolid taper_outer((0.5 * beampipe_dimensions[pieceIdx].length), trpVertices); + EightPointSolid taper_inner((0.5 * beampipe_dimensions[pieceIdx].length), trpVerticesInner); + + Box taper_entrance(beampipe_dimensions[pieceIdx].innerXRadius, + beampipe_dimensions[pieceIdx].innerYRadius, (0.5 * (pipeThickness + 5.0))); + Box taper_exit(beampipe_dimensions[pieceIdx].innerYRadius, + beampipe_dimensions[pieceIdx].innerYRadius, (0.5 * (pipeThickness + 5.0))); + SubtractionSolid hollowTaper(taper_outer, taper_inner); + hollowTaper = SubtractionSolid(hollowTaper, taper_entrance, + Position(0.0, 0.0, (-0.5 * beampipe_dimensions[pieceIdx].length))); + hollowTaper = SubtractionSolid(hollowTaper, taper_exit, + Position(0.0, 0.0, (0.5 * beampipe_dimensions[pieceIdx].length))); + + Volume v_taper(Form("v_taper_%d", pieceIdx), hollowTaper, m_SS); + sdet.setAttributes(det, v_taper, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_6 = assembly.placeVolume( + v_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), + Position(beampipe_dimensions[pieceIdx].xCenter, + beampipe_dimensions[pieceIdx].yCenter, + beampipe_dimensions[pieceIdx].zCenter))); + pv_pipe_6.addPhysVolID("sector", 1); + DetElement pipe_de_6(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_6.setPlacement(pv_pipe_6); + + //--------------------------------------------------------------- + + pieceIdx = 7; //pipe between taper and B2PF + + Tube pipe_after_taper(beampipe_dimensions[pieceIdx].innerXRadius, + beampipe_dimensions[pieceIdx].outerXRadius, + beampipe_dimensions[pieceIdx].length / 2); + + Volume v_pipe_7(Form("v_pipe_7_%d", pieceIdx), pipe_after_taper, m_SS); + sdet.setAttributes(det, v_pipe_7, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_7 = assembly.placeVolume( + v_pipe_7, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), + Position(beampipe_dimensions[pieceIdx].xCenter, + beampipe_dimensions[pieceIdx].yCenter, + beampipe_dimensions[pieceIdx].zCenter))); // 2353.06094))); + pv_pipe_7.addPhysVolID("sector", 1); + DetElement pipe_de_7(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_7.setPlacement(pv_pipe_7); + + //-------------------------------------------------------------- + // This is the beam tube in the B0 magnet for the hadron beam + // doesn't use the slope information calculated before - it stands alone + + pieceIdx = 8; + + Tube b0_hadron_tube(b0_hadron_tube_inner_r, b0_hadron_tube_outer_r, b0_hadron_tube_length / 2.0); + Volume v_b0_hadron_tube("v_b0_hadron_tube", b0_hadron_tube, m_Be); + sdet.setAttributes(det, v_b0_hadron_tube, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe_8 = assembly.placeVolume( + v_b0_hadron_tube, + Transform3D(RotationY(crossingAngle), Position(-16.5, 0.0, 640.0))); // 2353.06094))); + pv_pipe_8.addPhysVolID("sector", 1); + DetElement pipe_de_8(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_8.setPlacement(pv_pipe_6); + + //---------------------------------------------------------------- + + pieceIdx = 9; //neutral exit window + + Box pipeAfterB1APF_LARGE((beampipe_dimensions[0].outerXRadius + 5.0), + (beampipe_dimensions[0].outerYRadius + 5.0), + (beampipe_dimensions[0].length + 5.0) / 2); + Tube neutral_exit_window(0.0, windowRadius, 1.0); // 1.0cm thick + + IntersectionSolid finalWindow( + pipeAfterB1APF_outer, neutral_exit_window, + Position(160.0 * dd4hep::mm, 0.0, 0.5 * beampipe_dimensions[0].length)); + + Volume v_neutral_exit_window("v_neutral_exit_window", finalWindow, m_Al); + sdet.setAttributes(det, v_neutral_exit_window, x_det.regionStr(), x_det.limitsStr(), "AnlRed"); + + auto pv_pipe_9 = assembly.placeVolume( + v_neutral_exit_window, + Transform3D(RotationY(crossingAngle), Position(beampipe_dimensions[0].xCenter + 4.0, 0.0, + beampipe_dimensions[0].zCenter))); + pv_pipe_9.addPhysVolID("sector", 1); + DetElement pipe_de_9(sdet, Form("sector_pipe_%d_de", pieceIdx), 1); + pipe_de_9.setPlacement(pv_pipe_9); + + //----------------------------------------------------------------- + // Build vacuum volumes here + //----------------------------------------------------------------- + + pieceIdx = 0; + + Box vacuum_main_pipe(beampipe_dimensions[pieceIdx].innerXRadius, + beampipe_dimensions[pieceIdx].innerYRadius, + (beampipe_dimensions[pieceIdx].length - 2.0) / 2); + Box cutout_for_OMD_station(beampipe_dimensions[pieceIdx].innerXRadius, + beampipe_dimensions[pieceIdx].innerYRadius, 2.0); + + SubtractionSolid final_vacuum_main_pipe( + vacuum_main_pipe, cutout_for_OMD_station, + Position(0.0, 0.0, (2251.0 - beampipe_dimensions[pieceIdx].zCenter))); + final_vacuum_main_pipe = + SubtractionSolid(final_vacuum_main_pipe, cutout_for_OMD_station, + Position(0.0, 0.0, (2451.0 - beampipe_dimensions[pieceIdx].zCenter))); + + Volume v_vacuum_main_pipe("v_vacuum_main_pipe", final_vacuum_main_pipe, m_vac); + sdet.setAttributes(det, v_vacuum_main_pipe, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_vacuum_0 = assembly.placeVolume( + v_vacuum_main_pipe, + Transform3D(RotationY(crossingAngle), Position(beampipe_dimensions[pieceIdx].xCenter + 4.0, + 0.0, beampipe_dimensions[pieceIdx].zCenter))); + pv_vacuum_0.addPhysVolID("sector", 1); + DetElement vacuum_de_0(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); + vacuum_de_0.setPlacement(pv_vacuum_0); + + //------------------------------------------------------------------ + + for (int idx = 1; idx < 6; idx++) { //loop for the easier pieces to simplify + + if (idx == 2 || idx == 4) { + continue; + } //FIXME: don't fill RP chambers with vacuum yet - still an issue with RP geometry + + Box inner_vacuum(beampipe_dimensions[idx].innerXRadius, beampipe_dimensions[idx].innerYRadius, + (beampipe_dimensions[idx].length) / 2); + + Volume v_inner_vacuum(Form("v_vacuum_%d", idx), inner_vacuum, m_vac); + sdet.setAttributes(det, v_inner_vacuum, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_final = assembly.placeVolume( + v_inner_vacuum, + Transform3D(RotationY(beampipe_dimensions[idx].rotationAngle), + Position(beampipe_dimensions[idx].xCenter, beampipe_dimensions[idx].yCenter, + beampipe_dimensions[idx].zCenter))); + pv_final.addPhysVolID("sector", 1); + DetElement final_de(sdet, Form("sector_FF_vacuum_%d_de", idx), 1); + final_de.setPlacement(pv_final); + } + + //------------------------------------------------------------------ + + pieceIdx = 6; + + EightPointSolid vacuum_taper((0.5 * beampipe_dimensions[pieceIdx].length), trpVerticesInner); + + Volume v_vacuum_taper("v_vacuum_taper", vacuum_taper, m_vac); + sdet.setAttributes(det, v_vacuum_taper, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_vacuum_6 = assembly.placeVolume( + v_vacuum_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), + Position(beampipe_dimensions[pieceIdx].xCenter, 0.0, + beampipe_dimensions[pieceIdx].zCenter))); + pv_vacuum_6.addPhysVolID("sector", 1); + DetElement vacuum_de_6(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); + vacuum_de_6.setPlacement(pv_vacuum_6); + + //------------------------------------------------------------------- + + pieceIdx = 7; //vacuum between taper and B2PF + + Tube vacuum_pipe_after_taper(0.0, beampipe_dimensions[pieceIdx].innerXRadius, + beampipe_dimensions[pieceIdx].length / 2); + + Volume v_vacuum_pipe_after_taper("v_vacuum_pipe_after_taper", vacuum_pipe_after_taper, m_vac); + sdet.setAttributes(det, v_vacuum_pipe_after_taper, x_det.regionStr(), x_det.limitsStr(), + "AnlBlue"); + + auto pv_vacuum_7 = assembly.placeVolume( + v_vacuum_pipe_after_taper, Transform3D(RotationY(beampipe_dimensions[pieceIdx].rotationAngle), + Position(beampipe_dimensions[pieceIdx].xCenter, + beampipe_dimensions[pieceIdx].yCenter, + beampipe_dimensions[pieceIdx].zCenter))); + pv_vacuum_7.addPhysVolID("sector", 1); + DetElement vacuum_de_7(sdet, Form("sector_FF_vacuum_%d_de", pieceIdx), 1); + vacuum_de_7.setPlacement(pv_vacuum_7); + + //------------------------------------------------------------------- + + pv_assembly = det.pickMotherVolume(sdet).placeVolume(assembly); + pv_assembly.addPhysVolID("system", x_det.id()).addPhysVolID("barrel", 1); + sdet.setPlacement(pv_assembly); + assembly->GetShape()->ComputeBBox(); + return sdet; } DECLARE_DETELEMENT(forwardBeamPipeBrazil, create_detector) diff --git a/src/hadronDownstreamBeamPipe.cpp b/src/hadronDownstreamBeamPipe.cpp index adabee854..a14b995e0 100644 --- a/src/hadronDownstreamBeamPipe.cpp +++ b/src/hadronDownstreamBeamPipe.cpp @@ -31,21 +31,20 @@ using namespace dd4hep; * \endcode * */ -static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) -{ +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) { using namespace ROOT::Math; - xml_det_t x_det = e; - string det_name = x_det.nameStr(); + xml_det_t x_det = e; + string det_name = x_det.nameStr(); // Material air = det.air(); DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); + Assembly assembly(det_name + "_assembly"); // Material m_Cu = det.material("Copper"); // Material m_Al = det.material("Aluminum"); - Material m_Be = det.material("Beryllium"); - Material m_SS = det.material("StainlessSteel"); - Material m_vac = det.material("Vacuum"); - string vis_name = x_det.visStr(); + Material m_Be = det.material("Beryllium"); + Material m_SS = det.material("StainlessSteel"); + Material m_vac = det.material("Vacuum"); + string vis_name = x_det.visStr(); PlacedVolume pv_assembly; @@ -54,12 +53,10 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * //int numPipePieces = 4; //number of individual pipe sections - double b0_hadron_tube_inner_r = 2.9; // cm double b0_hadron_tube_outer_r = 3.1; // cm double b0_hadron_tube_length = 120.0; // cm - double drift_hadron_section_1_inner_r = 20.0; double drift_hadron_section_1_outer_r = 20.2; @@ -81,23 +78,22 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * //Calculatate full drift region from line formula for proton orbit - //(z, x) + //(z, x) //double orbit_start[2] = {22.0623828, -0.6543372}; //meters! //double orbit_end[2] = {38.5445361, -1.4039456}; //meters! - //22.07774534 + //22.07774534 double orbit_start[2] = {22.07774534, -0.650777226}; //meters - double orbit_end[2] = {38.54362489, -1.436245325}; //meters + double orbit_end[2] = {38.54362489, -1.436245325}; //meters //calculate straight line formula x = slope*z + intercept - double slope = (orbit_end[1]-orbit_start[1])/(orbit_end[0]-orbit_start[0]); - double intercept = orbit_start[1]-(slope*orbit_start[0]); - + double slope = (orbit_end[1] - orbit_start[1]) / (orbit_end[0] - orbit_start[0]); + double intercept = orbit_start[1] - (slope * orbit_start[0]); // This is the beam tube in the B0 magnet for the hadron beam // doesn't use the slope information calculated before - it stands alone - Tube b0_hadron_tube(b0_hadron_tube_inner_r, b0_hadron_tube_outer_r, b0_hadron_tube_length / 2.0); + Tube b0_hadron_tube(b0_hadron_tube_inner_r, b0_hadron_tube_outer_r, b0_hadron_tube_length / 2.0); Volume v_b0_hadron_tube("v_b0_hadron_tube", b0_hadron_tube, m_Be); sdet.setAttributes(det, v_b0_hadron_tube, x_det.regionStr(), x_det.limitsStr(), vis_name); @@ -105,70 +101,73 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * // build drift beam pipe here //---------------------------------- - double z_start_pipe[3] = {orbit_start[0], 30.000, 31.500 }; - double z_end_pipe[3] = {30.000, 31.500, 40.000 }; - - - for(int iSection = 0; iSection < 3; iSection++){ - - double z_endpoint = z_end_pipe[iSection]; //meters - double x_endpoint = (slope*z_endpoint) + intercept; - double x_startpoint = (slope*z_start_pipe[iSection]) + intercept; - - double length = sqrt(pow(z_endpoint - z_start_pipe[iSection],2) + pow(x_endpoint - x_startpoint,2)); - double z_center = (0.5*length + z_start_pipe[iSection])*cos(slope); - double x_center = (slope*z_center) + intercept; - - double entrance_r_inner = 0.0; //drift_hadron_section_1_inner_r; - double exit_radius_inner = 0.0; - double entrance_r_outer = 0.0; //drift_hadron_section_1_inner_r; - double exit_radius_outer = 0.0; - - if(iSection < 1){ - entrance_r_inner = drift_hadron_section_1_inner_r; - exit_radius_inner = drift_hadron_section_1_inner_r; - entrance_r_outer = drift_hadron_section_1_outer_r; - exit_radius_outer = drift_hadron_section_1_outer_r; - length = length - 0.04; - } - if(iSection == 1){ - entrance_r_inner = drift_hadron_section_3_inner_r_ent; - exit_radius_inner = drift_hadron_section_3_inner_r_ex; - entrance_r_outer = drift_hadron_section_3_outer_r_ent; - exit_radius_outer = drift_hadron_section_3_outer_r_ex; - drift_hadron_section_3_x = x_center; - drift_hadron_section_3_z = z_center; - drift_hadron_section_3_length = length - 0.02; - //old numbers commented out for reference - A. Jentsch - //length = length - 0.02; - //x_center = -99.25250431/100.0; - //z_center = 2924.185347/100.0; - //length = drift_hadron_section_3_length/100.0; - } - if(iSection == 2){ - entrance_r_inner = drift_hadron_section_4_inner_r; - exit_radius_inner = drift_hadron_section_4_inner_r; - entrance_r_outer = drift_hadron_section_4_outer_r; - exit_radius_outer = drift_hadron_section_4_outer_r; - drift_hadron_section_4_x = x_center; - drift_hadron_section_4_z = z_center; - drift_hadron_section_4_length = length - 0.02; - length = length - 0.02; - //old numbers commented out for reference - A. Jentsch - // x_center = -123.076799/100.0; - // z_center = 3423.617428/100.0; - //length = drift_hadron_section_4_length/100.0; - } - - Cone drift_pipe((length*100.0) / 2.0, entrance_r_inner, entrance_r_outer, exit_radius_inner, exit_radius_outer); - - Volume v_pipe(Form("v_drift_tube_pipe_%d", iSection), drift_pipe, m_SS); - sdet.setAttributes(det, v_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); - - auto pv_pipe = assembly.placeVolume(v_pipe, Transform3D(RotationY(slope), Position(100.0*x_center, 0.0, 100.0*z_center))); // 2353.06094))); - pv_pipe.addPhysVolID("sector", 1); - DetElement pipe_de(sdet, Form("sector_pipe_%d_de", iSection), 1); - pipe_de.setPlacement(pv_pipe); + double z_start_pipe[3] = {orbit_start[0], 30.000, 31.500}; + double z_end_pipe[3] = {30.000, 31.500, 40.000}; + + for (int iSection = 0; iSection < 3; iSection++) { + + double z_endpoint = z_end_pipe[iSection]; //meters + double x_endpoint = (slope * z_endpoint) + intercept; + double x_startpoint = (slope * z_start_pipe[iSection]) + intercept; + + double length = + sqrt(pow(z_endpoint - z_start_pipe[iSection], 2) + pow(x_endpoint - x_startpoint, 2)); + double z_center = (0.5 * length + z_start_pipe[iSection]) * cos(slope); + double x_center = (slope * z_center) + intercept; + + double entrance_r_inner = 0.0; //drift_hadron_section_1_inner_r; + double exit_radius_inner = 0.0; + double entrance_r_outer = 0.0; //drift_hadron_section_1_inner_r; + double exit_radius_outer = 0.0; + + if (iSection < 1) { + entrance_r_inner = drift_hadron_section_1_inner_r; + exit_radius_inner = drift_hadron_section_1_inner_r; + entrance_r_outer = drift_hadron_section_1_outer_r; + exit_radius_outer = drift_hadron_section_1_outer_r; + length = length - 0.04; + } + if (iSection == 1) { + entrance_r_inner = drift_hadron_section_3_inner_r_ent; + exit_radius_inner = drift_hadron_section_3_inner_r_ex; + entrance_r_outer = drift_hadron_section_3_outer_r_ent; + exit_radius_outer = drift_hadron_section_3_outer_r_ex; + drift_hadron_section_3_x = x_center; + drift_hadron_section_3_z = z_center; + drift_hadron_section_3_length = length - 0.02; + //old numbers commented out for reference - A. Jentsch + //length = length - 0.02; + //x_center = -99.25250431/100.0; + //z_center = 2924.185347/100.0; + //length = drift_hadron_section_3_length/100.0; + } + if (iSection == 2) { + entrance_r_inner = drift_hadron_section_4_inner_r; + exit_radius_inner = drift_hadron_section_4_inner_r; + entrance_r_outer = drift_hadron_section_4_outer_r; + exit_radius_outer = drift_hadron_section_4_outer_r; + drift_hadron_section_4_x = x_center; + drift_hadron_section_4_z = z_center; + drift_hadron_section_4_length = length - 0.02; + length = length - 0.02; + //old numbers commented out for reference - A. Jentsch + // x_center = -123.076799/100.0; + // z_center = 3423.617428/100.0; + //length = drift_hadron_section_4_length/100.0; + } + + Cone drift_pipe((length * 100.0) / 2.0, entrance_r_inner, entrance_r_outer, exit_radius_inner, + exit_radius_outer); + + Volume v_pipe(Form("v_drift_tube_pipe_%d", iSection), drift_pipe, m_SS); + sdet.setAttributes(det, v_pipe, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv_pipe = assembly.placeVolume( + v_pipe, Transform3D(RotationY(slope), + Position(100.0 * x_center, 0.0, 100.0 * z_center))); // 2353.06094))); + pv_pipe.addPhysVolID("sector", 1); + DetElement pipe_de(sdet, Form("sector_pipe_%d_de", iSection), 1); + pipe_de.setPlacement(pv_pipe); } //------------------------------ @@ -176,54 +175,57 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * //------------------------------ //last two entries are dummy numbers for now - double z_start_points[7] = {orbit_start[0]+0.03, 22.590, 24.590, 26.055, 28.055 , 20.0, 20.0 }; - double z_endpoints_array[7] = {22.499, 24.499, 25.980, 27.980, z_start_pipe[1] , 25.0, 25.0 }; - - - for(int iVac = 0; iVac < 7; iVac++){ - - double z_endpoint = z_endpoints_array[iVac]; //meters - double x_endpoint = (slope*z_endpoint) + intercept; - double x_startpoint = (slope*z_start_points[iVac]) + intercept; - - double length = sqrt(pow(z_endpoint - z_start_points[iVac],2) + pow(x_endpoint - x_startpoint,2)); - double z_center = (0.5*length + z_start_points[iVac])*cos(slope); - double x_center = (slope*z_center) + intercept; - - double entrance_r_inner = 0.0; //drift_hadron_section_1_inner_r; - double exit_radius_inner = 0.0; - - if(iVac < 5){ - entrance_r_inner = drift_hadron_section_1_inner_r; - exit_radius_inner = drift_hadron_section_1_inner_r; - } - if(iVac == 5){ - entrance_r_inner = drift_hadron_section_1_inner_r; - exit_radius_inner = drift_hadron_section_3_inner_r_ex; - x_center = drift_hadron_section_3_x;//-99.25250431/100.0; - z_center = drift_hadron_section_3_z;//2924.185347/100.0; - length = drift_hadron_section_3_length - 0.02; ///100.0; - } - if(iVac == 6){ - entrance_r_inner = drift_hadron_section_4_inner_r; - exit_radius_inner = drift_hadron_section_4_inner_r; - //x_center = -123.076799/100.0; - //z_center = 3423.617428/100.0; - //length = drift_hadron_section_4_length/100.0; - x_center = drift_hadron_section_4_x; - z_center = drift_hadron_section_4_z; - length = drift_hadron_section_4_length; - } - - Cone drift_vacuum((length*100.0) / 2.0, 0.0, entrance_r_inner-0.5, 0.0, exit_radius_inner-0.5); - - Volume v_vacuum(Form("v_drift_tube_vacuum_%d", iVac), drift_vacuum, m_vac); - sdet.setAttributes(det, v_vacuum, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); - - auto pv_vacuum = assembly.placeVolume(v_vacuum, Transform3D(RotationY(slope), Position(100.0*x_center, 0.0, 100.0*z_center))); // 2353.06094))); - pv_vacuum.addPhysVolID("sector", 1); - DetElement vacuum_de(sdet, Form("sector_vac_%d_de", iVac), 1); - vacuum_de.setPlacement(pv_vacuum); + double z_start_points[7] = {orbit_start[0] + 0.03, 22.590, 24.590, 26.055, 28.055, 20.0, 20.0}; + double z_endpoints_array[7] = {22.499, 24.499, 25.980, 27.980, z_start_pipe[1], 25.0, 25.0}; + + for (int iVac = 0; iVac < 7; iVac++) { + + double z_endpoint = z_endpoints_array[iVac]; //meters + double x_endpoint = (slope * z_endpoint) + intercept; + double x_startpoint = (slope * z_start_points[iVac]) + intercept; + + double length = + sqrt(pow(z_endpoint - z_start_points[iVac], 2) + pow(x_endpoint - x_startpoint, 2)); + double z_center = (0.5 * length + z_start_points[iVac]) * cos(slope); + double x_center = (slope * z_center) + intercept; + + double entrance_r_inner = 0.0; //drift_hadron_section_1_inner_r; + double exit_radius_inner = 0.0; + + if (iVac < 5) { + entrance_r_inner = drift_hadron_section_1_inner_r; + exit_radius_inner = drift_hadron_section_1_inner_r; + } + if (iVac == 5) { + entrance_r_inner = drift_hadron_section_1_inner_r; + exit_radius_inner = drift_hadron_section_3_inner_r_ex; + x_center = drift_hadron_section_3_x; //-99.25250431/100.0; + z_center = drift_hadron_section_3_z; //2924.185347/100.0; + length = drift_hadron_section_3_length - 0.02; ///100.0; + } + if (iVac == 6) { + entrance_r_inner = drift_hadron_section_4_inner_r; + exit_radius_inner = drift_hadron_section_4_inner_r; + //x_center = -123.076799/100.0; + //z_center = 3423.617428/100.0; + //length = drift_hadron_section_4_length/100.0; + x_center = drift_hadron_section_4_x; + z_center = drift_hadron_section_4_z; + length = drift_hadron_section_4_length; + } + + Cone drift_vacuum((length * 100.0) / 2.0, 0.0, entrance_r_inner - 0.5, 0.0, + exit_radius_inner - 0.5); + + Volume v_vacuum(Form("v_drift_tube_vacuum_%d", iVac), drift_vacuum, m_vac); + sdet.setAttributes(det, v_vacuum, x_det.regionStr(), x_det.limitsStr(), "AnlBlue"); + + auto pv_vacuum = assembly.placeVolume( + v_vacuum, Transform3D(RotationY(slope), + Position(100.0 * x_center, 0.0, 100.0 * z_center))); // 2353.06094))); + pv_vacuum.addPhysVolID("sector", 1); + DetElement vacuum_de(sdet, Form("sector_vac_%d_de", iVac), 1); + vacuum_de.setPlacement(pv_vacuum); } // Transform3D posAndRot(RotationZYX(rot.z(), rot.y(), rot.x()), Position(pos.x(), pos.y(), pos.z())); diff --git a/src/magnetVacuumFF.cpp b/src/magnetVacuumFF.cpp index 46328c297..eb462fcea 100644 --- a/src/magnetVacuumFF.cpp +++ b/src/magnetVacuumFF.cpp @@ -1,7 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (C) 2023 Alex Jentsch - #include "DD4hep/DetFactoryHelper.h" #include "DD4hep/Printout.h" #include @@ -27,252 +26,260 @@ using namespace dd4hep; static double getRotatedZ(double z, double x, double angle); static double getRotatedX(double z, double x, double angle); -static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) -{ - - xml_det_t x_det = e; - string det_name = x_det.nameStr(); - DetElement sdet(det_name, x_det.id()); - Assembly assembly(det_name + "_assembly"); - Material m_Vac = det.material("Vacuum"); - string vis_name = x_det.visStr(); - - PlacedVolume pv_assembly; - - //---------------------------------------------- - // Starting point is only the magnet centers, - // lengths, rotations, and radii --> - // everything else calculated internally to - // make it easier to update later. - //---------------------------------------------- - - bool makeIP_B0pfVacuum = true; //This is for the special gap location between IP and b0pf - - //information for actual FF magnets, with magnet centers as reference - vector radii_magnet; - vector lengths_magnet; - vector rotation_magnet; - vector x_elem_magnet; - vector y_elem_magnet; - vector z_elem_magnet; - - //calculated entrance/exit points of FF magnet - vector x_beg; - vector z_beg; - vector x_end; - vector z_end; - - //calculated center of gap regions between magnets, rotation, and length - vector angle_elem_gap; - vector z_gap; - vector x_gap; - vector length_gap; - - //storage elements for CutTube geometry element used for gaps - vector inRadius; - vector outRadius; - vector nxLow; - vector nyLow; - vector nzLow; - vector nxHigh; - vector nyHigh; - vector nzHigh; - vector phi_initial; - vector phi_final; - - for(xml_coll_t c(x_det,_U(element)); c; ++c){ - - xml_dim_t pos = c.child(_U(placement)); - double pos_x = pos.x(); - double pos_y = pos.y(); - double pos_z = pos.z(); - double pos_theta = pos.attr(_U(theta)); - xml_dim_t dims = c.child(_U(dimensions)); //dimensions(); - double dim_z = dims.z(); - xml_dim_t apperture = c.child(_Unicode(apperture)); - double app_r = apperture.r(); - - radii_magnet.push_back(app_r); // cm - lengths_magnet.push_back(dim_z); //cm - rotation_magnet.push_back(pos_theta); // radians - x_elem_magnet.push_back(pos_x*dd4hep::cm); - y_elem_magnet.push_back(pos_y*dd4hep::cm); - z_elem_magnet.push_back(pos_z*dd4hep::cm); - - } - - int numMagnets = radii_magnet.size(); //number of actual FF magnets between IP and FF detectors - int numGaps = numMagnets - 1; //number of gaps between magnets (excluding the IP to B0pf transition -- special case) - - //------------------------------------------- - // override numbers for the first element --> - // doesn't use the actual B0pf geometry!!! - // -->it's based on the B0 beam pipe - // this needs to be fixed later to read-in - // that beam pipe geometry - //------------------------------------------- - - radii_magnet[0] = 2.9; // cm - lengths_magnet[0] = 120.0; // cm - rotation_magnet[0] = -0.025; // radians - x_elem_magnet[0] = -16.5; // cm - y_elem_magnet[0] = 0.0; // cm - z_elem_magnet[0] = 640.0; // cm - - //------------------------------------------- - //calculate entrance/exit points of magnets - //------------------------------------------- - - for(int i = 0; i < numMagnets; i++){ - - // need to use the common coordinate system --> - // use x = z, and y = x to make things easier - - z_beg.push_back(getRotatedZ(-0.5*lengths_magnet[i], 0.0, rotation_magnet[i]) + z_elem_magnet[i]); - z_end.push_back(getRotatedZ( 0.5*lengths_magnet[i], 0.0, rotation_magnet[i]) + z_elem_magnet[i]); - x_beg.push_back(getRotatedX(-0.5*lengths_magnet[i], 0.0, rotation_magnet[i]) + x_elem_magnet[i]); - x_end.push_back(getRotatedX( 0.5*lengths_magnet[i], 0.0, rotation_magnet[i]) + x_elem_magnet[i]); - - } - - //------------------------------------------ - // this part is a bit ugly for now - - // it's to make the vacuum volume between the - // end of the IP beam pipe and the beginning of - // beginning of the B0pf magnet - // - // -->the volume will be calculated at the end - //------------------------------------------- - - double endOfCentralBeamPipe_z = 445.580*dd4hep::cm; //extracted from central_beampipe.xml, line 64 - double diameterReduce = 11.0*dd4hep::cm; //size reduction to avoid overlap with electron pipe - double vacuumDiameterEntrance = 25.792*dd4hep::cm - diameterReduce; //extracted from central_beampipe.xml, line 64 - double vacuumDiameterExit = 17.4*dd4hep::cm; //15mrad @ entrance to magnet to not overlap electron magnet - double crossingAngle = -0.025; //radians - double endOfCentralBeamPipe_x = endOfCentralBeamPipe_z*crossingAngle; - - //----------------------------------------------- - //calculate gap region center, length, and angle - //----------------------------------------------- - - for(int i = 1; i < numMagnets; i++){ - - angle_elem_gap.push_back((x_beg[i] - x_end[i-1])/(z_beg[i] - z_end[i-1])); - length_gap.push_back(sqrt(pow(z_beg[i] - z_end[i-1], 2) + pow(x_beg[i] - x_end[i-1], 2))); - z_gap.push_back(z_end[i-1] + 0.5*length_gap[i-1]*cos(angle_elem_gap[i-1])); - x_gap.push_back(x_end[i-1] + 0.5*length_gap[i-1]*sin(angle_elem_gap[i-1])); - - } - - //----------------------------------------------- - // fill CutTube storage elements - //----------------------------------------------- - - for(int gapIdx = 0; gapIdx < numGaps; gapIdx++){ - - inRadius.push_back(0.0); - outRadius.push_back(radii_magnet[gapIdx+1]); - phi_initial.push_back(0.0); - phi_final.push_back(2*M_PI); - nxLow.push_back(-(length_gap[gapIdx]/2.0)*sin(rotation_magnet[gapIdx]-angle_elem_gap[gapIdx])); - nyLow.push_back(0.0); - nzLow.push_back(-(length_gap[gapIdx]/2.0)*cos(rotation_magnet[gapIdx]-angle_elem_gap[gapIdx])); - nxHigh.push_back((length_gap[gapIdx]/2.0)*sin(rotation_magnet[gapIdx+1]-angle_elem_gap[gapIdx])); - nyHigh.push_back(0.0); - nzHigh.push_back((length_gap[gapIdx]/2.0)*cos(rotation_magnet[gapIdx+1]-angle_elem_gap[gapIdx])); - - } - - //----------------------- - // inside magnets - //----------------------- - - for(int pieceIdx = 0; pieceIdx < numMagnets; pieceIdx++){ - - std::string piece_name = Form("MagnetVacuum%d", pieceIdx); - - Tube magnetPiece(piece_name, 0.0, radii_magnet[pieceIdx], lengths_magnet[pieceIdx]/2); - Volume vpiece(piece_name, magnetPiece, m_Vac); - sdet.setAttributes(det, vpiece, x_det.regionStr(), x_det.limitsStr(), vis_name); - - auto pv = assembly.placeVolume(vpiece, Transform3D(RotationY(rotation_magnet[pieceIdx]), - Position(x_elem_magnet[pieceIdx], y_elem_magnet[pieceIdx], z_elem_magnet[pieceIdx]))); - pv.addPhysVolID("sector", 1); - - DetElement de(sdet, Form("sector%d_de", pieceIdx), 1); - de.setPlacement(pv); - - } - - //-------------------------- - //between magnets - //-------------------------- +static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens */) { + + xml_det_t x_det = e; + string det_name = x_det.nameStr(); + DetElement sdet(det_name, x_det.id()); + Assembly assembly(det_name + "_assembly"); + Material m_Vac = det.material("Vacuum"); + string vis_name = x_det.visStr(); + + PlacedVolume pv_assembly; + + //---------------------------------------------- + // Starting point is only the magnet centers, + // lengths, rotations, and radii --> + // everything else calculated internally to + // make it easier to update later. + //---------------------------------------------- + + bool makeIP_B0pfVacuum = true; //This is for the special gap location between IP and b0pf + + //information for actual FF magnets, with magnet centers as reference + vector radii_magnet; + vector lengths_magnet; + vector rotation_magnet; + vector x_elem_magnet; + vector y_elem_magnet; + vector z_elem_magnet; + + //calculated entrance/exit points of FF magnet + vector x_beg; + vector z_beg; + vector x_end; + vector z_end; + + //calculated center of gap regions between magnets, rotation, and length + vector angle_elem_gap; + vector z_gap; + vector x_gap; + vector length_gap; + + //storage elements for CutTube geometry element used for gaps + vector inRadius; + vector outRadius; + vector nxLow; + vector nyLow; + vector nzLow; + vector nxHigh; + vector nyHigh; + vector nzHigh; + vector phi_initial; + vector phi_final; + + for (xml_coll_t c(x_det, _U(element)); c; ++c) { + + xml_dim_t pos = c.child(_U(placement)); + double pos_x = pos.x(); + double pos_y = pos.y(); + double pos_z = pos.z(); + double pos_theta = pos.attr(_U(theta)); + xml_dim_t dims = c.child(_U(dimensions)); //dimensions(); + double dim_z = dims.z(); + xml_dim_t apperture = c.child(_Unicode(apperture)); + double app_r = apperture.r(); + + radii_magnet.push_back(app_r); // cm + lengths_magnet.push_back(dim_z); //cm + rotation_magnet.push_back(pos_theta); // radians + x_elem_magnet.push_back(pos_x * dd4hep::cm); + y_elem_magnet.push_back(pos_y * dd4hep::cm); + z_elem_magnet.push_back(pos_z * dd4hep::cm); + } + + int numMagnets = radii_magnet.size(); //number of actual FF magnets between IP and FF detectors + int numGaps = + numMagnets - + 1; //number of gaps between magnets (excluding the IP to B0pf transition -- special case) + + //------------------------------------------- + // override numbers for the first element --> + // doesn't use the actual B0pf geometry!!! + // -->it's based on the B0 beam pipe + // this needs to be fixed later to read-in + // that beam pipe geometry + //------------------------------------------- + + radii_magnet[0] = 2.9; // cm + lengths_magnet[0] = 120.0; // cm + rotation_magnet[0] = -0.025; // radians + x_elem_magnet[0] = -16.5; // cm + y_elem_magnet[0] = 0.0; // cm + z_elem_magnet[0] = 640.0; // cm + + //------------------------------------------- + //calculate entrance/exit points of magnets + //------------------------------------------- + + for (int i = 0; i < numMagnets; i++) { + + // need to use the common coordinate system --> + // use x = z, and y = x to make things easier + + z_beg.push_back(getRotatedZ(-0.5 * lengths_magnet[i], 0.0, rotation_magnet[i]) + + z_elem_magnet[i]); + z_end.push_back(getRotatedZ(0.5 * lengths_magnet[i], 0.0, rotation_magnet[i]) + + z_elem_magnet[i]); + x_beg.push_back(getRotatedX(-0.5 * lengths_magnet[i], 0.0, rotation_magnet[i]) + + x_elem_magnet[i]); + x_end.push_back(getRotatedX(0.5 * lengths_magnet[i], 0.0, rotation_magnet[i]) + + x_elem_magnet[i]); + } + + //------------------------------------------ + // this part is a bit ugly for now - + // it's to make the vacuum volume between the + // end of the IP beam pipe and the beginning of + // beginning of the B0pf magnet + // + // -->the volume will be calculated at the end + //------------------------------------------- + + double endOfCentralBeamPipe_z = + 445.580 * dd4hep::cm; //extracted from central_beampipe.xml, line 64 + double diameterReduce = 11.0 * dd4hep::cm; //size reduction to avoid overlap with electron pipe + double vacuumDiameterEntrance = + 25.792 * dd4hep::cm - diameterReduce; //extracted from central_beampipe.xml, line 64 + double vacuumDiameterExit = + 17.4 * dd4hep::cm; //15mrad @ entrance to magnet to not overlap electron magnet + double crossingAngle = -0.025; //radians + double endOfCentralBeamPipe_x = endOfCentralBeamPipe_z * crossingAngle; + + //----------------------------------------------- + //calculate gap region center, length, and angle + //----------------------------------------------- + + for (int i = 1; i < numMagnets; i++) { + + angle_elem_gap.push_back((x_beg[i] - x_end[i - 1]) / (z_beg[i] - z_end[i - 1])); + length_gap.push_back(sqrt(pow(z_beg[i] - z_end[i - 1], 2) + pow(x_beg[i] - x_end[i - 1], 2))); + z_gap.push_back(z_end[i - 1] + 0.5 * length_gap[i - 1] * cos(angle_elem_gap[i - 1])); + x_gap.push_back(x_end[i - 1] + 0.5 * length_gap[i - 1] * sin(angle_elem_gap[i - 1])); + } + + //----------------------------------------------- + // fill CutTube storage elements + //----------------------------------------------- + + for (int gapIdx = 0; gapIdx < numGaps; gapIdx++) { + + inRadius.push_back(0.0); + outRadius.push_back(radii_magnet[gapIdx + 1]); + phi_initial.push_back(0.0); + phi_final.push_back(2 * M_PI); + nxLow.push_back(-(length_gap[gapIdx] / 2.0) * + sin(rotation_magnet[gapIdx] - angle_elem_gap[gapIdx])); + nyLow.push_back(0.0); + nzLow.push_back(-(length_gap[gapIdx] / 2.0) * + cos(rotation_magnet[gapIdx] - angle_elem_gap[gapIdx])); + nxHigh.push_back((length_gap[gapIdx] / 2.0) * + sin(rotation_magnet[gapIdx + 1] - angle_elem_gap[gapIdx])); + nyHigh.push_back(0.0); + nzHigh.push_back((length_gap[gapIdx] / 2.0) * + cos(rotation_magnet[gapIdx + 1] - angle_elem_gap[gapIdx])); + } + + //----------------------- + // inside magnets + //----------------------- + + for (int pieceIdx = 0; pieceIdx < numMagnets; pieceIdx++) { + + std::string piece_name = Form("MagnetVacuum%d", pieceIdx); + + Tube magnetPiece(piece_name, 0.0, radii_magnet[pieceIdx], lengths_magnet[pieceIdx] / 2); + Volume vpiece(piece_name, magnetPiece, m_Vac); + sdet.setAttributes(det, vpiece, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv = assembly.placeVolume( + vpiece, Transform3D(RotationY(rotation_magnet[pieceIdx]), + Position(x_elem_magnet[pieceIdx], y_elem_magnet[pieceIdx], + z_elem_magnet[pieceIdx]))); + pv.addPhysVolID("sector", 1); + + DetElement de(sdet, Form("sector%d_de", pieceIdx), 1); + de.setPlacement(pv); + } + + //-------------------------- + //between magnets + //-------------------------- + + for (int pieceIdx = numMagnets; pieceIdx < numGaps + numMagnets; pieceIdx++) { + + int correctIdx = pieceIdx - numMagnets; + + std::string piece_name = Form("GapVacuum%d", correctIdx); + + CutTube gapPiece(piece_name, inRadius[correctIdx], outRadius[correctIdx], + length_gap[correctIdx] / 2, phi_initial[correctIdx], phi_final[correctIdx], + nxLow[correctIdx], nyLow[correctIdx], nzLow[correctIdx], nxHigh[correctIdx], + nyHigh[correctIdx], nzHigh[correctIdx]); + + Volume vpiece(piece_name, gapPiece, m_Vac); + sdet.setAttributes(det, vpiece, x_det.regionStr(), x_det.limitsStr(), vis_name); + + auto pv = assembly.placeVolume( + vpiece, Transform3D(RotationY(angle_elem_gap[correctIdx]), + Position(x_gap[correctIdx], 0.0, z_gap[correctIdx]))); + pv.addPhysVolID("sector", 1); + + DetElement de(sdet, Form("sector%d_de", pieceIdx), 1); + de.setPlacement(pv); + } + + //-------------------------------------------------------------- + //make and place vacuum volume to connect IP beam pipe to B0pf + //-------------------------------------------------------------- + + if (makeIP_B0pfVacuum) { + + double specialGapLength = sqrt(pow(z_beg[0] - endOfCentralBeamPipe_z, 2) + + pow(x_beg[0] - endOfCentralBeamPipe_x, 2)) - + 0.1; + double specialGap_z = 0.5 * specialGapLength * cos(crossingAngle) + endOfCentralBeamPipe_z; + double specialGap_x = 0.5 * specialGapLength * sin(crossingAngle) + endOfCentralBeamPipe_x; - for(int pieceIdx = numMagnets; pieceIdx < numGaps + numMagnets; pieceIdx++){ + std::string piece_name = Form("GapVacuum%d", numGaps + numMagnets); - int correctIdx = pieceIdx-numMagnets; + Cone specialGap(piece_name, specialGapLength / 2, 0.0, vacuumDiameterEntrance / 2, 0.0, + vacuumDiameterExit / 2); - std::string piece_name = Form("GapVacuum%d", correctIdx); + Volume specialGap_v(piece_name, specialGap, m_Vac); + sdet.setAttributes(det, specialGap_v, x_det.regionStr(), x_det.limitsStr(), vis_name); - CutTube gapPiece(piece_name, inRadius[correctIdx], outRadius[correctIdx], length_gap[correctIdx]/2, phi_initial[correctIdx], phi_final[correctIdx], - nxLow[correctIdx], nyLow[correctIdx], nzLow[correctIdx], nxHigh[correctIdx], nyHigh[correctIdx], nzHigh[correctIdx]); + auto pv = + assembly.placeVolume(specialGap_v, Transform3D(RotationY(crossingAngle), + Position(specialGap_x, 0.0, specialGap_z))); + pv.addPhysVolID("sector", 1); - Volume vpiece(piece_name, gapPiece, m_Vac); - sdet.setAttributes(det, vpiece, x_det.regionStr(), x_det.limitsStr(), vis_name); + DetElement de(sdet, Form("sector%d_de", numGaps + numMagnets), 1); + de.setPlacement(pv); + } - auto pv = assembly.placeVolume(vpiece, Transform3D(RotationY(angle_elem_gap[correctIdx]), - Position(x_gap[correctIdx], 0.0, z_gap[correctIdx]))); - pv.addPhysVolID("sector", 1); + //---------------------------------------------------- - DetElement de(sdet, Form("sector%d_de", pieceIdx), 1); - de.setPlacement(pv); + pv_assembly = det.pickMotherVolume(sdet).placeVolume(assembly); + pv_assembly.addPhysVolID("system", x_det.id()).addPhysVolID("barrel", 1); + sdet.setPlacement(pv_assembly); + assembly->GetShape()->ComputeBBox(); - - } - - //-------------------------------------------------------------- - //make and place vacuum volume to connect IP beam pipe to B0pf - //-------------------------------------------------------------- - - if(makeIP_B0pfVacuum){ - - double specialGapLength = sqrt(pow(z_beg[0] - endOfCentralBeamPipe_z, 2) + pow(x_beg[0] - endOfCentralBeamPipe_x, 2)) - 0.1; - double specialGap_z = 0.5*specialGapLength*cos(crossingAngle) + endOfCentralBeamPipe_z; - double specialGap_x = 0.5*specialGapLength*sin(crossingAngle) + endOfCentralBeamPipe_x; - - std::string piece_name = Form("GapVacuum%d", numGaps + numMagnets); - - Cone specialGap(piece_name, specialGapLength/2, 0.0, vacuumDiameterEntrance/2, 0.0, vacuumDiameterExit/2 ); - - Volume specialGap_v(piece_name, specialGap, m_Vac); - sdet.setAttributes(det, specialGap_v, x_det.regionStr(), x_det.limitsStr(), vis_name); - - auto pv = assembly.placeVolume(specialGap_v, Transform3D(RotationY(crossingAngle), Position(specialGap_x, 0.0, specialGap_z))); - pv.addPhysVolID("sector", 1); - - DetElement de(sdet, Form("sector%d_de", numGaps + numMagnets), 1); - de.setPlacement(pv); - - } - - //---------------------------------------------------- - - pv_assembly = det.pickMotherVolume(sdet).placeVolume(assembly); - pv_assembly.addPhysVolID("system", x_det.id()).addPhysVolID("barrel", 1); - sdet.setPlacement(pv_assembly); - assembly->GetShape()->ComputeBBox(); - - return sdet; + return sdet; } -double getRotatedZ(double z, double x, double angle){ +double getRotatedZ(double z, double x, double angle) { return z * cos(angle) - x * sin(angle); } - return z*cos(angle) - x*sin(angle); -} - -double getRotatedX(double z, double x, double angle){ - - return z*sin(angle) + x*cos(angle); -} +double getRotatedX(double z, double x, double angle) { return z * sin(angle) + x * cos(angle); } DECLARE_DETELEMENT(magnetElementInnerVacuum, create_detector) From 9800f7256ba9fb8d584fb8562475bd82bd741d60 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 16 Apr 2024 09:23:13 -0500 Subject: [PATCH 15/25] feat: add clang-format to .git-blame-ignore-revs (#709) ### Briefly, what does this PR introduce? This PR adds the clang-format commit to git blame ignore revs. ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [x] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? No. --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..75c7c5838 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +2ffa142d0bd7055cfbfd9ab7838f5e0b7f6c551c # feat(ci): change pre-commit clang-format to run in ci From 9d0191565b58b8eb9cb02aab65c848029c30cfd2 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Tue, 16 Apr 2024 14:43:01 -0500 Subject: [PATCH 16/25] fix: export all configs to STEP, use `part --level 1 HcalBarrel` (#702) ### Briefly, what does this PR introduce? Due to limitations in npdet_to_step, we disabled the HcalBarrel when exporting to STEP. With npsim 1.4.0, the issue with the HcalBarrel was [resolved](https://github.com/eic/npsim/pull/23). This PR re-enables the HcalBarrel in npdet_to_step conversion, and it simplifies the logic to export all detector configs (for consistency and predictability). TODO: - [x] restart CI pipeline when eic-shell nightly rolls out with npsim-1.4.0 ### What kind of change does this PR introduce? - [x] Bug fix (issue: HcalBarrel disabled in convert-to-step) - [ ] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [ ] Changes have been communicated to collaborators ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? No. --- .github/workflows/linux-eic-shell.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index 52f32c9fa..449d03beb 100644 --- a/.github/workflows/linux-eic-shell.yml +++ b/.github/workflows/linux-eic-shell.yml @@ -287,9 +287,9 @@ jobs: runs-on: ubuntu-latest needs: - build + - list-detector-configs strategy: - matrix: - detector_config: [epic_craterlake_no_bhcal, epic_craterlake_tracking_only, epic_dirc_only, epic_drich_only, epic_imaging_only, epic_ip6, epic_lfhcal_with_insert] + matrix: ${{fromJson(needs.list-detector-configs.outputs.configs_json)}} steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 @@ -309,6 +309,7 @@ jobs: declare -A detectors while read d ; do detectors[$d]='-l 3' ; done <<< $(npdet_to_step list $DETECTOR_PATH/${{matrix.detector_config}}.xml | sed '/world/d;s/.*(vol: \(.*\)).*/\1/g') # Then tweak the levels (default is 1) + detectors[HcalBarrel]='-l 1' detectors[LFHCAL]='-l 2' detectors[OuterBarrelMPGDSubAssembly]='-l 4' # Export to one STEP file From 1997384ba4f2df864cb5ebf0024f23ff90351660 Mon Sep 17 00:00:00 2001 From: Chandradoy Chatterjee Date: Tue, 23 Apr 2024 02:47:52 +0200 Subject: [PATCH 17/25] dRICH Extrusion Box azimuthal span 42 degrees (#712) ### Briefly, what does this PR introduce? The PR changes the azimuthal span of the extrusion box for the dRICH sensor from 48 degrees to 42 degrees. This will allow to have 18 degrees allowance for the services. ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [X ] Changes have been communicated to collaborators Marco Contalbrig has been updated about the changes. ### Does this PR introduce breaking changes? What changes might users need to make to their code? ### Does this PR change default behavior? --- compact/pid/drich.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compact/pid/drich.xml b/compact/pid/drich.xml index 7dc0e5b05..5e8b027d4 100644 --- a/compact/pid/drich.xml +++ b/compact/pid/drich.xml @@ -24,7 +24,7 @@ - + @@ -328,7 +328,7 @@ photodetector unit (PDU) assembly diagram: matrix of SiPMs with services radius="110.0*cm" /> Date: Thu, 25 Apr 2024 20:25:58 -0400 Subject: [PATCH 18/25] [pre-commit.ci] pre-commit autoupdate (#714) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-clang-format: v18.1.3 → v18.1.4](https://github.com/pre-commit/mirrors-clang-format/compare/v18.1.3...v18.1.4) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 812231abd..236d6ff38 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.3 + rev: v18.1.4 hooks: - id: clang-format - repo: https://github.com/Lucas-C/pre-commit-hooks From 823e91f79650879b1bb39ff29bde50af10b73d34 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Thu, 25 Apr 2024 20:26:25 -0400 Subject: [PATCH 19/25] calibrations.xml: add hpdirc_positive.lut (#711) Adds hpDIRC LUT to support https://github.com/eic/EICrecon/pull/1365 I pick @nathanwbrei 's fork over https://github.com/rdom/fastpid since the file got a minor update ```diff diff --git a/hpdirc_positive.lut b/hpdirc_positive.lut index a0c5841..ac5b96d 100644 --- a/hpdirc_positive.lut +++ b/hpdirc_positive.lut @@ -1,3 +1,21 @@ +# PDG code of the particle (e 11, pi 211, K 321, p 2212) +11 211 321 2212 + +# Charge (-1,1) +1 + +# Momentum [GeV/c] +0.20 10.2 0.2 + +# Polar angle [deg] +25.0 161.0 1.0 + +# Azimuthal angle [deg] +0.0 30.5 0.5 + +# Outputs columns are P[e], P[pi], P[K], P[p] +# We ignore muons for now + 11 1 0.20 25.00 0.00 0.0000 0.0000 0.0000 0.0000 11 1 0.20 25.00 0.50 0.0000 0.0000 0.0000 0.0000 11 1 0.20 25.00 1.00 0.0000 0.0000 0.0000 0.0000 ``` --- compact/calibrations.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compact/calibrations.xml b/compact/calibrations.xml index 07ba8aa2f..250d0709a 100644 --- a/compact/calibrations.xml +++ b/compact/calibrations.xml @@ -9,6 +9,11 @@ + + + + + From 81162e06dd01fe52f0d874a940c37d58293bd437 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Sun, 28 Apr 2024 19:17:08 -0500 Subject: [PATCH 20/25] fix: update tracker support and services cones per project CAD info (#661) ### Briefly, what does this PR introduce? This PR adds the outer support/services cone and places the cones and barrels in their actual intended positions. I'm marking this as a bugfix since the placement was completely wrong (with tracks in some regions going through two support cylinders...). TODO: - [x] #663 - [x] #673 - this is not really a dependency, but if the radius of that system increases, we want to figure it out before putting in the services - [x] #668 - [x] #683 - [x] #684 ### What kind of change does this PR introduce? - [x] Bug fix (issue #__) - [ ] New feature (issue #__) - [ ] Documentation update - [ ] Other: __ ### Please check if this PR fulfills the following: - [ ] Tests for the changes have been added - [ ] Documentation has been added / updated - [x] Changes have been communicated to collaborators @sly2j ### Does this PR introduce breaking changes? What changes might users need to make to their code? No. ### Does this PR change default behavior? Yes, it adds the project's estimate of the equivalent aluminum thickness of the services. --------- Co-authored-by: Dmitry Kalinkin Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- compact/pid/drich.xml | 2 +- compact/tracking/definitions_craterlake.xml | 5 +- .../tracking/support_service_craterlake.xml | 651 +++++++++++++++--- src/BarrelCalorimeterScFi_geo.cpp | 2 +- src/SupportServiceMaterial_geo.cpp | 64 +- 5 files changed, 638 insertions(+), 86 deletions(-) diff --git a/compact/pid/drich.xml b/compact/pid/drich.xml index 5e8b027d4..cde823bfa 100644 --- a/compact/pid/drich.xml +++ b/compact/pid/drich.xml @@ -22,7 +22,7 @@ - + diff --git a/compact/tracking/definitions_craterlake.xml b/compact/tracking/definitions_craterlake.xml index e0403f9c6..ce5bc835e 100644 --- a/compact/tracking/definitions_craterlake.xml +++ b/compact/tracking/definitions_craterlake.xml @@ -56,8 +56,9 @@ Service/Support setup - - + Ref: Services Material Budget 24.03.04..stp -- 450.00 mm + Ref: Services Material Budget 24.03.13.stp -- 670.00 mm, nudged 5 mm + Ref: Services Material Budget 24.03.04..stp -- 520.00 mm These may belong in definitions.xml diff --git a/compact/tracking/support_service_craterlake.xml b/compact/tracking/support_service_craterlake.xml index 55ba62bff..9deca9f98 100644 --- a/compact/tracking/support_service_craterlake.xml +++ b/compact/tracking/support_service_craterlake.xml @@ -7,6 +7,26 @@ See https://indico.bnl.gov/event/19854/#1-updated-epic-tracking-config Silicon tracker: the same effective thickness parameters from previous versions, routing changed MPGD: estimated by M. Posik + ┌───── + B + │ + / + A + / + │ + │ + ─2C─2B─2A─\ Outer Support Cone /─2A─2B─2C─2D─2E─┘ + Ecal pfRICH \ / + \ / + \─1C──1B──1A─\ Inner Support /─1A────1B─────1C────/ Outer Support Cone + \ Cones / + \ / + \ / + │ │ + │ │ + N (-) â”” ┘ (+) P + ──·──·──·──·──·────·──·──·──·──·── x ──·──·──·──·──·──·──·──·──·────·──·──·──·──·──·── z + @@ -24,34 +44,33 @@ Inner tracker service/support cones, symmetric Effective Aluminum for services for now - - - - - + Ref: Services Material Budget 24.03.13.stp - 0.5*mm to avoid overlap with OuterSiBarrel + Ref: Services Material Budget 24.03.13.stp - 0.5*mm to avoid overlap with OuterSiBarrel + + + - + - Tracker disk support barrels. 1: inner, 2: outer. All z parameters are unsigned - TBD: second cones to connect two barrels - + + Tracker disk support barrels. 1: inner, 2: outer. All z parameters are unsigned 1: Inner barrel for Si disk, 3 slices each ends (Negative CBA, Positive ABC) Positive - + - 136cm + Ref: Services Material Budget 24.03.13.stp @@ -61,21 +80,21 @@ - - - - - - + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + + + Negative - + - 106cm + Ref: Services Material Budget 24.03.13.stp @@ -85,12 +104,43 @@ - place holder to avoid zero thickness error - - - - - + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + + + + + + Outer tracker service/support cones, asymmetric + + Effective Aluminum for services for now + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + + + + Negative outer tracker service/support cone + + + + + + Ref: Services Material Budget 24.03.13.stp + + + + + Positive outer tracker service/support cone + + + + + + + + + 2. Outer barrel for Si barrel cables (guided out projectively) and MPGD (inner+disks). @@ -98,17 +148,17 @@ Positive - ~48.75cm - - - - + + + + + - 180cm. Should be ~174cm + @@ -122,32 +172,48 @@ - cables from Si tracker to outer barrels - cables from the Si cone - cables from the Si disks - - cables from MPGD - - - - - + + grounds-up thickness determination + cables from Si tracker to outer barrels + cables from the Si cone + cables from the Si disks + + cables from MPGD + + + + + + + total + + + + + + - total - - - - - + effective thickness + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + + + + + Negative - ~ 48.75cm - - + + + - 123.6cm. Should be 120cm + Ref: Services Material Budget 24.03.13.stp @@ -157,24 +223,98 @@ - cables from Si tracker to outer barrels - - - cables from MPGD - - - - - - - - Inner detector support cylinder - - - - - - + + grounds-up thickness determination + cables from Si tracker to outer barrels + + + cables from MPGD + + + + + + + + + effective thickness + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + Ref: Services Material Budget 24.03.13.stp + + + + + 3. Positive endcap disk routing for services. + + Average of inner and outer thickness + + + + + Ref: Services Material Budget 24.03.13.stp + + + 4. Segments between DRICH readout boxes. + + Blind cone segments that do not continue into DRICH readout boxes + + Average of inner and outer thickness + + + + + + + Modified from 110*cm to DRICH_sensorbox_rmin = 108*cm + + + + + Cone segments "A" that continue between the DRICH readout boxes + + + + + + + + + + + + + Cone segments "B" that go between the DRICH readout boxes + + Ref: Services Material Budget 24.03.13.stp + + + + + + + Ref: Services Material Budget 24.03.13.stp + + + + + Ref: Services Material Budget 24.03.13.stp + + + + + + + + + Inner detector support cylinder + + + + + + @@ -211,10 +351,11 @@ vis="TrackerSupportVis" rmin1="InnerSupportCone_rmin2" rmin2="InnerSupportCone_rmin1" + rmax="TrackerSupportCyl_rmin1+TrackerSupportCylN_thickness1A" length="InnerSupportCone_length" thickness="InnerSupportConeN_thickness"> - + - + @@ -290,11 +432,34 @@ + + + + + + + + + + + outer barrel @@ -304,7 +469,7 @@ @@ -314,7 +479,7 @@ @@ -325,7 +490,7 @@ @@ -335,7 +500,7 @@ @@ -345,7 +510,7 @@ @@ -355,7 +520,7 @@ @@ -365,7 +530,7 @@ @@ -373,6 +538,333 @@ + + + + + + + Service routings in front of DRICH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Service routings outside DRICH + + + + + + + + + + + + + + + + + + + + + + + + + Inner detector support barrel + diff --git a/src/BarrelCalorimeterScFi_geo.cpp b/src/BarrelCalorimeterScFi_geo.cpp index e0a2fa468..9c6c337a5 100644 --- a/src/BarrelCalorimeterScFi_geo.cpp +++ b/src/BarrelCalorimeterScFi_geo.cpp @@ -237,7 +237,7 @@ void buildFibers(Detector& desc, SensitiveDetector& sens, Volume& s_vol, int lay struct Fiber { Point pos; bool assigned = false; - Fiber(const Point& p) : pos(p){}; + Fiber(const Point& p) : pos(p) {}; }; std::vector fibers(f_pos.begin(), f_pos.end()); diff --git a/src/SupportServiceMaterial_geo.cpp b/src/SupportServiceMaterial_geo.cpp index c476f888c..2bab39730 100644 --- a/src/SupportServiceMaterial_geo.cpp +++ b/src/SupportServiceMaterial_geo.cpp @@ -44,15 +44,23 @@ std::pair build_shape(const Detector& descr, const xml_det_ const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); const double length = getAttrOrDefault(x_child, _U(length), x_support.length()); const double rmin = getAttrOrDefault(x_child, _U(rmin), x_support.rmin()) + offset; - solid = Tube(rmin, rmin + thickness, length / 2); + const double phimin = getAttrOrDefault( + x_child, _Unicode(phimin), getAttrOrDefault(x_support, _Unicode(phimin), 0.0 * deg)); + const double phimax = getAttrOrDefault( + x_child, _Unicode(phimax), getAttrOrDefault(x_support, _Unicode(phimax), 360.0 * deg)); + solid = Tube(rmin, rmin + thickness, length / 2, phimin, phimax); } // A disk is a cylinder, constructed differently else if (type == "Disk") { const double thickness = getAttrOrDefault(x_child, _U(thickness), x_support.thickness()); const double rmin = getAttrOrDefault(x_child, _U(rmin), x_support.rmin()); const double rmax = getAttrOrDefault(x_child, _U(rmax), x_support.rmax()); + const double phimin = getAttrOrDefault( + x_child, _Unicode(phimin), getAttrOrDefault(x_support, _Unicode(phimin), 0.0 * deg)); + const double phimax = getAttrOrDefault( + x_child, _Unicode(phimax), getAttrOrDefault(x_support, _Unicode(phimax), 360.0 * deg)); pos3D = pos3D + Position(0, 0, -x_support.thickness() / 2 + thickness / 2 + offset); - solid = Tube(rmin, rmax, thickness / 2); + solid = Tube(rmin, rmax, thickness / 2, phimin, phimax); } else if (type == "Cone") { const double base_rmin1 = getAttrOrDefault(x_child, _U(rmin1), x_support.rmin1()); const double base_rmin2 = getAttrOrDefault(x_child, _U(rmin2), x_support.rmin2()); @@ -68,7 +76,57 @@ std::pair build_shape(const Detector& descr, const xml_det_ const double rmin2 = base_rmin2 + transverse_offset; const double rmax1 = rmin1 + transverse_thickness; const double rmax2 = rmin2 + transverse_thickness; - solid = Cone(length / 2, rmin1, rmax1, rmin2, rmax2); + // Allow for optional hard rmin/rmax cutoffs + const double rmin = getAttrOrDefault( + x_child, _U(rmin), getAttrOrDefault(x_support, _Unicode(rmin), min(rmin1, rmin2))); + const double rmax = getAttrOrDefault( + x_child, _U(rmax), getAttrOrDefault(x_support, _Unicode(rmax), max(rmax1, rmax2))); + if (rmin > min(rmax1, rmax2)) { + printout(ERROR, x_det.nameStr(), + "%s: rmin (%f mm) must be smaller than the smallest rmax (%f %f mm)", + x_support.nameStr().c_str(), rmin / mm, rmax1 / mm, rmax2 / mm); + std::exit(1); + } + if (rmax < max(base_rmin1, base_rmin2)) { + printout(ERROR, x_det.nameStr(), + "%s: rmax (%f mm) must be larger than the largest rmin (%f %f mm)", + x_support.nameStr().c_str(), rmax / mm, base_rmin1 / mm, base_rmin2 / mm); + std::exit(1); + } + const double zmin = -length / 2 + length * (rmin - rmin1) / (rmin2 - rmin1); + const double zmax = -length / 2 + length * (rmax - rmax1) / (rmax2 - rmax1); + const auto rmin_at = [&](const double z) { + return rmin1 + (z + length / 2) * (rmin2 - rmin1) / length; + }; + const auto rmax_at = [&](const double z) { + return rmax1 + (z + length / 2) * (rmax2 - rmax1) / length; + }; + // Allow for optional phimin/phimax + const double phimin = getAttrOrDefault( + x_child, _Unicode(phimin), getAttrOrDefault(x_support, _Unicode(phimin), 0.0 * deg)); + const double phimax = getAttrOrDefault( + x_child, _Unicode(phimax), getAttrOrDefault(x_support, _Unicode(phimax), 360.0 * deg)); + const double deltaphi = phimax - phimin; + const double epsilon{TGeoShape::Tolerance()}; + if (fabs(zmin) >= length / 2 - epsilon && fabs(zmax) >= length / 2 - epsilon) { + if (fabs(phimax - phimin - 360 * deg) < epsilon) { + solid = Cone(length / 2, rmin1, rmax1, rmin2, rmax2); + } else { + solid = ConeSegment(length / 2, rmin1, rmax1, rmin2, rmax2, phimin, phimax); + } + } else { + std::vector v_rmin{max(rmin1, rmin), max(rmin2, rmin)}, + v_rmax{min(rmax1, rmax), min(rmax2, rmax)}, v_z{-length / 2, +length / 2}; + for (const auto& z : + (zmin < zmax ? std::vector{zmin, zmax} : std::vector{zmax, zmin})) { + if (-length / 2 + epsilon < z && z < -epsilon + length / 2) { + v_rmin.insert(std::prev(v_rmin.end()), std::max(rmin, rmin_at(z))); + v_rmax.insert(std::prev(v_rmax.end()), std::min(rmax, rmax_at(z))); + v_z.insert(std::prev(v_z.end()), z); + } + } + solid = Polycone(phimin, deltaphi, v_rmin, v_rmax, v_z); + } } else { printout(ERROR, x_det.nameStr(), "Unknown support type: %s", type.c_str()); std::exit(1); From cf368f18ba35e493a7e98e5d045f8586d774d26e Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Sun, 28 Apr 2024 23:44:33 -0400 Subject: [PATCH 21/25] scripts/view*: use bash from $PATH (#716) Existence of /bin/bash is not guaranteed. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- scripts/view1/generate_eps | 2 +- scripts/view11/generate_eps | 2 +- scripts/view12/generate_eps | 2 +- scripts/view13/generate_eps | 2 +- scripts/view14/generate_eps | 2 +- scripts/view15/generate_eps | 2 +- scripts/view2/generate_eps | 2 +- scripts/view20/generate_eps | 2 +- scripts/view3/generate_eps | 2 +- scripts/view4/generate_eps | 2 +- scripts/view5/generate_eps | 2 +- scripts/view50/generate_eps | 2 +- scripts/view6/generate_eps | 2 +- scripts/view7/generate_eps | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/scripts/view1/generate_eps b/scripts/view1/generate_eps index b7d4419ed..33beae078 100755 --- a/scripts/view1/generate_eps +++ b/scripts/view1/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #export DAWN_PS_PREVIEWER="derp" diff --git a/scripts/view11/generate_eps b/scripts/view11/generate_eps index 1f53c6534..c93288c27 100755 --- a/scripts/view11/generate_eps +++ b/scripts/view11/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #trignometry sin () diff --git a/scripts/view12/generate_eps b/scripts/view12/generate_eps index cbb2b355f..08ce870eb 100755 --- a/scripts/view12/generate_eps +++ b/scripts/view12/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #trignometry sin () diff --git a/scripts/view13/generate_eps b/scripts/view13/generate_eps index 748badbf6..1aab04df1 100755 --- a/scripts/view13/generate_eps +++ b/scripts/view13/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "view2 produces a series of XY slices a different z locations." diff --git a/scripts/view14/generate_eps b/scripts/view14/generate_eps index b1fd92b03..ca1fca10b 100755 --- a/scripts/view14/generate_eps +++ b/scripts/view14/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #trignometry sin () diff --git a/scripts/view15/generate_eps b/scripts/view15/generate_eps index 1bf171575..d05e5ca81 100755 --- a/scripts/view15/generate_eps +++ b/scripts/view15/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #trignometry sin () diff --git a/scripts/view2/generate_eps b/scripts/view2/generate_eps index d3162019e..bcbcec379 100755 --- a/scripts/view2/generate_eps +++ b/scripts/view2/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "view2 produces a series of XY slices a different z locations." diff --git a/scripts/view20/generate_eps b/scripts/view20/generate_eps index 5822e8eb3..9289de069 100755 --- a/scripts/view20/generate_eps +++ b/scripts/view20/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #export DAWN_PS_PREVIEWER="derp" diff --git a/scripts/view3/generate_eps b/scripts/view3/generate_eps index 1abde4653..d01291487 100755 --- a/scripts/view3/generate_eps +++ b/scripts/view3/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "view3 produces a series of XY slices a different z locations." diff --git a/scripts/view4/generate_eps b/scripts/view4/generate_eps index 0cf16687b..fbc0c7dea 100755 --- a/scripts/view4/generate_eps +++ b/scripts/view4/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # this is a detector slice diff --git a/scripts/view5/generate_eps b/scripts/view5/generate_eps index c551627db..b9626e2c1 100755 --- a/scripts/view5/generate_eps +++ b/scripts/view5/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # this is a detector slice diff --git a/scripts/view50/generate_eps b/scripts/view50/generate_eps index f2de94608..2a8e40fbf 100755 --- a/scripts/view50/generate_eps +++ b/scripts/view50/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #export DAWN_PS_PREVIEWER="derp" diff --git a/scripts/view6/generate_eps b/scripts/view6/generate_eps index 27040afdb..639c9fee5 100755 --- a/scripts/view6/generate_eps +++ b/scripts/view6/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "view6 produces a series of XY slices a different z locations." diff --git a/scripts/view7/generate_eps b/scripts/view7/generate_eps index 4f33c544b..a227de4f9 100755 --- a/scripts/view7/generate_eps +++ b/scripts/view7/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash echo "view7 produces a series of XY slices a different z locations." From ed8f4cf3d4119d0488c77fb9484931cd33b018c9 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Sun, 28 Apr 2024 23:50:20 -0400 Subject: [PATCH 22/25] bin/generate_prim_file: use POSIX process groups instead of psutil (#717) psutil is an external package. I'd rather not have to worry about providing it. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- bin/generate_prim_file | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/bin/generate_prim_file b/bin/generate_prim_file index 9474472f4..3e7f9fcb6 100755 --- a/bin/generate_prim_file +++ b/bin/generate_prim_file @@ -12,7 +12,6 @@ import atexit import time from datetime import datetime import fcntl -import psutil def readline_nonblocking(output): @@ -102,7 +101,8 @@ finished = False # run simulation print(' '.join(sim_cmd)) p = subprocess.Popen(args=sim_cmd, env=dawn_env, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, + preexec_fn=os.setsid) __child_pid = p.pid while elapse.seconds < args.timeout: line = readline_nonblocking(p.stdout) @@ -134,14 +134,10 @@ while elapse.seconds < args.timeout: time.sleep(1) -p.kill() -# use to kill the subprocess generated from the python wrapper -# this is unsafe so maybe more checks required -for proc in psutil.process_iter(): - pinfo = proc.as_dict(attrs=['pid', 'name', 'create_time']) - if pinfo['pid'] == p.pid + 1 and pinfo['name'] == 'python': - print('kill {}, generated from {}'.format(pinfo, p.pid)) - os.kill(pinfo['pid'], signal.SIGTERM) +try: + os.killpg(os.getpgid(p.pid), signal.SIGTERM) +except ProcessLookupError: + pass # assume process is dead # revert the change #os.system('sed -i \'s/radius=\"EcalEndcapP_FiberRadius*10\"/radius=\"EcalEndcapP_FiberRadius\"/\' {}'.format(ci_ecal)) From 52819f492d7f2042e49202a4275820f9bdaef0dc Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Sun, 5 May 2024 11:52:01 -0400 Subject: [PATCH 23/25] calibrations.xml: add LUTs for drich, pfrich and tof (#719) This adds LUTs for use in EICrecon. --- compact/calibrations.xml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/compact/calibrations.xml b/compact/calibrations.xml index 250d0709a..d9e89bc90 100644 --- a/compact/calibrations.xml +++ b/compact/calibrations.xml @@ -9,11 +9,26 @@ + + + + + + + + + + + + + + + From 66327439198f47563e56f925fa686aac07708eb6 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Sun, 5 May 2024 11:56:05 -0400 Subject: [PATCH 24/25] PFRICH: restore sensititvity to hits (#715) Fixes a minor regression from the latest geometry update in #664. Fixes: #706 --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/PFRICH_geo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PFRICH_geo.cpp b/src/PFRICH_geo.cpp index db9fbe1bc..1d2ee5613 100644 --- a/src/PFRICH_geo.cpp +++ b/src/PFRICH_geo.cpp @@ -305,6 +305,7 @@ static Ref_t createDetector(Detector& description, xml_h e, SensitiveDetector se Volume hrppdVol_air(detName + "_air_hrppd", hrppd_Solid, air); Volume hrppdVol(detName + "_hrppd", hrppd_Solid, sensorMat); + hrppdVol_air.setSensitiveDetector(sens); hrppdVol_air.setVisAttributes(gasvolVis); DetElement hrppdDE(sdet, "hrppd_de", 0); From 5a737d5c5baf7edff699804d7605cfa75b47872e Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Tue, 7 May 2024 12:34:00 -0400 Subject: [PATCH 25/25] calibrations.xml: update to use latest tof.lut and pfrich.lut (#721) This updates to use the latest LUT from https://github.com/eic/epic-data/pull/12 No binning change, so we don't need any file renames. --- compact/calibrations.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compact/calibrations.xml b/compact/calibrations.xml index d9e89bc90..b5392ec18 100644 --- a/compact/calibrations.xml +++ b/compact/calibrations.xml @@ -22,12 +22,12 @@ - + - +