Example #1
0
 def grid_latlon(self):
     """
     Return the latitude and longitude coordinate vectors of the
     model grid.
     """
     lats, _ = gaussian_lats_wts(self.nlat)
     lons = np.arange(0., 360., 360. / self.nlon)
     return lats, lons
Example #2
0
def inspect_gridtype(latitudes):
    """
    Determine a grid type by examining the points of a latitude
    dimension.

    Raises a ValueError if the grid type cannot be determined.

    **Argument:**

    *latitudes*
        An iterable of latitude point values.

    **Returns:**

    *gridtype*
        Either 'gaussian' for a Gaussian grid or 'regular' for an
        equally-spaced grid.

    """
    # Define a tolerance value for differences, this value must be much
    # smaller than expected grid spacings.
    tolerance = 5e-4
    # Get the number of latitude points in the dimension.
    nlat = len(latitudes)
    diffs = np.abs(np.diff(latitudes))
    equally_spaced = (np.abs(diffs - diffs[0]) < tolerance).all()
    if not equally_spaced:
        # The latitudes are not equally-spaced, which suggests they might
        # be gaussian. Construct sample gaussian latitudes and check if
        # the two match.
        gauss_reference, wts = gaussian_lats_wts(nlat)
        difference = np.abs(latitudes - gauss_reference)
        if (difference > tolerance).any():
            raise ValueError('latitudes are neither equally-spaced '
                             'or Gaussian')
        gridtype = 'gaussian'
    else:
        # The latitudes are equally-spaced. Construct reference global
        # equally spaced latitudes and check that the two match.
        if nlat % 2:
            # Odd number of latitudes includes the poles.
            equal_reference = np.linspace(90, -90, nlat)
        else:
            # Even number of latitudes doesn't include the poles.
            delta_latitude = 180. / nlat
            equal_reference = np.linspace(90 - 0.5 * delta_latitude,
                                          -90 + 0.5 * delta_latitude,
                                          nlat)
        difference = np.abs(latitudes - equal_reference)
        if (difference > tolerance).any():
            raise ValueError('equally-spaced latitudes are invalid '
                             '(they may be non-global)')
        gridtype = 'regular'
    return gridtype
Example #3
0
def inspect_gridtype(latitudes):
    """
    Determine a grid type by examining the points of a latitude
    dimension.

    Raises a ValueError if the grid type cannot be determined.

    **Argument:**

    *latitudes*
        An iterable of latitude point values.

    **Returns:**

    *gridtype*
        Either 'gaussian' for a Gaussian grid or 'regular' for an
        equally-spaced grid.

    """
    # Define a tolerance value for differences, this value must be much
    # smaller than expected grid spacings.
    tolerance = 5e-4
    # Get the number of latitude points in the dimension.
    nlat = len(latitudes)
    diffs = np.abs(np.diff(latitudes))
    equally_spaced = (np.abs(diffs - diffs[0]) < tolerance).all()
    if not equally_spaced:
        # The latitudes are not equally-spaced, which suggests they might
        # be gaussian. Construct sample gaussian latitudes and check if
        # the two match.
        gauss_reference, wts = gaussian_lats_wts(nlat)
        difference = np.abs(latitudes - gauss_reference)
        if (difference > tolerance).any():
            raise ValueError('latitudes are neither equally-spaced '
                             'or Gaussian')
        gridtype = 'gaussian'
    else:
        # The latitudes are equally-spaced. Construct reference global
        # equally spaced latitudes and check that the two match.
        if nlat % 2:
            # Odd number of latitudes includes the poles.
            equal_reference = np.linspace(90, -90, nlat)
        else:
            # Even number of latitudes doesn't include the poles.
            delta_latitude = 180. / nlat
            equal_reference = np.linspace(90 - 0.5 * delta_latitude,
                                          -90 + 0.5 * delta_latitude, nlat)
        difference = np.abs(latitudes - equal_reference)
        if (difference > tolerance).any():
            raise ValueError('equally-spaced latitudes are invalid '
                             '(they may be non-global)')
        gridtype = 'regular'
    return gridtype
