Index: /trunk/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 12680)
+++ /trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 12681)
@@ -778,15 +778,22 @@
     // XXX use PPIMAGE or DETREND for the recipe name?
     psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, "PPIMAGE");
-    if (!status)
-        psAbort("PPIMAGE recipe not found");
+    if (!status) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "PPIMAGE recipe not found.");
+        psFree(options);
+        psFree(fpa);
+        retrun false;
+    }
     psMetadata *detConstraints = psMetadataLookupPtr (&status, recipe, "DETREND.CONSTRAINTS");
-    if (!status)
-        psAbort("DETREND.CONSTRAINTS not found");
-    // XXX allow this and just skip?
+    if (!status) {
+        psWarning("DETREND.CONSTRAINTS not found --- no constraints will be applied.");
+        goto DETREND_SELECT;
+    }
 
     psString typeName = pmDetrendTypeToString (type);
     psMetadata *constraints = psMetadataLookupPtr (&status, detConstraints, typeName);
     if (!status) {
-        psAbort("DETREND.CONSTRAINTS for type %s not found", typeName);
+        psWarning("DETREND.CONSTRAINTS for type %s not found --- no contraints will be applied.", typeName);
+        psFree(typeName);
+        goto DETREND_SELECT;
     }
     psFree(typeName);
@@ -797,5 +804,6 @@
     while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
         if (item->type != PS_DATA_STRING) {
-            psAbort("invalid type for DETREND.CONSTRAINT element");
+            psWarning("Invalid type for DETREND.CONSTRAINT element %s --- ignoring constraint", item->name);
+            continue;
         }
         char *option  = item->name;     // item->name must correspond to a valid detselect option
@@ -809,25 +817,20 @@
             if (!status)
                 psAbort("failed to find filter (concept %s)", concept);
-
-        }
-        if (!strcasecmp (option, "exptime")) {
+        } else if (!strcasecmp (option, "exptime")) {
             options->exptime = psMetadataLookupF32 (&status, input->concepts, concept);
             options->exptimeSet = true;
             if (!status)
                 psAbort("exptime not found (concept %s)", concept);
-        }
-        if (!strcasecmp (option, "airmass")) {
+        } else if (!strcasecmp (option, "airmass")) {
             options->airmass = psMetadataLookupF32 (&status, input->concepts, concept);
             options->airmassSet = true;
             if (!status)
                 psAbort("airmass not found (concept %s)", concept);
-        }
-        if (!strcasecmp (option, "dettemp")) {
+        } else if (!strcasecmp (option, "dettemp")) {
             options->dettemp = psMetadataLookupF32 (&status, input->concepts, concept);
             options->dettempSet = true;
             if (!status)
                 psAbort("dettemp not found (concept %s)", concept);
-        }
-        if (!strcasecmp (option, "twilight")) {
+        } else if (!strcasecmp (option, "twilight")) {
             options->twilight = psMetadataLookupF32 (&status, input->concepts, concept);
             options->twilightSet = true;
@@ -849,4 +852,6 @@
     psFree(iter);
 
+DETREND_SELECT:
+
     // search for existing detrend data (detID)
     pmDetrendSelectResults *results = pmDetrendSelect (options, config);
@@ -859,6 +864,7 @@
     psFree (options);
 
-    if (found)
+    if (found) {
         *found = true;
+    }
     return file;
 }
@@ -930,5 +936,5 @@
 
     if (config->cameraName[0] == '_' &&
-	strcmp(config->cameraName + strlen(config->cameraName) - 5, "-CHIP") == 0) {
+        strcmp(config->cameraName + strlen(config->cameraName) - 5, "-CHIP") == 0) {
         // The input camera has already been mosaicked to this level
         pmFPAfile *file = pmFPAfileDefineOutput(config, NULL, filename);
