User Tools

Site Tools


tutorials:interfaces:tour

This is an old revision of the document!


A tour through GroIMP interfaces

The model

To highlight the flow of simulations in the different interfaces we use a simple model of a plant that can grow apically and with a second function split one bud into two of half the strength. The idea is to see how different indicators change over 10 growth steps depending on the time the buds split.

model.rgg
module A(float len) extends Sphere(0.1)
{
	{setShader(GREEN);}
}
int step=0;
module Leaf(float l,float w) extends Parallelogram(l,w){
{setShader(GREEN);}
 
public float getArea(){
	return l*w;
	}
}
protected void init ()
[
	{
	 step=0;
         dataset("data").clear();
	 chart(dataset("data"),XY_PLOT);
	}
	Axiom ==> A(1);
]
public void grow ()
[
	A(x) ==> F(x) [[M(-x/2)[for(int i=0; i<6; i++)(RH(60)[RL(70)Leaf(1,0.2)])]]]RH(137)A(x*0.9);
	Leaf(l,w) ==>Leaf(l*1.1,w); 
	{
	dataset("data").addRow()
	 .set(0,step)
	 .set(1,count((*F*)))
	 .set(2,sum((*F*)[length]))
	 .set(3,mean((*F*)[length]))
	 .set(4,count((*Leaf*)))
	 .set(5,sum((*Leaf*).getArea()))
	 .set(6,mean((*Leaf*).getArea()));
	step++;
	}
]
public void split()[
	A(x) ==> [RL(30) A(x/2)][RL(-30) A(x/2)];
]

GUI

To use this model in the default interface (GUI) we can just press the grow button 10 times and trigger the split in between.

In order to make this a bit more elegant and easier to use we can also create a new function:

public void test(){
 reset(); //go back to init and clean the dataset
 for(apply(5)){
  grow();  
 }
 for(apply(1)){
  split();
 }
 for(apply(5)){
  grow();
 }
}

Or even with a slider:

public @Editable @Range(min=0, max=9)  int splitPoint=5;
public void test(){
 reset();
 for(apply(splitPoint)){
  grow(); 
 }
 for(apply(1)){
  split();
 }
 for(apply(10-splitPoint)){
  grow();
 }
}

Headless

Now that we have a function that only requires us to press one button to get all steps, we are already closer to run it completely automatically.

The simplistic way to do so is using the headless mode. In this mode GroIMP starts executes a model or a command and closes again after it was done. This way we can execute our model with only one system call. For that to work we have to take care of three things, first that GroIMP knows what to do with the model once its opened, then that the model closes it self at the end and finally that we can get the data out of it.

startup

To make GroIMP do something at headless starting we have to overwrite the startup function of our model. The startup function is executed every time the model is started (also in the GUI!).

protected void startup(){
 super.startup(); //this starts the default startup function which is needed to make the model work
 //make sure what happens next only happens in headless 
 if (de.grogra.pf.boot.Main.getProperty("headless") != null){
  runLater(null);
 }
}

To make sure that all components are properly loaded before we start our simulation we do not directly push our model commands but we call runLater() which tells GroIMP that as soon as everything is ready it should execute the function run(Object info).

run(Object info)

In this run function we must describe everything that is suppose to happen in the simulation, including closing the software.

public void run(Object info){
 test();// run our chain of functions
 System.exit(0); //close GroIMP
}

We could now run this with java -Xverify:none -jar core.jar –headless PATH/TO/THE/MODEL.gsz and we would see: Nothing :-(

Even though GroIMP ran the simulation to completion we did not define any output for our data. There are several ways to do this using java, but for this tutorial we are going with one of the simplest. We are exporting the dataset we anyway already created to a csv file in and save this in the same directory as the project.

public void run(Object info){
 test();// run our chain of functions 
 java.io.FileWriter fw = new java.io.FileWriter(getWD()+"data.csv"); //create a java file writer for a file called data.csv in the working directory(where the project is stored)
 dataset("data").export(fw,","); // export our dataset data with comma as seperator
 fw.close(); // close the file writer 
 System.exit(0); //close GroIMP
}

Parameters

GroIMP gives us the ability to forward custom parameter form command line, in general these are model independent but in headless this is no issue since we have to start GroIMP for every model any way.

The usage of this is quite simple, every value we add with -X<key>=value will be added to Main.getProperty(<key>). So in our case: if we put -Xsp=6 to the command line we can use:

public void run(Object info){
 splitPoint = Integer.valueOf (Main.getProperty("sp"));
 test();
 java.io.FileWriter fw = new java.io.FileWriter(getWD()+"data.csv"); 
 dataset("data").export(fw);
 fw.close();
 System.exit(0);
}

This setup would now allow us to integrate the model into pipelines, e.g. an R script:

splitPoint <-5
setwd("\path\to\projectFolder")
System(paste("C:\Path\to\your\java -jar core.jar -xp=",splitPoint," --headless Project.gsz"))
data <- read.csv("data.csv", header = TRUE, sep = ",")

HTTP

groIMP.HTTP <- function(path, param, url="http://localhost:58080"){
  parameters=""
  for (name in names(param)) {  
    parameters <-paste(parameters,"&",name,"=",param[name],sep="")
  }
  req <- httr::GET(paste(url,"/open?",path,parameters,sep=""))
  return(httr::content(req,"text"))
  }


groIMP.CSV <- function(path, param, url="http://localhost:58080"){
  data <- groIMP.HTTP(path,param,url)
  return(read.table(text = data, sep =",", header = TRUE, stringsAsFactors = FALSE))  
}

df <- groIMP.CSV("Dokumente/ssc25/talks/GroLink/exampels/http/cut_grow.gsz",list(pre=1, initialLength=10.3))

cut_grow.gsz

API

tutorials/interfaces/tour.1749022110.txt.gz · Last modified: 2025/06/04 09:28 by tim2