#########################################################################################
#                                Downscaling with ERA-Interim                           #
#########################################################################################
# run it from the bash with:
#
# Rscript Downscaling.R 1984
#
# being 1984 the year you want to classify the WTs;
# in this way you can run up to 8 jobs at the same time, each one producing its output files!
# You can also run it for a sequence of years with the syntax:
# 
# Rscript Downscaling.R 1980 2014
#
# and it will compute each year from 1980 to 2014, each one after finishing the previous one.
# If you want to run many years in parallel with just only 1 command, run from the bash:
#
# for y in {1980..2014}; do Rscript Downscaling.R &; done
#
# but it'd need 24 processors! In practice, it is possible to run only 4-8 years at time


library(s2dverification)  # for the function Load()
source('/home/Earth/ncortesi/Downloads/scripts/Rfunctions.R') # for the calendar functions
Load.path <- '/home/Earth/ncortesi/Downloads/scripts/IC3.conf'      # Load() file path

workdir="/scratch/Earth/ncortesi/RESILIENCE/SD"    # working dir where to put the output maps and files
subdatadir="/scratch/Earth/ncortesi/RESILIENCE/SD_subdata"    # dir where to put the intermediate daily psl data (1 file for each subarray)

mslp.rean='ERAintDailyHighRes'  #'ERAintDailyLowRes'  # daily reanalysis dataset used for MSLP data

year.start=1980     # starting year of the MSLP daily data (from the 1st of january)
year.end=2014       # ending year of the MSLP daily data (up to the 31 of December)


##########################################################################################

args <- commandArgs(TRUE)

if(length(args) == 1) year.start <- year.end <- as.integer(args[1])
if(length(args) == 2) {year.start <- as.integer(args[1]); year.end <- as.integer(args[2])}

# Load 1 day of MSLP data from the reanalysis chosen, just to detect the number of latitude and longitude points:
MSLP <- Load('psl', NULL, mslp.rean, paste0(year.start,'0101'), storefreq = 'daily', leadtimemax = 1, output = 'lonlat', configfile = Load.path)

n.lat <- length(MSLP$lat)  # number of latitude values
n.lon <- length(MSLP$lon)  # number of longitude values

lon.pos <- ifelse(min(MSLP$lon>=0), TRUE, FALSE)  # set lon.pos to TRUE if the longitude values of the reanalysis grid has no negative values, FALSE if not.

# for each grid point of the reanalysis and each day to downscale, find the analogue days
# we exclude only central points > +77 degrees lat and < -77 deg.
n.lat.unused.poles <- 20 # number of unused latitude values near each of the two poles (must exclude last 10 degrees N/S, so it depends on the spatial res. of the reanalysis)

lat.used <- MSLP$lat[-c(1:n.lat.unused.poles,(n.lat-n.lat.unused.poles):n.lat)] # latitude values used as central points 
psl.res <- diff(lat.used)[1]  # psl grid resolution
lat.used <- round(lat.used,3) # round psl values to the third decimal to save them in a file with a short file name (precision: ~100 m)
n.lat.used <- length(lat.used)
    
lon.used <- round(MSLP$lon,3) # longitude values used as central points rounded to the third decimal (precision: ~100 m)
n.lon.used <- length(lon.used)

n.grid.points <- length(lat.used)*length(lon.used)

