e46073f856770bdfef4f7637eea8f9f9297aa139
chmalee
  Tue Nov 19 15:57:08 2019 -0800
Initial commit of new track type vcfPhased trio. A line with ticks, one
per haplotype per sample in the VCF, as specified by trackDb variables.

diff --git src/hg/lib/customFactory.c src/hg/lib/customFactory.c
index 062e1aa..9c7e8ee 100644
--- src/hg/lib/customFactory.c
+++ src/hg/lib/customFactory.c
@@ -24,30 +24,31 @@
 #include "hgConfig.h"
 #include "hdb.h"
 #include "hui.h"
 #include "customTrack.h"
 #include "customPp.h"
 #include "customFactory.h"
 #include "trashDir.h"
 #include "jsHelper.h"
 #include "encode/encodePeak.h"
 #include "udc.h"
 #include "bbiFile.h"
 #include "bigWig.h"
 #include "bigBed.h"
 #include "hgBam.h"
 #include "vcf.h"
+#include "vcfUi.h"
 #include "makeItemsItem.h"
 #include "bedDetail.h"
 #include "pgSnp.h"
 #include "regexHelper.h"
 #include "chromInfo.h"
 #include "grp.h"
 #include "trackHub.h"
 #include "bedTabix.h"
 #include "barChartBed.h"
 #include "barChartUi.h"
 #include "interact.h"
 #include "interactUi.h"
 #include "hic.h"
 #include "cgiApoptosis.h"
 
@@ -3050,70 +3051,81 @@
 static struct customFactory bamFactory =
 /* Factory for bam tracks */
     {
     NULL,
     "bam",
     bamRecognizer,
     bamLoader,
     };
 
 /*** VCF+tabix Factory - client-side Variant Call Format files compressed & indexed by tabix ***/
 
 static boolean vcfTabixRecognizer(struct customFactory *fac, struct customPp *cpp, char *type,
 				  struct customTrack *track)
 /* Return TRUE if looks like we're handling a vcfTabix track */
 {
-return (sameType(type, "vcfTabix"));
+return (sameType(type, "vcfTabix") || sameType(type, "vcfPhasedTrio"));
 }
 
 static struct customTrack *vcfTabixLoader(struct customFactory *fac, struct hash *chromHash,
 					  struct customPp *cpp, struct customTrack *track,
 					  boolean dbRequested)
 /* Process the vcfTabix track line. */
 {
 struct hash *settings = track->tdb->settingsHash;
 char *bigDataUrl = hashFindVal(settings, "bigDataUrl");
 char *bigDataIndexUrl = hashFindVal(settings, "bigDataIndex");
 
 requireBigDataUrl(bigDataUrl, fac->name, track->tdb->shortLabel);
 struct dyString *dyErr = dyStringNew(0);
 checkAllowedBigDataUrlProtocols(bigDataUrl);
 if (bigDataIndexUrl)
     checkAllowedBigDataUrlProtocols(bigDataIndexUrl);
 
+boolean isVcfPhasedTrio = sameString(hashFindVal(settings,"type"),"vcfPhasedTrio");
+if (isVcfPhasedTrio)
+    {
+    char *reqSampleName = hashFindVal(settings, VCF_PHASED_CHILD_SAMPLE_SETTING);
+    if (reqSampleName == NULL)
+        errAbort("Missing required setting '%s' from track line", VCF_PHASED_CHILD_SAMPLE_SETTING);
+    }
+
 if (doExtraChecking)
     {
     /* protect against temporary network error */
     int vcfMaxErr = 100;
     struct errCatch *errCatch = errCatchNew();
     if (errCatchStart(errCatch))
 	{
 	struct vcfFile *vcff = vcfTabixFileAndIndexMayOpen(bigDataUrl, bigDataIndexUrl, NULL, 0, 0, vcfMaxErr, -1);
 	if (vcff == NULL)
 	    {
             dyStringPrintf(dyErr, "Unable to load and/or parse %s's bigDataUrl %s or its tabix index",
 			   track->tdb->shortLabel, bigDataUrl);
 	    }
 	vcfFileFree(&vcff);
 	}
     errCatchEnd(errCatch);
     if (isNotEmpty(errCatch->message->string))
 	dyStringPrintf(dyErr, ": %s", errCatch->message->string);
     errCatchFree(&errCatch);
     }
 if (isNotEmpty(dyErr->string))
     track->networkErrMsg = dyStringCannibalize(&dyErr);
+if (isVcfPhasedTrio)
+    track->dbTrackType = cloneString("vcfPhasedTrio");
+else
     track->dbTrackType = cloneString("vcfTabix");
 return track;
 }
 
 static struct customFactory vcfTabixFactory =
 /* Factory for vcfTabix tracks */
     {
     NULL,
     "vcfTabix",
     vcfTabixRecognizer,
     vcfTabixLoader,
     };
 
 /*** makeItems Factory - for track where user interactively creates items. ***/
 
@@ -4255,31 +4267,36 @@
                 pfd->fac = fac;
                 slAddHead(&pfdList, pfd);
                 }
             oneList = track;
             }
 	else
     	    oneList = fac->loader(fac, chromHash, cpp, track, dbTrack);
 
 	/* Save a few more settings. */
 	for (oneTrack = oneList; oneTrack != NULL; oneTrack = oneTrack->next)
 	    {
 	    ctAddToSettings(track, "tdbType", oneTrack->tdb->type);
 	    if (dbTrack && oneTrack->dbTrackType != NULL)
 		ctAddToSettings(track, "dbTrackType", oneTrack->dbTrackType);
             if (!trackDbSetting(track->tdb, "inputType"))
+                {
+                if (sameString(oneTrack->tdb->type, "vcfPhasedTrio"))
+                    ctAddToSettings(track, "inputType", "vcfPhasedTrio");
+                else
                     ctAddToSettings(track, "inputType", fac->name);
+                }
             if (dataUrl)
 		ctAddToSettings(track, "dataUrl", dataUrl);
             if (!ctGenome(track) && ctDb)
                 ctAddToSettings(track, "db", ctDb);
 	    }
 	}
     trackList = slCat(trackList, oneList);
     }
 
 // Call the fac loader in parallel on all the bigDataUrl custom tracks
 // using pthreads to avoid long serial timeouts
 pthread_t *threads = NULL;
 if (doParallelLoad && (ptMax > 0))     // parallelFetch.threads=0 to disable parallel fetch
     {
     /* launch parallel threads */