c2007dd0e1b2b6df27907f5d4678fa9458d0cbc9
jcasper
  Thu Sep 18 22:47:37 2025 -0700
Fix to find normalization options for hic files that don't annotate the first chromosome, refs #36313

diff --git src/hg/lib/straw/cStraw.cpp src/hg/lib/straw/cStraw.cpp
index 0ee9662df06..463a28c2eb7 100644
--- src/hg/lib/straw/cStraw.cpp
+++ src/hg/lib/straw/cStraw.cpp
@@ -68,44 +68,51 @@
         strcpy(errString, "Unable to retrieve header data from file");
         free(repFname);
         return errString;
     }
 
     // Time to get the normalization options.  As a hack, we get these by making a dummy data request,
     // having that set up a global variable with the options seen, then retrieving that.  This will
     // miss situations where different normalization options are available at different resolutions.
     // That is a thing that can happen, but I haven't tested the performace hit of running through every
     // available resolution for the possible options just yet (let alone restructuring the browser side
     // of the code to support that kind of dependency).  In the interim, this method is still better
     // than the previous strategy of hard-coding in options that sometimes aren't available (and missing
     // ones that are).
  
     vector<contactRecord> strawRecords;
-    try {
+    {
         // using chrom[1] because [0] is always "All", which doesn't seem to play well because it
         // may have a different set of resolution options
-        string chrPos = (*p)->chromNames[1] + ":1:1";
+        int chrIx = 0;
+        do
+        {
+            chrIx++;
+            try {
+                string chrPos = (*p)->chromNames[chrIx] + ":1:1";
                 // Intentionally feed straw an empty normalization option.  This will cause an error (which we trap),
                 // but it's the easiest way to make the library load and compare the available options (the library
                 // short-circuits out early if "NONE" is provided).
                 strawRecords = straw("observed", "", string(repFname),
                     chrPos, chrPos, "BP", (*p)->bpResolutions[0]);
             } catch (strawException& err) {
                 // Do nothing - we're intentionally feeding it a bad norm option just so it'll go through the list
-        // and realize it can't find it, populating a list along the way.
+                // and realize it can't find it, populating a list along the way.  This doesn't work if there's no
+                // data for that chromosome though, in which case we have to keep trying until one works (or we run out).
+            }
+        } while ((chrIx < (*p)->nChroms) && (getNormOptions().size() == 0));
     }
-
     // Now the list that getNormOptions() depends on should be populated
     (*p)->normOptions = getNormOptions();
 
     free(repFname);
     return NULL;
 }
 
 extern "C" void cStrawClose(Straw **hicFile)
 /* Free up a straw object created with cStrawOpen() */
 {
     if (*hicFile != NULL)
     {
         delete (*hicFile)->genome;
         (*hicFile)->chromNames.clear();
         (*hicFile)->chromSizes.clear();