
SUBROUTINE write_stn_data_to_NC(filename,slon,slat, time,nsta,ntime,staname,nvar,var_name,var_units,data,flag)
!
! Purpose: this sub will creat a out netcdf file from input dataset
! of given stations and one variable 
!
! INPUT:
! filename: output netcdf data file
! slon: 1-D array of station longitudes that have nsta dimension
! slon: 1-D array of station latitudes that have nsta dimension
! nsta: number of given station
! ntime: dimension of time scale
! staname: 1-D array of station name has nsta dimension
! nvar: number of input variables
! var_name: name array of given Met variable has nvar dimension
! var_units: unit array of given Met variable has nvar dimension
! data: 3-D data array of given variables that have
!       nsta x ntime x nvar dimension
! flag: error flag that is fixed equal -99
!
! OUTPUT: netcdf file
!
   use netcdf
   implicit none
   
   character (len = *), intent (in) :: filename
   character (len = *), parameter :: lon_name = "lon", lat_name = "lat", time_name = "time",sname = "sta_name"
   integer, parameter :: ndims = 2
   integer :: nvar, nf90_put_att_text
   integer :: ncid, lon_id,lat_id,timdim_id, time_id,stadim_id,sta_id,k,var_id(nvar),dims_id(ndims),ilen
   integer, intent (in) :: nsta,ntime
   real, dimension (nsta,ntime,nvar), intent (in) :: data
   character(len = *),dimension(nvar),intent(in) :: var_units
   character(len = *),dimension(nvar),intent(in) :: var_name
   real, intent (in) :: flag
   real, intent (in) :: slon(nsta),slat(nsta),time(ntime)
   character (len = *), intent (in) :: staname(nsta)
   character*4 :: sta_order
   real, dimension (nsta) :: sta_dim

! Begin

!---- Create sid dimension value-----------------------!
   do k = 1, nsta
      sta_dim(k) = real(k)
   end do
   
   write(*,*) "open nc file"
   !----Open file and define Dimensions---------------------------!
   ! one dimension according station, the other according to time !

   call err_handle(nf90_create(filename,nf90_write,ncid))
   call err_handle(nf90_def_dim(ncid,sname,nsta,stadim_id))
   call err_handle(nf90_def_dim(ncid,time_name,ntime,timdim_id))

   write(*,*) "def dim ok"
   !----Define 1D variable------------------------------------------!
   call err_handle(nf90_def_var(ncid,sname,nf90_float,stadim_id, sta_id)) 
   call err_handle(nf90_def_var(ncid,lon_name,nf90_float,stadim_id,lon_id))
   call err_handle(nf90_def_var(ncid,lat_name,nf90_float,stadim_id,lat_id))
   call err_handle(nf90_def_var(ncid,time_name,nf90_float,timdim_id, time_id))
   !----Define 2D variable------------------------------------------!
   dims_id(1) = stadim_id
   dims_id(2) = timdim_id
   Do k = 1,nvar
       call err_handle(nf90_def_var(ncid,trim(var_name(k)),nf90_float,dims_id(1:2),var_id(k)))
   Enddo
   write(*,*) "def var ok"
   
!----Put Attribute of variables----------------------------------!
   call err_handle(nf90_put_att(ncid,lon_id,"long_name",lon_name))
   call err_handle(nf90_put_att(ncid,lon_id,"units","DegreeE"))
   call err_handle(nf90_put_att(ncid,lat_id,"lat_name",lat_name))
   call err_handle(nf90_put_att(ncid,lat_id,"units","DegreeN"))
   call err_handle(nf90_put_att(ncid,time_id,"time_name",time_name))
   call err_handle(nf90_put_att(ncid,time_id,"units","hours"))

