Skip to content

Commit

Permalink
Feature/b2i (#1275)
Browse files Browse the repository at this point in the history
6 bufr to ioda converters
this is second refactoring of the code.
the variables are grouped into metadata, obs and additional ioda vars
metadata is read from a yaml file (could also be a json file)
additional variables now include ocean basin
converters generate log files and have a command line option to test
the log against a reference file
Log files contain some human readable data, as well as cryptographic 
hash strings computed from the variables.
Simple utilities to plot data are included.

---------

Co-authored-by: Guillaume Vernieres <[email protected]>
  • Loading branch information
givelberg and guillaumevernieres authored Sep 27, 2024
1 parent c797d33 commit 2be1fcd
Show file tree
Hide file tree
Showing 34 changed files with 1,673 additions and 0 deletions.
2 changes: 2 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,5 @@ add_subdirectory(atm)

# gdas aerosol tests
add_subdirectory(aero)

add_subdirectory(marine)
161 changes: 161 additions & 0 deletions test/marine/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Copy the bkg files
# ------------------
set(TESTDATA ${PROJECT_BINARY_DIR}/test/testdata )


# Symlink test input yaml files
# -----------------------------
# create testinput dir
set (TESTINPUT_DIR ${PROJECT_BINARY_DIR}/test/marine/testinput)

file(MAKE_DIRECTORY ${TESTINPUT_DIR})

# symlink
foreach(FILENAME ${test_input})
get_filename_component(filename ${FILENAME} NAME)
execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink
${FILENAME}
${TESTINPUT_DIR}
)
endforeach(FILENAME)

# install
install(FILES ${test_input}
DESTINATION "test/testinput/")


###########################################################################
# bufr to ioda tests:
###########################################################################

# prepare a test.yaml file from test.yaml.in by replacing
# placeholder patterns __BUFRINPUTDIR__ and __IODAOUTPUTDIR__ and __OCEANBASIN__
# with actual directory paths
function(CREATE_CONFIG_FILE
test_config_in
test_config_out
bufr_input_dir
ioda_output_dir
ocean_basin_file
)
file(READ "${test_config_in}" file_content)
string(REPLACE "__BUFRINPUTDIR__" "\"${bufr_input_dir}\"" temp_content "${file_content}")
string(REPLACE "__IODAOUTPUTDIR__" "\"${ioda_output_dir}\"" temp_content2 "${temp_content}")
string(REPLACE "__OCEANBASIN__" "\"${ocean_basin_file}\"" temp_content3 "${temp_content2}")
file(WRITE "${test_config_out}" "${temp_content3}")
endfunction()


set(TEST_WORKING_DIR ${PROJECT_BINARY_DIR}/test/marine)

set(MARINE_BUFR2IODA_DIR ${PROJECT_SOURCE_DIR}/ush/ioda/bufr2ioda/marine)
set(MARINE_BUFR2IODA_DIR ${MARINE_BUFR2IODA_DIR}/b2i)
set(CONFIG_DIR ${PROJECT_SOURCE_DIR}/test/marine/testinput)
set(TESTREF_DIR ${PROJECT_SOURCE_DIR}/test/marine/testref)


function(CHECK_AND_SET_PATH PATH1 PATH2 RESULT_VAR)
# Check if PATH1 exists
if(EXISTS ${PATH1})
set(${RESULT_VAR} ${PATH1} PARENT_SCOPE)
set(${RESULT_VAR}_EXISTS TRUE PARENT_SCOPE)
return()
endif()

# Check if PATH2 exists
if(EXISTS ${PATH2})
set(${RESULT_VAR} ${PATH2} PARENT_SCOPE)
set(${RESULT_VAR}_EXISTS TRUE PARENT_SCOPE)
return()
endif()

# If neither path exists
set(${RESULT_VAR} "" PARENT_SCOPE)
set(${RESULT_VAR}_EXISTS FALSE PARENT_SCOPE)
endfunction()


