Index: trunk/ippTools/src/addtool.c
===================================================================
--- trunk/ippTools/src/addtool.c	(revision 38608)
+++ trunk/ippTools/src/addtool.c	(revision 38846)
@@ -156,4 +156,10 @@
     if (strcmp(stage, "fullforce")==0) {
       pxAddLabelSearchArgs (config, where, "-label",     "fullForceRun.label", "=="); //define using skycalRun label
+      pxAddLabelSearchArgs (config, where, "-data_group","fullForceRun.data_group", "==");
+      PXOPT_COPY_STR(config->args, where,  "-reduction", "fullForceRun.reduction",  "==");
+    }
+    if (strcmp(stage, "fullforce_summary")==0) {
+      //should be nearly identical to fullforce (uses the same tables)
+      pxAddLabelSearchArgs (config, where, "-label",     "fullForceRun.label", "=="); 
       pxAddLabelSearchArgs (config, where, "-data_group","fullForceRun.data_group", "==");
       PXOPT_COPY_STR(config->args, where,  "-reduction", "fullForceRun.reduction",  "==");
@@ -315,4 +321,21 @@
     }
 
+        if (strcmp(stage,"fullforce_summary") == 0) {
+      if (dvodb ) {
+        psTrace("addtool.c", PS_LOG_INFO, "dvodb argument found (%s) using addtool_find_ffsummary_id_dvo.sql\n%s\n", dvodb,stage);
+        // find the skycal_id of all the exposures that we want to queue up.                                                                                                   
+        bare_query = pxDataGet("addtool_find_ffsummary_id_dvo.sql");
+        // user supplied dvodb                                                                                                                                              
+        psStringAppend(&dvodb_string, "addRun.dvodb = '%s'", dvodb);
+      } else {
+        psTrace("addtool.c", PS_LOG_INFO, "dvodb argument not found using addtool_ffsummary_id.sql\n%s\n",stage);
+        // find the skycal_id of all the exposures that we want to queue up.                                                                                                   
+        bare_query = pxDataGet("addtool_find_ffsummary_id.sql");
+        // inherit dvodb from skycalRun, avoid matching NULL                                                                                                                   
+        psStringAppend(&dvodb_string, "(fullForceRun.dvodb IS NOT NULL AND previous_dvodb = fullForceRun.dvodb)");
+	// this is silly, there is no dvodb in skycalRun...?
+      }
+    }
+
 
 
@@ -350,4 +373,12 @@
 
 	}
+	if (strcmp(stage,"fullforce_summary") == 0) {
+	  //ff needs the ra /deg stuff
+	  psStringAppend(&query, " AND radeg >= %f", minra);
+	  psStringAppend(&query, " AND radeg <= %f", maxra);
+	  psStringAppend(&query, " AND decdeg >= %f", mindec);
+	  psStringAppend(&query, " AND decdeg <= %f", maxdec);
+
+	}
 
         psFree(whereClause);
@@ -404,4 +435,7 @@
       if (strcmp(stage,"fullforce") == 0) {
 	psStringAppend(&query, " GROUP BY ff_id, warp_id ");  //this needs checking, but I think it shoul be fine? it groups by lots of stuff (including stack - we only want one of each stack in there
+      }
+      if (strcmp(stage,"fullforce_summary") == 0) {
+	psStringAppend(&query, " GROUP BY ff_id ");  //needs to be checked, but should be fine: want 1 ff summary cmf.
       }
 
@@ -592,4 +626,31 @@
         psMetadata *md = output->data[i];
 
+        fullForceRunRow *row = fullForceRunObjectFromMetadata(md);
+
+        if (!row) {
+	  psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into fullforceRun");
+	  psFree(output);
+	  return false;
+        }
+
+	if (!dvodb) {  // there's no skycalRun.dvodb
+ 	  psError(PS_ERR_UNKNOWN, false, "cannot queue addstar run without a defined dvodb: label: %s, ff_id %" PRId64, row->label, row->ff_id);
+	  psFree(output);
+	  return false;
+        }
+        if (!workdir && !row->workdir) {
+	  psError(PS_ERR_UNKNOWN, false, "cannot queue addstar run without a defined workdir: label: %s, ff_id %" PRId64, row->label, row->ff_id);
+	  psFree(output);
+	  return false;
+        }
+
+        psFree(row);
+      }
+    }
+
+    if (strcmp(stage,"fullforce_summary") == 0) {
+      for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+	//i believe this is correct for ff_summary as well:
         fullForceRunRow *row = fullForceRunObjectFromMetadata(md);
 
@@ -908,4 +969,47 @@
         psFree(row);
     }
+    }
+    if (strcmp(stage,"fullforce_summary") == 0) {
+      for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+	psS64 stage_id =0; 
+	
+	fullForceRunRow *row = fullForceRunObjectFromMetadata(md);
+	stage_id = row->ff_id;
+	bool status = false;
+	
+        if (!row) {
+            psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into fullforceRun");
+            psFree(output);
+            return false;
+        }
+
+        // queue the exp
+        if (!pxaddQueueByCamID(config,
+			       stage,
+                               stage_id,
+			       0,
+                               workdir     ? workdir   : row->workdir,
+                               reduction   ? reduction : row->reduction,
+                               label       ? label     : row->label,
+                               data_group  ? data_group : (row->data_group ? row->data_group :  (label ? label : row->label)),
+                               dvodb       ? dvodb     : NULL,
+                               note        ? note      : NULL,
+                               image_only,
+                               minidvodb,
+                               minidvodb_group,
+                               minidvodb_name
+        )) {
+            if (!psDBRollback(config->dbh)) {
+                psError(PS_ERR_UNKNOWN, false, "database error sfg");
+            }
+            psError(PS_ERR_UNKNOWN, false,
+                    "failed to trying to queue stage %s %" PRId64,stage, stage_id);
+            psFree(row);
+            psFree(output);
+            return false;
+        }
+        psFree(row);
+    }
       }
 
@@ -968,4 +1072,7 @@
     if (strcmp(stage, "fullforce")==0) {
       query = psStringCopy("UPDATE addRun JOIN fullForceResult on (ff_id = stage_id and warp_id = stage_extra1 and stage = 'fullforce') JOIN fullForceRun on (ff_id)");
+    }
+    if (strcmp(stage, "fullforce_summary")==0) {
+      query = psStringCopy("UPDATE addRun JOIN fullForceSummary on (ff_id = stage_id and stage = 'fullforce_summary') JOIN fullForceRun on (ff_id)");
     }
 
@@ -1024,4 +1131,7 @@
       query = pxDataGet("addtool_find_pendingexp_ff.sql");
     }
+    if (strcmp(stage, "fullforce_summary")==0) {
+      query = pxDataGet("addtool_find_pendingexp_ffsummary.sql");
+    }
 
 
@@ -1066,9 +1176,9 @@
       }
     }
-
-    //    if (multi) {
-    //  psStringAppend(&query, " , %s", "stage_id");
-    //}
-
+    
+    if (strcmp(stage, "fullforce_summary") == 0) {
+      //this group by is needed to join against all the warps (to get camera)
+      psStringAppend(&query, "GROUP BY %s", "ff_id");
+    }
 
     // treat limit == 0 as "no limit"
@@ -1305,5 +1415,6 @@
     } else if (strcmp (stage,"fullforce") == 0) {
       query = pxDataGet("addtool_find_processedexp_ff.sql");
-
+    } else if (strcmp (stage,"fullforce_summary") == 0) {
+      query = pxDataGet("addtool_find_processedexp_ffsummary.sql");
     } else {
         psFree(where);
@@ -1430,4 +1541,7 @@
     if (strcmp(stage, "fullforce") == 0) {
       query = pxDataGet("addtool_revertprocessedexp_ff.sql");
+    }
+    if (strcmp(stage, "fullforce_summary") == 0) {
+      query = pxDataGet("addtool_revertprocessedexp_ffsummary.sql");
     }
 
