Skip to content

Commit

Permalink
Merge pull request #147 from IPGP/prerelease
Browse files Browse the repository at this point in the history
Prerelease v3.4.0
  • Loading branch information
PierreS-alpha authored Dec 2, 2024
2 parents 9fea70b + aa59379 commit 2ec7b19
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 69 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__pycache__
venv/
.idea/
venvrimo3/
rinexmod.egg-info/
py3rimo4a/
venvrimo3/

1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include requirements.txt
51 changes: 21 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,24 @@ It is developed in Python 3, and can be run from the command line or directly in
The required input metadata can come from a sitelog file, or be manually entered as arguments to the command line or the called function.
It is available under the GNU license on the following GitHub repository: https://github.com/IPGP/rinexmod

v2 - 2023-05-15 - Pierre Sakic - sakic@ipgp.fr
v1 - 2022-02-07 - Félix Léger - leger@ipgp.fr
v2+ - 2023-05-15 - Pierre Sakic - sakic@ipgp.fr
v1 - 2022-02-07 - Félix Léger - leger@ipgp.fr

Last version: v3.4.0 - 2024-09-30

## Tools overview

### Main tool

* `rinexmod.py` takes a list of RINEX Hatanaka compressed files (.d.Z or .d.gz or .rnx.gz),
* `rinexmod_run` takes a list of RINEX Hatanaka compressed files (.d.Z or .d.gz or .rnx.gz),
loops the rinex files list to modify the file's headers. It then writes them back to Hatanaka
compressed format in an output folder. It also permits to rename the files, changing
the four first characters of the file name with another station code. It can write
those files with the long name naming convention with the --longname option.

### Annex tools

They are stored in `misc_tools` folder.
They are stored in `bin/misc_tools` folder.

* `get_m3g_sitelogs.py` will get the last version of site logs from the M3G repository
and write them in an observatory-dependent subfolder.
Expand All @@ -42,14 +42,7 @@ The tool is designed in Python 3, and you must have it installed on your machine
You can use `pip` to install the last GitHub-hosted version with the following command:
```pip install git+https://github.com/IPGP/rinexmod```

To use the front-end functions, you must also add the `rinexmod` folder in your `$PATH` environnement variable,
defined in your `.bashrc`.
If you used PIP for the installation, your can locate the folder where `rinexmod` has been installed with:
```
pip show rinexmod
```
at the line `Location:`. Usually, it is `/usr/local/lib/python3.NN/dist-packages/rinexmod` .
Then edit your `~/.bashrc` and add it to the `$PATH` environnement variable
Since the version 3.4.0, the frontend program `rinexmod_run` is available directly when you call it in your console.

### Required external modules

Expand All @@ -67,11 +60,9 @@ You can install them with:
pip install hatanaka pycountry matplotlib colorlog pandas
```



## _rinexmod_ in command lines interface

### rinexmod.py
### rinexmod_run

This is the main frontend function. It takes a list of RINEX Hatanaka compressed files (.d.Z or .d.gz or .rnx.gz),
loop over the RINEX files list to modify the file's header. It then writes them back to Hatanaka-compressed
Expand Down Expand Up @@ -146,13 +137,13 @@ _rinexmod_ will add two comment lines, one indicating the source of the modifica
### Synopsis
```
rinexmod.py [-h] -i RINEXINPUT [RINEXINPUT ...] -o OUTPUTFOLDER
[-s SITELOG] [-k KEY=VALUE [KEY=VALUE ...]] [-m MARKER]
[-co COUNTRY] [-n NINECHARFILE] [-sti STATION_INFO]
[-lfi LFILE_APRIORI] [-r RELATIVE] [-nh] [-c {gz,Z,none}]
[-l] [-fs] [-fc] [-fr] [-ig] [-a] [-ol OUTPUT_LOGS] [-w]
[-v] [-t] [-u] [-fns {basic,flex,exact}]
[-mp MULTI_PROCESS] [-d] [-rm]
rinexmod_run [-h] -i RINEXINPUT [RINEXINPUT ...] -o OUTPUTFOLDER
[-s SITELOG] [-k KEY=VALUE [KEY=VALUE ...]] [-m MARKER]
[-co COUNTRY] [-n NINECHARFILE] [-sti STATION_INFO]
[-lfi LFILE_APRIORI] [-r RELATIVE] [-nh] [-c {gz,Z,none}]
[-l] [-fs] [-fc] [-fr] [-ig] [-a] [-ol OUTPUT_LOGS] [-w]
[-v] [-t] [-u] [-fns {basic,flex,exact}]
[-mp MULTI_PROCESS] [-d] [-rm]

RinexMod takes RINEX files (v2 or v3/4, compressed or not), rename them and modifiy their headers, and write them back to a destination directory

