Index: unk/ppStats/src/ppStatsSetup.c
===================================================================
--- /trunk/ppStats/src/ppStatsSetup.c	(revision 8399)
+++ 	(revision )
@@ -1,343 +1,0 @@
-#include <stdio.h>
-#include <pslib.h>
-#include <psmodules.h>
-#include <string.h>
-
-#include "ppStats.h"
-#include "ppStatsData.h"
-
-// Print usage information and die
-static void usageAndDie(pmConfig *config      // Configuration (contains the arguments list)
-    )
-{
-    printf("Return headers, concepts and/or image statistics.\n\n"
-           "Usage:\n"
-           "\t%s INPUT.fits [OUTPUT_NAME]\n"
-           "\n", config->argv[0]);
-    psArgumentHelp(config->arguments);
-    psFree(config);
-    psLibFinalize();
-    pmConceptsDone();
-    pmConfigDone();
-    exit(EXIT_FAILURE);
-}
-
-// Generate a list from the arguments
-static void listFromArguments(psMetadata *arguments, // Arguments to parse
-                              const char *name, // Name of the item, for error message
-                              const char *flag, // The flag for the argument of interest
-                              psList *target // The target list
-    )
-{
-    psString regex = NULL;              // Regular expression for the flag
-    psStringAppend(&regex, "^%s$", flag);
-    psMetadataIterator *iterator = psMetadataIteratorAlloc(arguments, PS_LIST_HEAD, regex); // Iterator
-    psFree(regex);
-    psMetadataItem *item;               // Item from iteration
-    while ((item = psMetadataGetAndIncrement(iterator))) {
-        if (item->type != PS_DATA_STRING) {
-            psLogMsg(__func__, PS_LOG_WARN, "%s name is not of type STRING (%x) --- ignored.\n",
-                     name, item->type);
-            continue;
-        }
-        if (item->data.V && strlen(item->data.V) > 0) {
-            psListAdd(target, PS_LIST_TAIL, item->data.V);
-        }
-    }
-    psFree(iterator);
-
-    return;
-}
-
-// Strings in a recipe may be defined multiply (with MULTI) or listed on a single line
-static void listFromRecipe(psMetadata *recipe, // Recipe to search
-                           const char *name, // Name for item within recipe
-                           psList *target // The target list
-    )
-{
-    // If the list already has entries, don't read anything else
-    if (psListLength(target) > 0) {
-        return;
-    }
-
-    // First check that at least one item of interest exists
-    psMetadataItem *checkItem = psMetadataLookup(recipe, name);
-    if (!checkItem) {
-        // Nothing to see here
-        return;
-    }
-
-    psString regex = NULL;              // Regular expression for the flag
-    psStringAppend(&regex, "^%s$", name);
-    psMetadataIterator *iterator = psMetadataIteratorAlloc(recipe, PS_LIST_HEAD, regex);
-    psFree(regex);
-    psMetadataItem *item;
-    int numItem = 0; // Occurrence of the item in the recipe; to help the user in case of trouble
-    while ((item = psMetadataGetAndIncrement(iterator))) {
-        numItem++;
-        if (item->type != PS_DATA_STRING) {
-            psLogMsg(__func__, PS_LOG_WARN, "Occurrence %d of %s in the recipe is "
-                     "not of type STRING (%x) --- ignored.\n", numItem, name, item->type);
-            continue;
-        }
-        // Parse into a list of independent values
-        psList *values = psStringSplit(item->data.V, " ,;", false);
-        // Copy into the target
-        psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
-        psString valueString;
-        while ((valueString = psListGetAndIncrement(valuesIter))) {
-            psListAdd(target, PS_LIST_TAIL, valueString);
-        }
-        psFree(valuesIter);
-        psFree(values);
-    }
-    psFree(iterator);
-
-    return;
-}
-
-// Set the statistics option; for arguments
-static inline void statsOptionArguments(psMetadata *arguments, // Arguments to parse
-                                        const char *name, // Name for option
-                                        ppStatsData *data, // Configuration data
-                                        psStatsOptions option // Option to check for
-    )
-{
-    if (psMetadataLookupBool(NULL, arguments, name)) {
-        data->stats->options |= option;
-        data->doStats = true;
-    }
-    return;
-}
-
-// Print out what we're going to do, from the list
-static void checkList(psList *list,     // List
-                      const char *name  // Name of list
-    )
-{
-    psString value;
-    psListIterator *iterator = psListIteratorAlloc(list, PS_LIST_HEAD, false);
-    while ((value = psListGetAndIncrement(iterator))) {
-        printf("%s: %s\n", name, value);
-    }
-    psFree(iterator);
-    return;
-}
-
-
-ppStatsData *ppStatsSetup(pmConfig *config // Configuration
-    )
-{
-    // Setup and parse command-line arguments
-    psMetadata *arguments = config->arguments; // Arguments
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-chip", PS_META_DUPLICATE_OK, "Chip to inspect", NULL);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-cell", PS_META_DUPLICATE_OK, "Cell to inspect", NULL);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-header", PS_META_DUPLICATE_OK, "Header to look up", NULL);
-    psMetadataAddStr(arguments, PS_LIST_TAIL, "-concept", PS_META_DUPLICATE_OK, "Concept to look up", NULL);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-mean", 0, "Calculate sample mean", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-stdev", 0, "Calculate sample standard deviation", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-median", 0, "Calculate sample median", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-quartile", 0, "Calculate sample quartiles", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-robust-median", 0, "Calculate robust median", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-robust-stdev", 0, "Calculate robust standard deviation", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-robust-quartile", 0, "Calculate robust quartile range", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-fitted-mean", 0, "Calculate fitted mean", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-fitted-stdev", 0, "Calculate fitted standard deviation", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-clipped-mean", 0, "Calculate clipped median", false);
-    psMetadataAddBool(arguments, PS_LIST_TAIL, "-clipped-stdev", 0, "Calculate clipped standard deviation", false);
-    psMetadataAddS32(arguments, PS_LIST_TAIL, "-iter", 0, "Clipping iterations", 0);
-    psMetadataAddF32(arguments, PS_LIST_TAIL, "-rej", 0, "Clipping level", 0.0);
-    psMetadataAddF32(arguments, PS_LIST_TAIL, "-sample", 0, "Sampling fraction", 0.0);
-
-    if (*config->argc == 1) {
-        // No command-line arguments: print the help
-        usageAndDie(config);
-    }
-    if (!psArgumentParse(arguments, config->argc, config->argv) ||
-        (*config->argc != 2 && *config->argc != 3)) {
-        printf("Unable to parse command-line arguments.\n\n");
-        usageAndDie(config);
-    }
-
-    // Parse the command-line options
-    ppStatsData *data = ppStatsDataAlloc(); // The data
-    data->inName = config->argv[1];
-    // Output filename is optional
-    if (*config->argc == 3) {
-        data->outName = config->argv[2];
-    }
-
-    listFromArguments(arguments, "Chip", "-chip", data->chips);
-    listFromArguments(arguments, "Cell", "-cell", data->cells);
-    listFromArguments(arguments, "Header", "-header", data->headers);
-    listFromArguments(arguments, "Concept", "-concept", data->concepts);
-
-    // Set the statistics options
-    statsOptionArguments(arguments, "-mean", data,     PS_STAT_SAMPLE_MEAN);
-    statsOptionArguments(arguments, "-stdev", data,    PS_STAT_SAMPLE_STDEV);
-    statsOptionArguments(arguments, "-median", data,   PS_STAT_SAMPLE_MEDIAN);
-    statsOptionArguments(arguments, "-quartile", data, PS_STAT_SAMPLE_QUARTILE);
-    statsOptionArguments(arguments, "-robust-median", data,   PS_STAT_ROBUST_MEDIAN);
-    statsOptionArguments(arguments, "-robust-stdev", data,    PS_STAT_ROBUST_STDEV);
-    statsOptionArguments(arguments, "-robust-quartile", data, PS_STAT_ROBUST_QUARTILE);
-    statsOptionArguments(arguments, "-fitted-mean", data,   PS_STAT_FITTED_MEAN);
-    statsOptionArguments(arguments, "-fitted-stdev", data,  PS_STAT_FITTED_STDEV);
-    statsOptionArguments(arguments, "-clipped-mean", data,  PS_STAT_CLIPPED_MEAN);
-    statsOptionArguments(arguments, "-clipped-stdev", data, PS_STAT_CLIPPED_STDEV);
-    data->stats->clipSigma = psMetadataLookupF32(NULL, arguments, "-rej");
-    data->stats->clipIter = psMetadataLookupS32(NULL, arguments, "-iter");
-    data->sample = psMetadataLookupF32(NULL, arguments, "-sample");
-
-
-    // Open the input file, determine the camera
-    {
-        data->inFile = psFitsOpen(data->inName, "r");
-        if (!data->inFile) {
-            psError(PS_ERR_IO, false, "Unable to open input file %s\n", data->inName);
-            goto die;
-        }
-        psMetadata *header = psFitsReadHeader(NULL, data->inFile); // The FITS (primary) header
-        psMetadata *format = pmConfigCameraFormatFromHeader(config, header);
-        if (!format) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to determine camera format for %s\n", data->inName);
-            psFree(header);
-            goto die;
-        }
-        data->inFPA = pmFPAConstruct(config->camera);
-        if (!data->inFPA) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to construct FPA for %s\n", data->inName);
-            psFree(header);
-            psFree(format);
-            goto die;
-        }
-        pmFPAview *view = pmFPAAddSourceFromHeader(data->inFPA, header, format);
-        psFree(header);
-        psFree(format);
-        if (!view) {
-            psError(PS_ERR_UNKNOWN, false, "Unable to add input file %s to FPA.\n", data->inName);
-            goto die;
-        }
-        psFree(view);
-    }
-
-    // Open the output file
-    if (data->outName && strlen(data->outName) > 0) {
-        data->outFile = fopen(data->outName, "w");
-        if (!data->outFile) {
-            psError(PS_ERR_IO, false, "Unable to open output file %s\n", data->outName);
-            goto die;
-        }
-    } else {
-        data->outFile = stdout;
-    }
-
-    // Determine recipe parameters
-    bool mdok;                          // Status of MD lookup
-    psMetadata *recipe = psMetadataLookupMD(&mdok, config->recipes, RECIPENAME);
-    if (!mdok || !recipe) {
-        psLogMsg(__func__, PS_LOG_WARN, "Unable to find recipe %s.\n", RECIPENAME);
-        return data;
-    }
-
-    listFromRecipe(recipe, "CHIP", data->chips);
-    listFromRecipe(recipe, "CELL", data->cells);
-    listFromRecipe(recipe, "HEADER", data->headers);
-    listFromRecipe(recipe, "CONCEPT", data->concepts);
-
-    // Parse the statistics options
-    psList *recipeStats = psListAlloc(NULL);
-    listFromRecipe(recipe, "STAT", recipeStats);
-    if (psListLength(recipeStats) > 0) {
-        psListIterator *iterator = psListIteratorAlloc(recipeStats, PS_LIST_HEAD, false);
-        psString stat;
-
-
-        #define CHECK_STAT(NAME, SYMBOL) \
-        if (strcasecmp(stat, NAME) == 0) { \
-            data->stats->options |= SYMBOL; \
-            data->doStats = true; \
-        }
-
-        while ((stat = psListGetAndIncrement(iterator))) {
-            // This might look a little weird if automatically formated,
-            // but it's legal C once the pre-processing has been done, and
-            // it reads a lot better than a whole heap of "if-then-else" statements.
-            CHECK_STAT("MEAN",     PS_STAT_SAMPLE_MEAN) else
-            CHECK_STAT("STDEV",    PS_STAT_SAMPLE_STDEV) else
-            CHECK_STAT("MEDIAN",   PS_STAT_SAMPLE_MEDIAN) else
-            CHECK_STAT("QUARTILE", PS_STAT_SAMPLE_QUARTILE) else
-            CHECK_STAT("SAMPLE_MEAN",     PS_STAT_SAMPLE_MEAN) else
-            CHECK_STAT("SAMPLE_STDEV",    PS_STAT_SAMPLE_STDEV) else
-            CHECK_STAT("SAMPLE_MEDIAN",   PS_STAT_SAMPLE_MEDIAN) else
-            CHECK_STAT("SAMPLE_QUARTILE", PS_STAT_SAMPLE_QUARTILE) else
-            CHECK_STAT("ROBUST",          PS_STAT_ROBUST_MEDIAN) else
-            CHECK_STAT("ROBUST_MEDIAN",   PS_STAT_ROBUST_MEDIAN) else
-            CHECK_STAT("ROBUST_STDEV",    PS_STAT_ROBUST_STDEV) else
-            CHECK_STAT("ROBUST_QUARTILE", PS_STAT_ROBUST_QUARTILE) else
-            CHECK_STAT("FITTED",       PS_STAT_FITTED_MEAN) else
-            CHECK_STAT("FITTED_MEAN",  PS_STAT_FITTED_MEAN) else
-            CHECK_STAT("FITTED_STDEV", PS_STAT_ROBUST_STDEV) else
-            CHECK_STAT("CLIPPED",       PS_STAT_CLIPPED_MEAN) else
-            CHECK_STAT("CLIPPED_MEAN",  PS_STAT_CLIPPED_MEAN) else
-            CHECK_STAT("CLIPPED_STDEV", PS_STAT_CLIPPED_STDEV) else {
-                psLogMsg(__func__, PS_LOG_WARN, "Can't interpret STATS entry in recipe: "
-                         "%s --- ignored.\n", stat);
-            }
-        }
-    }
-    psFree(recipeStats);
-
-   // Clipping options
-    if (data->stats->clipIter == 0 && isnan(data->stats->clipSigma)) {
-        int iter = psMetadataLookupS32(&mdok, recipe, "ITER"); // Number of clipping iterations
-        if (mdok && iter > 0) {
-            data->stats->clipIter = iter;
-        } else {
-            psLogMsg(__func__, PS_LOG_WARN, "ITER in recipe is not of type S32 and positive --- "
-                     "retaining default.\n");
-        }
-        float rej = psMetadataLookupF32(&mdok, recipe, "REJ"); // Clipping level
-        if (mdok && rej > 0) {
-            data->stats->clipSigma = rej;
-        } else {
-            psLogMsg(__func__, PS_LOG_WARN, "REJ in recipe is not of type F32 and positive --- "
-                     "retaining default.\n");
-        }
-    }
-
-    if (data->sample == 0) {
-        float sample = psMetadataLookupF32(&mdok, recipe, "SAMPLE"); // Sample fraction
-        if (mdok && sample > 0) {
-            data->sample = sample;
-        } else {
-            psLogMsg(__func__, PS_LOG_WARN, "SAMPLE in recipe is not of type F32 and positive --- "
-                     "retaining default.\n");
-        }
-    }
-
-    psMaskType maskVal = psMetadataLookupU8(&mdok, recipe, "MASKVAL"); // Mask value
-    if (mdok) {
-        data->maskVal = maskVal;
-    } else {
-        psLogMsg(__func__, PS_LOG_WARN, "ITER in recipe is not of type U8 --- retaining default.\n");
-    }
-
-    // Print out what we're going to do
-    if (psTraceGetLevel(__func__) > 9) {
-        checkList(data->chips, "CHIP");
-        checkList(data->cells, "CELL");
-        checkList(data->headers, "HEADER");
-        checkList(data->concepts, "CONCEPT");
-    }
-
-    return data;
-
-    // Common path for error conditions: clean up and exit.
-die:
-    psFree(config);
-    psFree(data);
-    pmConceptsDone();
-    pmConfigDone();
-    psLibFinalize();
-    exit(EXIT_FAILURE);
-}
