Example #1
0
def irregular_to_latlon(lon_1d, lat_1d, var_1d, nlon=360, nlat=181):
    '''
    Interpolate a variable on cube-sphere grid (such as FV3) to LatLon grid
    '''

    # Create a lat-lon uniform grid
    out_lon = _np.linspace(0.0, 360.0, nlon, endpoint=False)
    out_lat = _np.linspace(-90.0, 90.0, nlat)
    out_lon, out_lat = _np.meshgrid(out_lon, out_lat)

    # Interpolate from cube to lat-lon grid
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method='linear')

    lon_1d = _np.reshape(out_lon, (nlon * nlat, ))
    lat_1d = _np.reshape(out_lat, (nlon * nlat, ))
    var_1d = _np.reshape(out_var, (nlon * nlat, ))

    lat_1d = lat_1d[~_np.isnan(var_1d)]
    lon_1d = lon_1d[~_np.isnan(var_1d)]
    var_1d = var_1d[~_np.isnan(var_1d)]

    # Fill in extrapolated values with nearest neighbor
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method='nearest')

    return out_lon, out_lat, out_var
Example #2
0
def griddataBA(minfo, models, params, isig, silent=True):
    '''
    Interpolates model grid

    Usage:
    model_interp = griddata(minfo, models, params, isig, silent=True)

    where
    minfo = grid of parameters
    models = grid of models
    params = parameters,
    isig = (normalized) sigma0 index

    Ex:
    # read grid
    xdrpath = 'beatlas/disk_flx.xdr'
    listpar, lbdarr, minfo, models = bat.readBAsed(xdrpath, quiet=True)
    # find isig
    dims = ['M', 'ob', 'sig0', 'nr', 'cosi']
    dims = dict(zip(dims, range(len(dims))))
    isig = dims["sig0"]
    # interpolation
    params = [12.4, 1.44, 0.9, 4.4, 0.1]
    model_interp = np.exp(griddataBA(minfo, np.log(models), params, isig))

    If photospheric models are interpolated, let isig=None. For spectra,
    it is recommended to enter the log of the grid of spectra as input,
    as shown in the example above.
    '''
    # ranges
    ranges = _np.array([[parr.min(), parr.max()] for parr in minfo.T])

    # find neighbours, delete coincidences
    if _phc.is_inside_ranges(isig, [0, len(params)-1]):
        # exclude sig0 dimension, to take all their entries for interpolation
        keep, out, inside_ranges, params1, minfo1 = _phc.find_neighbours(
            _np.delete(params, isig), _np.delete(minfo, isig, axis=1), 
            _np.delete(ranges.T, isig, axis=1).T, silent=silent)
        params = _np.hstack([params1, params[isig]])
        minfo = _np.vstack([minfo1.T, minfo[:, isig]]).T
    else:
        keep, out, inside_ranges, params, minfo = _phc.find_neighbours(params, 
            minfo, ranges, silent=silent)

    # interpolation
    model_interp = _griddata(minfo[keep], models[keep], params, 
        method='linear')[0]

    if _np.isnan(model_interp).any() or _np.sum(model_interp) == 0.:
        if not silent:
            print('[griddataBA] Warning: linear interpolation didnt work, '
                'taking closest model')
        model_interp = _griddata(minfo[keep], models[keep], params, 
            method='nearest')[0]

    return model_interp
