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/.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 diff --git a/.github/workflows/linux-eic-shell.yml b/.github/workflows/linux-eic-shell.yml index fe7a81a42..449d03beb 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,9 +189,40 @@ 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: + 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: @@ -253,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 @@ -275,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 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 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c8a6affb0..236d6ff38 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,14 +1,12 @@ -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 - 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.4 hooks: - id: clang-format - repo: https://github.com/Lucas-C/pre-commit-hooks 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 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 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} 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)) 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): 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/compact/calibrations.xml b/compact/calibrations.xml new file mode 100644 index 000000000..b5392ec18 --- /dev/null +++ b/compact/calibrations.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compact/definitions.xml b/compact/definitions.xml index 08fd68a08..a50a06e66 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/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/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/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/compact/pid/drich.xml b/compact/pid/drich.xml index 7dc0e5b05..cde823bfa 100644 --- a/compact/pid/drich.xml +++ b/compact/pid/drich.xml @@ -22,9 +22,9 @@ - + - + @@ -328,7 +328,7 @@ photodetector unit (PDU) assembly diagram: matrix of SiPMs with services radius="110.0*cm" /> 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/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/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: 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::" 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/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 3668d000c..08ce870eb 100755 --- a/scripts/view12/generate_eps +++ b/scripts/view12/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #trignometry sin () @@ -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/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 1f2c9afe9..ca1fca10b 100755 --- a/scripts/view14/generate_eps +++ b/scripts/view14/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #trignometry sin () @@ -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..d05e5ca81 100755 --- a/scripts/view15/generate_eps +++ b/scripts/view15/generate_eps @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #trignometry sin () @@ -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 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." 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/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..9c6c337a5 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,15 +228,16 @@ 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; - Fiber(const Point& p) : pos(p){}; + 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 new file mode 100644 index 000000000..9b4f644d1 --- /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/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/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/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) 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 e23dc7957..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,19 +926,28 @@ 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)); + 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.); @@ -795,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.), @@ -811,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; } @@ -872,73 +1033,95 @@ 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(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); + 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(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); + 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; } 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/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..1d2ee5613 100644 --- a/src/PFRICH_geo.cpp +++ b/src/PFRICH_geo.cpp @@ -31,679 +31,703 @@ 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.setSensitiveDetector(sens); + 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..2bab39730 100644 --- a/src/SupportServiceMaterial_geo.cpp +++ b/src/SupportServiceMaterial_geo.cpp @@ -21,93 +21,151 @@ 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); + // 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; + 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, 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()); + 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; + // 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); } - // 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()); + 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); } - // 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); - - // visualization? - if (x_child.hasAttr(_U(vis))) { - vol.setVisAttributes(descr.visAttributes(x_child.visStr())); + 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); } - return {vol, tr}; + } else { + printout(ERROR, x_det.nameStr(), "Unknown support type: %s", type.c_str()); + std::exit(1); } - 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); + // 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); + + // 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 +183,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 new file mode 100644 index 000000000..122181474 --- /dev/null +++ b/src/forwardBeamPipeBrazil.cpp @@ -0,0 +1,600 @@ +// 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) 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/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 @@ + +