Example #4
0
 def __init__(self,sp,dt,ntrunc,ptop=0.,p0=1.e5,grav=9.80616,omega=7.292e-5,cp=1004,\
         rgas=287.,efold=3600.,ndiss=8,tdrag=1.e30,tdiab=1.e30,\
         umax=40,jetexp=2,delth=20,moistfact=1.0):
     # set model parameters
     self.p0 = p0 # mean surface pressure
     self.ptop = ptop # model top pressure
     self.rgas = rgas # gas constant for dry air
     self.grav = grav # gravity
     self.omega = omega # rotation rate
     self.cp = cp # specific heat of dry air at constant pressure
     self.delth = delth # static stability
     # factor to reduce static stability in rising air
     # (crude moist physics assuming air is saturated)
     # moistfact = 1 is dry model
     self.moistfact = moistfact
     dp = 0.5*(ptop-p0)
     exnf1 = cp*((p0+0.5*dp)/p0)**(rgas/cp)
     exnf2 = cp*((p0+1.5*dp)/p0)**(rgas/cp)
     self.delta_exnf = exnf2-exnf1 # diff in exner function between 2 levs.
     # efolding time scale for hyperdiffusion at shortest wavenumber
     self.efold = efold
     self.ndiss = ndiss # order of hyperdiffusion (2 for laplacian)
     self.sp = sp # Spharmt instance
     self.ntrunc = ntrunc # triangular truncation wavenumber
     self.dt = dt # time step (secs)
     self.tdiab = tdiab # lower layer drag timescale
     self.tdrag = tdrag # interface relaxation timescale
     # create lat/lon arrays
     delta = 2.*np.pi/sp.nlon
     if sp.gridtype == 'regular':
        lats1d = 0.5*np.pi-delta*np.arange(sp.nlat)
        wts = np.cos(lats1d)
     else:
        lats1d,wts = gaussian_lats_wts(sp.nlat)
        lats1d = lats1d*np.pi/180. # convert to radians.
     lons1d = np.arange(-np.pi,np.pi,delta)
     lons,lats = np.meshgrid(lons1d,lats1d)
     self.lons = lons; self.lats = lats
     # weights for computing global means.
     self.globalmeanwts = np.ones((sp.nlat,sp.nlon))*wts[:,np.newaxis]
     self.globalmeanwts = self.globalmeanwts/self.globalmeanwts.sum()
     self.f = 2.*omega*np.sin(lats)[:,:,np.newaxis] # coriolis
     # create laplacian operator and its inverse.
     indxm, indxn = getspecindx(ntrunc)
     indxn = indxn.astype(np.float32)
     totwavenum = indxn*(indxn+1.0)
     self.lap = -totwavenum/sp.rsphere**2
     self.ilap = np.zeros(self.lap.shape, np.float32)
     self.ilap[1:] = 1./self.lap[1:]
     # hyperdiffusion operator
     self.hyperdiff = -(1./efold)*(totwavenum/totwavenum[-1])**(ndiss/2)
     # set equilibrium layer thicknes profile.
     self._interface_profile(umax,jetexp)
Example #5
0
def grid_degree(NY=256,NX=None):
    '''
    Return lon,lat for the spherical grid with (NX,NY)
    If NX is not given, default NX = NY*2
    Spherical harmonic examples:
    NY = 256
    NY = 128
    '''
    if NX is None: NX = NY*2
    if not _SPHARM_INSTALLED:
        raise _import_error
    latdeg,wgt = spharm.gaussian_lats_wts(NY)
    londeg = numpy.linspace(0.,360.,NX+1)[:-1]
    return londeg,latdeg[::-1]
Example #6
0
    def planetaryvorticity(self, omega=None):
        """Planetary vorticity (Coriolis parameter).

        **Optional argument:**

        *omega*
            Earth's angular velocity. The default value if not specified
            is 7.292x10**-5 s**-1.

        **Returns:**

        *pvorticity*
            The planetary vorticity.

        **See also:**

        `~VectorWind.absolutevorticity`.

        **Example:**

        Compute planetary vorticity using default values::

            pvrt = w.planetaryvorticity()

        Override the default value for Earth's angular velocity::

            pvrt = w.planetaryvorticity(omega=7.2921150)

        """
        if omega is None:
            # Define the Earth's angular velocity.
            omega = 7.292e-05
        nlat = self.s.nlat
        if self.gridtype == 'gaussian':
            lat, wts = gaussian_lats_wts(nlat)
        else:
            if nlat % 2:
                lat = np.linspace(90, -90, nlat)
            else:
                dlat = 180. / nlat
                lat = np.arange(90 - dlat / 2., -90, -dlat)
        try:
            cp = 2. * omega * np.sin(np.deg2rad(lat))
        except (TypeError, ValueError):
            raise ValueError('invalid value for omega: {!r}'.format(omega))
        indices = [slice(0, None)] + [np.newaxis] * (len(self.u.shape) - 1)
        f = cp[indices] * np.ones(self.u.shape, dtype=np.float32)
        return f
