Bio::EnsEMBL::DBSQL::Funcgen::RegulatoryFeatureAdaptor - A database adaptor for fetching and
storing RegulatoryFeature objects.
sub _objs_from_sth
{ my ($self, $sth, $mapper, $dest_slice) = @_;
my ($sa, $reg_feat); $sa = ($dest_slice) ? $dest_slice->adaptor->db->get_SliceAdaptor() : $self->db->get_SliceAdaptor();
my $ft_adaptor = $self->db->get_FeatureTypeAdaptor();
my $fset_adaptor = $self->db->get_FeatureSetAdaptor();
my (@features, @reg_attrs, $seq_region_id);
my (%fset_hash, %slice_hash, %sr_name_hash, %sr_cs_hash, %ftype_hash);
my $skip_feature = 0;
my %feature_adaptors = (
'annotated' => $self->db->get_AnnotatedFeatureAdaptor(),
);
my (
$dbID, $efg_seq_region_id,
$seq_region_start, $seq_region_end,
$seq_region_strand, $bound_seq_region_start,
$bound_seq_region_end, $display_label,
$ftype_id, $fset_id,
$stable_id, $attr_id,
$attr_type
);
$sth->bind_columns(\$
dbID,\$ efg_seq_region_id,\$
seq_region_start,\$ seq_region_end,\$
seq_region_strand,\$ bound_seq_region_start,\$
bound_seq_region_end,\$ display_label,\$
ftype_id,\$ fset_id,\$
stable_id,\$ attr_id,\$
attr_type
);
my ($asm_cs, $cmp_cs, $asm_cs_name);
my ($asm_cs_vers, $cmp_cs_name, $cmp_cs_vers);
if ($mapper) {
$asm_cs = $mapper->assembled_CoordSystem();
$cmp_cs = $mapper->component_CoordSystem();
$asm_cs_name = $asm_cs->name();
$asm_cs_vers = $asm_cs->version();
$cmp_cs_name = $cmp_cs->name();
$cmp_cs_vers = $cmp_cs->version();
}
my ($dest_slice_start, $dest_slice_end);
my ($dest_slice_strand, $dest_slice_length, $dest_slice_sr_name);
if ($dest_slice) {
$dest_slice_start = $dest_slice->start();
$dest_slice_end = $dest_slice->end();
$dest_slice_strand = $dest_slice->strand();
$dest_slice_length = $dest_slice->length();
$dest_slice_sr_name = $dest_slice->seq_region_name();
}
my $slice;
FEATURE: while ( $sth->fetch() ) {
if(! $reg_feat || ($reg_feat->dbID != $dbID)){
if($skip_feature){
undef $reg_feat; $skip_feature = 0;
}
if($reg_feat){
$reg_feat->regulatory_attributes(\@reg_attrs); push @features, $reg_feat;
undef @reg_attrs;
}
$bound_seq_region_start = undef if ! $bound_seq_region_start;
$bound_seq_region_end = undef if ! $bound_seq_region_end;
$seq_region_id = $self->get_core_seq_region_id($efg_seq_region_id);
if(! $seq_region_id){
warn "Cannot get slice for eFG seq_region_id $efg_seq_region_id\n".
"The region you are using is not present in the current dna DB";
next;
}
$fset_hash{$fset_id} = $fset_adaptor->fetch_by_dbID($fset_id) if(! exists $fset_hash{$fset_id});
$slice = $slice_hash{'ID:'.$seq_region_id};
if (!$slice) {
$slice = $sa->fetch_by_seq_region_id($seq_region_id);
$slice_hash{'ID:'.$seq_region_id} = $slice;
$sr_name_hash{$seq_region_id} = $slice->seq_region_name();
$sr_cs_hash{$seq_region_id} = $slice->coord_system();
}
my $sr_name = $sr_name_hash{$seq_region_id};
my $sr_cs = $sr_cs_hash{$seq_region_id};
if ($mapper) {
throw("Not yet implmented mapper, check equals are Funcgen calls too!");
($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand)
= $mapper->fastmap($sr_name, $seq_region_start, $seq_region_end, $seq_region_strand, $sr_cs);
if(! defined $sr_name){
$skip_feature = 1;
next FEATURE;
}
if ( $asm_cs == $sr_cs || ( $cmp_cs != $sr_cs && $asm_cs->equals($sr_cs) ) ) {
$slice = $slice_hash{"NAME:$sr_name:$cmp_cs_name:$cmp_cs_vers"}
||= $sa->fetch_by_region($cmp_cs_name, $sr_name, undef, undef, undef, $cmp_cs_vers);
} else {
$slice = $slice_hash{"NAME:$sr_name:$asm_cs_name:$asm_cs_vers"}
||= $sa->fetch_by_region($asm_cs_name, $sr_name, undef, undef, undef, $asm_cs_vers);
}
}
if ($dest_slice) {
unless ($dest_slice_start == 1 && $dest_slice_strand == 1) {
if ($dest_slice_strand == 1) {
$seq_region_start = $seq_region_start - $dest_slice_start + 1;
$seq_region_end = $seq_region_end - $dest_slice_start + 1;
$bound_seq_region_start = $bound_seq_region_start - $dest_slice_start + 1 if $bound_seq_region_start;
$bound_seq_region_end = $bound_seq_region_end - $dest_slice_start + 1 if $bound_seq_region_end;
}
else {
my $tmp_seq_region_start = $seq_region_start;
my $tmp_bound_seq_region_start = $bound_seq_region_start;
$seq_region_start = $dest_slice_end - $seq_region_end + 1;
$seq_region_end = $dest_slice_end - $tmp_seq_region_start + 1;
$bound_seq_region_start = $dest_slice_end - $bound_seq_region_end + 1 if $bound_seq_region_end;
$bound_seq_region_end = $dest_slice_end - $tmp_bound_seq_region_start + 1 if $bound_seq_region_start;
$seq_region_strand *= -1;
}
}
if ($seq_region_end < 1 || $seq_region_start > $dest_slice_length
|| ( $dest_slice_sr_name ne $sr_name )){
$skip_feature = 1;
next FEATURE;
}
$slice = $dest_slice;
}
my ($reg_type, $reg_attrs, $ftype);
if(defined $ftype_id){
$ftype = $ft_adaptor->fetch_by_dbID($ftype_id);
}
$reg_feat = Bio::EnsEMBL::Funcgen::RegulatoryFeature->new_fast
({
'start' => $seq_region_start,
'end' => $seq_region_end,
'bound_start' => $bound_seq_region_start,
'bound_end' => $bound_seq_region_end,
'strand' => $seq_region_strand,
'slice' => $slice,
'analysis' => $fset_hash{$fset_id}->analysis(),
'adaptor' => $self,
'dbID' => $dbID,
'display_label' => $display_label,
'feature_set' => $fset_hash{$fset_id},
'feature_type' => $ftype,
'stable_id' => $stable_id,
});
}
if(defined $attr_id && ! $skip_feature){
my $attr = $feature_adaptors{$attr_type}->fetch_by_dbID($attr_id);
my $attr_sr_start = $attr->seq_region_start;
my $attr_sr_end = $attr->seq_region_end;
$attr->slice($slice);
if($slice->strand ==1){
$attr->start($attr_sr_start - $slice->start +1);
$attr->end($attr_sr_end - $slice->start +1);
}else{
$attr->start($slice->end - $attr_sr_end +1);
$attr->end($slice->end - $attr_sr_start +1);
}
push @reg_attrs, $attr;
}
}
if($reg_feat){
$reg_feat->regulatory_attributes(\@reg_attrs); push @features, $reg_feat;
}
return\@ features; } |
sub store
{ my ($self, @rfs) = @_;
if (scalar(@rfs) == 0) {
throw('Must call store with a list of RegulatoryFeature objects');
}
my $sth = $self->prepare("
INSERT INTO regulatory_feature (
seq_region_id, seq_region_start,
seq_region_end, bound_seq_region_start,
bound_seq_region_end, seq_region_strand,
display_label, feature_type_id,
feature_set_id, stable_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
my $sth2 = $self->prepare("
INSERT INTO regulatory_attribute (
regulatory_feature_id, attribute_feature_id, attribute_feature_table
) VALUES (?, ?, ?)");
my $db = $self->db();
foreach my $rf (@rfs) {
if( ! ref $rf || ! $rf->isa('Bio::EnsEMBL::Funcgen::RegulatoryFeature') ) {
throw('Feature must be an RegulatoryFeature object');
}
if ( $rf->is_stored($db) ) {
warning('RegulatoryFeature [' . $rf->dbID() . '] is already stored in the database');
next;
}
if ( ! $rf->analysis->is_stored($db)) {
throw('A stored Bio::EnsEMBL::Analysis must be attached to the RegulatoryFeature objects to be stored.');
}
if (! $rf->feature_set->is_stored($db)) {
throw('A stored Bio::EnsEMBL::Funcgen::FeatureSet must be attached to the RegulatoryFeature objects to be stored.');
}
if (! $rf->feature_type->is_stored($db)) {
throw('A stored Bio::EnsEMBL::Funcgen::FeatureType must be attached to the RegulatoryFeature objects to be stored.');
}
if($rf->analysis->dbID() != $rf->feature_set->analysis->dbID()){
throw("RegulatoryFeature analysis(".$rf->analysis->logic_name().") does not match FeatureSet analysis(".$rf->feature_set->analysis->logic_name().")\n".
"Cannot store mixed analysis sets");
}
my $seq_region_id;
($rf, $seq_region_id) = $self->_pre_store($rf);
$rf->adaptor($self);
$sth->bind_param(1, $seq_region_id, SQL_INTEGER);
$sth->bind_param(2, $rf->start(), SQL_INTEGER);
$sth->bind_param(3, $rf->end(), SQL_INTEGER);
$sth->bind_param(4, $rf->bound_start(), SQL_INTEGER);
$sth->bind_param(5, $rf->bound_end(), SQL_INTEGER);
$sth->bind_param(6, $rf->strand(), SQL_TINYINT);
$sth->bind_param(7, $rf->{'display_label'}, SQL_VARCHAR); $sth->bind_param(8, $rf->feature_type->dbID(), SQL_INTEGER);
$sth->bind_param(9, $rf->feature_set->dbID(), SQL_INTEGER);
$sth->bind_param(10, $rf->{'stable_id'}, SQL_INTEGER);
$sth->execute();
$rf->dbID( $sth->{'mysql_insertid'} );
my $table_type;
my %attrs = %{$rf->_attribute_cache()};
foreach my $table(keys %attrs){
($table_type = $table) =~ s/_feature//;
foreach my $id(keys %{$attrs{$table}}){
$sth2->bind_param(1, $rf->dbID, SQL_INTEGER);
$sth2->bind_param(2, $id, SQL_INTEGER);
$sth2->bind_param(3, $table_type, SQL_VARCHAR);
$sth2->execute();
}
}
}
return\@ rfs; } |