ODIN data

The unit ODIN_01 was deployed at Coles place between the 24\(^{th}\) of May and the 3\(^{rd}\) of June 2014.

odin_01 <- read.table("~/data/ODIN_data/christchurch/ODIN_01/odin_01.txt", header=T, quote="")
#force GMT as the time zone to avoid openair issues with daylight saving switches
#The actual time zone is 'NZST'
odin_01$date=as.POSIXct(paste(odin_01$Date,odin_01$Time),tz='GMT')
odin_01$Time<-NULL
odin_01$Date<-NULL
odin_01$Battery<-5*odin_01$Battery/1024

ECan data

The data from the Coles Place site was obtained from Environment Canterbury through Teresa Aberkane.

ecan_data <- read.delim("~/data/ODIN_data/christchurch/ecan_data20140603.txt",
                        quote="")
ecan_data$date<-as.POSIXct(ecan_data$date,tz='GMT')

Merging the data

ECan’s data was provided as 10 minute values while ODIN reports every 1 minute so before merging the data, the timebase must be homogenized

odin_01.10min<-timeAverage(odin_01,avg.time='10 min')
all_merged<-merge(odin_01.10min,ecan_data,by='date',all=TRUE)
names(all_merged)<-c('date','Dust.01','Humidity.01','Temperature.01',
                         'Battery.01', 'CO','PM10_fdms','PM2.5_fdms',
                         'BC','uvBC','pm10_sharp','Temperature_1m',
                         'Temperature_10m','RH')

Time sync

lag_test=ccf(all_merged$Temperature.01,all_merged$Temperature_1m,na.action=na.pass,lag.max=1000,type='correlation',ylab='Correlation',main='Temperature correlation as function of clock lag')

plot of chunk time_sync

odin01_lag=lag_test$lag[which.max(lag_test$acf)]

Battery life and solar charging

The current solar panel arrangement of ODIN does allow for a full recovery of the battery during daytime but the deployment life of the unit is still uncertain.
plot of chunk unnamed-chunk-1

ODIN T and RH comparison

Temperature

timePlot(all_merged,pollutant = c('Temperature.01','Temperature_1m'),
         group=TRUE)

plot of chunk unnamed-chunk-2

Relative Humidity

timePlot(all_merged,pollutant = c('Humidity.01','RH'),group=TRUE)

plot of chunk rh

Dust performance using ECan data for calibration

With ECan’s PM10 data available, a more accurate calibration can be applied to the raw Dust signal from ODIN.

First the data was divided in one training set (70% of observations) and validation set (30% of observations).

set.seed(50)
data_selector<-rbinom(length(all_merged$date),1,0.7)
training_10min=all_merged[data_selector==1,]
validation_10min=all_merged[data_selector==0,]

Training a linear model for the data:

odin1.lm.calib<-lm(data=training_10min,PM10_fdms~Dust.01+Temperature.01)
summary(odin1.lm.calib)
## 
## Call:
## lm(formula = PM10_fdms ~ Dust.01 + Temperature.01, data = training_10min)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -63.71 -12.67  -3.03  10.74  70.85 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -439.3347    10.2651   -42.8   <2e-16 ***
## Dust.01           1.1064     0.0229    48.3   <2e-16 ***
## Temperature.01   -3.8597     0.0765   -50.5   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.6 on 1023 degrees of freedom
##   (105 observations deleted due to missingness)
## Multiple R-squared:  0.755,  Adjusted R-squared:  0.754 
## F-statistic: 1.58e+03 on 2 and 1023 DF,  p-value: <2e-16
Parameter ODIN_1
Intercept -439 \(\pm\) 20.1
Slope Temperature -3.86 \(\pm\) 0.15
Slope Raw Dust 1.11 \(\pm\) 0.045

Applying the calibration function to the raw dust data:

all_merged$Dust.01.corr.2<-int1 +
  slp1T*all_merged$Temperature.01 +
  slp1D*all_merged$Dust.01

Now quantifying the errors in the calibration:

validation_10min$Dust.01.corr.2<-int1 +
  slp1T*validation_10min$Temperature.01 +
  slp1D*validation_10min$Dust.01
me_01<-mean(validation_10min$Dust.01.corr.2 - validation_10min$PM10_fdms,
            na.rm = TRUE)
rmse_01<-(mean((validation_10min$Dust.01.corr.2 - validation_10min$PM10_fdms)^2,
               na.rm = TRUE))^0.5
rse_01<-mean((validation_10min$Dust.01.corr.2 - validation_10min$PM10_fdms)^2,
             na.rm = TRUE) / 
  mean((mean(validation_10min$PM10_fdms,na.rm = TRUE) - 
          validation_10min$PM10_fdms)^2,na.rm = TRUE)
rsq_01<-1-rse_01
Indicator ODIN_1
Mean Error -0.751
Root Mean Squared Error 16.8
R\(^2\) 0.76
timeVariation(all_merged,pollutant=c('Dust.01.corr.2',
                                     'PM10_fdms',
                                     'PM2.5_fdms'),
              ylab='PM [ug/m3]')

plot of chunk plot_comparison

timePlot(all_merged,pollutant=c('Dust.01.corr.2',
                                'PM10_fdms',
                                'PM2.5_fdms'),
         group=TRUE,avg.time='60 min',ylab='PM [ug/m3]')

plot of chunk plot_comparison

timePlot(all_merged,pollutant=c('Dust.01.corr.2',
                                'BC',
                                'uvBC'),
         group=TRUE,avg.time='60 min',ylab='PM, BC [ug/m3]')

plot of chunk plot_comparison