This script parses and cleans the ODIN-SD data from their memory cards to then calculate summary statistics and plot draft maps of PM10 and PM2.5

Prepare libraries

library(librarian) # To more flexibly manage packages
shelf(readr,
      openair,
      automap,
      raster,
      gstat,
      sp,
      rgdal,
      ggmap,
      ggplot2,
      scales)
Warning in shelf(readr, openair, automap, raster, gstat, sp, rgdal, ggmap, : cran_repo = '@CRAN@' is not a valid URL. 
                    Defaulting to cran_repo = 'https://cran.r-project.org'.
Loading required package: sp
rgdal: version: 1.3-3, (SVN revision 759)
 Geospatial Data Abstraction Library extensions to R successfully loaded
 Loaded GDAL runtime: GDAL 2.1.4, released 2017/06/23
 Path to GDAL shared files: /usr/share/gdal
 GDAL binary built with GEOS: TRUE 
 Loaded PROJ.4 runtime: Rel. 4.9.3, 15 August 2016, [PJ_VERSION: 493]
 Path to PROJ.4 shared files: (autodetected)
 Linking to sp version: 1.3-1 
Loading required package: ggplot2

Attaching package: 'scales'
The following object is masked from 'package:readr':

    col_factor

Set constants

data_path <- "~/data/ODIN_SD/Gisborne/WORKING/"
folders_list <- dir(data_path,pattern = '00')
# Define time average for output
tavg <- '10 min'

Load data

Cycle through the folders to work with all the DATA.TXT files

for (i in (1:length(folders_list))){
  folder <- folders_list[i]
  print(folder)
  odin.data <- readr::read_delim(paste0(data_path,folder,"/DATA.TXT"),
                                 delim = ';',
                                 skip = 1,
                                 col_names = c('framelength',
                                               'PM1',
                                               'PM2.5',
                                               'PM10',
                                               'PM1x',
                                               'PM2.5x',
                                               'PM10x',
                                               'GasSN',
                                               'Gasppm',
                                               'GasT',
                                               'Gas2mV',
                                               'Temperature',
                                               'RH',
                                               'ODINid',
                                               'ODINsn',
                                               'RTCdate',
                                               'RTCtime',
                                               'GSMdate',
                                               'GSMtime',
                                               'RTCdate2',
                                               'RTCtime2'))
  # Pad missing GSM date-time with RTC date-time for simplicity
  
  odin.data$GSMtime[is.na(odin.data$GSMtime)] <- odin.data$RTCtime[is.na(odin.data$GSMtime)]
  odin.data$GSMdate[is.na(odin.data$GSMdate)] <- odin.data$RTCdate[is.na(odin.data$GSMdate)]
  
  # Construct POSIX objects for RTC and GSM timestamps
  odin.data$RTCtimestamp <- as.POSIXct(paste(odin.data$RTCdate,odin.data$RTCtime),tz='UTC')
  odin.data$GSMtimestamp <- as.POSIXct(paste(odin.data$GSMdate,odin.data$GSMtime),tz='UTC')

  # Find the correction from RTC to GSM timestamps

  time_correction.all <- as.numeric(difftime(odin.data$GSMtimestamp,odin.data$RTCtimestamp,units = 'secs'))
  time_correction.all[time_correction.all==0] <- NA
  time_diff <- mean(time_correction.all,na.rm = TRUE)

  # Calculate the "real" timestamp for the records

  odin.data$date <- odin.data$RTCtimestamp + time_diff
  odin.data <- odin.data[,c('date',
                            'PM1',
                            'PM2.5',
                            'PM10',
                            'Temperature',
                            'RH',
                            'ODINsn')]

  # Construct the ALLDATA frame

  if (i == 1){
    # This is the first iteration so we just copy the "odin.data" dataframe
    all.data <- odin.data
    all.data.tavg <- timeAverage(odin.data,avg.time = tavg)
    all.data.tavg$ODINsn <- odin.data$ODINsn[1]
  } else {
    # We already have "all.data" so we need to append the current "odin.data"
    all.data <- rbind(all.data,odin.data)
    tmp1 <- timeAverage(odin.data,avg.time = tavg)
    tmp1$ODINsn <- odin.data$ODINsn[1]
    all.data.tavg <- rbind(all.data.tavg,tmp1)
    # Remove all.data to clean for next iteration
    rm(odin.data)
  }
}
[1] "0005"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 16679 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   527 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0005… file 2   725 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0005… row 3   726 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0005… col 4   727 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0005… expected 5   728 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0005…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0008"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17040 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   327 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0008… file 2   328 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0008… row 3   329 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0008… col 4   330 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0008… expected 5   331 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0008…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0009"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17272 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1    20 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0009… file 2   119 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0009… row 3   120 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0009… col 4   121 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0009… expected 5   122 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0009…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0010"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 68195 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   485 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0010… file 2   486 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0010… row 3   487 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0010… col 4   488 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0010… expected 5   489 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0010…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0011"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17382 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1    18 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0011… file 2    19 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0011… row 3    20 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0011… col 4    21 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0011… expected 5    22 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0011…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0014"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 12591 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1  3941 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0014… file 2  4329 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0014… row 3  4618 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0014… col 4  4792 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0014… expected 5  4793 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0014…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0016"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 16217 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1    28 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0016… file 2    29 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0016… row 3    30 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0016… col 4    31 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0016… expected 5    32 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0016…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0017"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 15361 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   686 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0017… file 2   786 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0017… row 3  2026 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0017… col 4  2027 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0017… expected 5  2028 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0017…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0018"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17389 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1     5 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0018… file 2     6 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0018… row 3     7 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0018… col 4     8 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0018… expected 5     9 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0018…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0021"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17241 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   167 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0021… file 2   168 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0021… row 3   169 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0021… col 4   170 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0021… expected 5   171 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0021…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0023"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 42993 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   134 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0023… file 2   236 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0023… row 3   237 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0023… col 4   238 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0023… expected 5   239 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0023…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0025"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17351 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1    43 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0025… file 2    44 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0025… row 3    45 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0025… col 4    46 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0025… expected 5    47 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0025…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0026"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17398 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1     5 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0026… file 2     6 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0026… row 3     7 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0026… col 4     8 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0026… expected 5     9 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0026…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0027"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 16666 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   230 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0027… file 2   339 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0027… row 3   340 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0027… col 4   341 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0027… expected 5   342 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0027…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0028"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 17391 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1    10 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0028… file 2    11 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0028… row 3    12 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0028… col 4    13 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0028… expected 5    14 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0028…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0029"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 16866 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   531 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0029… file 2   532 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0029… row 3   533 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0029… col 4   534 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0029… expected 5   535 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0029…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.
[1] "0031"
Parsed with column specification:
cols(
  .default = col_integer(),
  GasSN = col_character(),
  Temperature = col_double(),
  RH = col_double(),
  ODINid = col_character(),
  ODINsn = col_character(),
  RTCdate = col_date(format = ""),
  RTCtime = col_time(format = ""),
  GSMdate = col_date(format = ""),
  GSMtime = col_time(format = ""),
  RTCdate2 = col_date(format = ""),
  RTCtime2 = col_time(format = "")
)
See spec(...) for full column specifications.
Warning in rbind(names(probs), probs_f): number of columns of result is not
a multiple of vector length (arg 1)
Warning: 4465 parsing failures.
row # A tibble: 5 x 5 col     row col   expected   actual     file                                   expected   <int> <chr> <chr>      <chr>      <chr>                                  actual 1   562 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0031… file 2  1071 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0031… row 3  1379 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0031… col 4  2197 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0031… expected 5  2282 <NA>  21 columns 18 columns '~/data/ODIN_SD/Gisborne/WORKING/0031…
... ................. ... .......................................................................... ........ .......................................................................... ...... .......................................................................... .... .......................................................................... ... .......................................................................... ... .......................................................................... ........ ..........................................................................
See problems(...) for more details.

Get devices locations

odin_locations <- readr::read_delim("odin_locations.txt", 
                             "\t", escape_double = FALSE, trim_ws = TRUE)
Parsed with column specification:
cols(
  serialn = col_character(),
  lat = col_double(),
  lon = col_double()
)
nsites <- length(odin_locations$serialn)
all.data$lon <- 0
all.data$lat <- 0
all.data.tavg$lon <- 0
all.data.tavg$lat <- 0
for (j in (1:nsites)){
  print(odin_locations$serialn[j])
  loc_id <- (substr(all.data$ODINsn,3,6)==substr(odin_locations$serialn[j],7,11))
  all.data$lon[loc_id] <- odin_locations$lon[j]
  all.data$lat[loc_id] <- odin_locations$lat[j]
  loc_id.tavg <- (substr(all.data.tavg$ODINsn,3,6)==substr(odin_locations$serialn[j],7,11))
  all.data.tavg$lon[loc_id.tavg] <- odin_locations$lon[j]
  all.data.tavg$lat[loc_id.tavg] <- odin_locations$lat[j]
}
[1] "ODINSD0025"
[1] "ODINSD0023"
[1] "ODINSD0026"
[1] "ODINSD0016"
[1] "ODINSD0011"
[1] "ODINSD0031"
[1] "ODINSD0029"
[1] "ODINSD0028"
[1] "ODINSD0009"
[1] "ODINSD0018"
[1] "ODINSD0014"
[1] "ODINSD0017"
[1] "ODINSD0027"
[1] "ODINSD0008"
[1] "ODINSD0010"
[1] "ODINSD0021"
# Subset for the campaign
start_date <-as.POSIXct("2018-06-22 12:00:00",tz="UTC")
end_date <-as.POSIXct("2018-08-16 12:00:00",tz="UTC")
nminutes <- difftime(end_date,start_date,units = 'min')
all.data <- subset(all.data, (date >= start_date) & (date <= end_date))
all.data.tavg <- subset(all.data.tavg, (date >= start_date) & (date <= end_date))

Summary statistics

Note that the statistics are calculated on 10 minutes averages and that the campaign went from June 22nd 12:00 UTC until August 16th 12:00 UTC (55 days in total).

The units for the parameters are: * PM2.5 [\(mu\)g/m3] * PM10 [\(mu\)g/m3] * Temperature [celsius] * RH [%]

# Calculate the summary table for each unit
summary_mean <- aggregate(cbind(Temperature, RH,PM2.5, PM10) ~ODINsn, all.data.tavg, FUN = mean)
summary_max <- aggregate(cbind(Temperature, RH,PM2.5, PM10) ~ODINsn, all.data.tavg, FUN = max)
summary_min <- aggregate(cbind(Temperature, RH,PM2.5, PM10) ~ODINsn, all.data.tavg, FUN = min)
summary_sd <- aggregate(cbind(Temperature, RH,PM2.5, PM10) ~ODINsn, all.data.tavg, FUN = sd)
summary_N <- aggregate(cbind(Temperature, RH,PM2.5, PM10) ~ODINsn, all.data.tavg, FUN = length)
summary_pct <- summary_N
summary_pct[,2:5] <- format(100 * (summary_N[,2:5] / (as.numeric(nminutes) / 10)),digits = 2)

Average concentrations

print(format(summary_mean,digits = 1))
   ODINsn Temperature RH PM2.5 PM10
1  SD0005          12 73  10.8 10.8
2  SD0008          13 69  12.8 18.5
3  SD0009          13 69  13.6 17.3
4  SD0010          13 67  25.5 34.1
5  SD0011          12 71  17.3 20.2
6  SD0014          12 71  20.4 28.7
7  SD0016          13 67  16.6 19.6
8  SD0017          12 70  20.9 24.4
9  SD0018          13 69  22.8 29.6
10 SD0021          13 70  14.1 17.0
11 SD0023          13 68   8.9 12.0
12 SD0025          12 71   4.9  6.7
13 SD0026          14 66  14.9 19.6
14 SD0027          13 70  11.5 16.3
15 SD0029          13 70  17.3 22.4
16 SD0031          12 72  12.5 15.5
17 SN0028          12 71   0.4  0.5

Maximum concentrations

print(format(summary_max,digits = 1))
   ODINsn Temperature RH PM2.5 PM10
1  SD0005          27 98   100  100
2  SD0008          29 98   203  299
3  SD0009          31 96   172  252
4  SD0010          31 93   353  536
5  SD0011          27 96   260  328
6  SD0014          29 97   322  528
7  SD0016          34 95   262  366
8  SD0017          28 96   338  454
9  SD0018          27 95   232  536
10 SD0021          28 98   314 1284
11 SD0023          33 96   164  213
12 SD0025          31 95   154  180
13 SD0026          32 95   242  328
14 SD0027          31 98   225  337
15 SD0029          30 96   280  361
16 SD0031          27 96   366  507
17 SN0028          26 98    40   46

Minimum concentrations

print(format(summary_min,digits = 1))
   ODINsn Temperature RH PM2.5 PM10
1  SD0005         0.3 27     4    4
2  SD0008         2.0 21     0    0
3  SD0009         0.2 21     0    0
4  SD0010         1.8 20     0    0
5  SD0011         1.4 24     0    0
6  SD0014         0.3 25     0    0
7  SD0016         2.2 16     0    0
8  SD0017         1.6 24     0    0
9  SD0018         1.4 22     0    0
10 SD0021         0.6 24     0    0
11 SD0023         1.4 18     0    0
12 SD0025         1.8 24     0    0
13 SD0026         3.5 18     0    0
14 SD0027         2.3 19     0    0
15 SD0029         1.3 22     0    0
16 SD0031         1.8 23     0    0
17 SN0028         0.5 27     0    0

Standard deviation

print(format(summary_mean,digits = 1))
   ODINsn Temperature RH PM2.5 PM10
1  SD0005          12 73  10.8 10.8
2  SD0008          13 69  12.8 18.5
3  SD0009          13 69  13.6 17.3
4  SD0010          13 67  25.5 34.1
5  SD0011          12 71  17.3 20.2
6  SD0014          12 71  20.4 28.7
7  SD0016          13 67  16.6 19.6
8  SD0017          12 70  20.9 24.4
9  SD0018          13 69  22.8 29.6
10 SD0021          13 70  14.1 17.0
11 SD0023          13 68   8.9 12.0
12 SD0025          12 71   4.9  6.7
13 SD0026          14 66  14.9 19.6
14 SD0027          13 70  11.5 16.3
15 SD0029          13 70  17.3 22.4
16 SD0031          12 72  12.5 15.5
17 SN0028          12 71   0.4  0.5

Data availability [%]

print(format(summary_pct,digits = 1))
   ODINsn Temperature  RH PM2.5 PM10
1  SD0005         100 100   100  100
2  SD0008         100 100   100  100
3  SD0009         100 100   100  100
4  SD0010          95  95    95   95
5  SD0011         100 100   100  100
6  SD0014         100 100   100  100
7  SD0016          95  95    95   95
8  SD0017         100 100   100  100
9  SD0018         100 100   100  100
10 SD0021         100 100   100  100
11 SD0023         100 100   100  100
12 SD0025         100 100   100  100
13 SD0026         100 100   100  100
14 SD0027         100 100   100  100
15 SD0029         100 100   100  100
16 SD0031         100 100   100  100
17 SN0028         100 100   100  100

Time series

PM2.5

ggplot(data = all.data.tavg, aes(x=date)) +
  geom_line(aes(y=PM2.5,colour = ODINsn))

PM10

ggplot(data = all.data.tavg, aes(x=date)) +
  geom_line(aes(y=PM10,colour = ODINsn))

Temperature

ggplot(data = all.data.tavg, aes(x=date)) +
  geom_line(aes(y=Temperature,colour = ODINsn))

Relative Humidity

ggplot(data = all.data.tavg, aes(x=date)) +
  geom_line(aes(y=RH,colour = ODINsn))

Malfunctioning ODIN

The previous summaries show that ODIN-0005 malfunctioned so it will be removed from the analysis.

remove_idx <- (all.data$ODINsn == "SD0005")
all.data[remove_idx,] <- NA
all.data <- na.exclude(all.data)
remove_idx <- (all.data.tavg$ODINsn == "SD0005")
all.data.tavg[remove_idx,] <- NA
all.data.tavg <- na.exclude(all.data.tavg)

Average Maps

# Some useful constants
proj4string_NZTM <- CRS('+init=epsg:2193')
proj4string_latlon <- CRS('+init=epsg:4326')
# Assign coordinates to the dataframe
summary_mean_map <- aggregate(cbind(Temperature, RH, PM2.5, PM10, lon, lat) ~ODINsn, all.data.tavg, FUN = mean)
coordinates(summary_mean_map) <- ~ lon + lat
proj4string(summary_mean_map) <- proj4string_latlon

# Get the basemap
centre_lat <- mean(summary_mean_map$lat)
centre_lon <- mean(summary_mean_map$lon)
ca <- get_map(
  c(lon=centre_lon,lat=centre_lat),
  zoom=13,crop=T,
  scale="auto",color="bw",source="google",
  maptype="terrain")
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=-38.660128,178.019052&zoom=13&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false

PM2.5

ggmap(ca) + 
  geom_point(data=as.data.frame(summary_mean_map),aes(x=lon,y=lat,colour = PM2.5),size = 5) +
  scale_colour_continuous(low="white", high="red",limits=c(0, max(summary_mean_map$PM2.5)),
                          name = "PM2.5", oob=squish)

PM10

ggmap(ca) + 
  geom_point(data=as.data.frame(summary_mean_map),aes(x=lon,y=lat,colour = PM10),size = 5) +
  scale_colour_continuous(low="white", high="red",limits=c(0, max(summary_mean_map$PM10)),
                          name = "PM10", oob=squish)

PMcoarse

ggmap(ca) + 
  geom_point(data=as.data.frame(summary_mean_map),aes(x=lon,y=lat,colour = PM10 - PM2.5),size = 5) +
  scale_colour_continuous(low="white", high="red",limits=c(0, max(summary_mean_map$PM10 - summary_mean_map$PM2.5)),
                          name = "PMcoarse", oob=squish)

# Save the "all.data" dataframe
save(all.data,file = 'alldata.RData')
save(all.data.tavg,file = 'alldataTAVG.RData')
IyctLS0KIyd0aXRsZTogIk9ESU4tU0QgU3VtbWFyeSIKIydvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKIydhdXRob3I6IEd1c3Rhdm8gT2xpdmFyZXMKIyctLS0KCiMnVGhpcyBzY3JpcHQgcGFyc2VzIGFuZCBjbGVhbnMgdGhlIE9ESU4tU0QgZGF0YSBmcm9tIHRoZWlyIG1lbW9yeSBjYXJkcyB0byB0aGVuIGNhbGN1bGF0ZSBzdW1tYXJ5IHN0YXRpc3RpY3MgCiMnYW5kIHBsb3QgZHJhZnQgbWFwcyBvZiBQTX4xMH4gYW5kIFBNfjIuNX4KIycKCiMnCiMnICMjIFByZXBhcmUgbGlicmFyaWVzCiMnICAKbGlicmFyeShsaWJyYXJpYW4pICMgVG8gbW9yZSBmbGV4aWJseSBtYW5hZ2UgcGFja2FnZXMKc2hlbGYocmVhZHIsCiAgICAgIG9wZW5haXIsCiAgICAgIGF1dG9tYXAsCiAgICAgIHJhc3RlciwKICAgICAgZ3N0YXQsCiAgICAgIHNwLAogICAgICByZ2RhbCwKICAgICAgZ2dtYXAsCiAgICAgIGdncGxvdDIsCiAgICAgIHNjYWxlcykKIycgIyMgU2V0IGNvbnN0YW50cwpkYXRhX3BhdGggPC0gIn4vZGF0YS9PRElOX1NEL0dpc2Jvcm5lL1dPUktJTkcvIgpmb2xkZXJzX2xpc3QgPC0gZGlyKGRhdGFfcGF0aCxwYXR0ZXJuID0gJzAwJykKIyBEZWZpbmUgdGltZSBhdmVyYWdlIGZvciBvdXRwdXQKdGF2ZyA8LSAnMTAgbWluJwojJyAjIyBMb2FkIGRhdGEKIycKIycgIEN5Y2xlIHRocm91Z2ggdGhlIGZvbGRlcnMgdG8gd29yayB3aXRoIGFsbCB0aGUgREFUQS5UWFQgZmlsZXMKIycgIApmb3IgKGkgaW4gKDE6bGVuZ3RoKGZvbGRlcnNfbGlzdCkpKXsKICBmb2xkZXIgPC0gZm9sZGVyc19saXN0W2ldCiAgcHJpbnQoZm9sZGVyKQogIG9kaW4uZGF0YSA8LSByZWFkcjo6cmVhZF9kZWxpbShwYXN0ZTAoZGF0YV9wYXRoLGZvbGRlciwiL0RBVEEuVFhUIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGltID0gJzsnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBza2lwID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gYygnZnJhbWVsZW5ndGgnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQTTEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQTTIuNScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BNMTAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQTTF4JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUE0yLjV4JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUE0xMHgnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdHYXNTTicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0dhc3BwbScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0dhc1QnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdHYXMybVYnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUZW1wZXJhdHVyZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1JIJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnT0RJTmlkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnT0RJTnNuJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUlRDZGF0ZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1JUQ3RpbWUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdHU01kYXRlJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnR1NNdGltZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1JUQ2RhdGUyJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUlRDdGltZTInKSkKICAjIFBhZCBtaXNzaW5nIEdTTSBkYXRlLXRpbWUgd2l0aCBSVEMgZGF0ZS10aW1lIGZvciBzaW1wbGljaXR5CiAgCiAgb2Rpbi5kYXRhJEdTTXRpbWVbaXMubmEob2Rpbi5kYXRhJEdTTXRpbWUpXSA8LSBvZGluLmRhdGEkUlRDdGltZVtpcy5uYShvZGluLmRhdGEkR1NNdGltZSldCiAgb2Rpbi5kYXRhJEdTTWRhdGVbaXMubmEob2Rpbi5kYXRhJEdTTWRhdGUpXSA8LSBvZGluLmRhdGEkUlRDZGF0ZVtpcy5uYShvZGluLmRhdGEkR1NNZGF0ZSldCiAgCiAgIyBDb25zdHJ1Y3QgUE9TSVggb2JqZWN0cyBmb3IgUlRDIGFuZCBHU00gdGltZXN0YW1wcwogIG9kaW4uZGF0YSRSVEN0aW1lc3RhbXAgPC0gYXMuUE9TSVhjdChwYXN0ZShvZGluLmRhdGEkUlRDZGF0ZSxvZGluLmRhdGEkUlRDdGltZSksdHo9J1VUQycpCiAgb2Rpbi5kYXRhJEdTTXRpbWVzdGFtcCA8LSBhcy5QT1NJWGN0KHBhc3RlKG9kaW4uZGF0YSRHU01kYXRlLG9kaW4uZGF0YSRHU010aW1lKSx0ej0nVVRDJykKCiAgIyBGaW5kIHRoZSBjb3JyZWN0aW9uIGZyb20gUlRDIHRvIEdTTSB0aW1lc3RhbXBzCgogIHRpbWVfY29ycmVjdGlvbi5hbGwgPC0gYXMubnVtZXJpYyhkaWZmdGltZShvZGluLmRhdGEkR1NNdGltZXN0YW1wLG9kaW4uZGF0YSRSVEN0aW1lc3RhbXAsdW5pdHMgPSAnc2VjcycpKQogIHRpbWVfY29ycmVjdGlvbi5hbGxbdGltZV9jb3JyZWN0aW9uLmFsbD09MF0gPC0gTkEKICB0aW1lX2RpZmYgPC0gbWVhbih0aW1lX2NvcnJlY3Rpb24uYWxsLG5hLnJtID0gVFJVRSkKCiAgIyBDYWxjdWxhdGUgdGhlICJyZWFsIiB0aW1lc3RhbXAgZm9yIHRoZSByZWNvcmRzCgogIG9kaW4uZGF0YSRkYXRlIDwtIG9kaW4uZGF0YSRSVEN0aW1lc3RhbXAgKyB0aW1lX2RpZmYKICBvZGluLmRhdGEgPC0gb2Rpbi5kYXRhWyxjKCdkYXRlJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQTTEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BNMi41JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQTTEwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUZW1wZXJhdHVyZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUkgnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ09ESU5zbicpXQoKICAjIENvbnN0cnVjdCB0aGUgQUxMREFUQSBmcmFtZQoKICBpZiAoaSA9PSAxKXsKICAgICMgVGhpcyBpcyB0aGUgZmlyc3QgaXRlcmF0aW9uIHNvIHdlIGp1c3QgY29weSB0aGUgIm9kaW4uZGF0YSIgZGF0YWZyYW1lCiAgICBhbGwuZGF0YSA8LSBvZGluLmRhdGEKICAgIGFsbC5kYXRhLnRhdmcgPC0gdGltZUF2ZXJhZ2Uob2Rpbi5kYXRhLGF2Zy50aW1lID0gdGF2ZykKICAgIGFsbC5kYXRhLnRhdmckT0RJTnNuIDwtIG9kaW4uZGF0YSRPRElOc25bMV0KICB9IGVsc2UgewogICAgIyBXZSBhbHJlYWR5IGhhdmUgImFsbC5kYXRhIiBzbyB3ZSBuZWVkIHRvIGFwcGVuZCB0aGUgY3VycmVudCAib2Rpbi5kYXRhIgogICAgYWxsLmRhdGEgPC0gcmJpbmQoYWxsLmRhdGEsb2Rpbi5kYXRhKQogICAgdG1wMSA8LSB0aW1lQXZlcmFnZShvZGluLmRhdGEsYXZnLnRpbWUgPSB0YXZnKQogICAgdG1wMSRPRElOc24gPC0gb2Rpbi5kYXRhJE9ESU5zblsxXQogICAgYWxsLmRhdGEudGF2ZyA8LSByYmluZChhbGwuZGF0YS50YXZnLHRtcDEpCiAgICAjIFJlbW92ZSBhbGwuZGF0YSB0byBjbGVhbiBmb3IgbmV4dCBpdGVyYXRpb24KICAgIHJtKG9kaW4uZGF0YSkKICB9Cn0KCiMnCiMnICBHZXQgZGV2aWNlcyBsb2NhdGlvbnMKIycgIApvZGluX2xvY2F0aW9ucyA8LSByZWFkcjo6cmVhZF9kZWxpbSgib2Rpbl9sb2NhdGlvbnMudHh0IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlx0IiwgZXNjYXBlX2RvdWJsZSA9IEZBTFNFLCB0cmltX3dzID0gVFJVRSkKbnNpdGVzIDwtIGxlbmd0aChvZGluX2xvY2F0aW9ucyRzZXJpYWxuKQphbGwuZGF0YSRsb24gPC0gMAphbGwuZGF0YSRsYXQgPC0gMAphbGwuZGF0YS50YXZnJGxvbiA8LSAwCmFsbC5kYXRhLnRhdmckbGF0IDwtIDAKZm9yIChqIGluICgxOm5zaXRlcykpewogIHByaW50KG9kaW5fbG9jYXRpb25zJHNlcmlhbG5bal0pCiAgbG9jX2lkIDwtIChzdWJzdHIoYWxsLmRhdGEkT0RJTnNuLDMsNik9PXN1YnN0cihvZGluX2xvY2F0aW9ucyRzZXJpYWxuW2pdLDcsMTEpKQogIGFsbC5kYXRhJGxvbltsb2NfaWRdIDwtIG9kaW5fbG9jYXRpb25zJGxvbltqXQogIGFsbC5kYXRhJGxhdFtsb2NfaWRdIDwtIG9kaW5fbG9jYXRpb25zJGxhdFtqXQogIGxvY19pZC50YXZnIDwtIChzdWJzdHIoYWxsLmRhdGEudGF2ZyRPRElOc24sMyw2KT09c3Vic3RyKG9kaW5fbG9jYXRpb25zJHNlcmlhbG5bal0sNywxMSkpCiAgYWxsLmRhdGEudGF2ZyRsb25bbG9jX2lkLnRhdmddIDwtIG9kaW5fbG9jYXRpb25zJGxvbltqXQogIGFsbC5kYXRhLnRhdmckbGF0W2xvY19pZC50YXZnXSA8LSBvZGluX2xvY2F0aW9ucyRsYXRbal0KfQojIFN1YnNldCBmb3IgdGhlIGNhbXBhaWduCnN0YXJ0X2RhdGUgPC1hcy5QT1NJWGN0KCIyMDE4LTA2LTIyIDEyOjAwOjAwIix0ej0iVVRDIikKZW5kX2RhdGUgPC1hcy5QT1NJWGN0KCIyMDE4LTA4LTE2IDEyOjAwOjAwIix0ej0iVVRDIikKbm1pbnV0ZXMgPC0gZGlmZnRpbWUoZW5kX2RhdGUsc3RhcnRfZGF0ZSx1bml0cyA9ICdtaW4nKQphbGwuZGF0YSA8LSBzdWJzZXQoYWxsLmRhdGEsIChkYXRlID49IHN0YXJ0X2RhdGUpICYgKGRhdGUgPD0gZW5kX2RhdGUpKQphbGwuZGF0YS50YXZnIDwtIHN1YnNldChhbGwuZGF0YS50YXZnLCAoZGF0ZSA+PSBzdGFydF9kYXRlKSAmIChkYXRlIDw9IGVuZF9kYXRlKSkKCiMnCiMnICMjIFN1bW1hcnkgc3RhdGlzdGljcwojJwojJ05vdGUgdGhhdCB0aGUgc3RhdGlzdGljcyBhcmUgY2FsY3VsYXRlZCBvbiAxMCBtaW51dGVzIGF2ZXJhZ2VzIGFuZCB0aGF0IHRoZSBjYW1wYWlnbgojJ3dlbnQgZnJvbSBKdW5lIDIybmQgMTI6MDAgVVRDIHVudGlsIEF1Z3VzdCAxNnRoIDEyOjAwIFVUQyAoNTUgZGF5cyBpbiB0b3RhbCkuCiMnCiMnVGhlIHVuaXRzIGZvciB0aGUgcGFyYW1ldGVycyBhcmU6CiMnICogUE1+Mi41fiBbJG11JGcvbV4zXl0KIycgKiBQTX4xMH4gWyRtdSRnL21eM15dCiMnICogVGVtcGVyYXR1cmUgW2NlbHNpdXNdCiMnICogUkggWyVdCiMnIAoKIyBDYWxjdWxhdGUgdGhlIHN1bW1hcnkgdGFibGUgZm9yIGVhY2ggdW5pdApzdW1tYXJ5X21lYW4gPC0gYWdncmVnYXRlKGNiaW5kKFRlbXBlcmF0dXJlLCBSSCxQTTIuNSwgUE0xMCkgfk9ESU5zbiwgYWxsLmRhdGEudGF2ZywgRlVOID0gbWVhbikKc3VtbWFyeV9tYXggPC0gYWdncmVnYXRlKGNiaW5kKFRlbXBlcmF0dXJlLCBSSCxQTTIuNSwgUE0xMCkgfk9ESU5zbiwgYWxsLmRhdGEudGF2ZywgRlVOID0gbWF4KQpzdW1tYXJ5X21pbiA8LSBhZ2dyZWdhdGUoY2JpbmQoVGVtcGVyYXR1cmUsIFJILFBNMi41LCBQTTEwKSB+T0RJTnNuLCBhbGwuZGF0YS50YXZnLCBGVU4gPSBtaW4pCnN1bW1hcnlfc2QgPC0gYWdncmVnYXRlKGNiaW5kKFRlbXBlcmF0dXJlLCBSSCxQTTIuNSwgUE0xMCkgfk9ESU5zbiwgYWxsLmRhdGEudGF2ZywgRlVOID0gc2QpCnN1bW1hcnlfTiA8LSBhZ2dyZWdhdGUoY2JpbmQoVGVtcGVyYXR1cmUsIFJILFBNMi41LCBQTTEwKSB+T0RJTnNuLCBhbGwuZGF0YS50YXZnLCBGVU4gPSBsZW5ndGgpCnN1bW1hcnlfcGN0IDwtIHN1bW1hcnlfTgpzdW1tYXJ5X3BjdFssMjo1XSA8LSBmb3JtYXQoMTAwICogKHN1bW1hcnlfTlssMjo1XSAvIChhcy5udW1lcmljKG5taW51dGVzKSAvIDEwKSksZGlnaXRzID0gMikKCiMnIAojJyAjIyBBdmVyYWdlIGNvbmNlbnRyYXRpb25zCiMnIApwcmludChmb3JtYXQoc3VtbWFyeV9tZWFuLGRpZ2l0cyA9IDEpKQojJyAKIycgIyMgTWF4aW11bSBjb25jZW50cmF0aW9ucwojJyAKcHJpbnQoZm9ybWF0KHN1bW1hcnlfbWF4LGRpZ2l0cyA9IDEpKQojJyAKIycgIyMgTWluaW11bSBjb25jZW50cmF0aW9ucwojJyAKcHJpbnQoZm9ybWF0KHN1bW1hcnlfbWluLGRpZ2l0cyA9IDEpKQojJyAKIycgIyMgU3RhbmRhcmQgZGV2aWF0aW9uCiMnIApwcmludChmb3JtYXQoc3VtbWFyeV9tZWFuLGRpZ2l0cyA9IDEpKQojJyAKIycgIyMgRGF0YSBhdmFpbGFiaWxpdHkgWyVdCiMnIApwcmludChmb3JtYXQoc3VtbWFyeV9wY3QsZGlnaXRzID0gMSkpCgojJwojJyAjIyBUaW1lIHNlcmllcwojJyAKCiMnCiMnICMjIyBQTX4yLjV+CiMnIApnZ3Bsb3QoZGF0YSA9IGFsbC5kYXRhLnRhdmcsIGFlcyh4PWRhdGUpKSArCiAgZ2VvbV9saW5lKGFlcyh5PVBNMi41LGNvbG91ciA9IE9ESU5zbikpCiMnCiMnICMjIyBQTX4xMH4KIycgCmdncGxvdChkYXRhID0gYWxsLmRhdGEudGF2ZywgYWVzKHg9ZGF0ZSkpICsKICBnZW9tX2xpbmUoYWVzKHk9UE0xMCxjb2xvdXIgPSBPRElOc24pKQojJwojJyAjIyMgVGVtcGVyYXR1cmUKIycgCmdncGxvdChkYXRhID0gYWxsLmRhdGEudGF2ZywgYWVzKHg9ZGF0ZSkpICsKICBnZW9tX2xpbmUoYWVzKHk9VGVtcGVyYXR1cmUsY29sb3VyID0gT0RJTnNuKSkKIycKIycgIyMjIFJlbGF0aXZlIEh1bWlkaXR5CiMnIApnZ3Bsb3QoZGF0YSA9IGFsbC5kYXRhLnRhdmcsIGFlcyh4PWRhdGUpKSArCiAgZ2VvbV9saW5lKGFlcyh5PVJILGNvbG91ciA9IE9ESU5zbikpCiMnCiMnICMjIyBNYWxmdW5jdGlvbmluZyBPRElOCiMnICBUaGUgcHJldmlvdXMgc3VtbWFyaWVzIHNob3cgdGhhdCBPRElOLTAwMDUgbWFsZnVuY3Rpb25lZCBzbyBpdCB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgYW5hbHlzaXMuCiMnICAKcmVtb3ZlX2lkeCA8LSAoYWxsLmRhdGEkT0RJTnNuID09ICJTRDAwMDUiKQphbGwuZGF0YVtyZW1vdmVfaWR4LF0gPC0gTkEKYWxsLmRhdGEgPC0gbmEuZXhjbHVkZShhbGwuZGF0YSkKcmVtb3ZlX2lkeCA8LSAoYWxsLmRhdGEudGF2ZyRPRElOc24gPT0gIlNEMDAwNSIpCmFsbC5kYXRhLnRhdmdbcmVtb3ZlX2lkeCxdIDwtIE5BCmFsbC5kYXRhLnRhdmcgPC0gbmEuZXhjbHVkZShhbGwuZGF0YS50YXZnKQoKIycKIycgIyMgQXZlcmFnZSBNYXBzCiMnIAojIFNvbWUgdXNlZnVsIGNvbnN0YW50cwpwcm9qNHN0cmluZ19OWlRNIDwtIENSUygnK2luaXQ9ZXBzZzoyMTkzJykKcHJvajRzdHJpbmdfbGF0bG9uIDwtIENSUygnK2luaXQ9ZXBzZzo0MzI2JykKIyBBc3NpZ24gY29vcmRpbmF0ZXMgdG8gdGhlIGRhdGFmcmFtZQpzdW1tYXJ5X21lYW5fbWFwIDwtIGFnZ3JlZ2F0ZShjYmluZChUZW1wZXJhdHVyZSwgUkgsIFBNMi41LCBQTTEwLCBsb24sIGxhdCkgfk9ESU5zbiwgYWxsLmRhdGEudGF2ZywgRlVOID0gbWVhbikKY29vcmRpbmF0ZXMoc3VtbWFyeV9tZWFuX21hcCkgPC0gfiBsb24gKyBsYXQKcHJvajRzdHJpbmcoc3VtbWFyeV9tZWFuX21hcCkgPC0gcHJvajRzdHJpbmdfbGF0bG9uCgojIEdldCB0aGUgYmFzZW1hcApjZW50cmVfbGF0IDwtIG1lYW4oc3VtbWFyeV9tZWFuX21hcCRsYXQpCmNlbnRyZV9sb24gPC0gbWVhbihzdW1tYXJ5X21lYW5fbWFwJGxvbikKY2EgPC0gZ2V0X21hcCgKICBjKGxvbj1jZW50cmVfbG9uLGxhdD1jZW50cmVfbGF0KSwKICB6b29tPTEzLGNyb3A9VCwKICBzY2FsZT0iYXV0byIsY29sb3I9ImJ3Iixzb3VyY2U9Imdvb2dsZSIsCiAgbWFwdHlwZT0idGVycmFpbiIpCgojJyAjIyMgUE1+Mi41fgpnZ21hcChjYSkgKyAKICBnZW9tX3BvaW50KGRhdGE9YXMuZGF0YS5mcmFtZShzdW1tYXJ5X21lYW5fbWFwKSxhZXMoeD1sb24seT1sYXQsY29sb3VyID0gUE0yLjUpLHNpemUgPSA1KSArCiAgc2NhbGVfY29sb3VyX2NvbnRpbnVvdXMobG93PSJ3aGl0ZSIsIGhpZ2g9InJlZCIsbGltaXRzPWMoMCwgbWF4KHN1bW1hcnlfbWVhbl9tYXAkUE0yLjUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIlBNMi41Iiwgb29iPXNxdWlzaCkKIycgIyMjIFBNfjEwfgpnZ21hcChjYSkgKyAKICBnZW9tX3BvaW50KGRhdGE9YXMuZGF0YS5mcmFtZShzdW1tYXJ5X21lYW5fbWFwKSxhZXMoeD1sb24seT1sYXQsY29sb3VyID0gUE0xMCksc2l6ZSA9IDUpICsKICBzY2FsZV9jb2xvdXJfY29udGludW91cyhsb3c9IndoaXRlIiwgaGlnaD0icmVkIixsaW1pdHM9YygwLCBtYXgoc3VtbWFyeV9tZWFuX21hcCRQTTEwKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJQTTEwIiwgb29iPXNxdWlzaCkKCiMnICMjIyBQTX5jb2Fyc2V+CmdnbWFwKGNhKSArIAogIGdlb21fcG9pbnQoZGF0YT1hcy5kYXRhLmZyYW1lKHN1bW1hcnlfbWVhbl9tYXApLGFlcyh4PWxvbix5PWxhdCxjb2xvdXIgPSBQTTEwIC0gUE0yLjUpLHNpemUgPSA1KSArCiAgc2NhbGVfY29sb3VyX2NvbnRpbnVvdXMobG93PSJ3aGl0ZSIsIGhpZ2g9InJlZCIsbGltaXRzPWMoMCwgbWF4KHN1bW1hcnlfbWVhbl9tYXAkUE0xMCAtIHN1bW1hcnlfbWVhbl9tYXAkUE0yLjUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gIlBNY29hcnNlIiwgb29iPXNxdWlzaCkKCgojIFNhdmUgdGhlICJhbGwuZGF0YSIgZGF0YWZyYW1lCnNhdmUoYWxsLmRhdGEsZmlsZSA9ICdhbGxkYXRhLlJEYXRhJykKc2F2ZShhbGwuZGF0YS50YXZnLGZpbGUgPSAnYWxsZGF0YVRBVkcuUkRhdGEnKQo=