Index: branches/eam_branches/ipp-20100823/ippTools/configure.ac
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/configure.ac	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/configure.ac	(revision 29515)
@@ -1,5 +1,5 @@
 AC_PREREQ(2.61)
 
-AC_INIT([ipptools], [1.1.63], [ipp-support@ifa.hawaii.edu])
+AC_INIT([ipptools], [1.1.65], [ipp-support@ifa.hawaii.edu])
 AC_CONFIG_SRCDIR([autogen.sh])
 
@@ -18,5 +18,5 @@
 PKG_CHECK_MODULES([PSLIB], [pslib >= 1.1.0])
 PKG_CHECK_MODULES([PSMODULES], [psmodules >= 1.1.0])
-PKG_CHECK_MODULES([IPPDB], [ippdb >= 1.1.63]) 
+PKG_CHECK_MODULES([IPPDB], [ippdb >= 1.1.65]) 
 PKG_CHECK_MODULES([PPSTAMP], [ppstamp >= 0.1.1]) 
 
Index: branches/eam_branches/ipp-20100823/ippTools/share/Makefile.am
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/Makefile.am	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/Makefile.am	(revision 29515)
@@ -61,4 +61,5 @@
 	chiptool_pendingimfile.sql \
 	chiptool_processedimfile.sql \
+	chiptool_revertcleanup.sql \
 	chiptool_revertprocessedimfile.sql \
 	chiptool_revertupdatedimfile.sql \
@@ -138,8 +139,10 @@
 	difftool_inputskyfile.sql \
 	difftool_listrun.sql \
+	difftool_listssrun.sql \
 	difftool_pendingcleanuprun.sql \
 	difftool_pendingcleanupskyfile.sql \
 	difftool_revertdiffskyfile_delete.sql \
 	difftool_revertdiffskyfile_updated.sql \
+	difftool_revertcleanup.sql \
 	difftool_setskyfiletoupdate.sql \
 	difftool_skyfile.sql \
@@ -274,4 +277,5 @@
 	pstamptool_revertreq.sql \
 	pstamptool_revertreq_deletejobs.sql \
+	pstamptool_stopdependentjob.sql \
 	pstamptool_updatejob.sql \
 	pxadmin_create_tables.sql \
@@ -356,4 +360,5 @@
 	warptool_revertwarped_delete.sql \
 	warptool_revertwarped_updated.sql \
+	warptool_revertcleanup.sql \
 	warptool_runstate.sql \
 	warptool_scmap.sql \
Index: branches/eam_branches/ipp-20100823/ippTools/share/addtool_find_cam_id.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/addtool_find_cam_id.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/addtool_find_cam_id.sql	(revision 29515)
@@ -2,4 +2,6 @@
     camRun.*
 FROM camRun
+JOIN camProcessedExp
+    USING(cam_id)
 JOIN chipRun
     USING(chip_id)
@@ -10,5 +12,5 @@
            FROM addRun
            JOIN camRun USING(cam_id)
-           JOIN chipRun USING(chip_id)
+	   JOIN chipRun USING(chip_id)
           ) as foo
      ON exp_id = added_exp_id
@@ -17,4 +19,5 @@
 WHERE
     camRun.state = 'full'
+    AND camProcessedExp.quality = 0
     AND added_exp_id IS NULL
     -- addtool adds checks on exposure being added to the dvodb previously
Index: branches/eam_branches/ipp-20100823/ippTools/share/addtool_find_cam_id_dvo.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/addtool_find_cam_id_dvo.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/addtool_find_cam_id_dvo.sql	(revision 29515)
@@ -1,6 +1,7 @@
 SELECT camRun.* FROM camRun
+JOIN camProcessedExp USING(cam_id)
 JOIN chipRun USING(chip_id)
 JOIN rawExp USING(exp_id)
-WHERE camRun.state = 'full'
+WHERE camRun.state = 'full' and camProcessedExp.quality = 0
     AND exp_id NOT IN (SELECT exp_id
        FROM addRun
Index: branches/eam_branches/ipp-20100823/ippTools/share/chiptool_listrun.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/chiptool_listrun.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/chiptool_listrun.sql	(revision 29515)
@@ -29,3 +29,3 @@
 LEFT JOIN camProcessedExp USING(cam_id)
 LEFT JOIN magicDSRun
-    ON stage_id = chip_id AND stage = 'chip' AND magicDSRun.re_place
+    ON stage_id = chip_id AND stage = 'chip' AND magicDSRun.re_place AND magicDSRun.state != 'drop'
Index: branches/eam_branches/ipp-20100823/ippTools/share/chiptool_processedimfile.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/chiptool_processedimfile.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/chiptool_processedimfile.sql	(revision 29515)
@@ -42,3 +42,3 @@
     AND chipProcessedImfile.class_id = rawImfile.class_id
 LEFT JOIN magicDSRun
-    ON stage_id = chip_id AND stage = 'chip' AND magicDSRun.re_place
+    ON stage_id = chip_id AND stage = 'chip' AND magicDSRun.re_place AND magicDSRun.state != 'drop'
Index: branches/eam_branches/ipp-20100823/ippTools/share/chiptool_revertcleanup.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/chiptool_revertcleanup.sql	(revision 29515)
+++ branches/eam_branches/ipp-20100823/ippTools/share/chiptool_revertcleanup.sql	(revision 29515)
@@ -0,0 +1,7 @@
+UPDATE chipProcessedImfile
+    JOIN chipRun using(chip_id,exp_id)
+SET chipProcessedImfile.data_state = 'full', 
+    chipRun.state = '%s'
+WHERE
+    chipRun.state = '%s'
+    AND chipProcessedImfile.data_state = '%s'
Index: branches/eam_branches/ipp-20100823/ippTools/share/difftool_listrun.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/difftool_listrun.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/difftool_listrun.sql	(revision 29515)
@@ -12,7 +12,5 @@
     diffRun.bothways,
     warp1,
-    stack1,
     warp2,
-    stack2,
     -- The following are only valid for warps
     -- XXX This needs to be more clever to handle diffs between stacks
@@ -27,4 +25,6 @@
     rawInput.exp_name AS exp_name_1,
     rawInput.exp_id AS exp_id_1,
+    rawInput.comment AS comment_1,
+    rawInput.dateobs AS dateobs_1,
     chipInput.chip_id AS chip_id_1,
     camInput.cam_id AS cam_id_1,
@@ -34,4 +34,6 @@
     rawTemplate.exp_name AS exp_name_2,
     rawTemplate.exp_id AS exp_id_2,
+    rawTemplate.comment AS comment_2,
+    rawTemplate.dateobs AS dateobs_2,
     chipTemplate.chip_id AS chip_id_2,
     camTemplate.cam_id AS cam_id_2,
Index: branches/eam_branches/ipp-20100823/ippTools/share/difftool_listssrun.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/difftool_listssrun.sql	(revision 29515)
+++ branches/eam_branches/ipp-20100823/ippTools/share/difftool_listssrun.sql	(revision 29515)
@@ -0,0 +1,20 @@
+SELECT DISTINCT
+    diffRun.diff_id,
+    diffRun.state,
+    diffRun.workdir,
+    diffRun.label,
+    diffRun.data_group,
+    diffRun.dist_group,
+    diffRun.note,
+    diffRun.tess_id
+FROM diffRun
+JOIN diffInputSkyfile USING(diff_id)
+JOIN stackRun AS stackInputRun
+    ON stackInputRun.stack_id = diffInputSkyfile.stack1
+JOIN stackSumSkyfile AS stackInput
+    ON stackInputRun.stack_id = stackInput.stack_id
+JOIN stackRun AS stackTemplateRun
+    ON stackTemplateRun.stack_id = diffInputSkyfile.stack2
+JOIN stackSumSkyfile AS stackTemplate
+    ON stackTemplateRun.stack_id = stackTemplate.stack_id
+WHERE diff_mode = 4
Index: branches/eam_branches/ipp-20100823/ippTools/share/difftool_revertcleanup.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/difftool_revertcleanup.sql	(revision 29515)
+++ branches/eam_branches/ipp-20100823/ippTools/share/difftool_revertcleanup.sql	(revision 29515)
@@ -0,0 +1,7 @@
+UPDATE diffSkyfile
+    JOIN diffRun using(diff_id)
+SET diffSkyfile.data_state = 'full', 
+    diffRun.state = '%s'
+WHERE
+    diffRun.state = '%s'
+    AND diffSkyfile.data_state = '%s'
Index: branches/eam_branches/ipp-20100823/ippTools/share/difftool_todiffskyfile.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/difftool_todiffskyfile.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/difftool_todiffskyfile.sql	(revision 29515)
@@ -13,5 +13,6 @@
     diffRun.bothways,
     diffRun.diff_mode,
-    diffSkyfile.path_base
+    diffSkyfile.path_base,
+    IFNULL(priority, 10000) AS priority
 FROM diffRun
 JOIN diffInputSkyfile USING(diff_id)
@@ -62,4 +63,5 @@
     ON diffInputSkyfile.diff_id = diffSkyfile.diff_id
     AND diffInputSkyfile.skycell_id = diffSkyfile.skycell_id
+LEFT JOIN Label ON Label.label = diffRun.label
 WHERE
 -- Ready to be processed
@@ -70,4 +72,5 @@
     AND diffSkyfile.data_state = 'update')
     )
+    AND (Label.active OR Label.active IS NULL)
 -- Ensure input warps are available
     AND (diffInputSkyfile.warp1 IS NULL
@@ -93,4 +96,2 @@
     AND stackTemplateSkyfile.quality = 0))
 
-
-
Index: branches/eam_branches/ipp-20100823/ippTools/share/disttool_pending_camera.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/disttool_pending_camera.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/disttool_pending_camera.sql	(revision 29515)
@@ -30,4 +30,4 @@
     AND distRun.stage = 'camera'
     AND distComponent.dist_id IS NULL
-    AND (((chipRun.magicked > 0) AND (camRun.magicked > 0)) OR distRun.no_magic)
+    AND (((clean OR (chipRun.magicked > 0)) AND (camRun.magicked > 0)) OR distRun.no_magic)
     AND (camRun.state = 'full' OR (distRun.clean AND camRun.state = 'cleaned'))
Index: branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_completed_runs.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_completed_runs.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_completed_runs.sql	(revision 29515)
@@ -1,4 +1,5 @@
 SELECT DISTINCT
     magic_ds_id,
+    magicked,
     re_place,
     label
@@ -7,7 +8,9 @@
 -- raw stage
 SELECT
-    magicDSRun.*
+    magicDSRun.*,
+    rawExp.magicked
     FROM magicDSRun
     JOIN rawImfile ON stage_id = rawImfile.exp_id
+    JOIN rawExp using(exp_id)
     LEFT JOIN magicDSFile
         ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
@@ -25,7 +28,9 @@
 -- chip stage
 SELECT
-    magicDSRun.*
+    magicDSRun.*,
+    chipRun.magicked
     FROM magicDSRun
-    JOIN chipProcessedImfile ON stage_id = chip_id
+    JOIN chipRun ON stage_id = chip_id
+    JOIN chipProcessedImfile USING(chip_id)
     LEFT JOIN magicDSFile
         ON magicDSFile.magic_ds_id = magicDSRun.magic_ds_id
@@ -44,7 +49,9 @@
 -- camera stage
 SELECT
