Example #1
0
    def _re_bound(self,plot_bounding_box,mat,box,density):

        # CEBHACKALERT: for Julien...
        # If plot_bounding_box is that of a Sheet, it will already have been
        # setup so that the density in the x direction and the density in the
        # y direction are equal.
        # If plot_bounding_box comes from elsewhere (i.e. you create it from
        # arbitrary bounds), it might need to be adjusted to ensure the density
        # in both directions is the same (see Sheet.__init__()). I don't know where
        # you want to do that; presumably the code should be common to Sheet and
        # where it's used in the plotting?
        #
        # It's possible we can move some of the functionality
        # into SheetCoordinateSystem.
        if plot_bounding_box.containsbb_exclusive(box):
             ct = SheetCoordinateSystem(plot_bounding_box,density,density)
             new_mat = np.zeros(ct.shape,dtype=np.float)
             r1,r2,c1,c2 = Slice(box,ct)
             new_mat[r1:r2,c1:c2] = mat
        else:
             scs = SheetCoordinateSystem(box,density,density)
             s=Slice(plot_bounding_box,scs)
             s.crop_to_sheet(scs)
             new_mat = s.submatrix(mat)

        return new_mat
Example #2
0
    def __init__(self, **params):
        """
        Initialize this object as an EventProcessor, then also as
        a SheetCoordinateSystem with equal xdensity and ydensity.

        views is a Layout, which stores associated measurements,
        i.e. representations of the sheet for use by analysis or plotting
        code.
        """
        EventProcessor.__init__(self, **params)

        # Initialize this object as a SheetCoordinateSystem, with
        # the same density along y as along x.
        SheetCoordinateSystem.__init__(self, self.nominal_bounds,
                                       self.nominal_density)

        n_units = round((self.lbrt[2] - self.lbrt[0]) * self.xdensity, 0)
        if n_units < 1:            raise ValueError(
                "Sheet bounds and density must be specified such that the "+ \
 "sheet has at least one unit in each direction; " \
 +self.name+ " does not.")

        # setup the activity matrix
        self.activity = zeros(self.shape, activity_type)

        # For non-plastic inputs
        self.__saved_activity = []
        self._plasticity_setting_stack = []

        self.views = Layout()
        self.views.Maps = Layout()
        self.views.Curves = Layout()
Example #3
0
    def __init__(self,**params):
        """
        Initialize this object as an EventProcessor, then also as
        a SheetCoordinateSystem with equal xdensity and ydensity.

        views is a Layout, which stores associated measurements,
        i.e. representations of the sheet for use by analysis or plotting
        code.
        """
        EventProcessor.__init__(self,**params)

        # Initialize this object as a SheetCoordinateSystem, with
        # the same density along y as along x.
        SheetCoordinateSystem.__init__(self,self.nominal_bounds,self.nominal_density)

        n_units = round((self.lbrt[2]-self.lbrt[0])*self.xdensity,0)
        if n_units<1: raise ValueError(
           "Sheet bounds and density must be specified such that the "+ \
           "sheet has at least one unit in each direction; " \
           +self.name+ " does not.")

        # setup the activity matrix
        self.activity = zeros(self.shape,activity_type)

        # For non-plastic inputs
        self.__saved_activity = []
        self._plasticity_setting_stack = []

        self.views = Layout()
        self.views.Maps = Layout()
        self.views.Curves = Layout()
Example #4
0
File: image.py Project: fcr/imagen
    def _set_image(self, image):
        # Stores a SheetCoordinateSystem with an activity matrix
        # representing the image
        if not isinstance(image, np.ndarray):
            image = np.array(image, np.float)

        rows, cols = image.shape
        self.scs = SheetCoordinateSystem(
            xdensity=1.0,
            ydensity=1.0,
            bounds=BoundingBox(points=((-cols / 2.0, -rows / 2.0),
                                       (cols / 2.0, rows / 2.0))))
        self.scs.activity = image
    def __call__(self, **params_to_override):
        p = ParamOverrides(self, params_to_override)

        shape = SheetCoordinateSystem(p.bounds, p.xdensity, p.ydensity).shape

        result = p.scale * np.ones(shape, np.float) + p.offset
        self._apply_mask(p, result)

        for of in p.output_fns:
            of(result)

        return result
