Program Dr_IDXs_SEACLID
  ! Calculating PDSI, SPI, SPEI 
  use netcdf

!------------------------------------------------------------------------------

  Real, parameter    :: Miss = -99.
  Integer, Parameter :: Nmon = 12
  Integer, Parameter :: NVar = 2, Nreg = 7, Nmem = 7, Nlead = 6
  Integer, Parameter :: Ncase = 3       !  cli,ann
  Character (Len=3), Parameter :: Cases(Ncase)=(/"cli","ann","mlr"/)

  Real, Allocatable :: Regs(:,:), Lon(:), Lat(:), xlon(:), xlat(:) 

  Real, Allocatable :: Pr_Ope(:,:,:,:,:,:), T2_Ope(:,:,:,:,:,:)   ! Nlon,Nlat,Nmem,Nlead,Ncase,Nmodel
  Real, Allocatable :: Pr_Ope_ens(:,:,:), T2_Ope_ens(:,:,:)       ! Nlon,Nlat,Nlead
  Real, Allocatable :: Pr_Ope_fcs(:,:,:), T2_Ope_fcs(:,:,:)       ! Nlon,Nlat,Nlead = *Cli_Obs + *Ano
  Real, Allocatable :: Pr_Ano(:,:,:), T2_Ano(:,:,:)               ! Nlon,Nlat,Nlead
  Real, Allocatable :: Pr_Cli_ens(:,:,:,:), T2_Cli_ens(:,:,:,:)           ! Nlon,Nlat,Nlead,Nmon
  Real, Allocatable :: Pr_Cli(:,:,:,:), T2_Cli(:,:,:,:)           ! Nlon,Nlat,Nlead,Nmon
  Real, Allocatable :: Pr_Cli_Obs(:,:,:), T2_Cli_Obs(:,:,:)       ! Nlon,Nlat,Nmon

  Real, Allocatable :: xmem(:), xlead(:), xtime(:)

!------------------------------------------------------------------------------
  Character (Len=255) :: Fname, BL_Dir, R_Fname, T_Fname, Out_Dr_Fname
  Character (Len=255) :: Cli_Dir, Dir_Ope, Mask_File, Dir_Out
  Character (Len=3)   :: TVar, RVar
  Character (Len=10),Allocatable :: Model_nm(:)
  Logical :: status, Empty

  Integer :: Yr1, Yr2, YOpe, MOpe, Nmodel, NYear, maxyrs
  Integer :: NLen, Nst, Nlon, Nlat, IO, Ntime, Nt, it, Landpoint
  Integer :: imod, ist, iyr, imw, ivar, isys, system, ilon, ilat
  Integer :: Nt1

!------------------------------------------------------------------------------
! For writing to NC file:
  Real, allocatable, Dimension (:,:,:,:) :: X4d
  Real, allocatable, Dimension (:) :: X1d,Xt
!------------------------------------------------------------------------------

  Namelist /File_Dir_Names/ Cli_Dir, Mask_File, Dir_Ope, Dir_Out, TVar, RVar
  Namelist /Data_Info/      Nmodel
  Namelist /Model_name/     Model_nm
  Namelist /Time_Infor/     YOpe, MOpe
