Index: trunk/ippTools/src/regtool.c
===================================================================
--- trunk/ippTools/src/regtool.c	(revision 15778)
+++ trunk/ippTools/src/regtool.c	(revision 16170)
@@ -44,13 +44,4 @@
 static bool updateprocessedexpMode(pxConfig *config);
 
-
-// static guidePendingExpRow *newToP1PendingExp(newExpRow *newExp);
-//static chipPendingExpRow *newTochipPendingExp(pxConfig *config, newExpRow *newExp);
-//static chipInputImfileRow *rawImfileTochipInputImfile(pxConfig *config, psS64 chip_id, rawImfileRow *rawImfile);
-
-static rawExpRow *newToRawExp(pxConfig *config, newExpRow *exp);
-//static psU32 mapCodeStrToInt(const char *codeStr);
-
-
 # define MODECASE(caseName, func) \
     case caseName: \
@@ -109,10 +100,6 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    bool status = false;
-    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -limit");
-        return false;
-    }
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
 
     // select newImfiles that:
@@ -163,11 +150,4 @@
     }
 
-    bool simple = false;
-    simple = psMetadataLookupBool(&status, config->args, "-simple");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -simple");
-        return false;
-    }
-
     // negate simple so the default is true
     if (!ippdbPrintMetadatas(stdout, output, "regPendingImfile", !simple)) {
@@ -187,334 +167,61 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    bool status = false;
     // required
-    psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");
-        return false;
-    }
-    if (!exp_id) {
-        psError(PS_ERR_UNKNOWN, true, "-exp_id is required");
-        return false;
-    }
-
-    psString exp_name = psMetadataLookupStr(&status, config->args, "-exp_name");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_name");
-        return false;
-    }
-    if (!exp_name) {
-        psError(PS_ERR_UNKNOWN, true, "-exp_name is required");
-        return false;
-    }
-
-    psString camera = psMetadataLookupStr(&status, config->args, "-inst");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst");
-        return false;
-    }
-    if (!camera) {
-        psError(PS_ERR_UNKNOWN, true, "-inst is required");
-        return false;
-    }
-
-    psString telescope = psMetadataLookupStr(&status, config->args, "-telescope");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope");
-        return false;
-    }
-    if (!telescope) {
-        psError(PS_ERR_UNKNOWN, true, "-telescope is required");
-        return false;
-    }
-
-    psString tmp_class_id = psMetadataLookupStr(&status, config->args, "-tmp_class_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -tmp_class_id");
-        return false;
-    }
-    if (!tmp_class_id) {
-        psError(PS_ERR_UNKNOWN, true, "-tmp_class_id is required");
-    }
-
-    psString class_id = psMetadataLookupStr(&status, config->args, "-class_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -class_id");
-        return false;
-    }
-    if (!class_id) {
-        psError(PS_ERR_UNKNOWN, true, "-class_id is required");
-        return false;
-    }
-
-    psString uri = psMetadataLookupStr(&status, config->args, "-uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -uri");
-        return false;
-    }
-    if (!uri) {
-        psError(PS_ERR_UNKNOWN, true, "-uri is required");
-        return false;
-    }
+    PXOPT_LOOKUP_STR(exp_id, config->args, "-exp_id", true, false);
+    PXOPT_LOOKUP_STR(exp_name, config->args, "-exp_name", true, false);
+    PXOPT_LOOKUP_STR(camera, config->args, "-inst", true, false);
+    PXOPT_LOOKUP_STR(telescope, config->args, "-telescope", true, false);
+    PXOPT_LOOKUP_STR(tmp_class_id, config->args, "-tmp_class_id", true, false);
+    PXOPT_LOOKUP_STR(class_id, config->args, "-class_id", true, false);
+    PXOPT_LOOKUP_STR(uri, config->args, "-uri", true, false);
 
     // optional
