Index: /trunk/dbconfig/config.md
===================================================================
--- /trunk/dbconfig/config.md	(revision 11678)
+++ /trunk/dbconfig/config.md	(revision 11679)
@@ -2,4 +2,4 @@
     pkg_name        STR     ippdb
     pkg_namespace   STR     ippdb
-    pkg_version     STR     1.1.0
+    pkg_version     STR     1.1.1
 END
Index: /trunk/ippdb/Makefile.am
===================================================================
--- /trunk/ippdb/Makefile.am	(revision 11678)
+++ /trunk/ippdb/Makefile.am	(revision 11679)
@@ -41,13 +41,18 @@
     $(top_builddir)/docs/man/man3/detResidExpRow.3 \
     $(top_builddir)/docs/man/man3/detRunSummaryRow.3 \
-    $(top_builddir)/docs/man/man3/p4RunRow.3 \
-    $(top_builddir)/docs/man/man3/p4InputImfileRow.3 \
-    $(top_builddir)/docs/man/man3/p4WarpedImfileRow.3 \
-    $(top_builddir)/docs/man/man3/p4StackedImfileRow.3 \
-    $(top_builddir)/docs/man/man3/p4DiffImfileRow.3 \
-    $(top_builddir)/docs/man/man3/p4MagicMaskImfileRow.3 
+    $(top_builddir)/docs/man/man3/p4aRunRow.3 \
+    $(top_builddir)/docs/man/man3/p4aInputExpRow.3 \
+    $(top_builddir)/docs/man/man3/p4aScfileRow.3 \
+    $(top_builddir)/docs/man/man3/p4bRunRow.3 \
+    $(top_builddir)/docs/man/man3/p4bInputScfileRow.3 \
+    $(top_builddir)/docs/man/man3/p4bDiffScfileRow.3 \
+    $(top_builddir)/docs/man/man3/p4cRunRow.3 \
+    $(top_builddir)/docs/man/man3/p4cInputExpRow.3 \
+    $(top_builddir)/docs/man/man3/p4MagicMaskImfileRow.3 \
+    $(top_builddir)/docs/man/man3/skyCellRow.3 \
+    $(top_builddir)/docs/man/man3/skyCellMapRow.3 
 
 
-docs/man/man3/ippdb.3 docs/man/man3/expTagCounterRow.3 docs/man/man3/summitExpRow.3 docs/man/man3/summitImfileRow.3 docs/man/man3/pzPendingExpRow.3 docs/man/man3/pzPendingImfileRow.3 docs/man/man3/pzDoneExpRow.3 docs/man/man3/pzDoneImfileRow.3 docs/man/man3/newExpRow.3 docs/man/man3/newImfileRow.3 docs/man/man3/rawExpRow.3 docs/man/man3/rawImfileRow.3 docs/man/man3/p1PendingExpRow.3 docs/man/man3/p2PendingExpRow.3 docs/man/man3/p2PendingImfileRow.3 docs/man/man3/p2ProcessedExpRow.3 docs/man/man3/p2MaskRow.3 docs/man/man3/p2ProcessedImfileRow.3 docs/man/man3/p3PendingExpRow.3 docs/man/man3/p3ProcessedExpRow.3 docs/man/man3/p3MaskRow.3 docs/man/man3/detRunRow.3 docs/man/man3/detInputExpRow.3 docs/man/man3/detProcessedImfileRow.3 docs/man/man3/detProcessedExpRow.3 docs/man/man3/detStackedImfileRow.3 docs/man/man3/detNormalizedStatImfileRow.3 docs/man/man3/detNormalizedImfileRow.3 docs/man/man3/detNormalizedExpRow.3 docs/man/man3/detResidImfileRow.3 docs/man/man3/detResidExpRow.3 docs/man/man3/detRunSummaryRow.3 docs/man/man3/p4RunRow.3 docs/man/man3/p4InputImfileRow.3 docs/man/man3/p4WarpedImfileRow.3 docs/man/man3/p4StackedImfileRow.3 docs/man/man3/p4DiffImfileRow.3 docs/man/man3/p4MagicMaskImfileRow.3:
+docs/man/man3/ippdb.3 docs/man/man3/expTagCounterRow.3 docs/man/man3/summitExpRow.3 docs/man/man3/summitImfileRow.3 docs/man/man3/pzPendingExpRow.3 docs/man/man3/pzPendingImfileRow.3 docs/man/man3/pzDoneExpRow.3 docs/man/man3/pzDoneImfileRow.3 docs/man/man3/newExpRow.3 docs/man/man3/newImfileRow.3 docs/man/man3/rawExpRow.3 docs/man/man3/rawImfileRow.3 docs/man/man3/p1PendingExpRow.3 docs/man/man3/p2PendingExpRow.3 docs/man/man3/p2PendingImfileRow.3 docs/man/man3/p2ProcessedExpRow.3 docs/man/man3/p2MaskRow.3 docs/man/man3/p2ProcessedImfileRow.3 docs/man/man3/p3PendingExpRow.3 docs/man/man3/p3ProcessedExpRow.3 docs/man/man3/p3MaskRow.3 docs/man/man3/detRunRow.3 docs/man/man3/detInputExpRow.3 docs/man/man3/detProcessedImfileRow.3 docs/man/man3/detProcessedExpRow.3 docs/man/man3/detStackedImfileRow.3 docs/man/man3/detNormalizedStatImfileRow.3 docs/man/man3/detNormalizedImfileRow.3 docs/man/man3/detNormalizedExpRow.3 docs/man/man3/detResidImfileRow.3 docs/man/man3/detResidExpRow.3 docs/man/man3/detRunSummaryRow.3 docs/man/man3/p4aRunRow.3 docs/man/man3/p4aInputExpRow.3 docs/man/man3/p4aScfileRow.3 docs/man/man3/p4bRunRow.3 docs/man/man3/p4bInputScfileRow.3 docs/man/man3/p4bDiffScfileRow.3 docs/man/man3/p4cRunRow.3 docs/man/man3/p4cInputExpRow.3 docs/man/man3/p4MagicMaskImfileRow.3 docs/man/man3/skyCellRow.3 docs/man/man3/skyCellMapRow.3:
 	$(DOXYGEN)
 
Index: /trunk/ippdb/configure.ac
===================================================================
--- /trunk/ippdb/configure.ac	(revision 11678)
+++ /trunk/ippdb/configure.ac	(revision 11679)
@@ -1,4 +1,4 @@
 dnl
-dnl This file was generated by glueforge 1.00
+dnl This file was generated by glueforge 0.36
 dnl
 dnl Do NOT directly edit this file.
@@ -7,5 +7,5 @@
 AC_PREREQ(2.59)
 
-AC_INIT([ippdb], [1.0.0], [pan-starrs.ifa.hawaii.edu])
+AC_INIT([ippdb], [1.1.1], [pan-starrs.ifa.hawaii.edu])
 AC_CONFIG_SRCDIR([ippdb.pc.in])
 
