Index: /trunk/ippTools/src/chiptool.c
===================================================================
--- /trunk/ippTools/src/chiptool.c	(revision 8119)
+++ /trunk/ippTools/src/chiptool.c	(revision 8120)
@@ -241,15 +241,16 @@
     psFree(pendingImfiles);
 
-    // point of no return for p2PendingImfile -> p2DoneImfile 
-    if (!psDBCommit(config->dbh)) {
-        psError(PS_ERR_UNKNOWN, false, "database error");
-        return false;
-    }
-
-    // XXX make exposure state transition transactional
+    // XXX I've decided to make the transaction cover the Exp migration as
+    // well.  Otherwise, if the last imfile in an exp is moved and the exp
+    // migration fails then the data base is left in a satuation where the exp
+    // migration can't happen.
 
     // look for pending exposures
     psArray *pendingExps = p2searchPendingExp(config);
     if (!pendingExps) {
+        // rollback
+        if (!psDBRollback(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+        }
         psError(PS_ERR_UNKNOWN, false, "no p2PendingExps found");
         return false;
@@ -265,29 +266,52 @@
         if (!pendingImfiles) {
             // exp has no coresponding imfiles
-            psArray *nukeMe = psArrayAlloc(1);
-            nukeMe->n = 0;
-            psArrayAdd(nukeMe, 0, pendingExp);
-            bool status = p2PendingExpDeleteRowObjects(config->dbh, nukeMe, MAX_ROWS);
-            psFree(nukeMe);
-            if (!status) {
+            psMetadata *where = psMetadataAlloc();
+            psMetadataAddStr(where, PS_LIST_TAIL, "exp_id", 0, "==", pendingExp->exp_id);
+            long long count = p2PendingExpDelete(config->dbh, where, MAX_ROWS);
+            psFree(where);
+            if (count != 0) {
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
                 psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+                psFree(pendingExps);
                 return false;
             }
-            // XXX need a func to convert from p2PendingExp -> p2DoneExp
 
             p2DoneExpRow *doneExp = p2pendingToDoneExp(pendingExp);
             if (!doneExp) {
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
                 psError(PS_ERR_UNKNOWN, false, "p2PendingExp -> p2DoneExp failed");
+                psFree(pendingExps);
                 return false;
             }
             if (!p2DoneExpInsertObject(config->dbh, doneExp)) {
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
                 psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+                psFree(doneExp);
+                psFree(pendingExps);
                 return false;
             }
-        }
-        // skip phase 3 for the time being
+            psFree(doneExp);
+        }
+        // XXX skip phase 3 for the time being
         psFree(pendingImfiles);
     }
 
+    psFree(pendingExps);
+
+    // point of no return for p2PendingImfile -> p2DoneImfile 
+    // point of no return for p2PendingExp -> p2DoneExp
+    if (!psDBCommit(config->dbh)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
     /*
     psArray *doneFrames = p2pendingToDone(config, pendingFrames);
@@ -328,5 +352,4 @@
         uri,
         "my recipe", // recipe
-        "my stats", // stats
         imfile->p1_version,
         imfile->p2_version
Index: /trunk/ippTools/src/dettool.c
===================================================================
--- /trunk/ippTools/src/dettool.c	(revision 8119)
+++ /trunk/ippTools/src/dettool.c	(revision 8120)
@@ -422,5 +422,9 @@
         rawExp->imfiles,
         rawExp->filter,
-        rawExp->stats
+        rawExp->airmass,
+        rawExp->ra,
+        rawExp->decl,
+        rawExp->exp_time,
+        rawExp->background
     );
 }
@@ -604,13 +608,4 @@
         return false;
     }
-    psString stats = psMetadataLookupStr(&status, config->args, "-stats");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -stats");
-        return false;
-    }
-    if (!stats) {
-        psError(PS_ERR_UNKNOWN, true, "-stats is required");
-        return false;
-    }
     psString recipe = psMetadataLookupStr(&status, config->args, "-recip");
     if (!status) {
@@ -645,5 +640,5 @@
     // create a new detProcessedImfile object
     detProcessedImfileRow *detRow = detProcessedImfileRowAlloc(
-        (psS32)atol(det_id), exp_id, class_id, uri, stats, recipe
+        (psS32)atol(det_id), exp_id, class_id, uri, recipe
     );   
     psFree(rawImfiles);
@@ -921,5 +916,5 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    // det_id, class_id, uri, stats, & recipe are required
+    // det_id, class_id, uri, & recipe are required
     bool status = false;
     psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");
@@ -948,13 +943,4 @@
     if (!uri) {
         psError(PS_ERR_UNKNOWN, true, "-uri is required");
-        return false;
-    }
-    psString stats = psMetadataLookupStr(&status, config->args, "-stats");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -stats");
-        return false;
-    }
-    if (!stats) {
-        psError(PS_ERR_UNKNOWN, true, "-stats is required");
         return false;
     }
@@ -1010,5 +996,5 @@
     // create a new detStackedImfile object
     detStackedImfileRow *stackedImfile = detStackedImfileRowAlloc(
-        (psS32)atol(det_id), iteration, class_id, uri, stats, recipe
+        (psS32)atol(det_id), iteration, class_id, uri, recipe
     );   
 
@@ -1270,5 +1256,5 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
  
-    // det_id, class_id, uri, stats, & recipe are required
+    // det_id, class_id, uri, & recipe are required
     bool status = false;
     psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");
@@ -1297,13 +1283,4 @@
     if (!uri) {
         psError(PS_ERR_UNKNOWN, true, "-uri is required");
-        return false;
-    }
-    psString stats = psMetadataLookupStr(&status, config->args, "-stats");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -stats");
-        return false;
-    }
-    if (!stats) {
-        psError(PS_ERR_UNKNOWN, true, "-stats is required");
         return false;
     }
@@ -1367,5 +1344,5 @@
     // create a new detNormalizedImfile object
     detNormalizedImfileRow *masterImfile = detNormalizedImfileRowAlloc(
-        (psS32)atol(det_id), iteration, class_id, uri, stats, recipe
+        (psS32)atol(det_id), iteration, class_id, uri, recipe
     );   
 
@@ -1541,5 +1518,5 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
 
-    // det_id, exp_id, class_id, stats, & recipe are required
+    // det_id, exp_id, class_id, & recipe are required
     bool status = false;
     psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");
@@ -1568,13 +1545,4 @@
     if (!class_id) {
         psError(PS_ERR_UNKNOWN, true, "-class_id is required");
-        return false;
-    }
-    psString stats = psMetadataLookupStr(&status, config->args, "-stats");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -stats");
-        return false;
-    }
-    if (!stats) {
-        psError(PS_ERR_UNKNOWN, true, "-stats is required");
         return false;
     }
@@ -1649,5 +1617,4 @@
                 exp_id,
                 class_id,
-                stats,
                 recipe
             );
@@ -1704,5 +1671,5 @@
     PS_ASSERT_PTR_NON_NULL(config, false);
  
-    // det_id, exp_id, stats, & recipe are required
+    // det_id, exp_id,  & recipe are required
     bool status = false;
     psString det_id = psMetadataLookupStr(&status, config->args, "-det_id");
@@ -1722,13 +1689,4 @@
     if (!exp_id) {
         psError(PS_ERR_UNKNOWN, true, "-exp_id is required");
-        return false;
-    }
-    psString stats = psMetadataLookupStr(&status, config->args, "-stats");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -stats");
-        return false;
-    }
-    if (!stats) {
-        psError(PS_ERR_UNKNOWN, true, "-stats is required");
         return false;
     }
@@ -1789,5 +1747,4 @@
                 iteration,
                 exp_id,
-                stats,
                 recipe,
                 accept
@@ -2099,5 +2056,9 @@
             inputExp->imfiles,
             inputExp->filter,
-            inputExp->stats
+            inputExp->airmass,
+            inputExp->ra,
+            inputExp->decl,
+            inputExp->exp_time,
+            inputExp->background
         );
         psArrayAdd(newInputExps, 0, newInputExp);
Index: /trunk/ippTools/src/dettoolConfig.c
===================================================================
--- /trunk/ippTools/src/dettoolConfig.c	(revision 8119)
+++ /trunk/ippTools/src/dettoolConfig.c	(revision 8120)
@@ -79,6 +79,4 @@
     psMetadataAddStr(addprocArgs, PS_LIST_TAIL, "-uri",  0,
         "define URI (required)", NULL);
-    psMetadataAddStr(addprocArgs, PS_LIST_TAIL, "-stats",  0,
-        "define stat (required)", NULL);
     psMetadataAddStr(addprocArgs, PS_LIST_TAIL, "-recip",  0,
         "define recipe (required)", NULL);
@@ -111,6 +109,4 @@
     psMetadataAddStr(addstacArgs, PS_LIST_TAIL, "-uri",  0,
         "define URI (required)", NULL);
-    psMetadataAddStr(addstacArgs, PS_LIST_TAIL, "-stats",  0,
-        "define stat (required)", NULL);
     psMetadataAddStr(addstacArgs, PS_LIST_TAIL, "-recip",  0,
         "define recipe (required)", NULL);
@@ -124,6 +120,4 @@
     psMetadataAddStr(stacArgs, PS_LIST_TAIL, "-class_id",  0,
         "search for class ID", NULL);
-    psMetadataAddStr(stacArgs, PS_LIST_TAIL, "-stats",  0,
-        "search for stats", NULL);
     psMetadataAddStr(stacArgs, PS_LIST_TAIL, "-recip",  0,
         "search for recipe", NULL);
@@ -137,6 +131,4 @@
     psMetadataAddStr(stacframeArgs, PS_LIST_TAIL, "-class_id",  0,
         "search for class ID", NULL);
-    psMetadataAddStr(stacframeArgs, PS_LIST_TAIL, "-stats",  0,
-        "search for stats", NULL);
     psMetadataAddStr(stacframeArgs, PS_LIST_TAIL, "-recip",  0,
         "search for recipe", NULL);
@@ -152,6 +144,4 @@
     psMetadataAddStr(addnormalizedArgs, PS_LIST_TAIL, "-uri",  0,
         "define URI (required)", NULL);
-    psMetadataAddStr(addnormalizedArgs, PS_LIST_TAIL, "-stats",  0,
-        "define stat (required)", NULL);
     psMetadataAddStr(addnormalizedArgs, PS_LIST_TAIL, "-recip",  0,
         "define recipe (required)", NULL);
@@ -165,6 +155,4 @@
     psMetadataAddStr(normalizedArgs, PS_LIST_TAIL, "-class_id",  0,
         "search for class ID", NULL);
-    psMetadataAddStr(normalizedArgs, PS_LIST_TAIL, "-stats",  0,
-        "search for stats", NULL);
     psMetadataAddStr(normalizedArgs, PS_LIST_TAIL, "-recip",  0,
         "search for recipe", NULL);
@@ -178,6 +166,4 @@
     psMetadataAddStr(normalizedframeArgs, PS_LIST_TAIL, "-class_id",  0,
         "search for class ID", NULL);
-    psMetadataAddStr(normalizedframeArgs, PS_LIST_TAIL, "-stats",  0,
-        "search for stats", NULL);
     psMetadataAddStr(normalizedframeArgs, PS_LIST_TAIL, "-recip",  0,
         "search for recipe", NULL);
@@ -193,6 +179,4 @@
     psMetadataAddStr(addresidArgs, PS_LIST_TAIL, "-class_id",  0,
         "define class ID (required)", NULL);
-    psMetadataAddStr(addresidArgs, PS_LIST_TAIL, "-stats",  0,
-        "define stats (required)", NULL);
     psMetadataAddStr(addresidArgs, PS_LIST_TAIL, "-recip",  0,
         "define recipe (required)", NULL);
@@ -208,6 +192,4 @@
     psMetadataAddStr(residArgs, PS_LIST_TAIL, "-class_id",  0,
         "search for class ID", NULL);
-    psMetadataAddStr(residArgs, PS_LIST_TAIL, "-stats",  0,
-        "search for stats", NULL);
     psMetadataAddStr(residArgs, PS_LIST_TAIL, "-recip",  0,
         "search for recipe", NULL);
@@ -221,6 +203,4 @@
     psMetadataAddStr(addresidexpArgs, PS_LIST_TAIL, "-exp_id",  0,
         "define detrend ID (required)", NULL);
-    psMetadataAddStr(addresidexpArgs, PS_LIST_TAIL, "-stats",  0,
-        "define stats (required)", NULL);
     psMetadataAddStr(addresidexpArgs, PS_LIST_TAIL, "-recip",  0,
         "define recipe (required)", NULL);
@@ -236,6 +216,4 @@
     psMetadataAddStr(residexpArgs, PS_LIST_TAIL, "-exp_id",  0,
         "search for exp ID", NULL);
-    psMetadataAddStr(residexpArgs, PS_LIST_TAIL, "-stats",  0,
-        "search for stats", NULL);
     psMetadataAddStr(residexpArgs, PS_LIST_TAIL, "-recip",  0,
         "search for recipe", NULL);
@@ -468,5 +446,4 @@
     }
     addWhereStr(filter);
-    addWhereStr(stats);
     addWhereStr(recipe);
     {
Index: /trunk/ippTools/src/guidetool.c
===================================================================
--- /trunk/ippTools/src/guidetool.c	(revision 8119)
+++ /trunk/ippTools/src/guidetool.c	(revision 8120)
@@ -10,5 +10,5 @@
 static bool pendingMode(pxConfig *config);
 static bool defineMode(pxConfig *config);
-static p1PendingExpRow *rawScienceTop1PendingExp(pxConfig *config, rawScienceExpRow *raw);
+static p1PendingExpRow *rawScienceTop1PendingExp(pxConfig *config, rawScienceExpRow *exp);
 
 int main(int argc, char **argv)
@@ -104,17 +104,79 @@
 }
 
-static p1PendingExpRow *rawScienceTop1PendingExp(pxConfig *config, rawScienceExpRow *raw)
+static p1PendingExpRow *rawScienceTop1PendingExp(pxConfig *config, rawScienceExpRow *exp)
 {
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(exp, NULL);
+
+    bool status = false;
+    psString filter = psMetadataLookupStr(&status, config->args, "-filter");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
+        return false;
+    }
+    if (!filter) {
+        psError(PS_ERR_UNKNOWN, true, "-filter is required");
+        return false;
+    }
+    psF32 airmass = psMetadataLookupF32(&status, config->args, "-airmass");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass");
+        return false;
+    }
+    if (!airmass) {
+        psError(PS_ERR_UNKNOWN, true, "-airmass is required");
+        return false;
+    }
+    psF64 ra = psMetadataLookupF64(&status, config->args, "-ra");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ra");
+        return false;
+    }
+    if (!ra) {
+        psError(PS_ERR_UNKNOWN, true, "-airmass is required");
+        return false;
+    }
+    psF64 dec = psMetadataLookupF64(&status, config->args, "-dec");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -dec");
+        return false;
+    }
+    if (!dec) {
+        psError(PS_ERR_UNKNOWN, true, "-dec is required");
+        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;
+    }
+    if (!exp_time) {
+        psError(PS_ERR_UNKNOWN, true, "-exp_time is required");
+        return false;
+    }
+    psF64 background = psMetadataLookupF64(&status, config->args, "-background");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -background");
+        return false;
+    }
+    if (!exp_time) {
+        psError(PS_ERR_UNKNOWN, true, "-background is required");
+        return false;
+    }
+
     return p1PendingExpRowAlloc(
-        raw->exp_id,
-        raw->camera,
-        raw->telescope,
-        raw->exp_type,
-//        newExp->class,
-        raw->imfiles,
-        raw->filter,
-        raw->stats,
-        "my recipe",                    //recipe
-        0xff                            // XXX calc version number
+        exp->exp_id,
+        exp->camera,
+        exp->telescope,
+        exp->exp_type,
+        exp->imfiles,
+        filter,
+        airmass,
+        ra,
+        dec,
+        exp_time,
+        background,
+        "my recipe",
+        0xff // XXX calc version number
     );
 }
Index: /trunk/ippTools/src/guidetoolConfig.c
===================================================================
--- /trunk/ippTools/src/guidetoolConfig.c	(revision 8119)
+++ /trunk/ippTools/src/guidetoolConfig.c	(revision 8120)
@@ -43,6 +43,4 @@
     psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-filter",  0,
         "define filter of interest", NULL);
-    psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-stats",  0,
-        "define stats of interest", NULL);
     psMetadataAddStr(pendingArgs, PS_LIST_TAIL, "-recipe",  0,
         "define recipe of interest", NULL);
@@ -64,6 +62,4 @@
     psMetadataAddStr(defineArgs, PS_LIST_TAIL, "-filter",  0,
         "define filter of interest", NULL);
-    psMetadataAddStr(defineArgs, PS_LIST_TAIL, "-stats",  0,
-        "define stats of interest", NULL);
     // these two are inputs NOT search parameters
     psMetadataAddStr(defineArgs, PS_LIST_TAIL, "-recipe",  0,
Index: /trunk/ippTools/src/p2insertPendingFrames.c
===================================================================
--- /trunk/ippTools/src/p2insertPendingFrames.c	(revision 8119)
+++ /trunk/ippTools/src/p2insertPendingFrames.c	(revision 8120)
@@ -44,8 +44,11 @@
             rawFrame->exposure->telescope,
             rawFrame->exposure->exp_type,
-//            rawFrame->exposure->class,
             rawFrame->exposure->imfiles,
             rawFrame->exposure->filter,
-            rawFrame->exposure->stats,
+            rawFrame->exposure->airmass,
+            rawFrame->exposure->ra,
+            rawFrame->exposure->decl,
+            rawFrame->exposure->exp_time,
+            rawFrame->exposure->background,
             "my recipe",
             0xff,
@@ -62,5 +65,4 @@
                 rawImage->class_id,
                 rawImage->uri,
-                "my stats",
                 "my recipe",
                 0xff, // p1
Index: /trunk/ippTools/src/p2pendingToDone.c
===================================================================
--- /trunk/ippTools/src/p2pendingToDone.c	(revision 8119)
+++ /trunk/ippTools/src/p2pendingToDone.c	(revision 8120)
@@ -22,8 +22,11 @@
             pendingFrame->exposure->telescope,
             pendingFrame->exposure->exp_type,
-//            pendingFrame->exposure->class,
             pendingFrame->exposure->imfiles,
             pendingFrame->exposure->filter,
-            pendingFrame->exposure->stats,
+            pendingFrame->exposure->airmass,
+            pendingFrame->exposure->ra,
+            pendingFrame->exposure->decl,
+            pendingFrame->exposure->exp_time,
+            pendingFrame->exposure->background,
             "my recipe",
             pendingFrame->exposure->p1_version,
@@ -46,5 +49,4 @@
                 pendingImage->class_id,
                 pendingImage->uri,
-                "my stats", // stats
                 "my recipe", // recipe
                 pendingImage->p1_version,
@@ -73,8 +75,11 @@
         pendingExp->telescope,
         pendingExp->exp_type,
-//        pendingExp->class,
         pendingExp->imfiles, // XXX ndone is uneeded?
         pendingExp->filter,
-        pendingExp->stats,
+        pendingExp->airmass,
+        pendingExp->ra,
+        pendingExp->decl,
+        pendingExp->exp_time,
+        pendingExp->background,
         "my recipe",
         pendingExp->p1_version,
Index: /trunk/ippTools/src/p2rawToPending.c
===================================================================
--- /trunk/ippTools/src/p2rawToPending.c	(revision 8119)
+++ /trunk/ippTools/src/p2rawToPending.c	(revision 8120)
@@ -21,8 +21,11 @@
             rawFrame->exposure->telescope,
             rawFrame->exposure->exp_type,
-//            rawFrame->exposure->class,
             rawFrame->exposure->imfiles,
             rawFrame->exposure->filter,
-            rawFrame->exposure->stats,
+            rawFrame->exposure->airmass,
+            rawFrame->exposure->ra,
+            rawFrame->exposure->decl,
+            rawFrame->exposure->exp_time,
+            rawFrame->exposure->background,
             "my recipe",
             0xff,   // p1
@@ -38,5 +41,4 @@
                 rawImage->class_id,
                 rawImage->uri,
-                "my stats",      // stats
                 "my recipe",     // recipe
                 0xff,   // p1
Index: /trunk/ippTools/src/pxframes.c
===================================================================
--- /trunk/ippTools/src/pxframes.c	(revision 8119)
+++ /trunk/ippTools/src/pxframes.c	(revision 8120)
@@ -6,4 +6,6 @@
 
 #include "pxtools.h"
+
+static rawDetrendExpRow *newToRawDetrendExp(pxConfig *config, newExpRow *exp);
 
 #define PX_FRAME_ALLOC(frametype, exptype) \
@@ -77,5 +79,5 @@
 PX_FRAME_PRINT(p2PendingFrame, p2PendingImfile);
 
-
+// XXX fix the exposure search so that it doesn't dump the entire table
 #define PX_FRAME_SEARCH(frametype, exptype, imfiletype) \
 psArray *frametype##Search(pxConfig *config) \
@@ -83,6 +85,5 @@
     PS_ASSERT_PTR_NON_NULL(config, NULL); \
  \
-    psArray *exposures = exptype##SelectRowObjects(config->dbh, \
-        config->where, MAX_ROWS); \
+    psArray *exposures = exptype##SelectRowObjects(config->dbh, NULL, MAX_ROWS); \
     if (!exposures) { \
         psError(PS_ERR_UNKNOWN, false, "no " #exptype " rows found"); \
@@ -131,19 +132,37 @@
 PX_FRAME_SEARCH(p2PendingFrame, p2PendingExp, p2PendingImfile);
 
-rawScienceFrame *newToRawScienceFrame(newFrame *newFrame) 
-{
+
+bool rawScienceFrameInsert(pxConfig *config, rawScienceFrame *frame)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+    PS_ASSERT_PTR_NON_NULL(config->dbh, false);
+    PS_ASSERT_PTR_NON_NULL(frame, false);
+
+    psDB *dbh = config->dbh;
+
+    if (!rawScienceExpInsertObject(dbh, frame->exposure)) {
+        psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+        return false;
+    }
+
+    psArray *images = frame->images;
+    for (long i = 0; i < psArrayLength(images); i++) {
+        if (!rawImfileInsertObject(dbh, images->data[i])) {
+            psError(PS_ERR_UNKNOWN, false, "dbh access failed");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+rawDetrendFrame *newToRawDetrendFrame(pxConfig *config, newFrame *newFrame) 
+{
+    newExpRow       *newExp = NULL;
+
     PS_ASSERT_PTR_NON_NULL(newFrame, NULL);
 
-    newExpRow *newExp = newFrame->exposure;
-    rawScienceExpRow *rawScienceExp = rawScienceExpRowAlloc(
-        newExp->exp_id,
-        newExp->camera,
-        newExp->telescope,
-        newExp->exp_type,
-//        newExp->class,
-        newExp->imfiles,
-        "my filter",
-        "my stats"
-    );
+    newExp = newFrame->exposure;
+    rawDetrendExpRow *rawDetrendExp = newToRawDetrendExp(config, newExp);
 
     psArray *newImages = newFrame->images;
@@ -155,6 +174,5 @@
             newImfile->class,
             newImfile->class_id,
-            newImfile->uri,
-            "my stats"
+            newImfile->uri
         );
         psArrayAdd(rawImages, 0, rawImfile);
@@ -162,12 +180,12 @@
     }
 
-    rawScienceFrame *rawScienceFrame = rawScienceFrameAlloc(rawScienceExp, rawImages);
-    psFree(rawScienceExp);
+    rawDetrendFrame *rawDetrendFrame = rawDetrendFrameAlloc(rawDetrendExp, rawImages);
+    psFree(rawDetrendExp);
     psFree(rawImages);
 
-    return rawScienceFrame;
-}
-
-bool rawScienceFrameInsert(pxConfig *config, rawScienceFrame *frame)
+    return rawDetrendFrame;
+}
+
+bool rawDetrendFrameInsert(pxConfig *config, rawDetrendFrame *frame)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
@@ -177,5 +195,5 @@
     psDB *dbh = config->dbh;
 
-    if (!rawScienceExpInsertObject(dbh, frame->exposure)) {
+    if (!rawDetrendExpInsertObject(dbh, frame->exposure)) {
         psError(PS_ERR_UNKNOWN, false, "dbh access failed");
         return false;
@@ -193,65 +211,77 @@
 }
 
-rawDetrendFrame *newToRawDetrendFrame(newFrame *newFrame) 
-{
-    newExpRow       *newExp = NULL;
-
-    PS_ASSERT_PTR_NON_NULL(newFrame, NULL);
-
-    newExp = newFrame->exposure;
-    rawDetrendExpRow *rawDetrendExp = rawDetrendExpRowAlloc(
-        newExp->exp_id,
-        newExp->camera,
-        newExp->telescope,
-        newExp->exp_type,
-//        newExp->class,
-        newExp->imfiles,
-        "my filter",
-        "my stats"
+static rawDetrendExpRow *newToRawDetrendExp(pxConfig *config, newExpRow *exp)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(exp, NULL);
+
+    bool status = false;
+    psString filter = psMetadataLookupStr(&status, config->args, "-filter");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
+        return false;
+    }
+    if (!filter) {
+        psError(PS_ERR_UNKNOWN, true, "-filter is required");
+        return false;
+    }
+    psF32 airmass = psMetadataLookupF32(&status, config->args, "-airmass");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass");
+        return false;
+    }
+    if (isnan(airmass)) {
+        psError(PS_ERR_UNKNOWN, true, "-airmass is required");
+        return false;
+    }
+    psF64 ra = psMetadataLookupF64(&status, config->args, "-ra");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ra");
+        return false;
+    }
+    if (isnan(ra)) {
+        psError(PS_ERR_UNKNOWN, true, "-airmass is required");
+        return false;
+    }
+    psF64 decl = psMetadataLookupF64(&status, config->args, "-decl");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -decl");
+        return false;
+    }
+    if (isnan(decl)) {
+        psError(PS_ERR_UNKNOWN, true, "-decl is required");
+        return false;
+    }
+    psF32 exp_time = psMetadataLookupF32(&status, config->args, "-exp_time");
+    if (isnan(exp_time)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time");
+        return false;
+    }
+    if (!exp_time) {
+        psError(PS_ERR_UNKNOWN, true, "-exp_time is required");
+        return false;
+    }
+    psF64 background = psMetadataLookupF64(&status, config->args, "-background");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -background");
+        return false;
+    }
+    if (!exp_time) {
+        psError(PS_ERR_UNKNOWN, true, "-background is required");
+        return false;
+    }
+
+    return rawDetrendExpRowAlloc(
+        exp->exp_id,
+        exp->camera,
+        exp->telescope,
+        exp->exp_type,
+        exp->imfiles,
+        filter,
+        airmass,
+        ra,
+        decl,
+        exp_time,
+        background
     );
-
-    psArray *newImages = newFrame->images;
-    psArray *rawImages = psArrayAlloc(psArrayLength(newImages));
-    for (long i = 0; i < psArrayLength(newImages); i++) {
-        newImfileRow *newImfile = newImages->data[i];
-        rawImfileRow *rawImfile = rawImfileRowAlloc(
-            newImfile->exp_id,
-            newImfile->class,
-            newImfile->class_id,
-            newImfile->uri,
-            "my stats"
-        );
-        psArrayAdd(rawImages, 0, rawImfile);
-        psFree(rawImfile);
-    }
-
-    rawDetrendFrame *rawDetrendFrame = rawDetrendFrameAlloc(rawDetrendExp, rawImages);
-    psFree(rawDetrendExp);
-    psFree(rawImages);
-
-    return rawDetrendFrame;
-}
-
-bool rawDetrendFrameInsert(pxConfig *config, rawDetrendFrame *frame)
-{
-    PS_ASSERT_PTR_NON_NULL(config, false);
-    PS_ASSERT_PTR_NON_NULL(config->dbh, false);
-    PS_ASSERT_PTR_NON_NULL(frame, false);
-
-    psDB *dbh = config->dbh;
-
-    if (!rawDetrendExpInsertObject(dbh, frame->exposure)) {
-        psError(PS_ERR_UNKNOWN, false, "dbh access failed");
-        return false;
-    }
-
-    psArray *images = frame->images;
-    for (long i = 0; i < psArrayLength(images); i++) {
-        if (!rawImfileInsertObject(dbh, images->data[i])) {
-            psError(PS_ERR_UNKNOWN, false, "dbh access failed");
-            return false;
-        }
-    }
-
-    return true;
-}
+}
Index: /trunk/ippTools/src/pxtools.h
===================================================================
--- /trunk/ippTools/src/pxtools.h	(revision 8119)
+++ /trunk/ippTools/src/pxtools.h	(revision 8120)
@@ -131,7 +131,6 @@
 psArray *newFrameSearch(pxConfig *config);
 
-rawScienceFrame *newToRawScienceFrame(newFrame *newFrame);
 bool rawScienceFrameInsert(pxConfig *config, rawScienceFrame *frame);
-rawDetrendFrame *newToRawDetrendFrame(newFrame *newFrame);
+rawDetrendFrame *newToRawDetrendFrame(pxConfig *config, newFrame *newFrame);
 bool rawDetrendFrameInsert(pxConfig *config, rawDetrendFrame *frame);
 
Index: /trunk/ippTools/src/regtool.c
===================================================================
--- /trunk/ippTools/src/regtool.c	(revision 8119)
+++ /trunk/ippTools/src/regtool.c	(revision 8120)
@@ -12,6 +12,9 @@
 static psArray *newFrameSearchPending(pxConfig *config);
 static p1PendingExpRow *newToP1PendingExp(newExpRow *newExp);
-static p2PendingExpRow *newToP2PendingExp(newExpRow *newExp);
+static p2PendingExpRow *newToP2PendingExp(pxConfig *config, newExpRow *newExp);
 static p2PendingImfileRow *newImfileToP2PendingImfile(newImfileRow *newImfile);
+static rawScienceFrame *newToRawScienceFrame(pxConfig *config, newFrame *newFrame);
+static rawScienceExpRow *newToRawScienceExp(pxConfig *config, newExpRow *exp);
+
 
 # define MODECASE(caseName, func) \
@@ -89,9 +92,18 @@
     // insert 'new' rawScience & detrendframes
     if (psArrayLength(new) > 0) {
+        // start a transaction so we don't end up file raw* frames but no
+        // p2Pending*, etc.
+        if (!psDBTransaction(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            psFree(exp);
+            psFree(new);
+            return false;
+        }
+
         for (long i = 0; i < psArrayLength(new); i++) {
             newFrame *newFrame = new->data[i];
             if (detrend) {
                 // it's a detrend frame
-                rawDetrendFrame *frame = newToRawDetrendFrame(newFrame); 
+                rawDetrendFrame *frame = newToRawDetrendFrame(config, newFrame); 
                 if (!frame) {
                     psError(PS_ERR_UNKNOWN, false, "failed to convert new frame into a detrend frame");
@@ -100,4 +112,8 @@
                 }
                 if (!rawDetrendFrameInsert(config, frame)) {
+                    // rollback
+                    if (!psDBRollback(config->dbh)) {
+                        psError(PS_ERR_UNKNOWN, false, "database error");
+                    }
                     psError(PS_ERR_UNKNOWN, false, "failed to insert frame into the database");
                     psFree(frame);
@@ -112,6 +128,10 @@
             // it's a science frame
             // insert into into rawScienceExp
-            rawScienceFrame *frame = newToRawScienceFrame(newFrame); 
+            rawScienceFrame *frame = newToRawScienceFrame(config, newFrame); 
             if (!frame) {
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
                 psError(PS_ERR_UNKNOWN, false, "failed to convert new frame into a science frame");
                 psFree(new);
@@ -119,4 +139,8 @@
             }
             if (!rawScienceFrameInsert(config, frame)) {
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
                 psError(PS_ERR_UNKNOWN, false, "failed to insert frame into the database");
                 psFree(frame);
@@ -127,11 +151,22 @@
 
             // insert into into p2PendingExp
-            p2PendingExpRow *exp = newToP2PendingExp(newFrame->exposure);
+            // XXX add a newToP2PendingFrame()
+            // XXX add a p2PendingFrameInsert()
+            p2PendingExpRow *exp = newToP2PendingExp(config, newFrame->exposure);
             if (!exp) {
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
                 psError(PS_ERR_UNKNOWN, false, "failed to convert newExp into a p2PendingExp");
                 psFree(new);
                 return false;
             }
+
             if (!p2PendingExpInsertObject(config->dbh, exp)) {
+                // rollback
+                if (!psDBRollback(config->dbh)) {
+                    psError(PS_ERR_UNKNOWN, false, "database error");
+                }
                 psError(PS_ERR_UNKNOWN, false, "failed to insert p2PendingExp into the database");
                 psFree(exp);
@@ -145,5 +180,9 @@
                 p2PendingImfileRow *imfile = newImfileToP2PendingImfile(newFrame->images->data[i]);
                 if (!p2PendingImfileInsertObject(config->dbh, imfile)) {
-                psError(PS_ERR_UNKNOWN, false, "failed to insert p2PendingImfile into the database");
+                    // rollback
+                    if (!psDBRollback(config->dbh)) {
+                        psError(PS_ERR_UNKNOWN, false, "database error");
+                    }
+                    psError(PS_ERR_UNKNOWN, false, "failed to insert p2PendingImfile into the database");
                     psFree(imfile);
                     psFree(new);
@@ -152,4 +191,9 @@
                 psFree(imfile);
             }
+        }
+        // point of no return for p2Pending[Exp|Imfile]
+        if (!psDBCommit(config->dbh)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            return false;
         }
     }
@@ -231,8 +275,11 @@
         newExp->telescope,
         newExp->exp_type,
-//        newExp->class,
         newExp->imfiles,
         "my filter",
-        "my stats",
+        0.1, // airmass
+        0.2, // ra
+        0.3, // dec
+        0.4, // exp time
+        0.5, // background
         "my recipe",
         0xff // XXX calc version number
@@ -240,15 +287,77 @@
 }
 
-static p2PendingExpRow *newToP2PendingExp(newExpRow *newExp)
-{
+static p2PendingExpRow *newToP2PendingExp(pxConfig *config, newExpRow *exp)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(exp, NULL);
+
+    bool status = false;
+    psString filter = psMetadataLookupStr(&status, config->args, "-filter");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
+        return false;
+    }
+    if (!filter) {
+        psError(PS_ERR_UNKNOWN, true, "-filter is required");
+        return false;
+    }
+    psF32 airmass = psMetadataLookupF32(&status, config->args, "-airmass");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass");
+        return false;
+    }
+    if (isnan(airmass)) {
+        psError(PS_ERR_UNKNOWN, true, "-airmass is required");
+        return false;
+    }
+    psF64 ra = psMetadataLookupF64(&status, config->args, "-ra");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ra");
+        return false;
+    }
+    if (isnan(ra)) {
+        psError(PS_ERR_UNKNOWN, true, "-ra is required");
+        return false;
+    }
+    psF64 decl = psMetadataLookupF64(&status, config->args, "-decl");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -decl");
+        return false;
+    }
+    if (isnan(decl)) {
+        psError(PS_ERR_UNKNOWN, true, "-decl is required");
+        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;
+    }
+    if (isnan(exp_time)) {
+        psError(PS_ERR_UNKNOWN, true, "-exp_time is required");
+        return false;
+    }
+    psF64 background = psMetadataLookupF64(&status, config->args, "-background");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -background");
+        return false;
+    }
+    if (isnan(background)) {
+        psError(PS_ERR_UNKNOWN, true, "-background is required");
+        return false;
+    }
+
     return p2PendingExpRowAlloc(
-        newExp->exp_id,
-        newExp->camera,
-        newExp->telescope,
-        newExp->exp_type,
-//        newExp->class,
-        newExp->imfiles,
-        "my filter", 
-        "my stats",
+        exp->exp_id,
+        exp->camera,
+        exp->telescope,
+        exp->exp_type,
+        exp->imfiles,
+        filter,
+        airmass,
+        ra,
+        decl,
+        exp_time,
+        background,
         "my recipe",
         0xff, // XXX calc version number
@@ -263,5 +372,4 @@
         newImfile->class_id,
         newImfile->uri,
-        "my stats",
         "my recipe",
         0xff, // XXX calc version number
@@ -269,2 +377,113 @@
     );
 }
+
+static rawScienceFrame *newToRawScienceFrame(pxConfig *config, newFrame *newFrame) 
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(newFrame, NULL);
+
+    newExpRow *newExp = newFrame->exposure;
+    rawScienceExpRow *rawScienceExp = newToRawScienceExp(config, newExp);
+    if (!rawScienceExp) {
+        psError(PS_ERR_UNKNOWN, false, "failed to convert newExp to rawScienceExp");
+        return NULL;
+    }
+
+    psArray *newImages = newFrame->images;
+    psArray *rawImages = psArrayAlloc(psArrayLength(newImages));
+    for (long i = 0; i < psArrayLength(newImages); i++) {
+        newImfileRow *newImfile = newImages->data[i];
+        rawImfileRow *rawImfile = rawImfileRowAlloc(
+            newImfile->exp_id,
+            newImfile->class,
+            newImfile->class_id,
+            newImfile->uri
+        );
+        psArrayAdd(rawImages, 0, rawImfile);
+        psFree(rawImfile);
+    }
+
+    rawScienceFrame *rawScienceFrame = rawScienceFrameAlloc(rawScienceExp, rawImages);
+    psFree(rawScienceExp);
+    psFree(rawImages);
+
+    return rawScienceFrame;
+}
+
+static rawScienceExpRow *newToRawScienceExp(pxConfig *config, newExpRow *exp)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(exp, NULL);
+
+    bool status = false;
+    psString filter = psMetadataLookupStr(&status, config->args, "-filter");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -filter");
+        return NULL;
+    }
+    if (!filter) {
+        psError(PS_ERR_UNKNOWN, true, "-filter is required");
+        return NULL;
+    }
+    psF32 airmass = psMetadataLookupF32(&status, config->args, "-airmass");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -airmass");
+        return NULL;
+    }
+    if (isnan(airmass)) {
+        psError(PS_ERR_UNKNOWN, true, "-airmass is required");
+        return NULL;
+    }
+    psF64 ra = psMetadataLookupF64(&status, config->args, "-ra");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -ra");
+        return NULL;
+    }
+    if (isnan(ra)) {
+        psError(PS_ERR_UNKNOWN, true, "-airmass is required");
+        return NULL;
+    }
+    psF64 decl = psMetadataLookupF64(&status, config->args, "-decl");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -decl");
+        return NULL;
+    }
+    if (isnan(decl)) {
+        psError(PS_ERR_UNKNOWN, true, "-decl is required");
+        return NULL;
+    }
+    psF32 exp_time = psMetadataLookupF32(&status, config->args, "-exp_time");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -exp_time");
+        return NULL;
+    }
+    if (isnan(exp_time)) {
+        psError(PS_ERR_UNKNOWN, true, "-exp_time is required");
+        return NULL;
+    }
+    psF64 background = psMetadataLookupF64(&status, config->args, "-background");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, false, "failed to lookup value for -background");
+        return NULL;
+    }
+    if (isnan(background)) {
+        psError(PS_ERR_UNKNOWN, true, "-background is required");
+        return NULL;
+    }
+
+    return rawScienceExpRowAlloc(
+        exp->exp_id,
+        exp->camera,
+        exp->telescope,
+        exp->exp_type,
+        exp->imfiles,
+        filter,
+        airmass,
+        ra,
+        decl,
+        exp_time,
+        background
+    );
+}
+
+
Index: /trunk/ippTools/src/regtoolConfig.c
===================================================================
--- /trunk/ippTools/src/regtoolConfig.c	(revision 8119)
+++ /trunk/ippTools/src/regtoolConfig.c	(revision 8120)
@@ -4,4 +4,5 @@
 
 #include <pmConfig.h>
+#include <math.h>
 
 #include "pxtools.h"
@@ -38,15 +39,25 @@
     psMetadata *updateArgs = psMetadataAlloc();
     psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-exp_id",  0,
-        "define class", NULL); 
-    psMetadataAddBool(updateArgs, PS_LIST_TAIL, "-detrend",  0,
-        "declare this as detrend data", false);
+        "exp_id to operate on", NULL); 
     psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-filter",  0,
-        "define filter of interest", NULL);
-    psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-stat",  0,
-        "define URL", NULL);
+        "define filter ", NULL);
+    psMetadataAddF32(updateArgs, PS_LIST_TAIL, "-airmass",  0,
+        "define airmass", NAN);
+    psMetadataAddF64(updateArgs, PS_LIST_TAIL, "-ra",  0,
+        "define RA", NAN);
+    psMetadataAddF64(updateArgs, PS_LIST_TAIL, "-decl",  0,
+        "define DEC", NAN);
+    psMetadataAddF32(updateArgs, PS_LIST_TAIL, "-exp_time",  0,
+        "define exposure time", NAN);
+    psMetadataAddF64(updateArgs, PS_LIST_TAIL, "-background",  0,
+        "define exposue background", NAN);
+    /*
     psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-recip",  0,
         "define URL", NULL);
     psMetadataAddStr(updateArgs, PS_LIST_TAIL, "-mosiac",  0,
         "define URL", NULL);
+    */
+    psMetadataAddBool(updateArgs, PS_LIST_TAIL, "-detrend",  0,
+        "declare this as detrend data", false);
 
 #define PXTOOL_MODE(option, modeval, argset) \
