beamline object, containing beam model and geometry parameters (e.g stearing magnets distance)
treatment plan filepath (.txt or .dcm). Alternatively, the user can input a beam_data_dict, dictionary with plan info, generated via 'spots_info_from_txt', or manually generated
number of primaries 'n'
particle type
source position and rotation with respect to the mother volume
beam_nr -> number of the beam to simulate (indexing from 1)
Additional options:
flat_generation (default False) -> if True, each spot gets assigned the same number of primaries (flat probability density function PDF) and a weight proportional to the spot's msw. Otherwise (default), weight is 1 for each spot, and the number of primaries per spot is sampled from a PDF that weights each spot according to its msw.
sorted_spot_generation (default True) -> if True, each spot is exhausted before moving to the next one. Otherwise, at each event a different spot is sampled from the PDF.
gantry rotation axis (default 'z')
User_info filled automatically at initialization:
PDF -> vector with a probability for each spot, defined accordingly to its msw (unless flat generation)
one vector for each spot feature, including: position, rotation, phase space parameters (X and Y direction separately), weight, energy, energy sigma.
Cpp side:
GateTreatmentPlanPBSource inherits from GateVSource
Implementation partly based on the Gate 9 GateSourceTPSPencilBeam
Main idea:
a single particle source (fSPS) of type GateSingleParticleSourcePencilBeam is created only once, at initialization
in PrepareNextTime, a spot is selected. Either the next spot that still has primaries to generate (sorted) or a spot sampled from the PDF.
NOTE: sampling of from the PDF relies on the CLHEP::RandGeneral function (as in Gate 9)
if the spot is different from the one selected at the previous Time, the parameters of the fSPS are updated with the ones of the current spot
in GeneratePrimaries, the configured fSPS generates a vertex. The weight of the event is assigned accordingly to the one of the current spot
Note on PrepareNextTime:
the simulation time is updated as the user had set an activity, with the difference that there is no random factor affecting the lenght of the time increment.
the number of particles is converted into time, by considering the following expression for the next time: next_time = t + 1/(Ntot*Bq).
the advantage of this approach, compare to simply setting a max number of particles, is that in case of multiple runs, the primaries are spread across the run_timing_intervals proportionally to the lenght of the interval, instead of being exhausted in the first run.
NOTE: somehow I currently simulate one particle less per run, still need to figure out why
Tests:
I adapted the tp source tests (test059) to use the new source instead of the TreatmentPlanSource class, which was not a real source but rather an object responsible to initialize several PencilBeamSources.
The tests seem to pass.
More test needed (?)
I leave this PR as a draft, we can discuss together what to do with it :)
New TP Source implementation:
Python side:
Cpp side:
Tests:
I leave this PR as a draft, we can discuss together what to do with it :)