# find the input files
set(BUFR_TEST_DIR_ORION
"/work/noaa/da/marineda/gfs-marine/data/obs/ci/bufr"
)
set(BUFR_TEST_DIR_HERA
"/scratch1/NCEPDEV/da/common/ci/bufr"
)
CHECK_AND_SET_PATH(
${BUFR_TEST_DIR_ORION}
${BUFR_TEST_DIR_HERA}
BUFR_TEST_DIR
)
if (NOT BUFR_TEST_DIR_EXISTS)
message(STATUS "BUFR test file directory not found -- bufr to ioda tests not generted.")
set(GENERATE_BUFR2IODA_TESTS FALSE)
else()
# message(STATUS "Found bufr test directory: ${BUFR_TEST_DIR}")

set(OCEAN_BASIN_FILE_HERA
"/scratch2/NCEPDEV/ocean/Guillaume.Vernieres/data/static/common/RECCAP2_region_masks_all_v20221025.nc"
)
set(OCEAN_BASIN_FILE_ORION
"/work/noaa/global/glopara/fix/gdas/soca/20240802/common/RECCAP2_region_masks_all_v20221025.nc"
)
CHECK_AND_SET_PATH(
${OCEAN_BASIN_FILE_ORION}
${OCEAN_BASIN_FILE_HERA}
OCEAN_BASIN_FILE
)
if (NOT OCEAN_BASIN_FILE_EXISTS)
message("Ocean basin data file not found -- bufr to ioda tests not generated.")
set(GENERATE_BUFR2IODA_TESTS FALSE)
endif()
# message(STATUS "Found ocean basin data in ${OCEAN_BASIN_FILE}")
set(GENERATE_BUFR2IODA_TESTS TRUE)
endif()


function(ADD_INSITU_TEST testname testbufr)
# set(CONFIG_TYPE "json")
set(CONFIG_TYPE "yaml")
set(DATE "2021063006")
set(TEST "bufr2ioda_insitu_${testname}")

set(TESTREF_FILE "${TEST}_${DATE}.ref")

# stage the input file to directory ${BUFR_INPUT_DIR}
set(BUFR_INPUT_DIR ${TEST_WORKING_DIR})
set(BUFR_TEST_FILE "${DATE}-gdas.t06z.${testbufr}.tm00.bufr_d")
set(BUFR_FILE "${BUFR_TEST_DIR}/${BUFR_TEST_FILE}")
if (NOT EXISTS ${BUFR_FILE})
message(FATAL_ERROR "BUFR file ${BUFR_FILE} not found")
endif()
file(COPY ${BUFR_FILE} DESTINATION ${BUFR_INPUT_DIR})

# stage the config file
set(CONFIG_FILE_NAME ${TEST}_${DATE}.${CONFIG_TYPE})
set(CONFIG_FILE_IN "${CONFIG_DIR}/${CONFIG_FILE_NAME}.in")
set(CONFIG_FILE "${TEST_WORKING_DIR}/${CONFIG_FILE_NAME}")
set(IODA_OUTPUT_DIR ${TEST_WORKING_DIR})
CREATE_CONFIG_FILE(
${CONFIG_FILE_IN}
${CONFIG_FILE}
${BUFR_INPUT_DIR}
${IODA_OUTPUT_DIR}
${OCEAN_BASIN_FILE}
)

add_test(
NAME test_${TEST}
COMMAND ${MARINE_BUFR2IODA_DIR}/${TEST}.py -c ${CONFIG_FILE} -t ${TESTREF_DIR}/${TESTREF_FILE}
WORKING_DIRECTORY ${TEST_WORKING_DIR}
)
endfunction()


