IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 17, 2014, 12:30:45 PM (12 years ago)
Author:
eugene
Message:

merge changes (from past YEAR) into trunk

Location:
branches/eam_branches/ipp-ops-20130712/psModules
Files:
111 edited
10 copied

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-ops-20130712/psModules

    • Property svn:mergeinfo deleted
  • branches/eam_branches/ipp-ops-20130712/psModules/src/astrom/Makefile.am

    r20801 r37066  
    1111        pmAstrometryRefstars.c \
    1212        pmAstrometryWCS.c \
    13         pmAstrometryVisual.c
     13        pmAstrometryVisual.c \
     14        pmKHcorrect.c
    1415
    1516pkginclude_HEADERS = \
     
    2122        pmAstrometryRefstars.h \
    2223        pmAstrometryWCS.h \
    23         pmAstrometryVisual.h
     24        pmAstrometryVisual.h \
     25        pmKHcorrect.h
    2426
    2527CLEANFILES = *~
  • branches/eam_branches/ipp-ops-20130712/psModules/src/astrom/pmAstrometryModel.c

    r26260 r37066  
    3939#include "pmFPAExtent.h"
    4040#include "pmFPAfileFitsIO.h"
     41#include "pmConcepts.h"
    4142#include "pmAstrometryWCS.h"
    4243#include "pmAstrometryUtils.h"
     
    452453}
    453454
    454 int pmConceptsChipNumberFromName (pmFPA *fpa, char *name) {
    455 
    456     for (int i = 0; i < fpa->chips->n; i++) {
    457         pmChip *chip = fpa->chips->data[i];
    458         if (!chip) continue;
    459         char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
    460         if (!thisone) continue;
    461         if (!strcmp (name, thisone)) return (i);
    462     }
    463     return -1;
    464 }
    465 
    466 pmChip *pmConceptsChipFromName (pmFPA *fpa, char *name) {
    467 
    468     for (int i = 0; i < fpa->chips->n; i++) {
    469         pmChip *chip = fpa->chips->data[i];
    470         if (!chip) continue;
    471         char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
    472         if (!thisone) continue;
    473         if (!strcmp (name, thisone)) return (chip);
    474     }
    475     return NULL;
    476 }
    477 
    478455// first layer converts Chip to Focal Plane
    479456bool pmAstromModelReadChips (pmFPAfile *file) {
  • branches/eam_branches/ipp-ops-20130712/psModules/src/astrom/pmAstrometryModel.h

    r18601 r37066  
    2727bool pmAstromModelWriteChips (pmFPAfile *file);
    2828
    29 int pmConceptsChipNumberFromName (pmFPA *fpa, char *name);
    30 pmChip *pmConceptsChipFromName (pmFPA *fpa, char *name);
    31 
    3229bool pmAstromModelReadForView (const pmFPAview *view, pmFPAfile *file, const pmConfig *config);
    3330bool pmAstromModelReadFPA (pmFPAfile *file);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/astrom/pmAstrometryObjects.c

    r31671 r37066  
    571571    psMemSetDeallocator (stats, (psFreeFunc)pmAstromStatsFree);
    572572
    573     //    stats->center = {0, 0, 0, 0};
    574     //    stats->offset = {0, 0, 0, 0};
    575     stats->angle     = 0.0;
    576     stats->scale     = 1.0;
    577     stats->minMetric = 0.0;
    578     stats->minVar    = 0.0;
    579     stats->nMatch    = 0;
    580     stats->nTest     = 0;
    581     stats->nSigma    = 0;
     573    stats->center.x    = 0;
     574    stats->center.y    = 0;
     575    stats->center.xErr = 0;
     576    stats->center.yErr = 0;
     577
     578    stats->offset.x    = 0;
     579    stats->offset.y    = 0;
     580    stats->offset.xErr = 0;
     581    stats->offset.yErr = 0;
     582
     583    stats->angle       = 0.0;
     584    stats->scale       = 1.0;
     585    stats->minMetric   = 0.0;
     586    stats->minVar      = 0.0;
     587    stats->nMatch      = 0;
     588    stats->nTest       = 0;
     589    stats->nSigma      = 0;
    582590
    583591    return (stats);
     
    914922    // fprintf (stderr, "sigma: nMatch: %d, nTest: %d, nTen: %d\n", stats->nMatch, stats->nTest, sort->data.U32[sort->n - 10]);
    915923
    916 
    917   psFree (sort);
     924    psFree (sort);
    918925    psFree (listNP);
    919926    psFree (gridNP);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/astrom/pmAstrometryObjects.h

    r26260 r37066  
    4242    float Color;                        ///< object color
    4343    float dMag;                         ///< error on object magnitude
     44    float SBinst;                       ///< surface brightness, used for Koppenhoefer correction
    4445}
    4546pmAstromObj;
  • branches/eam_branches/ipp-ops-20130712/psModules/src/astrom/pmAstrometryVisual.c

    r35768 r37066  
    946946    KapaSendLabel (kapa2, "X (FP)", KAPA_LABEL_XM);
    947947    KapaSendLabel (kapa2, "Y (FP)", KAPA_LABEL_YM);
    948     KapaSendLabel (kapa2, "pmAstromGridAngle residuals. Box: Correlation Peak.", KAPA_LABEL_XP);
     948    KapaSendLabel (kapa2, "pmAstromGridAngle red: raw, black: ref.", KAPA_LABEL_XP);
    949949
    950950    // plot the REF data.  (also calculate the plot ranges, accumulate the plot vectors)
     
    966966    KapaSetLimits(kapa2, &graphdata);
    967967
    968     psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
     968    psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_MIN  | PS_STAT_MAX );
    969969    psVectorStats (stats, zPlot, NULL, NULL, 0);
    970     float zero = stats->sampleMedian + 3.0;
    971     float range = 6.0;
    972 
     970    float range = stats->max - stats->min;
     971    range = PS_MAX (0.5, PS_MIN (6.0, range));
     972    float zero = stats->sampleMedian + 0.25*range;
     973
     974    float maxZ = zPlot->data.F32[0], minZ = zPlot->data.F32[0];
    973975    for (int i = 0; i < zPlot->n; i++) {
     976        maxZ = PS_MAX (maxZ, zPlot->data.F32[i]);
     977        minZ = PS_MIN (minZ, zPlot->data.F32[i]);
    974978        float value = (zero - zPlot->data.F32[i]) / range;
    975979        zPlot->data.F32[i] = PS_MAX(0.0, PS_MIN(1.0, value));
    976980    }
     981    fprintf (stderr, "ref mags: %f to %f (%f median)\n", minZ, maxZ, stats->sampleMedian);
    977982
    978983    // the point size will be scaled from the z vector
     
    9981003    psStatsInit(stats);
    9991004    psVectorStats (stats, zPlot, NULL, NULL, 0);
    1000     zero = stats->sampleMedian + 3.0;
    1001     range = 6.0;
    1002 
     1005    range = stats->max - stats->min;
     1006    range = PS_MAX (0.5, PS_MIN (6.0, range));
     1007    zero = stats->sampleMedian + 0.25*range;
     1008    // zero = stats->sampleMedian + 1.0;
     1009    // range = 6.0;
     1010
     1011    maxZ = zPlot->data.F32[0], minZ = zPlot->data.F32[0];
    10031012    for (int i = 0; i < zPlot->n; i++) {
     1013        maxZ = PS_MAX (maxZ, zPlot->data.F32[i]);
     1014        minZ = PS_MIN (minZ, zPlot->data.F32[i]);
    10041015        float value = (zero - zPlot->data.F32[i]) / range;
    10051016        zPlot->data.F32[i] = PS_MAX(0.0, PS_MIN(1.0, value));
    10061017    }
     1018    fprintf (stderr, "raw mags: %f to %f (%f median)\n", minZ, maxZ, stats->sampleMedian);
    10071019
    10081020    // the point size will be scaled from the z vector
  • branches/eam_branches/ipp-ops-20130712/psModules/src/astrom/pmAstrometryWCS.c

    r34271 r37066  
    576576    psFree (region);
    577577
     578    // XXX if the inversion fails, we probably do not have a valid transform anyway
     579    if (!chip->fromFPA) {
     580      psWarning ("failed to find a valid transformation");
     581      psFree (chip->toFPA);
     582      return false;
     583    }
     584
    578585    // this can take a very long time...
    579586    while (fpa->toSky->R < 0)
  • branches/eam_branches/ipp-ops-20130712/psModules/src/camera/pmFPAfile.c

    r33913 r37066  
    492492        return PM_FPA_FILE_CMF;
    493493    }
     494    if (!strcasecmp(type, "CFF"))     {
     495        return PM_FPA_FILE_CFF;
     496    }
    494497    if (!strcasecmp(type, "WCS"))     {
    495498        return PM_FPA_FILE_WCS;
     
    528531      return PM_FPA_FILE_LINEARITY;
    529532    }
    530     // deprecate this?
    531533    if (!strcasecmp(type, "ASTROM"))     {
    532         return PM_FPA_FILE_ASTROM_MODEL;
     534      return PM_FPA_FILE_ASTROM_MODEL;
    533535    }
    534536    if (!strcasecmp(type, "ASTROM.MODEL"))     {
     
    537539    if (!strcasecmp(type, "ASTROM.REFSTARS"))     {
    538540        return PM_FPA_FILE_ASTROM_REFSTARS;
     541    }
     542    if (!strcasecmp(type, "KH.CORRECT"))     {
     543        return PM_FPA_FILE_KH_CORRECT;
    539544    }
    540545    if (!strcasecmp(type, "SUBKERNEL"))     {
     
    562567      case PM_FPA_FILE_CMF:
    563568        return ("CMF");
     569      case PM_FPA_FILE_CFF:
     570        return ("CFF");
    564571      case PM_FPA_FILE_WCS:
    565572        return ("WCS");
     
    588595      case PM_FPA_FILE_ASTROM_REFSTARS:
    589596        return ("ASTROM.REFSTARS");
     597      case PM_FPA_FILE_KH_CORRECT:
     598        return ("KH.CORRECT");
    590599      case PM_FPA_FILE_SUBKERNEL:
    591600        return ("SUBKERNEL");
  • branches/eam_branches/ipp-ops-20130712/psModules/src/camera/pmFPAfile.h

    r33913 r37066  
    3434    PM_FPA_FILE_CMP,
    3535    PM_FPA_FILE_CMF,
     36    PM_FPA_FILE_CFF,
    3637    PM_FPA_FILE_WCS,
    3738    PM_FPA_FILE_RAW,
     
    4748    PM_FPA_FILE_ASTROM_MODEL,
    4849    PM_FPA_FILE_ASTROM_REFSTARS,
     50    PM_FPA_FILE_KH_CORRECT,
    4951    PM_FPA_FILE_SUBKERNEL,
    5052    PM_FPA_FILE_SRCTEXT,
  • branches/eam_branches/ipp-ops-20130712/psModules/src/camera/pmFPAfileDefine.c

    r35561 r37066  
    103103
    104104    type = psMetadataLookupStr(&status, data, "FILE.TYPE");
     105    if (!type) {
     106        psError(PM_ERR_CONFIG, true, "FILE.TYPE is not defined for %s\n", name);
     107        psFree(file);
     108        return NULL;
     109    }
     110
    105111    file->type = pmFPAfileTypeFromString(type);
    106112    if (file->type == PM_FPA_FILE_NONE) {
    107         psError(PM_ERR_CONFIG, true, "FILE.TYPE is not defined for %s\n", name);
     113        psError(PM_ERR_CONFIG, true, "FILE.TYPE %s is not registered in pmFPAfile.c:pmFPAfileTypeFromString\n", type);
    108114        psFree(file);
    109115        return NULL;
  • branches/eam_branches/ipp-ops-20130712/psModules/src/camera/pmFPAfileFitsIO.c

    r29833 r37066  
    150150      case PM_FPA_FILE_PSF:
    151151      case PM_FPA_FILE_ASTROM_MODEL:
    152       case PM_FPA_FILE_ASTROM_REFSTARS: {
     152      case PM_FPA_FILE_ASTROM_REFSTARS:
     153      case PM_FPA_FILE_KH_CORRECT:
     154        {
    153155          pmHDU *hdu = pmFPAviewThisHDU(view, fpa);
    154156          if (hdu) {
  • branches/eam_branches/ipp-ops-20130712/psModules/src/camera/pmFPAfileIO.c

    r35561 r37066  
    3434#include "pmMoments.h"
    3535#include "pmModelFuncs.h"
     36#include "pmModelClass.h"
    3637#include "pmModel.h"
    3738#include "pmSourceMasks.h"
     
    3940#include "pmSourceDiffStats.h"
    4041#include "pmSourceSatstar.h"
     42#include "pmSourceLensing.h"
    4143#include "pmSource.h"
    4244#include "pmSourceFitModel.h"
     
    4749#include "pmPSF_IO.h"
    4850
     51#include "pmKHcorrect.h"
    4952#include "pmAstrometryModel.h"
    5053#include "pmAstrometryRefstars.h"
     
    222225      case PM_FPA_FILE_CMP:
    223226      case PM_FPA_FILE_CMF:
     227      case PM_FPA_FILE_CFF:
    224228      case PM_FPA_FILE_WCS:
    225229      case PM_FPA_FILE_SRCTEXT:
     
    231235      case PM_FPA_FILE_ASTROM_MODEL:
    232236        status = pmAstromModelReadForView (view, file, config);
     237        break;
     238      case PM_FPA_FILE_KH_CORRECT:
     239        status = pmKHcorrectReadForView (view, file, config);
    233240        break;
    234241      case PM_FPA_FILE_EXPNUM:
     
    317324      case PM_FPA_FILE_CMP:
    318325      case PM_FPA_FILE_CMF:
     326      case PM_FPA_FILE_CFF:
    319327      case PM_FPA_FILE_WCS:
    320328      case PM_FPA_FILE_PSF:
    321329      case PM_FPA_FILE_ASTROM_MODEL:
    322330      case PM_FPA_FILE_ASTROM_REFSTARS:
     331      case PM_FPA_FILE_KH_CORRECT:
    323332      case PM_FPA_FILE_JPEG:
    324333      case PM_FPA_FILE_KAPA:
     
    405414      }
    406415    }
     416    if (file->type == PM_FPA_FILE_KH_CORRECT) {
     417      psTrace("psModules.camera", 6, "skip write for %s, no write function defined", file->name);
     418      return true;
     419    }
    407420
    408421    // open the file if not yet opened
     
    483496      case PM_FPA_FILE_CMP:
    484497      case PM_FPA_FILE_CMF:
     498      case PM_FPA_FILE_CFF:
    485499        status = pmFPAviewWriteObjects (view, file, config);
    486500        break;
     
    496510      case PM_FPA_FILE_ASTROM_REFSTARS:
    497511        status = pmAstromRefstarsWriteForView (view, file, config);
     512        break;
     513
     514      case PM_FPA_FILE_KH_CORRECT:
     515        psError(PS_ERR_IO, true, "cannot write type KH.CORRECT (%s)", file->name);
    498516        break;
    499517
     
    567585      case PM_FPA_FILE_PATTERN:
    568586      case PM_FPA_FILE_CMF:
     587      case PM_FPA_FILE_CFF:
    569588      case PM_FPA_FILE_WCS:
    570589      case PM_FPA_FILE_PSF:
    571590      case PM_FPA_FILE_ASTROM_MODEL:
    572591      case PM_FPA_FILE_ASTROM_REFSTARS:
     592      case PM_FPA_FILE_KH_CORRECT:
    573593      case PM_FPA_FILE_LINEARITY:
    574594      case PM_FPA_FILE_EXPNUM:
     
    643663      case PM_FPA_FILE_CMP:
    644664      case PM_FPA_FILE_CMF:
     665      case PM_FPA_FILE_CFF:
    645666      case PM_FPA_FILE_WCS:
    646667      case PM_FPA_FILE_PSF:
    647668      case PM_FPA_FILE_ASTROM_MODEL:
    648669      case PM_FPA_FILE_ASTROM_REFSTARS:
     670      case PM_FPA_FILE_KH_CORRECT:
    649671      case PM_FPA_FILE_EXPNUM:
    650672        psTrace ("psModules.camera", 6, "NOT freeing %s (%s) : save for further analysis\n", file->filename, file->name);
     
    804826      case PM_FPA_FILE_PATTERN:
    805827      case PM_FPA_FILE_CMF:
     828      case PM_FPA_FILE_CFF:
    806829      case PM_FPA_FILE_WCS:
    807830      case PM_FPA_FILE_PSF:
    808831      case PM_FPA_FILE_ASTROM_MODEL:
    809832      case PM_FPA_FILE_ASTROM_REFSTARS:
     833      case PM_FPA_FILE_KH_CORRECT:
    810834      case PM_FPA_FILE_LINEARITY:
    811835      case PM_FPA_FILE_EXPNUM:
     
    10111035      case PM_FPA_FILE_EXPNUM:
    10121036      case PM_FPA_FILE_ASTROM_MODEL:
     1037      case PM_FPA_FILE_KH_CORRECT:
    10131038      case PM_FPA_FILE_SX:
    10141039      case PM_FPA_FILE_RAW:
     
    10161041      case PM_FPA_FILE_CMP:
    10171042      case PM_FPA_FILE_WCS:
     1043      case PM_FPA_FILE_CFF:
    10181044      case PM_FPA_FILE_JPEG:
    10191045      case PM_FPA_FILE_KAPA:
  • branches/eam_branches/ipp-ops-20130712/psModules/src/camera/pmReadoutFake.c

    r35768 r37066  
    2020#include "pmMoments.h"
    2121#include "pmModelFuncs.h"
     22#include "pmModelClass.h"
    2223#include "pmModel.h"
    2324#include "pmModelUtils.h"
    24 #include "pmModelClass.h"
    2525#include "pmSourceMasks.h"
    2626#include "pmSourceExtendedPars.h"
    2727#include "pmSourceDiffStats.h"
    2828#include "pmSourceSatstar.h"
     29#include "pmSourceLensing.h"
    2930#include "pmSource.h"
    3031#include "pmSourceFitModel.h"
     
    5455
    5556    psF32 *params = model->params->data.F32; // Model parameters
    56     psEllipseAxes axes = pmPSF_ModelToAxes(params, model->type); // Ellipse axes
     57    psEllipseAxes axes = pmPSF_ModelToAxes(params, model->class->useReff); // Ellipse axes
    5758    // Curiously, the minor axis can be larger than the major axis, so need to check.
    5859    if (axes.major >= axes.minor) {
     
    6162        axes.major = axes.minor;
    6263    }
    63     return pmPSF_AxesToModel(params, axes, model->type);
     64    return pmPSF_AxesToModel(params, axes, model->class->useReff);
    6465}
    6566
     
    121122            }
    122123
    123             flux /= normModel->modelFlux(normModel->params);
     124            flux /= normModel->class->modelFlux(normModel->params);
    124125            psFree(normModel);
    125126        }
     
    163164        float fakeRadius = 1.0;         // Radius of fake source
    164165        if (isfinite(minFlux)) {
    165             fakeRadius = PS_MAX(fakeRadius, fakeModel->modelRadius(fakeModel->params, minFlux));
     166            fakeRadius = PS_MAX(fakeRadius, fakeModel->class->modelRadius(fakeModel->params, minFlux));
    166167        }
    167168        if (radius > 0) {
  • branches/eam_branches/ipp-ops-20130712/psModules/src/concepts/pmConcepts.c

    r30049 r37066  
    578578}
    579579
     580int pmConceptsChipNumberFromName (pmFPA *fpa, char *name) {
     581
     582    for (int i = 0; i < fpa->chips->n; i++) {
     583        pmChip *chip = fpa->chips->data[i];
     584        if (!chip) continue;
     585        char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
     586        if (!thisone) continue;
     587        if (!strcmp (name, thisone)) return (i);
     588    }
     589    return -1;
     590}
     591
     592pmChip *pmConceptsChipFromName (pmFPA *fpa, char *name) {
     593
     594    for (int i = 0; i < fpa->chips->n; i++) {
     595        pmChip *chip = fpa->chips->data[i];
     596        if (!chip) continue;
     597        char *thisone = psMetadataLookupStr (NULL, chip->concepts, "CHIP.NAME");
     598        if (!thisone) continue;
     599        if (!strcmp (name, thisone)) return (chip);
     600    }
     601    return NULL;
     602}
     603
  • branches/eam_branches/ipp-ops-20130712/psModules/src/concepts/pmConcepts.h

    r22699 r37066  
    161161    );
    162162
     163// some utility functions:
     164int pmConceptsChipNumberFromName (pmFPA *fpa, char *name);
     165pmChip *pmConceptsChipFromName (pmFPA *fpa, char *name);
     166
    163167/// @}
    164168#endif
  • branches/eam_branches/ipp-ops-20130712/psModules/src/config/pmConfig.c

    r34234 r37066  
    965965                                  "Original replaced by -R option", newRule);
    966966        }
     967        psFree(camerasIter);
     968    }
     969
     970    // Look for command-line options for files to replace
     971    while ((argNum = psArgumentGet(*argc, argv, "-photcode-rule")) > 0) {
     972        psArgumentRemove(argNum, argc, argv);
     973        if (argNum >= *argc) {
     974            psError(PM_ERR_CONFIG, true,
     975                    "-photcode-rule provided without new rule.");
     976            psFree(config);
     977            return NULL;
     978        }
     979
     980        psString newrule = psStringCopy(argv[argNum]); // The filerule, to be modified
     981        psArgumentRemove(argNum, argc, argv);
     982
     983        psMetadata *cameras = psMetadataLookupMetadata(NULL, config->system, "CAMERAS"); // List of cameras
     984        if (!cameras) {
     985            psError(PM_ERR_CONFIG, false, "Unable to find CAMERAS in the site configuration.\n");
     986            return false;
     987        }
     988
     989        psMetadataIterator *camerasIter = psMetadataIteratorAlloc(cameras, PS_LIST_HEAD, NULL); // Iterator
     990        psMetadataItem *cameraItem;     // Item from iteration
     991        while ((cameraItem = psMetadataGetAndIncrement(camerasIter))) {
     992            // Silently ignore problems --- they will be caught later, because if the user wants the nominated
     993            // file and it's not available for that camera, then they will know.
     994
     995            if (cameraItem->type != PS_DATA_METADATA) {
     996                psTrace("psModules.config", 2,
     997                        "Entry %s in CAMERAS is not of type METADATA --- ignored.", cameraItem->name);
     998                continue;
     999            }
     1000            psMetadata *camera = cameraItem->data.md; // Camera configuration
     1001
     1002            psMetadataAddStr (camera, PS_LIST_TAIL, "PHOTCODE.RULE", PS_META_REPLACE, "original replaced by -photcode-rule option", newrule);
     1003        }
     1004        psFree(newrule);
    9671005        psFree(camerasIter);
    9681006    }
     
    18601898    }
    18611899
    1862     return psMetadataLookupMetadata(NULL, filerules, realname);
     1900    return psMetadataLookupMetadata(&mdok, filerules, realname);
    18631901}
    18641902
  • branches/eam_branches/ipp-ops-20130712/psModules/src/detrend/pmDetrendDB.c

    r35531 r37066  
    111111        DETREND_STRING_CASE(LINEARITY);
    112112        DETREND_STRING_CASE(AUXMASK);
     113        DETREND_STRING_CASE(KH_CORRECT);
    113114    default:
    114115        return NULL;
  • branches/eam_branches/ipp-ops-20130712/psModules/src/detrend/pmDetrendDB.h

    r35531 r37066  
    4040    PM_DETREND_TYPE_LINEARITY,
    4141    PM_DETREND_TYPE_AUXMASK,
     42    PM_DETREND_TYPE_KH_CORRECT,
    4243} pmDetrendType;
    4344
  • branches/eam_branches/ipp-ops-20130712/psModules/src/detrend/pmPattern.c

    r35270 r37066  
    12221222    }
    12231223    double max_XX = 0;
     1224#if (PS_TRACE_ON)
    12241225    double solution_V = 0;
    12251226    int i_peak = -1;
     1227#endif
    12261228    for (int i = 0; i < numChips + 4; i++) { // If any cells have no value of themself, set the matrix to 1.0.
    12271229      if (XX->data.F64[i][i] == 0.0) {
     
    12301232      if (XX->data.F64[i][i] > max_XX) {
    12311233        max_XX = XX->data.F64[i][i];
     1234#if (PS_TRACE_ON)
    12321235        solution_V = solution->data.F64[i];
    12331236        i_peak = i;
     1237#endif
    12341238      }
    12351239    }
  • branches/eam_branches/ipp-ops-20130712/psModules/src/extras/pmThreadTools.c

    r35768 r37066  
    2929#include "pmMoments.h"
    3030#include "pmModelFuncs.h"
     31#include "pmModelClass.h"
    3132#include "pmModel.h"
    3233#include "pmModelUtils.h"
    33 #include "pmModelClass.h"
    3434#include "pmSourceMasks.h"
    3535#include "pmSourceExtendedPars.h"
     
    3737#include "pmSourcePhotometry.h"
    3838#include "pmSourceSatstar.h"
     39#include "pmSourceLensing.h"
    3940#include "pmSource.h"
    4041
  • branches/eam_branches/ipp-ops-20130712/psModules/src/extras/pmVisual.c

    r34403 r37066  
    2222bool pmSourceVisualClose(void);
    2323
    24 // #include "pmHDU.h"
    25 // #include "pmFPA.h"
    26 // #include "pmFPAfile.h"
    27 // #include "pmAstrometryObjects.h"
    28 // #include "pmSubtractionStamps.h"
    29 // #include "pmTrend2D.h"
    30 // #include "pmResiduals.h"
    31 // #include "pmGrowthCurve.h"
    32 // #include "pmSpan.h"
    33 // #include "pmFootprintSpans.h"
    34 // #include "pmFootprint.h"
    35 // #include "pmPeaks.h"
    36 // #include "pmMoments.h"
    37 // #include "pmModelFuncs.h"
    38 // #include "pmModel.h"
    39 // #include "pmSourceMasks.h"
    40 // #include "pmSourceExtendedPars.h"
    41 // #include "pmSourceDiffStats.h"
    4224#include "pmSourceSatstar.h"
    43 // #include "pmSource.h"
    44 // #include "pmSourceFitModel.h"
    45 // #include "pmPSF.h"
    46 // #include "pmPSFtry.h"
    47 // #include "pmFPAExtent.h"
    48 // #include "pmAstrometryVisual.h"
    49 // #include "pmSubtractionVisual.h"
    50 // #include "pmStackVisual.h"
    51 // #include "pmSourceVisual.h"
    5225
    5326# if (HAVE_KAPA)
     
    160133}
    161134
     135
     136// ask the user to continue or not.  give up after 2 seconds.
     137bool pmVisualAskUserOrDump(bool *plotFlag, bool *dumpData)
     138{
     139    struct timeval timeout;
     140    fd_set fdSet;
     141    int status;
     142
     143    if (dumpData) *dumpData = false;
     144
     145    char key[10];
     146    if (plotFlag && dumpData) {
     147        fprintf (stderr, "[p]ause? [c]ontinue? [s]kip the rest of these plots? [d]ump the data? [a]bort all visual plots? (c) ");
     148    }
     149    if (plotFlag && !dumpData) {
     150        fprintf (stderr, "[p]ause? [c]ontinue? [s]kip the rest of these plots? [a]bort all visual plots? (c) ");
     151    }
     152    if (!plotFlag && dumpData) {
     153        fprintf (stderr, "[p]ause? [c]ontinue? [d]ump the data? [a]bort all visual plots? (c) ");
     154    }
     155    if (!plotFlag && !dumpData) {
     156        fprintf (stderr, "[p]ause? [c]ontinue? [a]bort all visual plots? (c) ");
     157    }
     158
     159    /* Wait up to 1.0 second for a response, then continue */
     160    timeout.tv_sec = 10;
     161    timeout.tv_usec = 0;
     162
     163    FD_ZERO (&fdSet);
     164    FD_SET (STDIN_FILENO, &fdSet);
     165
     166    status = select (1, &fdSet, NULL, NULL, &timeout);
     167    if (status <= 0) {
     168        fprintf (stderr, "\n");
     169        return true; // if no data, give up
     170    }
     171
     172    while (true) {
     173        if (!fgets(key, 8, stdin)) {
     174            psWarning("Unable to read option");
     175        }
     176        switch (key[0]) {
     177          case 's':
     178            if (plotFlag) *plotFlag = false;
     179            return true;
     180          case 'd':
     181            if (dumpData) *dumpData = true;
     182            return true;
     183          case 'a':
     184            isVisual = false;
     185            return true;
     186          case 'c':
     187          case '\n':
     188            return true;
     189          default:
     190            break;
     191        }
     192       
     193        if (plotFlag && dumpData) {
     194          fprintf (stderr, "[p]ause? [c]ontinue? [s]kip the rest of these plots? [d]ump the data? [a]bort all visual plots? (c) ");
     195        }
     196        if (plotFlag && !dumpData) {
     197          fprintf (stderr, "[p]ause? [c]ontinue? [s]kip the rest of these plots? [a]bort all visual plots? (c) ");
     198        }
     199        if (!plotFlag && dumpData) {
     200          fprintf (stderr, "[p]ause? [c]ontinue? [d]ump the data? [a]bort all visual plots? (c) ");
     201        }
     202        if (!plotFlag && !dumpData) {
     203          fprintf (stderr, "[p]ause? [c]ontinue? [a]bort all visual plots? (c) ");
     204        }
     205    }
     206    return true;
     207}
    162208
    163209bool pmVisualImStats(psImage *image, double *mean, double *stdev, double *min, double *max) {
  • branches/eam_branches/ipp-ops-20130712/psModules/src/extras/pmVisual.h

    r30623 r37066  
    5252 */
    5353bool pmVisualAskUser(bool *plotFlag);
     54
     55
     56/** Ask the user how to proceed.
     57 * At the user's request, this will disable diagnostic plotting.
     58 * @param plotFlag, set to false if this plot should be disabled in the future
     59 * @param dumpData, set to true if user requests a data dump
     60 */
     61bool pmVisualAskUserOrDump(bool *plotFlag, bool *dumpData);
    5462
    5563
     
    138146bool pmVisualInitGraph (int kapa, void *section, void *graphdata);
    139147bool pmVisualAskUser(bool *plotFlag);
     148bool pmVisualAskUserOrDump(bool *plotFlag, bool *dumpData);
    140149bool pmVisualScaleImage(int kapaFD, psImage *inImage,
    141150                        const char *name, int channel, bool clip);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/imcombine/pmPSFEnvelope.c

    r35455 r37066  
    2020#include "pmMoments.h"
    2121#include "pmModelFuncs.h"
     22#include "pmModelClass.h"
    2223#include "pmModel.h"
    2324#include "pmModelUtils.h"
    24 #include "pmModelClass.h"
    2525#include "pmSourceMasks.h"
    2626#include "pmSourceExtendedPars.h"
    2727#include "pmSourceDiffStats.h"
    2828#include "pmSourceSatstar.h"
     29#include "pmSourceLensing.h"
    2930#include "pmSource.h"
    3031#include "pmSourceFitModel.h"
     
    167168                        continue;
    168169                    }
    169                     model->modelSetLimits(PM_MODEL_LIMITS_MODERATE);
     170                    model->class->modelSetLimits(PM_MODEL_LIMITS_MODERATE);
    170171                    bool limits = true; // Model within limits?
    171172                    for (int j = 0; j < model->params->n && limits; j++) {
    172                         if (!model->modelLimits(PS_MINIMIZE_PARAM_MIN, j, model->params->data.F32, NULL) ||
    173                             !model->modelLimits(PS_MINIMIZE_PARAM_MAX, j, model->params->data.F32, NULL)) {
     173                        if (!model->class->modelLimits(PS_MINIMIZE_PARAM_MIN, j, model->params->data.F32, NULL) ||
     174                            !model->class->modelLimits(PS_MINIMIZE_PARAM_MAX, j, model->params->data.F32, NULL)) {
    174175                            limits = false;
    175176                        }
     
    245246                continue;
    246247            }
    247             float srcRadius = model->modelRadius(model->params, PS_SQR(VARIANCE_VAL)); // Radius for source
     248            float srcRadius = model->class->modelRadius(model->params, PS_SQR(VARIANCE_VAL)); // Radius for source
    248249            psFree(model);
    249250            if (srcRadius == 0) {
  • branches/eam_branches/ipp-ops-20130712/psModules/src/imcombine/pmStack.c

    r35455 r37066  
    4343// #define TEST_X 972
    4444// #define TEST_Y 3213
    45 #define TEST_X 3289
    46 #define TEST_Y 4810
    47 #define TEST_RADIUS 0.5                 // Radius to examine
     45//#define TEST_X 3289
     46//#define TEST_Y 4810
     47//#define TEST_RADIUS 0.5                 // Radius to examine
     48//MEH -- streak-like junk md04s065i
     49#define TEST_X 1129
     50#define TEST_Y 4256
     51#define TEST_RADIUS 2.0                 // Radius to examine
    4852# endif
    4953
     
    108112
    109113// KMM functions to do bimodality rejection of pixels
    110 float gaussian(float x, float m, float s) {
     114double gaussian(float x, float m, float s) {
    111115  return(pow(s * sqrt(2 * M_PI),-1) * exp(-0.5 * pow( (x - m) / s, 2)));
    112116}
     
    116120                         float *mU, float *sU,
    117121                         float *pi1, float *m1, float *s1,
    118                          float *pi2, float *m2, float *s2) {
     122                         float *pi2, float *m2, float *s2,
     123                         int xyrdebug) {
    119124  assert(values);
    120125  assert(values->type.type == PS_TYPE_F32);
     
    151156  }
    152157
     158  if (xyrdebug == 1) {
     159      fprintf(stderr,"KMM uni: %d %f %d (%f %f)\n",
     160              xyrdebug,logL_unimodal,discrepant_index,
     161              *mU,*sU);
     162  }
     163
    153164  // Do EM loop
    154165  float dL = 0;
     
    186197  *pi2 = 0.5;
    187198
    188   float g1,g2,norm;
     199  //MEH -- need to be double to help avoid 0 in norm
     200  double g1,g2,norm;
    189201  float w1,w2;
    190202
     
    203215/*            *m2,*s2,*pi2); */
    204216/*     } */
     217
     218    if (xyrdebug == 1) {
     219        fprintf(stderr,"KMM EM iter: %d %f %f %f %f (%f %f %e) (%f %f %e)\n",
     220                *iter,logL_unimodal,logL_bimodal,oldL,dL,
     221                *m1,*s1,*pi1,
     222                *m2,*s2,*pi2);
     223    }
     224
    205225    // Expectation/P-stage
    206226    for (i = 0; i < values->n; i++) { // Calculate probabilities for each mode
     
    208228      g2 = gaussian(values->data.F32[i],*m2,*s2);
    209229      norm = (*pi1 * g1 + *pi2 * g2);
    210       P1->data.F32[i] = (*pi1 * g1) / norm;
    211       P2->data.F32[i] = (*pi2 * g2) / norm;
     230      //MEH -- must protect denom from norm=0
     231      if (norm > 0) {
     232          P1->data.F32[i] = (*pi1 * g1) / norm;
     233          P2->data.F32[i] = (*pi2 * g2) / norm;
     234      } else {
     235          P1->data.F32[i] = 0.0;
     236          P2->data.F32[i] = 0.0;
     237      } 
     238 
     239      if (xyrdebug == 1) {
     240          fprintf(stderr,"KMM EM-P loop: %d %d %le %le %le\n",
     241                         *iter,i,norm,g1,g2);
     242      }
     243
    212244    }
    213245    // Maximization/M-stage
     
    231263      w1 += P1->data.F32[i];
    232264      w2 += P2->data.F32[i];
     265
     266      if (xyrdebug == 1) {
     267          fprintf(stderr,"KMM EM-M loop: %d %d (%f %f %f %e) (%f %f %f %e)\n",
     268                         *iter,i,*m1,values->data.F32[i],w1,P1->data.F32[i],*m2,values->data.F32[i],w2,P2->data.F32[i]);
     269      }
     270
    233271    }
    234272    *m1 /= w1;
     
    250288      *pi2 = 0.0;
    251289    }
    252     if (*s1 == 0) { // sigma may not be zero
    253       *s1 = KMM_SMALL_NUMBER * *m1;
    254     }
    255     if (*s2 == 0) { // sigma may not be zero
    256       *s2 = KMM_SMALL_NUMBER * *m2;
    257     }
     290    if (*s1 == 0) { // sigma may not be zero -- MEH -- nor <0 and need additive offset if m~0
     291      *s1 = fabsf(KMM_SMALL_NUMBER * *m1) + KMM_SMALL_NUMBER;
     292    }
     293    if (*s2 == 0) { // sigma may not be zero
     294      *s2 = fabsf(KMM_SMALL_NUMBER * *m2) + KMM_SMALL_NUMBER;
     295    }
     296
     297    if (xyrdebug == 1) {
     298        fprintf(stderr,"KMM EM end: %d %f %f %f %f (%f %e %e %f) (%f %e %e %f)\n",
     299                *iter,logL_unimodal,logL_bimodal,oldL,dL,
     300                *m1,*s1,*pi1,w1,
     301                *m2,*s2,*pi2,w2);
     302    }
     303
    258304  } // End EM phase
    259305
     
    267313    *Punimodal = 1.0;
    268314  }
     315
     316  if (xyrdebug == 1) {
     317      fprintf(stderr,"KMM calc Puni: %d %f %d %f\n",
     318              xyrdebug,lambda,df,*Punimodal);
     319  }
     320
    269321  psFree(P1);
    270322  psFree(P2);
    271323}
    272324
    273 static void KMMFindPopular(const psVector *values, float *Punimodal, float *mean, float *sigma, float *pi) {
     325static void KMMFindPopular(const psVector *values, float *Punimodal, float *mean, float *sigma, float *pi, int xyrdebug) {
    274326  float KMM_MINIMUM_PVALUE = 0.05; // Should be an option.
    275327  float mU,sU;
     
    283335               &mU,&sU,
    284336               &pi1,&m1,&s1,
    285                &pi2,&m2,&s2);
     337               &pi2,&m2,&s2,xyrdebug);
    286338/*   fprintf(stdout,"%g %g : %g %g %g : %g %g %g : %g %d\t", */
    287339/*        mU,sU, */
     
    783835                          psImageMaskType goodMask, // Value for good pixels
    784836                          bool safe,           // Safe combination?
     837                          int nminpix,         // Minimum number of input per pixel
    785838                          float invTotalWeight    // Inverse of total weight for all inputs
    786839                          )
     
    802855    CHECKPIX(x, y, "bad vs good : %x %x %x\n", maskValue, badMask, blankMask);
    803856
    804     switch (num) {
     857    //MEH -- hackish adding of lower limit for input per pixel
     858    int numN = num;
     859    if (num < nminpix) {
     860        CHECKPIX(x, y, "Nmin (%d) inputs (%d) to combine, pixel %d,%d is manually set bad\n", nminpix, numN, x, y);
     861        numN = 0;
     862    }
     863    switch (numN) {
    805864      case 0: {
    806865          // Nothing to combine: it's bad
     
    898957    psVector *pixelSuspects = buffer->suspects; // Is the pixel suspect?
    899958    psVector *pixelLimits = buffer->limits; // Is the pixel suspect?
     959    //MEH -- adding a debug option for TESTING xyr position but could be better..
     960    int xyrdebug = 0;
    900961
    901962    // KMM values;
     
    917978        // This should probably be an option
    918979        if (useKMM) {
    919           KMMFindPopular(pixelData,&Punimodal,&KMMmean,&KMMsigma,&KMMpi);
     980#ifdef TESTING
     981            if (PS_SQR(x - TEST_X) + PS_SQR(y - TEST_Y) <= PS_SQR(TEST_RADIUS)) {
     982                xyrdebug = 1;
     983            }
     984# endif
     985          KMMFindPopular(pixelData,&Punimodal,&KMMmean,&KMMsigma,&KMMpi,xyrdebug);
    920986          CHECKPIX(x,y,"KMM Popularity Contest: (%d,%d) Puni: %g Mean: %f Sigma %f Pi: %f\n",
    921987                   x,y,Punimodal,KMMmean,KMMsigma,KMMpi);
     
    14591525    bool useVariance,
    14601526    bool safe,
     1527    int nminpix,
    14611528    bool rejection)
    14621529{
     
    16331700            psImageMaskType goodMask = 0; // OR of mask bits in all good input pixels
    16341701            combineExtract(&num, &suspect, &badMask, &goodMask, buffer, combinedImage, combinedMask, combinedVariance, input, weights, exps, addVariance, reject, x, y, badMaskBits, suspectMaskBits);
    1635             combinePixels(combinedImage, combinedMask, combinedVariance, exp, expnum, expweight, num, buffer, x, y, blankMaskBits, badMask, goodMask, safe, totalExpWeight);
     1702            combinePixels(combinedImage, combinedMask, combinedVariance, exp, expnum, expweight, num, buffer, x, y, blankMaskBits, badMask, goodMask, safe, nminpix, totalExpWeight);
    16361703
    16371704            if (iter > 0) {
  • branches/eam_branches/ipp-ops-20130712/psModules/src/imcombine/pmStack.h

    r34842 r37066  
    6161                    bool useVariance,   ///< Use variance values for rejection?
    6262                    bool safe,          ///< Play safe with small numbers of input pixels (mask if N <= 2)?
     63                    int nminpix,        ///< Minimum number input per pixel to combine
    6364                    bool rejectInspect  ///< Reject pixels instead of marking them for inspection?
    6465    );
  • branches/eam_branches/ipp-ops-20130712/psModules/src/imcombine/pmSubtraction.c

    r35771 r37066  
    3737#define USE_KERNEL_ERR                  // Use kernel error image?
    3838#define NUM_COVAR_POS 5                 // Number of positions for covariance calculation
     39//MEH -- this is causing diffim fault 5 -- seems not as robust
    3940#define USE_LOGFIT_REJECT
    4041
  • branches/eam_branches/ipp-ops-20130712/psModules/src/imcombine/pmSubtractionSimple.c

    r35941 r37066  
    3434#include "pmSourceSatstar.h"
    3535
     36#include "pmSourceLensing.h"
    3637#include "pmSource.h"
    3738
  • branches/eam_branches/ipp-ops-20130712/psModules/src/imcombine/pmSubtractionStamps.c

    r34403 r37066  
    2121#include "pmMoments.h"
    2222#include "pmModelFuncs.h"
     23#include "pmModelClass.h"
    2324#include "pmModel.h"
    2425#include "pmSourceMasks.h"
     
    2627#include "pmSourceDiffStats.h"
    2728#include "pmSourceSatstar.h"
     29#include "pmSourceLensing.h"
    2830#include "pmSource.h"
    2931
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects

    • Property svn:ignore
      •  

        old new  
        1212pmSourceIO_CMF_PS1_V1.v1.c
        1313pmSourceIO_CMF_PS1_V4.c
         14pmSourceIO_CMF_PS1_V5.c
        1415pmSourceIO_CMF_PS1_SV1.c
        1516pmSourceIO_CMF_PS1_SV2.c
         17pmSourceIO_CMF_PS1_SV3.c
        1618pmSourceIO_CMF_PS1_DV1.c
        1719pmSourceIO_CMF_PS1_DV2.c
        1820pmSourceIO_CMF_PS1_DV3.c
        19 
         21pmSourceIO_CMF_PS1_DV4.c
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/Makefile.am

    r34823 r37066  
    2020        pmModelClass.c \
    2121        pmModelUtils.c \
     22        pmModel_CentralPixel.c \
    2223        pmSource.c \
    2324        pmPhotObj.c \
     
    3940        pmSourceIO_SX.c \
    4041        pmSourceIO_CMP.c \
     42        pmSourceIO_CFF.c \
    4143        pmSourceIO_SMPDATA.c \
    4244        pmSourceIO_PS1_DEV_0.c \
     
    4749        pmSourceIO_CMF_PS1_V3.c \
    4850        pmSourceIO_CMF_PS1_V4.c \
     51        pmSourceIO_CMF_PS1_V5.c \
    4952        pmSourceIO_CMF_PS1_SV1.c \
    5053        pmSourceIO_CMF_PS1_SV2.c \
     54        pmSourceIO_CMF_PS1_SV3.c \
    5155        pmSourceIO_CMF_PS1_DV1.c \
    5256        pmSourceIO_CMF_PS1_DV2.c \
    5357        pmSourceIO_CMF_PS1_DV3.c \
     58        pmSourceIO_CMF_PS1_DV4.c \
    5459        pmSourceIO_MatchedRefs.c \
    5560        pmSourcePlots.c \
     
    7479        pmGrowthCurve.c \
    7580        pmSourceMatch.c \
     81        pmSourceLensing.c \
    7682        pmDetEff.c \
    7783        pmSourceGroups.c \
     
    97103        pmModelClass.h \
    98104        pmModelUtils.h \
     105        pmModel_CentralPixel.h \
    99106        pmSource.h \
    100107        pmPhotObj.h \
     
    110117        pmSourceOutputs.h \
    111118        pmSourceIO.h \
    112         pmSourceSatstar.h \ 
     119        pmSourceSatstar.h \
    113120        pmSourcePlots.h \
    114121        pmSourceVisual.h \
     
    122129        pmGrowthCurveGenerate.h \
    123130        pmSourceMatch.h \
     131        pmSourceLensing.h \
    124132        pmDetEff.h \
    125133        pmSourceGroups.h \
     
    142150pmSourceIO_CMF_PS1_V3.c \
    143151pmSourceIO_CMF_PS1_V4.c \
     152pmSourceIO_CMF_PS1_V5.c \
    144153pmSourceIO_CMF_PS1_DV1.c \
    145154pmSourceIO_CMF_PS1_DV2.c \
    146155pmSourceIO_CMF_PS1_DV3.c \
     156pmSourceIO_CMF_PS1_DV4.c \
    147157pmSourceIO_CMF_PS1_SV1.c \
    148 pmSourceIO_CMF_PS1_SV2.c
     158pmSourceIO_CMF_PS1_SV2.c \
     159pmSourceIO_CMF_PS1_SV3.c
    149160
    150161pmSourceIO_CMF_PS1_V1.c : pmSourceIO_CMF.c.in mksource.pl
     
    160171        mksource.pl pmSourceIO_CMF.c.in PS1_V4 pmSourceIO_CMF_PS1_V4.c
    161172
     173pmSourceIO_CMF_PS1_V5.c : pmSourceIO_CMF.c.in mksource.pl
     174        mksource.pl pmSourceIO_CMF.c.in PS1_V5 pmSourceIO_CMF_PS1_V5.c
     175
    162176pmSourceIO_CMF_PS1_DV1.c : pmSourceIO_CMF.c.in mksource.pl
    163177        mksource.pl pmSourceIO_CMF.c.in PS1_DV1 pmSourceIO_CMF_PS1_DV1.c
     
    169183        mksource.pl pmSourceIO_CMF.c.in PS1_DV3 pmSourceIO_CMF_PS1_DV3.c
    170184
     185pmSourceIO_CMF_PS1_DV4.c : pmSourceIO_CMF.c.in mksource.pl
     186        mksource.pl pmSourceIO_CMF.c.in PS1_DV4 pmSourceIO_CMF_PS1_DV4.c
     187
    171188pmSourceIO_CMF_PS1_SV1.c : pmSourceIO_CMF.c.in mksource.pl
    172189        mksource.pl pmSourceIO_CMF.c.in PS1_SV1 pmSourceIO_CMF_PS1_SV1.c
     
    175192        mksource.pl pmSourceIO_CMF.c.in PS1_SV2 pmSourceIO_CMF_PS1_SV2.c
    176193
     194pmSourceIO_CMF_PS1_SV3.c : pmSourceIO_CMF.c.in mksource.pl
     195        mksource.pl pmSourceIO_CMF.c.in PS1_SV3 pmSourceIO_CMF_PS1_SV3.c
     196
    177197# EXTRA_DIST = pmErrorCodes.h.in pmErrorCodes.dat pmErrorCodes.c.in
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/mksource.pl

    r34403 r37066  
    1919               "PS1_V3", 3,
    2020               "PS1_V4", 4,
     21               "PS1_V5", 5,
    2122    );
    2223%cmfmodes_dv = ("PS1_DV1", 1,
    2324                "PS1_DV2", 2,
    2425                "PS1_DV3", 3,
     26                "PS1_DV4", 4,
    2527    );
    2628%cmfmodes_sv = ("PS1_SV1", 1,
    2729                "PS1_SV2", 2,
     30                "PS1_SV3", 3,
    2831    );
    2932
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_DEV.c

    r35768 r37066  
    1616   * PM_PAR_SYY 5   - Y^2 term of elliptical contour (sqrt(2) / SigmaY)
    1717   * PM_PAR_SXY 6   - X*Y term of elliptical contour
    18    * PM_PAR_7   7   - normalized dev parameter
    1918
    2019   note that a standard dev model uses exp(-K*(z^(1/2n) - 1).  the additional elements (K,
     
    3736#include "pmMoments.h"
    3837#include "pmModelFuncs.h"
     38#include "pmModelClass.h"
    3939#include "pmModel.h"
    4040#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4241#include "pmSourceMasks.h"
    4342#include "pmSourceExtendedPars.h"
    4443#include "pmSourceDiffStats.h"
    4544#include "pmSourceSatstar.h"
     45#include "pmSourceLensing.h"
    4646#include "pmSource.h"
    4747#include "pmSourceFitModel.h"
     
    4949#include "pmPSFtry.h"
    5050#include "pmDetections.h"
     51#include "pmModel_CentralPixel.h"
    5152
    5253#include "pmModel_DEV.h"
     
    5859# define PM_MODEL_LIMITS          pmModelLimits_DEV
    5960# define PM_MODEL_RADIUS          pmModelRadius_DEV
     61# define PM_MODEL_SET_FWHM        pmModelSetFWHM_DEV
    6062# define PM_MODEL_FROM_PSF        pmModelFromPSF_DEV
    6163# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_DEV
     
    6365# define PM_MODEL_SET_LIMITS      pmModelSetLimits_DEV
    6466
    65 // f = exp(-z^0.125)
     67// f = exp(-kappa*r^(1/index))
     68// f = exp(-kappa*z^(0.5/index))
     69// index = 4, 0.5/index = 0.125
    6670# define ALPHA 0.125
    67 // # define ALPHA 0.25
    6871
    6972// the model is a function of the pixel coordinate (pixcoord[0,1] = x,y)
     
    7376// Lax parameter limits
    7477static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.001, 0.001, -1.0 };
    75 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 };
     78static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0 };
    7679
    7780// Moderate parameter limits
     
    8689static float *paramsMinUse = paramsMinLax;
    8790static float *paramsMaxUse = paramsMaxLax;
    88 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5 };
     91static float betaUse[] = { 2, 3e6, 5, 5, 10.0, 10.0, 0.5 };
    8992
    9093static bool limitsApply = true;         // Apply limits?
    91 
    92 # include "pmModel_SERSIC.CP.h"
    9394
    9495psF32 PM_MODEL_FUNC (psVector *deriv,
     
    109110    psAssert (z >= 0, "do not allow negative z values in model");
    110111
    111     float index = 0.5 / ALPHA;
    112     float par7 = ALPHA;
    113     float bn = 1.9992*index - 0.3271;
    114     float Io = exp(bn);
    115 
    116     psF32 f2 = bn*pow(z,ALPHA);
    117     psF32 f1 = Io*exp(-f2);
    118 
    119     psF32 radius = hypot(X, Y);
    120     if (radius < 1.0) {
    121 
    122         // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center
    123 
    124         // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
    125         psEllipseAxes axes;
    126         pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    127 
    128         // get the central pixel flux from the lookup table
    129         float xPix = (axes.major - centralPixelXo) / centralPixeldX;
    130         xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1);
    131         float yPix = (index - centralPixelYo) / centralPixeldY;
    132         yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1);
    133 
    134         // the integral of a Sersic has an analytical form as follows:
    135         float logGamma = lgamma(2.0*index);
    136         float bnFactor = pow(bn, 2.0*index);
    137         float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
    138 
    139         // XXX interpolate to get the value
    140         // XXX for the moment, just integerize
    141         // XXX I need to multiply by the integrated flux to get the flux in the central pixel
    142         float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm;
    143        
    144         float px1 = 1.0 / PAR[PM_PAR_SXX];
    145         float py1 = 1.0 / PAR[PM_PAR_SYY];
    146         float z10 = PS_SQR(px1);
    147         float z01 = PS_SQR(py1);
    148 
    149         // which pixels do we need for this interpolation?
    150         // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...)
    151         if ((X >= 0) && (Y >= 0)) {
    152             float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
    153             float V00 = Vcenter;
    154             float V10 = Io*exp(-bn*pow(z10,par7));
    155             float V01 = Io*exp(-bn*pow(z01,par7));
    156             float V11 = Io*exp(-bn*pow(z11,par7));
    157             f1 = interpolatePixels(V00, V10, V01, V11, X, Y);
    158         }
    159         if ((X < 0) && (Y >= 0)) {
    160             float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
    161             float V00 = Io*exp(-bn*pow(z10,par7));
    162             float V10 = Vcenter;
    163             float V01 = Io*exp(-bn*pow(z11,par7));
    164             float V11 = Io*exp(-bn*pow(z01,par7));
    165             f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y);
    166         }
    167         if ((X >= 0) && (Y < 0)) {
    168             float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
    169             float V00 = Io*exp(-bn*pow(z01,par7));
    170             float V10 = Io*exp(-bn*pow(z11,par7));
    171             float V01 = Vcenter;
    172             float V11 = Io*exp(-bn*pow(z10,par7));
    173             f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y));
    174         }
    175         if ((X < 0) && (Y < 0)) {
    176             float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
    177             float V00 = Io*exp(-bn*pow(z11,par7));
    178             float V10 = Io*exp(-bn*pow(z10,par7));
    179             float V01 = Io*exp(-bn*pow(z01,par7));
    180             float V11 = Vcenter;
    181             f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y));
    182         }
     112    // for DEV, we can hard-wire kappa(4):
     113    // float index = 4.0;
     114    float kappa = 7.670628;
     115
     116    // r = sqrt(z)
     117    float q = kappa*pow(z,ALPHA);
     118    float f0 = exp(-q);
     119
     120    assert (isfinite(q));
     121
     122    // only worry about the central pixels at most
     123    float radius = hypot(X, Y);
     124    if (radius <= 1.5) {
     125        // Nsub ~ 10*index^2 + 1
     126        psEllipseAxes axes = pmPSF_ModelToAxes(PAR, true); // DEV uses Reff
     127        int Nsub = 2 * ((int)(25 / axes.minor)) + 1;
     128        Nsub = PS_MIN (Nsub, 121);
     129        Nsub = PS_MAX (Nsub, 11);
     130        f0 = pmModelCP_SersicSubpix (X, Y, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], 4.0, Nsub);
    183131    }   
    184 
    185     psF32 z0 = PAR[PM_PAR_I0]*f1;
    186     psF32 f0 = PAR[PM_PAR_SKY] + z0;
    187 
    188     assert (isfinite(f2));
     132    assert (isfinite(f0));
     133
     134    float f1 = PAR[PM_PAR_I0]*f0;
     135    float f = PAR[PM_PAR_SKY] + f1;
     136
    189137    assert (isfinite(f1));
    190     assert (isfinite(z0));
    191     assert (isfinite(f0));
     138    assert (isfinite(f));
    192139
    193140    if (deriv != NULL) {
     
    195142
    196143        dPAR[PM_PAR_SKY]  = +1.0;
    197         dPAR[PM_PAR_I0]   = +2.0*f1; // XXX extra damping..
    198 
    199         // gradient is infinite for z = 0; saturate at z = 0.01
    200         psF32 z1 = (z < 0.01) ? z0*bn*ALPHA*pow(0.01,ALPHA - 1.0) : z0*bn*ALPHA*pow(z,ALPHA - 1.0);
    201 
    202         assert (isfinite(z1));
    203 
    204         dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]);
    205         dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]);
    206         dPAR[PM_PAR_SXX]  = +2.0*z1*px*px/PAR[PM_PAR_SXX];
    207         dPAR[PM_PAR_SYY]  = +2.0*z1*py*py/PAR[PM_PAR_SYY];
    208         dPAR[PM_PAR_SXY]  = -1.0*z1*X*Y;
    209     }
    210     return (f0);
     144        dPAR[PM_PAR_I0]   = +f0;
     145
     146        if (z > 0.01) {
     147          float z1 = f1*kappa*ALPHA*pow(z,ALPHA-1.0);
     148          dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px + Y*PAR[PM_PAR_SXY]);
     149          dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py + X*PAR[PM_PAR_SXY]);
     150          dPAR[PM_PAR_SXX]  = +2.0*z1*px*px/PAR[PM_PAR_SXX];
     151          dPAR[PM_PAR_SYY]  = +2.0*z1*py*py/PAR[PM_PAR_SYY];
     152          dPAR[PM_PAR_SXY]  = -1.0*z1*X*Y;
     153        } else {
     154          // gradient -> 0 for z -> 0, but has undef form
     155          float z1 = f1*kappa*ALPHA*pow(z,ALPHA);
     156          dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SXX] + PAR[PM_PAR_SXY]);
     157          dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SYY] + PAR[PM_PAR_SXY]);
     158          dPAR[PM_PAR_SXX]  = +2.0*z1*px/PAR[PM_PAR_SXX]/PAR[PM_PAR_SXX];
     159          dPAR[PM_PAR_SYY]  = +2.0*z1*py/PAR[PM_PAR_SYY]/PAR[PM_PAR_SYY];
     160          dPAR[PM_PAR_SXY]  = -1.0*z1;
     161        }
     162    }
     163    return (f);
    211164}
    212165
     
    292245bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
    293246{
     247    // for the moment, we are going to require moments and KronFlux
     248    if (!source->moments) return false;
     249    pmMoments *moments = source->moments;
     250
     251    if (!isfinite(moments->KronFlux)) return false;
     252    if (!isfinite(moments->Mrf)) return false;
     253    if (moments->Mrf < 0.0) return false;
     254
    294255    psF32 *PAR  = model->params->data.F32;
    295256
     
    297258    PAR[PM_PAR_SKY]  = 0.0;
    298259
    299     // set the shape parameters
    300     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, true)) {
    301       return false;
    302     }
    303 
    304     // the normalization is modified by the slope
    305     float index = 0.5 / ALPHA;
    306     float bn = 1.9992*index - 0.3271;
    307     float Io = exp(0.5*bn);
    308 
    309     // set the model normalization
    310     if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) {
    311       return false;
    312     }
    313     PAR[PM_PAR_I0] /= Io;
     260    psEllipseMoments emoments;
     261    emoments.x2 = moments->Mxx;
     262    emoments.xy = moments->Mxy;
     263    emoments.y2 = moments->Myy;
     264
     265    // force the axis ratio to be < 20.0
     266    psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0);
     267
     268    if (!isfinite(axes.major)) return false;
     269    if (!isfinite(axes.minor)) return false;
     270    if (!isfinite(axes.theta)) return false;
     271
     272    // Mxx, Mxy, Myy define the elliptical shape, but Mrf defines the width
     273    // the factor of 2.3 comes from Table 1 of Graham and Driver (2005)
     274    float scale = moments->Mrf / axes.major / 2.3;
     275    axes.major *= scale;
     276    axes.minor *= scale;
     277
     278    pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], axes, true);
     279
     280    // psEllipseAxes axes;
     281    // use the code in SetShape here to avoid doing this 2x
     282    // pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
     283
     284    // float norm = pmSersicNorm (4);  // hardwire
     285    float norm = 0.00168012;
     286    float normFlux = 2.0 * M_PI * axes.major * axes.minor * norm;
     287    PAR[PM_PAR_I0] = moments->KronFlux / normFlux;
    314288
    315289    // set the model position
     
    328302    psEllipseAxes axes;
    329303    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    330     float AspectRatio = axes.minor / axes.major;
    331 
    332     float index = 4.0;
    333     float bn = 1.9992*index - 0.3271;
    334 
    335     // the integral of a Sersic has an analytical form as follows:
    336     float logGamma = lgamma(2.0*index);
    337     float bnFactor = pow(bn, 2.0*index);
    338     float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
    339    
    340     psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio;
    341 
    342     return(Flux);
     304
     305    float norm = 0.00168012;
     306    float flux = PAR[PM_PAR_I0] * 2.0 * M_PI * axes.major * axes.minor * norm;
     307
     308    return(flux);
    343309}
    344310
     
    359325    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    360326
    361     // f = Io exp(-z^n) -> z^n = ln(Io/f)
    362     psF64 zn = log(PAR[PM_PAR_I0] / flux);
    363     psF64 radius = axes.major * sqrt (2.0) * pow(zn, 0.5 / ALPHA);
     327    // static value for DEV:
     328    float kappa = 7.670628;
     329
     330    // f = Io exp(-kappa*z^n) -> z^n = ln(Io/f) / kappa
     331    psF64 zn = log(PAR[PM_PAR_I0] / flux) / kappa;
     332    psF64 radius = axes.major * pow(zn, 0.5 / ALPHA);
    364333
    365334    psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)",
    366335              PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]);
    367336    return (radius);
     337}
     338
     339psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     340  return (NAN);
    368341}
    369342
     
    389362    // the 2D PSF model fits polarization terms (E0,E1,E2)
    390363    // convert to shape terms (SXX,SYY,SXY)
    391     bool useReff = pmModelUseReff (modelPSF->type);
     364    bool useReff = modelPSF->class->useReff;
    392365    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    393366        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    443416    // convert to shape terms (SXX,SYY,SXY)
    444417    // XXX user-defined value for limit?
    445     bool useReff = pmModelUseReff (model->type);
     418    bool useReff = model->class->useReff;
    446419    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    447420        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_DEV.h

    r35560 r37066  
    88psF64 pmModelFlux_DEV(const psVector *params);
    99psF64 pmModelRadius_DEV(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_DEV(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_DEV(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_DEV(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_EXP.c

    r35768 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838#include "pmSourceMasks.h"
    3939#include "pmSourceExtendedPars.h"
    4040#include "pmSourceDiffStats.h"
    4141#include "pmSourceSatstar.h"
     42#include "pmSourceLensing.h"
    4243#include "pmSource.h"
    4344#include "pmSourceFitModel.h"
     
    4546#include "pmPSFtry.h"
    4647#include "pmDetections.h"
     48#include "pmModel_CentralPixel.h"
    4749
    4850#include "pmModel_EXP.h"
     
    5456# define PM_MODEL_LIMITS          pmModelLimits_EXP
    5557# define PM_MODEL_RADIUS          pmModelRadius_EXP
     58# define PM_MODEL_SET_FWHM        pmModelSetFWHM_EXP
    5659# define PM_MODEL_FROM_PSF        pmModelFromPSF_EXP
    5760# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_EXP
     
    6265// 0.5 PIX: the parameters are defined in terms of pixel coords, so the incoming pixcoords
    6366// values need to be pixel coords
     67//
     68
     69// Notes on changing kappa value from 1.70056 to 1.678
     70// I'm using a functional form f(x,y) = Io exp(-kappa (r / r_e)). 
     71// The article by Graham & Driver (2005) uses a form Ie exp(-bn [(r / r_e) -1])
     72// which is equal to Ie exp(-bn (r / r_e)) exp(bn). 
     73// Thus, my Io = Ie exp(bn) and my kappa is their bn.
     74// My value of kappa is 1.700, their value for bn is 1.678., so I am off by a small amount there (1.5%). 
     75
     76
     77#define KAPPA_EXP 1.678
     78#define OLD_KAPP_EXP 1.70056
     79
    6480
    6581// Lax parameter limits
    6682static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.05, 0.05, -1.0 };
    67 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 };
     83static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0 };
    6884
    6985// Moderate parameter limits
     
    7894static float *paramsMinUse = paramsMinLax;
    7995static float *paramsMaxUse = paramsMaxLax;
    80 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5};
     96static float betaUse[] = { 2, 3e6, 5, 5, 10.0, 10.0, 0.5};
    8197
    8298static bool limitsApply = true;         // Apply limits?
    8399
    84 # include "pmModel_SERSIC.CP.h"
     100// # include "pmModel_SERSIC.CP.h"
     101
     102// the problems I'm having with the SERSIC-like functions are:
     103// 1) making sure I have the right functional form so that PAR[SXX,etc] represent R_eff (half-light radius)
     104// 2) getting the central pixel right
     105// 3) getting the derivaties right.
    85106
    86107psF32 PM_MODEL_FUNC (psVector *deriv,
     
    101122    psAssert (z >= 0, "do not allow negative z values in model");
    102123
    103     float index = 1.0;
    104     float par7 = 0.5;
    105     float bn = 1.9992*index - 0.3271;
    106     float Io = exp(bn);
    107 
    108     psF32 f2 = bn*sqrt(z);
    109     psF32 f1 = Io*exp(-f2);
    110 
     124    // for EXP, we can hard-wire kappa(1):
     125    // float index = 1.0;
     126    float kappa = KAPPA_EXP;
     127
     128    // sqrt(z) is r
     129    float q = kappa*sqrt(z);
     130    psF32 f0 = exp(-q);
     131
     132    assert (isfinite(q));
     133
     134    // only worry about the central 4 pixels at most
    111135    psF32 radius = hypot(X, Y);
    112     if (radius < 1.0) {
    113 
    114         // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center
    115 
    116         // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
    117         psEllipseAxes axes;
    118         pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    119 
    120         // get the central pixel flux from the lookup table
    121         float xPix = (axes.major - centralPixelXo) / centralPixeldX;
    122         xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1);
    123         float yPix = (index - centralPixelYo) / centralPixeldY;
    124         yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1);
    125 
    126         // the integral of a Sersic has an analytical form as follows:
    127         float logGamma = lgamma(2.0*index);
    128         float bnFactor = pow(bn, 2.0*index);
    129         float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
    130 
    131         // XXX interpolate to get the value
    132         // XXX for the moment, just integerize
    133         // XXX I need to multiply by the integrated flux to get the flux in the central pixel
    134         float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm;
    135        
    136         float px1 = 1.0 / PAR[PM_PAR_SXX];
    137         float py1 = 1.0 / PAR[PM_PAR_SYY];
    138         float z10 = PS_SQR(px1);
    139         float z01 = PS_SQR(py1);
    140 
    141         // which pixels do we need for this interpolation?
    142         // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...)
    143         if ((X >= 0) && (Y >= 0)) {
    144             float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
    145             float V00 = Vcenter;
    146             float V10 = Io*exp(-bn*pow(z10,par7));
    147             float V01 = Io*exp(-bn*pow(z01,par7));
    148             float V11 = Io*exp(-bn*pow(z11,par7));
    149             f1 = interpolatePixels(V00, V10, V01, V11, X, Y);
    150         }
    151         if ((X < 0) && (Y >= 0)) {
    152             float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
    153             float V00 = Io*exp(-bn*pow(z10,par7));
    154             float V10 = Vcenter;
    155             float V01 = Io*exp(-bn*pow(z11,par7));
    156             float V11 = Io*exp(-bn*pow(z01,par7));
    157             f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y);
    158         }
    159         if ((X >= 0) && (Y < 0)) {
    160             float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
    161             float V00 = Io*exp(-bn*pow(z01,par7));
    162             float V10 = Io*exp(-bn*pow(z11,par7));
    163             float V01 = Vcenter;
    164             float V11 = Io*exp(-bn*pow(z10,par7));
    165             f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y));
    166         }
    167         if ((X < 0) && (Y < 0)) {
    168             float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
    169             float V00 = Io*exp(-bn*pow(z11,par7));
    170             float V10 = Io*exp(-bn*pow(z10,par7));
    171             float V01 = Io*exp(-bn*pow(z01,par7));
    172             float V11 = Vcenter;
    173             f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y));
    174         }
    175     }   
    176 
    177     psF32 z0 = PAR[PM_PAR_I0]*f1;
    178     psF32 f0 = PAR[PM_PAR_SKY] + z0;
    179 
    180     assert (isfinite(f2));
     136    if (radius <= 1.5) {
     137        f0 = pmModelCP_SersicSubpix (X, Y, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], 1.0, 51);
     138    }
     139    assert (isfinite(f0));
     140
     141    psF32 f1 = PAR[PM_PAR_I0]*f0;
     142    psF32 f = PAR[PM_PAR_SKY] + f1;
     143
    181144    assert (isfinite(f1));
    182     assert (isfinite(z0));
    183     assert (isfinite(f0));
     145    assert (isfinite(f));
    184146
    185147    if (deriv != NULL) {
     
    187149
    188150        dPAR[PM_PAR_SKY]  = +1.0;
    189         dPAR[PM_PAR_I0]   = +f1;
    190 
    191         // gradient is infinite for z = 0; saturate at z = 0.01
    192         // z1 is -df/dz (the negative sign is canceled by most of dz/dPAR[i]
    193         psF32 z1 = (z < 0.01) ? 0.5*bn*z0/sqrt(0.01) : 0.5*bn*z0/sqrt(z);
    194 
    195         // XXX dampen SXX and SYY as in GAUSS?
    196         dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]);
    197         dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]);
    198         dPAR[PM_PAR_SXX]  = +2.0*z1*px*px/PAR[PM_PAR_SXX];
    199         dPAR[PM_PAR_SYY]  = +2.0*z1*py*py/PAR[PM_PAR_SYY];
    200         dPAR[PM_PAR_SXY]  = -1.0*z1*X*Y;
    201     }
    202     return (f0);
     151        dPAR[PM_PAR_I0]   = +f0;
     152
     153        if (z > 0.01) {
     154          float z1 = 0.5*f1*kappa/sqrt(z);
     155          dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px + Y*PAR[PM_PAR_SXY]);
     156          dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py + X*PAR[PM_PAR_SXY]);
     157          dPAR[PM_PAR_SXX]  = +2.0*z1*px*px/PAR[PM_PAR_SXX];
     158          dPAR[PM_PAR_SYY]  = +2.0*z1*py*py/PAR[PM_PAR_SYY];
     159          dPAR[PM_PAR_SXY]  = -1.0*z1*X*Y;
     160        } else {
     161          // gradient -> 0 for z -> 0, but has undef form
     162          float z1 = 0.5*f1*kappa;
     163          dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SXX] + PAR[PM_PAR_SXY]);
     164          dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SYY] + PAR[PM_PAR_SXY]);
     165          dPAR[PM_PAR_SXX]  = +2.0*z1*px/PAR[PM_PAR_SXX]/PAR[PM_PAR_SXX];
     166          dPAR[PM_PAR_SYY]  = +2.0*z1*py/PAR[PM_PAR_SYY]/PAR[PM_PAR_SYY];
     167          dPAR[PM_PAR_SXY]  = -1.0*z1;
     168        }
     169    }
     170    return (f);
    203171}
    204172
     
    284252bool PM_MODEL_GUESS (pmModel *model, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal)
    285253{
     254    // for the moment, we are going to require moments and KronFlux
     255    if (!source->moments) return false;
     256    pmMoments *moments = source->moments;
     257
     258    if (!isfinite(moments->KronFlux)) return false;
     259    if (!isfinite(moments->Mrf)) return false;
     260    if (moments->Mrf < 0.0) return false;
     261
    286262    psF32 *PAR  = model->params->data.F32;
    287263
     
    289265    PAR[PM_PAR_SKY]  = 0.0;
    290266
    291     // set the shape parameters
    292     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, true)) {
    293       return false;
    294     }
    295 
    296     // set the model normalization
    297     if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) {
    298       return false;
    299     }
     267    psEllipseMoments emoments;
     268    emoments.x2 = moments->Mxx;
     269    emoments.xy = moments->Mxy;
     270    emoments.y2 = moments->Myy;
     271
     272    // force the axis ratio to be < 20.0
     273    psEllipseAxes axes = psEllipseMomentsToAxes (emoments, 20.0);
     274
     275    if (!isfinite(axes.major)) return false;
     276    if (!isfinite(axes.minor)) return false;
     277    if (!isfinite(axes.theta)) return false;
     278
     279    // Mxx, Mxy, Myy define the elliptical shape, but Mrf defines the width
     280    float scale = moments->Mrf / axes.major;
     281    axes.major *= scale;
     282    axes.minor *= scale;
     283
     284    pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], axes, true);
     285
     286    // psEllipseAxes axes;
     287    // use the code in SetShape here to avoid doing this 2x
     288    // pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
     289
     290    // float norm = pmSersicNorm (4);  // hardwire
     291    float norm = 0.34578;
     292    float normFlux = 2.0 * M_PI * axes.major * axes.minor * norm;
     293    PAR[PM_PAR_I0] = moments->KronFlux / normFlux;
    300294
    301295    // set the model position
     
    306300    return(true);
    307301}
    308 
    309302// An exponential model is equivalent to a Sersic with index = 1.0
    310303psF64 PM_MODEL_FLUX (const psVector *params)
     
    314307    psEllipseAxes axes;
    315308    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    316     float AspectRatio = axes.minor / axes.major;
    317 
    318     float index = 1.0;
    319     float bn = 1.9992*index - 0.3271;
    320 
    321     // the integral of a Sersic has an analytical form as follows:
    322     float logGamma = lgamma(2.0*index);
    323     float bnFactor = pow(bn, 2.0*index);
    324     float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
    325    
    326     psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio;
    327 
    328     return(Flux);
     309
     310    // static value for EXP:
     311    float norm = 0.34578; // \int exp(-kappa*sqrt(z)) r dr
     312
     313    float flux = PAR[PM_PAR_I0] * 2.0 * M_PI * axes.major * axes.minor * norm;
     314
     315    return(flux);
    329316}
    330317
     
    345332    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    346333
    347     // f = Io exp(-sqrt(z)) -> sqrt(z) = ln(Io/f)
    348     psF64 zn = log(PAR[PM_PAR_I0] / flux);
    349     psF64 radius = axes.major * sqrt (2.0) * zn;
     334    // static value for EXP:
     335    float kappa = KAPPA_EXP;
     336
     337    // f = Io exp(-kappa*sqrt(z)) -> sqrt(z) = ln(Io/f) / kappa
     338    psF64 zn = log(PAR[PM_PAR_I0] / flux) / kappa;
     339    psF64 radius = axes.major * zn;
    350340
    351341    psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)",
    352342              PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]);
    353343    return (radius);
     344}
     345
     346psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     347  return (NAN);
    354348}
    355349
     
    375369    // the 2D PSF model fits polarization terms (E0,E1,E2)
    376370    // convert to shape terms (SXX,SYY,SXY)
    377     bool useReff = pmModelUseReff (modelPSF->type);
     371    bool useReff = modelPSF->class->useReff;
    378372    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    379373        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    429423    // convert to shape terms (SXX,SYY,SXY)
    430424    // XXX user-defined value for limit?
    431     bool useReff = pmModelUseReff (model->type);
     425    bool useReff = model->class->useReff;
    432426    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    433427        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
     
    501495    return;
    502496}
     497
     498# if (0)
     499void bilin_inter_function () {
     500        // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
     501        psEllipseAxes axes;
     502        pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
     503
     504        // get the central pixel flux from the lookup table
     505        float xPix = (axes.major - centralPixelXo) / centralPixeldX;
     506        xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1);
     507        float yPix = (index - centralPixelYo) / centralPixeldY;
     508        yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1);
     509
     510        // the integral of a Sersic has an analytical form as follows:
     511        float logGamma = lgamma(2.0*index);
     512        float bnFactor = pow(bn, 2.0*index);
     513        float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
     514
     515        // XXX interpolate to get the value
     516        // XXX for the moment, just integerize
     517        // XXX I need to multiply by the integrated flux to get the flux in the central pixel
     518        float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm;
     519       
     520        float px1 = 1.0 / PAR[PM_PAR_SXX];
     521        float py1 = 1.0 / PAR[PM_PAR_SYY];
     522        float z10 = PS_SQR(px1);
     523        float z01 = PS_SQR(py1);
     524
     525        // which pixels do we need for this interpolation?
     526        // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...)
     527        if ((X >= 0) && (Y >= 0)) {
     528            float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
     529            float V00 = Vcenter;
     530            float V10 = Io*exp(-bn*pow(z10,par7));
     531            float V01 = Io*exp(-bn*pow(z01,par7));
     532            float V11 = Io*exp(-bn*pow(z11,par7));
     533            f1 = interpolatePixels(V00, V10, V01, V11, X, Y);
     534        }
     535        if ((X < 0) && (Y >= 0)) {
     536            float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
     537            float V00 = Io*exp(-bn*pow(z10,par7));
     538            float V10 = Vcenter;
     539            float V01 = Io*exp(-bn*pow(z11,par7));
     540            float V11 = Io*exp(-bn*pow(z01,par7));
     541            f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y);
     542        }
     543        if ((X >= 0) && (Y < 0)) {
     544            float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
     545            float V00 = Io*exp(-bn*pow(z01,par7));
     546            float V10 = Io*exp(-bn*pow(z11,par7));
     547            float V01 = Vcenter;
     548            float V11 = Io*exp(-bn*pow(z10,par7));
     549            f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y));
     550        }
     551        if ((X < 0) && (Y < 0)) {
     552            float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
     553            float V00 = Io*exp(-bn*pow(z11,par7));
     554            float V10 = Io*exp(-bn*pow(z10,par7));
     555            float V01 = Io*exp(-bn*pow(z01,par7));
     556            float V11 = Vcenter;
     557            f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y));
     558        }
     559}
     560# endif
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_EXP.h

    r35560 r37066  
    88psF64 pmModelFlux_EXP(const psVector *params);
    99psF64 pmModelRadius_EXP(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_EXP(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_EXP(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_EXP(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_GAUSS.c

    r35768 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838#include "pmSourceMasks.h"
    3939#include "pmSourceExtendedPars.h"
    4040#include "pmSourceDiffStats.h"
    4141#include "pmSourceSatstar.h"
     42#include "pmSourceLensing.h"
    4243#include "pmSource.h"
    4344#include "pmSourceFitModel.h"
     
    5354# define PM_MODEL_GUESS           pmModelGuess_GAUSS
    5455# define PM_MODEL_LIMITS          pmModelLimits_GAUSS
     56# define PM_MODEL_SET_FWHM        pmModelSetFWHM_GAUSS
    5557# define PM_MODEL_RADIUS          pmModelRadius_GAUSS
    5658# define PM_MODEL_FROM_PSF        pmModelFromPSF_GAUSS
     
    6163// Lax parameter limits
    6264static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0 };
    63 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 };
     65static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0 };
    6466
    6567// Moderate parameter limits
     
    256258}
    257259
     260psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     261    return (2.35482004503*sigma);
     262}
     263
    258264// construct the PSF model from the FLT model and the psf
    259265bool PM_MODEL_FROM_PSF (pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf)
     
    278284    // the 2D PSF model fits polarization terms (E0,E1,E2)
    279285    // convert to shape terms (SXX,SYY,SXY)
    280     bool useReff = pmModelUseReff (modelPSF->type);
     286    bool useReff = modelPSF->class->useReff;
    281287    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    282288        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    330336    // the 2D PSF model fits polarization terms (E0,E1,E2)
    331337    // convert to shape terms (SXX,SYY,SXY)
    332     bool useReff = pmModelUseReff (model->type);
     338    bool useReff = model->class->useReff;
    333339    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    334340        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_GAUSS.h

    r35560 r37066  
    88psF64 pmModelFlux_GAUSS(const psVector *params);
    99psF64 pmModelRadius_GAUSS(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_GAUSS(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_GAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_GAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_PGAUSS.c

    r35768 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838#include "pmSourceMasks.h"
    3939#include "pmSourceExtendedPars.h"
    4040#include "pmSourceDiffStats.h"
    4141#include "pmSourceSatstar.h"
     42#include "pmSourceLensing.h"
    4243#include "pmSource.h"
    4344#include "pmSourceFitModel.h"
     
    5455# define PM_MODEL_LIMITS          pmModelLimits_PGAUSS
    5556# define PM_MODEL_RADIUS          pmModelRadius_PGAUSS
     57# define PM_MODEL_SET_FWHM        pmModelSetFWHM_PGAUSS
    5658# define PM_MODEL_FROM_PSF        pmModelFromPSF_PGAUSS
    5759# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_PGAUSS
     
    6163// Lax parameter limits
    6264static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0 };
    63 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 };
     65static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0 };
    6466
    6567// Moderate parameter limits
     
    323325}
    324326
     327// scale factor is constant for PGAUSS, I found it with the fwhm.sh script
     328psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     329    return (3.0063103*sigma);
     330}
     331
    325332bool PM_MODEL_FROM_PSF (pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf)
    326333{
     
    343350    // the 2D PSF model fits polarization terms (E0,E1,E2)
    344351    // convert to shape terms (SXX,SYY,SXY)
    345     bool useReff = pmModelUseReff (modelPSF->type);
     352    bool useReff = modelPSF->class->useReff;
    346353    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    347354        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    395402    // the 2D PSF model fits polarization terms (E0,E1,E2)
    396403    // convert to shape terms (SXX,SYY,SXY)
    397     bool useReff = pmModelUseReff (model->type);
     404    bool useReff = model->class->useReff;
    398405    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    399406        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_PGAUSS.h

    r35560 r37066  
    88psF64 pmModelFlux_PGAUSS(const psVector *params);
    99psF64 pmModelRadius_PGAUSS(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_PGAUSS(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_PGAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_PGAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_PS1_V1.c

    r35768 r37066  
    3535#include "pmMoments.h"
    3636#include "pmModelFuncs.h"
     37#include "pmModelClass.h"
    3738#include "pmModel.h"
    3839#include "pmModelUtils.h"
    39 #include "pmModelClass.h"
    4040#include "pmSourceMasks.h"
    4141#include "pmSourceExtendedPars.h"
    4242#include "pmSourceDiffStats.h"
    4343#include "pmSourceSatstar.h"
     44#include "pmSourceLensing.h"
    4445#include "pmSource.h"
    4546#include "pmSourceFitModel.h"
     
    5657# define PM_MODEL_LIMITS          pmModelLimits_PS1_V1
    5758# define PM_MODEL_RADIUS          pmModelRadius_PS1_V1
     59# define PM_MODEL_SET_FWHM        pmModelSetFWHM_PS1_V1
    5860# define PM_MODEL_FROM_PSF        pmModelFromPSF_PS1_V1
    5961# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_PS1_V1
     
    7072// Lax parameter limits
    7173static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, -1.0 };
    72 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
     74static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 20.0 };
    7375
    7476// Moderate parameter limits
    7577// Tolerate a small divot (k < 0)
    7678static float paramsMinModerate[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, -0.05 };
    77 static float paramsMaxModerate[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
     79static float paramsMaxModerate[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 20.0 };
    7880
    7981// Strict parameter limits
    8082// k = PAR_7 < 0 is very undesirable (big divot in the middle)
    8183static float paramsMinStrict[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 0.0 };
    82 static float paramsMaxStrict[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
     84static float paramsMaxStrict[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 20.0 };
    8385
    8486// Parameter limits to use
     
    335337}
    336338
     339// I used the script in models/fwhm.sh to generate the trend of FWHM scaling vs the K value
     340// FWHM = Scale * Sigma (not that PAR[PM_PAR_SXX] = sigma * sqrt(2)
     341//  K : z_hm  : FWHM
     342//  0 : 1.000 : 2.83
     343//  1 : 0.597 : 2.19
     344//  2 : 0.396 : 1.78
     345//  3 : 0.291 : 1.53
     346//  4 : 0.232 : 1.36
     347//  5 : 0.198 : 1.26
     348//  6 : 0.169 : 1.16
     349//  7 : 0.142 : 1.07
     350//  8 : 0.124 : 0.99
     351//  9 : 0.118 : 0.97
     352// 10 : 0.106 : 0.92
     353// 11 : 0.092 : 0.86
     354// 12 : 0.091 : 0.85
     355// 13 : 0.080 : 0.80
     356// 14 : 0.078 : 0.79
     357// 15 : 0.073 : 0.76
     358// 16 : 0.063 : 0.71
     359// 17 : 0.068 : 0.74
     360// 18 : 0.056 : 0.67
     361// 19 : 0.058 : 0.68
     362
     363// static float PS1_V1_Core[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0};
     364static float PS1_V1_Scale[] = {2.83, 2.19, 1.78, 1.53, 1.36, 1.26, 1.16, 1.07, 0.99, 0.97, 0.92, 0.86, 0.85, 0.80, 0.79, 0.76, 0.71, 0.74, 0.67, 0.68};
     365
     366psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     367
     368    psF32 *PAR = params->data.F32;
     369
     370    float core = PAR[PM_PAR_7];
     371
     372    if (!isfinite(core)) return (2.0*M_SQRT2*sigma);
     373
     374    // if PS1_V1_Core is defined as a set of integer steps, so we can simplify:
     375    int binCore = MAX(0, MIN (19, (int)core));
     376
     377    float scale = NAN;
     378    if (binCore == 0) {
     379        scale = (core - binCore + 0) * (PS1_V1_Scale[binCore + 1] - PS1_V1_Scale[binCore + 0]) + PS1_V1_Scale[binCore + 0];
     380    } else {
     381        scale = (core - binCore - 1) * (PS1_V1_Scale[binCore + 0] - PS1_V1_Scale[binCore - 1]) + PS1_V1_Scale[binCore - 1];
     382    }
     383
     384    return (scale * sigma);
     385}
     386
    337387bool PM_MODEL_FROM_PSF (pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf)
    338388{
    339 
    340389    psF32 *out = modelPSF->params->data.F32;
    341390    psF32 *in  = modelFLT->params->data.F32;
     
    356405    // the 2D PSF model fits polarization terms (E0,E1,E2)
    357406    // convert to shape terms (SXX,SYY,SXY)
    358     bool useReff = pmModelUseReff (modelPSF->type);
     407    bool useReff = modelPSF->class->useReff;
    359408    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    360409        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    410459    // convert to shape terms (SXX,SYY,SXY)
    411460    // XXX user-defined value for limit?
    412     bool useReff = pmModelUseReff (model->type);
     461    bool useReff = model->class->useReff;
    413462    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    414463        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_PS1_V1.h

    r35560 r37066  
    88psF64 pmModelFlux_PS1_V1(const psVector *params);
    99psF64 pmModelRadius_PS1_V1(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_PS1_V1(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_PS1_V1(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_PS1_V1(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_QGAUSS.c

    r35768 r37066  
    3535#include "pmMoments.h"
    3636#include "pmModelFuncs.h"
     37#include "pmModelClass.h"
    3738#include "pmModel.h"
    3839#include "pmModelUtils.h"
    39 #include "pmModelClass.h"
    4040#include "pmSourceMasks.h"
    4141#include "pmSourceExtendedPars.h"
    4242#include "pmSourceDiffStats.h"
    4343#include "pmSourceSatstar.h"
     44#include "pmSourceLensing.h"
    4445#include "pmSource.h"
    4546#include "pmSourceFitModel.h"
     
    5657# define PM_MODEL_LIMITS          pmModelLimits_QGAUSS
    5758# define PM_MODEL_RADIUS          pmModelRadius_QGAUSS
     59# define PM_MODEL_SET_FWHM        pmModelSetFWHM_QGAUSS
    5860# define PM_MODEL_FROM_PSF        pmModelFromPSF_QGAUSS
    5961# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_QGAUSS
     
    7072// Lax parameter limits
    7173static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, -1.0 };
    72 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
     74static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 20.0 };
    7375
    7476// Moderate parameter limits
    7577// Tolerate a small divot (k < 0)
    7678static float paramsMinModerate[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, -0.05 };
    77 static float paramsMaxModerate[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
     79static float paramsMaxModerate[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 20.0 };
    7880
    7981// Strict parameter limits
    8082// k = PAR_7 < 0 is very undesirable (big divot in the middle)
    8183static float paramsMinStrict[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 0.0 };
    82 static float paramsMaxStrict[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 20.0 };
     84static float paramsMaxStrict[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 20.0 };
    8385
    8486// Parameter limits to use
     
    336338}
    337339
     340// I used the script in models/fwhm.sh to generate the trend of FWHM scaling vs the K value
     341// FWHM = Scale * Sigma (not that PAR[PM_PAR_SXX] = sigma * sqrt(2)
     342//  K : z_hm  : FWHM
     343//  0 : 1.000 : 2.83
     344//  1 : 0.648 : 2.28
     345//  2 : 0.430 : 1.85
     346//  3 : 0.310 : 1.58
     347//  4 : 0.244 : 1.40
     348//  5 : 0.200 : 1.26
     349//  6 : 0.165 : 1.15
     350//  7 : 0.149 : 1.09
     351//  8 : 0.125 : 1.00
     352//  9 : 0.116 : 0.96
     353// 10 : 0.101 : 0.90
     354// 11 : 0.095 : 0.87
     355// 12 : 0.083 : 0.82
     356// 13 : 0.082 : 0.81
     357// 14 : 0.080 : 0.80
     358// 15 : 0.074 : 0.77
     359// 16 : 0.064 : 0.71
     360// 17 : 0.068 : 0.74
     361// 18 : 0.057 : 0.67
     362// 19 : 0.058 : 0.68
     363
     364// static float QGAUSS_Core[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0};
     365static float QGAUSS_Scale[] = {2.83, 2.28, 1.85, 1.58, 1.40, 1.26, 1.15, 1.09, 1.00, 0.96, 0.90, 0.87, 0.82, 0.81, 0.80, 0.77, 0.71, 0.74, 0.67, 0.68};
     366
     367psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     368
     369    psF32 *PAR = params->data.F32;
     370
     371    float core = PAR[PM_PAR_7];
     372
     373    if (!isfinite(core)) return (2.0*M_SQRT2*sigma);
     374
     375    // QGAUSS_Core is defined as a set of integer steps, so we can simplify:
     376    int binCore = MAX(0, MIN (19, (int)core));
     377
     378    float scale = NAN;
     379    if (binCore == 0) {
     380        scale = (core - binCore + 0) * (QGAUSS_Scale[binCore + 1] - QGAUSS_Scale[binCore + 0]) + QGAUSS_Scale[binCore + 0];
     381    } else {
     382        scale = (core - binCore - 1) * (QGAUSS_Scale[binCore + 0] - QGAUSS_Scale[binCore - 1]) + QGAUSS_Scale[binCore - 1];
     383    }
     384
     385    return (scale * sigma);
     386}
     387
    338388bool PM_MODEL_FROM_PSF (pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf)
    339389{
     
    357407    // the 2D PSF model fits polarization terms (E0,E1,E2)
    358408    // convert to shape terms (SXX,SYY,SXY)
    359     bool useReff = pmModelUseReff (modelPSF->type);
     409    bool useReff = modelPSF->class->useReff;
    360410    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    361411        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    415465    // the 2D PSF model fits polarization terms (E0,E1,E2)
    416466    // convert to shape terms (SXX,SYY,SXY)
    417     bool useReff = pmModelUseReff (model->type);
     467    bool useReff = model->class->useReff;
    418468    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    419469        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_QGAUSS.h

    r35560 r37066  
    88psF64 pmModelFlux_QGAUSS(const psVector *params);
    99psF64 pmModelRadius_QGAUSS(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_QGAUSS(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_QGAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_QGAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_RGAUSS.c

    r35768 r37066  
    3434#include "pmMoments.h"
    3535#include "pmModelFuncs.h"
     36#include "pmModelClass.h"
    3637#include "pmModel.h"
    3738#include "pmModelUtils.h"
    38 #include "pmModelClass.h"
    3939#include "pmSourceMasks.h"
    4040#include "pmSourceExtendedPars.h"
    4141#include "pmSourceDiffStats.h"
    4242#include "pmSourceSatstar.h"
     43#include "pmSourceLensing.h"
    4344#include "pmSource.h"
    4445#include "pmSourceFitModel.h"
     
    5556# define PM_MODEL_LIMITS          pmModelLimits_RGAUSS
    5657# define PM_MODEL_RADIUS          pmModelRadius_RGAUSS
     58# define PM_MODEL_SET_FWHM        pmModelSetFWHM_RGAUSS
    5759# define PM_MODEL_FROM_PSF        pmModelFromPSF_RGAUSS
    5860# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_RGAUSS
     
    6668// Lax parameter limits
    6769static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 1.25 };
    68 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 4.0 };
     70static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 4.0 };
    6971
    7072// Moderate parameter limits
     
    329331}
    330332
     333psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     334  return (NAN);
     335}
     336
    331337bool PM_MODEL_FROM_PSF (pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf)
    332338{
     
    350356    // the 2D PSF model fits polarization terms (E0,E1,E2)
    351357    // convert to shape terms (SXX,SYY,SXY)
    352     bool useReff = pmModelUseReff (modelPSF->type);
     358    bool useReff = modelPSF->class->useReff;
    353359    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    354360        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    403409    // the 2D PSF model fits polarization terms (E0,E1,E2)
    404410    // convert to shape terms (SXX,SYY,SXY)
    405     bool useReff = pmModelUseReff (model->type);
     411    bool useReff = model->class->useReff;
    406412    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    407413        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_RGAUSS.h

    r35560 r37066  
    88psF64 pmModelFlux_RGAUSS(const psVector *params);
    99psF64 pmModelRadius_RGAUSS(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_RGAUSS(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_RGAUSS(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_RGAUSS(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_SERSIC.c

    r35768 r37066  
    2020   * note that a Sersic model is usually defined in terms of R_e, the half-light radius.  This
    2121     construction does not include a factor of 2 in the X^2 term, etc, like for a Gaussian.
    22      Conversion from SXX, SYY, SXY to R_major, R_minor, theta can be done by using setting:
     22     Conversion from SXX, SYY, SXY to R_major, R_minor, theta can be done by using:
    2323     shape.sx = SXX / sqrt(2), shape.sy = SYY / sqrt(2), shape.sxy = SXY, then calling
    2424     psEllipseShapeToAxes, and multiplying the values of axes.major, axes.minor by sqrt(2)
     
    4343#include "pmMoments.h"
    4444#include "pmModelFuncs.h"
     45#include "pmModelClass.h"
    4546#include "pmModel.h"
    4647#include "pmModelUtils.h"
    47 #include "pmModelClass.h"
    4848#include "pmSourceMasks.h"
    4949#include "pmSourceExtendedPars.h"
    5050#include "pmSourceDiffStats.h"
    5151#include "pmSourceSatstar.h"
     52#include "pmSourceLensing.h"
    5253#include "pmSource.h"
    5354#include "pmSourceFitModel.h"
     
    5556#include "pmPSFtry.h"
    5657#include "pmDetections.h"
     58#include "pmModel_CentralPixel.h"
    5759
    5860#include "pmModel_SERSIC.h"
     
    6466# define PM_MODEL_LIMITS          pmModelLimits_SERSIC
    6567# define PM_MODEL_RADIUS          pmModelRadius_SERSIC
     68# define PM_MODEL_SET_FWHM        pmModelSetFWHM_SERSIC
    6669# define PM_MODEL_FROM_PSF        pmModelFromPSF_SERSIC
    6770# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_SERSIC
     
    7477
    7578// Lax parameter limits
    76 static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.001, 0.001, -1.0, 0.05 };
    77 static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 4.0 };
     79static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.001, 0.001, -1.0, 0.0625 };
     80static float paramsMaxLax[] = { 1.0e5, 1.0e9, 1.0e5, 1.0e5, 100, 100, 1.0, 1.0 };
    7881
    7982// Moderate parameter limits
     
    8891static float *paramsMinUse = paramsMinLax;
    8992static float *paramsMaxUse = paramsMaxLax;
    90 static float betaUse[] = { 1000, 3e6, 5, 5, 1.0, 1.0, 0.5, 2.0 };
     93static float betaUse[] = { 2, 3e6, 5, 5, 10.0, 10.0, 0.5, 1.0};
    9194
    9295static bool limitsApply = true;         // Apply limits?
    9396
    94 # include "pmModel_SERSIC.CP.h"
     97// # include "pmModel_SERSIC.CP.h"
    9598
    9699psF32 PM_MODEL_FUNC (psVector *deriv,
     
    111114    psAssert (z >= 0, "do not allow negative z values in model");
    112115
    113     float index = 0.5 / PAR[PM_PAR_7];
    114     float par7 = PAR[PM_PAR_7];
    115     float bn = 1.9992*index - 0.3271;
    116     float Io = exp(bn);
    117 
    118     psF32 f2 = bn*pow(z,par7);
    119     psF32 f1 = Io*exp(-f2);
     116    float Sindex = 0.5 / PAR[PM_PAR_7];
     117    float kappa = pmSersicKappa (Sindex);
     118
     119    float q = kappa*pow(z,PAR[PM_PAR_7]);
     120    psF32 f0 = exp(-q);
     121
     122    assert (isfinite(q));
    120123
    121124    psF32 radius = hypot(X, Y);
    122     if (radius < 1.0) {
    123 
    124         // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center
    125 
    126         // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
    127         psEllipseAxes axes;
    128         pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    129 
    130         // get the central pixel flux from the lookup table
    131         float xPix = (axes.major - centralPixelXo) / centralPixeldX;
    132         xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1);
    133         float yPix = (index - centralPixelYo) / centralPixeldY;
    134         yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1);
    135 
    136         // the integral of a Sersic has an analytical form as follows:
    137         float logGamma = lgamma(2.0*index);
    138         float bnFactor = pow(bn, 2.0*index);
    139         float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
    140 
    141         // XXX interpolate to get the value
    142         // XXX for the moment, just integerize
    143         // XXX I need to multiply by the integrated flux to get the flux in the central pixel
    144         float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm;
    145        
    146         float px1 = 1.0 / PAR[PM_PAR_SXX];
    147         float py1 = 1.0 / PAR[PM_PAR_SYY];
    148         float z10 = PS_SQR(px1);
    149         float z01 = PS_SQR(py1);
    150 
    151         // which pixels do we need for this interpolation?
    152         // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...)
    153         if ((X >= 0) && (Y >= 0)) {
    154             float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
    155             float V00 = Vcenter;
    156             float V10 = Io*exp(-bn*pow(z10,par7));
    157             float V01 = Io*exp(-bn*pow(z01,par7));
    158             float V11 = Io*exp(-bn*pow(z11,par7));
    159             f1 = interpolatePixels(V00, V10, V01, V11, X, Y);
    160         }
    161         if ((X < 0) && (Y >= 0)) {
    162             float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
    163             float V00 = Io*exp(-bn*pow(z10,par7));
    164             float V10 = Vcenter;
    165             float V01 = Io*exp(-bn*pow(z11,par7));
    166             float V11 = Io*exp(-bn*pow(z01,par7));
    167             f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y);
    168         }
    169         if ((X >= 0) && (Y < 0)) {
    170             float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
    171             float V00 = Io*exp(-bn*pow(z01,par7));
    172             float V10 = Io*exp(-bn*pow(z11,par7));
    173             float V01 = Vcenter;
    174             float V11 = Io*exp(-bn*pow(z10,par7));
    175             f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y));
    176         }
    177         if ((X < 0) && (Y < 0)) {
    178             float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
    179             float V00 = Io*exp(-bn*pow(z11,par7));
    180             float V10 = Io*exp(-bn*pow(z10,par7));
    181             float V01 = Io*exp(-bn*pow(z01,par7));
    182             float V11 = Vcenter;
    183             f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y));
    184         }
    185     }   
    186 
    187     psF32 z0 = PAR[PM_PAR_I0]*f1;
    188     psF32 f0 = PAR[PM_PAR_SKY] + z0;
    189 
    190     if (!isfinite(z0)) {
    191         fprintf(stderr, "z0 is not finite for %f %f %f %f %f.  Parameters: \n", X, Y, radius, z, f1);
     125    if (radius <= 1.5) {
     126        // Nsub ~ 10*index^2 + 1
     127        psEllipseAxes axes = pmPSF_ModelToAxes(PAR, true); // SERSIC model uses Reff
     128        int Nsub = 2 * ((int)(6.0*Sindex / axes.minor)) + 1;
     129        Nsub = PS_MIN (Nsub, 121);
     130        Nsub = PS_MAX (Nsub, 11);
     131        f0 = pmModelCP_SersicSubpix (X, Y, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], Sindex, Nsub);
     132    }
     133    if (!isfinite(f0)) {
     134        fprintf(stderr, "f0 is not finite for %f %f %f %f %f.  Parameters: \n", X, Y, radius, z, q);
    192135        fprintf(stderr, "%f %f %f %f %f %f %f %f\n", PAR[0], PAR[1], PAR[2], PAR[3], PAR[4],
    193136            PAR[5], PAR[6], PAR[7]);
    194137    }
    195 
    196     assert (isfinite(f2));
     138    assert (isfinite(f0));
     139
     140    psF32 f1 = PAR[PM_PAR_I0]*f0;
     141    psF32 f = PAR[PM_PAR_SKY] + f1;
     142
    197143    assert (isfinite(f1));
    198     assert (isfinite(z0));
    199     assert (isfinite(f0));
     144    assert (isfinite(f));
    200145
    201146    if (deriv != NULL) {
     
    203148
    204149        dPAR[PM_PAR_SKY]  = +1.0;
    205         dPAR[PM_PAR_I0]   = +f1;
    206 
    207         // gradient is infinite for z = 0; saturate at z = 0.01
    208         psF32 z1 = (z < 0.01) ? z0*bn*par7*pow(0.01,par7 - 1.0) : z0*bn*par7*pow(z,par7 - 1.0);
    209 
    210         dPAR[PM_PAR_7]    = (z < 0.01) ? -z0*pow(0.01,par7)*log(0.01) : -z0*f2*log(z);
    211         dPAR[PM_PAR_7]   *= 3.0;
    212 
    213         assert (isfinite(z1));
     150        dPAR[PM_PAR_I0]   = +f0;
     151
     152        if (z > 0.01) {
     153          float z1 = f1*kappa*PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7]-1.0);
     154          dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px + Y*PAR[PM_PAR_SXY]);
     155          dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py + X*PAR[PM_PAR_SXY]);
     156          dPAR[PM_PAR_SXX]  = +2.0*z1*px*px/PAR[PM_PAR_SXX];
     157          dPAR[PM_PAR_SYY]  = +2.0*z1*py*py/PAR[PM_PAR_SYY];
     158          dPAR[PM_PAR_SXY]  = -1.0*z1*X*Y;
     159          dPAR[PM_PAR_7]    = -1.0*f1*q*log(z);
     160        } else {
     161          // gradient -> 0 for z -> 0, but has undef form
     162          float z1 = f1*kappa*PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7]);
     163          dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SXX] + PAR[PM_PAR_SXY]);
     164          dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0/PAR[PM_PAR_SYY] + PAR[PM_PAR_SXY]);
     165          dPAR[PM_PAR_SXX]  = +2.0*z1*px/PAR[PM_PAR_SXX]/PAR[PM_PAR_SXX];
     166          dPAR[PM_PAR_SYY]  = +2.0*z1*py/PAR[PM_PAR_SYY]/PAR[PM_PAR_SYY];
     167          dPAR[PM_PAR_SXY]  = -1.0*z1;
     168          // dPAR[PM_PAR_7]    = -1.0*f1*q*log(z + 0.0001);
     169          dPAR[PM_PAR_7]    = -1.0*f1*q*log(z + 0.0001); // factor of 16 to reduce the gain
     170        }
    214171        assert (isfinite(dPAR[PM_PAR_7]));
    215 
    216         dPAR[PM_PAR_XPOS] = +1.0*z1*(2.0*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]);
    217         dPAR[PM_PAR_YPOS] = +1.0*z1*(2.0*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]);
    218         dPAR[PM_PAR_SXX]  = +2.0*z1*px*px/PAR[PM_PAR_SXX]; // XXX : increase drag?
    219         dPAR[PM_PAR_SYY]  = +2.0*z1*py*py/PAR[PM_PAR_SYY];
    220         dPAR[PM_PAR_SXY]  = -1.0*z1*X*Y;
    221     }
    222     return (f0);
     172    }
     173    return (f);
    223174}
    224175
     
    370321    psEllipseAxes axes;
    371322    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    372     float AspectRatio = axes.minor / axes.major;
    373 
    374     float index = 0.5 / PAR[PM_PAR_7];
    375     float bn = 1.9992*index - 0.3271;
    376 
    377     // the integral of a Sersic has an analytical form as follows:
    378     float logGamma = lgamma(2.0*index);
    379     float bnFactor = pow(bn, 2.0*index);
    380     float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
    381    
    382     psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio;
    383 
    384     return(Flux);
     323
     324    float Sindex = 0.5 / PAR[PM_PAR_7];
     325    float norm = pmSersicNorm (Sindex);
     326
     327    float flux = PAR[PM_PAR_I0] * 2.0 * M_PI * axes.major * axes.minor * norm;
     328
     329    return(flux);
    385330}
    386331
     
    401346    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    402347
     348    float Sindex = 0.5 / PAR[PM_PAR_7];
     349    float kappa = pmSersicKappa (Sindex);
     350
    403351    // f = Io exp(-z^n) -> z^n = ln(Io/f)
    404     psF64 zn = log(PAR[PM_PAR_I0] / flux);
    405     psF64 radius = axes.major * sqrt (2.0) * pow(zn, 0.5 / PAR[PM_PAR_7]);
     352    psF64 zn = log(PAR[PM_PAR_I0] / flux) / kappa;
     353    psF64 radius = axes.major * pow(zn, Sindex);
    406354
    407355    psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f), par 7 = %f",
    408356              PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], PAR[PM_PAR_7]);
    409357    return (radius);
     358}
     359
     360psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     361  return (NAN);
    410362}
    411363
     
    431383    // the 2D PSF model fits polarization terms (E0,E1,E2)
    432384    // convert to shape terms (SXX,SYY,SXY)
    433     bool useReff = pmModelUseReff (modelPSF->type);
     385    bool useReff = modelPSF->class->useReff;
    434386    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    435387        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     
    485437    // convert to shape terms (SXX,SYY,SXY)
    486438    // XXX user-defined value for limit?
    487     bool useReff = pmModelUseReff (model->type);
     439    bool useReff = model->class->useReff;
    488440    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    489441        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_SERSIC.h

    r35560 r37066  
    88psF64 pmModelFlux_SERSIC(const psVector *params);
    99psF64 pmModelRadius_SERSIC(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_SERSIC(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_SERSIC(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_SERSIC(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_TRAIL.c

    r35768 r37066  
    55 * The meaning of the parameters may thus vary depending on the specifics of the model.
    66 * All models which are used as a PSF representations share a few parameters, for which #
     7#include "pmModelClass.h"
    78 * define names are listed in pmModel.h:
    89
     
    3334#include "pmMoments.h"
    3435#include "pmModelFuncs.h"
     36#include "pmModelClass.h"
    3537#include "pmModel.h"
    3638#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3839#include "pmSourceMasks.h"
    3940#include "pmSourceExtendedPars.h"
    4041#include "pmSourceDiffStats.h"
    4142#include "pmSourceSatstar.h"
     43#include "pmSourceLensing.h"
    4244#include "pmSource.h"
    4345#include "pmSourceFitModel.h"
     
    5456# define PM_MODEL_LIMITS          pmModelLimits_TRAIL
    5557# define PM_MODEL_RADIUS          pmModelRadius_TRAIL
     58# define PM_MODEL_SET_FWHM        pmModelSetFWHM_TRAIL
    5659# define PM_MODEL_FROM_PSF        pmModelFromPSF_TRAIL
    5760# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_TRAIL
     
    6164// Lax parameter limits
    6265static float paramsMinLax[] = { -1.0e3, 1.0e-2, -1.0e2, -1.0e2,   0.5, -3.3, -0.5 };
    63 static float paramsMaxLax[] = {  1.0e5, 1.0e+8, +1.0e4, +1.0e4, 150.0, +3.3 , 5.0 };
     66static float paramsMaxLax[] = {  1.0e5, 1.00+9, +1.0e5, +1.0e5, 150.0, +3.3 , 5.0 };
    6467
    6568// Moderate parameter limits
     
    351354
    352355    psF32 *psfPAR  = source->modelPSF->params->data.F32;
    353     bool useReff = pmModelUseReff (source->modelPSF->type);
     356    bool useReff = source->modelPSF->class->useReff;
    354357
    355358    psEllipseAxes psfAxes;
     
    412415    // PAR_LENGTH is the unconvolved length.  add a bit for safety
    413416    return (0.5*PAR[PM_PAR_LENGTH] + 2);
     417}
     418
     419psF64 PM_MODEL_SET_FWHM (const psVector *params, psF64 sigma) {
     420  return (NAN);
    414421}
    415422
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/models/pmModel_TRAIL.h

    r35560 r37066  
    88psF64 pmModelFlux_TRAIL(const psVector *params);
    99psF64 pmModelRadius_TRAIL(const psVector *params, psF64 flux);
     10psF64 pmModelSetFWHM_TRAIL(const psVector *params, psF64 flux);
    1011bool pmModelFromPSF_TRAIL(pmModel *modelPSF, pmModel *modelFLT, const pmPSF *psf);
    1112bool  pmModelParamsFromPSF_TRAIL(pmModel *model, const pmPSF *psf, float Xo, float Yo, float Io);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmDetEff.c

    r34403 r37066  
    1717#include "pmMoments.h"
    1818#include "pmModelFuncs.h"
     19#include "pmModelClass.h"
    1920#include "pmModel.h"
    2021#include "pmModelUtils.h"
    21 #include "pmModelClass.h"
    2222#include "pmSourceMasks.h"
    2323#include "pmSourceExtendedPars.h"
    2424#include "pmSourceDiffStats.h"
    2525#include "pmSourceSatstar.h"
     26#include "pmSourceLensing.h"
    2627#include "pmSource.h"
    2728#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmFootprintCullPeaks.c

    r34800 r37066  
    2525bool dumpfootprints (pmFootprint *fp, pmFootprintSpans *fpSp);
    2626
    27  /*
    28   * Examine the peaks in a pmFootprint, and throw away the ones that are not sufficiently
    29   * isolated.  More precisely, for each peak find the highest coll that you'd have to traverse
    30   * to reach a still higher peak --- and if that coll's more (less?) than nsigma DN below your
    31   * starting point, discard the peak.
    32   */
     27/*
     28 * Examine the peaks in a pmFootprint, and throw away the ones that are not sufficiently
     29 * isolated.  More precisely, for each peak find the highest coll that you'd have to traverse
     30 * to reach a still higher peak --- and if that coll's more (less?) than nsigma DN below your
     31 * starting point, discard the peak.
     32 */
    3333
    3434# define IN_PEAK 1
     
    4848
    4949    if (fp->peaks == NULL || fp->peaks->n < 2) { // nothing to do
    50         return PS_ERR_NONE;
     50        return PS_ERR_NONE;
    5151    }
    5252
     
    9191
    9292        // max flux is above threshold for brightest peak
    93       pmPeak *maxPeak = NULL;
    94       for (int i = 0; i < fp->peaks->n; i++) {
    95         pmPeak *testPeak = fp->peaks->data[i];
    96         float this_peak = useSmoothedImage ? testPeak->smoothFlux : testPeak->rawFlux;
     93        pmPeak *maxPeak = NULL;
     94        for (int i = 0; i < fp->peaks->n; i++) {
     95            pmPeak *testPeak = fp->peaks->data[i];
     96            float this_peak = useSmoothedImage ? testPeak->smoothFlux : testPeak->rawFlux;
    9797       
    98         if (isfinite(this_peak)) {
    99           maxPeak = fp->peaks->data[i];
    100           break;
    101         }
    102       }
    103       psAssert(maxPeak,"maxPeak was not set in these peaks");
    104       //      = fp->peaks->data[0];
     98            if (isfinite(this_peak)) {
     99                maxPeak = fp->peaks->data[i];
     100                break;
     101            }
     102        }
     103        psAssert(maxPeak,"maxPeak was not set in these peaks");
     104        //      = fp->peaks->data[0];
    105105        float maxFlux = useSmoothedImage ? maxPeak->smoothFlux : maxPeak->rawFlux;
    106106
     
    130130        }
    131131#if (0)
    132         if (threshbounds->data.F32[threshbounds->n-1] > maxFlux) {
    133             psWarning ("upper limit: %f does not include max flux: %f",
    134                     threshbounds->data.F32[threshbounds->n-1], maxFlux);
    135         }
     132        if (threshbounds->data.F32[threshbounds->n-1] > maxFlux) {
     133            psWarning ("upper limit: %f does not include max flux: %f",
     134                       threshbounds->data.F32[threshbounds->n-1], maxFlux);
     135        }
    136136#endif
    137137        psHistogram *threshist = psHistogramAllocGeneric(threshbounds);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmGrowthCurve.c

    r34403 r37066  
    3030#include "pmMoments.h"
    3131#include "pmModelFuncs.h"
     32#include "pmModelClass.h"
    3233#include "pmModel.h"
    3334#include "pmModelUtils.h"
    34 #include "pmModelClass.h"
    3535#include "pmSourceMasks.h"
    3636#include "pmSourceExtendedPars.h"
    3737#include "pmSourceDiffStats.h"
    3838#include "pmSourceSatstar.h"
     39#include "pmSourceLensing.h"
    3940#include "pmSource.h"
    4041#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmGrowthCurveGenerate.c

    r34403 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmModel.c

    r34498 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    36 #include "pmModelClass.h"
    3737
    3838static void modelFree(pmModel *tmp)
    3939{
    4040    psTrace("psModules.objects", 10, "---- %s() begin ----\n", __func__);
     41    if (!tmp) return;
     42
    4143    psFree(tmp->params);
    4244    psFree(tmp->dparams);
     
    9092    }
    9193
    92     tmp->modelFunc          = class->modelFunc;
    93     tmp->modelFlux          = class->modelFlux;
    94     tmp->modelRadius        = class->modelRadius;
    95     tmp->modelLimits        = class->modelLimits;
    96     tmp->modelGuess         = class->modelGuess;
    97     tmp->modelFromPSF       = class->modelFromPSF;
    98     tmp->modelParamsFromPSF = class->modelParamsFromPSF;
    99     tmp->modelFitStatus     = class->modelFitStatus;
    100     tmp->modelSetLimits     = class->modelSetLimits;
     94    tmp->class = class;
     95
     96    // tmp->modelFunc          = class->modelFunc;
     97    // tmp->modelFlux          = class->modelFlux;
     98    // tmp->modelRadius        = class->modelRadius;
     99    // tmp->modelLimits        = class->modelLimits;
     100    // tmp->modelGuess         = class->modelGuess;
     101    // tmp->modelFromPSF       = class->modelFromPSF;
     102    // tmp->modelParamsFromPSF = class->modelParamsFromPSF;
     103    // tmp->modelFitStatus     = class->modelFitStatus;
     104    // tmp->modelSetLimits     = class->modelSetLimits;
    101105
    102106    psTrace("psModules.objects", 10, "---- %s() end ----\n", __func__);
     
    156160    psF32 tmpF;
    157161
    158     tmpF = model->modelFunc (NULL, model->params, x);
     162    tmpF = model->class->modelFunc (NULL, model->params, x);
    159163    psFree(x);
    160164    psTrace("psModules.objects", 10, "---- %s() end ----\n", __func__);
     
    176180    psF32 tmpF;
    177181
    178     tmpF = model->modelFunc (NULL, model->params, x);
     182    tmpF = model->class->modelFunc (NULL, model->params, x);
    179183    psFree(x);
    180184    psTrace("psModules.objects", 10, "---- %s() end ----\n", __func__);
     
    217221    // the options allow us to modify various aspects of the model
    218222    if (mode & PM_MODEL_OP_NORM) {
     223        // if we are including the sky, renormalizing should force use to normalized down the sky flux
     224        params->data.F32[PM_PAR_SKY] /= params->data.F32[PM_PAR_I0];
    219225        params->data.F32[PM_PAR_I0] = 1.0;
    220226    }
    221227    if (!(mode & PM_MODEL_OP_SKY)) {
    222228        params->data.F32[PM_PAR_SKY] = 0.0;
    223     }
     229    } 
    224230    if (mode & PM_MODEL_OP_CENTER) {
    225231        params->data.F32[PM_PAR_XPOS] = image->col0 + 0.5*image->numCols;
     
    281287            // add in the desired components for this coordinate
    282288            if (mode & PM_MODEL_OP_FUNC) {
    283                 pixelValue += model->modelFunc (NULL, params, x);
     289                pixelValue += model->class->modelFunc (NULL, params, x);
    284290            }
    285291
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmModel.h

    r31153 r37066  
    4747    bool isPCM;                         ///< is this model fitted with PSF-convolution?
    4848
     49    pmModelClass *class;
     50
    4951    // functions for this model which depend on the model class
    50     pmModelFunc          modelFunc;
    51     pmModelFlux          modelFlux;
    52     pmModelRadius        modelRadius;
    53     pmModelLimits        modelLimits;
    54     pmModelGuessFunc     modelGuess;
    55     pmModelFromPSFFunc   modelFromPSF;
    56     pmModelParamsFromPSF modelParamsFromPSF;
    57     pmModelFitStatusFunc modelFitStatus;
    58     pmModelSetLimitsFunc modelSetLimits;
     52   
     53    // pmModelFunc          modelFunc;
     54    // pmModelFlux          modelFlux;
     55    // pmModelRadius        modelRadius;
     56    // pmModelLimits        modelLimits;
     57    // pmModelGuessFunc     modelGuess;
     58    // pmModelFromPSFFunc   modelFromPSF;
     59    // pmModelParamsFromPSF modelParamsFromPSF;
     60    // pmModelFitStatusFunc modelFitStatus;
     61    // pmModelSetLimitsFunc modelSetLimits;
    5962};
    6063
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmModelClass.c

    r34259 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838
    3939#include "pmErrorCodes.h"
     
    5454
    5555static pmModelClass defaultModels[] = {
    56     {"PS_MODEL_GAUSS",        7, (pmModelFunc)pmModelFunc_GAUSS,   (pmModelFlux)pmModelFlux_GAUSS,   (pmModelRadius)pmModelRadius_GAUSS,   (pmModelLimits)pmModelLimits_GAUSS,   (pmModelGuessFunc)pmModelGuess_GAUSS,  (pmModelFromPSFFunc)pmModelFromPSF_GAUSS,  (pmModelParamsFromPSF)pmModelParamsFromPSF_GAUSS,  (pmModelFitStatusFunc)pmModelFitStatus_GAUSS,  (pmModelSetLimitsFunc)pmModelSetLimits_GAUSS  },
    57     {"PS_MODEL_PGAUSS",       7, (pmModelFunc)pmModelFunc_PGAUSS,  (pmModelFlux)pmModelFlux_PGAUSS,  (pmModelRadius)pmModelRadius_PGAUSS,  (pmModelLimits)pmModelLimits_PGAUSS,  (pmModelGuessFunc)pmModelGuess_PGAUSS, (pmModelFromPSFFunc)pmModelFromPSF_PGAUSS, (pmModelParamsFromPSF)pmModelParamsFromPSF_PGAUSS, (pmModelFitStatusFunc)pmModelFitStatus_PGAUSS, (pmModelSetLimitsFunc)pmModelSetLimits_PGAUSS },
    58     {"PS_MODEL_QGAUSS",       8, (pmModelFunc)pmModelFunc_QGAUSS,  (pmModelFlux)pmModelFlux_QGAUSS,  (pmModelRadius)pmModelRadius_QGAUSS,  (pmModelLimits)pmModelLimits_QGAUSS,  (pmModelGuessFunc)pmModelGuess_QGAUSS, (pmModelFromPSFFunc)pmModelFromPSF_QGAUSS, (pmModelParamsFromPSF)pmModelParamsFromPSF_QGAUSS, (pmModelFitStatusFunc)pmModelFitStatus_QGAUSS, (pmModelSetLimitsFunc)pmModelSetLimits_QGAUSS },
    59     {"PS_MODEL_PS1_V1",       8, (pmModelFunc)pmModelFunc_PS1_V1,  (pmModelFlux)pmModelFlux_PS1_V1,  (pmModelRadius)pmModelRadius_PS1_V1,  (pmModelLimits)pmModelLimits_PS1_V1,  (pmModelGuessFunc)pmModelGuess_PS1_V1, (pmModelFromPSFFunc)pmModelFromPSF_PS1_V1, (pmModelParamsFromPSF)pmModelParamsFromPSF_PS1_V1, (pmModelFitStatusFunc)pmModelFitStatus_PS1_V1, (pmModelSetLimitsFunc)pmModelSetLimits_PS1_V1 },
    60     {"PS_MODEL_RGAUSS",       8, (pmModelFunc)pmModelFunc_RGAUSS,  (pmModelFlux)pmModelFlux_RGAUSS,  (pmModelRadius)pmModelRadius_RGAUSS,  (pmModelLimits)pmModelLimits_RGAUSS,  (pmModelGuessFunc)pmModelGuess_RGAUSS, (pmModelFromPSFFunc)pmModelFromPSF_RGAUSS, (pmModelParamsFromPSF)pmModelParamsFromPSF_RGAUSS, (pmModelFitStatusFunc)pmModelFitStatus_RGAUSS, (pmModelSetLimitsFunc)pmModelSetLimits_RGAUSS },
    61     {"PS_MODEL_SERSIC",       8, (pmModelFunc)pmModelFunc_SERSIC,  (pmModelFlux)pmModelFlux_SERSIC,  (pmModelRadius)pmModelRadius_SERSIC,  (pmModelLimits)pmModelLimits_SERSIC,  (pmModelGuessFunc)pmModelGuess_SERSIC, (pmModelFromPSFFunc)pmModelFromPSF_SERSIC, (pmModelParamsFromPSF)pmModelParamsFromPSF_SERSIC, (pmModelFitStatusFunc)pmModelFitStatus_SERSIC, (pmModelSetLimitsFunc)pmModelSetLimits_SERSIC },
    62     {"PS_MODEL_EXP",          7, (pmModelFunc)pmModelFunc_EXP,     (pmModelFlux)pmModelFlux_EXP,     (pmModelRadius)pmModelRadius_EXP,     (pmModelLimits)pmModelLimits_EXP,     (pmModelGuessFunc)pmModelGuess_EXP,    (pmModelFromPSFFunc)pmModelFromPSF_EXP,    (pmModelParamsFromPSF)pmModelParamsFromPSF_EXP,    (pmModelFitStatusFunc)pmModelFitStatus_EXP,    (pmModelSetLimitsFunc)pmModelSetLimits_EXP    },
    63     {"PS_MODEL_DEV",          7, (pmModelFunc)pmModelFunc_DEV,     (pmModelFlux)pmModelFlux_DEV,     (pmModelRadius)pmModelRadius_DEV,     (pmModelLimits)pmModelLimits_DEV,     (pmModelGuessFunc)pmModelGuess_DEV,    (pmModelFromPSFFunc)pmModelFromPSF_DEV,    (pmModelParamsFromPSF)pmModelParamsFromPSF_DEV,    (pmModelFitStatusFunc)pmModelFitStatus_DEV,    (pmModelSetLimitsFunc)pmModelSetLimits_DEV    },
    64     {"PS_MODEL_TRAIL",        7, (pmModelFunc)pmModelFunc_TRAIL,   (pmModelFlux)pmModelFlux_TRAIL,   (pmModelRadius)pmModelRadius_TRAIL,   (pmModelLimits)pmModelLimits_TRAIL,   (pmModelGuessFunc)pmModelGuess_TRAIL,  (pmModelFromPSFFunc)pmModelFromPSF_TRAIL,  (pmModelParamsFromPSF)pmModelParamsFromPSF_TRAIL,  (pmModelFitStatusFunc)pmModelFitStatus_TRAIL,  (pmModelSetLimitsFunc)pmModelSetLimits_TRAIL  },
     56    {"PS_MODEL_GAUSS",        7, 0, (pmModelFunc)pmModelFunc_GAUSS,   (pmModelFlux)pmModelFlux_GAUSS,   (pmModelRadius)pmModelRadius_GAUSS,   (pmModelSetFWHM)pmModelSetFWHM_GAUSS,   (pmModelLimits)pmModelLimits_GAUSS,   (pmModelGuessFunc)pmModelGuess_GAUSS,  (pmModelFromPSFFunc)pmModelFromPSF_GAUSS,  (pmModelParamsFromPSF)pmModelParamsFromPSF_GAUSS,  (pmModelFitStatusFunc)pmModelFitStatus_GAUSS,  (pmModelSetLimitsFunc)pmModelSetLimits_GAUSS  },
     57    {"PS_MODEL_PGAUSS",       7, 0, (pmModelFunc)pmModelFunc_PGAUSS,  (pmModelFlux)pmModelFlux_PGAUSS,  (pmModelRadius)pmModelRadius_PGAUSS,  (pmModelSetFWHM)pmModelSetFWHM_PGAUSS,  (pmModelLimits)pmModelLimits_PGAUSS,  (pmModelGuessFunc)pmModelGuess_PGAUSS, (pmModelFromPSFFunc)pmModelFromPSF_PGAUSS, (pmModelParamsFromPSF)pmModelParamsFromPSF_PGAUSS, (pmModelFitStatusFunc)pmModelFitStatus_PGAUSS, (pmModelSetLimitsFunc)pmModelSetLimits_PGAUSS },
     58    {"PS_MODEL_QGAUSS",       8, 0, (pmModelFunc)pmModelFunc_QGAUSS,  (pmModelFlux)pmModelFlux_QGAUSS,  (pmModelRadius)pmModelRadius_QGAUSS,  (pmModelSetFWHM)pmModelSetFWHM_QGAUSS,  (pmModelLimits)pmModelLimits_QGAUSS,  (pmModelGuessFunc)pmModelGuess_QGAUSS, (pmModelFromPSFFunc)pmModelFromPSF_QGAUSS, (pmModelParamsFromPSF)pmModelParamsFromPSF_QGAUSS, (pmModelFitStatusFunc)pmModelFitStatus_QGAUSS, (pmModelSetLimitsFunc)pmModelSetLimits_QGAUSS },
     59    {"PS_MODEL_PS1_V1",       8, 0, (pmModelFunc)pmModelFunc_PS1_V1,  (pmModelFlux)pmModelFlux_PS1_V1,  (pmModelRadius)pmModelRadius_PS1_V1,  (pmModelSetFWHM)pmModelSetFWHM_PS1_V1,  (pmModelLimits)pmModelLimits_PS1_V1,  (pmModelGuessFunc)pmModelGuess_PS1_V1, (pmModelFromPSFFunc)pmModelFromPSF_PS1_V1, (pmModelParamsFromPSF)pmModelParamsFromPSF_PS1_V1, (pmModelFitStatusFunc)pmModelFitStatus_PS1_V1, (pmModelSetLimitsFunc)pmModelSetLimits_PS1_V1 },
     60    {"PS_MODEL_RGAUSS",       8, 0, (pmModelFunc)pmModelFunc_RGAUSS,  (pmModelFlux)pmModelFlux_RGAUSS,  (pmModelRadius)pmModelRadius_RGAUSS,  (pmModelSetFWHM)pmModelSetFWHM_RGAUSS,  (pmModelLimits)pmModelLimits_RGAUSS,  (pmModelGuessFunc)pmModelGuess_RGAUSS, (pmModelFromPSFFunc)pmModelFromPSF_RGAUSS, (pmModelParamsFromPSF)pmModelParamsFromPSF_RGAUSS, (pmModelFitStatusFunc)pmModelFitStatus_RGAUSS, (pmModelSetLimitsFunc)pmModelSetLimits_RGAUSS },
     61    {"PS_MODEL_SERSIC",       8, 1, (pmModelFunc)pmModelFunc_SERSIC,  (pmModelFlux)pmModelFlux_SERSIC,  (pmModelRadius)pmModelRadius_SERSIC,  (pmModelSetFWHM)pmModelSetFWHM_SERSIC,  (pmModelLimits)pmModelLimits_SERSIC,  (pmModelGuessFunc)pmModelGuess_SERSIC, (pmModelFromPSFFunc)pmModelFromPSF_SERSIC, (pmModelParamsFromPSF)pmModelParamsFromPSF_SERSIC, (pmModelFitStatusFunc)pmModelFitStatus_SERSIC, (pmModelSetLimitsFunc)pmModelSetLimits_SERSIC },
     62    {"PS_MODEL_EXP",          7, 1, (pmModelFunc)pmModelFunc_EXP,     (pmModelFlux)pmModelFlux_EXP,     (pmModelRadius)pmModelRadius_EXP,     (pmModelSetFWHM)pmModelSetFWHM_EXP,     (pmModelLimits)pmModelLimits_EXP,     (pmModelGuessFunc)pmModelGuess_EXP,    (pmModelFromPSFFunc)pmModelFromPSF_EXP,    (pmModelParamsFromPSF)pmModelParamsFromPSF_EXP,    (pmModelFitStatusFunc)pmModelFitStatus_EXP,    (pmModelSetLimitsFunc)pmModelSetLimits_EXP    },
     63    {"PS_MODEL_DEV",          7, 1, (pmModelFunc)pmModelFunc_DEV,     (pmModelFlux)pmModelFlux_DEV,     (pmModelRadius)pmModelRadius_DEV,     (pmModelSetFWHM)pmModelSetFWHM_DEV,     (pmModelLimits)pmModelLimits_DEV,     (pmModelGuessFunc)pmModelGuess_DEV,    (pmModelFromPSFFunc)pmModelFromPSF_DEV,    (pmModelParamsFromPSF)pmModelParamsFromPSF_DEV,    (pmModelFitStatusFunc)pmModelFitStatus_DEV,    (pmModelSetLimitsFunc)pmModelSetLimits_DEV    },
     64    {"PS_MODEL_TRAIL",        7, 0, (pmModelFunc)pmModelFunc_TRAIL,   (pmModelFlux)pmModelFlux_TRAIL,   (pmModelRadius)pmModelRadius_TRAIL,   (pmModelSetFWHM)pmModelSetFWHM_TRAIL,   (pmModelLimits)pmModelLimits_TRAIL,   (pmModelGuessFunc)pmModelGuess_TRAIL,  (pmModelFromPSFFunc)pmModelFromPSF_TRAIL,  (pmModelParamsFromPSF)pmModelParamsFromPSF_TRAIL,  (pmModelFitStatusFunc)pmModelFitStatus_TRAIL,  (pmModelSetLimitsFunc)pmModelSetLimits_TRAIL  },
    6565};
    6666
    6767static pmModelClass *models = NULL;
     68static psVector *modelClassLookupTable = NULL;  // translation between model types in header and here
    6869static int Nmodels = 0;
    6970
     
    135136    models = NULL;
    136137    Nmodels = 0;
     138    psFree(modelClassLookupTable);
     139    modelClassLookupTable = NULL;
    137140    return;
    138141}
     
    193196}
    194197
     198
     199bool pmModelClassWriteHeader(psMetadata *header)
     200{
     201    psMetadataAddS32(header, PS_LIST_TAIL, "MTNUM", PS_META_REPLACE, "number of model types", Nmodels);
     202    for (int i = 0; i < Nmodels; i++) {
     203        char modelNameKey[16];
     204        char modelValKey[16];
     205        sprintf(modelNameKey, "MTNAM%02d", i);
     206        sprintf(modelValKey,  "MTVAL%02d", i);
     207        psMetadataAddStr(header, PS_LIST_TAIL, modelNameKey, PS_META_REPLACE, "", models[i].name);
     208        psMetadataAddS32(header, PS_LIST_TAIL, modelValKey, PS_META_REPLACE, "", i);
     209    }
     210
     211    return true;
     212}
     213
     214bool pmModelClassReadHeader(psMetadata *header) {
     215    psFree(modelClassLookupTable);
     216
     217    bool status;
     218    int numHeaderModels = psMetadataLookupS32(&status, header, "MTNUM");
     219    if (!status) {
     220        return false;
     221    }
     222
     223    psVector *inputTypes = psVectorAlloc(numHeaderModels, PS_TYPE_S32);
     224    psVector *localTypes = psVectorAlloc(numHeaderModels, PS_TYPE_S32);
     225    int max_val = -1;
     226    for (int i = 0; i < numHeaderModels; i++) {
     227        char modelNameKey[16];
     228        char modelValKey[16];
     229        sprintf(modelNameKey, "MTNAM%02d", i);
     230        sprintf(modelValKey,  "MTVAL%02d", i);
     231        psString thisName = psMetadataLookupStr(&status, header, modelNameKey);
     232        int thisVal = psMetadataLookupS32(&status, header, modelValKey);
     233        if (thisVal > max_val) {
     234            max_val = thisVal;
     235        }
     236        inputTypes->data.S32[i] = thisVal;
     237        localTypes->data.S32[i] = pmModelClassGetType(thisName);
     238    }
     239    if (max_val < 0) {
     240        psFree(inputTypes);
     241        psFree(localTypes);
     242        return false;
     243    }
     244
     245    modelClassLookupTable = psVectorAlloc(max_val + 1, PS_TYPE_S32);
     246    psVectorInit(modelClassLookupTable, -1);
     247
     248    for (int i = 0; i < numHeaderModels; i++) {
     249        int thisVal = inputTypes->data.S32[i];
     250        int localVal = localTypes->data.S32[i];
     251        modelClassLookupTable->data.S32[thisVal] = localVal;
     252    }
     253    psFree(inputTypes);
     254    psFree(localTypes);
     255
     256    return true;
     257}
     258
     259pmModelType pmModelClassGetLocalType(pmModelType inputType) {
     260    pmModelType localType = -1;
     261
     262    if (modelClassLookupTable) {
     263        if (inputType >= 0 && inputType < modelClassLookupTable->n) {
     264            localType = modelClassLookupTable->data.S32[inputType];
     265        }
     266    } else {
     267        // no lookup table defined
     268        // for backwards compatability if inputType refers to a defined model, return it
     269        if (inputType >= 0 && pmModelClassGetName(inputType)) {
     270            localType = inputType;
     271        }
     272    }
     273
     274    return localType;
     275}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmModelClass.h

    r29004 r37066  
    3535    char *name;
    3636    int nParams;
     37    bool useReff;
    3738    pmModelFunc          modelFunc;
    3839    pmModelFlux          modelFlux;
    3940    pmModelRadius        modelRadius;
     41    pmModelSetFWHM       modelSetFWHM;
    4042    pmModelLimits        modelLimits;
    4143    pmModelGuessFunc     modelGuess;
     
    7678void pmModelClassSetLimits(pmModelLimitsType type);
    7779
     80// write keywords to header definining the model type values used by this program
     81bool pmModelClassWriteHeader(psMetadata *header);
     82// create a lookup table for translating input model type values to local model type values
     83bool pmModelClassReadHeader(psMetadata *header);
     84// translate input model type value to local value
     85pmModelType pmModelClassGetLocalType(pmModelType inputType);
    7886
    7987/// @}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmModelFuncs.h

    r35560 r37066  
    3636
    3737typedef enum {
    38     PM_MODEL_STATUS_NONE         = 0x00, ///< model fit not yet attempted, no other info
    39     PM_MODEL_STATUS_FITTED       = 0x01, ///< model fit completed
    40     PM_MODEL_STATUS_NONCONVERGE  = 0x02, ///< model fit did not converge
    41     PM_MODEL_STATUS_OFFIMAGE     = 0x04, ///< model fit drove out of range
    42     PM_MODEL_STATUS_BADARGS      = 0x08, ///< model fit called with invalid args
    43     PM_MODEL_STATUS_LIMITS       = 0x10, ///< model parameters hit limits
    44     PM_MODEL_STATUS_WEAK_FIT     = 0x20, ///< model fit met loose tolerance, but not tight tolerance
     38    PM_MODEL_STATUS_NONE           = 0x000, ///< model fit not yet attempted, no other info
     39    PM_MODEL_STATUS_FITTED         = 0x001, ///< model fit completed
     40    PM_MODEL_STATUS_NONCONVERGE    = 0x002, ///< model fit did not converge
     41    PM_MODEL_STATUS_OFFIMAGE       = 0x004, ///< model fit drove out of range
     42    PM_MODEL_STATUS_BADARGS        = 0x008, ///< model fit called with invalid args
     43    PM_MODEL_STATUS_LIMITS         = 0x010, ///< model parameters hit limits
     44    PM_MODEL_STATUS_WEAK_FIT       = 0x020, ///< model fit met loose tolerance, but not tight tolerance
     45    PM_MODEL_STATUS_NAN_CHISQ      = 0x040, ///< model fit failed with a NAN chisq
     46    PM_MODEL_SERSIC_PCM_FAIL_GUESS = 0x080, ///< sersic model fit failed on the initial moments-based guess
     47    PM_MODEL_SERSIC_PCM_FAIL_GRID  = 0x100, ///< sersic model fit failed on the grid search
     48    PM_MODEL_PCM_FAIL_GUESS        = 0x200, ///< non-sersic model fit failed on the initial moments-based guess
     49    PM_MODEL_BEST_FIT              = 0x400, ///< this model was the best fit and was subtracted
    4550} pmModelStatus;
    4651
     
    105110typedef psF64 (*pmModelRadius)(const psVector *params, double flux);
    106111
     112// This function returns the FWHM given the supplied sigma (major or minor)
     113typedef psF64 (*pmModelSetFWHM)(const psVector *params, double sigma);
     114
    107115//  This function provides the model guess parameters based on the details of
    108116//  the given source.
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmModelUtils.c

    r36288 r37066  
    3232#include "pmMoments.h"
    3333#include "pmModelFuncs.h"
     34#include "pmModelClass.h"
    3435#include "pmModel.h"
    3536#include "pmModelUtils.h"
    36 #include "pmModelClass.h"
    3737#include "pmSourceMasks.h"
    3838#include "pmSourceExtendedPars.h"
    3939#include "pmSourceDiffStats.h"
    4040#include "pmSourceSatstar.h"
     41#include "pmSourceLensing.h"
    4142#include "pmSource.h"
    4243#include "pmSourceFitModel.h"
     
    4445
    4546#include "pmErrorCodes.h"
    46 
    47 // XX static bool useModelVar = false;
    48 // XX
    49 // XX void pmModelSetModelVarOption (bool option) {
    50 // XX   useModelVar = option;
    51 // XX }
    52 // XX bool pmModelGetModelVarOption (void) {
    53 // XX   return useModelVar;
    54 // XX }
    5547
    5648/*****************************************************************************
     
    6759
    6860    // set model parameters for this source based on PSF information
    69     if (!modelEXT->modelFromPSF (modelPSF, modelEXT, psf)) {
     61    if (!modelEXT->class->modelFromPSF (modelPSF, modelEXT, psf)) {
    7062        psTrace ("psModules.objects", 3, "Failed to set model params from PSF");
    7163        psFree(modelPSF);
     
    8880
    8981    // set model parameters for this source based on PSF information
    90     if (!modelPSF->modelParamsFromPSF (modelPSF, psf, Xo, Yo, Io)) {
     82    if (!modelPSF->class->modelParamsFromPSF (modelPSF, psf, Xo, Yo, Io)) {
    9183        psFree(modelPSF);
    9284        return NULL;
     
    108100
    109101    // determine the normalized flux
    110     float normFlux = model->modelFlux (model->params);
     102    float normFlux = model->class->modelFlux (model->params);
    111103    assert (isfinite(normFlux));
    112104    assert (normFlux > 0);
     
    119111
    120112bool pmModelUseReff (pmModelType type) {
    121     bool useReff = false;
    122     useReff |= (type == pmModelClassGetType ("PS_MODEL_SERSIC"));
    123     useReff |= (type == pmModelClassGetType ("PS_MODEL_DEV"));
    124     useReff |= (type == pmModelClassGetType ("PS_MODEL_EXP"));
     113
     114    pmModelClass *class = pmModelClassSelect (type);
     115    psAssert (class, "undefined model class?");
     116    bool useReff = class->useReff;
    125117    return useReff;
    126118}
     
    128120// this function and the one below handle the two cases, where the model shape is uses R_eff or Sigma
    129121bool pmModelAxesToParams (float *Sxx, float *Sxy, float *Syy, psEllipseAxes axes, bool useReff)  {
     122
     123    // restrict axex to 0.5 here not below
     124    if (axes.minor < 0.2) axes.minor = 0.2;
     125    if (axes.major < 0.2) axes.major = 0.2;
    130126
    131127    psEllipseShape shape = psEllipseAxesToShape (axes);
     
    137133    // set the shape parameters
    138134    if (useReff) {
    139         *Sxx  = PS_MAX(0.5, shape.sx);
    140         *Syy  = PS_MAX(0.5, shape.sy);
     135        // *Sxx  = PS_MAX(0.5, shape.sx);
     136        // *Syy  = PS_MAX(0.5, shape.sy);
     137        *Sxx  = shape.sx;
     138        *Syy  = shape.sy;
    141139        *Sxy  = shape.sxy * 2.0;
    142140    } else {
    143         *Sxx  = PS_MAX(0.5, M_SQRT2*shape.sx);
    144         *Syy  = PS_MAX(0.5, M_SQRT2*shape.sy);
     141        // *Sxx  = PS_MAX(0.5, M_SQRT2*shape.sx);
     142        // *Syy  = PS_MAX(0.5, M_SQRT2*shape.sy);
     143        *Sxx  = M_SQRT2*shape.sx;
     144        *Syy  = M_SQRT2*shape.sy;
    145145        *Sxy  = shape.sxy;
    146146    }
     
    193193    if (!isfinite(axes.minor)) return false;
    194194    if (!isfinite(axes.theta)) return false;
     195    if (axes.major == 0) return false;
    195196
    196197    // Mxx, Mxy, Myy define the elliptical shape, but Mrf defines the width
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmModel_CentralPixel.c

    r36203 r37066  
    695695    int   npix = 0;
    696696
    697     float kappa = -0.275552 + 1.972625*Sindex + 0.003487 * PS_SQR(Sindex);
     697    // -0.275552 + 1.972625*Sindex + 0.003487 * PS_SQR(Sindex);
     698    float kappa = pmSersicKappa (Sindex);
    698699    float rindex = 0.5 / Sindex;
    699700
     
    703704
    704705    float delta = 1.0 / (float) Nsub;
    705     float off = -Nsub2 * delta;
    706     for (float ix = off; ix < 0.5; ix += delta) {
    707         for (float iy = off; iy < 0.5; iy += delta) {
    708 
    709             float dX = dx + ix;
    710             float dY = dy + iy;
     706    // float off = -Nsub2 * delta;
     707
     708    int Sx = (int) floor(dx / delta);
     709    int Sy = (int) floor(dy / delta);
     710
     711    for (int ix = -Nsub2; ix <= Nsub2; ix++) {
     712      float dX = delta * (Sx + ix);
     713      for (int iy = -Nsub2; iy <= Nsub2; iy++) {
     714        float dY = delta * (Sy + iy);
    711715            float z = PS_SQR(dX / Rxx) + PS_SQR(dY / Ryy) + dX * dY * Rxy;
    712716
    713717            float q = pow (z, rindex);
    714718            float f = exp(-kappa*q);
     719
     720            // if ((ix == 0) && (iy == 0)) {
     721            //   // fprintf (stderr, "this: %f  %f  %f  --  full : %f %f\n", z, q, f, flux, (float) npix);
     722            // }
    715723
    716724            flux += f;
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmMoments.h

    r32347 r37066  
    4444    float Myyyy;   ///< fourth moment
    4545
     46  // float wSum;    ///< window-weighted sum (NOT needed by lensing)
     47
    4648    float Sum;    ///< Pixel sum above sky (background).
    4749    float Peak;   ///< Peak counts above sky.
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPCM_MinimizeChisq.c

    r35768 r37066  
    3131#include "pmMoments.h"
    3232#include "pmModelFuncs.h"
     33#include "pmModelClass.h"
    3334#include "pmModel.h"
    3435#include "pmModelUtils.h"
    35 #include "pmModelClass.h"
    3636#include "pmSourceMasks.h"
    3737#include "pmSourceExtendedPars.h"
    3838#include "pmSourceDiffStats.h"
    3939#include "pmSourceSatstar.h"
     40#include "pmSourceLensing.h"
    4041#include "pmSource.h"
    4142#include "pmSourceFitModel.h"
    4243#include "pmPCMdata.h"
     44
     45# define SAVE_IMAGES 0
     46# if (SAVE_IMAGES)
     47int psphotSaveImage (psMetadata *header, psImage *image, char *filename);
     48# endif
    4349
    4450# define FACILITY "psModules.objects"
     
    9197    psF32 lambda = 0.001;
    9298    psF32 dLinear = 0.0;
    93     psF32 nu = 2.0;
     99    psF32 nu = 3.0;
    94100
    95101# if (USE_FFT && PRE_CONVOLVE)
     
    130136        }
    131137
     138        if (min->isInteractive) {
     139            fprintf (stderr, "%d : ", min->iter);
     140            for (int ti = 0; ti < params->n; ti++) {
     141                fprintf (stderr, "%f  ", params->data.F32[ti]);
     142            }
     143            fprintf (stderr, " : %f\n", min->value);
     144        }
     145
     146        char key[10]; // used for interactive responses
     147        bool testValue = false;
     148
    132149        // set a new guess for Alpha, Beta, Params
    133150        if (!psMinLM_GuessABP(Alpha, Beta, Params, alpha, beta, params, paramMask, checkLimits, lambda, &dLinear)) {
     151            if (false && min->isInteractive) {
     152                fprintf (stdout, "guess failed (singular matrix or NaN values), continue? [Y,n] ");
     153                if (!fgets(key, 8, stdin)) {
     154                    psWarning("Unable to read option");
     155                }
     156                switch (key[0]) {
     157                  case 'n':
     158                  case 'N':
     159                    done = true;
     160                    break;
     161                  case 'y':
     162                  case 'Y':
     163                  case '\n':
     164                    lambda *= 10.0;
     165                    continue;
     166                  default:
     167                    lambda *= 10.0;
     168                    continue;
     169                }
     170                if (done) break;
     171            }
    134172            min->iter ++;
    135173            if (min->iter >=  min->maxIter) break;
     
    138176        }
    139177
     178        if (false && min->isInteractive) {
     179            p_psVectorPrint(psTraceGetDestination(), Params, "current parameters: ");
     180            fprintf (stdout, "last chisq : %f\n", min->value);
     181            bool getOptions = true;
     182            while (getOptions) {
     183                fprintf (stdout, "options: (m)odify, (g)o, (q)uit: ");
     184                if (!fgets(key, 8, stdin)) {
     185                    psWarning("Unable to read option");
     186                }
     187                switch (key[0]) {
     188                  case 'm':
     189                  case 'M':
     190                    testValue = TRUE;
     191                    fprintf (stdout, "enter (Npar) (value): ");
     192                    int Npar = 0;
     193                    float value= 0;
     194                    int Nscan = fscanf (stdin, "%d %f", &Npar, &value);
     195                    if (Nscan != 2) {
     196                      fprintf (stderr, "scan failure\n");
     197                    }
     198                    Params->data.F32[Npar] = value;
     199                    break;
     200                  case 'g':
     201                  case 'G':
     202                  case '\n':
     203                    getOptions = false;
     204                    break;
     205                  default:
     206                    done = true;
     207                    break;
     208                }
     209                fprintf (stderr, "foo\n");
     210            }
     211            if (done) break;
     212        }
     213           
    140214        // dump some useful info if trace is defined
    141215        if (psTraceGetLevel(FACILITY) >= 6) {
     
    202276        // XXX : Madsen gives suggestion for better use of rho
    203277        // rho is positive if the new chisq is smaller
    204         if (rho >= -1e-6) {
     278        if (testValue || (rho >= -1e-6)) {
    205279            min->value = Chisq;
    206280            alpha  = psImageCopy(alpha, Alpha, PS_TYPE_F32);
     
    215289          case 0:
    216290            if (rho >= -1e-6) {
    217                 lambda *= 0.25;
     291                lambda *= 0.1;
    218292            } else {
    219293                lambda *= 10.0;
     
    234308            if (rho > 0.0) {
    235309                lambda *= PS_MAX(0.33, (1.0 - pow(2.0*rho - 1.0, 3.0)));
    236                 nu = 2.0;
     310                nu = 3.0;
    237311            } else {
    238312                lambda *= nu;
    239                 nu *= 2.0;
     313                nu *= 3.0;
    240314            }
    241315            break;
     
    381455            coord->data.F32[1] = (psF32) (i + 0.5 + source->pixels->row0);
    382456
    383             pcm->modelFlux->data.F32[i][j] = pcm->modelConv->modelFunc (deriv, params, coord);
     457            pcm->modelFlux->data.F32[i][j] = pcm->modelConv->class->modelFunc (deriv, params, coord);
    384458
    385459            for (int n = 0; n < params->n; n++) {
     
    408482# else
    409483    if (pcm->use1Dgauss) {
    410         // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
    411         // * the model flux is not masked
    412         // * threading takes place above this level
    413         pcm->modelConvFlux = psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type);
    414         psImageSmooth_PreAlloc_F32 (pcm->modelConvFlux, pcm->smdata);
    415         // psImageSmooth (pcm->modelConvFlux, pcm->sigma, pcm->nsigma);
     484
     485        if (USE_1D_CACHE) {
     486            // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
     487            // * the model flux is not masked
     488            // * threading takes place above this level
     489            pcm->modelConvFlux = psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type);
     490            psImageSmoothCache_F32 (pcm->modelConvFlux, pcm->smdata);
     491        } else {
     492            pcm->modelConvFlux = psImageCopy (pcm->modelConvFlux, pcm->modelFlux, pcm->modelFlux->type.type);
     493            psImageSmooth2dCache_F32 (pcm->modelConvFlux, pcm->smdata2d);
     494        }
    416495    } else {
    417496        psImageConvolveKernel (pcm->modelConvFlux, pcm->modelFlux, NULL, 0, pcm->psfFFT);
     
    428507# else
    429508        if (pcm->use1Dgauss) {
    430             // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
    431             // * the model flux is not masked
    432             // * threading takes place above this level
    433             dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type);
    434             psImageSmooth_PreAlloc_F32 (dmodelConv, pcm->smdata);
    435             // psImageSmooth (dmodelConv, pcm->sigma, pcm->nsigma);
     509            if (USE_1D_CACHE) {
     510                // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
     511                // * the model flux is not masked
     512                // * threading takes place above this level
     513                dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type);
     514                psImageSmoothCache_F32 (dmodelConv, pcm->smdata);
     515            } else {
     516                dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type);
     517                psImageSmooth2dCache_F32 (dmodelConv, pcm->smdata2d);
     518            }
    436519        } else {
    437520            psImageConvolveKernel (dmodelConv, dmodel, NULL, 0, pcm->psfFFT);
     
    449532
    450533        if (pcm->use1Dgauss) {
    451             // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
    452             // * the model flux is not masked
    453             // * threading takes place above this level
    454             dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type);
    455             psImageSmooth_PreAlloc_F32 (dmodelConv, pcm->smdata);
    456             // psImageSmooth (dmodelConv, pcm->sigma, pcm->nsigma);
     534            if (USE_1D_CACHE) {
     535                // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
     536                // * the model flux is not masked
     537                // * threading takes place above this level
     538                dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type);
     539                psImageSmoothCache_F32 (dmodelConv, pcm->smdata);
     540            } else {
     541                dmodelConv = psImageCopy (dmodelConv, dmodel, dmodel->type.type);
     542                psImageSmooth2dCache_F32 (dmodelConv, pcm->smdata2d);
     543            }
    457544        } else {
    458545            psImageConvolveFFT (dmodelConv, dmodel, NULL, 0, pcm->psf);
     
    474561    // XXX TEST : SAVE IMAGES
    475562# if (SAVE_IMAGES)
    476     psphotSaveImage (NULL, pcm->psf->image, "psf.fits");
    477     psphotSaveImage (NULL, pcm->modelFlux, "model.fits");
    478     psphotSaveImage (NULL, pcm->modelConvFlux, "modelConv.fits");
    479     psphotSaveImage (NULL, source->pixels, "obj.fits");
    480     psphotSaveImage (NULL, source->maskObj, "mask.fits");
    481     psphotSaveImage (NULL, source->variance, "variance.fits");
     563    static int Npass = 0;
     564    char name[128];
     565    if (!pcm->use1Dgauss) {
     566      snprintf (name, 128, "psf.%03d.fits", Npass); psphotSaveImage (NULL, pcm->psf->image, name);
     567    }
     568    snprintf (name, 128, "mod.%03d.fits", Npass); psphotSaveImage (NULL, pcm->modelFlux, name);
     569    snprintf (name, 128, "cnv.%03d.fits", Npass); psphotSaveImage (NULL, pcm->modelConvFlux, name);
     570    snprintf (name, 128, "obj.%03d.fits", Npass); psphotSaveImage (NULL, source->pixels, name);
     571    snprintf (name, 128, "msk.%03d.fits", Npass); psphotSaveImage (NULL, source->maskObj, name);
     572    snprintf (name, 128, "var.%03d.fits", Npass); psphotSaveImage (NULL, source->variance, name);
     573    for (int n = 0; n < pcm->dmodelsFlux->n; n++) {
     574        psImage *dmodelConv = pcm->dmodelsConvFlux->data[n];
     575        if (!dmodelConv) continue;
     576        snprintf (name, 128, "dpar.%01d.%03d.fits", n, Npass); psphotSaveImage (NULL, dmodelConv, name);
     577    }
     578    Npass ++;
    482579# endif
    483580
     
    506603
    507604            float ymodel  = pcm->modelConvFlux->data.F32[i][j];
    508             float yweight = 1.0 / source->variance->data.F32[i][j];
     605
     606            // XXXX note this point here:::
     607            float yweight = pcm->poissonErrors ? 1.0 / source->variance->data.F32[i][j] : 1.0;
    509608            float delta = ymodel - source->pixels->data.F32[i][j];
    510609
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPCMdata.c

    r35768 r37066  
    3131#include "pmMoments.h"
    3232#include "pmModelFuncs.h"
     33#include "pmModelClass.h"
    3334#include "pmModel.h"
    3435#include "pmModelUtils.h"
    35 #include "pmModelClass.h"
    3636#include "pmSourceMasks.h"
    3737#include "pmSourceExtendedPars.h"
    3838#include "pmSourceDiffStats.h"
    3939#include "pmSourceSatstar.h"
     40#include "pmSourceLensing.h"
    4041#include "pmSource.h"
    4142#include "pmSourceFitModel.h"
     
    4344
    4445# define USE_DELTA_PSF 0
    45 # define USE_1D_GAUSS 1
    4646
    4747static void pmPCMdataFree (pmPCMdata *pcm) {
     
    5858    psFree (pcm->psfFFT);
    5959    psFree (pcm->constraint);
     60
    6061    psFree (pcm->smdata); // pre-allocated data for psImageSmooth_PreAlloc
     62    psFree (pcm->smdata2d); // pre-allocated data for psImageSmooth_PreAlloc
    6163    return;
    6264}
     
    8890    }
    8991
     92    pcm->smdata = NULL;
     93    pcm->smdata2d = NULL;
     94
    9095    pcm->modelConv = NULL;
    9196    pcm->psf = NULL;
     
    9499    pcm->nDOF = 0;
    95100
     101    pcm->poissonErrors = true;
     102
    96103    // full convolution with the PSF is expensive.  if we have to save time, we can do a 1D
    97104    // convolution with a Gaussian approximation to the kernel
    98105    pcm->use1Dgauss = false;
    99     pcm->nsigma = 3.0;
     106    pcm->nsigma = NAN; // this is set to something defined by the user
    100107    pcm->sigma = 1.0; // this should be set to something sensible when the psf is known
    101108
     
    173180}
    174181
     182int pmPCMsetParams (psMinConstraint *constraint, pmSourceFitMode mode) {
     183
     184    // set parameter mask based on fitting mode
     185    int nParams = 0;
     186    int nParAll = constraint->paramMask->n;
     187
     188    switch (mode) {
     189      case PM_SOURCE_FIT_NORM:
     190        // fits only source normalization (Io)
     191        nParams = 1;
     192        psVectorInit (constraint->paramMask, 1);
     193        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     194        break;
     195
     196      case PM_SOURCE_FIT_PSF:
     197        // fits only x,y,Io
     198        nParams = 3;
     199        psVectorInit (constraint->paramMask, 1);
     200        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     201        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0;
     202        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0;
     203        break;
     204
     205      case PM_SOURCE_FIT_EXT:
     206        // fits all params except sky
     207        nParams = nParAll - 1;
     208        psVectorInit (constraint->paramMask, 0);
     209        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
     210        break;
     211
     212      case PM_SOURCE_FIT_EXT_AND_SKY:
     213        // fits all params including sky
     214        nParams = nParAll;
     215        psVectorInit (constraint->paramMask, 0);
     216        break;
     217
     218      case PM_SOURCE_FIT_SHAPE:
     219        // fits shape (Sxx, Sxy, Syy) and Io
     220        nParams = 5;
     221        psVectorInit (constraint->paramMask, 1);
     222        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 0;
     223        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     224        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SXX] = 0;
     225        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SXY] = 0;
     226        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SYY] = 0;
     227        break;
     228
     229      case PM_SOURCE_FIT_INDEX:
     230        // fits only Io, index (PAR7) -- only Io for models with < 8 params
     231        psVectorInit (constraint->paramMask, 1);
     232        constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
     233        if (nParAll == 7) {
     234            nParams = 1;
     235        } else {
     236            nParams = 2;
     237            constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0;
     238        }
     239        break;
     240
     241      case PM_SOURCE_FIT_NO_INDEX:
     242        // fits all but index (PAR7) including sky
     243        psVectorInit (constraint->paramMask, 0);
     244        if (nParAll == 7) {
     245            nParams = nParAll;
     246        } else {
     247            nParams = nParAll - 1;
     248            constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1;
     249        }
     250        break;
     251      default:
     252        psAbort("invalid fitting mode");
     253    }
     254    return nParams;
     255}
     256
     257static int modelType_GAUSS = -1;
     258static int modelType_PS1_V1 = -1;
     259
     260// generate a Gaussian smoothing kernel for supplied sigma.  sigma here does not need to match
     261// that used to allocate the structure, but it is recommended
     262bool psImageSmoothCacheKernel_PS1_V1 (psImageSmoothCacheData *smdata, float sigma, float kappa) {
     263    // check for NULL structure elements?
     264
     265    int size = smdata->Nrange;
     266
     267    psFree (smdata->kernel);
     268    smdata->kernel = psVectorAlloc(2 * smdata->Nrange + 1, PS_TYPE_F32);
     269
     270    double sum = 0.0;                   // Sum of Gaussian, for normalization
     271    double factor = 1.0 / (sigma * M_SQRT2);    // Multiplier for i -> z
     272
     273    // PS1_V1 is a power-law with fitted linear term:
     274    // 1 / (1 + kappa z + z^1.666)  where z = (r/sigma)^2
     275
     276    // generate the kernel (not normalized)
     277    for (int i = -size, j = 0; i <= size; i++, j++) {
     278        float z = PS_SQR(i * factor);
     279        sum += smdata->kernel->data.F32[j] = 1.0 / (1 + kappa * z + pow(z,1.666));
     280    }
     281
     282    // renormalize kernel to integral of 1.0
     283    for (int i = 0; i < 2 * size + 1; i++) {
     284        smdata->kernel->data.F32[i] /= sum;
     285    }
     286
     287    return true;
     288}
     289
     290psImageSmoothCacheData *psImageSmoothCacheSetKernel (float *sigma, float *kappa, float nsigma, psImage *flux, pmModel *modelPSF) {
     291
     292    psAssert (modelPSF, "psf model must be defined");
     293   
     294    psEllipseAxes axes;
     295    bool useReff = modelPSF->class->useReff;
     296    psF32 *PAR = modelPSF->params->data.F32;
     297    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
     298   
     299    *sigma = NAN;
     300    *kappa = NAN;
     301
     302    // XXX need to do this more carefully
     303    if (modelPSF->type == modelType_GAUSS) {
     304        float FWHM_MAJOR = 2*modelPSF->class->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
     305        float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
     306        *sigma = 0.50 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
     307    }
     308    if (modelPSF->type == modelType_PS1_V1) {
     309        *sigma = 0.5 * (axes.major + axes.minor);
     310        *kappa = PAR[PM_PAR_7];
     311    }
     312    psAssert (isfinite(*sigma), "invalid model type");
     313
     314    // psImageSmoothCacheAlloc generates a structure but does not assign the smoothing vector
     315    psImageSmoothCacheData *smdata = psImageSmoothCacheAlloc (flux, *sigma, nsigma);
     316
     317    if (modelPSF->type == modelType_GAUSS) {
     318        psImageSmoothCacheKernel_Gauss (smdata, *sigma);
     319    }
     320    if (modelPSF->type == modelType_PS1_V1) {
     321        psImageSmoothCacheKernel_PS1_V1 (smdata, *sigma, *kappa);
     322    }
     323
     324    return smdata;
     325}
     326
     327psImageSmooth2dCacheData *psImageSmooth2dCacheSetKernel (float *sigma, float *kappa, float nsigma, psImage *flux, pmModel *modelPSF) {
     328
     329    psAssert (modelPSF, "psf model must be defined");
     330   
     331    psEllipseAxes axes;
     332    bool useReff = modelPSF->class->useReff;
     333    psF32 *PAR = modelPSF->params->data.F32;
     334    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
     335   
     336    *sigma = NAN;
     337    *kappa = NAN;
     338
     339    // XXX need to do this more carefully
     340    if (modelPSF->type == modelType_GAUSS) {
     341        float FWHM_MAJOR = 2*modelPSF->class->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
     342        float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
     343        *sigma = 0.50 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
     344    }
     345    if (modelPSF->type == modelType_PS1_V1) {
     346        *sigma = 0.5 * (axes.major + axes.minor);
     347        *kappa = PAR[PM_PAR_7];
     348    }
     349    psAssert (isfinite(*sigma), "invalid model type");
     350
     351    // psImageSmoothCacheAlloc generates a structure but does not assign the smoothing vector
     352    psImageSmooth2dCacheData *smdata = psImageSmooth2dCacheAlloc (nsigma);
     353
     354    if (modelPSF->type == modelType_GAUSS) {
     355        psImageSmooth2dCacheKernel_Gauss (smdata, *sigma);
     356    }
     357    if (modelPSF->type == modelType_PS1_V1) {
     358        psImageSmooth2dCacheKernel_PS1_V1 (smdata, *sigma, *kappa);
     359    }
     360
     361    return smdata;
     362}
     363
    175364pmPCMdata *pmPCMinit(pmSource *source, pmSourceFitOptions *fitOptions, pmModel *model, psImageMaskType maskVal, float psfSize) {
    176365
    177     // make sure we save a cached copy of the psf flux
    178     pmSourceCachePSF (source, maskVal);
    179 
    180     // convert the cached cached psf model for this source to a psKernel
    181     psKernel *psf = pmPCMkernelFromPSF (source, psfSize);
    182     if (!psf) {
    183         // NOTE: this only happens if the source is too close to an edge
    184         model->flags |= PM_MODEL_STATUS_BADARGS;
    185         return NULL;
    186     }
    187 
    188 # if (USE_DELTA_PSF)
    189     psImageInit (psf->image, 0.0);
    190     psf->image->data.F32[(int)(0.5*psf->image->numRows)][(int)(0.5*psf->image->numCols)] = 1.0;
    191 # endif
     366    modelType_GAUSS = pmModelClassGetType ("PS_MODEL_GAUSS");
     367    modelType_PS1_V1 = pmModelClassGetType ("PS_MODEL_PS1_V1");
    192368
    193369    // count the number of unmasked pixels:
     
    217393    psMinConstraint *constraint = psMinConstraintAlloc();
    218394    constraint->paramMask = psVectorAlloc (params->n, PS_TYPE_VECTOR_MASK);
    219     constraint->checkLimits = model->modelLimits;
    220 
    221     // set parameter mask based on fitting mode
    222     int nParams = 0;
    223     switch (fitOptions->mode) {
    224       case PM_SOURCE_FIT_NORM:
    225         // NORM-only model fits only source normalization (Io)
    226         nParams = 1;
    227         psVectorInit (constraint->paramMask, 1);
    228         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    229         break;
    230       case PM_SOURCE_FIT_PSF:
    231         // PSF model only fits x,y,Io
    232         nParams = 3;
    233         psVectorInit (constraint->paramMask, 1);
    234         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    235         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0;
    236         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0;
    237         break;
    238       case PM_SOURCE_FIT_EXT:
    239         // EXT model fits all params (except sky)
    240         nParams = params->n - 1;
    241         psVectorInit (constraint->paramMask, 0);
    242         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    243         break;
    244       case PM_SOURCE_FIT_INDEX:
    245         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    246         psVectorInit (constraint->paramMask, 1);
    247         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    248         if (params->n == 7) {
    249             nParams = 1;
    250         } else {
    251             nParams = 2;
    252             constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0;
    253         }
    254         break;
    255       case PM_SOURCE_FIT_NO_INDEX:
    256         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    257         psVectorInit (constraint->paramMask, 0);
    258         constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    259         if (params->n == 7) {
    260             nParams = params->n - 1;
    261         } else {
    262             nParams = params->n - 2;
    263             constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1;
    264         }
    265         break;
    266       default:
    267         psAbort("invalid fitting mode");
    268     }
     395    constraint->checkLimits = model->class->modelLimits;
     396
     397    int nParams = pmPCMsetParams (constraint, fitOptions->mode);
    269398
    270399    if (nPix <  nParams + 1) {
    271400        psTrace ("psModules.objects", 4, "insufficient valid pixels\n");
    272         psFree (psf);
    273401        psFree (constraint);
    274402        model->flags |= PM_MODEL_STATUS_BADARGS;
     
    278406    // generate PCM data storage structure
    279407    pmPCMdata *pcm = pmPCMdataAlloc (params, constraint->paramMask, source);
    280 
    281     pcm->psf = psf;
    282408    pcm->modelConv = psMemIncrRefCounter(model);
    283409    pcm->constraint = constraint;
     410
     411    pcm->poissonErrors = fitOptions->poissonErrors;
     412    pcm->nsigma = fitOptions->nsigma;
    284413
    285414    pcm->nPix = nPix;
     
    288417
    289418# if (USE_1D_GAUSS)
    290     pmModel *modelPSF = source->modelPSF;
    291     psAssert (modelPSF, "psf model must be defined");
    292    
    293     psEllipseAxes axes;
    294     bool useReff = pmModelUseReff (modelPSF->type);
    295     psF32 *PAR = modelPSF->params->data.F32;
    296     pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
    297    
    298     float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
    299     float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
    300419
    301420    pcm->use1Dgauss = true;
    302     pcm->sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
    303     pcm->nsigma = 2.0;
    304 
    305     pcm->smdata = psImageSmooth_PreAlloc_DataAlloc (source->pixels, pcm->sigma, pcm->nsigma);
     421    if (USE_1D_CACHE) {
     422        pcm->smdata = psImageSmoothCacheSetKernel (&pcm->sigma, &pcm->kappa, pcm->nsigma, source->pixels, source->modelPSF);
     423    } else {
     424        pcm->smdata2d = psImageSmooth2dCacheSetKernel (&pcm->sigma, &pcm->kappa, pcm->nsigma, source->pixels, source->modelPSF);
     425    }
     426
    306427# else
     428    // make sure we save a cached copy of the psf flux
     429    pmSourceCachePSF (source, maskVal);
     430
     431    // convert the cached cached psf model for this source to a psKernel
     432    psKernel *psf = pmPCMkernelFromPSF (source, psfSize);
     433    if (!psf) {
     434        // NOTE: this only happens if the source is too close to an edge
     435        model->flags |= PM_MODEL_STATUS_BADARGS;
     436        return NULL;
     437    }
     438
     439# if (USE_DELTA_PSF)
     440    psImageInit (psf->image, 0.0);
     441    psf->image->data.F32[(int)(0.5*psf->image->numRows)][(int)(0.5*psf->image->numCols)] = 1.0;
     442# endif
     443    pcm->psf = psf;
    307444    pcm->smdata = NULL;
    308445# endif
     
    341478    }
    342479
    343     // if we changed the fit mode, we need to update nDOF
    344     int nParams = 0;
    345     // set parameter mask based on fitting mode
    346     switch (fitOptions->mode) {
    347       case PM_SOURCE_FIT_NORM:
    348         // NORM-only model fits only source normalization (Io)
    349         nParams = 1;
    350         psVectorInit (pcm->constraint->paramMask, 1);
    351         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    352         break;
    353       case PM_SOURCE_FIT_PSF:
    354         // PSF model only fits x,y,Io
    355         nParams = 3;
    356         psVectorInit (pcm->constraint->paramMask, 1);
    357         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    358         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_XPOS] = 0;
    359         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_YPOS] = 0;
    360         break;
    361       case PM_SOURCE_FIT_EXT:
    362         // EXT model fits all params (except sky)
    363         nParams = model->params->n - 1;
    364         psVectorInit (pcm->constraint->paramMask, 0);
    365         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    366         break;
    367       case PM_SOURCE_FIT_INDEX:
    368         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    369         psVectorInit (pcm->constraint->paramMask, 1);
    370         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_I0] = 0;
    371         if (model->params->n == 7) {
    372             nParams = 1;
    373         } else {
    374             nParams = 2;
    375             pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 0;
    376         }
    377         break;
    378       case PM_SOURCE_FIT_NO_INDEX:
    379         // PSF model only fits Io, index (PAR7) -- only Io for models with < 8 params
    380         psVectorInit (pcm->constraint->paramMask, 0);
    381         pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_SKY] = 1;
    382         if (model->params->n == 7) {
    383             nParams = model->params->n - 1;
    384         } else {
    385             nParams = model->params->n - 2;
    386             pcm->constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[PM_PAR_7] = 1;
    387         }
    388         break;
    389       default:
    390         psAbort("invalid fitting mode");
    391     }
     480    int nParams = pmPCMsetParams (pcm->constraint, fitOptions->mode);
    392481
    393482    if (pcm->nPix <  nParams + 1) {
     
    415504            pcm->dmodelsConvFlux->data[n] = psImageCopy (pcm->dmodelsConvFlux->data[n], source->pixels, PS_TYPE_F32);
    416505        }
    417         psFree(pcm->smdata);
    418         pcm->smdata = psImageSmooth_PreAlloc_DataAlloc (source->pixels, pcm->sigma, pcm->nsigma);
     506
     507        // If we have changed the window, we need to redefine the smoothing target vectors (but pcm->sigma,kappa,nsigma remain)
     508        if (USE_1D_CACHE) {
     509            psFree(pcm->smdata);
     510            pcm->smdata = psImageSmoothCacheAlloc (source->pixels, pcm->sigma, pcm->nsigma);
     511
     512            pmModel *modelPSF = source->modelPSF;
     513            if (modelPSF->type == modelType_GAUSS) {
     514                psImageSmoothCacheKernel_Gauss (pcm->smdata, pcm->sigma);
     515            }
     516            if (modelPSF->type == modelType_PS1_V1) {
     517                psImageSmoothCacheKernel_PS1_V1 (pcm->smdata, pcm->sigma, pcm->kappa);
     518            }
     519        } else {
     520            psFree(pcm->smdata2d);
     521            pcm->smdata2d = psImageSmooth2dCacheAlloc (pcm->nsigma);
     522
     523            pmModel *modelPSF = source->modelPSF;
     524            if (modelPSF->type == modelType_GAUSS) {
     525                // psImageSmooth2dCacheKernel_Gauss (pcm->smdata2d, pcm->sigma);
     526            }
     527            if (modelPSF->type == modelType_PS1_V1) {
     528                psImageSmooth2dCacheKernel_PS1_V1 (pcm->smdata2d, pcm->sigma, pcm->kappa);
     529            }
     530        }
    419531    }
    420532
     
    423535
    424536// construct a realization of the source model
    425 bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize) {
     537bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize, float nsigma) {
    426538
    427539    PS_ASSERT_PTR_NON_NULL(source, false);
     
    440552    // convolve the model image with the PSF
    441553    if (USE_1D_GAUSS) {
    442         // do not use the threaded, mask-aware version of this code (psImageSmoothMaskPixelsThread):
    443         // * the model flux is not masked
    444         // * threading takes place above this level
    445554       
    446         // define the Gauss parameters from the psf
    447         pmModel *modelPSF = source->modelPSF;
    448         psAssert (modelPSF, "psf model must be defined");
    449    
    450         psEllipseAxes axes;
    451         bool useReff = pmModelUseReff (modelPSF->type);
    452         psF32 *PAR = modelPSF->params->data.F32;
    453         pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
    454    
    455         float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
    456         float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
    457 
    458         float sigma = 0.5 * (FWHM_MAJOR + FWHM_MINOR) / 2.35;
    459         float nsigma = 2.0;
    460 
    461         psImageSmooth (source->modelFlux, sigma, nsigma);
     555        float sigma = NAN;
     556        float kappa = NAN;
     557
     558        if (USE_1D_CACHE) {
     559            psImageSmoothCacheData *smdata = psImageSmoothCacheSetKernel (&sigma, &kappa, nsigma, source->modelFlux, source->modelPSF);
     560            psImageSmoothCache_F32 (source->modelFlux, smdata);
     561            psFree (smdata);
     562        } else {
     563            psImageSmooth2dCacheData *smdata = psImageSmooth2dCacheSetKernel (&sigma, &kappa, nsigma, source->modelFlux, source->modelPSF);
     564            psImageSmooth2dCache_F32 (source->modelFlux, smdata);
     565            psFree (smdata);
     566        }
     567        // old call: psImageSmooth (source->modelFlux, sigma, nsigma);
    462568    } else {
    463569        // make sure we save a cached copy of the psf flux
     
    478584}
    479585
     586// construct a realization of the source model
     587bool pmPCMMakeModel (pmSource *source, pmModel *model, float Nsigma, psImageMaskType maskVal, int psfSize) {
     588
     589    PS_ASSERT_PTR_NON_NULL(source, false);
     590
     591    // if we already have a cached image, re-use that memory
     592    source->modelFlux = psImageCopy (source->modelFlux, source->pixels, PS_TYPE_F32);
     593    psImageInit (source->modelFlux, 0.0);
     594
     595    // modelFlux always has unity normalization (I0 = 1.0)
     596    // pmModelAdd (source->modelFlux, source->maskObj, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM, maskVal);
     597    pmModelAdd (source->modelFlux, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_SKY | PM_MODEL_OP_NORM, maskVal);
     598
     599    // convolve the model image with the PSF
     600    if (USE_1D_GAUSS) {
     601
     602        float sigma = NAN;
     603        float kappa = NAN;
     604
     605        if (USE_1D_CACHE) {
     606            psImageSmoothCacheData *smdata = psImageSmoothCacheSetKernel (&sigma, &kappa, Nsigma, source->modelFlux, source->modelPSF);
     607            psImageSmoothCache_F32 (source->modelFlux, smdata);
     608            psFree (smdata);
     609        } else {
     610            psImageSmooth2dCacheData *smdata = psImageSmooth2dCacheSetKernel (&sigma, &kappa, Nsigma, source->modelFlux, source->modelPSF);
     611            psImageSmooth2dCache_F32 (source->modelFlux, smdata);
     612            psFree (smdata);
     613        }
     614        // old call: psImageSmooth (source->modelFlux, sigma, nsigma);
     615    } else {
     616        // make sure we save a cached copy of the psf flux
     617        pmSourceCachePSF (source, maskVal);
     618
     619        // convert the cached cached psf model for this source to a psKernel
     620        psKernel *psf = pmPCMkernelFromPSF (source, psfSize);
     621        if (!psf) {
     622            // NOTE: this only happens if the source is too close to an edge
     623            model->flags |= PM_MODEL_STATUS_BADARGS;
     624            return NULL;
     625        }
     626
     627        // XXX not sure if I can place the output on top of the input
     628        psImageConvolveFFT (source->modelFlux, source->modelFlux, NULL, 0, psf);
     629    }
     630    return true;
     631}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPCMdata.h

    r32725 r37066  
    1414/// @addtogroup Objects Object Detection / Analysis Functions
    1515/// @{
     16
     17// XXX this is basically for testing -- when I am happy with the convolution process, I'll strip this out
     18# define USE_1D_CACHE 0
     19# define USE_1D_GAUSS 1
    1620
    1721/** pmPCMdata : PSF Convolved Model data storage structure
     
    3640    int nDOF;
    3741
     42    bool poissonErrors;
     43
    3844    bool use1Dgauss;
     45    float kappa;
    3946    float sigma;
    4047    float nsigma;
    4148
    42     psImageSmooth_PreAlloc_Data *smdata;
     49    // psArray *smdata;
     50    psImageSmoothCacheData *smdata;
     51    psImageSmooth2dCacheData *smdata2d;
    4352} pmPCMdata;
    4453
     
    96105bool pmSourceFitPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize);
    97106
    98 bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize);
     107bool pmPCMCacheModel (pmSource *source, psImageMaskType maskVal, int psfSize, float nsigma);
     108
     109bool pmPCMMakeModel (pmSource *source, pmModel *model, float Nsigma, psImageMaskType maskVal, int psfSize);
    99110
    100111/// @}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSF.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    328329// convert the parameters used in the fitted source model to the psEllipseAxes representation
    329330// (major,minor,theta)
    330 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, pmModelType type)
     331psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, bool useReff)
    331332{
    332333    psEllipseAxes axes;
     
    337338    PS_ASSERT_PTR_NON_NULL(modelPar, axes);
    338339
    339     bool useReff = pmModelUseReff (type);
    340340    pmModelParamsToAxes (&axes, modelPar[PM_PAR_SXX], modelPar[PM_PAR_SXY], modelPar[PM_PAR_SYY], useReff);
    341341    return axes;
     
    344344// convert the psEllipseAxes representation (major,minor,theta) to the parameters used in the
    345345// fitted source model
    346 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, pmModelType type)
     346bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, bool useReff)
    347347{
    348348    PS_ASSERT_PTR_NON_NULL(modelPar, false);
     
    356356    }
    357357   
    358     bool useReff = pmModelUseReff (type);
    359358    pmModelAxesToParams (&modelPar[PM_PAR_SXX], &modelPar[PM_PAR_SXY], &modelPar[PM_PAR_SYY], axes, useReff);
    360359    return true;
     
    419418
    420419    // get the model full-width at half-max
    421     float fwhmMajor = 2*model->modelRadius (model->params, 0.5);
     420    float fwhmMajor = 2*model->class->modelRadius (model->params, 0.5);
    422421
    423422# if (0)
    424423    psF32 *params = model->params->data.F32; // Model parameters
    425     psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO, model->type); // Ellipse axes
     424    psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO, model->class->useReff); // Ellipse axes
    426425
    427426    // Curiously, the minor axis can be larger than the major axis, so need to check.
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSF.h

    r35768 r37066  
    106106pmPSF *pmPSFBuildSimple (char *typeName, float sxx, float syy, float sxy, ...);
    107107
    108 bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, pmModelType type);
     108bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, bool useReff);
    109109bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis, bool useReff);
    110110
    111111psEllipsePol pmPSF_ModelToFit (psF32 *modelPar, bool useReff);
    112 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, pmModelType type);
     112psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, bool useReff);
    113113
    114114/// Calculate FWHM value from a PSF
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSF_IO.c

    r34403 r37066  
    4747#include "pmMoments.h"
    4848#include "pmModelFuncs.h"
     49#include "pmModelClass.h"
    4950#include "pmModel.h"
    5051#include "pmModelUtils.h"
    51 #include "pmModelClass.h"
    5252#include "pmSourceMasks.h"
    5353#include "pmSourceExtendedPars.h"
    5454#include "pmSourceDiffStats.h"
    5555#include "pmSourceSatstar.h"
     56#include "pmSourceLensing.h"
    5657#include "pmSource.h"
    5758#include "pmSourceFitModel.h"
     
    510511        psMetadataAddF32 (header, PS_LIST_TAIL, "SKY_BIAS", PS_DATA_F32, "sky bias level", psf->skyBias);
    511512
    512         float PSF_APERTURE =  psMetadataLookupF32(&status, roAnalysis, "PSF_APERTURE");
    513         if (status) {
     513        if (roAnalysis) {
     514          float PSF_APERTURE =  psMetadataLookupF32(&status, roAnalysis, "PSF_APERTURE");
     515          if (status) {
    514516            psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_APERTURE", PS_DATA_F32, "aperture for psf objects", PSF_APERTURE);
    515         }
    516         float PSF_FIT_RADIUS =  psMetadataLookupF32(&status, roAnalysis, "PSF_FIT_RADIUS");
    517         if (status) {
     517          }
     518          float PSF_FIT_RADIUS =  psMetadataLookupF32(&status, roAnalysis, "PSF_FIT_RADIUS");
     519          if (status) {
    518520            psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_FIT_RADIUS", PS_DATA_F32, "aperture for psf objects", PSF_FIT_RADIUS);
     521          }
    519522        }
    520523
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSFtry.c

    r34403 r37066  
    2929#include "pmMoments.h"
    3030#include "pmModelFuncs.h"
     31#include "pmModelClass.h"
    3132#include "pmModel.h"
    3233#include "pmModelUtils.h"
    33 #include "pmModelClass.h"
    3434#include "pmSourceMasks.h"
    3535#include "pmSourceExtendedPars.h"
    3636#include "pmSourceDiffStats.h"
    3737#include "pmSourceSatstar.h"
     38#include "pmSourceLensing.h"
    3839#include "pmSource.h"
    3940#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSFtryFitEXT.c

    r35768 r37066  
    2929#include "pmMoments.h"
    3030#include "pmModelFuncs.h"
     31#include "pmModelClass.h"
    3132#include "pmModel.h"
    3233#include "pmModelUtils.h"
    33 #include "pmModelClass.h"
    3434#include "pmSourceMasks.h"
    3535#include "pmSourceExtendedPars.h"
    3636#include "pmSourceDiffStats.h"
    3737#include "pmSourceSatstar.h"
     38#include "pmSourceLensing.h"
    3839#include "pmSource.h"
    3940#include "pmSourceUtils.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSFtryFitPSF.c

    r35923 r37066  
    2727#include "pmMoments.h"
    2828#include "pmModelFuncs.h"
     29#include "pmModelClass.h"
    2930#include "pmModel.h"
    3031#include "pmModelUtils.h"
    31 #include "pmModelClass.h"
    3232#include "pmSourceMasks.h"
    3333#include "pmSourceExtendedPars.h"
    3434#include "pmSourceDiffStats.h"
    3535#include "pmSourceSatstar.h"
     36#include "pmSourceLensing.h"
    3637#include "pmSource.h"
    3738#include "pmSourceFitModel.h"
     
    118119    psfTry->psf->nPSFstars = Npsf;
    119120
    120     // DEBUG code: save the PSF model fit data in detail
    121 # ifdef DEBUG
    122 
    123     char filename[64];
    124     snprintf (filename, 64, "psffit.%dx%d.dat", psfTry->psf->trendNx, psfTry->psf->trendNy);
    125     FILE *f = fopen (filename, "w");
    126     psAssert (f, "failed open");
    127 
    128     for (int i = 0; i < psfTry->sources->n; i++) {
    129 
    130         // skip masked sources
    131         if (psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PSFTRY_MASK_ALL) continue;
    132 
    133         pmSource *source = psfTry->sources->data[i];
    134 
    135         fprintf (f, "%6.1f %6.1f : %6.1f %6.1f : %8.3f %8.3f %8.3f : %f : %f %f %f : %f\n",
    136                  source->peak->xf, source->peak->yf,
    137                  source->modelPSF->params->data.F32[PM_PAR_XPOS], source->modelPSF->params->data.F32[PM_PAR_YPOS],
    138                  source->psfMag, source->apMag, source->psfMagErr,
    139                  source->modelPSF->params->data.F32[PM_PAR_I0],
    140                  source->modelPSF->params->data.F32[PM_PAR_SXX], source->modelPSF->params->data.F32[PM_PAR_SXY],
    141                  source->modelPSF->params->data.F32[PM_PAR_SYY], source->modelPSF->params->data.F32[PM_PAR_7]);
    142     }
    143     fclose (f);
    144 # endif
    145 
    146121    pmSourceVisualShowModelFits (psfTry->psf, psfTry->sources, maskVal);
    147122
    148     psLogMsg ("psphot.psftry", PS_LOG_MINUTIA, "fit psf:   %f sec for %d of %ld sources\n", psTimerMark ("psf.fit"), Npsf, psfTry->sources->n);
     123    psLogMsg ("psphot.psftry", PS_LOG_MINUTIA, "fit psf:   %f sec for %d of %ld sources (%d x %d model)\n", psTimerMark ("psf.fit"), Npsf, psfTry->sources->n, psfTry->psf->trendNx, psfTry->psf->trendNy);
    149124    psTrace ("psModules.object", 3, "keeping %d of %ld PSF candidates (PSF)\n", Npsf, psfTry->sources->n);
    150125
    151126    if (Npsf == 0) {
    152         psError(PS_ERR_UNKNOWN, false, "No sources with good PSF fits after model is built.");
    153         return false;
     127#if 0
     128        // DEBUG code: save the PSF model fit data in detail
     129
     130        char hostname[256];
     131        gethostname (hostname, 256);
     132
     133        int pid = getpid();
     134
     135        char filename[64];
     136        snprintf (filename, 64, "psffit.%s.%d.%dx%d.dat", hostname, pid, psfTry->psf->trendNx, psfTry->psf->trendNy);
     137        FILE *f = fopen (filename, "w");
     138        psAssert (f, "failed open");
     139
     140        for (int i = 0; i < psfTry->sources->n; i++) {
     141
     142            // skip masked sources
     143          // if (psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PSFTRY_MASK_ALL) continue;
     144
     145            pmSource *source = psfTry->sources->data[i];
     146
     147            if (!source->modelPSF) continue;
     148
     149            float par7 = (source->modelPSF->params->n == 7) ? -100 : source->modelPSF->params->data.F32[PM_PAR_7];
     150            fprintf (f, "%6.1f %6.1f : %6.1f %6.1f : %8.3f %8.3f %8.3f : %f : %f %f %f : %f %d\n",
     151                     source->peak->xf, source->peak->yf,
     152                     source->modelPSF->params->data.F32[PM_PAR_XPOS], source->modelPSF->params->data.F32[PM_PAR_YPOS],
     153                     source->psfMag, source->apMag, source->psfMagErr,
     154                     source->modelPSF->params->data.F32[PM_PAR_I0],
     155                     source->modelPSF->params->data.F32[PM_PAR_SXX], source->modelPSF->params->data.F32[PM_PAR_SXY],
     156                     source->modelPSF->params->data.F32[PM_PAR_SYY], par7,
     157                     psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i]);
     158        }
     159        fclose (f);
     160#endif
     161        psError(PS_ERR_UNKNOWN, false, "No sources with good PSF fits after model is built.");
     162        return false;
    154163    }
    155164
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSFtryMakePSF.c

    r35768 r37066  
    2828#include "pmMoments.h"
    2929#include "pmModelFuncs.h"
     30#include "pmModelClass.h"
    3031#include "pmModel.h"
    3132#include "pmModelUtils.h"
    32 #include "pmModelClass.h"
    3333#include "pmSourceMasks.h"
    3434#include "pmSourceExtendedPars.h"
    3535#include "pmSourceDiffStats.h"
    3636#include "pmSourceSatstar.h"
     37#include "pmSourceLensing.h"
    3738#include "pmSource.h"
    3839#include "pmSourceFitModel.h"
     
    211212        assert (source->modelEXT); // all unmasked sources should have modelEXT
    212213
    213         bool useReff = pmModelUseReff (source->modelEXT->type);
     214        bool useReff = source->modelEXT->class->useReff;
    214215        psEllipsePol pol = pmPSF_ModelToFit (source->modelEXT->params->data.F32, useReff);
    215216
     
    217218        e1->data.F32[i] = pol.e1;
    218219        e2->data.F32[i] = pol.e2;
     220    }
     221
     222    // weed out extreme e0 outliers here: find the median and exclude points not in the
     223    // range MEDIAN / 5 < e0 < 5 * MEDIAN
     224    {
     225      psStats *e0stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     226      if (psVectorStats (e0stats, e0, NULL, srcMask, 0xff)) {
     227        float e0med = e0stats->sampleMedian;
     228   
     229        for (int i = 0; i < sources->n; i++) {
     230          // skip any masked sources (failed to fit one of the model steps or get a magnitude)
     231          if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;
     232
     233          if (e0->data.F32[i] < 0.2*e0med) {
     234            srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_OUTLIER;
     235          }
     236          if (e0->data.F32[i] > 5.0*e0med) {
     237            srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_OUTLIER;
     238          }
     239        }
     240      }
     241      psFree (e0stats);
    219242    }
    220243
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSFtryMetric.c

    r34403 r37066  
    2828#include "pmMoments.h"
    2929#include "pmModelFuncs.h"
     30#include "pmModelClass.h"
    3031#include "pmModel.h"
    3132#include "pmModelUtils.h"
    32 #include "pmModelClass.h"
    3333#include "pmSourceMasks.h"
    3434#include "pmSourceExtendedPars.h"
    3535#include "pmSourceDiffStats.h"
    3636#include "pmSourceSatstar.h"
     37#include "pmSourceLensing.h"
    3738#include "pmSource.h"
    3839#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPSFtryModel.c

    r34403 r37066  
    2929#include "pmMoments.h"
    3030#include "pmModelFuncs.h"
     31#include "pmModelClass.h"
    3132#include "pmModel.h"
    3233#include "pmModelUtils.h"
    33 #include "pmModelClass.h"
    3434#include "pmSourceMasks.h"
    3535#include "pmSourceExtendedPars.h"
    3636#include "pmSourceDiffStats.h"
    3737#include "pmSourceSatstar.h"
     38#include "pmSourceLensing.h"
    3839#include "pmSource.h"
    3940#include "pmSourceFitModel.h"
     
    111112
    112113    // set the max order (0 = constant) which the number of psf stars can support:
     114    int MaxOrderForStars = 0;
     115
     116    // we require only 3 stars for n = 0, increase stars / cell for higher order
     117    if (sources->n >=  16) MaxOrderForStars = 1; //  4 cells, 4 per cell
     118    if (sources->n >=  54) MaxOrderForStars = 2; //  9 cells, 6 per cell
     119    if (sources->n >= 128) MaxOrderForStars = 3; // 16 cells, 8 per cell
     120    if (sources->n >= 300) MaxOrderForStars = 4; // 25 cells, 12 per cell
     121    if (sources->n >  576) MaxOrderForStars = 5; // 36 cells, 16 per cell
     122
    113123    // rule of thumb: require 3 stars per 'cell' (order+1)^2
    114     int MaxOrderForStars = 0;
    115     if (sources->n >= 12) MaxOrderForStars = 1; // 4 cells
    116     if (sources->n >= 27) MaxOrderForStars = 2; // 9 cells
    117     if (sources->n >= 48) MaxOrderForStars = 3; // 16 cells
    118     if (sources->n >  75) MaxOrderForStars = 4; // 25 cells
     124    // if (sources->n >= 12) MaxOrderForStars = 1; // 4 cells
     125    // if (sources->n >= 27) MaxOrderForStars = 2; // 9 cells
     126    // if (sources->n >= 48) MaxOrderForStars = 3; // 16 cells
     127    // if (sources->n >= 75) MaxOrderForStars = 4; // 25 cells
     128    // if (sources->n > 108) MaxOrderForStars = 5; // 36 cells
    119129
    120130    int orderMax = PS_MAX (options->psfTrendNx, options->psfTrendNy);
     
    236246    // linear clipped fit of chisq trend vs flux
    237247    if (options->chiFluxTrend) {
     248
     249        if (0) {
     250            FILE *f = fopen ("test.psf.dat", "w");
     251            int fd = fileno (f);
     252            p_psVectorPrint (fd, flux, "flux");
     253            p_psVectorPrint (fd, chisq, "chisq");
     254            p_psVectorPrint (fd, mask, "mask");
     255            fclose (f);
     256        }
     257
    238258        bool result = psVectorClipFitPolynomial1D(psfTry->psf->ChiTrend, options->stats,
    239259                                                  mask, 0xff, chisq, NULL, flux);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmPhotObj.c

    r34403 r37066  
    2929#include "pmMoments.h"
    3030#include "pmModelFuncs.h"
     31#include "pmModelClass.h"
    3132#include "pmModel.h"
    3233#include "pmModelUtils.h"
    33 #include "pmModelClass.h"
    3434#include "pmSourceMasks.h"
    3535#include "pmSourceExtendedPars.h"
    3636#include "pmSourceDiffStats.h"
    3737#include "pmSourceSatstar.h"
     38#include "pmSourceLensing.h"
    3839#include "pmSource.h"
    3940
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSource.c

    r35768 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838#include "pmSourceMasks.h"
    3939#include "pmSourceExtendedPars.h"
     
    4141#include "pmSourcePhotometry.h"
    4242#include "pmSourceSatstar.h"
     43#include "pmSourceLensing.h"
    4344#include "pmSource.h"
    4445
     
    6667    psFree(tmp->extpars);
    6768    psFree(tmp->diffStats);
     69    psFree(tmp->galaxyFits);
    6870    psFree(tmp->radialAper);
     71    psFree(tmp->lensingOBJ);
     72    psFree(tmp->lensingPSF);
    6973    psTrace("psModules.objects", 10, "---- end ----\n");
    7074}
     
    142146    source->apMagRaw         = NAN;
    143147    source->apRadius         = NAN;
     148    source->apNpixels        = 0;
    144149    source->apFlux           = NAN;
    145150    source->apFluxErr        = NAN;
     
    158163    source->sky              = NAN;
    159164    source->skyErr           = NAN;   
     165    source->extSN            = NAN;   
    160166
    161167    source->region = psRegionSet(NAN, NAN, NAN, NAN);
     
    164170    source->extpars = NULL;
    165171    source->diffStats = NULL;
     172    source->galaxyFits = NULL;
     173    source->lensingOBJ = NULL;
     174    source->lensingPSF = NULL;
    166175    source->radialAper = NULL;
    167176    source->parent = NULL;
     
    229238    source->apMagRaw         = in->apMagRaw;
    230239    source->apRadius         = in->apRadius;
     240    source->apNpixels        = in->apNpixels;
    231241    source->apFlux           = in->apFlux;
    232242    source->apFluxErr        = in->apFluxErr;
     
    247257
    248258    source->region           = in->region;
     259
     260    // XXX I am not copying the pointers to things like the blends, satstar profile, galaxyFits, etc
    249261
    250262    return(source);
     
    690702            // why do we recalculate moments here?
    691703            // we already attempt to do this in psphotSourceStats
    692             // pmSourceMoments (source, INNER_RADIUS);
    693704            Nsatstar ++;
    694705            continue;
     
    804815    return true;
    805816}
    806 
    807 /******************************************************************************
    808 pmSourceMoments(source, radius): this function takes a subImage defined in the
    809 pmSource data structure, along with the peak location, and determines the
    810 various moments associated with that peak.
    811 
    812 Requires the following to have been created:
    813     pmSource
    814     pmSource->peak
    815     pmSource->pixels
    816     pmSource->variance
    817     pmSource->mask
    818 
    819 XXX: The peak calculations are done in image coords, not subImage coords.
    820 
    821 XXX EAM : this version clips input pixels on S/N
    822 XXX EAM : this version returns false for several reasons
    823 *****************************************************************************/
    824 # define VALID_RADIUS(X,Y,RAD2) (((RAD2) >= (PS_SQR(X) + PS_SQR(Y))) ? 1 : 0)
    825 
    826 /*** this been moved to pmSourceMoments.c ***/
    827 # if (0)
    828 bool pmSourceMoments(pmSource *source,
    829                      psF32 radius)
    830 {
    831     psTrace("psModules.objects", 10, "---- begin ----\n");
    832     PS_ASSERT_PTR_NON_NULL(source, false);
    833     PS_ASSERT_PTR_NON_NULL(source->peak, false);
    834     PS_ASSERT_PTR_NON_NULL(source->pixels, false);
    835     PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false);
    836 
    837     //
    838     // XXX: Verify the setting for sky if source->moments == NULL.
    839     //
    840     psF32 sky = 0.0;
    841     if (source->moments == NULL) {
    842         source->moments = pmMomentsAlloc();
    843     } else {
    844         sky = source->moments->Sky;
    845     }
    846 
    847     //
    848     // Sum = SUM (z - sky)
    849     // X1  = SUM (x - xc)*(z - sky)
    850     // X2  = SUM (x - xc)^2 * (z - sky)
    851     // XY  = SUM (x - xc)*(y - yc)*(z - sky)
    852     //
    853     psF32 peakPixel = -PS_MAX_F32;
    854     psS32 numPixels = 0;
    855     psF32 Sum = 0.0;
    856     psF32 Var = 0.0;
    857     psF32 X1 = 0.0;
    858     psF32 Y1 = 0.0;
    859     psF32 X2 = 0.0;
    860     psF32 Y2 = 0.0;
    861     psF32 XY = 0.0;
    862     psF32 x  = 0;
    863     psF32 y  = 0;
    864     psF32 R2 = PS_SQR(radius);
    865 
    866     psF32 xPeak = source->peak->x;
    867     psF32 yPeak = source->peak->y;
    868     psF32 xOff = source->pixels->col0 - source->peak->x;
    869     psF32 yOff = source->pixels->row0 - source->peak->y;
    870 
    871     // XXX why do I get different results for these two methods of finding Sx?
    872     // XXX Sx, Sy would be better measured if we clip pixels close to sky
    873     // XXX Sx, Sy can still be imaginary, so we probably need to keep Sx^2?
    874     // We loop through all pixels in this subimage (source->pixels), and for each
    875     // pixel that is not masked, AND within the radius of the peak pixel, we
    876     // proceed with the moments calculation.  need to do two loops for a
    877     // numerically stable result.  first loop: get the sums.
    878     // XXX EAM : mask == 0 is valid
    879 
    880     for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    881 
    882         psF32 *vPix = source->pixels->data.F32[row];
    883         psF32 *vWgt = source->variance->data.F32[row];
    884         psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
    885 
    886         for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
    887             if (vMsk) {
    888                 if (*vMsk) {
    889                     vMsk++;
    890                     psTrace("psModules.objects", 10, "Ignoring pixel %d,%d due to mask: %d\n",
    891                             col, row, (int)*vMsk);
    892                     continue;
    893                 }
    894                 vMsk++;
    895             }
    896             if (isnan(*vPix)) continue;
    897 
    898             psF32 xDiff = col + xOff;
    899             psF32 yDiff = row + yOff;
    900 
    901             // radius is just a function of (xDiff, yDiff)
    902             if (!VALID_RADIUS(xDiff, yDiff, R2)) {
    903 #if 1
    904                 psTrace("psModules.objects", 10, "Ignoring pixel %d,%d due to position: %f %f\n",
    905                         col, row, xDiff, yDiff);
    906 #endif
    907                 continue;
    908             }
    909 
    910             psF32 pDiff = *vPix - sky;
    911             psF32 wDiff = *vWgt;
    912 
    913             // XXX EAM : check for valid S/N in pixel
    914             // XXX EAM : should this limit be user-defined?
    915 #if 1
    916             if (PS_SQR(pDiff) < wDiff) {
    917                 psTrace("psModules.objects", 10, "Ignoring pixel %d,%d due to insignificance: %f, %f\n",
    918                         col, row, pDiff, wDiff);
    919                 continue;
    920             }
    921 #endif
    922 
    923             Var += wDiff;
    924             Sum += pDiff;
    925 
    926             psF32 xWght = xDiff * pDiff;
    927             psF32 yWght = yDiff * pDiff;
    928 
    929             X1  += xWght;
    930             Y1  += yWght;
    931 
    932             XY  += xDiff * yWght;
    933             X2  += xDiff * xWght;
    934             Y2  += yDiff * yWght;
    935 
    936             peakPixel = PS_MAX (*vPix, peakPixel);
    937             numPixels++;
    938         }
    939     }
    940 
    941     // if we have less than (1/4) of the possible pixels, force a retry
    942     // XXX EAM - the limit is a bit arbitrary.  make it user defined?
    943     if ((numPixels < 0.75*R2) || (Sum <= 0)) {
    944         psTrace ("psModules.objects", 3, "insufficient valid pixels (%d vs %d; %f) for source\n",
    945                  numPixels, (int)(0.75*R2), Sum);
    946         psTrace("psModules.objects", 10, "---- end (false) ----\n");
    947         return (false);
    948     }
    949 
    950     psTrace ("psModules.objects", 4, "sky: %f  Sum: %f  X1: %f  Y1: %f  X2: %f  Y2: %f  XY: %f  Npix: %d\n",
    951              sky, Sum, X1, Y1, X2, Y2, XY, numPixels);
    952 
    953     //
    954     // first moment X  = X1/Sum + xc
    955     // second moment X = sqrt (X2/Sum - (X1/Sum)^2)
    956     // Sxy             = XY / Sum
    957     //
    958     x = X1/Sum;
    959     y = Y1/Sum;
    960     if ((fabs(x) > radius) || (fabs(y) > radius)) {
    961         psTrace ("psModules.objects", 3, "large centroid swing; invalid peak %d, %d\n",
    962                  source->peak->x, source->peak->y);
    963         psTrace("psModules.objects", 10, "---- end(false)  ----\n");
    964         return (false);
    965     }
    966 
    967     source->moments->Mx = x + xPeak;
    968     source->moments->My = y + yPeak;
    969 
    970     // XXX EAM : Sxy needs to have x*y subtracted
    971     source->moments->Mxy = XY/Sum - x*y;
    972     source->moments->Sum = Sum;
    973     source->moments->SN  = Sum / sqrt(Var);
    974     source->moments->Peak = peakPixel;
    975     source->moments->nPixels = numPixels;
    976 
    977     // XXX EAM : these values can be negative, so we need to limit the range
    978     // XXX EAM : make the use of this consistent: should this be the second moment or sqrt?
    979     // source->moments->Mxx = sqrt(PS_MAX(X2/Sum - PS_SQR(x), 0));
    980     // source->moments->Myy = sqrt(PS_MAX(Y2/Sum - PS_SQR(y), 0));
    981     source->moments->Mxx = PS_MAX(X2/Sum - PS_SQR(x), 0);
    982     source->moments->Myy = PS_MAX(Y2/Sum - PS_SQR(y), 0);
    983 
    984     psTrace ("psModules.objects", 4,
    985              "sky: %f  Sum: %f  Mx: %f  My: %f  Mxx: %f  Myy: %f  Mxy: %f\n",
    986              sky, Sum, source->moments->Mx, source->moments->My,
    987              source->moments->Mxx, source->moments->Myy, source->moments->Mxy);
    988 
    989     psTrace("psModules.objects", 10, "---- end ----\n");
    990     return(true);
    991 }
    992 # endif
    993817
    994818// construct a realization of the source model
     
    1165989    if (!isfinite(oldI0)) return false;
    1166990
    1167     bool useReff = pmModelUseReff (model->type);
     991    bool useReff = model->class->useReff;
    1168992    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
    1169993
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSource.h

    r34403 r37066  
    4040    PM_SOURCE_TMPF_PETRO_KEEP        = 0x0100,
    4141    PM_SOURCE_TMPF_PETRO_SKIP        = 0x0200,
     42    PM_SOURCE_TMPF_EXT_FIT           = 0x0400,  // not just galaxies (trails as well)
     43    PM_SOURCE_TMPF_PETRO             = 0x0800,
    4244} pmSourceTmpF;
    4345
     
    9597    float apMagRaw;                     ///< raw mag in given aperture
    9698    float apRadius;                     ///< radius for aperture magnitude
     99    int   apNpixels;                    ///< number of unmasked pixels in aperture
    97100    float apFlux;                       ///< apFlux corresponding to psfMag or extMag (depending on type)
    98101    float apFluxErr;                    ///< apFluxErr corresponding to psfMag or extMag (depending on type)
     
    111114    float sky;                          ///< The sky at the center of the object
    112115    float skyErr;                       ///< The sky error at the center of the object
     116    float extSN;                        ///< for externally supplied source the kron signal to noise (used by full force)
    113117
    114118    psRegion region;                    ///< area on image covered by selected pixels
     
    117121    pmSourceExtendedPars *extpars;      ///< extended source parameters
    118122    pmSourceDiffStats *diffStats;       ///< extra parameters for difference detections
     123    psArray *galaxyFits;                ///< fits to galaxy models (psphotFullForce only)
     124    pmSourceLensing *lensingOBJ;        ///< lensing moments parameters (per object)
     125    pmSourceLensing *lensingPSF;        ///< lensing moments parameters (psf, interpolated)
    119126    psArray *radialAper;                ///< radial flux in circular apertures
    120127    pmSource *parent;                   ///< reference to the master source from which this is derived
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceContour.c

    r34403 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838#include "pmSourceMasks.h"
    3939#include "pmSourceExtendedPars.h"
    4040#include "pmSourceDiffStats.h"
    4141#include "pmSourceSatstar.h"
     42#include "pmSourceLensing.h"
    4243#include "pmSource.h"
    4344
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceExtendedPars.c

    r34403 r37066  
    286286    return pars;
    287287}
     288
     289// *** pmSourceExtFitPars describes extra metadata related to an extended fit
     290static void pmSourceGalaxyFitsFree (pmSourceGalaxyFits *tmp) {
     291 
     292    psFree (tmp->Flux);
     293    psFree (tmp->dFlux);
     294    psFree (tmp->chisq);
     295
     296    return;
     297}
     298
     299pmSourceGalaxyFits *pmSourceGalaxyFitsAlloc (void) {
     300
     301    pmSourceGalaxyFits *tmp = (pmSourceGalaxyFits *) psAlloc(sizeof(pmSourceGalaxyFits));
     302    psMemSetDeallocator(tmp, (psFreeFunc) pmSourceGalaxyFitsFree);
     303
     304    tmp->Flux  = psVectorAllocEmpty (25, PS_TYPE_F32);
     305    tmp->dFlux = psVectorAllocEmpty (25, PS_TYPE_F32);
     306    tmp->chisq = psVectorAllocEmpty (25, PS_TYPE_F32);
     307    tmp->nPix = 0;
     308
     309    return tmp;
     310}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceExtendedPars.h

    r32347 r37066  
    8282} pmSourceExtFitPars;
    8383
     84typedef struct {
     85  int       modelType;
     86  psVector *Flux;
     87  psVector *dFlux;
     88  psVector *chisq;
     89  int       nPix;
     90  bool      reducedTrials;
     91  float     fRmajorMin;
     92  float     fRmajorMax;
     93  float     fRmajorDel;
     94  float     fRminorMin;
     95  float     fRminorMax;
     96  float     fRminorDel;
     97} pmSourceGalaxyFits;
     98
    8499pmSourceRadialFlux *pmSourceRadialFluxAlloc();
    85100bool psMemCheckSourceRadialFlux(psPtr ptr);
     
    109124pmSourceExtFitPars *pmSourceExtFitParsAlloc (void);
    110125
     126pmSourceGalaxyFits *pmSourceGalaxyFitsAlloc (void);
     127
    111128/// @}
    112129# endif /* PM_SOURCE_H */
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceFitModel.c

    r35768 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838#include "pmSourceMasks.h"
    3939#include "pmSourceExtendedPars.h"
    4040#include "pmSourceDiffStats.h"
    4141#include "pmSourceSatstar.h"
     42#include "pmSourceLensing.h"
    4243#include "pmSource.h"
    4344#include "pmSourcePhotometry.h"
     
    5960    opt->maxTol = 1.00;
    6061    opt->weight = 1.00;
     62    opt->nsigma = 5.00;
    6163    opt->maxChisqDOF = NAN;
    6264    opt->poissonErrors = true;
     
    6668    opt->gainFactorMode = 0;
    6769    opt->chisqConvergence = true;
     70    opt->isInteractive = false;
    6871
    6972    return opt;
     
    167170    psMinConstraint *constraint = psMinConstraintAlloc();
    168171    constraint->paramMask = psVectorAlloc (params->n, PS_TYPE_VECTOR_MASK);
    169     constraint->checkLimits = model->modelLimits;
     172    constraint->checkLimits = model->class->modelLimits;
    170173
    171174    // set parameter mask based on fitting mode
     
    230233    // force the floating parameters to fall within the contraint ranges
    231234    for (int i = 0; i < params->n; i++) {
    232         model->modelLimits (PS_MINIMIZE_PARAM_MIN, i, params->data.F32, NULL);
    233         model->modelLimits (PS_MINIMIZE_PARAM_MAX, i, params->data.F32, NULL);
     235        model->class->modelLimits (PS_MINIMIZE_PARAM_MIN, i, params->data.F32, NULL);
     236        model->class->modelLimits (PS_MINIMIZE_PARAM_MAX, i, params->data.F32, NULL);
    234237    }
    235238
     
    247250    myMin->gainFactorMode = options->gainFactorMode;
    248251    myMin->chisqConvergence = options->chisqConvergence;
     252    myMin->isInteractive = options->isInteractive;
    249253
    250254    psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32);
    251255
    252     fitStatus = psMinimizeLMChi2(myMin, covar, params, constraint, x, y, yErr, model->modelFunc);
     256    fitStatus = psMinimizeLMChi2(myMin, covar, params, constraint, x, y, yErr, model->class->modelFunc);
    253257    for (int i = 0; i < dparams->n; i++) {
    254258        if ((constraint->paramMask != NULL) && constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[i])
     
    279283    // set the model success or failure status
    280284    model->flags |= PM_MODEL_STATUS_FITTED;
    281     if (!fitStatus) model->flags |= PM_MODEL_STATUS_NONCONVERGE;
     285    if (!fitStatus) {
     286        if (isnan(myMin->value)) {
     287          model->flags |= PM_MODEL_STATUS_NAN_CHISQ;
     288        } else {
     289          model->flags |= PM_MODEL_STATUS_NONCONVERGE;
     290        }
     291    }
    282292
    283293    if (myMin->chisqConvergence) {
     
    296306            altmask->data.PS_TYPE_VECTOR_MASK_DATA[i] = (constraint->paramMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) ? 0 : 1;
    297307        }
    298         psMinimizeGaussNewtonDelta(delta, params, altmask, x, y, yErr, model->modelFunc);
     308        psMinimizeGaussNewtonDelta(delta, params, altmask, x, y, yErr, model->class->modelFunc);
    299309
    300310        for (int i = 0; i < dparams->n; i++) {
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceFitModel.h

    r35768 r37066  
    2121    PM_SOURCE_FIT_EXT_AND_SKY,
    2222    PM_SOURCE_FIT_INDEX,
     23    PM_SOURCE_FIT_SHAPE,
    2324    PM_SOURCE_FIT_NO_INDEX,
    2425    PM_SOURCE_FIT_TRAIL,
     
    3334    float weight;                       ///< use this weight for constant-weight fits
    3435    float covarFactor;                  ///< covariance factor for calculating the chisq
     36    float nsigma;                       ///< how far out to convolve
    3537    bool poissonErrors;                 ///< use poisson errors for fits?
    3638    bool saveCovariance;
    3739    int gainFactorMode;
    3840    bool chisqConvergence;
     41    bool isInteractive;
    3942} pmSourceFitOptions;
    4043
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceFitPCM.c

    r35768 r37066  
    3131#include "pmMoments.h"
    3232#include "pmModelFuncs.h"
     33#include "pmModelClass.h"
    3334#include "pmModel.h"
    3435#include "pmModelUtils.h"
    35 #include "pmModelClass.h"
    3636#include "pmSourceMasks.h"
    3737#include "pmSourceExtendedPars.h"
    3838#include "pmSourceDiffStats.h"
    3939#include "pmSourceSatstar.h"
     40#include "pmSourceLensing.h"
    4041#include "pmSource.h"
    4142#include "pmSourcePhotometry.h"
     
    5152# define TIMING 0
    5253
     54bool pmSourceChisqModelFlux (pmSource *source, pmModel *model, psImageMaskType maskVal);
     55
    5356bool pmSourceFitPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {
    5457   
     
    6063    // force the floating parameters to fall within the contraint ranges
    6164    for (int i = 0; i < params->n; i++) {
    62         pcm->modelConv->modelLimits (PS_MINIMIZE_PARAM_MIN, i, params->data.F32, NULL);
    63         pcm->modelConv->modelLimits (PS_MINIMIZE_PARAM_MAX, i, params->data.F32, NULL);
     65        pcm->modelConv->class->modelLimits (PS_MINIMIZE_PARAM_MIN, i, params->data.F32, NULL);
     66        pcm->modelConv->class->modelLimits (PS_MINIMIZE_PARAM_MAX, i, params->data.F32, NULL);
    6467    }
    6568
     
    6871    myMin->chisqConvergence = fitOptions->chisqConvergence;
    6972    myMin->gainFactorMode = fitOptions->gainFactorMode;
     73    myMin->isInteractive = fitOptions->isInteractive;
    7074
    7175    psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32);
     
    112116    } else {
    113117        // xxx this is wrong because it does not convolve with the psf
    114         pmSourceChisqUnsubtracted (source, pcm->modelConv, maskVal);
     118        pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize);
     119        pmSourceChisqModelFlux (source, pcm->modelConv, maskVal);
    115120    }
    116121    if (TIMING) { t4 = psTimerMark ("pmSourceFitPCM"); }
     
    118123    // set the model success or failure status
    119124    pcm->modelConv->flags |= PM_MODEL_STATUS_FITTED;
    120     if (!fitStatus) pcm->modelConv->flags |= PM_MODEL_STATUS_NONCONVERGE;
     125
     126    if (!fitStatus) {
     127        if (isnan(myMin->value)) {
     128            pcm->modelConv->flags |= PM_MODEL_STATUS_NAN_CHISQ;
     129        } else {
     130            pcm->modelConv->flags |= PM_MODEL_STATUS_NONCONVERGE;
     131        }
     132    }
    121133
    122134    if (myMin->chisqConvergence) {
     
    153165bool pmSourceModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) {
    154166
    155     if (!pcm->modelConv->modelGuess(pcm->modelConv, source, maskVal, markVal)) {
     167    if (!pcm->modelConv->class->modelGuess(pcm->modelConv, source, maskVal, markVal)) {
    156168        return false;
    157169    }
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceFitSet.c

    r35768 r37066  
    3232#include "pmMoments.h"
    3333#include "pmModelFuncs.h"
     34#include "pmModelClass.h"
    3435#include "pmModel.h"
    3536#include "pmModelUtils.h"
    36 #include "pmModelClass.h"
    3737#include "pmSourceMasks.h"
    3838#include "pmSourceExtendedPars.h"
    3939#include "pmSourceDiffStats.h"
    4040#include "pmSourceSatstar.h"
     41#include "pmSourceLensing.h"
    4142#include "pmSource.h"
    4243#include "pmSourcePhotometry.h"
     
    222223    float *paramOne = params + nParamBase;
    223224    float *betaOne = betas + nParamBase;
    224     bool status = model->modelLimits (mode, nParamOne, paramOne, betaOne);
     225    bool status = model->class->modelLimits (mode, nParamOne, paramOne, betaOne);
    225226    return status;
    226227}
     
    352353        // set the model success or failure status
    353354        model->flags |= PM_MODEL_STATUS_FITTED;
    354         if (!fitStatus) model->flags |= PM_MODEL_STATUS_NONCONVERGE;
     355        if (!fitStatus) {
     356          if (isnan(myMin->value)) {
     357            model->flags |= PM_MODEL_STATUS_NAN_CHISQ;
     358          } else {
     359            model->flags |= PM_MODEL_STATUS_NONCONVERGE;
     360          }
     361        }
    355362
    356363        // models can go insane: reject these
     
    381388        psVector *derivOne = thisSet->derivSet->data[i];
    382389
    383         chisqOne = model->modelFunc (derivOne, paramOne, x);
     390        chisqOne = model->class->modelFunc (derivOne, paramOne, x);
    384391        chisqSum += chisqOne;
    385392    }
     
    570577    myMin->gainFactorMode = options->gainFactorMode;
    571578    myMin->chisqConvergence = options->chisqConvergence;
     579    myMin->isInteractive = options->isInteractive;
    572580
    573581    psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceGroups.c

    r34403 r37066  
    1818#include "pmMoments.h"
    1919#include "pmModelFuncs.h"
     20#include "pmModelClass.h"
    2021#include "pmModel.h"
    2122#include "pmModelUtils.h"
    22 #include "pmModelClass.h"
    2323#include "pmSourceMasks.h"
    2424#include "pmSourceExtendedPars.h"
    2525#include "pmSourceDiffStats.h"
    2626#include "pmSourceSatstar.h"
     27#include "pmSourceLensing.h"
    2728#include "pmSource.h"
    2829#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO.c

    r35610 r37066  
    4040#include "pmMoments.h"
    4141#include "pmModelFuncs.h"
     42#include "pmModelClass.h"
    4243#include "pmModel.h"
    4344#include "pmModelUtils.h"
    44 #include "pmModelClass.h"
    4545#include "pmSourceMasks.h"
    4646#include "pmSourceExtendedPars.h"
    4747#include "pmSourceDiffStats.h"
    4848#include "pmSourceSatstar.h"
     49#include "pmSourceLensing.h"
    4950#include "pmSource.h"
    5051#include "pmSourceFitModel.h"
     
    6162static bool pmReadoutReadXFIT(pmFPAfile *file, pmReadout *readout, char * exttype, psMetadata *hduHeader, psString xfitname, psArray *sources, long *sourceIndex);
    6263static bool pmReadoutReadXRAD(pmFPAfile *file, pmReadout *readout, char * exttype, psMetadata *hduHeader, psString xfitname, psArray *sources, long *sourceIndex);
     64static bool pmReadoutReadXGAL(pmFPAfile *file, pmReadout *readout, char * exttype, psMetadata *hduHeader, psString xfitname, psArray *sources, long *sourceIndex);
    6365
    6466// lookup the EXTNAME values used for table data and image header segments
     
    6971                        psString *xfitname,    // Extension name for extended fitted measurements
    7072                        psString *xradname,    // Extension name for radial apertures
     73                        psString *xgalname,    // Extension name for galaxy shapes
    7174                        const pmFPAfile *file, // File of interest
    7275                        const pmFPAview *view  // View to level of interest
     
    140143        }
    141144        *xradname = pmFPAfileNameFromRule (rule, file, view);
     145    }
     146
     147    // EXTNAME for radial apertures
     148    if (xgalname) {
     149        const char *rule = psMetadataLookupStr(&status, menu, "CMF.XGAL");
     150        if (!rule) {
     151            psError(PS_ERR_UNKNOWN, true, "missing entry for CMF.XGAL in EXTNAME.RULES in camera.config");
     152            return false;
     153        }
     154        *xgalname = pmFPAfileNameFromRule (rule, file, view);
    142155    }
    143156
     
    352365# define PM_SOURCES_WRITE(NAME,TYPE)                                    \
    353366    if (!strcmp (exttype, NAME)) {                                      \
    354         status &= pmSourcesWrite_##TYPE(file->fits, readout, sources, file->header, outhead, dataname, recipe); \
     367        status = pmSourcesWrite_##TYPE(file->fits, readout, sources, file->header, outhead, dataname, recipe); \
    355368        if (xsrcname) {                                                 \
    356369            status &= pmSourcesWrite_##TYPE##_XSRC(file->fits, readout, sources, file->header, xsrcname, recipe); \
     
    362375            status &= pmSourcesWrite_##TYPE##_XRAD (file->fits, readout, sources, file->header, xradname, recipe); \
    363376        }                                                               \
     377        if (xgalname) {                                                 \
     378            status &= pmSourcesWrite_##TYPE##_XGAL (file->fits, readout, sources, xgalname, recipe); \
     379        }                                                               \
    364380    }
    365381
     
    464480        }
    465481
    466         // if this is not TRUE, the output files only contain the psf measurements.
    467         bool XSRC_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_ANALYSIS");
     482        // if none of these are TRUE, the output files only contain the psf measurements.
     483        bool doPetrosian = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
     484        bool doAnnuli    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
     485        bool XSRC_OUTPUT = doPetrosian || doAnnuli;
    468486        bool XFIT_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_FITS");
    469487        bool XRAD_OUTPUT = psMetadataLookupBool(&status, recipe, "RADIAL_APERTURES");
     488        bool XGAL_OUTPUT = psMetadataLookupBool(&status, recipe, "GALAXY_SHAPES");
    470489
    471490        // define the EXTNAME values for the different data segments:
     
    476495        psString xfitname = NULL;
    477496        psString xradname = NULL;
     497        psString xgalname = NULL;
    478498        if (!pmSourceIOextnames(&headname, &dataname, &deteffname,
    479499                                XSRC_OUTPUT ? &xsrcname : NULL,
    480500                                XFIT_OUTPUT ? &xfitname : NULL,
    481501                                XRAD_OUTPUT ? &xradname : NULL,
     502                                XGAL_OUTPUT ? &xgalname : NULL,
    482503                                file, view)) {
    483504            return false;
     
    563584                psMetadataAddStr (outhead, PS_LIST_TAIL, "XRADNAME", PS_META_REPLACE, "name of XRAD table extension", xradname);
    564585            }
     586            if (xgalname) {
     587                psMetadataAddStr (outhead, PS_LIST_TAIL, "XGALNAME", PS_META_REPLACE, "name of XGAL table extension", xgalname);
     588            }
    565589
    566590            // these are case-sensitive since the EXTYPE is case-sensitive
    567             status = true;
     591            status = false;
    568592            PM_SOURCES_WRITE("SMPDATA",   SMPDATA);
    569593            PM_SOURCES_WRITE("PS1_DEV_0", PS1_DEV_0);
     
    574598            PM_SOURCES_WRITE("PS1_V3",    CMF_PS1_V3);
    575599            PM_SOURCES_WRITE("PS1_V4",    CMF_PS1_V4);
     600            PM_SOURCES_WRITE("PS1_V5",    CMF_PS1_V5);
    576601            PM_SOURCES_WRITE("PS1_SV1",   CMF_PS1_SV1);
    577602            PM_SOURCES_WRITE("PS1_SV2",   CMF_PS1_SV2);
     603            PM_SOURCES_WRITE("PS1_SV3",   CMF_PS1_SV3);
    578604            PM_SOURCES_WRITE("PS1_DV1",   CMF_PS1_DV1);
    579605            PM_SOURCES_WRITE("PS1_DV2",   CMF_PS1_DV2);
    580606            PM_SOURCES_WRITE("PS1_DV3",   CMF_PS1_DV3);
     607            PM_SOURCES_WRITE("PS1_DV4",   CMF_PS1_DV4);
    581608
    582609            psFree (outhead);
     
    609636        psFree (xfitname);
    610637        psFree (xradname);
     638        psFree (xgalname);
    611639        psFree (deteffname);
    612640
     
    620648        psFree (xfitname);
    621649        psFree (xradname);
     650        psFree (xgalname);
    622651        psFree (deteffname);
    623652        return false;
    624653
     654      case PM_FPA_FILE_CFF: {
     655        // determine the output table format
     656        psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, "PSPHOT");
     657        if (!status) {
     658            psError(PS_ERR_UNKNOWN, true, "missing recipe PSPHOT in config data");
     659            return false;
     660        }
     661
     662        hdu = pmFPAviewThisHDU (view, fpa);
     663        pmConfigConformHeader(hdu->header, file->format);
     664        psFitsWriteBlank (file->fits, hdu->header, NULL);
     665        file->header = hdu->header;
     666        file->wrote_phu = true;
     667        if (!pmSourcesWrite_CFF(readout, file->fits, sources, hdu->header, recipe)) {
     668            psError(PS_ERR_UNKNOWN, false, "failed to write CFF");
     669            return false;
     670        }
     671        break;
     672      }
     673       
    625674      default:
    626675        fprintf (stderr, "warning: type mismatch\n");
     
    914963    psArray *sources = NULL;
    915964    pmHDU *hdu;
     965
     966    // define the EXTNAME values for the different data segments:
     967    psString headname = NULL;
     968    psString dataname = NULL;
     969    psString deteffname = NULL;
     970    psString xsrcname = NULL;
     971    psString xfitname = NULL;
     972    psString xradname = NULL;
     973    psString xgalname = NULL;
     974
     975    psMetadata *tableHeader = NULL;
     976    char *xtension = NULL;
    916977
    917978    switch (file->type) {
     
    9631024        hdu = pmFPAviewThisHDU (view, file->fpa);
    9641025
    965         // define the EXTNAME values for the different data segments:
    966         psString headname = NULL;
    967         psString dataname = NULL;
    968         psString deteffname = NULL;
    969         psString xsrcname = NULL;
    970         psString xfitname = NULL;
    971         psString xradname = NULL;
    972 
    9731026        // determine the output table format. Assume if we need to output extendend source
    9741027        // parameters that they may exist in the input.
     
    9811034        }
    9821035
    983         // if this is not TRUE, the output files only contain the psf measurements.
    984         bool XSRC_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_ANALYSIS");
     1036        // if none of these are TRUE, we only read the psf measurements
     1037        // XXX: shouldn't we look for these extensions and read the regardless of the recipe values?
     1038        bool doPetrosian = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN");
     1039        bool doAnnuli    = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");
     1040        bool XSRC_OUTPUT = doPetrosian || doAnnuli;
    9851041        bool XFIT_OUTPUT = psMetadataLookupBool(&status, recipe, "EXTENDED_SOURCE_FITS");
    9861042        bool XRAD_OUTPUT = psMetadataLookupBool(&status, recipe, "RADIAL_APERTURES");
     1043        bool XGAL_OUTPUT = psMetadataLookupBool(&status, recipe, "GALAXY_SHAPES");
    9871044
    9881045        if (!pmSourceIOextnames(&headname, &dataname, &deteffname,
     
    9901047                XFIT_OUTPUT ? &xfitname : NULL,
    9911048                XRAD_OUTPUT ? &xradname : NULL,
     1049                XGAL_OUTPUT ? &xgalname : NULL,
    9921050                file, view)) {
    9931051            return false;
     
    10331091        }
    10341092
    1035         psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header
     1093        tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header
    10361094        if (!tableHeader) psAbort("cannot read table header");
    10371095
    1038         char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION");
     1096        xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION");
    10391097        if (!xtension) psAbort("cannot read table type");
    10401098        if (strcmp (xtension, "BINTABLE")) {
     
    10621120            PM_SOURCES_READ_PSF("PS1_V3",    CMF_PS1_V3);
    10631121            PM_SOURCES_READ_PSF("PS1_V4",    CMF_PS1_V4);
     1122            PM_SOURCES_READ_PSF("PS1_V5",    CMF_PS1_V5);
    10641123            PM_SOURCES_READ_PSF("PS1_SV1",   CMF_PS1_SV1);
    10651124            PM_SOURCES_READ_PSF("PS1_SV2",   CMF_PS1_SV2);
     1125            PM_SOURCES_READ_PSF("PS1_SV3",   CMF_PS1_SV3);
    10661126            PM_SOURCES_READ_PSF("PS1_DV1",   CMF_PS1_DV1);
    10671127            PM_SOURCES_READ_PSF("PS1_DV2",   CMF_PS1_DV2);
    10681128            PM_SOURCES_READ_PSF("PS1_DV3",   CMF_PS1_DV3);
     1129            PM_SOURCES_READ_PSF("PS1_DV4",   CMF_PS1_DV4);
     1130
     1131            if (!sources) {
     1132                psError(PS_ERR_IO, false, "reading CMF data from %s with format %s\n", file->filename, exttype);
     1133                return false;
     1134            }
    10691135
    10701136            long *sourceIndex = NULL;
    1071             if (XSRC_OUTPUT || XFIT_OUTPUT || XRAD_OUTPUT) {
     1137            if (XSRC_OUTPUT || XFIT_OUTPUT || XRAD_OUTPUT || XGAL_OUTPUT) {
     1138                // Build sourceIndex. Lookup table from source->seq to index in sources array.
     1139                // Consists of an array of length max(source->seq) + 1.
     1140
     1141                // find maximum sequence number
    10721142                long seq_max = -1;
    10731143                for (long i = sources->n -1; i >= 0; i--) {
     
    10821152                    }
    10831153                }
     1154                // allocate and initialize the index
    10841155                sourceIndex = psAlloc((seq_max + 1) * sizeof(long));
    10851156                for (long i = 0; i < seq_max; i++) {
    10861157                    sourceIndex[i] = -1;
    10871158                }
     1159                // populate the index
    10881160                for (long i = 0; i < sources->n; i++) {
    10891161                    pmSource *source = sources->data[i];
     
    11111183                }
    11121184                psFree(xradname);
     1185            }
     1186            if (XGAL_OUTPUT && xgalname) {
     1187                // a cmf file may have an XGAL extension, but it is not required
     1188                if (!pmReadoutReadXGAL(file, readout, exttype, hdu->header, xgalname, sources, sourceIndex)) {
     1189                    // do anything?
     1190                }
     1191                psFree(xgalname);
    11131192            }
    11141193            psFree(sourceIndex);
     
    11321211        break;
    11331212
     1213      case PM_FPA_FILE_CFF: {
     1214        // determine the output table format
     1215        psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, "PSPHOT");
     1216        if (!status) {
     1217            psError(PS_ERR_UNKNOWN, true, "missing recipe PSPHOT in config data");
     1218            return false;
     1219        }
     1220        // read in header, if not yet loaded
     1221        hdu = pmFPAviewThisHDU (view, file->fpa);
     1222
     1223        // look these up in the camera config?
     1224        // headrule = {CHIP.NAME}.hdr
     1225        // datarule = {CHIP.NAME}.cff
     1226
     1227        // define the EXTNAME values for the different data segments:
     1228        headname = pmFPAfileNameFromRule("{CHIP.NAME}.hdr", file, view);
     1229        dataname = pmFPAfileNameFromRule("{CHIP.NAME}.cff", file, view);
     1230
     1231        // advance to the IMAGE HEADER extension
     1232        if (hdu->header == NULL) {
     1233            // if the IMAGE header does not exist, we have no data for this view
     1234            if (!psFitsMoveExtNameClean (file->fits, headname)) {
     1235                readout->data_exists = false;
     1236                psFree (headname);
     1237                psFree (dataname);
     1238                return true;
     1239            }
     1240            hdu->header = psFitsReadHeader (NULL, file->fits);
     1241        }
     1242
     1243        // advance to the table data extension
     1244        // since we have read the IMAGE header, the TABLE header should exist
     1245        if (!psFitsMoveExtName (file->fits, dataname)) {
     1246            psAbort("cannot find data extension %s in %s", dataname, file->filename);
     1247        }
     1248
     1249        tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header
     1250        if (!tableHeader) psAbort("cannot read table header");
     1251
     1252        // verify this is a binary table
     1253        char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION");
     1254        if (!xtension) psAbort("cannot read table type");
     1255        if (strcmp (xtension, "BINTABLE")) {
     1256            psWarning ("no binary table in extension %s, skipping\n", dataname);
     1257            psFree(tableHeader);
     1258            return false;
     1259        }
     1260
     1261        sources = pmSourcesRead_CFF(file->fits, hdu->header, recipe);
     1262
     1263        psTrace("psModules.objects", 6, "read CMF table from %s : %s : %s", file->filename, headname, dataname);
     1264        psFree (headname);
     1265        psFree (dataname);
     1266        psFree (tableHeader);
     1267        }
     1268        break;
     1269
    11341270      default:
    11351271        fprintf (stderr, "warning: type mismatch\n");
     
    12721408        PM_SOURCES_READ_XSRC("PS1_V3",    CMF_PS1_V3);
    12731409        PM_SOURCES_READ_XSRC("PS1_V4",    CMF_PS1_V4);
     1410        PM_SOURCES_READ_XSRC("PS1_V5",    CMF_PS1_V5);
    12741411        PM_SOURCES_READ_XSRC("PS1_SV1",   CMF_PS1_SV1);
    12751412        PM_SOURCES_READ_XSRC("PS1_SV2",   CMF_PS1_SV2);
     1413        PM_SOURCES_READ_XSRC("PS1_SV3",   CMF_PS1_SV3);
    12761414        PM_SOURCES_READ_XSRC("PS1_DV1",   CMF_PS1_DV1);
    12771415        PM_SOURCES_READ_XSRC("PS1_DV2",   CMF_PS1_DV2);
    12781416        PM_SOURCES_READ_XSRC("PS1_DV3",   CMF_PS1_DV3);
     1417        PM_SOURCES_READ_XSRC("PS1_DV4",   CMF_PS1_DV4);
    12791418    }
    12801419    psFree(tableHeader);
     
    13111450        PM_SOURCES_READ_XFIT("PS1_V3",    CMF_PS1_V3);
    13121451        PM_SOURCES_READ_XFIT("PS1_V4",    CMF_PS1_V4);
     1452        PM_SOURCES_READ_XFIT("PS1_V5",    CMF_PS1_V5);
    13131453        PM_SOURCES_READ_XFIT("PS1_SV1",   CMF_PS1_SV1);
    13141454        PM_SOURCES_READ_XFIT("PS1_SV2",   CMF_PS1_SV2);
     1455        PM_SOURCES_READ_XFIT("PS1_SV3",   CMF_PS1_SV3);
    13151456        PM_SOURCES_READ_XFIT("PS1_DV1",   CMF_PS1_DV1);
    13161457        PM_SOURCES_READ_XFIT("PS1_DV2",   CMF_PS1_DV2);
    13171458        PM_SOURCES_READ_XFIT("PS1_DV3",   CMF_PS1_DV3);
     1459        PM_SOURCES_READ_XFIT("PS1_DV4",   CMF_PS1_DV4);
    13181460    }
    13191461    psFree(tableHeader);
     
    13491491        PM_SOURCES_READ_XRAD("PS1_V3",    CMF_PS1_V3);
    13501492        PM_SOURCES_READ_XRAD("PS1_V4",    CMF_PS1_V4);
     1493        PM_SOURCES_READ_XRAD("PS1_V5",    CMF_PS1_V5);
    13511494        PM_SOURCES_READ_XRAD("PS1_SV1",   CMF_PS1_SV1);
    13521495        PM_SOURCES_READ_XRAD("PS1_SV2",   CMF_PS1_SV2);
     1496        PM_SOURCES_READ_XRAD("PS1_SV3",   CMF_PS1_SV3);
    13531497        PM_SOURCES_READ_XRAD("PS1_DV1",   CMF_PS1_DV1);
    13541498        PM_SOURCES_READ_XRAD("PS1_DV2",   CMF_PS1_DV2);
    13551499        PM_SOURCES_READ_XRAD("PS1_DV3",   CMF_PS1_DV3);
     1500        PM_SOURCES_READ_XRAD("PS1_DV4",   CMF_PS1_DV4);
    13561501    }
    13571502    psFree(tableHeader);
    13581503    return status;
    13591504}
     1505static bool pmReadoutReadXGAL(pmFPAfile *file, pmReadout *readout, char *exttype, psMetadata *hduHeader, psString xgalname, psArray *sources, long *sourceIndex)
     1506{
     1507    if (!psFitsMoveExtNameClean (file->fits, xgalname)) {
     1508        psTrace ("pmFPAfile", 1, "cannot find xgal extension %s in %s, skipping", xgalname, file->filename);
     1509        return false;
     1510    }
     1511
     1512    psMetadata *tableHeader = psFitsReadHeader(NULL, file->fits); // The FITS header
     1513    if (!tableHeader) psAbort("cannot read table header");
     1514
     1515    char *xtension = psMetadataLookupStr (NULL, tableHeader, "XTENSION");
     1516    if (!xtension) psAbort("cannot read table type");
     1517    if (strcmp (xtension, "BINTABLE")) {
     1518        psFree(tableHeader);
     1519        psWarning ("no binary table in extension %s, skipping\n", xgalname);
     1520        return false;
     1521    }
     1522
     1523# define PM_SOURCES_READ_XGAL(NAME,TYPE)                                \
     1524    if (!strcmp (exttype, NAME)) {                                      \
     1525        status = pmSourcesRead_##TYPE##_XGAL(file->fits, readout, hduHeader, tableHeader, sources, sourceIndex); \
     1526    }                                                                   
     1527
     1528    bool status = false;
     1529    if (file->type == PM_FPA_FILE_CMF) {
     1530        PM_SOURCES_READ_XGAL("PS1_V1",    CMF_PS1_V1);
     1531        PM_SOURCES_READ_XGAL("PS1_V2",    CMF_PS1_V2);
     1532        PM_SOURCES_READ_XGAL("PS1_V3",    CMF_PS1_V3);
     1533        PM_SOURCES_READ_XGAL("PS1_V4",    CMF_PS1_V4);
     1534        PM_SOURCES_READ_XGAL("PS1_V5",    CMF_PS1_V5);
     1535        PM_SOURCES_READ_XGAL("PS1_SV1",   CMF_PS1_SV1);
     1536        PM_SOURCES_READ_XGAL("PS1_SV2",   CMF_PS1_SV2);
     1537        PM_SOURCES_READ_XGAL("PS1_SV3",   CMF_PS1_SV3);
     1538        PM_SOURCES_READ_XGAL("PS1_DV1",   CMF_PS1_DV1);
     1539        PM_SOURCES_READ_XGAL("PS1_DV2",   CMF_PS1_DV2);
     1540        PM_SOURCES_READ_XGAL("PS1_DV3",   CMF_PS1_DV3);
     1541        PM_SOURCES_READ_XGAL("PS1_DV4",   CMF_PS1_DV4);
     1542    }
     1543    psFree(tableHeader);
     1544    return status;
     1545}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO.h

    r35610 r37066  
    2121  bool pmSourcesWrite_##TYPE##_XFIT(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname); \
    2222  bool pmSourcesWrite_##TYPE##_XRAD(psFits *fits, pmReadout *readout, psArray *sources, psMetadata *imageHeader, char *extname, psMetadata *recipe); \
     23  bool pmSourcesWrite_##TYPE##_XGAL(psFits *fits, pmReadout *readout, psArray *sources, char *extname, psMetadata *recipe); \
    2324  psArray *pmSourcesRead_##TYPE (psFits *fits, psMetadata *header); \
    2425  bool pmSourcesRead_##TYPE##_XSRC (psFits *fits, pmReadout *readout, psMetadata *header, psMetadata *tableHeader, psArray *sources, long *index); \
    2526  bool pmSourcesRead_##TYPE##_XFIT (psFits *fits, pmReadout *readout, psMetadata *header, psMetadata *tableHeader, psArray *sources, long *index); \
    2627  bool pmSourcesRead_##TYPE##_XRAD (psFits *fits, pmReadout *readout, psMetadata *header, psMetadata *tableHeader, psArray *sources, long *index);\
     28  bool pmSourcesRead_##TYPE##_XGAL (psFits *fits, pmReadout *readout, psMetadata *header, psMetadata *tableHeader, psArray *sources, long *index);\
    2729 
    2830// All of these functions need to use the same API, even if not all elements are used in a specific case
     
    3537MK_PROTO(CMF_PS1_V3);
    3638MK_PROTO(CMF_PS1_V4);
     39MK_PROTO(CMF_PS1_V5);
    3740MK_PROTO(CMF_PS1_SV1);
    3841MK_PROTO(CMF_PS1_SV2);
     42MK_PROTO(CMF_PS1_SV3);
    3943MK_PROTO(CMF_PS1_DV1);
    4044MK_PROTO(CMF_PS1_DV2);
    4145MK_PROTO(CMF_PS1_DV3);
     46MK_PROTO(CMF_PS1_DV4);
    4247
    4348int pmSourceGetDophotType (pmSource *source);
     
    5257
    5358psArray *pmSourcesReadCMP (char *filename, psMetadata *header);
     59psArray *pmSourcesRead_CFF (psFits *fits, psMetadata *header, psMetadata *recipe);
     60bool pmSourcesWrite_CFF (pmReadout *readout, psFits *fits, psArray *sources, psMetadata *header, psMetadata *recipe);
    5461
    5562bool pmSourcesWritePSFs (psArray *sources, char *filename);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_CMF.c.in

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    141142        @ALL@                       psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG",           PS_DATA_F32, "magnitude in standard aperture",             source->apMag);
    142143        @>PS1_V2,PS1_SV?,>PS1_DV1@  psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RAW",       PS_DATA_F32, "magnitude in reported aperture",             source->apMagRaw);
    143         @ALL@                       psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS",    PS_DATA_F32, "radius used for aperture mags",              outputs.apRadius);
     144        @ALL@                       psMetadataAdd (row, PS_LIST_TAIL, "AP_MAG_RADIUS",    PS_DATA_F32, "radius used for aperture mags",              source->apRadius);
    144145        @>PS1_DV1,>PS1_V3,>PS1_SV1@ psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX",          PS_DATA_F32, "instrumental flux in standard aperture",     source->apFlux);
    145146        @>PS1_DV1,>PS1_V3,>PS1_SV1@ psMetadataAdd (row, PS_LIST_TAIL, "AP_FLUX_SIG",      PS_DATA_F32, "aperture flux error",                        source->apFluxErr);
     147        @>PS1_V4,>PS1_SV2,>PS1_DV3@ psMetadataAdd (row, PS_LIST_TAIL, "AP_NPIX",          PS_DATA_S32, "aperture unmasked pixels",                   source->apNpixels);
    146148
    147149        @<PS1_V3,PS1_SV1,PS1_DV?@ psMetadataAdd (row, PS_LIST_TAIL, "PEAK_FLUX_AS_MAG", PS_DATA_F32, "Peak flux expressed as magnitude",           outputs.peakMag);
     
    162164        @ALL@                     psMetadataAdd (row, PS_LIST_TAIL, "EXT_NSIGMA",       PS_DATA_F32, "Nsigma deviations from PSF to EXT",          source->extNsigma);
    163165
     166        // PSF shape parameters:
    164167        @ALL@                     psMetadataAdd (row, PS_LIST_TAIL, "PSF_MAJOR",        PS_DATA_F32, "PSF width (major axis)",                     outputs.psfMajor);
    165168        @ALL@                     psMetadataAdd (row, PS_LIST_TAIL, "PSF_MINOR",        PS_DATA_F32, "PSF width (minor axis)",                     outputs.psfMinor);
    166169        @ALL@                     psMetadataAdd (row, PS_LIST_TAIL, "PSF_THETA",        PS_DATA_F32, "PSF orientation angle",                      outputs.psfTheta);
     170        @>PS1_V4,>PS1_SV2,>PS1_DV3@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_CORE",         PS_DATA_F32, "k term if defined",                          outputs.psfCore);
     171
     172        // I use a look-up table and linear interpolation to map PSF_MAJOR,PSF_MINOR + PSF_CORE to FWHM values
     173        @>PS1_V4,>PS1_SV2,>PS1_DV3@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_FWHM_MAJ",        PS_DATA_F32, "PSF FWHM (major axis)",                   outputs.psfMajorFWHM);
     174        @>PS1_V4,>PS1_SV2,>PS1_DV3@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_FWHM_MIN",        PS_DATA_F32, "PSF FWHM (minor axis)",                   outputs.psfMinorFWHM);
     175
     176        // psf data quality
    167177        @ALL@                     psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF",           PS_DATA_F32, "PSF coverage/quality factor (bad)",          source->pixWeightNotBad);
    168178        @>PS1_V2,PS1_SV?,>PS1_DV1@ psMetadataAdd (row, PS_LIST_TAIL, "PSF_QF_PERFECT",   PS_DATA_F32, "PSF coverage/quality factor (poor)",         source->pixWeightNotPoor);
     
    178188        @>PS1_V2,PS1_SV?@         psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4C",      PS_DATA_F32, "fourth momemt cos theta",                    moments.M_c4);
    179189        @>PS1_V2,PS1_SV?@         psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_M4S",      PS_DATA_F32, "fourth momemt sin theta",                    moments.M_s4);
     190
     191        // Lensing parameters:
     192        if (source->lensingOBJ && source->lensingOBJ->smear) {
     193          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X11_SM_OBJ",  PS_DATA_F32, "smear polarizability element (objects)",     source->lensingOBJ->smear->X11);
     194          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X12_SM_OBJ",  PS_DATA_F32, "smear polarizability element (objects)",     source->lensingOBJ->smear->X12);
     195          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X22_SM_OBJ",  PS_DATA_F32, "smear polarizability element (objects)",     source->lensingOBJ->smear->X22);
     196          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E1_SM_OBJ",   PS_DATA_F32, "smear polarizability element (objects)",     source->lensingOBJ->smear->e1);
     197          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E2_SM_OBJ",   PS_DATA_F32, "smear polarizability element (objects)",     source->lensingOBJ->smear->e2);
     198        }
     199
     200        if (source->lensingOBJ && source->lensingOBJ->shear) {
     201          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X11_SH_OBJ",  PS_DATA_F32, "shear polarizability element (objects)",     source->lensingOBJ->shear->X11);
     202          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X12_SH_OBJ",  PS_DATA_F32, "shear polarizability element (objects)",     source->lensingOBJ->shear->X12);
     203          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X22_SH_OBJ",  PS_DATA_F32, "shear polarizability element (objects)",     source->lensingOBJ->shear->X22);
     204          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E1_SH_OBJ",   PS_DATA_F32, "shear polarizability element (objects)",     source->lensingOBJ->shear->e1);
     205          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E2_SH_OBJ",   PS_DATA_F32, "shear polarizability element (objects)",     source->lensingOBJ->shear->e2);
     206        }
     207
     208        if (source->lensingPSF && source->lensingPSF->smear) {
     209          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X11_SM_PSF",  PS_DATA_F32, "smear polarizability element (objects)",     source->lensingPSF->smear->X11);
     210          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X12_SM_PSF",  PS_DATA_F32, "smear polarizability element (objects)",     source->lensingPSF->smear->X12);
     211          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X22_SM_PSF",  PS_DATA_F32, "smear polarizability element (objects)",     source->lensingPSF->smear->X22);
     212          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E1_SM_PSF",   PS_DATA_F32, "smear polarizability element (objects)",     source->lensingPSF->smear->e1);
     213          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E2_SM_PSF",   PS_DATA_F32, "smear polarizability element (objects)",     source->lensingPSF->smear->e2);
     214        }
     215
     216        if (source->lensingPSF && source->lensingPSF->shear) {
     217          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X11_SH_PSF",  PS_DATA_F32, "shear polarizability element (objects)",     source->lensingPSF->shear->X11);
     218          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X12_SH_PSF",  PS_DATA_F32, "shear polarizability element (objects)",     source->lensingPSF->shear->X12);
     219          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_X22_SH_PSF",  PS_DATA_F32, "shear polarizability element (objects)",     source->lensingPSF->shear->X22);
     220          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E1_SH_PSF",   PS_DATA_F32, "shear polarizability element (objects)",     source->lensingPSF->shear->e1);
     221          @>PS1_V4@               psMetadataAdd (row, PS_LIST_TAIL, "LENS_E2_SH_PSF",   PS_DATA_F32, "shear polarizability element (objects)",     source->lensingPSF->shear->e2);
     222        }
    180223
    181224        @>PS1_V2,PS1_SV?,>PS1_DV1@ psMetadataAdd (row, PS_LIST_TAIL, "MOMENTS_R1",       PS_DATA_F32, "first radial moment",                        moments.Mrf);
     
    268311
    269312    // define PSF model type
    270     // XXX need to carry the extra model parameters
    271313    int modelType = pmModelClassGetType ("PS_MODEL_GAUSS");
    272314
    273     char *PSF_NAME = psMetadataLookupStr (&status, header, "PSF_NAME");
     315    // if header does not define the model, default to a gaussian
     316    char *PSF_NAME = psMetadataLookupStr (&status, header, "PSFMODEL");
    274317    if (PSF_NAME != NULL) {
    275318        modelType = pmModelClassGetType (PSF_NAME);
    276319    }
    277320    assert (modelType > -1);
     321
     322    // do we expect to find lensing parameters?
     323    bool haveLensOBJ = psMetadataLookupBool (&status, header, "LENS_OBJ");
     324    bool haveLensPSF = psMetadataLookupBool (&status, header, "LENS_PSF");
    278325
    279326    // We get the size of the table, and allocate the array of sources first because the table
     
    310357        @ALL@     axes.theta        = psMetadataLookupF32 (&status, row, "PSF_THETA");
    311358        @ALL@     axes.theta        = axes.theta * PS_RAD_DEG;
     359       
     360        @>PS1_V4,>PS1_SV2,>PS1_DV3@ if (model->params->n > PM_PAR_7) {
     361        @>PS1_V4,>PS1_SV2,>PS1_DV3@     PAR[PM_PAR_7] = psMetadataLookupF32 (&status, row, "PSF_CORE");
     362        @>PS1_V4,>PS1_SV2,>PS1_DV3@ }
    312363
    313364        @ALL@     PAR[PM_PAR_SKY]   = psMetadataLookupF32 (&status, row, "SKY");
     
    321372        @ALL@     source->apMag     = psMetadataLookupF32 (&status, row, "AP_MAG");
    322373        @>PS1_V2,PS1_SV?,>PS1_DV1@ source->apMagRaw  = psMetadataLookupF32 (&status, row, "AP_MAG_RAW");
     374        @>PS1_DV1,>PS1_V3,>PS1_SV1@ source->apFlux = psMetadataLookupF32 (&status, row, "AP_FLUX");
     375        @>PS1_DV1,>PS1_V3,>PS1_SV1@ source->apFluxErr = psMetadataLookupF32 (&status, row, "AP_FLUX_SIG");
    323376
    324377        // XXX use these to determine PAR[PM_PAR_I0] if they exist?
     
    331384        @ALL@     dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN;
    332385
    333         pmPSF_AxesToModel (PAR, axes, modelType);
     386        pmPSF_AxesToModel (PAR, axes, model->class->useReff);
    334387
    335388        @ALL@     float peakMag     = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG");
     
    349402        @ALL@     source->crNsigma  = psMetadataLookupF32 (&status, row, "CR_NSIGMA");
    350403        @ALL@     source->extNsigma = psMetadataLookupF32 (&status, row, "EXT_NSIGMA");
    351         @ALL@     source->apRadius  = psMetadataLookupS32 (&status, row, "AP_MAG_RADIUS");
     404        @ALL@     source->apRadius  = psMetadataLookupF32 (&status, row, "AP_MAG_RADIUS");
     405        @>PS1_V4,>PS1_SV2,>PS1_DV3@ source->apNpixels = psMetadataLookupS32 (&status, row, "AP_NPIX");
    352406
    353407        // note that some older versions used PSF_PROBABILITY: this was not well defined.
     
    376430        @>PS1_V2,PS1_SV?@ source->moments->Mxyyy = -0.25 * psMetadataLookupF32 (&status, row, "MOMENTS_M4S");
    377431        @>PS1_V2,PS1_SV?@ source->moments->Myyyy = 0.0;
     432
     433        // Lensing parameters (on read if PS1_V5+)
     434        if (haveLensOBJ) {
     435          source->lensingOBJ = pmSourceLensingAlloc ();
     436          source->lensingOBJ->smear = pmLensingParsAlloc();
     437          source->lensingOBJ->shear = pmLensingParsAlloc();
     438
     439          @>PS1_V4@ source->lensingOBJ->smear->X11 = psMetadataLookupF32 (&status, row, "LENS_X11_SM_OBJ");
     440          @>PS1_V4@ source->lensingOBJ->smear->X12 = psMetadataLookupF32 (&status, row, "LENS_X12_SM_OBJ");
     441          @>PS1_V4@ source->lensingOBJ->smear->X22 = psMetadataLookupF32 (&status, row, "LENS_X22_SM_OBJ");
     442          @>PS1_V4@ source->lensingOBJ->smear->e1  = psMetadataLookupF32 (&status, row, "LENS_E1_SM_OBJ");
     443          @>PS1_V4@ source->lensingOBJ->smear->e2  = psMetadataLookupF32 (&status, row, "LENS_E2_SM_OBJ");
     444          @>PS1_V4@ source->lensingOBJ->shear->X11 = psMetadataLookupF32 (&status, row, "LENS_X11_SH_OBJ");
     445          @>PS1_V4@ source->lensingOBJ->shear->X12 = psMetadataLookupF32 (&status, row, "LENS_X12_SH_OBJ");
     446          @>PS1_V4@ source->lensingOBJ->shear->X22 = psMetadataLookupF32 (&status, row, "LENS_X22_SH_OBJ");
     447          @>PS1_V4@ source->lensingOBJ->shear->e1  = psMetadataLookupF32 (&status, row, "LENS_E1_SH_OBJ");
     448          @>PS1_V4@ source->lensingOBJ->shear->e2  = psMetadataLookupF32 (&status, row, "LENS_E2_SH_OBJ");
     449        }
     450
     451        if (haveLensPSF) {
     452          source->lensingPSF = pmSourceLensingAlloc ();
     453          source->lensingPSF->smear = pmLensingParsAlloc();
     454          source->lensingPSF->shear = pmLensingParsAlloc();
     455
     456          @>PS1_V4@ source->lensingPSF->smear->X11 = psMetadataLookupF32 (&status, row, "LENS_X11_SM_PSF");
     457          @>PS1_V4@ source->lensingPSF->smear->X12 = psMetadataLookupF32 (&status, row, "LENS_X12_SM_PSF");
     458          @>PS1_V4@ source->lensingPSF->smear->X22 = psMetadataLookupF32 (&status, row, "LENS_X22_SM_PSF");
     459          @>PS1_V4@ source->lensingPSF->smear->e1  = psMetadataLookupF32 (&status, row, "LENS_E1_SM_PSF");
     460          @>PS1_V4@ source->lensingPSF->smear->e2  = psMetadataLookupF32 (&status, row, "LENS_E2_SM_PSF");
     461          @>PS1_V4@ source->lensingPSF->shear->X11 = psMetadataLookupF32 (&status, row, "LENS_X11_SH_PSF");
     462          @>PS1_V4@ source->lensingPSF->shear->X12 = psMetadataLookupF32 (&status, row, "LENS_X12_SH_PSF");
     463          @>PS1_V4@ source->lensingPSF->shear->X22 = psMetadataLookupF32 (&status, row, "LENS_X22_SH_PSF");
     464          @>PS1_V4@ source->lensingPSF->shear->e1  = psMetadataLookupF32 (&status, row, "LENS_E1_SH_PSF");
     465          @>PS1_V4@ source->lensingPSF->shear->e2  = psMetadataLookupF32 (&status, row, "LENS_E2_SH_PSF");
     466        }
    378467
    379468        @>PS1_V2,PS1_SV?,>PS1_DV1@ source->moments->Mrf         = psMetadataLookupF32 (&status, row, "MOMENTS_R1");
     
    448537    }
    449538
     539#ifdef SORT_EXTENSIONS_BY_FLUX
    450540    // let's write these out in S/N order
    451541    sources = psArraySort (sources, pmSourceSortByFlux);
     542#endif
    452543
    453544    table = psArrayAllocEmpty (sources->n);
     
    708799            return false;
    709800        }
    710         // Find the source with this sequence number.
    711         // XXX: I am assuming that sources is sorted in order of seq
     801        // Find the source with this sequence number using the sourceIndex.
    712802        long seq = psMetadataLookupU32 (&status, row, "IPP_IDET");
    713         pmSource *source = NULL;
    714 #ifndef ASSUME_SORTED
    715         long j = seq < sources->n ? seq : sources->n - 1;
    716         for (; j >= 0; j--) {
    717             source = sources->data[j];
    718             if (source->seq == seq) {
    719                 break;
    720             }
    721         }
    722 #else
    723803        long j = sourceIndex[seq];
    724804        psAssert(j >= 0 && j < sources->n, "invalid sourceIndex");
    725         source = sources->data[j];
    726 #endif
     805        pmSource *source = sources->data[j];
    727806        if (!source) {
    728807            psError(PS_ERR_UNKNOWN, false, "Failed to find source for row %ld sequence number %ld\n", i, seq);
     
    789868    char name[64];
    790869
     870    pmModelType modelTypeTrail = pmModelClassGetType("PS_MODEL_TRAIL");
     871
    791872    // create a header to hold the output data
    792873    psMetadata *outhead = psMetadataAlloc ();
    793874
     875    pmModelClassWriteHeader(outhead);
     876
    794877    // write the links to the image header
    795878    psMetadataAddStr (outhead, PS_LIST_TAIL, "EXTNAME", PS_META_REPLACE, "xsrc table extension", extname);
    796879
     880#ifdef SORT_EXTENSIONS_BY_FLUX
    797881    // let's write these out in S/N order
    798882    sources = psArraySort (sources, pmSourceSortByFlux);
    799 
    800     @>PS1_DV2@ float magOffset;
    801     @>PS1_DV2@ float zeroptErr;
    802     @>PS1_DV2@ float fwhmMajor;
    803     @>PS1_DV2@ float fwhmMinor;
    804     @>PS1_DV2@ pmSourceOutputsCommonValues (&magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader);
     883#endif
     884
     885    float magOffset;
     886    float zeroptErr;
     887    float fwhmMajor;
     888    float fwhmMinor;
     889    pmSourceOutputsCommonValues (&magOffset, &zeroptErr, &fwhmMajor, &fwhmMinor, readout, imageHeader);
    805890
    806891    // we are writing one row per model; we need to write out same number of columns for each row: find the max Nparams
     
    823908    @>PS1_DV2@ pmChip *chip = readout->parent->parent;
    824909
     910    pmModelStatus badModel = PM_MODEL_STATUS_NONE;
     911    badModel |= PM_MODEL_STATUS_BADARGS;
     912    badModel |= PM_MODEL_STATUS_OFFIMAGE;
     913    badModel |= PM_MODEL_STATUS_NAN_CHISQ;
     914    badModel |= PM_MODEL_SERSIC_PCM_FAIL_GUESS;
     915    badModel |= PM_MODEL_SERSIC_PCM_FAIL_GRID;
     916    badModel |= PM_MODEL_PCM_FAIL_GUESS;
     917
    825918    table = psArrayAllocEmpty (sources->n);
    826919
     
    847940
    848941            // skip models which were not actually fitted
    849             if (model->flags & PM_MODEL_STATUS_BADARGS) continue;
     942            // XXX
     943            if (model->flags & badModel) continue;
    850944
    851945            PAR = model->params->data.F32;
     
    853947            xPos = PAR[PM_PAR_XPOS];
    854948            yPos = PAR[PM_PAR_YPOS];
    855             xErr = dPAR[PM_PAR_XPOS];
    856             yErr = dPAR[PM_PAR_YPOS];
     949
     950            // for the extended source models, we do not always fit the centroid in the non-linear fitting process
     951            // current situation (hard-wired into psphotSourceFits.c:psphotFitPCM,
     952            // SERSIC, DEV, EXP : X,Y not fitted (PCM and not PCM)
     953            // TRAIL : X,Y are fitted
     954            //
     955           
     956            // XXX this should be based on what happened, not on the model type
     957            if (model->type == modelTypeTrail) {
     958                xErr = dPAR[PM_PAR_XPOS];
     959                yErr = dPAR[PM_PAR_YPOS];
     960            } else {
     961                // this is definitely an underestimate since it does not
     962                // account for the extent of the source
     963                xErr = fwhmMajor * model->magErr / 2.35;
     964                yErr = fwhmMinor * model->magErr / 2.35;
     965            }
    857966
    858967            @>PS1_DV2@ psSphere ptSky = {0.0, 0.0, 0.0, 0.0};
     
    870979            row = psMetadataAlloc ();
    871980
    872             // XXX we are not writing out the mode (flags) or the type (psf, ext, etc)
    873981            // the psMetadataAdd entry and the double quotes are used by grep to select the output fields for automatic documentation
    874982            // This set of psMetadataAdd Entries marks the "----" "Start of the XFIT segment"
     
    888996            @>PS1_DV2@ float calMag = isfinite(magOffset) ? model->mag + magOffset : NAN;
    889997            @>PS1_DV2@ psMetadataAdd (row, PS_LIST_TAIL, "EXT_CAL_MAG", PS_DATA_F32, "EXT Magnitude using supplied calibration",   calMag);
    890             @>PS1_DV2@ psMetadataAdd (row, PS_LIST_TAIL, "EXT_CHISQ",   PS_DATA_F32, "EXT Magnitude using supplied calibration",   model->chisq);
    891             @>PS1_DV2@ psMetadataAdd (row, PS_LIST_TAIL, "EXT_NDOF",    PS_DATA_S32, "EXT Magnitude using supplied calibration",   model->nDOF);
     998            @>PS1_DV2,PS1_SV?@ psMetadataAdd (row, PS_LIST_TAIL, "EXT_CHISQ",   PS_DATA_F32, "EXT Model Chisq",   model->chisq);
     999            @>PS1_DV2,PS1_SV?@ psMetadataAdd (row, PS_LIST_TAIL, "EXT_NDOF",    PS_DATA_S32, "EXT Model num degrees of freedom",   model->nDOF);
     1000            @>PS1_SV1,PS1_SV?@ psMetadataAdd (row, PS_LIST_TAIL, "EXT_MODEL_TYPE",    PS_DATA_S32, "type for chosen EXT_MODEL",   source->modelEXT ? source->modelEXT->type : -1);
     1001
     1002            // EAM : adding for PV2 outputs:
     1003            @>PS1_SV1@ psMetadataAdd (row, PS_LIST_TAIL, "EXT_FLAGS", PS_DATA_S16, "model fit flags (pmModelStatus)", model->flags);
    8921004
    8931005            @>PS1_DV2@ psMetadataAddF32 (row, PS_LIST_TAIL, "POSANGLE",   0, "position angle at source (degrees)",         posAngle);
     
    9251037                    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_THETA_ERR",     0, "EXT angle err (SXY, isnan)", dPAR[PM_PAR_SXY]);
    9261038                } else {
    927                     psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type);
     1039                    psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    9281040                    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MAJ",    0, "EXT width (major axis), length for trail", axes.major);
    9291041                    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MIN",    0, "EXT width (minor axis), sigma for trail",  axes.minor);
     
    9461058
    9471059                snprintf (name, 64, "EXT_PAR_%02d", k);
    948 
     1060               
    9491061                if (k < model->params->n) {
    9501062                    psMetadataAddF32 (row, PS_LIST_TAIL, name, 0, "", model->params->data.F32[k]);
     
    9561068            // optionally, write out the covariance matrix values
    9571069            // XXX do I need to pad this to match the biggest covar matrix?
    958             if (model->covar) {
     1070            if (false && model->covar) {
    9591071                for (int iy = 0; iy < model->covar->numCols; iy++) {
    9601072                    for (int ix = iy; ix < model->covar->numCols; ix++) {
     
    10051117        return false;
    10061118    }
     1119    // set up the lookup table to translate between input model types and output model types
     1120    // if not defined it is assumed that the tables are the same
     1121    pmModelClassReadHeader(tableHeader);
    10071122
    10081123    for (long i = 0; i < numSources; i++) {
     
    10131128            return false;
    10141129        }
    1015         // Find the source with this sequence number.
    1016         // XXX: I am assuming that sources is sorted in order of seq.
    10171130        long seq = psMetadataLookupU32 (&status, row, "IPP_IDET");
    1018         long j = seq < sources->n ? seq : sources->n - 1;
    1019         pmSource *source = NULL;
    1020         for (; j >= 0; j--) {
    1021             source = sources->data[j];
    1022             if (source->seq == seq) {
    1023                 break;
    1024             }
    1025         }
     1131        long j = sourceIndex[seq];
     1132        psAssert(j >= 0 && j < sources->n, "invalid sourceIndex");
     1133        pmSource *source = sources->data[j];
    10261134        if (!source) {
    10271135            psError(PS_ERR_UNKNOWN, false, "Failed to find source for row %ld sequence number %ld\n", i, seq);
     
    10581166        model->magErr = psMetadataLookupF32(&status, row, "EXT_INST_MAG_SIG");
    10591167
     1168        model->chisq = psMetadataLookupF32(&status, row, "EXT_CHISQ");
     1169        model->nDOF = psMetadataLookupF32(&status, row, "EXT_NDOF");
     1170        model->flags = psMetadataLookupS16(&status, row, "EXT_FLAGS");
     1171
     1172        // EXT_MODEL_TYPE gives the model chosen by psphot as the best.
     1173        // Putting this into the XFIT table makes 3 copies of it (one for each model)
     1174        // but since we have many fewer XFIT rows than psf rows that is cheaper than putting it
     1175        // in the psf table.
     1176        psS32 extModelType = psMetadataLookupS32(&status, row, "EXT_MODEL_TYPE");
     1177        if (status) {
     1178            // translate between the type value in xfit and values used by this program
     1179            extModelType = pmModelClassGetLocalType(extModelType);
     1180        } else {
     1181            // older cmfs don't have this column
     1182            extModelType = -1;
     1183        }
     1184
    10601185        psEllipseAxes axes;
    10611186        axes.major = psMetadataLookupF32(&status, row, "EXT_WIDTH_MAJ");
    10621187        axes.minor = psMetadataLookupF32(&status, row, "EXT_WIDTH_MIN");
    10631188        axes.theta = psMetadataLookupF32(&status, row, "EXT_THETA");
    1064         if (!pmPSF_AxesToModel(PAR, axes, modelType)) {
     1189        if (!pmPSF_AxesToModel(PAR, axes, model->class->useReff)) {
    10651190            // Do we need to fail here or can this happen?
    10661191            psError(PS_ERR_UNKNOWN, false, "Failed to convert psf axes to model");
     
    10721197        if (model->params->n > 7) {
    10731198            PAR[7] = psMetadataLookupF32(&status, row, "EXT_PAR_07");
    1074         }
    1075         // read the covariance matrix
    1076         int nparams = model->params->n;
    1077         psImage *covar = psImageAlloc(nparams, nparams, PS_TYPE_F32);
    1078         for (int y = 0; y < nparams; y++) {
    1079             for (int x = 0; x < nparams; x++) {
    1080                 char name[64];
    1081                 snprintf(name, 64, "EXT_COVAR_%02d_%02d", y, x);
    1082                 covar->data.F32[y][x] = psMetadataLookupF32(&status, row, name);
     1199            // XXX add an error:
     1200            // dPAR[7] = psMetadataLookupF32(&status, row, "EXT_PAR_07_");
     1201        }
     1202
     1203        // XXX : make this depend on what is in the cmf
     1204        if (0) {
     1205            // read the covariance matrix
     1206            int nparams = model->params->n;
     1207            psImage *covar = psImageAlloc(nparams, nparams, PS_TYPE_F32);
     1208            for (int y = 0; y < nparams; y++) {
     1209                for (int x = 0; x < nparams; x++) {
     1210                    char name[64];
     1211                    snprintf(name, 64, "EXT_COVAR_%02d_%02d", y, x);
     1212                    covar->data.F32[y][x] = psMetadataLookupF32(&status, row, name);
     1213                }
     1214            }
     1215            model->covar = covar;
     1216        }
     1217
     1218        if (modelType == extModelType) {
     1219            // The software that created this source picked this model as the best of the fits.
     1220            // Set the extModel to point to it.
     1221            // This is important for programs like psastro (skycal) so that its output cmfs
     1222            // will have valid EXT_MODEL_TYPE
     1223            psFree(source->modelEXT);
     1224            source->modelEXT = psMemIncrRefCounter(model);
     1225            source->type = PM_SOURCE_TYPE_EXTENDED;
     1226            if (0) {
     1227                // since FLAGS were read we don't need to do this
     1228                source->mode |= PM_SOURCE_MODE_EXTMODEL;
     1229                source->mode |= PM_SOURCE_MODE_NONLINEAR_FIT;
    10831230            }
    10841231        }
    1085         model->covar = covar;
    10861232
    10871233        psArrayAdd(source->modelFits, 1, model);
    10881234        psFree(model);
    1089 
    10901235        psFree(row);
    10911236    }
     
    11401285    psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES");
    11411286
     1287#ifdef SORT_EXTENSIONS_BY_FLUX
    11421288    // let's write these out in S/N order
    11431289    sources = psArraySort (sources, pmSourceSortByFlux);
     1290#endif
    11441291
    11451292    table = psArrayAllocEmpty (sources->n);
     
    12091356
    12101357        write_annuli:
    1211             psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX",       PS_DATA_VECTOR, "flux within annuli",       radFlux);
    1212             psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_ERR",   PS_DATA_VECTOR, "flux error in annuli",     radFluxErr);
    1213             psMetadataAdd (row, PS_LIST_TAIL, "APER_FLUX_STDEV", PS_DATA_VECTOR, "flux standard deviation",  radFluxStdev);
    1214             psMetadataAdd (row, PS_LIST_TAIL, "APER_FILL",       PS_DATA_VECTOR, "fill factor of annuli",    radFill);
     1358            psMetadataAddVector (row, PS_LIST_TAIL, "APER_FLUX",       PS_META_REPLACE, "flux within annuli",       radFlux);
     1359            psMetadataAddVector (row, PS_LIST_TAIL, "APER_FLUX_ERR",   PS_META_REPLACE, "flux error in annuli",     radFluxErr);
     1360            psMetadataAddVector (row, PS_LIST_TAIL, "APER_FLUX_STDEV", PS_META_REPLACE, "flux standard deviation",  radFluxStdev);
     1361            psMetadataAddVector (row, PS_LIST_TAIL, "APER_FILL",       PS_META_REPLACE, "fill factor of annuli",    radFill);
    12151362            psFree (radFlux);
    12161363            psFree (radFluxErr);
     
    12771424            return false;
    12781425        }
    1279         // Find the source with this sequence number.
    1280         // XXX: I am assuming that sources is sorted in order of seq.
    12811426        long seq = psMetadataLookupU32 (&status, row, "IPP_IDET");
    1282         long j = seq < sources->n ? seq : sources->n - 1;
    1283         pmSource *source = NULL;
    1284         for (; j >= 0; j--) {
    1285             source = sources->data[j];
    1286             if (source->seq == seq) {
    1287                 break;
    1288             }
    1289         }
     1427        long j = sourceIndex[seq];
     1428        psAssert(j >= 0 && j < sources->n, "invalid sourceIndex");
     1429        pmSource *source = sources->data[j];
    12901430        if (!source) {
    12911431            psError(PS_ERR_UNKNOWN, false, "Failed to find source for row %ld sequence number %ld\n", i, seq);
     
    13431483    return true;
    13441484}
     1485
     1486// XXX where should I record the number of columns??
     1487bool pmSourcesWrite_CMF_@CMFMODE@_XGAL (psFits *fits, pmReadout *readout, psArray *sources, char *extname, psMetadata *recipe)
     1488{
     1489    bool status = false;
     1490
     1491    // perform full non-linear fits / extended source analysis?
     1492    if (!psMetadataLookupBool (&status, recipe, "GALAXY_SHAPES")) {
     1493        psLogMsg ("psphot", PS_LOG_INFO, "galaxy shapes were not measured, skipping\n");
     1494        return true;
     1495    }
     1496
     1497    // create a header to hold the output data
     1498    psMetadata *outhead = psMetadataAlloc ();
     1499
     1500    // write the links to the image header
     1501    psMetadataAddStr (outhead, PS_LIST_TAIL, "EXTNAME", PS_META_REPLACE, "galaxy table extension", extname);
     1502
     1503    psF32 Q = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_Q");
     1504    psMetadataAddF32 (outhead, PS_LIST_TAIL, "GALAXY_SHAPES_Q", PS_META_REPLACE, "", Q);
     1505
     1506    psF32 NSigma = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_NSIGMA");
     1507    psMetadataAddF32 (outhead, PS_LIST_TAIL, "GALAXY_SHAPES_NSIGMA", PS_META_REPLACE, "", NSigma);
     1508
     1509    psF32 clampSN = psMetadataLookupF32(&status, recipe, "GALAXY_SHAPES_CLAMP_SN");
     1510    psMetadataAddF32 (outhead, PS_LIST_TAIL, "GALAXY_SHAPES_CLAMP_SN", PS_META_REPLACE, "", clampSN);
     1511
     1512    // They are probably already in this order but ...
     1513    sources = psArraySort (sources, pmSourceSortBySeq);
     1514
     1515    psArray *table = psArrayAllocEmpty (sources->n);
     1516
     1517    for (int i = 0; i < sources->n; i++) {
     1518
     1519        pmSource *thisSource = sources->data[i];
     1520
     1521        // this is the "real" version of this source
     1522        pmSource *source = thisSource->parent ? thisSource->parent : thisSource;
     1523
     1524        // if we did not fit the galaxy model, modelFits will be NULL
     1525        if (source->modelFits == NULL) continue;
     1526
     1527        // if we did not fit the galaxy model, galaxyFits will also be NULL
     1528        if (source->galaxyFits == NULL) continue;
     1529
     1530        for (int iModel = 0; iModel < source->modelFits->n; iModel++) {
     1531            pmModel *model = source->modelFits->data[iModel];
     1532            if (!model) continue;
     1533
     1534            pmSourceGalaxyFits *galaxyFits = NULL;
     1535            for (int iFit = 0; iFit < source->galaxyFits->n; iFit++) {
     1536                galaxyFits = source->galaxyFits->data[iFit];
     1537                if (model->type == galaxyFits->modelType) break;
     1538                galaxyFits = NULL;
     1539            }
     1540
     1541            if (!galaxyFits) continue;
     1542
     1543            // X,Y coordinates are stored with the model parameters
     1544            psF32 *PAR = model->params->data.F32;
     1545
     1546            psMetadata *row = psMetadataAlloc ();
     1547
     1548            // we write out the x,y positions so people can link to the psf either way (position or ID)
     1549            psMetadataAddU32 (row, PS_LIST_TAIL, "IPP_IDET",         0, "IPP detection identifier index", source->seq);
     1550            psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TYPE",       0, "model type",                     galaxyFits->modelType);
     1551            psMetadataAddF32 (row, PS_LIST_TAIL, "X_FIT",            0, "model x coordinate",             PAR[PM_PAR_XPOS]);
     1552            psMetadataAddF32 (row, PS_LIST_TAIL, "Y_FIT",            0, "model y coordinate",             PAR[PM_PAR_YPOS]);
     1553            psMetadataAddF32 (row, PS_LIST_TAIL, "NPIX",             0, "number of pixels for fits",      galaxyFits->nPix);
     1554            // psMetadataAddS32 (row, PS_LIST_TAIL, "REDUCED_TRIALS",   0, "source has reduced number of trials",      galaxyFits->reducedTrials);
     1555
     1556            psVector *Flux = galaxyFits->Flux;
     1557            psVector *dFlux = galaxyFits->dFlux;
     1558            psVector *chisq = galaxyFits->chisq;
     1559
     1560            psMetadataAddVector (row, PS_LIST_TAIL, "GAL_FLUX",     PS_META_REPLACE, "normalization for galaxy flux", Flux);
     1561            psMetadataAddVector (row, PS_LIST_TAIL, "GAL_FLUX_ERR", PS_META_REPLACE, "error on normalization", dFlux);
     1562            psMetadataAddVector (row, PS_LIST_TAIL, "GAL_CHISQ",    PS_META_REPLACE, "galaxy fit chisq", chisq);
     1563
     1564            psMetadataAddF32 (row, PS_LIST_TAIL, "FR_MAJOR_MIN",    0, "fractional major axis min",      galaxyFits->fRmajorMin);
     1565            psMetadataAddF32 (row, PS_LIST_TAIL, "FR_MAJOR_MAX",    0, "fractional major axis max",      galaxyFits->fRmajorMax);
     1566            psMetadataAddF32 (row, PS_LIST_TAIL, "FR_MAJOR_DEL",    0, "fractional major axis max",      galaxyFits->fRmajorDel);
     1567            psMetadataAddF32 (row, PS_LIST_TAIL, "FR_MINOR_MIN",    0, "fractional minor axis min",      galaxyFits->fRminorMin);
     1568            psMetadataAddF32 (row, PS_LIST_TAIL, "FR_MINOR_MAX",    0, "fractional minor axis max",      galaxyFits->fRminorMax);
     1569            psMetadataAddF32 (row, PS_LIST_TAIL, "FR_MINOR_DEL",    0, "fractional minor axis max",      galaxyFits->fRminorDel);
     1570
     1571            psArrayAdd (table, 100, row);
     1572            psFree (row);
     1573        }
     1574    }
     1575
     1576    if (table->n == 0) {
     1577        if (!psFitsWriteBlank (fits, outhead, extname)) {
     1578            psError(psErrorCodeLast(), false, "Unable to write empty sources file.");
     1579            psFree(outhead);
     1580            psFree(table);
     1581            return false;
     1582        }
     1583        psFree (outhead);
     1584        psFree (table);
     1585        return true;
     1586    }
     1587
     1588    psTrace ("pmFPAfile", 5, "writing galaxy data %s\n", extname);
     1589    if (!psFitsWriteTable (fits, outhead, table, extname)) {
     1590        psError(psErrorCodeLast(), false, "writing galaxy data %s\n", extname);
     1591        psFree (outhead);
     1592        psFree(table);
     1593        return false;
     1594    }
     1595    psFree (outhead);
     1596    psFree (table);
     1597    return true;
     1598}
     1599
     1600bool pmSourcesRead_CMF_@CMFMODE@_XGAL(psFits *fits, pmReadout *readout, psMetadata *hduHeader, psMetadata *tableHeader, psArray *sources, long *sourceIndex)
     1601{
     1602    PS_ASSERT_PTR_NON_NULL(fits, false);
     1603    PS_ASSERT_PTR_NON_NULL(sources, false);
     1604
     1605    bool status;
     1606    long numSources = psFitsTableSize(fits); // Number of sources in table
     1607    if (numSources == 0) {
     1608        psError(psErrorCodeLast(), false, "XGAL Table contains no entries\n");
     1609        return false;
     1610    }
     1611    if (!readout->analysis) {
     1612        readout->analysis = psMetadataAlloc();
     1613    }
     1614    psF32 Q = psMetadataLookupF32(&status, tableHeader, "GALAXY_SHAPES_Q");
     1615    // XXX: turn this into an assert once we're done
     1616    if (status) {
     1617        psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "GALAXY_SHAPES_Q", PS_META_REPLACE, "", Q);
     1618
     1619        psF32 NSigma = psMetadataLookupF32(&status, tableHeader, "GALAXY_SHAPES_NSIGMA");
     1620        psAssert(status, "missing GALAXY_SHAPES_NSIGMA");
     1621        psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "GALAXY_SHAPES_NSIGMA", PS_META_REPLACE, "", NSigma);
     1622
     1623        psF32 clampSN = psMetadataLookupF32(&status, tableHeader, "GALAXY_SHAPES_CLAMP_SN");
     1624        psAssert(status, "missing GALAXY_SHAPES_CLAMP_SN");
     1625        psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "GALAXY_SHAPES_CLAMP_SN", PS_META_REPLACE, "", clampSN);
     1626    }
     1627
     1628    for (long i = 0; i < numSources; i++) {
     1629        psMetadata *row = psFitsReadTableRow(fits, i); // Table row
     1630        if (!row) {
     1631            psError(psErrorCodeLast(), false, "Unable to read row %ld of sources", i);
     1632            psFree(row);
     1633            return false;
     1634        }
     1635        // Find the source with this sequence number.
     1636        // XXX: I am assuming that sources is sorted in order of seq
     1637        long seq = psMetadataLookupU32 (&status, row, "IPP_IDET");
     1638        long j = sourceIndex[seq];
     1639        psAssert(j >= 0 && j < sources->n, "invalid sourceIndex");
     1640
     1641        pmSource *source = sources->data[j];
     1642        if (!source) {
     1643            psError(PS_ERR_UNKNOWN, false, "Failed to find source for row %ld sequence number %ld\n", i, seq);
     1644            psFree(row);
     1645            return false;
     1646        }
     1647
     1648        int modelType = psMetadataLookupS32 (&status,    row, "MODEL_TYPE");
     1649        psVector *Flux  = psMetadataLookupVector(&status, row, "GAL_FLUX");
     1650        psVector *dFlux = psMetadataLookupVector(&status, row, "GAL_FLUX_ERR");
     1651        psVector *chisq = psMetadataLookupVector(&status, row, "GAL_CHISQ");
     1652
     1653        if (Flux && Flux->n > 0) {
     1654            if (!source->galaxyFits) {
     1655                source->galaxyFits = psArrayAllocEmpty(1);
     1656            }
     1657
     1658            pmSourceGalaxyFits *galaxyFits = pmSourceGalaxyFitsAlloc();
     1659
     1660            psArrayAdd(source->galaxyFits, 1, galaxyFits);
     1661
     1662            psFree(galaxyFits);
     1663            galaxyFits->modelType = modelType;
     1664            galaxyFits->nPix = psMetadataLookupF32(&status, row, "NPIX");
     1665
     1666            galaxyFits->fRmajorMin = psMetadataLookupF32(&status, row, "FR_MAJOR_MIN");
     1667            galaxyFits->fRmajorMax = psMetadataLookupF32(&status, row, "FR_MAJOR_MAX");
     1668            galaxyFits->fRmajorDel = psMetadataLookupF32(&status, row, "FR_MAJOR_DEL");
     1669            galaxyFits->fRminorMin = psMetadataLookupF32(&status, row, "FR_MINOR_MIN");
     1670            galaxyFits->fRminorMax = psMetadataLookupF32(&status, row, "FR_MINOR_MAX");
     1671            galaxyFits->fRminorDel = psMetadataLookupF32(&status, row, "FR_MINOR_DEL");
     1672
     1673            psFree(galaxyFits->Flux);
     1674            galaxyFits->Flux  = psMemIncrRefCounter(Flux);
     1675            psFree(galaxyFits->dFlux);
     1676            galaxyFits->dFlux = psMemIncrRefCounter(dFlux);
     1677            psFree(galaxyFits->chisq);
     1678            galaxyFits->chisq = psMemIncrRefCounter(chisq);
     1679        }
     1680
     1681        psFree(row);
     1682    }
     1683
     1684    return true;
     1685}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_CMP.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    135136        lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky);
    136137
    137         axes = pmPSF_ModelToAxes (PAR, model->type);
     138        axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    138139
    139140        float psfMagErr = isfinite(source->psfMagErr) ? source->psfMagErr : 999;
     
    292293                goto skip_source;
    293294
    294             pmPSF_AxesToModel (PAR, axes, modelType);
     295            pmPSF_AxesToModel (PAR, axes, source->modelPSF->class->useReff);
    295296
    296297            psArrayAdd (sources, 100, source);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_MatchedRefs.c

    r35560 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    9899
    99100                    // select the raw objects for this readout
    100                     psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS");
     101                    psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS.SUBSET");
    101102                    if (rawstars == NULL) continue;
    102103
    103104                    // select the raw objects for this readout
    104                     psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS");
     105                    psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS.SUBSET");
    105106                    if (refstars == NULL) continue;
    106107                    psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n);
    107 
    108 # if (0)
    109                     // XXX test
    110                     FILE *outfile = fopen ("refstars.dat", "w");
    111                     assert (outfile);
    112                     for (int nn = 0; nn < refstars->n; nn++) {
    113                         pmAstromObj *ref = refstars->data[nn];
    114                         fprintf (outfile, "%lf %lf\n", ref->sky->r*PS_DEG_RAD, ref->sky->d*PS_DEG_RAD);
    115                     }
    116                     fclose (outfile);
    117 # endif
    118108
    119109                    psArray *matches = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.MATCH");
     
    127117
    128118                        psMetadata *row = psMetadataAlloc ();
    129                         psMetadataAdd (row, PS_LIST_TAIL, "RA",       PS_DATA_F64, "right ascension (deg, J2000)", PM_DEG_RAD*ref->sky->r);
    130                         psMetadataAdd (row, PS_LIST_TAIL, "DEC",      PS_DATA_F64, "declination (deg, J2000)",     PM_DEG_RAD*ref->sky->d);
    131                         psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP",   PS_DATA_F32, "x coord on chip",              raw->chip->x);
    132                         psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP",   PS_DATA_F32, "y coord on chip",              raw->chip->y);
    133                         psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP_FIT",PS_DATA_F32, "x fitted coord on chip",      ref->chip->x);
    134                         psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP_FIT",PS_DATA_F32, "y fitted coord on chip",      ref->chip->y);
    135                         psMetadataAdd (row, PS_LIST_TAIL, "X_FPA",    PS_DATA_F32, "x coord on focal plane",       raw->FP->x);
    136                         psMetadataAdd (row, PS_LIST_TAIL, "Y_FPA",    PS_DATA_F32, "y coord on focal plane",       raw->FP->y);
    137                         psMetadataAdd (row, PS_LIST_TAIL, "MAG_INST", PS_DATA_F32, "instrumental magnitude",       raw->Mag);
    138                         psMetadataAdd (row, PS_LIST_TAIL, "MAG_REF",  PS_DATA_F32, "reference star magnitude",     ref->Mag);
    139                         psMetadataAdd (row, PS_LIST_TAIL, "COLOR_REF",PS_DATA_F32, "reference star color",         ref->Color);
    140                         psMetadataAdd (row, PS_LIST_TAIL, "CHIP_ID",  PS_DATA_STRING, "chip identifier",           chipName);
     119                        psMetadataAdd (row, PS_LIST_TAIL, "RA_REF",     PS_DATA_F64, "right ascension (deg, J2000)", PM_DEG_RAD*ref->sky->r);
     120                        psMetadataAdd (row, PS_LIST_TAIL, "DEC_REF",    PS_DATA_F64, "declination (deg, J2000)",     PM_DEG_RAD*ref->sky->d);
     121                        psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP_REF", PS_DATA_F32, "x fitted coord on chip",       ref->chip->x);
     122                        psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP_REF", PS_DATA_F32, "y fitted coord on chip",       ref->chip->y);
     123                        psMetadataAdd (row, PS_LIST_TAIL, "X_CHIP_RAW", PS_DATA_F32, "x coord on chip",              raw->chip->x);
     124                        psMetadataAdd (row, PS_LIST_TAIL, "Y_CHIP_RAW", PS_DATA_F32, "y coord on chip",              raw->chip->y);
     125                        psMetadataAdd (row, PS_LIST_TAIL, "X_FPA_RAW",  PS_DATA_F32, "x coord on focal plane",       raw->FP->x);
     126                        psMetadataAdd (row, PS_LIST_TAIL, "Y_FPA_RAW",  PS_DATA_F32, "y coord on focal plane",       raw->FP->y);
     127                        psMetadataAdd (row, PS_LIST_TAIL, "X_TPA_RAW",  PS_DATA_F32, "x coord on focal plane",       raw->TP->x);
     128                        psMetadataAdd (row, PS_LIST_TAIL, "Y_TPA_RAW",  PS_DATA_F32, "y coord on focal plane",       raw->TP->y);
     129                        psMetadataAdd (row, PS_LIST_TAIL, "MAG_INST",   PS_DATA_F32, "instrumental magnitude",       raw->Mag);
     130                        psMetadataAdd (row, PS_LIST_TAIL, "MAG_REF",    PS_DATA_F32, "reference star magnitude",     ref->Mag);
     131                        psMetadataAdd (row, PS_LIST_TAIL, "COLOR_REF",  PS_DATA_F32, "reference star color",         ref->Color);
     132                        psMetadataAdd (row, PS_LIST_TAIL, "CHIP_ID",    PS_DATA_STRING, "chip identifier",           chipName);
    141133                        // XXX need to add the reference color, but this needs getstar / dvo.photcodes for the reference to be refined.
    142134
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_OBJ.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    9293        }
    9394
    94         axes = pmPSF_ModelToAxes (PAR, model->type);
     95        axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    9596
    9697        psLineInit (line);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_PS1_CAL_0.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    114115            yErr = dPAR[PM_PAR_YPOS];
    115116            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
    116                 axes = pmPSF_ModelToAxes (PAR, model->type);
     117                axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    117118            } else {
    118119                axes.major = NAN;
     
    289290        dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN;
    290291
    291         pmPSF_AxesToModel (PAR, axes, modelType);
     292        pmPSF_AxesToModel (PAR, axes, model->class->useReff);
    292293
    293294        float peakMag     = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG");
     
    623624            yErr = dPAR[PM_PAR_YPOS];
    624625
    625             axes = pmPSF_ModelToAxes (PAR, model->type);
     626            axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    626627
    627628            // generate RA,DEC
     
    713714    return true;
    714715}
     716
     717bool pmSourcesWrite_PS1_CAL_0_XGAL (psFits *fits, pmReadout *readout, psArray *sources, char *extname, psMetadata *recipe)
     718{
     719    return true;
     720}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_PS1_DEV_0.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    9091            yErr = dPAR[PM_PAR_YPOS];
    9192
    92             axes = pmPSF_ModelToAxes (PAR, model->type);
     93            axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    9394        } else {
    9495            // XXX: This code seg faults if source->peak is NULL.
     
    215216        source->psfMagErr    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");
    216217
    217         pmPSF_AxesToModel (PAR, axes, modelType);
     218        pmPSF_AxesToModel (PAR, axes, model->class->useReff);
    218219
    219220        float peakMag = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG");
     
    255256    return true;
    256257}
     258
     259bool pmSourcesWrite_PS1_DEV_0_XGAL(psFits *fits, pmReadout *readout, psArray *sources, char *extname, psMetadata *recipe)
     260{
     261    return true;
     262}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_PS1_DEV_1.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    9697            yErr = dPAR[PM_PAR_YPOS];
    9798            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
    98                 axes = pmPSF_ModelToAxes (PAR, model->type);
     99                axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    99100            } else {
    100101                axes.major = NAN;
     
    258259        dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN;
    259260
    260         pmPSF_AxesToModel (PAR, axes, modelType);
     261        pmPSF_AxesToModel (PAR, axes, model->class->useReff);
    261262
    262263        float peakMag     = psMetadataLookupF32 (&status, row, "PEAK_FLUX_AS_MAG");
     
    523524            yErr = dPAR[PM_PAR_YPOS];
    524525
    525             axes = pmPSF_ModelToAxes (PAR, model->type);
     526            axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    526527
    527528            row = psMetadataAlloc ();
     
    595596    return true;
    596597}
     598
     599bool pmSourcesWrite_PS1_DEV_1_XGAL(psFits *fits, pmReadout *readout, psArray *sources, char *extname, psMetadata *recipe)
     600{
     601    return true;
     602}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_RAW.c

    r34403 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_SMPDATA.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    9293            lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky);
    9394
    94             axes = pmPSF_ModelToAxes (PAR, model->type);
     95            axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    9596
    9697        } else {
     
    189190        axes.theta       = psMetadataLookupF32 (&status, row, "THETA");
    190191
    191         pmPSF_AxesToModel (PAR, axes, modelType);
     192        pmPSF_AxesToModel (PAR, axes, model->class->useReff);
    192193
    193194        source->psfMag = psMetadataLookupF32 (&status, row, "MAG_RAW") - ZERO_POINT;
     
    225226    return true;
    226227}
     228
     229bool pmSourcesWrite_SMPDATA_XGAL(psFits *fits, pmReadout *readout, psArray *sources, char *extname, psMetadata *recipe)
     230{
     231    return true;
     232}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceIO_SX.c

    r35768 r37066  
    3737#include "pmMoments.h"
    3838#include "pmModelFuncs.h"
     39#include "pmModelClass.h"
    3940#include "pmModel.h"
    4041#include "pmModelUtils.h"
    41 #include "pmModelClass.h"
    4242#include "pmSourceMasks.h"
    4343#include "pmSourceExtendedPars.h"
    4444#include "pmSourceDiffStats.h"
    4545#include "pmSourceSatstar.h"
     46#include "pmSourceLensing.h"
    4647#include "pmSource.h"
    4748#include "pmSourceFitModel.h"
     
    8182        // pmSourceSextractType (source, &type, &flags);
    8283
    83         axes = pmPSF_ModelToAxes (PAR, model->type);
     84        axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    8485
    8586        psLineInit (line);
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceMasks.h

    r34403 r37066  
    5656    PM_SOURCE_MODE2_DIFF_SELF_MATCH       = 0x00000800, ///< positive detection match is probably this source
    5757    PM_SOURCE_MODE2_SATSTAR_PROFILE       = 0x00001000, ///< saturated source is modeled with a radial profile
     58
     59    PM_SOURCE_MODE2_ECONTOUR_FEW_PTS      = 0x00002000, ///< too few points to measure the elliptical contour
     60    PM_SOURCE_MODE2_RADBIN_NAN_CENTER     = 0x00004000, ///< radial bins failed with too many NaN center bin
     61    PM_SOURCE_MODE2_PETRO_NAN_CENTER      = 0x00008000, ///< petrosian radial bins failed with too many NaN center bin
     62    PM_SOURCE_MODE2_PETRO_NO_PROFILE      = 0x00010000, ///< petrosian not build because radial bins missing
     63
     64    PM_SOURCE_MODE2_PETRO_INSIG_RATIO     = 0x00020000, ///< insignificant measurement of petrosian ratio
     65    PM_SOURCE_MODE2_PETRO_RATIO_ZEROBIN   = 0x00040000, ///< petrosian ratio in the 0th bin (likely bad)
     66   
     67    PM_SOURCE_MODE2_EXT_FITS_RUN          = 0x00080000, ///< we attempted to run extended fits on this source
     68    PM_SOURCE_MODE2_EXT_FITS_FAIL         = 0x00100000, ///< at least one of the model fits failed
     69    PM_SOURCE_MODE2_EXT_FITS_RETRY        = 0x00200000, ///< one of the model fits was re-tried with new window
     70    PM_SOURCE_MODE2_EXT_FITS_NONE         = 0x00400000, ///< ALL of the model fits failed
     71   
     72   
    5873} pmSourceMode2;
    5974
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceMatch.c

    r35383 r37066  
    1818#include "pmMoments.h"
    1919#include "pmModelFuncs.h"
     20#include "pmModelClass.h"
    2021#include "pmModel.h"
    2122#include "pmModelUtils.h"
    22 #include "pmModelClass.h"
    2323#include "pmSourceMasks.h"
    2424#include "pmSourceExtendedPars.h"
    2525#include "pmSourceDiffStats.h"
    2626#include "pmSourceSatstar.h"
     27#include "pmSourceLensing.h"
    2728#include "pmSource.h"
    2829#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceMoments.c

    r35560 r37066  
    3535#include "pmMoments.h"
    3636#include "pmModelFuncs.h"
     37#include "pmModelClass.h"
    3738#include "pmModel.h"
    3839#include "pmModelUtils.h"
    39 #include "pmModelClass.h"
    4040#include "pmSourceMasks.h"
    4141#include "pmSourceExtendedPars.h"
    4242#include "pmSourceDiffStats.h"
    4343#include "pmSourceSatstar.h"
     44#include "pmSourceLensing.h"
    4445#include "pmSource.h"
    4546
     
    6566void pmSourceMomentsSetVerbose(bool state){ beVerbose = state; }
    6667
     68bool pmSourceMomentsHighOrder    (pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal);
     69bool pmSourceMomentsRadialMoment (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal);
     70bool pmSourceMomentsKronFluxes   (pmSource *source, float sigma,  float minSN, psImageMaskType maskVal);
     71
    6772// if mode & EXTERNAL or mode2 & MATCHED, do not re-calculate the centroid (use peak as centroid)
    68 
    6973bool pmSourceMoments(pmSource *source, float radius, float sigma, float minSN, float minKronRadius, psImageMaskType maskVal)
    7074{
     
    7478    PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false);
    7579
    76     // this function assumes the sky has been well-subtracted for the image
    77     float sky = 0.0;
    78 
    7980    if (source->moments == NULL) {
    8081      source->moments = pmMomentsAlloc();
    8182    }
    82 
    83     float Sum = 0.0;
    84     float Var = 0.0;
    85     float SumCore = 0.0;
    86     float VarCore = 0.0;
    87     float R2 = PS_SQR(radius);
    88     float minSN2 = PS_SQR(minSN);
    89     float rsigma2 = 0.5 / PS_SQR(sigma);
    9083
    9184    // a note about coordinates: coordinates of objects throughout psphot refer to the primary
     
    110103    // of any object drops pretty quickly outside 1-2 sigmas.  (The exception is bright
    111104    // saturated stars, for which we need to use a very large radius here)
     105    // NOTE: if (mode & EXTERNAL) or (mode2 & MATCHED), do not re-calculate the centroid (use peak as centroid)
     106    // (we still call this function because it sets moments->Sum,SN,Peak,nPixels
    112107    if (!pmSourceMomentsGetCentroid (source, 1.5*sigma, 0.0, minSN, maskVal, source->peak->xf, source->peak->yf)) {
    113108        return false;
    114109    }
    115110
     111    pmSourceMomentsHighOrder (source, radius, sigma, minSN, maskVal);
     112
     113    // now calculate the 1st radial moment (for kron flux) using symmetrical averaging
     114    pmSourceMomentsRadialMoment (source, radius, minKronRadius, maskVal);
     115
     116    // now calculate the kron flux values using the 1st radial moment
     117    pmSourceMomentsKronFluxes (source, sigma, minSN, maskVal);
     118
     119    psTrace ("psModules.objects", 4, "Mrf: %f  KronFlux: %f  Mxx: %f  Mxy: %f  Myy: %f  Mxxx: %f  Mxxy: %f  Mxyy: %f  Myyy: %f  Mxxxx: %f  Mxxxy: %f  Mxxyy: %f  Mxyyy: %f  Mxyyy: %f\n",
     120             source->moments->Mrf,   source->moments->KronFlux,
     121             source->moments->Mxx,   source->moments->Mxy,   source->moments->Myy,
     122             source->moments->Mxxx,  source->moments->Mxxy,  source->moments->Mxyy,  source->moments->Myyy,
     123             source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy);
     124
     125    psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f  My: %f  Sum: %f  Mxx: %f  Mxy: %f  Myy: %f  Npix: %d\n",
     126             source->peak->xf, source->peak->yf,
     127             source->peak->rawFlux, sqrt(source->peak->detValue),
     128             source->moments->Mx, source->moments->My,
     129             source->moments->Sum,
     130             source->moments->Mxx, source->moments->Mxy, source->moments->Myy,
     131             source->moments->nPixels);
     132
     133    return(true);
     134}
     135
     136bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) {
     137
     138    // First Pass: calculate the first moments (these are subtracted from the coordinates below)
     139    // Sum = SUM (z - sky)
     140    // X1  = SUM (x - xc)*(z - sky)
     141    // .. etc
     142
     143    float sky = 0.0;
     144
     145    float peakPixel = -PS_MAX_F32;
     146    psS32 numPixels = 0;
     147    float Sum = 0.0;
     148    float Var = 0.0;
     149    float X1 = 0.0;
     150    float Y1 = 0.0;
     151    float R2 = PS_SQR(radius);
     152    float minSN2 = PS_SQR(minSN);
     153    float rsigma2 = 0.5 / PS_SQR(sigma);
     154
     155    float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage
     156    float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage
     157
     158    // we are guaranteed to have a valid pixel and variance at this location (right? right?)
     159    // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);
     160    // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
     161    // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
     162    // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel");
     163
     164    // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should
     165    // not depend on the fractional pixel location of the source.  However, the aperture
     166    // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel
     167    // position of the expected centroid
     168
     169    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
     170
     171        float yDiff = row + 0.5 - yPeak;
     172        if (fabs(yDiff) > radius) continue;
     173
     174        float *vPix = source->pixels->data.F32[row];
     175        float *vWgt = source->variance ? source->variance->data.F32[row] : source->pixels->data.F32[row];
     176
     177        psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
     178        // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];
     179
     180        for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
     181            if (vMsk) {
     182                if (*vMsk & maskVal) {
     183                    vMsk++;
     184                    continue;
     185                }
     186                vMsk++;
     187            }
     188            if (isnan(*vPix)) continue;
     189
     190            float xDiff = col + 0.5 - xPeak;
     191            if (fabs(xDiff) > radius) continue;
     192
     193            // radius is just a function of (xDiff, yDiff)
     194            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     195            if (r2 > R2) continue;
     196
     197            float pDiff = *vPix - sky;
     198            float wDiff = *vWgt;
     199
     200            // skip pixels below specified significance level.  for a PSFs, this
     201            // over-weights the wings of bright stars compared to those of faint stars.
     202            // for the estimator used for extended source analysis (where the window
     203            // function is allowed to be arbitrarily large), we need to clip to avoid
     204            // negative second moments.
     205            if (PS_SQR(pDiff) < minSN2*wDiff) continue; //
     206            if ((minSN > 0.0) && (pDiff < 0)) continue; //
     207
     208            // Apply a Gaussian window function.  Be careful with the window function.  S/N
     209            // weighting over weights the sky for faint sources
     210            if (sigma > 0.0) {
     211                float z  = r2*rsigma2;
     212                assert (z >= 0.0);
     213                float weight  = exp(-z);
     214
     215                wDiff *= weight;
     216                pDiff *= weight;
     217            }
     218
     219            Var += wDiff;
     220            Sum += pDiff;
     221
     222            float xWght = xDiff * pDiff;
     223            float yWght = yDiff * pDiff;
     224
     225            X1  += xWght;
     226            Y1  += yWght;
     227
     228            peakPixel = PS_MAX (*vPix, peakPixel);
     229            numPixels++;
     230        }
     231    }
     232
     233    // if we have less than (1/4) of the possible pixels (in circle or box), force a retry
     234    int minPixels = PS_MIN(0.75*R2, source->pixels->numCols*source->pixels->numRows/4.0);
     235
     236    // XXX EAM - the limit is a bit arbitrary.  make it user defined?
     237    if ((numPixels < minPixels) || (Sum <= 0)) {
     238        psTrace ("psModules.objects", 3, "insufficient valid pixels (%d vs %d; %f) for source\n", numPixels, minPixels, Sum);
     239        return (false);
     240    }
     241
     242    // calculate the first moment.
     243    float Mx = X1/Sum;
     244    float My = Y1/Sum;
     245    if ((fabs(Mx) > radius) || (fabs(My) > radius)) {
     246        psTrace ("psModules.objects", 3, "extreme centroid swing; invalid peak %d, %d\n", source->peak->x, source->peak->y);
     247        return (false);
     248    }
     249    if ((fabs(Mx) > 2.0) || (fabs(My) > 2.0)) {
     250        psTrace ("psModules.objects", 3, " big centroid swing; ok peak? %d, %d\n", source->peak->x, source->peak->y);
     251    }
     252
     253    psTrace ("psModules.objects", 5, "id: %d, sky: %f  Mx: %f  My: %f  Sum: %f  X1: %f  Y1: %f  Npix: %d\n", source->id, sky, Mx, My, Sum, X1, Y1, numPixels);
     254
     255    // add back offset of peak in primary image
     256    // also offset from pixel index to pixel coordinate
     257    // (the calculation above uses pixel index instead of coordinate)
     258    // 0.5 PIX: moments are calculated using the pixel index and converted here to pixel coords
     259
     260    // we only update the centroid if the position is not supplied from elsewhere
     261    bool skipCentroid = false;
     262    skipCentroid |= (source->mode  & PM_SOURCE_MODE_EXTERNAL); // skip externally supplied positions
     263    skipCentroid |= (source->mode2 & PM_SOURCE_MODE2_MATCHED); // skip sources defined by other image positions
     264
     265    if (skipCentroid) {
     266        source->moments->Mx = source->peak->xf;
     267        source->moments->My = source->peak->yf;
     268    } else {
     269        source->moments->Mx = Mx + xGuess;
     270        source->moments->My = My + yGuess;
     271    }
     272
     273    source->moments->Sum = Sum;
     274    source->moments->SN  = Sum / sqrt(Var);
     275    source->moments->Peak = peakPixel;
     276    source->moments->nPixels = numPixels;
     277
     278    return true;
     279}
     280
     281float pmSourceMinKronRadius(psArray *sources, float PSF_SN_LIM) {
     282
     283    psVector *radii = psVectorAllocEmpty(100, PS_TYPE_F32);
     284
     285    for (int i = 0; i < sources->n; i++) {
     286        pmSource *src = sources->data[i]; // Source of interest
     287        if (!src || !src->moments) {
     288            continue;
     289        }
     290
     291        if (src->mode & PM_SOURCE_MODE_BLEND) {
     292            continue;
     293        }
     294
     295        if (!src->moments->nPixels) continue;
     296
     297        if (src->moments->SN < PSF_SN_LIM) continue;
     298
     299        // XXX put in Mxx,Myy cut based on clump location
     300
     301        psVectorAppend(radii, src->moments->Mrf);
     302    }
     303
     304    // find the peak in this image
     305    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     306
     307    if (!psVectorStats (stats, radii, NULL, NULL, 0)) {
     308        psError(PS_ERR_UNKNOWN, false, "Unable to get image statistics.\n");
     309        psFree(stats);
     310        return NAN;
     311    }
     312
     313    float minRadius = stats->sampleMedian;
     314
     315    psFree(radii);
     316    psFree(stats);
     317    return minRadius;
     318}
     319
     320bool pmSourceMomentsHighOrder (pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal) {
     321
     322    // this function assumes the sky has been well-subtracted for the image
     323    float Sum = 0.0;
     324    float R2 = PS_SQR(radius);
     325    float minSN2 = PS_SQR(minSN);
     326    float rsigma2 = 0.5 / PS_SQR(sigma);
     327
    116328    // Now calculate higher-order moments, using the above-calculated first moments to adjust coordinates
    117     // Xn  = SUM (x - xc)^n * (z - sky)
     329    // Xn  = SUM (x - xc)^n * (z - sky) -- note that sky is 0.0 by definition here
    118330    float XX = 0.0;
    119331    float XY = 0.0;
     
    129341    float YYYY = 0.0;
    130342
    131     Sum = 0.0;  // the second pass may include slightly different pixels, re-determine Sum
    132 
    133     // float dX = source->moments->Mx - source->peak->xf;
    134     // float dY = source->moments->My - source->peak->yf;
    135     // float dR = hypot(dX, dY);
    136     // float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf;
    137     // float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf;
    138343    float Xo = source->moments->Mx;
    139344    float Yo = source->moments->My;
     
    154359
    155360        psImageMaskType  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
    156         // psImageMaskType  *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];
    157361
    158362        for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
     
    173377            if (r2 > R2) continue;
    174378
    175             float fDiff = *vPix - sky;
     379            float fDiff = *vPix;
    176380            float pDiff = fDiff;
    177381            float wDiff = *vWgt;
     
    181385            // stars.
    182386            if (PS_SQR(pDiff) < minSN2*wDiff) continue;
    183             if ((minSN > 0.0) && (pDiff < 0)) continue; //
     387            if ((minSN > 0.0) && (pDiff < 0)) continue;
    184388
    185389            // Apply a Gaussian window function.  Be careful with the window function.  S/N
    186             // weighting over weights the sky for faint sources
     390            // weighting over-weights the sky for faint sources
    187391            if (sigma > 0.0) {
    188392                float z = r2 * rsigma2;
     
    230434            XYYY  += xyyy;
    231435            YYYY  += yyyy;
    232 
    233             // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?)
    234             // XXX float r = sqrt(r2);
    235             // XXX float rf = r * fDiff;
    236             // XXX float rh = sqrt(r) * fDiff;
    237             // XXX float rs = fDiff;
    238             // XXX
    239             // XXX float rfw = r * pDiff;
    240             // XXX float rhw = sqrt(r) * pDiff;
    241             // XXX
    242             // XXX RF  += rf;
    243             // XXX RH  += rh;
    244             // XXX RS  += rs;
    245             // XXX
    246             // XXX RFW  += rfw;
    247             // XXX RHW  += rhw;
    248436        }
    249437    }
     438    // NOT needed : source->moments->wSum = Sum;
     439
    250440    source->moments->Mxx = XX/Sum;
    251441    source->moments->Mxy = XY/Sum;
     
    263453    source->moments->Myyyy = YYYY/Sum;
    264454
    265     // *** now calculate the 1st radial moment (for kron flux) -- symmetrical averaging
     455    return true;
     456}
     457
     458bool pmSourceMomentsRadialMoment (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal) {
     459
    266460
    267461    float **vPix = source->pixels->data.F32;
    268     float **vWgt = source->variance ? source->variance->data.F32 : source->pixels->data.F32;
    269462    psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
    270463
     
    272465    float RH = 0.0;
    273466    float RS = 0.0;
     467
     468    // centroid around which to calculate the moments
     469    float Xo = source->moments->Mx;
     470    float Yo = source->moments->My;
     471
     472    // center of mass in subimage.  Note: the calculation below uses pixel index, so we correct
     473    // xCM, yCM from pixel coords to pixel index here.
     474    float xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage
     475    float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage
     476
     477    float R2 = PS_SQR(radius);
    274478
    275479    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
     
    304508            if (r2 > R2) continue;
    305509
    306             float fDiff1 = vPix[row][col] - sky;
    307             float fDiff2 = vPix[yFlip][xFlip] - sky;
     510            float fDiff1 = vPix[row][col];
     511            float fDiff2 = vPix[yFlip][xFlip];
    308512            float pDiff = (fDiff1 > 0.0) ? sqrt(fabs(fDiff1*fDiff2)) : -sqrt(fabs(fDiff1*fDiff2));
    309513
     
    329533        kronRefRadius = MIN(radius, kronRefRadius);
    330534    }
    331     source->moments->Mrf = kronRefRadius;
    332 
    333     // *** now calculate the kron flux values using the 1st radial moment
    334 
    335     float radKinner = 1.0*kronRefRadius;
    336     float radKron   = 2.5*kronRefRadius;
    337     float radKouter = 4.0*kronRefRadius;
     535
     536    // if source is externally supplied and it already has a finite Mrf do not change it
     537    if (! ((source->mode & PM_SOURCE_MODE_EXTERNAL) && isfinite(source->moments->Mrf))) {
     538        source->moments->Mrf = kronRefRadius;
     539    }
     540
     541    return true;
     542}
     543
     544bool pmSourceMomentsKronFluxes (pmSource *source, float sigma, float minSN, psImageMaskType maskVal) {
     545
     546    float **vPix = source->pixels->data.F32;
     547    float **vWgt = source->variance ? source->variance->data.F32 : source->pixels->data.F32;
     548    psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;
     549
     550    float radKinner = 1.0*source->moments->Mrf;
     551    float radKron   = 2.5*source->moments->Mrf;
     552    float radKouter = 4.0*source->moments->Mrf;
    338553
    339554    int nKronPix = 0;
     
    341556    int nInner = 0;
    342557    int nOuter = 0;
    343     Sum = Var = 0.0;
     558   
     559    float Sum = 0.0;
     560    float Var = 0.0;
     561    float SumCore = 0.0;
     562    float VarCore = 0.0;
    344563    float SumInner = 0.0;
    345564    float SumOuter = 0.0;
     565
     566    // centroid around which to calculate the moments
     567    float Xo = source->moments->Mx;
     568    float Yo = source->moments->My;
     569
     570    // center of mass in subimage.  Note: the calculation below uses pixel index, so we correct
     571    // xCM, yCM from pixel coords to pixel index here.
     572    float xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage
     573    float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage
     574
     575    float minSN2 = PS_SQR(minSN);
    346576
    347577    // calculate the Kron flux, and related fluxes (NO symmetrical averaging)
     
    362592            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    363593
    364             float fDiff1 = vPix[row][col] - sky;
     594            float fDiff1 = vPix[row][col];
    365595            float pDiff = fDiff1;
    366596            float wDiff = vWgt[row][col];
     
    376606                Var += wDiff;
    377607                nKronPix ++;
    378                 // if (beVerbose) fprintf (stderr, "mome: %d %d  %f  %f  %f\n", col, row, sky, *vPix, Sum);
    379608            }
    380609
     
    397626    }
    398627    // *** should I rescale these fluxes by pi R^2 / nNpix?
    399     // XXX source->moments->KronCore    = SumCore       * M_PI * PS_SQR(sigma) / nCorePix;
    400     // XXX source->moments->KronCoreErr = sqrt(VarCore) * M_PI * PS_SQR(sigma) / nCorePix;
    401     // XXX source->moments->KronFlux    = Sum       * M_PI * PS_SQR(radKron) / nKronPix;
    402     // XXX source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix;
    403     // XXX source->moments->KronFinner = SumInner * M_PI * (PS_SQR(radKron)   - PS_SQR(radKinner)) / nInner;
    404     // XXX source->moments->KronFouter = SumOuter * M_PI * (PS_SQR(radKouter) -   PS_SQR(radKron)) / nOuter;
     628    // XXX source->moments->KronCore    = SumCore       * M_PI *  PS_SQR(sigma) / nCorePix;
     629    // XXX source->moments->KronCoreErr = sqrt(VarCore) * M_PI *  PS_SQR(sigma) / nCorePix;
     630    // XXX source->moments->KronFlux    = Sum           * M_PI * PS_SQR(radKron) / nKronPix;
     631    // XXX source->moments->KronFluxErr = sqrt(Var)     * M_PI * PS_SQR(radKron) / nKronPix;
     632    // XXX source->moments->KronFinner  = SumInner      * M_PI * (PS_SQR(radKron)   - PS_SQR(radKinner)) / nInner;
     633    // XXX source->moments->KronFouter  = SumOuter      * M_PI * (PS_SQR(radKouter) -   PS_SQR(radKron)) / nOuter;
    405634
    406635    source->moments->KronCore    = SumCore;
     
    408637    source->moments->KronFlux    = Sum;
    409638    source->moments->KronFluxErr = sqrt(Var);
    410     source->moments->KronFinner = SumInner;
    411     source->moments->KronFouter = SumOuter;
     639    source->moments->KronFinner  = SumInner;
     640    source->moments->KronFouter  = SumOuter;
    412641
    413642    // XXX not sure I should save this here...
     
    416645    source->moments->KronRadiusPSF  = source->moments->Mrf;
    417646
    418     psTrace ("psModules.objects", 4, "Mrf: %f  KronFlux: %f  Mxx: %f  Mxy: %f  Myy: %f  Mxxx: %f  Mxxy: %f  Mxyy: %f  Myyy: %f  Mxxxx: %f  Mxxxy: %f  Mxxyy: %f  Mxyyy: %f  Mxyyy: %f\n",
    419              source->moments->Mrf,   source->moments->KronFlux,
    420              source->moments->Mxx,   source->moments->Mxy,   source->moments->Myy,
    421              source->moments->Mxxx,  source->moments->Mxxy,  source->moments->Mxyy,  source->moments->Myyy,
    422              source->moments->Mxxxx, source->moments->Mxxxy, source->moments->Mxxyy, source->moments->Mxyyy, source->moments->Myyyy);
    423 
    424     psTrace ("psModules.objects", 3, "peak %f %f (%f = %f) Mx: %f  My: %f  Sum: %f  Mxx: %f  Mxy: %f  Myy: %f  sky: %f  Npix: %d\n",
    425              source->peak->xf, source->peak->yf, source->peak->rawFlux, sqrt(source->peak->detValue), source->moments->Mx,   source->moments->My, Sum, source->moments->Mxx,   source->moments->Mxy,   source->moments->Myy, sky, source->moments->nPixels);
    426 
    427     return(true);
    428 }
    429 
    430 bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) {
    431 
    432     // First Pass: calculate the first moments (these are subtracted from the coordinates below)
    433     // Sum = SUM (z - sky)
    434     // X1  = SUM (x - xc)*(z - sky)
    435     // .. etc
    436 
    437     float sky = 0.0;
    438 
    439     float peakPixel = -PS_MAX_F32;
    440     psS32 numPixels = 0;
    441     float Sum = 0.0;
    442     float Var = 0.0;
    443     float X1 = 0.0;
    444     float Y1 = 0.0;
    445     float R2 = PS_SQR(radius);
    446     float minSN2 = PS_SQR(minSN);
    447     float rsigma2 = 0.5 / PS_SQR(sigma);
    448 
    449     float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage
    450     float yPeak = yGuess - source->pixels->row0; // coord of peak in subimage
    451 
    452     // we are guaranteed to have a valid pixel and variance at this location (right? right?)
    453     // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);
    454     // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
    455     // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
    456     // psAssert (source->variance->data.F32[yPeak][xPeak] > 0, "peak must be on valid pixel");
    457 
    458     // the moments [Sum(x*f) / Sum(f)] are calculated in pixel index values, and should
    459     // not depend on the fractional pixel location of the source.  However, the aperture
    460     // (radius) and the Gaussian window (sigma) depend subtly on the fractional pixel
    461     // position of the expected centroid
    462 
    463     for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    464 
    465         float yDiff = row + 0.5 - yPeak;
    466         if (fabs(yDiff) > radius) continue;
    467 
    468         float *vPix = source->pixels->data.F32[row];
    469         float *vWgt = source->variance ? source->variance->data.F32[row] : source->pixels->data.F32[row];
    470 
    471         psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
    472         // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];
    473 
    474         for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
    475             if (vMsk) {
    476                 if (*vMsk & maskVal) {
    477                     vMsk++;
    478                     continue;
    479                 }
    480                 vMsk++;
    481             }
    482             if (isnan(*vPix)) continue;
    483 
    484             float xDiff = col + 0.5 - xPeak;
    485             if (fabs(xDiff) > radius) continue;
    486 
    487             // radius is just a function of (xDiff, yDiff)
    488             float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    489             if (r2 > R2) continue;
    490 
    491             float pDiff = *vPix - sky;
    492             float wDiff = *vWgt;
    493 
    494             // skip pixels below specified significance level.  for a PSFs, this
    495             // over-weights the wings of bright stars compared to those of faint stars.
    496             // for the estimator used for extended source analysis (where the window
    497             // function is allowed to be arbitrarily large), we need to clip to avoid
    498             // negative second moments.
    499             if (PS_SQR(pDiff) < minSN2*wDiff) continue; //
    500             if ((minSN > 0.0) && (pDiff < 0)) continue; //
    501 
    502             // Apply a Gaussian window function.  Be careful with the window function.  S/N
    503             // weighting over weights the sky for faint sources
    504             if (sigma > 0.0) {
    505                 float z  = r2*rsigma2;
    506                 assert (z >= 0.0);
    507                 float weight  = exp(-z);
    508 
    509                 wDiff *= weight;
    510                 pDiff *= weight;
    511             }
    512 
    513             Var += wDiff;
    514             Sum += pDiff;
    515 
    516             float xWght = xDiff * pDiff;
    517             float yWght = yDiff * pDiff;
    518 
    519             X1  += xWght;
    520             Y1  += yWght;
    521 
    522             peakPixel = PS_MAX (*vPix, peakPixel);
    523             numPixels++;
    524         }
    525     }
    526 
    527     // if we have less than (1/4) of the possible pixels (in circle or box), force a retry
    528     int minPixels = PS_MIN(0.75*R2, source->pixels->numCols*source->pixels->numRows/4.0);
    529 
    530     // XXX EAM - the limit is a bit arbitrary.  make it user defined?
    531     if ((numPixels < minPixels) || (Sum <= 0)) {
    532         psTrace ("psModules.objects", 3, "insufficient valid pixels (%d vs %d; %f) for source\n", numPixels, minPixels, Sum);
    533         return (false);
    534     }
    535 
    536     // calculate the first moment.
    537     float Mx = X1/Sum;
    538     float My = Y1/Sum;
    539     if ((fabs(Mx) > radius) || (fabs(My) > radius)) {
    540         psTrace ("psModules.objects", 3, "extreme centroid swing; invalid peak %d, %d\n", source->peak->x, source->peak->y);
    541         return (false);
    542     }
    543     if ((fabs(Mx) > 2.0) || (fabs(My) > 2.0)) {
    544         psTrace ("psModules.objects", 3, " big centroid swing; ok peak? %d, %d\n", source->peak->x, source->peak->y);
    545     }
    546 
    547     psTrace ("psModules.objects", 5, "id: %d, sky: %f  Mx: %f  My: %f  Sum: %f  X1: %f  Y1: %f  Npix: %d\n", source->id, sky, Mx, My, Sum, X1, Y1, numPixels);
    548 
    549     // add back offset of peak in primary image
    550     // also offset from pixel index to pixel coordinate
    551     // (the calculation above uses pixel index instead of coordinate)
    552     // 0.5 PIX: moments are calculated using the pixel index and converted here to pixel coords
    553 
    554     // we only update the centroid if the position is not supplied from elsewhere
    555     bool skipCentroid = false;
    556     skipCentroid |= (source->mode  & PM_SOURCE_MODE_EXTERNAL); // skip externally supplied positions
    557     skipCentroid |= (source->mode2 & PM_SOURCE_MODE2_MATCHED); // skip sources defined by other image positions
    558 
    559     if (skipCentroid) {
    560         source->moments->Mx = source->peak->xf;
    561         source->moments->My = source->peak->yf;
    562     } else {
    563         source->moments->Mx = Mx + xGuess;
    564         source->moments->My = My + yGuess;
    565     }
    566 
    567     source->moments->Sum = Sum;
    568     source->moments->SN  = Sum / sqrt(Var);
    569     source->moments->Peak = peakPixel;
    570     source->moments->nPixels = numPixels;
    571 
    572647    return true;
    573648}
    574 
    575 float pmSourceMinKronRadius(psArray *sources, float PSF_SN_LIM) {
    576 
    577     psVector *radii = psVectorAllocEmpty(100, PS_TYPE_F32);
    578 
    579     for (int i = 0; i < sources->n; i++) {
    580         pmSource *src = sources->data[i]; // Source of interest
    581         if (!src || !src->moments) {
    582             continue;
    583         }
    584 
    585         if (src->mode & PM_SOURCE_MODE_BLEND) {
    586             continue;
    587         }
    588 
    589         if (!src->moments->nPixels) continue;
    590 
    591         if (src->moments->SN < PSF_SN_LIM) continue;
    592 
    593         // XXX put in Mxx,Myy cut based on clump location
    594 
    595         psVectorAppend(radii, src->moments->Mrf);
    596     }
    597 
    598     // find the peak in this image
    599     psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
    600 
    601     if (!psVectorStats (stats, radii, NULL, NULL, 0)) {
    602         psError(PS_ERR_UNKNOWN, false, "Unable to get image statistics.\n");
    603         psFree(stats);
    604         return NAN;
    605     }
    606 
    607     float minRadius = stats->sampleMedian;
    608 
    609     psFree(radii);
    610     psFree(stats);
    611     return minRadius;
    612 }
    613 
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceOutputs.c

    r35768 r37066  
    2626#include "pmMoments.h"
    2727#include "pmModelFuncs.h"
     28#include "pmModelClass.h"
    2829#include "pmModel.h"
    2930#include "pmModelUtils.h"
    30 #include "pmModelClass.h"
    3131#include "pmSourceMasks.h"
    3232#include "pmSourceExtendedPars.h"
    3333#include "pmSourceDiffStats.h"
    3434#include "pmSourceSatstar.h"
     35#include "pmSourceLensing.h"
    3536#include "pmSource.h"
    3637#include "pmSourceFitModel.h"
     
    107108        }
    108109        if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXY]) && isfinite(PAR[PM_PAR_SYY])) {
    109             axes = pmPSF_ModelToAxes (PAR, model->type);
     110            axes = pmPSF_ModelToAxes (PAR, model->class->useReff);
    110111            outputs->psfMajor = axes.major;
    111112            outputs->psfMinor = axes.minor;
    112113            outputs->psfTheta = axes.theta*PS_DEG_RAD;
     114
     115            // some models (PS1_V1, QGAUSS) have an extra 'core' parameter
     116            outputs->psfCore = NAN;
     117            if (model->type == pmModelClassGetType ("PS_MODEL_PS1_V1")) {
     118                outputs->psfCore = PAR[PM_PAR_7];
     119            }
     120            if (model->type == pmModelClassGetType ("PS_MODEL_QGAUSS")) {
     121                outputs->psfCore = PAR[PM_PAR_7];
     122            }
     123
     124            outputs->psfMajorFWHM = model->class->modelSetFWHM(model->params, axes.major);
     125            outputs->psfMinorFWHM = model->class->modelSetFWHM(model->params, axes.minor);
    113126        } else {
    114127            outputs->psfMajor = NAN;
    115128            outputs->psfMinor = NAN;
    116129            outputs->psfTheta = NAN;
     130            outputs->psfCore = NAN;
    117131        }
    118132        outputs->chisq = model->chisq;
    119133        outputs->nDOF = model->nDOF;
    120134        outputs->nPix = model->nPix;
    121         outputs->apRadius = source->apRadius;
    122135    } else {
    123136        bool useMoments = pmSourcePositionUseMoments(source);
     
    137150        outputs->psfMinor = NAN;
    138151        outputs->psfTheta = NAN;
     152        outputs->psfCore = NAN;
    139153        outputs->chisq = NAN;
    140154        outputs->nDOF = 0;
    141155        outputs->nPix = 0;
    142         outputs->apRadius = NAN;
    143156    }
    144157
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceOutputs.h

    r33690 r37066  
    2626    float psfMinor;
    2727    float psfTheta;
     28    float psfCore;
     29    float psfMajorFWHM;
     30    float psfMinorFWHM;
    2831    float chisq;
    29     float apRadius;
    3032    int nPix;
    3133    int nDOF;
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourcePhotometry.c

    r34498 r37066  
    3333#include "pmMoments.h"
    3434#include "pmModelFuncs.h"
     35#include "pmModelClass.h"
    3536#include "pmModel.h"
    3637#include "pmModelUtils.h"
    37 #include "pmModelClass.h"
    3838#include "pmSourceMasks.h"
    3939#include "pmSourceExtendedPars.h"
    4040#include "pmSourceDiffStats.h"
    4141#include "pmSourceSatstar.h"
     42#include "pmSourceLensing.h"
    4243#include "pmSource.h"
    4344#include "pmSourceFitModel.h"
     
    113114    source->apFluxErr = NAN;
    114115
     116    pmModelStatus badModel = PM_MODEL_STATUS_NONE;
     117    badModel |= PM_MODEL_STATUS_BADARGS;
     118    badModel |= PM_MODEL_STATUS_OFFIMAGE;
     119    badModel |= PM_MODEL_STATUS_NAN_CHISQ;
     120    badModel |= PM_MODEL_SERSIC_PCM_FAIL_GUESS;
     121    badModel |= PM_MODEL_SERSIC_PCM_FAIL_GRID;
     122    badModel |= PM_MODEL_PCM_FAIL_GUESS;
     123
    115124    // XXXXXX review:
    116125    // Select the 'best' model -- this is used for PSF_QF,_PERFECT & ???. isPSF is true if this
     
    162171        for (int i = 0; i < source->modelFits->n; i++) {
    163172            pmModel *model = source->modelFits->data[i];
    164             if (model->flags & PM_MODEL_STATUS_BADARGS) continue;
     173            if (model->flags & badModel) continue;
    165174            status = pmSourcePhotometryModel (&model->mag, NULL, model);
    166175            if (model == source->modelEXT) foundEXT = true;
     
    321330
    322331    // measure fitMag
    323     flux = model->modelFlux (model->params);
     332    flux = model->class->modelFlux (model->params);
    324333    if (flux > 0) {
    325334        mag = -2.5*log10(flux);
     
    350359
    351360    bool status;
    352     int nPix = 0;
    353     status = pmSourcePhotometryAper(&nPix, &source->apMagRaw, &source->apFlux, &source->apFluxErr, model, image, variance, mask, maskVal);
     361    status = pmSourcePhotometryAper(&source->apNpixels, &source->apMagRaw, &source->apFlux, &source->apFluxErr, model, image, variance, mask, maskVal);
    354362    if (status) {
    355363        source->mode |= PM_SOURCE_MODE_AP_MAGS;
     
    481489
    482490            // for the full model, add all points
    483             value = fabs(model->modelFunc (NULL, params, coord) - sky);
     491            value = fabs(model->class->modelFunc (NULL, params, coord) - sky);
    484492            modelSum += value;
    485493
     
    884892
    885893            // for the full model, add all points
    886             float value = model->modelFunc (NULL, params, coord);
     894            float value = model->class->modelFunc (NULL, params, coord);
    887895
    888896            // fprintf (stderr, "%d, %d : %f, %f : %f - %f : %f\n",
     
    899907
    900908    psFree (coord);
     909    return (true);
     910}
     911
     912bool pmSourceChisqModelFlux (pmSource *source, pmModel *model, psImageMaskType maskVal)
     913{
     914    PS_ASSERT_PTR_NON_NULL(source, false);
     915    PS_ASSERT_PTR_NON_NULL(model, false);
     916
     917    float dC = 0.0;
     918    int Npix = 0;
     919
     920    psVector *params = model->params;
     921    psImage  *image = source->pixels;
     922    psImage  *modelFlux = source->modelFlux;
     923    psImage  *mask = source->maskObj;
     924    psImage  *variance = source->variance;
     925
     926    float Io = params->data.F32[PM_PAR_I0];
     927
     928    for (int iy = 0; iy < image->numRows; iy++) {
     929        for (int ix = 0; ix < image->numCols; ix++) {
     930
     931            // skip pixels which are masked
     932            if (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & maskVal) continue;
     933
     934            if (variance->data.F32[iy][ix] <= 0) continue;
     935
     936            dC += PS_SQR (image->data.F32[iy][ix] - Io*modelFlux->data.F32[iy][ix]) / variance->data.F32[iy][ix];
     937            Npix ++;
     938        }
     939    }
     940    model->nPix = Npix;
     941    model->nDOF = Npix - model->nPar;
     942    model->chisq = dC;
     943    model->chisqNorm = dC / model->nDOF;
     944
    901945    return (true);
    902946}
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourcePlotApResid.c

    r34403 r37066  
    3535#include "pmMoments.h"
    3636#include "pmModelFuncs.h"
     37#include "pmModelClass.h"
    3738#include "pmModel.h"
    3839#include "pmModelUtils.h"
    39 #include "pmModelClass.h"
    4040#include "pmSourceMasks.h"
    4141#include "pmSourceExtendedPars.h"
    4242#include "pmSourceDiffStats.h"
    4343#include "pmSourceSatstar.h"
     44#include "pmSourceLensing.h"
    4445#include "pmSource.h"
    4546#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourcePlotMoments.c

    r34403 r37066  
    3838#include "pmMoments.h"
    3939#include "pmModelFuncs.h"
     40#include "pmModelClass.h"
    4041#include "pmModel.h"
    4142#include "pmModelUtils.h"
    42 #include "pmModelClass.h"
    4343#include "pmSourceMasks.h"
    4444#include "pmSourceExtendedPars.h"
    4545#include "pmSourceDiffStats.h"
    4646#include "pmSourceSatstar.h"
     47#include "pmSourceLensing.h"
    4748#include "pmSource.h"
    4849#include "pmSourceFitModel.h"
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourcePlotPSFModel.c

    r35768 r37066  
    3939#include "pmMoments.h"
    4040#include "pmModelFuncs.h"
     41#include "pmModelClass.h"
    4142#include "pmModel.h"
    4243#include "pmModelUtils.h"
    43 #include "pmModelClass.h"
    4444#include "pmSourceMasks.h"
    4545#include "pmSourceExtendedPars.h"
    4646#include "pmSourceDiffStats.h"
    4747#include "pmSourceSatstar.h"
     48#include "pmSourceLensing.h"
    4849#include "pmSource.h"
    4950#include "pmSourceFitModel.h"
     
    146147        // force the axis ratio to be < 20.0
    147148        psEllipseAxes axes_mnt = psEllipseMomentsToAxes (moments, 20.0);
    148         psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, model->type);
     149        psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, model->class->useReff);
    149150
    150151        // moments major axis
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceSky.c

    r35560 r37066  
    3434#include "pmMoments.h"
    3535#include "pmModelFuncs.h"
     36#include "pmModelClass.h"
    3637#include "pmModel.h"
    3738#include "pmModelUtils.h"
    38 #include "pmModelClass.h"
    3939#include "pmSourceMasks.h"
    4040#include "pmSourceExtendedPars.h"
    4141#include "pmSourceDiffStats.h"
    4242#include "pmSourceSatstar.h"
     43#include "pmSourceLensing.h"
    4344#include "pmSource.h"
    4445
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceUtils.c

    r35560 r37066  
    3434#include "pmMoments.h"
    3535#include "pmModelFuncs.h"
     36#include "pmModelClass.h"
    3637#include "pmModel.h"
    3738#include "pmModelUtils.h"
    38 #include "pmModelClass.h"
    3939#include "pmSourceMasks.h"
    4040#include "pmSourceExtendedPars.h"
    4141#include "pmSourceDiffStats.h"
    4242#include "pmSourceSatstar.h"
     43#include "pmSourceLensing.h"
    4344#include "pmSource.h"
    4445
     
    6465    pmModel *model = pmModelAlloc(modelType);
    6566
    66     if (!model->modelGuess(model, source, maskVal, markVal)) {
     67    if (!model->class->modelGuess(model, source, maskVal, markVal)) {
    6768        psFree (model);
    6869        return NULL;
  • branches/eam_branches/ipp-ops-20130712/psModules/src/objects/pmSourceVisual.c

    r35768 r37066  
    1616#include "pmMoments.h"
    1717#include "pmModelFuncs.h"
     18#include "pmModelClass.h"
    1819#include "pmModel.h"
    1920#include "pmModelUtils.h"
    20 #include "pmModelClass.h"
    2121#include "pmSourceMasks.h"
    2222#include "pmSourceExtendedPars.h"
    2323#include "pmSourceDiffStats.h"
    2424#include "pmSourceSatstar.h"
     25#include "pmSourceLensing.h"
    2526#include "pmSource.h"
    2627#include "pmSourceFitModel.h"
     
    544545    psFree (model);
    545546
     547    bool dumpData = false;
     548
    546549    // pause and wait for user input:
    547550    // continue, save (provide name), ??
    548     pmVisualAskUser(&plotPSF);
     551retry:
     552    pmVisualAskUserOrDump(&plotPSF, &dumpData);
     553    if (dumpData) {
     554      char name[128];
     555      fprintf (stderr, "filename: ");
     556      int status = fscanf (stdin, "%127s", name);
     557      if (status != 1) {
     558        fprintf (stderr, "odd response\n");
     559        goto retry;
     560      }
     561
     562      FILE *f = fopen (name, "w");
     563      if (!f) {
     564        fprintf (stderr, "cannot open %s for output\n", name);
     565        goto retry;
     566      }
     567      for (int i = 0; i < x->n; i++) {
     568        float vModel = pmTrend2DEval (trend, x->data.F32[i], y->data.F32[i]);
     569        fprintf (f, "%f %f %f %f %d\n", x->data.F32[i], y->data.F32[i], param->data.F32[i], vModel, mask->data.PS_TYPE_VECTOR_MASK_DATA[i]);
     570      }
     571      fclose (f);
     572      goto retry;
     573    }
    549574
    550575    return true;
  • branches/eam_branches/ipp-ops-20130712/psModules/src/psmodules.h

    r35768 r37066  
    9595#include <pmAstrometryDistortion.h>
    9696#include <pmAstrometryVisual.h>
     97#include <pmKHcorrect.h>
    9798
    9899// the following headers are from psModule:imcombine
     
    128129
    129130#include <pmModelFuncs.h>
     131#include <pmModelClass.h>
    130132#include <pmModel.h>
     133#include <pmModel_CentralPixel.h>
    131134
    132135#include <pmSourceMasks.h>
     
    134137#include <pmSourceSatstar.h>
    135138#include <pmSourceDiffStats.h>
     139#include <pmSourceLensing.h>
    136140#include <pmSource.h>
    137141#include <pmSourceFitModel.h>
     
    146150#include <pmSourcePlots.h>
    147151#include <pmPSF_IO.h>
    148 #include <pmModelClass.h>
    149152#include <pmModelUtils.h>
    150153#include <pmSourcePhotometry.h>
  • branches/eam_branches/ipp-ops-20130712/psModules/test/objects

    • Property svn:ignore
      •  

        old new  
        88tap_pmSourceFitModel_Delta
        99tap_pmSourcePhotometry
         10tap_pmModel_CentralPixel
         11tap_pmModel_CentralPixel_v2
  • branches/eam_branches/ipp-ops-20130712/psModules/test/objects/Makefile.am

    r29547 r37066  
    1919        tap_pmModelUtils \
    2020        tap_pmModelClass \
     21        tap_pmModel_CentralPixel \
     22        tap_pmModel_CentralPixel_v2 \
    2123        tap_pmPSF \
    2224        tap_pmTrend2D \
Note: See TracChangeset for help on using the changeset viewer.