[GRASS5] r.mapcalc bug/64bit?

[re-posted to the list as it may be of wider interest, maybe
someone knows?]

Glynn, all,

I have discovered a pressing problem (for me) in
r.mapcalc as far as I see. I am doing time series
processing of satellite data to find frost periods. As
far as I see the if() doesn't behave as it should:

# input data, look reasonable:
GRASS 6.1.cvs (pat):~ > r.info -r modis_t_a_lst1km20040102.daily_min
min=-24.290000
max=-16.510000

GRASS 6.1.cvs (pat):~ > r.info -r startday_previous
min=1
max=1

GRASS 6.1.cvs (pat):~ > r.info -r condition_previous
min=1
max=1

GRASS 6.1.cvs (pat):~ > r.info -r duration
min=1
max=1

# filter command to check if a new frost period starts or
# an existing one continues:
GRASS 6.1.cvs (pat):~ > r.mapcalc 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 && (startday_previous == 0 || condition_previous == 0), 2, startday_previous)'
100%

GRASS 6.1.cvs (pat):~ > r.info -r startday
min=-2147483648
max=-2147483648

GRASS 6.1.cvs (pat):~ > r.univar startday
...
total null and non-null cells: 1136163
total null cells: 1136163
Of the non-null cells:
----------------------
n: 0
minimum: nan
maximum: nan
range: nan
mean: nan
standard deviation: nan
variance: nan
variation coefficient: nan %
sum: 0

#### ...apparently no output at all.

# settings:
g.region -p
projection: 99 (Transverse Mercator)
zone: 0
datum: rome40
ellipsoid: international
north: 5233880.40466952
south: 5050480.40466952
west: 1573324.58937663
east: 1821124.58937663
nsres: 200
ewres: 200
rows: 917
cols: 1239

# Redhat Enterprise RHEL4
uname -a
Linux eden 2.6.9-34.ELsmp #1 SMP Fri Feb 24 16:56:28 EST 2006 x86_64 x86_64 x86_64 GNU/Linux

##############################
# configuration:
XEON="-mcpu=nocona -mtune=nocona -m64 -minline-all-stringops"
# some flags to catch all possible problems:
MYCFLAGS="-g -Wall -Werror-implicit-function-declaration -fno-common $XEON"
MYCXXFLAGS="-g -Wall"

# RHEL 4/64bit:
CFLAGS="$MYCFLAGS" CXXFLAGS="$MYCXXFLAGS" ./configure \
  --enable-64bit \
  --with-libs=/usr/lib64 \
  --with-cxx \
  --with-gdal=/usr/local/bin/gdal-config \
  --with-postgres-includes=/usr/include/pgsql --with-postgres-libs=/usr/lib \
  --without-mysql \
  --without-odbc \
  --with-nls \
  --with-fftw \
  --with-freetype --with-freetype-includes=/usr/include/freetype2 \
  --disable-largefile \
  --without-opendwg \
  2>&1 | tee config_log.txt

# compiled: Mar 27 2006

Do you have any idea why this fails? Some tests with other data on a
32bit box didn't show this problem.

I am lost here, cry for help :slight_smile:

thanks

Markus

# filter command to check if a new frost period starts or
# an existing one continues:
GRASS 6.1.cvs (pat):~ > r.mapcalc \
   'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 && \
   (startday_previous == 0 || condition_previous == 0), 2, \
    startday_previous)'
100%

GRASS 6.1.cvs (pat):~ > r.info -r startday
min=-2147483648
max=-2147483648

GRASS 6.1.cvs (pat):~ > r.univar startday
...
total null and non-null cells: 1136163
total null cells: 1136163
Of the non-null cells:
----------------------
n: 0
minimum: nan
maximum: nan
range: nan
mean: nan
standard deviation: nan
variance: nan
variation coefficient: nan %
sum: 0

No problem, besides r.info (both -r and normal) doesn't translate NULLs.

on a 32-bit P4:
G61> r.mapcalc startday_previous='null()'
100%
G61> r.info startday_previous -r
min=-2147483648
max=-2147483648

maybe init start maps to 0,1 instead of null(),1 ?

in r.info test min,max result with G_is_null_value() ?
remember for CELL maps int can't be set to nan.

