spradlin / WCSim

The WCSim GEANT4 application
0 stars 0 forks source link

Use cmake build option to toggle overlap checking #23

Closed spradlin closed 1 year ago

spradlin commented 1 year ago

Offshoot of #17.

I want to be able to toggle comprehensive overlap checking in WCSim without modifying the source code.

spradlin commented 1 year ago

Overlap checking during geometry placement

When a GEANT4 G4PVPlacement physical volume is created, one of its constructor arguments is a bool flag that toggles the check for overlaps between the created volume and its containing/parent volume and, presumably, the other volumes contained in the parent volume. This is absolutely necessary when designing and debugging a representation of a detector or other simulated physical system. However, it produces a lot of output and is not necessary with a debugged geometry definition.

This is recognized in comments such as the following in src/WCSimConstructCylinder.cc:

  // Optionally switch on the checkOverlaps. Once the geometry is debugged, switch off for 
  // faster running. 

The current system seems to involve inchorently toggling members of WCSimDetectorConstruction:

I want to remove these data members and to replace their usage with uses of preprocessor constants that can be set by the cmake build system.

spradlin commented 1 year ago

Fixing overlap checking at compile time

Because one of the WCSimDetectorConstruction::checkOverlaps data members is passed to almost all of the G4PVPlacement calls, it is relatively easy to specify the at compile time. I have adopted the following:

  1. Declare the WCSimDetectorConstruction::checkOverlaps to be static constexpr. This makes these flags compiler constants while also retaining their type information and scope as data members of WCSimDetectorConstruction.
  2. Initialize the flags with a preprocessor variable that is set by the build system.

The first part is easy---just add static constexpr before the existing declarations of WCSimDetectorConstruction::checkOverlaps and WCSimDetectorConstruction::checkOverlapsPMT in the header. Being declared constexpr requires initialization at declaration, so these need to be assigned to appropriate values in the header.

I am assuming a preprocessor macro named WCSIM_CHECK_GEOMETRY_OVERLAPS. I have tried two methods of using a macro with the static constexpr data members, both of which work:

  1. If WCSIM_CHECK_GEOMETRY_OVERLAPS is equivalent to a macro that can be either #define or not. In this case, one can use an #ifdef #else #endif block to set the values of the overlap flags.
  2. If WCSIM_CHECK_GEOMETRY_OVERLAPS is a macro that cmake sets to contain either the string true or the string false. In this case, WCSIM_CHECK_GEOMETRY_OVERLAPS can be used on the right-hand-side of the initialization assignment for the static constexpr

Option 1 can be implemented in the source with a pattern like

#ifdef WCSIM_CHECK_GEOMETRY_OVERLAPS
  static constexpr G4bool checkOverlaps = true;
  static constexpr G4bool checkOverlapsPMT = true;
#else
  static constexpr G4bool checkOverlaps = false;
  static constexpr G4bool checkOverlapsPMT = false;
#endif

Option 2 is much cleaner in the source code:

  static constexpr G4bool checkOverlaps = WCSIM_CHECK_GEOMETRY_OVERLAPS;
  static constexpr G4bool checkOverlapsPMT = WCSIM_CHECK_GEOMETRY_OVERLAPS;

I prefer Option 2.

spradlin commented 1 year ago

Defining preprocessor macro in cmake

Web searches indicate that the cmake command target_compile_definitions. It allows one to do in cmake what one would normally do with #define statments in the source files. For example, one could turn on the overlap checking in Option 2 of the previous comment by including the following command in the CMakeLists.txt:

target_compile_definitions(WCSim PRIVATE WCSIM_CHECK_GEOMETRY_OVERLAPS=true)

This will make the substitution of true for every instance of WCSIM_CHECK_GEOMETRY_OVERLAPS in the source code for the WCSim target at build time without needing #define statements in the source code.

But that does not yet let me toggle it easily with cmake options. So, let me define a cmake option named WCSim_Geometry_Overlaps_CHECK by adding to the CMakeLists.txt file the following:

option(WCSim_Geometry_Overlaps_CHECK "Toggle GEANT4 overlap checking when placing geometry elements" OFF)

This adds a cmake option to the build system that can be set to either ON or OFF either with a cmake command line -D:

$ cmake -DWCSim_Geometry_Overlaps_CHECK=ON <build_dir>

or with the ccmake configuration utility.

Now all i need to do is use the value of the cmake option WCSim_Geometry_Overlaps_CHECK to set the value of the WCSIM_CHECK_GEOMETRY_OVERLAPS preproccessor macro. I used cmake-generator-expressions to conditionally set it to true or false:

target_compile_definitions(WCSim PRIVATE WCSIM_CHECK_GEOMETRY_OVERLAPS=$<IF:$<BOOL:${WCSim_Geometry_Overlaps_CHECK}>,true,false>)

And...it works! I can now turn overlap checking on or off, consistently and coherently, with a simple cmake option!

spradlin commented 1 year ago

Incorporated into tdealtry/main_into_hybrid at https://github.com/tdealtry/WCSim/commit/7663873c5d11d4cc1a50e535a185e6ed0124c6a4.