[med-svn] [Git][med-team/gffread][upstream] New upstream version 0.11.4
Andreas Tille
gitlab at salsa.debian.org
Thu Aug 8 10:59:33 BST 2019
Andreas Tille pushed to branch upstream at Debian Med / gffread
Commits:
5cd8d924 by Andreas Tille at 2019-08-08T09:54:00Z
New upstream version 0.11.4
- - - - -
4 changed files:
- Makefile
- gff_utils.cpp
- gff_utils.h
- gffread.cpp
Changes:
=====================================
Makefile
=====================================
@@ -10,7 +10,8 @@ LINKER := $(if $(LINKER),$(LINKER),g++)
LDFLAGS := $(if $(LDFLAGS),$(LDFLAGS),-g)
BASEFLAGS := -Wall -Wextra ${SEARCHDIRS} -D_FILE_OFFSET_BITS=64 \
--D_LARGEFILE_SOURCE -D_REENTRANT -fno-strict-aliasing -fno-exceptions -fno-rtti
+-D_LARGEFILE_SOURCE -D_REENTRANT -fno-strict-aliasing \
+ -std=c++0x -fno-exceptions -fno-rtti
GCCV8 := $(shell expr `g++ -dumpversion | cut -f1 -d.` \>= 8)
ifeq "$(GCCV8)" "1"
@@ -21,14 +22,14 @@ CXXFLAGS := $(if $(CXXFLAGS),$(BASEFLAGS) $(CXXFLAGS),$(BASEFLAGS))
ifneq (,$(filter %release %static, $(MAKECMDGOALS)))
# -- release build
- CXXFLAGS := -g -O3 -DNDEBUG -std=c++0x $(CXXFLAGS)
+ CXXFLAGS := -g -O3 -DNDEBUG $(CXXFLAGS)
else
ifneq (,$(filter %profile %gprof %prof, $(MAKECMDGOALS)))
- CXXFLAGS += -pg -O0 -DNDEBUG -std=c++0x
+ CXXFLAGS += -pg -O0 -DNDEBUG
LDFLAGS += -pg
else
#CXXFLAGS += -g -O0 -DNDEBUG
- CXXFLAGS += -g -O0 -DDEBUG -D_DEBUG -DGDEBUG -std=c++0x
+ CXXFLAGS += -g -O0 -DDEBUG -D_DEBUG -DGDEBUG
endif
ifneq (,$(filter %memcheck %memdebug, $(MAKECMDGOALS)))
#use sanitizer in gcc 4.9+
=====================================
gff_utils.cpp
=====================================
@@ -3,7 +3,7 @@
bool verbose=false; //same with GffReader::showWarnings and GffLoader::beVserbose
//bool debugState=false;
-
+/*
void printTabFormat(FILE* f, GffObj* t) {
static char dbuf[1024];
fprintf(f, "%s\t%s\t%c\t%d\t%d\t%d\t", t->getID(), t->getGSeqName(), t->strand, t->start, t->end, t->exons.Count());
@@ -26,6 +26,7 @@ void printTabFormat(FILE* f, GffObj* t) {
}
fprintf(f, "\n");
}
+*/
void printFasta(FILE* f, GStr& defline, char* seq, int seqlen, bool useStar) {
if (seq==NULL) return;
@@ -388,11 +389,11 @@ bool GffLoader::placeGf(GffObj* t, GenomicSeqData* gdata) {
//}
//GMessage("DBG>>Placing transcript %s(%d-%d, %d exons)\n", t->getID(), t->start, t->end, t->exons.Count());
- if (t->parent==NULL && t->isTranscript()) {
+ if (t->parent==NULL && t->isTranscript() && trAdoption) {
int gidx=gdata->gfs.Count()-1;
while (gidx>=0 && gdata->gfs[gidx]->end>=t->start) {
GffObj& g = *(gdata->gfs[gidx]);
- //find a container gene object for this transcript
+ //try to find a container gene object for this transcript
//if (g.isGene() && t->strand==g.strand && exonOverlap2Gene(t, g)) {
if (g.isGene() && (t->strand=='.' || t->strand==g.strand) && g.exons.Count()==0
&& t->start>=g.start && t->end<=g.end) {
@@ -403,7 +404,7 @@ bool GffLoader::placeGf(GffObj* t, GenomicSeqData* gdata) {
tdata=new GTData(t); //additional transcript data
gdata->tdata.Add(tdata);
}
- if (t->parent==NULL) t->parent=&g;
+ t->parent=&g;
//disable printing of gene if transcriptsOnly and --keep-genes wasn't given
if (transcriptsOnly && !keepGenes) {
T_NO_PRINT(g.udata); //tag it as non-printable
=====================================
gff_utils.h
=====================================
@@ -565,6 +565,7 @@ class GffLoader {
bool BEDinput:1;
bool TLFinput:1;
bool keepGenes:1;
+ bool trAdoption:1; //orphan transcript adoption by the container gene
bool keepGff3Comments:1;
bool sortRefsAlpha:1;
bool doCluster:1;
@@ -628,7 +629,7 @@ class GffLoader {
void printFasta(FILE* f, GStr& defline, char* seq, int seqlen=-1, bool useStar=false);
-void printTabFormat(FILE* f, GffObj* t);
+//void printTabFormat(FILE* f, GffObj* t);
//"position" a given coordinate x within a list of transcripts sorted by their start (lowest)
//coordinate, using quick-search; the returned int is the list index of the closest *higher*
=====================================
gffread.cpp
=====================================
@@ -4,16 +4,19 @@
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
-#define VERSION "0.11.2"
+#define VERSION "0.11.4"
#define USAGE "gffread v" VERSION ". Usage:\n\
gffread <input_gff> [-g <genomic_seqs_fasta> | <dir>][-s <seq_info.fsize>] \n\
- [-o <outfile.gff>] [-t <tname>] [-r [[<strand>]<chr>:]<start>..<end> [-R]]\n\
+ [-o <outfile>] [-t <trackname>] [-r [[<strand>]<chr>:]<start>..<end> [-R]]\n\
[-CTVNJMKQAFPGUBHZWTOLE] [-w <exons.fa>] [-x <cds.fa>] [-y <tr_cds.fa>]\n\
- [-i <maxintron>] [--sort-by <refseq_list.txt>] \n\
+ [-i <maxintron>] [--bed] [--table <attrlist>] [--sort-by <refseq_list.txt>]\n\
\n\
- Filter and convert GFF3/GTF2 records, extract corresponding sequences etc.\n\
- By default (i.e. without -O) only process transcripts, ignore other features.\n\
+ Filter, convert or cluster GFF/GTF/BED records, extract the sequence of\n\
+ transcripts (exon or CDS) and more.\n\
+ By default (i.e. without -O) only transcripts are processed, discarding any\n\
+ other non-transcript features. Default output is a simplified GFF3 with only\n\
+ the basic attributes.\n\
\n\
<input_gff> is a GFF file, use '-' for stdin\n\
\n\
@@ -39,7 +42,7 @@ Sorting: (by default, chromosomes are kept in the order they were found)\n\
--sort-by : sort the reference sequences by the order in which their\n\
names are given in the <refseq.lst> file\n\
Misc options: \n\
- -F attempt to preserve all GFF attributes preservation\n\
+ -F preserve all GFF attributes (for non-exon features)\n\
--keep-exon-attrs : for -F option, do not attempt to reduce redundant\n\
exon/CDS attributes\n\
-G do not keep exon attributes, move them to the transcript feature\n\
@@ -90,6 +93,8 @@ Output options:\n\
\"exon\" features\n\
--gene2exon: for single-line genes not parenting any transcripts, add an\n\
exon feature spanning the entire gene (treat it as a transcript)\n\
+ --t-adopt: try to find a parent gene overlapping/containing a transcript\n\
+ that does not have any explicit gene Parent\n\
-D decode url encoded characters within attributes\n\
-Z merge very close exons into a single exon (when intron size<4)\n\
-g full path to a multi-fasta file with the genomic sequences\n\
@@ -109,16 +114,19 @@ Output options:\n\
WARNING: all GFF records on reference sequences whose original IDs\n\
are not found in the 1st column of this table will be discarded!\n\
-t use <trackname> in the 2nd column of each GFF/GTF output line\n\
- -o print the GFF records to <outfile.gff> (those that passed any\n\
- given filters). Use -o- to enable printing of to stdout\n\
- -T for -o, output will be GTF instead of GFF3\n\
- --bed for -o, output BED format instead of GFF3\n\
- --tlf for -o, output \"transcript line format\" which is like GFF\n\
+ -o write the records into <outfile> instead of stdout\n\
+ -T main output will be GTF instead of GFF3\n\
+ --bed output records in BED format instead of default GFF3\n\
+ --tlf output \"transcript line format\" which is like GFF\n\
but exons, CDS features and related data are stored as GFF \n\
attributes in the transcript feature line, like this:\n\
exoncount=N;exons=<exons>;CDSphase=<N>;CDS=<CDScoords> \n\
- <exons> is a comma-delimited list of exon_start-exon_end coordinates;\n\
- <CDScoords> is CDS_start:CDS_end coordinates or a list like <exons>;\n\
+ <exons> is a comma-delimited list of exon_start-exon_end coordinates;\n\
+ <CDScoords> is CDS_start:CDS_end coordinates or a list like <exons>\n\
+ --table output a simple tab delimited format instead of GFF, with columns\n\
+ having the values of GFF attributes given in <attrlist>; special\n\
+ pseudo-attributes (prefixed by @) are recognized:\n\
+ @chr, @start, @end, @strand, @numexons, @exons, @cds, @covlen, @cdslen\n\
-v,-E expose (warn about) duplicate transcript IDs and other potential\n\
problems with the given GFF/GTF records\n\
"
@@ -149,6 +157,30 @@ class RefTran {
}
};
+enum ETableFieldType {
+ ctfGFF_Attr=0, // attribute name as is
+ ctfGFF_ID, //ID or @id
+ ctfGFF_Parent, //Parent or @parent
+ ctfGFF_chr, //@chr
+ ctfGFF_feature, //@feature
+ ctfGFF_start, //@start
+ ctfGFF_end, //@end
+ ctfGFF_strand, //@strand
+ ctfGFF_numexons, //@numexons
+ ctfGFF_exons, //@exons
+ ctfGFF_cds, //@cds
+ ctfGFF_covlen, //@covlen
+ ctfGFF_cdslen//@cdslen
+};
+
+class CTableField {
+ public:
+ ETableFieldType type;
+ GStr name; //only for type ctfGFF_Attr
+ CTableField(ETableFieldType atype=ctfGFF_Attr):type(atype) { }
+ CTableField(GStr& attrname):type(ctfGFF_Attr),name(attrname) { }
+};
+
FILE* ffasta=NULL;
FILE* f_in=NULL;
FILE* f_out=NULL;
@@ -173,7 +205,7 @@ bool covInfo=false; // --cov-info : only report genome coverage
//bool sortAlpha=false;
GStr sortBy; //file name with chromosomes listed in the desired order
//bool keepRefOrder=false; //sort within chromosomes, but follow the input chromosome order -- default!
-
+GStr tableFormat; //list of "attributes" to print in tab delimited format
//bool NoPseudo=false;
bool spliceCheck=false; //only known splice-sites
bool decodeChars=false; //decode url-encoded chars in attrs (-D)
@@ -193,6 +225,7 @@ bool fmtGFF3=true; //default output: GFF3
bool fmtGTF=false;
bool fmtBED=false;
bool fmtTLF=false;
+bool fmtTable=false;
bool addDescr=false;
//bool protmap=false;
bool multiExon=false;
@@ -221,6 +254,9 @@ GHash<GeneInfo> gene_ids;
bool debugMode=false;
//bool verbose=false;
+
+GVec<CTableField> tableCols; //table output format fields
+
void loadSeqInfo(FILE* f, GHash<SeqInfo> &si) {
GLineReader fr(f);
while (!fr.isEof()) {
@@ -251,6 +287,50 @@ void loadSeqInfo(FILE* f, GHash<SeqInfo> &si) {
} //while lines
}
+void setTableFormat(GStr& s) {
+ if (s.is_empty()) return;
+ GHash<ETableFieldType> specialFields;
+ specialFields.Add("chr", new ETableFieldType(ctfGFF_chr));
+ specialFields.Add("id", new ETableFieldType(ctfGFF_ID));
+ specialFields.Add("parent", new ETableFieldType(ctfGFF_Parent));
+ specialFields.Add("feature", new ETableFieldType(ctfGFF_feature));
+ specialFields.Add("start", new ETableFieldType(ctfGFF_start));
+ specialFields.Add("end", new ETableFieldType(ctfGFF_end));
+ specialFields.Add("strand", new ETableFieldType(ctfGFF_strand));
+ specialFields.Add("numexons", new ETableFieldType(ctfGFF_numexons));
+ specialFields.Add("exons", new ETableFieldType(ctfGFF_exons));
+ specialFields.Add("cds", new ETableFieldType(ctfGFF_cds));
+ specialFields.Add("covlen", new ETableFieldType(ctfGFF_covlen));
+ specialFields.Add("cdslen", new ETableFieldType(ctfGFF_cdslen));
+
+ s.startTokenize(" ,;.:", tkCharSet);
+ GStr w;
+ while (s.nextToken(w)) {
+ if (w[0]=='@') {
+ w=w.substr(1);
+ ETableFieldType* v=specialFields.Find(w.chars());
+ if (v!=NULL) {
+ CTableField tcol(*v);
+ tableCols.Add(tcol);
+ }
+ else GMessage("Warning: table field '@%s' not recognized!\n",w.chars());
+ continue;
+ }
+ if (w=="ID") {
+ CTableField tcol(ctfGFF_ID);
+ tableCols.Add(tcol);
+ continue;
+ }
+ if (w=="Parent") {
+ CTableField tcol(ctfGFF_Parent);
+ tableCols.Add(tcol);
+ continue;
+ }
+ CTableField col(w);
+ tableCols.Add(col);
+ }
+}
+
void loadRefTable(FILE* f, GHash<RefTran>& rt) {
GLineReader fr(f);
char* line=NULL;
@@ -347,16 +427,6 @@ bool process_transcript(GFastaDb& gfasta, GffObj& gffrec) {
//returns true if the transcript passed the filter
char* gname=gffrec.getGeneName();
if (gname==NULL) gname=gffrec.getGeneID();
- /*
- if (f_out) { //remove transcript_name, convert it to Name for GFF3 output -- should we?
- const char* tname=NULL;
- if ((tname=gffrec.getAttr("transcript_name"))!=NULL &&
- gffrec.getAttr("Name")==NULL) {
- gffrec.addAttr("Name", tname);
- gffrec.removeAttr("transcript_name");
- }
- }
- */
if (ensembl_convert && startsWith(gffrec.getID(), "ENS")) {
const char* biotype=gffrec.getAttr("gene_biotype");
if (biotype) {
@@ -676,15 +746,15 @@ bool process_transcript(GFastaDb& gfasta, GffObj& gffrec) {
}
void openfw(FILE* &f, GArgs& args, char opt) {
- GStr s=args.getOpt(opt);
- if (!s.is_empty()) {
- if (s=='-')
- f=stdout;
- else {
- f=fopen(s,"w");
- if (f==NULL) GError("Error creating file: %s\n", s.chars());
- }
- }
+ GStr s=args.getOpt(opt);
+ if (!s.is_empty()) {
+ if (s=='-')
+ f=stdout;
+ else {
+ f=fopen(s,"w");
+ if (f==NULL) GError("Error creating file: %s\n", s.chars());
+ }
+ }
}
#define FWCLOSE(fh) if (fh!=NULL && fh!=stdout) fclose(fh)
@@ -840,11 +910,104 @@ void printGffObj(FILE* f, GffObj* gfo, GStr& locname, GffPrintMode exonPrinting,
}
+void printGxfTab(FILE* f, GffObj& g) {
+ //using attribute list in tableCols
+ char* av=NULL;
+ for(int i=0;i<tableCols.Count();i++) {
+ if (i>0) fprintf(f,"\t");
+ switch(tableCols[i].type) {
+ case ctfGFF_Attr:
+ av=g.getAttr(tableCols[i].name.chars());
+ if (av!=NULL) fprintf(f,"%s",av);
+ else fprintf(f, ".");
+ break;
+ case ctfGFF_chr:
+ fprintf(f,"%s",g.getGSeqName());
+ break;
+ case ctfGFF_ID:
+ fprintf(f,"%s",g.getID());
+ break;
+ case ctfGFF_Parent:
+ if (g.parent!=NULL) fprintf(f,"%s",g.parent->getID());
+ else fprintf(f, ".");
+ break;
+ case ctfGFF_feature:
+ fprintf(f,"%s",g.getFeatureName());
+ break;
+ case ctfGFF_start:
+ fprintf(f,"%d",g.start);
+ break;
+ case ctfGFF_end:
+ fprintf(f,"%d",g.end);
+ break;
+ case ctfGFF_strand:
+ fprintf(f,"%c",g.strand);
+ break;
+ case ctfGFF_numexons:
+ fprintf(f,"%d",g.exons.Count());
+ break;
+ case ctfGFF_exons:
+ if (g.exons.Count()>0) {
+ for (int x=0;x<g.exons.Count();x++) {
+ if (x>0) fprintf(f,",");
+ fprintf(f,"%d-%d",g.exons[x]->start, g.exons[x]->end);
+ }
+ } else fprintf(f,".");
+ break;
+ case ctfGFF_cds:
+ if (g.hasCDS()) {
+ GVec<GffExon> cds;
+ g.getCDSegs(cds);
+ for (int x=0;x<cds.Count();x++) {
+ if (x>0) fprintf(f,",");
+ fprintf(f,"%d-%d",cds[x].start, cds[x].end);
+ }
+ }
+ else fprintf(f,".");
+ break;
+ case ctfGFF_covlen:
+ fprintf(f, "%d", g.covlen);
+ break;
+ case ctfGFF_cdslen:
+ if (g.hasCDS()) {
+ GVec<GffExon> cds;
+ g.getCDSegs(cds);
+ int clen=0;
+ for (int x=0;x<cds.Count();x++)
+ clen+=cds[x].end-cds[x].start+1;
+ fprintf(f, "%d", clen);
+ }
+ else fprintf(f, "0");
+ break;
+ }
+ }
+ fprintf(f,"\n");
+}
+
+void printAsTable(FILE* f, GffObj* gfo, int* out_counter=NULL) {
+ GffObj& t=*gfo;
+ GTData* tdata=(GTData*)(t.uptr);
+ if (tdata->replaced_by!=NULL || !T_PRINTABLE(t.udata)) return;
+ T_NO_PRINT(t.udata);
+ if (out_counter!=NULL) (*out_counter)++;
+ //print the parent first, if any and if not printed already
+ if (t.parent!=NULL && T_PRINTABLE(t.parent->udata)) {
+ GTData* pdata=(GTData*)(t.parent->uptr);
+ if (pdata && pdata->geneinfo!=NULL)
+ pdata->geneinfo->finalize();
+ //t.parent->addAttr("locus", locname.chars());
+ //(*out_counter)++; ?
+ printGxfTab(f, *t.parent);
+ T_NO_PRINT(t.parent->udata);
+ }
+ printGxfTab(f, *gfo);
+}
+
int main(int argc, char* argv[]) {
GArgs args(argc, argv,
"version;debug;merge;adj-stop;bed;in-bed;tlf;in-tlf;cluster-only;nc;cov-info;help;"
- "sort-alpha;keep-genes;keep-comments;keep-exon-attrs;force-exons;gene2exon;"
- "ignore-locus;no-pseudo;sort-by=hvOUNHPWCVJMKQYTDARSZFGLEBm:g:i:r:s:l:t:o:w:x:y:d:");
+ "sort-alpha;keep-genes;keep-comments;keep-exon-attrs;force-exons;t-adopt;gene2exon;"
+ "ignore-locus;no-pseudo;table=sort-by=hvOUNHPWCVJMKQYTDARSZFGLEBm:g:i:r:s:l:t:o:w:x:y:d:");
args.printError(USAGE, true);
if (args.getOpt('h') || args.getOpt("help")) {
GMessage("%s",USAGE);
@@ -887,6 +1050,7 @@ int main(int argc, char* argv[]) {
StarStop=(args.getOpt('S')!=NULL);
gffloader.keepGenes=(args.getOpt("keep-genes")!=NULL);
+ gffloader.trAdoption=(args.getOpt("t-adopt")!=NULL);
gffloader.keepGff3Comments=(args.getOpt("keep-comments")!=NULL);
gffloader.sortRefsAlpha=(args.getOpt("sort-alpha")!=NULL);
if (args.getOpt("sort-by")!=NULL) {
@@ -896,7 +1060,6 @@ int main(int argc, char* argv[]) {
}
if (!sortBy.is_empty())
gffloader.loadRefNames(sortBy);
-
gffloader.gene2exon=(args.getOpt("gene2exon")!=NULL);
gffloader.matchAllIntrons=(args.getOpt('K')==NULL);
gffloader.fuzzSpan=(args.getOpt('Q')!=NULL);
@@ -956,6 +1119,14 @@ int main(int argc, char* argv[]) {
//sortByLoc=true;
}
+ tableFormat=args.getOpt("table");
+ if (!tableFormat.is_empty()) {
+ setTableFormat(tableFormat);
+ fmtTable=true;
+ fmtGFF3=false;
+ gffloader.fullAttributes=true;
+ }
+
gffloader.mergeCloseExons=(args.getOpt('Z')!=NULL);
multiExon=(args.getOpt('U')!=NULL);
writeExonSegs=(args.getOpt('W')!=NULL);
@@ -1040,6 +1211,9 @@ int main(int argc, char* argv[]) {
openfw(f_w, args, 'w');
openfw(f_x, args, 'x');
openfw(f_y, args, 'y');
+
+ if (f_out==NULL && f_w==NULL && f_x==NULL && f_y==NULL)
+ f_out=stdout;
//if (f_y!=NULL || f_x!=NULL) wCDSonly=true;
//useBadCDS=useBadCDS || (fgtfok==NULL && fgtfbad==NULL && f_y==NULL && f_x==NULL);
@@ -1180,7 +1354,8 @@ int main(int argc, char* argv[]) {
firstLocusPrint=false;
}
}
- printGffObj(f_out, loc.rnas[rnas_i], locname, exonPrinting, out_counter);
+ if (fmtTable) printAsTable(f_out, loc.rnas[rnas_i], &out_counter);
+ else printGffObj(f_out, loc.rnas[rnas_i], locname, exonPrinting, out_counter);
++rnas_i;
}
}
@@ -1197,18 +1372,21 @@ int main(int argc, char* argv[]) {
int gfs_i=0;
for (int m=0;m<gdata->rnas.Count();m++) {
GffObj& t=*(gdata->rnas[m]);
- if (f_out && fmtGFF3) {
+ if (f_out && (fmtGFF3 || fmtTable)) {
//print other non-transcript (gene?) feature that might be there before t
- while (gfs_i<gdata->gfs.Count() && gdata->gfs[gfs_i]->start<=t.start) {
- GffObj& gfst=*(gdata->gfs[gfs_i]);
- if T_PRINTABLE(gfst.udata) { //never printed
- T_NO_PRINT(gfst.udata);
- if (firstGff3Print) { printGff3Header(f_out, args);firstGff3Print=false; }
- if (firstGSeqHeader) { printGSeqHeader(f_out, gdata); firstGSeqHeader=false; }
- gfst.printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
- }
- ++gfs_i;
- }
+ while (gfs_i<gdata->gfs.Count() && gdata->gfs[gfs_i]->start<=t.start) {
+ GffObj& gfst=*(gdata->gfs[gfs_i]);
+ if T_PRINTABLE(gfst.udata) { //never printed
+ T_NO_PRINT(gfst.udata);
+ if (fmtGFF3) {
+ if (firstGff3Print) { printGff3Header(f_out, args);firstGff3Print=false; }
+ if (firstGSeqHeader) { printGSeqHeader(f_out, gdata); firstGSeqHeader=false; }
+ gfst.printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
+ }
+ else printGxfTab(f_out, gfst);
+ }
+ ++gfs_i;
+ }
}
GTData* tdata=(GTData*)(t.uptr);
if (tdata->replaced_by!=NULL) continue;
@@ -1216,36 +1394,46 @@ int main(int argc, char* argv[]) {
numvalid++;
if (f_out && T_PRINTABLE(t.udata) ) {
T_NO_PRINT(t.udata);
- if (fmtGFF3 || t.isTranscript()) {
+ if (fmtGFF3 || fmtTable || t.isTranscript()) {
if (tdata->geneinfo)
tdata->geneinfo->finalize();
out_counter++;
- // if (fmtGTF) t.printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
- if (firstGff3Print) { printGff3Header(f_out, args);firstGff3Print=false; }
- if (firstGSeqHeader) { printGSeqHeader(f_out, gdata); firstGSeqHeader=false; }
- //for GFF3, print the parent first, if any
- if (fmtGFF3 && t.parent!=NULL && T_PRINTABLE(t.parent->udata)) {
+ if (fmtGFF3) {
+ if (firstGff3Print) { printGff3Header(f_out, args);firstGff3Print=false; }
+ if (firstGSeqHeader) { printGSeqHeader(f_out, gdata); firstGSeqHeader=false; }
+ }
+ //for GFF3 && table output, print the parent first, if any
+ if ((fmtGFF3 || fmtTable) && t.parent!=NULL && T_PRINTABLE(t.parent->udata)) {
GTData* pdata=(GTData*)(t.parent->uptr);
if (pdata && pdata->geneinfo!=NULL)
pdata->geneinfo->finalize();
- t.parent->printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
+ if (fmtTable)
+ printGxfTab(f_out, *(t.parent));
+ else
+ t.parent->printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
T_NO_PRINT(t.parent->udata);
}
- t.printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
+ if (fmtTable)
+ printGxfTab(f_out, t);
+ else
+ t.printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
}
}//GFF/GTF output requested
} //valid transcript
} //for each rna
//print the rest of the isolated pseudo/gene/region features not printed yet
- if (f_out && fmtGFF3) {
+ if (f_out && (fmtGFF3 || fmtTable)) {
while (gfs_i<gdata->gfs.Count()) {
GffObj& gfst=*(gdata->gfs[gfs_i]);
if T_PRINTABLE(gfst.udata) { //never printed
T_NO_PRINT(gfst.udata);
- if (firstGff3Print) { printGff3Header(f_out, args); firstGff3Print=false; }
- if (firstGSeqHeader) { printGSeqHeader(f_out, gdata); firstGSeqHeader=false; }
- gfst.printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
- }
+ if (fmtGFF3) {
+ if (firstGff3Print) { printGff3Header(f_out, args); firstGff3Print=false; }
+ if (firstGSeqHeader) { printGSeqHeader(f_out, gdata); firstGSeqHeader=false; }
+ gfst.printGxf(f_out, exonPrinting, tracklabel, NULL, decodeChars);
+ } else
+ printGxfTab(f_out, gfst);
+ }
++gfs_i;
}
}
View it on GitLab: https://salsa.debian.org/med-team/gffread/commit/5cd8d92443d463faca74bee7844219240412bc77
--
View it on GitLab: https://salsa.debian.org/med-team/gffread/commit/5cd8d92443d463faca74bee7844219240412bc77
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20190808/6d27705a/attachment-0001.html>
More information about the debian-med-commit
mailing list