Index: /trunk/ippTools/src/dettool.c
===================================================================
--- /trunk/ippTools/src/dettool.c	(revision 9095)
+++ /trunk/ippTools/src/dettool.c	(revision 9096)
@@ -1092,5 +1092,7 @@
         " GROUP BY"
         "    detProcessedImfile.class_id,"
-        "    rawImfile.class_id"
+        "    rawImfile.class_id,"
+        "    detInputExp.exp_tag,"
+        "    detRun.position"
         " HAVING"
         "    COUNT(detProcessedImfile.class_id) = COUNT(rawImfile.class_id)"
@@ -1145,4 +1147,143 @@
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
+
+    // det_id, exp_tag, recip, -bg, -bg_stdev, & -bg_mean_stdev
+    // are required
+    bool status = false;
+    psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -det_id");
+        return false;
+    }
+    if (!det_id) {
+        psError(PS_ERR_UNKNOWN, true, "-det_id is required");
+        return false;
+    }
+    psString exp_tag = psMetadataLookupStr(&status, config->args, "-exp_tag");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_tag");
+        return false;
+    }
+    if (!exp_tag) {
+        psError(PS_ERR_UNKNOWN, true, "-exp_tag is required");
+        return false;
+    }
+    psString recipe = psMetadataLookupStr(&status, config->args, "-recip");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -recip");
+        return false;
+    }
+    if (!recipe) {
+        psError(PS_ERR_UNKNOWN, true, "-recip is required");
+        return false;
+    }
+    psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");
+        return false;
+    }
+    if (isnan(bg)) {
+        psError(PS_ERR_UNKNOWN, true, "-bg is required");
+        return false;
+    }
+    psF64 bg_stdev = psMetadataLookupF64(&status, config->args, "-bg_stdev");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_stdev");
+        return false;
+    }
+    if (isnan(bg_stdev)) {
+        psError(PS_ERR_UNKNOWN, true, "-bg_stdev is required");
+        return false;
+    }
+    psF64 bg_mean_stdev = psMetadataLookupF64(&status, config->args, "-bg_mean_stdev");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg_mean_stdev");
+        return false;
+    }
+    if (isnan(bg_mean_stdev)) {
+        psError(PS_ERR_UNKNOWN, true, "-bg_mean_stdev is required");
+        return false;
+    }
+    // optional
+    psString b1_uri = psMetadataLookupStr(&status, config->args, "-b1_uri");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -b1_uri");
+        return false;
+    }
+    psString b2_uri = psMetadataLookupStr(&status, config->args, "-b2_uri");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -b2_uri");
+        return false;
+    }
+
+    psString query = psStringCopy(
+        " SELECT DISTINCT"
+        "    detProcessedImfile.det_id,"
+        "    detRun.iteration,"
+        "    detRun.det_type,"
+        "    detProcessedImfile.exp_tag"
+        " FROM detRun"
+        " JOIN detInputExp"
+        "    ON detRun.position = detInputExp.det_id"
+        "    AND detRun.iteration = detInputExp.iteration"
+        " JOIN rawDetrendExp"
+        "    ON detInputExp.exp_tag = rawDetrendExp.exp_tag"
+        " JOIN detProcessedImfile"
+        "    ON detInputExp.det_id = detProcessedImfile.det_id"
+        "    AND detInputExp.exp_tag = detProcessedImfile.exp_tag"
+        " LEFT JOIN detProcessedExp"
+        "    ON detInputExp.det_id = detProcessedExp.det_id"
+        "    AND detProcessedImfile.exp_tag= detProcessedExp.exp_tag"
+        " LEFT JOIN rawImfile"
+        "    ON detInputExp.exp_tag = rawImfile.exp_tag"
+        "    AND detProcessedImfile.class_id = rawImfile.class_id"
+        " WHERE"
+        "    detProcessedExp.det_id IS NULL"
+        "    AND detProcessedExp.exp_tag IS NULL"
+        "    AND detInputExp.include = 1"
+        "    AND detRun.position = %s"
+        "    AND detProcessedImfile.exp_tag = '%s'"
+        " GROUP BY"
+        "    detProcessedImfile.class_id,"
+        "    rawImfile.class_id"
+        " HAVING"
+        "    COUNT(detProcessedImfile.class_id) = COUNT(rawImfile.class_id)"
+        );
+
+    if (!p_psDBRunQuery(config->dbh, query, det_id, exp_tag)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        // XXX check psError here
+        psError(PS_ERR_UNKNOWN, false, "no pending rawDetrendExp rows found");
+        return false;
+    }
+    psFree(output);
+
+    // create a new detProcessedImfile object
+    detProcessedExpRow *detRow = detProcessedExpRowAlloc(
+        (psS32)atol(det_id),
+        exp_tag,
+        recipe,
+        bg,
+        bg_stdev,
+        bg_mean_stdev,
+        b1_uri,
+        b2_uri
+    );
+
+    // insert the new row into the detProcessedImfile table
+    if (!detProcessedExpInsertObject(config->dbh, detRow)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(detRow);
+        return false;
+    }
+
+    psFree(detRow);
 
     return true;
Index: /trunk/ippTools/src/dettoolConfig.c
===================================================================
--- /trunk/ippTools/src/dettoolConfig.c	(revision 9095)
+++ /trunk/ippTools/src/dettoolConfig.c	(revision 9096)
@@ -542,5 +542,5 @@
     PXTOOL_MODE("-addprocessedimfile", DETTOOL_MODE_ADDPROCESSEDIMFILE,  addprocessedimfileArgs);
     PXTOOL_MODE("-toprocessedexp",  DETTOOL_MODE_TOPROCESSEDEXP,  toprocessedexpArgs);
-    PXTOOL_MODE("-addprocessedexp", DETTOOL_MODE_ADDPROCESSEDIMFILE, addprocessedexpArgs);
+    PXTOOL_MODE("-addprocessedexp", DETTOOL_MODE_ADDPROCESSEDEXP, addprocessedexpArgs);
     PXTOOL_MODE("-processedexp",    DETTOOL_MODE_PROCESSEDIMFILE, processedimfileArgs);
     PXTOOL_MODE("-tostack",         DETTOOL_MODE_TOSTACK,       tostackArgs);
