2c43bbe76a2350dfd358bbb5047237243dcb984e
markd
  Tue Nov 8 23:09:32 2022 -0800
added a test case and improved debug and clarified code.  However it was pointless, because there was not accutally a bug, just a confused user

diff --git src/hg/utils/overlapSelect/selectTable.c src/hg/utils/overlapSelect/selectTable.c
index d477e1c..e7fd20c 100644
--- src/hg/utils/overlapSelect/selectTable.c
+++ src/hg/utils/overlapSelect/selectTable.c
@@ -28,50 +28,50 @@
 selectMapEnsure();
 return chromAnnMapFirst(selectMap);
 }
 
 void selectTableFree()
 /* free selectTable structures. */
 {
 chromAnnMapFree(&selectMap);
 }
 
 static void selectDumpChromAnn(struct chromAnn *ca, char *label)
 /* print a chromAnn if select by verbose level */
 {
 if (verboseLevel() >= 2)
     {
-    verbose(2, "%s: %s: %s %c %d-%d\n", label, ca->name, ca->chrom,
-            ((ca->strand == 0) ? '?' : ca->strand), ca->start, ca->end);
+    verbose(2, "%s: %s: %s:%d-%d, %c\n", label, ca->name, ca->chrom, ca->start, ca->end,
+            ((ca->strand == 0) ? '?' : ca->strand));
     if (verboseLevel() >= 3)
         {
         struct chromAnnBlk *cab;
         for (cab = ca->blocks; cab != NULL; cab = cab->next)
             verbose(3, "    blk: %d-%d\n", cab->start, cab->end);
         }
     }
 }
 
 void selectTableAddRecords(struct chromAnnReader *car)
 /* add records to the select table */
 {
 selectMapEnsure();
 
 struct chromAnn* ca;
 while ((ca = car->caRead(car)) != NULL)
     {
-    selectDumpChromAnn(ca, "selectAddChromAnn");
+    selectDumpChromAnn(ca, "select");
     chromAnnMapAdd(selectMap, ca);
     }
 }
 
 static boolean isSelfMatch(unsigned opts, struct chromAnn *inCa, struct chromAnn* selCa)
 /* check if this is a self record */
 {
 struct chromAnnBlk *inCaBlk, *selCaBlk;
 
 /* already know we are on same chrom and strand (if check strand) */
 if ((inCa->start != selCa->start) || (inCa->end != selCa->end))
     return FALSE;
 if (((inCa->name != NULL) && (selCa->name != NULL))
     && !sameString(inCa->name, selCa->name))
     return FALSE;
@@ -185,46 +185,51 @@
     {
     // bi-directional ceiling
     if (selectFracSimilarity(inCa, selCa, overBases) >= criteria->similarityCeil)
         notOverlapped = TRUE;
     }
 return overlapped && !notOverlapped;
 }
 
 static void addOverlapRecs(struct chromAnnRef **overlappingRecs, struct chromAnnRef *newRecs)
 /* add overlapping records that are not dups */
 {
 struct chromAnnRef *orl;
 for (orl = newRecs; orl != NULL; orl = orl->next)
     chromAnnRefAdd(overlappingRecs, orl->ref);
 }
+
+static void selectOverlappingEntryVerbose(struct chromAnn *inCa, struct chromAnn* selCa, char *result)
+/* verbose tracing for results of guts of overlap check */
+{
+verbose(2, "overlapping: %s: %s:%d-%d, %c  %s\n", selCa->name, selCa->chrom, selCa->start, selCa->end,
+        ((selCa->strand == '\0') ? '?' : selCa->strand), result);
+}
+
 static boolean selectOverlappingEntry(unsigned opts, struct chromAnn *inCa,
                                       struct chromAnn* selCa, struct overlapCriteria *criteria)
 /* select based on a single select chromAnn */
 {
 boolean overlapped = FALSE;
-verbose(2, "\toverlapping: enter %s: %d-%d, %c\n", selCa->name, selCa->start, selCa->end,
-        ((selCa->strand == '\0') ? '?' : selCa->strand));
 if (!passCriteria(opts, inCa, selCa))
     {
-    verbose(2, "\toverlapping: leave %s: fail criteria\n", selCa->name);
+    selectOverlappingEntryVerbose(inCa, selCa, "no (strand or name match criteria)");
     }
 else
     {
     overlapped = isOverlapped(opts, inCa, selCa, criteria);
-    verbose(2, "\toverlapping: leave %s: %s\n", selCa->name,
-            (overlapped ? "yes" : "no"));
+    selectOverlappingEntryVerbose(inCa, selCa, (overlapped ? "yes" : "no"));
     }
 return overlapped;
 }
 
 static boolean selectWithOverlapping(unsigned opts, struct chromAnn *inCa,
                                      struct chromAnnRef* overlapping,
                                      struct overlapCriteria *criteria,
                                      struct chromAnnRef **overlappingRecs)
 /* given a list of overlapping elements, see if inCa is selected, optionally returning
  * the list of selected records */
 {
 boolean anyHits = FALSE;
 struct chromAnnRef *curOverRecs = NULL;  /* don't add til; the end */
 struct chromAnnRef *selCa;
 
@@ -246,31 +251,32 @@
     {
     if (anyHits)
         addOverlapRecs(overlappingRecs, curOverRecs);
     slFreeList(&curOverRecs);
     }
 return anyHits;
 }
 
 boolean selectIsOverlapped(unsigned opts, struct chromAnn *inCa,
                            struct overlapCriteria *criteria,
                            struct chromAnnRef **overlappingRecs)
 /* Determine if a range is overlapped.  If overlappingRecs is not null, a list
  * of the of selected records is returned.  Free with slFreelList. */
 {
 selectMapEnsure();
-selectDumpChromAnn(inCa, "selectIsOverlapped");
+verbose(2, "selectIsOverlapped: enter %s\n", inCa->name);
+selectDumpChromAnn(inCa, "input");
 boolean hit = FALSE;
 struct chromAnnRef *overlapping = chromAnnMapFindOverlap(selectMap, inCa);
 if (overlapping != NULL)
     {
     hit = selectWithOverlapping(opts, inCa, overlapping, criteria, overlappingRecs);
     slFreeList(&overlapping);
     }
 verbose(2, "selectIsOverlapped: leave %s %s\n", inCa->name, (hit ? "yes" : "no"));
 return hit;
 }
 
 static void addToAggregateMap(Bits *overMap, int mapOff, struct chromAnn *ca1,
                               struct chromAnn *ca2)
 /* set bits based on overlap between two chromAnn */
 {