# load all MSLP data, one year at time:
for(y in year.start:year.end){
    print(paste0("Year: ",y))
    n.days <- n.days.in.a.year(y)
    
    MSLP <- Load('psl', NULL, mslp.rean, paste0(y,'0101'), storefreq = 'daily', leadtimemax = n.days, output = 'lonlat',  configfile = Load.path)
    gc()




    
    years.crossv <- c(year.start:year.end)
    ss <- which(years.crossv==y1)
    years.crossv <- years.crossv[-ss]  # remove all the potential analogue days belonging to the year of the day to downscale
    
    for(y2 in years.crossv){
         n.days2 <- n.days.in.a.year(y2)

         MSLP2 <- Load('psl', NULL, mslp.rean, paste0(y2,'0101'), storefreq = 'daily', leadtimemax = n.days2, output = 'lonlat',  configfile = Load.path)
         gc()
         
         for(day1 in 1:n.days1){
              for(day2 in 1:n.days2){

                 (MSLP1$obs[1,1,1,day1,,] - MSLP2$obs[1,1,1,day2,,])^2 + (MSLP1$obs[1,1,1,day1,,] - MSLP2$obs[1,1,1,day2,,])^2
                  
    }

    
    # create subdirs where to put the yearly output (there are too many files to put them in only 1 dir)
    if(!dir.exists(file.path(workdir,paste0(y,"_Rdata")))) dir.create(file.path(workdir,paste0(y,"_Rdata"))) 
    #if(!dir.exists(file.path(workdir,paste0(y,"_txt")))) dir.create(file.path(workdir,paste0(y,"_txt"))) 

    # loop over the lat/lon of the central point of the Lamb classification:
    for(latc in lat.used){
        #latc <- lat.used[1]; lonc <- lon.used[1];  # for the debug
        
        for(lonc in lon.used){
            pos.latc <- which(lat.used==latc)
            pos.lonc <- which(lon.used==lonc)
            cat(paste0("Grid point saved: ",(pos.latc-1)*n.lon.used+pos.lonc ,"/", n.grid.points, " "), "\r")
            
            
            # mean psl at each of the 9 grid points, for each day of the year:
            psl <- array(NA,c(n.days,9)) 
            
            for(p in 1:16) {
                 
                 pos.lon.low.res <- (pos.lon[p]-1):(pos.lon[p]+radiu1)
                
                 if(head(pos.lon.low.res,1) <= 0){
                     ss <- which(pos.lon.low.res <= 0)
                     pos.lon.low.res <- c(pos.lon.low.res[ss] + n.lon.used, pos.lon.low.res[-ss])
                 }
                 if(tail(pos.lon.low.res,1) > n.lon.used){
                     ss <- which(pos.lon.low.res > n.lon.used)
                     pos.lon.low.res <- c(pos.lon.low.res[-ss], pos.lon.low.res[ss]-n.lon.used)
                 }
                
                 pos.lat.low.res <- (pos.lat[p]-1):(pos.lat[p]+1)  # it never has to be corrected because we excluded the poles

                 MSLP.low.res <- MSLP.year$obs[1,1,1,,pos.lat.low.res,pos.lon.low.res]
                 psl[,p] <- apply(MSLP.low.res, 1, mean)
            }


            # create a data frame with all the info about the WT classification:    

            #years.period <- months.period <- days.period <- c()
            #for(y in year.start:year.end) years.period <- c(years.period, rep(y, n.days.in.a.year(y)))
            #for(y in year.start:year.end) months.period <- c(months.period, seq.months.in.a.year(y))
            #for(y in year.start:year.end) days.period <- c(days.period, seq.days.in.a.year(y))
            years.period <- rep(y, n.days)
            months.period <- seq.months.in.a.year(y)[1:n.days]
            days.period <- seq.days.in.a.year(y)[1:n.days]
            WT<-data.frame(Year=years.period, Month=months.period, Day=days.period, Direction=round(D2,3), WT.dir=D2.dir, stringsAsFactors=FALSE)

            WT$Year<-as.numeric(WT$Year);WT$Month<-as.numeric(WT$Month);WT$Day<-as.numeric(WT$Day);WT$Direction<-as.numeric(WT$Direction);WT$WT.dir<-as.character(WT$WT.dir)

            # colonna che identifica quali giorni sono di tipo ibrido e quali di tipo direzionale:
            WT$Hyb <- rep("Directional",length(D2))
            WT$Hyb[cyc.pure] <- "Pure_C"
            WT$Hyb[anticyc.pure] <- "Pure_A"
            WT$Hyb[hybrid.cyc] <- "Hybrid_C"
            WT$Hyb[hybrid.anticyc] <- "Hybrid_A"

             # colonna con la lista dei 26 WTs officiali:
            WT$WT <- WT$D2.dir
            WT$WT[cyc.pure] <- "C"
            WT$WT[anticyc.pure] <- "A"
            WT$WT[hybrid.cyc] <- paste("C.",WT$WT.dir[hybrid.cyc],sep="")
            WT$WT[hybrid.anticyc] <- paste("A.", WT$WT.dir[hybrid.anticyc],sep="")
            #WT$WT[indeter] <- "U"   # comment this line not to include the Unclassified U WT

            WT$WT.num <- match(WT$WT,WTs.type)# aggiunge una colonna con la conversione dei 26 tipi di tempo a numeri da 1 a 26

            # colonna con la lista dei 10 WTs ottenuti unendo a C e ad A gli otto WT direzionali puri;
            # i WTs ibridi si aggiungono ognuno al suo tipo direzionale corrispondente (es: C.SW si aggiunge a SW, ecc.)
            WT$WT10 <- WT$WT.dir
            WT$WT10[cyc.pure] <- "C"
            WT$WT10[anticyc.pure] <- "A"
            WT$WT10.num <- match(WT$WT10,WTs.type) # conversione dei 10 tipi di tempo a numeri da 1 a 9 + il tipo A che si converte nel numero 18

            # add the other geostrophical indexes:
            WT$SF=round(SF,5)
            WT$WF=round(WF,5)
            WT$F=round(F,5)
            WT$ZS=round(ZS,5)
            WT$ZW=round(ZW,5)
            WT$Z=round(Z,5)

            #WTs<-rbind(WTs,WT)
            
            # save the full data table as a .txt to exchange it with other people: 
            write.table(WT,file=paste0(workdir,"/",y,"_txt/WTs_",mslp.rean,"_year_",y,"_lat_",latc,"_lon_",lonc,".txt"),row.names=FALSE, col.names=TRUE, quote=FALSE, sep=" ")
            # save only the classification with 10 WTs, to have a smaller (binary) file:
            #WTs<-cbind(WT$Year, WT$Month, WT$Day, WT$WT10.num)
            WTs <- WT$WT10.num
            save(WTs, file=paste0(workdir,"/",y,"_Rdata/10WTs_",mslp.rean,"_year_",y,"_lat_",latc,"_lon_",lonc,".RData"), compress=FALSE)
            
            rm(WT,SF,WF,F,D,ZS,ZW,W)
            
        } # close for on lonc
    } # close for on latc
    cat("\n")
    
} # close for on y 


