Bias correction techniques in general require observational data to compare with climate projections in order to appropriately correct the bias.
-
The HadUK grid is a 1km x 1km gridded dataset derived from meterological station observations.
-
The first UKCP product for review is the UCKP convection-permitting dataset, on a 2.2km grid. Therefore, we are resmapling the 1km grid using bilenear interpolation to 2.2km grid extent.
-
We have ran this seperately in both r and python. The aim of this doc is to:
-
-
Ensure both methods produce the same result
-
Ensure the grid has been resampled to the correct extent and CRS
-
-
-
-
1.21. Data
-
-
1.2.11a. HadUK grid resampled in R
-
Resampling script here The 2.2km grid was derived from a reprojected (to BNG) UKCP 2.2km .nc file
-
In resampling it resampled the Sea as xx so replacing those vals as NA
-
r1 <-paste0(dd,"TestData.R-python/Resampled_HADs_tasmax.2000.01.tif")
-r1 <-rast(r1)#Contains 31 layers for each day of Jan
-
-#In the resampling, the method used seemed to have relable all Sea values as '1.000000e+20' so relabelling them here (but to be checked as to why they've been valued like this in the resampling)
-r1[r1 >200] =NA
-
-#check the crs
-crs(r1, proj=T)
-## [1] "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +a=6377563.396 +rf=299.324961266495 +units=m +no_defs"
-
-#Plot to check
-plot(r1$tasmax_1)
Ok there are some differences that I can see from the plot between the two resampled files!
-
## Cropping to a small area to compare with the same orginal HADS file
-i <-rast()
-ext(i) <-c(200000, 210000, 700000, 710000)
-
r1_ci <-crop(r1_c, i)
-plot(r1_ci$tasmax_1)
-
-
#Get number of cells in cropped extent
-cells <-cells(r1_ci)
-
-#get coords for all cells (for comparing above)
-r.reproj_c_xy <-sapply(cells, function(i){xyFromCell(r1_ci, i)})
-
-r.reproj_c_xy
#Get number of cells in cropped extent
-cells <-cells(ukcp_c)
-
-#get coords for all cells (for comparing above)
-ukcp_c_xy <-sapply(cells, function(i){xyFromCell(ukcp_c, i)})
-
-ukcp_c_xy
## Warning in all(ukcp_c_xy, r.reproj_c_xy): coercing argument of type 'double' to
-## logical
-
-## Warning in all(ukcp_c_xy, r.reproj_c_xy): coercing argument of type 'double' to
-## logical
-
-## [1] TRUE
Script to identify the mean, 2nd highest and 2nd lowers daily tasmax per UKCP18 CPM run.
-
These runs will be the focus of initial bias correction focus
-
-
-
1.21. Load Data
-
Data is tasmax runs converted to dataframe using sript ‘ConvertingAllCPMdataTOdf.R’, with files later renamed.Then daily means for historical periods and future periods were calculated using ‘calc.mean.sd.daily.R’ and summaries saved as .csv
Update 13.05.23 - Adding in infill data, mean to be calculated over the whole time period
-
As of June 2023, the tasmax-as-dataframe and tasmax daily means and the df data is located in vmfileshare/Interim/tasmax_dfs/
-
There is an error in the naming convention - Y00_Y20 should be Y01 to reflect the infill data time period (although this does cover a breif period of 2000) - to be updated in future
Y <-rep(c(1981:2000), each=360)
-
-dfs_hist <-lapply(names_hist, function(i){
- df <- dfs_hist[[i]]
-names(df) <-c("day", "mean", "sd")
- df$model <- i
- df$dn <-1:nrow(df)
- df$Y <- Y
-return(df)
-})
-
-#Create a single df in long form of Runs for the historical period
-historical_means <- dfs_hist %>%reduce(rbind)
#Create a pallete specific to the runs so when reordered maintain the same colours
-historical_means$model <-as.factor(historical_means$model)
-c <-brewer.pal(12, "Paired")
-my_colours <-setNames(c, levels(historical_means$model))
ggplot(historical_max_y) +
-geom_line(aes(x =as.numeric(Yf), y=max,
-color=model)) +
-theme_bw() +xlab("Year (Historical 1980 - 2000)") +
-ylab("Annual max of mean daily max temp (tasmax) oC") +
-scale_fill_brewer(palette ="Paired", name ="") +
-scale_colour_brewer(palette ="Paired", name ="") +
-theme(axis.text.x=element_blank(),
-axis.ticks.x=element_blank())
-
-
-
-
1.3.9boxplot - annual max
-
historical_max_y %>%
-mutate(model =fct_reorder(model, max, .fun='median')) %>%
-ggplot(aes(x=reorder(model, max), y=max, fill=model)) +
-geom_boxplot() +theme_bw() +
-ylab("Annual max of mean daily max temp (tasmax) oC") +xlab("model") +
-scale_fill_manual(values = my_colours) +
-theme(axis.text.x=element_blank(),
-axis.ticks.x=element_blank())
-
-
The daily max is quite different than the means - something to bear in mind but interesting to think about - eg Run 4 here has the 2nd lowest spread of max max temp, but is selected above based on means
-
-
-
1.3.10ANOVA
-
Daily means:
-
#-1 removes the intercept to compare coefficients of all Runs
-av1 <-aov(mean ~ model -1, historical_means)
-av1$coefficients[order(av1$coefficients)]
Max vals are different but based on means then selection would be Run 02 (2nd lowest), Run 04 & Run 03, and Run 11 (2nd lowest)
-
-
-
1.3.112b. Y2020 - Y2040
-
Y <-rep(c(2021:2040), each=360)
-
-
-dfs_Y21_Y40 <-lapply(names_Y21_Y40, function(i){
- df <- dfs_Y21_Y40[[i]]
-names(df) <-c("day", "mean", "sd")
- df$model <- i
- df$dn <-1:nrow(df)
- df$Y <- Y
-return(df)
-})
-
-#Create a single df in long form of Runs for the Y21_Y40 period
-Y21_Y40_means <- dfs_Y21_Y40 %>%reduce(rbind)
-
-
-
1.3.12Time series - daily
-
ggplot(Y21_Y40_means) +
-geom_line(aes(x=dn, y=mean, group=model, colour=model)) +
-# Removing sd ribbon for ease of viewing
-#geom_ribbon(aes(x =dn, ymin = mean - sd, ymax= mean + sd), alpha=0.4) +
-theme_bw() +xlab("Daily (1980 - 2000)") +
-ylab("Daily mean max temp (tasmax) oC") +
-#scale_fill_brewer(palette = "Paired", name = "") +
-scale_colour_brewer(palette ="Paired", name ="") +
-theme(axis.text.x=element_blank(),
-axis.ticks.x=element_blank(),
-legend.position ="none") +
-facet_wrap(.~ model, ncol=3) +guides(fill =FALSE)
-
## Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as
-## of ggplot2 3.3.4.
-## This warning is displayed once every 8 hours.
-## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
-## generated.
-
-
-
-
1.3.13boxplot - mean Y21_Y40
-
#Create a pallete specific to the runs so when reordered maintain the same colours
-Y21_Y40_means$model <-as.factor(Y21_Y40_means$model)
-c <-brewer.pal(12, "Paired")
-my_colours <-setNames(c, levels(Y21_Y40_means$model))
Based on means then selection would be Run 02 (2nd lowest), Run 04 & Run 03, and Run 11 (2nd lowest)
-
Based on this period, the seelction would be: Run 05, Run 03, Run 08, Run 06 (so definetly Run 3 but others to be discussed)
-
-
-
1.3.212c. Y2061 - Y2080
-
Y <-rep(c(2061:2080), each=360)
-
-
-dfs_Y61_Y80 <-lapply(names_Y61_Y80, function(i){
- df <- dfs_Y61_Y80[[i]]
-names(df) <-c("day", "mean", "sd")
- df$model <- i
- df$dn <-1:nrow(df)
- df$Y <- Y
-return(df)
-})
-
-#Create a single df in long form of Runs for the Y61_Y80 period
-Y61_Y80_means <- dfs_Y61_Y80 %>%reduce(rbind)
-
-
-
1.3.22Time series - daily
-
ggplot(Y61_Y80_means) +
-geom_line(aes(x=dn, y=mean, group=model, colour=model)) +
-# Removing sd ribbon for ease of viewing
-#geom_ribbon(aes(x =dn, ymin = mean - sd, ymax= mean + sd), alpha=0.4) +
-theme_bw() +xlab("Day (2060 - 2080)") +
-ylab("Daily mean max temp (tasmax) oC") +
-#scale_fill_brewer(palette = "Paired", name = "") +
-scale_colour_brewer(palette ="Paired", name ="") +
-theme(axis.text.x=element_blank(),
-axis.ticks.x=element_blank(),
-legend.position ="none") +
-facet_wrap(.~ model, ncol=3) +guides(fill =FALSE)
-
-
-
-
1.3.23boxplot - mean Y61_Y80
-
#Create a pallete specific to the runs so when reordered maintain the same colours
-Y61_Y80_means$model <-as.factor(Y61_Y80_means$model)
-c <-brewer.pal(12, "Paired")
-my_colours <-setNames(c, levels(Y61_Y80_means$model))
# As above, creating annual means
-infill.L <-list(Y00_Y20_means, Y41_Y60_means)
-
-infill.L_y <-lapply(infill.L, function(x){
- means_y <- x %>%
-group_by(Yf, model) %>%
- dplyr::summarise(mean.annual=mean(mean, na.rm=T), sd.annual=sd(mean, na.rm = T))})
-
## `summarise()` has grouped output by 'Yf'. You can override using the `.groups`
-## argument.
-## `summarise()` has grouped output by 'Yf'. You can override using the `.groups`
-## argument.