comparison variant_effect_predictor/Bio/Structure/Entry.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1f6dce3d34e0
1 # $Id: Entry.pm,v 1.17 2002/10/22 07:38:44 lapp Exp $
2 #
3 # bioperl module for Bio::Structure::Entry
4 #
5 # Cared for by Kris Boulez <kris.boulez@algonomics.com>
6 #
7 # Copyright Kris Boulez
8 #
9 # You may distribute this module under the same terms as perl itself
10
11 # POD documentation - main docs before the code
12
13 =head1 NAME
14
15 Bio::Structure::Entry - Bioperl structure Object, describes the whole entry
16
17 =head1 SYNOPSIS
18
19 #add synopsis here
20
21 =head1 DESCRIPTION
22
23 This object stores a whole Bio::Structure entry. It can consist of one or
24 more models (Bio::Structure::Model), which in turn consist of one or more
25 chains (Bio::Structure::Chain). A chain is composed of residues
26 (Bio::Structure::Residue) and a residue consists of atoms (Bio::Structure::Atom)
27 If no specific model or chain is chosen, the first one is choosen.
28
29 =head1 FEEDBACK
30
31 =head2 Mailing Lists
32
33 User feedback is an integral part of the evolution of this and other
34 Bioperl modules. Send your comments and suggestions preferably to one
35 of the Bioperl mailing lists. Your participation is much appreciated.
36
37 bioperl-l@bioperl.org - General discussion
38 http://bio.perl.org/MailList.html - About the mailing lists
39
40 =head2 Reporting Bugs
41
42 Report bugs to the Bioperl bug tracking system to help us keep track
43 the bugs and their resolution. Bug reports can be submitted via email
44 or the web:
45
46 bioperl-bugs@bio.perl.org
47 http://bugzilla.bioperl.org/
48
49 =head1 AUTHOR - Kris Boulez
50
51 Email kris.boulez@algonomics.com
52
53 =head1 APPENDIX
54
55 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
56
57 =cut
58
59
60 # Let the code begin...
61
62 package Bio::Structure::Entry;
63 use vars qw(@ISA);
64 use strict;
65
66 use Bio::Root::Root;
67 use Bio::Structure::StructureI;
68 use Bio::Structure::Model;
69 use Bio::Structure::Chain;
70 use Bio::Annotation::Collection;
71 use Tie::RefHash;
72
73 @ISA = qw(Bio::Root::Root Bio::Structure::StructureI);
74
75
76 =head2 new()
77
78 Title : new()
79 Usage : $struc = Bio::Structure::Entry->new(
80 -id => 'structure_id',
81 );
82
83 Function: Returns a new Bio::Structure::Entry object from basic
84 constructors. Probably most called from Bio::Structure::IO.
85 Returns : a new Bio::Structure::Model object
86
87 =cut
88
89 sub new {
90 my ($class, @args) = @_;
91 my $self = $class->SUPER::new(@args);
92
93 my($id, $model, $chain, $residue ) =
94 $self->_rearrange([qw(
95 ID
96 MODEL
97 CHAIN
98 RESIDUE
99 )],
100 @args);
101
102 # where to store parent->child relations (1 -> 1..n)
103 # value to this hash will be an array ref
104 # by using Tie::RefHash we can store references in this hash
105 $self->{'p_c'} = ();
106 tie %{ $self->{'p_c'} } , "Tie::RefHash";
107
108 # where to store child->parent relations (1 -> 1)
109 $self->{'c_p'} = ();
110 tie %{ $self->{'c_p'} } , "Tie::RefHash";
111
112 $id && $self->id($id);
113
114 $self->{'model'} = [];
115 $model && $self->model($model);
116
117
118 if($chain) {
119 if ( ! defined($self->model) ) { # no model yet, create default one
120 $self->_create_default_model;
121 }
122 for my $m ($self->model) { # add this chain on all models
123 $m->chain($chain);
124 }
125 }
126
127 $residue && $self->residue($residue);
128
129 # taken from Bio::Seq (or should we just inherit Bio::Seq and override some methods)
130 my $ann = Bio::Annotation::Collection->new;
131 $self->annotation($ann);
132
133 return $self;
134 }
135
136
137 =head2 model()
138
139 Title : model
140 Function: Connects a (or a list of) Model objects to a Bio::Structure::Entry.
141 To add a Model (and keep the existing ones) use add_model()
142 It returns a list of Model objects.
143 Returns : list of Bio::Structure::Model objects
144 Args : One Model or a reference to an array of Model objects
145
146 =cut
147
148 sub model {
149 my ($self, $model) = @_;
150
151 if( defined $model) {
152 if( (ref($model) eq "ARRAY") ||
153 ($model->isa('Bio::Structure::Model')) ) {
154 # remove existing ones, tell they've become orphan
155 my @obj = $self->model;
156 if (@obj) {
157 for my $m (@obj) {
158 $self->_remove_from_graph($m);
159 $self->{'model'} = [];
160 }
161 }
162 # add the new ones
163 $self->add_model($self,$model);
164 }
165 else {
166 $self->throw("Supplied a $model to model, we want a Bio::Structure::Model or a list of these\n");
167 }
168 }
169 # give back list of models via general get method
170 $self->get_models($self);
171 }
172
173
174
175 =head2 add_model()
176
177 Title : add_model
178 Usage : $structure->add_model($model);
179 Function: Adds a (or a list of) Model objects to a Bio::Structure::Entry.
180 Returns :
181 Args : One Model or a reference to an array of Model objects
182
183 =cut
184
185 sub add_model {
186 my($self,$entry,$model) = @_;
187
188 # if only one argument and it's a model, change evrything one place
189 # this is for people calling $entry->add_model($model);
190 if ( !defined $model && ref($entry) =~ /^Bio::Structure::Model/) {
191 $model = $entry;
192 $entry = $self;
193 }
194 # $self and $entry are the same here, but it's used for uniformicity
195 if ( !defined($entry) || ref($entry) !~ /^Bio::Structure::Entry/) {
196 $self->throw("first argument to add_model needs to be a Bio::Structure::Entry object\n");
197 }
198 if (defined $model) {
199 if (ref($model) eq "ARRAY") {
200 # if the user passed in a reference to an array
201 for my $m ( @{$model} ) {
202 if( ! $m->isa('Bio::Structure::Model') ) {
203 $self->throw("$m is not a Model\n");
204 }
205 if ( $self->_parent($m) ) {
206 $self->throw("$m already assigned to a parent\n");
207 }
208 push @{$self->{'model'}}, $m;
209 # create a stringified version of our ref
210 # not used untill we get symbolic ref working
211 #my $str_ref = "$self";
212 #$m->_grandparent($str_ref);
213 }
214 }
215 elsif ( $model->isa('Bio::Structure::Model') ) {
216 if ( $self->_parent($model) ) { # already assigned to a parent
217 $self->throw("$model already assigned\n");
218 }
219 push @{$self->{'model'}}, $model;
220 # create a stringified version of our ref
221 #my $str_ref = "$self";
222 #$model->_grandparent($str_ref);
223 }
224 else {
225 $self->throw("Supplied a $model to add_model, we want a Model or list of Models\n");
226 }
227 }
228
229 my $array_ref = $self->{'model'};
230 return $array_ref ? @{$array_ref} : ();
231 }
232
233
234 =head2 get_models()
235
236 Title : get_models
237 Usage : $structure->get_models($structure);
238 Function: general get method for models attached to an Entry
239 Returns : a list of models attached to this entry
240 Args : an Entry
241
242 =cut
243
244 sub get_models {
245 my ($self, $entry) = @_;
246
247 # self and entry can be the same
248 if ( !defined $entry) {
249 $entry = $self;
250 }
251 # pass through to add_model
252 $self->add_model($entry);
253 }
254
255
256
257 =head2 id()
258
259 Title : id
260 Usage : $entry->id("identity");
261 Function: Gets/sets the ID
262 Returns :
263 Args :
264
265 =cut
266
267 sub id {
268 my ($self, $value) = @_;
269 if (defined $value) {
270 $self->{'id'} = $value;
271 }
272 return $self->{'id'};
273 }
274
275
276 =head2 chain()
277
278 Title : chain
279 Usage : @chains = $structure->chain($chain);
280 Function: Connects a (or a list of) Chain objects to a Bio::Structure::Entry.
281 Returns : list of Bio::Structure::Residue objects
282 Args : One Residue or a reference to an array of Residue objects
283
284 =cut
285
286 sub chain {
287 my ($self, $chain) = @_;
288
289 if ( ! $self->model ) {
290 $self->_create_default_model;
291 }
292 my @models = $self->model;
293 my $first_model = $models[0];
294
295 if ( defined $chain) {
296
297 if( (ref($chain) eq "ARRAY") ||
298 ($chain->isa('Bio::Structure::Chain')) ) {
299 # remove existing ones, tell they've become orphan
300 my @obj = $self->get_chains($first_model);
301 if (@obj) {
302 for my $c (@obj) {
303 $self->_remove_from_graph($c);
304 }
305 }
306 # add the new ones
307 $self->add_chain($first_model,$chain);
308 }
309 else {
310 $self->throw("Supplied a $chain to chain, we want a Bio::Structure::Chain or a list of these\n");
311 }
312 }
313 $self->get_chains($first_model);
314 }
315
316
317 =head2 add_chain()
318
319 Title : add_chain
320 Usage : @chains = $structure->add_chain($add_chain);
321 Function: Adds a (or a list of) Chain objects to a Bio::Structure::Entry.
322 Returns :
323 Args :
324
325 =cut
326
327 sub add_chain {
328 my($self, $model, $chain) = @_;
329
330 if (ref($model) !~ /^Bio::Structure::Model/) {
331 $self->throw("add_chain: first argument needs to be a Model object ($model)\n");
332 }
333 if (defined $chain) {
334 if (ref($chain) eq "ARRAY") {
335 # if the user passed in a reference to an array
336 for my $c ( @{$chain} ) {
337 if( ! $c->isa('Bio::Structure::Chain') ) {
338 $self->throw("$c is not a Chain\n");
339 }
340 if ( $self->_parent($c) ) {
341 $self->throw("$c already assigned to a parent\n");
342 }
343 $self->_parent($c, $model);
344 $self->_child($model, $c);
345 # stringify $self ref
346 #my $str_ref = "$self";
347 #$c->_grandparent($str_ref);
348 }
349 }
350 elsif ( $chain->isa('Bio::Structure::Chain') ) {
351 if ( $self->_parent($chain) ) { # already assigned to parent
352 $self->throw("$chain already assigned to a parent\n");
353 }
354 $self->_parent($chain,$model);
355 $self->_child($model, $chain);
356 # stringify $self ref
357 #my $str_ref = "$self";
358 #$chain->_grandparent($str_ref);
359 }
360 else {
361 $self->throw("Supplied a $chain to add_chain, we want a Chain or list of Chains\n");
362 }
363 }
364 my $array_ref = $self->_child($model);
365 return $array_ref ? @{$array_ref} : ();
366 }
367
368
369 =head2 get_chains()
370
371 Title : get_chains
372 Usage : $entry->get_chains($model);
373 Function: general get method for chains attached to a Model
374 Returns : a list of chains attached to this model
375 Args : a Model
376
377 =cut
378
379 sub get_chains {
380 my ($self, $model) = @_;
381
382 if (! defined $model) {
383 $model = ($self->get_models)[0];
384 }
385 # pass through to add_chain
386 $self->add_chain($model);
387 }
388
389
390 =head2 residue()
391
392 Title : residue
393 Usage : @residues = $structure->residue($residue);
394 Function: Connects a (or a list of) Residue objects to a Bio::Structure::Entry.
395 Returns : list of Bio::Structure::Residue objects
396 Args : One Residue or a reference to an array of Residue objects
397
398 =cut
399
400 sub residue {
401 my ($self, $residue) = @_;
402
403 if ( ! $self->model ) {
404 my $m = $self->_create_default_model;
405 $self->add_model($self,$m);
406 }
407 my @models = $self->model;
408 my $first_model = $models[0];
409
410 if ( ! $self->get_chains($first_model) ) {
411 my $c = $self->_create_default_chain;
412 $self->add_chain($first_model, $c);
413 }
414 my @chains = $self->get_chains($first_model);
415 my $first_chain = $chains[0];
416
417 if( defined $residue) {
418 if( (ref($residue) eq "ARRAY") ||
419 ($residue->isa('Bio::Structure::Residue')) ) {
420 # remove existing ones, tell they've become orphan
421 my @obj = $self->get_residues($first_chain);
422 if (@obj) {
423 for my $r (@obj) {
424 $self->_remove_from_graph($r);
425 }
426 }
427 # add the new ones
428 $self->add_residue($first_chain,$residue);
429 }
430 else {
431 $self->throw("Supplied a $residue to residue, we want a Bio::Structure::Residue or a list of these\n");
432 }
433 }
434 $self->get_residues($first_chain);
435 }
436
437
438 =head2 add_residue()
439
440 Title : add_residue
441 Usage : @residues = $structure->add_residue($residue);
442 Function: Adds a (or a list of) Residue objects to a Bio::Structure::Entry.
443 Returns : list of Bio::Structure::Residue objects
444 Args : One Residue or a reference to an array of Residue objects
445
446 =cut
447
448 sub add_residue {
449 my($self,$chain,$residue) = @_;
450
451 if (ref($chain) !~ /^Bio::Structure::Chain/) {
452 $self->throw("add_residue: first argument needs to be a Chain object\n");
453 }
454 if (defined $residue) {
455 if (ref($residue) eq "ARRAY") {
456 # if the user passed in a reference to an array
457 for my $r ( @{$residue} ) {
458 if( ! $r->isa('Bio::Structure::Residue') ) {
459 $self->throw("$r is not a Residue\n");
460 }
461 if ( $self->_parent($r) ) {
462 $self->throw("$r already belongs to a parent\n");
463 }
464 $self->_parent($r, $chain);
465 $self->_child($chain, $r);
466 # stringify
467 my $str_ref = "$self";
468 $r->_grandparent($str_ref);
469 }
470 }
471 elsif ( $residue->isa('Bio::Structure::Residue') ) {
472 if ( $self->_parent($residue) ) {
473 $self->throw("$residue already belongs to a parent\n");
474 }
475 $self->_parent($residue, $chain);
476 $self->_child($chain, $residue);
477 # stringify
478 my $str_ref = "$self";
479 $residue->_grandparent($str_ref);
480 }
481 else {
482 $self->throw("Supplied a $residue to add_residue, we want a Residue or list of Residues\n");
483 }
484 }
485 my $array_ref = $self->_child($chain);
486 return $array_ref ? @{$array_ref} : ();
487 }
488
489
490 =head2 get_residues()
491
492 Title : get_residues
493 Usage : $structure->get_residues($chain);
494 Function: general get method for residues attached to a Chain
495 Returns : a list of residues attached to this chain
496 Args : a chain
497
498 =cut
499
500 sub get_residues {
501 my ($self, $chain) = @_;
502
503 if ( !defined $chain) {
504 $self->throw("get_residues needs a Chain as argument");
505 }
506 # pass through to add_residue
507 $self->add_residue($chain);
508 }
509
510
511 =head2 add_atom()
512
513 Title : add_atom
514 Usage : @atoms = $structure->add_atom($residue,$atom);
515 Function: Adds a (or a list of) Atom objects to a Bio::Structure::Residue.
516 Returns : list of Bio::Structure::Atom objects
517 Args : a residue and an atom
518
519 =cut
520
521 sub add_atom {
522 my($self,$residue,$atom) = @_;
523
524 if (ref($residue) !~ /^Bio::Structure::Residue/) {
525 $self->throw("add_atom: first argument needs to be a Residue object\n");
526 }
527 if (defined $atom) {
528 if (ref($atom) eq "ARRAY") {
529 # if the user passed in a reference to an array
530 for my $a ( @{$atom} ) {
531 if( ! $a->isa('Bio::Structure::Atom') ) {
532 $self->throw("$a is not an Atom\n");
533 }
534 if ( $self->_parent($a) ) {
535 $self->throw("$a already belongs to a parent\n");
536 }
537 $self->_parent($a, $residue);
538 $self->_child($residue, $a);
539 # stringify
540 #my $str_ref = "$self";
541 #$r->_grandparent($str_ref);
542 }
543 }
544 #elsif ( $atom->isa('Bio::Structure::Atom') ) {
545 elsif ( ref($atom) =~ /^Bio::Structure::Atom/ ) {
546 if ( $self->_parent($atom) ) {
547 $self->throw("$atom already belongs to a parent\n");
548 }
549 $self->_parent($atom, $residue);
550 $self->_child($residue, $atom);
551 # stringify
552 #my $str_ref = "$self";
553 #$atom->_grandparent($str_ref);
554 }
555 }
556 my $array_ref = $self->_child($residue);
557 return $array_ref ? @{$array_ref} : ();
558 }
559
560
561 =head2 get_atoms()
562
563 Title : get_atoms
564 Usage : $structure->get_atoms($residue);
565 Function: general get method for atoms attached to a Residue
566 Returns : a list of atoms attached to this residue
567 Args : a residue
568
569 =cut
570
571 sub get_atoms {
572 my ($self, $residue) = @_;
573
574 if ( !defined $residue) {
575 $self->throw("get_atoms needs a Residue as argument");
576 }
577 # pass through to add_atom
578 $self->add_atom($residue);
579 }
580
581
582 =head2 parent()
583
584 Title : parent
585 Usage : $structure->parent($residue);
586 Function: returns the parent of the argument
587 Returns : the parent of the argument
588 Args : a Bio::Structure object
589
590 =cut
591
592 =head2 conect()
593
594 Title : conect
595 Usage : $structure->conect($source);
596 Function: get/set method for conect
597 Returns : a list of serial numbers for atoms connected to source
598 (together with $entry->get_atom_by_serial($model, $serial) this should be OK for now)
599 Args : the serial number for the source atom
600
601 =cut
602
603 sub conect {
604 my ($self, $source, $serial, $type) = @_;
605
606 if ( !defined $source ) {
607 $self->throw("You need to supply at least a source to conect");
608 }
609 if ( defined $serial && defined $type ) {
610 if ( !exists(${$self->{'conect'}}{$source}) || ref(${$self->{'conect'}}{$source} !~ /^ARRAY/ ) ) {
611 ${$self->{'conect'}}{$source} = [];
612 }
613 # we also need to store type, a conect object might be better
614 my $c = $serial . "_" . $type;
615 push @{ ${$self->{'conect'}}{$source} }, $c;
616 }
617 return @{ ${$self->{'conect'}}{$source} };
618 }
619
620 =head2 get_all_conect_source()
621
622 Title : get_all_conect_source
623 Usage : @sources = $structure->get_all_conect_source;
624 Function: get all the sources for the conect records
625 Returns : a list of serial numbers for atoms connected to source
626 (together with $entry->get_atom_by_serial($model, $serial) this should be OK for now)
627 Args :
628 Description : This is a bit of a kludge, but it's the best for now. Conect info might need
629 to go in a sepearte object
630
631 =cut
632
633 sub get_all_conect_source {
634 my ($self) = shift;
635 my (@sources);
636
637 for my $source (sort {$a<=>$b} keys %{$self->{'conect'}}) {
638 push @sources, $source;
639 }
640 return @sources;
641 }
642
643
644 =head2 master()
645
646 Title : master
647 Usage : $structure->master($source);
648 Function: get/set method for master
649 Returns : the master line
650 Args : the master line for this entry
651
652 =cut
653
654 sub master {
655 my ($self, $value) = @_;
656 if (defined $value) {
657 $self->{'master'} = $value;
658 }
659 return $self->{'master'};
660 }
661
662
663 =head2 seqres()
664
665 Title : seqres
666 Usage : $seqobj = $structure->seqres("A");
667 Function: gets a sequence object containing the sequence from the SEQRES record.
668 if a chain-ID is given , the sequence for this chain is given, if none
669 is provided the first chain is choosen
670 Returns : a Bio::PrimarySeq
671 Args : the chain-ID of the chain you want the sequence from
672
673 =cut
674
675 sub seqres {
676 my ($self, $chainid) = @_;
677 my $s_u = "x3 A1 x7 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3 x1 A3";
678 my (%seq_ch);
679 if ( !defined $chainid) {
680 my $m = ($self->get_models($self))[0];
681 my $c = ($self->get_chains($m))[0];
682 $chainid = $c->id;
683 }
684 my $seqres = ($self->annotation->get_Annotations("seqres"))[0];
685 my $seqres_string = $seqres->as_text;
686 $self->debug("seqres : $seqres_string\n");
687 $seqres_string =~ s/^Value: //;
688 # split into lines of 62 long
689 my @l = unpack("A62" x (length($seqres_string)/62), $seqres_string);
690 for my $line (@l) {
691 # get out chain_id and sequence
692 # we use a1, as A1 strips all spaces :(
693 my ($chid, $seq) = unpack("x3 a1 x7 A51", $line);
694 if ($chid eq " ") {
695 $chid = "default";
696 }
697 $seq =~ s/(\w+)/\u\L$1/g; # ALA -> Ala (for SeqUtils)
698 $seq =~ s/\s//g; # strip all spaces
699 $seq_ch{$chid} .= $seq;
700 $self->debug("seqres : $chid $seq_ch{$chid}\n");
701 }
702 # do we have a seqres for this chainid
703 if(! exists $seq_ch{$chainid} ) {
704 $self->warn("There is no SEQRES known for chainid \"$chainid\"");
705 return undef;
706 }
707
708 # this will break for non-protein structures (about 10% for now) XXX KB
709 my $pseq = Bio::PrimarySeq->new(-alphabet => 'protein');
710 $pseq = Bio::SeqUtils->seq3in($pseq,$seq_ch{$chainid});
711 my $id = $self->id . "_" . $chainid;
712 $pseq->id($id);
713 return $pseq;
714 }
715
716 =head2 get_atom_by_serial()
717
718 Title : get_atom_by_serial
719 Usage : $structure->get_atom_by_serial($module, $serial);
720 Function: get the Atom for a for get_atom_by_serial
721 Returns : the Atom object with this serial number in the model
722 Args : Model on which to work, serial number for atom
723 (if only a number is supplied, the first model is chosen)
724
725 =cut
726
727 sub get_atom_by_serial {
728 my ($self, $model, $serial) = @_;
729
730 if ($model =~ /^\d+$/ && !defined $serial) { # only serial given
731 $serial = $model;
732 my @m = $self->get_models($self);
733 $model = $m[0];
734 }
735 if ( !defined $model || ref($model) !~ /^Bio::Structure::Model/ ) {
736 $self->throw("Could not find (first) model\n");
737 }
738 if ( !defined $serial || ($serial !~ /^\d+$/) ) {
739 $self->throw("The serial number you provided looks fishy ($serial)\n");
740 }
741 for my $chain ($self->get_chains($model) ) {
742 for my $residue ($self->get_residues($chain) ) {
743 for my $atom ($self->get_atoms($residue) ) {
744 # this could get expensive, do we cache ???
745 next unless ($atom->serial == $serial);
746 return $atom;
747 }
748 }
749 }
750 }
751
752 sub parent {
753 my ($self, $obj) = @_;
754
755 if ( !defined $obj) {
756 $self->throw("parent: you need to supply an argument to get the parent from\n");
757 }
758
759 # for now we pass on to _parent, untill we get the symbolic ref thing working.
760 $self->_parent($obj);
761 }
762
763 sub DESTROY {
764 my $self = shift;
765
766 #print STDERR "DESTROY on $self being called\n";
767
768 ## for my $pc (keys %{ $self->{'p_c'} } ) {
769 ## next unless ( defined ${ $self->{'p_c'} }{$pc} );
770 ## delete ${$self->{'p_c'}}{$pc};
771 ## }
772 ## for my $cp (keys %{ $self->{'c_p'} } ) {
773 ## next unless ( defined ${ $self->{'c_p'} }{$cp} );
774 ## delete ${$self->{'c_p'}}{$cp};
775 ## }
776 %{ $self->{'p_c'} } = ();
777 %{ $self->{'c_p'} } = ();
778 }
779
780 # copied from Bio::Seq.pm
781 #
782 =head2 annotation
783
784 Title : annotation
785 Usage : $obj->annotation($seq_obj)
786 Function:
787 Example :
788 Returns : value of annotation
789 Args : newvalue (optional)
790
791
792 =cut
793
794 sub annotation {
795 my ($obj,$value) = @_;
796 if( defined $value) {
797 $obj->{'annotation'} = $value;
798 }
799 return $obj->{'annotation'};
800
801 }
802
803
804 #
805 # from here on only private methods
806 #
807
808 =head2 _remove_models()
809
810 Title : _remove_models
811 Usage :
812 Function: Removes the models attached to an Entry. Tells the models they
813 don't belong to this Entry any more
814 Returns :
815 Args :
816
817 =cut
818
819 #'
820
821 sub _remove_models {
822 my ($self) = shift;
823
824 ;
825 }
826
827
828 =head2 _create_default_model()
829
830 Title : _create_default_model
831 Usage :
832 Function: Creates a default Model for this Entry. Typical situation
833 in an X-ray structure where there is only one model
834 Returns :
835 Args :
836
837 =cut
838
839 sub _create_default_model {
840 my ($self) = shift;
841
842 my $model = Bio::Structure::Model->new(-id => "default");
843 return $model;
844 }
845
846
847 =head2 _create_default_chain()
848
849 Title : _create_default_chain
850 Usage :
851 Function: Creates a default Chain for this Model. Typical situation
852 in an X-ray structure where there is only one chain
853 Returns :
854 Args :
855
856 =cut
857
858 sub _create_default_chain {
859 my ($self) = shift;
860
861 my $chain = Bio::Structure::Chain->new(-id => "default");
862 return $chain;
863 }
864
865
866
867 =head2 _parent()
868
869 Title : _parent
870 Usage : This is an internal function only. It is used to have one
871 place that keeps track of which object has which other object
872 as parent. Thus allowing the underlying modules (Atom, Residue,...)
873 to have no knowledge about all this (and thus removing the possibility
874 of reference cycles).
875 This method hides the details of manipulating references to an anonymous
876 hash.
877 Function: To get/set an objects parent
878 Returns : a reference to the parent if it exist, undef otherwise. In the
879 current implementation each node should have a parent (except Entry).
880 Args :
881
882 =cut
883
884 # manipulating the c_p hash
885
886 sub _parent {
887 no strict "refs";
888 my ($self, $key, $value) = @_;
889
890 if ( (!defined $key) || (ref($key) !~ /^Bio::/) ) {
891 $self->throw("First argument to _parent needs to be a reference to a Bio:: object ($key)\n");
892 }
893 if ( (defined $value) && (ref($value) !~ /^Bio::/) ) {
894 $self->throw("Second argument to _parent needs to be a reference to a Bio:: object\n");
895 }
896 # no checking here for consistency of key and value, needs to happen in caller
897
898 if (defined $value) {
899 # is this value already in, shout
900 if (defined ( $self->{'c_p'}->{$key}) &&
901 exists ( $self->{'c_p'}->{$key})
902 ) {
903 $self->throw("_parent: $key already has a parent ${$self->{'c_p'}}{$key}\n");
904 }
905 ${$self->{'c_p'}}{$key} = $value;
906 }
907 return ${$self->{'c_p'}}{$key};
908 }
909
910
911 =head2 _child()
912
913 Title : _child
914 Usage : This is an internal function only. It is used to have one
915 place that keeps track of which object has which other object
916 as child. Thus allowing the underlying modules (Atom, Residue,...)
917 to have no knowledge about all this (and thus removing the possibility
918 to have no knowledge about all this (and thus removing the possibility
919 of reference cycles).
920 This method hides the details of manipulating references to an anonymous
921 hash.
922 Function: To get/set an object's child(ren)
923 Returns : a reference to an array of child(ren) if it exist, undef otherwise.
924 Args :
925
926 =cut
927
928 # manipulating the p_c hash
929 sub _child {
930 my ($self, $key, $value) = @_;
931
932 if ( (!defined $key) || (ref($key) !~ /^Bio::/) ) {
933 $self->throw("First argument to _child needs to be a reference to a Bio:: object\n");
934 }
935 if ( (defined $value) && (ref($value) !~ /^Bio::/) ) {
936 $self->throw("Second argument to _child needs to be a reference to a Bio:: object\n");
937 }
938 # no checking here for consistency of key and value, needs to happen in caller
939
940 if (defined $value) {
941 if ( !exists(${$self->{'p_c'}}{$key}) || ref(${$self->{'p_c'}}{$key}) !~ /^ARRAY/ ) {
942 ${$self->{'p_c'}}{$key} = [];
943 }
944 push @{ ${$self->{'p_c'}}{$key} }, $value;
945 }
946 return ${$self->{'p_c'}}{$key};
947 }
948
949
950
951 =head2 _remove_from_graph()
952
953 Title : _remove_from_graph
954 Usage : This is an internal function only. It is used to remove from
955 the parent/child graph. We only remove the links from object to
956 his parent. Not the ones from object to its children.
957 Function: To remove an object from the parent/child graph
958 Returns :
959 Args : the object to be orphaned
960
961 =cut
962
963 sub _remove_from_graph {
964 my ($self, $object) = @_;
965
966 if ( !defined($object) && ref($object) !~ /^Bio::/) {
967 $self->throw("_remove_from_graph needs a Bio object as argument");
968 }
969 if ( $self->_parent($object) ) {
970 my $dad = $self->_parent($object);
971 # if we have a parent, remove me as being a child
972 for my $k (0 .. $#{$self->_child($dad)}) {
973 if ($object eq ${$self->{'p_c'}{$dad}}[$k]) {
974 splice(@{$self->{'p_c'}{$dad}}, $k,1);
975 }
976 }
977 delete( $self->{'c_p'}{$object});
978 }
979 }
980
981
982 sub _print_stats_pc {
983 # print stats about the parent/child hashes
984 my ($self) =@_;
985 my $pc = scalar keys %{$self->{'p_c'}};
986 my $cp = scalar keys %{$self->{'c_p'}};
987 my $now_time = Time::HiRes::time();
988 $self->debug("pc stats: P_C $pc C_P $cp $now_time\n");
989 }
990
991
992 1;