ProteinFeatureAdaptor.pm 11.3 KB
Newer Older
1
=head1 LICENSE
2

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Copyright [1999-2013] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=cut
18 19 20 21 22 23



=head1 CONTACT

  Please email comments or questions to the public Ensembl
Magali Ruffier's avatar
Magali Ruffier committed
24
  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
25 26

  Questions may also be sent to the Ensembl help desk at
Magali Ruffier's avatar
Magali Ruffier committed
27
  <http://www.ensembl.org/Help/Contact>.
28 29

=cut
30 31 32

=head1 NAME

33
Bio::EnsEMBL::DBSQL::ProteinFeatureAdaptor
34 35 36

=head1 SYNOPSIS

37 38 39
  use Bio::EnsEMBL::Registry;

  Bio::EnsEMBL::Registry->load_registry_from_db(
40 41
    -host => 'ensembldb.ensembl.org',
    -user => 'anonymous'
42 43
  );

44 45
  $pfa = Bio::EnsEMBL::Registry->get_adaptor( "human", "core",
    "proteinfeature" );
46

47
  my @prot_feats = @{ $pfa->fetch_all_by_translation_id(1231) };
48

49
  my $prot_feat = $pfa->fetch_by_dbID(523);
50

51
=head1 METHODS
52 53 54

=cut

55
package Bio::EnsEMBL::DBSQL::ProteinFeatureAdaptor;
56 57 58 59

use strict;

use Bio::EnsEMBL::DBSQL::BaseAdaptor;
60
use Bio::EnsEMBL::ProteinFeature;
61
use Bio::EnsEMBL::Utils::Exception qw(throw deprecate warning);
62

63 64
use vars qw(@ISA);
@ISA = qw(Bio::EnsEMBL::DBSQL::BaseAdaptor);
65

66
=head2 fetch_all_by_translation_id
67

68 69 70
  Arg [1]    : int $transl
               the internal id of the translation corresponding to protein 
               whose features are desired 
71 72
  Example    : @prot_feats =
                  @{ $prot_feat_adaptor->fetch_by_translation_id(1234) };
73 74 75 76 77
  Description: Gets all protein features present on a peptide using the
               translations internal identifier.  This method will return
               an unsorted list of all protein_feature types.  The feature
               types may be distinguished using the logic name attribute of
               the attached analysis objects.   
Graham McVicker's avatar
Graham McVicker committed
78
  Returntype : listref of Bio::EnsEMBL::ProteinFeatures
79 80
  Exceptions : none
  Caller     : ?
81
  Status     : Stable
82 83 84

=cut

85
sub fetch_all_by_translation_id {
86
  my ($self, $translation_id) = @_;
87

88 89
  if (!$translation_id) {
	throw("translation_id argument is required\n");
90
  }
91 92 93

  my @features;
  my $analysis_adaptor = $self->db()->get_AnalysisAdaptor();
94

95
  my $sth = $self->prepare("SELECT protein_feature_id, p.seq_start, p.seq_end, p.analysis_id, " . "       p.score, p.perc_ident, p.evalue, p.hit_start, p.hit_end, " . "       p.hit_name, p.hit_description, x.display_label, i.interpro_ac " . "FROM   protein_feature p " . "LEFT JOIN interpro AS i ON p.hit_name = i.id " . "LEFT JOIN xref AS x ON x.dbprimary_acc = i.interpro_ac " . "WHERE p.translation_id = ?");
96 97

  $sth->bind_param(1, $translation_id, SQL_INTEGER);
98
  $sth->execute();
99

100
  while (my $row = $sth->fetchrow_arrayref) {
101
	my ($dbID, $start, $end, $analysisid, $score, $perc_id, $evalue, $hstart, $hend, $hid, $hdesc, $desc, $interpro_ac) = @$row;
102 103 104 105 106 107 108

	my $analysis = $analysis_adaptor->fetch_by_dbID($analysisid);

	if (!$analysis) {
	  warning("Analysis with dbID=$analysisid does not exist\n" . "but is referenced by ProteinFeature $dbID");
	}

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
	my $feat = Bio::EnsEMBL::ProteinFeature->new(-DBID         => $dbID,
												 -ADAPTOR      => $self,
												 -SEQNAME      => $translation_id,
												 -START        => $start,
												 -END          => $end,
												 -ANALYSIS     => $analysis,
												 -PERCENT_ID   => $perc_id,
												 -P_VALUE      => $evalue,
												 -SCORE        => $score,
												 -HSTART       => $hstart,
												 -HEND         => $hend,
												 -HSEQNAME     => $hid,
												 -HDESCRIPTION => $hdesc,
												 -IDESC        => $desc,
												 -INTERPRO_AC  => $interpro_ac);
124 125 126

	push(@features, $feat);
  } ## end while (my $row = $sth->fetchrow_arrayref)
127

128
  $sth->finish();
129

130 131
  return \@features;
} ## end sub fetch_all_by_translation_id
132

