diff --git a/.gitignore b/.gitignore index 7874132504..f306e88a3c 100644 --- a/.gitignore +++ b/.gitignore @@ -168,6 +168,7 @@ L1_AMSUA_to_netcdf convert_airs_L2 convert_amsu_L1 convert_L2b +convert_goes_ABI_L1b # Test programs built by developer_tests rttov_test diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8bc9db08b3..b466545457 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,6 +22,11 @@ individual files. The changes are now listed with the most recent at the top. +**October 22 2024 :: Bug-fixes: WRF and GOES. Tag 11.8.2** + +- Force THM to be the WRF-DART temperature variable +- Remove offset on GOES observation converter + **September 27 2024 :: MOM6 mask bug-fix. Tag 11.8.1** - Fix for MOM6 CESM3 workhorse 2/3 degree grid TL319_t232 to diff --git a/conf.py b/conf.py index d78663aefd..902f7875d9 100644 --- a/conf.py +++ b/conf.py @@ -21,7 +21,7 @@ author = 'Data Assimilation Research Section' # The full version, including alpha/beta/rc tags -release = '11.8.1' +release = '11.8.2' root_doc = 'index' # -- General configuration --------------------------------------------------- diff --git a/observations/forward_operators/obs_def_rttov_mod.rst b/observations/forward_operators/obs_def_rttov_mod.rst index df98b706cc..7e65f32a01 100644 --- a/observations/forward_operators/obs_def_rttov_mod.rst +++ b/observations/forward_operators/obs_def_rttov_mod.rst @@ -6,7 +6,7 @@ MODULE ``obs_def_rttov_mod`` Overview -------- -DART RTTOV observation module, including the observation operators for the two primary +The DART RTTOV observation module, including the observation operators for the two primary RTTOV-observation types -- visible/infrared radiances and microwave radiances/brightness temperatures. @@ -46,25 +46,124 @@ Although a model may not have the necessary inputs by itself, the defaults in RTTOV based on climatology can be used. The impact on the quality of the results should be investigated. -The quanities for each observation type are defined in obs_def_rttov{13}_mod.f90, like so: +The quanities for each observation type are defined in obs_def_rttov{13}_mod.f90, for example: .. code:: - ! HIMAWARI_8_AHI_RADIANCE, QTY_RADIANCE + ! HIMAWARI_9_AHI_RADIANCE, QTY_RADIANCE If you want to change the quantity associated with an observation, for example, if you want -to assimilate HIMAWARI_8_AHI_RADIANCE as QTY_BRIGHTNESS_TEMPERATURE, edit the QTY -in obs_def_rttov{13}_mod.f90 and rerun quickbuild.sh. +to assimilate HIMAWARI_9_AHI_RADIANCE as QTY_BRIGHTNESS_TEMPERATURE, edit the QTY +in obs_def_rttov{13}_mod.f90 and rerun quickbuild.sh. Although both spectral radiance +(mW/cm/m^2/sr) and brightness temperature (Kelvin) quantify the same emitted/reflected +radiance from the atmosphere, the tendency for brightness temperatures to adhere closer +to a gaussian distribution may improve the quality of the assimilation if using +a DART filter type that depends on Gaussian assumptions (e.g. EAKF). This is +an ongoing area of research. -Known issues: -- DART does not yet provide any type of bias correction -- Cross-channel error correlations are not yet supported. A principal component approach has been discussed. For now, - the best bet is to use a subset of channels that are nearly independent of one another. -- Vertical localization will need to be tuned. Turning off vertical localization may work well if you have a large - number of ensemble members. Using the maximum peak of the weighting function or the cloud-top may be appropriate. - There are also other potential approaches being investigated. +RTTOV Metadata +--------------- + +The RTTOV module ingests metadata from the ``obs_seq.out`` file in order to calculate the +expected observed radiance. For example, a single ``HIMAWARI_9_AHI_RADIANCE`` +observation in units of brightness temperature (Kelvin) looks like the following: + +.. code:: + + + OBS 1 + 288.370817896852 + 0.000000000000000E+000 + -1 2 -1 + obdef + loc3d + 1.766273140907288 0.1535889655351639 34000.00000000000 2 + kind + 304 + visir + 100.500000000000 46.6700000000000 -888888.000000000 + -888888.000000000 + 31 9 56 8 + -888888.000000000 + 1 + 0 154166 + 1.00000000000000 + + +Please note, that in this example the radiance observation was assigned a vertical level (34000 Pa) +with the ``VERTISPRESSURE`` (integer = 2) vertical coordinate. +Although radiance/BT observations are technically representative of the entire atmospheric +column and not a single vertical level, for some applications where specific channels (wavelength) +are especially sensitive to constituents at particular atmospheric levels, assigning +a vertical level to the observation may improve the skill of the assimilation forecast. This is an ongoing +area of research. As an alternative, it is also common to leave the vertical level +as undefined (VERTISUNDEF, integer = -2), however, this limits the ability to vertically +localize the impact of the observation on the model state. + +In this example where the observation is infrared (IR) radiance, the metadata is located after +the ``visir`` line (Note: for microwave observations the metadata would follow ``mw``). +The metadata includes the azimuth and elevation angle of the satellite and the sun respectively. In this instance the sun azimuth/elevation are given missing values (-888888) because +solar reflectance has no impact on an IR radiance observation. Also note, the observation +provides a 4 integer description (31/9/56/8) of the platform/satellite/sensor/channel +combination specific to this satellite observation. For more information on this +metadata refer to this GOES observation converter example here: +:doc:`../../observations/obs_converters/GOES/README` + +.. Important :: + + It is important that the user confirms the satellite integer metadata within + the obs_seq.out file matches the metadata within rttov_sensor_db.csv. Furthermore, + confirm that the channel as defined in the obs_seq.out file matches the channel + available in the RTTOV coefficient file (.dat). See next section for more information. + +RTTOV coefficient files +----------------------- + +The RTTOV coefficent file (.dat) contains the appropriate parameter values for a specific satellite +radiance observation. The DART file (``rttov_sensor_db.csv``) refers to the RTTOV coefficent +file. For the ``HIMAWARI_9_AHI_RADIANCE`` observation type, for example, the following information +is provided within ``rttov_sensor_db.csv``: + +.. code:: + + HIMAWARI_9_AHI 31 9 56 ir rtcoef_himawari_9_ahi.dat + +The coefficent file (.dat) is included with the RTTOV installation and can be found at the +path ``${RTTOV_install}/rtcoef_rttov13/rttov9pred54L/rtcoef_himawari_9_ahi.dat``. This file +should be included in your run folder at runtime. Additional coefficent files for a given +satellite sensor may be required. + +It is good practice to always view your coefficent file (.dat) to confirm that the +channels listed in the file match the channel from the ``obs_seq.out`` file. The coefficent +file will include a list of channels (wavebands) with the associated wavelength (microns). + + +.. Important :: + + The RTTOV package includes multiple coefficent files (e.g. all wavelengths, IR only, etc.) that + contain the appropriate parameter data for each satellite/sensor/channel combination. Whether + the file contains all wavelengths versus only IR wavelengths is **extremely important** because + it will shift the value of the channel number. Recommended practice is to choose a coefficient file + with all channels included. If, on the other hand, you subset your coefficent file to only include + IR channels, you should edit your observation converter such that the channels match. + If RTTOV always returns expected observations of radiance = 0, or if the prior expected radiance + is unusually biased from your prior, this could be a sign there is a mismatch between the + obs_seq.out channel and the coefficient file channel. + + + +Known issues: +------------- +- DART does not provide any type of observation bias correction. It may be appropriate to preprocess your radiance + observations to remove systematic bias before assimilation, using techniques such as cumulative distribution + function (CDF) matching. +- Cross-channel error correlations are not supported. A principal component approach has been discussed. For now, + we recommend to use a subset of channels that are nearly independent of one another. +- Vertical localization will need to be tuned based on the research application. Turning off vertical localization + may work well if you have a large number of ensemble members. Using the maximum peak of the channel weighting + function or the cloud-top height to set a vertical location for an observation may be appropriate. The namelist ``&obs_def_rttov_mod_nml`` is read from file ``input.nml``. Namelists start with an ampersand '&' @@ -159,11 +258,13 @@ RTTOV v12 Namelist +------------------------+--------------------+----------------------------------------------------------------------+ | Item | Type | Description | +========================+====================+======================================================================+ - | rttov_sensor_db_file | character(len=512) | The location of the RTTOV sensor database. The format for the | - | | | database is a comma-separated file. The columns of the database are | - | | | the DART observation-kind, the platform/satellite/sensor ID, the | - | | | observation type, the coefficient file, and a comma-separated list | - | | | of RTTOV channels to use for this observation type. | + | rttov_sensor_db_file | character(len=512) | The location of the DART file with RTTOV sensor metadata. The format | + | | | is a comma-separated file. The columns are the DART | + | | | observation type, the platform/satellite/sensor ID, the | + | | | wavelength band, the coefficient file, and a comma-separated list | + | | | of RTTOV channels to use for this observation type. The default file | + | | | does not provide a list of channels, thus default behavior is to | + | | | make all channels available. | +------------------------+--------------------+----------------------------------------------------------------------+ | first_lvl_is_sfc | logical | Whether the first level of the model represents the surface (true) | | | | or the top of the atmosphere (false). | diff --git a/observations/obs_converters/GOES/README.rst b/observations/obs_converters/GOES/README.rst index 661ae5dd07..08d1bcac69 100644 --- a/observations/obs_converters/GOES/README.rst +++ b/observations/obs_converters/GOES/README.rst @@ -35,70 +35,130 @@ observation type). Specifying a vertical location ------------------------------ -Jeff Steward added (PR 48) the capability to specify a vertical location -if desired. This allows for localization in the vertical. - - It’s sometimes helpful, even though definitely wrong from a theoretical - standpoint, to give a vertical location to satellite observations - (which are integrated quantities). This has been an issue with - observation-space localization for some time, and this is the standard - workaround pioneered by Lili Lei and Jeff Whittaker. - -A short description of the namelist options -------------------------------------------- - -This table is meant to familiarize you with some of the options -available. Until we fully implement automatic documentation generation, -you would be well advised to familiarize yourself with the code. This is -not the full list of namelist variables … - -+-------------------------+---------------------+---------------------+ -| variable | default | meaning | -+=========================+=====================+=====================+ -| x_thin | 0 | Skip this many per | -| | | X scan. | -+-------------------------+---------------------+---------------------+ -| y_thin | 0 | Skip this many per | -| | | Y scan. | -+-------------------------+---------------------+---------------------+ -| goes_num | 16 | GOES Satellite | -| | | number. | -+-------------------------+---------------------+---------------------+ -| reject_dqf_1 | .true. | Bad scan rejection | -| | | criteria. If .true. | -| | | and DQF /= 0, the | -| | | scan is rejected. | -| | | If .false. any DQF | -| | | > 1 rejects the | -| | | scan. | -+-------------------------+---------------------+---------------------+ -| verbose | .false. | Run-time output | -| | | verbosity | -+-------------------------+---------------------+---------------------+ -| obs_err | MISSING_R8 | The observation | -| | | error standard | -| | | deviation (std dev, | -| | | in radiance units) | -| | | TODO: make this | -| | | more sophisticated. | -| | | You must supply a | -| | | value other than | -| | | MISSING_R8. Be | -| | | aware that the | -| | | observation | -| | | sequence files | -| | | convert this to a | -| | | variance. | -+-------------------------+---------------------+---------------------+ -| vloc_pres_hPa | -1.0 | The vertical | -| | | location of this | -| | | observation (hPa). | -| | | A negative means | -| | | there is no | -| | | vertical location | -| | | (which is typical | -| | | for a | -| | | ve | -| | | rtically-integrated | -| | | quantity). | -+-------------------------+---------------------+---------------------+ +Top of the atmosphere radiance observations are sensitive to the +atmospheric constituents (e.g. water vapor) that reside in the vertical +profile of the atmosphere. Given this is an integrated quantity and does +not depend on a single vertical location, it may be appropriate to leave +the vertical location undefined (i.e. VERTISUNDEF) within the ``obs_seq.out`` +file, by setting the ``vloc_pres_hPa = -1`` (See namelist options below). This approach, +however, limits the application of vertical localization during the assimilation step. + +Alternatively, for some applications it may be appropriate to assign +a vertical location to the radiance observation, by setting the ``vloc_pres_hPa`` +to a vertical pressure level (hPa). This is an ongoing area +of observation-space localization research, and is the standard +workaround pioneered by Lili Lei and Jeff Whittaker. + +Radiance versus Brightness Temperature +-------------------------------------- + +This converter assigns the observation type as ``GOES[16-19]_ABI_RADIANCE``. +The default setup in DART is that this radiance observation type is assigned +the quantity ``QTY_RADIANCE``. Radiance observations are commonly expressed +in spectrally resolved units (mW/cm/m^2/sr). + +Alternatively, radiances can also be expressed as brightness temperatures +(units: Kelvin) and the DART code also supports observation quantities of +``QTY_BRIGHTNESS_TEMPERATURE``. Both the spectral and temperature units +quantify the same physical properties of the atmosphere +(emitted and reflected radiation), however, in some applications it may +be advantageous to use brightness temperatures given their Gaussian +distribution. This is an ongoing area of research. + + +An overview of the namelist options +----------------------------------- + +A description of the most important namelist options. Note that supplying +an observation error value is mandatory. This is not the full list of namelist +variables. + ++-------------------------+------------+-----------------------------+ +| Variable | Default | Description | ++=========================+============+=============================+ +| x_thin | 0 | Skip this many observations | +| | | per X scan | ++-------------------------+------------+-----------------------------+ +| y_thin | 0 | Skip this many observations | +| | | per Y scan | ++-------------------------+------------+-----------------------------+ +| goes_num | 16 | GOES Satellite number | ++-------------------------+------------+-----------------------------+ +| reject_dqf_1 | .true. | Bad scan rejection critera. | +| | | If .true. and DQF /= 0, the | +| | | scan is rejected. If | +| | | .false. any DQF > 1 | +| | | rejects the scan. | ++-------------------------+------------+-----------------------------+ +| verbose | .false. | Run-time output verbosity | ++-------------------------+------------+-----------------------------+ +| obs_err | MISSING_R8 | The observation error | +| | | standard deviation in units | +| | | of radiance. IMPORTANT: | +| | | the user must supply a | +| | | value other than MISSING_R8.| +| | | Be aware that the | +| | | observation sequence files | +| | | convert this to a variance. | ++-------------------------+------------+-----------------------------+ +| vloc_pres_hPa | -1.0 | If a positive value, the | +| | | vertical location of the | +| | | observation (hPa) is | +| | | assigned with a vertical | +| | | coordinate of | +| | | VERTISPRESSURE. If negative | +| | | value there is no vertical | +| | | location and the coordinate | +| | | is VERTISUNDEFINED. | ++-------------------------+------------+-----------------------------+ + +Radiance metadata supplied to obs_seq.out file +---------------------------------------------- + +This converter is designed to supply metadata to the radiative transfer +model (RTTOV) :doc:`../../../observations/forward_operators/obs_def_rttov_mod` +that supports the calculation of the expected radiance +observation during the assimilation step. Below is a description +of this metadata information. + +The integer values that describe the platform/satellite/sensor/channel +combination for the GOES satellite are required by the RTTOV radiance +model to assign the appropriate coefficent file during the radiance +calculation. For more details refer to the +`RTTOV user guide. `__ + + ++-------------------------+------------+-----------------------------+ +| Variable | Value | Description | ++=========================+============+=============================+ +| sat az/el | Supplied | GOES satellite azimuth and | +| | by data | elevation angle | +| | file | | ++-------------------------+------------+-----------------------------+ +| sun az/el | -888888 | Sun azimuth and elevation | +| | | angle. The default is for | +| | | missing values. For IR | +| | | channels reflected solar | +| | | has no impact. For NIR/ | +| | | VIS/UV providing sun az/el | +| | | may be desirable but not | +| | | required by RTTOV. | ++-------------------------+------------+-----------------------------+ +| platform | 4 | Platform number supplied | +| | | by converter code. | ++-------------------------+------------+-----------------------------+ +| sat_id | 16 | Satellite ID number | +| | | supplied by converter code. | ++-------------------------+------------+-----------------------------+ +| instrument | 44 | Sensor number supplied by | +| | | converter code | ++-------------------------+------------+-----------------------------+ +| channel | Supplied | The wavelength channel | +| | by data | (1-16) assigned from band_id| +| | file | variable in data file. | ++-------------------------+------------+-----------------------------+ + + + + + diff --git a/observations/obs_converters/GOES/goes_ABI_L1b_mod.f90 b/observations/obs_converters/GOES/goes_ABI_L1b_mod.f90 index 8681809939..65b81751aa 100644 --- a/observations/obs_converters/GOES/goes_ABI_L1b_mod.f90 +++ b/observations/obs_converters/GOES/goes_ABI_L1b_mod.f90 @@ -462,8 +462,9 @@ subroutine make_obs_sequence (seq, map, lon1, lon2, lat1, lat2, & specularity = MISSING_R8 end if - ! the RTTOV ABI coefficients start from channel 7 - goes_channel = map%channel-6 + ! Defines the GOES ABI wavelength channels (band_id) + ! Channels range from 1-16 covering UV/VIS/NIR/IR spectrum + goes_channel = map%channel ! add additional metadata for this obs type. returns key to use in create call call set_visir_metadata(key, sat_az, sat_ze, sun_az, sun_ze, platform_id, sat_id, sensor_id, & diff --git a/observations/obs_converters/GOES/work/input.nml b/observations/obs_converters/GOES/work/input.nml index 12dfacad97..4670d10498 100644 --- a/observations/obs_converters/GOES/work/input.nml +++ b/observations/obs_converters/GOES/work/input.nml @@ -5,7 +5,7 @@ output_obs_qty_mod_file = '../../../../assimilation_code/modules/observations/obs_kind_mod.f90' input_obs_def_mod_file = '../../../../observations/forward_operators/DEFAULT_obs_def_mod.F90' output_obs_def_mod_file = '../../../../observations/forward_operators/obs_def_mod.f90' - obs_type_files = '../../../../observations/forward_operators/obs_def_rttov_mod.f90' + obs_type_files = '../../../../observations/forward_operators/obs_def_rttov13_mod.f90' quantity_files = '../../../../assimilation_code/modules/observations/atmosphere_quantities_mod.f90', '../../../../assimilation_code/modules/observations/chemistry_quantities_mod.f90', '../../../../assimilation_code/modules/observations/land_quantities_mod.f90', @@ -13,15 +13,15 @@ / &convert_goes_ABI_L1b_nml - l1_files = '' - l1_file_list = 'l1_files_to_process' + l1_files = 'OR_ABI-L1b-RadF-M6C08_G16_s20211841720210_e20211841729518_c20211841729575.nc' + l1_file_list = '' outputfile = 'obs_seq.test' - x_thin = 5 - y_thin = 5 - lon1 = 235.0 - lon2 = 293.0 - lat1 = 25.0 - lat2 = 50.0 + x_thin = 7 + y_thin = 7 + lon1 = -80.2 + lon2 = -71.8 + lat1 = 14.9 + lat2 = 22.1 goes_num = 16 obs_err = 1.0 verbose = .true. @@ -83,74 +83,4 @@ &obs_def_rttov_nml rttov_sensor_db_file = '../../../forward_operators/rttov_sensor_db.csv' - first_lvl_is_sfc = .true. - mw_clear_sky_only = .false. - interp_mode = 1 - do_checkinput = .true. - apply_reg_limits = .true. - verbose = .true. - fix_hgpl = .false. - do_lambertian = .false. - lambertian_fixed_angle = .true. - rad_down_lin_tau = .true. - use_q2m = .true. - use_uv10m = .true. - use_wfetch = .false. - use_water_type = .false. - addrefrac = .false. - plane_parallel = .false. - use_salinity = .false. - apply_band_correction = .true. - cfrac_data = .true. - clw_data = .true. - rain_data = .true. - ciw_data = .true. - snow_data = .true. - graupel_data = .true. - hail_data = .false. - w_data = .true. - clw_scheme = 1 - clw_cloud_top = 322. - fastem_version = 6 - supply_foam_fraction = .false. - use_totalice = .true. - use_zeeman = .false. - cc_threshold = 0.05 - ozone_data = .false. - co2_data = .false. - n2o_data = .false. - co_data = .false. - ch4_data = .false. - so2_data = .false. - addsolar = .false. - rayleigh_single_scatt = .true. - do_nlte_correction = .false. - solar_sea_brdf_model = 2 - ir_sea_emis_model = 2 - use_sfc_snow_frac = .false. - add_aerosl = .false. - aerosl_type = 1 - add_clouds = .true. - ice_scheme = 1 - use_icede = .false. - idg_scheme = 2 - user_aer_opt_param = .false. - user_cld_opt_param = .false. - grid_box_avg_cloud = .true. - cldstr_threshold = -1.0 - cldstr_simple = .false. - cldstr_low_cloud_top = 750.0 - ir_scatt_model = 2 - vis_scatt_model = 1 - dom_nstreams = 8 - dom_accuracy = 0.0 - dom_opdep_threshold = 0.0 - addpc = .false. - npcscores = -1 - addradrec = .false. - ipcreg = 1 - use_htfrtc = .false. - htfrtc_n_pc = -1 - htfrtc_simple_cloud = .false. - htfrtc_overcast = .false. /