Skip to content

Commit bdb89fc

Browse files
author
Jose Gomez-Dans
committed
Deal with the issue that f2py sets non-assigned optional parameters
as zeros. This was having an effect in the soil model, whereby the soil spectra were assumed to be 0. This has now been solved by having a pure python wrapper that tests whether the optional parameter is available or not, and if not, using the default spectral defined in prosail/dataSpect_P5B.f90 Closes #3
1 parent 7cff431 commit bdb89fc

File tree

4 files changed

+155
-25
lines changed

4 files changed

+155
-25
lines changed

prosail/__init__.py

+137-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,141 @@
11
import numpy as np
2-
from prosail_fortran import run_sail, run_prosail, prospect_5b
2+
from prosail_fortran import run_sail as sail, run_prosail as prosail
3+
from prosail_fortran import prospect_5b
4+
from prosail_fortran import mod_dataspec_p5b as spectral_libs
5+
6+
def run_prosail (n,cab,car,cbrown,cw,cm,lai,lidfa,lidfb,rsoil,psoil,hspot,
7+
tts,tto,psi,typelidf,
8+
soil_spectrum1=None,soil_spectrum2=None ):
9+
"""Run the PROSPECT_5B and SAILh radiative transfer models. The soil
10+
model is a linear mixture model, where two spectra are combined together as
11+
12+
rho_soil = rsoil*(psoil*soil_spectrum1+(1-psoil)*soil_spectrum2)
13+
By default, ``soil_spectrum1`` is a dry soil, and ``soil_spectrum2`` is a
14+
wet soil, so in that case, ``psoil`` is a surface soil moisture parameter.
15+
``rsoil`` is a soil brightness term. You can provide one or the two
16+
soil spectra if you want. The soil spectra must be defined
17+
between 400 and 2500 nm with 1nm spacing.
18+
19+
Parameters
20+
----------
21+
n: float
22+
Leaf layers
23+
cab: float
24+
leaf chlorophyll concentration
25+
car: float
26+
leaf carotenoid concentration
27+
cbrown: float
28+
senescent pigment
29+
cw: float
30+
equivalent leaf water
31+
cm: float
32+
leaf dry matter
33+
lai: float
34+
leaf area index
35+
lidfa: float
36+
a parameter for leaf angle distribution. If ``typliedf``=2, average
37+
leaf inclination angle.
38+
lidfb: float
39+
b parameter for leaf angle distribution. If ``typelidf``=2, ignored
40+
rsoil: float
41+
Soil scalar
42+
psoil: float
43+
Soil scalar
44+
tts: float
45+
Solar zenith angle
46+
tto: float
47+
Sensor zenith angle
48+
psi: float
49+
Relative sensor-solar azimuth angle ( saa - vaa )
50+
soil_spectrum1: 2101-element array
51+
First component of the soil spectrum
52+
soil_spectrum2: 2101-element array
53+
Second component of the soil spectrum
54+
55+
Returns
56+
--------
57+
Directional surface reflectance between 400 and 2500 nm
58+
59+
60+
"""
61+
62+
if soil_spectrum1 is not None:
63+
assert ( len(soil_spectrum1) == 2101 )
64+
else:
65+
soil_spectrum1 = spectral_libs.rsoil1
66+
67+
if soil_spectrum2 is not None:
68+
assert ( len(soil_spectrum1) == 2101 )
69+
else:
70+
soil_spectrum2 = spectral_libs.rsoil1
71+
72+
rho = prosail (n,cab,car,cbrown,cw,cm,lai,lidfa,lidfb,rsoil,psoil,hspot,
73+
tts,tto,psi,typelidf, soil_spectrum1, soil_spectrum2 )
74+
return rho
75+
76+
def run_sail (refl,trans,lai,lidfa,lidfb,rsoil,psoil,hspot,tts,tto,psi,typelidf,
77+
soil_spectrum1=None,soil_spectrum2=None ):
78+
"""Run the SAILh radiative transfer model. The soil model is a linear
79+
mixture model, where two spectra are combined together as
80+
81+
rho_soil = rsoil*(psoil*soil_spectrum1+(1-psoil)*soil_spectrum2)
82+
83+
By default, ``soil_spectrum1`` is a dry soil, and ``soil_spectrum2`` is a
84+
wet soil, so in that case, ``psoil`` is a surface soil moisture parameter.
85+
``rsoil`` is a soil brightness term. You can provide one or the two
86+
soil spectra if you want. The soil spectra, and leaf spectra must be defined
87+
between 400 and 2500 nm with 1nm spacing.
88+
89+
Parameters
90+
----------
91+
refl: 2101-element array
92+
Leaf reflectance
93+
trans: 2101-element array
94+
leaf transmittance
95+
lai: float
96+
leaf area index
97+
lidfa: float
98+
a parameter for leaf angle distribution. If ``typliedf``=2, average
99+
leaf inclination angle.
100+
lidfb: float
101+
b parameter for leaf angle distribution. If ``typelidf``=2, ignored
102+
rsoil: float
103+
Soil scalar
104+
psoil: float
105+
Soil scalar
106+
tts: float
107+
Solar zenith angle
108+
tto: float
109+
Sensor zenith angle
110+
psi: float
111+
Relative sensor-solar azimuth angle ( saa - vaa )
112+
soil_spectrum1: 2101-element array
113+
First component of the soil spectrum
114+
soil_spectrum2: 2101-element array
115+
Second component of the soil spectrum
116+
117+
Returns
118+
--------
119+
Directional surface reflectance between 400 and 2500 nm
120+
121+
122+
"""
123+
124+
125+
if soil_spectrum1 is not None:
126+
assert ( len(soil_spectrum1) == 2101 )
127+
else:
128+
soil_spectrum1 = spectral_libs.rsoil1
129+
130+
if soil_spectrum2 is not None:
131+
assert ( len(soil_spectrum1) == 2101 )
132+
else:
133+
soil_spectrum2 = spectral_libs.rsoil1
134+
135+
rho = sail (refl,trans,lai,lidfa,lidfb,rsoil,psoil,hspot,tts,tto,psi,typelidf,
136+
soil_spectrum1, soil_spectrum2 )
137+
return rho
138+
3139

