IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules

  • 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}
Note: See TracChangeset for help on using the changeset viewer.