Index: trunk/psModules/src/camera/pmFPAConstruct.c
===================================================================
--- trunk/psModules/src/camera/pmFPAConstruct.c	(revision 7309)
+++ trunk/psModules/src/camera/pmFPAConstruct.c	(revision 7311)
@@ -26,6 +26,6 @@
     bool status = true;                 // Result of MD lookup
     psMetadata *cells = psMetadataLookupMD(&status, format, "CELLS"); // The CELLS
-    if (! status) {
-        psError(PS_ERR_IO, false, "Unable to determine CELLS of camera.\n");
+    if (!status || !cells) {
+        psError(PS_ERR_IO, true, "Unable to determine CELLS of camera.\n");
         return NULL;
     }
@@ -114,6 +114,6 @@
     }
     psMetadataItem *resultItem = psMetadataLookup(header, keyword);
-    if (! resultItem) {
-        psError(PS_ERR_IO, false, "Unable to find %s in primary header to identify %s.\n", keyword, name);
+    if (!resultItem) {
+        psError(PS_ERR_IO, true, "Unable to find %s in primary header to identify %s.\n", keyword, name);
         return NULL;
     }
@@ -138,5 +138,8 @@
     fpa->hdu = psMemIncrRefCounter(hdu);
     if (hdu->header) {
-        pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
+        if (!pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL)) {
+            psError(PS_ERR_UNKNOWN, false, "Failed to read concepts for FPA");
+            return false;
+        }
     }
     pmFPASetFileStatus(fpa, true);
@@ -256,5 +259,8 @@
 
     if (hdu && level == PM_FPA_LEVEL_FPA) {
-        addHDUtoFPA(fpa, hdu);
+        if (!addHDUtoFPA(fpa, hdu)) {
+            psError(PS_ERR_UNKNOWN, false, "Adding HDU to FPA (%s)", contents);
+            return -1;
+        }
     }
 
@@ -333,5 +339,8 @@
         }
         newCell->config = psMemIncrRefCounter(cellData);
-        pmConceptsReadCell(newCell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL);
+        if (!pmConceptsReadCell(newCell, PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, false, NULL)) {
+            psError(PS_ERR_IO, false, "Reading concepts for cell %d", numCells);
+            return -1;
+        }
         numCells++;
     }
@@ -388,4 +397,9 @@
     bool mdok = true;                   // Status from MD lookups
     psMetadata *components = psMetadataLookupMD(&mdok, camera, "FPA"); // FPA components
+    if (!mdok || !components) {
+        psError(PS_ERR_IO, true, "Failed to lookup \"FPA\"");
+        psFree(fpa);
+        return NULL;
+    }
     psMetadataIterator *componentsIter = psMetadataIteratorAlloc(components, PS_LIST_HEAD, NULL);
     psMetadataItem *componentsItem = NULL; // Item from components
@@ -500,5 +514,11 @@
         hdu->format = psMemIncrRefCounter(format);
         const char *content = contentsItem->data.V; // The content data
-        processContents(fpa, chip, cell, hdu, level, content, format);
+        if (processContents(fpa, chip, cell, hdu, level, content, format) < 0) {
+            psError(PS_ERR_IO, false, "Error setting contents for %s", contentsItem->name);
+            psFree(hdu);
+            psFree(contentsIter);
+
+            return false;
+        }
         psFree(hdu);
     }
@@ -568,9 +588,17 @@
         if (!mdok || !contents || strlen(contents) == 0) {
             psError(PS_ERR_IO, true, "Unable to find CONTENTS in the camera format configuration.\n");
+            psFree(phdu);
             psFree(view);
             return NULL;
         }
 
-        processContents(fpa, NULL, NULL, phdu, PM_FPA_LEVEL_FPA, contents, format);
+        if (processContents(fpa, NULL, NULL, phdu, PM_FPA_LEVEL_FPA, contents, format) < 0) {
+            psError(PS_ERR_IO, false, "Error setting CONTENTS");
+            psFree(phdu);
+            psFree(view);
+
+            return NULL;
+        }
+
         psFree(phdu);
         return view;