Hamish

On Mon, May 01, 2006 at 08:01:27PM +1200, Hamish wrote:

> # filter command to check if a new frost period starts or
> # an existing one continues:
> GRASS 6.1.cvs (pat):~ > r.mapcalc \
> 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 && \
> (startday_previous == 0 || condition_previous == 0), 2, \
> startday_previous)'
> 100%
>
> GRASS 6.1.cvs (pat):~ > r.info -r startday
> min=-2147483648
> max=-2147483648
>
> GRASS 6.1.cvs (pat):~ > r.univar startday
> ...
> total null and non-null cells: 1136163
> total null cells: 1136163
> Of the non-null cells:
> ----------------------
> n: 0
> minimum: nan
> maximum: nan
> range: nan
> mean: nan
> standard deviation: nan
> variance: nan
> variation coefficient: nan %
> sum: 0

No problem, besides r.info (both -r and normal) doesn't translate NULLs.

OK, while this is "cosmetics", I wonder why the result is NULL!

I think that the result of the if() condition here [1]:

r.mapcalc 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 && (startday_previous == 0 || condition_previous == 0), 2, startday_previous)'

in my case:
r.mapcalc 'startday=if(-16.51 < -2.0 && ( 1 == 0 || 1 == 0), 2, 1)'
                      ( true && ( false || false ), 2, 1)

Shouldn't the result be 1 and not NULL?
At least I want 1, how to rewrite the condition?

confused,
  Markus

[1] http://grass.itc.it/pipermail/grass5/2006-April/022623.html

Markus Neteler wrote:

[re-posted to the list as it may be of wider interest, maybe
someone knows?]

Glynn, all,

I have discovered a pressing problem (for me) in
r.mapcalc as far as I see. I am doing time series
processing of satellite data to find frost periods. As
far as I see the if() doesn't behave as it should:

# input data, look reasonable:
GRASS 6.1.cvs (pat):~ > r.info -r modis_t_a_lst1km20040102.daily_min
min=-24.290000
max=-16.510000

GRASS 6.1.cvs (pat):~ > r.info -r startday_previous
min=1
max=1

GRASS 6.1.cvs (pat):~ > r.info -r condition_previous
min=1
max=1

GRASS 6.1.cvs (pat):~ > r.info -r duration
min=1
max=1

# filter command to check if a new frost period starts or
# an existing one continues:
GRASS 6.1.cvs (pat):~ > r.mapcalc 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 && (startday_previous == 0 || condition_previous == 0), 2, startday_previous)'
100%

GRASS 6.1.cvs (pat):~ > r.info -r startday
min=-2147483648
max=-2147483648

So startday is all null.

What does the following say:

r.mapcalc 'test = isnull(modis_t_a_lst1km20040102.daily_min) + isnull(startday_previous) + isnull(condition_previous)'
r.info -r test

?

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

On Mon, May 01, 2006 at 05:33:41PM +0100, Glynn Clements wrote:

Markus Neteler wrote:

> [re-posted to the list as it may be of wider interest, maybe
> someone knows?]
>
> Glynn, all,
>
> I have discovered a pressing problem (for me) in
> r.mapcalc as far as I see. I am doing time series
> processing of satellite data to find frost periods. As
> far as I see the if() doesn't behave as it should:
>
> # input data, look reasonable:
> GRASS 6.1.cvs (pat):~ > r.info -r modis_t_a_lst1km20040102.daily_min
> min=-24.290000
> max=-16.510000
>
> GRASS 6.1.cvs (pat):~ > r.info -r startday_previous
> min=1
> max=1
>
> GRASS 6.1.cvs (pat):~ > r.info -r condition_previous
> min=1
> max=1
>
> GRASS 6.1.cvs (pat):~ > r.info -r duration
> min=1
> max=1
>
> # filter command to check if a new frost period starts or
> # an existing one continues:
> GRASS 6.1.cvs (pat):~ > r.mapcalc 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 && (startday_previous == 0 || condition_previous == 0), 2, startday_previous)'
> 100%
>
> GRASS 6.1.cvs (pat):~ > r.info -r startday
> min=-2147483648
> max=-2147483648

