Как применить анализ поперечного сечения MetPy к набору данных с 2-мерными широтами и широтами?

#metpy

Вопрос:

У меня есть 4-мерные данные (время, глубина, y и x), но широта и долгота являются 2d-массивами. y и x — это просто индексы, поэтому просто целые числа, начинающиеся с 0, 1 … end и т.д. Очень похоже на примерный набор данных, предоставленный MetPy:

https://unidata.github.io/MetPy/latest/examples/cross_section.html

К сожалению, это не самый воспроизводимый, потому что он очень специфичен для самих данных. Но у меня возникли проблемы с частью поперечного сечения. Я могу проанализировать данные в соответствии с metpy, но затем я получаю ошибку при получении поперечного сечения:

 data = ds.metpy.parse_cf().squeeze()

print(data)

<xarray.Dataset>
Dimensions:               (y: 1347, x: 1379, deptht: 46, axis_nbounds: 2, time_counter: 12)
Coordinates:
    nav_lat               (y, x) float32 20.92 20.92 20.92 ... 68.49 68.49 68.48
    nav_lon               (y, x) float32 -78.95 -78.9 -78.85 ... -3.614 -3.546
  * deptht                (deptht) float32 3.047 9.454 ... 5.625e 03 5.875e 03
    time_centered         (time_counter) datetime64[ns] 1993-01-16T12:00:00 ....
  * time_counter          (time_counter) datetime64[ns] 1993-01-16T12:00:00 ....
Dimensions without coordinates: y, x, axis_nbounds
Data variables: (12/17)
    deptht_bounds         (deptht, axis_nbounds, y, x) float32 0.0 0.0 ... nan
    time_centered_bounds  (time_counter, axis_nbounds, y, x) datetime64[ns] 1...
    time_counter_bounds   (time_counter, axis_nbounds, y, x) datetime64[ns] 1...
    votemper              (time_counter, deptht, y, x) float32 26.63 ... nan
    vosaline              (time_counter, deptht, y, x) float32 35.88 ... nan
    sosstsst              (time_counter, y, x) float32 26.63 26.58 ... nan nan
    ...                    ...
    sohefldo              (time_counter, y, x) float32 -50.02 -45.85 ... nan nan
    somixhgt              (time_counter, y, x) float32 19.84 19.76 ... nan nan
    sowindsp              (time_counter, y, x) float32 5.591 5.48 ... nan nan
    sohefldp              (time_counter, y, x) float32 nan nan nan ... nan nan
    sowafldp              (time_counter, y, x) float32 3.94e-06 ... nan
    sobowlin              (time_counter, y, x) float32 20.04 20.04 ... nan nan
Attributes:
    name:                      1_VIKING20X.L46-KKG36107B_1d_19930101_19930704...
    description:               ocean T grid variables
    title:                     ocean T grid variables
    Conventions:               CF-1.6
    timeStamp:                 2019-Sep-11 21:02:06 GMT
    uuid:                      a091f081-2943-4c66-aa77-0917f654b802
    history:                   Thu Sep 12 22:15:40 2019: ncrcat -O -F /gfs1/w...
    NCO:                       4.4.8
    nco_openmp_thread_number:  1
 

Затем я пробую часть поперечного сечения (просто чтобы отметить, что 2D широта и долгота помечены как ‘nav_lat’ и ‘nav_lon’, вместо широты и длины):

  start = (40, -40)
 end = (50, -30)
    
 cross = cross_section(data, start, end).set_coords(('nav_lon', 'nav_lat'))
 print(cross)

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/metpy/interpolate/slices.py in cross_section(data, start, end, steps, interp_type)
    165         try:
--> 166             crs_data = data.metpy.pyproj_crs
    167             x = data.metpy.x

~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/metpy/xarray.py in pyproj_crs(self)
    252         """Return the coordinate reference system (CRS) as a pyproj object."""
--> 253         return self.crs.to_pyproj()
    254 

~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/metpy/xarray.py in crs(self)
    232             return self._data_array.coords['metpy_crs'].item()
--> 233         raise AttributeError('crs attribute is not available.')
    234 

