src/hg/hgTracks/cds.c 1.90

1.90 2009/03/19 22:21:05 angie
Refactoring for performance issue raised by David: moved all baseColor work that was done at load-time to draw-time, and removed the freeing-by-default of original genePred and psl structs converted to lf. Now, when there are so many items in the window that limitVisibility kicks it down to dense mode, we don't waste time on baseColor stuff that won't be used. Also some refactoring for tidiness in cds.c: got rid of a couple unused function args.
Index: src/hg/hgTracks/cds.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/hgTracks/cds.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -b -B -U 4 -r1.89 -r1.90
--- src/hg/hgTracks/cds.c	22 Dec 2008 21:03:54 -0000	1.89
+++ src/hg/hgTracks/cds.c	19 Mar 2009 22:21:05 -0000	1.90
@@ -600,34 +600,30 @@
     lf->start = gp->txStart;
     lf->end = gp->txEnd;
     lf->tallStart = gp->cdsStart;
     lf->tallEnd = gp->cdsEnd;
-    sfList = baseColorCodonsFromGenePred(chrom, lf, gp, NULL, useExonFrames,
-				  colorStopStart);
+    sfList = baseColorCodonsFromGenePred(lf, gp, useExonFrames, colorStopStart);
     genePredFree(&gp);
     }
 return(sfList);
 }
 
 
 