@@ -581,5 +609,14 @@
     psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file
     if (!mdok || !contents) {
-        psError(PS_ERR_IO, false, "Unable to find CONTENTS in the camera format configuration.\n");
+        if (mdok && !contents) {
+            psError(PS_ERR_IO, true, "CONTENTS metadata is NULL in the camera format configuration.");
+        } else {
+            if(psMetadataLookup(format, "CONTENTS") != NULL) {
+                psError(PS_ERR_IO, true, "CONTENTS is of wrong type in camera format configuration");
+            } else {
+                psError(PS_ERR_IO, true, "Unable to find CONTENTS in the camera format configuration.");
+            }
+        }
+
         psFree(view);
         return NULL;
Index: trunk/psModules/src/camera/pmFPARead.c
===================================================================
--- trunk/psModules/src/camera/pmFPARead.c	(revision 7309)
+++ trunk/psModules/src/camera/pmFPARead.c	(revision 7311)
@@ -35,5 +35,5 @@
     if (psRegionIsBad(*trimsec)) {
         psString regionString = psRegionToString(*trimsec);
-        psError(PS_ERR_IO, true, "Invalid trim section: %s\n", regionString);
+        psError(PS_ERR_UNKNOWN, true, "Invalid trim section: %s\n", regionString);
         psFree(regionString);
         psFree(readout);
@@ -319,9 +319,12 @@
     }
     if (!hdu->images && !pmHDURead(hdu, fits)) {
-        psError(PS_ERR_IO, false, "Unable to read HDU for cell.\n");
-        return false;
-    }
-
-    pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL);
+        psError(PS_ERR_UNKNOWN, false, "Unable to read HDU for cell.\n");
+        return false;
+    }
+
+    if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL)) {
+        psError(PS_ERR_UNKNOWN, false, "Failed to read concepts for cell");
+        return false;
+    }
 
     // Having read the cell, we now have to cut it up
@@ -397,5 +400,5 @@
         pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL);
     } else {
-        psLogMsg(__func__, PS_LOG_WARN, "Unable to read any chips in FPA.\n");
+        psError(PS_ERR_UNKNOWN, false, "Unable to read any chips in FPA");
     }
 
Index: trunk/psModules/src/camera/pmFPA_JPEG.c
===================================================================
--- trunk/psModules/src/camera/pmFPA_JPEG.c	(revision 7309)
+++ trunk/psModules/src/camera/pmFPA_JPEG.c	(revision 7311)
@@ -5,6 +5,6 @@
  *  @author EAM, IfA
  *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-06-02 00:55:22 $
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-06-03 01:02:08 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -141,5 +141,6 @@
 
         // XXX we need to decide where the scale will come from in the long term
-        psImageClippedStatsInit (10000);
+        unsigned long seed = 0;
+        psImageClippedStatsInit (10000, seed);
 
         psStats *stats = psImageClippedStats (readout->image, NULL, 0, 0.25, 0.75);
Index: trunk/psModules/src/camera/pmFPAfile.c
===================================================================
--- trunk/psModules/src/camera/pmFPAfile.c	(revision 7309)
+++ trunk/psModules/src/camera/pmFPAfile.c	(revision 7311)
@@ -21,4 +21,5 @@
 #include "pmPSF_IO.h"
 #include "pmFPA_JPEG.h"
+#define WERROR 0                        // if true, warnings in this file are treated as errors
 
 static void pmFPAfileFree(pmFPAfile *file)
@@ -84,4 +85,53 @@
     return file;
 }
+
+static const char *depthEnumToName(pmFPAdepth depth)
+{
+    const char *val = NULL;
+
+    switch (depth) {
+    case PM_FPA_DEPTH_NONE:
+        val = "NONE";
+        break;
+    case PM_FPA_DEPTH_FPA:
+        val = "FPA";
+        break;
+    case PM_FPA_DEPTH_CHIP:
+        val = "CHIP";
+        break;
+    case PM_FPA_DEPTH_CELL:
+        val = "CELL";
+        break;
+    case PM_FPA_DEPTH_READOUT:
+        val = "READOUT";
+        break;
+    default:
+        psAbort(PS_FILE_LINE, "You can't get here; depth = %d", depth);
+    }
+
+    return val;
+}
+
+static pmFPAdepth depthNameToEnum(const char *name)
+{
+    pmFPAdepth val;
+
+    if (name == NULL) {
+        val = PM_FPA_DEPTH_NONE;
+    } else if (!strcasecmp(name, "FPA"))     {
+        val = PM_FPA_DEPTH_FPA;
+    } else if (!strcasecmp(name, "CHIP"))    {
+        val = PM_FPA_DEPTH_CHIP;
+    } else if (!strcasecmp(name, "CELL"))    {
+        val = PM_FPA_DEPTH_CELL;
+    } else if (!strcasecmp(name, "READOUT")) {
+        val = PM_FPA_DEPTH_READOUT;
+    } else {
+        val = PM_FPA_DEPTH_NONE;
+    }
+
+    return val;
+}
+
 
 pmFPAfile *pmFPAfileDefine(psMetadata *files, psMetadata *camera, pmFPA *fpa, char *name)