Example #3
0
def griddataBA(minfo, models, params, isig, silent=True):
    '''
    Interpolates model grid

    Usage:
    model_interp = griddata(minfo, models, params, isig, silent=True)

    where
    minfo = grid of parameters
    models = grid of models
    params = parameters,
    isig = (normalized) sigma0 index

    Ex:
    # read grid
    xdrpath = 'beatlas/disk_flx.xdr'
    listpar, lbdarr, minfo, models = bat.readBAsed(xdrpath, quiet=True)
    # find isig
    dims = ['M', 'ob', 'sig0', 'nr', 'cosi']
    dims = dict(zip(dims, range(len(dims))))
    isig = dims["sig0"]
    # interpolation
    params = [12.4, 1.44, 0.9, 4.4, 0.1]
    model_interp = np.exp(griddataBA(minfo, np.log(models), params, isig))

    If photospheric models are interpolated, let isig=None. For spectra,
    it is recommended to enter the log of the grid of spectra as input,
    as shown in the example above.
    '''
    # ranges
    ranges = _np.array([[parr.min(), parr.max()] for parr in minfo.T])

    # find neighbours, delete coincidences
    if _phc.is_inside_ranges(isig, [0, len(params)-1]):
        # exclude sig0 dimension, to take all their entries for interpolation
        keep, out, inside_ranges, params1, minfo1 = _phc.find_neighbours(_np.delete(params, isig), \
                                                                    _np.delete(minfo, isig, axis=1), \
                                                                    _np.delete(ranges.T, isig, axis=1).T, \
                                                                    silent=silent)
        params = _np.hstack([params1, params[isig]])
        minfo = _np.vstack([minfo1.T, minfo[:, isig]]).T
    else:
        keep, out, inside_ranges, params, minfo = _phc.find_neighbours(params, minfo, ranges, silent=silent)

    # interpolation
    model_interp = _griddata(minfo[keep], models[keep], params, method='linear')[0]

    if _np.isnan(model_interp).any() or _np.sum(model_interp) == 0.:
        if not silent:
            print('[griddataBA] Warning: linear interpolation didnt work, taking closest model')
        model_interp = _griddata(minfo[keep], models[keep], params, method='nearest')[0]

    return model_interp
Example #4
0
def irregular_to_latlon(lon_1d,
                        lat_1d,
                        var_1d,
                        nlon=360,
                        nlat=181,
                        method='linear'):
    '''
    Interpolate a variable on irregular grid to a LatLon grid
    '''

    # Create a lat-lon uniform grid
    out_lon = _np.linspace(0.0, 360.0, nlon, endpoint=False)
    out_lat = _np.linspace(-90.0, 90.0, nlat)
    out_lon, out_lat = _np.meshgrid(out_lon, out_lat)

    # Interpolate from cube to lat-lon grid
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method=method)

    lon_1d = _np.reshape(out_lon, (nlon * nlat, ))
    lat_1d = _np.reshape(out_lat, (nlon * nlat, ))
    var_1d = _np.reshape(out_var, (nlon * nlat, ))

    lat_1d = lat_1d[~_np.isnan(var_1d)]
    lon_1d = lon_1d[~_np.isnan(var_1d)]
    var_1d = var_1d[~_np.isnan(var_1d)]

    return out_lon, out_lat, out_var
Example #5
0
def tripolar_to_latlon(in_lon, in_lat, in_var, nlon=360, nlat=200):
    '''
    Interpolate a variable on tripolar grid (such as MOM5) to LatLon grid
    '''

    # Make sure Longitude is monotonically increasing
    neg_lons = in_lon < 0.0
    in_lon[neg_lons] = in_lon[neg_lons] + 360.0

    # Roll the indices by 80:
    # This has to do with the tri-polar grid; it starts at 80E (or -280)
    var_roll = _np.roll(in_var, 80, axis=1)
    lon_roll = _np.roll(in_lon, 80, axis=1)
    lat_roll = _np.roll(in_lat, 80, axis=1)

    # Shrink the 2D data in to 1D for interpolating from tri-polar to lat-lon
    # grid
    var_1d = _np.ravel(var_roll)
    lon_1d = _np.ravel(lon_roll)
    lat_1d = _np.ravel(lat_roll)

    # Create a lat-lon uniform grid
    out_lon = _np.linspace(0.0, 360.0, nlon, endpoint=False)
    out_lat = _np.linspace(-90.0, 90.0, nlat)
    out_lon, out_lat = _np.meshgrid(out_lon, out_lat)

    # Interpolate from tri-polar to lat-lon grid and get rid of the ridiculous
    # values
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method='nearest')
    out_var = _np.ma.masked_where(out_var > 1.1 * in_var.max(), out_var)

    return out_lon, out_lat, out_var
