For most models this context hierarchy is convenient. However, it is possible to deviate from this standard (see configuring the context classes to use).
SesamGIM is component based, i.e. the initialisation process is divided in several tasks, and for each task there are components. The user chooses the component to use by setting the component object or a class object as particular initialiser parameter (depending on the kind of component, see below). SesamGIS then uses the object or instantiates the initialiser of this class and uses it for the specific initialisation step. Thus, it is possible to define custom initialisers and set their instance or class as parameter. In the latter case they need to be available on the class path.
Initialiser are responsible for the particular initialisation step whereas InitialiseServices always return an instance of a specific kind of class, e.g. agents. For example, an instance of GimAreaInitialiser reads shapefiles and calls a GimAreaInitialiseService to provide a concrete instance of GimAreaContext.
Let SesamGIM know about the root context of the RS model (the SesamGIM manager is then initialised automatically):
GManager.getMan().setRootContext(rootContext);
NOTE: This getMan() method may not be called before parameters are set up because it calls GManager#init() which initialises random number generators and uses random seed parameters!
The most convenient way is to use the GimInitialiser<AgentType> and to assign all initialiser and initialise service parameters directly to the parameters defined in SesamGIM (see below).
These initialisation components are used and may be defined:
There are initialise services for agents and each context layer. If the model wants to use a specific service implementation it needs to assign the particular service as a parameter. This is mandatory for the agent initialise service! If no services are defined for the contexts, default implementations are used.
Agents can be stored into DB including their milieu and GIS position using GAgentDbStoring, whereas agents is a collection of GimMilieuAgents and 99 is the ID that is associated with the data record:
GAgentDbStoring.storeAgents(agents, 99);
Of course, the procedure needs to be called after agent initialisation. It uses GSqlPa.TBLNAME_INIT_AGENTS as target table name. Furthermore, the column names need to correspond with the ones defined in DB and can be set using ParMa (see ). An SQL creation script can be found in ./config/test/sql/TestAgentStorageSQL.sql.
The according test class is de.cesr.sesamgim.testing.util.GAgentStoringTest.
Agent can be initialised from DB using the GDbAgentInitialiser:
PmParameterManager.setParameter(GInitialisersPa.INITIALISER_AGENTS, GDbAgentInitialiser.class);
The database should provide agent milieu and GIS positions. SesamGIM then assigned contexts according to GIS coordinates. The ID that is associated with the desired agent record needs to be specified in GBasicPa.INIT_PARAM_ID. Further parameters regard the structure of the table:
If the model does not consider GimMarketCellContexts the GMarketCellInitialiser should be set to null:
PmParameterManager.setParameterValue(GInitialisersPa.INITIALISER_MARKETCELL, null);
GGeoAreaContextAssigner.assignAgentsToAreaContexts(agents);
Since the GMarketCellInitialiser has a protected method generateSqlStatement(), one may create a custom subclass of GMarketCellInitialiser and override this method in order to easily use custom sources of the data. This is sometimes beneficial when the effort to compute the data is very high and one wants to use specific MySQL tables per simulated area.
Follow these steps to apply a custom initialiser:
log4j.logger.de.cesr.sesamgim.init.mc.GMarketCellInitialiser = DEBUG
CREATE TABLE <name> select <statement from step 1>
protected String generateSqlStatement(Context<Object> rootContext) { return "SELECT * FROM <your MYSQL table from step 2>" + " ORDER BY mz_id, num_persons, year, milieu_group_id"; }
GesamGIM uses its own instance of URandomService. Basically, it manages different random number generators:
By default, and when only a global random seed (RANDOM_SEED) is defined, these point to a single global random number generators (RND_STREAM). However, these streams can be fed by distinct random seeds:
To influence the random number generation of certain parts of SesamGIM change the according random number seed, e.g.:
PmParameterManager.setParameter(GRandomPa.RANDOM_SEED_INITIALISATION, new Integer(2));
Furthermore, it is possible to register custom random number generators for SesamGIM:
GManager.getURandomService().registerGenerator((String) PmParameterManager .getParameter(GRandomPa.RANDOM_STREAM), new MersenneTwister(3));
Alternatively, you may register your custom random number generator and adapt the stream name parameter accordingly (the last part is mandatory - otherwise you will replace more general generators). See the URaNuS manual and the next section for further information.
There is a kind of complex algorithm on what happens for the SesamGIM parts (creating contexts and agents, population updating, aggregation):
PmParameterManager.setParameter(GRandomPa.RANDOM_SEED, new Integer(1));
PmParameterManager.setParameter(GRandomPa.RANDOM_SEED_AGENT_INITIALISATION, new Integer(2));
GManager.getURandomService().registerGenerator((String) PmParameterManager .getParameter(GRandomPa.RANDOM_STREAM_AGENT_INITIALISATION), new MersenneTwister(3));
NOTE: To achieve independent random number streams for different parts it is sufficient to set the random seeds accordingly, even if they are set to the same value.
For further details, see URaNuS documentation and/or the source of GManager.init().
SesamGIM support the initialisation of Group context to manage agents as sub-contexts of GimMilieuContexts. In order to initialise group contexts you need to:
PmParameterManager.setParameter(GInitialisersPa.INITIALISER_GROUP, GGroupOrganiser.class)); PmParameterManager.setParameter(GInitialisersPa.INITIALISER_AGENTS, GGroupAreaAgentInitialiser.class);
The GGroupAreaAgentInitialiser or a sub-class as GimAgentInitialiser is required to set the GimGroupContext st the agents.
There is a random stream identifier GRandomPa.RANDOM_STREAM_GROUP_INITIALISATION that can be set to any available random stream and defaults to GRandomPa.RANDOM_STREAM_INITIALISATION.
Do not forget to reset the manager after the simulation (in case you do batch runs):
GManager.reset();
SesamGIM applies the Apache Log4J-Framework. To use it, copy ./config/log4j/log4j.properties to a place of your choice, adapt it to your needs and make it available in the classpath. See Apache Log4J for more information.
To test the resulting model setup, there are two features:
This tools creates an GraphML file that can be layout as hierarchy, e.g. in yED.
GContextUtils.printContextHierarchy(GManager.getMan().getRootContext(), new File("./output/contexts/ContextHierarchie.graphml"));
Use node attributes as labels in yed as follows:
You may output the contents of the GIS geography as shape files and control it in an GIS editor, e.g. QuantumGIS):
GShapefileService.writeShapeFile(GManager.getMan().getRootGeography(), "./output/gis/");
It is also possible to specify the classes of objects in the geography that shall be output by using the feature attribute:
List<String> features = Arrays.asList( "de.cesr.model.agents.Household", "de.cesr.model.environment.ContextEnvironment"); GShapefileService.writeShapeFile(GManager.getMan().getRootGeography(), "./output/gis/", features);
NOTE: The procedure calls all getter methods without parameters that return a simple data type including String. To prevent side effects you should ensure that getter methods of classes of objects in the geography are correctly implemented, i.e. do not cause any changes upon their call. Also consider super classes!
There is a QGIS project file ./config/qgis/TestOutputShapes.qgs. However, you need to run the JUnit test in de.cesr.sesamgim.testing.init.plz.GPlzInitialiserTest to produce required shape files.