IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42890 for trunk/ppImage/src


Ignore:
Timestamp:
Jun 5, 2025, 3:34:33 PM (14 months ago)
Author:
tdeboer
Message:

updates to ppImage functions for 2D overscan correction

Location:
trunk/ppImage/src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppImage/src/ppImage.h

    r42382 r42890  
    100100    // options for the analysis
    101101    pmOverscanOptions *overscan;        // Overscan options
     102    pmOverscanStatOptions *primary;        // Overscan primary options
     103    pmOverscanStatOptions *secondary;      // Overscan secondary options
     104   
    102105    int burntoolTrails;
    103106    // binning parameters
     
    188191
    189192bool ppImageDetrendFree(pmConfig *config, pmFPAview *view);
     193bool ppImageDoPatternForView(bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue);
    190194bool ppImageFringeFree(pmConfig *config, pmFPAview *view);
    191195
  • trunk/ppImage/src/ppImageDetrendPattern.c

    r42382 r42890  
    1111    }
    1212
    13 static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue);
     13bool ppImageDoPatternForView(bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue);
    1414
    1515bool ppImageDetrendPatternRowApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options);
     
    131131
    132132        bool doPattern = false;
    133         if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET")) {
     133        if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET")) {
    134134            ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
    135135        }
     
    213213
    214214        bool doPattern = false;
    215         if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CONTINUITY.SUBSET")) {
     215        if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CONTINUITY.SUBSET")) {
    216216            ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
    217217        }
     
    271271
    272272        bool doPattern = false;
    273         if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET")) {
     273        if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET")) {
    274274            ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
    275275        }
     
    449449}
    450450
    451 static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue) {
     451bool ppImageDoPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue) {
    452452
    453453    *doit = false;
  • trunk/ppImage/src/ppImageDetrendReadout.c

    r42382 r42890  
    44
    55#include "ppImage.h"
     6
     7#define ESCAPE(STATUS, ...)                           \
     8    {                                                 \
     9        psError(PS_ERR_UNKNOWN, STATUS, __VA_ARGS__); \
     10        psFree(view);                                 \
     11        return false;                                 \
     12    }
    613
    714bool ppImageDetrendReadout(pmConfig *config, ppImageOptions *options, pmFPAview *view)
     
    117124    // Subtract the overscan
    118125    if (options->doOverscan) {
    119       if (!pmOverscanSubtract (input, options->overscan)) {
    120         psError(PS_ERR_UNKNOWN, false, "Unable to subtract overscan.");
    121         psFree(detview);
    122         return false;
    123       }
    124       // psLogMsg ("ppImage", 6, "subtract overscan: %f sec\n", psTimerMark ("detrend.readout"));
     126        bool doTwoDOverscan = false;
     127        if (options->overscan->TwoD) {
     128            pmChip *chip = pmFPAfileThisChip(config->files, view, "PPIMAGE.INPUT");
     129            if (!ppImageDoPatternForView(&doTwoDOverscan, config, chip, view, RECIPE_NAME, "OVERSCAN.2D.SUBSET"))
     130            {
     131                ESCAPE(false, "Unable to determine whether 2D Overscan subtraction should be applied.");
     132            }
     133            // set doTwoDOverscan to False if the cell background is larger than 500 ADU or smaller than zero (peculiar)
     134            if (doTwoDOverscan) {
     135                float backest = psMetadataLookupF32(NULL, input->parent->concepts, "CELL.BACKEST");
     136                if (!isfinite(backest) || backest > 500 || backest < 0) {
     137                    doTwoDOverscan = false;
     138                }
     139            }
     140        }
     141        if (!pmOverscanSubtract(input, options->overscan, doTwoDOverscan)) {
     142            psError(PS_ERR_UNKNOWN, false, "Unable to subtract overscan.");
     143            psFree(detview);
     144            return false;
     145        }
     146        // psLogMsg ("ppImage", 6, "subtract overscan: %f sec\n", psTimerMark ("detrend.readout"));
    125147    }
    126148
  • trunk/ppImage/src/ppImageOptions.c

    r42382 r42890  
    187187    // XXX EAM : we should abort on invalid options. default options?
    188188    if (psMetadataLookupBool(NULL, recipe, "OVERSCAN")) {
     189        bool mdok;
     190
    189191        options->doOverscan = true;
    190192
    191         // Do the overscan as a single value?
    192         bool overscanSingle = psMetadataLookupBool(NULL, recipe, "OVERSCAN.SINGLE");
     193        // Fill in the options
     194        options->overscan = pmOverscanOptionsAlloc();
     195
     196        // these options apply to the overscan regardless of layout
     197        options->overscan->single   = psMetadataLookupBool(NULL, recipe, "OVERSCAN.SINGLE");
     198        options->overscan->constant = psMetadataLookupBool(NULL, recipe, "OVERSCAN.CONSTANT");
     199        options->overscan->value    = psMetadataLookupF32(NULL, recipe, "OVERSCAN.VALUE");
     200        options->overscan->minValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MIN.VALID");
     201        if (!mdok) { options->overscan->minValid = 0.0; }
     202        options->overscan->maxValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MAX.VALID");
     203        if (!mdok) { options->overscan->maxValid = (float) 0x10000; }
     204        options->overscan->maskVal  = 0x0001;
     205
     206        // statistics for the primary region
     207        options->overscan->primary = pmOverscanStatOptionsAlloc();
    193208
    194209        // How do we fit it?
    195         pmFit overscanFit = PM_FIT_NONE; // Fit type for overscan
    196         int overscanOrder = 0;          // Order for overscan fit
    197210        psString fit = psMetadataLookupStr(NULL, recipe, "OVERSCAN.FIT");
    198211        if (! strcasecmp(fit, "POLYNOMIAL")) {
    199             overscanFit = PM_FIT_POLY_ORD;
    200             overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
     212            options->overscan->primary->fitType = PM_FIT_POLY_ORD;
     213            options->overscan->primary->order  = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
    201214        } else if (! strcasecmp(fit, "CHEBYSHEV")) {
    202             overscanFit = PM_FIT_POLY_CHEBY;
    203             overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
     215            options->overscan->primary->fitType = PM_FIT_POLY_CHEBY;
     216            options->overscan->primary->order  = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
    204217        } else if (! strcasecmp(fit, "SPLINE")) {
    205             overscanFit = PM_FIT_SPLINE;
     218            options->overscan->primary->fitType = PM_FIT_SPLINE;
    206219        } else if (strcasecmp(fit, "NONE")) {
    207220            psLogMsg(__func__, PS_LOG_WARN,
     
    213226        // What method do we use to measure the overscan statistics?
    214227        // XXX allow user to specify psStats types by name
    215         psStats *overscanStats = NULL;  // Statistics for overscan
    216228        psString stat = psMetadataLookupStr(NULL, recipe, "OVERSCAN.STAT");
    217229        if (! strcasecmp(stat, "MEAN")) {
    218             // overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
    219             overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
     230            options->overscan->primary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
    220231        } else if (! strcasecmp(stat, "MEDIAN")) {
    221             overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
     232            options->overscan->primary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
    222233        } else {
    223             psErrorStackPrint(stderr, "OVERSCAN.STAT (%s) in recipe %s is not one of MEAN or MEDIAN",
    224                               stat, RECIPE_NAME);
     234            psErrorStackPrint(stderr, "OVERSCAN.STAT (%s) in recipe %s is not one of MEAN or MEDIAN", stat, RECIPE_NAME);
    225235            exit(EXIT_FAILURE);
    226236        }
    227237
    228         bool mdok;
    229         int boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.BOXCAR");
    230         float gauss = psMetadataLookupF32(NULL, recipe, "OVERSCAN.GAUSS");
    231         float minValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MIN.VALID");
    232         if (!mdok) { minValid = 0.0; }
    233 
    234         float maxValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MAX.VALID");
    235         if (!mdok) { maxValid = (float) 0x10000; }
    236 
    237         // Fill in the options
    238         options->overscan = pmOverscanOptionsAlloc(overscanSingle, overscanFit, overscanOrder,
    239                                                    overscanStats, boxcar, gauss);
    240 
    241         options->overscan->constant = psMetadataLookupBool(NULL, recipe, "OVERSCAN.CONSTANT");
    242         options->overscan->value = psMetadataLookupF32(NULL, recipe, "OVERSCAN.VALUE");
    243         options->overscan->minValid = minValid;
    244         options->overscan->maxValid = maxValid;
    245         options->overscan->maskVal  = 0x0001;
    246 
    247         psFree(overscanStats);
     238        options->overscan->primary->boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.BOXCAR");
     239        options->overscan->primary->gauss  = psMetadataLookupF32(NULL, recipe, "OVERSCAN.GAUSS");
     240
     241        // Do the overscan as a single value?
     242        options->overscan->TwoD = psMetadataLookupBool(NULL, recipe, "OVERSCAN.2D");
     243        if (options->overscan->TwoD) {
     244
     245            // statistics for the secondary region
     246            options->overscan->secondary = pmOverscanStatOptionsAlloc();
     247
     248            // How do we fit it?
     249            psString fit = psMetadataLookupStr(NULL, recipe, "OVERSCAN.2D.FIT");
     250            if (! strcasecmp(fit, "POLYNOMIAL")) {
     251                options->overscan->secondary->fitType = PM_FIT_POLY_ORD;
     252                options->overscan->secondary->order   = psMetadataLookupS32(NULL, recipe, "OVERSCAN.2D.ORDER");
     253            } else if (! strcasecmp(fit, "CHEBYSHEV")) {
     254                options->overscan->secondary->fitType = PM_FIT_POLY_CHEBY;
     255                options->overscan->secondary->order   = psMetadataLookupS32(NULL, recipe, "OVERSCAN.2D.ORDER");
     256            } else if (! strcasecmp(fit, "SPLINE")) {
     257                options->overscan->secondary->fitType = PM_FIT_SPLINE;
     258            } else if (strcasecmp(fit, "NONE")) {
     259                psLogMsg(__func__, PS_LOG_WARN,
     260                         "OVERSCAN.2D.FIT (%s) in recipe %s is not one of NONE, POLYNOMIAL, or SPLINE",
     261                         fit, RECIPE_NAME);
     262                exit(EXIT_FAILURE);
     263            }
     264
     265            // What method do we use to measure the overscan statistics?
     266            // XXX allow user to specify psStats types by name
     267            psString stat = psMetadataLookupStr(NULL, recipe, "OVERSCAN.2D.STAT");
     268            if (! strcasecmp(stat, "MEAN")) {
     269                options->overscan->secondary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
     270            } else if (! strcasecmp(stat, "MEDIAN")) {
     271                options->overscan->secondary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
     272            } else {
     273                psErrorStackPrint(stderr, "OVERSCAN.2D.STAT (%s) in recipe %s is not one of MEAN or MEDIAN", stat, RECIPE_NAME);
     274                exit(EXIT_FAILURE);
     275            }
     276
     277            //Read the 2D overscan BIASSEC regions
     278            psString biassecslow = psMetadataLookupStr(NULL, recipe, "OVERSCAN.2D.BIASSECSLOW");
     279            options->overscan->secondary->biassecslow = psRegionFromString(biassecslow);
     280           
     281            psString biassecfast = psMetadataLookupStr(NULL, recipe, "OVERSCAN.2D.BIASSECFAST");
     282            options->overscan->secondary->biassecfast = psRegionFromString(biassecfast);
     283           
     284            options->overscan->secondary->boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.2D.BOXCAR");
     285            options->overscan->secondary->gauss  = psMetadataLookupF32(NULL, recipe, "OVERSCAN.2D.GAUSS");
     286        }
    248287    }
    249288
Note: See TracChangeset for help on using the changeset viewer.