5b83a4f3758e71c48c76f3235f7a1924c21b4ae2
angie
  Tue Jan 15 13:21:18 2019 -0800
Implement liftOver -multiple -genePred; update gtexGeneModel with all the alts/patches.  refs #18855

diff --git src/hg/lib/liftOver.c src/hg/lib/liftOver.c
index 0f862fa..c72901e 100644
--- src/hg/lib/liftOver.c
+++ src/hg/lib/liftOver.c
@@ -1569,75 +1569,79 @@
 bed->blockCount = count = gp->exonCount;
 AllocArray(bed->blockSizes, count);
 AllocArray(bed->chromStarts, count);
 for (i=0; i<count; ++i)
     {
     int s = gp->exonStarts[i];
     int e = gp->exonEnds[i];
     bed->blockSizes[i] = e - s;
     bed->chromStarts[i] = s - start;
     }
 return bed;
 }
 
 void liftOverGenePred(char *fileName, struct hash *chainHash, 
                         double minMatch, double minBlocks, bool fudgeThick,
-                        FILE *mapped, FILE *unmapped)
+                      FILE *mapped, FILE *unmapped, boolean multiple)
 /* Lift over file in genePred format. */
 {
-//#*** TODO make multiple an argument; could also add db and chainTable args.
-bool multiple = FALSE;
 char *db = NULL, *chainTable = NULL;
 
 struct bed *bed;
 struct genePred *gp = NULL;
 char *error;
-FILE *f;
 struct genePred *gpList = genePredExtLoadAll(fileName);
 for (gp = gpList ; gp != NULL ; gp = gp->next)
     {
     // uglyf("%s %s %d %d %s\n", gp->name, gp->chrom, gp->txStart, gp->txEnd, gp->strand);
-    f = mapped;
     bed = genePredToBed(gp);
     error = remapBlockedBed(chainHash, bed, minMatch, minBlocks, fudgeThick,
                             multiple, db, chainTable);
     if (error)
 	{
-	f = unmapped;
 	fprintf(unmapped, "# %s\n", error);
+        bedFree(&bed);
+        genePredTabOut(gp, unmapped);
 	}
    else
 	{
-	int count, i, start;
+        int exonCount = gp->exonCount;
+        struct bed *bedList = bed;
+        for (;  bed != NULL;  bed = bed->next)
+            {
+            if (bed->blockCount > exonCount)
+                errAbort("program error: need to allocate extra blocks for bed.");
             freeMem(gp->chrom);
             gp->chrom = cloneString(bed->chrom);
-	gp->txStart = start = bed->chromStart;
+            int start = gp->txStart = bed->chromStart;
             gp->txEnd = bed->chromEnd;
             gp->strand[0] = bed->strand[0];
             gp->cdsStart = bed->thickStart;
             gp->cdsEnd = bed->thickEnd;
-	gp->exonCount = count = bed->blockCount;
+            int count = gp->exonCount = bed->blockCount;
+            int i;
             for (i=0; i<count; ++i)
                 {
                 int s = start + bed->chromStarts[i];
                 int e = s + bed->blockSizes[i];
                 gp->exonStarts[i] = s;
                 gp->exonEnds[i] = e;
                 }
+            genePredTabOut(gp, mapped);
+	    }
+        bedFreeList(&bedList);
 	}
-    genePredTabOut(gp, f);
-    bedFree(&bed);
 //    genePredFree(&gp);
     }
 }
 
 static struct liftRange *sampleToRangeList(struct sample *sample, int sizeOne)
 /* Make a range list corresponding to sample. */
 {
 int i;
 struct liftRange *rangeList = NULL, *range;
 for (i=0; i<sample->sampleCount; ++i)
     {
     AllocVar(range);
     range->start = range->end = sample->chromStart + sample->samplePosition[i];
     range->end += sizeOne;
     range->val = sample->sampleHeight[i];