edfe4db20446f5c266f2ba1155fc694d30fdf00c braney Fri Feb 3 09:10:41 2023 -0800 ongoing work on snake display for chains diff --git src/hg/hgTracks/chainSnakeTrack.c src/hg/hgTracks/chainSnakeTrack.c index cff200e..acd36e2 100644 --- src/hg/hgTracks/chainSnakeTrack.c +++ src/hg/hgTracks/chainSnakeTrack.c @@ -46,30 +46,38 @@ char *qName; /* chrom name on other species */ unsigned pixX1, pixX2; /* pixel coordinates within window */ }; #ifdef NOTNOW 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; return diff; } #endif +static int snakeFeatureCmpQSequence(const void *va, const void *vb) +/* sort by sequence name of the query sequence */ +{ +const struct snakeFeature *a = *((struct snakeFeature **)va); +const struct snakeFeature *b = *((struct snakeFeature **)vb); + +return strcmp(a->qSequence, b->qSequence); +} 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; } @@ -1069,52 +1077,56 @@ } s = sf->start; e = sf->end; sx = round((double)((int)s-winStart)*scale) + xOff; ex = round((double)((int)e-winStart)*scale) + xOff; color = (sf->orientation == -1) ? MG_RED : MG_BLUE; if (lastX != -1) { char buffer[1024]; #define MG_ORANGE 0xff0082E6 int color = MG_GRAY; if (lastQEnd != qs) { long long queryInsertSize = llabs(lastQEnd - qs); + if (queryInsertSize > 100) + color = MG_ORANGE; +#ifdef NOTNOW long long targetInsertSize; if (sf->orientation == 1) targetInsertSize = s - lastE; else targetInsertSize = lastS - e; int blue = 0; int red = 0; int green = 0; if (queryInsertSize > targetInsertSize) { double frac = ((double) queryInsertSize - targetInsertSize) / targetInsertSize; if (frac > 1.0) frac = 1.0; red = 255 - 255 * frac; blue = 255 * frac; } else { double frac = ((double) targetInsertSize - queryInsertSize) / targetInsertSize; if (frac > 1.0) frac = 1.0; red = 255 - 255 * frac; green = 255 * frac; } color = hvGfxFindColorIx(hvg, red, green, blue); +#endif } double queryGapNFrac = 0.0; double queryGapMaskedFrac = 0.0; #ifdef NOTNOW if ((qs > lastQEnd) && qs - lastQEnd < 1000000) { // sketchy char *fileName = trackDbSetting(tg->tdb, "bigDataUrl"); char *otherSpecies = trackDbSetting(tg->tdb, "otherSpecies"); int handle = halOpenLOD(fileName, NULL); char *queryGapDna = halGetDna(handle, otherSpecies, sf->qName, lastQEnd, qs, NULL); long long numNs = 0; long long numMasked = 0; char *i = queryGapDna; while (*i != '\0') { if (*i == 'N' || *i == 'n') { @@ -1532,37 +1544,31 @@ struct sqlResult *sr = NULL; struct linkedFeatures *list = NULL, *lf; //int qs; char optionChr[128]; /* Option - chromosome filter */ char *optionChrStr; char extraWhere[128] ; struct cartOptions *chainCart; struct chain *pChain; chainCart = (struct cartOptions *) tg->extraUiData; safef( optionChr, sizeof(optionChr), "%s.chromFilter", tg->table); optionChrStr = cartUsualString(cart, optionChr, "All"); int ourStart = winStart; int ourEnd = winEnd; -//optionChrStr = "chr15"; - -// we're grabbing everything now.. we really should be -// doing this as a preprocessing stage, rather than at run-time -//ourStart = 0; -//ourEnd = 500000000; ourStart = winStart; ourEnd = winEnd; if (startsWith("chr",optionChrStr)) { sqlSafef(extraWhere, sizeof(extraWhere), "qName = \"%s\" and score > %d",optionChrStr, chainCart->scoreFilter); sr = hRangeQuery(conn, track, chromName, ourStart, ourEnd, extraWhere, &rowOffset); } else { if (chainCart->scoreFilter > 0) { sqlSafef(extraWhere, sizeof(extraWhere), @@ -1621,34 +1627,41 @@ slSort(&list, linkedFeaturesCmpStart); else if ((tg->visibility == tvDense) && (chainCart->chainColor == chainColorScoreColors)) slSort(&list, chainCmpScore); else slReverse(&list); tg->items = list; /* Clean up. */ sqlFreeResult(&sr); hFreeConn(&conn); /* now load the items */ loadLinks(tg, ourStart, ourEnd, tg->visibility); + +/* we need to sort by query chrom so they'll bunch up together */ +slSort(&tg->items, snakeFeatureCmpQSequence); lf=tg->items; fixItems(lf); } /* chainLoadItems() */ +static void snakeDrawLeftLabels() +{ +} + void snakeMethods(struct track *tg, struct trackDb *tdb, int wordCount, char *words[]) /* Fill in custom parts of alignment chains. */ { struct cartOptions *chainCart; AllocVar(chainCart); boolean normScoreAvailable = chainDbNormScoreAvailable(tdb); /* what does the cart say about coloring option */ chainCart->chainColor = chainFetchColorOption(cart, tdb, FALSE); chainCart->scoreFilter = cartUsualIntClosestToHome(cart, tdb, @@ -1686,20 +1699,21 @@ { setNoColor(tg); chainCart->chainColor = chainColorNoColors; } else chainCart->chainColor = chainColorChromColors; } tg->canPack = FALSE; tg->loadItems = snakeLoadItems; tg->drawItems = snakeDraw; tg->mapItemName = lfMapNameFromExtra; tg->subType = lfSubChain; tg->extraUiData = (void *) chainCart; tg->totalHeight = snakeHeight; +tg->drawLeftLabels = snakeDrawLeftLabels; tg->drawItemAt = snakeDrawAt; tg->itemHeight = snakeItemHeight; }