@@ -94,5 +144,4 @@
 
     bool status;
-    char *depth;
     char *type;
 
@@ -100,5 +149,5 @@
     psMetadata *filerules = psMetadataLookupPtr (&status, camera, "FILERULES");
     if (filerules == NULL) {
-        psErrorStackPrint(stderr, "Can't find FILERULES in the CAMERA configuration!\n");
+        psError(PS_ERR_IO, true, "Can't find FILERULES in the CAMERA configuration!");
         return NULL;
     }
@@ -107,10 +156,11 @@
     // check for alias name (type == STR, name is aliased name)
     char *realname = psMetadataLookupStr (&status, filerules, name);
-    if (realname == NULL)
+    if (!realname || strlen(realname) == 0) {
         realname = name;
+    }
 
     psMetadata *data = psMetadataLookupPtr (&status, filerules, realname);
     if (data == NULL) {
-        psErrorStackPrint(stderr, "Can't find file concept %s!\n", name);
+        psError(PS_ERR_IO, true, "Can't find file concept %s!", name);
         return NULL;
     }
@@ -126,40 +176,10 @@
     file->extxtra  = psMemIncrRefCounter(psMetadataLookupStr (&status, data, "EXTNAME.XTRA"));
 
-    file->fileDepth = PM_FPA_DEPTH_NONE;
-    depth = psMetadataLookupStr (&status, data, "FILE.DEPTH");
-    if (depth != NULL) {
-        if (!strcasecmp (depth, "FPA"))     {
-            file->fileDepth = PM_FPA_DEPTH_FPA;
-        }
-        if (!strcasecmp (depth, "CHIP"))    {
-            file->fileDepth = PM_FPA_DEPTH_CHIP;
-        }
-        if (!strcasecmp (depth, "CELL"))    {
-            file->fileDepth = PM_FPA_DEPTH_CELL;
-        }
-        if (!strcasecmp (depth, "READOUT")) {
-            file->fileDepth = PM_FPA_DEPTH_READOUT;
-        }
-    }
+    file->fileDepth = depthNameToEnum(psMetadataLookupStr(&status, data, "FILE.DEPTH"));
     if (file->fileDepth == PM_FPA_DEPTH_NONE) {
         psLogMsg (__func__, 3, "warning: FILE.DEPTH is not set for %s\n", name);
     }
 
-    file->dataDepth = PM_FPA_DEPTH_NONE;
-    depth = psMetadataLookupStr (&status, data, "DATA.DEPTH");
-    if (depth != NULL) {
-        if (!strcasecmp (depth, "FPA"))     {
-            file->dataDepth = PM_FPA_DEPTH_FPA;
-        }
-        if (!strcasecmp (depth, "CHIP"))    {
-            file->dataDepth = PM_FPA_DEPTH_CHIP;
-        }
-        if (!strcasecmp (depth, "CELL"))    {
-            file->dataDepth = PM_FPA_DEPTH_CELL;
-        }
-        if (!strcasecmp (depth, "READOUT")) {
-            file->dataDepth = PM_FPA_DEPTH_READOUT;
-        }
-    }
+    file->dataDepth = depthNameToEnum(psMetadataLookupStr (&status, data, "DATA.DEPTH"));
     if (file->dataDepth == PM_FPA_DEPTH_NONE) {
         psLogMsg (__func__, 3, "warning: DATA.DEPTH is not set for %s\n", name);
@@ -240,4 +260,8 @@
     pmFPAfile *file = pmFPAfileDefine (files, format, fpa, name);
     psFree (fpa);
+    if (!file) {
+        psErrorStackPrint(stderr, "file %s not defined\n", name);
+        return NULL;
+    }
     return file;
 }
