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.
Files changed (38) hide show
  1. pymetranet-0.3.0/LICENSE +28 -0
  2. pymetranet-0.3.0/MANIFEST.in +2 -0
  3. pymetranet-0.3.0/PKG-INFO +22 -0
  4. pymetranet-0.3.0/README.md +2 -0
  5. pymetranet-0.3.0/examples/cmdlineparse.py +379 -0
  6. pymetranet-0.3.0/examples/compuncomp.py +73 -0
  7. pymetranet-0.3.0/examples/geodata.py +60 -0
  8. pymetranet-0.3.0/examples/import_pymetranet.py +44 -0
  9. pymetranet-0.3.0/examples/linkproduct.py +41 -0
  10. pymetranet-0.3.0/examples/msxdump.py +233 -0
  11. pymetranet-0.3.0/examples/polardata.py +133 -0
  12. pymetranet-0.3.0/examples/readproduct.py +69 -0
  13. pymetranet-0.3.0/examples/sweepinfo.py +50 -0
  14. pymetranet-0.3.0/examples/writeproduct.py +263 -0
  15. pymetranet-0.3.0/pymetranet/__init__.py +14 -0
  16. pymetranet-0.3.0/pymetranet/cmd_line_params.py +1079 -0
  17. pymetranet-0.3.0/pymetranet/geo_reference.py +232 -0
  18. pymetranet-0.3.0/pymetranet/libpymetranet.so +0 -0
  19. pymetranet-0.3.0/pymetranet/linker.py +119 -0
  20. pymetranet-0.3.0/pymetranet/lzw_c.py +84 -0
  21. pymetranet-0.3.0/pymetranet/msx_serializer.py +205 -0
  22. pymetranet-0.3.0/pymetranet/msx_serializer_v1.py +129 -0
  23. pymetranet-0.3.0/pymetranet/msx_serializer_v2.py +155 -0
  24. pymetranet-0.3.0/pymetranet/polar_data.py +479 -0
  25. pymetranet-0.3.0/pymetranet/product_data.py +396 -0
  26. pymetranet-0.3.0/pymetranet/product_file.py +537 -0
  27. pymetranet-0.3.0/pymetranet/version.py +4 -0
  28. pymetranet-0.3.0/pymetranet/volumesweep.py +919 -0
  29. pymetranet-0.3.0/pymetranet/volumesweep_serializer.py +110 -0
  30. pymetranet-0.3.0/pymetranet/xml_util.py +100 -0
  31. pymetranet-0.3.0/pymetranet.egg-info/PKG-INFO +22 -0
  32. pymetranet-0.3.0/pymetranet.egg-info/SOURCES.txt +37 -0
  33. pymetranet-0.3.0/pymetranet.egg-info/dependency_links.txt +1 -0
  34. pymetranet-0.3.0/pymetranet.egg-info/not-zip-safe +1 -0
  35. pymetranet-0.3.0/pymetranet.egg-info/requires.txt +1 -0
  36. pymetranet-0.3.0/pymetranet.egg-info/top_level.txt +1 -0
  37. pymetranet-0.3.0/setup.cfg +16 -0
  38. pymetranet-0.3.0/setup.py +61 -0
@@ -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,2 @@
1
+ include README.md
2
+ include LICENSE
@@ -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,2 @@
1
+ # pymetranet
2
+ 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()