1. biolab
  2. Untitled project
  3. orange-addon-golib

Commits

Tomaz Curk  committed 36996f1

GOlib is now merged into Genomics

  • Participants
  • Parent commits 2d9aa66
  • Branches default

Comments (0)

Files changed (7)

File LICENCE.txt

-GOLib a python library for handling gene ontologies
-
-Copyright (C) 2006  Ales Erjavec
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

File README.txt

-building
-
-run python setup.py build
-
-
-instaling
-
-run python setup.py install
-
-
-building Windows installer
-
-run python setup.py bdist_wininst

File doc/GOlib.html

-<html><HEAD>
-<LINK REL=StyleSheet HREF="style.css" TYPE="text/css" MEDIA=screen>
-<LINK REL=StyleSheet HREF="style-print.css" TYPE="text/css" MEDIA=print>
-</HEAD> <body>
-
-<h1>GOLib - A library for handling gene ontologies</h1>
-<index name="GOLib">
-<p>GOLib is an open source python library for handling of gene ontology (GO) databases released under the GPL licence
-<a href="http://www.geneontology.org/GO.doc.shtml"> (More about GO).</a> It is designed for fast searching and ease of use by using the power of python's expresive powers 
-combined with the speed of a C implemented search algorithm.
-</p>
-
-<p>Some of the basic uses that GOLib is sutible for:
-<ul>
-  <li>GO term manipulation in python</li>
-  <li>Searcing the GO for relevant terms</li>
-  <li>...</li>
-</ul>
-
-<h2>Downloading and loading the database</h2>
-<p><b><code>setDataDir(dataDir)</code></b></p>
-<index name ="setDataDir">
-<p>Set the data directory where the annotation and ontology files are stored (by default a directory named data
-located where the GOLib is instaled e.g. ...site-packages/GOLib/data)</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>dataDir</dt>
-  <dd>Path to the local data</dd>
-</dl>
-<br>
-
-<p><b><code>getDataDir()</code></b></p>
-<index name="getDataDir">
-<p>Get the data directory where the annotation and ontology files are stored (by default a directory named data 
-located where the GOLib is instaled e.g. ...site-packages/GOLib/data)</p>
-
-<p><b><code>downloadGO()</code></b></p>
-<index name = "downloadGO">
-<p>Downloads the curent gene ontology from 
-<a href="http://www.geneontology.org/ontology/gene_ontology.obo">http://www.geneontology.org/ontology/gene_ontology.obo</a> and saves on a local drive (You can specifie where with the <code>setDataDir</code> function</p>
-<br>
-
-<p><b><code>loadAnnotation(organism="sgd", forceReload=False, progressCallback=None)</code></b></p>
-<index name="loadAnnotation">
-<p>Loads the annotation for the specified organism</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>organism</dt>
-  <dd>Abbreviation of the organism you want to download (you can get the list of all available organisms with <code>listorganisms()</code> call).</dd>
-  <dt>forceReload</dt>
-  <dd>If True it will reload the database even if it is already loaded.</dd>
-</dl>
-<br>
-
-<p><b><code>loadGO(forceReload=False, progressCallback=None)</code></b></p>
-<index name="loadGO">
-<p>Loads the ontology from 'data_dir//gene_ontlogy.obo' where data_dir is set using setDataDir (default: .//data)</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>forceReload</dt>
-  <dd>If True it will reload the database even if it is already loaded.</dd>
-</dl>
-<br>
-
-<p><b><code>downloadAnnotation(organism="sgd")</code></b></p>
-<index name = "downloadAnnotation">
-<p>Downloads the annotation for the specified organism (e.g. "sgd", "fb", "mgi",...)</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>organism</dt>
-  <dd>Abbreviation of the organism you want to download (you can get the list of all available organisms with <code>listorganisms()</code> call).</dd>
-</dl>
-<br>
-
-<p><b><code>listOrganisms()</code></b></p>
-<index neme = "listOrganisms">
-<p>Connect to <a href="http://www.geneontology.org/GO.current.annotations.shtml">http://www.geneontology.org/GO.current.annotations.shtml</a>, parse out the organism names
-appearing in the table, and return the list of organisms.</p>
-<br>
-
-<p><b><code><index>listDownloadedOrganisms()</index></code></b></p>
-<index name ="listDownloadedOrganisms">
-<p>Returns a list with organism names off all local downloaded annotations</p>
-<XMP class=code>>>> import go
->>> go.downloadGO()
->>> go.listDownloadedorganisms()
-['ddb', 'sgd']
->>> go.listorganisms()
-['tigr_Aphagocytophilum', 'tair', 'tigr_Banthracis', 'goa_cow', 'tigr_Chydrogeno
-formans', 'wb', 'tigr_Cjejuni', 'cgd', 'tigr_Cburnetii', 'zfin', 'tigr_Dethenoge
-nes', 'ddb', 'fb', 'tigr_Echaffeensis', 'goa_chicken', 'tigr_Gsulfurreducens', '
-goa_human', 'GeneDB_Lmajor', 'tigr_Lmonocytogenes', 'tigr_Mcapsulatus', 'mgi', '
-tigr_Nsennetsu', 'gramene_oryza', 'goa_pdb', 'GeneDB_Pfalciparum', 'pseudocap',
-'tigr_Psyringae', 'rgd', 'sgd', 'GeneDB_Spombe', 'tigr_Soneidensis', 'tigr_Spome
-royi', 'GeneDB_Tbrucei', 'tigr_Tbrucei_chr2', 'goa_uniprot', 'tigr_Vcholerae']
->>> go.loadGO()
->>> go.loadAnnotation('sgd')
-</XMP>
-
-<h2>Acssessing the loaded data</h2>
-<p>The loaded data can be accessed by three fields in the go module:
-<ul>
-	<li>the <index>loadedGO</index> and </li>
-	<li><index>loadedSlimGO</index> whitch are of type GeneOntologyDB</li>
-	<li><index>loadedAnnotation</index> of type AnnotationDB</li>
-</ul>
-</p>
-
-<h2><index>GeneOntologyDB</index></h2>
-<index name = "classes+GeneOntologyDB">
-<p>An object holding the <index>ontology database</index>.</p>
-<p class=section>Members</p>
-<dl class=members>
-  <dt>terms</dt> 
-  <dd>List of instances of GOTerm class holding the details for each term</dd>
-  <dt>termDict</dt> 
-  <dd>A dictionary mapping GO id's to an instance of GOTerm class with that id</dd>
-  <dt>termDescriptorDict</dt> 
-  <dd>A dictionary mapping GO id's and alt_id's to a tuple (id, namespace, def, alt_id)</dd>
-  <dt>aliasMapper</dt> 
-  <dd>A dictionary mapping alt_id's and id's to id's</dd>
-</dl>
-
-<h2>AnnotationDB</h2>
-<index name = "classes+AnnotationDB">
-<p>An object holding the <index>annotation database</index>.</p>
-<p class=section>Members</p>
-<dl class=members>
-  <dt>geneNames</dt>
-  <dd>Names of all the genes in the annotation</dd>
-  <dt>annotationList</dt>
-  <dd>List of instances of Annotation class holding the details for each annotation record</dd>
-  <dt>aliasMapper</dt>
-  <dd>Alias mapper maps known aliases to gene names (column3 DB_Object_Symbol of annotation file)</dd>
-  <dt>geneNamesDict</dt>
-  <dd>A dictionary mapping any known alias to a list [DB_Object_ID, DB_Object_Symbol [,DB_Object_Synonym]] i.d. all known names</dd>
-  <dt>geneAnnotations</dt>
-  <dd>A dictionary mapping gene name (DB_Object_Symbol) to a list of all instances of Annotation with this name</dd>
-</dl>
-
-<h2>Mapping aliases to unique names</h2>
-<p>There are two dictionaries in the module's namespace for mapping known gene aliases and alternative GOId's to their respected unique identifiers.</p>
-<p></b><code>geneMapper</code></b> Maps known gene aliases(DB_Object_Synonym) to DB_Object_Name</p>
-<p></b><code>termMapper</code></b> Maps known GOterm alt_id's to unique GOId</p>
-<p class="header">Example: mapping gene names from aliases to unique names that can be used in a search (from <a href="golib.py">golib.py</a>)</p>
-<XMP class="code">geneNames=[ "YBR085W", ## synonim for AAC3
-			"AAD10",
-			"21S_rRNA_4" ##synonim for 21S_RRNA
-			]
-uniqueGeneNames = [go.geneMapper[name] for name in geneNames]
-print uniqueGeneNames #should print ["AAC3", "AAD10", "21S_rRNA_4"]
-</XMP>
-
-<h2>GOTerm</h2>
-<index name = "classes+GOTerm">
-<p>Holds the data for one term read from the ontology file. All fields from the ontology can be accsessed by their
-original name (e.g. the is_a field in the ontology can be accsessed like term.is_a - for more see <a href="http://geneontology.org/GO.format.obo-1_0.shtml">http://geneontology.org/GO.format.obo-1_0.shtml</a>), except for the def field that
-interferes with the python <code>def</code> statment and can be accesed like term._def or term.__dict__['def'].
-The fields that can have multiple values are stored as lists of strings otherwise the string after the field name from the
-ontology is supplied. If a field is not defined accessing it will result in an exception.
-The object also provides the folowing data memebers for quicker accsess: GOId, aspect, parents(list of GOId's of parents terms).</p>
-<p class=section>Some of the more frequently used GO tags (Again see <a href="http://geneontology.org/GO.format.obo-1_0.shtml#tags">http://geneontology.org/GO.format.obo-1_0.shtml</a> for more)</p>
-<dl class=methods>
-  <dt>id</dt>
-  <dd>The unique id of the term</dd>
-  <dt>name </dt>
-  <dd>The term name</dd>
-  <dt>alt_id</dt>
-  <dd>Defines an alternate id for this term</dd>
-  <dt>namespace</dt>
-  <dd>The namespace in which the term belongs (biological_process | cellular_component | molecular_function)</dd>
-  <dt>_def</dt>
-  <dd>The definition of the term</dd>
-  <dt>is_a</dt>
-  <dd>This tag describes a subclassing relationship between one term and another</dd>
-</dl>
-<p class="header">Example: printing some details of a GOTerms with keywords "catabolic" and "process" in their names (from <a href="golib.py">golib.py</a>)</p>
-<XMP class="code">selectedTerms=filter(lambda term: "catabolic" in term.name and "process" in term.name, go.loadedGO.terms)
-for term in selectedTerms:
-	print term.id, term.name, term._def
-</XMP>
-
-<h2>Annnotation</h2>
-<index name = "classes/annotation">
-<p>Holds the data for an annotation record read from the annotation file. Fields can be
-accessed with the names: DB, DB_Object_ID, DB_Object_Symbol, Qualifier, GO_ID, DB_Reference,
-Evidence_code, With_or_From, Aspect, DB_Object_Name, DB_Object_Synonym, DB_Object_Type, taxon,
-Date, Assigned_by (e.g. rec.GO_ID)
-or by supplying the original name of the field (see <a href="http://geneontology.org/GO.format.annotation.shtml">http://geneontology.org/GO.format.annotation.shtml</a> for further details)
-to the get method (e.g. rec.get("GO ID"))
-The object also provides the folowing data members for quicker access: geneName, GOId, evidence,
-aspect and alias(a list of aliases)</p>
-<p class=section>Atributes</p>
-<dl class=methods>
-  <dt>DB</dt>
-  <dd>Refers to the database from which the identifier in DB_Object_ID is drawn.</dd>
-  <dt>DB_Object_ID</dt>
-  <dd>A unique identifier in DB for the item</dd>
-  <dt>DB_Object_Symbol</dt>
-  <dd>A (unique and valid) string to which DB_Object_ID s matched</dd>
-  <dt>Qualifier</dt>
-  <dd>Flags that modify the interpretation of an annotation</dd>
-  <dt>GO_ID</dt>
-  <dd>GO id to whitch this entry is attributed</dd>
-  <dt>DB_Reference</dt>
-  <dd></dd>
-  <dt>Evidence_code</dt>
-  <dd>See <a href="http://geneontology.org/GO.evidence.shtml">http://geneontology.org/GO.evidence.shtml</a></dd>
-  <dt>With_or_From</dt>
-  <dd></dd>
-  <dt>Aspect</dt>
-  <dd>One of the strings "P" (biological process), "F" (molecular function) or "C" (cellular component)</dd>
-  <dt>DB_Object_Name</dt>
-  <dd>name of gene or gene product</dd>
-  <dt>DB_Object_Synonym</dt>
-  <dd>A list od synonym names for this gene</dd>
-  <dt>DB_Object_Type</dt>
-  <dd></dd>
-  <dt>taxon</dt>
-  <dd></dd>
-  <dt>Date</dt>
-  <dd>Date on which the annotation was made; format is YYYYMMDD</dd>
-  <dt>Assigned_by</dt>
-  <dd>The database which made the annotation one of the values from the set of <a href="http://geneontology.org/cgi-bin/xrefs.cgi">GO database cross-references</a></dd>
-</dl>
-
-<h2>Finding relevant GO terms</h2>
-<p>The GOLib's main functionality ...</p>
-<p><b><code>GOTermFinder(clusterGeneList, referenceGenes=None, evidenceCodes=None, slimsOnly=False, aspect="P", progressCallback=None)</code></b>-> {GOId : ([geneName, ...], float, int), ...}</p>
-<index name = "GOTermFinder">
-<p>The method accepts a list of cluster genes, optionally a list of reference genes (otherwise all annotated genes appearing in the loaded annotation file are used),
-and optionally a list of annotation evidence codes to use, otherwise all evidence codes are used. The slimsOnly argument indicates if only GO slims are to be used,
-otherwise all GO terms are considered. The progressCallback if present will be called with a single argument for all values in range [0..99].
-The method returns a dictionary of significant GO terms, items are tuples ([geneName, ...], p-value, nRef) where 
-<ul>
-  <li>[geneName, ...] is a list of cluster genes that map to the selected term</li>
-  <li>p-value is the probability that the mapping of the genes to this term is a coincidence given the reference distribution computed using a binomial distribution.</li>
-  <li>nRef is the number of reference genes that map to the term</li>
-</ul>
-</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>clusterGeneList</dt>
-  <dd>A list of gene names for whitch we want to find the matching relevant (w.r.t referenceGenes) GO terms</dd>
-  <dt>referenceGenes</dt>
-  <dd>A list of gene names used for reference. If None all genes in the currently loaded annotation are used.</dd>
-  <dt>evidenceCodes</dt>
-  <dd>A list of evidence codes to be considered. Only annotations with evidence in this list will be used. If None all evidences will be used.</dd>
-  <dt>slimsOnly</dt>
-  <dd>If True only slim terms will be returned (Set the slim terms using the setSlims function).</dd>
-  <dt>aspect</dt>
-  <dd>A string that determines to whitch top level term should the returned terms belong. Can be any of the folowing
-    "biological_process" or shorter "P" ,"cellular_component" or "C", "molecular_function" or "F"</dd>
-</dl>
-<p class="header">Example: Finding relevant GOTerms and printing them in ascending order (from <a href="golib.py">golib.py</a>)</p>
-<XMP class="code">def call(i): print i
-res=go.GOTermFinder(uniqueGeneNames, progressCallback=call)
-res=res.items()
-res.sort(lambda (_1,(_2,a,_3)), (_4,(_5,b,_6)): cmp(a,b))
-for GOId,(genes, p, n) in res:
-	print GOId, p, genes
-</XMP>
-
-<p><b><code>findTerms(geneList, slimsOnly=False, aspect=["F","C","P"], directAnnotationOnly=False, evidenceCodes=None, reportEvidence=True, progressCallback=None)</code></b></p>
-<index name= "findTerms">
-<p>For each gene in geneList search for matching GO terms. Argument slimsOnly restricts the GO terms to the slim set. The method returns a dictionary where key is a
-matching GO term and items are (gene, evidence) if reportEvidence == True [gene only, if reportEvidence=False] that map to the term. Climb the GO if directAnnotationOnly=False,
-otherwise report direct annotation only.</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>geneList</dt>
-  <dd>List of genes to find the terms for.</dd>
-  <dt>slimsOnly</dt>
-  <dd>If True only slim terms will be returned (Set the slim terms using the setSlims function).</dd>
-  <dt>aspect</dt>
-  <dd>A string that determines to whitch top level term should the returned terms belong. Can be any of the folowing
-    "biological_process" or shorter "P" ,"cellular_component" or "C", "molecular_function" or "F"</dd>
-  <dt>directAnnotationOnly</dt>
-  <dd>If true only the terms to whitch the genes map directly will be returned, otherwise all predecessor terms up to the root term will also be returned</dd>
-  <dt>evidenceCodes</dt>
-  <dd>A list of evidence codes to be considered. Only annotations with evidence in this list will be used. If None all evidences will be used.</dd>
-  <dt>reportEvidence</dt>
-  <dd>If True a list of evidence codes for each gene-term mapping will also be returned.</dd>
-</dl>
-
-<p><b><code>findGenes(GOTerms=[], directAnnotationOnly=False, evidenceCodes=None, reportEvidence=True, progressCallback=None)</code></b></p>
-<index name = "findGenes">
-<p>Return a dictionary where key is a matching gene and items are (GO terms) or (GO term, list of evidences) from the GOterms list.
-(Note this will take a lot of time if the directAnnotationOnly=False)</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>GOTerms</dt>
-  <dd>A list of GO terms to find the genes for.</dd>
-  <dt>directAnnotationOnly</dt>
-  <dd>If true only the terms to whitch the genes map directly will be returned, otherwise all predecessor terms up to the root term will also be returned</dd>
-  <dt>evidenceCodes</dt>
-  <dd>A list of evidence codes to be considered. Only annotations with evidence in this list will be used. If None all evidences will be used.</dd>
-  <dt>reportEvidence</dt>
-  <dd>If True a list of evidence codes for each gene-term mapping will also be returned.</dd>
-</dl>
-
-<p><b><code>extractGODAG(GOTerms=[])</code></b></p>
-<index name ="extractGODAG">
-<p>Returns the part of GO DAG that includes the listed GOTerms.</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>GOTerms</dt>
-  <dd>A list of GO terms.</dd>
-</dl>
-
-<p><b><code>setSlims(slims=None)</code></b></p>
-<index name ="setSlims">
-<p>Set the slim subset of a loaded ontology. 
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>slims</dt>
-  <dd>Can be a:
-  <ul>
-        <li>-a string identifier of a subsetdef: (e.g. "goslim_generic", "goslim_plant" ...) in the currently loaded ontology</li>
-        <li>-a filename of a slim ontology (e.g. "goslim_generic.obo" ...)</li>
-        <li>-a list of GO term id's</li>
-  </ul>
-</dl>
-
-<h2>Visualizing Enrichment Analysis</h2>
-<p>GOLib can visualize the enrichment analysis with a cone simple command.</p>
-<p><b><code>drawEnrichmentGraph(GOTerms, filename="graph.png", width=None, height=None)</code></b></p>
-<index name = "drawEnrichmentGraph">
-<p>Draws a graph of GOTerms</p>
-<p class=section>Arguments</p>
-<dl class=arguments>
-  <dt>GOTerms</dt>
-  <dd>Dictionary of terms (same structure as returned from GOTermFinder)</dd>
-  <dt>filename</dt>
-  <dd>Where to save the picture</dd>
-  <dt>width, height</dt>
-  <dd>Are optional (reasonable defaults are assumed) and serve only as a hint</dd>
-</dl>
-<p class="header">Example: (from <a href="golib.py">golib.py</a>)</p>
-<XMP class="code">terms=go.GOTermFinder(uniqueGeneNames)
-terms=go.filterByPValue(terms, 0.2)
-go.drawEnrichmentGraph(terms, "enrichment_graph.png", width=600)
-</XMP>
-<p>produces the folowing image</p>
-<img src="enrichment_graph.png">
-</body>
-</html>
-  

File doc/enrichment_graph.png

Removed
Old image

File go.c

-#include<Python.h>
-#include<structmember.h>
-#include<string.h>
-#include<stdio.h>
-
-#define RAISE_TYPE_ERROR(error) PyErr_SetString(PyExc_TypeError, error); Py_INCREF(PyExc_TypeError);
-#ifndef MAX
-#define MAX(a,b) (((a)<(b))?(b):(a))
-#endif
-
-struct _TermNode;
-typedef struct _TermNode{
-	char* id;
-	struct _TermNode* next;
-} TermNode;
-
-TermNode* makeTermNode(char* id){
-	TermNode* tmp=malloc(sizeof(TermNode));
-	tmp->id=id;
-	tmp->next=NULL;
-	return tmp;
-}
-
-typedef struct{
-	TermNode* head;
-	TermNode* tail;
-} TermList;
-
-TermList* makeTermList(){
-	TermList *list=malloc(sizeof(TermList));
-	memset(list, 0, sizeof(TermList));
-	return list;
-}
-
-void addTermNode(TermList* list, TermNode* node){
-	TermNode* tmp=list->head;
-	list->head=node;
-	node->next=tmp;
-	if(!list->tail)
-		list->tail=node;
-}
-
-void clearTermList(TermList* list){
-	TermNode* node=list->head;
-	while(node){
-		TermNode* tmp=node;
-		node=node->next;
-		free(tmp);
-	}
-	list->head=NULL;
-	list->tail=NULL;
-}
-
-struct _GeneEvidenceNode;
-typedef struct _GeneEvidenceNode{
-	char *geneName;
-	int evidence;
-	struct _GeneEvidenceNode* next;
-} GeneEvidenceNode;
-
-GeneEvidenceNode* makeGeneEvidenceNode(char* name, int evidence){
-	GeneEvidenceNode* tmp=malloc(sizeof(GeneEvidenceNode));
-	tmp->geneName=name;
-	tmp->evidence=evidence;
-	tmp->next=NULL;
-	return tmp;
-}
-
-typedef struct {
-	GeneEvidenceNode* head;
-	GeneEvidenceNode* tail;
-} GeneEvidenceList;
-
-GeneEvidenceList* makeGeneEvidenceList(){
-	GeneEvidenceList *list=malloc(sizeof(GeneEvidenceList));
-	memset(list, 0, sizeof(GeneEvidenceList));
-	return list;
-}
-
-void addGeneEvidenceNode(GeneEvidenceList* list, GeneEvidenceNode* node){
-	GeneEvidenceNode* tmp=list->head;
-	list->head=node;
-	node->next=tmp;
-	if(!list->tail)
-		list->tail=node;
-}
-
-void clearGeneEvidenceList(GeneEvidenceList* list){
-	GeneEvidenceNode* node=list->head;
-	while(node){
-		GeneEvidenceNode* tmp=node;
-		node=node->next;
-		free(tmp);
-	}
-
-	list->head=NULL;
-	list->tail=NULL;
-}
-
-struct _hash_entry;
-typedef struct _hash_entry{
-	char *key;
-	void *ptr;
-	struct _hash_entry* next;
-}hash_entry;
-
-typedef struct{
-	int buckets;
-	hash_entry * entries;
-}hash_table;
-
-hash_entry* makeHashEntry(char* key, void* ptr){
-	hash_entry* tmp=malloc(sizeof(hash_entry));
-	tmp->key=strdup(key);
-	tmp->ptr=ptr;
-	tmp->next=NULL;
-	return tmp;
-}
-
-unsigned int hash_fun(char* key, int maxVal){
-	unsigned int sum=0;
-	maxVal=MAX(maxVal, 1);
-	while(*key){
-		sum=sum*131+ *key;
-		key++;
-	}
-	return sum%maxVal;
-}
-
-void* hash_add(hash_table* hash, char* key, void* ptr){
-	unsigned int hashVal=hash_fun(key, hash->buckets);
-	hash_entry* entry=&hash->entries[hashVal];
-	if(entry->key){	//conflict
-		while(entry->next){
-			/*if the key allready in the hash table replace the ptr and 
-			return the old ptr*/
-			if(!strcmp(entry->key, key)){ 
-				void *tmp=entry->ptr;
-				entry->ptr=ptr;
-				printf("replacing hash entry %s\n", key);
-				return tmp;
-			}
-			entry=entry->next;
-		}
-		entry->next=makeHashEntry(key, ptr);
-	}
-	else {
-		entry->key=strdup(key);
-		entry->ptr=ptr;
-		entry->next=NULL;
-	}
-	return NULL;
-}
-
-#define HASH_MISS (void*)-1
-
-void *hash_get(hash_table* hash, char* key){
-	int hashVal=hash_fun(key, hash->buckets);
-	hash_entry* entry=&hash->entries[hashVal];
-	//printf("hash of %s:%i\n", key, hashVal);
-	while(entry && entry->key)
-		if(strcmp(key, entry->key)==0)
-			return entry->ptr;
-		else{
-			//printf("%s", entry->key);
-			entry=entry->next;
-		}
-	//printf("HASH MISS: %s\n",key);
-	return HASH_MISS;
-}
-
-char hash_has_key(hash_table* hash, char* key){
-	return hash_get(hash, key)!=HASH_MISS;
-}
-
-hash_table* makeHashTable(int buckets){
-	hash_table* hash=malloc(sizeof(hash_table));
-	hash->buckets=MAX(buckets,1);
-	hash->entries=malloc(sizeof(hash_entry)*buckets);
-	memset(hash->entries, 0, sizeof(hash_entry)*buckets);
-	return hash;
-}
-
-void freeHashTable(hash_table* table){
-	hash_entry* entry=NULL;
-	hash_entry* tmp=NULL;
-	int i;
-	for(i=0;i<table->buckets;i++){
-		entry=&table->entries[i];
-		if(entry->key)
-			free(entry->key);
-		entry=entry->next;
-		while(entry){
-			free(entry->key);
-			tmp=entry;
-			entry=entry->next;
-			free(tmp);
-		}
-	}
-	free(table->entries);
-	free(table);
-}
-
-typedef struct{
-	char* goID;
-	GeneEvidenceList mappedGenes;
-	TermList parents;
-	TermList children;
-	int numRef;
-	int code;
-	char visited;
-} GOTerm;
-
-typedef struct{
-	char* name;
-	char* goID;
-	int aspect;
-	int evidence;
-} AnnRecord;
-
-typedef struct{
-	PyObject_HEAD
-	PyObject* aliasMapper;
-	hash_table* hash;
-	AnnRecord* annotation;
-	int numGenes;
-} Annotation;
-
-static PyMemberDef Annotation_members[]={
-	{"aliasMapper", T_OBJECT_EX, offsetof(Annotation,aliasMapper), 0, ""},
-	{NULL}
-};
-typedef struct{
-	PyObject_HEAD
-	PyObject* aliasMapper;
-	int aspect;
-	hash_table* hash;
-	GOTerm *terms;
-} Ontology;
-
-static PyMemberDef Ontology_members[]={
-	{"aliasMapper", T_OBJECT_EX, offsetof(Ontology, aliasMapper), 0, ""},
-	{NULL}
-};
-
-void prepareGOTerms(Ontology* ontology);
-
-static void Annotation_dealloc(Annotation* self){
-	AnnRecord* rec=self->annotation;
-	//printf("Annotation.dealloc\n");
-	while(rec->name){
-		free(rec->name);
-		free(rec->goID);
-		rec++;
-	}
-	free(self->annotation);
-	freeHashTable(self->hash);
-	Py_XDECREF(self->aliasMapper);
-	self->ob_type->tp_free(self);
-}
-
-static void Ontology_dealloc(Ontology* self){
-	GOTerm* term=NULL;
-	TermNode* node=NULL;
-	//printf("Ontology.dealloc\n");
-	prepareGOTerms(self);
-	term=self->terms;
-	while(term->goID){
-		/* free the parent list of the term*/
-		node=term->parents.head;
-		while(node){
-			free(node->id);
-			node=node->next;
-		}
-		clearTermList(&term->parents);
-		clearTermList(&term->children);
-
-		free(term->goID);
-		term++;
-	}
-	freeHashTable(self->hash);
-	free(self->terms);
-	Py_XDECREF(self->aliasMapper);
-	self->ob_type->tp_free(self);
-}
-
-static PyTypeObject go_AnnotationType={
-	PyObject_HEAD_INIT(NULL)
-	0,                         /*ob_size*/
-    "go.Annotation",           /*tp_name*/
-    sizeof(Annotation),        /*tp_basicsize*/
-    0,                         /*tp_itemsize*/
-    (destructor)Annotation_dealloc,  /*tp_dealloc*/
-    0,                         /*tp_print*/
-    0,                         /*tp_getattr*/
-    0,                         /*tp_setattr*/
-    0,                         /*tp_compare*/
-    0,                         /*tp_repr*/
-    0,                         /*tp_as_number*/
-    0,                         /*tp_as_sequence*/
-    0,                         /*tp_as_mapping*/
-    0,                         /*tp_hash */
-    0,                         /*tp_call*/
-    0,                         /*tp_str*/
-    0,                         /*tp_getattro*/
-    0,                         /*tp_setattro*/
-    0,                         /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
-    "Holds the annotation records",      /*tp_doc*/
-	0,		               /* tp_traverse */
-    0,		               /* tp_clear */
-    0,		               /* tp_richcompare */
-    0,		               /* tp_weaklistoffset */
-    0,		               /* tp_iter */
-    0,		               /* tp_iternext */
-    0,                     /* tp_methods */
-    Annotation_members,             /* tp_members */
-
-};
-
-static PyTypeObject go_OntologyType={
-	PyObject_HEAD_INIT(NULL)
-	0,                         /*ob_size*/
-    "go.Ontology",               /*tp_name*/
-    sizeof(Ontology),            /*tp_basicsize*/
-    0,                         /*tp_itemsize*/
-    (destructor)Ontology_dealloc,      /*tp_dealloc*/
-    0,                         /*tp_print*/
-    0,                         /*tp_getattr*/
-    0,                         /*tp_setattr*/
-    0,                         /*tp_compare*/
-    0,                         /*tp_repr*/
-    0,                         /*tp_as_number*/
-    0,                         /*tp_as_sequence*/
-    0,                         /*tp_as_mapping*/
-    0,                         /*tp_hash */
-    0,                         /*tp_call*/
-    0,                         /*tp_str*/
-    0,                         /*tp_getattro*/
-    0,                         /*tp_setattro*/
-    0,                         /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
-    "Holds the go terms",      /*tp_doc*/
-	0,		               /* tp_traverse */
-    0,		               /* tp_clear */
-    0,		               /* tp_richcompare */
-    0,		               /* tp_weaklistoffset */
-    0,		               /* tp_iter */
-    0,		               /* tp_iternext */
-    0,                     /* tp_methods */
-    Ontology_members,             /* tp_members */
-};
-
-GOTerm* getGOTerm(Ontology* ontology, char* id){
-	GOTerm* term=hash_get(ontology->hash, id);
-	if(term==HASH_MISS && PyMapping_Check(ontology->aliasMapper) && PyMapping_HasKeyString(ontology->aliasMapper, id)){
-		PyObject* string=PyMapping_GetItemString(ontology->aliasMapper, id);
-		id=PyString_AsString(string);
-		term=hash_get(ontology->hash, id);
-		Py_DECREF(string);
-	}
-	/*if(term==HASH_MISS)
-		printf("HASH MISS: %s\n",id);*/
-
-	return term;
-}
-
-AnnRecord* getAnnRecord(Annotation* annotation, char* gene){
-	AnnRecord* rec=hash_get(annotation->hash, gene);
-	if(rec==HASH_MISS && PyMapping_Check(annotation->aliasMapper) && PyMapping_HasKeyString(annotation->aliasMapper, gene)){
-		PyObject* string=PyMapping_GetItemString(annotation->aliasMapper, gene);
-		gene=PyString_AsString(string);
-		rec=hash_get(annotation->hash, gene);
-		Py_DECREF(string);
-	}
-	/*if(rec==HASH_MISS)
-		printf("HASH MISS: %s\n",gene);*/
-	return rec;
-}
-
-GOTerm makeGOTerm(PyObject* tuple){
-	GOTerm term;
-	memset(&term, 0, sizeof(GOTerm));
-	if(tuple && PyTuple_Check(tuple)){
-		char* id=strdup(PyString_AsString(PyTuple_GetItem(tuple, 0)));
-		PyObject* parents=PyTuple_GetItem(tuple, 1);
-		int nParents=0;
-		TermList parentList;
-		parentList.head=NULL;
-		parentList.tail=NULL;
-		if(PyList_Check(parents) && (nParents=PyList_Size(parents))){
-			PyObject* iter=PyObject_GetIter(parents);
-			PyObject* item=NULL;
-			while((item=PyIter_Next(iter))){
-				addTermNode(&parentList, makeTermNode(strdup(PyString_AsString(item))));
-				Py_DECREF(item);
-			}
-			Py_DECREF(iter);
-		}
-		term.goID=id;
-		term.parents=parentList;
-		term.children.head=NULL;
-		term.children.tail=NULL;
-		return term;
-	}
-	else{
-		printf("Could not create a proper GOTerm");
-		term.goID="Uninitialized GO Term";
-		term.parents.head=NULL;
-		term.parents.tail=NULL;
-		term.children.head=NULL;
-		term.children.tail=NULL;
-		return term;
-	}
-}	
-
-AnnRecord makeAnnRecord(PyObject* tuple){
-	AnnRecord ann;
-	memset(&ann, 0, sizeof(AnnRecord));
-	if(tuple && PyTuple_Check(tuple)){
-		ann.name=strdup(PyString_AsString(PyTuple_GetItem(tuple, 0)));
-		ann.goID=strdup(PyString_AsString(PyTuple_GetItem(tuple, 1)));
-		ann.evidence=PyInt_AsLong(PyTuple_GetItem(tuple, 2));
-		ann.aspect=PyInt_AsLong(PyTuple_GetItem(tuple,3));
-	} else{
-		printf("Not a tuple. Failed to build a proper AnnRecord\n");
-		ann.name="Uninitialized annotation record";
-		ann.goID=NULL;
-		ann.evidence=0;
-		ann.aspect=0;
-	}
-	return ann;
-}
-
-PyObject* parseGOTerms(PyObject* self, PyObject* args){
-	PyObject* terms=NULL;
-	PyObject* iter=NULL;
-	PyObject* item=NULL;
-	PyObject* aliasMapper=Py_None;
-	GOTerm* goTerms=NULL;
-	GOTerm* ptr=NULL;
-	hash_table* hash=NULL;
-	Ontology *base=NULL;
-	int nTerms=0;
-	int maxTerms=0;
-	if(!PyArg_ParseTuple(args, "O|O:parseGOTerms", &terms, &aliasMapper)){
-		return NULL;
-	}
-	if(!PyList_Check(terms)){
-		RAISE_TYPE_ERROR("Wrong argument type. Need a list");
-		return NULL;
-	}
-	nTerms=PyList_Size(terms);
-	maxTerms=nTerms+1;
-	goTerms=malloc(sizeof(GOTerm)*maxTerms);
-	memset(goTerms, 0, sizeof(GOTerm)*maxTerms);
-	hash=makeHashTable(nTerms*3/2);
-	iter=PyObject_GetIter(terms);
-	ptr=goTerms;
-	while((item=PyIter_Next(iter))){
-		(*ptr)=makeGOTerm(item);
-		hash_add(hash, ptr->goID, ptr);
-		Py_DECREF(item);
-		ptr++;
-	}
-	Py_DECREF(iter);
-	base=(Ontology*)go_OntologyType.tp_new(&go_OntologyType, NULL, NULL);
-	base->terms=goTerms;
-	base->hash=hash;
-	base->aliasMapper=aliasMapper;
-	Py_INCREF(aliasMapper);
-	ptr=goTerms;
-	while(ptr->goID){
-		TermNode* node=ptr->parents.head;
-		while(node){
-			GOTerm* term=getGOTerm(base, node->id);
-			if(term!=HASH_MISS)
-				addTermNode(&term->children, makeTermNode(ptr->goID));
-			node=node->next;
-		}
-		ptr++;
-	}
-	return (PyObject*)base;
-}
-	
-PyObject* parseAnnotation(PyObject* self, PyObject* args){
-	PyObject* ann=NULL;
-	PyObject* iter=NULL;
-	PyObject* item=NULL;
-	PyObject* aliasMapper=Py_None;
-	AnnRecord* annotation=NULL;
-	AnnRecord* ptr=NULL;
-	Annotation* annot=NULL;
-	hash_table *hash=NULL;
-
-	char* lastName="I'm Bender baby! Please insert liquor!";
-	int nAnn=0;
-	int annSize=0;
-	int numGenes=0;
-	if(!PyArg_ParseTuple(args, "O|O:parseAnnotation", &ann, &aliasMapper)){
-		return NULL;
-	}
-	if(!PyList_Check(ann)){
-		RAISE_TYPE_ERROR("Need a list");
-		return NULL;
-	}
-	iter=PyObject_GetIter(ann);
-	nAnn=PyList_Size(ann);
-	annSize=nAnn+1;
-	annotation=malloc(sizeof(AnnRecord)*annSize);
-	memset(annotation, 0, sizeof(AnnRecord)*annSize);
-	hash=makeHashTable(annSize);
-	ptr=annotation;
-	while((item=PyIter_Next(iter))){
-		*ptr=makeAnnRecord(item);
-		if(strcmp(ptr->name, lastName)){
-			hash_add(hash, ptr->name, ptr);
-			lastName=ptr->name;
-			numGenes++;
-		}
-		ptr++;
-		Py_DECREF(item);
-	}
-	Py_DECREF(iter);
-	annot=(Annotation*)go_AnnotationType.tp_new(&go_AnnotationType, NULL, NULL);
-	annot->annotation=annotation;
-	annot->hash=hash;
-	annot->aliasMapper=aliasMapper;
-	annot->numGenes=numGenes;
-	Py_INCREF(aliasMapper);
-	return (PyObject*)annot; 
-}
-
-void prepareGOTerms(Ontology* base){
-	GOTerm* term=base->terms;
-	while(term->goID){
-		term->visited=0;
-		term->code=0;
-		term->numRef=0;
-		clearGeneEvidenceList(&term->mappedGenes);
-		term++;
-	}
-}
-
-void markTerms(GOTerm* term, Ontology* ontology, char* geneName, int evidence, char recursive, TermList* selected){
-	/*check if the gene allready on the selected list*/
-    TermNode *tnode=selected->head;
-	GeneEvidenceNode* gnode=term->mappedGenes.head;
-    while(tnode && strcmp(tnode->id, term->goID))
-		tnode=tnode->next;
-    /*if not add it*/
-	if(!tnode){
-		//printf("selected node %s\n", term->goID);
-		addTermNode(selected, makeTermNode(term->goID));
-	}
-		
-	/*add the gene/evidence to the term */
-	
-	while(gnode && strcmp(gnode->geneName, geneName))
-		gnode=gnode->next;
-	if(gnode)
-		gnode->evidence|=evidence;
-	else
-		/*add the gene name to term*/
-		addGeneEvidenceNode(&term->mappedGenes, makeGeneEvidenceNode(geneName, evidence));
-	//printf("marking term %s\n", term->goID);
-
-	if(recursive){
-		tnode=term->parents.head;
-		while(tnode){
-			if((term=getGOTerm(ontology, tnode->id))!=HASH_MISS)
-				markTerms(term, ontology, geneName, evidence, recursive, selected);
-			tnode=tnode->next;
-		}
-	}
-}
-
-#define DIRECT_MAPPING 1
-#define INDIRECT_MAPPING 2
-
-void clearVisited(Ontology* go){
-	GOTerm* term=go->terms;
-	while(term->goID){
-		term->visited=0;
-		term++;
-	}
-}
-
-/*recursivly mark ALL parents of a term to map indirectly, including
- the ones that are allready marked as direct  */
-void _slimMapping2(GOTerm* term, Ontology* ontology, Ontology* slimOntology, TermList* list){
-	GOTerm* parent=NULL;
-	TermNode* parentNode=NULL;
-	parentNode=term->parents.head;
-	while(parentNode){
-		if((parent=getGOTerm(ontology, parentNode->id))==HASH_MISS){
-			parentNode=parentNode->next;
-			continue;
-		}
-		parent->visited=INDIRECT_MAPPING;
-		_slimMapping2(parent, ontology, slimOntology, list);
-		parentNode=parentNode->next;
-	}
-}
-
-void _slimMapping1(GOTerm* term, Ontology* ontology, Ontology* slimOntology, TermList* list){
-	GOTerm* parent=NULL;
-	TermNode* parentNode=NULL;
-	parentNode=term->parents.head;
-	while(parentNode){
-		if((parent=getGOTerm(ontology, parentNode->id))==HASH_MISS){
-			parentNode=parentNode->next;
-			continue;
-		}
-		
-		if(getGOTerm(slimOntology, parent->goID)!=HASH_MISS && parent->visited==0){
-			/*if the parent in the slims subset and not yet visited
-			mark it and add it to the list and recursivly mark ALL parents of 
-			a term to map indirectly, including the ones that are allready marked as direct*/
-			parent->visited=DIRECT_MAPPING;
-			addTermNode(list, makeTermNode(parent->goID));
-			_slimMapping2(parent, ontology, slimOntology, list);
-		}else if(parent->visited==0)
-			/*else if not yet visited, NOTE:do nothing if term allready visited*/
-			_slimMapping1(parent, ontology, slimOntology, list);
-		parentNode=parentNode->next;
-	}
-}
-
-
-void slimMapping(GOTerm* term, Ontology* ontology, Ontology* slimOntology, TermList* list){
-	clearVisited(ontology);
-	if(getGOTerm(slimOntology, term->goID)!=HASH_MISS){
-		/*the term is allready in the slim subset*/
-		term->visited=DIRECT_MAPPING;
-		addTermNode(list, makeTermNode(term->goID));
-		return;
-	}
-	//printf("mapping slim: %s\n", goId);
-	_slimMapping1(term, ontology, slimOntology, list);
-}
-
-TermList* findTerms(char** geneName, int evidence, int aspect, char slimsOnly, char recursive, Annotation* annotation, Ontology* ontology, Ontology* slimOntology, PyObject* callback, int step, int start){
-	TermList* list=malloc(sizeof(TermList));
-	GOTerm* term=NULL;
-	int count=0;
-	list->head=NULL;
-	list->tail=NULL;
-
-	while(*geneName){
-		AnnRecord* ann=NULL;
-		char *mappedGeneName=NULL;
-		count++;
-		if(callback && count%step==0 && start<=100)
-			PyObject_CallFunction(callback, "i", start++);
-
-		if((ann=getAnnRecord(annotation, *geneName))==HASH_MISS){
-			printf("unknown geneName %s\n", *geneName);
-			geneName++;
-			continue;
-		}
-		
-		mappedGeneName=ann->name;
-		while(ann->name && !strcmp(ann->name, mappedGeneName)){
-			if((ann->aspect & aspect) && (evidence & ann->evidence)){
-				TermList termList;
-				TermNode* node=NULL;
-				if((term=getGOTerm(ontology, ann->goID))==HASH_MISS){
-					ann++;
-					continue;
-				}
-				memset(&termList, 0, sizeof(TermList));
-				if(slimsOnly && slimOntology){
-					slimMapping(term, ontology, slimOntology, &termList);
-					node=termList.head;
-					while(node){
-						if((term=getGOTerm(ontology, node->id))!=HASH_MISS && term->visited==DIRECT_MAPPING)
-							markTerms(term, ontology, *geneName, ann->evidence, recursive, list);
-						node=node->next;
-					}
-				}else
-					markTerms(term, ontology, *geneName, ann->evidence, recursive, list);
-				clearTermList(&termList);
-			}
-			ann++;
-		}
-		geneName++;
-	}
-	return list;
-}
-
-void addReference(GOTerm* term, Ontology* ontology, int code){
-	TermNode* node=NULL;
-	if(term->code==code)
-		return;
-	term->numRef++;
-	term->code=code;
-	//printf("adding ref %s\n", term->goID);
-
-	node=term->parents.head;
-	while(node){
-		if((term=getGOTerm(ontology, node->id))!=HASH_MISS)
-			addReference(term, ontology, code);
-		node=node->next;
-	}
-}
-
-void mapReferenceGenes(char** geneName, int evidence, int aspect, Annotation* annotation, Ontology* ontology, PyObject* callback, int step, int start){
-	GOTerm* term=NULL;
-	int markCode=1;
-	int count=0;
-	while(*geneName){
-		AnnRecord* ann=NULL;
-		char *mappedGeneName=NULL;
-		count++;
-		if(callback && count%step==0)
-			PyObject_CallFunction(callback, "i",start++);
-
-		if((ann=getAnnRecord(annotation, *geneName))==HASH_MISS){
-			printf("unknown geneName %s\n", *geneName);
-			geneName++;
-			continue;
-		}
-		mappedGeneName=ann->name;
-		//printf("%s, %s\n", *geneName, ann->name);
-		while(ann->name && strcmp(ann->name, mappedGeneName)==0){
-			//printf("mapping term %s\n", ann->goID);
-			if((term=getGOTerm(ontology, ann->goID))==HASH_MISS){
-				ann++;
-				continue;
-			}
-			if((ann->aspect & aspect)&&
-				(evidence & ann->evidence)){
-
-				addReference(term, ontology, markCode);
-			}
-			ann++;
-		}
-		markCode++;
-		geneName++;
-	}
-}
-
-char** mapStrings(PyObject* list){
-	int len=0;
-	char** strings=NULL;
-	char** ptr=NULL;
-	PyObject* iter=NULL;
-	PyObject* item=NULL;
-	if(!PyList_Check(list))
-		return NULL;
-	len=PyList_Size(list)+1;
-	strings=malloc(sizeof(char*)*len);
-	iter=PyObject_GetIter(list);
-	ptr=strings;
-	while((item=PyIter_Next(iter))){
-		*ptr=PyString_AsString(item);
-		Py_DECREF(item);
-		ptr++;
-	}
-	*ptr=NULL;	//sentry
-	Py_DECREF(iter);
-	return strings;
-}
-
-void freeMappedStrings(char** ptr){
-	char **tmp=ptr;
-	/*while(*ptr){
-		free(*ptr);
-		ptr++;
-	}*/
-	free(tmp);
-}
-
-double* log_sum_lookup(int size){
-	double* data=(double*) malloc(sizeof(double)*(size+1));
-	int i=0;
-	data[0]=0;
-	data[1]=0;
-	for(i=2;i<=size;i++)
-		data[i]=data[i-1]+log(i);
-	return data;
-}
-
-double logbin(int n, int r, double* lookup){
-	return lookup[n]-lookup[n-r]-lookup[r];
-
-/*	double sum=0;
-	int i=0;
-	//int t=(n-r+1>2)? n-r+1 : 2;
-	for(i=n;i>=n-r+1;--i)
-		sum+=log(i);
-	for(i=2;i<=r;++i)
-		sum-=log(i);
-	return sum;*/
-}
-
-double binomial(int n, int r, double p, double* lookup){
-	if(p==0.0){
-		if(r==0.0)
-			return 0.0;
-		else if(r>0.0)
-			return 1.0;
-	}else if(p==1.0){
-		if(n==r)
-			return 1.0;
-		else if(n>r)
-			return 0.0;
-	}
-	return exp(logbin(n, r, lookup)+r*log(p)+(n-r)*log(1.0-p));
-}
-		
-double p_value(int nClusterGenes, int nRefGenes, int nGenesMapped, int numRefGenesMapped, double* lookup){
-	double sum=0;
-	double p=(double)numRefGenesMapped/(double)nRefGenes;
-	int i=0;
-//	if(p>=1.0 || p<=0.0)
-//		printf("p==%f\n",p);
-	for(i=nGenesMapped;i<=nClusterGenes;i++)
-		sum+=binomial(nClusterGenes,i,p,lookup);
-	return sum;
-}
-
-PyObject* GOTermFinder(PyObject *self, PyObject* args){
-	PyObject* pyGenes=NULL;
-	PyObject* pyRefGenes=NULL;
-	PyObject* callback=NULL;
-	Annotation* annotation=NULL;
-	Ontology* ontology=NULL;
-	Ontology* slimOntology=NULL;
-	int evidence=0;
-	int aspect=0;
-	int numGenes;
-	int numRefGenes=0;
-	int progressStep=0;
-	double* loglookup=NULL;
-	char slimsOnly=0;
-	char** genes=NULL;
-	char** refGenes=NULL;
-	PyObject* result=NULL;
-	TermList* list=NULL;
-	TermNode* node=NULL;
-	//printf("Arg parsing\n");
-	if(!PyArg_ParseTuple(args, "OObiiO!O!|OO:GOTermFinder", &pyGenes, &pyRefGenes, &slimsOnly, &evidence, &aspect,
-		&go_AnnotationType, &annotation, &go_OntologyType, &ontology,  &slimOntology, &callback)){
-		return NULL;
-	}
-	if(!PyList_Check(pyGenes) || !PyList_Check(pyRefGenes)){
-		RAISE_TYPE_ERROR("Need a list");
-		return NULL;
-	}
-	if(callback==Py_None || !PyCallable_Check(callback))
-		callback=NULL;
-	numGenes=PyList_Size(pyGenes);
-	numRefGenes=PyList_Size(pyRefGenes);
-	progressStep=(numGenes+numRefGenes)/100;
-	//printf("mapping names\n");
-	genes=mapStrings(pyGenes);
-	refGenes=mapStrings(pyRefGenes);
-	prepareGOTerms(ontology);
-	//printf("mapping ref\n");
-	mapReferenceGenes(refGenes, evidence, aspect, annotation, ontology, callback, MAX(numRefGenes/100,1), 0);
-	//printf("finding terms\n");
-	list=findTerms(genes, evidence, aspect, slimsOnly, 1, annotation, ontology, slimOntology, callback, MAX(numGenes/100,1), 0);
-	node=list->head;
-	result=PyDict_New();
-	loglookup=log_sum_lookup(numGenes);
-	while(node){
-		PyObject* geneList=PyList_New(0);
-		GOTerm* term=hash_get(ontology->hash, node->id);
-		GeneEvidenceNode* ptr=term->mappedGenes.head;
-		int numMapped=0;
-		double pValue=0;
-		while(ptr){
-			PyObject* val=Py_BuildValue("s", ptr->geneName);
-			PyList_Append(geneList, val);
-			Py_DECREF(val);
-			numMapped++;
-			ptr=ptr->next;
-		}
-		pValue = p_value(numGenes, numRefGenes, numMapped,  term->numRef, loglookup);
-		PyObject* value = Py_BuildValue("Odi", geneList, pValue, term->numRef);
-		PyDict_SetItemString(result, term->goID, value);
-		Py_DECREF(value);
-		Py_DECREF(geneList);
-		node=node->next;
-	}
-	clearTermList(list);
-	free(list);
-	free(loglookup);
-	freeMappedStrings(genes);
-	freeMappedStrings(refGenes);
-	prepareGOTerms(ontology);
-	return result;
-}
-
-PyObject* findGOTerms(PyObject* self, PyObject* args){
-	PyObject* pyGenes=NULL;
-	PyObject* callback=NULL;
-	Annotation* annotation=NULL;
-	Ontology* ontology=NULL;
-	Ontology* slimOntology=NULL;
-	int evidence=0;
-	int aspect=0;
-	char slimsOnly=0;
-	char directAnnotation=0;
-	char reportEvidences=0;
-	char** genes=NULL;
-	TermList* list;
-	TermNode* node;
-	PyObject* result=NULL;
-	if(!PyArg_ParseTuple(args, "ObbiibO!O!|OO:findTerms", &pyGenes, &slimsOnly, &directAnnotation, &aspect, &evidence, &reportEvidences,
-		&go_AnnotationType, &annotation, &go_OntologyType, &ontology,  &slimOntology, &callback))
-		return NULL;
-	
-	if(!PyList_Check(pyGenes)){
-		RAISE_TYPE_ERROR("Need a list");
-		return NULL;
-	}
-	if(callback==Py_None || !PyCallable_Check(callback))
-		callback=NULL;
-	genes=mapStrings(pyGenes);
-	prepareGOTerms(ontology);
-	list=findTerms(genes, evidence, aspect, slimsOnly, (char)!directAnnotation, annotation, ontology, slimOntology, callback, MAX(PyList_Size(pyGenes)/100,1),0);
-	node=list->head;
-	result=PyDict_New();
-	while(node){
-		PyObject* list=PyList_New(0);
-		GOTerm* term=hash_get(ontology->hash, node->id);
-		GeneEvidenceNode* ptr=term->mappedGenes.head;
-		while(ptr){
-			PyObject* val=(reportEvidences)? Py_BuildValue("(si)", ptr->geneName, ptr->evidence) : Py_BuildValue("s", ptr->geneName);
-			PyList_Append(list, val);
-			Py_DECREF(val);
-			ptr=ptr->next;
-		}
-		PyDict_SetItemString(result, term->goID, list);
-		Py_DECREF(list);
-		node=node->next;
-	}
-	clearTermList(list);
-	free(list);
-	freeMappedStrings(genes);
-	return result;
-}
-
-PyObject* findGenes(PyObject* self, PyObject* args){
-	PyObject* pyTerms=NULL;
-	PyObject* result=NULL;
-	PyObject* callback=NULL;
-	Ontology* ontology=NULL;
-	Annotation* annotation=NULL;
-	char directAnnotation=0;
-	char reportEvidence=0;
-	int evidence=0;
-	char** terms=NULL;
-	char** geneNames=NULL;
-	GOTerm* term=NULL;
-	AnnRecord* ann=NULL;
-	int numGenes=0, i=0;
-	char* lastName="No GeNe NaMe 42";
-	char** name=NULL;
-	TermList* list=NULL;
-	TermNode* tnode=NULL;
-	GeneEvidenceNode* gnode=NULL;
-	hash_table* hash=NULL;
-
-	if(!PyArg_ParseTuple(args, "OibbO!O!|O:findGenes", &pyTerms, &evidence, &reportEvidence, &directAnnotation,
-		&go_AnnotationType, &annotation, &go_OntologyType, &ontology, &callback)){
-		return NULL;
-	}
-	if(!PyList_Check(pyTerms)){
-		RAISE_TYPE_ERROR("Need a list");
-		return NULL;
-	}
-	if(callback==Py_None || !PyCallable_Check(callback))
-		callback=NULL;
-	terms=mapStrings(pyTerms);
-	prepareGOTerms(ontology);
-	ann=annotation->annotation;
-	
-	while(ann->name){
-		numGenes++;
-		ann++;
-	}
-	hash=makeHashTable(PyList_Size(pyTerms));
-	name=terms;
-	while(*name){
-		hash_add(hash, *name, NULL);
-		name++;
-	}
-	ann=annotation->annotation;
-	geneNames=malloc(sizeof(char*)*numGenes);
-	memset(geneNames, 0, sizeof(char*)*numGenes);
-	while(ann->name){
-		if(strcmp(lastName, ann->name)!=0){
-			lastName=ann->name;
-			geneNames[i++]=ann->name;
-		}
-		ann++;
-	}
-
-	list=findTerms(geneNames, evidence, 7, 0, (char)!directAnnotation, annotation, ontology, NULL, callback, numGenes/100, 0);
-
-	tnode=list->head;
-	result=PyDict_New();
-	while(tnode){
-		if((term=getGOTerm(ontology, tnode->id))==HASH_MISS || !hash_has_key(hash, tnode->id)){
-			tnode=tnode->next;
-			continue;
-		}
-		gnode=term->mappedGenes.head;
-		while(gnode){
-			if(PyMapping_HasKeyString(result, gnode->geneName)){
-				PyObject* l=PyMapping_GetItemString(result, gnode->geneName);
-				PyObject* val=(reportEvidence)? Py_BuildValue("(si)", tnode->id, gnode->evidence) : Py_BuildValue("s", tnode->id);
-				PyList_Append(l, val);
-				Py_DECREF(l);
-				Py_DECREF(val);
-			} else{
-				PyObject* l=PyList_New(0);
-				PyObject* val=(reportEvidence)? Py_BuildValue("(si)", tnode->id, gnode->evidence) : Py_BuildValue("s", tnode->id);
-				PyList_Append(l, val);
-				PyMapping_SetItemString(result, gnode->geneName, l);
-				Py_DECREF(l);
-				Py_DECREF(val);
-			}
-			gnode=gnode->next;
-		}
-		tnode=tnode->next;
-	}
-	prepareGOTerms(ontology);
-	freeMappedStrings(terms);
-	freeHashTable(hash);
-	clearTermList(list);
-	free(list);
-	free(geneNames);
-	return result;
-}
-
-void collectAllChildrenTerms(GOTerm* term, Ontology* ontology, TermList *list, hash_table* hash){
-	TermNode* tnode=NULL;
-	if(!hash_has_key(hash, term->goID)){
-		addTermNode(list, makeTermNode(term->goID));
-		hash_add(hash, term->goID, (void*)42);
-	}
-	tnode=term->children.head;
-	while(tnode){
-		term=getGOTerm(ontology, tnode->id);
-		if(term!=HASH_MISS)
-			collectAllChildrenTerms(term, ontology, list, hash);
-		tnode=tnode->next;
-	}
-}
-
-PyObject* findGenes2(PyObject* self, PyObject* args){
-	PyObject* pyTerms=NULL;
-	PyObject* result=NULL;
-	PyObject* callback=NULL;
-	Ontology* ontology=NULL;
-	Annotation* annotation=NULL;
-	GOTerm* term=NULL;
-	char directAnnotation=0;
-	char reportEvidence=0;
-	int evidence=0;
-	char** terms=NULL;
-	char** geneNames=NULL;
-	hash_table *hash=NULL;
-	TermNode *tnode=NULL;
-	GeneEvidenceList *gelist=NULL;
-	GeneEvidenceNode *genode=NULL;
-	AnnRecord *ann=NULL;
-	char* lastName="No GeNe NaMe 42";
-	char** id=NULL;
-	int numTerms=0;
-	int numGenes=0;
-	TermList *allTerms=makeTermList();
-	if(!PyArg_ParseTuple(args, "OibbO!O!|O:findGenes", &pyTerms, &evidence, &reportEvidence, &directAnnotation,
-		&go_AnnotationType, &annotation, &go_OntologyType, &ontology, &callback)){
-		return NULL;
-	}
-	if(callback==Py_None || !PyCallable_Check(callback))
-		callback=NULL;
-	terms=mapStrings(pyTerms);
-
-	id=terms;
-	hash=makeHashTable(PyList_Size(pyTerms));
-	while(*id){
-		hash_add(hash, *id, (void*)42);
-		id++;
-	}
-	if(!directAnnotation){
-		hash_table * tmphash=makeHashTable(PyList_Size(pyTerms)*20);
-		id=terms;
-		while(*id){
-			if((term=getGOTerm(ontology, *id))!=HASH_MISS)
-				collectAllChildrenTerms(term, ontology, allTerms, tmphash);
-			id++;
-		}
-		tnode=allTerms->head;
-		while(tnode){
-			numTerms++;
-			tnode=tnode->next;
-		}
-		freeMappedStrings(terms);
-		terms=malloc(sizeof(char*)*(numTerms+1));
-		tnode=allTerms->head;
-		id=terms;
-		while(tnode){
-			*id=tnode->id;
-			id++;
-			tnode=tnode->next;
-		}
-		*id=NULL;
-	}
-	gelist=makeGeneEvidenceList();
-	ann=annotation->annotation;
-	while(ann->name){
-		if(hash_has_key(hash, ann->goID) && strcmp(ann->name, lastName)){
-			addGeneEvidenceNode(gelist, makeGeneEvidenceNode(ann->name, 4095));
-			lastName=ann->name;
-		}
-		ann++;
-	}
-	genode=gelist->head;
-	while(genode){
-		numGenes++;
-		genode=genode->next;
-	}
-	geneNames=malloc(sizeof(char*)*(numGenes+1));
-	genode=gelist->head;
-	id=geneNames;
-	while(genode){
-		*id=genode->geneName;
-		id++;
-		genode=genode->next;
-	}
-	*id=NULL;
-	clearTermList(allTerms);
-	allTerms=findTerms(geneNames, 4095, 7, 0, (char)!directAnnotation, annotation, ontology, NULL, callback, numGenes/100, 0);
-	
-	tnode=allTerms->head;
-	result=PyDict_New();
-	while(tnode){
-		if((term=getGOTerm(ontology, tnode->id))==HASH_MISS || !hash_has_key(hash, tnode->id)){
-			tnode=tnode->next;
-			continue;
-		}
-		genode=term->mappedGenes.head;
-		while(genode){
-			if(PyMapping_HasKeyString(result, genode->geneName)){
-				PyObject* l=PyMapping_GetItemString(result, genode->geneName);
-				PyObject* val=(reportEvidence)? Py_BuildValue("(si)", tnode->id, genode->evidence) : Py_BuildValue("s", tnode->id);
-				PyList_Append(l, val);
-				Py_DECREF(l);
-				Py_DECREF(val);
-			} else{
-				PyObject* l=PyList_New(0);
-				PyObject* val=(reportEvidence)? Py_BuildValue("(si)", tnode->id, genode->evidence) : Py_BuildValue("s", tnode->id);
-				PyList_Append(l, val);
-				PyMapping_SetItemString(result, genode->geneName, l);
-				Py_DECREF(l);
-				Py_DECREF(val);
-			}
-			genode=genode->next;
-		}
-		tnode=tnode->next;
-	}
-	prepareGOTerms(ontology);
-	freeMappedStrings(terms);
-	free(geneNames);
-	freeHashTable(hash);
-	clearTermList(allTerms);
-	clearGeneEvidenceList(gelist);
-	free(allTerms);
-	free(gelist);
-	return result;
-}
-
-PyObject* mapToSlims(PyObject* self, PyObject* arg){
-	Ontology* ontology=NULL;
-	Ontology* slimOntology=NULL;
-	char* goId=NULL;
-	GOTerm* term=NULL;
-	TermList list;
-	TermNode* node=NULL;
-	PyObject* result=PyList_New(0);
-	if(!PyArg_ParseTuple(arg, "sO!O!:mapToSlims", &goId, &go_OntologyType, &ontology, &go_OntologyType, &slimOntology)){
-		return NULL;
-	}
-	prepareGOTerms(ontology);
-	memset(&list, 0, sizeof(TermList));
-	if((term=getGOTerm(ontology, goId))==HASH_MISS){
-		return NULL;
-	}
-	//printf("mapping slim: %s\n", goId);
-	slimMapping(term, ontology, slimOntology, &list);
-	//printf("mapping complete\n");
-	node=list.head;
-	while(node){
-		PyObject* val=NULL;
-		term=hash_get(ontology->hash, node->id);
-		if(term->visited==INDIRECT_MAPPING){
-			node=node->next;
-			continue;
-		}
-		val=Py_BuildValue("s",term->goID);
-		PyList_Append(result, val);
-		Py_DECREF(val);
-		node=node->next;
-	}
-	clearTermList(&list);
-	return result;
-}
-
-static PyMethodDef go_methods[] = {
-	{"parseAnnotation", (PyCFunction)parseAnnotation, METH_VARARGS, "Builds and returns an annotation structure. The argument is a single list containig tuples (geneName, GOId, evidence, aspect) "},
-	{"parseGOTerms", (PyCFunction)parseGOTerms, METH_VARARGS, "Builds and returns an ontology structure. The argument is a single list containing tuples (GOid, parents), where parents is a list containg parent GOid's"},
-	{"GOTermFinder", (PyCFunction)GOTermFinder, METH_VARARGS, "Maps a list of gene names to relevant terms. Arguments(list of gene names, list of refernece genes, slims only, evidence, aspect, annotation, ontology, slim ontology, callback"},
-	{"findTerms", (PyCFunction)findGOTerms, METH_VARARGS, "Maps a list of gene names to terms. Arguments(list of gene names, slims only, direct annotation, evidence, report evidence,  annotation, ontology, slim ontology"},
-	{"mapToSlims", (PyCFunction)mapToSlims, METH_VARARGS, "Maps a term to slim terms. Arguments: (term id, full ontology, slim ontology)"},
-	{"findGenes", (PyCFunction)findGenes2, METH_VARARGS, "Given a list of GO term id's finds all genes that map to this terms. Arguments: (list of GO term id's, evidence, report evidence, direct annotation only, anotation, ontology "},
-    {NULL}  /* Sentinel */
-};
-
-#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-PyMODINIT_FUNC
-init_GOLib(void) 
-{
-    PyObject* m;
-
-    go_OntologyType.tp_new = PyType_GenericNew;
-    if (PyType_Ready(&go_OntologyType) < 0){
-		printf("go type not ready");
-        return;
-	}
-
-	go_AnnotationType.tp_new = PyType_GenericNew;
-    if (PyType_Ready(&go_AnnotationType) < 0){
-		printf("annotation type not ready");
-        return;
-	}
-
-    m = Py_InitModule3("_GOLib", go_methods,
-                       "Genetic ontology browser");
-
-    Py_INCREF(&go_OntologyType);
-	Py_INCREF(&go_AnnotationType);
-    PyModule_AddObject(m, "Ontology", (PyObject *)&go_OntologyType);
-	PyModule_AddObject(m, "Annotation", (PyObject *)&go_AnnotationType);
-}
-

File gpl.txt

-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.

File post_install_script.py

-import sys
-import go
-try:
-    if sys.argv[1]=="remove":
-        sys.exit(0)
-except:
-    pass
-print "Downloading GO database"
-go.downloadGO()
-print "Downloading annotation for yeast genome"
-go.downloadAnnotation()