Tags: Amateur Radio, Expedition, Propagation, Arranmore

Posted: May 6, 2013

Activity prediction, part 1

Along with a group of other Amateurs (including members of Sands Contest Group and Workington Radio Club) I’m going on DX-pedition to Arranmore at the end of September. While it might not exactly be Christmas Island, there’s still a lot of planning and preparation involved in a trip of this nature, and we’re keen to ensure that we make the most of our time on the island.

We’re hoping to have 6 stations on air, as propagation allows, and this raises the question of which geographic areas to target at which times of day for best results. Other members of the group are running propagation predictions using the usual tools, but I thought I’d take the opportunity to try out a new feature that Michael, G7VJR, recently added to Club Log.

If you haven’t got started with Club Log yet, I highly recommend it. It offers a wide variety of features for the DXer, and has a very active base of users uploading logs. For my purposes, that means that it’s possible for Club Log to perform analysis on the logs in aggregate; for example, you can generate graphs of activity over time between two DXCC entities. The recent addition that makes this post possible is an API to allow other programs to query these activity data; so I thought it would be interesting to generate graphs of activity between Ireland and the major population centres of the world. This could then be combined with propagation predictions to add a bit of ‘real world’ control, since the Club Log data are based on real QSOs that have taken place and been logged.

The first stage is writing a simple wrapper to the Club Log API to allow me to retrieve activity data from the command-line. There isn’t too much involved in this – just a straightforward GET request to an endpoint that returns JSON data. I wrote the wrapper as a new Galosh sub-command, which allows me to run:

$ galosh clublog-activity 291 254 > us_ireland.json

The code is on Github for the curious.

Next up: time to draw some graphs. I started off with the following rough-and-ready R script, which takes a JSON file from Club Log on STDIN and produces a PDF graph:

#!/usr/bin/env Rscript

args <- commandArgs(TRUE)

bandsOfInterest <- c( 160, 80, 60, 40, 30, 20, 17, 15, 12, 10, 6 )

plotActivity <- function(json, title) {
    json_data <- fromJSON(file=json)
    q_count   <- numeric()

    for ( band in as.character(bandsOfInterest) ) {
        count <- if (is.null(json_data[[band]][["count"]])) 0
                 else json_data[[band]][["count"]]
        json_data[[band]][["count"]] <- NULL
        q_count <- append(q_count, (unlist(json_data[[band]]) * count))

    d <- data.frame(
        band=rep(bandsOfInterest, each=24),

        ggplot(d, aes(x=time, y=q_count, fill=factor(band))) +
        geom_area(stat="identity") +
        guides(fill=guide_legend(title="Band")) +
        labs(title=title, x="Time", y="Qs")

if ( length(args) < 2 ) {
    write("Usage: act TITLE FILENAME", stderr())
    quit("no", 1)
} else {
    title = args[[1]]
    outputPath = args[[2]]

pdf(outputPath, width=6, height=4)
plotActivity("stdin", title)

Given the JSON file I downloaded above, this allows me to run:

$ cat us_ireland.json | ./activity_graph.r "Ireland to US" graph.pdf 

This provides a very straight-forward, at-a-glance overview of which bands you can expect to be active between two DXCC entities at any given time of day.

Now that we have the basics in place the next post in this series will cover generating real graphs for each of the primary directions from Arranmore.