-
Notifications
You must be signed in to change notification settings - Fork 81
/
FishHabitatSuitability.py
105 lines (89 loc) · 3.58 KB
/
FishHabitatSuitability.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import numpy as np
class FishHabitatSuitability():
def __init__(self):
self.name = "Fish Habitat Suitability Function"
self.description = "Computes fish habitat suitability by depth."
self.depth = 0.0
def getParameterInfo(self):
return [
{
'name': 'temperature',
'dataType': 'raster',
'value': None,
'required': True,
'displayname': "Surface Temperature Raster",
'description': "A single-band raster where values represent surface temperature in Celsius.",
},
{
'name': 'salinity',
'dataType': 'raster',
'value': None,
'required': True,
'displayname': "Surface Salinty Raster",
'description': "A single-band raster where values represent surface salinity in PSU.",
},
{
'name': 'depth',
'dataType': 'numeric',
'value': self.depth,
'required': True,
'displayname': "Ocean Depth",
'description': "A numeric value representing ocean depth in meters.",
},
]
def getConfiguration(self, **scalars):
return {
'inheritProperties': 2 | 4 | 8, # inherit everything but the pixel type (1)
'invalidateProperties': 2 | 4 | 8 # invalidate these aspects because we are modifying pixels and key metadata
}
def updateRasterInfo(self, **kwargs):
kwargs['output_info']['bandCount'] = 1
kwargs['output_info']['pixelType'] = 'f4'
kwargs['output_info']['statistics'] = ({'minimum': 0.0, 'maximum': 1.0}, )
kwargs['output_info']['histogram'] = ()
self.depth = abs(float(kwargs['depth']))
# piece-wise linear parameters for depth...
d = self.depth
dMinA = 0
dMinP = 2
dMaxP = 11
dMaxA = 20
if d < dMinA or d > dMaxA:
d = 0.0
elif d <= dMinP:
d = (d - dMinA) / (dMinP - dMinA)
elif d >= dMaxP:
d = (d - dMaxA) / (dMaxP - dMaxA)
else:
d = 1
self.depth = d
return kwargs
def updatePixels(self, tlc, shape, props, **pixelBlocks):
t = np.array(pixelBlocks['temperature_pixels'], dtype='f4', copy=False)
s = np.array(pixelBlocks['salinity_pixels'], dtype='f4', copy=False)
# piece-wise linear parameters for temperature...
tMinA = 17.99
tMinP = 26.37
tMaxP = 29.15
tMaxA = 33.35
np.putmask(t, t <= tMinP, (t - tMinA) / (tMinP - tMinA))
np.putmask(t, t >= tMaxP, (t - tMaxA) / (tMaxP - tMaxA))
np.putmask(t, (t > tMinP) & (t < tMaxP), 1)
np.putmask(t, t < 0, 0)
# piece-wise linear parameters for salinity...
sMinA = 28.81
sMinP = 32.27
sMaxP = 35.81
sMaxA = 36.79
np.putmask(s, s <= sMinP, (s - sMinA) / (sMinP - sMinA))
np.putmask(s, s >= sMaxP, (s - sMaxA) / (sMaxP - sMaxA))
np.putmask(s, (s > sMinP) & (s < sMaxP), 1)
np.putmask(s, s < 0, 0)
# get overall probability by tying all conditions
pixelBlocks['output_pixels'] = np.array(t * s * self.depth).astype(props['pixelType'], copy=False)
return pixelBlocks
def updateKeyMetadata(self, names, bandIndex, **keyMetadata):
if bandIndex == -1:
keyMetadata['datatype'] = 'Scientific'
keyMetadata['variable'] = 'FishHabitatSuitability'
return keyMetadata