Skip to content

Commit 1b5fec8

Browse files
committed
NPI-4237 remove usage of Union. Various minor fixes
1 parent 99318b1 commit 1b5fec8

15 files changed

Lines changed: 146 additions & 161 deletions

File tree

gnssanalysis/filenames.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
# The collections.abc (rather than typing) versions don't support subscripting until 3.9
99
# from collections import Iterable
10-
from typing import Iterable, Literal, Mapping, Any, Optional, Union, overload
10+
from typing import Iterable, Literal, Mapping, Any, Optional, overload
1111
import warnings
1212

1313
import click
@@ -262,7 +262,7 @@ def generate_IGS_long_filename(
262262
start_epoch: datetime.datetime,
263263
*,
264264
end_epoch: datetime.datetime,
265-
timespan: Union[datetime.timedelta, str, None] = ...,
265+
timespan: datetime.timedelta | str | None = ...,
266266
solution_type: str = ...,
267267
sampling_rate: str = ...,
268268
sampling_rate_seconds: Optional[int] = ...,
@@ -280,7 +280,7 @@ def generate_IGS_long_filename(
280280
start_epoch: datetime.datetime,
281281
*,
282282
end_epoch: None = ...,
283-
timespan: Union[datetime.timedelta, str],
283+
timespan: datetime.timedelta | str,
284284
solution_type: str = ...,
285285
sampling_rate: str = ...,
286286
sampling_rate_seconds: Optional[int] = ...,
@@ -297,7 +297,7 @@ def generate_IGS_long_filename(
297297
start_epoch: datetime.datetime,
298298
*,
299299
end_epoch: Optional[datetime.datetime] = None,
300-
timespan: Union[datetime.timedelta, str, None] = None,
300+
timespan: datetime.timedelta | str | None = None,
301301
solution_type: str = "", # TTT
302302
sampling_rate: str = "15M", # SMP
303303
sampling_rate_seconds: Optional[int] = None, # Not used here, but passed for structural consistency
@@ -321,7 +321,7 @@ def generate_IGS_long_filename(
321321
:param str format_type: File extension
322322
:param datetime.datetime start_epoch: datetime representing initial epoch in file
323323
:param Optional[datetime.datetime] end_epoch: datetime representing final epoch in file, defaults to None
324-
:param timespan: Union[datetime.timedelta, str, None] timespan: timedelta representing time range of data in file,
324+
:param timespan: datetime.timedelta | str | None timespan: timedelta representing time range of data in file,
325325
defaults to None
326326
:param str solution_type: Three letter solution type identifier, defaults to ""
327327
:param str sampling_rate: Three letter sampling rate string, defaults to "15M"
@@ -437,7 +437,7 @@ def nominal_span_string(span_seconds: float) -> str:
437437
def convert_nominal_span(
438438
nominal_span: str,
439439
non_timed_span_output: Literal["none", "timedelta"] = "timedelta",
440-
) -> Union[datetime.timedelta, None]:
440+
) -> datetime.timedelta | None:
441441
"""Effectively invert :func: `filenames.generate_nominal_span`, turn a span string into a timedelta
442442
443443
:param str nominal_span: Three-character span string in IGS format (e.g. 01D, 15M, 01L ?)
@@ -729,7 +729,7 @@ def determine_sp3_name_props(
729729

730730
# Next, properties from the filename:
731731
try:
732-
props_from_existing_name: Union[dict, None] = determine_properties_from_filename(
732+
props_from_existing_name: dict | None = determine_properties_from_filename(
733733
file_path.name, strict_mode=strict_mode
734734
)
735735
logging.debug(f"props_from_existing_name =\n{str(props_from_existing_name)}")

gnssanalysis/gn_aux.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Auxiliary functions"""
22

33
import logging as _logging
4-
from typing import overload, Union
4+
from typing import overload
55
import numpy as _np
66
import pandas as _pd
77

@@ -26,7 +26,7 @@ def rad2arcsec(x: _np.ndarray) -> _np.ndarray:
2626
return _np.rad2deg(x) * 3600
2727

2828

29-
def wrap_radians(x: Union[float, _np.ndarray]) -> Union[float, _np.ndarray]:
29+
def wrap_radians(x: float | _np.ndarray) -> float | _np.ndarray:
3030
"""Overwrite negative angles in radians with positive coterminal angles
3131
3232
:param float or _np.ndarray x: angles in radians
@@ -35,7 +35,7 @@ def wrap_radians(x: Union[float, _np.ndarray]) -> Union[float, _np.ndarray]:
3535
return x % (2 * _np.pi)
3636

3737

38-
def wrap_degrees(x: Union[float, _np.ndarray]) -> Union[float, _np.ndarray]:
38+
def wrap_degrees(x: float | _np.ndarray) -> float | _np.ndarray:
3939
"""Overwrite negative angles in decimal degrees with positive coterminal angles
4040
4141
:param float or _np.ndarray x: angles in decimal degrees
@@ -99,7 +99,7 @@ def unique_cols(df: _pd.DataFrame) -> _np.ndarray:
9999
return (a[:, 0][:, None] == a).all(1)
100100

101101

102-
def rm_duplicates_df(df: Union[_pd.DataFrame, _pd.Series], rm_nan_level: Union[int, str, None] = None):
102+
def rm_duplicates_df(df: _pd.DataFrame | _pd.Series, rm_nan_level: int | str | None = None):
103103
"""
104104
Takes in a clk/sp3/other dataframe and removes any duplicate indices.
105105
Optionally, removes level_values from the index which contain NaNs
@@ -134,7 +134,7 @@ def rm_duplicates_df(df: Union[_pd.DataFrame, _pd.Series], rm_nan_level: Union[i
134134
return df
135135

136136

137-
def get_sampling(arr: _np.ndarray) -> Union[int, None]:
137+
def get_sampling(arr: _np.ndarray) -> int | None:
138138
"""
139139
Simple function to compute sampling of the J2000 array
140140
@@ -170,10 +170,10 @@ def array_equal_unordered(a1: _np.ndarray, a2: _np.ndarray) -> bool:
170170

171171

172172
def rms(
173-
arr: Union[_pd.DataFrame, _pd.Series],
174-
axis: Union[None, int] = 0,
175-
level: Union[None, int, str] = None,
176-
) -> Union[_pd.Series, _pd.DataFrame]:
173+
arr: _pd.DataFrame | _pd.Series,
174+
axis: None | int = 0,
175+
level: None | int | str = None,
176+
) -> _pd.Series | _pd.DataFrame:
177177
"""Trivial function to compute root mean square"""
178178
if level is not None:
179179
return (arr**2).groupby(axis=axis, level=level).mean() ** 0.5
@@ -183,7 +183,7 @@ def rms(
183183

184184
def get_std_bounds(
185185
a: _np.ndarray,
186-
axis: Union[None, int, tuple[int, ...]] = None,
186+
axis: None | int | tuple[int, ...] = None,
187187
sigma_coeff: int = 3,
188188
):
189189
"""
@@ -210,7 +210,7 @@ def get_std_bounds(
210210
return bounds if axis is None else _np.expand_dims(a=bounds, axis=axis)
211211

212212

213-
def df_quick_select(df: _pd.DataFrame, ind_lvl: Union[str, int], ind_keys, as_mask: bool = False) -> _np.ndarray:
213+
def df_quick_select(df: _pd.DataFrame, ind_lvl: str | int, ind_keys, as_mask: bool = False) -> _np.ndarray:
214214
"""A faster alternative to do index selection over pandas dataframe, if multiple index levels are being used then better generate masks with this function and add them later into a single mask.
215215
df.loc(axis=0)[:,:,'IND_KEY',:] is the same as df_quick_select(df, 2, 'IND_KEY'),
216216
or, if used as mask: df[df_quick_select(df, 2, 'IND_NAME', as_mask=True)]"""
@@ -269,11 +269,11 @@ def degminsec2deg(a: list) -> _pd.Series: ...
269269
def degminsec2deg(a: str) -> float: ...
270270

271271

272-
def degminsec2deg(a: Union[_pd.Series, _pd.DataFrame, list, str]) -> Union[_pd.Series, _pd.DataFrame, float]:
272+
def degminsec2deg(a: _pd.Series | _pd.DataFrame | list | str) -> _pd.Series | _pd.DataFrame | float:
273273
"""Converts degrees/minutes/seconds to decimal degrees.
274274
275-
:param _Union[_pd.Series, _pd.DataFrame, list, str] a: space-delimited string values of degrees/minutes/seconds
276-
:return _Union[_pd.Series, _pd.DataFrame, float]: Series, DataFrame or scalar float decimal degrees, depending on the input
275+
:param __pd.Series | _pd.DataFrame | list | str a: space-delimited string values of degrees/minutes/seconds
276+
:return _pd.Series | _pd.DataFrame | float: Series, DataFrame or scalar float decimal degrees, depending on the input
277277
"""
278278
if isinstance(a, str):
279279
a_single = _np.asarray(a.split(maxsplit=2)).astype(float)
@@ -315,7 +315,7 @@ def deg2degminsec(a: list) -> _np.ndarray: ...
315315
def deg2degminsec(a: _np.ndarray) -> _np.ndarray: ...
316316

317317

318-
def deg2degminsec(a: Union[_np.ndarray, list, float]) -> Union[_np.ndarray, float]:
318+
def deg2degminsec(a: _np.ndarray | list | float) -> _np.ndarray | float:
319319
"""Converts decimal degrees to string representation in the form of degrees minutes seconds
320320
as in the sinex SITE/ID block. Could be used with multiple columns at once (2D ndarray)
321321
@@ -363,7 +363,7 @@ def throw_if_nans(trace_bytes: bytes, nan_to_find=b"-nan", max_reported_nans: in
363363
raise ValueError(f"Found nan values (max_nans = {max_reported_nans})\n{nans_bytes.decode()}")
364364

365365

366-
def df_groupby_statistics(df: Union[_pd.Series, _pd.DataFrame], lvl_name: Union[list, str]):
366+
def df_groupby_statistics(df: _pd.Series | _pd.DataFrame, lvl_name: list | str):
367367
"""Generate AVG/STD/RMS statistics from a dataframe summarizing over levels
368368
369369
:param _pd.Series df: an input dataframe or series
@@ -404,14 +404,14 @@ def _get_trend(dataset, deg=1):
404404

405405
def remove_outliers(
406406
dataframe: _pd.DataFrame,
407-
cutoff: Union[int, float, None] = None,
408-
coeff_std: Union[int, float] = 3,
407+
cutoff: int | float | None = None,
408+
coeff_std: int | float = 3,
409409
) -> _pd.DataFrame:
410410
"""Filters a dataframe with linear data. Runs detrending of the data to normalize to zero and applies absolute cutoff and std-based filtering
411411
412412
:param _pd.DataFrame dataframe: a dataframe to filter the columns
413-
:param _Union[int, float, None] cutoff: an absolute cutoff value to apply over detrended data, defaults to None
414-
:param _Union[int, float] coeff_std: STD coefficient, defaults to 3
413+
:param _int | float | None cutoff: an absolute cutoff value to apply over detrended data, defaults to None
414+
:param _int | float coeff_std: STD coefficient, defaults to 3
415415
:return _pd.DataFrame: a filtered dataframe
416416
"""
417417
detrend = dataframe - _get_trend(dataframe)

gnssanalysis/gn_datetime.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from datetime import date as _date
77
from datetime import timedelta as _timedelta
88
from io import StringIO as _StringIO
9-
from typing import Optional, overload, Union
9+
from typing import Optional, overload
1010

1111
import numpy as _np
1212
import pandas as _pd
@@ -17,7 +17,7 @@
1717
logger = logging.getLogger(__name__)
1818

1919

20-
def derive_gps_week(year: Union[int, str], day_of_year: Union[int, str], weekday_suffix: bool = False) -> str:
20+
def derive_gps_week(year: int | str, day_of_year: int | str, weekday_suffix: bool = False) -> str:
2121
"""
2222
Convert year, day-of-year to GPS week format: WWWWD or WWWW
2323
Based on code from Kristine Larson's gps.py
@@ -78,7 +78,7 @@ class GPSDate:
7878
# For compatibility, we have accessors called 'ts' and 'timestamp'.
7979
_internal_dt64: _np.datetime64
8080

81-
def __init__(self, time: Union[_np.datetime64, _datetime, _date, str]):
81+
def __init__(self, time: _np.datetime64 | _datetime | _date | str):
8282
if isinstance(time, _np.datetime64):
8383
self._internal_dt64 = time
8484
elif isinstance(time, (_datetime, _date, str)):
@@ -172,7 +172,7 @@ def datetime_to_gps_week(dt: _datetime, wkday_suff: bool = False) -> str:
172172
return derive_gps_week(yr, doy, weekday_suffix=wkday_suff)
173173

174174

175-
def dt2gpswk(dt: _datetime, wkday_suff: bool = False, both: bool = False) -> Union[str, tuple[str, str]]:
175+
def dt2gpswk(dt: _datetime, wkday_suff: bool = False, both: bool = False) -> str | tuple[str, str]:
176176
"""
177177
TODO DEPRECATED. Please use datetime_to_gps_week()
178178
"""
@@ -222,7 +222,7 @@ def gpswkD2dt(gpswkD: str) -> _datetime:
222222

223223

224224
def yydoysec2datetime(
225-
arr: Union[_np.ndarray, _pd.Series, list], recenter: bool = False, as_j2000: bool = True, delimiter: str = ":"
225+
arr: _np.ndarray | _pd.Series | list, recenter: bool = False, as_j2000: bool = True, delimiter: str = ":"
226226
) -> _np.ndarray:
227227
"""Converts snx YY:DOY:SSSSS [snx] or YYYY:DOY:SSSSS [bsx/bia] object Series/ndarray to datetime64.
228228
recenter overrides day seconds value to midday
@@ -241,7 +241,7 @@ def yydoysec2datetime(
241241
return datetime2j2000(datetime64) if as_j2000 else datetime64
242242

243243

244-
def datetime2yydoysec(datetime: Union[_np.ndarray, _pd.Series]) -> _np.ndarray:
244+
def datetime2yydoysec(datetime: _np.ndarray | _pd.Series) -> _np.ndarray:
245245
"""datetime64[s] -> yydoysecond
246246
The '2000-01-01T00:00:00' (-43200 J2000 for 00:000:00000) datetime becomes 00:000:00000 as it should,
247247
No masking and overriding with year 2100 is needed"""
@@ -270,7 +270,7 @@ def gpsweeksec2datetime(gps_week: _np.ndarray, tow: _np.ndarray, as_j2000: bool
270270
return datetime
271271

272272

273-
def datetime2gpsweeksec(array: _np.ndarray, as_decimal=False) -> Union[tuple, _np.ndarray]:
273+
def datetime2gpsweeksec(array: _np.ndarray, as_decimal=False) -> tuple | _np.ndarray:
274274
if array.dtype == int:
275275
ORIGIN = _gn_const.J2000_ORIGIN.astype("int64") - _gn_const.GPS_ORIGIN.astype("int64")
276276
gps_time = array + ORIGIN # need int conversion for the case of datetime64
@@ -523,10 +523,10 @@ def round_timedelta(delta, roundto, *, tol=0.5, abs_tol=None):
523523
524524
:delta:, :roundto:, and :abs_tol: (if used) must all have the same type.
525525
526-
:param Union[datetime.timedelta, numpy.timedelta64] delta: timedelta to round
527-
:param Union[datetime.timedelta, numpy.timedelta64] roundto: "measuring stick", :delta: is rounded to integer multiples of this value
526+
:param datetime.timedelta | numpy.timedelta64 delta: timedelta to round
527+
:param datetime.timedelta | numpy.timedelta64 roundto: "measuring stick", :delta: is rounded to integer multiples of this value
528528
:param float tol: relative tolerance to use for the measure of "near"
529-
:param Union[datetime.timedelta, numpy.timedelta64] abs_tol: absolute tolerance to use for the measure of "near"
529+
:param datetime.timedelta | numpy.timedelta64 abs_tol: absolute tolerance to use for the measure of "near"
530530
"""
531531
# TODO: Test this with numpy timedeltas, it was written for datetime.timedelta but should work
532532
if abs_tol is not None:

gnssanalysis/gn_diffaux.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import logging as _logging
22
from pathlib import Path as _Path
3-
from typing import Literal, Union
43

54
import numpy as _np
65
import pandas as _pd
@@ -24,7 +23,7 @@ def _valvar2diffstd(valvar1, valvar2, std_coeff=1):
2423
return df_combo
2524

2625

27-
def _diff2msg(diff, tol=None, dt_as_gpsweek: Union[bool, None] = False):
26+
def _diff2msg(diff, tol=None, dt_as_gpsweek: bool | None = False):
2827
_pd.set_option("display.max_colwidth", 10000)
2928
from_valvar = _np.all(_np.isin(["DIFF", "STD"], diff.columns.get_level_values(0).values))
3029

@@ -103,13 +102,13 @@ def _diff2msg(diff, tol=None, dt_as_gpsweek: Union[bool, None] = False):
103102
return msg
104103

105104

106-
def _compare_states(diffstd: _pd.DataFrame, log_lvl: int, tol: Union[float, None] = None, plot: bool = False) -> int:
105+
def _compare_states(diffstd: _pd.DataFrame, log_lvl: int, tol: float | None = None, plot: bool = False) -> int:
107106
"""_summary_
108107
109108
Args:
110109
diffstd (_pd.DataFrame): a difference DataFrame to assess
111110
log_lvl (int): logging level of the produced messages
112-
tol (_Union[float, None], optional): Either a float threshold or None to use the present STD values. Defaults to None.
111+
tol (float, optional): Either a float threshold or None to use the present STD values. Defaults to None.
113112
plot (bool, optional): So you want a simple plot to terminal? Defaults to False.
114113
115114
Returns:
@@ -142,13 +141,13 @@ def _compare_states(diffstd: _pd.DataFrame, log_lvl: int, tol: Union[float, None
142141
return 0
143142

144143

145-
def _compare_residuals(diffstd: _pd.DataFrame, log_lvl: int, tol: Union[float, None] = None):
144+
def _compare_residuals(diffstd: _pd.DataFrame, log_lvl: int, tol: float | None = None):
146145
"""Compares extracted POSTFIT residuals from the trace file and generates a comprehensive statistics on the present differences. Alternatively logs an OK message.
147146
148147
Args:
149148
diffstd (_pd.DataFrame): a difference DataFrame to assess
150149
log_lvl (int): logging level of the produced messages
151-
tol (_Union[float, None], optional): Either a float threshold or None to use the present STD values. Defaults to None.
150+
tol (float, optional): Either a float threshold or None to use the present STD values. Defaults to None.
152151
153152
Returns:
154153
int: status (0 means differences within threshold)
@@ -310,8 +309,8 @@ def compare_clk(
310309
clk_a: _pd.DataFrame,
311310
clk_b: _pd.DataFrame,
312311
norm_types: list[str] = ["daily", "epoch"],
313-
ext_dt: Union[_np.ndarray, _pd.Index, None] = None,
314-
ext_svs: Union[_np.ndarray, _pd.Index, None] = None,
312+
ext_dt: _np.ndarray | _pd.Index | None = None,
313+
ext_svs: _np.ndarray | _pd.Index | None = None,
315314
) -> _pd.DataFrame:
316315
"""
317316
DEPRECATED Please use diff_clk() instead.
@@ -333,8 +332,8 @@ def diff_clk(
333332
clk_baseline: _pd.DataFrame,
334333
clk_test: _pd.DataFrame,
335334
norm_types: list = ["daily", "epoch"],
336-
ext_dt: Union[_np.ndarray, _pd.Index, None] = None,
337-
ext_svs: Union[_np.ndarray, _pd.Index, None] = None,
335+
ext_dt: _np.ndarray | _pd.Index | None = None,
336+
ext_svs: _np.ndarray | _pd.Index | None = None,
338337
) -> _pd.DataFrame:
339338
"""Compares clock dataframes, removed common mode.
340339
@@ -343,8 +342,8 @@ def diff_clk(
343342
:param _pd.DataFrame clk_baseline: clk dataframe 2 / b
344343
:param _pd.DataFrame clk_test: clk dataframe 1 / a
345344
:param list[str] norm_types: normalization to apply, defaults to ["daily", "epoch"]
346-
:param _Union[_np.ndarray, _pd.Index, None] ext_dt: external datetime values to filter the clk dfs, defaults to None
347-
:param _Union[_np.ndarray, _pd.Index, None] ext_svs: external satellites to filter the clk dfs, defaults to None
345+
:param _np.ndarray | _pd.Index | None ext_dt: external datetime values to filter the clk dfs, defaults to None
346+
:param _np.ndarray | _pd.Index | None ext_svs: external satellites to filter the clk dfs, defaults to None
348347
:raises ValueError: if no common epochs between clk_a and external datetime were found
349348
:raises ValueError: if no common epochs between files were found
350349
:return _pd.DataFrame: clk differences in the same units as input clk dfs (usually seconds)
@@ -412,12 +411,12 @@ def diff_clk(
412411
def sisre(
413412
sp3_a: _pd.DataFrame,
414413
sp3_b: _pd.DataFrame,
415-
clk_a: Union[_pd.DataFrame, None] = None,
416-
clk_b: Union[_pd.DataFrame, None] = None,
414+
clk_a: _pd.DataFrame | None = None,
415+
clk_b: _pd.DataFrame | None = None,
417416
norm_types: list[str] = ["daily", "epoch"],
418417
output_mode: str = "rms",
419418
clean: bool = True,
420-
cutoff: Union[int, float, None] = None,
419+
cutoff: int | float | None = None,
421420
use_rms: bool = False,
422421
hlm_mode=None,
423422
plot: bool = False,
@@ -450,12 +449,12 @@ def sisre(
450449
def calculate_sisre(
451450
sp3_baseline: _pd.DataFrame,
452451
sp3_test: _pd.DataFrame,
453-
clk_baseline: Union[_pd.DataFrame, None] = None, # Clk b
454-
clk_test: Union[_pd.DataFrame, None] = None, # Clk a
452+
clk_baseline: _pd.DataFrame | None = None, # Clk b
453+
clk_test: _pd.DataFrame | None = None, # Clk a
455454
norm_types: list[str] = ["daily", "epoch"],
456455
output_mode: str = "rms",
457456
clean: bool = True,
458-
cutoff: Union[int, float, None] = None,
457+
cutoff: int | float | None = None,
459458
use_rms: bool = False,
460459
hlm_mode=None,
461460
plot: bool = False,

0 commit comments

Comments
 (0)