program plots_for_one_station
  !
  ! For producing files that can be used to generate "one-station standard plots"
  ! in python and in GrADS. However, these plots need to be generated separately,
  ! i.e., python or GrADS is not called directly from this program.
  !
  ! The following plots can be produced, depending on the details of the
  ! python or GrADS script:
  !
  !  1) The time series of simulated data at one station location,
  !     plotted against the background of the observed quantiles.
  !     Separate plots for 00, 06, 12 and 18 UTC. The plots are
  !     organized so that all the simulation data are projected
  !     on a single annual cycle (normal year, leap days excluded)
  !     regardless of the length of the simulation.
  !
  !  2) A quantile rank histogram, showing the normalized frequencies
  !     for 100 percentile bins from 0-1% to 99-100%. The Mean
  !     Square Deviation and its p-value are written as text in this plot.
  !
  !  NB hard-coding: the program currently gives output only for 00, 06, 12 and 18 UTC.
  !
  ! ----------------------------------------------------------------------
  ! Jouni Räisänen, University of Helsinki, August 2023
  !-----------------------------------------------------------------------
  !
  !  INPUT FILES (all as text files retrieved from .odb format):
  !  ------------------------------------------------------------
  !
  !  sim_file = simulated data from the station location of interest
  !
  !     Each line of this file includes:
  !
  !     1) year 
  !     2) month
  !     3) day
  !     4) hour
  !     5) data value
  !
  !  quantile_file = observed quantiles for this station
  !
  !     Each line of this file includes:
  !
  !     1) station code
  !     2) longitude
  !     3) latitude
  !     4) month
  !     5) day
  !     6) hour
  !     7-105) quantiles from 1% to 99%
  ! 
  !  rank_histogram_file = frequencies and MSD and P-values for plotting the rank histogram
  !
  !     Each line of this file includes:
  !
  !     1) station code
  !     2) longitude
  !     3) latitude
  !     4) UTC hour
  !     5) total number of observation for the UTC hour
  !     6) Mean squared deviation (MSD) of the quantile bin rank histogram wrt a flat histogram
  !     7) p-value of the MSD value, relative to the bootstrap sampling distribution
  !     8-107) frequencies for quantile bins 0-1%, 1-2%, ... ,98-99%, 99-100%
  !
  ! ----------------------------------------------------------------------------------------
  !
  !  OUTPUT FILES in ODB compatible text format (for python)
  !
  !     txt_data_time_series: individual data values from sim_file
  !
  !        The first line is a header. The other lines include:
  !
  !        1) station code
  !        2) longitude
  !        3) latitude
  !        4) year
  !        5) day of year (counted from Jan 1)
  !        6) UTC hour
  !        7) data value
  !  
  !     txt_data_quantiles: selected quantiles from the oberved distribution as a function of UTC hour and time of year
  !
  !        The first line is a header. The other lines include:
  !
  !        1) station code
  !        2) longitude
  !        3) latitude
  !        4) day of year (counted from Jan 1)
  !        5) UTC hour
  !        6-12) quantiles 1, 10, 25, 50, 75, 90 and 99%
  !
  !     txt_data_rank_histogram = quantile bin frequencies (separately for each UTC hour)
  !
  !        The first line is a header. The other lines include:
  !
  !        1) station code
  !        2) longitude
  !        3) latitude
  !        4) UTC hour
  !        5) Mean squared deviation (MSD) of the quantile bin rank histogram wrt a flat histogram
  !        6) p-value of the MSD value, relative to the bootstrap sampling distribution
  !        7-106) frequencies for quantile bins 0-1%, 1-2%, ... ,98-99%, 99-100%
  !
  ! ----------------------------------------------------------------------------------------
  !
  !  OUTPUT FILES in GrADS binary format (for GrADS)
  !
  !     grads_data_time_series = individual data values from sim_file
  !                              + values of selected quantiles as a fuction
  !                              of UTC hour and time of the year.
  ! 
  !     grads_data_rank_histogram = quantile bin frequencies (separately for each UTC hour)
  !
  ! 
  !   In addition, the program writes a few auxilliary texts files with hard-coded names
  !   for use in GrADS scripts:
  !
  !   "vrange_commands" : ranges needed on the y axis of plots
  !   "time_series_commands" : for plotting different years in time series with different colors
  !   "coordinates" : for including coordinate values in GrADS plot
  !   "msd_and_p-value_00" : for including 00 UTC MSD and p-value in GrADS plot
  !   "msd_and_p-value_06" : for including 06 UTC MSD and p-value in GrADS plot
  !   "msd_and_p-value_12" : for including 12 UTC MSD and p-value in GrADS plot
  !   "msd_and_p-value_18" : for including 18 UTC MSD and p-value in GrADS plot
  !   "msd_and_p-value" : for including all-UTC MSD and p-value in GrADS plot  
  !
  !------------------------------------------------------------------------------------------
  !
  !  NAMELIST PARAMETERS:
  !
  ! a) input files (see above)
  !
  ! sim_file  
  ! quantile_file 
  ! rank_histogram_file
  !
  ! b) output files in ODB compatible text format (see above)
  !
  ! txt_data_time_series
  ! txt_data_rank_histogram
  ! txt_data_quantiles
  !
  ! c) output files in GrADS binary format
  !
  ! grads_data_time_series
  ! grads_data_rank_histogram  
  !
  ! d) other
  !
  ! year1,month1 = beginning of the period in time series output
  ! year2,month2 = end of the period in time series output   
  ! include_rank_histograms: if .true. (.false.), rank histogram data is included (excluded) in output 
  ! l_code_in_char : if .true., (.false.) station codes are assumed to be 3-character strings (integers)
  ! l_round_6h : if .true., UTC hours are rounded to the closesest even 6-h (00, 06, 12 or 18 UTC).
  !              if .false., data for non-matching UTC hours are excluded from output
  !
  ! miss = missing value code. Default = -9.99e6. All data f with |f| >= |miss| are treated as missing
  !
  !-------------------------------------------------------------------------------------------
  !
  implicit none
  character*160 :: sim_file ! see above
  character*160 :: quantile_file ! see above
  character*160 :: rank_histogram_file ! see above
  character*160 :: grads_data_time_series ! see above
  character*160 :: grads_data_rank_histogram ! see above
  character*160 :: txt_data_time_series ! see above
  character*160 :: txt_data_quantiles ! see above
  character*160 :: txt_data_rank_histogram ! see above
  integer :: year1,year2 ! first and last year of simulation
  integer :: month1,month2 ! first and last month of simulation 
  integer :: nyear ! number of years = year2-year1+1
  !
  ! Data structures for input data
  !
  integer,parameter :: nhour=4 ! only 00, 06, 12 and 18 UTC used
  integer,parameter :: nmax_years=200 ! maximum length of a simulation in years
  integer,parameter :: ndays_year=365 ! number of days in a non-leap year
  
  real :: f(nmax_years,ndays_year,nhour) ! the simulated values
  real :: f1 ! a single simulated value
  !
  integer,parameter :: nquant=99 ! number of quantiles
  real :: quant(nquant,ndays_year,nhour) ! quantile values from quantile_file
  real :: quant1(nquant) ! quantile values for a single day and UTC hour
  !
  real :: freq(nquant+1,nhour+1) ! quantile bin frequencies from the rank histogram file  
  real :: freq1(nquant+1) ! frequencies for a single UTC hour
  real :: msd(nhour+1) ! MSD value from the rank histogram file
  real :: msd1  ! a single MSD value
  real :: p_value(nhour+1) ! p-values from the rank histogram files
  real :: p_value1 ! a single p-value

  integer :: yyear,mmonth,dday,hhour ! time as read from sim_file  
  integer :: year,month,day,hour ! time after eventual rounding to nearest 6-h
  character*3 :: station_char ! station code as 3-char string
  integer :: station_int ! station code as integer
  logical :: l_code_in_char ! .true. for station codes as string
  logical :: l_round_6h ! .true. for rounding time to nearest 6-h
  real :: ntot ! total number of observations as read from rank_histogram_file
  real :: lon,lat ! longitude and latitude
  integer :: i,j,k ! loop variables
  integer :: day_of_year ! day count from Jan 1 (in a non-leap year)

  real :: miss ! missing value code
  
  real :: fmin(nhour),fmax(nhour) ! minimum and maximum values for time series plots
  real :: fmin_down(nhour),fmax_up(nhour) ! same, but extended outward
  real :: freqmax(nhour+1) ! largest frequency for the rank histogram

  integer,parameter :: n_colors=13 ! number of colours for GrADS output
  integer :: color(n_colors) ! colours for GrADS output
  integer :: num_int_arr ! fix for Warning : Legacy Extension: REAL array index at (1)

  integer :: irec ! record number for GrADS output
