Example #1
0
    def randomize(self):
        """Randomize the layers components."""
        super(MarkovChainLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(
            colorgamuttype_constraint, self.path)
        self.colorgamut.randomize()

        number_of_states_constraint = cpool.get(self,
                                                NUMBER_OF_STATES_CONSTRAINT)
        self._init_states(
            model_random.randint_constrained(number_of_states_constraint))

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                     self.path)
        self.sampler.randomize()

        stamp_factory = ka_factory.get_factory('stamp')
        stamptype_constraint = cpool.get(self, STAMPTYPE_CONSTRAINT)
        self.stamp = stamp_factory.create_random(stamptype_constraint,
                                                 self.path, self.states)
        self.stamp.randomize()
Example #2
0
    def mutate(self):
        """Make random changes to the tree node.
        """
        cpool = model_constraintpool.ConstraintPool.get_pool()

        # delegate mutating to the nodes child components
        if self.left_treenode is not None:
            self.left_treenode.mutate()
        if self.right_treenode is not None:
            self.right_treenode.mutate()
        # mutating my details
        self.left_background.mutate()
        self.right_background.mutate()
        if model_random.is_mutating():
            self.layer.mutate()
        if model_random.is_mutating():
            if model_random.is_mutating():
                merger_factory = ka_factory.get_factory('merger')
                mergertype_constraint = cpool.get(self, MERGERTYPE_CONSTRAINT)
                self.merger = merger_factory.create_random(
                    mergertype_constraint, self.path)
            self.merger.randomize()
        if model_random.is_mutating():
            if model_random.is_mutating():
                modifier_factory = ka_factory.get_factory('modifier')
                modifiertype_constraint = cpool.get(self,
                                                    MODIFIERTYPE_CONSTRAINT)
                self.modifier = modifier_factory.create_random(
                    modifiertype_constraint, self.path)
            self.modifier.randomize()
Example #3
0
 def __init__(self, trunk):
     super(TreeNode, self).__init__(trunk)
     self.left_treenode = None
     self.right_treenode = None
     self.left_background = exon_color.Color(self.path, 0, 0, 0, 1)
     self.right_background = exon_color.Color(self.path, 0, 0, 0, 1)
     layer_factory = ka_factory.get_factory('layer')
     self.layer = layer_factory.create(layer_factory.keys()[0], self.path)
     merger_factory = ka_factory.get_factory('merger')
     self.merger = merger_factory.create(merger_factory.keys()[0],
                                         self.path)
     modifier_factory = ka_factory.get_factory('modifier')
     self.modifier = modifier_factory.create(modifier_factory.keys()[0],
                                             self.path)
Example #4
0
 def __init__(self, trunk):
     """FilledSpline diagram layer constructor"""
     super(FilledSpline, self).__init__(trunk)
     cpool = model_constraintpool.ConstraintPool.get_pool()
     colorgamut_factory = ka_factory.get_factory('colorgamut')
     colorgamut_key = colorgamut_factory.keys()[0]
     self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)
     self.linecolor = self.colorgamut.get_randomized_color(self.path)
     self.fillcolor = self.colorgamut.get_randomized_color(self.path)
     self.line_width = cpool.get(self, 'line_width')[0]
     self.roundness = cpool.get(self, 'roundness')[0]
     self.center = exon_position.Position(self.path, 0.0, 0.0)
     sampler_factory = ka_factory.get_factory('sampler')
     sampler_key = sampler_factory.keys()[0]
     self.sampler = sampler_factory.create(sampler_key, self.path)
Example #5
0
 def copy(self):
     """The FilledSpline diagram layers copy constructor.
     # check for distinct references, needs to copy content, not references
     post: __return__ is not self
     """
     new_one = FilledSpline(self.get_trunk())
     self.copy_base(new_one)
     new_one.linecolor = self.linecolor.copy()
     new_one.fillcolor = self.fillcolor.copy()
     new_one.line_width = self.line_width
     new_one.roundness = self.roundness
     new_one.center = self.center.copy()
     new_one.sampler = self.sampler.copy()
     # upgrade from a release older than 'v4'
     if self.__dict__.has_key('colorgamut'):
         new_one.colorgamut = self.colorgamut.copy()
     else:
         cpool = model_constraintpool.ConstraintPool.get_pool()
         colorgamut_factory = ka_factory.get_factory('colorgamut')
         colorgamuttype_constraint = cpool.get(self,
                                               COLORGAMUTTYPE_CONSTRAINT)
         new_one.colorgamut = colorgamut_factory.create_random(
             colorgamuttype_constraint, new_one.path)
         new_one.colorgamut.randomize()
     return new_one
Example #6
0
    def randomize(self):
        """Randomize the layers components."""
        super(QuadTreeLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        depth_constraint = cpool.get(self, DEPTH_CONSTRAINT)
        self.depth = model_random.randint_constrained(depth_constraint)

        border_width_constraint = cpool.get(self, BORDER_WIDTH_CONSTRAINT)
        self.border_width = model_random.uniform_constrained(
            border_width_constraint)

        propability_constraint = cpool.get(self, PROBABILITY_CONSTRAINT)
        self.propability = model_random.uniform_constrained(
            propability_constraint)

        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(
            colorgamuttype_constraint, self.path)
        self.colorgamut.randomize()

        self.tile_colors = []
        for dummy in range(self.depth):
            site_color = self.colorgamut.get_randomized_color(self.path)
            self.tile_colors.append(site_color)
Example #7
0
 def copy(self):
     """The Markov chain layer copy constructor
     # check for distinct references, needs to copy content, not references
     post: __return__ is not self
     """
     new_one = MarkovChainLayer(self.get_trunk())
     self.copy_base(new_one)
     new_one.states = self.states
     new_one.cell_colors = [None] * self.states
     for cix in range(len(self.cell_colors)):
         new_one.cell_colors[cix] = self.cell_colors[cix].copy()
     new_one.probability = [[0.0] * self.states
                            for dummy in range(self.states)]
     for row, row_probabilities in enumerate(self.probability):
         for col, cell_probability in enumerate(row_probabilities):
             new_one.probability[row][col] = cell_probability
     new_one.sampler = self.sampler.copy()
     new_one.stamp = self.stamp.copy()
     # upgrade from a release older than 'v4'
     if self.__dict__.has_key('colorgamut'):
         new_one.colorgamut = self.colorgamut.copy()
     else:
         cpool = model_constraintpool.ConstraintPool.get_pool()
         colorgamut_factory = ka_factory.get_factory('colorgamut')
         colorgamuttype_constraint = cpool.get(self,
                                               COLORGAMUTTYPE_CONSTRAINT)
         new_one.colorgamut = colorgamut_factory.create_random(
             colorgamuttype_constraint, new_one.path)
         new_one.colorgamut.randomize()
     return new_one
    def randomize(self):
        """Randomize the layers components.
        post: len(self.cell_colors) == self.states
        post: forall(self.rules, lambda f: 0 <= f < self.states)
        """
        super(LcaLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        size_constraint = cpool.get(self, SIZE_CONSTRAINT)
        self.size = model_random.randint_constrained(size_constraint)
        
        states_constraint = cpool.get(self, STATES_CONSTRAINT)
        self.states = model_random.randint_constrained(states_constraint)
        
        left_neighbors_constraint = cpool.get(self, LEFT_NEIGHBORS_CONSTRAINT)
        self.left_neighbors = model_random.randint_constrained(left_neighbors_constraint)
        right_neighbors_constraint = cpool.get(self, RIGHT_NEIGHBORS_CONSTRAINT)
        self.right_neighbors = model_random.randint_constrained(right_neighbors_constraint)
        
        self.rules = [random.randrange(0, self.states) \
                                for dummy in xrange(self.get_numberof_rules())]
        self.sequence_ordering = random.uniform(0.0, 1.0)
        
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(colorgamuttype_constraint, 
                                                           self.path)
        self.colorgamut.randomize()

        self.cell_colors = []
        for dummy in range(self.states):
            site_color = self.colorgamut.get_randomized_color(self.path)
            self.cell_colors.append(site_color)
Example #9
0
    def __init__(self, trunk):
        """Voronoi diagram layer constructor"""
        super(VoronoiDiagramLayer, self).__init__(trunk)
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)

        self.sites_point = [exon_position.Position(self.path, 0.0, 0.0)]
        self.sites_color = [self.colorgamut.get_randomized_color(self.path)]
        #        self._distance = VoronoiDiagramLayer._euclidean_square_distance
        self.order = 2  # euclidean distance
        sampler_factory = ka_factory.get_factory('sampler')
        sampler_key = sampler_factory.keys()[0]
        self.sampler = sampler_factory.create(sampler_key, self.path)
        stamp_factory = ka_factory.get_factory('stamp')
        stamp_key = stamp_factory.keys()[0]
        self.stamp = stamp_factory.create(stamp_key, self.path,
                                          len(self.sites_point))
Example #10
0
    def randomize(self):
        """Randomize the tree nodes components.
        post: self.layer is not None
        """
        cpool = model_constraintpool.ConstraintPool.get_pool()

        self.left_background.randomize()
        self.right_background.randomize()

        # create layer
        layer_factory = ka_factory.get_factory('layer')
        layertype_constraint = cpool.get(self, LAYERTYPE_CONSTRAINT)
        self.layer = layer_factory.create_random(layertype_constraint,
                                                 self.path)
        self.layer.randomize()

        # create strategy for merging 'left' and 'right' layer
        merger_factory = ka_factory.get_factory('merger')
        mergertype_constraint = cpool.get(self, MERGERTYPE_CONSTRAINT)
        self.merger = merger_factory.create_random(mergertype_constraint,
                                                   self.path)
        self.merger.randomize()

        # create strategy for modifying stacked layers
        modifier_factory = ka_factory.get_factory('modifier')
        modifiertype_constraint = cpool.get(self, MODIFIERTYPE_CONSTRAINT)
        self.modifier = modifier_factory.create_random(modifiertype_constraint,
                                                       self.path)
        self.modifier.randomize()

        number_of_constraint = cpool.get(self, NUMBER_OF_LAYERS_CONSTRAINT)
        depth = _count_slash(self.path)
        if (depth <= number_of_constraint[0] or \
           (depth > number_of_constraint[0] and random.choice([False, True]))) \
           and  depth <= number_of_constraint[1]:
            self.left_treenode = TreeNode(self.path)
            self.left_treenode.path += 'Left'
            self.left_treenode.randomize()
        if (depth <= number_of_constraint[0] or \
           (depth > number_of_constraint[0] and random.choice([False, True]))) \
           and  depth <= number_of_constraint[1]:
            self.right_treenode = TreeNode(self.path)
            self.right_treenode.path += 'Right'
            self.right_treenode.randomize()
Example #11
0
    def __init__(self, trunk):
        """Markov chain layer constructor"""
        super(MarkovChainLayer, self).__init__(trunk)
        self.states = 0
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)
        self.cell_colors = []

        self.probability = [[1.0] * self.states
                            for dummy in range(self.states)]

        sampler_factory = ka_factory.get_factory('sampler')
        sampler_key = sampler_factory.keys()[0]
        self.sampler = sampler_factory.create(sampler_key, self.path)

        stamp_factory = ka_factory.get_factory('stamp')
        stamp_key = stamp_factory.keys()[0]
        self.stamp = stamp_factory.create(stamp_key, self.path, self.states)
