Skip to content

Commit 92f4d4e

Browse files
Merge pull request #103 from IPGP/prerelease
Prerelease > master
2 parents 94bba3d + 60a71a3 commit 92f4d4e

12 files changed

+2211
-1264
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
__pycache__
2+
venv/
3+
.idea/
4+

README.md

+198-122
Large diffs are not rendered by default.

rinexmod.py

+96-85
Original file line numberDiff line numberDiff line change
@@ -9,75 +9,86 @@
99
(https://github.com/IPGP/rinexmod/blob/master/README.md)
1010
1111
# Credits:
12-
2021-02-07 Félix Léger - [email protected]
13-
2023-03-23 Pierre Sakic - [email protected]
12+
v1 - 2021-02-07 Félix Léger - [email protected]
13+
v2 - 2023-03-23 Pierre Sakic - [email protected]
1414
"""
1515

16-
import rinexmod.rinexmod_api as rma
16+
import rinexmod
17+
import rinexmod.rinexmod_api as rimo_api
18+
import argparse, textwrap
1719

1820
if __name__ == '__main__':
19-
20-
import argparse
21-
##### Class for --modif_kw
22-
class ParseKwargs(argparse.Action):
23-
def __call__(self, parser, namespace, values, option_string=None):
24-
setattr(namespace, self.dest, dict())
25-
for value in values:
26-
try:
27-
key, value = value.split('=')
28-
getattr(namespace, self.dest)[key] = value
29-
except Exception as e:
30-
__print_tips(values)
31-
raise e
21+
22+
class SmartFormatter(argparse.HelpFormatter):
23+
# source: https://stackoverflow.com/a/22157136/3464212
24+
def _split_lines(self, text, width):
25+
if text.startswith('R|'):
26+
return text[2:].splitlines()
27+
# this is the RawTextHelpFormatter._split_lines
28+
return argparse.HelpFormatter._split_lines(self, text, width)
3229

3330
##### Parsing Args
34-
parser = argparse.ArgumentParser(description='This program takes RINEX files (v2 or v3, compressed or not), rename them and modifiy their headers, and write them back to a destination directory')
35-
parser.add_argument('rinexinput', type=str,
36-
help='Input list file of the RINEX paths to process (generated with a find or ls command for instance) OR a single RINEX file\'s path (see -a/--alone for a single input file)')
37-
parser.add_argument('outputfolder', type=str,
38-
help='Output folder for modified RINEX files')
39-
parser.add_argument(
40-
'-s', '--sitelog', help='Get the RINEX header values from file\'s site\'s sitelog. Provide a single sitelog path or a folder contaning sitelogs.', type=str, default="")
41-
parser.add_argument('-k', '--modif_kw', help='''Modification keywords for RINEX's header fields and/or filename. Will override the information from the sitelog.
42-
Format : -k keyword_1=\'value\' keyword2=\'value\'. Acceptable keywords:\n
43-
comment, marker_name, marker_number, station (legacy alias for marker_name), receiver_serial, receiver_type, receiver_fw, antenna_serial, antenna_type,
44-
antenna_X_pos, antenna_Y_pos, antenna_Z_pos, antenna_H_delta, antenna_E_delta, antenna_N_delta,
45-
operator, agency, observables, interval, filename_file_period (01H, 01D...), filename_data_freq (30S, 01S...), filename_data_source (R, S, U)''', nargs='*', action=ParseKwargs, default=None)
46-
47-
parser.add_argument('-m', '--marker', help="A four or nine character site code that will be used to rename input files. (apply also to the header\'s MARKER NAME, but a custom -k marker_name='XXXX' overrides it)", type=str, default='')
48-
parser.add_argument('-n', '--ninecharfile',
31+
parser = argparse.ArgumentParser(description='RinexMod takes RINEX files (v2 or v3, compressed or not), rename them and modifiy their headers, and write them back to a destination directory',
32+
formatter_class=SmartFormatter,
33+
epilog=textwrap.dedent('RinexMod ' + str(rinexmod.__version__) + ' - GNU Public Licence v3 - P. Sakic et al. - IPGP-OVS - https://github.com/IPGP/rinexmod'))
34+
required = parser.add_argument_group('required arguments')
35+
optional = parser.add_argument_group('optional arguments')
36+
37+
required.add_argument('-i','--rinexinput', type=str, required=True, nargs='+',
38+
help="Input RINEX file(s). It can be 1) a list file of the RINEX paths to process (generated with find or ls command for instance) 2) several RINEX files paths 3) a single RINEX file path (see -a/--alone for a single input file)")
39+
required.add_argument('-o','--outputfolder', type=str, required=True,
40+
help='Output folder for modified RINEX files')
41+
optional.add_argument(
42+
'-s', '--sitelog', help="Get the RINEX header values from file's site's sitelog. Provide a single sitelog path or a folder contaning sitelogs.", type=str, default="")
43+
optional.add_argument('-k', '--modif_kw', help=("""Modification keywords for RINEX's header fields and/or filename. Format: -k keyword_1='value1' keyword2='value2'.
44+
Will override the information from the sitelog.
45+
Acceptable keywords: comment, marker_name, marker_number, station (legacy alias for marker_name), receiver_serial,
46+
receiver_type, receiver_fw, antenna_serial, antenna_type, antenna_X_pos, antenna_Y_pos, antenna_Z_pos, antenna_H_delta,
47+
antenna_E_delta, antenna_N_delta, operator, agency, sat_system, observables (legacy alias for sat_system), interval,
48+
filename_file_period (01H, 01D...), filename_data_freq (30S, 01S...), filename_data_source (R, S, U).
49+
"""), nargs='+', metavar="KEY=VALUE", action=rimo_api.ParseKwargs, default=None)
50+
optional.add_argument('-m', '--marker',
51+
help="A four or nine character site code that will be used to rename input files. (apply also to the header's MARKER NAME, but a custom -k marker_name='XXXX' overrides it)", type=str, default='')
52+
optional.add_argument('-co', '--country',
53+
help='A three character string corresponding to the ISO 3166 Country code that will be used to rename input files. It overrides other country code sources (sitelog, --marker...). List of ISO country codes: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes', type=str, default="")
54+
optional.add_argument('-n', '--ninecharfile',
4955
help='Path of a file that contains 9-char. site names (e.g. from the M3G database)', type=str, default="")
50-
parser.add_argument('-r', '--relative', help='Reconstruct files relative subfolders. You have to indicate the common parent folder, that will be replaced with the output folder', type=str, default=0)
51-
parser.add_argument('-c', '--compression', type=str,
52-
help='Set file\'s compression (acceptables values : \'gz\' (recommended to fit IGS standards), \'Z\', \'none\')', default='')
53-
parser.add_argument(
56+
optional.add_argument('-sti', '--station_info',
57+
help='Path of a GAMIT station.info file to obtain GNSS site metadata information (needs also -lfi option)', type=str, default="")
58+
optional.add_argument('-lfi', '--lfile_apriori',
59+
help='Path of a GAMIT apriori apr/L-File to obtain GNSS site position and DOMES information (needs also -sti option)', type=str, default="")
60+
optional.add_argument('-r', '--relative', help='Reconstruct files relative subfolders. You have to indicate the common parent folder, that will be replaced with the output folder', type=str, default=0)
61+
optional.add_argument('-nh', '--no_hatanaka', help="Skip high-level RINEX-specific Hatanaka compression (performed per default). See also -c 'none'", action='store_true', default=False)
62+
optional.add_argument('-c', '--compression', type=str,
63+
help="Set low-level RINEX file compression (acceptable values : 'gz' (recommended to fit IGS standards), 'Z', 'none')", default='')
64+
optional.add_argument(
5465
'-l', '--longname', help='Rename file using long name RINEX convention (force gzip compression).', action='store_true', default=False)
55-
parser.add_argument(
56-
'-fs', '--force_sitelog', help="Force sitelog-based header values when RINEX's header and sitelog site name do not correspond", action='store_true', default=False)
57-
parser.add_argument(
66+
optional.add_argument(
67+
'-fs', '--force_sitelog', help="If a single sitelog is provided, force sitelog-based header values when RINEX's header and sitelog site name do not correspond. \n If several sitelogs are provided, skip badly-formated sitelogs.", action='store_true', default=False)
68+
optional.add_argument(
69+
'-fc', '--force_fake_coords', help="When using GAMIT station.info metadata without apriori coordinates in the L-File, gives fake coordinates at (0°,0°) to the site", action='store_true', default=False)
70+
optional.add_argument(
5871
'-fr', '--force_rnx_load', help="Force the loading of the input RINEX. Useful if its name is not standard", action='store_true', default=False)
59-
parser.add_argument(
60-
'-i', '--ignore', help='Ignore firmware changes between instrumentation periods when getting header values info from sitelogs', action='store_true')
61-
parser.add_argument(
72+
optional.add_argument(
73+
'-ig', '--ignore', help='Ignore firmware changes between instrumentation periods when getting header values info from sitelogs', action='store_true')
74+
optional.add_argument(
6275
'-a', '--alone', help='INPUT is a single/alone RINEX file (and not a list file of RINEX paths)', action='store_true')
63-
parser.add_argument('-o', '--output_logs',
76+
optional.add_argument('-ol', '--output_logs',
6477
help='Folder where to write output logs. If not provided, logs will be written to OUTPUTFOLDER', type=str)
65-
parser.add_argument(
78+
optional.add_argument(
6679
'-w', '--write', help='Write (RINEX version, sample rate, file period) dependant output lists', action='store_true')
67-
parser.add_argument(
68-
'-v', '--verbose', help='Print file\'s metadata before and after modifications.', action='store_true', default=False)
69-
parser.add_argument(
80+
optional.add_argument(
81+
'-v', '--verbose', help="Print file's metadata before and after modifications.", action='store_true', default=False)
82+
optional.add_argument(
7083
'-t', '--sort', help='Sort the input RINEX list.', action='store_true', default=False)
71-
parser.add_argument(
84+
optional.add_argument(
7285
'-u', '--full_history', help="Add the full history of the station in the RINEX's 'header as comment.", action='store_true', default=False)
73-
parser.add_argument(
86+
optional.add_argument(
7487
'-tol', '--tolerant_file_period', help="the RINEX file period is tolerant and stick to the actual data content, but then can be odd (e.g. 07H, 14H...). A strict file period is applied per default (01H or 01D), being compatible with the IGS conventions", action='store_true', default=False)
75-
parser.add_argument(
76-
'-mp', '--multi_process', help="number of parallel multiprocesing (default: %(default)s, no parallelization)", type=int, default=1)
77-
parser.add_argument(
78-
'-d', '--debug', help="debug mode, stops if something goes wrong (default: %(default)s)", action='store_true', default=False)
79-
80-
88+
optional.add_argument(
89+
'-mp', '--multi_process', help="Number of parallel multiprocesing (default: %(default)s, no parallelization)", type=int, default=1)
90+
optional.add_argument(
91+
'-d', '--debug', help="Debug mode, stops if something goes wrong (default: %(default)s)", action='store_true', default=False)
8192

8293
args = parser.parse_args()
8394

@@ -86,8 +97,10 @@ def __call__(self, parser, namespace, values, option_string=None):
8697
sitelog = args.sitelog
8798
modif_kw = args.modif_kw
8899
marker = args.marker
100+
country = args.country
89101
ninecharfile = args.ninecharfile
90102
relative = args.relative
103+
no_hatanaka = args.no_hatanaka
91104
compression = args.compression
92105
longname = args.longname
93106
force_sitelog = args.force_sitelog
@@ -102,37 +115,35 @@ def __call__(self, parser, namespace, values, option_string=None):
102115
tolerant_file_period = args.tolerant_file_period
103116
multi_process = args.multi_process
104117
debug = args.debug
118+
station_info = args.station_info
119+
lfile_apriori = args.lfile_apriori
120+
force_fake_coords = args.force_fake_coords
105121

106-
rma.rinexmod_cli(rinexinput,
107-
outputfolder,
108-
sitelog=sitelog,
109-
modif_kw=modif_kw,
110-
marker=marker,
111-
longname=longname,
112-
force_sitelog=force_sitelog,
113-
force_rnx_load=force_rnx_load,
114-
ignore=ignore,
115-
ninecharfile=ninecharfile,
116-
compression=compression,
117-
relative=relative,
118-
verbose=verbose,
119-
alone=alone,
120-
output_logs=output_logs,
121-
write=write,
122-
sort=sort,
123-
full_history=full_history,
124-
tolerant_file_period=tolerant_file_period,
125-
multi_process=multi_process,
126-
debug=debug)
122+
rimo_api.rinexmod_cli(rinexinput,
123+
outputfolder,
124+
sitelog=sitelog,
125+
modif_kw=modif_kw,
126+
marker=marker,
127+
country=country,
128+
longname=longname,
129+
force_sitelog=force_sitelog,
130+
force_rnx_load=force_rnx_load,
131+
ignore=ignore,
132+
ninecharfile=ninecharfile,
133+
no_hatanaka=no_hatanaka,
134+
compression=compression,
135+
relative=relative,
136+
verbose=verbose,
137+
alone=alone,
138+
output_logs=output_logs,
139+
write=write,
140+
sort=sort,
141+
full_history=full_history,
142+
tolerant_file_period=tolerant_file_period,
143+
multi_process=multi_process,
144+
debug=debug,
145+
station_info=station_info,
146+
lfile_apriori=lfile_apriori,
147+
force_fake_coords=force_fake_coords)
127148

128-
def __print_tips(values):
129-
print("********************************************")
130-
print("TIP1: be sure you have respected the syntax:")
131-
print(" -k keyword_1='value' keyword2='value' ")
132-
print("TIP2: don't use -k as last option, it will ")
133-
print(" enroll rinexinput & outputfolder args ")
134-
print("********************************************")
135-
print(values)
136149

137-
return None
138-

rinexmod/__init__.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
from . import logger
12
from . import rinexfile
2-
from . import sitelog
3+
from . import metadata
4+
from . import gamit_meta
35
from . import rinexmod_api
6+
7+
__version__='3.0.0' ## CHANGE IT ALSO IN setup and readme !!!!
8+

0 commit comments

Comments
 (0)