Skip to content

Commit 5bb7992

Browse files
committed
feat(tofd):Add CI tests and auto-generation of ROOT geometry
Add missing script
1 parent c2d9d9c commit 5bb7992

9 files changed

Lines changed: 371 additions & 33 deletions

File tree

califa/README.md

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ Event data classes will be written [[like this]] in this file.
77

88
### (Main) FairTasks:
99
Classes generating new, higher level TClonesArray data from
10-
existing data.
11-
Tasks will be written in double curly braces here.
10+
existing data. Tasks will be written in double curly braces here.
1211

1312
Tasks are:
1413

@@ -28,11 +27,6 @@ These files generally hold channel-specific data used for calibration and the li
2827
- ./pars/R3BCalifaGeometry.h -- helper class to fetch infos on the positions and orientation of the crystals
2928
- ./pars/R3BCalifaContFact.h
3029

31-
To make sure that these are impossible to create/edit/view by unauthorized programs such as
32-
text editors or shell scripts, these classes are generally serialized to ROOT's exclusive binary
33-
only .root format. (There exist apostate rumors of a legacy FairParAsciiFileIo format which is
34-
readable by both humans and 3rd party tools.)
35-
3630
### online FairTasks
3731
- ./online/R3BCalifaOnlineSpectra.h
3832
- ./online/R3BCalifaDemoOnlineSpectra.h
@@ -49,10 +43,9 @@ readable by both humans and 3rd party tools.)
4943

5044
- ./ROOT_template_hacks.h -- helper class to wrap ROOT stuff in a std c++ way
5145
- ./CalifaLinkDef.h -- linking directives for CINT.
52-
- ../geometry/califa*.root -- 14 different ROOT-only binary files containing the material and orientation
53-
of the crystals and holding structure. At one point, these were probably generated by any of the 9 files matching
54-
- ../macros/r3b/geo/create_califa*.C. The pigeonhole principle suggests that there is not a bijection between
55-
the latter and the former.
46+
- ../geometry/califa*.root -- 9 different ROOT-only binary files containing the material and orientation
47+
of the crystals and holding structure. These are generated during the R3BRoot compilation by the macro:
48+
- /califa/geobase/create_califa_geo.C
5649

5750
# Califa processing chains
5851

