예제 #1
0
def readgridV6(H, **kwargs):
    """
    Accepts a header object as input, and selects appropriate readgrid function
    to use for reading in data from the flexpart binary Fortran files.

    See the :func:`read_grid` for more information on keyword arguments

    This is the 'V6' version of the function.

    """
    # set up the return dictionary (FLEXDATA updates fd, fd is returned)
    FLEXDATA = {}
    fd = reflexible.conv2netcdf4.Structure()

    # OPS is the options Structure, sets defaults, then update w/ kwargs
    fd.options = OPS = reflexible.conv2netcdf4.Structure()
    OPS.unit = 'time'
    OPS.nspec_ret = 0
    OPS.pspec_ret = 0
    OPS.age_ret = 0
    OPS.time_ret = 0
    OPS.scaledepo = 1.0
    OPS.scaleconc = 1.0
    OPS.decayconstant = 9e6
    OPS.date = None
    OPS.calcfoot = False
    OPS.verbose = False
    OPS.BinaryFile = False
    # add keyword overrides and options to header
    OPS.update(kwargs)

    # What direction is the run?
    unit = OPS.unit
    if H['loutstep'] > 0:
        forward = True
        if unit == 'time':
            # default forward unit
            unit = 'conc'
    else:
        forward = False

    # What species to return?
    nspec_ret = OPS.nspec_ret
    if isinstance(nspec_ret, int):
        nspec_ret = [nspec_ret]
    assert iter(nspec_ret), "nspec_ret must be iterable."

    # get times to return
    get_dates = None
    if OPS.time_ret is not None:
        get_dates = []
        time_ret = OPS.time_ret
        if isinstance(time_ret, int) == True:
            time_ret = [time_ret]

        if time_ret[0] < 0:
            if forward == False:
                # get all dates for calculating footprint.
                time_ret = np.arange(len(H.available_dates))
            else:
                raise ValueError(
                    "Must enter a positive time_ret for forward runs")

        for t in time_ret:
            get_dates.append(H.available_dates[t])

    # define what dates to extract if user has explicitly defined a 'date'
    if OPS.date is not None:
        date = OPS.date
        if time_ret is not None:
            Warning("overwriting time_ret variable, date was requested")
        get_dates = []
        if not isinstance(date, list):
            date = date.strip().split(',')
        for d in date:
            try:
                get_dates.append(H.available_dates[H.available_dates.index(d)])
                time_ret = None
            except:
                _shout("Cannot find date: %s in H['available_dates']\n" % d)

    if get_dates is None:
        raise ValueError("Must provide either time_ret or date value.")
    else:
        # assign grid dates for indexing fd
        fd.grid_dates = get_dates[:]

    print('getting grid for: ', get_dates)
    # Some pre-definitions
    fail = 0
    # set filename prefix
    prefix = ['grid_conc_', 'grid_pptv_',
              'grid_time_', 'footprint_', 'footprint_total',
              'grid_conc_nest_', 'grid_pptv_nest_',
              'grid_time_nest_', 'footprint_nest_', 'footprint_total_nest'
              ]

    units = ['conc', 'pptv', 'time', 'footprint', 'footprint_total']
    unit_i = units.index(unit)
    # Determine what module to read, try to use FortFlex, then dumpgrid, lastly pure Python
    # import the FortFlex / Fortran module
    try:
        from .FortFlex import readgrid_v6 as readgrid
        from .FortFlex import sumgrid
        useFortFlex = True
        OPS.useFortFlex = useFortFlex
        print('using FortFlex VERSION 6')
    except:
        # get the original module (no memory allocation)
        useFortFlex = False
        raise Warning('Cannot import FortFlex trying to use BinaryFile')
    if not useFortFlex:
        readgrid = _readgridBF
        OPS.BinaryFile = True

        # cheat: use key2var function to get values from header dict, H
        # need to change this to using H.xxxxx
        # headervars = ['nested','nspec','numxgrid','numygrid','numzgrid','nageclass',\
        #              'dates','pathname','decayconstant','numpoint','numpointspec',
        #              'area','Heightnn','lage']
        # for k in headervars:
        #    key2var(H,k)

        # reserve output fields
    print(H.numxgrid, H.numygrid, H.numzgrid, OPS.nspec_ret, OPS.pspec_ret, OPS.age_ret, len(get_dates), H.numpoint)

    # -------------------------------------------------

    # if forward:
    #    numpointspec = 1
    # else:
    #    numpointspec = numpoint
    # numpointspec = H['numpointspec']
    # if unit_i == 4:
    # grid=np.empty((numxgrid,numygrid,1,nspec_ret,pspec_ret,age_ret,len(get_dates)))
    # else:
    # grid=np.empty((numxgrid,numygrid,numzgrid,nspec_ret,pspec_ret,age_ret,len(get_dates)))
    # zplot=np.empty((numxgrid,numygrid,numzgrid,numpointspec))

    # --------------------------------------------------
    # Loop over all times, given in field H['available_dates']
    # --------------------------------------------------

    for date_i in range(len(get_dates)):
        datestring = get_dates[date_i]
        print(datestring)
        for s in nspec_ret:  # range(OPS.nspec_ret,OPS.nspec_ret+1):
            FLEXDATA[(s, datestring)] = fdc = reflexible.conv2netcdf4.FDC()
            # spec_fid = '_'+str(s+1).zfill(3)

            if unit_i != 4:
                filename = os.path.join(H['pathname'],
                                        prefix[(unit_i) + (H.nested * 5)] + datestring)
                H.zdims = H.numzgrid

            else:
                # grid total footprint
                print("Total footprint")
                filename = os.path.join(H['pathname'],
                                        prefix[(unit_i) + (H.nested * 5)])
                H.zdims = 1

            if os.path.exists(filename):
                H.filename = filename
                # print('reading: ' + filename)
                if OPS.verbose:
                    print('with values:')
                    inputvars = ['filename', 'numxgrid', 'numygrid',
                                 'zdims', 'numpoint', 'nageclass',
                                 'scaledepo', 'scaleconc',
                                 'decayconstant', 'numpointspec']
                    for v in inputvars:
                        print(v, " ==> ", H[v])

                if OPS.BinaryFile:
                    # print('Using BinaryFile')
                    gridT, wetgrid, drygrid, itime = _readgridBF(H, filename)
                else:
                    gridT, wetgrid, drygrid, itime = readgrid(
                        filename, H.numxgrid, H.numygrid, H.zdims,
                        H.numpointspec, H.nageclass, OPS.scaledepo,
                        OPS.scaleconc, H.decayconstant)

                # XXX zplot is the name below. needs some more name consistency
                zplot = gridT

                if OPS.calcfoot:
                    zplot = sumgrid(zplot, gridT,
                                    H.area, H.Heightnn)

                # get the total column and prep the grid
                if H.direction == 'forward':
                    # not trying to do anything here... must be done
                    # after retrieving the grid
                    # D = get_slabs(H,np.squeeze(zplot))
                    # rel_i = H.available_dates.index(datestring)
                    D = zplot
                    rel_i = 'k'
                else:
                    D = zplot
                    rel_i = 'k'

                # NOTE:
                # If you're changing things here, you might want to change
                # them in fill_backward as well, yes I know... something is
                # poorly designed ;(
                fdc.grid = D  # zplot
                fdc.itime = itime
                fdc.timestamp = datetime.datetime.strptime(
                    datestring, '%Y%m%d%H%M%S')
                fdc.species = H['species'][s]
                fdc.gridfile = filename
                fdc.rel_i = rel_i
                fdc.spec_i = s

            else:
                _shout('***ERROR: file %s not found! \n' % filename)
                fail = 1
        fd.set_with_dict(FLEXDATA)

        try:
            # just for testing, set the first available grid as a shortcut
            # this will be removed.
            qind = (0, fd.grid_dates[0])
            fd.grid = fd[qind][fd[qind].keys()[0]].grid
        except:
            pass

    return fd
