Example #1
0
    def __init__(self, varname, clim, segmentlist, name=None, unit=None):
        """Transect constructor.

        Args:
            - *varname*: the name of the variable to extract.
            - *clim*: a list or tuple with the two limit values (minimum and
              maximum).
            - *segmentlist*: a list Segment objects. Can be an empty list.
            - *name* (optional): a string defining the transect's name. If set
              to None it will be set to varname (default: None).
            - *unit* (optional): a string defining the transect's measurement
              unit (default: None).
        """
        if varname is None:
            raise ValueError("varname cannot be None")
        self.__varname = str(varname)
        if name is None:
            self.__name = self.__varname
        else:
            self.__name = str(name)
        if unit is None:
            self.__unit = None
        else:
            self.__unit = str(unit)
        if not isinstance(clim, (list, tuple)) or (len(clim) != 2) or not (is_number(clim[0]) and is_number(clim[1])):
            raise ValueError("clim must be a list of two numbers")
        self.__clim = clim
        if not isinstance(segmentlist, (list, tuple)) or ((len(segmentlist) > 0) and not isinstance(segmentlist[0], (Segment,))):
            raise ValueError("segmentlist must be a list of Segments")
        self.__segmentlist = segmentlist
        #Variable data cache
        self.__datacache = { 'filename':None, 'data':None }
        self.__mask = None
Example #2
0
 def __get_segment_data(self, segment_index):
     #Input validation
     if not is_number(segment_index):
         raise ValueError("'%s' is not a number." % (segment_index,))
     seg = self.__segmentlist[segment_index]
     #Retrieve indices
     x_min, y_min = self.__mask.convert_lon_lat_to_indices(seg.lon_min, seg.lat_min)
     x_max, y_max = self.__mask.convert_lon_lat_to_indices(seg.lon_max, seg.lat_max)
     #Check for single point case
     if (x_min == x_max) and (y_min == y_max):
         raise ValueError("Invalid segment: %s" % (seg,))
     #Get the output data
     if x_min == x_max:
         data = np.array(self.__datacache['data'][:, y_min:y_max, x_min], dtype=float)
         h_vals = self.__mask.ylevels[y_min:y_max,x_min]
     elif y_min == y_max:
         data = np.array(self.__datacache['data'][:, y_min, x_min:x_max], dtype=float)
         h_vals = self.__mask.xlevels[y_min,x_min:x_max]
     else:
         #Divide the segment in points
         xs = np.linspace(x_min,x_max,num=seg.points)
         ys = np.linspace(y_min,y_max,num=seg.points)
         xs = np.round(xs)
         ys = np.round(ys)
         #Fill data with the nearest neighbour
         data = list()
         for i in range(seg.points):
             data.append(self.__datacache['data'][:,ys[i],xs[i]])
         #Convert data to a Numpy array
         data = np.array(data)
         data = data.transpose()
         #TODO: find a meaningful array for h_vals.
         h_vals = np.array(range(seg.points))
     z_vals = self.__mask.zlevels
     return data, h_vals, z_vals
Example #3
0
 def __init__(self, varname, longvarname, units, layerlist, clim):
     #Input validation
     self.__varname = str(varname)
     self.__longvarname = str(longvarname)
     self.__units = units
     if not isinstance(layerlist, (list, tuple)) or ((len(layerlist) > 0) and not isinstance(layerlist[0], (Layer,))):
         raise ValueError("layerlist must be a list of Layers")
     self.__layerlist = layerlist
     if not (clim is None):
         if not isinstance(clim, (list, tuple)) or (len(clim) != 2) or not (is_number(clim[0]) and is_number(clim[1])):
             raise ValueError("clim must be a list of two numbers")
     self.__clim = clim
     self.__climslist = list()
