IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:50:52 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/simtest_nebulous_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simtest_nebulous_branches

  • branches/simtest_nebulous_branches/psModules

  • branches/simtest_nebulous_branches/psModules/src/camera/pmReadoutFake.c

    r23960 r27840  
    2323#include "pmSourceUtils.h"
    2424#include "pmModelUtils.h"
     25#include "pmSourceGroups.h"
    2526
    2627#include "pmReadoutFake.h"
    2728
    28 #define MODEL_TYPE "PS_MODEL_RGAUSS"    // Type of model to use
    2929#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 sources
    3130#define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \
    3231                    PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models
     32
     33
     34static bool threaded = false;           // Running threaded?
     35
     36
    3337
    3438
     
    5054}
    5155
    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
     57static 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()
     190static 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
     216bool 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
     239bool 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)
    55244{
    56245    PS_ASSERT_PTR_NON_NULL(readout, false);
    57246    PS_ASSERT_INT_LARGER_THAN(numCols, 0, false);
    58247    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
    61257    if (xOffset || yOffset) {
    62258        PS_ASSERT_VECTOR_NON_NULL(xOffset, false);
     
    64260        PS_ASSERT_VECTORS_SIZE_EQUAL(xOffset, yOffset, false);
    65261        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) {
    68264            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
    69265                    "Number of offset vectors (%ld) and sources (%ld) doesn't match",
    70                     xOffset->n, sources->n);
     266                    xOffset->n, numSources);
    71267            return false;
    72268        }
    73269    }
    74270    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     }
    79271
    80272    readout->image = psImageRecycle(readout->image, numCols, numRows, PS_TYPE_F32);
    81273    psImageInit(readout->image, 0);
    82274
     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
     347bool 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
    83354    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
    84360    for (int i = 0; i < numSources; i++) {
    85361        pmSource *source = sources->data[i]; // Source of interest
     
    87363            continue;
    88364        }
    89         if (source->mode & SOURCE_MASK) {
     365        if (source->mode & sourceMask) {
    90366            continue;
    91367        }
     
    93369            continue;
    94370        }
    95         float x, y;                     // Coordinates of source
     371        float xSrc, ySrc;                     // Coordinates of source
    96372        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];
    99375        } 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.