Index: palm/trunk/UTIL/inifor/src/inifor_defs.f90
===================================================================
--- palm/trunk/UTIL/inifor/src/inifor_defs.f90	(revision 4567)
+++ palm/trunk/UTIL/inifor/src/inifor_defs.f90	(revision 4568)
@@ -26,4 +26,8 @@
 ! -----------------
 ! $Id$
+! Bumped version number
+! 
+! 
+! 4553 2020-06-03 16:34:15Z eckhard
 ! Bumped version number
 ! 
@@ -178,5 +182,6 @@
 
 ! 
-!-- COSMO netCDF names
+!-- COSMO netCDF parameters
+INTEGER, PARAMETER          ::  NC_DEPTH_DIM_IDX = 3
 CHARACTER(SNAME), PARAMETER ::  NC_DEPTH_NAME = 'depth_2'
 CHARACTER(SNAME), PARAMETER ::  NC_HHL_NAME = 'HHL'
@@ -196,5 +201,5 @@
     ACHAR( 10 ) // ' Copyright 2017-2020 Deutscher Wetterdienst Offenbach' !< Copyright notice
  CHARACTER(LEN=*), PARAMETER ::  LOG_FILE_NAME = 'inifor.log' !< Name of INIFOR's log file
- CHARACTER(LEN=*), PARAMETER ::  VERSION = '1.4.15'           !< INIFOR version number
+ CHARACTER(LEN=*), PARAMETER ::  VERSION = '1.4.16'           !< INIFOR version number
  
  END MODULE inifor_defs
Index: palm/trunk/UTIL/inifor/src/inifor_grid.f90
===================================================================
--- palm/trunk/UTIL/inifor/src/inifor_grid.f90	(revision 4567)
+++ palm/trunk/UTIL/inifor/src/inifor_grid.f90	(revision 4568)
@@ -26,4 +26,9 @@
 ! -----------------
 ! $Id$
+! Handle COSMO soil data with and without additional surface temperature
+! Imporved messaging
+! 
+! 
+! 4553 2020-06-03 16:34:15Z eckhard
 ! Fixed domain extent check
 ! Added and fixed code documentation
@@ -177,5 +182,6 @@
         ONLY:  get_cosmo_grid, get_input_file_list, get_netcdf_attribute,      &
                get_netcdf_dim_vector, get_netcdf_variable, set_palm_origin,    &
-               parse_command_line_arguments, validate_config
+               parse_command_line_arguments, validate_config,                  &
+               has_surface_value
     USE inifor_transform,                                                      &
         ONLY:  average_2d, rotate_to_cosmo, find_horizontal_neighbours,        &
@@ -639,5 +645,5 @@
     CALL report ('setup_parameters', message)
 
-    message = "North pole of the rotated COSMO-DE system:" // NEW_LINE(' ') // &
+    message = "COSMO rotated north pole:" // NEW_LINE(' ') // &
        "           lon (lambda) = " // &
        TRIM(real_to_str_f(lambda_n * TO_DEGREES)) // " deg" // NEW_LINE(' ') //&
@@ -2384,5 +2390,5 @@
     ENDIF
 
-    nc_source_text = 'COSMO-DE analysis from ' // TRIM(cfg%start_date)
+    nc_source_text = 'COSMO analysis from ' // TRIM(cfg%start_date)
 
     n_invar = 17
@@ -2395,8 +2401,17 @@
 !- Section 1: NetCDF input variables
 !------------------------------------------------------------------------------
+
+!
+!-- COSMO's soil temperature T_SO may contain the surface temperature at
+!-- depth=0, which is a redundant copy the first soil layer. INIFOR uses this
+!-- flag to decide if this level is present and has to be ignored in
+!-- inifor_io:get_netcdf_start_and_count().
+    input_var_table(:)%has_redundant_first_level = .FALSE.
+
     var => input_var_table(1)
     var%name = 'T_SO'
     var%to_be_processed = .TRUE.
     var%is_upside_down = .FALSE.
