<div dir="ltr"><div><div>Thank you all for the comments. Here are some more from me.<br></div><div><br>On Thu, Jun 4, 2015 at 3:53 AM, Rainer M Krug <<a href="mailto:Rainer@krugs.de">Rainer@krugs.de</a>> wrote:<br>><br>> Vaclav Petras <<a href="mailto:wenzeslaus@gmail.com">wenzeslaus@gmail.com</a>> writes:<br>><br>> > Hi all,<br>> ><br>> > I'm happy to announce new command line interface of the `grass` program [1,<br>> > 2] available in trunk.<br>><br>> This sounds very exciting - and will make life much easier. Thanks a<br>> lot.<br>><br>> It might be to early to ask, but are there any penalties is speed when<br>> using this construct compared with the "traditional" way?<br><br>It is not too early. The time you have to currently pay is approximately 0.05 s. However, you pay for having the full session with all checks, cleanups and Mapset locking. Although the execution time is much longer than when just setting the variables manually (when you don't execute any cleanups, for example), the time is relatively short when running some computation.<br><br>Unfortunately, the price has to be paid every time you call a module. Then the price can grow especially if you call something many times (e.g. in a loop). This can be dealt with by not executing individual modules directly and creating a script (or module) for GRASS instead. Although this is less convenient then direct execution of modules, it brings advantages of writing Python script with GRASS Python API, script which can become true GRASS module and finally, and finally it separates GRASS-related functionality from your script (separation is good for maintenance and reuse). In any case, the goal is to keep the time as low as possible to support as many use cases as possible.<br><br></div>And here is my simple benchmark:<br><div><br>time grass71 ~/grassdata/nc_spm_08_grass7/PERMANENT/ --exec echo "from GRASS"<br><br>real    0m0.069s<br>user    0m0.048s<br>sys     0m0.008s<br><br>>> ><br>> > Certainly you already know that you can start GRASS GIS session in the<br>> > specified Location and Mapset in the following way:<br>> ><br>> > grass71 .../grassdata/location/mapset/<br>> ><br>> > The new interface adds `--exec` flag for specifying a command which will be<br>> > executed inside that GRASS session:<br>> ><br>> > grass71 .../grassdata/location/mapset/ --exec r.univar map=elevation<br>><br>> Am I right in assuming, that the --exec effectively splits the command<br>> into the "setup part" (mapset) before and the "command part" after and<br>> whatever follows will be executed?<br><br></div><div>Exactly, it splits the command line: standard `grass` program parameters are before --exec, command to execute is after.<br></div><div><br>> What happens when one specifies a shell command - I assume it will it also be<br>> executed?<br><br></div><div>Right, anything is executed, e.g.<br></div>env<br></div>RScript...<br>python -c "import grass.script as gscript; gscript.run_command('g.region', flags='g')"<br>r.external --ui<br>g.gui -f<br><div><br><div>Just note that the shell syntax is interpreted in the current shell (e.g. $VARIABLE), `grass` program gets just plain parameters to execute.<br></div><div><br>> I guess that if this is working, the next step would be to introduce the<br>> single command version so that one does not have to specify the mapset<br>> each time. E.g:<br><br></div><div>Yes! [1, 2] The code now allows to introduce such interface. The challenge is where to store the information about active Location and Mapset. Currently, .gisrc (or .grassrc or .grassgisrc) file stored in the current working directory seems as the best option to me. Another option is to use environment variables [3, 4] but I don't consider it a nice solution.<br><br>[1] <a href="https://trac.osgeo.org/grass/ticket/2579#Additionalideas">https://trac.osgeo.org/grass/ticket/2579#Additionalideas</a><br>[2] <a href="https://trac.osgeo.org/grass/ticket/2579#comment:10">https://trac.osgeo.org/grass/ticket/2579#comment:10</a><br>[3] <a href="https://trac.osgeo.org/grass/ticket/2679">https://trac.osgeo.org/grass/ticket/2679</a><br>[4] <a href="https://trac.osgeo.org/grass/ticket/2681">https://trac.osgeo.org/grass/ticket/2681</a><br><br>> ,----<br>> | grass71 --setmapset .../grassdata/test1/PERMANENT/<br>> | grass71 --exec r.external input=basins.tiff output=basins<br>> | grass71 --exec r.external input=elevation.tiff output=elevation<br>> | grass71 --unsetmapset<br>> `----<br><br></div><div>Rather than this, I prefer subcommand interface as known from git, docker or apt-get:<br><br>,----<br>| grass71 setmapset .../grassdata/test1/PERMANENT/<br>| grass71 run r.external input=basins.tiff output=basins<br>| grass71 run r.external input=elevation.tiff output=elevation<br>| grass71 unsetmapset<br>`----<br><br></div><div>Which subcommands and how to name them is of course a separate question. I'm quite comfortable with `run` but not so much with `setmapset` and `unsetmapset`.<br></div><div><br>> and finally introduce a mapper around this (similar to Rscript ore<br>> littler) so that one could say<br>><br>> ,----<br>> | grass71exec setmapset .../grassdata/test1/PERMANENT/<br>> | grass71exec r.external input=basins.tiff output=basins<br>> | grass71exec r.external input=elevation.tiff output=elevation<br>> | grass71exec unsetmapset<br>> `----<br></div><div><br></div><div>I don't see much advantage in this comparing to grass71 --exec for the usages other than shebang which requires special approach anyway (see below).<br></div><div><br>> and could use grass71exec as a shebang - that would be the ultimate<br>> convenience.<br><br></div><div>This would make sense. GRASS looks like an interpreter by requiring things to run inside, so it should behave as an interpreter.<br><br></div><div>Shebang may require to have a special wrapper to set some parameters (since shebang allows just one short parameter and no parameter when /usr/bin/env is used) but the challenge here is much bigger: Who will set the Mapset?<br><br></div><div>As I recently discussed on grass-dev, GRASS session is runtime+data [1]. Shebang version could just set up runtime while the script would be responsible for the data (setting Mapset). The implementation/design challenge is then who will create and delete the "gisrc" file which keeps info about the Mapset. GRASS would have to know that it is not supposed to require Mapset to be set when starting nor read the last used one from the user settings (I'm not sure what are the options to achieve this except for special shebang parameter/mode).<br></div><div><br></div><div>Another challenge is how to execute the script in GRASS session because you need another shebang to tell you how to actually execute the script. So my idea so far is to have:<br><br>#!grass71exec<br>#!python<br><br></div><div>where first line would by used by system to call grass program, then GRASS would copy the file, delete the first line and actually execute this copy. GRASS would have to know that it is supposed to do that (special shebang parameter/mode, two shebang lines, or special syntax for the second shebang).<br><br>[1] <a href="http://lists.osgeo.org/pipermail/grass-dev/2015-June/075203.html">http://lists.osgeo.org/pipermail/grass-dev/2015-June/075203.html</a><br></div><div><br>> Thanks a lot,<br>><br>> Rainer<br>><br>> ><br>> > This starts GRASS session, executes whatever command is specified after<br>> > `--exec` flag and then ends showing the (text) output of the module as if<br>> > the module would be executed manually in the GRASS session. And example<br>> > showing this in combination with r.external to get the data into the Mapset<br>> > is in the documentation [3].<br>> ><br>> > This interface is meant to remove the need for lengthy manual setup of<br>> > environmental variables followed by execution of GRASS modules in the<br>> > mock-up GRASS session [4]. The idea is to use correct GRASS session<br>> > maintained by `grass` program which means that any GRASS-related code must<br>> > be passed to the `grass` program as opposed to direct execution in the<br>> > former case.<br>> ><br>> > The interface can run any module or custom script with or without<br>> > parameters. GUI tools including g.gui [5] can be called as well which opens<br>> > new possibilities for application developers.<br>> ><br>> > The interface is the first implementation and currently is fully<br>> > operational only on Linux and similar systems but it benefits from a lot of<br>> > stable code which was already in place. Try it out and feel free to comment<br>> > here, on grass-dev or in the related ticket [6]. There is definitively many<br>> > potential improvements and it would be great to know what the community<br>> > demands.<br>> ><br>> > Vaclav<br>> ><br>> > [1] <a href="https://trac.osgeo.org/grass/changeset/65252">https://trac.osgeo.org/grass/changeset/65252</a><br>> > [2] <a href="https://trac.osgeo.org/grass/changeset/65294">https://trac.osgeo.org/grass/changeset/65294</a><br>> > [3]<br>> > <a href="http://grass.osgeo.org/grass71/manuals/grass7.html#exec-interface-example">http://grass.osgeo.org/grass71/manuals/grass7.html#exec-interface-example</a><br>> > [4]<br>> > <a href="http://grasswiki.osgeo.org/wiki/Working_with_GRASS_without_starting_it_explicitly">http://grasswiki.osgeo.org/wiki/Working_with_GRASS_without_starting_it_explicitly</a><br>> > [5] <a href="https://trac.osgeo.org/grass/changeset/65306">https://trac.osgeo.org/grass/changeset/65306</a><br>> > [6] <a href="https://trac.osgeo.org/grass/ticket/2579">https://trac.osgeo.org/grass/ticket/2579</a><br>> > _______________________________________________<br>> > grass-user mailing list<br>> > <a href="mailto:grass-user@lists.osgeo.org">grass-user@lists.osgeo.org</a><br>> > <a href="http://lists.osgeo.org/mailman/listinfo/grass-user">http://lists.osgeo.org/mailman/listinfo/grass-user</a><br>><br>> --<br>> Rainer M. Krug<br>> email: Rainer<at>krugs<dot>de<br>> PGP: 0x0F52F982<br><br></div></div></div>