
-------------------------------------------------------------------

     =========================================================
     Geant4 - an Object-Oriented Toolkit for Simulation in HEP
     =========================================================

                    Example ThreadsafeScorers
                    ----------------------------

 This example demonstrates a very simple application where an energy
 deposit and # of steps is accounted in thread-local (i.e. one instance per 
 thread) hits maps with underlying types of plain-old data (POD) and global
 (i.e. one instance) hits maps with underlying types of atomics.
 The example uses a coarse mesh, extensive physics, and step limiters
 to ensure that there is a higher degree of conflict between threads
 when updating the scorers to test the robustness of the atomics
 classes and maximize the compounding of thread-local round-off error.
    At the end of the simulation, the scorers are printed to
 "mfd_<DATA_TYPE>_<SCORER_TYPE>.out", where DATA_TYPE is either 
 "tl" (thread-local) or "tg" (thread-global) and SCORER_TYPE is "EnergyDeposit"
 or "NumberOfSteps". These values are then compared to a thread-global
 sum of these scorers that were updated via mutex locking. If round-off
 errors in thread-local EnergyDeposit are present, they can be viewed
 in "mfd_diff.out" at the end of the simulation

 1- ATOMICS and the ATOMIC SCORERS

   atomics can ONLY handle plain-old data (POD) types, e.g. int, double, etc.
   The implementation of atomics in compiler-dependent. At the very worst,
   the performance of an atomic is the same mutex locking.
   Atomics, in general, are not copy-constructable. This has to do with
   thread safety (e.g. making a copy while another thread tries to update)
   This is why atomics cannot be used in STL containers. The implementation
   in atomic.hh has limited copy-construction and still cannot be used in
   STL containers. Use these copy-constructors with extreme caution. See
   opening comments of G4atomic.hh for more details.
   
   The newly provided classes in this example (G4atomic, G4TAtomicHitsMap, and
   G4TAtomicHitsCollection) are intended for applications where memory is a 
   greater concern than performance. While atomics generally perform better than
   mutex locking, the synchronization is not without a cost. However, since
   the memory consumed by thread-local hits maps scales roughly linearly
   with the number of threads, simulations with a large number of scoring
   volumes can decrease simulation time by increasing the number of threads 
   beyond what was previously allowed due to the increase in memory consumption.
   ***************************************************************************
   *** These classes are intended to be included in the Geant4 source code ***
   *** release next year                                                   ***
   ***************************************************************************
   
   The G4TAtomicHitsMap and G4TAtomicHitsCollection work exactly the same way
   as the standard G4THitsMap and G4THitsCollection, respectively, with the
   exception(s) that you should only implement one instance and provide a 
   pointer/reference of that instance to the threads instead of having the
   threads create them. Additionally, there is no need to include them
   in the G4Run::Merge().
    
 2- GEOMETRY DEFINITION
  
   The geometry is constructed in the TSDetectorConstruction class.
   The setup consists of a box filling the world. The volume is divided into
   subregions, where the outermost boxes are a different material. The materials
   by default are water and boron as these have large scattering cross-sections 
   for neutrons (the default particle). 
    
 3- PHYSICS LIST
 
   The particle's type and the physic processes which will be available
   in this example are set are built from a variety of physics constructors.
   The chosen physics lists are extensive, primarily
   The constructors are:

      G4EmStandardPhysics_option4
      G4DecayPhysics
      G4RadioactiveDecayPhysics
      G4HadronPhysicsQGSP_BERT_HP
      G4HadronElasticPhysicsHP
      G4StepLimiterPhysics
      G4IonElasticPhysics
      G4IonBinaryCascadePhysics

 4- ACTION INITALIZATION

   TSActionInitialization, instantiates and registers to Geant4 kernel
    all user action classes.

   While in sequential mode the action classes are instatiated just once,
   via invoking the method:
      TSActionInitialization::Build()
   in multi-threading mode the same method is invoked for each thread worker
   and so all user action classes are defined thread-local.

   A run action class is instantiated both thread-local 
   and global that's why its instance is created also in the method
      TSActionInitialization::BuildForMaster() 
   which is invoked only in multi-threading mode.
     
 5- PRIMARY GENERATOR
  
   The primary generator is defined in the TSPrimaryGeneratorAction class.
   The default kinematics is a 1 MeV neutron, randomly distributed in front
   of the target across 100% of the transverse (X,Y) target size.
   This default setting can be changed via the Geant4 built-in commands 
   of the G4ParticleGun class.
     
 6- DETECTOR RESPONSE

   This example demonstrates a scoring implemented
   in the user action classes and TSRun object.
   
   The energy deposited is collected per event in the PrimitiveScorer
   G4PSEnergyDeposit (as part of a MultiFunctionalDetector)
   and the thread-local version are merged at the end of the run.
   
   The number of steps is collected per event in the PrimativeScorer
   G4PSNoOfSteps and the thread-local version are merged at the end of the run.

   When the MFD is recording an event i.e. TSRun::RecordEvent(const G4Event*),
   the global atomic hits map adds the same hits collections

   In multi-threading mode the energy accumulated in TSRun MFD object per
   workers is merged to the master in TSRun::Merge().

  7- HOW TO RUN

    - Execute ts_scorers in the 'interactive mode' with visualization:
        % ./ts_scorers
      and type in the commands from run.mac line by line:
        Idle> /control/verbose 2
        Idle> /tracking/verbose 1
        Idle> /run/beamOn 10 
        Idle> ...
        Idle> exit
      or
        Idle> /control/execute run.mac
        ....
        Idle> exit

    - Execute ts_scorers in the 'batch' mode from macro files
      (without visualization)
        % ./ts_scorers run.mac
        % ./ts_scorers run.mac > run.out

  
