Changeset 36086 for trunk/psphot/src/psphotSourceFits.c
- Timestamp:
- Aug 31, 2013, 6:02:26 AM (13 years ago)
- Location:
- trunk/psphot
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20130711/psphot (added) merged: 35844,35972-35973,36025,36028-36029,36031-36033,36053-36054,36062-36064,36074
- Property svn:mergeinfo changed
-
trunk/psphot/src
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20130711/psphot/src (added) merged: 35844,35972,36025,36028,36031-36033,36062-36064,36074
- Property svn:mergeinfo changed
-
trunk/psphot/src/psphotSourceFits.c
r35769 r36086 559 559 560 560 # define TIMING 0 561 # define EXTRA_VERBOSE 0 562 563 bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize); 564 bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 565 bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 566 bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 561 567 562 568 pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { … … 580 586 581 587 float t1, t2, t4, t5; 588 t1 = t2 = t4 = t5 = 0.0; 582 589 if (TIMING) { psTimerStart ("psphotFitPCM"); } 590 591 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 592 options.mode = PM_SOURCE_FIT_NO_INDEX; // XXX note that there may be a conflict with psphotExtendedSourceFits.c:133 593 options.mode = PM_SOURCE_FIT_EXT_AND_SKY; 594 // if we are ever (in a given psphot implementation) going to fit a parameter, we must set the options here to include 595 // that parameter (otherwise pmPCMupdate will fail to allocate the dmodelFlux image) 596 // thus, if the sersic analysis below uses an index fit, need to use this EXT_AND_SKY mode for init 597 } else { 598 options.mode = PM_SOURCE_FIT_EXT_AND_SKY; 599 } 583 600 584 601 pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize); … … 594 611 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 595 612 // use the source moments, etc to guess basic model parameters 596 if (!psphotSersicModel ClassGuessPCM (pcm, source)) {613 if (!psphotSersicModelGuessPCM (pcm, source, maskVal, psfSize)) { 597 614 psFree (pcm); 598 615 model->flags |= PM_MODEL_STATUS_BADARGS; 616 return model; 617 } 618 if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); } 619 620 // psphotFitSersicShapeAndIndex (pcm, readout, source, fitOptions, maskVal, markVal, psfSize); 621 options.mode = PM_SOURCE_FIT_NO_INDEX; 622 if (!psphotFitSersicShapeAndIndexGridAuto (pcm, readout, source, &options, maskVal, markVal, psfSize)) { 623 psFree (pcm); 624 model->flags |= PM_MODEL_STATUS_BADARGS; 625 psError(PS_ERR_UNKNOWN, true, "Failed to find a index & shape"); 626 psErrorClear (); // clear the polynomial error 599 627 return model; 600 628 } … … 608 636 } 609 637 610 if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); }611 612 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) {613 options.mode = PM_SOURCE_FIT_NO_INDEX;614 } else {615 options.mode = PM_SOURCE_FIT_EXT;616 }617 // update the pcm elements if we have changed the circumstance (options.mode or source->pixels)618 pmPCMupdate(pcm, source, &options, model);619 638 if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); } 620 639 … … 629 648 fprintf (stderr, "psphotFitPCM : nIter: %2d, radius: %6.1f, npix: %5d of %5d, t1: %6.4f, t2: %6.4f, t4: %6.4f, t5: %6.4f\n", model->nIter, model->fitRadius, model->nPix, nPixBig, t1, t2, t4, t5); 630 649 } 631 632 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 650 if (EXTRA_VERBOSE && !TIMING) { 651 int nPixBig = source->pixels->numCols * source->pixels->numRows; 652 float *PAR = model->params->data.F32; 653 fprintf (stderr, "source %d : %f - %f %f - %f %f %f - %f | nIter: %2d, radius: %6.1f, npix: %5d of %5d, chisq %f\n", source->id, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1], model->nIter, model->fitRadius, model->nPix, nPixBig, model->chisqNorm); 654 } 655 633 656 psFree (pcm); 634 657 … … 748 771 return true; 749 772 } 773 774 // float indexGuessInv[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083}; 775 float indexGuessInv[] = {0.5, 0.4, 0.3, 0.25, 0.20, 0.15, 0.125}; 776 # define N_INDEX_GUESS_INV 7 777 778 // float reffGuess[] = {3.0, 10.0, 20.0, 30.0, 40.0}; 779 float reffGuess[] = {0.5, 0.75, 1.0, 1.4, 2.0}; 780 # define N_REFF_GUESS 5 781 782 // A sersic model is very sensitive to the index. attempt to find the index first by grid search in just the index 783 // for a sersic model, attempt to fit just the index and normalization with a modest number of iterations 784 bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize) { 785 786 // we get a reasonable guess from: 787 // * Reff = Kron R1 788 // * Rmajor / Rminor & Theta from moments 789 // * Io from total Kron flux 790 791 // the guesses are used to fill in PAR: 792 psF32 *PAR = pcm->modelConv->params->data.F32; 793 794 // convert the moments to Major,Minor,Theta 795 psEllipseMoments moments; 796 797 if (!isfinite(source->moments->Mrf)) return false; 798 if (!isfinite(source->moments->Mxx)) return false; 799 if (!isfinite(source->moments->Mxy)) return false; 800 if (!isfinite(source->moments->Myy)) return false; 801 802 moments.x2 = source->moments->Mxx; 803 moments.y2 = source->moments->Myy; 804 moments.xy = source->moments->Mxy; 805 806 // limit axis ratio < 20.0 807 psEllipseAxes momentAxes = psEllipseMomentsToAxes (moments, 20.0); 808 809 if (0) { 810 psEllipseAxes guessAxes; 811 guessAxes.major = source->moments->Mrf; 812 guessAxes.minor = (momentAxes.minor / momentAxes.minor) * guessAxes.major; 813 guessAxes.theta = momentAxes.theta; 814 815 if (!isfinite(guessAxes.major)) return false; 816 if (!isfinite(guessAxes.minor)) return false; 817 if (!isfinite(guessAxes.theta)) return false; 818 819 // convert the major,minor,theta to shape parameters for an Reff-like model 820 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 821 } 822 823 // set the model position 824 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 825 return false; 826 } 827 828 // sky is zero (no longer fitted, but not yet deprecated) 829 PAR[PM_PAR_SKY] = 0.0; 830 831 // for the index loop, use Io = 1.0, use fitted values to determine Io 832 PAR[PM_PAR_I0] = 1.0; 833 834 float xMin = NAN; 835 float iMin = NAN; 836 float sMin = NAN; 837 float rMin = NAN; 838 839 // loop over index and Reff, keeping the ARatio and Theta constant? 840 // loop over index guesses and find the best fit 841 for (int j = 0; j < N_REFF_GUESS; j++) { 842 843 psEllipseAxes guessAxes; 844 guessAxes.major = reffGuess[j] * source->moments->Mrf; 845 guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major); 846 guessAxes.theta = momentAxes.theta; 847 848 if (!isfinite(guessAxes.major)) return false; 849 if (!isfinite(guessAxes.minor)) return false; 850 if (!isfinite(guessAxes.theta)) return false; 851 852 // convert the major,minor,theta to shape parameters for an Reff-like model 853 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 854 855 for (int i = 0; i < N_INDEX_GUESS_INV; i++) { 856 PAR[PM_PAR_7] = indexGuessInv[i]; 857 858 // generated the modelFlux 859 pmPCMMakeModel (source, pcm->modelConv, maskVal, psfSize); 860 861 float YY = 0.0; 862 float YM = 0.0; 863 float MM = 0.0; 864 bool usePoisson = false; 865 866 for (int iy = 0; iy < source->pixels->numRows; iy++) { 867 for (int ix = 0; ix < source->pixels->numCols; ix++) { 868 // skip masked points 869 if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) { 870 continue; 871 } 872 // skip zero-variance points 873 if (source->variance->data.F32[iy][ix] == 0) { 874 continue; 875 } 876 // skip nan value points 877 if (!isfinite(source->pixels->data.F32[iy][ix])) { 878 continue; 879 } 880 881 float fy = source->pixels->data.F32[iy][ix]; 882 float fm = source->modelFlux->data.F32[iy][ix]; 883 float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0; 884 885 YY += PS_SQR(fy) * wt; 886 YM += fm * fy * wt; 887 MM += PS_SQR(fm) * wt; 888 } 889 } 890 891 float Io = YM / MM; 892 float Chisq = YY - 2 * Io * YM + Io * Io * MM; 893 if (isnan(xMin) || (Chisq < xMin)) { 894 xMin = Chisq; 895 iMin = Io; 896 sMin = indexGuessInv[i]; 897 rMin = reffGuess[j]; 898 } 899 // fprintf (stderr, "%d | %f %f %f %f | %f %f %f %f", i, indexGuessInv[i], reffGuess[j], Io, Chisq, sMin, rMin, iMin, xMin); 900 // fprintf (stderr, "\n"); 901 } 902 } 903 904 { 905 psEllipseAxes guessAxes; 906 guessAxes.major = rMin * source->moments->Mrf; 907 guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major); 908 guessAxes.theta = momentAxes.theta; 909 910 if (!isfinite(guessAxes.major)) return false; 911 if (!isfinite(guessAxes.minor)) return false; 912 if (!isfinite(guessAxes.theta)) return false; 913 914 // convert the major,minor,theta to shape parameters for an Reff-like model 915 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 916 } 917 918 PAR[PM_PAR_I0] = iMin; 919 PAR[PM_PAR_7] = sMin; 920 921 return true; 922 } 923 924 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 925 bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 926 927 pmModel *model = pcm->modelConv; 928 929 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 930 931 pmSourceFitOptions options = *fitOptions; 932 933 for (int i = 0; i < 3; i++) { 934 // fit EXT (not PSF) model (set/unset the pixel mask) 935 options.mode = PM_SOURCE_FIT_SHAPE; 936 options.nIter = 2; 937 938 // update the pcm elements if we have changed the circumstance (here, options.mode) 939 pmPCMupdate(pcm, source, &options, model); 940 941 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 942 if (EXTRA_VERBOSE) { 943 float *PAR = model->params->data.F32; 944 fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 945 } 946 947 // fit EXT (not PSF) model (set/unset the pixel mask) 948 options.mode = PM_SOURCE_FIT_INDEX; 949 // options.mode = PM_SOURCE_FIT_EXT_AND_SKY; 950 options.nIter = 30; 951 952 // update the pcm elements if we have changed the circumstance (here, options.mode) 953 pmPCMupdate(pcm, source, &options, model); 954 955 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 956 if (EXTRA_VERBOSE) { 957 float *PAR = model->params->data.F32; 958 fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 959 } 960 } 961 962 // update the pcm elements if we have changed the circumstance (here, options.mode) 963 pmPCMupdate(pcm, source, fitOptions, model); 964 965 return true; 966 } 967 968 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 969 bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 970 971 pmModel *model = pcm->modelConv; 972 973 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 974 975 pmSourceFitOptions options = *fitOptions; 976 977 psF32 *PAR = pcm->modelConv->params->data.F32; 978 979 options.mode = PM_SOURCE_FIT_SHAPE; 980 options.nIter = 7; 981 982 // update the pcm elements if we have changed the circumstance (here, options.mode) 983 pmPCMupdate(pcm, source, &options, model); 984 985 // we have been provided a guess at the index (P[7]) from the list of indexGuessInv 986 987 // find the matching indexGuessInv 988 int nStart = -1; 989 for (int i = 0; i < N_INDEX_GUESS_INV; i++) { 990 if (fabs(PAR[PM_PAR_7] - indexGuessInv[i]) < 0.01) { 991 nStart = i; 992 break; 993 } 994 } 995 if (nStart == -1) { 996 fprintf (stderr, "WARNING: could not find start guess %f\n", PAR[PM_PAR_7]); 997 return false; 998 } 999 1000 psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32); 1001 psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32); 1002 1003 PAR[PM_PAR_7] = indexGuessInv[nStart]; 1004 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1005 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1006 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1007 psVectorAppend (chi2, model->chisqNorm); 1008 1009 PAR[PM_PAR_7] = (nStart < N_INDEX_GUESS_INV - 1) ? 0.5*(indexGuessInv[nStart + 1] + indexGuessInv[nStart]) : 0.1; 1010 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1011 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1012 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1013 psVectorAppend (chi2, model->chisqNorm); 1014 1015 PAR[PM_PAR_7] = (nStart > 0) ? 0.5*(indexGuessInv[nStart - 1] + indexGuessInv[nStart]) : 0.55; 1016 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1017 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1018 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1019 psVectorAppend (chi2, model->chisqNorm); 1020 1021 if (chi2->data.F32[1] < chi2->data.F32[2]) { 1022 if (nStart == N_INDEX_GUESS_INV - 1) { 1023 PAR[PM_PAR_7] = 0.11; 1024 } else { 1025 PAR[PM_PAR_7] = indexGuessInv[nStart + 1]; 1026 } 1027 } else { 1028 if (nStart == 0) { 1029 PAR[PM_PAR_7] = 0.52; 1030 } else { 1031 PAR[PM_PAR_7] = indexGuessInv[nStart - 1]; 1032 } 1033 } 1034 1035 psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2); 1036 if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) { 1037 psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola"); 1038 psFree (chi2); 1039 psFree (Sidx); 1040 psFree (poly); 1041 return false; 1042 } 1043 1044 // where is the minimum of this polynomial fit? 1045 float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0; 1046 1047 // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev) 1048 Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1); 1049 PAR[PM_PAR_7] = Smin; 1050 1051 // return to the original fitting mode (fitOptions) 1052 pmPCMupdate(pcm, source, fitOptions, model); 1053 1054 psFree (chi2); 1055 psFree (Sidx); 1056 psFree (poly); 1057 1058 return true; 1059 } 1060 1061 1062 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 1063 bool psphotFitSersicShapeAndIndexGridAutoScaled (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 1064 1065 pmModel *model = pcm->modelConv; 1066 1067 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 1068 1069 pmSourceFitOptions options = *fitOptions; 1070 1071 psF32 *PAR = pcm->modelConv->params->data.F32; 1072 1073 options.mode = PM_SOURCE_FIT_SHAPE; 1074 options.nIter = 5; 1075 1076 // update the pcm elements if we have changed the circumstance (here, options.mode) 1077 pmPCMupdate(pcm, source, &options, model); 1078 1079 float parStart[8]; 1080 for (int i = 0; i < 8; i++) parStart[i] = PAR[i]; 1081 1082 // we start with a guess at the index (P[7]) 1083 1084 // get chisq for P[7], P[7]*1.1, P[7]*1.25 (or *0.75 depending on the result of 1.1) 1085 1086 psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32); 1087 psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32); 1088 1089 PAR[PM_PAR_7] = parStart[7]; 1090 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1091 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1092 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1093 psVectorAppend (chi2, model->chisqNorm); 1094 1095 float fI = 1.1; 1096 PAR[PM_PAR_7] = parStart[7]*fI; 1097 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1098 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1099 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1100 psVectorAppend (chi2, model->chisqNorm); 1101 1102 if (chi2->data.F32[1] < chi2->data.F32[0]) { 1103 fI = 1.3; 1104 } else { 1105 fI = 1.0 / 1.3; 1106 } 1107 1108 PAR[PM_PAR_7] = parStart[7]*fI; 1109 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1110 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1111 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1112 psVectorAppend (chi2, model->chisqNorm); 1113 1114 // can we fit the 3 pts with a parabola? 1115 int nTry = 0; 1116 psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2); 1117 while (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) { 1118 psErrorClear (); // clear the polynomial error 1119 if (nTry > 4) { 1120 psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola"); 1121 psFree (chi2); 1122 psFree (Sidx); 1123 psFree (poly); 1124 return false; 1125 } 1126 fI = (fI < 1.0) ? fI / 1.3 : fI * 1.3; 1127 PAR[PM_PAR_7] = parStart[7]*fI; 1128 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1129 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1130 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1131 psVectorAppend (chi2, model->chisqNorm); 1132 nTry ++; 1133 } 1134 1135 // where is the minimum of this polynomial fit? 1136 float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0; 1137 1138 // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev) 1139 Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1); 1140 PAR[PM_PAR_7] = Smin; 1141 1142 // pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1143 // if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1144 1145 //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i]; 1146 //// 1147 //// for (float fI = 0.0; fI < 0.15; fI += 0.01) { 1148 //// PAR[PM_PAR_7] = parStart[7] - fI; 1149 //// 1150 //// // fit EXT (not PSF) model (set/unset the pixel mask) 1151 //// 1152 //// pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1153 //// if (TIMING) { 1154 //// float *PAR = model->params->data.F32; 1155 //// fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]); 1156 //// } 1157 //// } 1158 1159 // return to the original fitting mode (fitOptions) 1160 pmPCMupdate(pcm, source, fitOptions, model); 1161 1162 psFree (chi2); 1163 psFree (Sidx); 1164 psFree (poly); 1165 1166 return true; 1167 } 1168 1169 1170 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 1171 bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 1172 1173 pmModel *model = pcm->modelConv; 1174 1175 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 1176 1177 pmSourceFitOptions options = *fitOptions; 1178 1179 psF32 *PAR = pcm->modelConv->params->data.F32; 1180 1181 options.mode = PM_SOURCE_FIT_SHAPE; 1182 options.nIter = 10; 1183 1184 // update the pcm elements if we have changed the circumstance (here, options.mode) 1185 pmPCMupdate(pcm, source, &options, model); 1186 1187 psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32); 1188 psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32); 1189 1190 float par7[] = {0.100, 0.125, 0.150, 0.175, 0.200, 0.225, 0.250}; 1191 for (int i = 0; i < 7; i++) { 1192 PAR[PM_PAR_7] = par7[i]; 1193 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1194 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1195 psVectorAppend (Sidx, PAR[PM_PAR_7]); 1196 psVectorAppend (chi2, model->chisqNorm); 1197 } 1198 1199 psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2); 1200 if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) { 1201 psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola"); 1202 psFree (chi2); 1203 psFree (Sidx); 1204 psFree (poly); 1205 return false; 1206 } 1207 1208 // where is the minimum of this polynomial fit? 1209 fprintf (stderr, "fit1d: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1210 float Smin = -0.5 * poly->coeff[1] / poly->coeff[2]; 1211 1212 // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev) 1213 Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1); 1214 PAR[PM_PAR_7] = Smin; 1215 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1216 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1217 1218 //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i]; 1219 //// 1220 //// for (float fI = 0.0; fI < 0.15; fI += 0.01) { 1221 //// PAR[PM_PAR_7] = parStart[7] - fI; 1222 //// 1223 //// // fit EXT (not PSF) model (set/unset the pixel mask) 1224 //// 1225 //// pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1226 //// if (TIMING) { 1227 //// float *PAR = model->params->data.F32; 1228 //// fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]); 1229 //// } 1230 //// } 1231 1232 // return to the original fitting mode (fitOptions) 1233 pmPCMupdate(pcm, source, fitOptions, model); 1234 1235 psFree (chi2); 1236 psFree (Sidx); 1237 psFree (poly); 1238 1239 return true; 1240 } 1241 1242
Note:
See TracChangeset
for help on using the changeset viewer.