if (GENERATE_BUFR2IODA_TESTS)
ADD_INSITU_TEST("profile_argo" "subpfl")
ADD_INSITU_TEST("profile_bathy" "bathy")
ADD_INSITU_TEST("profile_glider" "subpfl")
ADD_INSITU_TEST("profile_tesac" "tesac")
ADD_INSITU_TEST("profile_xbtctd" "xbtctd")
ADD_INSITU_TEST("surface_trkob" "trkob")
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
data_format: subpfl
subsets: SUBPFL
source: NCEP data tank
data_type: argo
cycle_type: gdas
cycle_datetime: '2021063006'
dump_directory: __BUFRINPUTDIR__
ioda_directory: __IODAOUTPUTDIR__
ocean_basin: __OCEANBASIN__
data_description: 6-hrly in situ ARGO profiles
data_provider: U.S. NOAA

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
data_format: bathy
subsets: BATHY
source: NCEP data tank
data_type: bathy
cycle_type: gdas
cycle_datetime: '2021063006'
dump_directory: __BUFRINPUTDIR__
ioda_directory: __IODAOUTPUTDIR__
ocean_basin: __OCEANBASIN__
data_description: 6-hrly in situ Bathythermal profiles
data_provider: U.S. NOAA

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
data_format: subpfl
subsets: SUBPFL
source: NCEP data tank
data_type: glider
cycle_type: gdas
cycle_datetime: '2021063006'
dump_directory: __BUFRINPUTDIR__
ioda_directory: __IODAOUTPUTDIR__
ocean_basin: __OCEANBASIN__
data_description: 6-hrly in situ GLIDER profiles
data_provider: U.S. NOAA

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
data_format: tesac
subsets: TESAC
source: NCEP data tank
data_type: tesac
cycle_type: gdas
cycle_datetime: '2021063006'
dump_directory: __BUFRINPUTDIR__
ioda_directory: __IODAOUTPUTDIR__
ocean_basin: __OCEANBASIN__
data_description: 6-hrly in situ TESAC profiles
data_provider: U.S. NOAA

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
data_format: xbtctd
subsets: XBTCTD
source: NCEP data tank
data_type: xbtctd
cycle_type: gdas
cycle_datetime: '2021063006'
dump_directory: __BUFRINPUTDIR__
ioda_directory: __IODAOUTPUTDIR__
ocean_basin: __OCEANBASIN__
data_description: 6-hrly in situ XBT/XCTD profiles
data_provider: U.S. NOAA

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
data_format: trkob
subsets: TRACKOB
source: NCEP data tank
data_type: trackob
cycle_type: gdas
cycle_datetime: '2021063006'
dump_directory: __BUFRINPUTDIR__
ioda_directory: __IODAOUTPUTDIR__
ocean_basin: __OCEANBASIN__
data_description: 6-hrly in situ TRACKOB surface
data_provider: U.S. NOAA

