IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 19928


Ignore:
Timestamp:
Oct 6, 2008, 12:24:10 PM (18 years ago)
Author:
Paul Price
Message:

Don't put statistics on an FPA: too troublesome to get to, and it's ok to just carry around a psMetadata in ppImageLoop, passing it to functions that need it. Updated times for output statistics.

Location:
trunk/ppImage/src
Files:
1 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppImage/src/Makefile.am

    r19584 r19928  
    2323        ppImageAstrom.c \
    2424        ppImageAddstar.c \
    25         ppImageStats.c \
    2625        ppImageStatsOutput.c \
    2726        ppImagePixelStats.c \
     
    5352        ppImageAstrom.c \
    5453        ppImageAddstar.c \
    55         ppImageStats.c \
    5654        ppImageStatsOutput.c \
    5755        ppImagePixelStats.c \
  • trunk/ppImage/src/ppFocus.c

    r9738 r19928  
    99    psLibInit(NULL);
    1010
    11     psTimerStart(TIMERNAME);
     11    psTimerStart(TIMER_TOTAL);
    1212
    1313    // Parse the configuration and arguments
     
    6060    ppFocusFitFWHM (config, focus, fwhm);
    6161
    62     psLogMsg ("ppFocus", 3, "complete ppFocus run: %f sec\n", psTimerMark (TIMERNAME));
     62    psLogMsg ("ppFocus", 3, "complete ppFocus run: %f sec\n", psTimerMark (TIMER_TOTAL));
    6363
    6464    // Cleaning up
  • trunk/ppImage/src/ppImage.c

    r14000 r19928  
    99    psLibInit(NULL);
    1010
    11     psTimerStart(TIMERNAME);
     11    psTimerStart(TIMER_TOTAL);
    1212
    1313    // Parse the configuration and arguments
     
    3838    }
    3939
    40     psLogMsg ("ppImage", 3, "Complete ppImage run: %f sec\n", psTimerMark(TIMERNAME));
     40    psLogMsg("ppImage", PS_LOG_INFO, "Complete ppImage run: %f sec\n", psTimerMark(TIMER_TOTAL));
    4141
    4242    // Cleaning up
  • trunk/ppImage/src/ppImage.h

    r18724 r19928  
    1717
    1818#define RECIPE_NAME "PPIMAGE"           // Name of the recipe to use
    19 #define TIMERNAME "ppImage"             // Name of timer
     19#define TIMER_TOTAL   "PPIMAGE.TOTAL"   // Name of timer for total time
     20#define TIMER_DETREND "PPIMAGE.DETREND" // Name of timer for detrend time
     21#define TIMER_PHOT    "PPIMAGE.PHOT"    // Name of timer for photometry time
    2022
    2123// Options for ppImage processing
     
    151153bool ppImageDefineFile (pmConfig *config, pmFPA *input, char *filerule, char *argname, pmFPAfileType fileType, pmDetrendType detrendType);
    152154
    153 // calculate stats, including MD5
    154 bool ppImageStats (pmConfig *config, pmChip *chip, const pmFPAview *inputView, const ppImageOptions *options);
    155 
    156155// write stats to output file
    157 bool ppImageStatsOutput (pmConfig *config, const ppImageOptions *options);
     156bool ppImageStatsOutput(pmConfig *config, // Configuration
     157                        psMetadata *stats, // Statistics output
     158                        const ppImageOptions *options // Options
     159    );
    158160
    159161
     
    197199
    198200// calculate stats, including MD5
    199 bool ppImagePixelStats (pmConfig *config, const ppImageOptions *options, const pmFPAview *inputView);
     201bool ppImagePixelStats(pmConfig *config,// Configuration
     202                       psMetadata *stats, // Statistics output
     203                       const ppImageOptions *options, // Options
     204                       const pmFPAview *inputView // View to data
     205    );
    200206
    201207// calculate stats from headers and concepts
    202 bool ppImageMetadataStats (pmConfig *config, const ppImageOptions *options);
    203 
    204 void ppImageFileCheck (pmConfig *config);
     208bool ppImageMetadataStats(pmConfig *config, // Configuration
     209                          psMetadata *stats, // Statistics output
     210                          const ppImageOptions *options // Options
     211    );
     212
     213void ppImageFileCheck(pmConfig *config);
    205214
    206215/// Dump memory summary to text file
  • trunk/ppImage/src/ppImageCleanup.c

    r18032 r19928  
    2323    // fprintf (stderr, "Found %d leaks at %s\n", Nleaks, "ppImage");
    2424
    25     fprintf (stderr, "Found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "ppImage");
     25    fprintf(stderr, "Found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "ppImage");
    2626
    2727    return;
  • trunk/ppImage/src/ppImageLoop.c

    r19399 r19928  
    55#include "ppImage.h"
    66
    7 # define ESCAPE(MESSAGE) { \
     7#define ESCAPE(MESSAGE) { \
    88  psError(PS_ERR_UNKNOWN, false, MESSAGE); \
    9   psFree (view); \
     9  psFree(view); \
    1010  return false; \
    1111}
    1212
    13 bool ppImageLoop (pmConfig *config, ppImageOptions *options)
     13bool ppImageLoop(pmConfig *config, ppImageOptions *options)
    1414{
    15     bool status;
    16     pmChip *chip;
    17     pmCell *cell;
    18     pmReadout *readout;
    19 
    20     // measure the total elapsed time in ppImageLoop.
    21     psTimerStart ("ppImageLoop");
    22 
     15    psMetadata *stats = options->doStats ? psMetadataAlloc() : NULL; // Statistics to output
     16    float timeDetrend = 0;              // Amount of time spent in detrend
     17    float timePhot = 0;                 // Amount of time spent in photometry
     18
     19    bool status;                        // Status of MD lookup
    2320    pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "PPIMAGE.INPUT");
    2421    if (!status) {
     
    4037
    4138    // files associated with the science image
    42     if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) ESCAPE ("load failure for FPA");
    43 
     39    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     40        ESCAPE("load failure for FPA");
     41    }
     42
     43    pmChip *chip;                       // Chip from FPA
    4444    while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) {
    4545        psLogMsg ("ppImageLoop", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
     
    4747            continue;
    4848        }
    49         if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) ESCAPE ("load failure for Chip");
    50 
     49        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     50            ESCAPE("load failure for Chip");
     51        }
     52
     53        psTimerStart(TIMER_DETREND);
     54        pmCell *cell;                   // Cell from chip
    5155        while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
    5256            psLogMsg ("ppImageLoop", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
     
    5458                continue;
    5559            }
    56             if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) ESCAPE ("load failure for Cell");
     60            if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     61                ESCAPE("load failure for Cell");
     62            }
    5763
    5864            // Put version information into the header
     
    7076
    7177            // process each of the readouts
     78            pmReadout *readout;         // Readout from cell
    7279            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
    73                 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) ESCAPE ("load failure for Readout");
     80                if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     81                    ESCAPE("load failure for Readout");
     82                }
    7483                if (!readout->data_exists) {
    7584                    continue;
     
    7887                // XXX set the options->*Mask values here (after the mask images have been loaded
    7988                // and before any of the value are used)
    80                 if (!ppImageSetMaskBits (config, options))
    81                     ESCAPE ("Unable to set bit masks");
     89                if (!ppImageSetMaskBits(config, options)) {
     90                    ESCAPE("Unable to set bit masks");
     91                }
    8292
    8393                // perform the detrend analysis
    84                 if (!ppImageDetrendReadout(config, options, view))
    85                     ESCAPE ("Unable to detrend readout");
     94                if (!ppImageDetrendReadout(config, options, view)) {
     95                    ESCAPE("Unable to detrend readout");
     96                }
    8697            }
    8798        }
     
    89100        // Apply the fringe correction
    90101        if (options->doFringe) {
    91             if (!ppImageDetrendFringeApply (config, chip, view, options))
    92                 ESCAPE ("Unable to defringe");
     102            if (!ppImageDetrendFringeApply(config, chip, view, options)) {
     103                ESCAPE("Unable to defringe");
     104            }
    93105        }
    94106
    95107        // measure various statistics for this image
    96         if (!ppImagePixelStats (config, options, view))
    97             ESCAPE ("Unable to measures stats for image");
    98 
    99         if (!ppImageMosaicChip(config, options, view, "PPIMAGE.CHIP", "PPIMAGE.OUTPUT"))
    100             ESCAPE ("Unable to mosaic chip");
     108        if (!ppImagePixelStats(config, stats, options, view)) {
     109            ESCAPE("Unable to measures stats for image");
     110        }
     111        if (!ppImageMosaicChip(config, options, view, "PPIMAGE.CHIP", "PPIMAGE.OUTPUT")) {
     112            ESCAPE("Unable to mosaic chip");
     113        }
     114        timeDetrend += psTimerClear(TIMER_DETREND);
     115
    101116
    102117        // we perform photometry on the readouts of this chip in the output
     118        psTimerStart(TIMER_PHOT);
    103119        if (options->doPhotom) {
    104             if (!ppImagePhotom(config, view)) ESCAPE ("error running photometry.");
    105         }
     120            if (!ppImagePhotom(config, view)) {
     121                ESCAPE("error running photometry.");
     122            }
     123        }
     124        timePhot += psTimerClear(TIMER_PHOT);
    106125
    107126        // replace the masked pixels with the background level
    108127        if (options->replaceMasked) {
    109             if (!ppImageReplaceBackground (config, view, options))
    110                 ESCAPE ("Unable to replace masked pixels with background level");
     128            if (!ppImageReplaceBackground(config, view, options)) {
     129                ESCAPE("Unable to replace masked pixels with background level");
     130            }
    111131        }
    112132
    113133        // binning (used for display) must take place after the background is replaced, if desired
    114         if (!ppImageRebinChip(config, view, options, "PPIMAGE.BIN1"))
    115             ESCAPE ("Unable to bin chip (level 1).");
    116 
    117         if (!ppImageRebinChip(config, view, options, "PPIMAGE.BIN2"))
    118             ESCAPE ("Unable to bin chip (level 2).");
     134        if (!ppImageRebinChip(config, view, options, "PPIMAGE.BIN1")) {
     135            ESCAPE("Unable to bin chip (level 1).");
     136        }
     137        if (!ppImageRebinChip(config, view, options, "PPIMAGE.BIN2")) {
     138            ESCAPE("Unable to bin chip (level 2).");
     139        }
    119140
    120141        // Close cells (XXX shouldn't pmFPAfileClose iterate down as needed?)
     
    124145                continue;
    125146            }
    126             if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) ESCAPE ("save failure for Cell");
     147            if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     148                ESCAPE("save failure for Cell");
     149            }
    127150        }
    128151
    129152        // Close chip
    130         if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) ESCAPE ("save failure for Chip");
     153        if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     154            ESCAPE("save failure for Chip");
     155        }
    131156    }
    132157
    133158    // generate the full-scale FPA mosaic
    134     if (!ppImageMosaicFPA(config, options, "PPIMAGE.OUTPUT.FPA1", "PPIMAGE.BIN1")) ESCAPE ("failure in FPA Mosaic (level 1)");
    135     if (!ppImageMosaicFPA(config, options, "PPIMAGE.OUTPUT.FPA2", "PPIMAGE.BIN2")) ESCAPE ("failure in FPA Mosaic (level 2)");
     159    if (!ppImageMosaicFPA(config, options, "PPIMAGE.OUTPUT.FPA1", "PPIMAGE.BIN1")) {
     160        ESCAPE("failure in FPA Mosaic (level 1)");
     161    }
     162    if (!ppImageMosaicFPA(config, options, "PPIMAGE.OUTPUT.FPA2", "PPIMAGE.BIN2")) {
     163        ESCAPE("failure in FPA Mosaic (level 2)");
     164    }
    136165
    137166    // we perform astrometry on all chips after sources have been detected
    138167    // this also performs the psastro file IO
    139168    if (options->doAstromChip || options->doAstromMosaic) {
    140         if (!ppImageAstrom(config)) ESCAPE ("error running astrometry.");
     169        if (!ppImageAstrom(config)) {
     170            ESCAPE("error running astrometry.");
     171        }
    141172    }
    142173
    143174    if (psTraceGetLevel("ppImage") >= 3) {
    144         ppImageFileCheck (config);
     175        ppImageFileCheck(config);
    145176    }
    146177
    147178    // Write out summary statistics
    148     if (!ppImageMetadataStats (config, options)) ESCAPE ("Unable to write statistics file.");
     179    if (!ppImageMetadataStats(config, stats, options)) {
     180        ESCAPE("Unable to write statistics file.");
     181    }
     182
     183    // Output and Close FPA
     184    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     185        ESCAPE("save failure for FPA");
     186    }
     187
     188    psFree(view);
    149189
    150190    // Write out summary statistics
    151     if (!ppImageStatsOutput (config, options)) ESCAPE ("Unable to write statistics file.");
    152 
    153     // Output and Close FPA
    154     if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) ESCAPE ("save failure for FPA");
    155 
    156     psFree(view);
     191    if (options->doStats) {
     192        psMetadataAddF32(stats, PS_LIST_TAIL, "DT_DET", 0, "Time spent detrending (sec)", timeDetrend);
     193        psMetadataAddF32(stats, PS_LIST_TAIL, "DT_PHOT", 0, "Time spent photometering (sec)", timePhot);
     194        psMetadataAddF32(stats, PS_LIST_TAIL, "DT_TOTAL", 0, "Total time (sec)", psTimerMark(TIMER_TOTAL));
     195        if (!ppImageStatsOutput(config, stats, options)) {
     196            ESCAPE("Unable to write statistics file.");
     197        }
     198    }
     199
    157200    return true;
    158201}
  • trunk/ppImage/src/ppImageMetadataStats.c

    r18556 r19928  
    66
    77// calculate stats from headers and concepts
    8 bool ppImageMetadataStats (pmConfig *config, const ppImageOptions *options) {
     8bool ppImageMetadataStats(pmConfig *config, psMetadata *stats, const ppImageOptions *options)
     9{
     10    bool mdok;              // Status of MD lookup
    911
    10     bool mdok;              // Status of MD lookup
    11    
    1212    if (!options->doStats) {
    13         return true;
     13        return true;
    1414    }
    1515
     
    2020
    2121    if (!outImage && !outPhotom && !outAstrom) {
    22         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find any output file (PPIMAGE.OUTPUT, PSPHOT.OUTPUT, PSASTRO.OUTPUT).");
    23         return false;
     22        psError(PS_ERR_UNEXPECTED_NULL, true,
     23                "Unable to find any output file (PPIMAGE.OUTPUT, PSPHOT.OUTPUT, PSASTRO.OUTPUT).");
     24        return false;
    2425    }
    2526
     
    2728    pmFPAfile *output = outAstrom;
    2829    if (!output) {
    29         output = outPhotom;
     30        output = outPhotom;
    3031    }
    3132    if (!output) {
    32         output = outImage;
     33        output = outImage;
    3334    }
    3435
    35     // select or create the fpa-level analysis stats metadata for PPIMAGE.OUTPUT:
    36     psMetadata *stats = psMetadataLookupPtr (&mdok, outImage->fpa->analysis, "PPIMAGE.STATS");
    37     psMemIncrRefCounter (stats);
    38     if (!stats) {
    39         stats = psMetadataAlloc ();
    40         if (!psMetadataAdd (outImage->fpa->analysis, PS_LIST_TAIL, "PPIMAGE.STATS", PS_DATA_METADATA, "stats container", stats)) {
    41             psError(PS_ERR_UNKNOWN, false, "Unable to push stats on fpa.analysis.");
    42             psFree (stats);
    43             return false;
    44         }
    45     }
    46 
    47     // extract stats for the complete fpa
     36    // extract stats for the complete fpa
    4837    pmFPAview *view = pmFPAviewAlloc(0);
    49 
    5038    if (!ppStatsMetadata(stats, output->fpa, view, options->maskValue, config)) {
    51         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate stats for image.");
    52         psFree(view);
    53         psFree(stats);
    54         return false;
     39        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate stats for image.");
     40        psFree(view);
     41        return false;
    5542    }
    5643
    5744    psFree(view);
    58     psFree(stats);
    5945    return true;
    6046}
  • trunk/ppImage/src/ppImagePixelStats.c

    r18556 r19928  
    66
    77// calculate stats, including MD5
    8 bool ppImagePixelStats (pmConfig *config, const ppImageOptions *options, const pmFPAview *inputView) {
    9 
     8bool ppImagePixelStats(pmConfig *config, psMetadata *stats, const ppImageOptions *options,
     9                       const pmFPAview *inputView)
     10{
    1011    bool mdok;              // Status of MD lookup
    1112
     
    1314    pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
    1415    *view = *inputView;
    15    
     16
    1617    // perform the analysis of for this FPA
    1718    pmFPAfile *output = psMetadataLookupPtr(&mdok, config->files, "PPIMAGE.OUTPUT");
    1819    if (!output) {
    19         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find output file (PPIMAGE.OUTPUT).");
    20         psFree (view);
    21         return false;
     20        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find output file (PPIMAGE.OUTPUT).");
     21        psFree(view);
     22        return false;
    2223    }
    2324
    2425    // select the corresponding chip
    25     pmChip *chip = pmFPAviewThisChip (view, output->fpa);
     26    pmChip *chip = pmFPAviewThisChip(view, output->fpa);
    2627    if (!chip) {
    27         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find requested chip.");
    28         psFree (view);
    29         return false;
     28        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find requested chip.");
     29        psFree(view);
     30        return false;
    3031    }
    31    
     32
    3233    // Perform statistics for this chip
    3334    if (options->doStats) {
     35        if (!ppStatsPixels(stats, output->fpa, view, options->maskValue, config)) {
     36            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate stats for image.");
     37            psFree(view);
     38            return false;
     39        }
    3440
    35         // select or create the fpa-level analysis stats metadata (save on PPIMAGE.OUPUT:PPIMAGE.STATS)
    36         psMetadata *stats = psMetadataLookupPtr (&mdok, output->fpa->analysis, "PPIMAGE.STATS");
    37         psMemIncrRefCounter (stats);
    38         if (!stats) {
    39             stats = psMetadataAlloc ();
    40             if (!psMetadataAdd (output->fpa->analysis, PS_LIST_TAIL, "PPIMAGE.STATS", PS_DATA_METADATA, "stats container", stats)) {
    41                 psError(PS_ERR_UNKNOWN, false, "Unable to push stats on fpa.analysis.");
    42                 psFree (view);
    43                 psFree (stats);
    44                 return false;
    45             }
    46         }
     41        // extract the fringe amplitude from the analysis
     42        if (options->doFringe && !ppStatsFringe(stats, chip, "FRINGE", "FRINGE.SOLUTION")) {
     43            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to extract fringe solution for image.");
     44            psFree(view);
     45            return false;
     46        }
    4747
    48         if (!ppStatsPixels(stats, output->fpa, view, options->maskValue, config)) {
    49             psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate stats for image.");
    50             psFree (view);
    51             psFree (stats);
    52             return false;
    53         }
    54 
    55         // extract the fringe amplitude from the analysis
    56         if (options->doFringe && !ppStatsFringe(stats, chip, "FRINGE", "FRINGE.SOLUTION")) {
    57             psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to extract fringe solution for image.");
    58             psFree (view);
    59             psFree (stats);
    60             return false;
    61         }
    62 
    63         // extract the fringe residual amplitude from the analysis
    64         if (options->doFringe && !ppStatsFringe(stats, chip, "FRINGE_RESID", "FRINGE.RESIDUAL.SOLUTION")) {
    65             psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to extract fringe solution for image.");
    66             psFree (view);
    67             psFree (stats);
    68             return false;
    69         }
    70        
    71         psFree (stats);
     48        // extract the fringe residual amplitude from the analysis
     49        if (options->doFringe && !ppStatsFringe(stats, chip, "FRINGE_RESID", "FRINGE.RESIDUAL.SOLUTION")) {
     50            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to extract fringe solution for image.");
     51            psFree(view);
     52            return false;
     53        }
    7254    }
    7355
    74     pmCell *cell = NULL;
    75     pmReadout *readout = NULL;
    7656
    7757    view->cell = view->readout = -1;
     58    pmCell *cell = NULL;                // Cell from iteration
    7859    while ((cell = pmFPAviewNextCell(view, output->fpa, 1)) != NULL) {
    79         if (!cell->process || !cell->file_exists) {
    80             continue;
    81         }
     60        if (!cell->process || !cell->file_exists) {
     61            continue;
     62        }
    8263
    83         // Add MD5 information for cell
    84         pmHDU *hdu = pmHDUFromCell(cell); // HDU that owns the cell
    85         while ((readout = pmFPAviewNextReadout(view, output->fpa, 1)) != NULL) {
    86             const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
    87             const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
     64        // Add MD5 information for cell
     65        pmHDU *hdu = pmHDUFromCell(cell); // HDU that owns the cell
     66        pmReadout *readout = NULL;      // Readout from iteration
     67        while ((readout = pmFPAviewNextReadout(view, output->fpa, 1)) != NULL) {
     68            const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
     69            const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
    8870
    89             psString headerName = NULL; // Header name for MD5
    90             psStringAppend(&headerName, "MD5_%s_%s_%d", chipName, cellName, view->readout);
     71            psString headerName = NULL; // Header name for MD5
     72            psStringAppend(&headerName, "MD5_%s_%s_%d", chipName, cellName, view->readout);
    9173
    92             psVector *md5 = psImageMD5(readout->image); // md5 hash
    93             psString md5string = psMD5toString(md5); // String
    94             psFree (md5);
    95             psMetadataAddStr(hdu->header, PS_LIST_TAIL, headerName, PS_META_REPLACE,
    96                              "Image MD5", md5string);
    97             psFree (md5string);
    98             psFree (headerName);
    99         }
     74            psVector *md5 = psImageMD5(readout->image); // md5 hash
     75            psString md5string = psMD5toString(md5); // String
     76            psFree(md5);
     77            psMetadataAddStr(hdu->header, PS_LIST_TAIL, headerName, PS_META_REPLACE, "Image MD5", md5string);
     78            psFree(md5string);
     79            psFree(headerName);
     80        }
    10081    }
    10182
  • trunk/ppImage/src/ppImageStatsOutput.c

    r18069 r19928  
    66
    77// write stats to output file
    8 bool ppImageStatsOutput (pmConfig *config, const ppImageOptions *options) {
    9 
     8bool ppImageStatsOutput(pmConfig *config, psMetadata *stats, const ppImageOptions *options)
     9{
    1010    bool mdok;
    1111
    1212    // measure statistics, or ignore?
    13     if (!options->doStats) return true;
    14 
    15     // PPIMAGE.STATS is stored on PPIMAGE.OUTPUT
    16     pmFPAfile *output = psMetadataLookupPtr(&mdok, config->files, "PPIMAGE.OUTPUT");
    17     if (!output) {
    18         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find PPIMAGE.OUTPUT entry in config file.\n");
    19         return false;
    20     }
    21 
    22     // select the fpa-level analysis stats metadata:
    23     psMetadata *stats = psMetadataLookupPtr (&mdok, output->fpa->analysis, "PPIMAGE.STATS");
    24     if (!stats) {
    25         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find PPIMAGE.STATS entry in output fpa analysis.\n");
    26         return false;
    27     }
    28 
    29     // convert the stats MDC to a string
    30     char *statsMDC = psMetadataConfigFormat(stats);
    31     if (!statsMDC || strlen(statsMDC) == 0) {
    32         psError(PS_ERR_IO, false, "Unable to serialize stats metadata.\n");
    33         return false;
     13    if (!options->doStats) {
     14        return true;
    3415    }
    3516
     
    3718    const char *statsName = psMetadataLookupStr(&mdok, config->arguments, "STATS"); // Filename for statistics
    3819    if (!statsName && !strlen(statsName)) {
    39         psError (PS_ERR_UNEXPECTED_NULL, false, "missing STATS entry in arguments list.");
    40         psFree(statsMDC);
     20        psError(PS_ERR_UNEXPECTED_NULL, false, "missing STATS entry in arguments list.");
    4121        return false;
    4222    }
    4323
    44     // convert to a real UNIX filename
     24    // Write out
    4525    psString resolved = pmConfigConvertFilename(statsName, config, true, true); // Resolved filename
    46     FILE *statsFile = fopen (resolved, "w");
    47     if (!statsFile) {
    48         psError(PS_ERR_IO, true, "Unable to open statistics file %s for writing.\n", resolved);
    49         psFree(statsMDC);
     26    if (!psMetadataConfigWrite(stats, resolved)) {
     27        psError(PS_ERR_IO, false, "Unable to serialize stats metadata.\n");
    5028        psFree(resolved);
    5129        return false;
     
    5331    psFree(resolved);
    5432
    55     // write the stats MDC to a file
    56     // XXX why does this not call psMetadataConfigPrint?
    57     fprintf(statsFile, "%s", statsMDC);
    58 
    59     psFree(statsMDC);
    60     fclose(statsFile);
    6133    return true;
    6234}
Note: See TracChangeset for help on using the changeset viewer.