ee50897d485efc9969ea40d65b2e557cf0963f42
braney
  Wed Aug 26 15:16:17 2015 -0700
add -max option to bigWigMerge #15929

diff --git src/utils/bigWigMerge/bigWigMerge.c src/utils/bigWigMerge/bigWigMerge.c
index 3417b39..54e91cb 100644
--- src/utils/bigWigMerge/bigWigMerge.c
+++ src/utils/bigWigMerge/bigWigMerge.c
@@ -16,43 +16,46 @@
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "bigWigMerge v2 - Merge together multiple bigWigs into a single output bedGraph.\n"
   "You'll have to run bedGraphToBigWig to make the output bigWig.\n"
   "The signal values are just added together to merge them\n"
   "usage:\n"
   "   bigWigMerge in1.bw in2.bw .. inN.bw out.bedGraph\n"
   "options:\n"
   "   -threshold=0.N - don't output values at or below this threshold. Default is 0.0\n"
   "   -adjust=0.N - add adjustment to each value\n"
   "   -clip=NNN.N - values higher than this are clipped to this value\n"
   "   -inList - input file are lists of file names of bigWigs\n"
+  "   -max - merged value is maximum from input files rather than sum\n"
   );
 }
 
 double clThreshold = 0.0;
 double clAdjust = 0.0;
 double clClip = BIGDOUBLE;
 boolean clInList = FALSE;
+boolean clMax = FALSE;
 
 static struct optionSpec options[] = {
    {"threshold", OPTION_DOUBLE},
    {"adjust", OPTION_DOUBLE},
    {"clip", OPTION_DOUBLE},
    {"inList", OPTION_BOOLEAN},
+   {"max", OPTION_BOOLEAN},
    {NULL, 0},
 };
 
 
 static int bbiChromInfoCmpStringsWithEmbeddedNumbers(const void *va, const void *vb)
 /* Compare strings such as gene names that may have embedded numbers,
  * so that bmp4a comes before bmp14a */
 {
 const struct bbiChromInfo *a = *((struct bbiChromInfo **)va);
 const struct bbiChromInfo *b = *((struct bbiChromInfo **)vb);
 return cmpStringsWithEmbeddedNumbers(a->name, b->name);
 }
 
 struct bbiChromInfo *getAllChroms(struct bbiFile *fileList)
 /* Read chromosomes from all files and make sure they agree, and return merged list. */
@@ -175,53 +178,62 @@
         mergeBuf[i] = 0.0;
 
     /* Loop through each input file grabbing data and merging it in. */
     for (inFile = inFileList; inFile != NULL; inFile = inFile->next)
         {
 	struct bbiInterval *ivList = bigWigIntervalQuery(inFile, chrom->name, 0, chromSize, lm);
 	verbose(3, "Got %d intervals in %s\n", slCount(ivList), inFile->fileName);
 	struct bbiInterval *iv;
 	for (iv = ivList; iv != NULL; iv = iv->next)
 	    {
 	    double val = iv->val;
 	    if (val > clClip)
 	        val = clClip;
 	    int end = iv->end;
 	    for (i=iv->start; i < end; ++i)
+                {
+                if (clMax)
+                    {
+                    if (mergeBuf[i] < val) 
+                        mergeBuf[i] = val;
+                    }
+                else
                     mergeBuf[i] += val;
                 }
 	    }
+	}
 
 
     /* Output each range of same values as a bedGraph item */
     int sameCount;
     for (i=0; i<chromSize; i += sameCount)
         {
 	sameCount = doublesTheSame(mergeBuf+i, chromSize-i);
 	double val = mergeBuf[i] + clAdjust;
 	if (val > clThreshold)
 	    fprintf(f, "%s\t%d\t%d\t%g\n", chrom->name, i, i + sameCount, val);
 	}
 
     lmCleanup(&lm);
     }
 verbose(1, "\n");
 
 carefulClose(&f);
 }
 
 int main(int argc, char *argv[])
 /* Process command line. */
 {
 optionInit(&argc, argv, options);
 clThreshold = optionDouble("threshold", clThreshold);
 clAdjust = optionDouble("adjust", clAdjust);
 clClip = optionDouble("clip", clClip);
 clInList = optionExists("inList");
+clMax = optionExists("max");
 int minArgs = 4;
 if (clInList)
     minArgs -= 1;
 if (argc < minArgs)
     usage();
 bigWigMerge(argc-2, argv+1, argv[argc-1]);
 return 0;
 }