-void baseColorCodonsFromPsl(char *chromName, struct linkedFeatures *lf, 
-			    struct psl *psl, int sizeMul, boolean
-                            isXeno, int maxShade,
+struct simpleFeature *baseColorCodonsFromPsl(struct linkedFeatures *lf, 
+        struct psl *psl, int sizeMul, boolean isXeno, int maxShade,
 			    enum baseColorDrawOpt drawOpt, struct track *tg)
-/*divide a pslX record into a linkedFeature, where each simple feature
- * is a 3-base codon (or a partial codon if on a boundary). Uses
- * GenBank to get the CDS start/stop of the psl record and also grabs
- * the sequence. This takes care of hidden gaps in the alignment, that
- * alter the frame. Therefore this function relies on the mRNA
- * sequence (rather than the genomic) to determine the frame.*/
+/* Given an lf and the psl from which the lf was constructed, 
+ * return a list of simpleFeature elements, one per codon (or partial 
+ * codon if the codon falls on a gap boundary.  sizeMul, isXeno and maxShade
+ * are for defaulting to one-simpleFeature-per-exon if cds is not found. */
 {
 boolean colorStopStart = (drawOpt != baseColorDrawDiffCodons);
-struct simpleFeature *sfList = splitPslByCodon(chromName, lf, psl, sizeMul,
+struct simpleFeature *sfList = splitPslByCodon(psl->tName, lf, psl, sizeMul,
                                                isXeno, maxShade, drawOpt,
 					       colorStopStart, tg);
 slReverse(&sfList);
-lf->codons = sfList;
+return sfList;
 }
 
 
 enum baseColorDrawOpt baseColorGetDrawOpt(struct track *tg)
@@ -936,14 +932,11 @@
 slReverse(&sfList);
 return sfList;
 }
 
-static struct simpleFeature *splitByCodon( char *chrom, 
-        struct linkedFeatures *lf, 
-        unsigned *starts, unsigned *ends, 
-        int blockCount, unsigned
-        cdsStart, unsigned cdsEnd,
-        unsigned *gaps, int *exonFrames, boolean colorStopStart)
+static struct simpleFeature *splitByCodon(struct linkedFeatures *lf, 
+        unsigned *starts, unsigned *ends, int blockCount, unsigned cdsStart, unsigned cdsEnd,
+        int *exonFrames, boolean colorStopStart)
 {
     int codon = 0;
     int frame = 0;
     int currentStart = 0, currentEnd = 0;
@@ -1029,9 +1022,9 @@
           getting it for each codon, but suprisingly not faster
           than getting it for each linked feature*/
 	if (thisStart < cdsStart) thisStart = cdsStart;
 	if (thisEnd > cdsEnd) thisEnd = cdsEnd;
-        codonDna = hDnaFromSeq(database, chrom, thisStart, thisEnd, dnaUpper );
+        codonDna = hDnaFromSeq(database, chromName, thisStart, thisEnd, dnaUpper );
         base = thisStart;
 
         //break each block by codon and set color code to denote codon
         while (TRUE)
@@ -1074,14 +1067,14 @@
                 }
 
                 /*accumulate partial codon in case of 
                   one base exon, or start a new one.*/
-                updatePartialCodon(partialCodonSeq, chrom, sf->start,
+                updatePartialCodon(partialCodonSeq, chromName, sf->start,
                                 sf->end, !posStrand, codonDna, base);
 
                 /*get next 'frame' nt's to see what codon will be 
                   (skipping intron sequence)*/
-                getCodonDna(theRestOfCodon, chrom, frame, starts, ends, 
+                getCodonDna(theRestOfCodon, chromName, frame, starts, ends, 
                         blockCount, cdsStart, cdsEnd, i, !posStrand, NULL);
 
                 /* This code doesn't really work right in all cases of a
                  * one-base blocks. It broke with some TransMap alignments
@@ -1119,9 +1112,9 @@
             }
             /*start of a coding block with less than 3 bases*/
             else if (currentSize < 3)
             {
-                updatePartialCodon(partialCodonSeq,chrom,sf->start,
+                updatePartialCodon(partialCodonSeq,chromName,sf->start,
                         sf->end,!posStrand,codonDna, base);
                 if (strlen(partialCodonSeq) == 3) 
                     sf->grayIx = setColorByCds(partialCodonSeq,codon,
                             &foundStart, !posStrand, colorStopStart);
@@ -1163,24 +1156,22 @@
         slReverse(&sfList);
     return(sfList);
 }
 
-struct simpleFeature *baseColorCodonsFromGenePred(char *chrom,
-	struct linkedFeatures *lf, struct genePred *gp, unsigned *gaps,
-	boolean useExonFrames, boolean colorStopStart)
+struct simpleFeature *baseColorCodonsFromGenePred(struct linkedFeatures *lf, 
+	struct genePred *gp, boolean useExonFrames, boolean colorStopStart)
 /* Given an lf and the genePred from which the lf was constructed, 
  * return a list of simpleFeature elements, one per codon (or partial 
  * codon if the codon falls on a gap boundary.  If useExonFrames is true, 
  * use the frames portion of gp (which should be from a genePredExt);
  * otherwise determine frame from genomic sequence. */
 {
     if(useExonFrames)
-        return(splitByCodon(chrom,lf,gp->exonStarts,gp->exonEnds,gp->exonCount,
-			    gp->cdsStart,gp->cdsEnd,gaps,gp->exonFrames,
-			    colorStopStart));
+        return(splitByCodon(lf, gp->exonStarts, gp->exonEnds, gp->exonCount,
+			    gp->cdsStart, gp->cdsEnd, gp->exonFrames, colorStopStart));
     else
-        return(splitByCodon(chrom,lf,gp->exonStarts,gp->exonEnds,gp->exonCount,
-                    gp->cdsStart,gp->cdsEnd,gaps,NULL, colorStopStart));
+        return(splitByCodon(lf, gp->exonStarts, gp->exonEnds, gp->exonCount,
+			    gp->cdsStart, gp->cdsEnd, NULL, colorStopStart));
 }
 
 
 static void getMrnaBases(struct psl *psl, struct dnaSeq *mrnaSeq,
@@ -1697,18 +1688,11 @@
 void baseColorDrawCleanup(struct linkedFeatures *lf, struct dnaSeq **pMrnaSeq,
 			  struct psl **pPsl)
 /* Free structures allocated just for base/cds coloring. */
 {
-if (lf->original != NULL)
-    {
-    /* Currently, lf->original is used only for coloring PSL's.  If it is 
-     * used to color some other type in the future, this will remind the 
-     * programmer to free it here. */
-    assert(pPsl != NULL);
-    assert(lf->original == *pPsl);
-    }
-if (pPsl != NULL)
-    pslFree(pPsl);
+// We could free lf->original here (either genePredFree or pslFree, depending
+// on the type -- but save time by skipping that.  Maybe we should save time
+// by skipping this free too:
 if (pMrnaSeq != NULL)
     dnaSeqFree(pMrnaSeq);
 }