I recently had a requirement to visualise some geospatial radiation data exported from two radiation detectors, an R400 Radionuclide Identification Device (RID) and a GQ GMC 600+ Geiger counter (don’t ask) by plotting the data on an interactive map.

This simple R script below will plot the raw data from a Data Logger file downloaded from an FLIR identiFINDER R400 device onto an interactive heatmap for quick and easy visualisation of radiation levels during a geospatial survey. It takes a couple of minutes to get this working on a personal computer using RStudio, even if you have never used R before, alternatively the same script could be run on a web server as an easy way to display the map online. Everything you need to get this script working from scratch is included in the comments in the code below. Feel free to try it. Enjoy!

The same foundational code can easily be modified to map any geolocated data, for instance annual sales figures across various store locations — just change the column names, that’s all there is to it.

# R programming language (version R-3.5.1) - install this 1st
# http://www.stats.bris.ac.uk/R/

# RStudio IDE (version 1.1.453) - install this 2nd:
# https://www.rstudio.com/


# Install packages

# Import extended open functions -- to support reading Excel files.
# https://www.rdocumentation.org/packages/openxlsx/versions/4.1.0
# https://www.rdocumentation.org/packages/openxlsx/versions/4.1.0/topics/read.xlsx
if (!require(xlsx)) install.packages("xlsx", repos = "http://cran.us.r-project.org")
library("xlsx", lib.loc="C:/Program Files/R/R-3.5.1/library")

# Import extended filter() function.
if (!require(dplyr)) install.packages("dplyr", repos = "http://cran.us.r-project.org")
library("dplyr", lib.loc="C:/Program Files/R/R-3.5.1/library")

# Import mapping functions - setView() etc.
if (!require(maps)) install.packages("maps", repos = "http://cran.us.r-project.org")
library("maps", lib.loc="C:/Program Files/R/R-3.5.1/library")

# Import map layering functions - leaflet(), colorNumeric(), etc.
if (!require(leaflet)) install.packages("leaflet", repos = "http://cran.us.r-project.org")
library("leaflet", lib.loc="C:/Program Files/R/R-3.5.1/library")


# Load the raw data from an Excel workbook.

r400LogRaw = read.xlsx("C:/Users/tacheson/Downloads/R400/Data Logging 112.slk.xlsx", 1)

# Exclude records lacking mappable/geospatial/GIS data.
r400LogFiltered = filter(r400LogRaw, is.null(r400LogRaw$Longitude) == FALSE & is.na(r400LogRaw$Longitude) == FALSE)

# Enforce numeric data type where needed.
r400LogFiltered$Latitude <- as.numeric(as.character(r400LogFiltered$Latitude))
r400LogFiltered$Longitude <- as.numeric(as.character(r400LogFiltered$Longitude))


# Draw the map.

# Define the colour gradient used to visualise radiation dose rate on a heatmap.
colourPallette <- colorNumeric(
  palette = c("Yellow", "Red"),
  domain = r400LogFiltered$Average.Dose.Rate)

# Render the map.
# providerTiles e.g, CartoDB.Positron: http://leaflet-extras.github.io/leaflet-providers/preview/
# radius = ~Maximal.Dose.Rate
leaflet(r400LogFiltered) %>% 
  setView(lng = mean(r400LogFiltered$Longitude), lat = mean(r400LogFiltered$Latitude), zoom = 13) %>%
  addProviderTiles(providers$CartoDB.Positron) %>%
  addCircleMarkers(lng = ~Longitude, lat = ~Latitude, popup = ~paste0("Dose: ", Average.Dose.Rate), radius = 3, color = ~colourPallette(Average.Dose.Rate), stroke = FALSE, fillOpacity = 0.9)

Examples of the resulting geospatial radiation heatmaps, also available here as raw images and interactive HTML maps on my public OneDrive:

Geospatial radiation levels at Survey Area L2 at Rendlesham Forest,. The majority of background measurements have been removed by Exclusion Threshold 0.091. The map was captured at Zoom Level 2.
Geospatial radiation levels at Survey Area L2 at Rendlesham Forest. The majority of background measurements have been removed by Exclusion Threshold 0.019. The map was captured at Zoom Level 2.

Interpretation of these data is beyond the scope of the current blog post, but the results from one of the areas surveyed will be discussed in an upcoming documentary, Capel Green, in the context of radiation exposure associated with UAP (Unidentified Aerial Phenomena) documented by the UK MoD’s project CONDIGN (declassified) and other studies. Tri-axial multi-field EMF measurements were also recorded during the survey.

Identification of the radionuclides responsible for above-background radiation measurements was performed using the R400’s gamma-ray spectrometer. The resulting spectra, along with isotope identification, are beyond the scope of this discussion. Some of the spectra captured at the Survey Area L2 exhibited peaks at energies that do not match the fingerprints of known isotopes in the Identifinder database, and were therefore logged as “unknown.” This finding merits further investigation to identify the nuclide(s) responsible for the elevated radiation levels monitored at the specified GPS locations.

Radionuclide identification by gamma-ray spectrometry at Survey Area L2 using an FLIR R400 RID with the Identifinder 2 on-board nuclide identification database.

Measuring background gamma dose rate at Survey Area L2 using an FLIR R400 with a NaI (Tl) detector (and a GM tube for high dose rates).

The R400 has on-board GPS logging, while the GMC 600+ was used in conjunction with the GPSLogger app and the data then exported to the R400’s Data Logger file format. Data Column A is the GPS location of each measurement location on a grid pattern measured on site. Data Column B is the average (mean) radiation level at that GPS location from a 60 second measurement. The air radiation dose rate (in units of µSv per hour) quantifies irradiation of the sensors by α-rays, β-rays, γ-rays and x-rays during a specific monitoring period at the corresponding GPS location.

R400 radiation survey (homepage header)
R400 radiation survey (homepage header)

I’ve been dabbling in functional programming languages for a while – particularly F#, the excellent functional language available within the NET Framework and CLI — Microsoft’s thriving mainstream software development platform. Functional programming is, of course, naturally suited to processing datasets and crunching statistics.

This quick easy mapping application was the perfect excuse to venture deeper than ever before into R and the powerful packages available to its developers. The R programming language might have been called “S” for “statistical” (after its most popular application or even after the Scheme language that inspired its lexical scoping semantics) — had that name had not already been taken by its forerunner. I’d like to add a new function read.slk() to open raw SLK files (a proprietary file format from Microsoft used by the R400 device) using COM Interop, or do this by combining F# and R, because R can also be harnessed by the .NET CLR. If you find an R package that supports the SLK specification, or if you beat me to it and write one, please let me know!

I want to say a lot more about the R400… Perhaps I will in due course, so watch this space… It’s an exceptionally useful and interesting piece of kit, capable of very sensitive radiation detection as well as radionuclide identification by gamma-ray spectroscopy. Its principal use is in military and border threat detection, but it’s equally useful in the lab — and I’ve found it useful in a wide range of applications from radiation risk assessment, through to radiation surveys and environmental monitoring at atomic weapons storage facilities, and even recently in research into the radiation associated with UAP/UFOs!

From the archive: this post was imported from the previous version of this website, and is archived in the Internet Archive, here.

Leave a Reply