298302978224472f8e84720e6c11272684346e6b
braney
  Wed Apr 22 12:24:25 2020 -0700
add some code to recognize ribosomal slips in codon display mode.  Only
works on the + stand right now for wuhCor1

diff --git src/hg/hgTracks/cds.c src/hg/hgTracks/cds.c
index 249b341..965a08f 100644
--- src/hg/hgTracks/cds.c
+++ src/hg/hgTracks/cds.c
@@ -480,30 +480,40 @@
    sprintf(codon,"%c",'V');   
    }
 else if(grayIx == - 'L')
    {
    color = cdsColor[CDS_ALT_START];
    sprintf(codon,"%c",'L');   
    }
 #endif
 else if (grayIx <= 26)
     {
     color = ixColor;
     sprintf(codon,"%c",grayIx + 'A' - 1);
     if (codon[0] == GRAYIX_STOP_CODON_ALPHA)
 	codon[0] = '*';
     }
+else if (grayIx > 78)  // ribosomal slip begin
+    {
+    color = cdsColor[CDS_RIBO_SLIP1];
+    sprintf(codon,"%c",grayIx - 78 + 'A' - 1);
+    }
+else if (grayIx > 52)  // ribosomal slip end
+    {
+    color = cdsColor[CDS_RIBO_SLIP2];
+    sprintf(codon,"%c",grayIx - 52 + 'A' - 1);
+    }
 else if (grayIx > 26)
     {
     color = lighterShade(hvg, ixColor,1.5);
     sprintf(codon,"%c",grayIx - 26 + 'A' - 1);
     if (codon[0] == GRAYIX_STOP_CODON_ALPHA)
 	codon[0] = '*';
     }
 else
     {
     errAbort("colorAndCodonFromGrayIx: invalid grayIx %d", grayIx);
     color = cdsColor[CDS_ERROR];
     sprintf(codon,"X");
     }
 return color;
 }
@@ -1023,30 +1033,36 @@
 					      CDS_QUERY_INSERTION_AT_END_G,
 					      CDS_QUERY_INSERTION_AT_END_B);
 cdsColor[CDS_POLY_A] = hvGfxFindColorIx(hvg,CDS_POLY_A_R,
 					    CDS_POLY_A_G, 
 					    CDS_POLY_A_B);
 
 cdsColor[CDS_ALT_START] = hvGfxFindColorIx(hvg,CDS_ALT_START_R,
 					    CDS_ALT_START_G, 
 					    CDS_ALT_START_B);
 cdsColor[CDS_SYN_PROT] = hvGfxFindColorIx(hvg,CDS_SYN_PROT_R,
 					    CDS_SYN_PROT_G, 
 					    CDS_SYN_PROT_B);
 cdsColor[CDS_SYN_BLEND] = hvGfxFindColorIx(hvg,CDS_SYN_BLEND_R,
 					    CDS_SYN_BLEND_G, 
 					    CDS_SYN_BLEND_B);