Index: /trunk/ippdb/src/ippdb.c
===================================================================
--- /trunk/ippdb/src/ippdb.c	(revision 11678)
+++ /trunk/ippdb/src/ippdb.c	(revision 11679)
@@ -20,5 +20,5 @@
 /*
  *
- * This file was generated by glueforge 1.00
+ * This file was generated by glueforge 0.36
  *
  * Do NOT directly edit this file.
@@ -62,10 +62,15 @@
 #define DETRESIDEXP_TABLE_NAME "detResidExp"
 #define DETRUNSUMMARY_TABLE_NAME "detRunSummary"
-#define P4RUN_TABLE_NAME "p4Run"
-#define P4INPUTIMFILE_TABLE_NAME "p4InputImfile"
-#define P4WARPEDIMFILE_TABLE_NAME "p4WarpedImfile"
-#define P4STACKEDIMFILE_TABLE_NAME "p4StackedImfile"
-#define P4DIFFIMFILE_TABLE_NAME "p4DiffImfile"
+#define P4ARUN_TABLE_NAME "p4aRun"
+#define P4AINPUTEXP_TABLE_NAME "p4aInputExp"
+#define P4ASCFILE_TABLE_NAME "p4aScfile"
+#define P4BRUN_TABLE_NAME "p4bRun"
+#define P4BINPUTSCFILE_TABLE_NAME "p4bInputScfile"
+#define P4BDIFFSCFILE_TABLE_NAME "p4bDiffScfile"
+#define P4CRUN_TABLE_NAME "p4cRun"
+#define P4CINPUTEXP_TABLE_NAME "p4cInputExp"
 #define P4MAGICMASKIMFILE_TABLE_NAME "p4MagicMaskImfile"
+#define SKYCELL_TABLE_NAME "skyCell"
+#define SKYCELLMAP_TABLE_NAME "skyCellMap"
 #define MAX_STRING_LENGTH 1024
 
@@ -438,5 +443,5 @@
     psMetadata *where = expTagCounterMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, EXPTAGCOUNTER_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from expTagCounter");
@@ -460,5 +465,5 @@
         psMetadata *where = expTagCounterMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, EXPTAGCOUNTER_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from expTagCounter");
@@ -843,5 +848,5 @@
     psMetadata *where = summitExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, SUMMITEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from summitExp");
@@ -865,5 +870,5 @@
         psMetadata *where = summitExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, SUMMITEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from summitExp");
@@ -1292,5 +1297,5 @@
     psMetadata *where = summitImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, SUMMITIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from summitImfile");
@@ -1314,5 +1319,5 @@
         psMetadata *where = summitImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, SUMMITIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from summitImfile");
@@ -1610,5 +1615,5 @@
     psMetadata *where = pzPendingExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
@@ -1632,5 +1637,5 @@
         psMetadata *where = pzPendingExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, PZPENDINGEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingExp");
@@ -1994,5 +1999,5 @@
     psMetadata *where = pzPendingImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
@@ -2016,5 +2021,5 @@
         psMetadata *where = pzPendingImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, PZPENDINGIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzPendingImfile");
@@ -2312,5 +2317,5 @@
     psMetadata *where = pzDoneExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
@@ -2334,5 +2339,5 @@
         psMetadata *where = pzDoneExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, PZDONEEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneExp");
@@ -2718,5 +2723,5 @@
     psMetadata *where = pzDoneImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
@@ -2740,5 +2745,5 @@
         psMetadata *where = pzDoneImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, PZDONEIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from pzDoneImfile");
@@ -3101,5 +3106,5 @@
     psMetadata *where = newExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, NEWEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from newExp");
@@ -3123,5 +3128,5 @@
         psMetadata *where = newExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, NEWEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from newExp");
@@ -3441,5 +3446,5 @@
     psMetadata *where = newImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, NEWIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from newImfile");
@@ -3463,5 +3468,5 @@
         psMetadata *where = newImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, NEWIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from newImfile");
@@ -4164,5 +4169,5 @@
     psMetadata *where = rawExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, RAWEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from rawExp");
@@ -4186,5 +4191,5 @@
         psMetadata *where = rawExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, RAWEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from rawExp");
@@ -4844,5 +4849,5 @@
     psMetadata *where = rawImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, RAWIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from rawImfile");
@@ -4866,5 +4871,5 @@
         psMetadata *where = rawImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, RAWIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from rawImfile");
@@ -5161,5 +5166,5 @@
     psMetadata *where = p1PendingExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P1PENDINGEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p1PendingExp");
@@ -5183,5 +5188,5 @@
         psMetadata *where = p1PendingExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P1PENDINGEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p1PendingExp");
@@ -5521,5 +5526,5 @@
     psMetadata *where = p2PendingExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P2PENDINGEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2PendingExp");
@@ -5543,5 +5548,5 @@
         psMetadata *where = p2PendingExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P2PENDINGEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2PendingExp");
@@ -5903,5 +5908,5 @@
     psMetadata *where = p2PendingImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P2PENDINGIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2PendingImfile");
@@ -5925,5 +5930,5 @@
         psMetadata *where = p2PendingImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P2PENDINGIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2PendingImfile");
@@ -6241,5 +6246,5 @@
     psMetadata *where = p2ProcessedExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P2PROCESSEDEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2ProcessedExp");
@@ -6263,5 +6268,5 @@
         psMetadata *where = p2ProcessedExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P2PROCESSEDEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2ProcessedExp");
@@ -6515,5 +6520,5 @@
     psMetadata *where = p2MaskMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P2MASK_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2Mask");
@@ -6537,5 +6542,5 @@
         psMetadata *where = p2MaskMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P2MASK_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2Mask");
@@ -7025,5 +7030,5 @@
     psMetadata *where = p2ProcessedImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P2PROCESSEDIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2ProcessedImfile");
@@ -7047,5 +7052,5 @@
         psMetadata *where = p2ProcessedImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P2PROCESSEDIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p2ProcessedImfile");
@@ -7363,5 +7368,5 @@
     psMetadata *where = p3PendingExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P3PENDINGEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p3PendingExp");
@@ -7385,5 +7390,5 @@
         psMetadata *where = p3PendingExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P3PENDINGEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p3PendingExp");
@@ -7978,5 +7983,5 @@
     psMetadata *where = p3ProcessedExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P3PROCESSEDEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p3ProcessedExp");
@@ -8000,5 +8005,5 @@
         psMetadata *where = p3ProcessedExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P3PROCESSEDEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p3ProcessedExp");
@@ -8252,5 +8257,5 @@
     psMetadata *where = p3MaskMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P3MASK_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p3Mask");
@@ -8274,5 +8279,5 @@
         psMetadata *where = p3MaskMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P3MASK_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p3Mask");
@@ -9000,5 +9005,5 @@
     psMetadata *where = detRunMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETRUN_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detRun");
@@ -9022,5 +9027,5 @@
         psMetadata *where = detRunMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETRUN_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detRun");
@@ -9337,5 +9342,5 @@
     psMetadata *where = detInputExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETINPUTEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detInputExp");
@@ -9359,5 +9364,5 @@
         psMetadata *where = detInputExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETINPUTEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detInputExp");
@@ -9826,5 +9831,5 @@
     psMetadata *where = detProcessedImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETPROCESSEDIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detProcessedImfile");
@@ -9848,5 +9853,5 @@
         psMetadata *where = detProcessedImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETPROCESSEDIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detProcessedImfile");
@@ -10271,5 +10276,5 @@
     psMetadata *where = detProcessedExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETPROCESSEDEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detProcessedExp");
@@ -10293,5 +10298,5 @@
         psMetadata *where = detProcessedExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETPROCESSEDEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detProcessedExp");
@@ -10715,5 +10720,5 @@
     psMetadata *where = detStackedImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETSTACKEDIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detStackedImfile");
@@ -10737,5 +10742,5 @@
         psMetadata *where = detStackedImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETSTACKEDIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detStackedImfile");
@@ -11073,5 +11078,5 @@
     psMetadata *where = detNormalizedStatImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETNORMALIZEDSTATIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detNormalizedStatImfile");
@@ -11095,5 +11100,5 @@
         psMetadata *where = detNormalizedStatImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETNORMALIZEDSTATIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detNormalizedStatImfile");
@@ -11539,5 +11544,5 @@
     psMetadata *where = detNormalizedImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETNORMALIZEDIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detNormalizedImfile");
@@ -11561,5 +11566,5 @@
         psMetadata *where = detNormalizedImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETNORMALIZEDIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detNormalizedImfile");
@@ -11983,5 +11988,5 @@
     psMetadata *where = detNormalizedExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETNORMALIZEDEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detNormalizedExp");
@@ -12005,5 +12010,5 @@
         psMetadata *where = detNormalizedExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETNORMALIZEDEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detNormalizedExp");
@@ -12493,5 +12498,5 @@
     psMetadata *where = detResidImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETRESIDIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detResidImfile");
@@ -12515,5 +12520,5 @@
         psMetadata *where = detResidImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETRESIDIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detResidImfile");
@@ -12980,5 +12985,5 @@
     psMetadata *where = detResidExpMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETRESIDEXP_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detResidExp");
@@ -13002,5 +13007,5 @@
         psMetadata *where = detResidExpMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETRESIDEXP_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detResidExp");
@@ -13379,5 +13384,5 @@
     psMetadata *where = detRunSummaryMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, DETRUNSUMMARY_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from detRunSummary");
@@ -13401,5 +13406,5 @@
         psMetadata *where = detRunSummaryMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, DETRUNSUMMARY_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from detRunSummary");
@@ -13458,50 +13463,32 @@
     return true;
 }
-static void p4RunRowFree(p4RunRow *object);
-
-p4RunRow *p4RunRowAlloc(psS32 p4_id, const char *survey_mode, const char *state, const char *workdir, const char *filter, const char *skycell_id, const char *tess_id, psF64 ra, psF64 decl, const char *input_ss, const char *output_ss)
-{
-    p4RunRow        *_object;
-
-    _object = psAlloc(sizeof(p4RunRow));
-    psMemSetDeallocator(_object, (psFreeFunc)p4RunRowFree);
-
-    _object->p4_id = p4_id;
-    _object->survey_mode = psStringCopy(survey_mode);
+static void p4aRunRowFree(p4aRunRow *object);
+
+p4aRunRow *p4aRunRowAlloc(psS32 p4a_id, const char *state, const char *workdir, bool magic)
+{
+    p4aRunRow       *_object;
+
+    _object = psAlloc(sizeof(p4aRunRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4aRunRowFree);
+
+    _object->p4a_id = p4a_id;
     _object->state = psStringCopy(state);
     _object->workdir = psStringCopy(workdir);
-    _object->filter = psStringCopy(filter);
-    _object->skycell_id = psStringCopy(skycell_id);
-    _object->tess_id = psStringCopy(tess_id);
-    _object->ra = ra;
-    _object->decl = decl;
-    _object->input_ss = psStringCopy(input_ss);
-    _object->output_ss = psStringCopy(output_ss);
+    _object->magic = magic;
 
     return _object;
 }
 
-static void p4RunRowFree(p4RunRow *object)
-{
-    psFree(object->survey_mode);
+static void p4aRunRowFree(p4aRunRow *object)
+{
     psFree(object->state);
     psFree(object->workdir);
-    psFree(object->filter);
-    psFree(object->skycell_id);
-    psFree(object->tess_id);
-    psFree(object->input_ss);
-    psFree(object->output_ss);
-}
-
-bool p4RunCreateTable(psDB *dbh)
+}
+
+bool p4aRunCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key AUTO_INCREMENT", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "survey_mode", PS_DATA_STRING, "Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item survey_mode");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, "Primary Key AUTO_INCREMENT", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
         psFree(md);
         return false;
@@ -13517,41 +13504,11 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra", PS_DATA_F64, NULL, 0.0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item ra");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl", PS_DATA_F64, NULL, 0.0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item decl");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "input_ss", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item input_ss");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "output_ss", PS_DATA_STRING, NULL, "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item output_ss");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, P4RUN_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4ARUN_TABLE_NAME, md);
 
     psFree(md);
@@ -13560,19 +13517,14 @@
 }
 
-bool p4RunDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, P4RUN_TABLE_NAME);
-}
-
-bool p4RunInsert(psDB * dbh, psS32 p4_id, const char *survey_mode, const char *state, const char *workdir, const char *filter, const char *skycell_id, const char *tess_id, psF64 ra, psF64 decl, const char *input_ss, const char *output_ss)
+bool p4aRunDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4ARUN_TABLE_NAME);
+}
+
+bool p4aRunInsert(psDB * dbh, psS32 p4a_id, const char *state, const char *workdir, bool magic)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "survey_mode", PS_DATA_STRING, NULL, survey_mode)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item survey_mode");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, p4a_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
         psFree(md);
         return false;
@@ -13588,41 +13540,11 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, filter)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra", PS_DATA_F64, NULL, ra)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item ra");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl", PS_DATA_F64, NULL, decl)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item decl");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "input_ss", PS_DATA_STRING, NULL, input_ss)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item input_ss");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "output_ss", PS_DATA_STRING, NULL, output_ss)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item output_ss");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, P4RUN_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, magic)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4ARUN_TABLE_NAME, md);
     psFree(md);
 
@@ -13630,11 +13552,11 @@
 }
 
-long long p4RunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long p4aRunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, P4RUN_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, P4ARUN_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4Run");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aRun");
         return count;
 
@@ -13644,13 +13566,13 @@
     return deleted;
 }
-bool p4RunInsertObject(psDB *dbh, p4RunRow *object)
-{
-    return p4RunInsert(dbh, object->p4_id, object->survey_mode, object->state, object->workdir, object->filter, object->skycell_id, object->tess_id, object->ra, object->decl, object->input_ss, object->output_ss);
-}
-
-bool p4RunInsertObjects(psDB *dbh, psArray *objects)
+bool p4aRunInsertObject(psDB *dbh, p4aRunRow *object)
+{
+    return p4aRunInsert(dbh, object->p4a_id, object->state, object->workdir, object->magic);
+}
+
+bool p4aRunInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!p4RunInsertObject(dbh, objects->data[i])) {
+        if (!p4aRunInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -13660,11 +13582,11 @@
 }
 
-bool p4RunInsertFits(psDB *dbh, const psFits *fits)
+bool p4aRunInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  P4RUN_TABLE_NAME
-    if (!psFitsMoveExtName(fits, P4RUN_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4RUN_TABLE_NAME);
+    // move to (the first?) extension named  P4ARUN_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4ARUN_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4ARUN_TABLE_NAME);
         return false;
     }
@@ -13684,5 +13606,5 @@
     }
 
-    if (!psDBInsertRows(dbh, P4RUN_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, P4ARUN_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -13695,9 +13617,9 @@
 }
 
-bool p4RunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool p4aRunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, P4RUN_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4ARUN_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -13705,5 +13627,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, P4RUN_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4ARUN_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -13716,14 +13638,9 @@
 }
 
-psMetadata *p4RunMetadataFromObject(const p4RunRow *object)
+psMetadata *p4aRunMetadataFromObject(const p4aRunRow *object)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "survey_mode", PS_DATA_STRING, NULL, object->survey_mode)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item survey_mode");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, object->p4a_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
         psFree(md);
         return false;
@@ -13739,36 +13656,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "filter", PS_DATA_STRING, NULL, object->filter)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item filter");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra", PS_DATA_F64, NULL, object->ra)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item ra");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl", PS_DATA_F64, NULL, object->decl)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item decl");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "input_ss", PS_DATA_STRING, NULL, object->input_ss)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item input_ss");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "output_ss", PS_DATA_STRING, NULL, object->output_ss)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item output_ss");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, object->magic)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
         psFree(md);
         return false;
@@ -13779,16 +13666,11 @@
 }
 
-p4RunRow *p4RunObjectFromMetadata(psMetadata *md)
+p4aRunRow *p4aRunObjectFromMetadata(psMetadata *md)
 {
 
 bool status = false;
-    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
-        return false;
-    }
-    char* survey_mode = psMetadataLookupPtr(&status, md, "survey_mode");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item survey_mode");
+    psS32 p4a_id = psMetadataLookupS32(&status, md, "p4a_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4a_id");
         return false;
     }
@@ -13803,43 +13685,13 @@
         return false;
     }
-    char* filter = psMetadataLookupPtr(&status, md, "filter");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item filter");
-        return false;
-    }
-    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
-        return false;
-    }
-    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
-        return false;
-    }
-    psF64 ra = psMetadataLookupF64(&status, md, "ra");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra");
-        return false;
-    }
-    psF64 decl = psMetadataLookupF64(&status, md, "decl");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl");
-        return false;
-    }
-    char* input_ss = psMetadataLookupPtr(&status, md, "input_ss");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item input_ss");
-        return false;
-    }
-    char* output_ss = psMetadataLookupPtr(&status, md, "output_ss");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item output_ss");
-        return false;
-    }
-
-    return p4RunRowAlloc(p4_id, survey_mode, state, workdir, filter, skycell_id, tess_id, ra, decl, input_ss, output_ss);
-}
-psArray *p4RunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+    bool magic = psMetadataLookupBool(&status, md, "magic");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic");
+        return false;
+    }
+
+    return p4aRunRowAlloc(p4a_id, state, workdir, magic);
+}
+psArray *p4aRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -13847,5 +13699,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, P4RUN_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4ARUN_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -13857,5 +13709,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        p4RunRow *object = p4RunObjectFromMetadata(rowSet->data[i]);
+        p4aRunRow *object = p4aRunObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -13866,11 +13718,11 @@
     return returnSet;
 }
-bool p4RunDeleteObject(psDB *dbh, const p4RunRow *object)
-{
-    psMetadata *where = p4RunMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, P4RUN_TABLE_NAME, where, 0);
-    psFree(where)
+bool p4aRunDeleteObject(psDB *dbh, const p4aRunRow *object)
+{
+    psMetadata *where = p4aRunMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4ARUN_TABLE_NAME, where, 0);
+    psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4Run");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aRun");
         return false;
     }
@@ -13878,21 +13730,21 @@
         // XXX should this be a psAbort() instead?  It is possible that
         // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "p4RunRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long p4RunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "p4aRunRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4aRunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        p4RunRow *object = objects->data[i];
-        psMetadata *where = p4RunMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, P4RUN_TABLE_NAME, where, limit);
-        psFree(where)
+        p4aRunRow *object = objects->data[i];
+        psMetadata *where = p4aRunMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4ARUN_TABLE_NAME, where, limit);
+        psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4Run");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aRun");
             return count;
         }
@@ -13903,5 +13755,5 @@
     return deleted;
 }
-bool p4RunPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool p4aRunPrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -13909,9 +13761,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = p4RunMetadataFromObject(objects->data[i]);
+        psMetadata *md = p4aRunMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            P4RUN_TABLE_NAME,
+            P4ARUN_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -13934,9 +13786,9 @@
     return true;
 }
-bool p4RunPrintObject(FILE *stream, p4RunRow *object, bool mdcf)
+bool p4aRunPrintObject(FILE *stream, p4aRunRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = p4RunMetadataFromObject(object);
+    psMetadata *md = p4aRunMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -13949,32 +13801,30 @@
     return true;
 }
-static void p4InputImfileRowFree(p4InputImfileRow *object);
-
-p4InputImfileRow *p4InputImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id)
-{
-    p4InputImfileRow *_object;
-
-    _object = psAlloc(sizeof(p4InputImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)p4InputImfileRowFree);
-
-    _object->p4_id = p4_id;
+static void p4aInputExpRowFree(p4aInputExpRow *object);
+
+p4aInputExpRow *p4aInputExpRowAlloc(psS32 p4a_id, const char *exp_tag, psS32 p3_version)
+{
+    p4aInputExpRow  *_object;
+
+    _object = psAlloc(sizeof(p4aInputExpRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4aInputExpRowFree);
+
+    _object->p4a_id = p4a_id;
     _object->exp_tag = psStringCopy(exp_tag);
     _object->p3_version = p3_version;
-    _object->class_id = psStringCopy(class_id);
 
     return _object;
 }
 
-static void p4InputImfileRowFree(p4InputImfileRow *object)
+static void p4aInputExpRowFree(p4aInputExpRow *object)
 {
     psFree(object->exp_tag);
-    psFree(object->class_id);
-}
-
-bool p4InputImfileCreateTable(psDB *dbh)
+}
+
+bool p4aInputExpCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
         psFree(md);
         return false;
@@ -13990,11 +13840,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, P4INPUTIMFILE_TABLE_NAME, md);
+
+    bool status = psDBCreateTable(dbh, P4AINPUTEXP_TABLE_NAME, md);
 
     psFree(md);
@@ -14003,14 +13848,14 @@
 }
 
-bool p4InputImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, P4INPUTIMFILE_TABLE_NAME);
-}
-
-bool p4InputImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id)
+bool p4aInputExpDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4AINPUTEXP_TABLE_NAME);
+}
+
+bool p4aInputExpInsert(psDB * dbh, psS32 p4a_id, const char *exp_tag, psS32 p3_version)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, p4a_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
         psFree(md);
         return false;
@@ -14026,11 +13871,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, P4INPUTIMFILE_TABLE_NAME, md);
+
+    bool status = psDBInsertOneRow(dbh, P4AINPUTEXP_TABLE_NAME, md);
     psFree(md);
 
@@ -14038,11 +13878,11 @@
 }
 
-long long p4InputImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long p4aInputExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, P4AINPUTEXP_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aInputExp");
         return count;
 
@@ -14052,13 +13892,13 @@
     return deleted;
 }
-bool p4InputImfileInsertObject(psDB *dbh, p4InputImfileRow *object)
-{
-    return p4InputImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id);
-}
-
-bool p4InputImfileInsertObjects(psDB *dbh, psArray *objects)
+bool p4aInputExpInsertObject(psDB *dbh, p4aInputExpRow *object)
+{
+    return p4aInputExpInsert(dbh, object->p4a_id, object->exp_tag, object->p3_version);
+}
+
+bool p4aInputExpInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!p4InputImfileInsertObject(dbh, objects->data[i])) {
+        if (!p4aInputExpInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -14068,11 +13908,11 @@
 }
 
-bool p4InputImfileInsertFits(psDB *dbh, const psFits *fits)
+bool p4aInputExpInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  P4INPUTIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, P4INPUTIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4INPUTIMFILE_TABLE_NAME);
+    // move to (the first?) extension named  P4AINPUTEXP_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4AINPUTEXP_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4AINPUTEXP_TABLE_NAME);
         return false;
     }
@@ -14092,5 +13932,5 @@
     }
 
-    if (!psDBInsertRows(dbh, P4INPUTIMFILE_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, P4AINPUTEXP_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -14103,9 +13943,9 @@
 }
 
-bool p4InputImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool p4aInputExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4AINPUTEXP_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -14113,5 +13953,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, P4INPUTIMFILE_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4AINPUTEXP_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -14124,9 +13964,9 @@
 }
 
-psMetadata *p4InputImfileMetadataFromObject(const p4InputImfileRow *object)
+psMetadata *p4aInputExpMetadataFromObject(const p4aInputExpRow *object)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, object->p4a_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
         psFree(md);
         return false;
@@ -14142,9 +13982,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
 
 
@@ -14152,11 +13987,11 @@
 }
 
-p4InputImfileRow *p4InputImfileObjectFromMetadata(psMetadata *md)
+p4aInputExpRow *p4aInputExpObjectFromMetadata(psMetadata *md)
 {
 
 bool status = false;
-    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
+    psS32 p4a_id = psMetadataLookupS32(&status, md, "p4a_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4a_id");
         return false;
     }
@@ -14171,13 +14006,8 @@
         return false;
     }
-    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
-        return false;
-    }
-
-    return p4InputImfileRowAlloc(p4_id, exp_tag, p3_version, class_id);
-}
-psArray *p4InputImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+
+    return p4aInputExpRowAlloc(p4a_id, exp_tag, p3_version);
+}
+psArray *p4aInputExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -14185,5 +14015,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4AINPUTEXP_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -14195,5 +14025,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        p4InputImfileRow *object = p4InputImfileObjectFromMetadata(rowSet->data[i]);
+        p4aInputExpRow *object = p4aInputExpObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -14204,11 +14034,11 @@
     return returnSet;
 }
-bool p4InputImfileDeleteObject(psDB *dbh, const p4InputImfileRow *object)
-{
-    psMetadata *where = p4InputImfileMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+bool p4aInputExpDeleteObject(psDB *dbh, const p4aInputExpRow *object)
+{
+    psMetadata *where = p4aInputExpMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4AINPUTEXP_TABLE_NAME, where, 0);
+    psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aInputExp");
         return false;
     }
@@ -14216,21 +14046,21 @@
         // XXX should this be a psAbort() instead?  It is possible that
         // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "p4InputImfileRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long p4InputImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "p4aInputExpRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4aInputExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        p4InputImfileRow *object = objects->data[i];
-        psMetadata *where = p4InputImfileMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, P4INPUTIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        p4aInputExpRow *object = objects->data[i];
+        psMetadata *where = p4aInputExpMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4AINPUTEXP_TABLE_NAME, where, limit);
+        psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4InputImfile");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aInputExp");
             return count;
         }
@@ -14241,5 +14071,5 @@
     return deleted;
 }
-bool p4InputImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool p4aInputExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -14247,9 +14077,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = p4InputImfileMetadataFromObject(objects->data[i]);
+        psMetadata *md = p4aInputExpMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            P4INPUTIMFILE_TABLE_NAME,
+            P4AINPUTEXP_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -14272,9 +14102,9 @@
     return true;
 }
-bool p4InputImfilePrintObject(FILE *stream, p4InputImfileRow *object, bool mdcf)
+bool p4aInputExpPrintObject(FILE *stream, p4aInputExpRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = p4InputImfileMetadataFromObject(object);
+    psMetadata *md = p4aInputExpMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -14287,38 +14117,48 @@
     return true;
 }
-static void p4WarpedImfileRowFree(p4WarpedImfileRow *object);
-
-p4WarpedImfileRow *p4WarpedImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri)
-{
-    p4WarpedImfileRow *_object;
-
-    _object = psAlloc(sizeof(p4WarpedImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)p4WarpedImfileRowFree);
-
-    _object->p4_id = p4_id;
+static void p4aScfileRowFree(p4aScfileRow *object);
+
+p4aScfileRow *p4aScfileRowAlloc(psS32 p4a_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
+{
+    p4aScfileRow    *_object;
+
+    _object = psAlloc(sizeof(p4aScfileRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4aScfileRowFree);
+
+    _object->p4a_id = p4a_id;
+    _object->skycell_id = psStringCopy(skycell_id);
+    _object->tess_id = psStringCopy(tess_id);
     _object->exp_tag = psStringCopy(exp_tag);
     _object->p3_version = p3_version;
-    _object->class_id = psStringCopy(class_id);
     _object->uri = psStringCopy(uri);
-    _object->b1_uri = psStringCopy(b1_uri);
-    _object->b2_uri = psStringCopy(b2_uri);
+    _object->bg = bg;
+    _object->bg_mean_stdev = bg_mean_stdev;
 
     return _object;
 }
 
-static void p4WarpedImfileRowFree(p4WarpedImfileRow *object)
-{
+static void p4aScfileRowFree(p4aScfileRow *object)
+{
+    psFree(object->skycell_id);
+    psFree(object->tess_id);
     psFree(object->exp_tag);
-    psFree(object->class_id);
     psFree(object->uri);
-    psFree(object->b1_uri);
-    psFree(object->b2_uri);
-}
-
-bool p4WarpedImfileCreateTable(psDB *dbh)
+}
+
+bool p4aScfileCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -14334,9 +14174,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
@@ -14344,16 +14179,16 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, P4WARPEDIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4ASCFILE_TABLE_NAME, md);
 
     psFree(md);
@@ -14362,14 +14197,24 @@
 }
 
-bool p4WarpedImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, P4WARPEDIMFILE_TABLE_NAME);
-}
-
-bool p4WarpedImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri)
+bool p4aScfileDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4ASCFILE_TABLE_NAME);
+}
+
+bool p4aScfileInsert(psDB * dbh, psS32 p4a_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, p4a_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -14385,9 +14230,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
@@ -14395,16 +14235,16 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, b1_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, b2_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, P4WARPEDIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, bg)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, bg_mean_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4ASCFILE_TABLE_NAME, md);
     psFree(md);
 
@@ -14412,11 +14252,11 @@
 }
 
-long long p4WarpedImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long p4aScfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, P4WARPEDIMFILE_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, P4ASCFILE_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4WarpedImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aScfile");
         return count;
 
@@ -14426,13 +14266,13 @@
     return deleted;
 }
-bool p4WarpedImfileInsertObject(psDB *dbh, p4WarpedImfileRow *object)
-{
-    return p4WarpedImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id, object->uri, object->b1_uri, object->b2_uri);
-}
-
-bool p4WarpedImfileInsertObjects(psDB *dbh, psArray *objects)
+bool p4aScfileInsertObject(psDB *dbh, p4aScfileRow *object)
+{
+    return p4aScfileInsert(dbh, object->p4a_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->uri, object->bg, object->bg_mean_stdev);
+}
+
+bool p4aScfileInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!p4WarpedImfileInsertObject(dbh, objects->data[i])) {
+        if (!p4aScfileInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -14442,11 +14282,11 @@
 }
 
-bool p4WarpedImfileInsertFits(psDB *dbh, const psFits *fits)
+bool p4aScfileInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  P4WARPEDIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, P4WARPEDIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4WARPEDIMFILE_TABLE_NAME);
+    // move to (the first?) extension named  P4ASCFILE_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4ASCFILE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4ASCFILE_TABLE_NAME);
         return false;
     }
@@ -14466,5 +14306,5 @@
     }
 
-    if (!psDBInsertRows(dbh, P4WARPEDIMFILE_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, P4ASCFILE_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -14477,9 +14317,9 @@
 }
 
-bool p4WarpedImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool p4aScfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, P4WARPEDIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4ASCFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -14487,5 +14327,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, P4WARPEDIMFILE_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4ASCFILE_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -14498,9 +14338,19 @@
 }
 
-psMetadata *p4WarpedImfileMetadataFromObject(const p4WarpedImfileRow *object)
+psMetadata *p4aScfileMetadataFromObject(const p4aScfileRow *object)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4a_id", PS_DATA_S32, NULL, object->p4a_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4a_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -14516,9 +14366,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
@@ -14526,11 +14371,11 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, object->b1_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, object->b2_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, object->bg)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, object->bg_mean_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
         psFree(md);
         return false;
@@ -14541,11 +14386,21 @@
 }
 
-p4WarpedImfileRow *p4WarpedImfileObjectFromMetadata(psMetadata *md)
+p4aScfileRow *p4aScfileObjectFromMetadata(psMetadata *md)
 {
 
 bool status = false;
-    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
+    psS32 p4a_id = psMetadataLookupS32(&status, md, "p4a_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4a_id");
+        return false;
+    }
+    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
+        return false;
+    }
+    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
         return false;
     }
@@ -14560,9 +14415,4 @@
         return false;
     }
-    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
-        return false;
-    }
     char* uri = psMetadataLookupPtr(&status, md, "uri");
     if (!status) {
@@ -14570,18 +14420,18 @@
         return false;
     }
-    char* b1_uri = psMetadataLookupPtr(&status, md, "b1_uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b1_uri");
-        return false;
-    }
-    char* b2_uri = psMetadataLookupPtr(&status, md, "b2_uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b2_uri");
-        return false;
-    }
-
-    return p4WarpedImfileRowAlloc(p4_id, exp_tag, p3_version, class_id, uri, b1_uri, b2_uri);
-}
-psArray *p4WarpedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+    psF64 bg = psMetadataLookupF64(&status, md, "bg");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg");
+        return false;
+    }
+    psF64 bg_mean_stdev = psMetadataLookupF64(&status, md, "bg_mean_stdev");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_mean_stdev");
+        return false;
+    }
+
+    return p4aScfileRowAlloc(p4a_id, skycell_id, tess_id, exp_tag, p3_version, uri, bg, bg_mean_stdev);
+}
+psArray *p4aScfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -14589,5 +14439,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, P4WARPEDIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4ASCFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -14599,5 +14449,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        p4WarpedImfileRow *object = p4WarpedImfileObjectFromMetadata(rowSet->data[i]);
+        p4aScfileRow *object = p4aScfileObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -14608,11 +14458,11 @@
     return returnSet;
 }
-bool p4WarpedImfileDeleteObject(psDB *dbh, const p4WarpedImfileRow *object)
-{
-    psMetadata *where = p4WarpedImfileMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, P4WARPEDIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+bool p4aScfileDeleteObject(psDB *dbh, const p4aScfileRow *object)
+{
+    psMetadata *where = p4aScfileMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4ASCFILE_TABLE_NAME, where, 0);
+    psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4WarpedImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aScfile");
         return false;
     }
@@ -14620,21 +14470,21 @@
         // XXX should this be a psAbort() instead?  It is possible that
         // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "p4WarpedImfileRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long p4WarpedImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "p4aScfileRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4aScfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        p4WarpedImfileRow *object = objects->data[i];
-        psMetadata *where = p4WarpedImfileMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, P4WARPEDIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        p4aScfileRow *object = objects->data[i];
+        psMetadata *where = p4aScfileMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4ASCFILE_TABLE_NAME, where, limit);
+        psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4WarpedImfile");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4aScfile");
             return count;
         }
@@ -14645,5 +14495,5 @@
     return deleted;
 }
-bool p4WarpedImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool p4aScfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -14651,9 +14501,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = p4WarpedImfileMetadataFromObject(objects->data[i]);
+        psMetadata *md = p4aScfileMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            P4WARPEDIMFILE_TABLE_NAME,
+            P4ASCFILE_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -14676,9 +14526,9 @@
     return true;
 }
-bool p4WarpedImfilePrintObject(FILE *stream, p4WarpedImfileRow *object, bool mdcf)
+bool p4aScfilePrintObject(FILE *stream, p4aScfileRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = p4WarpedImfileMetadataFromObject(object);
+    psMetadata *md = p4aScfileMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -14691,60 +14541,52 @@
     return true;
 }
-static void p4StackedImfileRowFree(p4StackedImfileRow *object);
-
-p4StackedImfileRow *p4StackedImfileRowAlloc(psS32 p4_id, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri)
-{
-    p4StackedImfileRow *_object;
-
-    _object = psAlloc(sizeof(p4StackedImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)p4StackedImfileRowFree);
-
-    _object->p4_id = p4_id;
-    _object->class_id = psStringCopy(class_id);
-    _object->uri = psStringCopy(uri);
-    _object->b1_uri = psStringCopy(b1_uri);
-    _object->b2_uri = psStringCopy(b2_uri);
+static void p4bRunRowFree(p4bRunRow *object);
+
+p4bRunRow *p4bRunRowAlloc(psS32 p4b_id, const char *state, const char *workdir, bool magic)
+{
+    p4bRunRow       *_object;
+
+    _object = psAlloc(sizeof(p4bRunRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4bRunRowFree);
+
+    _object->p4b_id = p4b_id;
+    _object->state = psStringCopy(state);
+    _object->workdir = psStringCopy(workdir);
+    _object->magic = magic;
 
     return _object;
 }
 
-static void p4StackedImfileRowFree(p4StackedImfileRow *object)
-{
-    psFree(object->class_id);
-    psFree(object->uri);
-    psFree(object->b1_uri);
-    psFree(object->b2_uri);
-}
-
-bool p4StackedImfileCreateTable(psDB *dbh)
+static void p4bRunRowFree(p4bRunRow *object)
+{
+    psFree(object->state);
+    psFree(object->workdir);
+}
+
+bool p4bRunCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, P4STACKEDIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, "Primary Key AUTO_INCREMENT", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4BRUN_TABLE_NAME, md);
 
     psFree(md);
@@ -14753,39 +14595,34 @@
 }
 
-bool p4StackedImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, P4STACKEDIMFILE_TABLE_NAME);
-}
-
-bool p4StackedImfileInsert(psDB * dbh, psS32 p4_id, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri)
+bool p4bRunDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4BRUN_TABLE_NAME);
+}
+
+bool p4bRunInsert(psDB * dbh, psS32 p4b_id, const char *state, const char *workdir, bool magic)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, b1_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, b2_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, P4STACKEDIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, p4b_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, magic)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4BRUN_TABLE_NAME, md);
     psFree(md);
 
@@ -14793,11 +14630,11 @@
 }
 
-long long p4StackedImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long p4bRunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, P4STACKEDIMFILE_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, P4BRUN_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4StackedImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bRun");
         return count;
 
@@ -14807,13 +14644,13 @@
     return deleted;
 }
-bool p4StackedImfileInsertObject(psDB *dbh, p4StackedImfileRow *object)
-{
-    return p4StackedImfileInsert(dbh, object->p4_id, object->class_id, object->uri, object->b1_uri, object->b2_uri);
-}
-
-bool p4StackedImfileInsertObjects(psDB *dbh, psArray *objects)
+bool p4bRunInsertObject(psDB *dbh, p4bRunRow *object)
+{
+    return p4bRunInsert(dbh, object->p4b_id, object->state, object->workdir, object->magic);
+}
+
+bool p4bRunInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!p4StackedImfileInsertObject(dbh, objects->data[i])) {
+        if (!p4bRunInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -14823,11 +14660,11 @@
 }
 
-bool p4StackedImfileInsertFits(psDB *dbh, const psFits *fits)
+bool p4bRunInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  P4STACKEDIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, P4STACKEDIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4STACKEDIMFILE_TABLE_NAME);
+    // move to (the first?) extension named  P4BRUN_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4BRUN_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4BRUN_TABLE_NAME);
         return false;
     }
@@ -14847,5 +14684,5 @@
     }
 
-    if (!psDBInsertRows(dbh, P4STACKEDIMFILE_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, P4BRUN_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -14858,9 +14695,9 @@
 }
 
-bool p4StackedImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool p4bRunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, P4STACKEDIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4BRUN_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -14868,5 +14705,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, P4STACKEDIMFILE_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4BRUN_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -14879,29 +14716,24 @@
 }
 
-psMetadata *p4StackedImfileMetadataFromObject(const p4StackedImfileRow *object)
+psMetadata *p4bRunMetadataFromObject(const p4bRunRow *object)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, object->b1_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, object->b2_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, object->p4b_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, object->magic)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
         psFree(md);
         return false;
@@ -14912,37 +14744,32 @@
 }
 
-p4StackedImfileRow *p4StackedImfileObjectFromMetadata(psMetadata *md)
+p4bRunRow *p4bRunObjectFromMetadata(psMetadata *md)
 {
 
 bool status = false;
-    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
-        return false;
-    }
-    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
-        return false;
-    }
-    char* uri = psMetadataLookupPtr(&status, md, "uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
-        return false;
-    }
-    char* b1_uri = psMetadataLookupPtr(&status, md, "b1_uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b1_uri");
-        return false;
-    }
-    char* b2_uri = psMetadataLookupPtr(&status, md, "b2_uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b2_uri");
-        return false;
-    }
-
-    return p4StackedImfileRowAlloc(p4_id, class_id, uri, b1_uri, b2_uri);
-}
-psArray *p4StackedImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+    psS32 p4b_id = psMetadataLookupS32(&status, md, "p4b_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4b_id");
+        return false;
+    }
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
+        return false;
+    }
+    char* workdir = psMetadataLookupPtr(&status, md, "workdir");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
+        return false;
+    }
+    bool magic = psMetadataLookupBool(&status, md, "magic");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic");
+        return false;
+    }
+
+    return p4bRunRowAlloc(p4b_id, state, workdir, magic);
+}
+psArray *p4bRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -14950,5 +14777,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, P4STACKEDIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4BRUN_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -14960,5 +14787,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        p4StackedImfileRow *object = p4StackedImfileObjectFromMetadata(rowSet->data[i]);
+        p4bRunRow *object = p4bRunObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -14969,11 +14796,11 @@
     return returnSet;
 }
-bool p4StackedImfileDeleteObject(psDB *dbh, const p4StackedImfileRow *object)
-{
-    psMetadata *where = p4StackedImfileMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, P4STACKEDIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+bool p4bRunDeleteObject(psDB *dbh, const p4bRunRow *object)
+{
+    psMetadata *where = p4bRunMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4BRUN_TABLE_NAME, where, 0);
+    psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4StackedImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bRun");
         return false;
     }
@@ -14981,21 +14808,21 @@
         // XXX should this be a psAbort() instead?  It is possible that
         // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "p4StackedImfileRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long p4StackedImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "p4bRunRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4bRunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        p4StackedImfileRow *object = objects->data[i];
-        psMetadata *where = p4StackedImfileMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, P4STACKEDIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        p4bRunRow *object = objects->data[i];
+        psMetadata *where = p4bRunMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4BRUN_TABLE_NAME, where, limit);
+        psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4StackedImfile");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bRun");
             return count;
         }
@@ -15006,5 +14833,5 @@
     return deleted;
 }
-bool p4StackedImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool p4bRunPrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -15012,9 +14839,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = p4StackedImfileMetadataFromObject(objects->data[i]);
+        psMetadata *md = p4bRunMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            P4STACKEDIMFILE_TABLE_NAME,
+            P4BRUN_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -15037,9 +14864,9 @@
     return true;
 }
-bool p4StackedImfilePrintObject(FILE *stream, p4StackedImfileRow *object, bool mdcf)
+bool p4bRunPrintObject(FILE *stream, p4bRunRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = p4StackedImfileMetadataFromObject(object);
+    psMetadata *md = p4bRunMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -15052,38 +14879,46 @@
     return true;
 }
-static void p4DiffImfileRowFree(p4DiffImfileRow *object);
-
-p4DiffImfileRow *p4DiffImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri)
-{
-    p4DiffImfileRow *_object;
-
-    _object = psAlloc(sizeof(p4DiffImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)p4DiffImfileRowFree);
-
-    _object->p4_id = p4_id;
+static void p4bInputScfileRowFree(p4bInputScfileRow *object);
+
+p4bInputScfileRow *p4bInputScfileRowAlloc(psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *kind)
+{
+    p4bInputScfileRow *_object;
+
+    _object = psAlloc(sizeof(p4bInputScfileRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4bInputScfileRowFree);
+
+    _object->p4b_id = p4b_id;
+    _object->skycell_id = psStringCopy(skycell_id);
+    _object->tess_id = psStringCopy(tess_id);
     _object->exp_tag = psStringCopy(exp_tag);
     _object->p3_version = p3_version;
-    _object->class_id = psStringCopy(class_id);
-    _object->uri = psStringCopy(uri);
-    _object->b1_uri = psStringCopy(b1_uri);
-    _object->b2_uri = psStringCopy(b2_uri);
+    _object->kind = psStringCopy(kind);
 
     return _object;
 }
 
-static void p4DiffImfileRowFree(p4DiffImfileRow *object)
-{
+static void p4bInputScfileRowFree(p4bInputScfileRow *object)
+{
+    psFree(object->skycell_id);
+    psFree(object->tess_id);
     psFree(object->exp_tag);
-    psFree(object->class_id);
-    psFree(object->uri);
-    psFree(object->b1_uri);
-    psFree(object->b2_uri);
-}
-
-bool p4DiffImfileCreateTable(psDB *dbh)
+    psFree(object->kind);
+}
+
+bool p4bInputScfileCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -15099,26 +14934,11 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, "255")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBCreateTable(dbh, P4DIFFIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4BINPUTSCFILE_TABLE_NAME, md);
 
     psFree(md);
@@ -15127,14 +14947,24 @@
 }
 
-bool p4DiffImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, P4DIFFIMFILE_TABLE_NAME);
-}
-
-bool p4DiffImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri, const char *b1_uri, const char *b2_uri)
+bool p4bInputScfileDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4BINPUTSCFILE_TABLE_NAME);
+}
+
+bool p4bInputScfileInsert(psDB * dbh, psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *kind)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, p4b_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -15150,26 +14980,11 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, b1_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, b2_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
-        psFree(md);
-        return false;
-    }
-
-    bool status = psDBInsertOneRow(dbh, P4DIFFIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, kind)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4BINPUTSCFILE_TABLE_NAME, md);
     psFree(md);
 
@@ -15177,11 +14992,11 @@
 }
 
-long long p4DiffImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long p4bInputScfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, P4DIFFIMFILE_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, P4BINPUTSCFILE_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4DiffImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bInputScfile");
         return count;
 
@@ -15191,13 +15006,13 @@
     return deleted;
 }
-bool p4DiffImfileInsertObject(psDB *dbh, p4DiffImfileRow *object)
-{
-    return p4DiffImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id, object->uri, object->b1_uri, object->b2_uri);
-}
-
-bool p4DiffImfileInsertObjects(psDB *dbh, psArray *objects)
+bool p4bInputScfileInsertObject(psDB *dbh, p4bInputScfileRow *object)
+{
+    return p4bInputScfileInsert(dbh, object->p4b_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->kind);
+}
+
+bool p4bInputScfileInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!p4DiffImfileInsertObject(dbh, objects->data[i])) {
+        if (!p4bInputScfileInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -15207,11 +15022,11 @@
 }
 
-bool p4DiffImfileInsertFits(psDB *dbh, const psFits *fits)
+bool p4bInputScfileInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  P4DIFFIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, P4DIFFIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4DIFFIMFILE_TABLE_NAME);
+    // move to (the first?) extension named  P4BINPUTSCFILE_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4BINPUTSCFILE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4BINPUTSCFILE_TABLE_NAME);
         return false;
     }
@@ -15231,5 +15046,5 @@
     }
 
-    if (!psDBInsertRows(dbh, P4DIFFIMFILE_TABLE_NAME, rowSet)) {
+    if (!psDBInsertRows(dbh, P4BINPUTSCFILE_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
         psFree(rowSet);
@@ -15242,9 +15057,9 @@
 }
 
-bool p4DiffImfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+bool p4bInputScfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
 
-    rowSet = psDBSelectRows(dbh, P4DIFFIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4BINPUTSCFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return false;
@@ -15252,5 +15067,5 @@
 
     // output to fits
-    if (!psFitsWriteTable(fits, NULL, rowSet, P4DIFFIMFILE_TABLE_NAME)) {
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4BINPUTSCFILE_TABLE_NAME)) {
         psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
         psFree(rowSet);
@@ -15263,9 +15078,19 @@
 }
 
-psMetadata *p4DiffImfileMetadataFromObject(const p4DiffImfileRow *object)
+psMetadata *p4bInputScfileMetadataFromObject(const p4bInputScfileRow *object)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, object->p4b_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -15281,21 +15106,6 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b1_uri", PS_DATA_STRING, NULL, object->b1_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b1_uri");
-        psFree(md);
-        return false;
-    }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "b2_uri", PS_DATA_STRING, NULL, object->b2_uri)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item b2_uri");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "kind", PS_DATA_STRING, NULL, object->kind)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item kind");
         psFree(md);
         return false;
@@ -15306,11 +15116,21 @@
 }
 
-p4DiffImfileRow *p4DiffImfileObjectFromMetadata(psMetadata *md)
+p4bInputScfileRow *p4bInputScfileObjectFromMetadata(psMetadata *md)
 {
 
 bool status = false;
-    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
+    psS32 p4b_id = psMetadataLookupS32(&status, md, "p4b_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4b_id");
+        return false;
+    }
+    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
+        return false;
+    }
+    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
         return false;
     }
@@ -15325,28 +15145,13 @@
         return false;
     }
-    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
-        return false;
-    }
-    char* uri = psMetadataLookupPtr(&status, md, "uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
-        return false;
-    }
-    char* b1_uri = psMetadataLookupPtr(&status, md, "b1_uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b1_uri");
-        return false;
-    }
-    char* b2_uri = psMetadataLookupPtr(&status, md, "b2_uri");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item b2_uri");
-        return false;
-    }
-
-    return p4DiffImfileRowAlloc(p4_id, exp_tag, p3_version, class_id, uri, b1_uri, b2_uri);
-}
-psArray *p4DiffImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+    char* kind = psMetadataLookupPtr(&status, md, "kind");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item kind");
+        return false;
+    }
+
+    return p4bInputScfileRowAlloc(p4b_id, skycell_id, tess_id, exp_tag, p3_version, kind);
+}
+psArray *p4bInputScfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     psArray         *rowSet;
@@ -15354,5 +15159,5 @@
     psU64           i;
 
-    rowSet = psDBSelectRows(dbh, P4DIFFIMFILE_TABLE_NAME, where, limit);
+    rowSet = psDBSelectRows(dbh, P4BINPUTSCFILE_TABLE_NAME, where, limit);
     if (!rowSet) {
         return NULL;
@@ -15364,5 +15169,5 @@
 
     for (i = 0; i < rowSet->n; i++) {
-        p4DiffImfileRow *object = p4DiffImfileObjectFromMetadata(rowSet->data[i]);
+        p4bInputScfileRow *object = p4bInputScfileObjectFromMetadata(rowSet->data[i]);
         psArrayAdd(returnSet, 0, object);
         psFree(object);
@@ -15373,11 +15178,11 @@
     return returnSet;
 }
-bool p4DiffImfileDeleteObject(psDB *dbh, const p4DiffImfileRow *object)
-{
-    psMetadata *where = p4DiffImfileMetadataFromObject(object);
-    long long count = psDBDeleteRows(dbh, P4DIFFIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+bool p4bInputScfileDeleteObject(psDB *dbh, const p4bInputScfileRow *object)
+{
+    psMetadata *where = p4bInputScfileMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4BINPUTSCFILE_TABLE_NAME, where, 0);
+    psFree(where);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4DiffImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bInputScfile");
         return false;
     }
@@ -15385,21 +15190,21 @@
         // XXX should this be a psAbort() instead?  It is possible that
         // having an object match multiple rows was by design.
-        psError(PS_ERR_UNKNOWN, true, "p4DiffImfileRow object matched more then one row.  Check your database schema");
-        return false;
-    }
-
-    return true;
-}
-long long p4DiffImfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+        psError(PS_ERR_UNKNOWN, true, "p4bInputScfileRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4bInputScfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
 {
     long long       deleted = 0;
 
     for (long long i = 0; i < objects->n; i++) {
-        p4DiffImfileRow *object = objects->data[i];
-        psMetadata *where = p4DiffImfileMetadataFromObject(object);
-        long long count = psDBDeleteRows(dbh, P4DIFFIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        p4bInputScfileRow *object = objects->data[i];
+        psMetadata *where = p4bInputScfileMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4BINPUTSCFILE_TABLE_NAME, where, limit);
+        psFree(where);
         if (count < 0) {
-            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4DiffImfile");
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bInputScfile");
             return count;
         }
@@ -15410,5 +15215,5 @@
     return deleted;
 }
-bool p4DiffImfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+bool p4bInputScfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(objects, false);
@@ -15416,9 +15221,9 @@
     psMetadata *output = psMetadataAlloc();
     for (long i = 0; i < psArrayLength(objects); i++) {
-        psMetadata *md = p4DiffImfileMetadataFromObject(objects->data[i]);
+        psMetadata *md = p4bInputScfileMetadataFromObject(objects->data[i]);
         if (!psMetadataAddMetadata(
             output,
             PS_LIST_TAIL,
-            P4DIFFIMFILE_TABLE_NAME,
+            P4BINPUTSCFILE_TABLE_NAME,
             PS_META_DUPLICATE_OK,
             NULL,
@@ -15441,9 +15246,9 @@
     return true;
 }
-bool p4DiffImfilePrintObject(FILE *stream, p4DiffImfileRow *object, bool mdcf)
+bool p4bInputScfilePrintObject(FILE *stream, p4bInputScfileRow *object, bool mdcf)
 {
     PS_ASSERT_PTR_NON_NULL(object, false);
 
-    psMetadata *md = p4DiffImfileMetadataFromObject(object);
+    psMetadata *md = p4bInputScfileMetadataFromObject(object);
 
     if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
@@ -15456,34 +15261,48 @@
     return true;
 }
-static void p4MagicMaskImfileRowFree(p4MagicMaskImfileRow *object);
-
-p4MagicMaskImfileRow *p4MagicMaskImfileRowAlloc(psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri)
-{
-    p4MagicMaskImfileRow *_object;
-
-    _object = psAlloc(sizeof(p4MagicMaskImfileRow));
-    psMemSetDeallocator(_object, (psFreeFunc)p4MagicMaskImfileRowFree);
-
-    _object->p4_id = p4_id;
+static void p4bDiffScfileRowFree(p4bDiffScfileRow *object);
+
+p4bDiffScfileRow *p4bDiffScfileRowAlloc(psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
+{
+    p4bDiffScfileRow *_object;
+
+    _object = psAlloc(sizeof(p4bDiffScfileRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4bDiffScfileRowFree);
+
+    _object->p4b_id = p4b_id;
+    _object->skycell_id = psStringCopy(skycell_id);
+    _object->tess_id = psStringCopy(tess_id);
     _object->exp_tag = psStringCopy(exp_tag);
     _object->p3_version = p3_version;
-    _object->class_id = psStringCopy(class_id);
     _object->uri = psStringCopy(uri);
+    _object->bg = bg;
+    _object->bg_mean_stdev = bg_mean_stdev;
 
     return _object;
 }
 
-static void p4MagicMaskImfileRowFree(p4MagicMaskImfileRow *object)
-{
+static void p4bDiffScfileRowFree(p4bDiffScfileRow *object)
+{
+    psFree(object->skycell_id);
+    psFree(object->tess_id);
     psFree(object->exp_tag);
-    psFree(object->class_id);
     psFree(object->uri);
 }
 
-bool p4MagicMaskImfileCreateTable(psDB *dbh)
+bool p4bDiffScfileCreateTable(psDB *dbh)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, "Primary Key", 0)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -15499,9 +15318,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
@@ -15509,6 +15323,16 @@
         return false;
     }
-
-    bool status = psDBCreateTable(dbh, P4MAGICMASKIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4BDIFFSCFILE_TABLE_NAME, md);
 
     psFree(md);
@@ -15517,14 +15341,24 @@
 }
 
-bool p4MagicMaskImfileDropTable(psDB *dbh)
-{
-    return psDBDropTable(dbh, P4MAGICMASKIMFILE_TABLE_NAME);
-}
-
-bool p4MagicMaskImfileInsert(psDB * dbh, psS32 p4_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri)
+bool p4bDiffScfileDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4BDIFFSCFILE_TABLE_NAME);
+}
+
+bool p4bDiffScfileInsert(psDB * dbh, psS32 p4b_id, const char *skycell_id, const char *tess_id, const char *exp_tag, psS32 p3_version, const char *uri, psF64 bg, psF64 bg_mean_stdev)
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, p4b_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
         psFree(md);
         return false;
@@ -15540,9 +15374,4 @@
         return false;
     }
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
-        psFree(md);
-        return false;
-    }
     if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
         psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
@@ -15550,6 +15379,16 @@
         return false;
     }
-
-    bool status = psDBInsertOneRow(dbh, P4MAGICMASKIMFILE_TABLE_NAME, md);
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, bg)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, bg_mean_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4BDIFFSCFILE_TABLE_NAME, md);
     psFree(md);
 
@@ -15557,11 +15396,11 @@
 }
 
-long long p4MagicMaskImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+long long p4bDiffScfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
 {
     long long       deleted = 0;
 
-    long long count = psDBDeleteRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, limit);
+    long long count = psDBDeleteRows(dbh, P4BDIFFSCFILE_TABLE_NAME, where, limit);
     if (count < 0) {
-        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4MagicMaskImfile");
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bDiffScfile");
         return count;
 
@@ -15571,13 +15410,13 @@
     return deleted;
 }
-bool p4MagicMaskImfileInsertObject(psDB *dbh, p4MagicMaskImfileRow *object)
-{
-    return p4MagicMaskImfileInsert(dbh, object->p4_id, object->exp_tag, object->p3_version, object->class_id, object->uri);
-}
-
-bool p4MagicMaskImfileInsertObjects(psDB *dbh, psArray *objects)
+bool p4bDiffScfileInsertObject(psDB *dbh, p4bDiffScfileRow *object)
+{
+    return p4bDiffScfileInsert(dbh, object->p4b_id, object->skycell_id, object->tess_id, object->exp_tag, object->p3_version, object->uri, object->bg, object->bg_mean_stdev);
+}
+
+bool p4bDiffScfileInsertObjects(psDB *dbh, psArray *objects)
 {
     for (long i = 0; i < psArrayLength(objects); i++) {
-        if (!p4MagicMaskImfileInsertObject(dbh, objects->data[i])) {
+        if (!p4bDiffScfileInsertObject(dbh, objects->data[i])) {
             return false;
         }
@@ -15587,11 +15426,11 @@
 }
 
-bool p4MagicMaskImfileInsertFits(psDB *dbh, const psFits *fits)
+bool p4bDiffScfileInsertFits(psDB *dbh, const psFits *fits)
 {
     psArray         *rowSet;
 
-    // move to (the first?) extension named  P4MAGICMASKIMFILE_TABLE_NAME
-    if (!psFitsMoveExtName(fits, P4MAGICMASKIMFILE_TABLE_NAME)) {
-        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4MAGICMASKIMFILE_TABLE_NAME);
+    // move to (the first?) extension named  P4BDIFFSCFILE_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4BDIFFSCFILE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4BDIFFSCFILE_TABLE_NAME);
         return false;
     }
@@ -15611,4 +15450,1048 @@
     }
 
+    if (!psDBInsertRows(dbh, P4BDIFFSCFILE_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool p4bDiffScfileSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, P4BDIFFSCFILE_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4BDIFFSCFILE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *p4bDiffScfileMetadataFromObject(const p4bDiffScfileRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4b_id", PS_DATA_S32, NULL, object->p4b_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4b_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, object->uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg", PS_DATA_F64, NULL, object->bg)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "bg_mean_stdev", PS_DATA_F64, NULL, object->bg_mean_stdev)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item bg_mean_stdev");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+p4bDiffScfileRow *p4bDiffScfileObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    psS32 p4b_id = psMetadataLookupS32(&status, md, "p4b_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4b_id");
+        return false;
+    }
+    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
+        return false;
+    }
+    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
+        return false;
+    }
+    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+        return false;
+    }
+    psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version");
+        return false;
+    }
+    char* uri = psMetadataLookupPtr(&status, md, "uri");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item uri");
+        return false;
+    }
+    psF64 bg = psMetadataLookupF64(&status, md, "bg");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg");
+        return false;
+    }
+    psF64 bg_mean_stdev = psMetadataLookupF64(&status, md, "bg_mean_stdev");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item bg_mean_stdev");
+        return false;
+    }
+
+    return p4bDiffScfileRowAlloc(p4b_id, skycell_id, tess_id, exp_tag, p3_version, uri, bg, bg_mean_stdev);
+}
+psArray *p4bDiffScfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, P4BDIFFSCFILE_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        p4bDiffScfileRow *object = p4bDiffScfileObjectFromMetadata(rowSet->data[i]);
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool p4bDiffScfileDeleteObject(psDB *dbh, const p4bDiffScfileRow *object)
+{
+    psMetadata *where = p4bDiffScfileMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4BDIFFSCFILE_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bDiffScfile");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "p4bDiffScfileRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4bDiffScfileDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        p4bDiffScfileRow *object = objects->data[i];
+        psMetadata *where = p4bDiffScfileMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4BDIFFSCFILE_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4bDiffScfile");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool p4bDiffScfilePrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = p4bDiffScfileMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            P4BDIFFSCFILE_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool p4bDiffScfilePrintObject(FILE *stream, p4bDiffScfileRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = p4bDiffScfileMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
+static void p4cRunRowFree(p4cRunRow *object);
+
+p4cRunRow *p4cRunRowAlloc(psS32 p4c_id, const char *state, const char *workdir, bool magic)
+{
+    p4cRunRow       *_object;
+
+    _object = psAlloc(sizeof(p4cRunRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4cRunRowFree);
+
+    _object->p4c_id = p4c_id;
+    _object->state = psStringCopy(state);
+    _object->workdir = psStringCopy(workdir);
+    _object->magic = magic;
+
+    return _object;
+}
+
+static void p4cRunRowFree(p4cRunRow *object)
+{
+    psFree(object->state);
+    psFree(object->workdir);
+}
+
+bool p4cRunCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, "Primary Key AUTO_INCREMENT", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, "Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4CRUN_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool p4cRunDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4CRUN_TABLE_NAME);
+}
+
+bool p4cRunInsert(psDB * dbh, psS32 p4c_id, const char *state, const char *workdir, bool magic)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, p4c_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, workdir)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, magic)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4CRUN_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long p4cRunDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, P4CRUN_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4cRun");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool p4cRunInsertObject(psDB *dbh, p4cRunRow *object)
+{
+    return p4cRunInsert(dbh, object->p4c_id, object->state, object->workdir, object->magic);
+}
+
+bool p4cRunInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!p4cRunInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool p4cRunInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  P4CRUN_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4CRUN_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4CRUN_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
+    if (!psDBInsertRows(dbh, P4CRUN_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool p4cRunSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, P4CRUN_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4CRUN_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *p4cRunMetadataFromObject(const p4cRunRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, object->p4c_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "state", PS_DATA_STRING, NULL, object->state)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item state");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "workdir", PS_DATA_STRING, NULL, object->workdir)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item workdir");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, object->magic)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item magic");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+p4cRunRow *p4cRunObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    psS32 p4c_id = psMetadataLookupS32(&status, md, "p4c_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4c_id");
+        return false;
+    }
+    char* state = psMetadataLookupPtr(&status, md, "state");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item state");
+        return false;
+    }
+    char* workdir = psMetadataLookupPtr(&status, md, "workdir");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item workdir");
+        return false;
+    }
+    bool magic = psMetadataLookupBool(&status, md, "magic");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item magic");
+        return false;
+    }
+
+    return p4cRunRowAlloc(p4c_id, state, workdir, magic);
+}
+psArray *p4cRunSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, P4CRUN_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        p4cRunRow *object = p4cRunObjectFromMetadata(rowSet->data[i]);
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool p4cRunDeleteObject(psDB *dbh, const p4cRunRow *object)
+{
+    psMetadata *where = p4cRunMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4CRUN_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4cRun");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "p4cRunRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4cRunDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        p4cRunRow *object = objects->data[i];
+        psMetadata *where = p4cRunMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4CRUN_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4cRun");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool p4cRunPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = p4cRunMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            P4CRUN_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool p4cRunPrintObject(FILE *stream, p4cRunRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = p4cRunMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
+static void p4cInputExpRowFree(p4cInputExpRow *object);
+
+p4cInputExpRow *p4cInputExpRowAlloc(psS32 p4c_id, const char *exp_tag, psS32 p3_version)
+{
+    p4cInputExpRow  *_object;
+
+    _object = psAlloc(sizeof(p4cInputExpRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4cInputExpRowFree);
+
+    _object->p4c_id = p4c_id;
+    _object->exp_tag = psStringCopy(exp_tag);
+    _object->p3_version = p3_version;
+
+    return _object;
+}
+
+static void p4cInputExpRowFree(p4cInputExpRow *object)
+{
+    psFree(object->exp_tag);
+}
+
+bool p4cInputExpCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4CINPUTEXP_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool p4cInputExpDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4CINPUTEXP_TABLE_NAME);
+}
+
+bool p4cInputExpInsert(psDB * dbh, psS32 p4c_id, const char *exp_tag, psS32 p3_version)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, p4c_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4CINPUTEXP_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long p4cInputExpDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, P4CINPUTEXP_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4cInputExp");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool p4cInputExpInsertObject(psDB *dbh, p4cInputExpRow *object)
+{
+    return p4cInputExpInsert(dbh, object->p4c_id, object->exp_tag, object->p3_version);
+}
+
+bool p4cInputExpInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!p4cInputExpInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool p4cInputExpInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  P4CINPUTEXP_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4CINPUTEXP_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4CINPUTEXP_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
+    if (!psDBInsertRows(dbh, P4CINPUTEXP_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool p4cInputExpSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, P4CINPUTEXP_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, P4CINPUTEXP_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *p4cInputExpMetadataFromObject(const p4cInputExpRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, object->p4c_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, object->p3_version)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+p4cInputExpRow *p4cInputExpObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    psS32 p4c_id = psMetadataLookupS32(&status, md, "p4c_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4c_id");
+        return false;
+    }
+    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+        return false;
+    }
+    psS32 p3_version = psMetadataLookupS32(&status, md, "p3_version");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p3_version");
+        return false;
+    }
+
+    return p4cInputExpRowAlloc(p4c_id, exp_tag, p3_version);
+}
+psArray *p4cInputExpSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, P4CINPUTEXP_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        p4cInputExpRow *object = p4cInputExpObjectFromMetadata(rowSet->data[i]);
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool p4cInputExpDeleteObject(psDB *dbh, const p4cInputExpRow *object)
+{
+    psMetadata *where = p4cInputExpMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, P4CINPUTEXP_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4cInputExp");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "p4cInputExpRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long p4cInputExpDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        p4cInputExpRow *object = objects->data[i];
+        psMetadata *where = p4cInputExpMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, P4CINPUTEXP_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4cInputExp");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool p4cInputExpPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = p4cInputExpMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            P4CINPUTEXP_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool p4cInputExpPrintObject(FILE *stream, p4cInputExpRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = p4cInputExpMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
+static void p4MagicMaskImfileRowFree(p4MagicMaskImfileRow *object);
+
+p4MagicMaskImfileRow *p4MagicMaskImfileRowAlloc(psS32 p4c_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri)
+{
+    p4MagicMaskImfileRow *_object;
+
+    _object = psAlloc(sizeof(p4MagicMaskImfileRow));
+    psMemSetDeallocator(_object, (psFreeFunc)p4MagicMaskImfileRowFree);
+
+    _object->p4c_id = p4c_id;
+    _object->exp_tag = psStringCopy(exp_tag);
+    _object->p3_version = p3_version;
+    _object->class_id = psStringCopy(class_id);
+    _object->uri = psStringCopy(uri);
+
+    return _object;
+}
+
+static void p4MagicMaskImfileRowFree(p4MagicMaskImfileRow *object)
+{
+    psFree(object->exp_tag);
+    psFree(object->class_id);
+    psFree(object->uri);
+}
+
+bool p4MagicMaskImfileCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, "Primary Key", 0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, "255")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, P4MAGICMASKIMFILE_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool p4MagicMaskImfileDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, P4MAGICMASKIMFILE_TABLE_NAME);
+}
+
+bool p4MagicMaskImfileInsert(psDB * dbh, psS32 p4c_id, const char *exp_tag, psS32 p3_version, const char *class_id, const char *uri)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, p4c_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p3_version", PS_DATA_S32, NULL, p3_version)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p3_version");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "uri", PS_DATA_STRING, NULL, uri)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item uri");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, P4MAGICMASKIMFILE_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long p4MagicMaskImfileDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4MagicMaskImfile");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool p4MagicMaskImfileInsertObject(psDB *dbh, p4MagicMaskImfileRow *object)
+{
+    return p4MagicMaskImfileInsert(dbh, object->p4c_id, object->exp_tag, object->p3_version, object->class_id, object->uri);
+}
+
+bool p4MagicMaskImfileInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!p4MagicMaskImfileInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool p4MagicMaskImfileInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  P4MAGICMASKIMFILE_TABLE_NAME
+    if (!psFitsMoveExtName(fits, P4MAGICMASKIMFILE_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", P4MAGICMASKIMFILE_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
     if (!psDBInsertRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, rowSet)) {
         psError(PS_ERR_UNKNOWN, false, "databse insert failed");
@@ -15646,6 +16529,6 @@
 {
     psMetadata *md = psMetadataAlloc();
-    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4_id", PS_DATA_S32, NULL, object->p4_id)) {
-        psError(PS_ERR_UNKNOWN, false, "failed to add item p4_id");
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "p4c_id", PS_DATA_S32, NULL, object->p4c_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item p4c_id");
         psFree(md);
         return false;
@@ -15680,7 +16563,7 @@
 
 bool status = false;
-    psS32 p4_id = psMetadataLookupS32(&status, md, "p4_id");
-    if (!status) {
-        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4_id");
+    psS32 p4c_id = psMetadataLookupS32(&status, md, "p4c_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item p4c_id");
         return false;
     }
@@ -15706,5 +16589,5 @@
     }
 
-    return p4MagicMaskImfileRowAlloc(p4_id, exp_tag, p3_version, class_id, uri);
+    return p4MagicMaskImfileRowAlloc(p4c_id, exp_tag, p3_version, class_id, uri);
 }
 psArray *p4MagicMaskImfileSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
@@ -15737,5 +16620,5 @@
     psMetadata *where = p4MagicMaskImfileMetadataFromObject(object);
     long long count = psDBDeleteRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, 0);
-    psFree(where)
+    psFree(where);
     if (count < 0) {
         psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4MagicMaskImfile");
@@ -15759,5 +16642,5 @@
         psMetadata *where = p4MagicMaskImfileMetadataFromObject(object);
         long long count = psDBDeleteRows(dbh, P4MAGICMASKIMFILE_TABLE_NAME, where, limit);
-        psFree(where)
+        psFree(where);
         if (count < 0) {
             psError(PS_ERR_UNKNOWN, true, "failed to delete row from p4MagicMaskImfile");
@@ -15816,2 +16699,806 @@
     return true;
 }
+static void skyCellRowFree(skyCellRow *object);
+
+skyCellRow *skyCellRowAlloc(const char *skycell_id, const char *tess_id, psF64 ra1, psF64 decl1, psF64 ra2, psF64 decl2, psF64 ra3, psF64 decl3, psF64 ra4, psF64 decl4)
+{
+    skyCellRow      *_object;
+
+    _object = psAlloc(sizeof(skyCellRow));
+    psMemSetDeallocator(_object, (psFreeFunc)skyCellRowFree);
+
+    _object->skycell_id = psStringCopy(skycell_id);
+    _object->tess_id = psStringCopy(tess_id);
+    _object->ra1 = ra1;
+    _object->decl1 = decl1;
+    _object->ra2 = ra2;
+    _object->decl2 = decl2;
+    _object->ra3 = ra3;
+    _object->decl3 = decl3;
+    _object->ra4 = ra4;
+    _object->decl4 = decl4;
+
+    return _object;
+}
+
+static void skyCellRowFree(skyCellRow *object)
+{
+    psFree(object->skycell_id);
+    psFree(object->tess_id);
+}
+
+bool skyCellCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra1", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl1", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra2", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra2");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl2", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl2");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra3", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra3");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl3", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl3");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra4", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra4");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl4", PS_DATA_F64, NULL, 0.0)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl4");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, SKYCELL_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool skyCellDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, SKYCELL_TABLE_NAME);
+}
+
+bool skyCellInsert(psDB * dbh, const char *skycell_id, const char *tess_id, psF64 ra1, psF64 decl1, psF64 ra2, psF64 decl2, psF64 ra3, psF64 decl3, psF64 ra4, psF64 decl4)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra1", PS_DATA_F64, NULL, ra1)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl1", PS_DATA_F64, NULL, decl1)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra2", PS_DATA_F64, NULL, ra2)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra2");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl2", PS_DATA_F64, NULL, decl2)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl2");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra3", PS_DATA_F64, NULL, ra3)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra3");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl3", PS_DATA_F64, NULL, decl3)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl3");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra4", PS_DATA_F64, NULL, ra4)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra4");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl4", PS_DATA_F64, NULL, decl4)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl4");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, SKYCELL_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long skyCellDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, SKYCELL_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCell");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool skyCellInsertObject(psDB *dbh, skyCellRow *object)
+{
+    return skyCellInsert(dbh, object->skycell_id, object->tess_id, object->ra1, object->decl1, object->ra2, object->decl2, object->ra3, object->decl3, object->ra4, object->decl4);
+}
+
+bool skyCellInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!skyCellInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool skyCellInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  SKYCELL_TABLE_NAME
+    if (!psFitsMoveExtName(fits, SKYCELL_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", SKYCELL_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
+    if (!psDBInsertRows(dbh, SKYCELL_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool skyCellSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, SKYCELL_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, SKYCELL_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *skyCellMetadataFromObject(const skyCellRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra1", PS_DATA_F64, NULL, object->ra1)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl1", PS_DATA_F64, NULL, object->decl1)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl1");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra2", PS_DATA_F64, NULL, object->ra2)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra2");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl2", PS_DATA_F64, NULL, object->decl2)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl2");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra3", PS_DATA_F64, NULL, object->ra3)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra3");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl3", PS_DATA_F64, NULL, object->decl3)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl3");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "ra4", PS_DATA_F64, NULL, object->ra4)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item ra4");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "decl4", PS_DATA_F64, NULL, object->decl4)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item decl4");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+skyCellRow *skyCellObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
+        return false;
+    }
+    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
+        return false;
+    }
+    psF64 ra1 = psMetadataLookupF64(&status, md, "ra1");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra1");
+        return false;
+    }
+    psF64 decl1 = psMetadataLookupF64(&status, md, "decl1");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl1");
+        return false;
+    }
+    psF64 ra2 = psMetadataLookupF64(&status, md, "ra2");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra2");
+        return false;
+    }
+    psF64 decl2 = psMetadataLookupF64(&status, md, "decl2");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl2");
+        return false;
+    }
+    psF64 ra3 = psMetadataLookupF64(&status, md, "ra3");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra3");
+        return false;
+    }
+    psF64 decl3 = psMetadataLookupF64(&status, md, "decl3");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl3");
+        return false;
+    }
+    psF64 ra4 = psMetadataLookupF64(&status, md, "ra4");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item ra4");
+        return false;
+    }
+    psF64 decl4 = psMetadataLookupF64(&status, md, "decl4");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item decl4");
+        return false;
+    }
+
+    return skyCellRowAlloc(skycell_id, tess_id, ra1, decl1, ra2, decl2, ra3, decl3, ra4, decl4);
+}
+psArray *skyCellSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, SKYCELL_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        skyCellRow *object = skyCellObjectFromMetadata(rowSet->data[i]);
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool skyCellDeleteObject(psDB *dbh, const skyCellRow *object)
+{
+    psMetadata *where = skyCellMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, SKYCELL_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCell");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "skyCellRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long skyCellDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        skyCellRow *object = objects->data[i];
+        psMetadata *where = skyCellMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, SKYCELL_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCell");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool skyCellPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = skyCellMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            SKYCELL_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool skyCellPrintObject(FILE *stream, skyCellRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = skyCellMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
+static void skyCellMapRowFree(skyCellMapRow *object);
+
+skyCellMapRow *skyCellMapRowAlloc(const char *skycell_id, const char *tess_id, const char *exp_tag, const char *class_id)
+{
+    skyCellMapRow   *_object;
+
+    _object = psAlloc(sizeof(skyCellMapRow));
+    psMemSetDeallocator(_object, (psFreeFunc)skyCellMapRowFree);
+
+    _object->skycell_id = psStringCopy(skycell_id);
+    _object->tess_id = psStringCopy(tess_id);
+    _object->exp_tag = psStringCopy(exp_tag);
+    _object->class_id = psStringCopy(class_id);
+
+    return _object;
+}
+
+static void skyCellMapRowFree(skyCellMapRow *object)
+{
+    psFree(object->skycell_id);
+    psFree(object->tess_id);
+    psFree(object->exp_tag);
+    psFree(object->class_id);
+}
+
+bool skyCellMapCreateTable(psDB *dbh)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, "Primary Key", "64")) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBCreateTable(dbh, SKYCELLMAP_TABLE_NAME, md);
+
+    psFree(md);
+
+    return status;
+}
+
+bool skyCellMapDropTable(psDB *dbh)
+{
+    return psDBDropTable(dbh, SKYCELLMAP_TABLE_NAME);
+}
+
+bool skyCellMapInsert(psDB * dbh, const char *skycell_id, const char *tess_id, const char *exp_tag, const char *class_id)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, exp_tag)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, class_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
+        psFree(md);
+        return false;
+    }
+
+    bool status = psDBInsertOneRow(dbh, SKYCELLMAP_TABLE_NAME, md);
+    psFree(md);
+
+    return status;
+}
+
+long long skyCellMapDelete(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    long long count = psDBDeleteRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCellMap");
+        return count;
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool skyCellMapInsertObject(psDB *dbh, skyCellMapRow *object)
+{
+    return skyCellMapInsert(dbh, object->skycell_id, object->tess_id, object->exp_tag, object->class_id);
+}
+
+bool skyCellMapInsertObjects(psDB *dbh, psArray *objects)
+{
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        if (!skyCellMapInsertObject(dbh, objects->data[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool skyCellMapInsertFits(psDB *dbh, const psFits *fits)
+{
+    psArray         *rowSet;
+
+    // move to (the first?) extension named  SKYCELLMAP_TABLE_NAME
+    if (!psFitsMoveExtName(fits, SKYCELLMAP_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, true, "failed to find FITS extension %s", SKYCELLMAP_TABLE_NAME);
+        return false;
+    }
+
+    // check HDU type
+    if (psFitsGetExtType(fits) != PS_FITS_TYPE_BINARY_TABLE)  {
+        psError(PS_ERR_UNKNOWN, true, "FITS HDU type is not PS_FITS_TYPE_BINARY_TABLE");
+        return false;
+    }
+
+    // read fits table
+    rowSet = psFitsReadTable(fits);
+    if (!rowSet) {
+        psError(PS_ERR_UNKNOWN, true, "FITS read error or FITS table is empty");
+        psFree(rowSet);
+        return false;
+    }
+
+    if (!psDBInsertRows(dbh, SKYCELLMAP_TABLE_NAME, rowSet)) {
+        psError(PS_ERR_UNKNOWN, false, "databse insert failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+bool skyCellMapSelectRowsFits(psDB *dbh, psFits *fits, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+
+    rowSet = psDBSelectRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return false;
+    }
+
+    // output to fits
+    if (!psFitsWriteTable(fits, NULL, rowSet, SKYCELLMAP_TABLE_NAME)) {
+        psError(PS_ERR_UNKNOWN, false, "FITS table write failed");
+        psFree(rowSet);
+        return false;
+    }
+
+    psFree(rowSet);
+
+    return true;
+}
+
+psMetadata *skyCellMapMetadataFromObject(const skyCellMapRow *object)
+{
+    psMetadata *md = psMetadataAlloc();
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "skycell_id", PS_DATA_STRING, NULL, object->skycell_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item skycell_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "tess_id", PS_DATA_STRING, NULL, object->tess_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item tess_id");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "exp_tag", PS_DATA_STRING, NULL, object->exp_tag)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item exp_tag");
+        psFree(md);
+        return false;
+    }
+    if (!psMetadataAdd(md, PS_LIST_TAIL, "class_id", PS_DATA_STRING, NULL, object->class_id)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to add item class_id");
+        psFree(md);
+        return false;
+    }
+
+
+    return md;
+}
+
+skyCellMapRow *skyCellMapObjectFromMetadata(psMetadata *md)
+{
+
+bool status = false;
+    char* skycell_id = psMetadataLookupPtr(&status, md, "skycell_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item skycell_id");
+        return false;
+    }
+    char* tess_id = psMetadataLookupPtr(&status, md, "tess_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item tess_id");
+        return false;
+    }
+    char* exp_tag = psMetadataLookupPtr(&status, md, "exp_tag");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item exp_tag");
+        return false;
+    }
+    char* class_id = psMetadataLookupPtr(&status, md, "class_id");
+    if (!status) {
+        psError(PS_ERR_UNKNOWN, true, "failed to lookup value for item class_id");
+        return false;
+    }
+
+    return skyCellMapRowAlloc(skycell_id, tess_id, exp_tag, class_id);
+}
+psArray *skyCellMapSelectRowObjects(psDB *dbh, const psMetadata *where, unsigned long long limit)
+{
+    psArray         *rowSet;
+    psArray         *returnSet;
+    psU64           i;
+
+    rowSet = psDBSelectRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
+    if (!rowSet) {
+        return NULL;
+    }
+
+    // convert psMetadata rows to row objects
+
+    returnSet = psArrayAllocEmpty(rowSet->n);
+
+    for (i = 0; i < rowSet->n; i++) {
+        skyCellMapRow *object = skyCellMapObjectFromMetadata(rowSet->data[i]);
+        psArrayAdd(returnSet, 0, object);
+        psFree(object);
+    }
+
+    psFree(rowSet);
+
+    return returnSet;
+}
+bool skyCellMapDeleteObject(psDB *dbh, const skyCellMapRow *object)
+{
+    psMetadata *where = skyCellMapMetadataFromObject(object);
+    long long count = psDBDeleteRows(dbh, SKYCELLMAP_TABLE_NAME, where, 0);
+    psFree(where);
+    if (count < 0) {
+        psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCellMap");
+        return false;
+    }
+    if (count > 1) {
+        // XXX should this be a psAbort() instead?  It is possible that
+        // having an object match multiple rows was by design.
+        psError(PS_ERR_UNKNOWN, true, "skyCellMapRow object matched more then one row.  Check your database schema");
+        return false;
+    }
+
+    return true;
+}
+long long skyCellMapDeleteRowObjects(psDB *dbh, const psArray *objects, unsigned long long limit)
+{
+    long long       deleted = 0;
+
+    for (long long i = 0; i < objects->n; i++) {
+        skyCellMapRow *object = objects->data[i];
+        psMetadata *where = skyCellMapMetadataFromObject(object);
+        long long count = psDBDeleteRows(dbh, SKYCELLMAP_TABLE_NAME, where, limit);
+        psFree(where);
+        if (count < 0) {
+            psError(PS_ERR_UNKNOWN, true, "failed to delete row from skyCellMap");
+            return count;
+        }
+
+        deleted += count;
+    }
+
+    return deleted;
+}
+bool skyCellMapPrintObjects(FILE *stream, psArray *objects, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(objects, false);
+
+    psMetadata *output = psMetadataAlloc();
+    for (long i = 0; i < psArrayLength(objects); i++) {
+        psMetadata *md = skyCellMapMetadataFromObject(objects->data[i]);
+        if (!psMetadataAddMetadata(
+            output,
+            PS_LIST_TAIL,
+            SKYCELLMAP_TABLE_NAME,
+            PS_META_DUPLICATE_OK,
+            NULL,
+            md
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to add metadata");
+            psFree(md);
+            psFree(output);
+            return false;
+        }
+        psFree(md);
+    }
+
+    if (!ippdbPrintMetadataRaw(stream, output, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(output);
+    }
+    psFree(output);
+
+    return true;
+}
+bool skyCellMapPrintObject(FILE *stream, skyCellMapRow *object, bool mdcf)
+{
+    PS_ASSERT_PTR_NON_NULL(object, false);
+
+    psMetadata *md = skyCellMapMetadataFromObject(object);
+
+    if (!ippdbPrintMetadataRaw(stream, md, mdcf)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print metadata");
+        psFree(md);
+    }
+
+    psFree(md);
+
+    return true;
+}
Index: /trunk/ippdb/src/ippdb.h
===================================================================
--- /trunk/ippdb/src/ippdb.h	(revision 11678)
+++ /trunk/ippdb/src/ippdb.h	(revision 11679)
@@ -20,5 +20,5 @@
 /*
  *
- * This file was generated by glueforge 1.00
+ * This file was generated by glueforge 0.36
  *
  * Do NOT directly edit this file.
@@ -6830,57 +6830,43 @@
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** p4RunRow data structure
- *
- * Structure for representing a single row of p4Run table data.
+/** p4aRunRow data structure
+ *
+ * Structure for representing a single row of p4aRun table data.
  */
 
 typedef struct {
-    psS32           p4_id;
-    char            *survey_mode;
+    psS32           p4a_id;
     char            *state;
     char            *workdir;
-    char            *filter;
-    char            *skycell_id;
-    char            *tess_id;
-    psF64           ra;
-    psF64           decl;
-    char            *input_ss;
-    char            *output_ss;
-} p4RunRow;
-
-/** Creates a new p4RunRow object
- *
- *  @return A new p4RunRow object or NULL on failure.
- */
-
-p4RunRow *p4RunRowAlloc(
-    psS32           p4_id,
-    const char      *survey_mode,
+    bool            magic;
+} p4aRunRow;
+
+/** Creates a new p4aRunRow object
+ *
+ *  @return A new p4aRunRow object or NULL on failure.
+ */
+
+p4aRunRow *p4aRunRowAlloc(
+    psS32           p4a_id,
     const char      *state,
     const char      *workdir,
-    const char      *filter,
-    const char      *skycell_id,
-    const char      *tess_id,
-    psF64           ra,
-    psF64           decl,
-    const char      *input_ss,
-    const char      *output_ss
-);
-
-/** Creates a new p4Run table
- *
- * @return true on success
- */
-
-bool p4RunCreateTable(
+    bool            magic
+);
+
+/** Creates a new p4aRun table
+ *
+ * @return true on success
+ */
+
+bool p4aRunCreateTable(
     psDB            *dbh                ///< Database handle
 );
 
