Index: trunk/ippTools/share/Makefile.am
===================================================================
--- trunk/ippTools/share/Makefile.am	(revision 38845)
+++ trunk/ippTools/share/Makefile.am	(revision 38846)
@@ -12,4 +12,6 @@
 	addtool_find_ff_id.sql \
 	addtool_find_ff_id_dvo.sql \
+	addtool_find_ffsummary_id.sql \
+	addtool_find_ffsummary_id_dvo.sql \
 	addtool_find_skycal_id_dvo.sql \
 	addtool_find_skycal_id.sql \
@@ -22,4 +24,5 @@
 	addtool_find_pendingexp_diff.sql \
 	addtool_find_pendingexp_ff.sql \
+	addtool_find_pendingexp_ff_summary.sql \
 	addtool_find_pendingexp_skycal.sql \
 	addtool_find_pendingexp_stack.sql \
@@ -29,4 +32,5 @@
 	addtool_find_processedexp_diff.sql \
 	addtool_find_processedexp_ff.sql \
+	addtool_find_processedexp_ff_summary.sql \
 	addtool_find_processedexp_skycal.sql \
 	addtool_find_processedexp_stack.sql \
@@ -39,4 +43,5 @@
 	addtool_queue_diff_id.sql \
 	addtool_queue_ff_id.sql \
+	addtool_queue_ffsummary_id.sql \
 	addtool_queue_stack_id.sql \
 	addtool_queue_sky_id_multi.sql \
@@ -47,4 +52,5 @@
 	addtool_revertprocessedexp_diff.sql \
 	addtool_revertprocessedexp_ff.sql \
+	addtool_revertprocessedexp_ffsummary.sql \
 	addtool_revertprocessedexp_skycal.sql \
 	addtool_revertprocessedexp_stack.sql \
Index: trunk/ippTools/share/addtool_find_ffsummary_id.sql
===================================================================
--- trunk/ippTools/share/addtool_find_ffsummary_id.sql	(revision 38846)
+++ trunk/ippTools/share/addtool_find_ffsummary_id.sql	(revision 38846)
@@ -0,0 +1,21 @@
+SELECT
+     fullForceRun.*
+FROM 
+     fullForceRun
+JOIN fullForceSummary using (ff_id)
+
+LEFT JOIN (SELECT ff_id       AS added_ff_id,
+                  addRun.dvodb AS previous_dvodb
+           FROM addRun
+JOIN fullForceRun on (ff_id = stage_id and addRun.stage = 'fullforce_summary')
+          ) as foo
+     ON ff_id = added_ff_id 
+     --AND stage = 'skycal'
+     -- hook for qualifying the join on the previous_dvodb
+     AND %s
+WHERE
+    fullForceRun.state = 'full'
+    AND fullForceSummary.quality = 0
+    AND fullForceSummary.fault = 0 
+    AND added_ff_id IS NULL
+    -- addtool adds checks on exposure being added to the dvodb previously
Index: trunk/ippTools/share/addtool_find_ffsummary_id_dvo.sql
===================================================================
--- trunk/ippTools/share/addtool_find_ffsummary_id_dvo.sql	(revision 38846)
+++ trunk/ippTools/share/addtool_find_ffsummary_id_dvo.sql	(revision 38846)
@@ -0,0 +1,10 @@
+SELECT fullForceRun.* FROM fullForceRun JOIN fullForceSummary using (ff_id)
+JOIN skycalRun using (skycal_id) join stackRun using (stack_id) 
+JOIN skycell using (skycell_id, tess_id)
+
+WHERE fullForceRun.state = 'full' and fullForceSummary.quality = 0 and fullForceSummary.fault = 0 
+    AND fullForceRun.ff_id NOT IN (SELECT fullForceRun.ff_id
+       FROM addRun
+       JOIN fullForceRun on (fullForceRun.ff_id = addRun.stage_id and addRun.stage = 'fullforce_summary') JOIN fullForceSummary on (fullForceRun.ff_id = fullForceSummary.ff_id)
+       WHERE addRun.stage = 'fullforce_summary' AND %s
+      )
Index: trunk/ippTools/share/addtool_find_pendingexp_ffsummary.sql
===================================================================
--- trunk/ippTools/share/addtool_find_pendingexp_ffsummary.sql	(revision 38846)
+++ trunk/ippTools/share/addtool_find_pendingexp_ffsummary.sql	(revision 38846)
@@ -0,0 +1,19 @@
+   SELECT
+    addRun.*,
+    fullForceSummary.path_base as stageroot,
+    'GPC1' as camera,
+    'PS1' as telescope
+FROM addRun
+JOIN fullForceSummary
+    ON (ff_id = stage_id and stage = "fullforce_summary")
+JOIN fullForceRun
+    using(ff_id)
+LEFT JOIN addProcessedExp using (add_id)
+LEFT JOIN addMask
+    ON addRun.label = addMask.label
+WHERE
+    fullForceRun.state = 'full'
+    AND ((addRun.state = 'new' AND addProcessedExp.add_id IS NULL) OR addRun.state = 'update')
+    AND addRun.dvodb IS NOT NULL
+    AND addRun.workdir IS NOT NULL
+    AND addMask.label IS NULL
Index: trunk/ippTools/share/addtool_find_processedexp_ffsummary.sql
===================================================================
--- trunk/ippTools/share/addtool_find_processedexp_ffsummary.sql	(revision 38846)
+++ trunk/ippTools/share/addtool_find_processedexp_ffsummary.sql	(revision 38846)
@@ -0,0 +1,6 @@
+SELECT
+    addProcessedExp.*,
+    addRun.workdir
+FROM addProcessedExp
+JOIN addRun
+    USING(add_id)
Index: trunk/ippTools/share/addtool_queue_ffsummary.sql
===================================================================
--- trunk/ippTools/share/addtool_queue_ffsummary.sql	(revision 38846)
+++ trunk/ippTools/share/addtool_queue_ffsummary.sql	(revision 38846)
@@ -0,0 +1,23 @@
+INSERT INTO addRun
+    SELECT
+        0,              -- add_id
+        'fullforce_summary',		-- stage
+        ff_id,         -- stage_id
+        0,	       -- stage_extra1
+        '%s',           -- state
+        '%s',           -- workdir
+	'%s',           -- workdir_state
+        '%s',           -- reduction
+        '%s',           -- label
+        '%s',           -- data_group
+        '%s',           -- dvodb 
+        '%s',           -- note
+	%d,		-- image_only
+	%d,		-- minidvodb
+	'%s',           -- minidvodb_group 
+ 	'%s'	        -- minidvodb_name
+    FROM fullForceRun
+    WHERE
+        fullForceRun.state = 'full'
+        AND fullForceRun.ff_id = %lld
+
Index: trunk/ippTools/share/addtool_revertprocessedexp_ffsummary.sql
===================================================================
--- trunk/ippTools/share/addtool_revertprocessedexp_ffsummary.sql	(revision 38846)
+++ trunk/ippTools/share/addtool_revertprocessedexp_ffsummary.sql	(revision 38846)
@@ -0,0 +1,7 @@
+DELETE FROM addProcessedExp
+USING addProcessedExp, addRun
+WHERE
+    addRun.add_id = addProcessedExp.add_id
+    AND addProcessedExp.fault != 0
+    AND addRun.state = 'new'
+    AND addRun.stage = 'fullforce_summary'
Index: trunk/ippTools/src/addtool.c
===================================================================
--- trunk/ippTools/src/addtool.c	(revision 38845)
+++ 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");
     }
 
