Skip to content

Commit 4706dc8

Browse files
committed
Merge branch 'new_geometry' of github.com:pkurash/AliceO2 into new_geometry
merge
2 parents d7ce7e2 + 392421f commit 4706dc8

185 files changed

Lines changed: 82076 additions & 2443 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Common/DCAFitter/DCAFitterN_derivation.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,11 @@ I_XX -> I_XX + 1/sigma_X,prior^2 .
479479
In code this is implemented as
480480

481481
```cpp
482-
constexpr float XRegErrFactor = 10.f;
483-
const float sigmaX2 = C_YY * XRegErrFactor;
484-
sxx += 1.f / sigmaX2;
482+
static constexpr float XRegErrFactor = 10.f;
483+
...
484+
if (xRegErrFactor > 0.f) {
485+
sxx += 1.f / (cyy * xRegErrFactor);
486+
}
485487
```
486488

487489
This is different from multiplying `I_XX` by a number below one. A reduction of
@@ -491,7 +493,15 @@ not alter `I_YY`, `I_YZ`, or `I_ZZ`.
491493

492494
The regularization should remain weak. It is a numerical stabilizer for badly
493495
conditioned geometries, not an additional detector measurement of the local
494-
track `X` coordinate.
496+
track `X` coordinate. For this reason it is applied **only** where an invertible
497+
single-track contribution is actually required, i.e. for the `I_i` entering the
498+
chi2 minimization (`mTrcEInv`, hence `calcInverseWeight()`, `calcPCACoefs()`,
499+
`calcChi2()` and the Newton Hessian). `calcPCACovMatrix()` rebuilds the `I_i`
500+
with `TrackCovI::XRegNone`: there the prior is not needed (the sum over prongs is
501+
inverted, not the individual terms, and a genuinely ill-conditioned sum is
502+
detected and replaced by a loose dummy covariance), and including it would make
503+
the reported longitudinal vertex error follow the dummy `XRegErrFactor * C_YY`
504+
instead of the track slopes.
495505

496506
### `calcPCACovMatrix()`
497507

Common/DCAFitter/include/DCAFitter/DCAFitterN.h

Lines changed: 168 additions & 98 deletions
Large diffs are not rendered by default.

Common/DCAFitter/test/testDCAFitterN.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ inline void printStat(const FitStatusArray& a)
171171

172172
BOOST_AUTO_TEST_CASE(DCAFitterNProngs)
173173
{
174+
constexpr bool oldMode = false; // if true, use the old mode of DCAFitterN, which is less correct but faster
174175
constexpr int NTest = 10000;
175176
o2::utils::TreeStreamRedirector outStream("dcafitterNTest.root");
176177

@@ -196,6 +197,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs)
196197
std::memset(fitstat.data(), 0, sizeof(fitstat));
197198

198199
o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter
200+
ft.setOldMode(oldMode); // use the old mode of DCAFitterN
199201
ft.setBz(bz);
200202
ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway
201203
ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway
@@ -280,6 +282,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs)
280282
std::memset(fitstat.data(), 0, sizeof(fitstat));
281283

282284
o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter
285+
ft.setOldMode(oldMode); // use the old mode of DCAFitterN
283286
ft.setBz(bz);
284287
ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway
285288
ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway
@@ -366,6 +369,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs)
366369
std::memset(fitstat.data(), 0, sizeof(fitstat));
367370

368371
o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter
372+
ft.setOldMode(oldMode); // use the old mode of DCAFitterN
369373
ft.setBz(bz);
370374
ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway
371375
ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway
@@ -451,6 +455,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs)
451455
std::memset(fitstat.data(), 0, sizeof(fitstat));
452456

453457
o2::vertexing::DCAFitterN<2> ft; // 2 prong fitter
458+
ft.setOldMode(oldMode); // use the old mode of DCAFitterN
454459
ft.setBz(bz);
455460
ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway
456461
ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway
@@ -535,6 +540,7 @@ BOOST_AUTO_TEST_CASE(DCAFitterNProngs)
535540
std::memset(fitstat.data(), 0, sizeof(fitstat));
536541