Example #12
0
    def __init__(self, trunk):
        """Quad tree layer constructor"""
        super(QuadTreeLayer, self).__init__(trunk)
        self.depth = 1
        self.propability = 0.5
        self.border_width = 0.01
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)

        self.tile_colors = [self.colorgamut.get_randomized_color(self.path)]
 def __init__(self, trunk):
     """CircularArc diagram layer constructor"""
     super(CircularArc, self).__init__(trunk)
     cpool = model_constraintpool.ConstraintPool.get_pool()
     self.linecolor = exon_color.Color(self.path, 0, 0, 0, 1)
     self.line_width = cpool.get(self, LINE_WIDTH__CONSTRAINT)[0]
     self.size = cpool.get(self, SIZE_CONSTRAINT)[0]
     self.start_angle = cpool.get(self, START_ANGLE_CONSTRAINT)[0]
     self.angle = cpool.get(self, ANGLE_CONSTRAINT)[0]
     sampler_factory = ka_factory.get_factory('sampler')
     sampler_key = sampler_factory.keys()[0]
     self.sampler = sampler_factory.create(sampler_key, self.path)
Example #14
0
 def randomize(self):
     """Randomize the layers components."""
     super(FilledSpline, self).randomize()
     cpool = model_constraintpool.ConstraintPool.get_pool()
     line_width_constraint = cpool.get(self, 'line_width')
     roundness_constraint = cpool.get(self, 'roundness')
     colorgamut_factory = ka_factory.get_factory('colorgamut')
     colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
     self.colorgamut = colorgamut_factory.create_random(
         colorgamuttype_constraint, self.path)
     self.colorgamut.randomize()
     self.linecolor = self.colorgamut.get_randomized_color(self.path)
     self.fillcolor = self.colorgamut.get_randomized_color(self.path)
     self.line_width = model_random.uniform_constrained(
         line_width_constraint)
     self.roundness = model_random.uniform_constrained(roundness_constraint)
     self.center.randomize()
     sampler_factory = ka_factory.get_factory('sampler')
     samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
     self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                  self.path)
     self.sampler.randomize()
Example #15
0
    def randomize(self):
        """Randomize the layers components."""
        super(VoronoiDiagramLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        number_of_constraint = cpool.get(self, NUMBER_OF_SITES_CONSTRAINT)

        order_constraint = cpool.get(self, ORDER_CONSTRAINT)
        self.order = model_random.uniform_constrained(order_constraint)

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                     self.path)
        self.sampler.randomize()

        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(
            colorgamuttype_constraint, self.path)
        self.colorgamut.randomize()

        self.sites_point = []
        for dummy in range(
                model_random.randint_constrained(number_of_constraint)):
            site_point = exon_position.Position(self.path, 0.0, 0.0)
            site_point.randomize()
            self.sites_point.append(site_point)
        self.sites_color = []
        for dummy in range(
                model_random.randint_constrained(number_of_constraint)):
            site_color = self.colorgamut.get_randomized_color(self.path)
            self.sites_color.append(site_color)

        stamp_factory = ka_factory.get_factory('stamp')
        stamptype_constraint = cpool.get(self, STAMPTYPE_CONSTRAINT)
        self.stamp = stamp_factory.create_random(stamptype_constraint,
                                                 self.path,
                                                 len(self.sites_point))
        self.stamp.randomize()
Example #16
0
 def __init__(self, trunk):
     """LetterPress diagram layer constructor"""
     super(LetterPress, self).__init__(trunk)
     cpool = model_constraintpool.ConstraintPool.get_pool()
     self.textcolor = exon_color.Color(self.path, 0, 0, 0, 1)
     self.family = cpool.get(self, FONTFAMILY_CONSTRAINT)[0]
     self.style = cpool.get(self, FONTSTYLE_CONSTRAINT)[0]
     self.size = cpool.get(self, FONTSIZE_CONSTRAINT)[0]
     self.weight = cpool.get(self, FONTWEIGHT_CONSTRAINT)[0]
     self.center = exon_position.Position(self.path, 0.0, 0.0)
     sampler_factory = ka_factory.get_factory('sampler')
     sampler_key = sampler_factory.keys()[0]
     self.sampler = sampler_factory.create(sampler_key, self.path)
     self.buzzwords = exon_buzzword.Buzzword(self.path, [''])
    def __init__(self, trunk):
        """linear cellular automata layer constructor
        post: len(self.cell_colors) == self.states
        """
        super(LcaLayer, self).__init__(trunk)
        self.size = 2
        self.states = 2
        self.left_neighbors = 1
        self.right_neighbors = 1
        rsize = self.states ** (self.left_neighbors + 1 + self.right_neighbors)
        self.rules = [0 for dummy in xrange(rsize)]
        self.sequence_ordering = 0.25

        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)
        self.cell_colors = [self.colorgamut.get_randomized_color(self.path),
                            self.colorgamut.get_randomized_color(self.path), ]
    def randomize(self):
        """Randomize the layers components."""
        super(CircularArc, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.linecolor.randomize()
        line_width_constraint = cpool.get(self, LINE_WIDTH__CONSTRAINT)
        self.line_width = model_random.uniform_constrained(
            line_width_constraint)
        size_constraint = cpool.get(self, SIZE_CONSTRAINT)
        self.size = model_random.uniform_constrained(size_constraint)
        start_angle_constraint = cpool.get(self, START_ANGLE_CONSTRAINT)
        self.start_angle = model_random.uniform_constrained(
            start_angle_constraint)
        angle_constraint = cpool.get(self, ANGLE_CONSTRAINT)
        self.angle = model_random.uniform_constrained(angle_constraint)

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                     self.path)
        self.sampler.randomize()
Example #19
0
    def randomize(self):
        """Randomize the layers components."""
        super(LetterPress, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.textcolor.randomize()
        family_constraint = cpool.get(self, FONTFAMILY_CONSTRAINT)
        self.family = random.choice(family_constraint)
        style_constraint = cpool.get(self, FONTSTYLE_CONSTRAINT)
        self.style = random.choice(style_constraint)
        size_constraint = cpool.get(self, FONTSIZE_CONSTRAINT)
        self.size = model_random.randint_constrained(size_constraint)
        weight_constraint = cpool.get(self, FONTWEIGHT_CONSTRAINT)
        self.weight = model_random.randint_constrained(weight_constraint)
        self.center.randomize()

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint, 
                                                     self.path)
        self.sampler.randomize()

        self.buzzwords.randomize()
Example #20
0
 def copy(self):
     """The Voronoi diagram layers copy constructor.
     # check for distinct references, needs to copy content, not references
     post: __return__ is not self
     """
     new_one = VoronoiDiagramLayer(self.get_trunk())
     self.copy_base(new_one)
     new_one.sites_point = model_random.copy_list(self.sites_point)
     new_one.sites_color = model_random.copy_list(self.sites_color)
     new_one.order = self.order
     new_one.sampler = self.sampler.copy()
     new_one.stamp = self.stamp.copy()
     # upgrade from a release older than 'v4'
     if self.__dict__.has_key('colorgamut'):
         new_one.colorgamut = self.colorgamut.copy()
     else:
         cpool = model_constraintpool.ConstraintPool.get_pool()
         colorgamut_factory = ka_factory.get_factory('colorgamut')
         colorgamuttype_constraint = cpool.get(self,
                                               COLORGAMUTTYPE_CONSTRAINT)
         new_one.colorgamut = colorgamut_factory.create_random(
             colorgamuttype_constraint, new_one.path)
         new_one.colorgamut.randomize()
     return new_one
