9.4.  Parameters

The classes for users parameters management were added in 10.2 release for the purpose of simplification of users application code. The parameters objects are named parameters registered to a parameter manager, which provides the acces to them by name and performs their merging in multi-threading mode. Their usage is demonstrated in the basic examples B1 and B3a.

Further integration in the Geant4 framework is foreseen in the next Geant4 version.

9.4.1.  G4Parameter<T>

G4Parameter<T> templated class can be used instead of built-in types in order to facilitate merging of the values accumulated on workers to the master thread. The G4Parameter<T> object has, besides its value of the templated type T, also a name, the initial value, which the value is set to in Reset() function and a merge mode, specifying the operation which is performed in Merge() function. The merge mode is defined in G4MergeMode class enumeration. The default parameter merge operation is addition.

The parameter object can be either instatiated using its constructor and registerd in G4ParametersManager explicitly, or it can be created using G4ParametersManager::CreateParameter() function, their registering is then automatic. The first way is used in the basic examples B1 and B3a:

// B1RunAction.hh
class B1RunAction : public G4UserRunAction
{
  // ...
  private:
    G4Parameter<G4double> fEdep;
    G4Parameter<G4double> fEdep2;
};

// B1RunAction.cc
B1RunAction::B1RunAction()
: G4UserRunAction(),
  fEdep("Edep", 0.), 
  fEdep2("Edep2", 0.)   // the parameter is initialized with a name and a value = initValue
{ 
  // ..
  // Register parameter to the parameter manager
  G4ParameterManager* parameterManager = G4ParameterManager::Instance();
  parameterManager->RegisterParameter(fEdep);
  parameterManager->RegisterParameter(fEdep2); 
}

An alternative way of creating a parameter using G4ParametersManager is demonstrated below:

// B1RunAction.cc
B1RunAction::B1RunAction()
: G4UserRunAction()
{ 
  // ..
  // Parameters can be also created via parameter manager
  G4ParameterManager* parameterManager = G4ParameterManager::Instance();
  parameterManager->CreateParameter<G4double>("EdepBis", 0.);
  parameterManager->CreateParameter<G4double>("Edep2Bis", 0.);
}

The G4ParametersManager takes ownership of the parameters created by its CreateParameter() function the parameters allocated in the user code has to be deleted in the user code.

In multi-threading mode all parameters registered to G4ParametersManager accumulated on workers can be merged to the master thread by calling G4ParametersManager::Merge() function. This step may be not necessary in future after a planned closer integration of G4Parameter classes in the Geant4 kernel.

// B1RunAction.cc
void B1RunAction::EndOfRunAction(const G4Run* run)
{
  // ...
  // Merge parameters
  G4ParameterManager* parameterManager = G4ParameterManager::Instance();
  parameterManager->Merge();
}

The registered parameters can be accessed via G4ParametersManager by name:

  // ...
  // Access parameters
  G4ParameterManager* parameterManager = G4ParameterManager::Instance();
  G4double edepBis  = parameterManager->GetParameter<G4double>("EdepBis")->GetValue();
  G4double edep2Bis = parameterManager->GetParameter<G4double>("Edep2Bis")->GetValue();

9.4.2.  User defined parameters

Users can define their own parameter class derived from G4VParameter abstract base class. An example of a ProcessCounterParameter class, implementing a parameter holding a map of the processes occurences by the procesesses names, is given below. Such processes occurences map is used in several electromagnetic extended examples, e.g. TestEm1.

ProcCounterParameter.hh

#include "G4VParameter.hh"
#include "globals.hh"
#include <map>
class ProcCounterParameter : public G4VParameter
{
  public:
    ProcCounterParameter(const G4String& name) 
      : G4VParameter(name, 0), fProcCounter() {}
    virtual ~ProcCounterParameter() {}
    
    void CountProcesses(G4String procName);
    
    virtual void Merge(const G4VParameter& other);
    virtual void Reset();

  private:
    std::map<G4String,G4int> fProcCounter;
};

ProcCounterParameter.cc

void ProcCounterParameter::Merge(const G4VParameter& other)
{
  const ProcCounterParameter& otherProcCounterParameter 
    = static_cast<const ProcCounterParameter&>(other);

  std::map<G4String,G4int>::const_iterator it;
  for (it = otherProcCounterParameter.fProcCounter.begin(); 
       it != otherProcCounterParameter.fProcCounter.end(); ++it) {
       
    G4String procName = it->first;
    G4int otherCount  = it->second;
    if ( fProcCounter.find(procName) == fProcCounter.end()) {
      fProcCounter[procName] = otherCount;
    }
    else {
      fProcCounter[procName] += otherCount;
    }         
  }
} 

void ProcCounterParameter::Reset()
{
  fProcCounter.clear();
}

The implementation of the CountProcesses() function is identical as in Run::CountProcesses() function in TestEm1.