!
! For text output in odb-compatible format:
!
  INTEGER, PARAMETER :: L_dataline=1700 ! max length of input or output text line
  character*1700 :: dataline,headerline,emptyline ! for reading / writing text files
  character*2 :: number_of_bin ! quantile bin numbers for header in txt_data_quantiles
  character*16 :: frequency_value ! frequency value written as character string
!
  logical :: include_rank_histograms ! true for including rank histograms
  
  namelist/param/sim_file,quantile_file,rank_histogram_file,&
       grads_data_time_series,grads_data_rank_histogram,&
       year1,year2,month1,month2,&
       txt_data_time_series,txt_data_rank_histogram,txt_data_quantiles,&
       include_rank_histograms,l_code_in_char,l_round_6h,miss
  
  data color/9,14,4,11,5,13,3,10,7,12,8,2,6/
!
! default values
!  
  miss=-9.99e6
  l_code_in_char=.false.
  l_round_6h=.false.
  include_rank_histograms=.true.
!
! Read the namelist and count the number of years for output
!  
  read(*,nml=param)  
  nyear=year2-year1+1
  
  !************************************************************************************************
  ! Read the data from the input files. Only data for the period year1/month1-year2/month2
  ! will be included in the time series output, even if other data exist.
  !
  ! 1) time series
  !
  f=miss
  open(unit=1,form='formatted',file=sim_file,status='old')
     do while(.true.)