@@ -257,4 +281,5 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
+        psError(PS_ERR_IO, true, "Atempted to read an inactive file");
         return false;
     }
@@ -265,7 +290,9 @@
 
     if (file->mode == PM_FPA_MODE_NONE) {
+        psError(PS_ERR_IO, true, "File is mode PM_FPA_MODE_NONE");
         return false;
     }
     if (file->mode == PM_FPA_MODE_INTERNAL) {
+        psError(PS_ERR_IO, true, "File is mode PM_FPA_MODE_INTERNAL");
         return false;
     }
@@ -279,6 +306,8 @@
     // determine the file name
     file->filename = pmFPAfileNameFromRule (file->filerule, file, view);
-    if (file->filename == NULL)
-        return false;
+    if (file->filename == NULL) {
+        psError(PS_ERR_IO, true, "Filename is NULL");
+        return false;
+    }
 
     // indirect filenames
@@ -288,6 +317,7 @@
         file->filename = psMetadataLookupStr (&status, file->names, extra);
         psFree (extra);
-        if (file->filename == NULL)
+        if (file->filename == NULL) {
             psAbort ("pmFPAfile", "no file specified");
+        }
         // psMetadataLookupStr just returns a view, file->filename must be protected
         psMemIncrRefCounter (file->filename);
@@ -298,6 +328,7 @@
         // file->filename = pmDetrendSelect (extra);
         psFree (extra);
-        if (file->filename == NULL)
+        if (file->filename == NULL) {
             psAbort ("pmFPAfile", "no file specified");
+        }
         psMemIncrRefCounter (file->filename);
     }
@@ -309,6 +340,8 @@
         psTrace ("pmFPAfile", 5, "opening %s (type: %d)\n", file->filename, file->type);
         file->fits = psFitsOpen (file->filename, mode);
-        if (file->fits == NULL)
-            psAbort (__func__, "error opening file %s\n", file->filename);
+        if (file->fits == NULL) {
+            psError(PS_ERR_IO, false, "error opening file %s\n", file->filename);
+            return false;
+        }
         file->state = PM_FPA_STATE_OPEN;
         break;
@@ -325,5 +358,5 @@
 
     default:
-        fprintf (stderr, "warning: type mismatch for %s : %d\n", file->filename, file->type);
+        psError(PS_ERR_IO, true, "type mismatch for %s : %d\n", file->filename, file->type);
         return false;
     }
@@ -336,9 +369,13 @@
     PS_ASSERT_PTR_NON_NULL(view, false);
 
-    if (file->state & PM_FPA_STATE_INACTIVE)
-        return false;
-
-    if (file->mode != PM_FPA_MODE_READ)
-        return false;
+    if (file->state & PM_FPA_STATE_INACTIVE) {
+        psError(PS_ERR_IO, true, "Atempted to read an inactive file");
+        return false;
+    }
+
+    if (file->mode != PM_FPA_MODE_READ) {
+        psError(PS_ERR_IO, true, "File isn't mode PM_FPA_MODE_READ");
+        return false;
+    }
 
     // get the current depth
@@ -347,10 +384,22 @@
     // do we need to open this file?
     if (depth == file->fileDepth) {
-        pmFPAfileOpen (file, view);
+        if (!pmFPAfileOpen (file, view)) {
+            psError(PS_ERR_IO, false, "Opening file");
+            return false;
+        }
     }
 
     // do we need to read this file?
-    if (depth != file->dataDepth)
-        return false;
+    if (depth != file->dataDepth) {
+        #if WERROR
+        psError(PS_ERR_IO, true, "Desired depth %s doesn't match dataDepth %s",
+                depthEnumToName(depth), depthEnumToName(file->dataDepth));
+        return false;
+        #else
+
+        return true;
+        #endif
+
+    }
 
     switch (file->type) {
@@ -359,5 +408,6 @@
             psTrace ("pmFPAfile", 5, "reading %s (type: %d)\n", file->filename, file->type);
         } else {
-            psTrace ("pmFPAfile", 5, "skipping %s (type: %d)\n", file->filename, file->type);
+            psError(PS_ERR_UNKNOWN, false, "skipping %s (type: %d)\n", file->filename, file->type);
+            return false;
         }
         break;
