Index: /trunk/pstamp/src/pstamprequest.c
===================================================================
--- /trunk/pstamp/src/pstamprequest.c	(revision 18636)
+++ /trunk/pstamp/src/pstamprequest.c	(revision 18637)
@@ -11,7 +11,8 @@
     psString    fileName;
     psString    requestName;
+    bool        verbose;
 } psrOptions;
 
-char *str_columns[] = {
+char *string_columns[] = {
     "ROWNUM",
     "PROJECT",
@@ -20,4 +21,9 @@
     "ID",       // db id, exposure name, n/a
     "CLASS_ID",
+    "FILTER",
+    "STAMP_NAME",
+    NULL
+};
+char *double_columns[]= {
     "CENTER_X",
     "CENTER_Y",
@@ -25,8 +31,6 @@
     "HEIGHT",
     "FILTER",
-    "DATE_MIN",
-    "DATE_MAX",
-    "STAMP_NAME",
-    NULL
+    "MJD_MIN",
+    "MJD_MAX",
 };
 char *u32_columns[] = {
@@ -36,8 +40,8 @@
 };
 
-static void usage()
+static void usage(int exitStatus)
 {
     psErrorStackPrint(stderr, "Unable to parse command-line arguments.");
-    exit(1);
+    exit(exitStatus);
 }
 
@@ -46,10 +50,16 @@
     psMetadata *md = psMetadataAlloc();
 
-    for (char **col_name = str_columns; *col_name != NULL; col_name++) {
+    //  unset columns with string type default to "null"
+    for (char **col_name = string_columns; *col_name != NULL; col_name++) {
         psMetadataAddStr(md, PS_LIST_TAIL, *col_name, PS_META_DEFAULT, "", "null");
     }
+    //  unset columns with u32 type default to 0
     for (char **col_name = u32_columns; *col_name != NULL; col_name++) {
         psMetadataAddU32(md, PS_LIST_TAIL, *col_name, PS_META_DEFAULT, "", 0);
     }
+    //  unset columns with f64 type default to 0.
+    for (char **col_name = double_columns; *col_name != NULL; col_name++) {
+        psMetadataAddF64(md, PS_LIST_TAIL, *col_name, PS_META_DEFAULT, "", 0.0);
+    }
     return md;
 }
@@ -58,10 +68,10 @@
     if (*pArgc < 2) {
         fprintf(stderr, "must specify %s\n", idString);
-        usage();
+        usage(PS_EXIT_DATA_ERROR);
     }
     // catch common error
     if (*argv[argnum] == '-') {
         fprintf(stderr, "%s is not a valid %s\n", argv[argnum], idString);
-        usage();
+        usage(PS_EXIT_DATA_ERROR);
     }
 
@@ -73,7 +83,14 @@
 static pstampImageType getType(int argnum, int *pArgc, char *argv[], psrOptions *options, char *paramName)
 {
-    if (*pArgc < (argnum+2)) {
-        fprintf(stderr, "must specify image type and %s\n", paramName);
-        usage();
+    if (paramName) {
+        if (*pArgc < (argnum+2)) {
+            fprintf(stderr, "must specify image type and %s\n", paramName);
+            usage(PS_EXIT_DATA_ERROR);
+        }
+    }  else {
+        if (*pArgc < (argnum+1)) {
+            fprintf(stderr, "must specify image type");
+            usage(PS_EXIT_DATA_ERROR);
+        }
     }
     char *type = argv[argnum];
@@ -95,9 +112,11 @@
     } else {
         fprintf(stderr, "unknown image type %s\n", type);
-        usage();
+        usage(PS_EXIT_DATA_ERROR);
     }
     psMetadataAddStr (options->md, PS_LIST_TAIL, "IMG_TYPE", PS_META_REPLACE, "", type);
 
-    getId(paramName, argnum, pArgc, argv, options);
+    if (paramName) {
+        getId(paramName, argnum, pArgc, argv, options);
+    }
 
     return itype;
@@ -141,6 +160,24 @@
     }
 }
-
-static psrOptions *parseArguments(int argc, char *argv[])
+static void doByCoord(int argnum, int *pArgc, char *argv[], psrOptions *options)
+{
+    switch (getType(argnum, pArgc, argv, options, NULL)) {
+    case PSTAMP_RAW:
+        getId("CLASS_ID", argnum, pArgc, argv, options);
+        break;
+    case PSTAMP_CHIP:
+        getId("CLASS_ID", argnum, pArgc, argv, options);
+        break;
+    case PSTAMP_WARP:
+    case PSTAMP_DIFF:
+    case PSTAMP_STACK:
+        break;
+    default:
+        fprintf(stderr, "programming error unexpected image type\n");
+        exit(1);
+    }
+}
+
+static psrOptions *parseArguments(int argc, char *argv[], int *pExitStatus)
 {
     psrOptions *options = psAlloc(sizeof(psrOptions));
@@ -180,5 +217,5 @@
         if (argc < 2) {
             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "value required for request name");
-            usage();
+            usage(PS_EXIT_DATA_ERROR);
         }
         options->requestName = argv[argnum];