11      read(1,*,err=11,end=12) yyear,mmonth,dday,hhour,f1
         if(l_round_6h)then  
            call round_6h(yyear,mmonth,dday,hhour,year,month,day,hour)  ! Rounding to nearest 6-h?
         else
            year=yyear
            month=mmonth
            day=dday
            hour=hhour
         endif
         if((year.gt.year1.or.(year.eq.year1.and.month.ge.month1)).and. & ! Is the time within the 
           (year.lt.year2.or.(year.eq.year2.and.month.le.month2))) then   ! wanted range?
            
           if(.not.(month.eq.2.and.day.eq.29))then  ! leap days are skipped from plotting                      
              f(year-year1+1,day_of_year(month,day),1+hour/6)=f1 ! hard-coding to 6-hourly resolution           
           endif
         endif
       enddo
12 continue
   close(1)
   !
   ! 2) quantiles
   !
   quant=miss
   open(unit=1,form='formatted',file=quantile_file,status='old')
   do while(.true.)
           if(l_code_in_char)then
21            read(1,*,err=21,end=23)station_char,lon,lat,month,day,hour,(quant1(i),i=1,nquant)
           else
22            read(1,*,err=22,end=23)station_int,lon,lat,month,day,hour,(quant1(i),i=1,nquant)
           endif
           if((hour.eq.0.or.hour.eq.6.or.hour.eq.12.or.hour.eq.18)&
                .and.(.not.(month.eq.2.and.day.eq.29))) then  ! leap days are skipped from plotting
              do i=1,nquant
                 quant(i,day_of_year(month,day),1+hour/6)=quant1(i)
              enddo              
           endif
        enddo        
23 continue
   close(1)
   !
   ! 3) quantile bin frequencies and related MSD and p-value statistics
   !
   freq=miss
   if(include_rank_histograms)then
        open(unit=1,form='formatted',file=rank_histogram_file,status='old')
        do while(.true.)
           if(l_code_in_char)then
31            read(1,*,err=31,end=33)station_char,lon,lat,hour,ntot,msd1,p_value1,(freq1(i),i=1,nquant+1)
           else
32            read(1,*,err=32,end=33)station_int,lon,lat,hour,ntot,msd1,p_value1,(freq1(i),i=1,nquant+1)
           endif           
           if((hour.eq.0.or.hour.eq.6.or.hour.eq.12.or.hour.eq.18.or.hour.eq.24))then
              msd(1+hour/6)=msd1
              p_value(1+hour/6)=p_value1
              do i=1,nquant+1
                 freq(i,1+hour/6)=freq1(i)
              enddo
           endif
        enddo        
33      continue
        close(1)
     endif
     
