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/ppStack/src

    • Property svn:ignore
      •  

        old new  
        1010stamp-h1
        1111ppStackVersionDefinitions.h
         12ppStackErrorCodes.c
         13ppStackErrorCodes.h
  • branches/simtest_nebulous_branches/ppStack/src/ppStackSources.c

    r23573 r27840  
    88
    99//#define TESTING                         // Enable debugging output
     10
     11//#define ASTROMETRY                    // Correct astrometry?
    1012
    1113#ifdef TESTING
     
    6163    PS_ASSERT_PTR_NON_NULL(config, false);
    6264
     65    if (!options->matchZPs && !options->photometry) {
     66        options->norm = psVectorAlloc(options->num, PS_TYPE_F32);
     67        psVectorInit(options->norm, 0.0);
     68        return true;
     69    }
     70
    6371    psArray *sourceLists = options->sourceLists; // Source lists for each input
    6472    psVector *inputMask = options->inputMask; // Mask for inputs
     
    7987            }
    8088            source->psfMag += 1.0;
     89#ifdef ASTROMETRY
     90            if (source->modelPSF) {
     91                source->modelPSF->params->data.F32[PM_PAR_XPOS] += 1.0;
     92                source->modelPSF->params->data.F32[PM_PAR_YPOS] += 1.0;
     93            }
     94            if (source->peak) {
     95                source->peak->xf += 1.0;
     96                source->peak->yf += 1.0;
     97            }
     98#endif
    8199        }
    82100    }
     
    105123    psMetadata *airmassZP = psMetadataLookupMetadata(NULL, recipe, "ZP.AIRMASS"); // Airmass terms
    106124    if (!airmassZP) {
    107         psError(PS_ERR_UNKNOWN, false, "Unable to find ZP.AIRMASS in recipe.");
     125        psError(PPSTACK_ERR_CONFIG, false, "Unable to find ZP.AIRMASS in recipe.");
    108126        return false;
    109127    }
    110 
    111     int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs
     128    psMetadata *zpTargetMenu = psMetadataLookupMetadata(NULL, recipe, "ZP.TARGET"); // Target zero point terms
     129    if (!zpTargetMenu) {
     130        psError(PPSTACK_ERR_CONFIG, false, "Unable to find ZP.TARGET in recipe.");
     131        return false;
     132    }
     133
     134    int num = options->num;             // Number of inputs
    112135    psAssert(num == sourceLists->n, "Wrong number of source lists: %ld\n", sourceLists->n);
    113136
    114     psVector *zp = psVectorAlloc(num, PS_TYPE_F32); // Zero points for each image
     137    psVector *zp = psVectorAlloc(num, PS_TYPE_F32); // Relative zero points for each image
     138    psVector *zpExp = psVectorAlloc(num, PS_TYPE_F32); // Measured zero points for each image (maybe)
     139    int zpExpNum = 0;                                  // Number of measured zero points
    115140    const char *filter = NULL;          // Filter name
    116141    float airmassTerm = NAN;            // Airmass term
    117     float sumExpTime = 0.0;             // Sum of the exposure time
     142    float zpTarget = NAN;               // Target zero point
     143    int numGoodImages = 0;              // Number of good images
    118144    for (int i = 0; i < num; i++) {
     145        psArray *sources = sourceLists->data[i]; // Source list
     146        if (!sources || sources->n == 0) {
     147            psLogMsg("ppStack", PS_LOG_WARN, "Image %d has no sources for transparency measurement.", i);
     148            options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i] |= PPSTACK_MASK_CAL;
     149            zp->data.F32[i] = NAN;
     150            continue;
     151        }
     152        numGoodImages++;
     153
    119154        pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.INPUT", i); // File of interest
    120         pmCell *cell = pmFPAviewThisCell(view, file->fpa); // Cell of interest
    121155
    122156#if defined(TESTING) && 0
    123157        pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout
    124158        pmPSF *psf = psMetadataLookupPtr(NULL, config->arguments, "PSF.TARGET"); // PSF for fake image
    125         pmReadoutFakeFromSources(fake, FAKE_COLS, FAKE_ROWS, sourceLists->data[i],
     159        pmReadoutFakeFromSources(fake, FAKE_COLS, FAKE_ROWS, sourceLists->data[i], 0,
    126160                                 NULL, NULL, psf, 5, 0, false, true);
    127161        psString name = NULL;
     
    135169#endif
    136170
    137 
    138         float exptime = psMetadataLookupF32(NULL, cell->concepts, "CELL.EXPOSURE"); // Exposure time
     171        float exptime = options->exposures->data.F32[i]; // Exposure time
    139172        float airmass = psMetadataLookupF32(NULL, file->fpa->concepts, "FPA.AIRMASS"); // Airmass
    140173        const char *expFilter = psMetadataLookupStr(NULL, file->fpa->concepts, "FPA.FILTER"); // Filter name
     174        zpExp->data.F32[i] = psMetadataLookupF32(NULL, file->fpa->concepts, "FPA.ZP"); // Exposure zero point
     175        psLogMsg("ppStack", PS_LOG_INFO,
     176                 "Image %d: %.2f sec exposure in %s at airmass %.2f with zero point %.2f",
     177                 i, exptime, expFilter, airmass, zpExp->data.F32[i]);
    141178        if (!isfinite(exptime) || exptime == 0 || !isfinite(airmass) || airmass == 0 ||
    142179            !expFilter || strlen(expFilter) == 0) {
    143             psError(PS_ERR_UNEXPECTED_NULL, false,
     180            psError(PPSTACK_ERR_CONFIG, false,
    144181                    "Unable to find exposure time (%f), airmass (%f) or filter (%s)",
    145182                    exptime, airmass, expFilter);
     
    147184            return false;
    148185        }
     186        if (isfinite(zpExp->data.F32[i])) {
     187            zpExp->data.F32[i] += 2.5 * log10(exptime);
     188            zpExpNum++;
     189        }
    149190
    150191        if (!filter) {
    151192            filter = expFilter;
    152             airmassTerm = psMetadataLookupF32(NULL, airmassZP, filter);
    153             if (!isfinite(airmassTerm)) {
    154                 psError(PS_ERR_BAD_PARAMETER_VALUE, false,
     193            bool mdok;
     194            airmassTerm = psMetadataLookupF32(&mdok, airmassZP, filter);
     195            if (!mdok || !isfinite(airmassTerm)) {
     196                psError(PPSTACK_ERR_CONFIG, false,
    155197                        "Unable to find airmass term (ZP.AIRMASS) for filter %s", filter);
    156198                psFree(zp);
    157199                return false;
    158200            }
     201            zpTarget = psMetadataLookupF32(&mdok, zpTargetMenu, filter);
     202            if (!mdok || !isfinite(zpTarget)) {
     203                psError(PPSTACK_ERR_CONFIG, false,
     204                        "Unable to find target zero point (ZP.TARGET) for filter %s", filter);
     205                psFree(zp);
     206                return false;
     207            }
    159208        } else if (strcmp(filter, expFilter) != 0) {
    160             psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Filters don't match: %s vs %s", filter, expFilter);
     209            psError(PPSTACK_ERR_CONFIG, false, "Filters don't match: %s vs %s", filter, expFilter);
    161210            psFree(zp);
    162211            return false;
    163212        }
    164213
    165         zp->data.F32[i] = airmassTerm * airmass - 2.5 * log10(exptime);
    166         sumExpTime += exptime;
    167     }
    168 
    169     options->sumExposure = sumExpTime;
     214        zp->data.F32[i] = airmassTerm * airmass + 2.5 * log10(exptime);
     215    }
     216
     217    if (numGoodImages == 0) {
     218        psLogMsg("ppStack", PS_LOG_WARN, "No images with sources to measure transparency.");
     219        options->quality = PPSTACK_ERR_REJECTED;
     220        psFree(zp);
     221        psFree(zpExp);
     222        return true;
     223    }
     224    if (numGoodImages == 1) {
     225        psArray *sources = NULL;        // Sources
     226        for (int i = 0; i < num && !sources; i++) {
     227            if (options->inputMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) {
     228                continue;
     229            }
     230            sources = sourceLists->data[i];
     231        }
     232        options->quality = PPSTACK_ERR_REJECTED;
     233        options->sources = psMemIncrRefCounter(sources);
     234        options->norm = psVectorAlloc(num, PS_TYPE_F32);
     235        psVectorInit(options->norm, 1.0);
     236        options->zp = NAN;
     237        psLogMsg("ppStack", PS_LOG_WARN, "Single image with sources --- cannot match transparency.");
     238        psFree(zp);
     239        psFree(zpExp);
     240        return true;
     241    }
     242
     243    if (zpExpNum == numGoodImages) {
     244        for (int i = 0; i < num; i++) {
     245            zp->data.F32[i] = zpExp->data.F32[i];
     246        }
     247    }
    170248
    171249    psArray *matches = pmSourceMatchSources(sourceLists, radius, true); // List of matches
    172250    if (!matches) {
    173         psError(PS_ERR_UNKNOWN, false, "Unable to match sources");
     251        psError(PPSTACK_ERR_DATA, false, "Unable to match sources");
    174252        psFree(zp);
    175253        return false;
     
    180258#endif
    181259
    182     psVector *trans = pmSourceMatchRelphot(matches, zp, tol, iter1, starRej1, starSys1,
    183                                            iter2, starRej2, starSys2, starLimit,
    184                                            transIter, transRej, transThresh); // Transparencies for each image
    185     if (!trans) {
    186         psError(PS_ERR_UNKNOWN, false, "Unable to measure transparencies");
    187         return false;
    188     }
     260    if (options->matchZPs) {
     261        psVector *trans = pmSourceMatchRelphot(matches, zp, tol, iter1, starRej1, starSys1,
     262                                               iter2, starRej2, starSys2, starLimit,
     263                                               transIter, transRej, transThresh); // Transparencies per image
     264        if (!trans) {
     265            psError(PPSTACK_ERR_DATA, false, "Unable to measure transparencies");
     266            return false;
     267        }
     268        for (int i = 0; i < trans->n; i++) {
     269            if (!isfinite(trans->data.F32[i])) {
     270                inputMask->data.U8[i] |= PPSTACK_MASK_CAL;
     271            }
     272        }
     273        // M = m + c0 + c1 * airmass - 2.5log(t) + transparency
     274        // Want sources to have m corresponding to airmass = 1 and t = sumExpTime and transparency = 0
     275        // m_0 + c1 * airmass_0 + 2.5log(t_0) - trans_0 = m_1 + c1 * airmass_1 + 2.5log(t_1) - trans_1
     276        // m_0 = m_1 + zp_1 + trans_1 - c1 * airmass_0 - 2.5log(t_0)
     277        // We don't need to know the magnitude zero point for the filter, since it cancels out
     278        if (options->matchZPs) {
     279            options->norm = psVectorAlloc(num, PS_TYPE_F32);
     280            for (int i = 0; i < num; i++) {
     281                if (inputMask->data.U8[i] || !isfinite(trans->data.F32[i])) {
     282                    continue;
     283                }
     284                psArray *sources = sourceLists->data[i]; // Sources of interest
     285                float magCorr = zp->data.F32[i] + trans->data.F32[i] - 2.5*log10(options->sumExposure);
     286                if (zpExpNum == numGoodImages) {
     287                    // Using measured zero points, so attempt to set target zero point
     288                    magCorr -= zpTarget;
     289                }
     290                options->norm->data.F32[i] = -magCorr;
     291                psLogMsg("ppStack", PS_LOG_INFO,
     292                         "Applying scale correction to image %d: %f mag (%f)\n",
     293                         i, magCorr, trans->data.F32[i]);
     294
     295                for (int j = 0; j < sources->n; j++) {
     296                    pmSource *source = sources->data[j]; // Source of interest
     297                    if (!source) {
     298                        continue;
     299                    }
     300                    source->psfMag -= magCorr;
     301                }
     302            }
     303        }
     304
     305        if (zpExpNum == numGoodImages) {
     306            // Producing image with target zero point
     307            options->zp = zpTarget;
     308        } else {
     309            options->zp = NAN;
     310        }
     311
    189312
    190313#ifdef TESTING
    191     dumpMatches("source_mags.dat", num, matches, zp, trans);
    192 #endif
    193 
    194     for (int i = 0; i < trans->n; i++) {
    195         if (!isfinite(trans->data.F32[i])) {
    196             inputMask->data.U8[i] |= PPSTACK_MASK_CAL;
    197         }
    198     }
    199 
    200     // Save best matches SOMEWHERE for future photometry
    201     // XXX this is a really poor output location; clean up the pmFPAfiles used in ppStack
    202     pmCell *sourcesCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT");
    203     psArray *sourcesBest = psArrayAllocEmpty(matches->n);
    204 
    205     // XXX something of a hack: require at least 2 detections or the nominated fraction of the max possible
    206     int minMatches = PS_MAX(2, fracMatch * num);// Minimum number of matches required
    207     for (int i = 0; i < matches->n; i++) {
    208         pmSourceMatch *match = matches->data[i]; // Match of interest
    209         if (match->num < minMatches) {
    210             continue;
    211         }
    212 
    213         // We need to grab a single instance of this source: just take the first available
    214         int image = match->image->data.S32[0]; // Index of image
    215         int index = match->index->data.S32[0]; // Index of source within image
    216         psArray *sources = sourceLists->data[image]; // Sources for image
    217         pmSource *source = sources->data[index]; // Source of interest
    218 
    219         psArrayAdd(sourcesBest, sourcesBest->n, source);
    220     }
    221     psMetadataAdd(sourcesCell->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY | PS_META_REPLACE,
    222                   "psphot sources", sourcesBest);
    223     psLogMsg("ppStack", PS_LOG_INFO, "Selected %ld sources for photometry analysis", sourcesBest->n);
    224     psFree(sourcesBest);
     314        dumpMatches("source_mags.dat", num, matches, zp, trans);
     315#endif
     316        psFree(trans);
     317
     318#ifdef TESTING
     319        // Double check: all transparencies should be zero
     320        {
     321            psArray *matches = pmSourceMatchSources(sourceLists, radius, true); // List of matches
     322            if (!matches) {
     323                psError(PPSTACK_ERR_DATA, false, "Unable to match sources");
     324                psFree(zp);
     325                return false;
     326            }
     327            psVector *trans = pmSourceMatchRelphot(matches, zp, tol, iter1, starRej1, starSys1,
     328                                                   iter2, starRej2, starSys2, starLimit,
     329                                                   transIter, transRej, transThresh); // Transparencies
     330            for (int i = 0; i < num; i++) {
     331                fprintf(stderr, "Transparency of image %d: %f\n", i, trans->data.F32[i]);
     332            }
     333            psFree(trans);
     334            psFree(matches);
     335        }
     336#endif
     337    }
     338
     339    psFree(zp);
     340    psFree(zpExp);
     341
     342#ifdef ASTROMETRY
     343    // Position offsets
     344    {
     345        psArray *offsets = pmSourceMatchRelastro(matches, num, tol, iter1, starRej1,
     346                                                  iter2, starRej2, starLimit); // Shifts for each image
     347        if (!offsets) {
     348            psError(PPSTACK_ERR_DATA, false, "Unable to measure offsets");
     349            return false;
     350        }
     351        for (int i = 0; i < num; i++) {
     352            if (options->inputMask->data.U8[i]) {
     353                continue;
     354            }
     355            psArray *sources = sourceLists->data[i]; // Sources of interest
     356            psVector *offset = offsets->data[i];                      // Offsets for image
     357            float dx = offset->data.F32[0], dy = offset->data.F32[1]; // Offsets to apply
     358            if (!isfinite(dx) || !isfinite(dy)) {
     359                continue;
     360            }
     361            psLogMsg("ppStack", PS_LOG_INFO, "Applying astrometric correction to image %d: %f,%f\n",
     362                     i, dx, dy);
     363            for (int j = 0; j < sources->n; j++) {
     364                pmSource *source = sources->data[j]; // Source of interest
     365                if (!source) {
     366                    continue;
     367                }
     368                if (source->modelPSF) {
     369                    source->modelPSF->params->data.F32[PM_PAR_XPOS] -= dx;
     370                    source->modelPSF->params->data.F32[PM_PAR_YPOS] -= dy;
     371                }
     372                if (source->peak) {
     373                    source->peak->xf -= dx;
     374                    source->peak->yf -= dy;
     375                }
     376            }
     377        }
     378        psFree(offsets);
     379    }
     380#endif
     381
     382#if (defined TESTING && defined ASTROMETRY)
     383        // Double check: all offsets should be zero
     384        {
     385            psArray *matches = pmSourceMatchSources(sourceLists, radius, true); // List of matches
     386            if (!matches) {
     387                psError(PPSTACK_ERR_DATA, false, "Unable to match sources");
     388                psFree(zp);
     389                return false;
     390            }
     391            psArray *offsets = pmSourceMatchRelastro(matches, num, tol, iter1, starRej1,
     392                                                     iter2, starRej2, starLimit); // Shifts for each image
     393            for (int i = 0; i < num; i++) {
     394                psVector *offset = offsets->data[i]; // Offsets for image
     395                fprintf(stderr, "Offset of image %d: %f,%f\n", i, offset->data.F32[0], offset->data.F32[1]);
     396            }
     397            psFree(offsets);
     398            psFree(matches);
     399        }
     400#endif
     401
     402
     403    if (options->photometry) {
     404        // Save best matches for future photometry
     405        psArray *sourcesBest = options->sources = psArrayAllocEmpty(matches->n);
     406
     407        // XXX something of a hack: require at least 2 detections or the nominated fraction of the max possible
     408        int minMatches = PS_MAX(2, fracMatch * num);// Minimum number of matches required
     409        for (int i = 0; i < matches->n; i++) {
     410            pmSourceMatch *match = matches->data[i]; // Match of interest
     411            if (match->num < minMatches) {
     412                continue;
     413            }
     414
     415            // We need to grab a single instance of this source: just take the first available
     416            int image = match->image->data.S32[0]; // Index of image
     417            int index = match->index->data.S32[0]; // Index of source within image
     418            psArray *sources = sourceLists->data[image]; // Sources for image
     419            pmSource *source = sources->data[index]; // Source of interest
     420
     421            psArrayAdd(sourcesBest, sourcesBest->n, source);
     422        }
     423        psLogMsg("ppStack", PS_LOG_INFO, "Selected %ld sources for photometry analysis", sourcesBest->n);
     424    }
    225425
    226426    psFree(matches);
    227 
    228     // M = m + c0 + c1 * airmass - 2.5log(t) + transparency
    229     // Want sources to have m corresponding to airmass = 1 and t = sumExpTime and transparency = 0
    230     // m_0 + c1 * airmass_0 + 2.5log(t_0) - trans_0 = m_1 + c1 * airmass_1 + 2.5log(t_1) - trans_1
    231     // m_0 = m_1 + zp_1 + trans_1 - c1 * airmass_0 - 2.5log(t_0)
    232     // We don't need to know the magnitude zero point for the filter, since it cancels out
    233     options->norm = psVectorAlloc(num, PS_TYPE_F32);
    234     for (int i = 0; i < num; i++) {
    235         if (!isfinite(trans->data.F32[i])) {
    236             continue;
    237         }
    238         psArray *sources = sourceLists->data[i]; // Sources of interest
    239         float magCorr = airmassTerm - 2.5*log10(sumExpTime) - zp->data.F32[i] - trans->data.F32[i];
    240         options->norm->data.F32[i] = magCorr;
    241         psLogMsg("ppStack", PS_LOG_INFO, "Applying magnitude correction to image %d: %f\n", i, magCorr);
    242 
    243         for (int j = 0; j < sources->n; j++) {
    244             pmSource *source = sources->data[j]; // Source of interest
    245             if (!source) {
    246                 continue;
    247             }
    248             source->psfMag += magCorr;
    249         }
    250     }
    251     psFree(trans);
    252 
    253 #ifdef TESTING
    254     // Double check: all transparencies should be zero
    255     {
    256         psArray *matches = pmSourceMatchSources(sourceLists, radius); // List of matches
    257         if (!matches) {
    258             psError(PS_ERR_UNKNOWN, false, "Unable to match sources");
    259             psFree(zp);
    260             return false;
    261         }
    262         psVector *trans = pmSourceMatchRelphot(matches, zp, iter, tol, starLimit, transIter, transRej,
    263                                                transThresh, starRej, starSys);
    264         for (int i = 0; i < num; i++) {
    265             fprintf(stderr, "Transparency of image %d: %f\n", i, trans->data.F32[i]);
    266         }
    267         psFree(trans);
    268     }
    269 #endif
    270427
    271428    return true;
Note: See TracChangeset for help on using the changeset viewer.