-    psString exp_type = psMetadataLookupStr(&status, config->args, "-exp_type");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_type");
-        return false;
-    }
-
-    psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel");
-        return false;
-    }
-
-    psString filter = psMetadataLookupStr(&status, config->args, "-filter");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
-        return false;
-    }
-
-    psString comment = psMetadataLookupStr(&status, config->args, "-comment");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -comment");
-        return false;
-    }
-
-    psF32 airmass = psMetadataLookupF32(&status, config->args, "-airmass");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass");
-        return false;
-    }
-
-    psF64 ra = psMetadataLookupF64(&status, config->args, "-ra");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ra");
-        return false;
-    }
-
-    psF64 decl = psMetadataLookupF64(&status, config->args, "-decl");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -decl");
-        return false;
-    }
-
-    psF32 exp_time = psMetadataLookupF32(&status, config->args, "-exp_time");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time");
-        return false;
-    }
-
-    psF32 sat_pixel_frac = psMetadataLookupF32(&status, config->args, "-sat_pixel_frac");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -sat_pixel_frac");
-        return false;
-    }
-
-    psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");
-        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;
-    }
-
-    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;
-    }
-
-    psF64 alt = psMetadataLookupF64(&status, config->args, "-alt");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -alt");
-        return false;
-    }
-
-    psF64 az = psMetadataLookupF64(&status, config->args, "-az");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -az");
-        return false;
-    }
-
-    psF32 ccd_temp = psMetadataLookupF32(&status, config->args, "-ccd_temp");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp");
-        return false;
-    }
-
-    psF64 posang = psMetadataLookupF32(&status, config->args, "-posang");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang");
-        return false;
-    }
-
-    psF32 m1_x = psMetadataLookupF32(&status, config->args, "-m1_x");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_x");
-        return false;
-    }
-    psF32 m1_y = psMetadataLookupF32(&status, config->args, "-m1_y");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_y");
-        return false;
-    }
-    psF32 m1_z = psMetadataLookupF32(&status, config->args, "-m1_z");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_z");
-        return false;
-    }
-    psF32 m1_tip = psMetadataLookupF32(&status, config->args, "-m1_tip");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_tip");
-        return false;
-    }
-    psF32 m1_tilt = psMetadataLookupF32(&status, config->args, "-m1_tilt");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_tilt");
-        return false;
-    }
-
-    psF32 m2_x = psMetadataLookupF32(&status, config->args, "-m2_x");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_x");
-        return false;
-    }
-    psF32 m2_y = psMetadataLookupF32(&status, config->args, "-m2_y");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_y");
-        return false;
-    }
-    psF32 m2_z = psMetadataLookupF32(&status, config->args, "-m2_z");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_z");
-        return false;
-    }
-    psF32 m2_tip = psMetadataLookupF32(&status, config->args, "-m2_tip");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_tip");
-        return false;
-    }
-    psF32 m2_tilt = psMetadataLookupF32(&status, config->args, "-m2_tilt");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_tilt");
-        return false;
-    }
-
-    psF32 env_temp = psMetadataLookupF32(&status, config->args, "-env_temperature");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_temperature");
-        return false;
-    }
-    psF32 env_humid = psMetadataLookupF32(&status, config->args, "-env_humidity");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_humidity");
-        return false;
-    }
-    psF32 env_wind = psMetadataLookupF32(&status, config->args, "-env_wind_speed");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_wind_speed");
-        return false;
-    }
-    psF32 env_dir = psMetadataLookupF32(&status, config->args, "-env_wind_dir");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_wind_dir");
-        return false;
-    }
-
-    psF32 teltemp_m1 = psMetadataLookupF32(&status, config->args, "-teltemp_m1");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_m1");
-        return false;
-    }
-    psF32 teltemp_m1cell = psMetadataLookupF32(&status, config->args, "-teltemp_m1cell");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_m1cell");
-        return false;
-    }
-    psF32 teltemp_m2 = psMetadataLookupF32(&status, config->args, "-teltemp_m2");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_m2");
-        return false;
-    }
-    psF32 teltemp_spider = psMetadataLookupF32(&status, config->args, "-teltemp_spider");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_spider");
-        return false;
-    }
-    psF32 teltemp_truss = psMetadataLookupF32(&status, config->args, "-teltemp_truss");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_truss");
-        return false;
-    }
-    psF32 teltemp_extra = psMetadataLookupF32(&status, config->args, "-teltemp_extra");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_extra");
-        return false;
-    }
-
-    psF32 pon_time = psMetadataLookupF32(&status, config->args, "-pon_time");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -pon_time");
-        return false;
-    }
-
-    psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");
-        return false;
-    }
-    psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");
-        return false;
-    }
-    psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");
-        return false;
-    }
-    psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");
-        return false;
-    }
-    psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");
-        return false;
-    }
-
-    psString object = psMetadataLookupStr(&status, config->args, "-object");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -object");
-        return false;
-    }
-
-    psTime *dateobs = NULL;
-    {
-        psString dateobsStr = psMetadataLookupStr(&status, config->args, "-dateobs");
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -dateobs");
-            return false;
-        }
-        // pass through NULL as this is an optional field
-        if (dateobsStr) {
-            dateobs = psTimeFromISO(dateobsStr, PS_TIME_UTC);
-        } else {
-            dateobs = NULL;
-        }
-    }
-
-    psS16 code = psMetadataLookupS16(&status, config->args, "-code");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
-        return false;
-    }
+    PXOPT_LOOKUP_STR(exp_type, config->args, "-exp_type", false, false);
+    PXOPT_LOOKUP_STR(filelevel, config->args, "-filelevel", false, false);
+    PXOPT_LOOKUP_STR(filter, config->args, "-filter", false, false);
+    PXOPT_LOOKUP_STR(comment, config->args, "-comment", false, false);
+
+    PXOPT_LOOKUP_F32(airmass, config->args, "-airmass", false, false);
+    PXOPT_LOOKUP_F64(ra, config->args, "-ra", false, false);
+    PXOPT_LOOKUP_F64(decl, config->args, "-decl", false, false);
+    PXOPT_LOOKUP_F32(exp_time, config->args, "-exp_time", false, false);
+    PXOPT_LOOKUP_F32(sat_pixel_frac, config->args, "-sat_pixel_frac", false, false);
+    PXOPT_LOOKUP_F64(bg, config->args, "-bg", false, false);
+    PXOPT_LOOKUP_F64(bg_stdev, config->args, "-bg_stdev", false, false);
+    PXOPT_LOOKUP_F64(bg_mean_stdev, config->args, "-bg_mean_stdev", false, false);
+    PXOPT_LOOKUP_F64(alt, config->args, "-alt", false, false);
+    PXOPT_LOOKUP_F64(az, config->args, "-az", false, false);
+    PXOPT_LOOKUP_F32(ccd_temp, config->args, "-ccd_temp", false, false);
+    PXOPT_LOOKUP_F64(posang, config->args, "-posang", false, false);
+    PXOPT_LOOKUP_F32(m1_x, config->args, "-m1_x", false, false);
+    PXOPT_LOOKUP_F32(m1_y, config->args, "-m1_y", false, false);
+    PXOPT_LOOKUP_F32(m1_z, config->args, "-m1_z", false, false);
+    PXOPT_LOOKUP_F32(m1_tip, config->args, "-m1_tip", false, false);
+    PXOPT_LOOKUP_F32(m1_tilt, config->args, "-m1_tilt", false, false);
+    PXOPT_LOOKUP_F32(m2_x, config->args, "-m2_x", false, false);
+    PXOPT_LOOKUP_F32(m2_y, config->args, "-m2_y", false, false);
+    PXOPT_LOOKUP_F32(m2_z, config->args, "-m2_z", false, false);
+    PXOPT_LOOKUP_F32(m2_tip, config->args, "-m2_tip", false, false);
+    PXOPT_LOOKUP_F32(m2_tilt, config->args, "-m2_tilt", false, false);
+
+    PXOPT_LOOKUP_F32(env_temp, config->args, "-env_temperature", false, false);
+    PXOPT_LOOKUP_F32(env_humid, config->args, "-env_humidity", false, false);
+    PXOPT_LOOKUP_F32(env_wind, config->args, "-env_wind_speed", false, false);
+    PXOPT_LOOKUP_F32(env_dir, config->args, "-env_wind_dir", false, false);
+    PXOPT_LOOKUP_F32(teltemp_m1, config->args, "-teltemp_m1", false, false);
+    PXOPT_LOOKUP_F32(teltemp_m1cell, config->args, "-teltemp_m1cell", false, false);
+    PXOPT_LOOKUP_F32(teltemp_m2, config->args, "-teltemp_m2", false, false);
+    PXOPT_LOOKUP_F32(teltemp_spider, config->args, "-teltemp_spider", false, false);
+    PXOPT_LOOKUP_F32(teltemp_truss, config->args, "-teltemp_truss", false, false);
+    PXOPT_LOOKUP_F32(teltemp_extra, config->args, "-teltemp_extra", false, false);
+    PXOPT_LOOKUP_F32(pon_time, config->args, "-pon_time", false, false);
+    PXOPT_LOOKUP_F64(user_1, config->args, "-user_1", false, false);
+    PXOPT_LOOKUP_F64(user_2, config->args, "-user_2", false, false);
+    PXOPT_LOOKUP_F64(user_3, config->args, "-user_3", false, false);
+    PXOPT_LOOKUP_F64(user_4, config->args, "-user_4", false, false);
+    PXOPT_LOOKUP_F64(user_5, config->args, "-user_5", false, false);
+    PXOPT_LOOKUP_STR(object, config->args, "-object", false, false);
+    PXOPT_LOOKUP_TIME(dateobs, config->args, "-dateobs", false, false);
+    PXOPT_LOOKUP_S16(code, config->args, "-code", false, false);
 
     if (!rawImfileInsert(
@@ -574,9 +281,6 @@
     )) {
         psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(dateobs);
-        return false;
-    }
-
-    psFree(dateobs);
+        return false;
+    }
 
     return true;