Example #21
0
class QuadTreeLayer(model_layer.Layer):
    """QuadTreeLayer
    inv: len(self.tile_colors) > 0
    inv: self.depth  > 0
    """

    cdef = [
        {
            'bind': PROBABILITY_CONSTRAINT,
            'name': 'Probability of stepping one recursion deeper',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': 0.0,
            'max': 1.0
        },
        {
            'bind': DEPTH_CONSTRAINT,
            'name': 'Maximum recursion depth for quadtree',
            'domain': model_constraintpool.INT_RANGE,
            'min': 1,
            'max': 5
        },
        {
            'bind': BORDER_WIDTH_CONSTRAINT,
            'name': 'Width of the surrounding border',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': 0.001,
            'max': 0.1
        },
        {
            'bind': COLORGAMUTTYPE_CONSTRAINT,
            'name': 'Permitted color gamut',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('colorgamut').keys()
        },
    ]

    def __init__(self, trunk):
        """Quad tree layer constructor"""
        super(QuadTreeLayer, self).__init__(trunk)
        self.depth = 1
        self.propability = 0.5
        self.border_width = 0.01
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)

        self.tile_colors = [self.colorgamut.get_randomized_color(self.path)]

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in self.tile_colors:
            result += ka_debug.dot_ref(anchor, ref)
        return result

    def __eq__(self, other):
        """Equality """
        equal = isinstance(other, QuadTreeLayer) \
                and model_layer.Layer.__eq__(self, other) \
                and len(self.tile_colors) == len(other.tile_colors) \
                and self.depth == other.depth \
                and self.propability == other.propability \
                and self.border_width == other.border_width
        if equal:
            for index, site_color in enumerate(self.tile_colors):
                equal = equal and site_color == other.tile_colors[index]
        return equal

    def randomize(self):
        """Randomize the layers components."""
        super(QuadTreeLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        depth_constraint = cpool.get(self, DEPTH_CONSTRAINT)
        self.depth = model_random.randint_constrained(depth_constraint)

        border_width_constraint = cpool.get(self, BORDER_WIDTH_CONSTRAINT)
        self.border_width = model_random.uniform_constrained(
            border_width_constraint)

        propability_constraint = cpool.get(self, PROBABILITY_CONSTRAINT)
        self.propability = model_random.uniform_constrained(
            propability_constraint)

        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(
            colorgamuttype_constraint, self.path)
        self.colorgamut.randomize()

        self.tile_colors = []
        for dummy in range(self.depth):
            site_color = self.colorgamut.get_randomized_color(self.path)
            self.tile_colors.append(site_color)

    def mutate(self):
        """Make small random changes to the layers components."""
        super(QuadTreeLayer, self).mutate()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        depth_constraint = cpool.get(self, DEPTH_CONSTRAINT)
        self.depth = model_random.jitter_discret_constrained(
            self.depth, depth_constraint)
        propability_constraint = cpool.get(self, PROBABILITY_CONSTRAINT)
        self.propability = model_random.jitter_constrained(
            self.propability, propability_constraint)

        border_width_constraint = cpool.get(self, BORDER_WIDTH_CONSTRAINT)
        self.border_width = model_random.jitter_constrained(
            self.border_width, border_width_constraint)

        self.colorgamut.mutate()
        new_site_color = self.colorgamut.get_randomized_color(self.path)
        model_random.mutate_list(self.tile_colors, depth_constraint,
                                 new_site_color)
        for cix in range(len(self.tile_colors)):
            self.colorgamut.adjust_color(self.tile_colors[cix])

    def swap_places(self):
        """Shuffle similar components."""
        model_random.swap_places(self.tile_colors)

    def crossingover(self, other):
        """
        pre: isinstance(other, QuadTreeLayer)
        pre: isinstance(self, QuadTreeLayer)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        """
        new_one = QuadTreeLayer(self.get_trunk())
        cross_sequence = self.crossingover_base(new_one, other, 4)
        new_one.depth = self.depth if cross_sequence[0] \
                                               else other.depth
        new_one.propability = self.propability if cross_sequence[1] \
                                               else other.propability
        new_one.border_width = self.border_width if cross_sequence[2] \
                                               else other.border_width
        new_one.colorgamut = other.colorgamut.copy() if cross_sequence[3] \
                                                     else self.colorgamut.copy()
        new_one.tile_colors = model_random.crossingover_list(
            self.tile_colors, other.tile_colors)
        for cix in range(len(new_one.tile_colors)):
            new_one.colorgamut.adjust_color(new_one.tile_colors[cix])

        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        self.begin_render(ctx, width, height)
        cell_rand = random.Random(self.random_seed)
        self.render_tile(task, ctx, cell_rand, self.depth, -0.5, -0.5, 1.0,
                         1.0)

    def render_tile(self, task, ctx, cell_rand, depth, x, y, width, height):
        next_depth = depth - 1
        rgba = self.tile_colors[next_depth % len(self.tile_colors)].rgba
        ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
        ctx.rectangle(x, y, width, height)
        ctx.fill()
        if depth > 0 and not task.quit \
           and cell_rand.random() < self.propability:
            width2, height2 = 0.5 * width, 0.5 * height
            self.render_tile(task, ctx, cell_rand, next_depth, x, y, width2,
                             height2)
            self.render_tile(task, ctx, cell_rand, next_depth, x + width2, y,
                             width2, height2)
            self.render_tile(task, ctx, cell_rand, next_depth, x, y + height2,
                             width2, height2)
            self.render_tile(task, ctx, cell_rand, next_depth, x + width2,
                             y + height2, width2, height2)
        ctx.set_line_width((width + height) * self.border_width)
        ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
        ctx.rectangle(x, y, width, height)
        ctx.stroke()

    def explain(self, formater):
        formater.begin_list(_('Layer ') + self.__class__.__name__)
        super(QuadTreeLayer, self).explain(formater)
        formater.text_item(
            _('Probability of stepping one recursion step deeper: ') +
            str(self.propability))
        formater.text_item(_('Maximum recursion depth: ') + str(self.depth))
        formater.text_item(
            _('Width of the surrounding border: ') + str(self.border_width))
        self.colorgamut.explain(formater)
        formater.color_array(self.tile_colors, _('Site colors:'))
        formater.end_list()

    def copy(self):
        """The Quad tree layers copy constructor.
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        """
        new_one = QuadTreeLayer(self.get_trunk())
        self.copy_base(new_one)
        new_one.tile_colors = model_random.copy_list(self.tile_colors)
        new_one.propability = self.propability
        new_one.depth = self.depth
        new_one.border_width = self.border_width
        new_one.colorgamut = self.colorgamut.copy()
        return new_one
class CircularArc(model_layer.Layer):
    """A layer with circular arcs
    """

    cdef = [
        {
            'bind': LINE_WIDTH__CONSTRAINT,
            'name': 'Specifies line width of the circle.',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': 0.01,
            'max': 0.25
        },
        {
            'bind': SIZE_CONSTRAINT,
            'name': 'A factor for scaling the radius of the circle.',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': 0.01,
            'max': 1.0
        },
        {
            'bind': START_ANGLE_CONSTRAINT,
            'name': 'The start angle, in radians.',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': 0.0,
            'max': 2.0 * math.pi
        },
        {
            'bind': ANGLE_CONSTRAINT,
            'name': 'The angle spawned by this arc, in radians.',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': -3.0 * math.pi,
            'max': 3.0 * math.pi
        },
        {
            'bind': SAMPLERTYPE_CONSTRAINT,
            'name': 'Permitted sampler types',
            'domain': model_constraintpool.STRING_1_OF_N,
            'enum': ka_factory.get_factory('sampler').keys()
        },
    ]

    def __init__(self, trunk):
        """CircularArc diagram layer constructor"""
        super(CircularArc, self).__init__(trunk)
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.linecolor = exon_color.Color(self.path, 0, 0, 0, 1)
        self.line_width = cpool.get(self, LINE_WIDTH__CONSTRAINT)[0]
        self.size = cpool.get(self, SIZE_CONSTRAINT)[0]
        self.start_angle = cpool.get(self, START_ANGLE_CONSTRAINT)[0]
        self.angle = cpool.get(self, ANGLE_CONSTRAINT)[0]
        sampler_factory = ka_factory.get_factory('sampler')
        sampler_key = sampler_factory.keys()[0]
        self.sampler = sampler_factory.create(sampler_key, self.path)

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in [
                self.linecolor,
                self.sampler,
        ]:
            result += ka_debug.dot_ref(anchor, ref)
        return result

    def __eq__(self, other):
        """Equality based on the objects components."""
        equal = isinstance(other, CircularArc) \
                and super(CircularArc, self).__eq__(other) \
                and self.linecolor == other.linecolor \
                and self.line_width == other.line_width \
                and self.size == other.size \
                and self.start_angle == other.start_angle \
                and self.angle == other.angle \
                and self.sampler == other.sampler
        return equal

    def randomize(self):
        """Randomize the layers components."""
        super(CircularArc, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.linecolor.randomize()
        line_width_constraint = cpool.get(self, LINE_WIDTH__CONSTRAINT)
        self.line_width = model_random.uniform_constrained(
            line_width_constraint)
        size_constraint = cpool.get(self, SIZE_CONSTRAINT)
        self.size = model_random.uniform_constrained(size_constraint)
        start_angle_constraint = cpool.get(self, START_ANGLE_CONSTRAINT)
        self.start_angle = model_random.uniform_constrained(
            start_angle_constraint)
        angle_constraint = cpool.get(self, ANGLE_CONSTRAINT)
        self.angle = model_random.uniform_constrained(angle_constraint)

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                     self.path)
        self.sampler.randomize()

    def mutate(self):
        """Make small random changes to the layers components."""
        super(CircularArc, self).mutate()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.linecolor.mutate()
        line_width_constraint = cpool.get(self, LINE_WIDTH__CONSTRAINT)
        self.line_width = model_random.jitter_constrained(
            self.line_width, line_width_constraint)
        size_constraint = cpool.get(self, SIZE_CONSTRAINT)
        self.size = model_random.jitter_constrained(self.size, size_constraint)
        start_angle_constraint = cpool.get(self, START_ANGLE_CONSTRAINT)
        self.start_angle = model_random.jitter_constrained(
            self.start_angle, start_angle_constraint)
        angle_constraint = cpool.get(self, ANGLE_CONSTRAINT)
        self.angle = model_random.jitter_constrained(self.angle,
                                                     angle_constraint)
        self.sampler.mutate()

    def swap_places(self):
        """Shuffle similar components."""
        self.sampler.swap_places()

    def crossingover(self, other):
        """
        pre: isinstance(other, CircularArc)
        pre: isinstance(self, CircularArc)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        """
        new_one = CircularArc(self.get_trunk())
        crossing = self.crossingover_base(new_one, other, 4)
        new_one.linecolor = self.linecolor.crossingover(other.linecolor)
        new_one.line_width = self.line_width if crossing[
            0] else other.line_width
        new_one.size = self.size if crossing[1] else other.size
        new_one.start_angle = self.start_angle if crossing[
            2] else other.start_angle
        new_one.angle = self.angle if crossing[3] else other.angle
        new_one.sampler = model_random.crossingover_elem(
            self.sampler, other.sampler)
        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        self.begin_render(ctx, width, height)

        ctx.save()
        #        ka_debug.matrix_s(ctx.get_matrix())
        ctx.set_line_width(self.line_width)
        rgba = self.linecolor.rgba
        ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
        points = self.sampler.get_sample_points()
        for index, point in enumerate(points):
            nb2 = index + 1
            if nb2 < len(points):
                radius = self.size*math.sqrt((points[nb2][0]-point[0])**2.0 \
                                             + (points[nb2][1]-point[1])**2.0)
                if self.angle > 2.0 * math.pi or self.angle < -2.0 * math.pi:
                    ctx.arc(point[0], point[1], radius, 0.0, 2.0 * math.pi)
                elif self.angle > 0.0:
                    ctx.arc(point[0], point[1], radius, self.start_angle,
                            self.start_angle + self.angle)
                else:
                    ctx.arc_negative(point[0], point[1], radius,
                                     self.start_angle,
                                     self.start_angle + self.angle)
                ctx.stroke()

#        ka_debug.matrix_r(ctx.get_matrix())
        ctx.restore()

    def explain(self, formater):
        formater.begin_list(_('Layer ') + self.__class__.__name__)
        super(CircularArc, self).explain(formater)
        formater.color_item(self.linecolor, _('line color:'))
        formater.text_item(_('line width: ') + str(self.line_width))
        formater.text_item(_('size: ') + str(self.size))
        formater.text_item(_('start angle: ') + str(self.start_angle))
        formater.text_item(_('angle: ') + str(self.angle))
        text, surface, descr = self.sampler.explain()
        if surface is not None:
            formater.surface_item(surface,
                                  _('sampling points: ') + text, descr)
        else:
            formater.text_item(text)
        formater.end_list()

    def copy(self):
        """The CircularArc diagram layers copy constructor.
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        """
        new_one = CircularArc(self.get_trunk())
        self.copy_base(new_one)
        new_one.linecolor = self.linecolor.copy()
        new_one.line_width = self.line_width
        new_one.size = self.size
        new_one.start_angle = self.start_angle
        new_one.angle = self.angle
        new_one.sampler = self.sampler.copy()
        return new_one
Example #23
0
class FilledSpline(model_layer.Layer):
    """FilledSpline
    """

    cdef = [
        {
            'bind': 'length',
            'name': 'Number of interpolation points',
            'domain': model_constraintpool.INT_RANGE,
            'min': 4,
            'max': 32
        },
        {
            'bind': 'line_width',
            'name': 'Line width',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': 0.001,
            'max': 0.25
        },
        {
            'bind': 'roundness',
            'name': 'Roundness of spline',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': 0.1,
            'max': 20.0
        },
        {
            'bind': SAMPLERTYPE_CONSTRAINT,
            'name': 'Permitted sampler types',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('sampler').keys()
        },
        {
            'bind': COLORGAMUTTYPE_CONSTRAINT,
            'name': 'Permitted color gamut',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('colorgamut').keys()
        },
    ]

    def __init__(self, trunk):
        """FilledSpline diagram layer constructor"""
        super(FilledSpline, self).__init__(trunk)
        cpool = model_constraintpool.ConstraintPool.get_pool()
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)
        self.linecolor = self.colorgamut.get_randomized_color(self.path)
        self.fillcolor = self.colorgamut.get_randomized_color(self.path)
        self.line_width = cpool.get(self, 'line_width')[0]
        self.roundness = cpool.get(self, 'roundness')[0]
        self.center = exon_position.Position(self.path, 0.0, 0.0)
        sampler_factory = ka_factory.get_factory('sampler')
        sampler_key = sampler_factory.keys()[0]
        self.sampler = sampler_factory.create(sampler_key, self.path)

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in [
                self.colorgamut, self.linecolor, self.fillcolor, self.center,
                self.sampler
        ]:
            result += ka_debug.dot_ref(anchor, ref)
        return result

    def __eq__(self, other):
        """Equality based on the objects components."""
        equal = isinstance(other, FilledSpline) \
                and super(FilledSpline, self).__eq__(other) \
                and self.linecolor == other.linecolor \
                and self.fillcolor == other.fillcolor \
                and self.line_width == other.line_width \
                and self.roundness == other.roundness \
                and self.center == other.center \
                and self.sampler == other.sampler \
                and self.colorgamut == other.colorgamut
        return equal

    def randomize(self):
        """Randomize the layers components."""
        super(FilledSpline, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        line_width_constraint = cpool.get(self, 'line_width')
        roundness_constraint = cpool.get(self, 'roundness')
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(
            colorgamuttype_constraint, self.path)
        self.colorgamut.randomize()
        self.linecolor = self.colorgamut.get_randomized_color(self.path)
        self.fillcolor = self.colorgamut.get_randomized_color(self.path)
        self.line_width = model_random.uniform_constrained(
            line_width_constraint)
        self.roundness = model_random.uniform_constrained(roundness_constraint)
        self.center.randomize()
        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                     self.path)
        self.sampler.randomize()

    def mutate(self):
        """Make small random changes to the layers components."""
        super(FilledSpline, self).mutate()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        line_width_constraint = cpool.get(self, 'line_width')
        roundness_constraint = cpool.get(self, 'roundness')
        self.colorgamut.mutate()
        self.colorgamut.adjust_color(self.linecolor)
        self.colorgamut.adjust_color(self.fillcolor)
        self.line_width = model_random.jitter_constrained(
            self.line_width, line_width_constraint)
        self.roundness = model_random.jitter_constrained(
            self.roundness, roundness_constraint)
        self.center.mutate()
        self.sampler.mutate()

    def swap_places(self):
        """Shuffle similar components."""
        self.center.swap_places()
        self.sampler.swap_places()

    def crossingover(self, other):
        """
        pre: isinstance(other, FilledSpline)
        pre: isinstance(self, FilledSpline)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        """
        new_one = FilledSpline(self.get_trunk())
        crossing = self.crossingover_base(new_one, other, 3)
        if crossing[0]:
            new_one.colorgamut = other.colorgamut.copy()
            new_one.linecolor = other.linecolor.copy()
            new_one.fillcolor = other.fillcolor.copy()
        else:
            new_one.colorgamut = self.colorgamut.copy()
            new_one.linecolor = self.linecolor.copy()
            new_one.fillcolor = self.fillcolor.copy()
        new_one.line_width = other.line_width if crossing[
            1] else self.line_width
        new_one.roundness = other.roundness if crossing[2] else self.roundness
        new_one.center = self.center.crossingover(other.center)
        new_one.sampler = model_random.crossingover_elem(
            self.sampler, other.sampler)
        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        self.begin_render(ctx, width, height)

        px, py = self.center.x_pos, self.center.y_pos
        ctx.move_to(px, py)
        points = self.sampler.get_sample_points()
        for index in xrange(len(points)):
            if index == 0:
                pass
            elif index == 1:
                ctx.move_to(px + points[index][0], py + points[index][1])
            elif index == len(points) - 1:
                pass
            else:
                end_x, end_y = points[index][0], points[index][1]
                cstart_x = points[index - 1][0] - self.roundness * (
                    points[index - 1][0] - points[index - 2][0])
                cstart_y = points[index - 1][1] - self.roundness * (
                    points[index - 1][1] - points[index - 2][1])
                cend_x = end_x + self.roundness * (points[index + 1][0] -
                                                   end_x)
                cend_y = end_y + self.roundness * (points[index + 1][1] -
                                                   end_y)
                #                cstart_x = (points[index-1][0]+points[index-2][0])
                #                cstart_y = (points[index-1][1]+points[index-2][1])
                #                cend_x   = (points[index+1][0]+end_x)
                #                cend_y   = (points[index+1][1]+end_y)
                ctx.curve_to(
                    px + cend_x,
                    py + cend_y,  # end control point
                    px + cstart_x,
                    py + cstart_y,  # start control point
                    px + end_x,
                    py + end_y)  # end point