!------------------------------------------------------------------------------

  Open (1, file="Namelist_Anomaly_Pr_T2_Ope.txt", Status="Old")     ! Tinh voi APH 1961-2015

  Read (1, File_Dir_Names)
  Read (1, Data_Info)         
  Allocate (Model_nm(Nmodel))
  Read (1, Model_name)
  Read (1, Time_Infor)
  Close (1)

  Call Read_Regs 
  print*,"Parameters: Nlat,Nlon=",Nlat,Nlon
  
  Call Read_Ope_Data       ! Read data of "cli","ann","mlr" from Ope run at YOpe, MOpe
  Call Read_Clim_Data      ! Read Climatological mean of "pr", "t2", "pr_o", "t2_o" 
  Call Do_ens_Ano_Ope      ! Ensemble mean over Nspl = Nmodel*Nmem*Ncase = 2*7*3 = 42 corrected members

  Fname=trim(Dir_Out)//"Forecast_Ope_Pr_T2_and_Anomaly.nc"
  Call Write_Forecast_Mean_Ano_Pr_T2 (Fname)
   CONTAINS
   !------------------------------------------------------------------------------
   Subroutine Do_ens_Ano_Ope
      Integer :: imod,imem,ilon,ilat,ilead,Nlo,Nla,Nme,Nt,icas, it1, it2
      Integer :: Nspl,islp
      Real, Allocatable :: xtmp(:), xpr(:)
      Real :: xfcs, pope, pcli, tope, tcli, pobs, tobs, pmod, tmod

      ! Pr_Cli(:,:,:,:), T2_Cli(:,:,:,:)           ! Nlon,Nlat,Nlead,Nmon
      ! Pr_Ope_fcs(:,:,:), T2_Ope_fcs(:,:,:)       ! Nlon,Nlat,Nlead
      ! Pr_Cli_Obs(:,:,:), T2_Cli_Obs(:,:,:)       ! Nlon,Nlat,Nmon

      Nspl=Nmodel*Nmem*Ncase
      Allocate (xtmp(Nspl),xpr(Nspl))
      Allocate (Pr_Ope_ens(Nlon,Nlat,Nlead),T2_Ope_ens(Nlon,Nlat,Nlead))
      Allocate (Pr_Ope_fcs(Nlon,Nlat,Nlead),T2_Ope_fcs(Nlon,Nlat,Nlead))
      Pr_Ope_ens=Miss; T2_Ope_ens=Miss; Pr_Ope_fcs=Miss; T2_Ope_fcs=Miss
      Allocate (Pr_Ano(Nlon,Nlat,Nlead),T2_Ano(Nlon,Nlat,Nlead))
      Pr_Ano=Miss; T2_Ano=Miss

      Do ilead=1,Nlead
         imon=MOpe+ilead; if (imon>Nmon) imon=imon-Nmon    ! Month of the year
         Do ilon=1,Nlon
            Do ilat=1,Nlat
               if (Int(Regs(ilon,ilat))>0) then
                  pobs=Pr_Cli_Obs(ilon,ilat,imon);   tobs=T2_Cli_Obs(ilon,ilat,imon)   ! Obs
                  pcli=Pr_Cli(ilon,ilat,ilead,imon); tcli=T2_Cli(ilon,ilat,ilead,imon) ! Model Clim: Average over all corrected members and models
                  islp=0
                  Do imod=1,Nmodel      ! =2
                     Do imem=1,Nmem     ! =7
                        Do icas=1,Ncase ! =3
                           islp=islp+1
                           xpr (islp)=Pr_Ope(ilon,ilat,imem,ilead,icas,imod)
                           xtmp(islp)=T2_Ope(ilon,ilat,imem,ilead,icas,imod)
                        Enddo
                     Enddo
                  Enddo

                  ! Fcs ensemble mean: Average over all corrected members and models
                  Pr_Ope_ens(ilon,ilat,ilead)=Ave(xpr, islp,Miss)
                  T2_Ope_ens(ilon,ilat,ilead)=Ave(xtmp,islp,Miss)

                  pope=Pr_Ope_ens(ilon,ilat,ilead); 
                  tope=T2_Ope_ens(ilon,ilat,ilead);

                  ! Fcs Anomaly: Fcs ensemble mean MINUS Model Clim
                  if (pope/=Miss.AND.pcli/=Miss) Pr_Ano(ilon,ilat,ilead)=pope-pcli    ! otherwise have been set to Miss
                  if (tope/=Miss.AND.tcli/=Miss) T2_Ano(ilon,ilat,ilead)=tope-tcli

                  ! Operational fcs: = Model Anomaly + Obs
                  if (pobs/=Miss.AND.Pr_Ano(ilon,ilat,ilead)/=Miss) Pr_Ope_fcs(ilon,ilat,ilead)=pobs+Pr_Ano(ilon,ilat,ilead)   ! Fcs = Obs_Cli + Ano
                  if (tobs/=Miss.AND.T2_Ano(ilon,ilat,ilead)/=Miss) T2_Ope_fcs(ilon,ilat,ilead)=tobs+T2_Ano(ilon,ilat,ilead)

                  ! Relative anomaly for rainfall:
                  if (pobs>0.AND.Pr_Ano(ilon,ilat,ilead)/=Miss) Pr_Ano(ilon,ilat,ilead)=Pr_Ano(ilon,ilat,ilead)/pobs
               endif
            Enddo
         Enddo
      Enddo
   End Subroutine Do_ens_Ano_Ope
   !------------------------------------------------------------------------------
   Real Function Fcs (Xmodel,Xcli,Xobs)
      Real :: Xmodel,Xcli,Xobs, Resl, Bias

      if (Xmodel/=Miss.AND.Xcli/=Miss.AND.Xobs/=Miss) then
         Bias = Xmodel - Xcli
         Resl = Xobs   + Bias
      else
         Resl = Miss
      endif
      Fcs  = Resl 
   End Function Fcs
   !------------------------------------------------------------------------------
   Subroutine Write_Forecast_Mean_Ano_Pr_T2 (Fname)
      Character (Len=*) :: Fname
      Character (Len=250) :: var_nm, t_unit, var_ln, var_unit, lon_nm, lat_nm, z_nm, t_nm
      Real, Allocatable, Dimension (:) :: xtime
      INteger :: i, Nvar1

