Two distinct sets of weights are used in g4lbne. Their introduction pre-dates Geant4, as CPU time and disk space were also expensive in the good old days of the Fermilab NuMI beam-line. The so-called importance weights regulates the pion multiplicity during the Hadronic processes. The detector weights are used to simulate the isotropic character of the pion decay in a very efficient manner. Both weights are attribute of each neutrinos and are saved in the "Dk2nu" ROOT NTuples.
Numerous pions are being produced inside the approximately two interaction length target: The average pi+ (running the Horns with forward current) is about 4 to 5. Many - most in fact- might not reach the beginning of the decay channel, especially if they are produced at low momentum. Thus, one has interest in "pre-scaling" such unworthy pions (or Kaons..), before simulating their trajectory in the target and horns. However, for some studies, like measuring the inclusive pion yield off the target, such a pre-scale, and use of weights could make life more complicated for the analyst. For small samples, or when one is interested in very low neutrino energies, it is perhaps best to run without such weight. Thus, a data card:
will prompt G4lbne to always set the Importance Weight to unity, and skip the prescaling of the pion at the time they are created via the various Hadronic processes. The default for this option is "true", as we did for the past decade or so.
Here is the algorithm for computing this Importance Weight and for the pre-scaling the pion flux, as obtained by reading the existence code, and by replicating the code in a separate DK2Nu/ROOT application. Indeed, this weight can be recomputed from the Ntuple written out by G4lbne, as the complete genealogy of tracks leading to the creation of a neutrino is kept in the DK2Nu stream, allowing us to understand and check this part g4lbne code
First, let us mention the weighting scheme is arbitrary, provide no singularity in the probability to reject the hadron is encountered in calculation. Once again, the goal is not to waste time tracing and saving data for neutrino of unwanted direction or energy, so what is "low" or "high" energy might depend on the physics goal being pursued by running g4lbne. Currently, the parameters on which this probability for rejection is computed are fixed, hard-coded.
As in any Geant4 application, once a particle is generated, the Geant4 user has the option of loading it for tracking, or simply discard the generated particle. This is done in a derived class of G4VUserStackingaction , method classifyNewTrack. In our case, this method calls the private method LBNEStackingAction::KillUnimportantParticles. Which itself calls the LBNEImpWeight::CalculateImpWeight method. In this methods, one finds the following algorithm:
If the particle is a photon or an electronic it has already been classified as fkill, and the weight is irrelevant. If the particle is muon, it's weight is 1, i.e., always kept. If it is a hadron a weight is compute solely based on the total (kinetic + mass) energy of the hadron, and the weight of the parent of this hadron. The weight of the incident proton, from the beam, is always set to unity. First, the total energy is is discretized, bin size of 1 GeV. The preliminary value for the probability for rejection is the energy bin number divided by 30. This means that a 5 GeV pion has only 16.667% chance being accepted, and it's weight would be 6. This probability must of course between 0. and 1., so, hadrons with an energy above 30 GeV always have a preliminary weight of 1. To avoid excessively large weights, which cause large statistical fluctuations, the maximum preliminary weight is 100.
One then throw the dice, (G4UniformRand), and accept or reject the particle. If accepted, the final weight is set to the production of the importance weight of the parent particle and the preliminary weight. These weight a kept as "UserInformation: buffer in the accepted track. Once the tracking of this particle is done, a G4Trajectory is assigned to the track, and kept in memory. Note that each track in a given Geant4 event receives an unique identification number, also stored in the trajectory. At the end of the G4Event (one proton on target), the stack of trajectories is scanned, and Importance Weight for the neutrino is simply parent's Importance Weight.
As mentioned above, this algorithm has been re-implemented based on the genealogy found in the Dk2nu data structure. There is an other way to check that this algorithm is correct, in the sense that it does not bias the neutrino spectrum. Once simply run G4lbne w/o Importance weighting, and compare the spectrum. Based on one million PoT, the agreement is satisfactory.
See Dk2Nu package.