Example #6
0
def latlon_to_latlon(lon_in,
                     lat_in,
                     var_in,
                     nlon=360,
                     nlat=181,
                     method='linear'):
    '''
    Interpolate a variable on one LatLon grid to another LatLon grid
    '''

    nx, ny = var_in.shape

    # Shrink the 2D data into 1D data
    lon_1d = _np.reshape(lon_in, (nx * ny, ))
    lat_1d = _np.reshape(lat_in, (nx * ny, ))
    var_1d = _np.reshape(var_in, (nx * ny, ))

    # Create the desired lat-lon uniform grid
    out_lon = _np.linspace(0.0, 360.0, nlon, endpoint=False)
    out_lat = _np.linspace(-90.0, 90.0, nlat)
    out_lon, out_lat = _np.meshgrid(out_lon, out_lat)

    # Interpolate from input lat-lon to desired lat-lon grid
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method=method)

    lon_1d = _np.reshape(out_lon, (nlon * nlat, ))
    lat_1d = _np.reshape(out_lat, (nlon * nlat, ))
    var_1d = _np.reshape(out_var, (nlon * nlat, ))

    lat_1d = lat_1d[~_np.isnan(var_1d)]
    lon_1d = lon_1d[~_np.isnan(var_1d)]
    var_1d = var_1d[~_np.isnan(var_1d)]

    # Fill in extrapolated values with nearest neighbor
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method='nearest')

    return out_lon, out_lat, out_var
Example #7
0
def cube_to_latlon(lon_in,
                   lat_in,
                   var_in,
                   nlon=360,
                   nlat=181,
                   method='linear'):
    '''
    Interpolate a variable on cube-sphere grid (such as FV3) to LatLon grid
    '''

    nf, nx, ny = var_in.shape

    # Shrink the n faces 2D data into 1D data
    lon_1d = _np.reshape(lon_in, (nf * nx * ny, ))
    lat_1d = _np.reshape(lat_in, (nf * nx * ny, ))
    var_1d = _np.reshape(var_in, (nf * nx * ny, ))

    # Create a lat-lon uniform grid
    out_lon = _np.linspace(0.0, 360.0, nlon, endpoint=False)
    out_lat = _np.linspace(-90.0, 90.0, nlat)
    out_lon, out_lat = _np.meshgrid(out_lon, out_lat)

    # Interpolate from cube to lat-lon grid
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method=method)

    lon_1d = _np.reshape(out_lon, (nlon * nlat, ))
    lat_1d = _np.reshape(out_lat, (nlon * nlat, ))
    var_1d = _np.reshape(out_var, (nlon * nlat, ))

    lat_1d = lat_1d[~_np.isnan(var_1d)]
    lon_1d = lon_1d[~_np.isnan(var_1d)]
    var_1d = var_1d[~_np.isnan(var_1d)]

    # Fill in extrapolated values with nearest neighbor
    out_var = _griddata((lon_1d, lat_1d),
                        var_1d, (out_lon, out_lat),
                        method='nearest')

    return out_lon, out_lat, out_var
Example #8
0
def sigma4b_cranmer(M, w):
    '''Computes sigma4b defined in Cranmer 1996 (Eq. 4.22)
    
    Usage:
    s4b = sigma4b_cranmer(M, w)

    where w=Omega/Omega_c, M=stellar mass in Msun (from 1.7 to 20.)
    '''
    dir0 = '{0}/refs/tables/'.format(_hdtpath())
    tab = _np.load(dir0 + 'sigma4b_cranmer.npz')
    s4b = _griddata(tab['parlist'], tab['sigma4b'], _np.array([M, w]), method='linear')[0]
    return s4b
Example #9
0
def size_to_mobility(dna_fragment_length, 
                     efield, 
                     gelconcentration):
    
    muS = dset['muS']/(100*100)      # m**2 to cm**2/V/s
    muL = dset['muL']/(100*100)      # m**2 to cm**2/V/s
    gamma = dset['gamma']*1000       # kbp  to bp
    alpha = 1/muL - 1/muS
    beta = 1/muS
    
    mobility = _griddata( (dset['E'], dset['T']),
                          1/(beta + alpha * (1 - _np.exp(-dna_fragment_length/gamma))),
                          (efield, gelconcentration) )
    return mobility.item()
Example #10
0
def sigma4b_cranmer(M, w):
    '''Computes sigma4b defined in Cranmer 1996 (Eq. 4.22)

    Usage:
    s4b = sigma4b_cranmer(M, w)

    where w=Omega/Omega_c, M=stellar mass in Msun (from 1.7 to 20.)
    '''
    dir0 = '{0}/refs/tables/'.format(_hdtpath())
    tab = _np.load(dir0 + 'sigma4b_cranmer.npz')
    s4b = _griddata(tab['parlist'],
                    tab['sigma4b'],
                    _np.array([M, w]),
                    method='linear')[0]
    return s4b