#        print str(ctx.copy_path())
        rgba = self.fillcolor.rgba
        ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
        ctx.fill_preserve()
        ctx.set_line_width(self.line_width)
        rgba = self.linecolor.rgba
        ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
        ctx.stroke()

    def explain(self, formater):
        formater.begin_list(_('Layer ') + self.__class__.__name__)
        super(FilledSpline, self).explain(formater)
        self.colorgamut.explain(formater)
        formater.color_item(self.linecolor, _('line color:'))
        formater.text_item(_('line width: ') + str(self.line_width))
        formater.text_item(_('roundness: ') + str(self.roundness))
        formater.color_item(self.fillcolor, _('fill color:'))
        formater.position_item(self.center, _('center:'))
        text, surface, descr = self.sampler.explain()
        if surface is not None:
            formater.surface_item(surface,
                                  _('sampling points: ') + text, descr)
        else:
            formater.text_item(text)
        formater.end_list()

    def copy(self):
        """The FilledSpline diagram layers copy constructor.
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        """
        new_one = FilledSpline(self.get_trunk())
        self.copy_base(new_one)
        new_one.linecolor = self.linecolor.copy()
        new_one.fillcolor = self.fillcolor.copy()
        new_one.line_width = self.line_width
        new_one.roundness = self.roundness
        new_one.center = self.center.copy()
        new_one.sampler = self.sampler.copy()
        # upgrade from a release older than 'v4'
        if self.__dict__.has_key('colorgamut'):
            new_one.colorgamut = self.colorgamut.copy()
        else:
            cpool = model_constraintpool.ConstraintPool.get_pool()
            colorgamut_factory = ka_factory.get_factory('colorgamut')
            colorgamuttype_constraint = cpool.get(self,
                                                  COLORGAMUTTYPE_CONSTRAINT)
            new_one.colorgamut = colorgamut_factory.create_random(
                colorgamuttype_constraint, new_one.path)
            new_one.colorgamut.randomize()
        return new_one
Example #24
0
class MarkovChainLayer(model_layer.Layer):
    """Markov chain layer
    inv: self.cell_colors is not None and len(self.cell_colors) == self.states
    inv: self.probability is not None and len(self.probability) == self.states
    inv: 0 <= self.states
    inv: self.sampler is not None
    inv: self.stamp is not None
    """

    cdef = [
        {
            'bind': NUMBER_OF_STATES_CONSTRAINT,
            'name': 'Number of states',
            'domain': model_constraintpool.INT_RANGE,
            'min': 2,
            'max': 8
        },
        {
            'bind': SAMPLERTYPE_CONSTRAINT,
            'name': 'Permitted sampler types',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('sampler').keys()
        },
        {
            'bind': STAMPTYPE_CONSTRAINT,
            'name': 'Permitted stamp types',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('stamp').keys()
        },
        {
            'bind': COLORGAMUTTYPE_CONSTRAINT,
            'name': 'Permitted color gamut',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('colorgamut').keys()
        },
    ]

    def __init__(self, trunk):
        """Markov chain layer constructor"""
        super(MarkovChainLayer, self).__init__(trunk)
        self.states = 0
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)
        self.cell_colors = []

        self.probability = [[1.0] * self.states
                            for dummy in range(self.states)]

        sampler_factory = ka_factory.get_factory('sampler')
        sampler_key = sampler_factory.keys()[0]
        self.sampler = sampler_factory.create(sampler_key, self.path)

        stamp_factory = ka_factory.get_factory('stamp')
        stamp_key = stamp_factory.keys()[0]
        self.stamp = stamp_factory.create(stamp_key, self.path, self.states)

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in self.cell_colors:
            result += ka_debug.dot_ref(anchor, ref)
        for ref in self.probability:
            result += ka_debug.dot_ref(anchor, ref)
        for ref in [self.sampler, self.stamp, self.colorgamut]:
            result += ka_debug.dot_ref(anchor, ref)
        return result

    def _init_states(self, number_of_states):
        """
        pre: number_of_states >= 2
        post: self.states == number_of_states
        """
        if self.states == number_of_states:
            return False
        else:
            if self.states > number_of_states:
                self._shrink_states(number_of_states)
            elif self.states < number_of_states:
                self._append_states(number_of_states)
            self.states = number_of_states
            return True

    def _append_states(self, number_of_states):
        """
        pre: self.states < number_of_states
        pre: number_of_states > 0
        """
        for dummy in range(self.states, number_of_states):
            self.cell_colors.append(
                self.colorgamut.get_randomized_color(self.path))
        # completely recalculate probabilities
        self.probability = [[1.0 / number_of_states] * number_of_states
                            for dummy in range(number_of_states)]
        for row, row_probabilities in enumerate(self.probability):
            for col in range(len(row_probabilities)):
                self.probability[row][col] = random.random() / number_of_states
            self._normalize_row(row)

    def _shrink_states(self, number_of_states):
        """
        pre: self.states > number_of_states
        pre: number_of_states > 0
        """
        # copy remaining cell colors
        copy_cell_colors = [None] * number_of_states
        for cix in range(number_of_states):
            copy_cell_colors[cix] = self.cell_colors[cix].copy()
        self.cell_colors = copy_cell_colors
        # copy remaining probabilities
        copy_probability = [[1.0] * number_of_states
                            for dummy in range(number_of_states)]
        for row, row_probabilities in enumerate(copy_probability):
            for col in range(len(row_probabilities)):
                copy_probability[row][col] = self.probability[row][col]
            self._normalize_row(row)
        self.probability = copy_probability

    def _normalize_row(self, row):
        row_probabilities = self.probability[row]
        row_sum = 0.0
        for column in range(len(row_probabilities)):
            row_sum += self.probability[row][column]
        normalize = 1.0 / row_sum
        for column in range(len(row_probabilities)):
            self.probability[row][column] *= normalize

    def __eq__(self, other):
        """Equality based on the layers components."""
        equal = isinstance(other, MarkovChainLayer) \
                and super(MarkovChainLayer, self).__eq__(other) \
                and self.states == other.states \
                and self.sampler == other.sampler \
                and self.stamp == other.stamp \
                and self.colorgamut == other.colorgamut
        if equal:
            for cix, cell_color in enumerate(self.cell_colors):
                equal = equal and cell_color == other.cell_colors[cix]
        if equal:
            for row, row_probabilities in enumerate(self.probability):
                for col, cell_probability in enumerate(row_probabilities):
                    equal = equal \
                            and cell_probability == other.probability[row][col]
        return equal

    def randomize(self):
        """Randomize the layers components."""
        super(MarkovChainLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(
            colorgamuttype_constraint, self.path)
        self.colorgamut.randomize()

        number_of_states_constraint = cpool.get(self,
                                                NUMBER_OF_STATES_CONSTRAINT)
        self._init_states(
            model_random.randint_constrained(number_of_states_constraint))

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                     self.path)
        self.sampler.randomize()

        stamp_factory = ka_factory.get_factory('stamp')
        stamptype_constraint = cpool.get(self, STAMPTYPE_CONSTRAINT)
        self.stamp = stamp_factory.create_random(stamptype_constraint,
                                                 self.path, self.states)
        self.stamp.randomize()

    def mutate(self):
        """Make random changes to the layers components."""
        super(MarkovChainLayer, self).mutate()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        number_of_states_constraint = cpool.get(self,
                                                NUMBER_OF_STATES_CONSTRAINT)
        changed = self._init_states(
            model_random.jitter_discret_constrained(
                self.states, number_of_states_constraint))

        if not changed:
            for row, row_probabilities in enumerate(self.probability):
                for col in range(len(row_probabilities)):
                    self.probability[row][col] += \
                                            model_random.jitter(1.0 / self.states)
                self._normalize_row(row)

        self.sampler.mutate()
        self.stamp.mutate()
        self.colorgamut.mutate()
        for cix in range(len(self.cell_colors)):
            self.colorgamut.adjust_color(self.cell_colors[cix])

    def swap_places(self):
        """Shuffle similar components."""
        model_random.swap_places(self.cell_colors)
        model_random.swap_places(self.probability)
        for row, row_probabilities in enumerate(self.probability):
            model_random.swap_places(row_probabilities)
            self._normalize_row(row)
        self.sampler.swap_places()
        self.stamp.swap_places()

    def crossingover(self, other):
        """
        pre: isinstance(other, MarkovChainLayer)
        pre: isinstance(self, MarkovChainLayer)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        """
        new_one = MarkovChainLayer(self.get_trunk())
        cross_sequence = self.crossingover_base(new_one, other, 2)
        new_one.sampler = model_random.crossingover_elem(
            self.sampler, other.sampler)
        new_one.stamp = model_random.crossingover_elem(self.stamp, other.stamp)
        if cross_sequence[1]:
            probability = other.probability
            cell_colors = other.cell_colors
            new_one.states = other.states
        else:
            probability = self.probability
            cell_colors = self.cell_colors
            new_one.states = self.states
        new_one.probability = [[1.0 / new_one.states] * new_one.states
                               for dummy in range(new_one.states)]
        for row, row_probabilities in enumerate(probability):
            for col, cell_probability in enumerate(row_probabilities):
                new_one.probability[row][col] = cell_probability

        new_one.colorgamut = other.colorgamut.copy() if cross_sequence[0] \
                                                     else self.colorgamut.copy()
        new_one.cell_colors = []
        for cix in range(len(cell_colors)):
            color = cell_colors[cix].copy()
            new_one.colorgamut.adjust_color(color)
            new_one.cell_colors.append(color)
        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        self.begin_render(ctx, width, height)
        dw, dh = self.sampler.get_sample_extent()
        self.stamp.set_stamp_extent(dw, dh)
        cell_rand = random.Random(self.random_seed)
        cell_state = 0
        for point in self.sampler.get_sample_points():
            rgba = self.cell_colors[cell_state].rgba
            ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
            self.stamp.render(ctx, point, cell_state)
            cell_state = self._next_state(cell_state, cell_rand)

    def _next_state(self, cell_state, cell_rand):
        next_cell_state = self.states - 1
        row_probabilities = self.probability[cell_state]
        cell_sum, level = 0.0, cell_rand.random()
        for column, cell_probability in enumerate(row_probabilities):
            cell_sum += cell_probability
            if cell_sum >= level:
                next_cell_state = column
                break
        return next_cell_state

    def explain(self, formater):
        formater.begin_list(_('Layer ') + self.__class__.__name__)
        super(MarkovChainLayer, self).explain(formater)
        self.colorgamut.explain(formater)
        formater.color_array(self.cell_colors, _('cell colors:'))
        formater.text_item(_('number of states: ') + str(self.states))
        text, surface, descr = self.sampler.explain()
        if surface is not None:
            formater.surface_item(surface,
                                  _('sampling points: ') + text, descr)
        else:
            formater.text_item(text)
        text, surface, descr = self.stamp.explain()
        if surface is not None:
            formater.surface_item(surface, _('stamp: ') + text, descr)
        else:
            formater.text_item(text)
        formater.end_list()

    def copy(self):
        """The Markov chain layer copy constructor
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        """
        new_one = MarkovChainLayer(self.get_trunk())
        self.copy_base(new_one)
        new_one.states = self.states
        new_one.cell_colors = [None] * self.states
        for cix in range(len(self.cell_colors)):
            new_one.cell_colors[cix] = self.cell_colors[cix].copy()
        new_one.probability = [[0.0] * self.states
                               for dummy in range(self.states)]
        for row, row_probabilities in enumerate(self.probability):
            for col, cell_probability in enumerate(row_probabilities):
                new_one.probability[row][col] = cell_probability
        new_one.sampler = self.sampler.copy()
        new_one.stamp = self.stamp.copy()
        # upgrade from a release older than 'v4'
        if self.__dict__.has_key('colorgamut'):
            new_one.colorgamut = self.colorgamut.copy()
        else:
            cpool = model_constraintpool.ConstraintPool.get_pool()
            colorgamut_factory = ka_factory.get_factory('colorgamut')
            colorgamuttype_constraint = cpool.get(self,
                                                  COLORGAMUTTYPE_CONSTRAINT)
            new_one.colorgamut = colorgamut_factory.create_random(
                colorgamuttype_constraint, new_one.path)
            new_one.colorgamut.randomize()
        return new_one