So startday is all null.

What does the following say:

r.mapcalc 'test = isnull(modis_t_a_lst1km20040102.daily_min) + isnull(startday_previous) + isnull(condition_previous)'
r.info -r test

This test:

GRASS 6.1.cvs (pat):~ > r.mapcalc 'test = isnull(modis_t_a_lst1km20040102.daily_min) + isnull(startday_previous) + isnull(condition_previous)'
100%
GRASS 6.1.cvs (pat):~ > r.info -r test
min=1
max=3
GRASS 6.1.cvs (pat):~ > r.univar test
total null and non-null cells: 1136163
total null cells: 0

Of the non-null cells:
----------------------
n: 1136163
minimum: 1
maximum: 3
range: 2
mean: 2.99634
standard deviation: 0.0730131
variance: 0.00533091
variation coefficient: 2.43674 %
sum: 3404331

There are *some* NULL pixels due to clouds which are propagated to
the other input maps of above if() condition:
GRASS 6.1.cvs (pat):~ > r.univar modis_t_a_lst1km20040102.daily_min

Processing .. 100%

total null and non-null cells: 1136163
total null cells: 1133919

Of the non-null cells:
----------------------
n: 2244
minimum: -24.29
maximum: -16.51
range: 7.78
mean: -20.5391
standard deviation: 1.77196
variance: 3.13983
variation coefficient: -8.62722 %
sum: -46089.82

Then entire thing loops over the maps day by day.

Markus

Markus Neteler wrote:

> What does the following say:
>
> r.mapcalc 'test = isnull(modis_t_a_lst1km20040102.daily_min) + isnull(startday_previous) + isnull(condition_previous)'
> r.info -r test
>

This test:

GRASS 6.1.cvs (pat):~ > r.mapcalc 'test = isnull(modis_t_a_lst1km20040102.daily_min) + isnull(startday_previous) + isnull(condition_previous)'
100%
GRASS 6.1.cvs (pat):~ > r.info -r test
min=1
max=3

The "min=1" means that the value of every cell in the region is null
in at least one of the three input maps. Consequently, the output map
will be all nulls.

Note that the && and || operators follow the same null-propagation
rules as other operators, i.e. if either argument is null the result
will be null.

In particular, the following all evaluate to null, which may be
counterintuitive:

  true || null
  null || true
  false && null
  null && false

Currently, the behaviour of those operators is:

  &&|0 1 N |||0 1 N
  --+----- --+-----
  0 |0 0 N 0 |0 1 N
  1 |0 1 N 1 |1 1 N
  N |N N N N |N N N

Preserving the boolean axioms would give:

  &&|0 1 N |||0 1 N
  --+----- --+-----
  0 |0 0 0 0 |0 1 N
  1 |0 1 N 1 |1 1 1
  N |0 N N N |N 1 N

If you want the normal boolean axioms:

  true || x == true
  false && x == false

to hold even when x is null, you can replace && and || with:

  x || y -> eval(nx=if(isnull(x),0,x), ny=if(isnull(y),0,y),if(nx||ny,1,x||y))
  x && y -> eval(nx=if(isnull(x),1,x), ny=if(isnull(y),1,y),if(!nx||!ny,0,x&&y))

That's rather messy. If desired, I can re-write the && and ||
operators accordingly (or add an alternative set of and/or operators).

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

On Tue, May 02, 2006 at 06:24:09PM +0100, Glynn Clements wrote:

Markus Neteler wrote:

> > What does the following say:
> >
> > r.mapcalc 'test = isnull(modis_t_a_lst1km20040102.daily_min) + isnull(startday_previous) + isnull(condition_previous)'
> > r.info -r test
> >
>
> This test:
>
> GRASS 6.1.cvs (pat):~ > r.mapcalc 'test = isnull(modis_t_a_lst1km20040102.daily_min) + isnull(startday_previous) + isnull(condition_previous)'
> 100%
> GRASS 6.1.cvs (pat):~ > r.info -r test
> min=1
> max=3

The "min=1" means that the value of every cell in the region is null
in at least one of the three input maps. Consequently, the output map
will be all nulls.

Note that the && and || operators follow the same null-propagation
rules as other operators, i.e. if either argument is null the result
will be null.

