0

I have thousands raster maps (3652, named raster_name.1, raster_name.2,... raster_name.x,... raster_name.3652) and for each map I want to do the r.mapcalc-threshold operation below here: binary_raster_name.x = if ( raster_name.x > 293 , 1 , 0 ). My target is to create a binary threshold map for each raster I have in my project. Here is the script I tried:

GRASS 7.8.3 (LocationMatteo):~ >x=3652

GRASS 7.8.3 (LocationMatteo):~ >seq $x | parallel r.mapcalc expression="tas.binary{}=if(tasmax_day_CMCC-CMS_rcp45_r1i1p1_20300101-20391231.{}<293.15,1,0)"

It seems that parallel works as I get 3652 lines, but I get this error for each line:

IT: errore di sintassi vicino al token non atteso "("

EN: syntax error near the token not expected "(".

How can I run correctly r.mapcalc in parallel (or parallelized) in GRASS?

Which is the correct formula?

1
  • In addition to the answer by Micha, mind the white space around the equal sign " output = expression"
    – markusN
    Commented Oct 10, 2020 at 14:46

2 Answers 2

2

In general GRASS does not support parallelized operation. There are some workarounds: on the wiki.

However for this particular question, are you familiar with the r.reclass module? Creating a reclass raster is very "cheap". I guess the question is: what are you planning to do with these 3652 binary rasters after you create them?


(added after matteo.s comment)

Here's the procedure. I don't have 3600 maps on hand, so I created 99 maps with random values between 0 and 40). The commands below use some bash shell tricks. If you are on a different shell, or using the GUI, you'll have to adapt as needed.

# Create 99 random rasters, the -s flag sets a random seed
for i in `seq 1 99`; do r.mapcalc -s "precip_$i = rand(0, 40)"; done

# Prepare rules file for reclass
echo "0 thru 20 = 0 Less than 20                                                                    
20 thru 40 = 1 Greater than 20" > reclass.txt

# Run reclass for all precip rasters in a loop.
# The g.list command gets each precip raster to feed into r.reclass
for r in `g.list rast pattern=precip_* `; do r.reclass $r output=${r}_rcl rules=reclass.txt --o; done
# Now I have 99 reclass rasters, in addition to the originals.
# This took only a few seconds.

# Save a list of all precip reclass rasters for the r.series statement
# NOTE: In your case, with 3600 rasters you *must*
# put this list into a file, and use the file=... option to r.series.
rcl_list=`g.list rast pattern="precip*rcl" separator=comma`
r.series input=${rcl_list} output=precip_sum method=sum

That's it. HTH

1
  • I read running parallelized script on Grass was possible here: grasswiki.osgeo.org/wiki/Parallelizing_Scripts, hope it works with r.mapcalc. I am not familiar with r.reclass. I've run a r.series, but it does not have a "threshold" formula. My final output is a sum of all the binary maps, then divided /3652, so that I can have a final map where each pixel is defined by the ten-years (365x10=3650...) average number of "1" (rasters are daily climate maps, so my final output map is a ten-years average count of days in which temp is above 293.15 K, or 20°C). r.reclass is useful fot that?
    – matteo s.
    Commented Oct 9, 2020 at 11:23
1

I use GNU parallel and r.mapcalc a lot. I think the issue is quotes. Try this:

seq $x | parallel "r.mapcalc \"expression=tas.binary{}=if(tasmax_day_CMCC-CMS_rcp45_r1i1p1_20300101-20391231.{}<293.15,1,0)\""

OR

seq $x | parallel "r.mapcalc 'expression=tas.binary{}=if(tasmax_day_CMCC-CMS_rcp45_r1i1p1_20300101-20391231.{}<293.15,1,0)'"
1
  • The first one WORKSSSS!!!! Thank you mankoff
    – matteo s.
    Commented Oct 11, 2020 at 14:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.