+    input_var_table(1)%has_redundant_first_level = has_surface_value( var, soil_files(1) )
 
     var => input_var_table(2)
Index: palm/trunk/UTIL/inifor/src/inifor_io.f90
===================================================================
--- palm/trunk/UTIL/inifor/src/inifor_io.f90	(revision 4567)
+++ palm/trunk/UTIL/inifor/src/inifor_io.f90	(revision 4568)
@@ -26,4 +26,8 @@
 ! -----------------
 ! $Id$
+! Handle COSMO soil data with and without additional surface temperature
+! 
+! 
+! 4553 2020-06-03 16:34:15Z eckhard
 ! Option --help now points the user to INIFOR's wiki page
 ! Remove deprecated command-line options -clon and -clat
@@ -146,11 +150,11 @@
     USE inifor_defs,                                                           &
         ONLY:  DATE, SNAME, PATH, PI, TO_RADIANS, TO_DEGREES, VERSION,         &
-               NC_DEPTH_NAME, NC_HHL_NAME, NC_RLAT_NAME, NC_RLON_NAME,         &
-               NC_ROTATED_POLE_NAME, NC_POLE_LATITUDE_NAME,                    &
+               NC_DEPTH_DIM_IDX, NC_DEPTH_NAME, NC_HHL_NAME, NC_RLAT_NAME,     &
+               NC_RLON_NAME, NC_ROTATED_POLE_NAME, NC_POLE_LATITUDE_NAME,      &
                NC_POLE_LONGITUDE_NAME, RHO_L, iwp, wp,                         &
                PIDS_ORIGIN_LON, PIDS_ORIGIN_LAT, PIDS_ORIGIN_Z
     USE inifor_types
     USE inifor_util,                                                           &
-        ONLY:  add_hours_to, reverse, str, real_to_str
+        ONLY:  add_hours_to, nearly_equal, reverse, str, real_to_str
     USE netcdf
 
@@ -355,5 +359,7 @@
 
     start = (/ 1, 1, 1 /)
-    IF ( TRIM(in_var%name) .EQ. 'T_SO' )  THEN
+    IF ( TRIM(in_var%name) .EQ. 'T_SO' .AND.                                &
+         in_var%has_redundant_first_level )  THEN
+       
 !
 !--    Skip depth = 0.0 for T_SO and reduce number of depths from 9 to 8
@@ -1578,4 +1584,80 @@
  END SUBROUTINE set_palm_origin
 
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+! This function is meant to check weather a COSMO soil variable has an
+! additional and redunant surface value at depth = 0.0. For instance operational
+! DWD COSMO output contains the surface temperature in T_SO as a copy of the
+! values in the first soil layer.
+!------------------------------------------------------------------------------!
+ LOGICAL FUNCTION has_surface_value( soil_var, filename ) 
+
+    TYPE(nc_var), INTENT(IN)     ::  soil_var
+    CHARACTER(LEN=*), INTENT(IN) ::  filename
+    
+    CHARACTER(LEN=NF90_MAX_NAME) ::  dimname
+    REAL(wp), ALLOCATABLE        ::  depths(:)
+
+    CALL get_dimension_vector_of_variable(                                     &
+       soil_var%name,                                                          &
+       dim_idx = NC_DEPTH_DIM_IDX,                                             &
+       filename = filename,                                                    &
+       dim_vector = depths                                                     &
+    )
+
+    has_surface_value = nearly_equal( depths(1), 0.0_wp, 10 * EPSILON(1.0_wp) )
+
+ END FUNCTION has_surface_value 
+
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+! This routine reads the dim_idx-th dimension vector of the variable varname
+! from netCDF file filename. It is used for finding the depth coordinate vector
+! of COSMO soil variables without knowing its name.
+!------------------------------------------------------------------------------!
+ SUBROUTINE get_dimension_vector_of_variable( varname, dim_idx, filename, dim_vector )
+    CHARACTER(LEN=*), INTENT(IN)              ::  varname, filename
+    INTEGER, INTENT(IN)                       ::  dim_idx
+
+    REAL(wp), INTENT(OUT), ALLOCATABLE ::  dim_vector(:)
+
+    INTEGER                            ::  dimids(NF90_MAX_VAR_DIMS)
+    INTEGER                            ::  varid
+    CHARACTER(LEN=NF90_MAX_NAME)       ::  dimname
+
+    INTEGER ::  ncid
+
+    IF ( nf90_open( TRIM( filename ), NF90_NOWRITE, ncid ) .EQ. NF90_NOERR )  THEN
+
+!
+!--    get id of variable varname
+       CALL check( nf90_inq_varid( ncid, TRIM( varname ), varid ) )
+       
+!
+!--    get dimension ids of variable with varid
+       CALL check( nf90_inquire_variable( ncid, varid, dimids = dimids ) )
+
+!
+!--    get name of dim_idx-th dimension variable
+       CALL check( nf90_inquire_dimension( ncid, dimids(dim_idx), name = dimname ) )
+       CALL check( nf90_close( ncid ) )
+
+    ELSE
+
+       message = "Failed to open file '" // TRIM(filename) // "'."
+       CALL inifor_abort('get_netcdf_variable', message)
+
+    ENDIF
+
+    ! get dimension vector with dimname
+    CALL get_netcdf_dim_vector( filename, dimname, dim_vector )
+
+ END SUBROUTINE get_dimension_vector_of_variable
+
+
  END MODULE inifor_io
 #endif