califa/geobase/create_califa_geo.C

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void create_califa_geo_selector(const std::string expNumber = "nominal",
6565
f->Close();
6666
delete StruGeom;
6767

68-
auto fRefRot = std::make_unique<TGeoRotation>();
68+
auto fRefRot = new TGeoRotation();
6969
TGeoManager* gGeoMan = nullptr;
7070

7171
// ------- Load media from media file -------------------------
@@ -286,15 +286,15 @@ void create_califa_geo_selector(const std::string expNumber = "nominal",
286286
Fatal("Main", "Medium vacuum not found");
287287

288288
// -------------- Create geometry and top volume ---------------
289-
gGeoMan = (TGeoManager*)gROOT->FindObject("FAIRGeom");
289+
gGeoMan = static_cast<TGeoManager*>(gROOT->FindObject("FAIRGeom"));
290290
gGeoMan->SetName("CALIFAgeom");
291-
TGeoVolume* top = new TGeoVolumeAssembly("TOP");
291+
auto top = new TGeoVolumeAssembly("TOP");
292292
gGeoMan->SetTopVolume(top);
293293

294294
// Defintion of the Mother Volume --------------------------------
295-
auto tgeotrans0 = new TGeoCombiTrans("tgeotrans0", 0., 0., 9., fRefRot.get());
295+
auto tgeotrans0 = new TGeoCombiTrans("tgeotrans0", 0., 0., 9., fRefRot);
296296
tgeotrans0->RegisterYourself();
297-
auto tgeotrans1 = new TGeoCombiTrans("tgeotrans1", 0, 0, 0., fRefRot.get());
297+
auto tgeotrans1 = new TGeoCombiTrans("tgeotrans1", 0, 0, 0., fRefRot);
298298
tgeotrans1->RegisterYourself();
299299

300300
auto mother_outer = new TGeoTube("mother_outer", 0., 81., (58. + 73.5) / 2.);
@@ -309,8 +309,8 @@ void create_califa_geo_selector(const std::string expNumber = "nominal",
309309
"califa_mother",
310310
"mother_outer:tgeotrans0 - inner_hole:tgeotrans0 + mother_endcap:tgeotrans1 + mother_endcap2:tgeotrans1");
311311

312-
auto pWorld = std::make_unique<TGeoVolume>("CalifaWorld", califa_mother, pAirMedium);
313-
top->AddNode(pWorld.get(), 0, tgeotrans1);
312+
auto pWorld = new TGeoVolume("CalifaWorld", califa_mother, pAirMedium);
313+
top->AddNode(pWorld, 0, tgeotrans1);
314314

315315
// FINAL CALIFA CARREL + iPHOS VERSION (SINCE NOV 2019)
316316
const size_t N_ALV_TYPES = 23; // alveolar structures
@@ -1496,7 +1496,7 @@ void create_califa_geo_selector(const std::string expNumber = "nominal",
14961496
}
14971497

14981498
if (fMakeStr)
1499-
CreateHoldingStructure(pWorld.get(), holding_structure, pCarbonFibreMedium, pAlMedium, dispCalMes, dispCalWix);
1499+
CreateHoldingStructure(pWorld, holding_structure, pCarbonFibreMedium, pAlMedium, dispCalMes, dispCalWix);
15001500

15011501
gGeoMan->CloseGeometry();
15021502
gGeoMan->CheckOverlaps(0.001);

tofd/CMakeLists.txt

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@ set(SRCS
2424
calibration/R3BTofDMapped2Cal.cxx
2525
calibration/R3BTofDCal2Hit.cxx
2626
online/R3BTofDOnlineSpectra.cxx
27-
#R3BTofDCal2Histo.cxx
28-
#R3BTofDCal2HistoPar.cxx
29-
#R3BTofDChangePar.cxx
30-
#R3BTofDCal2Hit.cxx
31-
#R3BGeoTofD.cxx
32-
#R3BGeoTofDPar.cxx
33-
#R3BTofDContFact.cxx
3427
#R3BTofDDigiPar.cxx
3528
)
3629

@@ -47,13 +40,6 @@ set(HEADERS
4740
calibration/R3BTofDMapped2Cal.h
4841
calibration/R3BTofDCal2Hit.h
4942
online/R3BTofDOnlineSpectra.h
50-
#R3BTofDCal2Histo.h
51-
#R3BTofDCal2HistoPar.h
52-
#R3BTofDChangePar.h
53-
#R3BTofDCal2Hit.h
54-
#R3BGeoTofD.h
55-
#R3BGeoTofDPar.h
56-
#R3BTofDContFact.h
5743
#R3BTofDDigiPar.h
5844
)
5945

@@ -77,3 +63,8 @@ add_library_with_dictionary(
7763
R3BTracking
7864
ROOT::Spectrum
7965
R3BTCal)
66+
67+
if(BUILD_GEOMETRY)
68+
add_subdirectory(geobase)
69+
endif()
70+
add_subdirectory(test)

tofd/geobase/CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
##############################################################################
2+
# Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH #
3+
# Copyright (C) 2025 Members of R3B Collaboration #
4+
# #
5+
# This software is distributed under the terms of the #
6+
# GNU General Public Licence (GPL) version 3, #
7+
# copied verbatim in the file "LICENSE". #
8+
# #
9+
# In applying this license GSI does not waive the privileges and immunities #
10+
# granted to it by virtue of its status as an Intergovernmental Organization #
11+
# or submit itself to any jurisdiction. #
12+
##############################################################################
13+
14+
if(NOT EXISTS "${R3BROOT_SOURCE_DIR}/geometry/tofd_v2025.6.geo.root")
15+
message(STATUS "Starting to generate the standard root geometry v2025.6 for TofD")
16+
execute_process(COMMAND root -l -q -x "${R3BROOT_SOURCE_DIR}/tofd/geobase/create_tofd_geo.C")
17+
message(STATUS "${BYellow}TofD standard root geometry v2025.6 has been created${CR} ")
18+
else(NOT EXISTS "${R3BROOT_SOURCE_DIR}/geometry/tofd_v2025.6.geo.root")
19+
message(STATUS "${BYellow}TofD standard root geometry v2025.6 already exists${CR} ")
20+
endif(NOT EXISTS "${R3BROOT_SOURCE_DIR}/geometry/tofd_v2025.6.geo.root")
21+
22+
generate_root_test_script(${R3BROOT_SOURCE_DIR}/tofd/geobase/create_tofd_geo.C)
23+
add_test(NAME TofDRootGeometry COMMAND ${R3BROOT_BINARY_DIR}/tofd/geobase/create_tofd_geo.sh)
24+
set_tests_properties(TofDRootGeometry PROPERTIES TIMEOUT "2000")
25+
set_tests_properties(TofDRootGeometry PROPERTIES PASS_REGULAR_EXPRESSION
26+
"Macro finished successfully.")

tofd/geobase/create_tofd_geo.C

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/******************************************************************************
2+
* Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3+
* Copyright (C) 2022-2025 Members of R3B Collaboration *
4+
* *
5+
* This software is distributed under the terms of the *
6+
* GNU General Public Licence (GPL) version 3, *
7+
* copied verbatim in the file "LICENSE". *
8+
* *
9+
* In applying this license GSI does not waive the privileges and immunities *
10+
* granted to it by virtue of its status as an Intergovernmental Organization *
11+
* or submit itself to any jurisdiction. *
12+
******************************************************************************/
13+
14+
// ----------------------------------------------------------------------------
15+
// Author: M. Feijoo
16+
//
17+
// Last Update: 06/05/2022
18+
//
19+
// Comments:
20+
// ----------------------------------------------------------------------------
21+
22+
#include "TROOT.h"
23+
#include <TGeoManager.h>
24+
#include <TGeoMatrix.h>
25+
#include <TGeoVolume.h>
26+
#include <TMath.h>
27+
#include <fstream>
28+
#include <iomanip>
29+
#include <iostream>
30+
31+
// --------------------------------------------------------------------------
32+
// Configurable geometry for the Tof.
33+
// Use this macro to create root files with the different configurations
34+
// and positions/angles of the detector.
35+
//
36+
// Execute macro: root -l
37+
// .L create_tofd_geo.C
38+
// create_tofd_geo()
39+
// --------------------------------------------------------------------------
40+
41+
void create_tofd_geo(const char* geoTag = "v2025.6")
42+
{
43+
44+
TString geoPath = gSystem->Getenv("VMCWORKDIR");
45+
if (geoPath.IsNull())
46+
{
47+
std::cerr << "\033[35mERROR: VMCWORKDIR is not defined\033[0m" << std::endl;
48+
gApplication->Terminate();
49+
}
50+
51+
auto fRefRot = new TGeoRotation();
52+
TGeoManager* gGeoMan = nullptr;
53+
54+
// ------- Load media from media file -----------------------------------
55+
FairGeoLoader* geoLoad = new FairGeoLoader("TGeo", "FairGeoLoader");
56+
FairGeoInterface* geoFace = geoLoad->getGeoInterface();
57+
TString medFile = geoPath + "/geometry/media_r3b.geo";
58+
geoFace->setMediaFile(medFile);
59+
geoFace->readMedia();
60+
gGeoMan = gGeoManager;
61+
// --------------------------------------------------------------------------
62+
63+
// ------- Geometry file name (output) ----------------------------------
64+
TString geoFileName = geoPath + "/geometry/tofd_";
65+
geoFileName = geoFileName + geoTag + ".geo.root";
66+
// --------------------------------------------------------------------------
67+
68+
// ----------------- Get and create the required media -----------------
69+
FairGeoMedia* geoMedia = geoFace->getMedia();
70+
FairGeoBuilder* geoBuild = geoLoad->getGeoBuilder();
71+
72+
auto mAir = geoMedia->getMedium("Air");
73+
if (!mAir)
74+
Fatal("Main", "FairMedium Air not found");
75+
geoBuild->createMedium(mAir);
76+
auto pAirMedium = gGeoMan->GetMedium("Air");
77+
if (!pAirMedium)
78+
Fatal("Main", "Medium Air not found");
79+
80+
auto mTof = geoMedia->getMedium("plasticForTOF");
81+
if (!mTof)
82+
Fatal("Main", "FairMedium plasticForTOF not found");
83+
geoBuild->createMedium(mTof);
84+
auto pMedTof = gGeoMan->GetMedium("plasticForTOF");
85+
if (!pMedTof)
86+
Fatal("Main", "Medium plasticForTOF not found");
87+
88+
// -------------- Create geometry and top volume -------------------------
89+
gGeoMan = static_cast<TGeoManager*>(gROOT->FindObject("FAIRGeom"));
90+
gGeoMan->SetName("TOFDgeom");
91+
auto top = new TGeoVolumeAssembly("TOP");
92+
gGeoMan->SetTopVolume(top);
93+
94+
// Top Volume
95+
auto pWorld = gGeoMan->GetTopVolume();
96+
pWorld->SetVisLeaves(kTRUE);
97+
98+
// Detector specifications
99+
const size_t n_planes = 4;
100+
const size_t n_paddles = 44;
101+
102+
// Paddle dimensions in cm
103+
const float dx = 2.7;
104+
const float dy = 100.0;
105+
const float dz = 0.5;
106+
107+
// Positions (for each paddle)
108+
float x = 0.0, y = 0.0, z = 0.0;
109+
float shift = 0.0;
110+
const float air_gap_paddles = 0.04;
111+
const float air_gap_planes = 3.0;
112+
113+
// Plane definition
114+
auto Plane = gGeoMan->MakeBox(
115+
"Plane", pAirMedium, dx / 2. * n_paddles + dx / 4. + (n_paddles - 1) * air_gap_paddles / 2., dy / 2., dz / 2.);
116+
Plane->SetLineColor(1);
117+
118+
auto detector_width = n_paddles * dx + (n_paddles - 1) * air_gap_paddles;
119+
auto tofd = new TGeoVolumeAssembly("TOFD");
120+
121+
auto Paddle = gGeoMan->MakeBox("Paddle", pMedTof, dx / 2., dy / 2., dz / 2.);
122+
Paddle->SetVisLeaves(kTRUE);
123+
Paddle->SetLineColor(kBlue);
124+
125+
for (size_t n = 0; n < n_paddles; n++)
126+
{
127+
x = -detector_width / 2 + dx / 2 + n * (dx + air_gap_paddles);
128+
129+
auto pMatrix = new TGeoCombiTrans("", x, y, z, fRefRot);
130+
pMatrix->RegisterYourself();
131+
Plane->AddNode(Paddle, n + 1, pMatrix);
132+
}
133+
134+
for (size_t m = 0; m < n_planes; m++)
135+
{
136+
shift = (m % 2 == 0) ? -dx / 4. : dx / 4.;
137+
138+
auto z_plane = -dz * n_planes / 2 - (n_planes - 1) * air_gap_planes / 2 + dz / 2 + m * (dz + air_gap_planes) +
139+
(m > 1 ? 1.5 : -1.5);
140+
auto pMatrix_planes = new TGeoCombiTrans("", shift, y, z_plane, fRefRot);
141+
pMatrix_planes->RegisterYourself();
142+
tofd->AddNode(Plane, m + 1, pMatrix_planes);
143+
}
144+
145+
auto t0 = new TGeoCombiTrans();
146+
t0->RegisterYourself();
147+
pWorld->AddNode(tofd, 1, t0);
148+
149+
// --------------- Finish -----------------------------------------------
150+
gGeoMan->CloseGeometry();
151+
gGeoMan->CheckOverlaps(0.001);
152+
gGeoMan->PrintOverlaps();
153+
gGeoMan->Test();
154+
155+
TFile geoFile(geoFileName, "RECREATE");
156+
top->Write();
157+
// top->Draw("ogl");
158+
geoFile.Close();
159+
std::cout << "\033[34m Creating geometry:\033[0m "
160+
<< "\033[33m" << geoFileName << " \033[0m" << std::endl;
161+
std::cout << "Macro finished successfully." << std::endl;
162+
gApplication->Terminate();
163+
}

tofd/test/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
##############################################################################
2+
# Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH #
3+
# Copyright (C) 2025 Members of R3B Collaboration #
4+
# #
5+
# This software is distributed under the terms of the #
6+
# GNU General Public Licence (GPL) version 3, #
7+
# copied verbatim in the file "LICENSE". #
8+
# #
9+
# In applying this license GSI does not waive the privileges and immunities #
10+
# granted to it by virtue of its status as an Intergovernmental Organization #
11+
# or submit itself to any jurisdiction. #
12+
##############################################################################
13+
14+
if(GTEST_FOUND)
15+
add_executable(
16+
TofDUnitTests
17+
testTofDContainerPar.cxx)
18+
target_link_libraries(TofDUnitTests PRIVATE GTest::gtest_main GTest::gmock_main
19+
R3BTofD)
20+
gtest_discover_tests(TofDUnitTests DISCOVERY_TIMEOUT 600)
21+
endif(GTEST_FOUND)
22+
23+
generate_root_test_script(${R3BROOT_SOURCE_DIR}/tofd/test/testTofDSimulation.C)
24+
add_test(NAME TofDSimulation COMMAND ${R3BROOT_BINARY_DIR}/tofd/test/testTofDSimulation.sh)
25+
set_tests_properties(TofDSimulation PROPERTIES TIMEOUT "2000")
26+
set_tests_properties(TofDSimulation PROPERTIES PASS_REGULAR_EXPRESSION
27+
"Macro finished successfully.")

0 commit comments

Comments
 (0)