- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/simtest_nebulous_branches/psModules/src/camera/pmReadoutFake.c
r23960 r27840 23 23 #include "pmSourceUtils.h" 24 24 #include "pmModelUtils.h" 25 #include "pmSourceGroups.h" 25 26 26 27 #include "pmReadoutFake.h" 27 28 28 #define MODEL_TYPE "PS_MODEL_RGAUSS" // Type of model to use29 29 #define MAX_AXIS_RATIO 20.0 // Maximum axis ratio for PSF model 30 #define SOURCE_MASK (PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_CR_LIMIT) // Mask to apply to input sources31 30 #define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \ 32 31 PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models 32 33 34 static bool threaded = false; // Running threaded? 35 36 33 37 34 38 … … 50 54 } 51 55 52 bool pmReadoutFakeFromSources(pmReadout *readout, int numCols, int numRows, const psArray *sources, 53 const psVector *xOffset, const psVector *yOffset, const pmPSF *psf, 54 float minFlux, int radius, bool circularise, bool normalisePeak) 56 /// Generate fake sources on a readout 57 static bool readoutFake(pmReadout *readout, // Readout of interest 58 const pmSourceGroups *groups, // Source groups 59 const psVector *x, // x coordinates 60 const psVector *y, // y coordinates 61 const psVector *mag, // Magnitudes 62 const psVector *xOffset, // Offsets in x 63 const psVector *yOffset, // Offsets in y 64 const pmPSF *psf, // PSF 65 float minFlux, // Minimum flux 66 float radius, // Minimum radius 67 bool circularise, // Circularise PSF? 68 bool normalisePeak, // Normalise sources for peak? 69 int groupIndex, // Group index 70 int cellIndex // Cell index 71 ) 72 { 73 psArray *cells = groups->groups->data[groupIndex]; // Cells in group 74 psVector *cellSources = cells->data[cellIndex]; // Sources in cell 75 76 for (int i = 0; i < cellSources->n; i++) { 77 int index = cellSources->data.S32[i]; // Index for source of interest 78 float flux = powf(10.0, -0.4 * mag->data.F32[index]); // Flux of source 79 float xSrc = x->data.F32[index], ySrc = y->data.F32[index]; // Coordinates of source 80 81 if (normalisePeak) { 82 // Normalise flux 83 pmModel *normModel = pmModelFromPSFforXY(psf, xSrc, ySrc, 1.0); // Model for normalisation 84 if (!normModel || (normModel->flags & MODEL_MASK)) { 85 psFree(normModel); 86 continue; 87 } 88 // check that all params are valid: 89 bool validParams = true; 90 for (int j = 0; validParams && (j < normModel->params->n); j++) { 91 switch (j) { 92 case PM_PAR_SKY: 93 case PM_PAR_I0: 94 case PM_PAR_XPOS: 95 case PM_PAR_YPOS: 96 continue; 97 default: 98 if (!isfinite(normModel->params->data.F32[j])) { 99 validParams = false; 100 } 101 } 102 } 103 if (!validParams) { 104 psFree(normModel); 105 continue; 106 } 107 if (circularise && !circulariseModel(normModel)) { 108 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model."); 109 psFree(normModel); 110 return false; 111 } 112 113 flux /= normModel->modelFlux(normModel->params); 114 psFree(normModel); 115 } 116 117 pmModel *fakeModel = pmModelFromPSFforXY(psf, xSrc, ySrc, flux); 118 if (!fakeModel || (fakeModel->flags & MODEL_MASK)) { 119 psFree(fakeModel); 120 continue; 121 } 122 // check that all params are valid: 123 bool validParams = true; 124 for (int j = 0; validParams && (j < fakeModel->params->n); j++) { 125 switch (j) { 126 case PM_PAR_SKY: 127 case PM_PAR_I0: 128 case PM_PAR_XPOS: 129 case PM_PAR_YPOS: 130 continue; 131 default: 132 if (!isfinite(fakeModel->params->data.F32[j])) { 133 validParams = false; 134 } 135 } 136 } 137 if (!validParams) { 138 psFree(fakeModel); 139 continue; 140 } 141 if (circularise && !circulariseModel(fakeModel)) { 142 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model."); 143 psFree(fakeModel); 144 return false; 145 } 146 147 psTrace("psModules.camera", 10, "Adding source at %f,%f with flux %f\n", 148 fakeModel->params->data.F32[PM_PAR_XPOS], fakeModel->params->data.F32[PM_PAR_YPOS], 149 fakeModel->params->data.F32[PM_PAR_I0]); 150 151 pmSource *fakeSource = pmSourceAlloc(); // Fake source to generate 152 fakeSource->peak = pmPeakAlloc(xSrc, ySrc, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE); 153 float fakeRadius = 1.0; // Radius of fake source 154 if (isfinite(minFlux)) { 155 fakeRadius = PS_MAX(fakeRadius, fakeModel->modelRadius(fakeModel->params, minFlux)); 156 } 157 if (radius > 0) { 158 fakeRadius = PS_MAX(fakeRadius, radius); 159 } 160 161 if (xOffset) { 162 if (!pmSourceDefinePixels(fakeSource, readout, xSrc + xOffset->data.S32[index], 163 ySrc + yOffset->data.S32[index], fakeRadius)) { 164 psErrorClear(); 165 continue; 166 } 167 if (!pmModelAddWithOffset(fakeSource->pixels, NULL, fakeModel, PM_MODEL_OP_FULL, 0, 168 xOffset->data.S32[index], yOffset->data.S32[index])) { 169 psErrorClear(); 170 continue; 171 } 172 } else { 173 if (!pmSourceDefinePixels(fakeSource, readout, xSrc, ySrc, fakeRadius)) { 174 psErrorClear(); 175 continue; 176 } 177 if (!pmModelAdd(fakeSource->pixels, NULL, fakeModel, PM_MODEL_OP_FULL, 0)) { 178 psErrorClear(); 179 continue; 180 } 181 } 182 psFree(fakeSource); 183 psFree(fakeModel); 184 } 185 186 return true; 187 } 188 189 /// Thread job for readoutFake() 190 static bool readoutFakeThread(psThreadJob *job) 191 { 192 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 193 194 psArray *args = job->args; // Arguments 195 196 pmReadout *readout = args->data[0]; // Readout of interest 197 const pmSourceGroups *groups = args->data[1]; // Source groups 198 const psVector *x = args->data[2]; // x coordinates 199 const psVector *y = args->data[3]; // y coordinates 200 const psVector *mag = args->data[4]; // Magnitudes 201 const psVector *xOffset = args->data[5]; // Offsets in x 202 const psVector *yOffset = args->data[6]; // Offsets in y 203 const pmPSF *psf = args->data[7]; // PSF 204 float minFlux = PS_SCALAR_VALUE(args->data[8], F32); // Minimum flux 205 float radius = PS_SCALAR_VALUE(args->data[9], F32); // Minimum radius 206 bool circularise = PS_SCALAR_VALUE(args->data[10], U8); // Circularise PSF? 207 bool normalisePeak = PS_SCALAR_VALUE(args->data[11], U8); // Normalise for peak? 208 int groupIndex = PS_SCALAR_VALUE(args->data[12], S32); // Group index 209 int cellIndex = PS_SCALAR_VALUE(args->data[13], S32); // Cell index 210 211 return readoutFake(readout, groups, x, y, mag, xOffset, yOffset, psf, minFlux, radius, circularise, 212 normalisePeak, groupIndex, cellIndex); 213 } 214 215 216 bool pmReadoutFakeThreads(bool new) 217 { 218 bool old = threaded; // Old status, to return 219 220 if (!old && new) { 221 threaded = true; 222 223 { 224 psThreadTask *task = psThreadTaskAlloc("PSMODULES_READOUT_FAKE", 14); 225 task->function = &readoutFakeThread; 226 psThreadTaskAdd(task); 227 psFree(task); 228 } 229 230 } else if (old && !new) { 231 threaded = false; 232 psThreadTaskRemove("PSMODULES_READOUT_FAKE"); 233 } 234 235 return old; 236 } 237 238 239 bool pmReadoutFakeFromVectors(pmReadout *readout, int numCols, int numRows, 240 const psVector *x, const psVector *y, const psVector *mag, 241 const psVector *xOffset, const psVector *yOffset, 242 const pmPSF *psf, float minFlux, int radius, 243 bool circularise, bool normalisePeak) 55 244 { 56 245 PS_ASSERT_PTR_NON_NULL(readout, false); 57 246 PS_ASSERT_INT_LARGER_THAN(numCols, 0, false); 58 247 PS_ASSERT_INT_LARGER_THAN(numRows, 0, false); 59 PS_ASSERT_ARRAY_NON_NULL(sources, false); 60 248 PS_ASSERT_VECTOR_NON_NULL(x, false); 249 PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, false); 250 PS_ASSERT_VECTOR_NON_NULL(y, false); 251 PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, false); 252 PS_ASSERT_VECTORS_SIZE_EQUAL(y, x, false); 253 PS_ASSERT_VECTOR_NON_NULL(mag, false); 254 PS_ASSERT_VECTOR_TYPE(mag, PS_TYPE_F32, false); 255 PS_ASSERT_VECTORS_SIZE_EQUAL(mag, x, false); 256 long numSources = x->n; // Number of sources 61 257 if (xOffset || yOffset) { 62 258 PS_ASSERT_VECTOR_NON_NULL(xOffset, false); … … 64 260 PS_ASSERT_VECTORS_SIZE_EQUAL(xOffset, yOffset, false); 65 261 PS_ASSERT_VECTOR_TYPE(xOffset, PS_TYPE_S32, false); 66 PS_ASSERT_VECTOR_TYPE _EQUAL(xOffset, yOffset, false);67 if (xOffset->n != sources->n) {262 PS_ASSERT_VECTOR_TYPE(yOffset, PS_TYPE_S32, false); 263 if (xOffset->n != numSources) { 68 264 psError(PS_ERR_BAD_PARAMETER_SIZE, true, 69 265 "Number of offset vectors (%ld) and sources (%ld) doesn't match", 70 xOffset->n, sources->n);266 xOffset->n, numSources); 71 267 return false; 72 268 } 73 269 } 74 270 PS_ASSERT_PTR_NON_NULL(psf, false); 75 if (radius > 0 && isfinite(minFlux) && minFlux > 0.0) {76 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot define both minimum flux and fixed radius.");77 return false;78 }79 271 80 272 readout->image = psImageRecycle(readout->image, numCols, numRows, PS_TYPE_F32); 81 273 psImageInit(readout->image, 0); 82 274 275 int numThreads = threaded ? psThreadPoolSize() : 0; // Number of threads 276 pmSourceGroups *groups = pmSourceGroupsFromVectors(readout, x, y, numThreads); // Groups of sources 277 if (!groups) { 278 psError(PS_ERR_UNKNOWN, false, "Unable to generate source groups"); 279 return false; 280 } 281 282 if (threaded) { 283 for (int i = 0; i < groups->groups->n; i++) { 284 psArray *cells = groups->groups->data[i]; // Cell with sources 285 for (int j = 0; j < cells->n; j++) { 286 psThreadJob *job = psThreadJobAlloc("PSMODULES_READOUT_FAKE"); 287 psArray *args = job->args; 288 psArrayAdd(args, 1, readout); 289 psArrayAdd(args, 1, groups); 290 // Casting away const to add to array 291 psArrayAdd(args, 1, (psVector*)x); 292 psArrayAdd(args, 1, (psVector*)y); 293 psArrayAdd(args, 1, (psVector*)mag); 294 psArrayAdd(args, 1, (psVector*)xOffset); 295 psArrayAdd(args, 1, (psVector*)yOffset); 296 psArrayAdd(args, 1, (pmPSF*)psf); 297 PS_ARRAY_ADD_SCALAR(args, minFlux, PS_TYPE_F32); 298 PS_ARRAY_ADD_SCALAR(args, radius, PS_TYPE_S32); 299 PS_ARRAY_ADD_SCALAR(args, circularise, PS_TYPE_U8); 300 PS_ARRAY_ADD_SCALAR(args, normalisePeak, PS_TYPE_U8); 301 PS_ARRAY_ADD_SCALAR(args, i, PS_TYPE_S32); 302 PS_ARRAY_ADD_SCALAR(args, j, PS_TYPE_S32); 303 304 if (!psThreadJobAddPending(job)) { 305 psFree(job); 306 psFree(groups); 307 return false; 308 } 309 psFree(job); 310 } 311 if (!psThreadPoolWait(true)) { 312 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 313 psFree(groups); 314 return false; 315 } 316 } 317 } else if (!readoutFake(readout, groups, x, y, mag, xOffset, yOffset, psf, minFlux, radius, circularise, 318 normalisePeak, 0, 0)) { 319 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake sources on readout"); 320 psFree(groups); 321 return false; 322 } 323 324 psFree(groups); 325 326 // Set a concept value 327 #define CONCEPT_SET_S32(CONCEPTS, NAME, OLD, NEW) { \ 328 psMetadataItem *item = psMetadataLookup(CONCEPTS, NAME); \ 329 psAssert(item->type == PS_TYPE_S32, "Incorrect type: %x", item->type); \ 330 if (item->data.S32 == OLD) { \ 331 item->data.S32 = NEW; \ 332 } \ 333 } 334 335 if (readout->parent) { 336 CONCEPT_SET_S32(readout->parent->concepts, "CELL.XPARITY", 0, 1); 337 CONCEPT_SET_S32(readout->parent->concepts, "CELL.YPARITY", 0, 1); 338 CONCEPT_SET_S32(readout->parent->concepts, "CELL.XBIN", 0, 1); 339 CONCEPT_SET_S32(readout->parent->concepts, "CELL.YBIN", 0, 1); 340 } 341 342 return true; 343 344 } 345 346 347 bool pmReadoutFakeFromSources(pmReadout *readout, int numCols, int numRows, const psArray *sources, 348 pmSourceMode sourceMask, const psVector *xOffset, const psVector *yOffset, 349 const pmPSF *psf, float minFlux, int radius, 350 bool circularise, bool normalisePeak) 351 { 352 PS_ASSERT_ARRAY_NON_NULL(sources, false); 353 83 354 int numSources = sources->n; // Number of stars 355 psVector *x = psVectorAllocEmpty(numSources, PS_TYPE_F32); 356 psVector *y = psVectorAllocEmpty(numSources, PS_TYPE_F32); 357 psVector *mag = psVectorAllocEmpty(numSources, PS_TYPE_F32); 358 359 int numGood = 0; // Number of good sources 84 360 for (int i = 0; i < numSources; i++) { 85 361 pmSource *source = sources->data[i]; // Source of interest … … 87 363 continue; 88 364 } 89 if (source->mode & SOURCE_MASK) {365 if (source->mode & sourceMask) { 90 366 continue; 91 367 } … … 93 369 continue; 94 370 } 95 float x , y; // Coordinates of source371 float xSrc, ySrc; // Coordinates of source 96 372 if (source->modelPSF) { 97 x = source->modelPSF->params->data.F32[PM_PAR_XPOS];98 y = source->modelPSF->params->data.F32[PM_PAR_YPOS];373 xSrc = source->modelPSF->params->data.F32[PM_PAR_XPOS]; 374 ySrc = source->modelPSF->params->data.F32[PM_PAR_YPOS]; 99 375 } else { 100 x = source->peak->xf; 101 y = source->peak->yf; 102 } 103 104 float flux = powf(10.0, -0.4 * source->psfMag); // Flux of source 105 106 if (normalisePeak) { 107 // Normalise flux 108 pmModel *normModel = pmModelFromPSFforXY(psf, x, y, 1.0); // Model for normalisation 109 if (!normModel || (normModel->flags & MODEL_MASK)) { 110 psFree(normModel); 111 continue; 112 } 113 if (circularise && !circulariseModel(normModel)) { 114 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model."); 115 psFree(normModel); 116 return false; 117 } 118 119 flux /= normModel->modelFlux(normModel->params); 120 psFree(normModel); 121 } 122 123 pmModel *fakeModel = pmModelFromPSFforXY(psf, x, y, flux); 124 if (!fakeModel || (fakeModel->flags & MODEL_MASK)) { 125 psFree(fakeModel); 126 continue; 127 } 128 if (circularise && !circulariseModel(fakeModel)) { 129 psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model."); 130 psFree(fakeModel); 131 return false; 132 } 133 134 psTrace("psModules.camera", 10, "Adding source at %f,%f with flux %f\n", 135 fakeModel->params->data.F32[PM_PAR_XPOS], fakeModel->params->data.F32[PM_PAR_YPOS], 136 fakeModel->params->data.F32[PM_PAR_I0]); 137 138 pmSource *fakeSource = pmSourceAlloc(); // Fake source to generate 139 fakeSource->peak = pmPeakAlloc(x, y, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE); 140 float fakeRadius = radius > 0 ? radius : 141 PS_MAX(1.0, fakeModel->modelRadius(fakeModel->params, minFlux)); // Radius of fake source 142 143 if (xOffset) { 144 if (!pmSourceDefinePixels(fakeSource, readout, x + xOffset->data.S32[i], 145 y + yOffset->data.S32[i], fakeRadius)) { 146 psErrorClear(); 147 continue; 148 } 149 if (!pmModelAddWithOffset(fakeSource->pixels, NULL, fakeModel, PM_MODEL_OP_FULL, 0, 150 xOffset->data.S32[i], yOffset->data.S32[i])) { 151 psErrorClear(); 152 continue; 153 } 154 } else { 155 if (!pmSourceDefinePixels(fakeSource, readout, x, y, fakeRadius)) { 156 psErrorClear(); 157 continue; 158 } 159 if (!pmModelAdd(fakeSource->pixels, NULL, fakeModel, PM_MODEL_OP_FULL, 0)) { 160 psErrorClear(); 161 continue; 162 } 163 } 164 psFree(fakeSource); 165 psFree(fakeModel); 166 } 167 168 return true; 169 } 376 xSrc = source->peak->xf; 377 ySrc = source->peak->yf; 378 } 379 380 x->data.F32[numGood] = xSrc; 381 y->data.F32[numGood] = ySrc; 382 mag->data.F32[numGood] = source->psfMag; 383 numGood++; 384 } 385 x->n = numGood; 386 y->n = numGood; 387 mag->n = numGood; 388 389 bool status = pmReadoutFakeFromVectors(readout, numCols, numRows, x, y, mag, xOffset, yOffset, psf, 390 minFlux, radius, circularise, normalisePeak); 391 psFree(x); 392 psFree(y); 393 psFree(mag); 394 395 return status; 396 }
Note:
See TracChangeset
for help on using the changeset viewer.