23 changes: 23 additions & 0 deletions test/marine/testref/bufr2ioda_insitu_profile_argo_2021063006.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
dateTime: 97150, int64 min, max = 1625022120, 1625047140
dateTime hash = efcd92a143d8589288563e635318f2705900b0970e68a193eeffca3526cb4824
rcptdateTime: 97150, int64 min, max = 1625029260, 1626386700
rcptdateTime hash = da1886e087ccca11b77474c6cbc2434b4bdce86ea34f76c7a36b7d3f06602103
lon: 97150, float32 min, max = -174.8090057373047, 170.48915100097656
lon hash = e79a198bd3a8d0e72c3749ee84db8f5d6b6499a6c231540117c1270abff515ea
lat: 97150, float32 min, max = -59.77299880981445, 76.25086212158203
lat hash = be568a690e0f32204326993b16d4f7863b4f77db6cbe5febf30523098c9186b3
depth: 97150, float32 min, max = 0.0, 5700.7001953125
depth hash = 805664f9daa328e4dce41c33fdadfdf026908d7f6f044b3079bde03f343fe79a
stationID: 97150, <U11
stationID hash = 85faa16d0fc1e02d2fb4da51dea715732088589a45233b81a1f9f65932df6df5
temp: 97150, float32 min, max = -1.817999243736267, 31.73198890686035
temp hash = 674e8493b492fb7ac91207f706e79f94056009c61d16a7c657bfab391b4745af
saln: 97150, float32 min, max = 3.305000066757202, 42.47999954223633
saln hash = 57e87adc01b398c3e40b2d23c929aae3613f9811580bb4cffb18408a3c953584
seqNum: 97150, int32 min, max = 0, 155
seqNum hash = 91c64cfe2001beb9608338e86485d622485f9b9117c477d1ea64ccb01c32cbde
PreQC: 97150, int32 min, max = 0, 0
ObsError_temp: 97150, float32 min, max = 0.019999999552965164, 0.019999999552965164
ObsError_saln: 97150, float32 min, max = 0.009999999776482582, 0.009999999776482582
OceanBasin: 97150, int32 min, max = 0, 5
OceanBasin hash = f3a46a8533511f5885db7ff9623707a36b4a7135643041e9878c327e4378e42d
20 changes: 20 additions & 0 deletions test/marine/testref/bufr2ioda_insitu_profile_bathy_2021063006.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
dateTime: 1751, int64 min, max = 1625024880, 1625038860
dateTime hash = f4e49e8252561ec367b3ed86f971e15cdd00402bcbba8ac4f24a8c2ecf806f12
rcptdateTime: 1751, int64 min, max = 1625028540, 1633808940
rcptdateTime hash = b871fc57bec1719123c57bc84d09807f76ea972cfbadc944be59c0430e2b631c
lon: 1751, float32 min, max = -79.9000015258789, 13.020000457763672
lon hash = eb89f459093a674845f3de8277409658090f0c2e9a4af84367d0dcb4598fea39
lat: 1751, float32 min, max = -27.549999237060547, 29.93000030517578
lat hash = cc86ce703edb7b8b32dac497fd28576c77527ba168348af785315ce02f8cbfb7
depth: 1751, float32 min, max = 2.0, 1298.0
depth hash = 7fde28c9dae36779d0ad21459946791cc6cd3a461a6b5d544399c2bf22eb3d04
stationID: 1751, <U6
stationID hash = 41e65ec9607faf118615a8d9ce2bfabbbe6b6e835520cd35e9ed30abdc26c2f3
temp: 1751, float32 min, max = 3.5999999046325684, 29.100000381469727
temp hash = c00bbe5d969f8de8232ae22cd0948621e6b3e326e4931cdcfa2f7dd4d2509879
seqNum: 1751, int32 min, max = 0, 2
seqNum hash = 7429963169776e1dc0d26732c5053c7e81131cc66654c23aa6393258e9b5b9ae
PreQC: 1751, int32 min, max = 0, 0
ObsError_temp: 1751, float32 min, max = 0.23999999463558197, 0.23999999463558197
OceanBasin: 1751, int32 min, max = 1, 1
OceanBasin hash = 7de61dfe030e0fabc021c5e1c509cbd2f01afba06ac93959f94c5726d513937f
23 changes: 23 additions & 0 deletions test/marine/testref/bufr2ioda_insitu_profile_glider_2021063006.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
dateTime: 27280, int64 min, max = 1625022060, 1625046720
dateTime hash = 2761399c297bbda0b22acbe64f47b86f677e32ebf495a3cb8b7800ad84f25f75
rcptdateTime: 27280, int64 min, max = 1625030220, 1625580780
rcptdateTime hash = 1adb5fd7df4caec197d0d99367b6dfa890cd018336fc56e7eb860fa2204436a2
lon: 27280, float32 min, max = -127.5352783203125, -53.66297912597656
lon hash = 6367f3579cd1641387a49a60d766d3dc4a1352f760e7c6851469e2b6d5be9aa5
lat: 27280, float32 min, max = 15.612810134887695, 47.726619720458984
lat hash = ae48a82fc017206b16d4db9efdc63813763b131ebb0d47e81cbf90feea1d0d1f
depth: 27280, float32 min, max = 0.0, 1007.0
depth hash = 93d7c59fb8cf0cdcee45a96263515281be53b4557dcca9b86af9a9785728dcdc
stationID: 27280, <U11
stationID hash = fbeea224ff0ce14f6118bcb1e923d50d83a8bb71655570f16fdfab52ed3a7c3c
temp: 27280, float32 min, max = -0.4910034239292145, 28.96599769592285
temp hash = b1f6cc4411776b9f2315a6f945c38a520bb6199a9da544ece2ca2f772520634e
saln: 27280, float32 min, max = 0.0, 37.31399917602539
saln hash = 7563369a522cdbef7135a28b68f6f53a162a111d02ed384dabb374d8c5809c50
seqNum: 27280, int32 min, max = 0, 140
seqNum hash = eed58b20f19414e540dcf6e32a0c7ef9beaf3906045bd05279caa326e7a8e106
PreQC: 27280, int32 min, max = 0, 0
ObsError_temp: 27280, float32 min, max = 0.019999999552965164, 0.019999999552965164
ObsError_saln: 27280, float32 min, max = 0.009999999776482582, 0.009999999776482582
OceanBasin: 27280, int32 min, max = 0, 2
OceanBasin hash = 85f985fd1d0c5596e07c480680abd31277664a7bc61ae466f9cf733626a2ac46
23 changes: 23 additions & 0 deletions test/marine/testref/bufr2ioda_insitu_profile_tesac_2021063006.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
dateTime: 5487, int64 min, max = 1625022000, 1625043240
dateTime hash = a0af98fd9dc4ab5db04ce45fc1cec379559d5bd98c5c873eb4d90abdbde36273
rcptdateTime: 5487, int64 min, max = 1625023080, 1625261280
rcptdateTime hash = f8f825e450b1ded00758c84db419002a844cc60629cac49c68f7391e8a0d2f9e
lon: 5487, float32 min, max = -155.8300018310547, -53.65999984741211
lon hash = e1bc92ae650d0a069afbcc8c325163c246ba5c8fa23369bbd7d5587bea627941
lat: 5487, float32 min, max = 15.630000114440918, 47.779998779296875
lat hash = c650f2ae6dd49155ed65380f7384a4569b420a7690ad0af5e4e509ec96906e60
depth: 5487, float32 min, max = 0.0, 901.0
depth hash = 7ee6f7649a454ff1b5c0f9202b0bd62611ad2976b6bcb3da8864a39a0bfac552
stationID: 5487, <U5
stationID hash = 6259287276a7773a4c66e4e341211a9378de00486ee4e43b006d559b5450b740
temp: 5487, float32 min, max = -0.4899963438510895, 28.5200138092041
temp hash = 889e60262d755fb4d696939c4807ea98ca6d8862179994b258530edcc733fdd7
saln: 5487, float32 min, max = 2.75, 37.310001373291016
saln hash = 0d6560a45baa2ddb1058e5713c488a973094b86501a0c3c52ae93cff242cd982
seqNum: 5487, int32 min, max = 0, 37
seqNum hash = d8101166907ab433402ac4830f01ba91e0814fc52cf1b85e65cd8b64bbbf5f11
PreQC: 5487, int32 min, max = 0, 0
ObsError_temp: 5487, float32 min, max = 0.019999999552965164, 0.019999999552965164
ObsError_saln: 5487, float32 min, max = 0.009999999776482582, 0.009999999776482582
OceanBasin: 5487, int32 min, max = 0, 2
OceanBasin hash = 1684932c1f434fc914fc188c38c26f36e07a15d318c9eff77472356b5e1743cf
23 changes: 23 additions & 0 deletions test/marine/testref/bufr2ioda_insitu_profile_xbtctd_2021063006.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
dateTime: 109, int64 min, max = 1625014080, 1625042220
dateTime hash = 3710f5b53b1a8960639c8210b697550badfb98222d1aad6c44b301210d3e04bd
rcptdateTime: 109, int64 min, max = 1625049480, 1625193480
rcptdateTime hash = e0bccbdf6e454c5848376572a94172ea11191086a55949bf5151cb11a01af2c6
lon: 109, float32 min, max = 140.3979949951172, 163.00399780273438
lon hash = ee3fcf7ef503612c20f067c76c711eeaf4c122e8a55b5a7617be457a776aa848
lat: 109, float32 min, max = 30.476999282836914, 39.60200119018555
lat hash = 4c18d8695943f3dab12c20e9e6d8064b8d8150dddd0d717d7a389979dae876b9
depth: 109, float32 min, max = 3.0, 1100.0
depth hash = bc30fc93930ac4f607f537c7be455a10c64ea824c0f1c623b9f76716d81b2a02
stationID: 109, <U11
stationID hash = cdc82f65fba8a66fa268dd87910335435f3bdc054f22fc4a51f0f7af6ebb0857
temp: 109, float32 min, max = 3.5100035667419434, 24.33001136779785
temp hash = 1062fcd382a9d3311e89e38254fa619afc058f74c1485b6fc18199f640c9520c
saln: 109, float32 min, max = 33.43000030517578, 34.790000915527344
saln hash = 7c15d19799e5e1d559150f27d931d811c992a2bab9fa16cabb8f19cf330b35e8
seqNum: 109, int32 min, max = 0, 5
seqNum hash = 588361b4a1719ca93386b84f1b8be7a47fe10b90a0616256c05f40f359c824fa
PreQC: 109, int32 min, max = 0, 0
ObsError_temp: 109, float32 min, max = 0.11999999731779099, 0.11999999731779099
ObsError_saln: 109, float32 min, max = 1.0, 1.0
OceanBasin: 109, int32 min, max = 0, 2
OceanBasin hash = db7f48faf153ae3f838436037b5a2d64e4be9368d5c8d1f9d3701d4c6802779b
19 changes: 19 additions & 0 deletions test/marine/testref/bufr2ioda_insitu_surface_trkob_2021063006.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
dateTime: 929, int64 min, max = 1625011200, 1625043540
dateTime hash = fe44939ae1f54dbee46edec3c024dc1298017a51cf85fcfff2c261aeec886a3c
rcptdateTime: 929, int64 min, max = 1625088960, 1625175540
rcptdateTime hash = a08519e6ebdefd8b7946c32a557273d81608837a615965528c933996d4e444bf
lon: 929, float32 min, max = -4.429999828338623, 152.17999267578125
lon hash = 985190343e99bbbf3979e7285e8e276148b9291ad04f8e5ca5cdbb6ffe34010b
lat: 929, float32 min, max = -23.479999542236328, 48.91999816894531
lat hash = 4293df46db1a98b72f455c8682a9fbc9b655e3898f4f20912b49147539de5479
stationID: 929, <U4
stationID hash = b168519bf422422975e2f63be7bac9e8de9613e071534def510bfb9e2d01ff7c
temp: 929, float32 min, max = 13.600000381469727, 27.9999942779541
temp hash = 8cc9791112272e02bdf6b0b2c4a936a690efd00a311e81b49d9df8ba3a4b77a6
saln: 929, float32 min, max = 33.75, 37.58000183105469
saln hash = 3bc415581fbe183e324449621debeb359ed1599335a2ce70b98258e6811c1dca
PreQC: 929, int32 min, max = 0, 0
ObsError_temp: 929, float32 min, max = 0.30000001192092896, 0.30000001192092896
ObsError_saln: 929, float32 min, max = 1.0, 1.0
OceanBasin: 929, int32 min, max = 0, 2
OceanBasin hash = cd8318dfcc18b3c9fbcd8264ec98c4db6e1551185282e2cd08a499a2f26682d8
Loading

0 comments on commit 2be1fcd

Please sign in to comment.