@@ -381,5 +431,5 @@
 
     default:
-        fprintf (stderr, "warning: type mismatch\n");
+        psError(PS_ERR_IO, true, "warning: type mismatch; saw type %d", file->type);
         return false;
     }
@@ -393,8 +443,10 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
+        psError(PS_ERR_IO, true, "Atempted to write an inactive file");
         return false;
     }
 
     if (file->mode != PM_FPA_MODE_WRITE) {
+        psError(PS_ERR_IO, true, "File isn't mode PM_FPA_MODE_WRITE");
         return false;
     }
@@ -404,10 +456,22 @@
 
     // do we need to write this file?
-    if (depth != file->dataDepth)
-        return false;
+    if (depth != file->dataDepth) {
+        #if WERROR
+        psError(PS_ERR_IO, true, "Desired depth %s doesn't match dataDepth %s",
+                depthEnumToName(depth), depthEnumToName(file->dataDepth));
+        return false;
+        #else
+
+        return true;
+        #endif
+
+    }
 
     // do we need to open this file?
     if (depth >= file->fileDepth) {
-        pmFPAfileOpen (file, view);
+        if (!pmFPAfileOpen (file, view)) {
+            psError(PS_ERR_IO, false, "failed to open %s", file->filename);
+            return false;
+        }
     }
 
@@ -423,6 +487,10 @@
     case PM_FPA_FILE_CMP:
     case PM_FPA_FILE_CMF:
-        pmFPAviewWriteObjects (view, file);
-        psTrace ("pmFPAfile", 5, "wrote object %s (fpa: %p)\n", file->filename, file->fpa);
+        psTrace ("pmFPAfile", 5, "writing object %s (fpa: %p)\n", file->filename, file->fpa);
+        if (!pmFPAviewWriteObjects (view, file)) {
+            psError(PS_ERR_IO, false, "Failed to write object %s", file->filename);
+            return false;
+        }
+
         break;
 
@@ -451,19 +519,33 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
-        return false;
-    }
-    if (file->mode != PM_FPA_MODE_WRITE)
-        return false;
+        psError(PS_ERR_IO, true, "Atempted to create an inactive file");
+        return false;
+    }
+    if (file->mode != PM_FPA_MODE_WRITE) {
+        psError(PS_ERR_IO, true, "File isn't mode PM_FPA_MODE_WRITE");
+        return false;
+    }
 
     // get the current depth
     pmFPAdepth depth = pmFPAviewDepth (view);
 
+    // XXX is this a sufficient check to avoid creating elements?
+    if (file->src == NULL) {
+        #if WERROR
+        psError(PS_ERR_IO, true, "file->src is NULL");
+        return false;
+        #else
+
+        return true;
+        #endif
+
+    }
+
     // do we need to write this file?
-    if (depth != file->dataDepth)
-        return false;
-
-    // XXX is this a sufficient check to avoid creating elements?
-    if (file->src == NULL)
-        return false;
+    if (depth != file->dataDepth) {
+        psError(PS_ERR_IO, true, "Desired depth %s doesn't match dataDepth %s",
+                depthEnumToName(depth), depthEnumToName(file->dataDepth));
+        return false;
+    }
 
     switch (file->type) {
@@ -484,5 +566,5 @@
 
     default:
-        fprintf (stderr, "warning: type mismatch\n");
+        psError(PS_ERR_IO, true, "Unsupported type: %d", file->type);
         return false;
     }
@@ -496,4 +578,5 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
+        psError(PS_ERR_IO, true, "Atempted to close an inactive file");
         return false;
     }
@@ -505,5 +588,13 @@
     pmFPAdepth depth = pmFPAviewDepth (view);
     if (file->fileDepth != depth) {
-        return false;
+        #if WERROR
+        psError(PS_ERR_IO, true, "Desired depth %s doesn't match fileDepth %s",
+                depthEnumToName(depth), depthEnumToName(file->fileDepth));
+        return false;
+        #else
+
+        return true;
+        #endif
+
     }
 
