SPopulation

The class SPopulation is derived from PopBase, and serves as base class for concrete populations.

Generally every concrete population is associated with an agent data structure which it has to define. The agent data struct represents the individual agent properties, such as id, gender etc.

An important feature of a population are its actions. These actions (derived from Action) define species-specific propertoes and behaviour, such as mating, producing offspring, movement etc.

Code:

The agent structure

struct Agent {
    uint     m_iLifeState;
    int      m_iCellIndex;
    idtype   m_ulID;
    gridtype m_ulCellID;
    float    m_fBirthTime;
    uchar    m_iGender;
};
m_iLifeState

The life state of the agent, one of these values

Name

Value

LIFE_STATE_DEAD

0

the agent is dead

LIFE_STATE_ALIVE

1

the agent is alive

LIFE_STATE_FERTILE

5

the agenmt is live and fertile

LIFE_STATE_MOVING

8

the agent is moving

LIFE_STATE_SAILING

16

(currently not used)

m_iCellIndex

The index of the cell tha agent is currently inhabiting.

m_ulID

The agent’s ID.

m_ulCellID

The cell’s ID. For single computer applications this is equal to the cell index.

m_fBirthTime

Step number at which the agent was born.

m_iGender

The gender of the agent (0:female, 1:male).

Populations derived from SPopulation must derive their agent structures from Agent.

Public Methods

constructor

SPopulation(SCellGrid *pCG, PopFinder *pPopLooper, int iLayerSize, IDGen **apIDGen, uint32_t *aulState);
pCG

The SCellGrid for the current simulation.

pPopFinder

A PopLooper object. Such an object knows all population objects being used in this simulation. Useful for predator-prey relation ships because predators must be able to find their prey.

apIDGen

An array of id generators (one for each thread), capable of creating unique ids for agents.

aulState