-    magicDSRun.*
+    magicDSRun.*,
+    camRun.magicked
     FROM magicDSRun
-    JOIN camProcessedExp ON stage_id = camProcessedExp.cam_id
+    JOIN camRun ON stage_id = camRun.cam_id
+    JOIN camProcessedExp ON camRun.cam_id = camProcessedExp.cam_id
     LEFT JOIN magicDSFile
         ON magicDSFile.magic_ds_id = magicDSRun.magic_ds_id
@@ -61,7 +68,9 @@
 -- warp stage
 SELECT
-    magicDSRun.*
+    magicDSRun.*,
+    warpRun.magicked
     FROM magicDSRun
-    JOIN warpSkyfile on stage_id = warp_id
+    JOIN warpRun on stage_id = warp_id
+    JOIN warpSkyfile USING(warp_id)
     LEFT JOIN magicDSFile
         ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
@@ -81,10 +90,13 @@
 -- diff stage
 SELECT DISTINCT
-    magicDSRun.*
+    magicDSRun.*,
+    diffRun.magicked
     FROM magicDSRun
     JOIN magicRun USING (magic_id)
     JOIN magicInputSkyfile USING(magic_id)
+    JOIN diffRun
+        ON magicRun.diff_id = diffRun.diff_id
     JOIN diffSkyfile
-        ON magicRun.diff_id = diffSkyfile.diff_id
+        ON diffRun.diff_id = diffSkyfile.diff_id
         AND magicInputSkyfile.node = diffSkyfile.skycell_id
     LEFT JOIN magicDSFile
Index: branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_camera.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_camera.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_camera.sql	(revision 29515)
@@ -7,5 +7,7 @@
     camera,
     magicMask.uri AS streaks_uri,
+    magicMask.path_base AS streaks_path_base,
     CAST(NULL AS CHAR(255)) AS inv_streaks_uri,
+    CAST(NULL AS CHAR(255)) AS inv_streaks_path_base,
     stage,
     stage_id,
@@ -19,5 +21,6 @@
     recoveryroot,
     re_place,
-    remove
+    remove,
+    IFNULL(Label.priority, 10000) AS priority
 FROM magicDSRun
 JOIN magicMask USING (magic_id)
@@ -29,4 +32,5 @@
 LEFT JOIN magicDSFile
     ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
+LEFT JOIN Label ON magicDSRun.label = Label.label
 WHERE
     magicDSRun.state = 'new'
@@ -38,2 +42,3 @@
     AND camProcessedExp.quality = 0
     AND magicDSFile.component IS NULL
+    AND (Label.active OR Label.active IS NULL)
Index: branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_chip.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_chip.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_chip.sql	(revision 29515)
@@ -7,5 +7,7 @@
     camera,
     magicMask.uri AS streaks_uri,
+    magicMask.path_base AS streaks_path_base,
     CAST(NULL AS CHAR(255)) AS inv_streaks_uri,
+    CAST(NULL AS CHAR(255)) AS inv_streaks_path_base,
     stage,
     stage_id,
@@ -19,5 +21,6 @@
     recoveryroot,
     re_place,
-    remove
+    remove,
+    IFNULL(Label.priority, 10000) AS priority
 FROM magicDSRun
 JOIN magicMask USING (magic_id)
@@ -31,4 +34,6 @@
     ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
     AND magicDSFile.component = chipProcessedImfile.class_id
+LEFT JOIN Label
+    ON magicDSRun.label = Label.label
 WHERE
     magicDSRun.state = 'new'
@@ -38,2 +43,3 @@
     AND chipProcessedImfile.quality = 0
     AND magicDSFile.component IS NULL
+    AND (Label.active OR Label.active IS NULL)
Index: branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_diff.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_diff.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_diff.sql	(revision 29515)
@@ -7,5 +7,7 @@
     rawExp.camera,
     magicMask.uri AS streaks_uri,
+    magicMask.path_base AS streaks_path_base,
     CAST(NULL AS CHAR(255)) AS inv_streaks_uri,
+    CAST(NULL AS CHAR(255)) AS inv_streaks_path_base,
     stage,
     magicRun.diff_id AS stage_id,
@@ -20,5 +22,6 @@
     recoveryroot,
     re_place,
-    remove
+    remove,
+    IFNULL(Label.priority, 10000) AS priority
 FROM rawExp
 JOIN magicRun USING (exp_id)
@@ -33,4 +36,5 @@
     ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
     AND magicDSFile.component = diffSkyfile.skycell_id
+LEFT JOIN Label ON magicDSRun.label = Label.label
 WHERE
     magicDSRun.state = 'new'
@@ -40,4 +44,5 @@
     AND diffSkyfile.quality = 0
     AND magicDSFile.component IS NULL
+    AND (Label.active OR Label.active IS NULL)
 -- bothways diffSkyfiles
 UNION
@@ -49,5 +54,7 @@
     rawExp.camera,
     magicMask.uri AS streaks_uri,
+    magicMask.path_base AS streaks_path_base,
     (SELECT uri from magicMask where magic_id = inv_magic_id) AS inv_streaks_uri,
+    (SELECT path_base from magicMask where magic_id = inv_magic_id) AS inv_streaks_path_base,
     stage,
     magicRun.diff_id AS stage_id,
@@ -62,5 +69,6 @@
     recoveryroot,
     re_place,
-    remove
+    remove,
+    IFNULL(Label.priority, 10000) AS priority
 FROM rawExp
 JOIN magicRun USING (exp_id)
@@ -75,4 +83,5 @@
     ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
     AND magicDSFile.component = diffSkyfile.skycell_id
+LEFT JOIN Label ON magicDSRun.label = Label.label
 WHERE
     magicDSRun.state = 'new'
@@ -82,4 +91,5 @@
     AND diffSkyfile.quality = 0
     AND magicDSFile.component IS NULL
+    AND (Label.active OR Label.active IS NULL)
 ) AS magicDSRun
 -- we need the following so this query is compatible with the other stages
Index: branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_raw.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_raw.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_raw.sql	(revision 29515)
@@ -6,5 +6,7 @@
     rawExp.camera,
     magicMask.uri as streaks_uri,
+    magicMask.path_base as streaks_path_base,
     CAST(NULL AS CHAR(255)) AS inv_streaks_uri,
+    CAST(NULL AS CHAR(255)) AS inv_streaks_path_base,
     stage,
     stage_id,
@@ -20,5 +22,6 @@
     recoveryroot,
     re_place,
-    remove
+    remove,
+    10000 AS priority
 FROM magicDSRun
 JOIN magicMask USING (magic_id)
Index: branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_warp.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_warp.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magicdstool_todestreak_warp.sql	(revision 29515)
@@ -6,5 +6,7 @@
     camera,
     magicMask.uri as streaks_uri,
+    magicMask.path_base as streaks_path_base,
     CAST(NULL AS CHAR(255)) AS inv_streaks_uri,
+    CAST(NULL AS CHAR(255)) AS inv_streaks_path_base,
     stage,
     stage_id,
@@ -19,5 +21,6 @@
     recoveryroot,
     re_place,
-    remove
+    remove,
+    IFNULL(Label.priority, 10000) AS priority
 FROM magicDSRun
 JOIN magicMask USING (magic_id)
@@ -29,4 +32,5 @@
     ON magicDSRun.magic_ds_id = magicDSFile.magic_ds_id
     AND magicDSFile.component = warpSkyfile.skycell_id
+LEFT JOIN Label ON magicDSRun.label = Label.label
 WHERE
     magicDSRun.state = 'new'
@@ -36,2 +40,3 @@
     AND warpSkyfile.quality = 0
     AND magicDSFile.component IS NULL
+    AND (Label.active OR Label.active IS NULL)
Index: branches/eam_branches/ipp-20100823/ippTools/share/magictool_definebyquery_select.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magictool_definebyquery_select.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magictool_definebyquery_select.sql	(revision 29515)
@@ -15,7 +15,9 @@
     FROM diffRun
     JOIN diffInputSkyfile USING(diff_id)
+    JOIN diffSkyfile USING(diff_id, skycell_id)
     WHERE diffInputSkyfile.warp1 IS NOT NULL
         AND diffRun.exposure = 1
         AND diffRun.magicked = 0
+        AND diffSkyfile.quality = 0
     -- diff WHERE hook %s
     UNION
@@ -28,8 +30,10 @@
     FROM diffRun
     JOIN diffInputSkyfile USING(diff_id)
+    JOIN diffSkyfile USING(diff_id, skycell_id)
     WHERE diffInputSkyfile.warp2 IS NOT NULL
         AND diffRun.exposure = 1
         AND diffRun.bothways = 1
         AND diffRun.magicked = 0
+        AND diffSkyfile.quality = 0
     -- diff WHERE hook %s
     ) AS diffWarps
Index: branches/eam_branches/ipp-20100823/ippTools/share/magictool_revertnode.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magictool_revertnode.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magictool_revertnode.sql	(revision 29515)
@@ -3,2 +3,3 @@
 JOIN magicRun USING(magic_id) 
 WHERE magicNodeResult.fault != 0
+    AND magicRun.state = 'new'
Index: branches/eam_branches/ipp-20100823/ippTools/share/magictool_toprocess_inputs.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magictool_toprocess_inputs.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magictool_toprocess_inputs.sql	(revision 29515)
@@ -3,4 +3,6 @@
     magicRun.workdir,
     rawExp.exp_id,
+    rawExp.exp_name,
+    rawExp.workdir AS raw_workdir,
     rawExp.camera,
     -- convert magic_id into a boolean value (1 or 0)
Index: branches/eam_branches/ipp-20100823/ippTools/share/magictool_toprocess_tree.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magictool_toprocess_tree.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magictool_toprocess_tree.sql	(revision 29515)
@@ -3,4 +3,6 @@
     magicRun.workdir,
     rawExp.exp_id,
+    rawExp.exp_name,
+    rawExp.workdir AS raw_workdir,
     rawExp.camera,
     -- convert magic_id into a boolean value (1 or 0)
@@ -16,4 +18,5 @@
 WHERE
     magicRun.state = 'new'
+    AND (Label.active OR Label.active IS NULL)
 -- WHERE hook %s
 ORDER BY
Index: branches/eam_branches/ipp-20100823/ippTools/share/magictool_totree.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/magictool_totree.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/magictool_totree.sql	(revision 29515)
@@ -18,2 +18,3 @@
     AND magicTree.node IS NULL
     AND magicRun.fault = 0
+    AND (Label.active OR Label.active IS NULL)
Index: branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_revertdependent.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_revertdependent.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_revertdependent.sql	(revision 29515)
@@ -3,4 +3,5 @@
     JOIN pstampRequest USING(req_id)
 SET pstampDependent.fault = 0
+-- fault count hook %s
 WHERE pstampDependent.state = 'new'
     AND (pstampDependent.fault > 0)
Index: branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_revertjob.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_revertjob.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_revertjob.sql	(revision 29515)
@@ -2,4 +2,5 @@
     JOIN pstampRequest USING(req_id)
 SET pstampJob.fault = 0
+ -- clear fault count clause goes here %s
 WHERE  pstampRequest.state = 'run'
     AND pstampJob.state = 'run'
