7eb56e8694041997274ee6e9bc1eb862462ca964
kent
  Tue Mar 4 12:30:10 2014 -0800
Adding inList option.
diff --git src/utils/bigWigMerge/bigWigMerge.c src/utils/bigWigMerge/bigWigMerge.c
index 5802fef..33f46a3 100644
--- src/utils/bigWigMerge/bigWigMerge.c
+++ src/utils/bigWigMerge/bigWigMerge.c
@@ -1,49 +1,55 @@
 /* bigWigMerge - Merge together multiple bigWigs into a single one.. */
 #include "common.h"
 #include "linefile.h"
 #include "hash.h"
 #include "options.h"
 #include "localmem.h"
 #include "bbiFile.h"
 #include "bigWig.h"
+#include "obscure.h"
 
+/* version history -
+ *    v2 - added -inList option to avoid huge command lines when merging lots of files. */
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
-  "bigWigMerge - Merge together multiple bigWigs into a single output bedGraph.\n"
+  "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 v1 in1.bw in2.bw .. inN.bw out.bedGraph\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"
   );
 }
 
 double clThreshold = 0.0;
 double clAdjust = 0.0;
 double clClip = BIGDOUBLE;
+boolean clInList = FALSE;
 
 static struct optionSpec options[] = {
    {"threshold", OPTION_DOUBLE},
    {"adjust", OPTION_DOUBLE},
    {"clip", OPTION_DOUBLE},
+   {"inList", 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. */
@@ -93,41 +99,64 @@
 int doublesTheSame(double *pt, int size)
 /* Return count of numbers at start that are the same as first number.  */
 {
 int sameCount = 1;
 int i;
 double x = pt[0];
 for (i=1; i<size; ++i)
     {
     if (pt[i] != x)
         break;
     ++sameCount;
     }
 return sameCount;
 }
 
+void addWigsInFile(char *fileName, struct bbiFile **pList)
+/* Treate  each non-empty non-sharp line of fileName as a bigWig file name
+ * and try to load the bigWig and add to list */
+{
+int i,count;
+char **words, *buf = NULL;
+readAllWords(fileName, &words ,&count, &buf);
+for (i=0; i<count; ++i)
+    {
+    struct bbiFile *inFile = bigWigFileOpen(words[i]);
+    slAddTail(pList, inFile);
+    }
+freeMem(words);
+freeMem(buf);
+}
+
 void bigWigMerge(int inCount, char *inFiles[], char *outFile)
 /* bigWigMerge - Merge together multiple bigWigs into a single one.. */
 {
 /* Make a list of open bigWig files. */
 struct bbiFile *inFile, *inFileList = NULL;
 int i;
 for (i=0; i<inCount; ++i)
     {
+    if (clInList)
+        {
+	addWigsInFile(inFiles[i], &inFileList);
+	}
+    else
+	{
 	inFile = bigWigFileOpen(inFiles[i]);
 	slAddTail(&inFileList, inFile);
 	}
+    }
 
 FILE *f = mustOpen(outFile, "w");
 
 struct bbiChromInfo *chrom, *chromList = getAllChroms(inFileList);
 verbose(1, "Got %d chromosomes from %d bigWigs\nProcessing", 
 	slCount(chromList), slCount(inFileList));
 double *mergeBuf = NULL;
 int mergeBufSize = 0;
 for (chrom = chromList; chrom != NULL; chrom = chrom->next)
     {
     struct lm *lm = lmInit(0);
 
     /* Make sure merge buffer is big enough. */
     int chromSize = chrom->size;
     verboseDot();
@@ -172,20 +201,24 @@
 
     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);
-if (argc < 4)
+clInList = optionExists("inList");
+int minArgs = 4;
+if (clInList)
+    minArgs -= 1;
+if (argc < minArgs)
     usage();
 bigWigMerge(argc-2, argv+1, argv[argc-1]);
 return 0;
 }