-
Notifications
You must be signed in to change notification settings - Fork 0
/
waveform_models.py
executable file
·102 lines (80 loc) · 3.71 KB
/
waveform_models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# -*- coding: utf-8 -*-
"""
Created on Mon May 29 2023
@author: ardhuin
"""
"""waveform_models.py: A Python module for LRM waveform models
"""
#================================================================
# Imports
#----------------------------------------------------------------
import numpy as np
import scipy
from scipy import special
###################### Defines waveform theoretical models: brown from WHALES code, includes PTR convolution
def wf_brown_eval(xdata,incognita,noise,Gamma,Zeta,c_xi,PTR) :
'''
Define a waveform as in the WHALES code.
Based on a Brown model.
inputs :
- xdata : range gates
- incognita : (3,) vector with [0] = epoch, [1] = Hs, [2] = amplitude
- noise : thermal noise
- Gamma : coeff with antenna bandwidth (gamma in Tourain et al. 2020)
- Zeta : off nadir pointing angle (= mispointing)
- c_xi : 4 c /(G * h) (with G = Gamma in Tourain et al. 2020)
- PTR : optionnal PTR
output : - waveform
'''
ff0=noise+( incognita[2]/2*np.exp((-4/Gamma)*(np.sin(Zeta))**2) \
* np.exp (- c_xi*( (xdata-incognita[0])-c_xi*incognita[1]**2/2) ) \
* ( 1+scipy.special.erf( ((xdata-incognita[0])-c_xi*incognita[1]**2)/((np.sqrt(2)*incognita[1])) ) ) \
)
if PTR[0] < 1:
fff =fftconvolve(ff0,PTR,mode='same')
else:
fff=ff0
return fff
###################### Cost functions for retracking ... should use function above.
def waveform_brown_LS(incognita,data) :
"""
returns the least-square distance between the waveform data[0] and the theoretical
Brown-Hayne functional form, The unknown parameters in this version (17 Dec 2013) are Epoch, Sigma and Amplitude, where
sigma=( sqrt( (incognita(2)/(2*0.3)) ^2+SigmaP^2) ) is the rising time of the leading edge
For the explanation of the terms in the equation, please check "Coastal Altimetry" Book
"""
ydata =data[0] #Waveform coefficients
Gamma =data[1]
Zeta =data[2]
xdata =data[3] #Epoch
SigmaP=data[4]
c_xi =data[5] #Term related to the slope of the trailing edge
weights=data[6] #Weights to apply to the residuals
#print('YOWF',incognita,'##',xdata[0:2],Gamma,Zeta,c_xi)
fff = ( incognita[2]/2*np.exp((-4/Gamma)*(np.sin(Zeta))**2) \
* np.exp (- c_xi*( (xdata-incognita[0])-c_xi*incognita[1]**2/2) ) \
* ( 1+scipy.special.erf( ((xdata-incognita[0])-c_xi*incognita[1]**2)/((np.sqrt(2)*incognita[1])) ) ) \
)
cy= ( weights * ((ydata - fff) **2)).sum()
return cy
def waveform_brown_ML(incognita,data) :
"""
returns the ML distance between the waveform data[0] and the theoretical
Brown-Hayne functional form, The unknown parameters in this version (17 Dec 2013) are Epoch, Sigma and Amplitude, where
sigma=( sqrt( (incognita(2)/(2*0.3)) ^2+SigmaP^2) ) is the rising time of the leading edge
For the explanation of the terms in the equation, please check "Coastal Altimetry" Book
"""
ydata =data[0] #Waveform coefficients
Gamma =data[1]
Zeta =data[2]
xdata =data[3] #Epoch
SigmaP=data[4]
c_xi =data[5] #Term related to the slope of the trailing edge
weights=data[6] #Weights to apply to the residuals
fff = ( incognita[2]/2*np.exp((-4/Gamma)*(np.sin(Zeta))**2) \
* np.exp (- c_xi*( (xdata-incognita[0])-c_xi*incognita[1]**2/2) ) \
* ( 1+scipy.special.erf( ((xdata-incognita[0])-c_xi*incognita[1]**2)/((np.sqrt(2)*incognita[1])) ) ) \
)
ratio = np.divide(ydata+1.e-5,fff+1.e-5)
cy= ( ratio - np.log(ratio)-1.).sum()
return cy