Example #7
0
    def planetaryvorticity(self, omega=None):
        """Planetary vorticity (Coriolis parameter).

        **Optional argument:**

        *omega*
            Earth's angular velocity. The default value if not specified
            is 7.292x10**-5 s**-1.

        **Returns:**

        *pvorticity*
            The planetary vorticity.

        **See also:**

        `~VectorWind.absolutevorticity`.

        **Example:**

        Compute planetary vorticity using default values::

            pvrt = w.planetaryvorticity()

        Override the default value for Earth's angular velocity::

            pvrt = w.planetaryvorticity(omega=7.2921150)

        """
        if omega is None:
            # Define the Earth's angular velocity.
            omega = 7.292e-05
        nlat = self.s.nlat
        if self.gridtype == 'gaussian':
            lat, wts = gaussian_lats_wts(nlat)
        else:
            if nlat % 2:
                lat = np.linspace(90, -90, nlat)
            else:
                dlat = 180. / nlat
                lat = np.arange(90 - dlat / 2., -90, -dlat)
        try:
            cp = 2. * omega * np.sin(np.deg2rad(lat))
        except (TypeError, ValueError):
            raise ValueError('invalid value for omega: {!r}'.format(omega))
        indices = [slice(0, None)] + [np.newaxis] * (len(self.u.shape) - 1)
        f = cp[indices] * np.ones(self.u.shape, dtype=np.float32)
        return f
Example #8
0
def reference_solutions(container_type, gridtype):
    """Generate reference solutions in the required container."""
    container_type = container_type.lower()
    if container_type not in ('standard', 'iris', 'cdms', 'xarray'):
        raise ValueError("unknown container type: "
                         "'{!s}'".format(container_type))
    reference = __read_reference_solutions(gridtype)
    if container_type == 'standard':
        # Reference solution already in numpy arrays.
        return reference
    # Generate coordinate dimensions for meta-data interfaces.
    if gridtype == 'gaussian':
        lats, _ = gaussian_lats_wts(72)
    else:
        lats = np.linspace(90, -90, 73)
    lons = np.arange(0, 360, 2.5)
    _get_wrapper(container_type)(reference, lats, lons)
    return reference
Example #9
0
 def __init__(self,sp,dt,ntrunc,theta1=300,theta2=330,grav=9.80616,omega=7.292e-5,cp=1004,\
         zmid=5.e3,ztop=15.e3,efold=3600.,ndiss=8,tdrag=1.e30,tdiab=1.e30,umax=30,jetexp=4):
     # setup model parameters
     self.theta1 = theta1 # lower layer pot. temp.
     self.theta2 = theta2 # upper layer pot. temp.
     self.delth = theta2-theta1 # difference in potential temp between layers
     self.grav = grav # gravity
     self.omega = omega # rotation rate
     self.cp = cp # Specific Heat of Dry Air at Constant Pressure,
     self.zmid = zmid # resting depth of lower layer (m)
     self.ztop = ztop # resting depth of both layers (m)
     # efolding time scale for hyperdiffusion at shortest wavenumber
     self.efold = efold
     self.ndiss = ndiss # order of hyperdiffusion (2 for laplacian)
     self.sp = sp # Spharmt instance
     self.ntrunc = ntrunc # triangular truncation wavenumber
     self.dt = dt # time step (secs)
     self.tdiab = tdiab # lower layer drag timescale
     self.tdrag = tdrag # interface relaxation timescale
     # create lat/lon arrays
     delta = 2.*np.pi/sp.nlon
     if sp.gridtype == 'regular':
        lats1d = 0.5*np.pi-delta*np.arange(sp.nlat)
     else:
        lats1d,wts = gaussian_lats_wts(sp.nlat)
        lats1d = lats1d*np.pi/180.
     lons1d = np.arange(-np.pi,np.pi,delta)
     lons,lats = np.meshgrid(lons1d,lats1d)
     self.lons = lons
     self.lats = lats
     self.f = 2.*omega*np.sin(lats)[:,:,np.newaxis] # coriolis
     # create laplacian operator and its inverse.
     indxm, indxn = getspecindx(ntrunc)
     indxn = indxn.astype(np.float32)[:,np.newaxis]
     totwavenum = indxn*(indxn+1.0)
     self.lap = -totwavenum/sp.rsphere**2
     self.ilap = np.zeros(self.lap.shape, np.float32)
     self.ilap[1:,:] = 1./self.lap[1:,:]
     # hyperdiffusion operator
     self.hyperdiff = -(1./efold)*(totwavenum/totwavenum[-1])**(ndiss/2)
     # initialize orography to zero.
     self.orog = np.zeros((sp.nlat,sp.nlon),np.float32)
     # set equilibrium layer thicknes profile.
     self._interface_profile(umax,jetexp)
