IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 21, 2024, 8:50:38 PM (2 years ago)
Author:
hgao
Message:

implement 2D overscan subtraction per cell as configured in OVERSCAN.2D.SUBSET

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2dbias/ppImage/src/ppImageDetrendPattern.c

    r42382 r42679  
    55#include "ppImage.h"
    66
    7 #define ESCAPE(STATUS,...) {                            \
    8         psError(PS_ERR_UNKNOWN, STATUS, __VA_ARGS__);   \
    9         psFree(view);                                   \
    10         return false;                                   \
    11     }
    12 
    13 static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue);
     7#define ESCAPE(STATUS, ...)                           \
     8    {                                                 \
     9        psError(PS_ERR_UNKNOWN, STATUS, __VA_ARGS__); \
     10        psFree(view);                                 \
     11        return false;                                 \
     12    }
     13
     14bool ppImageDoPatternForView(bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipename, const char *recipevalue);
    1415
    1516bool ppImageDetrendPatternRowApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options);
     
    2627    assert(inputView->readout == -1);
    2728
    28     if (!ppImageDetrendPatternRowApply (config, chip, inputView, options)) {
    29         return false;
    30     }
    31     if (!ppImageDetrendPatternContinuityApply (config, chip, inputView, options)) {
    32         return false;
    33     }
    34     if (!ppImageDetrendPatternCellApply (config, chip, inputView, options)) {
    35         return false;
    36     }
    37     if (!ppImageDetrendPatternDeadCellsApply (config, chip, inputView, options)) {
    38         return false;
    39     }
    40     return(true);
     29    if (!ppImageDetrendPatternRowApply(config, chip, inputView, options))
     30    {
     31        return false;
     32    }
     33    if (!ppImageDetrendPatternContinuityApply(config, chip, inputView, options))
     34    {
     35        return false;
     36    }
     37    if (!ppImageDetrendPatternCellApply(config, chip, inputView, options))
     38    {
     39        return false;
     40    }
     41    if (!ppImageDetrendPatternDeadCellsApply(config, chip, inputView, options))
     42    {
     43        return false;
     44    }
     45    return (true);
    4146}
    4247
     
    4550    bool status;
    4651
    47     if (!options->doPatternRow) return true;
    48    
     52    if (!options->doPatternRow)
     53        return true;
     54
    4955    assert(inputView->chip != -1);
    5056    assert(inputView->cell == -1);
     
    7379
    7480    pmHDU *hdu = pmHDUFromChip(chip);
    75     if (psMetadataLookupBool(&status, hdu->header, "PTRN_ROW")) {
    76         psLogMsg("ppImage", PS_LOG_INFO, "Not performing row pattern correction as it has already been done.");
    77         return true;
     81    if (psMetadataLookupBool(&status, hdu->header, "PTRN_ROW"))
     82    {
     83        psLogMsg("ppImage", PS_LOG_INFO, "Not performing row pattern correction as it has already been done.");
     84        return true;
    7885    }
    7986
     
    8592
    8693    // grab the PATTERN.ROW.AMP file
    87     pmFPAfile *PRAfile = psMetadataLookupPtr (&status, config->files, "PPIMAGE.PATTERN.ROW.AMP");
    88     if (!PRAfile) {
    89         psLogMsg("ppImage", PS_LOG_INFO, "Pattern Row Amplitude file not found, applying to all (with limits from ROW.SUBSET) ");
    90     }
    91        
     94    pmFPAfile *PRAfile = psMetadataLookupPtr(&status, config->files, "PPIMAGE.PATTERN.ROW.AMP");
     95    if (!PRAfile)
     96    {
     97        psLogMsg("ppImage", PS_LOG_INFO, "Pattern Row Amplitude file not found, applying to all (with limits from ROW.SUBSET) ");
     98    }
     99
    92100    pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
    93101    *view = *inputView;
    94102
    95103    pmCell *cell = NULL;
    96     while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
    97         // const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
    98         // const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
    99         // psWarning ("Looping through %s, %s\n", chipName, cellName);
    100 
    101         if (!cell->process || !cell->file_exists) {
    102             continue;
    103         }
    104 
    105         // this forces pmFPAfileRead of the PATTERN.ROW.AMP file (XXX but is this needed?)
    106         if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    107             ESCAPE(false, "load failure for Cell");
    108         }
    109            
    110         if (!cell->data_exists) {
    111             continue;
    112         }
    113 
    114         if (cell->readouts->n > 1) {
    115             psWarning ("Skipping Video Cell for ppImageDetrendPatternApply");
    116             continue;
    117         }
    118 
    119         // grab the corresponding cell
    120         if (PRAfile) {
    121             pmCell *PRAcell = pmFPAviewThisCell (view, PRAfile->fpa);
    122             psAssert (PRAcell, "found Pattern Row Amplitude file, but not cell?");
    123 
    124             // find the nominal signal amplitude (check the ghost and/or crosstalk recipe file)
    125             float amplitude = psMetadataLookupF32 (&status, PRAcell->analysis, "PTN.ROW.AMP");
    126             if (!status) amplitude = NAN;
    127            
    128             // put the value on the science cell
    129             psMetadataAddF32 (cell->analysis, PS_LIST_TAIL, "PTN.ROW.AMP", PS_META_REPLACE, "", amplitude);
    130         }
    131 
    132         bool doPattern = false;
    133         if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET")) {
    134             ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
    135         }
    136         if (!doPattern) continue;
    137 
    138         // switch to test threaded version
    139         if (true) {
    140             // I need to allocate a view here to be freed by the
    141             // called function below. 
    142             pmFPAview *myView = pmFPAviewAlloc(0); // View for local processing
    143             *myView = *view;
    144 
    145             // allocate a job, construct the arguments for this job
    146             psThreadJob *job = psThreadJobAlloc("PPIMAGE_PATTERN_ROW_CELL");
    147             psArrayAdd(job->args, 1, config);
    148             psArrayAdd(job->args, 1, input->fpa);
    149             psArrayAdd(job->args, 1, chip);
    150             psArrayAdd(job->args, 1, cell);
    151             psArrayAdd(job->args, 1, myView);
    152             psArrayAdd(job->args, 1, options);
    153             if (!psThreadJobAddPending(job)) {
    154                 return false;
    155             }
    156         } else {
    157             // bump the counter since it must be freed by the function below. 
    158             psMemIncrRefCounter (view); // View for local processing
    159             if (!ppImageDetrendPatternApplyCell (config, input->fpa, chip, cell, view, options)) {
    160                 return false;
    161             }
    162         }
     104    while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL)
     105    {
     106        // const char *chipName = psMetadataLookupStr(NULL, chip->concepts, "CHIP.NAME");
     107        // const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME");
     108        // psWarning ("Looping through %s, %s\n", chipName, cellName);
     109
     110        if (!cell->process || !cell->file_exists)
     111        {
     112            continue;
     113        }
     114
     115        // this forces pmFPAfileRead of the PATTERN.ROW.AMP file (XXX but is this needed?)
     116        if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE))
     117        {
     118            ESCAPE(false, "load failure for Cell");
     119        }
     120
     121        if (!cell->data_exists)
     122        {
     123            continue;
     124        }
     125
     126        if (cell->readouts->n > 1)
     127        {
     128            psWarning("Skipping Video Cell for ppImageDetrendPatternApply");
     129            continue;
     130        }
     131
     132        // grab the corresponding cell
     133        if (PRAfile)
     134        {
     135            pmCell *PRAcell = pmFPAviewThisCell(view, PRAfile->fpa);
     136            psAssert(PRAcell, "found Pattern Row Amplitude file, but not cell?");
     137
     138            // find the nominal signal amplitude (check the ghost and/or crosstalk recipe file)
     139            float amplitude = psMetadataLookupF32(&status, PRAcell->analysis, "PTN.ROW.AMP");
     140            if (!status)
     141                amplitude = NAN;
     142
     143            // put the value on the science cell
     144            psMetadataAddF32(cell->analysis, PS_LIST_TAIL, "PTN.ROW.AMP", PS_META_REPLACE, "", amplitude);
     145        }
     146
     147        bool doPattern = false;
     148        if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.ROW.SUBSET"))
     149        {
     150            ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
     151        }
     152        if (!doPattern)
     153            continue;
     154
     155        // switch to test threaded version
     156        if (true)
     157        {
     158            // I need to allocate a view here to be freed by the
     159            // called function below.
     160            pmFPAview *myView = pmFPAviewAlloc(0); // View for local processing
     161            *myView = *view;
     162
     163            // allocate a job, construct the arguments for this job
     164            psThreadJob *job = psThreadJobAlloc("PPIMAGE_PATTERN_ROW_CELL");
     165            psArrayAdd(job->args, 1, config);
     166            psArrayAdd(job->args, 1, input->fpa);
     167            psArrayAdd(job->args, 1, chip);
     168            psArrayAdd(job->args, 1, cell);
     169            psArrayAdd(job->args, 1, myView);
     170            psArrayAdd(job->args, 1, options);
     171            if (!psThreadJobAddPending(job))
     172            {
     173                return false;
     174            }
     175        }
     176        else
     177        {
     178            // bump the counter since it must be freed by the function below.
     179            psMemIncrRefCounter(view); // View for local processing
     180            if (!ppImageDetrendPatternApplyCell(config, input->fpa, chip, cell, view, options))
     181            {
     182                return false;
     183            }
     184        }
    163185    }
    164186
    165187    // wait here for the threaded jobs to finish
    166     // if no threads are allocated, this
    167     if (!psThreadPoolWait(true, true)) {
    168         psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction.");
    169         return false;
    170     }
    171 
    172     psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_ROW",PS_META_REPLACE,"PATTERN.ROW correction applied",true);
     188    // if no threads are allocated, this
     189    if (!psThreadPoolWait(true, true))
     190    {
     191        psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction.");
     192        return false;
     193    }
     194
     195    psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_ROW", PS_META_REPLACE, "PATTERN.ROW correction applied", true);
    173196    psFree(view);
    174    
     197
    175198    return true;
    176199}
     
    180203    bool status;
    181204
    182     if (!options->doPatternContinuity) return true;
     205    if (!options->doPatternContinuity)
     206        return true;
    183207
    184208    assert(inputView->chip != -1);
     
    188212    // see the comment for PATTERN.ROW; the same rules apply for PATTERN.CELL
    189213
    190     int numCells = chip->cells->n;       // Number of cells
     214    int numCells = chip->cells->n;                         // Number of cells
    191215    psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell?
    192     pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
     216    pmFPAview *view = pmFPAviewAlloc(0);                   // View for local processing
    193217    *view = *inputView;
    194218
    195219    pmHDU *hdu = pmHDUFromChip(chip);
    196     if (psMetadataLookupBool(&status, hdu->header, "PTRN_CON")) {
    197         psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction as it has already been done.");
    198         return true;
     220    if (psMetadataLookupBool(&status, hdu->header, "PTRN_CON"))
     221    {
     222        psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction as it has already been done.");
     223        return true;
    199224    }
    200225
     
    202227    psLogMsg("ppImage", PS_LOG_INFO, "Performing pattern continuity correction for %s\n", chipName);
    203228
    204     for (int i = 0; i < chip->cells->n; i++) {
    205         view->cell = i;
    206 
    207         pmCell *cell = chip->cells->data[i]; // Cell of interest
    208 
    209         if (cell->readouts->n > 1) {
    210             psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction on video cell.");
    211             continue;
    212         }
    213 
    214         bool doPattern = false;
    215         if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CONTINUITY.SUBSET")) {
    216             ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
    217         }
    218 
    219         if (doPattern) {
    220             tweak->data.U8[i] = 0xFF;
    221         }
     229    for (int i = 0; i < chip->cells->n; i++)
     230    {
     231        view->cell = i;
     232
     233        pmCell *cell = chip->cells->data[i]; // Cell of interest
     234
     235        if (cell->readouts->n > 1)
     236        {
     237            psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell continuity correction on video cell.");
     238            continue;
     239        }
     240
     241        bool doPattern = false;
     242        if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CONTINUITY.SUBSET"))
     243        {
     244            ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
     245        }
     246
     247        if (doPattern)
     248        {
     249            tweak->data.U8[i] = 0xFF;
     250        }
    222251    }
    223252
    224253    // Tweak the cells
    225254    if (!pmPatternContinuity(chip, tweak, options->patternCellBG, options->patternCellMean,
    226                              options->maskValue, options->darkMask,options->patternContinuityEdgeWidth)) {
    227         psFree(tweak);
    228         psFree(view);
    229         return false;
     255                             options->maskValue, options->darkMask, options->patternContinuityEdgeWidth))
     256    {
     257        psFree(tweak);
     258        psFree(view);
     259        return false;
    230260    }
    231261    psFree(tweak);
    232262    psFree(view);
    233263
    234     psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CON",PS_META_REPLACE,"PATTERN.CONTINUITY correction applied",true);
     264    psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CON", PS_META_REPLACE, "PATTERN.CONTINUITY correction applied", true);
    235265    return true;
    236266}
     
    240270    bool status;
    241271
    242     if (!options->doPatternCell) return true;
     272    if (!options->doPatternCell)
     273        return true;
    243274
    244275    assert(inputView->chip != -1);
     
    246277    assert(inputView->readout == -1);
    247278
    248     int numCells = chip->cells->n;       // Number of cells
     279    int numCells = chip->cells->n;                         // Number of cells
    249280    psVector *tweak = psVectorAlloc(numCells, PS_TYPE_U8); // Tweak cell?
    250     pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
     281    pmFPAview *view = pmFPAviewAlloc(0);                   // View for local processing
    251282    *view = *inputView;
    252283
    253284    pmHDU *hdu = pmHDUFromChip(chip);
    254     if (psMetadataLookupBool(&status, hdu->header, "PTRN_CEL")) {
    255         psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction as it has already been done.");
    256         return true;
     285    if (psMetadataLookupBool(&status, hdu->header, "PTRN_CEL"))
     286    {
     287        psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction as it has already been done.");
     288        return true;
    257289    }
    258290
     
    260292    psLogMsg("ppImage", PS_LOG_INFO, "Performing cell pattern correction for %s\n", chipName);
    261293
    262     for (int i = 0; i < chip->cells->n; i++) {
    263         view->cell = i;
    264 
    265         pmCell *cell = chip->cells->data[i]; // Cell of interest
    266 
    267         if (cell->readouts->n > 1) {
    268             psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction on video cell.");
    269             continue;
    270         }
    271 
    272         bool doPattern = false;
    273         if (!doPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET")) {
    274             ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
    275         }
    276         if (doPattern) {
    277             tweak->data.U8[i] = 0xFF;
    278         }
     294    for (int i = 0; i < chip->cells->n; i++)
     295    {
     296        view->cell = i;
     297
     298        pmCell *cell = chip->cells->data[i]; // Cell of interest
     299
     300        if (cell->readouts->n > 1)
     301        {
     302            psLogMsg("ppImage", PS_LOG_INFO, "Not performing cell pattern correction on video cell.");
     303            continue;
     304        }
     305
     306        bool doPattern = false;
     307        if (!ppImageDoPatternForView(&doPattern, config, chip, view, RECIPE_NAME, "PATTERN.CELL.SUBSET"))
     308        {
     309            ESCAPE(false, "Unable to determine whether row pattern matching should be applied.");
     310        }
     311        if (doPattern)
     312        {
     313            tweak->data.U8[i] = 0xFF;
     314        }
    279315    }
    280316
    281317    // Tweak the cells
    282318    if (!pmPatternCell(chip, tweak, options->patternCellBG, options->patternCellMean,
    283                        options->maskValue, options->darkMask)) {
    284         psFree(tweak);
    285         psFree(view);
    286         return false;
     319                       options->maskValue, options->darkMask))
     320    {
     321        psFree(tweak);
     322        psFree(view);
     323        return false;
    287324    }
    288325    psFree(tweak);
    289326    psFree(view);
    290327
    291     psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CEL",PS_META_REPLACE,"PATTERN.CELL correction applied",true);
     328    psMetadataAddBool(hdu->header, PS_LIST_TAIL, "PTRN_CEL", PS_META_REPLACE, "PATTERN.CELL correction applied", true);
    292329    return true;
    293330}
    294331
    295 bool ppImageDetrendPatternDeadCellsMask (pmChip *chip, psImageMaskType maskVal) {
    296 
    297     int numCells = chip->cells->n;       // Number of cells
     332bool ppImageDetrendPatternDeadCellsMask(pmChip *chip, psImageMaskType maskVal)
     333{
     334
     335    int numCells = chip->cells->n; // Number of cells
    298336
    299337    // now mask bad cells
    300     for (int i = 0; i < numCells; i++) {
    301         pmCell *cell = chip->cells->data[i]; // Cell of interest
     338    for (int i = 0; i < numCells; i++)
     339    {
     340        pmCell *cell = chip->cells->data[i];     // Cell of interest
    302341        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
    303342
    304         psImage *mask = ro->mask; // mask of interest
    305         int numCols = mask->numCols, numRows = mask->numRows; // Size of image
    306        
    307         for (int y = 0; y < numRows; y++) {
    308             for (int x = 0; x < numCols; x++) {
    309                 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal;
    310             }
    311         }
     343        psImage *mask = ro->mask;                             // mask of interest
     344        int numCols = mask->numCols, numRows = mask->numRows; // Size of image
     345
     346        for (int y = 0; y < numRows; y++)
     347        {
     348            for (int x = 0; x < numCols; x++)
     349            {
     350                mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal;
     351            }
     352        }
    312353    }
    313354    return true;
    314355}
    315356
    316 bool ppImageDetrendPatternDeadCellsXY42 (pmChip *chip, psImageMaskType maskVal) {
     357bool ppImageDetrendPatternDeadCellsXY42(pmChip *chip, psImageMaskType maskVal)
     358{
    317359
    318360    bool status;
    319361
    320362    // extract the MEDIAN_CELL_BACKGROUND values to check for problems
    321     int numCells = chip->cells->n;       // Number of cells
    322     psVector *cellBackground = psVectorAllocEmpty (numCells, PS_DATA_F32);
    323 
    324     for (int i = 0; i < numCells; i++) {
    325         pmCell *cell = chip->cells->data[i];;
    326 
    327         if (!cell->process || !cell->file_exists || !cell->data_exists) continue;
    328        
    329         // select the HDU for this cell
    330         pmHDU *cellHDU = pmHDUFromCell(cell);  // HDU of interest
    331        
    332         psF32 BackValue = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL");
    333         if (!status) continue;
    334 
    335         psF32 BackError = psMetadataLookupF32(&status, cellHDU->header, "BACK_ERR");
    336         if (!status) continue;
    337 
    338         if (BackValue == 0.0) continue;
    339         if (BackError == 0.0) continue;
    340 
    341         psVectorAppend (cellBackground, BackValue / BackError);
    342     }
    343 
    344     if (cellBackground->n < 0.375*numCells) {
    345         // Chip is bad, mask the whole thing
    346         ppImageDetrendPatternDeadCellsMask (chip, maskVal);
    347         psFree (cellBackground);
    348         return true;
     363    int numCells = chip->cells->n; // Number of cells
     364    psVector *cellBackground = psVectorAllocEmpty(numCells, PS_DATA_F32);
     365
     366    for (int i = 0; i < numCells; i++)
     367    {
     368        pmCell *cell = chip->cells->data[i];
     369        ;
     370
     371        if (!cell->process || !cell->file_exists || !cell->data_exists)
     372            continue;
     373
     374        // select the HDU for this cell
     375        pmHDU *cellHDU = pmHDUFromCell(cell); // HDU of interest
     376
     377        psF32 BackValue = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL");
     378        if (!status)
     379            continue;
     380
     381        psF32 BackError = psMetadataLookupF32(&status, cellHDU->header, "BACK_ERR");
     382        if (!status)
     383            continue;
     384
     385        if (BackValue == 0.0)
     386            continue;
     387        if (BackError == 0.0)
     388            continue;
     389
     390        psVectorAppend(cellBackground, BackValue / BackError);
     391    }
     392
     393    if (cellBackground->n < 0.375 * numCells)
     394    {
     395        // Chip is bad, mask the whole thing
     396        ppImageDetrendPatternDeadCellsMask(chip, maskVal);
     397        psFree(cellBackground);
     398        return true;
    349399    }
    350400
    351401    // Second, calculate the median
    352     psVectorSortInPlace (cellBackground);
     402    psVectorSortInPlace(cellBackground);
    353403    int midPt = cellBackground->n / 2.0;
    354     float median = cellBackground->n % 2 ? cellBackground->data.F32[midPt] : 0.5*(cellBackground->data.F32[midPt] + cellBackground->data.F32[midPt-1]);
    355     psFree (cellBackground);
     404    float median = cellBackground->n % 2 ? cellBackground->data.F32[midPt] : 0.5 * (cellBackground->data.F32[midPt] + cellBackground->data.F32[midPt - 1]);
     405    psFree(cellBackground);
    356406
    357407    // XXX hardwired number
    358     if (median < 3.0) {
    359         // Chip is bad, mask the whole thing
    360         ppImageDetrendPatternDeadCellsMask (chip, maskVal);
    361     }
    362     psFree (cellBackground);
     408    if (median < 3.0)
     409    {
     410        // Chip is bad, mask the whole thing
     411        ppImageDetrendPatternDeadCellsMask(chip, maskVal);
     412    }
     413    psFree(cellBackground);
    363414    return true;
    364415}
    365416
    366417// to apply the dead cell pattern, we need to transfer the pattern for this chip from the
    367 // pmFPAfile for the pattern to the one for the image being processed. 
     418// pmFPAfile for the pattern to the one for the image being processed.
    368419bool ppImageDetrendPatternDeadCellsApply(pmConfig *config, pmChip *chip, const pmFPAview *inputView, ppImageOptions *options)
    369420{
    370421    bool status;
    371422
    372     if (!options->doPatternDeadCells) return true;
     423    if (!options->doPatternDeadCells)
     424        return true;
    373425
    374426    assert(inputView->chip != -1);
     
    380432
    381433    pmHDU *hdu = pmHDUFromChip(chip);
    382     if (psMetadataLookupBool(&status, hdu->header, "PTRN_DED")) {
    383         psLogMsg("ppImage", PS_LOG_INFO, "Not performing dead cell pattern correction as it has already been done.");
    384         return true;
    385     }
    386 
    387     if (!strcmp (chipName, "XY40") || !strcmp (chipName, "XY42")) {
    388         // special case : check for BACK_VAL / BACK_ERR > 3 or < 3
    389         psLogMsg("ppImage", PS_LOG_INFO, "Using special case for XY40 and XY42");
    390         ppImageDetrendPatternDeadCellsXY42 (chip, options->blankMask);
    391         return true;
     434    if (psMetadataLookupBool(&status, hdu->header, "PTRN_DED"))
     435    {
     436        psLogMsg("ppImage", PS_LOG_INFO, "Not performing dead cell pattern correction as it has already been done.");
     437        return true;
     438    }
     439
     440    if (!strcmp(chipName, "XY40") || !strcmp(chipName, "XY42"))
     441    {
     442        // special case : check for BACK_VAL / BACK_ERR > 3 or < 3
     443        psLogMsg("ppImage", PS_LOG_INFO, "Using special case for XY40 and XY42");
     444        ppImageDetrendPatternDeadCellsXY42(chip, options->blankMask);
     445        return true;
    392446    }
    393447
    394448    pmFPAfile *pattern = psMetadataLookupPtr(&status, config->files, "PPIMAGE.PATTERN.DEAD.CELLS");
    395     if (!pattern) {
    396         psLogMsg("ppImage", PS_LOG_INFO, "Pattern Dead Cells file not found, skipping");
    397         return true;
     449    if (!pattern)
     450    {
     451        psLogMsg("ppImage", PS_LOG_INFO, "Pattern Dead Cells file not found, skipping");
     452        return true;
    398453    }
    399454
     
    401456    *view = *inputView;
    402457
    403     pmChip *patternChip = pmFPAviewThisChip (view, pattern->fpa);
     458    pmChip *patternChip = pmFPAviewThisChip(view, pattern->fpa);
    404459
    405460    // grab the pattern from the input pattern file chip
    406     psImage *deadCellPattern = (psImage *) psMetadataLookupPtr (&status, patternChip->analysis, "PTN.DEAD.CELL");
    407     if (!deadCellPattern) {
     461    psImage *deadCellPattern = (psImage *)psMetadataLookupPtr(&status, patternChip->analysis, "PTN.DEAD.CELL");
     462    if (!deadCellPattern)
     463    {
    408464        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No DEAD CELL pattern for chip, skipping\n");
    409         psFree (view);
    410         return true;
     465        psFree(view);
     466        return true;
    411467    }
    412468
    413469    // copy the pattern pointer to the chip of the image being processed
    414     psMetadataAddImage (chip->analysis, PS_LIST_TAIL, "PTN.DEAD.CELL", PS_META_REPLACE, "", deadCellPattern);
     470    psMetadataAddImage(chip->analysis, PS_LIST_TAIL, "PTN.DEAD.CELL", PS_META_REPLACE, "", deadCellPattern);
    415471
    416472    // extract the MEDIAN_CELL_BACKGROUND values to check for problems
    417     int numCells = chip->cells->n;       // Number of cells
    418     psVector *cellBackground = psVectorAllocEmpty (numCells, PS_DATA_F32);
     473    int numCells = chip->cells->n; // Number of cells
     474    psVector *cellBackground = psVectorAllocEmpty(numCells, PS_DATA_F32);
    419475
    420476    pmCell *cell = NULL;
    421     while ((cell = pmFPAviewNextCell(view, chip->parent, 1)) != NULL) {
    422         if (!cell->process || !cell->file_exists || !cell->data_exists) {
    423             psVectorAppend (cellBackground, NAN);
    424             continue;
    425         }
    426        
    427         // select the HDU for this cell
    428         pmHDU *cellHDU = pmHDUFromCell(cell);  // HDU of interest
    429        
    430         psF32 value = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL");
    431         if (!status) {
    432             psVectorAppend (cellBackground, NAN);
    433             continue;
    434         }
    435         psVectorAppend (cellBackground, value);
     477    while ((cell = pmFPAviewNextCell(view, chip->parent, 1)) != NULL)
     478    {
     479        if (!cell->process || !cell->file_exists || !cell->data_exists)
     480        {
     481            psVectorAppend(cellBackground, NAN);
     482            continue;
     483        }
     484
     485        // select the HDU for this cell
     486        pmHDU *cellHDU = pmHDUFromCell(cell); // HDU of interest
     487
     488        psF32 value = psMetadataLookupF32(&status, cellHDU->header, "BACK_VAL");
     489        if (!status)
     490        {
     491            psVectorAppend(cellBackground, NAN);
     492            continue;
     493        }
     494        psVectorAppend(cellBackground, value);
    436495    }
    437496
    438497    // match cellBackground pattern to registered patterns and mask as needed
    439     if (!pmPatternDeadCells(chip, cellBackground, options->blankMask)) {
    440         psFree(cellBackground);
    441         psFree(view);
    442         return false;
     498    if (!pmPatternDeadCells(chip, cellBackground, options->blankMask))
     499    {
     500        psFree(cellBackground);
     501        psFree(view);
     502        return false;
    443503    }
    444504    psFree(cellBackground);
     
    449509}
    450510
    451 static bool doPatternForView (bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue) {
     511bool ppImageDoPatternForView(bool *doit, const pmConfig *config, const pmChip *chip, const pmFPAview *view, const char *recipeName, const char *recipeValue)
     512{
    452513
    453514    *doit = false;
     
    456517
    457518    doPattern = pmConfigRecipeValueByView(config, recipeName, recipeValue, chip->parent, view);
    458    
    459     if (!doPattern) {
     519
     520    if (!doPattern)
     521    {
    460522        psError(PS_ERR_UNKNOWN, false, "Unable to determine whether row pattern matching should be applied.");
    461523        return false;
    462524    }
    463     if (doPattern->type == PS_DATA_BOOL) {
     525    if (doPattern->type == PS_DATA_BOOL)
     526    {
    464527        *doit = doPattern->data.B;
    465528        return true;
    466529    }
    467     if (doPattern->type == PS_DATA_STRING) {
     530    if (doPattern->type == PS_DATA_STRING)
     531    {
    468532        // expect a string of the form "000110001001" with at least view->cell entries
    469533        char *string = doPattern->data.str;
    470         if (strlen(string) < view->cell) {
    471             psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string (too few elements %d)", (int) strlen(string));
     534        if (strlen(string) < view->cell)
     535        {
     536            psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string (too few elements %d)", (int)strlen(string));
    472537            return false;
    473538        }
    474         switch (string[view->cell]) {
    475           case '0':
    476           case 'f':
    477           case 'F':
    478           case 'n':
    479           case 'N':
     539        switch (string[view->cell])
     540        {
     541        case '0':
     542        case 'f':
     543        case 'F':
     544        case 'n':
     545        case 'N':
    480546            *doit = false;
    481547            return true;
    482           case '1':
    483           case 't':
    484           case 'T':
    485           case 'y':
    486           case 'Y':
     548        case '1':
     549        case 't':
     550        case 'T':
     551        case 'y':
     552        case 'Y':
    487553            *doit = true;
    488554            return true;
    489           default:
     555        default:
    490556            psError(PS_ERR_UNKNOWN, true, "error in PATTERN.ROW.SUBSET chip string %s (unknown value %c))", string, string[view->cell]);
    491557            return false;
     
    497563}
    498564
    499 // thread safety :
    500 bool ppImageDetrendPatternApplyCell (pmConfig *config, pmFPA *fpa, pmChip *chip, pmCell *cell, pmFPAview *view, ppImageOptions *options) {
    501  
     565// thread safety :
     566bool ppImageDetrendPatternApplyCell(pmConfig *config, pmFPA *fpa, pmChip *chip, pmCell *cell, pmFPAview *view, ppImageOptions *options)
     567{
     568
    502569    // process each of the readouts
    503     pmReadout *readout;         // Readout from cell
    504     while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
    505         if (!readout->data_exists) {
    506             continue;
    507         }
    508 
    509         // Perform pattern correction
    510         if (!pmPatternRow(readout, options->patternRowOrder, options->patternRowIter,
    511                           options->patternRowRej, options->patternRowThresh, options->patternRowMean,
    512                           options->patternRowStdev, options->maskValue, options->darkMask)) {
    513             psFree (view);
    514             return false;
    515         }
    516     }
    517     psFree (view); // supplied view must be freeable
     570    pmReadout *readout; // Readout from cell
     571    while ((readout = pmFPAviewNextReadout(view, fpa, 1)) != NULL)
     572    {
     573        if (!readout->data_exists)
     574        {
     575            continue;
     576        }
     577
     578        // Perform pattern correction
     579        if (!pmPatternRow(readout, options->patternRowOrder, options->patternRowIter,
     580                          options->patternRowRej, options->patternRowThresh, options->patternRowMean,
     581                          options->patternRowStdev, options->maskValue, options->darkMask))
     582        {
     583            psFree(view);
     584            return false;
     585        }
     586    }
     587    psFree(view); // supplied view must be freeable
    518588    return true;
    519589}
    520590
    521 psVector *ppImageDetrendPatternCellFailures(pmFPAfile *input, const pmFPAview *inputView) {
    522    
     591psVector *ppImageDetrendPatternCellFailures(pmFPAfile *input, const pmFPAview *inputView)
     592{
     593
    523594    bool status = false;
    524595    pmCell *cell = NULL;
    525    
     596
    526597    pmFPAview *view = pmFPAviewAlloc(0); // View for local processing
    527598    *view = *inputView;
    528599
    529600    // extract the MEDIAN_CELL_BACKGROUND values to check for problems
    530     psVector *cellBackground = psVectorAllocEmpty (64, PS_DATA_F32);
    531     while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
    532         if (!cell->process || !cell->file_exists || !cell->data_exists) {
    533             psVectorAppend (cellBackground, NAN);
    534             continue;
    535         }
    536        
    537         // select the HDU for this cell
    538         pmHDU *hdu = pmHDUFromCell(cell);  // HDU of interest
    539        
    540         psF32 value = psMetadataLookupF32(&status, hdu->header, "BACK_VAL");
    541         psVectorAppend (cellBackground, value);
     601    psVector *cellBackground = psVectorAllocEmpty(64, PS_DATA_F32);
     602    while ((cell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL)
     603    {
     604        if (!cell->process || !cell->file_exists || !cell->data_exists)
     605        {
     606            psVectorAppend(cellBackground, NAN);
     607            continue;
     608        }
     609
     610        // select the HDU for this cell
     611        pmHDU *hdu = pmHDUFromCell(cell); // HDU of interest
     612
     613        psF32 value = psMetadataLookupF32(&status, hdu->header, "BACK_VAL");
     614        psVectorAppend(cellBackground, value);
    542615    }
    543616    return cellBackground;
Note: See TracChangeset for help on using the changeset viewer.