예제 #2
0
def _readgrid_noFF(H, **kwargs):
    """ accepts a header dictionary as input, returns dictionary of Grid values
    %===========================================
    %
    %-------------------------------------------
    % input
    %   - H: required header dictionary
    %
    % optional (most is obtained from header dict)
    %   - date: which yyyymmddhhmmss from dates
    %   - unit: 'conc', 'pptv', ['time'], 'footprint'
    %   - nspec_ret: numspecies
    %   - pspec_ret:
    %   - age_ret:
    %   - time_ret:
    %   - nested: nested = True
    %
    %
    % output
    %   - grid dictionary object
    %   - fail indicator (-1=fail, 0=success)
    %-------------------------------------------
    % FLEXPART python import routines
    %-------------------------------------------
    % last changes: JFB, 10.10.2008
    %===========================================
    """
    # if os.sys.platform != 'win32':
    #    try:
    #        from FortFlex import readgrid, sumgrid
    #        useFortFlex = 1
    #        print('using FortFlex')
    #    except:
    #        useFortFlex = 0
    #        print('Cannot find FortFlex.so')
    useFortFlex = 0

    if 'date' in kwargs.keys():
        date = kwargs['date']
    # else: date = H['ibtime']
    else:
        date = None

    if 'unit' in kwargs.keys():
        unitname = kwargs['unit']
    else:
        unitname = 'time'

    units = ['conc', 'pptv', 'time', 'footprint']
    unit = units.index(unitname)

    if 'nspec_ret' in kwargs.keys():
        nspec_ret = kwargs['nspec_ret']
    else:
        nspec_ret = 1

    if 'pspec_ret' in kwargs.keys():
        pspec_ret = kwargs['ppsec_ret']
    else:
        pspec_ret = 1

    if 'age_ret' in kwargs.keys():
        age_ret = kwargs['age_ret']
    else:
        age_ret = 1

    if 'nested' in kwargs.keys():
        nested = kwargs['nested']
    else:
        nested = False

    if 'time_ret' in kwargs.keys():
        time_ret = kwargs['time_ret']
    else:
        time_ret = range(len(H['available_dates']))

    if 'scaledepo' in kwargs.keys():
        scaledepo = kwargs['scaledepo']
    else:
        scaledepo = 1.0

    if 'scaleconc' in kwargs.keys():
        scaleconc = kwargs['scaleconc']
    else:
        scaleconc = 1.0

    if 'decaycons' in kwargs.keys():
        decaycons = kwargs['decaycons']
    else:
        decaycons = 99999999990
    fail = -1

    # set filenames
    prefix = ['grid_conc_', 'grid_pptv_',
              'grid_time_', 'footprint_total',
              'grid_conc_nest_', 'grid_pptv_nest_',
              'grid_time_nest_', 'footprint_total_nest']

    # local functions for reading binary data and creating grid dump
    #    skip = lambda n=8 : f.read(n)
    #    getbin = lambda fmt,n=1 : struct.unpack(fmt*n,f.read(struct.calcsize(fmt)))[0]

    # Utility functions
    skip = lambda n=8: f2.seek(n, 1)
    getbin = lambda dtype, n=1: f2.read(dtype, (n,))

    def getdump(n, fmt='f'):
        """ function to get the dump values for the sparse format """
        # print(n)
        skip()
        # Dfmt=[fmt]*n
        #        a=[struct.unpack(ft,f.read(struct.calcsize(ft))) for ft in Dfmt]
        a = f2.read(fmt, n)
        #        dumplist=[a[j][0] for j in range(len(a))]
        # dumplist=[a[j] for j in range(len(a))]
        return a  # dumplist

    def key2var(D, key):
        cmd = "global %s; %s = D['%s'];" % (key, key, key)
        exec(cmd)

    def dumpgrid(dmp_i, cnt_r, dmp_r, grd, k, nage):
        """ function to dump sparse elements into grid """
        ii = 0
        fact = 1
        for ir in range(cnt_r):
            if dmp_r[ir] * fact > 0:
                n = dmp_i[ii]
                ii = ii + 1
                fact = fact * -1.
            else:
                n = n + 1  # XXX n is actually set before this?

            kz = n / (numxgrid * numygrid)
            jy = (n - kz * numxgrid * numygrid) / numxgrid
            ix = n - numxgrid * numygrid * kz - numxgrid * jy
            # print("n  ==> ix,jy,kz,k,nage")
            # print("%s ==> %s,%s,%s,%s,%s") % (n,ix,jy,kz,k,nage)
            # print(grd.shape)
            # print(grd[0,0,0,0,0])
            grd[ix, jy, kz - 1, k, nage] = abs(dmp_r[ir])
        return grd  # flipud(grd.transpose())

    G = {}
    # get values from header file
    H['nageclass'] = H['numageclasses']
    headervars = ['nested', 'nspec', 'numxgrid', 'numygrid', 'numzgrid',
                  'nageclass', 'available_dates', 'pathname', 'decayconstant',
                  'numpoint', 'Area', 'Heightnn']

    for k in headervars:
        key2var(H, k)

    # create zero arrays for datagrid and zplot
    datagrid = np.zeros((numxgrid, numygrid, numzgrid, numpoint),
                        dtype=np.float32)
    zplot = np.empty((numxgrid, numygrid, numzgrid, numpoint, nageclass))

    # --------------------------------------------------
    # Loop over all times, given in field H['dates']
    # --------------------------------------------------
    for ks in range(nspec_ret, nspec_ret + 1):
        # print('processing: ' + str(H['dates'][date_i]) + '   ' + str(ks))
        # print('processing: ' + str(date) + '   ' + str(ks))
        specs = '_' + str(ks).zfill(3)
        fpmax = -999.
        if date is None and time_ret is None:
            get_dates = [available_dates[0]]
        elif time_ret is None:
            get_dates = []
            date = date.strip().split(',')
            for d in date:
                try:
                    get_dates.append(available_dates.index(d))
                except:
                    shout("Cannot find date: %s in H['dates']\n" % d)
        else:
            get_dates = available_dates

        print('getting grid for: ', get_dates)

        for date_i in range(len(get_dates)):
            if unit != 4:
                datestring = H['available_dates'][date_i]
                # datestring = date
                filename = os.path.join(H['pathname'],
                                        prefix[(unit) + (nested * 4)] + datestring + specs)
            else:
                filename = os.path.join(H['pathname'],
                                        prefix[(unit) + (nested * 4)])

            # print('reading: ' + filename)

            if os.path.exists(filename):
                # print(nspec,numxgrid,numygrid,numzgrid,nageclass,scaledepo,scaleconc,decaycons)
                # print(ks)
                # print(date)

                if useFortFlex == 1:
                    # print('Using FortFLEX')
                    ###########################################################
                    # FORTRAN WRAPPER CODE - only works on linux
                    # #
                    # USAGE: grid = readgrid(filegrid,numxgrid,numygrid,numzgrid,\
                    # nspec,nageclass,scaleconc,decayconstant)
                    # #
                    # zplot = sumgrid(zplot, grid, area, heightnn,
                    #         [numxgrid,numygrid,numzgrid,numpoint,nageclass])
                    # #
                    # #
                    # NOTE: numpoint = number of releases, ageclass always 1 for backward
                    # #
                    # RETURN: grid(numxgrid,numygrid,numzgrid,numpoint,nageclass)
                    ###########################################################

                    concgrid = readgrid(filename, numxgrid, numygrid, numzgrid,
                                        numpoint, nageclass,
                                        scaleconc, decayconstant)

                    # contribution[:,:,:] = concgrid[:,:,:,:,0]
                    print(np.min(concgrid))
                    print(np.max(concgrid))

                    # altitude = 50000
                    zplot = sumgrid(zplot, concgrid,
                                    H.area, H.Heightnn)

                else:
                    dat_cnt = 0
                    nage = 0
                    # read data:
                    # datagrid=np.zeros((numxgrid,numygrid,numzgrid[nspec-1],
                    #                    nspec,nageclass),np.float)
                    datagrid = np.zeros(
                        (numxgrid, numygrid, numzgrid, 1, 1), np.float)
                    # f = open(filename, 'rb')
                    # print(filename)
                    f2 = reflexible.conv2netcdf4.BinaryFile(filename, order='fortran')
                    skip(4)
                    G['itime'] = getbin('i')
                    print(H['available_dates'][date_i])

                    # Read Wet Depostion
                    skip()
                    cnt_i = getbin('i')
                    dmp_i = getdump(cnt_i, 'i')
                    skip()
                    cnt_r = getbin('i')
                    dmp_r = getdump(cnt_r)
                    # wet=dumpgrid(dmp_i, cnt_r, dmp_r, datagrid, ks-1, nage)
                    # Read Dry Deposition
                    skip()
                    cnt_i = getbin('i')
                    dmp_i = getdump(cnt_i, 'i')
                    skip()
                    cnt_r = getbin('i')
                    dmp_r = getdump(cnt_r)
                    # dry=dumpgrid(dmp_i, cnt_r, dmp_r, datagrid, ks-1, nage)

                    # Read Concentrations
                    skip()
                    cnt_i = getbin('i')
                    dmp_i = getdump(cnt_i, 'i')
                    skip()
                    cnt_r = getbin('i')
                    dmp_r = getdump(cnt_r)
                    # print(dmp_i, cnt_r, dmp_r, datagrid, ks-1, nage)
                    concgrid = dumpgrid(dmp_i, cnt_r, dmp_r, datagrid,
                                        ks - 1, nage)
                    # G[H['ibtime']].append(concgrid) G[H['ibtime']] = concgrid
                    f2.close()
                fail = 0
            else:
                print("\n\n INPUT ERROR: Could not find file: %s" % filename)
                raise IOError('No file: %s' % filename)

        if useFortFlex == 1:
            G = zplot
    return G