133
=head2 fetch_by_dbID
134

135 136 137 138 139 140 141
  Arg [1]    : int $protfeat_id
               the unique database identifier of the protein feature to obtain
  Example    : my $feature = $prot_feat_adaptor->fetch_by_dbID();
  Description: Obtains a protein feature object via its unique id
  Returntype : Bio::EnsEMBL::ProteinFeauture
  Exceptions : none
  Caller     : ?
142
  Status     : Stable
143 144 145

=cut

146 147 148 149 150 151
sub fetch_by_dbID {
  my ($self, $protfeat_id) = @_;

  my $sth = $self->prepare("SELECT p.seq_start, p.seq_end, p.analysis_id, " . "       p.score, p.perc_ident, p.evalue, " . "       p.hit_start, p.hit_end, p.hit_name, " . "       x.display_label, i.interpro_ac " . "FROM   protein_feature p " . "LEFT JOIN interpro AS i ON p.hit_name = i.id " . "LEFT JOIN xref AS x ON x.dbprimary_acc = i.interpro_ac " . "WHERE  p.protein_feature_id = ?");

  $sth->bind_param(1, $protfeat_id, SQL_INTEGER);
152
  my $res = $sth->execute();
153 154 155 156

  if ($sth->rows == 0) {
	$sth->finish();
	return undef;
157
  }
158

159
  my ($start, $end, $analysis_id, $score, $perc_ident, $pvalue, $hstart, $hend, $hseqname, $idesc, $interpro_ac) = $sth->fetchrow_array();
160 161 162 163 164

  $sth->finish();

  my $analysis = $self->db->get_AnalysisAdaptor->fetch_by_dbID($analysis_id);

165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
  return
	Bio::EnsEMBL::ProteinFeature->new(-ADAPTOR     => $self,
									  -DBID        => $protfeat_id,
									  -START       => $start,
									  -END         => $end,
									  -HSTART      => $hstart,
									  -HEND        => $hend,
									  -HSEQNAME    => $hseqname,
									  -ANALYSIS    => $analysis,
									  -SCORE       => $score,
									  -P_VALUE     => $pvalue,
									  -PERCENT_ID  => $perc_ident,
									  -IDESC       => $idesc,
									  -INTERPRO_AC => $interpro_ac);
} ## end sub fetch_by_dbID
180

181
=head2 store
182

183
  Arg [1]    : Bio::EnsEMBL::ProteinFeature $feature
184 185 186
               The feature to be stored
  Arg [2]    : int $translation_id
            
187 188
  Example    : $protein_feature_adaptor->store($protein_feature);
  Description: Stores a protein feature in the database
189 190
  Returntype : int - the new internal identifier of the stored protein feature
  Exceptions : thrown if arg is not a Bio::EnsEMBL:
191
  Caller     : none
192
  Status     : Stable
193 194 195

=cut

196
sub store {
197
  my ($self, $feature, $translation_id) = @_;
198

199 200
  if (!ref($feature) || !$feature->isa('Bio::EnsEMBL::ProteinFeature')) {
	throw("ProteinFeature argument is required");
201
  }
Emmanuel Mongin's avatar
Emmanuel Mongin committed
202

203 204 205
  if (!$translation_id) {
	deprecate("Calling ProteinFeatureAdaptor without a translation_id is " . "deprecated.  Pass a translation_id argument rather than " . "setting the ProteinFeature seqname to be the translation " . "id");
	$translation_id = $feature->seqname();
206
  }
207

208
  my $db = $self->db();
209

210 211
  if ($feature->is_stored($db)) {
	warning("ProteinFeature " . $feature->dbID() . " is already stored in " . "this database - not storing again");
212
  }
213

214 215
  my $analysis = $feature->analysis();
  if (!defined($analysis)) {
216
	throw("Feature doesn't have analysis. Can't write to database");
217
  }
218 219
  if (!$analysis->is_stored($db)) {
	$db->get_AnalysisAdaptor->store($analysis);
220
  }
221

222
  my $sth = $self->prepare("INSERT INTO protein_feature " . "        SET translation_id  = ?, " . "            seq_start       = ?, " . "            seq_end         = ?, " . "            analysis_id     = ?, " . "            hit_start       = ?, " . "            hit_end         = ?, " . "            hit_name        = ?, " . "            hit_description = ?, " . "            score           = ?, " . "            perc_ident      = ?, " . "            evalue          = ?");
223

224 225 226 227 228 229 230 231 232 233 234
  $sth->bind_param(1,  $translation_id,        SQL_INTEGER);
  $sth->bind_param(2,  $feature->start,        SQL_INTEGER);
  $sth->bind_param(3,  $feature->end,          SQL_INTEGER);
  $sth->bind_param(4,  $analysis->dbID,        SQL_INTEGER);
  $sth->bind_param(5,  $feature->hstart,       SQL_INTEGER);
  $sth->bind_param(6,  $feature->hend,         SQL_INTEGER);
  $sth->bind_param(7,  $feature->hseqname,     SQL_VARCHAR);
  $sth->bind_param(8,  $feature->hdescription, SQL_LONGVARCHAR);
  $sth->bind_param(9,  $feature->score,        SQL_DOUBLE);
  $sth->bind_param(10, $feature->percent_id,   SQL_FLOAT);
  $sth->bind_param(11, $feature->p_value,      SQL_DOUBLE);
235 236

  $sth->execute();
237

238
  my $dbID = $sth->{'mysql_insertid'};
239

240 241
  $feature->adaptor($self);
  $feature->dbID($dbID);
242

243
  $sth->finish();
244

245 246
  return $dbID;
} ## end sub store
247

