File Coverage

GO/Handlers/obo_text.pm
Criterion Covered Total %
statement 107 192 55.7
branch 33 58 56.9
condition 2 6 33.3
subroutine 13 19 68.4
pod 0 14 0.0
total 155 289 53.6


line stmt bran cond sub pod time code
1             # $Id: obo_text.pm,v 1.16 2008/01/22 23:54:45 cmungall Exp $
2             #
3             # This GO module is maintained by Chris Mungall
4             #
5             # see also - http://www.geneontology.org
6             # - http://www.godatabase.org/dev
7             #
8             # You may distribute this module under the same terms as perl itself
9              
10             =head1 NAME
11              
12             GO::Handlers::obo_text -
13              
14             =head1 SYNOPSIS
15              
16             use GO::Handlers::obo_text
17              
18             =cut
19              
20             =head1 DESCRIPTION
21              
22             transforms OBO XML events into OBO Text
23              
24             L
25              
26             =head1 PUBLIC METHODS -
27              
28             =cut
29              
30             # makes objects from parser events
31              
32             package GO::Handlers::obo_text;
33 1     1   6 use Data::Stag qw(:all);
  1         2  
  1         839  
34 1     1   7 use GO::Parsers::ParserEventNames;
  1         2  
  1         285  
35 1     1   6 use base qw(GO::Handlers::base);
  1         3  
  1         404  
36 1     1   7 use strict qw(vars refs);
  1         2  
  1         2555  
