From 48a5603bf0cee9cf8c5fbdc6edcf898596dd3ba4 Mon Sep 17 00:00:00 2001 From: Michael Pitt Date: Wed, 13 Nov 2024 20:59:30 +0100 Subject: [PATCH] New b0 ecal geo (#788) ### Briefly, what does this PR introduce? This RP introduces fully configurable B0 ECAL geometry, allowing the setup coordinates of every single crystal. During the iteration with the designers, the B0 ECAL position was optimized and moved forward (downstream from the IP) by 15 cm. As a consequence, the B0 tracker position was rearranged, introducing a larger space between detector layers. In addition, a B0 exit window is added to the simulation to make a more realistic detector response ![image](https://github.com/user-attachments/assets/accb4ac3-55f9-4026-865c-76838dd109d2) ### What kind of change does this PR introduce? - [ ] Bug fix (issue #__) - [ ] New feature (issue #__) - [ ] Documentation update - [X] Other: B0 ECAL geometry update ### Please check if this PR fulfills the following: - [X] Tests for the changes have been added - [ ] Documentation has been added / updated - [X] Changes have been communicated to collaborators https://indico.bnl.gov/event/24923/contributions/97007/attachments/57475/98683/2024_09_24_B0_Geometry_update.pdf ### Does this PR introduce breaking changes? What changes might users need to make to their code? no ### Does this PR change default behavior? Slight change in B0 detector performance can be anticipated (better resolution in reconstructed tracks, and improved acceptance of B0 ECAL. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Dmitry Kalinkin --- compact/definitions.xml | 5 +- compact/far_forward/B0_ECal.xml | 192 +++++++++++++++++---- compact/far_forward/beampipe_hadron_B0.xml | 7 +- compact/far_forward/definitions.xml | 3 + src/B0ECal_geo.cpp | 5 - src/B0Window_geo.cpp | 56 ++++++ src/forwardBeamPipeBrazil.cpp | 20 ++- src/magnetVacuumFF.cpp | 14 +- 8 files changed, 251 insertions(+), 51 deletions(-) create mode 100644 src/B0Window_geo.cpp diff --git a/compact/definitions.xml b/compact/definitions.xml index 5b3eac10f..b4ae23299 100644 --- a/compact/definitions.xml +++ b/compact/definitions.xml @@ -46,8 +46,8 @@ The unused IDs below are saved for future use. #### (10-24) Interaction region beamline - - Beampipe ID : 10 - - Unused IDs: 11-24 + - Beampipe ID : 10-11 + - Unused IDs: 12-24 @@ -297,6 +297,7 @@ The unused IDs below are saved for future use. + #### (190-199) Far Backward Beamline Detectors diff --git a/compact/far_forward/B0_ECal.xml b/compact/far_forward/B0_ECal.xml index e7cbd128a..57e7cf135 100644 --- a/compact/far_forward/B0_ECal.xml +++ b/compact/far_forward/B0_ECal.xml @@ -1,23 +1,21 @@ - + - + - - - - - - - - - - - + + + + + + + + + @@ -31,30 +29,166 @@ type="B0_ECAL" readout="B0ECalHits"> - + - + + sizez="B0ECal_CrystalModule_length_a" + material="PbWO4" + vis="GreenVis"/> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compact/far_forward/beampipe_hadron_B0.xml b/compact/far_forward/beampipe_hadron_B0.xml index e739fdf68..b55e377ab 100644 --- a/compact/far_forward/beampipe_hadron_B0.xml +++ b/compact/far_forward/beampipe_hadron_B0.xml @@ -11,10 +11,15 @@ - + + + + + + diff --git a/compact/far_forward/definitions.xml b/compact/far_forward/definitions.xml index 31e8d42d1..9c8874021 100644 --- a/compact/far_forward/definitions.xml +++ b/compact/far_forward/definitions.xml @@ -56,6 +56,9 @@ + + + The inner radii are temporarily enlarged so the inner coils (UnionSolid) are not built with overlapping volumes Overlapping boolean volumes may cause issues in DAWN view, even if they were good in simulation diff --git a/src/B0ECal_geo.cpp b/src/B0ECal_geo.cpp index f5c271266..e4377a636 100644 --- a/src/B0ECal_geo.cpp +++ b/src/B0ECal_geo.cpp @@ -58,11 +58,6 @@ static Ref_t createDetector(Detector& desc, xml_h e, SensitiveDetector sens) { addModuleNumbers(sector, nmod); } - for (xml_coll_t disk(plm, _Unicode(disk)); disk; ++disk) { - auto [sector, nmod] = ip6::geo::add_disk(build_module, desc, detVol, disk, sens, sector_id++); - addModuleNumbers(sector, nmod); - } - // 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())); diff --git a/src/B0Window_geo.cpp b/src/B0Window_geo.cpp new file mode 100644 index 000000000..250078a16 --- /dev/null +++ b/src/B0Window_geo.cpp @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright (C) 2022 Dhevan Gangadharan + +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Shapes.h" +#include "DDRec/DetectorData.h" +#include "DDRec/Surface.h" +#include "XML/Layering.h" +#include + +using namespace std; +using namespace dd4hep; + +static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector /*sens*/) { + + xml_det_t x_det = e; + xml_comp_t x_dim = x_det.dimensions(); + xml_comp_t x_pos = x_det.position(); + xml_comp_t x_rot = x_det.rotation(); + // + string det_name = x_det.nameStr(); + string mat_name = dd4hep::getAttrOrDefault(x_det, _U(material), "StainlessSteel"); + // + double sizeR = x_dim.r(); + double sizeZ = x_dim.z(); + double sizeR_el = x_dim.x(); + double sizeR_had = x_dim.y(); + 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(); + + Tube tube(0.0, sizeR, sizeZ); + Tube tube_el(0.0, sizeR_el, sizeZ); + Tube tube_had(0.0, sizeR_had, sizeZ); + SubtractionSolid exit_window(tube, tube_had, Position(0.0, 0.0, 0.0)); + exit_window = SubtractionSolid(exit_window, tube_el, Position(-posX, 0.0, 0.0)); + + Volume vol(det_name + "_vol_ExitWindow", exit_window, description.material(mat_name)); + vol.setVisAttributes(description.visAttributes(x_det.visStr())); + + Transform3D pos(RotationZYX(rotX, rotY, rotZ), Position(posX, posY, posZ)); + + DetElement det(det_name, x_det.id()); + Volume motherVol = description.pickMotherVolume(det); + PlacedVolume phv = motherVol.placeVolume(vol, pos); + + det.setPlacement(phv); + + return det; +} + +DECLARE_DETELEMENT(B0Window, create_detector) diff --git a/src/forwardBeamPipeBrazil.cpp b/src/forwardBeamPipeBrazil.cpp index 122181474..aa3cc2cd2 100644 --- a/src/forwardBeamPipeBrazil.cpp +++ b/src/forwardBeamPipeBrazil.cpp @@ -16,11 +16,12 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * 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(); + 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(); + xml_comp_t x_pos = x_det.position(); PlacedVolume pv_assembly; @@ -48,6 +49,10 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * -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 b0PFCenter_z = + x_pos + .z(); // location of the center of B0 magnet, used to define the hadron beampipe inside the magnet + 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 @@ -467,8 +472,9 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * 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))); + v_b0_hadron_tube, Transform3D(RotationY(crossingAngle), + Position(b0PFCenter_z * sin(crossingAngle), 0.0, + b0PFCenter_z * cos(crossingAngle)))); // 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); diff --git a/src/magnetVacuumFF.cpp b/src/magnetVacuumFF.cpp index 3ffe3d1d8..2072ab782 100644 --- a/src/magnetVacuumFF.cpp +++ b/src/magnetVacuumFF.cpp @@ -112,12 +112,12 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * // that beam pipe geometry //------------------------------------------- - radii_magnet[0] = 2.9; // cm - lengths_magnet[0] = 120.0; // cm - rotation_magnet[0] = -0.025; // radians - x_elem_magnet[0] = -16.5; // cm - y_elem_magnet[0] = 0.0; // cm - z_elem_magnet[0] = 640.0; // cm + radii_magnet[0] = 2.9; // cm + lengths_magnet[0] = 120.0; // cm + rotation_magnet[0] = -0.025; // radians + x_elem_magnet[0] = 640.0 * sin(-0.025); // cm + y_elem_magnet[0] = 0.0; // cm + z_elem_magnet[0] = 640.0 * cos(-0.025); // cm //------------------------------------------- //calculate entrance/exit points of magnets @@ -176,7 +176,7 @@ static Ref_t create_detector(Detector& det, xml_h e, SensitiveDetector /* sens * for (int gapIdx = 0; gapIdx < numGaps; gapIdx++) { inRadius.push_back(0.0); - outRadius.push_back(radii_magnet[gapIdx + 1]); + outRadius.push_back(radii_magnet[gapIdx]); phi_initial.push_back(0.0); phi_final.push_back(2 * M_PI); nxLow.push_back(-(length_gap[gapIdx] / 2.0) *