1c208beb06fed20869c546a09a0ca2b8999b4bee
chmalee
  Wed Apr 17 16:46:31 2019 -0700
Taking bigDataUrl check out of hubCheck and into the trackHub lib so hgHubConnect can use it, refs #18870, #13428

diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c
index 1d0bf5f..fe807dd 100644
--- src/hg/lib/trackHub.c
+++ src/hg/lib/trackHub.c
@@ -37,30 +37,35 @@
 #include "chromInfo.h"
 #include "grp.h"
 #include "twoBit.h"
 #include "dbDb.h"
 #include "net.h"
 #include "bbiFile.h"
 #include "bPlusTree.h"
 #include "hgFind.h"
 #include "hubConnect.h"
 #include "trix.h"
 #include "vcf.h"
 #include "htmshell.h"
 #include "bigBedFind.h"
 #include "customComposite.h"
 #include "interactUi.h"
+#include "bedTabix.h"
+
+#ifdef USE_HAL
+#include "halBlockViz.h"
+#endif
 
 static struct hash *hubCladeHash;  // mapping of clade name to hub pointer
 static struct hash *hubAssemblyHash; // mapping of assembly name to genome struct
 static struct hash *hubOrgHash;   // mapping from organism name to hub pointer
 static struct trackHub *globalAssemblyHubList; // list of trackHubs in the user's cart
 static struct hash *trackHubHash;
 
 char *trackHubRelativeUrl(char *hubUrl, char *path)
 /* Return full path (in URL form if it's a remote hub) given
  * path possibly relative to hubUrl. Do a freeMem of result
  * when done. */
 {
 /* If path itself is a URL then just return a copy of it. */
 if (hasProtocol(path))
     return cloneString(path);
@@ -1154,15 +1159,92 @@
     hostPort = trackHubAssemblyField(database, "blat");
     }
 
 if (hostPort == NULL)
     return FALSE;
    
 hostPort = cloneString(hostPort);
 
 *pHost = nextWord(&hostPort);
 if (hostPort == NULL)
     return FALSE;
 *pPort = hostPort;
 
 return TRUE;
 }
+
+void hubCheckBigDataUrl(struct trackHub *hub, struct trackHubGenome *genome, struct trackDb *tdb)
+/* Check remote file exists and is of correct type. Wrap this in error catcher */
+{
+char *relativeUrl = trackDbSetting(tdb, "bigDataUrl");
+if (relativeUrl != NULL)
+    {
+    char *type = trackDbRequiredSetting(tdb, "type");
+    char *bigDataUrl = trackHubRelativeUrl(genome->trackDbFile, relativeUrl);
+
+    char *bigDataIndex = NULL;
+    char *relIdxUrl = trackDbSetting(tdb, "bigDataIndex");
+    if (relIdxUrl != NULL)
+        bigDataIndex = trackHubRelativeUrl(genome->trackDbFile, relIdxUrl);
+
+    verbose(2, "checking %s.%s type %s at %s\n", genome->name, tdb->track, type, bigDataUrl);
+    if (startsWithWord("bigWig", type))
+        {
+        /* Just open and close to verify file exists and is correct type. */
+        struct bbiFile *bbi = bigWigFileOpen(bigDataUrl);
+        bbiFileClose(&bbi);
+        }
+    else if (startsWithWord("bigNarrowPeak", type) || startsWithWord("bigBed", type) ||
+                startsWithWord("bigGenePred", type)  || startsWithWord("bigPsl", type)||
+                startsWithWord("bigChain", type)|| startsWithWord("bigMaf", type) ||
+                startsWithWord("bigBarChart", type) || startsWithWord("bigInteract", type))
+        {
+        /* Just open and close to verify file exists and is correct type. */
+        struct bbiFile *bbi = bigBedFileOpen(bigDataUrl);
+        char *typeString = cloneString(type);
+        nextWord(&typeString);
+        if (startsWithWord("bigBed", type) && (typeString != NULL))
+            {
+            unsigned numFields = sqlUnsigned(nextWord(&typeString));
+            if (numFields > bbi->fieldCount)
+                errAbort("fewer fields in bigBed (%d) than in type statement (%d) for track %s with bigDataUrl %s", bbi->fieldCount, numFields, trackHubSkipHubName(tdb->track), bigDataUrl);
+            }
+        bbiFileClose(&bbi);
+        }
+    else if (startsWithWord("vcfTabix", type))
+        {
+        /* Just open and close to verify file exists and is correct type. */
+        struct vcfFile *vcf = vcfTabixFileAndIndexMayOpen(bigDataUrl, bigDataIndex, NULL, 0, 0, 1, 1);
+        if (vcf == NULL)
+            // Warnings already indicated whether the tabix file is missing etc.
+            errAbort("Couldn't open %s and/or its tabix index (.tbi) file.  "
+                     "See http://genome.ucsc.edu/goldenPath/help/vcf.html",
+                     bigDataUrl);
+        vcfFileFree(&vcf);
+        }
+    else if (startsWithWord("bam", type))
+        {
+        bamFileAndIndexMustExist(bigDataUrl, bigDataIndex);
+        }
+    else if (startsWithWord("longTabix", type))
+        {
+        struct bedTabixFile *btf = bedTabixFileMayOpen(bigDataUrl, NULL, 0, 0);
+        if (btf == NULL)
+            errAbort("Couldn't open %s and/or its tabix index (.tbi) file.", bigDataUrl);
+        bedTabixFileClose(&btf);
+        }
+#ifdef USE_HAL
+    else if (startsWithWord("halSnake", type))
+        {
+        char *errString;
+        int handle = halOpenLOD(bigDataUrl, &errString);
+        if (handle < 0)
+            errAbort("HAL open error: %s", errString);
+        if (halClose(handle, &errString) < 0)
+            errAbort("HAL close error: %s", errString);
+        }
+#endif
+    else
+        errAbort("unrecognized type %s in genome %s track %s", type, genome->name, tdb->track);
+    freez(&bigDataUrl);
+    }
+}