Index: /trunk/psModules/src/camera/pmFPAMosaic.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAMosaic.c	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAMosaic.c	(revision 10966)
@@ -1045,8 +1045,7 @@
     psFree(chipRegion);
 
-    // Currently, there's nothing interesting in the chip concepts that needs to be updated.
-
-    // Copy the concepts for the target FPA
-    target->parent->concepts = psMetadataCopy(target->parent->concepts, source->parent->concepts);
+    // Copy the concepts
+    target->concepts = psMetadataCopy(target->concepts, source->concepts); // Chip level
+    target->parent->concepts = psMetadataCopy(target->parent->concepts, source->parent->concepts); // FPA lvl
 
     // Now make a new readout to go in the target cell
Index: /trunk/psModules/src/camera/pmFPAWrite.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAWrite.c	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAWrite.c	(revision 10966)
@@ -141,5 +141,5 @@
         pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CELLS |
                                  PM_CONCEPT_SOURCE_DEFAULTS;
-        if (!pmConceptsWriteCell(cell, source, false, NULL)) {
+        if (!pmConceptsWriteCell(cell, source, true, NULL)) {
             psError(PS_ERR_IO, false, "Unable to write concepts for cell.\n");
             return false;
@@ -191,5 +191,5 @@
             pmConceptSource source = PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CELLS |
                                      PM_CONCEPT_SOURCE_DEFAULTS;
-            if (!pmConceptsWriteChip(chip, source, false, true, NULL)) {
+            if (!pmConceptsWriteChip(chip, source, true, true, NULL)) {
                 psError(PS_ERR_IO, false, "Unable to write concepts for chip.\n");
                 return false;
Index: /trunk/psModules/src/camera/pmFPAfile.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAfile.c	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAfile.c	(revision 10966)
@@ -66,4 +66,9 @@
     file->header = NULL;
 
+    file->fileLevel = PM_FPA_LEVEL_NONE;
+    file->dataLevel = PM_FPA_LEVEL_NONE;
+    file->freeLevel = PM_FPA_LEVEL_NONE;
+    file->mosaicLevel = PM_FPA_LEVEL_NONE;
+
     file->fpa = NULL;
     file->fits = NULL;
Index: /trunk/psModules/src/camera/pmFPAfile.h
===================================================================
--- /trunk/psModules/src/camera/pmFPAfile.h	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAfile.h	(revision 10966)
@@ -7,6 +7,6 @@
 *  @author EAM, IfA
 *
-*  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2007-01-05 20:17:21 $
+*  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2007-01-08 22:30:21 $
 *
 *  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
@@ -63,7 +63,9 @@
     pmFPAfileState state;  // have we opened the file, etc?
 
+    // Desired levels, set by the user
     pmFPALevel fileLevel;  // what level in the FPA hierarchy represents a unique file?
     pmFPALevel dataLevel;  // at what level do we read/write the data segment?
     pmFPALevel freeLevel;  // at what level do we free the data segment?
+    pmFPALevel mosaicLevel;             // at what level is the mosaic?
 
     pmFPA *fpa;    // for I/O files, we carry a pointer to the complete fpa
Index: /trunk/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 10966)
@@ -30,11 +30,10 @@
 
 // define an input-type pmFPAfile, bind to the optional fpa if supplied
-pmFPAfile *pmFPAfileDefineInput(pmConfig *config, pmFPA *fpa, char *name)
+pmFPAfile *pmFPAfileDefineInput(pmConfig *config, pmFPA *fpa, const char *name)
 {
     PS_ASSERT_PTR_NON_NULL(config, NULL);
     PS_ASSERT_PTR_NON_NULL(config->files, NULL);
     PS_ASSERT_PTR_NON_NULL(config->camera, NULL);
-    PS_ASSERT_PTR_NON_NULL(name, NULL);
-    PS_ASSERT_INT_POSITIVE(strlen(name), NULL);
+    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
 
     bool status;
@@ -50,5 +49,5 @@
     // select the name from the FILERULES
     // check for alias name (type == STR, name is aliased name)
-    char *realname = psMetadataLookupStr (&status, filerules, name);
+    const char *realname = psMetadataLookupStr (&status, filerules, name);
     if (!realname || strlen(realname) == 0) {
         realname = name;
@@ -107,14 +106,12 @@
 
 // define a pmFPAfile, bind to the optional fpa if supplied
-pmFPAfile *pmFPAfileDefineOutput(pmConfig *config, pmFPA *fpa, char *name)
+pmFPAfile *pmFPAfileDefineOutput(pmConfig *config, pmFPA *fpa, const char *name)
 {
     PS_ASSERT_PTR_NON_NULL(config, NULL);
     PS_ASSERT_PTR_NON_NULL(config->files, NULL);
     PS_ASSERT_PTR_NON_NULL(config->camera, NULL);
-    PS_ASSERT_PTR_NON_NULL(name, NULL);
-    PS_ASSERT_INT_POSITIVE(strlen(name), NULL);
+    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
 
     bool status;
-    char *type;
 
     // select the FILERULES from the camera config
@@ -127,5 +124,5 @@
     // select the name from the FILERULES
     // check for alias name (type == STR, name is aliased name)
-    char *realname = psMetadataLookupStr (&status, filerules, name);
+    const char *realname = psMetadataLookupStr (&status, filerules, name);
     if (!realname || strlen(realname) == 0) {
         realname = name;
@@ -148,5 +145,5 @@
     file->extxtra  = psMemIncrRefCounter(psMetadataLookupStr (&status, data, "EXTNAME.XTRA"));
 
-    type = psMetadataLookupStr (&status, data, "FILE.TYPE");
+    const char *type = psMetadataLookupStr (&status, data, "FILE.TYPE");
     file->type = pmFPAfileTypeFromString(type);
     if (file->type == PM_FPA_FILE_NONE) {
@@ -188,4 +185,5 @@
     }
 
+    #if 0
     // for WRITE type of data, the output format needs to be determined
     // this is only needed if the output file is not identical in structure to the input?
@@ -231,4 +229,5 @@
         psFree (words);
     }
+    #endif
 
     // add argument-supplied OUTPUT name to this file
@@ -248,11 +247,9 @@
 // save the pmFPAfile on config->files
 // return the pmFPAfile (a view to the one saved on config->files)
-pmFPAfile *pmFPAfileDefineFromArgs (bool *found, pmConfig *config, char *filename, char *argname)
+pmFPAfile *pmFPAfileDefineFromArgs (bool *found, pmConfig *config, const char *filename, const char *argname)
 {
     PS_ASSERT_PTR_NON_NULL(config, NULL);
-    PS_ASSERT_PTR_NON_NULL(filename, NULL);
-    PS_ASSERT_INT_POSITIVE(strlen(filename), NULL);
-    PS_ASSERT_PTR_NON_NULL(argname, NULL);
-    PS_ASSERT_INT_POSITIVE(strlen(argname), NULL);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(argname, NULL);
 
     bool status;
@@ -269,5 +266,6 @@
     psArray *infiles = psMetadataLookupPtr(&status, config->arguments, argname);
     if (!status) {
-        psTrace("psModules.camera", 5, "Failed to find %s in argument list", argname);
+        //        psTrace("psModules.camera", 5, "Failed to find %s in argument list", argname);
+        psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to find %s in argument list", argname);
         return NULL;
     }
@@ -296,5 +294,5 @@
         return NULL;
     }
-    psFitsClose (fits);
+    psFitsClose(fits);
 
     // determine the current format from the header
@@ -417,11 +415,10 @@
 // save the pmFPAfiles on config->files
 // return the pmFPAfiles (a view to the one saved on config->files)
-pmFPAfile *pmFPAfileDefineSingleFromArgs (bool *found, pmConfig *config, char *filename, char *argname, int entry)
+pmFPAfile *pmFPAfileDefineSingleFromArgs (bool *found, pmConfig *config, const char *filename,
+        const char *argname, int entry)
 {
     PS_ASSERT_PTR_NON_NULL(config, NULL);
-    PS_ASSERT_PTR_NON_NULL(filename, NULL);
-    PS_ASSERT_INT_POSITIVE(strlen(filename), NULL);
-    PS_ASSERT_PTR_NON_NULL(argname, NULL);
-    PS_ASSERT_INT_POSITIVE(strlen(argname), NULL);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(argname, NULL);
 
     bool status;
@@ -533,9 +530,8 @@
 // define the named pmFPAfile from the camera->config
 // only valid for pmFPAfile->mode = READ
-pmFPAfile *pmFPAfileDefineFromConf (bool *found, pmConfig *config, char *filename)
+pmFPAfile *pmFPAfileDefineFromConf (bool *found, pmConfig *config, const char *filename)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
-    PS_ASSERT_PTR_NON_NULL(filename, false);
-    PS_ASSERT_INT_POSITIVE(strlen(filename), false);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
 
     if (*found) {
@@ -603,5 +599,6 @@
 // save the pmFPAfile on config->files
 // return the pmFPAfile (a view to the one saved on config->files)
-pmFPAfile *pmFPAfileDefineFromDetDB (bool *found, pmConfig *config, char *filename, pmFPA *input, pmDetrendType type)
+pmFPAfile *pmFPAfileDefineFromDetDB (bool *found, pmConfig *config, const char *filename,
+                                     pmFPA *input, pmDetrendType type)
 {
     PS_ASSERT_PTR_NON_NULL(input, NULL);
@@ -609,5 +606,5 @@
     PS_ASSERT_PTR_NON_NULL(config->camera, NULL);
     PS_ASSERT_PTR_NON_NULL(config->files, NULL);
-    PS_ASSERT_PTR_NON_NULL(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
 
     pmFPA *fpa = NULL;
@@ -681,12 +678,26 @@
 // create a new output pmFPAfile based on an existing FPA
 // only valid for pmFPAfile->mode == WRITE (or internal?)
-pmFPAfile *pmFPAfileDefineFromFPA (pmConfig *config, pmFPA *src, int xBin, int yBin, char *filename)
+pmFPAfile *pmFPAfileDefineFromFPA (pmConfig *config, pmFPA *src, int xBin, int yBin, const char *filename)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
     PS_ASSERT_PTR_NON_NULL(src, false);
-    PS_ASSERT_PTR_NON_NULL(filename, false);
-    PS_ASSERT_INT_POSITIVE(strlen(filename), false);
-
-    pmFPA *fpa = pmFPAConstruct (src->camera);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+
+    // Need to look up the format
+    bool mdok;                          // Status of MD lookup
+    psMetadata *formats = psMetadataLookupMetadata(&mdok, src->camera, "FORMATS"); // The FORMATS
+    if (!mdok || !formats) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FORMATS in camera configuration %s.\n",
+                config->cameraName);
+        return NULL;
+    }
+    psMetadata *format = psMetadataLookupMetadata(&mdok, formats, config->formatName); // The format
+    if (!mdok || !format) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find camera format %s within camera %s.\n",
+                config->formatName, config->cameraName);
+        return NULL;
+    }
+
+    pmFPA *fpa = pmFPAConstruct(src->camera);
     pmFPAfile *file = pmFPAfileDefineOutput (config, fpa, filename);
     if (!file) {
@@ -697,4 +708,5 @@
     file->xBin = xBin;
     file->yBin = yBin;
+    file->format = psMemIncrRefCounter(format);
 
     psFree (fpa);
@@ -704,9 +716,8 @@
 // create a new output pmFPAfile based on an existing FPA
 // only valid for pmFPAfile->mode == WRITE (or internal?)
-pmFPAfile *pmFPAfileDefineNewCamera (pmConfig *config, char *filename)
+pmFPAfile *pmFPAfileDefineNewCamera (pmConfig *config, const char *filename)
 {
     PS_ASSERT_PTR_NON_NULL(config, false);
-    PS_ASSERT_PTR_NON_NULL(filename, false);
-    PS_ASSERT_INT_POSITIVE(strlen(filename), false);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
 
     pmFPAfile *file = pmFPAfileDefineOutput (config, NULL, filename);
@@ -724,11 +735,156 @@
 }
 
+pmFPAfile *pmFPAfileDefineChipMosaic(pmConfig *config, pmFPA *src, const char *filename)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(src, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(config->cameraName, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(config->formatName, NULL);
+
+    if (config->cameraName[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);
+        file->camera = psMemIncrRefCounter(config->camera);
+        file->format = psMemIncrRefCounter(config->format);
+        file->fpa = pmFPAConstruct(file->camera);
+        return file;
+    }
+
+    // Find the correct camera configuration
+    bool mdok;                          // Status of MD lookup
+    psMetadata *cameras = psMetadataLookupMetadata(&mdok, config->site, "CAMERAS"); // Camera configurations
+    if (!mdok || !cameras) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find CAMERAS in the site configuration.\n");
+        return NULL;
+    }
+    psString name = NULL;               // Name of the new (automatically-generated) camera configuration
+    psStringAppend(&name, "_%s-CHIP", config->cameraName);
+    psMetadata *camera = psMetadataLookupMetadata(&mdok, cameras, name); // Camera configuration of interest
+    if (!mdok || !camera) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find automatically generated "
+                "camera configuration %s in site configuration.\n", name);
+        psFree(name);
+        return NULL;
+    }
+    psFree(name);
+
+    // Need to look up the format of the same name, but under the mosaic camera
+    psMetadata *formats = psMetadataLookupMetadata(&mdok, camera, "FORMATS"); // The FORMATS
+    if (!mdok || !formats) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FORMATS in camera configuration %s.\n",
+                config->cameraName);
+        return NULL;
+    }
+    psMetadata *format = psMetadataLookupMetadata(&mdok, formats, config->formatName); // The format
+    if (!mdok || !format) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find camera format %s within camera %s.\n",
+                config->formatName, config->cameraName);
+        return NULL;
+    }
+
+    pmFPA *fpa = pmFPAConstruct(camera);
+    if (!fpa) {
+        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate mosaicked camera.\n");
+        return NULL;
+    }
+    pmFPAfile *file = pmFPAfileDefineOutput(config, 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->mosaicLevel = PM_FPA_LEVEL_CHIP; // don't do any I/O on this at a lower level
+    file->format = psMemIncrRefCounter(format);
+
+    psFree(fpa);
+
+    return file;
+}
+
+pmFPAfile *pmFPAfileDefineFPAMosaic(pmConfig *config, pmFPA *src, const char *filename)
+{
+    PS_ASSERT_PTR_NON_NULL(config, NULL);
+    PS_ASSERT_PTR_NON_NULL(src, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(config->cameraName, NULL);
+
+    if (config->cameraName[0] == '_' &&
+            strcmp(config->cameraName + strlen(config->cameraName) - 4 , "-FPA") == 0) {
+        // The input camera has already been mosaicked to this level
+        pmFPAfile *file = pmFPAfileDefineOutput(config, NULL, filename);
+        file->camera = psMemIncrRefCounter(config->camera);
+        file->format = psMemIncrRefCounter(config->format);
+        file->fpa = pmFPAConstruct(file->camera);
+        return file;
+    }
+
+    // Find the correct camera configuration
+    bool mdok;                          // Status of MD lookup
+    psMetadata *cameras = psMetadataLookupMetadata(&mdok, config->site, "CAMERAS"); // Camera configurations
+    if (!mdok || !cameras) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find CAMERAS in the site configuration.\n");
+        return NULL;
+    }
+    psString original;                  // Name of the original camera configuration
+    psString name = NULL;               // Name of the new (automatically-generated) camera configuration
+    if (config->cameraName[0] == '_' &&
+            strcmp(config->cameraName + strlen(config->cameraName) - 5 , "-CHIP") == 0) {
+        // It's a chip mosaic; we need to get the original name
+        original = psStringNCopy(config->cameraName + 1, strlen(config->cameraName) - 6);
+    } else {
+        original = psMemIncrRefCounter(config->cameraName);
+    }
+    psStringAppend(&name, "_%s-FPA", original);
+    psFree(original);
+    psMetadata *camera = psMetadataLookupMetadata(&mdok, cameras, name); // Camera configuration of interest
+    if (!mdok || !camera) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find automatically generated "
+                "camera configuration %s in site configuration.\n", name);
+        psFree(name);
+        return NULL;
+    }
+    psFree(name);
+
+    // Need to look up the format of the same name, but under the mosaic camera
+    psMetadata *formats = psMetadataLookupMetadata(&mdok, camera, "FORMATS"); // The FORMATS
+    if (!mdok || !formats) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FORMATS in camera configuration %s.\n",
+                config->cameraName);
+        return NULL;
+    }
+    psMetadata *format = psMetadataLookupMetadata(&mdok, formats, config->formatName); // The format
+    if (!mdok || !format) {
+        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find camera format %s within camera %s.\n",
+                config->formatName, config->cameraName);
+        return NULL;
+    }
+
+    pmFPA *fpa = pmFPAConstruct(camera);
+    if (!fpa) {
+        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate mosaicked camera.\n");
+        return NULL;
+    }
+    pmFPAfile *file = pmFPAfileDefineOutput(config, 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->mosaicLevel = PM_FPA_LEVEL_FPA; // don't do any I/O on this at a lower level
+    file->format = psMemIncrRefCounter(format);
+
+    psFree(fpa);
+
+    return file;
+}
+
 // create a file with the given name, assign it type "INTERNAL", and supply it with an image
 // of the requested dimensions. (image only, mask and weight are ignored)
