====== Parameter Manager ====== This tutorial will go through how to get started with parameter managers. It will start with an overly simple project to highlight some key features, then, apply the same parameter management to a more advanced project. ===== Project description ===== The first project is a simple "newRGG" type project. It will be composed of shoots (cylinders) and buds (spheres). The single growth rule replace a bud by a shoot and two buds. We consider 2 types of bud that will make the growth slightly different: a green one, and a blue one. They both extend the same base bud module. We first declare the three type of modules that will represent the possible type of "bud". module BaseBud(super.radius) extends Sphere { int age = 0; void grow(){ switch(aging){ case 0: age+=1; break; case 1: age = (age>1)? age*age : (age>0)? 2 : 1; break; default: } } } module GBud(super.radius) extends BaseBud.(setShader(GREEN)) { void grow(){ super.grow(); radius *= 0.8; } } module BBud(super.radius) extends BaseBud.(setShader(BLUE)) { void grow(){ super.grow(); radius *= 0.6; } } Then we define some variables that represent the configuration of the project: * aging : the type of aging 0 or 1, it trigger the method declared in BaseBud * ageLimit : the threshold after which a bud cannot be replaced anymore (I know that's not how plant works but it is an example - could be any type of variable) * budType : 0 or 1 for green of blue bud * initialLength : the initial length of the shoot. public global int aging = 0; public global int ageLimit = 10; public global int budType = 0; public global float initialLength = 0.8; Then, we can declare a Bud factory, i.e. a method that produce the type of bud based on the ''budType'': BaseBud pBud(float len) { switch (budType) { case 0: return new GBud(len); case 1: return new BBud(len); default: return null; } } Lastly, the initialization and growth rule: protected void init () [ Axiom ==> pBud(initialLength); ] public void run () [ b:BaseBud(x), (!tooOld(b)) ==> F(x) [RU(30) RH(90) pBud(b[radius]).($[age]=b[age], grow())] [RU(-30) RH(90) pBud(b[radius]).($[age]=b[age], grow())]; ] boolean tooOld(BaseBud n){ return n[age]>ageLimit ; } The given model can be run until the ''ageLimit'' threshold is met. Depending on the value of each of the four presented variables, the resulting "tree" is different. ===== Parameters for GUI ===== We can first tag these fours variables as parameters to change them from the GUI editor. Replace their previous declaration with: @IsParameter @Choice({"Linear", "Exponential"}) public global int aging = 0; @IsParameter public global int ageLimit = 10; @IsParameter @Choice({"Green bud", "Blue bud"}) public global int budType = 0; @Range(min=0, max=1) @IsParameter public global float initialLength = 0.8; Now open the GUI editor by clicking on the parameter manager button: {{:01_user_documentation:03_interacting_with_groimp:08_parameter:05_parameter_manager:07_edit:pm_gui_btn.png?400|}} It will open the editor: {{:02_new_tutorials:pm_gui_example.png?400|}} ===== Check parameter "impact" ===== In order to simulate how these parameters could impact the resulting tree (not only from a 3d view perspective) we can compute a simple descriptor: the total volume of the buds with the method: public void compute_vol() { double s = sum( (*Sphere*).getVolume() ); println("Total volume of buds: " + s); } public void complete(){ for (applyUntilFinished()){ run(); } compute_vol(); } ===== Save parameters in file ===== Let's save the current set of parameter values in a file. In the parameter manager editor click on "save parameters". It will automatically create a parameter file and store the parameter in. ===== Command line & headless ===== Now we can also set up the project to be run-able in headless and modify parameters from outside of GroIMP, with either: * Command lines args: to give parameter value, or a parameter file to use * Modify the parameter file in the project Add the following to setup the headless to run the ''complete'' method from above and to load the parameter's value from the file: protected void startup() { super.startup(); if (de.grogra.pf.boot.Main.getProperty("headless") != null) { runLater(null); } } protected void run(Object info) { loadPMs(); complete(); System.exit(0); } Now run the project in headless with: java -jar core.jar --headless Model.gsz This will print in the terminal the output value of ''compute_vol''. E.g. ''Total volume of buds: 2.78392774842903 '' ==== Command line arg ==== Let's change some parameter value for the run: java -jar core.jar -PModel.ageLimit=15 -PModel.aging=1 -PModel.initialLength=1 -PModel.budType=1 --headless Model.gsz This should display in the terminal: ''Total volume of buds: 0.07469535004252173''. ==== Change the parameter file ==== It is also possible to simply change the content of the parameter file by simply opening the file and changing its content. The file is called ''parameter_files/default-parameter-manager.parameters''. By setting its content to: Model.budType=0 Model.ageLimit=7 Model.initialLength=0.5 Model.aging=0 And running in headless again: ''java -jar core.jar --headless Model.gsz'' I get the value: ''Total volume of buds: 2.592734549068271'' ====== QSM Project ====== Now let's see how these parameters can be fit into a bigger project, the [[:todo|QSM project example]]