Index: branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_stopdependentjob.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_stopdependentjob.sql	(revision 29515)
+++ branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_stopdependentjob.sql	(revision 29515)
@@ -0,0 +1,9 @@
+-- stop jobs which have a faulted dependent
+UPDATE pstampDependent
+    JOIN pstampJob USING(dep_id)
+    JOIN pstampRequest USING(req_id)
+SET pstampJob.state = 'stop', 
+    pstampJob.fault = %d,
+    pstampDependent.fault = %d 
+WHERE pstampJob.state = 'run'
+    AND pstampDependent.state = 'new'
Index: branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_updatejob.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_updatejob.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/pstamptool_updatejob.sql	(revision 29515)
@@ -1,2 +1,4 @@
-UPDATE pstampJob LEFT JOIN pstampDependent USING(dep_id)
+UPDATE pstampJob 
+    JOIN pstampRequest USING(req_id) 
+    LEFT JOIN pstampDependent USING(dep_id)
 SET 
Index: branches/eam_branches/ipp-20100823/ippTools/share/pubtool_revert.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/pubtool_revert.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/pubtool_revert.sql	(revision 29515)
@@ -2,4 +2,5 @@
 USING publishDone, publishRun, publishClient
 WHERE publishDone.pub_id = publishRun.pub_id
+    AND publishRun.state = 'new'
     AND publishRun.client_id = publishClient.client_id
     AND publishClient.active = 1
Index: branches/eam_branches/ipp-20100823/ippTools/share/pxadmin_create_tables.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/pxadmin_create_tables.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/pxadmin_create_tables.sql	(revision 29515)
@@ -1221,9 +1221,7 @@
 CREATE TABLE magicInputSkyfile (
         magic_id BIGINT,
-        diff_id BIGINT,
         node VARCHAR(64),
-        PRIMARY KEY(magic_id, diff_id, node),
-        FOREIGN KEY(magic_id) REFERENCES magicRun(magic_id),
-        FOREIGN KEY(diff_id) REFERENCES diffRun(diff_id)
+        PRIMARY KEY(magic_id, node),
+        FOREIGN KEY(magic_id) REFERENCES magicRun(magic_id)
 ) ENGINE=innodb DEFAULT CHARSET=latin1;
 
@@ -1253,4 +1251,5 @@
         magic_id BIGINT,
         uri VARCHAR(255),
+        path_base VARCHAR(255),
         streaks INT,
         fault SMALLINT,
@@ -1441,10 +1440,13 @@
         imagedb    VARCHAR(64),
         rlabel     VARCHAR(64),
+        need_magic TINYINT,
         outdir     VARCHAR(255),
-        need_magic TINYINT,
+        fault      SMALLINT,
+        fault_count INT,
         PRIMARY KEY(dep_id),
         KEY(state),
         KEY(stage),
-        KEY(stage_id)
+        KEY(stage_id),
+        KEY(fault)
 ) ENGINE=innodb DEFAULT CHARSET=latin1;
 
@@ -1837,4 +1839,5 @@
     registered TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- time run was registered
     note VARCHAR(255),             -- note
+    magicked BIGINT NOT NULL DEFAULT 0, -- magic mask applied
     PRIMARY KEY(diff_phot_id),
     KEY(diff_id),
Index: branches/eam_branches/ipp-20100823/ippTools/share/stacktool_tosum.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/stacktool_tosum.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/stacktool_tosum.sql	(revision 29515)
@@ -7,12 +7,15 @@
     stackRun.label,
     stackRun.state,
-    stackSumSkyfile.path_base
+    stackSumSkyfile.path_base,
+    IFNULL(Label.priority, 10000) AS priority
 FROM stackRun
 JOIN stackInputSkyfile USING(stack_id)
 JOIN warpRun USING(warp_id)
 LEFT JOIN stackSumSkyfile USING(stack_id)
+LEFT JOIN Label ON Label.label = stackRun.label
 WHERE
     ((stackRun.state = 'new' AND stackSumSkyfile.stack_id IS NULL)
     OR (stackRun.state = 'update' AND stackSumSkyfile.fault = 0 AND stackSumSkyfile.quality = 0))
+    AND (Label.active OR Label.active IS NULL)
     -- WHERE hook %s
 GROUP BY stack_id
Index: branches/eam_branches/ipp-20100823/ippTools/share/warptool_revertcleanup.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/warptool_revertcleanup.sql	(revision 29515)
+++ branches/eam_branches/ipp-20100823/ippTools/share/warptool_revertcleanup.sql	(revision 29515)
@@ -0,0 +1,7 @@
+UPDATE warpSkyfile
+    JOIN warpRun using(warp_id)
+SET warpSkyfile.data_state = 'full', 
+    warpRun.state = '%s'
+WHERE
+    warpRun.state = '%s'
+    AND warpSkyfile.data_state = '%s'
Index: branches/eam_branches/ipp-20100823/ippTools/share/warptool_scmap.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/warptool_scmap.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/warptool_scmap.sql	(revision 29515)
@@ -7,6 +7,10 @@
     chipRun.state,
     chipProcessedImfile.data_state,
+    chipProcessedImfile.fault AS chip_fault,
     chipProcessedImfile.magicked,
-    rawImfile.magicked AS raw_magicked
+    rawImfile.magicked AS raw_magicked,
+    IFNULL(magicDSRun.magic_ds_id, 0) AS magic_ds_id,
+    IFNULL(magicDSRun.state, 0) AS dsRun_state,
+    IFNULL(magicDSFile.fault, 0) as dsFile_fault
 FROM warpRun
 JOIN warpSkyCellMap
@@ -26,4 +30,9 @@
     ON chipRun.exp_id = rawImfile.exp_id
     AND chipProcessedImfile.class_id = rawImfile.class_id
+LEFT JOIN magicDSRun
+    ON chipRun.chip_id = magicDSRun.stage_id AND magicDSRun.stage = 'chip'
+LEFT JOIN magicDSFile
+    ON magicDSFile.magic_ds_id = magicDSRun.magic_ds_id 
+        AND chipProcessedImfile.class_id = magicDSFile.component
 WHERE
     1
Index: branches/eam_branches/ipp-20100823/ippTools/share/warptool_towarped.sql
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/share/warptool_towarped.sql	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/share/warptool_towarped.sql	(revision 29515)
@@ -97,12 +97,10 @@
         AND warpSkyfile.fault = 0
         AND camRun.state = 'full'
-        AND chipProcessedImfile.data_state = 'full'
-        -- if warpSkyfile was magicked previously require inputs to be magicked
-        -- this blocks processing until all the chip inputs have been destreaked
-        AND (warpSkyfile.magicked = 0 OR chipProcessedImfile.magicked >= 0)
         AND (Label.active OR Label.active IS NULL)
         -- where hook 2 %s
     GROUP BY warp_id, skycell_id
-    HAVING COUNT(warpSkyCellMap.class_id) = COUNT(chipProcessedImfile.class_id)
+    -- if warpSkyfile was magicked previously require inputs to be magicked
+    -- this blocks processing until all the chip inputs have been destreaked
+    HAVING COUNT(warpSkyCellMap.class_id) = SUM(IF(chipProcessedImfile.data_state ='full' and (chipRun.magicked = 0 OR chipProcessedImfile.magicked > 0), 1, 0))
     -- limit hook 2 %s
     )
Index: branches/eam_branches/ipp-20100823/ippTools/src/addtool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/addtool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/addtool.c	(revision 29515)
@@ -493,9 +493,13 @@
 
     // since there is only one exp per 'new' set addRun.state = 'full'
-    if (!pxaddRunSetState(config, row->add_id, "full")) {
+    // but check to make sure there are no faults
+
+    if (!fault) {
+      if (!pxaddRunSetState(config, row->add_id, "full")) {
         psError(PS_ERR_UNKNOWN, false, "failed to change addRun.state for add_id: %" PRId64, row->add_id);
         psFree(row);
         psFree(pendingRow);
         return false;
+      }
     }
     psFree(row);
Index: branches/eam_branches/ipp-20100823/ippTools/src/bgtool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/bgtool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/bgtool.c	(revision 29515)
@@ -658,5 +658,5 @@
     }
 
