Changeset 33415 for branches/meh_branches/ppstack_test/psModules
- Timestamp:
- Mar 5, 2012, 5:19:48 PM (14 years ago)
- Location:
- branches/meh_branches/ppstack_test
- Files:
-
- 3 deleted
- 65 edited
- 1 copied
-
. (modified) (1 prop)
-
psModules (modified) (1 prop)
-
psModules/src/astrom/pmAstrometryWCS.c (modified) (1 diff)
-
psModules/src/camera/pmReadoutFake.c (modified) (3 diffs)
-
psModules/src/concepts/pmConceptsStandard.c (modified) (1 diff)
-
psModules/src/detrend/pmBias.c (modified) (1 diff)
-
psModules/src/detrend/pmDark.c (modified) (1 diff)
-
psModules/src/detrend/pmFlatField.c (modified) (1 diff)
-
psModules/src/detrend/pmPattern.c (modified) (7 diffs)
-
psModules/src/detrend/pmPattern.h (modified) (1 diff)
-
psModules/src/detrend/pmShutterCorrection.c (modified) (1 diff)
-
psModules/src/imcombine/pmPSFEnvelope.c (modified) (2 diffs)
-
psModules/src/imcombine/pmStackReject.c (modified) (1 diff)
-
psModules/src/imcombine/pmSubtraction.c (modified) (6 diffs)
-
psModules/src/imcombine/pmSubtractionEquation.c (modified) (8 diffs)
-
psModules/src/imcombine/pmSubtractionEquation.v0.c (modified) (1 diff)
-
psModules/src/imcombine/pmSubtractionMatch.c (modified) (8 diffs)
-
psModules/src/imcombine/pmSubtractionStamps.c (modified) (10 diffs)
-
psModules/src/imcombine/pmSubtractionStamps.h (modified) (1 diff)
-
psModules/src/objects (modified) (1 prop)
-
psModules/src/objects/Makefile.am (modified) (2 diffs)
-
psModules/src/objects/mksource.pl (modified) (2 diffs)
-
psModules/src/objects/models/pmModel_DEV.c (modified) (7 diffs)
-
psModules/src/objects/models/pmModel_EXP.c (modified) (6 diffs)
-
psModules/src/objects/models/pmModel_PGAUSS.c (modified) (2 diffs)
-
psModules/src/objects/models/pmModel_PS1_V1.c (modified) (3 diffs)
-
psModules/src/objects/models/pmModel_QGAUSS.c (modified) (2 diffs)
-
psModules/src/objects/models/pmModel_RGAUSS.c (modified) (2 diffs)
-
psModules/src/objects/models/pmModel_SERSIC.CP.h (copied) (copied from trunk/psModules/src/objects/models/pmModel_SERSIC.CP.h )
-
psModules/src/objects/models/pmModel_SERSIC.c (modified) (7 diffs)
-
psModules/src/objects/pmFootprintCullPeaks.c (modified) (2 diffs)
-
psModules/src/objects/pmModelUtils.c (modified) (1 diff)
-
psModules/src/objects/pmMoments.c (modified) (2 diffs)
-
psModules/src/objects/pmMoments.h (modified) (1 diff)
-
psModules/src/objects/pmPCM_MinimizeChisq.c (modified) (6 diffs)
-
psModules/src/objects/pmPCMdata.c (modified) (5 diffs)
-
psModules/src/objects/pmPCMdata.h (modified) (2 diffs)
-
psModules/src/objects/pmPSF.c (modified) (7 diffs)
-
psModules/src/objects/pmPSF.h (modified) (1 diff)
-
psModules/src/objects/pmPeaks.c (modified) (3 diffs)
-
psModules/src/objects/pmPeaks.h (modified) (1 diff)
-
psModules/src/objects/pmSource.c (modified) (7 diffs)
-
psModules/src/objects/pmSource.h (modified) (3 diffs)
-
psModules/src/objects/pmSourceExtendedPars.c (modified) (1 diff)
-
psModules/src/objects/pmSourceExtendedPars.h (modified) (2 diffs)
-
psModules/src/objects/pmSourceFitModel.c (modified) (2 diffs)
-
psModules/src/objects/pmSourceFitPCM.c (modified) (6 diffs)
-
psModules/src/objects/pmSourceIO.c (modified) (6 diffs)
-
psModules/src/objects/pmSourceIO.h (modified) (2 diffs)
-
psModules/src/objects/pmSourceIO_CMF.c.in (modified) (16 diffs)
-
psModules/src/objects/pmSourceIO_CMF_PS1_DV1.c (modified) (2 diffs)
-
psModules/src/objects/pmSourceIO_CMF_PS1_DV2.c (modified) (2 diffs)
-
psModules/src/objects/pmSourceIO_CMF_PS1_SV1.c (modified) (5 diffs)
-
psModules/src/objects/pmSourceIO_CMF_PS1_V1.c (deleted)
-
psModules/src/objects/pmSourceIO_CMF_PS1_V2.c (deleted)
-
psModules/src/objects/pmSourceIO_CMF_PS1_V3.c (deleted)
-
psModules/src/objects/pmSourceIO_CMP.c (modified) (2 diffs)
-
psModules/src/objects/pmSourceIO_OBJ.c (modified) (1 diff)
-
psModules/src/objects/pmSourceIO_PS1_CAL_0.c (modified) (3 diffs)
-
psModules/src/objects/pmSourceIO_PS1_DEV_0.c (modified) (2 diffs)
-
psModules/src/objects/pmSourceIO_PS1_DEV_1.c (modified) (3 diffs)
-
psModules/src/objects/pmSourceIO_SMPDATA.c (modified) (2 diffs)
-
psModules/src/objects/pmSourceIO_SX.c (modified) (1 diff)
-
psModules/src/objects/pmSourceMasks.h (modified) (1 diff)
-
psModules/src/objects/pmSourceMoments.c (modified) (10 diffs)
-
psModules/src/objects/pmSourceOutputs.c (modified) (2 diffs)
-
psModules/src/objects/pmSourceOutputs.h (modified) (1 diff)
-
psModules/src/objects/pmSourcePhotometry.c (modified) (4 diffs)
-
psModules/src/objects/pmSourcePlotPSFModel.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/meh_branches/ppstack_test
- Property svn:mergeinfo changed
-
branches/meh_branches/ppstack_test/psModules
- Property svn:mergeinfo set to
-
branches/meh_branches/ppstack_test/psModules/src/astrom/pmAstrometryWCS.c
r28386 r33415 487 487 488 488 if (fpa->toSky == NULL) { 489 psFree(fpa->toTPA); 490 psFree(fpa->fromTPA); 489 491 fpa->toTPA = psPlaneTransformIdentity (1); 490 492 fpa->fromTPA = psPlaneTransformIdentity (1); -
branches/meh_branches/ppstack_test/psModules/src/camera/pmReadoutFake.c
r29004 r33415 51 51 52 52 psF32 *params = model->params->data.F32; // Model parameters 53 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO ); // Ellipse axes53 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO, model->type); // Ellipse axes 54 54 // Curiously, the minor axis can be larger than the major axis, so need to check. 55 55 if (axes.major >= axes.minor) { … … 58 58 axes.major = axes.minor; 59 59 } 60 return pmPSF_AxesToModel(params, axes );60 return pmPSF_AxesToModel(params, axes, model->type); 61 61 } 62 62 … … 314 314 } 315 315 } 316 if (!psThreadPoolWait(true )) {316 if (!psThreadPoolWait(true, true)) { 317 317 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 318 318 psFree(groups); -
branches/meh_branches/ppstack_test/psModules/src/concepts/pmConceptsStandard.c
r30049 r33415 751 751 bool has_video_cell = false; 752 752 753 if (concept->type != PS_DATA_STRING) { 754 psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Type for %s (%x) is not string\n", 755 concept->name, concept->type); 756 return NULL; 757 } 758 759 char *Vptr = strchr(concept->data.V,'V'); 760 if (Vptr) { 761 has_video_cell = true; 753 if (concept->type == PS_DATA_BOOL) { 754 has_video_cell = concept->data.B; 755 } else { 756 if (concept->type != PS_DATA_STRING) { 757 psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Type for %s (%x) is not string\n", 758 concept->name, concept->type); 759 return NULL; 760 } 761 762 char *Vptr = strchr(concept->data.V,'V'); 763 if (Vptr) { 764 has_video_cell = true; 765 } 762 766 } 763 767 -
branches/meh_branches/ppstack_test/psModules/src/detrend/pmBias.c
r29833 r33415 154 154 if (threaded) { 155 155 // wait here for the threaded jobs to finish 156 if (!psThreadPoolWait(true )) {156 if (!psThreadPoolWait(true, true)) { 157 157 psError(PS_ERR_UNKNOWN, false, "Unable to apply bias correction."); 158 158 return false; -
branches/meh_branches/ppstack_test/psModules/src/detrend/pmDark.c
r28405 r33415 601 601 if (threaded) { 602 602 // wait here for the threaded jobs to finish 603 if (!psThreadPoolWait(true )) {603 if (!psThreadPoolWait(true, true)) { 604 604 psError(PS_ERR_UNKNOWN, false, "Unable to apply dark."); 605 605 psFree(orders); -
branches/meh_branches/ppstack_test/psModules/src/detrend/pmFlatField.c
r28405 r33415 161 161 if (threaded) { 162 162 // wait here for the threaded jobs to finish 163 if (!psThreadPoolWait(true )) {163 if (!psThreadPoolWait(true, true)) { 164 164 psError(PS_ERR_UNKNOWN, false, "Unable to flat-field image."); 165 165 return false; -
branches/meh_branches/ppstack_test/psModules/src/detrend/pmPattern.c
r27676 r33415 6 6 7 7 #include "pmPattern.h" 8 9 #define PATTERN_ROW_BKG_FIX 1 8 10 9 11 … … 89 91 psImageInit(corr, NAN); 90 92 93 #ifdef PATTERN_ROW_BKG_FIX 94 // CZW: 2011-11-30 95 // Define the vectors to hold the "x" and "y" slope trends. 96 // Briefly, the slope trend in the y-axis is a due to variations in the 0-th order term 97 // of the PATTERN.ROW fit between individual rows across the cell. Similarly, the 1-st 98 // order term of the PATTERN.ROW fit defines the trend in the x-axis (as that's what we 99 // are fitting with PATTERN.ROW in the first place). However, the thing we're trying to 100 // fix with PATTERN.ROW is the detector level bias wiggles. These should be overlaid on 101 // the true sky level. Therefore, simply applying the PATTERN.ROW correction will 102 // introduce cell-to-cell sky variations as these two trends are removed. To avoid this, 103 // We store the 0th and 1st order values used for each row, and then fit a polynomial to 104 // these results. By re-adding these systematic trends back, we can remove the row-to-row 105 // variations without improperly removing the real sky trend. 106 psVector *yaxisData = psVectorAlloc(numRows, PS_TYPE_F32); // Data to fit to the constant term 107 psVector *yaxisMask = psVectorAlloc(numRows, PS_TYPE_VECTOR_MASK); // Mask for rows with no fit 108 psVector *xaxisData = psVectorAlloc(numRows, PS_TYPE_F32); // Data to fit to the linear term 109 psVectorInit(yaxisMask, 0); 110 #endif 91 111 for (int y = 0; y < numRows; y++) { 92 112 psVectorInit(clipMask, 0); … … 105 125 // Not enough points to fit 106 126 patternMaskRow(ro, y, maskBad); 127 #ifdef PATTERN_ROW_BKG_FIX 128 // Ignore this row in our subsequent fits, because the fit failed. 129 yaxisMask->data.PS_TYPE_VECTOR_MASK_DATA[y] = 0xFF; 130 #endif 107 131 continue; 108 132 } … … 111 135 psErrorClear(); 112 136 patternMaskRow(ro, y, maskBad); 113 continue; 114 } 115 116 poly->coeff[0] -= background; 137 #ifdef PATTERN_ROW_BKG_FIX 138 // Ignore this row in our subsequent fits, because the fit failed. 139 yaxisMask->data.PS_TYPE_VECTOR_MASK_DATA[y] = 0xFF; 140 #endif 141 continue; 142 } 143 #ifndef PATTERN_ROW_BKG_FIX 144 poly->coeff[0] -= background; 145 #else 146 // Store the results we found for this row. 147 yaxisData->data.F32[y] = poly->coeff[0]; 148 xaxisData->data.F32[y] = poly->coeff[1]; 149 psTrace("pattern",1,"%d %g %g\n",y,poly->coeff[0],poly->coeff[1]); 150 151 // yaxisData->data.F32[y] = 0.0; 152 /* xaxisData->data.F32[y] = 0.0; */ 153 154 #endif 117 155 memcpy(corr->data.F64[y], poly->coeff, (order + 1) * PSELEMTYPE_SIZEOF(PS_TYPE_F64)); 118 156 psVector *solution = psPolynomial1DEvalVector(poly, indices); // Solution vector … … 121 159 psErrorClear(); 122 160 patternMaskRow(ro, y, maskBad); 161 #ifdef PATTERN_ROW_BKG_FIX 162 yaxisMask->data.PS_TYPE_VECTOR_MASK_DATA[y] = 0xFF; 163 #endif 123 164 continue; 124 165 } … … 126 167 for (int x = 0; x < numCols; x++) { 127 168 image->data.F32[y][x] -= solution->data.F32[x]; 169 psTrace("pattern",5,"A: %d %d %g\n",x,y,solution->data.F32[x]); 128 170 } 129 171 psFree(solution); 130 172 } 131 173 174 #ifdef PATTERN_ROW_BKG_FIX 175 // Put the global trends back that were removed by the PATTERN.ROW correction. 176 // Set up the indices for the polynomial 177 psVector *yaxisIndices = psVectorAlloc(numRows, PS_TYPE_F32); 178 norm = 2.0 / (float)numRows; 179 for (int y = 0; y < numRows; y++) { 180 yaxisIndices->data.F32[y] = y * norm - 1.0; 181 psTrace("psModules.detrend.pattern",10,"%d %f %f\n",y,yaxisIndices->data.F32[y],yaxisData->data.F32[y]); 182 } 183 184 // Fit the trend of the constant term, producing the y-axis global trend 185 psStatsInit(clip); 186 psPolynomial1D *yaxisPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 1); // Polynomial to fit. 187 if (!psVectorClipFitPolynomial1D(yaxisPoly,clip,yaxisMask,0xFF,yaxisData, NULL, yaxisIndices)) { 188 psWarning("Unable to fit polynomial to y-axis trend"); 189 psErrorClear(); 190 // If we've failed, we need to do something, so add back in the background level, and 191 // expect that the final image will have background mismatches. 192 for (int y = 0; y < numRows; y++) { 193 for (int x = 0; x < numCols; x++) { 194 image->data.F32[y][x] += background; 195 corr->data.F64[y][0] -= background; 196 } 197 } 198 } 199 else { 200 psVector *solution = psPolynomial1DEvalVector(yaxisPoly,yaxisIndices); 201 if (!solution) { 202 psWarning("Unable to evaluate polynomial"); 203 psErrorClear(); 204 // If we've failed, we need to do something, so add back in the background level, and 205 // expect that the final image will have background mismatches. 206 for (int y = 0; y < numRows; y++) { 207 for (int x = 0; x < numCols; x++) { 208 image->data.F32[y][x] += background; 209 corr->data.F64[y][0] -= background; 210 } 211 } 212 } 213 else { 214 for (int y = 0; y < numRows; y++) { 215 for (int x = 0; x < numCols; x++) { 216 image->data.F32[y][x] += solution->data.F32[y]; 217 corr->data.F64[y][0] -= solution->data.F32[y]; 218 psTrace("pattern",5,"B: %d %d %g\n",x,y,solution->data.F32[x]); 219 } 220 } 221 } 222 psFree(solution); 223 } 224 225 // Fit the trend of the linear term, producing the x-axis global trend 226 // We can use the same mask vector, as the same rows failed the row-fit earlier. 227 psStatsInit(clip); 228 psPolynomial1D *xaxisPoly = psPolynomial1DAlloc(PS_POLYNOMIAL_ORD, 1); // Polynomial to fit. 229 if (!psVectorClipFitPolynomial1D(xaxisPoly,clip,yaxisMask,0xFF,xaxisData, NULL, yaxisIndices)) { 230 psWarning("Unable to fit polynomial to x-axis trend"); 231 psErrorClear(); 232 } 233 else { 234 psVector *solution = psPolynomial1DEvalVector(xaxisPoly,yaxisIndices); 235 if (!solution) { 236 psWarning("Unable to evaluate polynomial"); 237 psErrorClear(); 238 } 239 else { 240 for (int y = 0; y < numRows; y++) { 241 for (int x = 0; x < numCols; x++) { 242 image->data.F32[y][x] += solution->data.F32[y] * indices->data.F32[x]; 243 corr->data.F64[y][1] -= solution->data.F32[y] ; 244 psTrace("pattern",5,"C: %d %d %g %g\n",x,y,solution->data.F32[x],indices->data.F32[x]); 245 } 246 } 247 } 248 psFree(solution); 249 } 250 psFree(yaxisPoly); 251 psFree(xaxisPoly); 252 psFree(yaxisIndices); 253 psFree(yaxisMask); 254 psFree(yaxisData); 255 psFree(xaxisData); 256 // End PATTERN_ROW_BKG_FIX global trend replacement 257 #endif 258 132 259 psMetadataAddImage(ro->analysis, PS_LIST_TAIL, PM_PATTERN_ROW_CORRECTION, PS_META_REPLACE, 133 260 "Pattern row correction", corr); … … 382 509 383 510 511 512 bool pmPatternContinuity(pmChip *chip, const psVector *tweak, psStatsOptions bgStat, psStatsOptions cellStat, 513 psImageMaskType maskVal, psImageMaskType maskBad, int edgeWidth) 514 { 515 PS_ASSERT_PTR_NON_NULL(chip, false); 516 PS_ASSERT_VECTOR_NON_NULL(tweak, false); 517 PS_ASSERT_VECTOR_SIZE(tweak, chip->cells->n, false); 518 PS_ASSERT_VECTOR_TYPE(tweak, PS_TYPE_U8, false); 519 520 int numCells = tweak->n; // Number of cells 521 522 psVector *meanMask = psVectorAlloc(numCells, PS_TYPE_VECTOR_MASK); // Mask for means 523 psVectorInit(meanMask, 0); 524 525 // Mask bits 526 enum { 527 PM_PATTERN_IGNORE = 0x01, // Ignore this cell 528 PM_PATTERN_TWEAK = 0x02, // Tweak this cell 529 PM_PATTERN_ERROR = 0x04, // Error in calculating background 530 PM_PATTERN_ALL = 0xFF, // All causes 531 }; 532 533 // Count number of cells to tweak 534 int numTweak = 0; // Number of cells to tweak 535 int numIgnore = 0; // Number of cells to ignore 536 for (int i = 0; i < numCells; i++) { 537 pmCell *cell = chip->cells->data[i]; // Cell of interest 538 if (!cell || !cell->data_exists || !cell->process || 539 cell->readouts->n == 0 || cell->readouts->n > 1 || !cell->readouts->data[0]) { 540 numIgnore++; 541 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_IGNORE; 542 continue; 543 } 544 if (tweak->data.U8[i]) { 545 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PM_PATTERN_TWEAK; 546 numTweak++; 547 } 548 } 549 if (numTweak == 0) { 550 // Nothing to do 551 psFree(meanMask); 552 return true; 553 } 554 555 // Measure mean of each cell edge, and use that to determine the cell offsets. 556 557 psStats *bgStats = psStatsAlloc(bgStat); // Statistics on background 558 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 559 560 psRegion region = {0,0,0,0}; 561 562 /* These images hold the edge data for the OTA structure. */ 563 psImage *A = psImageAlloc(8,8,PS_TYPE_F64); // Top edge 564 psImage *B = psImageAlloc(8,8,PS_TYPE_F64); // Bottom edge 565 psImage *C = psImageAlloc(8,8,PS_TYPE_F64); // Right edge 566 psImage *D = psImageAlloc(8,8,PS_TYPE_F64); // Left edge 567 psImageInit(A,0.0); 568 psImageInit(B,0.0); 569 psImageInit(C,0.0); 570 psImageInit(D,0.0); 571 572 for (int i = 0; i < numCells; i++) { 573 if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) { 574 continue; 575 } 576 pmCell *cell = chip->cells->data[i]; // Cell of interest 577 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 578 579 psStatsInit(bgStats); 580 581 // Convert cell iterator i into an xy coordinate on the grid of cells 582 int y = (i % 8); 583 int x = (i - y) / 8; 584 585 for (int j = 0; j < 4; j++) { 586 if (j == 0) { // Region B 587 region = psRegionSet(0,ro->image->numCols, 588 0,edgeWidth); 589 } 590 else if (j == 1) { // Region A 591 region = psRegionSet(0,ro->image->numCols, 592 ro->image->numRows - edgeWidth,ro->image->numRows); 593 } 594 else if (j == 2) { // Region D 595 region = psRegionSet(0,edgeWidth, 596 0,ro->image->numRows); 597 } 598 else if (j == 3) { // Region C 599 region = psRegionSet(ro->image->numCols - edgeWidth,ro->image->numCols, 600 0,ro->image->numRows); 601 } 602 psImage *subset = psImageSubset(ro->image,region); 603 psImage *submask = psImageSubset(ro->mask,region); 604 605 if (!psImageBackground(bgStats, NULL, subset, submask, maskVal, rng)) { 606 psWarning("Unable to measure background for cell %d on edge %d\n", i, j); 607 psErrorClear(); 608 meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PM_PATTERN_ERROR; 609 if (j == 0) { B->data.F64[y][x] = NAN; } 610 else if (j == 1) { A->data.F64[y][x] = NAN; } 611 else if (j == 2) { C->data.F64[y][x] = NAN; } 612 else if (j == 3) { D->data.F64[y][x] = NAN; } 613 psFree(subset); 614 psFree(submask); 615 continue; // Move on to next edge, as only part of this cell may be a problem 616 } 617 618 // If the returned value is zero, assume something is wrong. Do I still need this? 619 if (psStatsGetValue(bgStats,bgStat) < 1e-6) { 620 if (j == 0) { B->data.F64[y][x] = NAN; } 621 else if (j == 1) { A->data.F64[y][x] = NAN; } 622 else if (j == 2) { C->data.F64[y][x] = NAN; } 623 else if (j == 3) { D->data.F64[y][x] = NAN; } 624 } 625 // If we have an error for this cell/edge, make sure we mask the value 626 if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_ERROR) { 627 if (j == 0) { B->data.F64[y][x] = NAN; } 628 else if (j == 1) { A->data.F64[y][x] = NAN; } 629 else if (j == 2) { C->data.F64[y][x] = NAN; } 630 else if (j == 3) { D->data.F64[y][x] = NAN; } 631 } 632 else { // Set the value to match what we got from the edge box. 633 if (j == 0) { B->data.F64[y][x] = psStatsGetValue(bgStats,bgStat); } 634 else if (j == 1) { A->data.F64[y][x] = psStatsGetValue(bgStats,bgStat); } 635 else if (j == 2) { C->data.F64[y][x] = psStatsGetValue(bgStats,bgStat); } 636 else if (j == 3) { D->data.F64[y][x] = psStatsGetValue(bgStats,bgStat); } 637 } 638 639 for (int u = 0; u < subset->numCols; u++) { 640 for (int v = 0; v < subset->numRows; v++) { 641 psTrace("psModules.detrend.cont",10,"BOX: %d %d (%d %d) (%d %d) %f %d", 642 i,j,x,y,u,v,subset->data.F32[v][u],submask->data.PS_TYPE_IMAGE_MASK_DATA[v][u]); 643 } 644 } 645 646 psFree(subset); 647 psFree(submask); 648 649 } 650 psTrace("psModules.detrend.cont",5, "OTA: %d (%d %d) A: %f B: %f C: %f D: %f", 651 i,x,y, 652 A->data.F64[y][x],B->data.F64[y][x],C->data.F64[y][x],D->data.F64[y][x]); 653 } 654 psFree(bgStats); 655 psFree(rng); 656 657 // We've now allocated all the edge values, so we can now minimize the offsets. 658 // This involves solving the equation A x = b, where 659 // A is the (64x64 for GPC1) matrix containing the edges that match for each cell 660 // x is the solution vector 661 // b is the combination of offsets across each cell boundary for each cell. 662 // Below "XX" is used as the matrix A, and "solution" is used as both b and x 663 // (due to the way psMatrixLUSolve operates). 664 psVector *solution = psVectorAlloc(64,PS_TYPE_F64); 665 psImage *XX = psImageAlloc(64,64,PS_TYPE_F64); 666 psVectorInit(solution,0.0); 667 psImageInit(XX,0.0); 668 669 for (int i = 0; i < numCells; i++) { 670 // Accumulate all the possible edge differences we can for this cell. 671 // As we do so, make a note of the correlations by incrementing the element of the matrix. 672 int y = (i % 8); 673 int x = (i - y) / 8; 674 int j; 675 double critical_value = 0.0; 676 if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) { 677 continue; 678 } 679 if (x + 1 < 8) { // We have a neighbor adjacent in the +x direction 680 j = 8 * (x + 1) + y; // Determine that neighbor's index 681 if (fabs(C->data.F64[y][x]) > fabs(D->data.F64[y][x+1])) { 682 critical_value = 2.0 * fabs(D->data.F64[y][x+1]); 683 } 684 else { 685 critical_value = 2.0 * fabs(C->data.F64[y][x]); 686 } 687 if (critical_value < 25) { critical_value = 25; } 688 psTrace("psModules.detrend.cont",5,"CmD %d %d %d %d %g %g %g", // diagnostic 689 i,x,y,j, 690 C->data.F64[y][x], 691 D->data.F64[y][x+1], 692 critical_value 693 ); 694 if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_PATTERN_IGNORE)&& // If there are no errors with the neighbor, 695 (isfinite(C->data.F64[y][x]))&&(isfinite(D->data.F64[y][x+1]))&& // and all edges have valid values, 696 (fabs(C->data.F64[y][x] - D->data.F64[y][x+1]) < critical_value) // and there are no large discontinuities, 697 ) { 698 solution->data.F64[i] += C->data.F64[y][x] - D->data.F64[y][x+1]; // Take the difference 699 XX->data.F64[i][i] += 1; // increment our relation with ourself 700 XX->data.F64[i][j] += -1; // decrement our relation with the neighbor 701 } 702 } 703 if (x - 1 > -1) { // etc. 704 j = 8 * (x - 1) + y; 705 if (fabs(C->data.F64[y][x-1]) > fabs(D->data.F64[y][x])) { 706 critical_value = 2.0 * fabs(D->data.F64[y][x]); 707 } 708 else { 709 critical_value = 2.0 * fabs(C->data.F64[y][x-1]); 710 } 711 if (critical_value < 25) { critical_value = 25; } 712 psTrace("psModules.detrend.cont",5,"DmC %d %d %d %d %g %g %g", 713 i,x,y,j, 714 D->data.F64[y][x], 715 C->data.F64[y][x-1], 716 critical_value 717 ); 718 719 if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_PATTERN_IGNORE)&& 720 (isfinite(D->data.F64[y][x]))&&(isfinite(C->data.F64[y][x-1]))&& 721 (fabs(D->data.F64[y][x] - C->data.F64[y][x-1]) < critical_value) 722 ) { 723 solution->data.F64[i] += D->data.F64[y][x] - C->data.F64[y][x-1]; 724 XX->data.F64[i][i] += 1; 725 XX->data.F64[i][j] += -1; 726 } 727 } 728 if (y + 1 < 8) { 729 j = 8 * x + (y + 1); 730 psTrace("psModules.detrend.cont",5,"AmB %d %d %d %d %g %g", 731 i,x,y,j, 732 A->data.F64[y][x], 733 B->data.F64[y+1][x] 734 ); 735 if (fabs(A->data.F64[y][x]) > fabs(B->data.F64[y+1][x])) { 736 critical_value = 2.0 * fabs(B->data.F64[y+1][x]); 737 } 738 else { 739 critical_value = 2.0 * fabs(A->data.F64[y][x]); 740 } 741 if (critical_value < 25) { critical_value = 25; } 742 if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_PATTERN_IGNORE)&& 743 (isfinite(A->data.F64[y][x]))&&(isfinite(B->data.F64[y+1][x]))&& 744 (fabs(A->data.F64[y][x] - B->data.F64[y+1][x]) < critical_value) 745 ) { 746 solution->data.F64[i] += A->data.F64[y][x] - B->data.F64[y+1][x]; 747 XX->data.F64[i][i] += 1; 748 XX->data.F64[i][j] += -1; 749 } 750 } 751 if (y - 1 > -1) { 752 j = 8 * x + (y - 1); 753 psTrace("psModules.detrend.cont",5,"BmA %d %d %d %d %g %g", 754 i,x,y,j, 755 B->data.F64[y][x], 756 A->data.F64[y-1][x] 757 ); 758 if (fabs(A->data.F64[y-1][x]) > fabs(B->data.F64[y][x])) { 759 critical_value = 2.0 * fabs(B->data.F64[y][x]); 760 } 761 else { 762 critical_value = 2.0 * fabs(A->data.F64[y-1][x]); 763 } 764 if (critical_value < 25) { critical_value = 25; } 765 if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_PATTERN_IGNORE)&& 766 (isfinite(B->data.F64[y][x]))&&(isfinite(A->data.F64[y-1][x]))&& 767 (fabs(B->data.F64[y][x] - A->data.F64[y-1][x]) < critical_value) 768 ) { 769 solution->data.F64[i] += B->data.F64[y][x] - A->data.F64[y-1][x]; 770 XX->data.F64[i][i] += 1; 771 XX->data.F64[i][j] += -1; 772 } 773 } 774 } 775 double max_XX = 0; 776 double solution_V = 0; 777 int i_peak = -1; 778 for (int i = 0; i < numCells; i++) { // If any cells have no value of themself, set the matrix to 1.0. 779 if (XX->data.F64[i][i] == 0.0) { 780 XX->data.F64[i][i] = 1.0; 781 } 782 if (XX->data.F64[i][i] > max_XX) { 783 max_XX = XX->data.F64[i][i]; 784 solution_V = solution->data.F64[i]; 785 i_peak = i; 786 } 787 } 788 psTrace("psModules.detrend.cont",5,"fixed point: %d %g\n", 789 i_peak,solution_V); 790 791 for (int i = 0; i < numCells; i++) { 792 /* if (!((XX->data.F64[i][i] == 1.0)&& */ 793 /* (solution->data.F64[i] == 0.0))) { */ 794 solution->data.F64[i] -= solution_V; 795 if (i != i_peak) { 796 for (int j = 0; j < numCells; j++) { 797 XX->data.F64[i][j] -= XX->data.F64[i_peak][j]; 798 } 799 } 800 /* } */ 801 } 802 for (int i = 0; i < numCells; i++) { 803 XX->data.F64[i_peak][i] = 0.0; 804 } 805 XX->data.F64[i_peak][i_peak] = 1.0; 806 807 808 #if (1) 809 for (int i = 0; i < numCells; i++) { // print matrix A 810 psTrace("psModules.detrend.cont",5,"A: %3d % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f % 2.0f", 811 i, 812 XX->data.F64[i][0], XX->data.F64[i][1], XX->data.F64[i][2], XX->data.F64[i][3], 813 XX->data.F64[i][4], XX->data.F64[i][5], XX->data.F64[i][6], XX->data.F64[i][7], 814 XX->data.F64[i][8], XX->data.F64[i][9], XX->data.F64[i][10], XX->data.F64[i][11], 815 XX->data.F64[i][12], XX->data.F64[i][13], XX->data.F64[i][14], XX->data.F64[i][15], 816 XX->data.F64[i][16], XX->data.F64[i][17], XX->data.F64[i][18], XX->data.F64[i][19], 817 XX->data.F64[i][20], XX->data.F64[i][21], XX->data.F64[i][22], XX->data.F64[i][23], 818 XX->data.F64[i][24], XX->data.F64[i][25], XX->data.F64[i][26], XX->data.F64[i][27], 819 XX->data.F64[i][28], XX->data.F64[i][29], XX->data.F64[i][30], XX->data.F64[i][31], 820 XX->data.F64[i][32], XX->data.F64[i][33], XX->data.F64[i][34], XX->data.F64[i][35], 821 XX->data.F64[i][36], XX->data.F64[i][37], XX->data.F64[i][38], XX->data.F64[i][39], 822 XX->data.F64[i][40], XX->data.F64[i][41], XX->data.F64[i][42], XX->data.F64[i][43], 823 XX->data.F64[i][44], XX->data.F64[i][45], XX->data.F64[i][46], XX->data.F64[i][47], 824 XX->data.F64[i][48], XX->data.F64[i][49], XX->data.F64[i][50], XX->data.F64[i][51], 825 XX->data.F64[i][52], XX->data.F64[i][53], XX->data.F64[i][54], XX->data.F64[i][55], 826 XX->data.F64[i][56], XX->data.F64[i][57], XX->data.F64[i][58], XX->data.F64[i][59], 827 XX->data.F64[i][60], XX->data.F64[i][61], XX->data.F64[i][62], XX->data.F64[i][63] 828 ); 829 } 830 831 for (int i = 0; i < numCells; i++) { // print vector b 832 psTrace("psModules.detrend.cont",5,"b: %d %f", 833 i, 834 solution->data.F64[i] 835 ); 836 } 837 #endif 838 839 // Solve the Ax=b equation 840 // psMatrixLUSolve(XX,solution); 841 psMatrixGJSolve(XX,solution); 842 #if (1) 843 for (int i = 0; i < numCells; i++) { // print vector b 844 psTrace("psModules.detrend.cont",5,"x: %d %f", 845 i, 846 solution->data.F64[i] 847 ); 848 } 849 #endif 850 851 /* old code to remove the minimum solution value from the set, to give a "minimal set of offsets." Mathematically unnecessary. */ 852 /* double min = 99e99; */ 853 /* for (int i = 0; i < numCells; i++) { */ 854 /* if (solution->data.F64[i] < min) { */ 855 /* min = solution->data.F64[i]; */ 856 /* } */ 857 /* psTrace("psModules.detrend.cont",5,"x: %d %f %f ", */ 858 /* i, */ 859 /* solution->data.F64[i],min */ 860 /* ); */ 861 /* } */ 862 /* for (int i = 0; i < numCells; i++) { */ 863 /* if (solution->data.F64[i] != 0.0) { */ 864 /* solution->data.F64[i] -= min; */ 865 /* } */ 866 /* } */ 867 868 // Cleanup 869 psFree(XX); 870 psFree(A); 871 psFree(B); 872 psFree(C); 873 psFree(D); 874 875 // Correct cells based on the offsets calculated, and store the result in the analysis metadata. 876 for (int i = 0; i < numCells; i++) { 877 if (meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_IGNORE) { 878 continue; 879 } 880 if (!(meanMask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PM_PATTERN_TWEAK)) { 881 continue; 882 } 883 pmCell *cell = chip->cells->data[i]; // Cell of interest 884 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 885 886 float correction = solution->data.F64[i]; 887 const char *cellName = psMetadataLookupStr(NULL, cell->concepts, "CELL.NAME"); // Name of cell 888 psLogMsg("psModules.detrend", PS_LOG_DETAIL, "Correcting background of cell %s by %f", 889 cellName, correction); 890 psBinaryOp(ro->image, ro->image, "-", psScalarAlloc(correction, PS_TYPE_F32)); 891 psMetadataAddF32(ro->analysis, PS_LIST_TAIL, PM_PATTERN_CELL_CORRECTION, PS_META_REPLACE, 892 "Pattern cell correction solution", correction); 893 } 894 895 psFree(solution); 896 psFree(meanMask); 897 898 return true; 899 } 900 901 bool pmPatternContinuityApply(pmReadout *ro, psImageMaskType maskBad) 902 { 903 PM_ASSERT_READOUT_NON_NULL(ro, false); 904 PM_ASSERT_READOUT_IMAGE(ro, false); 905 906 bool mdok; // Status of MD lookup 907 float corr = psMetadataLookupF32(&mdok, ro->analysis, PM_PATTERN_CELL_CORRECTION); // Correction to apply 908 if (!mdok) { 909 // No correction to apply 910 return true; 911 } 912 913 psImage *image = ro->image, *mask = ro->mask; // Image and mask of interest 914 int numCols = image->numCols, numRows = image->numRows; // Size of image 915 916 if (!isfinite(corr)) { 917 for (int y = 0; y < numRows; y++) { 918 for (int x = 0; x < numCols; x++) { 919 image->data.F32[y][x] = NAN; 920 } 921 } 922 if (mask) { 923 for (int y = 0; y < numRows; y++) { 924 for (int x = 0; x < numCols; x++) { 925 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= maskBad; 926 } 927 } 928 } 929 } else { 930 for (int y = 0; y < numRows; y++) { 931 for (int x = 0; x < numCols; x++) { 932 image->data.F32[y][x] += corr; 933 } 934 } 935 } 936 937 return true; 938 } 939 940 -
branches/meh_branches/ppstack_test/psModules/src/detrend/pmPattern.h
r26893 r33415 54 54 ); 55 55 56 /// Fix the background on cells known to be troublesome 57 bool pmPatternContinuity( 58 pmChip *chip, ///< Chip to correct 59 const psVector *tweak, ///< U8 vector indicating whether to tweak the corresponding cell 60 psStatsOptions bgStat, ///< Statistic to use for background measurement 61 psStatsOptions cellStat, ///< Statistic to use for combination of cell background measurements 62 psImageMaskType maskVal, ///< Mask value to use 63 psImageMaskType maskBad, ///< Mask value to give bad pixels 64 int edgeWidth ///< Size of box to use 65 ); 66 67 /// Apply previously measured cell pattern correction 68 bool pmPatternContinuityApply(pmReadout *ro, ///< Readout to correct 69 psImageMaskType maskBad ///< Mask value to give bad pixels 70 ); 71 72 56 73 57 74 /// @} -
branches/meh_branches/ppstack_test/psModules/src/detrend/pmShutterCorrection.c
r29004 r33415 805 805 if (threaded) { 806 806 // wait here for the threaded jobs to finish 807 if (!psThreadPoolWait(true )) {807 if (!psThreadPoolWait(true, true)) { 808 808 psError(PS_ERR_UNKNOWN, false, "Unable to apply shutter correction."); 809 809 psFree(shutterImage); -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmPSFEnvelope.c
r31451 r33415 36 36 37 37 38 //#define TESTING // Enable test output38 #define TESTING // Enable test output 39 39 // #define PEAK_NORM // Normalise peaks? 40 40 #define PEAK_FLUX 1.0e4 // Peak flux for each source … … 380 380 381 381 // measure the source moments: tophat windowing, no pixel S/N cutoff 382 if (!pmSourceMoments(source, maxRadius, 0. 0, 0.0, 0.0, maskVal)) {382 if (!pmSourceMoments(source, maxRadius, 0.25*maxRadius, 0.0, 0.0, maskVal)) { 383 383 // Can't do anything about it; limp along as best we can 384 384 psErrorClear(); -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmStackReject.c
r31435 r33415 313 313 } 314 314 315 if (!psThreadPoolWait(false )) {315 if (!psThreadPoolWait(false, true)) { 316 316 psError(psErrorCodeLast(), false, "Unable to grow bad pixels."); 317 317 psFree(source); -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmSubtraction.c
r30738 r33415 905 905 } 906 906 } 907 if (!psThreadPoolWait(true )) {907 if (!psThreadPoolWait(true, true)) { 908 908 psError(psErrorCodeLast(), false, "Error waiting for threads."); 909 909 return false; … … 1019 1019 } 1020 1020 } 1021 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "red"); 1021 1022 psString ds9text = NULL; 1023 1024 psStringAppend(&ds9text, "flux: %.0f ", match->fluxes->data.F32[i]); 1025 psStringAppend(&ds9text, "chi2: %.0f ", match->chisq->data.F32[i]); 1026 1027 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "red", ds9text); 1028 1029 psFree(ds9text); 1022 1030 1023 1031 // Set stamp for replacement … … 1041 1049 } else { 1042 1050 numGood++; 1043 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "green"); 1051 1052 //MEH bad way to do this - should also add to rej/red one as well 1053 // -- is match from subQuality what want? 1054 psString ds9text = NULL; 1055 1056 psStringAppend(&ds9text, "flux: %.0f ", match->fluxes->data.F32[i]); 1057 psStringAppend(&ds9text, "chi2: %.0f ", match->chisq->data.F32[i]); 1058 1059 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "green", ds9text); 1060 1061 psFree(ds9text); 1044 1062 } 1045 1063 } … … 1427 1445 } 1428 1446 1429 if (!psThreadPoolWait(false )) {1447 if (!psThreadPoolWait(false, true)) { 1430 1448 psError(psErrorCodeLast(), false, "Error waiting for threads."); 1431 1449 return false; … … 1487 1505 } 1488 1506 } 1507 psFree(out1->covariance); 1489 1508 out1->covariance = psImageCovarianceAverage(covars); 1490 1509 psFree(covars); … … 1527 1546 } 1528 1547 } 1548 psFree(out2->covariance); 1529 1549 out2->covariance = psImageCovarianceAverage(covars); 1530 1550 psFree(covars); -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmSubtractionEquation.c
r30622 r33415 796 796 stamp->normSquare1 = normSquare1; 797 797 stamp->normSquare2 = normSquare2; 798 799 // psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "normValue: %f %f %f (%f %f)\n", normI1, normI2, stamp->norm, normSquare1, normSquare2);798 799 //psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "normValue: %f %f %f (%f %f)\n", normI1, normI2, stamp->norm, normSquare1, normSquare2); 800 800 801 801 return true; … … 958 958 } 959 959 960 if (!psThreadPoolWait(true )) {960 if (!psThreadPoolWait(true, true)) { 961 961 psError(psErrorCodeLast(), false, "Error waiting for threads."); 962 962 return false; … … 1037 1037 (void)psBinaryOp(sumVector, sumVector, "+", stamp->vector); 1038 1038 1039 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "green" );1039 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "green", ""); 1040 1040 numStamps++; 1041 1041 } else if (stamp->status == PM_SUBTRACTION_STAMP_REJECTED) { 1042 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "red" );1042 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "red", ""); 1043 1043 } 1044 1044 } … … 1139 1139 normSquare2 += stamp->normSquare2; 1140 1140 1141 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "green" );1141 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "green", ""); 1142 1142 numStamps++; 1143 1143 } else if (stamp->status == PM_SUBTRACTION_STAMP_REJECTED) { 1144 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "red" );1144 pmSubtractionStampPrint(ds9, stamp->x, stamp->y, stamps->footprint, "red", ""); 1145 1145 } 1146 1146 } … … 1382 1382 float Myy = fluxY2 / fluxC1; 1383 1383 1384 //MEH uncomment and update 1384 1385 // fprintf (stderr, "conv1, flux2: %f, Mx: %f, My: %f, Mxx: %f, Myy: %f, chisq: %f, npix: %d\n", flux2, Mx, My, Mxx, Myy, chisq, npix); 1386 //fprintf (stderr, "conv1, flux2: %f, fluxC1: %f, Mxx: %f, Myy: %f, chisqR: %f, npix: %d\n", flux2, fluxC1, Mxx, Myy, chisqR, npix); 1387 1385 1388 moment += Mxx + Myy; 1386 1389 } … … 1554 1557 residual->kernel[y][x] = difference->kernel[y][x] - convolved1->kernel[y][x]; 1555 1558 convolved1->kernel[y][x] += source->kernel[y][x] * norm; 1559 //MEH 1560 //psLogMsg("psModules.imcombine", PS_LOG_INFO, "xy: %d %d, norm: %6.3f, bg: %6.3f, difference: %6.3f, target: %6.3f, source: %6.3f, residual: %6.3f, convolved1: %6.3f \n",x,y,norm,background,difference->kernel[y][x],target->kernel[y][x],source->kernel[y][x],residual->kernel[y][x],convolved1->kernel[y][x]); 1561 1556 1562 } 1557 1563 } … … 1652 1658 } else { 1653 1659 sumKernel2 = 1.0; 1654 } 1660 //MEH 1661 sumKernel2 = 0.001; 1662 } 1663 //MEH if sumKernel2 not use essentially, then not need to be 2.0*? but level of orderFactor may need to be adjusted then 1655 1664 1656 1665 // if we modify the chisq value by the (sumKernel1 + sumKernel2), we account for the … … 1658 1667 // penalized by increasing the score somewhat. the 0.01 value is not well-chosen. 1659 1668 float orderFactor = 0.01 * kernels->spatialOrder; 1660 float score = 2.0 * chisqRValue / (sumKernel1 + sumKernel2) + orderFactor; 1661 psLogMsg("psModules.imcombine", PS_LOG_INFO, "chisq: %6.3f, chisqD: %6.3f, moment: %6.3f, sumKernel_1: %6.3f, sumKernel_2, score: %6.3f: %6.3f\n", chisqRValue, chisqDValue, momentValue, sumKernel1, sumKernel2, score); 1669 //MEH 1670 //float score = 2.0 * chisqRValue / (sumKernel1 + sumKernel2) + orderFactor; 1671 float score = 2.0 * chisqRValue / (sqrt(sumKernel1) + sqrt(sumKernel2)) + orderFactor; 1672 psLogMsg("psModules.imcombine", PS_LOG_INFO, "chisq: %6.3f, chisqD: %6.3f, moment: %6.3f, sumKernel_1: %6.3f, sumKernel_2: %6.3f, score: %6.3f\n", chisqRValue, chisqDValue, momentValue, sumKernel1, sumKernel2, score); 1662 1673 1663 1674 // save this result if it is the first or the best (skip if bestMatch is NULL) -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmSubtractionEquation.v0.c
r30622 r33415 882 882 } 883 883 884 if (!psThreadPoolWait(true )) {884 if (!psThreadPoolWait(true, true)) { 885 885 psError(psErrorCodeLast(), false, "Error waiting for threads."); 886 886 return false; -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmSubtractionMatch.c
r31671 r33415 29 29 static bool useFFT = true; // Do convolutions using FFT 30 30 31 //#define TESTING32 //#define TESTING_MEMORY31 #define TESTING 32 #define TESTING_MEMORY 33 33 34 34 // Output memory usage information … … 538 538 // Where does our variance map come from? 539 539 // Getting the variance exactly right is not necessary --- it's just used for weighting. 540 // MEH - helpful to have one used output to log -- at some level want log output for most every step 541 540 542 psImage *variance = NULL; // Variance image to use 541 543 if (ro1->variance && ro2->variance) { 542 544 variance = (psImage*)psBinaryOp(NULL, ro1->variance, "+", ro2->variance); 545 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "TESTING:SubMatch variance avail: var1+var2"); 543 546 } else if (ro1->variance) { 544 547 variance = psMemIncrRefCounter(ro1->variance); 548 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "TESTING:SubMatch variance avail: var1"); 545 549 } else if (ro2->variance) { 546 550 variance = psMemIncrRefCounter(ro2->variance); 551 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "TESTING:SubMatch variance avail: var2"); 547 552 } else { 548 553 variance = (psImage*)psBinaryOp(NULL, ro1->image, "+", ro2->image); 549 } 554 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "TESTING:SubMatch variance avail: none ro1+ro2"); 555 } 556 550 557 551 558 // Putting important variable declarations here, since they are freed after a "goto" if there is an error. … … 726 733 float radMoment1 = stamps->normWindow1 / 2.75; 727 734 float radMoment2 = stamps->normWindow2 / 2.75; 735 //MEH - FWHM vs radialMoment need *2? may mess up other parts 736 //float radMoment1 = stamps->normWindow1 / 2.75*2; 737 //float radMoment2 = stamps->normWindow2 / 2.75*2; 728 738 pmSubtractionParamsScale(NULL, NULL, isisWidths, radMoment1, radMoment2); 729 739 … … 810 820 } 811 821 } 812 822 //MEH probably should comment out but should be ok? 813 823 // step 0 : calculate the normalizations, pass along to the next steps via stamps->normValue 814 824 psTrace("psModules.imcombine", 3, "Calculating normalization...\n"); … … 825 835 for (int order = 0; order <= N_TEST_ORDER; order++) { 826 836 for (int j = 0; j < N_TEST_MODES; j++) { 837 //MEH: thinking pmSubtractionCalculateNormalization needs to be called here for conv source 838 // per mode 839 //psTrace("psModules.imcombine", 3, "Calculating normalization...order: %d mode: %d\n",order,j); 840 // if (!pmSubtractionCalculateNormalization(stamps, TestModes[j])) { 841 // psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 842 // goto MATCH_ERROR; 843 //} 844 // 827 845 if (!pmSubtractionMatchAttempt(&bestMatch, kernels, stamps, TestModes[j], order, false)) { 828 846 goto MATCH_ERROR; … … 843 861 // apply the best fit so we are ready to roll 844 862 psLogMsg("psModules.imcombine", PS_LOG_INFO, "applying order: %d, mode: %d\n", bestMatch->spatialOrder, bestMatch->mode); 863 //MEH need to call normalization one more time for final/best run - 864 // but what if dual - already checked for in pmSubtractionCalculateNormalization 865 //if (!pmSubtractionCalculateNormalization(stamps, bestMatch->mode)) { 866 // psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 867 // goto MATCH_ERROR; 868 //} 869 // 845 870 if (!pmSubtractionMatchAttempt(NULL, kernels, stamps, bestMatch->mode, bestMatch->spatialOrder, true)) { 846 871 goto MATCH_ERROR; … … 1091 1116 } 1092 1117 1093 if (!psThreadPoolWait(true )) {1118 if (!psThreadPoolWait(true, true)) { 1094 1119 psError(psErrorCodeLast(), false, "Error waiting for threads."); 1095 1120 psFree(models); … … 1331 1356 *stampSize = *stampSize * scale + 0.5; 1332 1357 } 1333 1358 //MEH 1359 psLogMsg("psModules.imcombine", PS_LOG_INFO, "TESTING Scaling kernel parameters fwhm1,2,refscale/min/max: %f %f %f %f %f", fwhm1,fwhm2,scaleRefOption,scaleMinOption,scaleMaxOption); 1334 1360 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Scaling kernel parameters by %f", scale); 1335 1361 if (kernelSize) psLogMsg("psModules.imcombine", PS_LOG_INFO, " modified kernel size %d", *kernelSize); -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmSubtractionStamps.c
r31543 r33415 127 127 continue; 128 128 } 129 //MEH hack to limit bright end test 130 // if ((image1 && image1->data.F32[y][x] > 2000) || 131 // (image2 && image2->data.F32[y][x] > 2000 )) { 132 // fprintf (stderr, "%f,%f : thresh\n",image1->data.F32[y][x],image2->data.F32[y][x]); 133 // continue; 134 // } 129 135 130 136 if (subMask && subMask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & … … 188 194 } 189 195 190 void pmSubtractionStampPrint(FILE *ds9, float x, float y, float size, const char *color) 196 // MEH adding text to ds9 197 void pmSubtractionStampPrint(FILE *ds9, float x, float y, float size, const char *color, const char *ds9text) 191 198 { 192 199 if (!ds9regions || !ds9) { … … 196 203 if (color && strlen(color) > 0) { 197 204 fprintf(ds9, " # color=%s", color); 205 } 206 if (ds9text && strlen(ds9text) > 0) { 207 fprintf(ds9, " text={%s}", ds9text); 198 208 } 199 209 fprintf(ds9, "\n"); … … 486 496 normFrac, sysErr, skyErr); 487 497 } 488 498 //MEH - stamps.dat will repeatedly be overwritten - out to trace may be btter -- see end for summary 489 499 // XXX TEST : dump all stars in the stamps here 490 if ( 0) {500 if (1) { 491 501 FILE *f = fopen ("stamp.dat", "w"); 492 502 for (int i = 0; i < stamps->num; i++) { … … 589 599 stamp->status = PM_SUBTRACTION_STAMP_FOUND; 590 600 numFound++; 591 psTrace("psModules.imcombine", 5, "Found stamp in subregion %d: %d,%d\n", 592 i, (int)stamp->x, (int)stamp->y); 601 // psTrace("psModules.imcombine", 5, "Found stamp in subregion %d: %d,%d\n", 602 // i, (int)stamp->x, (int)stamp->y); 603 //MEH adding int flux to say something about the source 604 psTrace("psModules.imcombine", 5, "Found stamp in subregion %d: %d,%d Flux: %d\n", 605 i, (int)stamp->x, (int)stamp->y, (int)stamp->flux); 593 606 } else { 594 607 stamp->status = PM_SUBTRACTION_STAMP_NONE; … … 666 679 psTrace("psModules.imcombine", 9, "Rejecting input stamp (%d,%d) because outside region", 667 680 xPix, yPix); 668 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "red" );681 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "red", ""); 669 682 continue; 670 683 } 671 684 //MEH - are all using -0.5? seen some seem shifted 672 685 // fprintf (stderr, "stamp: %5.1f %5.1f == %d %d\n", xStamp, yStamp, xPix, yPix); 673 686 … … 692 705 psTrace("psModules.imcombine", 9, "Putting input stamp (%d,%d) into subregion %d", 693 706 xPix, yPix, j); 694 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "green" );707 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "green", ""); 695 708 } 696 709 } … … 699 712 psTrace("psModules.imcombine", 9, "Unable to find subregion for stamp (%d,%d)", 700 713 xPix, yPix); 701 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "yellow" );714 pmSubtractionStampPrint(ds9, xPix, yPix, footprint, "yellow", ""); 702 715 } 703 716 } … … 865 878 } 866 879 } 867 868 #if 0880 //MEH 881 #if 1 869 882 { 870 883 psFits *fits = NULL; … … 1156 1169 float sysErr = 0.25 * PS_SQR(stamps->sysErr); // Systematic error 1157 1170 float skyErr = stamps->skyErr; 1171 //MEH - image2 not used if not adding to additional.. also these are never freed here, but upstream/downstream? 1158 1172 psKernel *image1 = stamp->image1, *image2 = stamp->image2; // Input images 1173 //psKernel *image2 = stamp->image2; // Input images 1159 1174 for (int y = -size; y <= size; y++) { 1160 1175 for (int x = -size; x <= size; x++) { 1176 //MEH -- if conv to model then what does sys and weight mean for both? 1177 // w1+w2 vs 1/var1+1/var2.. depends on what the weight is for? 1178 // why additional ^2? 1161 1179 float additional = image1->kernel[y][x] + image2->kernel[y][x]; 1162 weight->kernel[y][x] = 1.0 / (skyErr + var->kernel[y][x] + sysErr * PS_SQR(additional)); 1180 //float additional = image2->kernel[y][x]; 1181 // weight->kernel[y][x] = 1.0 / (skyErr + var->kernel[y][x] + sysErr * PS_SQR(additional)); 1182 weight->kernel[y][x] = 1.0 / (skyErr + 1000.0*var->kernel[y][x] + sysErr * PS_SQR(additional)); 1163 1183 } 1164 1184 } 1185 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "TESTING:: Stamp %d (%.1f,%.1f) weight: %f var: %.1f sysErr: %.2f im1: %.0f im2: %.0f \n", 1186 i, stamp->x, stamp->y, weight->kernel[0][0],var->kernel[0][0],sysErr,image2->kernel[0][0],image1->kernel[0][0]); 1187 1165 1188 } else { 1166 1189 for (int y = -size; y <= size; y++) { 1167 1190 for (int x = -size; x <= size; x++) { 1168 weight->kernel[y][x] = 1.0 / var->kernel[y][x]; 1191 // weight->kernel[y][x] = 1.0 / var->kernel[y][x]; 1192 weight->kernel[y][x] = 1.0 / (1000.0*var->kernel[y][x]); 1169 1193 } 1170 1194 } -
branches/meh_branches/ppstack_test/psModules/src/imcombine/pmSubtractionStamps.h
r30622 r33415 163 163 float x, float y, ///< Position of stamp 164 164 float size,///< Size of circle 165 const char *color ///< Colour 165 const char *color, ///< Colour 166 const char *ds9text ///< info text 166 167 ); 167 168 // MEH added text to ds9 file 168 169 169 170 bool pmSubtractionStampsResetStatus (pmSubtractionStampList *stamps); -
branches/meh_branches/ppstack_test/psModules/src/objects
- Property svn:ignore
-
old new 5 5 *.la 6 6 *.lo 7 pmSourceIO_CMF_PS1_V1.c 8 pmSourceIO_CMF_PS1_V2.c 9 pmSourceIO_CMF_PS1_V3.c 10 pmSourceIO_CMF_PS1_V4.c 11 pmSourceIO_CMF_PS1_V3.v1.c 12 pmSourceIO_CMF_PS1_V1.v1.c 13 pmSourceIO_CMF_PS1_V2.v1.c 14
-
- Property svn:ignore
-
branches/meh_branches/ppstack_test/psModules/src/objects/Makefile.am
r31670 r33415 45 45 pmSourceIO_CMF_PS1_V2.c \ 46 46 pmSourceIO_CMF_PS1_V3.c \ 47 pmSourceIO_CMF_PS1_V4.c \ 47 48 pmSourceIO_CMF_PS1_SV1.c \ 48 49 pmSourceIO_CMF_PS1_DV1.c \ … … 130 131 131 132 # pmSourceID_CMF_* functions use a common framework 132 BUILT_SOURCES = pmSourceIO_CMF_PS1_V1. v1.c pmSourceIO_CMF_PS1_V2.v1.c pmSourceIO_CMF_PS1_V3.v1.c133 BUILT_SOURCES = pmSourceIO_CMF_PS1_V1.c pmSourceIO_CMF_PS1_V2.c pmSourceIO_CMF_PS1_V3.c pmSourceIO_CMF_PS1_V4.c 133 134 134 pmSourceIO_CMF_PS1_V1. v1.c : pmSourceIO_CMF.c.in mksource.pl135 mksource.pl pmSourceIO_CMF.c.in PS1_V1 pmSourceIO_CMF_PS1_V1. v1.c135 pmSourceIO_CMF_PS1_V1.c : pmSourceIO_CMF.c.in mksource.pl 136 mksource.pl pmSourceIO_CMF.c.in PS1_V1 pmSourceIO_CMF_PS1_V1.c 136 137 137 pmSourceIO_CMF_PS1_V2. v1.c : pmSourceIO_CMF.c.in mksource.pl138 mksource.pl pmSourceIO_CMF.c.in PS1_V2 pmSourceIO_CMF_PS1_V2. v1.c138 pmSourceIO_CMF_PS1_V2.c : pmSourceIO_CMF.c.in mksource.pl 139 mksource.pl pmSourceIO_CMF.c.in PS1_V2 pmSourceIO_CMF_PS1_V2.c 139 140 140 pmSourceIO_CMF_PS1_V3.v1.c : pmSourceIO_CMF.c.in mksource.pl 141 mksource.pl pmSourceIO_CMF.c.in PS1_V2 pmSourceIO_CMF_PS1_V3.v1.c 141 pmSourceIO_CMF_PS1_V3.c : pmSourceIO_CMF.c.in mksource.pl 142 mksource.pl pmSourceIO_CMF.c.in PS1_V3 pmSourceIO_CMF_PS1_V3.c 143 144 pmSourceIO_CMF_PS1_V4.c : pmSourceIO_CMF.c.in mksource.pl 145 mksource.pl pmSourceIO_CMF.c.in PS1_V4 pmSourceIO_CMF_PS1_V4.c 142 146 143 147 # EXTRA_DIST = pmErrorCodes.h.in pmErrorCodes.dat pmErrorCodes.c.in -
branches/meh_branches/ppstack_test/psModules/src/objects/mksource.pl
r31670 r33415 14 14 15 15 # see if we can add in PS1_DV* and PS1_SV* as well... 16 @cmfmodes = ("PS1_V1", 1,16 %cmfmodes = ("PS1_V1", 1, 17 17 "PS1_V2", 2, 18 "PS1_V3", 3); 18 "PS1_V3", 3, 19 "PS1_V4", 4); 20 21 print "1: $cmfmodes{1}\n"; 22 print "PS1_V1: $cmfmodes{'PS1_V1'}\n"; 19 23 20 24 open (FILE, "$template") || die "failed to open template $template\n"; … … 50 54 51 55 if ($gtMode) { 56 # print "gtMode : $line\n"; 52 57 $thisLevel = $cmfmodes{$gtMode}; 53 58 $myLevel = $cmfmodes{$cmfmode}; 54 if ($thisLevel <= $myLevel) { next; } 55 $line =~ s|\@<\S*\@\s*||; 59 print "gtMode : $gtMode vs $cmfmode, $thisLevel, $myLevel\n"; 60 if ($myLevel <= $thisLevel) { next; } 61 $line =~ s|\@>\S*\@\s*||; 56 62 } 57 63 58 64 if ($ltMode) { 65 # print "ltMode : $line\n"; 59 66 $thisLevel = $cmfmodes{$ltMode}; 60 67 $myLevel = $cmfmodes{$cmfmode}; 61 if ($thisLevel >= $myLevel) { next; } 62 $line =~ s|\@>\S*\@\s*||; 68 print "ltMode : $ltMode vs $cmfmode, $thisLevel, $myLevel\n"; 69 if ($myLevel >= $thisLevel) { next; } 70 $line =~ s|\@<\S*\@\s*||; 63 71 } 64 72 -
branches/meh_branches/ppstack_test/psModules/src/objects/models/pmModel_DEV.c
r31451 r33415 89 89 static bool limitsApply = true; // Apply limits? 90 90 91 # include "pmModel_SERSIC.CP.h" 92 91 93 psF32 PM_MODEL_FUNC (psVector *deriv, 92 94 const psVector *params, … … 94 96 { 95 97 psF32 *PAR = params->data.F32; 96 97 float index = 0.5 / ALPHA;98 float bn = 1.9992*index - 0.3271;99 float Io = exp(bn);100 98 101 99 psF32 X = pixcoord->data.F32[0] - PAR[PM_PAR_XPOS]; … … 105 103 psF32 z = (PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y); 106 104 107 assert (z >= 0); 105 // If the elliptical contour is defined in a valid way, we should never trigger this 106 // assert. Other models (like PGAUSS) don't use fractional powers, and thus do not have 107 // NaN values for negative values of z 108 psAssert (z >= 0, "do not allow negative z values in model"); 109 110 float index = 0.5 / ALPHA; 111 float par7 = ALPHA; 112 float bn = 1.9992*index - 0.3271; 113 float Io = exp(bn); 108 114 109 115 psF32 f2 = bn*pow(z,ALPHA); 110 116 psF32 f1 = Io*exp(-f2); 117 118 psF32 radius = hypot(X, Y); 119 if (radius < 1.0) { 120 121 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 122 123 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 124 psEllipseShape shape; 125 126 shape.sx = PAR[PM_PAR_SXX]; 127 shape.sy = PAR[PM_PAR_SYY]; 128 shape.sxy = PAR[PM_PAR_SXY]; 129 130 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 131 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 132 133 // get the central pixel flux from the lookup table 134 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 135 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 136 float yPix = (index - centralPixelYo) / centralPixeldY; 137 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 138 139 // the integral of a Sersic has an analytical form as follows: 140 float logGamma = lgamma(2.0*index); 141 float bnFactor = pow(bn, 2.0*index); 142 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 143 144 // XXX interpolate to get the value 145 // XXX for the moment, just integerize 146 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 147 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 148 149 float px1 = 1.0 / PAR[PM_PAR_SXX]; 150 float py1 = 1.0 / PAR[PM_PAR_SYY]; 151 float z10 = PS_SQR(px1); 152 float z01 = PS_SQR(py1); 153 154 // which pixels do we need for this interpolation? 155 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 156 if ((X >= 0) && (Y >= 0)) { 157 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 158 float V00 = Vcenter; 159 float V10 = Io*exp(-bn*pow(z10,par7)); 160 float V01 = Io*exp(-bn*pow(z01,par7)); 161 float V11 = Io*exp(-bn*pow(z11,par7)); 162 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 163 } 164 if ((X < 0) && (Y >= 0)) { 165 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 166 float V00 = Io*exp(-bn*pow(z10,par7)); 167 float V10 = Vcenter; 168 float V01 = Io*exp(-bn*pow(z11,par7)); 169 float V11 = Io*exp(-bn*pow(z01,par7)); 170 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 171 } 172 if ((X >= 0) && (Y < 0)) { 173 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 174 float V00 = Io*exp(-bn*pow(z01,par7)); 175 float V10 = Io*exp(-bn*pow(z11,par7)); 176 float V01 = Vcenter; 177 float V11 = Io*exp(-bn*pow(z10,par7)); 178 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 179 } 180 if ((X < 0) && (Y < 0)) { 181 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 182 float V00 = Io*exp(-bn*pow(z11,par7)); 183 float V10 = Io*exp(-bn*pow(z10,par7)); 184 float V01 = Io*exp(-bn*pow(z01,par7)); 185 float V11 = Vcenter; 186 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 187 } 188 } 189 111 190 psF32 z0 = PAR[PM_PAR_I0]*f1; 112 191 psF32 f0 = PAR[PM_PAR_SKY] + z0; … … 120 199 psF32 *dPAR = deriv->data.F32; 121 200 201 dPAR[PM_PAR_SKY] = +1.0; 202 dPAR[PM_PAR_I0] = +2.0*f1; // XXX extra damping.. 203 122 204 // gradient is infinite for z = 0; saturate at z = 0.01 123 205 psF32 z1 = (z < 0.01) ? z0*bn*ALPHA*pow(0.01,ALPHA - 1.0) : z0*bn*ALPHA*pow(z,ALPHA - 1.0); 124 125 dPAR[PM_PAR_SKY] = +1.0;126 dPAR[PM_PAR_I0] = +2.0*f1;127 206 128 207 assert (isfinite(z1)); … … 223 302 224 303 // set the shape parameters 304 // XXX adjust this? 225 305 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 226 306 return false; … … 246 326 } 247 327 328 // A DeVaucouleur model is equivalent to a Sersic with index = 4.0 248 329 psF64 PM_MODEL_FLUX (const psVector *params) 249 330 { 250 float z, norm;251 331 psEllipseShape shape; 252 332 253 333 psF32 *PAR = params->data.F32; 254 334 255 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;256 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;335 shape.sx = PAR[PM_PAR_SXX]; 336 shape.sy = PAR[PM_PAR_SYY]; 257 337 shape.sxy = PAR[PM_PAR_SXY]; 258 338 259 // Area is equivalent to 2 pi sigma^2339 // for a non-circular DeVaucouleur, the flux of the Rmajor equivalent is scaled by the AspectRatio 260 340 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 261 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 262 263 // the area needs to be multiplied by the integral of f(z) 264 norm = 0.0; 265 266 # define DZ 0.25 267 268 float f0 = 1.0; 269 float f1, f2; 270 for (z = DZ; z < 150; z += DZ) { 271 f1 = exp(-pow(z,ALPHA)); 272 z += DZ; 273 f2 = exp(-pow(z,ALPHA)); 274 norm += f0 + 4*f1 + f2; 275 f0 = f2; 276 } 277 norm *= DZ / 3.0; 278 279 psF64 Flux = PAR[PM_PAR_I0] * Area * norm; 341 float AspectRatio = axes.minor / axes.major; 342 343 float index = 4.0; 344 float bn = 1.9992*index - 0.3271; 345 346 // the integral of a Sersic has an analytical form as follows: 347 float logGamma = lgamma(2.0*index); 348 float bnFactor = pow(bn, 2.0*index); 349 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 350 351 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 280 352 281 353 return(Flux); … … 297 369 return (1.0); 298 370 299 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;300 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;371 shape.sx = PAR[PM_PAR_SXX]; 372 shape.sy = PAR[PM_PAR_SYY]; 301 373 shape.sxy = PAR[PM_PAR_SXY]; 302 374 -
branches/meh_branches/ppstack_test/psModules/src/objects/models/pmModel_EXP.c
r31451 r33415 81 81 static bool limitsApply = true; // Apply limits? 82 82 83 # include "pmModel_SERSIC.CP.h" 84 83 85 psF32 PM_MODEL_FUNC (psVector *deriv, 84 86 const psVector *params, … … 93 95 psF32 z = PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y; 94 96 95 // XXX if the elliptical contour is defined in valid way, this step should not be required. 96 // other models (like PGAUSS) don't use fractional powers, and thus do not have NaN values 97 // for negative values of z 98 // XXX use an assert here to force the elliptical parameters to be correctly determined 99 // if (z < 0) z = 0; 100 assert (z >= 0); 101 102 psF32 f2 = sqrt(z); 103 psF32 f1 = exp(-f2); 97 // If the elliptical contour is defined in a valid way, we should never trigger this 98 // assert. Other models (like PGAUSS) don't use fractional powers, and thus do not have 99 // NaN values for negative values of z 100 psAssert (z >= 0, "do not allow negative z values in model"); 101 102 float index = 1.0; 103 float par7 = 0.5; 104 float bn = 1.9992*index - 0.3271; 105 float Io = exp(bn); 106 107 psF32 f2 = bn*sqrt(z); 108 psF32 f1 = Io*exp(-f2); 109 110 psF32 radius = hypot(X, Y); 111 if (radius < 1.0) { 112 113 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 114 115 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 116 psEllipseShape shape; 117 118 shape.sx = PAR[PM_PAR_SXX]; 119 shape.sy = PAR[PM_PAR_SYY]; 120 shape.sxy = PAR[PM_PAR_SXY]; 121 122 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 123 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 124 125 // get the central pixel flux from the lookup table 126 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 127 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 128 float yPix = (index - centralPixelYo) / centralPixeldY; 129 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 130 131 // the integral of a Sersic has an analytical form as follows: 132 float logGamma = lgamma(2.0*index); 133 float bnFactor = pow(bn, 2.0*index); 134 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 135 136 // XXX interpolate to get the value 137 // XXX for the moment, just integerize 138 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 139 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 140 141 float px1 = 1.0 / PAR[PM_PAR_SXX]; 142 float py1 = 1.0 / PAR[PM_PAR_SYY]; 143 float z10 = PS_SQR(px1); 144 float z01 = PS_SQR(py1); 145 146 // which pixels do we need for this interpolation? 147 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 148 if ((X >= 0) && (Y >= 0)) { 149 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 150 float V00 = Vcenter; 151 float V10 = Io*exp(-bn*pow(z10,par7)); 152 float V01 = Io*exp(-bn*pow(z01,par7)); 153 float V11 = Io*exp(-bn*pow(z11,par7)); 154 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 155 } 156 if ((X < 0) && (Y >= 0)) { 157 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 158 float V00 = Io*exp(-bn*pow(z10,par7)); 159 float V10 = Vcenter; 160 float V01 = Io*exp(-bn*pow(z11,par7)); 161 float V11 = Io*exp(-bn*pow(z01,par7)); 162 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 163 } 164 if ((X >= 0) && (Y < 0)) { 165 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 166 float V00 = Io*exp(-bn*pow(z01,par7)); 167 float V10 = Io*exp(-bn*pow(z11,par7)); 168 float V01 = Vcenter; 169 float V11 = Io*exp(-bn*pow(z10,par7)); 170 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 171 } 172 if ((X < 0) && (Y < 0)) { 173 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 174 float V00 = Io*exp(-bn*pow(z11,par7)); 175 float V10 = Io*exp(-bn*pow(z10,par7)); 176 float V01 = Io*exp(-bn*pow(z01,par7)); 177 float V11 = Vcenter; 178 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 179 } 180 } 181 104 182 psF32 z0 = PAR[PM_PAR_I0]*f1; 105 183 psF32 f0 = PAR[PM_PAR_SKY] + z0; … … 118 196 // gradient is infinite for z = 0; saturate at z = 0.01 119 197 // z1 is -df/dz (the negative sign is canceled by most of dz/dPAR[i] 120 psF32 z1 = (z < 0.01) ? 0.5* z0/sqrt(0.01) : 0.5*z0/sqrt(z);198 psF32 z1 = (z < 0.01) ? 0.5*bn*z0/sqrt(0.01) : 0.5*bn*z0/sqrt(z); 121 199 122 200 // XXX dampen SXX and SYY as in GAUSS? … … 216 294 217 295 // set the shape parameters 296 // XXX adjust this? 218 297 if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) { 219 298 return false; … … 233 312 } 234 313 314 // An exponential model is equivalent to a Sersic with index = 1.0 235 315 psF64 PM_MODEL_FLUX (const psVector *params) 236 316 { 237 float z, norm;238 317 psEllipseShape shape; 239 318 240 319 psF32 *PAR = params->data.F32; 241 320 242 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;243 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;321 shape.sx = PAR[PM_PAR_SXX]; 322 shape.sy = PAR[PM_PAR_SYY]; 244 323 shape.sxy = PAR[PM_PAR_SXY]; 245 324 246 // Area is equivalent to 2 pi sigma^2325 // for a non-circular Exponential, the flux of the Rmajor equivalent is scaled by the AspectRatio 247 326 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 248 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 249 250 // the area needs to be multiplied by the integral of f(z) = exp(-sqrt(z)) [0 to infinity] 251 norm = 0.0; 252 253 # define DZ 0.25 254 255 float f0 = 1.0; 256 float f1, f2; 257 for (z = DZ; z < 150; z += DZ) { 258 f1 = exp(-sqrt(z)); 259 z += DZ; 260 f2 = exp(-sqrt(z)); 261 norm += f0 + 4*f1 + f2; 262 f0 = f2; 263 } 264 norm *= DZ / 3.0; 265 266 psF64 Flux = PAR[PM_PAR_I0] * Area * norm; 327 float AspectRatio = axes.minor / axes.major; 328 329 float index = 1.0; 330 float bn = 1.9992*index - 0.3271; 331 332 // the integral of a Sersic has an analytical form as follows: 333 float logGamma = lgamma(2.0*index); 334 float bnFactor = pow(bn, 2.0*index); 335 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 336 337 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 267 338 268 339 return(Flux); … … 284 355 return (1.0); 285 356 286 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;287 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;357 shape.sx = PAR[PM_PAR_SXX]; 358 shape.sy = PAR[PM_PAR_SYY]; 288 359 shape.sxy = PAR[PM_PAR_SXY]; 289 360 -
branches/meh_branches/ppstack_test/psModules/src/objects/models/pmModel_PGAUSS.c
r31451 r33415 217 217 } 218 218 219 psF64 PM_MODEL_FLUX(const psVector *params) 220 { 221 float norm, z; 219 // integrate the model to get the full flux 220 psF64 PM_MODEL_FLUX (const psVector *params) 221 { 222 float z, norm; 222 223 psEllipseShape shape; 223 224 … … 228 229 shape.sxy = PAR[PM_PAR_SXY]; 229 230 230 // Area is equivalent to 2 pi sigma^2231 231 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 232 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;233 234 // the area needs to be multiplied by the integral of f(z)232 float AspectRatio = axes.minor / axes.major; 233 234 // flux = 2 \pi \int f(r) r dr 235 235 norm = 0.0; 236 236 237 # define DZ 0.25 238 239 float f0 = 1.0; 237 # define DR 0.25 238 239 // f = f(r) * r 240 float f0 = 0.0; 240 241 float f1, f2; 241 for (z = DZ; z < 150; z += DZ) { 242 f1 = 1.0 / (1 + z + z*z/2.0 + z*z*z/6.0); 243 z += DZ; 244 f2 = 1.0 / (1 + z + z*z/2.0 + z*z*z/6.0); 242 for (float r = DR; r < 150; r += DR) { 243 z = 0.5 * PS_SQR(r / axes.major); 244 f1 = r / (1 + z + z*z/2.0 + z*z*z/6.0); 245 r += DR; 246 z = 0.5 * PS_SQR(r / axes.major); 247 f2 = r / (1 + z + z*z/2.0 + z*z*z/6.0); 245 248 norm += f0 + 4*f1 + f2; 246 249 f0 = f2; 247 250 } 248 norm *= D Z/ 3.0;249 250 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;251 norm *= DR / 3.0; 252 253 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 251 254 252 255 return(Flux); -
branches/meh_branches/ppstack_test/psModules/src/objects/models/pmModel_PS1_V1.c
r31670 r33415 14 14 * PM_PAR_XPOS 2 - X center of object 15 15 * PM_PAR_YPOS 3 - Y center of object 16 * PM_PAR_SXX 4 - X^2 term of elliptical contour ( sqrt(2) / SigmaX)17 * PM_PAR_SYY 5 - Y^2 term of elliptical contour ( sqrt(2) / SigmaY)16 * PM_PAR_SXX 4 - X^2 term of elliptical contour (SigmaX / sqrt(2)) 17 * PM_PAR_SYY 5 - Y^2 term of elliptical contour (SigmaY / sqrt(2)) 18 18 * PM_PAR_SXY 6 - X*Y term of elliptical contour 19 19 * PM_PAR_7 7 - amplitude of the linear component (k) … … 239 239 } 240 240 241 // integrate the model to get the full flux 241 242 psF64 PM_MODEL_FLUX (const psVector *params) 242 243 { … … 250 251 shape.sxy = PAR[PM_PAR_SXY]; 251 252 252 // Area is equivalent to 2 pi sigma^2253 253 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 254 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;255 256 // the area needs to be multiplied by the integral of f(z)254 float AspectRatio = axes.minor / axes.major; 255 256 // flux = 2 \pi \int f(r) r dr 257 257 norm = 0.0; 258 258 259 # define DZ 0.25 260 261 float f0 = 1.0; 259 # define DR 0.25 260 261 // f = f(r) * r 262 float f0 = 0.0; 262 263 float f1, f2; 263 for (z = DZ; z < 150; z += DZ) { 264 f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 265 z += DZ; 266 f2 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 264 for (float r = DR; r < 150; r += DR) { 265 z = 0.5 * PS_SQR(r / axes.major); 266 f1 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 267 r += DR; 268 z = 0.5 * PS_SQR(r / axes.major); 269 f2 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 267 270 norm += f0 + 4*f1 + f2; 268 271 f0 = f2; 269 272 } 270 norm *= D Z/ 3.0;271 272 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;273 norm *= DR / 3.0; 274 275 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 273 276 274 277 return(Flux); -
branches/meh_branches/ppstack_test/psModules/src/objects/models/pmModel_QGAUSS.c
r31670 r33415 240 240 } 241 241 242 // integrate the model to get the full flux 242 243 psF64 PM_MODEL_FLUX (const psVector *params) 243 244 { … … 251 252 shape.sxy = PAR[PM_PAR_SXY]; 252 253 253 // Area is equivalent to 2 pi sigma^2254 254 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 255 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;256 257 // the area needs to be multiplied by the integral of f(z)255 float AspectRatio = axes.minor / axes.major; 256 257 // flux = 2 \pi \int f(r) r dr 258 258 norm = 0.0; 259 259 260 # define DZ 0.25 261 262 float f0 = 1.0; 260 # define DR 0.25 261 262 // f = f(r) * r 263 float f0 = 0.0; 263 264 float f1, f2; 264 for (z = DZ; z < 150; z += DZ) { 265 f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 266 z += DZ; 267 f2 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 265 for (float r = DR; r < 150; r += DR) { 266 z = 0.5 * PS_SQR(r / axes.major); 267 f1 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 268 r += DR; 269 z = 0.5 * PS_SQR(r / axes.major); 270 f2 = r / (1 + PAR[PM_PAR_7]*z + pow(z, ALPHA)); 268 271 norm += f0 + 4*f1 + f2; 269 272 f0 = f2; 270 273 } 271 norm *= D Z/ 3.0;272 273 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;274 norm *= DR / 3.0; 275 276 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 274 277 275 278 return(Flux); -
branches/meh_branches/ppstack_test/psModules/src/objects/models/pmModel_RGAUSS.c
r31451 r33415 229 229 } 230 230 231 // integrate the model to get the full flux 231 232 psF64 PM_MODEL_FLUX (const psVector *params) 232 233 { 233 float norm, z;234 float z, norm; 234 235 psEllipseShape shape; 235 236 … … 240 241 shape.sxy = PAR[PM_PAR_SXY]; 241 242 242 // Area is equivalent to 2 pi sigma^2243 243 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 244 psF64 Area = 2.0 * M_PI * axes.major * axes.minor;245 246 // the area needs to be multiplied by the integral of f(z)244 float AspectRatio = axes.minor / axes.major; 245 246 // flux = 2 \pi \int f(r) r dr 247 247 norm = 0.0; 248 248 249 # define DZ 0.25 250 251 float f0 = 1.0; 249 # define DR 0.25 250 251 // f = f(r) * r 252 float f0 = 0.0; 252 253 float f1, f2; 253 for (z = DZ; z < 150; z += DZ) { 254 f1 = 1.0 / (1 + z + pow(z, PAR[PM_PAR_7])); 255 z += DZ; 256 f2 = 1.0 / (1 + z + pow(z, PAR[PM_PAR_7])); 254 for (float r = DR; r < 150; r += DR) { 255 z = 0.5 * PS_SQR(r / axes.major); 256 f1 = r / (1 + z + pow(z, PAR[PM_PAR_7])); 257 r += DR; 258 z = 0.5 * PS_SQR(r / axes.major); 259 f2 = r / (1 + z + pow(z, PAR[PM_PAR_7])); 257 260 norm += f0 + 4*f1 + f2; 258 261 f0 = f2; 259 262 } 260 norm *= D Z/ 3.0;261 262 psF64 Flux = PAR[PM_PAR_I0] * Area * norm;263 norm *= DR / 3.0; 264 265 psF64 Flux = PAR[PM_PAR_I0] * norm * 2.0 * M_PI * AspectRatio; 263 266 264 267 return(Flux); -
branches/meh_branches/ppstack_test/psModules/src/objects/models/pmModel_SERSIC.c
r31451 r33415 13 13 * PM_PAR_XPOS 2 - X center of object 14 14 * PM_PAR_YPOS 3 - Y center of object 15 * PM_PAR_SXX 4 - X^2 term of elliptical contour ( sqrt(2) / SigmaX)16 * PM_PAR_SYY 5 - Y^2 term of elliptical contour ( sqrt(2) / SigmaY)15 * PM_PAR_SXX 4 - X^2 term of elliptical contour (SigmaX / sqrt(2)) 16 * PM_PAR_SYY 5 - Y^2 term of elliptical contour (SigmaY / sqrt(2)) 17 17 * PM_PAR_SXY 6 - X*Y term of elliptical contour 18 18 * PM_PAR_7 7 - normalized sersic parameter 19 20 * note that a Sersic model is usually defined in terms of R_e, the half-light radius. This 21 construction does not include a factor of 2 in the X^2 term, etc, like for a Gaussian. 22 Conversion from SXX, SYY, SXY to R_major, R_minor, theta can be done by using setting: 23 shape.sx = SXX / sqrt(2), shape.sy = SYY / sqrt(2), shape.sxy = SXY, then calling 24 psEllipseShapeToAxes, and multiplying the values of axes.major, axes.minor by sqrt(2) 19 25 20 26 note that a standard sersic model uses exp(-K*(z^(1/2n) - 1). the additional elements (K, … … 85 91 static bool limitsApply = true; // Apply limits? 86 92 93 # include "pmModel_SERSIC.CP.h" 94 87 95 psF32 PM_MODEL_FUNC (psVector *deriv, 88 96 const psVector *params, … … 97 105 psF32 z = PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y; 98 106 99 // XXX if the elliptical contour is defined in valid way, this step should not be required. 100 // other models (like PGAUSS) don't use fractional powers, and thus do not have NaN values 101 // for negative values of z 102 // XXX use an assert here to force the elliptical parameters to be correctly determined 103 // if (z < 0) z = 0; 104 assert (z >= 0); 107 // If the elliptical contour is defined in a valid way, we should never trigger this 108 // assert. Other models (like PGAUSS) don't use fractional powers, and thus do not have 109 // NaN values for negative values of z 110 psAssert (z >= 0, "do not allow negative z values in model"); 105 111 106 112 float index = 0.5 / PAR[PM_PAR_7]; 113 float par7 = PAR[PM_PAR_7]; 107 114 float bn = 1.9992*index - 0.3271; 108 115 float Io = exp(bn); 109 116 110 psF32 f2 = bn*pow(z, PAR[PM_PAR_7]);117 psF32 f2 = bn*pow(z,par7); 111 118 psF32 f1 = Io*exp(-f2); 119 120 psF32 radius = hypot(X, Y); 121 if (radius < 1.0) { 122 123 // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center 124 125 // first, use Rmajor and index to find the central pixel flux (fraction of total flux) 126 psEllipseShape shape; 127 128 shape.sx = PAR[PM_PAR_SXX]; 129 shape.sy = PAR[PM_PAR_SYY]; 130 shape.sxy = PAR[PM_PAR_SXY]; 131 132 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 133 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 134 135 // get the central pixel flux from the lookup table 136 float xPix = (axes.major - centralPixelXo) / centralPixeldX; 137 xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1); 138 float yPix = (index - centralPixelYo) / centralPixeldY; 139 yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1); 140 141 // the integral of a Sersic has an analytical form as follows: 142 float logGamma = lgamma(2.0*index); 143 float bnFactor = pow(bn, 2.0*index); 144 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 145 146 // XXX interpolate to get the value 147 // XXX for the moment, just integerize 148 // XXX I need to multiply by the integrated flux to get the flux in the central pixel 149 float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm; 150 151 float px1 = 1.0 / PAR[PM_PAR_SXX]; 152 float py1 = 1.0 / PAR[PM_PAR_SYY]; 153 float z10 = PS_SQR(px1); 154 float z01 = PS_SQR(py1); 155 156 // which pixels do we need for this interpolation? 157 // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...) 158 if ((X >= 0) && (Y >= 0)) { 159 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 160 float V00 = Vcenter; 161 float V10 = Io*exp(-bn*pow(z10,par7)); 162 float V01 = Io*exp(-bn*pow(z01,par7)); 163 float V11 = Io*exp(-bn*pow(z11,par7)); 164 f1 = interpolatePixels(V00, V10, V01, V11, X, Y); 165 } 166 if ((X < 0) && (Y >= 0)) { 167 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 168 float V00 = Io*exp(-bn*pow(z10,par7)); 169 float V10 = Vcenter; 170 float V01 = Io*exp(-bn*pow(z11,par7)); 171 float V11 = Io*exp(-bn*pow(z01,par7)); 172 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y); 173 } 174 if ((X >= 0) && (Y < 0)) { 175 float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative 176 float V00 = Io*exp(-bn*pow(z01,par7)); 177 float V10 = Io*exp(-bn*pow(z11,par7)); 178 float V01 = Vcenter; 179 float V11 = Io*exp(-bn*pow(z10,par7)); 180 f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y)); 181 } 182 if ((X < 0) && (Y < 0)) { 183 float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive 184 float V00 = Io*exp(-bn*pow(z11,par7)); 185 float V10 = Io*exp(-bn*pow(z10,par7)); 186 float V01 = Io*exp(-bn*pow(z01,par7)); 187 float V11 = Vcenter; 188 f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y)); 189 } 190 } 191 112 192 psF32 z0 = PAR[PM_PAR_I0]*f1; 113 193 psF32 f0 = PAR[PM_PAR_SKY] + z0; … … 121 201 psF32 *dPAR = deriv->data.F32; 122 202 123 // gradient is infinite for z = 0; saturate at z = 0.01124 psF32 z1 = (z < 0.01) ? z0*bn*PAR[PM_PAR_7]*pow(0.01,PAR[PM_PAR_7] - 1.0) : z0*bn*PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7] - 1.0);125 126 203 dPAR[PM_PAR_SKY] = +1.0; 127 204 dPAR[PM_PAR_I0] = +f1; 128 dPAR[PM_PAR_7] = (z < 0.01) ? -z0*pow(0.01,PAR[PM_PAR_7])*log(0.01) : -z0*f2*log(z); 205 206 // gradient is infinite for z = 0; saturate at z = 0.01 207 psF32 z1 = (z < 0.01) ? z0*bn*par7*pow(0.01,par7 - 1.0) : z0*bn*par7*pow(z,par7 - 1.0); 208 209 dPAR[PM_PAR_7] = (z < 0.01) ? -z0*pow(0.01,par7)*log(0.01) : -z0*f2*log(z); 129 210 dPAR[PM_PAR_7] *= 3.0; 130 211 … … 269 350 float Io = exp(0.5*bn); 270 351 271 // XXX do we need this factor of sqrt(2)?272 // float Sxx = PS_MAX(0.5, M_SQRT2*shape.sx);273 // float Syy = PS_MAX(0.5, M_SQRT2*shape.sy);274 275 352 float Sxx = PS_MAX(0.5, shape.sx); 276 353 float Syy = PS_MAX(0.5, shape.sy); … … 294 371 } 295 372 373 // A sersic model has an integral flux which can be analytically represented 296 374 psF64 PM_MODEL_FLUX (const psVector *params) 297 375 { 298 float z, norm;299 376 psEllipseShape shape; 300 377 301 378 psF32 *PAR = params->data.F32; 302 379 303 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;304 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;380 shape.sx = PAR[PM_PAR_SXX]; 381 shape.sy = PAR[PM_PAR_SYY]; 305 382 shape.sxy = PAR[PM_PAR_SXY]; 306 383 307 // Area is equivalent to 2 pi sigma^2384 // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio 308 385 psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0); 309 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 310 311 // the area needs to be multiplied by the integral of f(z) 312 norm = 0.0; 313 314 # define DZ 0.25 315 316 float f0 = 1.0; 317 float f1, f2; 318 for (z = DZ; z < 150; z += DZ) { 319 // f1 = 1.0 / (1 + PAR[PM_PAR_7]*z + pow(z, 2.25)); 320 f1 = exp(-pow(z,PAR[PM_PAR_7])); 321 z += DZ; 322 f2 = exp(-pow(z,PAR[PM_PAR_7])); 323 norm += f0 + 4*f1 + f2; 324 f0 = f2; 325 } 326 norm *= DZ / 3.0; 327 328 psF64 Flux = PAR[PM_PAR_I0] * Area * norm; 386 float AspectRatio = axes.minor / axes.major; 387 388 float index = 0.5 / PAR[PM_PAR_7]; 389 float bn = 1.9992*index - 0.3271; 390 391 // the integral of a Sersic has an analytical form as follows: 392 float logGamma = lgamma(2.0*index); 393 float bnFactor = pow(bn, 2.0*index); 394 float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor; 395 396 psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio; 329 397 330 398 return(Flux); … … 346 414 return (1.0); 347 415 348 shape.sx = PAR[PM_PAR_SXX] / M_SQRT2;349 shape.sy = PAR[PM_PAR_SYY] / M_SQRT2;416 shape.sx = PAR[PM_PAR_SXX]; 417 shape.sy = PAR[PM_PAR_SYY]; 350 418 shape.sxy = PAR[PM_PAR_SXY]; 351 419 -
branches/meh_branches/ppstack_test/psModules/src/objects/pmFootprintCullPeaks.c
r31263 r33415 118 118 threshbounds->data.F32[i] = 0.25*beta2*PS_SQR(i) + min_threshold; 119 119 } 120 psAssert(threshbounds->data.F32[threshbounds->n-1] > maxFlux, "upper limit does not include max flux"); 121 120 if (threshbounds->data.F32[threshbounds->n-1] > maxFlux) { 121 psWarning ("upper limit: %f does not include max flux: %f", 122 threshbounds->data.F32[threshbounds->n-1], maxFlux); 123 } 122 124 psHistogram *threshist = psHistogramAllocGeneric(threshbounds); 123 125 … … 181 183 if (!myFP->n) { 182 184 psWarning ("empty footprint?"); 185 psFree (myFP); 183 186 continue; 184 187 } -
branches/meh_branches/ppstack_test/psModules/src/objects/pmModelUtils.c
r31153 r33415 122 122 if (!isfinite(axes.theta)) return false; 123 123 124 // Mxx, Mxy, Myy define the elliptical shape, but Mrf defines the width 125 float scale = (isfinite(moments->Mrf) && (moments->Mrf > 0.0)) ? moments->Mrf / axes.major : 1.0; 126 axes.major *= scale; 127 axes.minor *= scale; 128 124 129 psEllipseShape shape = psEllipseAxesToShape (axes); 125 130 -
branches/meh_branches/ppstack_test/psModules/src/objects/pmMoments.c
r29004 r33415 32 32 tmp->Mrf = 0.0; 33 33 tmp->Mrh = 0.0; 34 35 tmp->KronCore = 0.0; 36 tmp->KronCoreErr = 0.0; 37 34 38 tmp->KronFlux = 0.0; 35 39 tmp->KronFluxErr = 0.0; … … 37 41 tmp->KronFinner = 0.0; 38 42 tmp->KronFouter = 0.0; 43 44 tmp->KronFluxPSF = 0.0; 45 tmp->KronFluxPSFErr = 0.0; 46 tmp->KronRadiusPSF = 0.0; 39 47 40 48 tmp->Mx = 0.0; -
branches/meh_branches/ppstack_test/psModules/src/objects/pmMoments.h
r31153 r33415 51 51 int nPixels; ///< Number of pixels used. 52 52 53 float KronFluxPSF; ///< Kron Flux using PSF-optimized window 54 float KronFluxPSFErr; ///< Kron Flux Error using PSF-optimized window 55 float KronRadiusPSF; ///< Kron Radius using PSF-optimized window (Flux in 2.5 Radius) 56 53 57 float KronCore; ///< flux in r < 1.0*Mrf 54 58 float KronCoreErr; ///< error on flux in r < 1.0*Mrf -
branches/meh_branches/ppstack_test/psModules/src/objects/pmPCM_MinimizeChisq.c
r29012 r33415 45 45 # define USE_FFT 1 46 46 # define PRE_CONVOLVE 1 47 # define TESTCOPY 0 47 48 48 49 bool pmPCM_MinimizeChisq ( … … 93 94 psFree (pcm->psfFFT); 94 95 } 95 pcm->psfFFT = psImageConvolveKernelInit(pcm->modelFlux, pcm->psf); 96 # if (!TESTCOPY) 97 if (!pcm->use1Dgauss) { 98 pcm->psfFFT = psImageConvolveKernelInit(pcm->modelFlux, pcm->psf); 99 } 100 # endif 96 101 # endif 97 102 … … 285 290 286 291 // Convert i/j to image space: 287 coord->data.F32[0] = (psF32) (j + source->pixels->col0);288 coord->data.F32[1] = (psF32) (i + source->pixels->row0);292 coord->data.F32[0] = (psF32) (j + 0.5 + source->pixels->col0); 293 coord->data.F32[1] = (psF32) (i + 0.5 + source->pixels->row0); 289 294 290 295 pcm->modelFlux->data.F32[i][j] = pcm->modelConv->modelFunc (deriv, params, coord); … … 309 314 # if (PRE_CONVOLVE) 310 315 // convolve model image and derivative images with pre-convolved kernel 311 psImageConvolveKernel (pcm->modelConvFlux, pcm->modelFlux, NULL, 0, pcm->psfFFT); 316 317 // XXX for a test, just copy, rather than convolve 318 # if (TESTCOPY) 319 psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type); 320 # else 321 if (pcm->use1Dgauss) { 322 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 323 // * the model flux is not masked 324 // * threading takes place above this level 325 pcm->modelConvFlux = psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type); 326 psImageSmooth_PreAlloc_F32 (pcm->modelConvFlux, pcm->smdata); 327 // psImageSmooth (pcm->modelConvFlux, pcm->sigma, pcm->nsigma); 328 } else { 329 psImageConvolveKernel (pcm->modelConvFlux, pcm->modelFlux, NULL, 0, pcm->psfFFT); 330 } 331 # endif 332 312 333 for (int n = 0; n < pcm->dmodelsFlux->n; n++) { 313 334 if (pcm->dmodelsFlux->data[n] == NULL) continue; … … 315 336 psImage *dmodel = pcm->dmodelsFlux->data[n]; 316 337 psImage *dmodelConv = pcm->dmodelsConvFlux->data[n]; 317 psImageConvolveKernel (dmodelConv, dmodel, NULL, 0, pcm->psfFFT); 338 # if (TESTCOPY) 339 psImageCopy (dmodelConv, dmodel, dmodel->type.type); 340 # else 341 if (pcm->use1Dgauss) { 342 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 343 // * the model flux is not masked 344 // * threading takes place above this level 345 dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type); 346 psImageSmooth_PreAlloc_F32 (dmodelConv, pcm->smdata); 347 // psImageSmooth (dmodelConv, pcm->sigma, pcm->nsigma); 348 } else { 349 psImageConvolveKernel (dmodelConv, dmodel, NULL, 0, pcm->psfFFT); 350 } 351 # endif 318 352 } 319 353 # else … … 325 359 psImage *dmodel = pcm->dmodelsFlux->data[n]; 326 360 psImage *dmodelConv = pcm->dmodelsConvFlux->data[n]; 327 psImageConvolveFFT (dmodelConv, dmodel, NULL, 0, pcm->psf); 361 362 if (pcm->use1Dgauss) { 363 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 364 // * the model flux is not masked 365 // * threading takes place above this level 366 dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type); 367 psImageSmooth_PreAlloc_F32 (dmodelConv, pcm->smdata); 368 // psImageSmooth (dmodelConv, pcm->sigma, pcm->nsigma); 369 } else { 370 psImageConvolveFFT (dmodelConv, dmodel, NULL, 0, pcm->psf); 371 } 328 372 } 329 373 # endif // PRE-CONVOLVE -
branches/meh_branches/ppstack_test/psModules/src/objects/pmPCMdata.c
r31451 r33415 41 41 #include "pmPCMdata.h" 42 42 43 # define USE_DELTA_PSF 0 44 # define USE_1D_GAUSS 1 45 43 46 static void pmPCMdataFree (pmPCMdata *pcm) { 44 47 … … 54 57 psFree (pcm->psfFFT); 55 58 psFree (pcm->constraint); 59 psFree (pcm->smdata); // pre-allocated data for psImageSmooth_PreAlloc 56 60 return; 57 61 } … … 88 92 pcm->constraint = NULL; 89 93 pcm->nDOF = 0; 94 95 // full convolution with the PSF is expensive. if we have to save time, we can do a 1D 96 // convolution with a Gaussian approximation to the kernel 97 pcm->use1Dgauss = false; 98 pcm->nsigma = 3.0; 99 pcm->sigma = 1.0; // this should be set to something sensible when the psf is known 90 100 91 101 return pcm; … … 257 267 pcm->nDOF = nPix - nParams; 258 268 269 # if (USE_1D_GAUSS) 270 pmModel *modelPSF = source->modelPSF; 271 psAssert (modelPSF, "psf model must be defined"); 272 273 psEllipseShape shape; 274 psEllipseAxes axes; 275 276 shape.sx = modelPSF->params->data.F32[PM_PAR_SXX]; 277 shape.sy = modelPSF->params->data.F32[PM_PAR_SYY]; 278 shape.sxy = modelPSF->params->data.F32[PM_PAR_SXY]; 279 axes = psEllipseShapeToAxes (shape, 20.0); 280 281 float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*modelPSF->params->data.F32[PM_PAR_I0]); 282 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 283 284 pcm->use1Dgauss = true; 285 pcm->sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35; 286 pcm->nsigma = 2.0; 287 288 pcm->smdata = psImageSmooth_PreAlloc_DataAlloc (source->pixels, pcm->sigma, pcm->nsigma); 289 # else 290 pcm->smdata = NULL; 291 # endif 292 259 293 return pcm; 260 294 } … … 364 398 pcm->dmodelsConvFlux->data[n] = psImageCopy (pcm->dmodelsConvFlux->data[n], source->pixels, PS_TYPE_F32); 365 399 } 400 psFree(pcm->smdata); 401 pcm->smdata = psImageSmooth_PreAlloc_DataAlloc (source->pixels, pcm->sigma, pcm->nsigma); 366 402 } 367 403 368 404 return true; 369 405 } 406 407 // construct a realization of the source model 408 bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize) { 409 410 PS_ASSERT_PTR_NON_NULL(source, false); 411 412 // select appropriate model 413 pmModel *model = pmSourceGetModel (NULL, source); 414 if (model == NULL) return false; // model must be defined 415 416 // if we already have a cached image, re-use that memory 417 source->modelFlux = psImageCopy (source->modelFlux, source->pixels, PS_TYPE_F32); 418 psImageInit (source->modelFlux, 0.0); 419 420 // modelFlux always has unity normalization (I0 = 1.0) 421 pmModelAdd (source->modelFlux, source->maskObj, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM, maskVal); 422 423 // convolve the model image with the PSF 424 if (USE_1D_GAUSS) { 425 // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread): 426 // * the model flux is not masked 427 // * threading takes place above this level 428 429 // define the Gauss parameters from the psf 430 pmModel *modelPSF = source->modelPSF; 431 psAssert (modelPSF, "psf model must be defined"); 432 433 psEllipseShape shape; 434 psEllipseAxes axes; 435 436 shape.sx = modelPSF->params->data.F32[PM_PAR_SXX]; 437 shape.sy = modelPSF->params->data.F32[PM_PAR_SYY]; 438 shape.sxy = modelPSF->params->data.F32[PM_PAR_SXY]; 439 axes = psEllipseShapeToAxes (shape, 20.0); 440 441 float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*modelPSF->params->data.F32[PM_PAR_I0]); 442 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 443 444 float sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35; 445 float nsigma = 2.0; 446 447 psImageSmooth (source->modelFlux, sigma, nsigma); 448 } else { 449 // make sure we save a cached copy of the psf flux 450 pmSourceCachePSF (source, maskVal); 451 452 // convert the cached cached psf model for this source to a psKernel 453 psKernel *psf = pmPCMkernelFromPSF (source, psfSize); 454 if (!psf) { 455 // NOTE: this only happens if the source is too close to an edge 456 model->flags |= PM_MODEL_STATUS_BADARGS; 457 return NULL; 458 } 459 460 // XXX not sure if I can place the output on top of the input 461 psImageConvolveFFT (source->modelFlux, source->modelFlux, NULL, 0, psf); 462 } 463 return true; 464 } 465 -
branches/meh_branches/ppstack_test/psModules/src/objects/pmPCMdata.h
r31153 r33415 35 35 int nPar; 36 36 int nDOF; 37 38 bool use1Dgauss; 39 float sigma; 40 float nsigma; 41 42 psImageSmooth_PreAlloc_Data *smdata; 37 43 } pmPCMdata; 38 44 … … 90 96 bool pmSourceFitPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 91 97 98 bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize); 92 99 93 100 /// @} -
branches/meh_branches/ppstack_test/psModules/src/objects/pmPSF.c
r31451 r33415 281 281 // convert the parameters used in the fitted source model 282 282 // to the parameters used in the 2D PSF model 283 // XXX this function may be invalid for SERSIC, DEV, EXP models (SQRT2 not used?) 283 284 bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis) 284 285 { … … 307 308 // convert the PSF parameters used in the 2D PSF model fit into the 308 309 // parameters used in the source model 310 // XXX this function may be invalid for SERSIC, DEV, EXP models (SQRT2 not used?) 309 311 psEllipsePol pmPSF_ModelToFit (psF32 *modelPar) 310 312 { … … 329 331 // convert the parameters used in the fitted source model to the psEllipseAxes representation 330 332 // (major,minor,theta) 331 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR )333 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR, pmModelType type) 332 334 { 333 335 psEllipseShape shape; … … 336 338 axes.minor = NAN; 337 339 axes.theta = NAN; 338 // XXX: must assert non-NULL input parameter340 // XXX: must assert non-NULL input parameter 339 341 PS_ASSERT_PTR_NON_NULL(modelPar, axes); 340 342 341 shape.sx = modelPar[PM_PAR_SXX] / M_SQRT2; 342 shape.sy = modelPar[PM_PAR_SYY] / M_SQRT2; 343 shape.sxy = modelPar[PM_PAR_SXY]; 343 bool useReff = true; 344 useReff |= (type == pmModelClassGetType ("PS_MODEL_SERSIC")); 345 useReff |= (type == pmModelClassGetType ("PS_MODEL_DEV")); 346 useReff |= (type == pmModelClassGetType ("PS_MODEL_EXP")); 347 348 if (useReff) { 349 shape.sx = modelPar[PM_PAR_SXX]; 350 shape.sy = modelPar[PM_PAR_SYY]; 351 shape.sxy = modelPar[PM_PAR_SXY]; 352 } else { 353 shape.sx = modelPar[PM_PAR_SXX] / M_SQRT2; 354 shape.sy = modelPar[PM_PAR_SYY] / M_SQRT2; 355 shape.sxy = modelPar[PM_PAR_SXY]; 356 } 344 357 345 358 if ((shape.sx == 0) || (shape.sy == 0)) { … … 357 370 // convert the psEllipseAxes representation (major,minor,theta) to the parameters used in the 358 371 // fitted source model 359 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes )372 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, pmModelType type) 360 373 { 361 374 PS_ASSERT_PTR_NON_NULL(modelPar, false); … … 370 383 psEllipseShape shape = psEllipseAxesToShape (axes); 371 384 372 modelPar[PM_PAR_SXX] = shape.sx * M_SQRT2; 373 modelPar[PM_PAR_SYY] = shape.sy * M_SQRT2; 374 modelPar[PM_PAR_SXY] = shape.sxy; 375 385 bool useReff = true; 386 useReff |= pmModelClassGetType ("PS_MODEL_SERSIC"); 387 useReff |= pmModelClassGetType ("PS_MODEL_DEV"); 388 useReff |= pmModelClassGetType ("PS_MODEL_EXP"); 389 390 if (useReff) { 391 modelPar[PM_PAR_SXX] = shape.sx; 392 modelPar[PM_PAR_SYY] = shape.sy; 393 modelPar[PM_PAR_SXY] = shape.sxy; 394 } else { 395 modelPar[PM_PAR_SXX] = shape.sx * M_SQRT2; 396 modelPar[PM_PAR_SYY] = shape.sy * M_SQRT2; 397 modelPar[PM_PAR_SXY] = shape.sxy; 398 } 376 399 return true; 377 400 } … … 438 461 # if (0) 439 462 psF32 *params = model->params->data.F32; // Model parameters 440 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO ); // Ellipse axes463 psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO, model->type); // Ellipse axes 441 464 442 465 // Curiously, the minor axis can be larger than the major axis, so need to check. -
branches/meh_branches/ppstack_test/psModules/src/objects/pmPSF.h
r31451 r33415 106 106 pmPSF *pmPSFBuildSimple (char *typeName, float sxx, float syy, float sxy, ...); 107 107 108 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes );108 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, pmModelType type); 109 109 bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis); 110 110 111 111 psEllipsePol pmPSF_ModelToFit (psF32 *modelPar); 112 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR );112 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR, pmModelType type); 113 113 114 114 /// Calculate FWHM value from a PSF -
branches/meh_branches/ppstack_test/psModules/src/objects/pmPeaks.c
r31451 r33415 137 137 *****************************************************************************/ 138 138 static void peakFree(pmPeak *tmp) 139 {} // 139 { 140 if (!tmp) return; 141 psFree (tmp->saddlePoints); 142 return; 143 } 140 144 141 145 pmPeak *pmPeakAlloc(psS32 x, … … 162 166 tmp->type = type; 163 167 tmp->footprint = NULL; 168 tmp->saddlePoints = NULL; 164 169 165 170 psMemSetDeallocator(tmp, (psFreeFunc) peakFree); … … 185 190 out->assigned = in->assigned; 186 191 out->type = in->type; 192 out->footprint = in->footprint; 187 193 188 194 return true; -
branches/meh_branches/ppstack_test/psModules/src/objects/pmPeaks.h
r31451 r33415 71 71 bool assigned; ///< is peak assigned to a source? 72 72 pmPeakType type; ///< Description of peak. 73 pmFootprint *footprint; ///< reference to containing footprint 73 pmFootprint *footprint; ///< reference to containing footprint (just a view, not a memcopy) 74 psArray *saddlePoints; ///< set of saddle points between this peak and near neighbors 74 75 } 75 76 pmPeak; -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSource.c
r31670 r33415 58 58 psFree(tmp->modelEXT); 59 59 psFree(tmp->modelFits); 60 psFree(tmp->extFitPars); 60 61 psFree(tmp->extpars); 61 62 psFree(tmp->moments); … … 119 120 source->modelEXT = NULL; 120 121 source->modelFits = NULL; 122 source->extFitPars = NULL; 123 121 124 source->type = PM_SOURCE_TYPE_UNKNOWN; 122 125 source->mode = PM_SOURCE_MODE_DEFAULT; … … 136 139 source->apFluxErr = NAN; 137 140 141 source->windowRadius = NAN; 142 source->skyRadius = NAN; 143 source->skyFlux = NAN; 144 source->skySlope = NAN; 145 138 146 source->pixWeightNotBad = NAN; 139 147 source->pixWeightNotPoor = NAN; … … 196 204 // NOTE : because of the const id element, we cannot just assign *source = *in 197 205 206 source->imageID = in->imageID; 207 198 208 source->type = in->type; 199 209 source->mode = in->mode; 200 210 source->mode2 = in->mode2; 201 211 source->tmpFlags = in->tmpFlags; 212 202 213 source->psfMag = in->psfMag; 203 214 source->psfMagErr = in->psfMagErr; … … 210 221 source->apFlux = in->apFlux; 211 222 source->apFluxErr = in->apFluxErr; 223 224 source->windowRadius = in->windowRadius; 225 source->skyRadius = in->skyRadius; 226 source->skyFlux = in->skyFlux; 227 source->skySlope = in->skySlope; 228 212 229 source->pixWeightNotBad = in->pixWeightNotBad; 213 230 source->pixWeightNotPoor = in->pixWeightNotPoor; 231 214 232 source->psfChisq = in->psfChisq; 215 233 source->crNsigma = in->crNsigma; … … 252 270 } 253 271 mySource->region = srcRegion; 272 mySource->windowRadius = Radius; 254 273 255 274 return true; … … 321 340 mySource->psfImage = NULL; 322 341 } 342 mySource->windowRadius = Radius; 323 343 return extend; 324 344 } -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSource.h
r31670 r33415 36 36 PM_SOURCE_TMPF_MOMENTS_MEASURED = 0x0010, 37 37 PM_SOURCE_TMPF_CANDIDATE_PSFSTAR = 0x0020, 38 PM_SOURCE_TMPF_RADIAL_KEEP = 0x0040, 39 PM_SOURCE_TMPF_RADIAL_SKIP = 0x0080, 40 PM_SOURCE_TMPF_PETRO_KEEP = 0x0100, 41 PM_SOURCE_TMPF_PETRO_SKIP = 0x0200, 38 42 } pmSourceTmpF; 39 43 … … 76 80 pmModel *modelEXT; ///< EXT Model fit used for subtraction (parameters and type) 77 81 psArray *modelFits; ///< collection of extended source models (best == modelEXT) 82 psArray *extFitPars; ///< extra extended fit parameters 78 83 pmSourceType type; ///< Best identification of object. 79 84 pmSourceMode mode; ///< analysis flags set for object. … … 91 96 float apFlux; ///< apFlux corresponding to psfMag or extMag (depending on type) 92 97 float apFluxErr; ///< apFluxErr corresponding to psfMag or extMag (depending on type) 98 99 float windowRadius; ///< size of box used for full analysis 100 float skyRadius; ///< radius at which profile hits local sky (or goes flat) 101 float skyFlux; ///< mean flux per pixel in aperture at which profile hits local sky (or goes flat) 102 float skySlope; ///< mean flux slope at which profile hits local sky (or goes flat) 93 103 94 104 float pixWeightNotBad; ///< PSF-weighted coverage of unmasked (not BAD) pixels -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceExtendedPars.c
r31153 r33415 258 258 return ( psMemGetDeallocator(ptr) == (psFreeFunc) pmSourceExtendedFluxFree); 259 259 } 260 261 // *** pmSourceExtFitPars describes extra metadata related to an extended fit 262 static void pmSourceExtFitParsFree (pmSourceExtFitPars *pars) { 263 return; 264 } 265 266 pmSourceExtFitPars *pmSourceExtFitParsAlloc (void) { 267 268 pmSourceExtFitPars *pars = (pmSourceExtFitPars *) psAlloc(sizeof(pmSourceExtFitPars)); 269 psMemSetDeallocator(pars, (psFreeFunc) pmSourceExtFitParsFree); 270 271 pars->Mxx = NAN; 272 pars->Mxy = NAN; 273 pars->Myy = NAN; 274 275 pars->Mrf = NAN; 276 pars->Mrh = NAN; 277 278 pars->apMag = NAN; 279 pars->krMag = NAN; 280 pars->psfMag = NAN; 281 pars->peakMag = NAN; 282 283 return pars; 284 } -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceExtendedPars.h
r31153 r33415 67 67 } pmSourceExtendedPars; 68 68 69 // additional measurements related to the model fits 70 typedef struct { 71 float Mxx; 72 float Mxy; 73 float Myy; 74 75 float Mrf; 76 float Mrh; 77 78 float apMag; 79 float krMag; 80 float psfMag; 81 float peakMag; 82 } pmSourceExtFitPars; 83 69 84 pmSourceRadialFlux *pmSourceRadialFluxAlloc(); 70 85 bool psMemCheckSourceRadialFlux(psPtr ptr); … … 92 107 bool pmSourceRadialProfileSortPair(psVector *index, psVector *extra); 93 108 94 109 pmSourceExtFitPars *pmSourceExtFitParsAlloc (void); 95 110 96 111 /// @} -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceFitModel.c
r31153 r33415 176 176 break; 177 177 case PM_SOURCE_FIT_EXT: 178 // EXT model fits all params (exceptsky)179 nParams = params->n - 1;178 // EXT model fits all shape params and Io (not Xo, Yo, sky) 179 nParams = params->n - 3; 180 180 psVectorInit (constraint->paramMask, 0); 181 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 1; 182 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 1; 181 183 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1; 182 184 break; … … 193 195 break; 194 196 case PM_SOURCE_FIT_NO_INDEX: 195 // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params197 // PSF model only fits Io, Sxx, Sxy, Syy 196 198 psVectorInit (constraint->paramMask, 0); 199 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 1; 200 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 1; 197 201 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1; 198 202 if (params->n == 7) { 199 nParams = params->n - 1;203 nParams = params->n - 3; 200 204 } else { 201 nParams = params->n - 2;205 nParams = params->n - 4; 202 206 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1; 203 207 } -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceFitPCM.c
r31153 r33415 48 48 // convolved model image. 49 49 50 # define TIMING 0 51 50 52 bool pmSourceFitPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 51 53 54 if (TIMING) { psTimerStart ("pmSourceFitPCM"); } 55 52 56 psVector *params = pcm->modelConv->params; 53 57 psVector *dparams = pcm->modelConv->dparams; … … 63 67 64 68 psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32); 69 // NOTE : 4 allocs to here 65 70 71 float t1, t2, t3, t4, t5; 72 if (TIMING) { t1 = psTimerMark ("pmSourceFitPCM"); } 73 74 // NOTE : 996 allocs in here 66 75 bool fitStatus = pmPCM_MinimizeChisq (myMin, covar, params, source, pcm); 76 if (TIMING) { t2 = psTimerMark ("pmSourceFitPCM"); } 77 67 78 for (int i = 0; i < dparams->n; i++) { 68 79 if ((pcm->constraint->paramMask != NULL) && pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) … … 76 87 } 77 88 psTrace ("psphot", 4, "niter: %d, chisq: %f", myMin->iter, myMin->value); 89 if (TIMING) { t3 = psTimerMark ("pmSourceFitPCM"); } 78 90 79 91 // renormalize output model image (generated by fitting process) … … 97 109 pmSourceChisqUnsubtracted (source, pcm->modelConv, maskVal); 98 110 } 111 if (TIMING) { t4 = psTimerMark ("pmSourceFitPCM"); } 99 112 100 113 // set the model success or failure status … … 114 127 115 128 source->mode |= PM_SOURCE_MODE_FITTED; // XXX is this needed? 129 if (TIMING) { t5 = psTimerMark ("pmSourceFitPCM"); } 130 131 if (TIMING) { 132 fprintf (stderr, "nIter: %2d, npix: %5d, t1: %6.4f, t2: %6.4f, t3: %6.4f, t4: %6.4f, t5: %6.4f\n", myMin->iter, pcm->nPix, t1, t2, t3, t4, t5); 133 } 116 134 117 135 psFree(myMin); … … 121 139 } 122 140 141 // XXX deprecate this function or merge with the empirical model 123 142 bool pmSourceModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) { 124 143 -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO.c
r31670 r33415 57 57 #define BLANK_HEADERS "BLANK.HEADERS" // Name of metadata in camera configuration containing header names 58 58 // for putting values into a blank PHU 59 static bool pmReadoutReadXSRC(pmFPAfile *file, char * exttype, psMetadata *hduHeader, psString xsrcname, psArray *sources, long *sourceIndex); 60 static bool pmReadoutReadXFIT(pmFPAfile *file, char * exttype, psMetadata *hduHeader, psString xfitname, psArray *sources, long *sourceIndex); 61 static bool pmReadoutReadXRAD(pmFPAfile *file, pmReadout *readout, char * exttype, psMetadata *hduHeader, psString xfitname, psArray *sources, long *sourceIndex); 59 62 60 63 // lookup the EXTNAME values used for table data and image header segments … … 569 572 PM_SOURCES_WRITE("PS1_V2", CMF_PS1_V2); 570 573 PM_SOURCES_WRITE("PS1_V3", CMF_PS1_V3); 574 PM_SOURCES_WRITE("PS1_V4", CMF_PS1_V4); 571 575 PM_SOURCES_WRITE("PS1_SV1", CMF_PS1_SV1); 572 576 PM_SOURCES_WRITE("PS1_DV1", CMF_PS1_DV1); … … 960 964 psString dataname = NULL; 961 965 psString deteffname = NULL; 962 if (!pmSourceIOextnames(&headname, &dataname, &deteffname, NULL, NULL, NULL, file, view)) { 966 psString xsrcname = NULL; 967 psString xfitname = NULL; 968 psString xradname = NULL; 969 970 // determine the output table format. Assume if we need to output extendend source 971 // parameters that they may exist in the input. 972 // XXX: Perhaps we should use different recipe values. 973 // I.E. EXTENDED_SOURCE_ANALYSIS_READ or something like that 974 psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, "PSPHOT"); 975 if (!status) { 976 psError(PS_ERR_UNKNOWN, true, "missing recipe PSPHOT in config data"); 977 return false; 978 } 979 // if this is not TRUE, the output files only contain the psf measurements. 980 bool XSRC_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_ANALYSIS"); 981 bool XFIT_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_FITS"); 982 bool XRAD_OUTPUT = psMetadataLookupBool(&status, recipe, "RADIAL_APERTURES"); 983 984 if (!pmSourceIOextnames(&headname, &dataname, &deteffname, 985 XSRC_OUTPUT ? &xsrcname : NULL, 986 XFIT_OUTPUT ? &xfitname : NULL, 987 XRAD_OUTPUT ? &xradname : NULL, 988 file, view)) { 963 989 return false; 964 990 } … … 1025 1051 sources = pmSourcesRead_CMF_PS1_V3 (file->fits, hdu->header); 1026 1052 } 1053 if (!strcmp (exttype, "PS1_V4")) { 1054 sources = pmSourcesRead_CMF_PS1_V4 (file->fits, hdu->header); 1055 } 1027 1056 if (!strcmp (exttype, "PS1_SV1")) { 1028 1057 sources = pmSourcesRead_CMF_PS1_SV1 (file->fits, hdu->header); … … 1034 1063 sources = pmSourcesRead_CMF_PS1_DV2 (file->fits, hdu->header); 1035 1064 } 1065 1066 long *sourceIndex = NULL; 1067 if (XSRC_OUTPUT || XFIT_OUTPUT || XRAD_OUTPUT) { 1068 long seq_max = -1; 1069 for (long i = sources->n -1; i >= 0; i--) { 1070 pmSource *source = sources->data[i]; 1071 if (source->seq > seq_max) { 1072 seq_max = source->seq; 1073 } 1074 } 1075 sourceIndex = psAlloc((seq_max + 1) * sizeof(long)); 1076 for (long i = 0; i < seq_max; i++) { 1077 sourceIndex[i] = -1; 1078 } 1079 for (long i = 0; i < sources->n; i++) { 1080 pmSource *source = sources->data[i]; 1081 sourceIndex[source->seq] = i; 1082 } 1083 } 1084 if (XSRC_OUTPUT && xsrcname) { 1085 if (!pmReadoutReadXSRC(file, exttype, hdu->header, xsrcname, sources, sourceIndex)) { 1086 // XXX: is this an error? 1087 psErrorClear(); 1088 } 1089 psFree(xsrcname); 1090 } 1091 if (XFIT_OUTPUT && xfitname) { 1092 if (!pmReadoutReadXFIT(file, exttype, hdu->header, xfitname, sources, sourceIndex)) { 1093 // XXX: is this an error? 1094 psErrorClear(); 1095 } 1096 psFree(xfitname); 1097 } 1098 if (XRAD_OUTPUT && xradname) { 1099 if (!pmReadoutReadXRAD(file, readout, exttype, hdu->header, xradname, sources, sourceIndex)) { 1100 // XXX: is this an error? 1101 psErrorClear(); 1102 } 1103 psFree(xradname); 1104 } 1105 psFree(sourceIndex); 1036 1106 1037 1107 if (!pmReadoutReadDetEff(file->fits, readout, deteffname)) { … … 1161 1231 } 1162 1232 1163 1233 // XXX: We might be able to macroize this and reuse for the other types 1234 1235 static bool pmReadoutReadXSRC(pmFPAfile *file, char *exttype, psMetadata *hduHeader, psString xsrcname, psArray *sources, long *sourceIndex) 1236 { 1237 if (!psFitsMoveExtName (file->fits, xsrcname)) { 1238 psError(PS_ERR_UNKNOWN, false, "cannot find xsrc extension %s in %s", xsrcname, file->filename); 1239 return false; 1240 } 1241 1242 psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header 1243 if (!tableHeader) psAbort("cannot read table header"); 1244 1245 char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION"); 1246 if (!xtension) psAbort("cannot read table type"); 1247 if (strcmp (xtension, "BINTABLE")) { 1248 psWarning ("no binary table in extension %s, skipping\n", xsrcname); 1249 return false; 1250 } 1251 1252 // XXX these are case-sensitive since the EXTYPE is case-sensitive 1253 bool status = false; 1254 if (file->type == PM_FPA_FILE_CMF) { 1255 if (!strcmp (exttype, "PS1_SV1")) { 1256 status = pmSourcesRead_CMF_PS1_SV1_XSRC (file->fits, hduHeader, sources, sourceIndex); 1257 } 1258 } 1259 psFree(tableHeader); 1260 return status; 1261 } 1262 1263 static bool pmReadoutReadXFIT(pmFPAfile *file, char *exttype, psMetadata *hduHeader, psString extname, psArray *sources, long *sourceIndex) 1264 { 1265 if (!psFitsMoveExtName (file->fits, extname)) { 1266 psError(PS_ERR_UNKNOWN, false, "cannot find extension %s in %s", extname, file->filename); 1267 return false; 1268 } 1269 1270 psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header 1271 if (!tableHeader) psAbort("cannot read table header"); 1272 1273 char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION"); 1274 if (!xtension) psAbort("cannot read table type"); 1275 if (strcmp (xtension, "BINTABLE")) { 1276 psWarning ("no binary table in extension %s, skipping\n", extname); 1277 return false; 1278 } 1279 1280 // XXX these are case-sensitive since the EXTYPE is case-sensitive 1281 bool status = false; 1282 if (file->type == PM_FPA_FILE_CMF) { 1283 if (!strcmp (exttype, "PS1_SV1")) { 1284 status = pmSourcesRead_CMF_PS1_SV1_XFIT (file->fits, hduHeader, sources, sourceIndex); 1285 } 1286 } 1287 psFree(tableHeader); 1288 return status; 1289 } 1290 static bool pmReadoutReadXRAD(pmFPAfile *file, pmReadout *readout, char *exttype, psMetadata *hduHeader, psString extname, psArray *sources, long *sourceIndex) 1291 { 1292 if (!psFitsMoveExtName (file->fits, extname)) { 1293 psError(PS_ERR_UNKNOWN, false, "cannot find extension %s in %s", extname, file->filename); 1294 return false; 1295 } 1296 1297 psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header 1298 if (!tableHeader) psAbort("cannot read table header"); 1299 1300 char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION"); 1301 if (!xtension) psAbort("cannot read table type"); 1302 if (strcmp (xtension, "BINTABLE")) { 1303 psWarning ("no binary table in extension %s, skipping\n", extname); 1304 return false; 1305 } 1306 1307 // XXX these are case-sensitive since the EXTYPE is case-sensitive 1308 bool status = false; 1309 if (file->type == PM_FPA_FILE_CMF) { 1310 if (!strcmp (exttype, "PS1_SV1")) { 1311 status = pmSourcesRead_CMF_PS1_SV1_XRAD (file->fits, readout, hduHeader, sources, sourceIndex); 1312 } 1313 } 1314 psFree(tableHeader); 1315 return status; 1316 } -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO.h
r30621 r33415 62 62 bool pmSourcesWrite_CMF_PS1_V3_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe); 63 63 64 bool pmSourcesWrite_CMF_PS1_V4(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname, psMetadata *recipe); 65 bool pmSourcesWrite_CMF_PS1_V4_XSRC(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe); 66 bool pmSourcesWrite_CMF_PS1_V4_XFIT(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname); 67 bool pmSourcesWrite_CMF_PS1_V4_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe); 68 64 69 bool pmSourcesWrite_CMF_PS1_SV1(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname, psMetadata *recipe); 65 70 bool pmSourcesWrite_CMF_PS1_SV1_XSRC(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe); … … 86 91 psArray *pmSourcesRead_CMF_PS1_V2 (psFits *fits, psMetadata *header); 87 92 psArray *pmSourcesRead_CMF_PS1_V3 (psFits *fits, psMetadata *header); 93 psArray *pmSourcesRead_CMF_PS1_V4 (psFits *fits, psMetadata *header); 88 94 psArray *pmSourcesRead_CMF_PS1_SV1 (psFits *fits, psMetadata *header); 95 bool pmSourcesRead_CMF_PS1_SV1_XSRC (psFits *fits, psMetadata *header, psArray *sources, long *); 96 bool pmSourcesRead_CMF_PS1_SV1_XFIT (psFits *fits, psMetadata *header, psArray *sources, long *); 97 bool pmSourcesRead_CMF_PS1_SV1_XRAD (psFits *fits, pmReadout *readout, psMetadata *header, psArray *sources, long *); 89 98 psArray *pmSourcesRead_CMF_PS1_DV1 (psFits *fits, psMetadata *header); 90 99 psArray *pmSourcesRead_CMF_PS1_DV2 (psFits *fits, psMetadata *header); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_CMF.c.in
r31670 r33415 55 55 // followed by a zero-size matrix, followed by the table data 56 56 57 // # define MODE @CMFMODE@58 57 bool pmSourcesWrite_CMF_@CMFMODE@ (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname, psMetadata *recipe) 59 58 { … … 128 127 129 128 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 130 @ =PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in reported aperture", source->apMagRaw);129 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in reported aperture", source->apMagRaw); 131 130 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 132 131 @<PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); … … 139 138 @>PS1_V1@ psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", outputs.dec); 140 139 141 @ =PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag);140 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 142 141 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 143 142 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); … … 151 150 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 152 151 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor (bad)", source->pixWeightNotBad); 153 @ =PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", source->pixWeightNotPoor);152 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", source->pixWeightNotPoor); 154 153 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 155 154 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); … … 159 158 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 160 159 161 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", moments.M_c3); 162 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", moments.M_s3); 163 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", moments.M_c4); 164 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", moments.M_s4); 165 166 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", moments.Mrf); 167 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", moments.Mrh); 168 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Krf); 169 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", moments.dKrf); 170 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kinner); 171 @=PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kouter); 172 173 // Do NOT write these : not consistent with the definition of PS1_V3 in Ohana/src/libautocode/dev/cmf-ps1-v3.d 174 // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_FLUX", PS_DATA_F32, "Kron Flux (in 1.0 R1)", moments.KronCore); 175 // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_ERROR", PS_DATA_F32, "Kron Error (in 1.0 R1)", moments.KronCoreErr); 160 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", moments.M_c3); 161 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", moments.M_s3); 162 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", moments.M_c4); 163 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", moments.M_s4); 164 165 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", moments.Mrf); 166 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", moments.Mrh); 167 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Krf); 168 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", moments.dKrf); 169 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kinner); 170 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kouter); 171 172 @>PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "SKY_LIMIT_RAD", PS_DATA_F32, "Radius where object hits sky", source->skyRadius); 173 @>PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "SKY_LIMIT_FLUX", PS_DATA_F32, "Flux / pix where object hits sky", source->skyFlux); 174 @>PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "SKY_LIMIT_SLOPE", PS_DATA_F32, "d(Flux/pix)/dRadius where object hits sky", source->skySlope); 175 176 176 @ALL@ psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); 177 @ =PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags", source->mode2);178 @ =PS1_V3@ psMetadataAdd (row, PS_LIST_TAIL, "PADDING2", PS_DATA_S32, "more padding", 0);177 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags", source->mode2); 178 @>PS1_V2@ psMetadataAdd (row, PS_LIST_TAIL, "PADDING2", PS_DATA_S32, "more padding", 0); 179 179 180 180 // XXX not sure how to get this : need to load Nimages with weight? … … 222 222 223 223 // read in a readout from the fits file 224 psArray *pmSourcesRead_CMF_ PS1_V3(psFits *fits, psMetadata *header)224 psArray *pmSourcesRead_CMF_@CMFMODE@ (psFits *fits, psMetadata *header) 225 225 { 226 226 PS_ASSERT_PTR_NON_NULL(fits, false); … … 281 281 // XXX use these to determine PAR[PM_PAR_I0]? 282 282 @ALL@ source->psfMag = psMetadataLookupF32 (&status, row, "PSF_INST_MAG"); 283 @ALL@ source->psfMagErr = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");283 @ALL@ source->psfMagErr = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG"); 284 284 @ALL@ source->apMag = psMetadataLookupF32 (&status, row, "AP_MAG"); 285 @>PS1_V2@ source->apMagRaw = psMetadataLookupF32 (&status, row, "AP_MAG_RAW"); 286 287 // XXX use these to determine PAR[PM_PAR_I0] if they exist? 288 @>PS1_V2@ source->psfFlux = psMetadataLookupF32 (&status, row, "PSF_INST_FLUX"); 289 @>PS1_V2@ source->psfFluxErr= psMetadataLookupF32 (&status, row, "PSF_INST_FLUX_SIG"); 285 290 286 291 // XXX this scaling is incorrect: does not include the 2 \pi AREA factor … … 288 293 @ALL@ dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 289 294 290 pmPSF_AxesToModel (PAR, axes );295 pmPSF_AxesToModel (PAR, axes, modelType); 291 296 292 297 @ALL@ float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 303 308 304 309 @ALL@ source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); 305 @ =PS1_V3@ source->pixWeightNotPoor = psMetadataLookupF32 (&status, row, "PSF_QF_PERFECT");310 @>PS1_V2@ source->pixWeightNotPoor = psMetadataLookupF32 (&status, row, "PSF_QF_PERFECT"); 306 311 @ALL@ source->crNsigma = psMetadataLookupF32 (&status, row, "CR_NSIGMA"); 307 312 @ALL@ source->extNsigma = psMetadataLookupF32 (&status, row, "EXT_NSIGMA"); … … 321 326 @ALL@ source->moments->Myy = psMetadataLookupF32 (&status, row, "MOMENTS_YY"); 322 327 323 @=PS1_V3@ source->moments->Mrf = psMetadataLookupF32 (&status, row, "MOMENTS_R1"); 324 @=PS1_V3@ source->moments->Mrh = psMetadataLookupF32 (&status, row, "MOMENTS_RH"); 325 @=PS1_V3@ source->moments->KronFlux = psMetadataLookupF32 (&status, row, "KRON_FLUX"); 326 @=PS1_V3@ source->moments->KronFluxErr = psMetadataLookupF32 (&status, row, "KRON_FLUX_ERR"); 327 328 @=PS1_V3@ source->moments->KronFinner = psMetadataLookupF32 (&status, row, "KRON_FLUX_INNER"); 329 @=PS1_V3@ source->moments->KronFouter = psMetadataLookupF32 (&status, row, "KRON_FLUX_OUTER"); 328 @>PS1_V2@ source->moments->Mrf = psMetadataLookupF32 (&status, row, "MOMENTS_R1"); 329 @>PS1_V2@ source->moments->Mrh = psMetadataLookupF32 (&status, row, "MOMENTS_RH"); 330 @>PS1_V2@ source->moments->KronFlux = psMetadataLookupF32 (&status, row, "KRON_FLUX"); 331 @>PS1_V2@ source->moments->KronFluxErr = psMetadataLookupF32 (&status, row, "KRON_FLUX_ERR"); 332 333 @>PS1_V2@ source->moments->KronFinner = psMetadataLookupF32 (&status, row, "KRON_FLUX_INNER"); 334 @>PS1_V2@ source->moments->KronFouter = psMetadataLookupF32 (&status, row, "KRON_FLUX_OUTER"); 335 336 @>PS1_V3@ source->skyRadius = psMetadataLookupF32 (&status, row, "SKY_LIMIT_RAD"); 337 @>PS1_V3@ source->skyFlux = psMetadataLookupF32 (&status, row, "SKY_LIMIT_FLUX"); 338 @>PS1_V3@ source->skySlope = psMetadataLookupF32 (&status, row, "SKY_LIMIT_SLOPE"); 330 339 331 340 // XXX we do not save all of the 3rd and 4th moment parameters. when we load in data, 332 341 // we are storing enough information so the output will be consistent with the input 333 @ =PS1_V3@ source->moments->Mxxx = +1.0 * psMetadataLookupF32 (&status, row, "MOMENTS_M3C");334 @ =PS1_V3@ source->moments->Mxxy = 0.0;335 @ =PS1_V3@ source->moments->Mxyy = 0.0;336 @ =PS1_V3@ source->moments->Myyy = -1.0 * psMetadataLookupF32 (&status, row, "MOMENTS_M3S");337 338 @ =PS1_V3@ source->moments->Mxxxx = +1.00 * psMetadataLookupF32 (&status, row, "MOMENTS_M4C");339 @ =PS1_V3@ source->moments->Mxxxy = 0.0;340 @ =PS1_V3@ source->moments->Mxxyy = 0.0;341 @ =PS1_V3@ source->moments->Mxyyy = -0.25 * psMetadataLookupF32 (&status, row, "MOMENTS_M4S");342 @ =PS1_V3@ source->moments->Myyyy = 0.0;342 @>PS1_V2@ source->moments->Mxxx = +1.0 * psMetadataLookupF32 (&status, row, "MOMENTS_M3C"); 343 @>PS1_V2@ source->moments->Mxxy = 0.0; 344 @>PS1_V2@ source->moments->Mxyy = 0.0; 345 @>PS1_V2@ source->moments->Myyy = -1.0 * psMetadataLookupF32 (&status, row, "MOMENTS_M3S"); 346 347 @>PS1_V2@ source->moments->Mxxxx = +1.00 * psMetadataLookupF32 (&status, row, "MOMENTS_M4C"); 348 @>PS1_V2@ source->moments->Mxxxy = 0.0; 349 @>PS1_V2@ source->moments->Mxxyy = 0.0; 350 @>PS1_V2@ source->moments->Mxyyy = -0.25 * psMetadataLookupF32 (&status, row, "MOMENTS_M4S"); 351 @>PS1_V2@ source->moments->Myyyy = 0.0; 343 352 344 353 @ALL@ source->mode = psMetadataLookupU32 (&status, row, "FLAGS"); 345 @ =PS1_V3@ source->mode2 = psMetadataLookupU32 (&status, row, "FLAGS2");354 @>PS1_V2@ source->mode2 = psMetadataLookupU32 (&status, row, "FLAGS2"); 346 355 assert (status); 347 356 … … 353 362 } 354 363 355 bool pmSourcesWrite_CMF_ PS1_V3_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)364 bool pmSourcesWrite_CMF_@CMFMODE@_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe) 356 365 { 357 366 bool status; … … 541 550 542 551 // XXX this layout is still the same as PS1_DEV_1 543 bool pmSourcesWrite_CMF_ PS1_V3_XFIT (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname)552 bool pmSourcesWrite_CMF_@CMFMODE@_XFIT (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname) 544 553 { 545 554 … … 590 599 assert (model); 591 600 601 // pmSourceExtFitPars *extPars = source->extFitPars->data[j]; 602 // assert (extPars); 603 592 604 // skip models which were not actually fitted 593 605 if (model->flags & PM_MODEL_STATUS_BADARGS) continue; … … 600 612 yErr = dPAR[PM_PAR_YPOS]; 601 613 602 axes = pmPSF_ModelToAxes (PAR, 20.0); 614 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 615 616 float kronFlux = source->moments ? source->moments->KronFlux : NAN; 617 float kronMag = isfinite(kronFlux) ? -2.5*log10(kronFlux) : NAN; 603 618 604 619 row = psMetadataAlloc (); … … 612 627 psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG", 0, "EXT fit instrumental magnitude", model->mag); 613 628 psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_INST_MAG_SIG", 0, "Sigma of PSF instrumental magnitude", model->magErr); 629 630 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_XX", 0, "second moment in x", extPars->Mxx); 631 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_XY", 0, "second moment in x,y", extPars->Mxy); 632 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_YY", 0, "second moment in y", extPars->Myy); 633 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_R1", 0, "first radial moment", extPars->Mrf); 634 // psMetadataAddF32 (row, PS_LIST_TAIL, "MOMENTS_RH", 0, "half radial moment", extPars->Mrh); 635 636 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_INST_MAG", 0, "PSF fit instrumental magnitude", source->psfMag); 637 psMetadataAddF32 (row, PS_LIST_TAIL, "AP_MAG", 0, "PSF-sized aperture magnitude", source->apMag); 638 psMetadataAddF32 (row, PS_LIST_TAIL, "KRON_MAG", 0, "Kron Mag", kronMag); 614 639 615 640 psMetadataAddF32 (row, PS_LIST_TAIL, "NPARAMS", 0, "number of model parameters", model->params->n); … … 673 698 } 674 699 675 bool pmSourcesWrite_CMF_ PS1_V3_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)700 bool pmSourcesWrite_CMF_@CMFMODE@_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe) 676 701 { 677 702 return true; -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_CMF_PS1_DV1.c
r31451 r33415 263 263 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 264 264 265 pmPSF_AxesToModel (PAR, axes );265 pmPSF_AxesToModel (PAR, axes, modelType); 266 266 267 267 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 547 547 yErr = dPAR[PM_PAR_YPOS]; 548 548 549 axes = pmPSF_ModelToAxes (PAR, 20.0 );549 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 550 550 551 551 row = psMetadataAlloc (); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_CMF_PS1_DV2.c
r31451 r33415 281 281 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 282 282 283 pmPSF_AxesToModel (PAR, axes );283 pmPSF_AxesToModel (PAR, axes, modelType); 284 284 285 285 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 572 572 yErr = dPAR[PM_PAR_YPOS]; 573 573 574 axes = pmPSF_ModelToAxes (PAR, 20.0 );574 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 575 575 576 576 row = psMetadataAlloc (); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_CMF_PS1_SV1.c
r31451 r33415 280 280 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 281 281 282 pmPSF_AxesToModel (PAR, axes );282 pmPSF_AxesToModel (PAR, axes, modelType); 283 283 284 284 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 539 539 } 540 540 541 bool pmSourcesRead_CMF_PS1_SV1_XSRC(psFits *fits, psMetadata *hduHeader, psArray *sources, long *sourceIndex) 542 { 543 PS_ASSERT_PTR_NON_NULL(fits, false); 544 PS_ASSERT_PTR_NON_NULL(sources, false); 545 546 bool status; 547 long numSources = psFitsTableSize(fits); // Number of sources in table 548 if (numSources == 0) { 549 psError(psErrorCodeLast(), false, "XSRC Table contains no entries\n"); 550 return false; 551 } 552 553 // petrosian mags are not saved, we need to calculate fluxes. For this we need exptime and zero point 554 float zeropt = psMetadataLookupF32(&status, hduHeader, "FPA.ZP"); 555 float exptime = psMetadataLookupF32(&status, hduHeader, "EXPTIME"); 556 float magOffset = zeropt + 2.5*log10(exptime); 557 558 for (long i = 0; i < numSources; i++) { 559 psMetadata *row = psFitsReadTableRow(fits, i); // Table row 560 if (!row) { 561 psError(psErrorCodeLast(), false, "Unable to read row %ld of sources", i); 562 psFree(row); 563 return false; 564 } 565 // Find the source with this sequence number. 566 // XXX: I am assuming that sources is sorted in order of seq 567 long seq = psMetadataLookupU32 (&status, row, "IPP_IDET"); 568 pmSource *source = NULL; 569 #ifndef ASSUME_SORTED 570 long j = seq < sources->n ? seq : sources->n - 1; 571 for (; j >= 0; j--) { 572 source = sources->data[j]; 573 if (source->seq == seq) { 574 break; 575 } 576 } 577 #else 578 long j = sourceIndex[seq]; 579 psAssert(j >= 0 && j < sources->n, "invalid sourceIndex"); 580 source = sources->data[j]; 581 #endif 582 if (!source) { 583 psError(PS_ERR_UNKNOWN, false, "Failed to find source for row %ld sequence number %ld\n", i, seq); 584 psFree(row); 585 return false; 586 } 587 588 if (!source->extpars) { 589 source->extpars = pmSourceExtendedParsAlloc (); 590 } 591 pmSourceExtendedPars *extpars = source->extpars; 592 593 // Assume that X_EXT Y_EXT and sigmas match the psf src so skip 594 595 // We don't have enough information to calculate the major and minor axis. Set major to 1. Should we scale this by 596 // psf size or something? 597 extpars->axes.major = 1.0; 598 extpars->axes.minor = extpars->axes.major * psMetadataLookupF32(&status, row, "F25_ARATIO"); 599 extpars->axes.theta = psMetadataLookupF32(&status, row, "F25_THETA"); 600 601 float mag = psMetadataLookupF32(&status, row, "PETRO_MAG"); 602 float magErr = psMetadataLookupF32(&status, row, "PETRO_MAG_ERR"); 603 if (isfinite(mag)) { 604 extpars->petrosianFlux = pow(10., (magOffset - mag) / 2.5); 605 if (isfinite(magErr)) { 606 extpars->petrosianFluxErr = extpars->petrosianFlux / magErr; 607 } 608 } 609 610 extpars->petrosianRadius = psMetadataLookupF32(&status, row, "PETRO_RADIUS"); 611 extpars->petrosianRadiusErr= psMetadataLookupF32(&status, row, "PETRO_RADIUS_ERR"); 612 extpars->petrosianR50 = psMetadataLookupF32(&status, row, "PETRO_RADIUS_50"); 613 extpars->petrosianR50Err = psMetadataLookupF32(&status, row, "PETRO_RADIUS_50_ERR"); 614 extpars->petrosianR90 = psMetadataLookupF32(&status, row, "PETRO_RADIUS_90"); 615 extpars->petrosianR90Err = psMetadataLookupF32(&status, row, "PETRO_RADIUS_90_ERR"); 616 extpars->petrosianFill = psMetadataLookupF32(&status, row, "PETRO_FILL"); 617 618 psVector *radSB = psMetadataLookupVector(&status, row, "PROF_SB"); 619 psVector *radFlux = psMetadataLookupVector(&status, row, "PROF_FLUX"); 620 psVector *radFill = psMetadataLookupVector(&status, row, "PROF_FILL"); 621 622 if (radSB && radSB->n > 0) { 623 extpars->radProfile = pmSourceRadialProfileAlloc(); 624 extpars->radProfile->binSB = psMemIncrRefCounter(radSB); 625 extpars->radProfile->binSum = psMemIncrRefCounter(radFlux); 626 extpars->radProfile->binFill = psMemIncrRefCounter(radFill); 627 } 628 629 psFree(row); 630 } 631 632 return true; 633 } 634 541 635 // XXX this layout is still the same as PS1_DEV_1 542 636 bool pmSourcesWrite_CMF_PS1_SV1_XFIT(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname) … … 607 701 yErr = dPAR[PM_PAR_YPOS]; 608 702 609 axes = pmPSF_ModelToAxes (PAR, 20.0 );703 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 610 704 611 705 row = psMetadataAlloc (); … … 684 778 psFree (outhead); 685 779 psFree (table); 780 return true; 781 } 782 783 bool pmSourcesRead_CMF_PS1_SV1_XFIT(psFits *fits, psMetadata *hduHeader, psArray *sources, long *sourceIndex) 784 { 785 PS_ASSERT_PTR_NON_NULL(fits, false); 786 PS_ASSERT_PTR_NON_NULL(sources, false); 787 788 bool status; 789 long numSources = psFitsTableSize(fits); // Number of sources in table 790 if (numSources == 0) { 791 psError(psErrorCodeLast(), false, "XFIT Table contains no entries\n"); 792 return false; 793 } 794 795 for (long i = 0; i < numSources; i++) { 796 psMetadata *row = psFitsReadTableRow(fits, i); // Table row 797 if (!row) { 798 psError(psErrorCodeLast(), false, "Unable to read row %ld of sources", i); 799 psFree(row); 800 return false; 801 } 802 // Find the source with this sequence number. 803 // XXX: I am assuming that sources is sorted in order of seq. 804 long seq = psMetadataLookupU32 (&status, row, "IPP_IDET"); 805 long j = seq < sources->n ? seq : sources->n - 1; 806 pmSource *source = NULL; 807 for (; j >= 0; j--) { 808 source = sources->data[j]; 809 if (source->seq == seq) { 810 break; 811 } 812 } 813 if (!source) { 814 psError(PS_ERR_UNKNOWN, false, "Failed to find source for row %ld sequence number %ld\n", i, seq); 815 psFree(row); 816 return false; 817 } 818 if (!source->modelFits) { 819 // XXX: where to find the number of models to expect? 820 source->modelFits = psArrayAllocEmpty(5); 821 } 822 psString modelName = psMetadataLookupStr(&status, row, "MODEL_TYPE"); 823 if (!modelName) { 824 psError(PS_ERR_UNKNOWN, true, "Failed to find model name for row %ld\n", i); 825 psFree(row); 826 return false; 827 } 828 pmModelType modelType = pmModelClassGetType(modelName); 829 if (modelType < 0) { 830 psError(PS_ERR_UNKNOWN, true, "Failed to find model type for %s\n", modelName); 831 psFree(row); 832 return false; 833 } 834 pmModel *model = pmModelAlloc(modelType); 835 836 psF32 *PAR = model->params->data.F32; 837 psF32 *dPAR = model->dparams->data.F32; 838 839 PAR[PM_PAR_XPOS] = psMetadataLookupF32(&status, row, "X_EXT"); 840 PAR[PM_PAR_YPOS] = psMetadataLookupF32(&status, row, "Y_EXT"); 841 dPAR[PM_PAR_XPOS] = psMetadataLookupF32(&status, row, "X_EXT_SIG"); 842 dPAR[PM_PAR_YPOS] = psMetadataLookupF32(&status, row, "Y_EXT_SIG"); 843 844 model->mag = psMetadataLookupF32(&status, row, "EXT_INST_MAG"); 845 model->magErr = psMetadataLookupF32(&status, row, "EXT_INST_MAG_SIG"); 846 847 psEllipseAxes axes; 848 axes.major = psMetadataLookupF32(&status, row, "EXT_WIDTH_MAJ"); 849 axes.minor = psMetadataLookupF32(&status, row, "EXT_WIDTH_MIN"); 850 axes.theta = psMetadataLookupF32(&status, row, "EXT_THETA"); 851 if (!pmPSF_AxesToModel(PAR, axes, modelType)) { 852 // Do we need to fail here or can this happen? 853 psError(PS_ERR_UNKNOWN, false, "Failed to convert psf axes to model"); 854 psFree(model); 855 psFree(row); 856 return false; 857 } 858 // XXX: clean this up 859 if (model->params->n > 7) { 860 PAR[7] = psMetadataLookupF32(&status, row, "EXT_PAR_07"); 861 } 862 // read the covariance matrix 863 int nparams = model->params->n; 864 psImage *covar = psImageAlloc(nparams, nparams, PS_TYPE_F32); 865 for (int y = 0; y < nparams; y++) { 866 for (int x = 0; x < nparams; x++) { 867 char name[64]; 868 snprintf(name, 64, "EXT_COVAR_%02d_%02d", y, x); 869 covar->data.F32[y][x] = psMetadataLookupF32(&status, row, name); 870 } 871 } 872 model->covar = covar; 873 874 psArrayAdd(source->modelFits, 1, model); 875 psFree(model); 876 877 psFree(row); 878 } 879 686 880 return true; 687 881 } … … 831 1025 return true; 832 1026 } 1027 1028 bool pmSourcesRead_CMF_PS1_SV1_XRAD(psFits *fits, pmReadout *readout, psMetadata *hduHeader, psArray *sources, long *sourceIndex) 1029 { 1030 PS_ASSERT_PTR_NON_NULL(fits, false); 1031 PS_ASSERT_PTR_NON_NULL(sources, false); 1032 1033 bool status; 1034 long numSources = psFitsTableSize(fits); // Number of sources in table 1035 if (numSources == 0) { 1036 psError(psErrorCodeLast(), false, "XRAD Table contains no entries\n"); 1037 return false; 1038 } 1039 1040 long seq_first = -1; 1041 long seq_last = -1; 1042 psVector *fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32); 1043 long max_entries = -1; 1044 long num_entries = -1; 1045 1046 for (long i = 0; i < numSources; i++) { 1047 psMetadata *row = psFitsReadTableRow(fits, i); // Table row 1048 if (!row) { 1049 psError(psErrorCodeLast(), false, "Unable to read row %ld of sources", i); 1050 psFree(row); 1051 return false; 1052 } 1053 // Find the source with this sequence number. 1054 // XXX: I am assuming that sources is sorted in order of seq. 1055 long seq = psMetadataLookupU32 (&status, row, "IPP_IDET"); 1056 long j = seq < sources->n ? seq : sources->n - 1; 1057 pmSource *source = NULL; 1058 for (; j >= 0; j--) { 1059 source = sources->data[j]; 1060 if (source->seq == seq) { 1061 break; 1062 } 1063 } 1064 if (!source) { 1065 psError(PS_ERR_UNKNOWN, false, "Failed to find source for row %ld sequence number %ld\n", i, seq); 1066 psFree(row); 1067 return false; 1068 } 1069 if (seq_first == -1) { 1070 seq_first = seq; 1071 } 1072 if (seq == seq_first) { 1073 psF32 value = psMetadataLookupF32(&status, row, "PSF_FWHM"); 1074 psVectorAppend(fwhmValues, value); 1075 } 1076 if (seq == seq_last) { 1077 num_entries++; 1078 } else { 1079 num_entries = 1; 1080 seq_last = seq; 1081 } 1082 if (num_entries > max_entries) { 1083 max_entries = num_entries; 1084 } 1085 1086 if (!source->radialAper) { 1087 // XXX: where to find the number of models to expect? 1088 source->radialAper = psArrayAllocEmpty(5); 1089 } 1090 pmSourceRadialApertures *radialAper = pmSourceRadialAperturesAlloc(); 1091 1092 radialAper->flux = psMemIncrRefCounter(psMetadataLookupVector(&status, row, "APER_FLUX")); 1093 radialAper->fluxStdev = psMemIncrRefCounter(psMetadataLookupVector(&status, row, "APER_FLUX_STDEV")); 1094 radialAper->fluxErr = psMemIncrRefCounter(psMetadataLookupVector(&status, row, "APER_FLUX_ERR")); 1095 radialAper->fill = psMemIncrRefCounter(psMetadataLookupVector(&status, row, "APER_FILL")); 1096 1097 psArrayAdd(source->radialAper, 1, radialAper); 1098 1099 psFree(radialAper); 1100 psFree(row); 1101 } 1102 1103 // check for consistency between the length of fwhmValues and the maximum number of entries for each row 1104 if (fwhmValues->n != max_entries) { 1105 psError(PS_ERR_PROGRAMMING, true, "number of PSF_FWHM values found %ld does not match expected number: %ld\n", 1106 fwhmValues->n, max_entries); 1107 psAssert(0, "fixme"); 1108 } 1109 1110 if (!readout->analysis) { 1111 readout->analysis = psMetadataAlloc(); 1112 } 1113 1114 psMetadataAddVector(readout->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues); 1115 psFree(fwhmValues); 1116 1117 return true; 1118 } -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_CMP.c
r31451 r33415 135 135 lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky); 136 136 137 axes = pmPSF_ModelToAxes (PAR, 20.0 );137 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 138 138 139 139 float psfMagErr = isfinite(source->psfMagErr) ? source->psfMagErr : 999; … … 293 293 goto skip_source; 294 294 295 pmPSF_AxesToModel (PAR, axes );295 pmPSF_AxesToModel (PAR, axes, modelType); 296 296 297 297 psArrayAdd (sources, 100, source); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_OBJ.c
r29004 r33415 91 91 } 92 92 93 axes = pmPSF_ModelToAxes (PAR, 20.0 );93 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 94 94 95 95 psLineInit (line); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_PS1_CAL_0.c
r31451 r33415 113 113 yErr = dPAR[PM_PAR_YPOS]; 114 114 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 115 axes = pmPSF_ModelToAxes (PAR, 20.0 );115 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 116 116 } else { 117 117 axes.major = NAN; … … 288 288 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 289 289 290 pmPSF_AxesToModel (PAR, axes );290 pmPSF_AxesToModel (PAR, axes, modelType); 291 291 292 292 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 618 618 yErr = dPAR[PM_PAR_YPOS]; 619 619 620 axes = pmPSF_ModelToAxes (PAR, 20.0 );620 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 621 621 622 622 // generate RA,DEC -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_PS1_DEV_0.c
r31451 r33415 89 89 yErr = dPAR[PM_PAR_YPOS]; 90 90 91 axes = pmPSF_ModelToAxes (PAR, 20.0 );91 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 92 92 } else { 93 93 // XXX: This code seg faults if source->peak is NULL. … … 214 214 source->psfMagErr = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG"); 215 215 216 pmPSF_AxesToModel (PAR, axes );216 pmPSF_AxesToModel (PAR, axes, modelType); 217 217 218 218 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_PS1_DEV_1.c
r31451 r33415 95 95 yErr = dPAR[PM_PAR_YPOS]; 96 96 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 97 axes = pmPSF_ModelToAxes (PAR, 20.0 );97 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 98 98 } else { 99 99 axes.major = NAN; … … 257 257 dPAR[PM_PAR_I0] = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN; 258 258 259 pmPSF_AxesToModel (PAR, axes );259 pmPSF_AxesToModel (PAR, axes, modelType); 260 260 261 261 float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG"); … … 522 522 yErr = dPAR[PM_PAR_YPOS]; 523 523 524 axes = pmPSF_ModelToAxes (PAR, 20.0 );524 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 525 525 526 526 row = psMetadataAlloc (); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_SMPDATA.c
r31451 r33415 92 92 lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky); 93 93 94 axes = pmPSF_ModelToAxes (PAR, 20.0 );94 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 95 95 96 96 } else { … … 190 190 axes.theta = psMetadataLookupF32 (&status, row, "THETA"); 191 191 192 pmPSF_AxesToModel (PAR, axes );192 pmPSF_AxesToModel (PAR, axes, modelType); 193 193 194 194 source->psfMag = psMetadataLookupF32 (&status, row, "MAG_RAW") - ZERO_POINT; -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceIO_SX.c
r31451 r33415 81 81 // pmSourceSextractType (source, &type, &flags); 82 82 83 axes = pmPSF_ModelToAxes (PAR, 20.0 );83 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 84 84 85 85 psLineInit (line); -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceMasks.h
r31670 r33415 46 46 PM_SOURCE_MODE2_DIFF_WITH_DOUBLE = 0x00000002, ///< diff source matched to positive detections in both images 47 47 PM_SOURCE_MODE2_MATCHED = 0x00000004, ///< diff source matched to positive detections in both images 48 PM_SOURCE_MODE2_DIFF_SELF_MATCH = 0x00000800, ///< positive detection match is probably this source 48 49 49 50 PM_SOURCE_MODE2_ON_SPIKE = 0x00000008, ///< > 25% of (PSF-weighted) pixels land on diffraction spike -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceMoments.c
r31670 r33415 96 96 // (int) so they can be used in the image index below. 97 97 98 // do 2 passes : the first pass should use a somewhat smaller radius and no sigma window to 99 // get an unbiased (but probably noisy) centroid 100 if (!pmSourceMomentsGetCentroid (source, 0.75*radius, 0.0, minSN, maskVal, source->peak->xf, source->peak->yf)) { 101 return false; 102 } 103 // second pass applies the Gaussian window and uses the centroid from the first pass 104 if (!pmSourceMomentsGetCentroid (source, radius, sigma, minSN, maskVal, source->moments->Mx, source->moments->My)) { 98 // XXX // do 2 passes : the first pass should use a somewhat smaller radius and no sigma window to 99 // XXX // get an unbiased (but probably noisy) centroid 100 // XXX if (!pmSourceMomentsGetCentroid (source, 0.75*radius, 0.0, minSN, maskVal, source->peak->xf, source->peak->yf)) { 101 // XXX return false; 102 // XXX } 103 // XXX // second pass applies the Gaussian window and uses the centroid from the first pass 104 // XXX if (!pmSourceMomentsGetCentroid (source, radius, sigma, minSN, maskVal, source->moments->Mx, source->moments->My)) { 105 // XXX return false; 106 // XXX } 107 108 // If we use a large radius for the centroid, it will be biased by any neighbors. The flux 109 // of any object drops pretty quickly outside 1-2 sigmas. (The exception is bright 110 // saturated stars, for which we need to use a very large radius here) 111 if (!pmSourceMomentsGetCentroid (source, 1.5*sigma, 0.0, minSN, maskVal, source->peak->xf, source->peak->yf)) { 105 112 return false; 106 113 } … … 108 115 // Now calculate higher-order moments, using the above-calculated first moments to adjust coordinates 109 116 // Xn = SUM (x - xc)^n * (z - sky) 110 111 float RFW = 0.0;112 float RHW = 0.0;113 114 float RF = 0.0;115 float RH = 0.0;116 float RS = 0.0;117 117 float XX = 0.0; 118 118 float XY = 0.0; … … 143 143 float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage 144 144 145 // calculate the higher-order moments using Xo,Yo 145 146 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 146 147 … … 194 195 Sum += pDiff; 195 196 196 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?)197 197 float r = sqrt(r2); 198 float rf = r * fDiff;199 float rh = sqrt(r) * fDiff;200 float rs = fDiff;201 202 float rfw = r * pDiff;203 float rhw = sqrt(r) * pDiff;204 198 205 199 float x = xDiff * pDiff; … … 221 215 float yyyy = yDiff * yyy / r2; 222 216 223 RF += rf;224 RH += rh;225 RS += rs;226 227 RFW += rfw;228 RHW += rhw;229 230 217 XX += xx; 231 218 XY += xy; … … 242 229 XYYY += xyyy; 243 230 YYYY += yyyy; 231 232 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 233 // XXX float r = sqrt(r2); 234 // XXX float rf = r * fDiff; 235 // XXX float rh = sqrt(r) * fDiff; 236 // XXX float rs = fDiff; 237 // XXX 238 // XXX float rfw = r * pDiff; 239 // XXX float rhw = sqrt(r) * pDiff; 240 // XXX 241 // XXX RF += rf; 242 // XXX RH += rh; 243 // XXX RS += rs; 244 // XXX 245 // XXX RFW += rfw; 246 // XXX RHW += rhw; 244 247 } 245 248 } 246 247 source->moments->Mrf = RF/RS;248 source->moments->Mrh = RH/RS;249 250 249 source->moments->Mxx = XX/Sum; 251 250 source->moments->Mxy = XY/Sum; … … 262 261 source->moments->Mxyyy = XYYY/Sum; 263 262 source->moments->Myyyy = YYYY/Sum; 263 264 // *** now calculate the 1st radial moment (for kron flux) -- symmetrical averaging 265 266 float **vPix = source->pixels->data.F32; 267 float **vWgt = source->variance->data.F32; 268 psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA; 269 270 float RF = 0.0; 271 float RH = 0.0; 272 float RS = 0.0; 273 274 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 275 276 float yDiff = row - yCM; 277 if (fabs(yDiff) > radius) continue; 278 279 // coordinate of mirror pixel 280 int yFlip = yCM - yDiff; 281 if (yFlip < 0) continue; 282 if (yFlip >= source->pixels->numRows) continue; 283 284 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 285 // check mask and value for this pixel 286 if (vMsk && (vMsk[row][col] & maskVal)) continue; 287 if (isnan(vPix[row][col])) continue; 288 289 float xDiff = col - xCM; 290 if (fabs(xDiff) > radius) continue; 291 292 // coordinate of mirror pixel 293 int xFlip = xCM - xDiff; 294 if (xFlip < 0) continue; 295 if (xFlip >= source->pixels->numCols) continue; 296 297 // check mask and value for mirror pixel 298 if (vMsk && (vMsk[yFlip][xFlip] & maskVal)) continue; 299 if (isnan(vPix[yFlip][xFlip])) continue; 300 301 // radius is just a function of (xDiff, yDiff) 302 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 303 if (r2 > R2) continue; 304 305 float fDiff1 = vPix[row][col] - sky; 306 float fDiff2 = vPix[yFlip][xFlip] - sky; 307 float pDiff = (fDiff1 > 0.0) ? sqrt(fabs(fDiff1*fDiff2)) : -sqrt(fabs(fDiff1*fDiff2)); 308 309 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?) 310 float r = sqrt(r2); 311 float rf = r * pDiff; 312 float rh = sqrt(r) * pDiff; 313 float rs = 0.5 * (fDiff1 + fDiff2); 314 315 RF += rf; 316 RH += rh; 317 RS += rs; 318 } 319 } 320 321 source->moments->Mrf = RF/RS; 322 source->moments->Mrh = RH/RS; 264 323 265 324 // if Mrf (first radial moment) is very small, we are getting into low-significance … … 270 329 kronRefRadius = MIN(radius, kronRefRadius); 271 330 } 331 332 // *** now calculate the kron flux values using the 1st radial moment 272 333 273 334 float radKinner = 1.0*kronRefRadius; … … 283 344 float SumOuter = 0.0; 284 345 346 // calculate the Kron flux, and related fluxes (NO symmetrical averaging) 285 347 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 286 348 287 349 float yDiff = row - yCM; 288 350 if (fabs(yDiff) > radKouter) continue; 351 352 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 353 // check mask and value for this pixel 354 if (vMsk && (vMsk[row][col] & maskVal)) continue; 355 if (isnan(vPix[row][col])) continue; 356 357 float xDiff = col - xCM; 358 if (fabs(xDiff) > radKouter) continue; 359 360 // radKron is just a function of (xDiff, yDiff) 361 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff); 362 363 float fDiff1 = vPix[row][col] - sky; 364 float pDiff = fDiff1; 365 float wDiff = vWgt[row][col]; 366 367 // skip pixels below specified significance level. this is allowed, but should be 368 // avoided -- the over-weights the wings of bright stars compared to those of faint 369 // stars. 370 if (PS_SQR(pDiff) < minSN2*wDiff) continue; 371 372 float r = sqrt(r2); 373 if (r < radKron) { 374 Sum += pDiff; 375 Var += wDiff; 376 nKronPix ++; 377 // if (beVerbose) fprintf (stderr, "mome: %d %d %f %f %f\n", col, row, sky, *vPix, Sum); 378 } 379 380 // use sigma (fixed by psf) not a radKron based value 381 if (r < sigma) { 382 SumCore += pDiff; 383 VarCore += wDiff; 384 nCorePix ++; 385 } 386 387 if ((r > radKinner) && (r < radKron)) { 388 SumInner += pDiff; 389 nInner ++; 390 } 391 if ((r > radKron) && (r < radKouter)) { 392 SumOuter += pDiff; 393 nOuter ++; 394 } 395 } 396 } 397 // *** should I rescale these fluxes by pi R^2 / nNpix? 398 // XXX source->moments->KronCore = SumCore * M_PI * PS_SQR(sigma) / nCorePix; 399 // XXX source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix; 400 // XXX source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix; 401 // XXX source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix; 402 // XXX source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron) - PS_SQR(radKinner)) / nInner; 403 // XXX source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) - PS_SQR(radKron)) / nOuter; 404 405 source->moments->KronCore = SumCore; 406 source->moments->KronCoreErr = sqrt(VarCore); 407 source->moments->KronFlux = Sum; 408 source->moments->KronFluxErr = sqrt(Var); 409 source->moments->KronFinner = SumInner; 410 source->moments->KronFouter = SumOuter; 411 412 // XXX not sure I should save this here... 413 source->moments->KronFluxPSF = source->moments->KronFlux; 414 source->moments->KronFluxPSFErr = source->moments->KronFluxErr; 415 source->moments->KronRadiusPSF = source->moments->Mrf; 416 417 psTrace ("psModules.objects", 4, "Mrf: %f KronFlux: %f Mxx: %f Mxy: %f Myy: %f Mxxx: %f Mxxy: %f Mxyy: %f Myyy: %f Mxxxx: %f Mxxxy: %f Mxxyy: %f Mxyyy: %f Mxyyy: %f\n", 418 source->moments->Mrf, source->moments->KronFlux, 419 source->moments->Mxx, source->moments->Mxy, source->moments->Myy, 420 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy, 421 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy); 422 423 psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f My: %f Sum: %f Mxx: %f Mxy: %f Myy: %f sky: %f Npix: %d\n", 424 source->peak->xf, source->peak->yf, source->peak->rawFlux, sqrt(source->peak->detValue), source->moments->Mx, source->moments->My, Sum, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, sky, source->moments->nPixels); 425 426 return(true); 427 } 428 429 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) { 430 431 // First Pass: calculate the first moments (these are subtracted from the coordinates below) 432 // Sum = SUM (z - sky) 433 // X1 = SUM (x - xc)*(z - sky) 434 // .. etc 435 436 float sky = 0.0; 437 438 float peakPixel = -PS_MAX_F32; 439 psS32 numPixels = 0; 440 float Sum = 0.0; 441 float Var = 0.0; 442 float X1 = 0.0; 443 float Y1 = 0.0; 444 float R2 = PS_SQR(radius); 445 float minSN2 = PS_SQR(minSN); 446 float rsigma2 = 0.5 / PS_SQR(sigma); 447 448 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage 449 float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage 450 451 // we are guaranteed to have a valid pixel and variance at this location (right? right?) 452 // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]); 453 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 454 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel"); 455 // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel"); 456 457 // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should 458 // not depend on the fractional pixel location of the source. However, the aperture 459 // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel 460 // position of the expected centroid 461 462 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 463 464 float yDiff = row + 0.5 - yPeak; 465 if (fabs(yDiff) > radius) continue; 289 466 290 467 float *vPix = source->pixels->data.F32[row]; 291 468 float *vWgt = source->variance->data.F32[row]; 292 469 293 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];294 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];470 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row]; 471 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row]; 295 472 296 473 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) { … … 304 481 if (isnan(*vPix)) continue; 305 482 306 float xDiff = col - xCM;307 if (fabs(xDiff) > radKouter) continue;308 309 // radKron is just a function of (xDiff, yDiff)310 float r2 = PS_SQR(xDiff) + PS_SQR(yDiff);311 312 float pDiff = *vPix - sky;313 float wDiff = *vWgt;314 315 // skip pixels below specified significance level. this is allowed, but should be316 // avoided -- the over-weights the wings of bright stars compared to those of faint317 // stars.318 if (PS_SQR(pDiff) < minSN2*wDiff) continue;319 320 float r = sqrt(r2);321 if (r < radKron) {322 Sum += pDiff;323 Var += wDiff;324 nKronPix ++;325 // if (beVerbose) fprintf (stderr, "mome: %d %d %f %f %f\n", col, row, sky, *vPix, Sum);326 }327 328 // use sigma (fixed by psf) not a radKron based value329 if (r < sigma) {330 SumCore += pDiff;331 VarCore += wDiff;332 nCorePix ++;333 }334 335 if ((r > radKinner) && (r < radKron)) {336 SumInner += pDiff;337 nInner ++;338 }339 if ((r > radKron) && (r < radKouter)) {340 SumOuter += pDiff;341 nOuter ++;342 }343 }344 }345 // *** should I rescale these fluxes by pi R^2 / nNpix?346 source->moments->KronCore = SumCore * M_PI * PS_SQR(sigma) / nCorePix;347 source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix;348 source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix;349 source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix;350 source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron) - PS_SQR(radKinner)) / nInner;351 source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) - PS_SQR(radKron)) / nOuter;352 353 psTrace ("psModules.objects", 4, "Mrf: %f KronFlux: %f Mxx: %f Mxy: %f Myy: %f Mxxx: %f Mxxy: %f Mxyy: %f Myyy: %f Mxxxx: %f Mxxxy: %f Mxxyy: %f Mxyyy: %f Mxyyy: %f\n",354 source->moments->Mrf, source->moments->KronFlux,355 source->moments->Mxx, source->moments->Mxy, source->moments->Myy,356 source->moments->Mxxx, source->moments->Mxxy, source->moments->Mxyy, source->moments->Myyy,357 source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy);358 359 psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f My: %f Sum: %f Mxx: %f Mxy: %f Myy: %f sky: %f Npix: %d\n",360 source->peak->xf, source->peak->yf, source->peak->rawFlux, sqrt(source->peak->detValue), source->moments->Mx, source->moments->My, Sum, source->moments->Mxx, source->moments->Mxy, source->moments->Myy, sky, source->moments->nPixels);361 362 return(true);363 }364 365 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) {366 367 // First Pass: calculate the first moments (these are subtracted from the coordinates below)368 // Sum = SUM (z - sky)369 // X1 = SUM (x - xc)*(z - sky)370 // .. etc371 372 float sky = 0.0;373 374 float peakPixel = -PS_MAX_F32;375 psS32 numPixels = 0;376 float Sum = 0.0;377 float Var = 0.0;378 float X1 = 0.0;379 float Y1 = 0.0;380 float R2 = PS_SQR(radius);381 float minSN2 = PS_SQR(minSN);382 float rsigma2 = 0.5 / PS_SQR(sigma);383 384 float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage385 float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage386 387 // we are guaranteed to have a valid pixel and variance at this location (right? right?)388 // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);389 // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel");390 // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel");391 // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel");392 393 // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should394 // not depend on the fractional pixel location of the source. However, the aperture395 // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel396 // position of the expected centroid397 398 for (psS32 row = 0; row < source->pixels->numRows ; row++) {399 400 float yDiff = row + 0.5 - yPeak;401 if (fabs(yDiff) > radius) continue;402 403 float *vPix = source->pixels->data.F32[row];404 float *vWgt = source->variance->data.F32[row];405 406 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];407 // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];408 409 for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {410 if (vMsk) {411 if (*vMsk & maskVal) {412 vMsk++;413 continue;414 }415 vMsk++;416 }417 if (isnan(*vPix)) continue;418 419 483 float xDiff = col + 0.5 - xPeak; 420 484 if (fabs(xDiff) > radius) continue; -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceOutputs.c
r31451 r33415 107 107 } 108 108 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXY]) && isfinite(PAR[PM_PAR_SYY])) { 109 axes = pmPSF_ModelToAxes (PAR, 20.0 );109 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type); 110 110 outputs->psfMajor = axes.major; 111 111 outputs->psfMinor = axes.minor; … … 178 178 moments->KronCore = source->moments ? source->moments->KronCore : NAN; 179 179 moments->KronCoreErr = source->moments ? source->moments->KronCoreErr : NAN; 180 181 return true; 182 } 180 moments->KronPSF = source->moments ? source->moments->KronFluxPSF : NAN; 181 moments->KronPSFErr = source->moments ? source->moments->KronFluxPSFErr : NAN; 182 183 return true; 184 } 185 186 bool pmSourceLocalAstrometry (psSphere *ptSky, float *posAngle, float *pltScale, pmChip *chip, float xPos, float yPos) { 187 188 pmFPA *fpa = chip->parent; 189 190 if (!chip->toFPA) goto escape; 191 if (!fpa->toTPA) goto escape; 192 if (!fpa->toSky) goto escape; 193 194 // generate RA,DEC 195 psPlane ptCH, ptFP, ptTP_o, ptTP_x, ptTP_y; 196 197 // calculate the astrometry for the coordinate of interest 198 ptCH.x = xPos; 199 ptCH.y = yPos; 200 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 201 psPlaneTransformApply (&ptTP_o, fpa->toTPA, &ptFP); 202 psDeproject (ptSky, &ptTP_o, fpa->toSky); 203 204 // calculate the astrometry for the coordinate + 1pix in X 205 ptCH.x = xPos + 1.0; 206 ptCH.y = yPos; 207 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 208 psPlaneTransformApply (&ptTP_x, fpa->toTPA, &ptFP); 209 210 // calculate the astrometry for the coordinate + 1pix in Y 211 ptCH.x = xPos; 212 ptCH.y = yPos + 1.0; 213 psPlaneTransformApply (&ptFP, chip->toFPA, &ptCH); 214 psPlaneTransformApply (&ptTP_y, fpa->toTPA, &ptFP); 215 216 // the resulting Tangent Plane coordinates are in TP pixels; convert to local Tangent Plane 217 // degrees 218 219 float dTPx_dCHx = fpa->toSky->Xs * (ptTP_x.x - ptTP_o.x); 220 float dTPy_dCHx = fpa->toSky->Ys * (ptTP_x.y - ptTP_o.y); 221 222 float dTPx_dCHy = fpa->toSky->Xs * (ptTP_y.x - ptTP_o.x); 223 float dTPy_dCHy = fpa->toSky->Ys * (ptTP_y.y - ptTP_o.y); 224 225 float pltScale_x = hypot(dTPx_dCHx, dTPy_dCHx); 226 float pltScale_y = hypot(dTPx_dCHy, dTPy_dCHy); 227 *pltScale = 0.5*(pltScale_x + pltScale_y); 228 229 float posAngle_x = atan2 (+dTPy_dCHx, +dTPx_dCHx); 230 float posAngle_y = atan2 (-dTPy_dCHy, +dTPx_dCHy); 231 *posAngle = 0.5*(posAngle_x + posAngle_y); 232 233 return true; 234 235 escape: 236 // no astrometry calibration, give up 237 ptSky->r = NAN; 238 ptSky->d = NAN; 239 *posAngle = NAN; 240 *pltScale = NAN; 241 242 return false; 243 } 244 -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourceOutputs.h
r31153 r33415 52 52 float KronCore; 53 53 float KronCoreErr; 54 float KronPSF; 55 float KronPSFErr; 54 56 } pmSourceOutputsMoments; 55 57 -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourcePhotometry.c
r31670 r33415 56 56 static psImageMaskType maskBurntool = 0; 57 57 static psImageMaskType maskConvPoor = 0; 58 static psImageMaskType maskGhost = 0; 59 static psImageMaskType maskGlint = 0; 58 60 59 61 bool pmSourceMagnitudesInit (pmConfig *config, psMetadata *recipe) … … 68 70 maskBurntool = pmConfigMaskGet("BURNTOOL", config); 69 71 maskConvPoor = pmConfigMaskGet("CONV.POOR", config); 72 maskGhost = pmConfigMaskGet("GHOST", config); 73 maskGlint = pmConfigMaskGet("GHOST", config); 70 74 maskSuspect = maskSpike | maskStarCore | maskBurntool | maskConvPoor; 71 75 } … … 94 98 { 95 99 PS_ASSERT_PTR_NON_NULL(source, false); 96 PS_ASSERT_PTR_NON_NULL(psf, false);100 // PS_ASSERT_PTR_NON_NULL(psf, false); 97 101 98 102 int status = false; … … 533 537 } 534 538 539 // Check that if the peak is on/off a ghost, glint, or diffraction spike. In regular IPP 540 // processing, these values are only set in the image mask after the 'camera' stage 541 542 int xChip = source->peak->x; 543 int yChip = source->peak->y; 544 545 // need to access the parent if we are looking at a subimage (likely) 546 psImage *chipImage = (source->pixels == NULL) ? source->pixels : (psImage *) source->pixels->parent; 547 548 bool onChip = true; 549 onChip &= (xChip >= 0); 550 onChip &= (xChip < chipImage->numCols); 551 onChip &= (yChip >= 0); 552 onChip &= (yChip < chipImage->numRows); 553 if (!onChip) { 554 // if the source is off the edge of the chip, raise a different bit? 555 source->mode |= PM_SOURCE_MODE_OFF_CHIP; 556 } else { 557 int xMask = xChip - mask->col0; 558 int yMask = yChip - mask->row0; 559 psImageMaskType maskValue = mask->data.PS_TYPE_IMAGE_MASK_DATA[yMask][xMask]; 560 if (maskValue & maskGhost) { 561 source->mode |= PM_SOURCE_MODE_ON_GHOST; 562 } 563 pmSourceMode PM_SOURCE_MODE_ON_GLINT = PM_SOURCE_MODE_ON_GHOST; 564 if (maskValue & maskGlint) { 565 source->mode |= PM_SOURCE_MODE_ON_GLINT; 566 } 567 if (maskValue & maskSpike) { 568 source->mode |= PM_SOURCE_MODE_ON_SPIKE; 569 } 570 } 535 571 return (true); 536 572 } -
branches/meh_branches/ppstack_test/psModules/src/objects/pmSourcePlotPSFModel.c
r29004 r33415 145 145 // force the axis ratio to be < 20.0 146 146 psEllipseAxes axes_mnt = psEllipseMomentsToAxes (moments, 20.0); 147 psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, 20.0 );147 psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, 20.0, model->type); 148 148 149 149 // moments major axis
Note:
See TracChangeset
for help on using the changeset viewer.
