File: disptrans.py

package info (click to toggle)
python-disptrans 0.0.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,564 kB
  • sloc: python: 165; sh: 6; makefile: 4
file content (81 lines) | stat: -rw-r--r-- 2,244 bytes parent folder | download
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
"""Dispersion-compensated algorithm for mapping dispersive waveguide data from
the frequency-domain to distance-domain, and vice versa."""

import numpy as np


def freq2distance(f, fresp, beta, x):
    """Transform a frequency-domain signal to the distance-domain.

    Compensates for dispersion.

    Args:
        f (np.ndarray): frequency for frequency-domain signal, in units [Hz]
        fresp (np.ndarray): frequency-domain signal
        beta (np.ndarray): phase constant, in units [rad/m]
        x (np.ndarray): distance array for output data, in units [m]

    Returns:
        np.ndarray: distance-domain response

    """

    # TODO: add default value for x

    fpts = len(f)  # number of frequency-domain points
    xpts = len(x)  # number of distance-domain points

    # Calculate distance-domain response, xresp
    # TODO: optimize
    xresp = np.zeros(xpts, dtype=np.complex128)
    for x_idx in range(xpts):
        xresp[x_idx] = np.sum(fresp * np.exp(1j * beta * x[x_idx]))

    # Normalize
    xresp /= fpts

    return xresp


def distance2freq(x, xresp, beta, f):
    """Transform a distance-domain signal to the frequency-domain.

    Compensates for dispersion.

    Args:
        x (np.ndarray): distance array for input data, in units [m]
        xresp (np.ndarray): distance-domain response
        beta (np.ndarray): phase constant, in units [rad/m]
        f (np.ndarray): frequency for frequency-domain response, in units [Hz]

    Returns:
        np.ndarray: frequency-domain response

    """

    # TODO: add default value for f

    def _delta(xx):
        """Calculate derivative of xx."""
        result = np.zeros_like(xx)
        result[1:-1] = xx[2:] - xx[:-2]
        result[0] = result[1]
        result[-1] = result[-2]
        return result / 2

    fpts = len(f)  # number of frequency-domain points
    xstep = x[1] - x[0]  # distance-domain step size

    # Calculate frequency-domain response, fresp
    # TODO: optimize
    fresp = np.zeros(fpts, dtype=np.complex128)
    for f_idx in range(fpts):
        fresp[f_idx] = np.sum(xresp * np.exp(-1j * beta[f_idx] * x))

    # Group velocity
    vg = _delta(beta)

    # Normalize
    fresp *= fpts * xstep * vg / 2 / np.pi

    return fresp