Index: trunk/ippTools/src/addtool.c
===================================================================
--- trunk/ippTools/src/addtool.c	(revision 35304)
+++ trunk/ippTools/src/addtool.c	(revision 37551)
@@ -122,4 +122,7 @@
     PXOPT_COPY_S64(config->args, where,  "-sky_id",    "staticskyRun.sky_id", "==");
     PXOPT_COPY_S64(config->args, where,  "-skycal_id",  "skycalRun.skycal_id", "==");
+    PXOPT_COPY_S64(config->args, where,  "-diff_id",  "diffRun.diff_id", "==");
+    PXOPT_COPY_S64(config->args, where,  "-ff_id",  "fullForceRun.ff_id", "==");
+
     PXOPT_LOOKUP_STR(stage,       config->args, "-stage", false, false);
     if (strcmp(stage, "cam")== 0) {
@@ -146,5 +149,17 @@
       PXOPT_COPY_STR(config->args, where,  "-reduction", "skycalRun.reduction",  "==");
     }
-
+    if (strcmp(stage, "diff")==0) {
+      pxAddLabelSearchArgs (config, where, "-label",     "diffRun.label", "=="); //define using skycalRun label
+      pxAddLabelSearchArgs (config, where, "-data_group","diffRun.data_group", "==");
+      PXOPT_COPY_STR(config->args, where,  "-reduction", "diffRun.reduction",  "==");
+    }
+    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 (!psListLength(where->list)) {
         psFree(where);
@@ -258,5 +273,37 @@
     }
 
-
+    if (strcmp(stage,"diff") == 0) {
+      if (dvodb ) {
+        psTrace("addtool.c", PS_LOG_INFO, "dvodb argument found (%s) using addtool_find_diff_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_diff_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_find_diff_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_diff_id.sql");
+        // inherit dvodb from skycalRun, avoid matching NULL                                                                                                                   
+        psStringAppend(&dvodb_string, "(diffRun.dvodb IS NOT NULL AND previous_dvodb = diffRun.dvodb)");
+	// this is silly, there is no dvodb in skycalRun...?
+      }
+    }
+
+    if (strcmp(stage,"fullforce") == 0) {
+      if (dvodb ) {
+        psTrace("addtool.c", PS_LOG_INFO, "dvodb argument found (%s) using addtool_find_ff_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_ff_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_ff_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_ff_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...?
+      }
+    }
 
 
@@ -324,4 +371,15 @@
 	psStringAppend(&query, " GROUP BY skycal_id, sky_id, stack_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
       }
+      //needs to be checked HAF xxx
+      if (strcmp(stage,"diff") == 0) {
+	psStringAppend(&query, " GROUP BY diff_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
+      }
+      //needs to be checked HAF xxx
+      if (strcmp(stage,"fullforce") == 0) {
+	psStringAppend(&query, " GROUP BY ff_id, skycal_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
+      }
+
+
+
 
     psTrace("addtool.c", PS_LOG_INFO,"query: \n\n%s\n\n",query);
@@ -476,4 +534,57 @@
     }
 
+    if (strcmp(stage,"diff") == 0) {
+      for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+
+        diffRunRow *row = diffRunObjectFromMetadata(md);
+
+        if (!row) {
+	  psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into skycalRun");
+	  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, diff_id %" PRId64, row->label, row->diff_id);
+	  psFree(output);
+	  return false;
+        }
+        if (!workdir && !row->workdir) {
+	  psError(PS_ERR_UNKNOWN, false, "cannot queue addstar run without a defined workdir: label: %s, diff_id %" PRId64, row->label, row->diff_id);
+	  psFree(output);
+	  return false;
+        }
+
+        psFree(row);
+      }
+    }
+
+    if (strcmp(stage,"fullforce") == 0) {
+      for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+
+        fullForceRunRow *row = fullForceRunObjectFromMetadata(md);
+
+        if (!row) {
+	  psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into skycalRun");
+	  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);
+      }
+    }
 
 
@@ -672,4 +783,92 @@
       }
    
+    if (strcmp(stage,"diff") == 0) {
+    for (long i = 0; i < psArrayLength(output); i++) {
+        psMetadata *md = output->data[i];
+	psS64 stage_id =0; 
+	
+		  diffRunRow *row = diffRunObjectFromMetadata(md);
+	  stage_id = row->diff_id;
+	
+        if (!row) {
+            psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into skycalRun");
+            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);
+    }
+      }
+ 
+    if (strcmp(stage,"fullforce") == 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;
+	
+        if (!row) {
+            psError(PS_ERR_UNKNOWN, false, "failed to convert metadata into skycalRun");
+            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);
+    }
+      }
+
+
+
 
 
@@ -695,4 +894,7 @@
     PXOPT_COPY_S64(config->args, where, "-sky_id",    "staticskyRun.sky_id", "==");
     PXOPT_COPY_S64(config->args, where, "-skycal_id", "skycalRun.skycal_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-diff_id", "diffRun.diff_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-ff_id", "fullForceRun.ff_id", "==");
