Skip to content

Commit

Permalink
Add specificHumidity to ADPUPA BUFR DUMP Python API (NOAA-EMC#1246)
Browse files Browse the repository at this point in the history
This PR adds specificHumidity to the ADPUPA BUFR DUMP Python API. The
following file has been changed:
~/ush/ioda/bufr2ioda/bufr2ioda_adpupa.py

The specificHumidity is calculated using the dewPoint and pressure. The
information is extracted from the prepBUFR codes and also documented.

The validation of the output obs is performed using the specificHumidity
from the prepBUFR data. For more details, please check: NOAA-EMC#1193

Co-authored-by: Praveen Singh <[email protected]>
  • Loading branch information
PraveenKumar-NOAA and Praveen Singh committed Aug 7, 2024
1 parent f3fa26d commit 67e8c50
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions ush/ioda/bufr2ioda/bufr2ioda_adpupa.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ def Compute_WindComponents_from_WindDirection_and_WindSpeed(wdir, wspd):
return uob, vob


def Compute_SpecificHumidity_from_dewPoint_and_Pressure(tmdp, prlc):

# est is saturated vapor pressure in Mb
est = 6.1078 * np.exp((17.269 * (tmdp - 273.16))/((tmdp - 273.16)+237.3))
# Change est from Mb to Pa
est = est*100.

# specificHumidity (qob) is in kg/kg
qob = (0.622 * est)/(prlc - (0.378 * est))
qob = ma.array(qob)
qob = ma.masked_values(qob, qob.fill_value)

return qob


def bufr_to_ioda(config, logger):

subsets = config["subsets"]
Expand Down Expand Up @@ -191,6 +206,7 @@ def bufr_to_ioda(config, logger):
dewpointTemperatureOE = np.float32(np.ma.masked_array(np.full((len(tmdp)), 0.0)))
windEastwardOE = np.float32(np.ma.masked_array(np.full((len(wspd)), 0.0)))
windNorthwardOE = np.float32(np.ma.masked_array(np.full((len(wspd)), 0.0)))
specificHumidityOE = np.float32(np.ma.masked_array(np.full((len(qob)), 0.0)))

end_time = time.time()
running_time = end_time - start_time
Expand All @@ -208,6 +224,9 @@ def bufr_to_ioda(config, logger):
logger.debug(f' uob min/max = {uob.min()} {uob.max()}')
logger.debug(f' vob min/max = {vob.min()} {vob.max()}')

qob = Compute_SpecificHumidity_from_dewPoint_and_Pressure(tmdp, prlc)
logger.debug(f' qob min/max = {qob.min()} {qob.max()}')

end_time = time.time()
running_time = end_time - start_time
logger.info(f'Processing time for creating derived variables : {running_time} seconds')
Expand Down Expand Up @@ -236,6 +255,7 @@ def bufr_to_ioda(config, logger):
logger.debug(f' wspd shape = {wspd.shape}')
logger.debug(f' uob shape = {uob.shape}')
logger.debug(f' vob shape = {vob.shape}')
logger.debug(f' qob shape = {qob.shape}')

logger.debug(f' qmpr shape = {qmpr.shape}')
logger.debug(f' qmat shape = {qmat.shape}')
Expand Down Expand Up @@ -264,6 +284,7 @@ def bufr_to_ioda(config, logger):
logger.debug(f' wspd type = {wspd.dtype}')
logger.debug(f' uob type = {uob.dtype}')
logger.debug(f' vob type = {vob.dtype}')
logger.debug(f' qob type = {qob.dtype}')

logger.debug(f' qmpr type = {qmpr.dtype}')
logger.debug(f' qmat type = {qmat.dtype}')
Expand Down Expand Up @@ -365,6 +386,12 @@ def bufr_to_ioda(config, logger):
.write_attr('long_name', 'Northward Wind') \
.write_data(vob)

# Specific Humidity
obsspace.create_var('ObsValue/specificHumidity', dtype=qob.dtype, fillval=qob.fill_value) \
.write_attr('units', 'kg kg-1') \
.write_attr('long_name', 'Specific Humidity') \
.write_data(qob)

# Pressure Quality Marker
obsspace.create_var('QualityMarker/pressure', dtype=qmpr.dtype, fillval=qmpr.fill_value) \
.write_attr('long_name', 'Pressure Quality Marker') \
Expand Down Expand Up @@ -420,6 +447,12 @@ def bufr_to_ioda(config, logger):
.write_attr('long_name', 'Northward Wind Observation Error') \
.write_data(windNorthwardOE)

# Specific Humidity Observation Error
obsspace.create_var('ObsError/specificHumidity', dtype=qob.dtype, fillval=qob.fill_value) \
.write_attr('units', 'kg kg-1') \
.write_attr('long_name', 'Specific Humidity Observation Error') \
.write_data(specificHumidityOE)

end_time = time.time()
running_time = end_time - start_time
logger.info(f"Running time for splitting and output IODA: {running_time} seconds")
Expand Down

0 comments on commit 67e8c50

Please sign in to comment.