예제 #3
0
def readgridV6(H, **kwargs):
    """
    Accepts a header object as input, and selects appropriate readgrid function
    to use for reading in data from the flexpart binary Fortran files.

    See the :func:`read_grid` for more information on keyword arguments

    This is the 'V6' version of the function.

    """
    # set up the return dictionary (FLEXDATA updates fd, fd is returned)
    FLEXDATA = {}
    fd = reflexible.conv2netcdf4.Structure()

    # OPS is the options Structure, sets defaults, then update w/ kwargs
    fd.options = OPS = reflexible.conv2netcdf4.Structure()
    OPS.unit = 'time'
    OPS.nspec_ret = 0
    OPS.pspec_ret = 0
    OPS.age_ret = 0
    OPS.time_ret = 0
    OPS.scaledepo = 1.0
    OPS.scaleconc = 1.0
    OPS.decayconstant = 9e6
    OPS.date = None
    OPS.calcfoot = False
    OPS.verbose = False
    OPS.BinaryFile = False
    # add keyword overrides and options to header
    OPS.update(kwargs)

    # What direction is the run?
    unit = OPS.unit
    if H['loutstep'] > 0:
        forward = True
        if unit == 'time':
            # default forward unit
            unit = 'conc'
    else:
        forward = False

    # What species to return?
    nspec_ret = OPS.nspec_ret
    if isinstance(nspec_ret, int):
        nspec_ret = [nspec_ret]
    assert iter(nspec_ret), "nspec_ret must be iterable."

    # get times to return
    get_dates = None
    if OPS.time_ret is not None:
        get_dates = []
        time_ret = OPS.time_ret
        if isinstance(time_ret, int) == True:
            time_ret = [time_ret]

        if time_ret[0] < 0:
            if forward == False:
                # get all dates for calculating footprint.
                time_ret = np.arange(len(H.available_dates))
            else:
                raise ValueError(
                    "Must enter a positive time_ret for forward runs")

        for t in time_ret:
            get_dates.append(H.available_dates[t])

    # define what dates to extract if user has explicitly defined a 'date'
    if OPS.date is not None:
        date = OPS.date
        if time_ret is not None:
            Warning("overwriting time_ret variable, date was requested")
        get_dates = []
        if not isinstance(date, list):
            date = date.strip().split(',')
        for d in date:
            try:
                get_dates.append(H.available_dates[H.available_dates.index(d)])
                time_ret = None
            except:
                _shout("Cannot find date: %s in H['available_dates']\n" % d)

    if get_dates is None:
        raise ValueError("Must provide either time_ret or date value.")
    else:
        # assign grid dates for indexing fd
        fd.grid_dates = get_dates[:]

    print('getting grid for: ', get_dates)
    # Some pre-definitions
    fail = 0
    # set filename prefix
    prefix = [
        'grid_conc_', 'grid_pptv_', 'grid_time_', 'footprint_',
        'footprint_total', 'grid_conc_nest_', 'grid_pptv_nest_',
        'grid_time_nest_', 'footprint_nest_', 'footprint_total_nest'
    ]

    units = ['conc', 'pptv', 'time', 'footprint', 'footprint_total']
    unit_i = units.index(unit)
    # Determine what module to read, try to use FortFlex, then dumpgrid, lastly pure Python
    # import the FortFlex / Fortran module
    try:
        from .FortFlex import readgrid_v6 as readgrid
        from .FortFlex import sumgrid
        useFortFlex = True
        OPS.useFortFlex = useFortFlex
        print('using FortFlex VERSION 6')
    except:
        # get the original module (no memory allocation)
        useFortFlex = False
        raise Warning('Cannot import FortFlex trying to use BinaryFile')
    if not useFortFlex:
        readgrid = _readgridBF
        OPS.BinaryFile = True

        # cheat: use key2var function to get values from header dict, H
        # need to change this to using H.xxxxx
        # headervars = ['nested','nspec','numxgrid','numygrid','numzgrid','nageclass',\
        #              'dates','pathname','decayconstant','numpoint','numpointspec',
        #              'area','Heightnn','lage']
        # for k in headervars:
        #    key2var(H,k)

        # reserve output fields
    print(H.numxgrid, H.numygrid, H.numzgrid, OPS.nspec_ret, OPS.pspec_ret,
          OPS.age_ret, len(get_dates), H.numpoint)

    # -------------------------------------------------

    # if forward:
    #    numpointspec = 1
    # else:
    #    numpointspec = numpoint
    # numpointspec = H['numpointspec']
    # if unit_i == 4:
    # grid=np.empty((numxgrid,numygrid,1,nspec_ret,pspec_ret,age_ret,len(get_dates)))
    # else:
    # grid=np.empty((numxgrid,numygrid,numzgrid,nspec_ret,pspec_ret,age_ret,len(get_dates)))
    # zplot=np.empty((numxgrid,numygrid,numzgrid,numpointspec))

    # --------------------------------------------------
    # Loop over all times, given in field H['available_dates']
    # --------------------------------------------------

    for date_i in range(len(get_dates)):
        datestring = get_dates[date_i]
        print(datestring)
        for s in nspec_ret:  # range(OPS.nspec_ret,OPS.nspec_ret+1):
            FLEXDATA[(s, datestring)] = fdc = reflexible.conv2netcdf4.FDC()
            # spec_fid = '_'+str(s+1).zfill(3)

            if unit_i != 4:
                filename = os.path.join(
                    H['pathname'],
                    prefix[(unit_i) + (H.nested * 5)] + datestring)
                H.zdims = H.numzgrid

            else:
                # grid total footprint
                print("Total footprint")
                filename = os.path.join(H['pathname'],
                                        prefix[(unit_i) + (H.nested * 5)])
                H.zdims = 1

            if os.path.exists(filename):
                H.filename = filename
                # print('reading: ' + filename)
                if OPS.verbose:
                    print('with values:')
                    inputvars = [
                        'filename', 'numxgrid', 'numygrid', 'zdims',
                        'numpoint', 'nageclass', 'scaledepo', 'scaleconc',
                        'decayconstant', 'numpointspec'
                    ]
                    for v in inputvars:
                        print(v, " ==> ", H[v])

                if OPS.BinaryFile:
                    # print('Using BinaryFile')
                    gridT, wetgrid, drygrid, itime = _readgridBF(H, filename)
                else:
                    gridT, wetgrid, drygrid, itime = readgrid(
                        filename, H.numxgrid, H.numygrid, H.zdims,
                        H.numpointspec, H.nageclass, OPS.scaledepo,
                        OPS.scaleconc, H.decayconstant)

                # XXX zplot is the name below. needs some more name consistency
                zplot = gridT

                if OPS.calcfoot:
                    zplot = sumgrid(zplot, gridT, H.area, H.Heightnn)

                # get the total column and prep the grid
                if H.direction == 'forward':
                    # not trying to do anything here... must be done
                    # after retrieving the grid
                    # D = get_slabs(H,np.squeeze(zplot))
                    # rel_i = H.available_dates.index(datestring)
                    D = zplot
                    rel_i = 'k'
                else:
                    D = zplot
                    rel_i = 'k'

                # NOTE:
                # If you're changing things here, you might want to change
                # them in fill_backward as well, yes I know... something is
                # poorly designed ;(
                fdc.grid = D  # zplot
                fdc.itime = itime
                fdc.timestamp = datetime.datetime.strptime(
                    datestring, '%Y%m%d%H%M%S')
                fdc.species = H['species'][s]
                fdc.gridfile = filename
                fdc.rel_i = rel_i
                fdc.spec_i = s

            else:
                _shout('***ERROR: file %s not found! \n' % filename)
                fail = 1
        fd.set_with_dict(FLEXDATA)

        try:
            # just for testing, set the first available grid as a shortcut
            # this will be removed.
            qind = (0, fd.grid_dates[0])
            fd.grid = fd[qind][fd[qind].keys()[0]].grid
        except:
            pass

    return fd
