0306db6d76e3a164039b23b9b48a0677e5df03e6
braney
  Thu Mar 9 08:25:41 2017 -0800
first cut at adding support for pslSnake's

diff --git src/hg/hgTracks/snakeTrack.c src/hg/hgTracks/snakeTrack.c
index 27cd9b3..54cad7e 100644
--- src/hg/hgTracks/snakeTrack.c
+++ src/hg/hgTracks/snakeTrack.c
@@ -14,30 +14,31 @@
 #include "chainBlock.h"
 #include "chainLink.h"
 #include "chainDb.h"
 #include "chainCart.h"
 #include "errCatch.h"
 #include "twoBit.h"
 #include "bigWarn.h"
 #include <pthread.h>
 #include "trackHub.h"
 #include "limits.h"
 #include "snakeUi.h"
 #include "bits.h"
 #include "trix.h"
 
 #include "halBlockViz.h"
+#include "bigPsl.h"
 
 // this is the number of pixels used by the target self-align bar
 #define DUP_LINE_HEIGHT	4
 
 struct snakeFeature
     {
     struct snakeFeature *next;
     int start, end;			/* Start/end in browser coordinates. */
     int qStart, qEnd;			/* query start/end */
     int level;				/* level in snake */
     int orientation;			/* strand... -1 is '-', 1 is '+' */
     boolean drawn;			/* did we draw this feature? */
     char *qSequence;			/* may have sequence, or NULL */
     char *tSequence;			/* may have sequence, or NULL */
     char *qName;			/* chrom name on other species */
@@ -992,31 +993,31 @@
 	    }
 
 	char *ourDna;
 	if (isHalSnake)
 	    ourDna = sf->qSequence;
 	else
 	    ourDna = &seq->dna[sf->qStart];
 
 	int seqLen = sf->qEnd - sf->qStart;
 	toUpperN(ourDna, seqLen);
 	if (!isHalSnake && (sf->orientation == -1))
 	    reverseComplement(ourDna,seqLen);
 
 	// get the reference sequence
 	char *refDna;
