Meteor showers are one of the most accessible astronomical events for both amateurs and researchers. With today's inexpensive cameras, low‑cost radio receivers, and a wealth of open‑source tools, you can turn a backyard night‑sky session into a scientifically useful dataset. This guide walks you through the entire workflow---from planning and data capture to processing, analysis, and sharing your results---using only free software.
Planning Your Observation Session
1.1 Choose a Target Shower
Check the International Meteor Organization (IMO) calendar for the peak dates of major showers (e.g., Perseids, Geminids, Leonids). Note the radiant's right ascension (RA) and declination (Dec) so you can point your equipment correctly.
1.2 Estimate Observing Conditions
- Moon phase: A dark sky (new moon ± 3 days) maximizes faint meteors.
- Weather : Use a free forecast service like Meteoblue or open‑source weather-cli (
wttr.in) from the terminal. - Light pollution : Retrieve the Bortle scale rating for your location with the Light Pollution Map API (open‑source).
1.3 Build a Simple Observation Log
Create a plain‑text log (Markdown works great) to note:
# Observation Log -- Perseids 2025
- Date: 2025-08-12
- Site: 34.0522°N, 118.2437°W (https://www.amazon.com/s?k=Los+Angeles&tag=organizationtip101-20)
- Start/End: 22:30--04:00 local
- Moon: 0% (new)
- https://www.amazon.com/s?k=cloud&tag=organizationtip101-20 cover: 20% scattered
- https://www.amazon.com/s?k=equipment&tag=organizationtip101-20: https://www.amazon.com/s?k=Sony&tag=organizationtip101-20 A6000 + 16 mm f/2.8 https://www.amazon.com/s?k=lens&tag=organizationtip101-20, https://www.amazon.com/s?k=Raspberry+Pi&tag=organizationtip101-20 5 + SDR https://www.amazon.com/s?k=dongle&tag=organizationtip101-20 (https://www.amazon.com/s?k=radio&tag=organizationtip101-20)
- https://www.amazon.com/s?k=notes&tag=organizationtip101-20: Strong activity around 02:10 UT.
Capturing Meteor Data
Open‑source software can handle three popular observation modalities:
| Modality | Hardware | Open‑Source Capture Software |
|---|---|---|
| Visual (naked eye) | Stopwatch, notebook | MetRec (simple CLI timer) |
| Video (optical) | DSLR / mirrorless, webcam, low‑light cam | RMS (Rural Meteor Network) , UFO Capture (GPL) |
| Radio (forward scatter) | SDR dongle (RTL‑2832U), antenna | Radio Meteor Scatter (RMS) , GNU Radio |
2.1 Video Capture with RMS
-
Install RMS (Ubuntu/Debian example):
sudo https://www.amazon.com/s?k=APT&tag=organizationtip101-20-get update sudo https://www.amazon.com/s?k=APT&tag=organizationtip101-20-get https://www.amazon.com/s?k=Install&tag=organizationtip101-20 rms -
Configure a camera (e.g., a USB webcam):
rmsconfig # Follow https://www.amazon.com/s?k=prompts&tag=organizationtip101-20: select video https://www.amazon.com/s?k=device&tag=organizationtip101-20, set resolution (1280x720), fps (30), and output https://www.amazon.com/s?k=folder&tag=organizationtip101-20. -
Start recording (RMS runs in the background and slices each meteor into a separate AVI file):
rmscapture &
The software automatically timestamps frames using the system clock (ensure NTP is active).
2.2 Radio Capture with GNU Radio
-
Install GNU Radio (cross‑platform):
# On https://www.amazon.com/s?k=macOS&tag=organizationtip101-20 with Homebrew brew https://www.amazon.com/s?k=Install&tag=organizationtip101-20 gnuradio `` # On https://www.amazon.com/s?k=Linux&tag=organizationtip101-20 sudo https://www.amazon.com/s?k=APT&tag=organizationtip101-20-get https://www.amazon.com/s?k=Install&tag=organizationtip101-20 gnuradio -
Create a simple flowgraph (
meteor_radio.grc) that:- Tunes the SDR to a known forward‑scatter frequency (e.g., 137 MHz).
- Applies a band‑pass filter (± 5 kHz).
- Detects rapid amplitude spikes (meteor echoes).
- Writes timestamps and signal strength to a CSV file.
A minimal Python block for spike detection:
import https://www.amazon.com/s?k=NumPy&tag=organizationtip101-20 as np def detect_spikes(https://www.amazon.com/s?k=samples&tag=organizationtip101-20, https://www.amazon.com/s?k=threshold&tag=organizationtip101-20=5): power = np.abs(https://www.amazon.com/s?k=samples&tag=organizationtip101-20)**2 https://www.amazon.com/s?k=spikes&tag=organizationtip101-20 = np.where(power > https://www.amazon.com/s?k=threshold&tag=organizationtip101-20 * np.mean(power))[0] return https://www.amazon.com/s?k=spikes&tag=organizationtip101-20 -
Run the flowgraph and let it log to
radio_log.csv.
2.3 Visual Counts (Backup)
Even if you rely on video/radio, keep a basic visual count as a sanity check. Use the MetRec command‐line timer:
metrec start # starts timer
# shout "one" whenever you see a meteor
metrec stop # stops timer
The resulting metrec.log contains timestamps you can later merge with video/radio data.
Processing Raw Data
3.1 Organize Files
Create a project directory structure:
meteor_shower/
├─ https://www.amazon.com/s?k=logs&tag=organizationtip101-20/
│ ├─ visual.log
│ └─ radio_log.https://www.amazon.com/s?k=CSV&tag=organizationtip101-20
├─ video/
│ ├─ https://www.amazon.com/s?k=RAW&tag=organizationtip101-20/
│ └─ processed/
└─ analysis/
3.2 Extract Meteors from Video
RMS ships a meteor detector script (rmsdetect). Run it on the raw folder:
rmsdetect -i video/https://www.amazon.com/s?k=RAW&tag=organizationtip101-20 -o video/processed --https://www.amazon.com/s?k=CSV&tag=organizationtip101-20 meteors.https://www.amazon.com/s?k=CSV&tag=organizationtip101-20
The generated meteors.csv contains:
| ID | Start (UTC) | End (UTC) | Duration (s) | Peak Brightness (mag) | RA (°) | Dec (°) |
|---|
3.3 Clean and Merge Datasets (Python)
import https://www.amazon.com/s?k=Pandas&tag=organizationtip101-20 as pd
from pathlib import Path
# Load each source
video_df = pd.read_csv('video/processed/meteors.https://www.amazon.com/s?k=CSV&tag=organizationtip101-20')
radio_df = pd.read_csv('https://www.amazon.com/s?k=logs&tag=organizationtip101-20/radio_log.https://www.amazon.com/s?k=CSV&tag=organizationtip101-20')
visual_df = pd.read_csv('https://www.amazon.com/s?k=logs&tag=organizationtip101-20/visual.log', delim_whitespace=True, https://www.amazon.com/s?k=names&tag=organizationtip101-20=['timestamp'])
# Convert timestamps to datetime
video_df['start'] = pd.to_datetime(video_df['Start (UTC)'])
radio_df['time'] = pd.to_datetime(radio_df['timestamp'])
# Example merge: find video meteors within ±2 s of a https://www.amazon.com/s?k=radio&tag=organizationtip101-20 https://www.amazon.com/s?k=Echo&tag=organizationtip101-20
merged = pd.merge_asof(
video_df.sort_values('start'),
radio_df.sort_values('time'),
left_on='start',
right_on='time',
direction='nearest',
tolerance=pd.Timedelta('2s')
)
# Drop rows without a https://www.amazon.com/s?k=match&tag=organizationtip101-20 (pure visual only)
merged = merged.dropna(subset=['time'])
merged.to_csv('analysis/combined.https://www.amazon.com/s?k=CSV&tag=organizationtip101-20', https://www.amazon.com/s?k=index&tag=organizationtip101-20=False)
3.4 Calibrate Radiant Position
If you recorded the camera's orientation (azimuth, altitude) and used AstroPy to convert pixel coordinates to celestial coordinates, you can refine the RA/Dec values. A quick example:
from astropy.coordinates import SkyCoord, AltAz, EarthLocation
from astropy import units as u
from astropy.time import Time
loc = EarthLocation(lat=34.0522*u.deg, lon=-118.2437*u.deg, height=100*u.m)
obs_time = Time(merged['start'].iloc[0])
# Assume pixel->alt/az conversion factors are known:
alt = merged['pixel_alt'].iloc[0] * u.deg
az = merged['pixel_az'].iloc[0] * u.deg
altaz = AltAz(location=loc, obstime=obs_time, pressure=0*u.hPa)
coord = SkyCoord(alt=alt, az=az, https://www.amazon.com/s?k=frame&tag=organizationtip101-20=altaz).transform_to('icrs')
print(coord.ra.deg, coord.dec.deg)
Analyzing the Shower
4.1 Activity Curve (ZHR)
ZHR (Zenithal Hourly Rate) standardizes counts to a clear, dark sky with the radiant overhead. Use the classic formula:
[ ZHR = \frac{T_{\text}} \cdot \frac{r^{(6.5 - m)}}{\sin h} ]
where:
- (N) = number of meteors observed.
- (T_{\text}) = effective observing time (hours, corrected for cloud gaps).
- (r) = population index (typically 2.0--2.5 for Perseids).
- (m) = limiting magnitude of your site.
- (h) = altitude of the radiant.
A quick Python implementation:
import https://www.amazon.com/s?k=NumPy&tag=organizationtip101-20 as np
def zhr(N, T_eff, r, m_lim, h_deg):
sin_h = np.sin(np.radians(h_deg))
return (N / T_eff) * (r ** (6.5 - m_lim)) / sin_h
# Example values for a one‑hour https://www.amazon.com/s?k=bin&tag=organizationtip101-20
N = 45
T_eff = 0.95 # 5 % https://www.amazon.com/s?k=cloud&tag=organizationtip101-20 https://www.amazon.com/s?k=loss&tag=organizationtip101-20
r = 2.2
m_lim = 5.0 # typical suburban sky
h_deg = 55.0
print(f'ZHR ≈ {zhr(N, T_eff, r, m_lim, h_deg):.1f}')
Plot ZHR versus UT using Matplotlib:
import https://www.amazon.com/s?k=Matplotlib&tag=organizationtip101-20.pyplot as plt
df = merged.resample('1H', on='start').size().reset_index(name='count')
df['zhr'] = zhr(df['count'], 1.0, 2.2, 5.0, 55) # constant T_eff, r, etc.
plt.figure(figsize=(8,4))
plt.plot(df['start'], df['zhr'], https://www.amazon.com/s?k=marker&tag=organizationtip101-20='o')
plt.title('Perseids 2025 -- Estimated ZHR')
plt.xlabel('UTC')
plt.ylabel('ZHR')
plt.https://www.amazon.com/s?k=grid&tag=organizationtip101-20(True)
plt.tight_layout()
plt.savefig('analysis/zhr_curve.https://www.amazon.com/s?k=PNG&tag=organizationtip101-20')
4.2 Radiant Drift
Even within a single night the radiant drifts due to Earth's rotation. Fit a linear trend to RA/Dec vs. time:
from scipy.stats import linregress
ra_fit = linregress(df['start'].astype(np.int64), df['RA'])
dec_fit = linregress(df['start'].astype(np.int64), df['Dec'])
print(f'RA https://www.amazon.com/s?k=Drift&tag=organizationtip101-20: {ra_fit.slope*86400:.3f} deg/day')
print(f'Dec https://www.amazon.com/s?k=Drift&tag=organizationtip101-20: {dec_fit.slope*86400:.3f} deg/day')
Visualize drift:
plt.figure(figsize=(6,6))
plt.scatter(df['RA'], df['Dec'], c=df['start'].astype(int), cmap='viridis')
plt.xlabel('RA [°]')
plt.ylabel('Dec [°]')
plt.title('Radiant https://www.amazon.com/s?k=Drift&tag=organizationtip101-20 During Observation')
plt.colorbar(https://www.amazon.com/s?k=Label&tag=organizationtip101-20='UTC (timestamp)')
plt.show()
4.3 Correlating Radio Echoes & Optical Events
A key advantage of open‑source data fusion is checking whether a radio spike corresponds to a visual meteor. Use the merged dataframe:
coincident = merged[abs(merged['start'] - merged['time']) <= pd.Timedelta('2s')]
print(f'Coincident https://www.amazon.com/s?k=events&tag=organizationtip101-20: {len(coincident)} / {len(merged)}')
A high coincidence fraction (> 60 %) suggests robust forward‑scatter detection for future unattended stations.
Sharing and Archiving
-
Metadata -- Follow the IAU Meteor Data Standard (MDS) format. Include: observer name, location (lat/lon/elev), equipment details, limiting magnitude, and population index.
-
Git‑based Repository -- Create a public repo (GitHub/Gitea) with a
README.mdthat reproduces the analysis. Example directory layout:meteor_shower/ ├─ data/ # https://www.amazon.com/s?k=RAW&tag=organizationtip101-20 video, https://www.amazon.com/s?k=radio&tag=organizationtip101-20 https://www.amazon.com/s?k=CSV&tag=organizationtip101-20 (or links to large https://www.amazon.com/s?k=files&tag=organizationtip101-20) ├─ analysis/ # https://www.amazon.com/s?k=Jupyter+notebooks&tag=organizationtip101-20, https://www.amazon.com/s?k=CSV&tag=organizationtip101-20 results, plots ├─ https://www.amazon.com/s?k=Scripts&tag=organizationtip101-20/ # https://www.amazon.com/s?k=Python&tag=organizationtip101-20 https://www.amazon.com/s?k=utilities&tag=organizationtip101-20 (extract, calibrate, plot) └─ README.md -
DOI via Zenodo -- Archive the repository with Zenodo's GitHub integration to obtain a citable DOI.
-
Submit to IMO -- Upload the final CSV (MDS format) to the International Meteor Organization's database.
Tips & Tricks
| Issue | Open‑Source Remedy |
|---|---|
| Clock drift | Run chrony or ntpdate before every session. |
| Camera overheating | Use ffmpeg‑based temperature monitoring (ffprobe -show_streams). |
| False radio spikes | Apply a median‑filter in GNU Radio and set a dynamic threshold (threshold= 4 * σ). |
| Light‑pollution correction | Use the Sky Quality Meter CLI (skymeter) to log SQM values. |
| Batch processing | Write a Bash loop to call rmsdetect on each night's folder; combine with parallel. |
Closing Thoughts
The barrier to meaningful meteor‑shower research has dropped dramatically. By leveraging open‑source video capture (RMS), radio analysis (GNU Radio), and a Python data stack (pandas, AstroPy, Matplotlib, SciPy), you can produce results that stand shoulder‑to‑shoulder with professional observatories.
Beyond the personal satisfaction of watching streaks across the night sky, every well‑documented meteor adds a data point that refines our models of cometary debris streams and helps predict future shower intensities. So set up that low‑light camera, fire up the SDR, and let the cosmos write its story---then share it openly for all to explore.
Happy observing! 🚀✨