In particular, the following all evaluate to null, which may be
counterintuitive:

  true || null
  null || true
  false && null
  null && false

Currently, the behaviour of those operators is:

  &&|0 1 N |||0 1 N
  --+----- --+-----
  0 |0 0 N 0 |0 1 N
  1 |0 1 N 1 |1 1 N
  N |N N N N |N N N

Preserving the boolean axioms would give:

  &&|0 1 N |||0 1 N
  --+----- --+-----
  0 |0 0 0 0 |0 1 N
  1 |0 1 N 1 |1 1 1
  N |0 N N N |N 1 N

If you want the normal boolean axioms:

  true || x == true
  false && x == false

to hold even when x is null, you can replace && and || with:

  x || y -> eval(nx=if(isnull(x),0,x), ny=if(isnull(y),0,y),if(nx||ny,1,x||y))
  x && y -> eval(nx=if(isnull(x),1,x), ny=if(isnull(y),1,y),if(!nx||!ny,0,x&&y))

That's rather messy. If desired, I can re-write the && and ||
operators accordingly (or add an alternative set of and/or operators).

To maintain the behaviour, the && and || may remain.
To have an alternative set of and/or operators would be pretty good
(and solve my problem!). In fact, doing the eval mess is rather
complicated and error prone.

Looking forward the alternative set,
thanks for the explanation,

Markus

Markus Neteler wrote:

> If you want the normal boolean axioms:
>
> true || x == true
> false && x == false
>
> to hold even when x is null, you can replace && and || with:
>
> x || y -> eval(nx=if(isnull(x),0,x), ny=if(isnull(y),0,y),if(nx||ny,1,x||y))
> x && y -> eval(nx=if(isnull(x),1,x), ny=if(isnull(y),1,y),if(!nx||!ny,0,x&&y))
>
> That's rather messy. If desired, I can re-write the && and ||
> operators accordingly (or add an alternative set of and/or operators).

To maintain the behaviour, the && and || may remain.
To have an alternative set of and/or operators would be pretty good
(and solve my problem!). In fact, doing the eval mess is rather
complicated and error prone.

Looking forward the alternative set,

I've committed an update which adds the &&& and ||| operators (and the
and2() and or2() functions) with the new behaviour.

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

Glynn,

thanks for submitting the new operators. Here the test report:
- the first condition works fine (for me) now

+ r.info -r modis_t_a_lst1km20040102.daily_min
min=-24.290000
max=-16.510000
+ r.info -r startday_previous
min=1
max=1
+ r.info -r condition_previous
min=1
max=1
+ r.info -r duration
min=1
max=1
+ r.mapcalc 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 &&& (startday_previous == 0 ||| condition_previous == 0), 2, startday_previous)'
100%
+ r.info -r startday
min=1
max=1

... but here I am not sure if it is right (program continues):

+ r.info -r startday_previous
min=1
max=1
+ r.mapcalc 'condition=if(startday - startday_previous > 0 ||| modis_t_a_lst1km20040102.daily_min < -2.0, 1, 0)'
100%
+ r.info -r condition
min=1
max=1
+ r.mapcalc 'duration=if(condition == 1, if(condition_previous == 1 &&& condition == 1, duration + 1, 1), duration)'
100%
+ r.info -r duration
min=-2147483648
max=-2147483648

Should
a = if (1 == 1, if( 1 == 1 &&& 1 == 1, 1 + 1,1 ), 1)

a= 2 instead of null?

Markus

Markus Neteler wrote:

thanks for submitting the new operators. Here the test report:
- the first condition works fine (for me) now

+ r.info -r modis_t_a_lst1km20040102.daily_min
min=-24.290000
max=-16.510000
+ r.info -r startday_previous
min=1
max=1
+ r.info -r condition_previous
min=1
max=1
+ r.info -r duration
min=1
max=1
+ r.mapcalc 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 &&& (startday_previous == 0 ||| condition_previous == 0), 2, startday_previous)'
100%
+ r.info -r startday
min=1
max=1

... but here I am not sure if it is right (program continues):

