Index: /trunk/ippTasks/survey.pro
===================================================================
--- /trunk/ippTasks/survey.pro	(revision 32282)
+++ /trunk/ippTasks/survey.pro	(revision 32283)
@@ -213,10 +213,15 @@
 # user functions to manipulate magic labels
 macro survey.add.magic
-  if ($0 != 3)
-    echo "USAGE: survey.add.magic (label) (workdir base)"
+  if (($0 != 3)&&($0 != 4))
+    echo "USAGE: survey.add.magic (label) (workdir base) (multidiff)"
     break
   end
   book newpage SURVEY_MAGIC $1
   book setword SURVEY_MAGIC $1 WORKDIR $2
+  if ($0 == 3)
+     book setword SURVEY_MAGIC $1 MULTIDIFF FALSE
+  else 
+     book setword SURVEY_MAGIC $1 MULTIDIFF $3
+  end
   book setword SURVEY_MAGIC $1 STATE PENDING
 end
@@ -725,6 +730,11 @@
     book setword SURVEY_MAGIC $label STATE DONE
     book getword SURVEY_MAGIC $label WORKDIR -var workdir
-  
-    $run = magictool -rerun -definebyquery -label $label -diff_label $label -workdir $workdir/$label
+    book getword SURVEY_MAGIC $label MULTIDIFF -var multidiff
+
+    $run = magictool -pretend -rerun -definebyquery -label $label -diff_label $label -workdir $workdir/$label
+    
+    if (("$multidiff" == "TRUE")||("$multidiff" == "MULTIDIFF"))
+       $run = $run -multidiff
+    end
 
     if ($DB:n == 0)
@@ -735,5 +745,5 @@
     end
     
-    # echo $run
+    echo $run
     command $run
   end
Index: /trunk/ippTools/share/Makefile.am
===================================================================
--- /trunk/ippTools/share/Makefile.am	(revision 32282)
+++ /trunk/ippTools/share/Makefile.am	(revision 32283)
@@ -244,4 +244,5 @@
 	magictool_definebyquery_insert.sql \
 	magictool_definebyquery_select.sql \
+	magictool_definebyquery_select_multidiff.sql \
 	magictool_inputs.sql \
 	magictool_inputskyfile.sql \
Index: /trunk/ippTools/share/magictool_definebyquery_select.sql
===================================================================
--- /trunk/ippTools/share/magictool_definebyquery_select.sql	(revision 32282)
+++ /trunk/ippTools/share/magictool_definebyquery_select.sql	(revision 32283)
@@ -49,5 +49,4 @@
     ) AS oldMagicRun
     ON oldMagicRun.exp_id = chipRun.exp_id
---    AND oldMagicRun.diff_id = diffWarps.diff_id
 -- WHERE hook %s
 GROUP BY chipRun.exp_id
Index: /trunk/ippTools/share/magictool_definebyquery_select_multidiff.sql
===================================================================
--- /trunk/ippTools/share/magictool_definebyquery_select_multidiff.sql	(revision 32283)
+++ /trunk/ippTools/share/magictool_definebyquery_select_multidiff.sql	(revision 32283)
@@ -0,0 +1,53 @@
+-- Get a list of exposures on which magic may be performed
+SELECT DISTINCT
+    chipRun.exp_id,
+    MAX(diffWarps.diff_id) AS diff_id,
+    -- The following trick pulls out the 'inverse' value for the maximum diff_id
+    CONVERT(SUBSTRING_INDEX(GROUP_CONCAT(diffWarps.inverse ORDER BY diffWarps.diff_id DESC), ',', 1), UNSIGNED) AS inverse,
+    diff_data_group
+FROM (
+    -- Forward diffs
+    SELECT
+        diffRun.diff_id,
+        warp1 AS warp_id,
+        0 AS inverse,
+        diffRun.data_group AS diff_data_group
+    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
+    -- Backward diffs
+    SELECT
+        diffRun.diff_id,
+        warp2 AS warp_id,
+        1 AS inverse,
+        diffRun.data_group AS diff_data_group
+    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
+JOIN warpRun USING(warp_id)
+JOIN fakeRun USING(fake_id)
+JOIN camRun USING(cam_id)
+JOIN chipRun USING(chip_id)
+JOIN rawExp USING(exp_id)
+LEFT JOIN
+    (SELECT magic_id, exp_id, diff_id, label
+        FROM magicRun
+        -- rerun hook %s
+    ) AS oldMagicRun
+    ON oldMagicRun.exp_id = chipRun.exp_id
+    AND oldMagicRun.diff_id = diffWarps.diff_id
+-- WHERE hook %s
+GROUP BY chipRun.exp_id
Index: /trunk/ippTools/src/magictool.c
===================================================================
--- /trunk/ippTools/src/magictool.c	(revision 32282)
+++ /trunk/ippTools/src/magictool.c	(revision 32283)
@@ -131,5 +131,5 @@
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     PXOPT_LOOKUP_BOOL(pretend, config->args, "-pretend", false);
-
+    PXOPT_LOOKUP_BOOL(multidiff, config->args, "-multidiff", false);
     psMetadata *diffWhere = psMetadataAlloc(); // WHERE conditions for diffRuns
     PXOPT_COPY_STR(config->args, diffWhere, "-diff_label", "diffRun.label", "==");
@@ -142,5 +142,11 @@
     // Get list of exposures ready to magic
     {
-        psString query = pxDataGet("magictool_definebyquery_select.sql");
+        psString query;
+        if (multidiff) {
+	  query = pxDataGet("magictool_definebyquery_select_multidiff.sql");
+        }
+        else {
+	  query = pxDataGet("magictool_definebyquery_select.sql");
+        }
         if (!query) {
             psError(PXTOOLS_ERR_SYS, false, "failed to retreive SQL statement");
Index: /trunk/ippTools/src/magictoolConfig.c
===================================================================
--- /trunk/ippTools/src/magictoolConfig.c	(revision 32282)
+++ /trunk/ippTools/src/magictoolConfig.c	(revision 32283)
@@ -61,4 +61,5 @@
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-available", 0, "process what's immediately available?", false);
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-rerun", 0, "generate new run even if existing?", false);
+    psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-multidiff", 0, "allow multiple diffs to be magicked with the same label", false);
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
     psMetadataAddBool(definebyqueryArgs, PS_LIST_TAIL, "-pretend", 0, "list results but do not queue", false);