-    if (!chipBackgroundImfileInsert(config->dbh, chip_bg_id, class_id, path_base, magicked, dtime_script,
+    if (!chipBackgroundImfileInsert(config->dbh, chip_bg_id, class_id, path_base, "full", magicked, dtime_script,
                                     hostname, quality, fault, ver_code, bg, bg_stdev, maskfrac_npix,
                                     maskfrac_static, maskfrac_dynamic, maskfrac_magic, maskfrac_advisory)) {
@@ -1497,5 +1497,5 @@
     }
 
-    if (!warpBackgroundSkyfileInsert(config->dbh, warp_bg_id, skycell_id, path_base, magicked, dtime_script,
+    if (!warpBackgroundSkyfileInsert(config->dbh, warp_bg_id, skycell_id, path_base, "full", magicked, dtime_script,
                                     hostname, quality, fault, ver_code, bg, bg_stdev, maskfrac_npix,
                                     maskfrac_static, maskfrac_dynamic, maskfrac_magic, maskfrac_advisory)) {
Index: branches/eam_branches/ipp-20100823/ippTools/src/chiptool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/chiptool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/chiptool.c	(revision 29515)
@@ -50,4 +50,5 @@
 static bool pendingcleanuprunMode(pxConfig *config);
 static bool pendingcleanupimfileMode(pxConfig *config);
+static bool revertcleanupMode(pxConfig *config);
 static bool donecleanupMode(pxConfig *config);
 static bool runMode(pxConfig *config);
@@ -94,4 +95,5 @@
         MODECASE(CHIPTOOL_MODE_PENDINGCLEANUPRUN,       pendingcleanuprunMode);
         MODECASE(CHIPTOOL_MODE_PENDINGCLEANUPIMFILE,    pendingcleanupimfileMode);
+        MODECASE(CHIPTOOL_MODE_REVERTCLEANUP,           revertcleanupMode);
         MODECASE(CHIPTOOL_MODE_DONECLEANUP,             donecleanupMode);
         MODECASE(CHIPTOOL_MODE_RUN,                     runMode);
@@ -859,9 +861,10 @@
     }
     psString query_update = pxDataGet("chiptool_revertupdatedimfile.sql");
-    if (!query) {
+    if (!query_update) {
         psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
         psFree(where);
         return false;
     }
+
 
     if (where && psListLength(where->list)) {
@@ -886,4 +889,59 @@
     }
     psFree(query_update);
+
+    return true;
+}
+static bool revertcleanupMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-chip_id", "chipRun.chip_id", "==");
+    pxAddLabelSearchArgs (config, where, "-label", "chipRun.label", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-data_group", "chipRun.data_group", "LIKE");
+    PXOPT_LOOKUP_STR(state, config->args, "-state", false, false);
+
+    char* newState = NULL;
+    if (!state) {
+        state = "error_cleaned";
+    }
+    if (!strcmp(state, "error_cleaned")) {
+        newState = "goto_cleaned";
+    } else if (!strcmp(state, "error_purged")) {
+        newState = "goto_purged";
+    } else if (!strcmp(state, "error_scrubbed")) {
+        newState = "goto_scrubbed";
+    } else {
+        psError(PXTOOLS_ERR_CONFIG, true, "-state must be either error_cleaned, error_purged, or error_scrubbed");
+        return false;
+    }
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+
+    psString query = pxDataGet("chiptool_revertcleanup.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        psFree(where);
+        return false;
+    }
+
+    if (where && psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+
+    psFree(where);
+
+    if (!p_psDBRunQueryF(config->dbh, query, newState, state, state)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
 
     return true;
Index: branches/eam_branches/ipp-20100823/ippTools/src/chiptool.h
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/chiptool.h	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/chiptool.h	(revision 29515)
@@ -42,4 +42,5 @@
     CHIPTOOL_MODE_PENDINGCLEANUPRUN,
     CHIPTOOL_MODE_PENDINGCLEANUPIMFILE,
+    CHIPTOOL_MODE_REVERTCLEANUP,
     CHIPTOOL_MODE_DONECLEANUP,
     CHIPTOOL_MODE_RUN,
Index: branches/eam_branches/ipp-20100823/ippTools/src/chiptoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/chiptoolConfig.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/chiptoolConfig.c	(revision 29515)
@@ -290,4 +290,12 @@
     psMetadataAddU64(donecleanupArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
 
+    // -revertcleanup
+    psMetadata *revertcleanupArgs = psMetadataAlloc();
+    psMetadataAddS64(revertcleanupArgs, PS_LIST_TAIL, "-chip_id", 0,            "search by chip ID", 0);
+    psMetadataAddStr(revertcleanupArgs,  PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by chipRun label (LIKE comparison)", NULL);
+    psMetadataAddStr(revertcleanupArgs,  PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by chipRun data_group (LIKE comparison)", NULL);
+    psMetadataAddStr(revertcleanupArgs, PS_LIST_TAIL, "-state", 0,             "search by current state", NULL);
+    psMetadataAddS16(revertcleanupArgs, PS_LIST_TAIL, "-fault",  0,            "search by fault code", 0);
+
     // -run
     psMetadata *runArgs = psMetadataAlloc();
@@ -371,4 +379,5 @@
     PXOPT_ADD_MODE("-pendingcleanupimfile", "show runs that need to be cleaned up", CHIPTOOL_MODE_PENDINGCLEANUPIMFILE, pendingcleanupimfileArgs);
     PXOPT_ADD_MODE("-donecleanup",          "show runs that have been cleaned",     CHIPTOOL_MODE_DONECLEANUP,          donecleanupArgs);
+    PXOPT_ADD_MODE("-revertcleanup",        "show runs that have been cleaned",     CHIPTOOL_MODE_REVERTCLEANUP,        revertcleanupArgs);
     PXOPT_ADD_MODE("-run",                  "show runs",                            CHIPTOOL_MODE_RUN,                  runArgs);
     PXOPT_ADD_MODE("-tocleanedimfile",      "set imfile state to cleaned",          CHIPTOOL_MODE_TOCLEANEDIMFILE,      tocleanedimfileArgs);
Index: branches/eam_branches/ipp-20100823/ippTools/src/difftool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/difftool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/difftool.c	(revision 29515)
@@ -48,4 +48,5 @@
 static bool pendingcleanuprunMode(pxConfig *config);
 static bool pendingcleanupskyfileMode(pxConfig *config);
+static bool revertcleanupMode(pxConfig *config);
 static bool donecleanupMode(pxConfig *config);
 static bool updatediffskyfileMode(pxConfig *config);
@@ -60,4 +61,5 @@
 static bool tofullskyfileMode(pxConfig *config);
 static bool listrunMode(pxConfig *config);
+static bool listssrunMode(pxConfig *config);
 static bool setskyfiletoupdateMode(pxConfig *config);
 
@@ -99,4 +101,5 @@
         MODECASE(DIFFTOOL_MODE_PENDINGCLEANUPRUN,     pendingcleanuprunMode);
         MODECASE(DIFFTOOL_MODE_PENDINGCLEANUPSKYFILE, pendingcleanupskyfileMode);
+        MODECASE(DIFFTOOL_MODE_REVERTCLEANUP,         revertcleanupMode);
         MODECASE(DIFFTOOL_MODE_DONECLEANUP,           donecleanupMode);
         MODECASE(DIFFTOOL_MODE_UPDATEDIFFSKYFILE,     updatediffskyfileMode);
@@ -108,4 +111,5 @@
         MODECASE(DIFFTOOL_MODE_TOFULLSKYFILE,         tofullskyfileMode);
         MODECASE(DIFFTOOL_MODE_LISTRUN,               listrunMode);
+        MODECASE(DIFFTOOL_MODE_LISTSSRUN,             listssrunMode);
         MODECASE(DIFFTOOL_MODE_SETSKYFILETOUPDATE,    setskyfiletoupdateMode);
 
@@ -478,4 +482,6 @@
     }
     psFree(where);
+
+     psStringAppend(&query, "\nORDER by priority DESC, diff_id");
 
     // treat limit == 0 as "no limit"
@@ -1236,4 +1242,5 @@
     PXOPT_COPY_F32(config->args, warp2Where,  "-good_frac", "warpSkyfile.good_frac", ">=");
     PXOPT_COPY_STR(config->args, stackWhere, "-stack_label", "stackRun.label", "==");
+    PXOPT_COPY_STR(config->args, stackWhere, "-stack_data_group", "stackRun.data_group", "==");
 
     PXOPT_LOOKUP_BOOL(bothways, config->args, "-bothways", false);
@@ -1609,4 +1616,5 @@
     PXOPT_COPY_S64(config->args, selectWhere, "-warp_id", "inputWarpRun.warp_id", "==");
     PXOPT_COPY_S64(config->args, selectWhere, "-exp_id", "inputRawExp.exp_id", "==");
+    PXOPT_COPY_S64(config->args, selectWhere, "-template_exp_id", "templateRawExp.exp_id", "==");
     PXOPT_COPY_STR(config->args, selectWhere, "-filter", "inputRawExp.filter", "==");
     PXOPT_COPY_STR(config->args, selectWhere, "-obs_mode", "inputRawExp.obs_mode", "==");
@@ -1647,5 +1655,6 @@
     PXOPT_COPY_F32(config->args,   selectWhere, "-sun_angle_min",      "inputRawExp.sun_angle",      ">=");
     PXOPT_COPY_F32(config->args,   selectWhere, "-sun_angle_max",      "inputRawExp.sun_angle",      "<");
-    PXOPT_COPY_STR(config->args,   selectWhere, "-comment",            "inputRawExp.comment",        "LIKE");
+    PXOPT_COPY_STR(config->args,   selectWhere, "-input_comment",      "inputRawExp.comment",        "LIKE");
+    PXOPT_COPY_STR(config->args,   selectWhere, "-template_comment",   "templateRawExp.comment",     "LIKE");
 
     PXOPT_LOOKUP_BOOL(not_bothways, config->args, "-not-bothways", false);
@@ -1680,4 +1689,5 @@
 
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
 
@@ -1839,4 +1849,7 @@
     long numGood = 0;                   // Number of good rows added
     for (long i = 0; i < results->n; i++) {
+        if (limit && numGood >= limit) {
+            break;
+        }
         psMetadata *row = results->data[i]; // Result row from query
 
@@ -2535,4 +2548,61 @@
 
 
+static bool revertcleanupMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-diff_id",    "diffSkyfile.diff_id", "==");
+    pxAddLabelSearchArgs (config, where, "-label",     "diffRun.label", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-data_group",   "diffRun.data_group", "LIKE");
+
+    PXOPT_LOOKUP_STR(state, config->args, "-state", false, false);
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+    if (!state) {
+        state = "error_cleaned";
+    }
+    char *newState = NULL;
+    if (!strcmp(state, "error_cleaned")) {
+        newState = "goto_cleaned";
+    } else if (!strcmp(state, "error_purged")) {
+        newState = "goto_purged";
+    } else if (!strcmp(state, "error_scrubbed")) {
+        newState = "goto_scrubbed";
+    } else {
+        psError(PXTOOLS_ERR_CONFIG, true, "-state must be either error_cleaned, error_purged, or error_scrubbed");
+        return false;
+    }
+
+    psString query = pxDataGet("difftool_revertcleanup.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    if (!p_psDBRunQueryF(config->dbh, query, newState, state, state)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    int numDeleted = psDBAffectedRows(config->dbh);
+
+    psLogMsg("difftool", PS_LOG_INFO, "Reverted %d diffRuns and diffSkyfiles", numDeleted);
+
+    return true;
+}
 static bool donecleanupMode(pxConfig *config)
 {
@@ -2877,11 +2947,12 @@
 
     psMetadata *where = psMetadataAlloc();
-    PXOPT_COPY_S64(config->args, where,  "-diff_id", "diffRun.diff_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-tess_id", "diffRun.tess_id", "==");
-    PXOPT_COPY_S64(config->args, where,  "-magicked", "diffRun.magicked", "==");
-    pxAddLabelSearchArgs (config, where, "-label", "diffRun.label", "LIKE");
+    PXOPT_COPY_S64(config->args, where,  "-diff_id",    "diffRun.diff_id",  "==");
+    PXOPT_COPY_STR(config->args, where,  "-tess_id",    "diffRun.tess_id",  "LIKE");
+    PXOPT_COPY_S64(config->args, where,  "-magicked",   "diffRun.magicked", "==");
+    PXOPT_COPY_STR(config->args, where,  "-state",      "diffRun.state",    "==");
+    pxAddLabelSearchArgs (config, where, "-label",      "diffRun.label", "LIKE");
     pxAddLabelSearchArgs (config, where, "-data_group", "diffRun.data_group", "LIKE");
     pxAddLabelSearchArgs (config, where, "-dist_group", "diffRun.dist_group", "LIKE");
-
+    
     PXOPT_LOOKUP_BOOL(template, config->args, "-template", false);
     if (!template) {
@@ -2905,5 +2976,8 @@
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
-
+    PXOPT_LOOKUP_S16(diff_mode, config->args, "-diff_mode", false, false);
+    if (diff_mode) {
+      PXOPT_COPY_S16(config->args, where, "-diff_mode", "diffRun.diff_mode", "==");
+    }
 
     psString where2 = NULL;
@@ -2983,4 +3057,121 @@
     return true;
 }
+static bool listssrunMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where,  "-diff_id",    "diffRun.diff_id",  "==");
+    PXOPT_COPY_S64(config->args, where,  "-stack_id",   "stackInput.stack_id",  "==");
+    PXOPT_COPY_S64(config->args, where,  "-template_stack_id",  "stackTemplate.stack_id",  "==");
+    PXOPT_COPY_STR(config->args, where,  "-tess_id",    "diffRun.tess_id",  "LIKE");
+    PXOPT_COPY_STR(config->args, where,  "-state",      "diffRun.state",    "==");
+    pxAddLabelSearchArgs (config, where, "-label",      "diffRun.label", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-data_group", "diffRun.data_group", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-dist_group", "diffRun.dist_group", "LIKE");
+
+    // lookup these so we don't compare to zero if they are not supplied
+    PXOPT_LOOKUP_F64(mjd_obs_begin, config->args, "-mjd_obs_begin", false, false);
+    PXOPT_LOOKUP_F64(mjd_obs_end, config->args, "-mjd_obs_end", false, false);
+    
+    PXOPT_LOOKUP_BOOL(template, config->args, "-template", false);
+
+    if (!template) {
+        if (mjd_obs_begin) {
+            PXOPT_COPY_F64(config->args, where, "-mjd_obs_begin", "stackInput.mjd_obs",  ">=");
+        }
+        if (mjd_obs_end) {
+            PXOPT_COPY_F64(config->args, where, "-mjd_obs_end",   "stackInput.mjd_obs",  "<=");
+        }
+        PXOPT_COPY_STR(config->args, where, "-filter",        "stackInputRun.filter", "LIKE");
+    } else {
+        if (mjd_obs_begin) {
+            PXOPT_COPY_F64(config->args, where, "-mjd_obs_begin", "stackTemplate.mjd_obs",  ">=");
+        }
+        if (mjd_obs_end) {
+            PXOPT_COPY_F64(config->args, where, "-mjd_obs_end",   "stackTemplate.mjd_obs",  "<=");
+        }
+        PXOPT_COPY_STR(config->args, where, "-filter",        "stackTemplateRun.filter", "LIKE");
+    }
+
+    PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(pstamp_order, config->args, "-pstamp_order", false);
+
+    psString where2 = NULL;
+    psString query = pxDataGet("difftool_listssrun.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    } else if (where2) {
+        psStringAppend(&query, " AND %s", where2);
+    } else if (!all) {
+        psError(PXTOOLS_ERR_CONFIG, true, "search parameters or -all are required");
+        return false;
+    }
+    psFree(where);
+
+    if (pstamp_order) {
+        if (template) {
+            psStringAppend(&query, " ORDER BY stackTemplate.stack_id, diff_id DESC");
+        } else {
+            psStringAppend(&query, " ORDER BY stackInput.stack_id, diff_id DESC");
+        }
+    }
+            
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psErrorCode err = psErrorCodeLast();
+        switch (err) {
+            case PS_ERR_DB_CLIENT:
+                psError(PXTOOLS_ERR_SYS, false, "database error");
+            case PS_ERR_DB_SERVER:
+                psError(PXTOOLS_ERR_PROG, false, "database error");
+            default:
+                psError(PXTOOLS_ERR_PROG, false, "unknown error");
+        }
+
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psTrace("difftool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (psArrayLength(output)) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "diffRun", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
+    }
+
+    psFree(output);
+
+    return true;
+}
 // a very specfic function to queue a cleaned warpSkyfile to be updated
 static bool setskyfiletoupdateMode(pxConfig *config)
Index: branches/eam_branches/ipp-20100823/ippTools/src/difftool.h
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/difftool.h	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/difftool.h	(revision 29515)
@@ -42,4 +42,5 @@
     DIFFTOOL_MODE_PENDINGCLEANUPRUN,
     DIFFTOOL_MODE_PENDINGCLEANUPSKYFILE,
+    DIFFTOOL_MODE_REVERTCLEANUP,
     DIFFTOOL_MODE_DONECLEANUP,
     DIFFTOOL_MODE_UPDATEDIFFSKYFILE,
@@ -51,4 +52,5 @@
     DIFFTOOL_MODE_TOFULLSKYFILE,
     DIFFTOOL_MODE_LISTRUN,
+    DIFFTOOL_MODE_LISTSSRUN,
     DIFFTOOL_MODE_SETSKYFILETOUPDATE,
 } difftoolMode;
Index: branches/eam_branches/ipp-20100823/ippTools/src/difftoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/difftoolConfig.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/difftoolConfig.c	(revision 29515)
@@ -173,5 +173,5 @@
     psMetadata *listrunArgs = psMetadataAlloc();
     psMetadataAddS64(listrunArgs, PS_LIST_TAIL,  "-diff_id", 0,           "search by diff ID", 0);
-    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-tess_id",  0,          "search by tessellation ID", NULL);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-tess_id",  0,          "search by tessellation ID (LIKE comparison)", NULL);
     psMetadataAddStr(listrunArgs , PS_LIST_TAIL, "-warp_id",  0,         "search by warp_id", NULL);
     psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-template",  0,        "apply exposure args to template of bothways diff", false);
@@ -184,4 +184,6 @@
     psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by diffRun data_group (LIKE comparison)", NULL);
     psMetadataAddStr(listrunArgs,  PS_LIST_TAIL, "-dist_group",  PS_META_DUPLICATE_OK, "search by diffRun dist_group (LIKE comparison)", NULL);
+    psMetadataAddS16(listrunArgs,  PS_LIST_TAIL, "-diff_mode", 0,        "search for diff_mode", 0);
+    psMetadataAddStr(listrunArgs, PS_LIST_TAIL,  "-state",  0,           "search by state", NULL);
     pxmagicAddArguments(listrunArgs);
     pxspaceAddArguments(listrunArgs);
@@ -192,4 +194,29 @@
     psMetadataAddU64(listrunArgs, PS_LIST_TAIL,  "-limit",  0,            "limit result set to N items", 0);
     psMetadataAddBool(listrunArgs, PS_LIST_TAIL, "-simple",  0,          "use the simple output format", false);
+
+
+    // -listssrun
+    psMetadata *listssrunArgs = psMetadataAlloc();
+    psMetadataAddS64(listssrunArgs, PS_LIST_TAIL,  "-diff_id", 0,          "search by diff ID", 0);
+    psMetadataAddStr(listssrunArgs, PS_LIST_TAIL,  "-tess_id",  0,         "search by tessellation ID (LIKE comparison)", NULL);
+    psMetadataAddS64(listssrunArgs , PS_LIST_TAIL, "-stack_id",  0,        "search by input stack_id", 0);
+    psMetadataAddS64(listssrunArgs , PS_LIST_TAIL, "-template_stack_id",0, "search by template stack_id", 0);
+    psMetadataAddBool(listssrunArgs, PS_LIST_TAIL, "-template",  0,        "apply stack selectors to template", false);
+    psMetadataAddF64(listssrunArgs, PS_LIST_TAIL,  "-mjd_obs_begin", 0,    "search by stack MJD-OBS (>=)", 0);
+    psMetadataAddF64(listssrunArgs, PS_LIST_TAIL,  "-mjd_obs_end", 0,      "search by stack MJD-OBS(<=)", 0);
+    psMetadataAddStr(listssrunArgs, PS_LIST_TAIL,  "-filter", 0,           "search by stack filter", NULL);
+    psMetadataAddStr(listssrunArgs,  PS_LIST_TAIL, "-label",  PS_META_DUPLICATE_OK, "search by diffRun label (LIKE comparison)", NULL);
+    psMetadataAddStr(listssrunArgs,  PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by diffRun data_group (LIKE comparison)", NULL);
+    psMetadataAddStr(listssrunArgs,  PS_LIST_TAIL, "-dist_group",  PS_META_DUPLICATE_OK, "search by diffRun dist_group (LIKE comparison)", NULL);
+    psMetadataAddS16(listssrunArgs,  PS_LIST_TAIL, "-diff_mode", 0,        "search for diff_mode", 0);
+    psMetadataAddStr(listssrunArgs, PS_LIST_TAIL,  "-state",  0,           "search by state", NULL);
+    pxmagicAddArguments(listssrunArgs);
+    pxspaceAddArguments(listssrunArgs);
+
+    psMetadataAddBool(listssrunArgs, PS_LIST_TAIL, "-pstamp_order",  0,    "order results for postage stamp server", false);
+
+    psMetadataAddBool(listssrunArgs, PS_LIST_TAIL, "-all",  0,             "search without arguments", false);
+    psMetadataAddU64(listssrunArgs, PS_LIST_TAIL,  "-limit",  0,            "limit result set to N items", 0);
+    psMetadataAddBool(listssrunArgs, PS_LIST_TAIL, "-simple",  0,          "use the simple output format", false);
 
 
@@ -226,4 +253,5 @@
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-comment", 0, "search by comment (LIKE)", NULL);
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-stack_label", 0, "search by stack label", NULL);
+    psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-stack_data_group", 0, "search by stack data_group", NULL);
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-warp_label", 0, "search by warp label", NULL);
     psMetadataAddStr(definewarpstackArgs, PS_LIST_TAIL, "-data_group", 0, "search by data_group", NULL);
@@ -247,4 +275,5 @@
     psMetadataAddS64(definewarpwarpArgs, PS_LIST_TAIL, "-exp_id", 0, "search by exposure ID", 0);
     psMetadataAddBool(definewarpwarpArgs, PS_LIST_TAIL, "-not-bothways",  0, "only do the single-direction subtraction?", false);
+    psMetadataAddS64(definewarpwarpArgs, PS_LIST_TAIL,  "-template_exp_id",  0,  "search by template exposure ID", 0);
     psMetadataAddStr(definewarpwarpArgs, PS_LIST_TAIL, "-filter", 0, "search by filter", NULL);
     psMetadataAddF32(definewarpwarpArgs, PS_LIST_TAIL, "-distance", 0, "limit distance between input and template (deg)", NAN);
@@ -292,7 +321,9 @@
     psMetadataAddF64(definewarpwarpArgs,  PS_LIST_TAIL, "-posang_min",         0, "search by min rotator position angle", NAN);
     psMetadataAddF64(definewarpwarpArgs,  PS_LIST_TAIL, "-posang_max",         0, "search by max rotator position angle", NAN);
-    psMetadataAddF32(definewarpwarpArgs,  PS_LIST_TAIL, "-sun_angle_min",         0, "search by min solar angle", NAN);
-    psMetadataAddF32(definewarpwarpArgs,  PS_LIST_TAIL, "-sun_angle_max",         0, "search by max solar angle", NAN);
-    psMetadataAddStr(definewarpwarpArgs,  PS_LIST_TAIL, "-comment",            0, "search by comment field (LIKE comparison)", NULL);
+    psMetadataAddF32(definewarpwarpArgs,  PS_LIST_TAIL, "-sun_angle_min",      0, "search by min solar angle", NAN);
+    psMetadataAddF32(definewarpwarpArgs,  PS_LIST_TAIL, "-sun_angle_max",      0, "search by max solar angle", NAN);
+    psMetadataAddStr(definewarpwarpArgs,  PS_LIST_TAIL, "-input_comment",      0, "search by comment field for input exposure(LIKE comparison)", NULL);
+    psMetadataAddStr(definewarpwarpArgs,  PS_LIST_TAIL, "-template_comment",   0, "search by comment field for template exposure(LIKE comparison)", NULL);
+    psMetadataAddU64(definewarpwarpArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
 
     // -definestackstack
@@ -362,4 +393,12 @@
     psMetadataAddU64(pendingcleanupskyfileArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
 
+    // -revertcleanup
+    psMetadata *revertcleanupArgs = psMetadataAlloc();
+    psMetadataAddS64(revertcleanupArgs, PS_LIST_TAIL, "-diff_id", 0,            "search by difftool ID", 0);
+    psMetadataAddStr(revertcleanupArgs, PS_LIST_TAIL, "-label",  PS_META_DUPLICATE_OK, "search by diffRun label", NULL);
+    psMetadataAddStr(revertcleanupArgs, PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by diffRun data_group", NULL);
+    psMetadataAddStr(revertcleanupArgs, PS_LIST_TAIL, "-state",  0,            "search by state", NULL);
+
+
     // -donecleanup
     psMetadata *donecleanupArgs = psMetadataAlloc();
@@ -427,5 +466,4 @@
     PXOPT_ADD_MODE("-advance",          "", DIFFTOOL_MODE_ADVANCE,           advanceArgs);
     PXOPT_ADD_MODE("-diffskyfile",      "", DIFFTOOL_MODE_DIFFSKYFILE,       diffskyfileArgs);
-    PXOPT_ADD_MODE("-listrun",          "", DIFFTOOL_MODE_LISTRUN,           listrunArgs);
     PXOPT_ADD_MODE("-revertdiffskyfile","", DIFFTOOL_MODE_REVERTDIFFSKYFILE, revertdiffskyfileArgs);
     PXOPT_ADD_MODE("-definepoprun",     "", DIFFTOOL_MODE_DEFINEPOPRUN,      definepoprunArgs);
@@ -433,6 +471,9 @@
     PXOPT_ADD_MODE("-definewarpwarp",   "", DIFFTOOL_MODE_DEFINEWARPWARP,    definewarpwarpArgs);
     PXOPT_ADD_MODE("-definestackstack", "", DIFFTOOL_MODE_DEFINESTACKSTACK,  definestackstackArgs);
+    PXOPT_ADD_MODE("-listrun",          "list diff runs", DIFFTOOL_MODE_LISTRUN,           listrunArgs);
+    PXOPT_ADD_MODE("-listssrun",        "list stack-stack diff runs", DIFFTOOL_MODE_LISTSSRUN,           listssrunArgs);
     PXOPT_ADD_MODE("-pendingcleanuprun",     "show runs that need to be cleaned up", DIFFTOOL_MODE_PENDINGCLEANUPRUN,    pendingcleanuprunArgs);
     PXOPT_ADD_MODE("-pendingcleanupskyfile", "show runs that need to be cleaned up", DIFFTOOL_MODE_PENDINGCLEANUPSKYFILE, pendingcleanupskyfileArgs);
+    PXOPT_ADD_MODE("-revertcleanup",           "revert cleanup runs with errors",     DIFFTOOL_MODE_REVERTCLEANUP,          revertcleanupArgs);
     PXOPT_ADD_MODE("-donecleanup",           "show runs that have been cleaned",     DIFFTOOL_MODE_DONECLEANUP,          donecleanupArgs);
     PXOPT_ADD_MODE("-updatediffskyfile",     "update fault code for a diffskyfile",  DIFFTOOL_MODE_UPDATEDIFFSKYFILE,          updatediffskyfileArgs);
Index: branches/eam_branches/ipp-20100823/ippTools/src/magicdstool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/magicdstool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/magicdstool.c	(revision 29515)
@@ -637,4 +637,6 @@
     psFree(where);
 
+    psStringAppend(&query, "\nORDER BY priority DESC, magic_ds_id");
+
     // treat limit == 0 as "no limit"
     if (limit) {
@@ -933,4 +935,11 @@
     }
 
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
     if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
@@ -950,22 +959,29 @@
         return true;
     }
-    if (!psDBTransaction(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
     for (long i = 0; i < psArrayLength(output); i++) {
         psMetadata *row = output->data[i];
 
         psS64 magic_ds_id = psMetadataLookupS64(NULL, row, "magic_ds_id");
+        psS64 magicked =  psMetadataLookupS64(NULL, row, "magicked");
+        if (!psDBTransaction(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            return false;
+        }
 
         // if re_place, set stageRun.magicked
         bool setmagicked = psMetadataLookupBool(NULL, row, "re_place");
-        if (setmagicked && !setRunMagicked(config, magic_ds_id)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to change stageRun.magicked for magic_ds_id: %" PRId64,
-                magic_ds_id);
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
+        if (setmagicked) {
+            if (magicked <= 0) { 
+                if (!setRunMagicked(config, magic_ds_id)) {
+                    psError(PS_ERR_UNKNOWN, false, "failed to change stageRun.magicked for magic_ds_id: %" PRId64,
+                        magic_ds_id);
+                    if (!psDBRollback(config->dbh)) {
+                        psError(PS_ERR_UNKNOWN, false, "database error");
+                    }
+                    return false;
+                }
+            } else {
+                fprintf(stderr, "run is already marked as destreaked for magic_ds_id %" PRId64 "\n", magic_ds_id);
             }
-            return false;
         }
 
@@ -980,8 +996,8 @@
             return false;
         }
-    }
-    if (!psDBCommit(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
+        if (!psDBCommit(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            return false;
+        }
     }
 
Index: branches/eam_branches/ipp-20100823/ippTools/src/magictool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/magictool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/magictool.c	(revision 29515)
@@ -50,5 +50,5 @@
 static bool exposureMode(pxConfig *config);
 
-static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state);
+static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state, psString setString);
 static bool parseAndInsertNodeDeps(pxConfig *config, psS64 magic_id, const char *filename);
 
@@ -131,5 +131,5 @@
 
     psMetadata *queryWhere = psMetadataAlloc(); // WHERE conditions for everything else
-    PXOPT_COPY_S64(config->args, queryWhere, "-exp_id", "exp_id", "==");
+    PXOPT_COPY_S64(config->args, queryWhere, "-exp_id", "rawExp.exp_id", "==");
     PXOPT_COPY_STR(config->args, queryWhere, "-select_filter", "rawExp.filter", "==");
 
@@ -394,9 +394,20 @@
     // required
     PXOPT_LOOKUP_S64(magic_id, config->args, "-magic_id", true, false);
-    PXOPT_LOOKUP_STR(state, config->args, "-state", true, false);
+    PXOPT_LOOKUP_STR(state, config->args, "-set_state", true, false);
+    PXOPT_LOOKUP_S16(fault, config->args, "-set_fault", false, false);
+    PXOPT_LOOKUP_STR(note, config->args, "-set_note", false, false);
+    PXOPT_LOOKUP_BOOL(clearfault, config->args, "-clearfault", false);
+
+    psString setString = NULL;
+    if (fault || clearfault) {
+        psStringAppend(&setString, ", fault = %d", fault);
+    }
+    if (note) {
+        psStringAppend(&setString, ", note = '%s'", note);
+    }
 
     if (state) {
         // set detRun.state to state
-        return setmagicRunState(config, magic_id, state);
+        return setmagicRunState(config, magic_id, state, setString);
     }
 
@@ -612,5 +623,5 @@
     PXOPT_COPY_STR(config->args, where, "-label", "label", "==");
 
-    psString query = psStringCopy("UPDATE magicRun SET fault = 0, state = 'new' WHERE fault != 0");
+    psString query = psStringCopy("UPDATE magicRun SET fault = 0 WHERE state = 'new' AND fault != 0");
 
     if (psListLength(where->list)) {
@@ -1171,5 +1182,6 @@
 
     // optional
-    PXOPT_LOOKUP_STR(uri, config->args, "-uri", false, false);
+//    PXOPT_LOOKUP_STR(uri, config->args, "-uri", false, false);
+    PXOPT_LOOKUP_STR(path_base, config->args, "-path_base", true, false);
     PXOPT_LOOKUP_S32(streaks, config->args, "-streaks", false, false);
 
@@ -1184,5 +1196,6 @@
     if (!magicMaskInsert(config->dbh,
                          magic_id,
-                         uri,
+                         NULL,
+                         path_base,
                          streaks,
                          fault
@@ -1364,5 +1377,5 @@
 }
 
-static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state)
+static bool setmagicRunState(pxConfig *config, psS64 magic_id, const char *state, psString setString)
 {
     PS_ASSERT_PTR_NON_NULL(state, false);
@@ -1380,7 +1393,13 @@
         return false;
     }
-
-    char *query = "UPDATE magicRun SET state = '%s' WHERE magic_id = %" PRId64;
-    if (!p_psDBRunQueryF(config->dbh, query, state, magic_id)) {
+    psString query = NULL;
+    psStringAppend(&query, "UPDATE magicRun SET state = '%s'", state);
+    if (setString) {
+        psStringAppend(&query, setString);
+    }
+    psStringAppend(&query, " WHERE magic_id = %" PRId64, magic_id);;
+
+//    char *query = "UPDATE magicRun SET state = '%s' WHERE magic_id = %" PRId64;
+    if (!p_psDBRunQuery(config->dbh, query)) {
         psError(PS_ERR_UNKNOWN, false,
                 "failed to change state for magic_id %" PRId64, magic_id);
Index: branches/eam_branches/ipp-20100823/ippTools/src/magictoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/magictoolConfig.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/magictoolConfig.c	(revision 29515)
@@ -79,5 +79,8 @@
     psMetadata *updaterunArgs = psMetadataAlloc();
     psMetadataAddS64(updaterunArgs, PS_LIST_TAIL, "-magic_id", 0, "define magictool ID (required)", 0);
-    psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-state", 0, "set state (required)", NULL);
+    psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_state", 0, "set state (required)", NULL);
+    psMetadataAddS16(updaterunArgs, PS_LIST_TAIL, "-set_fault", 0, "set fault code", 0);
+    psMetadataAddStr(updaterunArgs, PS_LIST_TAIL, "-set_note",  0, "define note", NULL);
+    psMetadataAddBool(updaterunArgs, PS_LIST_TAIL, "-clearfault",  0, "set fault to zero", NULL);
 
     // -addinputskyfile
@@ -149,5 +152,5 @@
     psMetadata *addmaskArgs = psMetadataAlloc();
     psMetadataAddS64(addmaskArgs, PS_LIST_TAIL, "-magic_id", 0, "define magictool ID (required)", 0);
-    psMetadataAddStr(addmaskArgs, PS_LIST_TAIL, "-uri", 0, "define URI", NULL);
+    psMetadataAddStr(addmaskArgs, PS_LIST_TAIL, "-path_base", 0, "define path_base (required)", NULL);
     psMetadataAddS32(addmaskArgs, PS_LIST_TAIL, "-streaks", 0, "define number of streaks", 0);
     psMetadataAddS16(addmaskArgs, PS_LIST_TAIL, "-fault", 0, "set fault code", 0);
Index: branches/eam_branches/ipp-20100823/ippTools/src/pstamptool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/pstamptool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/pstamptool.c	(revision 29515)
@@ -46,4 +46,5 @@
 static bool pendingjobMode(pxConfig *config);
 static bool updatejobMode(pxConfig *config);
+static bool stopdependentjobMode(pxConfig *config);
 static bool revertjobMode(pxConfig *config);
 static bool addprojectMode(pxConfig *config);
@@ -63,4 +64,7 @@
     break;
 
+// XXX make this a configurable parameter
+#define PSTAMP_MAX_JOB_FAULTS 5
+#define PSTAMP_MAX_DEP_FAULTS 5
 
 int main(int argc, char **argv)
@@ -89,4 +93,5 @@
         MODECASE(PSTAMPTOOL_MODE_PENDINGJOB, pendingjobMode);
         MODECASE(PSTAMPTOOL_MODE_UPDATEJOB, updatejobMode);
+        MODECASE(PSTAMPTOOL_MODE_STOPDEPENDENTJOB, stopdependentjobMode);
         MODECASE(PSTAMPTOOL_MODE_REVERTJOB, revertjobMode);
         MODECASE(PSTAMPTOOL_MODE_ADDPROJECT, addprojectMode);
@@ -715,5 +720,6 @@
             outputBase,
             options,
-            dep_id
+            dep_id,
+            0   // fault_count
             )) {
         psError(PS_ERR_UNKNOWN, false, "database error");
@@ -877,7 +883,8 @@
     PXOPT_LOOKUP_S64(req_id,    config->args, "-req_id", false, false);
     PXOPT_LOOKUP_S64(dep_id,    config->args, "-dep_id", false, false);
-
-    if (!job_id && !req_id && !dep_id) {
-        psError(PS_ERR_UNKNOWN, true, "at least one of -job_id -req_id or -dep_id is required");
+    PXOPT_LOOKUP_S32(fault_count, config->args, "-fault_count",  false, false);
+
+    if (!job_id && !req_id && !dep_id && !fault_count) {
+        psError(PS_ERR_UNKNOWN, true, "at least one of -job_id -req_id -dep_id or -fault_count is required");
         return false;
     }
@@ -898,4 +905,6 @@
     PXOPT_COPY_S32(config->args, where, "-fault",  "pstampJob.fault", "==");
     PXOPT_COPY_STR(config->args, where, "-state",  "pstampJob.state", "==");
+    PXOPT_COPY_S32(config->args, where, "-fault_count", "pstampJob.fault_count", ">=");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
 
     psString query = pxDataGet("pstamptool_updatejob.sql");
@@ -909,4 +918,5 @@
         psStringAppend(&query, "\n %c pstampJob.fault = %d", c, fault);
         c = ',';
+        psStringAppend(&query, ", pstampJob.fault_count = pstampJob.fault_count+ 1");
     }
     
@@ -925,4 +935,49 @@
     psU64 affected = psDBAffectedRows(config->dbh);
     psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampJobs", affected);
+
+    return true;
+}
+// Terminate jobs which have dependents setting both the pstampDependent and pstampJob.fault
+static bool stopdependentjobMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_S32(fault,  config->args, "-set_fault",  true, false);
+
+    psMetadata *where = psMetadataAlloc();
+
+    PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+    PXOPT_COPY_S32(config->args, where, "-fault",  "pstampDependent.fault", "==");
+    pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
+    // if (fault_count) {
+        PXOPT_COPY_S32(config->args, where, "-fault_count", "pstampDependent.fault_count", ">=");
+    // }
+
+    // XXX: How about selecting by pstampRequest.label? No. That is too dangerous by itself.
+
+    psString query = pxDataGet("pstamptool_stopdependentjob.sql");
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    } else {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+    psFree(where);
+
+    if (!p_psDBRunQueryF(config->dbh, query, fault, fault)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psU64 affected = psDBAffectedRows(config->dbh);
+    psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampJobs and pstampDependents", affected);
 
     return true;
@@ -941,5 +996,10 @@
     pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
 
+    PXOPT_LOOKUP_BOOL(clear_fault_count, config->args, "-clear_fault_count", false);
+
     PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
+
+    // XXX: we don't actually use -limit. It doesn't work for UPDATE
+    // it's an allowed arg because add_poll_args adds it
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
     PXOPT_LOOKUP_S16(fault, config->args, "-fault",  false, false);
@@ -947,5 +1007,5 @@
     // By default only revert faults < PSTAMP_FIRST_ERROR_CODE which are our "ipp exit codes"
     // codes larger than that are the pstamp request interface.
-    // Don't fault those unless -fault waa provided
+    // Don't fault those unless -fault was explicitly provided
     psString faultClause = psStringCopy("");
     if (!fault) {
@@ -966,5 +1026,15 @@
     psFree(where);
 
-    if (!p_psDBRunQueryF(config->dbh, query, faultClause)) {
+    // don't keep reverting once the number of faults reaches some value unless 
+    // a parameter asking us to clear that count is provided
+    psString faultCountClause = NULL;
+    if (clear_fault_count) {
+        psStringAppend(&faultCountClause, "\n, pstampJob.fault_count = 0");
+    } else {
+        psStringAppend(&query, " AND pstampJob.fault_count < %d", PSTAMP_MAX_JOB_FAULTS);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, faultCountClause, faultClause)) {
+        psFree(faultCountClause);
         psFree(faultClause);
         psFree(query);
@@ -974,4 +1044,6 @@
 
     psFree(faultClause);
+    psFree(faultCountClause);
+    psFree(query);
 
     return true;
@@ -1178,5 +1250,6 @@
         need_magic,
         outdir,
-        0               // fault
+        0,              // fault
+        0               // fault_count
         )) {
         if (!psDBRollback(config->dbh)) {
@@ -1300,4 +1373,5 @@
         psStringAppend(&query, "%s fault = %d", needComma ? ", " : "", fault);
         needComma = true;
+        psStringAppend(&query, ", pstampDependent.fault_count = pstampDependent.fault_count + 1");
     }
     psStringAppend(&query, " WHERE dep_id = %" PRId64, dep_id);
@@ -1325,5 +1399,12 @@
     PXOPT_COPY_S64(config->args, where, "-fault", "pstampDependent.fault", "==");
     PXOPT_COPY_S64(config->args, where, "-dep_id", "dep_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-job_id", "job_id", "==");
+    PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
     pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "==");
+    PXOPT_LOOKUP_BOOL(clear_fault_count, config->args, "-clear_fault_count", false);
+
+    // XXX: we don't actually use -limit. It doesn't work for UPDATE
+    // it's an allowed arg because add_poll_args adds it
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
 
     if (!psListLength(where->list)) {
@@ -1352,5 +1433,15 @@
     }
 
-    if (!p_psDBRunQuery(config->dbh, query)) {
+    // don't keep reverting once the number of faults reaches some value unless 
+    // a parameter asking us to clear that count is provided
+    psString faultCountClause = NULL;
+    if (clear_fault_count) {
+        psStringAppend(&faultCountClause, "\n, pstampDependent.fault_count = 0");
+    } else {
+        psStringAppend(&faultCountClause, " ");
+        psStringAppend(&query, " AND pstampDependent.fault_count < %d", PSTAMP_MAX_DEP_FAULTS);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, faultCountClause)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
Index: branches/eam_branches/ipp-20100823/ippTools/src/pstamptool.h
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/pstamptool.h	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/pstamptool.h	(revision 29515)
@@ -38,4 +38,5 @@
     PSTAMPTOOL_MODE_LISTJOB,
     PSTAMPTOOL_MODE_PENDINGJOB,
+    PSTAMPTOOL_MODE_STOPDEPENDENTJOB,
     PSTAMPTOOL_MODE_JOBRESULT,
     PSTAMPTOOL_MODE_UPDATEJOB,
Index: branches/eam_branches/ipp-20100823/ippTools/src/pstamptoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/pstamptoolConfig.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/pstamptoolConfig.c	(revision 29515)
@@ -167,6 +167,20 @@
     psMetadataAddStr(updatejobArgs, PS_LIST_TAIL, "-state", 0,             "current state of jobs to update", 0);
     psMetadataAddS16(updatejobArgs, PS_LIST_TAIL, "-fault", 0,             "current value for job fault", 0);
+    psMetadataAddStr(updatejobArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by pstampJob label (LIKE comparision)", NULL);
+    psMetadataAddS32(updatejobArgs, PS_LIST_TAIL, "-fault_count", 0,       "select by fault_count (>=)", 0);
     psMetadataAddStr(updatejobArgs, PS_LIST_TAIL, "-set_state", 0,            "new state", NULL);
     psMetadataAddS16(updatejobArgs, PS_LIST_TAIL, "-set_fault", 0,            "new result", 0);
+    psMetadataAddU64(updatejobArgs, PS_LIST_TAIL, "-limit", 0,      "not used", 0);
+
+    // -stopdependentjob
+    psMetadata *stopdependentjobArgs = psMetadataAlloc();
+    psMetadataAddS64(stopdependentjobArgs, PS_LIST_TAIL,  "-req_id", 0,       "req_id of jobs to update", 0);
+    psMetadataAddS64(stopdependentjobArgs, PS_LIST_TAIL,  "-job_id", 0,       "job_id of jobs to update", 0);
+    psMetadataAddS64(stopdependentjobArgs, PS_LIST_TAIL,  "-dep_id", 0,       "dep_id of jobs to update", 0);
+    psMetadataAddS16(stopdependentjobArgs, PS_LIST_TAIL,  "-fault", 0,        "current value for dependent fault", 0);
+    psMetadataAddS32(stopdependentjobArgs, PS_LIST_TAIL,  "-fault_count", 0,   "select by fault_count (>=)", 0);
+    psMetadataAddS16(stopdependentjobArgs, PS_LIST_TAIL,  "-set_fault", 0,    "new fault value for job and dependent (required)", 0);
+    psMetadataAddStr(stopdependentjobArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by pstampJob label (LIKE comparision)", NULL);
+    psMetadataAddU64(stopdependentjobArgs, PS_LIST_TAIL, "-limit", 0,      "not used", 0);
 
     // -revertjob
@@ -177,6 +191,7 @@
     psMetadataAddS16(revertjobArgs, PS_LIST_TAIL, "-fault",  0,     "fault to revert", 0);
     psMetadataAddStr(revertjobArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK, "search by pstampRequest label (LIKE comparision)", NULL);
+    psMetadataAddBool(revertjobArgs, PS_LIST_TAIL, "-clear_fault_count", 0,       "clear job fault count", false);
     psMetadataAddBool(revertjobArgs, PS_LIST_TAIL, "-all", 0,       "revert all faulted jobs", false);
-    psMetadataAddU64(revertjobArgs, PS_LIST_TAIL, "-limit", 0,      "limit result set to N items", 0);
+    psMetadataAddU64(revertjobArgs, PS_LIST_TAIL, "-limit", 0,      "not used", 0);
 
     // -getdependent
@@ -201,7 +216,11 @@
     // -revertdependent
     psMetadata *revertdependentArgs = psMetadataAlloc();
-    psMetadataAddS64(revertdependentArgs, PS_LIST_TAIL, "-dep_id", 0, "define id for dependent", 0);
+    psMetadataAddS64(revertdependentArgs, PS_LIST_TAIL, "-dep_id", 0, "search by dep_id for dependent", 0);
+    psMetadataAddS64(revertdependentArgs, PS_LIST_TAIL, "-job_id", 0, "search by job_ idfor dependent", 0);
+    psMetadataAddS64(revertdependentArgs, PS_LIST_TAIL, "-req_id", 0, "search by req_id for dependent", 0);
     psMetadataAddStr(revertdependentArgs, PS_LIST_TAIL, "-label", PS_META_DUPLICATE_OK,   "define label for dependent ", NULL);
-    psMetadataAddS16(revertdependentArgs, PS_LIST_TAIL, "-fault",  0,   "define fault", 0);
+    psMetadataAddS16(revertdependentArgs, PS_LIST_TAIL, "-fault",  0, "search by dependent fault", 0);
+    psMetadataAddBool(revertdependentArgs, PS_LIST_TAIL, "-clear_fault_count", 0,       "clear job fault count", false);
+    psMetadataAddU64(revertdependentArgs, PS_LIST_TAIL, "-limit", 0,  "limit result set to N items", 0);
 
     // -pendingdependent
@@ -262,4 +281,5 @@
     PXOPT_ADD_MODE("-pendingjob",      "", PSTAMPTOOL_MODE_PENDINGJOB,   pendingjobArgs);
     PXOPT_ADD_MODE("-updatejob",       "", PSTAMPTOOL_MODE_UPDATEJOB,    updatejobArgs);
+    PXOPT_ADD_MODE("-stopdependentjob", "", PSTAMPTOOL_MODE_STOPDEPENDENTJOB,  stopdependentjobArgs);
     PXOPT_ADD_MODE("-revertjob",       "", PSTAMPTOOL_MODE_REVERTJOB,    revertjobArgs);
 
Index: branches/eam_branches/ipp-20100823/ippTools/src/pubtool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/pubtool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/pubtool.c	(revision 29515)
@@ -340,5 +340,5 @@
     }
 
-    if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause)) {
+    if (!p_psDBRunQueryF(config->dbh, query, whereClause, whereClause, whereClause)) {
         psError(PS_ERR_UNKNOWN, false, "Database error");
         psFree(whereClause);
Index: branches/eam_branches/ipp-20100823/ippTools/src/stacktool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/stacktool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/stacktool.c	(revision 29515)
@@ -901,4 +901,6 @@
     psFree(where);
 
+    psStringAppend(&query, "\nORDER by priority DESC, stack_id");
+
     // treat limit == 0 as "no limit"
     if (limit) {
@@ -982,4 +984,5 @@
     PXOPT_LOOKUP_STR(hostname, config->args, "-hostname", false, false);
     PXOPT_LOOKUP_F32(good_frac, config->args, "-good_frac", false, false);
+    PXOPT_LOOKUP_F64(mjd_obs, config->args, "-mjd_obs", false, false);
 
     PXOPT_LOOKUP_STR(ver_pslib, config->args, "-ver_pslib", false, false);
@@ -1047,4 +1050,5 @@
                                hostname,
                                good_frac,
+                               mjd_obs,
                                fault,
                                software_ver,
@@ -1094,5 +1098,5 @@
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_S64(config->args, where, "-stack_id", "stackSumSkyfile.stack_id", "==");
-    PXOPT_COPY_STR(config->args, where, "-tess_id", "stackRun.tess_id", "==");
+    PXOPT_COPY_STR(config->args, where, "-tess_id", "stackRun.tess_id", "LIKE");
     PXOPT_COPY_STR(config->args, where, "-skycell_id", "stackRun.skycell_id", "==");
     PXOPT_COPY_STR(config->args, where, "-filter", "stackRun.filter", "LIKE");
@@ -1100,4 +1104,7 @@
     PXOPT_COPY_STR(config->args, where, "-data_group", "stackRun.data_group", "LIKE");
     PXOPT_COPY_S16(config->args, where, "-fault", "stackSumSkyfile.fault", "==");
+    PXOPT_COPY_F64(config->args, where, "-mjd_obs_begin", "stackSumSkyfile.mjd_obs", ">=");
+    PXOPT_COPY_F64(config->args, where, "-mjd_obs_end", "stackSumSkyfile.mjd_obs", "<=");
+
 
 //  The following three selectors are incompatible with the sql so omit them
Index: branches/eam_branches/ipp-20100823/ippTools/src/stacktoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/stacktoolConfig.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/stacktoolConfig.c	(revision 29515)
@@ -172,4 +172,5 @@
     psMetadataAddStr(addsumskyfileArgs, PS_LIST_TAIL, "-hostname", 0,            "define hostname", 0);
     psMetadataAddF32(addsumskyfileArgs, PS_LIST_TAIL, "-good_frac",  0,            "define %% of good pixels", NAN);
+    psMetadataAddF64(addsumskyfileArgs, PS_LIST_TAIL, "-mjd_obs",  0,            "define mjd_obs (average mjd_obs of inputs)", NAN);
     psMetadataAddS16(addsumskyfileArgs, PS_LIST_TAIL, "-fault",  0,            "set fault code", 0);
     psMetadataAddS16(addsumskyfileArgs, PS_LIST_TAIL, "-quality",  0,            "set quality", 0);
@@ -185,5 +186,5 @@
     psMetadata *sumskyfileArgs= psMetadataAlloc();
     psMetadataAddS64(sumskyfileArgs, PS_LIST_TAIL, "-stack_id", 0,            "search by stack ID", 0);
-    psMetadataAddStr(sumskyfileArgs, PS_LIST_TAIL, "-tess_id", 0,            "search by tess ID", 0);
+    psMetadataAddStr(sumskyfileArgs, PS_LIST_TAIL, "-tess_id", 0,            "search by tess ID (LIKE comparison)", 0);
     psMetadataAddStr(sumskyfileArgs, PS_LIST_TAIL, "-skycell_id", 0,         "search by skycell ID", 0);
 #ifdef notdef
@@ -196,4 +197,6 @@
     psMetadataAddStr(sumskyfileArgs, PS_LIST_TAIL, "-data_group", 0,        "search by stackRun.data_group (LIKE comparison)", NULL);
     psMetadataAddStr(sumskyfileArgs, PS_LIST_TAIL, "-filter", 0,            "search by filter (LIKE comparison)", NULL);
+    psMetadataAddF64(sumskyfileArgs, PS_LIST_TAIL, "-mjd_obs_begin",  0,      "search by mjd_obs (average mjd_obs of inputs <=)", NAN);
+    psMetadataAddF64(sumskyfileArgs, PS_LIST_TAIL, "-mjd_obs_end",  0,      "search by mjd_obs (average mjd_obs of inputs>=)", NAN);
     psMetadataAddS16(sumskyfileArgs, PS_LIST_TAIL, "-fault",  0,            "search by fault code", 0);
     psMetadataAddU64(sumskyfileArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
@@ -204,5 +207,5 @@
     psMetadata *sassskyfileArgs = psMetadataAlloc();
     psMetadataAddS64(sassskyfileArgs, PS_LIST_TAIL, "-sass_id", 0,           "search by stack association ID", 0);
-    psMetadataAddStr(sassskyfileArgs, PS_LIST_TAIL, "-tess_id", 0,            "search by tess ID", 0);
+    psMetadataAddStr(sassskyfileArgs, PS_LIST_TAIL, "-tess_id", 0,            "search by tess ID (LIKE comparison)", 0);
     psMetadataAddStr(sassskyfileArgs, PS_LIST_TAIL, "-projection_cell", 0,         "search by projection cell", 0);
 
Index: branches/eam_branches/ipp-20100823/ippTools/src/warptool.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/warptool.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/warptool.c	(revision 29515)
@@ -52,4 +52,5 @@
 static bool pendingcleanuprunMode(pxConfig *config);
 static bool pendingcleanupwarpMode(pxConfig *config);
+static bool revertcleanupMode(pxConfig *config);
 static bool donecleanupMode(pxConfig *config);
 static bool tocleanedskyfileMode(pxConfig *config);
@@ -107,4 +108,5 @@
         MODECASE(WARPTOOL_MODE_PENDINGCLEANUPRUN,  pendingcleanuprunMode);
         MODECASE(WARPTOOL_MODE_PENDINGCLEANUPSKYFILE, pendingcleanupwarpMode);
+        MODECASE(WARPTOOL_MODE_REVERTCLEANUP,      revertcleanupMode);
         MODECASE(WARPTOOL_MODE_DONECLEANUP,        donecleanupMode);
         MODECASE(WARPTOOL_MODE_TOCLEANEDSKYFILE,   tocleanedskyfileMode);
@@ -1805,4 +1807,61 @@
 
 
+static bool revertcleanupMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_S64(config->args, where, "-warp_id",    "warpSkyfile.warp_id", "==");
+    pxAddLabelSearchArgs (config, where, "-label",     "warpRun.label", "LIKE");
+    pxAddLabelSearchArgs (config, where, "-data_group",   "warpRun.data_group", "LIKE");
+
+    PXOPT_LOOKUP_STR(state, config->args, "-state", false, false);
+
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+    if (!state) {
+        state = "error_cleaned";
+    }
+    char *newState = NULL;
+    if (!strcmp(state, "error_cleaned")) {
+        newState = "goto_cleaned";
+    } else if (!strcmp(state, "error_purged")) {
+        newState = "goto_purged";
+    } else if (!strcmp(state, "error_scrubbed")) {
+        newState = "goto_scrubbed";
+    } else {
+        psError(PXTOOLS_ERR_CONFIG, true, "-state must be either error_cleaned, error_purged, or error_scrubbed");
+        return false;
+    }
+
+    psString query = pxDataGet("warptool_revertcleanup.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    if (!p_psDBRunQueryF(config->dbh, query, newState, state, state)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    int numDeleted = psDBAffectedRows(config->dbh);
+
+    psLogMsg("warptool", PS_LOG_INFO, "Reverted %d warpRuns and warpSkyfiles", numDeleted);
+
+    return true;
+}
 static bool donecleanupMode(pxConfig *config)
 {
Index: branches/eam_branches/ipp-20100823/ippTools/src/warptool.h
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/warptool.h	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/warptool.h	(revision 29515)
@@ -48,4 +48,5 @@
     WARPTOOL_MODE_PENDINGCLEANUPRUN,
     WARPTOOL_MODE_PENDINGCLEANUPSKYFILE,
+    WARPTOOL_MODE_REVERTCLEANUP,
     WARPTOOL_MODE_DONECLEANUP,
     WARPTOOL_MODE_TOCLEANEDSKYFILE,
Index: branches/eam_branches/ipp-20100823/ippTools/src/warptoolConfig.c
===================================================================
--- branches/eam_branches/ipp-20100823/ippTools/src/warptoolConfig.c	(revision 29324)
+++ branches/eam_branches/ipp-20100823/ippTools/src/warptoolConfig.c	(revision 29515)
@@ -362,4 +362,11 @@
     psMetadataAddU64(pendingcleanupskyfileArgs, PS_LIST_TAIL, "-limit",  0,            "limit result set to N items", 0);
 
+    // -revertcleanup
+    psMetadata *revertcleanupArgs = psMetadataAlloc();
+    psMetadataAddS64(revertcleanupArgs, PS_LIST_TAIL, "-warp_id", 0,            "search by warptool ID", 0);
+    psMetadataAddStr(revertcleanupArgs, PS_LIST_TAIL, "-label",  PS_META_DUPLICATE_OK, "search by warpRun label", NULL);
+    psMetadataAddStr(revertcleanupArgs, PS_LIST_TAIL, "-data_group",  PS_META_DUPLICATE_OK, "search by warpRun data_group", NULL);
+    psMetadataAddStr(revertcleanupArgs, PS_LIST_TAIL, "-state",  0,            "search by state", NULL);
+
     // -donecleanup
     psMetadata *donecleanupArgs = psMetadataAlloc();
@@ -451,4 +458,5 @@
     PXOPT_ADD_MODE("-pendingcleanuprun",     "show runs that need to be cleaned up", WARPTOOL_MODE_PENDINGCLEANUPRUN,    pendingcleanuprunArgs);
     PXOPT_ADD_MODE("-pendingcleanupskyfile", "show runs that need to be cleaned up", WARPTOOL_MODE_PENDINGCLEANUPSKYFILE, pendingcleanupskyfileArgs);
+    PXOPT_ADD_MODE("-revertcleanup",         "revert cleanup runs with errors",     WARPTOOL_MODE_REVERTCLEANUP,          revertcleanupArgs);
     PXOPT_ADD_MODE("-donecleanup",           "show runs that have been cleaned",     WARPTOOL_MODE_DONECLEANUP,          donecleanupArgs);
     PXOPT_ADD_MODE("-tocleanedskyfile", "set skyfile as cleaned", WARPTOOL_MODE_TOCLEANEDSKYFILE, tocleanedskyfileArgs);
