our
@EXPORT
=
qw(matrix2graph cytoscape2graph)
;
sub
matrix2graph {
my
$arg
=
shift
;
my
$input
=
$arg
->{matrix};
my
$output
=
$arg
->{json};
my
$verbose
=
$arg
->{verbose};
my
$graph_stats
=
$arg
->{graph_stats};
open
(
my
$matrix_fh
,
'<:encoding(UTF-8)'
,
$input
);
my
$header_line
= <
$matrix_fh
>;
chomp
$header_line
;
my
@headers
=
split
/\t/,
$header_line
;
shift
@headers
;
my
(
@nodes
,
@edges
);
my
$threshold
= 0.0;
my
$current_index
= 0;
while
(
my
$line
= <
$matrix_fh
> ) {
chomp
$line
;
my
@values
=
split
/\t/,
$line
;
my
$node_id
=
shift
@values
;
push
@nodes
, {
data
=> {
id
=>
$node_id
} };
for
(
my
$i
=
$current_index
+ 1 ;
$i
<
scalar
@headers
;
$i
++ ) {
if
(
$values
[
$i
] >=
$threshold
) {
push
@edges
,
{
data
=> {
source
=>
$node_id
,
target
=>
$headers
[
$i
],
weight
=>
$values
[
$i
]
}
};
}
}
$current_index
++;
}
close
$matrix_fh
;
my
%graph
= (
elements
=> {
nodes
=> \
@nodes
,
edges
=> \
@edges
,
}
);
say
"Writting <$output> file "
if
$verbose
;
write_json( {
filepath
=>
$output
,
data
=> \
%graph
} );
return
defined
$graph_stats
? \
%graph
:
undef
;
}
sub
cytoscape2graph {
my
$arg
=
shift
;
my
$json_data
=
$arg
->{graph};
my
$output
=
$arg
->{output};
my
$metric
=
$arg
->{metric};
my
$verbose
=
$arg
->{verbose};
my
$jaccard
=
$metric
eq
'jaccard'
? 1 : 0;
my
@nodes
= @{
$json_data
->{elements}{nodes} };
my
@edges
= @{
$json_data
->{elements}{edges} };
my
$graph
= Graph->new(
undirected
=> 1 );
foreach
my
$node
(
@nodes
) {
$graph
->add_vertex(
$node
->{data}{id} );
}
foreach
my
$edge
(
@edges
) {
$graph
->add_weighted_edge(
$edge
->{data}{source},
$edge
->{data}{target},
$jaccard
? 1 -
$edge
->{data}{weight} :
$edge
->{data}{weight}
);
}
graph_stats(
$graph
,
$output
,
$metric
,
$verbose
);
return
1;
}
sub
graph_stats {
my
(
$g
,
$output
,
$metric
,
$verbose
) =
@_
;
say
"Writting <$output> file "
if
$verbose
;
open
(
my
$fh
,
'>:encoding(UTF-8)'
,
$output
);
print
$fh
"Metric: "
,
ucfirst
(
$metric
),
"\n"
;
print
$fh
"Number of vertices: "
,
scalar
$g
->vertices,
"\n"
;
print
$fh
"Number of edges: "
,
scalar
$g
->edges,
"\n"
;
print
$fh
"Is connected: "
,
$g
->is_connected,
"\n"
;
print
$fh
"Connected Components: "
,
scalar
$g
->connected_components,
"\n"
;
if
(
$g
->is_connected ) {
print
$fh
"Graph Diameter: "
, (
join
"->"
,
$g
->diameter ),
"\n"
;
print
$fh
"Average Path Length: "
,
sprintf
(
"%7.3f"
,
$g
->average_path_length),
"\n"
;
}
foreach
my
$v
(
$g
->vertices ) {
print
$fh
"Degree of vertex $v: "
,
$g
->degree(
$v
),
"\n"
;
}
my
$mst
=
$g
->MST_Kruskal;
print
$fh
"MST has "
,
scalar
$mst
->edges,
" edges\n"
;
foreach
my
$u
(
$g
->vertices ) {
foreach
my
$v
(
$g
->vertices ) {
if
(
$u
ne
$v
) {
my
@path
=
$g
->SP_Dijkstra(
$u
,
$v
);
if
(
@path
) {
my
$distance
=
$g
->path_length(
$u
,
$v
);
print
$fh
"Shortest path from $u to $v is "
,
(
join
"->"
,
@path
),
" ["
,
scalar
@path
,
"] with length $distance\n"
;
}
else
{
print
$fh
"No path from $u to $v\n"
;
}
}
}
}
close
$fh
;
return
1;
}
1;