Objective

Now that we have heat flux data we are ready to start fitting Hector runs to the ESM data! I started with the 24 models that had both temperature and heat flux data for each concentration driven experiment / ensemble member. I think that some of the results look promising but other fits are a bit um wonky.

library(gridExtra)
library(dplyr)
library(tidyr)
library(ggplot2)
library(rlist)
BASE_DIR <-  "/Users/dorh012/Documents/2019/hectorcal"
INPUT_DIR <- file.path(BASE_DIR, 'analysis', 'best_fit', 'temp-heat-1')
files <- list.files(INPUT_DIR, '.rds', full.names = TRUE) 
model_names <- gsub(pattern = '.rds', replacement = '', x = basename(files))    
    
comparison_plots <- lapply(files, function(input){
    
    x <- readRDS(input)
    
    if('message' %in% names(x)){
        
        NULL
    } else {
        
        x[[1]]
    }
    
    })
names(comparison_plots) <- model_names
did_not_converge <- model_names[which(unlist(lapply(comparison_plots, is.null)))]
comparison_plots <- list.clean(comparison_plots, fun = is.null)
residual_plots <- lapply(files, function(input){    
    x <- readRDS(input)
    
    if('message' %in% names(x)){
        
        NULL
    } else {
        
        x[[2]] 
    }})
names(residual_plots) <- model_names
residual_plots <- list.clean(residual_plots, fun = is.null)
MSE <- bind_rows(mapply(function(x, y){
    
    input <- readRDS(x)
    
    if('message' %in% names(input)){
        
        NULL
    } else {
        
        input[[3]] %>%  
            mutate(name = y)
    }}, x = files, y = model_names))
fit_params <- bind_rows(mapply(function(x, y){
    
    input <- readRDS(x)
   if('message' %in% names(input)){
        
        NULL
    } else {
        
       m <- matrix(input[[4]]$par, nrow = 1)  
       colnames(m) <- names(input[[4]]$par)
       tibble::as_tibble(m) %>% 
           bind_cols(value = input[[4]]$value, count = input[[4]]$counts[['function']]) %>% 
           mutate(name = y)
    }}, x = files, y = model_names))

Plot the residuals between the Hector and ESM data for heat flux for each model.

# Format the residual pltos to 
residual_plots %>% 
    lapply(function(input){
        
        input + 
            theme_bw(base_size = 10) + 
            theme(legend.position = 'none') + 
            labs(y = NULL, x = NULL) 
    }) -> 
    to_plot
grid.arrange(grobs = to_plot, ncol = 2)

Hmmm… so there are larger patterns in the residuals than I was expecting. Previously the only pattern we had seen in the residuals was that there was a greater spread in the residuals during the historical experiment that narrowed down in the future scenarios but was centered around 0. We still see that in some models (CCSM4) but then there is also all sorts of wonky behavior going on in the residuals for the other fits (FGOALS).


Comparison of the fits

# Format the residual pltos to 
comparison_plots %>% 
    lapply(function(input){
        
        other_model <- unique(pull(filter(input$data, model != 'hector'), model))
        
        colors <- c('grey', 'blue')
        names(colors) <- c(other_model, 'hector')
        
        alpha <- c(0, 1)
        names(alpha) <- c(other_model, 'hector')
        
        input + 
            theme_bw(base_size = 10) + 
            theme(legend.position = 'none') + 
            labs(y = NULL, x = NULL) + 
            scale_color_manual(values = colors) 
    }) -> 
    to_plot
grid.arrange(grobs = to_plot, ncol = 2)

Well it looks like we have some not so great fits. Like what is going on with incm4, I have no idea.

  1. Could Hector be struggling to capture the variability in the Heat Flux data that we don’t really expect for it to be able to capture?
  2. We had to reduce the number of experiments / ensemble members being used as comparison data so that there was parity for the heat flux and temperature data.

Should we include more temp data than heat flux data?


What do the paramters look like?

fit_params %>%
    gather(param, param_value, S, diff, alpha, volscl) -> 
    params_long