AttributeError: crs attribute is not available.

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
/tmp/ipykernel_2676704/3597335100.py in <module>
----> 1 cross = cross_section(data, start, end).set_coords(('nav_lon', 'nav_lat'))
      2 print(cross)

~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/metpy/interpolate/slices.py in cross_section(data, start, end, steps, interp_type)
    154     if isinstance(data, xr.Dataset):
    155         # Recursively apply to dataset
--> 156         return data.map(cross_section, True, (start, end), steps=steps,
    157                         interp_type=interp_type)
    158     elif data.ndim == 0:

~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/xarray/core/dataset.py in map(self, func, keep_attrs, args, **kwargs)
   5106         if keep_attrs is None:
   5107             keep_attrs = _get_keep_attrs(default=False)
-> 5108         variables = {
   5109             k: maybe_wrap_array(v, func(v, *args, **kwargs))
   5110             for k, v in self.data_vars.items()

~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/xarray/core/dataset.py in <dictcomp>(.0)
   5107             keep_attrs = _get_keep_attrs(default=False)
   5108         variables = {
-> 5109             k: maybe_wrap_array(v, func(v, *args, **kwargs))
   5110             for k, v in self.data_vars.items()
   5111         }

~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/metpy/interpolate/slices.py in cross_section(data, start, end, steps, interp_type)
    167             x = data.metpy.x
    168         except AttributeError:
--> 169             raise ValueError('Data missing required coordinate information. Verify that '
    170                              'your data have been parsed by MetPy with proper x and y '
    171                              'dimension coordinates and added crs coordinate of the '

ValueError: Data missing required coordinate information. Verify that your data have been parsed by MetPy with proper x and y dimension coordinates and added crs coordinate of the correct projection for each variable.
 

Я попробовал в качестве альтернативы, потому что, возможно, parse_cf вызывает проблемы:

 data = ds.metpy.assign_latitude_longitude(force=True).squeeze()
 

но тогда я все равно получаю ту же ошибку при применении поперечного сечения.

Есть идеи о том, как это исправить? Еще раз извините за отсутствие воспроизводимости, но любые идеи были бы очень полезны 🙂 Возможно, это связано с проекцией?

Это примерное изображение того, как данные выглядят в одном экземпляре времени и глубины (с учетом температуры):

введите описание изображения здесь

Ответ №1:

metpy.interpolate.cross_section требуется, чтобы ваши данные включали координаты измерений x и y и добавленную metpy_crs координату (из любого parse_cf или assign_crs ). В этой ситуации, когда эти координаты измерений x и y отсутствуют, но у вас есть координаты 2D широты и долготы, эти координаты измерений можно вычислить и добавить .metpy.assign_y_x() (вместо assign_latitude_longitude того, что вы заявили, что пытались, что делает обратное — добавление вспомогательных координат широты / долготы из координат измерений y / x).

Итак, если ваш набор данных имеет действительное отображение сетки CF, соответствующее вашей проекции данных, у вас будет:

 data = ds.metpy.parse_cf()
data = data.metpy.assign_y_x()

start = (40, -40)
end = (50, -30)
    
cross = cross_section(data, start, end).set_coords(('nav_lon', 'nav_lat'))
 

Если это не так:

 data = ds.metpy.assign_crs({
    "grid_mapping_name": "lambert_conformal_conic",
    "standard_parallel": 25.0,
    "longitude_of_central_meridian": 265.0,
    "latitude_of_projection_origin": 25.0,
})
data = data.metpy.assign_y_x()

start = (40, -40)
end = (50, -30)
    
cross = cross_section(data, start, end).set_coords(('nav_lon', 'nav_lat'))
 

(изменение атрибутов проекции на те, которые необходимы для вашей заданной проекции)

Комментарии:

1. Большое вам спасибо за помощь! ДА… к сожалению, я использую модель с вложенной сеткой, поэтому я думаю, что геометрия может отличаться от допустимого отображения сетки, поскольку я все еще получаю сообщение об ошибке, в котором говорится, что атрибут crs недоступен. Мне действительно нужно изучить геометрию модели, ха-ха, но это чрезвычайно полезно! 🙂