Mokka C/C++ Common Geometry Access (CGA) API

2. The C/C++ library

2.1 CGAInit

This function builds the geometry model, the one that is used by the simulation.

#ifdef __cplusplus
extern "C" {
#endif
    void CGAInit(const char* steer, const char *model, const char* setup, const char *host, const char *user, const char *passwd);
#ifdef __cplusplus
}
#endif

The parameters of this function allow access to the MySql geometry database used by the geometry model.

steer=the content of the steering file. If not present, the empty string ("") can be passed.
model=the model name in the geometry database. Required.
setup=the detector setup. Can be passed the empty string ("").
host
=the host name where the geometry database is running. Can be passed as ' ' if one wants to connect to the geometry database running on aldebaran.in2p3.fr.
user=the user name for geometry database access. Can be passed as ' ' if one wants to log on the "consult" account on the geometry database running on aldebaran.in2p3.fr.
passwd=the user password for geometry database access. Can be passed as ' ' which means passing the default password for the "consult" account on the geometry database running on aldebaran.in2p3.fr.

The following example shows how one could use this function:

char steer[]=""
char model[]="D08"
char setup[]=""
char host[]=""
char user[]=""
char passwd[]=""
CGAInit(steer, model, setup, host, user, passwd)

OR

CGAInit(" ", "D08", " ", " ", " ", " ")

2.2 CGAWhereAmI

This function gives you the name of the volume that a given point (x, y, z) is situated in:

#ifdef __cplusplus
extern "C" {
#endif
    void CGAWhereAmI(double * point, char *volName, int volNameLen);
#ifdef __cplusplus
}
#endif

The parameters of the function are as follows:

point=the x, y, z coordinates (in centimeters) of the point.
volName=the name of the volume (GEANT 4 logical volume) that "point" is situated in. This is filled by the function. If one did not allocate enough memory for volName, the name will be truncated.
volNameLen=the number of allocated characters for volName.

The following example shows how one could use this function and its return value:

#define MAXSTRLEN 30

double point[3];
char volName[MAXSTRLEN];

point[0] = -200*sin(3.1418/8);
point[1] = 200*cos(3.1418/8);
point[2] = 0;

CGAWhereAmI(point, volName, MAXSTRLEN);

fprintf(stdout, "%s\n", volName);

2.3 Getting the information on the particle passage through the volumes

One of the items of interest in reconstruction is to know the distances, or the number of X0 (the radiation length) that a particle traveled along in the different volumes, layers, etc. In order to get this information, one has first to shoot the desired particle, using the function CGABeamOn, and then to get the information using the function CGAGetSteps or the function CGAGetVolumeData.

2.3.1 CGABeamOn

This function allows one to shoot the desired particle:

#ifdef __cplusplus
extern "C" {
#endif
    void CGABeamOn(double *initial, double *final, double *direction,
                char * particle, float energy, int nbPart);
#ifdef __cplusplus
}
#endif

The parameters of this function are:

initial: the coordinates (in centimeters) of the point from where the particle is shot.
final: the coordinates (in centimeters) of the final point of the particle's trajectory. If the particle is charged, it shall be killed as soon as it enters the volume (layer) that the final point is situated in.
direction: the direction that the particle is shot.
particle:  the particle's name.
energy: the particle's energy.
nbPart: the number of particles that we want to shoot.

The following example shows how one could use this function:

double initial[3], final[3], direction[3];
float energy=20.0;
char particle[]="geantino";
int nbPart=1;

initial[0] = -68;
initial[1] = 169;
initial[2] = 0;
final[0] = -200*sin(3.1418/8);
final[1] = 200*cos(3.1418/8);
final[2] = 0;
direction[0] = final[0] - initial[0];
direction[1] = final[1] - initial[1];
direction[2] = final[2] - initial[2];

CGABeamOn(initial, final, direction, particle, energy, nbPart)

OR

CGABeamOn(initial, final, direction, "chargedgeantino", 20, 1);

2.3.2 CGAGetSteps

