#NEWLINE# def search_hierarchy( ID , hierarchy , options ) : #NEWLINE# #INDENT# 'Returns a three element tuple of lists.\n\n        * The first two lists are the gene_ids and transcript_ids that\n        * are associated with specified IDs.  The third is a list of\n        * possible transcript_ids - that is trancript_ids that are one\n        * level below where the gene id came from.\n\n        All three lists are guarenteed to be the same length, but both\n        the transcript lists could contain None values where no\n        transcript_id has been found.\n\n        Works by calling it self recursively, not efficient, but does\n        deal with the problem of cicular references: the recursion\n        limit will be quickly reached.\n\n        Can also raise ValueError if no feature of type\n        options.gene_type is found and options.missing_gene is false\n\n    ' #NEWLINE# gene_id = [ ] #NEWLINE# transcript_id = [ ] #NEWLINE# possible_transcript_id = [ ] #NEWLINE# entry = hierarchy [ ID ] #NEWLINE# if ( entry [ 'type' ] == options . gene_type ) : #NEWLINE# #INDENT# gene_id . append ( hierarchy [ ID ] [ 'gene_id' ] ) #NEWLINE# if ( not ( entry [ 'type' ] == options . transcript_type ) ) : #NEWLINE# #INDENT# transcript_id = [ None ] #NEWLINE# possible_transcript_id = [ None ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# transcript_id = [ entry [ 'transcript_id' ] ] #NEWLINE# possible_transcript_id = [ None ] #NEWLINE# #UNINDENT# return ( gene_id , transcript_id , possible_transcript_id ) #NEWLINE# #UNINDENT# for parent in entry [ 'Parent' ] : #NEWLINE# #INDENT# ( new_gene_id , new_transcript_id , new_possible_transcript_id ) = search_hierarchy ( parent , hierarchy , options ) #NEWLINE# gene_id . extend ( new_gene_id ) #NEWLINE# transcript_id . extend ( new_transcript_id ) #NEWLINE# possible_transcript_id . extend ( new_possible_transcript_id ) #NEWLINE# #UNINDENT# if options . missing_gene : #NEWLINE# #INDENT# possible_transcript_id = [ ( entry [ 'transcript_id' ] if ( x is None ) else x ) for x in possible_transcript_id ] #NEWLINE# #UNINDENT# if ( ( len ( gene_id ) == 0 ) and options . missing_gene ) : #NEWLINE# #INDENT# gene_id = [ entry [ 'gene_id' ] ] #NEWLINE# transcript_id = [ None ] #NEWLINE# possible_transcript_id = [ None ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( len ( gene_id ) == 0 ) and ( not options . missing_gene ) ) : #NEWLINE# #INDENT# raise ValueError ( ( 'Root found without finding an object of type %s' % options . gene_type ) ) #NEWLINE# #UNINDENT# #UNINDENT# if ( entry [ 'type' ] == options . transcript_type ) : #NEWLINE# #INDENT# transcript_id = [ ( entry [ 'transcript_id' ] if ( x is None ) else x ) for x in transcript_id ] #NEWLINE# #UNINDENT# assert ( ( len ( gene_id ) == len ( transcript_id ) ) and ( len ( transcript_id ) == len ( possible_transcript_id ) ) ) #NEWLINE# assert ( len ( gene_id ) > 0 ) #NEWLINE# return ( gene_id , transcript_id , possible_transcript_id )