celeritas icon indicating copy to clipboard operation
celeritas copied to clipboard

Implement physics constructor for OpticalPhysics

Open drbenmorgan opened this issue 1 year ago • 6 comments

Celeritas intends to implement optical photon offload from Geant4 via custom G4VProcesses for photon-generating processed (Cerenkov, Scintillation). Within Geant4, this means they will need to be added to the relevant particles in application physics lists both to enable the offload and for optical data construction/availablity (as with the EM processes).

Following the pattern for used for EM physics in CelerEMStandardPhysics, the changes here add a preliminary concrete G4VPhysicsConstructor to handle particle and process construction for Optical processes. Though Celeritas will not generate and track G4OpticalPhotons, this initial implement largely follows the core G4OpticalPhysics constructor just to get something in place with G4OpticalPhoton.

Comments are used, though it's fairly obvious, to note where the custom Celeritas processes will go. Adding this constructor in CelerEmPhysicsList and/or other lists and celer-g4 can be done, but wanted to submit a WIP just to check this is on the right base.

drbenmorgan avatar Jul 31 '24 19:07 drbenmorgan

Though adding this to CelerEmPhysicsList and CelerFTFPBert could proceed at this point, it might be worth thinking about how best to handle the optical physics parameters. One gotcha the last few commits show is that G4OpticalParameters (analogous to G4EmParameters) is only present from Geant4 10.7. Before this, the parameters are handled locally in G4OpticalPhysics, which CelerOpticalPhysics attempts to emulate.

I think all of the optical parameters can be handled/transfered in the same way as the EM ones are in the CelerEmStandardPhysics constructor:

https://github.com/celeritas-project/celeritas/blob/cc2d1df1b3d609c00c12561e2dec60d179e7c012/src/celeritas/ext/detail/CelerEmStandardPhysics.cc#L98-L107

i.e. obtain them from the input struct and:

  1. For Geant4 < 10.7, hold this locally and configure processes locally (see how Geant4 did it)
  2. Otherwise, call G4OpticalParameters setters as appropriate.

Some of this may of course not be needed later if we don't need to set these processes up to get data etc for Celeritas from them.

However, I don't think we can/should add the optical parameters as direct members of GeantPhysicsOptions as that's really focussed on EM options. It feels like we should maybe have a separate GeantOpticalPhysicsOptions struct that's a member of GeantPhysicsOptions? Longer term, could also consider a larger refactor so we'd have something like:

struct GeantPhysicsOptions
{
    GeantEmPhysicsOptions electromagnetic;
    GeantOpticalPhysicsOptions optical;
    // GeantHadronicPhysicsOptions hadronic;
};

but could just start with the optical parameter struct as a member?

drbenmorgan avatar Aug 01 '24 15:08 drbenmorgan

@drbenmorgan I think your plan for a separate struct (and later creating another one for EM parameters) is perfect. Thanks for this!

sethrj avatar Aug 01 '24 16:08 sethrj

Struct in place, but as you'll see, the implementation of CelerOpticalPhysics is now a mess due to the changes in how optical physics was configured between Geant4 10.5-10.7. I'll have a think how to improve that.

Next is to add GeantOpticalPhysicsOptions as a member of GeantPhysicsOptions, but ran into some test failures as naturally the generated JSON changes. I did think about having it as a std::optional as we probably don't always want optical physics on. However, need to play about with that as I don't think nlohmann::json supports this directly (and not sure on Celeritas policy on use of std::optional). Advice/ideas welcome!

drbenmorgan avatar Aug 02 '24 19:08 drbenmorgan

@drbenmorgan To make life easier for now, let's just stick to the newer versions, and we can throw a "not implemented" for the older versions if the experiments still need it by the time we've got sufficient optical physics implemented 😅

sethrj avatar Aug 02 '24 19:08 sethrj

Modulo fixing any errors in the CI, I think this is close to ready. I guess the last step is unit tests for when the optical physics are enabled (they are off by default), but am not 100% sure where to add these. GeantImporterTest.cc and the LarSphere test would appear to be appropriate, but I then get failures on G4Cerenkov and G4Scintillation not being exportable by GeantImporter.cc. I'm not sure about the higher level celeb-sim/celer-g4 yet.

drbenmorgan avatar Aug 06 '24 11:08 drbenmorgan

Having played a bit with the tests as above, one slight interface smell (depending on point of view) with the use of std::optional is that setting options through the top level GeantPhysicsOptions feels a bit messy:

    GeantPhysicsOptions opts; // default, no optical options
    opts.optical_options.cerenkov_radiation = on; // whoops, not the correct interface, and is nullopt anyway

    // so have to either do
    GeantOpticalOptions optical; // gets you the defaults
    optical.cerenkov_radiation = false;
    opts.optical_options = optical;

    // or
    opts.optical_options = GeantOpticalOptions();
    (*opts.optical_options).cerenkov_radiation = false; // or .value()...

So I'm leaning towards @sethrj's suggestion to define an explicit operator bool() const for GeantOpticalOptions which would return false if none of the processes are activated. JSON to/from can work just the same (I think), but need to decide what default construction behaviour is, and from that the need for a "build_default" or "deactivate" member function to provide a simple switch.

drbenmorgan avatar Aug 06 '24 15:08 drbenmorgan

@stognini I'll implement your suggestions in a fresh PR!

drbenmorgan avatar Sep 03 '24 14:09 drbenmorgan

Sorry I pulled the trigger too soon!

sethrj avatar Sep 03 '24 14:09 sethrj

No worries. Everything was looking great, so was just having a final look in case I spotted any minor detail after yesterday's commits. Thanks a lot @drbenmorgan !

stognini avatar Sep 03 '24 14:09 stognini