715e2acf2dd9ef6106cc42ce79c724e1e52ad62e braney Thu Mar 12 09:14:28 2026 -0700 NoDots MAF alignment display for hgc mafClick, with i-row preservation and mafFrag -noDots flag hgMaf.c: add hgMafFragHelperNoDots and public wrappers (hgMafFragNoDots, hgBigMafFragNoDots, hgMafFragFromMafListNoDots) that return a list of maf blocks containing only species with actual sequence — no dot-filled rows. Blocks are broken when the species set changes; gaps between same-species blocks are filled with native sequence for the reference and dashes for others. Preserve i-row data (leftStatus/rightStatus/leftLen/rightLen) through the NoDots path so insert annotations appear in emitted blocks. hgMaf.h: declare the new NoDots public functions. mafClick.c: use NoDots path when mafClickMafFrag is enabled. Fix block numbering (aliIx was never incremented in useMafFrag path). Use full textSize for NoDots line width. Use dots instead of spaces in diff mode for both paths. Fix species label width computation to check labelHash consistently so long assembly names don't misalign sequences. Strip ref gap columns where no other species has sequence. mafFrag: add -noDots option to invoke hgMafFragNoDots from the command line, with 4 new tests (noDots, noDotsRev, noDotsOutName, noDotsLarger). refs #21477 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> diff --git src/hg/ratStuff/mafFrag/mafFrag.c src/hg/ratStuff/mafFrag/mafFrag.c index 8984b625c77..8919c34764a 100644 --- src/hg/ratStuff/mafFrag/mafFrag.c +++ src/hg/ratStuff/mafFrag/mafFrag.c @@ -1,76 +1,99 @@ /* mafFrag - Extract maf sequences for a region from database. */ /* Copyright (C) 2011 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "linefile.h" #include "hash.h" #include "options.h" #include "jksql.h" #include "maf.h" #include "hdb.h" #include "hgMaf.h" void usage() /* Explain usage and exit. */ { errAbort( "mafFrag - Extract maf sequences for a region from database\n" "usage:\n" " mafFrag database mafTrack chrom start end strand out.maf\n" "options:\n" " -outName=XXX Use XXX instead of database.chrom for the name\n" + " -noDots Output only species with sequence (no dot-filled rows)\n" ); } char *outName = NULL; +boolean noDots = FALSE; static struct optionSpec options[] = { {"outName", OPTION_STRING}, + {"noDots", OPTION_BOOLEAN}, {NULL, 0}, }; void mafFragCheck(char *database, char *track, char *chrom, char *startString, char *endString, char *strand, char *outMaf) /* mafFragCheck - Check parameters and convert to binary. - * Call mafFrag. */ + * Call mafFrag or mafFragNoDots. */ { int start, end, chromSize; -struct mafAli *maf; if (!isdigit(startString[0]) || !isdigit(endString[0])) errAbort("%s %s not numbers", startString, endString); start = atoi(startString); end = atoi(endString); if (end <= start) errAbort("end before start!"); chromSize = hChromSize(database, chrom); if (end > chromSize) errAbort("End past chromSize (%d > %d)", end, chromSize); -maf = hgMafFrag(database, track, +if (noDots) + { + struct mafAli *mafList = hgMafFragNoDots(database, track, + chrom, start, end, *strand, + outName, NULL); + if (mafList != NULL) + { + FILE *f = mustOpen(outMaf, "w"); + mafWriteStart(f, "zero"); + struct mafAli *maf; + for (maf = mafList; maf != NULL; maf = maf->next) + mafWrite(f, maf); + mafWriteEnd(f); + carefulClose(&f); + mafAliFreeList(&mafList); + } + } +else + { + struct mafAli *maf = hgMafFrag(database, track, chrom, start, end, *strand, outName, NULL); if (maf != NULL) { FILE *f = mustOpen(outMaf, "w"); mafWriteStart(f, "zero"); mafWrite(f, maf); mafWriteEnd(f); carefulClose(&f); mafAliFree(&maf); } } +} int main(int argc, char *argv[]) /* Process command line. */ { dnaUtilOpen(); optionInit(&argc, argv, options); outName = optionVal("outName", NULL); +noDots = optionExists("noDots"); if (argc != 8) usage(); mafFragCheck(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]); return 0; }