37              
38             sub s_obo {
39 1     1 0 64 my $self = shift;
40             #$self->SUPER::s_obo(@_);
41 1         4 return;
42             }
43              
44             sub e_header {
45 1     1 0 4725 my $self = shift;
46 1         3 my $hdr = shift;
47              
48 1         10 my $fmt = stag_get($hdr,'format-version');
49 1   50     197 $self->tag("format-version"=>
50             (stag_sget($hdr,'format-version') || '1.2'));
51 1         49 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
52             localtime(time);
53 1         12 $self->tag('date'=>sprintf("%02d:%02d:%04d %02d:%02d",
54             $mday,$mon+1,$year+1900,$hour,$min));
55 1         3 $self->tag('autogenerated-by'=>$0);
56 1         8 foreach (stag_tnodes($hdr)) {
57 3         199 $self->tag(stag_name($_), _obo_escape($_->data));
58             }
59 1         6 my @sts = stag_get($hdr,'synonymtypedef');
60 1         284 foreach (@sts) {
61 15         61 my $scope = stag_sget($_,'scope');
62 15 50 50     973 $self->tag(synonymtypedef => sprintf("%s \"%s\" %s",
63             stag_sget($_,ID),
64             stag_sget($_,NAME) || '',
65             ($scope ? uc($scope) : '')));
66             }
67              
68 1         9 my @ssdefs = stag_get($hdr,'subsetdef');
69 1         156 foreach (@ssdefs) {
70 0         0 $self->tag(subsetdef => sprintf("%s \"%s\"",
71             stag_sget($_,ID),
72             stag_sget($_,NAME)));
73             }
74 1         7 $self->{__emitted_header} = 1;
75              
76 1         14 $self->print("\n");
77 1         23 return;
78             }
79              
80             sub e_typedef {
81 1     1 0 522 my $self = shift;
82 1         3 my $t = shift;
83 1         8 $self->stanza('Typedef', $t);
84             }
85              
86             sub e_term {
87 123     123 0 4892 my $self = shift;
88 123         186 my $t = shift;
89 123 50       334 if (!$self->{__emitted_header}) {
90 0         0 $self->e_header(stag_new(HEADER,[]));
91             }
92 123         331 $self->stanza('Term', $t);
93             }
94              
95             sub e_annotation {
96 0     0 0 0 my $self = shift;
97 0         0 my $t = shift;
98 0 0       0 if (!$self->{__emitted_header}) {
99 0         0 $self->e_header(stag_new(HEADER,[]));
100             }
101 0         0 $self->stanza('Annotation', $t);
102             }
103              
104             sub e_instance {
105 0     0 0 0 my $self = shift;
106 0         0 my $t = shift;
107 0 0       0 if (!$self->{__emitted_header}) {
108 0         0 $self->e_header(stag_new(HEADER,[]));
109             }
110 0         0 $self->stanza('Instance', $t);
111             }
112              
113             sub stanza {
114 124     124 0 176 my $self = shift;
115 124         151 my $stanza = shift;
116 124         173 my $t = shift;
117 124         518 $self->print("[$stanza]\n");
118 124         3071 my @BOOLEAN_TAGS =
119             (
120             IS_ANONYMOUS,
121             IS_OBSOLETE,
122             IS_CYCLIC,
123             IS_TRANSITIVE,
124             IS_SYMMETRIC,
125             IS_ANTI_SYMMETRIC,
126             IS_REFLEXIVE,
127             IS_METADATA_TAG,
128             );
129 124         821 my @TAGS =
130             (ID,
131             NAME,
132             ALT_ID,
133             NAMESPACE,
134             DEF,
135             COMMENT,
136             SUBSET,
137             IS_A ,
138             RELATIONSHIP,
139             UNION_OF,
140             INTERSECTION_OF,
141             SYNONYM,
142             PROPERTY_VALUE,
143             XREF_ANALOG,
144             XREF_UNKNOWN,
145             'object',
146             @BOOLEAN_TAGS,
147             );
148 124         250 my %IS_BOOLEAN = map { ($_=>1) } @BOOLEAN_TAGS;
  992         2178  
149 124         330 my @IGNORE = qw(is_root);
150 124         233 foreach my $tag (@IGNORE) {
151 124         737 stag_unset($t, $tag);
152             }
153 124         8457 foreach my $tag (@TAGS) {
154 2976         75818 my @vals = stag_get($t, $tag);
155 2976 100       182132 next unless @vals;
156              
157 599 100       3744 if ($tag eq DEF) {
    50          
    50          
    50          
    100          
    50          
    100          
    50          
    100          
158 2         4 my $def = shift @vals;
159 2         13 my $defstr = $def->get_defstr;
160 2         100 my $qn = stag_sget($t, "$tag/@");
161 2         204 $self->tag(def => _obo_escape($defstr), [$def->get_dbxref], $qn);
162             }
163             elsif ($tag eq RELATIONSHIP) {
164             $self->tag(relationship => sprintf("%s %s",
165             $_->sget_type,
166             $_->sget_to),
167             undef,
168             $_->sget('@'))
169 0         0 foreach @vals;
170             }
171             elsif ($tag eq INTERSECTION_OF) {
172             $self->tag(intersection_of => sprintf("%s %s",
173             $_->sget_type,
174             $_->sget_to),
175             undef,
176             $_->sget('@'))
177 0         0 foreach @vals;
178             }
179             elsif ($tag eq UNION_OF) {
180             $self->tag(union_of => sprintf("%s %s",
181             $_->sget_type,
182             $_->sget_to),
183             undef,
184             $_->sget('@'))
185 0         0 foreach @vals;
186             }
187             elsif ($tag eq SYNONYM) {
188 109         194 foreach my $syn (@vals) {
189 278         984 my $type = $syn->sget('@/synonym_type');
190 278         32037 my $scope = $syn->sget('@/scope');
191 278         63236 my @vals = (quote($syn->sget_synonym_text));
192 278 50       916 push(@vals,uc($scope)) if $scope;
193 278 50       597 push(@vals,$type) if $type;
194 278         1537 $self->tag($tag,
195             join(' ',@vals),
196             [$syn->get_dbxref]);
197             }
198             }
199             elsif ($tag eq XREF_ANALOG) {
200             $self->tag('xref', dbxref($_),undef,$_->sget('@'))
201 0         0 foreach @vals;
202             }
203             elsif ($tag eq PROPERTY_VALUE) {
204 116         269 foreach (@vals) {
205 116         610 my $dt = $_->sget_datatype;
206 116 50       5845 if ($dt) {
207 0         0 $self->tag('property_value' => sprintf("%s %s %s",
208             $_->sget_type,
209             quote($_->sget_value),
210             $dt));
211             }
212             else {
213 116         591 $self->tag('property_value' => sprintf("%s %s",
214             $_->sget_type,
215             $_->sget_to));
216             }
217             }
218             }
219             elsif ($tag eq 'object') {
220             # experimental: obof1.3
221 0         0 $self->tag('object' => $self->obo_id(@vals));
222             }
223             elsif ($IS_BOOLEAN{$tag}) {
224 1 50       6 $self->tag($tag, $vals[0] ? "true" : "false");
225             }
226             else {
227 371         632 foreach (@vals) {
228 371 50       734 if (ref($_)) {
229 0         0 $self->tag($tag, $_->sget('.'),undef,$_->sget('@'))
230             }
231             else {
232 371         720 $self->tag($tag, _obo_escape($_));
233             }
234             }
235             }
236 599         2826 stag_unset($t, $tag);
237             }
238 124         752 my @tnodes = stag_tnodes($t);
239             $self->tag($_->name, _obo_escape($_->data))
240 124         5898 foreach @tnodes;
241              
242 124         631 my @ntnodes = stag_ntnodes($t);
243 124 50       5169 if (@ntnodes) {
244 0         0 print STDERR $_->xml foreach @ntnodes;
245 0         0 $self->throw( "unknown elements");
246             }
247              
248 124         412 $self->print("\n");
249              
250             }
251              
252             sub obo_id {
253 0     0 0 0 my $self = shift;
254 0         0 my $v = shift;
255 0 0       0 if (ref($v)) {
256 0         0 my $isect = $v->sget_intersection;
257 0 0       0 if ($isect) {
258 0         0 my @links = $isect->get_link;
259 0         0 my @genus = grep {!$_->get_type} @links;
  0         0  
260 0         0 my @diffs = grep {$_->get_type} @links;
  0         0  
261 0         0 my $s =
262             join('^',
263 0         0 (map {$self->obo_id($_->sget_to)} @genus),
264             (map {
265 0         0 sprintf("%s(%s)",$_->sget_type,$self->obo_id($_->sget_to))
266             } @diffs));
267 0         0 return $s;
268             }
269             else {
270             }
271             }
272             else {
273 0         0 return $v;
274             }
275             }
276              
277             sub tag {
278 906     906 0 28592 my $self = shift;
279 906         1387 my ($t, $v, $xrefsr, $qualsr) = @_;
280 906 100       2992 my @xrefs = @{$xrefsr || []};
  906         3647  
281 906 50       2362 return unless defined $v;
282 906 100       1678 if ($t eq DEF) {
283 2         5 $v=quote($v);
284             }
285 906         1033 my $xrefl = '';
286 906 100       1602 if ($xrefsr) {
287 56         126 $xrefl =
288             ' ['.join(', ',
289             map {
290 280         608 dbxref($_);
291             } @xrefs).']';
292             }
293 906         962 my $ql = '';
294 906 50       1479 if ($qualsr) {
295 0         0 my %qh = stag_pairs($qualsr);
296 0         0 $ql = ' {'.join(
297             ', ',
298             map {
299 0         0 "$_=".quote($qh{$_})
300             } keys %qh
301             ).'}';
302             }
303 906         3571 $self->printf("%s: %s$xrefl$ql\n", $t, $v);
304 906         26133 return;
305             }
306              
307             sub _obo_escape {
308 493     493   1894 my $s=shift;
309 493         700 $s =~ s/\\/\\\\/;
310 493         835 $s =~ s/([\{\}])/\\$1/g;
311 493         1342 $s;
312             }
313              
314             sub dbxref {
315 56     56 0 69 my $x = shift;
316 56 50       111 if (ref($x)) {
317 56         264 my $xref = $x->sget_dbname . ':' . $x->sget_acc;
318 56         5856 my $name = $x->sget_name;
319 56 50       3367 if (defined($name)) {
320 0         0 $name =~ s/\"/\\\"/g;
321 0         0 $xref." \"$name\"";
322             }
323             else {
324 56         244 $xref;
325             }
326             }
327             else {
328 0         0 $x;
329             }
330             }
331              
332             sub safe {
333 0     0 0 0 my $word = shift;
334 0         0 $word =~ s/ /_/g;
335 0         0 $word =~ s/\-/_/g;
336 0         0 $word =~ s/\'/prime/g;
337 0         0 $word =~ tr/a-zA-Z0-9_//cd;
338 0         0 $word =~ s/^([0-9])/_$1/;
339 0         0 $word;
340             }
341              
342             sub quote {
343 280     280 0 15578 my $word = shift;
344             #$word =~ s/,/\\,/g; ## no longer required
345 280         652 $word =~ s/\"/\\\"/g;
346 280         874 "\"$word\"";
347             }
348              
349             # -- EXPERIMENTAL CODE --
350             # obo format for gene_assocs
351              
352             # we are hardcoding aspects here; this is OK, only for
353             # gene_assoc file which is GO specific
354             our %ASPECT_IDX =
355             (F => 'has_activity',
356             P => 'involved_in',
357             C => 'localised_to'
358             );
359              
360             sub e_prod {
361 0     0 0   my $self = shift;
362 0           my $prod = shift;
363              
364 0           my $proddb = $self->up_to('dbset')->get_proddb;
365            
366 0           my $acc = $prod->get_prodacc;
367 0           my $id = "$proddb:$acc";
368 0   0       my $type = $prod->get_prodtype || 'gene_product';
369 0           $self->print("!! ***************************** \n");
370 0           $self->print("!! Gene Product: $id \n");
371 0           $self->print("!! ***************************** \n");
372 0           $self->print("[$type]\n");
373 0           $self->tag(id=>$id);
374 0           $self->tag(dbname=>$proddb);
375 0           $self->tag(acc=>$acc);
376 0           $self->tag(symbol=>$prod->sget_prodsymbol);
377 0           $self->tag(name=>$prod->sget_prodname);
378 0           $self->tag(synonym=>$_) foreach $prod->sget_prodsyn;
379 0           $self->tag(has_taxon=>'NCBI:'.$prod->sget_prodtaxa);
380 0           $self->print("\n");
381              
382 0           my @assocs = $prod->get_assoc;
383 0           foreach my $assoc (@assocs) {
384 0           my $termacc = $assoc->get_termacc;
385 0           my $aspect = $assoc->get_aspect;
386 0           my $ns = $ASPECT_IDX{$aspect};
387 0           $self->print("[gene_product_annotation]\n");
388 0           $self->tag(involves_gene_product=>$id);
389 0           $self->tag($ns=>$termacc);
390 0           $self->tag($_=>'true') foreach $assoc->get_qualifier;
391 0           $self->tag(date=>$assoc->sget_assocdate);
392 0           $self->tag(source_db=>$assoc->sget_source_db);
393 0           my @evs = $assoc->get_evidence;
394 0           foreach my $ev (@evs) {
395 0           $self->tag(has_evidence=>$ev->sget_evcode, $ev->get_ref);
396 0           $self->tag(with=>$_) foreach $ev->get_with;
397             }
398 0           $self->print("\n");
399             }
400 0           $self->print("!! //\n\n");
401            
402             }
403              
404 0     0 0   sub dbxrefstr {
405              
406             }
407              
408             1;