Example #25
0
class VoronoiDiagramLayer(model_layer.Layer):
    """VoronoiDiagramLayer
    inv: len(self.sites_point) > 0
    inv: len(self.sites_color) > 0
    inv: self.sampler is not None
    inv: self.stamp is not None
    """

    cdef = [
        {
            'bind': ORDER_CONSTRAINT,
            'name': 'Natural logarithm of order p used in Minkowski distance',
            'domain': model_constraintpool.FLOAT_RANGE,
            'min': -4.0,
            'max': 4.0
        },
        {
            'bind': NUMBER_OF_SITES_CONSTRAINT,
            'name': 'Number of site points',
            'domain': model_constraintpool.INT_RANGE,
            'min': 2,
            'max': 10
        },
        {
            'bind': SAMPLERTYPE_CONSTRAINT,
            'name': 'Permitted sampler types',
            'domain': model_constraintpool.STRING_1_OF_N,
            'enum': ka_factory.get_factory('sampler').keys()
        },
        {
            'bind': STAMPTYPE_CONSTRAINT,
            'name': 'Permitted stamp types',
            'domain': model_constraintpool.STRING_1_OF_N,
            'enum': ka_factory.get_factory('stamp').keys()
        },
        {
            'bind': COLORGAMUTTYPE_CONSTRAINT,
            'name': 'Permitted color gamut',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('colorgamut').keys()
        },
    ]

    def __init__(self, trunk):
        """Voronoi diagram layer constructor"""
        super(VoronoiDiagramLayer, self).__init__(trunk)
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)

        self.sites_point = [exon_position.Position(self.path, 0.0, 0.0)]
        self.sites_color = [self.colorgamut.get_randomized_color(self.path)]
        #        self._distance = VoronoiDiagramLayer._euclidean_square_distance
        self.order = 2  # euclidean distance
        sampler_factory = ka_factory.get_factory('sampler')
        sampler_key = sampler_factory.keys()[0]
        self.sampler = sampler_factory.create(sampler_key, self.path)
        stamp_factory = ka_factory.get_factory('stamp')
        stamp_key = stamp_factory.keys()[0]
        self.stamp = stamp_factory.create(stamp_key, self.path,
                                          len(self.sites_point))

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in self.sites_point:
            result += ka_debug.dot_ref(anchor, ref)
        for ref in self.sites_color:
            result += ka_debug.dot_ref(anchor, ref)
        for ref in [self.sampler, self.stamp]:
            result += ka_debug.dot_ref(anchor, ref)
        return result

    def __eq__(self, other):
        """Equality """
        equal = isinstance(other, VoronoiDiagramLayer) \
                and model_layer.Layer.__eq__(self, other) \
                and len(self.sites_point) == len(other.sites_point) \
                and len(self.sites_color) == len(other.sites_color) \
                and self.order == other.order \
                and self.sampler == other.sampler \
                and self.stamp == other.stamp
        if equal:
            for index, site_point in enumerate(self.sites_point):
                equal = equal and site_point == other.sites_point[index]
        if equal:
            for index, site_color in enumerate(self.sites_color):
                equal = equal and site_color == other.sites_color[index]
        return equal

    def randomize(self):
        """Randomize the layers components."""
        super(VoronoiDiagramLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        number_of_constraint = cpool.get(self, NUMBER_OF_SITES_CONSTRAINT)

        order_constraint = cpool.get(self, ORDER_CONSTRAINT)
        self.order = model_random.uniform_constrained(order_constraint)

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint,
                                                     self.path)
        self.sampler.randomize()

        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(
            colorgamuttype_constraint, self.path)
        self.colorgamut.randomize()

        self.sites_point = []
        for dummy in range(
                model_random.randint_constrained(number_of_constraint)):
            site_point = exon_position.Position(self.path, 0.0, 0.0)
            site_point.randomize()
            self.sites_point.append(site_point)
        self.sites_color = []
        for dummy in range(
                model_random.randint_constrained(number_of_constraint)):
            site_color = self.colorgamut.get_randomized_color(self.path)
            self.sites_color.append(site_color)

        stamp_factory = ka_factory.get_factory('stamp')
        stamptype_constraint = cpool.get(self, STAMPTYPE_CONSTRAINT)
        self.stamp = stamp_factory.create_random(stamptype_constraint,
                                                 self.path,
                                                 len(self.sites_point))
        self.stamp.randomize()

    def mutate(self):
        """Make small random changes to the layers components."""
        super(VoronoiDiagramLayer, self).mutate()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        number_of_constraint = cpool.get(self, NUMBER_OF_SITES_CONSTRAINT)
        new_site_point = exon_position.Position(self.path, 0.0, 0.0)
        new_site_point.randomize()
        model_random.mutate_list(self.sites_point, number_of_constraint,
                                 new_site_point)

        self.colorgamut.mutate()
        new_site_color = self.colorgamut.get_randomized_color(self.path)
        model_random.mutate_list(self.sites_color, number_of_constraint,
                                 new_site_color)
        for cix in range(len(self.sites_color)):
            self.colorgamut.adjust_color(self.sites_color[cix])

        order_constraint = cpool.get(self, ORDER_CONSTRAINT)
        self.order = model_random.jitter_constrained(self.order,
                                                     order_constraint)

        self.sampler.mutate()
        self.stamp.mutate()

    def swap_places(self):
        """Shuffle similar components."""
        model_random.swap_places(self.sites_point)
        model_random.swap_places(self.sites_color)
        self.sampler.swap_places()
        self.stamp.swap_places()

    def crossingover(self, other):
        """
        pre: isinstance(other, VoronoiDiagramLayer)
        pre: isinstance(self, VoronoiDiagramLayer)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        """
        new_one = VoronoiDiagramLayer(self.get_trunk())
        cross_sequence = self.crossingover_base(new_one, other, 2)
        new_one.sites_point = model_random.crossingover_list(
            self.sites_point, other.sites_point)

        new_one.colorgamut = other.colorgamut.copy() if cross_sequence[0] \
                                                     else self.colorgamut.copy()
        new_one.sites_color = model_random.crossingover_list(
            self.sites_color, other.sites_color)
        for cix in range(len(new_one.sites_color)):
            new_one.colorgamut.adjust_color(new_one.sites_color[cix])

        new_one.order = self.order if cross_sequence[1] else other.order
        new_one.sampler = model_random.crossingover_elem(
            self.sampler, other.sampler)
        new_one.stamp = model_random.crossingover_elem(self.stamp, other.stamp)
        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        self.begin_render(ctx, width, height)
        dw, dh = self.sampler.get_sample_extent()
        self.stamp.set_stamp_extent(dw, dh)
        for point in self.sampler.get_sample_points():
            at_index, color = self._site_color_min_dist(point)
            rgba = color.rgba
            ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
            self.stamp.render(ctx, point, at_index)

    def _site_color_min_dist(self, point):
        """ Minkowski distance
        see http://en.wikipedia.org/wiki/Minkowski_distance
        pre: len(point) == 2
        """

        min_distance, at_index = 999999.9, 0
        for index, site_point in enumerate(self.sites_point):
            #            distance = self._distance(point, site[0])
            p = math.exp(self.order)
            try:
                distance = (math.fabs(point[0] - site_point.x_pos)**p +
                            math.fabs(point[1] - site_point.y_pos)**p)**(1.0 /
                                                                         p)
                if (distance < min_distance):
                    min_distance, at_index = distance, index
            except OverflowError:
                #                import sys
                #                print OverflowError, sys.exc_info()[0], \
                #                      '_site_color_min_dist', self.order, p, \
                #                      point[0], site_point.x_pos, point[1], site_point.y_pos
                pass
        return at_index, self.sites_color[at_index % len(self.sites_color)]

#    @staticmethod
#    def _euclidean_square_distance(point, site):
#        """
#        Like Euclidean distance distance but with square root.
#        see http://en.wikipedia.org/wiki/Euclidean_distance
#        x-coordinate is stored at index [0].
#        y-coordinate is stored at index [1].
#        """
#        return (point[0]-site.x_pos)**2 + (point[1]-site.y_pos)**2
#
#    @staticmethod
#    def _manhattan_distance(point, site):
#        """ Taxicab distance, Manhattan distance)
#        see http://en.wikipedia.org/wiki/Manhattan_distance
#        x-coordinate is stored at index [0].
#        y-coordinate is stored at index [1].
#        """
#        return math.fabs(point[0]-site.x_pos) + math.fabs(point[1]-site.y_pos)
#
#    @staticmethod
#    def _chebyshev_distance(point, site):
#        """ Chebyshev distance
#        see http://en.wikipedia.org/wiki/Chebyshev_distance
#        x-coordinate is stored at index [0].
#        y-coordinate is stored at index [1].
#        """
#        dx, dy = math.fabs(point[0]-site.x_pos), math.fabs(point[1]-site.y_pos)
#        return dx if dx > dy else dy

    def explain(self, formater):
        formater.begin_list(_('Layer ') + self.__class__.__name__)
        super(VoronoiDiagramLayer, self).explain(formater)
        self.colorgamut.explain(formater)
        formater.text_item(
            _('Natural logarithm of order p used in Minkowski distance: ') +
            str(self.order))
        formater.position_array(self.sites_point,
                                _('center points for sites:'))
        self.colorgamut.explain(formater)
        formater.color_array(self.sites_color, _('site colors:'))
        text, surface, descr = self.sampler.explain()
        if surface is not None:
            formater.surface_item(surface,
                                  _('sampling points: ') + text, descr)
        else:
            formater.text_item(text)
        text, surface, descr = self.stamp.explain()
        if surface is not None:
            formater.surface_item(surface, _('stamp: ') + text, descr)
        else:
            formater.text_item(text)
        formater.end_list()

    def copy(self):
        """The Voronoi diagram layers copy constructor.
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        """
        new_one = VoronoiDiagramLayer(self.get_trunk())
        self.copy_base(new_one)
        new_one.sites_point = model_random.copy_list(self.sites_point)
        new_one.sites_color = model_random.copy_list(self.sites_color)
        new_one.order = self.order
        new_one.sampler = self.sampler.copy()
        new_one.stamp = self.stamp.copy()
        # upgrade from a release older than 'v4'
        if self.__dict__.has_key('colorgamut'):
            new_one.colorgamut = self.colorgamut.copy()
        else:
            cpool = model_constraintpool.ConstraintPool.get_pool()
            colorgamut_factory = ka_factory.get_factory('colorgamut')
            colorgamuttype_constraint = cpool.get(self,
                                                  COLORGAMUTTYPE_CONSTRAINT)
            new_one.colorgamut = colorgamut_factory.create_random(
                colorgamuttype_constraint, new_one.path)
            new_one.colorgamut.randomize()
        return new_one
