Index: trunk/psModules/src/camera/pmFPAfileDefine.c
===================================================================
--- trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 16479)
+++ trunk/psModules/src/camera/pmFPAfileDefine.c	(revision 16481)
@@ -1200,4 +1200,11 @@
 
     file->src = psMemIncrRefCounter(src); // inherit output elements from this source pmFPA
+    if (src) {
+        if (!pmConceptsCopyFPA(file->fpa, src, true, false)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to copy concepts from source to new FPA");
+            psFree(file);
+            return NULL;
+        }
+    }
 
     file->mosaicLevel = PM_FPA_LEVEL_CHIP; // don't do any I/O on this at a lower level
@@ -1245,4 +1252,11 @@
 
     file->src = psMemIncrRefCounter(src); // inherit output elements from this source pmFPA
+    if (src) {
+        if (!pmConceptsCopyFPA(file->fpa, src, false, false)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to copy concepts from source to new FPA");
+            psFree(file);
+            return NULL;
+        }
+    }
 
     file->mosaicLevel = PM_FPA_LEVEL_FPA; // don't do any I/O on this at a lower level
Index: trunk/psModules/src/concepts/pmConcepts.c
===================================================================
--- trunk/psModules/src/concepts/pmConcepts.c	(revision 16479)
+++ trunk/psModules/src/concepts/pmConcepts.c	(revision 16481)
@@ -1120,2 +1120,80 @@
     return true;
 }
+
+
+bool pmConceptsCopyFPA(pmFPA *target, const pmFPA *source, bool chips, bool cells)
+{
+    PS_ASSERT_PTR_NON_NULL(target, false);
+    PS_ASSERT_PTR_NON_NULL(source, false);
+
+    // Copy FPA concepts
+    copyConcepts(target->concepts, source->concepts, dontCopyConceptsFPA);
+
+    // Copy chip concepts
+    bool status = true;                 // Status of chips
+    if (chips) {
+        psArray *targetChips = target->chips; // Chips in target
+        psArray *sourceChips = source->chips; // Chips in source
+        if (targetChips->n != sourceChips->n) {
+            psError(PS_ERR_IO, true,
+                    "Number of chips in target (%ld) and source (%ld) differ --- unable to copy concepts.",
+                    targetChips->n, sourceChips->n);
+            return false;
+        }
+        for (int i = 0; i < targetChips->n; i++) {
+            pmChip *targetChip = targetChips->data[i]; // Target chip of interest
+            pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest
+            if (! targetChip || ! sourceChip) {
+                continue;
+            }
+
+            status &= pmConceptsCopyChip(targetChip, sourceChip, cells);
+        }
+    }
+
+    return status;
+}
+
+bool pmConceptsCopyChip(pmChip *target, const pmChip *source, bool cells)
+{
+    PS_ASSERT_PTR_NON_NULL(target, false);
+    PS_ASSERT_PTR_NON_NULL(source, false);
+
+    // Copy chip concepts
+    copyConcepts(target->concepts, source->concepts, dontCopyConceptsChip);
+
+    // Copy cell concepts
+    bool status = true;                 // Status of cells
+    if (cells) {
+        psArray *targetCells = target->cells; // Cells in target
+        psArray *sourceCells = source->cells; // Cells in source
+        if (targetCells->n != sourceCells->n) {
+            psError(PS_ERR_IO, true,
+                    "Number of cells in target (%ld) and source (%ld) differ --- unable to copy concepts.",
+                    targetCells->n, sourceCells->n);
+            return false;
+        }
+        for (int j = 0; j < targetCells->n; j++) {
+            pmCell *targetCell = targetCells->data[j]; // Target chip of interest
+            pmCell *sourceCell = sourceCells->data[j]; // Source chip of interest
+            if (! targetCell || ! sourceCell) {
+                continue;
+            }
+
+            status &= pmConceptsCopyCell(targetCell, sourceCell);
+        }
+    }
+
+    return status;
+}
+
+
+bool pmConceptsCopyCell(pmCell *target, const pmCell *source)
+{
+    PS_ASSERT_PTR_NON_NULL(target, false);
+    PS_ASSERT_PTR_NON_NULL(source, false);
+
+    copyConcepts(target->concepts, source->concepts, dontCopyConceptsCell);
+
+    return true;
+}
Index: trunk/psModules/src/concepts/pmConcepts.h
===================================================================
--- trunk/psModules/src/concepts/pmConcepts.h	(revision 16479)
+++ trunk/psModules/src/concepts/pmConcepts.h	(revision 16481)
@@ -4,6 +4,6 @@
  * @author Paul Price, IfA
  *
- * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
- * @date $Date: 2007-03-30 21:12:56 $
+ * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2008-02-15 02:26:09 $
  * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
  */
@@ -203,4 +203,24 @@
                        const pmFPA *source    ///< The source FPA
                       );
+
+/// Copy the concepts within an FPA to another FPA; optionally recurse to lower levels
+bool pmConceptsCopyFPA(pmFPA *target,   ///< Target FPA
+                       const pmFPA *source, ///< Source FPA
+                       bool chips,      ///< Recurse to chips level?
+                       bool cells       ///< Recurse to cells level?
+    );
+
+/// Copy the concepts within a chip to another chip; optionally recurse to lower level
+bool pmConceptsCopyChip(pmChip *target, ///< Target chip
+                        const pmChip *source, ///< Source chip
+                        bool cells      ///< Recurse to cells level?
+    );
+
+/// Copy the concepts within a cell to another cell
+bool pmConceptsCopyCell(pmCell *target, ///< Target cell
+                        const pmCell *source ///< Source cell
+    );
+
+
 /// @}
 #endif
