0043d5ee22db1de1ec305eadb8442bd5a59fe5d7 max Mon Aug 10 08:55:00 2026 -0700 hgc: route non-BLAT alignment clicks to the modern single-page view, refs #37893 Behind a new modernAlignPage hg.conf gate (default off), ordinary alignment details -- mRNA/EST (htcCdnaAli), PSL/bigPsl, protein, cross-species and the other showSomeAlignment callers -- now render in the modern single-page alignment instead of the classic two-frame <frameset>, matching hgBlat's new results page. - Generalize showSomeAlignmentModern with a blatContext flag: TRUE keeps the hgBlat chrome (title 'BLAT Base Alignment', 'Back to results', 'Share a link'); FALSE is a plain track click, which has no BLAT results to return to or share, so the title is just 'Base Alignment' and those buttons are omitted. - alnModernStart() starts modern chrome and arms a flag when modernAlignPage is set; showSomeAlignment() then renders the modern body, else the classic frameset. htmlFramesetStart() is left untouched (it is shared with transMap, retro and pubs click pages), so only the converted callers change. - The window-restricted (showSomePartialDnaAlignment) and Lowe-Lab (showSomeAlignment2) renderers are left classic for now. - Register modernAlignPage in hgConfCatalog. diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index 1e224043630..504f1d89523 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -8354,35 +8354,51 @@ fprintf(body, "<H2>Alignment of %s and %s:%d-%d</H2>\n", psl->qName, displayChromName, partTStart+1, partTEnd); if (!cartUsualBoolean(cart, "blatNewPage", FALSE)) /* no "frame" in the new single-page view */ fprintf(body, "Click on links in the frame to the left to navigate through " "the alignment.\n"); blockCount = ffShAliPart(body, ffAli, wholePsl->qName, rna + rnaStart, rnaEnd - rnaStart, rnaStart, displayChromName, dnaSeq->dna, dnaSeq->size, wholeTStart, 8, FALSE, isRc, FALSE, TRUE, TRUE, TRUE, TRUE, cdsS, cdsE, partTStart, partTEnd); return blockCount; } +/* The modern single-page alignment (webStartGbNoBanner chrome, no <frameset>) can now stand in for + * the classic frameset on any alignment page, not just hgBlat's - gated by the modernAlignPage + * hg.conf flag. alnModernStart() starts the right page chrome and sets gAlnModern; showSomeAlignment() + * then renders the modern or classic body to match. These are forward-declared here because + * showSomeAlignment() sits above their definitions. */ +static boolean gAlnModern = FALSE; +static void showSomeAlignmentModern(struct psl *psl, bioSeq *oSeq, enum gfType qType, + int qStart, int qEnd, char *qName, int cdsS, int cdsE, boolean blatContext); +static void alnModernStart(char *classicTitle); + void showSomeAlignment(struct psl *psl, bioSeq *oSeq, enum gfType qType, int qStart, int qEnd, char *qName, int cdsS, int cdsE) -/* Display protein or DNA alignment in a frame. */ +/* Display protein or DNA alignment in a frame (or the modern single page when gAlnModern). */ { +if (gAlnModern) + { /* modern single-page view; blatContext=FALSE -> neutral chrome (no BLAT title/buttons) */ + showSomeAlignmentModern(psl, oSeq, qType, qStart, qEnd, qName, cdsS, cdsE, FALSE); + webEndGb(); + exit(0); // we drew the whole page; skip the frameset close + } int blockCount, i; struct tempName indexTn, bodyTn; FILE *index, *body; trashDirFile(&indexTn, "index", "index", ".html"); trashDirFile(&bodyTn, "body", "body", ".html"); /* Writing body of alignment. */ body = mustOpen(bodyTn.forCgi, "w"); htmStartDirDepth(body, psl->qName, 2); if (qType == gftRna || qType == gftDna) blockCount = showPartialDnaAlignment(psl, oSeq, body, cdsS, cdsE, FALSE); else blockCount = showGfAlignment(psl, oSeq, body, qType, qStart, qEnd, qName); htmEnd(body); @@ -8524,31 +8540,31 @@ if (isCustomTrack(aliTable)) { struct customTrack *ct = lookupCt(aliTable); tdb = ct->tdb; } else tdb = hashFindVal(trackHash, aliTable); if (tdb == NULL) errAbort("BUG: bigPsl alignment table '%s' not found; this maybe causes by `.' in track names", aliTable); if (!trackHubDatabase(database)) conn = hAllocConnTrack(database, tdb); char title[1024]; safef(title, sizeof title, "%s vs Genomic [%s]", acc, aliTable); -htmlFramesetStart(title); +alnModernStart(title); /* Get some environment vars. */ start = cartInt(cart, "l"); int end = cartInt(cart, "r"); char *chrom = cartString(cart, "c"); char *seq, *cdsString = NULL; struct lm *lm = lmInit(0); char *fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table); struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases); struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, chrom, start, end, 0, lm); char *bedRow[32]; char startBuf[16], endBuf[16]; for (bb = bbList; bb != NULL; bb = bb->next) { @@ -8678,31 +8694,31 @@ char **row; struct psl *psl; struct dnaSeq *rnaSeq; char *aliTable; int start; unsigned int cdsStart = 0, cdsEnd = 0; boolean hasBin; char accChopped[512] ; safef(accChopped, sizeof(accChopped), "%s",acc); chopSuffix(accChopped); aliTable = cartString(cart, "aliTable"); char *accForTitle = startsWith("ncbiRefSeq", aliTable) ? acc : accChopped; char title[1024]; safef(title, sizeof title, "%s vs Genomic [%s]", accForTitle, aliTable); -htmlFramesetStart(title); +alnModernStart(title); /* Get some environment vars. */ start = cartInt(cart, "o"); conn = hAllocConn(database); getCdsStartAndStop(conn, acc, aliTable, &cdsStart, &cdsEnd); /* Look up alignments in database */ if (!hFindSplitTable(database, seqName, aliTable, table, sizeof table, &hasBin)) errAbort("Failed to find aliTable=%s", aliTable); sqlSafef(query, sizeof query, "select * from %s where qName like '%s%%' and tName=\"%s\" and tStart=%d", table, acc, seqName, start); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) errAbort("Couldn't find alignment for %s at %d", acc, start); @@ -8942,31 +8958,31 @@ qSeq = loadGenomePart(otherDb, psl->qName, psl->qStart, psl->qEnd); safef(name, sizeof name, "%s.%s", otherOrg, psl->qName); } else if (otherTbf != NULL) { qSeq = twoBitReadSeqFragLower(otherTbf, psl->qName, psl->qStart, psl->qEnd); safef(name, sizeof name, "%s", psl->qName); } if (qSeq == NULL) { errAbort("Can't find query sequence in htcChainAli"); } char title[1024]; safef(title, sizeof title, "%s %s vs %s %s ", (otherOrg == NULL ? "" : otherOrg), psl->qName, org, psl->tName ); -htmlFramesetStart(title); +alnModernStart(title); showSomeAlignment(psl, qSeq, gftDnaX, psl->qStart, psl->qEnd, name, 0, 0); } void htcChainTransAli(char *item) /* Draw detailed alignment representation of a chain with translated protein */ { struct chain *chain; struct psl *fatPsl, *psl = NULL; char *track = cartString(cart, "o"); char *type = trackTypeInfo(track); char *typeWords[2]; char *otherDb = NULL, *org = NULL, *otherOrg = NULL; struct dnaSeq *qSeq = NULL; char name[128]; int cdsStart = cgiInt("qs"); @@ -8999,94 +9015,97 @@ pslFree(&fatPsl); if (sameWord(otherDb, "seq")) { qSeq = hExtSeq(database, psl->qName); safef(name, sizeof name, "%s", psl->qName); } else { qSeq = loadGenomePart(otherDb, psl->qName, psl->qStart, psl->qEnd); safef(name, sizeof name, "%s.%s", otherOrg, psl->qName); } char title[1024]; safef(title, sizeof title, "%s %s vs %s %s ", (otherOrg == NULL ? "" : otherOrg), psl->qName, org, psl->tName ); -htmlFramesetStart(title); +alnModernStart(title); /*showSomeAlignment(psl, qSeq, gftDnaX, psl->qStart, psl->qEnd, name, 0, 0); */ showSomeAlignment(psl, qSeq, gftDnaX, psl->qStart, psl->qEnd, name, cdsStart, cdsEnd); } static char *blatAsmLabel(char *database) /* A user-facing assembly label for the page title. For an assembly hub the internal * "hub_NNN_GCA_..." database name is not helpful, so use the assembly's friendly organism plus its * accession; for a native assembly just use the db name (e.g. "hg38"). */ { if (!trackHubDatabase(database)) return cloneString(database); char *acc = trackHubSkipHubName(database); /* drop the "hub_NNN_" prefix -> the accession */ char *org = hGenome(acc); /* GenArk table's friendly genome name for GC* accs */ if (isEmpty(org)) { org = trackHubAssemblyField(database, "organism"); /* else the hub's genomes.txt organism */ org = trackHubSkipHubName(org); /* strip the "hub_NNN_" prefix addHubName() baked in */ } if (isEmpty(org)) return cloneString(acc); char buf[256]; safef(buf, sizeof buf, "%s %s", org, acc); return cloneString(buf); } static void showSomeAlignmentModern(struct psl *psl, bioSeq *oSeq, enum gfType qType, - int qStart, int qEnd, char *qName, int cdsS, int cdsE) -/* Modern single-page version of showSomeAlignment for hgBlat's new table mode: a gold title bar with - * Back/Share buttons, a full-height "jump to" sidebar, then an "Alignment Summary" and the base-by- - * base alignment inlined below with steel-blue section headers, so the whole page scrolls (no - * <frameset>). The alignment body itself is generated by the shared library as before. The caller - * supplies the page chrome via webStartGbNoBanner()/webEndGb() - a menubar and <main> with no legacy - * section tables - so everything here is plain, table-free HTML. */ + int qStart, int qEnd, char *qName, int cdsS, int cdsE, boolean blatContext) +/* Modern single-page version of showSomeAlignment: a gold title bar, a full-height "jump to" + * sidebar, then an "Alignment summary" and the base-by-base alignment inlined below with steel-blue + * section headers, so the whole page scrolls (no <frameset>). The alignment body itself is + * generated by the shared library as before. The caller supplies the page chrome via + * webStartGbNoBanner()/webEndGb() - a menubar and <main> with no legacy section tables - so + * everything here is plain, table-free HTML. blatContext=TRUE is the hgBlat path: the title says + * "BLAT" and the bar carries "Back to results" and "Share a link"; blatContext=FALSE is a plain + * track click (mRNA/EST/PSL...), which has no BLAT results to go back to or share. */ { if (qName == NULL) qName = psl->qName; char *chrom = chromAliasGetDisplayChrom(database, cart, psl->tName); /* Alternate (chromAlias) names for the genomic sequence - e.g. its RefSeq/GenBank/Ensembl accessions * - shown after the main name in the "Only genome sequence" header. */ struct dyString *aliasDy = dyStringNew(128); struct slName *aliasList = chromAliasFindAliases(psl->tName), *al; struct hash *seenAlias = hashNew(0); hashStore(seenAlias, chrom); /* skip the name already shown, and the native name */ hashStore(seenAlias, psl->tName); boolean firstAlias = TRUE; for (al = aliasList; al != NULL; al = al->next) { if (isEmpty(al->name) || hashLookup(seenAlias, al->name)) continue; /* skip empties, the shown name, and duplicates (e.g. Ensembl and GenBank "7") */ hashStore(seenAlias, al->name); dyStringPrintf(aliasDy, "%s%s", firstAlias ? "" : ", ", al->name); firstAlias = FALSE; } hashFree(&seenAlias); char *aliasStr = dyStringCannibalize(&aliasDy); /* "NC_000007.14, CM000669.2, 7" or "" */ double ident = 100.0 - pslCalcMilliBad(psl, TRUE) * 0.1; char *idColor = (ident >= 98) ? "#1f7a34" : (ident >= 95) ? "#4d7c0f" : (ident >= 90) ? "#b45309" : "#b1301f"; -/* Offer "Share a link" only when a durable bigPsl custom track backs these results; without it there - * is nothing for a shared session to rebuild the alignment from. */ -char *shareBb = blatFindPinnedBigPsl(cart); +/* Offer "Share a link" only in the hgBlat context, and only when a durable bigPsl custom track + * backs these results; without it there is nothing for a shared session to rebuild the alignment + * from. A plain track click has no BLAT session to share. */ +char *shareBb = blatContext ? blatFindPinnedBigPsl(cart) : NULL; boolean canShare = (shareBb != NULL); freeMem(shareBb); /* Colors imported from the BLAT Redesign (slide 3): grey page, steel-blue section-header bars, navy * links with maroon hover, slate text. The <h2>/<hr> the shared alignment code emits are hidden; its * <h4> section headings become the steel-blue bars. The page chrome is webStartGbNoBanner (a menubar * and <main>, no legacy section tables), so we draw our own gold title bar in plain HTML. */ printf("<style>" "#main-menu-whole{margin-bottom:0}" /* no gap between the menubar and the title bar */ "#mainContent{background:#eef1f4}" /* grey page behind the white alignment panel */ ".blatTitleBar{background:#eaca92; color:#000; box-sizing:border-box; display:flex;" " align-items:center; justify-content:space-between; padding:8px 16px}" /* gold title band */ ".blatTitleBar .blatTtl{font-size:18px; font-weight:700}" ".blatTitleBar .blatBtns{display:flex; gap:8px; align-items:center}" ".blatBtn{padding:4px 12px; font-size:13px; border:1px solid #999; border-radius:3px;" @@ -9113,35 +9132,38 @@ " font-size:15px; font-weight:700}" /* -20px: bar spans full content width */ "#blatAlnContent h4:first-child{margin-top:0}" /* Alignment Summary flush at top */ "#blatAlnContent h4 a{color:#fff}" /* undo bootstrap.css (pulled in by webStartGbNoBanner's gbHeader) on the sequence blocks: * it would give <pre> a grey box, a border and word-break that mangles the alignment */ "#blatAlnContent pre{margin:0; padding:2px 0 12px; line-height:1.4; background:none; border:0;" " border-radius:0; color:#374a5e; white-space:pre; word-break:normal; word-wrap:normal}" /* key-value summary strip, mirroring hgBlat's .blatStrip (label over value, thin dividers) */ ".blatAlnStrip{display:flex; align-items:center; gap:24px; flex-wrap:wrap; margin:2px 0 14px}" ".blatAlnStat{display:flex; flex-direction:column; gap:1px}" ".blatAlnStat .k{font-size:12px; color:#5b6572; font-weight:700}" ".blatAlnStat .v{font-size:14px; color:#1e2833; font-weight:700}" ".blatAlnStrip .d{width:1px; height:28px; background:#d0d0d0}" "</style>\n"); -/* gold title bar, drawn directly (no framework subheadingBar, no JS): title on the left, then a - * "Share a link" button (when a durable track backs the results) and a "Back to results" button. */ +/* gold title bar, drawn directly (no framework subheadingBar, no JS): title on the left, then (in + * the hgBlat context only) a "Back to results" and, when a durable track backs the results, a + * "Share a link" button. */ printf("<div class='blatTitleBar'>"); -printf("<span class='blatTtl'>BLAT Base Alignment: %s</span>", blatAsmLabel(database)); +printf("<span class='blatTtl'>%s Base Alignment: %s</span>", + blatContext ? "BLAT" : "", blatAsmLabel(database)); printf("<span class='blatBtns'>"); +if (blatContext) printf("<a href='hgBlat?blatReopen=1&hgsid=%s' class='blatBtn'>" "\xe2\x80\xb9 Back to results</a>", cartSessionId(cart)); if (canShare) printf("<a href='#' id='blatShareBtn' class='blatBtn'>Share a link</a>"); printf("</span></div>\n"); /* one white panel laid out as two grid columns: a full-height "jump to" sidebar on the left, and on * the right an "Alignment Summary" header, the summary line, and the base-by-base alignment inlined * so the whole page scrolls */ printf("<div id='blatAlnBody'>\n"); printf("<div id='blatAlnContent'>\n"); printf("<h4>Alignment summary</h4>\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) */ @@ -9256,43 +9278,61 @@ " headers:{'Content-Type':'application/x-www-form-urlencoded'}," " body:'hgsid=%s&hgS_doSaveSessionJson=1&hgS_shareAnon=1'})\n" " .then(function(r){ return r.json(); }).then(function(data){\n" " btn.textContent = label; btn.dataset.busy = '';\n" " if (!data || !data.name) return;\n" " var link = window.location.origin + window.location.pathname +\n" " '?g=htcBlatAlign&c=%s&o=%d&i=' + encodeURIComponent('%s') +\n" // db comes from the session " '&u=l&s=' + encodeURIComponent(data.name);\n" " if (window.topLinks && topLinks.shareUrl) topLinks.shareUrl(link);\n" " }).catch(function(){ btn.textContent = label; btn.dataset.busy = ''; });\n" "});\n" "})();\n", cartSessionId(cart), psl->tName, psl->tStart, qName); } +static void alnModernStart(char *classicTitle) +/* Begin an alignment page. With the modernAlignPage hg.conf flag set, start the modern single-page + * chrome (webStartGbNoBanner) and arm gAlnModern so showSomeAlignment() renders the modern body; + * otherwise start the classic <frameset>. This is the plain track-click entry point (mRNA/EST/PSL + * details), so the modern page is drawn in its neutral, non-BLAT form. */ +{ +if (cfgOptionBooleanDefault("modernAlignPage", FALSE)) + { + gAlnModern = TRUE; + char pageTitle[256]; + safef(pageTitle, sizeof pageTitle, "Base Alignment: %s", blatAsmLabel(database)); + webStartGbNoBanner(cart, database, pageTitle); // menubar + <main>, no legacy section tables + } +else + htmlFramesetStart(classicTitle); +} + void htcUserAli(char *fileNames) /* Show alignment for accession. */ { char *pslName, *faName, *qName; struct lineFile *lf; bioSeq *oSeqList = NULL, *oSeq = NULL; struct psl *psl; int start; enum gfType tt, qt; boolean isProt; -/* In hgBlat's new table mode (blatNewPage) show a modern single-page alignment instead of the - * classic two-frame <frameset>. */ -boolean modern = cartUsualBoolean(cart, "blatNewPage", FALSE); +/* In hgBlat's new table mode (blatNewPage), or wherever the modernAlignPage flag is set, show a + * modern single-page alignment instead of the classic two-frame <frameset>. */ +boolean modern = cartUsualBoolean(cart, "blatNewPage", FALSE) + || cfgOptionBooleanDefault("modernAlignPage", FALSE); char title[1024]; safef(title, sizeof title, "User Sequence vs Genomic"); if (modern) { char pageTitle[256]; safef(pageTitle, sizeof pageTitle, "BLAT Base Alignment: %s", blatAsmLabel(database)); webStartGbNoBanner(cart, database, pageTitle); // menubar + <main>, no legacy section tables } else htmlFramesetStart(title); start = cartInt(cart, "o"); parseSs(fileNames, &pslName, &faName, &qName); if (modern && (!fileExists(pslName) || !fileExists(faName))) @@ -9310,31 +9350,31 @@ break; pslFree(&psl); } lineFileClose(&lf); if (psl == NULL) errAbort("Couldn't find alignment at %s:%d", seqName, start); oSeqList = faReadAllSeq(faName, !isProt); for (oSeq = oSeqList; oSeq != NULL; oSeq = oSeq->next) { if (sameString(oSeq->name, qName)) break; } if (oSeq == NULL) errAbort("%s is in %s but not in %s. Internal error.", qName, pslName, faName); if (modern) { - showSomeAlignmentModern(psl, oSeq, qt, 0, oSeq->size, NULL, 0, 0); + showSomeAlignmentModern(psl, oSeq, qt, 0, oSeq->size, NULL, 0, 0, TRUE); // hgBlat context webEndGb(); exit(0); // we drew the whole page; skip the framework's table-closing cartHtmlEnd } else showSomeAlignment(psl, oSeq, qt, 0, oSeq->size, NULL, 0, 0); // classic frameset; exits itself } void htcBlatAlign(char *qName) /* Durable base-by-base alignment for a shared BLAT link (g=htcBlatAlign): rebuild one alignment from * the saved session's durable bigPsl custom track (blatLastBigBed) instead of the ephemeral trash * .pslx/.fa the fresh-search htcUserAli path reads. seqName and o identify the hit; the query * sequence comes from the bigPsl record itself, so no stored trash sequence is needed. This backs * the "Share a link" button on the modern alignment page. */ { char pageTitle[256]; @@ -9347,54 +9387,54 @@ "has expired or been removed. Please run a new <a href=\"hgBlat\">BLAT search</a>.</p>\n"); webEndGb(); exit(0); } int start = cartInt(cart, "o"); char *seq = NULL; struct psl *psl = pslFromBigPslFileMatch(bbFile, seqName, start, qName, &seq, NULL); if (psl == NULL || seq == NULL) { printf("<p>This alignment was not found in the shared BLAT results.</p>\n"); webEndGb(); exit(0); } enum gfType qType = pslIsProtein(psl) ? gftProt : gftDna; struct dnaSeq *oSeq = newDnaSeq(cloneString(seq), strlen(seq), qName); -showSomeAlignmentModern(psl, oSeq, qType, 0, oSeq->size, NULL, 0, 0); +showSomeAlignmentModern(psl, oSeq, qType, 0, oSeq->size, NULL, 0, 0, TRUE); // hgBlat shared-link context webEndGb(); exit(0); // we drew the whole page; skip the framework's table-closing cartHtmlEnd } void htcProteinAli(char *readName, char *table) /* Show protein to translated dna alignment for accession. */ { struct psl *psl; int start; enum gfType qt = gftProt; struct sqlResult *sr; struct sqlConnection *conn = hAllocConn(database); struct dnaSeq *seq = NULL; char query[256], **row; char fullTable[HDB_MAX_TABLE_STRING]; boolean hasBin; char buffer[256]; int addp = 0; char *pred = NULL; char title[1024]; safef(title, sizeof title, "Protein Sequence vs Genomic"); -htmlFramesetStart(title); +alnModernStart(title); addp = cartUsualInt(cart, "addp",0); pred = cartUsualString(cart, "pred",NULL); start = cartInt(cart, "o"); if (!hFindSplitTable(database, seqName, table, fullTable, sizeof fullTable, &hasBin)) errAbort("track %s not found", table); sqlSafef(query, sizeof query, "select * from %s where qName = '%s' and tName = '%s' and tStart=%d", fullTable, readName, seqName, start); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) errAbort("Couldn't find alignment for %s at %d", readName, start); psl = pslLoad(row+hasBin); sqlFreeResult(&sr); if ((addp == 1) || (pred != NULL)) { @@ -9435,31 +9475,31 @@ void htcBlatXeno(char *readName, char *table) /* Show alignment for accession. */ { struct psl *psl; int start; struct sqlResult *sr; struct sqlConnection *conn = hAllocConn(database); struct dnaSeq *seq; char query[256], **row; char fullTable[HDB_MAX_TABLE_STRING]; boolean hasBin; char title[1024]; safef(title, sizeof title, "Sequence %s", readName); -htmlFramesetStart(title); +alnModernStart(title); start = cartInt(cart, "o"); if (!hFindSplitTable(database, seqName, table, fullTable, sizeof fullTable, &hasBin)) errAbort("track %s not found", table); sqlSafef(query, sizeof query, "select * from %s where qName = '%s' and tName = '%s' and tStart=%d", fullTable, readName, seqName, start); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) errAbort("Couldn't find alignment for %s at %d", readName, start); psl = pslLoad(row+hasBin); sqlFreeResult(&sr); hFreeConn(&conn); seq = hExtSeq(database, readName); showSomeAlignment(psl, seq, gftDnaX, 0, seq->size, NULL, 0, 0); } @@ -9785,31 +9825,31 @@ { struct psl *psl; struct dnaSeq *seq; struct sqlResult *sr; struct sqlConnection *conn = hAllocConn(database); char query[256], **row; int start; char *pslTable = cgiUsualString("pslTable", "illuminaProbesAlign"); char *seqTable = cgiUsualString("seqTable", "illuminaProbesSeq"); char *probeName = item; char *probeString; int rowOffset = hOffsetPastBin(database, seqName, pslTable); char title[1024]; safef(title, sizeof title, "Sequence %s", probeName); -htmlFramesetStart(title); +alnModernStart(title); start = cartInt(cart, "o"); /* get psl */ sqlSafef(query, sizeof(query), "select * from %s where qName = '%s' and tName = '%s' and tStart=%d", pslTable, probeName, seqName, start); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) errAbort("Couldn't find alignment for %s at %d", probeName, start); psl = pslLoad(row+rowOffset); sqlFreeResult(&sr); sqlSafef(query, sizeof(query), "select seq from %s where id = '%s'", seqTable, probeName); probeString = sqlNeedQuickString(conn, query); seq = newDnaSeq(probeString, strlen(probeString), probeName); hFreeConn(&conn); showSomeAlignment(psl, seq, gftDna, 0, seq->size, probeName, 0, 0); pslFree(&psl); @@ -16300,31 +16340,31 @@ qChrom = psl->qName; if ((ptr = strchr(qChrom, '.')) != NULL) qChrom = ptr+1; /* Make sure that otherOrg's chrom size matches psl's qSize */ if (hChromSize(database, qChrom) != psl->qSize) errAbort("Alignment's query size for %s is %d, but the size of %s in database %s is %d. Incorrect database in trackDb.type?", qChrom, psl->qSize, qChrom, otherDb, hChromSize(otherDb, qChrom)); psl = pslTrimToTargetRange(psl, winStart, winEnd); qSeq = loadGenomePart(otherDb, qChrom, psl->qStart, psl->qEnd); snprintf(name, sizeof(name), "%s.%s", otherOrg, qChrom); char title[1024]; safef(title, sizeof title, "%s %dk", name, psl->qStart/1000); -htmlFramesetStart(title); +alnModernStart(title); showSomeAlignment(psl, qSeq, gftDnaX, psl->qStart, psl->qEnd, name, 0, 0); } void doAlignCompGeno(struct trackDb *tdb, char *itemName, char *otherGenome) /* Handle click on blat or blastz track in a generic fashion */ /* otherGenome is the text to display for genome name on details page */ { char query[256]; struct sqlConnection *conn = hAllocConn(database); struct sqlResult *sr = NULL; char **row; int start = cartInt(cart, "o"); int end = cartInt(cart, "t"); char *chrom = cartString(cart, "c"); struct psl *pslList = NULL, *psl;