537542
o2::vertexing::DCAFitterN<3> ft; // 3 prong fitter
543+
ft.setOldMode(oldMode); // use the old mode of DCAFitterN
538544
ft.setBz(bz);
539545
ft.setPropagateToPCA(true); // After finding the vertex, propagate tracks to the DCA. This is default anyway
540546
ft.setMaxR(200); // do not consider V0 seeds with 2D circles crossing above this R. This is default anyway

DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalFwdTrack.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ class GlobalFwdTrack : public o2::track::TrackParCovFwd, public o2::dataformats:
3434
GlobalFwdTrack(o2::track::TrackParCovFwd const& t) { *this = t; }
3535
~GlobalFwdTrack() = default;
3636

37+
GlobalFwdTrack& operator=(const TrackParCovFwd& rhs)
38+
{
39+
o2::track::TrackParCovFwd::operator=(rhs);
40+
return *this;
41+
}
42+
43+
GlobalFwdTrack& operator=(const GlobalFwdTrack& rhs)
44+
{
45+
o2::track::TrackParCovFwd::operator=(rhs);
46+
o2::dataformats::MatchInfoFwd::operator=(rhs);
47+
return *this;
48+
}
49+
3750
SMatrix5 computeResiduals2Cov(const o2::track::TrackParCovFwd& t) const
3851
{
3952
SMatrix5 Residuals2Cov;

Detectors/Base/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ o2_add_library(DetectorsBase
3737
src/GlobalParams.cxx
3838
src/O2Tessellated.cxx
3939
src/TGeoGeometryUtils.cxx
40-
src/CADGeometryUtils.cxx
4140
PUBLIC_LINK_LIBRARIES FairRoot::Base
4241
O2::CommonUtils
4342
O2::DetectorsCommonDataFormats
@@ -90,6 +89,13 @@ o2_add_test(
9089
PUBLIC_LINK_LIBRARIES O2::DetectorsBase
9190
LABELS detectorsbase)
9291

92+
o2_add_test(
93+
O2Tessellated
94+
SOURCES test/testO2Tessellated.cxx
95+
COMPONENT_NAME DetectorsBase
96+
PUBLIC_LINK_LIBRARIES O2::DetectorsBase
97+
LABELS detectorsbase)
98+
9399
if(BUILD_SIMULATION)
94100
if (NOT APPLE)
95101
o2_add_test(

Detectors/Base/include/DetectorsBase/O2Tessellated.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class O2Tessellated : public TGeoBBox
8888
const TBuffer3D& GetBuffer3D(int reqSections, Bool_t localFrame) const override;
8989
void GetMeshNumbers(int& nvert, int& nsegs, int& npols) const override;
9090
int GetNmeshVertices() const override { return fNvert; }
91+
92+
/// Fill \a array with \a npoints points on this solid's boundary: every vertex, then deterministic R2 samples on facet interiors.
93+
Bool_t GetPointsOnSegments(Int_t npoints, Double_t* array) const override;
94+
9195
void InspectShape() const override {}
9296
TBuffer3D* MakeBuffer3D() const override;
9397
void Print(Option_t* option = "") const override;

Detectors/Base/src/GeometryManager.cxx

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#ifdef O2_WITH_VECGEOM
3434
#include "TGeo2VecGeom/RootGeoManager.h"
35+
#include <VecGeom/base/Version.h>
3536
#include <VecGeom/management/GeoManager.h>
3637
#include <VecGeom/management/ABBoxManager.h>
3738
#include <VecGeom/management/BVHManager.h>
@@ -40,7 +41,11 @@
4041
#include <VecGeom/navigation/NewSimpleNavigator.h>
4142
#include <VecGeom/navigation/BVHNavigator.h>
4243
#include <VecGeom/navigation/SimpleLevelLocator.h>
44+
#if VECGEOM_VERSION >= 0x020000
45+
#include <VecGeom/navigation/SimpleABBoxLevelLocator.h>
46+
#else
4347
#include <VecGeom/navigation/BVHLevelLocator.h>
48+
#endif
4449
#include <VecGeom/navigation/VNavigator.h>
4550
#include <VecGeom/volumes/LogicalVolume.h>
4651
#include <mutex>
@@ -557,6 +562,14 @@ void GeometryManager::loadGeometry(std::string_view simPrefix, bool applyMisalig
557562

558563
namespace
559564
{
565+
/// Volumes with very few daughters are cheaper to brute-force than to accelerate. Defined once
566+
/// because two places must agree on it: where the navigators and locators are attached below,
567+
/// and where vecGeomMaterialBudget() decides how to take a step.
568+
bool usesBvhAcceleration(vecgeom::LogicalVolume const* vol)
569+
{
570+
return vol->GetDaughtersp()->size() > 2;
571+
}
572+
560573
/// Converts the currently loaded TGeo geometry to VecGeom and sets up navigators, once per
561574
/// process, the first time the VecGeom backend is requested. Not part of loadGeometry(),
562575
/// which every job calls regardless of whether it ever uses the VecGeom backend.
@@ -578,16 +591,35 @@ void ensureVecGeomWorldBuilt()
578591
vecgeom::BVHManager::Init();
579592

580593
// For each logical volume, set both a navigator (used for ComputeStep) and a matched
581-
// level locator (used for point relocation after a boundary crossing via GlobalLocator);
582-
// volumes with very few daughters are cheaper to brute-force than to accelerate.
594+
// level locator (used for point relocation after a boundary crossing via GlobalLocator).
583595
for (auto& lvol : vecgeom::GeoManager::Instance().GetLogicalVolumesMap()) {
584596
auto* vol = lvol.second;
585-
if (vol->GetDaughtersp()->size() <= 2) {
597+
if (!usesBvhAcceleration(vol)) {
586598
vol->SetNavigator(vecgeom::NewSimpleNavigator<>::Instance());
587599
vol->SetLevelLocator(vecgeom::SimpleLevelLocator::GetInstance());
588600
} else {
601+
#if VECGEOM_VERSION >= 0x020000
602+
// VecGeom 2 turned BVHNavigator into a plain class with static entry points instead of a
603+
// VNavigator singleton, so there is nothing to attach: vecGeomMaterialBudget() calls it
604+
// directly.
605+
//
606+
// The locator changes too, and not by choice. BVHLevelLocator does not compile in 2.1.0 or
607+
// 2.1.1 -- the header is byte-identical in both -- because its four LevelLocate() calls
608+
// have no match among the single templated BVH::LevelLocate(int exclude_item_id, ...) that
609+
// v2 ships. It survived two releases because nothing in VecGeom includes that header
610+
// except itself, so upstream CI never compiles it; O2 appears to be its only consumer.
611+
//
612+
// SimpleABBoxLevelLocator is the accelerated stand-in, using the ABBoxes built just above.
613+
// Three of the four methods could be rebuilt on the templated API (the idiom is in
614+
// BVHNavigator itself: bvh->LevelInside<BVHNavigator>(exclude_id, point, id, dlp)), but
615+
// the direction-aware LevelLocateExclVol has no v2 counterpart at all, so this stays a
616+
// fallback rather than a reimplementation. Revert to BVHLevelLocator once upstream fixes
617+
// or removes it, and measure: whether ABBox location costs anything real here is unknown.
618+
vol->SetLevelLocator(vecgeom::SimpleABBoxLevelLocator::GetInstance());
619+
#else
589620
vol->SetNavigator(vecgeom::BVHNavigator<>::Instance());
590621
vol->SetLevelLocator(vecgeom::BVHLevelLocator::GetInstance());
622+
#endif
591623
}
592624
}
593625
});
@@ -614,9 +646,24 @@ o2::base::MatBudget GeometryManager::vecGeomMaterialBudget(float x0, float y0, f
614646
dir[i] *= invlen;
615647
}
616648

649+
// Only the allocation differs between VecGeom versions; everything below works on pointers in
650+
// both, which also keeps the std::swap() at the end of the loop a pointer swap rather than a
651+
// copy of the state itself.
652+
//
653+
// VecGeom 1 builds NavigationState as NavStatePath, a variable-size object that must be told the
654+
// maximum depth at construction and can only be made through MakeInstance(). VecGeom 2 dropped
655+
// NavStatePath and MakeInstance with it: NavigationState is NavStateIndex or NavStateTuple, both
656+
// fixed-size value types, so a thread_local object is the direct equivalent.
657+
#if VECGEOM_VERSION >= 0x020000
658+
thread_local static vecgeom::NavigationState newnavstateStorage, currnavstateStorage, startCacheStorage;
659+
thread_local static vecgeom::NavigationState* newnavstate = &newnavstateStorage;
660+
thread_local static vecgeom::NavigationState* currnavstate = &currnavstateStorage;
661+
thread_local static vecgeom::NavigationState* startCache = &startCacheStorage;
662+
#else
617663
thread_local static vecgeom::NavigationState* newnavstate = vecgeom::NavigationState::MakeInstance(vecgeom::GeoManager::Instance().getMaxDepth());
618664
thread_local static vecgeom::NavigationState* currnavstate = vecgeom::NavigationState::MakeInstance(vecgeom::GeoManager::Instance().getMaxDepth());
619665
thread_local static vecgeom::NavigationState* startCache = vecgeom::NavigationState::MakeInstance(vecgeom::GeoManager::Instance().getMaxDepth());
666+
#endif
620667
thread_local static bool startCacheValid = false;
621668

622669
Vector3D currPoint(x0, y0, z0);
@@ -649,9 +696,18 @@ o2::base::MatBudget GeometryManager::vecGeomMaterialBudget(float x0, float y0, f
649696
Int_t nzero = 0;
650697
while (remainingDist > 1.E-10) {
651698
auto* lvol = currnavstate->Top()->GetLogicalVolume();
652-
accountMaterial(static_cast<TGeoMaterial*>(lvol->GetMaterialPtr()), budStep);
653-
vecgeom::VNavigator const* navigator = lvol->GetNavigator();
654-
double step = static_cast<double>(navigator->ComputeStepAndPropagatedState(currPoint, dirr, remainingDist, *currnavstate, *newnavstate));
699+
// Not LogicalVolume::GetMaterialPtr(): VecGeom 2 dropped the material slot from the logical
700+
// volume. TGeo2VecGeom keeps what its conversion hook returned, indexed by logical volume id,
701+
// and serves it for both VecGeom versions.
702+
accountMaterial(static_cast<TGeoMaterial*>(tgeo2vecgeom::RootGeoManager::Instance().GetMaterialPtr(lvol)), budStep);
703+
#if VECGEOM_VERSION >= 0x020000
704+
const double step =
705+
usesBvhAcceleration(lvol)
706+
? static_cast<double>(vecgeom::BVHNavigator::ComputeStepAndPropagatedState(currPoint, dirr, remainingDist, *currnavstate, *newnavstate))
707+
: static_cast<double>(lvol->GetNavigator()->ComputeStepAndPropagatedState(currPoint, dirr, remainingDist, *currnavstate, *newnavstate));
708+
#else
709+
const double step = static_cast<double>(lvol->GetNavigator()->ComputeStepAndPropagatedState(currPoint, dirr, remainingDist, *currnavstate, *newnavstate));
710+
#endif
655711
if (step < 2.E-10) {
656712
nzero++;
657713
} else {

0 commit comments

Comments
 (0)