0f42d7fc723850694dd33dc22be6817a6c9446f0 jcasper Mon Aug 12 09:49:39 2024 -0700 Adding hReplaceGbdb call to cStraw to handle local hic files in GBiB, refs #27851 diff --git src/hg/lib/straw/cStraw.cpp src/hg/lib/straw/cStraw.cpp index 24f88cb..0ee9662 100644 --- src/hg/lib/straw/cStraw.cpp +++ src/hg/lib/straw/cStraw.cpp @@ -1,107 +1,115 @@ #include <cstring> #include <iostream> #include <fstream> #include <iostream> #include <sstream> #include <map> #include <set> #include <vector> #include <streambuf> #include "zlib.h" #include "straw.h" + +extern "C" { +#include "hReplaceGbdb.h" +} using namespace std; // Supplementary functions for invoking Straw in C struct Straw { string *fileName; string *genome; vector<string> chromNames; vector<int> chromSizes; int nChroms; vector<int> bpResolutions; int nBpRes; vector<int> fragResolutions; int nFragRes; vector<string> attributes; int nAttributes; set<string> normOptions; }; extern "C" char *cStrawOpen(char *fname, Straw **p) /* Create a Straw object based on the hic file at the provided path and set *p to point to it. * On error, set *p = NULL and return a non-null string describing the error. */ { *p = (Straw*) calloc (1, sizeof(struct Straw)); - (*p)->fileName = new string(fname); + char *repFname = hReplaceGbdb(fname); + (*p)->fileName = new string(repFname); (*p)->genome = new string(); try { - getHeaderFields(fname, *((*p)->genome), (*p)->chromNames, (*p)->chromSizes, (*p)->bpResolutions, + getHeaderFields(repFname, *((*p)->genome), (*p)->chromNames, (*p)->chromSizes, (*p)->bpResolutions, (*p)->fragResolutions, (*p)->attributes); } catch (strawException& err) { char *errMsg = (char*) calloc((size_t) strlen(err.what())+1, sizeof(char)); strcpy(errMsg, err.what()); free(*p); *p = NULL; + free(repFname); return errMsg; } (*p)->nChroms = (*p)->chromNames.size(); (*p)->nBpRes = (*p)->bpResolutions.size(); (*p)->nFragRes = (*p)->fragResolutions.size(); (*p)->nAttributes = (*p)->attributes.size(); // I seem to recall situations where getHeaderFields doesn't throw an error, but the data are // bad regardless (e.g. when the structure of a header changed between .hic versions). This // should help catch those. if ((*p)->nBpRes == 0) { char *errString = (char*) malloc (strlen("Unable to retrieve header data from file") + 1); 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"; // 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(fname), + 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. } // 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(); (*hicFile)->bpResolutions.clear(); (*hicFile)->fragResolutions.clear(); (*hicFile)->attributes.clear(); (*hicFile)->normOptions.clear();