Onze werkgroep heet iedereen welkom die belangstelling heeft voor astronomische of atmosferische waarnemingen op radiogolflengten.

U bent hier

Meteoren tellen met SpectrumLab

Automated counting of meteors

Prerequisites: use of SpectrumLab and Colorgramme Lab

Manually counting meteors is very reliable but very time intensive as loads of data need to be scanned. I therefore developed a script to automatically count meteors.

Meteors appear in the image in all sorts of shapes and colours. Meteors are usually displayed as vertical lines in the image, a few Hz wide, lasting seconds to minutes.However meteors are not the only items that are detected by the radio setup. The signal is polluted with noise, alien signals such as lightning and aircraft. Aircraft are a real nuisance and will cause a lot of false counts when no countermeasures are taken. Every hour, a line is written to a file that is published to the internet using Colorlab.

The basic idea behind counting meteors simple: as you can see a meteor is usually wider in frequency then an airplane. To obtain an accurate count, all reflections that are wider then an aircraft signal should be counted, keeping into mind that a single reflection can last a few seconds.

Of course every script has it flaws. When two aircraft reflections merge, the script will, due to the signal width assume a meteor was picked up. When large meteors appear, sometimes the meteors will be double counted. Despite these pitfalls, the script provides relatively accurate counts and saves countless of hours of manual labour.

Script:

To install import into Conditional Actions in SpectrumLab. Change the parameters as desired. This might take some experiments to figure out the best settings.

; Exported "Conditional Actions" for Spectrum Lab
if( initialising ) then lower=350:upper=1300:ignore=2:band=8:t=12:t1=6:t2=8
if( initialising ) then h_h=0:I=0:J_h=0:Ln=0:Ln1=0:Ln2=0:count_h=0:b_h=0:a=0:c1=0:c2=0:c3=0
if( initialising ) then h_10m=0:count_10m=0:b_10m=0:J_10m=0
if( initialising ) then c_peak=0:c_freq=0:c_noise=0:c_peak1=0:c_peak2=0
if( initialising ) then u_peak=0:u_freq=0:u_peak1=0:u_peak2=0
if( initialising ) then l_peak=0:l_freq=0:l_peak1=0:l_peak2=0
if( 1 ) then c_peak=peak_a(lower,upper):c_freq=peak_f(lower,upper):c_noise=noise(lower,upper)
if( 1 ) then c_peak1=avrg(c_freq-ignore-band,c_freq-ignore):c_peak2=avrg(c_freq+ignore,c_freq+ignore+band)
if( 1 ) then u_peak=peak_a(c_freq+5,upper):u_freq=peak_f(c_freq+5,upper)
if( 1 ) then u_peak1=avrg(u_freq-ignore-band,u_freq-ignore):u_peak2=avrg(u_freq+ignore,u_freq+band+ignore)
if( 1 ) then l_peak=peak_a(lower,c_freq-5):l_freq=peak_f(lower,c_freq-5)
if( 1 ) then l_peak1=avrg(l_freq-ignore-band,l_freq-ignore):l_peak2=avrg(l_freq+ignore,l_freq+band+ignore)
if( 1 ) then h_h=str("mmss",now):h_10m=str("ss",now):I=str("YYYYMMDDhh",now):J_h=str("hh",now):J_10m=str("hhmm",now):Ln=c_noise+t:Ln1=c_noise+t1:Ln2=c_noise+t2
if( ((c_peak>Ln)&(c_peak1>Ln1)&(c_peak2>Ln2)) ) then c1=1
if( ((u_peak>Ln)&(u_peak1>Ln1)&(u_peak2>Ln2)) ) then c2=1
if( ((l_peak>Ln)&(l_peak1>Ln1)&(l_peak2>Ln2)) ) then c3=1
if( (c1>0)||(c2>0)||(c3>0) ) then timer1.restart(0.5):c1=0:c2=0:c3=0
if( timer1.expired(1) ) then count_h=count_h+1:count_10m=count_10m+1:sp.print("----->",count_h)
if( (val(h_h,"####")==5955)&(b_h==0) ) then fopen1("c:\\Meteor\\RMOB\\RMOB-"+str("YYYYMM",now)+".dat",a):fp1(I,",",J_h,",",count_h):fclose1:sp.print("Last hour = ",count_h):count_h=0:b_h=b_h+1
if( (val(h_h,"####")==0001) ) then b_h=0
if( (val(h_10m,"####")==59)&(b_10m==0) ) then fopen1("c:\\Meteor\\RMOB\\RMOB10m-"+str("YYYYMM",now)+".dat",a):fp1(I,",",J_10m,",",count_10m):fclose1:sp.print("-> ",count_10m):count_10m=0:b_10m=b_10m+1
if( (val(h_10m,"####")==01) ) then b_10m=0

Script Documentation

if( initialising ) then lower=450:upper=1300:ignore=2:band=8:t=12:t1=6:t2=8 
Frequency : only at initialisation
Purpose: Initialize general variables specific for a certain receiver/antenna. These variables are to be tuned for every installation. The lower and higher variables define the range in which the script will scan.
lower: lower range in Hz
higher: higher range in Hz
ignore: The ignore parameter basically determines the with of the signal ignored. An airplane is represented as a line only a few Hz wide. This value should be about the thickness of an airplane trail. (in Hz)
band: the band being used to measure the signal above or below the central line (in Hz)
t: noise offset central part signal
t1: noise offset lower part signal
t2: noise offset upper part signal

