Skip to content

Commit b7f08b9

Browse files
sawenzelclaude
andcommitted
Relax the Geant4 field epsilons outside the muon spectrometer
This relaxes the Geant4 field-integration epsilons, keeps them tight as local fields in the muon spectrometer, and adds the support for local field parameters. - The tight epsilons from ALIROOT-7121 do not affect the 1/pT bias; only deltaIntersection does, and it stays at 1e-5 mm. - minimumEpsilon controls the long steps; relaxing it to 1e-4 moves nothing in the barrel, but it would move MCH positions, so YOUT1, DDIP and YOUT2 keep the tight values. - G4LocalFieldConstruction attaches the global field to every volume given its own parameters with /mcDet/createMagFieldParameters, so that the /mcMagField/<vol>/ settings take effect. - A volume whose subtree contains zero-field media is refused, since Geant4 VMC forces a local field onto all daughters. - This saves about 10% of the transport CPU time in pp. https://its.cern.ch/jira/browse/O2-7198 https://alice.its.cern.ch/jira/browse/ALIROOT-7121 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent e670fb4 commit b7f08b9

7 files changed

Lines changed: 155 additions & 10 deletions

File tree

‎Detectors/gconfig/CMakeLists.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ o2_add_library(G3Setup
1515
)
1616

1717
o2_add_library(G4Setup
18-
SOURCES src/G4Config.cxx src/G4RunConfiguration.cxx
18+
SOURCES src/G4Config.cxx src/G4RunConfiguration.cxx src/G4LocalFieldConstruction.cxx
1919
PUBLIC_LINK_LIBRARIES MC::Geant4VMC MC::Geant4 FairRoot::Base O2::SimulationDataFormat O2::Generators O2::SimSetup O2::FastSim
2020
)
2121

‎Detectors/gconfig/g4Config.C‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,8 @@ void Config()
119119
LOG(fatal) << "Unsupported geometry navigation mode";
120120
}
121121

122-
// o2::g4config::G4RunConfiguration differs from TG4RunConfiguration only in
123-
// providing the fast-simulation hook; with G4.fastSimModels empty it behaves
124-
// identically.
122+
// o2::g4config::G4RunConfiguration adds the fast-simulation hook and the local
123+
// magnetic fields; with neither configured it behaves like TG4RunConfiguration.
125124
auto runConfiguration = new o2::g4config::G4RunConfiguration(geomNavStr, physicsSetup,
126125
"stepLimiter+specialCuts",
127126
specialStacking, mtMode);

‎Detectors/gconfig/g4config.in‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,33 @@
4747
/process/em/transportationWithMsc Disabled
4848

4949
#
50-
# Adding extra lines for fixing tracking bias
51-
#
50+
# Field integration (O2-7198)
51+
# a tight deltaIntersection removes the 1/pT bias from chord-to-boundary placement (ALIROOT-7121)
5252
/mcMagField/setDeltaIntersection 1.0e-05 mm
53-
/mcMagField/setMinimumEpsilonStep 0.5e-05
54-
/mcMagField/setMaximumEpsilonStep 1.0e-05
53+
# the epsilons do not change the bias; minimumEpsilon sets the accuracy of long steps,
54+
# which only the muon spectrometer needs (it keeps the tight value as a local field)
55+
/mcMagField/setMinimumEpsilonStep 1.0e-04
56+
/mcMagField/setMaximumEpsilonStep 1.0e-03
5557
/mcMagField/printParameters
58+
# the muon spectrometer keeps tight epsilons as local fields (see G4LocalFieldConstruction)
59+
/mcDet/createMagFieldParameters YOUT1
60+
/mcMagField/YOUT1/stepperType NystromRK4
61+
/mcMagField/YOUT1/setConstDistance 1 mm
62+
/mcMagField/YOUT1/setDeltaIntersection 1.0e-05 mm
63+
/mcMagField/YOUT1/setMinimumEpsilonStep 0.5e-05
64+
/mcMagField/YOUT1/setMaximumEpsilonStep 1.0e-05
65+
/mcDet/createMagFieldParameters DDIP
66+
/mcMagField/DDIP/stepperType NystromRK4
67+
/mcMagField/DDIP/setConstDistance 1 mm
68+
/mcMagField/DDIP/setDeltaIntersection 1.0e-05 mm
69+
/mcMagField/DDIP/setMinimumEpsilonStep 0.5e-05
70+
/mcMagField/DDIP/setMaximumEpsilonStep 1.0e-05
71+
/mcDet/createMagFieldParameters YOUT2
72+
/mcMagField/YOUT2/stepperType NystromRK4
73+
/mcMagField/YOUT2/setConstDistance 1 mm
74+
/mcMagField/YOUT2/setDeltaIntersection 1.0e-05 mm
75+
/mcMagField/YOUT2/setMinimumEpsilonStep 0.5e-05
76+
/mcMagField/YOUT2/setMaximumEpsilonStep 1.0e-05
5677

