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
NearRealTimeCTDAS
CTDAS
Commits
1de4ae31
Commit
1de4ae31
authored
Feb 24, 2020
by
Woude, Auke van der
Browse files
Added up and downwind stations; use datetime instead of index for times
parent
fd559da1
Changes
1
Show whitespace changes
Inline
Side-by-side
da/ffdas/observationoperator.py
View file @
1de4ae31
...
@@ -57,7 +57,6 @@ d13C = -9.
...
@@ -57,7 +57,6 @@ d13C = -9.
Nav
=
6.023e23
# molecules/mole Avogadro's number
Nav
=
6.023e23
# molecules/mole Avogadro's number
tau_14CO2
=
5700
*
365
*
24
*
3600.
# s half life time of 14CO2
tau_14CO2
=
5700
*
365
*
24
*
3600.
# s half life time of 14CO2
lambda_14CO2
=
np
.
log
(
2
)
/
tau_14CO2
# s-1 radioactive decay
lambda_14CO2
=
np
.
log
(
2
)
/
tau_14CO2
# s-1 radioactive decay
tau_14CO2
=
5700
*
365
*
24
*
3600.
# s half life time of 14CO2
MOL2UMOL
=
1.0e6
MOL2UMOL
=
1.0e6
KMOL2UMOL
=
1.0e9
KMOL2UMOL
=
1.0e9
...
@@ -180,7 +179,8 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -180,7 +179,8 @@ class STILTObservationOperator(ObservationOperator):
if
line
[
0
]
==
'#'
:
continue
if
line
[
0
]
==
'#'
:
continue
else
:
else
:
ct_
,
filename
,
lat
,
lon
,
height
,
species_name
,
species_mass
,
recalc_factor
,
*
_
=
line
.
split
(
','
)
ct_
,
filename
,
lat
,
lon
,
height
,
species_name
,
species_mass
,
recalc_factor
,
*
_
=
line
.
split
(
','
)
sitename
=
filename
.
split
(
'_'
)[
1
]
two_names
=
any
(
x
in
filename
for
x
in
[
'UW'
,
'DW'
])
sitename
=
(
'_'
.
join
(
filename
.
split
(
'_'
)[
1
:
2
+
two_names
]))
ct
=
int
(
ct_
)
-
1
# Set the counter
ct
=
int
(
ct_
)
-
1
# Set the counter
self
.
obsnc
.
append
(
filename
)
self
.
obsnc
.
append
(
filename
)
self
.
sitenames
.
append
(
sitename
)
self
.
sitenames
.
append
(
sitename
)
...
@@ -206,7 +206,6 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -206,7 +206,6 @@ class STILTObservationOperator(ObservationOperator):
self
.
ops_sector
=
[]
self
.
ops_sector
=
[]
self
.
ops_id
=
[]
self
.
ops_id
=
[]
self
.
temporal_var
=
[]
self
.
temporal_var
=
[]
ct
=
0
for
line
in
lines
:
for
line
in
lines
:
if
line
[
0
]
==
'#'
:
continue
if
line
[
0
]
==
'#'
:
continue
else
:
else
:
...
@@ -215,7 +214,6 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -215,7 +214,6 @@ class STILTObservationOperator(ObservationOperator):
if
id
!=
0
:
if
id
!=
0
:
self
.
ops_sector
.
append
(
ct
)
self
.
ops_sector
.
append
(
ct
)
self
.
ops_id
.
append
(
id
)
self
.
ops_id
.
append
(
id
)
ct
+=
1
self
.
temporal_var
.
append
(
temporal_var
)
self
.
temporal_var
.
append
(
temporal_var
)
#set time control variables for this cycle
#set time control variables for this cycle
...
@@ -244,6 +242,18 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -244,6 +242,18 @@ class STILTObservationOperator(ObservationOperator):
self
.
datelist
.
append
(
dumdate
)
self
.
datelist
.
append
(
dumdate
)
dumdate
=
dumdate
+
dt
dumdate
=
dumdate
+
dt
self
.
get_c14_time_profile
()
def
get_c14_time_profile
():
"""Function that loads the nuclear power temporal variation"""
# Get the time profiles of the nuclear plants
temp_distribution_file
=
self
.
model_settings
[
'nuclear_timeprofiledir'
]
workbook
=
xlrd
.
open_workbook
(
temp_distribution_file
)
worksheet
=
workbook
.
sheet_by_name
(
'Sheet1'
)
time_profile_nuc
=
np
.
array
(
worksheet
.
col_values
(
19
)
self
.
nuc_time_profile
=
time_profile_nuc
### !!!! Only cache if made dependent on datepoint/datetime !!!!
### !!!! Only cache if made dependent on datepoint/datetime !!!!
def
get_time_index_nc
(
self
,
time
=
None
):
def
get_time_index_nc
(
self
,
time
=
None
):
"""Function that gets the time index from the flux files
"""Function that gets the time index from the flux files
...
@@ -332,12 +342,12 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -332,12 +342,12 @@ class STILTObservationOperator(ObservationOperator):
return
background_conc
return
background_conc
@
cached
@
cached
def
get_background_orig
(
self
,
i_species
,
i_
datepoint
):
def
get_background_orig
(
self
,
i_species
,
datepoint
):
"""Function that finds the background concentration, non-time dependent and hard-coded.
"""Function that finds the background concentration, non-time dependent and hard-coded.
Input:
Input:
i_species: int: the index of the species for which the background should be found
i_species: int: the index of the species for which the background should be found
i_loc : int: the index of the locatin for which the background should be found
i_loc : int: the index of the locatin for which the background should be found
datepoint: datetime
.datetime: the datetime of
the background concentration
datepoint: datetime
for which
the background concentration
should be found.
Returns:
Returns:
float: background concentration
float: background concentration
"""
"""
...
@@ -346,12 +356,12 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -346,12 +356,12 @@ class STILTObservationOperator(ObservationOperator):
return
backgrounds
[
i_species
]
return
backgrounds
[
i_species
]
@
cached
@
cached
def
get_c14_concentration
(
self
,
i_loc
,
i_
datepoint
,
gpp
,
ter
,
ff_flux
,
background
):
def
get_c14_concentration
(
self
,
i_loc
,
datepoint
,
gpp
,
ter
,
ff_flux
,
background
):
"""Function that gets the c14 concentration based on the emissions by the biosphere,
"""Function that gets the c14 concentration based on the emissions by the biosphere,
fossil fuels and nuclear power. The constants are defined at the top of this script.
fossil fuels and nuclear power. The constants are defined at the top of this script.
Input:
Input:
i_loc: int: the index of the location for which the c14 concentration should be calculated
i_loc: int: the index of the location for which the c14 concentration should be calculated
i_
datepoint:
int: the index of the datepoint
for which the c14 should be calculated
datepoint:
datepoint: datetime
for which the c14
concentration
should be calculated
gpp: float: The gross primary production in umol/s
gpp: float: The gross primary production in umol/s
ter: float: The total ecosystem respiration in umol/s
ter: float: The total ecosystem respiration in umol/s
ff_flux: float: The fossil fuel flux in umol/s
ff_flux: float: The fossil fuel flux in umol/s
...
@@ -359,7 +369,6 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -359,7 +369,6 @@ class STILTObservationOperator(ObservationOperator):
Returns:
Returns:
float: The C14 in ppm
float: The C14 in ppm
float: Delta(14C) """
float: Delta(14C) """
datepoint
=
self
.
datelist
[
i_datepoint
]
# First, get the footprint
# First, get the footprint
site
=
self
.
sitenames
[
i_loc
]
site
=
self
.
sitenames
[
i_loc
]
foot
=
self
.
get_foot
(
i_loc
,
datepoint
)
foot
=
self
.
get_foot
(
i_loc
,
datepoint
)
...
@@ -367,16 +376,12 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -367,16 +376,12 @@ class STILTObservationOperator(ObservationOperator):
indices
=
self
.
get_time_indices
(
datepoint
)
indices
=
self
.
get_time_indices
(
datepoint
)
# Get the fluxes from the nuclear plants
# Get the fluxes from the nuclear plants
# Get the time profiles of the nuclear plants
nuclear_time_profile
=
self
.
nuc_time_profile
[
indices
]
temp_distribution_file
=
self
.
model_settings
[
'nuclear_timeprofiledir'
]
workbook
=
xlrd
.
open_workbook
(
temp_distribution_file
)
worksheet
=
workbook
.
sheet_by_name
(
'Sheet1'
)
time_profile_nuc
=
np
.
array
(
worksheet
.
col_values
(
19
,
start_rowx
=
indices
.
start
,
end_rowx
=
indices
.
stop
))
# Get the fluxes and multiply them by the footprint and time profile
# Get the fluxes and multiply them by the footprint and time profile
# Note that the unit is already in Delta notation
# Note that the unit is already in Delta notation
file
=
self
.
model_settings
[
'nuclear_fluxdir'
]
file
=
self
.
model_settings
[
'nuclear_fluxdir'
]
nuc_flux
=
self
.
get_nc_variable
(
file
,
'E_14CO2_nuc'
)
nuc_flux
=
self
.
get_nc_variable
(
file
,
'E_14CO2_nuc'
)
nuc_flux
=
(
time_profile
_nuc
[:,
None
,
None
]
*
nuc_flux
[
None
,:]
*
foot
).
sum
()
nuc_flux
=
(
nuclear_
time_profile
[:,
None
,
None
]
*
nuc_flux
[
None
,:]
*
foot
).
sum
()
# now get the disequilibrium flux
# now get the disequilibrium flux
file
=
self
.
model_settings
[
'biosphere_fluxdir'
]
file
=
self
.
model_settings
[
'biosphere_fluxdir'
]
...
@@ -392,11 +397,11 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -392,11 +397,11 @@ class STILTObservationOperator(ObservationOperator):
co2_total
=
gpp
+
ter
+
ff_flux
+
background
co2_total
=
gpp
+
ter
+
ff_flux
+
background
print
(
'ff'
,
co2_14_ff
*
1E12
)
#
print('ff', co2_14_ff * 1E12)
print
(
'bg'
,
co2_14_bg
*
1E12
)
#
print('bg', co2_14_bg * 1E12)
print
(
'gpp'
,
alpha_14CO2_gpp
*
R_14CO2_bg
*
gpp
*
1E12
)
#
print('gpp', alpha_14CO2_gpp * R_14CO2_bg * gpp * 1E12)
print
(
'ter'
,
R_14CO2_ter
*
ter
)
#
print('ter', R_14CO2_ter * ter)
print
(
'nuc'
,
nuc_flux
)
#
print('nuc', nuc_flux)
# Conversion 14CO2 in ppm to DELTA ----
# Conversion 14CO2 in ppm to DELTA ----
Rm
=
(
co2_14_total
*
MASS_14CO2
)
/
(
co2_total
*
MASS_CO2
)
# ppm to mass ratio (kg 14CO2 / kgCO2)
Rm
=
(
co2_14_total
*
MASS_14CO2
)
/
(
co2_total
*
MASS_CO2
)
# ppm to mass ratio (kg 14CO2 / kgCO2)
A14
=
Rm
*
lambda_14CO2
*
1e3
*
Nav
/
MASS_14CO2
# kg14CO2/kgCO2 * 1/s * molecules/kmole / (kg14CO2/kmole14CO2) = molecules 14CO2 / kgCO2 / s
A14
=
Rm
*
lambda_14CO2
*
1e3
*
Nav
/
MASS_14CO2
# kg14CO2/kgCO2 * 1/s * molecules/kmole / (kg14CO2/kmole14CO2) = molecules 14CO2 / kgCO2 / s
...
@@ -451,17 +456,16 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -451,17 +456,16 @@ class STILTObservationOperator(ObservationOperator):
if
total
:
return
gpp_increase
+
ter_increase
if
total
:
return
gpp_increase
+
ter_increase
else
:
return
gpp_increase
,
ter_increase
else
:
return
gpp_increase
,
ter_increase
@
cached
def
get_temporal_profiles
(
self
,
datepoint
,
i_station
,
i_member
):
def
get_temporal_profiles
(
self
,
i_datepoint
,
i_station
,
i_member
):
""" Function that reads in the temporal profiles for the current timestep
""" Function that reads in the temporal profiles for the current timestep
Input:
Input:
i_
datepoint:
int: the index of the datepoint for which the c14
should be
calculate
d
datepoint:
datepoint: datetime for which the temporal profile
should be
foun
d
i_station: int: the index of the location for which the c14 concentration should be calculated
i_station: int: the index of the location for which the c14 concentration should be calculated
i_member: int: the index of the member for which the simulation is run
i_member: int: the index of the member for which the simulation is run
Returns:
Returns:
np.array (2): the time profiles for all categories. Indices: time, category"""
np.array (2): the time profiles for all categories. Indices: time, category"""
#read temporal profiles for the times within the footprint
#read temporal profiles for the times within the footprint
time_indices
=
self
.
get_time_indices
(
self
.
datelist
[
i_
datepoint
]
)
time_indices
=
self
.
get_time_indices
(
datepoint
)
station_name
=
self
.
sitenames
[
i_station
]
station_name
=
self
.
sitenames
[
i_station
]
temporal_prior
=
os
.
path
.
join
(
self
.
model_settings
[
'datadir'
],
'prior_temporal_{0}_{1:03}.nc'
.
format
(
station_name
,
i_member
))
temporal_prior
=
os
.
path
.
join
(
self
.
model_settings
[
'datadir'
],
'prior_temporal_{0}_{1:03}.nc'
.
format
(
station_name
,
i_member
))
temporal_prior
=
io
.
ct_read
(
temporal_prior
,
'read'
)
temporal_prior
=
io
.
ct_read
(
temporal_prior
,
'read'
)
...
@@ -490,10 +494,10 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -490,10 +494,10 @@ class STILTObservationOperator(ObservationOperator):
return
emis
return
emis
@
cached
@
cached
def
run_STILT
(
self
,
i_
datepoint
,
i_member
,
i_loc
,
i_species
,
do_pseudo
=
0
):
def
run_STILT
(
self
,
datepoint
,
i_member
,
i_loc
,
i_species
,
do_pseudo
=
0
):
"""This function reads in STILT footprints and returns hourly concentration data
"""This function reads in STILT footprints and returns hourly concentration data
Input:
Input:
i_datepoint: int: index of the datepoint from self.datelist
datepoint: datepoint: datetime: the datepoint for which the concentrations should be calculated
i_member : int: index of the ensemblemember
i_member : int: index of the ensemblemember
i_loc : int: index of the location
i_loc : int: index of the location
i_species : int: index of the species
i_species : int: index of the species
...
@@ -501,9 +505,7 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -501,9 +505,7 @@ class STILTObservationOperator(ObservationOperator):
Returns:
Returns:
float: the concentration increase at the respective location due to the emissions from the respective species"""
float: the concentration increase at the respective location due to the emissions from the respective species"""
# get the date:
# get the date:
datepoint
=
self
.
datelist
[
i_datepoint
]
temp_profiles
=
self
.
get_temporal_profiles
(
datepoint
,
i_loc
,
i_member
)
temp_profiles
=
self
.
get_temporal_profiles
(
i_datepoint
,
i_loc
,
i_member
)
spatial_emissions
=
self
.
get_spatial_emissions
(
i_member
,
i_species
)
spatial_emissions
=
self
.
get_spatial_emissions
(
i_member
,
i_species
)
#find correct background concentrationa
#find correct background concentrationa
footprint
=
self
.
get_foot
(
i_loc
,
datepoint
)
footprint
=
self
.
get_foot
(
i_loc
,
datepoint
)
...
@@ -545,11 +547,11 @@ class STILTObservationOperator(ObservationOperator):
...
@@ -545,11 +547,11 @@ class STILTObservationOperator(ObservationOperator):
logging
.
debug
(
'... and species {}'
.
format
(
self
.
spname
[
i_species
]))
logging
.
debug
(
'... and species {}'
.
format
(
self
.
spname
[
i_species
]))
for
i_datepoint
,
datepoint
in
enumerate
(
self
.
datelist
):
for
i_datepoint
,
datepoint
in
enumerate
(
self
.
datelist
):
logging
.
debug
(
'working on time {}'
.
format
(
datepoint
))
logging
.
debug
(
'working on time {}'
.
format
(
datepoint
))
background_concentration
=
self
.
get_background_orig
(
i_species
,
i_
datepoint
)
background_concentration
=
self
.
get_background_orig
(
i_species
,
datepoint
)
conc_increase_stilt
=
self
.
run_STILT
(
i_
datepoint
,
i_member
,
i_loc
,
i_species
)
conc_increase_stilt
=
self
.
run_STILT
(
datepoint
,
i_member
,
i_loc
,
i_species
)
if
self
.
spname
[
i_species
].
upper
()
==
'CO2'
:
if
self
.
spname
[
i_species
].
upper
()
==
'CO2'
:
gpp
,
ter
=
self
.
get_biosphere_concentration
(
i_loc
,
datepoint
)
gpp
,
ter
=
self
.
get_biosphere_concentration
(
i_loc
,
datepoint
)
logging
.
debug
(
'C14 (delta) = {}'
.
format
(
self
.
get_c14_concentration
(
i_loc
,
i_
datepoint
,
gpp
,
ter
,
conc_increase_stilt
,
background_concentration
)))
#
logging.debug('C14 (delta) = {}'.format(self.get_c14_concentration(i_loc, datepoint, gpp, ter, conc_increase_stilt, background_concentration)))
logging
.
debug
(
'{0:.3} for FF and {1:.3} for bio for {2}'
.
format
(
conc_increase_stilt
,
gpp
+
ter
,
self
.
spname
[
i_species
]))
logging
.
debug
(
'{0:.3} for FF and {1:.3} for bio for {2}'
.
format
(
conc_increase_stilt
,
gpp
+
ter
,
self
.
spname
[
i_species
]))
conc_STILT
.
append
(
conc_increase_stilt
+
gpp
+
ter
+
background_concentration
)
conc_STILT
.
append
(
conc_increase_stilt
+
gpp
+
ter
+
background_concentration
)
totser
[
i_member
]
=
np
.
array
(
conc_STILT
)
totser
[
i_member
]
=
np
.
array
(
conc_STILT
)
...
...
Write
Preview
Markdown
is supported
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