-	if (isHalSnake)
+        if (isHalSnake && differentString(tg->tdb->type, "pslSnake"))
 	    {
 	    refDna = sf->tSequence;
 	    }
 	else
 	    {
 	    struct dnaSeq *extraSeq = hDnaFromSeq(database, chromName, sf->start, sf->end, dnaUpper);
 	    refDna = extraSeq->dna;
 	    }
 	int si = s;
 	char *ptr1 = refDna;
 	char *ptr2 = ourDna;
 	for(; si < e; si++,ptr1++,ptr2++)
 	    {
 	    // if mismatch!  If reference is N ignore, if query is N, paint yellow
 	    if ( (*ptr1 != *ptr2) && !((*ptr1 == 'N') || (*ptr1 == 'n')))
@@ -1189,71 +1190,133 @@
 static char *doChromIxSearch(char *trixFile, char *searchName)
 /* search ixFile for the searchName, return name if found */
 {
 struct trix *trix = trixOpen(trixFile);
 char *trixWords[1];
 int trixWordCount = 1;
 trixWords[0] = strLower(searchName);
 char *name = NULL;  // assume NOT found
 
 struct trixSearchResult *tsList = trixSearch(trix, trixWordCount, trixWords, tsmExact);
 if (tsList)
    name = tsList->itemId;  // FOUND
 return name;
 }
 
+static struct hal_block_results_t *pslSnakeBlocks(char *fileName, struct track *track, char *chrom, unsigned start, unsigned end, unsigned int maxItems)
+/* create HAL-like blocks from a bigPsl file. */
+{
+struct hal_block_results_t *head;
+
+AllocVar(head);
+
+struct lm *lm = lmInit(0);
+//struct bigBedInterval *bb, *bbList = bigBedSelectRangeExt(track, chrom, start, end, lm, maxItems);
+struct bigBedInterval *bb, *bbList = bigBedSelectRangeExt(track, chrom, 0, hChromSize(database,chromName), lm, maxItems);
+
+struct bbiFile *bbi = fetchBbiForTrack(track);
+int seqTypeField =  0;
+if (sameString(track->tdb->type, "bigPsl"))
+    {
+    seqTypeField =  bbExtraFieldIndex(bbi, "seqType");
+    }
+bbiFileClose(&bbi);
+for (bb = bbList; bb != NULL; bb = bb->next)
+    {
+    char *seq, *cds;
+    struct psl *psl = pslFromBigPsl(chromName, bb, seqTypeField,  &seq, &cds); 
+    unsigned *targetStart = psl->tStarts;
+    unsigned *queryStart = psl->qStarts;
+    unsigned *size = psl->blockSizes;
+    int ii;
+
+    for(ii = 0; ii < psl->blockCount; ii++)
+        {
+        struct hal_block_t *block;
+        AllocVar(block);
+        slAddHead(&head->mappedBlocks, block);
+
+        block->qChrom = psl->qName;
+        block->tStart = *targetStart++;
+        block->qStart = *queryStart++;
+        block->size = *size++;
+        block->strand = psl->strand[0];
+        block->qSequence = &seq[block->qStart];
+
+        if (block->strand == '-')
+            block->qStart = psl->qSize - block->qStart;
+        }
+    }
+
+return head;
+}
+
 void halSnakeLoadItems(struct track *tg)
 // load up a snake from a HAL file.   This code is called in threads
 // so *no* use of globals please. All but full snakes are read into a single
 // linked feature.
 {
 unsigned showSnpWidth = cartOrTdbInt(cart, tg->tdb, 
     SNAKE_SHOW_SNP_WIDTH, SNAKE_DEFAULT_SHOW_SNP_WIDTH);
 
 char * chromAlias = NULL;	// create later when needed
 char * chromAliasFile = trackDbSetting(tg->tdb, "searchTrix");
 if (chromAliasFile)
    chromAlias = doChromIxSearch(chromAliasFile, chromName);
 
 char *aliasName = chromName;
 if (chromAlias)
    {
        if (differentWord(chromAlias, aliasName))
           aliasName = chromAlias;
    }
 
+boolean isPsl = sameString(tg->tdb->type, "pslSnake");
+
 // if we have a network error we want to put out a message about it
 struct errCatch *errCatch = errCatchNew();
 if (errCatchStart(errCatch))
     {
     char *fileName = trackDbSetting(tg->tdb, "bigDataUrl");
     char *otherSpecies = trackDbSetting(tg->tdb, "otherSpecies");
     char *errString;
+    int handle = -1;
+    if (!isPsl)
+        {
         int handle = halOpenLOD(fileName, &errString);
         if (handle < 0)
             warn("HAL open error: %s\n", errString);
+        }
     boolean isPackOrFull = (tg->visibility == tvFull) || 
 	(tg->visibility == tvPack);
     hal_dup_type_t dupMode =  (isPackOrFull) ? HAL_QUERY_AND_TARGET_DUPS :
 	HAL_QUERY_DUPS;
     hal_seqmode_type_t needSeq = isPackOrFull && (winBaseCount < showSnpWidth) ? HAL_LOD0_SEQUENCE : HAL_NO_SEQUENCE;
     int mapBackAdjacencies = (tg->visibility == tvFull);
     char codeVarName[1024];
     safef(codeVarName, sizeof codeVarName, "%s.coalescent", tg->tdb->track);
     char *coalescent = cartOptionalString(cart, codeVarName);
     char *otherDbName = trackHubSkipHubName(database);
-    struct hal_block_results_t *head = halGetBlocksInTargetRange(handle, otherSpecies, otherDbName, aliasName, winStart, winEnd, 0, needSeq, dupMode,mapBackAdjacencies, coalescent, &errString);
+    struct hal_block_results_t *head = NULL;
+    if (isPsl)
+        {
+        head = pslSnakeBlocks(fileName, tg, chromName, winStart, winEnd, 10000000);
+        }
+    else 
+        {
+        head = halGetBlocksInTargetRange(handle, otherSpecies, otherDbName, aliasName, winStart, winEnd, 0, needSeq, dupMode,mapBackAdjacencies, coalescent, &errString);
+        }
 
     // did we get any blocks from HAL
     if (head == NULL)
 	{
 	warn("HAL get blocks error: %s\n", errString);
 	errCatchEnd(errCatch);
 	return;
 	}
     struct hal_block_t* cur = head->mappedBlocks;
     struct linkedFeatures *lf = NULL;
     struct hash *qChromHash = newHash(5);
     struct linkedFeatures *lfList = NULL;
     char buffer[4096];
 
 #ifdef NOTNOW