geodezyx.gnss_edu package
Created on 12/08/2025 14:58:49
@author: psakic
Submodules
geodezyx.gnss_edu.gnss_edu module
Created on Tue Feb 11 16:39:34 2025
@author: snahmani
- geodezyx.gnss_edu.gnss_edu.Sagnac_rotate_around_z(row)
Calcule la correction Sagnac pour les coordonnées satellites. Retourne un pd.Series avec les nouvelles colonnes X_sat_corr, Y_sat_corr, Z_sat_corr.
- geodezyx.gnss_edu.gnss_edu.best_prn_for_interval(df: DataFrame, t0: Timestamp, t1: Timestamp, snr_col: str, snr_min: float, sampling: Timedelta, pool_prns: list[str]) str | None
Pick a PRN from pool_prns that fully covers [t0, t1] with SNR>=snr_min. Tie-breaker: highest mean SNR over the interval.
Returns None if no PRN can fully cover the interval.
- geodezyx.gnss_edu.gnss_edu.build_active_pivot_schedule(df: DataFrame, selected_prns: list[str], snr_col: str = 'S1', snr_min: float = 40.0, sampling: Timedelta = Timedelta('0 days 00:00:30'), switch_margin_db: float = 2.0) Series
Build a stable active pivot schedule from a pre-selected PRN set. Switch only if the best candidate is better than current by switch_margin_db.
- Returns:
active_pivot
- Return type:
pd.Series indexed by expected epochs, values are PRN or None
- geodezyx.gnss_edu.gnss_edu.check_full_coverage_from_active_pivot(active_pivot: Series) dict
Simple proof helper: - counts None epochs - returns first/last None epoch if any
- geodezyx.gnss_edu.gnss_edu.detect_intra_arc_holes(df, sampling=Timedelta('0 days 00:00:30'), gap=Timedelta('0 days 00:30:00'))
Detect missing observations inside satellite arcs.
- A hole is defined as:
sampling*2 < dt < gap
- Parameters:
df (pandas.DataFrame) – GNSS dataframe indexed by (epoch, prn)
sampling (Timedelta) – Expected RINEX sampling interval
gap (Timedelta) – Arc segmentation threshold
- Returns:
epoch_prev : last valid observation epoch : first observation after the hole dt : time difference n_missing : number of missing epochs
- Return type:
DataFrame with columns
- geodezyx.gnss_edu.gnss_edu.enforce_min_dwell(df: DataFrame, active_pivot: Series, snr_col: str, snr_min: float, sampling: Timedelta, min_dwell: Timedelta) Series
Stability post-filter: If a segment is shorter than min_dwell, try to absorb it into the previous pivot if the previous pivot can cover the short interval.
This reduces last-minute tiny segments (e.g. 25 min) without harming coverage.
- geodezyx.gnss_edu.gnss_edu.expected_epochs(t0: Timestamp, t1: Timestamp, sampling: Timedelta) DatetimeIndex
Return the expected epoch grid (inclusive endpoints) for a given sampling.
- geodezyx.gnss_edu.gnss_edu.fix_short_pivot_segments(df: DataFrame, active_pivot: Series, snr_col: str, snr_min: float, sampling: Timedelta, min_duration: Timedelta, pool: str = 'selected_only', selected_prns: list[str] | None = None) Series
Remove segments shorter than min_duration.
Priority
merge into previous pivot if it covers the short interval
merge into next pivot if it covers the short interval
fallback: pick best PRN that covers the short interval (optional pool)
- returns:
active_pivot_fixed
- rtype:
pd.Series
- geodezyx.gnss_edu.gnss_edu.get_approx_position(fichier)
Recherche la ligne contenant ‘APPROX POSITION XYZ’ dans le fichier et retourne les trois premières valeurs sous forme de numpy.array.
- geodezyx.gnss_edu.gnss_edu.greedy_pivot_set_cover(df: DataFrame, snr_col: str, snr_min: float, sampling: Timedelta = Timedelta('0 days 00:00:30'), require_full_coverage: bool = True, return_diagnostics: bool = True)
Greedy set-cover selection of PRNs to cover ALL expected epochs with SNR >= snr_min.
Guarantee: - If require_full_coverage=True: raise RuntimeError if full coverage is impossible.
- Returns:
selected_prns (list[str])
diagnostics (dict (optional))
- geodezyx.gnss_edu.gnss_edu.grep_file(pattern, filename)
Recherche un motif dans un fichier et retourne les lignes correspondantes.
- geodezyx.gnss_edu.gnss_edu.load_and_clean_rinex(path)
Charge et nettoie un fichier RINEX d’observation.
- Paramètres :
path : chemin vers le fichier RINEX.
- Retourne :
- dfDataFrame nettoyé, indexé par [‘epoch’, ‘prn’],
et contenant une colonne ‘ind_ligne’ indiquant le numéro de ligne.
- geodezyx.gnss_edu.gnss_edu.pivot_schedule_to_segments(active_pivot: Series, sampling: Timedelta, drop_none: bool = True) DataFrame
Convert an active pivot schedule to segments: columns = prn, start, end, duration, n_epochs.
- geodezyx.gnss_edu.gnss_edu.plot_gnss_sd_by_prn(df_SD: DataFrame, observable: str = 'SD_L1', **kwargs)
Convenience wrapper for SD plots (keeps the TP API stable).
- geodezyx.gnss_edu.gnss_edu.plot_gnss_timeseries_by_prn(df: DataFrame, y: str, gap: Timedelta = Timedelta('0 days 00:30:00'), label_arcs: bool = True, arc_label_fontsize: int = 8, arc_label_xytext: tuple[int, int] = (3, 3), show_legend: bool = False, legend_outside: bool = True, legend_ncol: int = 4, title: str | None = None, xlabel: str = 'Time (epoch)', ylabel: str | None = None, figsize: tuple[int, int] = (10, 6))
Plot a GNSS time series by satellite PRN with gap handling.
- This function is generic: it works for any DataFrame that:
is indexed by a MultiIndex with levels (‘epoch’, ‘prn’)
contains a numeric column y
- Parameters:
df (pandas.DataFrame) – MultiIndex (epoch, prn).
y (str) – Column name to plot.
gap (pandas.Timedelta) – Time gap threshold used to split continuous segments (“arcs”).
label_arcs (bool) – If True, write PRN text at the start of each arc.
arc_label_fontsize (int) – Font size for PRN labels.
arc_label_xytext (tuple) – (dx, dy) offset in points for the arc labels.
show_legend (bool) – If True, show legend (often unnecessary if label_arcs=True).
legend_outside (bool) – If True, place legend outside the axes (right side).
legend_ncol (int) – Legend columns.
title (str or None) – Plot title. If None, a default title is generated.
xlabel (str) – X axis label.
ylabel (str or None) – Y axis label. If None, uses y.
figsize (tuple) – Figure size.
- Return type:
fig, ax
- geodezyx.gnss_edu.gnss_edu.plot_residual_analysis(A, B, dP_est, figure_title=None, save_path=None, P_est=None, P_rnx_header=None)
- Computes residuals (v_est = B - A @ dP_est) and creates a figure containing:
Time series of residuals (displayed as points)
Histogram of residuals (number of observations per bin)
Q-Q Plot of residuals
Scatter plot of residuals vs predicted values
Text box displaying statistics (mean, variance, std dev, skewness, kurtosis)
(Optional) Text box with additional position information: - Distance between estimated position and initial RINEX header position - Local ENU coordinates computed via tools.toolCartLocGRS80
- Parameters:
A (-) – array-like, design matrix.
B (-) – array-like, observation vector.
dP_est (-) – array-like, estimated parameter vector.
figure_title (-) – str, overall figure title.
save_path (-) – str, full path (name + extension) to save the figure.
P_est (-) – array-like, estimated position (for additional info computation).
P_rnx_header (-) – array-like, initial position from RINEX header.
- Returns:
matplotlib Figure object containing all subplots.
- Return type:
fig
- geodezyx.gnss_edu.gnss_edu.plot_sd_derivative_by_prn(df_SD: DataFrame, obs: str, gap: Timedelta = Timedelta('0 days 00:30:00'), label_arcs: bool = True, normalize_by_dt: bool = True, elev_col: str | None = None, cutoff_deg: float | None = None, title: str | None = None, phase_to_meters: bool = False, wavelength_m: float | None = None)
Plot temporal derivative of a single-difference observable by PRN.
Notes (pedagogical)
If obs is a carrier-phase SD_L* (stored in cycles), you may set phase_to_meters=True to convert cycles -> meters using the wavelength. This is ONLY for comparison with code (meters); it does not remove ambiguities.
- param df_SD:
MultiIndex (epoch, prn). Must contain column obs.
- type df_SD:
DataFrame
- param obs:
Column to differentiate (e.g., “SD_L1” cycles, “SD_C1” meters).
- type obs:
str
- param phase_to_meters:
If True and obs starts with “SD_L”, convert cycles to meters before differencing.
- type phase_to_meters:
bool
- param wavelength_m:
Override wavelength (meters) used for cycles->meters conversion. If None and obs is SD_L1/SD_L2/SD_L5, use conv.L*_WAVELENGTH.
- type wavelength_m:
float or None
- geodezyx.gnss_edu.gnss_edu.plot_series(df, col1, col2=None, coeff1=1.0, coeff2=1.0, seuil=3600, renderer='browser')
Affiche les séries temporelles pour chaque satellite. Si col2 est fourni, affiche la série : coeff1 * col1 - coeff2 * col2. Sinon, affiche la série de la colonne col1 directement. La série est découpée en segments lorsqu’un “trou” (écart > seuil) est détecté.
Paramètres
- dfDataFrame
DataFrame avec un index multi-niveaux contenant au moins le niveau ‘prn’ et les colonnes col1 (et éventuellement col2).
- col1str
Nom de la première colonne.
- col2str, optional
Nom de la seconde colonne (optionnel). Si None, on affiche col1.
- coeff1float
Coefficient multiplicateur pour la première colonne (défaut 1.0).
- coeff2float
Coefficient multiplicateur pour la seconde colonne (défaut 1.0).
- seuilfloat
Seuil en secondes pour considérer un “trou” dans la série (défaut 3600).
- rendererstr
Renderer Plotly (ex : “browser” ou “iframe”).
Retourne
- figFigure
Figure Plotly contenant les courbes tracées.
- geodezyx.gnss_edu.gnss_edu.plot_tracking_timeline(df: DataFrame, sampling: Timedelta = Timedelta('0 days 00:00:30'), snr_col: str | None = None, snr_min: float | None = None, title: str | None = None)
Timeline heatmap of tracking availability by PRN.
Black = epoch exists for this PRN (and SNR >= snr_min if provided) White = missing epoch (or SNR < snr_min)
- Parameters:
df (DataFrame) – Must be indexed by MultiIndex (‘epoch’,’prn’).
sampling (Timedelta) – Expected observation interval (e.g. 30 s).
snr_col (str or None) – Column name for SNR (e.g., ‘S1’). If None, only presence/absence is shown.
snr_min (float or None) – If provided with snr_col, only epochs with SNR >= snr_min are considered “present”.
- geodezyx.gnss_edu.gnss_edu.plot_tracking_timeline_with_pivots(df: DataFrame, selected_prns: list[str], sampling: Timedelta = Timedelta('0 days 00:00:30'), snr_col: str = 'S1', snr_min: float = 40.0, active_pivot: Series | None = None, title: str | None = None)
Tracking timeline with SNR threshold + pivot satellites highlighted.
Color meaning
0 = white : missing epoch OR SNR < snr_min 1 = black : usable (SNR >= snr_min) but NOT selected as pivot 2 = green : usable (SNR >= snr_min) AND selected as pivot 3 = dark green : active pivot at this epoch (provided by active_pivot)
- param df:
MultiIndex (epoch, prn). Must contain snr_col.
- type df:
DataFrame
- param selected_prns:
PRNs selected by the greedy algorithm (candidate pivots).
- type selected_prns:
list[str]
- param sampling:
Expected sampling interval (e.g. 30 s).
- type sampling:
Timedelta
- param snr_col:
SNR column name (e.g., “S1”).
- type snr_col:
str
- param snr_min:
Minimum SNR threshold to consider a satellite usable.
- type snr_min:
float
- param active_pivot:
Series indexed by expected_epochs, values are PRN (string) or None/NaN. If provided, it is used to mark state=3 (dark green).
- type active_pivot:
pd.Series | None
- param title:
Plot title override.
- type title:
str | None
- rtype:
fig, ax, info
- geodezyx.gnss_edu.gnss_edu.prn_covers_interval(df: DataFrame, prn: str, t0: Timestamp, t1: Timestamp, snr_col: str, snr_min: float, sampling: Timedelta) bool
True if PRN has non-NaN SNR >= snr_min at ALL expected epochs in [t0, t1].
- geodezyx.gnss_edu.gnss_edu.prn_snr_on_grid(df: DataFrame, prn: str, snr_col: str, epochs: DatetimeIndex) Series
Return SNR series for one PRN reindexed on epochs. Missing epochs -> NaN.
geodezyx.gnss_edu.gpt3 module
Created on Fri Feb 9 07:43:47 2024
@author: snahmani
- geodezyx.gnss_edu.gpt3.gpt3_5_fast(mjd=None, lat=None, lon=None, h_ell=None, it=None, grid=None)
- geodezyx.gnss_edu.gpt3.gpt3_5_fast_readGrid(filename='./gpt3_5.grd')
geodezyx.gnss_edu.klobuchar module
Created on Tue Feb 6 10:30:57 2024
Filière ING3 - PPMD - Traitement de la mesure de phase
@author: Samuel Nahmani (1,2) https://www.ipgp.fr/annuaire/nahmani/) contact : nahmani@ipgp.fr ou samuel.nahmani@ign.fr (1) Université Paris Cité, Institut de physique du globe de Paris, CNRS, IGN, F-75005 Paris, France. (2) Univ Gustave Eiffel, ENSG, IGN, F-77455 Marne-la-Vallée, France.
Version: 1.0 Dépendances: numpy, geodezyx, datetime
- geodezyx.gnss_edu.klobuchar.klobuchar(phi, lambda_, elev, azimuth, tow, alpha, beta)
Compute ionospheric range correction for GPS L1 frequency using Klobuchar model.
Translation to Python of Meysam Mahooti (2024). Klobuchar Ionospheric Delay Model https://www.mathworks.com/matlabcentral/fileexchange/59530-klobuchar-ionospheric-delay-model MATLAB Central File Exchange. Retrieved February 7, 2024.
- Parameters:
phi (float) – Geodetic latitude of receiver (degrees).
lambda (float) – Geodetic longitude of receiver (degrees).
elev (float) – Elevation angle of satellite (degrees).
azimuth (float) – Geodetic azimuth of satellite (degrees).
tow (float) – Time of Week (seconds).
alpha (array_like) – The coefficients of a cubic equation representing the amplitude of the vertical delay (4 coefficients - 8 bits each).
beta (array_like) – The coefficients of a cubic equation representing the period of the model (4 coefficients - 8 bits each).
- Returns:
d_ion1 – Ionospheric slant range correction for the L1 frequency (metres).
- Return type:
float
References
Klobuchar, J.A., (1996) “Ionospheric Effects on GPS”, in Parkinson, Spilker (ed), “Global Positioning System Theory and Applications, pp.513-514.
ICD-GPS-200, Rev. C, (1997), pp. 125-128
NATO, (1991), “Technical Characteristics of the NAVSTAR GPS”, pp. A-6-31 - A-6-33
geodezyx.gnss_edu.read_vmf1_grid module
read_vmf1_grid.py — autonome (sans jdutil) Lecture + interpolation des coefficients VMF1 (ah, aw) aux coordonnées station et à des dates MJD arbitraires, à partir des fichiers VMFG_YYYYMMDD.HHH.
- Interpolation spatiale:
tente scipy.interpolate.griddata (linear)
sinon repli nearest neighbor (NumPy) si SciPy indisponible
Interpolation temporelle: linéaire entre pas 6h
Chemins: ./Mapping_Fcn/vmf1/VMFG_YYYYMMDD.HHH
- Format attendu des fichiers (après les lignes commençant par ‘!’):
lat lon ah aw zhd zwd (au minimum: lat, lon, ah, aw)
Auteur: adapté pour être autonome (remplacement de jdutil)
- class geodezyx.gnss_edu.read_vmf1_grid.VMFPoint(lat: 'float', lon: 'float', ah: 'float', aw: 'float')
Bases:
object- ah: float
- aw: float
- lat: float
- lon: float
- geodezyx.gnss_edu.read_vmf1_grid.add_hours(dt, hours: int)
- geodezyx.gnss_edu.read_vmf1_grid.datetime_to_mjd(dt) float
Convertit un datetime UTC naïf/aware en MJD (UTC).
- geodezyx.gnss_edu.read_vmf1_grid.floor_to_6h(dt)
Ramène dt à l’heure multiple de 6h immédiatement inférieure (UTC).
- geodezyx.gnss_edu.read_vmf1_grid.jd_to_calendar(jd: float) Tuple[int, int, int, float]
Convertit un Julian Day (float) en (year, month, day, hour_float). Implémentation autonome (remplace jdutil.jd_to_date).
- geodezyx.gnss_edu.read_vmf1_grid.mjd_to_datetime(mjd: float)
Conversion MJD -> datetime UTC naïf (sans tzinfo).
- geodezyx.gnss_edu.read_vmf1_grid.mjd_to_jd(mjd: float) float
- geodezyx.gnss_edu.read_vmf1_grid.read_vmf1_grid(mjd: Iterable[float], ell: Iterable[float]) Tuple[ndarray, ndarray]
Retourne (ah_vec, aw_vec) pour chaque MJD donné et une station ell=[lat_deg, lon_deg, h_m].
Paramètres
- mjdIterable[float]
Liste/array de dates en Modified Julian Day (UTC).
- ell[lat_deg, lon_deg, h_m]
Latitude (deg), Longitude (deg), Hauteur ellipsoïdale (m). (La hauteur n’est pas utilisée ici pour ah/aw, mais on garde la signature d’interface.)
Renvoie
ah_vec : np.ndarray shape (N,) aw_vec : np.ndarray shape (N,)
Notes
- Les fichiers requis sont:
./Mapping_Fcn/vmf1/VMFG_YYYYMMDD.H{00,06,12,18}
pour les 6h entourant chaque MJD.
Interpolation temporelle: linéaire entre t0=⌊MJD⌋_6h et t1=t0+6h.