+ r.info -r startday_previous
min=1
max=1
+ r.mapcalc 'condition=if(startday - startday_previous > 0 ||| modis_t_a_lst1km20040102.daily_min < -2.0, 1, 0)'
100%
+ r.info -r condition
min=1
max=1
+ r.mapcalc 'duration=if(condition == 1, if(condition_previous == 1 &&& condition == 1, duration + 1, 1), duration)'
100%
+ r.info -r duration
min=-2147483648
max=-2147483648

It depends upon the contents of the input files. If any of
condition_previous, condition, or duration contain nulls, you will get
them in the output. Whether the output is all-null depends upon which
cells are null in the inputs.

The exact logic of the last expression is:

  cp=N cp=1 cp=?
c=N N N N
c=1 N d+1 1
c=? d d d

where c = condition, cp = condition_previous, d = duration, N = null,
? = anything other than null or 1.

Note that "condition_previous == 1 &&& condition == 1" can be
simplified to just "condition_previous == 1", as the expression is
only evaluated if "condition == 1" is true.

Also note that the r.info commands indicates that condition and
condition_previous only contain 1 or null, so the logic can be
simplified to:

  cp=N cp=1
c=N N N
c=1 N d+1

Thus the output cell will only be null if all three input cells are
non-null.

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

On Wed, May 03, 2006 at 09:20:05PM +0100, Glynn Clements wrote:

Markus Neteler wrote:
> thanks for submitting the new operators. Here the test report:
> - the first condition works fine (for me) now
>
>
> + r.info -r modis_t_a_lst1km20040102.daily_min
> min=-24.290000
> max=-16.510000
> + r.info -r startday_previous
> min=1
> max=1
> + r.info -r condition_previous
> min=1
> max=1
> + r.info -r duration
> min=1
> max=1
> + r.mapcalc 'startday=if(modis_t_a_lst1km20040102.daily_min < -2.0 &&& (startday_previous == 0 ||| condition_previous == 0), 2, startday_previous)'
> 100%
> + r.info -r startday
> min=1
> max=1
>
>
> ... but here I am not sure if it is right (program continues):
>
>
> + r.info -r startday_previous
> min=1
> max=1
> + r.mapcalc 'condition=if(startday - startday_previous > 0 ||| modis_t_a_lst1km20040102.daily_min < -2.0, 1, 0)'
> 100%
> + r.info -r condition
> min=1
> max=1
> + r.mapcalc 'duration=if(condition == 1, if(condition_previous == 1 &&& condition == 1, duration + 1, 1), duration)'
> 100%
> + r.info -r duration
> min=-2147483648
> max=-2147483648

It depends upon the contents of the input files. If any of
condition_previous, condition, or duration contain nulls, you will get
them in the output. Whether the output is all-null depends upon which
cells are null in the inputs.

The exact logic of the last expression is:

  cp=N cp=1 cp=?
c=N N N N
c=1 N d+1 1
c=? d d d

where c = condition, cp = condition_previous, d = duration, N = null,
? = anything other than null or 1.

Note that "condition_previous == 1 &&& condition == 1" can be
simplified to just "condition_previous == 1", as the expression is
only evaluated if "condition == 1" is true.

Yes, agreed.

Also note that the r.info commands indicates that condition and
condition_previous only contain 1 or null, so the logic can be
simplified to:

  cp=N cp=1
c=N N N
c=1 N d+1

Thus the output cell will only be null if all three input cells are
non-null.

The last sentence I don't understand (sorry for being slow on this).
If all input is 1, I expect to get 2 as result (at least that's my
wish).

Simplified:
  r.mapcalc 'duration=if(condition == 1, if(condition_previous == 1, duration + 1, 1), duration)'

So: if c==1 and cp==1, why not d=d+1=2 ?

From your simplified table I would also expect this result.

thanks
Markus

r.info -r duration
min=-2147483648
max=-2147483648

r.info modified in CVS to report nan,nan for a CELL map of all NULLs.

Hamish

Hamish wrote:

> r.info -r duration
> min=-2147483648
> max=-2147483648

r.info modified in CVS to report nan,nan for a CELL map of all NULLs.

May I suggest "null" rather than "nan"?

"null" is the term normally used in GRASS documentation, while the use
of NaN for FP nulls is an implementation detail.

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