Example #10
0
def gaussian_latlon_grid(nlat, as_2d=True):
    """
    Creates a gaussian lat/lon grid for spherical transforms.

    Args
    ----
    nlat : int
        Number of gaussian latitudes. (# lons = 2*nlat)
    as_2d : bool
        If True, returns 2d lat/lon grids. Otherwise, returns
        1d arrays.

    Returns
    -------
    lo, la : numpy array
        Arrays of lon/lat values in degrees.
    """
    lo = np.linspace(0., 360., 2 * nlat + 1)[:-1]
    la, _ = spharm.gaussian_lats_wts(nlat)
    if as_2d:
        lo, la = np.meshgrid(lo, la)
    return lo, la
Example #11
0
    def __init__(self, nlat, nlon, latlon_type='regular'):
        '''
        Note: The latlon grid should not include the pole.
        Support latlon_type: regular, gaussian
        '''
        self.nlat = nlat
        self.nlon = nlon
        self.latlon_type = latlon_type
        self.grid_type = '%s latlon'%latlon_type

        self.nsize = nlat*nlon
        self.tmp_lons = np.linspace(0, 2*pi, nlon+1)

        if latlon_type == 'regular':
            self.tmp_lats = np.linspace(-pi/2, pi/2, nlat+2)

        elif latlon_type == 'gaussian':
            import spharm   # NCAR SPHEREPACK
            degs, wts = spharm.gaussian_lats_wts(nlat)
            pts = np.deg2rad(degs[::-1])    # convert to south first
            self.tmp_lats = np.zeros(nlat+2)
            self.tmp_lats[1:-1] = pts
            self.tmp_lats[0] = -np.pi/2
            self.tmp_lats[-1] = np.pi/2

        else:
            raise ValueError, 'Wrong latlon_type=%s. Support latlon_type: regular, gaussian'%(latlon_type)


        self.latlons = np.zeros((self.nsize,2), 'f8')
        seq = 0
        for lat in self.tmp_lats[1:-1]:
            for lon in self.tmp_lons[:-1]:
                self.latlons[seq,:] = (lat,lon)
                seq += 1

        self.dlat = self.tmp_lats[2] - self.tmp_lats[1]
        self.dlon = self.tmp_lons[2] - self.tmp_lons[1]
Example #12
0
 def _gridtype(self, latitudes):
     """Determine the type of a latitude dimension."""
     # Define a tolerance value for differences, this value must be much
     # smaller than expected grid spacings.
     tolerance = 0.001
     # Get the number of latitude points in the dimension.
     nlat = len(latitudes)
     diffs = np.abs(np.diff(latitudes))
     equally_spaced = (np.abs(diffs - diffs[0]) < tolerance).all()
     if not equally_spaced:
         # The latitudes are not equally-spaced, which suggests they might
         # be gaussian. Construct sample gaussian latitudes and check if
         # the two match.
         gauss_reference, wts = gaussian_lats_wts(nlat)
         difference = np.abs(latitudes - gaussian_reference)
         if (d > tolerance).any():
             raise ValueError('latitudes are unequally-spaced '
                              'but are not gaussian')
         gridtype = 'gaussian'
     else:
         # The latitudes are equally-spaced. Construct reference global
         # equally spaced latitudes and check that the two match.
         if nlat % 2:
             # Odd number of latitudes includes the poles.
             equal_reference = np.linspace(90, -90, nlat)
         else:
             # Even number of latitudes doesn't include the poles.
             delta_latitude = 180. / nlat
             equal_reference = np.linspace(90 - 0.5 * delta_latitude,
                                           -90 + 0.5 * delta_latitude,
                                           nlat)
         difference = np.abs(latitudes - equal_reference)
         if (difference > tolerance).any():
             raise ValueError('equally-spaced latitudes are '
                              'invalid (non-global?)')
         gridtype = 'regular'
     return gridtype
