sidescanpy.analysis.tvg#
TVG analysis: backscatter-vs-range profiles and hardware-TVG detection.
The TVG fit is sidescanpy.analysis.fit_tvg_models() (in
sidescanpy.analysis.tvg_fit). The candidate classifier below,
fit_range_decay() and fit_tvg_curve() with
TVGCandidateFit and TVGCandidateFitResult, is
deprecated since 0.10 and will be removed in 0.12: it anchored every
model at one reference bin, compared one spreading coefficient at a time
and took its window from the nadir and usable-range analyses, which
often left it fitting the wrong stretch of range.
Profiles and comparisons:
backscatter_vs_range(),backscatter_vs_sample()— binned statistics (re-exported fromsidescanpy.processing.profiles).compare_before_after()— raw vs. TVG-corrected dB and the applied gain, side by side.bin_by_altitude()— split pings into equal-count altitude bins.
Detecting what TVG the data already carries:
fit_tvg_curve()— fit four single-term candidate loss models (flat,spreading_only,absorption_only,full_physics) to an observed loss-vs-range curve (TVGCandidateFitResult).fit_range_decay()— bin a dataset, fit the candidates and classify which terms hardware has already removed (RangeDecayResult).
Contents
Raw and TVG-corrected backscatter side by side, with ground range. |
|
Split pings into |
|
One candidate loss model fit against an observed loss-vs-range curve. |
|
All four candidate fits for one curve, plus the best by fixed-scale RMSE. |
|
Fit four candidate hardware-TVG models to a binned raw dB-vs-range curve. |
|
TVG-status classification from a range-decay fit. |
|
Classify which TVG terms |
- sidescanpy.analysis.tvg.compare_before_after(ds_raw, params=None)#
Raw and TVG-corrected backscatter side by side, with ground range.
- Parameters:
- ds_rawxr.Dataset
Uncorrected channel dataset (see
sidescanpy.processing.invert()).- paramsTVGParams, optional
Passed to
apply_tvg().
- Returns:
- xr.Dataset
ds_rawwith geometric ranges plusbackscatter_db_raw(linear → dB, no gain),backscatter_db_corrected(apply_tvgoutput) andtvg_gain_db(their difference).
- sidescanpy.analysis.tvg.bin_by_altitude(ds, n_bins=3, altitude_var='altitude_m')#
Split pings into
n_binsequal-count (quantile) altitude bins.Comparing a range profile across altitude bins separates geometry-dependent effects (e.g. grazing angle) from range-only ones.
- Returns:
- dict[str, xr.Dataset]
Keys
"altitude_{lo:.2f}_{hi:.2f}m"in increasing altitude. Pings with non-finite altitude are in no bin.
- class sidescanpy.analysis.tvg.TVGCandidateFit(name, params, scale, rmse_db, fixed_scale_rmse_db, r_ref_m, r_fit_max_m, n_bins_used, r_fit_min_m=None)#
Bases:
objectOne candidate loss model fit against an observed loss-vs-range curve.
scaleis the least-squares multiplier on the candidate’s model (near 1: the data decays like that model as written; near 0: that term is essentially absent) andrmse_dbits residual.fixed_scale_rmse_dbis the residual with the scale pinned to 1 — the literal physics model. Candidates are ranked by the fixed-scale value, because a free scale on one term can absorb unrelated range-dependent effects and win on RMSE alone. Forflat(model identically zero) both values are equal.Deprecated since version 0.10: Removed in 0.12; see
TVGModelFit.
- class sidescanpy.analysis.tvg.TVGCandidateFitResult(candidates, best, observed_range_m, observed_loss_db)#
Bases:
objectAll four candidate fits for one curve, plus the best by fixed-scale RMSE.
Deprecated since version 0.10: Removed in 0.12; see
TVGFitResult.
- sidescanpy.analysis.tvg.fit_tvg_curve(binned, *, spreading_loss_db=30.0, absorption_db_per_m, r_ref_m=None, r_fit_min_m=None, r_fit_max_m=None, min_count_for_r_ref=30, fit_fraction=0.6, r_ref_search_fraction=0.5, value_col='mean')#
Fit four candidate hardware-TVG models to a binned raw dB-vs-range curve.
Deprecated since version 0.10: Removed in 0.12. Use
fit_tvg_models(), which fits a free constant, compares 20/30/40 log R with and without absorption, and ends its window at the noise knee.Each candidate is a term (or both) of
tvg_gain_db()still present in the data:flat— neither term (hardware compensated both)spreading_only— onlyspreading_loss_db * log10(R)absorption_only— only2 * absorption_db_per_m * Rfull_physics— both (no hardware compensation)
The fitted quantity is
observed_loss(r) = value[r_ref] - value[r](absolute level is unknown). Each candidate gets one free scale, fitted independently: a joint two-term regression is poorly conditioned because the terms are nearly collinear over realistic range spans.- Parameters:
- binnedpd.DataFrame
backscatter_vs_range()output computed on uncorrected dB backscatter.- spreading_loss_dbfloat, default 30.0
Spreading coefficient of the
spreading_onlyandfull_physicscandidates (DEFAULT_SPREADING_LOSS_DB).- absorption_db_per_mfloat
Required; pass the survey’s own frequency-appropriate value.
- r_ref_mfloat, optional
Reference range. Default: the bin with the highest value among bins with
count >= min_count_for_r_refin the nearr_ref_search_fractionof the range span (falls back to all eligible bins). Not simply the nearest bin, which often reads low from ring-down/blanking; not the global max, which on flat data can land on a far-range noise bump.- r_fit_min_mfloat, optional
Near edge of the fit window. Default
r_ref_m(one-sided). Set it lower to fit both sides of the reference.- r_fit_max_mfloat, optional
Far edge of the fit window. Default
r_ref_m + fit_fraction * (max_range - r_ref_m).- min_count_for_r_refint, default 30
- fit_fractionfloat, default 0.6
- r_ref_search_fractionfloat, default 0.5
- value_col{“mean”, “median”}, default “mean”
Per-bin statistic to fit.
- Returns:
- TVGCandidateFitResult
- Raises:
- ValueError
If
binnedis empty, or no bin hascount >= min_count_for_r_ref.
- class sidescanpy.analysis.tvg.RangeDecayResult(tvg_status=None, freq_hz=None, db_reference=None, absorption_db_per_m=None, bin_width_m=None, bin_width_m_requested=None, exclude_first_n_bins=0, n_bins_excluded_after_bottom=0, r_ref_m=None, r_ref_m_override=None, r_fit_min_m=None, r_fit_min_m_override=None, r_fit_min_auto_margin_m=None, r_fit_min_auto_search_max_m=None, r_fit_min_auto_peak_edge_m=None, r_fit_max_m=None, n_bins_used=None, best_candidate=None, best_scale=None, best_rmse_db=None, best_free_fit_scale=None, best_free_fit_rmse_db=None, ambiguous_rel_tol=None, candidates=<factory>, range_var=None, channel=None, water_column_n_excluded=0, nadir_gap_n_excluded=0, reject_outliers=False, outlier_mad_k=None, outlier_n_rejected=0, fit_value_col=None, notes=<factory>, binned=None, fit=None)#
Bases:
TVG-status classification from a range-decay fit.
Deprecated since version 0.10: Removed in 0.12, with
fit_range_decay(); seeTVGFitResult.tvg_statusnames what hardware has already removed:"none","spreading_only","absorption_only","full", or"ambiguous"(winner not clearly ahead, or too little data).best_rmse_dbis the winner’s fixed-scale RMSE (the ranking criterion);best_free_fit_*are its free-scale values.r_ref_m_override/r_fit_min_m_overriderecord what was requested (e.g."auto");r_ref_m/r_fit_min_mwhat was used. Withr_fit_min_m="auto"resolved,r_fit_min_auto_search_max_mis the bound of the near-field peak search (bin centers up to it) andr_fit_min_auto_peak_edge_mthe peak bin’s far edge, so the resolved value isr_fit_min_auto_peak_edge_m + r_fit_min_auto_margin_mbefore any clamp tor_ref_m; it can lie past the search bound.fit(the fullTVGCandidateFitResult) is left out ofto_dict();candidatessummarizes it.
- sidescanpy.analysis.tvg.fit_range_decay(ds, value_var='backscatter_intensity', range_var='slant_range_m', *, already_db=False, db_reference_percentile=99.0, db_reference_value=None, freq_hz=None, bin_width_m=5.0, usable_range_m=None, min_bins=6, ambiguous_rel_tol=0.2, min_total_count=30, exclude_before_sample=None, exclude_first_n_bins=0, reject_outliers=False, outlier_mad_k=3.5, outlier_min_bin_count=5, fit_value_col='mean', r_ref_m=None, r_fit_min_m=None, r_fit_min_auto_margin_m=5.0, r_ref_search_fraction=0.5, r_ref_window_fraction=0.3333333333333333, channel=None, spreading_loss_db=30.0)#
Classify which TVG terms
value_varalready carries.Deprecated since version 0.10: Removed in 0.12. Use
fit_tvg_models()(andcheck_tvg()); its best model is the TVG to apply and itstvg_statusreplaces this one. This function anchors every model at one reference bin, compares one spreading coefficient at a time and needs its window from the caller, so its answers differ.Converts to dB, bins by
range_var, fits the fourfit_tvg_curve()candidates and maps the winner (lowest fixed-scale RMSE) to a TVG status. If the runner-up’s RMSE is withinambiguous_rel_tol(relative) of the winner’s, the status is"ambiguous".Water-column samples are always excluded via
ground_range_m’s NaN pattern (when present), independent ofrange_var.- Parameters:
- range_varstr, default “slant_range_m”
Range axis; slant range matches
apply_tvg’s gain model.- already_dbbool, default False
value_varis already dB; skip the conversion.- db_reference_percentilefloat, default 99.0
- db_reference_valuefloat, optional
Exact linear reference instead of the percentile (e.g.
1.0for “dB re 1”).- freq_hzfloat, optional
Default: the channel’s center frequency (
center_frequency_hz()); sets the absorption term.- bin_width_mfloat, default 5.0
Requested bin width; shrunk (never widened) so that
usable_range_mspans at leastmin_binsbins.- usable_range_mfloat, optional
Far edge of the fit window.
- min_binsint, default 6
- min_total_countint, default 30
Fewer binned samples than this →
"ambiguous"without a fit.- exclude_before_samplenp.ndarray, optional
(ping, channel)sample index; samples before it are dropped (in dB space) before binning. For aggregate fits pass a uniform boundary (uniform_exclusion_boundary()): a per-ping one biases the near-range bins and the reference pick.- exclude_first_n_binsint, default 0
Drop this many nearest bins after binning, before the reference pick and fit — for a bright leading-edge artifact at the bottom return.
- reject_outliersbool, default False
Run
reject_range_outliers()on the dB values first (outlier_mad_k,outlier_min_bin_count).- fit_value_col{“mean”, “median”}, default “mean”
Passed to
fit_tvg_curve()asvalue_col.- r_ref_mfloat, “auto”, “mid_swath” or None
Reference range.
None:fit_tvg_curve()’s near-field auto-pick."auto"(recommended withr_fit_min_m="auto"): placedr_ref_window_fractionof the way from the resolved fit window’s near edge tousable_range_m, so it always lies inside the window."mid_swath"(legacy):usable_range_m / 2. Both string modes fall back to the auto-pick, with a note, whenusable_range_mis unavailable.- r_fit_min_mfloat, “auto” or None
Near edge of the fit window (resolved before
r_ref_m).None: one-sided fromr_ref_m."auto": the raw near-field peak bin’s far edge plusr_fit_min_auto_margin_m, searched up to a numericr_ref_morr_ref_search_fraction * usable_range_m; falls back toNonewith a note when it can’t be resolved. Only the peak is searched for within that bound: the margin, added afterwards, can carry the value past it, and the result reports both (r_fit_min_auto_search_max_m,r_fit_min_auto_peak_edge_m). If it ends up beyond a numeric/”mid_swath”r_ref_mit is clamped to it.- r_fit_min_auto_margin_mfloat, default 5.0
- r_ref_search_fractionfloat, default 0.5
- r_ref_window_fractionfloat, default 1/3
- channelint or str, optional
Restrict to one physical side (index or
channel_idvalue).Nonepools both. Applied by masking.- spreading_loss_dbfloat, default 30.0
Spreading coefficient of the
spreading_onlyandfull_physicscandidates; pass the value the survey’s correction uses.