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 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 __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 __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 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
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 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)
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 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 __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 __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)
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 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 __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()
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 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
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
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
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
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
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
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