Changeset 36707
- Timestamp:
- Apr 30, 2014, 3:48:08 PM (12 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/objects/pmSourceIO_CFF.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/objects/pmSourceIO_CFF.c
r36633 r36707 53 53 #include "pmSourceOutputs.h" 54 54 55 // read in a readout from thefits file55 // read in sources readout from a cff fits file 56 56 psArray *pmSourcesRead_CFF (psFits *fits, psMetadata *header) 57 57 { … … 78 78 // is large and ephemeral --- when the table gets blown away, whatever is allocated after 79 79 // 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++) { 80 long numRows = psFitsTableSize(fits); // Number of rows in table 81 psArray *sources = psArrayAllocEmpty(numRows); // Array of sources, to return 82 83 // convert the table to the pmSource entries 84 unsigned int ID_last = 0; 85 pmSource *source = NULL; 86 for (int i = 0; i < numRows; i++) { 85 87 psMetadata *row = psFitsReadTableRow(fits, i); // Table row 86 88 if (!row) { … … 123 125 float Sindex = psMetadataLookupF32 (&status, row, "INDEX"); // Should this be PAR_07 not sersic index 124 126 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 127 if (!source || ID != source->seq) { 128 if (source) { 129 psArrayAdd (sources, 1, source); 130 psFree(source); 131 } 132 source = pmSourceAlloc (); 133 pmModel *model = pmModelAlloc (modelType); 134 source->modelPSF = model; 135 // RoughClass wants source type to be unknown 136 // source->type = PM_SOURCE_TYPE_STAR; // XXX this should be added to the flags 137 source->type = PM_SOURCE_TYPE_UNKNOWN; 138 139 // XXX we can set this in general, but for a specific image, we need to weed out SATSTARS and 140 // stars that are masked 141 if (psfStar) { 142 source->tmpFlags |= PM_SOURCE_TMPF_CANDIDATE_PSFSTAR; 143 } 144 145 // NOTE: A SEGV here because "model" is NULL is probably caused by not initialising the models. 146 psF32 *PAR = model->params->data.F32; 147 psF32 *dPAR = model->dparams->data.F32; 148 149 source->seq = ID; 150 ID_last = ID; 151 152 PAR[PM_PAR_XPOS] = X; 153 PAR[PM_PAR_YPOS] = Y; 154 155 dPAR[PM_PAR_XPOS] = 0.0; 156 dPAR[PM_PAR_YPOS] = 0.0; 157 158 PAR[PM_PAR_SKY] = 0.0; 159 dPAR[PM_PAR_SKY] = 0.0; 160 161 PAR[PM_PAR_I0] = 1.0; 162 dPAR[PM_PAR_I0] = 0.0; 163 164 source->sky = PAR[PM_PAR_SKY]; 165 source->skyErr = dPAR[PM_PAR_SKY]; 166 167 source->psfMag = 0.0; 168 source->psfMagErr = 0.0; 169 source->apMag = 0.0; 170 source->apRadius = apRadius; 171 172 // we generate a somewhat fake PSF model here -- 173 // in most (all?) contexts, we will replace this with a measured psf model 174 // elsewhere 175 axes.major = 1.0; 176 axes.minor = 1.0; 177 axes.theta = 0.0; 178 pmPSF_AxesToModel (PAR, axes, modelType); 179 180 // peak->detValue, rawFlux, smoothFlux are all set to the flux argument which is counts per second 181 source->peak = pmPeakAlloc(X, Y, flux, PM_PEAK_LONE); 182 source->peak->xf = X; // pmPeakAlloc converts X,Y to int, so reset here 183 source->peak->yf = Y; // pmPeakAlloc converts X,Y to int, so reset here 184 source->peak->dx = 0.0; 185 source->peak->dy = 0.0; 186 187 source->moments = pmMomentsAlloc (); 188 source->moments->Mx = X; 189 source->moments->My = Y; 190 source->moments->Mrf = kronRadius * 0.4; // kronRadius is 2.5 * first radial moment 191 192 // Don't mark the moments as measured because that causes many fields to be left blank. 193 // The moments code knows not to change the position or the Mrf for external sources 194 // source->tmpFlags |= PM_SOURCE_TMPF_MOMENTS_MEASURED; 195 196 if (isfinite(petRadius)) { 197 source->extpars = pmSourceExtendedParsAlloc (); 198 source->extpars->petrosianRadius = petRadius; 199 } 200 201 } 192 202 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; 203 if (!source->modelFits) { 204 source->modelFits = psArrayAllocEmpty (1); 205 } 206 pmModel *model = pmModelAlloc(galaxyModelType); 207 psF32 *xPAR = model->params->data.F32; 208 209 xPAR[PM_PAR_SKY] = 0.0; 210 xPAR[PM_PAR_I0] = 1.0; 211 xPAR[PM_PAR_XPOS] = X; 200 212 xPAR[PM_PAR_YPOS] = Y; 201 213 … … 212 224 psArrayAdd (source->modelFits, 1, model); 213 225 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 226 psFree (model); 228 227 } 229 228 230 sources->data[i] = source;231 229 psFree(row); 230 } 231 if (source) { 232 // close out last source 233 psArrayAdd (sources, 1, source); 234 psFree(source); 232 235 } 233 236 … … 250 253 251 254 pmModelType sersicModelType = pmModelClassGetType("PS_MODEL_SERSIC"); 255 pmModelType devModelType = pmModelClassGetType("PS_MODEL_DEV"); 256 pmModelType selectedModelType = -1; 257 bool chooseBest = false; 258 bool chooseAll = false; 252 259 253 260 psString modelToChoose = psMetadataLookupStr(&mdok, recipe, "EXT_MODEL_TYPE_FOR_CFF"); 254 pmModelType selectedModelType = -1; 261 255 262 if (mdok && modelToChoose != NULL) { 256 if (strcmp(modelToChoose, "BEST")) { 263 if (!strcmp(modelToChoose, "BEST")) { 264 chooseBest = true; 265 } else if (!strcmp(modelToChoose, "ALL")) { 266 chooseAll = true; 267 } else if (strcmp(modelToChoose, "PS_MODEL_SERSIC")) { 268 // We have selected a model type other than Sersic. 269 // Save it's type for use below. Sersic is handled specially 257 270 selectedModelType = pmModelClassGetType(modelToChoose); 258 271 } 259 272 } 273 274 // minimum sersic index to force devModel 275 psF32 sersicMinDev = psMetadataLookupF32(&mdok, recipe, "EXT_MODEL_FORCE_DEV_SERSIC_MIN"); 276 if (!mdok) { 277 sersicMinDev = NAN; 278 } 279 280 sources = psArraySort (sources, pmSourceSortBySeq); 260 281 261 282 for (int i = 0; i < sources->n; i++) { … … 263 284 pmSource *source = thisSource->parent ? thisSource->parent : thisSource; 264 285 265 psF32 xPos, yPos, flux, rMajor, rMinor, theta; 266 psS32 modelType = 0; 286 #define MAX_ROWS_PER_SRC 10 287 psF32 xPos[MAX_ROWS_PER_SRC], yPos[MAX_ROWS_PER_SRC], flux[MAX_ROWS_PER_SRC]; 288 psF32 rMajor[MAX_ROWS_PER_SRC], rMinor[MAX_ROWS_PER_SRC], theta[MAX_ROWS_PER_SRC]; 289 psS32 modelType[MAX_ROWS_PER_SRC]; 290 psF32 sersicIndex[MAX_ROWS_PER_SRC]; 267 291 bool fitGalaxy = false; 268 292 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; 293 int n_rows = 0; 294 295 // start with psf model 296 pmModel *model = source->modelPSF; 297 if (model == NULL) continue; 298 psF32 *PAR = model->params->data.F32; 299 if (!isfinite(PAR[PM_PAR_SXX]) || !isfinite(PAR[PM_PAR_SYY]) || !isfinite(PAR[PM_PAR_SXY]) || 300 !isfinite(source->psfFlux)) { 301 continue; 302 } 303 304 xPos[0] = model->params->data.F32[PM_PAR_XPOS]; 305 yPos[0] = model->params->data.F32[PM_PAR_YPOS]; 306 flux[0] = source->psfFlux; 307 rMajor[0] = 0; 308 rMinor[0] = 0; 309 theta[0] = 0; 310 modelType[0] = -1; 311 sersicIndex[0] = NAN; 312 313 if (source->modelFits != NULL) { 314 // figure out which models to use based on recipe paramters 315 if (chooseAll) { 316 // Save parameters for all valid extended models 317 318 // but make sure we aren't going to overflow our arrays 319 assert (source->modelFits->n < MAX_ROWS_PER_SRC); 320 292 321 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; 322 pmModel *model = source->modelFits->data[j]; 323 psF32 *PAR = model->params->data.F32; 324 325 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY]) && isfinite(PAR[PM_PAR_SXY]) && 326 isfinite(model->mag)) { 327 328 xPos[n_rows] = PAR[PM_PAR_XPOS]; 329 yPos[n_rows] = PAR[PM_PAR_YPOS]; 330 331 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type); 332 rMajor[n_rows] = axes.major; 333 rMinor[n_rows] = axes.minor; 334 theta[n_rows] = axes.theta*PS_DEG_RAD; 335 flux[n_rows] = pow(10.0, -0.4*model->mag); 336 modelType[n_rows] = model->type; 337 fitGalaxy = true; 338 if (model->params->n == 8) { 339 // this will save the sersic index in all models but that might 340 // be useful 341 sersicIndex[n_rows] = 0.5 / PAR[PM_PAR_7]; 342 } else { 343 sersicIndex[n_rows] = NAN; 344 } 345 346 n_rows++; 347 } 348 } 349 } else { 350 int jModelSersic = -1; 351 int jModelDev = -1; 352 int jModelSelected = -1; 353 psF32 minChisq = NAN; 354 for (int j=0; j<source->modelFits->n; j++) { 355 pmModel *model = source->modelFits->data[j]; 356 if (chooseBest) { 357 // choose the model with lowest chisq 358 if (isfinite(model->chisq) && (!isfinite(minChisq) || model->chisq < minChisq)) { 359 jModelSelected = j; 360 minChisq = model->chisq; 361 } 362 } else { 363 // find the index of models of interest 364 if (model->type == selectedModelType) { 365 jModelSelected = j; 366 } else if (model->type == sersicModelType) { 367 jModelSersic = j; 368 } else if (model->type == devModelType) { 369 jModelDev = j; 370 } 371 } 372 } 373 if (jModelSelected >= 0 || jModelSersic >= 0) { 374 // If a specific non-sersic model we take paramers from that one. 375 // Otherwise we do the sersic model. 376 pmModel *model = jModelSelected >= 0 ? source->modelFits->data[jModelSelected] : 377 source->modelFits->data[jModelSersic]; 378 psF32 *PAR = model->params->data.F32; 379 380 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY]) && isfinite(PAR[PM_PAR_SXY]) && 381 isfinite(model->mag)) { 382 383 xPos[0] = PAR[PM_PAR_XPOS]; 384 yPos[0] = PAR[PM_PAR_YPOS]; 385 386 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type); 387 rMajor[0] = axes.major; 388 rMinor[0] = axes.minor; 389 theta[0] = axes.theta*PS_DEG_RAD; 390 flux[0] = pow(10.0, -0.4*model->mag); 391 modelType[0] = model->type; 392 fitGalaxy = true; 393 if (model->type == sersicModelType) { 394 PS_ASSERT_FLOAT_LARGER_THAN(PAR[PM_PAR_7], 0.0, false); 395 sersicIndex[0] = 0.5 / PAR[PM_PAR_7]; 396 } 397 398 n_rows = 1; 399 400 // Unless a specific non-sersic model type was selected do dev model for sources with 401 // sersic index above the recipe limit. 402 if (jModelSelected == -1 && jModelDev >= 0 && isfinite(sersicMinDev) && 403 sersicIndex[0] > sersicMinDev) { 404 405 model = source->modelFits->data[jModelDev]; 406 if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY]) && isfinite(PAR[PM_PAR_SXY]) && 407 isfinite(model->mag)) { 408 409 xPos[1] = PAR[PM_PAR_XPOS]; 410 yPos[1] = PAR[PM_PAR_YPOS]; 411 412 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type); 413 rMajor[1] = axes.major; 414 rMinor[1] = axes.minor; 415 theta[1] = axes.theta*PS_DEG_RAD; 416 flux[1] = pow(10.0, -0.4*model->mag); 417 modelType[1] = model->type; 418 sersicIndex[1] = NAN; 419 n_rows = 2; 420 } 421 } 297 422 } 298 423 } 299 424 } 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); 425 } 426 if (n_rows == 0) { 427 // didn't find a suitable extended model we have one row with the psf parameters 428 n_rows = 1; 429 } 430 431 for (int j = 0; j < n_rows; j++) { 432 psMetadata *row = psMetadataAlloc(); 433 psMetadataAddU32 (row, PS_LIST_TAIL, "ID", 0, "IPP detection identifier", source->seq); 434 psMetadataAddF32 (row, PS_LIST_TAIL, "X", 0, "x coordinate", xPos[j]); 435 psMetadataAddF32 (row, PS_LIST_TAIL, "Y", 0, "y coordinate", yPos[j]); 436 psMetadataAddF32 (row, PS_LIST_TAIL, "FLUX", 0, "flux per second", flux[j]/exptime); 437 psMetadataAddF32 (row, PS_LIST_TAIL, "AP_RADIUS", 0, "aperture radius", source->apRadius); 438 psMetadataAddF32 (row, PS_LIST_TAIL, "KRON_RADIUS", 0, "Kron radius", source->moments->Mrf * 2.5); 439 psMetadataAddF32 (row, PS_LIST_TAIL, "PETRO_RADIUS", 0, "Petrosian Radius", source->extpars ? source->extpars->petrosianRadius : NAN); 440 psMetadataAddBool (row, PS_LIST_TAIL, "FIT_GALAXY", 0, "source has xfit", fitGalaxy); 441 psMetadataAddBool (row, PS_LIST_TAIL, "PSF_STAR", 0, "source was psf star", psfStar); 442 psMetadataAddF32 (row, PS_LIST_TAIL, "R_MAJOR", 0, "radius of major axis", rMajor[j]); 443 psMetadataAddF32 (row, PS_LIST_TAIL, "R_MINOR", 0, "radius of minor axis", rMinor[j]); 444 psMetadataAddF32 (row, PS_LIST_TAIL, "THETA", 0, "theta", theta[j]); 445 psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TYPE", 0, "model type", modelType[j]); 446 psMetadataAddF32 (row, PS_LIST_TAIL, "INDEX", 0, "sersic index", sersicIndex[j]); 447 448 psArrayAdd(table, 100, row); 449 psFree(row); 450 } 349 451 } 350 452
Note:
See TracChangeset
for help on using the changeset viewer.
