LCOV - code coverage report
Current view: | top level - hemco/HEMCO/src/Shared/NcdfUtil - hco_ncdf_mod.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 0 | 1042 | 0.0 %
Date: | 2025-01-13 21:54:50 |  | Functions: | 0 | 44 | 0.0 %

              Line data    Source code
           1             : !------------------------------------------------------------------------------
           2             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
           3             : !                      and NASA/GFSC, SIVO, Code 610.3                        !
           4             : !------------------------------------------------------------------------------
           5             : !BOP
           6             : !
           7             : ! !MODULE: HCO_ncdf_mod.F90
           8             : !
           9             : ! !DESCRIPTION: Module HCO\_NCDF\_MOD contains routines to read data from
          10             : ! netCDF files.
          11             : !\\
          12             : !\\
          13             : ! !INTERFACE:
          14             : !
          15             : MODULE HCO_NCDF_MOD
          16             : !
          17             : ! !USES:
          18             : !
          19             :   ! Modules for netCDF read
          20             :   USE netCDF
          21             :   USE HCO_m_netcdf_io_open
          22             :   USE HCO_m_netcdf_io_get_dimlen
          23             :   USE HCO_m_netcdf_io_read
          24             :   USE HCO_m_netcdf_io_readattr
          25             :   USE HCO_m_netcdf_io_close
          26             :   USE HCO_m_netcdf_io_create
          27             :   USE HCO_m_netcdf_io_define
          28             :   USE HCO_m_netcdf_io_write
          29             :   USE HCO_m_netcdf_io_checks
          30             :   USE HCO_PRECISION_MOD, ONLY : SP => f4, DP => f8
          31             :
          32             :   IMPLICIT NONE
          33             :   PRIVATE
          34             : !
          35             : ! !PUBLIC MEMBER FUNCTIONS:
          36             : !
          37             :   PUBLIC  :: NC_OPEN
          38             :   PUBLIC  :: NC_APPEND
          39             :   PUBLIC  :: NC_CREATE
          40             :   PUBLIC  :: NC_SET_DEFMODE
          41             :   PUBLIC  :: NC_VAR_DEF
          42             :   PUBLIC  :: NC_VAR_CHUNK
          43             :   PUBLIC  :: NC_VAR_WRITE
          44             :   PUBLIC  :: NC_CLOSE
          45             :   PUBLIC  :: NC_READ_TIME
          46             :   PUBLIC  :: NC_READ_TIME_YYYYMMDDhhmm
          47             :   PUBLIC  :: NC_READ_VAR
          48             :   PUBLIC  :: NC_READ_ARR
          49             :   PUBLIC  :: NC_GET_REFDATETIME
          50             :   PUBLIC  :: NC_GET_GRID_EDGES
          51             :   PUBLIC  :: NC_GET_SIGMA_LEVELS
          52             :   PUBLIC  :: NC_WRITE
          53             :   PUBLIC  :: GET_TAU0
          54             : !
          55             : ! !PRIVATE MEMBER FUNCTIONS:
          56             : !
          57             :   PRIVATE :: GET_TIDX
          58             :   PRIVATE :: TIMEUNIT_CHECK
          59             :   PRIVATE :: NC_WRITE_3D
          60             :   PRIVATE :: NC_WRITE_4D
          61             :   PRIVATE :: NC_VAR_WRITE_INT_1D
          62             :   PRIVATE :: NC_VAR_WRITE_INT_2D
          63             :   PRIVATE :: NC_VAR_WRITE_INT_3D
          64             :   PRIVATE :: NC_VAR_WRITE_INT_4D
          65             :   PRIVATE :: NC_VAR_WRITE_R4_1D
          66             :   PRIVATE :: NC_VAR_WRITE_R4_2D
          67             :   PRIVATE :: NC_VAR_WRITE_R4_3D
          68             :   PRIVATE :: NC_VAR_WRITE_R4_4D
          69             :   PRIVATE :: NC_VAR_WRITE_R8_0D
          70             :   PRIVATE :: NC_VAR_WRITE_R8_1D
          71             :   PRIVATE :: NC_VAR_WRITE_R8_2D
          72             :   PRIVATE :: NC_VAR_WRITE_R8_3D
          73             :   PRIVATE :: NC_VAR_WRITE_R8_4D
          74             :   PRIVATE :: NC_READ_VAR_SP
          75             :   PRIVATE :: NC_READ_VAR_DP
          76             :   PRIVATE :: NC_GET_GRID_EDGES_SP
          77             :   PRIVATE :: NC_GET_GRID_EDGES_DP
          78             :   PRIVATE :: NC_GET_GRID_EDGES_C
          79             :   PRIVATE :: NC_GET_SIGMA_LEVELS_SP
          80             :   PRIVATE :: NC_GET_SIGMA_LEVELS_DP
          81             :   PRIVATE :: NC_GET_SIGMA_LEVELS_C
          82             :   PRIVATE :: NC_GET_SIG_FROM_HYBRID
          83             :   PRIVATE :: NC_READ_VAR_CORE
          84             : !
          85             : ! !REVISION HISTORY:
          86             : !  See https://github.com/geoschem/hemco for complete history
          87             : !EOP
          88             : !------------------------------------------------------------------------------
          89             : !BOC
          90             : !
          91             : ! !MODULE INTERFACES:
          92             : !
          93             :   INTERFACE NC_WRITE
          94             :      MODULE PROCEDURE NC_WRITE_3D
          95             :      MODULE PROCEDURE NC_WRITE_4D
          96             :   END INTERFACE NC_WRITE
          97             :
          98             :   INTERFACE NC_READ_VAR
          99             :      MODULE PROCEDURE NC_READ_VAR_SP
         100             :      MODULE PROCEDURE NC_READ_VAR_DP
         101             :   END INTERFACE NC_READ_VAR
         102             :
         103             :   INTERFACE NC_GET_GRID_EDGES
         104             :      MODULE PROCEDURE NC_GET_GRID_EDGES_SP
         105             :      MODULE PROCEDURE NC_GET_GRID_EDGES_DP
         106             :   END INTERFACE NC_GET_GRID_EDGES
         107             :
         108             :   INTERFACE NC_GET_SIGMA_LEVELS
         109             :      MODULE PROCEDURE NC_GET_SIGMA_LEVELS_SP
         110             :      MODULE PROCEDURE NC_GET_SIGMA_LEVELS_DP
         111             :   END INTERFACE NC_GET_SIGMA_LEVELS
         112             :
         113             :   INTERFACE NC_VAR_WRITE
         114             :      MODULE PROCEDURE NC_VAR_WRITE_INT_0D
         115             :      MODULE PROCEDURE NC_VAR_WRITE_INT_1D
         116             :      MODULE PROCEDURE NC_VAR_WRITE_INT_2D
         117             :      MODULE PROCEDURE NC_VAR_WRITE_INT_3D
         118             :      MODULE PROCEDURE NC_VAR_WRITE_INT_4D
         119             :      MODULE PROCEDURE NC_VAR_WRITE_R4_0D
         120             :      MODULE PROCEDURE NC_VAR_WRITE_R4_1D
         121             :      MODULE PROCEDURE NC_VAR_WRITE_R4_2D
         122             :      MODULE PROCEDURE NC_VAR_WRITE_R4_3D
         123             :      MODULE PROCEDURE NC_VAR_WRITE_R4_4D
         124             :      MODULE PROCEDURE NC_VAR_WRITE_R8_0D
         125             :      MODULE PROCEDURE NC_VAR_WRITE_R8_1D
         126             :      MODULE PROCEDURE NC_VAR_WRITE_R8_2D
         127             :      MODULE PROCEDURE NC_VAR_WRITE_R8_3D
         128             :      MODULE PROCEDURE NC_VAR_WRITE_R8_4D
         129             :   END INTERFACE NC_VAR_WRITE
         130             :
         131             : CONTAINS
         132             : !EOC
         133             : !------------------------------------------------------------------------------
         134             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         135             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         136             : !------------------------------------------------------------------------------
         137             : !BOP
         138             : !
         139             : ! !IROUTINE: Nc_Open
         140             : !
         141             : ! !DESCRIPTION: Simple wrapper routine to open the given netCDF file.
         142             : !\\
         143             : !\\
         144             : ! !INTERFACE:
         145             : !
         146           0 :   SUBROUTINE NC_OPEN( FileName, fID )
         147             : !
         148             : ! !INPUT PARAMETERS:
         149             : !
         150             :     CHARACTER(LEN=*), INTENT(IN)  :: FileName
         151             : !
         152             : ! !OUTPUT PARAMETERS:
         153             : !
         154             :     INTEGER,          INTENT(OUT) :: fID
         155             : !
         156             : ! !REVISION HISTORY:
         157             : !  See https://github.com/geoschem/hemco for complete history
         158             : !EOP
         159             : !------------------------------------------------------------------------------
         160             : !BOC
         161             :     !=================================================================
         162             :     ! NC_OPEN begins here
         163             :     !=================================================================
         164             :
         165             :     ! Open netCDF file
         166           0 :     CALL Ncop_Rd( fId, TRIM( FileName ) )
         167             :
         168           0 :   END SUBROUTINE NC_OPEN
         169             : !EOC
         170             : !------------------------------------------------------------------------------
         171             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         172             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         173             : !------------------------------------------------------------------------------
         174             : !BOP
         175             : !
         176             : ! !IROUTINE: Nc_Append
         177             : !
         178             : ! !DESCRIPTION: Simple wrapper routine to open the given netCDF file.
         179             : !  for appending extra values along a record dimension.
         180             : !\\
         181             : !\\
         182             : ! !INTERFACE:
         183             : !
         184           0 :   SUBROUTINE NC_APPEND( FileName, fID, nTime )
         185             : !
         186             : ! !INPUT PARAMETERS:
         187             : !
         188             :     CHARACTER(LEN=*), INTENT(IN)  :: FileName
         189             : !
         190             : ! !OUTPUT PARAMETERS:
         191             : !
         192             :     INTEGER,          INTENT(OUT) :: fID
         193             :     INTEGER,          OPTIONAL    :: nTime
         194             : !
         195             : ! !REVISION HISTORY:
         196             : !  See https://github.com/geoschem/hemco for complete history
         197             : !EOP
         198             : !------------------------------------------------------------------------------
         199             : !BOC
         200             : !
         201             : ! !LOCAL VARIABLES:
         202             : !
         203             :     INTEGER :: RC, vId
         204             :
         205             :     !=================================================================
         206             :     ! NC_APPEND begins here
         207             :     !=================================================================
         208             :
         209             :     ! Open netCDF file
         210           0 :     CALL Ncop_Wr( fId, TRIM(FileName) )
         211             :
         212             :     ! Also return the number of time slices so that we can
         213             :     ! append to an existing file w/o clobbering any data
         214           0 :     IF ( PRESENT( nTime ) ) THEN
         215           0 :        CALL Ncget_Unlim_Dimlen( fId, nTime )
         216             :     ENDIF
         217             :
         218           0 :   END SUBROUTINE NC_APPEND
         219             : !EOC
         220             : !------------------------------------------------------------------------------
         221             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         222             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         223             : !------------------------------------------------------------------------------
         224             : !BOP
         225             : !
         226             : ! !IROUTINE: Nc_Close
         227             : !
         228             : ! !DESCRIPTION: Simple wrapper routine to close the given lun.
         229             : !\\
         230             : !\\
         231             : ! !INTERFACE:
         232             : !
         233           0 :   SUBROUTINE NC_CLOSE( fID )
         234             : !
         235             : ! !INPUT PARAMETERS:
         236             : !
         237             :     INTEGER, INTENT(IN   ) :: fID
         238             : !
         239             : ! !REVISION HISTORY:
         240             : !  See https://github.com/geoschem/hemco for complete history
         241             : !EOP
         242             : !------------------------------------------------------------------------------
         243             : !BOC
         244             :
         245             :     !=================================================================
         246             :     ! NC_CLOSE begins here
         247             :     !=================================================================
         248             :
         249           0 :     CALL NcCl( fID )
         250             :
         251           0 :   END SUBROUTINE NC_CLOSE
         252             : !EOC
         253             : !------------------------------------------------------------------------------
         254             : !                  GEOS-Chem Global Chemical Transport Model                  !
         255             : !------------------------------------------------------------------------------
         256             : !BOP
         257             : !
         258             : ! !IROUTINE: Nc_Set_DefMode
         259             : !
         260             : ! !DESCRIPTION: Toggles netCDF define mode on or off.
         261             : !\\
         262             : !\\
         263             : ! !INTERFACE:
         264             : !
         265           0 :   SUBROUTINE Nc_Set_DefMode( fId, On, Off )
         266             : !
         267             : ! !INPUT PARAMETERS:
         268             : !
         269             :     INTEGER, INTENT(IN) :: fId   ! netCDF file ID
         270             :     LOGICAL, OPTIONAL   :: On    ! On=T   will turn on  netCDF define mode
         271             :     LOGICAL, OPTIONAL   :: Off   ! Off=T  will turn off netCDF define mdoe
         272             : !
         273             : ! !REMARKS:
         274             : !  This is a convenience wrapper for routines NcBegin_Def and NcEnd_Def in
         275             : !  NcdfUtil module m_netcdf_define_mod.F90.
         276             : !
         277             : ! !REVISION HISTORY:
         278             : !  See https://github.com/geoschem/hemco for complete history
         279             : !EOP
         280             : !------------------------------------------------------------------------------
         281             : !BOC
         282             :
         283             :     ! If the ON switch is passed then ...
         284           0 :     IF ( PRESENT( On ) ) THEN
         285           0 :        IF ( On ) THEN
         286           0 :           CALL NcBegin_Def( fId )  ! Turn define mode on
         287           0 :           RETURN
         288             :        ELSE
         289           0 :           CALL NcEnd_Def( fId )    ! Turn define mode off
         290           0 :           RETURN
         291             :        ENDIF
         292             :     ENDIF
         293             :
         294             :     ! If the OFF switch is passed then ,,,
         295           0 :     IF ( PRESENT( Off ) ) THEN
         296           0 :        IF ( Off ) THEN
         297           0 :           CALL NcEnd_Def( fId )      ! Turn define mode off
         298           0 :           RETURN
         299             :        ELSE
         300           0 :           CALL NcBegin_Def( fId )    ! Turn define mode on
         301           0 :           RETURN
         302             :        ENDIF
         303             :     ENDIF
         304             :
         305             :
         306             :   END SUBROUTINE Nc_Set_DefMode
         307             : !EOC
         308             : !------------------------------------------------------------------------------
         309             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         310             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         311             : !------------------------------------------------------------------------------
         312             : !BOP
         313             : !
         314             : ! !IROUTINE: Nc_Read_Time
         315             : !
         316             : ! !DESCRIPTION: Subroutine NC\_READ\_TIME reads the time variable of the
         317             : ! given fID and returns the time slices and unit.
         318             : !\\
         319             : !\\
         320             : ! !INTERFACE:
         321             : !
         322           0 :   SUBROUTINE NC_READ_TIME( fID,     nTime,        timeUnit, &
         323             :                            timeVec, timeCalendar, RC       )
         324             : !
         325             : ! !INPUT PARAMETERS:
         326             : !
         327             :     INTEGER,          INTENT(IN   )            :: fID
         328             : !
         329             : ! !OUTPUT PARAMETERS:
         330             : !
         331             :     INTEGER,          INTENT(  OUT)            :: nTime
         332             :     CHARACTER(LEN=*), INTENT(  OUT)            :: timeUnit
         333             :     REAL*8,           POINTER,       OPTIONAL  :: timeVec(:)
         334             :     CHARACTER(LEN=*), INTENT(  OUT), OPTIONAL  :: timeCalendar
         335             : !
         336             : ! !INPUT/OUTPUT PARAMETERS:
         337             : !
         338             :     INTEGER,          INTENT(INOUT)            :: RC
         339             : !
         340             : ! !REVISION HISTORY:
         341             : !  See https://github.com/geoschem/hemco for complete history
         342             : !EOP
         343             : !------------------------------------------------------------------------------
         344             : !BOC
         345             : !
         346             : ! !LOCAL VARIABLES:
         347             : !
         348             :     ! Scalars
         349             :     LOGICAL                :: hasTime
         350             :     CHARACTER(LEN=255)     :: v_name             ! netCDF variable name
         351             :     CHARACTER(LEN=255)     :: a_name             ! netCDF attribute name
         352             :     CHARACTER(LEN=255)     :: a_val              ! netCDF attribute value
         353             :     INTEGER                :: st1d(1), ct1d(1)   ! For 1D arrays
         354             :
         355             :     ! Arrays
         356           0 :     REAL*8 , ALLOCATABLE   :: tmpTime(:)
         357             :
         358             :     !=================================================================
         359             :     ! NC_READ_TIME begins here
         360             :     !=================================================================
         361             :
         362             :     ! Init
         363           0 :     RC      = 0
         364           0 :     nTime   = 0
         365           0 :     hasTime = .FALSE.
         366             :
         367             :     ! Variable name
         368           0 :     v_name = "time"
         369             :
         370             :     ! Check if dimension "time" exist
         371           0 :     hasTime = Ncdoes_Dim_Exist ( fID, TRIM(v_name) )
         372             :
         373             :     ! If time dim not found, also check for dimension "date"
         374           0 :     IF ( .NOT. hasTime ) THEN
         375           0 :        v_name   = "date"
         376           0 :        hasTime = Ncdoes_Dim_Exist ( fID, TRIM(v_name) )
         377             :     ENDIF
         378             :
         379             :     ! Return here if no time variable defined
         380           0 :     IF ( .NOT. hasTime ) RETURN
         381             :
         382             :     ! Get dimension length
         383           0 :     CALL Ncget_Dimlen ( fID, TRIM(v_name), nTime )
         384             :
         385             :     ! Read time/date units attribute
         386           0 :     a_name = "units"
         387             :     CALL NcGet_Var_Attributes( fID,          TRIM(v_name), &
         388           0 :                                TRIM(a_name), timeUnit     )
         389             :
         390             :     ! Read time vector from file.
         391           0 :     IF ( PRESENT(timeVec) ) THEN
         392           0 :        IF ( ASSOCIATED(timeVec) ) DEALLOCATE ( timeVec)
         393           0 :        ALLOCATE ( tmpTime(nTime) )
         394           0 :        ALLOCATE ( timeVec(nTime) )
         395           0 :        st1d = (/ 1     /)
         396           0 :        ct1d = (/ nTime /)
         397           0 :        CALL NcRd( tmpTime, fID, TRIM(v_name), st1d, ct1d )
         398           0 :        timevec(:) = tmpTime
         399           0 :        DEALLOCATE(tmpTime)
         400             :     ENDIF
         401             :
         402             :     ! Read calendar attribute
         403           0 :     IF ( PRESENT( timeCalendar ) ) THEN
         404             :
         405             :        ! We now get the status variable RC.  This will allow program
         406             :        ! flow to continue if the "time:calendar" attribute is not found.
         407           0 :        CALL NcGet_Var_Attributes( fId, v_name, 'calendar', timeCalendar, RC )
         408             :
         409             :        ! If "time:calendar" is found, then throw an error for
         410             :        ! climatological calendars without leap years.
         411           0 :        IF ( RC == 0 ) THEN
         412           0 :         SELECT CASE( TRIM( v_name ) )
         413             :           CASE( '360_day', '365_day', '366_day', 'all_leap',                 &
         414             :                 'allleap', 'no_leap', 'noleap'                              )
         415           0 :              WRITE( 6, '(/,a)' ) REPEAT( '=', 79 )
         416             :              WRITE( 6, '(a  )' ) 'HEMCO does not support calendar type '  // &
         417           0 :                                  TRIM( v_name )
         418           0 :              WRITE( 6, '(/,a)' )  'HEMCO supports the following calendars:'
         419           0 :              WRITE( 6, '(a)'   )  ' - standard (i.e. mixed gregorian/julian)'
         420           0 :              WRITE( 6, '(a)'   )  ' - gregorian'
         421           0 :              WRITE( 6, '(a,/)' ) REPEAT( '=', 79 )
         422           0 :              RC = -1
         423             :           CASE DEFAULT
         424             :              ! Do nothing
         425             :         END SELECT
         426             :        ENDIF
         427             :
         428             :        ! Reset RC so that we won't halt execution elsewhere
         429           0 :        RC = 0
         430             :     ENDIF
         431             :
         432           0 :   END SUBROUTINE NC_READ_TIME
         433             : !EOC
         434             : !------------------------------------------------------------------------------
         435             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         436             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         437             : !------------------------------------------------------------------------------
         438             : !BOP
         439             : !
         440             : ! !IROUTINE: Nc_Read_Var_Sp
         441             : !
         442             : ! !DESCRIPTION: Subroutine NC\_READ\_VAR\_SP reads the given variable from the
         443             : ! given fID and returns the corresponding variable values and units.
         444             : !\\
         445             : !\\
         446             : ! !INTERFACE:
         447             : !
         448           0 :   SUBROUTINE NC_READ_VAR_SP( fID, Var, nVar, varUnit, varVec, RC )
         449             : !
         450             : ! !INPUT PARAMETERS:
         451             : !
         452             :     INTEGER,          INTENT(IN   )            :: fID
         453             :     CHARACTER(LEN=*), INTENT(IN   )            :: var
         454             : !
         455             : ! !OUTPUT PARAMETERS:
         456             : !
         457             :     INTEGER,          INTENT(  OUT)            :: nVar
         458             :     CHARACTER(LEN=*), INTENT(  OUT)            :: varUnit
         459             :     REAL*4,           POINTER                  :: varVec(:)
         460             : !
         461             : ! !INPUT/OUTPUT PARAMETERS:
         462             : !
         463             :     INTEGER,          INTENT(INOUT)            :: RC
         464             : !
         465             : ! !REVISION HISTORY:
         466             : !  See https://github.com/geoschem/hemco for complete history
         467             : !EOP
         468             : !------------------------------------------------------------------------------
         469             : !BOC
         470             :
         471           0 :     CALL NC_READ_VAR_CORE( fID, Var, nVar, varUnit, varVecSp=varVec, RC=RC )
         472             :
         473           0 :   END SUBROUTINE NC_READ_VAR_SP
         474             : !EOC
         475             : !------------------------------------------------------------------------------
         476             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         477             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         478             : !------------------------------------------------------------------------------
         479             : !BOP
         480             : !
         481             : ! !IROUTINE: Nc_Read_Var_Dp
         482             : !
         483             : ! !DESCRIPTION: Subroutine NC\_READ\_VAR\_DP reads the given variable from the
         484             : ! given fID and returns the corresponding variable values and units.
         485             : !\\
         486             : !\\
         487             : ! !INTERFACE:
         488             : !
         489           0 :   SUBROUTINE NC_READ_VAR_DP( fID, Var, nVar, varUnit, varVec, RC )
         490             : !
         491             : ! !INPUT PARAMETERS:
         492             : !
         493             :     INTEGER,          INTENT(IN   )            :: fID
         494             :     CHARACTER(LEN=*), INTENT(IN   )            :: var
         495             : !
         496             : ! !OUTPUT PARAMETERS:
         497             : !
         498             :     INTEGER,          INTENT(  OUT)            :: nVar
         499             :     CHARACTER(LEN=*), INTENT(  OUT)            :: varUnit
         500             :     REAL*8,           POINTER                  :: varVec(:)
         501             : !
         502             : ! !INPUT/OUTPUT PARAMETERS:
         503             : !
         504             :     INTEGER,          INTENT(INOUT)            :: RC
         505             : !
         506             : ! !REVISION HISTORY:
         507             : !  See https://github.com/geoschem/hemco for complete history
         508             : !EOP
         509             : !------------------------------------------------------------------------------
         510             : !BOC
         511             :
         512           0 :     CALL NC_READ_VAR_CORE( fID, Var, nVar, varUnit, varVecDp=varVec, RC=RC )
         513             :
         514           0 :   END SUBROUTINE NC_READ_VAR_DP
         515             : !EOC
         516             : !------------------------------------------------------------------------------
         517             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         518             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         519             : !------------------------------------------------------------------------------
         520             : !BOP
         521             : !
         522             : ! !IROUTINE: Nc_Read_Var_Core
         523             : !
         524             : ! !DESCRIPTION: Subroutine NC\_READ\_VAR\_CORE reads the given variable from the
         525             : ! given fID and returns the corresponding variable values and units.
         526             : !\\
         527             : !\\
         528             : ! !INTERFACE:
         529             : !
         530           0 :   SUBROUTINE NC_READ_VAR_CORE( fID, Var, nVar, varUnit, varVecDp, varVecSp, RC )
         531             : !
         532             : ! !INPUT PARAMETERS:
         533             : !
         534             :     INTEGER,          INTENT(IN   )            :: fID
         535             :     CHARACTER(LEN=*), INTENT(IN   )            :: var
         536             : !
         537             : ! !OUTPUT PARAMETERS:
         538             : !
         539             :     INTEGER,          INTENT(  OUT)            :: nVar
         540             :     CHARACTER(LEN=*), INTENT(  OUT)            :: varUnit
         541             :     REAL*4,           POINTER,       OPTIONAL  :: varVecSp(:)
         542             :     REAL*8,           POINTER,       OPTIONAL  :: varVecDp(:)
         543             : !
         544             : ! !INPUT/OUTPUT PARAMETERS:
         545             : !
         546             :     INTEGER,          INTENT(INOUT)            :: RC
         547             : !
         548             : ! !REVISION HISTORY:
         549             : !  See https://github.com/geoschem/hemco for complete history
         550             : !EOP
         551             : !------------------------------------------------------------------------------
         552             : !BOC
         553             : !
         554             : ! !LOCAL VARIABLES:
         555             : !
         556             :     LOGICAL                :: hasVar
         557             :     CHARACTER(LEN=255)     :: v_name             ! netCDF variable name
         558             :     CHARACTER(LEN=255)     :: a_name             ! netCDF attribute name
         559             :     CHARACTER(LEN=255)     :: a_val              ! netCDF attribute value
         560             :     INTEGER                :: a_type             ! netCDF attribute type
         561             :     INTEGER                :: st1d(1), ct1d(1)   ! For 1D arrays
         562             :     INTEGER                :: I
         563             :
         564             :     !=================================================================
         565             :     ! NC_READ_VAR_CORE begins here
         566             :     !=================================================================
         567             :
         568             :     ! Init
         569           0 :     RC      = 0
         570           0 :     nVar    = 0
         571           0 :     hasVar  = .FALSE.
         572             :
         573             :     ! Variable name
         574           0 :     v_name = var
         575             :
         576             :     ! Check if variable exists
         577           0 :     hasVar = Ncdoes_Dim_Exist ( fID, TRIM(v_name) )
         578             :
         579             :     ! Return here if variable not defined
         580           0 :     IF ( .NOT. hasVar ) RETURN
         581             :
         582             :     ! Get dimension length
         583           0 :     CALL Ncget_Dimlen ( fID, TRIM(v_name), nVar )
         584             :
         585             :     ! Read vector from file.
         586           0 :     IF ( PRESENT(VarVecSp) ) THEN
         587           0 :        IF ( ASSOCIATED( VarVecSp ) ) DEALLOCATE(VarVecSp)
         588           0 :        ALLOCATE ( VarVecSp(nVar) )
         589           0 :        st1d = (/ 1    /)
         590           0 :        ct1d = (/ nVar /)
         591           0 :        CALL NcRd( VarVecSp, fID, TRIM(v_name), st1d, ct1d )
         592             :     ENDIF
         593           0 :     IF ( PRESENT(VarVecDp) ) THEN
         594           0 :        IF ( ASSOCIATED( VarVecDp ) ) DEALLOCATE(VarVecDp)
         595           0 :        ALLOCATE ( VarVecDp(nVar) )
         596           0 :        st1d = (/ 1    /)
         597           0 :        ct1d = (/ nVar /)
         598           0 :        CALL NcRd( VarVecDp, fID, TRIM(v_name), st1d, ct1d )
         599             :     ENDIF
         600             :
         601             :     ! Read units attribute. If unit attribute does not exist, return
         602             :     ! empty string (dimensionless vertical coordinates do not require
         603             :     ! a units attribute).
         604           0 :     a_name  = "units"
         605           0 :     hasVar  = Ncdoes_Attr_Exist ( fId, TRIM(v_name), TRIM(a_name), a_type )
         606           0 :     IF ( .NOT. hasVar ) THEN
         607           0 :        varUnit = ''
         608             :     ELSE
         609             :        CALL NcGet_Var_Attributes( fID,          TRIM(v_name), &
         610           0 :                                   TRIM(a_name), varUnit     )
         611             :
         612             :        ! Check if the last character of VarUnit is the ASCII null character
         613             :        ! ("\0", ASCII value = 0), which is used to denote the end of a string.
         614             :        ! The ASCII null character may be introduced if the netCDF file was
         615             :        ! written using a language other than Fortran.  The compiler might
         616             :        ! interpret the null character as part of the string instead of as
         617             :        ! an empty space.  If the null space is there, then replace it with
         618             :        ! a Fortran empty string value (''). (bmy, 7/17/18)
         619           0 :        I = LEN_TRIM( VarUnit )
         620           0 :        IF ( ICHAR( VarUnit(I:I) ) == 0 ) THEN
         621           0 :           VarUnit(I:I) = ''
         622             :        ENDIF
         623             :     ENDIF
         624             :
         625           0 :   END SUBROUTINE NC_READ_VAR_CORE
         626             : !EOC
         627             : !------------------------------------------------------------------------------
         628             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
         629             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
         630             : !------------------------------------------------------------------------------
         631             : !BOP
         632             : !
         633             : ! !IROUTINE: Nc_Read_Arr
         634             : !
         635             : ! !DESCRIPTION: Routine NC\_READ\_ARR reads variable ncVar into a 4-D array
         636             : ! (lon,lat,lev,time). Domain boundaries can be provided by input arguments
         637             : ! lon1,lon2, lat1,lat2, lev1,lev2, and time1,time2. The level and time bounds
         638             : ! are optional and can be set to zero (lev1=0 and/or time1=0) for data with
         639             : ! undefined level/time coordinates.
         640             : !\\
         641             : !\\
         642             : ! The default behavior for time slices is to read all slices (time1:time2),
         643             : ! and pass all of them to the output array. It is also possible to assign
         644             : ! specific weights (wgt1 and wgt2) to the two time slices time1 and time2,
         645             : ! respectively. In this case, only those two slices will be read and merged
         646             : ! using the given weights. The output array will then contain only one time
         647             : ! dimension. Negative weights are currently not supported and will be ignored,
         648             : ! e.g. providing negative weights has the same effect as providing no weights
         649             : ! at all.
         650             : !\\
         651             : !\\
         652             : ! If the passed variable contains attribute names `offset` and/or
         653             : ! `scale\_factor`, those operations will be applied to the data array
         654             : ! before returning it.
         655             : !\\
         656             : !\\
         657             : ! Missing values in the netCDF file are replaced with value 'MissVal'
         658             : ! (default = 0). Currently, the routine identifies attributes 'missing\_value'
         659             : ! and '\_FillValue' as missing values.
         660             : !\\
         661             : !\\
         662             : ! !INTERFACE:
         663             : !
         664           0 :   SUBROUTINE NC_READ_ARR( fID,    ncVar,   lon1,    lon2,  lat1,  &
         665             :                           lat2,   lev1,    lev2,    time1, time2, &
         666             :                           ncArr,  VarUnit, MissVal, wgt1,  wgt2,  &
         667             :                           ArbIdx, RC                               )
         668             : !
         669             : ! !USES:
         670             : !
         671             :     USE HCO_CHARPAK_MOD, ONLY : TRANLC
         672             : !
         673             : ! !INPUT PARAMETERS:
         674             : !
         675             :     INTEGER,          INTENT(IN)            :: fID
         676             :     CHARACTER(LEN=*), INTENT(IN)            :: ncVar        ! variable to read
         677             :     INTEGER,          INTENT(IN)            :: lon1,  lon2
         678             :     INTEGER,          INTENT(IN)            :: lat1,  lat2
         679             :     INTEGER,          INTENT(IN)            :: lev1,  lev2
         680             :     INTEGER,          INTENT(IN)            :: time1, time2
         681             :     REAL*4,           INTENT(IN ), OPTIONAL :: MissVal
         682             :     REAL*4,           INTENT(IN ), OPTIONAL :: wgt1
         683             :     REAL*4,           INTENT(IN ), OPTIONAL :: wgt2
         684             :     INTEGER,          INTENT(IN ), OPTIONAL :: ArbIdx      ! Index of arbitrary additional dimension (-1 if none)
         685             : !
         686             : ! !OUTPUT PARAMETERS:
         687             : !
         688             :     ! Array to write data
         689             :     REAL*4,           POINTER               :: ncArr(:,:,:,:)
         690             :
         691             :     ! Optional output
         692             :     CHARACTER(LEN=*), INTENT(OUT), OPTIONAL :: VarUnit
         693             : !
         694             : ! !INPUT/OUTPUT PARAMETERS:
         695             : !
         696             :     ! Error handling
         697             :     INTEGER,          INTENT(INOUT)         :: RC
         698             : !
         699             : ! !REVISION HISTORY:
         700             : !  See https://github.com/geoschem/hemco for complete history
         701             : !EOP
         702             : !------------------------------------------------------------------------------
         703             : !BOC
         704             : !
         705             : ! !LOCAL VARIABLES:
         706             : !
         707             :     !=================================================================
         708             :     ! Variable declarations
         709             :     !=================================================================
         710             :
         711             :     ! Data arrays
         712             :     CHARACTER(LEN=255)     :: v_name    ! netCDF variable name
         713             :     CHARACTER(LEN=255)     :: a_name    ! netCDF attribute name
         714             :     CHARACTER(LEN=255)     :: a_val     ! netCDF attribute value
         715             :     INTEGER                :: a_type    ! netCDF attribute type
         716             :     REAL*8                 :: corr      ! netCDF attribute value
         717             :
         718             :     ! Arrays for netCDF start and count values
         719             :     INTEGER                :: I, nRead, l1, l2
         720             :     INTEGER                :: ndims
         721             :     INTEGER                :: nlon,  nlat, nlev, ntime, arbdim
         722             :     INTEGER                :: nclev, nctime
         723             :     INTEGER                :: s1, s2, s3, s4, s5
         724             :     INTEGER                :: n1, n2, n3, n4, n5
         725             :     INTEGER                :: nt, st, tdim, sti, nti
         726             :     INTEGER                :: st2d(2), ct2d(2)   ! For 2D arrays
         727             :     INTEGER                :: st3d(3), ct3d(3)   ! For 3D arrays
         728             :     INTEGER                :: st4d(4), ct4d(4)   ! For 4D arrays
         729             :     INTEGER                :: st5d(5), ct5d(5)   ! For 5D arrays
         730             :
         731             :     ! Temporary arrays
         732           0 :     REAL*4, ALLOCATABLE    :: TMPARR_5D(:,:,:,:,:)
         733           0 :     REAL*4, ALLOCATABLE    :: WGTARR_5D(:,:,:,:,:)
         734           0 :     REAL*4, ALLOCATABLE    :: TMPARR_4D(:,:,:,:)
         735           0 :     REAL*4, ALLOCATABLE    :: WGTARR_4D(:,:,:,:)
         736           0 :     REAL*4, ALLOCATABLE    :: TMPARR_3D(:,:,:)
         737           0 :     REAL*4, ALLOCATABLE    :: WGTARR_3D(:,:,:)
         738           0 :     REAL*4, ALLOCATABLE    :: TMPARR_2D(:,:)
         739             :
         740             :     ! Logicals
         741             :     LOGICAL                :: FlipZ
         742             :     LOGICAL                :: ReadAtt
         743             :
         744             :     ! Missing value
         745             :     REAL*8                 :: miss8
         746             :     REAL*4                 :: miss4
         747             :     REAL*4                 :: MissValue
         748             :
         749             :     ! Weights
         750             :     LOGICAL                :: ApplyWeights
         751             :     REAL*4                 :: weight1, weight2
         752             :
         753             :     ! For error handling
         754             :     CHARACTER(LEN=255)     :: LOC, MSG
         755             :
         756             :     !=================================================================
         757             :     ! NC_READ_ARR begins here
         758             :     !=================================================================
         759             :
         760             :     !-----------------------------------------------------------------
         761             :     ! Initialize
         762             :     !-----------------------------------------------------------------
         763             :
         764             :     ! For error handling
         765           0 :     LOC = 'NC_READ_ARR ("ncdf_mod.F")'
         766             :
         767             :     ! Eventually deallocate output array
         768           0 :     IF ( ASSOCIATED ( ncArr ) ) DEALLOCATE ( ncArr )
         769             :
         770             :     ! weights to be applied to time1 and time2 (if any):
         771           0 :     weight1 = -999.0
         772           0 :     weight2 = -999.0
         773           0 :     IF(PRESENT(wgt1)) weight1 = wgt1
         774           0 :     IF(PRESENT(wgt2)) weight2 = wgt2
         775             :
         776             :     ! apply weights?
         777           0 :     IF ( time1 > 0 .AND. weight1 >= 0.0 ) THEN
         778             :        ApplyWeights = .TRUE.
         779             :     ELSE
         780           0 :        ApplyWeights = .FALSE.
         781             :     ENDIF
         782             :
         783             :     ! # of horizontal dimensions to read
         784           0 :     nLon = lon2 - lon1 + 1
         785           0 :     nLat = lat2 - lat1 + 1
         786             :
         787             :     ! # of vertical levels
         788           0 :     FlipZ = .FALSE. ! Flip z-axis?
         789           0 :     l1    = lev1    ! Lower level to be read
         790           0 :     l2    = lev2    ! Upper level to be read
         791           0 :     IF ( lev1 > 0 ) THEN
         792             :
         793             :        ! Check if we need to flip the vertical axis
         794           0 :        IF ( lev1 > lev2 ) THEN
         795           0 :           FlipZ = .TRUE.
         796           0 :           l1    = lev2
         797           0 :           l2    = lev1
         798             :        ENDIF
         799             :
         800             :        ! Number of levels to be read
         801           0 :        nLev = l2 - l1 + 1
         802             :
         803             :     ! no vertical levels:
         804             :     ELSE
         805             :        nLev = 0
         806             :     ENDIF
         807             :
         808             :     ! # of time slices
         809             :     ! read all time slices time1:time2:
         810           0 :     IF ( time1 > 0 .AND. weight1 < 0.0 ) THEN
         811           0 :        ntime = time2 - time1 + 1
         812             :     ! Interpolate amongs 2 time slices:
         813           0 :     ELSEIF ( ApplyWeights ) THEN
         814             :        ntime = 1
         815             :     ! no time dimension:
         816             :     ELSE
         817           0 :        ntime = 0
         818             :     ENDIF
         819             :
         820             :     ! # of arbitrary other dimensions
         821           0 :     arbdim = -1
         822           0 :     IF ( PRESENT(ArbIdx) ) THEN
         823           0 :        IF ( ArbIdx > 0 ) THEN
         824           0 :           arbdim = ArbIdx
         825             :        ENDIF
         826             :     ENDIF
         827             :
         828             :     ! Set dimensions of output array
         829             :     ! --> must have at least dimension 1
         830           0 :     nclev  = max(nlev ,1)
         831           0 :     nctime = max(ntime,1)
         832             :
         833             :     ! set total number of dimensions to be read. This is at least 2 and
         834             :     ! at most 5.
         835           0 :     ndims = 2
         836           0 :     if ( nlev   > 0 ) ndims = ndims + 1
         837           0 :     if ( ntime  > 0 ) ndims = ndims + 1
         838           0 :     if ( arbdim > 0 ) ndims = ndims + 1
         839             :
         840             :     !----------------------------------------
         841             :     ! Read array
         842             :     !----------------------------------------
         843             :
         844             :     ! Variable name
         845           0 :     v_name = TRIM(ncVar)
         846             :
         847             :     ! Allocate the output array
         848           0 :     ALLOCATE ( ncArr( nLon, nLat, ncLev, ncTime ) )
         849           0 :     ncArr = 0.0
         850             :
         851             :     ! Define number of required reads and time dimension on temporary array
         852           0 :     nRead = 1
         853           0 :     IF ( ntime > 0 ) THEN
         854           0 :        IF ( ApplyWeights ) THEN
         855             :           nRead = 2
         856             :           nt    = 2
         857             :        ELSE
         858           0 :           nRead = 1
         859           0 :           nt    = ntime
         860             :        ENDIF
         861             :     ENDIF
         862             :
         863             :     !----------------------------------------
         864             :     ! Read 5D array:
         865           0 :     IF ( ndims == 5 ) THEN
         866             :
         867             :        ! Allocate array. If time weights are applied, the two
         868             :        ! time slices are read into TMPARR_5D and then temporarily
         869             :        ! stored in WGTARR_5D. Same applies to 4D and 3D below.
         870             :        ! (ckeller, 01/09/17)
         871           0 :        IF ( ApplyWeights ) THEN
         872           0 :           ALLOCATE ( TMPARR_5D( nlon, nlat, nlev, 1, 1 ) )
         873           0 :           TMPARR_5D = 0.0
         874           0 :           ALLOCATE ( WGTARR_5D( nlon, nlat, nlev, nt, 1 ) )
         875           0 :           WGTARR_5D = 0.0
         876             :        ELSE
         877           0 :           ALLOCATE ( TMPARR_5D( nlon, nlat, nlev, nt, 1 ) )
         878           0 :           TMPARR_5D = 0.0
         879             :        ENDIF
         880             :
         881             :        ! Set default start/end indeces
         882           0 :        s1 = lon1
         883           0 :        n1 = nlon
         884           0 :        s2 = lat1
         885           0 :        n2 = nlat
         886           0 :        s3 = l1
         887           0 :        n3 = nlev
         888             :        s5 = arbdim
         889             :        n5 = 1
         890             :
         891             :        ! Read arrays from file
         892           0 :        DO I = 1, nRead
         893             :
         894             :           ! time index
         895           0 :           IF ( .NOT. ApplyWeights ) THEN
         896             :              s4 = time1
         897             :              n4 = ntime
         898             :           ELSE
         899           0 :              IF ( I == 1 ) THEN
         900             :                 s4 = time1
         901             :              ELSE
         902           0 :                 s4 = time2
         903             :              ENDIF
         904             :              n4 = 1
         905             :           ENDIF
         906             :
         907           0 :           st5d = (/ s1, s2, s3, s4, s5 /)
         908           0 :           ct5d = (/ n1, n2, n3, n4, n5 /)
         909           0 :           CALL NcRd( TMPARR_5D, fId, TRIM(v_name), st5d, ct5d )
         910             :
         911             :           ! Eventually pass time weighted arrays to temporary array
         912           0 :           IF ( ApplyWeights ) THEN
         913           0 :              WGTARR_5D(:,:,:,I,:) = TMPARR_5D(:,:,:,1,:)
         914             :           ENDIF
         915             :
         916             :        ENDDO
         917             :
         918             :        ! Pass to output array. Eventually apply time weights.
         919           0 :        IF ( ApplyWeights ) THEN
         920           0 :           ncArr(:,:,:,1) = WGTARR_5D(:,:,:,1,1) * weight1 &
         921           0 :                          + WGTARR_5D(:,:,:,2,1) * weight2
         922             :        ELSE
         923           0 :           ncArr(:,:,:,:) = TMPARR_5D(:,:,:,:,1)
         924             :        ENDIF
         925             :
         926             :        ! Cleanup
         927           0 :        DEALLOCATE(TMPARR_5D)
         928           0 :        IF(ALLOCATED(WGTARR_5D)) DEALLOCATE(WGTARR_5D)
         929             :     ENDIF
         930             :
         931             :     !----------------------------------------
         932             :     ! Read 4D array:
         933             :     ! This can be:
         934             :     ! - lon,lat,lev,time
         935             :     ! - lon,lat,lev,arb
         936             :     ! - lon,lat,time,arb
         937           0 :     IF ( ndims == 4 ) THEN
         938             :
         939             :        ! Allocate temporary array
         940           0 :        s1    = lon1
         941           0 :        n1    = nlon
         942           0 :        s2    = lat1
         943           0 :        n2    = nlat
         944           0 :        tdim  = -1
         945             :
         946             :        ! 3rd and 4th dim
         947             :
         948             :        ! lev is defined
         949           0 :        IF ( nlev > 0 ) THEN
         950           0 :           s3   = l1
         951           0 :           n3   = nlev
         952             :           ! plus time...
         953           0 :           IF ( ntime > 0 ) THEN
         954             :              n4   = nt
         955             :              tdim = 4
         956             :           ! ... or plus arbitrary dim
         957             :           ELSE
         958           0 :              s4 = arbdim
         959           0 :              n4 = 1
         960             :           ENDIF
         961             :
         962             :        ! lev not defined: time + arbitrary dim
         963             :        ELSE
         964             :           n3 = nt
         965             :           tdim = 3
         966             :           s4 = arbdim
         967             :           n4 = 1
         968             :        ENDIF
         969             :
         970           0 :        IF ( ApplyWeights ) THEN
         971           0 :           ALLOCATE ( WGTARR_4D(n1,n2,n3,n4) )
         972           0 :           WGTARR_4D = 0.0
         973           0 :           IF ( tdim == 3 ) THEN
         974           0 :              ALLOCATE ( TMPARR_4D(n1,n2,1,n4) )
         975           0 :              TMPARR_4D = 0.0
         976           0 :           ELSEIF ( tdim == 4 ) THEN
         977           0 :              ALLOCATE ( TMPARR_4D(n1,n2,n3,1) )
         978           0 :              TMPARR_4D = 0.0
         979             :           ENDIF
         980             :
         981             :        ELSE
         982           0 :           ALLOCATE ( TMPARR_4D(n1,n2,n3,n4) )
         983           0 :           TMPARR_4D = 0.0
         984             :        ENDIF
         985             :
         986             :        ! Read arrays from file
         987           0 :        DO I = 1, nRead
         988             :
         989             :           ! time index
         990           0 :           IF ( .NOT. ApplyWeights ) THEN
         991             :              sti = time1
         992             :              nti = ntime
         993             :           ELSE
         994           0 :              IF ( I == 1 ) THEN
         995             :                 sti = time1
         996             :              ELSE
         997           0 :                 sti = time2
         998             :              ENDIF
         999             :              nti = 1
        1000             :           ENDIF
        1001             :
        1002             :           ! need to adjust time index: this is either 3rd or 4th dimension:
        1003           0 :           IF ( tdim == 3 ) THEN
        1004             :              s3 = sti
        1005             :              n3 = nti
        1006           0 :           ELSEIF ( tdim == 4 ) THEN
        1007           0 :              s4 = sti
        1008           0 :              n4 = nti
        1009             :           ENDIF
        1010             :
        1011           0 :           st4d = (/ s1, s2, s3, s4 /)
        1012           0 :           ct4d = (/ n1, n2, n3, n4 /)
        1013             :
        1014             :           ! Read data from disk
        1015           0 :           CALL NcRd( TMPARR_4D, fId, TRIM(v_name), st4d, ct4d )
        1016             :
        1017             :           ! Eventually pass time weighted arrays to temporary array
        1018           0 :           IF ( ApplyWeights ) THEN
        1019           0 :              IF ( tdim == 3 ) THEN
        1020           0 :                 WGTARR_4D(:,:,I,:) = TMPARR_4D(:,:,1,:)
        1021           0 :              ELSEIF ( tdim == 4 ) THEN
        1022           0 :                 WGTARR_4D(:,:,:,I) = TMPARR_4D(:,:,:,1)
        1023             :              ENDIF
        1024             :           ENDIF
        1025             :        ENDDO
        1026             :
        1027             :        ! Pass to output array. Eventually apply time weights.
        1028           0 :        IF ( ApplyWeights ) THEN
        1029           0 :           IF ( tdim == 3 ) THEN
        1030           0 :              ncArr(:,:,:,1) = WGTARR_4D(:,:,1,:) * weight1 &
        1031           0 :                             + WGTARR_4D(:,:,2,:) * weight2
        1032           0 :           ELSEIF ( tdim == 4 ) THEN
        1033           0 :              ncArr(:,:,:,1) = WGTARR_4D(:,:,:,1) * weight1 &
        1034           0 :                             + WGTARR_4D(:,:,:,2) * weight2
        1035             :           ENDIF
        1036             :        ELSE
        1037           0 :           ncArr(:,:,:,:) = TMPARR_4D(:,:,:,:)
        1038             :        ENDIF
        1039             :
        1040             :        ! Cleanup
        1041           0 :        DEALLOCATE(TMPARR_4D)
        1042           0 :        IF(ALLOCATED(WGTARR_4D)) DEALLOCATE(WGTARR_4D)
        1043             :     ENDIF
        1044             :
        1045             :     !----------------------------------------
        1046             :     ! Read 3D array:
        1047             :     ! This can be:
        1048             :     ! - lon,lat,lev
        1049             :     ! - lon,lat,time
        1050             :     ! - lon,lat,arb
        1051           0 :     IF ( ndims == 3 ) THEN
        1052             :
        1053             :        ! Allocate temporary array
        1054           0 :        s1    = lon1
        1055           0 :        n1    = nlon
        1056           0 :        s2    = lat1
        1057           0 :        n2    = nlat
        1058           0 :        tdim  = -1
        1059             :
        1060             :        ! 3rd dim:
        1061             :        ! - lev is defined:
        1062           0 :        IF ( nlev > 0 ) THEN
        1063             :           s3   = l1
        1064             :           n3   = nlev
        1065             :        ! - time is defined:
        1066           0 :        ELSEIF ( ntime > 0 ) THEN
        1067             :           n3   = nt
        1068             :           tdim = 3
        1069             :        ! - arbitrary dimension is defined:
        1070           0 :        ELSEIF ( arbdim > 0 ) THEN
        1071           0 :           s3   = arbdim
        1072           0 :           n3   = 1
        1073             :        ENDIF
        1074             :
        1075           0 :        IF ( ApplyWeights ) THEN
        1076           0 :           ALLOCATE ( TMPARR_3D(n1,n2,1) )
        1077           0 :           TMPARR_3D = 0.0
        1078           0 :           ALLOCATE ( WGTARR_3D(n1,n2,n3) )
        1079           0 :           WGTARR_3D = 0.0
        1080             :        ELSE
        1081           0 :           ALLOCATE ( TMPARR_3D(n1,n2,n3) )
        1082           0 :           TMPARR_3D = 0.0
        1083             :        ENDIF
        1084             :
        1085             :        ! Read arrays from file
        1086           0 :        DO I = 1, nRead
        1087             :
        1088             :           ! time index
        1089           0 :           IF ( tdim  == 3 ) THEN
        1090           0 :              IF ( .NOT. ApplyWeights ) THEN
        1091             :                 s3 = time1
        1092             :                 n3 = ntime
        1093             :              ELSE
        1094           0 :                 IF ( I == 1 ) THEN
        1095             :                    s3 = time1
        1096             :                 ELSE
        1097           0 :                    s3 = time2
        1098             :                 ENDIF
        1099             :                 n3 = 1
        1100             :              ENDIF
        1101             :           ENDIF
        1102             :
        1103           0 :           st3d = (/ s1, s2, s3 /)
        1104           0 :           ct3d = (/ n1, n2, n3 /)
        1105           0 :           CALL NcRd( TMPARR_3D, fId, TRIM(v_name), st3d, ct3d )
        1106             :
        1107             :           ! Eventually pass time weighted arrays to temporary array
        1108           0 :           IF ( ApplyWeights ) THEN
        1109           0 :            WGTARR_3D(:,:,I) = TMPARR_3D(:,:,1)
        1110             :           ENDIF
        1111             :
        1112             :        ENDDO
        1113             :
        1114             :        ! Pass to output array. Eventually apply time weights.
        1115           0 :        IF ( ApplyWeights ) THEN
        1116           0 :           ncArr(:,:,1,1) = WGTARR_3D(:,:,1) * weight1 &
        1117           0 :                          + WGTARR_3D(:,:,2) * weight2
        1118             :        ELSE
        1119           0 :           IF ( tdim == 3 ) THEN
        1120           0 :              ncArr(:,:,1,:) = TMPARR_3D(:,:,:)
        1121             :           ELSE
        1122           0 :              ncArr(:,:,:,1) = TMPARR_3D(:,:,:)
        1123             :           ENDIF
        1124             :        ENDIF
        1125             :
        1126             :        ! Cleanup
        1127           0 :        IF(ALLOCATED(TMPARR_3D)) DEALLOCATE(TMPARR_3D)
        1128           0 :        IF(ALLOCATED(WGTARR_3D)) DEALLOCATE(WGTARR_3D)
        1129             :     ENDIF
        1130             :
        1131             :     !----------------------------------------
        1132             :     ! Read a 2D array (lon and lat only):
        1133           0 :     IF ( ndims == 2 ) THEN
        1134           0 :        ALLOCATE ( TMPARR_2D( nLon, nLat ) )
        1135           0 :        TMPARR_2D = 0.0
        1136           0 :        st2d      = (/ lon1, lat1 /)
        1137           0 :        ct2d      = (/ nlon, nlat /)
        1138           0 :        CALL NcRd( TMPARR_2D, fId, TRIM(v_name), st2d, ct2d )
        1139           0 :        ncArr(:,:,1,1) = TMPARR_2D(:,:)
        1140           0 :        DEALLOCATE(TMPARR_2D)
        1141             :     ENDIF
        1142             :
        1143             :     ! ------------------------------------------
        1144             :     ! Eventually apply scale / offset factors
        1145             :     ! ------------------------------------------
        1146             :
        1147             :     ! Check for scale factor
        1148           0 :     a_name  = "scale_factor"
        1149           0 :     ReadAtt = Ncdoes_Attr_Exist ( fId, TRIM(v_name), TRIM(a_name), a_type )
        1150             :
        1151           0 :     IF ( ReadAtt ) THEN
        1152           0 :        CALL NcGet_Var_Attributes(fId,TRIM(v_name),TRIM(a_name),corr)
        1153           0 :        ncArr(:,:,:,:) = ncArr(:,:,:,:) * corr
        1154             :     ENDIF
        1155             :
        1156             :     ! Check for offset factor
        1157           0 :     a_name  = "add_offset"
        1158           0 :     ReadAtt = Ncdoes_Attr_Exist ( fId, TRIM(v_name), TRIM(a_name), a_type )
        1159             :
        1160           0 :     IF ( ReadAtt ) THEN
        1161           0 :        CALL NcGet_Var_Attributes(fId,TRIM(v_name),TRIM(a_name),corr)
        1162           0 :        ncArr(:,:,:,:) = ncArr(:,:,:,:) + corr
        1163             :     ENDIF
        1164             :
        1165             :     ! ------------------------------------------
        1166             :     ! Check for filling values
        1167             :     ! NOTE: Test for REAL*4 and REAL*8
        1168             :     ! ------------------------------------------
        1169             :
        1170             :     ! Define missing value
        1171           0 :     IF ( PRESENT(MissVal) ) THEN
        1172           0 :        MissValue = MissVal
        1173             :     ELSE
        1174             :        MissValue = 0.0
        1175             :     ENDIF
        1176             :
        1177             :     ! 1: 'missing_value'
        1178           0 :     a_name  = "missing_value"
        1179           0 :     ReadAtt = Ncdoes_Attr_Exist ( fId, TRIM(v_name), TRIM(a_name), a_type )
        1180           0 :     IF ( ReadAtt ) THEN
        1181           0 :        IF ( a_type == NF90_REAL ) THEN
        1182           0 :           CALL NcGet_Var_Attributes( fId, TRIM(v_name), TRIM(a_name), miss4 )
        1183           0 :           WHERE ( ncArr == miss4 )
        1184             :              ncArr = MissValue
        1185             :           END WHERE
        1186           0 :        ELSE IF ( a_type == NF90_DOUBLE ) THEN
        1187           0 :           CALL NcGet_Var_Attributes( fId, TRIM(v_name), TRIM(a_name), miss8 )
        1188           0 :           miss4 = REAL( miss8 )
        1189           0 :           WHERE ( ncArr == miss4 )
        1190             :              ncArr = MissValue
        1191             :           END WHERE
        1192             :        ENDIF
        1193             :     ENDIF
        1194             :
        1195             :     ! 2: '_FillValue'
        1196           0 :     a_name  = "_FillValue"
        1197           0 :     ReadAtt = Ncdoes_Attr_Exist ( fId, TRIM(v_name), TRIM(a_name), a_type )
        1198           0 :     IF ( ReadAtt ) THEN
        1199           0 :        IF ( a_type == NF90_REAL ) THEN
        1200           0 :           CALL NcGet_Var_Attributes( fId, TRIM(v_name), TRIM(a_name), miss4 )
        1201           0 :           WHERE ( ncArr == miss4 )
        1202             :              ncArr = MissValue
        1203             :           END WHERE
        1204           0 :        ELSE IF ( a_type == NF90_DOUBLE ) THEN
        1205           0 :           CALL NcGet_Var_Attributes( fId, TRIM(v_name), TRIM(a_name), miss8 )
        1206           0 :           miss4 = REAL( miss8 )
        1207           0 :           WHERE ( ncArr == miss4 )
        1208             :              ncArr = MissValue
        1209             :           END WHERE
        1210             :        ENDIF
        1211             :     ENDIF
        1212             :
        1213             :     ! ------------------------------------------
        1214             :     ! Flip z-axis if needed
        1215             :     ! ------------------------------------------
        1216           0 :     IF ( FlipZ ) THEN
        1217           0 :        ncArr(:,:,:,:) = ncArr(:,:,ncLev:1:-1,:)
        1218             :     ENDIF
        1219             :
        1220             :     ! ----------------------------
        1221             :     ! Read optional arguments
        1222             :     ! ----------------------------
        1223             :
        1224             :     ! Read units
        1225           0 :     IF ( PRESENT(VarUnit) )THEN
        1226           0 :        a_name = "units"
        1227           0 :        CALL NcGet_Var_Attributes(fId,TRIM(v_name),TRIM(a_name),a_val)
        1228           0 :        VarUnit = TRIM(a_val)
        1229             :
        1230             :        ! Check if the last character of VarUnit is the ASCII null character
        1231             :        ! ("\0", ASCII value = 0), which is used to denote the end of a string.
        1232             :        ! The ASCII null character may be introduced if the netCDF file was
        1233             :        ! written using a language other than Fortran.  The compiler might
        1234             :        ! interpret the null character as part of the string instead of as
        1235             :        ! an empty space.  If the null space is there, then replace it with
        1236             :        ! a Fortran empty string value (''). (bmy, 7/17/18)
        1237           0 :        I = LEN_TRIM( VarUnit )
        1238           0 :        IF ( ICHAR( VarUnit(I:I) ) == 0 ) THEN
        1239           0 :           VarUnit(I:I) = ''
        1240             :        ENDIF
        1241             :     ENDIF
        1242             :
        1243             :     !=================================================================
        1244             :     ! Cleanup and quit
        1245             :     !=================================================================
        1246             :
        1247             :     ! Return w/ success
        1248           0 :     RC = 0
        1249             :
        1250           0 :   END SUBROUTINE NC_READ_ARR
        1251             : !EOC
        1252             : !------------------------------------------------------------------------------
        1253             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        1254             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        1255             : !------------------------------------------------------------------------------
        1256             : !BOP
        1257             : !
        1258             : ! !IROUTINE: Nc_Read_Time_yyyymmddhhmm
        1259             : !
        1260             : ! !DESCRIPTION: Returns a vector containing the datetimes (YYYYMMDDhhmm) of
        1261             : ! all time slices in the netCDF file.
        1262             : !\\
        1263             : ! !INTERFACE:
        1264             : !
        1265           0 :   SUBROUTINE NC_READ_TIME_YYYYMMDDhhmm( fID,              nTime,    &
        1266             :                                         all_YYYYMMDDhhmm, timeUnit, &
        1267             :                                         refYear,          RC )
        1268             : !
        1269             : ! !USES:
        1270             : !
        1271             :     USE HCO_JULDAY_MOD, ONLY : JULDAY, CALDATE
        1272             : !
        1273             : ! !INPUT PARAMETERS:
        1274             : !
        1275             :     INTEGER,          INTENT(IN   )           :: fID
        1276             : !
        1277             : ! !INPUT/OUTPUT PARAMETERS:
        1278             : !
        1279             :     REAL*8,           POINTER                 :: all_YYYYMMDDhhmm(:)
        1280             :     CHARACTER(LEN=*), INTENT(  OUT), OPTIONAL :: timeUnit
        1281             :     INTEGER,          INTENT(  OUT), OPTIONAL :: refYear
        1282             : !
        1283             : ! !INPUT/OUTPUT PARAMETERS:
        1284             : !
        1285             :     INTEGER,          INTENT(INOUT)           :: nTime
        1286             :     INTEGER,          INTENT(INOUT)           :: RC
        1287             : !
        1288             : ! !REVISION HISTORY:
        1289             : !  See https://github.com/geoschem/hemco for complete history
        1290             : !EOP
        1291             : !------------------------------------------------------------------------------
        1292             : !BOC
        1293             : !
        1294             : ! !LOCAL VARIABLES:
        1295             : !
        1296             :     ! Scalars
        1297             :     CHARACTER(LEN=255)  :: ncUnit, cal
        1298             :     INTEGER             :: refYr, refMt, refDy, refHr, refMn, refSc
        1299             :     INTEGER             :: T, YYYYMMDD, hhmmss
        1300             :     REAL*8              :: realrefDy, refJulday, tJulday
        1301             :
        1302             :     ! Pointers
        1303           0 :     REAL*8,   POINTER   :: tVec(:)
        1304             :
        1305             :     !=================================================================
        1306             :     ! NC_READ_TIME_YYYYMMDDhhmm begins here
        1307             :     !=================================================================
        1308             :
        1309             :     ! Init values
        1310           0 :     RC = 0
        1311           0 :     tVec => NULL()
        1312           0 :     IF ( PRESENT(TimeUnit) ) TimeUnit = ''
        1313           0 :     IF ( PRESENT(refYear ) ) refYear  = 0
        1314             :
        1315             :     ! Read time vector
        1316             :     CALL NC_READ_TIME ( fID,          nTime,            ncUnit,              &
        1317           0 :                         timeVec=tVec, timeCalendar=cal, RC=RC               )
        1318           0 :     IF ( RC/=0 ) THEN
        1319           0 :        WRITE( 6, '(/,a)' ) REPEAT( '=', 79 )
        1320           0 :        WRITE( 6, '(a)'   ) 'Error encountered in NC_READ_TIME (ncdf_mod.F90)'
        1321           0 :        WRITE( 6, '(a,/)' ) REPEAT( '=', 79 )
        1322           0 :        RETURN
        1323             :     ENDIF
        1324             :
        1325             :     ! If nTime is zero, return here!
        1326           0 :     IF ( nTime == 0 ) RETURN
        1327             :
        1328             :     ! Get reference date in julian days
        1329             :     CALL NC_GET_REFDATETIME ( ncUnit, refYr, refMt, &
        1330           0 :                               refDy,  refHr, refMn, refSc, RC )
        1331           0 :     IF ( RC /= 0 ) RETURN
        1332             :     realrefDy =         refDy              &
        1333             :               + ( MAX(0,refHr) / 24d0    ) &
        1334             :               + ( MAX(0,refMn) / 1440d0  ) &
        1335           0 :               + ( MAX(0,refSc) / 86400d0 )
        1336           0 :     refJulday = JULDAY ( refYr, refMt, realrefDy )
        1337             :
        1338             :     ! NOTE: It seems that there is an issue with reference dates
        1339             :     ! between 1800 and 1901: the respective time stamps all seem to
        1340             :     ! be off by one day (this problem doesn't appear for netCDF files
        1341             :     ! with reference date zero, i.e. hours since 1-1-1)!
        1342             :     ! I'm not sure what causes this problem, but adding one day to
        1343             :     ! reference dates that lie between 1600 and 1900 seems to fix the
        1344             :     ! problem.
        1345             :     ! TODO: requires more testing!
        1346           0 :     IF ( refYr <= 1900 .AND. refYr >= 1600 ) THEN
        1347           0 :        refJulday = refJulday + 1.0
        1348             :        !PRINT *, 'Reference julian day increased by one day!!!'
        1349             :     ENDIF
        1350             :
        1351             :     ! Get calendar dates
        1352           0 :     IF ( ASSOCIATED ( all_YYYYMMDDhhmm ) ) DEALLOCATE( all_YYYYMMDDhhmm )
        1353           0 :     ALLOCATE( all_YYYYMMDDhhmm(nTime) )
        1354           0 :     all_YYYYMMDDhhmm = 0.0d0
        1355             :
        1356             :     ! Construct julian date for every available time slice. Make sure it is
        1357             :     ! in the proper 'units', e.g. in days, hours or minutes, depending on
        1358             :     ! the reference unit.
        1359           0 :     DO T = 1, nTime
        1360           0 :        tJulDay = tVec(T)
        1361           0 :        IF ( refHr >= 0 ) tJulday = tJulday / 24.d0
        1362           0 :        IF ( refMn >= 0 ) tJulday = tJulday / 60.d0
        1363           0 :        IF ( refSc >= 0 ) tJulday = tJulday / 60.d0
        1364           0 :        tJulday = tJulday + refJulday
        1365           0 :        CALL CALDATE ( tJulday, YYYYMMDD, hhmmss )
        1366           0 :        all_YYYYMMDDhhmm(T) = ( DBLE( YYYYMMDD ) * 1d4   ) + &
        1367           0 :                              ( DBLE( hhmmss     / 100 ) )
        1368             :     ENDDO
        1369             :
        1370             :     ! Cleanup
        1371           0 :     IF ( ASSOCIATED( tVec ) ) DEALLOCATE( tVec )
        1372             :
        1373             :     ! Return
        1374           0 :     IF ( PRESENT(timeUnit) ) timeUnit = ncUnit
        1375           0 :     IF ( PRESENT(refYear ) ) refYear  = refYr
        1376           0 :     RC = 0
        1377             :
        1378           0 :   END SUBROUTINE NC_READ_TIME_YYYYMMDDhhmm
        1379             : !EOC
        1380             : !------------------------------------------------------------------------------
        1381             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        1382             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        1383             : !------------------------------------------------------------------------------
        1384             : !BOP
        1385             : !
        1386             : ! !IROUTINE: Nc_Get_RefDateTime
        1387             : !
        1388             : ! !DESCRIPTION: Returns the reference datetime (tYr / tMt / tDy / tHr /
        1389             : ! tMn ) of the provided time unit. For now, supported formats are
        1390             : ! "days since YYYY-MM-DD", "hours since YYYY-MM-DD HH:MM:SS", and
        1391             : ! "minutes since YYYY-MM-DD HH:NN:SS". For times in days since refdate,
        1392             : ! the returned reference hour rHr is set to -1. The same applies for the
        1393             : ! reference minute for units in days / hours since XXX.
        1394             : !\\
        1395             : ! !INTERFACE:
        1396             : !
        1397           0 :   SUBROUTINE NC_GET_REFDATETIME( tUnit, tYr, tMt, tDy, tHr, tMn, tSc, RC )
        1398             : !
        1399             : ! !USES:
        1400             : !
        1401             :     USE HCO_CHARPAK_MOD, ONLY : TRANLC
        1402             : !
        1403             : ! !INPUT PARAMETERS:
        1404             : !
        1405             :     ! Required
        1406             :     CHARACTER(LEN=*), INTENT( IN)    :: tUnit
        1407             : !
        1408             : ! !OUTPUT PARAMETERS:
        1409             : !
        1410             :     INTEGER,          INTENT(OUT)    :: tYr
        1411             :     INTEGER,          INTENT(OUT)    :: tMt
        1412             :     INTEGER,          INTENT(OUT)    :: tDy
        1413             :     INTEGER,          INTENT(OUT)    :: tHr
        1414             :     INTEGER,          INTENT(OUT)    :: tMn
        1415             :     INTEGER,          INTENT(OUT)    :: tSc
        1416             : !
        1417             : ! !INPUT/OUTPUT PARAMETERS:
        1418             : !
        1419             :     INTEGER,          INTENT(INOUT)  :: RC
        1420             : !
        1421             : ! !REMARKS:
        1422             : !
        1423             : ! !REVISION HISTORY:
        1424             : !  See https://github.com/geoschem/hemco for complete history
        1425             : !EOP
        1426             : !------------------------------------------------------------------------------
        1427             : !BOC
        1428             : !
        1429             : ! !LOCAL VARIABLES:
        1430             : !
        1431             :     CHARACTER(LEN=255)    :: LOC, MSG
        1432             :     CHARACTER(LEN=255)    :: MIRRUNIT
        1433             :     INTEGER               :: TTYPE, STAT, L1, L2
        1434             :     INTEGER               :: MINLEN, STRLEN, I
        1435             :
        1436             :     !=================================================================
        1437             :     ! NC_GET_REFDATETIME starts here
        1438             :     !=================================================================
        1439             :
        1440             :     ! Init
        1441           0 :     LOC = 'NC_GET_REFDATETIME (ncdf_mod.F)'
        1442             :
        1443             :     ! ----------------------------------------------------------------------
        1444             :     ! Determine time unit type
        1445             :     ! ----------------------------------------------------------------------
        1446             :
        1447             :     ! Mirror time unit and convert to lower case
        1448           0 :     MIRRUNIT = tUnit
        1449           0 :     CALL TRANLC( MIRRUNIT )
        1450             :
        1451             :     ! Check for reference time unit '(days, hours, minutes) since ...'
        1452             :     ! Set beginning of reference date according to the unit and define
        1453             :     ! minimum string length required by unit.
        1454             :
        1455             :     ! 'days since YYYY-M-D'
        1456           0 :     IF ( MIRRUNIT(1:10) == 'days since' ) THEN
        1457             :        TTYPE  = 1
        1458             :        L1     = 12
        1459             :        MINLEN = 19
        1460             :
        1461             :     ! 'hours since YYYY-M-D h:m:s'
        1462           0 :     ELSEIF ( MIRRUNIT(1:11) == 'hours since' ) THEN
        1463             :        TTYPE  = 2
        1464             :        L1     = 13
        1465             :        MINLEN = 26
        1466             :
        1467             :     ! 'minutes since YYYY-M-D h:m:s'
        1468           0 :     ELSEIF ( MIRRUNIT(1:13) == 'minutes since' ) THEN
        1469             :        TTYPE  = 3
        1470             :        L1     = 15
        1471             :        MINLEN = 28
        1472             :
        1473             :     ! 'seconds since YYYY-M-D h:m:s'
        1474           0 :     ELSEIF ( MIRRUNIT(1:13) == 'seconds since' ) THEN
        1475             :        TTYPE  = 4
        1476             :        L1     = 15
        1477             :        MINLEN = 28
        1478             :
        1479             :     ! Return w/ error otherwise
        1480             :     ELSE
        1481           0 :        PRINT *, 'Invalid time unit: ' // TRIM(tUnit)
        1482           0 :        RC = -999; RETURN
        1483             :     ENDIF
        1484             :
        1485             :     ! Check if time string is long enough or not
        1486           0 :     STRLEN = LEN(tUnit)
        1487           0 :     IF ( STRLEN < MINLEN ) THEN
        1488           0 :        PRINT *, 'Time unit string too short: ' // TRIM(tUnit)
        1489           0 :        RC = -999; RETURN
        1490             :     ENDIF
        1491             :
        1492             :     ! ----------------------------------------------------------------------
        1493             :     ! Determine reference time/date
        1494             :     ! Get the year, month, day and hour from the string
        1495             :     ! '... since YYYY-MM-DD hh:mm:ss
        1496             :
        1497             :     ! Read reference year, i.e. from beginning of date string until
        1498             :     ! first separator sign (-).
        1499           0 :     DO I=L1,STRLEN
        1500           0 :        IF(tUnit(I:I) == '-') EXIT
        1501             :     ENDDO
        1502           0 :     L2 = I-1
        1503             :
        1504           0 :     READ( tUnit(L1:L2),'(i4)', IOSTAT=STAT ) tYr
        1505           0 :     IF ( STAT /= 0 ) THEN
        1506           0 :        PRINT *, 'Invalid year in ' // TRIM(tUnit)
        1507           0 :        RC = -999; RETURN
        1508             :     ENDIF
        1509             :
        1510             :     ! Advance in date string: now read reference month.
        1511           0 :     L1 = L2 + 2
        1512           0 :     DO I=L1,STRLEN
        1513           0 :        IF(tUnit(I:I) == '-') EXIT
        1514             :     ENDDO
        1515           0 :     L2 = I-1
        1516           0 :     READ( tUnit(L1:L2), '(i2)', IOSTAT=STAT ) tMt
        1517           0 :     IF ( STAT /= 0 ) THEN
        1518           0 :        PRINT *, 'Invalid month in ' // TRIM(tUnit)
        1519           0 :        RC = -999; RETURN
        1520             :     ENDIF
        1521             :
        1522             :     ! Advance in date string: now read reference day.
        1523           0 :     L1 = L2 + 2
        1524           0 :     DO I=L1,STRLEN
        1525           0 :        IF(tUnit(I:I) == ' ') EXIT
        1526             :     ENDDO
        1527           0 :     L2 = I-1
        1528           0 :     READ( tUnit(L1:L2), '(i2)', IOSTAT=STAT ) tDy
        1529           0 :     IF ( STAT /= 0 ) THEN
        1530           0 :        PRINT *, 'Invalid day in ' // TRIM(tUnit)
        1531           0 :        RC = -999; RETURN
        1532             :     ENDIF
        1533             :
        1534             :     ! Get reference hour only if 'hours/minutes/seconds since'.
        1535           0 :     IF ( TTYPE > 1 ) THEN
        1536             :
        1537             :        ! Reference hour
        1538           0 :        L1 = L2 + 2
        1539           0 :        DO I=L1,STRLEN
        1540           0 :           IF(tUnit(I:I) == ':') EXIT
        1541             :        ENDDO
        1542           0 :        L2 = I-1
        1543           0 :        READ( tUnit(L1:L2), '(i2)', IOSTAT=STAT ) tHr
        1544           0 :        IF ( STAT /= 0 ) THEN
        1545           0 :           PRINT *, 'Invalid hour in ', TRIM(tUnit)
        1546           0 :           RC = -999; RETURN
        1547             :        ENDIF
        1548             :
        1549             :     ELSE
        1550             :        ! Set reference hour to -1
        1551           0 :        tHr = -1
        1552             :     ENDIF
        1553             :
        1554             :     ! Get reference minute only if 'minutes since...'
        1555           0 :     IF ( TTYPE>2 ) THEN
        1556             :
        1557             :        ! Reference minute
        1558           0 :        L1 = L2 + 2
        1559           0 :        DO I=L1,STRLEN
        1560           0 :           IF(tUnit(I:I) == ':') EXIT
        1561             :        ENDDO
        1562           0 :        L2 = I-1
        1563           0 :        READ( tUnit(L1:L2), '(i2)', IOSTAT=STAT ) tMn
        1564           0 :        IF ( STAT /= 0 ) THEN
        1565           0 :           PRINT *, 'Invalid minute in ', TRIM(tUnit)
        1566           0 :           RC = -999; RETURN
        1567             :        ENDIF
        1568             :
        1569             :     ELSE
        1570             :        ! Set reference minute to -1
        1571           0 :        tMn = -1
        1572             :     ENDIF
        1573             :
        1574             :     ! Get reference minute only if 'seconds since...'
        1575           0 :     IF ( TTYPE>3 ) THEN
        1576             :
        1577             :        ! Reference second
        1578           0 :        L1 = L2 + 2
        1579           0 :        DO I=L1,STRLEN
        1580           0 :           IF(tUnit(I:I) == ':') EXIT
        1581             :        ENDDO
        1582           0 :        L2 = I-1
        1583           0 :        READ( tUnit(L1:L2), '(i2)', IOSTAT=STAT ) tSc
        1584           0 :        IF ( STAT /= 0 ) THEN
        1585           0 :           PRINT *, 'Invalid second in ', TRIM(tUnit)
        1586           0 :           RC = -999; RETURN
        1587             :        ENDIF
        1588             :
        1589             :     ELSE
        1590             :        ! Set reference second to -1
        1591           0 :        tSc = -1
        1592             :     ENDIF
        1593             :
        1594             :     ! Return w/ success
        1595           0 :     RC = 0
        1596             :
        1597           0 :   END SUBROUTINE NC_GET_REFDATETIME
        1598             : !EOC
        1599             : !------------------------------------------------------------------------------
        1600             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        1601             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        1602             : !------------------------------------------------------------------------------
        1603             : !BOP
        1604             : !
        1605             : ! !IROUTINE: Get_Tidx
        1606             : !
        1607             : ! !DESCRIPTION: Routine GET\_TIDX returns the index with the specified time
        1608             : ! for a given time vector.
        1609             : !\\
        1610             : !\\
        1611             : ! !INTERFACE:
        1612             : !
        1613             :   SUBROUTINE GET_TIDX( TDIM, TIMEVEC,  TTYPE, TOFFSET, &
        1614             :                        YEAR, MONTH,    DAY,   HOUR,    &
        1615             :                        TIDX, TDIMREAD, RC )
        1616             : !
        1617             : ! !INPUT PARAMETERS:
        1618             : !
        1619             :     ! Required
        1620             :     INTEGER, INTENT(   IN)           :: TDIM
        1621             :     INTEGER, INTENT(   IN)           :: TTYPE
        1622             :     REAL*8,  INTENT(   IN)           :: TOFFSET
        1623             : !
        1624             : ! !INPUT/OUTPUT PARAMETERS:
        1625             : !
        1626             :     INTEGER, INTENT(INOUT)           :: TIMEVEC(TDIM)
        1627             :     INTEGER, INTENT(INOUT)           :: YEAR
        1628             :     INTEGER, INTENT(INOUT)           :: MONTH
        1629             :     INTEGER, INTENT(INOUT)           :: DAY
        1630             :     INTEGER, INTENT(INOUT)           :: HOUR
        1631             :     INTEGER, INTENT(INOUT)           :: RC
        1632             : !
        1633             : ! !OUTPUT PARAMETERS:
        1634             : !
        1635             :     INTEGER, INTENT(  OUT)           :: TIDX
        1636             :     INTEGER, INTENT(  OUT)           :: TDIMREAD
        1637             : !
        1638             : ! !REMARKS:
        1639             : !
        1640             : ! !REVISION HISTORY:
        1641             : !  See https://github.com/geoschem/hemco for complete history
        1642             : !EOP
        1643             : !------------------------------------------------------------------------------
        1644             : !BOC
        1645             : !
        1646             : ! !LOCAL VARIABLES:
        1647             : !
        1648             :     INTEGER                :: II, iiDiff, minDiff
        1649             :     REAL*8                 :: TAU
        1650             :     CHARACTER(LEN=255)     :: MSG, LOC
        1651             :
        1652             :     !=================================================================
        1653             :     ! GET_TIDX starts here
        1654             :     !=================================================================
        1655             :
        1656             :     ! Init
        1657             :     LOC = 'GET_TIDX (ncdf_mod.F)'
        1658             :     TIDX = 0
        1659             :     minDiff = -999
        1660             :
        1661             :     !-----------------------------------------------------------------
        1662             :     ! If year is given, compare netcdf-tau against desired tau
        1663             :     !-----------------------------------------------------------------
        1664             :     IF ( YEAR > 0 ) THEN
        1665             :
        1666             :        ! Restrict month, day and hour to valid values
        1667             :        MONTH = MIN ( MAX( 1, MONTH ), 12 )
        1668             :        DAY   = MIN ( MAX( 1, DAY   ), 31 )
        1669             :        HOUR  = MIN ( MAX( 0, HOUR  ), 23 )
        1670             :
        1671             :        ! Read desired tau => hours relative to G-C reference time
        1672             :        TAU = GET_TAU0( MONTH, DAY, YEAR, HOUR )
        1673             :
        1674             :        ! Convert to 'hours since ...' if unit is 'days since ...'
        1675             :        IF ( TTYPE == 2 ) THEN
        1676             :           TIMEVEC(:) = TIMEVEC(:) * 24
        1677             :        ENDIF
        1678             :
        1679             :        ! Convert time stamps to hours since G-C reference time
        1680             :        TIMEVEC(:) = TIMEVEC(:) + INT(TOFFSET)
        1681             :
        1682             :        ! Compare wanted tau to tau's of ncdf-file.
        1683             :        ! Loop over all time stamps and check which one is closest
        1684             :        ! to the specified one. Print a warning if time stamps don't
        1685             :        ! match!
        1686             :        DO II = 1, TDIM
        1687             :
        1688             :           ! Difference between time stamps
        1689             :           iiDiff = ABS( TIMEVEC(II) - INT(TAU) )
        1690             :
        1691             :           ! Check if this is closest time stamp so far, and save this
        1692             :           ! index and difference
        1693             :           IF ( iiDiff < minDiff .OR. II == 1 ) THEN
        1694             :              minDiff = iiDiff
        1695             :              TIDX    = II
        1696             :           ENDIF
        1697             :
        1698             :           ! Exit loop if difference is zero
        1699             :           IF ( minDiff == 0 ) EXIT
        1700             :
        1701             :        ENDDO
        1702             :
        1703             :        ! Warning if time stamps did not match
        1704             :        IF ( minDiff /= 0 ) THEN
        1705             :           PRINT *, 'In NCDF_MOD: Time stamp not found ' // &
        1706             :                    'take closest timestamp!'
        1707             :        ENDIF
        1708             :
        1709             :        ! Set number of time stamps to be read to 1
        1710             :        TDIMREAD = 1
        1711             :
        1712             :     !-----------------------------------------------------------------
        1713             :     ! If only month is given, assume netCDF file to contain monthly
        1714             :     ! data and pick the desired month.
        1715             :     !-----------------------------------------------------------------
        1716             :     ELSEIF ( MONTH > 0 ) THEN
        1717             :
        1718             :        ! Check if it's indeed monthly data:
        1719             :        IF ( TDIM /= 12 ) THEN
        1720             :           PRINT *, 'Array is not monthly '
        1721             :           RC = -999; RETURN
        1722             :        ENDIF
        1723             :
        1724             :        ! Set time index to specified month
        1725             :        TIDX = MONTH
        1726             :
        1727             :        ! Set number of time stamps to be read to 1
        1728             :        TDIMREAD = 1
        1729             :
        1730             :     !-----------------------------------------------------------------
        1731             :     ! If hour is given, assume netCDF file to contain hourly data
        1732             :     ! and pick the desired hour.
        1733             :     !-----------------------------------------------------------------
        1734             :     ELSEIF ( HOUR >= 0 ) THEN
        1735             :
        1736             :        ! Check if it's indeed hourly data:
        1737             :        IF ( TDIM /= 24 ) THEN
        1738             :           PRINT *, 'Array is not hourly'
        1739             :           RC = -999; RETURN
        1740             :        ENDIF
        1741             :
        1742             :        ! Set time index to specified hour (+1 since hour 0 is idx 1)
        1743             :        TIDX = HOUR + 1
        1744             :
        1745             :        ! Set number of time stamps to be read to 1
        1746             :        TDIMREAD = 1
        1747             :
        1748             :     !-----------------------------------------------------------------
        1749             :     ! Otherwise, read all time dimensions
        1750             :     !-----------------------------------------------------------------
        1751             :     ELSE
        1752             :        TIDX     = 1
        1753             :        TDIMREAD = TDIM
        1754             :     ENDIF
        1755             :
        1756             :     ! Return w/ success
        1757             :     RC = 0
        1758             :
        1759             :   END SUBROUTINE GET_TIDX
        1760             : !EOC
        1761             : !------------------------------------------------------------------------------
        1762             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        1763             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        1764             : !------------------------------------------------------------------------------
        1765             : !BOP
        1766             : !
        1767             : ! !IROUTINE: TimeUnit_Check
        1768             : !
        1769             : ! !DESCRIPTION: Makes a validity check of the passed unit string.
        1770             : ! Supported formats are "days since YYYY-MM-DD" (TIMETYPE=1) and
        1771             : ! "hours since YYYY-MM-DD HH:MM:SS" (TIMETYPE=2).
        1772             : !\\
        1773             : !\\
        1774             : ! The output argument TOFFSET gives the offset of the ncdf reference
        1775             : ! time relative to Geos-Chem reference time (in hours).
        1776             : !\\
        1777             : !\\
        1778             : ! !INTERFACE:
        1779             : !
        1780             :   SUBROUTINE TIMEUNIT_CHECK( TIMEUNIT, TIMETYPE, TOFFSET, FILENAME, RC )
        1781             : !
        1782             : ! !USES:
        1783             : !
        1784             :     USE HCO_CHARPAK_MOD, ONLY : TRANLC
        1785             : !
        1786             : ! !INPUT PARAMETERS:
        1787             : !
        1788             :     ! Required
        1789             :     CHARACTER(LEN=*), INTENT(IN  )  :: TIMEUNIT
        1790             :     CHARACTER(LEN=*), INTENT(IN  )  :: FILENAME
        1791             : !
        1792             : ! !OUTPUT PARAMETERS:
        1793             : !
        1794             :     INTEGER,          INTENT(  OUT) :: TIMETYPE
        1795             :     REAL*8,           INTENT(  OUT) :: TOFFSET
        1796             : !
        1797             : ! !INPUT/OUTPUT PARAMETERS:
        1798             : !
        1799             :     INTEGER,          INTENT(INOUT) :: RC
        1800             : !
        1801             : ! !REMARKS:
        1802             : !
        1803             : ! !REVISION HISTORY:
        1804             : !  See https://github.com/geoschem/hemco for complete history
        1805             : !EOP
        1806             : !------------------------------------------------------------------------------
        1807             : !BOC
        1808             : !
        1809             : ! !LOCAL VARIABLES:
        1810             : !
        1811             :     CHARACTER(LEN=255)    :: LOC, MSG
        1812             :     CHARACTER(LEN=255)    :: MIRRUNIT
        1813             :     INTEGER               :: STAT, L1, L2
        1814             :     INTEGER               :: TTYPE
        1815             :     INTEGER               :: YYYY, MM, DD, HH
        1816             :     INTEGER               :: STRLEN
        1817             :
        1818             :     !=================================================================
        1819             :     ! TIMEUNIT_CHECK starts here
        1820             :     !=================================================================
        1821             :
        1822             :     ! Init
        1823             :     LOC = 'TIMEUNIT_CHECK (ncdf_mod.F)'
        1824             :
        1825             :     ! Check length of time unit string. This must be at least 21
        1826             :     ! ("days since YYYY:MM:DD" is of length 21)
        1827             :     STRLEN = LEN(TIMEUNIT)
        1828             :     IF ( STRLEN < 21 ) THEN
        1829             :        PRINT *, 'Time unit string too short: ' // TRIM(FILENAME)
        1830             :        RC = -999; RETURN
        1831             :     ENDIF
        1832             :
        1833             :     ! ----------------------------------------------------------------------
        1834             :     ! Determine time unit type
        1835             :     ! ----------------------------------------------------------------------
        1836             :
        1837             :     ! Mirror time unit and convert to lower case
        1838             :     MIRRUNIT = TIMEUNIT
        1839             :     CALL TRANLC( MIRRUNIT )
        1840             :
        1841             :     ! Check for 'hours since'. If true, set TTYPE to 1 and set the
        1842             :     ! begin of the effective date string to 12. Also check if the time
        1843             :     ! string is at least of length 25, which is required for this
        1844             :     ! unit.
        1845             :     IF ( MIRRUNIT(1:11) == 'hours since' ) THEN
        1846             :        TTYPE = 1
        1847             :        L1    = 13
        1848             :        IF ( STRLEN < 25 ) THEN
        1849             :           PRINT *, 'Time unit string too short: ' // TRIM(FILENAME)
        1850             :           RC = -999; RETURN
        1851             :        ENDIF
        1852             :
        1853             :     ! Check for 'days since'. If true, set TTYPE to 2 and set the
        1854             :     ! begin of the effective date string to 11.
        1855             :     ELSEIF ( MIRRUNIT(1:10) == 'days since' ) THEN
        1856             :        TTYPE = 2
        1857             :        L1    = 12
        1858             :     ELSE
        1859             :        ! Return w/ error
        1860             :        PRINT *, 'Invalid time unit in', TRIM(FILENAME)
        1861             :        RC = -999; RETURN
        1862             :     ENDIF
        1863             :
        1864             :     ! ----------------------------------------------------------------------
        1865             :     ! Determine reference time/date
        1866             :     ! Get the year, month, day and hour from the string
        1867             :     ! '... since YYYY-MM-DD hh:mm:ss
        1868             :     ! ----------------------------------------------------------------------
        1869             :
        1870             :     ! Read reference year, i.e. first four integers
        1871             :     L2 = L1 + 3
        1872             :     READ( TIMEUNIT(L1:L2),'(i4)', IOSTAT=STAT ) YYYY
        1873             :     IF ( STAT /= 0 ) THEN
        1874             :        PRINT *, 'Invalid year in ', TRIM(TIMEUNIT), &
        1875             :             ' in file'             , TRIM(FILENAME)
        1876             :        RC = -999; RETURN
        1877             :     ENDIF
        1878             :
        1879             :     ! Read reference month. Typically, the month is represented by
        1880             :     ! two characters, i.e. 1 is 01, etc.
        1881             :     L1 = L2 + 2
        1882             :     L2 = L1 + 1
        1883             :     READ( TIMEUNIT(L1:L2), '(i2)', IOSTAT=STAT ) MM
        1884             :     ! Also check for the case where the month is only one character:
        1885             :     IF ( STAT /= 0 ) THEN
        1886             :        L2 = L1
        1887             :        READ( TIMEUNIT(L1:L2), '(i2)', IOSTAT=STAT ) MM
        1888             :        IF ( STAT /= 0 ) THEN
        1889             :           PRINT *, 'Invalid month in ', TRIM(TIMEUNIT), &
        1890             :                    ' in file'         , TRIM(FILENAME)
        1891             :           RC = -999; RETURN
        1892             :        ENDIF
        1893             :     ENDIF
        1894             :
        1895             :     ! Reference day. Typically, the day is represented by two
        1896             :     ! characters, i.e. 1 is 01, etc.
        1897             :     L1 = L2 + 2
        1898             :     L2 = L1 + 1
        1899             :     READ( TIMEUNIT(L1:L2), '(i2)', IOSTAT=STAT ) DD
        1900             :     ! Also check for the case where the day is only one character:
        1901             :     IF ( STAT /= 0 ) THEN
        1902             :        L2 = L1
        1903             :        READ( TIMEUNIT(L1:L2), '(i2)', IOSTAT=STAT ) DD
        1904             :        IF ( STAT /= 0 ) THEN
        1905             :           PRINT *, 'Invalid day in ', TRIM(TIMEUNIT), &
        1906             :                    ' in file'       , TRIM(FILENAME)
        1907             :           RC = -999; RETURN
        1908             :        ENDIF
        1909             :     ENDIF
        1910             :
        1911             :     ! Get reference hour only if 'hours since...'
        1912             :     IF ( TTYPE == 1 ) THEN
        1913             :
        1914             :        ! Reference hour
        1915             :        L1 = L2 + 2
        1916             :        L2 = L1 + 1
        1917             :        READ( TIMEUNIT(L1:L2), '(i2)', IOSTAT=STAT ) HH
        1918             :        IF ( STAT /= 0 ) THEN
        1919             :           L2 = L1
        1920             :           READ( TIMEUNIT(L1:L2), '(i2)', IOSTAT=STAT ) HH
        1921             :           IF ( STAT /= 0 ) THEN
        1922             :              PRINT *, 'Invalid hour in ', TRIM(TIMEUNIT), &
        1923             :                       ' in file'            , TRIM(FILENAME)
        1924             :              RC = -999; RETURN
        1925             :           ENDIF
        1926             :        ENDIF
        1927             :
        1928             :     ELSE
        1929             :        ! Set reference hour to 0
        1930             :        HH = 0
        1931             :
        1932             :     ENDIF
        1933             :
        1934             :     ! Get reference tau relative to G-C reference time, i.e. the
        1935             :     ! offset of the netCDF reference time to the G-C reference time.
        1936             :     ! This is hours since G-C reftime.
        1937             :     TOFFSET = GET_TAU0( MM, DD, YYYY, HH )
        1938             :
        1939             :     ! Remove one day if TOFFSET is negative, i.e. if the netCDF
        1940             :     ! reference time is older than G-C reference time. We have to do
        1941             :     ! this because GET_TAU0 does count the last day in this case!
        1942             :     IF ( TOFFSET < 0d0 ) THEN
        1943             :        TOFFSET = TOFFSET + 24d0
        1944             :     ENDIF
        1945             :
        1946             :     ! Output argument
        1947             :     TIMETYPE = TTYPE
        1948             :
        1949             :     ! Return w/ success
        1950             :     RC = 0
        1951             :
        1952             :   END SUBROUTINE TIMEUNIT_CHECK
        1953             : !EOC
        1954             : !------------------------------------------------------------------------------
        1955             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        1956             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        1957             : !------------------------------------------------------------------------------
        1958             : !BOP
        1959             : !
        1960             : ! !IROUTINE: Nc_Get_Grid_Edges_Sp
        1961             : !
        1962             : ! !DESCRIPTION: Routine to get the longitude or latitude edges. If the edge
        1963             : ! cannot be read from the netCDF file, they are calculated from the provided
        1964             : ! grid midpoints. Use the axis input argument to discern between longitude
        1965             : ! (axis 1) and latitude (axis 2).
        1966             : !\\
        1967             : !\\
        1968             : ! !INTERFACE:
        1969             : !
        1970           0 :   SUBROUTINE NC_GET_GRID_EDGES_SP( fID, AXIS, MID, NMID, EDGE, NEDGE, RC )
        1971             : !
        1972             : ! !USES:
        1973             : !
        1974             :     IMPLICIT NONE
        1975             : !
        1976             : ! !INPUT PARAMETERS:
        1977             : !
        1978             :     INTEGER,          INTENT(IN   ) :: fID             ! Ncdf File ID
        1979             :     INTEGER,          INTENT(IN   ) :: AXIS            ! 1=lon, 2=lat
        1980             :     INTEGER,          INTENT(IN   ) :: NMID            ! # of midpoints
        1981             :     REAL*4,           INTENT(IN   ) :: MID(NMID)       ! midpoints
        1982             : !
        1983             : ! !INPUT/OUTPUT PARAMETERS:
        1984             : !
        1985             :     REAL*4,           POINTER       :: EDGE(:)         ! edges
        1986             :     INTEGER,          INTENT(INOUT) :: NEDGE           ! # of edges
        1987             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        1988             : !
        1989             : ! !REVISION HISTORY:
        1990             : !  See https://github.com/geoschem/hemco for complete history
        1991             : !EOP
        1992             : !------------------------------------------------------------------------------
        1993             : !BOC
        1994             :
        1995             :     !======================================================================
        1996             :     ! NC_GET_GRID_EDGES_SP begins here
        1997             :     !======================================================================
        1998             :
        1999             :     CALL NC_GET_GRID_EDGES_C( fID, AXIS, NMID, NEDGE, RC, &
        2000           0 :                               MID4=MID,  EDGE4=EDGE )
        2001             :
        2002           0 :   END SUBROUTINE NC_GET_GRID_EDGES_SP
        2003             : !EOC
        2004             : !------------------------------------------------------------------------------
        2005             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2006             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2007             : !------------------------------------------------------------------------------
        2008             : !BOP
        2009             : !
        2010             : ! !IROUTINE: Nc_Get_Grid_Edges_Dp
        2011             : !
        2012             : ! !DESCRIPTION: Routine to get the longitude or latitude edges. If the edge
        2013             : ! cannot be read from the netCDF file, they are calculated from the provided
        2014             : ! grid midpoints. Use the axis input argument to discern between longitude
        2015             : ! (axis 1) and latitude (axis 2).
        2016             : !\\
        2017             : !\\
        2018             : ! !INTERFACE:
        2019             : !
        2020           0 :   SUBROUTINE NC_GET_GRID_EDGES_DP( fID, AXIS, MID, NMID, EDGE, NEDGE, RC )
        2021             : !
        2022             : ! !USES:
        2023             : !
        2024             :     IMPLICIT NONE
        2025             : !
        2026             : ! !INPUT PARAMETERS:
        2027             : !
        2028             :     INTEGER,          INTENT(IN   ) :: fID             ! Ncdf File ID
        2029             :     INTEGER,          INTENT(IN   ) :: AXIS            ! 1=lon, 2=lat
        2030             :     INTEGER,          INTENT(IN   ) :: NMID            ! # of midpoints
        2031             :     REAL*8,           INTENT(IN   ) :: MID(NMID)       ! midpoints
        2032             : !
        2033             : ! !INPUT/OUTPUT PARAMETERS:
        2034             : !
        2035             :     REAL*8,           POINTER       :: EDGE(:)         ! edges
        2036             :     INTEGER,          INTENT(INOUT) :: NEDGE           ! # of edges
        2037             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        2038             : !
        2039             : ! !REVISION HISTORY:
        2040             : !  See https://github.com/geoschem/hemco for complete history
        2041             : !EOP
        2042             : !------------------------------------------------------------------------------
        2043             : !BOC
        2044             :
        2045             :     !======================================================================
        2046             :     ! NC_GET_GRID_EDGES_DP begins here
        2047             :     !======================================================================
        2048             :
        2049             :     CALL NC_GET_GRID_EDGES_C( fID, AXIS, NMID, NEDGE, RC, &
        2050           0 :                               MID8=MID,  EDGE8=EDGE )
        2051             :
        2052           0 :   END SUBROUTINE NC_GET_GRID_EDGES_DP
        2053             : !EOC
        2054             : !------------------------------------------------------------------------------
        2055             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2056             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2057             : !------------------------------------------------------------------------------
        2058             : !BOP
        2059             : !
        2060             : ! !IROUTINE: Nc_Get_Grid_Edges_C
        2061             : !
        2062             : ! !DESCRIPTION: Routine to get the longitude or latitude edges. If the edge
        2063             : ! cannot be read from the netCDF file, they are calculated from the provided
        2064             : ! grid midpoints. Use the axis input argument to discern between longitude
        2065             : ! (axis 1) and latitude (axis 2).
        2066             : !\\
        2067             : !\\
        2068             : ! !INTERFACE:
        2069             : !
        2070           0 :   SUBROUTINE NC_GET_GRID_EDGES_C( fID, AXIS, NMID, NEDGE, RC, &
        2071           0 :                                   MID4, MID8, EDGE4, EDGE8 )
        2072             : !
        2073             : ! !INPUT PARAMETERS:
        2074             : !
        2075             :     INTEGER,          INTENT(IN   ) :: fID             ! Ncdf File ID
        2076             :     INTEGER,          INTENT(IN   ) :: AXIS            ! 1=lon, 2=lat
        2077             :     INTEGER,          INTENT(IN   ) :: NMID            ! # of midpoints
        2078             :     REAL*4, OPTIONAL, INTENT(IN   ) :: MID4(NMID)       ! midpoints
        2079             :     REAL*8, OPTIONAL, INTENT(IN   ) :: MID8(NMID)       ! midpoints
        2080             : !
        2081             : ! !INPUT/OUTPUT PARAMETERS:
        2082             : !
        2083             :     REAL*4, OPTIONAL, POINTER       :: EDGE4(:)         ! edges
        2084             :     REAL*8, OPTIONAL, POINTER       :: EDGE8(:)         ! edges
        2085             :     INTEGER,          INTENT(INOUT) :: NEDGE           ! # of edges
        2086             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        2087             : !
        2088             : ! !REVISION HISTORY:
        2089             : !  See https://github.com/geoschem/hemco for complete history
        2090             : !EOP
        2091             : !------------------------------------------------------------------------------
        2092             : !BOC
        2093             : !
        2094             : ! !LOCAL VARIABLES:
        2095             : !
        2096             :     LOGICAL              :: PoleMid
        2097             :     INTEGER              :: I, AS
        2098             :     CHARACTER(LEN=255)   :: ncVar, ThisUnit
        2099             :
        2100             :     !======================================================================
        2101             :     ! NC_GET_GRID_EDGES_DP begins here
        2102             :     !======================================================================
        2103             :
        2104             :     ! Error trap: edge and mid must be same kind
        2105           0 :     IF ( PRESENT(EDGE4) ) THEN
        2106           0 :        IF ( .NOT. PRESENT(MID4) ) THEN
        2107           0 :           PRINT *, 'If you provide EDGE4, you must also provide MID4'
        2108           0 :           RC = -999
        2109           0 :           RETURN
        2110             :        ENDIF
        2111           0 :     ELSEIF ( PRESENT(EDGE8) ) THEN
        2112           0 :        IF ( .NOT. PRESENT(MID8) ) THEN
        2113           0 :           PRINT *, 'If you provide EDGE8, you must also provide MID8'
        2114           0 :           RC = -999
        2115           0 :           RETURN
        2116             :        ENDIF
        2117             :     ELSE
        2118           0 :        PRINT *, 'EDGE4 or EDGE8 must be given'
        2119           0 :        RC = -999
        2120           0 :        RETURN
        2121             :     ENDIF
        2122             :
        2123             :     ! Try to read edges from ncdf file
        2124           0 :     IF ( AXIS == 1 ) THEN
        2125           0 :        ncVar = 'lon_edge'
        2126           0 :     ELSEIF ( AXIS == 2 ) THEN
        2127           0 :        ncVar = 'lat_edge'
        2128             :     ENDIF
        2129             :
        2130           0 :     IF ( PRESENT(EDGE4) ) THEN
        2131           0 :        CALL NC_READ_VAR( fID, TRIM(ncVar), nEdge, ThisUnit, Edge4, RC )
        2132             :     ELSE
        2133           0 :        CALL NC_READ_VAR( fID, TRIM(ncVar), nEdge, ThisUnit, Edge8, RC )
        2134             :     ENDIF
        2135           0 :     IF ( RC /= 0 ) RETURN
        2136             :
        2137             :     ! Also try 'XXX_edges'
        2138           0 :     IF ( nEdge == 0 ) THEN
        2139           0 :        IF ( AXIS == 1 ) THEN
        2140           0 :           ncVar = 'lon_edges'
        2141           0 :        ELSEIF ( AXIS == 2 ) THEN
        2142           0 :           ncVar = 'lat_edges'
        2143             :        ENDIF
        2144           0 :        IF ( PRESENT(EDGE4) ) THEN
        2145           0 :           CALL NC_READ_VAR( fID, 'lon_edges', nEdge, ThisUnit, Edge4, RC )
        2146             :        ELSE
        2147           0 :           CALL NC_READ_VAR( fID, 'lon_edges', nEdge, ThisUnit, Edge8, RC )
        2148             :        ENDIF
        2149           0 :        IF ( RC /= 0 ) RETURN
        2150             :     ENDIF
        2151             :
        2152             :     ! Sanity check if edges are read from files: dimension must be nlon + 1!
        2153           0 :     IF ( nEdge > 0 ) THEN
        2154           0 :        IF ( nEdge /= (nMid + 1) ) THEN
        2155           0 :           PRINT *, 'Edge has incorrect length!'
        2156           0 :           RC = -999; RETURN
        2157             :        ENDIF
        2158             :
        2159             :     ! If not read from file, calculate from provided lon midpoints.
        2160             :     ELSE
        2161             :
        2162           0 :        nEdge = nMid + 1
        2163           0 :        IF ( PRESENT(EDGE4) ) THEN
        2164           0 :           IF ( ASSOCIATED ( Edge4 ) ) DEALLOCATE( Edge4 )
        2165           0 :           ALLOCATE ( Edge4(nEdge), STAT=AS )
        2166           0 :           IF ( AS /= 0 ) THEN
        2167           0 :              PRINT *, 'Edge alloc. error in NC_GET_LON_EDGES (ncdf_mod.F90)'
        2168           0 :              RC = -999; RETURN
        2169             :           ENDIF
        2170           0 :           Edge4 = 0.0
        2171             :        ELSE
        2172           0 :           IF ( ASSOCIATED ( Edge8 ) ) DEALLOCATE( Edge8 )
        2173           0 :           ALLOCATE ( Edge8(nEdge), STAT=AS )
        2174             :           IF ( AS /= 0 ) THEN
        2175           0 :              PRINT *, 'Edge alloc. error in NC_GET_LON_EDGES (ncdf_mod.F90)'
        2176           0 :              RC = -999; RETURN
        2177             :           ENDIF
        2178           0 :           Edge8 = 0.0d0
        2179             :        ENDIF
        2180             :
        2181             :        ! Get leftmost edge by extrapolating from first two midpoints.
        2182             :        ! Error trap: for latitude axis, first edge must not be below -90!
        2183           0 :        IF ( PRESENT(EDGE4) ) THEN
        2184           0 :           Edge4(1) = Mid4(1) - ( (Mid4(2) - Mid4(1) ) / 2.0 )
        2185           0 :           IF ( Edge4(1) < -90.0 .AND. AXIS == 2 ) Edge4(1) = -90.0
        2186             :        ELSE
        2187           0 :           Edge8(1) = Mid8(1) - ( (Mid8(2) - Mid8(1) ) / 2.0d0 )
        2188           0 :           IF ( Edge8(1) < -90.0d0 .AND. AXIS == 2 ) Edge8(1) = -90.0d0
        2189             :        ENDIF
        2190             :
        2191             :        ! Calculate second edge. We need to catch the case where the first
        2192             :        ! latitude mid-point is -90 (this is the case for GEOS-5 generic
        2193             :        ! grids...). In that case, the second edge is put in the middle of
        2194             :        ! the first two mid points (e.g. between -90 and -89). In all other
        2195             :        ! case, we calculate it from the previously calculated left edge.
        2196             :        IF ( PRESENT(EDGE4) ) THEN
        2197           0 :           IF ( Mid4(1) == Edge4(1) ) THEN
        2198           0 :              Edge4(2) = Mid4(1) + ( Mid4(2) - Mid4(1) ) / 2.0
        2199           0 :              PoleMid  = .TRUE.
        2200             :           ELSE
        2201           0 :              Edge4(2) = Mid4(1) + Mid4(1) - Edge4(1)
        2202           0 :              PoleMid  = .FALSE.
        2203             :           ENDIF
        2204             :
        2205             :           ! Sequentially calculate the right edge from the previously
        2206             :           ! calculated left edge.
        2207           0 :           DO I = 2, nMid
        2208           0 :              Edge4(I+1) = Mid4(I) + Mid4(I) - Edge4(I)
        2209             :           ENDDO
        2210             :
        2211             :           ! Error check: max. lat edge must not exceed +90!
        2212           0 :           IF ( Edge4(nMId+1) > 90.01 .AND. AXIS == 2 ) THEN
        2213           0 :              IF ( PoleMid ) THEN
        2214           0 :                 Edge4(nMid+1) = 90.0
        2215             :              ELSE
        2216           0 :                 PRINT *, 'Uppermost latitude edge above 90 deg north!'
        2217           0 :                 PRINT *, Edge4
        2218           0 :                 RC = -999; RETURN
        2219             :              ENDIF
        2220             :           ENDIF
        2221             :
        2222             :        ! Real8
        2223             :        ELSE
        2224           0 :           IF ( Mid8(1) == Edge8(1) ) THEN
        2225           0 :              Edge8(2) = Mid8(1) + ( Mid8(2) - Mid8(1) ) / 2.0d0
        2226           0 :              PoleMid  = .TRUE.
        2227             :           ELSE
        2228           0 :              Edge8(2) = Mid8(1) + Mid8(1) - Edge8(1)
        2229           0 :              PoleMid  = .FALSE.
        2230             :           ENDIF
        2231             :
        2232             :           ! Sequentially calculate the right edge from the previously
        2233             :           ! calculated left edge.
        2234           0 :           DO I = 2, nMid
        2235           0 :              Edge8(I+1) = Mid8(I) + Mid8(I) - Edge8(I)
        2236             :           ENDDO
        2237             :
        2238             :           ! Error check: max. lat edge must not exceed +90!
        2239           0 :           IF ( Edge8(nMId+1) > 90.01d0 .AND. AXIS == 2 ) THEN
        2240           0 :              IF ( PoleMid ) THEN
        2241           0 :                 Edge8(nMid+1) = 90.0d0
        2242             :              ELSE
        2243           0 :                 PRINT *, 'Uppermost latitude edge above 90 deg north!'
        2244           0 :                 PRINT *, Edge8
        2245           0 :                 RC = -999; RETURN
        2246             :              ENDIF
        2247             :           ENDIF
        2248             :        ENDIF
        2249             :     ENDIF
        2250             :
        2251             :     ! Return w/ success
        2252           0 :     RC = 0
        2253             :
        2254           0 :   END SUBROUTINE NC_GET_GRID_EDGES_C
        2255             : !EOC
        2256             : !------------------------------------------------------------------------------
        2257             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2258             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2259             : !------------------------------------------------------------------------------
        2260             : !BOP
        2261             : !
        2262             : ! !IROUTINE: Nc_Get_Sigma_Levels_Sp
        2263             : !
        2264             : ! !DESCRIPTION: Wrapper routine to get the sigma levels in single precision.
        2265             : !\\
        2266             : !\\
        2267             : ! !INTERFACE:
        2268             : !
        2269           0 :   SUBROUTINE NC_GET_SIGMA_LEVELS_SP( fID,  ncFile, levName, lon1, lon2, lat1, &
        2270             :                                      lat2, lev1,   lev2,    time, SigLev, dir, RC )
        2271             : !
        2272             : ! !INPUT PARAMETERS:
        2273             : !
        2274             :     INTEGER,          INTENT(IN   ) :: fID             ! Ncdf File ID
        2275             :     CHARACTER(LEN=*), INTENT(IN   ) :: ncFile          ! ncFile
        2276             :     CHARACTER(LEN=*), INTENT(IN   ) :: levName         ! variable name
        2277             :     INTEGER,          INTENT(IN   ) :: lon1            ! lon lower bound
        2278             :     INTEGER,          INTENT(IN   ) :: lon2            ! lon upper bound
        2279             :     INTEGER,          INTENT(IN   ) :: lat1            ! lat lower bound
        2280             :     INTEGER,          INTENT(IN   ) :: lat2            ! lat upper bound
        2281             :     INTEGER,          INTENT(IN   ) :: lev1            ! lev lower bound
        2282             :     INTEGER,          INTENT(IN   ) :: lev2            ! lev upper bound
        2283             :     INTEGER,          INTENT(IN   ) :: time            ! time index
        2284             : !
        2285             : ! !INPUT/OUTPUT PARAMETERS:
        2286             : !
        2287             :     REAL*4,           POINTER       :: SigLev(:,:,:)   ! sigma levels
        2288             :     INTEGER,          INTENT(INOUT) :: dir             ! axis direction (1=up;-1=down)
        2289             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        2290             : !
        2291             : ! !REVISION HISTORY:
        2292             : !  See https://github.com/geoschem/hemco for complete history
        2293             : !EOP
        2294             : !------------------------------------------------------------------------------
        2295             : !BOC
        2296             :
        2297             :   CALL NC_GET_SIGMA_LEVELS_C( fID,  ncFile, levName, lon1, lon2, lat1, &
        2298             :                               lat2, lev1,   lev2,    time, dir,  RC,   &
        2299           0 :                               SigLev4=SigLev )
        2300             :
        2301           0 :   END SUBROUTINE NC_GET_SIGMA_LEVELS_SP
        2302             : !EOC
        2303             : !------------------------------------------------------------------------------
        2304             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2305             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2306             : !------------------------------------------------------------------------------
        2307             : !BOP
        2308             : !
        2309             : ! !IROUTINE: Nc_Get_Sigma_Levels_Dp
        2310             : !
        2311             : ! !DESCRIPTION: Wrapper routine to get the sigma levels in double precision.
        2312             : !\\
        2313             : !\\
        2314             : ! !INTERFACE:
        2315             : !
        2316           0 :   SUBROUTINE NC_GET_SIGMA_LEVELS_DP( fID,  ncFile, levName, lon1, lon2, lat1, &
        2317             :                                      lat2, lev1,   lev2,    time, SigLev, dir, RC )
        2318             : !
        2319             : ! !INPUT PARAMETERS:
        2320             : !
        2321             :     INTEGER,          INTENT(IN   ) :: fID             ! Ncdf File ID
        2322             :     CHARACTER(LEN=*), INTENT(IN   ) :: ncFile          ! ncFile
        2323             :     CHARACTER(LEN=*), INTENT(IN   ) :: levName         ! variable name
        2324             :     INTEGER,          INTENT(IN   ) :: lon1            ! lon lower bound
        2325             :     INTEGER,          INTENT(IN   ) :: lon2            ! lon upper bound
        2326             :     INTEGER,          INTENT(IN   ) :: lat1            ! lat lower bound
        2327             :     INTEGER,          INTENT(IN   ) :: lat2            ! lat upper bound
        2328             :     INTEGER,          INTENT(IN   ) :: lev1            ! lev lower bound
        2329             :     INTEGER,          INTENT(IN   ) :: lev2            ! lev upper bound
        2330             :     INTEGER,          INTENT(IN   ) :: time            ! time index
        2331             : !
        2332             : ! !INPUT/OUTPUT PARAMETERS:
        2333             : !
        2334             :     REAL*8,           POINTER       :: SigLev(:,:,:)   ! sigma levels
        2335             :     INTEGER,          INTENT(INOUT) :: dir             ! axis direction (1=up;-1=down)
        2336             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        2337             : !
        2338             : ! !REVISION HISTORY:
        2339             : !  See https://github.com/geoschem/hemco for complete history
        2340             : !EOP
        2341             : !------------------------------------------------------------------------------
        2342             : !BOC
        2343             :
        2344             :   CALL NC_GET_SIGMA_LEVELS_C( fID,  ncFile, levName, lon1, lon2, lat1, &
        2345             :                               lat2, lev1,   lev2,    time, dir,  RC,   &
        2346           0 :                               SigLev8=SigLev )
        2347             :
        2348           0 :   END SUBROUTINE NC_GET_SIGMA_LEVELS_DP
        2349             : !EOC
        2350             : !------------------------------------------------------------------------------
        2351             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2352             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2353             : !------------------------------------------------------------------------------
        2354             : !BOP
        2355             : !
        2356             : ! !IROUTINE: Nc_Get_Sigma_Levels_C
        2357             : !
        2358             : ! !DESCRIPTION: Routine to get the sigma levels from the netCDF file
        2359             : ! within the given grid bounds and for the given time index. This routine
        2360             : ! attempts to construct the 3D sigma values from provided variable levName.
        2361             : ! The vertical coordinate system is determined based upon the variable
        2362             : ! attribute "standard\_name".
        2363             : !\\
        2364             : !\\
        2365             : ! For now, only hybrid sigma coordinate systems are supported, and the
        2366             : ! standard\_name attribute must follow CF conventions and be set to
        2367             : ! "atmosphere\_hybrid\_sigma\_pressure\_coordinate".
        2368             : !\\
        2369             : !\\
        2370             : ! !INTERFACE:
        2371             : !
        2372           0 :   SUBROUTINE NC_GET_SIGMA_LEVELS_C( fID,  ncFile, levName, lon1, lon2, lat1, &
        2373             :                                     lat2, lev1,   lev2,    time, dir,  RC,   &
        2374             :                                     SigLev4, SigLev8 )
        2375             : !
        2376             : ! !INPUT PARAMETERS:
        2377             : !
        2378             :     INTEGER,          INTENT(IN   ) :: fID             ! Ncdf File ID
        2379             :     CHARACTER(LEN=*), INTENT(IN   ) :: ncFile          ! ncFile
        2380             :     CHARACTER(LEN=*), INTENT(IN   ) :: levName         ! variable name
        2381             :     INTEGER,          INTENT(IN   ) :: lon1            ! lon lower bound
        2382             :     INTEGER,          INTENT(IN   ) :: lon2            ! lon upper bound
        2383             :     INTEGER,          INTENT(IN   ) :: lat1            ! lat lower bound
        2384             :     INTEGER,          INTENT(IN   ) :: lat2            ! lat upper bound
        2385             :     INTEGER,          INTENT(IN   ) :: lev1            ! lev lower bound
        2386             :     INTEGER,          INTENT(IN   ) :: lev2            ! lev upper bound
        2387             :     INTEGER,          INTENT(IN   ) :: time            ! time index
        2388             : !
        2389             : ! !INPUT/OUTPUT PARAMETERS:
        2390             : !
        2391             :     INTEGER,          INTENT(  OUT) :: dir             ! axis direction (1=up;-1=down)
        2392             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        2393             :     REAL*4, OPTIONAL, POINTER       :: SigLev4(:,:,:)  ! sigma levels w/in
        2394             :     REAL*8, OPTIONAL, POINTER       :: SigLev8(:,:,:)  ! specified boundaries
        2395             : !
        2396             : ! !REVISION HISTORY:
        2397             : !  See https://github.com/geoschem/hemco for complete history
        2398             : !EOP
        2399             : !------------------------------------------------------------------------------
        2400             : !BOC
        2401             : !
        2402             : ! !LOCAL VARIABLES:
        2403             : !
        2404             :     ! Scalars
        2405             :     LOGICAL            :: found
        2406             :     INTEGER            :: a_type    ! netCDF attribute type
        2407             :
        2408             :     ! Straings
        2409             :     CHARACTER(LEN=255) :: stdname
        2410             :     CHARACTER(LEN=255) :: a_name    ! netCDF attribute name
        2411             :     CHARACTER(LEN=255) :: a_val     ! netCDF attribute value
        2412             :
        2413             :     !========================================================================
        2414             :     ! NC_GET_SIGMA_LEVELS begins here
        2415             :     !========================================================================
        2416             :
        2417             :     ! Initialize
        2418           0 :     RC = 0
        2419             :
        2420             :     !------------------------------------------------------------------------
        2421             :     ! Test that the level index variable exists
        2422             :     !------------------------------------------------------------------------
        2423           0 :     found = Ncdoes_Var_Exist( fID, TRIM(levName) )
        2424           0 :     IF ( .not. found ) THEN
        2425           0 :        WRITE(*,*) 'Cannot find level variable ',                             &
        2426           0 :                   TRIM(levName), ' in ', TRIM(ncFile), '!'
        2427           0 :        RC = -999
        2428           0 :        RETURN
        2429             :     ENDIF
        2430             :
        2431             :     !------------------------------------------------------------------------
        2432             :     ! Look for the "standard_name" or "long_name" attribute,
        2433             :     ! which will be used to identify the vertical coordinate
        2434             :     !------------------------------------------------------------------------
        2435             :
        2436             :     ! First look for "standard_name"
        2437           0 :     a_name = "standard_name"
        2438           0 :     found  = NcDoes_Attr_Exist( fId, TRIM(levName), TRIM(a_name), a_type )
        2439             :
        2440             :     ! If not found, then look for "long_name"
        2441           0 :     IF ( .not. found ) THEN
        2442           0 :        a_name = "long_name"
        2443           0 :        found  = NcDoes_Attr_Exist( fId, TRIM(levName), TRIM(a_name), a_type )
        2444             :
        2445             :        ! If neither attribute is found, then exit with error
        2446           0 :        IF ( .not. found ) THEN
        2447           0 :           WRITE(*,*) 'Cannot find level attribute ', TRIM(a_name),           &
        2448           0 :                ' in variable ', TRIM(levName), ' - File: ', TRIM(ncFile), '!'
        2449           0 :           RC = -999
        2450           0 :           RETURN
        2451             :        ENDIF
        2452             :     ENDIF
        2453             :
        2454             :     ! Read the "standard_name" or "long_name" attribute (whichever is found)
        2455           0 :     CALL NcGet_Var_Attributes( fID, TRIM(levName), TRIM(a_name), a_val )
        2456             :
        2457             :     !------------------------------------------------------------------------
        2458             :     ! Call functions to calculate sigma levels depending on the coordinate
        2459             :     ! system.
        2460             :     !------------------------------------------------------------------------
        2461           0 :     IF ( TRIM(a_val) == 'atmosphere_hybrid_sigma_pressure_coordinate' ) THEN
        2462             :
        2463           0 :        IF ( PRESENT( SigLev4 ) ) THEN
        2464             :
        2465             :           ! Return 4-byte real array
        2466             :           CALL NC_GET_SIG_FROM_HYBRID( fID,  levName, lon1, lon2,            &
        2467             :                                        lat1, lat2,    lev1, lev2,            &
        2468           0 :                                        time, dir,     RC,   SigLev4=SigLev4 )
        2469           0 :        ELSE IF ( PRESENT( SigLev8 ) ) THEN
        2470             :
        2471             :           ! Return 8-byte real array
        2472             :           CALL NC_GET_SIG_FROM_HYBRID( fID,  levName, lon1, lon2,            &
        2473             :                                        lat1, lat2,    lev1, lev2,            &
        2474           0 :                                        time,  dir,    RC,   SigLev8=SigLev8 )
        2475             :        ELSE
        2476             :
        2477             :           ! Othrwise exit with error
        2478           0 :           WRITE(*,*) 'SigLev array is missing!'
        2479           0 :           RC = -999
        2480           0 :           RETURN
        2481             :        ENDIF
        2482           0 :        IF ( RC /= 0 ) RETURN
        2483             :
        2484             :     ELSE
        2485             :
        2486             :        ! NOTE: for now, only hybrid sigma coordinates are supported!
        2487             :        ! So exit with error if we get this far
        2488           0 :        WRITE(*,*) 'Invalid level standard name: ', TRIM(stdname),            &
        2489           0 :             ' in ', TRIM(ncFile)
        2490           0 :        RC = -999
        2491           0 :        RETURN
        2492             :     ENDIF
        2493             :
        2494             :     ! Return w/ success
        2495           0 :     RC = 0
        2496             :
        2497             :   END SUBROUTINE NC_GET_SIGMA_LEVELS_C
        2498             : !EOC
        2499             : !------------------------------------------------------------------------------
        2500             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2501             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2502             : !------------------------------------------------------------------------------
        2503             : !BOP
        2504             : !
        2505             : ! !IROUTINE: Nc_Get_Sig_From_Hybrid
        2506             : !
        2507             : ! !DESCRIPTION: Calculates the sigma level field for a hybrid sigma coordinate
        2508             : ! system:
        2509             : !
        2510             : ! sigma(i,j,l,t) = ( a(l) * p0 + b(l) * ps(i,j,t) ) / ps(i,j,t)
        2511             : !
        2512             : ! or (p0=1):
        2513             : !
        2514             : ! sigma(i,j,l,t) = ( ap(l) + b(l) * ps(i,j,t) ) / ps(i,j,t)
        2515             : !
        2516             : ! where sigma are the sigma levels, ap and bp are the hybrid sigma coordinates,
        2517             : ! p0 is the constant reference pressure, and ps is the surface pressure. The
        2518             : ! variable names of ap, p0, bp, and ps are taken from level attribute
        2519             : ! `formula\_terms`.
        2520             : !\\
        2521             : !\\
        2522             : ! The direction of the vertical coordinate system is determined from attribute
        2523             : ! `positive` (up or down) or - if not found - from the b values, whereby it is
        2524             : ! assumed that the higher b value is found at the surface. The return argument
        2525             : ! dir is set to 1 for upward coordinates (level 1 is surface level) and -1 for
        2526             : ! downward coordinates (level 1 is top of atmosphere).
        2527             : !\\
        2528             : !\\
        2529             : ! !REMARKS:
        2530             : ! Example of valid netCDF meta-data: The attributes `standard\_name` and
        2531             : ! `formula\_terms` are required, as is the 3D surface pressure field.
        2532             : !
        2533             : ! double lev(lev) ;\\
        2534             : !        lev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ;\\
        2535             : !        lev:units = "level" ;\\
        2536             : !        lev:positive = "down" ;\\
        2537             : !        lev:formula_terms = "ap: hyam b: hybm ps: PS" ;\\
        2538             : ! double hyam(nhym) ;\\
        2539             : !        hyam:long_name = "hybrid A coefficient at layer midpoints" ;\\
        2540             : !        hyam:units = "hPa" ;\\
        2541             : ! double hybm(nhym) ;\\
        2542             : !        hybm:long_name = "hybrid B coefficient at layer midpoints" ;\\
        2543             : !        hybm:units = "1" ;\\
        2544             : ! double time(time) ;\\
        2545             : !        time:standard_name = "time" ;\\
        2546             : !        time:units = "days since 2000-01-01 00:00:00" ;\\
        2547             : !        time:calendar = "standard" ;\\
        2548             : ! double PS(time, lat, lon) ;\\
        2549             : !        PS:long_name = "surface pressure" ;\\
        2550             : !        PS:units = "hPa" ;\\
        2551             : !
        2552             : ! !INTERFACE:
        2553             : !
        2554           0 :   SUBROUTINE NC_GET_SIG_FROM_HYBRID ( fID,  levName, lon1,   lon2, lat1,     &
        2555             :                                       lat2, lev1,    lev2,   time, dir,      &
        2556             :                                       RC,   sigLev4, sigLev8                )
        2557             : !
        2558             : ! !INPUT PARAMETERS:
        2559             : !
        2560             :     INTEGER,          INTENT(IN   ) :: fID             ! Ncdf File ID
        2561             :     CHARACTER(LEN=*), INTENT(IN   ) :: levName         ! variable name
        2562             :     INTEGER,          INTENT(IN   ) :: lon1            ! lon lower bound
        2563             :     INTEGER,          INTENT(IN   ) :: lon2            ! lon upper bound
        2564             :     INTEGER,          INTENT(IN   ) :: lat1            ! lat lower bound
        2565             :     INTEGER,          INTENT(IN   ) :: lat2            ! lat upper bound
        2566             :     INTEGER,          INTENT(IN   ) :: lev1            ! lev lower bound
        2567             :     INTEGER,          INTENT(IN   ) :: lev2            ! lev upper bound
        2568             :     INTEGER,          INTENT(IN   ) :: time            ! time index
        2569             : !
        2570             : ! !INPUT/OUTPUT PARAMETERS:
        2571             : !
        2572             :     REAL*4, OPTIONAL, POINTER       :: SigLev4(:,:,:)  ! sigma levels w/in
        2573             :     REAL*8, OPTIONAL, POINTER       :: SigLev8(:,:,:)  ! specified boundaries
        2574             :     INTEGER,          INTENT(  OUT) :: dir             ! axis direction (1=up;-1=down)
        2575             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        2576             : !
        2577             : ! !REVISION HISTORY:
        2578             : !  See https://github.com/geoschem/hemco for complete history
        2579             : !EOP
        2580             : !------------------------------------------------------------------------------
        2581             : !BOC
        2582             : !
        2583             : ! !LOCAL VARIABLES:
        2584             : !
        2585             :     INTEGER              :: I, J, l1, l2, AS
        2586             :     INTEGER              :: nlev, nlat, nlon
        2587             :     INTEGER              :: nlevs
        2588             :     INTEGER              :: st1d(1), ct1d(1)
        2589             :     LOGICAL              :: ok
        2590           0 :     REAL*4, POINTER      :: a(:)
        2591           0 :     REAL*4, POINTER      :: b(:)
        2592           0 :     REAL*4, POINTER      :: ps(:,:,:,:)
        2593             :     REAL*8               :: p0
        2594             :     CHARACTER(LEN=255)   :: formula, ThisUnit
        2595             :     CHARACTER(LEN=255)   :: aname, bname, psname, p0name
        2596             :     CHARACTER(LEN=255)   :: a_name    ! netCDF attribute name
        2597             :     INTEGER              :: a_type    ! netCDF attribute type
        2598             :
        2599             :     !======================================================================
        2600             :     ! NC_GET_SIG_FROM_HYBRID begins here
        2601             :     !======================================================================
        2602             :
        2603             :     ! Init
        2604           0 :     p0 = -999.d0
        2605           0 :     a  => NULL()
        2606           0 :     b  => NULL()
        2607           0 :     ps => NULL()
        2608             :
        2609             :     ! Get desired grid dimensions.
        2610           0 :     nlon = lon2 - lon1 + 1
        2611           0 :     nlat = lat2 - lat1 + 1
        2612           0 :     nlev = lev2 - lev1 + 1
        2613             :
        2614             :     ! Get dimension length
        2615           0 :     CALL Ncget_Dimlen ( fID, TRIM(LevName), nlevs )
        2616             :
        2617             :     ! Sanity check
        2618           0 :     IF ( nlevs < nlev ) THEN
        2619           0 :        WRITE(*,*) TRIM(LevName), ' is only of length ', nlevs, ' - required is: ', nlev
        2620           0 :        RC = -999
        2621           0 :        RETURN
        2622             :     ENDIF
        2623             :
        2624             :     !------------------------------------------------------------------------
        2625             :     ! Get formula and parse variable names (ap, bp, p0, ps)
        2626             :     !------------------------------------------------------------------------
        2627             :
        2628             :     ! Get formula
        2629           0 :     a_name = "formula_terms"
        2630           0 :     IF ( .NOT. NcDoes_Attr_Exist ( fID,          TRIM(levName),            &
        2631             :                                    TRIM(a_name), a_type         ) ) THEN
        2632           0 :        WRITE(*,*) 'Cannot find attribute ', TRIM(a_name), ' in variable ', &
        2633           0 :                   TRIM(levName)
        2634           0 :        RC = -999
        2635           0 :        RETURN
        2636             :     ENDIF
        2637           0 :     CALL NcGet_Var_Attributes( fID, TRIM(levName), TRIM(a_name), formula )
        2638             :
        2639             :     ! Get variable names
        2640             :     !-------------------
        2641           0 :     I = INDEX( formula, 'a:' )
        2642           0 :     IF ( I > 0 ) THEN
        2643           0 :        CALL GetVarFromFormula( formula, 'a:',  aname, RC )
        2644           0 :        IF ( RC /= 0 ) RETURN
        2645           0 :        CALL GetVarFromFormula( formula, 'p0:', p0name, RC )
        2646           0 :        IF ( RC /= 0 ) RETURN
        2647             :     ELSE
        2648           0 :        CALL GetVarFromFormula( formula, 'ap:', aname, RC )
        2649           0 :        IF ( RC /= 0 ) RETURN
        2650           0 :        p0 = 1.0d0
        2651             :     ENDIF
        2652           0 :     IF ( RC /= 0 ) RETURN
        2653             :
        2654           0 :     CALL GetVarFromFormula( formula, 'b:', bname, RC )
        2655           0 :     IF ( RC /= 0 ) RETURN
        2656             :
        2657           0 :     CALL GetVarFromFormula( formula, 'ps:', psname, RC )
        2658           0 :     IF ( RC /= 0 ) RETURN
        2659             :
        2660             :     !------------------------------------------------------------------------
        2661             :     ! Read variables from file.
        2662             :     !------------------------------------------------------------------------
        2663             :
        2664           0 :     ALLOCATE ( a(nlevs), b(nlevs) )
        2665           0 :     st1d = (/ 1     /)
        2666           0 :     ct1d = (/ nlevs /)
        2667             :
        2668             :     ! read a
        2669             :     !-------
        2670           0 :     IF ( .NOT. Ncdoes_Var_Exist( fID, TRIM(aname) ) ) THEN
        2671           0 :        WRITE(*,*) 'Cannot find variable ', TRIM(aname), '!'
        2672           0 :        RC = -999
        2673           0 :        RETURN
        2674             :     ENDIF
        2675           0 :     CALL NcRd( a, fID, TRIM(aname), st1d, ct1d )
        2676             :
        2677             :     ! eventually read p0
        2678             :     !-------------------
        2679           0 :     IF ( p0 < 0.0d0 ) THEN
        2680           0 :        IF ( .NOT. Ncdoes_Var_Exist( fID, TRIM(p0name) ) ) THEN
        2681           0 :           WRITE(*,*) 'Cannot find variable ', TRIM(p0name), '!'
        2682           0 :           RC = -999
        2683           0 :           RETURN
        2684             :        ENDIF
        2685           0 :     CALL NcRd( p0, fID, TRIM(p0name) )
        2686             :     ENDIF
        2687             :
        2688             :     ! read b
        2689             :     !-------
        2690           0 :     IF ( .NOT. Ncdoes_Var_Exist( fID, TRIM(bname) ) ) THEN
        2691           0 :        WRITE(*,*) 'Cannot find variable ', TRIM(bname), '!'
        2692           0 :        RC = -999
        2693           0 :        RETURN
        2694             :     ENDIF
        2695           0 :     CALL NcRd( b, fID, TRIM(bname), st1d, ct1d )
        2696             :
        2697             :     ! Read ps
        2698             :     !--------
        2699             :     CALL NC_READ_ARR( fID, TRIM(psname), lon1, lon2, lat1, &
        2700           0 :                       lat2, 0, 0, time,  time, ps, VarUnit=thisUnit, RC=RC )
        2701           0 :     IF ( RC /= 0 ) RETURN
        2702             :
        2703             :     !------------------------------------------------------------------------
        2704             :     ! Determine positive axis ('up' or 'down')
        2705             :     ! Try to read it from the netCDF meta data (attribute `positive`). If not
        2706             :     ! found, determine it from b values (b value at surface higher than at
        2707             :     ! top of atmosphere).
        2708             :     !------------------------------------------------------------------------
        2709           0 :     a_name = "positive"
        2710           0 :     IF ( NcDoes_Attr_Exist( fID, TRIM(levName), TRIM(a_name), a_type ) ) THEN
        2711           0 :        CALL NcGet_Var_Attributes( fID, TRIM(levName), TRIM(a_name), formula )
        2712           0 :        IF ( TRIM(formula) == 'up' ) THEN
        2713           0 :           dir = 1
        2714           0 :        ELSEIF ( TRIM(formula) == 'down' ) THEN
        2715           0 :           dir = -1
        2716             :        ELSE
        2717           0 :           WRITE(*,*) 'level attribute `positive` must be `up` ', &
        2718           0 :                      'or `down`, instead: ', TRIM(formula)
        2719           0 :           RC = -999
        2720           0 :           RETURN
        2721             :        ENDIF
        2722             :
        2723             :     ! determine direction from b values.
        2724             :     ELSE
        2725             :
        2726           0 :        IF ( b(1) > b(nlevs) ) THEN
        2727           0 :           dir = 1
        2728             :        ELSE
        2729           0 :           dir = -1
        2730             :        ENDIF
        2731             :     ENDIF
        2732             :
        2733             :     !------------------------------------------------------------------------
        2734             :     ! Determine vertical indeces to be used. It is possible to calculate
        2735             :     ! the pressure only for a given number of layers (as specified by input
        2736             :     ! arguments lev1 and lev2). Assume those are always from bottom to top,
        2737             :     ! i.e. counting `upwards`.
        2738             :     !------------------------------------------------------------------------
        2739             :
        2740           0 :     IF ( dir == -1 ) THEN
        2741           0 :        l1 = nlevs - lev2 + 1
        2742           0 :        l2 = nlevs - lev1 + 1
        2743             :     ELSE
        2744             :        l1 = lev1
        2745             :        l2 = lev2
        2746             :     ENDIF
        2747             :
        2748             :     !------------------------------------------------------------------------
        2749             :     ! Calculate sigma values at grid edges
        2750             :     !------------------------------------------------------------------------
        2751             :
        2752           0 :     IF ( PRESENT(SigLev4) ) THEN
        2753           0 :        IF ( ASSOCIATED(SigLev4) ) DEALLOCATE(SigLev4)
        2754           0 :        ALLOCATE(SigLev4(nlon,nlat,nlev),STAT=AS)
        2755           0 :     ELSEIF ( PRESENT(SigLev8) ) THEN
        2756           0 :        IF ( ASSOCIATED(SigLev8) ) DEALLOCATE(SigLev8)
        2757           0 :        ALLOCATE(SigLev8(nlon,nlat,nlev),STAT=AS)
        2758             :     ELSE
        2759           0 :        WRITE(*,*) 'SigLev must be provided!'
        2760           0 :        RC = -999
        2761           0 :        RETURN
        2762             :     ENDIF
        2763           0 :     IF ( AS /= 0 ) THEN
        2764           0 :        WRITE(*,*) 'Cannot allocate SigLev!'
        2765           0 :        RC = -999
        2766           0 :        RETURN
        2767             :     ENDIF
        2768             :
        2769           0 :     DO J=1,nlat
        2770           0 :     DO I=1,nlon
        2771           0 :        IF ( PRESENT(SigLev4) ) THEN
        2772           0 :           SigLev4(i,j,:) = ( ( a(l1:l2) * p0 ) + ( b(l1:l2) * ps(i,j,1,1) ) ) &
        2773           0 :                         / ps(i,j,1,1)
        2774             :        ELSE
        2775           0 :           SigLev8(i,j,:) = ( ( a(l1:l2) * p0 ) + ( b(l1:l2) * ps(i,j,1,1) ) ) &
        2776           0 :                         / ps(i,j,1,1)
        2777             :        ENDIF
        2778             :     ENDDO
        2779             :     ENDDO
        2780             :
        2781             :     ! Cleanup
        2782           0 :     IF ( ASSOCIATED(a ) ) DEALLOCATE(a )
        2783           0 :     IF ( ASSOCIATED(b ) ) DEALLOCATE(b )
        2784           0 :     IF ( ASSOCIATED(ps) ) DEALLOCATE(ps)
        2785             :
        2786             :     ! Return w/ success
        2787           0 :     RC = 0
        2788             :
        2789           0 :   END SUBROUTINE NC_GET_SIG_FROM_HYBRID
        2790             : !EOC
        2791             : !------------------------------------------------------------------------------
        2792             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2793             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2794             : !------------------------------------------------------------------------------
        2795             : !BOP
        2796             : !
        2797             : ! !IROUTINE: GetVarFromFormula
        2798             : !
        2799             : ! !DESCRIPTION: helper function to extract the variable name from a vertical
        2800             : ! coordinate formula.
        2801             : !\\
        2802             : !\\
        2803             : ! !INTERFACE:
        2804             : !
        2805           0 :   SUBROUTINE GetVarFromFormula ( formula, inname, outname, RC )
        2806             : !
        2807             : ! !INPUT PARAMETERS:
        2808             : !
        2809             :     CHARACTER(LEN=*), INTENT(IN   ) :: formula
        2810             :     CHARACTER(LEN=*), INTENT(IN   ) :: inname
        2811             : !
        2812             : ! !INPUT/OUTPUT PARAMETERS:
        2813             : !
        2814             :     CHARACTER(LEN=*), INTENT(  OUT) :: outname
        2815             :     INTEGER,          INTENT(INOUT) :: RC              ! Return code
        2816             : !
        2817             : ! !REVISION HISTORY:
        2818             : !  See https://github.com/geoschem/hemco for complete history
        2819             : !EOP
        2820             : !------------------------------------------------------------------------------
        2821             : !BOC
        2822             : !
        2823             : ! !LOCAL VARIABLES:
        2824             : !
        2825             :     INTEGER              :: I, J, IDX, LN
        2826             :
        2827             :     !======================================================================
        2828             :     ! GetVarFromFormula begins here
        2829             :     !======================================================================
        2830             :
        2831             :     ! maximum length
        2832           0 :     LN = LEN(TRIM(formula))
        2833             :
        2834             :     ! Get start index of string
        2835             :     !--------------------------
        2836           0 :     I = INDEX( TRIM(formula), TRIM(inname) )
        2837           0 :     IF ( I <= 0 ) THEN
        2838           0 :        WRITE(*,*) 'Cannot extract ', TRIM(inname), ' from ', TRIM(formula)
        2839           0 :        RC = -999
        2840           0 :        RETURN
        2841             :     ENDIF
        2842             :
        2843             :     ! The variable name follows the formula string plus one space!
        2844           0 :     I = I + LEN(inname) + 1
        2845             :
        2846           0 :     outname = ''
        2847             :     IDX = 1
        2848           0 :     DO J = I, LN
        2849           0 :        IF ( formula(J:J) == ' ' ) EXIT
        2850           0 :        outname(IDX:IDX) = formula(J:J)
        2851           0 :        IDX = IDX + 1
        2852             :     ENDDO
        2853             :
        2854             :     ! Return w/ success
        2855           0 :     RC = 0
        2856             :
        2857           0 :   END SUBROUTINE GetVarFromFormula
        2858             : !EOC
        2859             : !------------------------------------------------------------------------------
        2860             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2861             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2862             : !------------------------------------------------------------------------------
        2863             : !BOP
        2864             : !
        2865             : ! !IROUTINE: Nc_Write_3d
        2866             : !
        2867             : ! !DESCRIPTION: Routine to write time slices of 2D fields into netCDF.
        2868             : !\\
        2869             : !\\
        2870             : ! !INTERFACE:
        2871             : !
        2872           0 :   SUBROUTINE NC_WRITE_3D( ncFile,  I,  J,    T,  N,   lon, lat, &
        2873           0 :                           time,    timeUnit, ncVars,  ncUnits,  &
        2874           0 :                           ncLongs, ncShorts, ncArrays            )
        2875             : !
        2876             : ! !INPUT PARAMETERS:
        2877             : !
        2878             :     CHARACTER(LEN=*), INTENT(IN)  :: ncFile             ! file path+name
        2879             :     INTEGER,          INTENT(IN)  :: I                  ! # of lons
        2880             :     INTEGER,          INTENT(IN)  :: J                  ! # of lats
        2881             :     INTEGER,          INTENT(IN)  :: T                  ! # of time slices
        2882             :     INTEGER,          INTENT(IN)  :: N                  ! # of vars
        2883             :     REAL*4,           INTENT(IN)  :: lon(I)             ! longitude
        2884             :     REAL*4,           INTENT(IN)  :: lat(J)             ! latitude
        2885             :     REAL*4,           INTENT(IN)  :: time(T)            ! time
        2886             :     CHARACTER(LEN=*), INTENT(IN)  :: timeUnit           ! time unit
        2887             :     CHARACTER(LEN=*), INTENT(IN)  :: ncVars(N)          ! nc variables
        2888             :     CHARACTER(LEN=*), INTENT(IN)  :: ncUnits(N)         ! var units
        2889             :     CHARACTER(LEN=*), INTENT(IN)  :: ncLongs(N)         ! var long names
        2890             :     CHARACTER(LEN=*), INTENT(IN)  :: ncShorts(N)        ! var short names
        2891             :     REAL*4, TARGET,   INTENT(IN)  :: ncArrays(I,J,T,N)  ! var arrays
        2892             : !
        2893             : ! !REMARKS:
        2894             : !  Created with the ncCodeRead script of the NcdfUtilities package,
        2895             : !  with subsequent hand-editing.
        2896             : !
        2897             : ! !REVISION HISTORY:
        2898             : !  See https://github.com/geoschem/hemco for complete history
        2899             : !EOP
        2900             : !------------------------------------------------------------------------------
        2901             : !BOC
        2902             : !
        2903             : ! !LOCAL VARIABLES:
        2904             : !
        2905             :     ! Scalars
        2906             :     INTEGER            :: fId, II
        2907             :     REAL*4, POINTER    :: tmpArr(:,:,:) => NULL()
        2908             :
        2909             :     !======================================================================
        2910             :     ! NC_WRITE_3D begins here
        2911             :     !======================================================================
        2912             :
        2913             :     CALL NC_DEFINE(ncFile=ncFile, nLon=I,            nLat=J,         &
        2914             :                    nTime=T,       timeUnit=timeUnit, ncVars=ncVars,  &
        2915             :                    ncUnits=ncUnits,ncLongs=ncLongs,ncShorts=ncShorts,&
        2916           0 :                    fId=fId )
        2917             :
        2918           0 :     CALL NC_WRITE_DIMS( fID=fId, lon=lon, lat=lat, time=time )
        2919             :
        2920           0 :     DO II = 1, N
        2921           0 :        tmpArr => ncArrays(:,:,:,II)
        2922           0 :        CALL NC_WRITE_DATA_3D ( fId, ncVars(II), tmpArr )
        2923           0 :        tmpArr => NULL()
        2924             :     ENDDO
        2925             :
        2926           0 :     CALL NcCl( fId )
        2927             :
        2928           0 :   END SUBROUTINE NC_WRITE_3D
        2929             : !EOC
        2930             : !------------------------------------------------------------------------------
        2931             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        2932             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        2933             : !------------------------------------------------------------------------------
        2934             : !BOP
        2935             : !
        2936             : ! !IROUTINE: Nc_Write_4d
        2937             : !
        2938             : ! !DESCRIPTION: Routine to write time slices of 3D fields into netCDF.
        2939             : !\\
        2940             : !\\
        2941             : ! !INTERFACE:
        2942             : !
        2943           0 :   SUBROUTINE NC_WRITE_4D (ncFile,  I, J, L, T, N, lon, lat, lev, &
        2944           0 :                           time,    timeUnit, ncVars,  ncUnits,   &
        2945           0 :                           ncLongs, ncShorts, ncArrays             )
        2946             : !
        2947             : ! !INPUT PARAMETERS:
        2948             : !
        2949             :     CHARACTER(LEN=*), INTENT(IN)  :: ncFile   ! file path+name
        2950             :     INTEGER,          INTENT(IN)  :: I        ! # of lons
        2951             :     INTEGER,          INTENT(IN)  :: J        ! # of lats
        2952             :     INTEGER,          INTENT(IN)  :: L        ! # of levs
        2953             :     INTEGER,          INTENT(IN)  :: T        ! # of time slices
        2954             :     INTEGER,          INTENT(IN)  :: N        ! # of vars
        2955             :     REAL*4,           INTENT(IN)  :: lon(:)   ! longitude
        2956             :     REAL*4,           INTENT(IN)  :: lat(:)   ! latitude
        2957             :     REAL*4,           INTENT(IN)  :: lev(:)   ! levels
        2958             :     REAL*4,           INTENT(IN)  :: time(:)  ! time
        2959             :     CHARACTER(LEN=*), INTENT(IN)  :: timeUnit ! time unit
        2960             :     CHARACTER(LEN=*), INTENT(IN)  :: ncVars(:)    ! nc variables
        2961             :     CHARACTER(LEN=*), INTENT(IN)  :: ncUnits(:)   ! var units
        2962             :     CHARACTER(LEN=*), INTENT(IN)  :: ncLongs(:)   ! var long names
        2963             :     CHARACTER(LEN=*), INTENT(IN)  :: ncShorts(:)  ! var short names
        2964             :     REAL*4, TARGET,   INTENT(IN)  :: ncArrays(:,:,:,:,:)  ! var arrays
        2965             : !
        2966             : ! !REMARKS:
        2967             : !  Created with the ncCodeRead script of the NcdfUtilities package,
        2968             : !  with subsequent hand-editing.
        2969             : !
        2970             : ! !REVISION HISTORY:
        2971             : !  See https://github.com/geoschem/hemco for complete history
        2972             : !EOP
        2973             : !------------------------------------------------------------------------------
        2974             : !BOC
        2975             : !
        2976             : ! !LOCAL VARIABLES:
        2977             : !
        2978             :     INTEGER            :: II, fID
        2979             :     REAL*4, POINTER    :: tmpArr(:,:,:,:) => NULL()
        2980             :
        2981             :     !======================================================================
        2982             :     ! NC_WRITE begins here
        2983             :     !======================================================================
        2984             :
        2985             :     CALL NC_DEFINE(ncFile=ncFile, nLon=I, nLat=J, nLev=L,            &
        2986             :                    nTime=T,  timeUnit=timeUnit, ncVars=ncVars,       &
        2987             :                    ncUnits=ncUnits,ncLongs=ncLongs,ncShorts=ncShorts,&
        2988           0 :                    fId=fId )
        2989             :
        2990           0 :     CALL NC_WRITE_DIMS( fID=fId, lon=lon, lat=lat, time=time, lev=lev)
        2991             :
        2992           0 :     DO II = 1, size(ncVars)
        2993           0 :        tmpArr => ncArrays(:,:,:,:,II)
        2994           0 :        CALL NC_WRITE_DATA_4D ( fId, ncVars(II), tmpArr )
        2995           0 :        tmpArr => NULL()
        2996             :     ENDDO
        2997             :
        2998           0 :     CALL NcCl( fId )
        2999             :
        3000           0 :   END SUBROUTINE NC_WRITE_4D
        3001             : !EOC
        3002             : !------------------------------------------------------------------------------
        3003             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        3004             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        3005             : !------------------------------------------------------------------------------
        3006             : !BOP
        3007             : !
        3008             : ! !IROUTINE: Nc_Define
        3009             : !
        3010             : ! !DESCRIPTION: Routine to define the variables and attributes of a netCDF
        3011             : !  file.
        3012             : !\\
        3013             : !\\
        3014             : ! !INTERFACE:
        3015             : !
        3016           0 :   SUBROUTINE NC_DEFINE ( ncFile,  nLon,    nLat,    nLev,    nTime,&
        3017           0 :                          timeUnit, ncVars,  ncUnits, ncLongs, ncShorts, fId )
        3018             : !
        3019             : ! !INPUT PARAMETERS:
        3020             : !
        3021             :     CHARACTER(LEN=*),   INTENT(IN   )  :: ncFile      ! ncdf file path + name
        3022             :     INTEGER,            INTENT(IN   )  :: nLon        ! # of lons
        3023             :     INTEGER,            INTENT(IN   )  :: nLat        ! # of lats
        3024             :     INTEGER, OPTIONAL,  INTENT(IN   )  :: nLev        ! # of levels
        3025             :     INTEGER,            INTENT(IN   )  :: nTime       ! # of time stamps
        3026             :     CHARACTER(LEN=*),   INTENT(IN   )  :: timeUnit    ! time unit
        3027             :     CHARACTER(LEN=*),   INTENT(IN   )  :: ncVars(:)   ! ncdf variables
        3028             :     CHARACTER(LEN=*),   INTENT(IN   )  :: ncUnits(:)  ! var units
        3029             :     CHARACTER(LEN=*),   INTENT(IN   )  :: ncLongs(:)  ! var long names
        3030             :     CHARACTER(LEN=*),   INTENT(IN   )  :: ncShorts(:) ! var short names
        3031             : !
        3032             : ! !OUTPUT PARAMETERS:
        3033             : !
        3034             :     INTEGER,            INTENT(  OUT)  :: fId      ! netCDF file ID
        3035             : !
        3036             : ! !REMARKS:
        3037             : !  Assumes that you have:
        3038             : !  (1) A netCDF library (either v3 or v4) installed on your system
        3039             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        3040             : !                                                                             .
        3041             : !  Although this routine was generated automatically, some further
        3042             : !  hand-editing may be required.
        3043             : !
        3044             : ! !REVISION HISTORY:
        3045             : !  See https://github.com/geoschem/hemco for complete history
        3046             : !EOP
        3047             : !------------------------------------------------------------------------------
        3048             : !BOC
        3049             : !
        3050             : ! !LOCAL VARIABLES:
        3051             : !
        3052             :     ! Declare netCDF variable ID and fill mode
        3053             :     INTEGER            :: vId
        3054             :     INTEGER            :: omode
        3055             :
        3056             :     ! Variables for netCDF dimensions
        3057             :     INTEGER            :: id_lon
        3058             :     INTEGER            :: id_lat
        3059             :     INTEGER            :: id_time
        3060             :     INTEGER            :: id_lev
        3061             :
        3062             :     ! Character strings
        3063             :     CHARACTER(LEN=255) :: v_name      ! netCDF variable name
        3064             :     CHARACTER(LEN=255) :: a_name      ! netCDF attribute name
        3065             :     CHARACTER(LEN=255) :: a_val       ! netCDF attribute value
        3066             :     CHARACTER(LEN=3  ) :: idstr       ! tracer ID string
        3067             :
        3068             :     ! Arrays for netCDF dimension IDs
        3069             :     INTEGER            :: var1d(1)    ! For 1D arrays
        3070             :     INTEGER            :: var3d(3)    ! For 3D arrays
        3071             :     INTEGER            :: var4d(4)    ! For 4D arrays
        3072             :
        3073             :     ! Other variables
        3074             :     INTEGER            :: I
        3075             :
        3076             :     !=================================================================
        3077             :     ! %%%%% NETCDF DEFINITION SECTION %%%%%
        3078             :     !=================================================================
        3079             :
        3080             :     ! Initialize the variable ID counter
        3081           0 :     vId = 0
        3082             :
        3083             :     ! Open filename
        3084           0 :     CALL NcCr_Wr( fId, TRIM(ncFile) )
        3085             :
        3086             :     ! Turn filling off
        3087           0 :     CALL NcSetFill( fId, NF90_NOFILL, omode )
        3088             :
        3089             :     !--------------------------------
        3090             :     ! GLOBAL ATTRIBUTES
        3091             :     !--------------------------------
        3092             :
        3093             :     ! Define the title global attribute
        3094           0 :     a_name = "Title"
        3095           0 :     a_val  = "Field generated by ncdf_util.F"
        3096           0 :     CALL NcDef_Glob_Attributes( fId, TRIM(a_name), TRIM(a_val) )
        3097             :
        3098             :     ! Define the history global attribute
        3099           0 :     a_name = "History"
        3100           0 :     a_val  = "Initial version"
        3101           0 :     CALL NcDef_Glob_Attributes( fId, TRIM(a_name), TRIM(a_val) )
        3102             :
        3103             :     ! Define the conventions global attribute
        3104           0 :     a_name = "Conventions"
        3105           0 :     a_val  = "COARDS"
        3106           0 :     CALL NcDef_Glob_Attributes( fId, TRIM(a_name), TRIM(a_val) )
        3107             :
        3108             :     ! Define the format global attribute
        3109           0 :     a_name = "Format"
        3110           0 :     a_val  = "netCDF-3"
        3111           0 :     CALL NcDef_Glob_Attributes( fId, TRIM(a_name), TRIM(a_val) )
        3112             :
        3113             :     !--------------------------------
        3114             :     ! DIMENSIONS
        3115             :     !--------------------------------
        3116             :
        3117             :     ! Define lon dimension
        3118           0 :     v_name = "lon"
        3119           0 :     CALL NcDef_Dimension( fId, TRIM(v_name), nlon, id_lon )
        3120             :
        3121             :     ! Define lat dimension
        3122           0 :     v_name = "lat"
        3123           0 :     CALL NcDef_Dimension( fId, TRIM(v_name), nlat, id_lat )
        3124             :
        3125             :     ! Define lev dimension
        3126           0 :     IF ( PRESENT(nlev) ) THEN
        3127           0 :        v_name = "lev"
        3128           0 :        CALL NcDef_Dimension( fId, TRIM(v_name), nlev, id_lev )
        3129             :     ENDIF
        3130             :
        3131             :     ! Define time dimension
        3132           0 :     v_name = "time"
        3133           0 :     CALL NcDef_Dimension( fId, TRIM(v_name), ntime, id_time, unlimited=.true. )
        3134             :
        3135             :     !--------------------------------
        3136             :     ! VARIABLE: lon
        3137             :     !--------------------------------
        3138             :
        3139             :     ! Define the "lon" variable
        3140           0 :     v_name = "lon"
        3141           0 :     var1d = (/ id_lon /)
        3142           0 :     CALL NcDef_Variable( fId, TRIM(v_name), NF90_FLOAT, 1, var1d, vId )
        3143             :
        3144             :     ! Define the "lon:long_name" attribute
        3145           0 :     a_name = "long_name"
        3146           0 :     a_val  = "Longitude"
        3147           0 :     CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val) )
        3148             :
        3149             :     ! Define the "lon:units" attribute
        3150           0 :     a_name = "units"
        3151           0 :     a_val  = "degrees_east"
        3152           0 :     CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val) )
        3153             :
        3154             :     !--------------------------------
        3155             :     ! VARIABLE: lat
        3156             :     !--------------------------------
        3157             :
        3158             :     ! Define the "lat" variable
        3159           0 :     v_name = "lat"
        3160           0 :     var1d = (/ id_lat /)
        3161           0 :     CALL NcDef_Variable( fId, TRIM(v_name), NF90_FLOAT, 1, var1d, vId )
        3162             :
        3163             :     ! Define the "lat:long_name" attribute
        3164           0 :     a_name = "long_name"
        3165           0 :     a_val  = "Latitude"
        3166           0 :     CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val) )
        3167             :
        3168             :     ! Define the "lat:units" attribute
        3169           0 :     a_name = "units"
        3170           0 :     a_val  = "degrees_north"
        3171           0 :     CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val) )
        3172             :
        3173             :     !--------------------------------
        3174             :     ! VARIABLE: lev
        3175             :     !--------------------------------
        3176             :
        3177           0 :     IF ( PRESENT(nlev) ) THEN
        3178             :
        3179             :        ! Define the "levels" variable
        3180           0 :        v_name = "lev"
        3181           0 :        var1d = (/ id_lev /)
        3182           0 :        CALL NcDef_Variable( fId, TRIM(v_name), NF90_INT, 1, var1d, vId )
        3183             :
        3184             :        ! Define the "time:long_name" attribute
        3185           0 :        a_name = "long_name"
        3186           0 :        a_val  = "Levels"
        3187           0 :        CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val))
        3188             :
        3189             :        ! Define the "time:units" attribute
        3190           0 :        a_name = "units"
        3191           0 :        a_val  = "unitless"
        3192           0 :        CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val))
        3193             :     ENDIF
        3194             :
        3195             :     !--------------------------------
        3196             :     ! VARIABLE: time
        3197             :     !--------------------------------
        3198             :
        3199             :     ! Define the "time" variable
        3200           0 :     v_name = "time"
        3201           0 :     var1d = (/ id_time /)
        3202           0 :     CALL NcDef_Variable( fId, TRIM(v_name), NF90_INT, 1, var1d, vId )
        3203             :
        3204             :     ! Define the "time:long_name" attribute
        3205           0 :     a_name = "long_name"
        3206           0 :     a_val  = "Time"
        3207           0 :     CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val) )
        3208             :
        3209             :     ! Define the "time:units" attribute
        3210           0 :     a_name = "units"
        3211           0 :     a_val  = trim(timeUnit)
        3212           0 :     CALL NcDef_Var_Attributes( fId, vId, TRIM(a_name), TRIM(a_val) )
        3213             :
        3214             :     !--------------------------------
        3215             :     ! Define variables
        3216             :     !--------------------------------
        3217             :
        3218           0 :     DO I = 1, SIZE(ncVars)
        3219             :
        3220           0 :        v_name = TRIM(ncVars(I))
        3221           0 :        IF ( PRESENT(nlev) ) THEN
        3222           0 :           var4d = (/ id_lon, id_lat, id_lev, id_time /)
        3223           0 :           CALL NcDef_Variable(fId,TRIM(v_name),NF90_DOUBLE,4,var4d,vId)
        3224             :        ELSE
        3225           0 :           var3d = (/ id_lon, id_lat, id_time /)
        3226           0 :           CALL NcDef_Variable(fId,TRIM(v_name),NF90_DOUBLE,3,var3d,vId)
        3227             :        ENDIF
        3228             :
        3229             :        ! Define the long_name attribute
        3230           0 :        a_name = "long_name"
        3231           0 :        a_val  = TRIM(ncLongs(I))
        3232           0 :        CALL NcDef_Var_Attributes(fId, vId, TRIM(a_name), TRIM(a_val) )
        3233             :
        3234             :        ! Define the short_name attribute
        3235           0 :        a_name = "short_name"
        3236           0 :        a_val  = TRIM(ncShorts(I))
        3237           0 :        CALL NcDef_Var_Attributes(fId, vId, TRIM(a_name), TRIM(a_val) )
        3238             :
        3239             :        ! Define the units attribute
        3240           0 :        a_name = "units"
        3241           0 :        a_val  = TRIM(ncUnits(I))
        3242           0 :        CALL NcDef_Var_Attributes(fId, vId, TRIM(a_name), TRIM(a_val) )
        3243             :     ENDDO
        3244             :
        3245             :     !=================================================================
        3246             :     ! %%%%% END OF NETCDF DEFINITION SECTION %%%%%
        3247             :     !=================================================================
        3248           0 :     CALL NcEnd_Def( fId )
        3249             :
        3250           0 :   END SUBROUTINE NC_DEFINE
        3251             : !EOC
        3252             : !------------------------------------------------------------------------------
        3253             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        3254             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        3255             : !------------------------------------------------------------------------------
        3256             : !BOP
        3257             : !
        3258             : ! !IROUTINE: Nc_Write_Dims
        3259             : !
        3260             : ! !DESCRIPTION: Routine to write dimension arrays to a netCDF file.
        3261             : !\\
        3262             : !\\
        3263             : ! !INTERFACE:
        3264             : !
        3265           0 :   SUBROUTINE NC_WRITE_DIMS( fID, lon, lat, time, lev )
        3266             : !
        3267             : ! !INPUT/OUTPUT PARAMETERS:
        3268             : !
        3269             :     INTEGER,          INTENT(INOUT) :: fId
        3270             : !
        3271             : ! !INPUT PARAMETERS:
        3272             : !
        3273             :     REAL*4,           INTENT(IN   ) :: lon(:)
        3274             :     REAL*4,           INTENT(IN   ) :: lat(:)
        3275             :     REAL*4,           INTENT(IN   ) :: time(:)
        3276             :     REAL*4, OPTIONAL, INTENT(IN   ) :: lev(:)
        3277             : !
        3278             : ! !REMARKS:
        3279             : !  Assumes that you have:
        3280             : !  (1) A netCDF library (either v3 or v4) installed on your system
        3281             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        3282             : !                                                                             .
        3283             : !  Although this routine was generated automatically, some further
        3284             : !  hand-editing may be required.
        3285             : !
        3286             : ! !REVISION HISTORY:
        3287             : !  See https://github.com/geoschem/hemco for complete history
        3288             : !EOP
        3289             : !------------------------------------------------------------------------------
        3290             : !BOC
        3291             : !
        3292             : ! !LOCAL VARIABLES:
        3293             : !
        3294             :     ! Character strings
        3295             :     CHARACTER(LEN=255) :: v_name             ! netCDF variable name
        3296             :
        3297             :     ! Arrays for netCDF start and count values
        3298             :     INTEGER            :: st1d(1), ct1d(1)   ! For 1D arrays
        3299             :     INTEGER            :: v_size
        3300             :
        3301             :     !=================================================================
        3302             :     ! Define lon/lat
        3303             :     !=================================================================
        3304             :
        3305             :     ! Write lon to netCDF file
        3306           0 :     v_name = "lon"
        3307           0 :     v_size = size( lon, 1 )
        3308           0 :     st1d   = (/ 1      /)
        3309           0 :     ct1d   = (/ v_size /)
        3310           0 :     CALL NcWr( lon, fId, TRIM(v_name), st1d, ct1d )
        3311             :
        3312             :     ! Write lat to netCDF file
        3313           0 :     v_name = "lat"
        3314           0 :     v_size = size( lat, 1 )
        3315           0 :     st1d   = (/ 1      /)
        3316           0 :     ct1d   = (/ v_size /)
        3317           0 :     CALL NcWr( lat, fId, TRIM(v_name), st1d, ct1d )
        3318             :
        3319             :     ! Write lev to netCDF file
        3320           0 :     IF ( PRESENT(lev) ) THEN
        3321           0 :        v_name = "lev"
        3322           0 :        v_size = size( lev, 1 )
        3323           0 :        st1d   = (/ 1      /)
        3324           0 :        ct1d   = (/ v_size /)
        3325           0 :        CALL NcWr( lev, fId, TRIM(v_name), st1d, ct1d )
        3326             :     ENDIF
        3327             :
        3328             :     ! Write passed time integer to netCDF file
        3329           0 :     v_name = "time"
        3330           0 :     v_size = size( time, 1 )
        3331           0 :     st1d   = (/ 1      /)
        3332           0 :     ct1d   = (/ v_size /)
        3333           0 :     CALL NcWr( time, fId, TRIM(v_name), st1d, ct1d )
        3334             :
        3335           0 :   END SUBROUTINE NC_WRITE_DIMS
        3336             : !EOC
        3337             : !------------------------------------------------------------------------------
        3338             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        3339             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        3340             : !------------------------------------------------------------------------------
        3341             : !BOP
        3342             : !
        3343             : ! !IROUTINE: Nc_Nrite_Data_3d
        3344             : !
        3345             : ! !DESCRIPTION: Routine to write a 3-D array to a netCDF file.
        3346             : !\\
        3347             : !\\
        3348             : ! !INTERFACE:
        3349             : !
        3350           0 :   SUBROUTINE NC_WRITE_DATA_3D ( fID, ncVar, Array )
        3351             : !
        3352             : ! !INPUT/OUTPUT PARAMETERS:
        3353             : !
        3354             :     INTEGER,          INTENT(INOUT) :: fId
        3355             : !
        3356             : ! !INPUT PARAMETERS:
        3357             : !
        3358             :     CHARACTER(LEN=*), INTENT(IN   ) :: ncVar
        3359             :     REAL*4,           POINTER       :: Array(:,:,:)
        3360             : !
        3361             : ! !REMARKS:
        3362             : !  Assumes that you have:
        3363             : !  (1) A netCDF library (either v3 or v4) installed on your system
        3364             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        3365             : !                                                                             .
        3366             : !  Although this routine was generated automatically, some further
        3367             : !  hand-editing may be required.
        3368             : !
        3369             : ! !REVISION HISTORY:
        3370             : !  See https://github.com/geoschem/hemco for complete history
        3371             : !EOP
        3372             : !------------------------------------------------------------------------------
        3373             : !BOC
        3374             : !
        3375             : ! !LOCAL VARIABLES:
        3376             : !
        3377             :     ! Arrays for netCDF start and count values
        3378             :     INTEGER            :: st3d(3), ct3d(3)   ! For 3D arrays
        3379             :
        3380             :     !=================================================================
        3381             :     ! Write data to netCDF file
        3382             :     !=================================================================
        3383             :
        3384           0 :     st3d = (/ 1, 1, 1 /)
        3385           0 :     ct3d = (/ size(array,1), size(array,2), size(array,3) /)
        3386           0 :     CALL NcWr( ARRAY, fId, TRIM(ncVar), st3d, ct3d )
        3387             :
        3388           0 :   END SUBROUTINE NC_WRITE_DATA_3D
        3389             : !EOC
        3390             : !------------------------------------------------------------------------------
        3391             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        3392             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        3393             : !------------------------------------------------------------------------------
        3394             : !BOP
        3395             : !
        3396             : ! !IROUTINE: Nc_Write_Data_4d
        3397             : !
        3398             : ! !DESCRIPTION: Routine to write a 4-D array to a netCDF file.
        3399             : !\\
        3400             : !\\
        3401             : ! !INTERFACE:
        3402             : !
        3403           0 :   SUBROUTINE NC_WRITE_DATA_4D ( fID, ncVar, Array )
        3404             : !
        3405             : ! !INPUT/OUTPUT PARAMETERS:
        3406             : !
        3407             :     INTEGER,          INTENT(INOUT) :: fId
        3408             : !
        3409             : ! !INPUT PARAMETERS:
        3410             : !
        3411             :     CHARACTER(LEN=*), INTENT(IN   ) :: ncVar
        3412             :     REAL*4,           POINTER       :: Array(:,:,:,:)
        3413             : !
        3414             : ! !REMARKS:
        3415             : !  Assumes that you have:
        3416             : !  (1) A netCDF library (either v3 or v4) installed on your system
        3417             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        3418             : !                                                                             .
        3419             : !  Although this routine was generated automatically, some further
        3420             : !  hand-editing may be required.
        3421             : !
        3422             : ! !REVISION HISTORY:
        3423             : !  See https://github.com/geoschem/hemco for complete history
        3424             : !EOP
        3425             : !------------------------------------------------------------------------------
        3426             : !BOC
        3427             : !
        3428             : ! !LOCAL VARIABLES:
        3429             : !
        3430             :     ! Arrays for netCDF start and count values
        3431             :     INTEGER            :: st4d(4), ct4d(4)   ! For 4D arrays
        3432             :
        3433             :     !=================================================================
        3434             :     ! Write data to netCDF file
        3435             :     !=================================================================
        3436             :
        3437           0 :     st4d   = (/ 1, 1, 1, 1 /)
        3438             :     ct4d   = (/ size(array,1), size(array,2), &
        3439           0 :                   size(array,3), size(array,4)   /)
        3440           0 :     CALL NcWr( ARRAY, fId, TRIM(ncVar), st4d, ct4d )
        3441             :
        3442           0 :   END SUBROUTINE NC_WRITE_DATA_4D
        3443             : !EOC
        3444             : !------------------------------------------------------------------------------
        3445             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        3446             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        3447             : !------------------------------------------------------------------------------
        3448             : !BOP
        3449             : !
        3450             : ! !IROUTINE: Nc_Create
        3451             : !
        3452             : ! !DESCRIPTION: Creates a new netCDF file and defines several global
        3453             : !  attributes.
        3454             : !\\
        3455             : !\\
        3456             : ! !INTERFACE:
        3457             : !
        3458           0 :   SUBROUTINE Nc_Create( NcFile,      Title,          nLon,                   &
        3459             :                         nLat,        nLev,           nTime,                  &
        3460             :                         fId,         lonID,          latId,                  &
        3461             :                         levId,       timeId,         VarCt,                  &
        3462             :                         Create_NC4,  KeepDefMode,    NcFormat,               &
        3463             :                         Conventions, History,        ProdDateTime,           &
        3464             :                         Reference,   Contact,        nIlev,                  &
        3465             :                         iLevId,      StartTimeStamp, EndTimeStamp           )
        3466             : !
        3467             : ! !INPUT PARAMETERS:
        3468             : !
        3469             :     ! Required arguments
        3470             :     CHARACTER(LEN=*), INTENT(IN   )  :: ncFile         ! ncdf file path + name
        3471             :     CHARACTER(LEN=*), INTENT(IN   )  :: title          ! ncdf file title
        3472             :     INTEGER,          INTENT(IN   )  :: nLon           ! # of lons
        3473             :     INTEGER,          INTENT(IN   )  :: nLat           ! # of lats
        3474             :     INTEGER,          INTENT(IN   )  :: nLev           ! # of level midpoints
        3475             :     INTEGER,          INTENT(IN   )  :: nTime          ! # of times
        3476             :     INTEGER,          OPTIONAL       :: nILev          ! # of level interfaces
        3477             :
        3478             :     ! Optional arguments (mostly global attributes)
        3479             :     LOGICAL,          OPTIONAL       :: Create_Nc4     ! Save as netCDF-4
        3480             :     LOGICAL,          OPTIONAL       :: KeepDefMode    ! If = T, then don't
        3481             :                                                        !  exit define mode
        3482             :     CHARACTER(LEN=*), OPTIONAL       :: NcFormat       ! e.g. netCDF-4
        3483             :     CHARACTER(LEN=*), OPTIONAL       :: Conventions    ! e.g. COARDS, CF, etc.
        3484             :     CHARACTER(LEN=*), OPTIONAL       :: History        ! History glob attribute
        3485             :     CHARACTER(LEN=*), OPTIONAL       :: ProdDateTime   ! Time/date of production
        3486             :     CHARACTER(LEN=*), OPTIONAL       :: Reference      ! Reference string
        3487             :     CHARACTER(LEN=*), OPTIONAL       :: Contact        ! People to contact
        3488             :     CHARACTER(LEN=*), OPTIONAL       :: StartTimeStamp ! Timestamps at start
        3489             :     CHARACTER(LEN=*), OPTIONAL       :: EndTimeStamp   !  and end of simulation
        3490             : !
        3491             : ! !OUTPUT PARAMETERS:
        3492             : !
        3493             :     INTEGER,          INTENT(  OUT)  :: fId            ! file id
        3494             :     INTEGER,          INTENT(  OUT)  :: lonId          ! lon  dimension id
        3495             :     INTEGER,          INTENT(  OUT)  :: latId          ! lat  dimension id
        3496             :     INTEGER,          INTENT(  OUT)  :: levId          ! lev  dimension id
        3497             :     INTEGER,          INTENT(  OUT)  :: timeId         ! time dimension id
        3498             :     INTEGER,          INTENT(  OUT)  :: VarCt          ! variable counter
        3499             :     INTEGER,          OPTIONAL       :: ilevId         ! ilev dimension id
        3500             : !
        3501             : ! !REMARKS:
        3502             : !  Assumes that you have:
        3503             : !  (1) A netCDF library (either v3 or v4) installed on your system
        3504             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        3505             : !                                                                             .
        3506             : !  Although this routine was generated automatically, some further
        3507             : !  hand-editing may be required.
        3508             : !
        3509             : ! !REVISION HISTORY:
        3510             : !  See https://github.com/geoschem/hemco for complete history
        3511             : !EOP
        3512             : !------------------------------------------------------------------------------
        3513             : !BOC
        3514             : !
        3515             : ! !LOCAL VARIABLES:
        3516             : !
        3517             :     ! Scalars
        3518             :     INTEGER            :: omode
        3519             :     LOGICAL            :: Save_As_Nc4
        3520             :     LOGICAL            :: QuitDefMode
        3521             :
        3522             :     ! Strings
        3523             :     CHARACTER(LEN=255) :: ThisHistory
        3524             :     CHARACTER(LEN=255) :: ThisNcFormat
        3525             :     CHARACTER(LEN=255) :: ThisConv
        3526             :     CHARACTER(LEN=255) :: ThisPdt
        3527             :     CHARACTER(LEN=255) :: ThisReference
        3528             :     CHARACTER(LEN=255) :: ThisContact
        3529             :     CHARACTER(LEN=255) :: ThisStartTimeStamp
        3530             :     CHARACTER(LEN=255) :: ThisEndTimeStamp
        3531             :
        3532             :     !=======================================================================
        3533             :     ! Initialize
        3534             :     !=======================================================================
        3535             :
        3536             :     ! Create file as NetCDF4?
        3537           0 :     IF ( PRESENT( Create_Nc4 ) ) THEN
        3538           0 :        Save_As_Nc4 = Create_Nc4
        3539             :     ELSE
        3540           0 :        Save_As_Nc4 = .FALSE.
        3541             :     ENDIF
        3542             :
        3543             :     ! Should we exit netCDF define mode before leaving this routine?
        3544           0 :     IF ( PRESENT( KeepDefMode ) ) THEN
        3545           0 :        QuitDefMode = ( .not. KeepDefMode )
        3546             :     ELSE
        3547             :        QuitDefMode = .TRUE.
        3548             :     ENDIF
        3549             :
        3550             :     ! History global attribute
        3551           0 :     IF ( PRESENT( History ) ) THEN
        3552           0 :        ThisHistory = TRIM( History )
        3553             :     ELSE
        3554           0 :        ThisHistory = 'Created by routine NC_CREATE (in ncdf_mod.F90)'
        3555             :     ENDIF
        3556             :
        3557             :     ! NetCDF format global attribute
        3558           0 :     IF ( PRESENT( NcFormat ) ) Then
        3559           0 :        ThisNcFormat = NcFormat
        3560             :     ELSE
        3561           0 :        IF ( Save_As_Nc4 ) THEN
        3562           0 :           ThisNcFormat = 'NetCDF-4'
        3563             :        ELSE
        3564           0 :           ThisNcFormat = 'NetCDF-3'
        3565             :        ENDIF
        3566             :     ENDIF
        3567             :
        3568             :     ! Conventions global attribute (assume COARDS)
        3569           0 :     IF ( PRESENT( Conventions ) ) THEN
        3570           0 :        ThisConv = TRIM( Conventions )
        3571             :     ELSE
        3572           0 :        ThisConv = 'COARDS'
        3573             :     ENDIF
        3574             :
        3575             :     ! Conventions global attribute (assume COARDS)
        3576           0 :     IF ( PRESENT( ProdDateTime ) ) THEN
        3577           0 :        ThisPdt= TRIM( ProdDateTime )
        3578             :     ENDIF
        3579             :
        3580             :     ! Conventions global attribute (assume COARDS)
        3581           0 :     IF ( PRESENT( Reference ) ) THEN
        3582           0 :        ThisReference = TRIM( Reference )
        3583             :     ELSE
        3584           0 :        ThisReference = ''
        3585             :     ENDIF
        3586             :
        3587             :     ! Contact
        3588           0 :     IF ( PRESENT( Contact ) ) THEN
        3589           0 :        ThisContact = TRIM( Contact )
        3590             :     ELSE
        3591           0 :        ThisContact = ''
        3592             :     ENDIF
        3593             :
        3594             :     ! Starting date and time of the simulation
        3595           0 :     IF ( PRESENT( StartTimeStamp ) ) THEN
        3596           0 :        ThisStartTimeStamp = TRIM( StartTimeStamp )
        3597             :     ELSE
        3598           0 :        ThisStartTimeStamp = ''
        3599             :     ENDIF
        3600             :
        3601             :     ! Ending date and time of the simulation
        3602           0 :     IF ( PRESENT( EndTimeStamp ) ) THEN
        3603           0 :        ThisEndTimeStamp = TRIM( EndTimeStamp )
        3604             :     ELSE
        3605           0 :        ThisEndTimeStamp = ''
        3606             :     ENDIF
        3607             :
        3608             :     !=======================================================================
        3609             :     ! Open the file
        3610             :     !=======================================================================
        3611             :
        3612             :     ! Open filename.  Save file in netCDF-4 format if requested by user.
        3613           0 :     CALL NcCr_Wr( fId, TRIM( ncFile ), Save_As_Nc4 )
        3614             :
        3615             :     ! Turn filling off
        3616           0 :     CALL NcSetFill( fId, NF90_NOFILL, omode )
        3617             :
        3618             :     !=======================================================================
        3619             :     ! Set global attributes
        3620             :     !=======================================================================
        3621             :
        3622             :     ! These attributes are required for COARDS or CF conventions
        3623           0 :     CALL NcDef_Glob_Attributes(  fId, 'title',        TRIM( Title         ) )
        3624           0 :     CALL NcDef_Glob_Attributes(  fId, 'history',      TRIM( ThisHistory   ) )
        3625           0 :     CALL NcDef_Glob_Attributes(  fId, 'format',       TRIM( ThisNcFormat  ) )
        3626           0 :     CALL NcDef_Glob_Attributes(  fId, 'conventions',  TRIM( ThisConv      ) )
        3627             :
        3628             :     ! These attributes are optional
        3629           0 :     IF ( PRESENT( ProdDateTime ) ) THEN
        3630           0 :      CALL NcDef_Glob_Attributes( fId, 'ProdDateTime', TRIM( ThisPdt       ) )
        3631             :     ENDIF
        3632             :
        3633           0 :     IF ( PRESENT( Reference ) ) THEN
        3634           0 :      CALL NcDef_Glob_Attributes( fId, 'reference',    TRIM( ThisReference ) )
        3635             :     ENDIF
        3636             :
        3637           0 :     IF ( PRESENT( Contact ) ) THEN
        3638           0 :      CALL NcDef_Glob_Attributes( fId, 'contact',      TRIM( ThisContact   ) )
        3639             :     ENDIF
        3640             :
        3641           0 :     IF ( PRESENT( StartTimeStamp ) ) THEN
        3642             :      CALL NcDef_Glob_Attributes( fId, 'simulation_start_date_and_time',      &
        3643           0 :                                        TRIM( ThisStartTimeStamp   )         )
        3644             :     ENDIF
        3645             :
        3646           0 :     IF ( PRESENT( EndTimeStamp ) ) THEN
        3647             :      CALL NcDef_Glob_Attributes( fId, 'simulation_end_date_and_time',        &
        3648           0 :                                        TRIM( ThisEndTimeStamp )             )
        3649             :     ENDIF
        3650             :
        3651             :     !=======================================================================
        3652             :     ! Set dimensions
        3653             :     !=======================================================================
        3654             :
        3655             :     ! Time
        3656           0 :     CALL NcDef_Dimension( fId, 'time', nTime, TimeId, unlimited=.true. )
        3657             :
        3658             :     ! Level midpoints
        3659           0 :     IF ( nLev > 0 ) THEN
        3660           0 :        CALL NcDef_Dimension( fId, 'lev',  nLev,  levId  )
        3661             :     ELSE
        3662           0 :        levId = -1
        3663             :     ENDIF
        3664             :
        3665             :     ! Optional ILev dimension: level interfaces
        3666           0 :     IF ( PRESENT( nIlev ) .and. PRESENT( iLevId ) ) THEN
        3667           0 :        IF ( nILev > 0 ) THEN
        3668           0 :           CALL NcDef_Dimension( fId, 'ilev', nIlev, iLevId )
        3669             :        ELSE
        3670           0 :           iLevId = -1
        3671             :        ENDIF
        3672             :     ENDIF
        3673             :
        3674             :     ! Lat and lon
        3675           0 :     CALL NcDef_Dimension( fId, 'lat',  nLat,  latId  )
        3676           0 :     CALL NcDef_Dimension( fId, 'lon',  nLon,  lonId  )
        3677             :
        3678             :     ! Close definition section
        3679           0 :     IF ( QuitDefMode ) THEN
        3680           0 :        CALL NcEnd_Def( fId )
        3681             :     ENDIF
        3682             :
        3683             :     ! Initialize variable counter
        3684           0 :     VarCt = -1
        3685             :
        3686           0 :   END SUBROUTINE Nc_Create
        3687             : !EOC
        3688             : !------------------------------------------------------------------------------
        3689             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        3690             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        3691             : !------------------------------------------------------------------------------
        3692             : !BOP
        3693             : !
        3694             : ! !IROUTINE: Nc_Var_Def
        3695             : !
        3696             : ! !DESCRIPTION: Defines a new netCDF variable along with its attributes.
        3697             : !\\
        3698             : !\\
        3699             : ! !INTERFACE:
        3700             : !
        3701           0 :   SUBROUTINE NC_Var_Def( fId,       lonId,        latId,        levId,       &
        3702             :                          TimeId,    VarName,      VarLongName,  VarUnit,     &
        3703             :                          DataType,  VarCt,        DefMode,      Compress,    &
        3704             :                          AddOffset, MissingValue, ScaleFactor,  Calendar,    &
        3705             :                          Axis,      StandardName, FormulaTerms, AvgMethod,   &
        3706             :                          Positive,  iLevId,       nUpdates                  )
        3707             : !
        3708             : ! !INPUT PARAMETERS:
        3709             : !
        3710             :     ! Required inputs
        3711             :     INTEGER,          INTENT(IN   ) :: fId          ! file ID
        3712             :     INTEGER,          INTENT(IN   ) :: lonId        ! ID of lon      (X) dim
        3713             :     INTEGER,          INTENT(IN   ) :: latId        ! ID of lat      (Y) dim
        3714             :     INTEGER,          INTENT(IN   ) :: levId        ! ID of lev ctr  (Z) dim
        3715             :     INTEGER,          OPTIONAL      :: iLevId       ! ID of lev edge (I) dim
        3716             :     INTEGER,          INTENT(IN   ) :: TimeId       ! ID of time     (T) dim
        3717             :     CHARACTER(LEN=*), INTENT(IN   ) :: VarName      ! Variable name
        3718             :     CHARACTER(LEN=*), INTENT(IN   ) :: VarLongName  ! Long name description
        3719             :     CHARACTER(LEN=*), INTENT(IN   ) :: VarUnit      ! Units
        3720             :     INTEGER,          INTENT(IN   ) :: DataType     ! 1=Int, 4=float, 8=double
        3721             :
        3722             :     ! Optional inputs
        3723             :     LOGICAL,          OPTIONAL      :: DefMode      ! Toggles define mode
        3724             :     LOGICAL,          OPTIONAL      :: Compress     ! Toggles compression
        3725             :     REAL*4,           OPTIONAL      :: AddOffset    ! Add offset attribute
        3726             :     REAL*4,           OPTIONAL      :: MissingValue ! Missing value attribute
        3727             :     REAL*4,           OPTIONAL      :: ScaleFactor  ! Scale factor attribute
        3728             :     CHARACTER(LEN=*), OPTIONAL      :: Calendar     ! Calendar for time var
        3729             :     CHARACTER(LEN=*), OPTIONAL      :: Axis         ! Axis for index vars
        3730             :     CHARACTER(LEN=*), OPTIONAL      :: StandardName ! Standard name attribute
        3731             :     CHARACTER(LEN=*), OPTIONAL      :: FormulaTerms ! Formula for vert coords
        3732             :     CHARACTER(LEN=*), OPTIONAL      :: AvgMethod    ! Averaging method
        3733             :     CHARACTER(LEN=*), OPTIONAL      :: Positive     ! Positive dir (up or down)
        3734             :     REAL*4,           OPTIONAL      :: nUpdates     ! # of updates (for time-
        3735             :                                                     !  averaged fields only)
        3736             : !
        3737             : ! !INPUT/OUTPUT PARAMETERS:
        3738             : !
        3739             :     INTEGER,          INTENT(INOUT) :: VarCt        ! variable counter
        3740             : !
        3741             : ! !REMARKS:
        3742             : !  Assumes that you have:
        3743             : !  (1) A netCDF library (either v3 or v4) installed on your system
        3744             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        3745             : !
        3746             : ! !REVISION HISTORY:
        3747             : !  See https://github.com/geoschem/hemco for complete history
        3748             : !EOP
        3749             : !------------------------------------------------------------------------------
        3750             : !BOC
        3751             : !
        3752             : ! !LOCAL VARIABLES:
        3753             : !
        3754             :     ! Arrays
        3755           0 :     INTEGER, ALLOCATABLE :: VarDims(:)
        3756             :
        3757             :     ! Scalars
        3758             :     INTEGER              :: nDim,     Pos
        3759             :     INTEGER              :: NF90_TYPE,  tmpIlevId
        3760             :     LOGICAL              :: isDefMode
        3761             :
        3762             :     ! Strings
        3763             :     CHARACTER(LEN=80)    :: Att
        3764             :
        3765             :     !=======================================================================
        3766             :     ! Initialize
        3767             :     !=======================================================================
        3768             :
        3769             :     ! Assume file is not in define mode unless explicitly told otherwise
        3770           0 :     IF ( PRESENT( DefMode ) ) THEN
        3771           0 :        isDefMode = DefMode
        3772             :     ELSE
        3773             :        isDefMode = .FALSE.
        3774             :     ENDIF
        3775             :
        3776             :     ! Test if iLevId (dimension for level interfaces) is present
        3777           0 :     IF ( PRESENT( iLevId ) ) THEN
        3778           0 :        tmpIlevId = iLevId
        3779             :     ELSE
        3780             :        tmpIlevId = -1
        3781             :     ENDIF
        3782             :
        3783             :     !=======================================================================
        3784             :     ! DEFINE VARIABLE
        3785             :     !=======================================================================
        3786             :
        3787             :     ! Reopen definition section, if necessary
        3788           0 :     IF ( .not. isDefMode ) CALL NcBegin_Def( fId )
        3789             :
        3790           0 :     VarCt = VarCt + 1
        3791             :
        3792             :     ! number of dimensions
        3793           0 :     nDim = 0
        3794           0 :     IF ( lonId     >= 0 ) nDim = nDim + 1
        3795           0 :     IF ( latId     >= 0 ) nDim = nDim + 1
        3796           0 :     IF ( levId     >= 0 ) nDim = nDim + 1
        3797           0 :     IF ( tmpIlevId >= 0 ) nDim = nDim + 1
        3798           0 :     if ( timeId    >= 0 ) nDim = nDim + 1
        3799             :
        3800             :     ! write dimensions
        3801           0 :     ALLOCATE( VarDims(nDim) )
        3802           0 :     Pos = 1
        3803           0 :     IF ( lonId >= 0 ) THEN
        3804           0 :        VarDims(Pos) = lonId
        3805           0 :        Pos          = Pos + 1
        3806             :     ENDIF
        3807           0 :     IF ( latId >= 0 ) THEN
        3808           0 :        VarDims(Pos) = latId
        3809           0 :        Pos          = Pos + 1
        3810             :     ENDIF
        3811           0 :     IF ( levId >= 0 ) THEN
        3812           0 :        VarDims(Pos) = levId
        3813           0 :        Pos          = Pos + 1
        3814             :     ENDIF
        3815           0 :     IF ( tmpIlevId >= 0 ) THEN
        3816           0 :        VarDims(Pos) = tmpIlevId
        3817           0 :        Pos          = Pos + 1
        3818             :     ENDIF
        3819           0 :     IF ( timeId >= 0 ) THEN
        3820           0 :        VarDims(Pos) = timeId
        3821           0 :        Pos          = Pos + 1
        3822             :     ENDIF
        3823             :
        3824             :     ! Set data type
        3825           0 :     IF ( DataType == 1 ) THEN
        3826           0 :        NF90_TYPE = NF90_INT
        3827           0 :     ELSEIF ( DataType == 4 ) THEN
        3828           0 :        NF90_TYPE = NF90_FLOAT
        3829           0 :     ELSEIF ( DataType == 8 ) THEN
        3830           0 :        NF90_TYPE = NF90_DOUBLE
        3831             :     ELSE
        3832           0 :        NF90_TYPE = NF90_FLOAT
        3833             :     ENDIF
        3834             :
        3835             :     !-----------------------------------------------------------------------
        3836             :     ! Define variable
        3837             :     !-----------------------------------------------------------------------
        3838             :     CALL NcDef_Variable( fId,  TRIM(VarName), NF90_TYPE,                     &
        3839           0 :                          nDim, VarDims,       VarCt,      Compress          )
        3840           0 :     DEALLOCATE( VarDims )
        3841             :
        3842             :     !-----------------------------------------------------------------------
        3843             :     ! Define variable atttibutes (some are optional)
        3844             :     !-----------------------------------------------------------------------
        3845             :
        3846             :     ! long_name (reuired)
        3847           0 :     Att = 'long_name'
        3848           0 :     CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), TRIM(VarLongName) )
        3849             :
        3850             :     ! units (requited)
        3851           0 :     Att = 'units'
        3852           0 :     CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att),  TRIM(VarUnit) )
        3853             :
        3854             :     ! add_offset (optional)
        3855           0 :     IF ( PRESENT( AddOffset ) ) THEN
        3856           0 :        Att = 'add_offset'
        3857           0 :        CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), AddOffset )
        3858             :     ENDIF
        3859             :
        3860             :     ! scale_factor (optional)
        3861           0 :     IF ( PRESENT( ScaleFactor ) ) THEN
        3862           0 :        Att = 'scale_factor'
        3863           0 :        CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), ScaleFactor )
        3864             :     ENDIF
        3865             :
        3866             :     ! missing_value (optional but recommended)
        3867           0 :     IF ( PRESENT( MissingValue ) ) THEN
        3868           0 :        Att = '_FillValue'
        3869           0 :        CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att),  MissingValue )
        3870             :     ENDIF
        3871             :
        3872             :     ! calendar (only used for time) -- skip if null string
        3873           0 :     IF ( PRESENT( Calendar ) ) THEN
        3874           0 :        IF ( LEN_TRIM( Calendar ) > 0 ) THEN
        3875           0 :           Att = 'calendar'
        3876           0 :           CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), TRIM(Calendar) )
        3877             :        ENDIF
        3878             :     ENDIF
        3879             :
        3880             :     ! axis (only used for index variables) -- skip if null string
        3881           0 :     IF ( PRESENT( Axis ) ) THEN
        3882           0 :        IF ( LEN_TRIM( Axis ) > 0 ) THEN
        3883           0 :           Att = 'axis'
        3884           0 :           CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), TRIM(Axis) )
        3885             :        ENDIF
        3886             :     ENDIF
        3887             :
        3888             :     ! averaging_method (optional) -- skip if null string
        3889           0 :     IF ( PRESENT( AvgMethod ) ) THEN
        3890           0 :        IF ( LEN_TRIM( AvgMethod ) > 0 ) THEN
        3891           0 :           Att = 'averaging_method'
        3892           0 :           CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), TRIM(AvgMethod) )
        3893             :        ENDIF
        3894             :     ENDIF
        3895             :
        3896             :     ! averaging_method (optional) -- skip if null string
        3897           0 :     IF ( PRESENT( Positive ) ) THEN
        3898           0 :        IF ( LEN_TRIM( Positive ) > 0 ) THEN
        3899           0 :           Att = 'positive'
        3900           0 :           CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), TRIM(Positive) )
        3901             :        ENDIF
        3902             :     ENDIF
        3903             :
        3904             :     ! Standard name (optional) -- skip if null string
        3905           0 :     IF ( PRESENT( StandardName ) ) THEN
        3906           0 :        IF ( LEN_TRIM( StandardName ) > 0 ) THEN
        3907           0 :           Att = 'standard_name'
        3908           0 :           CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), TRIM(StandardName))
        3909             :        ENDIF
        3910             :     ENDIF
        3911             :
        3912             :     ! Formula terms (optional) -- skip if null string
        3913           0 :     IF ( PRESENT( FormulaTerms ) ) THEN
        3914           0 :        IF ( LEN_TRIM( FormulaTerms ) > 0 ) THEN
        3915           0 :           Att = 'formula_terms'
        3916           0 :           CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), TRIM(FormulaTerms))
        3917             :        ENDIF
        3918             :     ENDIF
        3919             :
        3920             :     ! Number of updates
        3921           0 :     IF ( PRESENT( nUpdates ) ) THEN
        3922           0 :        IF ( nUpdates > 0.0 ) THEN
        3923           0 :           Att = 'number_of_updates'
        3924           0 :           CALL NcDef_Var_Attributes( fId, VarCt, TRIM(Att), nUpdates )
        3925             :        ENDIF
        3926             :     ENDIF
        3927             :
        3928             :     ! Close definition section, if necessary
        3929           0 :     IF ( .not. isDefMode ) CALL NcEnd_Def( fId )
        3930             :
        3931           0 :   END SUBROUTINE NC_Var_Def
        3932             : !EOC
        3933             : !------------------------------------------------------------------------------
        3934             : !                  GEOS-Chem Global Chemical Transport Model                  !
        3935             : !------------------------------------------------------------------------------
        3936             : !BOP
        3937             : !
        3938             : ! !IROUTINE: Nc_Var_Chunk
        3939             : !
        3940             : ! !DESCRIPTION: Turns on chunking for a netCDF variable.
        3941             : !\\
        3942             : !\\
        3943             : ! !INTERFACE:
        3944             : !
        3945           0 :   SUBROUTINE Nc_Var_Chunk( fId, vId, ChunkSizes, RC )
        3946             : !
        3947             : ! !INPUT PARAMETERS:
        3948             : !
        3949             :     INTEGER, INTENT(IN)  :: fId            ! NetCDF file ID
        3950             :     INTEGER, INTENT(IN)  :: vId            ! NetCDF variable ID
        3951             :     INTEGER, INTENT(IN)  :: ChunkSizes(:)  ! NetCDF chunk sizes for each dim
        3952             : !
        3953             : ! !OUTPUT PARAMETERS:
        3954             : !
        3955             :     INTEGER, INTENT(OUT) :: RC             ! Success or failure?
        3956             : !
        3957             : ! !REMARKS:
        3958             : !  RC will return an error (nonzero) status if chunking cannot be activated.
        3959             : !  Most often, this is because support for netCDF-4 compression is disabled,
        3960             : !  or if the netCDF file is not a netCDF-4 file.  In this case, RC will have
        3961             : !  an error code of -111.
        3962             : !
        3963             : ! !REVISION HISTORY:
        3964             : !  See https://github.com/geoschem/hemco for complete history
        3965             : !EOP
        3966             : !------------------------------------------------------------------------------
        3967             : !BOC
        3968             : !
        3969             : ! !LOCAL VARIABLES:
        3970             : !
        3971             : #if defined( NC_HAS_COMPRESSION )
        3972             :
        3973             :     ! Turn on chunking for this variable
        3974             :     ! But only if the netCDF library supports it
        3975             :     RC = NF90_Def_Var_Chunking( fId, vId, NF90_CHUNKED, ChunkSizes )
        3976             :
        3977             : #else
        3978             :
        3979             :     ! Otherwise return success
        3980           0 :     RC = 0
        3981             :
        3982             : #endif
        3983             :
        3984           0 :   END SUBROUTINE Nc_Var_Chunk
        3985             : !EOC
        3986             : !------------------------------------------------------------------------------
        3987             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        3988             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        3989             : !------------------------------------------------------------------------------
        3990             : !BOP
        3991             : !
        3992             : ! !IROUTINE: Nc_Var_Write_R8_0d
        3993             : !
        3994             : ! !DESCRIPTION: Writes data of a 0-D double precision variable.
        3995             : !\\
        3996             : !\\
        3997             : ! !INTERFACE:
        3998             : !
        3999           0 :   SUBROUTINE NC_VAR_WRITE_R8_0D( fId, VarName, Var )
        4000             : !
        4001             : ! !INPUT PARAMETERS:
        4002             : !
        4003             :     INTEGER,          INTENT(IN)  :: fId           ! file ID
        4004             :     CHARACTER(LEN=*), INTENT(IN)  :: VarName       ! variable name
        4005             :     REAL(kind=dp)                 :: Var           ! Variable to be written
        4006             : !
        4007             : ! !REMARKS:
        4008             : !  Assumes that you have:
        4009             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4010             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4011             : !                                                                             .
        4012             : !  Although this routine was generated automatically, some further
        4013             : !  hand-editing may be required.
        4014             : !
        4015             : ! !REVISION HISTORY:
        4016             : !  See https://github.com/geoschem/hemco for complete history
        4017             : !EOP
        4018             : !------------------------------------------------------------------------------
        4019             : !BOC
        4020             : !
        4021             : ! !LOCAL VARIABLES:
        4022             : !
        4023             :     !--------------------------------
        4024             :     ! WRITE DATA
        4025             :     !--------------------------------
        4026             :
        4027             :     ! Write to netCDF file
        4028           0 :     CALL NcWr( Var, fId, VarName )
        4029             :
        4030           0 :   END SUBROUTINE NC_VAR_WRITE_R8_0d
        4031             : !EOC
        4032             : !------------------------------------------------------------------------------
        4033             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4034             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4035             : !------------------------------------------------------------------------------
        4036             : !BOP
        4037             : !
        4038             : ! !IROUTINE: Nc_Var_Write_R8_1d
        4039             : !
        4040             : ! !DESCRIPTION: Writes data of a 1-D double precision variable.
        4041             : !\\
        4042             : !\\
        4043             : ! !INTERFACE:
        4044             : !
        4045           0 :   SUBROUTINE NC_VAR_WRITE_R8_1D( fId, VarName, Arr1D )
        4046             : !
        4047             : ! !INPUT PARAMETERS:
        4048             : !
        4049             :     INTEGER,          INTENT(IN)  :: fId           ! file ID
        4050             :     CHARACTER(LEN=*), INTENT(IN)  :: VarName       ! variable name
        4051             :     REAL(kind=dp),    POINTER     :: Arr1D(:)      ! array to be written
        4052             : !
        4053             : ! !REMARKS:
        4054             : !  Assumes that you have:
        4055             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4056             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4057             : !                                                                             .
        4058             : !  Although this routine was generated automatically, some further
        4059             : !  hand-editing may be required.
        4060             : !
        4061             : ! !REVISION HISTORY:
        4062             : !  See https://github.com/geoschem/hemco for complete history
        4063             : !EOP
        4064             : !------------------------------------------------------------------------------
        4065             : !BOC
        4066             : !
        4067             : ! !LOCAL VARIABLES:
        4068             : !
        4069             :     ! Arrays
        4070             :     INTEGER :: St1d(1), Ct1d(1)
        4071             :
        4072             :     !--------------------------------
        4073             :     ! WRITE DATA
        4074             :     !--------------------------------
        4075             :
        4076             :     ! Set start & count arrays
        4077           0 :     St1d(1) = 1
        4078           0 :     Ct1d(1) = SIZE( Arr1d, 1 )
        4079             :
        4080             :     ! Write to netCDF file
        4081           0 :     CALL NcWr( Arr1d, fId, VarName, St1d, Ct1d )
        4082             :
        4083           0 :   END SUBROUTINE NC_VAR_WRITE_R8_1D
        4084             : !EOC
        4085             : !------------------------------------------------------------------------------
        4086             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4087             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4088             : !------------------------------------------------------------------------------
        4089             : !BOP
        4090             : !
        4091             : ! !IROUTINE: Nc_Var_Write_R8_2d
        4092             : !
        4093             : ! !DESCRIPTION: Writes data of a 2-D double precision variable.
        4094             : !\\
        4095             : !\\
        4096             : ! !INTERFACE:
        4097             : !
        4098           0 :   SUBROUTINE NC_VAR_WRITE_R8_2D( fId, VarName, Arr2D )
        4099             : !
        4100             : ! !INPUT PARAMETERS:
        4101             : !
        4102             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4103             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4104             :     REAL(kind=dp),    POINTER    :: Arr2D(:,:)     ! array to be written
        4105             : !
        4106             : ! !REMARKS:
        4107             : !  Assumes that you have:
        4108             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4109             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4110             : !                                                                             .
        4111             : !  Although this routine was generated automatically, some further
        4112             : !  hand-editing may be required.
        4113             : !
        4114             : ! !REVISION HISTORY:
        4115             : !  See https://github.com/geoschem/hemco for complete history
        4116             : !EOP
        4117             : !------------------------------------------------------------------------------
        4118             : !BOC
        4119             : !
        4120             : ! !LOCAL VARIABLES:
        4121             : !
        4122             :     ! Arrays
        4123             :     INTEGER :: St2d(2), Ct2d(2)
        4124             :
        4125             :     ! Scalars
        4126             :     INTEGER :: I,       nDim
        4127             :
        4128             :     !--------------------------------
        4129             :     ! WRITE DATA
        4130             :     !--------------------------------
        4131             :
        4132             :     ! Set start & count arrays
        4133           0 :     nDim = 2
        4134           0 :     DO I =1, nDim
        4135           0 :        St2d(I) = 1
        4136           0 :        Ct2d(I) = SIZE( Arr2d, I )
        4137             :     ENDDO
        4138             :
        4139             :     ! Write to netCDF file
        4140           0 :     CALL NcWr( Arr2d, fId, VarName, St2d, Ct2d )
        4141             :
        4142           0 :   END SUBROUTINE NC_VAR_WRITE_R8_2D
        4143             : !EOC
        4144             : !------------------------------------------------------------------------------
        4145             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4146             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4147             : !------------------------------------------------------------------------------
        4148             : !BOP
        4149             : !
        4150             : ! !IROUTINE: Nc_Var_Write_R8_3D
        4151             : !
        4152             : ! !DESCRIPTION: Writes data of a 3-D double precision variable.
        4153             : !\\
        4154             : !\\
        4155             : ! !INTERFACE:
        4156             : !
        4157           0 :   SUBROUTINE NC_VAR_WRITE_R8_3D( fId, VarName, Arr3D )
        4158             : !
        4159             : ! !INPUT PARAMETERS:
        4160             : !
        4161             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4162             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4163             :     REAL(kind=dp),    POINTER    :: Arr3D(:,:,:)   ! array to be written
        4164             : !
        4165             : ! !REMARKS:
        4166             : !  Assumes that you have:
        4167             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4168             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4169             : !                                                                             .
        4170             : !  Although this routine was generated automatically, some further
        4171             : !  hand-editing may be required.
        4172             : !
        4173             : ! !REVISION HISTORY:
        4174             : !  See https://github.com/geoschem/hemco for complete history
        4175             : !EOP
        4176             : !------------------------------------------------------------------------------
        4177             : !BOC
        4178             : !
        4179             : ! !LOCAL VARIABLES:
        4180             : !
        4181             :     ! Arrays
        4182             :     INTEGER :: St3d(3), Ct3d(3)
        4183             :
        4184             :     ! Scalars
        4185             :     INTEGER :: I,       nDim
        4186             :
        4187             :     !--------------------------------
        4188             :     ! WRITE DATA
        4189             :     !--------------------------------
        4190             :
        4191             :     ! Set start & count arrays
        4192           0 :     nDim = 3
        4193           0 :     DO I = 1, nDim
        4194           0 :        St3d(I) = 1
        4195           0 :        Ct3d(I) = SIZE( Arr3d, I )
        4196             :     ENDDO
        4197             :
        4198             :     ! Write data to netCDF file
        4199           0 :     CALL NcWr( Arr3d, fId, VarName, St3d, Ct3d )
        4200             :
        4201           0 :   END SUBROUTINE NC_VAR_WRITE_R8_3D
        4202             : !EOC
        4203             : !------------------------------------------------------------------------------
        4204             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4205             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4206             : !------------------------------------------------------------------------------
        4207             : !BOP
        4208             : !
        4209             : ! !IROUTINE: Nc_Var_Write_r8_4d
        4210             : !
        4211             : ! !DESCRIPTION: Writes data of a 4-D double precision variable.
        4212             : !\\
        4213             : !\\
        4214             : ! !INTERFACE:
        4215             : !
        4216           0 :   SUBROUTINE NC_VAR_WRITE_R8_4D( fId, VarName, Arr4D )
        4217             : !
        4218             : ! !INPUT PARAMETERS:
        4219             : !
        4220             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4221             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4222             :     REAL(kind=dp),    POINTER    :: Arr4D(:,:,:,:) ! array to be written
        4223             : !
        4224             : ! !REMARKS:
        4225             : !  Assumes that you have:
        4226             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4227             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4228             : !                                                                             .
        4229             : !  Although this routine was generated automatically, some further
        4230             : !  hand-editing may be required.
        4231             : !
        4232             : ! !REVISION HISTORY:
        4233             : !  See https://github.com/geoschem/hemco for complete history
        4234             : !EOP
        4235             : !------------------------------------------------------------------------------
        4236             : !BOC
        4237             : !
        4238             : ! !LOCAL VARIABLES:
        4239             : !
        4240             :     ! Arrays
        4241             :     INTEGER :: St4d(4), Ct4d(4)
        4242             :
        4243             :     ! Scalars
        4244             :     INTEGER :: I,       nDim
        4245             :
        4246             :     !--------------------------------
        4247             :     ! WRITE DATA
        4248             :     !--------------------------------
        4249             :
        4250             :     ! Set start & count arrays
        4251           0 :     nDim = 4
        4252           0 :     DO I = 1, nDim
        4253           0 :        St4d(I) = 1
        4254           0 :        Ct4d(I) = SIZE( Arr4d, I )
        4255             :     ENDDO
        4256             :
        4257             :     ! Write to netCDF file
        4258           0 :     CALL NcWr( Arr4d, fId, VarName, St4d, Ct4d )
        4259             :
        4260           0 :   END SUBROUTINE NC_VAR_WRITE_R8_4D
        4261             : !EOC
        4262             : !------------------------------------------------------------------------------
        4263             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4264             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4265             : !------------------------------------------------------------------------------
        4266             : !BOP
        4267             : !
        4268             : ! !IROUTINE: Nc_Var_Write_R4_0d
        4269             : !
        4270             : ! !DESCRIPTION: Writes data of a 0-D single-precision variable.
        4271             : !\\
        4272             : !\\
        4273             : ! !INTERFACE:
        4274             : !
        4275           0 :   SUBROUTINE NC_VAR_WRITE_R4_0d( fId, VarName, Var )
        4276             : !
        4277             : ! !INPUT PARAMETERS:
        4278             : !
        4279             :     INTEGER,          INTENT(IN)  :: fId           ! file ID
        4280             :     CHARACTER(LEN=*), INTENT(IN)  :: VarName       ! variable name
        4281             :     REAL(kind=sp)                 :: Var           ! Variable to be written
        4282             : !
        4283             : ! !REMARKS:
        4284             : !  Assumes that you have:
        4285             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4286             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4287             : !                                                                             .
        4288             : !  Although this routine was generated automatically, some further
        4289             : !  hand-editing may be required.
        4290             : !
        4291             : ! !REVISION HISTORY:
        4292             : !  See https://github.com/geoschem/hemco for complete history
        4293             : !EOP
        4294             : !------------------------------------------------------------------------------
        4295             : !BOC
        4296             : !
        4297             : ! !LOCAL VARIABLES:
        4298             : !
        4299             :     !--------------------------------
        4300             :     ! WRITE DATA
        4301             :     !--------------------------------
        4302             :
        4303             :     ! Write to netCDF file
        4304           0 :     CALL NcWr( Var, fId, VarName )
        4305             :
        4306           0 :   END SUBROUTINE NC_VAR_WRITE_R4_0D
        4307             : !EOC
        4308             : !------------------------------------------------------------------------------
        4309             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4310             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4311             : !------------------------------------------------------------------------------
        4312             : !BOP
        4313             : !
        4314             : ! !IROUTINE: Nc_Var_Write_r4_1d
        4315             : !
        4316             : ! !DESCRIPTION: Writes data of a single precision variable.
        4317             : !\\
        4318             : !\\
        4319             : ! !INTERFACE:
        4320             : !
        4321           0 :   SUBROUTINE NC_VAR_WRITE_R4_1D( fId, VarName, Arr1D )
        4322             : !
        4323             : ! !INPUT PARAMETERS:
        4324             : !
        4325             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4326             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4327             :     REAL(kind=sp),    POINTER    :: Arr1D(:)       ! array to be written
        4328             : !
        4329             : ! !REMARKS:
        4330             : !  Assumes that you have:
        4331             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4332             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4333             : !                                                                             .
        4334             : !  Although this routine was generated automatically, some further
        4335             : !  hand-editing may be required.
        4336             : !
        4337             : ! !REVISION HISTORY:
        4338             : !  See https://github.com/geoschem/hemco for complete history
        4339             : !EOP
        4340             : !------------------------------------------------------------------------------
        4341             : !BOC
        4342             : !
        4343             : ! !LOCAL VARIABLES:
        4344             : !
        4345             :     ! Arrays
        4346             :     INTEGER :: St1d(1), Ct1d(1)
        4347             :
        4348             :     !--------------------------------
        4349             :     ! WRITE DATA
        4350             :     !--------------------------------
        4351             :
        4352             :     ! Set start & count arrays
        4353           0 :     St1d(1) = 1
        4354           0 :     Ct1d(1) = SIZE( Arr1d, 1 )
        4355             :
        4356             :     ! Write to netCDF file
        4357           0 :     CALL NcWr( Arr1d, fId, VarName, St1d, Ct1d )
        4358             :
        4359           0 :   END SUBROUTINE NC_VAR_WRITE_R4_1D
        4360             : !EOC
        4361             : !------------------------------------------------------------------------------
        4362             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4363             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4364             : !------------------------------------------------------------------------------
        4365             : !BOP
        4366             : !
        4367             : ! !IROUTINE: Nc_Var_Write_r4_2D
        4368             : !
        4369             : ! !DESCRIPTION: Writes data of a 2-D single precision variable.
        4370             : !\\
        4371             : !\\
        4372             : ! !INTERFACE:
        4373             : !
        4374           0 :   SUBROUTINE NC_VAR_WRITE_R4_2D( fId, VarName, Arr2D )
        4375             : !
        4376             : ! !INPUT PARAMETERS:
        4377             : !
        4378             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4379             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4380             :     REAL(kind=sp),    POINTER    :: Arr2D(:,:)     ! array to be written
        4381             : !
        4382             : ! !REMARKS:
        4383             : !  Assumes that you have:
        4384             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4385             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4386             : !                                                                             .
        4387             : !  Although this routine was generated automatically, some further
        4388             : !  hand-editing may be required.
        4389             : !
        4390             : ! !REVISION HISTORY:
        4391             : !  See https://github.com/geoschem/hemco for complete history
        4392             : !EOP
        4393             : !------------------------------------------------------------------------------
        4394             : !BOC
        4395             : !
        4396             : ! !LOCAL VARIABLES:
        4397             : !
        4398             :     ! Arrays
        4399             :     INTEGER :: St2d(2), Ct2d(2)
        4400             :
        4401             :     ! Scalars
        4402             :     INTEGER :: I,       nDim
        4403             :
        4404             :     !--------------------------------
        4405             :     ! WRITE DATA
        4406             :     !--------------------------------
        4407             :
        4408             :     ! Set start & count arrays
        4409           0 :     nDim = 2
        4410           0 :     DO I = 1, nDim
        4411           0 :        St2d(I) = 1
        4412           0 :        Ct2d(I) = SIZE( Arr2d, I )
        4413             :     ENDDO
        4414             :
        4415             :     ! Write to netCDF file
        4416           0 :     CALL NcWr( Arr2d, fId, VarName, St2d, Ct2d )
        4417             :
        4418           0 :   END SUBROUTINE NC_VAR_WRITE_R4_2D
        4419             : !EOC
        4420             : !------------------------------------------------------------------------------
        4421             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4422             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4423             : !------------------------------------------------------------------------------
        4424             : !BOP
        4425             : !
        4426             : ! !IROUTINE: Nc_Var_Write_r4_3d
        4427             : !
        4428             : ! !DESCRIPTION: Writes data of a 3-D single precision variable.
        4429             : !\\
        4430             : !\\
        4431             : ! !INTERFACE:
        4432             : !
        4433           0 :   SUBROUTINE NC_VAR_WRITE_R4_3D( fId, VarName, Arr3D )
        4434             : !
        4435             : ! !INPUT PARAMETERS:
        4436             : !
        4437             :     INTEGER,          INTENT(IN)  :: fId            ! file ID
        4438             :     CHARACTER(LEN=*), INTENT(IN)  :: VarName        ! variable name
        4439             :     REAL(kind=sp),    POINTER     :: Arr3D(:,:,:)   ! array to be written
        4440             : !
        4441             : ! !REMARKS:
        4442             : !  Assumes that you have:
        4443             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4444             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4445             : !                                                                             .
        4446             : !  Although this routine was generated automatically, some further
        4447             : !  hand-editing may be required.
        4448             : !
        4449             : ! !REVISION HISTORY:
        4450             : !  See https://github.com/geoschem/hemco for complete history
        4451             : !EOP
        4452             : !------------------------------------------------------------------------------
        4453             : !BOC
        4454             : !
        4455             : ! !LOCAL VARIABLES:
        4456             : !
        4457             :     ! Arrays
        4458             :     INTEGER :: St3d(3), Ct3d(3)
        4459             :
        4460             :     ! Scalars
        4461             :     INTEGER :: I, nDim
        4462             :
        4463             :     !--------------------------------
        4464             :     ! WRITE DATA
        4465             :     !--------------------------------
        4466             :
        4467             :     ! Set start & count arrays
        4468           0 :     nDim = 3
        4469           0 :     DO I = 1, nDim
        4470           0 :        St3d(I) = 1
        4471           0 :        Ct3d(I) = SIZE( Arr3d, I )
        4472             :     ENDDO
        4473             :
        4474             :     ! Write to netCDF file
        4475           0 :     CALL NcWr( Arr3d, fId, VarName, St3d, Ct3d )
        4476             :
        4477           0 :   END SUBROUTINE NC_VAR_WRITE_R4_3D
        4478             : !EOC
        4479             : !------------------------------------------------------------------------------
        4480             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4481             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4482             : !------------------------------------------------------------------------------
        4483             : !BOP
        4484             : !
        4485             : ! !IROUTINE: Nc_Var_Write_r4_4d
        4486             : !
        4487             : ! !DESCRIPTION: Writes data of a 4-D single precision variable.
        4488             : !\\
        4489             : !\\
        4490             : ! !INTERFACE:
        4491             : !
        4492           0 :   SUBROUTINE NC_VAR_WRITE_R4_4D( fId, VarName, Arr4D )
        4493             : !
        4494             : ! !INPUT PARAMETERS:
        4495             : !
        4496             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4497             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4498             :     REAL(kind=sp),    POINTER    :: Arr4D(:,:,:,:) ! array to be written
        4499             : !
        4500             : ! !REMARKS:
        4501             : !  Assumes that you have:
        4502             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4503             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4504             : !                                                                             .
        4505             : !  Although this routine was generated automatically, some further
        4506             : !  hand-editing may be required.
        4507             : !
        4508             : ! !REVISION HISTORY:
        4509             : !  See https://github.com/geoschem/hemco for complete history
        4510             : !EOP
        4511             : !------------------------------------------------------------------------------
        4512             : !BOC
        4513             : !
        4514             : ! !LOCAL VARIABLES:
        4515             : !
        4516             :     ! Arrays
        4517             :     INTEGER :: St4d(4), Ct4d(4)
        4518             :
        4519             :     ! Scalars
        4520             :     INTEGER :: I,       nDim
        4521             :
        4522             :     !--------------------------------
        4523             :     ! WRITE DATA
        4524             :     !--------------------------------
        4525             :
        4526           0 :     nDim = 4
        4527           0 :     DO I = 1, nDim
        4528           0 :        St4d(I) = 1
        4529           0 :        Ct4d(I) = SIZE( Arr4d, I )
        4530             :     ENDDO
        4531             :
        4532             :     ! Write to netCDF file
        4533           0 :     CALL NcWr( Arr4d, fId, VarName, St4d, Ct4d )
        4534             :
        4535           0 :   END SUBROUTINE NC_VAR_WRITE_R4_4D
        4536             : !EOC
        4537             : !------------------------------------------------------------------------------
        4538             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4539             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4540             : !------------------------------------------------------------------------------
        4541             : !BOP
        4542             : !
        4543             : ! !IROUTINE: Nc_Var_Write_Int_0d
        4544             : !
        4545             : ! !DESCRIPTION: Writes data of a 0-D integer variable.
        4546             : !\\
        4547             : !\\
        4548             : ! !INTERFACE:
        4549             : !
        4550           0 :   SUBROUTINE NC_VAR_WRITE_INT_0d( fId, VarName, Var )
        4551             : !
        4552             : ! !INPUT PARAMETERS:
        4553             : !
        4554             :     INTEGER,          INTENT(IN)  :: fId           ! file ID
        4555             :     CHARACTER(LEN=*), INTENT(IN)  :: VarName       ! variable name
        4556             :     INTEGER                       :: Var           ! Variable to be written
        4557             : !
        4558             : ! !REMARKS:
        4559             : !  Assumes that you have:
        4560             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4561             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4562             : !                                                                             .
        4563             : !  Although this routine was generated automatically, some further
        4564             : !  hand-editing may be required.
        4565             : !
        4566             : ! !REVISION HISTORY:
        4567             : !  See https://github.com/geoschem/hemco for complete history
        4568             : !EOP
        4569             : !------------------------------------------------------------------------------
        4570             : !BOC
        4571             : !
        4572             : ! !LOCAL VARIABLES:
        4573             : !
        4574             :     !--------------------------------
        4575             :     ! WRITE DATA
        4576             :     !--------------------------------
        4577             :
        4578             :     ! Write to netCDF file
        4579           0 :     CALL NcWr( Var, fId, VarName )
        4580             :
        4581           0 :   END SUBROUTINE NC_VAR_WRITE_INT_0D
        4582             : !EOC
        4583             : !------------------------------------------------------------------------------
        4584             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4585             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4586             : !------------------------------------------------------------------------------
        4587             : !BOP
        4588             : !
        4589             : ! !IROUTINE: Nc_Var_Write_int_1d
        4590             : !
        4591             : ! !DESCRIPTION: Writes data of an 1-D integer variable.
        4592             : !\\
        4593             : !\\
        4594             : ! !INTERFACE:
        4595             : !
        4596           0 :   SUBROUTINE NC_VAR_WRITE_INT_1D( fId, VarName, Arr1D )
        4597             : !
        4598             : ! !INPUT PARAMETERS:
        4599             : !
        4600             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4601             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4602             :     INTEGER,          POINTER    :: Arr1D(:)       ! array to be written
        4603             : !
        4604             : ! !REMARKS:
        4605             : !  Assumes that you have:
        4606             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4607             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4608             : !                                                                             .
        4609             : !  Although this routine was generated automatically, some further
        4610             : !  hand-editing may be required.
        4611             : !
        4612             : ! !REVISION HISTORY:
        4613             : !  See https://github.com/geoschem/hemco for complete history
        4614             : !EOP
        4615             : !------------------------------------------------------------------------------
        4616             : !BOC
        4617             : !
        4618             : ! !LOCAL VARIABLES:
        4619             : !
        4620             :     ! Arrays
        4621             :     INTEGER :: St1d(1), Ct1d(1)
        4622             :
        4623             :     !--------------------------------
        4624             :     ! WRITE DATA
        4625             :     !--------------------------------
        4626             :
        4627             :     ! Set start & count arrays
        4628           0 :     St1d(1) = 1
        4629           0 :     Ct1d(1) = SIZE( Arr1d, 1 )
        4630             :
        4631             :     ! Write to netCDF file
        4632           0 :     CALL NcWr( Arr1d, fId, VarName, St1d, Ct1d )
        4633             :
        4634           0 :   END SUBROUTINE NC_VAR_WRITE_INT_1D
        4635             : !EOC
        4636             : !------------------------------------------------------------------------------
        4637             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4638             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4639             : !------------------------------------------------------------------------------
        4640             : !BOP
        4641             : !
        4642             : ! !IROUTINE: Nc_Var_Write_int_2d
        4643             : !
        4644             : ! !DESCRIPTION: writes data of an 2-D integer variable.
        4645             : !\\
        4646             : !\\
        4647             : ! !INTERFACE:
        4648             : !
        4649           0 :   SUBROUTINE NC_VAR_WRITE_INT_2D( fId, VarName, Arr2D )
        4650             : !
        4651             : ! !INPUT PARAMETERS:
        4652             : !
        4653             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4654             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4655             :     INTEGER,          POINTER    :: Arr2D(:,:)     ! array to be written
        4656             : !
        4657             : ! !REMARKS:
        4658             : !  Assumes that you have:
        4659             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4660             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4661             : !                                                                             .
        4662             : !  Although this routine was generated automatically, some further
        4663             : !  hand-editing may be required.
        4664             : !
        4665             : ! !REVISION HISTORY:
        4666             : !  See https://github.com/geoschem/hemco for complete history
        4667             : !EOP
        4668             : !------------------------------------------------------------------------------
        4669             : !BOC
        4670             : !
        4671             : ! !LOCAL VARIABLES:
        4672             : !
        4673             :     ! Arrays
        4674             :     INTEGER :: St2d(2), Ct2d(2)
        4675             :
        4676             :     ! Scalars
        4677             :     INTEGER :: I,       nDim
        4678             :
        4679             :     !--------------------------------
        4680             :     ! WRITE DATA
        4681             :     !--------------------------------
        4682             :
        4683             :     ! Set start & count arrays
        4684           0 :     nDim = 2
        4685           0 :     DO I = 1, nDim
        4686           0 :        St2d(I) = 1
        4687           0 :        Ct2d(I) = SIZE( Arr2d, I )
        4688             :     ENDDO
        4689             :
        4690             :     ! Write to netCDF file
        4691           0 :     CALL NcWr( Arr2d, fId, VarName, St2d, Ct2d )
        4692             :
        4693           0 :   END SUBROUTINE NC_VAR_WRITE_INT_2D
        4694             : !EOC
        4695             : !------------------------------------------------------------------------------
        4696             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4697             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4698             : !------------------------------------------------------------------------------
        4699             : !BOP
        4700             : !
        4701             : ! !IROUTINE: Nc_Var_Write_int_3d
        4702             : !
        4703             : ! !DESCRIPTION: writes data of an 3-D integer variable.
        4704             : !\\
        4705             : !\\
        4706             : ! !INTERFACE:
        4707             : !
        4708           0 :   SUBROUTINE NC_VAR_WRITE_INT_3D( fId, VarName, Arr3D )
        4709             : !
        4710             : ! !INPUT PARAMETERS:
        4711             : !
        4712             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4713             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4714             :     INTEGER,          POINTER    :: Arr3D(:,:,:)   ! array to be written
        4715             : !
        4716             : ! !REMARKS:
        4717             : !  Assumes that you have:
        4718             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4719             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4720             : !                                                                             .
        4721             : !  Although this routine was generated automatically, some further
        4722             : !  hand-editing may be required.
        4723             : !
        4724             : ! !REVISION HISTORY:
        4725             : !  See https://github.com/geoschem/hemco for complete history
        4726             : !EOP
        4727             : !------------------------------------------------------------------------------
        4728             : !BOC
        4729             : !
        4730             : ! !LOCAL VARIABLES:
        4731             : !
        4732             :     ! Arrays
        4733             :     INTEGER :: St3d(3), Ct3d(3)
        4734             :
        4735             :     ! Scalars
        4736             :     INTEGER :: I,       nDim
        4737             :
        4738             :     !--------------------------------
        4739             :     ! WRITE DATA
        4740             :     !--------------------------------
        4741             :
        4742             :     ! Set start & count arrays
        4743           0 :     nDim = 3
        4744           0 :     DO I = 1, nDim
        4745           0 :        St3d(I) = 1
        4746           0 :        Ct3d(I) = SIZE( Arr3d, I )
        4747             :     ENDDO
        4748             :
        4749             :     ! Write to netCDF file
        4750           0 :     CALL NcWr( Arr3d, fId, trim(VarName), St3d, Ct3d )
        4751             :
        4752           0 :   END SUBROUTINE NC_VAR_WRITE_INT_3D
        4753             : !EOC
        4754             : !------------------------------------------------------------------------------
        4755             : !       NcdfUtilities: by Harvard Atmospheric Chemistry Modeling Group        !
        4756             : !                      and NASA/GSFC, SIVO, Code 610.3                        !
        4757             : !------------------------------------------------------------------------------
        4758             : !BOP
        4759             : !
        4760             : ! !IROUTINE: Nc_Var_Write_int_4d
        4761             : !
        4762             : ! !DESCRIPTION: writes data of an 4-Dinteger variable.
        4763             : !\\
        4764             : !\\
        4765             : ! !INTERFACE:
        4766             : !
        4767           0 :   SUBROUTINE NC_VAR_WRITE_INT_4D( fId, VarName, Arr4D )
        4768             : !
        4769             : ! !INPUT PARAMETERS:
        4770             : !
        4771             :     INTEGER,          INTENT(IN) :: fId            ! file ID
        4772             :     CHARACTER(LEN=*), INTENT(IN) :: VarName        ! variable name
        4773             :     INTEGER,          POINTER    :: Arr4D(:,:,:,:) ! array to be written
        4774             : !
        4775             : ! !REMARKS:
        4776             : !  Assumes that you have:
        4777             : !  (1) A netCDF library (either v3 or v4) installed on your system
        4778             : !  (2) The NcdfUtilities package (from Bob Yantosca) source code
        4779             : !                                                                             .
        4780             : !  Although this routine was generated automatically, some further
        4781             : !  hand-editing may be required.
        4782             : !
        4783             : ! !REVISION HISTORY:
        4784             : !  See https://github.com/geoschem/hemco for complete history
        4785             : !EOP
        4786             : !------------------------------------------------------------------------------
        4787             : !BOC
        4788             : !
        4789             : ! !LOCAL VARIABLES:
        4790             : !
        4791             :     ! Arrays
        4792             :     INTEGER :: St4d(4), Ct4d(4)
        4793             :
        4794             :     ! Scalars
        4795             :     INTEGER :: I, nDim
        4796             :
        4797             :     !--------------------------------
        4798             :     ! WRITE DATA
        4799             :     !--------------------------------
        4800             :
        4801             :     ! Set start & count arrays
        4802           0 :     nDim = 4
        4803           0 :     DO I = 1, nDim
        4804           0 :        St4d(I) = 1
        4805           0 :        Ct4d(I) = SIZE( Arr4d, I )
        4806             :     ENDDO
        4807             :
        4808             :     ! Write to netCDF file
        4809           0 :     CALL NcWr( Arr4d, fId, VarName, St4d, Ct4d )
        4810             :
        4811           0 :   END SUBROUTINE NC_VAR_WRITE_INT_4D
        4812             : !EOC
        4813             : !------------------------------------------------------------------------------
        4814             : !                  GEOS-Chem Global Chemical Transport Model                  !
        4815             : !------------------------------------------------------------------------------
        4816             : !BOP
        4817             : !
        4818             : ! !IROUTINE: Get_Tau0
        4819             : !
        4820             : ! !DESCRIPTION: Function GET\_TAU0\_6A returns the corresponding TAU0 value
        4821             : !  for the first day of a given MONTH of a given YEAR.  This is necessary to
        4822             : !  index monthly mean binary punch files, which are used as input to GEOS-Chem.
        4823             : !\\
        4824             : !\\
        4825             : !  This function takes 3 mandatory arguments (MONTH, DAY, YEAR) and 3
        4826             : !  optional arguments (HOUR, MIN, SEC).  It is intended to replace the current
        4827             : !  2-argument version of GET\_TAU0.  The advantage being that GET\_TAU0\_6A
        4828             : !  can compute a TAU0 for any date and time in the GEOS-Chem epoch, rather
        4829             : !  than just the first day of each month.  Overload this w/ an interface so
        4830             : !  that the user can also choose the version of GET\_TAU0 w/ 2 arguments
        4831             : !  (MONTH, YEAR), which is the prior version.
        4832             : !\\
        4833             : !\\
        4834             : ! !INTERFACE:
        4835             : !
        4836           0 :   FUNCTION GET_TAU0( MONTH, DAY, YEAR, HOUR, MIN, SEC ) RESULT( THIS_TAU0 )
        4837             : !
        4838             : ! !USES:
        4839             : !
        4840             :     USE HCO_JULDAY_MOD, ONLY : JULDAY
        4841             : !
        4842             : ! !INPUT PARAMETERS:
        4843             : !
        4844             :     INTEGER, INTENT(IN)           :: MONTH
        4845             :     INTEGER, INTENT(IN)           :: DAY
        4846             :     INTEGER, INTENT(IN)           :: YEAR
        4847             :     INTEGER, INTENT(IN), OPTIONAL :: HOUR
        4848             :     INTEGER, INTENT(IN), OPTIONAL :: MIN
        4849             :     INTEGER, INTENT(IN), OPTIONAL :: SEC
        4850             : !
        4851             : ! !RETURN VALUE:
        4852             : !
        4853             :     REAL*8                        :: THIS_TAU0   ! TAU0 timestamp
        4854             : !
        4855             : ! !REMARKS:
        4856             : !  TAU0 is hours elapsed since 00:00 GMT on 01 Jan 1985.
        4857             : !
        4858             : ! !REVISION HISTORY:
        4859             : !  See https://github.com/geoschem/hemco for complete history
        4860             : !EOP
        4861             : !------------------------------------------------------------------------------
        4862             : !BOC
        4863             : !
        4864             : ! !LOCAL VARIABLES:
        4865             : !
        4866             :     INTEGER :: TMP_HOUR, TMP_MIN, TMP_SEC
        4867             :     REAL*8  :: DAYS
        4868             :
        4869             :     !=======================================================================
        4870             :     ! GET_TAU0 begins here!
        4871             :     !=======================================================================
        4872             :
        4873             :     ! Error checking
        4874           0 :     IF ( MONTH < 1 .or. MONTH > 12 ) THEN
        4875           0 :        WRITE( 6, 100 )
        4876             : 100    FORMAT( 'Invalid MONTH selection!  STOP in GET_TAU0 (ncdf_mod.F90)!' )
        4877           0 :        STOP
        4878             :     ENDIF
        4879             :
        4880             :     ! Error checking
        4881           0 :     IF ( DAY < 1 .or. DAY > 31 ) THEN
        4882           0 :        WRITE( 6, 110 )
        4883             : 110    FORMAT( 'Invalid DAY selection!  STOP in GET_TAU0 (ncdf_mod.F90)!' )
        4884           0 :        STOP
        4885             :     ENDIF
        4886             :
        4887             :     ! If HOUR isn't passed, default to 0
        4888           0 :     IF ( PRESENT( HOUR ) ) THEN
        4889           0 :        TMP_HOUR = HOUR
        4890             :     ELSE
        4891             :        TMP_HOUR = 0
        4892             :     ENDIF
        4893             :
        4894             :     ! If MIN isn't passed, default to 0
        4895           0 :     IF ( PRESENT( MIN ) ) THEN
        4896           0 :        TMP_MIN = MIN
        4897             :     ELSE
        4898             :        TMP_MIN = 0
        4899             :     ENDIF
        4900             :
        4901             :     ! If SEC isn't passed, default to 0
        4902           0 :     IF ( PRESENT( SEC ) ) THEN
        4903           0 :        TMP_SEC = SEC
        4904             :     ELSE
        4905             :        TMP_SEC = 0
        4906             :     ENDIF
        4907             :
        4908             :     ! Number of days since midnight on 1/1/1985
        4909           0 :     THIS_TAU0 = JULDAY( YEAR, MONTH, DBLE( DAY ) ) - 2446066.5d0
        4910             :
        4911             :     ! Multiply by 24 to get hours since 1/1/1985
        4912             :     ! Also add in the hours elapsed since midnight on this date
        4913             :     THIS_TAU0 = ( THIS_TAU0 * 24d0 ) + ( TMP_HOUR         ) + &
        4914           0 :                 ( TMP_MIN   / 60d0 ) + ( TMP_SEC / 3600d0 )
        4915             :
        4916           0 :   END FUNCTION GET_TAU0
        4917             : END MODULE HCO_NCDF_MOD

Generated by: LCOV version 1.14