-
Notifications
You must be signed in to change notification settings - Fork 32
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 the "state of ground" to bring in the extra snow depth reports #1368
base: develop
Are you sure you want to change the base?
Changes from 13 commits
1c8096f
365675d
aee4dc2
0c02522
e57ac67
4376049
244693c
76a5e94
2a72e4d
a2d87fd
fbd1bb9
db46314
91f160e
dc8d9b8
d7bf5d7
3c1dbf7
55b54cd
5cd21ab
47bfb19
bb85eb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,6 @@ bufr: | |
query: "[*/CLON, */CLONH]" | ||
stationIdentification: | ||
query: "*/RPID" | ||
|
||
stationElevation: | ||
query: "[*/SELV, */HSMSL]" | ||
|
||
|
@@ -26,11 +25,8 @@ bufr: | |
query: "[*/SNWSQ1/TOSD, */MTRMSC/TOSD, */STGDSNDM/TOSD]" | ||
transforms: | ||
- scale: 1000.0 | ||
filters: | ||
- bounding: | ||
variable: totalSnowDepth | ||
lowerBound: 0 | ||
upperBound: 10000000 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For my understanding:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I previously put this large number (10000m) here for removing the missing values. Here, we don't need this any more because we need to set the missing snod values to 0 when sogr satisfies the defined conditions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might still have missing values though wouldn't we? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The missing values will be removed after applying sogr conditions. |
||
groundState: | ||
query: "[*/GRDSQ1/SOGR, */STGDSNDM/SOGR]" | ||
|
||
encoder: | ||
variables: | ||
|
@@ -65,11 +61,18 @@ encoder: | |
coordinates: "longitude latitude" | ||
source: variables/stationIdentification | ||
longName: "Identification of Observing Location" | ||
units: "m" | ||
units: "index" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jiaruidong2017 The unit of stationIdentification is not defined (empty) in the IODA convention table, and it is left for users to decide. Have you discussed the unit for |
||
|
||
# ObsValue | ||
- name: "ObsValue/totalSnowDepth" | ||
coordinates: "longitude latitude" | ||
source: variables/totalSnowDepth | ||
longName: "Total Snow Depth" | ||
units: "mm" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jiaruidong2017 The unit of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have to keep using the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jiaruidong2017 Is it possible to read in the totalSnowDepth in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is possible, but will require additional efforts. We can discuss this issue with the physics team. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jiaruidong2017 I guess only a one-line change is necessary for UFS. You just need to convert There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This issue (mismatch between units proscribed by JEDI and those used in the UFS) is bigger than this PR - as all other snow depth IODA files are in mm too. If we change these observations to mm, we'll need to change the others. I suggest that we leave this in mm for now, and create a separate issue to address the unit mismatch (by introducing a unit transform somewhere). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. Let's keep it as "mm" for now. |
||
|
||
- name: "ObsValue/groundState" | ||
coordinates: "longitude latitude" | ||
source: variables/groundState | ||
longName: "STATE OF THE GROUND" | ||
units: "index" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,9 +5,12 @@ | |
halo size: 250e3 | ||
obsdatain: | ||
engine: | ||
type: bufr | ||
type: script | ||
script file: "{{ USHgfs }}/bufr2ioda_sfcsno_bufr_encoder.py" | ||
args: | ||
input_path: '{{ DATA }}/obs/{{ OPREFIX }}sfcsno.tm00.bufr_d' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion:
This will make it clear that the script backend requires two inputs: bufr file and the mapping file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @emilyhcliu for the suggestions. I made the changes as suggested. |
||
mapping_path: '{{ DATA }}/obs/bufr_sfcsno_mapping.yaml' | ||
obsfile: '{{ DATA }}/obs/{{ OPREFIX }}sfcsno.tm00.bufr_d' | ||
mapping file: '{{ DATA }}/obs/bufr_sfcsno_mapping.yaml' | ||
obsdataout: | ||
engine: | ||
type: H5File | ||
|
@@ -54,7 +57,7 @@ | |
where: | ||
- variable: | ||
name: MetaData/stationElevation | ||
minvalue: -999.0 | ||
maxvalue: 999999999.9 | ||
- filter: Domain Check # land only | ||
where: | ||
- variable: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import numpy as np | ||
import bufr | ||
from pyioda.ioda.Engines.Bufr import Encoder | ||
|
||
|
||
def mask_container(container, mask): | ||
new_container = bufr.DataContainer() | ||
for var_name in container.list(): | ||
var = container.get(var_name) | ||
paths = container.get_paths(var_name) | ||
new_container.add(var_name, var[mask], paths) | ||
|
||
return new_container | ||
|
||
|
||
def create_obs_group(input_path, mapping_path): | ||
"""Create the ioda snow observations | ||
This method: | ||
- reads state of ground (sogr) and snow depth (snod) | ||
- applys sogr conditions to the missing snod values | ||
- removes the filled/missing snow values and creates the masked container | ||
- encoders the new container. | ||
|
||
Parameters | ||
---------- | ||
input_path: The input bufr file | ||
mapping_path: The input bufr2ioda mapping file | ||
|
||
""" | ||
|
||
YAML_PATH = mapping_path | ||
container = bufr.Parser(input_path, YAML_PATH).parse() | ||
|
||
sogr = container.get('variables/groundState') | ||
snod = container.get('variables/totalSnowDepth') | ||
snod[(sogr <= 11.0) & snod.mask] = 0.0 | ||
snod[(sogr == 15.0) & snod.mask] = 0.0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was your intention to remove these values (treat them as missing) or just to set them to 0 as you have done here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you want to update the mask you should do something like this (instead of zeroing things out):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to set the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, just FYI I don't think this code does exactly what you think it does. The result of the container get returns a numpy masked array. I think the following might be more correct... snod[(sogr <= 11.0) & (~snod.mask)] = 0.0 I don't think you really need to manually mask out the masked values like this (since you are removing them later anyways). You could probably just do this: snod[(sogr <= 11.0) | (sogr == 15.0)] = 0.0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @rmclaren There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok |
||
container.replace('variables/totalSnowDepth', snod) | ||
|
||
masked_container = mask_container(container, (~snod.mask)) | ||
|
||
data = next(iter(Encoder(YAML_PATH).encode(masked_container).values())) | ||
|
||
return data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on IODA data convention, the unit of
totalSnowDepth
ism
. We should remove the conversion of it from meter to millimeter.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above to keep use the conversion.