!**********************************************************************************************
!  Find the minimum and maximum values of f (or the 1st and 99th percentile)   
!  for defining the vranges for the GrADS time series plots  

   do j=1,nhour
      fmin(j)=quant(1,1,j)
      fmax(j)=quant(nquant,1,j)
      do i=1,ndays_year
         if(quant(1,i,j).lt.fmin(j))fmin(j)=quant(1,i,j)
         if(quant(nquant,i,j).gt.fmax(j))fmax(j)=quant(nquant,i,j)
         do k=1,nyear
            if(f(k,i,j).lt.fmin(j).and.abs(f(k,i,j)).lt.abs(miss))fmin(j)=f(k,i,j)
            if(f(k,i,j).gt.fmax(j).and.f(k,i,j).lt.abs(miss))fmax(j)=f(k,i,j)            
         enddo
      enddo      
     fmin_down(j)=fmin(j)-0.05*(fmax(j)-fmin(j))
     fmax_up(j)=fmax(j)+0.05*(fmax(j)-fmin(j))          
   enddo
!   
! Find the largest frequency from the rank histograms   
!
   freqmax=0.
   do j=1,nhour+1
      do i=1,nquant+1
         if(freq(i,j).gt.freqmax(j))freqmax(j)=freq(i,j)
      enddo      
   enddo
!
! Write the commands to the auxiliary script files for Grads   
!
   open(unit=1,form='formatted',file='vrange_commands')
   write(1,'(A11,2F10.3)')'set vrange ',fmin_down(1),fmax_up(1)
   write(1,'(A11,2F10.3)')'set vrange ',fmin_down(2),fmax_up(2)
   write(1,'(A11,2F10.3)')'set vrange ',fmin_down(3),fmax_up(3)
   write(1,'(A11,2F10.3)')'set vrange ',fmin_down(4),fmax_up(4)
   write(1,'(A13,F7.3)')'set vrange 0 ',1.1*(nquant+1)*freqmax(1) ! conversion to relative frequencies
   write(1,'(A13,F7.3)')'set vrange 0 ',1.1*(nquant+1)*freqmax(2) ! conversion to relative frequencies
   write(1,'(A13,F7.3)')'set vrange 0 ',1.1*(nquant+1)*freqmax(3) ! conversion to relative frequencies
   write(1,'(A13,F7.3)')'set vrange 0 ',1.1*(nquant+1)*freqmax(4) ! conversion to relative frequencies
   write(1,'(A13,F7.3)')'set vrange 0 ',1.1*(nquant+1)*freqmax(5) ! conversion to relative frequencies      
   close(1)

   open(unit=1,form='formatted',file='time_series_commands')
   do i=1,nyear
      write(1,'(A12)')'set cthick 4'
      write(1,'(A12)')'set cstyle 0'
      write(1,'(A11)')'set cmark 3'
      write(1,'(A15)')'set digsiz 0.07'
      if(nyear.eq.1)then
         num_int_arr=nint(1.+n_colors)/2.
         write(1,'(A11,I2)')'set ccolor ',color(num_int_arr)
         !write(1,'(A11,I2)')'set ccolor ',color(nint(1.+n_colors)/2.)
      else
         num_int_arr=nint(1+(i-1.)/(nyear-1.)*(n_colors-1.))
         write(1,'(A11,I2)')'set ccolor ',color(num_int_arr)
         !write(1,'(A11,I2)')'set ccolor ',color(nint(1+(i-1.)/(nyear-1.)*(n_colors-1.)))
      endif  
      write(1,'(A7,I2,A1)')'d &0(z=',i,')'
   enddo   
   close(1)

   open(unit=1,form='formatted',file='coordinates')
   write(1,'(F8.3)')lon
   write(1,'(F8.3)')lat
   close(1)
   
   if(include_rank_histograms)then
   open(unit=1,form='formatted',file='msd_and_p-value_00')
      write(1,'(A15)')'set strsiz 0.17'
      write(1,'(A18)')'set string 1 l 4 0'
      write(1,'(A25,F5.3)')'draw string 1.3 &0 MSD=',msd(1)
      write(1,'(A29,F5.3)')'draw string 3.0 &0 p-value=',p_value(1)      
      close(1)
   open(unit=1,form='formatted',file='msd_and_p-value_06')
      write(1,'(A15)')'set strsiz 0.17'
      write(1,'(A18)')'set string 1 l 4 0'
      write(1,'(A25,F5.3)')'draw string 1.3 &0 MSD=',msd(2)
      write(1,'(A29,F5.3)')'draw string 3.0 &0 p-value=',p_value(2)      
      close(1)
   open(unit=1,form='formatted',file='msd_and_p-value_12')
      write(1,'(A15)')'set strsiz 0.17'
      write(1,'(A18)')'set string 1 l 4 0'
      write(1,'(A25,F5.3)')'draw string 1.3 &0 MSD=',msd(3)
      write(1,'(A29,F5.3)')'draw string 3.0 &0 p-value=',p_value(3)      
      close(1)
   open(unit=1,form='formatted',file='msd_and_p-value_18')
      write(1,'(A15)')'set strsiz 0.17'
      write(1,'(A18)')'set string 1 l 4 0'
      write(1,'(A25,F5.3)')'draw string 1.3 &0 MSD=',msd(4)
      write(1,'(A29,F5.3)')'draw string 3.0 &0 p-value=',p_value(4)      
      close(1)
   open(unit=1,form='formatted',file='msd_and_p-value')
      write(1,'(A15)')'set strsiz 0.17'
      write(1,'(A18)')'set string 1 l 4 0'
      write(1,'(A25,F5.3)')'draw string 1.3 &0 MSD=',msd(5)
      write(1,'(A29,F5.3)')'draw string 3.0 &0 p-value=',p_value(5)      
      close(1)      
   endif   
