IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 25, 2007, 3:20:29 PM (19 years ago)
Author:
magnier
Message:

incorporating updates from eam_02_branch (cached models, pmPSF FITS IO)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/objects/pmSource.c

    r12949 r13034  
    66 *  @author EAM, IfA: significant modifications.
    77 *
    8  *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-04-21 19:47:14 $
     8 *  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-04-26 01:20:29 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    3939    psFree(tmp->pixels);
    4040    psFree(tmp->weight);
    41     psFree(tmp->mask);
     41    psFree(tmp->maskObj);
     42    psFree(tmp->maskView);
     43    psFree(tmp->modelFlux);
    4244    psFree(tmp->moments);
    4345    psFree(tmp->modelPSF);
     
    4749}
    4850
     51// free only the pixel data associated with this source
    4952void pmSourceFreePixels(pmSource *source)
    5053{
     
    5558    psFree (source->pixels);
    5659    psFree (source->weight);
    57     psFree (source->mask);
     60    psFree (source->maskObj);
     61    psFree (source->maskView);
     62    psFree (source->modelFlux);
    5863
    5964    source->pixels = NULL;
    6065    source->weight = NULL;
    61     source->mask = NULL;
     66    source->maskObj = NULL;
     67    source->maskView = NULL;
     68    source->modelFlux = NULL;
    6269    return;
    6370}
     
    7683    source->pixels = NULL;
    7784    source->weight = NULL;
    78     source->mask = NULL;
     85    source->maskObj = NULL;
     86    source->maskView = NULL;
     87    source->modelFlux = NULL;
    7988    source->moments = NULL;
    8089    source->blends = NULL;
     
    114123    // the original values.
    115124    pmSource *source = pmSourceAlloc ();
    116     source->peak = psMemIncrRefCounter (in->peak);
    117     source->pixels = psMemIncrRefCounter (in->pixels);
    118     source->weight = psMemIncrRefCounter (in->weight);
    119     source->mask = psMemIncrRefCounter (in->mask);
    120     source->moments = psMemIncrRefCounter (in->moments);
    121     source->blends = NULL;
    122     source->modelPSF = NULL;
    123     source->modelEXT = NULL;
     125
     126    // this is actually the same peak as the original, is this the correct way to handle this?
     127    source->peak = pmPeakAlloc (in->peak->x, in->peak->y, in->peak->value, in->peak->type);
     128    source->peak->xf = in->peak->xf;
     129    source->peak->yf = in->peak->yf;
     130    source->peak->flux = in->peak->flux;
     131    source->peak->SN = in->peak->SN;
     132
     133    // copy the values in the moments structure
     134    source->moments  =  pmMomentsAlloc();
     135    *source->moments = *in->moments;
     136
     137    // These images are all views to the parent. 
     138    // We want a new view, but pointing at the same pixels.
     139    source->pixels   = psImageCopyView (NULL, in->pixels);
     140    source->weight   = psImageCopyView (NULL, in->weight);
     141    source->maskView = psImageCopyView (NULL, in->maskView);
     142
     143    // the maskObj is a unique mask array; create a new mask image
     144    if (in->maskObj) {
     145        source->maskObj = psImageCopy (NULL, in->maskObj, PS_TYPE_MASK);
     146    }
     147
    124148    source->type = in->type;
    125149    source->mode = in->mode;
    126     psMemSetDeallocator(source, (psFreeFunc) sourceFree);
    127 
    128     // default values are NAN
    129     source->psfMag = NAN;
    130     source->extMag = NAN;
    131     source->errMag = NAN;
    132     source->apMag  = NAN;
    133     source->sky    = NAN;
    134     source->skyErr = NAN;
    135     source->pixWeight = NAN;
    136150
    137151    return(source);
     
    151165    srcRegion = psRegionForImage (readout->image, srcRegion);
    152166
    153     mySource->pixels = psMemIncrRefCounter(psImageSubset(readout->image, srcRegion));
    154     mySource->weight = psMemIncrRefCounter(psImageSubset(readout->weight, srcRegion));
    155     mySource->mask   = psMemIncrRefCounter(psImageSubset(readout->mask,  srcRegion));
    156     mySource->region = srcRegion;
     167    // these images are subset images of the equivalent parents
     168    mySource->pixels   = psMemIncrRefCounter(psImageSubset(readout->image, srcRegion));
     169    mySource->weight   = psMemIncrRefCounter(psImageSubset(readout->weight, srcRegion));
     170    mySource->maskView = psMemIncrRefCounter(psImageSubset(readout->mask,  srcRegion));
     171    mySource->region   = srcRegion;
     172
     173    // the object mask is a copy, and used to define the source pixels
     174    mySource->maskObj = psImageCopy (NULL, mySource->maskView, PS_TYPE_MASK);
    157175
    158176    return true;
     
    183201    extend |= (mySource->pixels == NULL);
    184202    extend |= (mySource->weight == NULL);
    185     extend |= (mySource->mask == NULL);
     203    extend |= (mySource->maskObj == NULL);
     204    extend |= (mySource->maskView == NULL);
    186205
    187206    // extend = true;
     
    190209        psFree (mySource->pixels);
    191210        psFree (mySource->weight);
    192         psFree (mySource->mask);
    193 
    194         mySource->pixels = psMemIncrRefCounter(psImageSubset(readout->image,  newRegion));
    195         mySource->weight = psMemIncrRefCounter(psImageSubset(readout->weight, newRegion));
    196         mySource->mask   = psMemIncrRefCounter(psImageSubset(readout->mask,   newRegion));
    197         mySource->region = newRegion;
    198     }
    199 
     211        psFree (mySource->maskView);
     212
     213        mySource->pixels   = psMemIncrRefCounter(psImageSubset(readout->image,  newRegion));
     214        mySource->weight   = psMemIncrRefCounter(psImageSubset(readout->weight, newRegion));
     215        mySource->maskView = psMemIncrRefCounter(psImageSubset(readout->mask,   newRegion));
     216        mySource->region   = newRegion;
     217
     218        // re-copy the main mask pixels.  NOTE: the user will need to reset the object mask
     219        // pixels (eg, with psImageKeepCircle)
     220        mySource->maskObj = psImageCopy (mySource->maskObj, mySource->maskView, PS_TYPE_MASK);
     221       
     222        // drop the old modelFlux pixels and force the user to re-create
     223        psFree (mySource->modelFlux);
     224        mySource->modelFlux = NULL;
     225    }
    200226    return extend;
    201227}
     
    207233
    208234// XXX EAM include a S/N cutoff in selecting the sources?
     235// XXX this function should probably accept the values, not a recipe. wrap with a
     236// psphot-specific function which applies the recipe values
    209237pmPSFClump pmSourcePSFClump(psArray *sources, psMetadata *recipe)
    210238{
     
    458486        // XXX EAM : can we use the value of SATURATE if mask is NULL?
    459487        inner = psRegionForSquare (source->peak->x, source->peak->y, 2);
    460         inner = psRegionForImage (source->mask, inner);
    461         int Nsatpix = psImageCountPixelMask (source->mask, inner, PM_MASK_SAT);
     488        inner = psRegionForImage (source->maskView, inner);
     489        int Nsatpix = psImageCountPixelMask (source->maskView, inner, PM_MASK_SAT);
    462490
    463491        // saturated star (size consistent with PSF or larger)
     
    572600    PS_ASSERT_PTR_NON_NULL(source->peak, false);
    573601    PS_ASSERT_PTR_NON_NULL(source->pixels, false);
    574     PS_ASSERT_PTR_NON_NULL(source->mask, false);
     602    PS_ASSERT_PTR_NON_NULL(source->maskObj, false);
    575603    PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false);
    576604
     
    622650        psF32 *vPix = source->pixels->data.F32[row];
    623651        psF32 *vWgt = source->weight->data.F32[row];
    624         psU8  *vMsk = (source->mask == NULL) ? NULL : source->mask->data.U8[row];
     652        psU8  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.U8[row];
    625653
    626654        for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
     
    719747}
    720748
    721 pmModel *pmSourceSelectModel (pmSource *source)
    722 {
     749// construct a realization of the source model
     750bool pmSourceCacheModel (pmSource *source) {
     751
     752    // select appropriate model
     753    pmModel *model = pmSourceGetModel (NULL, source);
     754    if (model == NULL) return false;  // model must be defined
     755       
     756    // if we already have a cached image, re-use that memory
     757    source->modelFlux = psImageCopy (source->modelFlux, source->pixels, PS_TYPE_F32);
     758    psImageInit (source->modelFlux, 0.0);
     759
     760    // in some places (psphotEnsemble), we need a normalized version
     761    // in others, we just want the model.  which is more commonly used?
     762    // modelFlux always has unity normalization (I0 = 1.0)
     763    pmModelAdd (source->modelFlux, source->maskObj, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM);
     764    return true;
     765}
     766
     767// should we call pmSourceCacheModel if it does not exist?
     768bool pmSourceOp (pmSource *source, pmModelOpMode mode, bool add) {
     769
     770    bool status;
     771
     772    if (add) {
     773        psTrace ("psphot", 3, "replacing object at %f,%f\n", source->peak->xf, source->peak->yf);
     774    } else {
     775        psTrace ("psphot", 3, "removing object at %f,%f\n", source->peak->xf, source->peak->yf);
     776    }
     777
     778    pmModel *model = pmSourceGetModel (NULL, source);
     779    if (model == NULL) return false;  // model must be defined
     780
     781    if (source->modelFlux) {
     782        // add in the pixels from the modelFlux image
     783        int dX = source->modelFlux->col0 - source->pixels->col0;
     784        int dY = source->modelFlux->row0 - source->pixels->row0;
     785        assert (dX >= 0);
     786        assert (dY >= 0);
     787        assert (dX + source->modelFlux->numCols <= source->pixels->numCols);
     788        assert (dY + source->modelFlux->numRows <= source->pixels->numRows);
     789       
     790        // modelFlux has unity normalization
     791        float Io = model->params->data.F32[PM_PAR_I0];
     792        if (mode & PM_MODEL_OP_NORM) {
     793            Io = 1.0;
     794        }
     795
     796        psU8 **mask = NULL;
     797        if (source->maskObj) {
     798            mask = source->maskObj->data.U8;
     799        }
     800
     801        // XXX need to respect the source and model masks?
     802        for (int iy = 0; iy < source->modelFlux->numRows; iy++) {
     803            int oy = iy + dY;
     804            for (int ix = 0; ix < source->modelFlux->numCols; ix++) {
     805                int ox = ix + dX;
     806                if (mask && mask[iy][ix]) continue;
     807                float value = Io*source->modelFlux->data.F32[iy][ix];
     808                if (add) {
     809                    source->pixels->data.F32[oy][ox] += value;
     810                } else {
     811                    source->pixels->data.F32[oy][ox] -= value;
     812                }
     813            }
     814        }
     815        return true;
     816    }
     817
     818    if (add) {
     819        status = pmModelAdd (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL);
     820    } else {
     821        status = pmModelSub (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL);
     822    }
     823
     824    return true;
     825}
     826
     827bool pmSourceAdd (pmSource *source, pmModelOpMode mode) {
     828    bool status = pmSourceOp (source, mode, true);
     829    return status;
     830}
     831
     832bool pmSourceSub (pmSource *source, pmModelOpMode mode) {
     833    bool status = pmSourceOp (source, mode, false);
     834    return status;
     835}
     836
     837// given a source, which model is currently appropriate?
     838// choose PSF or EXT based on source->type, but fall back on PSF
     839// if the EXT model is NULL
     840pmModel *pmSourceGetModel (bool *isPSF, const pmSource *source)
     841{
     842
     843    pmModel *model;
     844
     845    if (isPSF) {
     846      *isPSF = false;
     847    }
     848
    723849    switch (source->type) {
    724850    case PM_SOURCE_TYPE_STAR:
    725         return source->modelPSF;
     851        model = source->modelPSF;
     852        if (model == NULL)
     853            return NULL;
     854        if (isPSF) {
     855            *isPSF = true;
     856        }
     857        return model;
    726858
    727859    case PM_SOURCE_TYPE_EXTENDED:
    728         return source->modelEXT;
     860        model = source->modelEXT;
     861        if (!model && source->modelPSF) {
     862            if (isPSF) {
     863                *isPSF = true;
     864            }
     865            return source->modelPSF;
     866        }
     867        return (model);
     868        break;
    729869
    730870    default:
Note: See TracChangeset for help on using the changeset viewer.