diff --git a/.readthedocs.yml b/.readthedocs.yml index 5f752dee..2f24b7d6 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,6 +5,12 @@ # Required version: 2 +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.7" + # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py @@ -13,8 +19,9 @@ sphinx: #formats: # - pdf -# Optionally set the version of Python and requirements required to build your docs +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html python: - version: 3.7 install: - - requirements: docs/requirements.txt + - requirements: docs/requirements.txt \ No newline at end of file diff --git a/bin/agat_sp_move_attributes_within_records.pl b/bin/agat_sp_move_attributes_within_records.pl new file mode 100755 index 00000000..b01a1535 --- /dev/null +++ b/bin/agat_sp_move_attributes_within_records.pl @@ -0,0 +1,407 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Getopt::Long; +use File::Basename; +use POSIX qw(strftime); +use Pod::Usage; +use IO::File; +use AGAT::AGAT; + +my $header = get_agat_header(); +my $config; +my $primaryTagCopy="level2"; +my $primaryTagPaste="level3"; +my $opt_output= undef; +my $attributes="all_attributes"; +my $opt_gff = undef; +my $opt_verbose = undef; +my $opt_help; + +# OPTION MANAGMENT +my @copyARGV=@ARGV; +if ( !GetOptions( 'f|ref|reffile|gff=s' => \$opt_gff, + "feature_copy|fc=s" => \$primaryTagCopy, + "feature_paste|fp=s" => \$primaryTagPaste, + 'o|output=s' => \$opt_output, + "tag|att=s" => \$attributes, + 'v|verbose!' => \$opt_verbose, + 'c|config=s' => \$config, + 'h|help!' => \$opt_help ) ) +{ + pod2usage( { -message => 'Failed to parse command line', + -verbose => 1, + -exitval => 1 } ); +} + +if ($opt_help) { + pod2usage( { -verbose => 99, + -exitval => 0, + -message => "$header\n" } ); +} + +if ( ! $opt_gff ){ + pod2usage( { + -message => "$header\nAt least 1 parameter is mandatory: Input reference gff file: --gff\n\n", + -verbose => 0, + -exitval => 2 } ); +} + +# --- Manage config --- +$config = get_agat_config({config_file_in => $config}); + +############### +# Manage Output + +## FOR GFF FILE +my $gffout_ok_file ; + +if ($opt_output) { + my ($outfile,$path,$ext) = fileparse($opt_output,qr/\.[^.]*/); + + # set file names + $gffout_ok_file = $path.$outfile.$ext; +} +my $gffout_ok = prepare_gffout($config, $gffout_ok_file); + +# Manage $primaryTag for copy +my @ptagListCopy; +my $print_feature_string_copy; +if(! $primaryTagCopy or $primaryTagCopy eq "all"){ + $print_feature_string_copy = "all features"; + push(@ptagListCopy, "all"); +} +elsif($primaryTagCopy =~/^level[123]$/){ + $print_feature_string_copy .= "$primaryTagCopy features "; + push(@ptagListCopy, $primaryTagCopy); +} +else{ + @ptagListCopy= split(/,/, $primaryTagCopy); + foreach my $tag (@ptagListCopy){ + if($tag =~/^level[123]$/){ + $print_feature_string_copy .= "$primaryTagCopy features "; + } + else{ + $print_feature_string_copy .= "$tag feature "; + } + } +} + +# Manage $primaryTag to paste +my @ptagListPaste; +my $print_feature_string_paste; +if(! $primaryTagPaste or $primaryTagPaste eq "all"){ + $print_feature_string_paste = "all features"; + push(@ptagListPaste, "all"); +} +elsif($primaryTagPaste =~/^level[123]$/){ + $print_feature_string_paste .= "$primaryTagPaste features "; + push(@ptagListPaste, $primaryTagPaste); +} +else{ + @ptagListPaste= split(/,/, $primaryTagPaste); + foreach my $tag (@ptagListPaste){ + if($tag =~/^level[123]$/){ + $print_feature_string_paste .= "$primaryTagPaste features "; + } + else{ + $print_feature_string_paste .= "$tag feature "; + } + } +} + +# Manage attributes if given +### If attributes given, parse them: +my %attHashOk; +my @attListOk; +if ($attributes){ + + if ($attributes eq "all_attributes"){ + print "All attributes will be used !\n"; + $attHashOk{"all_attributes"}++; + } + else{ + my @attList= split(/,/, $attributes); + + foreach my $attribute (@attList){ + + if($attribute == 0){ # Attribute alone + #check for ID attribute + if(lc($attribute) eq "id" ){print "ID attribute cannot be modified !\n";exit;} + #check for Parent attribute + if(lc($attribute) eq "parent"){print "Parent attribute cannot be modified !\n";exit;} + $attHashOk{$attribute}++; + push(@attListOk, $attribute); + } + } + } + print "\n"; +} + +# start with some interesting information +my $stringPrint = strftime "%m/%d/%Y at %Hh%Mm%Ss", localtime; +$stringPrint .= "\nusage: $0 @copyARGV\n"; +$stringPrint .= "The attributes @attListOk from the following feature types: $print_feature_string_copy will be copy pasted to the following feature types: $print_feature_string_paste.\n"; +print $stringPrint; + + ####################### +# >>>>>>>>>>>>>>>>>>>>>>>># MAIN #<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + ####################### +my %all_cases = ('l1' => 0, 'l2' => 0, 'l3' => 0, 'all' => 0); +###################### +### Parse GFF input # +my ($hash_omniscient, $hash_mRNAGeneLink) = slurp_gff3_file_JD({ input => $opt_gff, + config => $config + }); +print("Parsing Finished\n"); +### END Parse GFF input # +######################### +# sort by seq id +my $hash_sortBySeq = gather_and_sort_l1_by_seq_id($hash_omniscient); + +################# +# == LEVEL 1 == # +################# +foreach my $seqid (sort { (($a =~ /(\d+)$/)[0] || 0) <=> (($b =~ /(\d+)$/)[0] || 0) } keys %{$hash_sortBySeq}){ # loop over all the feature level1 + + foreach my $tag_l1 (sort {$a cmp $b} keys %{$hash_omniscient->{'level1'}}){ + foreach my $feature_l1 ( @{$hash_sortBySeq->{$seqid}{$tag_l1}} ){ + my $id_l1 = lc($feature_l1->_tag_value('ID')); + my $copyl1 = check_feature($feature_l1, 'level1', \@ptagListCopy); + + ################# + # == LEVEL 2 == # + ################# + foreach my $tag_l2 (sort keys %{$hash_omniscient->{'level2'}}){ # primary_tag_key_level2 = mrna or mirna or ncrna or trna etc... + + if ( exists_keys( $hash_omniscient, ('level2', $tag_l2, $id_l1) ) ){ + my @list_fl2 = @{$hash_omniscient->{'level2'}{$tag_l2}{$id_l1}}; + foreach my $feature_l2 ( @list_fl2 ) { + + my $copyl2 = check_feature($feature_l2,'level2', \@ptagListCopy); + my $pastel2 = check_feature($feature_l2,'level2', \@ptagListPaste); + if($pastel2 and $copyl1){ + add_tags_from_to($feature_l1, $feature_l2); + } + + ################# + # == LEVEL 3 == # + ################# + my $id_l2 = lc($feature_l2->_tag_value('ID')); + + foreach my $tag_l3 (sort keys %{$hash_omniscient->{'level3'}}){ # primary_tag_key_level3 = cds or exon or start_codon or utr etc... + if ( exists_keys( $hash_omniscient, ('level3', $tag_l3, $id_l2) ) ){ + my @list_fl3 = @{$hash_omniscient->{'level3'}{$tag_l3}{$id_l2}}; + foreach my $feature_l3 ( @list_fl3 ) { + + my $copyl3 = check_feature($feature_l3, 'level3', \@ptagListCopy); + my $pastel3 = check_feature($feature_l3, 'level3', \@ptagListPaste); + #copy attributes from L1 to l3 + if ($copyl1 and $pastel3){ + add_tags_from_to($feature_l1, $feature_l3); + } + #copy attributes from L2 to l3 + if ($copyl2 and $pastel3){ + add_tags_from_to($feature_l2, $feature_l3); + } + # ------- Case L3 to L3 ------- + foreach my $tag_l3_again (sort keys %{$hash_omniscient->{'level3'}}){ # primary_tag_key_level3 = cds or exon or start_codon or utr etc... + if ( exists_keys( $hash_omniscient, ('level3', $tag_l3_again, $id_l2) ) ){ + my @list_fl3_again = @{$hash_omniscient->{'level3'}{$tag_l3_again}{$id_l2}}; + foreach my $feature_l3_again ( @list_fl3_again ) { + + # Check it is not the same feature + if( lc($feature_l3->_tag_value('ID')) ne lc($feature_l3_again->_tag_value('ID')) ){ + + my $pastel3_again = check_feature($feature_l3_again, 'level3', \@ptagListPaste); + #copy attributes from L1 to l3 + if ($copyl3 and $pastel3_again){ + add_tags_from_to($feature_l3, $feature_l3_again); + } + } + } + } + } + } + } + } + # ------- Case L2 to L2 ------- + foreach my $tag_l2_again (sort keys %{$hash_omniscient->{'level2'}}){ # primary_tag_key_level2 = mrna or mirna or ncrna or trna etc... + + if ( exists_keys( $hash_omniscient, ('level2', $tag_l2_again, $id_l1) ) ){ + my @list_fl2_again = @{$hash_omniscient->{'level2'}{$tag_l2_again}{$id_l1}}; + + foreach my $feature_l2_again ( @list_fl2_again ) { + # Check it is not the same feature + if( lc($feature_l2->_tag_value('ID')) ne lc($feature_l2_again->_tag_value('ID')) ){ + + my $pastel2_again = check_feature($feature_l2_again, 'level3', \@ptagListPaste); + #copy attributes from L1 to l3 + if ($copyl2 and $pastel2_again){ + add_tags_from_to($feature_l2, $feature_l2_again); + } + } + } + } + } + } + } + } + } + } +} + +# create omniscient with only selected recoreds +print_omniscient( {omniscient => $hash_omniscient, output => $gffout_ok} );#print gene modified in file + +####################################################################################################################### + #################### + # methods # + ################ + ############## + ############ + ########## + ######## + ###### + #### + ## + +# add tags and avoid Parent and ID +sub add_tags_from_to{ + my ($feature_from, $feature_to)=@_; + + # for each tag of feature_from + my @list_tags = $feature_from->get_all_tags(); + foreach my $tag (@list_tags){ + # Check tag is among those that have to be used + if(exists_keys(\%attHashOk,("all_attributes")) or exists_keys(\%attHashOk,($tag))){ + if (lc($tag) ne "id" and lc($tag) ne "parent" ){ + my @tag_values = $feature_from->get_tag_values($tag); + create_or_append_tag($feature_to, $tag, \@tag_values); + } + } + } +} + +sub check_feature{ + my ($feature, $level, $ptagList)=@_; + + my $keepit=undef; + my $primary_tag=$feature->primary_tag; + # check primary tag (feature type) to handle + foreach my $ptag (@$ptagList){ + + if($ptag eq "all"){ + $keepit = 1 ; + } + elsif(lc($ptag) eq $level){ + $keepit = 1 ; + } + elsif(lc($ptag) eq lc($primary_tag) ){ + $keepit = 1 ; + } + } + return $keepit; +} + +__END__ + +=head1 NAME + +agat_sp_move_attributes_within_records.pl + +=head1 DESCRIPTION + +The script aims to keep move attributes within a record e.g. from Level1 to Level2 and/or Level3 features; and / or from Level2 to Level2 or Level3 features; and / or from Level3 to Level3 features. +Example of L1 feature: gene +Example of L2 featrue + +=head1 SYNOPSIS + + agat_sp_move_attributes_within_records.pl --gff infile.gff --feature_copy mRNA --feature_paste CDS --attribute Dbxref,Ontology [ --output outfile ] + agat_sp_move_attributes_within_records.pl --help + +=head1 OPTIONS + +=over 8 + +=item B<-f>, B<--reffile>, B<--gff> or B<-ref> + +Input GFF3 file that will be read + +=item B<--feature_copy> or B<--fc> + +primary tag (feature type) option to list from which feature we will copy the attributes, case insensitive. +You can specified a feature (or a coma separated list) by giving its primary tag / feature type (column 3) value as: cds, Gene, MrNa, etc +You can specify directly all the feature of a particular level: + level2=mRNA,ncRNA,tRNA,etc + level3=CDS,exon,UTR,etc +By default all level2 feature are used. + +=item B<--feature_paste> or B<--fp> + +primary tag (feature type) option to list to which feature we will paste the attributes, case sensitive. +You can specified a feature (or a coma separated list) by giving its primary tag / feature type (column 3) value as: cds, Gene, MrNa, etc +You can specify directly all the feature of a particular level: + level2=mRNA,ncRNA,tRNA,etc + level3=CDS,exon,UTR,etc +By default all feature level3 are used. + + +=item B<-a> or B<--attribute> + +Attribute that will be copied and pasted. Case sensitive. +You can specified an attribute (or a coma separated list) by giving its attribute tag value (column9) as: Ontology, Dbxref, etc +Default: all_attributes +/!\ is a specific parameter meaning all the attributes will be use. + + +=item B<-o> or B<--output> + +Output GFF file. If no output file is specified, the output will be +written to STDOUT. + +=item B<-v> + +Verbose option for debugging purpose. + +=item B<-c> or B<--config> + +String - Input agat config file. By default AGAT takes as input agat_config.yaml file from the working directory if any, +otherwise it takes the orignal agat_config.yaml shipped with AGAT. To get the agat_config.yaml locally type: "agat config --expose". +The --config option gives you the possibility to use your own AGAT config file (located elsewhere or named differently). + +=item B<-h> or B<--help> + +Display this helpful text. + +=back + +=head1 FEEDBACK + +=head2 Did you find a bug? + +Do not hesitate to report bugs to help us keep track of the bugs and their +resolution. Please use the GitHub issue tracking system available at this +address: + + https://github.com/NBISweden/AGAT/issues + + Ensure that the bug was not already reported by searching under Issues. + If you're unable to find an (open) issue addressing the problem, open a new one. + Try as much as possible to include in the issue when relevant: + - a clear description, + - as much relevant information as possible, + - the command used, + - a data sample, + - an explanation of the expected behaviour that is not occurring. + +=head2 Do you want to contribute? + +You are very welcome, visit this address for the Contributing guidelines: +https://github.com/NBISweden/AGAT/blob/master/CONTRIBUTING.md + +=cut + +AUTHOR - Jacques Dainat diff --git a/docs/index.rst b/docs/index.rst index d569b363..26677eb2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -103,6 +103,7 @@ Contents tools/agat_sp_manage_functional_annotation.md tools/agat_sp_manage_introns.md tools/agat_sp_merge_annotations.md + tools/agat_sp_move_attributes_within_records tools/agat_sp_prokka_fix_fragmented_gene_annotations.md tools/agat_sp_sensitivity_specificity.md tools/agat_sp_separate_by_record_type.md diff --git a/docs/tools/agat_sp_move_attributes_within_records.md b/docs/tools/agat_sp_move_attributes_within_records.md new file mode 100644 index 00000000..76865081 --- /dev/null +++ b/docs/tools/agat_sp_move_attributes_within_records.md @@ -0,0 +1,67 @@ +# NAME + +agat\_sp\_move\_attributes\_within\_records.pl + +# DESCRIPTION + +The script aims to keep move attributes within a record e.g. from Level1 to Level2 and/or Level3 features; and / or from Level2 to Level2 or Level3 features; and / or from Level3 to Level3 features. +Example of L1 feature: gene +Example of L2 featrue + +# SYNOPSIS + +``` +agat_sp_move_attributes_within_records.pl --gff infile.gff --feature_copy mRNA --feature_paste CDS --attribute Dbxref,Ontology [ --output outfile ] +agat_sp_move_attributes_within_records.pl --help +``` + +# OPTIONS + +- **-f**, **--reffile**, **--gff** or **-ref** + + Input GFF3 file that will be read + +- **--feature\_copy** or **--fc** + + primary tag (feature type) option to list from which feature we will copy the attributes, case insensitive. + You can specified a feature (or a coma separated list) by giving its primary tag / feature type (column 3) value as: cds, Gene, MrNa, etc + You can specify directly all the feature of a particular level: + level2=mRNA,ncRNA,tRNA,etc + level3=CDS,exon,UTR,etc + By default all level2 feature are used. + +- **--feature\_paste** or **--fp** + + primary tag (feature type) option to list to which feature we will paste the attributes, case sensitive. + You can specified a feature (or a coma separated list) by giving its primary tag / feature type (column 3) value as: cds, Gene, MrNa, etc + You can specify directly all the feature of a particular level: + level2=mRNA,ncRNA,tRNA,etc + level3=CDS,exon,UTR,etc + By default all feature level3 are used. + +- **-a** or **--attribute** + + Attribute that will be copied and pasted. Case sensitive. + You can specified an attribute (or a coma separated list) by giving its attribute tag value (column9) as: Ontology, Dbxref, etc + Default: all\_attributes + /!\\ <all\_attributes> is a specific parameter meaning all the attributes will be use. + +- **-o** or **--output** + + Output GFF file. If no output file is specified, the output will be + written to STDOUT. + +- **-v** + + Verbose option for debugging purpose. + +- **-c** or **--config** + + String - Input agat config file. By default AGAT takes as input agat\_config.yaml file from the working directory if any, + otherwise it takes the orignal agat\_config.yaml shipped with AGAT. To get the agat\_config.yaml locally type: "agat config --expose". + The --config option gives you the possibility to use your own AGAT config file (located elsewhere or named differently). + +- **-h** or **--help** + + Display this helpful text. + diff --git a/lib/AGAT/OmniscientTool.pm b/lib/AGAT/OmniscientTool.pm index cb9f9498..6b6c013f 100644 --- a/lib/AGAT/OmniscientTool.pm +++ b/lib/AGAT/OmniscientTool.pm @@ -571,7 +571,8 @@ sub merge_overlap_loci{ my @list_tag_l2 = $omniscient->{'level1'}{$tag_l1}{$id2_l1}->get_all_tags(); foreach my $tag (@list_tag_l2){ if(lc($tag) ne "parent" and lc($tag) ne "id"){ - create_or_append_tag($omniscient->{'level1'}{$tag_l1}{$id_l1}, $tag ,$omniscient->{'level1'}{$tag_l1}{$id2_l1}->get_tag_values($tag)); + my @tag_values = $omniscient->{'level1'}{$tag_l1}{$id2_l1}->get_tag_values($tag); + create_or_append_tag($omniscient->{'level1'}{$tag_l1}{$id_l1}, $tag , \@tag_values); } } # remove the level1 of the ovelaping one @@ -611,7 +612,8 @@ sub merge_overlap_loci{ $resume_identic++; my @list_tag_l2 = $common->get_all_tags(); foreach my $tag (@list_tag_l2){ - create_or_append_tag($kept_l2, "merged_".$tag ,$common->get_tag_values($tag)); + my @tag_values = $common->get_tag_values($tag); + create_or_append_tag($kept_l2, "merged_".$tag , \@tag_values); } } } @@ -1325,6 +1327,9 @@ sub create_or_replace_tag{ # INPUT: feature object, String tag, String or Array ref; # Output: None +# /!\ If values are extracted using get_tag_values($tag) you should first save the result in an array and send the array ref to this function e.g +# my @tag_values = $feature->get_tag_values($tag); +# create_or_append_tag($other_feature, $tag , \@tag_values); sub create_or_append_tag{ my ($feature, $tag, $value)=@_; @@ -1333,15 +1338,15 @@ sub create_or_append_tag{ my @original_values = $feature->get_tag_values($tag); foreach my $value (@{$value}){ if(! grep { $value eq $_ } @original_values){ - $feature->add_tag_value($tag,@{$value}); + $feature->add_tag_value($tag,$value); } } } else{ - my @original_values = $feature->get_tag_values($tag); + my @original_values = $feature->get_tag_values($tag); if(! grep { $value eq $_ } @original_values){ $feature->add_tag_value($tag,$value); - } + } } } else{ diff --git a/t/gff_syntax/out/15_correct_output.gff b/t/gff_syntax/out/15_correct_output.gff index b3486e71..2bf3a620 100644 --- a/t/gff_syntax/out/15_correct_output.gff +++ b/t/gff_syntax/out/15_correct_output.gff @@ -9,4 +9,4 @@ scaffold789 maker match_part 558184 560123 . + . ID=agat-exon-4;Parent=CLUHART00 scaffold789 maker match_part 561401 561519 . + . ID=agat-exon-5;Parent=CLUHART00000006146;Target=CLUHART00000006146 1941 2059;merged_ID=CLUHART00000006146:exon:996;merged_Parent=CLUHART00000006147;merged_Target=CLUHART00000006147 1941 2059 scaffold789 maker match_part 562057 562121 . + . ID=CLUHART00000006147:exon:999;Parent=CLUHART00000006146;Target=CLUHART00000006147 2060 2124 scaffold789 maker match_part 564171 564235 . + . ID=CLUHART00000006146:exon:997;Parent=CLUHART00000006146;Target=CLUHART00000006146 2060 2124 -scaffold789 maker match_part 564372 564780 . + . ID=agat-exon-6;Parent=CLUHART00000006146;Target=CLUHART00000006146 2125 2533;merged_ID=CLUHART00000006146:exon:998;merged_Parent=CLUHART00000006147;merged_Target=CLUHART00000006147 +scaffold789 maker match_part 564372 564780 . + . ID=agat-exon-6;Parent=CLUHART00000006146;Target=CLUHART00000006146 2125 2533;merged_ID=CLUHART00000006146:exon:998;merged_Parent=CLUHART00000006147;merged_Target=CLUHART00000006147,2125,2533 diff --git a/t/scripts_output.t b/t/scripts_output.t index c34781f7..11f3914e 100644 --- a/t/scripts_output.t +++ b/t/scripts_output.t @@ -603,6 +603,15 @@ system(" $script --gff $input_folder/agat_sp_merge_annotations/fileA.gff --gff ok( system("diff $result $outtmp") == 0, "output $script"); unlink $outtmp; +# ------------------- check agat_sp_move_attributes_within_records script------------------- + +$script = $script_prefix."bin/agat_sp_move_attributes_within_records.pl"; +$result = "$output_folder/agat_sp_move_attributes_within_records.gff"; +system(" $script --gff $input_folder/agat_sp_move_attributes_within_records.gff --fp exon,CDS --fc mRNA -o $outtmp 2>&1 1>/dev/null"); +#run test +ok( system("diff $result $outtmp") == 0, "output $script"); +unlink $outtmp; + # ------------------- check agat_sp_prokka_fragmented_gene_annotations script------------------- $script = $script_prefix."bin/agat_sp_prokka_fix_fragmented_gene_annotations.pl"; diff --git a/t/scripts_output/in/agat_sp_move_attributes_within_records.gff b/t/scripts_output/in/agat_sp_move_attributes_within_records.gff new file mode 100644 index 00000000..d77cec81 --- /dev/null +++ b/t/scripts_output/in/agat_sp_move_attributes_within_records.gff @@ -0,0 +1,3 @@ +ptg000002l AUGUSTUS mRNA 3255 4626 0.5 + . ID=NBISM00000000001;Parent=NBISG00000000001;Dbxref=CDD:cd07067,Gene3D:G3DSA:3.40.50.1240,InterPro:IPR013078,InterPro:IPR029033,;Name=ARB_03491;Ontology_term=-;makerName=g1.t1;product=Probable phosphoglycerate mutase ARB_03491;uniprot_id=D4B4V1 +ptg000002l AUGUSTUS CDS 3255 3275 0.98 + 0 ID=NBISC00000000001;Parent=NBISM00000000001;makerName=g1.t1.CDS1 + diff --git a/t/scripts_output/out/agat_sp_move_attributes_within_records.gff b/t/scripts_output/out/agat_sp_move_attributes_within_records.gff new file mode 100644 index 00000000..06aded93 --- /dev/null +++ b/t/scripts_output/out/agat_sp_move_attributes_within_records.gff @@ -0,0 +1,6 @@ +##gff-version 3 +ptg000002l AGAT gene 3255 4626 . + . ID=NBISG00000000001;Dbxref=CDD:cd07067,Gene3D:G3DSA:3.40.50.1240,InterPro:IPR013078,InterPro:IPR029033;Name=ARB_03491;Ontology_term=-;makerName=g1.t1;product=Probable phosphoglycerate mutase ARB_03491;uniprot_id=D4B4V1 +ptg000002l AUGUSTUS mRNA 3255 4626 0.5 + . ID=NBISM00000000001;Parent=NBISG00000000001;Dbxref=CDD:cd07067,Gene3D:G3DSA:3.40.50.1240,InterPro:IPR013078,InterPro:IPR029033;Name=ARB_03491;Ontology_term=-;makerName=g1.t1;product=Probable phosphoglycerate mutase ARB_03491;uniprot_id=D4B4V1 +ptg000002l AGAT exon 3255 4626 . + . ID=agat-exon-1;Parent=NBISM00000000001;Dbxref=CDD:cd07067,Gene3D:G3DSA:3.40.50.1240,InterPro:IPR013078,InterPro:IPR029033;Name=ARB_03491;Ontology_term=-;makerName=g1.t1.CDS1,g1.t1;product=Probable phosphoglycerate mutase ARB_03491;uniprot_id=D4B4V1 +ptg000002l AUGUSTUS CDS 3255 3275 0.98 + 0 ID=NBISC00000000001;Parent=NBISM00000000001;Dbxref=CDD:cd07067,Gene3D:G3DSA:3.40.50.1240,InterPro:IPR013078,InterPro:IPR029033;Name=ARB_03491;Ontology_term=-;makerName=g1.t1.CDS1,g1.t1;product=Probable phosphoglycerate mutase ARB_03491;uniprot_id=D4B4V1 +ptg000002l AGAT three_prime_UTR 3276 4626 . + . ID=agat-three_prime_utr-1;Parent=NBISM00000000001;makerName=g1.t1.CDS1