diff --git a/README.md b/README.md index 0a6117b4df023dff7be5847509c115299c1d414a..b6b3cfef24094de2a201cfd4a48c3f42dc349b15 100644 --- a/README.md +++ b/README.md @@ -3,72 +3,158 @@ **Authors: Christophe Godin, Inria, 2021** **Licence: Open source LGPL** +## Getting started + +### Install conda package + +You can install the conda package with: + +```shell +conda install lpy_tools +``` + +### Install from sources + +Create the conda environment and install the dependencies: + +```shell +conda create -f conda/env.yaml +``` + +To install dependencies in an existing environment, first activate it then: + +```shell +conda env update -f conda/env.yaml +``` + +### Build conda package + +You will need the `conda-build` package to build packages. +Install it in the `base` environment with: +```shell +conda install conda-build +``` + +To build the `lpy_tools` conda packages, in the `base` environment from the root folder, run: + +```shell +conda build -c conda-forge -c fredboudon conda/. +# Convert linux package for OSX-64: +conda convert -p osx-64 ~/miniconda3/conda-bld/linux-64/lpy_tools* --output-dir ~/miniconda3/conda-bld/osx-64/ +# Convert linux package for WIN-64: +conda convert -p win-64 ~/miniconda3/conda-bld/linux-64/lpy_tools* --output-dir ~/miniconda3/conda-bld/win-64/ +``` + +> :warning: This should be done from the `base` environment! + + +You will need the `conda-verify` & `anaconda-client` package to upload packages. +Install them in the `base` environment with: +```shell +conda conda-verify anaconda-client +``` + +After a successful build, to upload the packages, run: +```shell +anaconda login # do this once +anaconda upload --user mosaic --label main ~/miniconda3/conda-bld/linux-64/lpy_tools*.tar.bz2 +anaconda upload --user mosaic --label main ~/miniconda3/conda-bld/osx-64/lpy_tools*.tar.bz2 +anaconda upload --user mosaic --label main ~/miniconda3/conda-bld/win-64/lpy_tools*.tar.bz2 +``` + +Official documentation on how to upload packages [here](https://docs.anaconda.com/anaconda-repository/user-guide/tasks/pkgs/upload-pkg/). + + +### Conda useful commands + +#### Purge built packages: +```bash +conda build purge +``` + +#### Clean cache & unused packages: +```bash +conda clean --all +``` + + + +## Usage + The module makes it possible to call a L-system from the user API and to plot figures corresponding to simulations obtained by varying some model parameters. Two parameters at most can be varied to create the figure. -The lscene_snapshot library offers 2 main functions: -- simulate_and_shoot(model_filename, variables, suffix, cam_settings = camdict) -- grid_simulate_and_shoot(simpoints, model_filename, free_variable_list, fixed_variables_dict, cam_settings = cam_setting_fun1, short_names = variable_short_names) +The `lscene_snapshot` library offers 2 main functions: +- `simulate_and_shoot(model_filename, variables, suffix, cam_settings = camdict)` +- `grid_simulate_and_shoot(simpoints, model_filename, free_variable_list, fixed_variables_dict, cam_settings = cam_setting_fun1, short_names = variable_short_names)` -## Declaration of variables in the L-system model +### Declaration of variables in the L-system model The L-system must export parameters that need to be controlled from the outside of the L-system file. Asssume for instance that parameters `diam, length, age, name` and `simtime` need to be exported. This is done by declaring in the L-system file: - extern(diam = 2.3) - extern(length = 10.6) - extern(age = 20) - extern(name = 'orchid') - extern(simtime = 30) - param1 = 12.4 - param2 = True` - +``` +extern(diam = 2.3) +extern(length = 10.6) +extern(age = 20) +extern(name = 'orchid') +extern(simtime = 30) +param1 = 12.4 +param2 = True` +``` This means that only the variables `diam, length, age, name` and `simtime` can be changed by resetting them from the outside. Note that `param1` and `param2` cannot by changed from the outside of the L-system file (as they are not declared as `extern`). -## Defining variables to call function `simulate_and_shoot()` of the library +### Defining variables to call function `simulate_and_shoot()` of the library A dictionary of variables chosen among the extern variable of the model system can be defined. Example: - vardict = {'diam':0.1, name:'fern', 'simtime': 38} +```python +vardict = {'diam':0.1, name:'fern', 'simtime': 38} +``` and then call the `simulate_and_shoot()` function. - - simulate_and_shoot(model_filename, variables, suffix, cam_settings = camdict) +```python +simulate_and_shoot(model_filename, variables, suffix, cam_settings = camdict) +``` suffix is an array of strings to store the computed images. TODO: explain ... -## Defining variables to call function `grid_simulate_and_shoot()` of the library +### Defining variables to call function `grid_simulate_and_shoot()` of the library It is possible to select a pair of variables for which we want to create a figure by giving them different values. `(x1,y1)(x2,y2), ... (xn,yn)` For this, we first need to identify the pair of variables selected variable that we want to browse. This is done by defining the list `free_variable_list` free_variable_list containing the list of free variables to vary for launching the set of simulations: - - free_variable_list = ['diam','age'] +```python +free_variable_list = ['diam','age'] +``` The first variable `diam` is considered as the x variable, while the second variable is the y variable (x will vary on the horizontal axis of the figure and y on the vertical axis. Other extern variables of the model can be given a constant value different from that they have in the L-system file by listing them in the list fixed_variables_dict, and then redefining their value: - - fixed_variables_dict = {'length', 'name'} +```python +fixed_variables_dict = {'length', 'name'} +``` All the other extern variables will keep constant and defined with the value given in the L-system file. Finally, to define the list of pairs of values of the free variables x and y (here `diam` and `age`), a dictionary is defined as follaws: - - simpoints = { y1:[x1,x2,..,xk], y2:[x1',x2',..,xl'], y3: ... , yn:[x1'',x2'', ..,xl''] } +```python +simpoints = { y1:[x1,x2,..,xk], y2:[x1',x2',..,xl'], y3: ... , yn:[x1'',x2'', ..,xl''] } +``` `simpoints` defines for each value of y a list of values of x for which a pair (x,y) must be computed by the simulation. In our example e.g.: - - simpoints = { 10:[1,2,3,4], 20:[1,2,3,4], 30.0:[1,2,5] } +```python +simpoints = { 10:[1,2,3,4], 20:[1,2,3,4], 30.0:[1,2,5] } +``` Meaning that (diam,age) values `(1,10), (2,10),(3,10),(4,10),(1,20),(2,20),(3,20),...,(5,30)` will be used to launch 11 simulations. Note that the y-arrays need not be of the same size nor have the same values. @@ -77,90 +163,97 @@ Note that the y-arrays need not be of the same size nor have the same values. The dictionary variable_short_names can be set to give a short name to each variable (extern or intern) that will be used to the label the small images. Only names in this list will be used to construct small image labels: - - variable_short_names = {'diam':'D', 'length': 'L'} +```python +variable_short_names = {'diam':'D', 'length': 'L'} +``` ### Setting camera attributes Camera attributes can be set prior to calling the simulation and shooting. Here are the attributes that can be defined with exmaple values: - - target_point = None # looks a bit above z = 0. Value is a 3-uple (x,y,z) - zoomcoef = 1. # increase to zoom out - camdist = 1. # increase to widen the observation window - elevation = 30 # elevation of the camera sight (in degrees) - azimuth = 0. # Azimuth of the camera - bb = None # Bounding box - width = 400 # Window size in pixels - height = 400 # Window size in pixels - aspectratio = 1.0 # contraction of X and Y direction defined by Height/Width - znear = 0.1 # defines the plane on which the scene is projected as the distance between camera and object that should not intersect visualized objects - zfar = 200 # Same thing for the farthest plane in the camera. Only objects between these two planes can be seen - lightpos = (0, 0, 10) # light characteristics - ambiant = (255, 255, 255) - diffuse = (0, 0, 0) - specular = (0, 0, 0)) +``` +target_point = None # looks a bit above z = 0. Value is a 3-uple (x,y,z) +zoomcoef = 1. # increase to zoom out +camdist = 1. # increase to widen the observation window +elevation = 30 # elevation of the camera sight (in degrees) +azimuth = 0. # Azimuth of the camera +bb = None # Bounding box +width = 400 # Window size in pixels +height = 400 # Window size in pixels +aspectratio = 1.0 # contraction of X and Y direction defined by Height/Width +znear = 0.1 # defines the plane on which the scene is projected as the distance between camera and object that should not intersect visualized objects +zfar = 200 # Same thing for the farthest plane in the camera. Only objects between these two planes can be seen +lightpos = (0, 0, 10) # light characteristics +ambiant = (255, 255, 255) +diffuse = (0, 0, 0) +specular = (0, 0, 0)) +``` Then all these values can be assembled in a dictionary that will be passed to the simulation and shooting function: - - camdict = {'camdist':camdist, 'zoomcoef':zoomcoef, 'bb':None, 'target_point':target_point} +```python +camdict = {'camdist':camdist, 'zoomcoef':zoomcoef, 'bb':None, 'target_point':target_point} +``` This camdict can be read directly from a LPy camera file using - - camdict = read_camera('my_camera.txt') +```python +camdict = read_camera('my_camera.txt') +``` Alternatively, if the camera parameters depend on the values of the free variables, on can define a function of the two free variables, that will return a dictionary corresponding to each pair of free variables values: - - def cam_setting_fun1(x,y): - ''' - Function that defines the camera setting values for each pair of parameter values (x,y) - ''' - t = target_point - z = zoomcoef - c = camdist - - return {'camdist':c, 'zoomcoef':z, 'bb':None, 'target_point':t, 'elevation':0.0} - +```python +def cam_setting_fun1(x,y): + """ + Function that defines the camera setting values for each pair of parameter values (x,y) + """ + t = target_point + z = zoomcoef + c = camdist + + return {'camdist':c, 'zoomcoef':z, 'bb':None, 'target_point':t, 'elevation':0.0} +``` ### Launching the simulation - shell> ipython --gui=qt make_snapshots.py - +```shell +ipython --gui=qt make_snapshots.py +``` or within ipython: - - ipython> %gui qt # to make sure that qt will be used for interpreting the event loop of PlantGL viewer - ipython> %run make_snapshots.py - +``` +ipython> %gui qt # to make sure that qt will be used for interpreting the event loop of PlantGL viewer +ipython> %run make_snapshots.py +``` ### Example of use - - from openalea.plantgl.all import Vector3 - from openalea import lpy - from .lscene_snapshots import simulate_and_shoot, grid_simulate_and_shoot, plot_images, build_suffix - - model_filename = 'model.lpy' - - ########################################### - # Define the simulations parameters - ########################################### - - free_variable_list = ['diam','age'] - fixed_variables_dict = {'length', 'name'} - simpoints = { 10:[1,2,3,4], 20:[1,2,3,4], 30.0:[1,2,5] } # {age:[list of diams], ...} - - # Definition of shortnames for variables (used for generating small image names) - variable_short_names = = {'diam':'D', 'length': 'L'} - - ########################################### - # Define the camera parameters - ########################################### - - target_point = Vector3(0,0,30.) # looks a bit above z = 0 - zoomcoef = 1 # increase to zoom out - camdist = 150. # increase to widen the observation window - camdict = {'camdist':camdist, 'zoomcoef':zoomcoef, 'bb':None, 'target_point':target_point} - - grid_simulate_and_shoot(simpoints, - model_filename, - free_variable_list, - fixed_variables_dict, - cam_settings = cam_dict, - short_names = variable_short_names) +```python +from openalea.plantgl.all import Vector3 +from openalea import lpy +from .lscene_snapshots import simulate_and_shoot, grid_simulate_and_shoot, plot_images, build_suffix + +model_filename = 'model.lpy' + +########################################### +# Define the simulations parameters +########################################### + +free_variable_list = ['diam','age'] +fixed_variables_dict = {'length', 'name'} +simpoints = { 10:[1,2,3,4], 20:[1,2,3,4], 30.0:[1,2,5] } # {age:[list of diams], ...} + +# Definition of shortnames for variables (used for generating small image names) +variable_short_names = {'diam':'D', 'length': 'L'} + +########################################### +# Define the camera parameters +########################################### + +target_point = Vector3(0,0,30.) # looks a bit above z = 0 +zoomcoef = 1 # increase to zoom out +camdist = 150. # increase to widen the observation window +camdict = {'camdist':camdist, 'zoomcoef':zoomcoef, 'bb':None, 'target_point':target_point} + +grid_simulate_and_shoot(simpoints, + model_filename, + free_variable_list, + fixed_variables_dict, + cam_settings = cam_dict, + short_names = variable_short_names) + +```