{"id":359,"date":"2016-09-14T09:00:34","date_gmt":"2016-09-14T08:00:34","guid":{"rendered":"http:\/\/elcep.legtux.org\/?p=359"},"modified":"2016-09-14T09:00:34","modified_gmt":"2016-09-14T08:00:34","slug":"r-et-netlogo-sont-sur-un-bateau-openmole","status":"publish","type":"post","link":"https:\/\/elcep.legtux.org\/?p=359","title":{"rendered":"R et Netlogo sont sur un bateau : OpenMole"},"content":{"rendered":"<p>J&rsquo;ai particip\u00e9 en juillet au coding-camp OpenMole (j&rsquo;y reviendrais surement plus tard, ou pas), o\u00f9 j&rsquo;ai d\u00e9couvert un moyen d&#8217;embarquer R dans OpenMole ! Cela m&rsquo;ouvre des perspectives inimaginables il y a encore quelques semaines !<\/p>\n<figure id=\"attachment_364\" aria-describedby=\"caption-attachment-364\" style=\"width: 408px\" class=\"wp-caption alignright\"><a href=\"http:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/08\/Horse_power_smudge_9000.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-364\" src=\"http:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/08\/Horse_power_smudge_9000.jpg\" alt=\"Image est en CC by Smudge 9000\" width=\"408\" height=\"272\" srcset=\"https:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/08\/Horse_power_smudge_9000.jpg 640w, https:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/08\/Horse_power_smudge_9000-300x200.jpg 300w\" sizes=\"auto, (max-width: 408px) 100vw, 408px\" \/><\/a><figcaption id=\"caption-attachment-364\" class=\"wp-caption-text\">Image est en CC by Smudge 9000<\/figcaption><\/figure>\n<p>Et oui parce qu&rsquo;on va pouvoir piloter Netlogo avec R dans OpenMole ! Un vrai jeu de poup\u00e9e russe ! Mais comme les poup\u00e9es russes, il va falloir proc\u00e9der par \u00e9tape pour pouvoir b\u00e9n\u00e9ficier de la puissance de la parall\u00e9lisation sur son propre desktop comme sur un cluster ou une grille et cela sans effort suppl\u00e9mentaire !<\/p>\n<h2>Etape 1 : Netlogo dans R<\/h2>\n<p>Je vais sauter celle du mod\u00e8le Netlogo fonctionnel, pour l&rsquo;exemple on va prendre un mod\u00e8le de la librairie : ants . La premi\u00e8re chose qu&rsquo;on va faire c&rsquo;est l&#8217;embarquer dans R. Pour cela il faudra avoir le package RNetlogo install\u00e9 \u00e9videmment .<\/p>\n<pre>##Script R pour explorer les donn\u00e9es le mod\u00e8le ants de NetLogo\r\n\r\n#Chargement du package RNetLogo\r\nlibrary(RNetLogo)\r\n\r\n#localiser l'installation de netlogo\r\nnl.path = \"\/opt\/netlogo-5.3.1-64\/app\/\"\r\nNLStart(nl.path, gui = TRUE) #lance netlogo avec (TRUE) ou non (FALSE) une GUI\r\n\r\n##D\u00e9finition du chemin du mod\u00e8le\r\nmodel.path = \"\/opt\/netlogo-5.3.1-64\/app\/models\/Sample Models\/Biology\/Ants.nlogo\"\r\n## chargement du mod\u00e8le dans netlogo\r\nNLLoadModel(model.path)\r\n\r\n#################################\r\n## CREATION DU PLAN D'EXPERIENCE\r\n#################################\r\n# Ici on va d\u00e9finir le domaine d'exploration de notre mod\u00e8le\r\n# Pour simplifier ici on le met dans le m\u00eame script, mais il serait plus \r\n# judicieux de l'\u00e9crire dans un fichier Rdata ou csv quand on passera \u00e0 \r\n# l'encapsulage dans OpenMole\r\n\r\ndiff.rate = seq(from = 0, to = 100, by = 10) ##explorer le parametre de 0 \u00e0 100 par pas de 10\r\nevap.rate = seq(from = 0, to = 100, by = 10)\r\npop.dif = seq(from = 40, to = 200, by = 20)\r\nreplication = seq(from = 1, to = 10, by = 1)\r\n\r\n#Cr\u00e9ation d'un data frame avec toutes les combinaison des param\u00e8tres\r\npl.exp = expand.grid(pop = pop.dif, diff = diff.rate, evap = evap.rate)\r\n\r\n\r\n#################################\r\n## RUN Netlogo\r\n#################################\r\n##cr\u00e9er un dataframe vide qui sera supprim\u00e9 quand on passera \u00e0 openmole\r\ndata.df = data.frame()\r\n\r\n#for(i in 1:length(pl.exp[,1])){\r\nfor(i in 1:5){\r\n  # Pour chaque ligne du tableau on va lancer une simulation\r\n  # ATTENTION : Cette premi\u00e8re boucle se fera par la suite dans OpenMole\r\n  \r\n  ##Maping des variables dans netlogo\r\n  NLCommand(\"set population \", pl.exp$pop[i])\r\n  NLCommand(\"set diffusion-rate \", pl.exp$diff[i])\r\n  NLCommand(\"set evaporation-rate \", pl.exp$evap[i])\r\n  \r\n  ## Lancement de la commande setup du mod\u00e8le\r\n  NLCommand(\"setup\")\r\n  ## cr\u00e9er un reporter qui stock la valeur de la somme de nourriture des patches\r\n  food = NLDoReport(2000, \"go\", \"sum [food] of patches\")\r\n  data.df = cbind(data.df, food)\r\n  \r\n}\r\n\r\ndata.df = t(data.df)\r\nplot(x = 1:length(data.df[,1]), y = data.df[,2], type = \"l\")<\/pre>\n<p>On a maintenant un script fonctionnel, mais il faudrait pouvoir le parall\u00e9liser. Si on voulait rester dans R il y aurait des solutions assez faciles avec les packages \u00ab\u00a0snow\u00a0\u00bb ou \u00ab\u00a0parallel\u00a0\u00bb. Cela nous conduirait \u00e0 parall\u00e9liser pour une machine donn\u00e9e. En utilisant OpenMole, on va \u00eatre capable de parall\u00e9liser de mani\u00e8re transparente sur notre ordinateur de bureau, mais aussi sans effort et avec un script identique sur un cluster ou une grille de calcul.<\/p>\n<h2>Etape 2 : empaqueter R avec care<\/h2>\n<p>Voil\u00e0 l&rsquo;\u00e9tape un peu fastidieuse (\u00e0 mon sens) mais n\u00e9cessaire. Les dev. d&rsquo;OpenMole nous invite \u00e0 utiliser <a href=\"https:\/\/github.com\/proot-me\/proot-static-build\/tree\/master\/static\" target=\"_blank\">care<\/a>, un logiciel qui va scanner notre script pour cr\u00e9er une archive contenant toutes les d\u00e9pendances dont aura besoin openMole pour ex\u00e9cuter une instance.<\/p>\n<h3>Modifier le srcipt<\/h3>\n<p>Avant cela une petite modification du script R s&rsquo;impose . L&rsquo;id\u00e9e ici est de passer un argument au script pour lui sp\u00e9cifier la ligne du jeu de param\u00e8tres que l&rsquo;on veut lancer et stocker les r\u00e9sultats dans un fichier CSV (par exemple).<\/p>\n<pre>##Script R pour explorer les donn\u00e9es le mod\u00e8le ants de NetLogo\r\n\r\n# Notre script va accepter un argument pass\u00e9 en ligne de commande\r\nargs&lt;-commandArgs(trailingOnly = TRUE)\r\nargs &lt;- as.numeric(args) ## on passe un chiffre\r\n\r\n#Chargement du package RNetLogo sans message d'info\r\nsuppressPackageStartupMessages(library(RNetLogo, quietly = TRUE, warn.conflicts = TRUE))\r\n\r\n#localiser l'installation de netlogo\r\nnl.path = \"\/opt\/netlogo-5.3.1-64\/app\/\"\r\nNLStart(nl.path, gui = FALSE) #lance netlogo avec (TRUE) ou non (FALSE) une gui\r\n\r\n##D\u00e9finition du chemin du mod\u00e8le\r\nmodel.path = \"\/opt\/netlogo-5.3.1-64\/app\/models\/Sample Models\/Biology\/Ants.nlogo\"\r\n## chargement du model\u00e9 dans netlogo\r\nNLLoadModel(model.path)\r\n\r\n#################################\r\n## CREATION DU PLAN D'EXPERIENCE\r\n#################################\r\n# Ici on va d\u00e9finir le domaine d'exploration de notre mod\u00e8le\r\n# Pour simplifier ici on le met dans le m\u00eame script, mais il serait plus \r\n# judicieux de l'\u00e9crire dans un fichier Rdata ou csv quand on passera \u00e0 \r\n# l'encapsulage dans OpenMole\r\n\r\ndiff.rate = seq(from = 0, to = 100, by = 10) ##explorer le parametre de 0 \u00e0 100 par pas de 10\r\nevap.rate = seq(from = 0, to = 100, by = 10)\r\npop.dif = seq(from = 40, to = 200, by = 20)\r\nreplication = seq(from = 1, to = 10, by = 1)\r\n\r\n#Creation d'un data frame avec toutes les combinaisons des param\u00e8tres\r\npl.exp = expand.grid(pop = pop.dif, diff = diff.rate, evap = evap.rate)\r\n\r\n\r\n\r\n#################################\r\n## RUN Netlogo\r\n#################################\r\n\r\n\r\n##Maping des variables dans netlogo\r\nNLCommand(\"set population \", pl.exp$pop[args])\r\nNLCommand(\"set diffusion-rate \", pl.exp$diff[args])\r\nNLCommand(\"set evaporation-rate \", pl.exp$evap[args])\r\n\r\n## Lancement de la commande setup du modele\r\nNLCommand(\"setup\")\r\n## creer un reporter qui stock la valeur de la somme de nourriture des patches\r\nfood = as.data.frame(NLDoReport(2000, \"go\", \"sum [food] of patches\"))\r\n\r\n# \r\n#   \r\n\r\nsave(food, file = \"\/mypath\/food.RData\")\r\n\r\nNLQuit()<\/pre>\n<p>Une fois le script modifi\u00e9, on peut tester que tout fonctionne<\/p>\n<pre>R --slave -f run_netlogo.R --args 4<\/pre>\n<p>Ce qui doit avoir pour effet de sauvegarder un fichier food.Rdata en itilisant la ligne 4 (args) du data frame cr\u00e9\u00e9 dans le script.<\/p>\n<h3>Cr\u00e9er un package pour OpenMole<\/h3>\n<p>L&rsquo;id\u00e9e ici est de cr\u00e9er un package qui contient R, le script, et toutes ses d\u00e9pendances (RNetlogo et Netlogo). Pour cela on utilisera <a href=\"https:\/\/github.com\/proot-me\/proot-static-build\/tree\/master\/static\" target=\"_blank\">care<\/a>. Il vous faudra t\u00e9l\u00e9charger l&rsquo;ex\u00e9cutable et le rendre ex\u00e9cutable soit dans le r\u00e9pertoire courant, soit dans les bins.<\/p>\n<p>Ensuite l&rsquo;usage est assez simple :<\/p>\n<pre>.\/care-x86_64 -o r.tar.gz.bin R --slave -f run_netlogo.R --args 4<\/pre>\n<p>Cela va avoir pour effet de lancer dans care votre script et lui permettre de d\u00e9tecter les d\u00e9pendances. Cela peut prendre du temps en fonction du temps d&rsquo;ex\u00e9cution de votre script.<\/p>\n<p>Vous obtenez en sortie une archive nomm\u00e9e r.tar.gz.bin et vous pourrez passer \u00e0 OpenMole !<\/p>\n<h2>Etape 3 : Embarquer R dans OpenMole<\/h2>\n<p>Vous pouvez lancer votre session <a href=\"http:\/\/www.openmole.org\/\">OpenMole<\/a>.<\/p>\n<pre>cd openmole_ex_dir\/\r\n.\/openmole<\/pre>\n<p>Cela devrait avoir pour effet d&rsquo;ouvrir votre navigateur pr\u00e9f\u00e9r\u00e9 : Firefox (ou chrome&#8230; \u00e7a marche aussi). Dans l&rsquo;interface graphique, vous pouvez charger une archive care.<\/p>\n<figure id=\"attachment_369\" aria-describedby=\"caption-attachment-369\" style=\"width: 525px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/Capture-d\u2019\u00e9cran_2016-09-14_09-35-55.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-369\" src=\"http:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/Capture-d\u2019\u00e9cran_2016-09-14_09-35-55.png\" alt=\"import care archive in openMole\" width=\"525\" height=\"281\" srcset=\"https:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/Capture-d\u2019\u00e9cran_2016-09-14_09-35-55.png 525w, https:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/Capture-d\u2019\u00e9cran_2016-09-14_09-35-55-300x161.png 300w\" sizes=\"auto, (max-width: 525px) 100vw, 525px\" \/><\/a><figcaption id=\"caption-attachment-369\" class=\"wp-caption-text\">import care archive in openMole<\/figcaption><\/figure>\n<p>Un widget bien fait d\u00e9tecte le param\u00e9trage de votre script et vous propose un squelette de script openmole. Il ne vous restera plus qu&rsquo;\u00e0 le peaufiner pour pouvoir parall\u00e9liser tout \u00e7a. \ud83d\ude00<\/p>\n<pre>val i3 = Val[Int] \/\/table of correspondance\r\n\r\nval output = Val[File]\r\n\r\nval rTask = CARETask(workDirectory \/ \"myscript.tar.gz.bin\", \"R  --slave -f run_grid.R --args ${i3}\") set(\r\n  inputs += (i3),\r\n  \/\/Default values. Can be removed if OpenMOLE Vals are set by values coming from the workflow\r\n  outputs += (i3),\r\n  outputFiles += (\"simulation.RData\", output)\r\n  )\r\n\r\nval copyHook = CopyFileHook(output, workDirectory \/ \"resultats\/run_result_${i3}.RData\")\r\n\r\nval exploration = ExplorationTask(\r\n                      (i3 in (1 to 24 by 1))\r\n                      )\r\nval env = LocalEnvironment(2) \/\/defined number of thread used by the mole\r\nexploration -&lt; (rTask hook copyHook on env)<\/pre>\n<p>Enjoy et merci pour le travail incroyable de la team OpenMole !<\/p>\n<p><a href=\"http:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/DSC_0983.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-370\" src=\"http:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/DSC_0983.jpg\" alt=\"dsc_0983\" width=\"700\" height=\"394\" srcset=\"https:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/DSC_0983.jpg 700w, https:\/\/elcep.legtux.org\/wp-content\/uploads\/2016\/09\/DSC_0983-300x169.jpg 300w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>J&rsquo;ai particip\u00e9 en juillet au coding-camp OpenMole (j&rsquo;y reviendrais surement plus tard, ou pas), o\u00f9 j&rsquo;ai d\u00e9couvert un moyen d&#8217;embarquer R dans OpenMole ! Cela m&rsquo;ouvre des perspectives inimaginables il y a encore quelques semaines ! Et oui parce qu&rsquo;on va pouvoir piloter Netlogo avec R dans OpenMole ! Un vrai jeu de poup\u00e9e russe &hellip; <a href=\"https:\/\/elcep.legtux.org\/?p=359\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">R et Netlogo sont sur un bateau : OpenMole<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[60,9,36,62,61],"class_list":["post-359","post","type-post","status-publish","format-standard","hentry","category-sma","tag-java","tag-netlogo","tag-openmole","tag-parallel","tag-rnetlogo"],"_links":{"self":[{"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=\/wp\/v2\/posts\/359","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=359"}],"version-history":[{"count":7,"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=\/wp\/v2\/posts\/359\/revisions"}],"predecessor-version":[{"id":371,"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=\/wp\/v2\/posts\/359\/revisions\/371"}],"wp:attachment":[{"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=359"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=359"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/elcep.legtux.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=359"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}