+cdsColor[CDS_RIBO_SLIP1] = hvGfxFindColorIx(hvg,CDS_RIBO_SLIP1_R,
+					    CDS_RIBO_SLIP1_G, 
+					    CDS_RIBO_SLIP1_B);
+cdsColor[CDS_RIBO_SLIP2] = hvGfxFindColorIx(hvg,CDS_RIBO_SLIP2_R,
+					    CDS_RIBO_SLIP2_G, 
+					    CDS_RIBO_SLIP2_B);
 }
 
 
 
 static void updatePartialCodon(char *retStr, int exonStart, int exonEnd, boolean posStrand)
 /* Add bases to the appropriate end of retStr, from exonStart until we have 3 bases or
  * run into exonEnd*/
 {
 char tmpStr[4];
 char tmpDna[4];
 char *codonDna = getCachedDna(exonStart, exonEnd);
 int baseCount = min(3-strlen(retStr), abs(exonEnd-exonStart));
 memcpy(tmpDna, codonDna, baseCount);
 tmpDna[baseCount] = '\0';
 if (posStrand)
@@ -1200,59 +1216,71 @@
 		}
 	    }
         else
             if(posStrand)
                 currentStart = exonStart;
             else 
                 currentEnd = exonEnd;
 
 	// If UTR + coding, trim to coding portion:
 	if (exonStart < cdsStart) exonStart = cdsStart;
 	if (exonEnd > cdsEnd) exonEnd = cdsEnd;
 
         // break each exon into codons and assign alternating shades.
         while (TRUE)
 	    {
+            int lastEnd = currentEnd;
             int codonInc = frame;
             if (frame == 0)  
 		{
                 altColor = altColor ? FALSE : TRUE;
 		codonInc = 3;
 		}
 
             if(posStrand)
                 currentEnd = currentStart + codonInc;
             else
                 currentStart = currentEnd - codonInc; 
 
             //we've gone off the end of the current exon
             if ((posStrand && currentEnd > exonEnd) ||
 		(!posStrand && currentStart < exonStart ))
 		{
                 if (posStrand)
 		    {
                     frame = currentEnd - exonEnd;
                     currentEnd = exonEnd;
 		    }
                 else
 		    {
                     frame = exonStart - currentStart;
                     currentStart = exonStart;
 		    }
                 if(frame == 3) 
 		    {
+                    // end of one block and the next block starts less than three bases away
                     frame = 0;
+                    if (posStrand && ((iInc*(i + iInc))<(iInc*iN) && (currentEnd + 3 > starts[i+1])))
+                        {
+                        int letter = sfList->grayIx;
+                        if (sfList->grayIx > 52)
+                            letter -= 52;
+                        else if (sfList->grayIx > 26)
+                            letter -= 52;
+
+                        sfList->grayIx = 78 + letter;
+                        }
                     break;
 		    }
 		/* accumulate partial codon in case of one base exon, or start a new one. */
 		updatePartialCodon(partialCodonSeq, currentStart, currentEnd, posStrand);
 		if (currentStart < winEnd && currentEnd > winStart)
 		    {
 		    // get next 'frame' nt's to see what codon will be (skipping intron sequence)
 		    char theRestOfCodon[4];
 		    getNextCodonDna(theRestOfCodon, frame, gp, i, posStrand);
 		    /* This code doesn't really work right in all cases of a
 		     * one-base blocks. It broke with some TransMap alignments
 		     * with indels around the one base.  This code is fragile, so
 		     * just work around it by truncating the sequence.
 		     */
 		    char tempCodonSeq[8];
@@ -1282,30 +1310,34 @@
             /*inside a coding block (with 3 bases)*/
             if (currentSize == 3)
 		{
 		AllocVar(sf);
 		sf->start = currentStart;
 		sf->end = currentEnd;
 		if ((posStrand && currentEnd <= cdsEnd) ||
 		    (!posStrand && currentStart >= cdsStart))
 		    {
 		    char currentCodon[4];
 		    char *thisDna = getCachedDna(currentStart, currentEnd);
 		    memcpy(currentCodon, thisDna, 3);
 		    currentCodon[3] = '\0';
 		    sf->grayIx = codonToGrayIx(currentCodon, altColor, &foundStart, 
 					       !posStrand, colorStopStart);
+
+                    // is this block less than 3 bases away from the previous block (ribo slip)
+                    if (posStrand && (lastEnd + 3 > currentEnd))
+                        sf->grayIx = - 'A' + 1 + 52 + baseColorLookupCodon(currentCodon);
 		    }
 		else
 		    sf->grayIx = GRAYIX_CDS_ERROR;
 		}
             /*start of a coding block with less than 3 bases*/
             else if (currentSize < 3)
 		{
                 updatePartialCodon(partialCodonSeq, currentStart, currentEnd, posStrand);
 		AllocVar(sf);
 		sf->start = currentStart;
 		sf->end = currentEnd;
                 if (strlen(partialCodonSeq) == 3) 
                     sf->grayIx = codonToGrayIx(partialCodonSeq, altColor,
                             &foundStart, !posStrand, colorStopStart);
                 else