Example #6
0
    def _set_image(self, image):
        # Stores a SheetCoordinateSystem with an activity matrix
        # representing the image
        if not isinstance(image, np.ndarray):
            image = np.array(image, np.float)

        rows, cols = image.shape
        self.scs = SheetCoordinateSystem(
            xdensity=1.0,
            ydensity=1.0,
            bounds=BoundingBox(points=((-cols / 2.0, -rows / 2.0), (cols / 2.0, rows / 2.0))),
        )
        self.scs.activity = image
Example #7
0
    def __call__(self,**params_to_override):
        p = ParamOverrides(self,params_to_override)
        if self.time_dependent:
            if 'name' in p:
                self._initialize_random_state(seed=self.seed, shared=True, name=p.name)
            self._hash_and_seed()

        shape = SheetCoordinateSystem(p.bounds,p.xdensity,p.ydensity).shape

        result = self._distrib(shape,p)
        self._apply_mask(p,result)

        for of in p.output_fns:
            of(result)

        return result
 def set_matrix_dimensions(self, bounds, xdensity, ydensity):
     """
     Change the dimensions of the matrix into which the pattern
     will be drawn.  Users of this class should call this method
     rather than changing the bounds, xdensity, and ydensity
     parameters directly.  Subclasses can override this method to
     update any internal data structures that may depend on the
     matrix dimensions.
     """
     self.bounds = bounds
     self.xdensity = xdensity
     self.ydensity = ydensity
     scs = SheetCoordinateSystem(bounds, xdensity, ydensity)
     for of in self.output_fns:
         if isinstance(of, TransferFn):
             of.initialize(SCS=scs, shape=scs.shape)
Example #9
0
    def _setup_xy(self,bounds,xdensity,ydensity,x,y,orientation):
        """
        Produce pattern coordinate matrices from the bounds and
        density (or rows and cols), and transforms them according to
        x, y, and orientation.
        """
        self.param.debug("bounds=%s, xdensity=%s, ydensity=%s, x=%s, y=%s, orientation=%s",bounds,xdensity,ydensity,x,y,orientation)
        # Generate vectors representing coordinates at which the pattern
        # will be sampled.

        # CB: note to myself - use slice_._scs if supplied?
        x_points,y_points = SheetCoordinateSystem(bounds,xdensity,ydensity).sheetcoordinates_of_matrixidx()

        # Generate matrices of x and y sheet coordinates at which to
        # sample pattern, at the correct orientation
        self.pattern_x, self.pattern_y = self._create_and_rotate_coordinate_arrays(x_points-x,y_points-y,orientation)