@@ -531,5 +622,5 @@
 
     default:
-        fprintf (stderr, "warning: type mismatch\n");
+        psError(PS_ERR_IO, true, "type mismatch: %d", file->type);
         return false;
     }
@@ -560,5 +651,10 @@
     bool status = false;
     pmFPAfile *file = psMetadataLookupPtr (&status, files, name);
+    if (!status) {
+        psError(PS_ERR_IO, true, "Failed to look up file %s", name);
+        return false;
+    }
     if (!file) {
+        psError(PS_ERR_IO, true, "file %s is NULL", name);
         return false;
     }
@@ -583,13 +679,35 @@
         pmFPAfile *file = item->data.V;
 
-        if (place == PM_FPA_BEFORE) {
-            pmFPAfileRead (file, view);
-            pmFPAfileCreate (file, view);
-        } else {
-            pmFPAfileWrite (file, view);
-            pmFPAfileClose (file, view);
+        switch (place) {
+        case PM_FPA_BEFORE:
+            if (file->mode == PM_FPA_MODE_READ && !pmFPAfileRead (file, view)) {
+                psError(PS_ERR_IO, false, "failed in FPA_BEFORE block for %s", file->name);
+                psFree(iter);
+                return false;
+            }
+            if (file->mode == PM_FPA_MODE_WRITE && !pmFPAfileCreate(file, view)) {
+                psError(PS_ERR_IO, false, "failed in FPA_BEFORE block for %s", file->name);
+                psFree(iter);
+                return false;
+            }
+            break;
+        case PM_FPA_AFTER:
+            if (file->mode == PM_FPA_MODE_WRITE && !pmFPAfileWrite (file, view)) {
+                psError(PS_ERR_IO, false, "failed in FPA_AFTER block for %s", file->name);
+                psFree(iter);
+                return false;
+            }
+            if (!pmFPAfileClose(file, view)) {
+                psError(PS_ERR_IO, false, "failed in FPA_AFTER block for %s", file->name);
+                psFree(iter);
+                return false;
+            }
+            break;
+        default:
+            psAbort(PS_FILE_LINE, "You can't get here");
         }
     }
     psFree (iter);
+
     return true;
 }
@@ -627,9 +745,13 @@
 
     pmFPAfile *file = psMetadataLookupPtr (&status, files, name);
-    if (file == NULL)
-        return false;
-
-    if (file->mode != PM_FPA_MODE_INTERNAL)
-        return false;
+    if (file == NULL) {
+        psError(PS_ERR_IO, true, "Failed to lookup %s", name);
+        return false;
+    }
+
+    if (file->mode != PM_FPA_MODE_INTERNAL) {
+        psError(PS_ERR_IO, true, "File %s has mode %d != PM_FPA_MODE_INTERNAL", name, file->mode);
+        return false;
+    }
 
     psMetadataRemoveKey (files, name);
@@ -648,6 +770,7 @@
 
     pmFPAfile *file = psMetadataLookupPtr (&status, files, name);
-    if (file == NULL)
-        return NULL;
+    if (file == NULL) {
+        return NULL;
+    }
 
     // internal files have the readout as a separate element:
@@ -677,4 +800,5 @@
 
     if (view->chip >= fpa->chips->n) {
+        psError(PS_ERR_IO, true, "Requested chip == %d >= fpa->chips->n == %d", view->chip, fpa->chips->n);
         return false;
     }
@@ -687,4 +811,5 @@
 
     if (view->cell >= chip->cells->n) {
+        psError(PS_ERR_IO, true, "Requested cell == %d >= chip->cells->n == %d", view->cell, chip->cells->n);
         return false;
     }
@@ -695,12 +820,15 @@
         return status;
     }
+    psError(PS_ERR_UNKNOWN, true, "Returning false");
     return false;
 
     // XXX pmReadoutRead, pmReadoutReadSegement disabled for now
-    # if (0)
-
-        if (view->readout >= cell->readouts->n) {
-            return false;
-        }
+    #if 0
+
+    if (view->readout >= cell->readouts->n) {
+        psError(PS_ERR_IO, true, "Requested readout == %d >= cell->readouts->n == %d",
+                view->readout, cell->readouts->n);
+        return false;
+    }
     pmReadout *readout = cell->readouts->data[view->readout];
 