예제 #4
0
def readgridV8(H, **kwargs):
    """
    Accepts a header object as input, and selects appropriate readgrid function
    to use for reading in data from the flexpart binary Fortran files.

    See the :func:`read_grid` for more information on keyword arguments

    This is the 'V8' version of the function.

    """
    # set up the return dictionary (FLEXDATA updates fd, fd is returned)
    FLEXDATA = {}
    fd = reflexible.conv2netcdf4.Structure()

    # OPS is the options Structure, sets defaults, then update w/ kwargs
    fd.options = OPS = reflexible.conv2netcdf4.Structure()
    OPS.unit = H.unit
    OPS.getwet = False
    OPS.getdry = False
    OPS.nspec_ret = 0
    # allows to select an index of npsec when calling readgrid
    OPS.npspec_int = False
    OPS.pspec_ret = 0
    OPS.age_ret = 0
    OPS.time_ret = 0
    OPS.scaledepo = 1.0
    OPS.scaleconc = 1.0
    OPS.decayconstant = 9e6
    OPS.date = None
    OPS.calcfoot = False
    OPS.verbose = False
    OPS.BinaryFile = False
    OPS.version = 'V8'
    # add keyword overrides and options to header
    OPS.update(kwargs)
    # H.update(OPS)

    # What direction is the run?
    unit = OPS.unit

    if H['loutstep'] > 0:
        forward = True
        if unit == 'time':
            # default forward unit
            unit = 'conc'
            OPS.unit = unit
    else:
        forward = False

    # What species to return?
    nspec_ret = OPS.nspec_ret
    if isinstance(nspec_ret, int):
        nspec_ret = [nspec_ret]
    assert iter(nspec_ret), "nspec_ret must be iterable."

    # get times to return
    get_dates = None
    if OPS.time_ret is not None:
        get_dates = []
        time_ret = OPS.time_ret
        if isinstance(time_ret, int) == True:
            time_ret = [time_ret]

        if time_ret[0] < 0:
            # if forward == False:
                # get all dates for calculating footprint.
            time_ret = np.arange(len(H.available_dates))
            # else:
            #    raise ValueError("Must enter a positive time_ret for forward runs")

        for t in time_ret:
            get_dates.append(H.available_dates[t])

    # define what dates to extract if user has explicitly defined a 'date'
    if OPS.date is not None:
        date = OPS.date
        if time_ret is not None:
            Warning("overwriting time_ret variable, date was requested")
        get_dates = []
        if not isinstance(date, list):
            date = date.strip().split(',')
        for d in date:
            try:
                get_dates.append(H.available_dates[H.available_dates.index(d)])
                time_ret = None
            except:
                _shout("Cannot find date: %s in H['available_dates']\n" % d)

    if get_dates is None:
        raise ValueError("Must provide either time_ret or date value.")
    else:
        # assign grid dates for indexing fd
        fd.grid_dates = get_dates[:]

    print 'getting grid for: ', get_dates
    # Some pre-definitions
    fail = 0
    # set filename prefix
    prefix = ['grid_conc_', 'grid_pptv_',
              'grid_time_', 'footprint_', 'footprint_total',
              'grid_conc_nest_', 'grid_pptv_nest_',
              'grid_time_nest_', 'footprint_nest_', 'footprint_total_nest'
              ]

    units = ['conc', 'pptv', 'time', 'footprint', 'footprint_total']
    unit_i = units.index(unit)

    # Determine what module to read, try to use FortFlex, then dumpgrid, lastly pure Python
    # import the FortFlex / Fortran module
    try:
        print('Assumed V8 Flexpart')
        from .FortFlex import readgrid, sumgrid
        useFortFlex = True
        print('Using readgrid from FortFlex')
    except:
        # get the original module (no memory allocation)
        try:
            from nilu.pflexpart.FortFlex import readgrid, sumgrid
            useFortFlex = True
            print('Using old nilu.pflexpart.FortFlex')
            # print 'using nilu.pflexpart FortFlex'
        except:
            useFortFlex = False
            print('Cannot load FortFlex, reverting to BinaryFile.')
    if not useFortFlex:
        readgrid = _readgridBF
        OPS.BinaryFile = True
        print('Using BinaryFile')

    # reserve output fields
    print H.numxgrid, H.numygrid, H.numzgrid, OPS.nspec_ret, OPS.pspec_ret, OPS.age_ret, len(get_dates), H.numpoint

    # -------------------------------------------------

    # add the requests to the fd object to be returned
    OPS.unit = unit

    #--------------------------------------------------
    # Loop over all times, given in field H['available_dates']
    #--------------------------------------------------

    for date_i in range(len(get_dates)):
        datestring = get_dates[date_i]
        print datestring
        for s in nspec_ret:  # range(OPS.nspec_ret,OPS.nspec_ret+1):A
            FLEXDATA[(s, datestring)] = fdc = reflexible.conv2netcdf4.FDC()
            spec_fid = '_' + str(s + 1).zfill(3)

            if unit_i != 4:
                filename = os.path.join(
                    H['pathname'],
                    prefix[(unit_i) + (H.nested * 5)] + datestring + spec_fid)
                H.zdims = H.numzgrid

            else:
                # grid total footprint
                print "Total footprint"
                filename = os.path.join(
                    H['pathname'],
                    prefix[(unit_i) + (H.nested * 5)] + spec_fid)
                H.zdims = 1

            if os.path.exists(filename):
                H.filename = filename
                # print 'reading: ' + filename
                if OPS.verbose:
                    print 'with values:'
                    inputvars = ['filename', 'numxgrid', 'numygrid',
                                 'zdims', 'numpoint', 'nageclass',
                                 'scaledepo', 'scaleconc',
                                 'decayconstant', 'numpointspec']
                    for v in inputvars:
                        print v, " ==> ", H[v]

                if OPS.BinaryFile:
                    print("Reading {0} with BinaryFile".format(filename))
                    gridT, wetgrid, drygrid, itime = _readgridBF(H, filename)
                else:
                    # Quick fix for Sabine's Ship releases, added nspec_int so that only one
                    # field of the nspec dimension is actually read
                    if OPS.npspec_int is not False:
                        npspec_int = OPS.npspec_int
                        numpointspec = 1
                    else:
                        npspec_int = 0
                        numpointspec = H.numpointspec

                    gridT, wetgrid, drygrid, itime = readgrid(
                        filename, H.numxgrid, H.numygrid, H.zdims,
                        numpointspec, H.nageclass, OPS.scaledepo,
                        OPS.scaleconc, H.decayconstant, npspec_int)
                if OPS.getwet:
                    wet = wetgrid
                if OPS.getdry:
                    dry = drygrid

                # XXX zplot is the name below. needs some more name consistency
                zplot = gridT

                if OPS.calcfoot:
                    zplot = sumgrid(zplot, gridT, H.area, H.Heightnn)

                # get the total column and prep the grid
                if H.direction == 'forward':
                    # not trying to do anything here... must be done
                    # after retrieving the grid
                    # D = get_slabs(H,np.squeeze(zplot))
                    rel_i = 0  # H.available_dates.index(datestring)
                    D = zplot

                else:
                    D = zplot
                    rel_i = 'k'

                # NOTE:
                # If you're changing things here, you might want to change
                # them in fill_backward as well, yes I know... something is
                # poorly designed ;(

                fdc.grid = D  # zplot

                fdc.itime = itime

                fdc.timestamp = \
                    datetime.datetime.strptime(datestring, '%Y%m%d%H%M%S')
                fdc.species = H['species'][s]
                fdc.gridfile = filename
                fdc.rel_i = rel_i
                fdc.spec_i = s
                if OPS.getwet:
                    fdc.wet = wet
                else:
                    fdc.wet = None

                if OPS.getdry:
                    fdc.dry = dry
                else:
                    fdc.dry = None

            else:
                _shout('***ERROR: file %s not found! \n' % filename)
                fail = 1

        fd.set_with_dict(FLEXDATA)  # XXX keys are tuples, is this really intended?
        try:
            # just for testing, set the first available grid as a shortcut
            # this will be removed.
            # TODO: this can be removed now?
            qind = (nspec_ret[0], fd.grid_dates[0])
            fd.grid = fd[qind][fd[qind].keys()[0]].grid
        except:
            pass

    return fd