Expand Down Expand Up @@ -195,7 +186,7 @@ optional arguments:
-fs, --force_sitelog If a single sitelog is provided, force sitelog-based header values when RINEX's header and sitelog site name do not correspond.
If several sitelogs are provided, skip badly-formated sitelogs.
-fc, --force_fake_coords
When using GAMIT station.info metadata without apriori coordinates in the L-File, gives fake coordinates at (0°,0°) to the site
When using GAMIT station.info metadata without apriori coordinates in the L-File, gives fake coordinates at (0??,0??) to the site
-fr, --force_rnx_load
Force the loading of the input RINEX. Useful if its name is not standard
-ig, --ignore Ignore firmware changes between instrumentation periods when getting header values info from sitelogs
Expand Down Expand Up @@ -229,10 +220,10 @@ RinexMod 3.3.0 - GNU Public Licence v3 - P. Sakic et al. - IPGP-OVS - https://gi
### Examples
```
./rinexmod.py -i RINEXLIST -o OUTPUTFOLDER (-k antenna_type='ANT TYPE' antenna_X_pos=9999 agency=AGN) (-m AGAL) (-r ./ROOTFOLDER/) (-f) (-v)
./rinexmod_run -i RINEXLIST -o OUTPUTFOLDER (-k antenna_type='ANT TYPE' antenna_X_pos=9999 agency=AGN) (-m AGAL) (-r ./ROOTFOLDER/) (-f) (-v)
```
```
./rinexmod.py (-a) -i RINEXFILE -o OUTPUTFOLDER (-s ./sitelogsfolder/stationsitelog.log) (-i) (-w) (-o ./LOGFOLDER) (-v)
./rinexmod_run (-a) -i RINEXFILE -o OUTPUTFOLDER (-s ./sitelogsfolder/stationsitelog.log) (-i) (-w) (-o ./LOGFOLDER) (-v)
```
## _rinexmod_ in API mode
Expand Down Expand Up @@ -373,7 +364,7 @@ rimo_api.rinexmod(rinexfile, outputfolder, sitelog=None, modif_kw=dict(), marker
position and DOMES information (needs also station_info option)
force_fake_coords: bool, optional
When using GAMIT station.info metadata without apriori coordinates
in the L-File, gives fake coordinates at (0°,0°) to the site
in the L-File, gives fake coordinates at (0??,0??) to the site
remove: bool, optional
Remove input RINEX file if the output RINEX is correctly written
The default is False.
Expand All @@ -397,17 +388,17 @@ rimo_api.rinexmod(rinexfile, outputfolder, sitelog=None, modif_kw=dict(), marker
```
## Other command line functions
### crzmeta.py
### crzmeta
Extract metadata from crz file.
With -p option, will plot the file's samples intervals
```
EXAMPLE:
./crzmeta.py RINEXFILE (-p)
./crzmeta RINEXFILE (-p)
```
### get_m3g_sitelogs.py
### get_m3g_sitelogs
This script will get the last version of sitelogs from M3G repository and write them
in an observatory dependent subfolder set in 'observatories'.
Expand All @@ -425,7 +416,7 @@ OPTION :

EXAMPLE:

./get_m3g_sitelogs.py OUTPUTFOLDER (-d)
./get_m3g_sitelogs OUTPUTFOLDER (-d)
```
## _rinexmod_ error messages
Expand Down
29 changes: 29 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
## Changelog

### v3.4.0 (Dec, 2024)

- shell programs are now in a `bin` folder and are set as executable in the `setup.py`
- **the frontend command line interface program has been renamed `rinexmod_run.py` to avoid conflict with the module name**
- add `shortname` option to force RINEX file renaming with short name convention, and modify `longname` option to force RINEX file renaming with long name convention
(Behavior of previous `longname` option was ambiguous.)
`shortname` is mutually exclusive with `longname`.

### v3.3.0 (Sep 4, 2024)

* `--tolerant_file_period/-tol` is replaced by a more flexible --filename_style/-fns option.
* it takes now one string argument with 3 acceptable values: 'basic' (per default), 'flex', and 'exact'.
see help for more details
* misc. improvements and bug corrections

### v3.2.0 (Aug 15, 2024)

Misc improvements:

* Enhanced log messages
* Some exception handling when reading RINEX
* RINEX version attribute is now also float
* you can now remove your input RINEXs with -rm, but be carful of what you are doing!


### v3.1.0 (Jun 5, 2024)

make rinexmod compliant with IGSMAIL-8458, i.e. nine characters site in sitelogs, and Country or Region field instead of Country.

### v3.0.0 (Mar 15, 2024)

- **important user interface change**
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
colorlog
pandas
hatanaka
matplotlib
#matplotlib
numpy
requests
setuptools
7 changes: 7 additions & 0 deletions rinexmod/bin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on 21/09/2024 20:30:36
@author: psakic
"""
7 changes: 7 additions & 0 deletions rinexmod/bin/misc_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on 21/09/2024 20:30:36
@author: psakic
"""
6 changes: 4 additions & 2 deletions misc_tools/crzmeta.py → rinexmod/bin/misc_tools/crzmeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ def crzmeta(rinexfile, plot):
return


if __name__ == '__main__':

def main():
import argparse

# Parsing Args
Expand All @@ -68,3 +67,6 @@ def crzmeta(rinexfile, plot):
plot = args.plot

crzmeta(rinexfile, plot)

if __name__ == '__main__':
main()
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@

import rinexmod.get_m3g

if __name__ == "__main__":

def main():
import argparse

# Parsing Args
Expand Down Expand Up @@ -123,3 +122,6 @@
rinexmod.get_m3g.get_m3g_sitelogs(
sitelogsfolder, delete, observatory, root, svn, move_folder, force, exclude
)

if __name__ == '__main__':
main()
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ def rinexrename(rinexinput, output=None, delete=False, alone=False, country="00X
return Output_path_list


if __name__ == '__main__':

def main():
import argparse


Expand All @@ -80,3 +79,6 @@ def rinexrename(rinexinput, output=None, delete=False, alone=False, country="00X
country = args.country

rinexrename(rinexinput, output, delete, alone, country)

if __name__ == '__main__':
main()
5 changes: 1 addition & 4 deletions rinexmod.py → rinexmod/bin/rinexmod_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@
import argparse
import textwrap

import textwrap


import rinexmod
import rinexmod.rinexmod_api as rimo_api

from argparse import RawTextHelpFormatter

if __name__ == "__main__":
def main():

class SmartFormatter(argparse.HelpFormatter):
# source: https://stackoverflow.com/a/22157136/3464212
Expand Down
14 changes: 8 additions & 6 deletions rinexmod/rinexfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from pathlib import Path

import hatanaka
import matplotlib.pyplot as plt
#import matplotlib.pyplot as plt
import numpy as np

import rinexmod.logger as rimo_log
Expand Down Expand Up @@ -675,14 +675,14 @@ def _get_date_patterns(self):
# Pattern of an observation line containing a date - RINEX 3
# date_pattern = re.compile('> (\d{4}) (\d{2}) (\d{2}) (\d{2}) (\d{2}) ((?: |\d)\d.\d{4})')
date_pattern = re.compile(
"> (\d{4}) (\d{2}| \d) (\d{2}| \d) (\d{2}| \d) (\d{2}| \d) ((?: |\d)\d.\d{4})"
r"> (\d{4}) (\d{2}| \d) (\d{2}| \d) (\d{2}| \d) (\d{2}| \d) ((?: |\d)\d.\d{4})"
)
year_prefix = "" # Prefix of year for date formatting

elif self.version_float < 3:
# Pattern of an observation line containing a date - RINEX 2
date_pattern = re.compile(
" (\d{2}) ((?: |\d)\d{1}) ((?: |\d)\d{1}) ((?: |\d)\d{1}) ((?: |\d)\d{1}) ((?: |\d)\d{1}.\d{4})"
r" (\d{2}) ((?: |\d)\d{1}) ((?: |\d)\d{1}) ((?: |\d)\d{1}) ((?: |\d)\d{1}) ((?: |\d)\d{1}.\d{4})"
)
year_prefix = "20" # Prefix of year for date formatting
### !!!!!!!!! before 2000 must be implemented !!!!!!
Expand Down Expand Up @@ -881,7 +881,9 @@ def _date_conv(sample):

non_nominal_interval_percent = num_bad_sp / len(samples_rate_diff)

plot = False
if plot:
import matplotlib.pyplot as plt
print(
"{:29} : {}".format(
"Sample intervals not nominals",
Expand Down Expand Up @@ -2164,13 +2166,13 @@ def regex_pattern_rinex_filename():
pattern_dic = dict()
# pattern_dic["shortname"] = "....[0-9]{3}(\d|\D)\.[0-9]{2}(o|d)(|\.(Z|gz))"
pattern_dic["shortname"] = (
"....[0-9]{3}(\d|\D)([0-9]{2}\.|\.)[0-9]{2}(o|d)(|\.(Z|gz))" ### add subhour starting min
r"....[0-9]{3}(\d|\D)([0-9]{2}\.|\.)[0-9]{2}(o|d)(|\.(Z|gz))" ### add subhour starting min
)
pattern_dic["longname"] = (
".{4}[0-9]{2}.{3}_(R|S|U)_[0-9]{11}_([0-9]{2}\w)_[0-9]{2}\w_\w{2}\.\w{3}(\.gz|)"
r".{4}[0-9]{2}.{3}_(R|S|U)_[0-9]{11}_([0-9]{2}\w)_[0-9]{2}\w_\w{2}\.\w{3}(\.gz|)"
)
pattern_dic["longname_gfz"] = (
".{4}[0-9]{2}.{3}_[0-9]{8}_.{3}_.{3}_.{2}_[0-9]{8}_[0-9]{6}_[0-9]{2}\w_[0-9]{2}\w_[A-Z]*\.\w{3}(\.gz)?"
r".{4}[0-9]{2}.{3}_[0-9]{8}_.{3}_.{3}_.{2}_[0-9]{8}_[0-9]{6}_[0-9]{2}\w_[0-9]{2}\w_[A-Z]*\.\w{3}(\.gz)?"
)

return pattern_dic
Expand Down
Loading

0 comments on commit 2ec7b19

Please sign in to comment.