IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 16367


Ignore:
Timestamp:
Feb 7, 2008, 6:37:16 PM (18 years ago)
Author:
Paul Price
Message:

Making progress with refactoring of ppStack for optimisation. This version of the code does NOT yet work.

Location:
branches/pap_branch_080207/ppStack/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/pap_branch_080207/ppStack/src/ppStackCamera.c

    r15844 r16367  
    1010
    1111#include "ppStack.h"
     12
     13
     14// Define an output convolved image file
     15static pmFPAfile *defineOutputConvolved(const char *name, // FPA file name
     16                                        pmFPA *fpa, // FPA to bind
     17                                        const pmConfig *config, // Configuration
     18                                        pmFPAfileType type // Expected type
     19    )
     20{
     21    pmFPAfile *file = pmFPAfileDefineOutput(config, fpa, name);
     22    if (!file) {
     23        psError(PS_ERR_UNKNOWN, false, "Unable to define output convolved file %s", name);
     24        return NULL;
     25    }
     26    if (file->type != PM_FPA_FILE_IMAGE) {
     27        psError(PS_ERR_IO, true, "PPSTACK.OUTCONV is not of type %s", pmFPAfileStringFromType(type));
     28        return NULL;
     29    }
     30
     31    return file;
     32}
     33
     34// Define an input convolved image file, using the output as a basis
     35static pmFPAfile *defineInputConvolved(const char *inputName, // Input FPA file name
     36                                       pmFPAfile *outFile, // Corresponding output FPA file
     37                                       pmConfig *config, // Configuration
     38                                       pmFPAfileType type // Expected type
     39    )
     40{
     41    pmFPAview *view = pmFPAviewAlloc(0); // View into sky cells
     42    view->chip = view->cell = view->readout = 0;
     43
     44    psString imageName = pmFPANameFromRule(outFile->filerule, outFile->fpa, view);
     45    psArray *imageNames = psArrayAlloc(1);
     46    imageNames->data[0] = imageName;
     47    psMetadataAddArray(config->arguments, PS_LIST_TAIL, "INCONV.FILENAMES", PS_META_REPLACE,
     48                       "Filenames of input convolved image files", imageNames);
     49    psFree(imageNames);
     50    bool found = false;                 // Found the file?
     51    pmFPAfile *imageFile = pmFPAfileDefineFromArgs(&found, config, "PPSTACK.INCONV",
     52                                                   "INCONV.FILENAMES");
     53    psMetadataRemoveKey(config->arguments, "INCONV.FILENAMES");
     54    if (!imageFile || !found) {
     55        psError(PS_ERR_UNKNOWN, false, "Unable to define %s file", inputName);
     56        return NULL;
     57    }
     58    if (imageFile->type != type) {
     59        psError(PS_ERR_IO, true, "PPSTACK.INCONV is not of type %s",
     60                pmFPAfileStringFromType(type));
     61        return NULL;
     62    }
     63
     64    return imageFile;
     65}
     66
     67
     68
    1269
    1370bool ppStackCamera(pmConfig *config)
     
    138195            }
    139196        }
     197
     198        // Output convolved files
     199        pmFPAfile *outconvImage  = defineOutputConvolved("PPSTACK.OUTCONV", imageFile->fpa, config,
     200                                                         PM_FPA_FILE_IMAGE);
     201        pmFPAfile *outconvMask   = defineOutputConvolved("PPSTACK.OUTCONV.MASK", imageFile->fpa, config,
     202                                                         PM_FPA_FILE_MASK);
     203        pmFPAfile *outconvWeight = defineOutputConvolved("PPSTACK.OUTCONV.WEIGHT", imageFile->fpa, config,
     204                                                         PM_FPA_FILE_WEIGHT);
     205        if (!outconvImage || !outconvMask || !outconvWeight) {
     206            return false;
     207        }
     208
     209        // Input convolved files
     210        pmFPAfile *inconvImage  = defineInputConvolved("PPSTACK.INCONV", outconvImage, config,
     211                                                       PM_FPA_FILE_IMAGE);
     212        pmFPAfile *inconvMask   = defineInputConvolved("PPSTACK.INCONV.MASK", outconvMask, config,
     213                                                       PM_FPA_FILE_MASK);
     214        pmFPAfile *inconvWeight = defineInputConvolved("PPSTACK.INCONV.WEIGHT", outconvWeight, config,
     215                                                       PM_FPA_FILE_WEIGHT);
     216        if (!inconvImage || !inconvMask || !inconvWeight) {
     217            return false;
     218        }
     219
    140220
    141221        psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0,
  • branches/pap_branch_080207/ppStack/src/ppStackLoop.c

    r15224 r16367  
    1010
    1111#include "ppStack.h"
     12
     13// Here follows lists of files for activation/deactivation at various stages.  Each must be NULL-terminated.
     14
     15// All files in the system
     16static char *allFiles[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.WEIGHT",
     17                            "PPSTACK.OUTCONV", "PPSTACK.OUTCONV.MASK", "PPSTACK.OUTCONV.WEIGHT",
     18                            "PPSTACK.INCONV", "PPSTACK.INCONV.MASK", "PPSTACK.INCONV.WEIGHT",
     19                            "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.WEIGHT",
     20                            "PSPHOT.PSF.SAVE", "PSPHOT.PSF.LOAD", "PPSTACK.SOURCES",
     21                            "PSPHOT.OUTPUT", "PSPHOT.RESID", "PSPHOT.BACKMDL", "PSPHOT.BACKMDL.STDEV",
     22                            "PSPHOT.BACKGND", "PSPHOT.BACKSUB", "SOURCE.PLOT.MOMENTS",
     23                            "SOURCE.PLOT.PSFMODEL", "SOURCE.PLOT.APRESID", "PSPHOT.INPUT.CMF",
     24                            0 };
     25
     26// Files required in preparation for convolution
     27static char *prepareFiles[] = { "PSPHOT.PSF.LOAD", "PPSTACK.SOURCES", 0 };
     28
     29// Files for convolution; these should be turned on one by one
     30static char *convolutionFiles[] = { "PPSTACK.INPUT", "PPSTACK.INPUT.MASK", "PPSTACK.INPUT.WEIGHT",
     31                                    "PPSTACK.OUTCONV", "PPSTACK.OUTCONV.MASK", "PPSTACK.OUTCONV.WEIGHT",
     32                                    0 };
     33
     34// Input files for the combination
     35static char *inCombineFiles = { "PPSTACK.INCONV", "PPSTACK.INCONV.MASK", "PPSTACK.INCONV.WEIGHT", 0 };
     36
     37// Output files for the combination and photometry
     38static char *outCombineFiles = { "PPSTACK.OUTPUT", "PPSTACK.OUTPUT.MASK", "PPSTACK.OUTPUT.WEIGHT",
     39                                 "PSPHOT.OUTPUT", "PSPHOT.RESID", "PSPHOT.BACKMDL",
     40                                 "PSPHOT.BACKMDL.STDEV", "PSPHOT.BACKGND", "PSPHOT.BACKSUB",
     41                                 "SOURCE.PLOT.MOMENTS", "SOURCE.PLOT.PSFMODEL", "SOURCE.PLOT.APRESID",
     42                                 "PSPHOT.INPUT.CMF", 0 };
     43
     44
     45// Activate/deactivate a list of files
     46static void fileActivation(pmConfig *config, // Configuration
     47                           char **files, // Files to turn on/off
     48                           bool state   // Activation state
     49    )
     50{
     51    assert(config);
     52    assert(files);
     53
     54    for (int i = 0; files[i] != NULL; i++) {
     55        pmFPAfileActivate(config->files, state, files[i]);
     56    }
     57    return;
     58}
     59
     60// Activate/deactivate a single element for a list; return array of files
     61static psArray *fileActivationSingle(pmConfig *config, // Configuration
     62                                     char **files, // Files to turn on/off
     63                                     bool state,   // Activation state
     64                                     int num // Number of file in sequence
     65                                     )
     66{
     67    assert(config);
     68    assert(files);
     69
     70    psList *list = psListAlloc(NULL);   // List of files
     71
     72    for (int i = 0; files[i] != NULL; i++) {
     73        pmFPAfile *file = pmFPAfileActivateSingle(config->files, state, files[i], num); // Activated file
     74        psListAdd(list, PS_LIST_TAIL, file);
     75    }
     76
     77    psArray *array = psListToArray(list);
     78    psFree(list);
     79
     80    return array;
     81}
     82
     83// Set the data level for a list of files
     84static void fileSetDataLevel(pmConfig *config, // Configuration
     85                             char **files, // Files for which to set level
     86                             pmFPALevel level // Level to set
     87                             )
     88{
     89    assert(config);
     90    assert(files);
     91
     92    for (int i = 0; files[i] != NULL; i++) {
     93        psArray *selected = pmFPAfileSelect(config->files, files[i]); // Selected files of interest
     94        for (int j = 0; j < selected->n; j++) {
     95            pmFPAfile *file = selected->data[j];
     96            assert(file);
     97            file->dataLevel = level;
     98        }
     99        psFree(selected);
     100    }
     101    return;
     102}
     103
     104
     105
     106// Iterate down the hierarchy, loading files; we can get away with this because we're working on skycells
     107static pmFPAview *filesIterateDown(pmConfig *config // Configuration
     108                                  )
     109{
     110    assert(config);
     111
     112    pmFPAview *view = pmFPAviewAlloc(0);// Pointer into FPA hierarchy
     113    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     114        return NULL;
     115    }
     116    view->chip = 0;
     117    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     118        return NULL;
     119    }
     120    view->cell = 0;
     121    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     122        return NULL;
     123    }
     124    view->readout = 0;
     125    if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     126        return NULL;
     127    }
     128    return view;
     129}
     130
     131// Iterate up the hierarchy, writing files; we can get away with this because we're working on skycells
     132static bool filesIterateUp(pmConfig *config // Configuration
     133                           )
     134{
     135    assert(config);
     136
     137    pmFPAview *view = pmFPAviewAlloc(0);// Pointer into FPA hierarchy
     138    view->chip = view->cell = view->readout = 0;
     139    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     140        return false;
     141    }
     142    view->readout = -1;
     143    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     144        return false;
     145    }
     146    view->cell = -1;
     147    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     148        return false;
     149    }
     150    view->chip = -1;
     151    if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     152        return false;
     153    }
     154    return true;
     155}
     156
    12157
    13158bool ppStackLoop(pmConfig *config)
     
    32177    }
    33178
    34     pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PPSTACK.INPUT"); // Token input file
    35     if (!input) {
    36         psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find input data!\n");
    37         return false;
    38     }
    39179    pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PPSTACK.OUTPUT"); // Output file
    40180    if (!output) {
    41         psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find output data!\n");
     181        psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find output data!");
    42182        return false;
    43183    }
    44184
    45     pmFPAview *view = pmFPAviewAlloc(0); // Pointer into FPA hierarchy
    46     pmHDU *lastHDU = NULL;              // Last HDU that was updated
    47 
    48     // Iterate over the FPA hierarchy
    49     if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    50         return false;
    51     }
    52 
    53     pmChip *chip;                       // Chip of interest
    54     while ((chip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) {
    55         if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    56             return false;
    57         }
    58 
    59         pmCell *cell;                // Cell of interest
    60         while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
    61             if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     185    // Preparation iteration: Load the sources, and get a target PSF model
     186    psArray *sources = NULL;            // Sources to use for PSF matching
     187    pmPSF *targetPSF = NULL;            // Target PSF
     188    {
     189        pmFPAfileActivate(config->files, false, NULL);
     190        fileActivation(config, prepareFiles, true);
     191        pmFPAview *view = filesIterateDown(config);
     192        if (!view) {
     193            return false;
     194        }
     195
     196        pmReadout *sourcesRO = pmFPAfileThisReadout(config->files, view, "PPSTACK.SOURCES"); // Readout
     197        // We want to hang on to the 'sources' even when its host FPA is blown away
     198        sources = psMemIncrRefCounter(psMetadataLookupPtr(&mdok, sourcesRO->analysis, "PSPHOT.SOURCES"));
     199        if (!sources) {
     200            psError(PS_ERR_UNKNOWN, true, "Unable to find sources.");
     201            psFree(view);
     202            return false;
     203        }
     204
     205        // Generate list of PSFs
     206        psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD,
     207                                                               "^PPSTACK.INPUT$"); // Iterator
     208        psMetadataItem *fileItem; // Item from iteration
     209        int fileNum = 0;        // Number of file
     210        psList *psfList = psListAlloc(NULL); // List of PSFs for PSF envelope
     211        while ((fileItem = psMetadataGetAndIncrement(fileIter))) {
     212            assert(fileItem->type == PS_DATA_UNKNOWN);
     213            pmFPAfile *inputFile = fileItem->data.V; // An input file
     214            pmChip *chip = pmFPAviewThisChip(view, inputFile->fpa); // The chip: holds the PSF
     215            pmPSF *psf = psMetadataLookupPtr(NULL, ro->parent->parent->analysis, "PSPHOT.PSF"); // PSF
     216            if (!psf) {
     217                psError(PS_ERR_UNKNOWN, false, "Unable to find PSF.");
     218                psFree(view);
     219                psFree(sources);
    62220                return false;
    63221            }
    64 
    65             // Put version information into the header
    66             pmHDU *hdu = pmHDUFromCell(cell);
    67             if (hdu && hdu != lastHDU) {
    68                 if (!hdu->header) {
    69                     hdu->header = psMetadataAlloc();
    70                 }
    71                 ppStackVersionMetadata(hdu->header);
    72                 lastHDU = hdu;
    73             }
    74 
    75             pmReadout *readout;         // Readout of interest
    76             while ((readout = pmFPAviewNextReadout(view, input->fpa, 1))) {
    77                 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    78                     return false;
    79                 }
    80 
    81                 // Perform the analysis
    82                 if (!ppStackReadout(config, view)) {
    83                     psError(PS_ERR_UNKNOWN, false, "Unable to stack images.\n");
    84                     return false;
    85                 }
    86 
    87                 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    88                     return false;
     222            psListAdd(psfList, PS_LIST_TAIL, psf);
     223        }
     224        psFree(fileIter);
     225        psFree(view);
     226
     227        psArray *psfArray = psListToArray(psfList); // Array of PSFs
     228        psFree(psfList);
     229        targetPSF = pmPSFEnvelope(numCols, numRows, psfArray, psfInstances, psfRadius, psfModel,
     230                                  psfOrder, psfOrder);
     231        psFree(psfArray);
     232        if (!targetPSF) {
     233            psError(PS_ERR_UNKNOWN, false, "Unable to determine output PSF.");
     234            psFree(sources);
     235            return false;
     236        }
     237
     238        filesIterateUp(config);
     239    }
     240
     241
     242    // Generate convolutions and write them to disk
     243    psArray *cells = psArrayAlloc(numFiles);    // Cells for convolved images --- a handle for reading again
     244    for (int i = 0; i < numFiles; i++) {
     245        pmFPAfileActivate(config->files, false, NULL);
     246        psArray *files = fileActivationSingle(config, prepareFiles, true, i);
     247        pmFPAview *view = filesIterateDown(config);
     248        if (!view) {
     249            return false;
     250        }
     251
     252        pmReadout *readout = pmFPAviewThisReadout(view, files->data[0]); // Input readout
     253        psFree(view);
     254
     255        // Background subtraction, scaling and normalisation is performed automatically by the image matching
     256        if (!ppStackMatch(ro, sources, outPSF, config)) {
     257            psError(PS_ERR_UNKNOWN, false, "Unable to match image %d --- ignoring.", i);
     258            psFree(convolved);
     259            return false;
     260        }
     261
     262#ifdef CONVOLUTION_FILES
     263        if (readout->image) {
     264            psString name = NULL;           // Name of image
     265            psStringAppend(&name, "convolved%03d_image.fits", i);
     266            psFits *fits = psFitsOpen(name, "w");
     267            psFree(name);
     268            psFitsWriteImage(fits, NULL, readout->image, 0, NULL);
     269            psFitsClose(fits);
     270        }
     271        if (readout->mask) {
     272            psString name = NULL;           // Name of image
     273            psStringAppend(&name, "convolved%03d_mask.fits", i);
     274            psFits *fits = psFitsOpen(name, "w");
     275            psFree(name);
     276            psFitsWriteImage(fits, NULL, readout->mask, 0, NULL);
     277            psFitsClose(fits);
     278        }
     279        if (readout->weight) {
     280            psString name = NULL;           // Name of image
     281            psStringAppend(&name, "convolved%03d_weight.fits", i);
     282            psFits *fits = psFitsOpen(name, "w");
     283            psFree(name);
     284            psFitsWriteImage(fits, NULL, readout->weight, 0, NULL);
     285            psFitsClose(fits);
     286        }
     287#endif // CONVOLUTION_FILES
     288
     289        cells->data[i] = psMemIncrRefCounter(readout->parent);
     290        filesIterateUp(config);
     291    }
     292
     293    // Set files to read at the readout level --- then when we iterate down, the pmFPAfileIO stuff should take
     294    // care of the basic things, and we can just worry about grabbing the readouts by chunks
     295    fileSetDataLevel(config, inCombineFiles, PM_FPA_LEVEL_CHUNK);
     296    pmFPAfileActivate(config->files, false, NULL);
     297    fileActivation(inCombineFiles, true);
     298    fileActivation(outCombineFiles, true);
     299
     300    {
     301        pmFPAview *view = filesIterateDown(config);
     302        if (!view) {
     303            psFree(cells);
     304            return false;
     305        }
     306        pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSTACK.OUTPUT"); // Output readout
     307        psFree(view);
     308
     309        psArray *readouts = psArrayAlloc(numFiles); // Readouts for convolved images
     310        for (int i = 0; i < numFiles; i++) {
     311            readouts->data[i] = pmReadoutAlloc(cells->data[i]); // Readout into which to read
     312        }
     313
     314        // Read convolutions by chunks
     315        int numRead = 0;                    // Number of inputs read
     316        int numChunk = 0;                   // Chunk number
     317        bool more = true;               // More to read?
     318        for (int numChunk = 0; more; numChunk++) {
     319            for (int i = 0; i < numFiles; i++) {
     320                pmReadout *readout = readouts->data[i];
     321                assert(readout);
     322
     323                // Files, containing the FITS handle
     324                pmFPAfile *imageFile = pmFPAfileSelectSingle(config->files, "PPSTACK.INCONV", i);
     325                pmFPAfile *maskFile = pmFPAfileSelectSingle(config->files, "PPSTACK.INCONV.MASK", i);
     326                pmFPAfile *weightFile = pmFPAfileSelectSingle(config->files, "PPSTACK.INCONV.WEIGHT", i);
     327
     328                // FITS handles
     329                psFits *fitsImage = imageFile->fits;
     330                psFits *fitsMask = maskFile->fits;
     331                psFits *fitsWeight = weightFile->fits;
     332
     333                if (!pmReadoutReadChunk(readout, fitsImage, 0, numScans, overlap) ||
     334                    !pmReadoutReadChunkMask(readout, fitsMask, 0, numScans, overlap) ||
     335                    !pmReadoutReadChunkWeight(readout, fitsWeight, 0, numScans, overlap)) {
     336                    psError(PS_ERR_IO, false, "Unable to read chunk %d for file %d", numChunk, i);
     337                    psFree(readouts);
     338                    psFree(cells);
    89339                }
    90340            }
    91341
    92             // Perform statistics on the cell
    93             if (stats) {
    94                 ppStatsFPA(stats, output->fpa, view, maskBlank, config);
    95             }
    96 
    97             if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     342            if (!ppStackReadout(config, outRO, readouts)) {
     343                psError(PS_ERR_UNKNOWN, false, "Unable to stack images.\n");
    98344                return false;
    99345            }
    100         }
    101 
    102         if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
    103             return false;
    104         }
    105     }
    106 
    107     if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
    108         return false;
     346
     347            for (int i = 0; i < numFiles && more; i++) {
     348                pmReadout *readout = readouts->data[i];
     349                assert(readout);
     350
     351                // Files, containing the FITS handle
     352                pmFPAfile *imageFile = pmFPAfileSelectSingle(config->files, "PPSTACK.INCONV", i);
     353                pmFPAfile *maskFile = pmFPAfileSelectSingle(config->files, "PPSTACK.INCONV.MASK", i);
     354                pmFPAfile *weightFile = pmFPAfileSelectSingle(config->files, "PPSTACK.INCONV.WEIGHT", i);
     355
     356                // FITS handles
     357                psFits *fitsImage = imageFile->fits;
     358                psFits *fitsMask = maskFile->fits;
     359                psFits *fitsWeight = weightFile->fits;
     360
     361                more &= pmReadoutMore(readout, fitsImage, 0, numScans, overlap);
     362                more &= pmReadoutMoreMask(readout, fitsMask, 0, numScans, overlap);
     363                more &= pmReadoutMoreWeight(readout, fitsWeight, 0, numScans, overlap);
     364            }
     365        }
     366
     367        // Get rid of the input files
     368        fileActivation(outCombineFiles, false);
     369        filesIterateUp(config);
     370
     371        ppStackPhotometry(config, outRO);
     372
     373        // Put version information into the header
     374        pmHDU *hdu = pmHDUFromCell(outRO->parent);
     375        if (!hdu) {
     376            psError(PS_ERR_UNKNOWN, true, "Unable to find HDU for output.");
     377            return false;
     378        }
     379        if (!hdu->header) {
     380            hdu->header = psMetadataAlloc();
     381        }
     382        ppStackVersionMetadata(hdu->header);
     383
     384        // Statistics on output
     385        if (stats) {
     386            ppStatsFPA(stats, output->fpa, view, maskBlank, config);
     387        }
     388
     389        // Write out the output files
     390        filesActivation(outCombineFiles, true);
     391        filesIterateUp(config);
    109392    }
    110393
Note: See TracChangeset for help on using the changeset viewer.