Scientific Computing

Estimating Electron Number Density via WSPR

WSPR is used by radio amateurs and radio scientists to measure radio propagation from VLF to VHF. On the order of one million WSPR spots occur daily worldwide. Most of these measurements are at HF (2-30 MHz) frequencies. Here is a discussion of one possible science application of WSPR in an NVIS configuration.

The units used are MKS.

The fundamental wave modes explored by Tonks and Langmuir [1] in the 1920s are responsible for important behaviors observed in plasmas such as those present in Earth’s ionosphere. Key inflection points in behavior of externally excited waves traveling through a region of plasma are marked by the electron plasma frequency ω_pe or equivalently f_pe. Where f ≪ f_pe, waves will not pass through the plasma–they will be reflected. Where f ≫ f_pe, waves will pass through the plasma, with a detectable phase shift. This phase shift is exploited to compute total electron content (TEC) via GPS receivers in the 1-1.5 GHz range (and beacons at other frequencies), a key quantity used in tomography of ionospheric number density reconstruction.

The electron plasma frequency is:

ω_pe = (N_e e2 / (m_e ε_0))(1/2) [rad/s]

f_pe = ω_pe/(2𝜋) = 1/(2𝜋) (N_e e2 / (m_e ε_0))(1/2) [Hz]

If we consider measurements from networks of radio amateurs using programs such as WSPR, which records SNR vs. time for numerous frequencies and disparate stations with a two-minute cadence, we may generate dynamic maps of electron density at the midpoint of each single-hop path. For this study, we initially focus on NVIS stations to keep within a single ionospheric hop. For world-wide communications, 10-20 or so hops may be involved, and in general the ionosphere and lithosphere will be heterogeneous, increasing the difficulty of the estimation problem.

Estimation of electron number density in ionosphere F2 layer: An oft-cited approximation for the maximum number density in the F2 layer (NmF2) is given as:

f_c = 9 * (N_max)^(1/2) [Hz]

or

N_max = f_c2 / 81 [m(-3)]

This is an approximation for:

N_e = f_pe2 * (4𝜋2 m_e ε_0) / e^2

assuming you know the critical frequency from a frequency swept (chirp) measurement from a vertical ionosonde.

For a locally stratified and homogeneous ionosphere near the midpoint of an NVIS path, we might estimate electron density N_e at an NVIS path midpoint, with assumptions on the height of the refracting layer. Oblique incidence chirp ionospheric sounders have been known since 1964 and vertical incidence chirp ionospheric sounder since 1971 to be a highly power-efficient means of ionospheric characterization [2]. In the 1996, the benefits of adding time synchronization to remotely located oblique ionosondes was realized, giving absolute time delay, allowing virtual height to be estimated more accurately than with relative-only timing available from unsynchronized chirp transmitter and obliquely-located receivers. Chirp sounders in modern times have seen further benefit from addition of broadband phase modulation to the stepped-frequency chirp.

TEC and f_0F_2 related statistically: TEC and f_0F_2 have been related in a coarse sense as confirmed via observation [3] to be during nighttime hours:

TEC = 1.24 x 10^(-6) τ (f_0F_2)^2

where τ is slab thickness in meters, taken to be 230 x 10^3 in [3].

References:

[1] Tonks, L. and Langmuir, I. (1929). Oscillations in ionized gases. DOI: 10.1103/PhysRev.33.195. Physical Review 33:195-210.

[2] Barry, G. (1971). A Low-Power Vertical-Incidence Ionosonde. DOI: 10.1109/TGE.1971.271471. IEEE Transactions on Geoscience Electronics 9(2):86-89.

[3] Spalla P. and Ciraolo, L. (1994). TEC and f_0F_2 comparison. Annali Di Geofisica, 37(5):929-938.

NRL Plasma Forumulary

pgrep pkill fulltext process name search

Adding the -f option to pgrep and pkill searches the whole command line, instead of the default first 15 characters. This is useful for example with chromium-browser that actually lists in ps as /usr/lib/chromium-browser/chromium-browser–too long for pgrep and pkill default to find.

pgrep -f chromium

works, while

pgrep chromium

does not work with default settings.

Make this change persistent by adding these lines to ~/.bash_aliases

alias pgrep="pgrep -f"
alias pkill="pkill -f"

Examples for Chromium:

  • find running process by name: pgrep chromium returns the PID (integer).
  • SIGTERM running process by name: pkill chromium

Raspberry Pi camera RAW images with Python

The PiCamera Python module acquires RAW Bayer masked data from the color Raspberry Pi camera module. Getting raw Bayer images from the camera into 2592 x 1944 pixels for the V1 camera, 3280 x 2464 for the V2 camera requires a program as simple as:

import picamera
import picamera.array

with picamera.PiCamera() as cam:
    with picamera.array.PiBayerArray(cam) as stream:
        cam.capture(stream, 'jpeg', bayer=True)
        img = stream.array

Python code for Raspberry Pi camera Bayer non-demasked image

It takes several seconds to load and process the first image. Acquiring an image series is much faster.

References:

Control Dropbox from Linux Terminal

If a remote PC with the graphical Dropbox client isn’t syncing, it may be due to a reboot where the Dropbox dæmon didn’t restart because there was no remote login to the graphical desktop. Dropbox can be remotely restarted over SSH with the command

dropbox start

(no & needed)

More Dropbox Linux Terminal commands can be found here.

When starting Dropbox this way, the Dropbox dæmon will stop when logging out over SSH. Therefore, ensure that when issuing the command over SSH

dropbox status

the reply is

Up to date

before disconnecting from the remote PC SSH session.

Red Pitaya HF ionospheric radar

This procedure describes setting up a Red Pitaya with the PiRadar code.

Get the radar code:

git clone https://github.com/pavel-demin/red-pitaya-notes
git switch develop

Get the development build virtual machine

Compile & create the SD card image. A general example is from the LED Blinker, which of course must be modified to fit PiRadar.

image → SD card

Format a micro SD card to FAT32 (find the SD card device name from df – be sure you don’t overwrite your hard drive!). Let’s suppose you found your SD card at /dev/mmcblk0, then:

umount /dev/mmcblk0
mkdosfs -F 32 -n piradar /dev/mmcblk0

Unzip the PiRadar image you created to this SD card

mount /dev/mmcblk0 /mnt/piradar
unzip ecosystem-*-piradar.zip -d /mnt/piradar
umount /mnt/piradar

Boot the Red Pitaya with this SD card. Connect to Red Pitaya via Ethernet using SSH (login/password root/root) using Avahi

ssh root@redpitaya.local

or via serial port


Related: PiRadar HF ionospheric radar

Setup Red Pitaya for NMR pulsed transmission

Setup Red Pitaya NMR image: format a micro SD card to FAT32 (find the SD card device name from df – be sure you don’t overwrite your hard drive!). Let’s suppose you found your SD card at /dev/mmcblk0, then:

umount /dev/mmcblk0

mkdosfs -F 32 -n NMR /dev/mmcblk0

Unzip Pavel Demin SD Card image to this SD card

mount /dev/mmcblk0 /mnt/NMR

unzip ecosystem-*-pulsed-nmr.zip -d /mnt/NMR

umount /mnt/NMR

Boot the Red Pitaya with this SD card.

Connect to Red Pitaya via Ethernet using SSH (login/password root/root) using Avahi

ssh root@redpitaya.local

or via serial port


Setup laptop: get NMR code

cd ~
git clone https://github.com/pavel-demin/red-pitaya-notes

Run the NMR control program

cd red-pitaya-notes/projects/pulsed_nmr/client
python3 pulsed_nmr.py

You should see some perturbation (even if essentially zero amplitude) in the NMR trace plot.

  • If “start” button doesn’t change to “stop” when clicked, that can indicate that the Red Pitaya NMR dæmon is not running. Be sure you copied over the correct image to the SD card when you did the unzip step.

pulsed-nmr consumes about 8% CPU when generating a waveform and 5% CPU when idle.

Recompile server code: this is precompiled and running as a service in Pavel’s image. TODO: Does it take rewriting the image since the SD card filesystem is read-only?

apt install gcc-arm-linux-gnueabihf

arm-linux-gnueabihf-gcc -static -O3 -march=armv7-a -mcpu=cortex-a9 -mtune=cortex-a9 -mfpu=neon -mfloat-abi=hard server/pulsed-nmr.c -o pulsed-nmr -lm

Related: Red Pitaya GNURadio image setup

Install LibSVM in Matlab, GNU Octave and Python

Matlab and Octave are popular for machine learning prototypes due to their easier to learn (vs. R) interface. Python via scikit-learn is also a top choice for machine learning. Here’s how to install LibSVM for Matlab and GNU Octave.

Prereqs:

apt install make git g++

Compile LibSVM

git clone https://github.com/cjlin1/libsvm

cd libsvm

make

Creates executables svm-train svm-predict svm-scale. Compile the Matlab/Octave and Python modules, for which the API is similar.

Compile LibSVM Matlab/Octave module

cd libsvm/matlab

Open Matlab or Octave, and from that internal Terminal, type (this uses make.m)

make

which creates a few .mex files. See the matlab/README for examples of using LibSVM from Matlab and Octave.

Compile LibSVM Python module

cd libsvm/python

make

See the python/README for examples of using LibSVM from Python.