Skip to content

Commit

Permalink
Merge branch 'master' into StandardPUP
Browse files Browse the repository at this point in the history
  • Loading branch information
pysoer authored Nov 29, 2023
2 parents 1b53eab + aa381d5 commit 905890b
Show file tree
Hide file tree
Showing 6 changed files with 697 additions and 28 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
*.spec
docs/build
.coverage
htmlcov
htmlcov
.DS_Store
**/.DS_Store
.DS_Store?
98 changes: 80 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
[![Downloads](https://pepy.tech/badge/cinrad)](https://pepy.tech/project/cinrad)
[![DOI](https://zenodo.org/badge/139155365.svg)](https://zenodo.org/badge/latestdoi/139155365)

Decode CINRAD (China New Generation Weather Radar) data and visualize.
Decode CINRAD (China New Generation Weather Radar) data and visualize.

[中文说明](https://github.com/CyanideCN/PyCINRAD/blob/master/README_zh.md)
[中文说明](README_zh.md)

**`example` folder contains detailed examples!**

Expand Down Expand Up @@ -66,12 +66,15 @@ Attributes:
nyquist_vel: 8.37801
task: VCP21D
```

For example, it's very convenient to save data as netcdf format.

```python
>>> data.to_netcdf('1.nc')
```

`xarray` also makes interpolation very convenient.

```python
>>> data.interp(azimuth=np.deg2rad(300), distance=180)
<xarray.Dataset>
Expand Down Expand Up @@ -117,6 +120,14 @@ f = PUP(your_radar_file)
data = f.get_data()
```

ROSE2.0 standard format products, with _FMT_ in the filename, currently support most radial format data (PPI, CR, OHP, etc.), as well as some raster data (RHI, ET, VIL, etc.), and also support special format data (HI, TVS, MESO, STI, etc.).

```python
from cinrad.io import StandardPUP
f = StandardPUP(your_radar_file)
data = f.get_data()
```

#### Decode phased array radar data

`cinrad.io.PhasedArrayData` provides similar interface to decode level 2 data from phased array radar.
Expand Down Expand Up @@ -163,10 +174,39 @@ fig('D:\\')

`cinrad.calc.GridMapper` can merge different radar scans into a cartesian grid.

```python
import cinrad
f1 = cinrad.io.StandardData(your_radar_file1)
f2 = cinrad.io.StandardData(your_radar_file2)
br1 = f1.get_data(2, 230, "REF")
br2 = f2.get_data(2, 230, "REF")
br = br1 + br2
gm = cinrad.calc.GridMapper(list(rls), max_dist=0.05)
grids = gm(step=0.05)
# to visualize:PPI(grids,style="black")
```

The combined reflectivity puzzle is TODO



#### Hydrometeor classification

`cinrad.calc.hydro_class` uses algorithm suggested by Dolan to classify hydrometeors into 10 categories. (Requires REF, ZDR, RHO, and KDP)

```python
import cinrad
f = cinrad.io.StandardData(your_radar_file)
ref = f.get_data(0, 230, 'REF')
zdr = f.get_data(0, 230, 'ZDR')
rho = f.get_data(0, 230, 'RHO')
kdp = f.get_data(0, 230, 'KDP')

hcl = cinrad.calc.hydro_class(ref, zdr, rho, kdp)
fig = cinrad.visualize.PPI(hcl,style="white")
fig("d:/")
```

### cinrad.correct

This submodule provides algorithms to correct raw radar fields.
Expand All @@ -187,11 +227,15 @@ v_corrected = cinrad.correct.dealias(v)
Visualize the data stored in acceptable format (`cinrad.datastruct`). It also means that you can using customized data to perform visualization, as long as the data is stored as `xarray.Dataset` and constructed by the same protocol (variables naming conventions, data coordinates and dimensions, etc.) For further information about this method, please see the examples contained in `example` folder.

```python
# eg.1
from cinrad.visualize import PPI
fig = PPI(R) #Plot PPI
fig('D:\\') #Pass the path to save the fig
fig = PPI(data, add_city_names=True, dpi=300, style="black") #draw br
fig.gridlines(draw_labels=True,linewidth=1)
fig('D:\\') #save

# eg.2
from cinrad.visualize import Section
fig = Section(Slice_) #Plot VCS
fig = Section(sec) #draw section
fig('D:\\')
```

Expand All @@ -201,31 +245,49 @@ The path passed into the class can either be the folder path or the file path. A

The summary of args that can be passed into `PPI` are listed as follows.

|arg|function|
|:-:|:-:|
|`cmap`|colormaps used for plotting|
|`norm`|norm used for plotting|
|`nlabel`|number of labels on the colorbar|
|`label`|labels on the colorbar|
|`highlight`|highlight area of input name|
|`dpi`|dpi of figure|
|`extent`|area to plot e.g. `extent=[90, 91, 29, 30]`|
|`section`|cross-section data to ppi plot|
|`style`|control the background color `black` or `white`|
|`add_city_names`|annotate name of city on the plot|
| arg | function |
| :--------------: | :--------------------------------------------------------------: |
| `cmap` | colormaps used for plotting |
| `norm` | norm used for plotting |
| `nlabel` | number of labels on the colorbar |
| `label` | labels on the colorbar |
| `highlight` | highlight area of input name |
| `dpi` | dpi of figure |
| `extent` | area to plot e.g. `extent=[90, 91, 29, 30]` |
| `section` | cross-section data to ppi plot |
| `style` | control the background color `black` or `white` or `transparent` |
| `add_city_names` | annotate name of city on the plot |

Beside args, class `PPI` has some other auxiliary plotting functions.

##### PPI.plot_range_rings(self, _range, color='white', linewidth=0.5, **kwargs)
##### PPI.plot_range_rings(self, \_range, color='white', linewidth=0.5, \*\*kwargs)

Plot range rings on the PPI plot.

##### PPI.gridlines(self, draw_labels: bool = True, linewidth: Number_T = 0, **kwargs):

Plot gridlines on the PPI plot.

##### PPI.plot_cross_section(self, data, ymax=None)

Plot VCS section under the PPI plot.

This function is very similar to `vcs` argument of class `PPI`, but the range of y-axis can be adjusted only by this function.

```python
f = StandardData(your_radar_file)
rl = list(f.iter_tilt(230, "REF"))
cr = cinrad.calc.quick_cr(rl)
fig = PPI(cr, dpi=300, style="black")
vcs = cinrad.calc.VCS(rl)
sec = vcs.get_section(start_cart=(112, 27), end_cart=(114, 28)) # cart_sec
# sec = vcs.get_section(start_polar=(113, 250), end_polar=(114, 28)) # polar_sec
fig.plot_cross_section(sec, linecolor="red")
fig.plot_range_rings([100, 200, 300], color="white", linewidth=3) # draw rings
fig.gridlines(draw_labels=True, linewidth=1, color="white") # draw grids
fig("D:/")
```

##### PPI.storm_track_info(self, filepath)

Plot PUP STI product on the current PPI map, including past positions, current position, and forecast positions.
Expand Down
75 changes: 67 additions & 8 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ python setup.py install

```python
from cinrad.io import CinradReader, StandardData
f = CinradReader(your_radar_file) #老版本数据
f = StandardData(your_radar_file) #新版本标准数据
f = CinradReader(your_radar_file,radar_type="CC") #老版本数据,如果识别雷达型号出错时,手动输入radar_type
f = StandardData(your_radar_file) #新版本标准数据,一般来说,文件名中间有_FMT_
f.get_data(tilt, drange, dtype) #获取数据
f.get_raw(tilt, drange, dtype)
```
Expand Down Expand Up @@ -119,6 +119,19 @@ f = PUP(your_radar_file)
data = f.get_data()
```

```python
from cinrad.io import SWAN
f = SWAN(your_radar_file, product="CR")
data = f.get_data()
```
ROSE2.0 新标准格式产品,文件中一般有“_FMT_”,目前支持绝大部分径向格式数据(PPI、CR、OHP等),以及部分栅格数据(RHI、ET、VIL等),还支持特殊格式的数据(HI、TVS、MESO、STI等)。

```python
from cinrad.io import StandardPUP
f = StandardPUP(your_radar_file)
data = f.get_data()
```

#### 读取相控阵雷达数据

`cinrad.io.PhasedArrayData`提供读取相控阵雷达基数据的功能,用法和其他接口非常类似。
Expand Down Expand Up @@ -155,6 +168,14 @@ data = f.get_data(0, 40, 'REF')
r_list = [f.get_data(i, drange, 'REF') for i in f.angleindex_r]
# 或者
r_list = list(f.iter_tilt(230, 'REF'))

# 计算cr/et/vil/vild
cr = cinrad.calc.quick_cr(r_list)
et = cinrad.calc.quick_et(r_list)
vil = cinrad.calc.quick_vil(r_list)
vild = cinrad.calc.quick_vild(r_list)
# 可以调用PPI画图
fig = cinrad.visualize.PPI(cr)
```
#### VCS

Expand All @@ -175,12 +196,32 @@ fig('D:\\')

#### 雷达拼图

`cinrad.calc.GridMapper`可以将不同雷达的扫描数据合并成雷达格点拼图。

`cinrad.calc.GridMapper`可以将不同雷达的扫描数据合并成雷达格点拼图,即拼基本反射率。
```python
import cinrad
f1 = cinrad.io.StandardData(your_radar_file1)
f2 = cinrad.io.StandardData(your_radar_file2)
br1 = f1.get_data(2, 230, "REF")
br2 = f2.get_data(2, 230, "REF")
br = br1 + br2
gm = cinrad.calc.GridMapper(list(rls), max_dist=0.05)
grids = gm(step=0.05)
# to visualize:PPI(grids,style="black")
```
`组合反射率拼图`还无法直接支持
#### 水凝物分类

`cinrad.calc.hydro_class`从反射率,差分反射率,协相关系数和差分传播相移率计算出10种水凝物类型。

```python
import cinrad
f = cinrad.io.StandardData(your_radar_file)
ref = f.get_data(0, 230, 'REF')
zdr = f.get_data(0, 230, 'ZDR')
rho = f.get_data(0, 230, 'RHO')
kdp = f.get_data(0, 230, 'KDP')
hcl = cinrad.calc.hydro_class(ref, zdr, rho, kdp)
# to visualize:PPI(hcl,style="black")
```
### cinrad.correct

提供雷达原数据的校正。
Expand All @@ -203,9 +244,13 @@ v_corrected = cinrad.correct.dealias(v)
示例:

```python
# eg.1
from cinrad.visualize import PPI
fig = PPI(R) #绘制基本反射率图片
fig = PPI(data, add_city_names=True, dpi=300, style="black") #绘制基本反射率图片
fig.gridlines(draw_labels=True,linewidth=1) #画网格线
fig('D:\\') #传入文件夹路径保存图片

# eg.2
from cinrad.visualize import Section
fig = Section(sec) #绘制剖面
fig('D:\\')
Expand All @@ -229,20 +274,34 @@ fig('D:\\')
|`dpi`|分辨率|
|`extent`|绘图的经纬度范围 e.g. `extent=[90, 91, 29, 30]`|
|`section`|`ppi`图中绘制的剖面的数据,为`xarray.Dataset`类型|
|`style`|背景颜色,可设置为黑色`black`或者白色`white`|
|`style`|背景颜色,可设置为黑色`black`或者白色`white`或者透明图`transparent`|
|`add_city_names`|标注城市名|

同时`PPI`类中定义有其他绘图函数:
##### PPI.plot_range_rings(self, _range, color='white', linewidth=0.5, **kwargs)

在PPI图上绘制圆圈。

##### PPI.gridlines(self, draw_labels: bool = True, linewidth: Number_T = 0, **kwargs):

在PPI上绘制经纬度网格线

##### PPI.plot_cross_section(self, data, ymax=None)

在PPI图下方加入VCS剖面图,和`vcs`参数相似,用此函数还可以自定义y轴的范围。需要注意的是,在`%matplotlib inline`环境下,不能使用此方法插入剖面。请在实例化`PPI`时就使用`section`参数来插入剖面。

```python
fig = cinrad.visualize.PPI(data, section=section_data)
f = StandardData(your_radar_file)
rl = list(f.iter_tilt(230, "REF"))
cr = cinrad.calc.quick_cr(rl)
fig = PPI(cr, dpi=300, style="black")
vcs = cinrad.calc.VCS(rl)
sec = vcs.get_section(start_cart=(112, 27), end_cart=(114, 28)) # 传入经纬度坐标
# sec = vcs.get_section(start_polar=(113, 250), end_polar=(114, 28)) # 传入极坐标
fig.plot_cross_section(sec, linecolor="red")
fig.plot_range_rings([100, 200, 300], color="white", linewidth=3)# 用这个来画圈
fig.gridlines(draw_labels=True, linewidth=1, color="white")# 用这个来画经纬度网格线
fig("D:/")
```

##### PPI.storm_track_info(self, filepath)
Expand Down
30 changes: 29 additions & 1 deletion cinrad/data/radar_station.json
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@
396.0
],
"Z9737": [
"\u5b89\u5316",
"\u76ca\u9633",
111.21194444444444,
28.379166666666666,
"SA",
Expand Down Expand Up @@ -1482,5 +1482,33 @@
36.28638888888889,
"CB",
3824.0
],
"Z9537": [
"\u6d4e\u5b81",
116.270636,
3529249,
"CAD",
38.0
],
"Z9094": [
"\u4e60\u6c34",
106.226325,
28.269191,
"CAD",
1446.0
],
"Z9095": [
"\u52a1\u5ddd",
107.812935,
28.712447,
"CAD",
1164.0
],
"Z9096": [
"\u6995\u6c5f",
105.443122,
28.89593,
"CAD",
1350.0
]
}
1 change: 1 addition & 0 deletions cinrad/io/level3.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Optional, Union, Any
import datetime
from io import BytesIO
import warnings

import numpy as np
from xarray import Dataset, DataArray
Expand Down
Loading

0 comments on commit 905890b

Please sign in to comment.