@@ -186,5 +223,5 @@
     } else {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "req_name is required\n");
-        usage();
+        usage(PS_EXIT_DATA_ERROR);
     }
 
@@ -193,5 +230,5 @@
         if (argc < 2) {
             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "project is required");
-            usage();
+            usage(PS_EXIT_DATA_ERROR);
         }
         psMetadataAddStr(md, PS_LIST_TAIL, "PROJECT", PS_META_REPLACE, "", argv[argnum]);
@@ -199,19 +236,16 @@
     } else {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "project is required\n");
-        usage();
-    }
-
-    // user tag will be used as the base name for the postage stamp images
+        usage(PS_EXIT_DATA_ERROR);
+    }
+
+    // if provided, stamp name tag will be appended to the base name for the postage stamp images
     if ((argnum = psArgumentGet(argc, argv, "-stamp_name"))) {
         psArgumentRemove(argnum, &argc, argv);
         if (argc < 2) {
             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "missing value for stamp_name");
-            usage();
+            usage(PS_EXIT_DATA_ERROR);
         }
         psMetadataAddStr(md, PS_LIST_TAIL, "STAMP_NAME", PS_META_REPLACE, "", argv[argnum]);
         psArgumentRemove(argnum, &argc, argv);
-    } else {
-        // if stamp name not specified use requestName
-        psMetadataAddStr(md, PS_LIST_TAIL, "STAMP_NAME", PS_META_REPLACE, "", options->requestName);
     }
 
@@ -228,7 +262,4 @@
     // find style & image type
     if ((argnum = psArgumentGet(argc, argv, "-bycoord"))) {
-        fprintf(stderr, "-bycoord not implemented yet\n");
-        exit(1);
-
         gotStyle = true;
         psMetadataAddStr(md, PS_LIST_TAIL, "REQ_TYPE", PS_META_REPLACE, "", 1+argv[argnum]);
@@ -236,5 +267,5 @@
         psArgumentRemove(argnum, &argc, argv); needCoord = true;
         needROI = true;
-        // TODO: we need an IMG_TYPE too...
+        doByCoord(argnum, &argc, argv, options);
     }
 
@@ -242,5 +273,5 @@
         if (gotStyle) {
             fprintf(stderr, "only one of -bycoord -byid -byexp may be specified\n");
-            usage(1);
+            usage(PS_EXIT_DATA_ERROR);
         }
         gotStyle = true;
@@ -253,5 +284,5 @@
         if (gotStyle) {
             fprintf(stderr, "only one of -bycoord -byid -byexp may be specified\n");
-            usage(1);
+            usage(PS_EXIT_DATA_ERROR);
         }
         gotStyle = true;
@@ -260,8 +291,25 @@
         doByExp(argnum, &argc, argv, options);
     } 
-
     if (!gotStyle) {
         fprintf(stderr, "one of -bycoord -byid -byexp must be specified\n");
-        usage();
+        usage(PS_EXIT_DATA_ERROR);
+    }
+    if ((argnum = psArgumentGet(argc, argv, "-mjd_min"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        if (argc < 2) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "missing value mjd_min");
+            usage(PS_EXIT_DATA_ERROR);
+        }
+        psMetadataAddF64(md, PS_LIST_TAIL, "MJD_MIN", PS_META_REPLACE, "", atof(argv[argnum]));
+        psArgumentRemove(argnum, &argc, argv);
+    } 
+    if ((argnum = psArgumentGet(argc, argv, "-mjd_max"))) {
+        psArgumentRemove(argnum, &argc, argv);
+        if (argc < 2) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "missing value mjd_max");
+            usage(PS_EXIT_DATA_ERROR);
+        }
+        psMetadataAddF64(md, PS_LIST_TAIL, "MJD_MAX", PS_META_REPLACE, "", atof(argv[argnum]));
+        psArgumentRemove(argnum, &argc, argv);
     }
 
