diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index 9b08602aab7aeb37bb5c41bb9a90181656b0ad5b..679791372a74cd0e8970249ab149a8c33031512f 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -625,6 +625,8 @@ InitStatus CbmL1::Init() auto timerStart = std::chrono::high_resolution_clock::now(); ca::tools::MaterialHelper matHelper; + matHelper.SetSafeMaterialInitialization(fDoSafeMaterialInitialization); + if (!fMatBudgetParallelProjection) { matHelper.SetDoRadialProjection(target.z); } matHelper.SetNraysPerDim(fMatBudgetNrays); diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 492c765cff0de67596a137564c58a6b4d5c81bf0..4a0e38c0ae0b907a177fbf61448c16f40b89acbe 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -197,6 +197,10 @@ public: /// Possible entries of Detector ID are listed in CbmL1DetectorID.h. void DisableTrackingStation(L1DetectorID detID, int iSt); + /// Sets safe but slow material initialisation to get around potential problems in TGeoVoxelFinder + /// (use it only in case of a crash at the initialisation of material maps) + void SetSafeMaterialInitialization(bool val = true) { fDoSafeMaterialInitialization = val; } + /// Sets material budget file name for MVD void SetMvdMaterialBudgetFileName(const TString& fileName) { @@ -479,6 +483,9 @@ public: private: static CbmL1* fpInstance; ///< Instance of CbmL1 + bool fDoSafeMaterialInitialization {false}; /// Do safe but slow material initialisation + /// to get around potential problems in TGeoVoxelFinder + int fNpointsMvd = 0; ///< Number of MC points for MVD int fNpointsSts = 0; ///< Number of MC points for STS int fNpointsMuch = 0; ///< Number of MC points for MuCh diff --git a/reco/L1/catools/CaToolsMaterialHelper.cxx b/reco/L1/catools/CaToolsMaterialHelper.cxx index 4ca3b7fac135f20b18c496efa7347f169f40e5fe..5c2577efcc402b52068433ca7d9d0ed7f1c84636 100644 --- a/reco/L1/catools/CaToolsMaterialHelper.cxx +++ b/reco/L1/catools/CaToolsMaterialHelper.cxx @@ -11,6 +11,8 @@ #include "TGeoMedium.h" #include "TGeoNavigator.h" #include "TGeoNode.h" +#include "TGeoPhysicalNode.h" +#include "TGeoVoxelFinder.h" #include <iostream> #include <thread> @@ -32,7 +34,7 @@ MaterialHelper::MaterialHelper() LOG(info) << "------------------------------------------------------------------------------------"; LOG(info) << " create L1 material maps "; LOG(info) << ""; - LOG(info) << " !! To run it with the full speed, set: \"export OMP_NUM_THREADS = <n CPUs>\" before running !!"; + LOG(info) << " !! To run it with the full speed, set: \"export OMP_NUM_THREADS=<n CPUs>\" before running !!"; LOG(info) << ""; // if possible, read the allowed n threads from the environment variable { @@ -49,9 +51,74 @@ MaterialHelper::MaterialHelper() LOG(info) << " Maps will be created using " << fNthreads << " CPU threads"; LOG(info) << ""; + LOG(info) << " It might crash because of a ROOT bug. In this case do one of the following: "; + LOG(info) << ""; + LOG(info) << " - fix illegal overlaps in the geometry via gGeoManager->CheckOverlaps()"; + LOG(info) << " - run with CbmL1::SetSafeMaterialInitialization() option. "; + LOG(info) << " It fixes the crash, but slows down the initialization significantly."; + LOG(info) << " - manually disable voxel finders for problematic volumes in CaToolsMaterialHelper.cxx"; + LOG(info) << ""; LOG(info) << "------------------------------------------------------------------------------------"; InitThreads(); + + // + // It looks like TGeoVoxelFinder contains a bug and therefore sometimes produces a crash. + // + // Currently, the crash only happens on some of TGeoVolumeAssembly volumes + // and only when an (inproper?) alignment matrices are applied. + // + // Here we try to catch this case and disable those finders. + // + // Disabling all the voxel finders leads to a very long initialization, try to avoid it! + // + // TODO: make a bug report to the ROOT team; remove the following code once the bug is fixed. + // + + if (fDoSafeInitialization) { // disable all voxel finders + TObjArray* volumes = gGeoManager->GetListOfVolumes(); + if (volumes) { + for (int iv = 0; iv < volumes->GetEntriesFast(); iv++) { + TGeoVolume* vol = dynamic_cast<TGeoVolume*>(volumes->At(iv)); + if (!vol) { continue; } + TGeoVoxelFinder* finder = vol->GetVoxels(); + if (finder) { finder->SetInvalid(); } + } + } + } + else { // disable some voxel finders in some cases + + // check if any alignment was applied + + bool isAlignmentApplied = false; + { + TObjArray* nodes = gGeoManager->GetListOfPhysicalNodes(); + if (nodes) { + for (int in = 0; in < nodes->GetEntriesFast(); in++) { + TGeoPhysicalNode* node = dynamic_cast<TGeoPhysicalNode*>(nodes->At(in)); + if (!node) continue; + if (node->IsAligned()) { + isAlignmentApplied = true; + break; + } + } + } + } + + // disable potentially problematic voxel finders + + if (isAlignmentApplied) { + TObjArray* volumes = gGeoManager->GetListOfVolumes(); + if (volumes) { + for (int iv = 0; iv < volumes->GetEntriesFast(); iv++) { + TGeoVolumeAssembly* vol = dynamic_cast<TGeoVolumeAssembly*>(volumes->At(iv)); + if (!vol) { continue; } + TGeoVoxelFinder* finder = vol->GetVoxels(); + if (finder) { finder->SetInvalid(); } + } + } + } + } } diff --git a/reco/L1/catools/CaToolsMaterialHelper.h b/reco/L1/catools/CaToolsMaterialHelper.h index 487df8679a48675fff92f3ef8e8b76f16f3cd64b..7105b0c996112fef57e0cbd81b958b0f56bd469b 100644 --- a/reco/L1/catools/CaToolsMaterialHelper.h +++ b/reco/L1/catools/CaToolsMaterialHelper.h @@ -66,6 +66,8 @@ namespace ca /// L1Material GenerateMaterialMap(double zRef, double zMin, double zMax, double xyMax, int nBinsDim); + void SetSafeMaterialInitialization(bool val = true) { fDoSafeInitialization = val; } + private: /// initialise the necessary amount of threads in TGeoManager void InitThreads(); @@ -84,7 +86,8 @@ namespace ca int fNraysBinPerDim {3}; // shoot fNraysBinPerDim * fNraysBinPerDim rays in each map bin double fTargetZ {0.}; // z of the target for the radial projection std::vector<TGeoNavigator*> fNavigators {}; // list of created navigators - + bool fDoSafeInitialization {false}; // perform slow but safe initialization + // to get around the crashes in TGeoVoxelFinder ClassDef(MaterialHelper, 0); };