Commit fcbe28f5 authored by Dan Baston's avatar Dan Baston

Add configuration for CPC Global Daily temp and precip

parent 290582df
......@@ -70,6 +70,7 @@ CORRUPT_HINDCASTS = {
'1984092800': {'198504'}
}
class CFSStatic(paths.Static, paths.ElectricityStatic, paths.AgricultureStatic):
def __init__(self, source):
super(CFSStatic, self).__init__(source)
......@@ -256,6 +257,8 @@ class NCEP(paths.ObservedForcing):
)
if year >= 1979:
# FIXME call new code in data_sources and Delete compute_noaa_cpc_pwetdays.py
# Download and process files in a single command
# We do this to avoid including 365 files/year as
# individual dependencies, clogging up the Makefile.
......@@ -346,6 +349,9 @@ class CFSForecast(paths.ForecastForcing):
def p_wetdays(self, *, yearmon=None, target, member=None):
month = int(target[4:])
# FIXME use global_prep steps to create wet day ltmeans here instead of assuming they're available
# (when they're not part of the ObservedForcing interface)
return paths.Vardef(os.path.join(self.source,
'NCEP',
'wetdays_ltmean',
......
import os
from typing import Iterable, List
from wsim_workflow.config_base import ConfigBase
from wsim_workflow.step import Step
import wsim_workflow.paths as paths
from wsim_workflow.data_sources import cpc_daily_temperature, cpc_daily_precipitation
from config_cfs import CFSForecast, CFSStatic
class CPC(paths.ObservedForcing):
def __init__(self, source):
self.source = source
self.temp_workdir = os.path.join(self.source, 'CPC_Global_Daily_Temperature', 'raw')
self.precip_workdir = os.path.join(self.source, 'CPC_Global_Daily_Precipitation', 'raw')
def prep_steps(self, *, yearmon: str) -> List[Step]:
return \
cpc_daily_temperature.download_monthly_temperature(
yearmon=yearmon,
workdir=self.temp_workdir,
output_filename=self.temp_monthly(yearmon=yearmon).file) + \
cpc_daily_precipitation.download_monthly_precipitation(
yearmon=yearmon,
workdir=self.precip_workdir,
precipitation_fname=self.precip_monthly(yearmon=yearmon).file,
wetdays_fname=self.p_wetdays(yearmon=yearmon).file)
def precip_monthly(self, *, yearmon: str) -> paths.Vardef:
return paths.Vardef(os.path.join(self.source, 'CPC_Global_Daily_Precipitation', 'monthly_sum', 'P_{}.nc'.format(yearmon)), 'Pr')
def temp_monthly(self, *, yearmon: str) -> paths.Vardef:
return paths.Vardef(os.path.join(self.source, 'CPC_Global_Daily_Temperature', 'monthly_mean', 'T_{}.nc'.format(yearmon)), 'tavg')
def p_wetdays(self, *, yearmon: str) -> paths.Vardef:
return paths.Vardef(os.path.join(self.source, 'CPC_Global_Daily_Precipitation', 'monthly_wetdays', 'pWetDays_{}.nc'.format(yearmon)), 'pWetDays')
class CPCConfig(ConfigBase):
def result_fit_years(self) -> Iterable[int]:
return range(1981, 2019)
def static_data(self):
return self._static
def workspace(self) -> paths.DefaultWorkspace:
return self._workspace
def observed_data(self) -> paths.ObservedForcing:
return self._observed
def historical_years(self):
return range(1979, 2019) # 1979 to 2018
def __init__(self, source, derived):
self._observed = CPC(source)
self._forecast = {
'CFSv2': CFSForecast(source, derived, self._observed),
}
self._static = CFSStatic(source)
self._workspace = paths.DefaultWorkspace(derived)
config = CPCConfig
# Copyright (c) 2018-2019 ISciences, LLC.
# All rights reserved.
#
# WSIM is licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import calendar
import os
from typing import List, Optional
from ..step import Step
from .. import commands
from .. import dates
def download_daily_precipitation(*, yearmon, workdir) -> Step:
return Step(targets=[],
dependencies=[],
commands=[
[
os.path.join('{BINDIR}',
'utils',
'noaa_cpc_daily_precip',
'download_noaa_cpc_daily_precip.py'),
'--yearmon', yearmon,
'--output_dir', workdir
]
])
def input_files(*, workdir: str, yearmon: str) -> str:
year, month = dates.parse_yearmon(yearmon)
return os.path.join(workdir,
str(year),
'PRCP_CU_GAUGE_V1.0GLB_0.50deg.lnx.[{YEARMON}01:{YEARMON}{DAYS_IN_MONTH:02d}].gz'.format(YEARMON=yearmon,
DAYS_IN_MONTH=calendar.monthrange(year, month)[1]))
def compute_wetdays(*, yearmon: str, workdir: str, fname: str) -> Step:
# TODO document use of [x-1] here to ignore trace precipitation
step = commands.wsim_integrate(inputs=input_files(workdir=workdir, yearmon=yearmon) + '::1@[x-1]->pWetDays',
stats='fraction_defined_above_zero',
output=fname,
keepvarnames=True)
# Remove dependencies; they will be taken care of by merging this step with download_daily_precipitation()
# This is done to avoid hundreds of dependencies per year.
step.dependencies = set()
return step
def compute_monthly_precipitation(*, yearmon: str, workdir: str, fname: str):
year, month = dates.parse_yearmon(yearmon)
days_in_month = calendar.monthrange(year, month)[1]
seconds_in_month = days_in_month * 24 * 60 * 60
# convert from 0.1mm daily totals to mm/s (kg/m^2/s)
transformation = '[x*10/{}]'.format(seconds_in_month)
step = commands.wsim_integrate(inputs=input_files(workdir=workdir, yearmon=yearmon) + '::1@{}->Pr'.format(transformation),
stats='ave',
output=fname,
attrs=['Pr:units=kg/m^2/s', 'Pr:standard_name=precipitation_flux'],
keepvarnames=True)
# Remove dependencies; they will be taken care of by merging this step with download_daily_precipitation()
# This is done to avoid hundreds of dependencies per year.
step.dependencies = set()
return step
def download_monthly_precipitation(*,
yearmon,
workdir,
precipitation_fname: Optional[str] = None,
wetdays_fname: Optional[str] = None) -> List[Step]:
assert yearmon >= '197901'
assert precipitation_fname or wetdays_fname
step = download_daily_precipitation(yearmon=yearmon, workdir=workdir)
if wetdays_fname:
step = step.merge(compute_wetdays(yearmon=yearmon, workdir=workdir, fname=wetdays_fname))
if precipitation_fname:
step = step.merge(compute_monthly_precipitation(yearmon=yearmon, workdir=workdir, fname=precipitation_fname))
return [step]
# Copyright (c) 2019 ISciences, LLC.
# All rights reserved.
#
# WSIM is licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License. You may
# obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from typing import List
from ..step import Step
def download_monthly_temperature(*, yearmon: str, workdir: str, output_filename: str) -> List[Step]:
assert yearmon >= '197901'
# FIXME Need some sort of locking mechanism so that multiple calls to this script don't try to download the same file.
# Could pre-empt and download in global_prep_steps??
return [
Step(
targets=output_filename,
dependencies=[],
commands=[
[
os.path.join('{BINDIR}', 'utils', 'noaa_cpc_daily_temp', 'get_cpc_monthly_mean_temperature.R'),
'--yearmon', yearmon,
'--workdir', workdir,
'--output', output_filename,
]
]
)
]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment