Index: /trunk/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 9436)
+++ /trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 9437)
@@ -247,4 +247,5 @@
             formatName = words->data[1];
             file->camera = pmConfigCameraByName(config, words->data[0]);
+            // XXX do we need to save the camera name?
             if (!file->camera) {
                 psError(PS_ERR_IO, false, "camera %s not found\n", (char *)words->data[0]);
@@ -611,4 +612,8 @@
         return NULL;
     }
+    // a camera config is needed (as source of file rule)
+    if (config->cameraName == NULL) {
+        psAbort ("pmFPAfileDefine", "camera defined but not cameraName!");
+    }
 
     // find or define a pmFPAfile with this name
@@ -633,20 +638,14 @@
     // detselect -camera (camera) -time (time) -type (type) [others]
     // camera and time are functions of (pmFPA *input)
-
-    // XXX does this do something NASTY to the stack??
+    // XXX we need to get the time, but we don't have the CELL.TIME yet set (no CELL yet read)
+    // add other options here f(pmFPA *input, type)
     psTime *time = psTimeGetNow (PS_TIME_TAI);
-
-    psString camera = psStringCopy ("megacam");
-    pmDetrendSelectOptions *options = pmDetrendSelectOptionsAlloc(camera, *time, type);
-    psFree (camera);
+    pmDetrendSelectOptions *options = pmDetrendSelectOptionsAlloc(config->cameraName, *time, type);
     psFree (time);
-
-    // add other options here f(pmFPA *input, type)
 
     // search for existing detrend data (detID)
     pmDetrendSelectResults *results = pmDetrendSelect (options);
     if (!results) {
-        psLogMsg ("pmFPAfile", 2, "no matching detrend data");
-        psError (PS_ERR_IO, true, "no matching detrend data");
+        psError (PS_ERR_IO, false, "no matching detrend data");
         return NULL;
     }
Index: /trunk/psModules/src/camera/pmFPAfileIO.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAfileIO.c	(revision 9436)
+++ /trunk/psModules/src/camera/pmFPAfileIO.c	(revision 9437)
@@ -36,5 +36,4 @@
 
     bool status;
-    char *extra;
     char *mode = NULL;
     char *readMode = "r";
@@ -76,26 +75,52 @@
     // indirect filenames
     if (!strcasecmp (file->filename, "@FILES")) {
+        char *extra = pmFPAfileNameFromRule (file->filextra, file, view);
+        if (extra == NULL) {
+            psError(PS_ERR_IO, false, "error converting extrule to name %s\n", file->extrule);
+            return false;
+        }
+
         psFree (file->filename);
-        extra = pmFPAfileNameFromRule (file->filextra, file, view);
         file->filename = psMetadataLookupStr (&status, file->names, extra);
-        psFree (extra);
+
         if (file->filename == NULL) {
             psError(PS_ERR_IO, true, "filename lookup error (@FILES) for %s : %s\n", file->filextra, extra);
+            psFree (extra);
             return false;
         }
         // psMetadataLookupStr just returns a view, file->filename must be protected
         psMemIncrRefCounter (file->filename);
-    }
+        psFree (extra);
+    }
+
+    // get name from detrend database
+    // extrule expands to yield the class_id
+    // filextra contains the desired -det_id detID -iteration iter string
     if (!strcasecmp (file->filename, "@DETDB")) {
+        char *extra = pmFPAfileNameFromRule (file->extrule, file, view);
+        if (extra == NULL) {
+            psError(PS_ERR_IO, false, "error converting extrule to name %s\n", file->extrule);
+            return false;
+        }
+        psTrace ("pmFPAfile", 6, "looking for detrend (%s, %s)\n", file->filextra, extra);
+
         psFree (file->filename);
-        extra = pmFPAfileNameFromRule (file->extrule, file, view);
-        psTrace ("pmFPAfile", 6, "looking for detrend (%s, %s)\n", file->filextra, extra);
+
         file->filename = pmDetrendFile (file->filextra, extra);
+        if (file->filename == NULL) {
+            psError(PS_ERR_IO, false, "failed to find a valid detrend image for detID %s : classID %s\n", file->filextra, extra);
+            psFree (extra);
+            return false;
+        }
+
+        // XXXX this is very ad-hoc
+        // XXXX prepend the value config[WORKDIR] to the filename...
+        char *workdir = psMetadataLookupStr (NULL, config->site, "WORKDIR");
+        if (workdir) {
+            psStringPrepend (&file->filename, "%s/", workdir);
+        }
+
         psTrace ("pmFPAfile", 6, "got detrend file %s\n", file->filename);
         psFree (extra);
-        if (file->filename == NULL) {
-            psError(PS_ERR_IO, true, "filename lookup error (@DETBD) for %s : %s\n", file->filextra, extra);
-            return false;
-        }
     }
     // if () "neb://" -> get from neb...
@@ -571,8 +596,7 @@
     PS_ASSERT_PTR_NON_NULL(view, false);
 
-    bool status = true;
     psMetadata *files = config->files;
 
-    // attempt to perform all create, read, write
+    // attempt to perform all create, read, write, close operations
     psMetadataItem *item = NULL;
     psMetadataIterator *iter = psMetadataIteratorAlloc (files, PS_LIST_HEAD, NULL);
@@ -584,9 +608,9 @@
             if (!pmFPAfileRead (file, view, config)) {
                 psError(PS_ERR_IO, false, "failed READ in FPA_BEFORE block for %s", file->name);
-                status = false;
+                goto failure;
             }
             if (!pmFPAfileCreate(file, view)) {
                 psError(PS_ERR_IO, false, "failed CREATE in FPA_BEFORE block for %s", file->name);
-                status = false;
+                goto failure;
             }
             break;
@@ -594,9 +618,9 @@
             if (!pmFPAfileWrite (file, view, config)) {
                 psError(PS_ERR_IO, false, "failed WRITE in FPA_AFTER block for %s", file->name);
-                status = false;
+                goto failure;
             }
             if (!pmFPAfileClose(file, view)) {
                 psError(PS_ERR_IO, false, "failed CLOSE in FPA_AFTER block for %s", file->name);
-                status = false;
+                goto failure;
             }
             break;
@@ -617,5 +641,5 @@
             if (!pmFPAfileFreeData(file, view)) {
                 psError(PS_ERR_IO, false, "failed FREE in FPA_AFTER block for %s", file->name);
-                status = false;
+                goto failure;
             }
             break;
@@ -625,5 +649,9 @@
     }
     psFree (iter);
-    return status;
-}
-
+    return true;
+
+failure:
+    psFree (iter);
+    return false;
+}
+
