- Timestamp:
- Sep 19, 2014, 4:05:27 PM (12 years ago)
- Location:
- branches/eam_branches/ps2-tc3-20130727
- Files:
-
- 3 edited
-
. (modified) (1 prop)
-
psModules/src/objects (modified) (1 prop)
-
psModules/src/objects/pmSourceIO_CFF.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ps2-tc3-20130727
- Property svn:mergeinfo changed
-
branches/eam_branches/ps2-tc3-20130727/psModules/src/objects
- Property svn:ignore
-
old new 15 15 pmSourceIO_CMF_PS1_SV1.c 16 16 pmSourceIO_CMF_PS1_SV2.c 17 pmSourceIO_CMF_PS1_SV3.c 18 pmSourceIO_CMF_PS1_SV4.c 17 19 pmSourceIO_CMF_PS1_DV1.c 18 20 pmSourceIO_CMF_PS1_DV2.c 19 21 pmSourceIO_CMF_PS1_DV3.c 22 pmSourceIO_CMF_PS1_DV4.c 20 23
-
- Property svn:ignore
-
branches/eam_branches/ps2-tc3-20130727/psModules/src/objects/pmSourceIO_CFF.c
r36680 r37403 37 37 #include "pmMoments.h" 38 38 #include "pmModelFuncs.h" 39 #include "pmModelClass.h" 39 40 #include "pmModel.h" 40 41 #include "pmModelUtils.h" 41 #include "pmModelClass.h"42 42 #include "pmSourceMasks.h" 43 43 #include "pmSourceExtendedPars.h" … … 53 53 #include "pmSourceOutputs.h" 54 54 55 // read in a readout from thefits file56 psArray *pmSourcesRead_CFF (psFits *fits, psMetadata *header )55 // read in sources readout from a cff fits file 56 psArray *pmSourcesRead_CFF (psFits *fits, psMetadata *header, psMetadata *recipe) 57 57 { 58 58 PS_ASSERT_PTR_NON_NULL(fits, false); … … 75 75 PS_ASSERT_INT_NONNEGATIVE(modelType, NULL); 76 76 77 pmModelType sersicModelType = pmModelClassGetType("PS_MODEL_SERSIC"); 78 pmModelType devModelType = pmModelClassGetType("PS_MODEL_DEV"); 79 80 psString modelForce = psMetadataLookupStr(&status, recipe, "EXT_MODEL_TYPE_FORCE"); 81 psF32 forceDevSersicMin = NAN; 82 bool forceAll = false; 83 int modelTypeForce = 0; 84 if (!strcmp(modelForce, "ALL")) { 85 forceAll = true; 86 } else if (!strcmp(modelForce, "PS_MODEL_SERSIC")) { 87 modelTypeForce = sersicModelType; 88 forceDevSersicMin = psMetadataLookupF32(&status, recipe, "EXT_MODEL_FORCE_DEV_SERSIC_MIN"); 89 } else { 90 modelTypeForce = pmModelClassGetType(modelForce); 91 PS_ASSERT_INT_NONNEGATIVE(modelTypeForce, NULL); 92 } 93 94 // skip extended model types for likely stars 95 // max value of KronMag - psfMag to keep ... 96 psF32 starCut = psMetadataLookupF32(&status, recipe, "EXT_MODEL_FORCE_MAGDIFF_MAX"); 97 if (!status) { 98 starCut = 0; 99 } 100 // ... unless SN is less than this value 101 psF32 SNMinForCut = psMetadataLookupF32(&status, recipe, "EXT_MODEL_FORCE_CUT_SN_MIN"); 102 if (!status) { 103 SNMinForCut = 10; 104 } 105 77 106 // We get the size of the table, and allocate the array of sources first because the table 78 107 // is large and ephemeral --- when the table gets blown away, whatever is allocated after 79 108 // the table is read blocks the free. In fact, it's better to read the table row by row. 80 long numSources = psFitsTableSize(fits); // Number of sources in table 81 psArray *sources = psArrayAlloc(numSources); // Array of sources, to return 82 83 // convert the table to the pmSource entriesa 84 for (int i = 0; i < numSources; i++) { 109 long numRows = psFitsTableSize(fits); // Number of rows in table 110 psArray *sources = psArrayAllocEmpty(numRows); // Array of sources, to return 111 112 // convert the table to the pmSource entries 113 pmSource *source = NULL; 114 for (int i = 0; i < numRows; i++) { 85 115 psMetadata *row = psFitsReadTableRow(fits, i); // Table row 86 116 if (!row) { … … 108 138 float kronRadius = psMetadataLookupF32 (&status, row, "KRON_RADIUS"); 109 139 float petRadius = psMetadataLookupF32 (&status, row, "PETRO_RADIUS"); 140 float SN = psMetadataLookupF32 (&status, row, "SN"); 110 141 bool fitGalaxy = psMetadataLookupU8 (&status, row, "FIT_GALAXY"); 111 142 bool psfStar = psMetadataLookupU8 (&status, row, "PSF_STAR"); … … 114 145 float Rminor = psMetadataLookupF32 (&status, row, "R_MINOR"); 115 146 float theta = psMetadataLookupF32 (&status, row, "THETA"); 147 float chisq = psMetadataLookupF32 (&status, row, "CHISQ"); 148 float nDOF = psMetadataLookupF32 (&status, row, "NDOF"); 149 float magDiff = psMetadataLookupF32 (&status, row, "MAG_DIFF"); 150 psS16 modelFlags = psMetadataLookupS32 (&status, row, "MODEL_FLAGS"); 116 151 117 152 int galaxyModelType = psMetadataLookupS32(&status, row, "MODEL_TYPE"); 118 if (status ) {153 if (status && galaxyModelType >= 0) { 119 154 galaxyModelType = pmModelClassGetLocalType(galaxyModelType); 120 155 } else { … … 123 158 float Sindex = psMetadataLookupF32 (&status, row, "INDEX"); // Should this be PAR_07 not sersic index 124 159 125 pmSource *source = pmSourceAlloc (); 126 pmModel *model = pmModelAlloc (modelType); 127 source->modelPSF = model; 128 // RoughClass wants source type to be unknown 129 // source->type = PM_SOURCE_TYPE_STAR; // XXX this should be added to the flags 130 source->type = PM_SOURCE_TYPE_UNKNOWN; 131 132 // XXX we can set this in general, but for a specific image, we need to weed out SATSTARS and 133 // stars that are masked 134 if (psfStar) { 135 source->tmpFlags |= PM_SOURCE_TMPF_CANDIDATE_PSFSTAR; 136 } 137 138 // NOTE: A SEGV here because "model" is NULL is probably caused by not initialising the models. 139 psF32 *PAR = model->params->data.F32; 140 psF32 *dPAR = model->dparams->data.F32; 141 142 source->seq = ID; 143 PAR[PM_PAR_XPOS] = X; 144 PAR[PM_PAR_YPOS] = Y; 145 146 dPAR[PM_PAR_XPOS] = 0.0; 147 dPAR[PM_PAR_YPOS] = 0.0; 148 149 PAR[PM_PAR_SKY] = 0.0; 150 dPAR[PM_PAR_SKY] = 0.0; 151 152 PAR[PM_PAR_I0] = 1.0; 153 dPAR[PM_PAR_I0] = 0.0; 154 155 source->sky = PAR[PM_PAR_SKY]; 156 source->skyErr = dPAR[PM_PAR_SKY]; 157 158 source->psfMag = 0.0; 159 source->psfMagErr = 0.0; 160 source->apMag = 0.0; 161 source->apRadius = apRadius; 162 163 // we generate a somewhat fake PSF model here -- 164 // in most (all?) contexts, we will replace this with a measured psf model 165 // elsewhere 166 axes.major = 1.0; 167 axes.minor = 1.0; 168 axes.theta = 0.0; 169 pmPSF_AxesToModel (PAR, axes, modelType); 170 171 // peak->detValue, rawFlux, smoothFlux are all set to the flux argument which is counts per second 172 source->peak = pmPeakAlloc(X, Y, flux, PM_PEAK_LONE); 173 source->peak->xf = X; // pmPeakAlloc converts X,Y to int, so reset here 174 source->peak->yf = Y; // pmPeakAlloc converts X,Y to int, so reset here 175 source->peak->dx = 0.0; 176 source->peak->dy = 0.0; 177 178 source->moments = pmMomentsAlloc (); 179 source->moments->Mx = X; 180 source->moments->My = Y; 181 source->moments->Mrf = kronRadius * 0.4; // kronRadius is 2.5 * first radial moment 182 183 // Don't mark the moments as measured because that causes many fields to be left blank. 184 // The moments code knows not to change the position or the Mrf for external sources 185 // source->tmpFlags |= PM_SOURCE_TMPF_MOMENTS_MEASURED; 186 187 if (isfinite(petRadius)) { 188 source->extpars = pmSourceExtendedParsAlloc (); 189 source->extpars->petrosianRadius = petRadius; 190 } 191 160 if (!source || ID != source->seq) { 161 if (source) { 162 psArrayAdd (sources, 1, source); 163 psFree(source); 164 } 165 source = pmSourceAlloc (); 166 pmModel *model = pmModelAlloc (modelType); 167 source->modelPSF = model; 168 // RoughClass wants source type to be unknown 169 // source->type = PM_SOURCE_TYPE_STAR; // XXX this should be added to the flags 170 source->type = PM_SOURCE_TYPE_UNKNOWN; 171 172 // XXX we can set this in general, but for a specific image, we need to weed out SATSTARS and 173 // stars that are masked 174 if (psfStar) { 175 source->tmpFlags |= PM_SOURCE_TMPF_CANDIDATE_PSFSTAR; 176 } 177 178 // NOTE: A SEGV here because "model" is NULL is probably caused by not initialising the models. 179 psF32 *PAR = model->params->data.F32; 180 psF32 *dPAR = model->dparams->data.F32; 181 182 source->seq = ID; 183 184 PAR[PM_PAR_XPOS] = X; 185 PAR[PM_PAR_YPOS] = Y; 186 187 dPAR[PM_PAR_XPOS] = 0.0; 188 dPAR[PM_PAR_YPOS] = 0.0; 189 190 PAR[PM_PAR_SKY] = 0.0; 191 dPAR[PM_PAR_SKY] = 0.0; 192 193 PAR[PM_PAR_I0] = 1.0; 194 dPAR[PM_PAR_I0] = 0.0; 195 196 source->sky = PAR[PM_PAR_SKY]; 197 source->skyErr = dPAR[PM_PAR_SKY]; 198 199 source->psfMag = 0.0; 200 source->psfMagErr = 0.0; 201 source->apMag = 0.0; 202 source->apRadius = apRadius; 203 204 // we generate a somewhat fake PSF model here -- 205 // in most (all?) contexts, we will replace this with a measured psf model 206 // elsewhere 207 axes.major = 1.0; 208 axes.minor = 1.0; 209 axes.theta = 0.0; 210 pmPSF_AxesToModel (PAR, axes, model->class->useReff); 211 212 // peak->detValue, rawFlux, smoothFlux are all set to the flux argument which is counts per second 213 source->peak = pmPeakAlloc(X, Y, flux, PM_PEAK_LONE); 214 source->peak->xf = X; // pmPeakAlloc converts X,Y to int, so reset here 215 source->peak->yf = Y; // pmPeakAlloc converts X,Y to int, so reset here 216 source->peak->dx = 0.0; 217 source->peak->dy = 0.0; 218 219 source->extSN = SN; 220 221 source->moments = pmMomentsAlloc (); 222 source->moments->Mx = X; 223 source->moments->My = Y; 224 source->moments->Mrf = kronRadius * 0.4; // kronRadius is 2.5 * first radial moment 225 226 // Don't mark the moments as measured because that causes many fields to be left blank. 227 // The moments code knows not to change the position or the Mrf for external sources 228 // source->tmpFlags |= PM_SOURCE_TMPF_MOMENTS_MEASURED; 229 230 if (isfinite(petRadius)) { 231 source->extpars = pmSourceExtendedParsAlloc (); 232 source->extpars->petrosianRadius = petRadius; 233 } 234 235 } 236 bool saveExtModelParams = false; 192 237 if (fitGalaxy && galaxyModelType >= 0) { 193 source->modelFits = psArrayAllocEmpty (1); 194 pmModel *model = pmModelAlloc(galaxyModelType); 195 psF32 *xPAR = model->params->data.F32; 196 197 xPAR[PM_PAR_SKY] = 0.0; 198 xPAR[PM_PAR_I0] = 1.0; 199 xPAR[PM_PAR_XPOS] = X; 238 // skip likely stars 239 if (magDiff < starCut || SN < SNMinForCut) { 240 if (forceAll) { 241 saveExtModelParams = true; 242 } else if (galaxyModelType == modelTypeForce) { 243 // This is the model type that we are looking for 244 // proceed 245 saveExtModelParams = true; 246 } else if (modelTypeForce == sersicModelType && galaxyModelType == devModelType) { 247 // We're doing sersic models, if sersic index is greater than the recipe's minimum index 248 // do dev model as well 249 if (isfinite(forceDevSersicMin) || Sindex >= forceDevSersicMin) { 250 saveExtModelParams = true; 251 } 252 } else { 253 // not interested in this model 254 } 255 } 256 } 257 258 if (saveExtModelParams) { 259 if (!source->modelFits) { 260 source->modelFits = psArrayAllocEmpty (1); 261 } 262 pmModel *model = pmModelAlloc(galaxyModelType); 263 psF32 *xPAR = model->params->data.F32; 264 265 xPAR[PM_PAR_SKY] = 0.0; 266 xPAR[PM_PAR_I0] = 1.0; 267 xPAR[PM_PAR_XPOS] = X; 200 268 xPAR[PM_PAR_YPOS] = Y; 201 269 … … 205 273 galaxyAxes.theta = theta * PS_RAD_DEG; 206 274 207 pmPSF_AxesToModel (xPAR, galaxyAxes, galaxyModelType);275 pmPSF_AxesToModel (xPAR, galaxyAxes, model->class->useReff); 208 276 if (model->params->n > 7) { 209 277 xPAR[PM_PAR_7] = 0.5 / Sindex; 210 278 } 211 279 280 model->chisq = chisq; 281 model->nDOF = nDOF; 282 model->flags = modelFlags; 283 212 284 psArrayAdd (source->modelFits, 1, model); 213 285 214 #ifdef notyet215 // XXX: set source->modelEXT to this model and flag as extended so that we have a better216 // shot at subtracting extended sources?217 218 // This doesn't work right. Need to do some more work to flesh out the model before it can be219 // used in subtaction. Better idea might be to do 2 passes in psphotFullForceReadout to220 // First find the best extended models and then do everything else.221 source->modelEXT = psMemIncrRefCounter(model);222 // is this safe? (no see above)223 source->type = PM_SOURCE_TYPE_EXTENDED;224 source->mode |= PM_SOURCE_MODE_EXTMODEL;225 #endif226 227 286 psFree (model); 228 287 } 229 288 230 sources->data[i] = source;231 289 psFree(row); 290 } 291 if (source) { 292 // close out last source 293 psArrayAdd (sources, 1, source); 294 psFree(source); 232 295 } 233 296 … … 250 313 251 314 pmModelType sersicModelType = pmModelClassGetType("PS_MODEL_SERSIC"); 315 pmModelType devModelType = pmModelClassGetType("PS_MODEL_DEV"); 316 pmModelType selectedModelType = -1; 317 bool chooseBest = false; 318 bool chooseAll = false; 252 319 253 320 psString modelToChoose = psMetadataLookupStr(&mdok, recipe, "EXT_MODEL_TYPE_FOR_CFF"); 254 pmModelType selectedModelType = -1; 321 255 322 if (mdok && modelToChoose != NULL) { 256 if (strcmp(modelToChoose, "BEST")) { 323 if (!strcmp(modelToChoose, "BEST")) { 324 chooseBest = true; 325 } else if (!strcmp(modelToChoose, "ALL")) { 326 chooseAll = true; 327 } else if (strcmp(modelToChoose, "PS_MODEL_SERSIC")) { 328 // We have selected a model type other than Sersic. 329 // Save it's type for use below. Sersic is handled specially 257 330 selectedModelType = pmModelClassGetType(modelToChoose); 258 331 } 259 332 } 333 334 // minimum sersic index to force devModel 335 psF32 sersicMinDev = psMetadataLookupF32(&mdok, recipe, "EXT_MODEL_FORCE_DEV_SERSIC_MIN"); 336 if (!mdok) { 337 sersicMinDev = NAN; 338 } 339 340 sources = psArraySort (sources, pmSourceSortBySeq); 260 341 261 342 for (int i = 0; i < sources->n; i++) { … … 263 344 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 264 345 265 psF32 xPos, yPos, flux, rMajor, rMinor, theta; 266 psS32 modelType = 0; 346 #define MAX_ROWS_PER_SRC 10 347 psF32 xPos[MAX_ROWS_PER_SRC], yPos[MAX_ROWS_PER_SRC], flux[MAX_ROWS_PER_SRC]; 348 psF32 rMajor[MAX_ROWS_PER_SRC], rMinor[MAX_ROWS_PER_SRC], theta[MAX_ROWS_PER_SRC]; 349 psF32 chisq[MAX_ROWS_PER_SRC], nDOF[MAX_ROWS_PER_SRC]; 350 psS32 modelFlags[MAX_ROWS_PER_SRC]; 351 psS32 modelType[MAX_ROWS_PER_SRC]; 352 psF32 sersicIndex = NAN; 267 353 bool fitGalaxy = false; 268 354 bool psfStar = (source->mode & PM_SOURCE_MODE_PSFSTAR) ? true : false; 269 psF32 sersicIndex = 0; 270 // For now only perform galaxy fits on extended objects 271 if (source->modelEXT == NULL) { 272 pmModel *model = source->modelPSF; 273 if (model == NULL) continue; 274 psF32 *PAR = model->params->data.F32; 275 if (!isfinite(PAR[PM_PAR_SXX]) || !isfinite(PAR[PM_PAR_SYY]) || !isfinite(PAR[PM_PAR_SXY]) || 276 !isfinite(source->psfFlux)) { 277 continue; 278 } 279 280 xPos = model->params->data.F32[PM_PAR_XPOS]; 281 yPos = model->params->data.F32[PM_PAR_YPOS]; 282 flux = source->psfFlux; 283 rMajor = 0; 284 rMinor = 0; 285 theta = 0; 286 } else { 287 // Find the model with the selected type. If selected type is -1 choose the one selected ad 288 // modelEXT which was the best 289 int iModel = -1; 290 if (source->modelEXT) { 291 pmModelType ext_model_type = selectedModelType != -1 ? selectedModelType : source->modelEXT->type; 355 int n_rows = 0; 356 357 psF32 kronFlux = source->moments->KronFlux; 358 psF32 SN = NAN; 359 psF32 magDiff = NAN; 360 if (isfinite(kronFlux) && isfinite(source->moments->KronFluxErr) && isfinite(source->psfMag)) { 361 SN = kronFlux/source->moments->KronFluxErr; 362 // kronMag - psfMag for use as star/glaxy separator 363 magDiff = -2.5 * log10(kronFlux) - source->psfMag ; 364 } 365 366 // start with psf model 367 pmModel *model = source->modelPSF; 368 if (model == NULL) continue; 369 psF32 *PAR = model->params->data.F32; 370 if (!isfinite(PAR[PM_PAR_SXX]) || !isfinite(PAR[PM_PAR_SYY]) || !isfinite(PAR[PM_PAR_SXY]) || 371 !isfinite(source->psfFlux)) { 372 continue; 373 } 374 375 // save the PSF model parameters for each object as the first entry 376 xPos[0] = model->params->data.F32[PM_PAR_XPOS]; 377 yPos[0] = model->params->data.F32[PM_PAR_YPOS]; 378 flux[0] = source->psfFlux; 379 rMajor[0] = 0; 380 rMinor[0] = 0; 381 theta[0] = 0; 382 modelType[0] = -1; 383 sersicIndex = NAN; 384 chisq[0] = NAN; 385 nDOF[0] = NAN; 386 modelFlags[0] = 0; 387 n_rows ++; 388 389 if (source->modelFits != NULL) { 390 // figure out which models to use based on recipe paramters 391 if (chooseAll) { 392 // Save parameters for all valid extended models 393 394 // but make sure we aren't going to overflow our arrays 395 assert (source->modelFits->n < MAX_ROWS_PER_SRC); 396 292 397 for (int j=0; j<source->modelFits->n; j++) { 293 pmModel *aModel = source->modelFits->data[j]; 294 if (aModel->type == ext_model_type) { 295 iModel = j; 296 break; 398 pmModel *model = source->modelFits->data[j]; 399 psF32 *PAR = model->params->data.F32; 400 401 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY]) && isfinite(PAR[PM_PAR_SXY]) && 402 isfinite(model->mag)) { 403 404 xPos[n_rows] = PAR[PM_PAR_XPOS]; 405 yPos[n_rows] = PAR[PM_PAR_YPOS]; 406 407 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->class->useReff); 408 rMajor[n_rows] = axes.major; 409 rMinor[n_rows] = axes.minor; 410 theta[n_rows] = axes.theta*PS_DEG_RAD; 411 flux[n_rows] = pow(10.0, -0.4*model->mag); 412 modelType[n_rows] = model->type; 413 chisq[n_rows] = model->chisq; 414 nDOF[n_rows] = model->nDOF; 415 modelFlags[n_rows] = model->flags; 416 fitGalaxy = true; 417 if (model->params->n == 8) { 418 // this will save the sersic index in all models but that might 419 // be useful 420 sersicIndex = 0.5 / PAR[PM_PAR_7]; 421 } else { 422 sersicIndex = NAN; 423 } 424 425 n_rows++; 426 } 427 } 428 } else { 429 int jModelSersic = -1; 430 int jModelDev = -1; 431 int jModelSelected = -1; 432 psF32 minChisq = NAN; 433 for (int j=0; j<source->modelFits->n; j++) { 434 pmModel *model = source->modelFits->data[j]; 435 if (chooseBest) { 436 // choose the model with lowest chisq 437 if (isfinite(model->chisq) && (!isfinite(minChisq) || model->chisq < minChisq)) { 438 jModelSelected = j; 439 minChisq = model->chisq; 440 } 441 } else { 442 // find the index of models of interest 443 if (model->type == selectedModelType) { 444 jModelSelected = j; 445 } else if (model->type == sersicModelType) { 446 jModelSersic = j; 447 } else if (model->type == devModelType) { 448 jModelDev = j; 449 } 450 } 451 } 452 if (jModelSelected >= 0 || jModelSersic >= 0) { 453 // If a specific non-sersic model we take paramers from that one. 454 // Otherwise we do the sersic model. 455 pmModel *model = jModelSelected >= 0 ? source->modelFits->data[jModelSelected] : 456 source->modelFits->data[jModelSersic]; 457 psF32 *PAR = model->params->data.F32; 458 459 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY]) && isfinite(PAR[PM_PAR_SXY]) && 460 isfinite(model->mag)) { 461 462 xPos[0] = PAR[PM_PAR_XPOS]; 463 yPos[0] = PAR[PM_PAR_YPOS]; 464 465 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->class->useReff); 466 rMajor[0] = axes.major; 467 rMinor[0] = axes.minor; 468 theta[0] = axes.theta*PS_DEG_RAD; 469 flux[0] = pow(10.0, -0.4*model->mag); 470 modelType[0] = model->type; 471 chisq[0] = model->chisq; 472 nDOF[0] = model->nDOF; 473 modelFlags[0] = model->flags; 474 fitGalaxy = true; 475 if (model->type == sersicModelType) { 476 PS_ASSERT_FLOAT_LARGER_THAN(PAR[PM_PAR_7], 0.0, false); 477 sersicIndex = 0.5 / PAR[PM_PAR_7]; 478 } 479 480 n_rows = 1; 481 482 // Unless a specific non-sersic model type was selected do dev model for sources with 483 // sersic index above the recipe limit. 484 if (jModelSelected == -1 && jModelDev >= 0 && isfinite(sersicMinDev) && 485 sersicIndex > sersicMinDev) { 486 487 model = source->modelFits->data[jModelDev]; 488 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY]) && isfinite(PAR[PM_PAR_SXY]) && 489 isfinite(model->mag)) { 490 491 xPos[1] = PAR[PM_PAR_XPOS]; 492 yPos[1] = PAR[PM_PAR_YPOS]; 493 494 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->class->useReff); 495 rMajor[1] = axes.major; 496 rMinor[1] = axes.minor; 497 theta[1] = axes.theta*PS_DEG_RAD; 498 flux[1] = pow(10.0, -0.4*model->mag); 499 modelType[1] = model->type; 500 sersicIndex = NAN; 501 chisq[1] = model->chisq; 502 nDOF[1] = model->nDOF; 503 modelFlags[1] = model->flags; 504 n_rows = 2; 505 } 506 } 297 507 } 298 508 } 299 509 } 300 if (iModel == -1) { 301 // Can this happen? perhaps if model type is qgauss (extended but below s/n for model fits? 302 // XXX: Should this be an assert? 303 continue; 304 } 305 pmModel *model = source->modelFits->data[iModel]; 306 psF32 *PAR = model->params->data.F32; 307 xPos = PAR[PM_PAR_XPOS]; 308 yPos = PAR[PM_PAR_YPOS]; 309 if (model->type == pmModelClassGetType("PS_MODEL_TRAIL")) { 310 // XXX: do we need to handle this type 311 continue; 312 } else { 313 if (!isfinite(PAR[PM_PAR_SXX]) || !isfinite(PAR[PM_PAR_SYY]) || !isfinite(PAR[PM_PAR_SXY]) || 314 !isfinite(model->mag)) { 315 // bad model 316 continue; 317 } 318 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type); 319 rMajor = axes.major; 320 rMinor = axes.minor; 321 theta = axes.theta*PS_DEG_RAD; 322 flux = pow(10.0, -0.4*model->mag); 323 fitGalaxy = true; 324 } 325 modelType = model->type; 326 if (modelType == sersicModelType) { 327 PS_ASSERT_FLOAT_LARGER_THAN(PAR[PM_PAR_7], 0.0, false); 328 sersicIndex = 0.5 / PAR[PM_PAR_7]; 329 } 330 } 331 psMetadata *row = psMetadataAlloc(); 332 psMetadataAddU32 (row, PS_LIST_TAIL, "ID", 0, "IPP detection identifier", source->seq); 333 psMetadataAddF32 (row, PS_LIST_TAIL, "X", 0, "x coordinate", xPos); 334 psMetadataAddF32 (row, PS_LIST_TAIL, "Y", 0, "y coordinate", yPos); 335 psMetadataAddF32 (row, PS_LIST_TAIL, "FLUX", 0, "flux per second", flux/exptime); 336 psMetadataAddF32 (row, PS_LIST_TAIL, "AP_RADIUS", 0, "aperture radius", source->apRadius); 337 psMetadataAddF32 (row, PS_LIST_TAIL, "KRON_RADIUS", 0, "Kron radius", source->moments->Mrf * 2.5); 338 psMetadataAddF32 (row, PS_LIST_TAIL, "PETRO_RADIUS", 0, "Petrosian Radius", source->extpars ? source->extpars->petrosianRadius : NAN); 339 psMetadataAddBool (row, PS_LIST_TAIL, "FIT_GALAXY", 0, "source has xfit", fitGalaxy); 340 psMetadataAddBool (row, PS_LIST_TAIL, "PSF_STAR", 0, "source was psf star", psfStar); 341 psMetadataAddF32 (row, PS_LIST_TAIL, "R_MAJOR", 0, "radius of major axis", rMajor); 342 psMetadataAddF32 (row, PS_LIST_TAIL, "R_MINOR", 0, "radius of minor axis", rMinor); 343 psMetadataAddF32 (row, PS_LIST_TAIL, "THETA", 0, "theta", theta); 344 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TYPE", 0, "model type", modelType); 345 psMetadataAddF32 (row, PS_LIST_TAIL, "INDEX", 0, "sersic index", sersicIndex); 346 347 psArrayAdd(table, 100, row); 348 psFree(row); 510 } 511 512 for (int j = 0; j < n_rows; j++) { 513 psMetadata *row = psMetadataAlloc(); 514 psMetadataAddU32 (row, PS_LIST_TAIL, "ID", 0, "IPP detection identifier", source->seq); 515 psMetadataAddF32 (row, PS_LIST_TAIL, "X", 0, "x coordinate", xPos[j]); 516 psMetadataAddF32 (row, PS_LIST_TAIL, "Y", 0, "y coordinate", yPos[j]); 517 psMetadataAddF32 (row, PS_LIST_TAIL, "FLUX", 0, "flux per second", flux[j]/exptime); 518 psMetadataAddF32 (row, PS_LIST_TAIL, "SN", 0, "kron flux signal to noise", SN); 519 psMetadataAddF32 (row, PS_LIST_TAIL, "MAG_DIFF", 0, "psf mag - kron mag", magDiff); 520 psMetadataAddF32 (row, PS_LIST_TAIL, "AP_RADIUS", 0, "aperture radius", source->apRadius); 521 psMetadataAddF32 (row, PS_LIST_TAIL, "KRON_RADIUS", 0, "Kron radius", source->moments->Mrf * 2.5); 522 psMetadataAddF32 (row, PS_LIST_TAIL, "PETRO_RADIUS", 0, "Petrosian Radius", source->extpars ? source->extpars->petrosianRadius : NAN); 523 psMetadataAddBool (row, PS_LIST_TAIL, "FIT_GALAXY", 0, "source has xfit", fitGalaxy); 524 psMetadataAddBool (row, PS_LIST_TAIL, "PSF_STAR", 0, "source was psf star", psfStar); 525 psMetadataAddF32 (row, PS_LIST_TAIL, "R_MAJOR", 0, "radius of major axis", rMajor[j]); 526 psMetadataAddF32 (row, PS_LIST_TAIL, "R_MINOR", 0, "radius of minor axis", rMinor[j]); 527 psMetadataAddF32 (row, PS_LIST_TAIL, "THETA", 0, "theta", theta[j]); 528 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TYPE", 0, "model type", modelType[j]); 529 psMetadataAddF32 (row, PS_LIST_TAIL, "INDEX", 0, "sersic index", sersicIndex); 530 psMetadataAddF32 (row, PS_LIST_TAIL, "CHISQ", 0, "chisq", chisq[j]); 531 psMetadataAddF32 (row, PS_LIST_TAIL, "NDOF", 0, "n degrees of freedom", nDOF[j]); 532 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_FLAGS", 0, "model flags", modelFlags[j]); 533 534 psArrayAdd(table, 100, row); 535 psFree(row); 536 } 349 537 } 350 538
Note:
See TracChangeset
for help on using the changeset viewer.