!
!*************************************************************** 
! Write the GrADS binary files needed for the plots

   open(unit=1,form='unformatted',file=grads_data_time_series,access='DIRECT',&
        recl=4,status='unknown')
   do j=1,nhour
      do i=1,ndays_year                   
         irec=((i-1)+(j-1)*ndays_year)*(nyear+7)
         do k=1,nyear
            write(1,rec=irec+k)f(k,i,j)  ! time series
         enddo
         write(1,rec=irec+nyear+1)quant(1,i,j) ! selected quantile
         write(1,rec=irec+nyear+2)quant(10,i,j)
         write(1,rec=irec+nyear+3)quant(25,i,j)
         write(1,rec=irec+nyear+4)quant(50,i,j)
         write(1,rec=irec+nyear+5)quant(75,i,j)
         write(1,rec=irec+nyear+6)quant(90,i,j)
         write(1,rec=irec+nyear+7)quant(99,i,j)                        
      enddo   
   enddo
   close(1)

   if(include_rank_histograms)then
   open(unit=1,form='unformatted',file=grads_data_rank_histogram,access='DIRECT',&
        recl=4,status='unknown')
   do j=1,nhour+1
      irec=(nquant+1)*(j-1)               
      do i=1,nquant+1
         write(1,rec=irec+i)freq(i,j) !quantile bin frequencies
      enddo      
   enddo
   close(1)
   endif

!*************************************************************** 
! Write the time series, quantiles and rank histogram data to text files

!
!     Empty data line 
!
      do i=1,L_dataline
         emptyline(i:i)=' '
      enddo
!
!  Time series. 365 days per year, 4 times per day, from year1 to year2
!      
   open(unit=1,form='formatted',file=txt_data_time_series)
   headerline=emptyline
   if(l_code_in_char)then      
   headerline='station@hdr:string longitude@hdr:real latitude@hdr:real year@hdr:integer'//&
        ' day_of_year@hdr:integer hour@hdr:integer value@body:real'
   else
   headerline='station@hdr:integer longitude@hdr:real latitude@hdr:real year@hdr:integer'//&
        ' day_of_year@hdr:integer hour@hdr:integer value@body:real'
   endif
   write(1,*)trim(headerline)
   do year=year1,year2
      do j=1,365         
         do hour=0,18,6
            if(abs(f(year-year1+1,j,1+hour/6)).lt.abs(miss))then
                  if(l_code_in_char)then
                     write(1,'(A3,2F16.6,1X,I4,1X,I3,1X,I2,F16.6)')station_char,lon,lat,year,j,hour,f(year-year1+1,j,1+hour/6)
                  else
                     write(1,'(I6,2F16.6,1X,I4,1X,I3,1X,I2,F16.6)')station_int,lon,lat,year,j,hour,f(year-year1+1,j,1+hour/6)
                  endif
               else
                  if(l_code_in_char)then
                     write(1,'(A3,2F16.6,1X,I4,1X,I3,1X,I2,A16)')station_char,lon,lat,year,j,hour,' NaN'
                  else
                     write(1,'(I6,2F16.6,1X,I4,1X,I3,1X,I2,A16)')station_int,lon,lat,year,j,hour,' NaN'                     
                  endif
               endif               
         enddo         
      enddo
   enddo   
   close(1)
