def __init__(self, vehicle, title_font="fonts/Railway To Hells.ttf", subtitle_font="fonts/Road_Rage.ttf", text_font="fonts/AGENCYB.TTF", title_colour='magenta', subtitle_colour='darkred', text_colour='black') -> None: self.vehicle = vehicle pdfmetrics.registerFont(TTFont('subtitle', subtitle_font)) pdfmetrics.registerFont(TTFont('title', title_font)) pdfmetrics.registerFont(TTFont('text', text_font)) try: self.title_colour = colors.getAllNamedColors()[title_colour] except KeyError: self.title_colour = colors.black try: self.subtitle_colour = colors.getAllNamedColors()[subtitle_colour] except KeyError: self.subtitle_colour = colors.black try: self.text_colour = colors.getAllNamedColors()[text_colour] except KeyError: self.text_colour = colors.black self.canvas = canvas.Canvas(self.vehicle.name + ".pdf", pagesize=landscape(A5)) w = self.canvas._pagesize[0] h = self.canvas._pagesize[1] self.canvas.setFillColor(self.text_colour) self.canvas.rect(0, 0, w, h) self.canvas.setFillColor(self.title_colour) self.canvas.rect(10, 10, w - 20, h - 20)
def printableColors(): allColors = colors.getAllNamedColors() colorsForCategories = colors.getAllNamedColors().values() for k in allColors.keys(): for unwantedName in ['white', 'yellow', 'CMYK', 'black', 'transparent']: if k.find(unwantedName) > -1: print "removing %s" % k if allColors[k] in colorsForCategories: colorsForCategories.remove(allColors[k]) return colorsForCategories
def _render(self, drawing): gap = 5 legend = legends.Legend() legend.alignment = 'right' legend.x = gap legend.y = self.height - 3 * gap legend.deltay = 5 legend.dxTextSpace = 5 legend.fontSize = 14 legend.columnMaximum = len(colors.getAllNamedColors().keys()) legend.colorNamePairs = zip(colors.getAllNamedColors().values(), colors.getAllNamedColors().keys()) drawing.add(legend, 'legend')
def test1(self): "Test colorDistance function." cols = colors.getAllNamedColors().values() for col in cols: d = colors.colorDistance(col, col) assert d == 0
def motifGenomeDiagram(pckname, filetype = ['finalExpression', 'annotation', 'TFset']): from reportlab.lib import colors from reportlab.lib.units import cm from Bio.Graphics import GenomeDiagram from Bio import SeqIO from Bio.SeqFeature import SeqFeature, FeatureLocation wt = readData(pckname, filetype[0]) d = readData(pckname, filetype[1]) d['strand'] = [-1 if i==0 else 1 for i in d.strand] tfset = readData(pckname, filetype[2]) cols = list(colors.getAllNamedColors().keys()) cols = [col for col in cols if 'pale' not in col and 'light' not in col and 'white' not in col and 'snow' not in col and 'ivory' not in col] cols = np.random.choice(cols, len(tfset.tf_name.unique())) gdd = GenomeDiagram.Diagram(pckname) for gene in d.gene.unique(): this_gene = d[:][d.gene == gene] gdt_features = gdd.new_track(len(d.gene.unique()) - gene, greytrack=False) gds_features = gdt_features.new_set() for motif in this_gene.axes[0]: if(this_gene.strand[motif] == 1): angle = 0 else: angle = 180 mot_size = len(tfset.consensus[tfset.tf_name == this_gene.tf_ind[motif]][0]) feature = SeqFeature(FeatureLocation(int(this_gene.positions[motif]), int(this_gene.positions[motif] + mot_size - 1)), strand=this_gene.strand[motif]) gds_features.add_feature(feature, name=str(this_gene.tf_ind[motif]), label=True, label_position="start", label_size = 6, label_angle=angle, color = cols[this_gene.tf_ind[motif]], sigil="BIGARROW", arrowshaft_height=this_gene.percent[motif], arrowhead_length=1) gdd.draw(format='linear', pagesize=(15*cm, 10*cm), fragments=1,start=0, end=len(wt.seqs[0]), orientation = 'portrait', tracklines = 0) gdd.write(pckname +"_motifs.pdf", "pdf")
def get_color(col): if isinstance(col, str): return colors.getAllNamedColors().get(col) elif isinstance(col, list): return colors.Color(*[x / 255.0 for x in col]) else: raise Exception("Unknown color defintion type")
def printColors(canvas): canvas.setFont("Helvetica",10) y = x = 0; dy=inch*1/2.0; dx=1*inch; w=h=dy/2 rdx=(dx-w)/2; rdy=h/5.0 available_paper = 10*inch for name, color in colors.getAllNamedColors().iteritems(): # for [namedcolor, name] in ( # 'darkseagreen', 'darkslateblue', # [colors.darkblue, 'darkblue'], # [colors.darkcyan, 'darkcyan'], # [colors.darkolivegreen, 'darkolivegreen'], # [colors.cornflower, 'cornflower'], # [colors.orchid, 'orchid'], # [colors.lavenderblush, "lavenderblush"], # [colors.lawngreen, "lawngreen"], # [colors.lemonchiffon, "lemonchiffon"], # [colors.lightblue, "lightblue"], # [colors.lightcoral, "lightcoral"]): canvas.setFillColor(color) canvas.rect(x+rdx, y+rdy, w, h, fill=1) canvas.setFillColor(colors.black) canvas.drawString(x+dx/4 + 1*inch, y+rdy, name) rdy += .2*inch available_paper -= (y+rdy) if available_paper < 1*inch: c.showPage() y = x = 0; dy=inch*1/2.0; dx=1*inch; w=h=dy/2 rdx=(dx-w)/2; rdy=h/5.0 available_paper = 10*inch
def test1(self): "Test colorDistance function." cols = list(colors.getAllNamedColors().values()) for col in cols: d = colors.colorDistance(col, col) assert d == 0
def test0(self): "Test color2bw function on all named colors." cols = colors.getAllNamedColors().values() for col in cols: gray = colors.color2bw(col) r, g, b = gray.red, gray.green, gray.blue assert r == g == b
def draw(self): """Actually draws the filled or outlined path on the canvas. """ if self.fill_color: self.canvas.setFillColor(getAllNamedColors()[self.fill_color]) self.canvas.drawPath(self.p, fill=True, stroke=False) else: self.canvas.drawPath(self.p, fill=False, stroke=True)
def test0(self): "Test color2bw function on all named colors." cols = list(colors.getAllNamedColors().values()) for col in cols: gray = colors.color2bw(col) r, g, b = gray.red, gray.green, gray.blue assert r == g == b
def get(col_str): allcols = colors.getAllNamedColors() regex_t = re.compile('\(([0-9\.]*),([0-9\.]*),([0-9\.]*)\)') regex_h = re.compile('#([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])') if col_str in allcols.keys(): return allcols[col_str] res = regex_t.search(col_str, 0) if res: return (float(res.group(1)),float(res.group(2)),float(res.group(3))) res = regex_h.search(col_str, 0) if res: return tuple([ float(int(res.group(i),16))/255 for i in range(1,4)]) return colors.red
def get(col_str): if col_str == None: col_str = '' global allcols if allcols is None: allcols = colors.getAllNamedColors() if col_str in allcols.keys(): return allcols[col_str] res = regex_t.search(col_str, 0) if res: return (float(res.group(1)), float(res.group(2)), float(res.group(3))) res = regex_h.search(col_str, 0) if res: return tuple([float(int(res.group(i), 16)) / 255 for i in range(1, 4)]) return colors.red
def get_available_colors(self): """Returns a list of available colors""" # Get reportlab available colors colors = getAllNamedColors() # Remove bad colors colors.pop('white', None) colors.pop('black', None) # Returns only the colors values (without their names) colors = colors.values() # Shuffle colors list random.shuffle(colors) return colors
class PackProfile: colors = getAllNamedColors() def __init__(self, name, color): self.name = name self.color = color if isinstance(color, str): if color == '': self.color = None elif color.startswith('#'): try: self.color = HexColor(color) except ValueError: raise Exception("Not a valid hex color: " + color) else: if color in PackProfile.colors: self.color = PackProfile.colors[color] else: raise Exception("Not a color: " + color) elif not isinstance(color, Color): raise TypeError("Invalid color parameter: ", type(color)) @staticmethod def available_colors(contains=''): return sorted(color for color in PackProfile.colors.keys() if contains in color) @staticmethod def load(filename): config = ConfigParser() config.read(filename) if "PROFILE" in config: profile = config["PROFILE"] return PackProfile(profile.get("name", ''), profile.get("color", None)) else: return None @staticmethod def write_sample(filename): config = ConfigParser() config["PROFILE"] = {"name": "Sample Pack", "color": "crimson"} with open(filename, mode='w') as file: config.write(file)
def test4(self): "Construct CMYK instances and test round trip conversion" rgbCols = colors.getAllNamedColors().items() # Make a roundtrip test (RGB > CMYK > RGB). for name, rgbCol in rgbCols: r1, g1, b1 = rgbCol.red, rgbCol.green, rgbCol.blue c, m, y, k = colors.rgb2cmyk(r1, g1, b1) cmykCol = colors.CMYKColor(c,m,y,k) r2, g2, b2 = cmykCol.red, cmykCol.green, cmykCol.blue #colors.cmyk2rgb((c, m, y, k)) rgbCol2 = colors.Color(r2, g2, b2) # Make sure the differences for each RGB component # isreally small (< power(10, -N)! N = 16 # max. value found to work on Python2.0 and Win2K. deltas = map(abs, (r1-r2, g1-g2, b1-b2)) assert deltas < [math.pow(10, -N)] * 3
def test4(self): "Construct CMYK instances and test round trip conversion" rgbCols = list(colors.getAllNamedColors().items()) # Make a roundtrip test (RGB > CMYK > RGB). for name, rgbCol in rgbCols: r1, g1, b1 = rgbCol.red, rgbCol.green, rgbCol.blue c, m, y, k = colors.rgb2cmyk(r1, g1, b1) cmykCol = colors.CMYKColor(c, m, y, k) r2, g2, b2 = cmykCol.red, cmykCol.green, cmykCol.blue #colors.cmyk2rgb((c, m, y, k)) rgbCol2 = colors.Color(r2, g2, b2) # Make sure the differences for each RGB component # isreally small (< power(10, -N)! N = 16 # max. value found to work on Python2.0 and Win2K. deltas = list(map(abs, (r1 - r2, g1 - g2, b1 - b2))) assert deltas < [math.pow(10, -N)] * 3
def get(col_str): """ parse a string and return a tuple """ all_colors = colors.getAllNamedColors() if col_str in all_colors.keys(): return all_colors[col_str] res = RGB_REGEX.search(col_str, 0) if res: return (float(res.group(1)), float(res.group(2)), float(res.group(3))) res = HEX_REGEX.search(col_str, 0) if res: return tuple([float(int(res.group(i), 16)) / 255 for i in range(1, 4)]) return colors.red
def test3(self): "Test roundtrip RGB to CMYK conversion." # Take all colors as test subjects, except 'transparent'. ## rgbCols = colors.getAllNamedColors() ## del rgbCols['transparent'] rgbCols = colors.getAllNamedColors().items() # Make a roundtrip test (RGB > CMYK > RGB). for name, rgbCol in rgbCols: r1, g1, b1 = rgbCol.red, rgbCol.green, rgbCol.blue c, m, y, k = colors.rgb2cmyk(r1, g1, b1) r2, g2, b2 = colors.cmyk2rgb((c, m, y, k)) rgbCol2 = colors.Color(r2, g2, b2) # Make sure the differences for each RGB component # isreally small (< power(10, -N)! N = 16 # max. value found to work on Python2.0 and Win2K. deltas = map(abs, (r1-r2, g1-g2, b1-b2)) assert deltas < [math.pow(10, -N)] * 3
def dibujarPartes(): """Dibujar nodos y arcos.""" for linea in ArrLineas: linea.strokeColor = Color(0,0.51,0.84) linea.strokeWidth = 2 d.add(linea) for nodo in ArrNodos: # nodo.circulo.setFill('blue') # nodo.circulo.setOutline('cyan') nodo.circulo.fillColor = Color(0,0.51,0.84) nodo.circulo.strokeColor = Color(0,0.51,0.84) # nodo.circulo.strokeWidth = 5 d.add(nodo.circulo) tex = String(nodo.centro.x,nodo.centro.y,str(nodo.numero)) tex.textAnchor = 'middle' tex.fontSize = 18 tex.fillColor = getAllNamedColors()['white'] d.add(tex)
def test3(self): "Test roundtrip RGB to CMYK conversion." # Take all colors as test subjects, except 'transparent'. ## rgbCols = colors.getAllNamedColors() ## del rgbCols['transparent'] rgbCols = list(colors.getAllNamedColors().items()) # Make a roundtrip test (RGB > CMYK > RGB). for name, rgbCol in rgbCols: r1, g1, b1 = rgbCol.red, rgbCol.green, rgbCol.blue c, m, y, k = colors.rgb2cmyk(r1, g1, b1) r2, g2, b2 = colors.cmyk2rgb((c, m, y, k)) rgbCol2 = colors.Color(r2, g2, b2) # Make sure the differences for each RGB component # isreally small (< power(10, -N)! N = 16 # max. value found to work on Python2.0 and Win2K. deltas = list(map(abs, (r1 - r2, g1 - g2, b1 - b2))) assert deltas < [math.pow(10, -N)] * 3
def _toColor(arg, default=None): '''try to map an arbitrary arg to a color instance''' if isinstance(arg, Color): return arg tArg = type(arg) if tArg in (types.ListType, types.TupleType): assert 3 <= len(arg) <= 4, 'Can only convert 3 and 4 sequences to color' assert 0 <= min(arg) and max(arg) <= 1 return len(arg) == 3 and Color(arg[0], arg[1], arg[2]) or CMYKColor(arg[0], arg[1], arg[2], arg[3]) elif tArg == types.StringType: C = getAllNamedColors() s = arg.lower() if C.has_key(s): return C[s] try: return toColor(eval(arg)) except: pass try: return HexColor(arg) except: if default is None: raise ValueError('Invalid color value %r' % arg) return default
def _render_rm_file(rm_file_name, image_width=DEFAULT_IMAGE_WIDTH, image_height=DEFAULT_IMAGE_HEIGHT, crop_box=None): """ Render the .rm files (old .lines). See also https://plasma.ninja/blog/devices/remarkable/binary/format/2017/12/26/reMarkable-lines-file-format.html """ rm_file = "%s.rm" % rm_file_name rm_file_metadata = "%s-metadata.json" % rm_file_name is_landscape = image_width > image_height if is_landscape: image_height, image_width = image_width, image_height crop_box = [0.0, 0.0, image_width, image_height ] if crop_box is None else crop_box # Calculate the image height and width that we use for the overlay if is_landscape: image_width = float(crop_box[2]) - float(crop_box[0]) image_height = max( image_height, image_width * DEFAULT_IMAGE_HEIGHT / DEFAULT_IMAGE_WIDTH) ratio = (image_height) / (DEFAULT_IMAGE_HEIGHT) else: image_height = float(crop_box[3]) - float(crop_box[1]) image_width = max( image_width, image_height * DEFAULT_IMAGE_WIDTH / DEFAULT_IMAGE_HEIGHT) ratio = (image_width) / (DEFAULT_IMAGE_WIDTH) # Is this a reMarkable .lines file? with open(rm_file, 'rb') as f: data = f.read() offset = 0 expected_header_v3 = b'reMarkable .lines file, version=3 ' expected_header_v5 = b'reMarkable .lines file, version=5 ' if len(data) < len(expected_header_v5) + 4: abort('File too short to be a valid file') fmt = '<{}sI'.format(len(expected_header_v5)) header, nlayers = struct.unpack_from(fmt, data, offset) offset += struct.calcsize(fmt) is_v3 = (header == expected_header_v3) is_v5 = (header == expected_header_v5) if (not is_v3 and not is_v5) or nlayers < 1: abort('Not a valid reMarkable file: <header={}><nlayers={}>'.format( header, nlayers)) return # Load name of layers; if layer name starts with # we use this color # for this layer layer_colors = [None for l in range(nlayers)] if os.path.exists(rm_file_metadata): with open(rm_file_metadata, "r") as meta_file: layers = json.loads(meta_file.read())["layers"] for l in range(len(layers)): layer = layers[l] matches = re.search(r"#([^\s]+)", layer["name"], re.M | re.I) if not matches: continue color_code = matches[0].lower() # Try to parse hex code try: has_alpha = len(color_code) > 7 layer_colors[l] = colors.HexColor(color_code, hasAlpha=has_alpha) continue except: pass # Try to get from name color_code = color_code[1:] color_names = colors.getAllNamedColors() if color_code in color_names: layer_colors[l] = color_names[color_code] # No valid color found... automatic fallback to default # Iterate through layers on the page (There is at least one) packet = io.BytesIO() can = canvas.Canvas(packet, pagesize=(image_width, image_height)) for layer in range(nlayers): fmt = '<I' (nstrokes, ) = struct.unpack_from(fmt, data, offset) offset += struct.calcsize(fmt) # Iterate through the strokes in the layer (If there is any) for stroke in range(nstrokes): if is_v3: fmt = '<IIIfI' pen, color, i_unk, pen_width, nsegments = struct.unpack_from( fmt, data, offset) offset += struct.calcsize(fmt) if is_v5: fmt = '<IIIffI' pen, color, i_unk, pen_width, unknown, nsegments = struct.unpack_from( fmt, data, offset) offset += struct.calcsize(fmt) opacity = 1 last_x = -1. last_y = -1. # Check which tool is used for both, v3 and v5 and set props # https://support.remarkable.com/hc/en-us/articles/115004558545-5-1-Tools-Overview is_highlighter = (pen == 5 or pen == 18) is_eraser = pen == 6 is_eraser_area = pen == 8 is_sharp_pencil = (pen == 7 or pen == 13) is_tilt_pencil = (pen == 1 or pen == 14) is_marker = (pen == 3 or pen == 16) is_ballpoint = (pen == 2 or pen == 15) is_fineliner = (pen == 4 or pen == 17) is_brush = (pen == 0 or pen == 12) if is_sharp_pencil or is_tilt_pencil: color = 4 if is_brush: pass elif is_ballpoint or is_fineliner: pen_width = 32 * pen_width * pen_width - 116 * pen_width + 107 elif is_marker: pen_width = 64 * pen_width - 112 opacity = 0.9 elif is_highlighter: pen_width = 30 opacity = 0.2 color = 3 elif is_eraser: pen_width = 1280 * pen_width * pen_width - 4800 * pen_width + 4510 color = 2 elif is_sharp_pencil or is_tilt_pencil: pen_width = 16 * pen_width - 27 opacity = 0.9 elif is_eraser_area: opacity = 0. else: print('Unknown pen: {}'.format(pen)) opacity = 0. # Iterate through the segments to form a polyline points = [] width = [] for segment in range(nsegments): fmt = '<ffffff' xpos, ypos, i_unk2, pressure, tilt, _ = struct.unpack_from( fmt, data, offset) offset += struct.calcsize(fmt) if is_ballpoint or is_brush: width.append((6 * pen_width + 2 * pressure) / 8 * ratio) else: width.append( (5 * pen_width + 2 * tilt + 1 * pressure) / 8 * ratio) xpos = ratio * xpos + float(crop_box[0]) ypos = image_height - ratio * ypos + float(crop_box[1]) points.extend([xpos, ypos]) if is_eraser_area or is_eraser: continue # Render lines drawing = Drawing(image_width, image_height) can.setLineCap(1) if layer_colors[layer] is None: can.setStrokeColor(default_stroke_color[color]) else: can.setStrokeColor(layer_colors[layer]) p = can.beginPath() p.moveTo(points[0], points[1]) for i in range(0, len(points), 2): can.setLineWidth(width[int(i / 2)]) p.lineTo(points[i], points[i + 1]) p.moveTo(points[i], points[i + 1]) if i % 10 == 0: p.close() p.close() can.drawPath(p) can.save() packet.seek(0) overlay = PdfReader(packet) if is_landscape: for page in overlay.pages: page.Rotate = 90 return overlay
def generate_diagram(filepath, layers, title, subject): """Generates the stack diagram and writes it to a PDF file. :param filepath: the path to the PDF file that should be written :param layers: the layers of the stack in chronological order :param title: the title of the PDF file :param subject: the subject of the PDF file :type filepath: str :type layers: list of `Layer` :type title: unicode :type subject: unicode """ scale = Scale(layers) stack_height = build_stack(layers, scale) labels, displaced_labels = place_labels(layers) total_margin = dimensions["margin"] full_label_width = dimensions["label_skip"] + dimensions["label_width"] width = dimensions["stack_width"] + 2 * total_margin + full_label_width if Label.needs_left_row: width += full_label_width legend, legend_height = build_legend(displaced_labels, width) height = scale.scale_height + stack_height + legend_height + 2 * total_margin + dimensions["scale_skip"] if legend: height += dimensions["legend_skip"] verified = all(layer.verified for layer in layers) if not verified: red_line_space = dimensions["red_line_skip"] + dimensions["red_line_width"] width += 2 * red_line_space height += 2 * red_line_space total_margin += red_line_space c = canvas.Canvas(filepath, pagesize=(width, height), pageCompression=True) c.setAuthor("JuliaBase samples database") c.setTitle(title) c.setSubject(subject) c.setLineJoin(1) c.setLineCap(1) if not verified: red_line_position = dimensions["red_line_width"] / 2 + dimensions["red_line_skip"] c.saveState() c.setStrokeColor(getAllNamedColors()["red"]) c.setLineWidth(dimensions["red_line_width"]) c.rect(red_line_position, red_line_position, width - 2 * red_line_position, height - 2 * red_line_position) c.restoreState() c.translate(total_margin, total_margin) yoffset = 0 for item in reversed(legend): item.drawOn(c, 0, yoffset) yoffset += item.height + 0.3 * lineskip if legend: c.translate(0, legend_height + dimensions["legend_skip"]) for label in labels: label.print_label(c) c.saveState() if Label.needs_left_row: c.translate(full_label_width, 0) layers = [layer for layer in reversed(layers) if layer.nm >= 0] for i, layer in enumerate(layers): layer.draw(c) c.restoreState() c.translate(full_label_width if Label.needs_left_row else 0, stack_height + dimensions["scale_skip"]) scale.draw(c) c.showPage() c.save()
def _create_colors(self, color_names): colors_by_name = colors.getAllNamedColors() return [colors_by_name[name] for name in color_names]
def generate_diagram(filepath, layers, title, subject): """Generates the stack diagram and writes it to a PDF file. :param filepath: the path to the PDF file that should be written :param layers: the layers of the stack in chronological order :param title: the title of the PDF file :param subject: the subject of the PDF file :type filepath: str :type layers: list of `Layer` :type title: unicode :type subject: unicode """ scale = Scale(layers) stack_height = build_stack(layers, scale) labels, displaced_labels = place_labels(layers) total_margin = dimensions["margin"] full_label_width = dimensions["label_skip"] + dimensions["label_width"] width = dimensions["stack_width"] + 2 * total_margin + full_label_width if Label.needs_left_row: width += full_label_width legend, legend_height = build_legend(displaced_labels, width) height = scale.scale_height + stack_height + legend_height + 2 * total_margin + dimensions[ "scale_skip"] if legend: height += dimensions["legend_skip"] verified = all(layer.verified for layer in layers) if not verified: red_line_space = dimensions["red_line_skip"] + dimensions[ "red_line_width"] width += 2 * red_line_space height += 2 * red_line_space total_margin += red_line_space c = canvas.Canvas(filepath, pagesize=(width, height), pageCompression=True) c.setAuthor("JuliaBase samples database") c.setTitle(title) c.setSubject(subject) c.setLineJoin(1) c.setLineCap(1) if not verified: red_line_position = dimensions["red_line_width"] / 2 + dimensions[ "red_line_skip"] c.saveState() c.setStrokeColor(getAllNamedColors()["red"]) c.setLineWidth(dimensions["red_line_width"]) c.rect(red_line_position, red_line_position, width - 2 * red_line_position, height - 2 * red_line_position) c.restoreState() c.translate(total_margin, total_margin) yoffset = 0 for item in reversed(legend): item.drawOn(c, 0, yoffset) yoffset += item.height + 0.3 * lineskip if legend: c.translate(0, legend_height + dimensions["legend_skip"]) for label in labels: label.print_label(c) c.saveState() if Label.needs_left_row: c.translate(full_label_width, 0) layers = [layer for layer in reversed(layers) if layer.nm >= 0] for i, layer in enumerate(layers): layer.draw(c) c.restoreState() c.translate(full_label_width if Label.needs_left_row else 0, stack_height + dimensions["scale_skip"]) scale.draw(c) c.showPage() c.save()
# License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # ############################################################################## from reportlab.lib import colors import re allcols = colors.getAllNamedColors() regex_t = re.compile('\(([0-9\.]*),([0-9\.]*),([0-9\.]*)\)') regex_h = re.compile('#([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z][0-9a-zA-Z])') def get(col_str): if col_str is None: col_str = '' global allcols if col_str in allcols.keys(): return allcols[col_str] res = regex_t.search(col_str, 0) if res: return float(res.group(1)), float(res.group(2)), float(res.group(3)) res = regex_h.search(col_str, 0) if res:
def GenomeMap(file, GenomeId, grid=10000, cross=True): # print(GenomeId) gd_diagram = GenomeDiagram.Diagram('phages') with open(file, 'r') as f: reader = csv.reader(f) data = list(reader) records = [] ref = {} for Id in GenomeId: try: record = SeqIO.read(Id + ".gb", "genbank") except FileNotFoundError or IOError or ValueError: hd = Entrez.efetch(db="nucleotide", id=Id, rettype='gb', retmode="text") record = SeqIO.read(hd, 'genbank') fw = open(Id + '.gb', 'w') SeqIO.write(record, fw, 'genbank') fw.close() os.getcwd() for i in SeqIO.parse(Id + ".gb", "genbank"): ref[Id] = i.annotations['keywords'] records.append(record) feature_sets = {} max_len = 0 for i, record in enumerate(records): max_len = max(max_len, len(record)) gd_track_for_features = gd_diagram.new_track( 5 - 2 * i, name=record.description, greytrack=True, greytrack_fontsize=16, greytrack_labels=1, largetick=True, smalltick=True, scale_ticks=True, scale_largeticks=0.5, scale_smallticks=0.1, scale_largetick_interval=grid, scale_smalltick_interval=grid / 20, scale_largetick_labels=True, start=0, end=len(record), ) assert record.name not in feature_sets feature_sets[record.id] = gd_track_for_features.new_set() for crosslink in data: if not cross: break set_X = feature_sets[crosslink[0].split(' ')[0]] set_Y = feature_sets[crosslink[1].split(' ')[0]] # 手动划分连接类型时使用 # score = 100 # try: # if crosslink[7] == 1 or crosslink[7] == -1: # score = 100 # except TypeError: # score = 50 if crosslink[0].split(' ')[0] in CLASS1 and crosslink[1].split( ' ')[0] in CLASS1: color = colors.linearlyInterpolatedColor( colors.green, colors.yellow, 0, len(GenomeId), GenomeId.index(crosslink[1].split(' ')[0])) elif crosslink[0].split(' ')[0] in CLASS2 and crosslink[1].split( ' ')[0] in CLASS2: color = colors.linearlyInterpolatedColor( colors.purple, colors.red, 0, len(GenomeId), GenomeId.index(crosslink[1].split(' ')[0])) else: color = colors.linearlyInterpolatedColor( colors.blue, colors.cyan, 0, len(GenomeId), GenomeId.index(crosslink[1].split(' ')[0])) # color = list(colors.getAllNamedColors().keys())[GenomeId.index(crosslink[1].split(' ')[0]) * 17 + 17 % 163] F_x = set_X.add_feature( SeqFeature( FeatureLocation(int(crosslink[2]), int(crosslink[3]), strand=0)), color=color, border=color, ) F_y = set_Y.add_feature( SeqFeature( FeatureLocation(int(crosslink[4]), int(crosslink[5]), strand=0)), color=color, border=color, ) link_xy = CrossLink(F_x, F_y, color, color) gd_diagram.cross_track_links.append(link_xy) for record in records: gd_feature_set = feature_sets[record.id] # 矫正ori for feature in record.features: if feature.type == 'rep_origin': print(record.description + ' 的起始位点在:' + str(feature.location.start)) record = record[feature.location. start:] + record[:feature.location.start] if record.features[0].strand == -1: print('daole') record = record.reverse_complement(id=True, name=True, description=True, features=True, annotations=True, letter_annotations=True) break # 务必绘制反向互补序列时手动开启 # record = record.reverse_complement(id=True, name=True, description=True, features=True, # annotations=True, letter_annotations=True) print(record.description + ' 的起始位点已校正') # 画features i = 0 if ref[record.id] != ['']: for feature in record.features: if feature.type != "gene": continue color = list(colors.getAllNamedColors().keys())[len(feature) % 163] gd_feature_set.add_feature(feature, color=color, label=True, label_size=10, label_angle=90, sigil="ARROW", arrowshaft_height=1.0, arrowhead_length=0.1) i += 1 elif ref[record.id] == ['']: for feature in record.features: if feature.type != "CDS": continue color = list(colors.getAllNamedColors().keys())[len(feature) % 163] gd_feature_set.add_feature(feature, color=color, label=True, label_size=10, label_angle=90, sigil="ARROW", arrowshaft_height=1.0, arrowhead_length=0.2) i += 1 # 用来手动添加重组位点 # for pos in recombinations: # if pos in record.features: # gd_feature_set.add_feature(feature, color=color, label=True, label_size=10, label_angle=90, # sigil="ARROW", arrowshaft_height=1.0, arrowhead_length=0.1) if not cross: # 用来绘制单一序列 gd_diagram.draw(format="linear", pagesize='A4', fragments=5, start=0, end=max_len, fragment_size=1) gd_diagram.write("T7.pdf", "PDF") else: # 用来绘制比对序列 gd_diagram.draw(format="linear", pagesize=(10 * len(GenomeId) * cm, 120 * cm), fragments=1, start=0, end=max_len, fragment_size=1) gd_diagram.write(output, "PDF") print("已输出为PDF")
from datetime import date, timedelta, datetime import logging from reportlab.lib import colors from django.conf import settings from django.db import models from django.template.defaultfilters import slugify import payment_gateways color_list = colors.getAllNamedColors().keys() color_list.sort() COLOR_OPTIONS = [(x, x) for x in color_list] # Create your models here. class Event(models.Model): name = models.CharField(max_length=100, unique=True) badge_number = models.IntegerField("Next badge number", default=1) to_print = models.BooleanField("Print the badges for this event", default=True) end_date = models.DateField("Date the event ends") slug = models.SlugField() class Meta: ordering = ('name',) def __unicode__(self): return self.name def next_badge_number(self): num = self.badge_number
def _render_rm_file(rm_file_name, page_layout=None, path_highlighter=None): """ Render the .rm files (old .lines). See also https://plasma.ninja/blog/devices/remarkable/binary/format/2017/12/26/reMarkable-lines-file-format.html """ rm_file = "%s.rm" % rm_file_name rm_file_metadata = "%s-metadata.json" % rm_file_name # Is this a reMarkable .lines file? with open(rm_file, 'rb') as f: data = f.read() offset = 0 expected_header_v3 = b'reMarkable .lines file, version=3 ' expected_header_v5 = b'reMarkable .lines file, version=5 ' if len(data) < len(expected_header_v5) + 4: print('File too short to be a valid file') os.abort() fmt = '<{}sI'.format(len(expected_header_v5)) header, nlayers = struct.unpack_from(fmt, data, offset) offset += struct.calcsize(fmt) is_v3 = (header == expected_header_v3) is_v5 = (header == expected_header_v5) if (not is_v3 and not is_v5) or nlayers < 1: print('Not a valid reMarkable file: <header={}><nlayers={}>'.format(header, nlayers)) os.abort() # Load name of layers; if layer name starts with # we use this color # for this layer layer_colors = [None for _ in range(nlayers)] if os.path.exists(rm_file_metadata): with open(rm_file_metadata, "r") as meta_file: layers = json.loads(meta_file.read())["layers"] for l in range(len(layers)): layer = layers[l] matches = re.search(r"#([^\s]+)", layer["name"], re.M | re.I) if not matches: continue color_code = matches[0].lower() # Try to parse hex code try: has_alpha = len(color_code) > 7 layer_colors[l] = colors.HexColor(color_code, hasAlpha=has_alpha) continue except: pass # Try to get from name color_code = color_code[1:] color_names = colors.getAllNamedColors() if color_code in color_names: layer_colors[l] = color_names[color_code] # No valid color found... automatic fallback to default # Iterate through layers on the page (There is at least one) packet = io.BytesIO() can = canvas.Canvas(packet, pagesize=(page_layout.x_end, page_layout.y_end)) for layer in range(nlayers): fmt = '<I' (strokes_count,) = struct.unpack_from(fmt, data, offset) offset += struct.calcsize(fmt) # Iterate through the strokes in the layer (If there is any) for stroke in range(strokes_count): if is_v3: fmt = '<IIIfI' pen_nr, color, i_unk, width, segments_count = struct.unpack_from(fmt, data, offset) offset += struct.calcsize(fmt) if is_v5: fmt = '<IIIffI' pen_nr, color, i_unk, width, unknown, segments_count = struct.unpack_from(fmt, data, offset) offset += struct.calcsize(fmt) last_width = 0 # Check which tool is used for both, v3 and v5 and set props # https://support.remarkable.com/hc/en-us/articles/115004558545-5-1-Tools-Overview is_highlighter = (pen_nr == 5 or pen_nr == 18) is_eraser = pen_nr == 6 is_eraser_area = pen_nr == 8 is_sharp_pencil = (pen_nr == 7 or pen_nr == 13) is_tilt_pencil = (pen_nr == 1 or pen_nr == 14) is_marker = (pen_nr == 3 or pen_nr == 16) is_ballpoint = (pen_nr == 2 or pen_nr == 15) is_fineliner = (pen_nr == 4 or pen_nr == 17) is_brush = (pen_nr == 0 or pen_nr == 12) is_calligraphy = pen_nr == 21 if is_sharp_pencil or is_tilt_pencil: pen = Mechanical_Pencil(page_layout.scale, width, color) if is_brush: pen = Brush(page_layout.scale, width, color) elif is_ballpoint: pen = Ballpoint(page_layout.scale, width, color) elif is_fineliner: pen = Fineliner(page_layout.scale, width, color) elif is_marker: pen = Marker(page_layout.scale, width, color) elif is_calligraphy: pen = Calligraphy(page_layout.scale, width, color) elif is_highlighter: pen = Highlighter(page_layout.scale, 30, color) elif is_eraser: pen = Eraser(page_layout.scale, width, color) elif is_eraser_area: pen = EraseArea(page_layout.scale, width, color) elif is_tilt_pencil: pen = Pencil(page_layout.scale, width, color) elif is_sharp_pencil: pen = Mechanical_Pencil(page_layout.scale, width, color) else: print('Unknown pen: {}'.format(pen_nr)) opacity = 0. # Iterate through the segments to form a polyline segment_points = [] segment_widths = [] segment_opacities = [] segment_colors = [] for segment in range(segments_count): fmt = '<ffffff' x_pos, y_pos, speed, tilt, width, pressure = struct.unpack_from(fmt, data, offset) offset += struct.calcsize(fmt) if segment % pen.segment_length == 0: segment_color = pen.get_segment_color(speed, tilt, width, pressure, last_width) segment_width = pen.get_segment_width(speed, tilt, width, pressure, last_width) segment_opacity = pen.get_segment_opacity(speed, tilt, width, pressure, last_width) segment_widths.append(segment_width) segment_opacities.append(segment_opacity) if layer_colors[layer] is None: segment_colors.append(segment_color) else: segment_colors.append(layer_colors[layer]) if page_layout.is_landscape: render_xpos = page_layout.x_end - page_layout.scale * y_pos render_ypos = page_layout.y_end - page_layout.scale * x_pos else: render_xpos = page_layout.x_start + page_layout.scale * x_pos render_ypos = page_layout.y_end - page_layout.scale * y_pos segment_points.extend([render_xpos, render_ypos]) last_width = segment_width if is_eraser_area or is_eraser: continue # Render lines after the arrays are filled # such that we have access to the next and previous points can.setLineCap(0 if is_highlighter else 1) for i in range(2, len(segment_points), 2): can.setStrokeColor(segment_colors[int(i / 2)]) can.setLineWidth(segment_widths[int(i / 2)]) can.setStrokeAlpha(segment_opacities[int(i / 2)]) p = can.beginPath() p.moveTo(segment_points[i - 2], segment_points[i - 1]) p.lineTo(segment_points[i], segment_points[i + 1]) p.moveTo(segment_points[i], segment_points[i + 1]) p.close() can.drawPath(p) # Special handling to plot snapped highights if(path_highlighter and os.path.exists(path_highlighter)): for file_name in os.listdir(path_highlighter): with open(os.path.join(path_highlighter, file_name), "r") as highlighter_file: highlights = json.loads(highlighter_file.read())["highlights"] for h in highlights[0]: rects = h["rects"][0] if page_layout.is_landscape: render_xpos = page_layout.x_end - page_layout.scale * rects["y"] render_ypos = page_layout.y_end - page_layout.scale * rects["x"] else: render_xpos = page_layout.x_start + page_layout.scale * rects["x"] render_ypos = page_layout.y_end - page_layout.scale * rects["y"] width = rects["width"] * page_layout.scale height = rects["height"] * page_layout.scale render_ypos -= height / 2 can.setStrokeColor(default_stroke_color[3]) can.setLineWidth(height) can.setStrokeAlpha(0.2) p = can.beginPath() p.moveTo(render_xpos, render_ypos) p.lineTo(render_xpos+width, render_ypos) p.close() can.drawPath(p) can.save() packet.seek(0) overlay = PdfReader(packet) return overlay