Example #11
0
def geneva_interp_fast(Mstar, oblat, t, Zstr='014', silent=True):
    '''
    Interpolates Geneva stellar models, from grid of
    pre-computed interpolations.

    Usage:
    Rpole, logL, age = geneva_interp_fast(Mstar, oblat, t, Zstr='014')

    where t is given in tMS, and tar is the open tar file. For now, only
    Zstr='014' is available.
    '''
    # read grid
    dir0 = '{0}/refs/geneva_models/'.format(_hdtpath())
    if Mstar <= 20.:
        fname = 'geneva_interp_Z{:}.npz'.format(Zstr)
    else:
        fname = 'geneva_interp_Z{:}_highM.npz'.format(Zstr)
    data = _np.load(dir0 + fname)
    Mstar_arr = data['Mstar_arr']
    oblat_arr = data['oblat_arr']
    t_arr = data['t_arr']
    Rpole_grid = data['Rpole_grid']
    logL_grid = data['logL_grid']
    age_grid = data['age_grid']

    # build grid of parameters
    par_grid = []
    for M in Mstar_arr:
        for ob in oblat_arr:
            for tt in t_arr:
                par_grid.append([M, ob, tt])
    par_grid = _np.array(par_grid)

    # set input/output parameters
    par = _np.array([Mstar, oblat, t])

    # set ranges
    ranges = _np.array([[par_grid[:, i].min(), par_grid[:, i].max()]
                        for i in range(len(par))])

    # find neighbours
    keep, out, inside_ranges, par, par_grid = _phc.find_neighbours(
        par, par_grid, ranges)

    # interpolation method
    if inside_ranges:
        interp_method = 'linear'
    else:
        if not silent:
            print('[geneva_interp_fast] Warning: parameters out of available '
                  'range, taking closest model')
        interp_method = 'nearest'

    if len(keep[keep]) == 1:
        # coincidence
        Rpole = Rpole_grid.flatten()[keep][0]
        logL = logL_grid.flatten()[keep][0]
        age = age_grid.flatten()[keep][0]
    else:
        # interpolation
        Rpole = _griddata(par_grid[keep],
                          Rpole_grid.flatten()[keep],
                          par,
                          method=interp_method,
                          rescale=True)[0]
        logL = _griddata(par_grid[keep],
                         logL_grid.flatten()[keep],
                         par,
                         method=interp_method,
                         rescale=True)[0]
        age = _griddata(par_grid[keep],
                        age_grid.flatten()[keep],
                        par,
                        method=interp_method,
                        rescale=True)[0]

    return Rpole, logL, age