-/** Deletes a p4Run table
- *
- * @return true on success
- */
-
-bool p4RunDropTable(
+/** Deletes a p4aRun table
+ *
+ * @return true on success
+ */
+
+bool p4aRunDropTable(
     psDB            *dbh                ///< Database handle
 );
@@ -6893,17 +6879,10 @@
  */
 
-bool p4RunInsert(
-    psDB            *dbh,               ///< Database handle
-    psS32           p4_id,
-    const char      *survey_mode,
+bool p4aRunInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4a_id,
     const char      *state,
     const char      *workdir,
-    const char      *filter,
-    const char      *skycell_id,
-    const char      *tess_id,
-    psF64           ra,
-    psF64           decl,
-    const char      *input_ss,
-    const char      *output_ss
+    bool            magic
 );
 
@@ -6913,5 +6892,5 @@
  */
 
-long long p4RunDelete(
+long long p4aRunDelete(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
@@ -6919,5 +6898,5 @@
 );
 
-/** Insert a single p4RunRow object into a table
+/** Insert a single p4aRunRow object into a table
  *
  * This function constructs and inserts a single row based on it's parameters.
@@ -6926,10 +6905,10 @@
  */
 
-bool p4RunInsertObject(
-    psDB            *dbh,               ///< Database handle
-    p4RunRow        *object             ///< p4RunRow object
-);
-
-/** Insert an array of p4RunRow object into a table
+bool p4aRunInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4aRunRow       *object             ///< p4aRunRow object
+);
+
+/** Insert an array of p4aRunRow object into a table
  *
  * This function constructs and inserts multiple rows based on it's parameters.
@@ -6938,10 +6917,10 @@
  */
 
-bool p4RunInsertObjects(
-    psDB            *dbh,               ///< Database handle
-    psArray         *objects            ///< array of p4RunRow objects
-);
-
-/** Insert data from a binary FITS table p4RunRow into the database
+bool p4aRunInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4aRunRow objects
+);
+
+/** Insert data from a binary FITS table p4aRunRow into the database
  *
  * This function expects a psFits object with a FITS table as the first
@@ -6953,5 +6932,5 @@
  */
 
-bool p4RunInsertFits(
+bool p4aRunInsertFits(
     psDB            *dbh,               ///< Database handle
     const psFits    *fits               ///< psFits object
@@ -6968,5 +6947,5 @@
  */
 
-bool p4RunSelectRowsFits(
+bool p4aRunSelectRowsFits(
     psDB            *dbh,               ///< Database handle
     psFits          *fits,              ///< psFits object
@@ -6975,22 +6954,22 @@
 );
 
-/** Convert a p4RunRow into an equivalent psMetadata
+/** Convert a p4aRunRow into an equivalent psMetadata
  *
  * @return A psMetadata pointer or NULL on error
  */
 
-psMetadata *p4RunMetadataFromObject(
-    const p4RunRow  *object             ///< fooRow to convert into a psMetadata
+psMetadata *p4aRunMetadataFromObject(
+    const p4aRunRow *object             ///< fooRow to convert into a psMetadata
 );
 
 /** Convert a psMetadata into an equivalent fooRow
  *
- * @return A p4RunRow pointer or NULL on error
- */
-
-p4RunRow *p4RunObjectFromMetadata(
+ * @return A p4aRunRow pointer or NULL on error
+ */
+
+p4aRunRow *p4aRunObjectFromMetadata(
     psMetadata      *md                 ///< psMetadata to convert into a fooRow
 );
-/** Selects up to limit rows from the database and returns as p4RunRow objects in a psArray
+/** Selects up to limit rows from the database and returns as p4aRunRow objects in a psArray
  *
  *  See psDBSelectRows() for documentation on the format of where.
@@ -6999,10 +6978,10 @@
  */
 
-psArray *p4RunSelectRowObjects(
+psArray *p4aRunSelectRowObjects(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
     unsigned long long limit            ///< Maximum number of elements to return
 );
-/** Deletes a row from the database coresponding to an p4Run
+/** Deletes a row from the database coresponding to an p4aRun
  *
  *  Note that a 'where' search psMetadata is constructed from each object and
@@ -7012,7 +6991,7 @@
  */
 
-bool p4RunDeleteObject(
-    psDB            *dbh,               ///< Database handle
-    const p4RunRow *object    ///< Object to delete
+bool p4aRunDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4aRunRow *object    ///< Object to delete
 );
 /** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
@@ -7024,10 +7003,10 @@
  */
 
-long long p4RunDeleteRowObjects(
+long long p4aRunDeleteRowObjects(
     psDB            *dbh,               ///< Database handle
     const psArray   *objects,           ///< Array of objects to delete
     unsigned long long limit            ///< Maximum number of elements to delete 
 );
-/** Formats and prints an array of p4RunRow objects
+/** Formats and prints an array of p4aRunRow objects
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7037,10 +7016,10 @@
  */
 
-bool p4RunPrintObjects(
+bool p4aRunPrintObjects(
     FILE            *stream,            ///< a stream
-    psArray         *objects,           ///< An array of p4RunRow objects
+    psArray         *objects,           ///< An array of p4aRunRow objects
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** Formats and prints an p4RunRow object
+/** Formats and prints an p4aRunRow object
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7050,48 +7029,46 @@
  */
 
-bool p4RunPrintObject(
+bool p4aRunPrintObject(
     FILE            *stream,            ///< a stream
-    p4RunRow *object,    ///< an p4RunRow object
+    p4aRunRow *object,    ///< an p4aRunRow object
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** p4InputImfileRow data structure
- *
- * Structure for representing a single row of p4InputImfile table data.
+/** p4aInputExpRow data structure
+ *
+ * Structure for representing a single row of p4aInputExp table data.
  */
 
 typedef struct {
-    psS32           p4_id;
+    psS32           p4a_id;
     char            *exp_tag;
     psS32           p3_version;
-    char            *class_id;
-} p4InputImfileRow;
-
-/** Creates a new p4InputImfileRow object
- *
- *  @return A new p4InputImfileRow object or NULL on failure.
- */
-
-p4InputImfileRow *p4InputImfileRowAlloc(
-    psS32           p4_id,
+} p4aInputExpRow;
+
+/** Creates a new p4aInputExpRow object
+ *
+ *  @return A new p4aInputExpRow object or NULL on failure.
+ */
+
+p4aInputExpRow *p4aInputExpRowAlloc(
+    psS32           p4a_id,
     const char      *exp_tag,
-    psS32           p3_version,
-    const char      *class_id
-);
-
-/** Creates a new p4InputImfile table
- *
- * @return true on success
- */
-
-bool p4InputImfileCreateTable(
+    psS32           p3_version
+);
+
+/** Creates a new p4aInputExp table
+ *
+ * @return true on success
+ */
+
+bool p4aInputExpCreateTable(
     psDB            *dbh                ///< Database handle
 );
 
-/** Deletes a p4InputImfile table
- *
- * @return true on success
- */
-
-bool p4InputImfileDropTable(
+/** Deletes a p4aInputExp table
+ *
+ * @return true on success
+ */
+
+bool p4aInputExpDropTable(
     psDB            *dbh                ///< Database handle
 );
@@ -7104,10 +7081,9 @@
  */
 
-bool p4InputImfileInsert(
-    psDB            *dbh,               ///< Database handle
-    psS32           p4_id,
+bool p4aInputExpInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4a_id,
     const char      *exp_tag,
-    psS32           p3_version,
-    const char      *class_id
+    psS32           p3_version
 );
 
@@ -7117,5 +7093,5 @@
  */
 
-long long p4InputImfileDelete(
+long long p4aInputExpDelete(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
@@ -7123,5 +7099,5 @@
 );
 
-/** Insert a single p4InputImfileRow object into a table
+/** Insert a single p4aInputExpRow object into a table
  *
  * This function constructs and inserts a single row based on it's parameters.
@@ -7130,10 +7106,10 @@
  */
 
-bool p4InputImfileInsertObject(
-    psDB            *dbh,               ///< Database handle
-    p4InputImfileRow *object             ///< p4InputImfileRow object
-);
-
-/** Insert an array of p4InputImfileRow object into a table
+bool p4aInputExpInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4aInputExpRow  *object             ///< p4aInputExpRow object
+);
+
+/** Insert an array of p4aInputExpRow object into a table
  *
  * This function constructs and inserts multiple rows based on it's parameters.
@@ -7142,10 +7118,10 @@
  */
 
-bool p4InputImfileInsertObjects(
-    psDB            *dbh,               ///< Database handle
-    psArray         *objects            ///< array of p4InputImfileRow objects
-);
-
-/** Insert data from a binary FITS table p4InputImfileRow into the database
+bool p4aInputExpInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4aInputExpRow objects
+);
+
+/** Insert data from a binary FITS table p4aInputExpRow into the database
  *
  * This function expects a psFits object with a FITS table as the first
@@ -7157,5 +7133,5 @@
  */
 
-bool p4InputImfileInsertFits(
+bool p4aInputExpInsertFits(
     psDB            *dbh,               ///< Database handle
     const psFits    *fits               ///< psFits object
@@ -7172,5 +7148,5 @@
  */
 
-bool p4InputImfileSelectRowsFits(
+bool p4aInputExpSelectRowsFits(
     psDB            *dbh,               ///< Database handle
     psFits          *fits,              ///< psFits object
@@ -7179,22 +7155,22 @@
 );
 
-/** Convert a p4InputImfileRow into an equivalent psMetadata
+/** Convert a p4aInputExpRow into an equivalent psMetadata
  *
  * @return A psMetadata pointer or NULL on error
  */
 
-psMetadata *p4InputImfileMetadataFromObject(
-    const p4InputImfileRow *object             ///< fooRow to convert into a psMetadata
+psMetadata *p4aInputExpMetadataFromObject(
+    const p4aInputExpRow *object             ///< fooRow to convert into a psMetadata
 );
 
 /** Convert a psMetadata into an equivalent fooRow
  *
- * @return A p4InputImfileRow pointer or NULL on error
- */
-
-p4InputImfileRow *p4InputImfileObjectFromMetadata(
+ * @return A p4aInputExpRow pointer or NULL on error
+ */
+
+p4aInputExpRow *p4aInputExpObjectFromMetadata(
     psMetadata      *md                 ///< psMetadata to convert into a fooRow
 );
-/** Selects up to limit rows from the database and returns as p4InputImfileRow objects in a psArray
+/** Selects up to limit rows from the database and returns as p4aInputExpRow objects in a psArray
  *
  *  See psDBSelectRows() for documentation on the format of where.
@@ -7203,10 +7179,10 @@
  */
 
-psArray *p4InputImfileSelectRowObjects(
+psArray *p4aInputExpSelectRowObjects(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
     unsigned long long limit            ///< Maximum number of elements to return
 );
-/** Deletes a row from the database coresponding to an p4InputImfile
+/** Deletes a row from the database coresponding to an p4aInputExp
  *
  *  Note that a 'where' search psMetadata is constructed from each object and
@@ -7216,7 +7192,7 @@
  */
 
-bool p4InputImfileDeleteObject(
-    psDB            *dbh,               ///< Database handle
-    const p4InputImfileRow *object    ///< Object to delete
+bool p4aInputExpDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4aInputExpRow *object    ///< Object to delete
 );
 /** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
@@ -7228,10 +7204,10 @@
  */
 
-long long p4InputImfileDeleteRowObjects(
+long long p4aInputExpDeleteRowObjects(
     psDB            *dbh,               ///< Database handle
     const psArray   *objects,           ///< Array of objects to delete
     unsigned long long limit            ///< Maximum number of elements to delete 
 );
-/** Formats and prints an array of p4InputImfileRow objects
+/** Formats and prints an array of p4aInputExpRow objects
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7241,10 +7217,10 @@
  */
 
-bool p4InputImfilePrintObjects(
+bool p4aInputExpPrintObjects(
     FILE            *stream,            ///< a stream
-    psArray         *objects,           ///< An array of p4InputImfileRow objects
+    psArray         *objects,           ///< An array of p4aInputExpRow objects
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** Formats and prints an p4InputImfileRow object
+/** Formats and prints an p4aInputExpRow object
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7254,54 +7230,56 @@
  */
 
-bool p4InputImfilePrintObject(
+bool p4aInputExpPrintObject(
     FILE            *stream,            ///< a stream
-    p4InputImfileRow *object,    ///< an p4InputImfileRow object
+    p4aInputExpRow *object,    ///< an p4aInputExpRow object
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** p4WarpedImfileRow data structure
- *
- * Structure for representing a single row of p4WarpedImfile table data.
+/** p4aScfileRow data structure
+ *
+ * Structure for representing a single row of p4aScfile table data.
  */
 
 typedef struct {
-    psS32           p4_id;
+    psS32           p4a_id;
+    char            *skycell_id;
+    char            *tess_id;
     char            *exp_tag;
     psS32           p3_version;
-    char            *class_id;
     char            *uri;
-    char            *b1_uri;
-    char            *b2_uri;
-} p4WarpedImfileRow;
-
-/** Creates a new p4WarpedImfileRow object
- *
- *  @return A new p4WarpedImfileRow object or NULL on failure.
- */
-
-p4WarpedImfileRow *p4WarpedImfileRowAlloc(
-    psS32           p4_id,
+    psF64           bg;
+    psF64           bg_mean_stdev;
+} p4aScfileRow;
+
+/** Creates a new p4aScfileRow object
+ *
+ *  @return A new p4aScfileRow object or NULL on failure.
+ */
+
+p4aScfileRow *p4aScfileRowAlloc(
+    psS32           p4a_id,
+    const char      *skycell_id,
+    const char      *tess_id,
     const char      *exp_tag,
     psS32           p3_version,
-    const char      *class_id,
     const char      *uri,
-    const char      *b1_uri,
-    const char      *b2_uri
-);
-
-/** Creates a new p4WarpedImfile table
- *
- * @return true on success
- */
-
-bool p4WarpedImfileCreateTable(
+    psF64           bg,
+    psF64           bg_mean_stdev
+);
+
+/** Creates a new p4aScfile table
+ *
+ * @return true on success
+ */
+
+bool p4aScfileCreateTable(
     psDB            *dbh                ///< Database handle
 );
 
-/** Deletes a p4WarpedImfile table
- *
- * @return true on success
- */
-
-bool p4WarpedImfileDropTable(
+/** Deletes a p4aScfile table
+ *
+ * @return true on success
+ */
+
+bool p4aScfileDropTable(
     psDB            *dbh                ///< Database handle
 );
@@ -7314,13 +7292,14 @@
  */
 
-bool p4WarpedImfileInsert(
-    psDB            *dbh,               ///< Database handle
-    psS32           p4_id,
+bool p4aScfileInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4a_id,
+    const char      *skycell_id,
+    const char      *tess_id,
     const char      *exp_tag,
     psS32           p3_version,
-    const char      *class_id,
     const char      *uri,
-    const char      *b1_uri,
-    const char      *b2_uri
+    psF64           bg,
+    psF64           bg_mean_stdev
 );
 
@@ -7330,5 +7309,5 @@
  */
 
-long long p4WarpedImfileDelete(
+long long p4aScfileDelete(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
@@ -7336,5 +7315,5 @@
 );
 
-/** Insert a single p4WarpedImfileRow object into a table
+/** Insert a single p4aScfileRow object into a table
  *
  * This function constructs and inserts a single row based on it's parameters.
@@ -7343,10 +7322,10 @@
  */
 
-bool p4WarpedImfileInsertObject(
-    psDB            *dbh,               ///< Database handle
-    p4WarpedImfileRow *object             ///< p4WarpedImfileRow object
-);
-
-/** Insert an array of p4WarpedImfileRow object into a table
+bool p4aScfileInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4aScfileRow    *object             ///< p4aScfileRow object
+);
+
+/** Insert an array of p4aScfileRow object into a table
  *
  * This function constructs and inserts multiple rows based on it's parameters.
@@ -7355,10 +7334,10 @@
  */
 
-bool p4WarpedImfileInsertObjects(
-    psDB            *dbh,               ///< Database handle
-    psArray         *objects            ///< array of p4WarpedImfileRow objects
-);
-
-/** Insert data from a binary FITS table p4WarpedImfileRow into the database
+bool p4aScfileInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4aScfileRow objects
+);
+
+/** Insert data from a binary FITS table p4aScfileRow into the database
  *
  * This function expects a psFits object with a FITS table as the first
@@ -7370,5 +7349,5 @@
  */
 
-bool p4WarpedImfileInsertFits(
+bool p4aScfileInsertFits(
     psDB            *dbh,               ///< Database handle
     const psFits    *fits               ///< psFits object
@@ -7385,5 +7364,5 @@
  */
 
-bool p4WarpedImfileSelectRowsFits(
+bool p4aScfileSelectRowsFits(
     psDB            *dbh,               ///< Database handle
     psFits          *fits,              ///< psFits object
@@ -7392,22 +7371,22 @@
 );
 
-/** Convert a p4WarpedImfileRow into an equivalent psMetadata
+/** Convert a p4aScfileRow into an equivalent psMetadata
  *
  * @return A psMetadata pointer or NULL on error
  */
 
-psMetadata *p4WarpedImfileMetadataFromObject(
-    const p4WarpedImfileRow *object             ///< fooRow to convert into a psMetadata
+psMetadata *p4aScfileMetadataFromObject(
+    const p4aScfileRow *object             ///< fooRow to convert into a psMetadata
 );
 
 /** Convert a psMetadata into an equivalent fooRow
  *
- * @return A p4WarpedImfileRow pointer or NULL on error
- */
-
-p4WarpedImfileRow *p4WarpedImfileObjectFromMetadata(
+ * @return A p4aScfileRow pointer or NULL on error
+ */
+
+p4aScfileRow *p4aScfileObjectFromMetadata(
     psMetadata      *md                 ///< psMetadata to convert into a fooRow
 );
-/** Selects up to limit rows from the database and returns as p4WarpedImfileRow objects in a psArray
+/** Selects up to limit rows from the database and returns as p4aScfileRow objects in a psArray
  *
  *  See psDBSelectRows() for documentation on the format of where.
@@ -7416,10 +7395,10 @@
  */
 
-psArray *p4WarpedImfileSelectRowObjects(
+psArray *p4aScfileSelectRowObjects(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
     unsigned long long limit            ///< Maximum number of elements to return
 );
-/** Deletes a row from the database coresponding to an p4WarpedImfile
+/** Deletes a row from the database coresponding to an p4aScfile
  *
  *  Note that a 'where' search psMetadata is constructed from each object and
@@ -7429,7 +7408,7 @@
  */
 
-bool p4WarpedImfileDeleteObject(
-    psDB            *dbh,               ///< Database handle
-    const p4WarpedImfileRow *object    ///< Object to delete
+bool p4aScfileDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4aScfileRow *object    ///< Object to delete
 );
 /** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
@@ -7441,10 +7420,10 @@
  */
 
-long long p4WarpedImfileDeleteRowObjects(
+long long p4aScfileDeleteRowObjects(
     psDB            *dbh,               ///< Database handle
     const psArray   *objects,           ///< Array of objects to delete
     unsigned long long limit            ///< Maximum number of elements to delete 
 );
-/** Formats and prints an array of p4WarpedImfileRow objects
+/** Formats and prints an array of p4aScfileRow objects
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7454,10 +7433,10 @@
  */
 
-bool p4WarpedImfilePrintObjects(
+bool p4aScfilePrintObjects(
     FILE            *stream,            ///< a stream
-    psArray         *objects,           ///< An array of p4WarpedImfileRow objects
+    psArray         *objects,           ///< An array of p4aScfileRow objects
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** Formats and prints an p4WarpedImfileRow object
+/** Formats and prints an p4aScfileRow object
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7467,50 +7446,48 @@
  */
 
-bool p4WarpedImfilePrintObject(
+bool p4aScfilePrintObject(
     FILE            *stream,            ///< a stream
-    p4WarpedImfileRow *object,    ///< an p4WarpedImfileRow object
+    p4aScfileRow *object,    ///< an p4aScfileRow object
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** p4StackedImfileRow data structure
- *
- * Structure for representing a single row of p4StackedImfile table data.
+/** p4bRunRow data structure
+ *
+ * Structure for representing a single row of p4bRun table data.
  */
 
 typedef struct {
-    psS32           p4_id;
-    char            *class_id;
-    char            *uri;
-    char            *b1_uri;
-    char            *b2_uri;
-} p4StackedImfileRow;
-
-/** Creates a new p4StackedImfileRow object
- *
- *  @return A new p4StackedImfileRow object or NULL on failure.
- */
-
-p4StackedImfileRow *p4StackedImfileRowAlloc(
-    psS32           p4_id,
-    const char      *class_id,
-    const char      *uri,
-    const char      *b1_uri,
-    const char      *b2_uri
-);
-
-/** Creates a new p4StackedImfile table
- *
- * @return true on success
- */
-
-bool p4StackedImfileCreateTable(
+    psS32           p4b_id;
+    char            *state;
+    char            *workdir;
+    bool            magic;
+} p4bRunRow;
+
+/** Creates a new p4bRunRow object
+ *
+ *  @return A new p4bRunRow object or NULL on failure.
+ */
+
+p4bRunRow *p4bRunRowAlloc(
+    psS32           p4b_id,
+    const char      *state,
+    const char      *workdir,
+    bool            magic
+);
+
+/** Creates a new p4bRun table
+ *
+ * @return true on success
+ */
+
+bool p4bRunCreateTable(
     psDB            *dbh                ///< Database handle
 );
 
-/** Deletes a p4StackedImfile table
- *
- * @return true on success
- */
-
-bool p4StackedImfileDropTable(
+/** Deletes a p4bRun table
+ *
+ * @return true on success
+ */
+
+bool p4bRunDropTable(
     psDB            *dbh                ///< Database handle
 );
@@ -7523,11 +7500,10 @@
  */
 
-bool p4StackedImfileInsert(
-    psDB            *dbh,               ///< Database handle
-    psS32           p4_id,
-    const char      *class_id,
-    const char      *uri,
-    const char      *b1_uri,
-    const char      *b2_uri
+bool p4bRunInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4b_id,
+    const char      *state,
+    const char      *workdir,
+    bool            magic
 );
 
@@ -7537,5 +7513,5 @@
  */
 
-long long p4StackedImfileDelete(
+long long p4bRunDelete(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
@@ -7543,5 +7519,5 @@
 );
 
-/** Insert a single p4StackedImfileRow object into a table
+/** Insert a single p4bRunRow object into a table
  *
  * This function constructs and inserts a single row based on it's parameters.
@@ -7550,10 +7526,10 @@
  */
 
-bool p4StackedImfileInsertObject(
-    psDB            *dbh,               ///< Database handle
-    p4StackedImfileRow *object             ///< p4StackedImfileRow object
-);
-
-/** Insert an array of p4StackedImfileRow object into a table
+bool p4bRunInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4bRunRow       *object             ///< p4bRunRow object
+);
+
+/** Insert an array of p4bRunRow object into a table
  *
  * This function constructs and inserts multiple rows based on it's parameters.
@@ -7562,10 +7538,10 @@
  */
 
-bool p4StackedImfileInsertObjects(
-    psDB            *dbh,               ///< Database handle
-    psArray         *objects            ///< array of p4StackedImfileRow objects
-);
-
-/** Insert data from a binary FITS table p4StackedImfileRow into the database
+bool p4bRunInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4bRunRow objects
+);
+
+/** Insert data from a binary FITS table p4bRunRow into the database
  *
  * This function expects a psFits object with a FITS table as the first
@@ -7577,5 +7553,5 @@
  */
 
-bool p4StackedImfileInsertFits(
+bool p4bRunInsertFits(
     psDB            *dbh,               ///< Database handle
     const psFits    *fits               ///< psFits object
@@ -7592,5 +7568,5 @@
  */
 
-bool p4StackedImfileSelectRowsFits(
+bool p4bRunSelectRowsFits(
     psDB            *dbh,               ///< Database handle
     psFits          *fits,              ///< psFits object
@@ -7599,22 +7575,22 @@
 );
 
-/** Convert a p4StackedImfileRow into an equivalent psMetadata
+/** Convert a p4bRunRow into an equivalent psMetadata
  *
  * @return A psMetadata pointer or NULL on error
  */
 
-psMetadata *p4StackedImfileMetadataFromObject(
-    const p4StackedImfileRow *object             ///< fooRow to convert into a psMetadata
+psMetadata *p4bRunMetadataFromObject(
+    const p4bRunRow *object             ///< fooRow to convert into a psMetadata
 );
 
 /** Convert a psMetadata into an equivalent fooRow
  *
- * @return A p4StackedImfileRow pointer or NULL on error
- */
-
-p4StackedImfileRow *p4StackedImfileObjectFromMetadata(
+ * @return A p4bRunRow pointer or NULL on error
+ */
+
+p4bRunRow *p4bRunObjectFromMetadata(
     psMetadata      *md                 ///< psMetadata to convert into a fooRow
 );
-/** Selects up to limit rows from the database and returns as p4StackedImfileRow objects in a psArray
+/** Selects up to limit rows from the database and returns as p4bRunRow objects in a psArray
  *
  *  See psDBSelectRows() for documentation on the format of where.
@@ -7623,10 +7599,10 @@
  */
 
-psArray *p4StackedImfileSelectRowObjects(
+psArray *p4bRunSelectRowObjects(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
     unsigned long long limit            ///< Maximum number of elements to return
 );
-/** Deletes a row from the database coresponding to an p4StackedImfile
+/** Deletes a row from the database coresponding to an p4bRun
  *
  *  Note that a 'where' search psMetadata is constructed from each object and
@@ -7636,7 +7612,7 @@
  */
 
-bool p4StackedImfileDeleteObject(
-    psDB            *dbh,               ///< Database handle
-    const p4StackedImfileRow *object    ///< Object to delete
+bool p4bRunDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4bRunRow *object    ///< Object to delete
 );
 /** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
@@ -7648,10 +7624,10 @@
  */
 
-long long p4StackedImfileDeleteRowObjects(
+long long p4bRunDeleteRowObjects(
     psDB            *dbh,               ///< Database handle
     const psArray   *objects,           ///< Array of objects to delete
     unsigned long long limit            ///< Maximum number of elements to delete 
 );
-/** Formats and prints an array of p4StackedImfileRow objects
+/** Formats and prints an array of p4bRunRow objects
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7661,10 +7637,10 @@
  */
 
-bool p4StackedImfilePrintObjects(
+bool p4bRunPrintObjects(
     FILE            *stream,            ///< a stream
-    psArray         *objects,           ///< An array of p4StackedImfileRow objects
+    psArray         *objects,           ///< An array of p4bRunRow objects
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** Formats and prints an p4StackedImfileRow object
+/** Formats and prints an p4bRunRow object
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7674,54 +7650,52 @@
  */
 
-bool p4StackedImfilePrintObject(
+bool p4bRunPrintObject(
     FILE            *stream,            ///< a stream
-    p4StackedImfileRow *object,    ///< an p4StackedImfileRow object
+    p4bRunRow *object,    ///< an p4bRunRow object
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** p4DiffImfileRow data structure
- *
- * Structure for representing a single row of p4DiffImfile table data.
+/** p4bInputScfileRow data structure
+ *
+ * Structure for representing a single row of p4bInputScfile table data.
  */
 
 typedef struct {
-    psS32           p4_id;
+    psS32           p4b_id;
+    char            *skycell_id;
+    char            *tess_id;
     char            *exp_tag;
     psS32           p3_version;
-    char            *class_id;
-    char            *uri;
-    char            *b1_uri;
-    char            *b2_uri;
-} p4DiffImfileRow;
-
-/** Creates a new p4DiffImfileRow object
- *
- *  @return A new p4DiffImfileRow object or NULL on failure.
- */
-
-p4DiffImfileRow *p4DiffImfileRowAlloc(
-    psS32           p4_id,
+    char            *kind;
+} p4bInputScfileRow;
+
+/** Creates a new p4bInputScfileRow object
+ *
+ *  @return A new p4bInputScfileRow object or NULL on failure.
+ */
+
+p4bInputScfileRow *p4bInputScfileRowAlloc(
+    psS32           p4b_id,
+    const char      *skycell_id,
+    const char      *tess_id,
     const char      *exp_tag,
     psS32           p3_version,
-    const char      *class_id,
-    const char      *uri,
-    const char      *b1_uri,
-    const char      *b2_uri
-);
-
-/** Creates a new p4DiffImfile table
- *
- * @return true on success
- */
-
-bool p4DiffImfileCreateTable(
+    const char      *kind
+);
+
+/** Creates a new p4bInputScfile table
+ *
+ * @return true on success
+ */
+
+bool p4bInputScfileCreateTable(
     psDB            *dbh                ///< Database handle
 );
 
-/** Deletes a p4DiffImfile table
- *
- * @return true on success
- */
-
-bool p4DiffImfileDropTable(
+/** Deletes a p4bInputScfile table
+ *
+ * @return true on success
+ */
+
+bool p4bInputScfileDropTable(
     psDB            *dbh                ///< Database handle
 );
@@ -7734,13 +7708,12 @@
  */
 
-bool p4DiffImfileInsert(
-    psDB            *dbh,               ///< Database handle
-    psS32           p4_id,
+bool p4bInputScfileInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4b_id,
+    const char      *skycell_id,
+    const char      *tess_id,
     const char      *exp_tag,
     psS32           p3_version,
-    const char      *class_id,
-    const char      *uri,
-    const char      *b1_uri,
-    const char      *b2_uri
+    const char      *kind
 );
 
@@ -7750,5 +7723,5 @@
  */
 
-long long p4DiffImfileDelete(
+long long p4bInputScfileDelete(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
@@ -7756,5 +7729,5 @@
 );
 
-/** Insert a single p4DiffImfileRow object into a table
+/** Insert a single p4bInputScfileRow object into a table
  *
  * This function constructs and inserts a single row based on it's parameters.
@@ -7763,10 +7736,10 @@
  */
 
-bool p4DiffImfileInsertObject(
-    psDB            *dbh,               ///< Database handle
-    p4DiffImfileRow *object             ///< p4DiffImfileRow object
-);
-
-/** Insert an array of p4DiffImfileRow object into a table
+bool p4bInputScfileInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4bInputScfileRow *object             ///< p4bInputScfileRow object
+);
+
+/** Insert an array of p4bInputScfileRow object into a table
  *
  * This function constructs and inserts multiple rows based on it's parameters.
@@ -7775,10 +7748,10 @@
  */
 
-bool p4DiffImfileInsertObjects(
-    psDB            *dbh,               ///< Database handle
-    psArray         *objects            ///< array of p4DiffImfileRow objects
-);
-
-/** Insert data from a binary FITS table p4DiffImfileRow into the database
+bool p4bInputScfileInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4bInputScfileRow objects
+);
+
+/** Insert data from a binary FITS table p4bInputScfileRow into the database
  *
  * This function expects a psFits object with a FITS table as the first
@@ -7790,5 +7763,5 @@
  */
 
-bool p4DiffImfileInsertFits(
+bool p4bInputScfileInsertFits(
     psDB            *dbh,               ///< Database handle
     const psFits    *fits               ///< psFits object
@@ -7805,5 +7778,5 @@
  */
 
-bool p4DiffImfileSelectRowsFits(
+bool p4bInputScfileSelectRowsFits(
     psDB            *dbh,               ///< Database handle
     psFits          *fits,              ///< psFits object
@@ -7812,22 +7785,22 @@
 );
 
-/** Convert a p4DiffImfileRow into an equivalent psMetadata
+/** Convert a p4bInputScfileRow into an equivalent psMetadata
  *
  * @return A psMetadata pointer or NULL on error
  */
 
-psMetadata *p4DiffImfileMetadataFromObject(
-    const p4DiffImfileRow *object             ///< fooRow to convert into a psMetadata
+psMetadata *p4bInputScfileMetadataFromObject(
+    const p4bInputScfileRow *object             ///< fooRow to convert into a psMetadata
 );
 
 /** Convert a psMetadata into an equivalent fooRow
  *
- * @return A p4DiffImfileRow pointer or NULL on error
- */
-
-p4DiffImfileRow *p4DiffImfileObjectFromMetadata(
+ * @return A p4bInputScfileRow pointer or NULL on error
+ */
+
+p4bInputScfileRow *p4bInputScfileObjectFromMetadata(
     psMetadata      *md                 ///< psMetadata to convert into a fooRow
 );
-/** Selects up to limit rows from the database and returns as p4DiffImfileRow objects in a psArray
+/** Selects up to limit rows from the database and returns as p4bInputScfileRow objects in a psArray
  *
  *  See psDBSelectRows() for documentation on the format of where.
@@ -7836,10 +7809,10 @@
  */
 
-psArray *p4DiffImfileSelectRowObjects(
+psArray *p4bInputScfileSelectRowObjects(
     psDB            *dbh,               ///< Database handle
     const psMetadata *where,            ///< Row match criteria
     unsigned long long limit            ///< Maximum number of elements to return
 );
-/** Deletes a row from the database coresponding to an p4DiffImfile
+/** Deletes a row from the database coresponding to an p4bInputScfile
  *
  *  Note that a 'where' search psMetadata is constructed from each object and
@@ -7849,7 +7822,7 @@
  */
 
-bool p4DiffImfileDeleteObject(
-    psDB            *dbh,               ///< Database handle
-    const p4DiffImfileRow *object    ///< Object to delete
+bool p4bInputScfileDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4bInputScfileRow *object    ///< Object to delete
 );
 /** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
@@ -7861,10 +7834,10 @@
  */
 
-long long p4DiffImfileDeleteRowObjects(
+long long p4bInputScfileDeleteRowObjects(
     psDB            *dbh,               ///< Database handle
     const psArray   *objects,           ///< Array of objects to delete
     unsigned long long limit            ///< Maximum number of elements to delete 
 );
-/** Formats and prints an array of p4DiffImfileRow objects
+/** Formats and prints an array of p4bInputScfileRow objects
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7874,10 +7847,10 @@
  */
 
-bool p4DiffImfilePrintObjects(
+bool p4bInputScfilePrintObjects(
     FILE            *stream,            ///< a stream
-    psArray         *objects,           ///< An array of p4DiffImfileRow objects
+    psArray         *objects,           ///< An array of p4bInputScfileRow objects
     bool            mdcf                ///< format as mdconfig or simple
 );
-/** Formats and prints an p4DiffImfileRow object
+/** Formats and prints an p4bInputScfileRow object
  *
  * When mdcf is set the formated output is in psMetadataConfig
@@ -7887,9 +7860,630 @@
  */
 
-bool p4DiffImfilePrintObject(
+bool p4bInputScfilePrintObject(
     FILE            *stream,            ///< a stream
-    p4DiffImfileRow *object,    ///< an p4DiffImfileRow object
+    p4bInputScfileRow *object,    ///< an p4bInputScfileRow object
     bool            mdcf                ///< format as mdconfig or simple
 );
+/** p4bDiffScfileRow data structure
+ *
+ * Structure for representing a single row of p4bDiffScfile table data.
+ */
+
+typedef struct {
+    psS32           p4b_id;
+    char            *skycell_id;
+    char            *tess_id;
+    char            *exp_tag;
+    psS32           p3_version;
+    char            *uri;
+    psF64           bg;
+    psF64           bg_mean_stdev;
+} p4bDiffScfileRow;
+
+/** Creates a new p4bDiffScfileRow object
+ *
+ *  @return A new p4bDiffScfileRow object or NULL on failure.
+ */
+
+p4bDiffScfileRow *p4bDiffScfileRowAlloc(
+    psS32           p4b_id,
+    const char      *skycell_id,
+    const char      *tess_id,
+    const char      *exp_tag,
+    psS32           p3_version,
+    const char      *uri,
+    psF64           bg,
+    psF64           bg_mean_stdev
+);
+
+/** Creates a new p4bDiffScfile table
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfileCreateTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Deletes a p4bDiffScfile table
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfileDropTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Insert a single row into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfileInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4b_id,
+    const char      *skycell_id,
+    const char      *tess_id,
+    const char      *exp_tag,
+    psS32           p3_version,
+    const char      *uri,
+    psF64           bg,
+    psF64           bg_mean_stdev
+);
+
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long p4bDiffScfileDelete(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+
+/** Insert a single p4bDiffScfileRow object into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfileInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4bDiffScfileRow *object             ///< p4bDiffScfileRow object
+);
+
+/** Insert an array of p4bDiffScfileRow object into a table
+ *
+ * This function constructs and inserts multiple rows based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfileInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4bDiffScfileRow objects
+);
+
+/** Insert data from a binary FITS table p4bDiffScfileRow into the database
+ *
+ * This function expects a psFits object with a FITS table as the first
+ * extension.  The table must have at least one row of data in it, that is of
+ * the appropriate format (number of columns and their type).  All other
+ * extensions are ignored.
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfileInsertFits(
+    psDB            *dbh,               ///< Database handle
+    const psFits    *fits               ///< psFits object
+);
+
+/** Selects up to limit from the database and returns them in a binary FITS table
+ *
+ * This function assumes an empty psFits object and will create a FITS table
+ * as the first extension.
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfileSelectRowsFits(
+    psDB            *dbh,               ///< Database handle
+    psFits          *fits,              ///< psFits object
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+
+/** Convert a p4bDiffScfileRow into an equivalent psMetadata
+ *
+ * @return A psMetadata pointer or NULL on error
+ */
+
+psMetadata *p4bDiffScfileMetadataFromObject(
+    const p4bDiffScfileRow *object             ///< fooRow to convert into a psMetadata
+);
+
+/** Convert a psMetadata into an equivalent fooRow
+ *
+ * @return A p4bDiffScfileRow pointer or NULL on error
+ */
+
+p4bDiffScfileRow *p4bDiffScfileObjectFromMetadata(
+    psMetadata      *md                 ///< psMetadata to convert into a fooRow
+);
+/** Selects up to limit rows from the database and returns as p4bDiffScfileRow objects in a psArray
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return A psArray pointer or NULL on error
+ */
+
+psArray *p4bDiffScfileSelectRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+/** Deletes a row from the database coresponding to an p4bDiffScfile
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+bool p4bDiffScfileDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4bDiffScfileRow *object    ///< Object to delete
+);
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long p4bDiffScfileDeleteRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psArray   *objects,           ///< Array of objects to delete
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+/** Formats and prints an array of p4bDiffScfileRow objects
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfilePrintObjects(
+    FILE            *stream,            ///< a stream
+    psArray         *objects,           ///< An array of p4bDiffScfileRow objects
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** Formats and prints an p4bDiffScfileRow object
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool p4bDiffScfilePrintObject(
+    FILE            *stream,            ///< a stream
+    p4bDiffScfileRow *object,    ///< an p4bDiffScfileRow object
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** p4cRunRow data structure
+ *
+ * Structure for representing a single row of p4cRun table data.
+ */
+
+typedef struct {
+    psS32           p4c_id;
+    char            *state;
+    char            *workdir;
+    bool            magic;
+} p4cRunRow;
+
+/** Creates a new p4cRunRow object
+ *
+ *  @return A new p4cRunRow object or NULL on failure.
+ */
+
+p4cRunRow *p4cRunRowAlloc(
+    psS32           p4c_id,
+    const char      *state,
+    const char      *workdir,
+    bool            magic
+);
+
+/** Creates a new p4cRun table
+ *
+ * @return true on success
+ */
+
+bool p4cRunCreateTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Deletes a p4cRun table
+ *
+ * @return true on success
+ */
+
+bool p4cRunDropTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Insert a single row into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4cRunInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4c_id,
+    const char      *state,
+    const char      *workdir,
+    bool            magic
+);
+
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long p4cRunDelete(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+
+/** Insert a single p4cRunRow object into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4cRunInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4cRunRow       *object             ///< p4cRunRow object
+);
+
+/** Insert an array of p4cRunRow object into a table
+ *
+ * This function constructs and inserts multiple rows based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4cRunInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4cRunRow objects
+);
+
+/** Insert data from a binary FITS table p4cRunRow into the database
+ *
+ * This function expects a psFits object with a FITS table as the first
+ * extension.  The table must have at least one row of data in it, that is of
+ * the appropriate format (number of columns and their type).  All other
+ * extensions are ignored.
+ *
+ * @return true on success
+ */
+
+bool p4cRunInsertFits(
+    psDB            *dbh,               ///< Database handle
+    const psFits    *fits               ///< psFits object
+);
+
+/** Selects up to limit from the database and returns them in a binary FITS table
+ *
+ * This function assumes an empty psFits object and will create a FITS table
+ * as the first extension.
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return true on success
+ */
+
+bool p4cRunSelectRowsFits(
+    psDB            *dbh,               ///< Database handle
+    psFits          *fits,              ///< psFits object
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+
+/** Convert a p4cRunRow into an equivalent psMetadata
+ *
+ * @return A psMetadata pointer or NULL on error
+ */
+
+psMetadata *p4cRunMetadataFromObject(
+    const p4cRunRow *object             ///< fooRow to convert into a psMetadata
+);
+
+/** Convert a psMetadata into an equivalent fooRow
+ *
+ * @return A p4cRunRow pointer or NULL on error
+ */
+
+p4cRunRow *p4cRunObjectFromMetadata(
+    psMetadata      *md                 ///< psMetadata to convert into a fooRow
+);
+/** Selects up to limit rows from the database and returns as p4cRunRow objects in a psArray
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return A psArray pointer or NULL on error
+ */
+
+psArray *p4cRunSelectRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+/** Deletes a row from the database coresponding to an p4cRun
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+bool p4cRunDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4cRunRow *object    ///< Object to delete
+);
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long p4cRunDeleteRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psArray   *objects,           ///< Array of objects to delete
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+/** Formats and prints an array of p4cRunRow objects
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool p4cRunPrintObjects(
+    FILE            *stream,            ///< a stream
+    psArray         *objects,           ///< An array of p4cRunRow objects
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** Formats and prints an p4cRunRow object
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool p4cRunPrintObject(
+    FILE            *stream,            ///< a stream
+    p4cRunRow *object,    ///< an p4cRunRow object
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** p4cInputExpRow data structure
+ *
+ * Structure for representing a single row of p4cInputExp table data.
+ */
+
+typedef struct {
+    psS32           p4c_id;
+    char            *exp_tag;
+    psS32           p3_version;
+} p4cInputExpRow;
+
+/** Creates a new p4cInputExpRow object
+ *
+ *  @return A new p4cInputExpRow object or NULL on failure.
+ */
+
+p4cInputExpRow *p4cInputExpRowAlloc(
+    psS32           p4c_id,
+    const char      *exp_tag,
+    psS32           p3_version
+);
+
+/** Creates a new p4cInputExp table
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpCreateTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Deletes a p4cInputExp table
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpDropTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Insert a single row into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpInsert(
+    psDB            *dbh,               ///< Database handle
+    psS32           p4c_id,
+    const char      *exp_tag,
+    psS32           p3_version
+);
+
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long p4cInputExpDelete(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+
+/** Insert a single p4cInputExpRow object into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpInsertObject(
+    psDB            *dbh,               ///< Database handle
+    p4cInputExpRow  *object             ///< p4cInputExpRow object
+);
+
+/** Insert an array of p4cInputExpRow object into a table
+ *
+ * This function constructs and inserts multiple rows based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of p4cInputExpRow objects
+);
+
+/** Insert data from a binary FITS table p4cInputExpRow into the database
+ *
+ * This function expects a psFits object with a FITS table as the first
+ * extension.  The table must have at least one row of data in it, that is of
+ * the appropriate format (number of columns and their type).  All other
+ * extensions are ignored.
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpInsertFits(
+    psDB            *dbh,               ///< Database handle
+    const psFits    *fits               ///< psFits object
+);
+
+/** Selects up to limit from the database and returns them in a binary FITS table
+ *
+ * This function assumes an empty psFits object and will create a FITS table
+ * as the first extension.
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpSelectRowsFits(
+    psDB            *dbh,               ///< Database handle
+    psFits          *fits,              ///< psFits object
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+
+/** Convert a p4cInputExpRow into an equivalent psMetadata
+ *
+ * @return A psMetadata pointer or NULL on error
+ */
+
+psMetadata *p4cInputExpMetadataFromObject(
+    const p4cInputExpRow *object             ///< fooRow to convert into a psMetadata
+);
+
+/** Convert a psMetadata into an equivalent fooRow
+ *
+ * @return A p4cInputExpRow pointer or NULL on error
+ */
+
+p4cInputExpRow *p4cInputExpObjectFromMetadata(
+    psMetadata      *md                 ///< psMetadata to convert into a fooRow
+);
+/** Selects up to limit rows from the database and returns as p4cInputExpRow objects in a psArray
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return A psArray pointer or NULL on error
+ */
+
+psArray *p4cInputExpSelectRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+/** Deletes a row from the database coresponding to an p4cInputExp
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+bool p4cInputExpDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const p4cInputExpRow *object    ///< Object to delete
+);
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long p4cInputExpDeleteRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psArray   *objects,           ///< Array of objects to delete
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+/** Formats and prints an array of p4cInputExpRow objects
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpPrintObjects(
+    FILE            *stream,            ///< a stream
+    psArray         *objects,           ///< An array of p4cInputExpRow objects
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** Formats and prints an p4cInputExpRow object
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool p4cInputExpPrintObject(
+    FILE            *stream,            ///< a stream
+    p4cInputExpRow *object,    ///< an p4cInputExpRow object
+    bool            mdcf                ///< format as mdconfig or simple
+);
 /** p4MagicMaskImfileRow data structure
  *
@@ -7898,5 +8492,5 @@
 
 typedef struct {
-    psS32           p4_id;
+    psS32           p4c_id;
     char            *exp_tag;
     psS32           p3_version;
@@ -7911,5 +8505,5 @@
 
 p4MagicMaskImfileRow *p4MagicMaskImfileRowAlloc(
-    psS32           p4_id,
+    psS32           p4c_id,
     const char      *exp_tag,
     psS32           p3_version,
@@ -7945,5 +8539,5 @@
 bool p4MagicMaskImfileInsert(
     psDB            *dbh,               ///< Database handle
-    psS32           p4_id,
+    psS32           p4c_id,
     const char      *exp_tag,
     psS32           p3_version,
@@ -8099,4 +8693,430 @@
     bool            mdcf                ///< format as mdconfig or simple
 );
+/** skyCellRow data structure
+ *
+ * Structure for representing a single row of skyCell table data.
+ */
+
+typedef struct {
+    char            *skycell_id;
+    char            *tess_id;
+    psF64           ra1;
+    psF64           decl1;
+    psF64           ra2;
+    psF64           decl2;
+    psF64           ra3;
+    psF64           decl3;
+    psF64           ra4;
+    psF64           decl4;
+} skyCellRow;
+
+/** Creates a new skyCellRow object
+ *
+ *  @return A new skyCellRow object or NULL on failure.
+ */
+
+skyCellRow *skyCellRowAlloc(
+    const char      *skycell_id,
+    const char      *tess_id,
+    psF64           ra1,
+    psF64           decl1,
+    psF64           ra2,
+    psF64           decl2,
+    psF64           ra3,
+    psF64           decl3,
+    psF64           ra4,
+    psF64           decl4
+);
+
+/** Creates a new skyCell table
+ *
+ * @return true on success
+ */
+
+bool skyCellCreateTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Deletes a skyCell table
+ *
+ * @return true on success
+ */
+
+bool skyCellDropTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Insert a single row into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool skyCellInsert(
+    psDB            *dbh,               ///< Database handle
+    const char      *skycell_id,
+    const char      *tess_id,
+    psF64           ra1,
+    psF64           decl1,
+    psF64           ra2,
+    psF64           decl2,
+    psF64           ra3,
+    psF64           decl3,
+    psF64           ra4,
+    psF64           decl4
+);
+
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long skyCellDelete(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+
+/** Insert a single skyCellRow object into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool skyCellInsertObject(
+    psDB            *dbh,               ///< Database handle
+    skyCellRow      *object             ///< skyCellRow object
+);
+
+/** Insert an array of skyCellRow object into a table
+ *
+ * This function constructs and inserts multiple rows based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool skyCellInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of skyCellRow objects
+);
+
+/** Insert data from a binary FITS table skyCellRow into the database
+ *
+ * This function expects a psFits object with a FITS table as the first
+ * extension.  The table must have at least one row of data in it, that is of
+ * the appropriate format (number of columns and their type).  All other
+ * extensions are ignored.
+ *
+ * @return true on success
+ */
+
+bool skyCellInsertFits(
+    psDB            *dbh,               ///< Database handle
+    const psFits    *fits               ///< psFits object
+);
+
+/** Selects up to limit from the database and returns them in a binary FITS table
+ *
+ * This function assumes an empty psFits object and will create a FITS table
+ * as the first extension.
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return true on success
+ */
+
+bool skyCellSelectRowsFits(
+    psDB            *dbh,               ///< Database handle
+    psFits          *fits,              ///< psFits object
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+
+/** Convert a skyCellRow into an equivalent psMetadata
+ *
+ * @return A psMetadata pointer or NULL on error
+ */
+
+psMetadata *skyCellMetadataFromObject(
+    const skyCellRow *object             ///< fooRow to convert into a psMetadata
+);
+
+/** Convert a psMetadata into an equivalent fooRow
+ *
+ * @return A skyCellRow pointer or NULL on error
+ */
+
+skyCellRow *skyCellObjectFromMetadata(
+    psMetadata      *md                 ///< psMetadata to convert into a fooRow
+);
+/** Selects up to limit rows from the database and returns as skyCellRow objects in a psArray
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return A psArray pointer or NULL on error
+ */
+
+psArray *skyCellSelectRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+/** Deletes a row from the database coresponding to an skyCell
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+bool skyCellDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const skyCellRow *object    ///< Object to delete
+);
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long skyCellDeleteRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psArray   *objects,           ///< Array of objects to delete
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+/** Formats and prints an array of skyCellRow objects
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool skyCellPrintObjects(
+    FILE            *stream,            ///< a stream
+    psArray         *objects,           ///< An array of skyCellRow objects
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** Formats and prints an skyCellRow object
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool skyCellPrintObject(
+    FILE            *stream,            ///< a stream
+    skyCellRow *object,    ///< an skyCellRow object
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** skyCellMapRow data structure
+ *
+ * Structure for representing a single row of skyCellMap table data.
+ */
+
+typedef struct {
+    char            *skycell_id;
+    char            *tess_id;
+    char            *exp_tag;
+    char            *class_id;
+} skyCellMapRow;
+
+/** Creates a new skyCellMapRow object
+ *
+ *  @return A new skyCellMapRow object or NULL on failure.
+ */
+
+skyCellMapRow *skyCellMapRowAlloc(
+    const char      *skycell_id,
+    const char      *tess_id,
+    const char      *exp_tag,
+    const char      *class_id
+);
+
+/** Creates a new skyCellMap table
+ *
+ * @return true on success
+ */
+
+bool skyCellMapCreateTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Deletes a skyCellMap table
+ *
+ * @return true on success
+ */
+
+bool skyCellMapDropTable(
+    psDB            *dbh                ///< Database handle
+);
+
+/** Insert a single row into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool skyCellMapInsert(
+    psDB            *dbh,               ///< Database handle
+    const char      *skycell_id,
+    const char      *tess_id,
+    const char      *exp_tag,
+    const char      *class_id
+);
+
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long skyCellMapDelete(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+
+/** Insert a single skyCellMapRow object into a table
+ *
+ * This function constructs and inserts a single row based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool skyCellMapInsertObject(
+    psDB            *dbh,               ///< Database handle
+    skyCellMapRow   *object             ///< skyCellMapRow object
+);
+
+/** Insert an array of skyCellMapRow object into a table
+ *
+ * This function constructs and inserts multiple rows based on it's parameters.
+ *
+ * @return true on success
+ */
+
+bool skyCellMapInsertObjects(
+    psDB            *dbh,               ///< Database handle
+    psArray         *objects            ///< array of skyCellMapRow objects
+);
+
+/** Insert data from a binary FITS table skyCellMapRow into the database
+ *
+ * This function expects a psFits object with a FITS table as the first
+ * extension.  The table must have at least one row of data in it, that is of
+ * the appropriate format (number of columns and their type).  All other
+ * extensions are ignored.
+ *
+ * @return true on success
+ */
+
+bool skyCellMapInsertFits(
+    psDB            *dbh,               ///< Database handle
+    const psFits    *fits               ///< psFits object
+);
+
+/** Selects up to limit from the database and returns them in a binary FITS table
+ *
+ * This function assumes an empty psFits object and will create a FITS table
+ * as the first extension.
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return true on success
+ */
+
+bool skyCellMapSelectRowsFits(
+    psDB            *dbh,               ///< Database handle
+    psFits          *fits,              ///< psFits object
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+
+/** Convert a skyCellMapRow into an equivalent psMetadata
+ *
+ * @return A psMetadata pointer or NULL on error
+ */
+
+psMetadata *skyCellMapMetadataFromObject(
+    const skyCellMapRow *object             ///< fooRow to convert into a psMetadata
+);
+
+/** Convert a psMetadata into an equivalent fooRow
+ *
+ * @return A skyCellMapRow pointer or NULL on error
+ */
+
+skyCellMapRow *skyCellMapObjectFromMetadata(
+    psMetadata      *md                 ///< psMetadata to convert into a fooRow
+);
+/** Selects up to limit rows from the database and returns as skyCellMapRow objects in a psArray
+ *
+ *  See psDBSelectRows() for documentation on the format of where.
+ *
+ * @return A psArray pointer or NULL on error
+ */
+
+psArray *skyCellMapSelectRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psMetadata *where,            ///< Row match criteria
+    unsigned long long limit            ///< Maximum number of elements to return
+);
+/** Deletes a row from the database coresponding to an skyCellMap
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+bool skyCellMapDeleteObject(
+    psDB            *dbh,               ///< Database handle
+    const skyCellMapRow *object    ///< Object to delete
+);
+/** Deletes up to limit rows from the database and returns the number of rows actually deleted. 
+ *
+ *  Note that a 'where' search psMetadata is constructed from each object and
+ *  used to find rows to delete.
+ *
+ * @return A The number of rows removed or a negative value on error
+ */
+
+long long skyCellMapDeleteRowObjects(
+    psDB            *dbh,               ///< Database handle
+    const psArray   *objects,           ///< Array of objects to delete
+    unsigned long long limit            ///< Maximum number of elements to delete 
+);
+/** Formats and prints an array of skyCellMapRow objects
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool skyCellMapPrintObjects(
+    FILE            *stream,            ///< a stream
+    psArray         *objects,           ///< An array of skyCellMapRow objects
+    bool            mdcf                ///< format as mdconfig or simple
+);
+/** Formats and prints an skyCellMapRow object
+ *
+ * When mdcf is set the formated output is in psMetadataConfig
+ * format, otherwise it is in a simple tabular format.
+ *
+ * @return true on success
+ */
+
+bool skyCellMapPrintObject(
+    FILE            *stream,            ///< a stream
+    skyCellMapRow *object,    ///< an skyCellMapRow object
+    bool            mdcf                ///< format as mdconfig or simple
+);
 
 /// @}
@@ -8106,3 +9126,3 @@
 #endif
 
-#endif // P4MAGICMASKIMFILE_DB_H
+#endif // SKYCELLMAP_DB_H
Index: /trunk/ippdb/tests/alloc.c
===================================================================
--- /trunk/ippdb/tests/alloc.c	(revision 11678)
+++ /trunk/ippdb/tests/alloc.c	(revision 11679)
@@ -17,4 +17,5 @@
         }
 
+        if (!object->counter == 64) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -399,4 +400,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -490,4 +492,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -691,4 +694,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -800,4 +804,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1002,4 +1007,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1050,4 +1056,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1098,4 +1105,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1130,4 +1138,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1182,4 +1191,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1230,4 +1240,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1290,4 +1301,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1346,4 +1358,5 @@
             exit(EXIT_FAILURE);
         }
+        if (!object->fault == -16) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1386,25 +1399,22 @@
             exit(EXIT_FAILURE);
         }
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        p4RunRow        *object;
-
-        object = p4RunRowAlloc(-32, "a string", "a string", "a string", "a string", "a string", "a string", 64.64, 64.64, "a string", "a string"    );
-
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->survey_mode, "a string", MAX_STRING_LENGTH)) {
+        if (!object->fault == -16) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4aRunRow       *object;
+
+        object = p4aRunRowAlloc(-32, "a string", "a string", true    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4a_id == -32) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1418,5 +1428,47 @@
             exit(EXIT_FAILURE);
         }
-        if (strncmp(object->filter, "a string", MAX_STRING_LENGTH)) {
+        if (!object->magic == true) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4aInputExpRow  *object;
+
+        object = p4aInputExpRowAlloc(-32, "a string", -32    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4a_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4aScfileRow    *object;
+
+        object = p4aScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4a_id == -32) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -1430,37 +1482,4 @@
             exit(EXIT_FAILURE);
         }
-        if (!object->ra == 64.64) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (!object->decl == 64.64) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->input_ss, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->output_ss, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        p4InputImfileRow *object;
-
-        object = p4InputImfileRowAlloc(-32, "a string", -32, "a string"    );
-
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
         if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
             psFree(object);
@@ -1471,153 +1490,293 @@
             exit(EXIT_FAILURE);
         }
+        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg_mean_stdev == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4bRunRow       *object;
+
+        object = p4bRunRowAlloc(-32, "a string", "a string", true    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4b_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->state, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->workdir, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->magic == true) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4bInputScfileRow *object;
+
+        object = p4bInputScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string"    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4b_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->kind, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4bDiffScfileRow *object;
+
+        object = p4bDiffScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4b_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg_mean_stdev == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4cRunRow       *object;
+
+        object = p4cRunRowAlloc(-32, "a string", "a string", true    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4c_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->state, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->workdir, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->magic == true) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4cInputExpRow  *object;
+
+        object = p4cInputExpRowAlloc(-32, "a string", -32    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4c_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        p4MagicMaskImfileRow *object;
+
+        object = p4MagicMaskImfileRowAlloc(-32, "a string", -32, "a string", "a string"    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!object->p4c_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
         if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
             psFree(object);
             exit(EXIT_FAILURE);
         }
-
-        psFree(object);
-    }
-
-    {
-        p4WarpedImfileRow *object;
-
-        object = p4WarpedImfileRowAlloc(-32, "a string", -32, "a string", "a string", "a string", "a string"    );
-
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (!object->p3_version == -32) {
+        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        skyCellRow      *object;
+
+        object = skyCellRowAlloc("a string", "a string", 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra1 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl1 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra2 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl2 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra3 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl3 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra4 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl4 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        skyCellMapRow   *object;
+
+        object = skyCellMapRowAlloc("a string", "a string", "a string", "a string"    );
+
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
             psFree(object);
             exit(EXIT_FAILURE);
         }
         if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b1_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b2_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        p4StackedImfileRow *object;
-
-        object = p4StackedImfileRowAlloc(-32, "a string", "a string", "a string", "a string"    );
-
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b1_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b2_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        p4DiffImfileRow *object;
-
-        object = p4DiffImfileRowAlloc(-32, "a string", -32, "a string", "a string", "a string", "a string"    );
-
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (!object->p3_version == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b1_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b2_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        p4MagicMaskImfileRow *object;
-
-        object = p4MagicMaskImfileRowAlloc(-32, "a string", -32, "a string", "a string"    );
-
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (!object->p3_version == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
             psFree(object);
             exit(EXIT_FAILURE);
Index: /trunk/ippdb/tests/createtable.c
===================================================================
--- /trunk/ippdb/tests/createtable.c	(revision 11678)
+++ /trunk/ippdb/tests/createtable.c	(revision 11679)
@@ -478,65 +478,110 @@
         }
 
-        if(!p4RunCreateTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if(!p4InputImfileCreateTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if(!p4WarpedImfileCreateTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if(!p4StackedImfileCreateTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if(!p4DiffImfileCreateTable(dbh)) {
+        if(!p4aRunCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!p4aInputExpCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!p4aScfileCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!p4bRunCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!p4bInputScfileCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!p4bDiffScfileCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!p4cRunCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!p4cInputExpCreateTable(dbh)) {
             exit(EXIT_FAILURE);
         }
@@ -554,4 +599,34 @@
 
         if(!p4MagicMaskImfileCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!skyCellCreateTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if(!skyCellMapCreateTable(dbh)) {
             exit(EXIT_FAILURE);
         }
Index: /trunk/ippdb/tests/dbcleanup.c
===================================================================
--- /trunk/ippdb/tests/dbcleanup.c	(revision 11678)
+++ /trunk/ippdb/tests/dbcleanup.c	(revision 11679)
@@ -6,5 +6,5 @@
     psDB            *dbh;
 
-    dbh = psDBInit("localhost", "test", NULL, "test");
+    dbh = psDBInit("localhost", "test", NULL, "test", 0);
     if (!dbh) {
         exit(EXIT_FAILURE);
@@ -42,10 +42,15 @@
     p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS detResidExp");
     p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS detRunSummary");
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4Run");
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4InputImfile");
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4WarpedImfile");
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4StackedImfile");
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4DiffImfile");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4aRun");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4aInputExp");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4aScfile");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4bRun");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4bInputScfile");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4bDiffScfile");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4cRun");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4cInputExp");
     p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4MagicMaskImfile");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS skyCell");
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS skyCellMap");
 
     psDBCleanup(dbh);
Index: /trunk/ippdb/tests/dbsetup.c
===================================================================
--- /trunk/ippdb/tests/dbsetup.c	(revision 11678)
+++ /trunk/ippdb/tests/dbsetup.c	(revision 11679)
@@ -7,5 +7,5 @@
     psDB            *dbh;
 
-    dbh = psDBInit("localhost", "test", NULL, "test");
+    dbh = psDBInit("localhost", "test", NULL, "test", 0);
     if (!dbh) {
         exit(EXIT_FAILURE);
@@ -106,21 +106,36 @@
     detRunSummaryCreateTable(dbh);
 
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4Run");
-    p4RunCreateTable(dbh);
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4aRun");
+    p4aRunCreateTable(dbh);
 
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4InputImfile");
-    p4InputImfileCreateTable(dbh);
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4aInputExp");
+    p4aInputExpCreateTable(dbh);
 
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4WarpedImfile");
-    p4WarpedImfileCreateTable(dbh);
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4aScfile");
+    p4aScfileCreateTable(dbh);
 
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4StackedImfile");
-    p4StackedImfileCreateTable(dbh);
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4bRun");
+    p4bRunCreateTable(dbh);
 
-    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4DiffImfile");
-    p4DiffImfileCreateTable(dbh);
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4bInputScfile");
+    p4bInputScfileCreateTable(dbh);
+
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4bDiffScfile");
+    p4bDiffScfileCreateTable(dbh);
+
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4cRun");
+    p4cRunCreateTable(dbh);
+
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4cInputExp");
+    p4cInputExpCreateTable(dbh);
 
     p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS p4MagicMaskImfile");
     p4MagicMaskImfileCreateTable(dbh);
+
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS skyCell");
+    skyCellCreateTable(dbh);
+
+    p_psDBRunQuery(dbh, "DROP TABLE IF EXISTS skyCellMap");
+    skyCellMapCreateTable(dbh);
 
     psDBCleanup(dbh);
Index: /trunk/ippdb/tests/droptable.c
===================================================================
--- /trunk/ippdb/tests/droptable.c	(revision 11678)
+++ /trunk/ippdb/tests/droptable.c	(revision 11679)
@@ -478,65 +478,110 @@
         }
 
-        if (!p4RunDropTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4InputImfileDropTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4WarpedImfileDropTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4StackedImfileDropTable(dbh)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4DiffImfileDropTable(dbh)) {
+        if (!p4aRunDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aInputExpDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aScfileDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bRunDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bInputScfileDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bDiffScfileDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cRunDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cInputExpDropTable(dbh)) {
             exit(EXIT_FAILURE);
         }
@@ -554,4 +599,34 @@
 
         if (!p4MagicMaskImfileDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellDropTable(dbh)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellMapDropTable(dbh)) {
             exit(EXIT_FAILURE);
         }
Index: /trunk/ippdb/tests/insert.c
===================================================================
--- /trunk/ippdb/tests/insert.c	(revision 11678)
+++ /trunk/ippdb/tests/insert.c	(revision 11679)
@@ -478,65 +478,110 @@
         }
 
-        if (!p4RunInsert(dbh, -32, "a string", "a string", "a string", "a string", "a string", "a string", 64.64, 64.64, "a string", "a string")) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4InputImfileInsert(dbh, -32, "a string", -32, "a string")) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4WarpedImfileInsert(dbh, -32, "a string", -32, "a string", "a string", "a string", "a string")) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4StackedImfileInsert(dbh, -32, "a string", "a string", "a string", "a string")) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4DiffImfileInsert(dbh, -32, "a string", -32, "a string", "a string", "a string", "a string")) {
+        if (!p4aRunInsert(dbh, -32, "a string", "a string", true)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aInputExpInsert(dbh, -32, "a string", -32)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aScfileInsert(dbh, -32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bRunInsert(dbh, -32, "a string", "a string", true)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bInputScfileInsert(dbh, -32, "a string", "a string", "a string", -32, "a string")) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bDiffScfileInsert(dbh, -32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cRunInsert(dbh, -32, "a string", "a string", true)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cInputExpInsert(dbh, -32, "a string", -32)) {
             exit(EXIT_FAILURE);
         }
@@ -554,4 +599,34 @@
 
         if (!p4MagicMaskImfileInsert(dbh, -32, "a string", -32, "a string", "a string")) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellInsert(dbh, "a string", "a string", 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellMapInsert(dbh, "a string", "a string", "a string", "a string")) {
             exit(EXIT_FAILURE);
         }
Index: /trunk/ippdb/tests/insertfits.c
===================================================================
--- /trunk/ippdb/tests/insertfits.c	(revision 11678)
+++ /trunk/ippdb/tests/insertfits.c	(revision 11679)
@@ -830,109 +830,187 @@
         }
 
-        if (!p4RunInsertFits(dbh, fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!psFitsClose(fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        // open a temp
-        fits = psFitsOpen(TMP_FILENAME, "r");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4InputImfileInsertFits(dbh, fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!psFitsClose(fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        // open a temp
-        fits = psFitsOpen(TMP_FILENAME, "r");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4WarpedImfileInsertFits(dbh, fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!psFitsClose(fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        // open a temp
-        fits = psFitsOpen(TMP_FILENAME, "r");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4StackedImfileInsertFits(dbh, fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!psFitsClose(fits)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        // open a temp
-        fits = psFitsOpen(TMP_FILENAME, "r");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4DiffImfileInsertFits(dbh, fits)) {
+        if (!p4aRunInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aInputExpInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aScfileInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bRunInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bInputScfileInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bDiffScfileInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cRunInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cInputExpInsertFits(dbh, fits)) {
             exit(EXIT_FAILURE);
         }
@@ -961,4 +1039,56 @@
 
         if (!p4MagicMaskImfileInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellInsertFits(dbh, fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!psFitsClose(fits)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        // open a temp
+        fits = psFitsOpen(TMP_FILENAME, "r");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellMapInsertFits(dbh, fits)) {
             exit(EXIT_FAILURE);
         }
Index: /trunk/ippdb/tests/insertobject.c
===================================================================
--- /trunk/ippdb/tests/insertobject.c	(revision 11678)
+++ /trunk/ippdb/tests/insertobject.c	(revision 11679)
@@ -689,105 +689,171 @@
     {
         psDB            *dbh;
-        p4RunRow        *object;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4RunRowAlloc(-32, "a string", "a string", "a string", "a string", "a string", "a string", 64.64, 64.64, "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4RunInsertObject(dbh, object)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        p4InputImfileRow *object;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4InputImfileRowAlloc(-32, "a string", -32, "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4InputImfileInsertObject(dbh, object)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        p4WarpedImfileRow *object;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4WarpedImfileRowAlloc(-32, "a string", -32, "a string", "a string", "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4WarpedImfileInsertObject(dbh, object)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        p4StackedImfileRow *object;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4StackedImfileRowAlloc(-32, "a string", "a string", "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4StackedImfileInsertObject(dbh, object)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        p4DiffImfileRow *object;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4DiffImfileRowAlloc(-32, "a string", -32, "a string", "a string", "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4DiffImfileInsertObject(dbh, object)) {
+        p4aRunRow       *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4aRunRowAlloc(-32, "a string", "a string", true);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aRunInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        p4aInputExpRow  *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4aInputExpRowAlloc(-32, "a string", -32);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aInputExpInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        p4aScfileRow    *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4aScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aScfileInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        p4bRunRow       *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4bRunRowAlloc(-32, "a string", "a string", true);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bRunInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        p4bInputScfileRow *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4bInputScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string");
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bInputScfileInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        p4bDiffScfileRow *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4bDiffScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bDiffScfileInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        p4cRunRow       *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4cRunRowAlloc(-32, "a string", "a string", true);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cRunInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        p4cInputExpRow  *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4cInputExpRowAlloc(-32, "a string", -32);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cInputExpInsertObject(dbh, object)) {
             exit(EXIT_FAILURE);
         }
@@ -812,4 +878,48 @@
 
         if (!p4MagicMaskImfileInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        skyCellRow      *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = skyCellRowAlloc("a string", "a string", 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellInsertObject(dbh, object)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        skyCellMapRow   *object;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        object = skyCellMapRowAlloc("a string", "a string", "a string", "a string");
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellMapInsertObject(dbh, object)) {
             exit(EXIT_FAILURE);
         }
Index: /trunk/ippdb/tests/metadatafromobject.c
===================================================================
--- /trunk/ippdb/tests/metadatafromobject.c	(revision 11678)
+++ /trunk/ippdb/tests/metadatafromobject.c	(revision 11679)
@@ -1643,24 +1643,20 @@
     {
         psMetadata      *md;
-        p4RunRow        *object;
-        bool            status;
-
-        object = p4RunRowAlloc(-32, "a string", "a string", "a string", "a string", "a string", "a string", 64.64, 64.64, "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        md = p4RunMetadataFromObject(object);
-        if (!md) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-
-        if (!psMetadataLookupS32(&status, md, "p4_id") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "survey_mode"), "a string", MAX_STRING_LENGTH)) {
+        p4aRunRow       *object;
+        bool            status;
+
+        object = p4aRunRowAlloc(-32, "a string", "a string", true);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4aRunMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4a_id") == -32) {
             psFree(md);
             exit(EXIT_FAILURE);
@@ -1674,5 +1670,63 @@
             exit(EXIT_FAILURE);
         }
-        if (strncmp(psMetadataLookupPtr(&status, md, "filter"), "a string", MAX_STRING_LENGTH)) {
+        if (!psMetadataLookupBool(&status, md, "magic") == true) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4aInputExpRow  *object;
+        bool            status;
+
+        object = p4aInputExpRowAlloc(-32, "a string", -32);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4aInputExpMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4a_id") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4aScfileRow    *object;
+        bool            status;
+
+        object = p4aScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4aScfileMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4a_id") == -32) {
             psFree(md);
             exit(EXIT_FAILURE);
@@ -1686,45 +1740,4 @@
             exit(EXIT_FAILURE);
         }
-        if (!psMetadataLookupF64(&status, md, "ra") == 64.64) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataLookupF64(&status, md, "decl") == 64.64) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "input_ss"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "output_ss"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-    }
-
-    {
-        psMetadata      *md;
-        p4InputImfileRow *object;
-        bool            status;
-
-        object = p4InputImfileRowAlloc(-32, "a string", -32, "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        md = p4InputImfileMetadataFromObject(object);
-        if (!md) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-
-        if (!psMetadataLookupS32(&status, md, "p4_id") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
         if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
             psFree(md);
@@ -1735,185 +1748,357 @@
             exit(EXIT_FAILURE);
         }
+        if (strncmp(psMetadataLookupPtr(&status, md, "uri"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "bg") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "bg_mean_stdev") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4bRunRow       *object;
+        bool            status;
+
+        object = p4bRunRowAlloc(-32, "a string", "a string", true);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4bRunMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4b_id") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "state"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "workdir"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupBool(&status, md, "magic") == true) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4bInputScfileRow *object;
+        bool            status;
+
+        object = p4bInputScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string");
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4bInputScfileMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4b_id") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "skycell_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "tess_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "kind"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4bDiffScfileRow *object;
+        bool            status;
+
+        object = p4bDiffScfileRowAlloc(-32, "a string", "a string", "a string", -32, "a string", 64.64, 64.64);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4bDiffScfileMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4b_id") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "skycell_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "tess_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "uri"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "bg") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "bg_mean_stdev") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4cRunRow       *object;
+        bool            status;
+
+        object = p4cRunRowAlloc(-32, "a string", "a string", true);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4cRunMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4c_id") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "state"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "workdir"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupBool(&status, md, "magic") == true) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4cInputExpRow  *object;
+        bool            status;
+
+        object = p4cInputExpRowAlloc(-32, "a string", -32);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4cInputExpMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4c_id") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        p4MagicMaskImfileRow *object;
+        bool            status;
+
+        object = p4MagicMaskImfileRowAlloc(-32, "a string", -32, "a string", "a string");
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = p4MagicMaskImfileMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (!psMetadataLookupS32(&status, md, "p4c_id") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
         if (strncmp(psMetadataLookupPtr(&status, md, "class_id"), "a string", MAX_STRING_LENGTH)) {
             psFree(md);
             exit(EXIT_FAILURE);
         }
-
-        psFree(md);
-    }
-
-    {
-        psMetadata      *md;
-        p4WarpedImfileRow *object;
-        bool            status;
-
-        object = p4WarpedImfileRowAlloc(-32, "a string", -32, "a string", "a string", "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        md = p4WarpedImfileMetadataFromObject(object);
-        if (!md) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-
-        if (!psMetadataLookupS32(&status, md, "p4_id") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
+        if (strncmp(psMetadataLookupPtr(&status, md, "uri"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        skyCellRow      *object;
+        bool            status;
+
+        object = skyCellRowAlloc("a string", "a string", 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64, 64.64);
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = skyCellMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (strncmp(psMetadataLookupPtr(&status, md, "skycell_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "tess_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "ra1") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "decl1") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "ra2") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "decl2") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "ra3") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "decl3") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "ra4") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataLookupF64(&status, md, "decl4") == 64.64) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+    }
+
+    {
+        psMetadata      *md;
+        skyCellMapRow   *object;
+        bool            status;
+
+        object = skyCellMapRowAlloc("a string", "a string", "a string", "a string");
+        if (!object) {
+            exit(EXIT_FAILURE);
+        }
+
+        md = skyCellMapMetadataFromObject(object);
+        if (!md) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+
+        if (strncmp(psMetadataLookupPtr(&status, md, "skycell_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "tess_id"), "a string", MAX_STRING_LENGTH)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
             psFree(md);
             exit(EXIT_FAILURE);
         }
         if (strncmp(psMetadataLookupPtr(&status, md, "class_id"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "b1_uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "b2_uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-    }
-
-    {
-        psMetadata      *md;
-        p4StackedImfileRow *object;
-        bool            status;
-
-        object = p4StackedImfileRowAlloc(-32, "a string", "a string", "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        md = p4StackedImfileMetadataFromObject(object);
-        if (!md) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-
-        if (!psMetadataLookupS32(&status, md, "p4_id") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "class_id"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "b1_uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "b2_uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-    }
-
-    {
-        psMetadata      *md;
-        p4DiffImfileRow *object;
-        bool            status;
-
-        object = p4DiffImfileRowAlloc(-32, "a string", -32, "a string", "a string", "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        md = p4DiffImfileMetadataFromObject(object);
-        if (!md) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-
-        if (!psMetadataLookupS32(&status, md, "p4_id") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "class_id"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "b1_uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "b2_uri"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-    }
-
-    {
-        psMetadata      *md;
-        p4MagicMaskImfileRow *object;
-        bool            status;
-
-        object = p4MagicMaskImfileRowAlloc(-32, "a string", -32, "a string", "a string");
-        if (!object) {
-            exit(EXIT_FAILURE);
-        }
-
-        md = p4MagicMaskImfileMetadataFromObject(object);
-        if (!md) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-
-        if (!psMetadataLookupS32(&status, md, "p4_id") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "exp_tag"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataLookupS32(&status, md, "p3_version") == -32) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "class_id"), "a string", MAX_STRING_LENGTH)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(psMetadataLookupPtr(&status, md, "uri"), "a string", MAX_STRING_LENGTH)) {
             psFree(md);
             exit(EXIT_FAILURE);
Index: /trunk/ippdb/tests/objectfrommetadata.c
===================================================================
--- /trunk/ippdb/tests/objectfrommetadata.c	(revision 11678)
+++ /trunk/ippdb/tests/objectfrommetadata.c	(revision 11679)
@@ -2532,12 +2532,8 @@
     {
         psMetadata      *md;
-        p4RunRow        *object;
-
-        md = psMetadataAlloc();
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4_id", 0, NULL, -32)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "survey_mode", 0, NULL, "a string")) {
+        p4aRunRow       *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4a_id", 0, NULL, -32)) {
             psFree(md);
             exit(EXIT_FAILURE);
@@ -2551,5 +2547,85 @@
             exit(EXIT_FAILURE);
         }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "filter", 0, NULL, "a string")) {
+        if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, true)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4aRunObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4a_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->state, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->workdir, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->magic == true) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4aInputExpRow  *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4a_id", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "exp_tag", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4aInputExpObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4a_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4aScfileRow    *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4a_id", 0, NULL, -32)) {
             psFree(md);
             exit(EXIT_FAILURE);
@@ -2563,34 +2639,100 @@
             exit(EXIT_FAILURE);
         }
-        if (!psMetadataAddF64(md, PS_LIST_TAIL, "ra", 0, NULL, 64.64)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddF64(md, PS_LIST_TAIL, "decl", 0, NULL, 64.64)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "input_ss", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "output_ss", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4RunObjectFromMetadata(md);
-        if (!object) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->survey_mode, "a string", MAX_STRING_LENGTH)) {
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "exp_tag", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "uri", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "bg", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "bg_mean_stdev", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4aScfileObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4a_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg_mean_stdev == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4bRunRow       *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4b_id", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "state", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "workdir", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, true)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4bRunObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4b_id == -32) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -2604,5 +2746,51 @@
             exit(EXIT_FAILURE);
         }
-        if (strncmp(object->filter, "a string", MAX_STRING_LENGTH)) {
+        if (!object->magic == true) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4bInputScfileRow *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4b_id", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "skycell_id", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "tess_id", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "exp_tag", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "kind", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4bInputScfileObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4b_id == -32) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -2616,30 +2804,34 @@
             exit(EXIT_FAILURE);
         }
-        if (!object->ra == 64.64) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (!object->decl == 64.64) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->input_ss, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->output_ss, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        psMetadata      *md;
-        p4InputImfileRow *object;
-
-        md = psMetadataAlloc();
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4_id", 0, NULL, -32)) {
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->kind, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4bDiffScfileRow *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4b_id", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "skycell_id", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "tess_id", 0, NULL, "a string")) {
             psFree(md);
             exit(EXIT_FAILURE);
@@ -2653,18 +2845,188 @@
             exit(EXIT_FAILURE);
         }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "uri", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "bg", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "bg_mean_stdev", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4bDiffScfileObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4b_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->bg_mean_stdev == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4cRunRow       *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4c_id", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "state", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "workdir", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAdd(md, PS_LIST_TAIL, "magic", PS_DATA_BOOL, NULL, true)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4cRunObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4c_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->state, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->workdir, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->magic == true) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4cInputExpRow  *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4c_id", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "exp_tag", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4cInputExpObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4c_id == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->p3_version == -32) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        p4MagicMaskImfileRow *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4c_id", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "exp_tag", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
         if (!psMetadataAddStr(md, PS_LIST_TAIL, "class_id", 0, NULL, "a string")) {
             psFree(md);
             exit(EXIT_FAILURE);
         }
-
-        object = p4InputImfileObjectFromMetadata(md);
-        if (!object) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-
-        if (!object->p4_id == -32) {
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "uri", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = p4MagicMaskImfileObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (!object->p4c_id == -32) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -2682,14 +3044,120 @@
             exit(EXIT_FAILURE);
         }
-
-        psFree(object);
-    }
-
-    {
-        psMetadata      *md;
-        p4WarpedImfileRow *object;
-
-        md = psMetadataAlloc();
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4_id", 0, NULL, -32)) {
+        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        skyCellRow      *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "skycell_id", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "tess_id", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "ra1", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "decl1", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "ra2", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "decl2", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "ra3", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "decl3", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "ra4", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddF64(md, PS_LIST_TAIL, "decl4", 0, NULL, 64.64)) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        object = skyCellObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra1 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl1 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra2 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl2 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra3 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl3 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->ra4 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (!object->decl4 == 64.64) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(object);
+    }
+
+    {
+        psMetadata      *md;
+        skyCellMapRow   *object;
+
+        md = psMetadataAlloc();
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "skycell_id", 0, NULL, "a string")) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+        if (!psMetadataAddStr(md, PS_LIST_TAIL, "tess_id", 0, NULL, "a string")) {
             psFree(md);
             exit(EXIT_FAILURE);
@@ -2699,34 +3167,22 @@
             exit(EXIT_FAILURE);
         }
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
         if (!psMetadataAddStr(md, PS_LIST_TAIL, "class_id", 0, NULL, "a string")) {
             psFree(md);
             exit(EXIT_FAILURE);
         }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "b1_uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "b2_uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4WarpedImfileObjectFromMetadata(md);
-        if (!object) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-
-        if (!object->p4_id == -32) {
+
+        object = skyCellMapObjectFromMetadata(md);
+        if (!object) {
+            psFree(md);
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(md);
+
+        if (strncmp(object->skycell_id, "a string", MAX_STRING_LENGTH)) {
+            psFree(object);
+            exit(EXIT_FAILURE);
+        }
+        if (strncmp(object->tess_id, "a string", MAX_STRING_LENGTH)) {
             psFree(object);
             exit(EXIT_FAILURE);
@@ -2736,211 +3192,5 @@
             exit(EXIT_FAILURE);
         }
-        if (!object->p3_version == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
         if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b1_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b2_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        psMetadata      *md;
-        p4StackedImfileRow *object;
-
-        md = psMetadataAlloc();
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4_id", 0, NULL, -32)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "class_id", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "b1_uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "b2_uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4StackedImfileObjectFromMetadata(md);
-        if (!object) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b1_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b2_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        psMetadata      *md;
-        p4DiffImfileRow *object;
-
-        md = psMetadataAlloc();
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4_id", 0, NULL, -32)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "exp_tag", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "class_id", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "b1_uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "b2_uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4DiffImfileObjectFromMetadata(md);
-        if (!object) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (!object->p3_version == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b1_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->b2_uri, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(object);
-    }
-
-    {
-        psMetadata      *md;
-        p4MagicMaskImfileRow *object;
-
-        md = psMetadataAlloc();
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p4_id", 0, NULL, -32)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "exp_tag", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddS32(md, PS_LIST_TAIL, "p3_version", 0, NULL, -32)) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "class_id", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-        if (!psMetadataAddStr(md, PS_LIST_TAIL, "uri", 0, NULL, "a string")) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        object = p4MagicMaskImfileObjectFromMetadata(md);
-        if (!object) {
-            psFree(md);
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(md);
-
-        if (!object->p4_id == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->exp_tag, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (!object->p3_version == -32) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->class_id, "a string", MAX_STRING_LENGTH)) {
-            psFree(object);
-            exit(EXIT_FAILURE);
-        }
-        if (strncmp(object->uri, "a string", MAX_STRING_LENGTH)) {
             psFree(object);
             exit(EXIT_FAILURE);
Index: /trunk/ippdb/tests/selectrowsfits.c
===================================================================
--- /trunk/ippdb/tests/selectrowsfits.c	(revision 11678)
+++ /trunk/ippdb/tests/selectrowsfits.c	(revision 11679)
@@ -703,93 +703,159 @@
         }
 
-        if (!p4RunSelectRowsFits(dbh, fits, NULL, 1)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(fits);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        fits = psFitsOpen(TMP_FILENAME, "w");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4InputImfileSelectRowsFits(dbh, fits, NULL, 1)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(fits);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        fits = psFitsOpen(TMP_FILENAME, "w");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4WarpedImfileSelectRowsFits(dbh, fits, NULL, 1)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(fits);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        fits = psFitsOpen(TMP_FILENAME, "w");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4StackedImfileSelectRowsFits(dbh, fits, NULL, 1)) {
-            exit(EXIT_FAILURE);
-        }
-
-        psFree(fits);
-        psDBCleanup(dbh);
-    }
-
-    {
-        psDB            *dbh;
-        psFits          *fits;
-
-        dbh = psDBInit("localhost", "test", NULL, "test");
-        if (!dbh) {
-            exit(EXIT_FAILURE);
-        }
-
-        fits = psFitsOpen(TMP_FILENAME, "w");
-        if (!fits) {
-            exit(EXIT_FAILURE);
-        }
-
-        if (!p4DiffImfileSelectRowsFits(dbh, fits, NULL, 1)) {
+        if (!p4aRunSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aInputExpSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4aScfileSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bRunSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bInputScfileSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4bDiffScfileSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cRunSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!p4cInputExpSelectRowsFits(dbh, fits, NULL, 1)) {
             exit(EXIT_FAILURE);
         }
@@ -814,4 +880,48 @@
 
         if (!p4MagicMaskImfileSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellSelectRowsFits(dbh, fits, NULL, 1)) {
+            exit(EXIT_FAILURE);
+        }
+
+        psFree(fits);
+        psDBCleanup(dbh);
+    }
+
+    {
+        psDB            *dbh;
+        psFits          *fits;
+
+        dbh = psDBInit("localhost", "test", NULL, "test");
+        if (!dbh) {
+            exit(EXIT_FAILURE);
+        }
+
+        fits = psFitsOpen(TMP_FILENAME, "w");
+        if (!fits) {
+            exit(EXIT_FAILURE);
+        }
+
+        if (!skyCellMapSelectRowsFits(dbh, fits, NULL, 1)) {
             exit(EXIT_FAILURE);
         }
