Index: /trunk/psLib/src/types/psMetadata.c
===================================================================
--- /trunk/psLib/src/types/psMetadata.c	(revision 9533)
+++ /trunk/psLib/src/types/psMetadata.c	(revision 9534)
@@ -12,6 +12,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.137 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-10-12 23:43:58 $
+ *  @version $Revision: 1.138 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-10-13 19:06:00 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -1413,5 +1413,5 @@
 }
 
-psPolynomial2D *psPolynomial2DfromMD (psMetadata *folder)
+psPolynomial1D *psPolynomial1DfromMD (psMetadata *folder)
 {
     PS_ASSERT_PTR_NON_NULL(folder, NULL);
@@ -1420,14 +1420,130 @@
 
     // get polynomial orders
-    // XXX add status failures tests
     int nXorder = psMetadataLookupS32 (&status, folder, "NORDER_X");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial1D in metadata is missing NORDER_X");
+        return NULL;
+    }
+    // how many polynomial coeffs are expected?
+    int nElementsExpected = psMetadataLookupS32 (&status, folder, "NELEMENTS");
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial1D in metadata is missing NELEMENTS");
+        return NULL;
+    }
+
+    psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, nXorder);
+
+    int nElements = 0;
+    for (int nx = 0; nx < poly->nX + 1; nx++) {
+        sprintf (keyword, "VAL_X%02d", nx);
+        poly->coeff[nx] = psMetadataLookupF64 (&status, folder, keyword);
+        if (!status) {
+            // an undefined component implies the component was masked
+            // this is symmetrical with the 1DtoMD function
+            poly->mask[nx] = 1;
+            poly->coeff[nx] = 0;
+            poly->coeffErr[nx] = 0;
+        } else {
+            poly->mask[nx] = 0;
+            nElements ++;
+        }
+        sprintf (keyword, "ERR_X%02d", nx);
+        poly->coeffErr[nx] = psMetadataLookupF64 (&status, folder, keyword);
+    }
+    if (nElements != nElementsExpected) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psPolynomial1D in metadata does not have the correct number of coefficients: "
+                "%d found vs %d expected", nElements, nElementsExpected);
+        psFree(poly);
+        return NULL;
+    }
+    return (poly);
+}
+
+// XXX : these may need F64, or %g format for output
+bool psPolynomial1DtoMD (psMetadata *md,
+                         psPolynomial1D *poly,
+                         char *format,
+                         ...)
+{
+    PS_ASSERT_PTR_NON_NULL(md, false);
+    PS_ASSERT_PTR_NON_NULL(poly, false);
+    //XXX:  Current implementation only supports ordinary polynomials.
+    if (poly->type != PS_POLYNOMIAL_ORD)
+        return false;
+
+    int Nbyte;
+    char tmp;
+    char *root;
+    va_list argp;
+
+    va_start (argp, format);
+    Nbyte = vsnprintf (&tmp, 0, format, argp);
+    va_end (argp);
+
+    if (Nbyte <= 0)
+        return false;
+
+    va_start (argp, format);
+    root = (char *) psAlloc (Nbyte + 1);
+    memset (root, 0, Nbyte + 1);
+    vsnprintf (root, Nbyte + 1, format, argp);
+    va_end (argp);
+
+    psMetadata *folder = psMetadataAlloc ();
+
+    // specify the polynomial orders
+    psMetadataAdd (folder, PS_LIST_TAIL, "NORDER_X", PS_DATA_S32, "number of x orders", poly->nX);
+
+    char namespace[80];
+    char namespace_err[80];
+    int nElements = 0;   // count the number of unmasked elements
+
+    // place polynomial entries on folder
+    for (int nx = 0; nx < poly->nX + 1; nx++) {
+        if (poly->mask[nx] == 0) {
+            sprintf(namespace, "VAL_X%02d", nx);
+            sprintf(namespace_err, "ERR_X%02d", nx);
+            psMetadataAdd (folder, PS_LIST_TAIL, namespace, PS_DATA_F64,
+                           "polynomial coefficient", poly->coeff[nx]);
+            psMetadataAdd (folder, PS_LIST_TAIL, namespace_err, PS_DATA_F64,
+                           "polynomial coefficient error", poly->coeffErr[nx]);
+            nElements ++;
+        }
+    }
+    psMetadataAdd (folder, PS_LIST_TAIL, "NELEMENTS", PS_DATA_S32, "number of unmasked coeffs", nElements);
+    psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 1D polynomial", folder);
+    psFree (root);
+    psFree(folder);
+    return true;
+}
+
+psPolynomial2D *psPolynomial2DfromMD (psMetadata *folder)
+{
+    PS_ASSERT_PTR_NON_NULL(folder, NULL);
+    bool status;
+    char keyword[80];
+
+    // get polynomial orders
+    int nXorder = psMetadataLookupS32 (&status, folder, "NORDER_X");
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial2D in metadata is missing NORDER_X");
+        return NULL;
+    }
     int nYorder = psMetadataLookupS32 (&status, folder, "NORDER_Y");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial2D in metadata is missing NORDER_Y");
