LCOV - code coverage report
Current view: top level - hemco/HEMCO/src/Core - hcoio_read_std_mod.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 516 0.0 %
Date: 2025-03-13 18:55:17 Functions: 0 2 0.0 %

          Line data    Source code
       1             : !BOC
       2             : #if defined ( MODEL_GCCLASSIC ) || defined( MODEL_WRF ) || defined( MODEL_CESM ) || defined( HEMCO_STANDALONE )
       3             : ! The 'standard' HEMCO I/O module is used for:
       4             : ! - HEMCO Standalone (HEMCO_STANDALONE)
       5             : ! - GEOS-Chem 'Classic' (MODEL_GCCLASSIC)
       6             : ! - WRF-GC (MODEL_WRF)
       7             : ! - CESM-GC and CAM-Chem / HEMCO-CESM (MODEL_CESM)
       8             : !EOC
       9             : !------------------------------------------------------------------------------
      10             : !                   Harmonized Emissions Component (HEMCO)                    !
      11             : !------------------------------------------------------------------------------
      12             : !BOP
      13             : !
      14             : ! !MODULE: hcoio_read_std_mod.F90
      15             : !
      16             : ! !DESCRIPTION: Module HCOIO\_read\_mod controls data processing
      17             : ! (file reading, unit conversion, regridding) for HEMCO in the
      18             : ! 'standard' environment (i.e. non-ESMF).
      19             : !
      20             : ! This module implements the 'standard' environment (i.e. non-ESMF).
      21             : !\\
      22             : !\\
      23             : ! !INTERFACE:
      24             : !
      25             : MODULE HCOIO_Read_Mod
      26             : !
      27             : ! !USES:
      28             : !
      29             :   USE HCO_Types_Mod
      30             :   USE HCO_Error_Mod
      31             :   USE HCO_CharTools_Mod
      32             :   USE HCO_State_Mod,       ONLY : Hco_State
      33             :   USE HCOIO_Util_Mod
      34             : 
      35             :   IMPLICIT NONE
      36             :   PRIVATE
      37             : !
      38             : ! !PUBLIC MEMBER FUNCTIONS:
      39             : !
      40             :   PUBLIC  :: HCOIO_Read
      41             :   PUBLIC  :: HCOIO_CloseAll
      42             : !
      43             : ! !REMARKS:
      44             : !  Beginning with HEMCO 3.0.0, all I/O modules use the same module names,
      45             : !  and their compilation depends on pre-processor flags defined at the top
      46             : !  of the file.
      47             : !
      48             : !  This is to streamline the implementation of one unified Data Input Layer,
      49             : !  that can be switched in and out at compile time, and reduce branching of
      50             : !  code paths elsewhere.
      51             : !
      52             : ! !REVISION HISTORY:
      53             : !  22 Aug 2013 - C. Keller   - Initial version
      54             : !  See https://github.com/geoschem/hemco for complete history
      55             : !EOP
      56             : !------------------------------------------------------------------------------
      57             : !BOC
      58             : !
      59             : ! !DEFINED PARAMETERS
      60             : !
      61             :   ! Parameter used for difference testing of floating points
      62             :   REAL(dp), PRIVATE, PARAMETER :: EPSILON = 1.0e-5_dp
      63             : 
      64             : #if defined( MODEL_CESM ) || defined( MODEL_WRF )
      65             :   REAL(hp), PRIVATE            :: GC_72_EDGE_SIGMA(73) = (/ &
      66             :     1.000000E+00, 9.849998E-01, 9.699136E-01, 9.548285E-01, 9.397434E-01, 9.246593E-01, &
      67             :     9.095741E-01, 8.944900E-01, 8.794069E-01, 8.643237E-01, 8.492406E-01, 8.341584E-01, &
      68             :     8.190762E-01, 7.989697E-01, 7.738347E-01, 7.487007E-01, 7.235727E-01, 6.984446E-01, &
      69             :     6.733175E-01, 6.356319E-01, 5.979571E-01, 5.602823E-01, 5.226252E-01, 4.849751E-01, &
      70             :     4.473417E-01, 4.097261E-01, 3.721392E-01, 3.345719E-01, 2.851488E-01, 2.420390E-01, &
      71             :     2.055208E-01, 1.746163E-01, 1.484264E-01, 1.261653E-01, 1.072420E-01, 9.115815E-02, &
      72             :     7.748532E-02, 6.573205E-02, 5.565063E-02, 4.702097E-02, 3.964964E-02, 3.336788E-02, &
      73             :     2.799704E-02, 2.341969E-02, 1.953319E-02, 1.624180E-02, 1.346459E-02, 1.112953E-02, &
      74             :     9.171478E-03, 7.520355E-03, 6.135702E-03, 4.981002E-03, 4.023686E-03, 3.233161E-03, &
      75             :     2.585739E-03, 2.057735E-03, 1.629410E-03, 1.283987E-03, 1.005675E-03, 7.846040E-04, &
      76             :     6.089317E-04, 4.697755E-04, 3.602270E-04, 2.753516E-04, 2.082408E-04, 1.569208E-04, &
      77             :     1.184308E-04, 8.783617E-05, 6.513694E-05, 4.737232E-05, 3.256847E-05, 1.973847E-05, &
      78             :     9.869233E-06/)
      79             : #endif
      80             : 
      81             : CONTAINS
      82             : !EOC
      83             : !------------------------------------------------------------------------------
      84             : !                   Harmonized Emissions Component (HEMCO)                    !
      85             : !------------------------------------------------------------------------------
      86             : !BOP
      87             : !
      88             : ! !IROUTINE: HCOIO_Read
      89             : !
      90             : ! !DESCRIPTION: Reads a netCDF file and returns the regridded array in proper
      91             : ! units. This routine uses the HEMCO generic data reading and regridding
      92             : ! routines.
      93             : !\\
      94             : !\\
      95             : ! Two different regridding algorithm are used: NCREGRID for 3D data with
      96             : ! vertical regridding, and map\_a2a for all other data. map\_a2a also
      97             : ! supports index-based remapping, while this feature is currently not
      98             : ! possible in combination with NCREGRID.
      99             : !\\
     100             : !\\
     101             : ! 3D data is vertically regridded onto the simulation grid on the sigma
     102             : ! interface levels. In order to calculate these levels correctly, the netCDF
     103             : ! vertical coordinate description must adhere to the CF - conventions. See
     104             : ! routine NC\_Get\_Sigma\_Levels in Ncdf\_Mod for more details.
     105             : !\\
     106             : !\\
     107             : ! A simpler vertical interpolation scheme is used if (a) the number of
     108             : ! vertical levels of the input data corresponds to the number of levels
     109             : ! on the simulation grid (direct mapping, no remapping), (b) the vertical
     110             : ! level variable name (long\_name) contains the word "GEOS-Chem level". In
     111             : ! the latter case, the vertical levels of the input data is interpreted as
     112             : ! GEOS vertical levels and mapped onto the simulation grid using routine
     113             : ! ModelLev\_Interpolate.
     114             : !\\
     115             : !\\
     116             : ! !INTERFACE:
     117             : !
     118           0 :   SUBROUTINE HCOIO_Read( HcoState, Lct, RC )
     119             : !
     120             : ! !USES:
     121             : !
     122             :     USE HCO_Ncdf_Mod,       ONLY : NC_Open
     123             :     USE HCO_Ncdf_Mod,       ONLY : NC_Close
     124             :     USE HCO_Ncdf_Mod,       ONLY : NC_Read_Var
     125             :     USE HCO_Ncdf_Mod,       ONLY : NC_Read_Arr
     126             :     USE HCO_Ncdf_Mod,       ONLY : NC_Get_Grid_Edges
     127             :     USE HCO_Ncdf_Mod,       ONLY : NC_Get_Sigma_Levels
     128             :     USE HCO_Ncdf_Mod,       ONLY : NC_IsModelLevel
     129             :     USE HCO_Ncdf_Mod,       ONLY : NC_IsSigmaLevel
     130             :     USE HCO_CHARPAK_MOD,    ONLY : TRANLC
     131             :     USE HCO_Unit_Mod,       ONLY : HCO_Unit_Change
     132             :     USE HCO_Unit_Mod,       ONLY : HCO_Unit_ScalCheck
     133             :     USE HCO_Unit_Mod,       ONLY : HCO_IsUnitless
     134             :     USE HCO_Unit_Mod,       ONLY : HCO_IsIndexData
     135             :     USE HCO_Unit_Mod,       ONLY : HCO_UnitTolerance
     136             :     USE HCO_GeoTools_Mod,   ONLY : HCO_ValidateLon
     137             :     USE HCO_FileData_Mod,   ONLY : FileData_ArrCheck
     138             :     USE HCO_FileData_Mod,   ONLY : FileData_ArrInit
     139             :     USE HCO_FileData_Mod,   ONLY : FileData_Cleanup
     140             :     USE HCOIO_MESSY_MOD,    ONLY : HCO_MESSY_REGRID
     141             :     USE HCO_INTERP_MOD,     ONLY : REGRID_MAPA2A
     142             :     USE HCO_INTERP_MOD,     ONLY : ModelLev_Check
     143             :     USE HCO_CLOCK_MOD,      ONLY : HcoClock_Get
     144             :     USE HCO_DIAGN_MOD,      ONLY : Diagn_Update
     145             :     USE HCO_EXTLIST_MOD,    ONLY : HCO_GetOpt
     146             :     USE HCO_TIDX_MOD,       ONLY : tIDx_IsInRange
     147             : 
     148             :     include "netcdf.inc"
     149             : !
     150             : ! !INPUT PARAMETERS:
     151             : !
     152             :     TYPE(HCO_State),  POINTER        :: HcoState   ! HEMCO state object
     153             :     TYPE(ListCont),   POINTER        :: Lct        ! HEMCO list container
     154             : !
     155             : ! !INPUT/OUTPUT PARAMETERS:
     156             : !
     157             :     INTEGER,          INTENT(INOUT)  :: RC         ! Success or failure?
     158             : !
     159             : ! !REVISION HISTORY:
     160             : !  13 Mar 2013 - C. Keller   - Initial version
     161             : !  See https://github.com/geoschem/hemco for complete history
     162             : !EOP
     163             : !------------------------------------------------------------------------------
     164             : !BOC
     165             : !
     166             : ! !LOCAL VARIABLES:
     167             : !
     168             :     CHARACTER(LEN=255)            :: thisUnit, LevUnit, LevName
     169             :     CHARACTER(LEN=1023)           :: MSG, LOC
     170             :     CHARACTER(LEN=1023)           :: srcFile, srcFile2
     171             :     INTEGER                       :: NX, NY
     172             :     INTEGER                       :: NCRC, Flag, AS
     173             :     INTEGER                       :: ncLun, ncLun2
     174             :     INTEGER                       :: ierr,   v_id
     175             :     INTEGER                       :: nlon,   nlat,  nlev, nTime
     176             :     INTEGER                       :: lev1,   lev2,  dir
     177             :     INTEGER                       :: tidx1,  tidx2,  ncYr,  ncMt
     178             :     INTEGER                       :: tidx1b, tidx2b, ncYr2, ncMt2
     179             :     INTEGER                       :: HcoID
     180             :     INTEGER                       :: ArbIdx
     181             :     INTEGER                       :: nlatEdge, nlonEdge
     182             :     INTEGER                       :: Direction
     183             :     REAL(hp)                      :: MW_g
     184             :     REAL(sp)                      :: wgt1,   wgt2
     185           0 :     REAL(sp), POINTER             :: ncArr(:,:,:,:)
     186           0 :     REAL(sp), POINTER             :: ncArr2(:,:,:,:)
     187           0 :     REAL(hp), POINTER             :: SigEdge(:,:,:)
     188           0 :     REAL(hp), POINTER             :: SigLev (:,:,:)
     189           0 :     REAL(hp), POINTER             :: LonMid   (:)
     190           0 :     REAL(hp), POINTER             :: LatMid   (:)
     191           0 :     REAL(hp), POINTER             :: LevMid   (:)
     192           0 :     REAL(hp), POINTER             :: LonEdge  (:)
     193           0 :     REAL(hp), POINTER             :: LatEdge  (:)
     194             :     REAL(hp)                      :: UnitFactor
     195             :     LOGICAL                       :: KeepSpec
     196             :     LOGICAL                       :: FOUND
     197             :     LOGICAL                       :: IsModelLevel
     198             :     LOGICAL                       :: DoReturn
     199             :     INTEGER                       :: UnitTolerance
     200             :     INTEGER                       :: AreaFlag, TimeFlag
     201             :     REAL(dp)                      :: YMDhma,  YMDhmb, YMDhm1
     202             :     REAL(dp)                      :: oYMDhm1, oYMDhm2
     203             :     INTEGER                       :: cYr, cMt, cDy, cHr, Yr1, Yr2
     204             :     INTEGER                       :: nYears, iYear
     205             :     INTEGER                       :: I, J
     206             : 
     207             :     ! Use MESSy regridding routines?
     208             :     LOGICAL                       :: UseMESSy
     209             : 
     210             :     ! SAVEd scalars
     211             :     LOGICAL, SAVE                 :: doPrintWarning = .TRUE.
     212             : 
     213             :     !=================================================================
     214             :     ! HCOIO_READ begins here
     215             :     !=================================================================
     216           0 :     LOC = 'HCOIO_READ (HCOIO_READ_STD_MOD.F90)'
     217             : 
     218             :     ! Enter
     219           0 :     CALL HCO_ENTER( HcoState%Config%Err, LOC, RC )
     220           0 :     IF ( RC /= HCO_SUCCESS ) THEN
     221           0 :         CALL HCO_ERROR( 'ERROR 0', RC, THISLOC=LOC )
     222           0 :         RETURN
     223             :     ENDIF
     224             : 
     225             :     ! Initialize pointers
     226           0 :     ncArr   => NULL()
     227           0 :     ncArr2  => NULL()
     228           0 :     SigEdge => NULL()
     229           0 :     SigLev  => NULL()
     230           0 :     LonMid  => NULL()
     231           0 :     LatMid  => NULL()
     232           0 :     LevMid  => NULL()
     233           0 :     LonEdge => NULL()
     234           0 :     LatEdge => NULL()
     235             : 
     236             :     ! Zero local variables for safety's sake
     237           0 :     dir     =  0
     238           0 :     lev1    =  0
     239           0 :     lev2    =  0
     240           0 :     ncYr    =  0
     241           0 :     ncMt    =  0
     242           0 :     ncYr2   =  0
     243           0 :     ncMt2   =  0
     244           0 :     nLon    =  0
     245           0 :     nLat    =  0
     246           0 :     nLev    =  0
     247           0 :     nTime   =  0
     248           0 :     tIdx1   =  0
     249           0 :     tIdx2   =  0
     250           0 :     tidx1b  =  0
     251           0 :     tidx2b  =  0
     252           0 :     wgt1    =  0.0_sp
     253           0 :     wgt2    =  0.0_sp
     254             : 
     255             :     ! Get unit tolerance set in configuration file
     256           0 :     UnitTolerance = HCO_UnitTolerance( HcoState%Config )
     257             : 
     258             :     ! For convenience, copy horizontal grid dimensions from HEMCO
     259             :     ! state object
     260           0 :     NX = HcoState%NX
     261           0 :     NY = HcoState%NY
     262             : 
     263             :     ! Verbose
     264           0 :     IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
     265           0 :        WRITE(MSG,*) 'Processing container: ', TRIM(Lct%Dct%cName)
     266           0 :        CALL HCO_MSG( HcoState%Config%Err, MSG, SEP1='-' )
     267             :     ENDIF
     268             : 
     269             :     ! If the file has cycle flag "E" (e.g. it's a restart file), then we will
     270             :     ! read it only once and then never again.  If the file has already been
     271             :     ! read on a previous call, then don't call HCOIO_READ. (bmy, 10/4/18)
     272             :     !
     273             :     ! Moved this handling from hcoio_dataread_mod, as it is non-MAPL specific
     274             :     ! (hplin, 4/5/21)
     275             :     IF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT .and.                      &
     276           0 :          Lct%Dct%Dta%UpdtFlag  == HCO_UFLAG_ONCE  .and.                      &
     277             :          Lct%Dct%Dta%isTouched                          ) THEN
     278             : 
     279             :        ! Print a warning message only once
     280           0 :        IF ( doPrintWarning ) THEN
     281           0 :           doPrintWarning = .FALSE.
     282             :           MSG = 'No further attempts will be made to read file: ' //         &
     283           0 :                 TRIM( Lct%Dct%Dta%NcFile )
     284           0 :           CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
     285             :        ENDIF
     286             : 
     287             :        ! Return without reading
     288           0 :        CALL HCO_LEAVE( HcoState%Config%Err, RC )
     289           0 :        RETURN
     290             :     ENDIF
     291             : 
     292             :     ! ----------------------------------------------------------------
     293             :     ! Parse source file name. This will replace all tokens ($ROOT,
     294             :     ! ($YYYY), etc., with valid values.
     295             :     ! ----------------------------------------------------------------
     296           0 :     CALL SrcFile_Parse( HcoState, Lct, srcFile, FOUND, RC )
     297           0 :     IF ( RC /= HCO_SUCCESS ) THEN
     298             :        MSG = 'Error encountered in routine "SrcFile_Parse", located '     // &
     299           0 :              'module src/Core/hcoio_read_std_mod.F90!'
     300           0 :         CALL HCO_ERROR( MSG, RC )
     301           0 :         RETURN
     302             :     ENDIF
     303             : 
     304             :     ! Handle found or not in the standard way if HEMCO is in regular run mode.
     305           0 :     IF ( .NOT. HcoState%Options%isDryRun ) THEN
     306             : 
     307             :        !====================================================================
     308             :        ! HEMCO is in regular simulation mode (not dry-run)!
     309             :        !====================================================================
     310             : 
     311             :        ! If file not found, return w/ error. No error if cycling attribute is
     312             :        ! select to range. In that case, just make sure that array is empty.
     313           0 :        IF ( .NOT. FOUND ) THEN
     314           0 :           IF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGE ) .OR.      &
     315             :                ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT )     ) THEN
     316             : 
     317             :              ! If MustFind flag is enabled, return with error if field is not
     318             :              ! found
     319           0 :              IF ( Lct%Dct%Dta%MustFind ) THEN
     320             :                 MSG = 'Cannot find file for current simulation time: ' // &
     321             :                      TRIM(srcFile) // ' - Cannot get field ' // &
     322             :                      TRIM(Lct%Dct%cName) // '. Please check file name ' // &
     323           0 :                      'and time (incl. time range flag) in the config. file'
     324           0 :                 CALL HCO_ERROR( MSG, RC )
     325           0 :                 RETURN
     326             : 
     327             :              ! If MustFind flag is not enabled, ignore this field and return
     328             :              ! with a warning.
     329             :              ELSE
     330           0 :                 CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE. )
     331             :                 MSG = 'No valid file found for current simulation time - data '// &
     332           0 :                      'will be ignored for time being - ' // TRIM(Lct%Dct%cName)
     333           0 :                 CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
     334           0 :                 CALL HCO_LEAVE ( HcoState%Config%Err,  RC )
     335           0 :                 RETURN
     336             :              ENDIF
     337             : 
     338             :           ELSE
     339             :              MSG = 'Cannot find file for current simulation time: ' // &
     340             :                   TRIM(srcFile) // ' - Cannot get field ' // &
     341             :                   TRIM(Lct%Dct%cName) // '. Please check file name ' // &
     342           0 :                   'and time (incl. time range flag) in the config. file'
     343           0 :              CALL HCO_ERROR( MSG, RC )
     344           0 :              RETURN
     345             :           ENDIF
     346             :        ENDIF
     347             : 
     348             :     ELSE
     349             : 
     350             :        !====================================================================
     351             :        ! HEMCO is in a "dry-run" mode!
     352             :        !====================================================================
     353             : 
     354             :        ! Simulate file read buffer
     355           0 :        IF ( TRIM(HcoState%ReadLists%FileInArchive) == TRIM(srcFile) ) THEN
     356           0 :           CALL HCO_LEAVE ( HcoState%Config%Err,  RC )
     357           0 :           RETURN
     358             :        ENDIF
     359             : 
     360             :        ! If file exists, print the result. If NOT, then handle accordingly
     361             :        ! But NEVER error out (HCO_ERROR), as we want to get a list of all
     362             :        ! files. (hplin, 11/2/19)
     363           0 :        IF ( .NOT. FOUND ) THEN
     364           0 :           IF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGE )       .OR.       &
     365             :                ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT )     ) THEN
     366             : 
     367             :              ! If MustFind flag is enabled, return with error if field is not
     368             :              ! found
     369           0 :              IF ( Lct%Dct%Dta%MustFind ) THEN
     370             :                 MSG = 'Cannot find file for current simulation time: '    // &
     371             :                      TRIM(srcFile) // ' - Cannot get field '              // &
     372             :                      TRIM(Lct%Dct%cName) // '. Please check file name '   // &
     373           0 :                      'and time (incl. time range flag) in the config. file'
     374           0 :                 CALL HCO_Warning( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
     375             : 
     376             :                 ! Write a msg to stdout (NOT FOUND)
     377           0 :                 WRITE( 6, 300 ) TRIM( srcFile )
     378             :  300            FORMAT( 'HEMCO: REQUIRED FILE NOT FOUND ', a )
     379             : 
     380             :              ! If MustFind flag is not enabled, ignore this field and return
     381             :              ! with a warning.
     382             :              ELSE
     383           0 :                 CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE. )
     384             :                 MSG = 'No valid file found for current simulation time - '// &
     385             :                      'data will be ignored for time being - '             // &
     386           0 :                      TRIM(Lct%Dct%cName)
     387           0 :                 CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
     388             : 
     389             :                 ! Write a msg to stdout (OPTIONAL)
     390           0 :                 WRITE( 6, 310 ) TRIM( srcFile )
     391             :  310            FORMAT( 'HEMCO: OPTIONAL FILE NOT FOUND ', a )
     392             : 
     393             :              ENDIF
     394             : 
     395             :           ! Not range or exact
     396             :           ELSE
     397             :              MSG = 'Cannot find file for current simulation time: '       // &
     398             :                   TRIM(srcFile) // ' - Cannot get field '                 // &
     399             :                   TRIM(Lct%Dct%cName) // '. Please check file name '      // &
     400           0 :                   'and time (incl. time range flag) in the config. file'
     401           0 :              CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
     402             : 
     403             :              ! Write a msg to stdout (NOT FOUND)
     404           0 :              WRITE( 6, 300 ) TRIM(srcFile)
     405             : 
     406             :           ENDIF
     407             :        ELSE
     408             : 
     409             :           ! Write a mesage to stdout (HEMCO: Opening...)
     410           0 :           WRITE( 6, 100 ) TRIM( srcFile )
     411             : 
     412             :        ENDIF
     413             : 
     414             :        ! It is safe to leave now, we do not need to handle opening the file.
     415             :        ! This may be changed in the future if the "dry-run" mode requires
     416             :        ! a check of the file contents... this may be beyond the scope for now.
     417             : 
     418             :        ! Simulate the "reading" in netCDF to prevent duplicate entries
     419             :        ! in the log
     420           0 :        HcoState%ReadLists%FileInArchive = TRIM(srcFile)
     421             : 
     422             :        ! Skip further processing
     423           0 :        CALL HCO_LEAVE ( HcoState%Config%Err,  RC )
     424           0 :        RETURN
     425             :     ENDIF ! End of dry-run mode else clause
     426             : 
     427             :     ! ----------------------------------------------------------------
     428             :     ! Open netCDF
     429             :     ! ----------------------------------------------------------------
     430             : 
     431             :     ! Check if file is already in buffer. In that case use existing
     432             :     ! open stream. Otherwise open new file. At any given time there
     433             :     ! can only be one file in buffer.
     434           0 :     ncLun = -1
     435           0 :     IF ( HcoState%ReadLists%FileLun > 0 ) THEN
     436           0 :        IF ( TRIM(HcoState%ReadLists%FileInArchive) == TRIM(srcFile) ) THEN
     437           0 :           ncLun = HcoState%ReadLists%FileLun
     438             :        ELSE
     439           0 :           CALL NC_CLOSE ( HcoState%ReadLists%FileLun )
     440           0 :           HcoState%ReadLists%FileLun = -1
     441             :        ENDIF
     442             :     ENDIF
     443             : 
     444             :     ! To read from existing stream:
     445           0 :     IF ( ncLun > 0 ) THEN
     446             : 
     447             :        ! Verbose mode
     448           0 :        IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
     449           0 :           WRITE(MSG,*) 'Reading from existing stream: ', TRIM(srcFile)
     450           0 :           CALL HCO_MSG( HcoState%Config%Err, MSG )
     451             :        ENDIF
     452             : 
     453             :     ! To open a new file:
     454             :     ELSE
     455           0 :        CALL NC_OPEN ( TRIM(srcFile), ncLun )
     456             : 
     457             :        ! Verbose mode
     458           0 :        IF ( HCO_IsVerb(HcoState%Config%Err,1) ) THEN
     459           0 :           WRITE(MSG,*) 'Opening file: ', TRIM(srcFile)
     460           0 :           CALL HCO_MSG( HcoState%Config%Err, MSG )
     461             :        ENDIF
     462             : 
     463             :        ! Also write to standard output
     464           0 :        WRITE( 6, 100 ) TRIM( srcFile )
     465             :  100   FORMAT( 'HEMCO: Opening ', a )
     466             : 
     467             :        ! This is now the file in archive
     468           0 :        HcoState%ReadLists%FileInArchive = TRIM(srcFile)
     469           0 :        HcoState%ReadLists%FileLun       = ncLun
     470             :     ENDIF
     471             : 
     472             :     ! ----------------------------------------------------------------
     473             :     ! Extract time slice information
     474             :     ! This determines the lower and upper time slice index (tidx1
     475             :     ! and tidx2) to be read based upon the time slice information
     476             :     ! extracted from the file and the time stamp settings set in the
     477             :     ! HEMCO configuration file. Multiple time slices are only selected
     478             :     ! for weekdaily data or for 'autodetected' hourly data (using the
     479             :     ! wildcard character in the configuration file time attribute) or
     480             :     ! if data shall be interpolated between two (consecutive) time
     481             :     ! slices. The weights to be assigned to those two time slices is
     482             :     ! also calculated in GET_TIMEIDX and returned as variables wgt1
     483             :     ! and wgt2, respectively.
     484             :     ! ----------------------------------------------------------------
     485             :     CALL GET_TIMEIDX ( HcoState,  Lct,                &
     486             :                        ncLun,     tidx1,    tidx2,    &
     487             :                        wgt1,      wgt2,     oYMDhm1,  &
     488           0 :                        YMDhma,    YMDhm1,   RC        )
     489           0 :     IF ( RC /= HCO_SUCCESS ) THEN
     490           0 :         CALL HCO_ERROR( 'ERROR 1', RC, THISLOC=LOC )
     491           0 :         RETURN
     492             :     ENDIF
     493             : 
     494             :     !-----------------------------------------------------------------
     495             :     ! Check for negative tidx1. tidx1 can still be negative if:
     496             :     ! (a) CycleFlag is set to range and the current simulation
     497             :     ! time is outside of the data time range. In this case, we
     498             :     ! prompt a warning and make sure that there is no data
     499             :     ! associated with this FileData container.
     500             :     ! (b) CycleFlag is set to exact and none of the data time
     501             :     ! stamps matches the current simulation time exactly. Return
     502             :     ! with error!
     503             :     !-----------------------------------------------------------------
     504           0 :     IF ( tidx1 < 0 ) THEN
     505           0 :        DoReturn = .FALSE.
     506           0 :        IF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_CYCLE ) THEN
     507           0 :           MSG = 'Invalid time index in ' // TRIM(srcFile)
     508           0 :           CALL HCO_ERROR( MSG, RC )
     509             :           DoReturn = .TRUE.
     510           0 :        ELSEIF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGE ) .OR.      &
     511             :                 ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT )     ) THEN
     512           0 :           IF ( Lct%Dct%Dta%MustFind ) THEN
     513             :              MSG = 'Cannot find field with valid time stamp in ' // &
     514             :                    TRIM(srcFile) // ' - Cannot get field ' // &
     515             :                    TRIM(Lct%Dct%cName) // '. Please check file name ' // &
     516           0 :                    'and time (incl. time range flag) in the config. file'
     517           0 :              CALL HCO_ERROR( MSG, RC )
     518             :              DoReturn = .TRUE.
     519             :           ELSE
     520           0 :              CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE.)
     521             :              MSG = 'Simulation time is outside of time range provided for '//&
     522           0 :                   TRIM(Lct%Dct%cName) // ' - field is ignored for the time being!'
     523           0 :              CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
     524           0 :              DoReturn = .TRUE.
     525           0 :              CALL HCO_LEAVE ( HcoState%Config%Err,  RC )
     526             :           ENDIF
     527             :        ENDIF
     528             : 
     529             :        ! Eventually return here
     530             :        IF ( DoReturn ) THEN
     531           0 :           RETURN
     532             :        ENDIF
     533             :     ENDIF
     534             : 
     535             :     ! ----------------------------------------------------------------
     536             :     ! Check if variable is in file
     537             :     ! ----------------------------------------------------------------
     538           0 :     ierr = Nf_Inq_Varid( ncLun, Lct%Dct%Dta%ncPara, v_id )
     539           0 :     IF ( ierr /= NF_NOERR ) THEN
     540             : 
     541             :        ! If MustFind flag is enabled, return with error if field is not
     542             :        ! found
     543           0 :        IF ( Lct%Dct%Dta%MustFind ) THEN
     544             :           MSG = 'Cannot find field ' // TRIM(Lct%Dct%cName) // &
     545           0 :                 '. Please check variable name in the config. file'
     546           0 :           CALL HCO_ERROR( MSG, RC )
     547           0 :           RETURN
     548             : 
     549             :        ! If MustFind flag is not enabled, ignore this field and return
     550             :        ! with a warning.
     551             :        ELSE
     552           0 :           CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE. )
     553             :           MSG = 'Cannot find field ' // TRIM(Lct%Dct%cName) // &
     554           0 :                 '. Will be ignored for time being.'
     555           0 :           CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
     556           0 :           CALL HCO_LEAVE ( HcoState%Config%Err,  RC )
     557           0 :           RETURN
     558             :        ENDIF
     559             :     ENDIF
     560             : 
     561             :     ! ----------------------------------------------------------------
     562             :     ! Read grid
     563             :     ! ----------------------------------------------------------------
     564             : 
     565             :     ! Extract longitude midpoints
     566           0 :     CALL NC_READ_VAR ( ncLun, 'lon', nlon, thisUnit, LonMid, NCRC )
     567           0 :     IF ( NCRC /= 0 ) THEN
     568           0 :        CALL HCO_ERROR( 'NC_READ_VAR: lon', RC )
     569           0 :        RETURN
     570             :     ENDIF
     571             : 
     572           0 :     IF ( nlon == 0 ) THEN
     573           0 :        CALL NC_READ_VAR ( ncLun, 'longitude', nlon, thisUnit, LonMid, NCRC )
     574             :     ENDIF
     575           0 :     IF ( NCRC /= 0 ) THEN
     576           0 :        CALL HCO_ERROR( 'NC_READ_VAR: longitude', RC )
     577           0 :        RETURN
     578             :     ENDIF
     579             : 
     580           0 :     IF ( nlon == 0 ) THEN
     581           0 :        CALL NC_READ_VAR ( ncLun, 'Longitude', nlon, thisUnit, LonMid, NCRC )
     582             :     ENDIF
     583           0 :     IF ( NCRC /= 0 ) THEN
     584           0 :        CALL HCO_ERROR( 'NC_READ_LON: Longitude', RC )
     585           0 :        RETURN
     586             :     ENDIF
     587             : 
     588           0 :     IF ( nlon == 0 ) THEN
     589             :        MSG = 'Cannot find longitude variable in ' // TRIM(srcFile) // &
     590           0 :              ' - Must be one of `lon`, `longitude`, `Longitude`'
     591           0 :        CALL HCO_ERROR( MSG, RC )
     592           0 :        RETURN
     593             :     ENDIF
     594             : 
     595             :     ! Unit must be degrees_east
     596           0 :     CALL TRANLC( thisUnit)
     597           0 :     IF ( INDEX( thisUnit, 'degrees_east' ) == 0 ) THEN
     598             :        MSG = 'illegal longitude unit in ' // TRIM(srcFile) // &
     599           0 :              ' - Must be `degrees_east`.'
     600           0 :        CALL HCO_ERROR( MSG, RC )
     601           0 :        RETURN
     602             :     ENDIF
     603             : 
     604             :     ! Make sure longitude is steadily increasing.
     605           0 :     CALL HCO_ValidateLon( HcoState, nlon, LonMid, RC )
     606           0 :     IF ( RC /= HCO_SUCCESS ) THEN
     607           0 :         CALL HCO_ERROR( 'ERROR 2', RC, THISLOC=LOC )
     608           0 :         RETURN
     609             :     ENDIF
     610             : 
     611             :     ! Extract latitude midpoints
     612           0 :     CALL NC_READ_VAR ( ncLun, 'lat', nlat, thisUnit, LatMid, NCRC )
     613           0 :     IF ( NCRC /= 0 ) THEN
     614           0 :        CALL HCO_ERROR( 'NC_READ_LON: lat', RC )
     615           0 :        RETURN
     616             :     ENDIF
     617             : 
     618           0 :     IF ( nlat == 0 ) THEN
     619           0 :        CALL NC_READ_VAR ( ncLun, 'latitude', nlat, thisUnit, LatMid, NCRC )
     620             :     ENDIF
     621           0 :     IF ( NCRC /= 0 ) THEN
     622           0 :        CALL HCO_ERROR( 'NC_READ_LON: latitude', RC )
     623           0 :        RETURN
     624             :     ENDIF
     625             : 
     626           0 :     IF ( nlat == 0 ) THEN
     627           0 :        CALL NC_READ_VAR ( ncLun, 'Latitude', nlat, thisUnit, LatMid, NCRC )
     628             :     ENDIF
     629           0 :     IF ( NCRC /= 0 ) THEN
     630           0 :        CALL HCO_ERROR( 'NC_READ_LON: Latitude', RC )
     631           0 :        RETURN
     632             :     ENDIF
     633             : 
     634           0 :     IF ( nlat == 0 ) THEN
     635             :        MSG = 'Cannot find latitude variable in ' // TRIM(srcFile) // &
     636           0 :              ' - Must be one of `lat`, `latitude`, `Latitude`'
     637           0 :        CALL HCO_ERROR( MSG, RC )
     638           0 :        RETURN
     639             :     ENDIF
     640             : 
     641             :     ! Unit must be degrees_north
     642           0 :     CALL TRANLC( thisUnit)
     643           0 :     IF ( INDEX( thisUnit, 'degrees_north' ) == 0 ) THEN
     644             :        MSG = 'illegal latitude unit in ' // TRIM(srcFile) // &
     645           0 :              ' - Must be `degrees_north`.'
     646           0 :        CALL HCO_ERROR( MSG, RC )
     647           0 :        RETURN
     648             :     ENDIF
     649             : 
     650             :     ! Get level index if we are dealing with 3D data
     651           0 :     IF ( Lct%Dct%Dta%SpaceDim == 3 ) THEN
     652             : 
     653             :        ! Try to extract level midpoints
     654           0 :        LevName = 'lev'
     655           0 :        CALL NC_READ_VAR ( ncLun, LevName, nlev, LevUnit, LevMid, NCRC )
     656           0 :        IF ( NCRC /= 0 ) THEN
     657           0 :           CALL HCO_ERROR( 'NC_READ_VAR: lev', RC )
     658           0 :           RETURN
     659             :        ENDIF
     660           0 :        IF ( nlev == 0 ) THEN
     661           0 :           LevName = 'height'
     662           0 :           CALL NC_READ_VAR ( ncLun, LevName, nlev, LevUnit, LevMid, NCRC )
     663           0 :           IF ( NCRC /= 0 ) THEN
     664           0 :              CALL HCO_ERROR( 'NC_READ_VAR: height', RC )
     665           0 :              RETURN
     666             :           ENDIF
     667             :        ENDIF
     668           0 :        IF ( nlev == 0 ) THEN
     669           0 :           LevName = 'level'
     670           0 :           CALL NC_READ_VAR ( ncLun, LevName, nlev, LevUnit, LevMid, NCRC )
     671           0 :           IF ( NCRC /= 0 ) THEN
     672           0 :              CALL HCO_ERROR( 'NC_READ_VAR: level', RC )
     673           0 :              RETURN
     674             :           ENDIF
     675             :        ENDIF
     676             : 
     677             :        ! Error check
     678           0 :        IF ( nlev == 0 ) THEN
     679             :           MSG = 'Cannot find vertical coordinate variable in ' // &
     680           0 :                  TRIM(SrcFile) // ' - Must be one of `lev`, `level`, `height`.'
     681           0 :           CALL HCO_ERROR( MSG, RC )
     682           0 :           RETURN
     683             :        ENDIF
     684             : 
     685             :        ! Are these model levels? This will only return true if the long
     686             :        ! name of the level variable contains "GEOS-Chem level".
     687             :        ! For now, we assume levels are already on model levels if the
     688             :        ! number of levels to be read is explicitly set in the configuration
     689             :        ! file (ckeller, 5/20/15).
     690           0 :        IF ( Lct%Dct%Dta%Levels == 0 ) THEN
     691             : 
     692             :           ! Check if vertical coordinate is GEOS-Chem levels
     693           0 :           IsModelLevel = NC_IsModelLevel( ncLun, LevName )
     694             : 
     695             :           ! Further check if the given number of vertical levels should be
     696             :           ! treated as model levels. This is the case if e.g. the nuber of
     697             :           ! levels found on the file exactly matches the number of vertical
     698             :           ! levels of the grid. Some of these assumptions are rather arbitrary.
     699             :           ! IsModelLev will stay True if is was set so in NC_ISMODELLEVEL
     700             :           ! above. (ckeller, 9/29/15)
     701           0 :           CALL ModelLev_Check( HcoState, nlev, IsModelLevel, RC )
     702           0 :           IF ( RC /= HCO_SUCCESS ) THEN
     703           0 :               CALL HCO_ERROR( 'ERROR 3', RC, THISLOC=LOC )
     704           0 :               RETURN
     705             :           ENDIF
     706             : 
     707             :           ! Override IsModelLevel if the long_name contains
     708             :           ! "atmospheric_hybrid_sigma_pressure_coordinate"
     709           0 :           IsModelLevel = ( .not. NC_IsSigmaLevel( ncLun, LevName ) )
     710             : 
     711             :           ! Set level indeces to be read
     712           0 :           lev1 = 1
     713           0 :           lev2 = nlev
     714             : 
     715             :        ! If levels are explicitly given:
     716             :        ELSE
     717             : 
     718             :           ! If long_name is "atmospheric_hybrid_sigma_pressure_coordinate",
     719             :           ! then treat it as sigma levels; otherwise assume model levels.
     720           0 :           IsModelLevel = ( .not. NC_IsSigmaLevel( ncLun, LevName ) )
     721             : 
     722             :           ! Number of levels to be read must be smaller or equal to total
     723             :           ! number of available levels
     724           0 :           IF ( ABS(Lct%Dct%Dta%Levels) > nlev ) THEN
     725           0 :              WRITE(MSG,*) Lct%Dct%Dta%Levels, ' levels requested but file ', &
     726           0 :                 'has only ', nlev, ' levels: ', TRIM(Lct%Dct%cName)
     727           0 :              CALL HCO_ERROR( MSG, RC )
     728           0 :              RETURN
     729             :           ENDIF
     730             : 
     731             :           ! Set levels to be read
     732           0 :           IF ( Lct%Dct%Dta%Levels > 0 ) THEN
     733           0 :              lev1 = 1
     734           0 :              lev2 = Lct%Dct%Dta%Levels
     735             : 
     736             :           ! Reverse axis!
     737             :           ELSE
     738           0 :              lev1 = nlev
     739           0 :              lev2 = nlev + Lct%Dct%Dta%Levels + 1
     740             :           ENDIF
     741             : 
     742             :        ENDIF
     743             : 
     744             :        ! Verbose
     745           0 :        IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
     746           0 :           WRITE(MSG,*) 'Will read vertical levels ', lev1, ' to ', lev2
     747           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG)
     748             :        ENDIF
     749             : 
     750             :     ! For 2D data, set lev1 and lev2 to zero. This will ignore
     751             :     ! the level dimension in the netCDF reading call that follows.
     752             :     ELSE
     753           0 :        nlev        = 0
     754           0 :        lev1        = 0
     755           0 :        lev2        = 0
     756           0 :        IsModelLevel = .FALSE.
     757             :     ENDIF
     758             : 
     759             :     ! ----------------------------------------------------------------
     760             :     ! Check for arbitrary additional dimension. Will return -1 if not
     761             :     ! set.
     762             :     ! ----------------------------------------------------------------
     763           0 :     CALL GetArbDimIndex( HcoState, ncLun, Lct, ArbIdx, RC )
     764           0 :     IF ( RC /= HCO_SUCCESS ) THEN
     765           0 :         CALL HCO_ERROR( 'ERROR 4', RC, THISLOC=LOC )
     766           0 :         RETURN
     767             :     ENDIF
     768             : 
     769             :     ! ----------------------------------------------------------------
     770             :     ! Read data
     771             :     ! ----------------------------------------------------------------
     772             : 
     773             :     ! Verbose mode
     774           0 :     IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
     775           0 :        WRITE(MSG,*) 'Reading variable ', TRIM(Lct%Dct%Dta%ncPara)
     776           0 :        CALL HCO_MSG(HcoState%Config%Err,MSG)
     777             :     ENDIF
     778             : 
     779             :     CALL NC_READ_ARR( fID     = ncLun,              &
     780             :                       ncVar   = Lct%Dct%Dta%ncPara, &
     781             :                       lon1    = 1,                  &
     782             :                       lon2    = nlon,               &
     783             :                       lat1    = 1,                  &
     784             :                       lat2    = nlat,               &
     785             :                       lev1    = lev1,               &
     786             :                       lev2    = lev2,               &
     787             :                       time1   = tidx1,              &
     788             :                       time2   = tidx2,              &
     789             :                       ncArr   = ncArr,              &
     790             :                       varUnit = thisUnit,           &
     791             :                       wgt1    = wgt1,               &
     792             :                       wgt2    = wgt2,               &
     793             :                       MissVal = HCO_MISSVAL,        &
     794             :                       ArbIdx  = ArbIdx,             &
     795           0 :                       RC      = NCRC                 )
     796             : 
     797           0 :     IF ( NCRC /= 0 ) THEN
     798           0 :        CALL HCO_ERROR( 'NC_READ_ARRAY', RC )
     799           0 :        RETURN
     800             :     ENDIF
     801             : 
     802             :     ! Check for missing values: set base emissions and masks to 0, and
     803             :     ! scale factors to 1. This will make sure that these entries will
     804             :     ! be ignored.
     805             : !!! CALL CheckMissVal ( Lct, ncArr )
     806             : 
     807             :     !-----------------------------------------------------------------
     808             :     ! Eventually do interpolation between files. This is a pretty
     809             :     ! crude implementation for data interpolation between different
     810             :     ! files. It is only applied to data that is marked as interpolated
     811             :     ! data and if no appropriate interpolation date could be found in
     812             :     ! the first file. This will only be the case if the preferred date-
     813             :     ! time is outside the file range.
     814             :     !-----------------------------------------------------------------
     815           0 :     IF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_INTER .AND. wgt1 < 0.0_sp ) THEN
     816             : 
     817             :        ! No need to read another file if the previous file had exactly the
     818             :        ! time stamp we were looking for.
     819           0 :        IF ( oYMDhm1 == YMDhma ) THEN
     820           0 :           FOUND = .FALSE.
     821             :        ELSE
     822             :           ! Check if there exists another file for a future/previous date
     823             :           ! oYMDhm1 is the originally preferred date, YMDhma is the date read
     824             :           ! from the file. If YMDhma is in the future, we need to look for a
     825             :           ! file in the past. Else, need to look for a file in the future.
     826           0 :           IF ( oYMDhm1 < YMDhma ) THEN
     827           0 :              Direction = -1
     828             :           ELSE
     829           0 :              Direction = +1
     830             :           ENDIF
     831             :           CALL SrcFile_Parse ( HcoState,  Lct, srcFile2, &
     832           0 :                                FOUND, RC, Direction = Direction )
     833           0 :           IF ( RC /= HCO_SUCCESS ) THEN
     834           0 :               CALL HCO_ERROR( 'ERROR 5', RC, THISLOC=LOC )
     835           0 :               RETURN
     836             :           ENDIF
     837             :        ENDIF
     838             : 
     839             :        ! If found, read data. Assume that all meta-data is the same.
     840           0 :        IF ( FOUND ) THEN
     841             : 
     842             :           ! Open file
     843           0 :           CALL NC_OPEN ( TRIM(srcFile2), ncLun2 )
     844             : 
     845             :           ! Define time stamp to be read. Use this call only
     846             :           ! to get the datetime of the first time slice (YMDhm1).
     847             :           ! All other values will be ignored and reset below.
     848             :           CALL GET_TIMEIDX ( HcoState,  Lct,               &
     849             :                              ncLun2,    tidx1,    tidx2,   &
     850             :                              wgt1,      wgt2,     oYMDhm2, &
     851           0 :                              YMDhmb,    YMDhm1,   RC       )
     852           0 :           IF ( RC /= HCO_SUCCESS ) THEN
     853           0 :               CALL HCO_ERROR( 'ERROR 6', RC, THISLOC=LOC )
     854           0 :               RETURN
     855             :           ENDIF
     856             : 
     857             :           ! Always read first time slice
     858           0 :           tidx1 = 1
     859           0 :           tidx2 = 1
     860           0 :           wgt1  = -1.0_sp
     861           0 :           wgt2  = -1.0_sp
     862             : 
     863             :           ! Read data and write into array ncArr2
     864             :           CALL NC_READ_ARR( fID     = ncLun2,             &
     865             :                             ncVar   = Lct%Dct%Dta%ncPara, &
     866             :                             lon1    = 1,                  &
     867             :                             lon2    = nlon,               &
     868             :                             lat1    = 1,                  &
     869             :                             lat2    = nlat,               &
     870             :                             lev1    = lev1,               &
     871             :                             lev2    = lev2,               &
     872             :                             time1   = tidx1,              &
     873             :                             time2   = tidx2,              &
     874             :                             ncArr   = ncArr2,             &
     875             :                             varUnit = thisUnit,           &
     876             :                             wgt1    = wgt1,               &
     877             :                             wgt2    = wgt2,               &
     878             :                             MissVal = HCO_MISSVAL,        &
     879             :                             ArbIdx  = ArbIdx,             &
     880           0 :                             RC      = NCRC                 )
     881           0 :           IF ( NCRC /= 0 ) THEN
     882           0 :              CALL HCO_ERROR( 'NC_READ_ARRAY (2)', RC )
     883           0 :              RETURN
     884             :           ENDIF
     885             : 
     886             :           ! Eventually fissing values
     887             : !!!          CALL CheckMissVal ( Lct, ncArr2 )
     888             : 
     889             :           ! Calculate weights to be applied to ncArr2 and ncArr1. These
     890             :           ! weights are calculated based on the originally preferred
     891             :           ! datetime oYMDh1 and the selected datetime of file 1 (YMDhma)
     892             :           ! and file 2 (YMDhm1)
     893             :           ! If date on file 1 < date on file 2:
     894           0 :           IF ( YMDhma < YMDhm1 ) THEN
     895           0 :              CALL GetWeights ( YMDhma, YMDhm1, oYMDhm1, wgt1, wgt2 )
     896             :           ! If date on file 1 > date on file 2:
     897           0 :           ELSEIF ( YMDhma > YMDhm1 ) THEN
     898           0 :              CALL GetWeights ( YMDhm1, YMDhma, oYMDhm1, wgt2, wgt1 )
     899             :           ! If both datetimes are for some reason the same (this should
     900             :           ! not happen!)
     901             :           ELSE
     902           0 :              wgt1 = 0.5_sp
     903           0 :              wgt2 = 0.5_sp
     904             :           ENDIF
     905             : 
     906             :           ! Apply weights
     907           0 :           ncArr = (wgt1 * ncArr) + (wgt2 * ncArr2)
     908             : 
     909             :           ! Verbose
     910           0 :           IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
     911           0 :              MSG = 'Interpolated data between two files:'
     912           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
     913           0 :              MSG = '- File 1: ' // TRIM(srcFile)
     914           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
     915           0 :              WRITE(MSG,*) '   Time stamp used: ', YMDhma
     916           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
     917           0 :              WRITE(MSG,*) '   Applied weight: ', wgt1
     918           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
     919           0 :              MSG = '- File 2: ' // TRIM(srcFile2)
     920           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
     921           0 :              WRITE(MSG,*) '   Time stamp used: ', YMDhm1
     922           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
     923           0 :              WRITE(MSG,*) '   Applied weight: ', wgt2
     924           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
     925             :           ENDIF
     926             : 
     927             :           ! Cleanup
     928           0 :           IF ( ASSOCIATED(ncArr2) ) DEALLOCATE(ncArr2)
     929             : 
     930             :           ! Close file
     931           0 :           CALL NC_CLOSE ( ncLun2 )
     932             :        ENDIF !FOUND
     933             : 
     934             :     !-----------------------------------------------------------------
     935             :     ! Eventually calculate averages. Currently, averages are only
     936             :     ! calculated on the year dimension, e.g. over years.
     937             :     !-----------------------------------------------------------------
     938           0 :     ELSEIF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_AVERG    .OR. &
     939             :              Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGEAVG       ) THEN
     940             : 
     941             :        ! cYr is the current simulation year
     942             :        CALL HcoClock_Get( HcoState%Clock, cYYYY=cYr, cMM=cMt, cDD=cDy, &
     943           0 :                           cH=cHr, RC=RC )
     944           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     945           0 :            CALL HCO_ERROR( 'ERROR 7', RC, THISLOC=LOC )
     946           0 :            RETURN
     947             :        ENDIF
     948             : 
     949             :        ! Determine year range to be read:
     950             :        ! By default, we would like to average between the year range given
     951             :        ! in the time attribute
     952           0 :        Yr1 = Lct%Dct%Dta%ncYrs(1)
     953           0 :        Yr2 = Lct%Dct%Dta%ncYrs(2)
     954             : 
     955             :        ! If averaging shall only be performed if outside the given
     956             :        ! range, check if current simulation date is within the range
     957             :        ! provied in the configuration file. If so, set year range to
     958             :        ! be read to current year only.
     959           0 :        IF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGEAVG ) ) THEN
     960           0 :           IF ( tIDx_IsInRange(Lct,cYr,cMt,cDy,cHr) ) THEN
     961           0 :              Yr1 = cYr
     962           0 :              Yr2 = cYr
     963             :           ENDIF
     964             :        ENDIF
     965             : 
     966             :        ! Total number of years to be read
     967           0 :        nYears = Yr2 - Yr1 + 1
     968             : 
     969             :        ! Read and add annual data if there is more than one year to be
     970             :        ! used.
     971           0 :        IF ( nYears > 1 ) THEN
     972             : 
     973             :           ! Cleanup ncArr. This is refilled again
     974           0 :           ncArr = 0.0_sp
     975             : 
     976           0 :           DO iYear = Yr1, Yr2
     977             : 
     978             :              ! Get file name for this year
     979             :              CALL SrcFile_Parse ( HcoState, Lct, srcFile2, &
     980           0 :                                   FOUND, RC, Year=iYear )
     981           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     982           0 :                  CALL HCO_ERROR( 'ERROR 8', RC, THISLOC=LOC )
     983           0 :                  RETURN
     984             :              ENDIF
     985             : 
     986             :              ! If found, read data. Assume that all meta-data is the same.
     987           0 :              IF ( .NOT. FOUND ) THEN
     988           0 :                 WRITE(MSG,*) 'Cannot find file for year ', iYear, ' - needed ', &
     989           0 :                    'to perform time-averaging on file ', TRIM(Lct%Dct%Dta%ncFile)
     990           0 :                 CALL HCO_ERROR( MSG, RC )
     991           0 :                 RETURN
     992             :              ENDIF
     993             : 
     994             :              ! Open file
     995           0 :              CALL NC_OPEN ( TRIM(srcFile2), ncLun2 )
     996             : 
     997             :              ! Define time stamp to be read.
     998             :              CALL GET_TIMEIDX ( HcoState,  Lct,               &
     999             :                                 ncLun2,    tidx1,    tidx2,   &
    1000             :                                 wgt1,      wgt2,     oYMDhm2, &
    1001             :                                 YMDhmb,    YMDhm1,   RC,      &
    1002           0 :                                 Year=iYear                    )
    1003           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1004           0 :                  CALL HCO_ERROR( 'ERROR 9', RC, THISLOC=LOC )
    1005           0 :                  RETURN
    1006             :              ENDIF
    1007             : 
    1008             :              ! Do not perform weights
    1009           0 :              wgt1  = -1.0_sp
    1010           0 :              wgt2  = -1.0_sp
    1011             : 
    1012             :              ! Read data and write into array ncArr2
    1013             :              CALL NC_READ_ARR( fID     = ncLun2,             &
    1014             :                                ncVar   = Lct%Dct%Dta%ncPara, &
    1015             :                                lon1    = 1,                  &
    1016             :                                lon2    = nlon,               &
    1017             :                                lat1    = 1,                  &
    1018             :                                lat2    = nlat,               &
    1019             :                                lev1    = lev1,               &
    1020             :                                lev2    = lev2,               &
    1021             :                                time1   = tidx1,              &
    1022             :                                time2   = tidx2,              &
    1023             :                                ncArr   = ncArr2,             &
    1024             :                                varUnit = thisUnit,           &
    1025             :                                wgt1    = wgt1,               &
    1026             :                                wgt2    = wgt2,               &
    1027             :                                MissVal = HCO_MISSVAL,        &
    1028             :                                ArbIdx  = ArbIdx,             &
    1029           0 :                                RC      = NCRC                 )
    1030           0 :              IF ( NCRC /= 0 ) THEN
    1031           0 :                 CALL HCO_ERROR( 'NC_READ_ARRAY (3)', RC )
    1032           0 :                 RETURN
    1033             :              ENDIF
    1034             : 
    1035             :              ! Eventually fissing values
    1036             : !!!             CALL CheckMissVal ( Lct, ncArr2 )
    1037             : 
    1038             :              ! Add all values to ncArr
    1039           0 :              ncArr = ncArr + ncArr2
    1040             : 
    1041             :              ! Cleanup
    1042           0 :              IF ( ASSOCIATED(ncArr2) ) DEALLOCATE(ncArr2)
    1043             : 
    1044             :              ! Close file
    1045           0 :              CALL NC_CLOSE ( ncLun2 )
    1046             : 
    1047             :           ENDDO !iYear
    1048             : 
    1049             :           ! Now calculate average
    1050           0 :           ncArr = ncArr / REAL(nYears,sp)
    1051             : 
    1052             :           ! Verbose
    1053           0 :           IF ( HcoState%amIRoot .AND. HCO_IsVerb(HcoState%Config%Err,1) ) THEN
    1054           0 :              WRITE(MSG,110) TRIM(Lct%Dct%cName), Yr1, Yr2
    1055           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
    1056             :           ENDIF
    1057             :  110      FORMAT( 'Field ', a, ': Average data over years ', I4.4, ' to ', I4.4 )
    1058             : 
    1059             :        ENDIF !nYears>1
    1060             :     ENDIF !Averaging
    1061             : 
    1062             :     !-----------------------------------------------------------------
    1063             :     ! Convert to HEMCO units
    1064             :     ! HEMCO data are all in kg/m2/s for fluxes and kg/m3 for
    1065             :     ! concentrations. Unit conversion is performed based on the
    1066             :     ! unit on the input file and the srcUnit attribute given in the
    1067             :     ! configuration file. By default, HEMCO will attempt to convert
    1068             :     ! the units found in the input file to the standard quantities
    1069             :     ! for mass (kg), area (m2 or m3), and time (s). For instance,
    1070             :     ! g/cm2/hr will be converted to kg/m2/s. The exceptions to this
    1071             :     ! rule are:
    1072             :     ! 1. If srcUnit is set to '1', the input data are expected to
    1073             :     !    be unitless. If the units string on the input file is none
    1074             :     !    of the units recognized by HEMCO as unitless, an error is
    1075             :     !    returned if the unit tolerance setting is set to zero, or
    1076             :     !    a warning is prompted if unit tolerance is greater than zero.
    1077             :     ! 2. If srcUnit is set to 'count', no unit conversion is performed
    1078             :     !    and data will be treated as 'index' data, e.g. regridding will
    1079             :     !    preserve the absolute values.
    1080             :     !-----------------------------------------------------------------
    1081             : 
    1082             :     ! If OrigUnit is set to wildcard character: use unit from source file
    1083           0 :     IF ( TRIM(Lct%Dct%Dta%OrigUnit) == &
    1084             :          TRIM(HCO_GetOpt(HcoState%Config%ExtList,'Wildcard')) ) THEN
    1085           0 :        Lct%Dct%Dta%OrigUnit = TRIM(thisUnit)
    1086             :     ENDIF
    1087             : 
    1088             :     ! If OrigUnit is set to '1' or to 'count', perform no unit
    1089             :     ! conversion.
    1090           0 :     IF ( HCO_IsUnitLess(Lct%Dct%Dta%OrigUnit)  .OR. &
    1091             :          HCO_IsIndexData(Lct%Dct%Dta%OrigUnit)       ) THEN
    1092             : 
    1093             :        ! Check if file unit is also unitless. This will return 0 for
    1094             :        ! unitless, 1 for HEMCO emission unit, 2 for HEMCO conc. unit,
    1095             :        ! -1 otherwise.
    1096           0 :        Flag = HCO_UNIT_SCALCHECK( thisUnit )
    1097             : 
    1098             :        ! Return with error if: (1) thisUnit is recognized as HEMCO unit and
    1099             :        ! unit tolerance is set to zero; (2) thisUnit is neither unitless nor
    1100             :        ! a HEMCO unit and unit tolerance is set to zero or one.
    1101             :        ! The unit tolerance is defined in the configuration file.
    1102           0 :        IF ( Flag /= 0 .AND. UnitTolerance == 0 ) THEN
    1103             :           MSG = 'Illegal unit: ' // TRIM(thisUnit) // '. File: ' // &
    1104           0 :                 TRIM(srcFile)
    1105           0 :           CALL HCO_ERROR( MSG, RC )
    1106           0 :           RETURN
    1107             :        ENDIF
    1108             : 
    1109             :        ! Prompt a warning if thisUnit is not recognized as unitless.
    1110           0 :        IF ( Flag /= 0 ) THEN
    1111             :           MSG = 'Data is treated as unitless, but file attribute suggests ' // &
    1112           0 :                 'it is not: ' // TRIM(thisUnit) // '. File: ' // TRIM(srcFile)
    1113           0 :           CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
    1114             :        ENDIF
    1115             : 
    1116             :        ! Verbose mode
    1117           0 :        IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
    1118           0 :           WRITE(MSG,*) 'Based on srcUnit attribute (', TRIM(Lct%Dct%Dta%OrigUnit), &
    1119           0 :                        '), no unit conversion is performed.'
    1120           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG)
    1121             :        ENDIF
    1122             : 
    1123             :     ! Convert to HEMCO units in all other cases.
    1124             :     ELSE
    1125             : 
    1126             :        ! For zero unit tolerance, make sure that thisUnit matches
    1127             :        ! with unit set in configuration file. For higher unit
    1128             :        ! tolerances, prompt a level 3 warning.
    1129           0 :        IF ( TRIM(Lct%Dct%Dta%OrigUnit) /= TRIM(thisUnit) ) THEN
    1130             :           MSG = 'File units do not match: ' // TRIM(thisUnit) // &
    1131             :                 ' vs. ' // TRIM(Lct%Dct%Dta%OrigUnit)    // &
    1132           0 :                 '. File: ' // TRIM(srcFile)
    1133             : 
    1134           0 :           IF ( UnitTolerance == 0 ) THEN
    1135           0 :              CALL HCO_ERROR( MSG, RC )
    1136           0 :              RETURN
    1137             :           ELSE
    1138           0 :              CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
    1139             :           ENDIF
    1140             :        ENDIF
    1141             : 
    1142             :        ! Shadow species properties needed for unit conversion
    1143           0 :        HcoID = Lct%Dct%HcoID
    1144           0 :        IF ( HcoID > 0 ) THEN
    1145           0 :           MW_g = HcoState%Spc(HcoID)%MW_g
    1146             :        ELSE
    1147           0 :           MW_g = -999.0_hp
    1148             :        ENDIF
    1149             : 
    1150             :        ! Now convert to HEMCO units. This attempts to convert mass,
    1151             :        ! area/volume and time to HEMCO standards (kg, m2/m3, s).
    1152           0 :        ncYr  = FLOOR( MOD( oYMDhm1, 1.0e12_dp ) / 1.0e8_dp )
    1153           0 :        ncMt  = FLOOR( MOD( oYMDhm1, 1.0e8_dp  ) / 1.0e6_dp )
    1154             : 
    1155           0 :        IF ( ncYr == 0 ) THEN
    1156           0 :           CALL HcoClock_Get( HcoState%Clock, cYYYY = ncYr, RC=RC )
    1157           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    1158           0 :               CALL HCO_ERROR( 'ERROR 10', RC, THISLOC=LOC )
    1159           0 :               RETURN
    1160             :           ENDIF
    1161             :        ENDIF
    1162           0 :        IF ( ncMt == 0 ) THEN
    1163           0 :           CALL HcoClock_Get( HcoState%Clock, cMM   = ncMt, RC=RC )
    1164           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    1165           0 :               CALL HCO_ERROR( 'ERROR 11', RC, THISLOC=LOC )
    1166           0 :               RETURN
    1167             :           ENDIF
    1168             :        ENDIF
    1169             : 
    1170             :        ! Verbose mode
    1171           0 :        IF ( HcoState%amIRoot .and. HCO_IsVerb(HcoState%Config%Err,3) ) THEN
    1172           0 :           WRITE(MSG,*) 'Unit conversion settings: '
    1173           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG)
    1174           0 :           WRITE(MSG,*) '- Year, month        : ', ncYr, ncMt
    1175           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG)
    1176             :        ENDIF
    1177             : 
    1178             :        CALL HCO_UNIT_CHANGE(                 &
    1179             :             HcoConfig     = HcoState%Config, &
    1180             :             Array         = ncArr,           &
    1181             :             Units         = thisUnit,        &
    1182             :             MW            = MW_g,            &
    1183             :             YYYY          = ncYr,            &
    1184             :             MM            = ncMt,            &
    1185             :             AreaFlag      = AreaFlag,        &
    1186             :             TimeFlag      = TimeFlag,        &
    1187             :             FACT          = UnitFactor,      &
    1188           0 :             RC            = RC                )
    1189           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    1190           0 :           MSG = 'Cannot convert units for ' // TRIM(Lct%Dct%cName)
    1191           0 :           CALL HCO_ERROR( MSG , RC )
    1192           0 :           RETURN
    1193             :        ENDIF
    1194             : 
    1195             :        ! Verbose mode
    1196           0 :        IF ( UnitFactor /= 1.0_hp ) THEN
    1197           0 :           IF ( HCO_IsVerb(HcoState%Config%Err,1) ) THEN
    1198           0 :              WRITE(MSG,*) 'Data was in units of ', TRIM(thisUnit), &
    1199           0 :                           ' - converted to HEMCO units by applying ', &
    1200           0 :                           'scale factor ', UnitFactor
    1201           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
    1202             :           ENDIF
    1203             :        ELSE
    1204           0 :           IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
    1205           0 :              WRITE(MSG,*) 'Data was in units of ', TRIM(thisUnit), &
    1206           0 :                           ' - unit conversion factor is ', UnitFactor
    1207           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG)
    1208             :           ENDIF
    1209             :        ENDIF
    1210             : 
    1211             :        ! Check for valid unit combinations, i.e. emissions must be kg/m2/s,
    1212             :        ! concentrations kg/m3. Eventually multiply by emission time step
    1213             :        ! or divide by area to obtain those values.
    1214             : 
    1215             :        ! Concentration data
    1216           0 :        IF ( AreaFlag == 3 .AND. TimeFlag == 0 ) THEN
    1217           0 :           Lct%Dct%Dta%IsConc = .TRUE.
    1218             : 
    1219             :        ! If concentration data is per second (kg/m3/s), multiply by emission
    1220             :        ! time step to get concentration (kg/m3).
    1221           0 :        ELSEIF ( AreaFlag == 3 .AND. TimeFlag == 1 ) THEN
    1222           0 :           Lct%Dct%Dta%IsConc = .TRUE.
    1223             : 
    1224           0 :           ncArr = ncArr * HcoState%TS_EMIS
    1225             :           MSG = 'Data converted from kg/m3/s to kg/m3: ' // &
    1226           0 :                 TRIM(Lct%Dct%cName) // ': ' // TRIM(thisUnit)
    1227           0 :           CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
    1228             : 
    1229             :        ! Unitless data
    1230           0 :        ELSEIF ( AreaFlag == -1 .AND. TimeFlag == -1 ) THEN
    1231             :           ! nothing do to
    1232             : 
    1233             :        ! Emission data
    1234           0 :        ELSEIF ( AreaFlag == 2 .AND. TimeFlag == 1 ) THEN
    1235             :           ! nothing do to
    1236             : 
    1237             :        ! Emission data that is not per time (kg/m2): convert to kg/m2/s
    1238           0 :        ELSEIF ( AreaFlag == 2 .AND. TimeFlag == 0 ) THEN
    1239           0 :           ncArr = ncArr / HcoState%TS_EMIS
    1240             :           MSG = 'Data converted from kg/m2 to kg/m2/s: ' // &
    1241           0 :                 TRIM(Lct%Dct%cName) // ': ' // TRIM(thisUnit)
    1242           0 :           CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
    1243             : 
    1244             :        ! Emission data that is not per area (i.e. kg/s) needs to be converted
    1245             :        ! to per area manually.
    1246           0 :        ELSEIF ( AreaFlag == 0 .AND. TimeFlag == 1 ) THEN
    1247             : 
    1248             :           ! Get lat edges: those are read from file if possible, otherwise
    1249             :           ! calculated from the lat midpoints.
    1250             :           ! ==> Sine of lat is needed. Do conversion right here.
    1251             :           CALL NC_GET_GRID_EDGES ( ncLun, 2, LatMid,   nlat, &
    1252           0 :                                    LatEdge,  nlatEdge, NCRC   )
    1253           0 :           IF ( NCRC /= 0 ) THEN
    1254           0 :              MSG = 'Cannot read lat edge of ' // TRIM(srcFile)
    1255           0 :              CALL HCO_ERROR( MSG, RC )
    1256           0 :              RETURN
    1257             :           ENDIF
    1258             : 
    1259             :           ! Now normalize data by area calculated from lat edges.
    1260             :           CALL NORMALIZE_AREA( HcoState, ncArr,   nlon, &
    1261           0 :                                LatEdge,  srcFile, RC     )
    1262           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    1263           0 :               CALL HCO_ERROR( 'ERROR 12', RC, THISLOC=LOC )
    1264           0 :               RETURN
    1265             :           ENDIF
    1266             : 
    1267             :        ! All other combinations are invalid
    1268             :        ELSE
    1269             :           MSG = 'Unit must be unitless, emission or concentration: ' // &
    1270           0 :                 TRIM(Lct%Dct%cName) // ': ' // TRIM(thisUnit)
    1271           0 :           CALL HCO_ERROR( MSG, RC )
    1272           0 :           RETURN
    1273             :        ENDIF
    1274             :     ENDIF ! Unit conversion
    1275             : 
    1276             :     !-----------------------------------------------------------------
    1277             :     ! Get horizontal grid edges
    1278             :     !-----------------------------------------------------------------
    1279             : 
    1280             :     ! Get longitude edges and make sure they are steadily increasing.
    1281             :     CALL NC_GET_GRID_EDGES ( ncLun, 1, LonMid,   nlon, &
    1282           0 :                              LonEdge,  nlonEdge, NCRC   )
    1283           0 :     IF ( NCRC /= 0 ) THEN
    1284           0 :        MSG = 'Cannot read lon edge of ' // TRIM(srcFile)
    1285           0 :        CALL HCO_ERROR( MSG, RC )
    1286           0 :        RETURN
    1287             :     ENDIF
    1288           0 :     CALL HCO_ValidateLon( HcoState, nlonEdge, LonEdge, RC )
    1289           0 :     IF ( RC /= HCO_SUCCESS ) THEN
    1290           0 :         CALL HCO_ERROR( 'ERROR 13', RC, THISLOC=LOC )
    1291           0 :         RETURN
    1292             :     ENDIF
    1293             : 
    1294             :     ! Get latitude edges (only if they have not been read yet
    1295             :     ! for unit conversion)
    1296           0 :     IF ( .NOT. ASSOCIATED( LatEdge ) ) THEN
    1297             :        CALL NC_GET_GRID_EDGES ( ncLun, 2, LatMid,   nlat, &
    1298           0 :                                 LatEdge,  nlatEdge, NCRC   )
    1299           0 :        IF ( NCRC /= 0 ) THEN
    1300           0 :           MSG = 'Cannot read lat edge of ' // TRIM(srcFile)
    1301           0 :           CALL HCO_ERROR( MSG, RC )
    1302           0 :           RETURN
    1303             :        ENDIF
    1304             :     ENDIF
    1305             : 
    1306             :     !-----------------------------------------------------------------
    1307             :     ! Determine regridding algorithm to be applied: use NCREGRID from
    1308             :     ! MESSy only if we need to regrid vertical levels. For all other
    1309             :     ! fields, use the much faster map_a2a.
    1310             :     ! Perform no vertical regridding if the vertical levels are model
    1311             :     ! levels. Model levels are assumed to start at the surface, i.e.
    1312             :     ! the first input level must correspond to the surface level. The
    1313             :     ! total number of vertical levels must not match the number of
    1314             :     ! vertical levels on the simulation grid. Data is not extrapolated
    1315             :     ! beyond the existing levels.
    1316             :     ! Vertical regridding based on NCREGRID will always map the input
    1317             :     ! data onto the entire simulation grid (no extrapolation beyond
    1318             :     ! the vertical input coordinates).
    1319             :     ! Index-based remapping can currently not be done with the MESSy
    1320             :     ! routines, i.e. it is not possible to vertically regrid index-
    1321             :     ! based data.
    1322             :     !-----------------------------------------------------------------
    1323             : 
    1324           0 :     UseMESSy = .FALSE.
    1325           0 :     IF ( nlev > 1 .AND. .NOT. IsModelLevel ) THEN
    1326           0 :        UseMESSy = .TRUE.
    1327             :     ENDIF
    1328             : 
    1329             : #if defined( MODEL_CESM ) || defined( MODEL_WRF )
    1330             :     ! If in WRF or the CESM environment, the vertical grid is arbitrary.
    1331             :     ! MESSy regridding ALWAYS has to be used.
    1332           0 :     IF ( nlev > 1 ) THEN
    1333           0 :       UseMESSy = .TRUE.
    1334             : 
    1335           0 :       IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
    1336           0 :         WRITE(MSG,*) '  ==> WRF/CESM: Always forcing MESSy regridding for number of verticals', nlev, IsModelLevel
    1337           0 :         CALL HCO_MSG(HcoState%Config%Err,MSG)
    1338             :       ENDIF
    1339             :     ENDIF
    1340             : #endif
    1341             : 
    1342           0 :     IF ( HCO_IsIndexData(Lct%Dct%Dta%OrigUnit) .AND. UseMESSy ) THEN
    1343             :        MSG = 'Cannot do MESSy regridding for index data: ' // &
    1344           0 :              TRIM(srcFile)
    1345           0 :        CALL HCO_ERROR( MSG, RC )
    1346           0 :        RETURN
    1347             :     ENDIF
    1348             : 
    1349             :     !-----------------------------------------------------------------
    1350             :     ! Use MESSy regridding
    1351             :     !-----------------------------------------------------------------
    1352           0 :     IF ( UseMESSy ) THEN
    1353           0 :        IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
    1354           0 :           WRITE(MSG,*) '  ==> Use MESSy regridding (NCREGRID)'
    1355           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG)
    1356             :        ENDIF
    1357             : 
    1358             : #if !defined( MODEL_CESM ) && !defined( MODEL_WRF )
    1359             :        ! If we do MESSy regridding, we can only do one time step
    1360             :        ! at a time at the moment!
    1361             :        IF ( tidx1 /= tidx2 ) THEN
    1362             :           MSG = 'Cannot do MESSy regridding for more than one time step; ' &
    1363             :                 // TRIM(srcFile)
    1364             :           CALL HCO_ERROR( MSG, RC )
    1365             :           RETURN
    1366             :        ENDIF
    1367             : 
    1368             :        ! Note: This seems to be a soft restriction - removing this
    1369             :        ! does not conflict with MESSy regridding. Need to check (hplin, 5/30/20)
    1370             :        ! This has to be used for WRF-GC and HEMCO_CESM so ifdefd out
    1371             : #endif
    1372             : 
    1373             : #if defined( MODEL_WRF ) || defined( MODEL_CESM )
    1374             :        !--------------------------------------------------------------
    1375             :        ! Eventually get sigma levels
    1376             :        ! For files that have hardcoded GEOS-Chem "index"-based levels,
    1377             :        ! translate these levels back into a sigma representation
    1378             :        ! of the GEOS-Chem levels (sigma = p/ps on INTERFACE)
    1379             :        !
    1380             :        ! There are caveats with this. This is essentially a copy of the
    1381             :        ! hardcoded hPa lists from
    1382             :        ! http://wiki.seas.harvard.edu/geos-chem/index.php/GEOS-Chem_vertical_grids
    1383             :        ! hard-coded by hand, and we only assume that the data is either
    1384             :        ! 47-levels or 72-levels.
    1385             :        !
    1386             :        ! Parse the 72 list using regex like so: ^ ?\d{1,2} then remove the lines
    1387             :        ! Then you have the 73 edges.
    1388             :        !
    1389             :        ! psfc = PEDGE(0) = 1013.250 hPa
    1390             :        !
    1391             :        ! Ported from the original WRF-GC implementation (hplin, 5/27/20)
    1392             :        !--------------------------------------------------------------
    1393           0 :        IF ( nlev > 1 .AND. IsModelLevel ) THEN
    1394           0 :           IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
    1395           0 :             WRITE(MSG,*) '  ==> WRF/CESM: Writing in fixed sigma coordinates for GEOS-Chem levels', nlon, nlat
    1396           0 :             CALL HCO_MSG(HcoState%Config%Err,MSG)
    1397             :           ENDIF
    1398             : 
    1399           0 :           ALLOCATE(SigEdge(nlon, nlat, nlev))
    1400             : 
    1401           0 :           DO I = 1, nlon
    1402           0 :              DO J = 1, nlat
    1403             :                ! Fill with pre-defined, hard coded sigma levels computed.
    1404           0 :                SigEdge(I, J, :) = GC_72_EDGE_SIGMA(1:nlev)
    1405             :              ENDDO
    1406             :            ENDDO
    1407             :        ENDIF
    1408             : #endif
    1409             : 
    1410             :        !--------------------------------------------------------------
    1411             :        ! Eventually get sigma levels
    1412             :        ! Vertical regridding is performed on sigma interface levels:
    1413             :        ! sigma(i,j,l) = p(i,j,l) / ps(i,j)
    1414             :        ! NC_Get_Sigma_Levels attempts to create the sigma levels from
    1415             :        ! the content of the netCDF file.
    1416             :        ! For now, it is assumed that all input data is on vertical
    1417             :        ! mid-point levels, and the interface values are calculated
    1418             :        ! by linear interpolation of the mid-point values in a second
    1419             :        ! step.
    1420             :        ! For model levels, the sigma levels don't need to be known
    1421             :        ! as vertical interpolation will be done based on subroutine
    1422             :        ! ModelLev_Interpolate (within HCO_MESSY_REGRID).
    1423             :        !--------------------------------------------------------------
    1424           0 :        IF ( nlev > 1 .AND. .NOT. IsModelLevel ) THEN
    1425             : 
    1426             :           ! Get sigma levels
    1427             :           CALL NC_Get_Sigma_Levels ( fID     = ncLun,   &
    1428             :                                      ncFile  = srcFile, &
    1429             :                                      levName = LevName, &
    1430             :                                      lon1    = 1,       &
    1431             :                                      lon2    = nlon,    &
    1432             :                                      lat1    = 1,       &
    1433             :                                      lat2    = nlat,    &
    1434             :                                      lev1    = 1,       &
    1435             :                                      lev2    = nlev,    &
    1436             :                                      time    = tidx1,   &
    1437             :                                      SigLev  = SigLev,  &
    1438             :                                      Dir     = dir,     &
    1439           0 :                                      RC      = NCRC      )
    1440           0 :           IF ( NCRC /= 0 ) THEN
    1441           0 :              CALL HCO_ERROR( 'Cannot read sigma levels of '//TRIM(srcFile), RC )
    1442           0 :              RETURN
    1443             :           ENDIF
    1444             : 
    1445             :           ! Interpolate onto edges
    1446           0 :           CALL SigmaMidToEdges ( HcoState, SigLev, SigEdge, RC )
    1447           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    1448           0 :               CALL HCO_ERROR( 'ERROR 14', RC, THISLOC=LOC )
    1449           0 :               RETURN
    1450             :           ENDIF
    1451             : 
    1452             :           ! Sigma levels are not needed anymore
    1453           0 :           IF ( ASSOCIATED(SigLev) ) DEALLOCATE(SigLev)
    1454             : 
    1455             :           !-----------------------------------------------------------
    1456             :           ! Flip vertical axis if positive axis is 'down', i.e. level
    1457             :           ! index 1 is the top of the atmosphere
    1458             :           !-----------------------------------------------------------
    1459           0 :           IF ( dir == -1 ) THEN
    1460           0 :              SigEdge(:,:,:  ) = SigEdge(:,:,nlev+1:1:-1  )
    1461           0 :              NcArr  (:,:,:,:) = NcArr  (:,:,nlev  :1:-1,:)
    1462             :           ENDIF
    1463             : 
    1464             :        ENDIF ! nlev>1
    1465             : 
    1466             : #if defined( MODEL_WRF ) || defined( MODEL_CESM )
    1467             :        ! Input data is "never" on model levels because model levels can change! (hplin, 5/29/20)
    1468           0 :        IsModelLevel = .false.
    1469             : #endif
    1470             : 
    1471             :        ! Now do the regridding
    1472             :        CALL HCO_MESSY_REGRID ( HcoState,  NcArr,                 &
    1473             :                                LonEdge,   LatEdge,      SigEdge, &
    1474           0 :                                Lct,       IsModelLevel, RC        )
    1475           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    1476           0 :            CALL HCO_ERROR( 'ERROR 15', RC, THISLOC=LOC )
    1477           0 :            RETURN
    1478             :        ENDIF
    1479             : 
    1480             :        ! Cleanup
    1481           0 :        IF ( ASSOCIATED(SigEdge) ) DEALLOCATE(SigEdge)
    1482             : 
    1483             :     !-----------------------------------------------------------------
    1484             :     ! Use map_a2a regridding
    1485             :     !-----------------------------------------------------------------
    1486             :     ELSE
    1487           0 :        IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
    1488           0 :           WRITE(MSG,*) '  ==> Use map_a2a regridding'
    1489           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG)
    1490             :        ENDIF
    1491             : 
    1492           0 :        CALL REGRID_MAPA2A ( HcoState, NcArr, LonEdge, LatEdge, Lct, RC )
    1493           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    1494           0 :            CALL HCO_ERROR( 'ERROR 16', RC, THISLOC=LOC )
    1495           0 :            RETURN
    1496             :        ENDIF
    1497             : 
    1498             :     ENDIF
    1499             : 
    1500             :     !-----------------------------------------------------------------
    1501             :     ! Add to diagnostics (if it exists)
    1502             :     !-----------------------------------------------------------------
    1503           0 :     IF ( HcoState%Options%Field2Diagn ) THEN
    1504           0 :        IF ( Lct%Dct%Dta%SpaceDim == 3 .AND. ASSOCIATED(Lct%Dct%Dta%V3) ) THEN
    1505           0 :           IF ( ASSOCIATED(Lct%Dct%Dta%V3(1)%Val) ) THEN
    1506             :              CALL Diagn_Update ( HcoState, cName=TRIM(Lct%Dct%cName), &
    1507           0 :                                  Array3D=Lct%Dct%Dta%V3(1)%Val, COL=-1, RC=RC )
    1508           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1509           0 :                  CALL HCO_ERROR( 'ERROR 17', RC, THISLOC=LOC )
    1510           0 :                  RETURN
    1511             :              ENDIF
    1512             :           ENDIF
    1513           0 :        ELSEIF ( Lct%Dct%Dta%SpaceDim == 2 .AND. ASSOCIATED(Lct%Dct%Dta%V2) ) THEN
    1514           0 :           IF ( ASSOCIATED(Lct%Dct%Dta%V2(1)%Val) ) THEN
    1515             :              CALL Diagn_Update ( HcoState, cName=TRIM(Lct%Dct%cName), &
    1516           0 :                                  Array2D=Lct%Dct%Dta%V2(1)%Val, COL=-1, RC=RC )
    1517           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1518           0 :                  CALL HCO_ERROR( 'ERROR 18', RC, THISLOC=LOC )
    1519           0 :                  RETURN
    1520             :              ENDIF
    1521             :           ENDIF
    1522             :        ENDIF
    1523             :     ENDIF
    1524             : 
    1525             :     !-----------------------------------------------------------------
    1526             :     ! Cleanup and leave
    1527             :     !-----------------------------------------------------------------
    1528           0 :     IF ( ASSOCIATED ( ncArr   ) ) DEALLOCATE ( ncArr   )
    1529           0 :     IF ( ASSOCIATED ( LonMid  ) ) DEALLOCATE ( LonMid  )
    1530           0 :     IF ( ASSOCIATED ( LatMid  ) ) DEALLOCATE ( LatMid  )
    1531           0 :     IF ( ASSOCIATED ( LevMid  ) ) DEALLOCATE ( LevMid  )
    1532           0 :     IF ( ASSOCIATED ( LonEdge ) ) DEALLOCATE ( LonEdge )
    1533           0 :     IF ( ASSOCIATED ( LatEdge ) ) DEALLOCATE ( LatEdge )
    1534             : 
    1535             :     ! Return w/ success
    1536           0 :     CALL HCO_LEAVE ( HcoState%Config%Err,  RC )
    1537             : 
    1538           0 :   END SUBROUTINE HCOIO_Read
    1539             : !EOC
    1540             : !------------------------------------------------------------------------------
    1541             : !                   Harmonized Emissions Component (HEMCO)                    !
    1542             : !------------------------------------------------------------------------------
    1543             : !BOP
    1544             : !
    1545             : ! !IROUTINE: HCOIO_CloseAll
    1546             : !
    1547             : ! !DESCRIPTION: Subroutine HCOIO\_CloseAll makes sure that there is no open
    1548             : ! netCDF file left in the stream.
    1549             : !\\
    1550             : !\\
    1551             : ! !INTERFACE:
    1552             : !
    1553           0 :   SUBROUTINE HCOIO_CloseAll( HcoState, RC )
    1554             : !
    1555             : ! !USES:
    1556             : !
    1557             :     USE HCO_Ncdf_Mod,   ONLY : NC_CLOSE
    1558             : !
    1559             : ! !INPUT PARAMTERS:
    1560             : !
    1561             :     TYPE(HCO_State), POINTER          :: HcoState    ! HEMCO state
    1562             : !
    1563             : ! !INPUT/OUTPUT PARAMETERS:
    1564             : !
    1565             :     INTEGER,          INTENT(INOUT)   :: RC
    1566             : !
    1567             : ! !REVISION HISTORY:
    1568             : !  24 Mar 2016 - C. Keller: Initial version
    1569             : !  See https://github.com/geoschem/hemco for complete history
    1570             : !EOP
    1571             : !------------------------------------------------------------------------------
    1572             : !BOC
    1573             : !
    1574             : ! !LOCAL VARIABLES:
    1575             : !
    1576             :     !======================================================================
    1577             :     ! HCOIO_CloseAll begins here
    1578             :     !======================================================================
    1579           0 :     IF ( HcoState%ReadLists%FileLun > 0 ) THEN
    1580           0 :        CALL NC_CLOSE( HcoState%ReadLists%FileLun )
    1581           0 :        HcoState%ReadLists%FileLun = -1
    1582             :     ENDIF
    1583             : 
    1584             :     ! Return w/ success
    1585           0 :     RC = HCO_SUCCESS
    1586             : 
    1587           0 :   END SUBROUTINE HCOIO_CloseAll
    1588             : !EOC
    1589             : END MODULE HCOIO_Read_Mod
    1590             : #endif

Generated by: LCOV version 1.14