@@ -588,16 +292,7 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    bool status = false;
-    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -limit");
-        return false;
-    }
-
-    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -faulted");
-        return false;
-    }
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(faulted, config->args, "-faulted", false);
 
     psString query = pxDataGet("regtool_processedimfile.sql");
@@ -655,14 +350,4 @@
     }
 
-    bool simple = false;
-    {
-        bool status = false;
-        simple = psMetadataLookupBool(&status, config->args, "-simple");
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");
-            return false;
-        }
-    }
-
     if (psArrayLength(output)) {
         // negative simple so the default is true
@@ -716,14 +401,5 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    bool status = false;
-    psS16 code = psMetadataLookupS16(&status, config->args, "-code");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
-        return false;
-    }
-    if (code == INT16_MAX) {
-        psError(PS_ERR_UNKNOWN, true, "-code is required");
-        return false;
-    }
+    PXOPT_LOOKUP_S16(code, config->args, "-code", true, false);
 
     if (!pxSetFaultCode(config->dbh, "rawImfile", config->where, code)) {
@@ -740,10 +416,6 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    bool status = false;
-    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -limit");
-        return false;
-    }
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
 
     // return only exps that:
@@ -792,11 +464,4 @@
     }
 
-    bool simple = false;
-    simple = psMetadataLookupBool(&status, config->args, "-simple");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -simple");
-        return false;
-    }
-
     // negate simple so the default is true
     if (!ippdbPrintMetadatas(stdout, output, "regPendingExp", !simple)) {
@@ -821,20 +486,65 @@
     // that the correct count of imfiles is in rawImfile
 
-    bool status = false;
-    psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");
-        return false;
-    }
-    if (!exp_id) {
-        psError(PS_ERR_UNKNOWN, true, "-exp_id is required");
-        return false;
-    }
-
-    bool detrend = psMetadataLookupBool(&status, config->args, "-detrend");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -detrend");
-        return false;
-    }
+    // required
+    PXOPT_LOOKUP_STR(exp_id, config->args, "-exp_id", true, false);
+    PXOPT_LOOKUP_STR(exp_name, config->args, "-exp_name", true, false);
+    PXOPT_LOOKUP_STR(camera, config->args, "-inst", true, false);
+    PXOPT_LOOKUP_STR(telescope, config->args, "-telescope", true, false);
+    PXOPT_LOOKUP_STR(exp_tag, config->args, "-exp_tag", true, false);
+    PXOPT_LOOKUP_STR(filelevel, config->args, "-filelevel", true, false);
+
+    // optional
+    PXOPT_LOOKUP_STR(dvodb, config->args, "-dvodb", false, false);
+    PXOPT_LOOKUP_STR(tess_id, config->args, "-tess_id", false, false);
+    PXOPT_LOOKUP_STR(end_stage, config->args, "-end_stage", false, false);
+    PXOPT_LOOKUP_STR(exp_type, config->args, "-exp_type", false, false);
+    PXOPT_LOOKUP_STR(workdir, config->args, "-workdir", false, false);
+    PXOPT_LOOKUP_STR(reduction, config->args, "-reduction", false, false);
+    PXOPT_LOOKUP_STR(filter, config->args, "-filter", false, false);
+    PXOPT_LOOKUP_STR(comment, config->args, "-comment", false, false);
+    PXOPT_LOOKUP_F32(airmass, config->args, "-airmass", false, false);
+    PXOPT_LOOKUP_F64(ra, config->args, "-ra", false, false);
+    PXOPT_LOOKUP_F64(decl, config->args, "-decl", false, false);
+    PXOPT_LOOKUP_F32(exp_time, config->args, "-exp_time", false, false);
+    PXOPT_LOOKUP_F32(sat_pixel_frac, config->args, "-sat_pixel_frac", false, false);
+    PXOPT_LOOKUP_F64(bg, config->args, "-bg", false, false);
+    PXOPT_LOOKUP_F64(bg_stdev, config->args, "-bg_stdev", false, false);
+    PXOPT_LOOKUP_F64(bg_mean_stdev, config->args, "-bg_mean_stdev", false, false);
+    PXOPT_LOOKUP_F64(alt, config->args, "-alt", false, false);
+    PXOPT_LOOKUP_F64(az, config->args, "-az", false, false);
+    PXOPT_LOOKUP_F32(ccd_temp, config->args, "-ccd_temp", false, false);
+    PXOPT_LOOKUP_F64(posang, config->args, "-posang", false, false);
+    PXOPT_LOOKUP_F32(m1_x, config->args, "-m1_x", false, false);
+    PXOPT_LOOKUP_F32(m1_y, config->args, "-m1_y", false, false);
+    PXOPT_LOOKUP_F32(m1_z, config->args, "-m1_z", false, false);
+    PXOPT_LOOKUP_F32(m1_tip, config->args, "-m1_tip", false, false);
+    PXOPT_LOOKUP_F32(m1_tilt, config->args, "-m1_tilt", false, false);
+    PXOPT_LOOKUP_F32(m2_x, config->args, "-m2_x", false, false);
+    PXOPT_LOOKUP_F32(m2_y, config->args, "-m2_y", false, false);
+    PXOPT_LOOKUP_F32(m2_z, config->args, "-m2_z", false, false);
+    PXOPT_LOOKUP_F32(m2_tip, config->args, "-m2_tip", false, false);
+    PXOPT_LOOKUP_F32(m2_tilt, config->args, "-m2_tilt", false, false);
+
+    PXOPT_LOOKUP_F32(env_temp, config->args, "-env_temperature", false, false);
+    PXOPT_LOOKUP_F32(env_humid, config->args, "-env_humidity", false, false);
+    PXOPT_LOOKUP_F32(env_wind, config->args, "-env_wind_speed", false, false);
+    PXOPT_LOOKUP_F32(env_dir, config->args, "-env_wind_dir", false, false);
+    PXOPT_LOOKUP_F32(teltemp_m1, config->args, "-teltemp_m1", false, false);
+    PXOPT_LOOKUP_F32(teltemp_m1cell, config->args, "-teltemp_m1cell", false, false);
+    PXOPT_LOOKUP_F32(teltemp_m2, config->args, "-teltemp_m2", false, false);
+    PXOPT_LOOKUP_F32(teltemp_spider, config->args, "-teltemp_spider", false, false);
+    PXOPT_LOOKUP_F32(teltemp_truss, config->args, "-teltemp_truss", false, false);
+    PXOPT_LOOKUP_F32(teltemp_extra, config->args, "-teltemp_extra", false, false);
+    PXOPT_LOOKUP_F32(pon_time, config->args, "-pon_time", false, false);
+    PXOPT_LOOKUP_F64(user_1, config->args, "-user_1", false, false);
+    PXOPT_LOOKUP_F64(user_2, config->args, "-user_2", false, false);
+    PXOPT_LOOKUP_F64(user_3, config->args, "-user_3", false, false);
+    PXOPT_LOOKUP_F64(user_4, config->args, "-user_4", false, false);
+    PXOPT_LOOKUP_F64(user_5, config->args, "-user_5", false, false);
+    PXOPT_LOOKUP_STR(object, config->args, "-object", false, false);
+    PXOPT_LOOKUP_TIME(dateobs, config->args, "-dateobs", false, false);
+
+    // default
+    PXOPT_LOOKUP_S16(code, config->args, "-code", false, false);
 
     psString query = pxDataGet("regtool_pendingexp.sql");
