| 1 | #Step 1 Source files and load data |
|---|
| 2 | source('BuildEmulator/BuildEmulator.R') |
|---|
| 3 | source("BuildEmulator/DannyDevelopment.R") |
|---|
| 4 | source("BuildEmulator/JamesNewDevelopment.R") |
|---|
| 5 | library("ncdf4") # to manipulate ncdf |
|---|
| 6 | #load("Demonstrations/TnSReal.RData") |
|---|
| 7 | |
|---|
| 8 | ######################### |
|---|
| 9 | # First settings |
|---|
| 10 | |
|---|
| 11 | case_name="AYOTTE" |
|---|
| 12 | subcase_name="24SC" |
|---|
| 13 | variable="theta" # qv ou rneb # Don't use "var" which is un R function !!! |
|---|
| 14 | |
|---|
| 15 | WAVEN=1 |
|---|
| 16 | |
|---|
| 17 | source('htune_case_setup.R') |
|---|
| 18 | file = paste("WAVE",WAVEN,"/Wave",WAVEN,".RData",sep="") |
|---|
| 19 | load(file) |
|---|
| 20 | |
|---|
| 21 | casesu <-case_setup(case_name) |
|---|
| 22 | NLES=casesu[1] |
|---|
| 23 | TimeLES=casesu[2] |
|---|
| 24 | TimeSCM=casesu[3] |
|---|
| 25 | |
|---|
| 26 | NRUNS=dim(wave_param_US)[1] |
|---|
| 27 | nparam=dim(wave_param_US)[2]-1 |
|---|
| 28 | |
|---|
| 29 | ######################### |
|---|
| 30 | # Get vertical grid to project everything |
|---|
| 31 | print("Get vertical grid") |
|---|
| 32 | |
|---|
| 33 | file=paste("WAVE",WAVEN,"/",case_name,"/",subcase_name,"/SCM_",WAVEN,"-001.nc",sep="") |
|---|
| 34 | print(file) |
|---|
| 35 | nc = nc_open(file) |
|---|
| 36 | zf = ncvar_get(nc,"zf") |
|---|
| 37 | zfSCM = zf[,1] |
|---|
| 38 | nlev = length(zfSCM) |
|---|
| 39 | nc_close(nc) |
|---|
| 40 | |
|---|
| 41 | # Get vertical grid of LES |
|---|
| 42 | file = paste("LES/",case_name,"/",subcase_name,"/LES",0,".nc",sep="") |
|---|
| 43 | nc = nc_open(file) |
|---|
| 44 | zfLES = ncvar_get(nc,"zf") |
|---|
| 45 | nc_close(nc) |
|---|
| 46 | |
|---|
| 47 | # Extract the SCM vertical below the top of the LES |
|---|
| 48 | zgrid = rep(0,nlev) |
|---|
| 49 | ii = 1 |
|---|
| 50 | maxzLES = max(zfLES) |
|---|
| 51 | minzLES = min(zfLES) |
|---|
| 52 | for (k in 1:nlev) { |
|---|
| 53 | if ( zfSCM[k] <= maxzLES & zfSCM[k] >= minzLES ) { |
|---|
| 54 | zgrid[ii] = zfSCM[k] |
|---|
| 55 | ii = ii +1 |
|---|
| 56 | } |
|---|
| 57 | } |
|---|
| 58 | zgrid=zgrid[1:ii-1] |
|---|
| 59 | nlevout = length(zgrid)[1] |
|---|
| 60 | |
|---|
| 61 | print("Chosen vertical grid:") |
|---|
| 62 | print(zgrid) |
|---|
| 63 | |
|---|
| 64 | ######################### |
|---|
| 65 | # Interpolate LES data on the chosen vertical grid |
|---|
| 66 | print("Interpolate LES data on the chosen vertical grid") |
|---|
| 67 | |
|---|
| 68 | dataLES = matrix(0,ncol=NLES+2,nrow=nlevout) |
|---|
| 69 | dataLES[,1] = zgrid |
|---|
| 70 | |
|---|
| 71 | for ( k in 0:(NLES-1) ) { |
|---|
| 72 | file = paste("LES/",case_name,"/",subcase_name,"/LES",k,".nc",sep="") |
|---|
| 73 | nc = nc_open(file) |
|---|
| 74 | zf = ncvar_get(nc,"zf") |
|---|
| 75 | data = ncvar_get(nc,variable) |
|---|
| 76 | nc_close(nc) |
|---|
| 77 | |
|---|
| 78 | tempFun <- approxfun(zf,data[,TimeLES],yleft=data[1,TimeLES]) |
|---|
| 79 | dataLES[,k+2] <- tempFun(zgrid) |
|---|
| 80 | |
|---|
| 81 | if ( k == 0 ) { |
|---|
| 82 | # Check the interpolation |
|---|
| 83 | plot(x=dataLES[,k+2],y=dataLES[,1],type='l') |
|---|
| 84 | lines(x=data[,TimeLES],y=zf,col="red") |
|---|
| 85 | } |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | # Compute observation uncertainty |
|---|
| 89 | for ( k in 1:nlevout ) { |
|---|
| 90 | dataLES[k,NLES+2] = sd(dataLES[k,2:NLES+1])^2 |
|---|
| 91 | } |
|---|
| 92 | |
|---|
| 93 | save(dataLES,file="dataLES.RData") |
|---|
| 94 | load("dataLES.RData") |
|---|
| 95 | |
|---|
| 96 | ######################### |
|---|
| 97 | # Interpolate SCM data on the chosen vertical grid |
|---|
| 98 | print("Interpolate SCM data on the chosen vertical grid") |
|---|
| 99 | |
|---|
| 100 | dataSCM = matrix(0,ncol=NRUNS+1,nrow=nlevout) |
|---|
| 101 | dataSCM[,1] = zgrid |
|---|
| 102 | |
|---|
| 103 | for ( k in 1:NRUNS ) { |
|---|
| 104 | i = sprintf("%03i",k) |
|---|
| 105 | file=paste("WAVE",WAVEN,"/",case_name,"/",subcase_name,"/SCM_",WAVEN,"-",i,".nc",sep="") |
|---|
| 106 | nc = nc_open(file) |
|---|
| 107 | zf = ncvar_get(nc,"zf") |
|---|
| 108 | data = ncvar_get(nc,variable) |
|---|
| 109 | nc_close(nc) |
|---|
| 110 | nlev = dim(zf)[1] |
|---|
| 111 | |
|---|
| 112 | # yright, yleft to constrain what happen at the edge. Not clear yet how to do it properly |
|---|
| 113 | tempFun <- approxfun(zf[,TimeSCM],data[,TimeSCM],yright=data[1,TimeSCM],yleft=data[nlev,TimeSCM]) |
|---|
| 114 | dataSCM[,k+1] <- tempFun(zgrid) |
|---|
| 115 | |
|---|
| 116 | if ( k == 0 ) { |
|---|
| 117 | # Check the interpolation |
|---|
| 118 | plot(x=dataSCM[,k+2],y=dataSCM[,1],type='l') |
|---|
| 119 | lines(x=data[,TimeSCM],y=zf,col="red") |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | } |
|---|
| 123 | |
|---|
| 124 | save(dataSCM,file="dataSCM.RData") |
|---|
| 125 | load("dataSCM.RData") |
|---|
| 126 | |
|---|
| 127 | # For memory yet |
|---|
| 128 | #nt=dim(data)[2] |
|---|
| 129 | #dataout = matrix(0,ncol=nt,nrow=nlevout) |
|---|
| 130 | #for ( it in 1:nt){ |
|---|
| 131 | # tempFun <- approxfun(zf,data[,it],yleft=data[1,it]) |
|---|
| 132 | # dataout[,it] <- tempFun(zgrid) |
|---|
| 133 | #} |
|---|
| 134 | |
|---|
| 135 | #load("Demonstrations/TSensembleNW1.RData") |
|---|
| 136 | plot(x=dataLES[,2],y=dataLES[,1],type='l',lwd=2,col=2,xlab=variable,ylab="Altitude") |
|---|
| 137 | depths <- dataLES[,1] |
|---|
| 138 | for(j in 1:NRUNS){ |
|---|
| 139 | lines(x=dataSCM[,j],y=depths,col=8,lwd=0.5) |
|---|
| 140 | } |
|---|
| 141 | lines(x=dataLES[,2],y=dataLES[,1],lwd=2,col=2) |
|---|
| 142 | #Step 2 Extract the fields you want |
|---|
| 143 | SCMdata <- dataSCM[,-1] |
|---|
| 144 | #ORCA2Data <- t(as.matrix(tData[,23:52])) |
|---|
| 145 | #dim(ORCA2Data) |
|---|
| 146 | |
|---|
| 147 | #Step 3: Centre the data and find the Singular vectors (EOFs) |
|---|
| 148 | SCMsvd <- CentreAndBasis(SCMdata) |
|---|
| 149 | par(mfrow=c(3,3)) |
|---|
| 150 | for ( i in 1:9 ) { |
|---|
| 151 | plot(x=SCMsvd$tBasis[,i],y=dataSCM[,1],type='l') |
|---|
| 152 | } |
|---|
| 153 | |
|---|
| 154 | #Step 4: Set a discrepancy variance and check the performance of basis reconstructions |
|---|
| 155 | # To be thought about |
|---|
| 156 | tmp = rep(0.01,nlevout) |
|---|
| 157 | #for ( i in 1:nlevout ) { |
|---|
| 158 | # if ( dataSCM[i,1] >= 2500. ) {tmp[i] = 1} |
|---|
| 159 | #} |
|---|
| 160 | |
|---|
| 161 | #for ( i in 1:nlevout ) { |
|---|
| 162 | # if ( dataSCM[i,1] >= 2000. ) {tmp[i] = 0.1} |
|---|
| 163 | #} |
|---|
| 164 | |
|---|
| 165 | #Disc <- diag(0.01,nlevout) |
|---|
| 166 | Disc <- diag(tmp) |
|---|
| 167 | DiscInv <- GetInverse(Disc) |
|---|
| 168 | attributes(DiscInv) |
|---|
| 169 | ObsDat <- dataLES[,2] - SCMsvd$EnsembleMean |
|---|
| 170 | par(mfrow=c(1,2), mar = c(4,4,2,4)) |
|---|
| 171 | vSVD <- VarMSEplot(SCMsvd, ObsDat, weightinv = DiscInv, ylim = c(0,80), qmax = NULL) |
|---|
| 172 | abline(v = which(vSVD[,2] > 0.9)[1]) |
|---|
| 173 | |
|---|
| 174 | #Step 5: Rotate the basis for optimal calibration |
|---|
| 175 | rotSCM <- RotateBasis(SCMsvd, ObsDat, kmax = 4, weightinv = DiscInv, v = c(0.3,0.15,0.1,0.1,0.1), vtot = 0.95, MaxTime = 20) |
|---|
| 176 | #save(rotSCM,file="Demonstrations/rotOrca.RData") |
|---|
| 177 | |
|---|
| 178 | #load("rotSCM.RData") |
|---|
| 179 | vROT <- VarMSEplot(rotSCM, ObsDat, weightinv = DiscInv, ylim = c(0,80), qmax = NULL) |
|---|
| 180 | abline(v = which(vROT[,2] > 0.99)[1]) |
|---|
| 181 | qROT <- which(vROT[,2] > 0.99)[1] |
|---|
| 182 | qROT |
|---|
| 183 | |
|---|
| 184 | #Step 6: Emulate the basis coefficients and tune emulators! |
|---|
| 185 | tDataSCM <- GetEmulatableDataWeighted(Design = wave_param_US[,-1], EnsembleData = rotSCM, HowManyBasisVectors = qROT, weightinv = DiscInv) |
|---|
| 186 | tData = tDataSCM |
|---|
| 187 | StanEmsO <- InitialBasisEmulators(tData, HowManyEmulators=qROT) |
|---|
| 188 | # If it seems not working, relaunch source('BuildEmulator/BuildEmulator.R') |
|---|
| 189 | # A fast check that it worked |
|---|
| 190 | names(StanEmsO[[1]]) |
|---|
| 191 | |
|---|
| 192 | # To remove heavy data, especially if you want to save the emulators |
|---|
| 193 | #for ( i in 1:qROT ) { |
|---|
| 194 | # StanEmsO[[i]]$StanModel <- NULL |
|---|
| 195 | #} |
|---|
| 196 | #save(StanEmsO,file="Demonstrations/StanEmsO.RData") |
|---|
| 197 | |
|---|
| 198 | #load("Demonstrations/StanEmsO.RData") |
|---|
| 199 | for ( i in 1:qROT ) { |
|---|
| 200 | tLOOs1 <- LOO.plot(StanEmulator = StanEmsO[[i]], ParamNames = StanEmsO[[i]]$Names) |
|---|
| 201 | } |
|---|
| 202 | |
|---|
| 203 | #Step 7: History Matching preliminaries. If your emulator is good enough to history match, you don't always want to do it on the whole field as that inverts massive matrices everywhere in parameter space! We now model the relationship between field and coefficient implausibilities. |
|---|
| 204 | ###NOTE IF WE WILL RULE OUT ALL OF SPACE, THERE IS A DISCREPANCY SCALING STEP TO AVOID THIS, SEE SPATIALDEMO AND USE CAUTION! |
|---|
| 205 | ImplDesign <- 2*as.data.frame(randomLHS(nparam, nparam)) - 1 |
|---|
| 206 | colnames(ImplDesign) <- colnames(tData)[1:nparam] |
|---|
| 207 | EmOutput1 <- lapply(1:length(StanEmsO), function(e) EMULATOR.gpstan(ImplDesign,StanEmsO[[e]],FastVersion = TRUE)) |
|---|
| 208 | Expectation1 <- matrix(0, nrow = dim(ImplDesign)[1], ncol = length(StanEmsO)) |
|---|
| 209 | Variance1 <- matrix(0, nrow = dim(ImplDesign)[1], ncol = length(StanEmsO)) |
|---|
| 210 | for (j in 1:length(StanEmsO)){ |
|---|
| 211 | Expectation1[,j] <- EmOutput1[[j]]$Expectation |
|---|
| 212 | Variance1[,j] <- EmOutput1[[j]]$Variance |
|---|
| 213 | } |
|---|
| 214 | |
|---|
| 215 | #ImplModel <- HMCoeffBound(JJArotSAT, tObsJJASAT[[1]], Expectation1, Variance1, Error = 0*diag(8192), Disc = DiscScaled, weightinv = DiscInvScaled) # Error set as 0 matrix as combined into Discrepancy |
|---|
| 216 | #With raw discrepancy (in case emulator uncertainty is large) |
|---|
| 217 | ImplModel <- HMCoeffBound(rotSCM, ObsDat, Expectation1, Variance1, Error = 0*diag(nlevout), Disc = Disc, weightinv = DiscInv) |
|---|
| 218 | #save(ImplModel, file="Demonstrations/ImplModel.RData") |
|---|
| 219 | |
|---|
| 220 | #load("Demonstrations/ImplModel.RData") |
|---|
| 221 | T_c <- ImplModel$Bound |
|---|
| 222 | stan_dens(ImplModel$model, pars = "T_c") |
|---|
| 223 | par(mfrow=c(1,1)) |
|---|
| 224 | plot(ImplModel$SampleIf, ImplModel$SampleIc, pch=18, xlim = c(0,max(ImplModel$SampleIf)), ylim = c(0,max(ImplModel$SampleIc))) |
|---|
| 225 | abline(v = qchisq(0.995, 30)) # bound on the field |
|---|
| 226 | abline(h = qchisq(0.995, length(StanEmsO)), lty = 2) # where the chi-squared bound is, based on the number of basis vectors |
|---|
| 227 | abline(h = T_c) |
|---|
| 228 | |
|---|
| 229 | #Final step: History matching in the coefficient space. |
|---|
| 230 | CoeffHM <- DesignHM <- NULL |
|---|
| 231 | tempDesign1000 <- 2*as.data.frame(randomLHS(1000, 20)) - 1 |
|---|
| 232 | colnames(tempDesign1000) <- colnames(tData)[1:20] |
|---|
| 233 | EmOutput1000 <- lapply(1:length(StanEmsO), function(e) EMULATOR.gpstan(tempDesign1000,StanEmsO[[e]], FastVersion = TRUE)) |
|---|
| 234 | Expectation1000 <- Variance1000 <- matrix(0, nrow = dim(tempDesign1000)[1], ncol = length(StanEmsO)) |
|---|
| 235 | for (j in 1:length(StanEmsO)){ |
|---|
| 236 | Expectation1000[,j] <- EmOutput1000[[j]]$Expectation |
|---|
| 237 | Variance1000[,j] <- EmOutput1000[[j]]$Variance |
|---|
| 238 | } |
|---|
| 239 | CoeffHM <- HistoryMatch(rotSCM, type="scoresMV", ObsDat, Expectation1000, Variance1000, Error = 0*diag(nlevout), Disc = Disc, ModelBound = FALSE, weightinv = DiscInv)$impl |
|---|
| 240 | sum(CoeffHM < T_c) / length(CoeffHM) |
|---|
| 241 | summary(CoeffHM) |
|---|
| 242 | |
|---|
| 243 | ans <- Reconstruct(Expectation1000[which.min(CoeffHM),],rotSCM$tBasis[,1:qROT])+rotSCM$EnsembleMean |
|---|
| 244 | plot(x=dataLES[,2],y=dataLES[,1],type='l',lwd=2,col=2,xlab=variable,ylab="Altitude") |
|---|
| 245 | for(j in 2:NRUNS+1){ |
|---|
| 246 | lines(x=dataSCM[,j],y=dataSCM[,1],col=8,lwd=0.5) |
|---|
| 247 | } |
|---|
| 248 | lines(x=dataLES[,2],y=dataLES[,1],type='l',lwd=2,col=2) |
|---|
| 249 | for(k in 1:10){ |
|---|
| 250 | anss <- Reconstruct(Expectation1000[k,],rotSCM$tBasis[,1:qROT])+rotSCM$EnsembleMean |
|---|
| 251 | lines(x=anss,y=dataSCM[,1],col=3,lwd=1.5) |
|---|
| 252 | } |
|---|
| 253 | lines(x=ans,y=dataSCM[,1],col=4,lwd=1.5) |
|---|
| 254 | |
|---|