be4311c07e14feb728abc6425ee606ffaa611a58
markd
  Fri Jan 22 06:46:58 2021 -0800
merge with master

diff --git src/hg/hgPhyloPlace/writeCustomTracks.c src/hg/hgPhyloPlace/writeCustomTracks.c
index 36399a6..6e98f88 100644
--- src/hg/hgPhyloPlace/writeCustomTracks.c
+++ src/hg/hgPhyloPlace/writeCustomTracks.c
@@ -249,52 +249,53 @@
 
 static char *trackNameFromSampleIds(struct slName *sampleIds)
 /* Make a name for our subtree custom track by concatenating sample names. */
 {
 struct dyString *dy = dyStringCreate("subtree_%s", sampleIds->name);
 struct slName *id;
 for (id = sampleIds->next;  id != NULL;  id = id->next)
     {
     dyStringPrintf(dy, "_%s", id->name);
     if (dy->stringSize > 200)
         break;
     }
 return dyStringCannibalize(&dy);
 }
 
-static void writeSubtreeTrackLine(FILE *ctF, struct subtreeInfo *ti, int fontHeight)
+static void writeSubtreeTrackLine(FILE *ctF, struct subtreeInfo *ti, char *source, int fontHeight)
 /* Write a custom track line to ctF for one subtree. */
 {
 fprintf(ctF, "track name=%s", trackNameFromSampleIds(ti->subtreeUserSampleIds));
 // Keep the description from being too long in order to avoid buffer overflow in hgTrackUi
 int descLen = fprintf(ctF, " description='Uploaded sample%s %s",
                       (slCount(ti->subtreeUserSampleIds) > 1 ? "s" : ""),
                       ti->subtreeUserSampleIds->name);
 struct slName *id;
 for (id = ti->subtreeUserSampleIds->next;  id != NULL;  id = id->next)
     {
     if (descLen > 200)
         {
         fprintf(ctF, " and %d other samples", slCount(id));
         break;
         }
     descLen += fprintf(ctF, ", %s", id->name);
     }
-fprintf(ctF, " and nearest neighboring sequences from GISAID' type=vcf visibility=pack "
+int height = heightForSampleCount(fontHeight, slCount(ti->subtreeNameList));
+fprintf(ctF, " and nearest neighboring %s sequences' type=vcf visibility=pack "
         "hapClusterEnabled=on hapClusterHeight=%d hapClusterMethod='treeFile %s' "
         "highlightIds=%s",
-        heightForSampleCount(fontHeight, slCount(ti->subtreeNameList)), ti->subtreeTn->forHtml,
+        source, height, ti->subtreeTn->forHtml,
         slNameListToString(ti->subtreeUserSampleIds, ','));
 if (isNotEmpty(geneTrack))
     fprintf(ctF, " hapClusterColorBy=function geneTrack=%s", geneTrack);
 fputc('\n', ctF);
 }
 
 static void writeVcfHeader(FILE *f, struct slName *sampleNames)
 /* Write a minimal VCF header with sample names for genotype columns. */
 {
 fprintf(f, "##fileformat=VCFv4.2\n");
 fprintf(f, "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT");
 struct slName *s;
 for (s = sampleNames;  s != NULL;  s = s->next)
     fprintf(f, "\t%s", s->name);
 fputc('\n', f);
@@ -513,56 +514,56 @@
 char refBases[chromSize];
 memset(refBases, 0, sizeof refBases);
 char *sampleBases[chromSize];
 memset(sampleBases, 0, sizeof sampleBases);
 treeToBaseAlleles(bigTree, refBases, sampleBases, sampleToIx, NULL);
 vcfToBaseAlleles(userVcf, refBases, sampleBases, sampleToIx);
 int sampleCount = sampleToIx->elCount;
 baseAllelesToVcf(refBases, sampleBases, chromSize, sampleCount, f);
 int i;
 for (i = 0;  i < chromSize;  i++)
     freeMem(sampleBases[i]);
 }
 
 static void addSubtreeCustomTracks(FILE *ctF, char *userVcfFile, struct subtreeInfo *subtreeInfoList,
                                    struct hash *samplePlacements, struct phyloTree *bigTree,
-                                   int fontHeight, int *pStartTime)
+                                   char *source, int fontHeight, int *pStartTime)
 /* For each subtree trashfile, write VCF+treeFile custom track text to ctF. */
 {
 struct vcfFile *userVcf = parseUserVcf(userVcfFile, pStartTime);
 if (! userVcf)
     {
     warn("Problem parsing VCF file with user variants '%s'; can't make subtree subtracks.",
          userVcfFile);
     return;
     }
 if (!bigTree)
     return;
 struct subtreeInfo *ti;
 for (ti = subtreeInfoList;  ti != NULL;  ti = ti->next)
     {
-    writeSubtreeTrackLine(ctF, ti, fontHeight);
+    writeSubtreeTrackLine(ctF, ti, source, fontHeight);
     writeVcfHeader(ctF, ti->subtreeNameList);
     writeSubtreeVcf(ctF, ti->subtreeIdToIx, userVcf, bigTree);
     fputc('\n', ctF);
     }
 vcfFileFree(&userVcf);
 reportTiming(pStartTime, "write subtree custom tracks");
 }
 
 struct tempName *writeCustomTracks(struct tempName *vcfTn, struct usherResults *ur,
                                    struct slName *sampleIds, struct phyloTree *bigTree,
-                                   int fontHeight, int *pStartTime)
+                                   char *source, int fontHeight, int *pStartTime)
 /* Write one custom track per subtree, and one custom track with just the user's uploaded samples. */
 {
 struct tempName *ctVcfTn = userVcfWithImputedBases(vcfTn, ur->samplePlacements, sampleIds);
 struct tempName *ctTn;
 AllocVar(ctTn);
 trashDirFile(ctTn, "ct", "ct_pp", ".ct");
 FILE *ctF = mustOpen(ctTn->forCgi, "w");
 addSubtreeCustomTracks(ctF, ctVcfTn->forCgi, ur->subtreeInfoList, ur->samplePlacements, bigTree,
-                       fontHeight, pStartTime);
+                       source, fontHeight, pStartTime);
 addSampleOnlyCustomTrack(ctF, ctVcfTn, ur->bigTreePlusTn->forCgi, sampleIds, fontHeight,
                          pStartTime);
 carefulClose(&ctF);
 return ctTn;
 }