One can get the information on distances, number of X0 and the entrance point in evry volume by calling the function CGAGetSteps:

#ifdef __cplusplus
extern "C" {
#endif

    void CGAGetSteps(char ** volNames, char **matNames, double * distance,
                double **prePoints, double * nbX0, double *nInterLen,
                int * nSteps, int *OKFlag, int volNameLen, int matNameLen);

#ifdef __cplusplus
}
#endif

The parameters of the function are as follows:

volNames=an array of names of the volumes (GEANT 4 logical volumes) that the particle went through. This array is filled by the function. If one did not allocate enough memory for every name, the names will be truncated.
matNames=an array of names of the materials (GEANT 4 materials) that the particle went through. This array is filled by the function. If one did not allocate enough memory for every name, the names will be truncated.
distance=an array of distances that the particle went along in each volume. This array is filled by the function.
prePoints=a matrix of the x, y, z coordinates of the entrance point in evry volume. This matrix is filled by the function.
nbX0=an array containig the number of radiation lengths in evry volume that the particle went through. This array is filled by the function.
nInterLen=an array containig the number of interaction lengths in evry volume that the particle went through. This array is filled by the function.
nSteps=the number of elements/volumes:
    - the initial value is the number of elements allocated for volNames, distance, nbX0, and the number of rows allocated for prePoints.
    - the value after this function returns is the real number of layers that the particle went through.
OKFlag=when this function returns, it is set to -1 if the initial value of nsteps is less than the number of volumes that the particle went through, otherwise OKFlag is left unchanged.  Thus, one should test OKFlag before trying to use the return values of the function. If it is set to -1, one should allocate a larger amount of elements for the above parameters.
volNameLen=the number of allocated characters for every volName.
matNameLen=the number of allocated characters for every matName.

The following example shows how one could use this function and its return values:

#define MAXSTRLEN 30
#define MAXLAYERS 1000

char **volNames, matNames;
double distance[MAXLAYERS];
double **preSteps, nbX0[MAXLAYERS], nIntLen[MAXLAYERS];
int nSteps=MAXLAYERS, OKFlag=1;

 volNames=(char**)malloc(MAXLAYERS*sizeof(char*));
 matNames=(char**)malloc(MAXLAYERS*sizeof(char*));
 preSteps=(double**)malloc(MAXLAYERS*sizeof(double*));
 for(i=0; i<MAXLAYERS; i++) {
                volNames[i]=(char*)malloc(MAXSTRLEN*sizeof(char));
                matNames[i]=(char*)malloc(MAXSTRLEN*sizeof(char));
                preSteps[i]=(double*)malloc(3*sizeof(double));
 }

CGAGetSteps(volNames, matNames, distance, preSteps, nbX0, nIntLen, &nSteps,
                &OKFlag, MAXSTRLEN, MAXSTRLEN);

if(OKFlag == -1) {
                fprintf(stderr, "CGAGETSTEPS ERROR!\n");
                exit(1);
}

for(i=0; i<nSteps; i++) {
                fprintf(stdout, "%s %f %f %f %f %f\n", volNames[i], distance[i],
                        preSteps[i][0], preSteps[i][1], preSteps[i][2],
                        nbX0[i]);
}

2.3.3 CGAGetVolumeData

Suppose we were interested in getting the above information as a sum over the layers of a module. We can use for this purpose the function CGAGetVolumeData:

#ifdef __cplusplus
extern "C" {
#endif
void CGAGetVolumeData(char * volName, double * distance,
                double **preSteps, double * nbX0, double *nInterLen,
                int * nSteps, int * OKFlag);
#ifdef __cplusplus
}
#endif

The parameters of the subroutine are as follows:

volName=the name of the (GEANT 4 logical volume) of the module of interest.
distance=an array of distances that the particle went along in each module. This array is filled by the function.
preSteps=a matrix of the x, y, z coordinates of the entrance point in evry module. This matrix is filled by the function.
nbX0=an array containig the number of radiation lengths in evry module that the particle went through. This array is filled by the function.
nInterLen=an array containig the number of interaction lengths in evry volume that the particle went through. This array is filled by the function.
nSteps=the number of elements/modules:
    - the initial value is the number of elements allocated for distance, nbX0, and the number of rows allocated for prePoints
    - the value after this function returns is the real number of modules that the particle went through.