4140

5141
def trans_prosail ( N, cab, car, cbrown, cw, cm, lai, lidfa, lidfb, rsoil, psoil, \

prosail/dataSpec_P5B.f90

+1-1
Original file line numberDiff line numberDiff line change
@@ -2268,4 +2268,4 @@ MODULE MOD_dataSpec_P5B
22682268
4.960E-02,4.960E-02,4.960E-02,4.960E-02,4.959E-02,4.959E-02,4.944E-02,4.930E-02,4.915E-02,4.900E-02,&
22692269
4.885E-02/
22702270

2271-
END
2271+
END

prosail/prosail_fortran.pyf

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ python module prosail_fortran ! in
1818
real*8 dimension(2101) :: es
1919
integer, parameter,optional :: nw=2101
2020
end module mod_dataspec_p5b
21-
subroutine run_prosail(n,cab,car,cbrown,cw,cm,lai,lidfa,lidfb,rsoil,psoil,hspot,tts,tto,psi,typelidf,retval, soil_spectrum1, soil_spectrum2) ! in :prosail_fortran:run_prosail.f90
21+
subroutine run_prosail(n,cab,car,cbrown,cw,cm,lai,lidfa,lidfb,rsoil,psoil,hspot,tts,tto,psi,typelidf,soil_spectrum1, soil_spectrum2, retval) ! in :prosail_fortran:run_prosail.f90
2222
use mod_sail
2323
use mod_angle
2424
use mod_flag_util
@@ -41,8 +41,8 @@ python module prosail_fortran ! in
4141
real*8 intent(in) :: tto
4242
real*8 intent(in) :: psi
4343
integer intent(in) :: typelidf
44-
real*8, dimension(2101), intent(in), optional :: soil_spectrum1
45-
real*8, dimension(2101), intent(in), optional :: soil_spectrum2
44+
real*8, dimension(2101), intent(in) :: soil_spectrum1
45+
real*8, dimension(2101), intent(in) :: soil_spectrum2
4646
real*8 dimension(2101),intent(out) :: retval
4747
end subroutine run_prosail
4848
subroutine run_sail(refl,trans,lai,lidfa,lidfb,rsoil,psoil,hspot,tts,tto,psi,typelidf,soil_spectrum1, soil_spectrum2, retval) ! in :prosail_fortran:run_prosail.f90
@@ -64,8 +64,8 @@ python module prosail_fortran ! in
6464
real*8 intent(in) :: tto
6565
real*8 intent(in) :: psi
6666
integer intent(in) :: typelidf
67-
real*8,dimension(2101),intent(in),optional :: soil_spectrum1
68-
real*8,dimension(2101),intent(in),optional :: soil_spectrum2
67+
real*8,dimension(2101),intent(in) :: soil_spectrum1
68+
real*8,dimension(2101),intent(in) :: soil_spectrum2
6969
real*8 dimension(2101),intent(out) :: retval
7070
end subroutine run_sail
7171
subroutine prospect_5b(n,cab,car,cbrown,cw,cm,rt) ! in :prosail_fortran:prospect_5B.f90

prosail/run_prosail.f90

+12-18
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ SUBROUTINE run_prosail ( N, Cab, Car, Cbrown, Cw, Cm, lai, LIDFa, LIDFb, &
2121
INTEGER, intent(in) :: TypeLidf
2222
REAL*8,ALLOCATABLE,SAVE :: resh(:),resv(:)
2323
REAL*8,ALLOCATABLE,SAVE :: rsoil0(:),PARdiro(:),PARdifo(:)
24-
REAL*8, dimension(nw), intent(in), optional :: soil_spectrum1
25-
REAL*8, dimension(nw), intent(in), optional :: soil_spectrum2
24+
REAL*8, dimension(nw), intent(in) :: soil_spectrum1
25+
REAL*8, dimension(nw), intent(in) :: soil_spectrum2
26+
2627
INTEGER :: ii
2728
REAL*8 :: ihot, skyl
2829
! ANGLE CONVERSION
@@ -85,13 +86,11 @@ SUBROUTINE run_prosail ( N, Cab, Car, Cbrown, Cw, Cm, lai, LIDFa, LIDFb, &
8586
ALLOCATE (rsoil0(nw))
8687
!psoil = 1. ! soil factor (psoil=0: wet soil / psoil=1: dry soil)
8788
! rsoil : soil brightness term
88-
if ( present(soil_spectrum1) ) then
89-
Rsoil1 = soil_spectrum1
90-
endif
91-
if ( present ( soil_spectrum2 ) ) then
92-
Rsoil2 = soil_spectrum2
93-
endif
94-
rsoil0=rsoil*(psoil*Rsoil1+(1-psoil)*Rsoil2)
89+
90+
91+
92+
rsoil0=rsoil*(psoil*soil_spectrum1+(1-psoil)*soil_spectrum2)
93+
9594

9695
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9796
!! 4SAIL canopy structure parm !!
@@ -168,8 +167,9 @@ SUBROUTINE run_sail ( refl, trans, lai, LIDFa, LIDFb, &
168167
INTEGER, intent(in) :: TypeLidf
169168
REAL*8,ALLOCATABLE,SAVE :: resh(:),resv(:)
170169
REAL*8,ALLOCATABLE,SAVE :: rsoil0(:),PARdiro(:),PARdifo(:)
171-
REAL*8, dimension(nw), intent(in), optional :: soil_spectrum1
172-
REAL*8, dimension(nw), intent(in), optional :: soil_spectrum2
170+
REAL*8, dimension(nw), intent(in) :: soil_spectrum1
171+
REAL*8, dimension(nw), intent(in) :: soil_spectrum2
172+
173173
INTEGER :: ii
174174
REAL*8 :: ihot, skyl
175175
! ANGLE CONVERSION
@@ -232,14 +232,8 @@ SUBROUTINE run_sail ( refl, trans, lai, LIDFa, LIDFb, &
232232
ALLOCATE (rsoil0(nw))
233233
!psoil = 1. ! soil factor (psoil=0: wet soil / psoil=1: dry soil)
234234
! rsoil : soil brightness term
235-
if ( present(soil_spectrum1) ) then
236-
Rsoil1 = soil_spectrum1
237-
endif
238-
if ( present ( soil_spectrum2 ) ) then
239-
Rsoil2 = soil_spectrum2
240-
endif
241235

242-
rsoil0=rsoil*(psoil*Rsoil1+(1-psoil)*Rsoil2)
236+
rsoil0=rsoil*(psoil*soil_spectrum1+(1-psoil)*soil_spectrum2)
243237

244238
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
245239
!! 4SAIL canopy structure parm !!

0 commit comments

Comments
 (0)