if( initialising ) then h_h=0:I=0:J_h=0:Ln=0:Ln1=0:Ln2=0:count_h=0:b_h=0:a=0:c1=0:c2=0:c3=0
if( initialising ) then h_10m=0:count_10m=0:b_10m=0:J_10m=0
if( initialising ) then c_peak=0:c_freq=0:c_noise=0:c_peak1=0:c_peak2=0
if( initialising ) then u_peak=0:u_freq=0:u_peak1=0:u_peak2=0
if( initialising ) then l_peak=0:l_freq=0:l_peak1=0:l_peak2=0 

Frequency : only at initialisation
Purpose: Initialize general variables specific to the script

if( 1 ) then c_peak=peak_a(lower,upper):c_freq=peak_f(lower,upper):c_noise=noise(lower,upper) 
Frequency : always
Purpose: return maximum amplitude, frequency and noise level.
peak_a(lower,upper):returns the amplitude of the highest peak in the signal between the lower and upper band
peak_f(lower,upper):returns the frequency of the highest peak between the lower and upper band
noise(lower,upper): returns the noise level between the lower and upper band

if( 1 ) then c_peak1=avrg(c_freq-ignore-band,c_freq-ignore):c_peak2=avrg(c_freq+ignore,c_freq+ignore+band) 
Frequency : always
Purpose: determine the signal levels just above and below the central peak.

avrg(c_freq-ignore-band,c_freq-ignore): Calculate the average signal between the first peak in the signal and the lower band, taking into account a small section that is ignored. This prevents airplanes being counted.
avrg(c_freq+ignore,c_freq+ignore+band): do the same for the upper band of the first peak in the signal
if( 1 ) then u_peak=peak_a(c_freq+5,upper):u_freq=peak_f(c_freq+5,upper) 

Frequency : always
Purpose: determine the second highest peak in the signal, in the part between the upper limit and the central frequency

peak_a(c_freq+5,upper): get the second highest peak amplitude
peak_f(c_freq+5,upper): get the second highest peak frequency
if( 1 ) then u_peak1=avrg(u_freq-ignore-band,u_freq-ignore):u_peak2=avrg(u_freq+ignore,u_freq+band+ignore) 

Frequency : always
Purpose: determine the signal levels just above and below the second peak

avrg(u_freq-ignore-band,u_freq-ignore): Calculate the average signal between the second peak in the signal and the lower band, taking into account a small section that is ignored. This prevents airplanes being counted.
avrg(u_freq+ignore,u_freq+band+ignore): do the same for the upper band of the second peak in the signal
if( 1 ) then l_peak=peak_a(lower,c_freq-5):l_freq=peak_f(lower,c_freq-5) 

Frequency : always
Purpose: determine the third highest peak in the signal, in the part between the central peak in the signal and the lower limit

if( 1 ) then l_peak1=avrg(l_freq-ignore-band,l_freq-ignore):l_peak2=avrg(l_freq+ignore,l_freq+band+ignore) 
Frequency : always
Purpose: determine the signal levels just above and below the second peak

avrg(l_freq-ignore-band,l_freq-ignore): calculate the average signal between the second peak and the lower band.
avrg(l_freq+ignore,l_freq+band+ignore): do the same for the upper band of the second peak
if( 1 ) then h_h=str("mmss",now):h_10m=str("ss",now):I=str("YYYYMMDDhh",now):J_h=str("hh",now):J_10m=str("hhmm",now):Ln=c_noise+t:Ln1=c_noise+t1:Ln2=c_noise+t2

Frequency : always
Purpose: set variables for time and noise levels

if( ((c_peak>Ln)&(c_peak1>Ln1)&(c_peak2>Ln2)) ) then c1=1 
Frequency : if we detect a meteor
Purpose: if the noise level is smaller then the signal at the central peak, a meteor is counted. In fact, the script will check a few Hz up and down the central peak to verify.

if( ((u_peak>Ln)&(u_peak1>Ln1)&(u_peak2>Ln2)) ) then c2=1 
Frequency : if we detect a meteor
Purpose: same for the second peak

if( ((l_peak>Ln)&(l_peak1>Ln1)&(l_peak2>Ln2)) ) then c3=1 
Frequency : if we detect a meteor
Purpose: same for the third peak

if( (c1>0)||(c2>0)||(c3>0) ) then timer1.restart(0.5):c1=0:c2=0:c3=0 
Frequency : if a meteor is counted
Purpose: if a meteor is counted, restart a timer

if( timer1.expired(1) ) then count_h=count_h+1:count_10m=count_10m+1:sp.print("----->",count_h) 
Frequency : if timer expires
Purpose: add 1 to the counters (both hourly and ten minutes) and print to the screen

if( (val(h_h,"####")==5955)&(b_h==0) ) then fopen1("c:\\Meteor\\RMOB\\RMOB-"+str("YYYYMM",now)+".dat",a):fp1(I,",",J_h,",",count_h):fclose1:sp.print("Last hour = ",count_h):count_h=0:b_h=b_h+1 
Frequency : every hour
Purpose: write a line to the file every hour

if( (val(h_h,"####")==0001) ) then b_h=0 
Frequency : every hour
Purpose: reset counter

if( (val(h_10m,"####")==59)&(b_10m==0) ) then fopen1("c:\\Meteor\\RMOB\\RMOB10m-"+str("YYYYMM",now)+".dat",a):fp1(I,",",J_10m,",",count_10m):fclose1:sp.print("-> ",count_10m):count_10m=0:b_10m=b_10m+1 
Frequency : every 10 minutes
Purpose: write a line to the file every hour

if( (val(h_10m,"####")==01) ) then b_10m=0 
Frequency : every 10 minutes
Purpose: reset counter

 

Reageer