Skip to content

Detector

__init__(fs=128000, seg_ms=10.0, threshold=-10, freq_window=(0, 10000), bandwidth=1600, history=4)

Initializes a carrier detector, used to detect possible carriers in the received signal.

pageplot

Parameters:

Name Type Description Default
fs float

Sampling frequency [Hz]

128000
seg_ms float

Duration of each segment [ms]

10.0
threshold float

Power threshold for detection

-10
freq_window tuple[float, float]

Frequency interval (f_min, f_max). Frequencies outside this interval will be discarded.

(0, 10000)
bandwidth float

Bandwidth of span [Hz], used to ignore other frequencies that can be confirmed.

1600
history int

Number of previous segments to consider for carrier detection.

4

Raises:

Type Description
ValueError

If the sampling frequency is less than or equal to zero.

ValueError

If the segment duration is less than or equal to zero.

Examples:

>>> import argos3
>>> import numpy as np 
>>> 
>>> fc = np.random.randint(10,80)*100
>>> print(fc)
2400
>>>
>>> transmitter = argos3.Transmitter(fc=fc, output_print=False, output_plot=False)
>>> t, s = transmitter.transmit(argos3.Datagram(pcdnum=1234, numblocks=1))
>>> 
>>> channel = argos3.Channel(duration=1, noise_mode="ebn0", noise_db=20)
>>> channel.add_signal(s, position_factor=0.5)
>>> channel.add_noise()
>>> st = channel.channel
>>> 
>>> detector = argos3.CarrierDetector(seg_ms=10, threshold=-15)
>>> detector.detect(st.copy())
>>> detections = detector.return_channels()
>>>
>>> print(detections)
[(np.float64(2400.0), 41, 65)]
>>>                   
>>> first_sample = int((detections[0][1] - 5) * detector.fs * detector.seg_s)
>>> last_sample = int(detections[0][2] * detector.fs * detector.seg_s)
>>> st_prime = st[first_sample:last_sample]
>>> 
>>> receiver = argos3.Receiver(fc=detections[0][0], output_print=False, output_plot=False)
>>> datagramRX, success = receiver.receive(st_prime)
>>> 
>>> print(success)
True
>>> print(datagramRX.parse_datagram())
{
  "msglength": 1,
  "pcdid": 1234,
  "data": {
    "bloco_1": {
      "sensor_1": 37,
      "sensor_2": 198,
      "sensor_3": 9
    }
  },
  "tail": 7
}
  • Waterfall Diagram: pageplot
  • Frequency Domain Segment: pageplot
  • Waterfall Detection Diagram: pageplot
  • Waterfall Decision Diagram: pageplot
Reference:
AS3-SP-516-2097-CNES (Section 3.3)

segment_signal(signal)

Divides the received signal into segments of time \(x_n[m]\), each segment with seg_ms duration, according to the expression below.

\[ x_n[m] = s(t_{n} + mT_s) \]
Where
  • \(x_n[m]\) : Segment of time \(n\).
  • \(s(t)\) : Received signal.
  • \(T_s\) : Sampling period.
  • \(m\) : Segment number.
  • \(t_n\) : Start time of segment \(n\).

Parameters:

Name Type Description Default
signal ndarray

Received signal

required

Returns:

Type Description
list[ndarray]

list[np.ndarray]: List of time segments

analyze_signal(signal)

Calculates the FFT of each segment \(x_n[m]\), using the expression below.

\[ X_n[k] = \sum_{m=0}^{N-1} x_n[m]\, e^{-j2\pi km/N} \]
Where
  • \(X_n[k]\) : FFT of segment \(n\).
  • \(x_n[m]\) : Segment of time \(n\).
  • \(N\) : Number of samples in the segment.
  • \(k\) : Number of the Fourier transform.
  • \(m\) : Sample number.
  • \(T_s\) : Sampling period.
  • \(e^{-j2\pi km/N}\) : Complex exponential.

Then, calculates the power spectral density \(P_n[k]\) in \(dB\), and divides by the number of samples \(N\) contained in the segment for normalization.

\[ P_n[k] = \frac{|X_n[k]|^2}{N} \]
Where
  • \(P_n[k]\) : Power spectral density of segment \(n\), normalized in \(dB\).
  • \(X_n[k]\) : FFT of segment \(n\).
  • \(N\) : Number of samples in the segment.

Parameters:

Name Type Description Default
signal ndarray

Received signal

required

Returns:

Name Type Description
freqs tuple[ndarray, ndarray]

tuple with frequencies and power spectral density in \(dB\)

Examples:

  • Waterfall Diagram: pageplot
  • 3D Waterfall Diagram: pageplot

detect(signal)

Detects possible carriers in the signal, comparing \(P_n[k]\) with the threshold \(P_t\), for each index \(k\) of the FFT, as shown below.

\[ f_n[k] = \begin{cases} \dfrac{k}{N} \cdot f_s, & \text{if } P_n[k] > P_t\\ \text{not detected}, & \text{if } P_n[k] \leq P_t \end{cases} \]
Where
  • \(f_n[k]\) : Detected frequency in segment \(n\).
  • \(P_n[k]\) : Power spectral density of segment \(n\).
  • \(P_t\) : Power threshold.
  • \(N\) : Number of samples in the segment.
  • \(f_s\) : Sampling frequency.
  • \(k\) : Index of the FFT.
  • not detected: Frequency ignored in the detection process.

Parameters:

Name Type Description Default
signal ndarray

Received signal

required

Returns:

Name Type Description
results list[tuple[ndarray, list[float]]]

List of tuples with the segments and detected frequencies

Examples:

  • Waterfall Detection Diagram: pageplot

decision()

Returns only frequencies that were detected in two consecutive segments. The tolerance is given by the FFT spectral resolution, \(\Delta f\), according to the expression below.

\[ \Delta f = \dfrac{f_s}{N} \]
Where
  • \(\Delta f\) : FFT spectral resolution.
  • \(f_s\) : sampling frequency.
  • \(N\) : number of samples in the segment.

Parameters:

Name Type Description Default
signal ndarray

Received signal

required

Returns:

Name Type Description
confirmed_freqs list[float]

list of confirmed carrier frequencies

Examples:

  • Waterfall Decision Diagram: pageplot

return_channels()

Scans the decision_matrix and returns the confirmed frequencies. with the start and end segment where the carrier was demodulated.

Returns:

Name Type Description
channels list[tuple[float, int, int]]

List of tuples (freq_Hz, start_segment, end_segment)