CRPropa / CRPropa3

CRPropa is a public astrophysical simulation framework for propagating extraterrestrial ultra-high energy particles. https://crpropa.github.io/CRPropa3/
https://crpropa.desy.de
GNU General Public License v3.0
72 stars 69 forks source link

Handling of interruptions #503

Open JulienDoerner opened 2 months ago

JulienDoerner commented 2 months ago

Dear all,

This PR introduces a new handling of interruption of CRPropa simulations. The idea is to store all candidates which are currently propagating in the simulation and write them into an output file. Additionally the information about the number of not yet started candidates will be displayed. Having this information it is possible to continue the simulation after it was interrupted.

handling

To use the storing at an interruption the user has to provide an output module to the moduleList.

 sim = ModuleList() 
 ... 

 output_on_break = TextOutput(my_file.txt)
 sim.setInterruptAction(output_on_break)

After the break the candidates which have stored can be reloaded with the particleCollector. In case of a simulation with a Candidate Vector the output file will also contain the indices of the not started particles. This allows a real tracing that all particles are covered and nothing is lost.

examples in the documentation

To illustrate this new feature two example notebooks (one with a source interface and one with a candidate vector) are added to the documentation.

The example with the source interface needs some manual adaption of the number of not started Candidates. And both example need a manually triggered Keyboard Interrupt. Therefore, both notebooks are excluded from the example notebook testing.

JulienDoerner commented 2 months ago

@rafaelab

I applied your code style comments.

About the modules: The interruptAction is an independent module like everywhere else in the code. This design is designed like the onDetection in the observer, where an Output module is given to the observer and it will be processed on the detection. The same is working for the interruption. I think we could rename it to onInterruption for more consistency.

I would not suggest to put it into the observer (which is stored inside the module list), as it could lead to some confusions if you have different observers in the same simulation.

rafaelab commented 2 months ago

I would not suggest to put it into the observer (which is stored inside the module list), as it could lead to some confusions if you have different observers in the same simulation.'

Hm... That does seem to make sense.

However, I'm personally very reluctant to see modules in the ModuleList, as it breaks the underlying code logical structure and compromises the clean design. If this change is allowed, the code will no longer be 100% modular. However, I do no have a better suggestion to achieve this. What do you think, @lukasmerten ?

Maybe something like this could be though of. Any time you save a particle, according to the current structure, an Observer is required. In this case, it would be a special type of observer similar to ObserverDetectAll (e.g., ObserverUnprocessed or ObserverWaitingList or whatever) that dumps the output onInterruption. For instance:

output = TextOutput()
obsInterrupt = ObserverUnprocessed()
obsInterrupt.onInterrupt(output)
lukasmerten commented 2 months ago

Hi @rafaelab and @JulienDoerner I have to think about this but won't have time until next week. I'll let you know if I come up with something useful.