OKFlag=when this function returns, it is set to -1 if the initial value of nsteps is less than the number of volumes that the particle went through, otherwise OKFlag is left unchanged.  Thus, one should test OKFlag before trying to use the return values of the function. If it is set to -1, one should allocate a larger amount of elements for the above parameters.

The following example shows how one could use this function and its return values:

#define MAXLAYERS 1000

double distance[MAXLAYERS];
double **preSteps, nbX0[MAXLAYERS], nIntLen[MAXLAYERS];
int nSteps=MAXLAYERS, OKFlag=1;

 preSteps=(double**)malloc(MAXLAYERS*sizeof(double*));
 for(i=0; i<MAXLAYERS; i++) {
                preSteps[i]=(double*)malloc(3*sizeof(double));
 }

CGAGetVolumeData("EnvLog", distance, preSteps, nbX0, nIntLen, &nSteps,
                &OKFlag);

if(OKFlag == -1) {
                fprintf(stderr, "ERREUR GETVOLDATA\n");
                exit(1);
}

for(i=0; i<nSteps; i++) {
                fprintf(stdout, "EnvLog %f %f %f %f %f\n", distance[i],
                        preSteps[i][0], preSteps[i][1], preSteps[i][2], nbX0[i]);
}
 

2.4 Getting the coordinates of the cell center

    The cell center coordinates are calculated by the sensitive detector. One has to set the right sensitive detector first by using CGASetSD, and then use CGACellIndex to get the cell center coordinates. Example no. 4 shows how to get the cell center coordinates from a LCIO file written by Mokka. One first has to read a SIMCALORIMETERHIT collection, get its flag and pass it to CGASetSD. Then make a loop over all hits of the collection and for every hit call CGACellIIndex with the CellID0 of the hit.

2.4.1 CGASetSD

   Just call this function with the flag as argument:

LCCollection* col = evt->getCollection( *name ) ;
LCFlagImpl flag( col->getFlag() ) ;
CGASetSD(flag.getFlag());
 

2.4.2 CGACellIndex

    One can call this function with the CellID 0 of the hit as argument and it will return the x, y, z coordinates of the cell center as a std::vector<double>:

int id0 = hit->getCellID0();
std::vector<double> result  =  CGACellIndex(id0);
cout << " pos from CGA: (" <<
           result[0] << ", " <<
           result[1] << ", " <<
           result[2] << ")" << endl;
 
 
 

2.5 Getting the CellId of a point

    The CellId of a point of given coordinates is calculated by the sensitive detector. One has to set the right sensitive detector first by using CGASetSD, and then use CGAGetCellId to get the compressed cell index.

NB: With the latest versions of Geant 4, one has also to shoot first a particle, so that Geant 4 does its initializations.


2.5.1 CGAGetCellId

    One can call this function with the coordinates of the point, a flag that will be returned by the method to show if the point was really inside a cell (flag = 1), inside a guard-ring (flag = 0; the CellId will be the one of the nearest cell), or inside anothe volume that is not sensitive (flag = -1 and CellId = 0), and optionnally a direction that is used by Geant 4 if the point is on the border of two volumina.

int cellId, flag;
double x = 50.0, y = 20.0, z = -15.0;
double xDir = 1.0, yDir = 0.0, zDir = 1.0;
CGASetSD(SDIndex);

cellId = CGAGetCellId(x, y, z, flag, xDir, yDir, zDir);

or

cellId = CGAGetCellId(x, y, z, flag); // the default direction is (0.0, 0.0, 1.0)



Back to CGA API home page


Team working on the Geant4 simulation for The Next Linear Collider:
      Henri VIDEAU
      Jean-Claude BRIENT
      Paulo Mora de Freitas
      Gabriel Musat