Example #26
0
class LetterPress(model_layer.Layer):
    """LetterPress
    """

    cdef = [{'bind'  : FONTFAMILY_CONSTRAINT,
             'name'  : 'Font family',
             'domain': model_constraintpool.STRING_1_OF_N,
             'enum'  : ['Normal',
                        'Sans',
                        'Serif',
                        'Monospace',]},
            {'bind'  : FONTSTYLE_CONSTRAINT,
             'name'  : 'Font style',
             'domain': model_constraintpool.INT_1_OF_N,
             'enum'  : [('Normal',  pango.STYLE_NORMAL),
                        ('Oblique', pango.STYLE_OBLIQUE),
                        ('Italic',  pango.STYLE_ITALIC),]},
            {'bind'  : FONTSIZE_CONSTRAINT,
             'name'  : 'Font size in percent of the drawing area.',
             'domain': model_constraintpool.INT_RANGE,
             'min'   : 1, 'max': 100},
            {'bind'  : FONTWEIGHT_CONSTRAINT,
             'name'  : 'Specifies how bold or light the font should be.',
             'domain': model_constraintpool.INT_RANGE,
             'min'   : 100, 'max': 900},
            {'bind'  : SAMPLERTYPE_CONSTRAINT,
             'name'  : 'Permitted sampler types',
             'domain': model_constraintpool.STRING_1_OF_N,
             'enum'  : ka_factory.get_factory('sampler').keys()},
            ]

    font_style = {pango.STYLE_NORMAL:  'Normal', 
                  pango.STYLE_OBLIQUE: 'Oblique', 
                  pango.STYLE_ITALIC:  'Italic', 
                 }

    def __init__(self, trunk):
        """LetterPress diagram layer constructor"""
        super(LetterPress, self).__init__(trunk)
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.textcolor = exon_color.Color(self.path, 0, 0, 0, 1)
        self.family = cpool.get(self, FONTFAMILY_CONSTRAINT)[0]
        self.style = cpool.get(self, FONTSTYLE_CONSTRAINT)[0]
        self.size = cpool.get(self, FONTSIZE_CONSTRAINT)[0]
        self.weight = cpool.get(self, FONTWEIGHT_CONSTRAINT)[0]
        self.center = exon_position.Position(self.path, 0.0, 0.0)
        sampler_factory = ka_factory.get_factory('sampler')
        sampler_key = sampler_factory.keys()[0]
        self.sampler = sampler_factory.create(sampler_key, self.path)
        self.buzzwords = exon_buzzword.Buzzword(self.path, [''])

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in [self.textcolor, self.center, self.sampler, self.buzzwords]:
            result += ka_debug.dot_ref(anchor, ref)
        return result
    
    def __eq__(self, other):
        """Equality based on the objects components."""
        equal = isinstance(other, LetterPress) \
                and super(LetterPress, self).__eq__(other) \
                and self.textcolor == other.textcolor \
                and self.family == other.family \
                and self.style == other.style \
                and self.size == other.size \
                and self.weight == other.weight \
                and self.center == other.center \
                and self.sampler == other.sampler \
                and self.buzzwords == other.buzzwords
        return equal

    def randomize(self):
        """Randomize the layers components."""
        super(LetterPress, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.textcolor.randomize()
        family_constraint = cpool.get(self, FONTFAMILY_CONSTRAINT)
        self.family = random.choice(family_constraint)
        style_constraint = cpool.get(self, FONTSTYLE_CONSTRAINT)
        self.style = random.choice(style_constraint)
        size_constraint = cpool.get(self, FONTSIZE_CONSTRAINT)
        self.size = model_random.randint_constrained(size_constraint)
        weight_constraint = cpool.get(self, FONTWEIGHT_CONSTRAINT)
        self.weight = model_random.randint_constrained(weight_constraint)
        self.center.randomize()

        sampler_factory = ka_factory.get_factory('sampler')
        samplertype_constraint = cpool.get(self, SAMPLERTYPE_CONSTRAINT)
        self.sampler = sampler_factory.create_random(samplertype_constraint, 
                                                     self.path)
        self.sampler.randomize()

        self.buzzwords.randomize()

    def mutate(self):
        """Make small random changes to the layers components."""
        super(LetterPress, self).mutate()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        self.textcolor.mutate()
        if model_random.is_mutating():
            family_constraint = cpool.get(self, FONTFAMILY_CONSTRAINT)
            self.family = random.choice(family_constraint)
        if model_random.is_mutating():
            style_constraint = cpool.get(self, FONTSTYLE_CONSTRAINT)
            self.style = random.choice(style_constraint)
        if model_random.is_mutating():
            size_constraint = cpool.get(self, FONTSIZE_CONSTRAINT)
            self.size = model_random.jitter_discret_constrained(
                                                    self.size, size_constraint)
        if model_random.is_mutating():
            weight_constraint = cpool.get(self, FONTWEIGHT_CONSTRAINT)
            self.weight = model_random.jitter_discret_constrained(
                                                self.weight, weight_constraint)
        self.center.mutate()
        self.sampler.mutate()
        self.buzzwords.mutate()

    def swap_places(self):
        """Shuffle similar components."""
        self.center.swap_places()
        self.sampler.swap_places()
        self.buzzwords.swap_places()

    def crossingover(self, other):
        """
        pre: isinstance(other, LetterPress)
        pre: isinstance(self, LetterPress)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        """
        new_one = LetterPress(self.get_trunk())
        crossing = self.crossingover_base(new_one, other, 7)
        new_one.textcolor = self.textcolor.crossingover(other.textcolor)
        new_one.center = self.center.crossingover(other.center)
        new_one.sampler = model_random.crossingover_elem(self.sampler,
                                                      other.sampler)
        new_one.buzzwords = self.buzzwords.crossingover(other.buzzwords)
        new_one.family = self.family if crossing[3] else other.family
        new_one.style = self.style if crossing[4] else other.style
        new_one.size = self.size if crossing[5] else other.size
        new_one.weight = self.weight if crossing[6] else other.weight
        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        self.begin_render(ctx, width, height)
 
        ctx.save()
#        ka_debug.matrix_s(ctx.get_matrix())
        ctx.scale(1.0/width, 1.0/height)
#        ka_debug.matrix(ctx.get_matrix())
        pango_ctx = pangocairo.CairoContext(ctx)
        points = self.sampler.get_sample_points()
        if len(points) > 0:
            fi = di = -1
            for word in self.buzzwords.wordlist:
                di = (di+1) % len(points)
                px = self.center.x_pos + points[di][0]
                py = self.center.y_pos + points[di][1]
    
                try:
                    layout = pango_ctx.create_layout()
                    fi = (fi+1) % len(self.family)
                    desc = pango.FontDescription(self.family[fi])
                    desc.set_size(int(self.size * width * 0.01 * pango.SCALE))
                    desc.set_style(self.style)
                    desc.set_weight(self.weight)
                    layout.set_text(word.encode('utf-8'))
                    layout.set_font_description(desc)
                    layout.set_alignment(pango.ALIGN_CENTER)
                    rgba = self.textcolor.rgba
                    pango_ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
                    pango_ctx.update_layout(layout)
        
                    pixel_size = layout.get_pixel_size()
                    dx, dy = 0.5 * pixel_size[0], 0.9 * pixel_size[1]
                    pango_ctx.move_to((width * px) - dx, (height * py) - dy)
                    pango_ctx.show_layout(layout)
                except:
                    ka_debug.err('failed on pango [%s] [%s]' % \
                           (sys.exc_info()[0], sys.exc_info()[1]))
                    traceback.print_exc(file=sys.__stderr__)
#        ka_debug.matrix_r(ctx.get_matrix())
        ctx.restore()

    def explain(self, formater):
        formater.begin_list(_('Layer ') + self.__class__.__name__)
        super(LetterPress, self).explain(formater)
        formater.text_list(_('buzzwords: '), self.buzzwords.wordlist)
        formater.color_item(self.textcolor, _('text color:'))
        formater.text_item(_('Font: ') + self.family
                            + ', ' + LetterPress.font_style[self.style]
                            + ', ' + str(self.size)
                            + ', ' + str(self.weight))
        formater.position_item(self.center, _('center:'))
        text, surface, descr = self.sampler.explain()
        if surface is not None:
            formater.surface_item(surface, _('sampling points: ') + text, descr)
        else:
            formater.text_item(text)
        formater.end_list()

    def copy(self):
        """The LetterPress diagram layers copy constructor.
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        """
        new_one = LetterPress(self.get_trunk())
        self.copy_base(new_one)
        new_one.textcolor = self.textcolor.copy()
        new_one.family = self.family
        new_one.style = self.style
        new_one.size = self.size
        new_one.weight = self.weight
        new_one.center = self.center.copy()
        new_one.sampler = self.sampler.copy()
        new_one.buzzwords = self.buzzwords.copy()
        return new_one
Example #27
0
class TreeNode(model_allele.Allele):
    """
    inv: (self.left_treenode is None) or isinstance(self.left_treenode, TreeNode)
    inv: (self.right_treenode is None) or isinstance(self.right_treenode, TreeNode)
    inv: self.layer is not None
    inv: self.merger is not None
    inv: self.modifier is not None
    """

    cdef = [
        {
            'bind': LAYERTYPE_CONSTRAINT,
            'name': 'Permitted layer types',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('layer').keys()
        },
        {
            'bind': NUMBER_OF_LAYERS_CONSTRAINT,
            'name': 'Number of layers',
            'domain': model_constraintpool.INT_RANGE,
            'min': 1,
            'max': 4,
        },
        {
            'bind': MERGERTYPE_CONSTRAINT,
            'name': 'Permitted merging strategies for layers',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('merger').keys()
        },
        {
            'bind': MODIFIERTYPE_CONSTRAINT,
            'name': 'Permitted merging strategies for layers',
            'domain': model_constraintpool.STRING_M_OF_N,
            'enum': ka_factory.get_factory('modifier').keys()
        },
    ]

    def __init__(self, trunk):
        super(TreeNode, self).__init__(trunk)
        self.left_treenode = None
        self.right_treenode = None
        self.left_background = exon_color.Color(self.path, 0, 0, 0, 1)
        self.right_background = exon_color.Color(self.path, 0, 0, 0, 1)
        layer_factory = ka_factory.get_factory('layer')
        self.layer = layer_factory.create(layer_factory.keys()[0], self.path)
        merger_factory = ka_factory.get_factory('merger')
        self.merger = merger_factory.create(merger_factory.keys()[0],
                                            self.path)
        modifier_factory = ka_factory.get_factory('modifier')
        self.modifier = modifier_factory.create(modifier_factory.keys()[0],
                                                self.path)

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in [
                self.left_treenode, self.right_treenode, self.layer,
                self.merger, self.modifier, self.left_background,
                self.right_background
        ]:
            if ref is not None:
                result += ka_debug.dot_ref(anchor, ref)
        return result

    @staticmethod
    def _paint_checker_board(ctx):
        """Paint a checker board background"""
        steps = 16
        delta = (1.0) / (1.0 * steps)
        ctx.set_operator(cairo.OPERATOR_SOURCE)
        for row in range(steps):
            for col in range(steps):
                ctx.rectangle(col * delta - 0.5, row * delta - 0.5, delta,
                              delta)
                if (col + row) % 2 == 0:
                    ctx.set_source_rgb(0.4, 0.4, 0.4)
                else:
                    ctx.set_source_rgb(0.6, 0.6, 0.6)
                ctx.fill()

    def __eq__(self, other):
        """Equality based on layers quantity and content."""
        equal = isinstance(other, TreeNode) \
                 and self.left_treenode == other.left_treenode \
                 and self.right_treenode == other.right_treenode \
                 and self.left_background == other.left_background \
                 and self.right_background == other.right_background \
                 and self.layer == other.layer \
                 and self.merger == other.merger \
                 and self.modifier == other.modifier
        #        if not equal and isinstance(other, TreeNode):
        #            print self.__class__
        #            print self.left_treenode == other.left_treenode
        #            print self.right_treenode == other.right_treenode
        #            print self.left_background == other.left_background
        #            print self.right_background == other.right_background
        #            print self.layer == other.layer
        #            print self.merger == other.merger
        #            print self.modifier == other.modifier
        #            print equal
        return equal

    def randomize(self):
        """Randomize the tree nodes components.
        post: self.layer is not None
        """
        cpool = model_constraintpool.ConstraintPool.get_pool()

        self.left_background.randomize()
        self.right_background.randomize()

        # create layer
        layer_factory = ka_factory.get_factory('layer')
        layertype_constraint = cpool.get(self, LAYERTYPE_CONSTRAINT)
        self.layer = layer_factory.create_random(layertype_constraint,
                                                 self.path)
        self.layer.randomize()

        # create strategy for merging 'left' and 'right' layer
        merger_factory = ka_factory.get_factory('merger')
        mergertype_constraint = cpool.get(self, MERGERTYPE_CONSTRAINT)
        self.merger = merger_factory.create_random(mergertype_constraint,
                                                   self.path)
        self.merger.randomize()

        # create strategy for modifying stacked layers
        modifier_factory = ka_factory.get_factory('modifier')
        modifiertype_constraint = cpool.get(self, MODIFIERTYPE_CONSTRAINT)
        self.modifier = modifier_factory.create_random(modifiertype_constraint,
                                                       self.path)
        self.modifier.randomize()

        number_of_constraint = cpool.get(self, NUMBER_OF_LAYERS_CONSTRAINT)
        depth = _count_slash(self.path)
        if (depth <= number_of_constraint[0] or \
           (depth > number_of_constraint[0] and random.choice([False, True]))) \
           and  depth <= number_of_constraint[1]:
            self.left_treenode = TreeNode(self.path)
            self.left_treenode.path += 'Left'
            self.left_treenode.randomize()
        if (depth <= number_of_constraint[0] or \
           (depth > number_of_constraint[0] and random.choice([False, True]))) \
           and  depth <= number_of_constraint[1]:
            self.right_treenode = TreeNode(self.path)
            self.right_treenode.path += 'Right'
            self.right_treenode.randomize()

    def mutate(self):
        """Make random changes to the tree node.
        """
        cpool = model_constraintpool.ConstraintPool.get_pool()

        # delegate mutating to the nodes child components
        if self.left_treenode is not None:
            self.left_treenode.mutate()
        if self.right_treenode is not None:
            self.right_treenode.mutate()
        # mutating my details
        self.left_background.mutate()
        self.right_background.mutate()
        if model_random.is_mutating():
            self.layer.mutate()
        if model_random.is_mutating():
            if model_random.is_mutating():
                merger_factory = ka_factory.get_factory('merger')
                mergertype_constraint = cpool.get(self, MERGERTYPE_CONSTRAINT)
                self.merger = merger_factory.create_random(
                    mergertype_constraint, self.path)
            self.merger.randomize()
        if model_random.is_mutating():
            if model_random.is_mutating():
                modifier_factory = ka_factory.get_factory('modifier')
                modifiertype_constraint = cpool.get(self,
                                                    MODIFIERTYPE_CONSTRAINT)
                self.modifier = modifier_factory.create_random(
                    modifiertype_constraint, self.path)
            self.modifier.randomize()

    def swap_places(self):
        """Swap 'left' and 'right' tree node delegate swapping to the nodes components."""
        # shuffle tree node
        self.left_treenode, self.right_treenode = \
                          model_random.swap_parameters(self.left_treenode,
                                                       self.right_treenode)
        self.left_background, self.right_background = \
                          model_random.swap_parameters(self.left_background,
                                                       self.right_background)
        # delegate swapping to the nodes child components
        if self.left_treenode is not None:
            self.left_treenode.swap_places()
        if self.right_treenode is not None:
            self.right_treenode.swap_places()
        self.layer.swap_places()
        self.merger.swap_places()
        self.modifier.swap_places()

    def crossingover(self, other):
        """Returns a deep copy mixed from my tree node and the other tree node.
        pre: isinstance(other, TreeNode)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        post: __return__.layer is not None
        """
        # deep copy
        new_one = TreeNode(self.get_trunk())
        # crossing over the layers
        new_one.left_treenode = other.left_treenode \
                                    if model_random.is_crossing() \
                                    else self.left_treenode
        if new_one.left_treenode is not None:
            new_one.left_treenode = new_one.left_treenode.copy()
        new_one.right_treenode = other.right_treenode \
                                    if model_random.is_crossing() \
                                    else self.right_treenode
        if new_one.right_treenode is not None:
            new_one.right_treenode = new_one.right_treenode.copy()
        new_one.left_background = self.left_background.crossingover(
            other.left_background)
        new_one.right_background = self.right_background.crossingover(
            other.right_background)
        new_one.layer = other.layer.copy() \
                                    if model_random.is_crossing() \
                                    else self.layer.copy()
        new_one.merger = other.merger.copy() \
                                    if model_random.is_crossing() \
                                    else self.merger.copy()
        new_one.modifier = other.modifier.copy() \
                                    if model_random.is_crossing() \
                                    else self.modifier.copy()
        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        if task.quit:
            #            ka_debug.info('quitting task: [%s], %s' % \
            #                   (task.work_for, self.path))
            return
#!!        time.sleep(0.001)
        try:
            ctx.save()
            #            ka_debug.matrix_s(ctx.get_matrix())
            if (self.left_treenode is None) and (self.right_treenode is None):
                # I am a leaf, use my own layer painting strategy
                self.layer.render(task, ctx, width, height)
            elif (self.left_treenode is not None) and (self.right_treenode
                                                       is not None):
                # merge 'left' and 'right' tree node
                left_surface, left_ctx = self._prepare_surface(ctx, width, height, \
                                                               self.left_background)
                self.left_treenode.render(task, left_ctx, width, height)
                #            left_surface.write_to_png('/dev/shm/left_' + self.left_treenode.get_unique_id() + '.png')
                right_surface, right_ctx = self._prepare_surface(ctx, width, height, \
                                                                 self.right_background)
                right_ctx.set_operator(cairo.OPERATOR_SOURCE)
                self.right_treenode.render(task, right_ctx, width, height)
                #            right_surface.write_to_png('/dev/shm/right_' + self.right_treenode.get_unique_id() + '.png')

                if not task.quit:
                    self.merger.merge_layers(left_surface, right_surface, \
                                             ctx, width, height)
            elif (self.left_treenode
                  is not None) and (self.right_treenode is None):
                self.modifier.render_single_layer(task, self.layer,
                                                  self.left_treenode, ctx,
                                                  width, height)
            elif (self.left_treenode is None) and (self.right_treenode
                                                   is not None):
                self.modifier.render_single_layer(task, self.layer,
                                                  self.right_treenode, ctx,
                                                  width, height)
#            ka_debug.matrix_r(ctx.get_matrix())
            ctx.restore()
        except:
            ka_debug.err('failed calculating [%s] [%s] [%s]' % \
                   (self.get_unique_id(), sys.exc_info()[0], sys.exc_info()[1]))
            traceback.print_exc(file=sys.__stderr__)
#            ka_debug.matrix(ctx.get_matrix())

    def _prepare_surface(self, ctx, width, height, background):
        new_surface = ctx.get_target().create_similar(
            cairo.CONTENT_COLOR_ALPHA, width, height)
        new_ctx = cairo.Context(new_surface)
        new_ctx.scale(float(width), float(height))
        #        ka_debug.matrix(new_ctx.get_matrix())
        new_ctx.translate(0.5, 0.5)
        #        ka_debug.matrix(new_ctx.get_matrix())
        new_ctx.set_operator(cairo.OPERATOR_SOURCE)
        rgba = background.rgba
        new_ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
        new_ctx.paint()
        return new_surface, new_ctx

    def explain(self, task, formater):
        """Explain all layers, modifier and mergers."""

        width = height = 256

        # explain layers for current node and its child nodes
        leaf = (self.left_treenode is None) and (self.right_treenode is None)
        # preview
        #ex        title = 'Leaf ' if leaf  else 'Combined layers of subtree'
        #ex        formater.begin_list(title)
        # preview this node
        self._preview(task, self, formater, width, height)

        # explain details
        if leaf:
            # explain the leafs layer
            self.layer.explain(formater)
        elif (self.left_treenode is not None) and (self.right_treenode
                                                   is not None):
            formater.begin_list(_('Details for merging node ') + self.path)
            # explain how layers are combined
            formater.color_item(self.left_background,
                                _('left background color:'),
                                alpha=True)
            self.merger.explain_left(formater)
            self.left_treenode.explain(task, formater)
            formater.color_item(self.right_background,
                                _('right background color:'),
                                alpha=True)
            self.merger.explain_right(formater)
            self.right_treenode.explain(task, formater)
            formater.end_list()
        else:
            formater.begin_list(_('Details for modifying node ') + self.path)
            # preview this node
            self._preview(task, self.layer, formater, width, height)
            if self.left_treenode is not None:
                self.modifier.explain(task, formater, self.layer,
                                      self.left_treenode)
            if self.right_treenode is not None:
                self.modifier.explain(task, formater, self.layer,
                                      self.right_treenode)
            formater.end_list()


#ex        formater.end_list()

    def _preview(self, task, source, formater, width, height):
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
        ctx = cairo.Context(surface)
        ctx.scale(float(width), float(height))
        #        ka_debug.matrix(ctx.get_matrix())
        ctx.translate(0.5, 0.5)
        #        ka_debug.matrix(ctx.get_matrix())
        TreeNode._paint_checker_board(ctx)
        ctx.save()
        #        ka_debug.matrix_s(ctx.get_matrix())
        source.render(task, ctx, width, height)
        formater.surface_item(surface, 'Tree node ' + self.path, self.path)
        #        ka_debug.matrix_r(ctx.get_matrix())
        ctx.restore()

    def copy(self):
        """ The tree nodes copy constructor.
        post: __return__.layer is not None
        """
        new_one = TreeNode(self.get_trunk())
        new_one.path = self.path[:]
        new_one.left_treenode = self.left_treenode.copy() \
                                if self.left_treenode is not None \
                                else None
        new_one.right_treenode = self.right_treenode.copy() \
                                 if self.right_treenode is not None \
                                 else None
        new_one.layer = self.layer.copy()
        new_one.merger = self.merger.copy()
        new_one.modifier = self.modifier.copy()
        new_one.left_background = self.left_background.copy()
        new_one.right_background = self.right_background.copy()
        return new_one
class LcaLayer(model_layer.Layer):
    """LcaLayer
    inv: len(self.cell_colors) > 0
    inv: self.size >= 1
    inv: self.states >= 1
    inv: self.left_neighbors >= 0
    inv: self.right_neighbors >= 0
    """

    cdef = [{'bind'  : SIZE_CONSTRAINT,
             'name'  : 'Number of cells.',
             'domain': model_constraintpool.INT_RANGE,
             'min'   : 2, 'max': 32},
            {'bind'  : STATES_CONSTRAINT,
             'name'  : 'Number of states.',
             'domain': model_constraintpool.INT_RANGE,
             'min'   : 2, 'max': 6},
            {'bind'  : LEFT_NEIGHBORS_CONSTRAINT,
             'name'  : 'Number of left neighbors.',
             'domain': model_constraintpool.INT_RANGE,
             'min'   : 0, 'max': 2},
            {'bind'  : RIGHT_NEIGHBORS_CONSTRAINT,
             'name'  : 'Number of right neighbors.',
             'domain': model_constraintpool.INT_RANGE,
             'min'   : 0, 'max': 2},
            {'bind'  : COLORGAMUTTYPE_CONSTRAINT,
             'name'  : 'Permitted color gamut',
             'domain': model_constraintpool.STRING_M_OF_N,
             'enum'  : ka_factory.get_factory('colorgamut').keys()},
           ]

    def __init__(self, trunk):
        """linear cellular automata layer constructor
        post: len(self.cell_colors) == self.states
        """
        super(LcaLayer, self).__init__(trunk)
        self.size = 2
        self.states = 2
        self.left_neighbors = 1
        self.right_neighbors = 1
        rsize = self.states ** (self.left_neighbors + 1 + self.right_neighbors)
        self.rules = [0 for dummy in xrange(rsize)]
        self.sequence_ordering = 0.25

        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamut_key = colorgamut_factory.keys()[0]
        self.colorgamut = colorgamut_factory.create(colorgamut_key, self.path)
        self.cell_colors = [self.colorgamut.get_randomized_color(self.path),
                            self.colorgamut.get_randomized_color(self.path), ]

    def dot(self):
        result = ""
        anchor = ka_debug.dot_id(self) + ' -> '
        for ref in [self.colorgamut, ]:
            result += ka_debug.dot_ref(anchor, ref)
        for ref in self.cell_colors:
            result += ka_debug.dot_ref(anchor, ref)
        return result
    
    def __eq__(self, other):
        """Equality """
        equal = isinstance(other, LcaLayer) \
                and model_layer.Layer.__eq__(self, other) \
                and self.size == other.size \
                and self.states == other.states \
                and self.left_neighbors == other.left_neighbors \
                and self.right_neighbors == other.right_neighbors \
                and self.sequence_ordering == other.sequence_ordering \
                and len(self.cell_colors) == len(other.cell_colors)
        if equal:
            for index, rule in enumerate(self.rules):
                equal = equal and rule == other.rules[index]
        if equal:
            for index, site_color in enumerate(self.cell_colors):
                equal = equal and site_color == other.cell_colors[index]
        return equal

    def randomize(self):
        """Randomize the layers components.
        post: len(self.cell_colors) == self.states
        post: forall(self.rules, lambda f: 0 <= f < self.states)
        """
        super(LcaLayer, self).randomize()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        size_constraint = cpool.get(self, SIZE_CONSTRAINT)
        self.size = model_random.randint_constrained(size_constraint)
        
        states_constraint = cpool.get(self, STATES_CONSTRAINT)
        self.states = model_random.randint_constrained(states_constraint)
        
        left_neighbors_constraint = cpool.get(self, LEFT_NEIGHBORS_CONSTRAINT)
        self.left_neighbors = model_random.randint_constrained(left_neighbors_constraint)
        right_neighbors_constraint = cpool.get(self, RIGHT_NEIGHBORS_CONSTRAINT)
        self.right_neighbors = model_random.randint_constrained(right_neighbors_constraint)
        
        self.rules = [random.randrange(0, self.states) \
                                for dummy in xrange(self.get_numberof_rules())]
        self.sequence_ordering = random.uniform(0.0, 1.0)
        
        colorgamut_factory = ka_factory.get_factory('colorgamut')
        colorgamuttype_constraint = cpool.get(self, COLORGAMUTTYPE_CONSTRAINT)
        self.colorgamut = colorgamut_factory.create_random(colorgamuttype_constraint, 
                                                           self.path)
        self.colorgamut.randomize()

        self.cell_colors = []
        for dummy in range(self.states):
            site_color = self.colorgamut.get_randomized_color(self.path)
            self.cell_colors.append(site_color)

    def fill_sequence(self, lca_state):
        """
        post: forall(lca_state, lambda f: 0 <= f < self.states)
        """
        seq_random = random.Random()
        seq_random.seed(self.random_seed)
        state = lca_state[0] = seq_random.randrange(0, self.states)
        for index in xrange(1, len(lca_state)):
            if seq_random.uniform(0.0, 1.0) < self.sequence_ordering:
                state = seq_random.randrange(0, self.states)
            lca_state[index] = state


    def patch_rulesize(self):
        rsize = self.get_numberof_rules()
        if len(self.rules) > rsize:
            self.rules = self.rules[:rsize]
        while len(self.rules) < rsize:
            self.rules.append(random.randrange(0, self.states))
        
        self.rules = [x % self.states for x in self.rules]


    def patch_colorsize(self):
        if len(self.cell_colors) > self.states:
            self.cell_colors = self.cell_colors[:self.states]
        while len(self.cell_colors) < self.states:
            site_color = self.colorgamut.get_randomized_color(self.path)
            self.cell_colors.append(site_color)

    def mutate(self):
        """Make small random changes to the layers components.
        post: len(self.cell_colors) == self.states
        post: forall(self.rules, lambda f: 0 <= f < self.states)
        """
        super(LcaLayer, self).mutate()
        cpool = model_constraintpool.ConstraintPool.get_pool()
        size_constraint = cpool.get(self, SIZE_CONSTRAINT)
        self.size = model_random.jitter_discret_constrained(
                                                  self.size, size_constraint)
        states_constraint = cpool.get(self, STATES_CONSTRAINT)
        self.states = model_random.jitter_discret_constrained(
                                                  self.states, states_constraint)

        left_neighbors_constraint = cpool.get(self, LEFT_NEIGHBORS_CONSTRAINT)
        self.left_neighbors = model_random.randint_constrained(left_neighbors_constraint)
        self.left_neighbors = model_random.jitter_discret_constrained(
                                 self.left_neighbors, left_neighbors_constraint)
        right_neighbors_constraint = cpool.get(self, RIGHT_NEIGHBORS_CONSTRAINT)
        self.right_neighbors = model_random.jitter_discret_constrained(
                               self.right_neighbors, right_neighbors_constraint)
        self.patch_rulesize()

        self.patch_colorsize()
        self.colorgamut.mutate()
        for cix in range(len(self.cell_colors)):
            self.colorgamut.adjust_color(self.cell_colors[cix])

    def swap_places(self):
        """Shuffle similar components."""
        model_random.swap_places(self.cell_colors)
        model_random.swap_places(self.rules)

    def crossingover(self, other):
        """
        pre: isinstance(other, LcaLayer)
        pre: isinstance(self, LcaLayer)
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        post: __return__ is not other
        post: model_locus.unique_check(__return__, self, other) == ''
        post: len(__return__.cell_colors) == __return__.states
        post: len(__return__.rules) == __return__.get_numberof_rules()
        post: forall(__return__.rules, lambda f: 0 <= f < __return__.states)
        """
        new_one = LcaLayer(self.get_trunk())
        cross_sequence = self.crossingover_base(new_one, other, 6)
        new_one.size = self.size if cross_sequence[0] \
                                 else other.size
        new_one.states = self.states if cross_sequence[1] \
                                     else other.states
        #TODO rules an die geänderten states anpassen.
        
        new_one.left_neighbors = self.left_neighbors if cross_sequence[2] \
                                                     else other.left_neighbors
        new_one.right_neighbors = self.right_neighbors if cross_sequence[3] \
                                                       else other.right_neighbors
        new_one.colorgamut = other.colorgamut.copy() if cross_sequence[4] \
                                                     else self.colorgamut.copy() 
        new_one.sequence_ordering = self.sequence_ordering if cross_sequence[5] \
                                                           else other.sequence_ordering

        new_one.rules = model_random.crossingover_nativeelement_list(self.rules, \
                                                                     other.rules)
        new_one.patch_rulesize()

        new_one.cell_colors = model_random.crossingover_list(self.cell_colors,
                                                             other.cell_colors)
        new_one.patch_colorsize()
        for cix in range(len(new_one.cell_colors)):
            new_one.colorgamut.adjust_color(new_one.cell_colors[cix])

        return new_one

    def render(self, task, ctx, width, height):
        """
        pre: ctx is not None
        pre: width > 0
        pre: height > 0
        pre: width == height
        """
        self.begin_render(ctx, width, height)
        lca_state = [0 for dummy in xrange(self.size)]
        lca_nextstate = [0 for dummy in xrange(self.size)]
        self.fill_sequence(lca_state)
        delta = 1.0 / self.size
        next_state = 0
        x_pos = -0.5
        for dummy in xrange(self.size):
            y_pos = -0.5
            for col in xrange(self.size):
                ruleNumber = self.get_rule_index(lca_state, col)
                next_state = lca_nextstate[col] = self.rules[ruleNumber]
                rgba = self.cell_colors[next_state % len(self.cell_colors)].rgba
                ctx.set_source_rgba(rgba[0], rgba[1], rgba[2], rgba[3])
                ctx.rectangle(x_pos, y_pos, delta, delta)
                ctx.fill()
                y_pos += delta
            x_pos += delta
            # copy temporary cell array to actual cell array
            lca_state = lca_nextstate[:]

    def get_numberof_rules(self):
        """
        post: __return__ >= 1
        """
        return self.states ** (self.left_neighbors + 1 + self.right_neighbors)
  
    def get_rule_index(self, lca_state, index):
        """
        pre: len(lca_state) == self.size
        pre: 0 <= index < self.size
        post: 0 <= __return__ < len(self.rules)
        """
        ruleNumber = 0
        for nx in xrange(index - self.left_neighbors,
                         index + self.right_neighbors + 1):
            ruleNumber *= self.states
            ruleNumber += lca_state[nx % len(lca_state)]
        return ruleNumber

    def explain(self, formater):
        formater.begin_list(_('Layer ') + self.__class__.__name__)
        super(LcaLayer, self).explain(formater)
        formater.text_item(_('Number of states: ') + str(self.states))
        formater.text_item(_('Number of left neighbors: ') + str(self.left_neighbors))
        formater.text_item(_('Number of right neighbors: ') + str(self.right_neighbors))
        formater.text_item(_('Number of cells: ') + str(self.size))
        formater.text_item(_('Stability of sequence ordering: ') + str(self.size))
        self.colorgamut.explain(formater)
        formater.color_array(self.cell_colors, _('Cell colors:'))
        formater.end_list()

    def copy(self):
        """The linear cellular automata layers copy constructor.
        # check for distinct references, needs to copy content, not references
        post: __return__ is not self
        pre: len(self.cell_colors) == self.states
        post: len(__return__.cell_colors) == __return__.states
        """
        new_one = LcaLayer(self.get_trunk())
        self.copy_base(new_one)
        new_one.cell_colors = model_random.copy_list(self.cell_colors)
        new_one.states = self.states
        new_one.rules = self.rules[:]
        new_one.size = self.size
        new_one.left_neighbors = self.left_neighbors
        new_one.right_neighbors = self.right_neighbors
        new_one.sequence_ordering = self.sequence_ordering
        new_one.colorgamut = self.colorgamut.copy()
        return new_one