colindex2 2.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- colindex2-2.9.0/LICENSE +21 -0
- colindex2-2.9.0/PKG-INFO +269 -0
- colindex2-2.9.0/README.md +242 -0
- colindex2-2.9.0/colindex2/__init__.py +11 -0
- colindex2-2.9.0/colindex2/circle_overlap.py +122 -0
- colindex2-2.9.0/colindex2/colindex2.py +580 -0
- colindex2-2.9.0/colindex2/commands.py +285 -0
- colindex2-2.9.0/colindex2/data_settings.py +50 -0
- colindex2-2.9.0/colindex2/draw_map.py +235 -0
- colindex2-2.9.0/colindex2/get_IDfile.py +331 -0
- colindex2-2.9.0/colindex2/modules.py +976 -0
- colindex2-2.9.0/colindex2/tracking_overlap2.py +1107 -0
- colindex2-2.9.0/colindex2.egg-info/PKG-INFO +269 -0
- colindex2-2.9.0/colindex2.egg-info/SOURCES.txt +18 -0
- colindex2-2.9.0/colindex2.egg-info/dependency_links.txt +1 -0
- colindex2-2.9.0/colindex2.egg-info/entry_points.txt +6 -0
- colindex2-2.9.0/colindex2.egg-info/requires.txt +9 -0
- colindex2-2.9.0/colindex2.egg-info/top_level.txt +1 -0
- colindex2-2.9.0/setup.cfg +4 -0
- colindex2-2.9.0/setup.py +26 -0
colindex2-2.9.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-2024 satoru kasuga
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
colindex2-2.9.0/PKG-INFO
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: colindex2
|
|
3
|
+
Version: 2.9.0
|
|
4
|
+
Summary: depression detection/tracking schemes
|
|
5
|
+
Home-page: https://gitlab.com/kasugab3621/colindex2.git
|
|
6
|
+
Author: Satoru Kasuga
|
|
7
|
+
Author-email: kasugab3621@outlook.com
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
Requires-Dist: pandas
|
|
12
|
+
Requires-Dist: xarray
|
|
13
|
+
Requires-Dist: scipy>=0.16
|
|
14
|
+
Requires-Dist: numba
|
|
15
|
+
Requires-Dist: netCDF4
|
|
16
|
+
Requires-Dist: h5netcdf
|
|
17
|
+
Requires-Dist: matplotlib
|
|
18
|
+
Requires-Dist: cartopy
|
|
19
|
+
Dynamic: author
|
|
20
|
+
Dynamic: author-email
|
|
21
|
+
Dynamic: description
|
|
22
|
+
Dynamic: description-content-type
|
|
23
|
+
Dynamic: home-page
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
Dynamic: requires-dist
|
|
26
|
+
Dynamic: summary
|
|
27
|
+
|
|
28
|
+
# colindex2
|
|
29
|
+
|
|
30
|
+
<div align="left">
|
|
31
|
+
<img src="map.png" width="40%">
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
A python package for atmospheric depression detection and tracking. The main target is to capture upper tropospheric depressions such as cutoff lows and blockng highs from their earlier stages of troughs and ridges, respectively, with their seamless transitions of vortex-related variables.
|
|
35
|
+
|
|
36
|
+
### Reference
|
|
37
|
+
|
|
38
|
+
- Kasuga, S., M. Honda, J. Ukita, S. Yaname, H. Kawase, A. Yamazaki, 2021: Seamless detection of cutoff lows and preexisting troughs. *Monthly Weather Review*, **149**, 3119–3134, [https://doi.org/10.1175/MWR-D-20-0255.1](https://doi.org/10.1175/MWR-D-20-0255.1)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
:warning: The tracking scheme is underconstruction and its definition may be changed unnoticed. The relatively stabe versions are v2.7.6, and v2.8.1 See Tags and CHANGELOG. (edit: 2025.4.30)
|
|
42
|
+
|
|
43
|
+
# Install
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
pip install git+https://gitlab.com/kasugab3621/colindex2.git
|
|
47
|
+
```
|
|
48
|
+
Dependecies are `numpy`, `pandas`, `numba`, `xarary`, `netCDF4`, and `h5netcdf`.
|
|
49
|
+
<!--
|
|
50
|
+
> If you use anaconda environment, prepare the dependencies using `conda` in advance and then install `colindex2` using conda's `pip`, as recommended by [ANACONDA](https://www.anaconda.com/blog/using-pip-in-a-conda-environment).
|
|
51
|
+
-->
|
|
52
|
+
|
|
53
|
+
# Table of contents
|
|
54
|
+
[[_TOC_]]
|
|
55
|
+
|
|
56
|
+
# How to execute
|
|
57
|
+
## Import use for python users
|
|
58
|
+
|
|
59
|
+
Below examples excecute the detection and tracking with default settings.
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
# importing
|
|
63
|
+
import xarray as xr
|
|
64
|
+
from colindex2 import Detect, Track
|
|
65
|
+
|
|
66
|
+
# make xr.DataArray of a latitude-longitude 2-dimensional field
|
|
67
|
+
# with a temporal axis (such as "time"/"valid_time")
|
|
68
|
+
z = xr.open_dataarray("z.nc")
|
|
69
|
+
|
|
70
|
+
# execute detection with default options
|
|
71
|
+
Detect(z)
|
|
72
|
+
|
|
73
|
+
# execute tracking with default options
|
|
74
|
+
# set date range (pd.date_range) and level of the field (e.g., 300 hPa) to be tracked
|
|
75
|
+
track_times = pd.date_range("yyyy-mm-dd hh", "yyyy-mm-dd hh", freq="6h")
|
|
76
|
+
Track(track_times, 300)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
<details>
|
|
80
|
+
|
|
81
|
+
<summary> Important arguments and defaults </summary>
|
|
82
|
+
|
|
83
|
+
- For `Detect()`
|
|
84
|
+
|
|
85
|
+
| args| values | description |
|
|
86
|
+
| ---- | ----------- | ----- |
|
|
87
|
+
| odir | "./d01" | parent output directory name |
|
|
88
|
+
| r | np.arange(200,2101,100) | searching radius variable r [km]|
|
|
89
|
+
| SR_thres | 3.0 | SR threshold to remove tiny trough |
|
|
90
|
+
| So_thres | 3.0 | So threshold to remove weak vortices [m/100km]|
|
|
91
|
+
|
|
92
|
+
- For `Track()`
|
|
93
|
+
|
|
94
|
+
| args| values | description |
|
|
95
|
+
| ---- | ----------- | ----- |
|
|
96
|
+
| odir | "./d01" | parent output directory name |
|
|
97
|
+
| tlimit | 150.0 | Traveling speed limit to prevent wrong connections by large depressions [km/h]. Default 150 km/h is 900 km in 6 hour. |
|
|
98
|
+
| long_term | False | If False, tracking ID will be continuously counted up during the analysis period, and massive memory usage may occur. If True, tracking ID will be labeled from 1 in every 00UTC 1st Jan. |
|
|
99
|
+
| DU_thres | 0 | Threshold for noise removal with respect to duration (life time) [hour]. Note this parameter is sensitive to short-time noise, thus to remove noises try 24 or 36. |
|
|
100
|
+
|
|
101
|
+
</details>
|
|
102
|
+
|
|
103
|
+
## Command use for non-python users
|
|
104
|
+
But, python3 and requirements must be installed.
|
|
105
|
+
|
|
106
|
+
If you add `-h` for the respective commands, their documets will be appear.
|
|
107
|
+
|
|
108
|
+
- 1. Generate data_settings.py
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
$ gen_data_settings
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- 2. Edit [data_settings.py](data_settings.py)
|
|
115
|
+
|
|
116
|
+
- 3. Run detection
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
$ detect z.nc
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- 4. Run tracking
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
$ track
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- Draw maps to check tracking data and AS (netcdf output only)
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
$ draw_map z.nc ./d01 L 300 nps
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
- Find and make each tracking data
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
$ find_track ./d01 L 300 a
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
# How to use outputs
|
|
141
|
+
## Directory structure of outputs
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
current_dir/
|
|
145
|
+
|
|
|
146
|
+
└── d01/ # default name
|
|
147
|
+
|
|
|
148
|
+
├── AS/ # 2D averaged slope function
|
|
149
|
+
| └── AS-{ty}-{yyyymmddhhTT}-{llll}.nc (or .grd)
|
|
150
|
+
|
|
|
151
|
+
├── V/ # point values after detection
|
|
152
|
+
| └── V-{ty}-{yyyymmddhhTT}-{llll}.csv
|
|
153
|
+
|
|
|
154
|
+
├── Vt/ # intermediate data
|
|
155
|
+
| └── V-{ty}-{yyyymmddhhTT}-{llll}.csv
|
|
156
|
+
|
|
|
157
|
+
├── Vtc/ # final point values after tracking
|
|
158
|
+
| └── V-{ty}-{yyyymmddhhTT}-{llll}.csv
|
|
159
|
+
|
|
|
160
|
+
└── ID/ # continuous csv for a specific track whose id is `ID`
|
|
161
|
+
└── {ty}-{l}-{yyyymm}-{ID}.csv
|
|
162
|
+
```
|
|
163
|
+
where, `ty` is `L` or `H`, `yyyymmddhhTT` is timestep, `llll` is level in 4 digits, and `l` is level.
|
|
164
|
+
|
|
165
|
+
## How to load outputs in programs
|
|
166
|
+
|
|
167
|
+
- python3
|
|
168
|
+
|
|
169
|
+
point data (`V` and `Vtc`, csv)
|
|
170
|
+
```python
|
|
171
|
+
import pandas as pd
|
|
172
|
+
df = pd.read_csv(path_to_V, parse_dates=["time"])
|
|
173
|
+
```
|
|
174
|
+
mesh data (`AS`, netcdf)
|
|
175
|
+
```python
|
|
176
|
+
import xarray
|
|
177
|
+
da = xr.open_dataarray(path_to_AS)
|
|
178
|
+
```
|
|
179
|
+
- julia
|
|
180
|
+
|
|
181
|
+
point data (`V` and `Vtc`, csv)
|
|
182
|
+
```julia
|
|
183
|
+
using CSV, DataFrames, Dates
|
|
184
|
+
df = CSV.read(path_to_V, DataFrame)
|
|
185
|
+
df.time = DateTime.(df.time, "yyyy-mm-dd HH:MM:SS")
|
|
186
|
+
```
|
|
187
|
+
mesh data (`AS`, netcdf)
|
|
188
|
+
```julia
|
|
189
|
+
using Datasets
|
|
190
|
+
ds = Dataset(path_to_AS)
|
|
191
|
+
ar = ds["AS"][:,:]
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Variable parameters for point value csv (`Vct`)
|
|
195
|
+
|
|
196
|
+
<details>
|
|
197
|
+
<summary> Click here </summary>
|
|
198
|
+
|
|
199
|
+
| Names| Description |
|
|
200
|
+
| ---- | ----------- |
|
|
201
|
+
| time | Time. |
|
|
202
|
+
| ty | 0 for lows and troughs, 1 for highs and ridges |
|
|
203
|
+
| lev | Level. Usually in hPa. |
|
|
204
|
+
| lat, lon | Central coorditates in latitude and longitude. |
|
|
205
|
+
| valV | Value of input field on the center |
|
|
206
|
+
| valX | Value of the nearest local minimum (maximum) of input field for a low (high). |
|
|
207
|
+
| lonX,latX | Latitude and longitude of the nearest local extremum. If the deteciton depressino is trough or ridge, this value will be 999.9 |
|
|
208
|
+
| So | Optimal slope [m/100 km]. Intensity of depresion (as circular geostrophic winds). |
|
|
209
|
+
| ro | Optimal radius [r km]. Size of depression (as a radius of the circulation). |
|
|
210
|
+
| Do | Optimal depth [m]. Vertical depth of depression, generally proportional to ro. |
|
|
211
|
+
| SBG | Background slope [m/100 km]. |
|
|
212
|
+
| SBGang | Angle of Background slope vector [radian]. 0 for east. |
|
|
213
|
+
| m, n | Zonal, meridional components of SBG, respectivelly [m/100 km]. |
|
|
214
|
+
| SR | Slope ratio. For analytic characters of a Gaussian-shaped depression, 0.-1.34 for vortices, 1.34- for waves, and larger values (e.g., 3.) for ripples in a jet. |
|
|
215
|
+
| ex | Distinction between depressions and waves. <br>1 (there is a extremum within ro\*0.65) for lows/highs and 0 (otherwise) for troughs/ridges. |
|
|
216
|
+
| EE | Eccentricity (1 for pure isotropic, smaller values for Ellipses). |
|
|
217
|
+
| XX | Zonal discrete laplacian with a step of ro [m/(100 km)**2]. Small value means the feature has weak structure in zonal like sub-tropical ridges. |
|
|
218
|
+
| ID | Identification number. Tend to be larger than number of detection since it includes noises |
|
|
219
|
+
| MERGE | Merge lysis flag. <br>`-1` for soritary lysis, <br>`-2` for being merged from someone, <br>`-3` for lysis at the end of analysis, <br>`-4` for being involved in the secondary proces (see Fig. S2 in KH25), <br>other integers for the object ID of its merge lysis. |
|
|
220
|
+
| SPLIT | Split genesis flag. <br>`-1` for soritary genesis, <br>`-2` for being splitting and producing someone, <br>`-3` for genesis at the start of analysis, <br>`-4` for being involved in the secondary proces (see Fig. S2 in KH25), <br>other integers for the object ID of its split genesis. |
|
|
221
|
+
| DIST | Moving distance in a timestep [km]. Central difference. When merge/split/genesis/lysis, value will be missing, and the same applies to SPEED and DIR. |
|
|
222
|
+
| SPEED | Moving speed [m/s]. DIST/timestep. |
|
|
223
|
+
| DIR | Moving direction [radian]. 0 for east. |
|
|
224
|
+
| \_ DC | Accumulated duration [timestep] including before split. |
|
|
225
|
+
| DU | Duration [hour]. |
|
|
226
|
+
| XS | Sequential duration being ex=1 (lows/highs). |
|
|
227
|
+
| QS5 | 1 for Quasi-stational with 85% temporal overlapping of ro circles. |
|
|
228
|
+
| QS7 | As with QS5 but with 70%. |
|
|
229
|
+
| ALLDIST | Accumulated moving distance [km]. |
|
|
230
|
+
| MEDDIST | Median moving distance of all timesteps [km]. |
|
|
231
|
+
| MAX | 1 for the maximum development timestep (maximum So). |
|
|
232
|
+
| MAXSo | So when MAX. |
|
|
233
|
+
| MAXXS | Maximum duration of XS in a track (XS can be scored in multiple sequences). |
|
|
234
|
+
| MAXQS5 | Maximum duration of QS5 in a track. |
|
|
235
|
+
| MAXQS7 | Maximum duration of QS7 in a track. |
|
|
236
|
+
| exGEN | Genesis as vortex (`ex` changed from `0` to `1` for t-1 to t). |
|
|
237
|
+
| exLYS | Lysis as vortex (`ex` changed from `1` to `0` for t to t+1). |
|
|
238
|
+
|
|
239
|
+
</details>
|
|
240
|
+
|
|
241
|
+
## How to get csv for a specific track
|
|
242
|
+
|
|
243
|
+
Please obtain the ID for a specific depressin and its appeared year and month in advance.
|
|
244
|
+
|
|
245
|
+
Use `find_one` function by importing Finder.
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
from colindex2 import Finder
|
|
249
|
+
|
|
250
|
+
# set output dir (default:"`./d01`") and timestep of output csv in `Vtc`
|
|
251
|
+
F = Finder(odir="./d01", timestep=6)
|
|
252
|
+
|
|
253
|
+
# set type (`"L"` or `"H"` for low or high detection, respectively), level (e.g., 300 hPa here), and year/month with 6 digits (e.g., 201504) when the feature appeared, and ID for the specific feature (e.g., 333)
|
|
254
|
+
# here, the result will be produced at "`./d01/ID/L-300-201504-333.csv`"
|
|
255
|
+
F.find_one("L", 300, 201504, 333)
|
|
256
|
+
|
|
257
|
+
# try below to concatenate the specific track with before splitting from and after merging to other features
|
|
258
|
+
F.find_one("L", 300, 201504, 333, before_split=True, after_merge=True)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
You can use following functions (experimental, welcome bug reports!)
|
|
262
|
+
|
|
263
|
+
- `count_all(ty, lev)`: Print out count of all tracks on the specific level in the output directory.
|
|
264
|
+
|
|
265
|
+
- `find_all(ty, lev, all_in_one=False)`: Search all tracks on the specific level in a whole time range and save them as csvs. Recommended for case studies.
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
# For more details
|
|
269
|
+
see [documents](https://kasugab3621.gitlab.io/colindex2/index.html).
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# colindex2
|
|
2
|
+
|
|
3
|
+
<div align="left">
|
|
4
|
+
<img src="map.png" width="40%">
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
A python package for atmospheric depression detection and tracking. The main target is to capture upper tropospheric depressions such as cutoff lows and blockng highs from their earlier stages of troughs and ridges, respectively, with their seamless transitions of vortex-related variables.
|
|
8
|
+
|
|
9
|
+
### Reference
|
|
10
|
+
|
|
11
|
+
- Kasuga, S., M. Honda, J. Ukita, S. Yaname, H. Kawase, A. Yamazaki, 2021: Seamless detection of cutoff lows and preexisting troughs. *Monthly Weather Review*, **149**, 3119–3134, [https://doi.org/10.1175/MWR-D-20-0255.1](https://doi.org/10.1175/MWR-D-20-0255.1)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
:warning: The tracking scheme is underconstruction and its definition may be changed unnoticed. The relatively stabe versions are v2.7.6, and v2.8.1 See Tags and CHANGELOG. (edit: 2025.4.30)
|
|
15
|
+
|
|
16
|
+
# Install
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
pip install git+https://gitlab.com/kasugab3621/colindex2.git
|
|
20
|
+
```
|
|
21
|
+
Dependecies are `numpy`, `pandas`, `numba`, `xarary`, `netCDF4`, and `h5netcdf`.
|
|
22
|
+
<!--
|
|
23
|
+
> If you use anaconda environment, prepare the dependencies using `conda` in advance and then install `colindex2` using conda's `pip`, as recommended by [ANACONDA](https://www.anaconda.com/blog/using-pip-in-a-conda-environment).
|
|
24
|
+
-->
|
|
25
|
+
|
|
26
|
+
# Table of contents
|
|
27
|
+
[[_TOC_]]
|
|
28
|
+
|
|
29
|
+
# How to execute
|
|
30
|
+
## Import use for python users
|
|
31
|
+
|
|
32
|
+
Below examples excecute the detection and tracking with default settings.
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
# importing
|
|
36
|
+
import xarray as xr
|
|
37
|
+
from colindex2 import Detect, Track
|
|
38
|
+
|
|
39
|
+
# make xr.DataArray of a latitude-longitude 2-dimensional field
|
|
40
|
+
# with a temporal axis (such as "time"/"valid_time")
|
|
41
|
+
z = xr.open_dataarray("z.nc")
|
|
42
|
+
|
|
43
|
+
# execute detection with default options
|
|
44
|
+
Detect(z)
|
|
45
|
+
|
|
46
|
+
# execute tracking with default options
|
|
47
|
+
# set date range (pd.date_range) and level of the field (e.g., 300 hPa) to be tracked
|
|
48
|
+
track_times = pd.date_range("yyyy-mm-dd hh", "yyyy-mm-dd hh", freq="6h")
|
|
49
|
+
Track(track_times, 300)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
<details>
|
|
53
|
+
|
|
54
|
+
<summary> Important arguments and defaults </summary>
|
|
55
|
+
|
|
56
|
+
- For `Detect()`
|
|
57
|
+
|
|
58
|
+
| args| values | description |
|
|
59
|
+
| ---- | ----------- | ----- |
|
|
60
|
+
| odir | "./d01" | parent output directory name |
|
|
61
|
+
| r | np.arange(200,2101,100) | searching radius variable r [km]|
|
|
62
|
+
| SR_thres | 3.0 | SR threshold to remove tiny trough |
|
|
63
|
+
| So_thres | 3.0 | So threshold to remove weak vortices [m/100km]|
|
|
64
|
+
|
|
65
|
+
- For `Track()`
|
|
66
|
+
|
|
67
|
+
| args| values | description |
|
|
68
|
+
| ---- | ----------- | ----- |
|
|
69
|
+
| odir | "./d01" | parent output directory name |
|
|
70
|
+
| tlimit | 150.0 | Traveling speed limit to prevent wrong connections by large depressions [km/h]. Default 150 km/h is 900 km in 6 hour. |
|
|
71
|
+
| long_term | False | If False, tracking ID will be continuously counted up during the analysis period, and massive memory usage may occur. If True, tracking ID will be labeled from 1 in every 00UTC 1st Jan. |
|
|
72
|
+
| DU_thres | 0 | Threshold for noise removal with respect to duration (life time) [hour]. Note this parameter is sensitive to short-time noise, thus to remove noises try 24 or 36. |
|
|
73
|
+
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
## Command use for non-python users
|
|
77
|
+
But, python3 and requirements must be installed.
|
|
78
|
+
|
|
79
|
+
If you add `-h` for the respective commands, their documets will be appear.
|
|
80
|
+
|
|
81
|
+
- 1. Generate data_settings.py
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
$ gen_data_settings
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- 2. Edit [data_settings.py](data_settings.py)
|
|
88
|
+
|
|
89
|
+
- 3. Run detection
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
$ detect z.nc
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- 4. Run tracking
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
$ track
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- Draw maps to check tracking data and AS (netcdf output only)
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
$ draw_map z.nc ./d01 L 300 nps
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- Find and make each tracking data
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
$ find_track ./d01 L 300 a
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
# How to use outputs
|
|
114
|
+
## Directory structure of outputs
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
current_dir/
|
|
118
|
+
|
|
|
119
|
+
└── d01/ # default name
|
|
120
|
+
|
|
|
121
|
+
├── AS/ # 2D averaged slope function
|
|
122
|
+
| └── AS-{ty}-{yyyymmddhhTT}-{llll}.nc (or .grd)
|
|
123
|
+
|
|
|
124
|
+
├── V/ # point values after detection
|
|
125
|
+
| └── V-{ty}-{yyyymmddhhTT}-{llll}.csv
|
|
126
|
+
|
|
|
127
|
+
├── Vt/ # intermediate data
|
|
128
|
+
| └── V-{ty}-{yyyymmddhhTT}-{llll}.csv
|
|
129
|
+
|
|
|
130
|
+
├── Vtc/ # final point values after tracking
|
|
131
|
+
| └── V-{ty}-{yyyymmddhhTT}-{llll}.csv
|
|
132
|
+
|
|
|
133
|
+
└── ID/ # continuous csv for a specific track whose id is `ID`
|
|
134
|
+
└── {ty}-{l}-{yyyymm}-{ID}.csv
|
|
135
|
+
```
|
|
136
|
+
where, `ty` is `L` or `H`, `yyyymmddhhTT` is timestep, `llll` is level in 4 digits, and `l` is level.
|
|
137
|
+
|
|
138
|
+
## How to load outputs in programs
|
|
139
|
+
|
|
140
|
+
- python3
|
|
141
|
+
|
|
142
|
+
point data (`V` and `Vtc`, csv)
|
|
143
|
+
```python
|
|
144
|
+
import pandas as pd
|
|
145
|
+
df = pd.read_csv(path_to_V, parse_dates=["time"])
|
|
146
|
+
```
|
|
147
|
+
mesh data (`AS`, netcdf)
|
|
148
|
+
```python
|
|
149
|
+
import xarray
|
|
150
|
+
da = xr.open_dataarray(path_to_AS)
|
|
151
|
+
```
|
|
152
|
+
- julia
|
|
153
|
+
|
|
154
|
+
point data (`V` and `Vtc`, csv)
|
|
155
|
+
```julia
|
|
156
|
+
using CSV, DataFrames, Dates
|
|
157
|
+
df = CSV.read(path_to_V, DataFrame)
|
|
158
|
+
df.time = DateTime.(df.time, "yyyy-mm-dd HH:MM:SS")
|
|
159
|
+
```
|
|
160
|
+
mesh data (`AS`, netcdf)
|
|
161
|
+
```julia
|
|
162
|
+
using Datasets
|
|
163
|
+
ds = Dataset(path_to_AS)
|
|
164
|
+
ar = ds["AS"][:,:]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Variable parameters for point value csv (`Vct`)
|
|
168
|
+
|
|
169
|
+
<details>
|
|
170
|
+
<summary> Click here </summary>
|
|
171
|
+
|
|
172
|
+
| Names| Description |
|
|
173
|
+
| ---- | ----------- |
|
|
174
|
+
| time | Time. |
|
|
175
|
+
| ty | 0 for lows and troughs, 1 for highs and ridges |
|
|
176
|
+
| lev | Level. Usually in hPa. |
|
|
177
|
+
| lat, lon | Central coorditates in latitude and longitude. |
|
|
178
|
+
| valV | Value of input field on the center |
|
|
179
|
+
| valX | Value of the nearest local minimum (maximum) of input field for a low (high). |
|
|
180
|
+
| lonX,latX | Latitude and longitude of the nearest local extremum. If the deteciton depressino is trough or ridge, this value will be 999.9 |
|
|
181
|
+
| So | Optimal slope [m/100 km]. Intensity of depresion (as circular geostrophic winds). |
|
|
182
|
+
| ro | Optimal radius [r km]. Size of depression (as a radius of the circulation). |
|
|
183
|
+
| Do | Optimal depth [m]. Vertical depth of depression, generally proportional to ro. |
|
|
184
|
+
| SBG | Background slope [m/100 km]. |
|
|
185
|
+
| SBGang | Angle of Background slope vector [radian]. 0 for east. |
|
|
186
|
+
| m, n | Zonal, meridional components of SBG, respectivelly [m/100 km]. |
|
|
187
|
+
| SR | Slope ratio. For analytic characters of a Gaussian-shaped depression, 0.-1.34 for vortices, 1.34- for waves, and larger values (e.g., 3.) for ripples in a jet. |
|
|
188
|
+
| ex | Distinction between depressions and waves. <br>1 (there is a extremum within ro\*0.65) for lows/highs and 0 (otherwise) for troughs/ridges. |
|
|
189
|
+
| EE | Eccentricity (1 for pure isotropic, smaller values for Ellipses). |
|
|
190
|
+
| XX | Zonal discrete laplacian with a step of ro [m/(100 km)**2]. Small value means the feature has weak structure in zonal like sub-tropical ridges. |
|
|
191
|
+
| ID | Identification number. Tend to be larger than number of detection since it includes noises |
|
|
192
|
+
| MERGE | Merge lysis flag. <br>`-1` for soritary lysis, <br>`-2` for being merged from someone, <br>`-3` for lysis at the end of analysis, <br>`-4` for being involved in the secondary proces (see Fig. S2 in KH25), <br>other integers for the object ID of its merge lysis. |
|
|
193
|
+
| SPLIT | Split genesis flag. <br>`-1` for soritary genesis, <br>`-2` for being splitting and producing someone, <br>`-3` for genesis at the start of analysis, <br>`-4` for being involved in the secondary proces (see Fig. S2 in KH25), <br>other integers for the object ID of its split genesis. |
|
|
194
|
+
| DIST | Moving distance in a timestep [km]. Central difference. When merge/split/genesis/lysis, value will be missing, and the same applies to SPEED and DIR. |
|
|
195
|
+
| SPEED | Moving speed [m/s]. DIST/timestep. |
|
|
196
|
+
| DIR | Moving direction [radian]. 0 for east. |
|
|
197
|
+
| \_ DC | Accumulated duration [timestep] including before split. |
|
|
198
|
+
| DU | Duration [hour]. |
|
|
199
|
+
| XS | Sequential duration being ex=1 (lows/highs). |
|
|
200
|
+
| QS5 | 1 for Quasi-stational with 85% temporal overlapping of ro circles. |
|
|
201
|
+
| QS7 | As with QS5 but with 70%. |
|
|
202
|
+
| ALLDIST | Accumulated moving distance [km]. |
|
|
203
|
+
| MEDDIST | Median moving distance of all timesteps [km]. |
|
|
204
|
+
| MAX | 1 for the maximum development timestep (maximum So). |
|
|
205
|
+
| MAXSo | So when MAX. |
|
|
206
|
+
| MAXXS | Maximum duration of XS in a track (XS can be scored in multiple sequences). |
|
|
207
|
+
| MAXQS5 | Maximum duration of QS5 in a track. |
|
|
208
|
+
| MAXQS7 | Maximum duration of QS7 in a track. |
|
|
209
|
+
| exGEN | Genesis as vortex (`ex` changed from `0` to `1` for t-1 to t). |
|
|
210
|
+
| exLYS | Lysis as vortex (`ex` changed from `1` to `0` for t to t+1). |
|
|
211
|
+
|
|
212
|
+
</details>
|
|
213
|
+
|
|
214
|
+
## How to get csv for a specific track
|
|
215
|
+
|
|
216
|
+
Please obtain the ID for a specific depressin and its appeared year and month in advance.
|
|
217
|
+
|
|
218
|
+
Use `find_one` function by importing Finder.
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from colindex2 import Finder
|
|
222
|
+
|
|
223
|
+
# set output dir (default:"`./d01`") and timestep of output csv in `Vtc`
|
|
224
|
+
F = Finder(odir="./d01", timestep=6)
|
|
225
|
+
|
|
226
|
+
# set type (`"L"` or `"H"` for low or high detection, respectively), level (e.g., 300 hPa here), and year/month with 6 digits (e.g., 201504) when the feature appeared, and ID for the specific feature (e.g., 333)
|
|
227
|
+
# here, the result will be produced at "`./d01/ID/L-300-201504-333.csv`"
|
|
228
|
+
F.find_one("L", 300, 201504, 333)
|
|
229
|
+
|
|
230
|
+
# try below to concatenate the specific track with before splitting from and after merging to other features
|
|
231
|
+
F.find_one("L", 300, 201504, 333, before_split=True, after_merge=True)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
You can use following functions (experimental, welcome bug reports!)
|
|
235
|
+
|
|
236
|
+
- `count_all(ty, lev)`: Print out count of all tracks on the specific level in the output directory.
|
|
237
|
+
|
|
238
|
+
- `find_all(ty, lev, all_in_one=False)`: Search all tracks on the specific level in a whole time range and save them as csvs. Recommended for case studies.
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
# For more details
|
|
242
|
+
see [documents](https://kasugab3621.gitlab.io/colindex2/index.html).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .colindex2 import Detect
|
|
2
|
+
from .commands import detect, track, gen_data_settings, find_track
|
|
3
|
+
from .tracking_overlap2 import Track
|
|
4
|
+
from .get_IDfile import Finder
|
|
5
|
+
from .draw_map import _draw_map
|
|
6
|
+
|
|
7
|
+
from .modules import great_circle_distance_numba
|
|
8
|
+
from .modules import great_circle_distance # for arrays
|
|
9
|
+
from .modules import invert_gcd2
|
|
10
|
+
from .modules import moving_direction
|
|
11
|
+
from .modules import bilinear_interp
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import numpy as np
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def area_heron(a, b, c):
|
|
7
|
+
s = (a+b+c)/2
|
|
8
|
+
if min(s-a, s-b, s-c) <= 0:
|
|
9
|
+
return np.nan
|
|
10
|
+
else:
|
|
11
|
+
return np.sqrt(s*(s-a)*(s-b)*(s-c))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class circle:
|
|
15
|
+
def __init__(self, r, x):
|
|
16
|
+
self.r = r
|
|
17
|
+
self.x = x
|
|
18
|
+
self.S = np.pi * r * r
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class circle_overlap:
|
|
22
|
+
def __init__(self, c1, c2):
|
|
23
|
+
|
|
24
|
+
fct = 1
|
|
25
|
+
d = np.abs(c1.x - c2.x)
|
|
26
|
+
S = area_heron(c1.r, c2.r, d)
|
|
27
|
+
|
|
28
|
+
if np.isnan(S): # cannot make inner triangle
|
|
29
|
+
|
|
30
|
+
alpha1 = np.nan
|
|
31
|
+
d1 = np.nan
|
|
32
|
+
h = np.nan
|
|
33
|
+
|
|
34
|
+
if d < c1.r:
|
|
35
|
+
overlap = 1.
|
|
36
|
+
else:
|
|
37
|
+
overlap = 0.
|
|
38
|
+
|
|
39
|
+
else: # can make inner triangle
|
|
40
|
+
|
|
41
|
+
alpha1 = np.arcsin(2 * S / c1.r / d)
|
|
42
|
+
h = S / d * 2
|
|
43
|
+
d1 = c1.r * np.cos(alpha1)
|
|
44
|
+
|
|
45
|
+
fan = c1.r**2 * alpha1 / 2
|
|
46
|
+
tri = d1 * h / 2
|
|
47
|
+
|
|
48
|
+
if c2.r > np.sqrt(c1.r**2+d**2):
|
|
49
|
+
fct = -1
|
|
50
|
+
left = fan - tri
|
|
51
|
+
right = c1.S / 2 - left
|
|
52
|
+
else:
|
|
53
|
+
right = fan - tri
|
|
54
|
+
|
|
55
|
+
overlap = min(right / c1.S * 2, 1)
|
|
56
|
+
|
|
57
|
+
self.d = d
|
|
58
|
+
self.S = S
|
|
59
|
+
self.overlap = overlap
|
|
60
|
+
self.alpha1 = alpha1
|
|
61
|
+
self.d1 = d1*fct
|
|
62
|
+
self.h = h
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test():
|
|
66
|
+
|
|
67
|
+
import matplotlib.pyplot as plt
|
|
68
|
+
import matplotlib.patches as patches
|
|
69
|
+
|
|
70
|
+
r1, r2 = 500, 600
|
|
71
|
+
|
|
72
|
+
ds = np.arange(100, 1151, 50)
|
|
73
|
+
overs = []
|
|
74
|
+
alpha1s = []
|
|
75
|
+
d1s = []
|
|
76
|
+
hs = []
|
|
77
|
+
|
|
78
|
+
for d in ds:
|
|
79
|
+
|
|
80
|
+
c1 = circle(r=r1, x=0)
|
|
81
|
+
c2 = circle(r=r2, x=d)
|
|
82
|
+
o = cirlce_overlap(c1, c2)
|
|
83
|
+
overs.append(o.overlap)
|
|
84
|
+
alpha1s.append(o.alpha1)
|
|
85
|
+
d1s.append(o.d1)
|
|
86
|
+
hs.append(o.h)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
for i, d in enumerate(ds):
|
|
90
|
+
|
|
91
|
+
print(f'{d=}')
|
|
92
|
+
|
|
93
|
+
ax = plt.axes()
|
|
94
|
+
C1 = patches.Circle(xy=(0, 500), radius=r1, fc='none', ec='tab:blue')
|
|
95
|
+
C2 = patches.Circle(xy=(d, 500), radius=r2, fc='none', ec='tab:blue')
|
|
96
|
+
ax.add_patch(C1)
|
|
97
|
+
ax.add_patch(C2)
|
|
98
|
+
ax.plot(0, 500, marker='.', c='tab:blue')
|
|
99
|
+
ax.plot(d, 500, marker='.', c='tab:blue')
|
|
100
|
+
ax.plot([d1s[i], d1s[i]], [500-hs[i], 500+hs[i]], c='r')
|
|
101
|
+
ax.set_aspect('equal')
|
|
102
|
+
ax.set_xlim([-700,1250])
|
|
103
|
+
ax.set_ylim([-200, 1200])
|
|
104
|
+
ax.set_title(f'O={overs[i]:.3f}')
|
|
105
|
+
plt.savefig(f'fig/cc_d{d}.png')
|
|
106
|
+
plt.close()
|
|
107
|
+
|
|
108
|
+
ax = plt.axes()
|
|
109
|
+
ax.plot(ds, overs)
|
|
110
|
+
ax.plot(ds[i], overs[i], '.r')
|
|
111
|
+
plt.savefig(f'fig/overs_{d}.png')
|
|
112
|
+
plt.close()
|
|
113
|
+
|
|
114
|
+
'''ax = plt.axes()
|
|
115
|
+
ax.plot(ds, np.array(alpha1s)/np.pi)
|
|
116
|
+
ax.plot(ds[i], alpha1s[i]/np.pi, '.r')
|
|
117
|
+
plt.savefig(f'fig/alpha1s_d{d}.png')
|
|
118
|
+
plt.close()'''
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == '__main__':
|
|
122
|
+
test()
|