Event-struct Package for Sunsort

Relies on: Coord, Vector, Reaction
C include file: evsubs.h
FORTRAN include files: subs.i and evsubs.i

This package allows the user to manipulate particle objects. The user can set properties of a particle and read them back. The package is intelligent and, given partial information about a particle, it will calculate missing parameters.

Particle data is held in an opaque structure typedefed to be called particle. Users should not attempt to access the structure directly or make any assumptions about its contents.

There are essentially two types of particles. Those which were directly detected in the reaction or inferred from missing momentum in the reaction and those that have been inferred by kinematic reconstruction of a parent particle by combining two daughter particles.

Although particles can be created individually in C, they are usually built into an array. In FORTRAN they can only be accessed through an array and then only through the default array.

Particle Parameters

Particles have the following parameters. The parameter types are noted as double (FORTRAN double precision), int (FORTRAN integer), vector (uses the Vector package or particle (in C a particle *, in FORTRAN and integer index into the default particle array).

Some parameters are read-only. They have been noted below. Those parameters that can be calculated automatically have also been noted.

double v_x, v_y and v_z

Together these three parameters hold the velocity of the particle. Note that these three parameters may be replaced by a vector structure at some time in the future. To cope with this possibility, the set and read routines look like they will do after this change is made. These values are not auto-calculated at the moment, but may be in future.

vector p

This holds the momentum of the particle. This is handled by the vector package so many properties of this can be requested. This can be auto-calculated. Note that this parameter can be in three states: unknown, direction (but not magnitude) known and completely known.

double e

The energy of the particle. This can be auto-calculated.

double etot

This parameter holds a running total of daughter particle energies. This is not auto-calculated by the event-struct package, but is set by the RP package.

double t

This parameter holds a time associated with a particle. It's up to the user to decide which time to place here.

vector pcm

This holds the momentum of the particle in the centre of mass frame of the reaction. This is handled by the vector package so many properties of this can be requested. This is read only and is automatically calculated when requested.

double q

This holds the excitation Q.

double q2

This parameter holds the two body Q-value for this particle, that is the Q-value assuming that there were only two final state particles and this was one of them. It's read-only and is automatically calculated when requested.

double m

This parameter holds the mass of the particle. It may be auto-calculated.

integer z

This parameter holds the charge of the particle.

integer fold

This parameter holds the fold of the particle, that is the number of raw particles that have been added together to make this particle. For particles that are detected in the reaction this is 1. For particles made by combining two others, it's the sum of the folds of the daughter particles.

Although this parameter is not automatically calculated, it is set correctly by the RP package and the missing_p routine.

particle hi

If fold>1 then this is the identifier of the heavier particle. It is not auto-calculated, but is set correctly by the RP package.

particle li

If fold>1 then this is the identifier of the lighter particle. It is not auto-calculated, but is set correctly by the RP package.

integer det

if fold=1 and this particle was directly detected, then this is the number of the detector in which the particle was detected. The user may place any suitable value here, but it makes most sense to use that match the numbering of the detectors passed to the Coord package.

integer seg

if fold=1 and this particle was directly detected, then this is the segment within the detector where the particle was detected. The user may place any suitable value here.

Accessing parameters

For each parameter, except vector parameters, x there are routines ev_x and evs_x to read and set the parameter (for read-only parameters, the evs_x routine is missing). Each of the reading routines takes one parameter - a particle ID (in C a particle *, in FORTRAN an integer). Each of the writing routines takes two parameters, a particle ID and

For vector parameters, there are a series of reading routines ev_x_y where x is the name of the event-struct parameter and y is the name of the vector parameter (namely one of r, x, y, z, t, p, td, pd, tx, ty, txd, tyd and r2).

To completely set the momentum parameter, use one of the following routines: evs_p_xyz, evs_p_rtp, evs_p_rtpd, evs_p_rtt or evs_p_rttd. Their syntax is similar to the vector_set routines described in the Vector package but you pass a particle ID instead of a pointer to a vector. These can be called from FORTRAN unlike the vector_set routines themselves.

As well as completely setting a momentum vector, it's possible to just specify its direction. In this case the magnitude of the vector will be automatically calculated from other available data. The routines are evs_dir_xyz, evs_dir_tp, evs_dir_tpd, evs_dir_tt and evs_dir_ttd. They are similar to the evs_p routines described above except that the vector magnitude is ignored (in the case of the evs_dir_xyz routine) or not specified (in the case of the other routines). Note that these routines only set the direction of the momentum vector, they do not alter the direction of the velocity vector.

An alternative way of setting the momentum vector direction is to go through the Coord package with the evs_dir_from_coord routine described below.

The v_x, v_y and v_z parameters may be read individually with ev_v_x, ev_v_y and ev_v_z but may only be set as a group with evs_v_xyz which has similar syntax to evs_p_xyz. Should the decision be made to store the velocity using the Vector package then these calls will stay intact.

Automatic Calculation

Several event-struct parameters may be calculated automatically when sufficient information is available. Those that are read-only may only be calculated automatically, those that are read-write will be calculated if they haven't been set, but once the user has placed a value into them then the automatic calculation will be disabled.

The following list shows which variables may be automatically calculated and how it's done.

Particle energy (e)

If p and m are available then e is calculated as p^2/(2m). p must have been completely specified, not just its direction given.

If v and m are available then e is calculated as 0.5*m*v^2.

2 body Q-value (q2)

First the mass of the recoiling (mr) particle is calculated by taking the masses of the projectile (mp) and target (mt) from the reaction parameters and subtracting the mass of this particle. That is mr = mp+mt-m.

Secondly, q2 is calculated as

	(m+mr)*e - (mr-mp)*e1 - p1*p_z
	------------------------------
	              mr
      

e1 and p1 are the beam energy and momentum taken from the reaction parameters.

Mass (m)

If p and e are available then m is calculated as p^2/(2e). p must have been completely specified, not just its direction given.

If p and v are available then m is calculated as abs(p/v). Again p must have been completely specified, not just its direction given. No check is made that p and v point in the same direction.

Magnitude of momentum (p_r and p_r2)

If e, m and the direction of p have been specified, then p is scaled such that p^2 = 2*m*e.

Individual particle routines

void ev_reset_particle(particle *p);
subroutine ev_reset_particle(integer p)

This routine completely resets a particle throwing away all information about it. You must use this if you wish to reuse a particle slot otherwise some old information will persist.

If you want to reset an entire particle array, then use ev_reset described later.

void evs_dir_from_coord(particle *p, struct xy *c);
subroutine evs_dir_from_coord(integer p, double precision cx, double precision cy)

This routine sets the direction of the momentum vector of a particle from a hit location. The detector number the particle was detected in should already have been set with the evs_det routine and the detector coordinate data loaded into the Coord package.

In C you pass a structure giving the coordinate of the hit on the detector surface. In FORTRAN you pass it as two separate double precision numbers. See the documentation of the Coord package for more information.

Note that although you can't call the Coord package directly from FORTRAN, you can still go through this function.

particle *chit(particle *new, particle *old);
subroutine chit(integer new, integer old)

This routine makes an exact copy of a particle. old points to the existing particle and new points to where the copy should go. The C version returns the pointer new.

See also the routine new_chit described later.

particle *crhit(particle *new, double newmass, particle *old);
subroutine crhit(integer new, double precision newmass, integer old)

This routine makes an copy of a particle and then changes the mass of the copy. old points to the existing particle, new points to where the copy should go and newmass is the mass the new particle should have. Depending on what parameters were set in the old particle, parameters may have changed in the new particle (for example if the energy of the particle and the direction of the momentum were set in the old particle the the magnitude of the momenta will be different between the two particles).The C version returns the pointer new.

See also the routine new_crhit described later.

Arrays of particles

Although being able to manipulate particles is useful, they are more useful when grouped into an array. Once so grouped, a header is added. The header is defined to be a structure with at least the following elements:

	struct evhead {
	    ...
	    int cmult[];
	    int pmult[];
	    int n[];
	    int p[];
	    int type;
	    particle *ev;
	    struct reac *reac;
	};
      
The elements are as follows:
int cmult[]
Channel multiplicities. cmult[n] holds the number of channels that fired in detector n. cmult[0] holds the number of channels that have fired in the whole system.
int pmult[]
Particle multiplicities. pmult[n] holds the number of particles that hit detector n. pmult[0] holds the number of particles that have hit the whole system.
int n[]
Number of particles of each fold. n[1] holds the number of singles particles, n[2] the number of particles constructed out of 2 singles etc. n[0] holds the total number of particles in the array. n[] should always be kept up to date. Routines which create new particles will do this automatically.
int p[]
Offset to the start of particles of fold n. p[1] is always 1 and in general p[n] is p[n-1]+n[n-1]. p[] only need be kept up to date if the user wants to use it. No routine relies on the values in here, but some may update them.
int type
The type of the event. This is purely advisory and for the user's benefit. It is suggested that when the user identified the type of the event they place an identifying mark here for information.
particle *ev
This points to the base of the particle array.
struct reac *reac;
This points to the reaction to be used for calculations with this array.

cmult[] and pmult[] are advisory. The user may choose to keep them up to date or not. No routines will break if they are not kept up to date correctly.

There is one global array of particles accessible through the C external variable evhead. These are the only particles that can be accessed from FORTRAN. The particle IDs used in FORTRAN refer to array indeces in this default array. That is, FORTRAN particle 1 is C particle (evhead->ev + 1).

Array based routines

int ev_init(struct evhead *evh, struct reac *reac, int numdets, int maxfold, int np)
integer function ev_init(integer numdets, integer maxfold, integer np)

This routine creates an array of particles allocating memory for the particles and other arrays. It may be called several times for the same array in which case if first frees any existing memory.

evh is a pointer to the array to be initialised. reac is a pointer to the reaction to use for calculations on this array. numdets is the number of detectors (used to set the size of the cmult and pmult arrays. maxfold is the maximum number of particles that can be combined together (that is, the maximum value of the fold variable for a particle). np is the maximum number of particles that can be stored in the array (a good value is 2^maxfold).

This routine returns OK if all goes well otherwise it returns ABORT.

The FORTRAN version of this call always refers to the default array and uses the default reaction structure.

void ev_free(struct evhead *evh);

This routine deallocates all the memory associated with a particle array. It does not free the memory pointed to directly by evh.

This routine is only appropriate for particle arrays declared by the user in C, not for the global particle array structure which should be left alone.

void ev_reset(struct evhead *evh);
subroutine ev_reset

This routine resets a particle array. It sets the event type to 0, sets the cmult, pmult, n and p arrays all to zero except p[1] which is set to 1. It then calls ev_reset_particle for every particle in the array.

particle *ev_new_particle(struct evhead *evh);
integer function ev_new_particle()

This routine returns the next singles particle slot, that is particle index n[1]+1. It increments pmult[0], n[1] and n[0] in the array header. It the calls ev_reset_particle for the particle, sets the fold to 1, the excitation q to 0 and resets hi and li.

When you find a particle in your detector system, this is the function you call.

double evhead_etot(struct evhead *);
double precision function evhead_etot()

This routine calculates the total energy of all singles particles in a particle array. For the purpose of this call, the singles particles are those from p[1] to p[1]+n[1]-1 inclusive. The energy returned is the sum of all the e values for the particles in that range.

void wrtev(struct evhead *evh, int npart)
subroutine wrtev(integer npart)

This routine writes out the particle array header and the parameters of the first npart particles. It's a useful diagnostic.

particle *new_chit(particle *old);
integer function new_chit(integer old)

This routine makes an exact copy of a particle. The copy is placed in the next slot (given by n[0]) in the same array as the old particle. n[0] is updated.

These routines return NULL or -1 if there's no more room in the particle array.

See also the routine chit described earlier.

particle *new_chit(double newmass, particle *old);
integer function new_crhit(double precision newmass, integer old)

This routine makes an copy of a particle and then changes the mass of the copy. The copy is placed in the next slot (given by n[0]) in the same array as the old particle. n[0] is updated.

These routines return NULL or -1 if there's no more room in the particle array.

See also the routine crhit described earlier.

particle *missing_p(struct evhead *evh)
integer function missing_p()

This routine determines how much mass and momentum is missing from a reaction. It uses all the particles from 1 to n[1] to determine this. It then creates a new particle in slot n[0]+1 which balances the reaction.

This routine should be called before any two-fold (or higher) particles are created. If done this way then this particle will be counted in the etot calculations.

particle *punchthru(struct evhead *evh)
integer function punchthru()

As an alternative to missing_p, this routine determines how much momentum is missing from the reaction then finds the particle with the closest trajectory. It makes a copy of this particle into the next free slot of the array then alters the energy of the original particle to balance the reaction.

The routine returns the ID of the copy of the original particle. The ID of the modified particle (which is in the slot in the array the original particle occupied) is in the hi element of the copied particle.


Steven M. Singer
Last modified: Thu Sep 30 20:38:55 BST 1999