faafcf1c5f1b1da28a628d6e9aa7ab9d3ee455a8 braney Fri Apr 28 12:13:01 2023 -0700 fix pack mode diff --git src/hg/hgTracks/snake.c src/hg/hgTracks/snake.c index 215f29e..76337eb 100644 --- src/hg/hgTracks/snake.c +++ src/hg/hgTracks/snake.c @@ -16,40 +16,57 @@ #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 "chromAlias.h" #include "bigPsl.h" #include "snake.h" +typedef int (*compareFunction )(const void *elem1, const void *elem2); + static int snakeFeatureCmpScore(const void *va, const void *vb) /* sort by score of the alignment. */ { const struct snakeFeature *a = *((struct snakeFeature **)va); const struct snakeFeature *b = *((struct snakeFeature **)vb); int diff = b->score - a->score; return diff; } +static int snakeFeatureCmpTStart(const void *va, const void *vb) +/* sort by start position on the target sequence */ +{ +const struct snakeFeature *a = *((struct snakeFeature **)va); +const struct snakeFeature *b = *((struct snakeFeature **)vb); +int diff = a->start - b->start; + +if (diff == 0) + { + diff = a->qStart - b->qStart; + } + +return diff; +} + static int snakeFeatureCmpQStart(const void *va, const void *vb) /* sort by start position on the query sequence */ { const struct snakeFeature *a = *((struct snakeFeature **)va); const struct snakeFeature *b = *((struct snakeFeature **)vb); int diff = a->qStart - b->qStart; if (diff == 0) { diff = a->start - b->start; } return diff; } @@ -1124,133 +1141,139 @@ else lastX = ex; lastS = s; lastE = e; lastLevel = sf->level; lastQEnd = qe; } } struct cartOptions { enum chainColorEnum chainColor; /* ChromColors, ScoreColors, NoColors */ int scoreFilter ; /* filter chains by score if > 0 */ }; -static void fixItems(struct linkedFeatures *lf) +static void fixItems(struct linkedFeatures *lf, compareFunction compare) // put all chain blocks from a single query chromosome into one // linkedFeatures structure { struct linkedFeatures *firstLf, *next; struct snakeFeature *sf, *nextSf; firstLf = lf; for (;lf; lf = next) { next = lf->next; if (!sameString(firstLf->name, lf->name) && (lf->components != NULL)) { - slSort(&firstLf->components, snakeFeatureCmpQStart); + slSort(&firstLf->components, compare); firstLf->next = lf; firstLf = lf; } for (sf = (struct snakeFeature *)lf->components; sf != NULL; sf = nextSf) { sf->qName = lf->name; sf->orientation = lf->orientation; sf->score = lf->score; nextSf = sf->next; if (firstLf != lf) { lf->components = NULL; slAddHead(&firstLf->components, sf); } } } if (firstLf != NULL) { - slSort(&firstLf->components, snakeFeatureCmpQStart); + slSort(&firstLf->components, compare); firstLf->next = 0; } } void snakeDrawLeftLabels() { } static void makeSnakeFeatures(struct linkedFeatures *lf) /* allocate an info structure for every block in the alignment. */ { for(; lf; lf = lf->next) { struct simpleFeature *sf = lf->components; struct snakeFeature *sfList = NULL; for(;sf; sf = sf->next) { struct snakeFeature *this; AllocVar(this); *(struct simpleFeature *)this = *sf; this->orientation = lf->orientation; slAddHead(&sfList, this); } lf->components = (struct simpleFeature *)sfList; } } -static void makeSingleCoverage(struct linkedFeatures *lf) +static void makeSingleCoverage(struct linkedFeatures *lf, compareFunction compare) /* Because snakes are a display of O+O of the query sequence projected onto the reference sequence, * we need to only have one copy of each piece of the query sequence. */ { for(; lf; lf = lf->next) // for each query sequence { slSort(&lf->components, snakeFeatureCmpScore); // we want to choose the higher scoring alignements Bits *qBits = bitAlloc(lf->qSize); // the bit array we use to keep track if we've seen this query sequence struct simpleFeature *sf = lf->components; struct simpleFeature *prevSf = NULL; for(; sf ; sf = sf->next) { // have we seen this query range? if (bitCountRange(qBits, sf->qStart, sf->qEnd - sf->qStart)) { // if we've seen this query sequence, then delete it if (prevSf == NULL) lf->components = sf->next; else prevSf->next = sf->next; } else { bitSetRange(qBits, sf->qStart, sf->qEnd - sf->qStart); prevSf = sf; } } - slSort(&lf->components, snakeFeatureCmpQStart); + slSort(&lf->components, compare); } } void maybeLoadSnake(struct track *track) /* check to see if we're doing snakes and if so load the correct methods. */ { boolean doSnake = cartOrTdbBoolean(cart, track->tdb, "doSnake", FALSE); if (doSnake) { + compareFunction compare; + if (track->visibility == tvFull) + compare = snakeFeatureCmpQStart; + else + // we don't care about the order on query + compare = snakeFeatureCmpTStart; + track->drawLeftLabels = snakeDrawLeftLabels; track->itemHeight = snakeItemHeight; track->totalHeight = snakeHeight; track->drawItemAt = snakeDrawAt; track->drawItems = snakeDraw; slSort(&track->items, linkedFeaturesCmpName); makeSnakeFeatures(track->items); - fixItems(track->items); - makeSingleCoverage(track->items); - track->visibility = track->limitedVis = tvFull; + fixItems(track->items, compare); + makeSingleCoverage(track->items, compare); track->canPack = FALSE; } }