params_long %>% 
    dplyr::group_by(param) %>%  
    dplyr::summarise(min = min(param_value), 
              mean = mean(param_value), 
              max = max(param_value), 
              sd = sd(param_value)) %>% 
    knitr::kable(digits = 3) %>%  
    kableExtra::kable_styling(bootstrap_options = c("striped"))
param min mean max sd
alpha -21.462 -0.892 1.722 4.666
diff 0.996 104.819 1553.504 325.005
S 0.232 8.614 139.990 28.676
volscl -6.465 2.976 60.251 12.669

So it looks like we are still getting some unrealistic parameter values. I wonder if they are for the models that only contain the historical runs? Then I suspect that the heat flux data is unable to help resolve the issues of identifying S and diff.

# Determine which models only have historical data. 
MSE %>%
    separate(experiment, c("cmip_experiment", "ensemble"), sep = '_') %>%  
    mutate(model = gsub('conc_', '', name)) %>% 
    select(cmip_experiment, model) %>% 
    distinct %>% 
    mutate(historical = if_else(cmip_experiment == 'historical', 1, 0)) %>%  
    group_by(model) %>%  
    summarise(exp_count = n(), 
              historical = sum(historical)) %>%  
    filter(exp_count == 1 & historical == 1) %>% 
    select(model) %>% 
    mutate(only_history = TRUE) -> 
    history_id_tibble
params_long %>%  
        mutate(model = gsub('conc_', '', name)) %>% 
    left_join(history_id_tibble) -> 
    to_plot
ggplot(data = to_plot) + 
    geom_dotplot(aes(param_value, fill = only_history), stackgroups = TRUE, binpositions = "all") + 
    facet_wrap(~param, scales = 'free')

Hmmm that was not the pattern I was expecting.


Take Aways

