Quickstart
Here are presented the main steps to use this library. This is intended for researchers who have a VLF antenna, and who aim to have a real-time estimate of the electron density of the D-region. This can however also be useful to researchers aiming to analyse VLF data in post-processing. An example script may be found on the Codeberg folder, showing the structure of the main command script. This can be tailored to the needs of each user.
Note
In the following, it is assumed that the antenna is an AWESOME antenna. This has mainly one implication, on the naming convention of the data files. If the antenna has a different naming convention, please refer to the section Reading files
The start of the running script should be as follows:
import schedule
import time # Only needed here so that the script keeps running
from vlf4ions.class_definition import *
from vlf4ions.forecast_nowcast import nowcast
Defining the receiver
The first step is to define the receiver in use. For the antenna in Nançay, this is done by:
Nancay = receiver('NC', lat = 47.3755933, lon = 2.1944333)
In this example, we define a receiver called Nancay , giving lat/lon, the latitude and longitude of the receiver. This is only useful for plotting purposes. We also precise 'NC' , which will be the name of the receiver appearing in the email alerts.
Defining the transmitter
Note
In this documentation, we will use transmitter and station interchangeably. Both terms refer to the VLF emitters
whose amplitude and phase are recorded.
The next step is precising which transmitters are of interest to us, and their characteristics. For example
NRK = station('NRK', 63.85, -22.47, 37.5, 24.4, ':15')
defines a transmitter. Several informations are needed:
'NRK'is the call-sign of the station63.85/-22.47are the latitude and longitude of the station. This is needed for plots.37.5is the frequency of the station, in kHz24.4is the detection threshold for this particular station, in °/hour (see Detection threshold).':15'is the number of seconds after the minute at which the data for this station should be read.
Additional parameters can be also inputted. For a more complete description of the station class, please see Station.
Important
It is assumed in this version that the data for each station is going to be read once per minute. It is important that the data for two different stations is not read at the same time; to avoid this, just input different parameters for the reading time when creating the different transmitters and the nowcast (see below).
Paths
As described in the Required files section, additional files are required to estimate sunrises and sunsets, electron density in the D-region and the solar X-ray flux. Those need to be specified in the main script:
#-------------- Paths
path_breakpoint = '/results/' # Where the breakpoints will be stored
path_mau = '/NarrowbandSync/' # Data read
path_sunrise = '/NarrowbandSync/Necessary_files/' # List of sunrise/sunset
path_to_CSVfiles = '/NarrowbandSync/Necessary_files/' # Results from LMP
path_to_results = path_breakpoint # Files (maps & probas) sent with alerts
path_to_probas = 'example_path' # CSV files for flux estimation
Defining email alerts
Once the receiver and the different transmitters are defined, the alerts to send can be created. The first step is too allow Python to send an email using an account. For Gmail accounts, see Gmail app passwords .
In the script, the sender and password can then be defined:
sender = 'dummy@gmail.com'
password = 'aaaa aaaa aaaa aaaa'
This should be common to all the alerts to send, but different alerts could use different senders as well.
Then, alerts could be sent for different reasons: to inform of the receiver having stopped, in case of flare detection, or to ping at midnight to prove that the script is still running for example. So different alerts can be defined, with their own characteristics.
As an example, below are defined different example alerts:
# Email if the receiver is down
recipients = ['dummy2@example.fr'] # Note: must be a list
subject = Nancay.name + ' down'
body = 'Relaunch the antenna'
antenna_down = email_alerts(subject, body, sender, password, recipients)
# Detection by a single receiver
subject = 'Detection - ' + Nancay.name
body = 'Placeholder here - Real body updated for each detection'
detection_alert = email_alerts(subject, body, sender, password, recipients,
files=[path_to_results+'last.pdf', path_to_results+'last_map.pdf'])
# Alert if there is a high chance of strong flares
subject = 'High proba - ' + Nancay.name
body = '10 percent probability of flux being above threshold'
proba_alert = email_alerts(subject, body, sender, password, recipients,
threshold=5e-5, files=[path_to_results+'last.pdf',
path_to_results+'last_map.pdf'])
This syntax can also be applied to pings. Since different people may be interested in different alerts, the recipients can be specific to each alert. For more information on additional parameters, please see Alerts
Important
Particular case: Flare detection
In case of flare detection by a single station, the email alert should also countains information on the type of flare detected. This is done internally by the update_detection_body() method. Therefore, alerts for flare detection should be created as the other type of alerts, but the text put in the body will not be taken into account.
Nowcast
Even though alerts can be sent if each station has detected a flare separately, it is better to send an alert after having a more global estimate of the Sun’s X-ray flux and the electron density in the D-region. This is done through the nowcast class (see Nowcast)
# -------------- Nowcast
nowcast_here = nowcast([NAA, GQD, NRK, NSY], Nancay, alerts=[proba_alert],
reading_time=':00')
Updating df values
The values of df are first inputted by the user (see Phase detrend and Station). However, as time passes, they may change [cannon2025]. Ideally, they should be changed regularly. However, to limit the work needed by the user, this may be done regularly as:
# -------------- Update of df values
schedule.every().monday.at("00:01:05").do(NRK.update_df, Nancay, path_to_data)
# -------------- Write df values in a file
schedule.every().sunday.at("00:01:05").do(ms.write_file_with_df, stations, path_to_results)
Note
As before, this should be done at a time that doesn’t conflict with a nowcast time, a time when the data for a station is updated, or a scheduled email is sent
Main script
Once the receiver, the transmitter and the alerts are defined, the main script can be called. An example for Nançay is found below:
# Call every minute the function for each station
# NOTE: No two stations should be called at the same time
schedule.every().minute.at(NRK.reading_time).do(NRK.update_breakpoints,
path_breakpoint, path_mau, path_sunrise, antenna_down, detection_alert, Nancay)
# Call the nowcast
schedule.every().minute.at(nowcast_here.reading_time).do(nowcast_here.run,
path_to_probas, path_to_results, path_to_CSVfiles)
# Send a ping every day 5 second after midnight to
# let the user know that the script is still running
schedule.every().day.at('00:00:05').do(midnight_ping.send_email())
# Next part ensure that the script keeps running from one minute to the next
while True:
schedule.run_pending()
time.sleep(1)
Results
The main results of the code are the email alerts, with the flux estimation. However, additional files are also produced. Those are stored in the path specified in path_to_results path specified in the script. Two types of files are created:
Files with the list of all breakpoints detected for each station. There is one file per station and per day. Those files are handled with the
manage_statefilemodule and the two function therein. Note: the first line of those file corresponds to the last breakpoint of the previous day if there was a file created for the previous day. If this breakpoint was in flare time, the new file will also include the last quiet breakpoint. If no file were created the previous day, or if the previous day only contained flare breakpoints (which would be incorrect), the new file is initialised with a new quiet breakpoint with arbitrary slope, amplitude and phase.
Note
The breakpoint files are always initialised with a ‘artificial’ breakpoint. This is either the last breakpoint measured on the previous day (if there was data on the previous day), or a series of 0 and 1 which will be replaced as soon as a breakpoint is detected. The only exception to this is the case where the last breakpoint on the previous day was in flare time. In this case, the first line of the new file will be the last measured breakpoint, except it will be noted as in quiet time. This is done to prevent errors occuring when looking for the last quiet point. It will thus cause mistakes for detected flares occuring accross midnight, but may be corrected at a later version.
Two plot files, updated every minute, each time the
nowcastclass is called. They are calledlast.pdfandlast_map.pdfand they represent respectively the plot of the probability density function for the flux estimation (see Estimating solar X-ray flux) and the map with computed electron density (see Plotting the results). They are the files which should be sent with email alerts (see Alerts).A file per day (
date_nowcast.csv), where all the flux estimates are written (see Estimating solar X-ray flux). If a recapitulative email is sent with all the flare detections of the day, this should be included. It is mainly useful for debugging and keeping track of everything that happened during the day. If GOES data is unavailable for any reason, this would be a good sustitute.A file every week (or longer, depending on the user), where the values of
dfare stored. They can changed if they are automatically updated, so keeping track of them makes the debugging and post-processing easier (see Updating df values).