!----Put Attribute of station name-------------------------------!  
!@   Do k = 1,nsta
!@      write(sta_order, '(i0)') k
!@      ilen = LEN(trim(staname(k)))
!@      call err_handle(nf90_put_att_text(ncid,sta_id,"sta"//trim(sta_order),ilen,trim(staname(k))))   
!@   Enddo

!----Put Attribute of variables ---------------------------------!  
   Do k = 1, nvar
      write(sta_order, '(i0)') k
      call err_handle(nf90_put_att(ncid,var_id(k),"sta"//trim(sta_order),var_name(k)))
      call err_handle(nf90_put_att(ncid,var_id(k),"units",var_units(k)))
      call err_handle(nf90_put_att(ncid,var_id(k),"missing_value",flag))
   Enddo
   call err_handle ( nf90_enddef(ncid) )
   write(*,*) "put attr ok"
   
   !----Put value of variables-----------------------------------!
   call err_handle(nf90_put_var(ncid,lon_id,slon))
   call err_handle(nf90_put_var(ncid,lat_id,slat))
   call err_handle(nf90_put_var(ncid,time_id,time))

   Do k = 1, nvar
      call err_handle(nf90_put_var(ncid,var_id(k),data(:,:,k)))
   Enddo
   write(*,*) "put value ok"
   
   !----Close file-----------------------------------------------!
   call err_handle ( nf90_close (ncid) )

   print*,"   Completed writing append to file ", filename

   return
END SUBROUTINE write_stn_data_to_NC
!=============================================================================================!
SUBROUTINE write_station_data2netcdf(filename,slon,slat,h,reg, time,nsta,ntime,var_name,var_units,data,flag)
!
! Purpose: this sub will creat a out netcdf file from input dataset
! of given stations and one variable 
!
! INPUT:
! filename: output netcdf data file
! slon: 1-D array of station longitudes that have nsta dimension
! slon: 1-D array of station latitudes that have nsta dimension
! nsta: number of given station
! ntime: dimension of time scale
! var_name: name of given Met variable
! var_units: unit of given Met variable
! data: 2-D data array of given Met variable that have
!       nsta x ntime dimension
! flag: error flag that is fixed equal -99
!
! OUTPUT: netcdf file
!
   use netcdf
   implicit none
   
   character (len = *), intent (in) :: filename, var_name
   character (len = *), parameter :: lon_name = "lon", lat_name = "lat", time_name = "time"
   character (len = *), parameter :: h_name="elevation", reg_name="region" !, stn_name="stn_name"
   integer, parameter :: NDIMS = 5 !3
   integer :: ncid, var_id, dims_id(NDIMS), lon_id, lat_id, time_id, h_id, reg_id  !, stn_id
   integer, intent (in) :: nsta,ntime
   real, dimension (nsta,ntime), intent (in) :: data
   character (len = *), intent (in) :: var_units
   real, intent (in) :: flag
   real, intent (in) :: slon(nsta),slat(nsta),time(ntime), h(nsta), reg(nsta)
!   character (len = *), intent (in) :: stn(nsta)
   
   write(*,*) "open nc file"
   !----Open file and define Dimensions--------------------------------------!
   call err_handle ( nf90_create (filename, nf90_write, ncid) )
   call err_handle ( nf90_def_dim (ncid, lon_name, nsta, dims_id(1)) )
   call err_handle ( nf90_def_dim (ncid, lat_name, nsta, dims_id(2)) )
   call err_handle ( nf90_def_dim (ncid, time_name, ntime, dims_id(3)) )
   call err_handle ( nf90_def_dim (ncid, h_name, nsta, dims_id(4)) )
   call err_handle ( nf90_def_dim (ncid, reg_name, nsta, dims_id(5)) )
!   call err_handle ( nf90_def_dim (ncid, stn_name, nsta, dims_id(6)) )
   
   write(*,*) "def dim ok"
   !----Define variable------------------------------------------------------!
   call err_handle ( nf90_def_var (ncid, lon_name, nf90_float, dims_id(1), lon_id) )
   call err_handle ( nf90_def_var (ncid, lat_name, nf90_float, dims_id(2), lat_id) )
   call err_handle ( nf90_def_var (ncid, time_name, nf90_float, dims_id(3), time_id) )
   call err_handle ( nf90_def_var (ncid, var_name, nf90_float, dims_id(2:3), var_id) )
   call err_handle ( nf90_def_var (ncid, h_name, nf90_float, dims_id(4), h_id) )
   call err_handle ( nf90_def_var (ncid, reg_name, nf90_float, dims_id(5), reg_id) )
!   call err_handle ( nf90_def_var (ncid, stn_name, nf90_char, (/nsts/), stn_id) )! dims_id(6), stn_id) )
   
   write(*,*) "def var ok"
   !----Put Attribute of variables-------------------------------------------!
   call err_handle ( nf90_put_att (ncid, lon_id, "long_name", lon_name) )
   call err_handle ( nf90_put_att (ncid, lon_id, "units",         "DegreeE") )
   call err_handle ( nf90_put_att (ncid, lat_id, "long_name", lat_name) )
   call err_handle ( nf90_put_att (ncid, lat_id, "units",         "DegreeN") )
   call err_handle ( nf90_put_att (ncid, time_id, "long_name", time_name) )
   call err_handle ( nf90_put_att (ncid, time_id, "units",         "Day or Mon") )
   call err_handle ( nf90_put_att (ncid, h_id,    "long_name", h_name) )
   call err_handle ( nf90_put_att (ncid, h_id,    "units",         "m") )
   call err_handle ( nf90_put_att (ncid, h_id,   "missing_value", flag) )
   call err_handle ( nf90_put_att (ncid, reg_id, "long_name", reg_name) )
   call err_handle ( nf90_put_att (ncid, reg_id, "units",         "-") )
!   call err_handle ( nf90_put_att (ncid, stn_id, "long_name", stn_name) )
!   call err_handle ( nf90_put_att (ncid, stn_id, "units",         "-") )

   call err_handle ( nf90_put_att (ncid, var_id, "long_name", var_name) )
   call err_handle ( nf90_put_att (ncid, var_id, "units",         var_units) )
   call err_handle ( nf90_put_att (ncid, var_id, "missing_value", flag) )
   
   call err_handle ( nf90_enddef(ncid) )
   write(*,*) "put attr ok"
   
   !----Put value of variables-----------------------------------------------!
   call err_handle ( nf90_put_var (ncid,lon_id,slon))
   call err_handle ( nf90_put_var (ncid,lat_id,slat))
   call err_handle ( nf90_put_var (ncid,time_id,time))
   call err_handle ( nf90_put_var (ncid,var_id,data))
   call err_handle ( nf90_put_var (ncid,h_id, h))
   call err_handle ( nf90_put_var (ncid,reg_id, reg))
!   call err_handle ( nf90_put_var (ncid,stn_id, stn))

   write(*,*) "put value ok"
   !----Close file-----------------------------------------------------------!
   call err_handle ( nf90_close (ncid) )

   print*,"   Completed writing append to file ", filename

   return
END SUBROUTINE write_station_data2netcdf

!--------------------------------------------------------------------------------------------
!SUBROUTINE write_station_data2netcdf_append(filename,slon,slat, time,nsta,ntime,var_name,var_units,data,flag)
SUBROUTINE write_station_data2netcdf_append (filename,nsta,ntime,var_name,var_units,data,flag)
   use netcdf
   implicit none

   character (len = *), intent (in) :: filename, var_name
   character (len = *), parameter :: lon_name = "lon", lat_name = "lat", time_name = "time"
   character (len = *), parameter :: h_name="elevation", reg_name="region" !, stn_name="stn_name"
   integer, parameter :: NDIMS = 5 ! 3
   integer :: ncid, var_id, dims_id(NDIMS), lon_id, lat_id, time_id, h_id, reg_id !,stn_id
   integer, intent (in) :: nsta,ntime
   real, dimension (nsta,ntime), intent (in) :: data
   character (len = *), intent (in) :: var_units
   real, intent (in) :: flag
   !real, intent (in) :: slon(nsta),slat(nsta),time(ntime)

   write(*,*) "open nc file"
   !----Open file and define Dimensions--------------------------------------!
   call err_handle ( nf90_open   (filename, nf90_write, ncid) )
   call err_handle ( nf90_inq_dimid (ncid, lon_name, dims_id(1)) ) 
   call err_handle ( nf90_inq_dimid (ncid, lat_name, dims_id(2)) )
   call err_handle ( nf90_inq_dimid (ncid, time_name, dims_id(3)) )
   call err_handle ( nf90_inq_dimid (ncid, h_name, dims_id(4)) )
   call err_handle ( nf90_inq_dimid (ncid, reg_name, dims_id(5)) )
!   call err_handle ( nf90_inq_dimid (ncid, stn_name, dims_id(6)) )

   call err_handle ( nf90_redef (ncid) )
   write(*,*) "def dim ok"
   !----Define variable------------------------------------------------------!
   call err_handle ( nf90_def_var (ncid, var_name, nf90_float, dims_id(2:3), var_id) )

   write(*,*) "def var ok"
   !----Put Attribute of variables-------------------------------------------!
   call err_handle ( nf90_put_att (ncid, var_id, "long_name", var_name) )
   call err_handle ( nf90_put_att (ncid, var_id, "units",         var_units) )
   call err_handle ( nf90_put_att (ncid, var_id, "missing_value", flag) )

   call err_handle ( nf90_enddef(ncid) )
   write(*,*) "put attr ok"

   !----Put value of variables-----------------------------------------------!
   call err_handle ( nf90_put_var (ncid,var_id,data))
   write(*,*) "put value ok"
   !----Close file-----------------------------------------------------------!
   call err_handle ( nf90_close (ncid) )

   print*,"   Completed writing append to file ", filename

   return
END SUBROUTINE write_station_data2netcdf_append
!--------------------------------------------------------------------------------------------
SUBROUTINE read_netcdf_station(filename,nstn,ntime,data,var_name,time,slon,slat,h,reg)
!
! INPUT:
! filename: netcdf data file that need to read
! nsta: number of given station
! ntime: dimension of time scale
! var_name: name of given Met variable
!
! OUTPUT:
! data: 2-D data array of given Met variable that have
!       nsta x ntime dimension
!
   use netcdf
   implicit none
   
   character (len = *), intent (in) :: filename, var_name
   character (len = 15) :: lon_name, lat_name, time_name, h_name, reg_name
   integer, parameter :: NDIMS = 5
   integer :: ncid, var_id, lon_id, lat_id, time_id, h_id, reg_id, dims_id(NDIMS)
   integer, intent (in out) :: nstn, ntime
   real, allocatable, dimension(:,:), intent (in out) :: data
   real, allocatable, dimension(:), intent (in out)   :: slon,slat,time, h, reg

   print*,"   Reading netCDF file: ", filename
   call err_handle ( nf90_open (filename, nf90_Nowrite, ncid))
   write(*,*) "Open file ok"

   call err_handle ( nf90_inq_varid (ncid, var_name, var_id))

   lon_name = "lon"; lat_name = "lat" !; time_name = "time"
   h_name="elevation"; reg_name="region" !, stn_name="stn_name"

   call err_handle ( nf90_inq_varid (ncid, lon_name, lon_id))
   call err_handle ( nf90_inq_varid (ncid, lat_name, lat_id))
   call err_handle ( nf90_inq_varid (ncid, h_name, h_id))
   call err_handle ( nf90_inq_varid (ncid, reg_name, reg_id))

   call err_handle ( nf90_inquire_variable (ncid, var_id, dimids = dims_id(2:3)) )
   call err_handle ( nf90_inquire_dimension (ncid, dims_id(2),name = lat_name, len = nstn) )
   call err_handle ( nf90_inquire_dimension (ncid, dims_id(3),name = time_name, len = ntime) )

   Allocate (data(nstn,ntime),slon(nstn),slat(nstn),h(nstn),reg(nstn))

   write(*,*) "Inquire varid ok"
   call err_handle ( nf90_get_var(ncid,var_id,data))
   call err_handle ( nf90_inq_varid (ncid, lon_name, lon_id))
   call err_handle ( nf90_get_var(ncid,lon_id, slon))
   call err_handle ( nf90_inq_varid (ncid, lat_name, lat_id))
   call err_handle ( nf90_get_var(ncid,lat_id, slat))
   call err_handle ( nf90_inq_varid (ncid, h_name, h_id))
   call err_handle ( nf90_get_var(ncid,h_id, h))
   call err_handle ( nf90_inq_varid (ncid, reg_name, reg_id))
   call err_handle ( nf90_get_var(ncid,reg_id, reg))
   call err_handle ( nf90_close(ncid) )
   print*,"   Completed reading file ",filename

   return
END SUBROUTINE read_netcdf_station
!------------------------------------------------------------------------------------
SUBROUTINE err_handle (stat)
   use netcdf
   integer :: stat
   if ( stat .ne. nf90_noerr) then
      print*, trim(nf90_strerror(stat))
      stop
   endif
END SUBROUTINE err_handle
!------------------------------------------------------------------------------------


