<p>Here's a Perl script that can do this:</p>

<pre class="lang-perl prettyprint-override"><code>#!/usr/bin/env perl 
use strict;
use warnings;

## Change this to whatever taxon you are working with
my $taxon = 'taxon:1000';
chomp(my $date = `date +%Y%M%d`);

my (%aspect, %gos);
## Read the GO.terms_and_ids file to get the aspect (sub ontology)
## of each GO term. 
open(my $fh, $ARGV[0]) or die "Need a GO.terms_and_ids file as 1st arg: $!\n";
while (&lt;$fh&gt;) {
    next if /^!/;
    chomp;
    my @fields = split(/\t/);
    ## $aspect{GO:0000001} = 'P'
    $aspect{$fields[0]} = $fields[2];
}
close($fh);

## Read the list of gene annotations
open($fh, $ARGV[1]) or die "Need a list of gene annotattions as 2nd arg: $!\n";
while (&lt;$fh&gt;) {
    chomp;
    my ($gene, @terms) = split(/[\s,]+/);
    ## $gos{geneA} = (go1, go2 ... goN)
    $gos{$gene} = [ @terms ];
}
close($fh);

foreach my $gene (keys(%gos)) {
    foreach my $term (@{$gos{$gene}}) {
        ## Warn and skip if there is no aspect for this term
        if (!$aspect{$term}) {
            print STDERR "Unknown GO term ($term) for gene $gene\n";
            next;
        }
        ## Build a pseudo GAF line 
        my @out = ('DB', $gene, $gene, ' ', $term, 'PMID:foo', 'TAS', ' ', $aspect{$term},
                             $gene, ' ', 'protein', $taxon, $date, 'DB', ' ', ' ');
        print join("\t", @out). "\n";
    }
}
</code></pre>

<p>Make it executable and run it with the <code>GO.terms_and_ids</code> file as the 1st argument and the list of gene annotations as the second. Using the current <code>GO.terms_and_ids</code> and the example annotations in the question, I get:</p>

<pre><code>$ foo.pl GO.terms_and_ids file.gos 
DB  geneD   geneD       GO:0005634  PMID:foo    TAS     C   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0003677  PMID:foo    TAS     F   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0030154  PMID:foo    TAS     P   geneD       protein taxon:1000  20170308    DB       
Unknown GO term (GO:0006350) for gene geneD
DB  geneD   geneD       GO:0006355  PMID:foo    TAS     P   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0007275  PMID:foo    TAS     P   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0030528  PMID:foo    TAS     F   geneD       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0016020  PMID:foo    TAS     C   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0005524  PMID:foo    TAS     F   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0006468  PMID:foo    TAS     P   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0005737  PMID:foo    TAS     C   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0004674  PMID:foo    TAS     F   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0006914  PMID:foo    TAS     P   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0016021  PMID:foo    TAS     C   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0015031  PMID:foo    TAS     P   geneB       protein taxon:1000  20170308    DB       
DB  geneA   geneA       GO:0006950  PMID:foo    TAS     P   geneA       protein taxon:1000  20170308    DB       
DB  geneA   geneA       GO:0005737  PMID:foo    TAS     C   geneA       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0003779  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0006941  PMID:foo    TAS     P   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005524  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0003774  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005516  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005737  PMID:foo    TAS     C   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005863  PMID:foo    TAS     C   geneC       protein taxon:1000  20170308    DB       
</code></pre>

<p>Note that this is very much a pseudo-GAF file since most of the fields apart from the gene name, GO term and sub-ontology are fake. It should still work for what you need, however.</p>

CC BY-SA 3.0
2017-06-08T09:47:17.907Z
I think the evidence code should be changed to IEA, because it is unlikely one would have manually annotated GO's for a non-model organism.
Michael
CC BY-SA 3.0
2017-06-08T10:09:28.967Z
@Michael, it doesn't really make any difference so I chose TAS since these are annotations provided by the OP. But sure, IEA would also work. The field will be ignored in any case when doing an enrichment analysis so you can put whatever you prefer.
terdon
CC BY-SA 3.0
2017-06-08T10:13:32.047Z
Sure, IEA might be even discarded by some tools.
Michael
CC BY-SA 3.0
2017-06-08T09:08:04.750Z
2017-06-08T20:43:01.263Z
2017-06-08T20:43:01.263Z
terdon
<p>This question is based on <a href="https://www.biostars.org/p/129057/" rel="noreferrer">a question</a> on BioStars  posted >2 years ago by user jack.</p>

<p>It describes a very frequent problem of generating GO annotations for non-model organisms. While it is based on some specific format and single application (Ontologizer), it would be useful to have a general description of the pathway to getting to a GAF file. </p>