-pmReadout *pmFPAfileDefineInternal (psMetadata *files, char *name, int Nx, int Ny, int type)
+pmReadout *pmFPAfileDefineInternal (psMetadata *files, const char *name, int Nx, int Ny, int type)
 {
     PS_ASSERT_PTR_NON_NULL(files, false);
-    PS_ASSERT_PTR_NON_NULL(name, false);
-    PS_ASSERT_INT_POSITIVE(strlen(name), false);
+    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
 
     pmReadout *readout = pmReadoutAlloc(NULL);
@@ -748,9 +904,8 @@
 }
 
-bool pmFPAfileDropInternal(psMetadata *files, char *name)
+bool pmFPAfileDropInternal(psMetadata *files, const char *name)
 {
     PS_ASSERT_PTR_NON_NULL(files, false);
-    PS_ASSERT_PTR_NON_NULL(name, false);
-    PS_ASSERT_INT_POSITIVE(strlen(name), false);
+    PS_ASSERT_STRING_NON_EMPTY(name, NULL);
 
     bool status = false;
Index: /trunk/psModules/src/camera/pmFPAfileDefine.h
===================================================================
--- /trunk/psModules/src/camera/pmFPAfileDefine.h	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAfileDefine.h	(revision 10966)
@@ -7,6 +7,6 @@
 *  @author EAM, IfA
 *
-*  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-11-19 01:55:24 $
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2007-01-08 22:30:21 $
 *
 *  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
@@ -22,5 +22,5 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineInput (pmConfig *config, pmFPA *fpa, char *name);
+pmFPAfile *pmFPAfileDefineInput (pmConfig *config, pmFPA *fpa, const char *name);
 
 // load the pmFPAfile information from the camera configuration data
@@ -28,5 +28,5 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineOutput (pmConfig *config, pmFPA *fpa, char *name);
+pmFPAfile *pmFPAfileDefineOutput (pmConfig *config, pmFPA *fpa, const char *name);
 
 // look for the given argname on the argument list.  find the give filename from the file rules
@@ -34,5 +34,5 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineFromArgs (bool *found, pmConfig *config, char *filename, char *argname);
+pmFPAfile *pmFPAfileDefineFromArgs (bool *found, pmConfig *config, const char *filename, const char *argname);
 
 // look for the given argname on the argument list.  find the give filename from the file rules
@@ -40,5 +40,5 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineFromConf (bool *found, pmConfig *config, char *filename);
+pmFPAfile *pmFPAfileDefineFromConf (bool *found, pmConfig *config, const char *filename);
 
 // look for the given argname on the argument list.  find the give filename from the file rules
@@ -46,5 +46,6 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineFromDetDB (bool *found, pmConfig *config, char *filename, pmFPA *input, pmDetrendType type);
+pmFPAfile *pmFPAfileDefineFromDetDB (bool *found, pmConfig *config, const char *filename,
+                                     pmFPA *input, pmDetrendType type);
 
 // create a new output pmFPAfile based on an existing FPA
@@ -52,5 +53,5 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineFromFPA (pmConfig *config, pmFPA *src, int xBin, int yBin, char *filename);
+pmFPAfile *pmFPAfileDefineFromFPA (pmConfig *config, pmFPA *src, int xBin, int yBin, const char *filename);
 
 // create a new output pmFPAfile based on an existing FPA
@@ -59,12 +60,30 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineNewCamera (pmConfig *config, char *filename);
+pmFPAfile *pmFPAfileDefineNewCamera (pmConfig *config, const char *filename);
+
+/// Create a new output pmFPAfile based upon a chip mosaic of an existing FPA
+///
+/// The new pmFPAfile is inserted into the config->files metadata, freed and returned; so that the user does
+/// not have to (and should not!) free the result.
+pmFPAfile *pmFPAfileDefineChipMosaic(pmConfig *config, ///< Configuration data
+                                     pmFPA *src, ///< Source FPA
+                                     const char *filename ///< Output (root) filename
+                                    );
+
+/// Create a new output pmFPAfile based upon an FPA mosaic of an existing FPA
+///
+/// The new pmFPAfile is inserted into the config->files metadata, freed and returned; so that the user does
+/// not have to (and should not!) free the result.
+pmFPAfile *pmFPAfileDefineFPAMosaic(pmConfig *config, ///< Configuration data
+                                    pmFPA *src, ///< Source FPA
+                                    const char *filename ///< Output (root) filename
+                                   );
 
 // create a file with the given name, assign it type "INTERNAL", and supply it with an image
 // of the requested dimensions. (image only, mask and weight are ignored)
-pmReadout *pmFPAfileDefineInternal (psMetadata *files, char *name, int Nx, int Ny, int type);
+pmReadout *pmFPAfileDefineInternal (psMetadata *files, const char *name, int Nx, int Ny, int type);
 
 // delete the INTERNAL file of the given name (if it exists)
-bool pmFPAfileDropInternal (psMetadata *files, char *name);
+bool pmFPAfileDropInternal (psMetadata *files, const char *name);
 
 // look for the given argname on the argument list.  find the give filename from the file rules
@@ -72,4 +91,6 @@
 // Note that the returned pmFPAfile is a view only, so it should not be freed by the caller --- the only
 // reference count is held by the config->files metadata.
-pmFPAfile *pmFPAfileDefineSingleFromArgs (bool *found, pmConfig *config, char *filename, char *argname, int entry);
+pmFPAfile *pmFPAfileDefineSingleFromArgs (bool *found, pmConfig *config, const char *filename,
+        const char *argname, int entry);
+
 # endif
Index: /trunk/psModules/src/camera/pmFPAfileIO.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAfileIO.c	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAfileIO.c	(revision 10966)
@@ -465,5 +465,6 @@
 
     // do we need to write this file?
-    if (level != file->dataLevel) {
+    if ((file->mosaicLevel == PM_FPA_LEVEL_NONE && level != file->dataLevel) || // No mosaicking happening
+            (file->mosaicLevel != PM_FPA_LEVEL_NONE && level != file->mosaicLevel)) { // Mosaicking happening
         psTrace("psModules.camera", 6, "skip writing of %s at this level %s: dataLevel is %s",
                 file->name, pmFPALevelToName(level), pmFPALevelToName(file->dataLevel));
@@ -472,5 +473,7 @@
 
     // do we need to open this file?
-    if (level >= file->fileLevel) {
+    if (level >= file->fileLevel &&
+            (file->mosaicLevel == PM_FPA_LEVEL_NONE ||
+             (file->mosaicLevel != PM_FPA_LEVEL_NONE && level >= file->mosaicLevel))) {
         if (!pmFPAfileOpen (file, view, config)) {
             psError(PS_ERR_IO, false, "failed to open %s", file->filename);
@@ -540,5 +543,5 @@
 
 // create the data elements (headers, images) appropriate for this view
-bool pmFPAfileCreate (pmFPAfile *file, const pmFPAview *view)
+bool pmFPAfileCreate (pmFPAfile *file, const pmFPAview *view, const pmConfig *config)
 {
     PS_ASSERT_PTR_NON_NULL(file, false);
@@ -571,5 +574,5 @@
 
     // do we need to write this file?
-    if (level != file->fileLevel) {
+    if (level != file->fileLevel || file->mosaicLevel != PM_FPA_LEVEL_NONE) {
         psTrace("psModules.camera", 6, "skip creation of %s at this level %s: fileLevel is %s",
                 file->name, pmFPALevelToName(level), pmFPALevelToName(file->fileLevel));
@@ -581,10 +584,29 @@
     case PM_FPA_FILE_MASK:
     case PM_FPA_FILE_WEIGHT:
-    case PM_FPA_FILE_FRINGE:
-        // create FPA structure component based on view
-        pmFPAAddSourceFromView (file->fpa, view, file->format);
-        psTrace ("pmFPAfile", 5, "created fpa data elements for %s (fpa: %p)\n", file->name, file->fpa);
-        break;
-
+    case PM_FPA_FILE_FRINGE: {
+            // create FPA structure component based on view
+            #if 0
+            psMetadata *format = file->format; // Camera format configuration
+            if (!format) {
+                // It's likely a mosaic, for which we don't yet know the appropriate format
+                const psMetadata *camera = file->fpa->camera; // Camera configuration
+                psMetadata *formats = psMetadataLookupMetadata(NULL, camera, "FORMATS"); // The FORMATS
+                if (!formats) {
+                    psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find FORMATS in camera configuration.\n");
+                    return false;
+                }
+                format = psMetadataLookupMetadata(NULL, formats, config->formatName);
+                if (!format) {
+                    psError(PS_ERR_UNEXPECTED_NULL, false,
+                            "Unable to find format %s in camera configuration.\n", config->formatName);
+                    return false;
+                }
+                file->format = psMemIncrRefCounter(format);
+            }
+            #endif
+            pmFPAAddSourceFromView (file->fpa, view, file->format);
+            psTrace ("pmFPAfile", 5, "created fpa data elements for %s (fpa: %p)\n", file->name, file->fpa);
+            break;
+        }
     case PM_FPA_FILE_SX:
     case PM_FPA_FILE_RAW:
@@ -727,5 +749,5 @@
                 goto failure;
             }
-            if (!pmFPAfileCreate(file, view)) {
+            if (!pmFPAfileCreate(file, view, config)) {
                 psError(PS_ERR_IO, false, "failed CREATE in FPA_BEFORE block for %s", file->name);
                 goto failure;
Index: /trunk/psModules/src/camera/pmFPAfileIO.h
===================================================================
--- /trunk/psModules/src/camera/pmFPAfileIO.h	(revision 10965)
+++ /trunk/psModules/src/camera/pmFPAfileIO.h	(revision 10966)
@@ -7,6 +7,6 @@
 *  @author EAM, IfA
 *
-*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-06-17 01:50:43 $
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2007-01-08 22:30:21 $
 *
 *  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
@@ -22,5 +22,5 @@
 bool pmFPAfileRead (pmFPAfile *file, const pmFPAview *view, pmConfig *config);
 
-bool pmFPAfileCreate (pmFPAfile *file, const pmFPAview *view);
+bool pmFPAfileCreate (pmFPAfile *file, const pmFPAview *view, pmConfig *config);
 
 // write to the real file corresponding to the given pmFPAfile for the current view
