User Interface - Defining New Commands¶
G4UImessenger¶
G4UImessenger
is a base class which represents a messenger that
delivers command(s) to the destination class object. Concrete messengers
are instantiated by, and owned by, the functional classes for which they
provide a user interface; messengers should be deleted by those classes
in their own destructors.
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.
G4UIcommand
objects are owned by the messenger. If instantiated via
new, they should be deleted in the messenger destructor.
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
, andG4State_EventProc
. Refer to the as a state machine for meaning of each state. Please note that thePause
state had been removed fromG4ApplicationState
.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 theSetParameterName()
method. For the case of aG4ThreeVector
, you can set the relation between parameters, e.g.,"x > y"
.
G4UIdirectory¶
This is a G4UIcommand
derived class for defining a directory
containing commands. It is owned by, and should be deleted in the
destructor of, the associated G4UImessenger class, after all of its
contained commands have been deleted.
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 theSetNewValue()
method of your messenger into Boolean.G4String convertToString(G4bool currVal)
Convert the current Boolean value to
G4String
which should be returned by theGetCurrentValue()
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 theSetNewValue()
method of your messenger into integer.G4String convertToString(G4int currVal)
Convert the current integer value to
G4String
, which should be returned by theGetCurrentValue()
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 theSetNewValue()
method of your messenger into double.G4String convertToString(G4double currVal)
Convert the current double value to
G4String
which should be returned by theGetCurrentValue()
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 theSetNewValue()
method of your messenger into aG4ThreeVector
.G4String convertToString(G4ThreeVector currVal)
Convert the current three vector to
G4String
, which should be returned by theGetCurrentValue()
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 theSetNewValue()
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 theSetNewValue()
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 theSetNewValue()
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 theGetCurrentValue()
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 theSetNewValue()
method of your messenger into aG4ThreeVector
. 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 theSetNewValue()
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 theSetNewValue()
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 theGetCurrentValue()
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 overridden by the current value of the
target class.
An example messenger¶
This example is of G4ParticleGunMessenger
, which is made by
inheriting G4UIcommand
.
#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
#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 std::cout and std::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(const G4String& coutString); G4int ReceiveG4cerr(const G4String& cerrString);
These methods receive the string stream of
G4cout
andG4cerr
, 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(const G4String& coutString) { logFile << coutString << flush; return 0; }
Set the destination of
G4cout/G4cerr
usingG4UImanager::SetCoutDestination(session)
.Typically this method is invoked from the constructor of
G4UIsession
and its derived classes, such asG4UIGAG/G4UIteminal
. This method sets the destination ofG4cout/G4cerr
to the session. For example, when the following code appears in the constructor ofG4UIterminal
, the methodSetCoutDestination(this)
tells UImanager that this instance ofG4UIterminal
receives the stream generated byG4cout
.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
exampleB1
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; }
Note
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 [Ellis1990]
P.J.Plauger, “The Draft Standard C++ Library” [Plauger1995]