Example #10
0
    def __call__(self,**params_to_override):
        p = ParamOverrides(self,params_to_override)

        xsize,ysize = SheetCoordinateSystem(p.bounds,p.xdensity,p.ydensity).shape
        xsize,ysize = int(round(xsize)),int(round(ysize))

        xdisparity  = int(round(xsize*p.xdisparity))
        ydisparity  = int(round(xsize*p.ydisparity))
        dotsize     = int(round(xsize*p.dotsize))

        bigxsize = 2*xsize
        bigysize = 2*ysize
        ndots=int(round(p.dotdensity * (bigxsize+2*dotsize) * (bigysize+2*dotsize) /
                        min(dotsize,xsize) / min(dotsize,ysize)))
        halfdot = np.floor(dotsize/2)

        # Choose random colors and locations of square dots
        random_seed = p.random_seed

        np.random.seed(random_seed*12+random_seed*99)
        col=np.where(np.random.random((ndots))>=0.5, 1.0, -1.0)

        np.random.seed(random_seed*122+random_seed*799)
        xpos=np.floor(np.random.random((ndots))*(bigxsize+2*dotsize)) - halfdot

        np.random.seed(random_seed*1243+random_seed*9349)
        ypos=np.floor(np.random.random((ndots))*(bigysize+2*dotsize)) - halfdot

        # Construct arrays of points specifying the boundaries of each
        # dot, cropping them by the big image size (0,0) to (bigxsize,bigysize)
        x1=xpos.astype('l') ; x1=np.choose(np.less(x1,0),(x1,0))
        y1=ypos.astype('l') ; y1=np.choose(np.less(y1,0),(y1,0))
        x2=(xpos+(dotsize-1)).astype('l') ; x2=np.choose(np.greater(x2,bigxsize),(x2,bigxsize))
        y2=(ypos+(dotsize-1)).astype('l') ; y2=np.choose(np.greater(y2,bigysize),(y2,bigysize))

        # Draw each dot in the big image, on a blank background
        bigimage = np.zeros((bigysize,bigxsize))
        for i in range(ndots):
            bigimage[y1[i]:y2[i]+1,x1[i]:x2[i]+1] = col[i]

        result = p.offset + p.scale*bigimage[ (ysize/2)+ydisparity:(3*ysize/2)+ydisparity ,
                                              (xsize/2)+xdisparity:(3*xsize/2)+xdisparity ]

        for of in p.output_fns:
            of(result)

        return result
    def situated(self):
        if self.bounds.lbrt() == self.situated_bounds.lbrt():
            self.warning("CFView is already situated.")
            return self
        l, b, r, t = self.bounds.lbrt()
        xd = int(np.round(self.data.shape[1] / (r-l)))
        yd = int(np.round(self.data.shape[0] / (t-b)))

        scs = SheetCoordinateSystem(self.situated_bounds, xd, yd)

        data = np.zeros(scs.shape, dtype=np.float64)
        r1, r2, c1, c2 = self.input_sheet_slice
        data[r1:r2, c1:c2] = self.data

        return CFView(data, self.situated_bounds, roi_bounds=self.bounds,
                      situated_bounds=self.situated_bounds,
                      label=self.label, value=self.value)
Example #12
0
    def _distrib(self, shape, p):
        max_density = min(p.xdensity,p.ydensity)
        if (p.grid_density > max_density and not hasattr(self,"warned_about_density")):
            self.warning("Requested grid_density %s larger than xdensity %s or ydensity %s; capped at %s" %
                         (p.grid_density,p.xdensity,p.ydensity,max_density))
            p.grid_density = max_density
            self.warned_about_density=True

        Nx = shape[1]
        Ny = shape[0] # Size of the pixel matrix

        assert (Nx>0 and Ny>0), 'Pixel matrix cannot be zero'

        SC = SheetCoordinateSystem(p.bounds, p.xdensity, p.ydensity)
        unitary_distance_x = SC._SheetCoordinateSystem__xstep
        unitary_distance_y = SC._SheetCoordinateSystem__ystep

        sheet_x_size = unitary_distance_x * Nx
        sheet_y_size = unitary_distance_y * Ny

        # Sizes of the structure matrix
        nx = int(round(sheet_x_size * p.grid_density))  # Number of points in the x's
        ny = int(round(sheet_y_size * p.grid_density))  # Number of points in the y's

        assert ( nx > 0 ), 'Grid density or bound box in the x dimension too small'
        assert ( ny > 0 ), 'Grid density or bound box in the y dimension too smal'

        ps_x = int(round(Nx / nx)) #Closest integer
        ps_y = int(round(Ny / ny))

        # This is the actual matrix of the pixels
        A = np.ones(shape) * 0.5

        if p.grid == False:  #The centers of the spots are randomly distributed in space

            x = p.random_generator.randint(0, Nx - ps_x + 1)
            y = p.random_generator.randint(0, Ny - ps_y + 1)
            z = p.random_generator.randint(0,2)

            # Noise matrix is mapped to the pixel matrix
            A[x: (x + ps_y), y: (y + ps_x)] =  z

            return A * p.scale + p.offset

        else: #In case you want the grid

            if  ( Nx % nx == 0) and (Ny % ny == 0): #When the noise grid falls neatly into the the pixel grid
                x = p.random_generator.randint(0, nx)
                y = p.random_generator.randint(0, ny)
                z = p.random_generator.randint(0,2)

               # Noise matrix is mapped to the pixel matrix (faster method)
                A[x*ps_y: (x*ps_y + ps_y), y*ps_x: (y*ps_x + ps_x)] = z

                return A * p.scale + p.offset

            else: # If noise grid does not fit neatly in the pixel grid (slow method)

                x_points,y_points = SC.sheetcoordinates_of_matrixidx()

                # Obtain length of the side and length of the
                # division line between the grid

                size_of_block_x = Nx * 1.0 / nx
                size_of_block_y = Ny * 1.0 / ny

                # Construct the noise matrix
                Z = np.ones((nx,ny)) * 0.5
                x = p.random_generator.randint(0, nx)
                y = p.random_generator.randint(0, ny)
                z = p.random_generator.randint(0,2)
                Z[x,y] = z

                            # Noise matrix is mapped to the pixel matrix
                for i in range(Nx):
                    for j in range(Ny):
                        # Map along the x coordinates
                        x_entry = int( i / size_of_block_x)
                        y_entry = int( j / size_of_block_y)
                        A[j][i] = Z[x_entry][y_entry]

                return A * p.scale + p.offset
