IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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

updates from trunk

Location:
branches/simmosaic_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simmosaic_branches

  • branches/simmosaic_branches/psModules

  • branches/simmosaic_branches/psModules/src/objects/pmSourceIO_CMF_PS1_V2.c

    r24403 r27839  
    4545// followed by a zero-size matrix, followed by the table data
    4646
    47 bool pmSourcesWrite_CMF_PS1_V2 (psFits *fits, pmReadout *readout, psArray *sources,
    48                                 psMetadata *imageHeader, psMetadata *tableHeader, char *extname)
     47bool pmSourcesWrite_CMF_PS1_V2 (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, psMetadata *tableHeader, char *extname)
    4948{
    5049    PS_ASSERT_PTR_NON_NULL(fits, false);
     
    5453    psArray *table;
    5554    psMetadata *row;
    56     int i;
    5755    psF32 *PAR, *dPAR;
    5856    psEllipseAxes axes;
     
    6967    float magOffset = NAN;
    7068    float exptime   = psMetadataLookupF32 (&status1, fpa->concepts, "FPA.EXPOSURE");
    71     float zeropt    = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
    72     float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR");
     69    float zeropt    = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP");
     70    if (!isfinite(zeropt)) {
     71        zeropt    = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
     72    }
    7373    if (status1 && status2 && (exptime > 0.0)) {
    7474        magOffset = zeropt + 2.5*log10(exptime);
    7575    }
     76    float zeroptErr = psMetadataLookupF32 (&status2, imageHeader, "ZPT_ERR");
    7677
    7778    // if the sequence is defined, write these in seq order; otherwise
     
    8081        pmSource *source = (pmSource *) sources->data[0];
    8182        if (source->seq == -1) {
    82           // let's write these out in S/N order
    83           sources = psArraySort (sources, pmSourceSortBySN);
     83            // let's write these out in S/N order
     84            sources = psArraySort (sources, pmSourceSortBySN);
    8485        } else {
    85           sources = psArraySort (sources, pmSourceSortBySeq);
     86            sources = psArraySort (sources, pmSourceSortBySeq);
    8687        }
    8788    }
     
    9192    // we write out PSF-fits for all sources, regardless of quality.  the source flags tell us the state
    9293    // by the time we call this function, all values should be assigned.  let's use asserts to be sure in some cases.
    93     for (i = 0; i < sources->n; i++) {
     94    for (int i = 0; i < sources->n; i++) {
    9495        pmSource *source = (pmSource *) sources->data[i];
    9596
     
    99100        // generated on Alloc, and would thus be wrong for read in sources.
    100101        if (source->seq == -1) {
    101           source->seq = i;
     102            source->seq = i;
    102103        }
    103104
     
    111112            yPos = PAR[PM_PAR_YPOS];
    112113            if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) {
    113               xErr = dPAR[PM_PAR_XPOS];
    114               yErr = dPAR[PM_PAR_YPOS];
     114                xErr = dPAR[PM_PAR_XPOS];
     115                yErr = dPAR[PM_PAR_YPOS];
    115116            } else {
    116               // in linear-fit mode, there is no error on the centroid
    117               xErr = source->peak->dx;
    118               yErr = source->peak->dy;
     117                // in linear-fit mode, there is no error on the centroid
     118                xErr = source->peak->dx;
     119                yErr = source->peak->dy;
    119120            }
    120121            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
     
    128129            nDOF = model->nDOF;
    129130            nPix = model->nPix;
    130             apRadius = model->radiusFit; // XXX should we really use the fitRadius for aperture Radius?
     131            apRadius = source->apRadius;
    131132            errMag = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
    132133        } else {
     
    209210    }
    210211
     212    // XXX why do we make a copy here to be supplemented with the masks?  why not do this in the calling function?
    211213    psMetadata *header = psMetadataCopy(NULL, tableHeader);
    212214    pmSourceMasksHeader(header);
    213215
    214216    if (table->n == 0) {
    215         psFitsWriteBlank(fits, header, extname);
     217        if (!psFitsWriteBlank(fits, header, extname)) {
     218            psError(psErrorCodeLast(), false, "Unable to write blank sources file.");
     219            psFree(table);
     220            psFree(header);
     221            return false;
     222        }
    216223        psFree(table);
    217224        psFree(header);
     
    221228    psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
    222229    if (!psFitsWriteTable(fits, header, table, extname)) {
    223         psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
     230        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
    224231        psFree(table);
    225232        psFree(header);
     
    261268    for (int i = 0; i < numSources; i++) {
    262269        psMetadata *row = psFitsReadTableRow(fits, i); // Table row
     270        if (!row) {
     271            psError(psErrorCodeLast(), false, "Unable to read row %d of sources", i);
     272            psFree(sources);
     273            return NULL;
     274        }
    263275
    264276        pmSource *source = pmSourceAlloc ();
     
    304316        source->peak->dx   = dPAR[PM_PAR_XPOS];
    305317        source->peak->dy   = dPAR[PM_PAR_YPOS];
     318        source->peak->SN   = sqrt(source->peak->flux); // XXX a proxy: various functions sort by peak S/N
    306319
    307320        source->pixWeight = psMetadataLookupF32 (&status, row, "PSF_QF");
    308321        source->crNsigma  = psMetadataLookupF32 (&status, row, "CR_NSIGMA");
    309322        source->extNsigma = psMetadataLookupF32 (&status, row, "EXT_NSIGMA");
     323        source->apRadius  = psMetadataLookupS32 (&status, row, "AP_MAG_RADIUS");
    310324
    311325        // note that some older versions used PSF_PROBABILITY: this was not well defined.
     
    313327        model->nDOF       = psMetadataLookupS32 (&status, row, "PSF_NDOF");
    314328        model->nPix       = psMetadataLookupS32 (&status, row, "PSF_NPIX");
    315         model->radiusFit  = psMetadataLookupS32 (&status, row, "AP_MAG_RADIUS");
    316329
    317330        source->moments = pmMomentsAlloc ();
     
    330343}
    331344
    332 // XXX this layout is still the same as PS1_DEV_1
    333 bool pmSourcesWrite_CMF_PS1_V2_XSRC (psFits *fits, psArray *sources, char *extname, psMetadata *recipe)
     345bool pmSourcesWrite_CMF_PS1_V2_XSRC (psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe)
    334346{
    335347
     
    340352    psF32 xPos, yPos;
    341353    psF32 xErr, yErr;
     354    int nRow = -1;
    342355
    343356    // create a header to hold the output data
     
    347360    psMetadataAddStr (outhead, PS_LIST_TAIL, "EXTNAME", PS_META_REPLACE, "xsrc table extension", extname);
    348361
     362    pmChip *chip = readout->parent->parent;
     363    pmFPA  *fpa  = chip->parent;
     364
     365    // zero point corrections
     366    bool status1 = false;
     367    bool status2 = false;
     368    float magOffset = 0.0;
     369    float exptime   = psMetadataLookupF32(&status1, fpa->concepts, "FPA.EXPOSURE");
     370    float zeropt    = psMetadataLookupF32(&status2, fpa->concepts, "FPA.ZP");
     371    if (!isfinite(zeropt)) {
     372        zeropt    = psMetadataLookupF32 (&status2, imageHeader, "ZPT_OBS");
     373    }
     374    if (status1 && status2 && (exptime > 0.0)) {
     375        magOffset = zeropt + 2.5*log10(exptime);
     376    }
     377
    349378    // let's write these out in S/N order
    350379    sources = psArraySort (sources, pmSourceSortBySN);
     
    353382
    354383    // which extended source analyses should we perform?
     384    bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
    355385    bool doPetrosian    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
    356     bool doIsophotal    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ISOPHOTAL");
    357     bool doAnnuli       = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
    358     bool doKron         = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_KRON");
    359 
    360     psVector *radialBinsLower = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
    361     psVector *radialBinsUpper = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
    362     assert (radialBinsLower->n == radialBinsUpper->n);
     386    // bool doIsophotal    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ISOPHOTAL");
     387    // bool doKron         = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_KRON");
     388
     389    psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER");
     390    psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER");
     391    psAssert (radMin->n == radMax->n, "inconsistent annular bins");
     392
     393    // int nRadialBins = 0;
     394    // if (doAnnuli) {
     395    //  // get the max count of radial bins
     396    //  for (int i = 0; i < sources->n; i++) {
     397    //      pmSource *source = sources->data[i];
     398    //      if (!source->extpars) continue;
     399    //      if (!source->extpars->radProfile ) continue;
     400    //         if (!source->extpars->radProfile->binSB) continue;
     401    //      nRadialBins = PS_MAX(nRadialBins, source->extpars->radProfile->binSB->n);
     402    //  }
     403    // }
    363404
    364405    // we write out all sources, regardless of quality.  the source flags tell us the state
     
    396437        psMetadataAdd (row, PS_LIST_TAIL, "Y_EXT_SIG",        PS_DATA_F32, "Sigma in EXT y coordinate",                  yErr);
    397438
     439        float AxialRatio = NAN;
     440        float AxialTheta = NAN;
     441        pmSourceExtendedPars *extpars = source->extpars;
     442        if (extpars) {
     443            AxialRatio = extpars->axes.minor / extpars->axes.major;
     444            AxialTheta = extpars->axes.theta;
     445        }
     446        psMetadataAdd (row, PS_LIST_TAIL, "F25_ARATIO",       PS_DATA_F32, "Axial Ratio of radial profile",              AxialRatio);
     447        psMetadataAdd (row, PS_LIST_TAIL, "F25_THETA",        PS_DATA_F32, "Angle of radial profile ellipse",                  AxialTheta);
     448
    398449        // Petrosian measurements
    399450        // XXX insert header data: petrosian ref radius, flux ratio
     451        // XXX check flags to see if Pet was measured
    400452        if (doPetrosian) {
    401             pmSourcePetrosianValues *petrosian = source->extpars->petrosian;
    402             if (petrosian) {
    403                 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       petrosian->mag);
    404                 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", petrosian->magErr);
    405                 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          petrosian->rad);
    406                 psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    petrosian->radErr);
     453            pmSourceExtendedPars *extpars = source->extpars;
     454            if (extpars) {
     455                // XXX note that this mag is either calibrated or instrumental depending on existence of zero point
     456                float mag = (extpars->petrosianFlux > 0.0) ? -2.5*log10(extpars->petrosianFlux) + magOffset : NAN; // XXX zero point
     457                float magErr = (extpars->petrosianFlux > 0.0) ? extpars->petrosianFlux / extpars->petrosianFluxErr : NAN; // XXX zero point
     458                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude", mag);
     459                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG_ERR",    PS_DATA_F32, "Petrosian Magnitude Error", magErr);
     460                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius (pix)", extpars->petrosianRadius);
     461                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error (pix)", extpars->petrosianRadiusErr);
     462                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50",     PS_DATA_F32, "Petrosian R50 (pix)", extpars->petrosianR50);
     463                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)", extpars->petrosianR50Err);
     464                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90",     PS_DATA_F32, "Petrosian R90 (pix)", extpars->petrosianR90);
     465                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)", extpars->petrosianR90Err);
    407466            } else {
    408467                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_MAG",        PS_DATA_F32, "Petrosian Magnitude",       NAN);
     
    410469                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS",     PS_DATA_F32, "Petrosian Radius",          NAN);
    411470                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_ERR", PS_DATA_F32, "Petrosian Radius Error",    NAN);
     471                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50",     PS_DATA_F32, "Petrosian R50 (pix)", NAN);
     472                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_50_ERR", PS_DATA_F32, "Petrosian R50 Error (pix)",NAN);
     473                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90",     PS_DATA_F32, "Petrosian R90 (pix)", NAN);
     474                psMetadataAdd (row, PS_LIST_TAIL, "PETRO_RADIUS_90_ERR", PS_DATA_F32, "Petrosian R90 Error (pix)",NAN);
    412475            }
    413476        }
    414477
     478# if (0)
    415479        // Kron measurements
    416480        if (doKron) {
     
    445509            }
    446510        }
    447 
    448         // Flux Annuli
     511# endif
     512
     513        // Flux Annuli (if we have extended source measurements, we have these.  only optionally save them)
    449514        if (doAnnuli) {
    450             pmSourceAnnuli *annuli = source->extpars->annuli;
    451             if (annuli) {
    452                 psVector *fluxVal = annuli->flux;
    453                 psVector *fluxErr = annuli->fluxErr;
    454                 psVector *fluxVar = annuli->fluxVar;
    455 
    456                 for (int j = 0; j < fluxVal->n; j++) {
    457                     char name[32];
    458                     sprintf (name, "FLUX_VAL_R_%02d", j);
    459                     psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", fluxVal->data.F32[j]);
    460                     sprintf (name, "FLUX_ERR_R_%02d", j);
    461                     psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", fluxErr->data.F32[j]);
    462                     sprintf (name, "FLUX_VAR_R_%02d", j);
    463                     psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", fluxVar->data.F32[j]);
    464                 }
    465             } else {
    466                 for (int j = 0; j < radialBinsLower->n; j++) {
    467                     char name[32];
    468                     sprintf (name, "FLUX_VAL_R_%02d", j);
    469                     psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux value in annulus", NAN);
    470                     sprintf (name, "FLUX_ERR_R_%02d", j);
    471                     psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux error in annulus", NAN);
    472                     sprintf (name, "FLUX_VAR_R_%02d", j);
    473                     psMetadataAdd (row, PS_LIST_TAIL, name, PS_DATA_F32, "flux stdev in annulus", NAN);
    474                 }
    475             }
    476         }
    477 
    478         psArrayAdd (table, 100, row);
    479         psFree (row);
    480     }
    481 
     515            psVector *radSB   = psVectorAlloc(radMin->n, PS_TYPE_F32);
     516            psVector *radFlux = psVectorAlloc(radMin->n, PS_TYPE_F32);
     517            psVector *radFill = psVectorAlloc(radMin->n, PS_TYPE_F32);
     518            psVectorInit (radSB, NAN);
     519            psVectorInit (radFlux, NAN);
     520            psVectorInit (radFill, NAN);
     521            if (!source->extpars) goto empty_annuli;
     522            if (!source->extpars->radProfile) goto empty_annuli;
     523            if (!source->extpars->radProfile->binSB) goto empty_annuli;
     524            psAssert (source->extpars->radProfile->binSum, "programming error");
     525            psAssert (source->extpars->radProfile->binFill, "programming error");
     526            psAssert (source->extpars->radProfile->binSB->n <= radFlux->n, "inconsistent vector lengths");
     527            psAssert (source->extpars->radProfile->binSum->n <= radFlux->n, "inconsistent vector lengths");
     528            psAssert (source->extpars->radProfile->binFill->n <= radFlux->n, "inconsistent vector lengths");
     529
     530            // copy the data from fluxVal (which is not guaranteed to be the full length) to radFlux
     531            for (int j = 0; j < source->extpars->radProfile->binSB->n; j++) {
     532                radSB->data.F32[j]   = source->extpars->radProfile->binSB->data.F32[j];
     533                radFlux->data.F32[j] = source->extpars->radProfile->binSum->data.F32[j];
     534                radFill->data.F32[j] = source->extpars->radProfile->binFill->data.F32[j];
     535            }
     536
     537        empty_annuli:
     538            psMetadataAdd (row, PS_LIST_TAIL, "PROF_SB", PS_DATA_VECTOR, "mean surface brightness annuli", radSB);
     539            psMetadataAdd (row, PS_LIST_TAIL, "PROF_FLUX", PS_DATA_VECTOR, "flux within annuli", radFlux);
     540            psMetadataAdd (row, PS_LIST_TAIL, "PROF_FILL", PS_DATA_VECTOR, "fill factor of annuli", radFill);
     541            psFree (radSB);
     542            psFree (radFlux);
     543            psFree (radFill);
     544        }
     545        if (nRow < 0) {
     546            nRow = row->list->n;
     547        } else {
     548            psAssert (nRow == row->list->n, "inconsistent row lengths");
     549        }
     550        psArrayAdd (table, 100, row);
     551        psFree (row);
     552    }
     553   
    482554    if (table->n == 0) {
    483         psFitsWriteBlank (fits, outhead, extname);
    484         psFree (outhead);
    485         psFree (table);
    486         return true;
    487     }
    488 
     555        if (!psFitsWriteBlank (fits, outhead, extname)) {
     556            psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
     557            psFree(outhead);
     558            psFree(table);
     559            return false;
     560        }
     561        psFree (outhead);
     562        psFree (table);
     563        return true;
     564    }
     565   
    489566    psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
    490567    if (!psFitsWriteTable (fits, outhead, table, extname)) {
    491         psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
    492         psFree (outhead);
    493         psFree(table);
    494         return false;
     568        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
     569        psFree (outhead);
     570    psFree(table);
     571    return false;
    495572    }
    496573    psFree (outhead);
    497574    psFree (table);
    498 
     575   
    499576    return true;
    500577}
    501578
    502579// XXX this layout is still the same as PS1_DEV_1
    503 bool pmSourcesWrite_CMF_PS1_V2_XFIT (psFits *fits, psArray *sources, char *extname)
     580bool pmSourcesWrite_CMF_PS1_V2_XFIT (psFits *fits, pmReadout *readout, psArray *sources, char *extname)
    504581{
    505582
     
    607684
    608685    if (table->n == 0) {
    609         psFitsWriteBlank (fits, outhead, extname);
     686        if (!psFitsWriteBlank (fits, outhead, extname)) {
     687            psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
     688            psFree(outhead);
     689            psFree(table);
     690            return false;
     691        }
    610692        psFree (outhead);
    611693        psFree (table);
     
    615697    psTrace ("pmFPAfile", 5, "writing ext data %s\n", extname);
    616698    if (!psFitsWriteTable (fits, outhead, table, extname)) {
    617         psError(PS_ERR_IO, false, "writing ext data %s\n", extname);
     699        psError(psErrorCodeLast(), false, "writing ext data %s\n", extname);
    618700        psFree (outhead);
    619701        psFree(table);
Note: See TracChangeset for help on using the changeset viewer.