-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgo_children.pl
executable file
·131 lines (112 loc) · 4.31 KB
/
go_children.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
#!/usr/bin/perl -w
use strict;
use Getopt::Long;
my $ver = '1.0';
use Getopt::Long;
my %opts=();
GetOptions(\%opts,"i:s@", "g:s");
if (!$opts{i} or !$opts{g}){
print "----------------------------------------------------------------------
\t\t\tversion : $ver
----------------------------------------------------------------------
USAGE: perl $0
-i input GOID (GO:######), could be multiple, such as -i GO:#### -i GO:#####
-g input go.obo file
[note]
this script will print the input GOID and all its children to stdout, one per line
----------------------------------------------------------------------\n";
exit;
}
#### ontology parser
my %hNodesAndRelationship = ();
my %hObsoleteTerms = ();
&obo_parser($opts{g},\%hNodesAndRelationship,\%hObsoleteTerms);
#use Data::Dumper;
#print Dumper %hNodesAndRelationship;
#exit;
my %hChildren = ();
foreach my $goid (@{$opts{i}}){
&find_children($goid, $hNodesAndRelationship{$goid}, \%hChildren);
$hChildren{$goid} ++;
}
print join("\n", sort keys %hChildren), "\n";
## --
sub find_children{
my ($goid, $hrCurrentNode, $hrChildren)=@_;
return if (!defined $$hrCurrentNode{children});
foreach my $child_node (@{$$hrCurrentNode{children}}){
my $current_goid = $$child_node{acc};
$$hrChildren{$current_goid} ++;
&find_children($current_goid, $child_node, $hrChildren);
}
}
sub obo_parser{
my ($infile,$hash,$obsoleteHash)=@_;
#### parsing obo_file
my $backup=$/;
$/="\n\[";
my $header=1;
open IN, $infile or die "Cannot open file: $infile!\n";
while (<IN>){
if ($header){
$header=0;
my ($ver)=/format-version:\s+([0-9.]+)/;
print STDERR "\t===============================================================================\n\t\tParsing OBO file, current version is $ver .\n\t===============================================================================\n";
}else{
#### new [item]
my $acc='';
my $name_space='';
my $name='';
my $is_root=0;
my $is_obsolete=0;
my @aAlt_id=();
my @aParents=();
my @aRecommanded_ids_for_obsolete_id=();
my @aContents=split(/\n/,$_);
foreach my $line (@aContents){
if ($line=~/^id: (\S+)/){
$acc=$1;
push @aAlt_id,$acc;
}elsif($line=~/^alt_id: (\S+)/){
push @aAlt_id,$1;
}elsif($line=~/^name: (.+)/){
$name=$1;
}elsif($line=~/^namespace: (.+)/){
$name_space=$1;
}elsif($line=~/^is_a:\s+(GO:\d+)/){
push @aParents,$1;
}elsif($line=~/^relationship: part_of (GO:\d+)/){
push @aParents,$1;
}elsif($line=~/is_obsolete: true/){
$is_obsolete=1;
}elsif($line=~/^comment:/){
(@aRecommanded_ids_for_obsolete_id)=$line=~/(GO:\d+)/g;
}
}
#### add new item in hash
if ($is_obsolete){### if obsolete
foreach my $local_acc (@aAlt_id){
$$obsoleteHash{$local_acc}=\@aRecommanded_ids_for_obsolete_id;
}
}else{
$is_root=1 if !(scalar @aParents);
my %newHash=(acc=>$acc,parents=>\@aParents,name=>$name,name_space=>$name_space,is_root=>$is_root,is_relationship_build=>0);
foreach my $local_acc (@aAlt_id){
$$hash{$local_acc}=\%newHash;
}
}
}
}
close IN;
#### building relationships for all nodes
foreach my $key (keys %{$hash}){
if ((!$$hash{$key}{is_root}) and (!$$hash{$key}{is_relationship_build})){ # if not root and relationship not build
for(my $i=0; $i<@{$$hash{$key}{parents}}; $i++){
my $parent_go_id=$$hash{$key}{parents}[$i];
$$hash{$key}{parents}[$i]=$$hash{$parent_go_id};
push @{$$hash{$parent_go_id}{children}}, $$hash{$key};
}
$$hash{$key}{is_relationship_build}=1;
}
}
}