The initial state for the WELL random number generators`.

aiSeeds

Additional uints to seed WELL RNGs not used for moving and mating.

destructor

virtual ~SPopulation();

the destructor deletes all created objects and arrays.

setPrioList

virtual int  setPrioList();

Saves priority level data read from the input file.

preLoop

virtual int  preLoop();

This methood is called immediately before the simulation loop starts. Useful to do calculations not possible in the constructor.

postLoop

virtual int  postLoop();

This method is called immediatel after the simulation loop stops. Useful fo some cleanup operations.

preWrite

virtual int  preWrite(float fTime);
fTime

Current simulation step.

This method is called before data is written to the output file. Useful to prepare data for output.

doActions

virtual int doActions(uint iPrio, float fTime);
iPrio

Current priority level.

fTime

Current simulation step.

This method loops through all actions of the specified priority level and applies their execute() methods them to all agents of the population.

initializeStep

virtual int initializeStep(float fTime);
fTime

Current simulation step.

This method is called at the beginning of a simulation step before doActions() is invoked.

finalizeStep

virtual int finalizeStep();

This method is called just after doActions() at the end of the simulation step.

initListIdx

virtual void initListIdx();

This method clears the birth, death and move registration lists.

registerBirth

virtual void registerBirth(int iCellIndex, int iMotherIndex, int iFatherIndex=-1);
iCellIndex

ID of Cell in which a birth occurs.

iMotherIndex

Index of the mother agent.

iFatherIndex

Index of the Father agent.

Since births occur in the parallelized loop in doActions() we can’t make the changes immediately, because of potential race conditions. For this reason, every birth is registered (i.e. the relevant data is put into a list), and only in finalizeStep() are the births performed.

registerDeath

virtual void registerDeath(int iCellIndex, int iAgentIndex);
iCellIndex

ID of Cell in which a death occurs.

iAgentIndex

Index of the dead agent.

Since deaths occur in the parallelized loop in doActions() we can’t make the changes immediately, because of potential race conditions. For this reason, every death is registered (i.e. the relevant data is put into a list), and only in finalizeStep() are the deaths performed.

registerMove

virtual void registerMove(int iCellIndexFrom, int iAgentIndex, int iCellIndexTo);
iCellIndexFrom

Index of cell the agent currently inhabits.

iAgentIndex

Index of Agent wanting to move.

iCellIndexTo

Index of the cell the agent wants to move to.

Since moves occur in the parallelized loop in doActions() we can’t make the changes immediately, because of potential race conditions. For this reason, every move is registered (i.e. the relevant data is put into a list), and only in finalizeStep() are the moves performed.

reserveAgentSpace

virtual int  reserveAgentSpace(int iNumAgents);
iNumAgents

Number of spaces to reserve in the agent container.

Makes sure there are at least iNumAgents contiguous unused locations in the ACTIVE state.

Rerturns the first index of the reserved region.

updateEvent

virtual int  updateEvent(int iEventID, char *pData, float fT);
iEventID

ID of the event.

pData

Additional data.

fT

Current time step.

Handling of events. This method is called from within the simulation loop.

This method does nothing, but can be overwritten by derived classes.

flushEvents

virtual void flushEvents(float fT);
fT

Current time step.

This method is called from within the simulation loop when no more events are to be expected for this step. This can be used to minimize the updates by storing the events in updatEvent(), and actually handle them all in flushEvents().

compactData

virtual void compactData();

Rearranges the agents in the LayerBuf containers so that there is no hole between the first and the last agent. Usually this is only used when writing the agent data to file: each layer is compacted anf then written.

getMaxLoadedID

virtual idtype getMaxLoadedID();

Return the highest agent ID that has been loaded. This is needed to initialize the ID generator correctly.

getUID

virtual idtype getUID();

Returns a new unique Agent ID.

readSpeciesData

virtual int readSpeciesData(ParamProvider2 *pPP);
pPP

A pointer to a ParamProvider2 object.

Extracts class name, species name and priority levels from the ParamProvider2 object.

addAgent

virtual int addAgent(int iCellIndex, char *pData, bool bUpdateCount);

addAgentData

virtual int addAgentData(int iCellIndex, int iAgentIndex, char **ppData);
iCellIndex

Cell of the agent.

iAgentIndex

The agent’s index.

ppData

Pointer to a C-style string containing the values for agent attributes.

Tries to get the life state, the agent ID, the birth time and the gender from the string pointed at by ppData.

On exit of this function *ppData points to the beginning of the next data item.

addAgentDataSingle

template<typename T1>    int addAgentDataSingle(char **ppData, T1 *pAgentDataMember);
ppData

Pointer to a C-style string containing the values for agent attributes.

pAgentMember

A pointer to a data member.

Reads a single item from the string, then advances *ppData to point at the next item. For numerical items only.

addPopSpecificAgentData

virtual int addPopSpecificAgentData(int iAgentIndex, char **ppData);
iAgentIndex

The agent’s index.

ppData

Pointer to a C-style string containing the values for agent attributes.

This method is called after the basic agent items have been read. Here, this method does nothing, but should be implemented by derived population classes to continue reading agent data from ppData.

createAgentAtIndex

virtual int createAgentAtIndex(int iAgentIndex, int iCellIndex);
iAgentIndex

The agent’s index.

iCellIndex

Cell in which to create agent.

In particular, the birth time is the current time step, and the gender is randomly chosen. The life state is set to LIFE_STATE_ALIVE.

reserveAgentSpace

virtual void setAgentBasic(int iAgentIndex, void *pBasic);
iAgentIndex

Index of the agent to modify.

pBasic

Pointer to an object of a derived agent struct.

Copies the basic items of pBasic to the agent at the specified index.

mergePop

virtual int mergePop(PopBase *pPop);
pPop

Pointer to a population object.

If the population’s class and species names match, the agents have the same type, and the population’s actions are all equal to this objects actions, then the populatiuon is merged to this.

Useful if the agents of the same type are injected at a later phase of the simulation.

getClassName

virtual const std::string getClassName();

Returns the class name.

getSpeciesName

virtual const std::string getSpeciesName();

Return the species name.

getNumAgentsArray

ulong *getNumAgentsArray();

Returns an array containing the number of agent in each cell.

getNumAgents

virtual ulong getNumAgents(int iCellIndex);
iCellIndex

Index of a cell.

Returns the number of agents in this cell.

getNumAgentsTotal

virtual inline ulong getNumAgentsTotal();

Return the total number of agents in the simulation (actually, the number of ACTIVE locations).

getNumAgentsEffective

virtual inline ulong getNumAgentsEffective();

Return the total number of agents in the simulation (minus the number of agents in the death list).

getNumAgentsMax

virtual ulong getNumAgentsMax();

Returns the maximum number of agents that can be held in the LayerBuf (without adding a new layer).

updateNumAgentsPerCell

virtual void updateNumAgentsPerCell();

Recount the agents in each cell.

updateTotal

virtual void updateTotal();

Update the total count of ACTIVE locations.

checkLists

virtual int checkLists();

Checks the validity of the linked lists. Returns a negative number on error. This check slows down execution time considerably. It is only used for debugging.

getFreeIndex

virtual int getFreeIndex();

Returns the index of an unused location.

getFirstAgentIndex

virtual int getFirstAgentIndex();

Returns the index of the first agent in the ACTIVE list.

getLastAgentIndex

virtual int getLastAgentIndex();

Returns the index of the last agent in the ACTIVE list.

getMoveList

std::vector<int>** getMoveList();

Returns the move lists. This is needed by actions who must read or manipulate the list of moving agents.

getWELL

virtual WELL512 **getWELL();

Returns the array of WELL random number generators.

getCG

virtual SCellGrid *getCG();

Returns a ponter to the SCellGrid.

randomize

virtual void randomize(int i);

Calculates i random numbers from each WELL.

flushDeadSpace

virtual int flushDeadSpace();

Calls the normal death procedure for all agents in the previous death list.

setParams

virtual int setParams(const std::string sParams);
sParams

A string specifying a parameter value.

Tries to interpret and set the specified parameter (as passed for the --pop-params option).

getAgentLifeState

virtual uint     getAgentLifeState(int iAgentIndex);

Returns the life state of the agent at index iAgentIndex.

getAgentCellIndex

virtual int      getAgentCellIndex(int iAgentIndex);

Returns the cell index of the agent at index iAgentIndex.

getAgentID

virtual idtype   getAgentID(int iAgentIndex);

Returns the ID of the agent at index iAgentIndex.

getAgentCellID

virtual gridtype getAgentCellID(int iAgentIndex);

Returns the ID of the cell of the agent at index iAgentIndex.

getAgentBirthTime

virtual float    getAgentBirthTime(int iAgentIndex);

Returns the birth time of the agent at index iAgentIndex.

getAgentGender

virtual uchar    getAgentGender(int iAgentIndex);

Returns the gender of the agent at index iAgentIndex (0: female, 1:male).

reserveAgentSpace

virtual void setAgentDataType();

Cerates and stores the HDF5 type for the agents.

Some Protected Members

LayerBuf<T> m_aAgents;

The array of agent structs.

LBController *m_pAgentController;

The controller for the agent array.

LayerBuf<T> m_aWriteCopy;

Auxiliary layerbuf for writing.

LBController *m_pWriteCopyController;

The controller for the auxiliary layerbuf.

SCellGrid   *m_pCG;

The cell grid for this simulation.

Prioritizer<T> m_prio;

Priority level info for the populations actions.

PopFinder *m_pPopFinder;

A container holding all ppopulations.

std::vector<int>** m_vBirthList;

List of registered births (consecutive triples of cell index, mother’s index, father’s index).

std::vector<int>** m_vDeathList;

A list of the agent indexes registered for death.

std::vector<int>** m_vMoveList;

A list of registered moves (consecutive triples of index of origin cell, agent index, index of target cell).

Some Protected Methods

recycleDeadSpaceNew

virtual int recycleDeadSpaceNew();

Fills as many locations of previously died agents as possible with the data of new born agents. This reduces the number of unparallelizable list operations.

moveAgent

virtual int moveAgent(int iCellIndexFrom, int iAgentIndex, int iCellIndexTo);
iCellIndexFrom

Index of origint cell.

iAgentIndex

Agent index.

iCellTo

Index of target cell.

This method performs the actual move of the agent by changing the agent’s m_iCellIndex member.

performMoves

virtual int performMoves();

Processes the registered moves in parallel. This is ok, because every move only affects one agent, no agent makes more than one move per step.

makePopSpecificMove

virtual int makePopSpecificMove(int iCellIndexFrom, int iAgentIndex, int iCellIndexTo);

Can be overridden to do specific actions just after an agent has moved.

// not used

performBirths

virtual int performBirths();

Calls the method makeOffspring() for all registered birth entries.

performBirths

virtual int performBirths(ulong iNumBirths, int *piBirthData);

Calls the method makeOffspringAtIndex() for all birth data entries in piBirthData.

makeOffspring

void makeOffspring(int iCellIndex, int iMotherIndex, int iFatherIndex);
iCellIndex

Location of birth.

iMotherIndex

Index of new agent’s mother.

iFatherIndex

Index of new agent’s father.

Creates a new agent in specified cell, then calls makePopSpecificOffspring() for population specific post-natal operations.

makeOffspringAtIndex

void makeOffspringAtIndex(int iAgentIndex, int iCellIndex, int iMotherIndex, int iFatherIndex);
iAgentIndex

Index of new Agent.

iCellIndex

Location of birth.

iMotherIndex

Index of new agent’s mother.

iFatherIndex

Index of new agent’s father.

Creates an agent with at specified index in the specified cell, then calls makePopSpecificOffspring() for population specific post-natal operations.

makePopSpecificOffspring

virtual int makePopSpecificOffspring(int iAgentIndex, int iMotherIndex, int iFatherIndex);
iAgentIndex

Index of new agent birth.

iMotherIndex

Index of new agent’s mother.

iFatherIndex

Index of new agent’s father.

This method can be overridden by derived populations to implement specific operations just after the birth of an agent.

performDeaths

virtual int performDeaths(ulong iNumDeaths, int *piDeathData);
iNumDeaths

Number of entries in the death list.

piDeathData

Pointer to the death list.

Calls makePopSpecificDeath() for each agent in the death list and moves their locations to the PASSIVE list.

makePopSpecificDeath

virtual int makePopSpecificDeath(int iAgentIndex);
iAgentIndex

Index of dead agent.

This method can be overridden by derived populations to implement specific operations just after the death of an agent.

agentRealSizeQDF

size_t agentRealSizeQDF() const {return sizeof(T);};

Returns the size of the agent structure.

createAgentDataTypeQDF

virtual hid_t createAgentDataTypeQDF();

Creates a HDF data type for the agent structure and returns a handle to it.

addPopSpecificAgentDataTypeQDF

virtual void addPopSpecificAgentDataTypeQDF(hid_t *hAgentDataType);
hAgentDataType

HDF5 handle for agent datatype to be modified

This method can be used to extend the HDF5 data type of the agent structure. It should be overriden by population classes whose agents have additional members.

writeAgentDataQDF

int writeAgentDataQDF(hid_t dataspace_id, hid_t dataset_id, hid_t hAgentType);
dataspace_id

HDF5 handle to data space into which to write agent data.

dataset_id

HDF5 handle to data set for the agent data.

hAgentType

HDF5 handle to data type of the agent structure.

Currently this method simply calls writeAgentDataQDFSafe().

writeAgentDataQDFSafe

int writeAgentDataQDFSafe(hid_t hDataSpace_id, hid_t hDataSet_id, hid_t hAgentType);
hDataSpace

HDF5 handle to data space into which to write agent data.

hDataSet

HDF5 handle to data set for the agent data.

hAgentType

HDF5 handle to data type of the agent structure.

This method writes the agent data compactly, but without modifying the LayerBuf. This is done by using a separate LBController with only one layer to which the data of each layer of the actual agent data is copied and written in turn. This ensures that a simulation with output runs identically to one without.

writeSpeciesDataQDF

int writeSpeciesDataQDF(hid_t hSpeciesGroup);
hSpeciesGroup

HDF5 handle to the group to write to.

Writes the attributes of SPopulation.

readAgentDataQDF

int readAgentDataQDF(hid_t hDataSpace, hid_t hDataSet, hid_t hAgentType);
hDataSpace

HDF5 handle to data space from which to read agent data.

hDataSet

HDF5 handle to data set for the agent data.

hAgentType

HDF5 handle to data type of the agent structure.

hDataSpace

readSpeciesDataQDF

int readSpeciesDataQDF(hid_t hSpeciesGroup);
hSpeciesGroup

HDF5 handle to the group to read from.

Reads the attributes of SPopulation.

writeStatArrsQDF

int writeStatArrsQDF(hid_t hSpeciesGroup);
hSpeciesGroup

HDF5 handle to the group to write to.

Can be overridden to write additional arrays into the species group.

WILL PROBABLY BE DELETED AS IT DUPLICATES writeAdditionalDataQDF().

readStatArrsQDF

int readStatArrsQDF(hid_t hSpeciesGroup);
hSpeciesGroup

HDF5 handle to the group to read from.

Can be overridden to read additional arrays from the species group.

WILL PROBABLY BE DELETED AS IT DUPLICATES readAdditionalDataQDF().

writeAdditionalDataQDF

virtual int writeAdditionalDataQDF(hid_t hSpeciesGroup);
hSpeciesGroup

HDF5 handle to the group to write to.

Can be overridden to write additional data to the species group.

readAdditionalDataQDF

virtual int readAdditionalDataQDF(hid_t hSpeciesGroup);
hSpeciesGroup

HDF5 handle to the group to read from.

Can be overridden to read additional data.