User Interface - Defining New Commands
G4UImessenger
G4UImessenger is a base class which represents a
messenger that delivers command(s) to the destination class object. Your
concrete messenger should have the following functionalities.
Construct your command(s) in the constructor of your messenger.
Destruct your command(s) in the destructor of your messenger.
These requirements mean that your messenger should keep all
pointers to your command objects as its data members.
You can use G4UIcommand derived classes for the most
frequent types of command. These derived classes have their own
conversion methods according to their types, and they make
implementation of the SetNewValue() and
GetCurrentValue() methods of your messenger much easier
and simpler.
For complicated commands which take various parameters, you can
use the G4UIcommand base class, and construct
G4UIparameter objects by yourself. You don't need to delete
G4UIparameter object(s).
In the SetNewValue() and GetCurrentValue()
methods of your messenger, you can compare the G4UIcommand
pointer given in the argument of these methods with the pointer of
your command, because your messenger keeps the pointers to the
commands. Thus, you don't need to compare by command name. Please
remember, in the cases where you use G4UIcommand derived
classes, you should store the pointers with the types of these
derived classes so that you can use methods defined in the derived
classes according to their types without casting.
G4UImanager/G4UIcommand/G4UIparameter have very powerful
type and range checking routines. You are strongly recommended to
set the range of your parameters. For the case of a numerical value
(int or double), the range can be given by a
G4String using C++ notation, e.g., "X > 0 &&
X < 10". For the case of a string type parameter, you can
set a candidate list. Please refer to the detailed descriptions below.
GetCurrentValue() will be invoked after the user's
application of the corresponding command, and before the
SetNewValue() invocation. This GetCurrentValue()
method will be invoked only if
at least one parameter of the command has a range
at least one parameter of the command has a candidate list
at least the value of one parameter is omitted and this
parameter is defined as omittable and
currentValueAsDefault
For the first two cases, you can re-set the range or the candidate
list if you need to do so, but these ``re-set'' parameters are
needed only for the case where the range or the candidate list
varies dynamically.
A command can be ``state sensitive'', i.e., the command can be
accepted only for a certain G4ApplicationState(s). For
example, the /run/beamOn command should not be accepted
when Geant4 is processing another event (``G4State_EventProc''
state). You can set the states available for the command with the
AvailableForStates() method.
G4UIcommand and its derived classes
Methods available for all derived classes
These are methods defined in the G4UIcommand base class
which should be used from the derived classes.
void SetGuidance(char*)
Define a guidance line. You can invoke this method as many times
as you need to give enough amount of guidance. Please note that the
first line will be used as a title head of the command guidance.
void availableForStates(G4ApplicationState s1,...)
If your command is valid only for certain states of the Geant4
kernel, specify these states by this method. Currently available
states are G4State_PreInit, G4State_Init, G4State_Idle,
G4State_GeomClosed, and G4State_EventProc.
Refer to the section 3.4.2 for meaning of each state. Please note that
the Pause state had been removed from
G4ApplicationState.
void SetRange(char* range)
Define a range of the parameter(s). Use C++ notation, e.g.,
"x > 0 && x < 10", with variable name(s)
defined by the SetParameterName() method. For the case of
a G4ThreeVector, you can set the relation between
parameters, e.g., "x > y".
G4UIdirectory
This is a G4UIcommand derived class for defining a
directory.
G4UIdirectory(char* directoryPath)
Constructor. Argument is the (full-path) directory, which must
begin and terminate with `/'.
G4UIcmdWithoutParameter
This is a G4UIcommand derived class for a command which
takes no parameter.
G4UIcmdWithoutParameter(char* commandPath,
G4UImessenger* theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
G4UIcmdWithABool
This is a G4UIcommand derived class which takes one
boolean type parameter.
G4UIcmdWithABool(char* commandpath,G4UImanager*
theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
void SetParameterName(char* paramName,
G4bool omittable)
Define the name of the boolean parameter and set the omittable
flag. If omittable is true, you should define the default value
using the next method.
void SetDefaultValue(G4bool defVal)
Define the default value of the boolean parameter.
G4bool GetNewBoolValue(G4String paramString)
Convert G4String parameter value given by the
SetNewValue() method of your messenger into boolean.
G4String convertToString(G4bool currVal)
Convert the current boolean value to G4String
whichshould be returned by the GetCurrentValue() method
of your messenger.
G4UIcmdWithAnInteger
This is a G4UIcommand derived class which takes one
integer type parameter.
G4UIcmdWithAnInteger(char* commandpath,
G4UImanager* theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
void SetParameterName(char* paramName,
G4bool omittable)
Define the name of the integer parameter and set the omittable
flag. If omittable is true, you should define the default value
using the next method.
void SetDefaultValue(G4int defVal)
Define the default value of the integer parameter.
G4int GetNewIntValue(G4String paramString)
Convert G4String parameter value given by the
SetNewValue() method of your messenger into integer.
G4String convertToString(G4int currVal)
Convert the current integer value to G4String, which
should be returned by the GetCurrentValue() method of your
messenger.
G4UIcmdWithADouble
This is a G4UIcommand derived class which takes one
double type parameter.
G4UIcmdWithADouble(char* commandpath,
G4UImanager* theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
void SetParameterName(char* paramName,
G4bool omittable)
Define the name of the double parameter and set the omittable
flag. If omittable is true, you should define the default value
using the next method.
void SetDefaultValue(G4double defVal)
Define the default value of the double parameter.
G4double GetNewDoubleValue(G4String paramString)
Convert G4String parameter value given by the
SetNewValue() method of your messenger into double.
G4String convertToString(G4double currVal)
Convert the current double value to G4String which
should be returned by the GetCurrentValue() method of
your messenger.
G4UIcmdWithAString
This is a G4UIcommand derived class which takes one
string type parameter.
G4UIcmdWithAString(char* commandpath,
G4UImanager* theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
void SetParameterName(char* paramName,
G4bool omittable)
Define the name of the string parameter and set the omittable
flag. If omittable is true, you should define the default value
using the next method.
void SetDefaultValue(char* defVal)
Define the default value of the string parameter.
void SetCandidates(char* candidateList)
Define a candidate list which can be taken by the parameter.
Each candidate listed in this list should be separated by a single
space. If this candidate list is given, a string given by the user
but which is not listed in this list will be rejected.
G4UIcmdWith3Vector
This is a G4UIcommand derived class which takes one
three vector parameter.
G4UIcmdWith3Vector(char* commandpath,
G4UImanager* theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
void SetParameterName(char* paramNamX, char* paramNamY,
char* paramNamZ, G4bool omittable)
Define the names of each component of the three vector and set
the omittable flag. If omittable is true, you should define the
default value using the next method.
void SetDefaultValue(G4ThreeVector defVal)
Define the default value of the three vector.
G4ThreeVector GetNew3VectorValue(G4String paramString)
Convert the G4String parameter value given by the
SetNewValue() method of your messenger into a
G4ThreeVector.
G4String convertToString(G4ThreeVector currVal)
Convert the current three vector to G4String, which
should be returned by the GetCurrentValue() method of
your messenger.
G4UIcmdWithADoubleAndUnit
This is a G4UIcommand derived class which takes one
double type parameter and its unit.
G4UIcmdWithADoubleAndUnit(char* commandpath,
G4UImanager* theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
void SetParameterName(char* paramName,
G4bool omittable)
Define the name of the double parameter and set the omittable
flag. If omittable is true, you should define the default value
using the next method.
void SetDefaultValue(G4double defVal)
Define the default value of the double parameter.
void SetUnitCategory(char* unitCategory)
Define acceptable unit category.
void SetDefaultUnit(char* defUnit)
Define the default unit. Please use this method and the
SetUnitCategory() method alternatively.
G4double GetNewDoubleValue(G4String paramString)
Convert G4String parameter value given by the
SetNewValue() method of your messenger into double.
Please note that the return value has already been multiplied by the
value of the given unit.
G4double GetNewDoubleRawValue(G4String paramString)
Convert G4String parameter value given by the
SetNewValue() method of your messenger into double but
without multiplying the value of the given unit.
G4double GetNewUnitValue(G4String paramString)
Convert G4String unit value given by the
SetNewValue() method of your messenger into double.
G4String convertToString(G4bool currVal,
char* unitName)
Convert the current double value to a G4String, which
should be returned by the GetCurrentValue() method of your
messenger. The double value will be divided by the value of the
given unit and converted to a string. Given unit will be added to the string.
G4UIcmdWith3VectorAndUnit
This is a G4UIcommand derived class which takes one
three vector parameter and its unit.
G4UIcmdWith3VectorAndUnit(char* commandpath,
G4UImanager* theMessenger)
Constructor. Arguments are the (full-path) command name and the
pointer to your messenger.
void SetParameterName(char* paramNamX, char* paramNamY,
char* paramNamZ,G4bool omittable)
Define the names of each component of the three vector and set
the omittable flag. If omittable is true, you should define the
default value using the next method.
void SetDefaultValue(G4ThreeVector defVal)
Define the default value of the three vector.
void SetUnitCategory(char* unitCategory)
Define acceptable unit category.
void SetDefaultUnit(char* defUnit)
Define the default unit. Please use this method and the
SetUnitCategory() method alternatively.
G4ThreeVector GetNew3VectorValue(G4String paramString)
Convert a G4String parameter value given by the
SetNewValue() method of your messenger into a
G4ThreeVector. Please note that the return value has
already been multiplied by the value of the given unit.
G4ThreeVector GetNew3VectorRawValue(G4String paramString)
Convert a G4String parameter value given by the
SetNewValue() method of your messenger into three vector,
but without multiplying the value of the given unit.
G4double GetNewUnitValue(G4String paramString)
Convert a G4String unit value given by the
SetNewValue() method of your messenger into a double.
G4String convertToString(G4ThreeVector currVal,
char* unitName)
Convert the current three vector to a G4String which
should be returned by the GetCurrentValue() method of
your messenger. The three vector value will be divided by the value of
the given unit and converted to a string. Given unit will be added
to the string.
Additional comments on the SetParameterName() method
You can add one additional argument of G4bool type for
every SetParameterName() method mentioned above. This
additional argument is named currentAsDefaultFlag and the
default value of this argument is false. If you assign
this extra argument as true, the default value of the
parameter will be overriden by the current value of the target
class.
An example messenger
This example is of G4ParticleGunMessenger, which is
made by inheriting G4UIcommand.
An example of G4ParticleGunMessenger.hh.
#ifndef G4ParticleGunMessenger_h
#define G4ParticleGunMessenger_h 1
class G4ParticleGun;
class G4ParticleTable;
class G4UIcommand;
class G4UIdirectory;
class G4UIcmdWithoutParameter;
class G4UIcmdWithAString;
class G4UIcmdWithADoubleAndUnit;
class G4UIcmdWith3Vector;
class G4UIcmdWith3VectorAndUnit;
#include "G4UImessenger.hh"
#include "globals.hh"
class G4ParticleGunMessenger: public G4UImessenger
{
public:
G4ParticleGunMessenger(G4ParticleGun * fPtclGun);
~G4ParticleGunMessenger();
public:
void SetNewValue(G4UIcommand * command,G4String newValues);
G4String GetCurrentValue(G4UIcommand * command);
private:
G4ParticleGun * fParticleGun;
G4ParticleTable * particleTable;
private: //commands
G4UIdirectory * gunDirectory;
G4UIcmdWithoutParameter * listCmd;
G4UIcmdWithAString * particleCmd;
G4UIcmdWith3Vector * directionCmd;
G4UIcmdWithADoubleAndUnit * energyCmd;
G4UIcmdWith3VectorAndUnit * positionCmd;
G4UIcmdWithADoubleAndUnit * timeCmd;
};
#endif
An example of G4ParticleGunMessenger.cc.
#include "G4ParticleGunMessenger.hh"
#include "G4ParticleGun.hh"
#include "G4Geantino.hh"
#include "G4ThreeVector.hh"
#include "G4ParticleTable.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWith3Vector.hh"
#include "G4UIcmdWith3VectorAndUnit.hh"
#include <iostream.h>
G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
:fParticleGun(fPtclGun)
{
particleTable = G4ParticleTable::GetParticleTable();
gunDirectory = new G4UIdirectory("/gun/");
gunDirectory->SetGuidance("Particle Gun control commands.");
listCmd = new G4UIcmdWithoutParameter("/gun/list",this);
listCmd->SetGuidance("List available particles.");
listCmd->SetGuidance(" Invoke G4ParticleTable.");
particleCmd = new G4UIcmdWithAString("/gun/particle",this);
particleCmd->SetGuidance("Set particle to be generated.");
particleCmd->SetGuidance(" (geantino is default)");
particleCmd->SetParameterName("particleName",true);
particleCmd->SetDefaultValue("geantino");
G4String candidateList;
G4int nPtcl = particleTable->entries();
for(G4int i=0;i<nPtcl;i++)
{
candidateList += particleTable->GetParticleName(i);
candidateList += " ";
}
particleCmd->SetCandidates(candidateList);
directionCmd = new G4UIcmdWith3Vector("/gun/direction",this);
directionCmd->SetGuidance("Set momentum direction.");
directionCmd->SetGuidance("Direction needs not to be a unit vector.");
directionCmd->SetParameterName("Px","Py","Pz",true,true);
directionCmd->SetRange("Px != 0 || Py != 0 || Pz != 0");
energyCmd = new G4UIcmdWithADoubleAndUnit("/gun/energy",this);
energyCmd->SetGuidance("Set kinetic energy.");
energyCmd->SetParameterName("Energy",true,true);
energyCmd->SetDefaultUnit("GeV");
energyCmd->SetUnitCandidates("eV keV MeV GeV TeV");
positionCmd = new G4UIcmdWith3VectorAndUnit("/gun/position",this);
positionCmd->SetGuidance("Set starting position of the particle.");
positionCmd->SetParameterName("X","Y","Z",true,true);
positionCmd->SetDefaultUnit("cm");
positionCmd->SetUnitCandidates("micron mm cm m km");
timeCmd = new G4UIcmdWithADoubleAndUnit("/gun/time",this);
timeCmd->SetGuidance("Set initial time of the particle.");
timeCmd->SetParameterName("t0",true,true);
timeCmd->SetDefaultUnit("ns");
timeCmd->SetUnitCandidates("ns ms s");
// Set initial value to G4ParticleGun
fParticleGun->SetParticleDefinition( G4Geantino::Geantino() );
fParticleGun->SetParticleMomentumDirection( G4ThreeVector(1.0,0.0,0.0) );
fParticleGun->SetParticleEnergy( 1.0*GeV );
fParticleGun->SetParticlePosition(G4ThreeVector(0.0*cm, 0.0*cm, 0.0*cm));
fParticleGun->SetParticleTime( 0.0*ns );
}
G4ParticleGunMessenger::~G4ParticleGunMessenger()
{
delete listCmd;
delete particleCmd;
delete directionCmd;
delete energyCmd;
delete positionCmd;
delete timeCmd;
delete gunDirectory;
}
void G4ParticleGunMessenger::SetNewValue(
G4UIcommand * command,G4String newValues)
{
if( command==listCmd )
{ particleTable->dumpTable(); }
else if( command==particleCmd )
{
G4ParticleDefinition* pd = particleTable->findParticle(newValues);
if(pd != NULL)
{ fParticleGun->SetParticleDefinition( pd ); }
}
else if( command==directionCmd )
{ fParticleGun->SetParticleMomentumDirection(directionCmd->
GetNew3VectorValue(newValues)); }
else if( command==energyCmd )
{ fParticleGun->SetParticleEnergy(energyCmd->
GetNewDoubleValue(newValues)); }
else if( command==positionCmd )
{ fParticleGun->SetParticlePosition(
directionCmd->GetNew3VectorValue(newValues)); }
else if( command==timeCmd )
{ fParticleGun->SetParticleTime(timeCmd->
GetNewDoubleValue(newValues)); }
}
G4String G4ParticleGunMessenger::GetCurrentValue(G4UIcommand * command)
{
G4String cv;
if( command==directionCmd )
{ cv = directionCmd->ConvertToString(
fParticleGun->GetParticleMomentumDirection()); }
else if( command==energyCmd )
{ cv = energyCmd->ConvertToString(
fParticleGun->GetParticleEnergy(),"GeV"); }
else if( command==positionCmd )
{ cv = positionCmd->ConvertToString(
fParticleGun->GetParticlePosition(),"cm"); }
else if( command==timeCmd )
{ cv = timeCmd->ConvertToString(
fParticleGun->GetParticleTime(),"ns"); }
else if( command==particleCmd )
{ // update candidate list
G4String candidateList;
G4int nPtcl = particleTable->entries();
for(G4int i=0;i<nPtcl;i++)
{
candidateList += particleTable->GetParticleName(i);
candidateList += " ";
}
particleCmd->SetCandidates(candidateList);
}
return cv;
}
How to control the output of G4cout/G4cerr
Instead of cout and cerr,
Geant4 uses G4cout and
G4cerr. Output streams from
G4cout/G4cerr
are handled by G4UImanager which allows the application
programmer to control the flow of the stream. Output strings may
therefore be displayed on another window or stored in a file. This
is accomplished as follows:
Derive a class from G4UIsession and implement the two
methods:
G4int ReceiveG4cout(G4String coutString);
G4int ReceiveG4cerr(G4String cerrString);
These methods receive the string stream of G4cout and
G4cerr, respectively. The string can be handled to meet
specific requirements. The following sample code shows how to make
a log file of the output stream:
ostream logFile;
logFile.open("MyLogFile");
G4int MySession::ReceiveG4cout(G4String coutString)
{
logFile << coutString << flush;
return 0;
}
Set the destination of G4cout/G4cerr using
G4UImanager::SetCoutDestination(session).
Typically this method is invoked from the constructor of
G4UIsession and its derived classes, such as
G4UIGAG/G4UIteminal. This method sets the destination of
G4cout/G4cerr to the session. For example, when the
following code appears in the constructor of G4UIterminal,
the method SetCoutDestination(this) tells
UImanager that this instance of
G4UIterminal receives the stream
generated by G4cout.
G4UIterminal::G4UIterminal()
{
UI = G4UImanager::GetUIpointer();
UI->SetCoutDestination(this);
// ...
}
Similarly, UI->SetCoutDestination(NULL) must be added
to the destructor of the class.
Write or modify the main program. To modify exampleN01
to produce a log file, derive a class as described in step 1 above,
and add the following lines to the main program:
#include "MySession.hh"
main()
{
// get the pointer to the User Interface manager
G4UImanager* UI = G4UImanager::GetUIpointer();
// construct a session which receives G4cout/G4cerr
MySession * LoggedSession = new MySession;
UI->SetCoutDestination(LoggedSession);
// session->SessionStart(); // not required in this case
// .... do simulation here ...
delete LoggedSession;
return 0;
}
G4cout/G4cerr should not be used in the constructor of a
class if the instance of the class is intended to be used as
static. This restriction comes from the language
specification of C++. See the documents below for details:
M.A.Ellis, B.Stroustrup, ``Annotated C++ Reference Manual'', Section 3.4
P.J.Plauger, ``The Draft Standard C++ Library''