Repast Simphony: Batch file to enable batch runs

In trying to do batch runs, I was following this listserv post.  It is a fantastic post!  However, the batch file has a typo.

The batch file should be:

@echo off
rem The version of Repast Simphony being used.
set VERSION=1.2.0
rem The installed path of Repast. Quotes may be necessary if there is a space character in the path.
set REPAST="C:\Program Files\RepastSimphony-1.2.0"
rem The installed path of Eclipse. Quotes may be necessary if there is a space character in the path.
set ECLIPSE="C:\Program Files\RepastSimphony-1.2.0\eclipse"
rem The plugins path of Eclipse.
set PLUGINS=%ECLIPSE%\plugins
rem The workspace containing the Repast model.
set WORKSPACE=%REPAST%\workspace
rem The name of the model. This might be case-sensitive. This is the name of your package. It should 
rem be the package at the top of all your .java files and match the "package" listed in your model.score 
rem file (when viewed as a text file).
set MODELNAME=myPackage
rem The folder of the model. This might be case-sensitive. This is the base folder of your project in 
rem the file system.
set MODELFOLDER=%WORKSPACE%\myProjectFolder
rem The file containing the batch parameters. For some additional information, see Repast documentation 
rem of batch parameters at http://repast.sourceforge.net/docs/reference/SIM/Batch%20Parameters.html and/or 
rem an example batch_params.xml file at http://www.pamelatoman.net/blog/2010/08/sample-batchparamsxml/.
set BATCHPARAMS=%MODELFOLDER%\batch\batch_params.xml

rem Execute in batch mode.
java -cp %PLUGINS%\repast.simphony.batch_%VERSION%\bin;%PLUGINS%\repast.simphony.runtime_%VERSION%\lib\*;
%PLUGINS%\repast.simphony.core_%VERSION%\lib\*;%PLUGINS%\repast.simphony.core_%VERSION%\bin;
%PLUGINS%\repast.simphony.bin_and_src_%VERSION%\*;%PLUGINS%\repast.simphony.score.runtime_%VERSION%\lib\*;
%PLUGINS%\repast.simphony.data_%VERSION%\lib\*;
%MODELFOLDER%\bin repast.simphony.batch.BatchMain -params %BATCHPARAMS% %MODELFOLDER%\%MODELNAME%.rs 

You can run this batch file from anywhere on the filesystem.

This came to light after fighting for significantly too much time with a RuntimeException that told me it “couldn’t find classes using supplied class loader”. It was telling me that it couldn’t find myPackage.ClassName on the very same path that had the compiled code! All the pointers toward this sort of error pointed to the model.score file — but model.score was not the problem here. The problem was that the model’s actual bin had not been added to the classpath.

For posterity, the exception I was getting was:

java.lang.RuntimeException: Couldn't find classes using supplied class loader: 
myPackage.ClassName on path: correct\path\to\project\bin
at repast.simphony.scenario.ScenarioLoader.getAgentClasses(ScenarioLoader.java:274)
at repast.simphony.scenario.ScenarioLoader.load(ScenarioLoader.java:160)
at repast.simphony.batch.BatchRunner.run(BatchRunner.java:87)
at repast.simphony.batch.BatchMain.run(BatchMain.java:119)
at repast.simphony.batch.BatchMain.main(BatchMain.java:141)
usage: repast.simphony.batch.BatchMain [options] target
Where target is the path to a scenario file or the fully qualified name of a class 
that implements repast.simphony.batch.BatchScenarioCreator.
-help            print this message
-interactive     specifies if the batch mode is interactive
-opt <file>      use optimizable parameter sweeper with given optimizing properties file
-params <file>   use given parameter sweep file 

Build a Repast installer that doesn’t share your source code

By default, a model installer built using Repast’s Build Installer functionality will also include your raw source code (not just the bytecode).  If you do not want your .java files to be bundled with the model installer, you can change this in the project’s installer/installation_components.xml file.  Remove or comment out these lines from that file (near the bottom):

<pack name="Sources" required="no">
<description>The model source code</description>
<file src="repast.simphony.bin_and_src_$REPAST_VERSION/temp/src" targetdir="$INSTALL_PATH/yourModelName"/>
</pack>

After you create the new installer and install the model, the directories of the standalone model should no longer contain your source code.  Those directories will only contain the .class files.  (Of course, it’s still possible for the user to decompile the .class files back into .java files, but at least removing the raw .java files sends the signal and requires some actual work to get the code on any unscrupulous users’ parts. Use an obfuscator to avoid decompilation if you’re worried.)

Repast uses IzPack to build the software installer for its models.  Inside your project’s /installer directory are the .xml and other files that IzPack uses.

Repast Simphony: FileNotFoundException upon saving model scenario

After creating new display items in the Repast runtime environment (a Data Set and a Chart) , I wanted to save the scenario so that Repast would remember to create these display items each time I ran the model.  (When you click the Save Button/diskette in the runtime environment, the display items currently in the Scenario Tree are saved and then will always automatically load with the model — it saves a lot of work in recreating displays.)

But each time I clicked the diskette to save the model, I got this file not found exception:

2010/07/28 15:27:59,640: Error while saving scenario
java.io.FileNotFoundException: C:\Program 
Files\RepastSimphony-1.2.0\workspace\yourModelName\yourModelName.rs\styles\.svn\all-wcprops (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.(Unknown Source)
at java.io.FileOutputStream.(Unknown Source)
at repast.simphony.util.FileUtils.copyDirs(FileUtils.java:88)
at repast.simphony.util.FileUtils.copyDirs(FileUtils.java:81)
at repast.simphony.ui.RSApplication.doSave(RSApplication.java:420)
at repast.simphony.ui.RSApplication.save(RSApplication.java:376)
at repast.simphony.ui.action.SaveModel.actionPerformed(SaveModel.java:17)
(and so on)

And then suddenly my /yourModelName.rs/ folder (the one containing model.score) would be suddenly, horribly, inexplicably gone — which meant that running the model again was impossible until I reinstated it.  (Repast was renaming the directory to /yourModelName.rs.bak/ and renaming any existing .bak files to .bak0, .bak1, and so on.)

At first I thought that the problem was a case of Repast moving /yourModelName.rs/ in expectation of generating a new version from my current runtime settings in its place, and then trying to copy previous data from the old filename (that no longer existed) rather than the renamed .bak version, but this is actually not what was happening.  The FileNotFoundException wasn’t actually indicating a missing file (although by the time I got the exception, that file was indeed missing on that path)… it was indicating an unwriteable file.

In fact, for me, this was a Subversion-related problem.  I was able to fix it by unsetting the read-only attributes on my .svn folders and their files and subfolders (both /yourModelName.rs/.svn and /yourModelName.rs/styles/.svn).  I unchecked all the read-only checkboxes in the properties of those files.  And then, magically, I could save the model scenario.  Repast generated scenario.xml without any trouble once the .svn directory properties were changed.

I am unsure why this happened.  Repast hasn’t complained about the other .svn directories in the project (which are all still marked as read-only).  Other team members have not had this issue.  I was able to successfully save scenarios earlier this year.  But in any event, lesson learned and solution found.

Exposing data file paths in Repast

How do you let the user specify the location of files in Repast?

To expose any variables to the user in Repast, the variables need to be specified as model parameters (not as, say, command line arguments).  When the model is set up that way, after the Repast modeling environment is launched but before the model itself begins to run, the user can change the paths to the data files for that particular run within the Parameters tab.

In practice, this means you first define a new set of attributes in the model.score file (one for each file).  Set SType as STRING.  Set the default path.  Then, to retrieve the user-provided values during a model run, you use the parameter access syntax (as used without previous explanation in the Repast Predator-Prey tutorial code):

This approach to letting the user select data input files is not nearly as robust as it should/could be.  It would be nice to launch a file chooser, for instance.  Additionally, although Repast lists “File” on the drop-down for SType, I haven’t been able to run anything with that type selected.  The internet has been massively unhelpful in explaining what Repast expects when you set SType to File, and now that the basic functionality needed is in the model and the to-do list has continued to grow, I just don’t feel up to reading the source code or bothering the Repast listserv on this particular issue…. But I am curious about the purpose of File as an SType.


Notes on Standalone Repast Runtime Models

This topic comes up because I recently built a runtime version of the Repast model I’m working on, according to the Build Installer instructions. As I quickly found out, the directory structure gets shuffled around during the build. As a result, as soon as the model is run from that new standalone installation, any hard-coded paths to files generate a NullPointerException. (And if those paths are fixed to work in the runtime environment, then the new paths will not continue to work in the development environment.) The easiest development-period fix was to allow the user to specify the location of all files — including GIS files so fundamental to the way the model operates that I hadn’t previously thought about exposing them.

Two more notes related to running the model as a standalone runtime version:

  • In the parameter setting screen, the current directory . is INSTALLNAME/yourModelName.  If you intend to keep the input data files there, congratulations!  If not, you’ll need to update the path accordingly.
  • Data files in the project’s root directory were ignored during Build Installer for me.  When I moved the data files to a /data folder parallel to /src, they were included as part of the installer.  The data files originally stored in /data installed into the INSTALLNAME/yourModelName/bin/data directory.

Critical discourse analysis: Skulls in a Smithsonian exhibit

My current client is extremely interested in how “us vs. them” dynamics manifest in language. Most manifestations are subtle, but I’ve spent so much time in that headspace that I’m now getting insight flashes from Critical Discourse Analysis everywhere I look. I gotta say, actually seeing these power dynamics is like having my eyes opened to something I expect I’d have been happier not seeing. (It all reminds me of the Matrix. Or maybe Amazing Grace would be a better analogy. Something between the two, anyway.)

Here’s an example that I can’t stop thinking about. I visited the “Written in Bone” exhibit at the Smithsonian Museum of Natural History. One of the exhibits was a set of 3 skulls – a Native American skull (left), a European skull (center), and an African skull (right). I think the message they were aiming for was “everyone’s background is written in their skull” – a fitting message for an exhibit about skeletal analysis, forensics, and what bones can teach us about history.

Fuzzy shot of three skulls in a museum display

I took a poorly lit and poorly focused shot of the "ethnic skulls" display.

The display text is:

  • Left: Individuals with Native American ancestry have proportionately wider faces and shorter, broader cranial vaults.
  • Center: Individuals with European ancestry tend to have straight facial profiles and narrower faces with projecting, sharply angled nasal bones.
  • Right: Individuals with sub-Saharan African ancestry generally show greater facial projection in the area of the mouth, wider distance between the eyes, and a wider nasal cavity.

Interesting facts! But the language choices stopped me cold. The text gives the Native Americans and sub-Saharan Africans a series of comparative “-er” adjectives. Every time a “distinctive feature” is mentioned, it is as a comparative (to something else that goes unnamed). But the European language is different. Three of the four adjectives are pure, non-comparative words. To boot, the visual design also echoes “European-as-normative” in its use of the (literally whiter!) European skull as the centerpiece.

Likely the visual design was deliberate – museum designers certainly are well-versed in visual metaphors – but I would be surprised if the author really intended to say, “I am white, and I am designing this exhibit for white people”. It might be true, but that message is so blatantly racial that it’s hard to believe anyone intends to give it in 2010.

It’s hard to unsee the constant unintended us-vs.-them signalling baked into human communication once you start seeing it.