IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 3, 2007, 4:32:39 PM (19 years ago)
Author:
eugene
Message:

iterate on the match as well as the fit, added user-set radii for iterations

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psastro/src/psastroOneChip.c

    r13165 r15201  
    11# include "psastroInternal.h"
    22
    3 # define REQUIRED_RECIPE_VALUE(VALUE, NAME, TYPE, MESSAGE)\
     3# define REQUIRED_RECIPE_VALUE(VALUE, NAME, TYPE)\
    44  VALUE = psMetadataLookup##TYPE (&status, recipe, NAME); \
    55  if (!status) { \
    6    psError(PSASTRO_ERR_CONFIG, false, MESSAGE); \
    7    return false; }
     6   psAbort ("Failed to find %s in recipe", NAME); }
    87
    98bool psastroOneChip (pmFPA *fpa, pmChip *chip, psArray *refstars, psArray *rawstars, psMetadata *recipe, psMetadata *updates) {
    109
    1110    bool status;
    12     pmAstromStats *gridStats = NULL;
    1311    pmAstromStats *stats = NULL;
    1412
    15     // supplied radius is in pixels
    16     REQUIRED_RECIPE_VALUE (double RADIUS, "PSASTRO.MATCH.RADIUS", F32, "Failed to lookup matching radius");
     13    // default value for match/fit : radius is in pixels
     14    REQUIRED_RECIPE_VALUE (double RADIUS, "PSASTRO.MATCH.RADIUS", F32);
     15
     16    // run the match/fit sequence NITER times
     17    REQUIRED_RECIPE_VALUE (int nIter, "PSASTRO.MATCH.FIT.NITER", S32);
    1718
    1819    // correct radius to FP units (physical pixel scale in microns per pixel)
    19     REQUIRED_RECIPE_VALUE (double pixelScale, "PSASTRO.PIXEL.SCALE", F32, "Failed to lookup pixel scale");
     20    REQUIRED_RECIPE_VALUE (double pixelScale, "PSASTRO.PIXEL.SCALE", F32);
    2021    RADIUS *= pixelScale;
    2122
    2223    // select the desired chip order
    23     REQUIRED_RECIPE_VALUE (int order, "PSASTRO.CHIP.ORDER", S32, "failed to find single-chip fit order\n");
     24    REQUIRED_RECIPE_VALUE (int order, "PSASTRO.CHIP.ORDER", S32);
    2425
    2526    // allowed limits for valid solutions
    26     REQUIRED_RECIPE_VALUE (float maxError, "PSASTRO.MAX.ERROR", F32, "failed to find single-chip max allowed error\n");
    27     REQUIRED_RECIPE_VALUE (int minNstar, "PSASTRO.MIN.NSTAR", S32, "failed to find single-chip min allowed stars\n");
     27    REQUIRED_RECIPE_VALUE (float maxError, "PSASTRO.MAX.ERROR", F32);
     28    REQUIRED_RECIPE_VALUE (int minNstar, "PSASTRO.MIN.NSTAR", S32);
    2829
    2930    // do we need to get a rough initial match?
    30     REQUIRED_RECIPE_VALUE (bool gridSearch, "PSASTRO.GRID.SEARCH", Bool, "failed to find chip grid-search option\n");
     31    REQUIRED_RECIPE_VALUE (bool gridSearch, "PSASTRO.GRID.SEARCH", Bool);
     32
     33    // do we need to get a rough initial match?
     34    REQUIRED_RECIPE_VALUE (int maxNstar, "PSASTRO.GRID.NSTAR.MAX", S32);
    3135
    3236    if (gridSearch) {
     37        // generate the bright subset of maxNstar entries (note: rawstars is sorted by S/N)
     38        psArray *gridStars = psArrayAlloc (PS_MIN (maxNstar, rawstars->n));
     39        for (int i = 0; (i < maxNstar) && (i < rawstars->n); i++) {
     40            gridStars->data[i] = psMemIncrRefCounter (rawstars->data[i]);
     41        }
     42
    3343        // find initial offset / rotation
    34         gridStats = pmAstromGridMatch (rawstars, refstars, recipe);
     44        pmAstromStats *gridStats = pmAstromGridMatch (gridStars, refstars, recipe);
    3545        if (gridStats == NULL) {
    3646            psLogMsg ("psastro", 3, "failed to find a grid match solution\n");
     47            psFree (gridStars);
    3748            return false;
    3849        }
     
    4051
    4152        // tweak the position by finding peak of matches stars
    42         stats = pmAstromGridTweak (rawstars, refstars, recipe, gridStats);
     53        stats = pmAstromGridTweak (gridStars, refstars, recipe, gridStats);
    4354        if (stats == NULL) {
    4455            psLogMsg ("psastro", 3, "failed to measure tweaked grid solution\n");
    4556            psFree (gridStats);
     57            psFree (gridStars);
    4658            return false;
    4759        }
     
    5163        pmAstromGridApply (chip->toFPA, stats);
    5264        psastroUpdateChipToFPA (fpa, chip, rawstars, refstars);
    53     }
    54 
    55     // use small radius to match stars
    56     psArray *match = pmAstromRadiusMatchFP (rawstars, refstars, RADIUS);
    57     if (match == NULL) {
    58         psLogMsg ("psastro", 3, "failed to find radius-matched sources\n");
    59         psFree (stats);
    6065        psFree (gridStats);
    61         return false;
    62     }
    63 
    64     // modify the order to correspond to the actual number of matched stars:
    65     if ((match->n < 11) && (order >= 3)) order = 2;
    66     if ((match->n <  7) && (order >= 2)) order = 1;
    67     if ((match->n <  4) && (order >= 1)) order = 0;
    68     if (order < 1) {
    69         psLogMsg ("psastro", 3, "insufficient stars or invalid order: %ld stars", match->n);
    70         psFree (match);
    71         psFree (stats);
    72         psFree (gridStats);
    73         return false;
    74     }
    75 
    76     // create output toFPA; set masks appropriate to the Elixir DVO astrometry format
    77     psFree (chip->toFPA);
    78     chip->toFPA = psPlaneTransformAlloc (order, order);
    79     for (int i = 0; i <= chip->toFPA->x->nX; i++) {
    80         for (int j = 0; j <= chip->toFPA->x->nY; j++) {
    81             if (i + j > order) {
    82                 chip->toFPA->x->mask[i][j] = 1;
    83                 chip->toFPA->y->mask[i][j] = 1;
    84             }
    85         }
    86     }
    87 
    88     // XXX allow statitic to be set by the user
    89     psStats *fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
    90     // psStats *fitStats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
    91     fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.CHIP.NSIGMA");
    92     fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.CHIP.NITER");
    93 
    94     // improved fit for astrometric terms
    95     pmAstromFitResults *results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats);
    96     if (!results) {
    97         psLogMsg ("psastro", 3, "failed to perform the matched fit\n");
    98         psFree (match);
    99         psFree (stats);
    100         psFree (fitStats);
    101         psFree (gridStats);
    102         return false;
    103     }
     66        psFree (gridStars);
     67    }
     68
     69    psArray *match = NULL;
     70    psStats *fitStats = NULL;
     71    pmAstromFitResults *results = NULL;
     72
     73    for (int iter = 0; iter < nIter; iter++) {
     74       
     75        char name[128];
     76
     77        sprintf (name, "PSASTRO.MATCH.RADIUS.N%d", iter);
     78        float radius = psMetadataLookupF32 (&status, recipe, name);
     79        radius *= pixelScale;
     80        if (!status || (radius == 0.0)) {
     81            radius = RADIUS;
     82        }
     83
     84
     85        // use small radius to match stars
     86        match = pmAstromRadiusMatchFP (rawstars, refstars, radius);
     87        if (match == NULL) {
     88            psLogMsg ("psastro", 3, "failed to find radius-matched sources\n");
     89            psFree (stats);
     90            return false;
     91        }
     92
     93        // modify the order to correspond to the actual number of matched stars:
     94        if ((match->n < 11) && (order >= 3)) order = 2;
     95        if ((match->n <  7) && (order >= 2)) order = 1;
     96        if ((match->n <  4) && (order >= 1)) order = 0;
     97        if (order < 1) {
     98            psLogMsg ("psastro", 3, "insufficient stars or invalid order: %ld stars", match->n);
     99            psFree (match);
     100            psFree (stats);
     101            return false;
     102        }
     103
     104        // create output toFPA; set masks appropriate to the Elixir DVO astrometry format
     105        psFree (chip->toFPA);
     106        chip->toFPA = psPlaneTransformAlloc (order, order);
     107        for (int i = 0; i <= chip->toFPA->x->nX; i++) {
     108            for (int j = 0; j <= chip->toFPA->x->nY; j++) {
     109                if (i + j > order) {
     110                    chip->toFPA->x->mask[i][j] = 1;
     111                    chip->toFPA->y->mask[i][j] = 1;
     112                }
     113            }
     114        }
     115
     116        // XXX allow statitic to be set by the user
     117        // fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
     118        fitStats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     119        fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.CHIP.NSIGMA");
     120        fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.CHIP.NITER");
     121
     122        // improved fit for astrometric terms
     123        results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats);
     124        if (!results) {
     125            psLogMsg ("psastro", 3, "failed to perform the matched fit\n");
     126            psFree (match);
     127            psFree (stats);
     128            psFree (fitStats);
     129            return false;
     130        }
    104131   
     132        // determine fromFPA transformation and apply new transformation to raw & ref stars
     133        psastroUpdateChipToFPA (fpa, chip, rawstars, refstars);
     134   
     135        if (iter < nIter - 1) {
     136            psFree (fitStats);
     137            psFree (results);
     138            psFree (match);
     139        }
     140
     141        // toSky converts from FPA & TPA units (microns) to sky units (radians)
     142        float plateScale = 0.5*(fpa->toSky->Xs + fpa->toSky->Ys)*3600.0*PM_DEG_RAD;
     143        // float astError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) * plateScale;
     144        float astError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) * plateScale;
     145        int astNstar = results->yStats->clippedNvalues;
     146        psLogMsg ("psastro", PS_LOG_INFO, "pass %d, error: %f arcsec, Nstars: %d", iter, astError, astNstar);
     147    }
     148
     149
     150
    105151    // toSky converts from FPA & TPA units (microns) to sky units (radians)
    106152    float plateScale = 0.5*(fpa->toSky->Xs + fpa->toSky->Ys)*3600.0*PM_DEG_RAD;
    107153
    108154    // pixError is the average 1D scatter in pixels ('results' are in FPA units = microns)
    109     float pixError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) / pixelScale;
    110     // float pixError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) / pixelScale;
     155    // float pixError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) / pixelScale;
     156    float pixError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) / pixelScale;
    111157
    112158    // astError is the average 1D scatter in arcsec ('results' are in FPA units = microns)
    113     float astError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) * plateScale;
    114     // float astError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) * plateScale;
     159    // float astError = 0.5*(results->xStats->clippedStdev + results->yStats->clippedStdev) * plateScale;
     160    float astError = 0.5*(results->xStats->robustStdev + results->yStats->robustStdev) * plateScale;
    115161    int astNstar = results->yStats->clippedNvalues;
    116162
     
    140186    psMetadataAddF32 (updates, PS_LIST_TAIL, "EQUINOX",  PS_META_REPLACE, "equinox of ref catalog", 2000.0); // XXX this is bogus: should be defined based on equinox of refstars
    141187
    142     // determine fromFPA transformation and apply new transformation to raw & ref stars
    143     psastroUpdateChipToFPA (fpa, chip, rawstars, refstars);
     188    // XXX drop from here : determine fromFPA transformation and apply new transformation to raw & ref stars
     189    // psastroUpdateChipToFPA (fpa, chip, rawstars, refstars);
    144190   
    145191    // XXX check if we correctly applied the new transformation:
    146192    if (psTraceGetLevel("psastro.dump") > 0) {
    147193        psastroDumpRawstars (rawstars, fpa, chip);
    148     }
    149     if (psTraceGetLevel("psastro.dump") > 0) {
     194        psastroDumpMatchedStars ("match.dat", rawstars, refstars, match);
    150195        psastroDumpStars (refstars, "refstars.cal.dat");
    151196    }
    152197
    153198    if (psTraceGetLevel("psastro.plot") > 0) {
    154         psastroPlotOneChipFit (rawstars, refstars, match, results);
     199        psastroPlotOneChipFit (rawstars, refstars, match, recipe);
    155200    }
    156201
     
    159204    psFree (results);
    160205    psFree (fitStats);
    161     psFree (gridStats);
    162206    return validSolution;
    163207}
Note: See TracChangeset for help on using the changeset viewer.