+        return NULL;
+    }
+    // how many polynomial coeffs are expected?
+    int nElementsExpected = psMetadataLookupS32 (&status, folder, "NELEMENTS");
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial2D in metadata is missing NELEMENTS");
+        return NULL;
+    }
 
     psPolynomial2D *poly = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXorder, nYorder);
 
+    int nElements = 0;
     for (int nx = 0; nx < poly->nX + 1; nx++) {
         for (int ny = 0; ny < poly->nY + 1; ny++) {
@@ -1435,16 +1551,23 @@
             poly->coeff[nx][ny] = psMetadataLookupF64 (&status, folder, keyword);
             if (!status) {
-                //XXX: Setting the mask of a corrupted polynomial doesn't make sense.
-                //The polynomial is garbage if ANY coeff-element is lost!!!
-                //                    poly->mask[nx][ny] = 1;
-                psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                        "psPolynomial2D in metadata has lost a coefficient somewhere!"
-                        " >>position= [x,y] = %02d, %02d", nx, ny);
-                psFree(poly);
-                return NULL;
+                // an undefined component implies the component was masked
+                // this is symmetrical with the 2DtoMD function
+                poly->mask[nx][ny] = 1;
+                poly->coeff[nx][ny] = 0;
+                poly->coeffErr[nx][ny] = 0;
+            } else {
+                poly->mask[nx][ny] = 0;
+                nElements ++;
             }
             sprintf (keyword, "ERR_X%02d_Y%02d", nx, ny);
             poly->coeffErr[nx][ny] = psMetadataLookupF64 (&status, folder, keyword);
         }
+    }
+    if (nElements != nElementsExpected) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psPolynomial2D in metadata does not have the correct number of coefficients: "
+                "%d found vs %d expected", nElements, nElementsExpected);
+        psFree(poly);
+        return NULL;
     }
     return (poly);
@@ -1462,7 +1585,11 @@
     if (poly->type != PS_POLYNOMIAL_ORD)
         return false;
+
+    // XXX I'm puzzled by this test.  a polynomial of 0 order with a value of 0 is a
+    // perfectly valid polynomial and can be written out.  a polynomial with all elements
+    // masked still carries information.
     //Make sure polynomial isn't 0, completely empty
-    if (poly->nX == 0 && poly->nY == 0 && poly->coeff[0][0] == 0)
-        return false;
+    //if (poly->nX == 0 && poly->nY == 0 && poly->coeff[0][0] == 0)
+    //return false;
 
     int Nbyte;
@@ -1492,4 +1619,6 @@
     char namespace[80];
     char namespace_err[80];
+    int nElements = 0;   // count the number of unmasked elements
+
     // place polynomial entries on folder
     for (int nx = 0; nx < poly->nX + 1; nx++) {
@@ -1502,7 +1631,9 @@
                 psMetadataAdd (folder, PS_LIST_TAIL, namespace_err, PS_DATA_F64,
                                "polynomial coefficient error", poly->coeffErr[nx][ny]);
+                nElements ++;
             }
         }
     }
+    psMetadataAdd (folder, PS_LIST_TAIL, "NELEMENTS", PS_DATA_S32, "number of unmasked coeffs", nElements);
     psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 2D polynomial", folder);
     psFree (root);
@@ -1519,17 +1650,29 @@
 
     // get polynomial orders
-    // XXX add status failures tests
     int nXorder = psMetadataLookupS32 (&status, folder, "NORDER_X");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial3D in metadata is missing NORDER_X");
+        return NULL;
+    }
     int nYorder = psMetadataLookupS32 (&status, folder, "NORDER_Y");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial3D in metadata is missing NORDER_Y");
+        return NULL;
+    }
     int nZorder = psMetadataLookupS32 (&status, folder, "NORDER_Z");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial3D in metadata is missing NORDER_Z");
+        return NULL;
+    }
+    // how many polynomial coeffs are expected?
+    int nElementsExpected = psMetadataLookupS32 (&status, folder, "NELEMENTS");
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial3D in metadata is missing NELEMENTS");
+        return NULL;
+    }
 
     psPolynomial3D *poly = psPolynomial3DAlloc (PS_POLYNOMIAL_ORD, nXorder, nYorder, nZorder);
 
+    int nElements = 0;
     for (int nx = 0; nx < poly->nX + 1; nx++) {
         for (int ny = 0; ny < poly->nY + 1; ny++) {
@@ -1538,12 +1681,12 @@
                 poly->coeff[nx][ny][nz] = psMetadataLookupF64 (&status, folder, keyword);
                 if (!status) {
-                    //XXX: Setting the mask of a corrupted polynomial doesn't make sense.
-                    //The polynomial is garbage if ANY coeff-element is lost!!!
-                    //                    poly->mask[nx][ny][nz] = 1;
-                    psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                            "psPolynomial3D in metadata has lost a coefficient somewhere!"
-                            " >>position= [x,y,z] = %02d, %02d, %02d", nx, ny, nz);
-                    psFree(poly);
-                    return NULL;
+                    // an undefined component implies the component was masked
+                    // this is symmetrical with the 3DtoMD function
+                    poly->mask[nx][ny][nz] = 1;
+                    poly->coeff[nx][ny][nz] = 0;
+                    poly->coeffErr[nx][ny][nz] = 0;
+                } else {
+                    poly->mask[nx][ny][nz] = 0;
+                    nElements ++;
                 }
                 sprintf (keyword, "ERR_X%02d_Y%02d_Z%02d", nx, ny, nz);
@@ -1551,4 +1694,11 @@
             }
         }
+    }
+    if (nElements != nElementsExpected) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psPolynomial3D in metadata does not have the correct number of coefficients: "
+                "%d found vs %d expected", nElements, nElementsExpected);
+        psFree(poly);
+        return NULL;
     }
     return (poly);
@@ -1565,7 +1715,4 @@
     if (poly->type != PS_POLYNOMIAL_ORD)
         return false;
-    //Make sure polynomial isn't 0, completely empty
-    if (poly->nX == 0 && poly->nY == 0 && poly->nZ == 0 && poly->coeff[0][0][0] == 0)
-        return false;
 
     int Nbyte;
@@ -1596,4 +1743,6 @@
     char namespace[80];
     char namespace_err[80];
+    int nElements = 0;   // count the number of unmasked elements
+
     // place polynomial entries on folder
     for (int nx = 0; nx < poly->nX + 1; nx++) {
@@ -1609,9 +1758,10 @@
                                    PS_DATA_F64, "polynomial coeffficient error",
                                    poly->coeffErr[nx][ny][nz], nx, ny, nz);
+                    nElements ++;
                 }
             }
         }
     }
-
+    psMetadataAdd (folder, PS_LIST_TAIL, "NELEMENTS", PS_DATA_S32, "number of unmasked coeffs", nElements);
     psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 3D polynomial", folder);
     psFree(root);
@@ -1620,5 +1770,4 @@
 }
 
-
 psPolynomial4D *psPolynomial4DfromMD (psMetadata *folder)
 {
@@ -1628,22 +1777,34 @@
     char keyword[80];
 
-    // get polynomial orders
-    // XXX add status failures tests
     int nXorder = psMetadataLookupS32 (&status, folder, "NORDER_X");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial4D in metadata is missing NORDER_X");
+        return NULL;
+    }
     int nYorder = psMetadataLookupS32 (&status, folder, "NORDER_Y");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial4D in metadata is missing NORDER_Y");
+        return NULL;
+    }
     int nZorder = psMetadataLookupS32 (&status, folder, "NORDER_Z");
-    if (!status)
-        return NULL;
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial4D in metadata is missing NORDER_Z");
+        return NULL;
+    }
     int nTorder = psMetadataLookupS32 (&status, folder, "NORDER_T");
-    if (!status)
-        return NULL;
-
-    psPolynomial4D *poly = psPolynomial4DAlloc(PS_POLYNOMIAL_ORD,
-                           nXorder, nYorder, nZorder, nTorder);
-
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial4D in metadata is missing NORDER_T");
+        return NULL;
+    }
+    // how many polynomial coeffs are expected?
+    int nElementsExpected = psMetadataLookupS32 (&status, folder, "NELEMENTS");
+    if (!status) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "psPolynomial4D in metadata is missing NELEMENTS");
+        return NULL;
+    }
+
+    psPolynomial4D *poly = psPolynomial4DAlloc(PS_POLYNOMIAL_ORD, nXorder, nYorder, nZorder, nTorder);
+
+    int nElements = 0;
     for (int nx = 0; nx < poly->nX + 1; nx++) {
         for (int ny = 0; ny < poly->nY + 1; ny++) {
@@ -1653,14 +1814,13 @@
                     poly->coeff[nx][ny][nz][nt] = psMetadataLookupF64 (&status, folder, keyword);
                     if (!status) {
-                        //XXX: Setting the mask of a corrupted polynomial doesn't make sense.
-                        //The polynomial is garbage if ANY coeff-element is lost!!!
-                        //                    poly->mask[nx][ny][nz][nt] = 1;
-                        psError(PS_ERR_BAD_PARAMETER_VALUE, false,
-                                "psPolynomial4D in metadata has lost a coefficient somewhere!"
-                                " >>position= [x,y,z,t] = %02d, %02d, %02d, %02d", nx,ny,nz,nt);
-                        psFree(poly);
-                        return NULL;
+                        // an undefined component implies the component was masked
+                        // this is symmetrical with the 4DtoMD function
+                        poly->mask[nx][ny][nz][nt] = 1;
+                        poly->coeff[nx][ny][nz][nt] = 0;
+                        poly->coeffErr[nx][ny][nz][nt] = 0;
+                    } else {
+                        poly->mask[nx][ny][nz][nt] = 0;
+                        nElements ++;
                     }
-
                     sprintf (keyword, "ERR_X%02d_Y%02d_Z%02d_T%02d", nx, ny, nz, nt);
                     poly->coeffErr[nx][ny][nz][nt] = psMetadataLookupF64 (&status, folder, keyword);
@@ -1668,4 +1828,11 @@
             }
         }