Index: palm/trunk/UTIL/inifor/src/inifor_types.f90
===================================================================
--- palm/trunk/UTIL/inifor/src/inifor_types.f90	(revision 4567)
+++ palm/trunk/UTIL/inifor/src/inifor_types.f90	(revision 4568)
@@ -26,4 +26,8 @@
 ! -----------------
 ! $Id$
+! Handle COSMO soil data with and without additional surface temperature
+!
+! 
+! 4553 2020-06-03 16:34:15Z eckhard
 ! Minor code readability improvements
 ! 
@@ -245,4 +249,5 @@
     LOGICAL                               ::  is_read = .FALSE.         !< INIFOR flag indicating whether variable has been read
     LOGICAL                               ::  is_upside_down  = .FALSE. !< INIFOR flag indicating whether vertical dimension is reversed (typically the case with COSMO-DE atmospheric fields)
+    LOGICAL                               ::  has_redundant_first_level !< INIFOR flag inidicating whether a soil variable has a redundant first level (e.g. COSMO's T_SO may contain the surface temperature at depth=0, which is a redundant copy the first model layer)
     TYPE(grid_definition), POINTER        ::  grid                      !< Pointer to the corresponding output grid
     TYPE(grid_definition), POINTER        ::  intermediate_grid         !< Pointer to the corresponding intermediate grid
Index: palm/trunk/UTIL/inifor/src/inifor_util.f90
===================================================================
--- palm/trunk/UTIL/inifor/src/inifor_util.f90	(revision 4567)
+++ palm/trunk/UTIL/inifor/src/inifor_util.f90	(revision 4568)
@@ -26,4 +26,8 @@
 ! -----------------
 ! $Id$
+! Added function for checking floating point equality
+! 
+! 
+! 4523 2020-05-07 15:58:16Z eckhard
 ! respect integer working precision (iwp) specified in inifor_defs.f90
 ! 
@@ -462,3 +466,21 @@
  END SUBROUTINE
 
+
+!------------------------------------------------------------------------------!
+! Description:
+! ------------
+!> Check for exact or near equality of two floating point numbers. Inspired by
+!> https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
+!------------------------------------------------------------------------------!
+ LOGICAL FUNCTION nearly_equal(a, b, max_rel_diff)
+
+    REAL(wp), INTENT(IN) ::  a, b, max_rel_diff
+    REAL(wp)             ::  diff, mag
+ 
+    diff = ABS( a - b ) 
+    mag = MAX( ABS(a), ABS(b) )
+    nearly_equal = ( diff .LE. mag * max_rel_diff )
+
+ END FUNCTION nearly_equal
+
  END MODULE inifor_util