@@ -847,20 +557,10 @@
         // build a query to search by exp_id
         psMetadata *where = psMetadataAlloc();
-        bool status = false;
-        psString exp_id = psMetadataLookupStr(&status, config->args, "-exp_id");
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_id");
+        if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
+            psFree(where);
             psFree(query);
             return false;
         }
-        if (exp_id) {
-            if (!psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", exp_id)) {
-                psError(PS_ERR_UNKNOWN, false, "failed to add item exp_id");
-                psFree(where);
-                psFree(query);
-                return false;
-            }
-        }
-
 
         psString whereClause = psDBGenerateWhereSQL(where, NULL);
@@ -898,4 +598,14 @@
         return false;
     }
+    // sanity check that we only got one row
+    if (psArrayLength(output) != 1) {
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psError(PS_ERR_UNKNOWN, false, "should have gotten 1 row but %lu rows were returned", psArrayLength(output));
+        psFree(output);
+        return NULL;
+    }
 
     if (!psDBTransaction(config->dbh)) {
@@ -906,632 +616,21 @@
 
     // insert the exp into rawExp
-    for (long i = 0; psArrayLength(output) > i; i++) {
-        psMetadata *row = output->data[i];
-        // convert metadata into a newExp object
-        newExpRow *newExp = newExpObjectFromMetadata(row);
-        // convert newExp object into a rawExp object
-        rawExpRow *rawExp = newToRawExp(config, newExp);
-        if (!rawExp) {
-            // rollback
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            psError(PS_ERR_UNKNOWN, false, "failed to convert newExp to rawExp");
-            psFree(newExp);
-            psFree(output);
-            return false;
-        }
-        psFree(newExp);
-
-        // insert the rawExp object into the database
-        if (!rawExpInsertObject(config->dbh, rawExp)) {
-            // rollback
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            psError(PS_ERR_UNKNOWN, false, "database error");
-            psFree(rawExp);
-            psFree(output);
-            return false;
-        }
-
-        // if this is a detrend image don't put it in the chip queue (and we're
-        // done)
-        if (detrend) {
-            // set the state for the newExp to stop
-            if (!pxnewExpSetState(config, exp_id, "stop")) {
-                // rollback
-                if (!psDBRollback(config->dbh)) {
-                    psError(PS_ERR_UNKNOWN, false, "database error");
-                }
-                psError(PS_ERR_UNKNOWN, false, "failed to change newExp.state for exp_id: %s", exp_id);
-                psFree(rawExp);
-                psFree(output);
-                return false;
-            }
-            psFree(rawExp);
-            continue;
-        }
-
-
-        // set the state for the newExp to stop
-        if (!pxnewExpSetState(config, exp_id, "stop")) {
-            // rollback
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            psError(PS_ERR_UNKNOWN, false, "failed to change newExp.state for exp_id: %s", exp_id);
-            psFree(rawExp);
-            psFree(output);
-            return false;
-        }
-
-        // insert an entry into the chipPendingExp table
-        // this can only be run as the newExp's state has been set to stop
-        if (!pxchipQueueByExpTag(config,
-                    rawExp->exp_id,
-                    rawExp->workdir,
-                    NULL, // label
-                    rawExp->reduction,
-                    NULL, // expgroup
-                    NULL  // dvodb
-        )) {
-            // rollback
-            if (!psDBRollback(config->dbh)) {
-                psError(PS_ERR_UNKNOWN, false, "database error");
-            }
-            psError(PS_ERR_UNKNOWN, false, "failed to queue chipPendingExp");
-            psFree(rawExp);
-            psFree(output);
-            return false;
-        }
-        psFree(rawExp);
-    }
+    psMetadata *row = output->data[0];
+    // convert metadata into a newExp object
+    newExpRow *newExp = newExpObjectFromMetadata(row);
     psFree(output);
 
-    if (!psDBCommit(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
-
-    return true;
-}
-
-
-static bool processedexpMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    bool status = false;
-    psU64 limit = psMetadataLookupU64(&status, config->args, "-limit");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -limit");
-        return false;
-    }
-
-    bool faulted = psMetadataLookupU64(&status, config->args, "-faulted");
-    if (!status) {
-        psError(PXTOOLS_ERR_PROG, false, "failed to lookup value for -faulted");
-        return false;
-    }
-
-    psString query = pxDataGet("regtool_processedexp.sql");
-    if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
-        return false;
-    }
-
-    if (config->where) {
-        psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawExp");
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
-
-    if (faulted) {
-        // list only faulted rows
-        psStringAppend(&query, " %s", "AND rawExp.fault != 0");
-    } else {
-        // don't list faulted rows
-        psStringAppend(&query, " %s", "AND rawExp.fault = 0");
-    }
-
-    // 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");
-        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("regtool", PS_LOG_INFO, "no rows found");
-        psFree(output);
-        return true;
-    }
-
-    bool simple = false;
-    {
-        bool status = false;
-        simple = psMetadataLookupBool(&status, config->args, "-simple");
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -simple");
-            return false;
-        }
-    }
-
-    if (psArrayLength(output)) {
-        // negative simple so the default is true
-        if (!ippdbPrintMetadatas(stdout, output, "rawExp", !simple)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to print array");
-            psFree(output);
-            return false;
-        }
-    }
-
-    psFree(output);
-
-    return true;
-}
-
-static bool revertprocessedexpMode(pxConfig *config)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-
-    psString query = pxDataGet("regtool_revertprocessedexp.sql");
-    if (!query) {
-        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
-        return false;
-    }
-
-    if (config->where) {
-        psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawExp");
-        psStringAppend(&query, " AND %s", whereClause);
-        psFree(whereClause);
-    }
-
-    if (!p_psDBRunQuery(config->dbh, query)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        psFree(query);
-        return false;
-    }
-    psFree(query);
-
-    if (psDBAffectedRows(config->dbh) < 1) {
-        psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");
-        return false;
-    }
-
-    return true;
-}
-
-
-static bool updateprocessedexpMode(pxConfig *config)
-{
-    bool status = false;
-    psS16 code = psMetadataLookupS16(&status, config->args, "-code");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
-        return false;
-    }
-    if (code == INT16_MAX) {
-        psError(PS_ERR_UNKNOWN, true, "-code is required");
-        return false;
-    }
-
-    if (!pxSetFaultCode(config->dbh, "rawExp", config->where, code)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to set set fault flag");
-        return false;
-    }
-
-    return true;
-}
-
-
-# if 0
-static guidePendingExpRow *newToP1PendingExp(newExpRow *newExp)
-{
-    return guidePendingExpRowAlloc(
-        newExp->exp_id,
-        newExp->camera,
-        newExp->telescope,
-        newExp->exp_type,
-        newExp->imfiles,
-        "my filter",
-        0.1, // airmass
-        0.2, // ra
-        0.3, // dec
-        0.4, // exp time
-        0.5, // background
-        "my recipe",
-        0xff // XXX calc version number
-    );
-}
-#endif
-
-
-#if 0
-static chipPendingExpRow *newTochipPendingExp(pxConfig *config, newExpRow *exp)
-{
-    PS_ASSERT_PTR_NON_NULL(config, NULL);
-    PS_ASSERT_PTR_NON_NULL(exp, NULL);
-
-    // optional
-    bool status = false;
-    psString label = psMetadataLookupStr(&status, config->args, "-label");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -label");
-        return false;
-    }
-
-    chipPendingExpRow *chipExp = chipPendingExpRowAlloc(
-            0,              // chip ID, assigned by db
-            exp->exp_id,
-            0xdeadbeef,     // guide version
-            label,
-            "my recipe",    // recipe
-            NULL,           // expgroup
-            NULL            // dvodb
-    );
-
-    return chipExp;
-}
-
-
-static chipInputImfileRow *rawImfileTochipInputImfile(pxConfig *config, psS64 chip_id, rawImfileRow *rawImfile)
-{
-    return chipInputImfileRowAlloc(
-            chip_id,
-            rawImfile->class_id,
-            rawImfile->uri
-    );
-}
-#endif
-
-
-static rawExpRow *newToRawExp(pxConfig *config, newExpRow *exp)
-{
-    PS_ASSERT_PTR_NON_NULL(config, NULL);
-    PS_ASSERT_PTR_NON_NULL(exp, NULL);
-
-    bool status = false;
-    // required
-    psString exp_name = psMetadataLookupStr(&status, config->args, "-exp_name");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_name");
-        return false;
-    }
-    if (!exp_name) {
-        psError(PS_ERR_UNKNOWN, true, "-exp_name is required");
-        return false;
-    }
-
-    psString camera = psMetadataLookupStr(&status, config->args, "-inst");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -inst");
-        return false;
-    }
-    if (!camera) {
-        psError(PS_ERR_UNKNOWN, true, "-inst is required");
-        return false;
-    }
-
-    psString telescope = psMetadataLookupStr(&status, config->args, "-telescope");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -telescope");
-        return false;
-    }
-    if (!telescope) {
-        psError(PS_ERR_UNKNOWN, true, "-telescope 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;
-    }
-
-    // optional
-    psString exp_type = psMetadataLookupStr(&status, config->args, "-exp_type");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_type");
-        return false;
-    }
-
-    psString filelevel = psMetadataLookupStr(&status, config->args, "-filelevel");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filelevel");
-        return false;
-    }
-    if (!filelevel) {
-        psError(PS_ERR_UNKNOWN, true, "-filelevel is required");
-        return false;
-    }
-
-    psString workdir = psMetadataLookupStr(&status, config->args, "-workdir");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -workdir");
-        return false;
-    }
-
-    psString reduction = psMetadataLookupStr(&status, config->args, "-reduction");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -reduction");
-        return false;
-    }
-
-    psString filter = psMetadataLookupStr(&status, config->args, "-filter");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
-        return false;
-    }
-
-    psString comment = psMetadataLookupStr(&status, config->args, "-comment");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -comment");
-        return false;
-    }
-
-    psF32 airmass = psMetadataLookupF32(&status, config->args, "-airmass");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass");
-        return false;
-    }
-
-    psF64 ra = psMetadataLookupF64(&status, config->args, "-ra");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ra");
-        return false;
-    }
-
-    psF64 decl = psMetadataLookupF64(&status, config->args, "-decl");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -decl");
-        return false;
-    }
-
-    psF32 exp_time = psMetadataLookupF32(&status, config->args, "-exp_time");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time");
-        return false;
-    }
-
-    psF32 sat_pixel_frac = psMetadataLookupF32(&status, config->args, "-sat_pixel_frac");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -sat_pixel_frac");
-        return false;
-    }
-
-    psF64 bg = psMetadataLookupF64(&status, config->args, "-bg");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -bg");
-        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;
-    }
-
-    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;
-    }
-
-    psF64 alt = psMetadataLookupF64(&status, config->args, "-alt");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -alt");
-        return false;
-    }
-
-    psF64 az = psMetadataLookupF64(&status, config->args, "-az");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -az");
-        return false;
-    }
-
-    psF32 ccd_temp = psMetadataLookupF32(&status, config->args, "-ccd_temp");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ccd_temp");
-        return false;
-    }
-
-    psF64 posang = psMetadataLookupF32(&status, config->args, "-posang");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -posang");
-        return false;
-    }
-
-    psF32 m1_x = psMetadataLookupF32(&status, config->args, "-m1_x");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_x");
-        return false;
-    }
-    psF32 m1_y = psMetadataLookupF32(&status, config->args, "-m1_y");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_y");
-        return false;
-    }
-    psF32 m1_z = psMetadataLookupF32(&status, config->args, "-m1_z");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_z");
-        return false;
-    }
-    psF32 m1_tip = psMetadataLookupF32(&status, config->args, "-m1_tip");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_tip");
-        return false;
-    }
-    psF32 m1_tilt = psMetadataLookupF32(&status, config->args, "-m1_tilt");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m1_tilt");
-        return false;
-    }
-
-    psF32 m2_x = psMetadataLookupF32(&status, config->args, "-m2_x");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_x");
-        return false;
-    }
-    psF32 m2_y = psMetadataLookupF32(&status, config->args, "-m2_y");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_y");
-        return false;
-    }
-    psF32 m2_z = psMetadataLookupF32(&status, config->args, "-m2_z");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_z");
-        return false;
-    }
-    psF32 m2_tip = psMetadataLookupF32(&status, config->args, "-m2_tip");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_tip");
-        return false;
-    }
-    psF32 m2_tilt = psMetadataLookupF32(&status, config->args, "-m2_tilt");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -m2_tilt");
-        return false;
-    }
-
-    psF32 env_temp = psMetadataLookupF32(&status, config->args, "-env_temperature");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_temperature");
-        return false;
-    }
-    psF32 env_humid = psMetadataLookupF32(&status, config->args, "-env_humidity");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_humidity");
-        return false;
-    }
-    psF32 env_wind = psMetadataLookupF32(&status, config->args, "-env_wind_speed");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_wind_speed");
-        return false;
-    }
-    psF32 env_dir = psMetadataLookupF32(&status, config->args, "-env_wind_dir");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -env_wind_dir");
-        return false;
-    }
-
-    psF32 teltemp_m1 = psMetadataLookupF32(&status, config->args, "-teltemp_m1");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_m1");
-        return false;
-    }
-    psF32 teltemp_m1cell = psMetadataLookupF32(&status, config->args, "-teltemp_m1cell");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_m1cell");
-        return false;
-    }
-    psF32 teltemp_m2 = psMetadataLookupF32(&status, config->args, "-teltemp_m2");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_m2");
-        return false;
-    }
-    psF32 teltemp_spider = psMetadataLookupF32(&status, config->args, "-teltemp_spider");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_spider");
-        return false;
-    }
-    psF32 teltemp_truss = psMetadataLookupF32(&status, config->args, "-teltemp_truss");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_truss");
-        return false;
-    }
-    psF32 teltemp_extra = psMetadataLookupF32(&status, config->args, "-teltemp_extra");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -teltemp_extra");
-        return false;
-    }
-
-    psF32 pon_time = psMetadataLookupF32(&status, config->args, "-pon_time");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -pon_time");
-        return false;
-    }
-
-    psF64 user_1 = psMetadataLookupF64(&status, config->args, "-user_1");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_1");
-        return false;
-    }
-    psF64 user_2 = psMetadataLookupF64(&status, config->args, "-user_2");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_2");
-        return false;
-    }
-    psF64 user_3 = psMetadataLookupF64(&status, config->args, "-user_3");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_3");
-        return false;
-    }
-    psF64 user_4 = psMetadataLookupF64(&status, config->args, "-user_4");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_4");
-        return false;
-    }
-    psF64 user_5 = psMetadataLookupF64(&status, config->args, "-user_5");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -user_5");
-        return false;
-    }
-
-    psString object = psMetadataLookupStr(&status, config->args, "-object");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -object");
-        return false;
-    }
-
-    psTime *dateobs = NULL;
-    {
-        psString dateobsStr = psMetadataLookupStr(&status, config->args, "-dateobs");
-        if (!status) {
-            psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -dateobs");
-            return false;
-        }
-        // pass through NULL as this is an optional field
-        if (dateobsStr) {
-            dateobs = psTimeFromISO(dateobsStr, PS_TIME_UTC);
-        } else {
-            dateobs = NULL;
-        }
-    }
-
-    // default
-    psS16 code = psMetadataLookupS16(&status, config->args, "-code");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -code");
-        return false;
-    }
-
-    rawExpRow *raw = rawExpRowAlloc(
-        exp->exp_id,
+    // carry through these values
+    // new CLI options overwrite existing values
+    workdir   = workdir ? workdir : newExp->workdir;
+    reduction = reduction ? reduction : newExp->reduction;
+    dvodb     = dvodb ? dvodb : newExp->dvodb;
+    tess_id   = tess_id ? tess_id : newExp->tess_id;
+    end_stage = end_stage ? end_stage : newExp->end_stage;
+
+    psFree(newExp);
+
+    if (!rawExpInsert(config->dbh,
+        (psS64)atoll(exp_id),
         exp_name,
         camera,
@@ -1541,8 +640,11 @@
         exp_type,
         filelevel,
-        workdir ? workdir : exp->workdir,
-        reduction ? reduction : exp->reduction,
+        workdir,
+        reduction,
+        dvodb,
+        tess_id,
+        end_stage,
         filter,
-	comment,
+        comment,
         airmass,
         ra,
@@ -1557,25 +659,25 @@
         ccd_temp,
         posang,
-	m1_x,
-	m1_y,
-	m1_z,
-	m1_tip,
-	m1_tilt,
-	m2_x,
-	m2_y,
-	m2_z,
-	m2_tip,
-	m2_tilt,
-	env_temp,
-	env_humid,
-	env_wind,
-	env_dir,
-	teltemp_m1,
-	teltemp_m1cell,
-	teltemp_m2,
-	teltemp_spider,
-	teltemp_truss,
-	teltemp_extra,
-	pon_time,
+        m1_x,
+        m1_y,
+        m1_z,
+        m1_tip,
+        m1_tilt,
+        m2_x,
+        m2_y,
+        m2_z,
+        m2_tip,
+        m2_tilt,
+        env_temp,
+        env_humid,
+        env_wind,
+        env_dir,
+        teltemp_m1,
+        teltemp_m1cell,
+        teltemp_m2,
+        teltemp_spider,
+        teltemp_truss,
+        teltemp_extra,
+        pon_time,
         user_1,
         user_2,
@@ -1586,10 +688,183 @@
         0.0,
         code
-    );
-
-    if (dateobs) {
-        psFree(dateobs);
-    }
-
-    return raw;
-}
+    )) {
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    // set the state for the newExp to stop
+    if (!pxnewExpSetState(config, exp_id, "stop")) {
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psError(PS_ERR_UNKNOWN, false, "failed to change newExp.state for exp_id: %s", exp_id);
+        return false;
+    }
+
+    // should we stop here and proceed on to the chip stage?
+    if (psStrcasestr(end_stage, "reg")) {
+        // then we are done here
+        if (!psDBCommit(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            return false;
+        }
+
+        return true;
+    }
+    // else continue on...
+
+
+    // insert an entry into the chipPendingExp table
+    // this can only be run as the newExp's state has been set to stop
+    if (!pxchipQueueByExpTag(config,
+                (psS64)atoll(exp_id),
+                workdir,
+                NULL, // label
+                reduction,
+                NULL, // expgroup
+                dvodb,
+                tess_id,
+                end_stage
+    )) {
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
+        psError(PS_ERR_UNKNOWN, false, "failed to queue chipPendingExp");
+        return false;
+    }
+
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+
+    return true;
+}
+
+
+static bool processedexpMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_BOOL(faulted, config->args, "-faulted", false);
+
+    psString query = pxDataGet("regtool_processedexp.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (config->where) {
+        psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawExp");
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+
+    if (faulted) {
+        // list only faulted rows
+        psStringAppend(&query, " %s", "AND rawExp.fault != 0");
+    } else {
+        // don't list faulted rows
+        psStringAppend(&query, " %s", "AND rawExp.fault = 0");
+    }
+
+    // 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");
+        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("regtool", PS_LOG_INFO, "no rows found");
+        psFree(output);
+        return true;
+    }
+
+    if (psArrayLength(output)) {
+        // negative simple so the default is true
+        if (!ippdbPrintMetadatas(stdout, output, "rawExp", !simple)) {
+            psError(PS_ERR_UNKNOWN, false, "failed to print array");
+            psFree(output);
+            return false;
+        }
+    }
+
+    psFree(output);
+
+    return true;
+}
+
+static bool revertprocessedexpMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psString query = pxDataGet("regtool_revertprocessedexp.sql");
+    if (!query) {
+        psError(PXTOOLS_ERR_DATA, false, "failed to retreive SQL statement");
+        return false;
+    }
+
+    if (config->where) {
+        psString whereClause = psDBGenerateWhereConditionSQL(config->where, "rawExp");
+        psStringAppend(&query, " AND %s", whereClause);
+        psFree(whereClause);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    if (psDBAffectedRows(config->dbh) < 1) {
+        psError(PS_ERR_UNKNOWN, false, "should have affected atleast 1 row");
+        return false;
+    }
+
+    return true;
+}
+
+
+static bool updateprocessedexpMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_S16(code, config->args, "-code", true, false);
+
+    if (!pxSetFaultCode(config->dbh, "rawExp", config->where, code)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to set set fault flag");
+        return false;
+    }
+
+    return true;
+}
