cacatoo
Version:
Building, exploring, and sharing spatially structured models
242 lines (198 loc) • 17.1 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cacatoo manual</title><link rel="icon" type="image/png" href="images/favicon.png" />
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/menu.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
<link href='https://fonts.googleapis.com/icon?family=Material+Icons' rel='stylesheet'>
<script src="scripts/jquery.js"></script>
<script src="scripts/cacatoo.js"></script> <!-- Include cacatoo library (compiled with rollup) -->
<script src="scripts/all.js"></script> <!-- Include other libraries (concattenated in 1 file) -->
</head>
<body>
<!-- --------------------- START MENU. Couldnt get it to load dynamically, so this needs to be replaced in every HTML file upon changing --------------------- -->
<header class="header" id="btnNav"><buton class="header__button" id="btnNav" type="button"><i class="material-icons">menu</i></buton></header>
<nav class="nav"><div class="nav__links">
<a href="#" class="nav__head"><i id="btnNavclose" class="material-icons" style="cursor:pointer"> menu </i> Cacatoo </a>
<a href="index.html" id="nav__link" class="nav__link">Home</a>
<a href="https://github.com/bramvandijk88/cacatoo" id="nav__link" target="_blank" class="nav__link"> Source code (Github)</a>
<!-- <a href="https://replit.com/@bramvandijk88/Cacatoo-IBMs-with-examples" id="nav__link" target="_blank" class="nav__link"> Replit </a> -->
<a href="#" class="nav__head"><i class="material-icons"> play_circle_outline </i> Examples</a>
<a href="example_predator_prey.html" id="nav__link" class="nav__link"> Predator prey</a>
<a href="example_colony_growth.html" id="nav__link" class="nav__link"> Colony growth</a>
<a href="example_pheromones.html" id="nav__link" class="nav__link"> Ant pheromones</a>
<a href="example_aapjes.html" id="nav__link" class="nav__link"> Aapjes (monkeys)</a>
<a href="example_mutational_jackpot.html" id="nav__link" class="nav__link"> Mutational jackpot</a>
<a href="example_starlings.html" id="nav__link" class="nav__link"> Starlings</a> <a href="example_cooperation.html" id="nav__link" class="nav__link"> Cooperation</a>
<a href="example_TEs.html" id="nav__link" class="nav__link"> Transposon evolution</a>
<a href="examples_jsfiddle.html" id="nav__link" class="nav__link"> More examples (JSFiddle)</a>
<a href="#" class="nav__head"><i class="material-icons"> grid_on </i> How to Cacatoo </a>
<a href="overview.html" class="nav__link"> Tutorials (Blog style)</a>
<a href="list_of_options.html" class="nav__link"> All configuration options</a>
<a href="populating_the_simulation.html" class="nav__link"> Populating a simulation</a> <a href="display_and_colours.html" class="nav__link"> Display, colours, and UI</a>
<a href="neighbourhood_retrieval.html" class="nav__link"> Neighbourhood retrieval</a>
<a href="random_numbers.html" class="nav__link"> Using random numbers </a>
<a href="grid_events.html" class="nav__link"> Grid events</a>
<a href="working_with_odes.html" class="nav__link"> Working with ODEs</a>
<a href="jsdocs/index.html" id="nav__headlink" target="_blank" class="nav__headlink"><i class="material-icons">data_object </i> Full JS-Docs</a>
</div><div class="nav__overlay"></div></nav>
<script>
document.addEventListener("DOMContentLoaded", () => {
const nav = document.querySelector(".nav");
document.querySelector("#btnNav").addEventListener("click", () => {
nav.classList.add("nav--open");
});
document.querySelector(".nav__overlay").addEventListener("click", () => {
nav.classList.remove("nav--open");
});
document.querySelector("#btnNavclose").addEventListener("click", () => {
nav.classList.remove("nav--open");
});
var all_links = document.getElementsByClassName("nav__link");
var hide_menu = function() {
nav.classList.remove("nav--open");
};
for (var i = 0; i < all_links.length; i++) {
all_links[i].addEventListener('click', hide_menu, false);
}
});
</script>
<!-- --------------------- END MENU --------------------- -->
<a id="top"></a>
<div id="main">
<h1 class="page-title"><a href="https://github.com/bramvandijk88/cacatoo"><img src="images/elephant_cacatoo_small.png"></a> <b>Cacatoo overview </b> </img></h1>
<center><h4> <a href="first_project.html">Next tutorial →</a></h4></center>
Cacatoo is a javascript-library that simulates discrete individuals, and how they interact, on a grid. Individual-based models are a powerful method to
explore intractable biological systems and therewith generate new insights or hypotheses. Here, I provide three blog style tutorials to get you started. <br><br>
In this tutorial, I will briefly explain:
<ol>
<li> <a href="#1">Why I made Cacatoo</a> </li>
<ul><li><a href="#1.1">Why grid-based models?</a></li></ul>
<ul><li><a href="#1.2">A more user-friendly CASH</a></li></ul>
<ul><li><a href="#1.3">The new and improved Javascript</a></li></ul>
<li> <a href="#2">Getting started with Cacatoo</a> </li>
<ul><li><a href="#2.1">Explore Cacatoo online (replit)</a></li></ul>
<ul><li><a href="#2.2">Get it on Github</a></li></ul>
<li> <a href="#3">The basic structure of a Cacatoo model</a> </li>
<ul><li><a href="#3.1">Setup</a></li></ul>
<ul><li><a href="#3.2">Defining the rules</a></li></ul>
<ul><li><a href="#3.3">Main simulation loop</a></li></ul>
<ul><li><a href="#3.4">Example code</a></li></ul>
<li> <a href="#4">The advantage of a dynamic programming language</a> </li>
</ol>
<br>
<hr>
<br>
<a id="1"></a><center><h3>Why I made Cacatoo</h3></center>
<a id="1.1"></a><h4> <b>Why grid-based models?</b></h4>
When implementing individual-based models, there are a number of important decisions to make. When the primary interest is spatial structure, the most important decision is
whether space is continuous or discrete. While modelling individuals in continuous space is very powerful when modeling <a href="https://www.biorxiv.org/content/10.1101/2021.07.04.450902v1.abstract">flocking behaviour</a> (Papadopoulou et al, 2021), <a href="https://link.springer.com/article/10.1186/1471-2148-11-335">foraging strategies</a> (van der Post & Semmann, 2011), or
<a href="https://www.microbiologyresearch.org/content/journal/micro/10.1099/00221287-147-11-2897?crawler=true">biofilm mechanics</a> (Kreft et al., 2001), it is often computationally infeasible to model increasingly large populations.
Thus, when one is for example interested in evolution, grid-based models are a much more powerful tool to simulate a continuous process of mutation and selection.
Although these grid-based simulations may appear somewhat "unrealistic", it is important to note that realism is not what necessarily defines a good model. Instead, A is a good model of system B, when studying A teaching
you something about B (Paulien Hogeweg, 2011 lecture on Computational Biology). I have published numerous papers that were based primarily on grid-based models, and I can personally testify to having learned a lot through grid-based modelling, no matter how
weird and "pixely" they may look! <br><br>
<center><img src="images/pp.gif"></img></center>
<br>
<a id="1.2"></a><h4> <b>A more user-friendly CASH</b></h4>
When working with individual-based models, direct visual feedback is important. Not only are you more likely to detect programming mistakes, but it also aids rapid exploration of parameter space.
Over the last decade, most of my models were implemented by using the <a href="https://www.bramvandijk.com/software/#cash21">CASH C-library</a>, which would allow direct visual feedback by means of the X11
library. CASH was originally developed by R.J. de Boer & A.D. Staritsk, and was then further developed by Nobuto Takeuchi (CASH2s) and myself (CASH2.1). However, as it is
based in C, developing models with CASH requires a lot of programming experience, and even an experienced user like myself can sometimes take days to track down a simple bug.
Moreover, sharing your model with other users can be a pain in the neck, as installation is slightly different depending on the operating system. For this reason, I have
been trying to find a new programming language in which to implement something that is reminiscent of CASH. Even though some of the new programming languages (<i>e.g. </i> Ruby, Julia)
are very fast, creating a display for direct visual feedback typically slowed things down tremendously. <br><br>
<a id="1.3"></a><h4> <b>The new and improved Javascript</b></h4>
After searching for a new programming language for CASH for years, Inge Wortel and Johannes Textor published <a href="https://artistoo.net/" target="_blank">Artistoo</a>, a toolbox to simulate
cell tissues with 100% Javascript (see animation below). They even compared this toolbox with other known C++-libraries, and show their toolbox is not significantly slower. This initially surprised me, as I
remember Javascript being a language that was mostly use to make websites more annoying, and I did not expect it to be fast. As it turns out, it wasn't always this fast. Google has invested
a lot of money in optimising Javascript, especially for their own V8-engine in the Chrome browser. After fiddling around with Javascript a bit myself, I realised this was exactly what I
needed to make a new-and-improved version of CASH. And because silly acronyms are an essential component of being a good biologist, the tool is now called Cacatoo: <b>Ca</b>sh-like <b>c</b>ellular <b>a</b>utomaton <b>too</b>lkit
(full credits for this to Jeroen Meijer). <br><br>
<center><img src="images/cellsorting.gif"></img><br>Simple cell-sorting modelled in <a href="https://artistoo.net/" target="_blank">Artistoo</a></center>
<br><br>
<hr><br>
<a id="2"></a><center><h3> Getting started with Cacatoo</h3></center>
<a id="2.1"></a><h4> <b>Explore Cacatoo online (JSFiddle)</b></h4>
The easiest way to get started with Cacatoo is to go check out one of the <a href="examples_jsfiddle.html">JSFiddle examples</a>. JSFiddle is an online, free-to-use coding platform.
It can be used without an account (although making account has some benefits). You can simply click the "Fork" button, and start playing with Cacatoo. No need to download or install
anything!
<br><br><center><img src="images/jsfiddle.gif"></img></center>
<br>
<a id="2.2"></a><h4> <b>Get it on Github</b></h4>
If you're more interested in developing, you may want to actually get your own copy of the code. If so, then the best way to get your hands on Cacatoo is to go to the <a href="https://github.com/bramvandijk88/cacatoo">Github page</a>
and download the code (either clone it using 'git clone', or click 'Code', and then download the zip) directly from Github. Then, you can simply start checking out (and modifying!) the files in the examples directory.
<br><br><center><img src="images/github.gif"></img></center>
<br>
<br><br>
<hr><br>
<a id="3"></a><center><h3> The basic structure of a Cacatoo model </h3></center>
The basic structure of a Cacatoo model consists of three blocks of code: <br><br>
<a id="3.1"></a><h4> <b>1. Setup </b></h4>
In the setup, one defines the basic parameters of the model, including a name, the width/height of the grid, the duration of the simulation, etc. Once that is done,
it is time to populate the grid with individuals (or other types of entities) and make sure these are displayed however you want them to be displayed.
<br><br><center><img src="images/cacatoo_recipe.png" style="width:800px; height:250px; object-fit: cover; object-position:100% 24%"></img></center>
<a id="3.2"></a><h4> <b>2. Defining the rules </b></h4>
In step 2, one defines the actual rules of each grid point. For example, you can allows species to compete for empty spots, individuals
may die stochastically (or through some deterministic process!), etc. Go nuts!
<br><br><center><img src="images/cacatoo_recipe.png" style="width:800px; height:220px; object-fit: cover; object-position:100% 67%"></img></center>
<a id="3.3"></a><h4> <b>3. Main simulation loop </b></h4>
Finally, one defines what the main simulation loop is. This includes the updating of the grid (i.e. applying the rules defined in step 2 to the whole grid), mixing the grid,
occasional bottlenecks, etc. Here, you can also add plots to visualise the results of your simulation in real time!
<br><br><center><img src="images/cacatoo_recipe.png" style="width:800px; height:170px; object-fit: cover; object-position:100% 100%"></img></center>
<br>
<a id="3.4"></a><h4> <b>Example code </b></h4>
The code below illustrates what steps 1 through 3 will look like for a simple Cacatoo model. It's not that many lines of code!
<pre class="prettyprint lang-js"><code> <font size =2> // NOTE: For a full version of this code with explanatory comments, see 01_GoL.html in the examples directory.
// 1. SETUP. First, set up a configuration-object. Here we define how large the grid is, how long will it run, what colours will the critters be, etc.
let config = {
title: "Cacatoo example",
description: "My first Cacatoo model",
maxtime: 50000,
ncol : 200,
nrow : 200,
scale : 2,
statecolours: {'alive':{1:'white'}},
}
// 1. SETUP. (continued) Now, let's use that configuration-object to generate a new Cacatoo simulation
sim = new Simulation(config)
sim.makeGridmodel("gol")
sim.initialGrid(sim.gol,'alive',1,0.5)
sim.createDisplay("gol","alive","Game of life (white=alive)")
// 2. DEFINING THE RULES. Below, the user defines the nextState function. This function will be applied for each grid point when we will update the grid later.
sim.gol.nextState = function(i,j)
{
let neighbours = sim.gol.countMoore8(this,i,j,1,'alive')
let state = this.grid[i][j].alive;
if(state == 0 && neighbours == 3)
this.grid[i][j].alive = 1;
else if(state == 1 && (neighbours < 2 || neighbours > 3))
this.grid[i][j].alive = 0;
else
this.grid[i][j].alive = state;
}
// 3. MAIN SIMULATION LOOP. Finally, we need to set the update-function, which is the mainwill be applied to the whole grid each time step.
sim.gol.update = function()
{
this.synchronous()
}
sim.start()</font></code></pre>
<a id="4"></a><center><h3> The advantage of a dynamic programming language </h3></center>
You can use the above scaffolding to start building models right away. However, you are by no means bound to this structure. The best thing about Javascript is that it is a dynamical programming language, meaning
you can modify functions and data structures on the fly (note: this can also be a downside, be careful not to screw up ;D). Another advantage of Javascript is that all the variables that are defined in Cacatoo
are accessible from a developer console, for example the one in Google Chrome (accessed through CTRL+SHIFT+I, or CMD+SHIFT+I on OSX, see animation below). This makes debugging or interacting with your code so much easier than it could
have ever been with C. Of course, as your model becomes more complex, it may be that it becomes a bit slower than C. But hey, now that you have fleshed out all the bugs, your code can still simply
be ran from the command line using nodejs. If perhaps you really want to run thousands of simulations, nobody is stopping you from implementing your tried-and-true code in C, if you really want to ;)
<br><br><center><img src="images/console.gif"></img></center>
<br><br>
<center><h4><a href="#top">↑ Back to the top</a> | <a href="first_project.html">Next tutorial →</a></h4></center>
</div>
<br class="clear">
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>