IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 42885


Ignore:
Timestamp:
May 29, 2025, 3:28:25 PM (14 months ago)
Author:
tdeboer
Message:

build in safeties to prevent bad fits leading to random pattern row correction and bad cells

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tags/ipp-ops-20220906/psModules/src/detrend/pmPattern.c

    r42092 r42885  
    239239# define READNOISE 10 /* arbitrary number */
    240240    float sigma = sqrt(stats->robustMedian + PS_SQR(READNOISE));
     241    if(isnan(sigma)) sigma=20.;
    241242    float delta = PS_MIN (thresh * sigma, 2*nominalAmplitude);
    242243    float lower = stats->robustMedian - delta; // Lower bound for data
     
    246247    // if the noise from the background is too large
    247248    float significance = nominalAmplitude / sigma;
     249    significance = abs(significance);
    248250   
    249251    // XXX EAM : arbitrary number
    250252    if (isfinite(nominalAmplitude) && (significance < 1.0/6.0)) {
     253      psLogMsg("ppImage", PS_LOG_INFO, "Skipping row pattern correction for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance);
     254      return true;
     255    }
     256    //Add some safeties in case of bad fits
     257    if (isnan(significance) || (background < 0.0)) {
    251258      psLogMsg("ppImage", PS_LOG_INFO, "Skipping row pattern correction for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance);
    252259      return true;
     
    554561# define READNOISE 10 /* arbitrary number */
    555562    float sigma = sqrt(stats->robustMedian + PS_SQR(READNOISE));
     563    if(isnan(sigma)) sigma=20.; // XXX EAM : somewhat arbitrary number
    556564    float delta = PS_MIN (thresh * sigma, 5*nominalAmplitude);
    557565    float lower = stats->robustMedian - delta; // Lower bound for data
     
    561569    // if the noise from the background is too large
    562570    float significance = nominalAmplitude / sigma;
    563    
     571    significance = abs(significance);
     572     
    564573    // XXX EAM : arbitrary number
    565574    if (isfinite(nominalAmplitude) && (significance < 1.0/6.0)) {
     
    569578      return true;
    570579    }
     580    //Add some safeties in case of bad fits
     581    if (isnan(significance) || (background < 0.0)) {
     582      psLogMsg("ppImage", PS_LOG_INFO, "Skipping row pattern correction due to bad fit for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance);
     583      psFree(stats);
     584      psFree(rng);
     585      return true;
     586    }
     587   
    571588    psLogMsg("ppImage", PS_LOG_INFO, "Performing row pattern correction for %s, %s, stats: %f - %f - %f : %f %f %f\n", chipName, cellName, lower, background, upper, sigma, nominalAmplitude, significance);
    572589# endif   
     
    10051022    psFree(meanMask);
    10061023
     1024    return true;
     1025}
     1026
     1027// Compare the backs (cellBackgrounds) vector to each of the patterns loaded for this chip.
     1028// Choose the one that matches best & mask as appropriate
     1029// can we pass the backgrounds in using an image (8 x 8)
     1030bool pmPatternDeadCells(pmChip *chip, const psVector *backs, psImageMaskType maskVal)
     1031{
     1032    PS_ASSERT_PTR_NON_NULL(chip, false);
     1033    PS_ASSERT_VECTOR_NON_NULL(backs, false);
     1034    PS_ASSERT_VECTOR_SIZE(backs, chip->cells->n, false);
     1035    PS_ASSERT_VECTOR_TYPE(backs, PS_TYPE_F32, false);
     1036
     1037    // Look for the dead cell pattern cube in the analysis metadata.
     1038    // NOTE: not all chips have the pattern, skip if not found.
     1039    bool mdok;
     1040    psImage *deadCellPattern = (psImage *) psMetadataLookupPtr (&mdok, chip->analysis, "PTN.DEAD.CELL");
     1041    if (!mdok) {
     1042        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No DEAD CELL pattern for chip, skipping\n");
     1043        return true;
     1044    }
     1045
     1046    int numCells = backs->n;            // Number of cells
     1047    int numColsD = deadCellPattern->numCols;
     1048    int numRowsD = deadCellPattern->numRows;
     1049
     1050    assert (backs->n == numRowsD);
     1051
     1052    // The background values need to be normalized (divide by the median).
     1053    // First extract the valid data values
     1054    psVector *valid = psVectorAllocEmpty(backs->n, PS_TYPE_F32); // Mean for each cell
     1055    for (int i = 0; i < backs->n; i++) {
     1056        float value = backs->data.F32[i];
     1057        if (!isfinite(value)) { backs->data.F32[i] = NAN; continue; }
     1058        if (value > 50000.0)  { backs->data.F32[i] = NAN; continue; } // XXX warning: hard-wired value
     1059        psVectorAppend (valid, value);
     1060    }
     1061    if (valid->n == 0) {
     1062        psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n");
     1063        psFree (valid);
     1064        return true;
     1065    }
     1066
     1067    // Second, calculate the median
     1068    psVectorSortInPlace (valid);
     1069    int midPt = valid->n / 2.0;
     1070    float median = valid->n % 2 ? valid->data.F32[midPt] : 0.5*(valid->data.F32[midPt] + valid->data.F32[midPt-1]);
     1071    psFree (valid);
     1072
     1073    // Finally, renormalize:
     1074    for (int i = 0; i < backs->n; i++) {
     1075        if (!isfinite(backs->data.F32[i])) { continue; }
     1076        backs->data.F32[i] /= median;
     1077    }
     1078
     1079    // there are 2 columns (value & mask) for each mode, plus the constant mode
     1080    int nModes = numColsD / 2 + 1;
     1081   
     1082    psVector *stdev = psVectorAlloc(nModes, PS_TYPE_F32); // Mean for each cell
     1083
     1084    // measure stdev for each comparison
     1085    for (int i = 0; i < nModes; i++) {
     1086        float Sum1 = 0.0;
     1087        float Sum2 = 0.0;
     1088        int   Npts = 0;
     1089
     1090        // choose the column with the background values for this mode
     1091        int nModeColumn = 2*(i - 1);
     1092
     1093        for (int j = 0; j < backs->n; j++) {
     1094
     1095            float valObs = backs->data.F32[j];
     1096            float valRef = (i == 0) ? 0.0 : deadCellPattern->data.F32[j][nModeColumn];
     1097
     1098            if (!isfinite(valObs)) continue;
     1099            if (!isfinite(valRef)) continue;
     1100
     1101            float dS = valObs - valRef;
     1102            Sum1 += dS;
     1103            Sum2 += dS*dS;
     1104            Npts ++;
     1105        }
     1106        if (Npts == 0) {
     1107            // is this is an error?
     1108            // no valid data, ignore this test
     1109            psLogMsg("psModules.detrend", PS_LOG_DETAIL, "No valid backgrounds, skipping\n");
     1110            psFree (stdev);
     1111            return true;
     1112        }
     1113
     1114        float mean = Sum1 / Npts;
     1115        float sigma = sqrt(Sum2 / Npts - mean*mean);
     1116        stdev->data.F32[i] = sigma;
     1117        fprintf (stderr, "mode: %d, stdev: %f\n", i, sigma);
     1118    }
     1119
     1120    // loop over stdev and choose the lowest one
     1121    int   minI = 0;
     1122    float minV = stdev->data.F32[minI];
     1123
     1124    for (int i = 1; i < nModes; i++) {
     1125        if (stdev->data.F32[i] < minV) {
     1126            minI = i;
     1127            minV = stdev->data.F32[i];
     1128        }
     1129    }
     1130    psFree (stdev);
     1131
     1132    if (minI == 0) return true;
     1133
     1134    int nModeColumnMask = 2*(minI - 1) + 1;
     1135
     1136    // now mask bad cells
     1137    for (int i = 0; i < numCells; i++) {
     1138        if (deadCellPattern->data.F32[i][nModeColumnMask] > 0) continue;
     1139
     1140        pmCell *cell = chip->cells->data[i]; // Cell of interest
     1141        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     1142
     1143        psImage *mask = ro->mask; // mask of interest
     1144        int numCols = mask->numCols, numRows = mask->numRows; // Size of image
     1145       
     1146        for (int y = 0; y < numRows; y++) {
     1147            for (int x = 0; x < numCols; x++) {
     1148                mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskVal;
     1149            }
     1150        }
     1151    }
    10071152    return true;
    10081153}
Note: See TracChangeset for help on using the changeset viewer.