QualityAssessModel.pm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package QualityAssessModel;
  2. ## assesses a 3d model built from the templates in 'tList' based on hhsearch posterior probabilities
  3. ## for each query residue take the max. posterior probability over all templates as a quality measure
  4. use strict;
  5. use TemplateList;
  6. use Template;
  7. use utilities;
  8. use vars qw($AUTOLOAD);
  9. use Carp;
  10. {
  11. my %_attr_data = # DEFAULT ACCESS
  12. (
  13. _tList => ['###', 'read/write'],
  14. _outbase => ['###', 'read/write'],
  15. _pdbFile => ['###', 'read/write'],
  16. );
  17. sub _accessible {
  18. my ($self, $attr, $mode) = @_;
  19. $_attr_data{$attr}[1] =~ /$mode/;
  20. }
  21. sub _default_for {
  22. my ($self, $attr) = @_;
  23. $_attr_data{$attr}[0];
  24. }
  25. sub _standard_keys {
  26. keys %_attr_data;
  27. }
  28. }
  29. ## constructor
  30. sub new {
  31. my ($caller, %arg) = @_;
  32. my $caller_is_obj = ref($caller);
  33. my $class = $caller_is_obj || $caller;
  34. my $self = bless {}, $class;
  35. foreach my $attrname ($self->_standard_keys() ) {
  36. my ($argname) = ($attrname =~ /^_(.*)/);
  37. if (exists $arg{$argname}) {
  38. $self->{$attrname} = $arg{$argname};
  39. } elsif ($caller_is_obj) {
  40. $self->{$attrname} = $caller->{$attrname};
  41. } else {
  42. $self->{$attrname} = $self->_default_for($attrname);
  43. }
  44. }
  45. return $self;
  46. }
  47. ## automatically generated getters and setters:
  48. ## $AUTOLOAD contains full name of a routine and is checked for name/accessiblity
  49. ## then an anonymous routine (names e.g. get_name) is created and stored
  50. ## in table for future use
  51. sub AUTOLOAD {
  52. no strict "refs";
  53. my ($self, $newval) = @_;
  54. if ($AUTOLOAD =~ /.*::get(_\w+)/ && $self->_accessible($1, 'read')) {
  55. my $attr_name = $1;
  56. *{$AUTOLOAD} = sub { return $_[0]->{$attr_name} };
  57. return $self->{$attr_name}
  58. }
  59. if ($AUTOLOAD =~ /.*::set(_\w+)/ && $self->_accessible($1, 'write')) {
  60. my $attr_name = $1;
  61. *{$AUTOLOAD} = sub { $_[0]->{$attr_name} = $_[1]; return };
  62. $self->{$1} = $newval;
  63. return
  64. }
  65. ## mistaken?
  66. croak("No such method: $AUTOLOAD");
  67. }
  68. sub DESTROY {
  69. }
  70. sub run {
  71. my $self = shift;
  72. my $pos = shift;
  73. my @templatePPs;
  74. ## generate all posteriors for all templates
  75. for (my $i=0; $i<$self->get_tList()->size(); $i++) {
  76. my $tabFile = $self->get_outbase() . "." . $self->get_tList()->get($i)->get_Filt() . ".tab";
  77. my %PP = &PosteriorsFromTabFile( $tabFile, $self->get_tList()->get($i)->get_No() );
  78. push (@templatePPs, \%PP);
  79. }
  80. ## find maximum pp for each query residue
  81. my @maxPP = (0) x $self->get_tList()->get_queryLength();
  82. for (my $i=0; $i<@maxPP; $i++) {
  83. for (my $j=0; $j<@templatePPs; $j++) {
  84. if (exists($templatePPs[$j]->{$i})) {
  85. $maxPP[$i] = &max($maxPP[$i], $templatePPs[$j]->{$i});
  86. }
  87. }
  88. }
  89. ## write result in pdb file
  90. my $pdbFile = $self->get_pdbFile();
  91. open(PDB, "< $pdbFile");
  92. my @pdb = <PDB>;
  93. close(PDB);
  94. my $maxDisplacement = 100;
  95. my $minDisplacement = 5;
  96. # ATOM 1 N SER A 2 31.507 77.672 34.913 1.00 39.58 N
  97. for (my $i=0; $i<@pdb; $i++) {
  98. if ($pdb[$i] =~ /^ATOM\s+\S+\s+\S+\s+\S+\s+(\d+)/) {
  99. my $residue = $1;
  100. my $temperatureFactor = $maxDisplacement - $maxPP[$residue-1]*$maxPP[$residue-1] * ($maxDisplacement - $minDisplacement);
  101. $temperatureFactor = sprintf("%6.2f", $temperatureFactor);
  102. $pdb[$i] =~ s/(.{60})(.{6})(.*)/$1$temperatureFactor$3/;
  103. }
  104. }
  105. open(PDB, "> $pdbFile");
  106. print (PDB @pdb);
  107. close(PDB);
  108. }