IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 16077


Ignore:
Timestamp:
Jan 14, 2008, 4:56:48 PM (18 years ago)
Author:
eugene
Message:

substantial rework: calculate the average rotation and offset, apply to the TPA

File:
1 edited

Legend:

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

    r15891 r16077  
    4949  }
    5050
    51   // loop over all chips, replace input astrometry elements with those from astrom
     51  // we now have a set of chip solutions and a set of prediction measure the overall
     52  // offset and rotation of the two systems by comparing the chip corners, projected onto
     53  // the focal plane (all 4 to prevent solutions tied to a single corner)
     54
     55  psVector *xObs = psVectorAllocEmpty (4*input->fpa->chips->n, PS_TYPE_F32);
     56  psVector *yObs = psVectorAllocEmpty (4*input->fpa->chips->n, PS_TYPE_F32);
     57  psVector *xRef = psVectorAllocEmpty (4*input->fpa->chips->n, PS_TYPE_F32);
     58  psVector *yRef = psVectorAllocEmpty (4*input->fpa->chips->n, PS_TYPE_F32);
     59
     60  int nPts = 0;
     61
    5262  pmChip *obsChip = NULL;
     63  while ((obsChip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
     64      if (!obsChip->process || !obsChip->file_exists || !obsChip->data_exists) { continue; }
     65
     66      // set the chip astrometry using the astrom file
     67      pmChip *refChip = pmFPAviewThisChip (view, astrom->fpa);
     68
     69      psRegion *region = pmChipPixels (obsChip);
     70      psPlane ptCP, ptFP;
     71
     72      ptCP.x = region->x0; ptCP.y = region->y0;
     73      psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
     74      xObs->data.F32[nPts] = ptFP.x;
     75      yObs->data.F32[nPts] = ptFP.y;
     76      psPlaneTransformApply (&ptFP, refChip->toFPA, &ptCP);
     77      xRef->data.F32[nPts] = ptFP.x;
     78      yRef->data.F32[nPts] = ptFP.y;
     79      nPts ++;
     80
     81      ptCP.x = region->x0; ptCP.y = region->y1;
     82      psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
     83      xObs->data.F32[nPts] = ptFP.x;
     84      yObs->data.F32[nPts] = ptFP.y;
     85      psPlaneTransformApply (&ptFP, refChip->toFPA, &ptCP);
     86      xRef->data.F32[nPts] = ptFP.x;
     87      yRef->data.F32[nPts] = ptFP.y;
     88      nPts ++;
     89
     90      ptCP.x = region->x1; ptCP.y = region->y1;
     91      psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
     92      xObs->data.F32[nPts] = ptFP.x;
     93      yObs->data.F32[nPts] = ptFP.y;
     94      psPlaneTransformApply (&ptFP, refChip->toFPA, &ptCP);
     95      xRef->data.F32[nPts] = ptFP.x;
     96      yRef->data.F32[nPts] = ptFP.y;
     97      nPts ++;
     98
     99      ptCP.x = region->x1; ptCP.y = region->y0;
     100      psPlaneTransformApply (&ptFP, obsChip->toFPA, &ptCP);
     101      xObs->data.F32[nPts] = ptFP.x;
     102      yObs->data.F32[nPts] = ptFP.y;
     103      psPlaneTransformApply (&ptFP, refChip->toFPA, &ptCP);
     104      xRef->data.F32[nPts] = ptFP.x;
     105      yRef->data.F32[nPts] = ptFP.y;
     106      nPts ++;
     107
     108      psFree (region);
     109  }
     110  xObs->n = yObs->n = xRef->n = yRef->n = nPts;
     111       
     112  psPlaneTransform *map = psPlaneTransformAlloc (1, 1);
     113 
     114  psVector *mask = psVectorAlloc (nPts, PS_TYPE_U8);
     115  psVectorInit (mask, 0);
     116
     117  psStats *stats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
     118  stats->clipIter = 1;
     119
     120  for (int i = 0; i < 3; i++) {
     121      psVectorClipFitPolynomial2D (map->x, stats, mask, 0xff, xObs, NULL, xRef, yRef);
     122      psTrace ("psModules.astrom", 3, "x resid: %f +/- %f (%ld of %ld)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues, xObs->n);
     123
     124      psVectorClipFitPolynomial2D (map->y, stats, mask, 0xff, yObs, NULL, xRef, yRef);
     125      psTrace ("psModules.astrom", 3, "x resid: %f +/- %f (%ld of %ld)\n", stats->clippedMean, stats->clippedStdev, stats->clippedNvalues, yObs->n);
     126  }
     127
     128  // loop over all chips, select the outliers, and replace the measured astrometry with the model
     129  // the measured transformation above must be applied to make the comparison, and also then applied to the
     130  // model transformation
     131
     132  psFree (xObs);
     133  psFree (yObs);
     134  psFree (xRef);
     135  psFree (yRef);
     136  psFree (mask);
     137  psFree (stats);
     138
     139  psFree (view);
     140  view = pmFPAviewAlloc (0);
     141
    53142  while ((obsChip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
    54143    psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, obsChip->file_exists, obsChip->process);
     
    61150
    62151    psPlane refPixel = {0.0, 0.0, 0.0, 0.0};
    63     psPlane obsCoord, refCoord;
     152    psPlane obsCoord, refCoord, tmpCoord;
    64153
    65154    // find location of 0,0 pixel in focal plane coords for this chip
     
    67156
    68157    // find location of 0,0 pixel in focal plane coords for ref chip
    69     psPlaneTransformApply (&refCoord, refChip->toFPA, &refPixel);
     158    // apply the global field rotation and offset before comparing
     159    psPlaneTransformApply (&tmpCoord, refChip->toFPA, &refPixel);
     160    psPlaneTransformApply (&refCoord, map, &tmpCoord);
    70161   
    71     psPlane offPixel = {0.0, 0.0, 0.0, 0.0};
     162    psPlane offPixel = {100.0, 0.0, 100.0, 0.0};
    72163    psPlane obsOffPt, refOffPt;
    73164
     
    76167
    77168    // find location of 0,0 pixel in focal plane coords for ref chip
    78     psPlaneTransformApply (&refOffPt, refChip->toFPA, &offPixel);
     169    psPlaneTransformApply (&tmpCoord, refChip->toFPA, &offPixel);
     170    psPlaneTransformApply (&refOffPt, map, &tmpCoord);
    79171   
    80     double obsAngle = atan2 (obsOffPt.y - obsCoord.y, obsOffPt.x - obsCoord.x);
    81     double refAngle = atan2 (refOffPt.y - refCoord.y, refOffPt.x - refCoord.x);
     172    double obsAngle = PM_DEG_RAD*atan2 (obsOffPt.y - obsCoord.y, obsOffPt.x - obsCoord.x);
     173    double refAngle = PM_DEG_RAD*atan2 (refOffPt.y - refCoord.y, refOffPt.x - refCoord.x);
    82174
    83175    bool badAstrom = false;
     
    86178    badAstrom |= fabs(obsAngle   - refAngle)   > angleTol;
    87179
     180    fprintf (stderr, "chip %d, angle: %f, pixel: %f,%f\n", view->chip, obsAngle - refAngle, obsCoord.x - refCoord.x, obsCoord.y - refCoord.y);
     181
    88182    if (!badAstrom) continue;
     183
     184    psLogMsg ("psastro", PS_LOG_INFO, "fixing chip %d, angle: %f, pixel: %f,%f\n",
     185              view->chip, obsAngle - refAngle, obsCoord.x - refCoord.x, obsCoord.y - refCoord.y);
    89186
    90187    psFree (obsChip->toFPA);
    91188    psFree (obsChip->fromFPA);
    92189
    93     // supply astrometry from model
    94     obsChip->toFPA   = psMemIncrRefCounter (refChip->toFPA);
    95     obsChip->fromFPA = psMemIncrRefCounter (refChip->fromFPA);
    96   }
    97 
    98   psFree (input->fpa->toSky);
    99   psFree (input->fpa->toTPA);
    100   psFree (input->fpa->fromTPA);
    101   input->fpa->toSky   = psMemIncrRefCounter (astrom->fpa->toSky);
    102   input->fpa->toTPA   = psMemIncrRefCounter (astrom->fpa->toTPA);
    103   input->fpa->fromTPA = psMemIncrRefCounter (astrom->fpa->fromTPA);
    104 
    105   psMetadata *updates = psMetadataAlloc();
    106   pmAstromWriteBilevelMosaic (updates, input->fpa, NONLIN_TOL);
    107   psMetadataAddMetadata (input->fpa->analysis, PS_LIST_TAIL, "PSASTRO.HEADER",  PS_META_REPLACE, "psastro header stats", updates);
    108   psFree (updates);
    109 
     190    // apply the exiting fromTPA transformation to make the new toFPA consistent with the toTPA layter
     191    // XXX this only works if toTPA is at most a linear transformation
     192    psPlaneTransform *toFPA = psPlaneTransformAlloc(refChip->toFPA->x->nX, refChip->toFPA->x->nY);
     193    for (int i = 0; i <= refChip->toFPA->x->nX; i++) {
     194        for (int j = 0; j <= refChip->toFPA->x->nY; j++) {
     195            double f1 = refChip->toFPA->x->coeffMask[i][j] ? 0.0 : map->x->coeff[1][0]*refChip->toFPA->x->coeff[i][j];
     196            double f2 = refChip->toFPA->y->coeffMask[i][j] ? 0.0 : map->x->coeff[0][1]*refChip->toFPA->y->coeff[i][j];
     197            toFPA->x->coeff[i][j] = f1 + f2;
     198
     199            double g1 = refChip->toFPA->x->coeffMask[i][j] ? 0.0 : map->y->coeff[1][0]*refChip->toFPA->x->coeff[i][j];
     200            double g2 = refChip->toFPA->y->coeffMask[i][j] ? 0.0 : map->y->coeff[0][1]*refChip->toFPA->y->coeff[i][j];
     201            toFPA->y->coeff[i][j] = g1 + g2;
     202        }
     203    }
     204    toFPA->x->coeff[0][0] += map->x->coeff[0][0];
     205    toFPA->y->coeff[0][0] += map->y->coeff[0][0];
     206
     207    psRegion *region = pmChipPixels (obsChip);
     208    obsChip->toFPA   = toFPA;
     209    obsChip->fromFPA = psPlaneTransformInvert(NULL, obsChip->toFPA, *region, 50);
     210    psFree (region);
     211   
     212    // XXX this stuff below should be applied to each readout...
     213    // XXX for now, just use first readout
     214    pmCell *cell = obsChip->cells->data[0];
     215    pmReadout *readout = cell->readouts->data[0];
     216
     217    // use the new position to re-try the match fit
     218    // select the raw objects for this readout
     219    psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS");
     220    if (rawstars == NULL) { continue; }
     221
     222    // select the raw objects for this readout
     223    psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS");
     224    if (refstars == NULL) { continue; }
     225
     226    // the absolute minimum number of stars is 4 (for order = 1)
     227    if ((rawstars->n < 4) || (refstars->n < 4)) {
     228        readout->data_exists = false;
     229        psLogMsg ("psastro", 3, "insufficient rawstars (%ld) or refstars (%ld)",
     230                  rawstars->n, refstars->n);
     231        continue;
     232    }
     233
     234    psastroUpdateChipToFPA (input->fpa, obsChip, rawstars, refstars);
     235
     236    // update the header
     237    psMetadata *updates = psMemIncrRefCounter (psMetadataLookupMetadata (&status, readout->analysis, "PSASTRO.HEADER"));
     238    if (!updates) {
     239        updates = psMetadataAlloc ();
     240    }
     241
     242    // XXX update the header with info to reflect the failure
     243    if (!psastroOneChipFit (input->fpa, obsChip, refstars, rawstars, recipe, updates)) {
     244        readout->data_exists = false;
     245        psLogMsg ("psastro", 3, "failed to find a solution\n");
     246        psFree (updates);
     247        continue;
     248    }
     249
     250    pmAstromWriteWCS (updates, input->fpa, obsChip, NONLIN_TOL);
     251    psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSASTRO.HEADER",  PS_META_REPLACE | PS_DATA_METADATA, "psastro header stats", updates);
     252    psFree (updates);
     253  }
     254
     255  psFree (map);
    110256  psFree (view);
    111257  return true;
Note: See TracChangeset for help on using the changeset viewer.