IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 11, 2016, 2:33:18 PM (10 years ago)
Author:
eugene
Message:

add skips for chips without a valid solution (do not just crash); add recipe value for PSASTRO.MODEL.REF.CHIP.ANGLE, the position angle expected for the reference chip for an exposure with PA = 0.0; posAngle needs to be adjusted to match reference chip target value; if the projection is not TAN or DIS when attempting bilevel mosaic fitting, re-fit the projection + distortion to be TAN + distortion

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/czw_branch/20160809/psastro/src/psastroMosaicAstrom.c

    r27558 r39686  
    1515
    1616bool psastroMosaicFit (pmFPA *fpa, psMetadata *recipe, const char *rootname, int pass);
     17bool psastroProjectionRefit (pmFPA *fpa, psMetadata *recipe);
    1718
    1819// XXX require this fpa to have multiple chip extensions and a PHU?
     
    4243    int nIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER");
    4344    if (!status) psAbort ("missing config value");
     45
     46    // XXX if projection is not TAN, fit the measured projection here and combine toTPA/fromTPA functions
     47    if ((fpa->toSky->type != PS_PROJ_TAN) && (fpa->toSky->type != PS_PROJ_DIS)) {
     48      if (!psastroProjectionRefit (fpa, recipe)) psAbort ("failed to refit distortion");
     49    }
    4450
    4551    // this should be in a loop with nIter =
     
    154160    return true;
    155161}
     162
     163// we have a fpa->toSky projection which is NOT of type TAN along with a toTPA which is
     164// the Identity transform.  we want to convert this to TAN projection plus a non-identity
     165// transformation to take the non-TAN components.
     166
     167// we are going to generate a set of FP->(x,y) using the current projection + fromTPA
     168// transformations along with a set of TP->(x,y) values using the desired TAN projection,
     169// then we will fit TP vs FP
     170
     171bool psastroProjectionRefit (pmFPA *fpa, psMetadata *recipe) {
     172
     173  bool status;
     174
     175    // allocate mosaic-level polynomial transformation and set masks needed by DVO
     176    int order = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.ORDER");
     177    if (!status) {
     178        psError(PSASTRO_ERR_UNKNOWN, false, "failed to find mosaic distortion fit order\n");
     179        return false;
     180    }
     181
     182    pmChip *chip = NULL;
     183    pmCell *cell = NULL;
     184    pmReadout *readout = NULL;
     185    pmFPAview *view = pmFPAviewAlloc (0);
     186
     187    psVector *L = psVectorAllocEmpty (1000, PS_TYPE_F32);
     188    psVector *M = psVectorAllocEmpty (1000, PS_TYPE_F32);
     189
     190    psVector *P = psVectorAllocEmpty (1000, PS_TYPE_F32);
     191    psVector *Q = psVectorAllocEmpty (1000, PS_TYPE_F32);
     192
     193    psProjection *toSkyTan = psProjectionAlloc (fpa->toSky->R, fpa->toSky->D, fpa->toSky->Xs, fpa->toSky->Ys, PS_PROJ_TAN);
     194
     195    float xMin = NAN;
     196    float xMax = NAN;
     197    float yMin = NAN;
     198    float yMax = NAN;
     199
     200    bool firstObject = true;
     201
     202    // this loop selects the matched stars for all chips
     203    while ((chip = pmFPAviewNextChip (view, fpa, 1)) != NULL) {
     204        psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
     205        if (!chip->process || !chip->file_exists) continue;
     206       
     207        while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {
     208            psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
     209            if (!cell->process || !cell->file_exists) continue;
     210
     211            // process each of the readouts
     212            // XXX there can only be one readout per chip, right?
     213            while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {
     214                if (! readout->data_exists) continue;
     215
     216                // select the raw objects for this readout
     217                psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS.SUBSET");
     218                if (refstars == NULL) continue;
     219                psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n);
     220
     221                psArray *matches = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.MATCH");
     222                if (matches == NULL) continue;
     223
     224                // we are looking over the matched refstars only to be sure we are
     225                // covering the valid space of the projection + transformation, and not
     226                // beyond
     227
     228                for (int i = 0; i < matches->n; i++) {
     229                    pmAstromMatch *match = matches->data[i];
     230                    pmAstromObj *ref = refstars->data[match->ref];
     231
     232                    psPlane fpOld, tpNew, tpOld;
     233
     234                    psProject (&tpOld, ref->sky, fpa->toSky); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
     235                    psPlaneTransformApply (&fpOld, fpa->fromTPA, &tpOld);
     236
     237                    psProject (&tpNew, ref->sky, toSkyTan); // find the focal-plane coord of this RA,DEC coord using the ref chip projection
     238
     239                    psVectorAppend (L, fpOld.x);
     240                    psVectorAppend (M, fpOld.y);
     241
     242                    psVectorAppend (P, tpNew.x);
     243                    psVectorAppend (Q, tpNew.y);
     244
     245                    if (firstObject) {
     246                      xMin = xMax = fpOld.x;
     247                      yMin = yMax = fpOld.y;
     248                      firstObject = false;
     249                    }
     250
     251                    xMin = PS_MIN (xMin, fpOld.x);
     252                    xMax = PS_MAX (xMax, fpOld.x);
     253                    yMin = PS_MIN (yMin, fpOld.y);
     254                    yMax = PS_MAX (yMax, fpOld.y);
     255                }
     256            }
     257        }
     258    }
     259
     260    // the original transforms are (1, 1), but we will need higher order to fit the distortions
     261    psFree (fpa->toTPA);
     262
     263    // the original transforms are (1, 1), but we will need higher order to fit the distortions
     264    fpa->toTPA = psPlaneTransformAlloc (order, order);
     265    for (int i = 0; i <= fpa->toTPA->x->nX; i++) {
     266        for (int j = 0; j <= fpa->toTPA->x->nY; j++) {
     267            if (i + j > order) {
     268                fpa->toTPA->x->coeffMask[i][j] = PS_POLY_MASK_SET;
     269                fpa->toTPA->y->coeffMask[i][j] = PS_POLY_MASK_SET;
     270            }
     271        }
     272    }
     273
     274    psVectorFitPolynomial2D (fpa->toTPA->x, NULL, 0, P, NULL, L, M);
     275    psVectorFitPolynomial2D (fpa->toTPA->y, NULL, 0, Q, NULL, L, M);
     276   
     277    psRegion fitRegion = psRegionSet (xMin, xMax, yMin, yMax);
     278
     279    // psPlaneTransformInvert will generate a new fromTPA with order to match toTPA
     280    fpa->fromTPA = psPlaneTransformInvert (fpa->fromTPA, fpa->toTPA, fitRegion, 100);
     281
     282    psFree (fpa->toSky);
     283    fpa->toSky = toSkyTan;
     284
     285    psFree (L);
     286    psFree (M);
     287    psFree (P);
     288    psFree (Q);
     289
     290    psFree (view);
     291    return true;
     292}
     293
Note: See TracChangeset for help on using the changeset viewer.