!
   PROGRAM BC_ANN_1982_2020_Feb_2024      ! BC_ANN_1982-2020_Feb_2024.f90
 
   Use Netcdf

   Integer, Parameter :: Yr1=1982, Yr2=2021, Nmon=12, Nreg=7, NLead=6, Nvar=17, Nfile=9
   Integer, Parameter :: Nyrs=(Yr2-Yr1+1)
   Real, Parameter    :: Miss=-99.
   Character (Len=4)  :: vname(Nvar)=(/"pr_o","t2_o","tx_o","tm_o","pr","t2","tx","tm", &
                                       "h500","h850","olr","q2","rh2","slp","u200","u850","w700"/)
   Character (Len=10) :: v_unit(Nvar)=(/"mm/month","C deg","C deg","C deg","mm/month","C deg","C deg","C deg", &
                                       "m","m","w/m2","kg/kg","%","hPa","m/s","m/s","m/s"/)
   Integer            :: Fcs_mon, Nyr1, NMax, Ncase, Ntc_var

   Character (Len=255) :: Fname
   Real, Allocatable   :: lon(:),lat(:),Regs(:,:), X3d(:,:,:)
! xlon,xlat,xlev,xtime,Nlo,Nla,Nz,Nt
   Real, Allocatable   :: xlon(:),xlat(:),xlev(:),xtime(:)
   Integer             :: Nlo,Nla,Nz,Nt 
   Integer             :: Nlon, Nlat, Ntime, Ngrd, ilon, ilat, it
   Integer             :: Mvars
   Real, Allocatable   :: Dat_All(:,:,:,:,:) ! (Nlon,Nlat,Ntime,Nvar,NLead) - Anomaly data = Original data - Original Clim
   Real, Allocatable   :: Dat_Org(:,:,:,:,:) ! (Nlon,Nlat,Ntime,Nvar,NLead) - Original data
   Real, Allocatable   :: Clim   (:,:,:,:,:) ! (Nlon,Nlat,Nmon,Nvar,NLead)  - Original Clim
   Real, Allocatable   :: Mod_Cli(:,:,:,:)   ! (Nlon,Nlat,NLead,Nmon) - Model Climatological Mean
   Real, Allocatable   :: Del_Cli(:,:,:,:)   ! (Nlon,Nlat,NLead,Nmon) : Del = F - O, Tinh tu Chuong trinh nay
   Real, Allocatable   :: Bias_Cli(:,:,:,:)  ! (Nlon,Nlat,NLead,Nmon)    - Model Cli. Bias = Model_Fcs - Obs ==> Corrected=Model_Fcs-Bias
                                             ! Neu Run_Cli=.true. thi nhan tu Del_Cli, neu Run_Cli=.false. thi doc tu file
   Real, Allocatable   :: X_inp(:,:), Y_inp(:), Yest(:,:), Yhq(:,:)
   Character (Len=5)   :: yvarn, Model_nm

   !--------------------------------------------------------------------------------
   ! Regression:

   Real, Allocatable   :: Xorg(:), Xhq(:)          !
   Real, Allocatable   :: Beta(:,:,:,:)            ! NLead,Nmon,Nreg,Mhq
   Integer             :: Mhq, Nhq                 ! Mhq = Mxvar+1, Nhq=Nsample*Mhq
   Integer :: Nyear, imon      ! Tong so nam co SL va chi so thang
   !--------------------------------------------------------------------------------
   ! ANN:
   character (len=250) :: input_file, output_file, save_file
   character (len=250) :: Dir, Dir_ANN_Out, Dir_Cli, Dir_ANN_Save, Dir_Corrected
   logical :: training_mode

   ! Use for calculating scaling factors
   Integer :: Nsample, Nepoc, Nsample1

   Real,allocatable, Dimension(:,:) :: Inputs, Outputs, Inputs_X, Outputs_Y
   Real,allocatable, Dimension(:)   :: min_in, max_in, min_out, max_out
   Real :: mean_error, mean_error_check
   !-------------------------------------------------------------------------------
    integer ::  Nin, Nhidden, Nout, iin, ihid, iout
    integer :: i,j,k

    Real,allocatable, Dimension(:,:) :: weight_ih, weight_ho, moment_ih, moment_ho
    Real,allocatable, Dimension(:)   :: fin, fhid, fout, ftarget, delta_o, delta_h
   ! Training
    Real :: learning_rate0, learning_rate, momentum, error, tmp, mintmp
    logical :: debug, Run_Cli
   !--------------------------------------------------------------------------------
   Integer :: Op_Nhidden, Op_Nepoc   ! Optimal values
   Real    :: Op_learning_rate
   Real, Allocatable :: X4d(:,:,:,:), X5d(:,:,:,:,:), F1d(:),O1d(:), Score_Cor(:,:,:), Score_AV(:,:,:) 
   !------------------- For ANN -------------------------------------------------------------
   Namelist /ann_info/ Nhidden,learning_rate,momentum,training_mode,Nepoc,debug
   Namelist /Model_info/ Model_nm, yvarn

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

   Open (1, file="Namelist_ANN_Training.txt",Status="old")
   Read (1, ann_info)
   Read (1, Model_info)
   learning_rate0 = learning_rate

   Fname="/home/tanpv/Data/AWC/Mask_VN_0.25_Corrected.nc"
   Call rd_ncdf_2d (Fname,lon,lat,Nlon,Nlat,Regs,"reg") ! 7 sub-regs mask

   !Model_nm="clWRF";  yvarn="pr"

   Dir="/home/tanpv/Progs/562_VNU/Data/For_BC/"
   Call Read_all_data (Dir,Model_nm)      ! Chu y: Chuong trinh nay chi su dung Mem1 cua toan giai doan 1982-2021 de training
                                          ! Giai doan 1982-2011: LT6 = LT5 
   Call Calc_Clim_and_Anomaly             ! Tinh trung binh khi hau va anomaly cua tat ca cac bien
   Call Calc_Bias_Cli (yvarn)             ! Tinh Delta va Factor giua Obs clim va Model clim   

   Dir_ANN_Save  ="/home/tanpv/Data/562_VNU/0.25_VN/2024/ANN_Save/"
   Dir_Cli       ="/work/projects/G09/562_VNU/0.25_VN/2024/Cli_Out/" !"/home/tanpv/Data/562_VNU/0.25_VN/Cli_Out/"
   Dir_Corrected ="/home/tanpv/Data/562_VNU/0.25_VN/2024/Corrected/"

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

   write (Fname,"(A)") trim(Dir_Cli)//"Clim_Mean_Bias_"//trim(Model_nm)//"_"//trim(yvarn)//".nc"
   Call Write_Clim_data (Fname)
      
   Nyear=Nyrs
   Do ilead=1,NLead
      if (Allocated(X5d)) Deallocate (X5d)
      Allocate (X5d(Nlon,Nlat,Nmon,Nyear,5))   ! 5th-dimension = 4: 1) OBS, 2) ANN est, 3) Cli BC, 4) Model out, 5) mlr 
      X5d=Miss
      Do imon=1,Nmon
         if (Allocated(X4d)) Deallocate (X4d)
         Allocate (X4d(Nlon,Nlat,4,Nyrs)) !-1))  ! z=4: 1) Yobs, 2) Yest, 3) Ymodel, 4) Mlr
         X4d=Miss
         Do ireg=1,Nreg
            Call Make_Data (trim(yvarn),ireg,imon,ilead)
            write (save_file,"(3(A,I2.2),A)") trim(Dir_ANN_Save)//"Sav_"//trim(yvarn)//"_"//trim(Model_nm)//"_Reg_",ireg,"_mon_",imon,"_lead_",ilead,".txt"
            learning_rate = learning_rate0 !  0.05
            Call ANN_2023(Inputs_X,Outputs_Y,Nsample1,Mvars,1,Miss)    !ANN_2023 (Xinp,Youtp,Nspl,MXvar,MYvar,Miss)
            Call Calc_HQTT (ilead,imon,ireg)    ! Return to Xhq(Nsample1)

            Call Convert_to_lat_lon (ireg)      ! Return to X4d
         Enddo
         Call Store_5th_Arr (ilead,imon)
      Enddo
      write (Fname,"(A,I2.2,A)") trim(Dir_Corrected)//"BC_Training_"//trim(yvarn)//"_"//trim(Model_nm)//"_lead_",ilead,".nc"
      Call Write_Out_4_Drought (Fname,yvarn)
   Enddo
   Fname=trim(Dir_Cli)//"Beta_"//trim(yvarn)//"_"//trim(Model_nm)//".nc"
   Call Write_Beta_HQ (Fname,yvarn)
   !--------------------------------------------------------------------------------
      
   CONTAINS
   !--------------------------------------------------------------------------------
   Subroutine Calc_HQTT (ilead,imon,ireg)
      Integer :: i,j,k, ilead,imon,ireg
      Real :: S,Q,U,RR,F, tmp
      Real, Allocatable :: X2d(:,:), Check(:), A(:)
      Real :: xtmp(Mvars)
      Logical :: OK

      ! Xhq(:), Beta(:)
      Mhq = Mvars+1      ! Tong cac bien Doc lap va 1 bien phu thuoc
      Allocate (X2d(Nsample1,Mhq),Check(Nsample1))
      icount=0; Check=0
      Do i=1,Nsample1
         xtmp(1:Mvars)=X_inp(i,1:Mvars); OK=Valid_Ar1(xtmp,Mvars,Miss)
         if (Y_inp(i)/=Miss.AND.OK) then
            icount=icount+1; Check(i)=1
            X2d(icount,1)=Y_inp(i); X2d(icount,2:Mhq)=X_inp(i,1:Mvars)
         endif
      Enddo
      Nhq = Mhq*icount   ! N x M
      if (Allocated (Xorg)) Deallocate (Xorg) ! 1-D array X(N x M)
      Allocate (Xorg(Nhq))
      i=0
      Do j=1,Mhq
         Do it=1,icount   ! Sample size
            i=i+1; Xorg(i)=X2d(it,j)          ! Xorg(icount x Mhq)
         Enddo
      Enddo
      Nhq = icount  ! Sample size
      Deallocate (X2d)

      Allocate (A(Mhq))                       ! Regression Coefficiences
      Call REGRE(Xorg,Nhq,Mhq,A,S,Q,U,RR,F)
      if (.not.Allocated(Beta)) Allocate (Beta(NLead,Nmon,Nreg,Mhq))  ! To be written out to file
      Beta(ilead,imon,ireg,1:Mhq) = A(1:Mhq)     ! Luu he so HQ
      ! Tinh gia tri HQ:
      if (Allocated (Xhq)) Deallocate (Xhq); Allocate (Xhq(Nsample1)); Xhq=Miss
      Do i=1,Nsample1
         if (Check(i)==1) then
            tmp=0.
            Do j=2,Mhq
               tmp=tmp+A(j)*X_inp(i,j-1)
            Enddo
            Xhq(i)=A(1) + tmp
         endif
      Enddo
      Deallocate (A,Check)
   End Subroutine Calc_HQTT
   !--------------------------------------------------------------------------------
   Subroutine Write_Beta_HQ (Fname,yvarn)
      Character (Len=*) :: Fname,yvarn
      Character (Len=250) :: var_nm, t_unit, var_ln, var_unit, lon_nm, lat_nm, z_nm, t_nm, var_longname
      Real :: xlead(NLead),xmon(Nmon),xreg(Nreg),xvar(Mhq)

      ! (Beta(NLead,Nmon,Nreg,Mhq)
      Do i=1,NLead; xlead(i)=i; Enddo
      Do i=1,Nmon;  xmon (i)=i; Enddo
      Do i=1,Nreg;  xreg (i)=i; Enddo
      Do i=1,Mhq;   xvar (i)=i; Enddo
      t_unit="months since 1982-01-01 ";
      lon_nm="lead"; lat_nm="mon"; t_nm="reg"; z_nm="var"
      var_ln="Multi Linear Regression Coefficiences"
      Call wr_ncdf_4d (Fname,xlead,xmon,xreg,xvar,NLead,Nmon,Nreg,Mhq,Beta,"beta", &
                      t_unit, var_ln, var_unit, lon_nm, lat_nm, z_nm, t_nm, Miss)
   End Subroutine Write_Beta_HQ
   !--------------------------------------------------------------------------------
   Subroutine Write_Out_4_Drought (Fname,yvarn)
      Character (Len=*) :: Fname,yvarn
      Integer, parameter :: Nvar=5      ! For writing out
      Character (Len=250) :: var_nm, t_unit, var_ln, var_unit, lon_nm, lat_nm, z_nm, t_nm, var_longname
      Integer :: imon,iyr,imem,ivar,it, Nz
      Real, Allocatable :: Y4d(:,:,:,:), zlev(:), xtime(:)
      Character (Len=3), parameter :: vname(Nvar)=(/"obs","ann","mod","cli","mlr"/)
      Character (Len=20), parameter :: v_ln(Nvar)=(/"observation","ANN estimation","Model Forecast","Climatology bias correction","Multi Linear Reg."/)
      ! X6d(Nlon,Nlat,Nmon,Nyear,Nmem+1,5)

      Nz=Nvar;
      Allocate (zlev(Nz),xtime(Ntime),Y4d(Nlon,Nlat,Nz,Ntime))
      Do i=1,Nz; zlev(i)=i; Enddo; 
      Do i=1,Ntime; xtime(i)=i; Enddo
      t_unit="months since 1982-01-01 "; lon_nm="lon"; lat_nm="lat"; t_nm="month"; z_nm="member"
      if (trim(yvarn)=="pr") then
         var_unit="mm/month"
      else
         var_unit="C degree"
      endif
      var_ln="Outputs of "//trim(yvarn)//" for drought calculation. z=1:obs, 2:ann, 3:model, 4:cli, 5: mlr "
      Do ivar=1,Nvar
         it=0
         Do iyr=1,Nyear
            Do imon=1,Nmon
               it=it+1; 
               Do ilon=1,Nlon
                  Do ilat=1,Nlat
                     Y4d(ilon,ilat,ivar,it)=X5d(ilon,ilat,imon,iyr,ivar)
                  Enddo
               Enddo
            Enddo
         Enddo
      Enddo
      Call wr_ncdf_4d (Fname,Lon,Lat,zlev,xtime,Nlon,Nlat,Nz,Ntime,Y4d,trim(yvarn), &
                      t_unit, var_ln, var_unit, lon_nm, lat_nm, z_nm, t_nm, Miss)
   End Subroutine Write_Out_4_Drought
   !--------------------------------------------------------------------------------
   Subroutine Write_Clim_data (Fname)  ! Trung binh khi hau cua tat ca cac bien
      Character (Len=*) :: Fname
      Character (Len=250) :: var_ln1, t_unit, var_ln, var_unit, lon_nm, lat_nm, z_nm, t_nm
      Real, Allocatable, Dimension (:) :: zlev, xtime
      Real, Allocatable :: X4d(:,:,:,:)
      INteger :: i, Nz

!   Real, Allocatable   :: Clim   (:,:,:,:,:) ! (Nlon,Nlat,Nmon,Nvar,NLead)  - Original Clim
!   Character (Len=4)  :: vname(Nvar)=(/"pr_o","t2_o","tx_o","tm_o","pr","t2","tx","tm", &
!                                       "h500","h850","olr","q2","rh2","slp","u200","u850","w700"/)
! Bias_Cli(Nlon,Nlat,NLead,Nmon)

      Allocate (zlev(NLead),xtime(Nmon),X4d(Nlon,Nlat,NLead,Nmon))
      Do i=1,NLead; zlev(i)=i; Enddo; Do i=1,Nmon; xtime(i)=i; Enddo
      t_unit="months since 1982-01-01 "; lon_nm="lon"; lat_nm="lat"; t_nm="mon"; z_nm="lead"
      var_ln1="Climatological mean of the Model outputs and observarions for the period 1982-2020."
      Do ivar=1,Nvar
         Do ilead=1,NLead
            Do imon=1,Nmon
               Do ilon=1,Nlon
                  Do ilat=1,Nlat
                     X4d(ilon,ilat,ilead,imon)=Clim(ilon,ilat,imon,ivar,ilead)
                  Enddo
               enddo
            Enddo
         Enddo
         var_ln=trim(var_ln1)//" Variable: "//trim(vname(ivar))
         if (ivar==1) then
            Call wr_ncdf_4d (Fname,Lon,Lat,zlev,xtime,Nlon,Nlat,NLead,Nmon,X4d,trim(vname(ivar)), &
                         t_unit, var_ln,trim(v_unit(ivar)), lon_nm, lat_nm, z_nm, t_nm, Miss)
         else
            Call wr_ncdf_4d_apd (Fname,X4d,trim(vname(ivar)), Nlon,Nlat,NLead,Nmon, &
                                var_ln,trim(v_unit(ivar)), lon_nm, lat_nm, z_nm, t_nm, Miss)
         endif
      Enddo
      var_ln="Differences between model outputs and observarions used as climatological biases."
      if (yvarn=="pr") then; var_unit="mm/month"; else; var_unit="C deg"; endif
      Call wr_ncdf_4d_apd (Fname,Bias_Cli,"bias",Nlon,Nlat,NLead,Nmon, &
                                var_ln,var_unit, lon_nm, lat_nm, z_nm, t_nm, Miss)
      print*,"Write_Bias_Cli... Done!"
   End Subroutine Write_Clim_data
   !--------------------------------------------------------------------------------
   Subroutine Convert_to_lat_lon (ireg)
      Integer :: ireg,ilon,ilat,it,iyr

      it=0
      Do ilon=1,Nlon
         Do ilat=1,Nlat
            if (Int(Regs(ilon,ilat))==ireg) then
               Do iyr=1,Nyrs !-1
                  it=it+1
                  X4d(ilon,ilat,1,iyr)=Y_inp(it)    ! Obs Anomaly
                  X4d(ilon,ilat,2,iyr)=Yest(it,1)   ! Ann Anomaly estimated
                  X4d(ilon,ilat,3,iyr)=X_inp(it,1)  ! Model Anomaly
                  X4d(ilon,ilat,4,iyr)=Xhq(it)      ! MLR Anomaly
               Enddo
            endif
         Enddo
      Enddo
      !print*,"Size of Y_inp(:),X_inp(:,:): ",Size(Y_inp, Dim=1), Size(X_inp, Dim=1), Size(X_inp, Dim=2)
      !print*,"Convert: Nit=",it; pause

   End Subroutine Convert_to_lat_lon
   !--------------------------------------------------------------------------------
   Subroutine Store_5th_Arr (ilead,imon)
      Integer :: imon,imem,ilon,ilat,it,iyr,iob,ifc
      Real    :: xtmp, o1,o2,o3,o4, c1,c2,c3,c4

      ! X5d(Nlon,Nlat,Nmon,Nyear,5) - 1) OBS, 2) ANN est, 3) Model out, 4) Cli BC, 5) Mlr
      ! X4d(Nlon,Nlat,4,Nyrs)) !-1))  ! z=4: 1) Yobs, 2) Yest, 3) Ymodel, 4) Mlr
      if (yvarn=="pr") then
         iob=1; ifc=5
      elseif (yvarn=="t2") then
         iob=2; ifc=6
      elseif (yvarn=="tx") then
         iob=3; ifc=7
      elseif (yvarn=="tm") then
         iob=4; ifc=8
      endif

      !Do it=1,3             ! 1) OBS, 2) ANN est, 3) Model out
      Do iyr=1,Nyear     ! imem=1,Nmem
         Do ilon=1,Nlon
            Do ilat=1,Nlat
               if (Int(Regs(ilon,ilat))>0) then
                  !X5d(ilon,ilat,imon,iyr,it)=X4d(ilon,ilat,it,iyr)
                  o1=X4d(ilon,ilat,1,iyr); c1=Clim(ilon,ilat,imon, iob,ilead)
                  o2=X4d(ilon,ilat,2,iyr); c2=Clim(ilon,ilat,imon, iob,ilead)
                  o3=X4d(ilon,ilat,3,iyr); c3=Clim(ilon,ilat,imon, ifc,ilead)
                  o4=X4d(ilon,ilat,4,iyr); c4=Clim(ilon,ilat,imon, iob,ilead)
                  if (o1/=Miss.AND.c1/=Miss) X5d(ilon,ilat,imon,iyr,1) = o1+c1 ! Obs Ano + Obs Clim = Org Obs
                  if (o2/=Miss.AND.c2/=Miss) X5d(ilon,ilat,imon,iyr,2) = o2+c2 ! Ann Ano + Obs Clim = Ann
                  if (o3/=Miss.AND.c3/=Miss) X5d(ilon,ilat,imon,iyr,3) = o3+c3 ! Mod Ano + Mod Clim = Org Mod
                  if (o4/=Miss.AND.c4/=Miss) X5d(ilon,ilat,imon,iyr,5) = o4+c4 ! Mlr Ano + Obs Clim = Mlr  <<<<<< Chu y: Gan vao chi so thu 5

                  if (X5d(ilon,ilat,imon,iyr,2)<0) X5d(ilon,ilat,imon,iyr,2) = 0 ! Monthly rainfall and Temp. must not be negative
                  if (X5d(ilon,ilat,imon,iyr,5)<0) X5d(ilon,ilat,imon,iyr,5) = 0 ! Monthly rainfall and Temp. must not be negative

                  !X5d(ilon,ilat,imon,iyr,1)=X4d(ilon,ilat,1,iyr) + Clim(ilon,ilat,imon, iob,ilead) ! Obs Ano + Obs Clim = Org Obs
                  !X5d(ilon,ilat,imon,iyr,2)=X4d(ilon,ilat,2,iyr) + Clim(ilon,ilat,imon, iob,ilead) ! Ann Ano + Obs Clim = Ann
                  !X5d(ilon,ilat,imon,iyr,3)=X4d(ilon,ilat,3,iyr) + Clim(ilon,ilat,imon, ifc,ilead) ! Mod Ano + Mod Clim = Org Mod

                  ! 4) Cli: Climatological Bias Correction: Clim(Nlon,Nlat,Nmon, Nvar,NLead):
                  if (X4d(ilon,ilat,3,iyr)/=Miss.AND.Bias_Cli(ilon,ilat,ilead,imon)/=Miss) then
                     xtmp=X5d(ilon,ilat,imon,iyr,3)     ! Org Mod
                     if (yvarn=="pr") then
                        !X5d(ilon,ilat,imon,iyr,4)=X4d(ilon,ilat,3,iyr)*Bias_Cli(ilon,ilat,ilead,imon)   ! For rainfall: BC = Model*BC_Factor
                        X5d(ilon,ilat,imon,iyr,4) = xtmp * Bias_Cli(ilon,ilat,ilead,imon) ! For rainfall: BC = Model*BC_Factor
                     else
                        !X5d(ilon,ilat,imon,iyr,4)=X4d(ilon,ilat,3,iyr)+Bias_Cli(ilon,ilat,ilead,imon)   ! For Temp. X1d = Model+Bias = Corrected
                        X5d(ilon,ilat,imon,iyr,4) = xtmp + Bias_Cli(ilon,ilat,ilead,imon) ! For Temp. X1d = Model+Bias = Corrected 
                     endif
                     if (X5d(ilon,ilat,imon,iyr,4)<0) X5d(ilon,ilat,imon,iyr,4)=0         ! Monthly rainfall and Temp. must not be negative
                  else
                     X5d(ilon,ilat,imon,iyr,4)=Miss
                  endif
               endif
            Enddo
         Enddo
      Enddo
      !Enddo
      !  4) Cli: Climatological Bias Correction: Clim(Nlon,Nlat,Nmon, Nvar,NLead)
      !Do ilon=1,Nlon
      !   Do ilat=1,Nlat
      !      if (Int(Regs(ilon,ilat))>0) then
      !         Do iyr=1,Nyear
      !            if (X4d(ilon,ilat,3,iyr)/=Miss.AND.Bias_Cli(ilon,ilat,ilead,imon)/=Miss) then
      !               xtmp=X5d(ilon,ilat,imon,iyr,3)     ! Org Mod
      !               if (yvarn=="pr") then
                        !X5d(ilon,ilat,imon,iyr,4)=X4d(ilon,ilat,3,iyr)*Bias_Cli(ilon,ilat,ilead,imon)   ! For rainfall: BC = Model*BC_Factor
      !                  X5d(ilon,ilat,imon,iyr,4) = xtmp * Bias_Cli(ilon,ilat,ilead,imon)
      !               else
                        !X5d(ilon,ilat,imon,iyr,4)=X4d(ilon,ilat,3,iyr)+Bias_Cli(ilon,ilat,ilead,imon)   ! For Temp. X1d = Model+Bias = Corrected
      !                  X5d(ilon,ilat,imon,iyr,4) = xtmp + Bias_Cli(ilon,ilat,ilead,imon)
      !               endif
      !               if (X5d(ilon,ilat,imon,iyr,4)<0) X5d(ilon,ilat,imon,iyr,4)=0                       ! Monthly rainfall and Temp. must not be negative
      !            else
      !               X5d(ilon,ilat,imon,iyr,4)=Miss 
      !            endif
      !         Enddo
      !      endif
      !   Enddo
      !Enddo
   End Subroutine Store_5th_Arr
   !--------------------------------------------------------------------------------
   Subroutine Make_Data (yvarn,ireg,imon,ilead)
      Character (Len=*) :: yvarn
      Integer :: ireg,imon,imon1,ilead,ipredictand,iprd
      Integer :: ilon,ilat,it,Npoint,Mx,i,j,Nspl,iyr,icount
      Real, Allocatable :: X2d(:,:)

      Npoint = Get_Reg_Points (ireg)   
      Ngrd   = Npoint      ! So diem luoi trong vung ireg
      Nsample1=Nyrs*Npoint  ! Dung luong mau
      !print*,"Nsample1,Nyrs=",Nsample1,Nyrs
      Mx=22                 ! So bien doc lap
      Mvars=Mx
      if (Allocated(X_inp)) Deallocate (X_inp)
      if (Allocated(Y_inp)) Deallocate (Y_inp)
      Allocate (X_inp(Nsample1,Mx),Y_inp(Nsample1))
      if (yvarn=="pr") then
         ipredictand=1; iprd=5
      elseif (yvarn=="t2") then
         ipredictand=2; iprd=6
      elseif (yvarn=="tx") then
         ipredictand=3; iprd=7
      elseif (yvarn=="tm") then
         ipredictand=4; iprd=8
      endif

      i=0
      Do ilon=1,Nlon
         Do ilat=1,Nlat
            if (Int(Regs(ilon,ilat))==ireg) then
               Do it=1,Ntime
                  imon1=mod(it,Nmon); if (imon1==0) imon1=Nmon
                  if (imon1==imon) then
                     i=i+1
                     Y_inp(i)  =Dat_All(ilon,ilat,it,ipredictand,ilead)   ! Observation
                     X_inp(i,1)=Dat_All(ilon,ilat,it,iprd,ilead)          ! Model fcs
                     X_inp(i,2)=Dat_All(ilon,ilat,it,11,ilead)   ! olr
                     X_inp(i,3)=Dat_All(ilon,ilat,it,12,ilead)   ! q2
                     X_inp(i,4)=Dat_All(ilon,ilat,it,13,ilead)   ! rh2
                     X_inp(i,5)=Dat_All(ilon,ilat,it,17,ilead)   ! w700
                     if (Dat_All(ilon,ilat,it,15,ilead)/=Miss.AND.Dat_All(ilon,ilat,it,16,ilead)/=Miss) then
                        X_inp(i,6)=Dat_All(ilon,ilat,it,15,ilead)-Dat_All(ilon,ilat,it,16,ilead) ! u200-u850
                     else
                        X_inp(i,6)=Miss
                     endif
                     ! 4 neighbor gridpoints
                     X_inp(i,7)=Dat_All(ilon-1,ilat,it,iprd,ilead)          ! Model fcs
                     X_inp(i,8)=Dat_All(ilon+1,ilat,it,iprd,ilead)          ! Model fcs
                     X_inp(i,9)=Dat_All(ilon,ilat-1,it,iprd,ilead)          ! Model fcs
                     X_inp(i,10)=Dat_All(ilon,ilat+1,it,iprd,ilead)          ! Model fcs

                     X_inp(i,11)=Dat_All(ilon-1,ilat,it,11,ilead)   ! olr
                     X_inp(i,12)=Dat_All(ilon+1,ilat,it,11,ilead)   ! olr
                     X_inp(i,13)=Dat_All(ilon,ilat-1,it,11,ilead)   ! olr
                     X_inp(i,14)=Dat_All(ilon,ilat+1,it,11,ilead)   ! olr

                     X_inp(i,15)=Dat_All(ilon-1,ilat,it,17,ilead)   ! w700
                     X_inp(i,16)=Dat_All(ilon+1,ilat,it,17,ilead)   ! w700
                     X_inp(i,17)=Dat_All(ilon,ilat-1,it,17,ilead)   ! w700
                     X_inp(i,18)=Dat_All(ilon,ilat+1,it,17,ilead)   ! w700

                     X_inp(i,19)=Dat_All(ilon-1,ilat,it,12,ilead)   ! q2
                     X_inp(i,20)=Dat_All(ilon+1,ilat,it,12,ilead)   ! q2
                     X_inp(i,21)=Dat_All(ilon,ilat-1,it,12,ilead)   ! q2
                     X_inp(i,22)=Dat_All(ilon,ilat+1,it,12,ilead)   ! q2

                     !if (Dat_All(ilon,ilat,it,9,ilead)/=Miss.AND.Dat_All(ilon,ilat,it,10,ilead)/=Miss) then
                     !    X_inp(i,2)=Dat_All(ilon,ilat,it,9,ilead)-Dat_All(ilon,ilat,it,10,ilead)  ! h500-h850
                     !else
                     !    X_inp(i,2)=Miss
                     !endif
                     !X_inp(i,3)=Dat_All(ilon,ilat,it,11,ilead)   ! olr
                     !X_inp(i,4)=Dat_All(ilon,ilat,it,12,ilead)   ! q2
                     !X_inp(i,5)=Dat_All(ilon,ilat,it,13,ilead)   ! rh2
                     !X_inp(i,6)=Dat_All(ilon,ilat,it,14,ilead)   ! slp
                     !if (Dat_All(ilon,ilat,it,15,ilead)/=Miss.AND.Dat_All(ilon,ilat,it,16,ilead)/=Miss) then
                     !   X_inp(i,7)=Dat_All(ilon,ilat,it,15,ilead)-Dat_All(ilon,ilat,it,16,ilead) ! u200-u850
                     !else
                     !   X_inp(i,7)=Miss
                     !endif
                     !X_inp(i,8)=Dat_All(ilon,ilat,it,17,ilead)   ! w700
                  endif
               Enddo
            endif
         Enddo
      Enddo
      Nspl=i
      Nsample1=Nspl
      if (Allocated(Inputs_X)) Deallocate (Inputs_X)
      if (Allocated(Outputs_Y)) Deallocate (Outputs_Y)
      Allocate (Inputs_X(Mx,Nsample1), Outputs_Y(1,Nsample1))
      i=0
      Do it=1,Nspl
         i=i+1
         Outputs_Y(1,i)=Y_inp(it)
         Do j=1,Mx
            Inputs_X(j,i)=X_inp(it,j)
         Enddo
      Enddo
      !print*,"Nsample1,i,Npoint,Nsample1/Npoint=",Nsample1,i,Npoint,Nsample1/Npoint; pause
      Deallocate (Y_inp,X_inp)
      Allocate (Y_inp(Nsample1),X_inp(Nsample1,Mx))
      Y_inp(1:Nsample1)=Outputs_Y(1,1:Nsample1); 
      Do j=1,Mx
         X_inp(1:Nsample1,j)=Inputs_X(j,1:Nsample1)
      Enddo

      ! ------------------------------------
      ! For Regression:  Valid_Ar1(X,N,Miss)