248 249 250
sub fetch_by_translation_id {
  deprecate("Use fetch_all_by_translation_id instead.");
  fetch_all_by_translation_id(@_);
251 252
}

253
sub fetch_all_by_feature_and_dbID {
254 255
  my $self           = shift;
  my $feature        = shift;
256 257
  my $translation_id = shift;
  deprecate("Use fetch_all_by_translation_id instead.");
258

259
  print STDERR "translation_id = $translation_id feature = $feature\n";
260

261
  my $features = $self->fetch_all_by_translation_id($translation_id);
262

263 264
  my @out;
  foreach my $f (@$features) {
265 266 267
	my $logic_name = lc($f->analysis->logic_name());
	print STDERR "LOGIC_NAME = $logic_name | FEATURE = $feature\n";
	push(@out, $f) if ($logic_name eq lc($feature));
268
  }
269

270 271
  return \@out;
}
272

273
sub save {
274

275 276 277
  my ($self, $features) = @_;

  my @feats = @$features;
278
  throw("Must call save with features") if (scalar(@feats) == 0);
279

280 281
  #  my @tabs = $self->_tables;
  #  my ($tablename) = @{$tabs[0]};
282 283
  my $tablename = 'protein_feature';

284
  my $db               = $self->db();
285 286
  my $analysis_adaptor = $db->get_AnalysisAdaptor();

287
  my $sql = qq{INSERT INTO $tablename (translation_id, seq_start, seq_end, hit_start, hit_end, hit_name, hdescription, analysis_id, score, evalue, perc_ident, external_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)};
288 289 290

  my $sth = $self->prepare($sql);

291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
  foreach my $feat (@feats) {
	if (!ref $feat || !$feat->isa("Bio::EnsEMBL::ProteinFeature")) {
	  throw("feature must be a Bio::EnsEMBL::ProteinFeature," . " not a [" . ref($feat) . "].");
	}

	if ($feat->is_stored($db)) {
	  warning("ProteinFeature [" . $feat->dbID . "] is already stored" . " in this database.");
	  next;
	}

	my $hstart = defined $feat->hstart ? $feat->hstart : $feat->start;
	my $hend   = defined $feat->hend   ? $feat->hend   : $feat->end;

	if (!defined($feat->analysis)) {
	  throw("An analysis must be attached to the features to be stored.");
	}

	#store the analysis if it has not been stored yet
	if (!$feat->analysis->is_stored($db)) {
	  $analysis_adaptor->store($feat->analysis());
	}

	my $original = $feat;
	my $extra_data = $feat->extra_data ? $self->dump_data($feat->extra_data) : '';

	$sth->bind_param(1,  $feat->translation_id, SQL_INTEGER);
	$sth->bind_param(2,  $feat->start,          SQL_INTEGER);
	$sth->bind_param(3,  $feat->end,            SQL_INTEGER);
	$sth->bind_param(4,  $hstart,               SQL_INTEGER);
	$sth->bind_param(5,  $hend,                 SQL_INTEGER);
	$sth->bind_param(6,  $feat->hseqname,       SQL_VARCHAR);
322 323 324 325 326 327
	$sth->bind_param(7,  $feat->hdescription,   SQL_LONGVARCHAR);
	$sth->bind_param(8,  $feat->analysis->dbID, SQL_INTEGER);
	$sth->bind_param(9,  $feat->score,          SQL_DOUBLE);
	$sth->bind_param(10, $feat->p_value,        SQL_DOUBLE);
	$sth->bind_param(11, $feat->percent_id,     SQL_FLOAT);
	$sth->bind_param(12, $extra_data,           SQL_LONGVARCHAR);
328 329 330 331 332

	$sth->execute();
	$original->dbID($sth->{'mysql_insertid'});
	$original->adaptor($self);
  } ## end foreach my $feat (@feats)
333

334 335
  $sth->finish();
} ## end sub save
336

337
1;
338