Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests to convert sat bias files and save them to R2D2; make calls to R2D2 more generic #37

Merged
merged 17 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
##### get test data from EMC FTP server
# set URL and hash
set(URL "https://ftp.emc.ncep.noaa.gov/static_files/public/GDASApp")
set(SHA "2b547a5f489130edc240db04a08034d15787c15732871526b1873f0a27e491a4")
set(SHA "0ecc05f647c27110a32c4181a92bdfc2c0474ed5035bd379a63add39429368c0")
string(SUBSTRING ${SHA} 0 6 SHORTSHA)
set(TAR "gdasapp-fix-${SHORTSHA}.tgz")
# download test files
Expand All @@ -27,6 +27,8 @@ list(APPEND test_data
${CMAKE_CURRENT_BINARY_DIR}/testdata/prof.nc
${CMAKE_CURRENT_BINARY_DIR}/testdata/icec.nc
${CMAKE_CURRENT_BINARY_DIR}/testdata/icefb.nc
${CMAKE_CURRENT_BINARY_DIR}/testdata/gdas.t00z.abias
${CMAKE_CURRENT_BINARY_DIR}/testdata/gdas.t00z.abias_pc
)

# install
Expand Down
11 changes: 11 additions & 0 deletions test/atm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,15 @@ if(BUILD_GDASBUNDLE)
COMMAND ${PROJECT_BINARY_DIR}/bin/bufr2ioda.x ${PROJECT_BINARY_DIR}/test/testinput/bufr_adpsfc.yaml
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/)

# test generate UFO CRTM sat bias files from GSI sat bias files
add_test(NAME test_gdasapp_convert_gsi_satbias
COMMAND ${PROJECT_SOURCE_DIR}/test/atm/test_convert_gsi_satbias.sh ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/)

# test saving the output of the previous test to an R2D2 database
add_test(NAME test_gdasapp_store_gsi_satbias
COMMAND ${PROJECT_SOURCE_DIR}/test/atm/test_store_gsi_satbias.py
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/test/)
set_tests_properties(test_gdasapp_store_gsi_satbias PROPERTIES DEPENDS "test_gdasapp_convert_gsi_satbias")

endif(BUILD_GDASBUNDLE)
38 changes: 38 additions & 0 deletions test/atm/test_convert_gsi_satbias.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash
set -ex
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still need -x?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it might be useful for debugging purposes

# test script to run GSI to UFO sat bias converter and produce files
srcdir=$1
builddir=$2

# stage a testrun directory for this test
testrun=$builddir/test/testrun/satbias_conv
mkdir -p $testrun

# copy GSI input files
# the converter assumes a directory structure like we have for GDAS/GFS
mkdir -p $testrun/input/gdas.20220401/00/atmos

cp $builddir/test/testdata/gdas.t00z.abias* $testrun/input/gdas.20220401/00/atmos/.

# create the YAML file as input
cat > $builddir/test/testinput/run_satbias_conv.yaml << EOF
start time: 2022-04-01T00:00:00Z
end time: 2022-04-01T00:00:00Z
assim_freq: 6
dump: gdas
gsi_bc_root: $testrun/input
ufo_bc_root: $testrun/out
work_root: $testrun/work
satbias2ioda: $builddir/bin/satbias2ioda.x
EOF

# run the script
python3 $srcdir/ush/run_satbias_conv.py --config $builddir/test/testinput/run_satbias_conv.yaml