!      Mhq = Mx+1      ! Tong cac bien Doc lap va 1 bien phu thuoc
!      Allocate (X2d(Nsample1,Mhq))
!      icount=0
!      Do i=1,Nsample1
!         if (Y_inp(i)/=Miss.AND.Valid_Ar1(X_inp(i,1:Mx))) then
!            icount=icount+1
!            X2d(icount,1)=Y_inp(i); X2d(icount,2:Mhq)=X_inp(i,1:Mx)
!         endif
!      Enddo
!      Nhq = Mhq*icount   ! N x M
!      if (Allocated (Xorg)) Deallocate (Xorg)
!      Allocate (Xorg(Nhq))
!      i=0
!      Do j=1,Mhq
!         Do it=1,icount   ! Sample size
!            i=i+1; Xorg(i)=X2d(it,j)
!         Enddo
!      Enddo
!      Nhq = icount  ! Sample size
!      Deallocate (X2d)
   End Subroutine Make_Data
   !--------------------------------------------------------------------------------
   Integer Function Get_Reg_Points (ireg)
      Integer :: ireg,ilon,ilat,Npoint

      Npoint=0
      Do ilon=1,Nlon
         Do ilat=1,Nlat
            if (Regs(ilon,ilat)==ireg) Npoint=Npoint+1
         Enddo
      Enddo
      Get_Reg_Points = Npoint
   End Function Get_Reg_Points
   !--------------------------------------------------------------------------------
   Subroutine Calc_Bias_Cli (yvarn)
      Character (Len=*) :: yvarn
      !Integer, parameter :: Nt0=348, Nyr=Nt0/Nmon   ! 1/1982-12/2010
      Integer :: ilon,ilat,imon,imon1,it,ilead,iob,ifc,iyr
      !Real :: F(Nt0), O(Nt0), Xo(Nyr), Xf(Nyr), MeanO,MeanF
      Real :: F(Ntime),O(Ntime),Xo(Nyrs),Xf(Nyrs), MeanO,MeanF

      if (yvarn=="pr") then
         iob=1; ifc=5
      elseif (yvarn=="t2") then
         iob=2; ifc=6
      elseif (yvarn=="tx") then
         iob=3; ifc=7
      elseif (yvarn=="tm") then
         iob=4; ifc=8
      endif
      if (Allocated(Bias_Cli)) Deallocate (Bias_Cli)      
      Allocate (Bias_Cli(Nlon,Nlat,NLead,Nmon)); Bias_Cli=Miss
      Do ilon=1,Nlon
         Do ilat=1,Nlat
            if (Int(Regs(ilon,ilat))>0) then
               Do ilead=1,NLead
                  Do imon=1,Nmon
                     MeanO=Clim(ilon,ilat,imon,iob,ilead)
                     MeanF=Clim(ilon,ilat,imon,ifc,ilead)
                     if (MeanO/=Miss.AND.MeanF/=Miss.AND.MeanF/=0.) then
                        if (yvarn=="pr") then                                ! For rainfall: Del_Cli=MeanO/MeanF
                           Bias_Cli(ilon,ilat,ilead,imon)=MeanO/MeanF         ! Model_BC = Del_Cli*Model
                        else
                           Bias_Cli(ilon,ilat,ilead,imon)=MeanO-MeanF         ! Model_BC = MeanF + Del_Cli
                        endif
                     endif
                  Enddo
               Enddo
            endif
         Enddo
      Enddo
      !Del_Cli(:,:,NLead+1,:)=Del_Cli(:,:,NLead,:)  ! Dong lenh nay thua, vi Nlead+1=7 khong can nua. 
   End Subroutine Calc_Bias_Cli
   !--------------------------------------------------------------------------------
   Subroutine Calc_Clim_and_Anomaly    ! Calcutale clim and anomaly of all variables
      Integer :: ilon,ilat,imon,imon1,it,ilead,iob,ifc,iyr,ireg
      Real :: F(Ntime),O(Ntime),Xo(Nyrs),Xf(Nyrs), Mean, xtmp