+
     PXOPT_LOOKUP_STR(stage,       config->args, "-stage", false, false);
     pxcamGetSearchArgs (config, where); // most search arguments based on camera
@@ -709,14 +911,20 @@
     psString query = NULL;
     if (strcmp(stage, "cam")==0) {
-      query = psStringCopy("UPDATE addRun JOIN camRun on cam_id = stage_id JOIN chipRun USING(chip_id) JOIN rawExp USING(exp_id)");
+      query = psStringCopy("UPDATE addRun JOIN camRun on (cam_id = stage_id and stage = 'cam')  JOIN chipRun USING(chip_id) JOIN rawExp USING(exp_id)");
     }
     if (strcmp(stage, "stack")==0) {
-      query = psStringCopy("UPDATE addRun JOIN stackRun on stack_id = stage_id");
+      query = psStringCopy("UPDATE addRun JOIN stackRun on (stack_id = stage_id and stage = 'stack')");
     }
     if (strcmp(stage, "staticsky")==0) {
-      query = psStringCopy("UPDATE addRun JOIN staticskyRun on sky_id = stage_id");
+      query = psStringCopy("UPDATE addRun JOIN staticskyRun on (sky_id = stage_id and stage = 'staticsky')");
     }
     if (strcmp(stage, "skycal")==0) {
-      query = psStringCopy("UPDATE addRun JOIN skycalRun on skycal_id = stage_id");
+      query = psStringCopy("UPDATE addRun JOIN skycalRun on (skycal_id = stage_id and stage = 'skycal')");
+    }
+    if (strcmp(stage, "diff")==0) {
+      query = psStringCopy("UPDATE addRun JOIN diffInputSkyfile on (diff_id = stage_id and diff_skyfile_id = stage_extra1 and stage = 'diff') JOIN diffSkyfile on (diff_id, skycell_id) JOIN diffRun using (diff_id)");
+    }
+    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)");
     }
 
@@ -743,4 +951,6 @@
     PXOPT_COPY_S64(config->args, where, "-sky_id",    "staticskyRun.sky_id", "==");
     PXOPT_COPY_S64(config->args, where, "-skycal_id", "skycalRun.skycal_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-ff_id",    "fullForceRun.ff_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-diff_id",    "diffRun.diff_id", "==");
     PXOPT_LOOKUP_STR(stage,       config->args, "-stage", false, false);
     pxcamGetSearchArgs (config, where);
@@ -764,4 +974,10 @@
       query = pxDataGet("addtool_find_pendingexp_skycal.sql");
     }
+    if (strcmp(stage, "diff")==0) {
+      query = pxDataGet("addtool_find_pendingexp_diff.sql");
+    }
+    if (strcmp(stage, "fullforce")==0) {
+      query = pxDataGet("addtool_find_pendingexp_ff.sql");
+    }
 
 
@@ -790,4 +1006,15 @@
       psStringAppend(&query, " GROUP BY %s", "sky_id, stage_extra1");
     }
+    if (strcmp(stage, "diff") == 0) {
+      //this group by is needed to join against all the warps (to get camera)
+      psStringAppend(&query, " GROUP BY %s", "diff_id, stage_extra1");
+    }
+    if (strcmp(stage, "fullforce") == 0) {
+      //this group by is needed to join against all the warps (to get camera)
+      psStringAppend(&query, " GROUP BY %s", "ff_id, stage_extra1");
+    }
+
+
+
     // treat limit == 0 as "no limit"
     if (limit) {
@@ -994,4 +1221,9 @@
     } else if (strcmp (stage,"skycal") == 0) {
       query = pxDataGet("addtool_find_processedexp_skycal.sql");
+    } else if (strcmp (stage,"diff") == 0) {
+      query = pxDataGet("addtool_find_processedexp_diff.sql");
+    } else if (strcmp (stage,"fullforce") == 0) {
+      query = pxDataGet("addtool_find_processedexp_ff.sql");
+
     } else {
         psFree(where);
@@ -1112,4 +1344,10 @@
     if (strcmp(stage, "skycal") == 0) {
       query = pxDataGet("addtool_revertprocessedexp_skycal.sql");
+    }
+    if (strcmp(stage, "diff") == 0) {
+      query = pxDataGet("addtool_revertprocessedexp_diff.sql");
+    }
+    if (strcmp(stage, "fullforce") == 0) {
+      query = pxDataGet("addtool_revertprocessedexp_ff.sql");
     }
 