예제 #5
0
def _readgrid_noFF(H, **kwargs):
    """ accepts a header dictionary as input, returns dictionary of Grid values
    %===========================================
    %
    %-------------------------------------------
    % input
    %   - H: required header dictionary
    %
    % optional (most is obtained from header dict)
    %   - date: which yyyymmddhhmmss from dates
    %   - unit: 'conc', 'pptv', ['time'], 'footprint'
    %   - nspec_ret: numspecies
    %   - pspec_ret:
    %   - age_ret:
    %   - time_ret:
    %   - nested: nested = True
    %
    %
    % output
    %   - grid dictionary object
    %   - fail indicator (-1=fail, 0=success)
    %-------------------------------------------
    % FLEXPART python import routines
    %-------------------------------------------
    % last changes: JFB, 10.10.2008
    %===========================================
    """
    # if os.sys.platform != 'win32':
    #    try:
    #        from FortFlex import readgrid, sumgrid
    #        useFortFlex = 1
    #        print('using FortFlex')
    #    except:
    #        useFortFlex = 0
    #        print('Cannot find FortFlex.so')
    useFortFlex = 0

    if 'date' in kwargs.keys():
        date = kwargs['date']
    # else: date = H['ibtime']
    else:
        date = None

    if 'unit' in kwargs.keys():
        unitname = kwargs['unit']
    else:
        unitname = 'time'

    units = ['conc', 'pptv', 'time', 'footprint']
    unit = units.index(unitname)

    if 'nspec_ret' in kwargs.keys():
        nspec_ret = kwargs['nspec_ret']
    else:
        nspec_ret = 1

    if 'pspec_ret' in kwargs.keys():
        pspec_ret = kwargs['ppsec_ret']
    else:
        pspec_ret = 1

    if 'age_ret' in kwargs.keys():
        age_ret = kwargs['age_ret']
    else:
        age_ret = 1

    if 'nested' in kwargs.keys():
        nested = kwargs['nested']
    else:
        nested = False

    if 'time_ret' in kwargs.keys():
        time_ret = kwargs['time_ret']
    else:
        time_ret = range(len(H['available_dates']))

    if 'scaledepo' in kwargs.keys():
        scaledepo = kwargs['scaledepo']
    else:
        scaledepo = 1.0

    if 'scaleconc' in kwargs.keys():
        scaleconc = kwargs['scaleconc']
    else:
        scaleconc = 1.0

    if 'decaycons' in kwargs.keys():
        decaycons = kwargs['decaycons']
    else:
        decaycons = 99999999990
    fail = -1

    # set filenames
    prefix = [
        'grid_conc_', 'grid_pptv_', 'grid_time_', 'footprint_total',
        'grid_conc_nest_', 'grid_pptv_nest_', 'grid_time_nest_',
        'footprint_total_nest'
    ]

    # local functions for reading binary data and creating grid dump
    #    skip = lambda n=8 : f.read(n)
    #    getbin = lambda fmt,n=1 : struct.unpack(fmt*n,f.read(struct.calcsize(fmt)))[0]

    # Utility functions
    skip = lambda n=8: f2.seek(n, 1)
    getbin = lambda dtype, n=1: f2.read(dtype, (n, ))

    def getdump(n, fmt='f'):
        """ function to get the dump values for the sparse format """
        # print(n)
        skip()
        # Dfmt=[fmt]*n
        #        a=[struct.unpack(ft,f.read(struct.calcsize(ft))) for ft in Dfmt]
        a = f2.read(fmt, n)
        #        dumplist=[a[j][0] for j in range(len(a))]
        # dumplist=[a[j] for j in range(len(a))]
        return a  # dumplist

    def key2var(D, key):
        cmd = "global %s; %s = D['%s'];" % (key, key, key)
        exec(cmd)

    def dumpgrid(dmp_i, cnt_r, dmp_r, grd, k, nage):
        """ function to dump sparse elements into grid """
        ii = 0
        fact = 1
        for ir in range(cnt_r):
            if dmp_r[ir] * fact > 0:
                n = dmp_i[ii]
                ii = ii + 1
                fact = fact * -1.
            else:
                n = n + 1  # XXX n is actually set before this?

            kz = n / (numxgrid * numygrid)
            jy = (n - kz * numxgrid * numygrid) / numxgrid
            ix = n - numxgrid * numygrid * kz - numxgrid * jy
            # print("n  ==> ix,jy,kz,k,nage")
            # print("%s ==> %s,%s,%s,%s,%s") % (n,ix,jy,kz,k,nage)
            # print(grd.shape)
            # print(grd[0,0,0,0,0])
            grd[ix, jy, kz - 1, k, nage] = abs(dmp_r[ir])
        return grd  # flipud(grd.transpose())

    G = {}
    # get values from header file
    H['nageclass'] = H['numageclasses']
    headervars = [
        'nested', 'nspec', 'numxgrid', 'numygrid', 'numzgrid', 'nageclass',
        'available_dates', 'pathname', 'decayconstant', 'numpoint', 'Area',
        'Heightnn'
    ]

    for k in headervars:
        key2var(H, k)

    # create zero arrays for datagrid and zplot
    datagrid = np.zeros((numxgrid, numygrid, numzgrid, numpoint),
                        dtype=np.float32)
    zplot = np.empty((numxgrid, numygrid, numzgrid, numpoint, nageclass))

    # --------------------------------------------------
    # Loop over all times, given in field H['dates']
    # --------------------------------------------------
    for ks in range(nspec_ret, nspec_ret + 1):
        # print('processing: ' + str(H['dates'][date_i]) + '   ' + str(ks))
        # print('processing: ' + str(date) + '   ' + str(ks))
        specs = '_' + str(ks).zfill(3)
        fpmax = -999.
        if date is None and time_ret is None:
            get_dates = [available_dates[0]]
        elif time_ret is None:
            get_dates = []
            date = date.strip().split(',')
            for d in date:
                try:
                    get_dates.append(available_dates.index(d))
                except:
                    shout("Cannot find date: %s in H['dates']\n" % d)
        else:
            get_dates = available_dates

        print('getting grid for: ', get_dates)

        for date_i in range(len(get_dates)):
            if unit != 4:
                datestring = H['available_dates'][date_i]
                # datestring = date
                filename = os.path.join(
                    H['pathname'],
                    prefix[(unit) + (nested * 4)] + datestring + specs)
            else:
                filename = os.path.join(H['pathname'],
                                        prefix[(unit) + (nested * 4)])

            # print('reading: ' + filename)

            if os.path.exists(filename):
                # print(nspec,numxgrid,numygrid,numzgrid,nageclass,scaledepo,scaleconc,decaycons)
                # print(ks)
                # print(date)

                if useFortFlex == 1:
                    # print('Using FortFLEX')
                    ###########################################################
                    # FORTRAN WRAPPER CODE - only works on linux
                    # #
                    # USAGE: grid = readgrid(filegrid,numxgrid,numygrid,numzgrid,\
                    # nspec,nageclass,scaleconc,decayconstant)
                    # #
                    # zplot = sumgrid(zplot, grid, area, heightnn,
                    #         [numxgrid,numygrid,numzgrid,numpoint,nageclass])
                    # #
                    # #
                    # NOTE: numpoint = number of releases, ageclass always 1 for backward
                    # #
                    # RETURN: grid(numxgrid,numygrid,numzgrid,numpoint,nageclass)
                    ###########################################################

                    concgrid = readgrid(filename, numxgrid, numygrid, numzgrid,
                                        numpoint, nageclass, scaleconc,
                                        decayconstant)

                    # contribution[:,:,:] = concgrid[:,:,:,:,0]
                    print(np.min(concgrid))
                    print(np.max(concgrid))

                    # altitude = 50000
                    zplot = sumgrid(zplot, concgrid, H.area, H.Heightnn)

                else:
                    dat_cnt = 0
                    nage = 0
                    # read data:
                    # datagrid=np.zeros((numxgrid,numygrid,numzgrid[nspec-1],
                    #                    nspec,nageclass),np.float)
                    datagrid = np.zeros((numxgrid, numygrid, numzgrid, 1, 1),
                                        np.float)
                    # f = open(filename, 'rb')
                    # print(filename)
                    f2 = reflexible.conv2netcdf4.BinaryFile(filename,
                                                            order='fortran')
                    skip(4)
                    G['itime'] = getbin('i')
                    print(H['available_dates'][date_i])

                    # Read Wet Depostion
                    skip()
                    cnt_i = getbin('i')
                    dmp_i = getdump(cnt_i, 'i')
                    skip()
                    cnt_r = getbin('i')
                    dmp_r = getdump(cnt_r)
                    # wet=dumpgrid(dmp_i, cnt_r, dmp_r, datagrid, ks-1, nage)
                    # Read Dry Deposition
                    skip()
                    cnt_i = getbin('i')
                    dmp_i = getdump(cnt_i, 'i')
                    skip()
                    cnt_r = getbin('i')
                    dmp_r = getdump(cnt_r)
                    # dry=dumpgrid(dmp_i, cnt_r, dmp_r, datagrid, ks-1, nage)

                    # Read Concentrations
                    skip()
                    cnt_i = getbin('i')
                    dmp_i = getdump(cnt_i, 'i')
                    skip()
                    cnt_r = getbin('i')
                    dmp_r = getdump(cnt_r)
                    # print(dmp_i, cnt_r, dmp_r, datagrid, ks-1, nage)
                    concgrid = dumpgrid(dmp_i, cnt_r, dmp_r, datagrid, ks - 1,
                                        nage)
                    # G[H['ibtime']].append(concgrid) G[H['ibtime']] = concgrid
                    f2.close()
                fail = 0
            else:
                print("\n\n INPUT ERROR: Could not find file: %s" % filename)
                raise IOError('No file: %s' % filename)

        if useFortFlex == 1:
            G = zplot
    return G