Skip to content

Commit c7cbb71

Browse files
committed
Improve safety calculations in Tessellated solid
Optimization: Cache safety and only recalculate when becoming invalid. This works since safety can be underestimated and does not need to be precise. Precise safety evaluation for Tessellated is expensive.
1 parent 23fa9c3 commit c7cbb71

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

Detectors/Base/include/DetectorsBase/O2Tessellated.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ class O2Tessellated : public TGeoBBox
133133
template <bool closest_facet = false>
134134
Double_t SafetyKernel(const Double_t* point, bool in, int* closest_facet_id = nullptr) const;
135135

136+
// cached values for safety
137+
mutable float mLast_x;
138+
mutable float mLast_y;
139+
mutable float mLast_z;
140+
mutable float mCachedSafety;
141+
mutable size_t cached_counter = 0;
142+
mutable size_t call_counter = 0;
143+
136144
ClassDefOverride(O2Tessellated, 1) // tessellated shape class
137145
};
138146

Detectors/Base/src/O2Tessellated.cxx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1349,8 +1349,30 @@ Double_t O2Tessellated::Safety(const Double_t* point, Bool_t in) const
13491349
// we could use some caching here (in future) since queries to the solid will likely
13501350
// be made with some locality
13511351

1352+
if (in) {
1353+
call_counter++;
1354+
// distance to last known evaluation
1355+
const auto xd = float(point[0]) - mLast_x;
1356+
const auto yd = float(point[1]) - mLast_y;
1357+
const auto zd = float(point[2]) - mLast_z;
1358+
const auto d2 = xd * xd + yd * yd + zd * zd;
1359+
1360+
if (d2 < mCachedSafety * mCachedSafety) {
1361+
// we moved less than known safety
1362+
mCachedSafety - std::sqrt(d2);
1363+
cached_counter++;
1364+
}
1365+
}
1366+
13521367
// fall-back to precise safety kernel
1353-
return SafetyKernel<false>(point, in);
1368+
const auto safety = SafetyKernel<false>(point, in);
1369+
if (in) {
1370+
mLast_x = point[0];
1371+
mLast_y = point[1];
1372+
mLast_z = point[2];
1373+
mCachedSafety = safety;
1374+
}
1375+
return safety;
13541376
}
13551377

13561378
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)