Markus Neteler wrote:

> Also note that the r.info commands indicates that condition and
> condition_previous only contain 1 or null, so the logic can be
> simplified to:
>
> cp=N cp=1
> c=N N N
> c=1 N d+1
>
> Thus the output cell will only be null if all three input cells are
> non-null.

Sorry, that should have read:

  Thus the output cell will only be NON-NULL if all three input
  cells are non-null.

The last sentence I don't understand (sorry for being slow on this).
If all input is 1, I expect to get 2 as result (at least that's my
wish).

Simplified:
  r.mapcalc 'duration=if(condition == 1, if(condition_previous == 1, duration + 1, 1), duration)'

So: if c==1 and cp==1, why not d=d+1=2 ?

From your simplified table I would also expect this result.

d+1 is only 2 if d is 1. If d is null, it d+1 is null.

IOW, if c==1 and cp==1 and d==1, then the result is 2. But that's
three different conditions which have to be met. The other 7 possible
combinations all result in null. Unless there's at least one cell
where the non-null portions of all three input maps overlap, the
output will be all-null.

Try:
  r.mapcalc 'temp = isnull(condition) + isnull(condition_previous) + isnull(duration)'
  r.info -r temp

If the minimum value for temp isn't zero, then every cell is null in
at least one of the three input maps, and thus the output will be
all-null.

More generally, I find the fact that all of your input maps contain
only null and 1 rather odd. That, and the fact that you are testing
whether startday_previous and condition_previous are equal to zero
suggest that something is using null where you really want zero.

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

On Fri, 5 May 2006 02:12:03 +0100
Glynn Clements <glynn@gclements.plus.com> wrote:

Hamish wrote:

> r.info modified in CVS to report nan,nan for a CELL map of all
> NULLs.

May I suggest "null" rather than "nan"?

"null" is the term normally used in GRASS documentation, while the use
of NaN for FP nulls is an implementation detail.

+1

Maciek

--------------------
W polskim Internecie s? setki milion?w stron. My przekazujemy Tobie tylko najlepsze z nich!
http://katalog.panoramainternetu.pl/

Glynn,

Glynn Clements wrote:

Markus Neteler wrote:

Also note that the r.info commands indicates that condition and
condition_previous only contain 1 or null, so the logic can be
simplified to:

cp=N cp=1
c=N N N
c=1 N d+1

Thus the output cell will only be null if all three input cells are
non-null.
     
Sorry, that should have read:

Thus the output cell will only be NON-NULL if all three input
cells are non-null.

The last sentence I don't understand (sorry for being slow on this).
If all input is 1, I expect to get 2 as result (at least that's my
wish).

Simplified:
r.mapcalc 'duration=if(condition == 1, if(condition_previous == 1, duration + 1, 1), duration)'

So: if c==1 and cp==1, why not d=d+1=2 ?

From your simplified table I would also expect this result.
   
d+1 is only 2 if d is 1. If d is null, it d+1 is null.

IOW, if c==1 and cp==1 and d==1, then the result is 2. But that's
three different conditions which have to be met. The other 7 possible
combinations all result in null. Unless there's at least one cell
where the non-null portions of all three input maps overlap, the
output will be all-null.

Try:
r.mapcalc 'temp = isnull(condition) + isnull(condition_previous) + isnull(duration)'
r.info -r temp

If the minimum value for temp isn't zero, then every cell is null in
at least one of the three input maps, and thus the output will be
all-null.

I think that it behaves correctly and I found the problem (see below):

More generally, I find the fact that all of your input maps contain
only null and 1 rather odd. That, and the fact that you are testing
whether startday_previous and condition_previous are equal to zero
suggest that something is using null where you really want zero.

I guess that I figured out the introduction of NULL:
r.mapcalc 'condition=if(startday - startday_previous > 0 |||
modis_t_a_lst1km20040101.daily_min < -2.0, 1, 0)'

If pixels in the satellite image are covered by clouds, they were set to
NULL in the preprocessing.
Null is propagated and looping over the days it "crashes" the algorithms.

It seems that I have think about this, maybe implement a better "reset"
to 0 if a new frost period
is found.

Markus