Example #13
0
def make_padded_lats_lons(nlat, nlon, ll_type):
    if 'shift_lon' in ll_type:
        ll_type = ll_type.split('-')[0]
        shift_lon = True
    else:
        ll_type = ll_type
        shift_lon = False

    if shift_lon:
        dlon = 2*np.pi/nlon
        padded_lons = np.linspace(dlon/2, 2*np.pi+dlon/2, nlon+1)
    else:
        padded_lons = np.linspace(0, 2*pi, nlon+1)


    assert ll_type in ['regular', 'gaussian', 'include_pole'], "ll_type {} is not supported.".foramt(ll_type)

    if ll_type == 'include_pole':
        padded_lats = np.linspace(-pi/2, pi/2, nlat)

    elif ll_type == 'regular':
        dlat = np.pi/nlat 
        padded_lats = np.zeros(nlat+2)
        padded_lats[1:-1] = np.linspace((-pi+dlat)/2, (pi-dlat)/2, nlat)
        padded_lats[0] = -np.pi/2
        padded_lats[-1] = np.pi/2

    elif ll_type == 'gaussian':
        import spharm   # NCAR SPHEREPACK
        degs, wts = spharm.gaussian_lats_wts(nlat)
        pts = np.deg2rad(degs[::-1])    # convert to south first
        padded_lats = np.zeros(nlat+2)
        padded_lats[1:-1] = pts
        padded_lats[0] = -np.pi/2
        padded_lats[-1] = np.pi/2

    return ll_type, padded_lats, padded_lons
Example #14
0
 def _gridtype(self, latitudes):
     """Determine the type of a latitude dimension."""
     # Define a tolerance value for differences, this value must be much
     # smaller than expected grid spacings.
     tolerance = 0.001
     # Get the number of latitude points in the dimension.
     nlat = len(latitudes)
     diffs = np.abs(np.diff(latitudes))
     equally_spaced = (np.abs(diffs - diffs[0]) < tolerance).all()
     if not equally_spaced:
         # The latitudes are not equally-spaced, which suggests they might
         # be gaussian. Construct sample gaussian latitudes and check if
         # the two match.
         gauss_reference, wts = gaussian_lats_wts(nlat)
         difference = np.abs(latitudes - gaussian_reference)
         if (d > tolerance).any():
             raise ValueError('latitudes are unequally-spaced '
                              'but are not gaussian')
         gridtype = 'gaussian'
     else:
         # The latitudes are equally-spaced. Construct reference global
         # equally spaced latitudes and check that the two match.
         if nlat % 2:
             # Odd number of latitudes includes the poles.
             equal_reference = np.linspace(90, -90, nlat)
         else:
             # Even number of latitudes doesn't include the poles.
             delta_latitude = 180. / nlat
             equal_reference = np.linspace(90 - 0.5 * delta_latitude,
                                           -90 + 0.5 * delta_latitude, nlat)
         difference = np.abs(latitudes - equal_reference)
         if (difference > tolerance).any():
             raise ValueError('equally-spaced latitudes are '
                              'invalid (non-global?)')
         gridtype = 'regular'
     return gridtype
Example #15
0
    def planetaryvorticity(self, omega=None):
        """Planetary vorticity (Coriolis parameter).

        **Optional argument:**

        *omega*
            Earth's angular velocity. The default value if not specified
            is 7.292x10**-5 s**-1.

        **Example:**

        Compute planetary vorticity using default values:

            pvrt = w.planetaryvorticity()

        Override the default value for Earth's angular velocity:

            pvrt = w.planetaryvorticity(omega=7.2921150)

        """
        if omega is None:
            # Define the Earth's angular velocity.
            omega = 7.292e-05
        nlat = self.s.nlat
        if self.gridtype == 'gaussian':
            lat, wts = gaussian_lats_wts(nlat)
        else:
            if nlat % 2:
                lat = np.linspace(90, -90, nlat)
            else:
                dlat = 180. / nlat
                lat = np.arange(90 - dlat / 2., -90, -dlat)
        try:
            cp = 2. * omega * np.sin(np.deg2rad(lat))
        except TypeError, ValueError:
            raise ValueError('invalid value for omega: {!r}'.format(omega))
