Source code for hydrac.inversion.run_inversion_implicit

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Implicit scheme (:mod:`hydrac.inversion.run_inversion_attenuation`)
======================================================================

.. autoclass:: Run_inversion_implicit
   :members:
   :private-members:

"""

import numpy as np
from hydrac.util.parameters import Parameters
from hydrac.inversion.multifrequence.implicit_scheme_multi \
    import implicit_scheme_multi
from hydrac.inversion.monofrequence.implicit_scheme_mono \
    import implicit_scheme_mono


[docs]class Run_inversion_implicit(object): """Implicit inversion scheme class This class uses an implicit scheme as descibed in Hurther et al. 2011 ( doi:10.1016/j.coastaleng.2011.01.006). This inversion method can work for both singlefrequency and multifrequency observations. Specific methods are build to handle these cases : Single frequency inversion : :func:`elementary_inv_mono` inverts the calibrated intensity at one frequency and need supplementary information regarding the median size of the suspended particles to contrain the inversion. Multi frequency inversion : :func:`elementary_inv_multi` inverts a set of calibrated intensities measured for F frequencies. Parameters ---------- obj : Hydroacoustic object defined by :class:`hydrac.instruments.acoustique.Acoustic`. a0 : float Median size of particles, necessary for single frequency inversion. """ def __init__(self, obj, a0=None, **kwargs): self.obj = obj self.a0 = a0 self.kwargs = kwargs if self.obj.o_hac.tag_M == "multi": if self.a0 is None: self.obj.calc_inv(self.elementary_inv_multi, self.obj.o_hac.param) else: self.obj.calc_inv(self.elementary_inv_mono, self.obj.o_hac.param) else: print('good {}'.format(2555555)) self.obj.calc_inv(self.elementary_inv_mono, self.obj.o_hac.param)
[docs] def elementary_inv_multi(self, BX, model): """ Handles multifrequency data only. Computes the inversion of a single sample profile set of N observations. Parameters ---------- BX : Subset of the calibrated Intensity 3D - matrix for one sample, thus keeping the information relative to the range in order to correct for the potential effects of sediment scattering attenuation. Intensity (N x Ns x F) --> BX (N x F) model : paramcontainer of model presets computed by the package :mod:`hydrac.model`. Contains all the information relative to the particle physical properties, as well as scattering properties. """ a_mat = np.atleast_2d(np.zeros(np.shape(BX)[0:2])) zeta_mat = np.atleast_2d(np.zeros(np.shape(BX))) solution = np.atleast_2d(np.zeros(np.shape(BX)[0:2])) for uy in range(len(self.obj.o_hac.param)): try: len(np.unique(BX - self.obj.o_hac.param['P' + str(uy)].asv)) == 1 r = self.obj.o_hac.param['P' + str(uy)].BinRange[:, 0] except(ValueError): pass if self.obj.o_hac.instr_name == 'ub-mes': dr = r[1, 1:] - r[1, 0:-1] +\ (np.sqrt(self.obj.o_hac.do ** 2 + r[1, 1:] ** 2) - np.sqrt(self.obj.o_hac.do ** 2 + r[1, 0:-1] ** 2) ) else: dr = np.diff(r) if self.obj.o_hac.tag_M == 'mono': a_mat = np.unique(a_mat+self.a0) inv = Parameters({}) for i in range(np.size(BX, 1)): print(('sample number {}/{}'.format(i+1, np.size(BX, 1)))) if np.any(np.isnan(np.squeeze(BX[0, i, :]))): solution[:, i] = solution[:, i] + np.NaN a_mat[:, i] = a_mat[:, i] + np.NaN zeta_mat[:, i, :] = zeta_mat[:, i, :] + np.NaN else: # print('le soleil vient de se lever') [s_tmp, a_tmp, z_tmp] = implicit_scheme_multi( np.squeeze(np.squeeze(BX[:, i, :])), r, model, dr=dr) s_tmp[np.where(np.isinf(s_tmp))] = np.NaN z_tmp[np.where(np.isinf(z_tmp))] = np.NaN solution[:, i] = s_tmp a_mat[:, i] = a_tmp zeta_mat[:, i, :] = z_tmp.T inv.update({'conc': solution, 'a_mat': a_mat, 'zeta_mat': zeta_mat}) return inv
[docs] def elementary_inv_mono(self, BX, model): """ Handles singlefrequency data only. Computes the inversion of a single sample profile set of F observation for the F similar frequencies. Parameters ---------- BX : Subset of the calibrated Intensity 3D - matrix for one sample, thus keeping the information relative to the range in order to correct for the potential effects of sediment scattering attenuation. Intensity (N x Ns x F) --> BX (N x F) model : paramcontainer of model presets computed by the package :mod:`hydrac.model` """ a_mat = self.a0 zeta_mat = np.atleast_2d(np.zeros(np.shape(BX))) solution = np.atleast_2d(np.zeros(np.shape(BX))) for uy in range(len(self.obj.o_hac.param)): try: len(np.unique(BX - self.obj.o_hac.param['P' + str(uy)].asv)) == 1 r = self.obj.o_hac.param['P' + str(uy)].BinRange[:, 0] except: ValueError if self.obj.o_hac.instr_name == 'ub_mes': dr = r[1:] - r[0:-1] +\ (np.sqrt(self.obj.o_hac.d0 ** 2 + r[1:] ** 2) - np.sqrt(self.obj.o_hac.d0 ** 2 + r[0:-1] ** 2) ) else: dr = np.diff(r) inv = Parameters({}) for i in range(np.size(BX, 1)): print(('sample number {}/{}'.format(i+1, np.size(BX, 1)))) if np.any(np.isnan(np.squeeze(BX[0, i, :]))): solution[:, i, :] = solution[:, i, :] + np.NaN zeta_mat[:, i, :] = zeta_mat[:, i, :] + np.NaN else: [s_tmp, z_tmp] = implicit_scheme_mono(np.squeeze( np.squeeze(BX[:, i, :])), self.a0, r, model, dr=dr) solution[:, i, :] = s_tmp zeta_mat[:, i, :] = z_tmp inv.update({'conc': solution, 'a_mat': a_mat, 'zeta_mat': zeta_mat}) return inv