Example #12
0
def geneva_closest(Mstar, oblat, t, Zstr='014', tar=None, silent=True):
    '''
    Interpolate models between rotation rates, at closest Mstar.

    Usage:
    Rpole, logL = geneva_closest(Mstar, oblat, t, Zstr='014', tar=None, 
        silent=True)

    where t is given in tMS, and tar is the open tar file. The chosen
    metallicity is according to the input tar file. If tar=None, the
    code will take Zstr='014' by default.
    '''
    # oblat to Omega/Omega_c
    w = oblat2w(oblat)

    # grid
    if Mstar <= 20.:
        Mlist = _np.array([1.7, 2., 2.5, 3., 4., 5., 7., 9., 12., 15., 20.])
        Mstr = _np.array([
            '1p700', '2p000', '2p500', '3p000', '4p000', '5p000', '7p000',
            '9p000', '12p00', '15p00', '20p00'
        ])
        Vlist = _np.array([0., 0.1, 0.3, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95])
        Vstr = _np.array([
            '00000', '10000', '30000', '50000', '60000', '70000', '80000',
            '90000', '95000'
        ])
    else:
        Mlist = _np.array([20., 25., 32., 40., 60., 85., 120.])
        Mstr = _np.array(
            ['20p00', '25p00', '32p00', '40p00', '60p00', '85p00', '120p0'])
        Vlist = _np.array([0., 0.568])
        Vstr = _np.array(['00000', '56800'])

    # read tar file
    if tar is None:
        dir0 = '{0}/refs/geneva_models/'.format(_hdtpath())
        fmod = 'Z{:}.tar.gz'.format(Zstr)
        tar = _tarfile.open(dir0 + fmod, 'r:gz')
    else:
        Zstr = tar.getnames()[0][7:10]

    # find closest Mstar
    iM = _np.where(_np.abs(Mstar - Mlist) == _np.min(_np.abs(Mstar -
                                                             Mlist)))[0][0]

    # find values at selected age
    nw = len(Vlist)
    wlist = _np.zeros(nw)
    Rplist = _np.zeros(nw)
    logLlist = _np.zeros(nw)
    agelist = _np.zeros(nw)
    for iw, vs in enumerate(Vstr):
        fname = 'M{:}Z{:}00V{:}.dat'.format(Mstr[iM], Zstr, vs)
        age1, _, logL1, _, Hfrac1, _, _, w1, Rpole1 = geneva_read(fname,
                                                                  tar=tar)
        t1 = age1 / age1[_np.where(Hfrac1 == 0.)[0][0] - 1]
        if t > t1.max() and not silent:
            print('[geneva_closest] Warning: requested age not available, '
                  'taking t/tMS={:.2f} instead of t/tMS={:.2f}.'.format(
                      t1.max(), t))
        it = _np.where(_np.abs(t - t1) == _np.min(_np.abs(t - t1)))[0][0]
        wlist[iw] = w1[it]
        Rplist[iw] = Rpole1[it]
        logLlist[iw] = logL1[it]
        agelist[iw] = age1[it] / 1e6
    # interpolate between rotation rates
    if w <= wlist.max():
        Rpole = _griddata(wlist, Rplist, [w], method='linear')[0]
        logL = _griddata(wlist, logLlist, [w], method='linear')[0]
        age = _griddata(wlist, agelist, [w], method='linear')[0]
    else:
        if not silent:
            print('[geneva_closest] Warning: no model rotating this fast at '
                  'this age, taking closest model instead. (omega={:.2f} '
                  'instead of omega={:.2f})'.format(wlist.max(), w))
        iwmax = _np.where(wlist == wlist.max())[0][0]
        Rpole = Rplist[iwmax]
        logL = logLlist[iwmax]
        age = agelist[iwmax]

    return Rpole, logL, age
Example #13
0
def interpolBA2(params, ctrlarr, minfo, models):
    ctrlarr[_np.isnan(ctrlarr)] = params
    return _griddata(minfo, models, ctrlarr)
Example #14
0
def interpolBA2(params, ctrlarr, minfo, models):
    ctrlarr[_np.isnan(ctrlarr)] = params
    return _griddata(minfo, models, ctrlarr)
Example #15
0
def geneva_interp_fast(Mstar, oblat, t, Zstr='014', silent=True):
    '''
    Interpolates Geneva stellar models, from grid of
    pre-computed interpolations.

    Usage:
    Rpole, logL, age = geneva_interp_fast(Mstar, oblat, t, Zstr='014')

    where t is given in tMS, and tar is the open tar file. For now, only
    Zstr='014' is available.
    '''
    # read grid
    dir0 = '{0}/refs/geneva_models/'.format(_hdtpath())
    if Mstar <= 20.:
        fname = 'geneva_interp_Z{:}.npz'.format(Zstr)
    else:
        fname = 'geneva_interp_Z{:}_highM.npz'.format(Zstr)
    data = _np.load(dir0 + fname)
    Mstar_arr = data['Mstar_arr']
    oblat_arr =data['oblat_arr']
    t_arr = data['t_arr']
    Rpole_grid = data['Rpole_grid']
    logL_grid = data['logL_grid']
    age_grid = data['age_grid']

    # build grid of parameters
    par_grid = []
    for M in Mstar_arr:
        for ob in oblat_arr:
            for tt in t_arr:
                par_grid.append([M, ob, tt])
    par_grid = _np.array(par_grid)

    # set input/output parameters
    par = _np.array([Mstar, oblat, t])

    # set ranges
    ranges = _np.array([[par_grid[:, i].min(), par_grid[:, i].max()] for i in range(len(par))])

    # find neighbours
    keep, out, inside_ranges, par, par_grid = _phc.find_neighbours(par, par_grid, ranges)

    # interpolation method
    if inside_ranges:
        interp_method = 'linear'
    else:
        if not silent:
            print('[geneva_interp_fast] Warning: parameters out of available range, taking closest model')
        interp_method = 'nearest'

    if len(keep[keep]) == 1:
        # coincidence
        Rpole = Rpole_grid.flatten()[keep][0]
        logL = logL_grid.flatten()[keep][0]
        age = age_grid.flatten()[keep][0]
    else:
        # interpolation
        Rpole = _griddata(par_grid[keep], Rpole_grid.flatten()[keep], par, method=interp_method, rescale=True)[0]
        logL = _griddata(par_grid[keep], logL_grid.flatten()[keep], par, method=interp_method, rescale=True)[0]
        age = _griddata(par_grid[keep], age_grid.flatten()[keep], par, method=interp_method, rescale=True)[0]

    return Rpole, logL, age