Example #16
0
from spharm import gaussian_lats_wts, Spharmt, legendre, specintrp, getgeodesicpts, regrid
import numpy, math, sys

# Rossby-Haurwitz wave field

def rhwave(wavenum,omega,re,lats,lons):
    return -re**2*omega*numpy.sin(lats)+re**2*omega*((numpy.cos(lats))**wavenum)*numpy.sin(lats)*numpy.cos(wavenum*lons)

# create Rossby-Haurwitz wave data on 144x73 regular and 192x94 gaussian grids.

nlats_reg = 73
nlons_reg = 144
nlats_gau = 94
nlons_gau = 192
gaulats, wts = gaussian_lats_wts(nlats_gau)
lats_reg = numpy.zeros((nlats_reg,nlons_reg),numpy.float64)
lons_reg = numpy.zeros((nlats_reg,nlons_reg),numpy.float64)
lons_gau = numpy.zeros((nlats_gau,nlons_gau),numpy.float64)

wavenum = 4.0
omega = 7.848e-6
re = 6.371e6
delat = 2.*math.pi/nlons_reg
lats = (0.5*math.pi-delat*numpy.indices(lats_reg.shape)[0,:,:])
lons = (delat*numpy.indices(lons_reg.shape)[1,:,:])
psi_reg_exact = rhwave(wavenum,omega,re,lats,lons)
delat = 2.*math.pi/nlons_gau
lats = (math.pi/180.)*numpy.transpose(gaulats*numpy.ones((nlons_gau,nlats_gau),'d'))
lons = (delat*numpy.indices(lons_gau.shape)[1,:,:])
psi_gau = rhwave(wavenum,omega,re,lats,lons)
Example #17
0
    def __init__(self, nlat, nlon, ll_type='regular', geo='sphere'):
        '''
        Note: The latlon grid should not include the pole.
        Support ll_type: regular, gaussian
        Support shape: sphere, plane
        '''
        self.nlat = nlat
        self.nlon = nlon
        self.ll_type = ll_type
        self.geo = geo  

        self.nsize = nlat*nlon


        #-----------------------------------------------------
        # Generate latlon grid
        #-----------------------------------------------------
        lons = np.linspace(0, 2*np.pi, nlon+1)[:-1]

        if ll_type == 'regular':
            lats = np.linspace(-np.pi/2, np.pi/2, nlat+2)[1:-1]

        elif ll_type == 'gaussian':
            import spharm   # NCAR SPHEREPACK
            degs, wts = spharm.gaussian_lats_wts(nlat)
            lats = np.deg2rad(degs[::-1])    # convert to south pole first

        else:
            raise ValueError, 'Wrong ll_type=%s. Support ll_type: regular, gaussian'%(ll_type)

        self.lons = lons
        self.lats = lats


        #-----------------------------------------------------
        # Set the connectivity
        #-----------------------------------------------------
        if geo == 'sphere':
            # vtk_cell_type is VTK_QUAD(=9)

            xyzs = np.zeros((nlat*nlon,3), 'f8')
            seq = 0
            for lat in lats:
                for lon in lons:
                    xyzs[seq,0] = np.cos(lat)*np.cos(lon)
                    xyzs[seq,1] = np.cos(lat)*np.sin(lon)
                    xyzs[seq,2] = np.sin(lat)
                    seq += 1

            link_size = (nlat-1)*nlon
            links = np.zeros((link_size,5), 'i4')

            link_seq = 0
            for j in xrange(nlat-1):
                for i in xrange(nlon):
                    ip = i+1 if i<nlon-1 else 0
                    seq1 = j*nlon + i
                    seq2 = j*nlon + ip
                    seq3 = (j+1)*nlon + ip
                    seq4 = (j+1)*nlon + i
                    links[link_seq,0] = visit_writer.quad
                    links[link_seq,1:] = [seq1, seq2, seq3, seq4]
                    link_seq += 1

            self.pts = xyzs.ravel().tolist()
            self.links = links.tolist()

        elif geo == 'plane':
            if ll_type == 'regular':
                self.dimensions = (nlon,nlat,1)

            elif ll_type == 'gaussian':
                self.x = self.lons.tolist()
                self.y = self.lats.tolist()
                self.z = [0]