#'CST_Analogs
#' 
#'@author Carmen Alvarez-Castro, \email{carmen.alvarez-castro@cmcc.it}
#'        adapted version of the method of Pascal Yiou \email{pascal.yiou@lsce.ipsl.fr}
#'
#'@description search for days with similar atmospheric conditions based on the large scale slp
#              and the local scale (precipitation or Temperature)
#'
#'@param month month of the analog day
#'       day day of the analog day
#'       yr year of the analog day
#'       mAnalog month or list of months to search for analogs
#'       yr1 first year of the total period of study
#'       yr2 last year of the total period of study
#'       ical number of days per year in the calendar (360,365,366)
#'@import 
#'
#'@return list      best.corr.time.ana,best.dist.time.ana,selec.dist.time,selec.corr.time 
#'        list      file.dat with a list of days with the format yyyymmdd ordered by best analog with the dist (minima) and corr (maxima) 
#'        plot      preliminary plot of the best analog selected
#'
#'@example

# month=01
# day=18
# yr=2013
# ical=366
# yr1=1993
# yr2=2018
# mAnalog=c(01,02,09,10,11,12) #search analogs in these months
# Best.ana.number=3  # save me the three best analogs
# BestAnalogs=CST_Analogs(LargeSmodVar1=slp_cmcc,LocalSmodVar2=prate_cmcc,LargeSobsVar1=slp_ERA5,LocalSobsVar2=prate_ERA5,
#             month,yr,day,mAnalog,Best.ana.number,excludeSameyr=TRUE)

function(LargeSmodVar1,LocalSmodVar2,LargeSobsVar1,LocalSobsVar2,
         month,yr,day,mAnalog,Best.ana.number,yr1,yr2,ical,excludeSameyr=TRUE){
analog.day=(10000*yr)+(100*month)+day
time=ReproduceTime(ical,yr1,yr2)
#determine position of the day to analog
analog.time=which(time$time==analog.day)
#selecting analogs from a certain month/season
iseas=which(time$month %in% mAnalog)
analog.seas=c()
analog.seas$time=time$time[iseas]
analog.seas$month=time$month[iseas]
analog.seas$day=time$day[iseas] 
analog.seas$year=time$year[iseas]
ModLargeS=LargeSmodVar1[iseas,]
ModLocalS=LocalSmodVar2[iseas,]
ObsLargeS=LargeSobsVar1[iseas,]
ObsLocalS=LocalSobsVar2[iseas,]

if(excludeSameyr==TRUE){
#excluding days in the same year of the analog day
ExcludeAna=which(analog.seas$year %in% yr)
if(analog.seas$year==ExcludeAna){iseas=NaN}
length(ExcludeAna)
eseas=c(iseas[1:(ExcludeAna[1]-1)],iseas[(ExcludeAna[length(ExcludeAna)]+1):(length(iseas))])
analog.seas$time=time$time[eseas]
analog.seas$month=time$month[eseas]
analog.seas$day=time$day[eseas] 
analog.seas$year=time$year[eseas]
ModLargeS=LargeSmodVar1[eseas,]
ModLocalS=LocalSmodVar2[eseas,]
ObsLargeS=LargeSobsVar1[eseas,]
ObsLocalS=LocalSobsVar2[eseas,]
}

# determine the number of best analogues

i=1
rms.reg=c()
cor.reg=c()
# search in the observations the best analog associated to the analog day in the model
for(i in 1:nrow(ModLargeS)){
  diff=t(ObsLargeS[i,]-LargeSmodVar1[analog.time,])
  diffi=diff^2
  rms=apply(diffi,1,sum,na.rm=TRUE)
  dum=cor(ObsLocalS[i,],LocalSobsVar2[analog.time,],
          method="spearman")
  rms.reg=cbind(rms.reg,rms)
  cor.reg=cbind(cor.reg,dum)
}
dist=as.numeric(sqrt(rms.reg/nrow(ModLargeS))/100)
dist.max=max(dist)
dist.min1=min(dist)
dist.min=order(dist)
corr.max=max(cor.reg)
corr.min=min(cor.reg)

#### select best analogues based on highest correlation and minimun euclidean distance
# selec.corr1=which(cor.reg>0.8)
# selec.corr2=which(cor.reg<(-0.8))
# selec.dist1=which(dist==0)
################################### this must be modified!!!!
#selection based on best distance
selec.dist=dist[dist.min]
selec.dist.time=analog.seas$time[dist.min]
selec.dist.corr=cor.reg[dist.min]
best.dist.ana=selec.dist[2:(Best.ana.number+1)]
best.dist.time.ana=selec.dist.time[2:(Best.ana.number+1)]
best.dist.corr.ana=selec.dist.corr[2:(Best.ana.number+1)]
best.dist.day.ana=dist.min[2:(Best.ana.number+1)]
#selec.corr=cor.reg[c(selec.corr1,selec.corr2)]
#selec.corr.dist=dist[c(selec.corr1,selec.corr2)]
#selec.corr.time=time[c(selec.corr1,selec.corr2)]

# selection based on best correlation
selec.corr=order(cor.reg)
selec.corr.dist=dist[selec.corr]
selec.corr.time=analog.seas$time[selec.corr]
best.corr.ana=selec.corr[2:(Best.ana.number+1)]
best.corr.time.ana=selec.corr.time[2:(Best.ana.number+1)]
best.corr.dist.ana=selec.corr.dist[2:(Best.ana.number+1)]
best.corr.day.ana=selec.corr[2:(Best.ana.number+1)]

return(list(best.corr.time.ana,best.dist.time.ana,selec.dist.time,selec.corr.time))
}
