e86128cfb99722359894e3997b13b58783ca68ae
markd
  Sat Jan 17 14:31:01 2026 -0800
add number of aligned bases and alignment span

diff --git src/hg/pslStats/pslStats.c src/hg/pslStats/pslStats.c
index 896c90ceb15..c2977f2419a 100644
--- src/hg/pslStats/pslStats.c
+++ src/hg/pslStats/pslStats.c
@@ -301,64 +301,65 @@
     ss->minTCover = min(ss->minTCover, ss2->minTCover);
     ss->maxTCover = max(ss->maxTCover, ss2->maxTCover);
     ss->minRepMatch = min(ss->minRepMatch, ss2->minRepMatch);
     ss->maxRepMatch = max(ss->maxRepMatch, ss2->maxRepMatch);
     }
 ss->queryCnt += ss2->queryCnt;
 ss->totalQSize += ss2->totalQSize;
 ss->totalAlign += ss2->totalAlign;
 ss->totalMatch += ss2->totalMatch;
 ss->totalRepMatch += ss2->totalRepMatch;
 ss->alnCnt += ss2->alnCnt;
 }
 
 /* header for alignment statistics */
 static char *alnStatsHdr = "qName\t" "qSize\t" "tName\t" "tStart\t" "tEnd\t"
-"ident\t" "qCover\t" "repMatch\t" "tCover\n";
+    "ident\t" "qCover\t" "repMatch\t" "tCover\t" "alnSize\t" "alnSpan\n";
 
 /* format for alignStats output */
-static char *alnStatsFmt = "%s\t%d\t%s\t%d\t%d\t%0.4f\t%0.4f\t%0.4f\t%0.4f\n";
+static char *alnStatsFmt = "%s\t%d\t%s\t%d\t%d\t%0.4f\t%0.4f\t%0.4f\t%0.4f\t%d\t%d\n";
 
 static void alignStatsOutputUnaligned(FILE *fh, struct hash* querySizesTbl)
 /* output stats on unaligned */
 {
 struct hashCookie cookie = hashFirst(querySizesTbl);
 struct hashEl *hel;
 while ((hel = hashNext(&cookie)) != NULL)
     {
     struct querySizeCnt *qs = hel->val;
     if (qs->alnCnt == 0)
-        fprintf(fh, alnStatsFmt, hel->name, qs->qSize, "", 0, 0, 0.0, 0.0, 0.0, 0.0);
+        fprintf(fh, alnStatsFmt, hel->name, qs->qSize, "", 0, 0, 0.0, 0.0, 0.0, 0.0, 0, 0);
     }
 }
 
 static void pslAlignStats(char *pslFile, char *statsFile, char *querySizeFile)
 /* collect and output per-alignment stats */
 {
 struct hash* querySizesTbl = (querySizeFile != NULL)
     ? querySizeCntLoad(querySizeFile) : NULL;
 struct lineFile *pslLf = pslFileOpen(pslFile);
 FILE *fh = mustOpen(statsFile, "w");
 struct psl* psl;
 
 if (!tsvHeader)
     fputc('#', fh);
 fputs(alnStatsHdr, fh);
 while ((psl = pslNext(pslLf)) != NULL)
     {
     fprintf(fh, alnStatsFmt, psl->qName, psl->qSize, psl->tName, psl->tStart, psl->tEnd,
-            calcIdent(psl), calcQCover(psl), calcRepMatch(psl), calcTCover(psl));
+            calcIdent(psl), calcQCover(psl), calcRepMatch(psl), calcTCover(psl),
+            calcAligned(psl), psl->tEnd - psl->tStart);
     if (querySizesTbl != NULL)
         querySizeCntGet(querySizesTbl, psl->qName, psl->qSize)->alnCnt++;
     pslFree(&psl);
     }
 lineFileClose(&pslLf);
 
 if (querySizesTbl != NULL)
     alignStatsOutputUnaligned(fh, querySizesTbl);
 
 carefulClose(&fh);
 }
 
 /* header for query statistics */
 static char *queryStatsHdr = "qName\t" "qSize\t" "alnCnt\t" "minIdent\t" "maxIdent\t" "meanIdent\t"
 "minQCover\t" "maxQCover\t" "meanQCover\t" "minRepMatch\t" "maxRepMatch\t" "meanRepMatch\t"