Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
geomultisens
pyrsr
Commits
6a19fcba
Commit
6a19fcba
authored
Aug 21, 2019
by
Daniel Scheffler
Browse files
Refactored the term 'srf' to 'rsr'.
Signed-off-by:
Daniel Scheffler
<
danschef@gfz-potsdam.de
>
parent
e73589e3
Changes
1
Hide whitespace changes
Inline
Side-by-side
pyrsr/rsr.py
View file @
6a19fcba
...
...
@@ -27,20 +27,20 @@ def RSR_reader(satellite, sensor, no_thermal=False, no_pan=False, v=False):
:param v: verbose mode
"""
# LayerBandsAssignment = META.get_LayerBandsAssignment(GMS_id, no_thermal=no_thermal, no_pan=no_pan)
SR
F
_dict
=
collections
.
OrderedDict
()
SR
F
_dir
=
os
.
path
.
join
(
__path__
[
0
],
'data'
,
satellite
,
sensor
)
R
SR_dict
=
collections
.
OrderedDict
()
R
SR_dir
=
os
.
path
.
join
(
__path__
[
0
],
'data'
,
satellite
,
sensor
)
for
bandname
in
glob
(
os
.
path
.
join
(
SR
F
_dir
,
'band_*'
)):
SR
F
_path
=
os
.
path
.
join
(
SR
F
_dir
,
bandname
)
for
bandname
in
glob
(
os
.
path
.
join
(
R
SR_dir
,
'band_*'
)):
R
SR_path
=
os
.
path
.
join
(
R
SR_dir
,
bandname
)
try
:
SR
F
_dict
[
bandname
]
=
np
.
loadtxt
(
SR
F
_path
,
skiprows
=
1
)
R
SR_dict
[
bandname
]
=
np
.
loadtxt
(
R
SR_path
,
skiprows
=
1
)
if
v
:
print
(
'Reading SR
F
for %s %s, %s...'
%
(
satellite
,
sensor
,
bandname
))
print
(
'Reading
R
SR for %s %s, %s...'
%
(
satellite
,
sensor
,
bandname
))
except
FileNotFoundError
:
raise
FileNotFoundError
(
'No spectral response functions found for %s %s %s at %s! >None< is returned.'
%
(
satellite
,
sensor
,
bandname
,
SR
F
_path
))
%
(
satellite
,
sensor
,
bandname
,
R
SR_path
))
return
SR
F
_dict
return
R
SR_dict
class
RelativeSpectralResponse
(
object
):
...
...
@@ -65,9 +65,9 @@ class RelativeSpectralResponse(object):
if
wvl_unit
not
in
[
'micrometers'
,
'nanometers'
]:
raise
ValueError
(
'Unknown wavelength unit %s.'
%
wvl_unit
)
self
.
sr
fs
_wvl
=
[]
# wavelength positions with 1 nm precision
self
.
sr
f
s
=
{}
#
srf
values with 1 nm precision
self
.
sr
f
s_norm01
=
{}
#
srf
values with 1 nm precision
self
.
r
sr_wvl
=
[]
# wavelength positions with 1 nm precision
self
.
r
srs
=
{}
#
RSR
values with 1 nm precision
self
.
r
srs_norm01
=
{}
#
RSR
values with 1 nm precision
self
.
bands
=
[]
self
.
wvl
=
[]
self
.
wvl_unit
=
wvl_unit
...
...
@@ -84,64 +84,64 @@ class RelativeSpectralResponse(object):
self
.
from_satellite_sensor
(
satellite
,
sensor
)
def
from_satellite_sensor
(
self
,
satellite
,
sensor
):
sr
f
_dict
=
RSR_reader
(
satellite
,
sensor
,
no_thermal
=
self
.
no_thermal
,
no_pan
=
self
.
no_pan
,
r
sr_dict
=
RSR_reader
(
satellite
,
sensor
,
no_thermal
=
self
.
no_thermal
,
no_pan
=
self
.
no_pan
,
v
=
self
.
v
)
# type: collections.OrderedDict # (ordered according to LBA)
return
self
.
from_dict
(
sr
f
_dict
)
return
self
.
from_dict
(
r
sr_dict
)
def
from_dict
(
self
,
sr
f
_dict
):
def
from_dict
(
self
,
r
sr_dict
):
# type: (collections.OrderedDict) -> RelativeSpectralResponse
"""Create an instance of
SRF
from a dictionary.
"""Create an instance of
RelativeSpectralResponse
from a dictionary.
:param sr
f
_dict: {'key_LayerBandsAssignment': <2D array: cols=[wvl,resp],rows=samples>}
:param
r
sr_dict: {'key_LayerBandsAssignment': <2D array: cols=[wvl,resp],rows=samples>}
"""
is_nm
=
[
300
<
np
.
max
(
sr
f
_dict
[
band
][:,
0
])
<
15000
for
band
in
sr
f
_dict
]
assert
len
(
set
(
is_nm
))
==
1
,
"'sr
f
_dict' must contain only one wavelength unit."
is_nm
=
[
300
<
np
.
max
(
r
sr_dict
[
band
][:,
0
])
<
15000
for
band
in
r
sr_dict
]
assert
len
(
set
(
is_nm
))
==
1
,
"'
r
sr_dict' must contain only one wavelength unit."
scale_factor
=
1
if
is_nm
[
0
]
else
1000
all_wvls
=
np
.
concatenate
(
list
((
arr
[:,
0
]
for
key
,
arr
in
sr
f
_dict
.
items
())))
*
scale_factor
all_wvls
=
np
.
concatenate
(
list
((
arr
[:,
0
]
for
key
,
arr
in
r
sr_dict
.
items
())))
*
scale_factor
wvl
=
np
.
arange
(
all_wvls
.
min
(),
all_wvls
.
max
()
+
self
.
specres_nm
,
self
.
specres_nm
).
astype
(
np
.
int16
)
df
=
DataFrame
(
index
=
wvl
)
bandnames
=
[]
for
band
in
sr
f
_dict
:
# = OrderedDict -> order follows LayerBandsAssignment
for
band
in
r
sr_dict
:
# = OrderedDict -> order follows LayerBandsAssignment
bandname
=
band
if
not
self
.
format_bandnames
else
(
'B%s'
%
band
if
len
(
band
)
==
2
else
'B0%s'
%
band
)
bandnames
.
append
(
bandname
)
sr
f
s
=
sr
f
_dict
[
band
][:,
1
]
wvls
=
np
.
array
(
sr
f
_dict
[
band
][:,
0
]
*
scale_factor
)
r
srs
=
r
sr_dict
[
band
][:,
1
]
wvls
=
np
.
array
(
r
sr_dict
[
band
][:,
0
]
*
scale_factor
)
# interpolate input SR
F
s to target spectral resolution
# interpolate input
R
SRs to target spectral resolution
wvl_s
=
wvl
[
np
.
abs
(
wvl
-
min
(
wvls
)).
argmin
()]
wvl_e
=
wvl
[
np
.
abs
(
wvl
-
max
(
wvls
)).
argmin
()]
wvls_tgtres
=
np
.
arange
(
wvl_s
,
wvl_e
+
self
.
specres_nm
,
self
.
specres_nm
).
astype
(
np
.
int16
)
sr
f
s_tgtres
=
interp1d
(
wvls
,
sr
f
s
,
bounds_error
=
False
,
fill_value
=
0
,
kind
=
'linear'
)(
wvls_tgtres
)
r
srs_tgtres
=
interp1d
(
wvls
,
r
srs
,
bounds_error
=
False
,
fill_value
=
0
,
kind
=
'linear'
)(
wvls_tgtres
)
# join SR
F
for the current band to df
df
=
df
.
join
(
Series
(
sr
f
s_tgtres
,
index
=
wvls_tgtres
,
name
=
bandname
))
# join
R
SR for the current band to df
df
=
df
.
join
(
Series
(
r
srs_tgtres
,
index
=
wvls_tgtres
,
name
=
bandname
))
df
=
df
.
fillna
(
0
)
wvl
=
np
.
array
(
df
.
index
.
astype
(
np
.
float
))
sr
f
s_norm01
=
df
.
to_dict
(
orient
=
'series'
)
# type: Dict[Series]
r
srs_norm01
=
df
.
to_dict
(
orient
=
'series'
)
# type: Dict[Series]
################
# set attributes
################
for
bN
in
sr
f
s_norm01
:
self
.
sr
f
s_norm01
[
bN
]
=
sr
f
=
np
.
array
(
sr
f
s_norm01
[
bN
],
dtype
=
np
.
float
)
self
.
sr
f
s
[
bN
]
=
sr
f
/
np
.
trapz
(
x
=
wvl
,
y
=
sr
f
)
# TODO seems like we NEED nanometers here; BUT WHY??
for
bN
in
r
srs_norm01
:
self
.
r
srs_norm01
[
bN
]
=
r
sr
=
np
.
array
(
r
srs_norm01
[
bN
],
dtype
=
np
.
float
)
self
.
r
srs
[
bN
]
=
r
sr
/
np
.
trapz
(
x
=
wvl
,
y
=
r
sr
)
# TODO seems like we NEED nanometers here; BUT WHY??
self
.
sr
fs
_wvl
=
np
.
array
(
wvl
)
self
.
r
sr_wvl
=
np
.
array
(
wvl
)
self
.
bands
=
bandnames
# FIXME this is not the GMS algorithm to calculate center wavelengths
# calculate center wavelengths
# TODO seems like we NEED nanometers here; BUT WHY??:
self
.
wvl
=
np
.
array
([
np
.
trapz
(
x
=
self
.
sr
fs
_wvl
,
y
=
self
.
sr
fs
_wvl
*
self
.
sr
f
s
[
band
])
for
band
in
self
.
bands
])
self
.
wvl
=
np
.
array
([
np
.
trapz
(
x
=
self
.
r
sr_wvl
,
y
=
self
.
r
sr_wvl
*
self
.
r
srs
[
band
])
for
band
in
self
.
bands
])
# self.wvl = self.wvl if self.wvl_unit == 'micrometers' else np.array([int(i) for i in self.wvl])
self
.
sr
fs
_wvl
=
self
.
sr
fs
_wvl
if
self
.
wvl_unit
==
'nanometers'
else
self
.
sr
fs
_wvl
/
1000
self
.
r
sr_wvl
=
self
.
r
sr_wvl
if
self
.
wvl_unit
==
'nanometers'
else
self
.
r
sr_wvl
/
1000
self
.
wvl
=
self
.
wvl
if
self
.
wvl_unit
==
'nanometers'
else
self
.
wvl
/
1000
self
.
conv
.
update
({
key
:
value
for
key
,
value
in
zip
(
self
.
bands
,
self
.
wvl
)})
...
...
@@ -152,7 +152,7 @@ class RelativeSpectralResponse(object):
def
instrument
(
self
,
bands
):
return
{
'rspf'
:
np
.
vstack
([
self
[
band
]
for
band
in
bands
]),
'wvl_rsp'
:
np
.
copy
(
self
.
sr
fs
_wvl
),
'wvl_rsp'
:
np
.
copy
(
self
.
r
sr_wvl
),
'wvl_inst'
:
np
.
copy
(
self
.
wvl
),
'sol_irr'
:
None
}
...
...
@@ -160,26 +160,26 @@ class RelativeSpectralResponse(object):
def
convert_wvl_unit
(
self
):
"""Convert the wavelength unit to nanometers if they are in micrometers or vice versa."""
factor
=
1
/
1000
if
self
.
wvl_unit
==
'nanometers'
else
1000
self
.
sr
fs
_wvl
=
self
.
sr
fs
_wvl
*
factor
self
.
r
sr_wvl
=
self
.
r
sr_wvl
*
factor
self
.
wvl
=
self
.
wvl
*
factor
self
.
wvl_unit
=
'nanometers'
if
self
.
wvl_unit
==
'micrometers'
else
'micrometers'
def
__call__
(
self
,
band
):
return
self
.
sr
f
s
[
band
]
return
self
.
r
srs
[
band
]
def
__getitem__
(
self
,
band
):
return
self
.
sr
f
s
[
band
]
return
self
.
r
srs
[
band
]
def
__iter__
(
self
):
for
band
in
self
.
bands
:
yield
self
[
band
]
def
plot_sr
f
s
(
self
,
figsize
:
tuple
=
(
15
,
5
),
band
:
Union
[
str
,
List
[
str
]]
=
None
,
normalize
:
bool
=
True
):
def
plot_
r
srs
(
self
,
figsize
:
tuple
=
(
15
,
5
),
band
:
Union
[
str
,
List
[
str
]]
=
None
,
normalize
:
bool
=
True
):
"""Show a plot of all spectral response functions.
:param figsize: figure size of the plot
:param band: band key to plot a single band instead of all bands
:param normalize: normalize SR
F
s to 0-1 (default: True)
:param normalize: normalize
R
SRs to 0-1 (default: True)
"""
if
band
and
band
not
in
self
.
bands
:
raise
ValueError
(
"Parameter 'band' must be a string out of those: %s."
...
...
@@ -188,8 +188,8 @@ class RelativeSpectralResponse(object):
plt
.
figure
(
figsize
=
figsize
)
bands2plot
=
[
band
]
if
band
else
self
.
bands
for
band
in
bands2plot
:
sr
f
s
=
list
(
self
.
sr
f
s_norm01
[
band
])
if
normalize
else
list
(
self
.
sr
f
s
[
band
])
plt
.
plot
(
self
.
sr
fs
_wvl
,
sr
f
s
,
'-'
,
label
=
'Band %s'
%
band
)
r
srs
=
list
(
self
.
r
srs_norm01
[
band
])
if
normalize
else
list
(
self
.
r
srs
[
band
])
plt
.
plot
(
self
.
r
sr_wvl
,
r
srs
,
'-'
,
label
=
'Band %s'
%
band
)
plt
.
title
(
' '
.
join
([
'Spectral response functions'
,
self
.
satellite
,
self
.
sensor
]))
plt
.
xlabel
(
'wavelength [%s]'
%
self
.
wvl_unit
)
plt
.
ylabel
(
'spectral response'
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment