IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42379


Ignore:
Timestamp:
Feb 8, 2023, 11:54:08 AM (3 years ago)
Author:
eugene
Message:

merge from eam_branches/ipp-20220316. no_warn strncpy; avoid passing NULL to sprintf %s; add code for PATTERN_DEAD_CELLS; fix error in PSF residual image evaluation; drop detailed mask analysis for binned images (not actually used)

Location:
trunk/psModules
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules

  • trunk/psModules/src/camera/pmFPABin.c

    r34843 r42379  
    3131    psImage *outImage;                  // Output image
    3232    if (out->image && out->image->numCols >= numColsOut && out->image->numRows >= numRowsOut) {
    33         outImage = out->image;
     33        outImage = out->image;
    3434    } else {
    35         outImage = out->image = psImageRecycle(out->image,  numColsOut, numRowsOut, PS_TYPE_F32);
     35        outImage = out->image = psImageRecycle(out->image,  numColsOut, numRowsOut, PS_TYPE_F32);
    3636    }
    3737
    3838    psImage *outMask;                   // Output mask
    3939    if (out->mask && out->mask->numCols >= numColsOut && out->mask->numRows >= numRowsOut) {
    40         outMask = out->mask;
     40        outMask = out->mask;
    4141    } else {
    42         outMask = out->mask = psImageRecycle(out->mask,  numColsOut, numRowsOut, PS_TYPE_IMAGE_MASK);
     42        outMask = out->mask = psImageRecycle(out->mask,  numColsOut, numRowsOut, PS_TYPE_IMAGE_MASK);
    4343    }
    4444
     
    5050    int yStart = psImageBinningGetFineY(binning, 0); // Starting input y for binning
    5151    for (int yOut = 0; yOut < numRowsOut; yOut++) {
    52         int yStop = psImageBinningGetFineY(binning, yOut + 1); // Stopping input y for binning
    53         yStop = PS_MIN(yStop, yLast);
    54         int xStart = psImageBinningGetFineX(binning, 0); // Starting input x for binning
    55         for (int xOut = 0; xOut < numColsOut; xOut++) {
    56             int xStop = psImageBinningGetFineX(binning, xOut + 1); // Stopping input x for binning
    57             xStop = PS_MIN(xStop, xLast);
     52        int yStop = psImageBinningGetFineY(binning, yOut + 1); // Stopping input y for binning
     53        yStop = PS_MIN(yStop, yLast);
     54        int xStart = psImageBinningGetFineX(binning, 0); // Starting input x for binning
     55        for (int xOut = 0; xOut < numColsOut; xOut++) {
     56            int xStop = psImageBinningGetFineX(binning, xOut + 1); // Stopping input x for binning
     57            xStop = PS_MIN(xStop, xLast);
    5858
    59             float sum = 0.0;            // Sum of pixels
    60             int numPix = 0;             // Number of pixels
     59            float sum = 0.0;            // Sum of pixels
     60            int numPix = 0;             // Number of pixels
    6161
    6262            for (int j = 0; j < Nbits; j++) { // Reset bit counter
    63               bitcounter[j] = 0;
     63                bitcounter[j] = 0;
    6464            }
    6565            pxlcount = 0;
    6666           
    67             for (int y = yStart; y < yStop; y++) {
    68                 for (int x = xStart; x < xStop; x++) {
    69                   if (inMask && (inMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] != 0)) {
    70                       for (int j = 0; j < Nbits; j++) {
    71                         psImageMaskType M = (psImageMaskType) pow(2,j);
    72                         if (inMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & M) {
    73                           bitcounter[j]++;
     67            for (int y = yStart; y < yStop; y++) {
     68                for (int x = xStart; x < xStop; x++) {
     69                    if (false && inMask && (inMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] != 0)) {
     70                        for (int j = 0; j < Nbits; j++) {
     71                            psImageMaskType M = (psImageMaskType) pow(2,j);
     72                            if (inMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & M) {
     73                                bitcounter[j]++;
     74                            }
    7475                        }
    75                       }
    7676                    }
    7777                 
    78                     if (inMask && (inMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) {
    79                         continue;
    80                     }
    81                     if (!isfinite(inImage->data.F32[y][x])) {
    82                         continue;
    83                     }
    84                     sum += inImage->data.F32[y][x];
    85                     numPix++;
     78                    if (inMask && (inMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) {
     79                        continue;
     80                    }
     81                    if (!isfinite(inImage->data.F32[y][x])) {
     82                        continue;
     83                    }
     84                    sum += inImage->data.F32[y][x];
     85                    numPix++;
    8686
    8787
    88                 }
    89             }
    90            
     88                }
     89            }
    9190           
    9291            // Values to set
    93             float imageValue;
     92            float imageValue;
    9493            psImageMaskType maskValue;
    95             if (numPix > 0) {
    96                 imageValue = sum / numPix;
    97                 maskValue = 0;
    98             } else {
    99                 imageValue = NAN;
    100                 maskValue = maskVal;
    101             }
    102             outImage->data.F32[yOut][xOut] = imageValue;
    103             if (0) {
    104               outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] = maskValue;
     94            if (numPix > 0) {
     95                imageValue = sum / numPix;
     96                maskValue = 0;
    10597            } else {
    106               outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] = 0;
     98                imageValue = NAN;
     99                maskValue = maskVal;
    107100            }
    108             for (int j = 0; j < Nbits; j++) {
    109               if (bitcounter[j] > 0.5 * pxlcount) {
    110                 outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] |= (int) pow(2,j);
    111               }
     101            outImage->data.F32[yOut][xOut] = imageValue;
     102            if (true) {
     103                outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] = maskValue;
     104            } else {
     105                outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] = 0;
    112106            }
    113             xStart = xStop;
    114         }
    115         yStart = yStop;
     107            // this loop is pointless if pxlcount == 0 (all masked)
     108            if (false) {
     109                if (pxlcount) {
     110                    for (int j = 0; j < Nbits; j++) {
     111                        if (bitcounter[j] > 0.5 * pxlcount) {
     112                            outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] |= (1 << j);
     113                        }
     114                    }
     115                } else {
     116                    outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] = maskValue;
     117                }
     118            }
     119            xStart = xStop;
     120        }
     121        yStart = yStop;
    116122    }
    117123
     
    120126    out->data_exists = true;
    121127    if (out->parent) {
    122         pmCell *outCell = out->parent;  // Output cell
    123         outCell->data_exists = outCell->parent->data_exists = true;
     128        pmCell *outCell = out->parent;  // Output cell
     129        outCell->data_exists = outCell->parent->data_exists = true;
    124130
    125         // We would copy the concepts from the input cell, except that is done by pmFPACopy,
    126         // pmChipCopyStructure, etc.  This function just does the mechanics of binning.
    127         // We don't even update the CELL.XBIN, CELL.YBIN because that would apply the correction twice.
     131        // We would copy the concepts from the input cell, except that is done by pmFPACopy,
     132        // pmChipCopyStructure, etc.  This function just does the mechanics of binning.
     133        // We don't even update the CELL.XBIN, CELL.YBIN because that would apply the correction twice.
    128134    }
    129135
  • trunk/psModules/src/camera/pmFPAfile.c

    r42338 r42379  
    557557    if (!strcasecmp(type, "PATTERN.ROW.AMP"))     {
    558558        return PM_FPA_FILE_PATTERN_ROW_AMP;
     559    }
     560    if (!strcasecmp(type, "PATTERN.DEAD.CELLS"))     {
     561        return PM_FPA_FILE_PATTERN_DEAD_CELLS;
    559562    }
    560563    if (!strcasecmp(type, "SUBKERNEL"))     {
     
    614617      case PM_FPA_FILE_PATTERN_ROW_AMP:
    615618        return ("PATTERN.ROW.AMP");
     619      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
     620        return ("PATTERN.DEAD.CELLS");
    616621      case PM_FPA_FILE_SUBKERNEL:
    617622        return ("SUBKERNEL");
  • trunk/psModules/src/camera/pmFPAfile.h

    r42338 r42379  
    5353    PM_FPA_FILE_PATTERN,
    5454    PM_FPA_FILE_PATTERN_ROW_AMP,
     55    PM_FPA_FILE_PATTERN_DEAD_CELLS,
    5556    PM_FPA_FILE_LINEARITY,
    5657    PM_FPA_FILE_NEWNONLIN,
  • trunk/psModules/src/camera/pmFPAfileFitsIO.c

    r41892 r42379  
    153153      case PM_FPA_FILE_KH_CORRECT:
    154154      case PM_FPA_FILE_PATTERN_ROW_AMP:
     155      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
    155156        {
    156157          pmHDU *hdu = pmFPAviewThisHDU(view, fpa);
  • trunk/psModules/src/camera/pmFPAfileIO.c

    r42338 r42379  
    256256        status = pmPatternRowAmpRead(view, file, config);
    257257        break;
     258      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
     259        status = pmPatternDeadCellsRead(view, file, config);
     260        break;
    258261      case PM_FPA_FILE_SX:
    259262      case PM_FPA_FILE_RAW:
     
    368371      case PM_FPA_FILE_KH_CORRECT:
    369372      case PM_FPA_FILE_PATTERN_ROW_AMP:
     373      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
    370374      case PM_FPA_FILE_JPEG:
    371375      case PM_FPA_FILE_KAPA:
     
    460464      return true;
    461465    }
     466    if (file->type == PM_FPA_FILE_PATTERN_DEAD_CELLS) {
     467      psTrace("psModules.camera", 6, "skip write for %s, no write function defined", file->name);
     468      return true;
     469    }
    462470
    463471    // open the file if not yet opened
     
    560568      case PM_FPA_FILE_PATTERN_ROW_AMP:
    561569        psError(PS_ERR_IO, true, "cannot write type PATTERN.ROW.AMP (%s)", file->name);
     570        break;
     571
     572      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
     573        psError(PS_ERR_IO, true, "cannot write type PATTERN.DEAD.CELLS (%s)", file->name);
    562574        break;
    563575
     
    638650      case PM_FPA_FILE_KH_CORRECT:
    639651      case PM_FPA_FILE_PATTERN_ROW_AMP:
     652      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
    640653      case PM_FPA_FILE_LINEARITY:
    641654      case PM_FPA_FILE_NEWNONLIN:
     
    718731      case PM_FPA_FILE_KH_CORRECT:
    719732      case PM_FPA_FILE_PATTERN_ROW_AMP:
     733      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
    720734      case PM_FPA_FILE_EXPNUM:
    721735        psTrace ("psModules.camera", 6, "NOT freeing %s (%s) : save for further analysis\n", file->filename, file->name);
     
    883897      case PM_FPA_FILE_KH_CORRECT:
    884898      case PM_FPA_FILE_PATTERN_ROW_AMP:
     899      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
    885900      case PM_FPA_FILE_LINEARITY:
    886901      case PM_FPA_FILE_NEWNONLIN:
     
    10891104      case PM_FPA_FILE_KH_CORRECT:
    10901105      case PM_FPA_FILE_PATTERN_ROW_AMP:
     1106      case PM_FPA_FILE_PATTERN_DEAD_CELLS:
    10911107      case PM_FPA_FILE_SX:
    10921108      case PM_FPA_FILE_RAW:
  • trunk/psModules/src/detrend/pmDark.c

    r40454 r42379  
    129129    } else {
    130130        if (!ordinateParseConcept(value, readout, name)) {
    131             psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", rule, name);
     131            psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", "NULL", name);
    132132            return false;
    133133        }
  • trunk/psModules/src/detrend/pmDetrendDB.c

    r41892 r42379  
    113113        DETREND_STRING_CASE(KH_CORRECT);
    114114        DETREND_STRING_CASE(PATTERN_ROW_AMP);
     115        DETREND_STRING_CASE(PATTERN_DEAD_CELLS);
    115116    default:
    116117        return NULL;
  • trunk/psModules/src/detrend/pmDetrendDB.h

    r42338 r42379  
    4343    PM_DETREND_TYPE_KH_CORRECT,
    4444    PM_DETREND_TYPE_PATTERN_ROW_AMP,
     45    PM_DETREND_TYPE_PATTERN_DEAD_CELLS,
    4546} pmDetrendType;
    4647
  • trunk/psModules/src/detrend/pmOverscan.c

    r42356 r42379  
    3838    opts->order = order;
    3939    opts->stat = psMemIncrRefCounter(stat);
     40
     41    opts->minValid = 0.0; // default value if not defined
     42    opts->maxValid = (float) 0x10000; // default value if not defined
     43    opts->maskVal = 0x0001; // default value if not defined
    4044
    4145    // Smoothing
     
    314318        psFree(reducedScalar);
    315319
     320        // EAM 2022.03.29 : if the calculated overscan value is below the threshold,
     321        // declare the readout dead and mask
     322
     323        if ((reduced < overscanOpts->minValid) || (reduced > overscanOpts->maxValid)) {
     324            fprintf (stderr, "bad overscan (1) %f, masking readout\n", reduced);
     325            psImage *mask = input->mask;
     326            for (int y = 0; y < mask->numRows; y++) {
     327                for (int x = 0; x < mask->numCols; x++) {
     328                    mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= overscanOpts->maskVal;
     329                }
     330            }
     331        }
     332
    316333        psFree(stats);
    317334        return true;
     
    371388        // generate stats of overscan vector for header
    372389        {
    373           psString comment = NULL;    // Comment to add
    374           psStats *vectorStats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
    375           if (!psVectorStats (vectorStats, reduced, NULL, NULL, 0)) {
    376               psError(PS_ERR_UNKNOWN, false, "failure to measure stats");
    377               return false;
    378           }
    379           psStringAppend(&comment, "Mean Overscan value: %f", vectorStats->sampleMean);
    380           psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, "");
    381           psFree(comment);
    382 
    383           // write metadata header value
    384           psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan mean", vectorStats->sampleMean);
    385           psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", vectorStats->sampleStdev);
    386           psFree (vectorStats);
     390            psString comment = NULL;    // Comment to add
     391            psStats *vectorStats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
     392            if (!psVectorStats (vectorStats, reduced, NULL, NULL, 0)) {
     393                psError(PS_ERR_UNKNOWN, false, "failure to measure stats");
     394                return false;
     395            }
     396            psStringAppend(&comment, "Mean Overscan value: %f", vectorStats->sampleMean);
     397            psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, "");
     398            psFree(comment);
     399
     400            // write metadata header value
     401            psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan mean", vectorStats->sampleMean);
     402            psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", vectorStats->sampleStdev);
     403
     404            // EAM 2022.03.29 : if the calculated overscan value is below the threshold,
     405            // declare the readout dead and mask
     406         
     407            if ((vectorStats->sampleMean < overscanOpts->minValid) || (vectorStats->sampleMean > overscanOpts->maxValid)) {
     408                fprintf (stderr, "bad overscan (2) %f, masking readout\n", vectorStats->sampleMean);
     409                psImage *mask = input->mask;
     410                for (int y = 0; y < mask->numRows; y++) {
     411                    for (int x = 0; x < mask->numCols; x++) {
     412                        mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= overscanOpts->maskVal;
     413                    }
     414                }
     415            }
     416
     417            psFree (vectorStats);
    387418        }
    388419
     
    469500          psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_VAL", PS_META_REPLACE, "Overscan mean", vectorStats->sampleMean);
    470501          psMetadataAddF32(hdu->header, PS_LIST_TAIL, "OVER_SIG", PS_META_REPLACE, "Overscan stdev", vectorStats->sampleStdev);
     502
     503          // EAM 2022.03.29 : if the calculated overscan value is below the threshold,
     504          // declare the readout dead and mask
     505         
     506          if ((vectorStats->sampleMean < overscanOpts->minValid) || (vectorStats->sampleMean > overscanOpts->maxValid)) {
     507              fprintf (stderr, "bad overscan (3) %f, masking readout\n", vectorStats->sampleMean);
     508              psImage *mask = input->mask;
     509              for (int y = 0; y < mask->numRows; y++) {
     510                  for (int x = 0; x < mask->numCols; x++) {
     511                      mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= overscanOpts->maskVal;
     512                  }
     513              }
     514          }
    471515          psFree (vectorStats);
    472516        }
  • trunk/psModules/src/detrend/pmOverscan.h

    r14505 r42379  
    4343    int boxcar;                         ///< Boxcar smoothing radius
    4444    float gauss;                        ///< Gaussian smoothing sigma
     45    float minValid;                     ///< if overscan is too low, readout is dead : mask
     46    float maxValid;                     ///< if overscan is too high, readout is dead : mask
     47    psImageMaskType maskVal;            ///< Mask value to give dead readouts
     48
    4549    // Outputs
    4650    psPolynomial1D *poly;               ///< Result of polynomial fit
  • trunk/psModules/src/detrend/pmPattern.c

    r42092 r42379  
    10051005    psFree(meanMask);
    10061006
     1007    return true;
     1008}
     1009
     1010// Compare the backs (cellBackgrounds) vector to each of the patterns loaded for this chip.
     1011// Choose the one that matches best & mask as appropriate
     1012// can we pass the backgrounds in using an image (8 x 8)
     1013bool pmPatternDeadCells(pmChip *chip, const psVector *backs, psImageMaskType maskVal)
     1014{
     1015    PS_ASSERT_PTR_NON_NULL(chip, false);
     1016    PS_ASSERT_VECTOR_NON_NULL(backs, false);
     1017    PS_ASSERT_VECTOR_SIZE(backs, chip->cells->n, false);
     1018    PS_ASSERT_VECTOR_TYPE(backs, PS_TYPE_F32, false);
     1019
     1020    // Look for the dead cell pattern cube in the analysis metadata.
     1021    // NOTE: not all chips have the pattern, skip if not found.
     1022    bool mdok;
     1023    psImage *deadCellPattern = (psImage *) psMetadataLookupPtr (&mdok, chip->analysis, "PTN.DEAD.CELL");
     1024    if (!mdok) {
     1025        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No DEAD CELL pattern for chip, skipping\n");
     1026        return true;
     1027    }
     1028
     1029    int numCells = backs->n;            // Number of cells
     1030    int numColsD = deadCellPattern->numCols;
     1031    int numRowsD = deadCellPattern->numRows;
     1032
     1033    assert (backs->n == numRowsD);
     1034
     1035    // The background values need to be normalized (divide by the median).
     1036    // First extract the valid data values
     1037    psVector *valid = psVectorAllocEmpty(backs->n, PS_TYPE_F32); // Mean for each cell
     1038    for (int i = 0; i < backs->n; i++) {
     1039        float value = backs->data.F32[i];
     1040        if (!isfinite(value)) { backs->data.F32[i] = NAN; continue; }
     1041        if (value > 50000.0)  { backs->data.F32[i] = NAN; continue; } // XXX warning: hard-wired value
     1042        psVectorAppend (valid, value);
     1043    }
     1044    if (valid->n == 0) {
     1045        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n");
     1046        psFree (valid);
     1047        return true;
     1048    }
     1049
     1050    // Second, calculate the median
     1051    psVectorSortInPlace (valid);
     1052    int midPt = valid->n / 2.0;
     1053    float median = valid->n % 2 ? valid->data.F32[midPt] : 0.5*(valid->data.F32[midPt] + valid->data.F32[midPt-1]);
     1054    psFree (valid);
     1055
     1056    // Finally, renormalize:
     1057    for (int i = 0; i < backs->n; i++) {
     1058        if (!isfinite(backs->data.F32[i])) { continue; }
     1059        backs->data.F32[i] /= median;
     1060    }
     1061
     1062    // there are 2 columns (value & mask) for each mode, plus the constant mode
     1063    int nModes = numColsD / 2 + 1;
     1064   
     1065    psVector *stdev = psVectorAlloc(nModes, PS_TYPE_F32); // Mean for each cell
     1066
     1067    // measure stdev for each comparison
     1068    for (int i = 0; i < nModes; i++) {
     1069        float Sum1 = 0.0;
     1070        float Sum2 = 0.0;
     1071        int   Npts = 0;
     1072
     1073        // choose the column with the background values for this mode
     1074        int nModeColumn = 2*(i - 1);
     1075
     1076        for (int j = 0; j < backs->n; j++) {
     1077
     1078            float valObs = backs->data.F32[j];
     1079            float valRef = (i == 0) ? 0.0 : deadCellPattern->data.F32[j][nModeColumn];
     1080
     1081            if (!isfinite(valObs)) continue;
     1082            if (!isfinite(valRef)) continue;
     1083
     1084            float dS = valObs - valRef;
     1085            Sum1 += dS;
     1086            Sum2 += dS*dS;
     1087            Npts ++;
     1088        }
     1089        if (Npts == 0) {
     1090            // is this is an error?
     1091            // no valid data, ignore this test
     1092            psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n");
     1093            psFree (stdev);
     1094            return true;
     1095        }
     1096
     1097        float mean = Sum1 / Npts;
     1098        float sigma = sqrt(Sum2 / Npts - mean*mean);
     1099        stdev->data.F32[i] = sigma;
     1100        fprintf (stderr, "mode: %d, stdev: %f\n", i, sigma);
     1101    }
     1102
     1103    // loop over stdev and choose the lowest one
     1104    int   minI = 0;
     1105    float minV = stdev->data.F32[minI];
     1106
     1107    for (int i = 1; i < nModes; i++) {
     1108        if (stdev->data.F32[i] < minV) {
     1109            minI = i;
     1110            minV = stdev->data.F32[i];
     1111        }
     1112    }
     1113    psFree (stdev);
     1114
     1115    if (minI == 0) return true;
     1116
     1117    int nModeColumnMask = 2*(minI - 1) + 1;
     1118
     1119    // now mask bad cells
     1120    for (int i = 0; i < numCells; i++) {
     1121        if (deadCellPattern->data.F32[i][nModeColumnMask] > 0) continue;
     1122
     1123        pmCell *cell = chip->cells->data[i]; // Cell of interest
     1124        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     1125
     1126        psImage *mask = ro->mask; // mask of interest
     1127        int numCols = mask->numCols, numRows = mask->numRows; // Size of image
     1128       
     1129        for (int y = 0; y < numRows; y++) {
     1130            for (int x = 0; x < numCols; x++) {
     1131                mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal;
     1132            }
     1133        }
     1134    }
    10071135    return true;
    10081136}
  • trunk/psModules/src/detrend/pmPattern.h

    r35081 r42379  
    8686
    8787
     88bool pmPatternDeadCells(pmChip *chip, const psVector *backs, psImageMaskType maskVal);
     89
    8890/// @}
    8991#endif
  • trunk/psModules/src/detrend/pmPatternIO.c

    r41892 r42379  
    482482}
    483483
    484 // read the set of tables, one for each chip
     484// Read the set of tables, one for each chip.  The values are saved on the cell->analysis
     485// metadata of the pmFPAfile associated with the pattern file.  Later, when this is used (e.g.,
     486// ppImageDetrendPatternRowApply), the values are transferred to the cell->analysis metadata of
     487// the pmFPAfile for the image being processed.
    485488bool pmPatternRowAmpReadChips (pmFPAfile *file) {
    486489
     
    560563    return true;
    561564}
     565
     566/**************** PatternDeadCells I/O *************************/
     567
     568bool pmPatternDeadCellsRead (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     569    {
     570        // read the full model in one pass: require the level to be FPA
     571        if (view->chip != -1) {
     572            psError(PS_ERR_IO, false, "Pattern Dead Cells must be read at the FPA level");
     573            return false;
     574        }
     575
     576        if (!pmPatternDeadCellsReadFPA (file)) {
     577            psError(PS_ERR_IO, false, "Failed to read Pattern Dead Cells for fpa");
     578            return false;
     579        }
     580        return true;
     581    }
     582
     583// read in all chip-level Pattern Dead Cells data for this FPA
     584bool pmPatternDeadCellsReadFPA (pmFPAfile *file) {
     585
     586    if (!pmPatternDeadCellsReadChips (file)) {
     587        psError(PS_ERR_IO, false, "Failed to read Pattern Dead Cells for chips");
     588        return false;
     589    }
     590
     591    return true;
     592}
     593
     594// Read the set of dead cell image cubes, one for each chip.  The values are saved on the
     595// chip->analysis metadata of the pmFPAfile associated with the pattern file.  Later, when this
     596// is used (e.g., ppImageDetrendPatternDeadCellsApply), the values are transferred to the
     597// chip->analysis metadata of the pmFPAfile for the image being processed.
     598bool pmPatternDeadCellsReadChips (pmFPAfile *file) {
     599
     600    bool haveData, status;
     601
     602    // loop over the extensions
     603    // for each extension, use the extname (eg, XY01.ded) to assign to a chip
     604
     605    // move to the start of the file
     606    haveData = psFitsMoveExtNum (file->fits, 1, false);
     607    if (!haveData) {
     608        psError(PS_ERR_IO, false, "Failed to read even the first extension?");
     609        return false;
     610    }
     611
     612    int nGood = 0;
     613    while (haveData) {
     614
     615        // load the header
     616        psMetadata *header = psFitsReadHeader(NULL, file->fits); // The FITS header
     617        if (!header) psAbort("cannot read dead cell header");
     618
     619        // load the full model in one shot
     620        psImage *deadCellData = psFitsReadImage(file->fits, psRegionSet(0,0,0,0), 0); // dead cell patterns
     621        if (!deadCellData) psAbort("cannot read dead cell pattern");
     622       
     623        // determine the chip (not all chips have DEAD CELL patterns)
     624        char *extname = psMetadataLookupStr (&status, header, "EXTNAME");
     625        psLogMsg ("psModules.detrend", 8, "read dead cell pattern for extname %s\n", extname);
     626
     627        // I expect to find a name of the form: chipName.ded (eg, XY01.ded)
     628        // where chipName like 'XY01'
     629        psAssert (strlen(extname) == 8, "invalid extension %s", extname);
     630        psAssert (extname[5] == 'd', "invalid extension %s", extname);
     631        psAssert (extname[6] == 'e', "invalid extension %s", extname);
     632        psAssert (extname[7] == 'd', "invalid extension %s", extname);
     633
     634        char chipName[5];
     635        strncpy (chipName, extname, 4);
     636        chipName[4] = 0;
     637
     638        pmChip *chip = pmConceptsChipFromName (file->fpa, chipName);
     639        if (!chip) psAbort ("invalid chip?");
     640
     641        psMetadataAddImage (chip->analysis, PS_LIST_TAIL, "PTN.DEAD.CELL", PS_META_REPLACE, "", deadCellData);
     642        psFree (deadCellData);
     643        psFree (header);
     644
     645        // move to the next extension
     646        haveData = psFitsMoveExtNum (file->fits, 1, true);
     647        nGood ++;
     648    }
     649    psLogMsg ("psModules.detrend", 4, "read patterns for %d chips from Pattern Dead Cells file\n", nGood);
     650
     651    return true;
     652}
  • trunk/psModules/src/detrend/pmPatternIO.h

    r41892 r42379  
    4040bool pmPatternRowAmpReadChips (pmFPAfile *file);
    4141
     42bool pmPatternDeadCellsRead (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
     43bool pmPatternDeadCellsReadFPA (pmFPAfile *file);
     44bool pmPatternDeadCellsReadChips (pmFPAfile *file);
     45
    4246#endif
  • trunk/psModules/src/extras/pmVisualUtils.c

    r34085 r42379  
    222222    }
    223223
    224     strncpy(name, addNodeName, MAX_COMPONENT_LENGTH);
     224    ps_strncpy_nowarn(name, addNodeName, MAX_COMPONENT_LENGTH);
    225225    char *pname = name+1;               // Take off the period
    226226    // Iterate through the components of addNodeName.  Strip off the first
  • trunk/psModules/src/objects/models

    • Property svn:ignore
      •  

        old new  
        11.deps
         2.dirstamp
  • trunk/psModules/src/objects/pmModel.c

    r36859 r42379  
    344344
    345345                // 2D residual variations are set for the true source position
    346                 pixelValue += Io*(Vo + XoSave*Vx + XoSave*Vy);
     346                pixelValue += Io*(Vo + XoSave*Vx + YoSave*Vy);
    347347            }
    348348
Note: See TracChangeset for help on using the changeset viewer.