+    }
+    if (nElements != nElementsExpected) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psPolynomial4D in metadata does not have the correct number of coefficients: "
+                "%d found vs %d expected", nElements, nElementsExpected);
+        psFree(poly);
+        return NULL;
     }
     return (poly);
@@ -1682,9 +1849,4 @@
     if (poly->type != PS_POLYNOMIAL_ORD)
         return false;
-    //Make sure polynomial isn't 0, completely empty
-    if (poly->nX == 0 && poly->nY == 0 && poly->nZ == 0 && poly->nT == 0
-            && poly->coeff[0][0][0][0] == 0)
-        return false;
-
 
     int Nbyte;
@@ -1716,4 +1878,6 @@
     char namespace[80];
     char namespace_err[80];
+    int nElements = 0;   // count the number of unmasked elements
+
     // place polynomial entries on folder
     for (int nx = 0; nx < poly->nX + 1; nx++) {
@@ -1730,4 +1894,5 @@
                                        PS_DATA_F64, "polynomial coeffficient error",
                                        poly->coeffErr[nx][ny][nz][nt], nx, ny, nz, nt);
+                        nElements ++;
                     }
                 }
@@ -1735,4 +1900,5 @@
         }
     }
+    psMetadataAdd (folder, PS_LIST_TAIL, "NELEMENTS", PS_DATA_S32, "number of unmasked coeffs", nElements);
     psMetadataAdd (md, PS_LIST_TAIL, root, PS_DATA_METADATA, "folder for 4D polynomial", folder);
     psFree(root);
Index: /trunk/psLib/src/types/psMetadata.h
===================================================================
--- /trunk/psLib/src/types/psMetadata.h	(revision 9533)
+++ /trunk/psLib/src/types/psMetadata.h	(revision 9534)
@@ -11,6 +11,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.86 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-10-12 23:43:58 $
+*  @version $Revision: 1.87 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-10-13 19:06:00 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -1070,4 +1070,37 @@
 );
 
+/** Allocates a new psPolynomial1D structure with information from a psMetadata.
+ *
+ *  Parses a psMetadata container with psPolynomial1D information.  The first two
+ *  elements of the metadata folder specify the order of the x & y variables.  (ie,
+ *  NORDER_X, NORDER_Y).  The following elements are the values of the coefficients
+ *  and the coefficient errors.  (ie, VAL_X00_Y00, ERR_X00_Y00, etc.).  If the orders
+ *  or any coefficients are missing or have incorrect syntax, NULL is returned.
+ *
+ *  @return psPolynomial1D*:        Newly allocated psPolynomial1D from metadata.
+ */
+psPolynomial1D *psPolynomial1DfromMD(
+    psMetadata *folder                 ///< folder containing the polynomial info.
+);
+
+/** Stores the information from a psPolynomial1D structure in a psMetadata container.
+ *
+ *  Creates a psMetadata folder with psPolynomial1D information.  The first two
+ *  elements of the metadata folder specify the order of the x & y variables.  (ie,
+ *  NORDER_X, NORDER_Y).  The following elements are the values of the coefficients
+ *  and the coefficient errors.  (ie, VAL_X00_Y00, ERR_X00_Y00, etc.).  The input
+ *  polynomial must be of ordinary type and have a valid name format.  False is also
+ *  returned if any inputs are NULL.  *If a particular mask element is non-zero, that
+ *  polynomial coefficient (and error) are skipped.
+ *
+ *  @return bool:       True if successful, otherwise false.
+ */
+bool psPolynomial1DtoMD(
+    psMetadata *md,                    ///< Metadata container for polynomial storage.
+    psPolynomial1D *poly,              ///< Polynomial information to be stored.
+    char *format,                      ///< Name of polynomial folder.
+    ...                                ///< Arguments for name formatting.
+);
+
 /** Allocates a new psPolynomial2D structure with information from a psMetadata.
  *
