LCOV - code coverage report
Current view: top level - src - mo_smi_write.f90 (source / functions) Hit Total Coverage
Test: SMI coverage Lines: 221 335 66.0 %
Date: 2024-04-30 09:16:25 Functions: 4 5 80.0 %

          Line data    Source code
       1             : !> \file mo_smi_write.f90
       2             : !> \brief   \copybrief mo_smi_write
       3             : !> \details \copydetails mo_smi_write
       4             : 
       5             : !> \brief Writing subroutines for SMI
       6             : !> \author Luis Samaniego
       7             : !> \date 09.02.2011
       8             : !> \copyright Copyright 2005-\today, the CHS Developers, Luis Samaniego, Sabine Attinger: All rights reserved.
       9             : !! SMI is released under the LGPLv3+ license \license_note
      10             : module mo_smi_write
      11             : 
      12             :   use mo_kind,                 only: i4, sp, dp
      13             :   use mo_smi_global_variables, only: period
      14             : 
      15             :   implicit none
      16             : 
      17             :   ! ! clusters
      18             :   integer(i4), dimension(:,:,:), allocatable      :: idCluster
      19             :   integer(i4)                                     :: nInterArea
      20             :   integer(i4)                                     :: nEvents           ! total number of drough events to estimate SAD
      21             :   integer(i4), dimension(:), allocatable          :: shortCnoList      ! consolidated cluster no. list
      22             :   integer(i4), dimension(:,:), allocatable        :: eventId           ! event identification number, cluster, month of occurence
      23             :   integer(i4)                                     :: nClusters         ! number od clusters
      24             :   integer(i4), dimension(:), allocatable          :: eIdPerm           ! permutation of the event Ids with ascending area
      25             :   !
      26             :   ! cluster statistics
      27             :   real(dp), dimension(:,:), allocatable          :: DAreaEvol    ! drought area evolution (fraction Germany)
      28             :   real(dp), dimension(:,:), allocatable          :: DTMagEvol    !         magnitud
      29             :   real(dp), dimension(:), allocatable            :: aDD          ! average (mean) drought duration space-time
      30             :   real(dp), dimension(:), allocatable            :: aDA          ! average (mean) drought area
      31             :   real(dp), dimension(:), allocatable            :: TDM          ! total drought magnitud
      32             :   real(dp), dimension(:,:,:), allocatable        :: SAD          ! severity area duration curves
      33             :   real(dp), dimension(:,:), allocatable          :: SADperc      ! percentilles of severity area duration curves
      34             :   integer(i4)                                    :: nDsteps      ! number of durations steps
      35             :   real(dp), dimension(:,:,:), allocatable        :: severity     ! severity for a given duration
      36             :   real(dp), dimension(:,:,:), allocatable        :: dASevol      ! evolution of the drought areas and severity
      37             : 
      38             :   integer(i4), parameter                         :: nDurations = 4         ! number of durations
      39             :   integer(i4), dimension(nDurations), parameter  :: durList = (/3,6,9,12/) !(/3,6,9,12/)   ! list of durations to evaluate
      40             :   integer(i4), parameter                         :: nQProp = 3             ! number of SAD percetiles for a given duration
      41             :   real(dp), dimension(nQProp), parameter         :: QProp = (/90._dp, 96._dp, 98._dp /)
      42             :                                                                            ! percentiles corresponding
      43             :                                                                            ! to return periods of 10,25,50 years
      44             : 
      45             :   integer(i4)                                    :: nLargerEvents = 600    ! n. largest drought events
      46             :   !
      47             :   ! Basin summary
      48             :   integer(i4), parameter                         :: nBasins = 6
      49             : 
      50             : contains
      51             : 
      52             :   !> \brief for writting the SMI to nc file
      53             :   !> \author Stephan Thober
      54             :   !> \date 5.7.2014
      55             :   !> \date 9.8.2019
      56             :   !!       - refactored to new period structure and leap day handling
      57           4 :   subroutine WriteSMI( outpath, SMI, mask, per, lats_1d, lons_1d, lats_2d, lons_2d, easting, northing)
      58             : 
      59             :     use mo_kind,          only: i4, sp
      60             :     use mo_string_utils,  only: num2str
      61             :     use mo_constants,     only: nodata_sp, nodata_dp
      62             :     use mo_netcdf,        only: NcDataset, NcVariable, NcDimension
      63             : 
      64             :     implicit none
      65             : 
      66             :     ! input variables
      67             :     character(len=*),                              intent(in) :: outpath     ! ouutput path for results
      68             : 
      69             :     logical,        dimension(:,:),                intent(in) :: mask
      70             :     type(period),                                  intent(in) :: per
      71             :     real(sp),       dimension(:,:),                intent(in) :: SMI
      72             :     real(dp),       dimension(:),   allocatable,   intent(in) :: lats_1d, lons_1d   ! latitude and longitude fields of input
      73             :     real(dp),       dimension(:,:),   allocatable,   intent(in) :: lats_2d, lons_2d   ! latitude and longitude fields of input
      74             :     real(dp), dimension(:), allocatable, intent(in) :: easting ! easting coordinates of input
      75             :     real(dp), dimension(:), allocatable, intent(in) :: northing ! easting coordinates of input
      76             :     ! local Variables
      77             :     type(NcDataset)                                           :: nc_out
      78             :     type(NcVariable)                                          :: nc_var
      79             :     type(NcDimension)                                         :: nc_y, nc_x, nc_tim
      80             :     character(256)                                            :: Fname
      81             :     integer(i4)                                               :: ii          ! month
      82             : 
      83           4 :     real(sp),       dimension(:,:,:), allocatable             :: dummy_D3_sp ! field real unpacked
      84             :     integer(i4)                                               :: y
      85             :     integer(i4)                                               :: x
      86             : 
      87             :     ! initialize dimension
      88           4 :     y = size(mask, 2)
      89           4 :     x = size(mask, 1)
      90           4 :     print *,'x: ', x
      91           4 :     print *,'y: ', y
      92             :     ! fname
      93           4 :     fName = trim(outpath) //'SMI.nc'
      94           4 :     nc_out = NcDataset(fName, 'w')
      95           4 :     if (allocated(lats_1d)) then
      96           0 :        nc_y = nc_out%setDimension("lat", y)
      97           0 :        nc_x = nc_out%setDimension("lon", x)
      98           4 :     else if (allocated(lats_2d)) then
      99           3 :        nc_y = nc_out%setDimension("northing", y)
     100           3 :        nc_x = nc_out%setDimension("easting", x)
     101             :     else
     102           1 :        nc_y = nc_out%setDimension("y", y)
     103           1 :        nc_x = nc_out%setDimension("x", x)
     104             :     end if
     105           4 :     nc_tim = nc_out%setDimension("time", -1)
     106             : 
     107             :     ! unpack estimated SMIp
     108          20 :     allocate( dummy_d3_sp( x, y, size( SMI, 2) ) )
     109        1029 :     do ii = 1,  size( SMI, 2)
     110        1029 :       dummy_d3_sp( :, :, ii) = unpack ( SMI(:,ii), mask, nodata_sp )
     111             :     end do
     112             : 
     113             :     ! save SMI (same sequence as in 1)
     114             :     nc_var = nc_out%setVariable('SMI', "f32", &
     115          16 :          (/ nc_x, nc_y, nc_tim /))
     116           4 :     call nc_var%setData(dummy_d3_sp)
     117           4 :     call nc_var%setAttribute('long_name', 'soil moisture index')
     118           4 :     call nc_var%setAttribute('missing_value', nodata_sp)
     119           4 :     call nc_var%setAttribute('units', '-')
     120           4 :     deallocate( dummy_d3_sp )
     121             : 
     122             :     ! add lat and lon
     123           4 :     if (allocated(lats_1d)) then
     124           0 :       print *, 'lat1d'
     125           0 :       nc_var = nc_out%setVariable('lat', "f64", (/ nc_y /))
     126           0 :       call nc_var%setData(lats_1d)
     127           0 :       call nc_var%setAttribute('long_name', 'latitude')
     128           0 :       call nc_var%setAttribute('missing_value', nodata_dp)
     129           0 :       call nc_var%setAttribute('units', 'degrees_north')
     130           4 :    else if (allocated(lats_2d)) then
     131           3 :       print *, 'lats2d'
     132           9 :       nc_var = nc_out%setVariable('lat', "f64", (/ nc_x, nc_y /))
     133           3 :       call nc_var%setData(lats_2d)
     134           3 :       call nc_var%setAttribute('long_name', 'latitude')
     135           3 :       call nc_var%setAttribute('missing_value', nodata_dp)
     136           3 :       call nc_var%setAttribute('units', 'degrees_north')
     137             : 
     138             :       ! nc_var = nc_out%setVariable('northing', "f64", (/ nc_y/))
     139             :       ! call nc_var%setData(northing)
     140             :       ! call nc_var%setAttribute('long_name', 'northing')
     141             :       ! call nc_var%setAttribute('missing_value', nodata_dp)
     142             :       ! call nc_var%setAttribute('units', 'meters')
     143             :    end if
     144             : 
     145           4 :     if (allocated(lons_1d)) then
     146           0 :       nc_var = nc_out%setVariable('lon', "f64", (/ nc_x /))
     147           0 :       call nc_var%setData(lons_1d)
     148           0 :       call nc_var%setAttribute('long_name', 'longitude')
     149           0 :       call nc_var%setAttribute('missing_value', nodata_dp)
     150           0 :       call nc_var%setAttribute('units', 'degrees_east')
     151           4 :     else if (allocated(lons_2d)) then
     152           9 :       nc_var = nc_out%setVariable('lon', "f64", (/ nc_x, nc_y /))
     153           3 :       call nc_var%setData(lons_2d)
     154           3 :       call nc_var%setAttribute('long_name', 'longitude')
     155           3 :       call nc_var%setAttribute('missing_value', nodata_dp)
     156           3 :       call nc_var%setAttribute('units', 'degrees_east')
     157             : 
     158             :       ! nc_var = nc_out%setVariable('easting', "f64", (/ nc_x /))
     159             :       ! call nc_var%setData(easting)
     160             :       ! call nc_var%setAttribute('long_name', 'easting')
     161             :       ! call nc_var%setAttribute('missing_value', nodata_dp)
     162             :       ! call nc_var%setAttribute('units', 'meters')
     163             : 
     164             : 
     165             :     end if
     166             : 
     167             :     ! add time
     168           8 :     nc_var = nc_out%setVariable('time', "i32", (/ nc_tim /))
     169           4 :     call nc_var%setData(per%time_points)
     170           4 :     call nc_var%setAttribute('long_name', 'time')
     171             :     call nc_var%setAttribute('units', 'days since '                              // &
     172             :                                       trim(num2str(per%y_start,   '(i4)')) // '-'     // &
     173             :                                       trim(num2str(per%m_start, '(i2.2)')) // '-'     // &
     174           4 :                                       trim(num2str(per%d_start, '(i2.2)')) // ' 00:00:00' )
     175             :     ! close file
     176           4 :     call nc_out%close()
     177             : 
     178           4 :   end subroutine WriteSMI
     179             : 
     180             :   !> \brief for writting the CDF information (that is the kernel and associated soil moisture values) to nc file
     181             :   !> \author Stephan Thober
     182             :   !> \date 8.8.2019
     183           1 :   subroutine WriteCDF( outpath, SM, hh, mask, per, nCalendarStepsYear, lats_1d, lons_1d, lats_2d, lons_2d, easting, northing)
     184             : 
     185           4 :     use mo_kind,          only: i4, sp
     186             :     use mo_message,       only: message
     187             :     use mo_string_utils,  only: num2str
     188             :     use mo_constants,     only: nodata_sp, nodata_dp
     189             :     use mo_netcdf,        only: NcDataset, NcVariable, NcDimension
     190             : 
     191             :     implicit none
     192             : 
     193             :     ! input variables
     194             :     character(len=*),                              intent(in) :: outpath     ! ouutput path for results
     195             : 
     196             :     logical,        dimension(:,:),                intent(in) :: mask
     197             :     type(period),                                  intent(in) :: per
     198             :     real(sp),       dimension(:,:),                intent(in) :: SM
     199             :     integer(i4),                                   intent(in) :: nCalendarStepsYear
     200             :     real(dp),       dimension(:),   allocatable,   intent(in) :: lats_1d, lons_1d   ! latitude and longitude fields of input
     201             :     real(dp),       dimension(:,:),   allocatable,   intent(in) :: lats_2d, lons_2d   ! latitude and longitude fields of input
     202             :     real(dp), dimension(:), allocatable, intent(in) :: easting ! easting coordinates of input
     203             :     real(dp), dimension(:), allocatable, intent(in) :: northing ! easting coordinates of input
     204             :     real(dp),       dimension(:,:),                intent(in) :: hh
     205             : 
     206             :     ! local Variables
     207             :     type(NcDataset)                                           :: nc_out
     208             :     type(NcVariable)                                          :: nc_var
     209             :     type(NcDimension)                                         :: nc_y, nc_x, nc_tim, nc_cal
     210             :     character(256)                                            :: Fname
     211             :     integer(i4)                                               :: mm          ! month
     212             : 
     213           1 :     real(sp),       dimension(:,:,:), allocatable             :: dummy_D3_sp ! field real unpacked
     214           1 :     real(dp),       dimension(:,:,:), allocatable             :: dummy_D3_dp ! field real unpacked
     215             :     integer(i4)                                               :: y
     216             :     integer(i4)                                               :: x
     217             : 
     218             :     ! initialize dimension
     219           1 :     y = size(mask, 2)
     220           1 :     x = size(mask, 1)
     221             : 
     222             :     ! fname
     223           1 :     fName = trim(outpath) //'cdf_info.nc'
     224           1 :     nc_out = NcDataset(fName, 'w')
     225           1 :     if (allocated(lats_1d)) then
     226           0 :        nc_y = nc_out%setDimension("lat", y)
     227           0 :        nc_x = nc_out%setDimension("lon", x)
     228           1 :     else if (allocated(lats_2d)) then
     229           1 :        nc_y = nc_out%setDimension("northing", y)
     230           1 :        nc_x = nc_out%setDimension("easting", x)
     231             :     else
     232           0 :        nc_y = nc_out%setDimension("y", y)
     233           0 :        nc_x = nc_out%setDimension("x", x)
     234             :     end if
     235           1 :     nc_tim = nc_out%setDimension("time", -1)
     236             : 
     237             :     ! unpack soil moisture estimated
     238           5 :     allocate( dummy_d3_sp( x, y, size( SM, 2) ) )
     239         361 :     do mm = 1,  size( SM, 2)
     240         361 :       dummy_d3_sp( :, :, mm) = unpack ( SM(:,mm), mask, nodata_sp )
     241             :     end do
     242             : 
     243             :     ! save SM (same sequence as in 1)
     244             :     nc_var = nc_out%setVariable('SM', "f32", &
     245           4 :          (/ nc_x, nc_y, nc_tim /))
     246           1 :     call nc_var%setData(dummy_d3_sp)
     247           1 :     call nc_var%setAttribute('long_name', 'soil moisture saturation')
     248           1 :     call nc_var%setAttribute('missing_value', nodata_sp)
     249           1 :     call nc_var%setAttribute('units', 'fraction of pore space')
     250           1 :     deallocate( dummy_d3_sp )
     251             : 
     252             :     ! write out kernel width if it has been optimised
     253           5 :     allocate( dummy_D3_dp( x, y, size( hh, 2 ) ) )
     254          13 :     do mm = 1, size( hh, 2 )
     255          13 :       dummy_D3_dp(:, :, mm) = unpack( hh(:,mm), mask, real( nodata_sp, dp ) )
     256             :     end do
     257           1 :     nc_cal = nc_out%setDimension("time_steps", size(dummy_d3_dp,3))
     258             :     nc_var = nc_out%setVariable('kernel_width', "f64", &
     259           4 :         (/ nc_x, nc_y, nc_cal /))
     260           1 :     call nc_var%setData(dummy_d3_dp)
     261           1 :     call nc_var%setAttribute('long_name', 'optimised kernel width')
     262           1 :     call nc_var%setAttribute('missing_value', nodata_dp)
     263           1 :     if (nCalendarStepsYear .eq. 12_i4) then
     264           1 :       call nc_var%setAttribute('units', 'months')
     265           0 :     else if (nCalendarStepsYear .eq. 365_i4) then
     266           0 :       call nc_var%setAttribute('units', 'days')
     267             :     else
     268           0 :       call message("***ERROR: nCalendarStepsYear has to be 12 or 365 in subroutine WriteCDF")
     269           0 :       stop 1
     270             :     end if
     271             : 
     272           1 :     deallocate( dummy_D3_dp )
     273             : 
     274             :     ! add lat and lon
     275           1 :     if (allocated(lats_1d)) then
     276           0 :       nc_var = nc_out%setVariable('lat', "f64", (/ nc_y /))
     277           0 :       call nc_var%setData(lats_1d)
     278           0 :       call nc_var%setAttribute('long_name', 'latitude')
     279           0 :       call nc_var%setAttribute('missing_value', nodata_dp)
     280           0 :       call nc_var%setAttribute('units', 'degrees_north')
     281           1 :     else if (allocated(lats_2d)) then
     282           3 :       nc_var = nc_out%setVariable('lat', "f64", (/ nc_x, nc_y /))
     283           1 :       call nc_var%setData(lats_2d)
     284           1 :       call nc_var%setAttribute('long_name', 'latitude')
     285           1 :       call nc_var%setAttribute('missing_value', nodata_dp)
     286           1 :       call nc_var%setAttribute('units', 'degrees_north')
     287             : 
     288             :       ! nc_var = nc_out%setVariable('northing', "f64", (/ nc_y /))
     289             :       ! call nc_var%setData(northing)
     290             :       ! call nc_var%setAttribute('long_name', 'northing')
     291             :       ! call nc_var%setAttribute('missing_value', nodata_dp)
     292             :       ! call nc_var%setAttribute('units', 'meters')
     293             :    end if
     294             : 
     295           1 :     if (allocated(lons_1d)) then
     296           0 :       nc_var = nc_out%setVariable('lon', "f64", (/ nc_x /))
     297           0 :       call nc_var%setData(lons_1d)
     298           0 :       call nc_var%setAttribute('long_name', 'longitude')
     299           0 :       call nc_var%setAttribute('missing_value', nodata_dp)
     300           0 :       call nc_var%setAttribute('units', 'degrees_east')
     301             : 
     302           1 :     else if (allocated(lons_2d)) then
     303           3 :       nc_var = nc_out%setVariable('lon', "f64", (/ nc_x, nc_y /))
     304           1 :       call nc_var%setData(lons_2d)
     305           1 :       call nc_var%setAttribute('long_name', 'longitude')
     306           1 :       call nc_var%setAttribute('missing_value', nodata_dp)
     307           1 :       call nc_var%setAttribute('units', 'degrees_east')
     308             : 
     309             :       ! nc_var = nc_out%setVariable('easting', "f64", (/ nc_x /))
     310             :       ! call nc_var%setData(easting)
     311             :       ! call nc_var%setAttribute('long_name', 'easting')
     312             :       ! call nc_var%setAttribute('missing_value', nodata_dp)
     313             :       ! call nc_var%setAttribute('units', 'meters')
     314             :     end if
     315             : 
     316             :     ! add time
     317           2 :     nc_var = nc_out%setVariable('time', "i32", (/ nc_tim /))
     318           1 :     call nc_var%setData(per%time_points)
     319           1 :     call nc_var%setAttribute('long_name', 'time')
     320             :     call nc_var%setAttribute('units', 'days since '                              // &
     321             :                                       trim(num2str(per%y_start,   '(i4)')) // '-'     // &
     322             :                                       trim(num2str(per%m_start, '(i2.2)')) // '-'     // &
     323           1 :                                       trim(num2str(per%d_start, '(i2.2)')) // ' 00:00:00' )
     324             :     ! close file
     325           1 :     call nc_out%close()
     326             : 
     327           1 :   end subroutine WriteCDF
     328             : 
     329             :   !> \brief WRITE netCDF files
     330             :   !!        FORMAT     netCDF
     331             :   !!        http://www.unidata.ucar.edu/software/netcdf/
     332             :   !> \author Luis E. Samaniego-Eguiguren, UFZ
     333             :   !> \date 16.02.2011
     334           3 :   subroutine WriteNetCDF(outpath, wFlag, per, lats_1d, lons_1d, lats_2d, lons_2d, easting, northing, &
     335           3 :         SMIc, SM_invert, duration)
     336             :     !
     337           1 :     use mo_kind,          only: i4
     338             :     use mo_string_utils,  only: num2str
     339             :     use mo_constants,     only: nodata_i4 , nodata_dp, nodata_sp
     340             :     use mo_netcdf,        only: NcDataset, NcVariable, NcDimension
     341             : 
     342             :     implicit none
     343             :     !
     344             :     ! input variables
     345             :     character(len=*),                            intent(in) :: outpath     ! ouutput path for results
     346             :     type(period),                                intent(in) :: per
     347             :     integer(i4),                                 intent(in) :: wFlag
     348             :     real(dp),       dimension(:),   allocatable,   intent(in) :: lats_1d, lons_1d   ! latitude and longitude fields of input
     349             :     real(dp),       dimension(:,:),   allocatable,   intent(in) :: lats_2d, lons_2d   ! latitude and longitude fields of input
     350             :     real(dp), dimension(:), allocatable, intent(in) :: easting ! easting coordinates of input
     351             :     real(dp), dimension(:), allocatable, intent(in) :: northing ! easting coordinates of input
     352             :     integer(i4),    dimension(:,:,:), optional,  intent(in) :: SMIc         ! Drought indicator
     353             :     real(sp),       dimension(:,:,:), optional,  intent(in) :: SM_invert
     354             :     integer(i4),                      optional,  intent(in) :: duration     ! optional, duration
     355             : 
     356             :     ! local Variables
     357             :     type(NcDataset)              :: nc_out
     358             :     type(NcVariable)             :: nc_var
     359             :     type(NcDimension)            :: nc_y, nc_x, nc_tim
     360             :     character(256)               :: Fname
     361             : 
     362           4 :     select case (wFlag)
     363             : 
     364             :     case (2)
     365             :        ! fname
     366           1 :        fName  = trim(outpath)//'SM_invert.nc'
     367           1 :        nc_out = NcDataset(fname, 'w')
     368             : 
     369           1 :        if (allocated(lats_1d)) then
     370           0 :           nc_y = nc_out%setDimension("lat", size(SM_invert, 2))
     371           0 :           nc_x = nc_out%setDimension("lon", size(SM_invert, 1))
     372           1 :        else if (allocated(lats_2d)) then
     373           1 :           nc_y = nc_out%setDimension("northing", size(SM_invert, 2))
     374           1 :           nc_x = nc_out%setDimension("easting", size(SM_invert, 1))
     375             :        else
     376           0 :           nc_y = nc_out%setDimension("y", size(SM_invert, 2))
     377           0 :           nc_x = nc_out%setDimension("x", size(SM_invert, 1))
     378             :        end if
     379           1 :        nc_tim = nc_out%setDimension("time", -1)
     380             : 
     381             :        nc_var = nc_out%setVariable('SM_Lall', "f32", &
     382           4 :             (/ nc_x, nc_y, nc_tim /))
     383           1 :        call nc_var%setData(SM_invert)
     384           1 :        call nc_var%setAttribute('long_name', 'SM according to inverse of SMI')
     385           1 :        call nc_var%setAttribute('missing_value', nodata_sp)
     386           1 :        call nc_var%setAttribute('units', 'mm')
     387             : 
     388             : 
     389             :     case (3)
     390             :        ! fname
     391           1 :        fName  = trim(outpath)//'SMIc.nc'
     392           1 :        nc_out = NcDataset(fname, 'w')
     393           1 :        print *, 'y SMIc: ',size(SMIc, 2)
     394           1 :        print *, 'x SMIc: ',size(SMIc, 1)
     395           1 :        if (allocated(lats_1d)) then
     396           0 :           nc_y = nc_out%setDimension("lat", size(SMIc, 2))
     397           0 :           nc_x = nc_out%setDimension("lon", size(SMIc, 1))
     398           1 :        else if (allocated(lats_2d)) then
     399           1 :           nc_y = nc_out%setDimension("northing", size(SMIc, 2))
     400           1 :           nc_x = nc_out%setDimension("easting", size(SMIc, 1))
     401             :        else
     402           0 :           nc_y = nc_out%setDimension("y", size(SMIc, 2))
     403           0 :           nc_x = nc_out%setDimension("x", size(SMIc, 1))
     404             :        end if
     405           1 :        nc_tim = nc_out%setDimension("time", -1)
     406             : 
     407             :        nc_var = nc_out%setVariable('mSMIc', "i32", &
     408           4 :             (/ nc_x, nc_y, nc_tim /))
     409           1 :        call nc_var%setData(SMIc)
     410           1 :        call nc_var%setAttribute('long_name', 'monthly SMI indicator SMI < th')
     411           1 :        call nc_var%setAttribute('missing_value', nodata_i4)
     412           1 :        call nc_var%setAttribute('units', '-')
     413             : 
     414             :     case (4)
     415             :        ! fname
     416           1 :        fName = trim(outpath)//'DCluster.nc'
     417           1 :        nc_out = NcDataset(fname, 'w')
     418             : 
     419           1 :        if (allocated(lats_1d)) then
     420           0 :           nc_y = nc_out%setDimension("lat", size(idCluster, 2))
     421           0 :           nc_x = nc_out%setDimension("lon", size(idCluster, 1))
     422           1 :        else if (allocated(lats_2d)) then
     423           1 :           nc_y = nc_out%setDimension("northing", size(idCluster, 2))
     424           1 :           nc_x = nc_out%setDimension("easting", size(idCluster, 1))
     425             :        else
     426           0 :           nc_y = nc_out%setDimension("y", size(idCluster, 2))
     427           0 :           nc_x = nc_out%setDimension("x", size(idCluster, 1))
     428             :        end if
     429           1 :        nc_tim = nc_out%setDimension("time", -1)
     430             : 
     431             :        nc_var = nc_out%setVariable('mDC', "i32", &
     432           4 :             (/ nc_x, nc_y, nc_tim /))
     433           1 :        call nc_var%setData(idCluster)
     434           1 :        call nc_var%setAttribute('long_name', 'consolidated cluster evolution')
     435           1 :        call nc_var%setAttribute('missing_value', nodata_i4)
     436           1 :        call nc_var%setAttribute('units', '-')
     437             : 
     438             :     case (5)
     439             :        ! fname
     440           0 :        write (fName, '(i2.2)') duration
     441           0 :        fName = trim(outpath)//'sev_'//trim(fName)//'.nc'
     442           0 :        nc_out = NcDataset(fname, 'w')
     443             : 
     444           0 :        if (allocated(lats_1d)) then
     445           0 :           nc_y = nc_out%setDimension("lat", size(severity, 2))
     446           0 :           nc_x = nc_out%setDimension("lon", size(severity, 1))
     447           0 :        else if (allocated(lats_2d)) then
     448           0 :           nc_y = nc_out%setDimension("northing", size(severity, 2))
     449           0 :           nc_x = nc_out%setDimension("easting", size(severity, 1))
     450             :        else
     451           0 :           nc_y = nc_out%setDimension("y", size(severity, 2))
     452           0 :           nc_x = nc_out%setDimension("x", size(severity, 1))
     453             :        end if
     454           0 :        nc_tim = nc_out%setDimension("time", -1)
     455             : 
     456             :        nc_var = nc_out%setVariable('Severity', "f64", &
     457           0 :             (/ nc_x, nc_y, nc_tim /))
     458           0 :        call nc_var%setData(idCluster)
     459           0 :        call nc_var%setAttribute('long_name', 'd-month severity')
     460           0 :        call nc_var%setAttribute('missing_value', nodata_dp)
     461           3 :        call nc_var%setAttribute('units', '-')
     462             : 
     463             :     end select
     464             : 
     465             :     ! add lat and lon
     466           3 :     if (allocated(lats_1d)) then
     467           0 :       nc_var = nc_out%setVariable('lat', "f64", (/ nc_y /))
     468           0 :       call nc_var%setData(lats_1d)
     469           0 :       call nc_var%setAttribute('long_name', 'latitude')
     470           0 :       call nc_var%setAttribute('missing_value', nodata_dp)
     471           0 :       call nc_var%setAttribute('units', 'degrees_north')
     472           3 :     else if (allocated(lats_2d)) then
     473           9 :       nc_var = nc_out%setVariable('lat', "f64", (/ nc_x, nc_y /))
     474           3 :       call nc_var%setData(lats_2d)
     475           3 :       call nc_var%setAttribute('long_name', 'latitude')
     476           3 :       call nc_var%setAttribute('missing_value', nodata_dp)
     477           3 :       call nc_var%setAttribute('units', 'degrees_north')
     478             : 
     479             :       ! nc_var = nc_out%setVariable('northing', "f64", (/ nc_y /))
     480             :       ! call nc_var%setData(northing)
     481             :       ! call nc_var%setAttribute('long_name', 'northing')
     482             :       ! call nc_var%setAttribute('missing_value', nodata_dp)
     483             :       ! call nc_var%setAttribute('units', 'meters')
     484             :    end if
     485             : 
     486           3 :     if (allocated(lons_1d)) then
     487           0 :        nc_var = nc_out%setVariable('lon', "f64", (/ nc_x /))
     488           0 :       call nc_var%setData(lons_1d)
     489           0 :       call nc_var%setAttribute('long_name', 'longitude')
     490           0 :       call nc_var%setAttribute('missing_value', nodata_dp)
     491           0 :       call nc_var%setAttribute('units', 'degrees_east')
     492           3 :     else if (allocated(lons_2d)) then
     493           9 :       nc_var = nc_out%setVariable('lon', "f64", (/ nc_x, nc_y /))
     494           3 :       call nc_var%setData(lons_2d)
     495           3 :       call nc_var%setAttribute('long_name', 'longitude')
     496           3 :       call nc_var%setAttribute('missing_value', nodata_dp)
     497           3 :       call nc_var%setAttribute('units', 'degrees_east')
     498             : 
     499             :       ! nc_var = nc_out%setVariable('easting', "f64", (/ nc_x /))
     500             :       ! call nc_var%setData(easting)
     501             :       ! call nc_var%setAttribute('long_name', 'easting')
     502             :       ! call nc_var%setAttribute('missing_value', nodata_dp)
     503             :       ! call nc_var%setAttribute('units', 'meters')
     504             :     end if
     505             : 
     506             :     ! add time
     507             :     if ((wflag .eq. 2) .or. &
     508           3 :         (wflag .eq. 3) .or. &
     509             :         (wflag .eq. 4)) then
     510           6 :       nc_var = nc_out%setVariable('time', "i32", (/ nc_tim /))
     511           3 :       call nc_var%setData(per%time_points)
     512           3 :       call nc_var%setAttribute('long_name', 'time')
     513             :       call nc_var%setAttribute('units', 'days since '                              // &
     514             :           trim(num2str(per%y_start,   '(i4)')) // '-'     // &
     515             :           trim(num2str(per%m_start, '(i2.2)')) // '-'     // &
     516           3 :           trim(num2str(per%d_start, '(i2.2)')) // ' 00:00:00' )
     517             :     end if
     518             :     ! close file
     519           3 :     call nc_out%close()
     520           3 :   end subroutine WriteNetCDF
     521             : 
     522             : !> \brief WRITE Results of the cluster analysis
     523             : !> \author Luis E. Samaniego-Eguiguren, UFZ
     524             : !> \date 17.03.2011
     525           1 : subroutine WriteResultsCluster(SMIc, outpath, wFlag, yStart, yEnd, nMonths, nCells, &
     526             :      deltaArea, cellsize, d)
     527             : 
     528           3 :   use mo_kind,          only : i4, dp
     529             :   use mo_constants,     only : YearMonths
     530             : 
     531             :   !
     532             :   implicit none
     533             : 
     534             :   ! input variables
     535             :   character(len=*),      intent(in)        :: outpath     ! ouutput path for results
     536             :   integer(i4), dimension(:,:,:),intent(in) :: SMIc        ! Drought indicator 1 - is under drought
     537             :   integer(i4),           intent(in)        :: wFlag
     538             :   integer(i4),           intent(in)        :: yStart
     539             :   integer(i4),           intent(in)        :: yEnd
     540             :   integer(i4),           intent(in)        :: nMonths
     541             :   integer(i4),           intent(in)        :: nCells
     542             :   integer(i4),           intent(in)        :: deltaArea
     543             :   real(sp),              intent(in)        :: cellsize
     544             :   integer(i4), optional, intent(in)        :: d
     545             :   real(dp), parameter                      :: eps = 1.0e-5_dp ! EPSILON(1.0_dp)
     546             : 
     547             : 
     548             :   ! local variables
     549             :   real(dp)                  :: pDArea
     550             :   !
     551             :   integer(i4)               :: i, j, t, k, y, m, mStart, mEnd
     552             :   character(len=256)        :: FMT
     553             :   character(len=256)        :: fName
     554             : 
     555           2 :   select case (wFlag)
     556             :     case (1)
     557             :       ! main statistics
     558           1 :       fName = trim(outpath) // 'results_ADM.txt'
     559           1 :       open  (10, file = fName, status='unknown')
     560           1 :       write (10, 100 ) 'i', 'c_Id', 'mStart', 'mEnd', 'aDD', 'aDA', 'TDM'
     561          70 :       do i = 1,nClusters
     562             :          ! find starting and ending months of every cluster
     563          69 :          mStart = 0
     564          69 :          mEnd = 0
     565       13090 :          do t = 1, nMonths
     566       13090 :             if ( DAreaEvol(t,i) .gt. 0.0_dp) then
     567          69 :                mEnd = t
     568          69 :                if (mStart .eq. 0) mStart = t
     569             :             end if
     570       13090 :             if ( ( DAreaEvol(t,i) .lt. eps) .and. (mStart .gt. 0) ) exit
     571             :          end do
     572          70 :         write (10,110)  i, shortCnoList(i), mStart, mEnd, aDD(i), aDA(i), TDM(i)
     573             :       end do
     574           1 :       close (10)
     575             :       !
     576           1 :       fName = trim(outpath) // 'DArea_evol.txt'
     577           1 :       open  (11, file = fName, status='unknown')
     578           1 :       write (FMT, 120) '(a5,', nClusters, '(2x,a2,i7.7))'
     579          70 :       write (11, FMT ) 'm', ('c_', shortCnoList(i), i=1,nClusters)
     580           1 :       write (FMT, 130) '(i5,', nClusters, 'e11.5)'
     581         361 :       do t=1, nMonths
     582         361 :         write (11,FMT) t, (DAreaEvol(t,i), i=1,nClusters)
     583             :       end  do
     584           1 :       close (11)
     585             :       !
     586           1 :       fName = trim(outpath) // 'TDM_evol.txt'
     587           1 :       open  (12, file = fName, status='unknown')
     588           1 :       write (FMT, 120) '(a5,', nClusters, '(2x,a2,i7.7))'
     589          70 :       write (12, FMT ) 'm', ('c_', shortCnoList(i), i=1,nClusters)
     590           1 :       write (FMT, 130) '(i5,', nClusters, 'e11.5)'
     591         361 :       do t=1, nMonths
     592         361 :         write (12,FMT) t, (DTMagEvol(t,i), i=1,nClusters)
     593             :       end  do
     594           1 :       close (12)
     595             :       !
     596           1 :       fName = trim(outpath) // 'event_ids.txt'
     597           1 :       open  (13, file = fName, status='unknown')
     598           1 :       write (13, 140 ) '<event>', 'c_Id', 'month', 'nCells'
     599             :       ! sorted events in ascending order of areal extend
     600          70 :       do i=1, nEvents
     601         277 :         write (13,145) eIdPerm(i), (eventId(eIdPerm(i),j), j=1,3)
     602             :       end  do
     603           1 :       close (13)
     604             :       !
     605             :       ! NEW STATISTICS
     606             :       ! total drought area evolution (% w.r.t. whole domain)
     607           1 :       fName = trim(outpath) // 'DArea_evol_total.txt'
     608           1 :       open  (14, file = fName, status='unknown')
     609           1 :       write (14, 150 ) 'year', 'month', '%AreaEU'
     610           1 :       t = 0
     611          31 :       do y =yStart, yEnd
     612         391 :         do m = 1, int(YearMonths, i4)
     613         360 :           t = t + 1
     614             :           pdArea = real( count( SMIc(:,:,t) == 1 ), dp) / &
     615       14760 :                    real( nCells, dp) * 1e2_dp
     616         390 :           write(14,160) y, m, pdArea
     617             :         end do
     618             :       end do
     619           1 :       close (14)
     620             :       !
     621             :       ! Time evolution of the cluster area (less than SMIc) and monthly severity
     622           1 :       fName = trim(outpath) // 'DcArea_sev_evol.txt'
     623           1 :       open  (15, file = fName, status='unknown')
     624           1 :       write (15, 170 ) 'year', 'month', '%cAreaEU','SevDE'
     625           1 :       t = 0
     626          31 :       do y =yStart, yEnd
     627         391 :         do m = 1, int(YearMonths, i4)
     628         360 :           t = t + 1
     629         390 :           write(15,180) y, m, dASevol(t,1,nBasins+1), dASevol(t,2,nBasins+1)
     630             :         end do
     631             :       end do
     632           1 :       close (15)
     633             :       !
     634             :     case(2)
     635             :       ! SAD curves for each event and duration
     636           0 :       do k = 1, nLargerEvents
     637           0 :          write (fName,200) 'SAD_e_',  eIdPerm( nEvents + 1 - k ) , '_', d, '.txt'
     638           0 :          fName = trim(outpath) // trim(fName)
     639           0 :          open (20, file=fName, status='unknown')
     640           0 :          write (20,210) 'Area[km2]', 'Severity'
     641           0 :          write (20,220) (( SAD(i, j, k ), j=1,2 ), i=1, nInterArea)
     642           0 :          close(20)
     643             :       end do
     644             : 
     645             :       ! SAD percentiles for a given duration
     646           0 :       write (fName,230) 'SAD_perc_', d, '.txt'
     647           0 :       fName = trim(outpath) // trim(fName)
     648           0 :       open (21, file=fName, status='unknown')
     649           0 :       write (FMT, 240) '(a15,', nQProp, '(9x,a2,f4.2))'
     650           0 :       write (21,FMT) 'Area[km2]', ('p_', QProp(i), i=1,nQProp)
     651           0 :       write (FMT, 250) '(f15.0,', nQProp, 'f15.5)'
     652           0 :       write (21,FMT) ( real(i * deltaArea, dp)*(real(cellsize,dp)**2.0_dp), (SADperc(i,j), j=1,nQProp), i=1, nInterArea)
     653             : 
     654           1 :       close (21)
     655             :   end select
     656             : 
     657             :   100 format (2a15, 2a10, 3a15)
     658             :   110 format (2i15, 2i10, 3f15.5)
     659             :   120 format (a4,i5,a13)
     660             :   130 format (a4,i5,a6)
     661             :   140 format (4a12)
     662             :   145 format (4i12)
     663             :   150 format (2a10,a10)
     664             :   160 format (2i10,f10.3)
     665             :   170 format (2a10,2a10)
     666             :   180 format (2i10,2f10.3)
     667             : 
     668             :   200 format (a6,i5.5,a,i2.2,a4)
     669             :   210 format (2a15)
     670             :   220 format (f15.0, f15.5)
     671             :   230 format (a9,i5.5,a,i2.2,a4)
     672             :   240 format (a5,i2,a13)
     673             :   250 format (a7,i2,a6)
     674           1 : end subroutine WriteResultsCluster
     675             : 
     676             : 
     677             : !> \brief WRITE Results of the cluster SMI basins
     678             : !> \author Luis E. Samaniego-Eguiguren, UFZ
     679             : !> \date 24.05.2011
     680           0 : subroutine WriteResultsBasins( outpath, SMI, mask, yStart, yEnd, nMonths, Basin_Id )
     681             : 
     682             :   use mo_kind,          only : i4
     683             :   use mo_constants,     only : nodata_dp, YearMonths
     684             : 
     685             :   implicit none
     686             : 
     687             :   ! input variables
     688             :   character(len=*),            intent(in) :: outpath     ! ouutput path for results
     689             :   real(sp),    dimension(:,:), intent(in) :: SMI
     690             :   logical,     dimension(:,:), intent(in) :: mask
     691             :   integer(i4),                 intent(in) :: yStart
     692             :   integer(i4),                 intent(in) :: yEnd
     693             :   integer(i4),                 intent(in) :: nMonths     ! number of simulated months
     694             :   integer(i4), dimension(:,:), intent(in) :: Basin_Id    ! IDs for basinwise drought analysis
     695             : 
     696             :   ! local variables
     697             :   real(dp),    dimension(size(mask,1), &
     698           0 :                         size(mask,2), nMonths) :: SMI_unpack
     699             :   character(len=256)                           :: fName
     700             :   integer(i4)                                  :: i, m, y, j
     701           0 :   real(dp),    dimension(:,:), allocatable     :: Basin_SMI
     702             : 
     703             :   !-------------------------
     704             :   ! basin wise
     705             :   !-------------------------
     706           0 :   allocate( Basin_SMI (nMonths, nBasins+1) )
     707             :   ! unpack SMI
     708           0 :   do i = 1, size(SMI,2)
     709           0 :      SMI_unpack(:,:,i) = unpack(real(SMI(:,i), dp), mask, nodata_dp)
     710             :   end do
     711             : 
     712           0 :   Basin_SMI = nodata_dp
     713             :   !
     714           0 :   do m = 1, nMonths
     715           0 :     do i = 1, nBasins
     716             :       !
     717           0 :       Basin_SMI(m,i) = sum( SMI_unpack(:,:,m), Basin_Id(:,:) == i ) / real(count(Basin_Id(:,:) == i), dp)
     718             :       !
     719             :     end do
     720             :     Basin_SMI(m,nBasins+1) = sum(SMI_unpack(:,:,m), mask ) /  &
     721           0 :          real(count(mask), dp)
     722             :   end do
     723             :   !
     724             :   ! Print Results
     725           0 :   fName = trim(outpath) // 'basin_avg_SMI.txt'
     726           0 :   open(20, file =fName , status = 'unknown')
     727           0 :   write(20, 1) 'Month_No', 'year', 'month', ('Basin_', i, i = 1, nBasins), 'Germany_Avg'
     728             :   !
     729           0 :   fName = trim(outpath) // 'basin_avg_dArea.txt'
     730           0 :   open(21, file =fName , status = 'unknown')
     731           0 :   write(21, 3) 'Month_No', 'year', 'month', ('Basin_', i, i = 1, nBasins)
     732             :   !
     733           0 :   fName = trim(outpath) // 'basin_avg_sev.txt'
     734           0 :   open(22, file =fName , status = 'unknown')
     735           0 :   write(22, 3) 'Month_No', 'year', 'month', ('Basin_', i, i = 1, nBasins)
     736             :   !! NEW !!
     737           0 :   m=0
     738           0 :   do y = yStart, yEnd
     739           0 :      do j = 1, int(YearMonths, i4)
     740           0 :         m = m + 1
     741           0 :         write(20, 2) m, y, j, (Basin_SMI(m,i), i = 1, nBasins), Basin_SMI(m,nBasins+1)
     742           0 :         write(21, 4) m, y, j, (dASevol(m,1,i), i = 1, nBasins)
     743           0 :         write(22, 4) m, y, j, (dASevol(m,2,i), i = 1, nBasins)
     744             :      end do
     745             :   end do
     746           0 :   close(20)
     747           0 :   close(21)
     748           0 :   close(22)
     749             :   !
     750             :   1 format(3a8, 2x, 6(a6, i2.2, 2x),  a13 )
     751             :   2 format(3i8, 2x, 6(f8.4,     2x),  f13.4)
     752             :   3 format(3a8, 2x, 6(a6, i2.2, 2x) )
     753             :   4 format(3i8, 2x, 6(f8.4,     2x) )
     754             : 
     755           0 : end subroutine WriteResultsBasins
     756             : 
     757             : end module mo_smi_write

Generated by: LCOV version 1.16