e0894c245daeae473063161e21bed7ca6dda3c5c
kent
  Tue Aug 19 10:58:48 2014 -0700
Adding selfPair as a special case second list like single.
diff --git src/parasol/gensub2/gensub2.c src/parasol/gensub2/gensub2.c
index 1314001..f6e0456 100644
--- src/parasol/gensub2/gensub2.c
+++ src/parasol/gensub2/gensub2.c
@@ -26,33 +26,34 @@
   "       $(path2)  - Full path name of second file.\n"
   "       $(dir1)   - First directory. Includes trailing slash if any.\n"
   "       $(dir2)   - Second directory.\n"
   "       $(lastDir1) - The last directory in the first path. Includes trailing slash if any.\n"
   "       $(lastDir2) - The last directory in the second path. Includes trailing slash if any.\n"
   "       $(lastDirs1=<n>) - The last n directories in the first path.\n"
   "       $(lastDirs2=<n>) - The last n directories in the second path.\n"
   "       $(root1)  - First file name without directory or extension.\n"
   "       $(root2)  - Second file name without directory or extension.\n"
   "       $(ext1)   - First file extension.\n"
   "       $(ext2)   - Second file extension.\n"
   "       $(file1)  - Name without dir of first file.\n"
   "       $(file2)  - Name without dir of second file.\n"
   "       $(num1)   - Index of first file in list.\n"
   "       $(num2)   - Index of second file in list.\n"
-  "The <file list 2> parameter can be 'single' if there is only \n"
-  "one file list.  By default the order is diagonal, meaning if \n"
-  "the first list is ABC and the secon list is abc the combined \n"
+  "The <file list 2> parameter can be 'single' if there is only one file list and \n"
+  "'selfPair' if there is a single list, but you want all\n" 
+  "pairs of single list with itself.  By default the order is diagonal, meaning if \n"
+  "the first list is ABC and the second list is abc the combined \n"
   "order is Aa Ba Ab Ca Bb Ac  Cb Bc Cc.  This tends to put the \n"
   "largest jobs first if the file lists are both sorted by size. \n"
   "The following options can change this:\n"
   "    -group1 - write elements in order Aa Ab Ac Ba Bb Bc Ca Cb Cc\n"
   "    -group2 - write elements in order Aa Ba Ca Ab Bb Cb Ac Bc Cc\n"
   "template file syntax help for check statement: {check 'when' 'what' <file>}\n"
   " where 'when' is either 'in' or 'out'\n"
   " and 'what' is one of: 'exists' 'exists+' 'line' 'line+'\n"
   " 'exists' means file exists, may be zero size\n"
   " 'exists+' means file exists and is non-zero size\n"
   " 'line' means file may have 0 or more lines of ascii data and is properly\n"
   "        line-feed terminated\n"
   " 'line+' means file is 1 or more lines of ascii data and is properly\n"
   "        line-feed terminated"
   , version
@@ -258,31 +259,33 @@
     writeSubbed(loopEl->name, subList, f);
 
 /* Clean up. */
 slFreeList(&subList);
 }
 
 void gensub2(char *list1Name, char *list2Name, char *templateName, char *conName)
 /* gensub2 - Generate condor submission file from template and two file lists. */
 {
 struct lineFile *lfT = lineFileOpen(templateName, TRUE);
 FILE *f = mustOpen(conName, "w");
 char *lineT;
 int i, j;
 struct slName *loopText = NULL, *loopEl;
 bool gotLoop = FALSE, gotEndLoop = FALSE;
-boolean twoLists = !sameWord(list2Name, "single");
+boolean isSingle = sameWord(list2Name, "single");
+boolean selfPair = sameWord(list2Name, "selfPair");
+boolean twoLists = !isSingle && !selfPair;
 char **lines1 = NULL, **lines2 = NULL;
 int count1, count2;
 
 /* Read input list files. */
 readLines(list1Name, &count1, &lines1);
 if (twoLists)
     readLines(list2Name, &count2, &lines2);
 else
     {
     AllocArray(lines2, 1);
     lines2[0] = "single";
     count2 = 1;
     }
 
 
@@ -314,30 +317,38 @@
     errAbort("No #ENDLOOP statement in %s", templateName);
 slReverse(&loopText);
 
 if (optionExists("group1"))
     {
     for (i=0; i<count1; ++i)
 	for (j=0; j<count2; ++j)
 	    outputOneSub(lines1[i], lines2[j], i, j, loopText, f);
     }
 else if (optionExists("group2"))
     {
     for (j=0; j<count2; ++j)
 	for (i=0; i<count1; ++i)
 	    outputOneSub(lines1[i], lines2[j], i, j, loopText, f);
     }
+else if (selfPair)
+    {
+    for (i=0; i<count1; ++i)
+       {
+       for (j=i+1; j<count1; ++j)
+            outputOneSub(lines1[i], lines1[j], i, j, loopText, f);
+       }
+    }
 else
     {
     /* This loop is constructed to output stuff on the diagonal.
      * That is if list 1 contains A,B,C and list 2 a,b,c the
      * order of the output will be Aa Ba Ab Ca Bb Ac Cb Bc Cc
      * This is so that if both lists are sorted by size, then
      * the largest sized jobs will tend to be output first. */
     int bothCount = count1 + count2, bothIx;
     bothCount = count1 + count2;
     for (bothIx = 0; bothIx < bothCount; ++bothIx)
 	{
 	i = bothIx;
 	j = 0;
 	while (i >= 0)
 	    {