3e672be5b65370e1b5e779086da908994ec37c65
braney
  Fri Sep 16 16:02:42 2011 -0700
allow for an R,G,B field (normally field 9).  #5287
diff --git src/utils/bedToBigBed/bedToBigBed.c src/utils/bedToBigBed/bedToBigBed.c
index 06384b9..1efef18 100644
--- src/utils/bedToBigBed/bedToBigBed.c
+++ src/utils/bedToBigBed/bedToBigBed.c
@@ -6,66 +6,69 @@
 #include "dystring.h"
 #include "obscure.h"
 #include "asParse.h"
 #include "basicBed.h"
 #include "sig.h"
 #include "rangeTree.h"
 #include "zlibFace.h"
 #include "sqlNum.h"
 #include "bigBed.h"
 
 static char const rcsid[] = "$Id: bedToBigBed.c,v 1.24 2010/05/19 18:51:13 hiram Exp $";
 
 int blockSize = 256;
 int itemsPerSlot = 512;
 int bedFields = 0;
+int rgbField = 0;
 char *as = NULL;
 static boolean doCompress = FALSE;
 static boolean tabSep = FALSE;
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "bedToBigBed v. %d - Convert bed file to bigBed.\n"
   "usage:\n"
   "   bedToBigBed in.bed chrom.sizes out.bb\n"
   "Where in.bed is in one of the ascii bed formats, but not including track lines\n"
   "and chrom.sizes is two column: <chromosome name> <size in bases>\n"
   "and out.bb is the output indexed big bed file.\n"
   "The in.bed file must be sorted by chromosome,start,\n"
   "  to sort a bed file, use the unix sort command:\n"
   "     sort -k1,1 -k2,2n unsorted.bed > sorted.bed\n"
   "\n"
   "options:\n"
   "   -blockSize=N - Number of items to bundle in r-tree.  Default %d\n"
   "   -itemsPerSlot=N - Number of data points bundled at lowest level. Default %d\n"
   "   -bedFields=N - Number of fields that fit standard bed definition.  If undefined\n"
   "                  assumes all fields in bed are defined.\n"
   "   -as=fields.as - If have non-standard fields, it's great to put a definition\n"
   "                   of each field in a row in AutoSql format here.\n"
-  "   -unc - If set, do not use compression."
+  "   -rgbField=N  - the Nth field is a comma separated R,G,B triple.\n"
+  "   -unc - If set, do not use compression.\n"
   "   -tabs - If set, expect fields to be tab separated, normally\n"
   "           expects white space separator.\n"
   , bbiCurrentVersion, blockSize, itemsPerSlot
   );
 }
 
 static struct optionSpec options[] = {
    {"blockSize", OPTION_INT},
    {"itemsPerSlot", OPTION_INT},
    {"bedFields", OPTION_INT},
+   {"rgbField", OPTION_INT},
    {"as", OPTION_STRING},
    {"unc", OPTION_BOOLEAN},
    {"tabs", OPTION_BOOLEAN},
    {NULL, 0},
 };
 
 void writeBlocks(struct bbiChromUsage *usageList, struct lineFile *lf, struct asObject *as, 
 	bits16 definedFieldCount, int itemsPerSlot, struct bbiBoundsArray *bounds, 
 	int sectionCount, boolean doCompress, FILE *f, 
 	int resTryCount, int resScales[], int resSizes[],
 	bits16 *retFieldCount, bits16 *retDefinedFieldCount, bits32 *retMaxBlockSize)
 /* Read through lf, writing it in f.  Save starting points of blocks (every itemsPerSlot)
  * to boundsArray */
 {
 int maxBlockSize = 0;
@@ -132,31 +135,39 @@
 	chrom = row[0];
 	start = lineFileNeedNum(lf, row, 1);
 	end = lineFileNeedNum(lf, row, 2);
 
 	/* Check remaining fields are formatted right. */
 	if (fieldCount > 3)
 	    {
 	    /* Go through and check that numerical strings really are numerical. */
 	    struct asColumn *asCol = slElementFromIx(as->columnList, 3);
 	    int i;
 	    for (i=3; i<fieldCount; ++i)
 		{
 		enum asTypes type = asCol->lowType->type;
 		if (! (asCol->isList || asCol->isArray))
 		    {
-		    if (asTypesIsInt(type))
+		    if (rgbField == i + 1)
+			{
+			// we check for error, but save the R,G,B truple in 
+			// the bigBed
+			if (-1 == bedParseRgb(row[i]))
+			    errAbort("ERROR: expecting r,g,b specification, "
+				    "found: '%s'", row[i]);
+			}
+		    else if (asTypesIsInt(type))
 			lineFileNeedFullNum(lf, row, i);
 		    else if (asTypesIsFloating(type))
 			lineFileNeedDouble(lf, row, i);
 		    }
 		asCol = asCol->next;
 		}
 	    }
 
 	sameChrom = sameString(chrom, usage->name);
 	}
     else  /* No next line */
 	{
 	atEnd = TRUE;
 	}
 
@@ -666,26 +677,27 @@
 
 void bedToBigBed(char *inName, char *chromSizes, char *outName)
 /* bedToBigBed - Convert bed file to bigBed.. */
 {
 bbFileCreate(inName, chromSizes, blockSize, itemsPerSlot, bedFields, as, 
 	doCompress, outName);
 }
 
 int main(int argc, char *argv[])
 /* Process command line. */
 {
 optionInit(&argc, argv, options);
 blockSize = optionInt("blockSize", blockSize);
 itemsPerSlot = optionInt("itemsPerSlot", itemsPerSlot);
 bedFields = optionInt("bedFields", bedFields);
+rgbField = optionInt("rgbField", rgbField);
 as = optionVal("as", as);
 doCompress = !optionExists("unc");
 tabSep = optionExists("tabs");
 if (argc != 4)
     usage();
 bedToBigBed(argv[1], argv[2], argv[3]);
 optionFree();
 if (verboseLevel() > 1)
     printVmPeak();
 return 0;
 }