Project

General

Profile

Download (4.97 KB) Statistics
| Branch: | Revision:
1
#!/usr/bin/python
2
#
3
# Python test script using GRASS to load 8 daily LST grids and calculate
4
# pixel-wise averages excluding missing values, for comparison against
5
# the corresponding 8-day LST product obtained from LP DAAC. Script is
6
# hard-coded to use the 8-day LST grid for tile h09v04 on 2000.03.05,
7
# for no particular reason. Also compares the observed count of non-null
8
# daily LST values (0-8) to the number of clear sky days as indicated in
9
# the 8-day Clear_sky_days layer.
10
#
11
# 8-day target:
12
#  MOD11A2.A2000065.h09v04.005.2007176162644.hdf
13
#
14
# Note that it appears Version 5 8-day means were rounded to the nearest
15
# integer, as implemented below. However, reproducing the Version 4
16
# product instead appears to require truncating the mean. This
17
# difference can be expressed as follows in terms of GRASS mapcalc,
18
# where 'sum' and 'n' are integer rasters:
19
#  * v004: sum/n                <-- integer division
20
#  * v005: round(float(sum)/n)  <-- floating point division, then round
21
#
22
# Script can be run from within an existing GRASS 7 session; all work is
23
# done within a temporary LOCATION that gets removed at the end.
24
# Untested in earlier versions of GRASS.
25
#
26
# Jim Regetz
27
# NCEAS
28
# 16-May-2012
29

    
30
import os, glob, shutil
31
import numpy as np
32
import grass.script as gs
33
import grass.script.array as garray
34

    
35
tmp_location = 'tmp' + str(os.getpid())
36
orig_location = gs.gisenv()['LOCATION_NAME']
37
orig_mapset = gs.gisenv()['MAPSET']
38

    
39
gs.os.environ['GRASS_OVERWRITE'] = '1'
40

    
41
# load 11A2 (8-day) tile of interest
42
name_of_8day_hdf = 'MOD11A2.A2000065.h09v04.005.2007176162644.hdf'
43
# first load daytime LST
44
lst8day = 'HDF4_EOS:EOS_GRID:%s/%s:%s' % (
45
     '/home/layers/data/climate/MOD11A2.005-8day-1km-L3-LST',
46
     name_of_8day_hdf,
47
     'MODIS_Grid_8Day_1km_LST:LST_Day_1km')
48
gs.run_command('r.in.gdal', input=lst8day, output='LST_8day_h09v04',
49
    location=tmp_location)
50

    
51
# switch to new location
52
gs.run_command('g.gisenv', set='LOCATION_NAME=%s' % tmp_location)
53
gs.run_command('g.gisenv', set='MAPSET=PERMANENT')
54

    
55
# set GRASS region to match
56
gs.run_command('g.proj', flags='c',
57
    proj4='+proj=sinu +a=6371007.181 +b=6371007.181 +ellps=sphere')
58
gs.run_command('g.region', rast='LST_8day_h09v04')
59

    
60
# now load clear sky days and generate count raster
61
csd8day = 'HDF4_EOS:EOS_GRID:%s/%s:%s' % (
62
     '/home/layers/data/climate/MOD11A2.005-8day-1km-L3-LST',
63
     name_of_8day_hdf,
64
     'MODIS_Grid_8Day_1km_LST:Clear_sky_days')
65
gs.run_command('r.in.gdal', input=csd8day, output='CSD_8day_h09v04')
66
gs.mapcalc('nCSD_8day_h09v04 = %s' %
67
    '+'.join(['((CSD_8day_h09v04 >> %d) & 1)' % pos for pos in range(8)]))
68

    
69
# load the corresponding dailies
70
ordir = '/home/layers/data/climate/MOD11A1.004-OR-orig-2000'
71
LST = list()
72
CDC = list()
73
for doy in range(65, 72+1):
74
    pathglob = os.path.join(ordir, 'MOD11A1.A2000%03d.h09v04*hdf' % doy)
75
    try:
76
        hdfpath = glob.glob(pathglob)[0]
77
    except:
78
        print '*** problem finding', pathglob, '***'
79
        continue
80
    hdfname = os.path.basename(hdfpath)
81
    LST.append('LST_' + '_'.join(hdfname.split('.')[1:3]))
82
    gs.run_command('r.in.gdal',
83
        input='HDF4_EOS:EOS_GRID:%s:MODIS_Grid_Daily_1km_LST:LST_Day_1km' % hdfpath,
84
        output=LST[-1])
85
    CDC.append('CDC_' + '_'.join(hdfname.split('.')[1:3]))
86
    gs.run_command('r.in.gdal',
87
        input='HDF4_EOS:EOS_GRID:%s:MODIS_Grid_Daily_1km_LST:Clear_day_cov' % hdfpath,
88
        output=CDC[-1])
89

    
90
# generate the 8-day mean and number of observations
91
numerator = '(%s)' % '+'.join(['if(isnull(%s), 0, %s)' % (m, m)
92
    for m in LST])
93
denominator = '(%s)' % '+'.join(['if(!isnull(%s))' % m
94
    for m in LST])
95
gs.mapcalc('nobs_LST_h09v04 = %s' % denominator)
96
gs.mapcalc('mean_LST_h09v04 = round(float(%s)/nobs_LST_h09v04)' % numerator)
97

    
98
# generate the 8-day sum of Clear_day_cov
99
gs.mapcalc('sum_CDC_h09v04 = %s' % '+'.join(['if(isnull(%s), 0, %s)' % (m, m)
100
    for m in CDC]))
101

    
102
gs.os.environ['GRASS_OVERWRITE'] = '0'
103

    
104
# compare LST grid values and report out...
105
mean_theirs = garray.array()
106
mean_theirs.read('LST_8day_h09v04')
107
print 'Average of their 8-day product:', mean_theirs.mean()
108
mean_ours = garray.array()
109
mean_ours.read('mean_LST_h09v04')
110
print 'Average of our 8-day product:', mean_ours.mean()
111
if (mean_ours==mean_theirs).all():
112
    print 'Successfully reproduced LST_Day_1km from', name_of_8day_hdf
113
else:
114
    print 'Failed to reproduce LST_Day_1km from', name_of_8day_hdf
115

    
116
# compare nObs grid values and report out...
117
nobs_theirs = garray.array()
118
nobs_theirs.read('nCSD_8day_h09v04')
119
print 'Average of counts based on Clear_sky_days:', nobs_theirs.mean()
120
nobs_ours = garray.array()
121
nobs_ours.read('nobs_LST_h09v04')
122
print 'Average of our N_obs:', nobs_ours.mean()
123
if (nobs_ours==nobs_theirs).all():
124
    print 'Successfully reproduced Clear_sky_days counts from', name_of_8day_hdf
125
else:
126
    print 'Failed to reproduce Clear_sky_days counts from', name_of_8day_hdf
127

    
128
# clean up
129
gs.run_command('g.gisenv', set='LOCATION_NAME=%s' % orig_location)
130
gs.run_command('g.gisenv', set='MAPSET=%s' % orig_mapset)
131
shutil.rmtree(os.path.join(gs.gisenv()['GISDBASE'], tmp_location))
(3-3/3)