Example #4
0
    def __init__(self, lon_lat_min, lon_lat_max, name=None, points=50):
        """Segment constructor.

        Args:
            - *lon_lat_min*: tuple or list with Segment's starting point in
              longitude and latitude.
            - *lon_lat_max*: tuple or list with Segment's ending point in
              longitude and latitude.
            - *name* (optional): a string defining the name of the segment (default: None).
            - *points* (optional): the number of points of the segment
              (default: 50). It is a required argument for diagonals and it is
              ignored for fixed latitude and fixed longitude segments.
        """
        if name is None:
            self.__name = None
        else:
            self.__name = str(name)
        if not (isinstance(lon_lat_min, (list, tuple)) and isinstance(lon_lat_max, (list, tuple))):
            raise ValueError("lon_lat_min and lon_lat_max must be tuples or lists")
        if not ((len(lon_lat_min) == 2) and (len(lon_lat_max) == 2)):
            raise ValueError("lon_lat_min and lon_lat_max must hold two values")
        for t in [lon_lat_min, lon_lat_max]:
            for el in t:
                if not is_number(el):
                    raise ValueError("%s is not a number" % (el,))
        self.__lon_min = lon_lat_min[0]
        self.__lat_min = lon_lat_min[1]
        self.__lon_max = lon_lat_max[0]
        self.__lat_max = lon_lat_max[1]
        self.points = None
        #If the segment is diagonal check that points is a number greater than 0
        if (self.__lon_min != self.__lon_max) and (self.__lat_min != self.__lat_max):
            if not is_number(points) or (points <= 0):
                raise ValueError("points must be defined as a number greater than zero")
            else:
                self.points = points
Example #5
0
    def from_square_cutting(mask, degrees, start_lon, start_lat):
        """
        Creates a list of SubMask objects from cutting a Mask object into
        square sections.  The cutting starts from a point and proceeds to cut
        along longitude then along latitude.

        ++++++++    ++++++++    s->+++++
        ++++++++ -> s->+++++ -> ssssssss
        s->+++++    ssssssss    ssssssss

        Args:
            - *mask*: a Mask object.
            - *degrees*: number of degrees for a sigle section side.
            - *start_lon*: starting longitude point.
            - *start_lat*: starting latitude point.

        Returns: a list of SubMasks mapping a single section each.
        """
        # Input validation
        if not isinstance(mask, Mask):
            raise ValueError("mask must be an instance of Mask")
        if not is_number(degrees):
            raise ValueError("degrees must be a number")
        if not is_number(start_lon):
            raise ValueError("start_lon must be a number")
        if not is_number(start_lat):
            raise ValueError("start_lat must be a number")
        # Get mask dimensions
        min_lon = mask.xlevels.min()
        max_lon = mask.xlevels.max()
        min_lat = mask.ylevels.min()
        max_lat = mask.ylevels.max()
        # Compute maximum value for degrees
        max_deg = min([(max_lon - min_lon), (max_lat - min_lat)])
        if degrees <= 0:
            raise ValueError("degrees must be greater than 0.")
        if degrees > max_deg:
            raise ValueError("The degrees value of %g is too big for this mask (maximum: %g)" % (degrees, max_deg))
        # Check if starting point is inside the original mask
        if (start_lon > max_lon) or (start_lon < min_lon):
            raise ValueError("Invalid longitude %g (min: %g, max: %g)" % (start_lon, min_lon, max_lon))
        if (start_lat > max_lat) or (start_lat < min_lat):
            raise ValueError("Invalid latitude %g (min: %g, max: %g)" % (start_lat, min_lat, max_lat))
        output = list()
        # Bottom Left point
        BL_point = [start_lon, start_lat]
        # Top Right point
        TR_point = [start_lon + degrees, start_lat + degrees]
        # Section indices
        lon_in = 0
        lat_in = 0
        # Latitude cycle
        while (TR_point[1] <= max_lat):
            # Longitude cycle
            while (TR_point[0] <= max_lon):
                # Create the Rectagle
                rect = Rectangle(BL_point[0], TR_point[0], BL_point[1], TR_point[1])
                # Create the basin
                basin = SimpleBasin("section_%d_%d" % (lat_in, lon_in), rect)
                # Create the SubMask and append it to output
                output.append(SubMask(basin, maskobject=mask))
                # Increment longitude index
                lon_in += 1
                # Increment longitude
                BL_point[0] += degrees
                TR_point[0] += degrees
            # Increment latitude index
            lat_in += 1
            # Increment latitude
            BL_point[1] += degrees
            TR_point[1] += degrees
            # Reset Longitude index
            lon_in = 0
            # Reset Longitude
            BL_point[0] = start_lon
            TR_point[0] = start_lon + degrees
        return output