!
!  Selected quantiles of the observed distribution. 365 days per year, 4 time per day.
!   
   open(unit=1,form='formatted',file=txt_data_quantiles)
   headerline=emptyline
   if(l_code_in_char)then      
     headerline='station@hdr:string longitude@hdr:real latitude@hdr:real day_of_year@hdr:integer hour@hdr:integer'//&
          ' q01@body:real q10@body:real q25@body:real q50@body:real q75@body:real q90@body:real q99@body:real'
   else
     headerline='station@hdr:integer longitude@hdr:real latitude@hdr:real day_of_year@hdr:integer hour@hdr:integer'//&
          ' q01@body:real q10@body:real q25@body:real q50@body:real q75@body:real q90@body:real q99@body:real'     
    endif  
   write(1,*)trim(headerline)
   do year=year1,year2
      do j=1,365
         do hour=0,18,6
            if(l_code_in_char)then
            write(1,'(A3,2F16.6,1X,I3,1X,I2,7F16.6)')station_char,lon,lat,j,hour,&
                 quant(1,j,hour/6+1),quant(10,j,hour/6+1),quant(25,j,hour/6+1),quant(50,j,hour/6+1),&
                 quant(75,j,hour/6+1),quant(90,j,hour/6+1),quant(99,j,hour/6+1)
            else
            write(1,'(I6,2F16.6,1X,I3,1X,I2,7F16.6)')station_int,lon,lat,j,hour,&
                 quant(1,j,hour/6+1),quant(10,j,hour/6+1),quant(25,j,hour/6+1),quant(50,j,hour/6+1),&
                 quant(75,j,hour/6+1),quant(90,j,hour/6+1),quant(99,j,hour/6+1)
            endif
         enddo         
      enddo
   enddo   
   close(1)
!
!  Rank histogram of frequencies. 100 bins from 0-1% to 99-100. Before that, the MSD and p-values   
   !
   if(include_rank_histograms)then
   open(unit=1,form='formatted',file=txt_data_rank_histogram)
   headerline=emptyline
   if(l_code_in_char)then      
      headerline='station@hdr:string longitude@hdr:real latitude@hdr:real hour@hdr:integer'
   else
      headerline='station@hdr:integer longitude@hdr:real latitude@hdr:real hour@hdr:integer'
   endif   
   headerline=trim(headerline)//' msd@body:real p_value@body:real'
   do j=0,nquant
      write(number_of_bin,'(i2.2)')j
      headerline=trim(headerline)//' f'//number_of_bin//'@body:real'
   enddo
   write(1,*)trim(headerline)
   
   do hour=0,24,6
     if(l_code_in_char)then
     write(dataline,'(A3,2F16.6,1X,I2,2F16.6)')&
          station_char,lon,lat,hour,msd(1+hour/6),p_value(1+hour/6)
     else
     write(dataline,'(I6,2F16.6,1X,I2,2F16.6)')&
          station_int,lon,lat,hour,msd(1+hour/6),p_value(1+hour/6)
  endif
  
     do i=1,nquant+1
        write(frequency_value,'(F16.6)')freq(i,1+hour/6)
        dataline=trim(dataline)//frequency_value          
     enddo
     write(1,*)trim(dataline)      
   enddo   
    
   close(1)
   endif
   
   end program plots_for_one_station

      integer function day_of_year(month,day)
!
!     Number of day 'day' in the 'month':th month from the beginning of a non-leap year 
!        
        implicit none
        integer :: year,month,day
        integer,parameter :: nmon=12
        integer :: days_before(nmon) ! this is for normal years
        integer :: dnumber
        data days_before / 0,31,59,90,120,151,181,212,243,273,304,334 /

        day_of_year=days_before(month)+day
        return
        end function day_of_year

!
! rounding the time to the nearest full 6 hours
!       
subroutine round_6h(year,month,day,hour,year1,month1,day1,hour1)
implicit none
integer :: year,month,day,hour  ! time before rounding
integer :: year1,month1,day1,hour1 ! time after rounding
integer :: ndays_month !  number of days in a month
ndays_month=31
if(month.eq.4.or.month.eq.6.or.month.eq.9.or.month.eq.11)ndays_month=30
if(month.eq.2)then
   if((mod(year,4).eq.0.and.mod(year,100).gt.0).or.(mod(year,400).eq.0))then
     ndays_month=29
   else
     ndays_month=28
  endif 
endif
year1=year
month1=month
day1=day
hour1=6*((hour+3)/6)
if(hour.ge.21)then ! Hour was rounded forward to 00 UTC -> increment day
      hour1=0
      day1=day+1
      if(day1.gt.ndays_month)then ! increment month
         day1=1
         month1=month1+1
         if(month1.gt.12)then ! increment year
            month1=1
            year1=year+1
         endif
      endif
endif
return
end subroutine round_6h


        
