pymetranet 0.3.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.
- pymetranet-0.3.0/LICENSE +28 -0
- pymetranet-0.3.0/MANIFEST.in +2 -0
- pymetranet-0.3.0/PKG-INFO +22 -0
- pymetranet-0.3.0/README.md +2 -0
- pymetranet-0.3.0/examples/cmdlineparse.py +379 -0
- pymetranet-0.3.0/examples/compuncomp.py +73 -0
- pymetranet-0.3.0/examples/geodata.py +60 -0
- pymetranet-0.3.0/examples/import_pymetranet.py +44 -0
- pymetranet-0.3.0/examples/linkproduct.py +41 -0
- pymetranet-0.3.0/examples/msxdump.py +233 -0
- pymetranet-0.3.0/examples/polardata.py +133 -0
- pymetranet-0.3.0/examples/readproduct.py +69 -0
- pymetranet-0.3.0/examples/sweepinfo.py +50 -0
- pymetranet-0.3.0/examples/writeproduct.py +263 -0
- pymetranet-0.3.0/pymetranet/__init__.py +14 -0
- pymetranet-0.3.0/pymetranet/cmd_line_params.py +1079 -0
- pymetranet-0.3.0/pymetranet/geo_reference.py +232 -0
- pymetranet-0.3.0/pymetranet/libpymetranet.so +0 -0
- pymetranet-0.3.0/pymetranet/linker.py +119 -0
- pymetranet-0.3.0/pymetranet/lzw_c.py +84 -0
- pymetranet-0.3.0/pymetranet/msx_serializer.py +205 -0
- pymetranet-0.3.0/pymetranet/msx_serializer_v1.py +129 -0
- pymetranet-0.3.0/pymetranet/msx_serializer_v2.py +155 -0
- pymetranet-0.3.0/pymetranet/polar_data.py +479 -0
- pymetranet-0.3.0/pymetranet/product_data.py +396 -0
- pymetranet-0.3.0/pymetranet/product_file.py +537 -0
- pymetranet-0.3.0/pymetranet/version.py +4 -0
- pymetranet-0.3.0/pymetranet/volumesweep.py +919 -0
- pymetranet-0.3.0/pymetranet/volumesweep_serializer.py +110 -0
- pymetranet-0.3.0/pymetranet/xml_util.py +100 -0
- pymetranet-0.3.0/pymetranet.egg-info/PKG-INFO +22 -0
- pymetranet-0.3.0/pymetranet.egg-info/SOURCES.txt +37 -0
- pymetranet-0.3.0/pymetranet.egg-info/dependency_links.txt +1 -0
- pymetranet-0.3.0/pymetranet.egg-info/not-zip-safe +1 -0
- pymetranet-0.3.0/pymetranet.egg-info/requires.txt +1 -0
- pymetranet-0.3.0/pymetranet.egg-info/top_level.txt +1 -0
- pymetranet-0.3.0/setup.cfg +16 -0
- pymetranet-0.3.0/setup.py +61 -0
pymetranet-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Eldes Radar
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pymetranet
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Python Metranet library
|
|
5
|
+
Home-page: https://github.com/eldesradar/pymetranet
|
|
6
|
+
Author: Eldes
|
|
7
|
+
Author-email: info@eldes.t
|
|
8
|
+
License: BSD-3-Clause license
|
|
9
|
+
Keywords: pymetranet
|
|
10
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
11
|
+
Classifier: Natural Language :: English
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Requires-Python: >=3.6
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: numpy
|
|
20
|
+
|
|
21
|
+
# pymetranet
|
|
22
|
+
Python Metranet Library
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
#!/bin/env python3
|
|
2
|
+
|
|
3
|
+
#import from system
|
|
4
|
+
import sys
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
#safe pymetranet import
|
|
8
|
+
import import_pymetranet
|
|
9
|
+
import pymetranet as met
|
|
10
|
+
|
|
11
|
+
class CappiParams(met.ProdParamsBase):
|
|
12
|
+
PARAM_FILES = "files"
|
|
13
|
+
PARAM_PID = "pid"
|
|
14
|
+
PARAM_MOMENT = "moment"
|
|
15
|
+
PARAM_TIME = "time"
|
|
16
|
+
PARAM_CURSWEEP = "currentsweep"
|
|
17
|
+
PARAM_VOLSWEEPS = "volumesweeps"
|
|
18
|
+
PARAM_IN_TYPE = "in_type"
|
|
19
|
+
PARAM_HEIGHT = "height"
|
|
20
|
+
PARAM_PSEUDO = "pseudo"
|
|
21
|
+
PARAM_KDPMAX = "kdp_max"
|
|
22
|
+
PARAM_BBCORR = "beam_blockage_corr"
|
|
23
|
+
PARAM_DEACORR = "dealiasing_corr"
|
|
24
|
+
PARAM_FORMAT = "format"
|
|
25
|
+
PARAM_DATABITS = "databits"
|
|
26
|
+
PARAM_SIZE = "size"
|
|
27
|
+
PARAM_COMPRESS = "compress"
|
|
28
|
+
PARAM_ZVPR = "z_vpr"
|
|
29
|
+
PARAM_INDIR = "indir"
|
|
30
|
+
PARAM_OUTDIR = "outdir"
|
|
31
|
+
PARAM_VERBOSE = "verbose"
|
|
32
|
+
PARAM_LINKIT = "linkit"
|
|
33
|
+
PARAM_ENCODING = "encoding"
|
|
34
|
+
PARAM_LINK_NODE_FILE = "link_node_file"
|
|
35
|
+
PARAM_DATA_LEVEL_FILE = "data_level_file"
|
|
36
|
+
PARAM_BLOCK_CORR_FILE = "blockage_corr_file"
|
|
37
|
+
PARAM_SPECKLE = "speckle"
|
|
38
|
+
PARAM_FLT_COEFF = "filter_coefficients"
|
|
39
|
+
PARAM_FLT_LOOPS = "filter_loops"
|
|
40
|
+
PARAM_FLT_THR = "filter_threshold"
|
|
41
|
+
PARAM_FLT_FACTOR = "filter_factor"
|
|
42
|
+
PARAM_REG_WIDTH = "regression_width"
|
|
43
|
+
PARAM_COMMENTS = "comments"
|
|
44
|
+
|
|
45
|
+
def __init__(self):
|
|
46
|
+
super().__init__()
|
|
47
|
+
|
|
48
|
+
#map the fields and info product info defaults, ranges, etc...
|
|
49
|
+
self.init_param_info()
|
|
50
|
+
self.init_product_info()
|
|
51
|
+
|
|
52
|
+
def init_param_info(self) -> None:
|
|
53
|
+
#set default to values
|
|
54
|
+
CP = CappiParams
|
|
55
|
+
PPInfo = met.ProductParamInfo
|
|
56
|
+
PPType = met.ProductParamType
|
|
57
|
+
self._map_param_info[CP.PARAM_FILES] = PPInfo("", PPType.Hidden)
|
|
58
|
+
self._map_param_info[CP.PARAM_PID] = PPInfo("", PPType.Pid)
|
|
59
|
+
self._map_param_info[CP.PARAM_MOMENT] = PPInfo("Z", PPType.Enum)
|
|
60
|
+
self._map_param_info[CP.PARAM_TIME] = PPInfo("", PPType.Hidden)
|
|
61
|
+
self._map_param_info[CP.PARAM_CURSWEEP] = PPInfo(1, PPType.Hidden)
|
|
62
|
+
self._map_param_info[CP.PARAM_VOLSWEEPS] = PPInfo(1, PPType.Hidden)
|
|
63
|
+
self._map_param_info[CP.PARAM_IN_TYPE] = PPInfo("MSE", PPType.Pid)
|
|
64
|
+
self._map_param_info[CP.PARAM_HEIGHT] = PPInfo(1, PPType.Float)
|
|
65
|
+
self._map_param_info[CP.PARAM_PSEUDO] = PPInfo(False, PPType.Bool)
|
|
66
|
+
self._map_param_info[CP.PARAM_KDPMAX] = PPInfo(28, PPType.Float)
|
|
67
|
+
self._map_param_info[CP.PARAM_BBCORR] = PPInfo(False, PPType.Bool)
|
|
68
|
+
self._map_param_info[CP.PARAM_DEACORR] = PPInfo(False, PPType.Bool)
|
|
69
|
+
self._map_param_info[CP.PARAM_FORMAT] = PPInfo("RECT", PPType.Enum)
|
|
70
|
+
self._map_param_info[CP.PARAM_DATABITS] = PPInfo("8", PPType.Enum)
|
|
71
|
+
self._map_param_info[CP.PARAM_SIZE] = PPInfo(met.MapSizeRect(400, 400, 1, 1), PPType.MapSizeRect)
|
|
72
|
+
self._map_param_info[CP.PARAM_COMPRESS] = PPInfo(True, PPType.Bool)
|
|
73
|
+
self._map_param_info[CP.PARAM_ZVPR] = PPInfo(False, PPType.Bool)
|
|
74
|
+
self._map_param_info[CP.PARAM_INDIR] = PPInfo("/opt/metraserver/data", PPType.PathDir)
|
|
75
|
+
self._map_param_info[CP.PARAM_OUTDIR] = PPInfo("/opt/metraserver/data", PPType.PathDir)
|
|
76
|
+
self._map_param_info[CP.PARAM_VERBOSE] = PPInfo(False, PPType.Bool)
|
|
77
|
+
self._map_param_info[CP.PARAM_LINKIT] = PPInfo(False, PPType.Bool)
|
|
78
|
+
self._map_param_info[CP.PARAM_ENCODING] = PPInfo("hard-coded", PPType.PathFile)
|
|
79
|
+
self._map_param_info[CP.PARAM_LINK_NODE_FILE] = PPInfo("default", PPType.PathFile)
|
|
80
|
+
self._map_param_info[CP.PARAM_DATA_LEVEL_FILE] = PPInfo("default", PPType.PathFile)
|
|
81
|
+
self._map_param_info[CP.PARAM_BLOCK_CORR_FILE] = PPInfo("default", PPType.PathFile)
|
|
82
|
+
self._map_param_info[CP.PARAM_SPECKLE] = PPInfo(0, PPType.Int)
|
|
83
|
+
self._map_param_info[CP.PARAM_FLT_COEFF] = PPInfo("default", PPType.PathFile)
|
|
84
|
+
self._map_param_info[CP.PARAM_FLT_LOOPS] = PPInfo(10, PPType.Int)
|
|
85
|
+
self._map_param_info[CP.PARAM_FLT_THR] = PPInfo(4.0, PPType.Float)
|
|
86
|
+
self._map_param_info[CP.PARAM_FLT_FACTOR] = PPInfo(1.3, PPType.Float)
|
|
87
|
+
self._map_param_info[CP.PARAM_REG_WIDTH] = PPInfo(10, PPType.Int)
|
|
88
|
+
self._map_param_info[CP.PARAM_COMMENTS] = PPInfo("", PPType.String)
|
|
89
|
+
|
|
90
|
+
def init_product_info(self) -> None:
|
|
91
|
+
prod_info = self._product_info
|
|
92
|
+
map_info = self._map_param_info
|
|
93
|
+
|
|
94
|
+
prod_info.product_name = "CAPPI"
|
|
95
|
+
prod_info.version = "Version 2.10.1.0 Apr 8 2024"
|
|
96
|
+
prod_info.description = "The program cappi generates CAPPI product"
|
|
97
|
+
|
|
98
|
+
#define some shortcuts to easily create types
|
|
99
|
+
DEF_STR = lambda value : met.ProductParamDefault[str](True, value)
|
|
100
|
+
DEF_BOOL = lambda value : met.ProductParamDefault[bool](True, value)
|
|
101
|
+
DEF_INT = lambda value : met.ProductParamDefault[int](True, value)
|
|
102
|
+
DEF_FLOAT = lambda value : met.ProductParamDefault[float](True, value)
|
|
103
|
+
RNG_INT = lambda val_min, val_max : met.ProductParamRange[int](True, val_min, val_max)
|
|
104
|
+
RNG_FLOAT = lambda val_min, val_max : met.ProductParamRange[float](True, val_min, val_max)
|
|
105
|
+
RNG_SIZE = lambda val_min, val_max : met.ProductParamRange[met.MapSizeRect](True, val_min, val_max)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
#add general group
|
|
109
|
+
group_general = met.ProductParamGroup("General")
|
|
110
|
+
prod_info.groups.append(group_general)
|
|
111
|
+
|
|
112
|
+
#add pid to group general
|
|
113
|
+
key = CappiParams.PARAM_PID
|
|
114
|
+
prod_info.params.append(met.ProductParamPid(key,
|
|
115
|
+
"3-letters as Oxy where x represents the moment, y is the radar ID", group_general,
|
|
116
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
117
|
+
|
|
118
|
+
#add moment
|
|
119
|
+
key = CappiParams.PARAM_MOMENT
|
|
120
|
+
moments = ["W", "V", "UZ", "Z", "ZDR", "RHO", "PHIDP", "KDP"]
|
|
121
|
+
prod_info.params.append(met.ProductParamEnum(key,
|
|
122
|
+
"moment type for data processing", group_general,
|
|
123
|
+
map_info[key].value, DEF_STR(map_info[key].value),
|
|
124
|
+
moments, True, True))
|
|
125
|
+
|
|
126
|
+
#add time
|
|
127
|
+
key = CappiParams.PARAM_TIME
|
|
128
|
+
prod_info.params.append(met.ProductParamHidden(key,
|
|
129
|
+
"time, priority, compression of input, i.e. 1236523550U", group_general,
|
|
130
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
131
|
+
|
|
132
|
+
#add current sweep
|
|
133
|
+
key = CappiParams.PARAM_CURSWEEP
|
|
134
|
+
prod_info.params.append(met.ProductParamHidden(key,
|
|
135
|
+
"input sweep number (volume file extension)", group_general,
|
|
136
|
+
str(map_info[key].value), DEF_STR(str(map_info[key].value))))
|
|
137
|
+
|
|
138
|
+
#add volume sweeps
|
|
139
|
+
key = CappiParams.PARAM_VOLSWEEPS
|
|
140
|
+
prod_info.params.append(met.ProductParamHidden(key,
|
|
141
|
+
"number of total sweeps (elevations) in volume", group_general,
|
|
142
|
+
str(map_info[key].value), DEF_STR(str(map_info[key].value))))
|
|
143
|
+
|
|
144
|
+
#add in type
|
|
145
|
+
key = CappiParams.PARAM_IN_TYPE
|
|
146
|
+
prod_info.params.append(met.ProductParamPid(key,
|
|
147
|
+
"input file type, combined with 'time' to form filename", group_general,
|
|
148
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
149
|
+
|
|
150
|
+
#add height
|
|
151
|
+
key = CappiParams.PARAM_HEIGHT
|
|
152
|
+
prod_info.params.append(met.ProductParamFloat(key,
|
|
153
|
+
"height for product", group_general,
|
|
154
|
+
map_info[key].value,
|
|
155
|
+
DEF_FLOAT(map_info[key].value),
|
|
156
|
+
RNG_FLOAT(0, 18)))
|
|
157
|
+
|
|
158
|
+
#add pseudo
|
|
159
|
+
key = CappiParams.PARAM_PSEUDO
|
|
160
|
+
prod_info.params.append(met.ProductParamBool(key,
|
|
161
|
+
"create pseudo CAPPI", group_general,
|
|
162
|
+
map_info[key].value, DEF_BOOL(map_info[key].value)))
|
|
163
|
+
|
|
164
|
+
#add kdpmax
|
|
165
|
+
key = CappiParams.PARAM_KDPMAX
|
|
166
|
+
prod_info.params.append(met.ProductParamFloat(key,
|
|
167
|
+
"maximum KDP value (deg/km) in output product", group_general,
|
|
168
|
+
map_info[key].value,
|
|
169
|
+
DEF_FLOAT(map_info[key].value),
|
|
170
|
+
RNG_FLOAT(3, 30)))
|
|
171
|
+
|
|
172
|
+
#add bb corr
|
|
173
|
+
key = CappiParams.PARAM_BBCORR
|
|
174
|
+
prod_info.params.append(met.ProductParamBool(key,
|
|
175
|
+
"1 means perform beam blockage correction", group_general,
|
|
176
|
+
map_info[key].value, DEF_BOOL(map_info[key].value)))
|
|
177
|
+
|
|
178
|
+
#add dealiasing correction
|
|
179
|
+
key = CappiParams.PARAM_DEACORR
|
|
180
|
+
prod_info.params.append(met.ProductParamBool(key,
|
|
181
|
+
"1 means perform dealiasing correction", group_general,
|
|
182
|
+
map_info[key].value, DEF_BOOL(map_info[key].value)))
|
|
183
|
+
|
|
184
|
+
#add format
|
|
185
|
+
key = CappiParams.PARAM_FORMAT
|
|
186
|
+
formats = ["RECT", "POLAR"]
|
|
187
|
+
prod_info.params.append(met.ProductParamEnum(key,
|
|
188
|
+
"data display format selected from RECT or POLAR", group_general,
|
|
189
|
+
map_info[key].value, DEF_STR(map_info[key].value),
|
|
190
|
+
formats))
|
|
191
|
+
|
|
192
|
+
#add databits
|
|
193
|
+
key = CappiParams.PARAM_DATABITS
|
|
194
|
+
databits = ["4", "8"]
|
|
195
|
+
prod_info.params.append(met.ProductParamEnum(key,
|
|
196
|
+
"data bits 4 or 8", group_general,
|
|
197
|
+
map_info[key].value, DEF_STR(map_info[key].value),
|
|
198
|
+
databits))
|
|
199
|
+
|
|
200
|
+
#add size
|
|
201
|
+
key = CappiParams.PARAM_SIZE
|
|
202
|
+
prod_info.params.append(met.ProductParamMapSizeRect(key,
|
|
203
|
+
"RECT x,y point and resolution (km)", group_general,
|
|
204
|
+
map_info[key].value,
|
|
205
|
+
met.ProductParamDefault[met.MapSizeRect](True, map_info[key].value),
|
|
206
|
+
RNG_SIZE(met.MapSizeRect(100, 100, 0.05, 0.05), #min
|
|
207
|
+
met.MapSizeRect(1000, 1000, 2.0, 2.0)))) #max
|
|
208
|
+
|
|
209
|
+
#add compress
|
|
210
|
+
key = CappiParams.PARAM_COMPRESS
|
|
211
|
+
prod_info.params.append(met.ProductParamBool(key,
|
|
212
|
+
"compress product", group_general,
|
|
213
|
+
map_info[key].value, DEF_BOOL(map_info[key].value)))
|
|
214
|
+
|
|
215
|
+
#add zvpr
|
|
216
|
+
key = CappiParams.PARAM_ZVPR
|
|
217
|
+
prod_info.params.append(met.ProductParamBool(key,
|
|
218
|
+
"for intensity data, use vpr profile to project data", group_general,
|
|
219
|
+
map_info[key].value, DEF_BOOL(map_info[key].value)))
|
|
220
|
+
|
|
221
|
+
#add indir
|
|
222
|
+
key = CappiParams.PARAM_INDIR
|
|
223
|
+
prod_info.params.append(met.ProductParamPathDir(key,
|
|
224
|
+
"input data directory", group_general,
|
|
225
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
226
|
+
|
|
227
|
+
#add outdir
|
|
228
|
+
key = CappiParams.PARAM_OUTDIR
|
|
229
|
+
prod_info.params.append(met.ProductParamPathDir(key,
|
|
230
|
+
"output data directory", group_general,
|
|
231
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
232
|
+
|
|
233
|
+
#add verbose
|
|
234
|
+
key = CappiParams.PARAM_VERBOSE
|
|
235
|
+
prod_info.params.append(met.ProductParamBool(key,
|
|
236
|
+
"verbose flag, 1 for more messages from program", group_general,
|
|
237
|
+
map_info[key].value, DEF_BOOL(map_info[key].value)))
|
|
238
|
+
|
|
239
|
+
#add linkit
|
|
240
|
+
key = CappiParams.PARAM_LINKIT
|
|
241
|
+
prod_info.params.append(met.ProductParamBool(key,
|
|
242
|
+
"flag 1 for creating link files for product", group_general,
|
|
243
|
+
map_info[key].value, DEF_BOOL(map_info[key].value)))
|
|
244
|
+
|
|
245
|
+
#add encoding
|
|
246
|
+
key = CappiParams.PARAM_ENCODING
|
|
247
|
+
prod_info.params.append(met.ProductParamPathFile(key,
|
|
248
|
+
"file name which specifies moments encoding", group_general,
|
|
249
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
250
|
+
|
|
251
|
+
#add link node file
|
|
252
|
+
key = CappiParams.PARAM_LINK_NODE_FILE
|
|
253
|
+
prod_info.params.append(met.ProductParamPathFile(key,
|
|
254
|
+
"file name which specifies link node directory", group_general,
|
|
255
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
256
|
+
|
|
257
|
+
#add data level file
|
|
258
|
+
key = CappiParams.PARAM_DATA_LEVEL_FILE
|
|
259
|
+
prod_info.params.append(met.ProductParamPathFile(key,
|
|
260
|
+
"file name which specifies data levels", group_general,
|
|
261
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
262
|
+
|
|
263
|
+
#add blockage correction file
|
|
264
|
+
key = CappiParams.PARAM_BLOCK_CORR_FILE
|
|
265
|
+
prod_info.params.append(met.ProductParamPathFile(key,
|
|
266
|
+
"file name for beam blockage correction, default [installdir]/etc/pgs/blockage_correction_'radarname'.dat", group_general,
|
|
267
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
268
|
+
|
|
269
|
+
#add speckle
|
|
270
|
+
key = CappiParams.PARAM_SPECKLE
|
|
271
|
+
prod_info.params.append(met.ProductParamInt(key,
|
|
272
|
+
"apply speckle fiter", group_general,
|
|
273
|
+
map_info[key].value,
|
|
274
|
+
DEF_INT(map_info[key].value),
|
|
275
|
+
RNG_INT(0, 5)))
|
|
276
|
+
|
|
277
|
+
#add filter coefficients
|
|
278
|
+
key = CappiParams.PARAM_FLT_COEFF
|
|
279
|
+
prod_info.params.append(met.ProductParamString(key,
|
|
280
|
+
"file name which specifies coefficients for PHDP FIR filter", group_general,
|
|
281
|
+
map_info[key].value,
|
|
282
|
+
DEF_STR(map_info[key].value)))
|
|
283
|
+
|
|
284
|
+
#add filter loops
|
|
285
|
+
key = CappiParams.PARAM_FLT_LOOPS
|
|
286
|
+
prod_info.params.append(met.ProductParamInt(key,
|
|
287
|
+
"number of times for filtering", group_general,
|
|
288
|
+
map_info[key].value,
|
|
289
|
+
DEF_INT(map_info[key].value),
|
|
290
|
+
RNG_INT(0, 20)))
|
|
291
|
+
|
|
292
|
+
#add filter threshold
|
|
293
|
+
key = CappiParams.PARAM_FLT_THR
|
|
294
|
+
prod_info.params.append(met.ProductParamFloat(key,
|
|
295
|
+
"threshold to determine more PHDP filtering", group_general,
|
|
296
|
+
map_info[key].value,
|
|
297
|
+
DEF_FLOAT(map_info[key].value),
|
|
298
|
+
RNG_FLOAT(0, 20)))
|
|
299
|
+
|
|
300
|
+
#add filter factor
|
|
301
|
+
key = CappiParams.PARAM_FLT_FACTOR
|
|
302
|
+
prod_info.params.append(met.ProductParamFloat(key,
|
|
303
|
+
"factor to change filter threshold", group_general,
|
|
304
|
+
map_info[key].value,
|
|
305
|
+
DEF_FLOAT(map_info[key].value),
|
|
306
|
+
RNG_FLOAT(1, 2)))
|
|
307
|
+
|
|
308
|
+
#add regression width
|
|
309
|
+
key = CappiParams.PARAM_REG_WIDTH
|
|
310
|
+
prod_info.params.append(met.ProductParamInt(key,
|
|
311
|
+
"integrating data points to generate KDP", group_general,
|
|
312
|
+
map_info[key].value,
|
|
313
|
+
DEF_INT(map_info[key].value),
|
|
314
|
+
RNG_INT(2, 20)))
|
|
315
|
+
|
|
316
|
+
#add comments
|
|
317
|
+
key = CappiParams.PARAM_COMMENTS
|
|
318
|
+
prod_info.params.append(met.ProductParamString(key,
|
|
319
|
+
"comments added by user", group_general,
|
|
320
|
+
map_info[key].value, DEF_STR(map_info[key].value)))
|
|
321
|
+
|
|
322
|
+
def gest_init_args(prog_name: str, args):
|
|
323
|
+
for arg in args:
|
|
324
|
+
if arg == "-init":
|
|
325
|
+
params = CappiParams()
|
|
326
|
+
print("%s %s" % (prog_name, params.get_params_cmd_line()))
|
|
327
|
+
return True
|
|
328
|
+
elif arg == "-xmldef":
|
|
329
|
+
params = CappiParams()
|
|
330
|
+
print("%s" % params.get_xml_def())
|
|
331
|
+
return True
|
|
332
|
+
|
|
333
|
+
return False
|
|
334
|
+
|
|
335
|
+
def main():
|
|
336
|
+
if gest_init_args("CAPPI", sys.argv):
|
|
337
|
+
return 0
|
|
338
|
+
|
|
339
|
+
parser = met.CmdLineParams()
|
|
340
|
+
ret_parse = parser.parse_cmd_line(len(sys.argv), sys.argv)
|
|
341
|
+
|
|
342
|
+
#usage of get param count method
|
|
343
|
+
#print("##### GET PARAM COUNT METHOD ###")
|
|
344
|
+
#print("param count: %d" % parser.get_params_count())
|
|
345
|
+
|
|
346
|
+
#usage of params dicitonary
|
|
347
|
+
#print("##### ITERATE PARAM DICTIONARY ###")
|
|
348
|
+
#idx = 0
|
|
349
|
+
#for param_name, param_value in parser.params.items():
|
|
350
|
+
#print("param[%d] - name: '%s' value: '%s'" % (idx, param_name, param_value))
|
|
351
|
+
#idx += 1
|
|
352
|
+
|
|
353
|
+
#usage of get param value iterating dictionary keys
|
|
354
|
+
#print("##### ITERATE PARAM KEYS AND GETTING PARAM VALUE VIA GET PARAM VALUE METHOD ###")
|
|
355
|
+
#idx = 0
|
|
356
|
+
#for key in parser.params:
|
|
357
|
+
#value = parser.get_param_value(key)
|
|
358
|
+
#print("param[%d] - key: '%s' value(via get_param_value): '%s'" % (idx, key, value))
|
|
359
|
+
#idx += 1
|
|
360
|
+
|
|
361
|
+
#validate parameters
|
|
362
|
+
params = CappiParams()
|
|
363
|
+
try:
|
|
364
|
+
params.validate(parser)
|
|
365
|
+
except Exception as ex:
|
|
366
|
+
print(ex)
|
|
367
|
+
return 1
|
|
368
|
+
|
|
369
|
+
#construct parameters for product with its default values, then
|
|
370
|
+
#inject command line inside params
|
|
371
|
+
ret = params.inject(parser)
|
|
372
|
+
print("injected %d parameters from the command line" % ret)
|
|
373
|
+
for param_name, param_value in params.map_info.items():
|
|
374
|
+
print("%s: '%s' (type: %s)" % (param_name, param_value.value, param_value.param_type))
|
|
375
|
+
|
|
376
|
+
return 0
|
|
377
|
+
|
|
378
|
+
if __name__ == '__main__':
|
|
379
|
+
main()
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/env python3
|
|
2
|
+
|
|
3
|
+
#import from system
|
|
4
|
+
import sys
|
|
5
|
+
import os
|
|
6
|
+
import math
|
|
7
|
+
import argparse
|
|
8
|
+
import time
|
|
9
|
+
import numpy as np
|
|
10
|
+
from PIL import Image, ImageDraw
|
|
11
|
+
|
|
12
|
+
#safe pymetranet import
|
|
13
|
+
import import_pymetranet
|
|
14
|
+
from pymetranet import ProductFile, lzw15_compress, lzw15_decompress
|
|
15
|
+
|
|
16
|
+
def main():
|
|
17
|
+
parser = argparse.ArgumentParser()
|
|
18
|
+
parser.add_argument('infile', nargs='*', type=str)
|
|
19
|
+
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
|
|
22
|
+
for file_name in args.infile:
|
|
23
|
+
#load product file
|
|
24
|
+
print("loading product %s..." % file_name)
|
|
25
|
+
prod = ProductFile()
|
|
26
|
+
prod.load_file(file_name)
|
|
27
|
+
print("product file %s successfully loaded!" % file_name)
|
|
28
|
+
|
|
29
|
+
#show header info
|
|
30
|
+
infos = prod.get_header_info()
|
|
31
|
+
for i in range(len(infos)):
|
|
32
|
+
print("info[%d/%d]:" % (i+1, len(infos)), infos[i])
|
|
33
|
+
|
|
34
|
+
#iterate over product data
|
|
35
|
+
buffer_from_load_file = prod.data.data
|
|
36
|
+
filter = np.where(buffer_from_load_file >= 0)
|
|
37
|
+
idx_rows = filter[0]
|
|
38
|
+
idx_cols = filter[1]
|
|
39
|
+
|
|
40
|
+
#compress data, uncompress again
|
|
41
|
+
buffer_of_bytes_from_loaded_file = buffer_from_load_file.tobytes()
|
|
42
|
+
print("len of buffer_of_bytes_from_loaded_file:", len(buffer_of_bytes_from_loaded_file))
|
|
43
|
+
compressed = lzw15_compress(buffer_of_bytes_from_loaded_file)
|
|
44
|
+
compressed_bytes = b"".join(compressed)
|
|
45
|
+
print("len of compressed_bytes:", len(compressed_bytes))
|
|
46
|
+
#newbytes = b"".join(lzw15_decompress(compressed))
|
|
47
|
+
newbytes = b"".join(lzw15_decompress(compressed_bytes))
|
|
48
|
+
print("len of newbytes:", len(newbytes))
|
|
49
|
+
oldbytes = buffer_from_load_file.tobytes()
|
|
50
|
+
print("len of oldbytes:", len(oldbytes))
|
|
51
|
+
print("oldbytes == newbytes:", oldbytes == newbytes)
|
|
52
|
+
|
|
53
|
+
#match data (they must be equal)
|
|
54
|
+
for i in range(len(idx_rows)):
|
|
55
|
+
i_idx = idx_rows[i]
|
|
56
|
+
j_idx = idx_cols[i]
|
|
57
|
+
k_idx = i_idx * buffer_from_load_file.shape[0] + j_idx
|
|
58
|
+
if buffer_from_load_file[i_idx, j_idx] != newbytes[k_idx]:
|
|
59
|
+
print("buffer_from_load_file[%d,%d] different from newbytes[%d]:" % (i_idx, j_idx, k_idx),
|
|
60
|
+
buffer_from_load_file[i_idx, j_idx], newbytes[k_idx])
|
|
61
|
+
print("oldbytes[%d]:" % k_idx, oldbytes[k_idx], "newbytes[%d]" % k_idx, newbytes[k_idx])
|
|
62
|
+
break
|
|
63
|
+
else:
|
|
64
|
+
print("buffer_from_load_file[%d,%d] equals to newbytes[%d]:" % (i_idx, j_idx, k_idx),
|
|
65
|
+
buffer_from_load_file[i_idx, j_idx],
|
|
66
|
+
"buffer_of_bytes_from_loaded_file[%d]:" % k_idx, buffer_of_bytes_from_loaded_file[k_idx],
|
|
67
|
+
"newbytes[%d]:" % k_idx, newbytes[k_idx],
|
|
68
|
+
"oldbytes[%d]:" % k_idx, oldbytes[k_idx])
|
|
69
|
+
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
if __name__ == '__main__':
|
|
73
|
+
main()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/bin/env python
|
|
2
|
+
|
|
3
|
+
#import from system
|
|
4
|
+
import sys
|
|
5
|
+
import os
|
|
6
|
+
import math
|
|
7
|
+
import argparse
|
|
8
|
+
import time
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
#safe pymetranet import
|
|
12
|
+
import import_pymetranet
|
|
13
|
+
from pymetranet import PolarSweepSerializer, PolarSweep, PolarPpiData, GeoReference, GeoRefGate
|
|
14
|
+
|
|
15
|
+
def main() -> int:
|
|
16
|
+
parser = argparse.ArgumentParser()
|
|
17
|
+
parser.add_argument("--mom", type=str, default="Z")
|
|
18
|
+
parser.add_argument('infile', nargs='*', type=str)
|
|
19
|
+
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
|
|
22
|
+
for file_name in args.infile:
|
|
23
|
+
print("loading file %s..." % file_name)
|
|
24
|
+
loaded_sweep = PolarSweepSerializer.load(file_name)
|
|
25
|
+
print("file %s successfully loaded" % file_name)
|
|
26
|
+
|
|
27
|
+
#transform 'mom'
|
|
28
|
+
polar = PolarPpiData()
|
|
29
|
+
polar.transform(loaded_sweep, mom_name=args.mom)
|
|
30
|
+
print("moment '%s' transformed into polar from loaded sweep" % args.mom)
|
|
31
|
+
|
|
32
|
+
#get or calculate informazion needed for geo calculation
|
|
33
|
+
gate_width = loaded_sweep.sweepheader.gatewidth
|
|
34
|
+
idx_mid: int = int(len(loaded_sweep.rays) / 2)
|
|
35
|
+
ele_deg_start: float = loaded_sweep.rays[idx_mid].get_startel_deg()
|
|
36
|
+
ele_deg_end: float = loaded_sweep.rays[idx_mid].get_endel_deg()
|
|
37
|
+
|
|
38
|
+
print("ele_deg_start '%g' ele_deg_end: '%g'" % (ele_deg_start, ele_deg_end))
|
|
39
|
+
if ele_deg_start > 180.0:
|
|
40
|
+
ele_deg_start = ele_deg_start - 360.0
|
|
41
|
+
print("corrected ele_deg_start to '%g'" % ele_deg_start)
|
|
42
|
+
rad_height: float = loaded_sweep.sweepheader.radarheight * 0.001
|
|
43
|
+
print("gate_width: '%g'" % gate_width)
|
|
44
|
+
print("rad_height: '%g'" % rad_height)
|
|
45
|
+
|
|
46
|
+
#build 'geo' i.e. gate height and horizon distance
|
|
47
|
+
#for each gate
|
|
48
|
+
geo_ref: GeoReference = GeoReference()
|
|
49
|
+
geo_ref.build(polar.get_ray(0), ele_deg_start, gate_width, rad_height)
|
|
50
|
+
|
|
51
|
+
#print geo information
|
|
52
|
+
for i in range(len(geo_ref.data)):
|
|
53
|
+
geo_info = geo_ref.data[i]
|
|
54
|
+
print("geo info[%03d] gate index: '%g' mid height: '%g' horizon distance: '%g'" \
|
|
55
|
+
% (i, geo_info.gate_index, geo_info.gate_mid_height, geo_info.horizon_distance))
|
|
56
|
+
|
|
57
|
+
return 0
|
|
58
|
+
|
|
59
|
+
if __name__ == '__main__':
|
|
60
|
+
sys.exit(main())
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/bin/env python3
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
#safe pymetranet import
|
|
7
|
+
try:
|
|
8
|
+
import pymetranet
|
|
9
|
+
except ModuleNotFoundError as ex:
|
|
10
|
+
#exe_dir = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
|
|
11
|
+
exe_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
|
|
12
|
+
if os.path.isfile(exe_dir):
|
|
13
|
+
#detected exe_dir as file instead of dir, use parent dir, this occurs when
|
|
14
|
+
#running a python program from a self-executable zip file generated with zipapps
|
|
15
|
+
exe_dir = os.path.dirname(exe_dir)
|
|
16
|
+
paths = [os.path.abspath(os.path.join(exe_dir, "pymetranet")),
|
|
17
|
+
os.path.abspath(os.path.join(exe_dir, "..", "pymetranet")),
|
|
18
|
+
os.path.abspath(os.path.join(exe_dir, "..", "lib", "pymetranet")),
|
|
19
|
+
os.path.abspath(os.path.join(exe_dir, "..", "..", "..", "share", "src", "pymetranet", "pymetranet")),
|
|
20
|
+
os.path.abspath(os.path.join(exe_dir, "..", "..", "..", "..", "share", "src", "pymetranet", "pymetranet")),
|
|
21
|
+
os.path.abspath(os.path.join(exe_dir, "..", "..", "..", "..", "..", "share", "src", "pymetranet", "pymetranet"))]
|
|
22
|
+
found = False
|
|
23
|
+
|
|
24
|
+
#search library in zip format
|
|
25
|
+
for path in paths:
|
|
26
|
+
zip_file = path + ".pyz"
|
|
27
|
+
#searching for 'zip_file' file
|
|
28
|
+
if os.path.isfile(zip_file):
|
|
29
|
+
found = True
|
|
30
|
+
#found pymetranet as zip file 'zip_file', add it to sys path
|
|
31
|
+
sys.path.append(zip_file)
|
|
32
|
+
break
|
|
33
|
+
|
|
34
|
+
if not found:
|
|
35
|
+
#search library as folder
|
|
36
|
+
for path in paths:
|
|
37
|
+
#searching for dir 'path'
|
|
38
|
+
if os.path.isdir(path):
|
|
39
|
+
found = True
|
|
40
|
+
#found pymetranet as dir in 'path', add dir parent to sys path
|
|
41
|
+
sys.path.append(os.path.dirname(path))
|
|
42
|
+
break
|
|
43
|
+
if not found:
|
|
44
|
+
raise ModuleNotFoundError("can't find pymetranet package not in the system nor in known local relative paths")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/env python3
|
|
2
|
+
|
|
3
|
+
#import from system
|
|
4
|
+
import sys
|
|
5
|
+
import os
|
|
6
|
+
import math
|
|
7
|
+
import argparse
|
|
8
|
+
import time
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
#safe pymetranet import
|
|
12
|
+
import import_pymetranet
|
|
13
|
+
from pymetranet import ProductFile, Linker
|
|
14
|
+
|
|
15
|
+
def main():
|
|
16
|
+
parser = argparse.ArgumentParser()
|
|
17
|
+
parser.add_argument("--link", type=str, default="default")
|
|
18
|
+
parser.add_argument('infile', nargs='*', type=str)
|
|
19
|
+
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
|
|
22
|
+
for file_name in args.infile:
|
|
23
|
+
#load product file
|
|
24
|
+
print("loading product %s..." % file_name)
|
|
25
|
+
prod = ProductFile()
|
|
26
|
+
prod.load_file(file_name)
|
|
27
|
+
print("product file %s successfully loaded!" % file_name)
|
|
28
|
+
|
|
29
|
+
#show header info
|
|
30
|
+
infos = prod.get_header_info()
|
|
31
|
+
for i in range(len(infos)):
|
|
32
|
+
print("info[%d/%d]:" % (i+1, len(infos)), infos[i])
|
|
33
|
+
|
|
34
|
+
#generate links for the file read
|
|
35
|
+
print("generating hard links for for '%s' link file: '%s'" % (file_name, args.link))
|
|
36
|
+
Linker.create_links(file_name, args.link)
|
|
37
|
+
|
|
38
|
+
return 0
|
|
39
|
+
|
|
40
|
+
if __name__ == '__main__':
|
|
41
|
+
main()
|