Example #13
0
    def _distrib(self, shape, p):
        max_density = min(p.xdensity,p.ydensity)
        if (p.grid_density > max_density and not hasattr(self,"warned_about_density")):
            self.warning("Requested grid_density %s larger than xdensity %s or ydensity %s; capped at %s" %
                         (p.grid_density,p.xdensity,p.ydensity,max_density))
            p.grid_density = max_density
            self.warned_about_density=True

        Nx = shape[1]
        Ny = shape[0] # Size of the pixel matrix

        assert (Nx>0 and Ny>0), 'Pixel matrix cannot be zero'

        SC = SheetCoordinateSystem(p.bounds, p.xdensity, p.ydensity)
        unitary_distance_x = SC._SheetCoordinateSystem__xstep
        unitary_distance_y = SC._SheetCoordinateSystem__ystep


        sheet_x_size = unitary_distance_x * Nx
        sheet_y_size = unitary_distance_y * Ny

        # Sizes of the structure matrix
        nx = int(round(sheet_x_size * p.grid_density))  # Number of points in the x's
        ny = int(round(sheet_y_size * p.grid_density))  # Number of points in the y's

        assert ( nx > 0 ), 'Grid density or bound box in the x dimension too small'
        assert ( ny > 0 ), 'Grid density or bound box in the y dimension too small'

        # If the noise grid is proportional to the pixel grid and fits
        # neatly into it then this method is ~100 times faster
        if ( Nx % nx == 0) and (Ny % ny == 0):

            if (Nx == nx) and (Ny == ny):  #This is faster to call the whole procedure
                result = 0.5 * (p.random_generator.randint(-1, 2, shape) + 1)
                return  result * p.scale + p.offset

            else:
                # This is the actual matrix of the pixels
                A = np.zeros(shape)
                # Noise matrix that contains the structure of 0, 0.5, and 1's
                Z = 0.5 * (p.random_generator.randint(-1, 2, (nx, ny)) + 1 )

                ps_x = int(round(Nx * 1.0/ nx))  #Closest integer
                ps_y = int(round(Ny * 1.0/ ny))

                # Noise matrix is mapped to the pixel matrix
                for i in range(nx):
                    for j in range(ny):
                        A[i * ps_y: (i + 1) * ps_y, j * ps_x: (j + 1) * ps_x] = Z[i,j]

                return A * p.scale + p.offset

        # General method in case the noise grid does not
        # fall neatly in the pixel grid
        else:

            # Obtain length of the side and length of the
            # division line between the grid
            x_points,y_points = SC.sheetcoordinates_of_matrixidx()

            # This is the actual matrix of the pixels
            A = np.zeros(shape)
            # Noise matrix that contains the structure of 0, 0.5, and 1's
            Z = 0.5 * (p.random_generator.randint(-1, 2, (nx, ny)) + 1 )

            size_of_block_x = Nx * 1.0 / nx
            size_of_block_y = Ny * 1.0 / ny

            # Noise matrix is mapped to the pixel matrix
            for i in range(Nx):
                for j in range(Ny):
                    # Map along the x coordinates
                    x_entry = int( i / size_of_block_x)
                    y_entry = int( j / size_of_block_y)
                    A[j][i] = Z[x_entry][y_entry]

            return A * p.scale + p.offset
