Index: trunk/psModules/src/imcombine/pmReadoutCombine.c
===================================================================
--- trunk/psModules/src/imcombine/pmReadoutCombine.c	(revision 5741)
+++ trunk/psModules/src/imcombine/pmReadoutCombine.c	(revision 6205)
@@ -5,6 +5,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-11-15 20:09:03 $
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-01-26 21:10:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -461,2 +461,123 @@
 }
 
+
+
+/**
+ *
+ * The input array fluxLevels consists of Ni vectors, one per mosaic image.
+ * Each vector consists of Nj elements, each a measurement of the input
+ * flat-field image flux levels. All of these vectors must be constructed with
+ * the same number of elements, or the function will return an error. If a chip
+ * is missing from a particular image, that element should be set to NaN. The
+ * vector chipGains supplies initial guesses for the chip gains. If the vector
+ * contains the values 0.0 or NaN for any of the elements, the gain is set to the
+ * mean of the valid values. If the vector length does not match the number of
+ * chips, an warning is raised, all chip gain guesses will be set to 1.0, and the
+ * vector length modified to match the number of chips defined by the supplied
+ * fluxLevels. The sourceFlux input vector must be allocated (not NULL), but the
+ * routine will set the vector length to the number of source images regardless
+ * of the initial state of the vector. All vectors used by this function must be
+ * of type PS_DATA_F64.
+ *
+ 
+fluxLevels(i, j): for each flat field image i, this psArray contains a vector
+with an elemenmt for each chip j.  So, fluxLevels(i, j) corresponds to the
+measured flux M_(i, j) for flat image i, chip j.
+ 
+chipGains[]: has j elements, one for each chip.
+ 
+ 
+They have the observed flux levels for each chip of each image.  They want to
+solve for the actual flux levels and the gain of each chip.
+ 
+Okay, they want to solve for source fluxes and chip gains.
+ 
+ 
+ 
+ 
+ 
+ 
+ *
+ */
+bool pmFlatNormalization(
+    psVector *sourceFlux,
+    psVector *chipGains,
+    psArray *fluxLevels)
+{
+    PS_ASSERT_PTR_NON_NULL(fluxLevels, false);
+    psS32 numImages = fluxLevels->n;
+    psS32 numChips = ((psVector *) fluxLevels->data[0])->n;
+    for (psS32 i = 0 ; i < numImages ; i++) {
+        psVector *tmpVec = (psVector *) fluxLevels->data[i];
+        PS_ASSERT_VECTOR_NON_NULL(tmpVec, false);
+        PS_ASSERT_VECTOR_TYPE(tmpVec, PS_TYPE_F64, false);
+        PS_ASSERT_VECTOR_SIZE(tmpVec, numChips, false);
+    }
+
+    //
+    // Ensure that *localChipGains points to a vector of the same length as numImages.
+    //
+    PS_ASSERT_PTR_NON_NULL(chipGains, false);
+    PS_ASSERT_VECTOR_TYPE(chipGains, PS_TYPE_F64, false);
+    psVector *localChipGains = chipGains;
+    if (numChips != chipGains->n) {
+        psLogMsg(__func__, PS_LOG_WARN, "WARNING: the chipGains vector length does not match the number of chips.\n");
+        localChipGains = psVectorAlloc(numChips, PS_TYPE_F64);
+        psBool rc = psVectorInit(localChipGains, 1.0);
+        if (rc == false) {
+            printf("XXX: gen error\n");
+        }
+    }
+
+    //
+    // If the chipGains vector contains the values 0.0 or NaN for any of the elements,
+    // the gain is set to the mean of the valid values.
+    //
+    psBool meanFlag = false;
+    psVector *chipGainsMask = psVectorAlloc(chipGains->n, PS_TYPE_U8);
+    for (psS32 i = 0 ; i < chipGains->n ; i++) {
+        if ((fabs(chipGains->data.F64[i]) < FLT_EPSILON) ||
+                (isnan(chipGains->data.F64[i]))) {
+            chipGainsMask->data.U8[i] = 1;
+            meanFlag = true;
+        }
+    }
+    // Must calculate the mean.
+    if (meanFlag == true) {
+        psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        stats = psVectorStats(stats, chipGains, NULL, chipGainsMask, 1);
+        if (stats == NULL) {
+            printf("XXX: gen error\n");
+        }
+        psF64 mean;
+        psBool rc = p_psGetStatValue(stats, &mean);
+        if (rc == false) {
+            printf("XXX: gen error\n");
+        }
+        // Set the gain to this mean for chips with a gain of 0.0 or NAN
+
+        for (psS32 i = 0 ; i < chipGains->n ; i++) {
+            if ((fabs(chipGains->data.F64[i]) < FLT_EPSILON) ||
+                    (isnan(chipGains->data.F64[i]))) {
+                chipGains->data.F64[i] = mean;
+            }
+        }
+    }
+
+    //
+    // Assert that sourceFlux is non-NULL, correct type, correct size.
+    //
+    PS_ASSERT_PTR_NON_NULL(sourceFlux, false);
+    PS_ASSERT_VECTOR_TYPE(sourceFlux, PS_TYPE_F64, false);
+    psVectorRealloc(sourceFlux, numImages);
+
+
+
+
+
+
+    psFree(psVector);
+    if (numImages != chipGains->n) {
+        psFree(localChipGains);
+    }
+}
Index: trunk/psModules/src/imcombine/pmReadoutCombine.h
===================================================================
--- trunk/psModules/src/imcombine/pmReadoutCombine.h	(revision 5741)
+++ trunk/psModules/src/imcombine/pmReadoutCombine.h	(revision 6205)
@@ -5,6 +5,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-11-15 20:09:03 $
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-01-26 21:10:50 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -72,3 +72,29 @@
 pmFringePoint;
 
+
+/**
+ * 
+ * The input array fluxLevels consists of Ni vectors, one per mosaic image.
+ * Each vector consists of Nj elements, each a measurement of the input
+ * flat-field image flux levels. All of these vectors must be constructed with
+ * the same number of elements, or the function will return an error. If a chip
+ * is missing from a particular image, that element should be set to NaN. The
+ * vector chipGains supplies initial guesses for the chip gains. If the vector
+ * contains the values 0.0 or NaN for any of the elements, the gain is set to the
+ * mean of the valid values. If the vector length does not match the number of
+ * chips, an warning is raised, all chip gain guesses will be set to 1.0, and the
+ * vector length modified to match the number of chips defined by the supplied
+ * fluxLevels. The sourceFlux input vector must be allocated (not NULL), but the
+ * routine will set the vector length to the number of source images regardless
+ * of the initial state of the vector. All vectors used by this function must be
+ * of type PS_DATA_F64.
+ * 
+ */
+bool pmFlatNormalization(
+    psVector *sourceFlux,
+    psVector *chipGains,
+    psArray *fluxLevels
+);
+
+
 #endif