5778
# Change default parameters for killing looping particles
5879
#
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef O2_SIMSETUP_G4LOCALFIELDCONSTRUCTION_H_
13+
#define O2_SIMSETUP_G4LOCALFIELDCONSTRUCTION_H_
14+
15+
#include "TG4VUserPostDetConstruction.h"
16+
17+
#include <memory>
18+
19+
namespace o2::g4config
20+
{
21+
22+
/// Gives every volume with its own field parameters (/mcDet/createMagFieldParameters <vol>)
23+
/// a local copy of the global field, so that the /mcMagField/<vol>/ settings take effect.
24+
class G4LocalFieldConstruction : public TG4VUserPostDetConstruction
25+
{
26+
public:
27+
/// next is another construction step run first (may be nullptr); it is owned
28+
explicit G4LocalFieldConstruction(TG4VUserPostDetConstruction* next) : mNext(next) {}
29+
void Construct() override;
30+
31+
private:
32+
std::unique_ptr<TG4VUserPostDetConstruction> mNext;
33+
};
34+
35+
} // namespace o2::g4config
36+
37+
#endif // O2_SIMSETUP_G4LOCALFIELDCONSTRUCTION_H_

‎Detectors/gconfig/include/SimSetup/G4RunConfiguration.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace o2::g4config
1818
{
1919

20-
/// The Geant4 VMC run configuration of O2: adds the fast simulation.
20+
/// The Geant4 VMC run configuration of O2: adds the fast simulation and the local magnetic fields.
2121
class G4RunConfiguration : public TG4RunConfiguration
2222
{
2323
public:
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#include "SimSetup/G4LocalFieldConstruction.h"
13+
#include "SimConfig/G4Params.h"
14+
15+
#include "TG4GeometryManager.h"
16+
17+
#include <G4UIcommandTree.hh>
18+
#include <G4UImanager.hh>
19+
#include <TGeoManager.h>
20+
#include <TVirtualMC.h>
21+
#include <fairlogger/Logger.h>
22+
23+
#include <string>
24+
#include <unordered_set>
25+
26+
namespace o2::g4config
27+
{
28+
29+
namespace
30+
{
31+
// First volume in the subtree of vol whose medium has no magnetic field (ifield = 0)
32+
const TGeoVolume* findZeroFieldVolume(const TGeoVolume* vol, std::unordered_set<const TGeoVolume*>& visited)
33+
{
34+
if (!visited.insert(vol).second) {
35+
return nullptr;
36+
}
37+
auto med = vol->GetMedium();
38+
if (med && !vol->IsAssembly() && med->GetParam(1) == 0) {
39+
return vol;
40+
}
41+
for (int i = 0; i < vol->GetNdaughters(); ++i) {
42+
if (auto nf = findZeroFieldVolume(vol->GetNode(i)->GetVolume(), visited)) {
43+
return nf;
44+
}
45+
}
46+
return nullptr;
47+
}
48+
} // namespace
49+
50+
void G4LocalFieldConstruction::Construct()
51+
{
52+
if (mNext) {
53+
mNext->Construct();
54+
}
55+
auto tree = G4UImanager::GetUIpointer()->GetTree()->FindCommandTree("/mcMagField/");
56+
auto field = TVirtualMC::GetMC()->GetMagField();
57+
if (!tree || !field) {
58+
return;
59+
}
60+
int nattached = 0;
61+
for (int i = 1; i <= tree->GetTreeEntry(); ++i) {
62+
std::string path = tree->GetTree(i)->GetPathName(); // "/mcMagField/<vol>/"
63+
auto name = path.substr(12, path.size() - 13);
64+
auto vol = gGeoManager->GetVolume(name.c_str());
65+
if (!vol) {
66+
LOG(warn) << "local field: no volume " << name << "; its field parameters are unused";
67+
continue;
68+
}
69+
// Geant4 VMC forces a local field onto all daughters, which would override zero-field media
70+
std::unordered_set<const TGeoVolume*> visited;
71+
if (auto nf = findZeroFieldVolume(vol, visited)) {
72+
LOG(warn) << "local field: volume " << name << " contains the zero-field volume " << nf->GetName() << "; skipped";
73+
continue;
74+
}
75+
vol->SetField(field);
76+
LOG(info) << "local field: volume " << name << " uses the parameters in /mcMagField/" << name << "/";
77+
++nattached;
78+
}
79+
if (nattached > 0) {
80+
TG4GeometryManager::Instance()->SetIsLocalField(true);
81+
if (o2::conf::G4Params::Instance().navmode != o2::conf::EG4Nav::kTGeo) {
82+
LOG(warn) << "local field: Geant4 VMC builds local fields only with TGeo navigation; the global field applies everywhere";
83+
}
84+
}
85+
}
86+
87+
} // namespace o2::g4config

‎Detectors/gconfig/src/G4RunConfiguration.cxx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// or submit itself to any jurisdiction.
1111

1212
#include "SimSetup/G4RunConfiguration.h"
13+
#include "SimSetup/G4LocalFieldConstruction.h"
1314
#include "FastSim/G4FastSimulation.h"
1415

1516
namespace o2::g4config
@@ -23,7 +24,7 @@ TG4VUserFastSimulation* G4RunConfiguration::CreateUserFastSimulation()
2324
TG4VUserPostDetConstruction* G4RunConfiguration::CreateUserPostDetConstruction()
2425
{
2526
auto fastSimRegions = o2::fastsim::createFastSimRegionConstruction();
26-
return fastSimRegions ? fastSimRegions : TG4RunConfiguration::CreateUserPostDetConstruction();
27+
return new G4LocalFieldConstruction(fastSimRegions ? fastSimRegions : TG4RunConfiguration::CreateUserPostDetConstruction());
2728
}
2829

2930
} // namespace o2::g4config

0 commit comments

Comments
 (0)