IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 36707 for trunk/psModules


Ignore:
Timestamp:
Apr 30, 2014, 3:48:08 PM (12 years ago)
Author:
bills
Message:

read and write CFF files with more than one row per source

File:
1 edited

Legend:

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

    r36633 r36707  
    5353#include "pmSourceOutputs.h"
    5454
    55 // read in a readout from the fits file
     55// read in sources readout from a cff fits file
    5656psArray *pmSourcesRead_CFF (psFits *fits, psMetadata *header)
    5757{
     
    7878    // is large and ephemeral --- when the table gets blown away, whatever is allocated after
    7979    // the table is read blocks the free.  In fact, it's better to read the table row by row.
    80     long numSources = psFitsTableSize(fits); // Number of sources in table
    81     psArray *sources = psArrayAlloc(numSources); // Array of sources, to return
    82 
    83     // convert the table to the pmSource entriesa
    84     for (int i = 0; i < numSources; i++) {
     80    long numRows = psFitsTableSize(fits); // Number of rows in table
     81    psArray *sources = psArrayAllocEmpty(numRows); // Array of sources, to return
     82
     83    // convert the table to the pmSource entries
     84    unsigned int ID_last = 0;
     85    pmSource *source = NULL;
     86    for (int i = 0; i < numRows; i++) {
    8587        psMetadata *row = psFitsReadTableRow(fits, i); // Table row
    8688        if (!row) {
     
    123125        float Sindex     = psMetadataLookupF32 (&status, row, "INDEX"); // Should this be PAR_07 not sersic index
    124126
    125         pmSource *source = pmSourceAlloc ();
    126         pmModel *model = pmModelAlloc (modelType);
    127         source->modelPSF  = model;
    128 //        RoughClass wants source type to be unknown
    129 //        source->type = PM_SOURCE_TYPE_STAR; // XXX this should be added to the flags
    130         source->type = PM_SOURCE_TYPE_UNKNOWN;
    131 
    132         // XXX we can set this in general, but for a specific image, we need to weed out SATSTARS and
    133         // stars that are masked
    134         if (psfStar) {
    135             source->tmpFlags |= PM_SOURCE_TMPF_CANDIDATE_PSFSTAR;
    136         }
    137 
    138         // NOTE: A SEGV here because "model" is NULL is probably caused by not initialising the models.
    139         psF32 *PAR = model->params->data.F32;
    140         psF32 *dPAR = model->dparams->data.F32;
    141 
    142         source->seq       = ID;
    143         PAR[PM_PAR_XPOS]  = X;
    144         PAR[PM_PAR_YPOS]  = Y;
    145 
    146         dPAR[PM_PAR_XPOS] = 0.0;
    147         dPAR[PM_PAR_YPOS] = 0.0;
    148 
    149         PAR[PM_PAR_SKY]   = 0.0;
    150         dPAR[PM_PAR_SKY]  = 0.0;
    151 
    152         PAR[PM_PAR_I0]    = 1.0;
    153         dPAR[PM_PAR_I0]   = 0.0;
    154 
    155         source->sky       = PAR[PM_PAR_SKY];
    156         source->skyErr    = dPAR[PM_PAR_SKY];
    157 
    158         source->psfMag    = 0.0;
    159         source->psfMagErr = 0.0;
    160         source->apMag     = 0.0;
    161         source->apRadius  = apRadius;
    162 
    163         // we generate a somewhat fake PSF model here --
    164         // in most (all?) contexts, we will replace this with a measured psf model
    165         // elsewhere
    166         axes.major        = 1.0;
    167         axes.minor        = 1.0;
    168         axes.theta        = 0.0;
    169         pmPSF_AxesToModel (PAR, axes, modelType);
    170 
    171         // peak->detValue, rawFlux, smoothFlux are all set to the flux argument which is counts per second
    172         source->peak      = pmPeakAlloc(X, Y, flux, PM_PEAK_LONE);
    173         source->peak->xf  = X; // pmPeakAlloc converts X,Y to int, so reset here
    174         source->peak->yf  = Y; // pmPeakAlloc converts X,Y to int, so reset here
    175         source->peak->dx  = 0.0;
    176         source->peak->dy  = 0.0;
    177 
    178         source->moments = pmMomentsAlloc ();
    179         source->moments->Mx = X;
    180         source->moments->My = Y;
    181         source->moments->Mrf = kronRadius * 0.4; // kronRadius is 2.5 * first radial moment
    182 
    183         // Don't mark the moments as measured because that causes many fields to be left blank.
    184         // The moments code knows not to change the position or the Mrf for external sources
    185         // source->tmpFlags |= PM_SOURCE_TMPF_MOMENTS_MEASURED;
    186 
    187         if (isfinite(petRadius)) {
    188             source->extpars = pmSourceExtendedParsAlloc ();
    189             source->extpars->petrosianRadius = petRadius;
    190         }
    191 
     127        if (!source || ID != source->seq) {
     128            if (source) {
     129                psArrayAdd (sources, 1, source);
     130                psFree(source);
     131            }
     132            source = pmSourceAlloc ();
     133            pmModel *model = pmModelAlloc (modelType);
     134            source->modelPSF  = model;
     135            //        RoughClass wants source type to be unknown
     136            //        source->type = PM_SOURCE_TYPE_STAR; // XXX this should be added to the flags
     137            source->type = PM_SOURCE_TYPE_UNKNOWN;
     138
     139            // XXX we can set this in general, but for a specific image, we need to weed out SATSTARS and
     140            // stars that are masked
     141            if (psfStar) {
     142                source->tmpFlags |= PM_SOURCE_TMPF_CANDIDATE_PSFSTAR;
     143            }
     144
     145            // NOTE: A SEGV here because "model" is NULL is probably caused by not initialising the models.
     146            psF32 *PAR = model->params->data.F32;
     147            psF32 *dPAR = model->dparams->data.F32;
     148
     149            source->seq       = ID;
     150            ID_last = ID;
     151
     152            PAR[PM_PAR_XPOS]  = X;
     153            PAR[PM_PAR_YPOS]  = Y;
     154
     155            dPAR[PM_PAR_XPOS] = 0.0;
     156            dPAR[PM_PAR_YPOS] = 0.0;
     157
     158            PAR[PM_PAR_SKY]   = 0.0;
     159            dPAR[PM_PAR_SKY]  = 0.0;
     160
     161            PAR[PM_PAR_I0]    = 1.0;
     162            dPAR[PM_PAR_I0]   = 0.0;
     163
     164            source->sky       = PAR[PM_PAR_SKY];
     165            source->skyErr    = dPAR[PM_PAR_SKY];
     166
     167            source->psfMag    = 0.0;
     168            source->psfMagErr = 0.0;
     169            source->apMag     = 0.0;
     170            source->apRadius  = apRadius;
     171
     172            // we generate a somewhat fake PSF model here --
     173            // in most (all?) contexts, we will replace this with a measured psf model
     174            // elsewhere
     175            axes.major        = 1.0;
     176            axes.minor        = 1.0;
     177            axes.theta        = 0.0;
     178            pmPSF_AxesToModel (PAR, axes, modelType);
     179
     180            // peak->detValue, rawFlux, smoothFlux are all set to the flux argument which is counts per second
     181            source->peak      = pmPeakAlloc(X, Y, flux, PM_PEAK_LONE);
     182            source->peak->xf  = X; // pmPeakAlloc converts X,Y to int, so reset here
     183            source->peak->yf  = Y; // pmPeakAlloc converts X,Y to int, so reset here
     184            source->peak->dx  = 0.0;
     185            source->peak->dy  = 0.0;
     186
     187            source->moments = pmMomentsAlloc ();
     188            source->moments->Mx = X;
     189            source->moments->My = Y;
     190            source->moments->Mrf = kronRadius * 0.4; // kronRadius is 2.5 * first radial moment
     191
     192            // Don't mark the moments as measured because that causes many fields to be left blank.
     193            // The moments code knows not to change the position or the Mrf for external sources
     194            // source->tmpFlags |= PM_SOURCE_TMPF_MOMENTS_MEASURED;
     195
     196            if (isfinite(petRadius)) {
     197                source->extpars = pmSourceExtendedParsAlloc ();
     198                source->extpars->petrosianRadius = petRadius;
     199            }
     200
     201        }
    192202        if (fitGalaxy && galaxyModelType >= 0) {
    193             source->modelFits = psArrayAllocEmpty (1);
    194             pmModel *model = pmModelAlloc(galaxyModelType);
    195             psF32 *xPAR = model->params->data.F32;
    196 
    197             xPAR[PM_PAR_SKY]  = 0.0;
    198             xPAR[PM_PAR_I0]   = 1.0;
    199             xPAR[PM_PAR_XPOS] = X;
     203            if (!source->modelFits) {
     204                source->modelFits = psArrayAllocEmpty (1);
     205            }
     206            pmModel *model = pmModelAlloc(galaxyModelType);
     207            psF32 *xPAR = model->params->data.F32;
     208
     209            xPAR[PM_PAR_SKY]  = 0.0;
     210            xPAR[PM_PAR_I0]   = 1.0;
     211            xPAR[PM_PAR_XPOS] = X;
    200212            xPAR[PM_PAR_YPOS] = Y;
    201213           
     
    212224            psArrayAdd (source->modelFits, 1, model);
    213225
    214 #ifdef notyet
    215             // XXX: set source->modelEXT to this model and flag as extended so that we have a better
    216             // shot at subtracting extended sources?
    217 
    218             // This doesn't work right. Need to do some more work to flesh out the model before it can be
    219             // used in subtaction. Better idea might be to do 2 passes in psphotFullForceReadout to
    220             // First find the best extended models and then do everything else.
    221             source->modelEXT = psMemIncrRefCounter(model);
    222             // is this safe? (no see above)
    223             source->type = PM_SOURCE_TYPE_EXTENDED;
    224             source->mode |= PM_SOURCE_MODE_EXTMODEL;
    225 #endif
    226 
    227226            psFree (model);
    228227        }
    229228
    230         sources->data[i] = source;
    231229        psFree(row);
     230    }
     231    if (source) {
     232        // close out last source
     233        psArrayAdd (sources, 1, source);
     234        psFree(source);
    232235    }
    233236
     
    250253
    251254    pmModelType sersicModelType = pmModelClassGetType("PS_MODEL_SERSIC");
     255    pmModelType devModelType    = pmModelClassGetType("PS_MODEL_DEV");
     256    pmModelType selectedModelType = -1;
     257    bool chooseBest = false;
     258    bool chooseAll = false;
    252259
    253260    psString modelToChoose = psMetadataLookupStr(&mdok, recipe, "EXT_MODEL_TYPE_FOR_CFF");
    254     pmModelType selectedModelType = -1;
     261
    255262    if (mdok && modelToChoose != NULL) {
    256         if (strcmp(modelToChoose, "BEST")) {
     263        if (!strcmp(modelToChoose, "BEST")) {
     264            chooseBest = true;
     265        } else if (!strcmp(modelToChoose, "ALL")) {
     266            chooseAll = true;
     267        } else if (strcmp(modelToChoose, "PS_MODEL_SERSIC")) {
     268            // We have selected a model type other than Sersic.
     269            // Save it's type for use below.  Sersic is handled specially
    257270            selectedModelType = pmModelClassGetType(modelToChoose);
    258271        }
    259272    }
     273
     274    // minimum sersic index to force devModel
     275    psF32 sersicMinDev = psMetadataLookupF32(&mdok, recipe, "EXT_MODEL_FORCE_DEV_SERSIC_MIN");
     276    if (!mdok) {
     277        sersicMinDev = NAN;
     278    }
     279
     280    sources = psArraySort (sources, pmSourceSortBySeq);
    260281
    261282    for (int i = 0; i < sources->n; i++) {
     
    263284        pmSource *source = thisSource->parent ? thisSource->parent : thisSource;
    264285
    265         psF32 xPos, yPos, flux, rMajor, rMinor, theta;
    266         psS32 modelType = 0;
     286        #define MAX_ROWS_PER_SRC 10
     287        psF32 xPos[MAX_ROWS_PER_SRC], yPos[MAX_ROWS_PER_SRC], flux[MAX_ROWS_PER_SRC];
     288        psF32 rMajor[MAX_ROWS_PER_SRC], rMinor[MAX_ROWS_PER_SRC], theta[MAX_ROWS_PER_SRC];
     289        psS32 modelType[MAX_ROWS_PER_SRC];
     290        psF32 sersicIndex[MAX_ROWS_PER_SRC];
    267291        bool fitGalaxy = false;
    268292        bool psfStar = (source->mode & PM_SOURCE_MODE_PSFSTAR) ? true : false;
    269         psF32 sersicIndex = 0;
    270         // For now only perform galaxy fits on extended objects
    271         if (source->modelEXT == NULL) {
    272             pmModel *model = source->modelPSF;
    273             if (model == NULL) continue;
    274             psF32 *PAR = model->params->data.F32;
    275             if (!isfinite(PAR[PM_PAR_SXX]) || !isfinite(PAR[PM_PAR_SYY])  || !isfinite(PAR[PM_PAR_SXY]) ||
    276                 !isfinite(source->psfFlux)) {
    277                 continue;
    278             }
    279 
    280             xPos = model->params->data.F32[PM_PAR_XPOS];
    281             yPos = model->params->data.F32[PM_PAR_YPOS];
    282             flux = source->psfFlux;
    283             rMajor = 0;
    284             rMinor = 0;
    285             theta = 0;
    286         } else {
    287             //   Find the model with the selected type. If selected type is -1 choose the one selected ad
    288             //   modelEXT which was the best
    289             int iModel = -1;
    290             if (source->modelEXT) {
    291                 pmModelType ext_model_type =  selectedModelType != -1  ? selectedModelType : source->modelEXT->type;
     293        int n_rows = 0;
     294
     295        // start with psf model
     296        pmModel *model = source->modelPSF;
     297        if (model == NULL) continue;
     298        psF32 *PAR = model->params->data.F32;
     299        if (!isfinite(PAR[PM_PAR_SXX]) || !isfinite(PAR[PM_PAR_SYY])  || !isfinite(PAR[PM_PAR_SXY]) ||
     300            !isfinite(source->psfFlux)) {
     301            continue;
     302        }
     303
     304        xPos[0] = model->params->data.F32[PM_PAR_XPOS];
     305        yPos[0] = model->params->data.F32[PM_PAR_YPOS];
     306        flux[0] = source->psfFlux;
     307        rMajor[0] = 0;
     308        rMinor[0] = 0;
     309        theta[0] = 0;
     310        modelType[0] = -1;
     311        sersicIndex[0] = NAN;
     312
     313        if (source->modelFits != NULL) {
     314            // figure out which models to use based on recipe paramters
     315            if (chooseAll) {
     316                // Save parameters for all valid extended models
     317
     318                // but make sure we aren't going to overflow our arrays
     319                assert (source->modelFits->n < MAX_ROWS_PER_SRC);
     320
    292321                for (int j=0; j<source->modelFits->n; j++) {
    293                     pmModel *aModel = source->modelFits->data[j];
    294                     if (aModel->type == ext_model_type) {
    295                         iModel = j;
    296                         break;
     322                    pmModel *model = source->modelFits->data[j];
     323                    psF32 *PAR = model->params->data.F32;
     324
     325                    if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY])  && isfinite(PAR[PM_PAR_SXY]) &&
     326                        isfinite(model->mag)) {
     327
     328                        xPos[n_rows] = PAR[PM_PAR_XPOS];
     329                        yPos[n_rows] = PAR[PM_PAR_YPOS];
     330
     331                        psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type);
     332                        rMajor[n_rows] = axes.major;
     333                        rMinor[n_rows] = axes.minor;
     334                        theta[n_rows]  = axes.theta*PS_DEG_RAD;
     335                        flux[n_rows] = pow(10.0, -0.4*model->mag);
     336                        modelType[n_rows] = model->type;
     337                        fitGalaxy = true;
     338                        if (model->params->n == 8) {
     339                            // this will save the sersic index in all models but that might
     340                            // be useful
     341                            sersicIndex[n_rows] = 0.5 / PAR[PM_PAR_7];
     342                        } else {
     343                            sersicIndex[n_rows] = NAN;
     344                        }
     345
     346                        n_rows++;
     347                    }
     348                }
     349            } else {
     350                int jModelSersic = -1;
     351                int jModelDev = -1;
     352                int jModelSelected = -1;
     353                psF32 minChisq = NAN;
     354                for (int j=0; j<source->modelFits->n; j++) {
     355                    pmModel *model = source->modelFits->data[j];
     356                    if (chooseBest) {
     357                        // choose the model with lowest chisq
     358                        if (isfinite(model->chisq) && (!isfinite(minChisq) || model->chisq < minChisq)) {
     359                            jModelSelected = j;
     360                            minChisq = model->chisq;
     361                        }
     362                    } else {
     363                        // find the index of models of interest
     364                        if (model->type == selectedModelType) {
     365                            jModelSelected = j;
     366                        } else if (model->type == sersicModelType) {
     367                            jModelSersic = j;
     368                        } else if (model->type == devModelType) {
     369                            jModelDev = j;
     370                        }
     371                    }
     372                }
     373                if (jModelSelected >= 0 || jModelSersic >= 0) {
     374                    // If a specific non-sersic model we take paramers from that one.
     375                    // Otherwise we do the sersic model.
     376                    pmModel *model = jModelSelected >= 0 ? source->modelFits->data[jModelSelected] :
     377                                                           source->modelFits->data[jModelSersic];
     378                    psF32 *PAR = model->params->data.F32;
     379
     380                    if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY])  && isfinite(PAR[PM_PAR_SXY]) &&
     381                        isfinite(model->mag)) {
     382
     383                        xPos[0] = PAR[PM_PAR_XPOS];
     384                        yPos[0] = PAR[PM_PAR_YPOS];
     385
     386                        psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type);
     387                        rMajor[0] = axes.major;
     388                        rMinor[0] = axes.minor;
     389                        theta[0]  = axes.theta*PS_DEG_RAD;
     390                        flux[0] = pow(10.0, -0.4*model->mag);
     391                        modelType[0] = model->type;
     392                        fitGalaxy = true;
     393                        if (model->type == sersicModelType) {
     394                            PS_ASSERT_FLOAT_LARGER_THAN(PAR[PM_PAR_7], 0.0, false);
     395                            sersicIndex[0] = 0.5 / PAR[PM_PAR_7];
     396                        }
     397
     398                        n_rows = 1;
     399
     400                        // Unless a specific non-sersic model type was selected do dev model for sources with
     401                        // sersic index above the recipe limit.
     402                        if (jModelSelected == -1 && jModelDev >= 0 && isfinite(sersicMinDev) &&
     403                            sersicIndex[0] > sersicMinDev) {
     404
     405                            model = source->modelFits->data[jModelDev];
     406                            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SYY])  && isfinite(PAR[PM_PAR_SXY]) &&
     407                                isfinite(model->mag)) {
     408
     409                                xPos[1] = PAR[PM_PAR_XPOS];
     410                                yPos[1] = PAR[PM_PAR_YPOS];
     411
     412                                psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type);
     413                                rMajor[1] = axes.major;
     414                                rMinor[1] = axes.minor;
     415                                theta[1]  = axes.theta*PS_DEG_RAD;
     416                                flux[1] = pow(10.0, -0.4*model->mag);
     417                                modelType[1] = model->type;
     418                                sersicIndex[1] = NAN;
     419                                n_rows = 2;
     420                            }
     421                        }
    297422                    }
    298423                }
    299424            }
    300             if (iModel == -1) {
    301                 // Can this happen? perhaps if model type is qgauss (extended but below s/n for model fits?
    302                 // XXX: Should this be an assert?
    303                 continue;
    304             }
    305             pmModel *model = source->modelFits->data[iModel];
    306             psF32 *PAR = model->params->data.F32;
    307             xPos = PAR[PM_PAR_XPOS];
    308             yPos = PAR[PM_PAR_YPOS];
    309             if (model->type == pmModelClassGetType("PS_MODEL_TRAIL")) {
    310                 // XXX: do we need to handle this type
    311                 continue;
    312             } else {
    313                 if (!isfinite(PAR[PM_PAR_SXX]) || !isfinite(PAR[PM_PAR_SYY])  || !isfinite(PAR[PM_PAR_SXY]) ||
    314                     !isfinite(model->mag)) {
    315                     // bad model
    316                     continue;
    317                 }
    318                 psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type);
    319                 rMajor = axes.major;
    320                 rMinor = axes.minor;
    321                 theta  = axes.theta*PS_DEG_RAD;
    322                 flux = pow(10.0, -0.4*model->mag);
    323                 fitGalaxy = true;
    324             }
    325             modelType = model->type;
    326             if (modelType == sersicModelType) {
    327                 PS_ASSERT_FLOAT_LARGER_THAN(PAR[PM_PAR_7], 0.0, false);
    328                 sersicIndex = 0.5 / PAR[PM_PAR_7];
    329             }
    330         }
    331         psMetadata *row = psMetadataAlloc();
    332         psMetadataAddU32 (row, PS_LIST_TAIL, "ID",         0,   "IPP detection identifier",  source->seq);
    333         psMetadataAddF32 (row, PS_LIST_TAIL, "X",                0, "x coordinate",          xPos);
    334         psMetadataAddF32 (row, PS_LIST_TAIL, "Y",                0, "y coordinate",          yPos);
    335         psMetadataAddF32 (row, PS_LIST_TAIL, "FLUX",             0, "flux per second",       flux/exptime);
    336         psMetadataAddF32 (row, PS_LIST_TAIL, "AP_RADIUS",        0, "aperture radius",       source->apRadius);
    337         psMetadataAddF32 (row, PS_LIST_TAIL, "KRON_RADIUS",      0, "Kron radius",           source->moments->Mrf * 2.5);
    338         psMetadataAddF32 (row, PS_LIST_TAIL, "PETRO_RADIUS",     0, "Petrosian Radius",      source->extpars ? source->extpars->petrosianRadius : NAN);
    339         psMetadataAddBool (row, PS_LIST_TAIL, "FIT_GALAXY",      0, "source has xfit",       fitGalaxy);
    340         psMetadataAddBool (row, PS_LIST_TAIL, "PSF_STAR",        0, "source was psf star",   psfStar);
    341         psMetadataAddF32 (row, PS_LIST_TAIL, "R_MAJOR",          0, "radius of major axis",  rMajor);
    342         psMetadataAddF32 (row, PS_LIST_TAIL, "R_MINOR",          0, "radius of minor axis",  rMinor);
    343         psMetadataAddF32 (row, PS_LIST_TAIL, "THETA",            0, "theta",                 theta);
    344         psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "model type",            modelType);
    345         psMetadataAddF32 (row, PS_LIST_TAIL, "INDEX",            0, "sersic index",          sersicIndex);
    346 
    347         psArrayAdd(table, 100, row);
    348         psFree(row);
     425        }
     426        if (n_rows == 0) {
     427            // didn't find a suitable extended model we have one row with the psf parameters
     428            n_rows = 1;
     429        }
     430
     431        for (int j = 0; j < n_rows; j++) {
     432            psMetadata *row = psMetadataAlloc();
     433            psMetadataAddU32 (row, PS_LIST_TAIL, "ID",         0,   "IPP detection identifier",  source->seq);
     434            psMetadataAddF32 (row, PS_LIST_TAIL, "X",                0, "x coordinate",          xPos[j]);
     435            psMetadataAddF32 (row, PS_LIST_TAIL, "Y",                0, "y coordinate",          yPos[j]);
     436            psMetadataAddF32 (row, PS_LIST_TAIL, "FLUX",             0, "flux per second",       flux[j]/exptime);
     437            psMetadataAddF32 (row, PS_LIST_TAIL, "AP_RADIUS",        0, "aperture radius",       source->apRadius);
     438            psMetadataAddF32 (row, PS_LIST_TAIL, "KRON_RADIUS",      0, "Kron radius",           source->moments->Mrf * 2.5);
     439            psMetadataAddF32 (row, PS_LIST_TAIL, "PETRO_RADIUS",     0, "Petrosian Radius",      source->extpars ? source->extpars->petrosianRadius : NAN);
     440            psMetadataAddBool (row, PS_LIST_TAIL, "FIT_GALAXY",      0, "source has xfit",       fitGalaxy);
     441            psMetadataAddBool (row, PS_LIST_TAIL, "PSF_STAR",        0, "source was psf star",   psfStar);
     442            psMetadataAddF32 (row, PS_LIST_TAIL, "R_MAJOR",          0, "radius of major axis",  rMajor[j]);
     443            psMetadataAddF32 (row, PS_LIST_TAIL, "R_MINOR",          0, "radius of minor axis",  rMinor[j]);
     444            psMetadataAddF32 (row, PS_LIST_TAIL, "THETA",            0, "theta",                 theta[j]);
     445            psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "model type",            modelType[j]);
     446            psMetadataAddF32 (row, PS_LIST_TAIL, "INDEX",            0, "sersic index",          sersicIndex[j]);
     447
     448            psArrayAdd(table, 100, row);
     449            psFree(row);
     450        }
    349451    }
    350452
Note: See TracChangeset for help on using the changeset viewer.