Well we have both not so great parameter values and Hector fits. Do we want to increase the amount of temperature data being used in the fits? Do we want to limit heat flux comparison data to year 2100? Or do we want to smooth out the heat flux data so Hector is not being contorted to fit the peaks (I think that is where some of the off volscl and alpha values are coming from).

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgT2JqZWN0aXZlIAoKTm93IHRoYXQgd2UgaGF2ZSBoZWF0IGZsdXggZGF0YSB3ZSBhcmUgcmVhZHkgdG8gc3RhcnQgZml0dGluZyBIZWN0b3IgcnVucyB0byB0aGUgRVNNIGRhdGEhIEkgc3RhcnRlZCB3aXRoIHRoZSAyNCBtb2RlbHMgdGhhdCBoYWQgYm90aCB0ZW1wZXJhdHVyZSBhbmQgaGVhdCBmbHV4IGRhdGEgZm9yIGVhY2ggY29uY2VudHJhdGlvbiBkcml2ZW4gZXhwZXJpbWVudCAvIGVuc2VtYmxlIG1lbWJlci4gSSB0aGluayB0aGF0IHNvbWUgb2YgdGhlIHJlc3VsdHMgbG9vayBwcm9taXNpbmcgYnV0IG90aGVyIGZpdHMgYXJlIGEgYml0IHVtIHdvbmt5LiAKCmBgYHtyfQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJsaXN0KQoKQkFTRV9ESVIgPC0gICIvVXNlcnMvZG9yaDAxMi9Eb2N1bWVudHMvMjAxOS9oZWN0b3JjYWwiCklOUFVUX0RJUiA8LSBmaWxlLnBhdGgoQkFTRV9ESVIsICdhbmFseXNpcycsICdiZXN0X2ZpdCcsICd0ZW1wLWhlYXQtMScpCgoKZmlsZXMgPC0gbGlzdC5maWxlcyhJTlBVVF9ESVIsICcucmRzJywgZnVsbC5uYW1lcyA9IFRSVUUpIAptb2RlbF9uYW1lcyA8LSBnc3ViKHBhdHRlcm4gPSAnLnJkcycsIHJlcGxhY2VtZW50ID0gJycsIHggPSBiYXNlbmFtZShmaWxlcykpICAgIAogICAgCmNvbXBhcmlzb25fcGxvdHMgPC0gbGFwcGx5KGZpbGVzLCBmdW5jdGlvbihpbnB1dCl7CiAgICAKICAgIHggPC0gcmVhZFJEUyhpbnB1dCkKICAgIAogICAgaWYoJ21lc3NhZ2UnICVpbiUgbmFtZXMoeCkpewogICAgICAgIAogICAgICAgIE5VTEwKICAgIH0gZWxzZSB7CiAgICAgICAgCiAgICAgICAgeFtbMV1dCiAgICB9CiAgICAKICAgIH0pCm5hbWVzKGNvbXBhcmlzb25fcGxvdHMpIDwtIG1vZGVsX25hbWVzCgoKZGlkX25vdF9jb252ZXJnZSA8LSBtb2RlbF9uYW1lc1t3aGljaCh1bmxpc3QobGFwcGx5KGNvbXBhcmlzb25fcGxvdHMsIGlzLm51bGwpKSldCmNvbXBhcmlzb25fcGxvdHMgPC0gbGlzdC5jbGVhbihjb21wYXJpc29uX3Bsb3RzLCBmdW4gPSBpcy5udWxsKQoKCnJlc2lkdWFsX3Bsb3RzIDwtIGxhcHBseShmaWxlcywgZnVuY3Rpb24oaW5wdXQpeyAgICAKICAgIHggPC0gcmVhZFJEUyhpbnB1dCkKICAgIAogICAgaWYoJ21lc3NhZ2UnICVpbiUgbmFtZXMoeCkpewogICAgICAgIAogICAgICAgIE5VTEwKICAgIH0gZWxzZSB7CiAgICAgICAgCiAgICAgICAgeFtbMl1dIAogICAgfX0pCm5hbWVzKHJlc2lkdWFsX3Bsb3RzKSA8LSBtb2RlbF9uYW1lcwpyZXNpZHVhbF9wbG90cyA8LSBsaXN0LmNsZWFuKHJlc2lkdWFsX3Bsb3RzLCBmdW4gPSBpcy5udWxsKQoKCk1TRSA8LSBiaW5kX3Jvd3MobWFwcGx5KGZ1bmN0aW9uKHgsIHkpewogICAgCiAgICBpbnB1dCA8LSByZWFkUkRTKHgpCiAgICAKICAgIGlmKCdtZXNzYWdlJyAlaW4lIG5hbWVzKGlucHV0KSl7CiAgICAgICAgCiAgICAgICAgTlVMTAogICAgfSBlbHNlIHsKICAgICAgICAKICAgICAgICBpbnB1dFtbM11dICU+JSAgCiAgICAgICAgICAgIG11dGF0ZShuYW1lID0geSkKICAgIH19LCB4ID0gZmlsZXMsIHkgPSBtb2RlbF9uYW1lcykpCgoKZml0X3BhcmFtcyA8LSBiaW5kX3Jvd3MobWFwcGx5KGZ1bmN0aW9uKHgsIHkpewogICAgCiAgICBpbnB1dCA8LSByZWFkUkRTKHgpCgogICBpZignbWVzc2FnZScgJWluJSBuYW1lcyhpbnB1dCkpewogICAgICAgIAogICAgICAgIE5VTEwKICAgIH0gZWxzZSB7CiAgICAgICAgCiAgICAgICBtIDwtIG1hdHJpeChpbnB1dFtbNF1dJHBhciwgbnJvdyA9IDEpICAKICAgICAgIGNvbG5hbWVzKG0pIDwtIG5hbWVzKGlucHV0W1s0XV0kcGFyKQogICAgICAgdGliYmxlOjphc190aWJibGUobSkgJT4lIAogICAgICAgICAgIGJpbmRfY29scyh2YWx1ZSA9IGlucHV0W1s0XV0kdmFsdWUsIGNvdW50ID0gaW5wdXRbWzRdXSRjb3VudHNbWydmdW5jdGlvbiddXSkgJT4lIAogICAgICAgICAgIG11dGF0ZShuYW1lID0geSkKICAgIH19LCB4ID0gZmlsZXMsIHkgPSBtb2RlbF9uYW1lcykpCmBgYAoKCiMjIyBQbG90IHRoZSByZXNpZHVhbHMgYmV0d2VlbiB0aGUgSGVjdG9yIGFuZCBFU00gZGF0YSBmb3IgaGVhdCBmbHV4IGZvciBlYWNoIG1vZGVsLiAKCmBgYHtyLCBmaWcuaGVpZ2h0PTQwLCBmaWcud2lkdGg9MTB9CgojIEZvcm1hdCB0aGUgcmVzaWR1YWwgcGx0b3MgdG8gCnJlc2lkdWFsX3Bsb3RzICU+JSAKICAgIGxhcHBseShmdW5jdGlvbihpbnB1dCl7CiAgICAgICAgCiAgICAgICAgaW5wdXQgKyAKICAgICAgICAgICAgdGhlbWVfYncoYmFzZV9zaXplID0gMTApICsgCiAgICAgICAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgKyAKICAgICAgICAgICAgbGFicyh5ID0gTlVMTCwgeCA9IE5VTEwpIAogICAgfSkgLT4gCiAgICB0b19wbG90CgpncmlkLmFycmFuZ2UoZ3JvYnMgPSB0b19wbG90LCBuY29sID0gMikKYGBgCgoKSG1tbS4uLiBzbyB0aGVyZSBhcmUgbGFyZ2VyIHBhdHRlcm5zIGluIHRoZSByZXNpZHVhbHMgdGhhbiBJIHdhcyBleHBlY3RpbmcuIFByZXZpb3VzbHkgdGhlIG9ubHkgcGF0dGVybiB3ZSBoYWQgc2VlbiBpbiB0aGUgcmVzaWR1YWxzIHdhcyB0aGF0IHRoZXJlIHdhcyBhIGdyZWF0ZXIgc3ByZWFkIGluIHRoZSByZXNpZHVhbHMgZHVyaW5nIHRoZSBoaXN0b3JpY2FsIGV4cGVyaW1lbnQgdGhhdCBuYXJyb3dlZCBkb3duIGluIHRoZSBmdXR1cmUgc2NlbmFyaW9zIGJ1dCB3YXMgY2VudGVyZWQgYXJvdW5kIDAuIFdlIHN0aWxsIHNlZSB0aGF0IGluIHNvbWUgbW9kZWxzIChDQ1NNNCkgYnV0IHRoZW4gdGhlcmUgaXMgYWxzbyBhbGwgc29ydHMgb2Ygd29ua3kgYmVoYXZpb3IgZ29pbmcgb24gaW4gdGhlIHJlc2lkdWFscyBmb3IgdGhlIG90aGVyIGZpdHMgKEZHT0FMUykuCgo8YnI+CgoKIyMjIENvbXBhcmlzb24gb2YgdGhlIGZpdHMgCgpgYGB7ciwgZmlnLmhlaWdodD00MCwgZmlnLndpZHRoPTEwfQoKIyBGb3JtYXQgdGhlIHJlc2lkdWFsIHBsdG9zIHRvIApjb21wYXJpc29uX3Bsb3RzICU+JSAKICAgIGxhcHBseShmdW5jdGlvbihpbnB1dCl7CiAgICAgICAgCiAgICAgICAgb3RoZXJfbW9kZWwgPC0gdW5pcXVlKHB1bGwoZmlsdGVyKGlucHV0JGRhdGEsIG1vZGVsICE9ICdoZWN0b3InKSwgbW9kZWwpKQogICAgICAgIAogICAgICAgIGNvbG9ycyA8LSBjKCdncmV5JywgJ2JsdWUnKQogICAgICAgIG5hbWVzKGNvbG9ycykgPC0gYyhvdGhlcl9tb2RlbCwgJ2hlY3RvcicpCiAgICAgICAgCiAgICAgICAgYWxwaGEgPC0gYygwLCAxKQogICAgICAgIG5hbWVzKGFscGhhKSA8LSBjKG90aGVyX21vZGVsLCAnaGVjdG9yJykKICAgICAgICAKICAgICAgICBpbnB1dCArIAogICAgICAgICAgICB0aGVtZV9idyhiYXNlX3NpemUgPSAxMCkgKyAKICAgICAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArIAogICAgICAgICAgICBsYWJzKHkgPSBOVUxMLCB4ID0gTlVMTCkgKyAKICAgICAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9ycykgCiAgICB9KSAtPiAKICAgIHRvX3Bsb3QKCmdyaWQuYXJyYW5nZShncm9icyA9IHRvX3Bsb3QsIG5jb2wgPSAyKQpgYGAKCldlbGwgaXQgbG9va3MgbGlrZSB3ZSBoYXZlIHNvbWUgbm90IHNvIGdyZWF0IGZpdHMuIExpa2Ugd2hhdCBpcyBnb2luZyBvbiB3aXRoIGluY200LCBJIGhhdmUgbm8gaWRlYS4gCgoxLiBDb3VsZCBIZWN0b3IgYmUgc3RydWdnbGluZyB0byBjYXB0dXJlIHRoZSB2YXJpYWJpbGl0eSBpbiB0aGUgSGVhdCBGbHV4IGRhdGEgdGhhdCB3ZSBkb24ndCByZWFsbHkgZXhwZWN0IGZvciBpdCB0byBiZSBhYmxlIHRvIGNhcHR1cmU/CjIuIFdlIGhhZCB0byByZWR1Y2UgdGhlIG51bWJlciBvZiBleHBlcmltZW50cyAvIGVuc2VtYmxlIG1lbWJlcnMgYmVpbmcgdXNlZCBhcyBjb21wYXJpc29uIGRhdGEgc28gdGhhdCB0aGVyZSB3YXMgcGFyaXR5IGZvciB0aGUgaGVhdCBmbHV4IGFuZCB0ZW1wZXJhdHVyZSBkYXRhLiAKClNob3VsZCB3ZSBpbmNsdWRlIG1vcmUgdGVtcCBkYXRhIHRoYW4gaGVhdCBmbHV4IGRhdGE/IAoKPGJyPgoKIyMjIFdoYXQgZG8gdGhlIHBhcmFtdGVycyBsb29rIGxpa2U/CgpgYGB7cn0KZml0X3BhcmFtcyAlPiUKICAgIGdhdGhlcihwYXJhbSwgcGFyYW1fdmFsdWUsIFMsIGRpZmYsIGFscGhhLCB2b2xzY2wpIC0+IAogICAgcGFyYW1zX2xvbmcKCnBhcmFtc19sb25nICU+JSAKICAgIGRwbHlyOjpncm91cF9ieShwYXJhbSkgJT4lICAKICAgIGRwbHlyOjpzdW1tYXJpc2UobWluID0gbWluKHBhcmFtX3ZhbHVlKSwgCiAgICAgICAgICAgICAgbWVhbiA9IG1lYW4ocGFyYW1fdmFsdWUpLCAKICAgICAgICAgICAgICBtYXggPSBtYXgocGFyYW1fdmFsdWUpLCAKICAgICAgICAgICAgICBzZCA9IHNkKHBhcmFtX3ZhbHVlKSkgJT4lIAogICAga25pdHI6OmthYmxlKGRpZ2l0cyA9IDMpICU+JSAgCiAgICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIpKQpgYGAKClNvIGl0IGxvb2tzIGxpa2Ugd2UgYXJlIHN0aWxsIGdldHRpbmcgc29tZSB1bnJlYWxpc3RpYyBwYXJhbWV0ZXIgdmFsdWVzLiBJIHdvbmRlciBpZiB0aGV5IGFyZSBmb3IgdGhlIG1vZGVscyB0aGF0IG9ubHkgY29udGFpbiB0aGUgaGlzdG9yaWNhbCBydW5zPyBUaGVuIEkgc3VzcGVjdCB0aGF0IHRoZSBoZWF0IGZsdXggZGF0YSBpcyB1bmFibGUgdG8gaGVscCByZXNvbHZlIHRoZSBpc3N1ZXMgb2YgaWRlbnRpZnlpbmcgUyBhbmQgZGlmZi4gCgoKYGBge3IsIG1lc3NhZ2UgPSBGQUxTRX0KIyBEZXRlcm1pbmUgd2hpY2ggbW9kZWxzIG9ubHkgaGF2ZSBoaXN0b3JpY2FsIGRhdGEuIApNU0UgJT4lCiAgICBzZXBhcmF0ZShleHBlcmltZW50LCBjKCJjbWlwX2V4cGVyaW1lbnQiLCAiZW5zZW1ibGUiKSwgc2VwID0gJ18nKSAlPiUgIAogICAgbXV0YXRlKG1vZGVsID0gZ3N1YignY29uY18nLCAnJywgbmFtZSkpICU+JSAKICAgIHNlbGVjdChjbWlwX2V4cGVyaW1lbnQsIG1vZGVsKSAlPiUgCiAgICBkaXN0aW5jdCAlPiUgCiAgICBtdXRhdGUoaGlzdG9yaWNhbCA9IGlmX2Vsc2UoY21pcF9leHBlcmltZW50ID09ICdoaXN0b3JpY2FsJywgMSwgMCkpICU+JSAgCiAgICBncm91cF9ieShtb2RlbCkgJT4lICAKICAgIHN1bW1hcmlzZShleHBfY291bnQgPSBuKCksIAogICAgICAgICAgICAgIGhpc3RvcmljYWwgPSBzdW0oaGlzdG9yaWNhbCkpICU+JSAgCiAgICBmaWx0ZXIoZXhwX2NvdW50ID09IDEgJiBoaXN0b3JpY2FsID09IDEpICU+JSAKICAgIHNlbGVjdChtb2RlbCkgJT4lIAogICAgbXV0YXRlKG9ubHlfaGlzdG9yeSA9IFRSVUUpIC0+IAogICAgaGlzdG9yeV9pZF90aWJibGUKCnBhcmFtc19sb25nICU+JSAgCiAgICAgICAgbXV0YXRlKG1vZGVsID0gZ3N1YignY29uY18nLCAnJywgbmFtZSkpICU+JSAKICAgIGxlZnRfam9pbihoaXN0b3J5X2lkX3RpYmJsZSkgLT4gCiAgICB0b19wbG90CgpnZ3Bsb3QoZGF0YSA9IHRvX3Bsb3QpICsgCiAgICBnZW9tX2RvdHBsb3QoYWVzKHBhcmFtX3ZhbHVlLCBmaWxsID0gb25seV9oaXN0b3J5KSwgc3RhY2tncm91cHMgPSBUUlVFLCBiaW5wb3NpdGlvbnMgPSAiYWxsIikgKyAKICAgIGZhY2V0X3dyYXAofnBhcmFtLCBzY2FsZXMgPSAnZnJlZScpCgpgYGAKCkhtbW0gdGhhdCB3YXMgbm90IHRoZSBwYXR0ZXJuIEkgd2FzIGV4cGVjdGluZy4gCgoKPGJyPgoKIyMjIFRha2UgQXdheXMgCgpXZWxsIHdlIGhhdmUgYm90aCBub3Qgc28gZ3JlYXQgcGFyYW1ldGVyIHZhbHVlcyBhbmQgSGVjdG9yIGZpdHMuIERvIHdlIHdhbnQgdG8gaW5jcmVhc2UgdGhlIGFtb3VudCBvZiB0ZW1wZXJhdHVyZSBkYXRhIGJlaW5nIHVzZWQgaW4gdGhlIGZpdHM/IERvIHdlIHdhbnQgdG8gbGltaXQgaGVhdCBmbHV4IGNvbXBhcmlzb24gZGF0YSB0byB5ZWFyIDIxMDA/IE9yIGRvIHdlIHdhbnQgdG8gc21vb3RoIG91dCB0aGUgaGVhdCBmbHV4IGRhdGEgc28gSGVjdG9yIGlzIG5vdCBiZWluZyBjb250b3J0ZWQgdG8gZml0IHRoZSBwZWFrcyAoSSB0aGluayB0aGF0IGlzIHdoZXJlIHNvbWUgb2YgdGhlIG9mZiB2b2xzY2wgYW5kIGFscGhhIHZhbHVlcyBhcmUgY29taW5nIGZyb20pLgo=