-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathrcl-dot-resmap.pl
executable file
·184 lines (160 loc) · 4.8 KB
/
rcl-dot-resmap.pl
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/perl
# Reads the .hi.RESOLUTION.resdot file that describes the resolution tree,
# with node information for levels and link for edges.
# Creates a GraphViz definition for a plot.
# With --xlabel-remainder, extra labels are displayed, indicating
# how many cells of a parent are not accounted for by the children displayed,
# i.e. cells that were split off into smaller clusters.
use Getopt::Long;
use warnings;
use strict;
my @ARGV_COPY = @ARGV;
my $n_args = @ARGV;
$::debug = 0;
$::test = 0;
my $help = 0;
my $verbose = 0;
my $progname = 'rcl-dot-resmap.pl';
my $plot_xlabeltype = "none";
my $plot_minres = 0;
my $plot_labeltype = 'size';
sub help {
print <<EOH;
Usage:
$progname [options]
Options:
--help this
from a cluster as it splits into its subclusters.
--minres=<num> do not display nodes of size below <num>
--label=<string> size|ival|leaf|none
--xlabel=<string> size|ival|peel currently only shown for parents
EOH
}
if
(! GetOptions
( "help" => \$help
, "test" => \$::test
, "debug=i" => \$::debug
, "minres=i" => \$plot_minres
, "label=s" => \$plot_labeltype
, "xlabel=s" => \$plot_xlabeltype
, "verbose" => \$verbose
)
)
{ print STDERR "option processing failed\n";
exit(1);
}
if ($help) {
help();
exit 0;
}
die "Need size|ival|leaf\n" unless $plot_labeltype =~ /^(size|ival|leaf|none)$/;
my %nodeinfo = ();
my @links = ();
my $maxrung = 0;
my $n_skip_edges = 0;
my $n_skip_nodes = 0;
while (<>) { chomp;
my @F = split "\t", $_;
my $type = shift @F;
if ($type eq 'node') {
die "Expect 4 data fields for node at line $.\n" unless @F == 4;
my ($name, $val, $size, $peel) = @F;
if ($size < $plot_minres) {
$n_skip_nodes++;
next;
}
my $rung = int(($val-0.01)/20); # integer in range 0-50.
$nodeinfo{$name} =
{ name => $name
, val => $val
, ival => int($val)
, rung => $rung
, size => $size
, peel => $peel
, is_parent => 0
, leaf => ""
};
if ($name =~ /_x(\S+)/) {
$nodeinfo{$name}{leaf} = $1;
}
# dangersign dependency on rcl-res naming convention
#
$maxrung = $rung if $rung > $maxrung;
} elsif ($type eq 'link') {
die "Expect 2 data fields for node at line $.\n" unless @F == 2;
my ($parent, $child) = @F;
if (!defined($nodeinfo{$parent}) || !defined($nodeinfo{$child})) {
$n_skip_edges++;
next;
}
push @links,
{ parent => $F[0]
, child => $F[1]
};
$nodeinfo{$parent}{is_parent}++; # dangersign; depends on links following nodes.
}
}
print STDERR "Highest rung at $maxrung\n";
print STDERR "Blanked $n_skip_nodes nodes and $n_skip_edges edges\n";
my @rulerlevels = map { "lev$_" } 0..($maxrung+1);
push @rulerlevels, map { my $j=$_+1; "lev$_ -> lev$j [minlen=1.0]" } 0..$maxrung;
my @treelevels = ();
# check if any parent+child are on the same rung. Moan if so.
# then ... push child down/up if possible (todo).
# down the tree/drawing, but leaves in tree are high in rung.
#
my $amends = 0;
while (1) {
$amends = 0;
for my $link (@links) {
my ($p, $c) = ($link->{parent}, $link->{child});
if ($nodeinfo{$p}{rung} >= $nodeinfo{$c}{rung}) {
print STDERR "Equal rank $nodeinfo{$p}{rung} for $p and $c (amending)\n" if $verbose;
$nodeinfo{$c}{rung} += 1;
$amends++;
}
}
last unless $amends;
}
print STDERR "Adjusted position for $amends nodes\n" if $amends;
# now pin the nodes to the $maxrung-rung ladder.
for my $rung (0..$maxrung) {
my @besties = grep { $nodeinfo{$_}{rung} == $rung } keys %nodeinfo;
push @treelevels, qq{{ rank = same; lev$rung @besties; }};
}
my @nodenames = ();
if ($plot_labeltype eq 'none') {
}
elsif ($plot_labeltype eq 'leaf') {
@nodenames = map { qq{$_ [label=$nodeinfo{$_}{leaf}];} } grep { length($nodeinfo{$_}{leaf}); } keys %nodeinfo;
}
elsif ($plot_labeltype =~ /^(size|ival)$/) {
@nodenames = map { qq{$_ [label=$nodeinfo{$_}{$plot_labeltype}];} } keys %nodeinfo;
}
if ($plot_xlabeltype =~ /^(size|ival|peel)$/) {
push @nodenames,
map {qq{$_ [xlabel=< <font point-size="40">[$nodeinfo{$_}{$plot_xlabeltype}]</font> >];} }
grep { $nodeinfo{$_}{is_parent} } keys %nodeinfo;
}
{ local $" = "\n";
print <<EOH;
digraph g {
node [shape="circle", width=1.0, fixedsize=true, label="" ];
edge [arrowhead=none]
ranksep = 0.2;
subgraph levels {
label="levels";
node [style="invis", shape=point, width=0.01];
edge [style="invis"];
@rulerlevels
}
subgraph tree {
node [width=2, fontsize=40];
EOH
print "@treelevels\n@nodenames\n";
}
for my $it (@links) {
print "$it->{parent} -> $it->{child}\n";
}
print "}}\n";