@@ -711,5 +839,5 @@
     }
     return true;
-    # endif
+    #endif
 }
 
@@ -731,4 +859,5 @@
 
     if (view->chip >= fpa->chips->n) {
+        psError(PS_ERR_IO, true, "Requested chip == %d >= fpa->chips->n == %d", view->chip, fpa->chips->n);
         return false;
     }
@@ -757,4 +886,5 @@
 
     if (view->cell >= chip->cells->n) {
+        psError(PS_ERR_IO, true, "Requested cell == %d >= chip->cells->n == %d", view->cell, chip->cells->n);
         return false;
     }
@@ -762,15 +892,17 @@
 
     if (view->readout == -1) {
-        pmCellWrite (cell, fits, NULL, true);
-        return true;
-    }
+        return pmCellWrite (cell, fits, NULL, true);
+    }
+    psError(PS_ERR_UNKNOWN, true, "Returning false");
     return false;
 
     // XXX disable readout write for now
-    # if (0)
-
-        if (view->readout >= cell->readouts->n) {
-            return false;
-        }
+    #if 0
+
+    if (view->readout >= cell->readouts->n) {
+        psError(PS_ERR_IO, true, "Requested readout == %d >= cell->readouts->n == %d",
+                view->readout, cell->readouts->n);
+        return false;
+    }
     pmReadout *readout = cell->readouts->data[view->readout];
 
@@ -781,5 +913,5 @@
     }
     return true;
-    # endif
+    #endif
 }
 
@@ -808,7 +940,9 @@
     psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
     if (!status) {
+        psError(PS_ERR_IO, false, "Failed to read %s from metadata\n", argname);
         return NULL;
     }
     if (infiles->n < 1) {
+        psError(PS_ERR_IO, false, "Found n == %d files in %s from metadata\n", infiles->n, argname);
         return NULL;
     }
@@ -819,8 +953,17 @@
     phu = psFitsReadHeader (NULL, fits);
     format = pmConfigCameraFormatFromHeader (config, phu);
-    psFitsClose (fits);
+    psFitsClose (fits);                        // don't close phu; we'll use it below
+    if (!format) {
+        psError(PS_ERR_IO, false, "Failed to read CCD format from %s\n", infiles->data[0]);
+        psFree(phu);
+        return NULL;
+    }
 
     // build the template fpa, set up the basic view
     fpa = pmFPAConstruct (config->camera);
+    if (!fpa) {
+        psError(PS_ERR_IO, false, "Failed to construct FPA from %s", infiles->data[0]);
+        return NULL;
+    }
 
     // load the given filerule (from config->camera) and associate it with the fpa
@@ -828,5 +971,6 @@
     file = pmFPAfileDefine (config->files, config->camera, fpa, filename);
     if (!file) {
-        psErrorStackPrint(stderr, "file %s not defined\n", filename);
+        psError(PS_ERR_IO, false, "file %s not defined", filename);
+        psFree(phu);
         psFree (fpa);
         psFree (format);
@@ -854,4 +998,11 @@
         // set the view to the corresponding entry for this phu
         pmFPAview *view = pmFPAAddSourceFromHeader (fpa, phu, format);
+        if (!view) {
+            psError(PS_ERR_IO, false, "Failed to set view from file %s", infiles->data[i]);
+            psFree(phu);
+            psFree (fpa);
+            psFree (format);
+            return NULL;
+        }
 
         // XXX is this the correct psMD to save the filename?
@@ -871,5 +1022,5 @@
 
 // XXX this this function through, then finish
-# if 0
+#if 0
 // look for the given name on the argument list.
 // returns the file (a view to the one saved on config->files)
@@ -925,5 +1076,5 @@
     file = pmFPAfileDefine (config->files, config->camera, fpa, filename);
     if (!file) {
-        psErrorStackPrint(stderr, "file %s not defined\n", filename);
+        psError(PS_ERR_IO, false, "file %s not defined", filename);
         psFree (fpa);
         psFree (format);
@@ -966,5 +1117,5 @@
     return file;
 }
-# endif
+#endif
 
 // create a new output pmFPAfile based on an existing FPA
@@ -979,4 +1130,8 @@
     pmFPA *fpa = pmFPAConstruct (config->camera);
     pmFPAfile *file = pmFPAfileDefine (config->files, config->camera, fpa, filename);
+    if (!file) {
+        psErrorStackPrint(stderr, "file %s not defined\n", filename);
+        return NULL;
+    }
     file->src = src; // inherit output elements from this source pmFPA
     file->xBin = xBin;
@@ -1014,5 +1169,5 @@
     file = pmFPAfileDefine (config->files, config->camera, NULL, filename);
     if (!file) {
-        psErrorStackPrint(stderr, "file %s not defined\n", filename);
+        psError(PS_ERR_IO, false, "file %s not defined\n", filename);
         return NULL;
     }
@@ -1120,4 +1275,10 @@
     newName = psStringCopy (rule);
 
+    if (strstr (newName, "{OUTPUT}") != NULL) {
+        char *name = psMetadataLookupStr (NULL, file->names, "OUTPUT");
+        if (name != NULL) {
+            newName = psStringSubstitute (newName, name, "{OUTPUT}");
+        }
+    }
     if (strstr (newName, "{CHIP.NAME}") != NULL) {
         pmChip *chip = pmFPAviewThisChip (view, file->fpa);
@@ -1144,10 +1305,4 @@
         }
     }
