IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 7061


Ignore:
Timestamp:
May 3, 2006, 5:57:35 PM (20 years ago)
Author:
Paul Price
Message:

Code coming together, doesn't yet compile

Location:
trunk/ppMerge/src
Files:
5 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppMerge/src

    • Property svn:ignore set to
      .deps
      Makefile
      Makefile.in
  • trunk/ppMerge/src/Makefile.am

    r6904 r7061  
    44ppImage_LDADD = $(PSLIB_LIBS) $(PSMODULE_LIBS)
    55ppImage_SOURCES = \
    6         ppConfig.c \
    7         ppFile.c \
    8         ppMem.c \
    9         ppImage.c \
    10         ppImageConfig.c \
    11         ppImageData.c \
    12         ppImageDetrendBias.c \
    13         ppImageDetrendCell.c \
    14         ppImageDetrendMask.c \
    15         ppImageDetrendNonLinear.c \
    16         ppImageLoop.c \
    17         ppImageOptions.c \
    18         ppImageParseCamera.c \
    19         ppImageParseDetrend.c \
    20         ppImageWeights.c
    21 #       ppImageLoadPixels.c
    22 #       ppDetrendFlat.c
    23 #       ppImageOutput.c
    24 #       ppImageDetrendPedestal.c
    25 #       ppImageOutput.c
    26 #       ppImagePhot.c
     6        ppMerge.c               \
     7        ppMergeBackground.c     \
     8        ppMergeCheckInputs.c    \
     9        ppMergeCombine.c        \
     10        ppMergeConfig.c         \
     11        ppMergeData.c           \
     12        ppMergeOptions.c
    2713
    2814
    2915noinst_HEADERS = \
    30         ppConfig.h \
    31         ppFile.h \
    32         ppMem.h \
    33         ppImage.h \
    34         ppImageData.h \
    35         ppImageDetrend.h \
    36         ppImageOptions.h
     16        ppMerge.h               \
     17        ppMergeBackground.h     \
     18        ppMergeCheckInputs.h    \
     19        ppMergeCombine.h        \
     20        ppMergeConfig.h         \
     21        ppMergeData.h           \
     22        ppMergeOptions.h
    3723
    3824clean-local:
  • trunk/ppMerge/src/ppMerge.c

    r6903 r7061  
    11#include <stdio.h>
    2 #include "pslib.h"
    3 #include "pmConcepts.h"
     2#include <pslib.h>
     3#include <psmodules.h>
     4
    45#include "ppMerge.h"
    56#include "ppMem.h"
     
    1314
    1415    // Parse the configuration and arguments
    15     ppImageConfig(config, argc, argv);
    16 
    17     // Open the input image, output image, output mask
    18     // Get camera configuration from header if not already defined
     16    // Open the input image(s)
     17    // Determine camera, format from header if not already defined
    1918    // Construct camera in preparation for reading
    20     ppImageParseCamera(data, config);
     19    pmConfig *config = ppMergeConfig(&argc, argv);
    2120
    2221    // Set various tasks (define optional operations)
    23     ppImageOptionsParse(data, options, config);
     22    ppMergeOptions *options = ppMergeOptionsParse(config);
    2423
    25     // open detrend images, load headers, optionally load pixels
    26     ppImageParseDetrend(data, options, config);
     24    // Check the inputs
     25    ppMergeData *data = ppMergeCheckInputs(options, config);
     26    if (!data) {
     27        psError("Not enough valid input files.\n");
     28        exit(EXIT_FAILURE);
     29    }
    2730
    28     // Image Arithmetic Loop
    29     ppImageLoop(data, options, config);
     31    // Measure the background in each image
     32    psImage *scale = NULL;              // The scalings
     33    psImage *zero = NULL;               // The zeros
     34    ppMergeScaleZero(&scale, &zero, data, options, config);
     35
     36    // Do the combination and write
     37    ppMergeCombine(scale, zero, data, options, config);
    3038
    3139    // Cleaning up
    3240    psFree(data);
     41    psFree(scale);
     42    psFree(zero);
    3343    psFree(options);
    3444    psFree(config);
     45
    3546    psTimerStop();
    3647    psTraceReset();
     48    psErrorClear();
    3749    pmConceptsDone();
     50    pmConfigDone();
     51
    3852    ppMemCheck();
    3953
  • trunk/ppMerge/src/ppMerge.h

    r5862 r7061  
    1 # include <stdio.h>
    2 # include <strings.h>
    3 # include <glob.h>
     1#ifndef PP_MERGE_H
     2#define PP_MERGE_H
    43
    5 # include "pslib.h"
     4#include <stdio.h>
     5#include <pslib.h>
     6#include <psmodules.h>
    67
    7 # include "psAdditionals.h"
     8#define RECIPE "PPMERGE"                // Name of the recipe to use
    89
    9 # include "pmAstrometry.h"
    10 # include "pmReadout.h"
    11 # include "pmConfig.h"
    12 # include "pmFPAConstruct.h"
    13 # include "pmFPARead.h"
    14 # include "pmFPAConceptsGet.h"
    15 # include "pmFPAWrite.h"
    16 
    17 # include "pmReadoutCombine.h"
    18 
    19 # define RECIPE "MERGE" // Name of the recipe to use
    20 
    21 // XXX : same as in ppImage
    22 typedef enum {
    23     PP_LOAD_NONE,
    24     PP_LOAD_FPA,
    25     PP_LOAD_CHIP,
    26     PP_LOAD_CELL,
    27 } ppImageLoadDepth;
    28 
    29 // XXX : same as in ppImage
    30 typedef struct {
    31     psMetadata *site;
    32     psMetadata *camera;
    33     psMetadata *recipe;
    34     psMetadata *arguments;
    35     psDB       *database;
    36 } ppConfig;
    37 
    38 typedef struct {
    39     char *filename;
    40     pmFPA *fpa;
    41     psFits *fits;
    42     psMetadata *header;
    43     double zero;
    44     double scale;
    45 } ppFPA;
    46 
    47 typedef struct {
    48     psArray *input;
    49     ppFPA *output;
    50     ppFPA *process;
    51     ppFPA *mask;
    52 } ppData;
    53 
    54 typedef struct {
    55     ppImageLoadDepth imageLoadDepth;
    56     bool doMask;                        // apply a pixel mask before stacking
    57     pmCombineParams *combineParams;
    58     bool applyZeroScale;
    59     double gain;
    60     double readnoise;
    61 } ppOptions;
    62 
    63 bool ppMergeConfig (ppConfig *config, int argc, char **argv);
    64 bool ppMergeLoop (ppData *data, ppOptions *options, ppConfig *config);
    65 bool ppMergeOptions (ppData *data, ppOptions *options, ppConfig *config);
    66 bool ppMergeOutput (ppData *data, ppOptions *options, ppConfig *config);
    67 bool ppMergeParseCamera (ppData *data, ppConfig *config);
    68 bool ppMergeParseDetrend (ppData *data, ppOptions *options, ppConfig *config);
    69 
    70 bool ppMergeCell (pmCell *output, pmCell *mask, psArray *cellList, ppOptions *options, ppConfig *config);
    71 
    72 // XXX : these functions are identical to the ppImage equivalents
    73 pmReadout* ppDetrendSelectFirst (pmCell *cell, char *name, bool doThis);
    74 bool ppFPAOpen (ppFPA *fpa, psMetadata *camera, char *name, bool doThis);
    75 bool ppMergeLoadPixels (ppFPA *input, ppFPA *process, psDB *db, int nChip, int nCell);
  • trunk/ppMerge/src/ppMergeBackground.c

    r7001 r7061  
    55
    66#include "ppMergeBackground.h"
     7
     8#define MAX_ITER 10                     // Maximum number of iterations for pmFlatNormalize
     9#define TOLERANCE 1e-3                  // Tolerance to reach for pmFlatNormalize
     10
    711
    812// Extract a particular statistic from the stats
     
    2933
    3034
    31 // Get the background for each chip of each input
    32 psImage *ppMergeBackground(const ppMergeOptions *options, // The options
    33                            const pmConfig *config // The configuration
     35// Get the scale and zero for each chip of each input
     36bool ppMergeScaleZero(ppImage **scales, // The scales for each integration/cell
     37                      ppImage **zeros, // The zeroes for each integration/cell
     38                      ppMergeData *data,// The data
     39                      const ppMergeOptions *options, // The options
     40                      const pmConfig *config // The configuration
    3441    )
    3542{
    3643    assert(config->camera);             // Need the camera configuration
    37     int numCells = 0;                   // Number of cells in the model FPA
    38     {
    39         // Count the cells
    40         pmFPA *fpa = pmFPAConstruct(config->camera); // The FPA
    41         psArray *chips = fpa->chips;        // Array of chips
    42         for (int i = 0; i < chips->n; i++) {
    43             pmChip *chip = chips->data[i];  // Chip of interest
    44             if (!chip) {
    45                 continue;
    46             }
    47             psArray *cells = chip->cells;   // Array of cells
    48             for (int j = 0; j < cells->n; j++) {
    49                 pmCell *cell = cells->data[j];
    50                 if (cell) {
    51                 numCells++;
    52                 }
    53             }
    54         }
    55         psFree(fpa);
    56     }
     44
    5745    psArray *filenames = psMetadataLookupPtr(NULL, config->arguments, "INPUT"); // The input file names
    5846    assert(filenames);                  // It should be here --- it's put here in ppMergeConfig
    5947
    60     psImage *background = psImageAlloc(filenames->n, numCells, PS_TYPE_F64); // Background measurements
     48    // Sanity checks
     49    assert(!options->scale || scales);
     50    assert(!scales || !*scales || ((*scales)->type.type == PS_TYPE_F64 &&
     51                                   (*scales)->numCols == data->numCells &&
     52                                   (*scales)->numRows == filenames->n));
     53    assert(!options->zero || zeros);
     54    assert(!zeros || !*zeros || ((*zeros)->type.type == PS_TYPE_F64 &&
     55                                 (*zeros)->numCols == data->numCells &&
     56                                 (*zeros)->numRows == filenames->n));
     57
     58    psImage *background = psImageAlloc(filenames->n, data->numCells, PS_TYPE_F64); // Background measurements
    6159    psImageInit(background, NAN);
    6260    psStats *bgStats = psStatsAlloc(options->background); // Statistic to measure the background
    63 
     61    psVector *gains = NULL;             // The gains for each cell
     62    psImage *exptime = NULL;            // The exposure time for each integration of each cell
     63    if (options->scale) {
     64        gains = psVectorAlloc(data->numCells, PS_TYPE_F64);
     65    }
     66    if (options->exptime) {
     67        exptime = psImageAlloc(filenames->n, data->numCells, PS_TYPE_F64);
     68    }
     69
     70    bool status = true;                 // Status of getting the scale and zero --- did everything go right?
    6471    for (int i = 0; i < filenames->n; i++) {
    6572        psString name = filenames->data[i]; // The name of the file
     
    7077        if (!inFile) {
    7178            psErrorPrint(PS_ERR_IO, false, "Unable to open input file %s --- ignored.\n", name);
     79            status = false;
    7280            continue;
    7381        }
    74         psMetadata *header = psFitsReadHeader(NULL, inFile); // The FITS (primary) header
    75         psMetadata *format = pmConfigCameraFormatFromHeader(config, header); // The camera format
    76         psFree(header);
    77         if (!format) {
    78             psErrorPrint(PS_ERR_IO, false, "Unable to identify camera format for input file %s --- "
    79                          "ignored.\n", name);
    80             continue;
    81         }
    82 
    83         pmFPA *fpa = pmFPAConstruct(config->camera); // The FPA
    84         pmFPAview *view = pmFPAAddSourceFromHeader(fpa, phu, format); // View of the PHU
    85         int cellNum = 0;                // Number of the cell
     82
     83        pmFPA *fpa = in->data[i];       // The FPA for this input
     84        int cellNum = -1;               // Number of the cell
    8685        psArray *chips = fpa->chips;    // Array of chips
    87         for (int i = 0; i < chips->n; i++) {
    88             pmChip *chip = chips->data[i]; // The chip of interest
     86        for (int j = 0; j < chips->n; j++) {
     87            pmChip *chip = chips->data[j]; // The chip of interest
    8988            if (!chip) {
    9089                continue;
    9190            }
    9291            psArray *cells = chip->cells; // Array of cells
    93             for (int j = 0; j < cells->n; j++) {
    94                 pmCell *cell = cells->data[j]; // The cell of interest
     92            for (int k = 0; k < cells->n; k++) {
     93                pmCell *cell = cells->data[k]; // The cell of interest
    9594                if (!cell) {
    9695                    continue;
    9796                }
    98 
    99                 if (!pmCellRead(cell, inFile, config->database)) {
    100                     // Nothing here
    101                     psFree(cell);
    102                     cellNum++;
    103                     continue;
    104                 }
    105 
    106                 if (cell->readouts->n > 1) {
    107                     psLogMsg(__func__, PS_LOG_WARN, "File %s chip %d cell %d contains more than one readout "
    108                              "--- ignoring all but the first.\n", name, i, j);
    109                 }
    110 
    111                 pmReadout *readout = cell->readouts->data[0]; // The readout of interest
    112                 psImage *image = readout->image; // The pixels of interest
    113                 if (!image) {
    114                     psFree(cell);
    115                     cellNum++;
    116                     continue;
    117                 }
    118 
    119                 psImageStats(bgStats, image, readout->mask, options->maskVal);
    120                 background[i][cellNum++] = getStat(bgStats, options->background);
    121                 psFree(cell);
     97                cellNum++;
     98
     99                if (!pmCellReadHeader(cell, inFile)) {
     100                    psLogMsg(__func__, PS_LOG_WARN, "Unable to read header for file %s chip %d cell %d --- "
     101                             "ignored.\n", name, j, k);
     102                    status = false;
     103                }
     104
     105                // Normalising by the exposure time
     106                if (options->exptime) {
     107                    bool mdok = true;   // Status of MD lookup
     108                    exptime->data.F64[i][cellNum] = psMetadataLookup(&mdok, cell->concepts, "CELL.EXPOSURE");
     109                    if (!mdok || isnan(exptime->data.F64[i][cellNum])) {
     110                        psLogMsg(__func__, PS_LOG_WARN, "CELL.EXPOSURE for file %s chip %d cell %d is not "
     111                                 "set.\n", name, j, k);
     112                        exptime->data.F64[i][cellNum] = NAN;
     113                        status = false;
     114                    }
     115                }
     116
     117                // Scaling by the background
     118                if (options->scale || options->zero) {
     119                    if (!pmCellRead(cell, inFile, config->database)) {
     120                        // Nothing here
     121                        psFree(cell);
     122                        continue;
     123                    }
     124
     125                    if (cell->readouts->n > 1) {
     126                        psLogMsg(__func__, PS_LOG_WARN, "File %s chip %d cell %d contains more than one "
     127                                 "readout --- ignoring all but the first.\n", name, j, k);
     128                        status = false;
     129                    }
     130
     131                    pmReadout *readout = cell->readouts->data[0]; // The readout of interest
     132                    psImage *image = readout->image; // The pixels of interest
     133                    if (!image) {
     134                        psFree(cell);
     135                        continue;
     136                    }
     137
     138                    // Get the gain
     139                    if (options->scale) {
     140                        bool mdok = true;   // Status of MD lookup
     141                        gain->data.F32[cellNum] = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN");
     142                        if (!mdok || isnan(gain->data.F32[cellNum])) {
     143                            psLogMsg(__func__, PS_LOG_WARN, "CELL.GAIN for file %s chip %d cell %d is not "
     144                                     "set.\n", name, j, k);
     145                            gain->data.F32[cellNum] = NAN;
     146                            status = false;
     147                        }
     148                    }
     149
     150                    // Get the background
     151                    psImageStats(bgStats, image, readout->mask, options->maskVal);
     152                    background[i][cellNum] = getStat(bgStats, options->background);
     153                }
     154
     155                psCellFreeData(cell);
    122156            }
    123             psFree(chip);
    124         }
    125         psFree(fpa);
    126         psFree(view);
     157            psChipFreeData(chip);
     158        }
     159        psFPAFreeData(fpa);
    127160        psFitsClose(inFile);
    128161    }
    129162    psFree(bgStats);
    130163
    131     return background;
     164    if (options->scale) {
     165        // Need to normalize over the focal plane
     166        bool converge = true;           // Did we converge?
     167        psVector *fluxes = pmFlatNormalize(&converge, gains, background, MAX_ITER, TOLERANCE);
     168        if (!converge || !fluxes) {
     169            psLogMsg(__func__, PS_LOG_WARN, "Normalisation failed to converge --- continuing anyway.\n");
     170            status = false;
     171        }
     172        psFree(gains);
     173
     174        *scales = psImageCopy(*scales, background, PS_TYPE_F64);
     175        psImage *scalesDeref = *scales; // Dereference the pointer
     176
     177        for (int i = 0; i < scalesDeref->numRows; i++) {
     178            psF64 bg = fluxes->data.F64[i];
     179            for (int j = 0; j < scalesDeref->numCols; j++) {
     180                scalesDeref->data.F64[i][j] = bg;
     181            }
     182        }
     183    }
     184
     185    if (options->exptime) {
     186        if (!options->scale) {
     187            // Copy over the exposure times
     188            psImageCopy(*scales, exptime, PS_TYPE_F64);
     189        } else {
     190            psBinaryOp(*scales, *scales, "*", exptime);
     191        }
     192    }
     193
     194    if (options->zero) {
     195        if (!*zeros) {
     196            // This is much faster than copying!
     197            *zeros = psMemIncrRefCounter(background);
     198        } else {
     199            *zeros = psImageCopy(*zeros, background, PS_TYPE_F64);
     200        }
     201    }
     202
     203    psFree(background);
     204
     205    return status;
    132206}
     207
  • trunk/ppMerge/src/ppMergeBackground.h

    r7001 r7061  
    22#define PP_MERGE_BACKGROUND_H
    33
    4 // Get the background for each chip of each input
    5 psImage *ppMergeBackground(const ppMergeOptions *options, // The options
    6                            const pmConfig *config // The configuration
     4// Get the scale and zero for each chip of each input
     5bool ppMergeScaleZero(ppImage **scales, // The scales for each integration/cell
     6                      ppImage **zeros, // The zeroes for each integration/cell
     7                      ppMergeData *data,// The data
     8                      const ppMergeOptions *options, // The options
     9                      const pmConfig *config // The configuration
    710    );
    811
  • trunk/ppMerge/src/ppMergeCheckInputs.c

    r7002 r7061  
    55
    66#include "ppMergeCheckInputs.h"
     7#include "ppMergeData.h"
    78
    89// Check input files to make sure everything's consistent
    9 bool ppCheckInputs(const pmConfig *config // Configuration
     10ppMergeData *ppMergeCheckInputs(ppMergeOptions *options, // Options
     11                                const pmConfig *config // Configuration
    1012    )
    1113{
     14    ppMergeData *data = ppMergeDataAlloc(); // The data, to return
     15
     16    // Output file
     17    psString outName = psMetadataLookupStr(NULL, config->arguments, "OUTPUT"); // The output file name
     18    assert(outName);                    // It should be there!
     19    data->outFile = psFitsOpen(outName, "w"); // Output FITS file
     20    if (!data->outFile) {
     21        // There's no point in continuing if we can't open the output
     22        psErrorStackPrint(stderr, "Can't open output image: %s\n", outName);
     23        exit(EXIT_FAILURE);
     24    }
     25
    1226    psArray *filenames = psMetadataLookupPtr(NULL, config->arguments, "INPUT"); // The input file names
    1327    assert(filenames);
     
    2741        }
    2842        psMetadata *header = psFitsReadHeader(NULL, inFile); // The FITS (primary) header
    29         psMetadata *format = pmConfigCameraFormatFromHeader(config, header); // The camera format
    30         psFree(header);
    31         if (!format) {
    32             psErrorPrint(PS_ERR_IO, false, "Unable to identify camera format for input file %s --- "
    33                          "ignored.\n", name);
     43        psFitsClose(inFile);
     44
     45        // The formats must be identical.  The chief reason for this is so that we know what output format to
     46        // use.  I guess one could specify a different output format on the command line, but how do we
     47        // generate a PHU for that?  Perhaps we could revisit this restriction in the future (construct an
     48        // FPAview from the specified camera format configuration, and use pmFPAAddSourceFromView), but for
     49        // now it's less hassle just to limit the output format to be the input format.
     50        if (!data->format) {
     51            data->format = pmConfigCameraFormatFromHeader(config, header);
     52            psFree(header);
     53            if (!options->format) {
     54                psLogMsg(__func__, PS_LOG_WARN, "Unable to identify camera format for input file %s --- "
     55                             "ignored.\n", name);
     56                // Kick it out
     57                psFree(header);
     58                data->in->data[i] = NULL;
     59                continue;
     60            }
     61        } else if (!pmConfigValidateCameraFormat(options->format, header)) {
     62            psLogMsg(__func__, PS_LOG_WARN, "Input file %s doesn't match camera format --- ignored.\n", name);
    3463            // Kick it out
    35             psFree(filenames->data[i]);
    36             filenames->data[i] = NULL;
     64            psFree(header);
     65            data->in->data[i] = NULL;
    3766            continue;
    3867        }
    39         psFitsClose(inFile);
     68
     69        data->in->data[i] = pmFPAConstruct(config->camera);
     70        pmFPAview *view = pmFPAAddSourceFromHeader(data->in->data[i], header, data->format);
     71        psFree(view);
     72
     73        // Use the first valid input as the basis for the output --- including the header
     74        if (!data->out) {
     75            data->out = pmFPAConstruct(config->camera);
     76            pmFPAview *view = pmFPAAddSourceFromHeader(data->out, header, data->format);
     77            psFree(view);
     78        }
     79
    4080        numGood++;
    4181    }
    4282
     83    // Count the cells
     84    int numCells = 0;           // Number of cells in the output FPA
     85    psArray *chips = data->out->chips; // Array of chips in output
     86    for (int i = 0; i < chips->n; i++) {
     87        pmChip *chip = chips->data[i];  // Chip of interest
     88        if (!chip) {
     89            continue;
     90        }
     91        psArray *cells = chip->cells;   // Array of cells
     92        for (int j = 0; j < cells->n; j++) {
     93            pmCell *cell = cells->data[j];
     94                if (cell) {
     95                    numCells++;
     96                }
     97        }
     98    }
     99    data->numCells = numCells;
     100
    43101    return (numGood > 1);
    44102}
     103
     104
  • trunk/ppMerge/src/ppMergeCheckInputs.h

    r7000 r7061  
    33
    44// Check input files to make sure everything's consistent
    5 bool ppCheckInputs(const pmConfig *config // Configuration
     5bool ppMergeCheckInputs(ppMergeOptions *options, // Options
     6                        const pmConfig *config // Configuration
    67    );
    78
  • trunk/ppMerge/src/ppMergeOptions.c

    r6998 r7061  
    77//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    88
     9#if 0
    910// Free function
    1011static void mergeOptionsFree(ppMergeOptions *options // Options to free
    1112    )
    1213{
    13     psFree(options->combine);
    1414}
     15#endif
    1516
    1617// Allocator
     
    1819{
    1920    ppMergeOptions *options = psAlloc(sizeof(ppMergeOptions)); // The options, to return
    20     psMemSetDeallocator(options, (psFreeFunc)mergeOptionsFree);
     21    // psMemSetDeallocator(options, (psFreeFunc)mergeOptionsFree);
    2122
    2223    options->rows = 0;
Note: See TracChangeset for help on using the changeset viewer.