Changeset 25027 for branches/pap/psModules
- Timestamp:
- Aug 7, 2009, 4:08:25 PM (17 years ago)
- Location:
- branches/pap
- Files:
-
- 82 edited
- 10 copied
-
. (modified) (1 prop)
-
psModules (modified) (1 prop)
-
psModules/src/astrom/pmAstrometryDistortion.c (modified) (1 diff)
-
psModules/src/astrom/pmAstrometryObjects.c (modified) (7 diffs)
-
psModules/src/astrom/pmAstrometryObjects.h (modified) (1 diff)
-
psModules/src/astrom/pmAstrometryUtils.c (modified) (2 diffs)
-
psModules/src/astrom/pmAstrometryVisual.c (modified) (1 diff)
-
psModules/src/astrom/pmAstrometryWCS.c (modified) (2 diffs)
-
psModules/src/astrom/pmAstrometryWCS.h (modified) (1 diff)
-
psModules/src/camera/Makefile.am (modified) (2 diffs)
-
psModules/src/camera/pmFPABin.c (modified) (3 diffs)
-
psModules/src/camera/pmFPACopy.c (modified) (3 diffs)
-
psModules/src/camera/pmFPAMaskWeight.c (modified) (11 diffs)
-
psModules/src/camera/pmFPAMaskWeight.h (modified) (4 diffs)
-
psModules/src/camera/pmFPARead.c (modified) (25 diffs)
-
psModules/src/camera/pmFPARead.h (modified) (6 diffs)
-
psModules/src/camera/pmFPAWrite.c (modified) (2 diffs)
-
psModules/src/camera/pmFPAfileFringeIO.c (copied) (copied from trunk/psModules/src/camera/pmFPAfileFringeIO.c )
-
psModules/src/camera/pmFPAfileFringeIO.h (copied) (copied from trunk/psModules/src/camera/pmFPAfileFringeIO.h )
-
psModules/src/camera/pmFPAfileIO.c (modified) (3 diffs)
-
psModules/src/camera/pmHDU.c (modified) (1 diff)
-
psModules/src/camera/pmHDUGenerate.c (modified) (4 diffs)
-
psModules/src/camera/pmReadoutFake.c (modified) (3 diffs)
-
psModules/src/camera/pmReadoutStack.c (modified) (2 diffs)
-
psModules/src/concepts/pmConcepts.c (modified) (1 diff)
-
psModules/src/concepts/pmConceptsRead.c (modified) (1 diff)
-
psModules/src/concepts/pmConceptsStandard.c (modified) (4 diffs)
-
psModules/src/config/pmConfig.c (modified) (2 diffs)
-
psModules/src/config/pmErrorCodes.dat (modified) (1 diff)
-
psModules/src/detrend/Makefile.am (modified) (2 diffs)
-
psModules/src/detrend/pmDark.c (modified) (17 diffs)
-
psModules/src/detrend/pmDark.h (modified) (2 diffs)
-
psModules/src/detrend/pmDetrendDB.c (modified) (1 diff)
-
psModules/src/detrend/pmDetrendDB.h (modified) (1 diff)
-
psModules/src/detrend/pmDetrendThreads.c (modified) (1 diff)
-
psModules/src/detrend/pmFringeStats.c (modified) (10 diffs)
-
psModules/src/detrend/pmFringeStats.h (modified) (2 diffs)
-
psModules/src/detrend/pmMaskBadPixels.c (modified) (3 diffs)
-
psModules/src/detrend/pmMaskBadPixels.h (modified) (1 diff)
-
psModules/src/detrend/pmOverscan.c (modified) (4 diffs)
-
psModules/src/detrend/pmPattern.c (copied) (copied from trunk/psModules/src/detrend/pmPattern.c )
-
psModules/src/detrend/pmPattern.h (copied) (copied from trunk/psModules/src/detrend/pmPattern.h )
-
psModules/src/detrend/pmRemnance.c (modified) (1 diff)
-
psModules/src/detrend/pmShutterCorrection.c (modified) (1 diff)
-
psModules/src/detrend/pmSkySubtract.c (modified) (1 diff)
-
psModules/src/extras/Makefile.am (modified) (2 diffs)
-
psModules/src/extras/ippStages.c (copied) (copied from trunk/psModules/src/extras/ippStages.c )
-
psModules/src/extras/ippStages.h (copied) (copied from trunk/psModules/src/extras/ippStages.h )
-
psModules/src/extras/pmVisual.c (modified) (1 diff)
-
psModules/src/imcombine/pmImageCombine.c (modified) (3 diffs)
-
psModules/src/imcombine/pmPSFEnvelope.c (modified) (16 diffs)
-
psModules/src/imcombine/pmReadoutCombine.c (modified) (6 diffs)
-
psModules/src/imcombine/pmReadoutCombine.h (modified) (1 diff)
-
psModules/src/imcombine/pmSubtraction.c (modified) (8 diffs)
-
psModules/src/imcombine/pmSubtractionEquation.c (modified) (12 diffs)
-
psModules/src/imcombine/pmSubtractionKernels.c (modified) (2 diffs)
-
psModules/src/imcombine/pmSubtractionMask.c (modified) (2 diffs)
-
psModules/src/imcombine/pmSubtractionMatch.c (modified) (5 diffs)
-
psModules/src/imcombine/pmSubtractionStamps.c (modified) (5 diffs)
-
psModules/src/objects/Makefile.am (modified) (2 diffs)
-
psModules/src/objects/models/pmModel_PS1_V1.c (modified) (1 diff)
-
psModules/src/objects/models/pmModel_SGAUSS.c (modified) (1 diff)
-
psModules/src/objects/pmFootprint.h (modified) (1 diff)
-
psModules/src/objects/pmFootprintArraysMerge.c (modified) (3 diffs)
-
psModules/src/objects/pmFootprintCullPeaks.c (copied) (copied from trunk/psModules/src/objects/pmFootprintCullPeaks.c )
-
psModules/src/objects/pmGrowthCurveGenerate.c (modified) (2 diffs)
-
psModules/src/objects/pmMoments.c (modified) (1 diff)
-
psModules/src/objects/pmPSF.c (modified) (1 diff)
-
psModules/src/objects/pmPSF.h (modified) (1 diff)
-
psModules/src/objects/pmPSFtry.c (modified) (21 diffs)
-
psModules/src/objects/pmPeaks.c (modified) (1 diff)
-
psModules/src/objects/pmSource.c (modified) (13 diffs)
-
psModules/src/objects/pmSource.h (modified) (1 diff)
-
psModules/src/objects/pmSourceContour.c (modified) (6 diffs)
-
psModules/src/objects/pmSourceFitModel.c (modified) (1 diff)
-
psModules/src/objects/pmSourceGroup.h (copied) (copied from trunk/psModules/src/objects/pmSourceGroup.h )
-
psModules/src/objects/pmSourceIO.c (modified) (8 diffs)
-
psModules/src/objects/pmSourceIO.h (modified) (3 diffs)
-
psModules/src/objects/pmSourceIO_CMF_PS1_V2.c (copied) (copied from trunk/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c )
-
psModules/src/objects/pmSourceIO_MatchedRefs.c (copied) (copied from trunk/psModules/src/objects/pmSourceIO_MatchedRefs.c )
-
psModules/src/objects/pmSourceIO_RAW.c (modified) (1 diff)
-
psModules/src/objects/pmSourceMasks.c (modified) (1 diff)
-
psModules/src/objects/pmSourceMasks.h (modified) (1 diff)
-
psModules/src/objects/pmSourceMatch.c (modified) (9 diffs)
-
psModules/src/objects/pmSourceMoments.c (modified) (8 diffs)
-
psModules/src/objects/pmSourceUtils.c (modified) (1 diff)
-
psModules/src/psmodules.h (modified) (2 diffs)
-
psModules/test/camera/tap_pmFPAMaskW.c (modified) (4 diffs)
-
psModules/test/concepts/tap_pmConcepts.c (modified) (4 diffs)
-
psModules/test/objects/tap_pmGrowthCurve.c (modified) (3 diffs)
-
psModules/test/objects/tap_pmSource.c (modified) (3 diffs)
-
psModules/test/objects/tap_pmSourceIO_PS1_DEV_1.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/pap
- Property svn:mergeinfo changed
-
branches/pap/psModules
- Property svn:mergeinfo deleted
-
branches/pap/psModules/src/astrom/pmAstrometryDistortion.c
r23487 r25027 151 151 152 152 // also measure the L and M median positions as a representative coordinate 153 psVectorStats (stats, L, NULL, NULL, 0); 153 if (!psVectorStats (stats, L, NULL, NULL, 0)) { 154 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 155 goto skip; 156 } 154 157 grad->FP.x = stats->sampleMedian; 155 158 156 psVectorStats (stats, M, NULL, NULL, 0); 159 if (!psVectorStats (stats, M, NULL, NULL, 0)) { 160 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 161 goto skip; 162 } 157 163 grad->FP.y = stats->sampleMedian; 158 164 -
branches/pap/psModules/src/astrom/pmAstrometryObjects.c
r21422 r25027 83 83 { 84 84 psArray *matches = psArrayAllocEmpty(x1->n); 85 psVector *found1 = psVectorAlloc(x1->n, PS_TYPE_S8); 86 psVector *found2 = psVectorAlloc(x2->n, PS_TYPE_S8); 85 87 86 88 const double RADIUS_SQR = PS_SQR(RADIUS); 87 89 double dX, dY, dR; 90 91 psVectorInit (found1, 0); 92 psVectorInit (found2, 0); 88 93 89 94 int jStart; … … 100 105 } 101 106 107 if (found1->data.S8[i]) { 108 i++; 109 continue; 110 } 111 if (found2->data.S8[j]) { 112 j++; 113 continue; 114 } 115 102 116 jStart = j; 103 while ( fabs(dX) < RADIUS && j < x2->n) {117 while ((fabs(dX) < RADIUS) && (j < x2->n)) { 104 118 105 119 dX = x1->data.F64[i] - x2->data.F64[j]; … … 111 125 continue; 112 126 } 127 if (found2->data.S8[j]) { 128 j++; 129 continue; 130 } 113 131 114 132 // got a match; add to output list … … 117 135 psFree (match); 118 136 137 found1->data.S8[i] = 1; 138 found2->data.S8[j] = 1; 139 119 140 j++; 120 141 } … … 122 143 i++; 123 144 } 145 psFree (found1); 146 psFree (found2); 147 124 148 return (matches); 125 149 } … … 420 444 obj->sky = psSphereAlloc(); 421 445 obj->Mag = 0; 446 obj->Color= 0; 422 447 obj->dMag = 0; 423 448 … … 447 472 *obj->sky = *old->sky; 448 473 obj->Mag = old->Mag; 474 obj->Color = old->Color; 449 475 obj->dMag = old->dMag; 450 476 -
branches/pap/psModules/src/astrom/pmAstrometryObjects.h
r20801 r25027 33 33 typedef struct 34 34 { 35 psPlane *pix; ///< the position in the pmReadout frame 36 psPlane *cell; ///< the position in the pmCell frame 37 psPlane *chip; ///< the position in the pmChip frame 38 psPlane *FP; ///< the position in the pmFPA frame 39 psPlane *TP; ///< the position in the tangent plane 40 psSphere *sky; ///< the position on the Celestial Sphere. 41 double Mag; ///< object magnitude XXX what filter? 42 double dMag; ///< error on object magnitude 35 psPlane *pix; ///< the position in the pmReadout frame 36 psPlane *cell; ///< the position in the pmCell frame 37 psPlane *chip; ///< the position in the pmChip frame 38 psPlane *FP; ///< the position in the pmFPA frame 39 psPlane *TP; ///< the position in the tangent plane 40 psSphere *sky; ///< the position on the Celestial Sphere. 41 float Mag; ///< object magnitude in extracted filter 42 float Color; ///< object color 43 float dMag; ///< error on object magnitude 43 44 } 44 45 pmAstromObj; -
branches/pap/psModules/src/astrom/pmAstrometryUtils.c
r19991 r25027 46 46 47 47 /* this loop uses the Newton-Raphson method to solve for Xo,Yo 48 * it needs the high order terms to be small49 * Xo,Yo are in pixels;50 */48 * it needs the high order terms to be small 49 * Xo,Yo are in pixels; 50 */ 51 51 double dPos = tol + 1; 52 52 for (int i = 0; (dPos > tol) && (i < 20); i++) { … … 60 60 Beta->data.F32[1] = psPolynomial2DEval (trans->y, Xo, Yo); 61 61 62 if (!psMatrixGJSolve F32(Alpha, Beta)) {63 psError(PS_ERR_UNKNOWN, false, "Unable to solve for center.");64 psFree (Alpha);65 psFree (Beta);66 psFree (XdX);67 psFree (XdY);68 psFree (YdX);69 psFree (YdY);62 if (!psMatrixGJSolve (Alpha, Beta)) { 63 psError(PS_ERR_UNKNOWN, false, "Unable to solve for center."); 64 psFree (Alpha); 65 psFree (Beta); 66 psFree (XdX); 67 psFree (XdY); 68 psFree (YdX); 69 psFree (YdY); 70 70 return NULL; 71 71 } -
branches/pap/psModules/src/astrom/pmAstrometryVisual.c
r23487 r25027 17 17 #include "pmFPAExtent.h" 18 18 19 # if (HAVE_KAPA)20 # include <kapa.h>21 # include "pmKapaPlots.h"19 #if (HAVE_KAPA) 20 #include <kapa.h> 21 #include "pmKapaPlots.h" 22 22 #include "pmVisual.h" 23 23 -
branches/pap/psModules/src/astrom/pmAstrometryWCS.c
r21430 r25027 96 96 97 97 if (!status1 || !status2) { 98 Nx = psMetadataLookupS32 (&status1, header, "IMNAXIS1"); 99 Ny = psMetadataLookupS32 (&status2, header, "IMNAXIS2"); 100 } 101 102 if (!status1 || !status2) { 98 103 Nx = psMetadataLookupS32 (&status1, header, "ZNAXIS1"); 99 104 Ny = psMetadataLookupS32 (&status2, header, "ZNAXIS2"); … … 143 148 int Nx = region->x1 - region->x0; 144 149 int Ny = region->y1 - region->y0; 145 psMetadataAddS32 (header, PS_LIST_TAIL, " NAXIS1", PS_META_REPLACE, "Mosaic Dimensions", Nx);146 psMetadataAddS32 (header, PS_LIST_TAIL, " NAXIS2", PS_META_REPLACE, "Mosaic Dimensions", Ny);150 psMetadataAddS32 (header, PS_LIST_TAIL, "IMNAXIS1", PS_META_REPLACE, "Mosaic Dimensions", Nx); 151 psMetadataAddS32 (header, PS_LIST_TAIL, "IMNAXIS2", PS_META_REPLACE, "Mosaic Dimensions", Ny); 147 152 148 153 pmAstromWCStoHeader (header, wcs); -
branches/pap/psModules/src/astrom/pmAstrometryWCS.h
r21159 r25027 68 68 bool psPlaneDistortIsDiagonal (psPlaneDistort *distort); 69 69 70 # define PM_DEG_RAD 57.295779513082322 71 # define PM_RAD_DEG 0.017453292519943 70 // XXX probably should remove these and just use the PS_ version in the code 71 # define PM_DEG_RAD PS_DEG_RAD 72 # define PM_RAD_DEG PS_RAD_DEG 72 73 73 74 /// @} -
branches/pap/psModules/src/camera/Makefile.am
r19695 r25027 23 23 pmFPAfileIO.c \ 24 24 pmFPAfileFitsIO.c \ 25 pmFPAfileFringeIO.c \ 25 26 pmFPAFlags.c \ 26 27 pmFPALevel.c \ … … 51 52 pmFPAfileIO.h \ 52 53 pmFPAfileFitsIO.h \ 54 pmFPAfileFringeIO.h \ 53 55 pmFPAFlags.h \ 54 56 pmFPALevel.h \ -
branches/pap/psModules/src/camera/pmFPABin.c
r21183 r25027 28 28 int numColsOut = binning->nXruff, numRowsOut = binning->nYruff; // Size of output image 29 29 30 // Output image 31 psImage *outImage; 30 31 psImage *outImage; // Output image 32 32 if (out->image && out->image->numCols >= numColsOut && out->image->numRows >= numRowsOut) { 33 33 outImage = out->image; 34 34 } else { 35 35 outImage = out->image = psImageRecycle(out->image, numColsOut, numRowsOut, PS_TYPE_F32); 36 } 37 38 psImage *outMask; // Output mask 39 if (out->mask && out->mask->numCols >= numColsOut && out->mask->numRows >= numRowsOut) { 40 outMask = out->mask; 41 } else { 42 outMask = out->mask = psImageRecycle(out->mask, numColsOut, numRowsOut, PS_TYPE_IMAGE_MASK); 36 43 } 37 44 … … 53 60 continue; 54 61 } 62 if (!isfinite(inImage->data.F32[y][x])) { 63 continue; 64 } 55 65 sum += inImage->data.F32[y][x]; 56 66 numPix++; … … 58 68 } 59 69 60 outImage->data.F32[yOut][xOut] = numPix > 0 ? sum / numPix : NAN; 70 // Values to set 71 float imageValue; 72 psImageMaskType maskValue; 73 if (numPix > 0) { 74 imageValue = sum / numPix; 75 maskValue = 0; 76 } else { 77 imageValue = NAN; 78 maskValue = maskVal; 79 } 80 outImage->data.F32[yOut][xOut] = imageValue; 81 outMask->data.PS_TYPE_IMAGE_MASK_DATA[yOut][xOut] = maskValue; 61 82 xStart = xStop; 62 83 } -
branches/pap/psModules/src/camera/pmFPACopy.c
r23761 r25027 70 70 psImageBinningSetRuffSize(binning, PS_IMAGE_BINNING_CENTER); 71 71 *target = psImageAlloc(binning->nXruff, binning->nYruff, source->type.type); 72 psImageInit (*target, 0.0); 72 73 return; 73 74 } … … 221 222 psTrace("psModules.camera", 3, "xFlip: %d; yFlip: %d\n", xFlip, yFlip); 222 223 224 // Blow away extant readouts 225 for (int i = 0; i < target->readouts->n; i++) { 226 psFree(target->readouts->data[i]); 227 target->readouts->data[i] = NULL; 228 } 229 target->readouts->n = 0; 230 223 231 // Perform deep copy of the images. I would prefer *not* to do a deep copy, in the interests of speed (we 224 232 // still need to do another deep copy into the HDU for when we write out), but this is the only way I can … … 242 250 readoutCopyComponent(&targetReadout->variance, sourceReadout->variance, binning, xFlip, yFlip, 243 251 pixels); 252 // Copy covariance matrix: doesn't care about flips, etc. 253 if (sourceReadout->covariance) { 254 if (targetReadout->covariance) { 255 psFree(targetReadout->covariance); 256 } 257 targetReadout->covariance = psKernelCopy(sourceReadout->covariance); 258 #if 0 259 if (binning) { 260 // XXX This isn't strictly correct, but we don't have a function that bins covariance matrices 261 // with unequal binning factors. 262 psKernel *covar = psImageCovarianceBin(PS_MAX(binning->nXbin, binning->nYbin), 263 targetReadout->covariance); 264 psFree(targetReadout->covariance); 265 targetReadout->covariance = covar; 266 } 267 #endif 268 } 244 269 245 270 // Copy bias -
branches/pap/psModules/src/camera/pmFPAMaskWeight.c
r23259 r25027 109 109 float saturation = psMetadataLookupF32(&mdok, cell->concepts, "CELL.SATURATION"); // Saturation level 110 110 if (!mdok || isnan(saturation)) { 111 psError(PS_ERR_IO, true, "CELL.SATURATION is not set --- unable to set mask.\n"); 112 return false; 111 // psError(PS_ERR_IO, true, "CELL.SATURATION is not set --- unable to set mask.\n"); 112 // return false; 113 psWarning("CELL.SATURATION is not set --- completely masking cell.\n"); 114 saturation = NAN; 113 115 } 114 116 float bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level 115 117 if (!mdok || isnan(bad)) { 116 psError(PS_ERR_IO, true, "CELL.BAD is not set --- unable to set mask.\n"); 117 return false; 118 // psError(PS_ERR_IO, true, "CELL.BAD is not set --- unable to set mask.\n"); 119 // return false; 120 psWarning("CELL.BAD is not set --- completely masking cell.\n"); 121 bad = NAN; 118 122 } 119 123 psTrace("psModules.camera", 5, "Saturation: %f, bad: %f\n", saturation, bad); 120 124 125 // if CELL.GAIN or CELL.READNOISE are not set, then the variance will be set to NAN; 126 // in this case, we have to set the mask as well 127 float gain = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN"); // Cell gain 128 if (!mdok) { gain = NAN; } 129 float readnoise = psMetadataLookupF32(&mdok, cell->concepts, "CELL.READNOISE"); // Cell read noise 130 if (!mdok) { readnoise = NAN; } 121 131 122 132 // Set up the mask … … 127 137 } 128 138 psImage *mask = readout->mask; // The mask pixels 139 140 // completely mask if SATURATION or BAD are invalid 141 if (isnan(saturation) || isnan(bad) || isnan(gain) || isnan(readnoise)) { 142 psImageInit(mask, badMask); 143 return true; 144 } 145 129 146 psImageInit(mask, 0); 130 147 … … 199 216 } 200 217 201 bool pmReadoutSetVariance(pmReadout *readout, bool poisson)218 bool pmReadoutSetVariance(pmReadout *readout, const psImage *noiseMap, bool poisson) 202 219 { 203 220 PS_ASSERT_PTR_NON_NULL(readout, false); 221 // check that the noiseMap (if it exists) matches the readout variance size) 204 222 205 223 pmCell *cell = readout->parent; // The parent cell … … 209 227 float gain = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN"); // Cell gain 210 228 if (!mdok || isnan(gain)) { 211 psError(PS_ERR_IO, true, "CELL.GAIN is not set --- unable to set variance.\n"); 212 return false; 229 // psError(PS_ERR_IO, true, "CELL.GAIN is not set --- unable to set variance.\n"); 230 // return false; 231 psWarning("CELL.GAIN is not set --- setting variance to NAN\n"); 232 gain = NAN; 213 233 } 214 234 float readnoise = psMetadataLookupF32(&mdok, cell->concepts, "CELL.READNOISE"); // Cell read noise 215 235 if (!mdok || isnan(readnoise)) { 216 psError(PS_ERR_IO, true, "CELL.READNOISE is not set --- unable to set variance.\n"); 217 return false; 218 } 219 if (psMetadataLookup(cell->concepts, "CELL.READNOISE.UPDATE")) { 236 // psError(PS_ERR_IO, true, "CELL.READNOISE is not set --- unable to set variance.\n"); 237 // return false; 238 psWarning("CELL.READNOISE is not set --- setting variance to NAN\n"); 239 readnoise = NAN; 240 } 241 // if we have a non-NAN readnoise, then we need to ensure it has been updated (not necessary if NAN) 242 if (!isnan(gain) && psMetadataLookup(cell->concepts, "CELL.READNOISE.UPDATE")) { 220 243 psError(PS_ERR_IO, true, "CELL.READNOISE has not yet been updated for the gain"); 221 244 return false; 245 } 246 247 // for invalid input data, set the readout variance to NAN 248 if (isnan(gain) || isnan(readnoise)) { 249 if (!readout->variance) { 250 // generate the image if needed 251 readout->variance = psImageAlloc(readout->image->numCols, readout->image->numRows, PS_TYPE_F32); 252 } 253 // XXX need to set the mask, if defined 254 psImageInit(readout->variance, NAN); 255 return true; 222 256 } 223 257 … … 228 262 229 263 // a negative variance is non-sensical. if the image value drops below 1, the variance must be 1. 264 // XXX this calculation is wrong: limit is 1 e-, but this is in DN 230 265 readout->variance = (psImage*)psUnaryOp(readout->variance, readout->variance, "abs"); 231 266 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "max", … … 239 274 } 240 275 241 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", 242 psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32)); 276 // apply a supplied readnoise map (NOTE: in DN, not electrons): 277 if (noiseMap) { 278 psImage *rdVar = (psImage*)psBinaryOp(NULL, (const psPtr) noiseMap, "*", (const psPtr) noiseMap); 279 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", rdVar); 280 psFree (rdVar); 281 } else { 282 readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32)); 283 } 243 284 244 285 return true; … … 247 288 // this function creates the variance pixels, or uses the existing variance pixels. it will set 248 289 // the noise pixel values only if the variance image is not supplied 249 bool pmReadoutGenerateVariance(pmReadout *readout, bool poisson)290 bool pmReadoutGenerateVariance(pmReadout *readout, const psImage *noiseMap, bool poisson) 250 291 { 251 292 PS_ASSERT_PTR_NON_NULL(readout, false); … … 291 332 readout->variance = variance; 292 333 293 return pmReadoutSetVariance(readout, poisson);294 } 295 296 bool pmReadoutGenerateMaskVariance(pmReadout *readout, psImageMaskType satMask, psImageMaskType badMask, bool poisson)334 return pmReadoutSetVariance(readout, noiseMap, poisson); 335 } 336 337 bool pmReadoutGenerateMaskVariance(pmReadout *readout, psImageMaskType satMask, psImageMaskType badMask, const psImage *noiseMap, bool poisson) 297 338 { 298 339 PS_ASSERT_PTR_NON_NULL(readout, false); … … 301 342 302 343 success &= pmReadoutGenerateMask(readout, satMask, badMask); 303 success &= pmReadoutGenerateVariance(readout, poisson);344 success &= pmReadoutGenerateVariance(readout, noiseMap, poisson); 304 345 305 346 return success; 306 347 } 307 348 308 bool pmCellGenerateMaskVariance(pmCell *cell, psImageMaskType satMask, psImageMaskType badMask, bool poisson)349 bool pmCellGenerateMaskVariance(pmCell *cell, psImageMaskType satMask, psImageMaskType badMask, const psImage *noiseMap, bool poisson) 309 350 { 310 351 PS_ASSERT_PTR_NON_NULL(cell, false); … … 314 355 for (int i = 0; i < readouts->n; i++) { 315 356 pmReadout *readout = readouts->data[i]; // The readout 316 success &= pmReadoutGenerateMaskVariance(readout, poisson, satMask, badMask);357 success &= pmReadoutGenerateMaskVariance(readout, satMask, badMask, noiseMap, poisson); 317 358 } 318 359 … … 482 523 return false; 483 524 } 484 float stdev = psStatsGetValue(stdevStats, stdevStat); // Sta dard deviation of fluxes525 float stdev = psStatsGetValue(stdevStats, stdevStat); // Standard deviation of fluxes 485 526 psFree(stdevStats); 486 527 psFree(noise); -
branches/pap/psModules/src/camera/pmFPAMaskWeight.h
r21363 r25027 54 54 /// can't be generated. 55 55 bool pmReadoutSetVariance(pmReadout *readout, ///< Readout for which to set variance 56 const psImage *noiseMap, ///< 2D image of the read noise in DN 56 57 bool poisson ///< Include poisson variance (in addition to read noise)? 57 58 ); … … 72 73 /// with HDU entry). This is intended for most operations. 73 74 bool pmReadoutGenerateVariance(pmReadout *readout, ///< Readout for which to generate variance 75 const psImage *noiseMap, ///< 2D image of the read noise in DN 74 76 bool poisson ///< Include poisson variance (in addition to read noise)? 75 77 ); … … 81 83 psImageMaskType sat, ///< Mask value to give saturated pixels 82 84 psImageMaskType bad, ///< Mask value to give bad (low) pixels 85 const psImage *noiseMap, ///< 2D image of the read noise in DN 83 86 bool poisson ///< Include poisson variance (in addition to read noise)? 84 87 ); … … 90 93 psImageMaskType sat, ///< Mask value to give saturated pixels 91 94 psImageMaskType bad, ///< Mask value to give bad (low) pixels 95 const psImage *noiseMap, ///< 2D image of the read noise in DN 92 96 bool poisson ///< Include poisson variance (in addition to read noise)? 93 97 ); -
branches/pap/psModules/src/camera/pmFPARead.c
r23827 r25027 64 64 65 65 // Set the "thisXXXScan" value in the readout for the appropriate image type 66 static intreadoutSetThisScan(pmReadout *readout, // Readout of interest66 static void readoutSetThisScan(pmReadout *readout, // Readout of interest 67 67 fpaReadType type, // Type of image 68 68 int thisScan // Starting scan number … … 72 72 case FPA_READ_TYPE_IMAGE: 73 73 readout->thisImageScan = thisScan; 74 return readout->lastImageScan;74 return; 75 75 case FPA_READ_TYPE_MASK: 76 76 readout->thisMaskScan = thisScan; 77 return readout->lastMaskScan;77 return; 78 78 case FPA_READ_TYPE_VARIANCE: 79 79 readout->thisVarianceScan = thisScan; 80 return readout->lastVarianceScan;80 return; 81 81 default: 82 82 psAbort("Unknown read type: %x\n", type); 83 83 } 84 return false;85 84 } 86 85 … … 103 102 104 103 // Set the "lastXXXScan" value in the readout for the appropriate image type 105 static intreadoutSetLastScan(pmReadout *readout, // Readout of interest104 static void readoutSetLastScan(pmReadout *readout, // Readout of interest 106 105 fpaReadType type, // Type of image 107 106 int lastScan // Last scan number … … 111 110 case FPA_READ_TYPE_IMAGE: 112 111 readout->lastImageScan = lastScan; 113 return readout->lastImageScan;112 return; 114 113 case FPA_READ_TYPE_MASK: 115 114 readout->lastMaskScan = lastScan; 116 return readout->lastMaskScan;115 return; 117 116 case FPA_READ_TYPE_VARIANCE: 118 117 readout->lastVarianceScan = lastScan; 119 return readout->lastVarianceScan;118 return; 120 119 default: 121 120 psAbort("Unknown read type: %x\n", type); 122 121 } 123 return false;124 122 } 125 123 … … 143 141 // Determine number of readouts in the FITS file 144 142 // In the process, reads the header and concepts 145 static boolcellNumReadouts(pmCell *cell, // Cell of interest143 static int cellNumReadouts(pmCell *cell, // Cell of interest 146 144 psFits *fits, // FITS file 147 145 pmConfig *config // Configuration … … 155 153 if (!hdu || hdu->blankPHU) { 156 154 psError(PS_ERR_IO, true, "Unable to find HDU"); 157 return false;155 return 0; 158 156 } 159 157 if (!pmCellReadHeader(cell, fits, config)) { 160 158 psError(PS_ERR_IO, false, "Unable to read header for cell!\n"); 161 return false;159 return 0; 162 160 } 163 161 if (!pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CELLS, true, NULL)) { 164 162 psError(PS_ERR_IO, false, "Failed to read concepts for cell.\n"); 165 return false;163 return 0; 166 164 } 167 165 … … 171 169 if (!mdok) { 172 170 psError(PS_ERR_IO, true, "Unable to find NAXIS in header for extension %s\n", hdu->extname); 173 return false; 174 } 171 return 0; 172 } 173 175 174 if (naxis == 0) { 176 175 // No pixels to read 177 176 psError(PS_ERR_IO, true, "No pixels in extension %s.", hdu->extname); 178 return false;177 return 0; 179 178 } 180 179 if (naxis < 2 || naxis > 3) { 181 180 psError(PS_ERR_IO, true, "NAXIS in header of extension %s (= %d) is not valid.\n", 182 181 hdu->extname, naxis); 183 return false;182 return 0; 184 183 } 185 184 int naxis3; // Number of image planes … … 188 187 if (!mdok) { 189 188 psError(PS_ERR_IO, true, "Unable to find NAXIS3 in header for extension %s\n", hdu->extname); 190 return false;189 return 0; 191 190 } 192 191 } else { … … 296 295 static bool readoutMore(pmReadout *readout, // Readout of interest 297 296 psFits *fits, // FITS file 298 int z, // Plane number 297 int z, // Plane number to read 298 int *zMax, // Max plane number in this cell 299 299 int numScans, // Number of scans to read at a time 300 300 fpaReadType type, // Type of image … … 310 310 // N readouts, but numScans set to 0. only the first should report that it requires data, 311 311 // even if all readouts lack the image pointer. 312 if (!image) { 312 if (numScans == 0) { 313 if (!image) { 313 314 return true; 314 } 315 316 // If we have already read an image, this result implies we are done (no more to read) 317 if (numScans == 0) { 318 return false; 315 } else { 316 return false; 317 } 319 318 } 320 319 … … 324 323 return false; 325 324 } 326 int naxis3= cellNumReadouts(cell, fits, config); // Number of planes327 if (z >= naxis3) {325 *zMax = cellNumReadouts(cell, fits, config); // Number of planes 326 if (z >= *zMax) { 328 327 // No more to read 329 328 return false; … … 486 485 psFits *fits, // FITS file 487 486 int z, // Desired image plane 487 int *zMax, // Max plane number in this cell 488 488 int numScans, // Number of scans (row or col depends on CELL.READDIR); 0 for all 489 489 int overlap, // Number of scans (row/col) to overlap between scans … … 511 511 512 512 int naxis3 = cellNumReadouts(cell, fits, config); // Number of image planes 513 if (zMax) *zMax = naxis3; 514 513 515 if (z >= naxis3) { 514 516 psError(PS_ERR_IO, false, "Desired image plane (%d) exceeds available number (%d).", … … 592 594 } 593 595 594 // Determine the number of scans to read 595 int lastScan = readoutSetLastScan(readout, type, thisScan + numScans); 596 int origThisScan = thisScan; // Original value of thisScan (starting point for read) 596 597 if (thisScan == 0) { 597 598 overlap = 0; … … 601 602 thisScan = 0; 602 603 } 603 readoutSetThisScan(readout, type, thisScan);604 604 605 605 // Calculate limits, adjust readout->row0,col0 … … 620 620 } 621 621 } 622 int lastScan = origThisScan + numScans; // Last scan to read 623 624 readoutSetThisScan(readout, type, thisScan); 625 readoutSetLastScan(readout, type, lastScan); 622 626 623 627 // Blow away existing data. … … 1021 1025 1022 1026 1023 bool pmReadoutMore(pmReadout *readout, psFits *fits, int z, int numScans, pmConfig *config)1027 bool pmReadoutMore(pmReadout *readout, psFits *fits, int z, int *zMax, int numScans, pmConfig *config) 1024 1028 { 1025 1029 PS_ASSERT_PTR_NON_NULL(readout, false); 1026 1030 PS_ASSERT_FITS_NON_NULL(fits, false); 1027 1031 1028 return readoutMore(readout, fits, z, numScans, FPA_READ_TYPE_IMAGE, config);1029 } 1030 1031 bool pmReadoutReadChunk(pmReadout *readout, psFits *fits, int z, int numScans, int overlap, pmConfig *config)1032 return readoutMore(readout, fits, z, zMax, numScans, FPA_READ_TYPE_IMAGE, config); 1033 } 1034 1035 bool pmReadoutReadChunk(pmReadout *readout, psFits *fits, int z, int *zMax, int numScans, int overlap, pmConfig *config) 1032 1036 { 1033 1037 PS_ASSERT_PTR_NON_NULL(readout, false); … … 1036 1040 PS_ASSERT_INT_NONNEGATIVE(numScans, false); 1037 1041 1038 return readoutReadChunk(readout, fits, z, numScans, overlap, FPA_READ_TYPE_IMAGE, config);1042 return readoutReadChunk(readout, fits, z, zMax, numScans, overlap, FPA_READ_TYPE_IMAGE, config); 1039 1043 } 1040 1044 … … 1044 1048 PS_ASSERT_FITS_NON_NULL(fits, false); 1045 1049 1046 return readoutReadChunk(readout, fits, z, 0, 0, FPA_READ_TYPE_IMAGE, config);1050 return readoutReadChunk(readout, fits, z, NULL, 0, 0, FPA_READ_TYPE_IMAGE, config); 1047 1051 } 1048 1052 … … 1084 1088 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1085 1089 1086 bool pmReadoutMoreMask(pmReadout *readout, psFits *fits, int z, int numScans, pmConfig *config)1090 bool pmReadoutMoreMask(pmReadout *readout, psFits *fits, int z, int *zMax, int numScans, pmConfig *config) 1087 1091 { 1088 1092 PS_ASSERT_PTR_NON_NULL(readout, false); 1089 1093 PS_ASSERT_FITS_NON_NULL(fits, false); 1090 1094 1091 return readoutMore(readout, fits, z, numScans, FPA_READ_TYPE_MASK, config);1092 } 1093 1094 bool pmReadoutReadChunkMask(pmReadout *readout, psFits *fits, int z, int numScans, int overlap,1095 return readoutMore(readout, fits, z, zMax, numScans, FPA_READ_TYPE_MASK, config); 1096 } 1097 1098 bool pmReadoutReadChunkMask(pmReadout *readout, psFits *fits, int z, int *zMax, int numScans, int overlap, 1095 1099 pmConfig *config) 1096 1100 { … … 1100 1104 PS_ASSERT_INT_NONNEGATIVE(numScans, false); 1101 1105 1102 return readoutReadChunk(readout, fits, z, numScans, overlap, FPA_READ_TYPE_MASK, config);1106 return readoutReadChunk(readout, fits, z, zMax, numScans, overlap, FPA_READ_TYPE_MASK, config); 1103 1107 } 1104 1108 … … 1108 1112 PS_ASSERT_FITS_NON_NULL(fits, false); 1109 1113 1110 return readoutReadChunk(readout, fits, z, 0, 0, FPA_READ_TYPE_MASK, config);1114 return readoutReadChunk(readout, fits, z, NULL, 0, 0, FPA_READ_TYPE_MASK, config); 1111 1115 } 1112 1116 … … 1139 1143 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 1140 1144 1141 bool pmReadoutMoreVariance(pmReadout *readout, psFits *fits, int z, int numScans, pmConfig *config)1145 bool pmReadoutMoreVariance(pmReadout *readout, psFits *fits, int z, int *zMax, int numScans, pmConfig *config) 1142 1146 { 1143 1147 PS_ASSERT_PTR_NON_NULL(readout, false); 1144 1148 PS_ASSERT_FITS_NON_NULL(fits, false); 1145 1149 1146 return readoutMore(readout, fits, z, numScans, FPA_READ_TYPE_VARIANCE, config);1147 } 1148 1149 bool pmReadoutReadChunkVariance(pmReadout *readout, psFits *fits, int z, int numScans, int overlap,1150 return readoutMore(readout, fits, z, zMax, numScans, FPA_READ_TYPE_VARIANCE, config); 1151 } 1152 1153 bool pmReadoutReadChunkVariance(pmReadout *readout, psFits *fits, int z, int *zMax, int numScans, int overlap, 1150 1154 pmConfig *config) 1151 1155 { … … 1155 1159 PS_ASSERT_INT_NONNEGATIVE(numScans, false); 1156 1160 1157 return readoutReadChunk(readout, fits, z, numScans, overlap, FPA_READ_TYPE_VARIANCE, config);1161 return readoutReadChunk(readout, fits, z, zMax, numScans, overlap, FPA_READ_TYPE_VARIANCE, config); 1158 1162 } 1159 1163 … … 1163 1167 PS_ASSERT_FITS_NON_NULL(fits, false); 1164 1168 1165 return readoutReadChunk(readout, fits, z, 0, 0, FPA_READ_TYPE_VARIANCE, config);1169 return readoutReadChunk(readout, fits, z, NULL, 0, 0, FPA_READ_TYPE_VARIANCE, config); 1166 1170 } 1167 1171 -
branches/pap/psModules/src/camera/pmFPARead.h
r21363 r25027 21 21 psFits *fits, ///< FITS file from which to read 22 22 int z, ///< Readout number/plane; zero-offset indexing 23 int *zMax, ///< Max plane number in this cell 23 24 int numScans, ///< Number of scans (rows/cols) to read 24 25 pmConfig *config ///< Configuration … … 31 32 psFits *fits, ///< FITS file from which to read 32 33 int z, ///< Readout number/plane; zero-offset indexing 34 int *zMax, ///< Max plane number in this cell 33 35 int numScans, ///< Number of scans (rows/cols) to read 34 36 int overlap, ///< Overlap between consecutive reads … … 98 100 psFits *fits, ///< FITS file from which to read 99 101 int z, ///< Readout number/plane; zero-offset indexing 102 int *zMax, ///< Max plane number in this cell 100 103 int numScans, ///< Number of scans (rows/cols) to read 101 104 pmConfig *config ///< Configuration … … 108 111 psFits *fits, ///< FITS file from which to read 109 112 int z, ///< Readout number/plane; zero-offset indexing 113 int *zMax, ///< Max plane number in this cell 110 114 int numScans, ///< Number of scans (rows/cols) to read 111 115 int overlap, ///< Overlap between consecutive reads … … 150 154 psFits *fits, ///< FITS file from which to read 151 155 int z, ///< Readout number/plane; zero-offset indexing 156 int *zMax, ///< Max plane number in this cell 152 157 int numScans, ///< Number of scans (rows/cols) to read 153 158 pmConfig *config ///< Configuration … … 160 165 psFits *fits, ///< FITS file from which to read 161 166 int z, ///< Readout number/plane; zero-offset indexing 167 int *zMax, ///< Max plane number in this cell 162 168 int numScans, ///< Number of scans (rows/cols) to read 163 169 int overlap, ///< Overlap between consecutive reads -
branches/pap/psModules/src/camera/pmFPAWrite.c
r23428 r25027 160 160 psArray **imageArray = appropriateImageArray(hdu, type); // Array of images in the HDU 161 161 162 // XXX detect missing variance & mask images... 163 162 164 // Generate the HDU if needed --- this is required after a pmFPACopy, or similar, which does not 163 165 // generate the HDU, but only copies the structure. 164 if (!blank && !hdu->blankPHU && !*imageArray && (!pmHDUGenerateForCell(cell) || !*imageArray)) { 165 psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell --- likely programming error."); 166 return false; 166 if (!blank && !hdu->blankPHU && !*imageArray) { 167 if (!pmHDUGenerateForCell(cell)) { 168 psError(PS_ERR_UNKNOWN, false, "Unable to generate HDU for cell --- likely programming error."); 169 return false; 170 } 171 if (!*imageArray) { 172 if (type == FPA_WRITE_TYPE_IMAGE) { 173 psError(PS_ERR_UNKNOWN, false, "Expected to write an image, but it is missing...programming error?."); 174 return false; 175 } 176 if (type == FPA_WRITE_TYPE_MASK) { 177 psWarning("No mask image for this cell; skipping"); 178 } 179 if (type == FPA_WRITE_TYPE_VARIANCE) { 180 psWarning("No variance image for this cell; skipping"); 181 } 182 return true; 183 } 167 184 } 168 185 … … 724 741 } 725 742 if (!psFitsCompressionApply(fits, compress)) { 726 psError(PS_ERR_UNKNOWN, false, "Unable to set FITS compression to NONE");743 psError(PS_ERR_UNKNOWN, false, "Unable to restore FITS compression"); 727 744 psFree(compress); 728 745 return false; -
branches/pap/psModules/src/camera/pmFPAfileIO.c
r23576 r25027 23 23 #include "pmFPAWrite.h" 24 24 #include "pmFPAfileFitsIO.h" 25 #include "pmFPAfileFringeIO.h" 25 26 #include "pmSpan.h" 26 27 #include "pmFootprint.h" … … 192 193 status = pmFPAviewReadFitsImage(view, file, config); 193 194 if (status) { 194 if (!pmFPAviewReadF itsTable(view, file, "FRINGE")) {195 if (!pmFPAviewReadFringes(view, file)) { 195 196 psError(PS_ERR_UNKNOWN, false, "Unable to read fringe data from %s.\n", file->filename); 196 197 return false; … … 451 452 status = pmFPAviewWriteFitsImage (view, file, config); 452 453 if (status) { 453 if (!pmFPAviewWriteF itsTable(view, file, "FRINGE", config)) {454 if (!pmFPAviewWriteFringes(view, file, config)) { 454 455 psError(PS_ERR_UNKNOWN, false, "Unable to write fringe data from %s.\n", file->filename); 455 456 return false; -
branches/pap/psModules/src/camera/pmHDU.c
r21363 r25027 93 93 } 94 94 95 psTrace("psModules.camera", 5, "Reading the header...\n"); 96 97 // The header may already exist (e.g., from doing concept writing at the PHU level) so we need to be 98 // careful. We read into a separate container and copy that over the top of anything that's already read. 99 psMetadata *header = psFitsReadHeader(NULL, fits); 100 if (!header) { 101 psError(PS_ERR_IO, false, "Unable to read header for extension %s\n", hdu->extname); 102 return false; 103 } 104 95 105 if (!hdu->header) { 96 psTrace("psModules.camera", 5, "Reading the header...\n"); 97 hdu->header = psFitsReadHeader(hdu->header, fits); 98 if (! hdu->header) { 99 psError(PS_ERR_IO, false, "Unable to read header for extension %s\n", hdu->extname); 100 return false; 101 } 102 } 106 hdu->header = header; 107 return true; 108 } 109 110 psMetadataIterator *iter = psMetadataIteratorAlloc(header, PS_LIST_HEAD, NULL); // Iterator 111 psMetadataItem *item; // Item from iteration 112 while ((item = psMetadataGetAndIncrement(iter))) { 113 const char *name = item->name; // Name of item 114 if (psMetadataLookup(hdu->header, name)) { 115 // It exists; clobber 116 psMetadataRemoveKey(hdu->header, name); 117 } 118 psMetadataAddItem(hdu->header, item, PS_LIST_TAIL, 0); 119 } 120 psFree(iter); 121 psFree(header); 103 122 104 123 return true; -
branches/pap/psModules/src/camera/pmHDUGenerate.c
r23318 r25027 390 390 if (numReadouts == 0 || (imageType == 0 && maskType == 0 && varianceType == 0)) { 391 391 // Nothing from which to create an HDU 392 psFree(cells);393 ps Error(PS_ERR_IO, true, "Nothing from which to create an HDU\n");394 return false;392 // psError(PS_ERR_IO, true, "Nothing from which to create an HDU\n"); 393 psWarning("Nothing from which to create an HDU, must be empty\n"); 394 return true; 395 395 } 396 396 … … 504 504 psFree(iter); 505 505 } 506 psFree(cells);507 508 506 return true; 509 507 } … … 615 613 return true; 616 614 } 617 618 return generateHDU(hdu, cells); 615 bool status = generateHDU(hdu, cells); 616 psFree (cells); 617 return status; 619 618 } 620 619 case PM_FPA_LEVEL_CHIP: … … 664 663 } 665 664 666 return generateHDU(hdu, cells); 665 bool status = generateHDU(hdu, cells); 666 psFree (cells); 667 return status; 667 668 } 668 669 case PM_FPA_LEVEL_FPA: -
branches/pap/psModules/src/camera/pmReadoutFake.c
r21104 r25027 29 29 #define MAX_AXIS_RATIO 20.0 // Maximum axis ratio for PSF model 30 30 #define SOURCE_MASK (PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_CR_LIMIT) // Mask to apply to input sources 31 #define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \ 32 PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models 31 33 32 34 … … 80 82 81 83 int numSources = sources->n; // Number of stars 82 83 float flux0 = NAN; // Flux for central intensity of 1.084 if (normalisePeak) {85 pmModel *fakeModel = pmModelFromPSFforXY(psf, (float)numCols / 2.0, (float)numRows / 2.0,86 1.0); // Fake model, with central intensity of 1.087 psAssert(fakeModel, "failed to generate model: should this be an error or not?");88 89 if (circularise && !circulariseModel(fakeModel)) {90 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model.");91 psFree(fakeModel);92 return false;93 }94 95 flux0 = fakeModel->modelFlux(fakeModel->params); // Flux for central intensity of 1.096 psFree(fakeModel);97 }98 99 84 for (int i = 0; i < numSources; i++) { 100 85 pmSource *source = sources->data[i]; // Source of interest … … 118 103 119 104 float flux = powf(10.0, -0.4 * source->psfMag); // Flux of source 105 120 106 if (normalisePeak) { 121 flux /= flux0; 107 // Normalise flux 108 pmModel *normModel = pmModelFromPSFforXY(psf, x, y, 1.0); // Model for normalisation 109 if (!normModel || (normModel->flags & MODEL_MASK)) { 110 psFree(normModel); 111 continue; 112 } 113 if (circularise && !circulariseModel(normModel)) { 114 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model."); 115 psFree(normModel); 116 return false; 117 } 118 119 flux /= normModel->modelFlux(normModel->params); 120 psFree(normModel); 122 121 } 123 122 124 123 pmModel *fakeModel = pmModelFromPSFforXY(psf, x, y, flux); 125 if (!fakeModel) { 124 if (!fakeModel || (fakeModel->flags & MODEL_MASK)) { 125 psFree(fakeModel); 126 126 continue; 127 127 } -
branches/pap/psModules/src/camera/pmReadoutStack.c
r21363 r25027 252 252 continue; 253 253 } 254 if (!readout->process) { 255 continue; 256 } 254 257 if (!readout->image) { 255 258 psError(PS_ERR_UNEXPECTED_NULL, true, "Input readout %ld has NULL image.\n", i); … … 260 263 pmCell *cell = readout->parent; // The parent cell 261 264 bool mdok = true; // Status of MD lookup 262 psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim section265 psRegion *trimsec = cell ? psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC") : NULL; // Trim section 263 266 if (!mdok || !trimsec || psRegionIsNaN(*trimsec)) { 264 psWarning("CELL.TRIMSEC is not set for readout %ld --- ignored.\n", i); 267 psWarning("CELL.TRIMSEC is not set for readout %ld --- attempting to use image size.\n", i); 268 xSize = PS_MAX(xSize, readout->image->numCols); 269 ySize = PS_MAX(ySize, readout->image->numRows); 270 xMin = PS_MIN(xMin, 0); 271 xMax = PS_MAX(xMax, readout->image->numCols - 1); 272 yMin = PS_MIN(yMin, 0); 273 yMax = PS_MAX(yMax, readout->image->numRows - 1); 265 274 } else { 266 275 xSize = PS_MAX(xSize, trimsec->x1 - trimsec->x0); -
branches/pap/psModules/src/concepts/pmConcepts.c
r23832 r25027 485 485 concept[length - 1] = '\0'; 486 486 487 // special variants: 488 if (!strcmp(concept, "FPA.DATE")) { 489 psTime *fpaTime = psMetadataLookupPtr(NULL, fpa->concepts, "FPA.TIME"); 490 if (!fpaTime) { 491 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Missing concept FPA.TIME needed for FPA.DATE"); 492 psFree(string); 493 return NULL; 494 } 495 psString dateTimeString = psTimeToISO(fpaTime); // String representation 496 psList *dateTime = psStringSplit(dateTimeString, "T", true); 497 psFree(dateTimeString); 498 psString dateString = psMemIncrRefCounter(psListGet(dateTime, PS_LIST_HEAD)); // The date string 499 psFree (dateTime); 500 501 if (!psStringSubstitute(&string, dateString, "{FPA.DATE}")) { 502 psError(PS_ERR_UNKNOWN, false, "Unable to replace concept %s", concept); 503 psFree(string); 504 psFree(dateString); 505 return NULL; 506 } 507 psFree (dateString); 508 continue; 509 } 510 487 511 psTrace("psModules.concepts", 7, "Interpolating concept %s", concept); 488 512 -
branches/pap/psModules/src/concepts/pmConceptsRead.c
r22699 r25027 425 425 if (rows->n == 0) { 426 426 psWarning("No rows returned from database query for concept %s --- ignored.", name); 427 psFree(rows); 427 428 return NULL; 428 429 } -
branches/pap/psModules/src/concepts/pmConceptsStandard.c
r23819 r25027 36 36 // Format type for time 37 37 typedef enum { 38 TIME_FORMAT_YYYYMMDD, // Date stored in YYYY-MM-DD order (ISO-standard)39 TIME_FORMAT_DDMMYYYY, // Date stored in DD-MM-YYYY order40 TIME_FORMAT_MMDDYYYY, // Date stored in MM-DD-YYYY order41 TIME_FORMAT_JD, // Date stored as JD42 TIME_FORMAT_MJD, // Date stored as MJD38 TIME_FORMAT_YYYYMMDD, // Date stored in YYYY-MM-DD order (ISO-standard) 39 TIME_FORMAT_DDMMYYYY, // Date stored in DD-MM-YYYY order 40 TIME_FORMAT_MMDDYYYY, // Date stored in MM-DD-YYYY order 41 TIME_FORMAT_JD, // Date stored as JD 42 TIME_FORMAT_MJD, // Date stored as MJD 43 43 } conceptTimeFormatType; 44 44 … … 391 391 } 392 392 393 393 394 // FPA.RA and FPA.DEC 394 395 psMetadataItem *p_pmConceptFormat_FPA_Coords(const psMetadataItem *concept, … … 410 411 // How to interpret the coordinates 411 412 bool mdok = true; // Status of MD lookup 412 psMetadata *formats = psMetadataLookupMetadata(&mdok, 413 cameraFormat, 414 "FORMATS"); 413 psMetadata *formats = psMetadataLookupMetadata(&mdok, cameraFormat, "FORMATS"); 414 bool sexagesimal = false; // Write sexagesimal format? 415 415 if (mdok && formats) { 416 psString format = psMetadataLookupStr(&mdok, formats, concept->name);416 psString format = psMetadataLookupStr(&mdok, formats, concept->name); 417 417 if (mdok && strlen(format) > 0) { 418 418 if (strcasecmp(format, "HOURS") == 0) { … … 428 428 coords /= defaultCoordScaling(concept); 429 429 } 430 431 psString ra = psMetadataLookupStr(&mdok, formats, "FPA.RA"); // Format for RA 432 psString dec = psMetadataLookupStr(&mdok, formats, "FPA.DEC"); // Format for Dec 433 if (ra && strcasecmp(ra, "HOURS") == 0 && dec && strcasecmp(dec, "DEGREES") == 0) { 434 sexagesimal = true; 435 } 430 436 } else { 431 437 coords /= defaultCoordScaling(concept); 432 438 } 433 439 434 // We choose to write sexagesimal format 435 int big, medium; // Degrees and minutes 436 float small; // Seconds 437 bool negative = (coords < 0); // Are we working below zero? 438 coords = fabs(coords); 439 big = (int)abs(coords); 440 coords -= big; 441 medium = 60.0 * coords; 442 coords -= medium / 60.0; 443 small = 3600.0 * coords; 444 small = (float)((int)(small * 1000.0)) / 1000.0; 445 if (negative) { 446 big *= -1; 447 } 448 psString coordString = NULL; // String with the coordinates in sexagesimal format 449 psStringAppend(&coordString, "%d:%02d:%06.3f", big, medium, small); 450 psMetadataItem *coordItem = psMetadataItemAllocStr(concept->name, concept->comment, coordString); 451 psFree(coordString); 440 psMetadataItem *coordItem = NULL; // Item with coordinates, to return 441 if (sexagesimal) { 442 int big, medium; // Degrees and minutes 443 float small; // Seconds 444 bool negative = (coords < 0); // Are we working below zero? 445 coords = fabs(coords); 446 big = (int)abs(coords); 447 coords -= big; 448 medium = 60.0 * coords; 449 coords -= medium / 60.0; 450 small = 3600.0 * coords; 451 small = (float)((int)(small * 1000.0)) / 1000.0; 452 if (negative) { 453 big *= -1; 454 } 455 psString coordString = NULL; // String with the coordinates in sexagesimal format 456 psStringAppend(&coordString, "%d:%02d:%06.3f", big, medium, small); 457 coordItem = psMetadataItemAllocStr(concept->name, concept->comment, coordString); 458 psFree(coordString); 459 } else { 460 coordItem = psMetadataItemAllocF64(concept->name, concept->comment, coords); 461 } 452 462 453 463 return coordItem; -
branches/pap/psModules/src/config/pmConfig.c
r23748 r25027 243 243 unsigned int numBadLines = 0; 244 244 struct stat filestat; 245 246 pmErrorRegister(); 245 247 246 248 psTrace("psModules.config", 3, "Loading %s configuration from file %s\n", … … 1496 1498 } 1497 1499 } 1500 globfree(&globList); 1498 1501 } 1499 1502 psFree (words); -
branches/pap/psModules/src/config/pmErrorCodes.dat
r23688 r25027 12 12 SKY Problem in sky 13 13 STAMPS Unable to select stamps for PSF-matching 14 SMALL_AREA Small area for PSF-matching 14 15 # these errors correspond to standard exit conditions 15 16 ARGUMENTS Incorrect arguments -
branches/pap/psModules/src/detrend/Makefile.am
r20617 r25027 16 16 pmShifts.c \ 17 17 pmDark.c \ 18 pmRemnance.c 18 pmRemnance.c \ 19 pmPattern.c 19 20 20 21 # pmSkySubtract.c … … 33 34 pmShifts.h \ 34 35 pmDark.h \ 35 pmRemnance.h 36 pmRemnance.h \ 37 pmPattern.h 36 38 37 39 # pmSkySubtract.h -
branches/pap/psModules/src/detrend/pmDark.c
r21183 r25027 1 #ifdef HAVE_CONFIG_H 2 #include <config.h> 3 #endif 4 1 5 #include <stdio.h> 2 6 #include <pslib.h> 3 7 #include <string.h> 8 #include <strings.h> 4 9 5 10 #include "psPolynomialMD.h" … … 12 17 #include "pmReadoutStack.h" 13 18 #include "pmDetrendThreads.h" 14 19 #include "pmErrorCodes.h" 15 20 #include "pmDark.h" 16 21 17 22 #define PM_DARK_FITS_EXTNAME "PS_DARK" // FITS extension name for ordinates table 18 23 #define PM_DARK_FITS_NAME "NAME" // Column name for concept name in ordinates table 24 #define PM_DARK_FITS_RULE "RULE" // Column name for concept rule in ordinates table 19 25 #define PM_DARK_FITS_ORDER "ORDER" // Column name for polynomial order in ordinates table 20 26 #define PM_DARK_FITS_SCALE "SCALE" // Column name for scaling option in ordinates table … … 22 28 #define PM_DARK_FITS_MAX "MAX" // Column name for maximum value in ordinates table 23 29 24 25 26 // Look up the value of an ordinate in a readout 27 static bool ordinateLookup(float *value, // Value of ordinate, to return 28 bool *inRange, // is value within min : max range? 29 const char *name, // Name of ordinate (concept name) 30 bool scale, // Scale the value? 31 float min, float max, // Minimum and maximum values for scaling 32 const pmReadout *ro // Readout of interest 33 ) 34 { 35 assert(value); 36 assert(name); 37 assert(ro); 38 39 *inRange = true; 40 41 pmCell *cell = ro->parent; // Parent cell 42 if (!cell) { 43 return false; 44 } 30 static bool ordinateParseConcept(double *value, const pmReadout *readout, const char *name) { 31 32 *value = NAN; 33 34 pmCell *cell = readout->parent; // Parent cell 35 psAssert(cell, "readout is missing cell \n"); 36 45 37 psMetadataItem *item = psMetadataLookup(cell->concepts, name); 46 38 if (!item) { 47 39 pmChip *chip = cell->parent; // Parent chip 48 if (!chip) { 49 return false; 50 } 40 psAssert(chip, "cell is missing chip \n"); 41 51 42 item = psMetadataLookup(chip->concepts, name); 52 43 if (!item) { 53 44 pmFPA *fpa = chip->parent; // Parent FPA 54 if (!fpa) { 55 return false; 56 } 45 psAssert(fpa, "chip is missing fpa \n"); 46 57 47 item = psMetadataLookup(fpa->concepts, name); 58 48 if (!item) { 59 ps Warning("Unable to find concept %s in readout", name);49 psError(PM_ERR_CONFIG, true, "Unable to find concept %s in readout", name); 60 50 return false; 61 51 } … … 63 53 } 64 54 65 *value = psMetadataItemParseF 32(item); // Value of interest55 *value = psMetadataItemParseF64(item); // Value of interest 66 56 if (!isfinite(*value)) { 67 57 psWarning("Non-finite value (%f) of concept %s in readout", *value, name); 68 return false; 69 } 58 } 59 return true; 60 } 61 62 static bool ordinateParseRule(double *value, const pmReadout *readout, const char *name, const char *rule) { 63 64 psAssert(name, "ordinate name is not defined"); 65 psAssert(rule, "ordinate rule is not defined"); 66 67 *value = NAN; 68 69 psArray *words = psStringSplitArray(rule, " ", false); 70 71 // we should have a rule of the form (concept) OP (concept) OP (concept) ... 72 // for now, the only allowed OP is * (eventually, we can steal code from opihi for a better 73 // RPN parser). 74 75 if (words->n % 2 == 0) { 76 psError(PM_ERR_CONFIG, true, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule); 77 psFree(words); 78 return false; 79 } 80 81 for (int i = 1; i < words->n; i+=2) { 82 if (strcmp((char *)words->data[i], "*")) { 83 psError(PM_ERR_CONFIG, true, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule); 84 psFree(words); 85 return false; 86 } 87 } 88 89 if (!ordinateParseConcept(value, readout, words->data[0])) { 90 psError(PM_ERR_CONFIG, false, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule); 91 psFree(words); 92 return false; 93 } 94 95 double value2 = 0.0; 96 for (int i = 2; i < words->n; i+=2) { 97 if (!ordinateParseConcept(&value2, readout, words->data[i])) { 98 psError(PM_ERR_CONFIG, false, "syntax error in DARK.ORDINATE %s rule %s\n", name, rule); 99 psFree(words); 100 return false; 101 } 102 *value *= value2; 103 } 104 psFree(words); 105 return true; 106 } 107 108 // Look up the value of an ordinate in a readout 109 static bool ordinateLookup(double *value, // Value of ordinate, to return 110 bool *inRange, // is value within min : max range? 111 const char *name, // Name of ordinate (concept or abstract name) 112 const char *rule, // Rule for generating the value (if NULL use name as concept) 113 bool scale, // Scale the value? 114 float min, float max, // Minimum and maximum values for scaling 115 const pmReadout *readout // Readout of interest 116 ) 117 { 118 assert(value); 119 assert(name); 120 assert(readout); 121 122 *inRange = true; 123 124 if (rule) { 125 if (!ordinateParseRule(value, readout, name, rule)) { 126 psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", rule, name); 127 return false; 128 } 129 } else { 130 if (!ordinateParseConcept(value, readout, name)) { 131 psError(PM_ERR_CONFIG, false, "trouble parsing rule %s for DARK.ORDINATE %s", rule, name); 132 return false; 133 } 134 } 135 70 136 if (scale) { 71 137 if (*value < min || *value > max) { … … 82 148 { 83 149 psFree(ord->name); 150 psFree(ord->rule); 84 151 return; 85 152 } … … 91 158 92 159 ord->name = psStringCopy(name); 160 ord->rule = NULL; 93 161 ord->order = order; 94 162 ord->scale = false; … … 118 186 119 187 pmReadout *readout = inputs->data[i]; // Readout of interest 120 float normValue; // Normalisation value 121 if (!ordinateLookup(&normValue, &inRange, normConcept, false, NAN, NAN, readout)) { 122 psWarning("Unable to find value of %s for readout %d", normConcept, i); 188 double normValue; // Normalisation value 189 if (!ordinateLookup(&normValue, &inRange, normConcept, NULL, false, NAN, NAN, readout)) { 190 psError(PM_ERR_CONFIG, false, "problem finding concept %s for DARK.NORM", normConcept); 191 return false; 192 } 193 if (!isfinite(normValue)) { 194 psWarning("Unable to find acceptable value of %s for readout %d", normConcept, i); 123 195 roMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff; 124 196 norm->data.F32[i] = NAN; … … 140 212 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information 141 213 if (ord->order <= 0) { 142 psError(PS_ERR_UNKNOWN, true, "Bad order for concept%s (%d) --- ignored", ord->name, ord->order);214 psError(PS_ERR_UNKNOWN, true, "Bad order for DARK.ORDINATE %s (%d) --- ignored", ord->name, ord->order); 143 215 psFree(values); 144 216 psFree(roMask); … … 157 229 158 230 pmReadout *readout = inputs->data[j]; // Readout of interest 159 float value = NAN; // Value of ordinate 160 if (!ordinateLookup(&value, &inRange, ord->name, ord->scale, ord->min, ord->max, readout)) { 231 double value = NAN; // Value of ordinate 232 if (!ordinateLookup(&value, &inRange, ord->name, ord->rule, ord->scale, ord->min, ord->max, readout)) { 233 psError(PM_ERR_CONFIG, false, "problem finding rule for DARK.ORDINATE %s", ord->name); 234 return false; 235 } 236 if (!isfinite(value)) { 237 psWarning("Unable to find acceptable value of DARK.ORDINATE %s for readout %d", ord->name, i); 161 238 roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff; 162 239 val->data.F32[i] = NAN; … … 165 242 } 166 243 if (!inRange) { 244 psWarning("Value of DARK.ORDINATE %s for readout %d is out of range", ord->name, i); 167 245 roMask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xff; 168 246 val->data.F32[i] = NAN; … … 309 387 return false; 310 388 } 389 390 pmDarkVisualInit(values); 311 391 312 392 pmReadout *outReadout = output->readouts->data[0]; … … 352 432 psVectorInit(poly->coeff, NAN); 353 433 } 434 435 pmDarkVisualPixelFit(pixels, mask); 436 pmDarkVisualPixelModel(poly, values); 437 354 438 for (int k = 0; k < poly->coeff->n; k++) { 355 439 pmReadout *ro = output->readouts->data[k]; // Readout of interest … … 447 531 for (int i = 0; i < numOrdinates; i++) { 448 532 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest 449 floatvalue = NAN; // Value for ordinate450 if (!ordinateLookup(&value, &inRange, ord->name, ord-> scale, ord->min, ord->max, readout)) {451 psError(PS_ERR_UNKNOWN, true, "Unable to find value for %s", ord->name);533 double value = NAN; // Value for ordinate 534 if (!ordinateLookup(&value, &inRange, ord->name, ord->rule, ord->scale, ord->min, ord->max, readout)) { 535 psError(PS_ERR_UNKNOWN, true, "Unable to find value for DARK.ORDINATE %s", ord->name); 452 536 psFree(values); 453 537 return false; 454 538 } 539 if (!isfinite(value)) { 540 psError(PS_ERR_UNKNOWN, true, "Value for DARK.ORDINATE %s is NAN", ord->name); 541 psFree(values); 542 return false; 543 } 455 544 values->data.F32[i] = value; 456 545 } 457 floatnorm = NAN; // Normalisation value546 double norm = NAN; // Normalisation value 458 547 bool doNorm = false; // Do normalisation? 459 548 if (normConcept && strlen(normConcept) > 0) { 460 if (!ordinateLookup(&norm, &inRange, normConcept, false, NAN, NAN, readout)) {549 if (!ordinateLookup(&norm, &inRange, normConcept, NULL, false, NAN, NAN, readout)) { 461 550 psError(PS_ERR_UNKNOWN, true, "Unable to find value for %s", normConcept); 462 551 psFree(values); … … 470 559 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate information 471 560 if (ord->order <= 0) { 472 psError(PS_ERR_UNKNOWN, true, "Bad order for concept%s (%d) --- ignored", ord->name, ord->order);561 psError(PS_ERR_UNKNOWN, true, "Bad order for DARK.ORDINATE %s (%d) --- ignored", ord->name, ord->order); 473 562 psFree(values); 474 563 psFree(orders); … … 701 790 pmDarkOrdinate *ord = ordinates->data[i]; // Ordinate of interest 702 791 psMetadata *row = psMetadataAlloc(); // FITS table row 703 psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "Concept name", ord->name); 792 psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_NAME, 0, "DARK.ORDINATE name", ord->name); 793 794 // XXX write a dummy value if ord->rule == NULL? (eg, NONE) 795 if (ord->rule) { 796 psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_RULE, 0, "DARK.ORDINATE rule", ord->rule); 797 } else { 798 psMetadataAddStr(row, PS_LIST_TAIL, PM_DARK_FITS_RULE, 0, "DARK.ORDINATE rule", "NONE"); 799 } 800 704 801 psMetadataAddS32(row, PS_LIST_TAIL, PM_DARK_FITS_ORDER, 0, "Polynomial order", ord->order); 705 802 psMetadataAddBool(row, PS_LIST_TAIL, PM_DARK_FITS_SCALE, 0, "Scale values?", ord->scale); … … 878 975 ord->max = psMetadataLookupF32(NULL, row, PM_DARK_FITS_MAX); 879 976 977 // load the ordinate rule; it is not an error if this field is missing or NULL 978 // a NULL rule means 'use the name as the single concept' 979 const char *rule = psMetadataLookupStr(&mdok, row, PM_DARK_FITS_RULE); 980 if (!rule || !strcasecmp(rule, "NONE")) { 981 ord->rule = NULL; 982 } else { 983 ord->rule = psStringCopy(rule); 984 } 880 985 ordinates->data[i] = ord; 881 986 } … … 892 997 } 893 998 999 #if (HAVE_KAPA) 1000 #include <kapa.h> 1001 #include "pmKapaPlots.h" 1002 #include "pmVisual.h" 1003 1004 static int nKapa = 0; 1005 static int *kapa = NULL; 1006 static bool plotFlag = true; 1007 static psArray *xVectors = NULL; 1008 1009 // this init function only gets the ordinates for the first readout... 1010 bool pmDarkVisualInit(psArray *values) { 1011 1012 if (!pmVisualIsVisual()) return true; 1013 1014 // skip if we have already opened the windows (or if none are requested...) 1015 if (nKapa) return true; 1016 1017 // values has Ninput vectors with Norder elements; we need Norder vectors with Ninput elements... 1018 int nOrders = 0; 1019 for (int i = 0; i < values->n; i++) { 1020 psVector *vect = values->data[i]; 1021 if (!nOrders) { 1022 nOrders = vect->n; 1023 } else { 1024 psAssert (nOrders == vect->n, "mismatch in order vector lengths"); 1025 } 1026 } 1027 xVectors = psArrayAlloc(nOrders); 1028 for (int i = 0; i < nOrders; i++) { 1029 xVectors->data[i] = psVectorAlloc(values->n, PS_TYPE_F32); 1030 } 1031 1032 for (int i = 0; i < values->n; i++) { 1033 psVector *vect = values->data[i]; 1034 for (int j = 0; j < vect->n; j++) { 1035 psVector *xVec = xVectors->data[j]; 1036 xVec->data.F32[i] = vect->data.F32[j]; 1037 } 1038 } 1039 1040 nKapa = nOrders; 1041 1042 kapa = psAlloc(nKapa*sizeof(int)); 1043 1044 for (int i = 0; i < nKapa; i++) { 1045 kapa[i] = -1; 1046 pmVisualInitWindow(&kapa[i], "ppmerge"); 1047 } 1048 return true; 1049 } 1050 1051 bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask) { 1052 1053 Graphdata graphdata; 1054 1055 if (!pmVisualIsVisual()) return true; 1056 1057 KapaInitGraph(&graphdata); 1058 1059 psAssert(nKapa == xVectors->n, "inconsistent number of orders %d vs %ld\n", nKapa, xVectors->n); 1060 1061 psVector *xSub = psVectorAlloc(pixels->n, PS_TYPE_F32); 1062 psVector *ySub = psVectorAlloc(pixels->n, PS_TYPE_F32); 1063 1064 for (int i = 0; i < xVectors->n; i++) { 1065 psVector *x = xVectors->data[i]; 1066 1067 // generate vectors of the unmasked values 1068 int nSub = 0; 1069 for (int j = 0; j < pixels->n; j++) { 1070 if (mask && mask->data.PS_TYPE_VECTOR_MASK_DATA[j]) continue; 1071 xSub->data.F32[nSub] = x->data.F32[j]; 1072 ySub->data.F32[nSub] = pixels->data.F32[j]; 1073 nSub ++; 1074 } 1075 xSub->n = ySub->n = nSub; 1076 1077 // plot the unmasked values 1078 pmVisualScaleGraphdata (&graphdata, xSub, ySub, false); 1079 KapaSetGraphData(kapa[i], &graphdata); 1080 KapaSetLimits(kapa[i], &graphdata); 1081 KapaClearPlots (kapa[i]); 1082 1083 KapaSetFont (kapa[i], "courier", 14); 1084 KapaBox (kapa[i], &graphdata); 1085 KapaSendLabel (kapa[i], "ordinate", KAPA_LABEL_XM); 1086 KapaSendLabel (kapa[i], "pixel values", KAPA_LABEL_YM); 1087 1088 graphdata.color = KapaColorByName("black"); 1089 graphdata.style = 2; 1090 graphdata.ptype = 2; 1091 KapaPrepPlot (kapa[i], xSub->n, &graphdata); 1092 KapaPlotVector(kapa[i], xSub->n, xSub->data.F32, "x"); 1093 KapaPlotVector(kapa[i], xSub->n, ySub->data.F32, "y"); 1094 } 1095 pmVisualAskUser (&plotFlag); 1096 return true; 1097 } 1098 1099 bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values) { 1100 1101 Graphdata graphdata; 1102 1103 if (!pmVisualIsVisual()) return true; 1104 1105 KapaInitGraph(&graphdata); 1106 1107 psAssert(nKapa == xVectors->n, "inconsistent number of orders %d vs %ld\n", nKapa, xVectors->n); 1108 1109 psVector *yFit = psVectorAlloc(values->n, PS_TYPE_F32); 1110 1111 for (int i = 0; i < values->n; i++) { 1112 psVector *coord = values->data[i]; 1113 yFit->data.F32[i] = psPolynomialMDEval (poly, coord); 1114 } 1115 1116 for (int i = 0; i < xVectors->n; i++) { 1117 psVector *xFit = xVectors->data[i]; 1118 1119 KapaGetGraphData(kapa[i], &graphdata); 1120 graphdata.color = KapaColorByName("red"); 1121 graphdata.style = 2; 1122 graphdata.ptype = 7; 1123 KapaPrepPlot (kapa[i], xFit->n, &graphdata); 1124 KapaPlotVector(kapa[i], xFit->n, xFit->data.F32, "x"); 1125 KapaPlotVector(kapa[i], xFit->n, yFit->data.F32, "y"); 1126 } 1127 pmVisualAskUser (&plotFlag); 1128 return true; 1129 } 1130 1131 bool pmDarkVisualCleanup() { 1132 1133 for (int i = 0; i < nKapa; i++) { 1134 KapaClose(kapa[i]); 1135 } 1136 psFree (kapa); 1137 psFree (xVectors); 1138 return true; 1139 } 1140 1141 # else 1142 1143 bool pmDarkVisualInit(psArray *values) { return true; } 1144 bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask) { return true; } 1145 bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values) { return true; } 1146 bool pmDarkVisualCleanup() { return true; } 1147 1148 # endif -
branches/pap/psModules/src/detrend/pmDark.h
r21183 r25027 13 13 // An ordinate for fitting darks 14 14 typedef struct { 15 psString name; // Name of concept to fit 15 psString name; // Name of ordinate 16 psString rule; // Rule for generating ordinate (math on concepts) 16 17 int order; // Polynomial order to fit 17 18 bool scale; // Rescale values? … … 116 117 ); 117 118 119 bool pmDarkVisualInit(psArray *values); 120 bool pmDarkVisualPixelFit(psVector *pixels, psVector *mask); 121 bool pmDarkVisualCleanup(); 122 bool pmDarkVisualPixelModel(psPolynomialMD *poly, psArray *values); 118 123 119 124 #endif -
branches/pap/psModules/src/detrend/pmDetrendDB.c
r23600 r25027 105 105 DETREND_STRING_CASE(FRINGE); 106 106 DETREND_STRING_CASE(ASTROM); 107 DETREND_STRING_CASE(NOISEMAP); 107 108 default: 108 109 return NULL; -
branches/pap/psModules/src/detrend/pmDetrendDB.h
r23487 r25027 35 35 PM_DETREND_TYPE_BACKGROUND, 36 36 PM_DETREND_TYPE_ASTROM, 37 PM_DETREND_TYPE_NOISEMAP, 37 38 } pmDetrendType; 38 39 -
branches/pap/psModules/src/detrend/pmDetrendThreads.c
r21457 r25027 60 60 } 61 61 62 // NOISEMAP : for now, not applied in the threaded loop 63 62 64 return true; 63 65 } -
branches/pap/psModules/src/detrend/pmFringeStats.c
r23259 r25027 464 464 for (long i = 0; i < fringes->n; i++) { 465 465 pmFringeStats *fringe = fringes->data[i]; // The fringe of interest 466 if (!fringe) { 467 psWarning ("skipping empty fringe stats for entry %ld -- video cell?\n", i); 468 continue; 469 } 466 470 pmFringeRegions *regions = fringe->regions; // The fringe regions 467 471 if (numPoints == 0) { … … 496 500 for (long i = 0; i < fringes->n; i++) { 497 501 pmFringeStats *fringe = fringes->data[i]; // The fringe of interest 502 if (!fringe) { 503 psWarning ("skipping empty fringe stats for entry %ld -- video cell?\n", i); 504 continue; 505 } 498 506 pmFringeRegions *regions = fringe->regions; // The fringe regions 499 507 // Copy the data over … … 520 528 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 521 529 522 bool pmFringesFormat(pmCell *cell,psMetadata *header, const psArray *fringes)523 { 524 PS_ASSERT_PTR_NON_NULL( cell, false);530 psArray *pmFringesFormatTable(psMetadata *header, const psArray *fringes) 531 { 532 PS_ASSERT_PTR_NON_NULL(header, false); 525 533 PS_ASSERT_ARRAY_NON_NULL(fringes, false); 526 534 … … 531 539 if (stats->regions != regions) { 532 540 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Regions for fringe statistics are not identical.\n"); 533 return false;541 return NULL; 534 542 } 535 543 } … … 557 565 // Vectors: x, y, mask, f, df 558 566 559 psMetadata *scalars = psMemIncrRefCounter(header); // Metadata to hold the scalars; will be the header 560 if (!scalars) { 561 scalars = psMetadataAlloc(); 562 } 563 psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGDX", PS_META_REPLACE, "Median box half-width", 564 regions->dX); 565 psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGDY", PS_META_REPLACE, "Median box half-height", 566 regions->dY); 567 psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGNX", PS_META_REPLACE, "Large-scale smoothing in x", 568 regions->nX); 569 psMetadataAddS32(scalars, PS_LIST_TAIL, "PSFRNGNY", PS_META_REPLACE, "Large-scale smoothing in y", 570 regions->nY); 571 psMetadataAdd(cell->analysis, PS_LIST_TAIL, "FRINGE.HEADER", PS_DATA_METADATA, 572 "Header for fringe data", scalars); 573 psFree(scalars); 574 567 psMetadataAddS32(header, PS_LIST_TAIL, "PSFRNGDX", PS_META_REPLACE, "Median box half-width", regions->dX); 568 psMetadataAddS32(header, PS_LIST_TAIL, "PSFRNGDY", PS_META_REPLACE, "Median box half-height", regions->dY); 569 psMetadataAddS32(header, PS_LIST_TAIL, "PSFRNGNX", PS_META_REPLACE, "Large-scale smoothing in x", regions->nX); 570 psMetadataAddS32(header, PS_LIST_TAIL, "PSFRNGNY", PS_META_REPLACE, "Large-scale smoothing in y", regions->nY); 575 571 576 572 psArray *table = psArrayAlloc(numRows); // The table … … 605 601 } 606 602 607 psMetadataAdd(cell->analysis, PS_LIST_TAIL, "FRINGE", PS_DATA_ARRAY, "Fringe data", table); 608 609 return true; 610 } 611 612 613 psArray *pmFringesParse(pmCell *cell) 614 { 615 PS_ASSERT_PTR_NON_NULL(cell, NULL); 603 return table; 604 } 605 606 psArray *pmFringesParseTable(psArray *table, psMetadata *header) 607 { 608 PS_ASSERT_PTR_NON_NULL(table, NULL); 609 PS_ASSERT_PTR_NON_NULL(header, NULL); 616 610 617 611 bool mdok; // Status of MD lookup 618 psMetadata *header = psMetadataLookupMetadata(&mdok, cell->analysis, "FRINGE.HEADER"); // Header619 if (!mdok || !header) {620 psError(PS_ERR_UNKNOWN, false, "Unable to find header for fringe data.\n");621 return NULL;622 }623 624 psArray *table = psMetadataLookupPtr(NULL, cell->analysis, "FRINGE"); // FITS table625 if (!table) {626 psError(PS_ERR_UNKNOWN, false, "Unable to find table for fringe data.\n");627 return NULL;628 }629 630 612 631 613 // Read the scalars from the header … … 722 704 } 723 705 706 bool pmFringesFormat(pmCell *cell, psMetadata *inHeader, const psArray *fringes) 707 { 708 PS_ASSERT_PTR_NON_NULL(cell, false); 709 PS_ASSERT_ARRAY_NON_NULL(fringes, false); 710 711 psMetadata *header = psMemIncrRefCounter(inHeader); // Metadata to hold the scalars; will be the header 712 if (!inHeader) { 713 inHeader = psMetadataAlloc(); 714 } 715 716 psArray *table = pmFringesFormatTable(header, fringes); 717 if (!table) { 718 psError (PS_ERR_UNKNOWN, false, "unable to generate table from fringes"); 719 psFree(header); 720 return NULL; 721 } 722 723 psMetadataAdd(cell->analysis, PS_LIST_TAIL, "FRINGE.HEADER", PS_DATA_METADATA, "Header for fringe data", header); 724 psFree(header); 725 726 psMetadataAdd(cell->analysis, PS_LIST_TAIL, "FRINGE.TABLE", PS_DATA_ARRAY, "Fringe data", table); 727 psFree(table); 728 729 return true; 730 } 731 732 psArray *pmFringesParse(pmCell *cell) 733 { 734 PS_ASSERT_PTR_NON_NULL(cell, NULL); 735 736 bool mdok; // Status of MD lookup 737 psMetadata *header = psMetadataLookupMetadata(&mdok, cell->analysis, "FRINGE.HEADER"); // Header 738 if (!mdok || !header) { 739 psError(PS_ERR_UNKNOWN, false, "Unable to find header for fringe data.\n"); 740 return NULL; 741 } 742 743 psArray *table = psMetadataLookupPtr(NULL, cell->analysis, "FRINGE.TABLE"); // FITS table 744 if (!table) { 745 psError(PS_ERR_UNKNOWN, false, "Unable to find table for fringe data.\n"); 746 return NULL; 747 } 748 749 psArray *fringes = pmFringesParseTable(table, header); 750 if (!fringes) { 751 psError(PS_ERR_UNKNOWN, false, "Unable to add parse the fringe table data"); 752 return NULL; 753 } 754 755 return fringes; 756 } 724 757 725 758 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 821 854 822 855 // Solve the least-squares equation 823 if (! psMatrixGJSolve(A, B)) { 824 psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations. Returning NULL.\n"); 856 if (!psMatrixGJSolve(A, B)) { 857 psLogMsg("psModules.detrend", PS_LOG_INFO, "Could not solve linear equations. Returning NULL.\n"); 858 psFree(A); 859 psFree(B); 825 860 return false; 826 861 } … … 882 917 883 918 psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_QUARTILE); // Statistics 884 psVectorStats(stats, diffs, NULL, mask, 1); 919 if (!psVectorStats(stats, diffs, NULL, mask, 1)) { 920 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 921 return 0; 922 } 885 923 float middle = stats->sampleMedian; // The middle of the distribution 886 924 float thresh = rej * 0.74 * (stats->sampleUQ - stats->sampleLQ); // The rejection threshold … … 969 1007 970 1008 // Get rid of the extreme outliers by assuming most of the points are somewhat clustered 971 psVectorStats(median, science->f, NULL, NULL, 0); 1009 if (!psVectorStats(median, science->f, NULL, NULL, 0)) { 1010 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 1011 return NULL; 1012 } 972 1013 scale->coeff->data.F32[0] = median->sampleMedian; 973 1014 for (int i = 0; i < fringes->n; i++) { 974 1015 pmFringeStats *fringe = fringes->data[i]; // The fringe of interest 975 psVectorStats(median, fringe->f, NULL, NULL, 0); 1016 if (!psVectorStats(median, fringe->f, NULL, NULL, 0)) { 1017 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 1018 return NULL; 1019 } 976 1020 scale->coeff->data.F32[0] -= median->sampleMedian; 977 1021 scale->coeff->data.F32[i] = 0.0; -
branches/pap/psModules/src/detrend/pmFringeStats.h
r21183 r25027 142 142 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 143 143 144 /// Write an array of fringes measurements to a FITS table. 145 /// 146 /// Writes an array of fringe measurements for a cell as a FITS table in the analysis metadata. The array of 147 /// fringe statistics must all use the same fringe regions (or there is no point in storing them all 148 /// together). The header is supplemented with scalar values dX, dY, nX and nY (as PSFRNGDX, PSFRNGDY, 149 /// PSFRNGNX, PSFRNGNY) from the fringe regions, while the fringe coordinates and mask are written as a FITS 150 /// table (as x, y, mask, f, df; f and df are vectors). 144 /// Convert an array of fringes measurements to a psArray suitable for writing as a FITS table. 145 /// 146 /// Converts an array of fringe measurements for a cell into the corresponding rows of a FITS 147 /// table (array of psMetadata). The array of fringe statistics must all use the same fringe 148 /// regions (or there is no point in storing them all together). The header is supplemented 149 /// with scalar values dX, dY, nX and nY (as PSFRNGDX, PSFRNGDY, PSFRNGNX, PSFRNGNY) from the 150 /// fringe regions, while the fringe coordinates and mask are written as a FITS table rows (as 151 /// x, y, mask, f, df; f and df are vectors). Use psFitsTableWrite to save the resulting rows 152 /// to disk. 153 psArray *pmFringesFormatTable(psMetadata *header, const psArray *fringes); 154 155 156 /// Parses an array of fringes measurements from a FITS table. 157 /// 158 /// The fringes for the cell are read from the FITS table (array of psMetadata rows). The 159 /// table provides the region and the (possibly multiple) fringe statistics for that region. 160 /// The supplied header defines the scalar values dX, dY, nX and nY (as PSFRNGDX, PSFRNGDY, 161 /// PSFRNGNX, PSFRNGNY) 162 psArray *pmFringesParseTable(psArray *table, psMetadata *header); 163 164 /// Deprecated Function: converts the fringes to a FITS table (array of psMetadata) and saves 165 /// them on the cell->analysis; scalar values are dX, dY, nX and nY are written to the header 166 /// (as PSFRNGDX, PSFRNGDY, PSFRNGNX, PSFRNGNY) 151 167 bool pmFringesFormat(pmCell *cell, ///< Cell for which to write 152 168 psMetadata *header, ///< Header, or NULL … … 154 170 ); 155 171 156 /// Parses an array of fringes measurements from a FITS table. 157 /// 158 /// The fringes for the cell are read from the FITS table in the analysis metadata. The table provides the 159 /// region and the (possibly multiple) fringe statistics for that region. The current extension is used if 160 /// the extension name is not provided. 172 /// Deprecated Function: pulls a the header and FITS table (array of psMetadata) representing 173 /// the fringes from the cell->analysis and converts to fringe measurements 161 174 psArray *pmFringesParse(pmCell *cell ///< Cell for which to read fringes 162 175 ); 163 164 176 165 177 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// -
branches/pap/psModules/src/detrend/pmMaskBadPixels.c
r21183 r25027 81 81 82 82 83 bool pmMaskFlagSuspectPixels (pmReadout *output, const pmReadout *readout, float median, float stdev,84 float rej, psImageMaskType maskVal)83 bool pmMaskFlagSuspectPixelsBySigma(pmReadout *output, const pmReadout *readout, float median, float stdev, 84 float rej, psImageMaskType maskVal) 85 85 { 86 86 PS_ASSERT_PTR_NON_NULL(readout, false); … … 115 115 // If we get down here and the statistics are missing, then we should go and mask the entire image 116 116 psWarning("Missing statistics --- flagging entire image as suspect."); 117 return (psImage*)psBinaryOp(suspect, suspect, "+", psScalarAlloc(1.0, PS_TYPE_F32)); 117 psBinaryOp (suspect, suspect, "+", psScalarAlloc(1.0, PS_TYPE_F32)); 118 return true; 118 119 } 119 120 … … 128 129 for (int x = 0; x < image->numCols; x++) { 129 130 if (fabs((image->data.F32[y][x] - median) / stdev) < rej) continue; 131 if (mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) continue; 132 suspect->data.F32[y][x] += 1.0; 133 } 134 } 135 psFree(suspect); // Drop reference 136 137 psMetadataItem *numItem = psMetadataLookup(output->analysis, PM_MASK_ANALYSIS_NUM); // Item with number 138 assert(numItem); 139 numItem->data.S32++; 140 141 return true; 142 } 143 144 bool pmMaskFlagSuspectPixelsByValue(pmReadout *output, const pmReadout *readout, 145 float min, float max, psImageMaskType maskVal) 146 { 147 PS_ASSERT_PTR_NON_NULL(readout, false); 148 PS_ASSERT_IMAGE_NON_NULL(readout->image, false); 149 PS_ASSERT_IMAGE_NON_EMPTY(readout->image, false); 150 PS_ASSERT_IMAGE_TYPE(readout->image, PS_TYPE_F32, false); 151 if (readout->mask) { 152 PS_ASSERT_IMAGE_NON_EMPTY(readout->mask, false); 153 PS_ASSERT_IMAGES_SIZE_EQUAL(readout->image, readout->mask, false); 154 PS_ASSERT_IMAGE_TYPE(readout->mask, PS_TYPE_IMAGE_MASK, false); 155 } 156 PS_ASSERT_PTR_NON_NULL(output, false); 157 158 bool mdok; // Status of MD lookup 159 psImage *suspect = psMetadataLookupPtr(&mdok, output->analysis, PM_MASK_ANALYSIS_SUSPECT); // Suspect img 160 if (suspect) { 161 PS_ASSERT_IMAGE_NON_EMPTY(suspect, false); 162 PS_ASSERT_IMAGE_TYPE(suspect, PS_TYPE_F32, false); 163 PS_ASSERT_IMAGES_SIZE_EQUAL(readout->image, suspect, false); 164 psMemIncrRefCounter(suspect); 165 } else { 166 suspect = psImageAlloc(readout->image->numCols, readout->image->numRows, PS_TYPE_F32); 167 psImageInit(suspect, 0); 168 psMetadataAddImage(output->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_SUSPECT, PS_META_REPLACE, 169 "Suspect pixels", suspect); 170 psMetadataAddS32(output->analysis, PS_LIST_TAIL, PM_MASK_ANALYSIS_NUM, PS_META_REPLACE, 171 "Number of input images", 0); 172 } 173 174 psImage *image = readout->image; // Image of interest 175 psImage *mask = readout->mask; // Corresponding mask 176 177 psTrace ("psModules.detrend", 3, "suspect: < %f or > %f\n", min, max); 178 179 // XXX this loop could result in pixels with suspect = 0.0 but no valid input pixels (all 180 // masked). need to track the number of good as well as suspect pixels? 181 for (int y = 0; y < image->numRows; y++) { 182 for (int x = 0; x < image->numCols; x++) { 183 bool above = image->data.F32[y][x] > max; 184 bool below = image->data.F32[y][x] < min; 185 if (!above && !below) continue; 130 186 if (mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal)) continue; 131 187 suspect->data.F32[y][x] += 1.0; -
branches/pap/psModules/src/detrend/pmMaskBadPixels.h
r21183 r25027 50 50 /// high value in the suspect pixels image, allowing them to be identified. The suspect pixels 51 51 /// image is of type S32. The relevant median and standard deviation must be supplied in the 52 /// readout->analysis metadata as READOUT.MEDIAN, READOUT.STDEV e53 bool pmMaskFlagSuspectPixels (pmReadout *output, ///< Output readout, optionally with suspect pixels image52 /// readout->analysis metadata as READOUT.MEDIAN, READOUT.STDEV 53 bool pmMaskFlagSuspectPixelsBySigma(pmReadout *output, ///< Output readout, optionally with suspect pixels image 54 54 const pmReadout *readout, ///< Readout to inspect 55 55 float median, ///< Image median 56 56 float stdev, ///< Image standard deviation 57 57 float rej, ///< Rejection threshold (standard deviations) 58 psImageMaskType maskVal ///< Mask value for statistics 59 ); 60 61 /// Find out-of-range pixels and flag them 62 /// 63 /// Pixels great > max or < min have the corresponding pixel in the "suspect pixels" image 64 /// incremented. After accumulating over a suitable sample of images, bad pixels should have a 65 /// high value in the suspect pixels image, allowing them to be identified. The suspect pixels 66 /// image is of type S32. The relevant median and standard deviation must be supplied in the 67 /// readout->analysis metadata as READOUT.MEDIAN, READOUT.STDEV 68 bool pmMaskFlagSuspectPixelsByValue(pmReadout *output, ///< Output readout, optionally with suspect pixels image 69 const pmReadout *readout, ///< Readout to inspect 70 float min, ///< Image min acceptable value 71 float max, ///< Image max acceptable value 58 72 psImageMaskType maskVal ///< Mask value for statistics 59 73 ); -
branches/pap/psModules/src/detrend/pmOverscan.c
r23826 r25027 74 74 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0; 75 75 ordinate->data.F32[i] = 2.0*(float)i/(float)pixels->n - 1.0; // Scale to [-1,1] 76 psVectorStats(myStats, values, NULL, NULL, 0); 76 if (!psVectorStats(myStats, values, NULL, NULL, 0)) { 77 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 78 return false; 79 } 77 80 reduced->data.F32[i] = psStatsGetValue(myStats, statistic); 78 81 } else if (overscanOpts->fitType == PM_FIT_NONE) { … … 275 278 psFree(iter); 276 279 277 (void)psVectorStats(stats, pixels, NULL, NULL, 0); 280 if (!psVectorStats(stats, pixels, NULL, NULL, 0)) { 281 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 282 return false; 283 } 278 284 psFree(pixels); 279 285 double reduced = psStatsGetValue(stats, statistic); // Result of statistics … … 349 355 psString comment = NULL; // Comment to add 350 356 psStats *vectorStats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 351 psVectorStats (vectorStats, reduced, NULL, NULL, 0); 357 if (!psVectorStats (vectorStats, reduced, NULL, NULL, 0)) { 358 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 359 return false; 360 } 352 361 psStringAppend(&comment, "Mean Overscan value: %f", vectorStats->sampleMean); 353 362 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, ""); … … 412 421 psString comment = NULL; // Comment to add 413 422 psStats *vectorStats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 414 psVectorStats (vectorStats, reduced, NULL, NULL, 0); 423 if (!psVectorStats (vectorStats, reduced, NULL, NULL, 0)) { 424 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 425 return false; 426 } 415 427 psStringAppend(&comment, "Mean Overscan value: %f", vectorStats->sampleMean); 416 428 psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, comment, ""); -
branches/pap/psModules/src/detrend/pmRemnance.c
r23259 r25027 66 66 values->n = numValues; 67 67 if (!psVectorStats(stats, values, NULL, NULL, 0)) { 68 // Can't do anything about it 69 psErrorClear(); 68 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 69 return false; 70 } 71 if (isnan(stats->sampleMedian)) { 70 72 maxMask = max; 71 73 continue; -
branches/pap/psModules/src/detrend/pmShutterCorrection.c
r23487 r25027 350 350 psStats *rawStats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 351 351 psStats *resStats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 352 psVectorStats (rawStats, counts, NULL, NULL, 0); 353 psVectorStats (resStats, resid, NULL, NULL, 0); 352 if (!psVectorStats (rawStats, counts, NULL, NULL, 0)) { 353 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 354 return NULL; 355 } 356 if (!psVectorStats (resStats, resid, NULL, NULL, 0)) { 357 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 358 return NULL; 359 } 354 360 355 361 // XXX temporary hard-wired minimum stdev improvement factor 356 362 psTrace("psModules.detrend", 3, "raw scatter %f vs res scatter %f\n", rawStats->sampleStdev, resStats->sampleStdev); 357 363 if (rawStats->sampleStdev / resStats->sampleStdev < 1.5) corr->valid = false; 364 if (isnan(rawStats->sampleStdev) || isnan(resStats->sampleStdev)) corr->valid = false; 358 365 359 366 psFree (rawStats); -
branches/pap/psModules/src/detrend/pmSkySubtract.c
r21183 r25027 410 410 // XXX: How do we know if these matrix operations were successful? 411 411 // 412 Aout = psMatrixLUD (Aout, &outPerm, A);412 Aout = psMatrixLUDecomposition(Aout, &outPerm, A); 413 413 PS_ASSERT_IMAGE_NON_NULL(Aout, NULL); 414 414 PS_ASSERT_IMAGE_NON_EMPTY(Aout, NULL); 415 415 psVector *C = psVectorAlloc(localPolyTerms, PS_TYPE_F64); 416 psMatrixLUSol ve(C, Aout, B, outPerm);416 psMatrixLUSolution(C, Aout, B, outPerm); 417 417 418 418 // -
branches/pap/psModules/src/extras/Makefile.am
r21422 r25027 8 8 psIOBuffer.c \ 9 9 pmKapaPlots.c \ 10 pmVisual.c 10 pmVisual.c \ 11 ippStages.c 11 12 12 13 pkginclude_HEADERS = \ … … 15 16 psIOBuffer.h \ 16 17 pmKapaPlots.h \ 17 pmVisual.h 18 pmVisual.h \ 19 ippStages.h 18 20 19 21 CLEANFILES = *~ -
branches/pap/psModules/src/extras/pmVisual.c
r23242 r25027 281 281 psStats *statsX = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 282 282 psStats *statsY = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 283 psVectorStats (statsX, xVec, NULL, NULL, 0); 284 psVectorStats (statsY, yVec, NULL, NULL, 0); 283 if (!psVectorStats (statsX, xVec, NULL, NULL, 0)) { 284 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 285 return false; 286 } 287 if (!psVectorStats (statsY, yVec, NULL, NULL, 0)) { 288 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 289 return false; 290 } 285 291 286 292 float xhi = statsX->sampleMedian + 3 *statsX->sampleStdev; -
branches/pap/psModules/src/imcombine/pmImageCombine.c
r21183 r25027 132 132 // Combine all the pixels, using the specified stat. 133 133 if (!psVectorStats(stats, pixelData, pixelErrors, pixelMasks, 0xff)) { 134 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 135 return false; 136 } 137 if (isnan(stats->sampleMean)) { 134 138 combine->data.F32[y][x] = NAN; 135 139 psFree(buffer); … … 137 141 } 138 142 float combinedPixel = stats->sampleMean; // Value of the combination 139 143 140 144 if (iter == 0) { 141 145 // Save the value produced with no rejection, since it may be useful later … … 364 368 // Get the median 365 369 psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN); 366 psVectorStats(stats, pixels, NULL, mask, 1); 370 if (!psVectorStats(stats, pixels, NULL, mask, 1)) { 371 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 372 } 367 373 float median = stats->sampleMedian; 368 374 psFree(stats); -
branches/pap/psModules/src/imcombine/pmPSFEnvelope.c
r23242 r25027 33 33 34 34 35 // #define TESTING // Enable test output35 // #define TESTING // Enable test output 36 36 #define PEAK_FLUX 1.0e4 // Peak flux for each source 37 37 #define SKY_VALUE 0.0e0 // Sky value for fake image … … 40 40 #define PSF_STATS PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV // Statistics options for measuring PSF 41 41 #define SOURCE_FIT_ITERATIONS 100 // Number of iterations for source fitting 42 #define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \ 43 PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models 42 44 43 45 … … 112 114 psImageInit(envelope, SKY_VALUE); 113 115 pmReadout *fakeRO = pmReadoutAlloc(NULL); // Fake readout 114 float maxRadius = 0.0; // Maximum radius of sources 116 float maxRadius = 0.0; // Maximum radius for sources 117 psVector *numbers = psVectorAlloc(numFakes, PS_TYPE_S32); // Number of detections for each source 118 psVectorInit(numbers, 0); 115 119 for (int i = 0; i < inputs->n; i++) { 116 120 pmPSF *psf = inputs->data[i]; // PSF of interest … … 127 131 psFree(xOffset); 128 132 psFree(fakes); 133 psFree(numbers); 129 134 psf->residuals = resid; 130 135 return NULL; … … 140 145 141 146 double flux = fakeRO->image->data.F32[(int)y][(int)x]; 147 if (!isfinite(flux) || flux < 0) { 148 continue; 149 } 142 150 float norm = PEAK_FLUX / flux; // Normalisation for source 143 151 psRegion region = psRegionSet(x - radius, x + radius, y - radius, y + radius); // PSF region … … 151 159 // Get the radius 152 160 pmModel *model = pmModelFromPSFforXY(psf, x, y, PEAK_FLUX); // Model for source 153 psAssert (model, "failed to generate model: should this be an error or not?"); 161 if (!model || (model->flags & MODEL_MASK)) { 162 continue; 163 } 154 164 float srcRadius = model->modelRadius(model->params, PS_SQR(VARIANCE_VAL)); // Radius for source 165 if (srcRadius == 0) { 166 continue; 167 } 155 168 if (srcRadius > maxRadius) { 156 169 maxRadius = srcRadius; 157 170 } 158 psFree(model); 171 172 // If we got this far, the source is decent 173 numbers->data.S32[j]++; 159 174 } 160 175 … … 175 190 psFree(fakeRO); 176 191 177 if (maxRadius > radius) {178 maxRadius = radius;179 }180 181 192 #ifdef TESTING 182 193 { … … 190 201 191 202 // Put the fake sources onto a full-size image 203 psArray *goodFakes = psArrayAllocEmpty(numFakes); // Good fake sources 192 204 pmReadout *readout = pmReadoutAlloc(NULL); // Readout to contain envelope pixels 193 205 readout->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); … … 195 207 for (int i = 0; i < numFakes; i++) { 196 208 pmSource *source = fakes->data[i]; // Fake source 209 if (numbers->data.S32[i] > 0) { 210 psArrayAdd(goodFakes, goodFakes->n, source); 211 } 212 197 213 // Position of source on fake image 198 214 int xFake = source->peak->x + xOffset->data.S32[i]; … … 213 229 psFree(yOffset); 214 230 psFree(fakes); 231 psFree(numbers); 215 232 return NULL; 216 233 } … … 220 237 psFree(yOffset); 221 238 psFree(envelope); 239 psFree(numbers); 240 241 psFree(fakes); 242 fakes = goodFakes; 243 numFakes = fakes->n; 244 245 if (numFakes == 0.0) { 246 psError(PS_ERR_UNKNOWN, false, "No fake sources are suitable for PSF fitting."); 247 psFree(fakes); 248 psFree(readout); 249 return false; 250 } 222 251 223 252 // XXX Setting the variance seems to be an art … … 232 261 psImageInit(readout->mask, 0); 233 262 263 if (maxRadius > radius) { 264 maxRadius = radius; 265 } 266 234 267 #ifdef TESTING 235 268 { … … 243 276 244 277 // Reset the sources to point to the new pixels, and measure the moments in preparation for PSF fitting 278 int numMoments = 0; // Number of moments measured 245 279 for (int i = 0; i < numFakes; i++) { 246 280 pmSource *source = fakes->data[i]; // Fake source … … 257 291 source->maskObj = NULL; 258 292 259 if (!pmSourceDefinePixels(source, readout, x, y, maxRadius)) {293 if (!pmSourceDefinePixels(source, readout, x, y, radius)) { 260 294 psError(PS_ERR_UNKNOWN, false, "Unable to define pixels for source."); 261 295 psFree(readout); … … 264 298 } 265 299 266 if (!pmSourceMoments(source, maxRadius)) { 267 psError(PS_ERR_UNKNOWN, false, "Unable to measure moments for source."); 268 psFree(readout); 269 psFree(fakes); 270 return NULL; 271 } 300 // measure the source moments: tophat windowing, no pixel S/N cutoff 301 if (!pmSourceMoments(source, maxRadius, 0.0, 1.0)) { 302 // Can't do anything about it; limp along as best we can 303 psErrorClear(); 304 continue; 305 } 306 numMoments++; 307 } 308 309 if (numMoments == 0) { 310 psError(PS_ERR_UNKNOWN, true, "Unable to measure moments for sources."); 311 psFree(fakes); 312 psFree(readout); 313 return NULL; 272 314 } 273 315 … … 286 328 options->psfFieldXo = 0; 287 329 options->psfFieldYo = 0; 330 options->chiFluxTrend = false; // All sources have similar flux, so fitting a trend often fails 288 331 289 332 pmSourceFitModelInit(SOURCE_FIT_ITERATIONS, 0.01, VARIANCE_VAL, true); -
branches/pap/psModules/src/imcombine/pmReadoutCombine.c
r21363 r25027 173 173 for (int i = 0; i < inputs->n; i++) { 174 174 pmReadout *readout = inputs->data[i]; // Readout of interest 175 psAssert(readout, "readout was not defined"); 176 if (!readout->process) continue; 175 177 if (!readout->image) { 176 178 psError(PS_ERR_UNEXPECTED_NULL, true, "Image data is missing for image %d.\n", i); … … 271 273 for (int r = 0; r < inputs->n; r++) { 272 274 pmReadout *readout = inputs->data[r]; // Input readout 275 if (!readout->process) continue; 273 276 psTrace("psModules.imcombine", 3, "Iterating input %d: %d --> %d, %d --> %d\n", r, 274 277 minInputCols - readout->col0, maxInputCols - readout->col0, … … 277 280 } 278 281 #endif 282 283 // set up windows for visualization (if selected) 284 pmReadoutCombineVisualInit(); 279 285 280 286 // Dereference output products … … 308 314 for (int r = 0; r < inputs->n; r++) { 309 315 pmReadout *readout = inputs->data[r]; // Input readout 316 if (!readout->process) { 317 maskData[r] = 1; 318 continue; 319 } 310 320 int yIn = i - readout->row0; // y position on input readout 311 321 int xIn = j - readout->col0; // x position on input readout … … 384 394 // Combination 385 395 if (!psVectorStats(stats, pixels, errors, mask, 1)) { 386 // Can't do much about it, but it's not worth worrying about 387 psErrorClear(); 396 psError(PS_ERR_UNKNOWN, false, "error in pixel stats"); 397 return false; 398 } 399 400 outputImage[yOut][xOut] = psStatsGetValue(stats, params->combine); 401 402 if (!isfinite(outputImage[yOut][xOut])) { 403 pmReadoutCombineVisualPixels(pixels, mask, outputImage[yOut][xOut]); 404 } 405 406 if (isnan(outputImage[yOut][xOut])) { 388 407 outputImage[yOut][xOut] = NAN; 389 408 outputMask[yOut][xOut] = params->blank; 409 sigma->data.F32[yOut][xOut] = NAN; 390 410 if (params->variances) { 391 411 outputVariance[yOut][xOut] = NAN; 392 412 } 393 sigma->data.F32[yOut][xOut] = NAN; 394 } else { 395 outputImage[yOut][xOut] = psStatsGetValue(stats, params->combine); 396 outputMask[yOut][xOut] = isfinite(outputImage[yOut][xOut]) ? 0 : params->blank; 397 if (params->variances) { 398 float stdev = psStatsGetValue(stats, combineStdev); 399 outputVariance[yOut][xOut] = PS_SQR(stdev); // Variance 400 // XXXX this is not the correct formal error. 401 // also, the weighted mean is not obviously the correct thing here 402 } 403 sigma->data.F32[yOut][xOut] = psStatsGetValue(stats, combineStdev); 404 } 413 continue; 414 } 415 outputMask[yOut][xOut] = 0; 416 sigma->data.F32[yOut][xOut] = psStatsGetValue(stats, combineStdev); 417 if (params->variances) { 418 float stdev = psStatsGetValue(stats, combineStdev); 419 outputVariance[yOut][xOut] = PS_SQR(stdev); // Variance 420 // XXXX this is not the correct formal error. 421 // also, the weighted mean is not obviously the correct thing here 422 } 405 423 } 406 424 } … … 423 441 } 424 442 443 #if (HAVE_KAPA) 444 #include <kapa.h> 445 #include "pmKapaPlots.h" 446 #include "pmVisual.h" 447 448 static int kapa = -1; 449 static bool plotFlag = true; 450 451 // this init function only gets the ordinates for the first readout... 452 bool pmReadoutCombineVisualInit(void) { 453 454 if (!pmVisualIsVisual()) return true; 455 456 // skip if we have already opened the windows (or if none are requested...) 457 if (kapa != -1) return true; 458 459 pmVisualInitWindow(&kapa, "ppmerge"); 460 return true; 461 } 462 463 bool pmReadoutCombineVisualPixels(psVector *pixels, psVector *mask, float mean) { 464 465 Graphdata graphdata; 466 float xline[2], yline[2]; 467 468 if (!pmVisualIsVisual()) return true; 469 470 if (!plotFlag) return true; 471 472 KapaInitGraph(&graphdata); 473 474 psVector *xAll = psVectorAlloc(pixels->n, PS_TYPE_F32); 475 psVector *xSub = psVectorAlloc(pixels->n, PS_TYPE_F32); 476 psVector *ySub = psVectorAlloc(pixels->n, PS_TYPE_F32); 477 478 // generate vectors of the unmasked values 479 int nSub = 0; 480 for (int j = 0; j < pixels->n; j++) { 481 xAll->data.F32[j] = j; 482 if (mask && mask->data.PS_TYPE_VECTOR_MASK_DATA[j]) continue; 483 xSub->data.F32[nSub] = j; 484 ySub->data.F32[nSub] = pixels->data.F32[j]; 485 nSub ++; 486 } 487 xSub->n = ySub->n = nSub; 488 xAll->n = pixels->n; 489 490 xline[0] = 0; 491 xline[1] = pixels->n; 492 yline[0] = mean; 493 yline[1] = mean; 494 495 // plot the unmasked values 496 pmVisualScaleGraphdata (&graphdata, xAll, pixels, false); 497 KapaSetGraphData(kapa, &graphdata); 498 KapaSetLimits(kapa, &graphdata); 499 KapaClearPlots (kapa); 500 501 KapaSetFont (kapa, "courier", 14); 502 KapaBox (kapa, &graphdata); 503 KapaSendLabel (kapa, "ordinate", KAPA_LABEL_XM); 504 KapaSendLabel (kapa, "pixel values", KAPA_LABEL_YM); 505 506 graphdata.color = KapaColorByName("black"); 507 graphdata.style = 2; 508 graphdata.ptype = 2; 509 KapaPrepPlot (kapa, xSub->n, &graphdata); 510 KapaPlotVector(kapa, xSub->n, xSub->data.F32, "x"); 511 KapaPlotVector(kapa, xSub->n, ySub->data.F32, "y"); 512 513 graphdata.color = KapaColorByName("red"); 514 graphdata.style = 2; 515 graphdata.ptype = 7; 516 KapaPrepPlot (kapa, xAll->n, &graphdata); 517 KapaPlotVector(kapa, xAll->n, xAll->data.F32, "x"); 518 KapaPlotVector(kapa, xAll->n, pixels->data.F32, "y"); 519 520 graphdata.color = KapaColorByName("blue"); 521 graphdata.style = 0; 522 graphdata.ptype = 7; 523 KapaPrepPlot (kapa, 2, &graphdata); 524 KapaPlotVector(kapa, 2, xline, "x"); 525 KapaPlotVector(kapa, 2, yline, "y"); 526 527 pmVisualAskUser (&plotFlag); 528 return true; 529 } 530 531 bool pmReadoutCombineVisualCleanup(void) { 532 533 if (!pmVisualIsVisual()) return true; 534 if (kapa == -1) return true; 535 536 KapaClose(kapa); 537 return true; 538 } 539 540 # else 541 542 bool pmReadoutCombineVisualInit(void) { return true; } 543 bool pmReadoutCombineVisualPixels(psVector *pixels, psVector *mask, float mean) { return true; } 544 bool pmReadoutCombineVisualCleanup(void) { return true; } 545 546 # endif -
branches/pap/psModules/src/imcombine/pmReadoutCombine.h
r21363 r25027 47 47 ); 48 48 49 bool pmReadoutCombineVisualInit(void); 50 bool pmReadoutCombineVisualPixels(psVector *pixels, psVector *mask, float mean); 51 bool pmReadoutCombineVisualCleanup(void); 52 49 53 /// @} 50 54 #endif -
branches/pap/psModules/src/imcombine/pmSubtraction.c
r23839 r25027 196 196 { 197 197 psKernel *convolved = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Convolved image 198 int numBytes = (2 * footprint + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_F32); // Number of bytes to copy199 198 for (int y = -footprint; y <= footprint; y++) { 200 // Convolution with a delta function is just the value specified by the offset 201 memcpy(&convolved->kernel[y][-footprint], &image->kernel[y - v][-footprint - u], numBytes); 199 for (int x = -footprint; x <= footprint; x++) { 200 convolved->kernel[y][x] = image->kernel[y - v][x - u]; 201 } 202 202 } 203 203 return convolved; 204 204 } 205 205 206 // Take a subset of an image207 static inline psImage *convolveSubsetAlloc(psImage *image, // Image to be convolved208 psRegion region, // Region of interest (with border)209 bool threaded // Are we running threaded?210 )211 {212 if (!image) {213 return NULL;214 }215 // XXX if (threaded) {216 // XXX psMutexLock(image);217 // XXX }218 psImage *subset = psImageSubset(image, region); // Subset image, to return219 // XXX if (threaded) {220 // XXX psMutexUnlock(image);221 // XXX }222 return subset;223 }224 225 // Free the subset of an image226 static inline void convolveSubsetFree(psImage *parent, // Parent image227 psImage *child, // Child (subset) image228 bool threaded // Are we running threaded?229 )230 {231 if (!child || !parent) {232 return;233 }234 // XXX if (threaded) {235 // XXX psMutexLock(parent);236 // XXX }237 psFree(child);238 // XXX if (threaded) {239 // XXX psMutexUnlock(parent);240 // XXX }241 return;242 }243 206 244 207 // Convolve an image using FFT … … 256 219 region.y0 - size, region.y1 + size); // Add a border 257 220 258 bool threaded = pmSubtractionThreaded(); // Are we running threaded? 259 260 psImage *subImage = convolveSubsetAlloc(image, border, threaded); // Subimage to convolve 261 psImage *subMask = convolveSubsetAlloc(mask, border, threaded); // Subimage mask 221 psImage *subImage = image ? psImageSubset(image, border) : NULL; // Subimage to convolve 222 psImage *subMask = mask ? psImageSubset(mask, border) : NULL; // Subimage mask 262 223 263 224 psImage *convolved = psImageConvolveFFT(NULL, subImage, subMask, maskVal, kernel); // Convolution 264 225 265 convolveSubsetFree(image, subImage, threaded);266 convolveSubsetFree(mask, subMask, threaded);226 psFree(subImage); 227 psFree(subMask); 267 228 268 229 // Now, we have to stick it in where it belongs … … 300 261 region.y0 - size, region.y1 + size); // Add a border 301 262 302 bool threaded = pmSubtractionThreaded(); // Are we running threaded? 303 304 psImage *subVariance = convolveSubsetAlloc(variance, border, threaded); // Variance map 305 psImage *subSys = convolveSubsetAlloc(sys, border, threaded); // Systematic error image 306 psImage *subMask = convolveSubsetAlloc(mask, border, threaded); // Mask 263 psImage *subVariance = variance ? psImageSubset(variance, border) : NULL; // Variance map 264 psImage *subSys = sys ? psImageSubset(sys, border) : NULL; // Systematic error image 265 psImage *subMask = mask ? psImageSubset(mask, border) : NULL; // Mask 307 266 308 267 // XXX Can trim this a little by combining the convolution: only have to take the FFT of the kernel once … … 310 269 psImage *convSys = subSys ? psImageConvolveFFT(NULL, subSys, subMask, maskVal, kernel) : NULL; // Conv sys 311 270 312 convolveSubsetFree(variance, subVariance, threaded);313 convolveSubsetFree(sys, subSys, threaded);314 convolveSubsetFree(mask, subMask, threaded);271 psFree(subVariance); 272 psFree(subSys); 273 psFree(subMask); 315 274 316 275 // Now, we have to stick it in where it belongs … … 420 379 if (box > 0) { 421 380 int colMin = region.x0, colMax = region.x1, rowMin = region.y0, rowMax = region.y1; // Bounds 422 bool threaded = pmSubtractionThreaded(); // Are we running threaded?423 424 381 psRegion region = psRegionSet(colMin - box, colMax + box, 425 382 rowMin - box, rowMax + box); // Region to convolve 426 383 427 psImage *image = convolveSubsetAlloc(subMask, region, threaded); // Mask to convolve384 psImage *image = subMask ? psImageSubset(subMask, region) : NULL; // Mask to convolve 428 385 429 386 psImage *convolved = psImageConvolveMask(NULL, image, subBad, subConvBad, 430 387 -box, box, -box, box); // Convolved subtraction mask 431 388 432 convolveSubsetFree(subMask, image, threaded);389 psFree(image); 433 390 434 391 psAssert(convolved->numCols - 2 * box == colMax - colMin, "Bad number of columns"); … … 653 610 float value = 0.0; // Value of convolved pixel 654 611 int uMin = x - size, uMax = x + size; // Range for u 655 psF32 *xKernelData = xKernel->data.F32; // Kernel values612 psF32 *xKernelData = &xKernel->data.F32[xKernel->n - 1]; // Kernel values 656 613 psF32 *imageData = &image->kernel[y][uMin]; // Image values 657 for (int u = uMin; u <= uMax; u++, xKernelData ++, imageData++) {614 for (int u = uMin; u <= uMax; u++, xKernelData--, imageData++) { 658 615 value += *xKernelData * *imageData; 659 616 } … … 668 625 float value = 0.0; // Value of convolved pixel 669 626 int vMin = y - size, vMax = y + size; // Range for v 670 psF32 *yKernelData = yKernel->data.F32; // Kernel values627 psF32 *yKernelData = &yKernel->data.F32[yKernel->n - 1]; // Kernel values 671 628 psF32 *imageData = &temp->kernel[x][vMin]; // Image values; NOTE: wrong way! 672 for (int v = vMin; v <= vMax; v++, yKernelData ++, imageData++) {629 for (int v = vMin; v <= vMax; v++, yKernelData--, imageData++) { 673 630 value += *yKernelData * *imageData; 674 631 } … … 821 778 } 822 779 psFree(mask); 780 781 // XXX raise an error? 782 if (isnan(stats->sampleMean)) { 783 psFree(stats); 784 return -1; 785 } 823 786 824 787 double mean, rms; // Mean and RMS of deviations -
branches/pap/psModules/src/imcombine/pmSubtractionEquation.c
r23839 r25027 15 15 #include "pmSubtractionVisual.h" 16 16 17 //#define TESTING 17 // #define TESTING // TESTING output for debugging; may not work with threads! 18 19 #define USE_VARIANCE // Include variance in equation? 18 20 19 21 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// … … 31 33 for (int y = - footprint; y <= footprint; y++) { 32 34 for (int x = - footprint; x <= footprint; x++) { 33 sum += image1->kernel[y][x] * image2->kernel[y][x] / 1.0; // variance->kernel[y][x]; 35 double value = image1->kernel[y][x] * image2->kernel[y][x]; 36 #ifdef USE_VARIANCE 37 value /= variance->kernel[y][x]; 38 #endif 39 sum += value; 34 40 } 35 41 } … … 195 201 for (int y = - footprint; y <= footprint; y++) { 196 202 for (int x = - footprint; x <= footprint; x++) { 197 sumC += conv->kernel[y][x] / 1.0; // variance->kernel[y][x]; 203 double value = conv->kernel[y][x]; 204 #ifdef USE_VARIANCE 205 value /= variance->kernel[y][x]; 206 #endif 207 sumC += value; 198 208 } 199 209 } … … 218 228 for (int y = - footprint; y <= footprint; y++) { 219 229 for (int x = - footprint; x <= footprint; x++) { 220 double invNoise2 = 1.0 / 1.0; // variance->kernel[y][x]; 230 double invNoise2 = 1.0; 231 #ifdef USE_VARIANCE 232 invNoise2 /= variance->kernel[y][x]; 233 #endif 221 234 double value = input->kernel[y][x] * invNoise2; 222 235 sumI += value; … … 277 290 for (int y = - footprint; y <= footprint; y++) { 278 291 for (int x = - footprint; x <= footprint; x++) { 279 sumTC += target->kernel[y][x] * conv->kernel[y][x] / 1.0; // variance->kernel[y][x]; 292 double value = target->kernel[y][x] * conv->kernel[y][x]; 293 #ifdef USE_VARIANCE 294 value /= variance->kernel[y][x]; 295 #endif 296 sumTC += value; 280 297 } 281 298 } … … 297 314 for (int y = - footprint; y <= footprint; y++) { 298 315 for (int x = - footprint; x <= footprint; x++) { 299 float value = target->kernel[y][x] / 1.0; // variance->kernel[y][x]; 316 double value = target->kernel[y][x]; 317 #ifdef USE_VARIANCE 318 value /= variance->kernel[y][x]; 319 #endif 300 320 sumIT += value * input->kernel[y][x]; 301 321 sumT += value; … … 366 386 for (int y = - footprint; y <= footprint; y++) { 367 387 for (int x = - footprint; x <= footprint; x++) { 368 sumC += conv->kernel[y][x] / 1.0; // variance->kernel[y][x]; 388 double value = conv->kernel[y][x]; 389 #ifdef USE_VARIANCE 390 value /= variance->kernel[y][x]; 391 #endif 392 sumC += value; 369 393 } 370 394 } … … 765 789 for (int i = 0; i < stamps->num; i++) { 766 790 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest 791 767 792 if (stamp->status == PM_SUBTRACTION_STAMP_USED) { 793 794 #ifdef TESTING 795 // XXX double-check for NAN in data: 796 for (int iy = 0; iy < stamp->matrix1->numRows; iy++) { 797 for (int ix = 0; ix < stamp->matrix1->numCols; ix++) { 798 if (!isfinite(stamp->matrix1->data.F64[iy][ix])) { 799 fprintf (stderr, "WARNING: NAN in matrix1\n"); 800 } 801 } 802 } 803 for (int ix = 0; ix < stamp->vector1->n; ix++) { 804 if (!isfinite(stamp->vector1->data.F64[ix])) { 805 fprintf (stderr, "WARNING: NAN in vector1\n"); 806 } 807 } 808 #endif 809 768 810 (void)psBinaryOp(sumMatrix, sumMatrix, "+", stamp->matrix1); 769 811 (void)psBinaryOp(sumVector, sumVector, "+", stamp->vector1); … … 774 816 } 775 817 } 818 819 #ifdef TESTING 820 for (int ix = 0; ix < sumVector->n; ix++) { 821 if (!isfinite(sumVector->data.F64[ix])) { 822 fprintf (stderr, "WARNING: NAN in vector1\n"); 823 } 824 } 825 #endif 826 776 827 calculatePenalty(sumVector, kernels); 777 828 778 829 #ifdef TESTING 830 for (int ix = 0; ix < sumVector->n; ix++) { 831 if (!isfinite(sumVector->data.F64[ix])) { 832 fprintf (stderr, "WARNING: NAN in vector1\n"); 833 } 834 } 779 835 { 780 836 psImage *inverse = psMatrixInvert(NULL, sumMatrix, NULL); … … 798 854 799 855 psVector *permutation = NULL; // Permutation vector, required for LU decomposition 800 psImage *luMatrix = psMatrixLUD (NULL, &permutation, sumMatrix);856 psImage *luMatrix = psMatrixLUDecomposition(NULL, &permutation, sumMatrix); 801 857 psFree(sumMatrix); 802 858 if (!luMatrix) { … … 807 863 return NULL; 808 864 } 809 kernels->solution1 = psMatrixLUSolve(kernels->solution1, luMatrix, sumVector, permutation); 865 kernels->solution1 = psMatrixLUSolution(kernels->solution1, luMatrix, sumVector, permutation); 866 867 #ifdef TESTING 868 // XXX double-check for NAN in data: 869 for (int ix = 0; ix < kernels->solution1->n; ix++) { 870 if (!isfinite(kernels->solution1->data.F64[ix])) { 871 fprintf (stderr, "WARNING: NAN in vector1\n"); 872 } 873 } 874 #endif 810 875 811 876 psFree(sumVector); … … 1062 1127 source = stamp->image1; 1063 1128 convolutions = stamp->convolutions1; 1129 1130 // Having convolved image1 and changed its normalisation, we need to renormalise the residual 1131 // so that it is on the scale of image1. 1132 psImage *image = pmSubtractionKernelImage(kernels, stamp->xNorm, stamp->yNorm, 1133 false); // Kernel image 1134 if (!image) { 1135 psError(PS_ERR_UNKNOWN, false, "Unable to generate image of kernel."); 1136 return false; 1137 } 1138 double sumKernel = 0; // Sum of kernel, for normalising residual 1139 int size = kernels->size; // Half-size of kernel 1140 int fullSize = 2 * size + 1; // Full size of kernel 1141 for (int y = 0; y < fullSize; y++) { 1142 for (int x = 0; x < fullSize; x++) { 1143 sumKernel += image->data.F32[y][x]; 1144 } 1145 } 1146 psFree(image); 1147 devNorm = 1.0 / sumKernel / numPixels; 1064 1148 break; 1065 1149 case PM_SUBTRACTION_MODE_2: -
branches/pap/psModules/src/imcombine/pmSubtractionKernels.c
r20421 r25027 145 145 146 146 // Calculate moments 147 double sum = 0.0; // Sum of kernel component, for normalisation148 147 double moment = 0.0; // Moment, for penalty 149 148 for (int v = -size, y = 0; v <= size; v++, y++) { 150 149 for (int u = -size, x = 0; u <= size; u++, x++) { 151 150 double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel 152 sum += value;153 151 moment += value * (PS_SQR(u) + PS_SQR(v)); 154 152 } … … 163 161 } 164 162 } 165 sum = 1.0 / s um;163 sum = 1.0 / sqrt(sum); 166 164 psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 167 165 psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32)); 168 moment *= sum;166 moment *= PS_SQR(sum); 169 167 } 170 168 -
branches/pap/psModules/src/imcombine/pmSubtractionMask.c
r23851 r25027 6 6 #include <pslib.h> 7 7 8 #include "pmErrorCodes.h" 8 9 #include "pmSubtraction.h" 9 10 #include "pmSubtractionKernels.h" … … 78 79 } 79 80 if (numBad > badFrac * numCols * numRows) { 80 psError(P S_ERR_BAD_PARAMETER_VALUE, true,81 psError(PM_ERR_SMALL_AREA, true, 81 82 "Fraction of bad pixels (%d/%d=%f) exceeds limit (%f)\n", 82 83 numBad, numCols * numRows, (float)numBad/(float)(numCols * numRows), badFrac); -
branches/pap/psModules/src/imcombine/pmSubtractionMatch.c
r23944 r25027 246 246 badFrac, mode); // Subtraction mask 247 247 if (!subMask) { 248 psError( PS_ERR_UNKNOWN, false, "Unable to generate subtraction mask.");248 psError(psErrorCodeLast(), false, "Unable to generate subtraction mask."); 249 249 psFree(kernels); 250 250 psFree(regions); … … 337 337 PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(optThreshold, 1.0, false); 338 338 } 339 PS_ASSERT_INT_ POSITIVE(iter, false);339 PS_ASSERT_INT_NONNEGATIVE(iter, false); 340 340 PS_ASSERT_FLOAT_LARGER_THAN(rej, 0.0, false); 341 341 … … 379 379 badFrac, subMode); 380 380 if (!subMask) { 381 psError( PS_ERR_UNKNOWN, false, "Unable to generate subtraction mask.");381 psError(psErrorCodeLast(), false, "Unable to generate subtraction mask."); 382 382 goto MATCH_ERROR; 383 383 } … … 432 432 } 433 433 434 if (sources) { 434 if (stampsName && strlen(stampsName) > 0) { 435 stamps = pmSubtractionStampsSetFromFile(stampsName, ro1->image, subMask, region, size, 436 footprint, stampSpacing, subMode); 437 } else if (sources) { 435 438 stamps = pmSubtractionStampsSetFromSources(sources, ro1->image, subMask, region, size, 436 439 footprint, stampSpacing, subMode); 437 } else if (stampsName && strlen(stampsName) > 0) {438 stamps = pmSubtractionStampsSetFromFile(stampsName, ro1->image, subMask, region, size,439 footprint, stampSpacing, subMode);440 440 } 441 441 … … 830 830 psFree(mask); 831 831 832 // XXX raise an error here or not? 833 if (isnan(stats->robustMedian)) { 834 psFree(stats); 835 return PM_SUBTRACTION_MODE_ERR; 836 } 837 832 838 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Median width ratio: %lf", stats->robustMedian); 833 839 pmSubtractionMode mode = (stats->robustMedian <= 1.0 ? PM_SUBTRACTION_MODE_1 : PM_SUBTRACTION_MODE_2); 834 840 psFree(stats); 835 841 836 // XXX EAM : I think Paul left some test code in here. I've commented these lines out837 // return PM_SUBTRACTION_MODE_2;838 // exit(1);839 840 842 return mode; 841 843 } -
branches/pap/psModules/src/imcombine/pmSubtractionStamps.c
r23937 r25027 78 78 } 79 79 80 // Is this position unmasked? 81 static bool checkStampMask(int x, int y, // Coordinates of stamp 82 int numCols, int numRows, // Size of image 83 const psImage *mask, // Mask 84 pmSubtractionMode mode, // Mode for subtraction 85 int footprint, // Size of stamp 86 int border // Size of border 87 ) 88 { 89 // Check the footprint bounds 90 if (x < border || x >= numCols - border || y < border || y >= numRows - border) { 91 return false; 92 } 93 94 if (!mask) { 95 return true; 96 } 97 98 // Check the central pixel 99 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & (PM_SUBTRACTION_MASK_BORDER | PM_SUBTRACTION_MASK_REJ)) { 100 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= PM_SUBTRACTION_MASK_REJ; 101 return false; 102 } 103 104 return true; 80 81 // Search a region for a suitable stamp 82 bool stampSearch(int *xStamp, int *yStamp, // Coordinates of stamp, to return 83 float *fluxStamp, // Flux of stamp, to return 84 const psImage *image1, const psImage *image2, // Images to search 85 float thresh1, float thresh2, // Thresholds for images 86 const psImage *subMask, // Subtraction mask 87 int xMin, int xMax, int yMin, int yMax, // Bounds of search 88 int numCols, int numRows, // Size of images 89 int border // Border around image 90 ) 91 { 92 bool found = false; // Found a suitable stamp? 93 *fluxStamp = -INFINITY; // Flux of best stamp 94 95 // Ensure we're not going to go outside the bounds of the image 96 xMin = PS_MAX(border, xMin); 97 xMax = PS_MIN(numCols - border - 1, xMax); 98 yMin = PS_MAX(border, yMin); 99 yMax = PS_MIN(numRows - border - 1, yMax); 100 101 for (int y = yMin; y <= yMax; y++) { 102 for (int x = xMin; x <= xMax; x++) { 103 if ((image1 && image1->data.F32[y][x] < thresh1) || 104 (image2 && image2->data.F32[y][x] < thresh2)) { 105 continue; 106 } 107 108 if (subMask && subMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 109 (PM_SUBTRACTION_MASK_BORDER | PM_SUBTRACTION_MASK_REJ)) { 110 return false; 111 } 112 113 // We take the MIN to attempt to avoid transients in both images 114 float flux = (image1 && image2) ? PS_MIN(image1->data.F32[y][x], image2->data.F32[y][x]) : 115 ((image1) ? image1->data.F32[y][x] : image2->data.F32[y][x]); // Flux at pixel 116 if (flux > *fluxStamp) { 117 *xStamp = x; 118 *yStamp = y; 119 *fluxStamp = flux; 120 found = true; 121 } 122 } 123 } 124 125 return found; 105 126 } 106 127 … … 314 335 numSearch++; 315 336 316 float xStamp = 0, yStamp = 0;// Coordinates of stamp317 float fluxStamp = NAN;// Flux of stamp318 bool goodStamp = false; // Found a good stamp?337 int xStamp = 0, yStamp = 0; // Coordinates of stamp 338 float fluxStamp = -INFINITY; // Flux of stamp 339 bool goodStamp = false; // Found a good stamp? 319 340 320 341 // A couple different ways of finding stamps: … … 324 345 psVector *fluxList = stamps->flux->data[i]; // List of stamp fluxes 325 346 326 // Take stamp off the top of the (sorted) list 327 if (xList->n > 0) { 328 int index = xList->n - 1; // Index of new stamp 329 xStamp = xList->data.F32[index]; 330 yStamp = yList->data.F32[index]; 331 fluxStamp = fluxList->data.F32[index]; 347 // Take stamps off the top of the (sorted) list 348 for (int j = xList->n - 1; j >= 0 && !goodStamp; j--) { 349 int xCentre = xList->data.F32[j] + 0.5, yCentre = yList->data.F32[j] + 0.5;// Stamp centre 332 350 333 351 // Chop off the top of the list 334 xList->n = index; 335 yList->n = index; 336 fluxList->n = index; 337 338 goodStamp = true; 339 int x = xStamp + 0.5, y = yStamp + 0.5; // Pixel location 340 if (image1 && image1->data.F32[y][x] < thresh1) { 341 goodStamp = false; 342 } else if (image2 && image2->data.F32[y][x] < thresh2) { 343 goodStamp = false; 344 } 345 } else { 346 psTrace("psModules.imcombine", 9, "No sources in subregion %d", i); 352 xList->n = j; 353 yList->n = j; 354 fluxList->n = j; 355 356 // Fish around a bit to see if we can find a pixel that isn't masked 357 psTrace("psModules.imcombine", 7, "Searching for stamp %d around %d,%d\n", 358 i, xCentre, yCentre); 359 360 // Search bounds 361 int search = footprint - size; // Search radius 362 int xMin = PS_MAX(border, xCentre - search); 363 int xMax = PS_MIN(numCols - border -1, xCentre + search); 364 int yMin = PS_MAX(border, yCentre - search); 365 int yMax = PS_MIN(numRows - border - 1, yCentre + search); 366 367 goodStamp = stampSearch(&xStamp, &yStamp, &fluxStamp, image1, image2, thresh1, thresh2, 368 subMask, xMin, xMax, yMin, yMax, numCols, numRows, border); 347 369 } 348 370 } else { 349 371 // Use a simple method of automatically finding stamps --- take the highest pixel in the 350 372 // subregion 351 fluxStamp = 0.0;352 373 psRegion *subRegion = stamps->regions->data[i]; // Sub-region of interest 353 374 354 const psImage *image = NULL; // Image for flux of stamp 355 switch (mode) { 356 case PM_SUBTRACTION_MODE_1: 357 image = image2 ? image2 : image1; 358 break; 359 case PM_SUBTRACTION_MODE_2: 360 image = image1 ? image1 : image2; 361 break; 362 case PM_SUBTRACTION_MODE_UNSURE: 363 case PM_SUBTRACTION_MODE_DUAL: 364 // If both are available, we'll take the MIN value below in the hope of rejecting 365 // transients in both 366 image = (image1 && image2) ? NULL : (image1 ? image1 : image2); 367 default: 368 psAbort("Unrecognised mode: %x", mode); 369 } 370 371 for (int y = subRegion->y0; y <= subRegion->y1; y++) { 372 for (int x = subRegion->x0; x <= subRegion->x1; x++) { 373 if ((image1 && image1->data.F32[y][x] < thresh1) || 374 (image2 && image2->data.F32[y][x] < thresh2)) { 375 continue; 376 } 377 float value = image ? image->data.F32[y][x] : 378 PS_MIN(image1->data.F32[y][x], image2->data.F32[y][x]); // Value of image 379 if (value > fluxStamp && 380 checkStampMask(x, y, numCols, numRows, subMask, mode, footprint, border)) { 381 fluxStamp = image->data.F32[y][x]; 382 xStamp = x; 383 yStamp = y; 384 goodStamp = true; 385 } 386 } 387 } 375 goodStamp = stampSearch(&xStamp, &yStamp, &fluxStamp, image1, image2, thresh1, thresh2, 376 subMask, subRegion->x0, subRegion->x1, subRegion->y0, subRegion->y1, 377 numCols, numRows, border); 388 378 } 389 379 … … 453 443 region, footprint, spacing); // Stamp list 454 444 int numStamps = stamps->num; // Number of stamps 455 int numCols = image->numCols, numRows = image->numRows; // Size of image456 int border = footprint + size; // Border size457 445 458 446 psString ds9name = NULL; // Filename for ds9 region file … … 480 468 psTrace("psModules.imcombine", 9, "Rejecting input stamp (%d,%d) because outside region", 481 469 xPix, yPix); 482 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "magenta");483 continue;484 }485 if (!checkStampMask(xPix, yPix, numCols, numRows, subMask, mode, footprint, border)) {486 // Not a good stamp487 psTrace("psModules.imcombine", 9, "Rejecting input stamp (%d,%d) because bad mask",488 xPix, yPix);489 470 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "red"); 490 471 continue; -
branches/pap/psModules/src/objects/Makefile.am
r23184 r25027 10 10 pmFootprintArraysMerge.c \ 11 11 pmFootprintAssignPeaks.c \ 12 pmFootprintCullPeaks.c \ 12 13 pmFootprintFind.c \ 13 14 pmFootprintFindAtPoint.c \ … … 38 39 pmSourceIO_PS1_CAL_0.c \ 39 40 pmSourceIO_CMF_PS1_V1.c \ 41 pmSourceIO_CMF_PS1_V2.c \ 42 pmSourceIO_MatchedRefs.c \ 40 43 pmSourcePlots.c \ 41 44 pmSourcePlotPSFModel.c \ -
branches/pap/psModules/src/objects/models/pmModel_PS1_V1.c
r20001 r25027 159 159 break; 160 160 case PM_PAR_7: 161 params_min = 0.1;161 params_min = -1.0; 162 162 break; 163 163 default: -
branches/pap/psModules/src/objects/models/pmModel_SGAUSS.c
r15834 r25027 325 325 326 326 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 327 psVectorStats (stats, contour, NULL, NULL, 0); 327 if (!psVectorStats (stats, contour, NULL, NULL, 0)) { 328 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 329 return false; 330 } 328 331 value = stats->sampleMedian; 329 332 -
branches/pap/psModules/src/objects/pmFootprint.h
r20945 r25027 51 51 void pmSetFootprintArrayIDsForImage(psImage *idImage, 52 52 const psArray *footprints, // the footprints to insert 53 const bool relativeIDs); // show IDs starting at 0, not pmFootprint->id 53 const bool relativeIDs // show IDs starting at 0, not pmFootprint->id 54 ); 54 55 55 56 psErrorCode pmFootprintsAssignPeaks(psArray *footprints, const psArray *peaks); 56 57 57 psErrorCode pmFootprintArrayCullPeaks(const psImage *img, const psImage *weight, psArray *footprints, 58 const float nsigma, const float threshold_min); 59 psErrorCode pmFootprintCullPeaks(const psImage *img, const psImage *weight, pmFootprint *fp, 60 const float nsigma, const float threshold_min); 58 psErrorCode pmFootprintCullPeaks(const psImage *img, // the image wherein lives the footprint 59 const psImage *weight, // corresponding variance image 60 pmFootprint *fp, // Footprint containing mortal peaks 61 const float nsigma_delta, // how many sigma above local background a peak needs to be to survive 62 const float fPadding, // fractional padding added to stdev since bright peaks have unreasonably high significance 63 const float min_threshold // minimum permitted coll height 64 ); 61 65 62 66 psArray *pmFootprintArrayToPeaks(const psArray *footprints); -
branches/pap/psModules/src/objects/pmFootprintArraysMerge.c
r20937 r25027 28 28 */ 29 29 psArray *pmFootprintArraysMerge(const psArray *footprints1, // one set of footprints 30 const psArray *footprints2, // the other set 31 const int includePeaks) { // which peaks to set? 0x1 => footprints1, 0x2 => 2 32 assert (footprints1->n == 0 || pmFootprintTest(footprints1->data[0])); 33 assert (footprints2->n == 0 || pmFootprintTest(footprints2->data[0])); 30 const psArray *footprints2, // the other set 31 const int includePeaks // which peaks to set? 0x1 => footprints1, 0x2 => 2 32 ) 33 { 34 if (!footprints1 && !footprints2) { 35 // No footprints in merged array 36 return psArrayAllocEmpty(0); 37 } 34 38 35 if (footprints1->n == 0 || footprints2->n == 0) { // nothing to do but put copies on merged36 const psArray *old = (footprints1->n == 0) ? footprints2 : footprints1;39 assert(!footprints1 || footprints1->n == 0 || pmFootprintTest(footprints1->data[0])); 40 assert(!footprints2 || footprints2->n == 0 || pmFootprintTest(footprints2->data[0])); 37 41 38 psArray *merged = psArrayAllocEmpty(old->n); 39 for (int i = 0; i < old->n; i++) { 40 psArrayAdd(merged, 1, old->data[i]); 41 } 42 43 return merged; 42 if (!footprints1 || footprints1->n == 0 || !footprints2 || footprints2->n == 0) { 43 // nothing to do but put copies on merged 44 const psArray *old = (!footprints1 || footprints1->n == 0) ? footprints2 : footprints1; 45 46 psArray *merged = psArrayAllocEmpty(old->n); 47 for (int i = 0; i < old->n; i++) { 48 psArrayAdd(merged, 1, old->data[i]); 49 } 50 51 return merged; 44 52 } 45 53 /* … … 48 56 */ 49 57 { 50 pmFootprint *fp1 = footprints1->data[0];51 pmFootprint *fp2 = footprints2->data[0];52 if (fp1->region.x0 != fp2->region.x0 ||53 fp1->region.x1 != fp2->region.x1 ||54 fp1->region.y0 != fp2->region.y0 ||55 fp1->region.y1 != fp2->region.y1) {56 psError(PS_ERR_BAD_PARAMETER_SIZE, true,57 "The two pmFootprint arrays correspnond to different-sized regions");58 return NULL;59 }58 pmFootprint *fp1 = footprints1->data[0]; 59 pmFootprint *fp2 = footprints2->data[0]; 60 if (fp1->region.x0 != fp2->region.x0 || 61 fp1->region.x1 != fp2->region.x1 || 62 fp1->region.y0 != fp2->region.y0 || 63 fp1->region.y1 != fp2->region.y1) { 64 psError(PS_ERR_BAD_PARAMETER_SIZE, true, 65 "The two pmFootprint arrays correspnond to different-sized regions"); 66 return NULL; 67 } 60 68 } 61 69 /* … … 72 80 * Now assign the peaks appropriately. We could do this more efficiently 73 81 * using idImage (which we just freed), but this is easy and probably fast enough 74 */ 82 */ 75 83 if (includePeaks & 0x1) { 76 psArray *peaks = pmFootprintArrayToPeaks(footprints1);77 pmFootprintsAssignPeaks(merged, peaks);78 psFree(peaks);84 psArray *peaks = pmFootprintArrayToPeaks(footprints1); 85 pmFootprintsAssignPeaks(merged, peaks); 86 psFree(peaks); 79 87 } 80 88 81 89 if (includePeaks & 0x2) { 82 psArray *peaks = pmFootprintArrayToPeaks(footprints2);83 pmFootprintsAssignPeaks(merged, peaks);84 psFree(peaks);90 psArray *peaks = pmFootprintArrayToPeaks(footprints2); 91 pmFootprintsAssignPeaks(merged, peaks); 92 psFree(peaks); 85 93 } 86 94 87 95 return merged; 88 96 } -
branches/pap/psModules/src/objects/pmGrowthCurveGenerate.c
r21183 r25027 89 89 psVectorAppend (values, growth->fitMag); 90 90 } 91 psVectorStats (stats, values, NULL, NULL, 0); 91 if (!psVectorStats (stats, values, NULL, NULL, 0)) { 92 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 93 return false; 94 } 92 95 psf->growth->fitMag = stats->sampleMedian; 93 96 … … 104 107 psVectorAppend (values, growth->apMag->data.F32[i]); 105 108 } 106 psVectorStats (stats, values, NULL, NULL, 0); 109 if (!psVectorStats (stats, values, NULL, NULL, 0)) { 110 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 111 return false; 112 } 107 113 psf->growth->apMag->data.F32[i] = stats->sampleMedian; 108 114 } -
branches/pap/psModules/src/objects/pmMoments.c
r23487 r25027 51 51 tmp->Sky = 0.0; 52 52 tmp->nPixels = 0; 53 tmp->SN = 0; 53 54 54 55 psTrace("psModules.objects", 10, "---- %s() end ----\n", __func__); -
branches/pap/psModules/src/objects/pmPSF.c
r23487 r25027 75 75 options->poissonErrorsParams = true; 76 76 77 options->chiFluxTrend = true; 78 77 79 return options; 78 80 } -
branches/pap/psModules/src/objects/pmPSF.h
r23487 r25027 82 82 bool poissonErrorsParams; ///< use poission errors for model parameter fitting 83 83 float radius; 84 bool chiFluxTrend; // Fit a trend in Chi2 as a function of flux? 84 85 } pmPSFOptions; 85 86 -
branches/pap/psModules/src/objects/pmPSFtry.c
r21183 r25027 43 43 44 44 for (int j = 0; j < trend->map->map->numRows; j++) { 45 for (int i = 0; i < trend->map->map->numCols; i++) {46 fprintf (stderr, "%5.2f ", trend->map->map->data.F32[j][i]);47 }48 fprintf (stderr, "\t\t\t");49 for (int i = 0; i < trend->map->map->numCols; i++) {50 fprintf (stderr, "%5.2f ", trend->map->error->data.F32[j][i]);51 }52 fprintf (stderr, "\n");45 for (int i = 0; i < trend->map->map->numCols; i++) { 46 fprintf (stderr, "%5.2f ", trend->map->map->data.F32[j][i]); 47 } 48 fprintf (stderr, "\t\t\t"); 49 for (int i = 0; i < trend->map->map->numCols; i++) { 50 fprintf (stderr, "%5.2f ", trend->map->error->data.F32[j][i]); 51 } 52 fprintf (stderr, "\n"); 53 53 } 54 54 return true; … … 63 63 float Wt = 0.0; 64 64 for (int j = 0; j < map->map->numRows; j++) { 65 for (int i = 0; i < map->map->numCols; i++) {66 if (!isfinite(map->map->data.F32[j][i])) continue;67 Sum += map->map->data.F32[j][i] * map->error->data.F32[j][i];68 Wt += map->error->data.F32[j][i];69 }65 for (int i = 0; i < map->map->numCols; i++) { 66 if (!isfinite(map->map->data.F32[j][i])) continue; 67 Sum += map->map->data.F32[j][i] * map->error->data.F32[j][i]; 68 Wt += map->error->data.F32[j][i]; 69 } 70 70 } 71 71 … … 75 75 // XXX for now, we are just replacing bad pixels with the Mean 76 76 for (int j = 0; j < map->map->numRows; j++) { 77 for (int i = 0; i < map->map->numCols; i++) {78 if (isfinite(map->map->data.F32[j][i]) && 79 (map->error->data.F32[j][i] > 0.0)) continue;80 map->map->data.F32[j][i] = Mean;81 }77 for (int i = 0; i < map->map->numCols; i++) { 78 if (isfinite(map->map->data.F32[j][i]) && 79 (map->error->data.F32[j][i] > 0.0)) continue; 80 map->map->data.F32[j][i] = Mean; 81 } 82 82 } 83 83 return true; … … 174 174 175 175 pmSource *source = psfTry->sources->data[i]; 176 if (!source->moments) {176 if (!source->moments) { 177 177 psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL; 178 continue;179 }180 if (!source->moments->nPixels) {178 continue; 179 } 180 if (!source->moments->nPixels) { 181 181 psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL; 182 continue;183 }182 continue; 183 } 184 184 185 185 source->modelEXT = pmSourceModelGuess (source, psfTry->psf->type); … … 211 211 212 212 if (Next == 0) { 213 psError(PS_ERR_UNKNOWN, true, "No sources with good extended fits from which to determine PSF.");213 psError(PS_ERR_UNKNOWN, false, "No sources with good extended fits from which to determine PSF."); 214 214 psFree(psfTry); 215 215 return NULL; … … 282 282 283 283 if (Npsf == 0) { 284 psError(PS_ERR_UNKNOWN, true, "No sources with good PSF fits after model is built.");284 psError(PS_ERR_UNKNOWN, false, "No sources with good PSF fits after model is built."); 285 285 psFree(psfTry); 286 286 return NULL; … … 311 311 312 312 // linear clipped fit of chisq trend vs flux 313 bool result = psVectorClipFitPolynomial1D(psfTry->psf->ChiTrend, options->stats, mask, 0xff, chisq, NULL, flux); 314 psStatsOptions meanStat = psStatsMeanOption(options->stats->options); // Statistic for mean 315 psStatsOptions stdevStat = psStatsStdevOption(options->stats->options); // Statistic for stdev 316 317 psLogMsg ("pmPSFtry", 4, "chisq vs flux fit: %f +/- %f\n", 318 psStatsGetValue(stats, meanStat), psStatsGetValue(stats, stdevStat)); 319 320 psFree(flux); 321 psFree(mask); 322 psFree(chisq); 323 324 if (!result) { 325 psError(PS_ERR_UNKNOWN, false, "Failed to fit psf->ChiTrend"); 326 psFree(psfTry); 327 return NULL; 313 if (options->chiFluxTrend) { 314 bool result = psVectorClipFitPolynomial1D(psfTry->psf->ChiTrend, options->stats, 315 mask, 0xff, chisq, NULL, flux); 316 psStatsOptions meanStat = psStatsMeanOption(options->stats->options); // Statistic for mean 317 psStatsOptions stdevStat = psStatsStdevOption(options->stats->options); // Statistic for stdev 318 319 psLogMsg ("pmPSFtry", 4, "chisq vs flux fit: %f +/- %f\n", 320 psStatsGetValue(stats, meanStat), psStatsGetValue(stats, stdevStat)); 321 322 psFree(flux); 323 psFree(mask); 324 psFree(chisq); 325 326 if (!result) { 327 psError(PS_ERR_UNKNOWN, false, "Failed to fit psf->ChiTrend"); 328 psFree(psfTry); 329 return NULL; 330 } 328 331 } 329 332 … … 600 603 601 604 for (int i = 0; i < sources->n; i++) { 602 // skip any masked sources (failed to fit one of the model steps or get a magnitude)603 if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;604 605 // skip any masked sources (failed to fit one of the model steps or get a magnitude) 606 if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue; 607 605 608 pmSource *source = sources->data[i]; 606 609 assert (source->modelEXT); // all unmasked sources should have modelEXT … … 628 631 for (int i = 1; i <= PS_MAX (psf->trendNx, psf->trendNy); i++) { 629 632 630 // copy srcMask to mask (we do not want the mask values set in pmPSFFitShapeParamsMap to be sticky)631 for (int i = 0; i < mask->n; i++) {632 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i];633 }633 // copy srcMask to mask (we do not want the mask values set in pmPSFFitShapeParamsMap to be sticky) 634 for (int i = 0; i < mask->n; i++) { 635 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]; 636 } 634 637 if (!pmPSFFitShapeParamsMap (psf, i, &scatterTotal, mask, x, y, mag, e0, e1, e2, dz)) { 635 638 break; … … 643 646 } 644 647 if (entryMin == -1) { 645 psError (PS_ERR_UNKNOWN, true, "failed to find image map for shape params");648 psError (PS_ERR_UNKNOWN, false, "failed to find image map for shape params"); 646 649 return false; 647 650 } 648 651 649 // copy srcMask to mask (we do not want the mask values set in pmPSFFitShapeParamsMap to be sticky)650 for (int i = 0; i < mask->n; i++) {651 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i];652 }652 // copy srcMask to mask (we do not want the mask values set in pmPSFFitShapeParamsMap to be sticky) 653 for (int i = 0; i < mask->n; i++) { 654 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]; 655 } 653 656 if (!pmPSFFitShapeParamsMap (psf, entryMin, &scatterTotal, mask, x, y, mag, e0, e1, e2, dz)) { 654 657 psAbort ("failed pmPSFFitShapeParamsMap on second pass?"); … … 659 662 psf->trendNy = trend->map->map->numRows; 660 663 661 // copy mask back to srcMask662 for (int i = 0; i < mask->n; i++) {663 srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = mask->data.PS_TYPE_VECTOR_MASK_DATA[i];664 }664 // copy mask back to srcMask 665 for (int i = 0; i < mask->n; i++) { 666 srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = mask->data.PS_TYPE_VECTOR_MASK_DATA[i]; 667 } 665 668 666 669 psFree (mask); … … 686 689 for (int i = 0; i < psf->psfTrendStats->clipIter; i++) { 687 690 688 psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options);689 psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options);690 691 pmTrend2D *trend = NULL;692 float mean, stdev;691 psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options); 692 psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options); 693 694 pmTrend2D *trend = NULL; 695 float mean, stdev; 693 696 694 697 // XXX we are using the same stats structure on each pass: do we need to re-init it? 695 698 bool status = true; 696 699 697 trend = psf->params->data[PM_PAR_E0];700 trend = psf->params->data[PM_PAR_E0]; 698 701 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e0, NULL); 699 mean = psStatsGetValue (trend->stats, meanOption);700 stdev = psStatsGetValue (trend->stats, stdevOption);702 mean = psStatsGetValue (trend->stats, meanOption); 703 stdev = psStatsGetValue (trend->stats, stdevOption); 701 704 psTrace ("psModules.objects", 4, "clipped E0 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e0->n); 702 pmSourceVisualPSFModelResid (trend, x, y, e0, srcMask);703 704 trend = psf->params->data[PM_PAR_E1];705 pmSourceVisualPSFModelResid (trend, x, y, e0, srcMask); 706 707 trend = psf->params->data[PM_PAR_E1]; 705 708 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e1, NULL); 706 mean = psStatsGetValue (trend->stats, meanOption);707 stdev = psStatsGetValue (trend->stats, stdevOption);709 mean = psStatsGetValue (trend->stats, meanOption); 710 stdev = psStatsGetValue (trend->stats, stdevOption); 708 711 psTrace ("psModules.objects", 4, "clipped E1 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e1->n); 709 pmSourceVisualPSFModelResid (trend, x, y, e1, srcMask);710 711 trend = psf->params->data[PM_PAR_E2];712 pmSourceVisualPSFModelResid (trend, x, y, e1, srcMask); 713 714 trend = psf->params->data[PM_PAR_E2]; 712 715 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e2, NULL); 713 mean = psStatsGetValue (trend->stats, meanOption);714 stdev = psStatsGetValue (trend->stats, stdevOption);716 mean = psStatsGetValue (trend->stats, meanOption); 717 stdev = psStatsGetValue (trend->stats, stdevOption); 715 718 psTrace ("psModules.objects", 4, "clipped E2 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e2->n); 716 pmSourceVisualPSFModelResid (trend, x, y, e2, srcMask);719 pmSourceVisualPSFModelResid (trend, x, y, e2, srcMask); 717 720 718 721 if (!status) { … … 755 758 if (psf->fieldNx > psf->fieldNy) { 756 759 Nx = scale; 757 float AR = psf->fieldNy / (float) psf->fieldNx;758 Ny = (int) (Nx * AR + 0.5);760 float AR = psf->fieldNy / (float) psf->fieldNx; 761 Ny = (int) (Nx * AR + 0.5); 759 762 Ny = PS_MAX (1, Ny); 760 763 } else { 761 764 Ny = scale; 762 float AR = psf->fieldNx / (float) psf->fieldNy;763 Nx = (int) (Ny * AR + 0.5);765 float AR = psf->fieldNx / (float) psf->fieldNy; 766 Nx = (int) (Ny * AR + 0.5); 764 767 Nx = PS_MAX (1, Nx); 765 768 } … … 809 812 810 813 if (scale == 1) { 811 x_fit = psMemIncrRefCounter (x);812 y_fit = psMemIncrRefCounter (y);813 x_tst = psMemIncrRefCounter (x);814 y_tst = psMemIncrRefCounter (y);815 e0obs_fit = psMemIncrRefCounter (e0obs);816 e1obs_fit = psMemIncrRefCounter (e1obs);817 e2obs_fit = psMemIncrRefCounter (e2obs);818 e0obs_tst = psMemIncrRefCounter (e0obs);819 e1obs_tst = psMemIncrRefCounter (e1obs);820 e2obs_tst = psMemIncrRefCounter (e2obs);814 x_fit = psMemIncrRefCounter (x); 815 y_fit = psMemIncrRefCounter (y); 816 x_tst = psMemIncrRefCounter (x); 817 y_tst = psMemIncrRefCounter (y); 818 e0obs_fit = psMemIncrRefCounter (e0obs); 819 e1obs_fit = psMemIncrRefCounter (e1obs); 820 e2obs_fit = psMemIncrRefCounter (e2obs); 821 e0obs_tst = psMemIncrRefCounter (e0obs); 822 e1obs_tst = psMemIncrRefCounter (e1obs); 823 e2obs_tst = psMemIncrRefCounter (e2obs); 821 824 } else { 822 x_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);823 y_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);824 x_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);825 y_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);826 e0obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);827 e1obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);828 e2obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);829 e0obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);830 e1obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);831 e2obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);832 for (int i = 0; i < e0obs_fit->n; i++) {833 // e0obs->n == 8 or 9:834 // i = 0, 1, 2, 3 : 2i+0 = 0, 2, 4, 6835 // i = 0, 1, 2, 3 : 2i+1 = 1, 3, 5, 7836 x_fit->data.F32[i] = x->data.F32[2*i+0]; 837 x_tst->data.F32[i] = x->data.F32[2*i+1]; 838 y_fit->data.F32[i] = y->data.F32[2*i+0]; 839 y_tst->data.F32[i] = y->data.F32[2*i+1]; 840 841 e0obs_fit->data.F32[i] = e0obs->data.F32[2*i+0]; 842 e0obs_tst->data.F32[i] = e0obs->data.F32[2*i+1]; 843 e1obs_fit->data.F32[i] = e1obs->data.F32[2*i+0];844 e1obs_tst->data.F32[i] = e1obs->data.F32[2*i+1];845 e2obs_fit->data.F32[i] = e2obs->data.F32[2*i+0];846 e2obs_tst->data.F32[i] = e2obs->data.F32[2*i+1];847 }825 x_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 826 y_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 827 x_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 828 y_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 829 e0obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 830 e1obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 831 e2obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 832 e0obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 833 e1obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 834 e2obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32); 835 for (int i = 0; i < e0obs_fit->n; i++) { 836 // e0obs->n == 8 or 9: 837 // i = 0, 1, 2, 3 : 2i+0 = 0, 2, 4, 6 838 // i = 0, 1, 2, 3 : 2i+1 = 1, 3, 5, 7 839 x_fit->data.F32[i] = x->data.F32[2*i+0]; 840 x_tst->data.F32[i] = x->data.F32[2*i+1]; 841 y_fit->data.F32[i] = y->data.F32[2*i+0]; 842 y_tst->data.F32[i] = y->data.F32[2*i+1]; 843 844 e0obs_fit->data.F32[i] = e0obs->data.F32[2*i+0]; 845 e0obs_tst->data.F32[i] = e0obs->data.F32[2*i+1]; 846 e1obs_fit->data.F32[i] = e1obs->data.F32[2*i+0]; 847 e1obs_tst->data.F32[i] = e1obs->data.F32[2*i+1]; 848 e2obs_fit->data.F32[i] = e2obs->data.F32[2*i+0]; 849 e2obs_tst->data.F32[i] = e2obs->data.F32[2*i+1]; 850 } 848 851 } 849 852 … … 852 855 // copy mask values to fitMask as a starting point 853 856 for (int i = 0; i < fitMask->n; i++) { 854 fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = mask->data.PS_TYPE_VECTOR_MASK_DATA[i];857 fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = mask->data.PS_TYPE_VECTOR_MASK_DATA[i]; 855 858 } 856 859 … … 859 862 for (int i = 0; i < nIter; i++) { 860 863 // XXX we are using the same stats structure on each pass: do we need to re-init it? 861 psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options);862 psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options);863 864 pmTrend2D *trend = NULL;865 float mean, stdev;866 867 // XXX we are using the same stats structure on each pass: do we need to re-init it?868 bool status = true;869 870 trend = psf->params->data[PM_PAR_E0];871 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e0obs_fit, NULL);872 mean = psStatsGetValue (trend->stats, meanOption);873 stdev = psStatsGetValue (trend->stats, stdevOption);874 psTrace ("psModules.objects", 4, "clipped E0 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e0obs_fit->n);875 // printTrendMap (trend);876 psImageMapCleanup (trend->map);877 // printTrendMap (trend);878 pmSourceVisualPSFModelResid (trend, x, y, e0obs, mask);879 880 trend = psf->params->data[PM_PAR_E1];881 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e1obs_fit, NULL);882 mean = psStatsGetValue (trend->stats, meanOption);883 stdev = psStatsGetValue (trend->stats, stdevOption);884 psTrace ("psModules.objects", 4, "clipped E1 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e1obs_fit->n);885 // printTrendMap (trend);886 psImageMapCleanup (trend->map);887 // printTrendMap (trend);888 pmSourceVisualPSFModelResid (trend, x, y, e1obs, mask);889 890 trend = psf->params->data[PM_PAR_E2];891 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e2obs_fit, NULL);892 mean = psStatsGetValue (trend->stats, meanOption);893 stdev = psStatsGetValue (trend->stats, stdevOption);894 psTrace ("psModules.objects", 4, "clipped E2 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e2obs->n);895 // printTrendMap (trend);896 psImageMapCleanup (trend->map);897 // printTrendMap (trend);898 pmSourceVisualPSFModelResid (trend, x, y, e2obs, mask);864 psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options); 865 psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options); 866 867 pmTrend2D *trend = NULL; 868 float mean, stdev; 869 870 // XXX we are using the same stats structure on each pass: do we need to re-init it? 871 bool status = true; 872 873 trend = psf->params->data[PM_PAR_E0]; 874 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e0obs_fit, NULL); 875 mean = psStatsGetValue (trend->stats, meanOption); 876 stdev = psStatsGetValue (trend->stats, stdevOption); 877 psTrace ("psModules.objects", 4, "clipped E0 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e0obs_fit->n); 878 // printTrendMap (trend); 879 psImageMapCleanup (trend->map); 880 // printTrendMap (trend); 881 pmSourceVisualPSFModelResid (trend, x, y, e0obs, mask); 882 883 trend = psf->params->data[PM_PAR_E1]; 884 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e1obs_fit, NULL); 885 mean = psStatsGetValue (trend->stats, meanOption); 886 stdev = psStatsGetValue (trend->stats, stdevOption); 887 psTrace ("psModules.objects", 4, "clipped E1 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e1obs_fit->n); 888 // printTrendMap (trend); 889 psImageMapCleanup (trend->map); 890 // printTrendMap (trend); 891 pmSourceVisualPSFModelResid (trend, x, y, e1obs, mask); 892 893 trend = psf->params->data[PM_PAR_E2]; 894 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e2obs_fit, NULL); 895 mean = psStatsGetValue (trend->stats, meanOption); 896 stdev = psStatsGetValue (trend->stats, stdevOption); 897 psTrace ("psModules.objects", 4, "clipped E2 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e2obs->n); 898 // printTrendMap (trend); 899 psImageMapCleanup (trend->map); 900 // printTrendMap (trend); 901 pmSourceVisualPSFModelResid (trend, x, y, e2obs, mask); 899 902 } 900 903 psf->psfTrendStats->clipIter = nIter; // restore default setting … … 941 944 // XXX copy fitMask values back to mask 942 945 for (int i = 0; i < fitMask->n; i++) { 943 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i];946 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i]; 944 947 } 945 948 psFree (fitMask); … … 958 961 float dEsquare = 0.0; 959 962 psStatsInit (stats); 960 psVectorStats (stats, e0res, NULL, mask, maskValue); 963 if (!psVectorStats (stats, e0res, NULL, mask, maskValue)) { 964 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 965 return false; 966 } 961 967 dEsquare += PS_SQR(psStatsGetValue(stats, stdevOpt)); 962 968 963 969 psStatsInit (stats); 964 psVectorStats (stats, e1res, NULL, mask, maskValue); 970 if (!psVectorStats (stats, e1res, NULL, mask, maskValue)) { 971 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 972 return false; 973 } 965 974 dEsquare += PS_SQR(psStatsGetValue(stats, stdevOpt)); 966 975 967 976 psStatsInit (stats); 968 psVectorStats (stats, e2res, NULL, mask, maskValue); 977 if (!psVectorStats (stats, e2res, NULL, mask, maskValue)) { 978 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 979 return false; 980 } 969 981 dEsquare += PS_SQR(psStatsGetValue(stats, stdevOpt)); 970 982 … … 998 1010 for (int i = 0; i < nBin; i++) { 999 1011 int j; 1000 int nValid = 0;1012 int nValid = 0; 1001 1013 for (j = 0; (j < nGroup) && (n < mag->n); j++, n++) { 1002 1014 int N = index->data.U32[n]; … … 1006 1018 1007 1019 mkSubset->data.PS_TYPE_VECTOR_MASK_DATA[j] = mask->data.PS_TYPE_VECTOR_MASK_DATA[N]; 1008 if (!mask->data.PS_TYPE_VECTOR_MASK_DATA[N]) nValid ++;1009 } 1010 if (nValid < 3) continue;1020 if (!mask->data.PS_TYPE_VECTOR_MASK_DATA[N]) nValid ++; 1021 } 1022 if (nValid < 3) continue; 1011 1023 1012 1024 dE0subset->n = j; … … 1018 1030 float dEsquare = 0.0; 1019 1031 psStatsInit (statsS); 1020 psVectorStats (statsS, dE0subset, NULL, mkSubset, 0xff); 1032 if (!psVectorStats (statsS, dE0subset, NULL, mkSubset, 0xff)) { 1033 } 1021 1034 dEsquare += PS_SQR(psStatsGetValue(statsS, stdevOpt)); 1022 1035 1023 1036 psStatsInit (statsS); 1024 psVectorStats (statsS, dE1subset, NULL, mkSubset, 0xff); 1037 if (!psVectorStats (statsS, dE1subset, NULL, mkSubset, 0xff)) { 1038 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 1039 return false; 1040 } 1025 1041 dEsquare += PS_SQR(psStatsGetValue(statsS, stdevOpt)); 1026 1042 1027 1043 psStatsInit (statsS); 1028 psVectorStats (statsS, dE2subset, NULL, mkSubset, 0xff); 1044 if (!psVectorStats (statsS, dE2subset, NULL, mkSubset, 0xff)) { 1045 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 1046 return false; 1047 } 1029 1048 dEsquare += PS_SQR(psStatsGetValue(statsS, stdevOpt)); 1030 1049 -
branches/pap/psModules/src/objects/pmPeaks.c
r23187 r25027 147 147 tmp->y = y; 148 148 tmp->value = value; 149 tmp->flux = 0;149 tmp->flux = value; 150 150 tmp->SN = 0; 151 151 tmp->xf = x; -
branches/pap/psModules/src/objects/pmSource.c
r23187 r25027 242 242 extend |= (mySource->maskView == NULL); 243 243 244 // extend = true;245 244 if (extend) { 246 245 // re-create the subimage … … 250 249 251 250 mySource->pixels = psImageSubset(readout->image, newRegion); 252 mySource->variance = psImageSubset(readout->variance, newRegion);251 mySource->variance = psImageSubset(readout->variance, newRegion); 253 252 mySource->maskView = psImageSubset(readout->mask, newRegion); 254 253 mySource->region = newRegion; … … 291 290 292 291 bool status = true; // Status of MD lookup 293 float PSF_ CLUMP_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_CLUMP_SN_LIM");292 float PSF_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); 294 293 if (!status) { 295 PSF_ CLUMP_SN_LIM = 0;294 PSF_SN_LIM = 0; 296 295 } 297 296 float PSF_CLUMP_GRID_SCALE = psMetadataLookupF32(&status, recipe, "PSF_CLUMP_GRID_SCALE"); … … 342 341 } 343 342 344 if (src->moments->SN < PSF_ CLUMP_SN_LIM) {343 if (src->moments->SN < PSF_SN_LIM) { 345 344 psTrace("psModules.objects", 10, "Rejecting source from clump because of low S/N (%f)\n", 346 345 src->moments->SN); … … 450 449 if (tmpSrc->moments == NULL) 451 450 continue; 452 if (tmpSrc->moments->SN < PSF_ CLUMP_SN_LIM)451 if (tmpSrc->moments->SN < PSF_SN_LIM) 453 452 continue; 454 453 … … 479 478 stats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV); 480 479 481 psVectorStats (stats, tmpSx, NULL, NULL, 0); 480 if (!psVectorStats (stats, tmpSx, NULL, NULL, 0)) { 481 psError(PS_ERR_UNKNOWN, false, "failed to measure Sx stats"); 482 return (emptyClump); 483 } 482 484 psfClump.X = stats->clippedMean; 483 485 psfClump.dX = stats->clippedStdev; 484 486 485 psVectorStats (stats, tmpSy, NULL, NULL, 0); 487 if (!psVectorStats (stats, tmpSy, NULL, NULL, 0)) { 488 psError(PS_ERR_UNKNOWN, false, "failed to measure Sy stats"); 489 return (emptyClump); 490 } 486 491 psfClump.Y = stats->clippedMean; 487 492 psfClump.dY = stats->clippedStdev; … … 528 533 bool status; 529 534 float PSF_SN_LIM = psMetadataLookupF32 (&status, recipe, "PSF_SN_LIM"); 530 if (!status) 531 PSF_SN_LIM = 20.0; 535 if (!status) PSF_SN_LIM = 20.0; 532 536 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA"); 533 if (!status) 534 PSF_CLUMP_NSIGMA = 1.5; 535 float INNER_RADIUS = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS");537 if (!status) PSF_CLUMP_NSIGMA = 1.5; 538 539 // float INNER_RADIUS = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); 536 540 537 541 pmSourceMode noMoments = PM_SOURCE_MODE_MOMENTS_FAILURE | PM_SOURCE_MODE_SKYVAR_FAILURE | PM_SOURCE_MODE_SKY_FAILURE | PM_SOURCE_MODE_BELOW_MOMENTS_SN; … … 543 547 pmSource *source = (pmSource *) sources->data[i]; 544 548 545 // psf clumps are found for image subregions:546 // skip sources not in this region 549 // psf clumps are found for image subregions: 550 // skip sources not in this region 547 551 if (source->peak->x < region->x0) continue; 548 552 if (source->peak->x >= region->x1) continue; 549 553 if (source->peak->y < region->y0) continue; 550 if (source->peak->y >= region->y1) continue;551 552 // should be set by pmSourceAlloc554 if (source->peak->y >= region->y1) continue; 555 556 // should be set by pmSourceAlloc 553 557 psAssert (source->type == PM_SOURCE_TYPE_UNKNOWN, "source type was not init-ed?"); 554 558 … … 556 560 if (!source->moments) { 557 561 source->type = PM_SOURCE_TYPE_STAR; 558 psAssert (source->mode & noMoments, "why is this source missing moments?");562 psAssert (source->mode & noMoments, "why is this source missing moments?"); 559 563 Nstar++; 560 564 continue; … … 576 580 source->type = PM_SOURCE_TYPE_STAR; 577 581 source->mode |= PM_SOURCE_MODE_SATSTAR; 578 // recalculate moments here with larger box? 579 pmSourceMoments (source, INNER_RADIUS); 582 // why do we recalculate moments here? 583 // we already attempt to do this in psphotSourceStats 584 // pmSourceMoments (source, INNER_RADIUS); 580 585 Nsatstar ++; 581 586 continue; … … 590 595 } 591 596 592 // likely defect (too small to be stellar) (push out to 3 sigma) 593 // low S/N objects which are small are probably stellar 594 // only set candidate defects if 595 // XXX these limits are quite arbitrary 596 if ((sigX < 0.05) || (sigY < 0.05)) { 597 source->type = PM_SOURCE_TYPE_DEFECT; 598 source->mode |= PM_SOURCE_MODE_DEFECT; 599 Ncr ++; 600 continue; 601 } 602 603 // likely unsaturated extended source (too large to be stellar) 604 if ((sigX > (clump.X + 3*clump.dX)) || (sigY > (clump.Y + 3*clump.dY))) { 605 source->type = PM_SOURCE_TYPE_EXTENDED; 606 Next ++; 607 continue; 608 } 609 610 // the rest are probable stellar objects 611 starsn_moments->data.F32[starsn_moments->n] = source->moments->SN; 612 starsn_moments->n ++; 613 starsn_peaks->data.F32[starsn_peaks->n] = source->peak->SN; 614 starsn_peaks->n ++; 615 Nstar ++; 616 617 // PSF star (within 1.5 sigma of clump center, S/N > limit) 618 psF32 radius = hypot ((sigX-clump.X)/clump.dX, (sigY-clump.Y)/clump.dY); 619 if ((source->moments->SN > PSF_SN_LIM) && (radius < PSF_CLUMP_NSIGMA)) { 620 source->type = PM_SOURCE_TYPE_STAR; 621 source->mode |= PM_SOURCE_MODE_PSFSTAR; 622 Npsf ++; 623 continue; 597 // The following determinations require the use of moments 598 if (!(source->mode & noMoments)) { 599 // likely defect (too small to be stellar) (push out to 3 sigma) 600 // low S/N objects which are small are probably stellar 601 // XXX these limits are quite arbitrary 602 if (sigX < 0.05 || sigY < 0.05) { 603 source->type = PM_SOURCE_TYPE_DEFECT; 604 source->mode |= PM_SOURCE_MODE_DEFECT; 605 Ncr ++; 606 continue; 607 } 608 609 // likely unsaturated extended source (too large to be stellar) 610 if (sigX > clump.X + 3*clump.dX || sigY > clump.Y + 3*clump.dY) { 611 source->type = PM_SOURCE_TYPE_EXTENDED; 612 Next ++; 613 continue; 614 } 615 616 // the rest are probable stellar objects 617 starsn_moments->data.F32[starsn_moments->n] = source->moments->SN; 618 starsn_moments->n ++; 619 starsn_peaks->data.F32[starsn_peaks->n] = source->peak->SN; 620 starsn_peaks->n ++; 621 Nstar ++; 622 623 // PSF star (within 1.5 sigma of clump center, S/N > limit) 624 psF32 radius = hypot ((sigX-clump.X)/clump.dX, (sigY-clump.Y)/clump.dY); 625 if ((source->moments->SN > PSF_SN_LIM) && (radius < PSF_CLUMP_NSIGMA)) { 626 source->type = PM_SOURCE_TYPE_STAR; 627 source->mode |= PM_SOURCE_MODE_PSFSTAR; 628 Npsf ++; 629 continue; 630 } 624 631 } 625 632 … … 636 643 637 644 if (!psVectorStats (stats, starsn_moments, NULL, NULL, 0)) { 638 // Don't care about this error 639 psErrorClear(); 645 psError(PS_ERR_UNKNOWN, false, "failed to measure SN / moments stats"); 646 psFree (stats); 647 psFree (starsn_peaks); 648 return false; 640 649 } 641 650 psLogMsg ("pmObjects", 3, "SN range (moments): %f - %f\n", stats->min, stats->max); … … 648 657 stats = psStatsAlloc (PS_STAT_MIN | PS_STAT_MAX); 649 658 if (!psVectorStats (stats, starsn_peaks, NULL, NULL, 0)) { 650 // Don't care about this error 651 psErrorClear(); 659 psError(PS_ERR_UNKNOWN, false, "failed to measure SN / moments stats"); 660 psFree (stats); 661 psFree (starsn_peaks); 662 return false; 652 663 } 653 664 psLogMsg ("psModules.objects", 3, "SN range (peaks) : %f - %f (%ld)\n", -
branches/pap/psModules/src/objects/pmSource.h
r23487 r25027 213 213 */ 214 214 bool pmSourceMoments( 215 pmSource *source, ///< The input pmSource for which moments will be computed 216 float radius ///< Use a circle of pixels around the peak 215 pmSource *source, ///< The input pmSource for which moments will be computed 216 float radius, ///< Use a circle of pixels around the peak 217 float sigma, ///< size of Gaussian window function (<= 0.0 -> skip window) 218 float minSN ///< minimum pixel significance 217 219 ); 218 220 -
branches/pap/psModules/src/objects/pmSourceContour.c
r23187 r25027 273 273 x0 = findContourPos (image, threshold, xR, yR, RIGHT, x1); 274 274 if (x0 == x1) { 275 // fprintf (stderr, "top: %d (%d - %d)\n", yR, xR, x1);275 // fprintf (stderr, "top: %d (%d - %d)\n", yR, xR, x1); 276 276 goto pt1; 277 277 } … … 282 282 x1 = findContourNeg (image, threshold, xR, yR, RIGHT); 283 283 } 284 // fprintf (stderr, "pos: %d (%d - %d)\n", yR, x0, x1);284 // fprintf (stderr, "pos: %d (%d - %d)\n", yR, x0, x1); 285 285 286 286 xVec->data.F32[Npt + 0] = image->col0 + x0; … … 288 288 yVec->data.F32[Npt + 0] = image->row0 + yR; 289 289 yVec->data.F32[Npt + 1] = image->row0 + yR; 290 290 291 Npt += 2; 291 292 … … 307 308 x0 = findContourPos (image, threshold, xR, yR, RIGHT, x1); 308 309 if (x0 == x1) { 309 // fprintf (stderr, "top: %d (%d - %d)\n", yR, xR, x1);310 // fprintf (stderr, "top: %d (%d - %d)\n", yR, xR, x1); 310 311 goto pt2; 311 312 } … … 322 323 yVec->data.F32[Npt + 0] = image->row0 + yR; 323 324 yVec->data.F32[Npt + 1] = image->row0 + yR; 325 324 326 Npt += 2; 325 327 … … 334 336 yVec->n = Npt; 335 337 336 // fprintf (stderr, "done\n");337 338 psArray *tmpArray = psArrayAlloc(2); 338 339 -
branches/pap/psModules/src/objects/pmSourceFitModel.c
r23187 r25027 172 172 fitStatus = psMinimizeLMChi2(myMin, covar, params, constraint, x, y, yErr, model->modelFunc); 173 173 for (int i = 0; i < dparams->n; i++) { 174 if (psTraceGetLevel("psModules.objects") >= 4) {175 fprintf (stderr, "%f ", params->data.F32[i]);176 }177 174 if ((constraint->paramMask != NULL) && constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) 178 175 continue; 179 176 dparams->data.F32[i] = sqrt(covar->data.F32[i][i]); 177 if (psTraceGetLevel("psModules.objects") >= 4) { 178 fprintf (stderr, "%f +/- %f\n", params->data.F32[i], dparams->data.F32[i]); 179 } 180 180 } 181 181 psTrace ("psModules.objects", 4, "niter: %d, chisq: %f", myMin->iter, myMin->value); -
branches/pap/psModules/src/objects/pmSourceIO.c
r22699 r25027 496 496 status = pmSourcesWrite_CMF_PS1_V1 (file->fits, readout, sources, file->header, outhead, dataname); 497 497 } 498 if (!strcmp (exttype, "PS1_V2")) { 499 status = pmSourcesWrite_CMF_PS1_V2 (file->fits, readout, sources, file->header, outhead, dataname); 500 } 498 501 if (xsrcname) { 499 502 if (!strcmp (exttype, "PS1_DEV_1")) { … … 506 509 status = pmSourcesWrite_CMF_PS1_V1_XSRC (file->fits, sources, xsrcname, recipe); 507 510 } 511 if (!strcmp (exttype, "PS1_V2")) { 512 status = pmSourcesWrite_CMF_PS1_V2_XSRC (file->fits, sources, xsrcname, recipe); 513 } 508 514 } 509 515 if (xfitname) { … … 517 523 status = pmSourcesWrite_CMF_PS1_V1_XFIT (file->fits, sources, xfitname); 518 524 } 525 if (!strcmp (exttype, "PS1_V2")) { 526 status = pmSourcesWrite_CMF_PS1_V2_XFIT (file->fits, sources, xfitname); 527 } 519 528 } 520 529 if (!status) { … … 562 571 563 572 // not needed if only one chip 564 if (file->fpa->chips->n == 1) return true; 565 573 if (file->fpa->chips->n == 1) { 574 pmSourceIO_WriteMatchedRefs (file->fits, file->fpa, config); 575 return true; 576 } 566 577 567 578 // find the FPA phu … … 667 678 psFree (outhead); 668 679 680 pmSourceIO_WriteMatchedRefs (file->fits, file->fpa, config); 669 681 return true; 670 682 } … … 679 691 680 692 pmFPA *fpa = file->fpa; 693 694 pmSourceIO_ReadMatchedRefs (file->fits, fpa, config); 681 695 682 696 if (view->chip == -1) { … … 941 955 sources = pmSourcesRead_CMF_PS1_V1 (file->fits, hdu->header); 942 956 } 957 if (!strcmp (exttype, "PS1_V2")) { 958 sources = pmSourcesRead_CMF_PS1_V2 (file->fits, hdu->header); 959 } 943 960 } 944 961 … … 1053 1070 } 1054 1071 1072 -
branches/pap/psModules/src/objects/pmSourceIO.h
r21516 r25027 39 39 bool pmSourcesWrite_CMF_PS1_V1_XFIT (psFits *fits, psArray *sources, char *extname); 40 40 41 bool pmSourcesWrite_CMF_PS1_V2 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname); 42 bool pmSourcesWrite_CMF_PS1_V2_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe); 43 bool pmSourcesWrite_CMF_PS1_V2_XFIT (psFits *fits, psArray *sources, char *extname); 44 41 45 bool pmSource_CMF_WritePHU (const pmFPAview *view, pmFPAfile *file, pmConfig *config); 42 46 … … 48 52 psArray *pmSourcesRead_PS1_CAL_0 (psFits *fits, psMetadata *header); 49 53 psArray *pmSourcesRead_CMF_PS1_V1 (psFits *fits, psMetadata *header); 54 psArray *pmSourcesRead_CMF_PS1_V2 (psFits *fits, psMetadata *header); 50 55 51 56 bool pmSourcesWritePSFs (psArray *sources, char *filename); … … 75 80 bool pmSourceLocalAstrometry (psSphere *ptSky, float *posAngle, float *pltScale, pmChip *chip, float xPos, float yPos); 76 81 82 bool pmSourceIO_WriteMatchedRefs (psFits *fits, pmFPA *fpa, pmConfig *config); 83 bool pmSourceIO_ReadMatchedRefs (psFits *fits, pmFPA *fpa, const pmConfig *config); 84 77 85 /// @} 78 86 # endif /* PM_SOURCE_IO_H */ -
branches/pap/psModules/src/objects/pmSourceIO_RAW.c
r20937 r25027 254 254 } 255 255 256 fprintf (f, "# %5s %5s %8s %7s %7s %6s %6s %10s %7s %7s %7s %4s %4s %5s\n", 257 "x", "y", "peak", "Mx", "My", "Mxx", "Myy", "Sum", "Peak", "Sky", "SN", "nPix", "type", "mode"); 258 256 259 for (i = 0; i < sources->n; i++) { 257 260 source = sources->data[i]; 258 261 if (source->moments == NULL) 259 262 continue; 260 fprintf (f, "%5d %5d % 7.1f %7.1f %7.1f %6.3f %6.3f %10.1f %7.1f %7.1f %7.1f %4d %2d %#5x\n",263 fprintf (f, "%5d %5d %8.1f %7.1f %7.1f %6.3f %6.3f %10.1f %7.1f %7.1f %7.1f %4d %2d %#5x\n", 261 264 source->peak->x, source->peak->y, source->peak->value, 262 265 source->moments->Mx, source->moments->My, -
branches/pap/psModules/src/objects/pmSourceMasks.c
r23184 r25027 44 44 ADD_MASK(header, RADIAL_FLUX , "Calculated radial flux measurements"); 45 45 ADD_MASK(header, SIZE_SKIPPED , "Could not be determine size"); 46 ADD_MASK(header, ON_SPIKE , "Source lands in bright star spike"); 47 ADD_MASK(header, ON_GHOST , "Source lands in bright star ghost / glint"); 48 ADD_MASK(header, OFF_CHIP , "Source centroid lands off chip edge"); 46 49 47 50 return true; -
branches/pap/psModules/src/objects/pmSourceMasks.h
r23184 r25027 34 34 PM_SOURCE_MODE_RADIAL_FLUX = 0x08000000, ///< radial flux measurements calculated 35 35 PM_SOURCE_MODE_SIZE_SKIPPED = 0x10000000, ///< size could not be determined 36 PM_SOURCE_MODE_ON_SPIKE = 0x20000000, ///< peak lands on diffraction spike 37 PM_SOURCE_MODE_ON_GHOST = 0x40000000, ///< peak lands on ghost or glint 38 PM_SOURCE_MODE_OFF_CHIP = 0x80000000, ///< peak lands off edge of chip 36 39 } pmSourceMode; 37 40 -
branches/pap/psModules/src/objects/pmSourceMatch.c
r23241 r25027 45 45 psVector **x, psVector **y, // Coordinate vectors to return 46 46 psVector **mag, psVector **magErr, // Magnitude and error vectors to return 47 psVector **indices, // Indices for sources 47 48 const psArray *sources // Input sources 48 49 ) … … 58 59 *mag = psVectorRecycle(*mag, numSources, PS_TYPE_F32); 59 60 *magErr = psVectorRecycle(*magErr, numSources, PS_TYPE_F32); 61 *indices = psVectorRecycle(*indices, numSources, PS_TYPE_S32); 60 62 float xMin = INFINITY, xMax = -INFINITY, yMin = INFINITY, yMax = -INFINITY; // Bounds of sources 61 63 long num = 0; // Number of valid sources 62 64 for (long i = 0; i < numSources; i++) { 63 65 pmSource *source = sources->data[i]; // Source of interest 64 if (!source) continue; 65 if (source->mode & SOURCE_MASK) continue; 66 if (!isfinite(source->psfMag)) continue; 67 if (!isfinite(source->errMag)) continue; 68 if (source->psfMag > SOURCE_FAINTEST) continue; 66 if (!source || (source->mode & SOURCE_MASK) || !isfinite(source->psfMag) || 67 !isfinite(source->errMag) || source->psfMag > SOURCE_FAINTEST) { 68 continue; 69 } 69 70 70 71 float xSrc, ySrc; // Coordinates of source … … 78 79 (*y)->data.F32[num] = ySrc; 79 80 (*mag)->data.F32[num] = source->psfMag; 80 (*magErr)->data.F32[num] = source->errMag ; 81 (*magErr)->data.F32[num] = source->errMag; 82 (*indices)->data.S32[num] = i; 81 83 num++; 82 84 } … … 85 87 (*mag)->n = num; 86 88 (*magErr)->n = num; 89 (*indices)->n = num; 87 90 88 91 if (*bounds) { … … 175 178 psVector *xImage = NULL, *yImage = NULL; // Coordinates of sources 176 179 psVector *magImage = NULL, *magErrImage = NULL; // Magnitude and mag 177 178 int numSources = sourcesParse(&boundsImage, &xImage, &yImage, &magImage, &magErrImage, 180 psVector *indices = NULL; // Indices for sources 181 182 int numSources = sourcesParse(&boundsImage, &xImage, &yImage, &magImage, &magErrImage, &indices, 179 183 sources); // Number of sources 180 184 … … 187 191 for (int j = 0; j < numSources; j++) { 188 192 pmSourceMatch *match = pmSourceMatchAlloc(); // Match data 189 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], i, j); 193 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 194 i, indices->data.S32[j]); 190 195 matches->data[j] = match; 191 196 } … … 206 211 for (int j = 0, k = numMaster; j < numSources; j++, k++) { 207 212 pmSourceMatch *match = pmSourceMatchAlloc(); // Match data 208 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], i, j); 213 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 214 i, indices->data.S32[j]); 209 215 matches->data[k] = match; 210 216 } … … 231 237 // Record the match 232 238 pmSourceMatch *match = matches->data[index]; // Match data 233 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], i, j); 239 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 240 i, indices->data.S32[j]); 234 241 numMatch++; 235 242 } else { 236 243 // Add to the master list 237 244 pmSourceMatch *match = pmSourceMatchAlloc(); // Match data 238 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], i, j); 245 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 246 i, indices->data.S32[j]); 239 247 xMaster->data.F32[numMaster] = xImage->data.F32[j]; 240 248 yMaster->data.F32[numMaster] = yImage->data.F32[j]; … … 469 477 470 478 if (!psVectorStats(stats, trans, NULL, badImage, 0xFF)) { 479 psError(PS_ERR_UNKNOWN, false, "Unable to perform statistics on transparencies."); 480 psFree(stats); 481 return -1; 482 } 483 // XXX handle this case better: 484 if (isnan(stats->clippedMean)) { 471 485 psError(PS_ERR_UNKNOWN, false, "Unable to perform statistics on transparencies."); 472 486 psFree(stats); -
branches/pap/psModules/src/objects/pmSourceMoments.c
r21363 r25027 57 57 # define VALID_RADIUS(X,Y,RAD2) (((RAD2) >= (PS_SQR(X) + PS_SQR(Y))) ? 1 : 0) 58 58 59 bool pmSourceMoments(pmSource *source, psF32 radius )59 bool pmSourceMoments(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN) 60 60 { 61 61 PS_ASSERT_PTR_NON_NULL(source, false); … … 84 84 psF32 Y1 = 0.0; 85 85 psF32 R2 = PS_SQR(radius); 86 psF32 minSN2 = PS_SQR(minSN); 87 psF32 rsigma2 = 0.5 / PS_SQR(sigma); 86 88 87 89 // a note about coordinates: coordinates of objects throughout psphot refer to the primary … … 97 99 98 100 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 101 102 psF32 yDiff = row - yPeak; 103 if (fabs(yDiff) > radius) continue; 99 104 100 105 psF32 *vPix = source->pixels->data.F32[row]; … … 113 118 114 119 psF32 xDiff = col - xPeak; 115 psF32 yDiff = row - yPeak;120 if (fabs(xDiff) > radius) continue; 116 121 117 122 // radius is just a function of (xDiff, yDiff) … … 121 126 psF32 wDiff = *vWgt; 122 127 123 // XXX EAM : should this limit be user-defined? 124 if (PS_SQR(pDiff) < wDiff) continue; 125 126 Var += wDiff; 127 Sum += pDiff; 128 129 psF32 xWght = xDiff * pDiff; 130 psF32 yWght = yDiff * pDiff; 131 132 X1 += xWght; 133 Y1 += yWght; 128 // skip pixels below specified significance level 129 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 130 if (pDiff < 0) continue; 131 132 if (sigma > 0.0) { 133 // apply a pseudo-gaussian weight 134 135 // XXX a lot of extra flops; can we do pre-calculate? 136 psF32 z = (PS_SQR(xDiff) + PS_SQR(yDiff))*rsigma2; 137 assert (z >= 0.0); 138 psF32 t = 1.0 + z*(1.0 + z/2.0*(1.0 + z/3.0)); 139 psF32 weight = 1.0 / t; 140 141 // fprintf (stderr, "%6.1f %6.1f %8.1f %8.1f %5.3f ", xDiff, yDiff, pDiff, wDiff, weight); 142 143 wDiff *= weight; 144 pDiff *= weight; 145 } 146 147 Var += wDiff; 148 Sum += pDiff; 149 150 psF32 xWght = xDiff * pDiff; 151 psF32 yWght = yDiff * pDiff; 152 153 X1 += xWght; 154 Y1 += yWght; 155 156 // fprintf (stderr, " : %6.1f %6.1f %8.1f %8.1f\n", X1, Y1, Sum, Var); 134 157 135 158 peakPixel = PS_MAX (*vPix, peakPixel); … … 188 211 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 189 212 213 psF32 yDiff = row - yCM; 214 if (fabs(yDiff) > radius) continue; 215 190 216 psF32 *vPix = source->pixels->data.F32[row]; 191 217 psF32 *vWgt = source->variance->data.F32[row]; … … 203 229 204 230 psF32 xDiff = col - xCM; 205 psF32 yDiff = row - yCM;231 if (fabs(xDiff) > radius) continue; 206 232 207 233 // radius is just a function of (xDiff, yDiff) … … 215 241 // XXX EAM : should this limit be user-defined? 216 242 217 if (PS_SQR(pDiff) < wDiff) continue;243 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 218 244 if (pDiff < 0) continue; 245 246 if (sigma > 0.0) { 247 // apply a pseudo-gaussian weight 248 249 // XXX a lot of extra flops; can we do pre-calculate? 250 psF32 z = (PS_SQR(xDiff) + PS_SQR(yDiff))*rsigma2; 251 assert (z >= 0.0); 252 psF32 t = 1.0 + z*(1.0 + z/2.0*(1.0 + z/3.0)); 253 psF32 weight = 1.0 / t; 254 255 // fprintf (stderr, "%6.1f %6.1f %8.1f %8.1f %5.3f ", xDiff, yDiff, pDiff, wDiff, weight); 256 257 wDiff *= weight; 258 pDiff *= weight; 259 } 219 260 220 261 Sum += pDiff; -
branches/pap/psModules/src/objects/pmSourceUtils.c
r23187 r25027 94 94 source->peak = pmPeakAlloc (xChip, yChip, Io, PM_PEAK_LONE); 95 95 96 int x0Cell = psMetadataLookupS32(NULL, cell->concepts, "CELL.X0"); 97 int y0Cell = psMetadataLookupS32(NULL, cell->concepts, "CELL.Y0"); 98 int xParityCell = psMetadataLookupS32(NULL, cell->concepts, "CELL.XPARITY"); 99 int yParityCell = psMetadataLookupS32(NULL, cell->concepts, "CELL.YPARITY"); 96 float xReadout, yReadout; 100 97 101 // XXX fix the binning : currently not selected from concepts 102 // int xBin = psMetadataLookupS32(NULL, cell->concepts, "CELL.XBIN"); // Binning in x and y 103 // int yBin = psMetadataLookupS32(NULL, cell->concepts, "CELL.YBIN"); // Binning in x and y 104 int xBin = 1; 105 int yBin = 1; 98 // if we have information about the chip & cell, adjust the coordinates chip->cell->readout 99 // otherwise, assume 0,0 offset and 1,1 parity 100 if (cell) { 101 int x0Cell = psMetadataLookupS32(NULL, cell->concepts, "CELL.X0"); 102 int y0Cell = psMetadataLookupS32(NULL, cell->concepts, "CELL.Y0"); 103 int xParityCell = psMetadataLookupS32(NULL, cell->concepts, "CELL.XPARITY"); 104 int yParityCell = psMetadataLookupS32(NULL, cell->concepts, "CELL.YPARITY"); 106 105 107 // Position on the cell 108 float xCell = PM_CHIP_TO_CELL(xChip, x0Cell, xParityCell, xBin); 109 float yCell = PM_CHIP_TO_CELL(yChip, y0Cell, yParityCell, yBin); 106 // XXX fix the binning : currently not selected from concepts 107 // int xBin = psMetadataLookupS32(NULL, cell->concepts, "CELL.XBIN"); // Binning in x and y 108 // int yBin = psMetadataLookupS32(NULL, cell->concepts, "CELL.YBIN"); // Binning in x and y 109 int xBin = 1; 110 int yBin = 1; 110 111 111 // Position on the readout 112 // float xReadout = CELL_TO_READOUT(xCell, x0Readout); 113 // float yReadout = CELL_TO_READOUT(yCell, y0Readout); 112 // Position on the cell 113 float xCell = PM_CHIP_TO_CELL(xChip, x0Cell, xParityCell, xBin); 114 float yCell = PM_CHIP_TO_CELL(yChip, y0Cell, yParityCell, yBin); 115 116 // Position on the readout 117 // float xReadout = CELL_TO_READOUT(xCell, x0Readout); 118 // float yReadout = CELL_TO_READOUT(yCell, y0Readout); 119 xReadout = xCell; 120 yReadout = yCell; 121 } else { 122 xReadout = xChip; 123 yReadout = yChip; 124 } 114 125 115 pmSourceDefinePixels (source, readout, x Cell, yCell, radius);126 pmSourceDefinePixels (source, readout, xReadout, yReadout, radius); 116 127 117 128 return (source); -
branches/pap/psModules/src/psmodules.h
r23751 r25027 47 47 #include <pmFPAfileDefine.h> 48 48 #include <pmFPAfileFitsIO.h> 49 #include <pmFPAfileFringeIO.h> 49 50 #include <pmFPAfileIO.h> 50 51 #include <pmFPARead.h> … … 76 77 #include <pmDark.h> 77 78 #include <pmRemnance.h> 79 #include <pmPattern.h> 78 80 79 81 // the following headers are from psModule:astrom -
branches/pap/psModules/test/camera/tap_pmFPAMaskW.c
r21474 r25027 356 356 // ---------------------------------------------------------------------- 357 357 // pmReadoutSetVariance() tests: NULL inputs 358 // bool pmReadoutSetVariance(pmReadout *readout, bool poisson)358 // bool pmReadoutSetVariance(pmReadout *readout, const psImage *noiseMap, bool poisson) 359 359 if (1) { 360 360 psMemId id = psMemGetId(); … … 367 367 368 368 // Set readout == NULL, ensure pmReadoutSetVariance() returnes FALSE, with no seg faults, memory leaks 369 rc = pmReadoutSetVariance(NULL, false);370 ok(!rc, "pmReadoutSetVariance(NULL, false) returned FALSE with null pmReadout input");369 rc = pmReadoutSetVariance(NULL, NULL, false); 370 ok(!rc, "pmReadoutSetVariance(NULL, NULL, false) returned FALSE with null pmReadout input"); 371 371 372 372 … … 375 375 rc|= psMetadataAddF32(readout->parent->concepts, PS_LIST_HEAD, "CELL.READNOISE", PS_META_REPLACE, NULL, CELL_READNOISE); 376 376 ok(rc, "Set GAIN and READNOISE in cell->concepts successfully"); 377 377 /* 378 * Getting the section below to run requires generating a noiseMap 379 * 378 380 // Call pmReadoutSetVariance() and then verify that the mask data was set correctly 379 381 rc = pmReadoutSetVariance(readout, false); … … 419 421 420 422 ok(!errorFlag, "pmReadoutSetWeight() set the weight values correctly (Poisson)"); 423 */ 421 424 psFree(fpa); 422 425 psFree(camera); -
branches/pap/psModules/test/concepts/tap_pmConcepts.c
r21223 r25027 77 77 } 78 78 79 psMetadataItem *dummyConceptCopier( 80 const psMetadataItem *source, 81 const psMetadataItem *target, 82 const psMetadata *cameraFormat, 83 const pmFPA *fpa, 84 const pmChip *chip, 85 const pmCell *cell) 86 { 87 if (target == NULL || 88 source == PM_CONCEPT_SOURCE_NONE || 89 cameraFormat == NULL || 90 fpa == NULL || 91 chip == NULL || 92 cell == NULL) { 93 printf("dummyConceptCopier() args are NULL\n"); 94 } 95 return(NULL); 96 } 79 97 80 98 int main(int argc, char* argv[]) … … 92 110 psMetadataItem *blank = psMetadataItemAlloc("myItem1", PS_DATA_BOOL, "I am a boolean", true); 93 111 pmConceptSpec *tmp = pmConceptSpecAlloc(blank, dummyConceptParser, 94 dummyConceptFormatter, true);112 dummyConceptFormatter, dummyConceptCopier, true); 95 113 ok(tmp != NULL, "pmConceptSpecAlloc() returned non-NULL"); 96 114 skip_start(tmp == NULL, 4, "Skipping tests because pmConceptSpecAlloc() returned NULL"); … … 98 116 ok(tmp->parse == dummyConceptParser, "pmConceptSpecAlloc() set the ->parse member correctly"); 99 117 ok(tmp->format == dummyConceptFormatter, "pmConceptSpecAlloc() set the ->format member correctly"); 118 ok(tmp->copy == dummyConceptCopier, "pmConceptSpecAlloc() set the ->copy member correctly"); 100 119 ok(tmp->required == true, "pmConceptSpecAlloc() set the ->required member correctly"); 101 120 skip_end(); … … 109 128 { 110 129 psMemId id = psMemGetId(); 111 pmConceptSpec *tmp = pmConceptSpecAlloc(NULL, NULL, NULL, false);130 pmConceptSpec *tmp = pmConceptSpecAlloc(NULL, NULL, NULL, NULL, false); 112 131 ok(tmp != NULL, "pmConceptSpecAlloc() returned non-NULL with NULL inputs"); 113 132 psFree(tmp); -
branches/pap/psModules/test/objects/tap_pmGrowthCurve.c
r21223 r25027 129 129 130 130 source->modelPSF->dparams->data.F32[PM_PAR_I0] = 1; 131 source->mode = PM_SOURCE_MODE_ SUBTRACTED;131 source->mode = PM_SOURCE_MODE_PSFSTAR; 132 132 133 133 source->modelPSF->radiusFit = 15.0; … … 232 232 233 233 source->modelPSF->dparams->data.F32[PM_PAR_I0] = 1; 234 source->mode = PM_SOURCE_MODE_ SUBTRACTED;234 source->mode = PM_SOURCE_MODE_PSFSTAR; 235 235 236 236 source->modelPSF->radiusFit = 15.0; … … 334 334 335 335 source->modelPSF->dparams->data.F32[PM_PAR_I0] = 1; 336 source->mode = PM_SOURCE_MODE_ SUBTRACTED;336 source->mode = PM_SOURCE_MODE_PSFSTAR; 337 337 338 338 source->modelPSF->radiusFit = 15.0; -
branches/pap/psModules/test/objects/tap_pmSource.c
r21471 r25027 432 432 psArray *sources = psArrayAlloc(NUM_SOURCES); 433 433 psMetadata *recipe = psMetadataAlloc(); 434 bool rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "PSF_ CLUMP_SN_LIM", 0, NULL, 0.0);434 bool rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "PSF_SN_LIM", 0, NULL, 0.0); 435 435 rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "MOMENTS_SX_MAX", 0, NULL, 10.0); 436 436 rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "MOMENTS_SY_MAX", 0, NULL, 10.0); … … 452 452 psArray *sources = psArrayAlloc(NUM_SOURCES); 453 453 psMetadata *recipe = psMetadataAlloc(); 454 bool rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "PSF_ CLUMP_SN_LIM", 0, NULL, 0.0);454 bool rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "PSF_SN_LIM", 0, NULL, 0.0); 455 455 rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "MOMENTS_SX_MAX", 0, NULL, 10.0); 456 456 rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "MOMENTS_SY_MAX", 0, NULL, 10.0); … … 490 490 } 491 491 psMetadata *recipe = psMetadataAlloc(); 492 bool rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "PSF_ CLUMP_SN_LIM", 0, NULL, 0.0);492 bool rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "PSF_SN_LIM", 0, NULL, 0.0); 493 493 rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "MOMENTS_SX_MAX", 0, NULL, 10.0); 494 494 rc = psMetadataAddF32(recipe, PS_LIST_HEAD, "MOMENTS_SY_MAX", 0, NULL, 10.0); -
branches/pap/psModules/test/objects/tap_pmSourceIO_PS1_DEV_1.c
r21223 r25027 48 48 psMetadata *tableHeader = psMetadataAlloc(); 49 49 psString extname = psStringCopy("ext"); 50 bool rc = pmSourcesWrite_PS1_DEV_1(NULL, sources, imageHeader, tableHeader, extname , NULL);50 bool rc = pmSourcesWrite_PS1_DEV_1(NULL, sources, imageHeader, tableHeader, extname); 51 51 ok(rc == false, "pmSourcesWrite_PS1_DEV_1() returned FALSE with NULL psFits input parameter"); 52 52 psFree(fitsFile); … … 72 72 psMetadata *tableHeader = psMetadataAlloc(); 73 73 psString extname = psStringCopy("ext"); 74 bool rc = pmSourcesWrite_PS1_DEV_1(fitsFile, NULL, imageHeader, tableHeader, extname , NULL);74 bool rc = pmSourcesWrite_PS1_DEV_1(fitsFile, NULL, imageHeader, tableHeader, extname); 75 75 ok(rc == false, "pmSourcesWrite_PS1_DEV_1() returned FALSE with NULL pmSource input parameter"); 76 76 psFree(fitsFile); … … 96 96 psMetadata *tableHeader = psMetadataAlloc(); 97 97 psString extname = psStringCopy("ext"); 98 bool rc = pmSourcesWrite_PS1_DEV_1(fitsFile, sources, imageHeader, tableHeader, NULL , NULL);98 bool rc = pmSourcesWrite_PS1_DEV_1(fitsFile, sources, imageHeader, tableHeader, NULL); 99 99 ok(rc == false, "pmSourcesWrite_PS1_DEV_1() returned FALSE with NULL extname input parameter"); 100 100 psFree(fitsFile); … … 216 216 psMetadata *tableHeader = psMetadataAlloc(); 217 217 psString extname = psStringCopy("ext"); 218 bool rc = pmSourcesWrite_PS1_DEV_1(fitsFile, sources, imageHeader, tableHeader, extname , NULL);218 bool rc = pmSourcesWrite_PS1_DEV_1(fitsFile, sources, imageHeader, tableHeader, extname); 219 219 ok(rc == true, "pmSourcesWrite_PS1_DEV_1() returned TRUE with acceptable input parameters"); 220 220 psFree(fitsFile);
Note:
See TracChangeset
for help on using the changeset viewer.