Example #14
0
class PatternSampler(ImageSampler):
    """
    When called, resamples - according to the size_normalization
    parameter - an image at the supplied (x,y) sheet coordinates.

    (x,y) coordinates outside the image are returned as the background
    value.
    """

    whole_pattern_output_fns = param.HookList(
        class_=TransferFn,
        default=[],
        doc="""
        Functions to apply to the whole image before any sampling is done.""",
    )

    background_value_fn = param.Callable(
        default=None,
        doc="""
        Function to compute an appropriate background value. Must accept
        an array and return a scalar.""",
    )

    size_normalization = param.ObjectSelector(
        default="original",
        objects=["original", "stretch_to_fit", "fit_shortest", "fit_longest"],
        doc="""
        Determines how the pattern is scaled initially, relative to
        the default retinal dimension of 1.0 in sheet coordinates:

        'stretch_to_fit': scale both dimensions of the pattern so they
        would fill a Sheet with bounds=BoundingBox(radius=0.5)
        (disregards the original's aspect ratio).

        'fit_shortest': scale the pattern so that its shortest
        dimension is made to fill the corresponding dimension on a
        Sheet with bounds=BoundingBox(radius=0.5) (maintains the
        original's aspect ratio, filling the entire bounding box).

        'fit_longest': scale the pattern so that its longest dimension
        is made to fill the corresponding dimension on a Sheet with
        bounds=BoundingBox(radius=0.5) (maintains the original's
        aspect ratio, fitting the image into the bounding box but not
        necessarily filling it).

        'original': no scaling is applied; each pixel of the pattern
        corresponds to one matrix unit of the Sheet on which the
        pattern being displayed.""",
    )

    def _get_image(self):
        return self.scs.activity

    def _set_image(self, image):
        # Stores a SheetCoordinateSystem with an activity matrix
        # representing the image
        if not isinstance(image, np.ndarray):
            image = np.array(image, np.float)

        rows, cols = image.shape
        self.scs = SheetCoordinateSystem(
            xdensity=1.0,
            ydensity=1.0,
            bounds=BoundingBox(points=((-cols / 2.0, -rows / 2.0), (cols / 2.0, rows / 2.0))),
        )
        self.scs.activity = image

    def _del_image(self):
        self.scs = None

    def __call__(self, image, x, y, sheet_xdensity, sheet_ydensity, width=1.0, height=1.0):
        """
        Return pixels from the supplied image at the given Sheet (x,y)
        coordinates.

        The image is assumed to be a NumPy array or other object that
        exports the NumPy buffer interface (i.e. can be converted to a
        NumPy array by passing it to numpy.array(), e.g. Image.Image).
        The whole_pattern_output_fns are applied to the image before
        any sampling is done.

        To calculate the sample, the image is scaled according to the
        size_normalization parameter, and any supplied width and
        height. sheet_xdensity and sheet_ydensity are the xdensity and
        ydensity of the sheet on which the pattern is to be drawn.
        """
        # CEB: could allow image=None in args and have 'if image is
        # not None: self.image=image' here to avoid re-initializing the
        # image.
        self.image = image

        for wpof in self.whole_pattern_output_fns:
            wpof(self.image)
        if not self.background_value_fn:
            self.background_value = 0.0
        else:
            self.background_value = self.background_value_fn(self.image)

        pattern_rows, pattern_cols = self.image.shape

        if width == 0 or height == 0 or pattern_cols == 0 or pattern_rows == 0:
            return np.ones(x.shape) * self.background_value

        # scale the supplied coordinates to match the pattern being at density=1
        x = x * sheet_xdensity  # deliberately don't operate in place (so as not to change supplied x & y)
        y = y * sheet_ydensity

        # scale according to initial pattern size_normalization selected (size_normalization)
        self.__apply_size_normalization(x, y, sheet_xdensity, sheet_ydensity, self.size_normalization)

        # scale according to user-specified width and height
        x /= width
        y /= height

        # now sample pattern at the (r,c) corresponding to the supplied (x,y)
        r, c = self.scs.sheet2matrixidx(x, y)
        # (where(cond,x,y) evaluates x whether cond is True or False)
        r.clip(0, pattern_rows - 1, out=r)
        c.clip(0, pattern_cols - 1, out=c)
        left, bottom, right, top = self.scs.bounds.lbrt()
        return np.where((x >= left) & (x < right) & (y > bottom) & (y <= top), self.image[r, c], self.background_value)

    def __apply_size_normalization(self, x, y, sheet_xdensity, sheet_ydensity, size_normalization):
        pattern_rows, pattern_cols = self.image.shape

        # Instead of an if-test, could have a class of this type of
        # function (c.f. OutputFunctions, etc)...
        if size_normalization == "original":
            return

        elif size_normalization == "stretch_to_fit":
            x_sf, y_sf = pattern_cols / sheet_xdensity, pattern_rows / sheet_ydensity
            x *= x_sf
            y *= y_sf

        elif size_normalization == "fit_shortest":
            if pattern_rows < pattern_cols:
                sf = pattern_rows / sheet_ydensity
            else:
                sf = pattern_cols / sheet_xdensity
            x *= sf
            y *= sf

        elif size_normalization == "fit_longest":
            if pattern_rows < pattern_cols:
                sf = pattern_cols / sheet_xdensity
            else:
                sf = pattern_rows / sheet_ydensity
            x *= sf
            y *= sf