@@ -271,5 +319,5 @@
     if (!pstampGetROI(&roiParam, &argc, argv, &gotCenter, &gotRange)) {
         if (needROI) {
-            usage();
+            usage(PS_EXIT_DATA_ERROR);
         } else {
             psErrorClear();
@@ -280,19 +328,29 @@
         unsigned coord_mask = 0;
 
-        if (!roiParam.celestialCenter) {
+        if (roiParam.celestialCenter) {
+            psMetadataAddF64 (md, PS_LIST_TAIL, "CENTER_X", PS_META_REPLACE, "",
+                RAD_TO_DEG(roiParam.centerRA));
+            psMetadataAddF64 (md, PS_LIST_TAIL, "CENTER_Y", PS_META_REPLACE, "",
+                RAD_TO_DEG(roiParam.centerDEC));
+        } else {
             if (needCoord) {
                 fprintf(stderr, "need to specify ROI in sky coordinates with -bycoord\n");
-                usage();
+                usage(PS_EXIT_DATA_ERROR);
             }
             coord_mask |= PSTAMP_CENTER_IN_PIXELS;
-        }
-        psMetadataAddStr (md, PS_LIST_TAIL, "CENTER_X", PS_META_REPLACE, "", roiParam.center[0]);
-        psMetadataAddStr (md, PS_LIST_TAIL, "CENTER_Y", PS_META_REPLACE, "", roiParam.center[1]);
-
-        if (!roiParam.celestialRange) {
+            psMetadataAddF64 (md, PS_LIST_TAIL, "CENTER_X", PS_META_REPLACE, "", atof(roiParam.center[0]));
+            psMetadataAddF64 (md, PS_LIST_TAIL, "CENTER_Y", PS_META_REPLACE, "", atof(roiParam.center[1]));
+        }
+
+        if (roiParam.celestialRange) {
+            psMetadataAddF64 (md, PS_LIST_TAIL, "WIDTH", PS_META_REPLACE, "",  
+                RAD_TO_DEG(atof(roiParam.range[0])));
+            psMetadataAddF64 (md, PS_LIST_TAIL, "HEIGHT", PS_META_REPLACE, "", 
+                RAD_TO_DEG(atof(roiParam.range[1])));
+        } else {
             coord_mask |= PSTAMP_RANGE_IN_PIXELS;
-        }
-        psMetadataAddStr (md, PS_LIST_TAIL, "WIDTH", PS_META_REPLACE, "",  roiParam.range[0]);
-        psMetadataAddStr (md, PS_LIST_TAIL, "HEIGHT", PS_META_REPLACE, "", roiParam.range[1]);
+            psMetadataAddF64 (md, PS_LIST_TAIL, "WIDTH", PS_META_REPLACE, "",  atof(roiParam.range[0]));
+            psMetadataAddF64 (md, PS_LIST_TAIL, "HEIGHT", PS_META_REPLACE, "", atof(roiParam.range[1]));
+        }
 
         psMetadataAddU32(md, PS_LIST_TAIL, "COORD_MASK", PS_META_REPLACE, "", coord_mask);
@@ -305,5 +363,5 @@
     } else if (argc == 1) {
         fprintf(stderr, "output file name is required\n");
-        usage();
+        usage(PS_EXIT_DATA_ERROR);
     } else {
         fprintf(stderr, "too many arguments supplied:");
@@ -313,5 +371,5 @@
         }
         fprintf(stderr, "\n");
-        usage();
+        usage(PS_EXIT_DATA_ERROR);
     }
 
@@ -319,9 +377,10 @@
 }
 
-static bool writeTable(psrOptions *options)
+static bool writeTable(psrOptions *options, int *pExitStatus)
 {
     psFits *fitsFile = psFitsOpen(options->fileName, "w");
     if (fitsFile == NULL) {
         psError(PS_ERR_IO, true, "failed to open %s for output\n", options->fileName);
+        *pExitStatus = PS_EXIT_SYS_ERROR;
         return false;
     }
@@ -336,4 +395,5 @@
     if (!psFitsWriteTable(fitsFile, header, table, STAMP_REQUEST_EXTNAME)) {
         psError(PS_ERR_IO, false, "failed to write fits table");
+        *pExitStatus = PS_EXIT_SYS_ERROR;
         return false;
     }
@@ -341,4 +401,5 @@
     if (! psFitsClose(fitsFile)) {
         psError(PS_ERR_IO, false, "failed to close fits table");
+        *pExitStatus = PS_EXIT_SYS_ERROR;
         return false;
     }
@@ -349,5 +410,8 @@
 int main(int argc, char *argv[])
 {
-    psrOptions *options = parseArguments(argc, argv);
+    int exitStatus = 0;
+
+    // all of the action happens in parseArguments
+    psrOptions *options = parseArguments(argc, argv, &exitStatus);
 
     if (!options) {
@@ -355,12 +419,11 @@
     }
 
-    // psMetadataPrint(stderr, options->md, 0);
-
-    if (writeTable(options)) {
-        return 0;
-    } else {
+    if (options->verbose) {
+        psMetadataPrint(stderr, options->md, 0);
+    }
+
+    if (!writeTable(options, &exitStatus)) {
         psErrorStackPrint(stderr, "failed to create request table");
-        // XXX: we should have variable status codes that indicate what the problem was
-        return 1;
-    }
-}
+    }
+    return exitStatus;
+}
