IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 7, 2009, 4:08:25 PM (17 years ago)
Author:
Paul Price
Message:

Merging trunk (r25026) to get up-to-date on old branch.

Location:
branches/pap
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/pap

  • branches/pap/magic

    • Property svn:ignore set to
      magic
      ssa-core-cpp
      Makefile
      Makefile.bak
  • branches/pap/magic/remove/src

    • Property svn:ignore
      •  

        old new  
         1isdestreaked
        12streaksremove
        23streaksreplace
        34streakscompare
        45streaksrelease
         6makefile
  • branches/pap/magic/remove/src/streaksremove.c

    r23936 r25027  
     1/*
     2 * streaksremove
     3 *
     4 * Convert satellite streak detctions into masks and remove the covered pixels from the
     5 * input images.
     6 * Optionally swap the inputs with the outputs so that subsequent references to the original
     7 * images access the destreaked versions.
     8 */
     9
    110#include "streaksremove.h"
    211
     
    413static bool readAndCopyToOutput(streakFiles *sf, bool exciseAll);
    514static void exciseNonWarpedPixels(streakFiles *sfiles, double newMaskValue);
    6 static bool warpedPixel(streakFiles *sfiles, PixelPos *cellCoord);
     15static bool warpedPixel(streakFiles *sfiles, int x, int y);
    716static void excisePixel(streakFiles *sfiles, unsigned int x, unsigned int y, bool streak, double newMaskValue);
    817static void writeImages(streakFiles *sf, bool exciseImageCube);
    918static void updateAstrometry(streakFiles *sfiles);
     19static void censorSources(streakFiles *sfiles, psU32 maskStreak);
    1020
    1121int
     
    2333    }
    2434
    25     psU32 maskStreak = 0;
    26     psU32 maskMask = 0;
     35    // Values to set for masked pixels
     36    psU32 maskStreak = 0;           // for the image and weight (usually NAN, MAXINT for integer images)
     37    psU32 maskMask = 0;             // value looked up for MASK.STREAK
    2738
    2839    psString streaksFileName = psMetadataLookupStr(NULL, config->arguments, "STREAKS");
    2940
     41    // call Paul Sydney's code to parse the streaks file that DetectStreaks produced
    3042    Streaks *streaks = readStreaksFile(streaksFileName);
    3143    if (!streaks) {
    32         psErrorStackPrint(stderr, "failed to read streaks file: %s", streaksFileName);
     44        psError(PS_ERR_UNKNOWN, "failed to read streaks file: %s", streaksFileName);
    3345        streaksExit("", PS_EXIT_PROG_ERROR);
    3446    }
    3547
    36     streakFiles *sfiles = openFiles(config, true);
     48    // open all of the input and output files, save their descriptions in the streakFiles struct
     49    streakFiles *sfiles = openFiles(config, true, argv[0]);
    3750    setupAstrometry(sfiles);
    3851
     52    // Optionally we can set pixels that are masked to NAN since they couldn't have been
     53    // examined for streaks. Usually this is done by the distribution system just prior
     54    // to release
    3955    bool nanForRelease = psMetadataLookupBool(&status, config->arguments, "NAN_FOR_RELEASE");
    4056    if (nanForRelease && (sfiles->inMask == NULL)) {
     
    5268
    5369    if (checkNonWarpedPixels ) {
    54         // From ICD:
     70        // From magic ICD:
    5571        // In the raw and detrended images, the pixels which were not
    5672        // included in any of the streak-processed warps must also be masked.
     
    6581        }
    6682        psF64 cwp_t = psTimerClear("COMPUTE_WARPED_PIXELS");
    67         printf("time to compute warped pixels: %f\n", cwp_t);
     83        psLogMsg("streaksremove", PS_LOG_INFO, "time to compute warped pixels: %f\n", cwp_t);
    6884    }
    6985   
    7086    if (sfiles->stage == IPP_STAGE_RAW) {
    71         // copy PHU to output files
     87        // Except for raw stage, all of our (GPC1) files have one image extension.
     88        // Raw files have a phu and multiple extensions, one per chip
     89        // Since this is a raw file, copy it's PHU to output files
    7290        copyPHU(sfiles, true);
    7391
     
    82100    int totalStreakPixels = 0;
    83101
    84     // Iterate through each component of the input (there is only one except for raw images)
     102    // Iterate through each component of the input (except for raw images there is only one)
    85103    do {
    86104        bool exciseImageCube = false;
     
    110128            psTimerStart("GET_STREAK_PIXELS");
    111129
    112             StreakPixels *pixels = streak_on_component (streaks, sfiles->astrom,
    113                                       sfiles->inImage->numCols, sfiles->inImage->numRows);
    114 
    115             printf("time to get streak pixels: %f\n", psTimerClear("GET_STREAK_PIXELS"));
    116 
     130            // call Paul Sydney's code to compute the set of pixels that are covered by the detected streaks
     131            StreakPixels *pixels = streak_on_component(streaks, sfiles->astrom, sfiles->inImage->numCols,
     132                                                        sfiles->inImage->numRows);
     133            psLogMsg("streaksremove", PS_LOG_INFO, "time to get streak pixels: %f\n", psTimerClear("GET_STREAK_PIXELS"));
    117134           
     135            // if this extension contained an image, excise the streaked pixels.
     136            // otherwise it contained an image cube (video cell) which is handled in the if block
    118137            if (sfiles->inImage->image) {
    119138                if (checkNonWarpedPixels) {
     
    124143                    exciseNonWarpedPixels(sfiles, maskStreak);
    125144
    126                     printf("time to excise non warped pixels: %f\n", psTimerClear("EXCISE_NON_WARPED"));
     145                    psLogMsg("streaksremove", PS_LOG_INFO, "time to excise non warped pixels: %f\n", psTimerClear("EXCISE_NON_WARPED"));
    127146                }
    128                 totalStreakPixels +=  psArrayLength(pixels);
     147
     148
    129149                psTimerStart("REMOVE_STREAKS");
    130                 for (int i = 0; i < psArrayLength (pixels); ++i) {
    131                     PixelPos *pixelPos = psArrayGet (pixels, i);
    132 
    133                     if (!checkNonWarpedPixels || warpedPixel(sfiles, pixelPos)) {
    134 
    135                         excisePixel(sfiles, pixelPos->x, pixelPos->y, true, maskStreak);
    136 
    137                     } else {
    138                         // This pixel was not included in any warp and has thus already excised
    139                         // by exciseNonWarpedPixels
     150
     151                for (int y=0 ; y < sfiles->inImage->numRows; y++) {
     152                    for (int x = 0; x < sfiles->inImage->numCols; x++) {
     153                        if (psImageGet(pixels, x, y)) {
     154                            ++totalStreakPixels;
     155                            if (!checkNonWarpedPixels || warpedPixel(sfiles, x, y)) {
     156
     157                                excisePixel(sfiles, x, y, true, maskStreak);
     158
     159                            } else {
     160                                // This pixel was not included in any warp and has thus already excised
     161                                // by exciseNonWarpedPixels
     162                            }
     163                        }
    140164                    }
    141165                }
    142                 printf("time to remove streak pixels: %f\n", psTimerClear("REMOVE_STREAKS"));
     166
     167                psLogMsg("streaksremove", PS_LOG_INFO, "time to remove streak pixels: %f\n", psTimerClear("REMOVE_STREAKS"));
    143168
    144169                if (nanForRelease) {
     170                    // set any pixels that were masked, to NAN (unless they are already NAN)
    145171                    setMaskedToNAN(sfiles, maskMask, true);
    146172                }
    147173
    148174            } else {
    149                 // this component contains an image cube, excise it completely
     175                // this component contains an image cube
     176                // For now excise it completely
    150177                exciseImageCube = true;
    151178            }
    152             psArrayElementsFree (pixels);
    153179            psFree(pixels);
    154180        }
    155181
    156182        if (sfiles->stage == IPP_STAGE_CHIP) {
     183            // as a convience to the user of the output, replace the bogus WCS transform in the
     184            // chip processed files with the data calcuated by psastro at the camera stage
     185            // (actually we use a linear approximation)
    157186            updateAstrometry(sfiles);
    158187        }
    159188
    160         // write out the destreaked temporary images and the recovery images
     189        censorSources(sfiles, maskStreak);
     190
     191        // write the destreaked "temporary" images and the recovery images
    161192        writeImages(sfiles, exciseImageCube);
    162193
    163         printf("time to process component %d: %f\n", sfiles->extnum, psTimerClear("PROCESS_COMPONENT"));
     194
     195        psLogMsg("streaksremove", PS_LOG_INFO, "time to process component %d: %f\n", sfiles->extnum, psTimerClear("PROCESS_COMPONENT"));
    164196    } while (streakFilesNextExtension(sfiles));
    165197
     198
    166199    psFree(streaks);
    167200
    168     printf("pixels: %ld streak pixels: %ld %4.2f%%\n", totalPixels, totalStreakPixels, 100. * totalStreakPixels / totalPixels);
     201    psLogMsg("streaksremove", PS_LOG_INFO, "pixels: %ld streak pixels: %ld %4.2f%%\n", totalPixels, totalStreakPixels, 100. * totalStreakPixels / totalPixels);
     202
     203    // check the weight and mask files for extra extensions that might be in files
     204    // (covariance matrix for example)
     205    copyExtraExtensions(sfiles);
     206
     207    // all done close the files. This is where the files are written so it can take a long time.
    169208
    170209    psTimerStart("CLOSE_IMAGES");
    171     // close all files
     210
    172211    closeImages(sfiles);
    173     printf("time to close images: %f\n", psTimerClear("CLOSE_IMAGES"));
     212
     213    psLogMsg("streaksremove", PS_LOG_INFO, "time to close images: %f\n", psTimerClear("CLOSE_IMAGES"));
     214
     215
     216    if (!replicateOutputs(sfiles)) {
     217        psError(PS_ERR_UNKNOWN, false, "failed to replicate output files");
     218        deleteTemps(sfiles);
     219        psErrorStackPrint(stderr, "");
     220        exit(PS_EXIT_UNKNOWN_ERROR);
     221    }
    174222
    175223    // NOTE: from here on we can't just quit if something goes wrong.
    176224    // especially if we're working at the raw stage
    177 
    178     if (!replicateOutputs(sfiles)) {
    179         psError(PS_ERR_UNKNOWN, false, "failed to replicate output files");
    180         psErrorStackPrint(stderr, "");
    181         exit(PS_EXIT_UNKNOWN_ERROR);
    182     }
     225    // turn off automatic deletion of output files by streaksExit
     226    setStreakFiles(NULL);
    183227
    184228    if (psMetadataLookupBool(&status, config->arguments, "REPLACE")) {
    185229        //     swap the instances for the input and output
    186         //     Note this is a database operation. No file I/O is performed
     230        //     Note this is a nebulous database operation. No file I/O is performed
    187231        if (!swapOutputsToInputs(sfiles)) {
    188             psError(PS_ERR_UNKNOWN, false, "failed to swap files");
    189 
    190             // XXX: Now what? I guess swapOutputsToInputs will need to undo anything that
    191             // it has done and give a detailed report of what happened
    192 
    193             psErrorStackPrint(stderr, "");
     232            // XXX: Now what?
     233            // It is up to the program that reverts failed destreak runs to insure that
     234            // any input files that have been swapped are restored and that the de-streaked
     235            // versions are deleted
     236
     237            psErrorStackPrint(stderr, "failed to swap files");
     238
     239            // XXX: pick a specific error code for this failure
    194240            exit(PS_EXIT_UNKNOWN_ERROR);
    195241        }
    196 
    197         if (psMetadataLookupBool(&status, config->arguments, "REMOVE")) {
    198             //      delete the temporary storage objects (which now points to the original image(s)
    199             if (!deleteTemps(sfiles)) {
    200                 psError(PS_ERR_UNKNOWN, false, "failed to delete temporary files");
    201                 // XXX: Now what? At this point the output files have been swapped, so we can't
    202                 // repeat the operation.
    203 
    204                 // Returning error status here is problematic. The inputs have been streak removed
    205                 // but they're still lying around
    206                 // Maybe just print an error message and
    207                 // let other system tools clean up
    208                 psErrorStackPrint(stderr, "");
    209                 exit(PS_EXIT_UNKNOWN_ERROR);
    210             }
    211         }
    212     }
     242    }
     243    // all done. Clean up to look for memory leaks.
    213244
    214245    psFree(sfiles);
     
    218249    streaksNebulousCleanup();
    219250    pmConfigDone();
    220     printf("time to run streaksremove: %f\n", psTimerClear("STREAKSREMOVE"));
     251    psLogMsg("streaksremove", PS_LOG_INFO, "time to run streaksremove: %f\n", psTimerClear("STREAKSREMOVE"));
    221252    psLibFinalize();
    222253
     
    235266    fprintf(stderr, "\t-weight WEIGHT.fits: weight file to de-streak\n");
    236267    fprintf(stderr, "\t-replace: replace the input images with the output\n");
    237     fprintf(stderr, "\t-remove: remove the original image after processing (requires -replace)\n");
    238268    fprintf(stderr, "\t-keepnonwarped: do not exise pixels that were not part of difference processing\n");
    239269    fprintf(stderr, "\t-transparent val: instead of setting excicsed pixel to NAN add val\n");
     
    311341    bool gotReplace = false;
    312342    if ((argnum = psArgumentGet(argc, argv, "-replace"))) {
     343        if (!nebulousImage) {
     344            psError(PS_ERR_UNKNOWN, true, "replace is only supported for nebulous files");
     345            usage();
     346        }
    313347        gotReplace = true;
    314348        psArgumentRemove(argnum, &argc, argv);
     
    394428        psArgumentRemove(argnum, &argc, argv);
    395429    }
     430    if ((argnum = psArgumentGet(argc, argv, "-sources"))) {
     431        psArgumentRemove(argnum, &argc, argv);
     432        bool nebulousSources = IN_NEBULOUS(argv[argnum]);
     433        if (nebulousSources != nebulousImage) {
     434            psError(PS_ERR_UNKNOWN, true, "sources file must have %snebulous path with %s image path\n",
     435                nebulousImage ? "" : "non ", nebulousImage ? "nebulous" : "regular");
     436            usage();
     437        }
     438        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "SOURCES", 0,
     439                "name of input sources file", argv[argnum]);
     440        psArgumentRemove(argnum, &argc, argv);
     441    }
    396442
    397443    if ((argnum = psArgumentGet(argc, argv, "-tmproot"))) {
     
    403449            usage();
    404450        }
    405         psString dir = pathToDirectory(argv[argnum]);
    406         psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "directory for temporary files",
    407             dir);
    408         psFree(dir);
     451        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "path for (temporary if replae) output files",
     452            argv[argnum]);
    409453        psArgumentRemove(argnum, &argc, argv);
    410454    } else {
     
    415459    if ((argnum = psArgumentGet(argc, argv, "-recovery"))) {
    416460        psArgumentRemove(argnum, &argc, argv);
    417         psString dir = pathToDirectory(argv[argnum]);
    418         psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "directory for recovery files",
    419             dir);
    420         psFree(dir);
     461        psMetadataAddStr(config->arguments, PS_LIST_TAIL, "RECOVERY", 0, "path for recovery files",
     462            argv[argnum]);
    421463        psArgumentRemove(argnum, &argc, argv);
    422464    } else if ((stage == IPP_STAGE_RAW) && gotReplace) {
    423465        psError(PS_ERR_UNKNOWN, true, "-recovery is required for -stage raw with -replace\n");
    424466        usage();
    425     }
    426 
    427     if ((argnum = psArgumentGet(argc, argv, "-remove"))) {
    428         if (!gotReplace) {
    429             psError(PS_ERR_UNKNOWN, true, "-replace is required with -remove\n");
    430             usage();
    431         }
    432         psArgumentRemove(argnum, &argc, argv);
    433         psMetadataAddBool(config->arguments, PS_LIST_TAIL, "REMOVE", 0, "remove original files",
    434             true);
    435467    }
    436468
     
    451483updateAstrometry(streakFiles *sf)
    452484{
     485    // XXX: why do I check this here? Shouldn't it be just around the call to linearizeTransforms?
    453486    if (sf->bilevelAstrometry) {
    454487
    455         linearizeTransforms(sf->astrom);
     488        if (!linearizeTransforms(sf->astrom)) {
     489            // fit failed, leave the astrometry unchanged
     490            return;
     491        }
    456492
    457493        if (!pmAstromWriteWCS(sf->outImage->header, sf->inAstrom->fpa, sf->chip, 0.001)) {
     
    501537        }
    502538    }
    503     sf->outImage->header = (psMetadata*) psMemIncrRefCounter(sf->inImage->header);
     539    sf->outImage->header = psMemIncrRefCounter(sf->inImage->header);
    504540    if (sf->recImage) {
    505         sf->recImage->header = (psMetadata*) psMemIncrRefCounter(sf->inImage->header);
    506     }
     541        sf->recImage->header = psMetadataCopy(NULL, sf->inImage->header);
     542        addRecoveryKeyword(sf->recImage->header);
     543    }
     544    addDestreakKeyword(sf->outImage->header);
    507545
    508546    if (!SFILE_IS_IMAGE(sf->inImage)) {
     
    520558
    521559    // set up the compression parameters
    522 #ifdef STREAKS_COMPRESS_OUTPUT
    523     // compression of the image pixels is disabled for now. Some consortium members
    524     // have problems reading them
    525     copyFitsOptions(sf->outImage, sf->recImage, sf->inImage);
    526 
    527     // XXX: TODO: can we derive these values from the input header?
    528     // psFitsCompressionGet(sf->inImage->image) gives compression none
    529     // perhaps we should just use the definition of COMP_IMG in the configuration
    530     psFitsSetCompression(sf->outImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    531     if (sf->recImage) {
    532         psFitsSetCompression(sf->recImage->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    533     }
    534 #endif
     560    copyFitsOptions(sf->outImage, sf->recImage, sf->inImage, sf->tiles);
    535561
    536562    if (sf->inMask) {
     
    539565            sf->outMask->header = (psMetadata*) psMemIncrRefCounter(sf->inMask->header);
    540566            if (sf->recMask) {
    541                 sf->recMask->header = (psMetadata*) psMemIncrRefCounter(sf->inMask->header);
    542             }
     567                sf->recMask->header = psMetadataCopy(NULL, sf->outMask->header);
     568                addRecoveryKeyword(sf->recMask->header);
     569            }
     570            addDestreakKeyword(sf->outMask->header);
    543571            if (updateAstrometry) {
    544572                pmAstromWriteWCS(sf->outMask->header, sf->inAstrom->fpa, sf->chip, 0.001);
     
    554582            }
    555583
    556 #ifdef STREAKS_COMPRESS_OUTPUT
    557             // XXX: see note above
    558             copyFitsOptions(sf->outMask, sf->recMask, sf->inMask);
    559             psFitsSetCompression(sf->outMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    560             if (sf->recMask) {
    561                 psFitsSetCompression(sf->recMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    562             }
     584            copyFitsOptions(sf->outMask, sf->recMask, sf->inMask, sf->tiles);
    563585            if (sf->outChMask) {
    564                 copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask);
    565                 psFitsSetCompression(sf->outChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    566                 if (sf->recChMask) {
    567                     psFitsSetCompression(sf->recChMask->fits, PS_FITS_COMPRESS_PLIO, sf->tiles, 8, 0, 0);
    568                 }
    569             }
    570 #endif
     586                copyFitsOptions(sf->outChMask, sf->recChMask, sf->inMask, sf->tiles);
     587            }
    571588        }
    572589    }
     
    576593        sf->outWeight->header = (psMetadata*) psMemIncrRefCounter(sf->inWeight->header);
    577594        if (sf->recWeight) {
    578             sf->recWeight->header = (psMetadata*) psMemIncrRefCounter(sf->inWeight->header);
    579         }
     595            sf->recWeight->header = psMetadataCopy(NULL, sf->outWeight->header);
     596            addRecoveryKeyword(sf->recWeight->header);
     597        }
     598        addDestreakKeyword(sf->outWeight->header);
    580599        if (updateAstrometry) {
    581600            pmAstromWriteWCS(sf->inWeight->header, sf->inAstrom->fpa, sf->chip, 0.001);
     
    583602        setupImageRefs(sf->outWeight, sf->recWeight, sf->inWeight, sf->extnum, exciseAll);
    584603
    585 #ifdef STREAKS_COMPRESS_OUTPUT
    586         copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight);
    587         // XXX: see note above
    588         psFitsSetCompression(sf->outWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    589         if (sf->recWeight) {
    590             psFitsSetCompression(sf->recWeight->fits, PS_FITS_COMPRESS_RICE, sf->tiles, 8, 0, 0);
    591         }
    592 #endif
    593     }
    594     // and for raw images, create sub images that represent the actual image
    595     // area (no overscan)
     604        copyFitsOptions(sf->outWeight, sf->recWeight, sf->inWeight, sf->tiles);
     605    }
    596606
    597607    return true;
    598608}
    599 
    600 
    601609
    602610static void
     
    746754
    747755static bool
    748 warpedPixel(streakFiles *sfiles, PixelPos *cellCoord)
     756warpedPixel(streakFiles *sfiles, int x, int y)
    749757{
    750758    PixelPos chipCoord;
     
    757765    // we clip so that the streak calculation code doesn't have to
    758766    // clipping here insures that we don't touch the overscan regions
    759     if ((cellCoord->x < 0) || (cellCoord->x >= sfiles->inImage->numCols) ||
    760         (cellCoord->y < 0) || (cellCoord->y >= sfiles->inImage->numRows)) {
     767    if ((x < 0) || (x >= sfiles->inImage->numCols) ||
     768        (y < 0) || (y >= sfiles->inImage->numRows)) {
    761769        return false;
    762770    }
    763771
    764     cellToChipInt(&chipCoord.x, &chipCoord.y, sfiles->astrom, cellCoord->x, cellCoord->y);
     772    cellToChipInt(&chipCoord.x, &chipCoord.y, sfiles->astrom, x, y);
    765773
    766774    if (chipCoord.x < 0 || chipCoord.x >= sfiles->warpedPixels->numCols) {
     
    774782}
    775783
     784// read a sources file (.cmf) and remove any rows whose coordinate is convered by a
     785// streak mask
     786static void
     787censorSources(streakFiles *sfiles, psU32 maskStreak)
     788{
     789    if ((!sfiles->inSources) || (!sfiles->outMask)) {
     790        return;
     791    }
     792    psImage *maskImage = sfiles->outMask->image;
     793    if (!maskImage) {
     794        psError(PS_ERR_IO, false, "maskImage is null!");
     795        streaksExit("", PS_EXIT_PROG_ERROR);
     796    }
     797
     798    sFile *in = sfiles->inSources;
     799    sFile *out = sfiles->outSources;
     800
     801    in->header = psFitsReadHeader(NULL, in->fits);
     802    if (!in->header) {
     803        psError(PS_ERR_IO, false, "failed to read header from %s", in->resolved_name);
     804        streaksExit("", PS_EXIT_DATA_ERROR);
     805    }
     806
     807    bool status;
     808    psString extname = psMetadataLookupStr(&status, in->header, "EXTNAME");
     809    if (!extname) {
     810        psError(PS_ERR_IO, false, "failed to find extname in header of %s", in->resolved_name);
     811        streaksExit("", PS_EXIT_DATA_ERROR);
     812    }
     813
     814    psArray *inTable = psFitsReadTable(in->fits);
     815    if (!inTable->n) {
     816        psError(PS_ERR_IO, false, "table in %s is empty", in->resolved_name);
     817        streaksExit("", PS_EXIT_DATA_ERROR);
     818    }
     819
     820    psArray *outTable = psArrayAllocEmpty(inTable->n);
     821    int j = 0;
     822    int numCensored = 0;
     823    for (int i = 0 ; i < inTable->n; i++) {
     824        psMetadata *row = inTable->data[i];
     825
     826        psF32 x = psMetadataLookupF32 (&status, row, "X_PSF");
     827        psF32 y = psMetadataLookupF32 (&status, row, "Y_PSF");
     828       
     829        psU32 mask = psImageGet(maskImage, x, y);
     830
     831        // Key the source if the center pixel is not masked with maskStreak
     832        if (! (mask & maskStreak) ) {
     833            psArraySet(outTable, j++, row);
     834        } else {
     835            numCensored++;
     836        }
     837    }
     838
     839    // get rid of unused elements (don't know if this is necessary)
     840    psArrayRealloc(outTable, j);
     841
     842    addDestreakKeyword(in->header);
     843    if (psArrayLength(outTable) > 0) {
     844        printf("Censored %d sources\n", numCensored);
     845        if (! psFitsWriteTable(out->fits, in->header, outTable, extname)) {
     846            psError(PS_ERR_IO, false, "failed to write table to %s", out->resolved_name);
     847            streaksExit("", PS_EXIT_DATA_ERROR);
     848        }
     849    } else {
     850        printf("Censored ALL %d sources\n", numCensored);
     851        if (! psFitsWriteTableEmpty(out->fits, in->header, inTable->data[0], extname)) {
     852            psError(PS_ERR_IO, false, "failed to write empty table to %s", out->resolved_name);
     853            streaksExit("", PS_EXIT_DATA_ERROR);
     854        }
     855    }
     856
     857    if (!psFitsClose(out->fits)) {
     858        psError(PS_ERR_IO, false, "failed to close table %s", out->resolved_name);
     859        streaksExit("", PS_EXIT_DATA_ERROR);
     860    }
     861}
Note: See TracChangeset for help on using the changeset viewer.