Index: trunk/psModules/src/camera/pmFPAMosaic.c
===================================================================
--- trunk/psModules/src/camera/pmFPAMosaic.c	(revision 7755)
+++ trunk/psModules/src/camera/pmFPAMosaic.c	(revision 7849)
@@ -4,4 +4,5 @@
 #include "pmFPA.h"
 #include "pmHDU.h"
+#include "pmConceptsAverage.h"
 #include "pmHDUUtils.h"
 #include "pmFPAMosaic.h"
@@ -27,11 +28,4 @@
 if ((value) > (max)) { \
     (max) = (value); \
-}
-
-// Update a metadata entry directly
-#define MD_UPDATE(MD, NAME, TYPE, VALUE) \
-{ \
-    psMetadataItem *item = psMetadataLookup(MD, NAME); \
-    item->data.TYPE = VALUE; \
 }
 
@@ -529,108 +523,4 @@
 
     return mosaic;
-}
-
-
-// Set the concepts in the new cell, based on the values in the old one
-static bool cellConcepts(pmCell *target,// Target cell
-                         psList *sources, // Source cells
-                         int xBin, int yBin, // Binning
-                         psRegion *trimsec // The trim section
-                        )
-{
-    assert(target);
-    assert(sources);
-    assert(xBin > 0 && yBin > 0);
-    assert(trimsec);
-
-    bool success = true;                // Result of setting everything
-    float gain       = 0.0;             // Gain
-    float readnoise  = 0.0;             // Read noise
-    float saturation = INFINITY;        // Saturation level
-    float bad        = -INFINITY;       // Bad level
-    float exposure   = 0.0;             // Exposure time
-    float darktime   = 0.0;             // Dark time
-    double time      = 0.0;             // Time of observation
-    psTimeType timeSys = 0;             // Time system
-    int readdir      = 0;               // Cell read direction
-
-    int nCells = 0;                     // Number of cells;
-    psListIterator *sourcesIter = psListIteratorAlloc(sources, PS_LIST_HEAD, false); // Iterator for sources
-    pmCell *cell = NULL;                // Source cell from iteration
-    while ((cell = psListGetAndIncrement(sourcesIter))) {
-        if (!cell) {
-            continue;
-        }
-
-        nCells++;
-        gain       += psMetadataLookupF32(NULL, cell->concepts, "CELL.GAIN");
-        readnoise  += psMetadataLookupF32(NULL, cell->concepts, "CELL.READNOISE");
-        exposure   += psMetadataLookupF32(NULL, cell->concepts, "CELL.EXPOSURE");
-        darktime   += psMetadataLookupF32(NULL, cell->concepts, "CELL.DARKTIME");
-        psTime *cellTime = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TIME");
-        time       += psTimeToMJD(cellTime);
-        if (nCells == 1) {
-            timeSys = psMetadataLookupS32(NULL, cell->concepts, "CELL.TIMESYS");
-            readdir = psMetadataLookupS32(NULL, cell->concepts, "CELL.READDIR");
-        } else {
-            if (timeSys != psMetadataLookupS32(NULL, cell->concepts, "CELL.TIMESYS")) {
-                psLogMsg(__func__, PS_LOG_ERROR, "Differing time systems in use: %d vs %d\n", timeSys,
-                         psMetadataLookupS32(NULL, cell->concepts, "CELL.TIMESYS"));
-                success = false;
-            }
-            if (readdir != psMetadataLookupS32(NULL, cell->concepts, "CELL.READDIR")) {
-                psLogMsg(__func__, PS_LOG_ERROR, "Differing cell read directions in use: %d vs %d\n", readdir,
-                         psMetadataLookupS32(NULL, cell->concepts, "CELL.READDIR"));
-                success = false;
-            }
-        }
-
-        float cellSaturation = psMetadataLookupF32(NULL, cell->concepts, "CELL.SATURATION");
-        if (cellSaturation < saturation) {
-            saturation = cellSaturation;
-        }
-        float cellBad = psMetadataLookupF32(NULL, cell->concepts, "CELL.BAD");
-        if (cellBad > bad) {
-            bad = cellBad;
-        }
-    }
-    psFree(sourcesIter);
-
-    gain      /= (float)nCells;
-    readnoise /= (float)nCells;
-    exposure  /= (float)nCells;
-    darktime  /= (float)nCells;
-    time      /= (double)nCells;
-
-    MD_UPDATE(target->concepts, "CELL.GAIN", F32, gain);
-    MD_UPDATE(target->concepts, "CELL.READNOISE", F32, readnoise);
-    MD_UPDATE(target->concepts, "CELL.SATURATION", F32, saturation);
-    MD_UPDATE(target->concepts, "CELL.BAD", F32, bad);
-    MD_UPDATE(target->concepts, "CELL.EXPOSURE", F32, exposure);
-    MD_UPDATE(target->concepts, "CELL.DARKTIME", F32, darktime);
-    MD_UPDATE(target->concepts, "CELL.TIMESYS", S32, timeSys);
-    MD_UPDATE(target->concepts, "CELL.X0", S32, 0);
-    MD_UPDATE(target->concepts, "CELL.Y0", S32, 0);
-    MD_UPDATE(target->concepts, "CELL.XPARITY", S32, 1);
-    MD_UPDATE(target->concepts, "CELL.YPARITY", S32, 1);
-    MD_UPDATE(target->concepts, "CELL.XBIN", S32, xBin);
-    MD_UPDATE(target->concepts, "CELL.YBIN", S32, yBin);
-    MD_UPDATE(target->concepts, "CELL.READDIR", S32, readdir);
-
-    // CELL.TIME needs special care
-    {
-        psMetadataItem *timeItem = psMetadataLookup(target->concepts, "CELL.TIME");
-        psFree(timeItem->data.V);
-        timeItem->data.V = psTimeFromMJD(time);
-    }
-
-    // CELL.TRIMSEC needs special care
-    {
-        psMetadataItem *trimsecItem = psMetadataLookup(target->concepts, "CELL.TRIMSEC");
-        psFree(trimsecItem->data.V);
-        trimsecItem->data.V = psMemIncrRefCounter(trimsec);
-    }
-
-    return success;
 }
 
@@ -1105,5 +995,5 @@
     // Set the concepts for the target cell
     psList *sourceCells = psArrayToList(source->cells); // List of cells
-    cellConcepts(targetCell, sourceCells, xBin, yBin, chipRegion);
+    pmConceptsAverageCells(targetCell, sourceCells, xBin, yBin, chipRegion, NULL);
     psFree(sourceCells);
     psFree(chipRegion);
@@ -1211,5 +1101,5 @@
         }
     }
-    cellConcepts(targetCell, sourceCells, xBin, yBin, fpaRegion);
+    pmConceptsAverageCells(targetCell, sourceCells, xBin, yBin, fpaRegion, NULL);
     psFree(sourceCells);
     psFree(fpaRegion);
