From 7fe29173043fdb7e710d9d6e5eafd306af873dcf Mon Sep 17 00:00:00 2001 From: Michael Barton Date: Sun, 3 Mar 2013 20:29:06 -0500 Subject: [PATCH] Implement duplicate features Signed-off-by: Michael Barton --- lib/genomer-plugin-view/gff_record_helper.rb | 1 - lib/genomer-plugin-view/table.rb | 36 ++++++----- .../gff_record_helper_spec.rb | 49 +++++++------- spec/genomer-view-plugin/table_spec.rb | 64 ++++++++++++++----- spec/spec_helper.rb | 2 +- 5 files changed, 93 insertions(+), 59 deletions(-) diff --git a/lib/genomer-plugin-view/gff_record_helper.rb b/lib/genomer-plugin-view/gff_record_helper.rb index 2a0ac51..7b6fa5c 100644 --- a/lib/genomer-plugin-view/gff_record_helper.rb +++ b/lib/genomer-plugin-view/gff_record_helper.rb @@ -2,7 +2,6 @@ module GenomerPluginView::GffRecordHelper - DEFAULT_GFF_MAPPING = {'product' => 'product', 'Note' => 'note' } GFF_TO_TABLE = { diff --git a/lib/genomer-plugin-view/table.rb b/lib/genomer-plugin-view/table.rb index 99bcff1..6ef3033 100644 --- a/lib/genomer-plugin-view/table.rb +++ b/lib/genomer-plugin-view/table.rb @@ -21,33 +21,37 @@ def run def create_encoded_features(genes,prefix) features = genes.map do |gene| feature = gene.clone - attrs = Hash[feature.attributes] + attrs = feature.attributes.clone - if id = attrs['ID'] - attrs['ID'] = (prefix.is_a?(String) ? prefix + id : id) - end - - feature.feature = attrs['feature_type'] || 'CDS' + feature_type = attrs.detect{|k,v| k == 'feature_type'} + feature.feature = (feature_type ? feature_type.last : 'CDS') unless SUPPORTED_FEATURE_TYPES.include?(feature.feature) raise Genomer::Error, "Unknown feature_type '#{feature.feature}'" end + attrs.map! do |(k,v)| + v = (k == 'ID' && prefix.instance_of?(String) ? prefix + v : v) + [k,v] + end + if feature.feature == "CDS" - name, prdt, ftn = attrs['Name'], attrs['product'], attrs['function'] - if name - name = name.clone - name[0,1] = name[0,1].upcase - prdt, ftn = name,prdt - end + if attrs.detect{|(k,v)| k == 'Name' } + attrs.map! do |(k,v)| + v = v.clone + v[0,1] = v[0,1].upcase if k == 'Name' - attrs.delete('Name') - attrs['product'] = prdt - attrs['function'] = ftn + v = nil if k == 'function' + k = 'function' if k == 'product' + k = 'product' if k == 'Name' + [k,v] + end + end + #attrs.delete('Name') end - feature.attributes = attrs.to_a.reject{|(_,value)| value.nil? } + feature.attributes = attrs.reject{|(_,value)| value.nil? } feature end genes.zip(features).flatten diff --git a/spec/genomer-view-plugin/gff_record_helper_spec.rb b/spec/genomer-view-plugin/gff_record_helper_spec.rb index a77a8e0..efd42e6 100644 --- a/spec/genomer-view-plugin/gff_record_helper_spec.rb +++ b/spec/genomer-view-plugin/gff_record_helper_spec.rb @@ -68,7 +68,7 @@ context "gene feature with attributes" do let(:annotation) do - @attn.feature('gene').attributes('ID' => 'id') + @attn.feature('gene').attributes([['ID', 'id']]) end it "should return a table entry" do @@ -189,7 +189,7 @@ context "for a feature with an unknown attribute" do let(:annotation) do - @attn.attributes('something' => 'else') + @attn.attributes([['something','else']]) end it "should return an empty array" do @@ -199,34 +199,34 @@ end feature_keys = { - :gene => { - 'Name' => 'gene', - 'ID' => 'locus_tag' }, - :tRNA => { - 'product' => 'product', - 'Note' => 'note'}, - :rRNA => { - 'product' => 'product', - 'Note' => 'note'}, - :miscRNA => { - 'product' => 'product', - 'Note' => 'note'}, - :tmRNA => { - 'product' => 'product', - 'Note' => 'note'}, - :CDS => { - 'ec_number' => 'EC_number', - 'function' => 'function', - 'product' => 'product', - 'Note' => 'note', - 'ID' => 'protein_id' }} + :gene => [ + ['Name', 'gene'], + ['ID', 'locus_tag']], + :tRNA => [ + ['product', 'product'], + ['Note', 'note']], + :rRNA => [ + ['product', 'product'], + ['Note', 'note']], + :miscRNA => [ + ['product', 'product'], + ['Note', 'note']], + :tmRNA => [ + ['product', 'product'], + ['Note', 'note']], + :CDS => [ + ['ec_number', 'EC_number'], + ['function', 'function'], + ['product', 'product'], + ['Note', 'note'], + ['ID', 'protein_id' ]]} feature_keys.each do |type,mappings| mappings.each do |a,b| context "#{type.to_s} feature" do let(:annotation) do - @attn.feature(type.to_s).attributes(a => :value) + @attn.feature(type.to_s).attributes([[a, :value]]) end it "should return #{b} for the attribute #{a}" do @@ -238,7 +238,6 @@ end end - end end diff --git a/spec/genomer-view-plugin/table_spec.rb b/spec/genomer-view-plugin/table_spec.rb index dc1109c..c3f6661 100644 --- a/spec/genomer-view-plugin/table_spec.rb +++ b/spec/genomer-view-plugin/table_spec.rb @@ -73,7 +73,7 @@ let(:flags){ {:generate_encoded_features => 'pre_'} } - let(:annotations){ [gene({:attributes => {'ID' => '1'}})] } + let(:annotations){ [gene({:attributes => [['ID', '1']]})] } it "should call the to_genbank_features method " do subject.run.should == <<-EOS.unindent @@ -91,9 +91,9 @@ let(:flags){ {:generate_encoded_features => 'pre_'} } - let(:annotations){ [gene({:attributes => {'ID' => '1', - 'feature_type' => 'tRNA', - 'product' => 'tRNA-Gly'}})] } + let(:annotations){ [gene({:attributes => [['ID', '1'], + ['feature_type', 'tRNA'], + ['product', 'tRNA-Gly']]})] } it "should call the to_genbank_features method " do subject.run.should == <<-EOS.unindent @@ -112,7 +112,7 @@ describe "#create_encoded_features" do let(:prefix) do - nil + true end subject do @@ -143,10 +143,26 @@ end + describe "passed a gene with an ID attributes" do + + let(:attributes) do + [['ID', 'something']] + end + + let(:annotations) do + [gene({:attributes => attributes})] + end + + it "should not change the attributes" do + subject.attributes.should == attributes + end + + end + describe "passed a gene with a known feature_type attribute" do let(:attributes) do - {'feature_type' => 'tRNA'} + [['feature_type', 'tRNA']] end let(:annotations) do @@ -162,7 +178,7 @@ describe "passed a gene with an unknown feature_type attribute" do let(:attributes) do - {'feature_type' => 'unknown'} + [['feature_type', 'unknown']] end let(:annotations) do @@ -176,10 +192,26 @@ end + describe "passed a gene with a duplicate attribute" do + + let(:attributes) do + [['product', 'abcd'],['product', 'efgh']] + end + + let(:annotations) do + [gene({:attributes => attributes})] + end + + it "should not change attributes" do + subject.should have_identical_attributes cds({:attributes => attributes}) + end + + end + describe "passed a gene with a Name attribute" do let(:attributes) do - {'Name' => 'abcD'} + [['Name', 'abcD']] end let(:annotations) do @@ -187,7 +219,7 @@ end it "should set the capitalise value to the product key" do - subject.should have_identical_attributes cds({:attributes => {'product' => 'AbcD'}}) + subject.should have_identical_attributes cds({:attributes => [['product', 'AbcD']]}) end end @@ -195,7 +227,7 @@ describe "passed a gene with a product attribute" do let(:attributes) do - {'product' => 'abcd'} + [['product', 'abcd']] end let(:annotations) do @@ -211,7 +243,7 @@ describe "passed a gene with a function attribute" do let(:attributes) do - {'function' => 'abcd'} + [['function', 'abcd']] end let(:annotations) do @@ -227,7 +259,7 @@ describe "passed a gene with product and function attributes" do let(:attributes) do - {'product' => 'abcd', 'function' => 'efgh'} + [['product', 'abcd'], ['function', 'efgh']] end let(:annotations) do @@ -243,7 +275,7 @@ describe "passed a gene with Name and product attributes" do let(:attributes) do - {'Name' => 'abcD','product' => 'efgh'} + [['Name', 'abcD'], ['product', 'efgh']] end let(:annotations) do @@ -252,7 +284,7 @@ it "should map Name to product and product to function" do subject.should have_identical_attributes cds({:attributes => - {'product' => 'AbcD','function' => 'efgh'}}) + [['product', 'AbcD'], ['function', 'efgh']]}) end end @@ -260,7 +292,7 @@ describe "passed a gene with Name, product and function attributes" do let(:attributes) do - {'Name' => 'abcD','product' => 'efgh', 'function' => 'ijkl'} + [['Name', 'abcD'], ['product', 'efgh'], ['function', 'ijkl']] end let(:annotations) do @@ -269,7 +301,7 @@ it "should map Name to product and product to function" do subject.should have_identical_attributes cds({:attributes => - {'product' => 'AbcD','function' => 'efgh'}}) + [['product', 'AbcD'], ['function', 'efgh']]}) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7e38b4b..cf68c7f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,7 +22,7 @@ def gene(opts = Hash.new) :start => 1, :end => 3, :feature => 'gene', - :attributes => Hash.new} + :attributes => Array.new} Annotation.new(default.merge(opts)).to_gff3_record end