- Timestamp:
- Jul 20, 2010, 7:21:53 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20100621/psModules/src/objects/pmPCMdata.c
r28687 r28692 1 static void pmPCMDataFree (pmPCMData *pcm) { 1 /* @file pmPCMdata.c 2 * structures and functions to support PSF-convolved model fitting 3 * 4 * @author EAM, IfA 5 * 6 * @version $Revision: 1.29 $ 7 * @date $Date: 2009-02-16 22:30:50 $ 8 * Copyright 2010 Institute for Astronomy, University of Hawaii 9 */ 10 11 #ifdef HAVE_CONFIG_H 12 #include <config.h> 13 #endif 14 15 #include <stdio.h> 16 #include <math.h> 17 #include <string.h> 18 #include <strings.h> 19 #include <pslib.h> 20 #include "pmHDU.h" 21 #include "pmFPA.h" 22 #include "pmFPAMaskWeight.h" 23 24 #include "pmTrend2D.h" 25 #include "pmResiduals.h" 26 #include "pmGrowthCurve.h" 27 #include "pmSpan.h" 28 #include "pmFootprintSpans.h" 29 #include "pmFootprint.h" 30 #include "pmPeaks.h" 31 #include "pmMoments.h" 32 #include "pmModelFuncs.h" 33 #include "pmModel.h" 34 #include "pmModelUtils.h" 35 #include "pmModelClass.h" 36 #include "pmSourceMasks.h" 37 #include "pmSourceExtendedPars.h" 38 #include "pmSourceDiffStats.h" 39 #include "pmSource.h" 40 #include "pmSourceFitModel.h" 41 #include "pmPCMdata.h" 42 43 static void pmPCMdataFree (pmPCMdata *pcm) { 2 44 3 45 if (pcm == NULL) return; 4 46 5 psFree (pcm->model); 47 psFree (pcm->modelFlux); 48 psFree (pcm->modelConvFlux); 49 psFree (pcm->dmodelsFlux); 50 psFree (pcm->dmodelsConvFlux); 51 6 52 psFree (pcm->modelConv); 7 psFree (pcm-> dmodels);8 psFree (pcm-> dmodelsConv);53 psFree (pcm->psf); 54 psFree (pcm->constraint); 9 55 return; 10 56 } 11 57 12 pmPCM Data *pmPCMDataAlloc (58 pmPCMdata *pmPCMdataAlloc ( 13 59 const psVector *params, 14 60 const psVector *paramMask, 15 61 pmSource *source) { 16 62 17 pmPCM Data *pcm = (pmPCMData *) psAlloc(sizeof(pmPCMData));18 psMemSetDeallocator(pcm, (psFreeFunc) pmPCM DataFree);63 pmPCMdata *pcm = (pmPCMdata *) psAlloc(sizeof(pmPCMdata)); 64 psMemSetDeallocator(pcm, (psFreeFunc) pmPCMdataFree); 19 65 20 66 // Allocate storage images for raw model and derivative images 21 pcm->model = psImageCopy (NULL, source->pixels, PS_TYPE_F32);22 pcm->dmodels = psArrayAlloc (params->n);67 pcm->modelFlux = psImageCopy (NULL, source->pixels, PS_TYPE_F32); 68 pcm->dmodelsFlux = psArrayAlloc (params->n); 23 69 for (psS32 n = 0; n < params->n; n++) { 24 pcm->dmodels ->data[n] = NULL;70 pcm->dmodelsFlux->data[n] = NULL; 25 71 if ((paramMask != NULL) && (paramMask->data.PS_TYPE_VECTOR_MASK_DATA[n])) { continue; } 26 pcm->dmodels ->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32);72 pcm->dmodelsFlux->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32); 27 73 } 28 74 29 75 // Allocate storage images for convolved model and derivative images 30 pcm->modelConv = psImageCopy (NULL, source->pixels, PS_TYPE_F32);31 pcm->dmodelsConv = psArrayAlloc (params->n);76 pcm->modelConvFlux = psImageCopy (NULL, source->pixels, PS_TYPE_F32); 77 pcm->dmodelsConvFlux = psArrayAlloc (params->n); 32 78 for (psS32 n = 0; n < params->n; n++) { 33 pcm->dmodelsConv ->data[n] = NULL;79 pcm->dmodelsConvFlux->data[n] = NULL; 34 80 if ((paramMask != NULL) && (paramMask->data.PS_TYPE_VECTOR_MASK_DATA[n])) { continue; } 35 pcm->dmodelsConv->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32); 36 } 81 pcm->dmodelsConvFlux->data[n] = psImageCopy (NULL, source->pixels, PS_TYPE_F32); 82 } 83 84 pcm->modelConv = NULL; 85 pcm->psf = NULL; 86 pcm->constraint = NULL; 87 pcm->nDOF = 0; 37 88 38 89 return pcm; 39 90 } 40 91 41 psImage *pmPCM DataSaveImage (pmPCMData *pcm) {42 43 psImage *model = psImageCopy (NULL, pcm->modelConv , PS_TYPE_F32);92 psImage *pmPCMdataSaveImage (pmPCMdata *pcm) { 93 94 psImage *model = psImageCopy (NULL, pcm->modelConvFlux, PS_TYPE_F32); 44 95 45 96 return model; 46 97 } 47 98 99 psKernel *pmPCMkernelFromPSF (pmSource *source, int nPix) { 100 101 assert (source); 102 assert (source->psfImage); // XXX build if needed? 103 104 int x0 = source->peak->xf - source->psfImage->col0; 105 int y0 = source->peak->yf - source->psfImage->row0; 106 107 // need to decide on the size: dynamically? statically? 108 psKernel *psf = psKernelAlloc (-nPix, +nPix, -nPix, +nPix); 109 110 // XXX we should just re-construct a PSF at this location 111 // psModelAdd (psf->image, NULL, source->modelPSF, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM | PM_MODEL_OP_CENTER); 112 113 // if the realized PSF for this object does not cover the full kernel, give up for now 114 if (x0 + psf->xMin < 0) goto escape; 115 if (x0 + psf->xMax >= source->psfImage->numCols) goto escape; 116 if (y0 + psf->yMin < 0) goto escape; 117 if (y0 + psf->yMax >= source->psfImage->numRows) goto escape; 118 119 double sum = 0.0; 120 for (int j = psf->yMin; j <= psf->yMax; j++) { 121 for (int i = psf->xMin; i <= psf->xMax; i++) { 122 double value = source->psfImage->data.F32[y0 + j][x0 + i]; 123 psf->kernel[j][i] = value; 124 sum += value; 125 } 126 } 127 assert (sum > 0.0); 128 129 // psf must be normalized (integral = 1.0) 130 for (int i = 0; i < psf->image->numRows; i++) { 131 for (int j = 0; j < psf->image->numCols; j++) { 132 psf->image->data.F32[i][j] /= sum; 133 } 134 } 135 136 return psf; 137 138 escape: 139 psFree (psf); 140 return NULL; 141 } 142 143 pmPCMdata *pmPCMinit(pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, float psfSize) { 144 145 // make sure we savep a cached copy of the psf flux 146 pmSourceCachePSF (source, maskVal); 147 148 // convert the cached cached psf model for this source to a psKernel 149 psKernel *psf = pmPCMkernelFromPSF (source, psfSize); 150 if (!psf) return NULL; 151 152 # if (USE_DELTA_PSF) 153 psImageInit (psf->image, 0.0); 154 psf->image->data.F32[(int)(0.5*psf->image->numRows)][(int)(0.5*psf->image->numCols)] = 1.0; 155 # endif 156 157 // allocate the model 158 pmModel *modelConv = pmModelAlloc(modelType); 159 if (!modelConv) { 160 psFree (psf); 161 return NULL; 162 } 163 164 // count the number of unmasked pixels: 165 int nPix = 0; 166 for (psS32 i = 0; i < source->pixels->numRows; i++) { 167 for (psS32 j = 0; j < source->pixels->numCols; j++) { 168 // XXX are we doing the right thing with the mask? 169 // skip masked points 170 if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[i][j]) { 171 continue; 172 } 173 // skip zero-variance points 174 if (source->variance->data.F32[i][j] == 0) { 175 continue; 176 } 177 // skip nan value points 178 if (!isfinite(source->pixels->data.F32[i][j])) { 179 continue; 180 } 181 nPix ++; 182 } 183 } 184 185 psVector *params = modelConv->params; 186 187 // create the minimization constraints 188 psMinConstraint *constraint = psMinConstraintAlloc(); 189 constraint->paramMask = psVectorAlloc (params->n, PS_TYPE_VECTOR_MASK); 190 constraint->checkLimits = modelConv->modelLimits; 191 192 // set parameter mask based on fitting mode 193 int nParams = 0; 194 switch (fitOptions->mode) { 195 case PM_SOURCE_FIT_NORM: 196 // NORM-only model fits only source normalization (Io) 197 nParams = 1; 198 psVectorInit (constraint->paramMask, 1); 199 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0; 200 break; 201 case PM_SOURCE_FIT_PSF: 202 // PSF model only fits x,y,Io 203 nParams = 3; 204 psVectorInit (constraint->paramMask, 1); 205 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0; 206 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0; 207 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0; 208 break; 209 case PM_SOURCE_FIT_EXT: 210 // EXT model fits all params (except sky) 211 nParams = params->n - 1; 212 psVectorInit (constraint->paramMask, 0); 213 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1; 214 break; 215 case PM_SOURCE_FIT_INDEX: 216 // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params 217 psVectorInit (constraint->paramMask, 1); 218 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0; 219 if (params->n == 7) { 220 nParams = 1; 221 } else { 222 nParams = 2; 223 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0; 224 } 225 break; 226 case PM_SOURCE_FIT_NO_INDEX: 227 // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params 228 psVectorInit (constraint->paramMask, 0); 229 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1; 230 if (params->n == 7) { 231 nParams = params->n - 1; 232 } else { 233 nParams = params->n - 2; 234 constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1; 235 } 236 break; 237 default: 238 psAbort("invalid fitting mode"); 239 } 240 241 // generate PCM data storage structure 242 pmPCMdata *pcm = pmPCMdataAlloc (params, constraint->paramMask, source); 243 244 pcm->modelConv = modelConv; 245 pcm->psf = psf; 246 pcm->constraint = constraint; 247 248 if (nPix < nParams + 1) { 249 psTrace ("psModules.objects", 4, "insufficient valid pixels\n"); 250 pcm->modelConv->flags |= PM_MODEL_STATUS_BADARGS; 251 abort (); 252 // XXX This should not be an abort!! 253 } 254 pcm->nPix = nPix; 255 pcm->nDOF = nPix - nParams - 1; 256 257 return pcm; 258 }
Note:
See TracChangeset
for help on using the changeset viewer.
