11#!/usr/bin/env python
22# -*- coding: UTF-8 -*-
33
4- from collections import defaultdict
54import os
65import os .path as op
76import re
87import sys
8+
9+ from collections import defaultdict
910from urllib .parse import quote , unquote
1011
1112from ..annotation .reformat import atg_name
6768)
6869multiple_gff_attributes = ("Parent" , "Alias" , "Dbxref" , "Ontology_term" )
6970safechars = " /:?~#+!$'@()*[]|"
70- VALID_HUMAN_CHROMOSMES = set ([str (x ) for x in range (1 , 23 )] + ["X" , "Y" ])
71+ VALID_HUMAN_CHROMOSOMES = {
72+ ** {str (i ): f"chr{ i } " for i in range (1 , 23 )},
73+ "X" : "chrX" ,
74+ "Y" : "chrY" ,
75+ "MT" : "chrM" ,
76+ }
7177
7278
7379class GffLine (object ):
@@ -209,6 +215,7 @@ def update_attributes(self, skipEmpty=True, gff3=True, gtf=None, urlquote=True):
209215 attributes = []
210216 if gtf :
211217 gff3 = None
218+ urlquote = False
212219 elif gff3 is None :
213220 gff3 = self .gff3
214221
@@ -1495,7 +1502,6 @@ def chain(args):
14951502 prev_gid = curr_gid
14961503
14971504 for gkey , v in sorted (gffdict .items ()):
1498- gseqid , key = gkey
14991505 seqid = v ["seqid" ]
15001506 source = v ["source" ]
15011507 type = v ["type" ]
@@ -1672,7 +1678,12 @@ def format(args):
16721678 action = "store_true" ,
16731679 help = "Store entire GFF file in memory during first iteration" ,
16741680 )
1675-
1681+ p .add_argument (
1682+ "--human_chr" ,
1683+ default = False ,
1684+ action = "store_true" ,
1685+ help = "Only allow 1-22XY/MT, and add `chr` prefix to seqid" ,
1686+ )
16761687 p .set_outfile ()
16771688 p .set_SO_opts ()
16781689
@@ -1843,6 +1854,10 @@ def format(args):
18431854 so , _ = GODag_from_SO ()
18441855 valid_soterm = {}
18451856
1857+ gtf = ".gtf" in gffile and not opts .gff3
1858+ if gtf :
1859+ logger .info ("Output in GTF format" )
1860+
18461861 fw = must_open (outfile , "w" )
18471862 if not make_gff_store :
18481863 gff = Gff (gffile , keep_attr_order = (not opts .no_keep_attr_order ), strict = strict )
@@ -2021,6 +2036,11 @@ def format(args):
20212036 _parent = [parent , "{0}-Protein" .format (parent )]
20222037 g .set_attr ("Parent" , _parent )
20232038
2039+ if opts .human_chr :
2040+ if g .seqid not in VALID_HUMAN_CHROMOSOMES :
2041+ continue
2042+ g .seqid = VALID_HUMAN_CHROMOSOMES [g .seqid ]
2043+
20242044 pp = g .get_attr ("Parent" , first = False )
20252045 if (
20262046 opts .multiparents == "split" and (pp and len (pp ) > 1 ) and g .type != "CDS"
@@ -2034,9 +2054,8 @@ def format(args):
20342054 fix_gsac (g , notes )
20352055 print (g , file = fw )
20362056 else :
2037- if g .gff3 and not opts .gff3 :
2038- opts .gff3 = True
2039- g .update_attributes (gff3 = opts .gff3 )
2057+ gff3 = g .gff3 or opts .gff3
2058+ g .update_attributes (gff3 = gff3 , gtf = gtf )
20402059 if gsac :
20412060 fix_gsac (g , notes )
20422061 if duptype == g .type and skip [(g .seqid , g .idx , id , g .start , g .end )] == 1 :
@@ -2576,7 +2595,6 @@ def gtf(args):
25762595 gff = Gff (gffile , strict = not opts .nostrict )
25772596 transcript_info = AutoVivification ()
25782597 for g in gff :
2579- transcript_id = None
25802598 if g .type .endswith (("RNA" , "transcript" )):
25812599 if "ID" in g .attributes and "Parent" in g .attributes :
25822600 transcript_id = g .get_attr ("ID" )
@@ -3024,7 +3042,7 @@ def bed(args):
30243042 "--human_chr" ,
30253043 default = False ,
30263044 action = "store_true" ,
3027- help = "Only allow 1-22XY, and add `chr` prefix to seqid" ,
3045+ help = "Only allow 1-22XY/MT , and add `chr` prefix to seqid" ,
30283046 )
30293047 p .add_argument (
30303048 "--ensembl_cds" ,
@@ -3090,9 +3108,9 @@ def bed(args):
30903108 if span :
30913109 bl .score = bl .span
30923110 if human_chr :
3093- if bl .seqid not in VALID_HUMAN_CHROMOSMES :
3111+ if bl .seqid not in VALID_HUMAN_CHROMOSOMES :
30943112 continue
3095- bl .seqid = "chr" + bl .seqid
3113+ bl .seqid = VALID_HUMAN_CHROMOSOMES [ bl .seqid ]
30963114 if ensembl_cds :
30973115 if g .get_attr ("gene_biotype" ) != "protein_coding" :
30983116 continue
0 commit comments