<p>Note, that the input format is lacking a bit of essential information, like how it was obtained. Therefore, it is har to assign evidence code. Therefore, lets assume that the assignments of GO terms were done automagically. </p>

<hr>

<blockquote>
  <p>I want to do the Gene enrichment using Ontologizer without a
  predefined association file(it's not model organism). </p>
  
  <p>I have parsed a file with two columns for that organism like this : </p>

<pre><code>geneA  GO:0006950,GO:0005737
geneB  GO:0016020,GO:0005524,GO:0006468,GO:0005737,GO:0004674,GO:0006914,GO:0016021,GO:0015031
geneC  GO:0003779,GO:0006941,GO:0005524,GO:0003774,GO:0005516,GO:0005737,GO:0005863
geneD  GO:0005634,GO:0003677,GO:0030154,GO:0006350,GO:0006355,GO:0007275,GO:0030528
</code></pre>
  
  <p>I have downloaded the .ob file from Gene ontology file which contain
  this information (from <a href="http://www.geneontology.org/doc/GO.terms_and_ids" rel="noreferrer">here</a>) : </p>

<pre><code>!
! GO IDs (primary only) and name text strings
! GO:0000000 [tab] text string [tab] F|P|C
! where F = molecular function, P = biological process, C = cellular component
!
GO:0000001  mitochondrion inheritance   P
GO:0000002  mitochondrial genome maintenance    P
GO:0000003  reproduction    P
GO:0000005  ribosomal chaperone activity    F
GO:0000006  high affinity zinc uptake transmembrane transporter activity    F
GO:0000007  low-affinity zinc ion transmembrane transporter activity    F
GO:0000008  thioredoxin F
GO:0000009  alpha-1,6-mannosyltransferase activity  F
GO:0000010  trans-hexaprenyltranstransferase activity   F
GO:0000011  vacuole inheritance P
</code></pre>
  
  <p>What I need as output is .gaf file in the following format (in the
  format of the files <a href="http://geneontology.org/page/download-annotations" rel="noreferrer">here</a>):</p>

<pre><code>!gaf-version: 2.0

!Project_name: Leishmania major GeneDB

!URL: http://www.genedb.org/leish

!Contact Email: mb4@sanger.ac.uk

 GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0003723    PMID:22396527    ISO    GeneDB:Tb927.10.10130    F    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene    taxon:347515    20120910    GeneDB_Lmajor       
 GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0044429    PMID:20660476    ISS        C    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene    taxon:347515    20100803 GeneDB_Lmajor             GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0016554    PMID:22396527    ISO    GeneDB:Tb927.10.10130    P    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene   taxon:347515    20120910    GeneDB_Lmajor       
 GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0048255    PMID:22396527    ISO    GeneDB:Tb927.10.10130    P    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene    taxon:347515    20120910    GeneDB_Lmajor  
</code></pre>
  
  <p>How to create your own GO association file (gaf)?</p>
</blockquote>

CC BY-SA 3.0
2017-06-08T07:59:06.230Z
Please add some tags for GO, non-model organism, gaf, overrepresentation analysis etc. I just used a random tag because there are not many sensible tags in the list yet.
Michael
CC BY-SA 3.0
2017-06-08T08:07:55.797Z
I modified a bit the question, added tags and I centered the question in creating the file in that format, if you disagree, just revert my changes
llrs
CC BY-SA 3.0
2017-06-08T08:08:10.450Z
I added [tag:gene-ontology] and [tag:gaf]. I'm not sure whether a [tag:over-representation-analysis] or a [tag:enrichment-analysis] would be more appropriate.
Devon Ryan
CC BY-SA 3.0
2017-06-08T08:09:23.467Z
@Llopis: Hopefully I didn't just accidentally overwrite your changes!
Devon Ryan
CC BY-SA 3.0
2017-06-08T08:11:28.820Z
No luck, my edit was rejected (or at least doesn't appear) :\
llrs
CC BY-SA 3.0
2017-06-08T09:14:34.530Z
If you want to bring questions from another site, [please don't just copy/paste them verbatim](https://bioinformatics.meta.stackexchange.com/q/78/298). Instead, *ask them again in your own words*. And if you do copy, it would be better to put the quoted text in a quote block to clearly indicate that it is a quote.
terdon
CC BY-SA 3.0
2017-06-08T09:26:12.477Z
@terdon, sorry need to adapt to the new rules ;) I accepted the edits, however I don't have time to rewrite the question in my own words, and I don't think it is strictly necessary. Even if that might seem a contradiction with my previous post, it is not imo, because the question is pretty aged.
Michael
CC BY-SA 3.0
2017-06-08T09:27:59.297Z
@Michael no, I didn't expect you to rewrite this now! But please do so next time. Going around just pinching questions verbatim from other sites doesn't seem right. Not unless you're in a position to offer clarifications or this is an issue that affects you too.
terdon
CC BY-SA 3.0
2017-06-08T09:32:42.303Z
Indeed, I can offer ample clarification for this question, we are doing exactly the same thing, except that we are using InterproScan to assign GO terms not Blast2GO as was likely used here. I have a similar script to convert IPS output to GAF.
Michael
CC BY-SA 3.0
2017-06-08T13:24:05.687Z
Ha! I only now realized you were the person who first raised the whole copying from other sites issue as a problem :)
terdon
<sequence-annotation><gene-ontology>
How can I create my own GO association file (gaf)?
# How can I create my own GO association file (gaf)?

(Asked by: username_0 on 2017-06-08)

This question is based on a question on BioStars  posted >2 years ago by user jack.
It describes a very frequent problem of generating GO annotations for non-model organisms. While it is based on some specific format and single application (Ontologizer), it would be useful to have a general description of the pathway to getting to a GAF file. 
Note, that the input format is lacking a bit of essential information, like how it was obtained. Therefore, it is har to assign evidence code. Therefore, lets assume that the assignments of GO terms were done automagically. 


I want to do the Gene enrichment using Ontologizer without a
  predefined association file(it's not model organism). 
I have parsed a file with two columns for that organism like this : 
geneA  GO:0006950,GO:0005737
geneB  GO:0016020,GO:0005524,GO:0006468,GO:0005737,GO:0004674,GO:0006914,GO:0016021,GO:0015031
geneC  GO:0003779,GO:0006941,GO:0005524,GO:0003774,GO:0005516,GO:0005737,GO:0005863
geneD  GO:0005634,GO:0003677,GO:0030154,GO:0006350,GO:0006355,GO:0007275,GO:0030528

I have downloaded the .ob file from Gene ontology file which contain
  this information (from here) : 
!
! GO IDs (primary only) and name text strings
! GO:0000000 [tab] text string [tab] F|P|C
! where F = molecular function, P = biological process, C = cellular component
!
GO:0000001  mitochondrion inheritance   P
GO:0000002  mitochondrial genome maintenance    P
GO:0000003  reproduction    P
GO:0000005  ribosomal chaperone activity    F
GO:0000006  high affinity zinc uptake transmembrane transporter activity    F
GO:0000007  low-affinity zinc ion transmembrane transporter activity    F
GO:0000008  thioredoxin F
GO:0000009  alpha-1,6-mannosyltransferase activity  F
GO:0000010  trans-hexaprenyltranstransferase activity   F
GO:0000011  vacuole inheritance P

What I need as output is .gaf file in the following format (in the
  format of the files here):
!gaf-version: 2.0

!Project_name: Leishmania major GeneDB

!URL: http://www.genedb.org/leish

!Contact Email: mb4@sanger.ac.uk

 GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0003723    PMID:22396527    ISO    GeneDB:Tb927.10.10130    F    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene    taxon:347515    20120910    GeneDB_Lmajor       
 GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0044429    PMID:20660476    ISS        C    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene    taxon:347515    20100803 GeneDB_Lmajor             GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0016554    PMID:22396527    ISO    GeneDB:Tb927.10.10130    P    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene   taxon:347515    20120910    GeneDB_Lmajor       
 GeneDB_Lmajor    LmjF.36.4770    LmjF.36.4770        GO:0048255    PMID:22396527    ISO    GeneDB:Tb927.10.10130    P    mitochondrial RNA binding complex 1 subunit, putative    LmjF36.4770    gene    taxon:347515    20120910    GeneDB_Lmajor  

How to create your own GO association file (gaf)?

**Tags:** sequence-annotation, gene-ontology
> **Comments:**
> **username_0**: Please add some tags for GO, non-model organism, gaf, overrepresentation analysis etc. I just used a random tag because there are not many sensible tags in the list yet.  
> **username_1**: I modified a bit the question, added tags and I centered the question in creating the file in that format, if you disagree, just revert my changes  
> **username_2**: I added [tag:gene-ontology] and [tag:gaf]. I'm not sure whether a [tag:over-representation-analysis] or a [tag:enrichment-analysis] would be more appropriate.  
> **username_2**: @Llopis: Hopefully I didn't just accidentally overwrite your changes!  
> **username_1**: No luck, my edit was rejected (or at least doesn't appear) :\  
> **username_3**: If you want to bring questions from another site, [please don't just copy/paste them verbatim](https://bioinformatics.meta.stackexchange.com/q/78/298). Instead, *ask them again in your own words*. And if you do copy, it would be better to put the quoted text in a quote block to clearly indicate that it is a quote.  
> **username_0**: @terdon, sorry need to adapt to the new rules ;) I accepted the edits, however I don't have time to rewrite the question in my own words, and I don't think it is strictly necessary. Even if that might seem a contradiction with my previous post, it is not imo, because the question is pretty aged.  
> **username_3**: @Michael no, I didn't expect you to rewrite this now! But please do so next time. Going around just pinching questions verbatim from other sites doesn't seem right. Not unless you're in a position to offer clarifications or this is an issue that affects you too.  
> **username_0**: Indeed, I can offer ample clarification for this question, we are doing exactly the same thing, except that we are using InterproScan to assign GO terms not Blast2GO as was likely used here. I have a similar script to convert IPS output to GAF.  
> **username_3**: Ha! I only now realized you were the person who first raised the whole copying from other sites issue as a problem :)  

---

## 1 answers

### Answer by username_3 on 2017-06-08. Score: 8 | Accepted answer

Here's a Perl script that can do this:
#!/usr/bin/env perl 
use strict;
use warnings;

## Change this to whatever taxon you are working with
my $taxon = 'taxon:1000';
chomp(my $date = `date +%Y%M%d`);

my (%aspect, %gos);
## Read the GO.terms_and_ids file to get the aspect (sub ontology)
## of each GO term. 
open(my $fh, $ARGV[0]) or die "Need a GO.terms_and_ids file as 1st arg: $!\n";
while (<$fh>) {
    next if /^!/;
    chomp;
    my @fields = split(/\t/);
    ## $aspect{GO:0000001} = 'P'
    $aspect{$fields[0]} = $fields[2];
}
close($fh);

## Read the list of gene annotations
open($fh, $ARGV[1]) or die "Need a list of gene annotattions as 2nd arg: $!\n";
while (<$fh>) {
    chomp;
    my ($gene, @terms) = split(/[\s,]+/);
    ## $gos{geneA} = (go1, go2 ... goN)
    $gos{$gene} = [ @terms ];
}
close($fh);

foreach my $gene (keys(%gos)) {
    foreach my $term (@{$gos{$gene}}) {
        ## Warn and skip if there is no aspect for this term
        if (!$aspect{$term}) {
            print STDERR "Unknown GO term ($term) for gene $gene\n";
            next;
        }
        ## Build a pseudo GAF line 
        my @out = ('DB', $gene, $gene, ' ', $term, 'PMID:foo', 'TAS', ' ', $aspect{$term},
                             $gene, ' ', 'protein', $taxon, $date, 'DB', ' ', ' ');
        print join("\t", @out). "\n";
    }
}

Make it executable and run it with the GO.terms_and_ids file as the 1st argument and the list of gene annotations as the second. Using the current GO.terms_and_ids and the example annotations in the question, I get:
$ foo.pl GO.terms_and_ids file.gos 
DB  geneD   geneD       GO:0005634  PMID:foo    TAS     C   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0003677  PMID:foo    TAS     F   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0030154  PMID:foo    TAS     P   geneD       protein taxon:1000  20170308    DB       
Unknown GO term (GO:0006350) for gene geneD
DB  geneD   geneD       GO:0006355  PMID:foo    TAS     P   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0007275  PMID:foo    TAS     P   geneD       protein taxon:1000  20170308    DB       
DB  geneD   geneD       GO:0030528  PMID:foo    TAS     F   geneD       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0016020  PMID:foo    TAS     C   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0005524  PMID:foo    TAS     F   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0006468  PMID:foo    TAS     P   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0005737  PMID:foo    TAS     C   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0004674  PMID:foo    TAS     F   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0006914  PMID:foo    TAS     P   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0016021  PMID:foo    TAS     C   geneB       protein taxon:1000  20170308    DB       
DB  geneB   geneB       GO:0015031  PMID:foo    TAS     P   geneB       protein taxon:1000  20170308    DB       
DB  geneA   geneA       GO:0006950  PMID:foo    TAS     P   geneA       protein taxon:1000  20170308    DB       
DB  geneA   geneA       GO:0005737  PMID:foo    TAS     C   geneA       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0003779  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0006941  PMID:foo    TAS     P   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005524  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0003774  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005516  PMID:foo    TAS     F   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005737  PMID:foo    TAS     C   geneC       protein taxon:1000  20170308    DB       
DB  geneC   geneC       GO:0005863  PMID:foo    TAS     C   geneC       protein taxon:1000  20170308    DB       

Note that this is very much a pseudo-GAF file since most of the fields apart from the gene name, GO term and sub-ontology are fake. It should still work for what you need, however.

> **Comments:**
> **username_0**: I think the evidence code should be changed to IEA, because it is unlikely one would have manually annotated GO's for a non-model organism.  
> **username_3**: @Michael, it doesn't really make any difference so I chose TAS since these are annotations provided by the OP. But sure, IEA would also work. The field will be ignored in any case when doing an enrichment analysis so you can put whatever you prefer.  
> **username_0**: Sure, IEA might be even discarded by some tools.  

---