Example #16
0
def geneva_closest(Mstar, oblat, t, Zstr='014', tar=None, silent=True):
    '''
    Interpolate models between rotation rates, at closest Mstar.

    Usage:
    Rpole, logL = geneva_closest(Mstar, oblat, t, Zstr='014', tar=None, silent=True)

    where t is given in tMS, and tar is the open tar file. The chosen
    metallicity is according to the input tar file. If tar=None, the
    code will take Zstr='014' by default.
    '''
    # oblat to Omega/Omega_c
    w = oblat2w(oblat)

    # grid
    if Mstar <= 20.:
        Mlist = _np.array([1.7, 2., 2.5, 3., 4., 5., 7., 9., 12., 15., 20.])
        Mstr = _np.array(['1p700', '2p000', '2p500', '3p000', '4p000', '5p000', \
                         '7p000', '9p000', '12p00', '15p00', '20p00'])
        Vlist = _np.array([0., 0.1, 0.3, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95])
        Vstr = _np.array(['00000', '10000', '30000', '50000', '60000', '70000', \
                         '80000', '90000', '95000'])
    else:
        Mlist = _np.array([20., 25., 32., 40., 60., 85., 120.])
        Mstr = _np.array(['20p00', '25p00', '32p00', '40p00', '60p00', '85p00', \
                         '120p0'])
        Vlist = _np.array([0., 0.568])
        Vstr = _np.array(['00000', '56800'])

    # read tar file
    if tar == None:
        dir0 = '{0}/refs/geneva_models/'.format(_hdtpath())
        fmod = 'Z{:}.tar.gz'.format(Zstr)
        tar = _tarfile.open(dir0 + fmod, 'r:gz')
    else:
        Zstr = tar.getnames()[0][7:10]

    # find closest Mstar
    iM = _np.where(_np.abs(Mstar-Mlist) == _np.min(_np.abs(Mstar-Mlist)))[0][0]

    # find values at selected age
    nw = len(Vlist)
    wlist = _np.zeros(nw)
    Rplist = _np.zeros(nw)
    logLlist = _np.zeros(nw)
    agelist = _np.zeros(nw)
    for iw, vs in enumerate(Vstr):
        fname = 'M{:}Z{:}00V{:}.dat'.format(Mstr[iM], Zstr, vs)
        age1, _, logL1, _, Hfrac1, _, _, w1, Rpole1 = geneva_read(fname, tar=tar)
        t1 = age1 / age1[_np.where(Hfrac1 == 0.)[0][0]-1]
        if t > t1.max() and not silent:
            print('[geneva_closest] Warning: requested age not available, taking t/tMS={:.2f} instead of t/tMS={:.2f}.'.format(t1.max(),t))
        it = _np.where(_np.abs(t-t1) == _np.min(_np.abs(t-t1)))[0][0]
        wlist[iw] = w1[it]
        Rplist[iw] = Rpole1[it]
        logLlist[iw] = logL1[it]
        agelist[iw] = age1[it] / 1e6
    # interpolate between rotation rates
    if w <= wlist.max():
        Rpole = _griddata(wlist, Rplist, [w], method='linear')[0]
        logL = _griddata(wlist, logLlist, [w], method='linear')[0]
        age = _griddata(wlist, agelist, [w], method='linear')[0]
    else:
        if not silent:
            print('[geneva_closest] Warning: no model rotating this fast at this age, taking closest model instead. (omega={:.2f} instead of omega={:.2f})'.format(wlist.max(),w))
        iwmax = _np.where(wlist == wlist.max())[0][0]
        Rpole = Rplist[iwmax]
        logL = logLlist[iwmax]
        age = agelist[iwmax]

    return Rpole, logL, age