!      Allocate (Pr_Ope_ens(Nlon,Nlat,Nlead),T2_Ope_ens(Nlon,Nlat,Nlead))
!      Pr_Ope_ens=Miss; T2_Ope_ens=Miss
!      Allocate (Pr_Ano(Nlon,Nlat,Nlead),T2_Ano(Nlon,Nlat,Nlead))

      Allocate (xtime(Nlead))
      Do i=1,Nlead; xtime(i)=i; Enddo
      Write(t_unit,"(A,I4.4,A,I2.2,A)") "months since ",YOpe,"-",MOpe+1,"-01 "; 
      lon_nm="lon"; lat_nm="lat"; t_nm="lead";

      !Fname=trim(Dir_Out)//"Forecast_Ope_Pr_T2_and_Anomaly.nc"

      var_ln="Model rainfall ensemble forecast"
      var_unit="mm/month"
      Call wr_ncdf_3d (Fname,Lon,Lat,xtime,Nlon,Nlat,Nlead,Pr_Ope_ens,"pr",t_unit, var_ln, var_unit, lon_nm, lat_nm, t_nm, Miss)
      var_ln="Model 2-m temperature ensemble forecast"
      var_unit="C degree"
      Call wr_ncdf_3d_apd (Fname,T2_Ope_ens,"t2",Nlon,Nlat,Nlead, var_ln, var_unit, lon_nm, lat_nm, t_nm, Miss)
      var_ln="Relative Anomaly of the Model rainfall forecast"
      var_unit="-"
      Call wr_ncdf_3d_apd (Fname,Pr_Ano,"pr_ano",Nlon,Nlat,Nlead, var_ln, var_unit, lon_nm, lat_nm, t_nm, Miss)
      var_ln="Anomaly of the Model 2-m temperature forecast"
      var_unit="C degree"
      Call wr_ncdf_3d_apd (Fname,T2_Ano,"t2_ano",Nlon,Nlat,Nlead, var_ln, var_unit, lon_nm, lat_nm, t_nm, Miss)

      ! Pr_Ope_fcs(:,:,:), T2_Ope_fcs(:,:,:)       ! Nlon,Nlat,Nlead
      var_ln="Model rainfall forecast obtained by adding anomaly forecast to observation climatology"
      var_unit="mm/month"
      Call wr_ncdf_3d_apd (Fname,Pr_Ope_fcs,"pr_fcs",Nlon,Nlat,Nlead, var_ln, var_unit, lon_nm, lat_nm, t_nm, Miss)
      var_ln="Model 2-m temperature forecast obtained by adding anomaly forecast to observation climatology"
      var_unit="C degree"
      Call wr_ncdf_3d_apd (Fname,T2_Ope_fcs,"t2_fcs",Nlon,Nlat,Nlead, var_ln, var_unit, lon_nm, lat_nm, t_nm, Miss)
      Deallocate (xtime)
   End Subroutine Write_Forecast_Mean_Ano_Pr_T2
   !--------------------------------------------------------------------------------
   Subroutine Read_Regs 
     Integer :: ilon,ilat, ireg, ic,j
     Real :: tmp

     Call rd_ncdf_2d (Mask_File,Lon,Lat,Nlon,Nlat,Regs,"reg")
     Nst=0;
     Do ilon=1,Nlon
        Do ilat=1,Nlat
           if (Int(Regs(ilon,ilat))>0) then
              Nst=Nst+1
           endif
        Enddo
     Enddo
     !print*,"Nst=",Nst; pause
   End Subroutine Read_Regs
   !------------------------------------------------------------------------------
   Subroutine Read_Clim_Data !(Fname)
      !Character (Len=*) :: Fname
      Integer :: Nlo,Nla,Nle,Nt,imod,it
      Real, Allocatable :: xlon(:),xlat(:),xled(:),xtime(:),X4d(:,:,:,:)

      Fname=trim(Cli_Dir)//"Monthly_Clim.nc"
      Call rd_ncdf_4d (Fname,xlon,xlat,xled,xtime,Nlo,Nla,Nle,Nt,Pr_Cli,"pr_m") !_m")
      Deallocate (xlon,xlat,xled,xtime)
       
      Call rd_ncdf_4d (Fname,xlon,xlat,xled,xtime,Nlo,Nla,Nle,Nt,T2_Cli,"t2_m") !_m")
      Deallocate (xlon,xlat,xled,xtime)
      Call rd_ncdf_3d (Fname,xlon,xlat,xtime,Nlo,Nla,Nt,Pr_Cli_Obs,"pr_o")
      Deallocate (xlon,xlat,xtime)
      Call rd_ncdf_3d (Fname,xlon,xlat,xtime,Nlo,Nla,Nt,T2_Cli_Obs,"t2_o")
      Deallocate (xlon,xlat,xtime)
      print*,"Read_Clim_Data: Done!"
   End Subroutine Read_Clim_Data
   !------------------------------------------------------------------------------
   Subroutine Read_Ope_Data
      Integer :: ist,ilon,ilat,ilead,Nlo,Nla,Nme,Nt,icas, it1, it2
      Character (Len=255) :: Fname
      Real, Allocatable :: X4d(:,:,:,:), time(:), xlon(:),xlat(:),xmem(:),xtime(:)

      ! Pr_Ope(:,:,:,:,:,:), T2_Ope(:,:,:,:,:,:)     ! Nlon,Nlat,Nmem,Nlead,Ncase,Nmodel
      Allocate (T2_Ope(Nlon,Nlat,Nmem,Nlead,Ncase,Nmodel))
      Allocate (Pr_Ope(Nlon,Nlat,Nmem,Nlead,Ncase,Nmodel))
      Do imod=1,Nmodel
         write (Fname,"(A,I4.4,I2.2,A)") trim(Dir_Ope)//"BC_Ope_",YOpe,MOpe,"_"//trim(TVar)//"_"//trim(Model_nm(imod))//".nc"
         Do icas=1,Ncase
            Call rd_ncdf_4d (Fname,xlon,xlat,xmem,xtime,Nlo,Nla,Nme,Nt,X4d,trim(Cases(icas)))
            T2_Ope(:,:,:,:,icas,imod)=X4d(:,:,:,:)
            Deallocate (xlon,xlat,xmem,xtime,X4d)
         Enddo
      Enddo
      Do imod=1,Nmodel
         write (Fname,"(A,I4.4,I2.2,A)") trim(Dir_Ope)//"BC_Ope_",YOpe,MOpe,"_"//trim(RVar)//"_"//trim(Model_nm(imod))//".nc"
         Do icas=1,Ncase
            Call rd_ncdf_4d (Fname,xlon,xlat,xmem,xtime,Nlo,Nla,Nme,Nt,X4d,trim(Cases(icas)))
            Pr_Ope(:,:,:,:,icas,imod)=X4d(:,:,:,:)
            Deallocate (xlon,xlat,xmem,xtime,X4d)
         Enddo
      Enddo
   End Subroutine Read_Ope_Data
   !------------------------------------------------------------------------------
   Include "/home/tanpv/Mylibs/sub_wr_ncdf_Tan.F90"
   Include "/home/tanpv/Mylibs/sub_rd_ncdf_Tan.F90"
   Include "/home/tanpv/Mylibs/Ave.f90"
   !--------------------------------------------------------------------
   END ! Program