Example #15
0
File: image.py Project: fcr/imagen
class PatternSampler(ImageSampler):
    """
    When called, resamples - according to the size_normalization
    parameter - an image at the supplied (x,y) sheet coordinates.

    (x,y) coordinates outside the image are returned as the background
    value.
    """
    whole_pattern_output_fns = param.HookList(class_=TransferFn,
                                              default=[],
                                              doc="""
        Functions to apply to the whole image before any sampling is done.""")

    background_value_fn = param.Callable(default=None,
                                         doc="""
        Function to compute an appropriate background value. Must accept
        an array and return a scalar.""")

    size_normalization = param.ObjectSelector(
        default='original',
        objects=['original', 'stretch_to_fit', 'fit_shortest', 'fit_longest'],
        doc="""
        Determines how the pattern is scaled initially, relative to
        the default retinal dimension of 1.0 in sheet coordinates:

        'stretch_to_fit': scale both dimensions of the pattern so they
        would fill a Sheet with bounds=BoundingBox(radius=0.5)
        (disregards the original's aspect ratio).

        'fit_shortest': scale the pattern so that its shortest
        dimension is made to fill the corresponding dimension on a
        Sheet with bounds=BoundingBox(radius=0.5) (maintains the
        original's aspect ratio, filling the entire bounding box).

        'fit_longest': scale the pattern so that its longest dimension
        is made to fill the corresponding dimension on a Sheet with
        bounds=BoundingBox(radius=0.5) (maintains the original's
        aspect ratio, fitting the image into the bounding box but not
        necessarily filling it).

        'original': no scaling is applied; each pixel of the pattern
        corresponds to one matrix unit of the Sheet on which the
        pattern being displayed.""")

    def _get_image(self):
        return self.scs.activity

    def _set_image(self, image):
        # Stores a SheetCoordinateSystem with an activity matrix
        # representing the image
        if not isinstance(image, np.ndarray):
            image = np.array(image, np.float)

        rows, cols = image.shape
        self.scs = SheetCoordinateSystem(
            xdensity=1.0,
            ydensity=1.0,
            bounds=BoundingBox(points=((-cols / 2.0, -rows / 2.0),
                                       (cols / 2.0, rows / 2.0))))
        self.scs.activity = image

    def _del_image(self):
        self.scs = None

    def __call__(self,
                 image,
                 x,
                 y,
                 sheet_xdensity,
                 sheet_ydensity,
                 width=1.0,
                 height=1.0):
        """
        Return pixels from the supplied image at the given Sheet (x,y)
        coordinates.

        The image is assumed to be a NumPy array or other object that
        exports the NumPy buffer interface (i.e. can be converted to a
        NumPy array by passing it to numpy.array(), e.g. Image.Image).
        The whole_pattern_output_fns are applied to the image before
        any sampling is done.

        To calculate the sample, the image is scaled according to the
        size_normalization parameter, and any supplied width and
        height. sheet_xdensity and sheet_ydensity are the xdensity and
        ydensity of the sheet on which the pattern is to be drawn.
        """
        # CEB: could allow image=None in args and have 'if image is
        # not None: self.image=image' here to avoid re-initializing the
        # image.
        self.image = image

        for wpof in self.whole_pattern_output_fns:
            wpof(self.image)
        if not self.background_value_fn:
            self.background_value = 0.0
        else:
            self.background_value = self.background_value_fn(self.image)

        pattern_rows, pattern_cols = self.image.shape

        if width == 0 or height == 0 or pattern_cols == 0 or pattern_rows == 0:
            return np.ones(x.shape) * self.background_value

        # scale the supplied coordinates to match the pattern being at density=1
        x = x * sheet_xdensity  # deliberately don't operate in place (so as not to change supplied x & y)
        y = y * sheet_ydensity

        # scale according to initial pattern size_normalization selected (size_normalization)
        self.__apply_size_normalization(x, y, sheet_xdensity, sheet_ydensity,
                                        self.size_normalization)

        # scale according to user-specified width and height
        x /= width
        y /= height

        # now sample pattern at the (r,c) corresponding to the supplied (x,y)
        r, c = self.scs.sheet2matrixidx(x, y)
        # (where(cond,x,y) evaluates x whether cond is True or False)
        r.clip(0, pattern_rows - 1, out=r)
        c.clip(0, pattern_cols - 1, out=c)
        left, bottom, right, top = self.scs.bounds.lbrt()
        return np.where((x >= left) & (x < right) & (y > bottom) & (y <= top),
                        self.image[r, c], self.background_value)

    def __apply_size_normalization(self, x, y, sheet_xdensity, sheet_ydensity,
                                   size_normalization):
        pattern_rows, pattern_cols = self.image.shape

        # Instead of an if-test, could have a class of this type of
        # function (c.f. OutputFunctions, etc)...
        if size_normalization == 'original':
            return

        elif size_normalization == 'stretch_to_fit':
            x_sf, y_sf = pattern_cols / sheet_xdensity, pattern_rows / sheet_ydensity
            x *= x_sf
            y *= y_sf

        elif size_normalization == 'fit_shortest':
            if pattern_rows < pattern_cols:
                sf = pattern_rows / sheet_ydensity
            else:
                sf = pattern_cols / sheet_xdensity
            x *= sf
            y *= sf

        elif size_normalization == 'fit_longest':
            if pattern_rows < pattern_cols:
                sf = pattern_cols / sheet_xdensity
            else:
                sf = pattern_rows / sheet_ydensity
            x *= sf
            y *= sf
Example #16
0
 def __init__(self, **params):
     EventProcessor.__init__(**params)
     SheetCoordinateSystem.__init__()