[GRASS-user] How to find the second largest value in a series of rasters.

Dear all,

I have to find the maximum value for each cell in a series of rasters and
generate both a maximum value map and a categorical map with the raster
number which contains the maximum value.

R.series is, therefore, perfect to accomplish that using
method=maximum,max_raster.

My problem is that I also need to find the *second largest* value and the
corresponding raster number which contains the second largest value.

I am doing that by iterating over all classes through a shell script, but it
obviously takes much more time than using a simple r.series command.

Can anyone share any idea on how to accomplish that using r.series or
something similar?

Thanks in advance for your thoughts.

Best regards,
Marcello.

--
View this message in context: http://osgeo-org.1803224.n2.nabble.com/How-to-find-the-second-largest-value-in-a-series-of-rasters-tp7075764p7075764.html
Sent from the Grass - Users mailing list archive at Nabble.com.

On 08/12/11 21:30, Marcello Gorini wrote:

Dear all,

I have to find the maximum value for each cell in a series of rasters and
generate both a maximum value map and a categorical map with the raster
number which contains the maximum value.

R.series is, therefore, perfect to accomplish that using
method=maximum,max_raster.

My problem is that I also need to find the *second largest* value and the
corresponding raster number which contains the second largest value.

I am doing that by iterating over all classes through a shell script, but it
obviously takes much more time than using a simple r.series command.

Can anyone share any idea on how to accomplish that using r.series or
something similar?

Thanks in advance for your thoughts.

Since you have the max_raster value, can't you just take that map out of the list you submit to r.series and find the new max_raster and value ?

Moritz

Moritz:

Since you have the max_raster value, can’t you just take that map out of the list you submit to r.series and find the new max_raster and value ?

Unfortunately, I can’t. There is not on single map which is the maximum everywhere. The calculation is done in a cell-by-cell basis, so different maps have the maximum value locally.

Somehow, if after identifying the maximum value, I could make it zero or -9999, for instance, then I could re-run r.series to get the second largest value, but I don’t know how to do it.

But thanks anyway.

Cheers,
Marcello.

Marcello wrote:

I have to find the maximum value for each cell in a series
of rasters and generate both a maximum value map and a
categorical map with the raster number which contains the
maximum value.

see also:

http://grass.osgeo.org/wiki/Time_series#Common_legends_for_many_raster_maps

it sounds like you have done something similar already, but
maybe you could adapt it somehow, or it is faster.

I think you'll have to use g.copy + r.null (or better r.reclass)
to hide the highest values.

Hamish

Marcello:

I have to find the maximum value for each cell in a series
of rasters and generate both a maximum value map and a
categorical map with the raster number which contains the
maximum value.

Hamish:

see also:

http://grass.osgeo.org/wiki/Time_series#Common_legends_for_many_raster_maps

it sounds like you have done something similar already, but
maybe you could adapt it somehow, or it is faster.

I think you’ll have to use g.copy + r.null (or better r.reclass)
to hide the highest values.

Thanks for the ideas. I still haven’t quite figured out how to do it without a loop, but I will keep trying.

Anyway, I found very useful this kind of expression:

 for MAP in `g.mlist rast pattern=$MAP_PATTERN` ; do

   eval `[r.info](http://r.info) -r $MAP`

I didn’t know it was possible. Thanks.

Cheers,
Marcello.

Marcello Gorini wrote:

I have to find the maximum value for each cell in a series of rasters and
generate both a maximum value map and a categorical map with the raster
number which contains the maximum value.

R.series is, therefore, perfect to accomplish that using
method=maximum,max_raster.

My problem is that I also need to find the *second largest* value and the
corresponding raster number which contains the second largest value.

I am doing that by iterating over all classes through a shell script, but it
obviously takes much more time than using a simple r.series command.

Can anyone share any idea on how to accomplish that using r.series or
something similar?

There isn't an efficient way to do this using existing tools. If you
need the efficiency, I suggest adding a "second largest" aggregate to
lib/stats (based upon c_max.c and c_maxx.c), and updating r.series to
use it.

--
Glynn Clements <glynn@gclements.plus.com>

Marcello:

My problem is that I also need to find the second largest value and the
corresponding raster number which contains the second largest value.

I am doing that by iterating over all classes through a shell script, but it
obviously takes much more time than using a simple r.series command.

Can anyone share any idea on how to accomplish that using r.series or
something similar?

Glynn:

There isn’t an efficient way to do this using existing tools. If you
need the efficiency, I suggest adding a “second largest” aggregate to
lib/stats (based upon c_max.c and c_maxx.c), and updating r.series to
use it.

Thanks for pointing me the way. I think it is a little beyond my skills, but I might give it a try.

Cheers,
Marcello.

what about computing the first largest value, making your categorical map, and using it as a mask ?

if you mask all cell containing the first largest value, then the second largest value will become the first largest value of the masked raster serie …

my 2 ct

Sylvain

2011/12/10 Marcello Gorini <gorini@gmail.com>

Marcello:

My problem is that I also need to find the second largest value and the
corresponding raster number which contains the second largest value.

I am doing that by iterating over all classes through a shell script, but it
obviously takes much more time than using a simple r.series command.

Can anyone share any idea on how to accomplish that using r.series or
something similar?

Glynn:

There isn’t an efficient way to do this using existing tools. If you
need the efficiency, I suggest adding a “second largest” aggregate to
lib/stats (based upon c_max.c and c_maxx.c), and updating r.series to
use it.

Thanks for pointing me the way. I think it is a little beyond my skills, but I might give it a try.

Cheers,
Marcello.


grass-user mailing list
grass-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-user

Sylvain Maillard wrote:

what about computing the first largest value, making your categorical map,
and using it as a mask ?

if you mask all cell containing the first largest value, then the second
largest value will become the first largest value of the masked raster
serie ...

Every cell has a largest value (provided that the cell is non-null in
at least one input map).

The problem can be solved by running "r.series method=max_raster",
then filtering each input map, setting a cell to null if the input
map has the largest value for that particular cell, then running
"r.series method=max" on the filtered maps.

But that's very inefficient compared to implementing a
"second-largest" aggregate directly.

--
Glynn Clements <glynn@gclements.plus.com>