4fb78c6bbad5852d825f348e8ec13faaa6b46f5c markd Tue Jul 18 12:37:09 2023 -0700 allow UTR as a discontinouis feature diff --git src/lib/gff3.c src/lib/gff3.c index 18e05cc..494e823 100644 --- src/lib/gff3.c +++ src/lib/gff3.c @@ -47,30 +47,31 @@ char *gff3FeatGene = "gene"; char *gff3FeatPseudogene = "pseudogene"; char *gff3FeatNCRnaGene ="ncRNA_gene"; char *gff3FeatNCRna ="ncRNA"; char *gff3FeatRRna = "rRNA"; char *gff3FeatTRna = "tRNA"; char *gff3FeatMRna = "mRNA"; char *gff3FeatLncRna = "lnc_RNA"; char *gff3FeatPseudogenicTranscript = "pseudogenic_transcript"; char *gff3FeatScRna = "scRNA"; char *gff3FeatSnRna = "snRNA"; char *gff3FeatSnoRna = "snoRNA"; char *gff3FeatUnconfirmedTranscript = "unconfirmed_transcript"; char *gff3FeatExon = "exon"; char *gff3FeatCDS = "CDS"; +char *gff3FeatUTR = "UTR"; char *gff3FeatThreePrimeUTR = "three_prime_UTR"; char *gff3FeatFivePrimeUTR = "five_prime_UTR"; char *gff3FeatStartCodon = "start_codon"; char *gff3FeatStopCodon = "stop_codon"; char *gff3FeatTranscript = "transcript"; char *gff3FeatPrimaryTranscript = "primary_transcript"; char *gff3FeatCGeneSegment = "C_gene_segment"; char *gff3FeatDGeneSegment = "D_gene_segment"; char *gff3FeatJGeneSegment = "J_gene_segment"; char *gff3FeatVGeneSegment = "V_gene_segment"; static bool gff3FileStopDueToErrors(struct gff3File *g3f) /* determine if we should stop due to the number of errors */ { return g3f->errCnt > g3f->maxErr; @@ -944,30 +945,31 @@ gff3AnnErr(g3a, FALSE, "Annotation records for discontinuous features with ID=\"%s\" must have one and only one parent", g3a->id); for (struct gff3Ann *g3a2 = g3a->nextPart; (g3a2 != NULL) && !gff3FileStopDueToErrors(g3a->file); g3a2 = g3a2->nextPart) { if (slCount(g3a2->parentIds) != 1) gff3AnnErr(g3a2, FALSE, "Annotation records for discontinuous features with ID=\"%s\" must have one and only one parent", g3a2->id); else if (!sameString(g3a->type, g3a2->type)) gff3AnnErr(g3a2, FALSE, "Annotation records for discontinuous features with ID=\"%s\" do not have the same type, found \"%s\" and \"%s\"", g3a->id, g3a->type, g3a2->type); else if (!sameString(g3a2->parentIds->name, g3a->parentIds->name)) gff3AnnErr(g3a2, FALSE, "Annotation records for discontinuous features with ID=\"%s\" must have same parent, found: \"%s\" and \"%s\"", g3a->id, g3a2->parentIds->name, g3a->parentIds->name); } // The discontinuous features abomination means we can't check for duplicate // ids in features were it makes no sense. Add non-spec restriction. if (!(sameString(g3a->type, gff3FeatCDS) || + sameString(g3a->type, gff3FeatUTR) || sameString(g3a->type, gff3FeatThreePrimeUTR) || sameString(g3a->type, gff3FeatFivePrimeUTR) || sameString(g3a->type, gff3FeatStartCodon) || sameString(g3a->type, gff3FeatStopCodon))) gff3AnnErr(g3a, FALSE, "Incorrect duplicated ID=\"%s\" or attempt to create discontinuous features for type \"%s\"", g3a->id, g3a->type); } static void discontinFeatureFillArray(struct gff3Ann *g3a, int numAnns, struct gff3Ann *featAnns[]) /* convert list to array for sorting */ { int i = 0; for (; g3a != NULL; g3a = g3a->nextPart) featAnns[i++] = g3a; }