# copy output to testoutput
testout=$builddir/test/testoutput
mkdir -p $testout/satbias
cp -rf $testrun/out/* $testout/satbias/.

# clean up run directory
rm -rf $testrun
72 changes: 72 additions & 0 deletions test/atm/test_store_gsi_satbias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
import os
from r2d2 import store
from solo.configuration import Configuration
from solo.date import date_sequence
import yaml
import ufsda.r2d2


def store_satbias(yaml_file):
config = Configuration(yaml_file)
ufsda.r2d2.store(config)


if __name__ == "__main__":
# create a dummy R2D2 config YAML
r2d2_config = {
'databases':
{'test': {'cache_fetch': False,
'class': 'LocalDB',
'root': os.path.join(os.getcwd(), 'r2d2-test')}, },
'fetch_order': ['test'],
'store_order': ['test'],
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couldn't that be a call to genyaml and we keep an r2d2_config.yaml template somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, do you think that is what should be done in this and your existing test? Or stick with this approach for now? Does it make sense for the same r2d2 db to be used for both the atm and soca tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, we have a few r2d2_config dictionaries defined here and there, it might be a good idea to consolidate how we deal with the config. I would say create an issue somewhere so we can remember to deal with it later, or change it now? Up to you. I won't block this pr for this issue.
As for the r2d2 db, yes, I do think we should have the same one.

with open(os.path.join(os.getcwd(), 'testinput', 'r2d2_config_test.yaml'), 'w') as f:
yaml.dump(r2d2_config, f, sort_keys=False, default_flow_style=False)
os.environ['R2D2_CONFIG'] = os.path.join(os.getcwd(), 'testinput', 'r2d2_config_test.yaml')
# create YAML for satbias
satbias = {
'start': '2022-04-01T00:00:00Z',
'end': '2022-04-01T00:00:00Z',
'step': 'PT6H',
'source_dir': os.path.join(os.getcwd(), 'testoutput', 'satbias'),
'source_file_fmt': '{source_dir}/{dump}.{year}{month}{day}/{hour}/atmos/{obs_type}_satbias.nc4',
'type': 'bc',
'database': 'test',
'provider': 'gsi',
'experiment': 'gdasapp',
'obs_types': [
'amsua_metop-b',
'atms_npp',
'cris-fsr_npp',
'iasi_metop-c',
],
}
satbias_yaml = os.path.join(os.getcwd(), 'testinput', 'r2d2_store_satbias.yaml')
with open(satbias_yaml, 'w') as f:
yaml.dump(satbias, f, sort_keys=False, default_flow_style=False)
# create YAML for tlapse
tlapse = {
'start': '2022-04-01T00:00:00Z',
'end': '2022-04-01T00:00:00Z',
'step': 'PT6H',
'source_dir': os.path.join(os.getcwd(), 'testoutput', 'satbias'),
'source_file_fmt': '{source_dir}/{dump}.{year}{month}{day}/{hour}/atmos/{obs_type}_tlapmean.txt',
'type': 'tlapse',
'database': 'test',
'provider': 'gsi',
'experiment': 'gdasapp',
'obs_types': [
'amsua_metop-b',
'atms_npp',
'cris-fsr_npp',
'iasi_metop-c',
],
}
tlapse_yaml = os.path.join(os.getcwd(), 'testinput', 'r2d2_store_tlapse.yaml')
with open(tlapse_yaml, 'w') as f:
yaml.dump(tlapse, f, sort_keys=False, default_flow_style=False)
# call the store commands
store_satbias(satbias_yaml)
store_satbias(tlapse_yaml)
1 change: 1 addition & 0 deletions test/soca/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ ecbuild_add_test(
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/obs
ENVIRONMENT
OBS_DIR=${OBS_DIR}
PYTHONPATH=${PROJECT_BINARY_DIR}/ush:$ENV{PYTHONPATH}
)
35 changes: 5 additions & 30 deletions test/soca/create_obsdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,15 @@
import argparse
import os
import shutil
from r2d2 import store
from solo.configuration import Configuration
from solo.date import date_sequence
import yaml
import ufsda.r2d2


def store_obs(yaml_file):
config = Configuration(yaml_file)
dates = date_sequence(config.start, config.end, config.step)
obs_types = config.obs_types
provider = config.provider
experiment = config.experiment
database = config.database
type = config.type
source_dir = config.source_dir
step = config.step

for date in dates:
day = str(date).split('T')[0]
year = day[0:4]
month = day[4:6]
day = day[6:8]
for obs_type in obs_types:
obs_prefix = obs_type.split('_')[0]
store(
provider=provider,
type=type,
experiment=experiment,
database=database,
date=date,
obs_type=obs_type,
time_window=step,
source_file=f'{source_dir}/{obs_type}_{year}{month}{day}.nc4',
ignore_missing=True,
)
ufsda.r2d2.store(config)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍



if __name__ == "__main__":
Expand Down Expand Up @@ -68,10 +42,11 @@ def store_obs(yaml_file):
shutil.copyfile(os.path.join(obsdir, 'icefb.nc'), 'icefb_GDR_20180415.nc4', follow_symlinks=True)

# Create the test R2D2 database
obsstore = {'start': '20180415',
'end': '20180415',
obsstore = {'start': '2018-04-15T00:00:00Z',
'end': '2018-04-15T00:00:00Z',
'step': 'P1D',
'source_dir': '.',
'source_file_fmt': '{source_dir}/{obs_type}_{year}{month}{day}.nc4',
'type': 'ob',
'database': 'shared',
'provider': 'gdasapp',
Expand Down
1 change: 1 addition & 0 deletions ush/ufsda/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .disk_utils import *
from .ufs_yaml import gen_yaml, parse_config
import ufsda.stage
import ufsda.r2d2
import ufsda.post
34 changes: 34 additions & 0 deletions ush/ufsda/r2d2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import r2d2
from solo.configuration import Configuration
from solo.date import date_sequence, Hour


def store(config):
times = date_sequence(config.start, config.end, config.step)
obs_types = config.obs_types
provider = config.provider
experiment = config.experiment
database = config.database
type = config.type
source_dir = config.source_dir
source_file_fmt = config.source_file_fmt
step = config.step
dump = config.get('dump', 'gdas')

for time in times:
year = Hour(time).format('%Y')
month = Hour(time).format('%m')
day = Hour(time).format('%d')
hour = Hour(time).format('%H')
for obs_type in obs_types:
r2d2.store(
provider=provider,
type=type,
experiment=experiment,
database=database,
date=time,
obs_type=obs_type,
time_window=step,
source_file=eval(f"f'{source_file_fmt}'"),
ignore_missing=True,
)