-    if (strstr (newName, "{OUTPUT}") != NULL) {
-        char *name = psMetadataLookupStr (NULL, file->names, "OUTPUT");
-        if (name != NULL) {
-            newName = psStringSubstitute (newName, name, "{OUTPUT}");
-        }
-    }
     return newName;
 }
@@ -1167,4 +1322,5 @@
     }
     if (view->chip >= in->chips->n) {
+        psError(PS_ERR_IO, true, "Requested chip == %d >= in->chips->n == %d", view->chip, in->chips->n);
         return false;
     }
@@ -1177,4 +1333,6 @@
     }
     if (view->cell >= inChip->cells->n) {
+        psError(PS_ERR_IO, true, "Requested cell == %d>= inChip->cells->n == %d",
+                view->cell, inChip->cells->n);
         return false;
     }
@@ -1186,4 +1344,5 @@
         return true;
     }
+    psError(PS_ERR_UNKNOWN, true, "Returning false");
     return false;
 
@@ -1203,8 +1362,8 @@
     if (view->chip == -1) {
         pmFPAAddSourceFromView (out, view, format);
-        pmFPACopyStructure (out, in, xBin, yBin);
-        return true;
+        return pmFPACopyStructure (out, in, xBin, yBin);
     }
     if (view->chip >= in->chips->n) {
+        psError(PS_ERR_IO, true, "Requested chip == %d >= in->chips->n == %d", view->chip, in->chips->n);
         return false;
     }
@@ -1214,8 +1373,9 @@
     if (view->cell == -1) {
         pmFPAAddSourceFromView (out, view, format);
-        pmChipCopyStructure (outChip, inChip, xBin, yBin);
-        return true;
+        return pmChipCopyStructure (outChip, inChip, xBin, yBin);
     }
     if (view->cell >= inChip->cells->n) {
+        psError(PS_ERR_IO, true, "Requested cell == %d>= inChip->cells->n == %d",
+                view->cell, inChip->cells->n);
         return false;
     }
@@ -1225,7 +1385,7 @@
     if (view->readout == -1) {
         pmFPAAddSourceFromView (out, view, format);
-        pmCellCopyStructure (outCell, inCell, xBin, yBin);
-        return true;
-    }
+        return pmCellCopyStructure (outCell, inCell, xBin, yBin);
+    }
+    psError(PS_ERR_UNKNOWN, true, "Returning false");
     return false;
 
Index: trunk/psModules/src/camera/pmReadout.c
===================================================================
--- trunk/psModules/src/camera/pmReadout.c	(revision 7309)
+++ trunk/psModules/src/camera/pmReadout.c	(revision 7311)
@@ -76,4 +76,8 @@
             readout->mask = psMemIncrRefCounter(psImageSubset(masks->data[i], *trimsec));
         }
+        if (readout->weight == NULL || readout->mask == NULL) {
+            psError(PS_ERR_UNKNOWN, false, "Trimming readout %d", i);
+            return false;
+        }
 
         // Set up the mask
