Changeset 31153 for trunk/psModules/src/objects/pmSourceIO_CMF_PS1_SV1.c
- Timestamp:
- Apr 4, 2011, 1:04:41 PM (15 years ago)
- Location:
- trunk/psModules
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/objects/pmSourceIO_CMF_PS1_SV1.c (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules
- Property svn:ignore
-
old new 28 28 ChangeLog 29 29 psmodules-*.tar.* 30 a.out.dSYM
-
- Property svn:ignore
-
trunk/psModules/src/objects/pmSourceIO_CMF_PS1_SV1.c
r30621 r31153 50 50 51 51 #include "pmSourceIO.h" 52 #include "pmSourceOutputs.h" 52 53 53 54 // panstarrs-style FITS table output (header + table in 1st extension) … … 66 67 psArray *table; 67 68 psMetadata *row; 68 psF32 *PAR, *dPAR;69 psEllipseAxes axes;70 psF32 xPos, yPos;71 psF32 xErr, yErr;72 psF32 errMag, chisq, apRadius;73 psS32 nPix, nDOF;74 69 75 70 pmChip *chip = readout->parent->parent; 76 pmFPA *fpa = chip->parent; 77 78 bool status1 = false; 79 bool status2 = false; 80 float magOffset = NAN; 81 float exptime = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE"); 82 float zeropt = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP"); 83 if (!isfinite(zeropt)) { 84 zeropt = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS"); 85 } 86 if (status1 && status2 && (exptime > 0.0)) { 87 magOffset = zeropt + 2.5*log10(exptime); 88 } 89 float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR"); 90 91 // if the sequence is defined, write these in seq order; otherwise 92 // write them in S/N order: 71 72 // if the sequence is defined, write these in seq order; otherwise write them in S/N order. 73 // Careful: if we are working with child sources, then we need to sort by the parent info, 74 // not our info 93 75 if (sources->n > 0) { 94 pmSource *source = (pmSource *)sources->data[0];76 pmSource *source = sources->data[0]; 95 77 if (source->seq == -1) { 96 // let's write these out in S/N order 97 sources = psArraySort (sources, pmSourceSortBySN); 78 sources = psArraySort (sources, pmSourceSortByFlux); 98 79 } else { 99 80 sources = psArraySort (sources, pmSourceSortBySeq); … … 103 84 table = psArrayAllocEmpty (sources->n); 104 85 105 # if (0) 106 // we use this just to define the output vectors (which must be present for all objects) 107 bool status = false; 108 psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER"); 109 psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER"); 110 psAssert (radMax, "this must have been defined and tested earlier!"); 111 psAssert (radMax->n, "this must have been defined and tested earlier!"); 112 psAssert (radMin->n == radMax->n, "inconsistent annular bins"); 113 114 // write the radial profile apertures to header 115 for (int i = 0; i < radMax->n; i++) { 116 sprintf (keyword1, "RMIN_%02d", i); 117 sprintf (keyword2, "RMAX_%02d", i); 118 psMetadataAddF32 (imageHeader, PS_LIST_TAIL, keyword1, PS_META_REPLACE, "min radius for SB profile", radMin->data.F32[i]); 119 psMetadataAddF32 (imageHeader, PS_LIST_TAIL, keyword2, PS_META_REPLACE, "min radius for SB profile", radMax->data.F32[i]); 120 } 121 # endif 86 short nImageOverlap; 87 float magOffset; 88 float zeroptErr; 89 float fwhmMajor; 90 float fwhmMinor; 91 pmSourceOutputsCommonValues (&nImageOverlap, &magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader); 122 92 123 93 // we write out PSF-fits for all sources, regardless of quality. the source flags tell us the state 124 94 // by the time we call this function, all values should be assigned. let's use asserts to be sure in some cases. 125 95 for (int i = 0; i < sources->n; i++) { 126 pmSource *source = (pmSource *) sources->data[i]; 127 128 // If source->seq is -1, source was generated in this analysis. If source->seq is 129 // not -1, source was read from elsewhere: in the latter case, preserve the source 130 // ID. source.seq is used instead of source.id since the latter is a const 131 // generated on Alloc, and would thus be wrong for read in sources. 96 // this is the source associated with this image 97 pmSource *thisSource = sources->data[i]; 98 99 // this is the "real" version of this source 100 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 101 102 // If source->seq is -1, source is unique and generated in this analysis. If 103 // source->seq is not -1, source was read from elsewhere or tied to other source (eg 104 // from another image): in the latter case, preserve the source ID. source.seq is used 105 // instead of source.id since the latter is a const generated on Alloc, and would thus 106 // be wrong for read in sources. 132 107 if (source->seq == -1) { 133 108 source->seq = i; 134 109 } 135 110 136 // no difference between PSF and non-PSF model 137 pmModel *model = source->modelPSF; 138 139 if (model != NULL) { 140 PAR = model->params->data.F32; 141 dPAR = model->dparams->data.F32; 142 xPos = PAR[PM_PAR_XPOS]; 143 yPos = PAR[PM_PAR_YPOS]; 144 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) { 145 xErr = dPAR[PM_PAR_XPOS]; 146 yErr = dPAR[PM_PAR_YPOS]; 147 } else { 148 // in linear-fit mode, there is no error on the centroid 149 xErr = source->peak->dx; 150 yErr = source->peak->dy; 151 } 152 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) { 153 axes = pmPSF_ModelToAxes (PAR, 20.0); 154 } else { 155 axes.major = NAN; 156 axes.minor = NAN; 157 axes.theta = NAN; 158 } 159 chisq = model->chisq; 160 nDOF = model->nDOF; 161 nPix = model->nPix; 162 apRadius = source->apRadius; 163 errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0]; 164 } else { 165 xPos = source->peak->xf; 166 yPos = source->peak->yf; 167 xErr = source->peak->dx; 168 yErr = source->peak->dy; 169 axes.major = NAN; 170 axes.minor = NAN; 171 axes.theta = NAN; 172 chisq = NAN; 173 nDOF = 0; 174 nPix = 0; 175 apRadius = NAN; 176 errMag = NAN; 177 } 178 179 float calMag = isfinite(magOffset) ? source->psfMag + magOffset : NAN; 180 float peakMag = (source->peak->flux > 0) ? -2.5*log10(source->peak->flux) : NAN; 181 psS16 nImageOverlap = 1; 182 183 psSphere ptSky = {0.0, 0.0, 0.0, 0.0}; 184 float posAngle = 0.0; 185 float pltScale = 0.0; 186 pmSourceLocalAstrometry (&ptSky, &posAngle, &pltScale, chip, xPos, yPos); 111 // set the 'best' values for various output fields: 112 pmSourceOutputs outputs; 113 pmSourceOutputsSetValues (&outputs, source, chip, fwhmMajor, fwhmMinor, magOffset); 114 115 pmSourceOutputsMoments moments; 116 pmSourceOutputsSetMoments (&moments, source); 187 117 188 118 row = psMetadataAlloc (); 189 119 psMetadataAdd (row, PS_LIST_TAIL, "IPP_IDET", PS_DATA_U32, "IPP detection identifier index", source->seq); 190 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", xPos);191 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", yPos);192 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", xErr); // XXX this is only measured for non-linear fits193 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", yErr); // XXX this is only measured for non-linear fits194 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", posAngle*PS_DEG_RAD);195 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", pltScale*PS_DEG_RAD*3600.0);120 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF", PS_DATA_F32, "PSF x coordinate", outputs.xPos); 121 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF", PS_DATA_F32, "PSF y coordinate", outputs.yPos); 122 psMetadataAdd (row, PS_LIST_TAIL, "X_PSF_SIG", PS_DATA_F32, "Sigma in PSF x coordinate", outputs.xErr); 123 psMetadataAdd (row, PS_LIST_TAIL, "Y_PSF_SIG", PS_DATA_F32, "Sigma in PSF y coordinate", outputs.yErr); 124 psMetadataAdd (row, PS_LIST_TAIL, "POSANGLE", PS_DATA_F32, "position angle at source (degrees)", outputs.posAngle); 125 psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE", PS_DATA_F32, "plate scale at source (arcsec/pixel)", outputs.pltScale); 196 126 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG", PS_DATA_F32, "PSF fit instrumental magnitude", source->psfMag); 197 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", errMag);127 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude", source->errMag); 198 128 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX", PS_DATA_F32, "PSF fit instrumental flux (counts)", source->psfFlux); 199 129 psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX_SIG",PS_DATA_F32, "Sigma of PSF instrumental flux", source->psfFluxErr); 200 130 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG", PS_DATA_F32, "magnitude in standard aperture", source->apMag); 201 131 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW", PS_DATA_F32, "magnitude in reported aperture", source->apMagRaw); 202 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", apRadius);203 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", peakMag);204 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", calMag);132 psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS", PS_DATA_F32, "radius used for aperture mags", outputs.apRadius); 133 psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude", outputs.peakMag); 134 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG", PS_DATA_F32, "PSF Magnitude using supplied calibration", outputs.calMag); 205 135 psMetadataAdd (row, PS_LIST_TAIL, "CAL_PSF_MAG_SIG", PS_DATA_F32, "measured scatter of zero point calibration", zeroptErr); 206 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", ptSky.r*PS_DEG_RAD);207 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", ptSky.d*PS_DEG_RAD);136 psMetadataAdd (row, PS_LIST_TAIL, "RA_PSF", PS_DATA_F64, "PSF RA coordinate (degrees)", outputs.ra); 137 psMetadataAdd (row, PS_LIST_TAIL, "DEC_PSF", PS_DATA_F64, "PSF DEC coordinate (degrees)", outputs.dec); 208 138 psMetadataAdd (row, PS_LIST_TAIL, "SKY", PS_DATA_F32, "Sky level", source->sky); 209 139 psMetadataAdd (row, PS_LIST_TAIL, "SKY_SIGMA", PS_DATA_F32, "Sigma of sky level", source->skyErr); 210 140 211 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", chisq);141 psMetadataAdd (row, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "Chisq of PSF-fit", outputs.chisq); 212 142 psMetadataAdd (row, PS_LIST_TAIL, "CR_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to CF", source->crNsigma); 213 143 psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA", PS_DATA_F32, "Nsigma deviations from PSF to EXT", source->extNsigma); 214 144 215 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", axes.major);216 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", axes.minor);217 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", axes.theta);145 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR", PS_DATA_F32, "PSF width (major axis)", outputs.psfMajor); 146 psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR", PS_DATA_F32, "PSF width (minor axis)", outputs.psfMinor); 147 psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA", PS_DATA_F32, "PSF orientation angle", outputs.psfTheta); 218 148 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF", PS_DATA_F32, "PSF coverage/quality factor (bad)", source->pixWeightNotBad); 219 149 psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT", PS_DATA_F32, "PSF coverage/quality factor (poor)", source->pixWeightNotPoor); 220 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", nDOF); 221 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", nPix); 222 223 // distinguish moments measure from window vs S/N > XX ?? 224 float Mxx = source->moments ? source->moments->Mxx : NAN; 225 float Mxy = source->moments ? source->moments->Mxy : NAN; 226 float Myy = source->moments ? source->moments->Myy : NAN; 227 228 float Mrf = source->moments ? source->moments->Mrf : NAN; 229 float Mrh = source->moments ? source->moments->Mrh : NAN; 230 float Krf = source->moments ? source->moments->KronFlux : NAN; 231 float dKrf = source->moments ? source->moments->KronFluxErr : NAN; 232 233 float Kinner = source->moments ? source->moments->KronFinner : NAN; 234 float Kouter = source->moments ? source->moments->KronFouter : NAN; 235 236 float M_c3 = source->moments ? 1.0*source->moments->Mxxx - 3.0*source->moments->Mxyy : NAN; 237 float M_s3 = source->moments ? 3.0*source->moments->Mxxy - 1.0*source->moments->Myyy : NAN; 238 float M_c4 = source->moments ? 1.0*source->moments->Mxxxx - 6.0*source->moments->Mxxyy + 1.0*source->moments->Myyyy : NAN; 239 float M_s4 = source->moments ? 4.0*source->moments->Mxxxy - 4.0*source->moments->Mxyyy : NAN; 240 241 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", Mxx); 242 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", Mxy); 243 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", Myy); 244 245 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", M_c3); 246 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", M_s3); 247 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", M_c4); 248 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", M_s4); 249 250 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", Mrf); 251 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", Mrh); 252 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Krf); 253 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", dKrf); 254 255 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Kinner); 256 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", Kouter); 150 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NDOF", PS_DATA_S32, "degrees of freedom", outputs.nDOF); 151 psMetadataAdd (row, PS_LIST_TAIL, "PSF_NPIX", PS_DATA_S32, "number of pixels in fit", outputs.nPix); 152 153 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XX", PS_DATA_F32, "second moments (X^2)", moments.Mxx); 154 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_XY", PS_DATA_F32, "second moments (X*Y)", moments.Mxy); 155 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_YY", PS_DATA_F32, "second moments (Y*Y)", moments.Myy); 156 157 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3C", PS_DATA_F32, "third momemt cos theta", moments.M_c3); 158 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M3S", PS_DATA_F32, "third momemt sin theta", moments.M_s3); 159 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C", PS_DATA_F32, "fourth momemt cos theta", moments.M_c4); 160 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S", PS_DATA_F32, "fourth momemt sin theta", moments.M_s4); 161 162 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1", PS_DATA_F32, "first radial moment", moments.Mrf); 163 psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_RH", PS_DATA_F32, "half radial moment", moments.Mrh); 164 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Krf); 165 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_ERR", PS_DATA_F32, "Kron Flux Error", moments.dKrf); 166 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kinner); 167 psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER", PS_DATA_F32, "Kron Flux (in 2.5 R1)", moments.Kouter); 257 168 258 169 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS", PS_DATA_U32, "psphot analysis flags", source->mode); 259 170 psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2", PS_DATA_U32, "psphot analysis flags", source->mode2); 260 261 # if (0)262 // XXX if we have raw radial apertures, write them out here263 psVector *radFlux = psVectorAlloc(radMax->n, PS_TYPE_F32);264 psVector *radFluxErr = psVectorAlloc(radMax->n, PS_TYPE_F32);265 psVector *radFill = psVectorAlloc(radMax->n, PS_TYPE_F32);266 psVectorInit (radFlux, NAN);267 psVectorInit (radFluxErr, NAN);268 psVectorInit (radFill, NAN);269 if (!source->radial) goto empty_annuli;270 if (!source->radial->flux) goto empty_annuli;271 if (!source->radial->fill) goto empty_annuli;272 psAssert (source->radial->flux->n <= radFlux->n, "inconsistent vector lengths");273 psAssert (source->radial->fill->n <= radFlux->n, "inconsistent vector lengths");274 275 // copy the data from fluxVal (which is not guaranteed to be the full length) to radFlux276 for (int j = 0; j < source->radial->flux->n; j++) {277 radFlux->data.F32[j] = source->radial->flux->data.F32[j];278 radFluxErr->data.F32[j] = source->radial->fluxErr->data.F32[j];279 radFill->data.F32[j] = source->radial->fill->data.F32[j];280 }281 282 empty_annuli:283 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux);284 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_ERR", PS_DATA_VECTOR, "flux error in annuli", radFluxErr);285 psMetadataAdd (row, PS_LIST_TAIL, "APER_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill);286 psFree (radFlux);287 psFree (radFluxErr);288 psFree (radFill);289 # endif290 171 291 172 // XXX not sure how to get this : need to load Nimages with weight? … … 406 287 // recreate the peak to match (xPos, yPos) +/- (xErr, yErr) 407 288 source->peak = pmPeakAlloc(PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], peakFlux, PM_PEAK_LONE); 408 source->peak->flux = peakFlux; 289 source->peak->rawFlux = peakFlux; 290 source->peak->smoothFlux = peakFlux; 409 291 source->peak->xf = PAR[PM_PAR_XPOS]; // more accurate position 410 292 source->peak->yf = PAR[PM_PAR_YPOS]; // more accurate position 411 293 source->peak->dx = dPAR[PM_PAR_XPOS]; 412 294 source->peak->dy = dPAR[PM_PAR_YPOS]; 413 if (isfinite (source->errMag) && (source->errMag > 0.0)) {414 source->peak->SN = 1.0 / source->errMag;415 } else {416 source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N417 }418 295 419 296 source->pixWeightNotBad = psMetadataLookupF32 (&status, row, "PSF_QF"); … … 429 306 430 307 source->moments = pmMomentsAlloc (); 308 source->moments->Mx = source->peak->xf; // we don't have both Mx,My and xf,yf in the cmf 309 source->moments->My = source->peak->yf; // we don't have both Mx,My and xf,yf in the cmf 310 431 311 source->moments->Mxx = psMetadataLookupF32 (&status, row, "MOMENTS_XX"); 432 312 source->moments->Mxy = psMetadataLookupF32 (&status, row, "MOMENTS_XY"); … … 500 380 501 381 // let's write these out in S/N order 502 sources = psArraySort (sources, pmSourceSortBy SN);382 sources = psArraySort (sources, pmSourceSortByFlux); 503 383 504 384 table = psArrayAllocEmpty (sources->n); … … 522 402 // we write out all sources, regardless of quality. the source flags tell us the state 523 403 for (int i = 0; i < sources->n; i++) { 524 pmSource *source = sources->data[i]; 404 // this is the source associated with this image 405 pmSource *thisSource = sources->data[i]; 406 407 // this is the "real" version of this source 408 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 525 409 526 410 // skip sources without measurements … … 556 440 } 557 441 psMetadataAdd (row, PS_LIST_TAIL, "F25_ARATIO", PS_DATA_F32, "Axial Ratio of radial profile", AxialRatio); 558 psMetadataAdd (row, PS_LIST_TAIL, "F25_THETA", PS_DATA_F32, "Angle of radial profile ellipse", AxialTheta);442 psMetadataAdd (row, PS_LIST_TAIL, "F25_THETA", PS_DATA_F32, "Angle of radial profile ellipse", AxialTheta); 559 443 560 444 // Petrosian measurements … … 567 451 float mag = (extpars->petrosianFlux > 0.0) ? -2.5*log10(extpars->petrosianFlux) + magOffset : NAN; // XXX zero point 568 452 float magErr = (extpars->petrosianFlux > 0.0) ? extpars->petrosianFlux / extpars->petrosianFluxErr : NAN; // XXX zero point 569 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", mag);570 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", magErr);571 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius (pix)", extpars->petrosianRadius);572 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error (pix)", extpars->petrosianRadiusErr);453 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", mag); 454 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", magErr); 455 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius (pix)", extpars->petrosianRadius); 456 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error (pix)", extpars->petrosianRadiusErr); 573 457 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50", PS_DATA_F32, "Petrosian R50 (pix)", extpars->petrosianR50); 574 458 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)", extpars->petrosianR50Err); 575 459 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90", PS_DATA_F32, "Petrosian R90 (pix)", extpars->petrosianR90); 576 460 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)", extpars->petrosianR90Err); 461 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_FILL", PS_DATA_F32, "Petrosian Fill Factor", extpars->petrosianFill); 577 462 } else { 578 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", NAN);579 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", NAN);580 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius", NAN);581 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error", NAN);463 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG", PS_DATA_F32, "Petrosian Magnitude", NAN); 464 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR", PS_DATA_F32, "Petrosian Magnitude Error", NAN); 465 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS", PS_DATA_F32, "Petrosian Radius", NAN); 466 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error", NAN); 582 467 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50", PS_DATA_F32, "Petrosian R50 (pix)", NAN); 583 468 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)",NAN); 584 469 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90", PS_DATA_F32, "Petrosian R90 (pix)", NAN); 585 470 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)",NAN); 471 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_FILL", PS_DATA_F32, "Petrosian Fill Factor", NAN); 586 472 } 587 473 } … … 672 558 673 559 // let's write these out in S/N order 674 sources = psArraySort (sources, pmSourceSortBy SN);560 sources = psArraySort (sources, pmSourceSortByFlux); 675 561 676 562 // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams 677 563 int nParamMax = 0; 678 564 for (int i = 0; i < sources->n; i++) { 679 pmSource *source = sources->data[i]; 565 // this is the source associated with this image 566 pmSource *thisSource = sources->data[i]; 567 568 // this is the "real" version of this source 569 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 570 680 571 if (source->modelFits == NULL) continue; 681 572 for (int j = 0; j < source->modelFits->n; j++) { … … 691 582 for (int i = 0; i < sources->n; i++) { 692 583 693 pmSource *source = sources->data[i]; 584 pmSource *thisSource = sources->data[i]; 585 586 // this is the "real" version of this source 587 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 694 588 695 589 // XXX if no model fits are saved, write out modelEXT? … … 747 641 748 642 if (k < model->params->n) { 749 psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "", model->params->data.F32[k]);643 psMetadataAddF32 (row, PS_LIST_TAIL, name, 0, "", model->params->data.F32[k]); 750 644 } else { 751 psMetadataAddF32 (row, PS_LIST_TAIL, name, PS_DATA_F32, "", NAN);645 psMetadataAddF32 (row, PS_LIST_TAIL, name, 0, "", NAN); 752 646 } 753 647 } 754 648 755 // XXX other parameters which may be set. 756 // XXX flag / value to define the model 757 // XXX write out the model type, fit status flags 758 649 // optionally, write out the covariance matrix values 650 // XXX do I need to pad this to match the biggest covar matrix? 651 if (model->covar) { 652 for (int iy = 0; iy < model->covar->numCols; iy++) { 653 for (int ix = iy; ix < model->covar->numCols; ix++) { 654 snprintf (name, 64, "EXT_COVAR_%02d_%02d", iy, ix); 655 psMetadataAddF32 (row, PS_LIST_TAIL, name, 0, "", model->covar->data.F32[iy][ix]); 656 657 } 658 } 659 } 759 660 psArrayAdd (table, 100, row); 760 661 psFree (row); … … 790 691 bool pmSourcesWrite_CMF_PS1_SV1_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe) 791 692 { 792 693 bool status = false; 793 694 psArray *table; 794 695 psMetadata *row; … … 796 697 char keyword1[80], keyword2[80]; 797 698 699 // perform full non-linear fits / extended source analysis? 700 if (!psMetadataLookupBool (&status, recipe, "RADIAL_APERTURES")) { 701 psLogMsg ("psphot", PS_LOG_INFO, "radial apertures were not measured, skipping\n"); 702 return true; 703 } 704 798 705 // create a header to hold the output data 799 706 psMetadata *outhead = psMetadataAlloc (); … … 803 710 804 711 // we use this just to define the output vectors (which must be present for all objects) 805 bool status = false;806 712 psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER"); 807 713 psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER"); … … 818 724 } 819 725 726 // the FWHM values are available if we measured a psf-matched convolved set 820 727 psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES"); 821 if (!fwhmValues) {822 psError (PM_ERR_CONFIG, true, "convolved or measured FWHM is not defined for this readout");823 return false;824 }825 728 826 729 // let's write these out in S/N order 827 sources = psArraySort (sources, pmSourceSortBy SN);730 sources = psArraySort (sources, pmSourceSortByFlux); 828 731 829 732 table = psArrayAllocEmpty (sources->n); … … 832 735 for (int i = 0; i < sources->n; i++) { 833 736 834 pmSource *source = sources->data[i]; 737 // this is the source associated with this image 738 pmSource *thisSource = sources->data[i]; 739 740 // this is the "real" version of this source 741 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 835 742 836 743 // skip sources without radial aper measurements (or insufficient) 837 if (source->radialAper == NULL) continue; 838 psAssert (source->radialAper->n == fwhmValues->n, "inconsistent radial aperture set"); 839 840 for (int entry = 0; entry < fwhmValues->n; entry++) { 744 if (source->radialAper == NULL) continue; 745 746 // psAssert (source->radialAper->n == fwhmValues->n, "inconsistent radial aperture set"); 747 748 for (int entry = 0; entry < source->radialAper->n; entry++) { 841 749 842 750 // choose the convolved EXT model, if available, otherwise the simple one … … 844 752 assert (radialAper); 845 753 846 bool useMoments = true; 847 useMoments = (useMoments && source->moments); // can't if there are no moments 848 useMoments = (useMoments && source->moments->nPixels); // can't if the moments were not measured 849 useMoments = (useMoments && !(source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE)); // can't if the moments failed... 850 851 if (useMoments) { 754 if (pmSourcePositionUseMoments(source)) { 852 755 xPos = source->moments->Mx; 853 756 yPos = source->moments->My; … … 863 766 psMetadataAddF32 (row, PS_LIST_TAIL, "X_APER", 0, "Center of aperture measurements", xPos); 864 767 psMetadataAddF32 (row, PS_LIST_TAIL, "Y_APER", 0, "Center of aperture measurements", yPos); 865 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_FWHM", 0, "FWHM of matched PSF", fwhmValues->data.F32[entry]); 768 if (fwhmValues) { 769 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_FWHM", 0, "FWHM of matched PSF", fwhmValues->data.F32[entry]); 770 } else { 771 psMetadataAddF32 (row, PS_LIST_TAIL, "PSF_FWHM", 0, "image is not FWHM-matched", NAN); 772 } 866 773 867 774 // XXX if we have raw radial apertures, write them out here 868 psVector *radFlux = psVectorAlloc(radMax->n, PS_TYPE_F32); 869 psVector *radFluxErr = psVectorAlloc(radMax->n, PS_TYPE_F32); 870 psVector *radFill = psVectorAlloc(radMax->n, PS_TYPE_F32); 775 psVector *radFlux = psVectorAlloc(radMax->n, PS_TYPE_F32); 776 psVector *radFluxErr = psVectorAlloc(radMax->n, PS_TYPE_F32); 777 psVector *radFill = psVectorAlloc(radMax->n, PS_TYPE_F32); 778 psVector *radFluxStdev = psVectorAlloc(radMax->n, PS_TYPE_F32); 871 779 psVectorInit (radFlux, NAN); 872 780 psVectorInit (radFluxErr, NAN); … … 879 787 // copy the data from fluxVal (which is not guaranteed to be the full length) to radFlux 880 788 for (int j = 0; j < radialAper->flux->n; j++) { 881 radFlux->data.F32[j] = radialAper->flux->data.F32[j]; 882 radFluxErr->data.F32[j] = radialAper->fluxErr->data.F32[j]; 883 radFill->data.F32[j] = radialAper->fill->data.F32[j]; 789 radFlux->data.F32[j] = radialAper->flux->data.F32[j]; 790 radFluxErr->data.F32[j] = radialAper->fluxErr->data.F32[j]; 791 radFluxStdev->data.F32[j] = radialAper->fluxStdev->data.F32[j]; 792 radFill->data.F32[j] = radialAper->fill->data.F32[j]; 884 793 } 885 794 886 795 write_annuli: 887 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux); 888 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_ERR", PS_DATA_VECTOR, "flux error in annuli", radFluxErr); 889 psMetadataAdd (row, PS_LIST_TAIL, "APER_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill); 796 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux); 797 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_ERR", PS_DATA_VECTOR, "flux error in annuli", radFluxErr); 798 psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_STDEV", PS_DATA_VECTOR, "flux standard deviation", radFluxStdev); 799 psMetadataAdd (row, PS_LIST_TAIL, "APER_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill); 890 800 psFree (radFlux); 891 801 psFree (radFluxErr); 802 psFree (radFluxStdev); 892 803 psFree (radFill); 893 804
Note:
See TracChangeset
for help on using the changeset viewer.
