GCC Code Coverage Report


Directory: ./
File: src/calib/mkROOTGeo.cc
Date: 2025-09-01 06:19:01
Exec Total Coverage
Lines: 0 86 0.0%
Functions: 0 9 0.0%
Branches: 0 28 0.0%

Line Branch Exec Source
1 #include "na64calib/mkROOTGeo.hh"
2
3 #if defined(ROOT_FOUND) && ROOT_FOUND
4
5 #include "na64util/str-fmt.hh"
6
7 #include <TGeoVolume.h>
8 #include <TGeoMatrix.h>
9 #include <TGeoManager.h>
10 #include <TGeoMaterial.h>
11
12 namespace na64dp {
13
14 PlacementsBasedGeometry::PlacementsBasedGeometry(
15 TGeoManager * gmgr
16 , log4cpp::Category & L_
17 ) : _geoManager(gmgr)
18 , _L(L_)
19 {
20 _instantiate_materials(); // TODO: other source
21 }
22
23 PlacementsBasedGeometry::~PlacementsBasedGeometry() {
24 }
25
26 void
27 PlacementsBasedGeometry::_instantiate_materials() {
28 // TODO: this hardcoded definitions will be most likely deleted in favour
29 // of more elaborated materials management API. Copied from p348reco
30 //_matMixtures
31 unsigned int mediumIndex = 0;
32 TGeoMaterial *_siliconMat = new TGeoMaterial( "siliconMat"
33 , 28.0855
34 , 14.
35 , 2.329 );
36 _siliconMat->SetRadLen(1.);//calc automatically, need this for elemental mats.
37 _matMixtures.emplace( "silicon"
38 , new TGeoMedium( "silicon", mediumIndex++, _siliconMat, 0) );
39
40 TGeoMixture *_airMat = new TGeoMixture("airMat",3);
41 _airMat->AddElement(14.01,7.,.78);
42 _airMat->AddElement(16.00,8.,.21);
43 _airMat->AddElement(39.95,18.,.01);
44 _airMat->SetDensity(1.2e-3);
45 _matMixtures.emplace( "air"
46 , new TGeoMedium("air", mediumIndex++, _airMat, 0) );
47
48 TGeoMixture *_vacuumMat = new TGeoMixture("vacuumMat",3);
49 _vacuumMat->AddElement(14.01,7.,.78);
50 _vacuumMat->AddElement(16.00,8.,.21);
51 _vacuumMat->AddElement(39.95,18.,.01);
52 _vacuumMat->SetDensity(1.2e-15);
53 _matMixtures.emplace( "vacuum"
54 , new TGeoMedium("vacuum", mediumIndex++, _vacuumMat, 0) );
55 }
56
57 TGeoMatrix *
58 PlacementsBasedGeometry::_instantiate_ROOT_placement(const calib::Placement & pl) {
59 TGeoTranslation tr( pl.center[0], pl.center[1], pl.center[2] );
60 TGeoRotation rot( util::format("%s-rotation", pl.name.c_str()).c_str()
61 , pl.rot[0], pl.rot[1], pl.rot[2] );
62 // TODO: ROOT does not copy this object, but it is unclear whether it
63 // deletes it (memleak)
64 return new TGeoCombiTrans(tr, rot);
65 }
66
67 TGeoVolume *
68 PlacementsBasedGeometry::_instantiate_entity( const calib::Placement & pl
69 , TGeoVolume * parent ) {
70 TGeoVolume * volPtr = nullptr;
71 TGeoMedium * mediumPtr;
72 switch(pl.suppInfoType) {
73 case calib::Placement::kRegularWiredPlane :
74 case calib::Placement::kIrregularWiredPlane :
75 case calib::Placement::kVolumetricDetector :
76 {
77 volPtr = _geoManager->MakeBox( pl.name.c_str()
78 , mediumPtr = get_medium(pl.material)
79 , pl.size[0]/2
80 , pl.size[1]/2
81 , pl.size[2]/2
82 );
83 // ^^^ TODO: rotation?
84 _L << log4cpp::Priority::DEBUG
85 << "Created ROOT geometry box item \"" << pl.name << "\" of sizes "
86 << pl.size[0]
87 << "x" << pl.size[1]
88 << "x" << pl.size[2]
89 << " at " << pl.center[0]
90 << "x" << pl.center[1]
91 << "x" << pl.center[2]
92 << " filled with material \"" << mediumPtr->GetMaterial()->GetName()
93 << "\""
94 ;
95 } break;
96 // ...
97 default:
98 _L << log4cpp::Priority::WARN
99 << "No ROOT geometry set for placement item \""
100 << pl.name.c_str() << "\".";
101 return nullptr;
102 };
103 if( (!mediumPtr) && !pl.material.empty() ) {
104 NA64DP_RUNTIME_ERROR("Unknown material or medium \"%s\" (for entity \"%s\")."
105 , pl.material.c_str(), pl.name.c_str() );
106 }
107
108 //volPtr->SetTransparency(15);
109 //volPtr->SetLineColor(kBlue);
110 //^^^ TODO: parameterise?
111
112 parent->AddNode(volPtr, 1, _instantiate_ROOT_placement(pl));
113 assert(volPtr);
114 return volPtr;
115 }
116
117 void
118 PlacementsBasedGeometry::add_placement(const calib::Placement & pl ) {
119 _nativePlacements.push_back(pl);
120 }
121
122 std::pair<TVector3, TVector3>
123 PlacementsBasedGeometry::world_boundaries() const {
124 // init dft values to nan
125 float vs[2][3];
126 for( int i = 0; i < 2; ++i ) {
127 for( int j = 0; j < 3; ++j ) {
128 vs[i][j] = std::nan("0");
129 }
130 }
131 // iterate over all placements available
132 for(const calib::Placement & pl : _nativePlacements) {
133 // calculate radius of the sphere encompassing object (distance to
134 // most distant possible point, ignoring actual rotation)
135 float sz = sqrt( (std::isnan(pl.size[0]) ? 0. : pl.size[0]*pl.size[0])
136 + (std::isnan(pl.size[1]) ? 0. : pl.size[1]*pl.size[1])
137 + (std::isnan(pl.size[2]) ? 0. : pl.size[2]*pl.size[2])
138 );
139 // compare min/max estimation for each dimension
140 for( int j = 0; j < 3; ++j ) {
141 const float mn = pl.center[j] - sz
142 , mx = pl.center[j] + sz
143 ;
144 if( std::isnan(vs[0][j]) || vs[0][j] > mn ) vs[0][j] = mn;
145 if( std::isnan(vs[1][j]) || vs[1][j] < mx ) vs[1][j] = mx;
146 }
147 }
148 return std::pair<TVector3, TVector3>(
149 TVector3( vs[0][0], vs[0][1], vs[0][2] ),
150 TVector3( vs[1][0], vs[1][1], vs[1][2] ));
151 }
152
153 void
154 PlacementsBasedGeometry::instantiate_geometry( TGeoVolume * topVol ) {
155 for (const calib::Placement & pl : _nativePlacements) {
156 /*TGeoVolume * newVol = */ _instantiate_entity(pl, topVol);
157 }
158 _nativePlacements.clear();
159 }
160
161 TGeoMedium *
162 PlacementsBasedGeometry::get_medium(const std::string & nm) {
163 auto it = _matMixtures.find(nm);
164 if( _matMixtures.end() == it ) return nullptr;
165 return it->second;
166 }
167
168 }
169 #endif // defined(ROOT_FOUND) && ROOT_FOUND
170