Skip to content

Commit 26f3cee

Browse files
committed
Make monopoles mass configurable via parameter
1 parent 1d62ef1 commit 26f3cee

8 files changed

Lines changed: 51 additions & 20 deletions

File tree

‎Common/SimConfig/include/SimConfig/G4Params.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "CommonUtils/ConfigurableParam.h"
1616
#include "CommonUtils/ConfigurableParamHelper.h"
17+
#include "SimulationDataFormat/MonopoleParticles.h"
1718

1819
namespace o2
1920
{
@@ -67,6 +68,9 @@ struct G4Params : public o2::conf::ConfigurableParamHelper<G4Params> {
6768
// the only volume with an electric field, and its magnitude is the TPC's own
6869
// TPCGEMParam.ElectricField[0]
6970
float monopoleMagneticCharge = 1.f;
71+
// Monopole mass in GeV, preliminarly applied to all the monopoles species
72+
// To-do: allow different monopoles masses in the same run
73+
float monopoleMass = static_cast<float>(o2::sim::MonopoleMassDefaultGeV);
7074

7175
// Fast simulation. Empty fastSimModels (the default) disables the feature
7276
// entirely; see Detectors/gconfig/include/SimSetup/G4FastSimulation.h.

‎DataFormats/simulation/include/SimulationDataFormat/MonopoleParticles.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ constexpr int MonopolePdgSymm = 4110000;
2929
/// monopole carrying opposite electric and magnetic charge
3030
constexpr int MonopolePdgAsymm = 4120000;
3131

32+
/// Default monopole mass in GeV.
33+
constexpr double MonopoleMassDefaultGeV = 100.;
34+
3235
/// true for the monopole and antimonopole of both species
3336
constexpr bool isMonopole(int pdg) noexcept
3437
{

‎DataFormats/simulation/include/SimulationDataFormat/O2DatabasePDG.h‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string>
2020
#include "TDatabasePDG.h"
2121
#include "TParticlePDG.h"
22+
#include "SimulationDataFormat/MonopoleParticles.h"
2223

2324
namespace o2
2425
{
@@ -44,7 +45,13 @@ class O2DatabasePDG
4445
}
4546

4647
// adds ALICE particles to a given TDatabasePDG instance
47-
static void addALICEParticles(TDatabasePDG* db = TDatabasePDG::Instance());
48+
// monopoleMass is the mass of all monopole species in GeV; it has to match
49+
// G4Params.monopoleMass or the generator and the transport will disagree
50+
// To fix: all quantities in the MCTrack dependent from GetMass() will get the default 100 GeV.
51+
// A possible fix would be to stop deriving the masses from the compiled-in table,
52+
// or a better solution should be found in the future
53+
static void addALICEParticles(TDatabasePDG* db = TDatabasePDG::Instance(),
54+
double monopoleMass = o2::sim::MonopoleMassDefaultGeV);
4855
static void addParticlesFromExternalFile(TDatabasePDG* db);
4956

5057
// get particle's (if any) mass
@@ -84,7 +91,7 @@ class O2DatabasePDG
8491

8592
// by keeping this inline, we can use it in other parts of the code, for instance Framework or Analysis,
8693
// without needing to link against this library
87-
inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db)
94+
inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db, double monopoleMass)
8895
{
8996
//
9097
// Add ALICE particles to the ROOT PDG data base
@@ -191,11 +198,11 @@ inline void O2DatabasePDG::addALICEParticles(TDatabasePDG* db)
191198

192199
// BSM targeted inclusions
193200
// Monopoles with same electric and magnetic charge
194-
db->AddParticle("Monopole_symm", "Monopole_symm", 100., kTRUE, 0.0, 0, "BSM", 4110000);
195-
db->AddParticle("AntiMonopole_symm", "AntiMonopole_symm", 100., kTRUE, 0.0, 0, "BSM", -4110000);
201+
db->AddParticle("Monopole_symm", "Monopole_symm", monopoleMass, kTRUE, 0.0, 0, "BSM", 4110000);
202+
db->AddParticle("AntiMonopole_symm", "AntiMonopole_symm", monopoleMass, kTRUE, 0.0, 0, "BSM", -4110000);
196203
// Monopoles with opposite electric and magnetic charge
197-
db->AddParticle("Monopole_asymm", "Monopole_asymm", 100., kTRUE, 0.0, 0, "BSM", 4120000);
198-
db->AddParticle("AntiMonopole_asymm", "AntiMonopole_asymm", 100., kTRUE, 0.0, 0, "BSM", -4120000);
204+
db->AddParticle("Monopole_asymm", "Monopole_asymm", monopoleMass, kTRUE, 0.0, 0, "BSM", 4120000);
205+
db->AddParticle("AntiMonopole_asymm", "AntiMonopole_asymm", monopoleMass, kTRUE, 0.0, 0, "BSM", -4120000);
199206

200207
// IONS
201208
//

‎Detectors/TPC/simulation/src/Detector.cxx‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "DetectorsBase/Stack.h"
1919
#include "SimulationDataFormat/TrackReference.h"
2020
#include "SimulationDataFormat/MonopoleParticles.h"
21+
#include "SimConfig/G4Params.h"
2122

2223
#include "FairVolume.h" // for FairVolume
2324

@@ -127,15 +128,16 @@ Bool_t Detector::ProcessHits(FairVolume* vol)
127128
// To-do: add dyons case
128129
bool isMonopole = false;
129130
if (static_cast<int>(trackCharge) == 0) {
130-
isMonopole = o2::sim::isMonopole(fMC->TrackPid());
131+
static const bool sMonopoleIonisation = o2::conf::G4Params::Instance().monopole;
132+
isMonopole = sMonopoleIonisation && o2::sim::isMonopole(fMC->TrackPid());
131133
if (!isMonopole) {
132134
// set a very large step size for neutral particles
133135
fMC->SetMaxStep(1.e10);
134136
return kFALSE; // take only charged particles
135137
}
136138
if (fMC->Edep() <= 0.) {
137-
// The monopole deposits nothing when no ionisation process is attached to
138-
// it (G4.monopole=0), so no hit to make.
139+
// An ionising monopole depositing nothing on this step: there
140+
// is no hit to create, and the step limit is deliberately left alone
139141
return kFALSE;
140142
}
141143
}

‎Detectors/gconfig/src/O2MonopolePhysics.cxx‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,11 @@ class O2MonopolePhysics : public G4VUserPhysicsList
420420
{
421421
auto* table = G4ParticleTable::GetParticleTable();
422422

423-
// Built once and shared by all monopoles species: O2MonopoleEquation reads the
424-
// sign of the magnetic charge off the track, so one chord finder serves
425-
// monopoles and anti-monopoles
426-
const MonopoleFieldSetup fieldSetup =
427-
buildMonopoleFieldSetup(mMagneticCharge / CLHEP::eplus, tpcDriftFieldMagnitude());
423+
// Built on the first monopole species actually found, then shared by the rest:
424+
// O2MonopoleEquation reads the sign of the magnetic charge off the track, so
425+
// one chord finder serves monopoles and anti-monopoles
426+
// No monopoles in the particles table == no monopole ionisation attached
427+
MonopoleFieldSetup fieldSetup;
428428

429429
int nAttached = 0;
430430
for (int pdg : gMonopolePDGs) {
@@ -477,6 +477,9 @@ class O2MonopolePhysics : public G4VUserPhysicsList
477477
// Deflect the monopole in the field as well; without this only the energy
478478
// loss above would act and the monopole would fly straight through, since
479479
// its electric charge (and hence the usual Lorentz force) is zero.
480+
if (fieldSetup.chordFinder == nullptr) {
481+
fieldSetup = buildMonopoleFieldSetup(mMagneticCharge / CLHEP::eplus, tpcDriftFieldMagnitude());
482+
}
480483
installMonopoleTransport(pmanager, particle, fieldSetup);
481484

482485
++nAttached;

‎Generators/src/GeneratorFactory.cxx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <Generators/BoxGenerator.h>
1818
#include <fairlogger/Logger.h>
1919
#include <SimConfig/SimConfig.h>
20+
#include <SimConfig/G4Params.h>
2021
#include <Generators/GeneratorFromFile.h>
2122
#include <Generators/GeneratorTParticle.h>
2223
#include <Generators/GeneratorTParticleParam.h>
@@ -86,7 +87,9 @@ void GeneratorFactory::setPrimaryGenerator(o2::conf::SimConfig const& conf, Fair
8687

8788
/** generators **/
8889

89-
o2::O2DatabasePDG::addALICEParticles(TDatabasePDG::Instance());
90+
// Monopole configurable mass added to the PDG database
91+
o2::O2DatabasePDG::addALICEParticles(TDatabasePDG::Instance(),
92+
o2::conf::G4Params::Instance().monopoleMass);
9093
auto genconfig = conf.getGenerator();
9194
#if defined(GENERATORS_WITH_PYTHIA8) && defined(GENERATORS_WITH_HEPMC3)
9295
if (GeneratorHybridParam::Instance().switchExtToHybrid && (genconfig.compare("external") == 0 || genconfig.compare("extgen") == 0)) {

‎Steer/src/O2MCApplication.cxx‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,12 +1753,16 @@ void addSpecialParticles()
17531753
TVirtualMC::GetMC()->DefineParticle(-900000020, "AntiSexaquark", kPTUndefined, 2.0, 0.0, 4.35e+17, "Hadron", 0.0, 0, 1, 0, 0, 0, 0, 0, -2, kTRUE);
17541754

17551755
// BSM Monopoles
1756+
// The transported mass has to match the one the generator used; see
1757+
// G4Params.monopoleMass and o2::sim::MonopoleMassDefaultGeV.
1758+
// To-do: find a way to define multiple masses for monopoles species
1759+
const double monopoleMass = o2::conf::G4Params::Instance().monopoleMass;
17561760
// Symmetric monopoles: same electric and magnetic charge
1757-
TVirtualMC::GetMC()->DefineParticle(4110000, "Monopole_symm", kPTHadron, 100., 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
1758-
TVirtualMC::GetMC()->DefineParticle(-4110000, "AntiMonopole_symm", kPTHadron, 100., 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
1761+
TVirtualMC::GetMC()->DefineParticle(4110000, "Monopole_symm", kPTHadron, monopoleMass, 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
1762+
TVirtualMC::GetMC()->DefineParticle(-4110000, "AntiMonopole_symm", kPTHadron, monopoleMass, 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
17591763
// Asymmetric monopoles: opposite electric and magnetic charge
1760-
TVirtualMC::GetMC()->DefineParticle(4120000, "Monopole_asymm", kPTHadron, 100., 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
1761-
TVirtualMC::GetMC()->DefineParticle(-4120000, "AntiMonopole_asymm", kPTHadron, 100., 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
1764+
TVirtualMC::GetMC()->DefineParticle(4120000, "Monopole_asymm", kPTHadron, monopoleMass, 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
1765+
TVirtualMC::GetMC()->DefineParticle(-4120000, "AntiMonopole_asymm", kPTHadron, monopoleMass, 0.0, 1e10, "BSM", 0.0, 0, 0, 0, 0, 0, 0, 0, 0, kTRUE);
17621766
}
17631767

17641768
void O2MCApplicationBase::AddParticles()

‎macro/o2sim.C‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <Generators/GeneratorFactory.h>
1616
#include <Generators/Generator.h>
1717
#include "SimulationDataFormat/O2DatabasePDG.h"
18+
#include "SimConfig/G4Params.h"
1819
#include "SimulationDataFormat/MCEventHeader.h"
1920
#include <SimConfig/SimConfig.h>
2021
#include <SimConfig/SimParams.h>
@@ -178,7 +179,11 @@ FairRunSim* o2sim_init(bool asservice, bool evalmat = false)
178179
run->Init();
179180

180181
// add ALICE particles to TDatabasePDG singleton
181-
o2::O2DatabasePDG::addALICEParticles(TDatabasePDG::Instance());
182+
// The monopole mass has to be the one the transport uses; in the worker
183+
// (asservice) the GeneratorFactory call is skipped, so this is the only
184+
// place that registers it.
185+
o2::O2DatabasePDG::addALICEParticles(TDatabasePDG::Instance(),
186+
o2::conf::G4Params::Instance().monopoleMass);
182187

183188
long runStart = timestamp;
184189
{

0 commit comments

Comments
 (0)