draw.py 3.08 KB
Newer Older
Tiago Peixoto's avatar
Tiago Peixoto committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 Tiago de Paula Peixoto <tiago@skewed.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os
from functools import wraps

import graph_tool.all as gt

import process_entry
from analyze import analyze_entries

from locks import acquire_lock
from util import *

def cache_draw(f):
    @wraps(f)
    def wrap(entry, alt, **kwargs):
        if len(kwargs) > 0:
            return f(entry, alt, **kwargs)
        base = f"{process_entry.root}/cache/draw/{entry.name}"
        fname = f"{base}/{alt}.png"
        if not os.path.exists(fname):
            os.makedirs(base, exist_ok=True)
            buf = f(entry, alt)
            if buf is not None:
                with open(fname, "wb") as fo:
                    shutil.copyfileobj(buf, fo)
        if os.path.exists(fname):
            return open(fname, "rb")
        return None
    return wrap

@cache_draw
def draw_entry(entry, alt, svg=False, size=1000, bg_color="#cdcdcd",
               edge_color=None, full=False):

    if svg:
        fmt = "svg"
    else:
        fmt = "png"

    try:
        if alt is None:
            props = entry._analyses["vertex_properties"]
        else:
            props = entry.analyses[alt]["vertex_properties"]
        props = [p[0] for p in props]
        if "_pos" not in props:
            raise KeyError

        buf = io.BytesIO()
        for alt, g in entry.parse(alts=[alt], cache_only=True):

            c = gt.label_largest_component(g, directed=False)
            if c.fa.sum() > .6 * g.num_vertices() and not full:
                g = gt.Graph(gt.GraphView(g, vfilt=c), prune=True)

            gt.graph_draw(g, pos=g.vp["_pos"], fmt=fmt, edge_color=edge_color,
                          bg_color=bg_color, output_size=(size, size),
                          adjust_aspect=False, output=buf)
            buf.seek(0)
            return buf
    except KeyError:
        return None

if __name__ == "__main__":

        if len(sys.argv) > 1:
            names = sys.argv[1:]
        else:
            names = None

        entries = process_entry.get_entries(names)

        for entry in entries.values():
            with acquire_lock(entry, block=False) as lock:
                if lock is None:
                    continue
                print("entry:", entry.name)
                analyze_entries([entry], cache_only=True)
                for alt, g in entry.parse(cache_only=True, lazy=True):
                    print(f"\t{alt}...")
                    draw_entry(entry, alt)