\n");
printf("
\n");
printf("
Alignment Summary
\n");
/* comma-format the coordinates and base counts, matching the new Table view (readable at the
* hundreds-of-millions scale of genomic coordinates, and the convention elsewhere in the browser) */
char tStartC[32], tEndC[32], matchC[32], qSizeC[32];
sprintLongWithCommas(tStartC, psl->tStart + 1);
sprintLongWithCommas(tEndC, psl->tEnd);
sprintLongWithCommas(matchC, psl->match + psl->repMatch);
sprintLongWithCommas(qSizeC, psl->qSize);
-printf("
%s aligned to %s:%s-%s, "
- "%.1f%% identity, "
- "%s of %s bases matched, strand %s.
\n",
- qName, chrom, tStartC, tEndC, idColor, ident,
- matchC, qSizeC, psl->strand);
+/* key-value strip (Query / Position / Identity / Matches / Strand), styled like hgBlat's summary
+ * strip so the two pages read as one design. */
+printf("
"
+ "
Query%s
"
+ "
"
+ "
Position%s:%s-%s
"
+ "
"
+ "
Identity"
+ "%.1f%%
"
+ "
"
+ "
Matches%s of %s
"
+ "
"
+ "
Strand%s
"
+ "
\n",
+ qName, chrom, tStartC, tEndC, idColor, ident, matchC, qSizeC, psl->strand);
if (isNotEmpty(aliasStr))
printf("
Genome sequence %s is also known as: %s.
\n", chrom, aliasStr);
/* The shared library returns the number of alignment blocks it actually shows. The DNA path merges
* blocks separated by gaps <= 8 bases, so this can be fewer than psl->blockCount; use it (not
* psl->blockCount) so the sidebar's "Block N" links match the #1..#N anchors that were emitted. */
int blockCount;
if (qType == gftRna || qType == gftDna)
blockCount = showPartialDnaAlignment(psl, oSeq, stdout, cdsS, cdsE, FALSE);
else
blockCount = showGfAlignment(psl, oSeq, stdout, qType, qStart, qEnd, qName);
printf("
\n"); /* #blatAlnContent */
/* Sidebar, emitted after the alignment so blockCount is known; CSS grid puts it back in column 1.
* The inner div is position:sticky so the links stay in view as the long alignment scrolls. */
printf("
\n");
@@ -27384,40 +27400,71 @@
* Bring up the bigPsl detail page with all the alignments. */
{
char *trackName = cartString(cart, "trackName");
char *trackDescription = cartString(cart, "trackDescription");
char *pslName, *faName, *qName;
parseSs(fileNames, &pslName, &faName, &qName);
struct tempName bigBedTn;
trashDirDateFile(&bigBedTn, "hgBlat", "bp", ".bb");
char *bigBedFile = bigBedTn.forCgi;
makeBigPsl(pslName, faName, database, bigBedFile);
char* host = getenv("HTTP_HOST");
boolean isProt = cgiOptionalString("isProt") != NULL;
-char *customTextTemplate = "track type=bigPsl indelDoubleInsert=on indelQueryInsert=on pslFile=%s visibility=pack showAll=on htmlUrl=http://%s/goldenPath/help/hgUserPsl.html %s bigDataUrl=%s name=\"%s\" description=\"%s\" colorByStrand=\"0,0,0 0,0,150\" mouseOver=\"${oChromStart}-${oChromEnd} of ${oChromSize} bp, strand ${oStrand}\"\n";
+// blatResult=on tags this as a BLAT results track so previous ones can be found (see blatOldTracks).
+char *customTextTemplate = "track type=bigPsl blatResult=on indelDoubleInsert=on indelQueryInsert=on pslFile=%s visibility=pack showAll=on htmlUrl=http://%s/goldenPath/help/hgUserPsl.html %s bigDataUrl=%s name=\"%s\" description=\"%s\" colorByStrand=\"0,0,0 0,0,150\" mouseOver=\"${oChromStart}-${oChromEnd} of ${oChromSize} bp, strand ${oStrand}\"\n";
char *extraForMismatch = "indelPolyA=on showDiffBasesAllScales=. baseColorUseSequence=lfExtra baseColorDefault=diffBases";
if (isProt)
extraForMismatch = "";
char buffer[4096];
safef(buffer, sizeof buffer, customTextTemplate, bigBedTn.forCgi, host, extraForMismatch, bigBedTn.forCgi, trackName, trackDescription);
struct customTrack *ctList = getCtList();
struct customTrack *newCts = customFactoryParse(database, buffer, FALSE, NULL, NULL);
+
+/* Optionally clear PREVIOUS BLAT result tracks (those tagged blatResult=on) so the user is not
+ * confused about which results are current. hg.conf "blatOldTracks":
+ * keep (default) - do nothing, every search's track stays as-is
+ * hide - leave earlier BLAT tracks in the session but set them to hide
+ * delete - remove earlier BLAT tracks from the session (their trash files age out)
+ * Only BLAT-tagged tracks are touched; the track just made is left alone. */
+char *oldTracks = cfgOptionDefault("blatOldTracks", "keep");
+if (differentString(oldTracks, "keep"))
+ {
+ struct customTrack *ct, *next, *keptList = NULL;
+ for (ct = ctList; ct != NULL; ct = next)
+ {
+ next = ct->next;
+ if (ct->tdb != NULL && sameOk(trackDbSetting(ct->tdb, "blatResult"), "on"))
+ {
+ if (sameString(oldTracks, "hide"))
+ {
+ cartSetString(cart, ct->tdb->track, "hide");
+ slAddHead(&keptList, ct); /* keep it in the session, just hidden */
+ }
+ /* "delete": drop it from the list so customTracksSaveCart writes it out */
+ }
+ else
+ slAddHead(&keptList, ct);
+ }
+ slReverse(&keptList);
+ ctList = keptList;
+ }
+
theCtList = customTrackAddToList(ctList, newCts, NULL, FALSE);
customTracksSaveCart(database, cart, theCtList);
/* Pin this bigPsl file in the cart so hgBlat's Table view can reopen exactly these results from a
* shared session (see doShareReopen in hgBlat.c) - unambiguously, even when the cart holds several
* BLAT custom tracks from earlier searches. */
cartSetString(cart, "blatLastBigBed", bigBedFile);
cartSetString(cart, "i", "PrintAllSequences");
hgCustom(newCts->tdb->track, NULL);
if (sameOk(cartOptionalString(cart, "autoRearr"), "1"))
{
char snakeVar[256];