!   Real, Allocatable   :: Dat_All(:,:,:,:,:) ! (Nlon,Nlat,Ntime,Nvar,NLead) - Anomaly data = Original data - Original Clim
!   Real, Allocatable   :: Dat_Org(:,:,:,:,:) ! (Nlon,Nlat,Ntime,Nvar,NLead) - Original data
!   Real, Allocatable   :: Clim   (:,:,:,:,:) ! (Nlon,Nlat,Nmon,Nvar,NLead)  - Original Clim
!   Character (Len=4)  :: vname(Nvar)=(/"pr_o","t2_o","tx_o","tm_o","pr","t2","tx","tm", &
!                                       "h500","h850","olr","q2","rh2","slp","u200","u850","w700"/)
      Allocate (Dat_All(Nlon,Nlat,Ntime,Nvar,NLead))
      Allocate (Clim   (Nlon,Nlat,Nmon, Nvar,NLead))
      Dat_All=Miss; Clim=Miss

      Do ilead=1,NLead
         Do ivar=1,Nvar 
            Do ilon=1,Nlon
               Do ilat=1,Nlat
                  ireg=Int(Regs(ilon,ilat))

                  ! Mean values
                  Do imon=1,Nmon
                     iyr=0
                     Do it=1,Ntime
                        imon1=mod(it,Nmon); if (imon1==0) imon1=Nmon
                        if (imon1==imon) then
                           iyr=iyr+1; Xf(iyr)=Dat_Org(ilon,ilat,it,ivar,ilead)
                        endif
                     Enddo
                     Mean = Ave(Xf,iyr,Miss)

                     if (ivar<=4) then !.AND.ireg<=0) then   ! For Obs data 
                        if (ireg>0) then
                           Clim(ilon,ilat,imon,ivar,ilead)=Mean
                        else
                           Clim(ilon,ilat,imon,ivar,ilead)=Miss
                        endif 
                     else                            ! For model data
                        Clim(ilon,ilat,imon,ivar,ilead)=Mean
                     endif
                  Enddo

                  ! Anomaly
                  Do it=1,Ntime
                     imon1=mod(it,Nmon); if (imon1==0) imon1=Nmon
                     Mean = Clim(ilon,ilat,imon1,ivar,ilead)
                     xtmp = Dat_Org(ilon,ilat,it,ivar,ilead)
                     if (ivar<=4) then !.AND.ireg<=0) then   ! For Obs data
                        if (ireg>0) then
                           !Dat_All(ilon,ilat,it,ivar,ilead)=Dat_Org(ilon,ilat,it,ivar,ilead)-Mean
                           if (Mean/=Miss.AND.xtmp/=Miss) Dat_All(ilon,ilat,it,ivar,ilead)=xtmp-Mean
                        else
                           Dat_All(ilon,ilat,it,ivar,ilead)=Miss
                        endif
                     else
                        !Dat_All(ilon,ilat,it,ivar,ilead)=Dat_Org(ilon,ilat,it,ivar,ilead)-Mean
                        if (Mean/=Miss.AND.xtmp/=Miss) Dat_All(ilon,ilat,it,ivar,ilead)=xtmp-Mean
                     endif
                  Enddo
               Enddo
            Enddo
         Enddo
      Enddo
   End Subroutine Calc_Clim_and_Anomaly
   !--------------------------------------------------------------------------------
   Subroutine Read_all_data (Dir,Model_nm)  ! Read all Dat_Org
      Character (Len=*) :: Dir,Model_nm
      Character (Len=255) :: Fname
      Real, Allocatable :: xlon(:),xlat(:),xtime(:)
      Integer :: ilead,ivar,Nlo,Nla,Nt

      Do ilead=1,NLead  ! lead3_RegCM_01_BL_Test_VN.nc
         write(Fname,"(A,I1.1,A)") trim(Dir)//"lead",ilead,"_"//trim(Model_nm)//"_01_BL_Test_VN.nc"  ! clWRF_VN.nc"
         Do ivar=1,Nvar
            Call rd_ncdf_3d (Fname,xlon,xlat,xtime,Nlo,Nla,Nt,X3d,trim(vname(ivar)))
            if (ilead==1.AND.ivar==1) then
               Ntime=Nyrs*Nmon ! Ntime=Nt
               Allocate (Dat_Org(Nlon,Nlat,Ntime,Nvar,NLead))
               Dat_Org=Miss
            endif
            Dat_Org(:,:,1:Nt,ivar,ilead) = X3d(:,:,1:Nt)
            Deallocate (xlon,xlat,xtime,X3d)
         Enddo
      Enddo
   End Subroutine Read_all_data
   !--------------------------------------------------------------------------------
     
   Include "/home/tanpv/Mylibs/Sub_HQTT.f90"
   !Include "/home/tanpv/Mylibs/Sub_LAD.f90"
   !Include "/home/tanpv/Mylibs/Sub_LMV.f90"
   Include "/home/tanpv/Mylibs/Calc_Correlation_Coefficient.f90"  ! Correlation (X, Y, N, Corr, Prob, Miss)
   Include "/home/tanpv/Mylibs/Sub_Verification.f90"              ! ME, MAE, RME, RMAE
   Include "/home/tanpv/Mylibs/sub_wr_ncdf_Tan.F90" 
   Include "/home/tanpv/Mylibs/sub_rd_ncdf_Tan.F90"
   Include "/home/tanpv/Mylibs/Sub_neural_2023.f90"
   Include "/home/tanpv/Mylibs/Stdev.f90"
   Include "/home/tanpv/Mylibs/Ave.f90"
   Include "/home/tanpv/Mylibs/Function_Valid_Ar1.f90"

   !--------------------------------------------------------------------------------
   END
   Include "/home/tanpv/Mylibs/Student_Prob.f90"
   !-------------------------------------------------------------------------------------------
