00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 #ifdef HAVE_CONFIG_H
00144 # include <config.h>
00145 #endif
00146 #include "sinfo_vltPort.h"
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 #include "sinfo_focus.h"
00157 #include "sinfo_recipes.h"
00158 #include <float.h>
00159
00160
00161
00162
00163
00164 #define XDIMG 2
00165 #define TOLG 0.001
00166 #define LABG 0.1
00167 #define ITSG 200
00168 #define LABFACG 10.0
00169 #define LABMAXG 1.0e+10
00170 #define LABMING 1.0e-10
00171 #define NPAR 7
00172 #define PI_NUMB (3.1415926535897932384626433832795)
00173
00174
00175
00176
00177
00178
00179 static double chi1 ;
00180 static double chi2 ;
00181 static double labda ;
00182 static double vec[NPAR] ;
00183 static double matrix1[NPAR][NPAR] ;
00184 static double matrix2[NPAR][NPAR] ;
00185 static int nfree ;
00186 static int parptr[NPAR] ;
00187
00188
00189
00190
00191
00192 static int new_inv_mat (void) ;
00193
00194 static void new_get_mat ( double * xdat,
00195 int * xdim,
00196 double * ydat,
00197 double * wdat,
00198 int * ndat,
00199 double * fpar,
00200 double * epar
00201 ) ;
00202
00203 static int new_get_vec ( double * xdat,
00204 int * xdim,
00205 double * ydat,
00206 double * wdat,
00207 int * ndat,
00208 double * fpar,
00209 double * epar,
00210 int * npar ) ;
00211
00212 static int new_gauss2Ellipse ( double * parlist ) ;
00221
00222
00223
00224
00225
00249
00250
00251 double sinfo_new_gaussian_ellipse(double * xdat, double * parlist)
00252 {
00253 double result ;
00254 double x ;
00255 double y ;
00256 double fwhmx ;
00257 double fwhmy ;
00258 double costheta ;
00259 double sintheta ;
00260 double argX ;
00261 double argY ;
00262
00263
00264 x = xdat[0] - parlist[0] ;
00265 y = xdat[1] - parlist[1] ;
00266
00267 fwhmx = fabs(parlist[4]) ;
00268 fwhmy = fabs(parlist[5]) ;
00269
00270 costheta = cos ( parlist[6] ) ;
00271 sintheta = sin ( parlist[6] ) ;
00272
00273 argX = x * costheta + y * sintheta ;
00274 argY = -x * sintheta + y * costheta ;
00275
00276
00277 result = parlist[2] * exp(-4.*log(2.0)*((argX/fwhmx)*(argX/fwhmx)+
00278 (argY/fwhmy)*(argY/fwhmy))) +
00279 parlist[3] ;
00280
00281 return result ;
00282 }
00283
00308 void
00309 sinfo_new_gaussian_ellipse_deriv(double * xdat,
00310 double * parlist,
00311 double * dervs )
00312 {
00313 double x ;
00314 double y ;
00315 double fwhmx ;
00316 double fwhmy ;
00317 double argX ;
00318 double argY ;
00319 double expon ;
00320 double e8log2 ;
00321 double fwx2 ;
00322 double fwy2 ;
00323 double costheta ;
00324 double sintheta ;
00325
00326
00327 x = xdat[0] - parlist[0] ;
00328 y = xdat[1] - parlist[1] ;
00329
00330 fwhmx = fabs(parlist[4]) ;
00331 fwhmy = fabs(parlist[5]) ;
00332 fwx2 = fwhmx * fwhmx ;
00333 fwy2 = fwhmy * fwhmy ;
00334
00335 costheta = cos ( parlist[6] ) ;
00336 sintheta = sin ( parlist[6] ) ;
00337
00338 argX = x * costheta + y * sintheta ;
00339 argY = -x * sintheta + y * costheta ;
00340
00341 expon = exp ( -4.0 * log(2.0) * ((argX/fwhmx)*(argX/fwhmx) +
00342 (argY/fwhmy)*(argY/fwhmy)) ) ;
00343 e8log2 = expon * 8.0 * log(2.0) ;
00344
00345
00346
00347 dervs[0] = -parlist[2]*e8log2 * (-argX*costheta/fwx2 + argY*sintheta/fwy2);
00348
00349 dervs[1] = -parlist[2]*e8log2 * (-argX*sintheta/fwx2 - argY*costheta/fwy2);
00350
00351 dervs[2] = expon ;
00352
00353 dervs[3] = 1. ;
00354
00355 dervs[4] = parlist[2]*e8log2 * argX*argX/(fwx2*fwhmx) ;
00356
00357 dervs[5] = parlist[2]*e8log2 * argY*argY/(fwy2*fwhmy) ;
00358
00359 dervs[6] = -parlist[2]*e8log2 * argY * argX * (1.0/fwx2 - 1.0/fwy2) ;
00360
00361 }
00362
00373 static int new_inv_mat (void)
00374 {
00375 double even ;
00376 double hv[NPAR] ;
00377 double mjk ;
00378 double rowmax ;
00379 int evin ;
00380 int i, j, k, row ;
00381 int per[NPAR] ;
00382
00383
00384 for ( i = 0 ; i < nfree ; i++ )
00385 {
00386 per[i] = i ;
00387 }
00388
00389 for ( j = 0 ; j < nfree ; j++ )
00390 {
00391
00392 rowmax = fabs ( matrix2[j][j] ) ;
00393 row = j ;
00394
00395 for ( i = j + 1 ; i < nfree ; i++ )
00396 {
00397 if ( fabs ( matrix2[i][j] ) > rowmax )
00398 {
00399 rowmax = fabs( matrix2[i][j] ) ;
00400 row = i ;
00401 }
00402 }
00403
00404
00405 if ( matrix2[row][j] == 0.0 )
00406 {
00407 return -6 ;
00408 }
00409
00410
00411
00412 if ( row > j )
00413 {
00414 for ( k = 0 ; k < nfree ; k++ )
00415 {
00416 even = matrix2[j][k] ;
00417 matrix2[j][k] = matrix2[row][k] ;
00418 matrix2[row][k] = even ;
00419 }
00420
00421 evin = per[j] ;
00422 per[j] = per[row] ;
00423 per[row] = evin ;
00424 }
00425
00426
00427 even = 1.0 / matrix2[j][j] ;
00428 for ( i = 0 ; i < nfree ; i++ )
00429 {
00430 matrix2[i][j] *= even ;
00431 }
00432 matrix2[j][j] = even ;
00433
00434 for ( k = 0 ; k < j ; k++ )
00435 {
00436 mjk = matrix2[j][k] ;
00437 for ( i = 0 ; i < j ; i++ )
00438 {
00439 matrix2[i][k] -= matrix2[i][j] * mjk ;
00440 }
00441 for ( i = j + 1 ; i < nfree ; i++ )
00442 {
00443 matrix2[i][k] -= matrix2[i][j] * mjk ;
00444 }
00445 matrix2[j][k] = -even * mjk ;
00446 }
00447
00448 for ( k = j + 1 ; k < nfree ; k++ )
00449 {
00450 mjk = matrix2[j][k] ;
00451 for ( i = 0 ; i < j ; i++ )
00452 {
00453 matrix2[i][k] -= matrix2[i][j] * mjk ;
00454 }
00455 for ( i = j + 1 ; i < nfree ; i++ )
00456 {
00457 matrix2[i][k] -= matrix2[i][j] * mjk ;
00458 }
00459 matrix2[j][k] = -even * mjk ;
00460 }
00461 }
00462
00463
00464 for ( i = 0 ; i < nfree ; i++ )
00465 {
00466 for ( k = 0 ; k < nfree ; k++ )
00467 {
00468 hv[per[k]] = matrix2[i][k] ;
00469 }
00470 for ( k = 0 ; k < nfree ; k++ )
00471 {
00472 matrix2[i][k] = hv[k] ;
00473 }
00474 }
00475
00476
00477 return 0 ;
00478 }
00479
00495 static void new_get_mat ( double * xdat,
00496 int * xdim,
00497 double * ydat,
00498 double * wdat,
00499 int * ndat,
00500 double * fpar,
00501 double * epar
00502 )
00503 {
00504 double wd ;
00505 double wn ;
00506 double yd ;
00507 int i, j, n ;
00508
00509 for ( j = 0 ; j < nfree ; j++ )
00510 {
00511 vec[j] = 0.0 ;
00512 for ( i = 0 ; i<= j ; i++ )
00513
00514 {
00515 matrix1[j][i] = 0.0 ;
00516 }
00517 }
00518 chi2 = 0.0 ;
00519
00520
00521 for ( n = 0 ; n < (*ndat) ; n++ )
00522 {
00523 wn = wdat[n] ;
00524 if ( wn > 0.0 )
00525 {
00526 yd=ydat[n] - sinfo_new_gaussian_ellipse(&xdat[(*xdim) * n],fpar) ;
00527 sinfo_new_gaussian_ellipse_deriv( &xdat[(*xdim) * n], fpar, epar ) ;
00528 chi2 += yd * yd * wn ;
00529 for ( j = 0 ; j < nfree ; j++ )
00530 {
00531 wd = epar[parptr[j]] * wn ;
00532 vec[j] += yd * wd ;
00533 for ( i = 0 ; i <= j ; i++ )
00534 {
00535 matrix1[j][i] += epar[parptr[i]] * wd ;
00536 }
00537 }
00538 }
00539 }
00540 }
00541
00542
00568 static int new_get_vec ( double * xdat,
00569 int * xdim,
00570 double * ydat,
00571 double * wdat,
00572 int * ndat,
00573 double * fpar,
00574 double * epar,
00575 int * npar )
00576 {
00577 double dj ;
00578 double dy ;
00579 double mii ;
00580 double mji ;
00581 double mjj ;
00582 double wn ;
00583 int i, j, n, r ;
00584
00585
00586 for ( j = 0 ; j < nfree ; j++ )
00587 {
00588 mjj = matrix1[j][j] ;
00589 if ( mjj <= 0.0 )
00590 {
00591 return -5 ;
00592 }
00593 mjj = sqrt( mjj ) ;
00594 for ( i = 0 ; i < j ; i++ )
00595 {
00596 mji = matrix1[j][i] / mjj / sqrt( matrix1[i][i] ) ;
00597 matrix2[i][j] = matrix2[j][i] = mji ;
00598 }
00599 matrix2[j][j] = 1.0 + labda ;
00600 }
00601
00602 if ( (r = new_inv_mat()) )
00603 {
00604 return r ;
00605 }
00606
00607 for ( i = 0 ; i < (*npar) ; i ++ )
00608 {
00609 epar[i] = fpar[i] ;
00610 }
00611
00612
00613 for ( j = 0 ; j < nfree ; j++ )
00614 {
00615 dj = 0.0 ;
00616 mjj = matrix1[j][j] ;
00617 if ( mjj <= 0.0)
00618 {
00619 return -7 ;
00620 }
00621 mjj = sqrt ( mjj ) ;
00622 for ( i = 0 ; i < nfree ; i++ )
00623 {
00624 mii = matrix1[i][i] ;
00625 if ( mii <= 0.0 )
00626 {
00627 return -7 ;
00628 }
00629 mii = sqrt( mii ) ;
00630 dj += vec[i] * matrix2[j][i] / mjj / mii ;
00631 }
00632 epar[parptr[j]] += dj ;
00633 }
00634 chi1 = 0.0 ;
00635
00636
00637 for ( n = 0 ; n < (*ndat) ; n++ )
00638 {
00639 wn = wdat[n] ;
00640 if ( wn > 0.0 )
00641 {
00642 dy=ydat[n] - sinfo_new_gaussian_ellipse(&xdat[(*xdim) * n],epar);
00643 chi1 += wdat[n] * dy * dy ;
00644 }
00645 }
00646 return 0 ;
00647 }
00648
00649
00650
00698 int sinfo_new_lsqfitd ( double * xdat,
00699 int * xdim,
00700 double * ydat,
00701 double * wdat,
00702 int * ndat,
00703 double * fpar,
00704 double * epar,
00705 int * mpar,
00706 int * npar,
00707 double * tol ,
00708 int * its ,
00709 double * lab )
00710 {
00711 int i, n, r ;
00712 int itc ;
00713 int found ;
00714 int nuse ;
00715 double tolerance ;
00716
00717 itc = 0 ;
00718 found = 0 ;
00719 nfree = 0 ;
00720 nuse = 0 ;
00721
00722 if ( *tol < (DBL_EPSILON * 10.0 ) )
00723 {
00724 tolerance = DBL_EPSILON * 10.0 ;
00725 }
00726 else
00727 {
00728 tolerance = *tol ;
00729 }
00730
00731 labda = fabs( *lab ) * LABFACG ;
00732 for ( i = 0 ; i < (*npar) ; i++ )
00733 {
00734 if ( mpar[i] )
00735 {
00736 if ( nfree > NPAR )
00737 {
00738 return -1 ;
00739 }
00740 parptr[nfree++] = i ;
00741 }
00742 }
00743
00744 if (nfree == 0)
00745 {
00746 return -2 ;
00747 }
00748
00749 for ( n = 0 ; n < (*ndat) ; n++ )
00750 {
00751 if ( wdat[n] > 0.0 )
00752 {
00753 nuse ++ ;
00754 }
00755 }
00756
00757 if ( nfree >= nuse )
00758 {
00759 return -3 ;
00760 }
00761 if ( labda == 0.0 )
00762 {
00763
00764 for ( i = 0 ; i < nfree ; fpar[parptr[i++]] = 0.0 ) ;
00765 new_get_mat ( xdat, xdim, ydat, wdat, ndat, fpar, epar) ;
00766 r = new_get_vec ( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
00767 if ( r )
00768 {
00769 return r ;
00770 }
00771 for ( i = 0 ; i < (*npar) ; i++ )
00772 {
00773 fpar[i] = epar[i] ;
00774 epar[i] = 0.0 ;
00775 }
00776 chi1 = sqrt( chi1 / (double) (nuse - nfree) ) ;
00777 for ( i = 0 ; i < nfree ; i++ )
00778 {
00779 if ( (matrix1[i][i] <= 0.0 ) || (matrix2[i][i] <= 0.0) )
00780 {
00781 return -7 ;
00782 }
00783 epar[parptr[i]] = chi1 * sqrt( matrix2[i][i] ) /
00784 sqrt( matrix1[i][i] ) ;
00785 }
00786 }
00787 else
00788 {
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 while ( !found )
00804 {
00805 if ( itc++ == (*its) )
00806 {
00807 return -4 ;
00808 }
00809 new_get_mat( xdat, xdim, ydat, wdat, ndat, fpar, epar ) ;
00810
00811
00812
00813
00814
00815 if ( labda > LABMING )
00816 {
00817 labda = labda / LABFACG ;
00818 }
00819 r = new_get_vec ( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
00820
00821 if ( r )
00822 {
00823 return r ;
00824 }
00825
00826 while ( chi1 >= chi2 )
00827 {
00828
00829
00830
00831
00832
00833
00834 if ( labda > LABMAXG )
00835 {
00836 break ;
00837 }
00838 labda = labda * LABFACG ;
00839 r = new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar) ;
00840
00841 if ( r )
00842 {
00843 return r ;
00844 }
00845 }
00846
00847 if ( labda <= LABMAXG )
00848 {
00849 for ( i = 0 ; i < *npar ; i++ )
00850 {
00851 fpar[i] = epar[i] ;
00852 }
00853 }
00854 if ( (fabs( chi2 - chi1 ) <= (tolerance * chi1)) ||
00855 (labda > LABMAXG) )
00856 {
00857
00858
00859
00860
00861
00862
00863 labda = LABMING ;
00864 new_get_mat(xdat,xdim,ydat,wdat,ndat,fpar,epar) ;
00865 r=new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar ) ;
00866
00867 if ( r )
00868 {
00869 return r ;
00870 }
00871 for ( i = 0 ; i < (*npar) ; i++ )
00872 {
00873 epar[i] = 0.0 ;
00874 }
00875 chi2 = sqrt ( chi2 / (double) (nuse - nfree) ) ;
00876
00877 for ( i = 0 ; i < nfree ; i++ )
00878 {
00879 if ( (matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0) )
00880 {
00881 return -7 ;
00882 }
00883 epar[parptr[i]] = chi2 * sqrt( matrix2[i][i] ) /
00884 sqrt( matrix1[i][i] ) ;
00885 }
00886 found = 1 ;
00887 }
00888 }
00889 }
00890 return itc ;
00891 }
00892
00922 int
00923 sinfo_new_fit_2d_gaussian ( cpl_image * image,
00924 double * fit_par,
00925 double * derv_par,
00926 int * mpar,
00927 int lleftx,
00928 int llefty,
00929 int halfbox_x,
00930 int halfbox_y,
00931 int* check )
00932 {
00933 int i, j, n ;
00934 int col, row ;
00935 int boxi, boxj ;
00936 int iters ;
00937 int ndata ;
00938 int xdim ;
00939 int npar ;
00940 int its ;
00941 double lab ;
00942 double tol ;
00943 double maxval ;
00944 double background ;
00945 double amplitude ;
00946 float * backarray=NULL ;
00947 double M, Mx, My ;
00948 double Mxx, Mxy, Myy ;
00949 double X0, Y0 ;
00950 double xydat[4 *halfbox_x*halfbox_y][XDIMG] ;
00951 double zdat[4*halfbox_x*halfbox_y] ;
00952 double wdat[4*halfbox_x*halfbox_y] ;
00953 double xco, yco ;
00954 double value ;
00955 double denom ;
00956 double temp ;
00957 int llx, lly ;
00958 int foundrow ;
00959 int foundcol ;
00960 int k ;
00961 int ilx=0;
00962 int ily=0;
00963 float* pidata=NULL;
00964
00965
00966 if ( NULL == image )
00967 {
00968 sinfo_msg_error("no image given") ;
00969 return -1 ;
00970 }
00971 ilx=cpl_image_get_size_x(image);
00972 ily=cpl_image_get_size_y(image);
00973
00974 if ( NULL == fit_par )
00975 {
00976 sinfo_msg_error("no fit parameters given") ;
00977 return -1 ;
00978 }
00979 if ( NULL == derv_par )
00980 {
00981 sinfo_msg_error("no derivatives of fit parameters given") ;
00982 return -1 ;
00983 }
00984 if ( lleftx < 0 || lleftx + 2*halfbox_x >= ilx ||
00985 llefty < 0 || llefty + 2*halfbox_y >= ily )
00986 {
00987 sinfo_msg_error("wrong lower left point of fitting box given!") ;
00988 return -1 ;
00989 }
00990 if ( halfbox_x <= 1 || halfbox_y <= 1 )
00991 {
00992 sinfo_msg_error("wrong box dimensions given") ;
00993 return -1 ;
00994 }
00995
00996 if ( NULL == (backarray = (float*) cpl_calloc(4*halfbox_x+4*halfbox_y,
00997 sizeof(float) ) ) )
00998 {
00999 sinfo_msg_error("could not allocate memory") ;
01000 return -1 ;
01001 }
01002
01003
01004
01005
01006
01007
01008 foundrow = 0 ;
01009 foundcol = 0 ;
01010 maxval = -SINFO_DBL_MAX ;
01011 pidata=cpl_image_get_data_float(image);
01012 for ( col = lleftx ; col < lleftx + 2*halfbox_x ; col++ )
01013 {
01014 for ( row = llefty ; row < llefty + 2*halfbox_y ; row++ )
01015 {
01016 if ( isnan(pidata[col+row*ilx]) )
01017 {
01018 continue ;
01019 }
01020 if ( maxval < pidata[col+row*ilx] )
01021 {
01022 maxval = pidata[col+row*ilx] ;
01023 foundrow = row ;
01024 foundcol = col ;
01025 }
01026 }
01027 }
01028
01029 if ( foundrow == 0 || foundcol == 0 || maxval <= 0. ||
01030 foundrow == ilx-1 || foundcol == ily-1 )
01031 {
01032 sinfo_msg_warning("no maximum found") ;
01033 cpl_free(backarray) ;
01034 return -1 ;
01035 }
01036
01037
01038
01039 llx = foundcol - halfbox_x ;
01040 lly = foundrow - halfbox_y ;
01041 if ((foundcol - halfbox_x) > 0) {
01042 llx = (foundcol - halfbox_x);
01043 } else {
01044 llx=1;
01045 check++;
01046 }
01047
01048 if ((foundrow - halfbox_y) > 0) {
01049 lly = (foundrow - halfbox_y);
01050 } else {
01051 lly=1;
01052 check++;
01053 }
01054
01055 if ( ( llx + 2*halfbox_x) < ilx-1 ) {
01056
01057 } else {
01058 halfbox_x=(int) (ilx-2-llx)/2;
01059 check++;
01060 }
01061
01062 if ( ( lly + 2*halfbox_y) < ily-1 ) {
01063
01064 } else {
01065 halfbox_y=(int) (ily-2-lly)/2;
01066 check++;
01067 }
01068
01069 if ( llx <= 0 || lly < 0 || llx + 2*halfbox_x >= ilx-1 ||
01070 lly + 2*halfbox_y >= ily )
01071 {
01072 sinfo_msg_error("box does not fit into image") ;
01073 cpl_free(backarray) ;
01074 return -1 ;
01075 }
01076
01077
01078
01079 M = Mx = My = 0. ;
01080 n = 0 ;
01081 boxi = boxj = 0 ;
01082 for ( j = lly ; j < lly + 2*halfbox_y ; j++ )
01083 {
01084 boxj = j - lly ;
01085 for ( i = llx ; i < llx + 2*halfbox_x ; i++ )
01086 {
01087 boxi = i - llx ;
01088 if ( !isnan(pidata[i+j*ilx]) )
01089 {
01090 M += pidata[i+j*ilx] ;
01091 Mx += (double)boxi * pidata[i+j*ilx] ;
01092 My += (double)boxj * pidata[i+j*ilx] ;
01093
01094
01095
01096
01097
01098
01099 if ( i == llx || i == llx + 2*halfbox_x -1 ||
01100 j == lly || j == lly + 2*halfbox_y -1 )
01101 {
01102 backarray[n] = pidata[i+j*ilx] ;
01103 n++ ;
01104 }
01105 }
01106 }
01107 }
01108 if ( M <= 0. )
01109 {
01110 sinfo_msg_warning("only negative or zero values") ;
01111 cpl_free(backarray) ;
01112 return -1 ;
01113 }
01114 if ( n < 3 )
01115 {
01116 sinfo_msg_error("not enough data points to calculate background") ;
01117 cpl_free(backarray) ;
01118 return -1 ;
01119 }
01120
01121 if (FLT_MAX==(background=sinfo_new_clean_mean(backarray,n,10.,10.)))
01122 {
01123 sinfo_msg_error("it was not possible to compute the "
01124 "clean mean of the background values") ;
01125 cpl_free(backarray) ;
01126 return -1 ;
01127 }
01128 cpl_free (backarray) ;
01129
01130 amplitude = maxval - background ;
01131 if ( amplitude < 1e-12 )
01132 {
01133 sinfo_msg_warning("amplitude is too small") ;
01134 return -1 ;
01135 }
01136
01137
01138 X0 = Mx / M ;
01139 Y0 = My / M ;
01140
01141 if ( X0 <= 0. || Y0 <= 0. || X0 >= 2.*(double)halfbox_x ||
01142 Y0 >= 2.*(double)halfbox_y )
01143 {
01144 sinfo_msg_warning("center of gravity is outside the fitting box!") ;
01145 return -1 ;
01146 }
01147
01148
01149
01150
01151
01152 n = 0 ;
01153 M = Mx = Mxx = My = Myy = Mxy = 0. ;
01154 boxi = boxj = 0 ;
01155 for ( j = lly ; j < lly + 2*halfbox_y ; j++ )
01156 {
01157 boxj = j - lly ;
01158 for ( i = llx ; i < llx + 2*halfbox_x ; i++ )
01159 {
01160 boxi = i - llx ;
01161 value = pidata[i+j*ilx] ;
01162 if ( !isnan(value) )
01163 {
01164 xydat[n][0] = (double) boxi ;
01165 xydat[n][1] = (double) boxj ;
01166 zdat[n] = value ;
01167 wdat[n] = 1. ;
01168 n++ ;
01169
01170
01171
01172 value -= background ;
01173 xco = (double) boxi - X0 ;
01174 yco = (double) boxj - Y0 ;
01175 M += value ;
01176 Mx += xco * value ;
01177 My += yco * value ;
01178 Mxx += xco * xco * value ;
01179 Myy += yco * yco * value ;
01180 Mxy += xco * yco * value ;
01181 }
01182 }
01183 }
01184 if ( M <= 0. )
01185 {
01186 sinfo_msg_warning("only negative or zero values") ;
01187 return -1 ;
01188 }
01189
01190
01191
01192
01193
01194
01195
01196 Mx /= M ;
01197 My /= M ;
01198 Mxx /= M ;
01199 Myy /= M ;
01200 Mxy /= M ;
01201
01202 denom = 2. * (Mxx*Myy - Mxy*Mxy) ;
01203 if ( denom == 0. )
01204 {
01205 sinfo_msg_error("denominator is zero!") ;
01206 return -1 ;
01207 }
01208
01209
01210 fit_par[0] = X0 ;
01211 fit_par[1] = Y0 ;
01212 fit_par[2] = amplitude ;
01213 fit_par[3] = background ;
01214 fit_par[4] = Myy/denom ;
01215 fit_par[5] = Mxx/denom ;
01216 fit_par[6] = -Mxy/denom ;
01217
01218
01219 if ( 0 > new_gauss2Ellipse (fit_par) )
01220 {
01221 sinfo_msg_warning("gauss2Ellipse does not run!") ;
01222 return -1 ;
01223 }
01224
01225
01226 ndata = 4 * halfbox_x * halfbox_y ;
01227 xdim = XDIMG ;
01228 npar = NPAR ;
01229 its = ITSG ;
01230 lab = LABG ;
01231 tol = TOLG ;
01232 for ( i = 0 ; i < NPAR ; i++ )
01233 {
01234 derv_par[i] = 0. ;
01235 }
01236
01237 if ( 0 > ( iters = sinfo_new_lsqfitd ( &xydat[0][0],
01238 &xdim,
01239 zdat,
01240 wdat,
01241 &ndata,
01242 fit_par,
01243 derv_par,
01244 mpar,
01245 &npar,
01246 &tol,
01247 &its,
01248 &lab )) )
01249 {
01250 sinfo_msg_warning(" least squares fit failed, error no: %d!", iters) ;
01251 return -1 ;
01252 }
01253
01254
01255 if ( fit_par[2] <= 0. || fit_par[4] < 0. || fit_par[5] < 0. )
01256 {
01257 sinfo_msg_error("sorry, some impossible negative fit results!") ;
01258 return -1 ;
01259 }
01260 fit_par[0] += llx ;
01261 fit_par[1] += lly ;
01262 if ( fit_par[0] < llx || fit_par[0] >= llx + 2*halfbox_x ||
01263 fit_par[1] < lly || fit_par[1] >= lly + 2*halfbox_y )
01264 {
01265 sinfo_msg_error("sorry, centroid after the fit "
01266 "outside the fitting box") ;
01267 return -1 ;
01268 }
01269
01270
01271
01272 if ( fabs ( fit_par[6] ) > PI_NUMB / 4. )
01273 {
01274
01275 if ( fabs (fit_par[6]) >= 2. * PI_NUMB )
01276 {
01277 k = (int) (fit_par[6] / (2.*PI_NUMB)) ;
01278 if ( k > 0 )
01279 {
01280 fit_par[6] -= k*2.*PI_NUMB ;
01281 }
01282 else
01283 {
01284 fit_par[6] += k*2.*PI_NUMB ;
01285 }
01286 }
01287
01288 if ( fabs (fit_par[6]) > PI_NUMB / 2. )
01289 {
01290 if ( fit_par[6] > 0. )
01291 {
01292 fit_par[6] -= PI_NUMB ;
01293 }
01294 else
01295 {
01296 fit_par[6] += PI_NUMB ;
01297 }
01298 }
01299
01300 if ( fabs (fit_par[6]) > PI_NUMB / 4. )
01301 {
01302 temp = fit_par[4] ;
01303 fit_par[4] = fit_par[5] ;
01304 fit_par[5] = temp ;
01305 if ( fit_par[6] < 0. )
01306 {
01307 fit_par[6] += PI_NUMB / 2. ;
01308 }
01309 else
01310 {
01311 fit_par[6] -= PI_NUMB / 2. ;
01312 }
01313 }
01314 }
01315
01316 return iters ;
01317 }
01318
01328 cpl_image *
01329 sinfo_new_plot_gaussian (cpl_image * image,
01330 double * parlist )
01331 {
01332 int col, row ;
01333 cpl_image * retImage ;
01334 double xdat[2] ;
01335 int ilx=0;
01336 int ily=0;
01337 float* podata=NULL;
01338
01339 if ( image == NULL )
01340 {
01341 sinfo_msg_error("no input image given!") ;
01342 return NULL ;
01343 }
01344 ilx=cpl_image_get_size_x(image);
01345 ily=cpl_image_get_size_y(image);
01346
01347 if ( parlist == NULL )
01348 {
01349 sinfo_msg_error("no Gaussian parameters given!") ;
01350 return NULL ;
01351 }
01352
01353 retImage = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT) ;
01354 podata=cpl_image_get_data_float(retImage);
01355 for ( row = 0 ; row < ily ; row++ )
01356 {
01357 for ( col = 0 ; col < ilx ; col++ )
01358 {
01359 xdat[0] = (double) col ;
01360 xdat[1] = (double) row ;
01361 podata[col+row*ilx] = sinfo_new_gaussian_ellipse( xdat , parlist) ;
01362 }
01363 }
01364
01365 return retImage ;
01366 }
01367
01375 static int new_gauss2Ellipse ( double * parlist )
01376 {
01377 double a, b, c ;
01378 double ellipseconst ;
01379 double axisX, axisY, phi ;
01380 double p ;
01381
01382 if ( parlist == NULL )
01383 {
01384 sinfo_msg_error(" no parameters given!\n") ;
01385 return -1 ;
01386 }
01387
01388 a = parlist[4] ;
01389 b = parlist[5] ;
01390 c = parlist[6] ;
01391
01392 ellipseconst = 2. * log(2.) ;
01393
01394 if ( a*b - c*c <= 0. )
01395 {
01396 sinfo_msg_warning("estimates of moments are unusable, "
01397 "they do not make an ellipse!") ;
01398 return -1 ;
01399 }
01400
01401 if ( a == b )
01402 {
01403 phi = 0. ;
01404 }
01405 else
01406 {
01407 phi = 0.5 * atan( 2. * c / (a-b) ) ;
01408 }
01409
01410 p = sqrt ( (a-b) * (a-b) + 4. * c*c ) ;
01411
01412 if ( a > b )
01413 {
01414 axisX = 2. * sqrt ( ellipseconst / (a+b+p) ) ;
01415 axisY = 2. * sqrt ( ellipseconst / (a+b-p) ) ;
01416 }
01417 else
01418 {
01419 axisX = 2. * sqrt ( ellipseconst / (a+b-p) ) ;
01420 axisY = 2. * sqrt ( ellipseconst / (a+b+p) ) ;
01421 }
01422
01423 parlist[4] = axisX ;
01424 parlist[5] = axisY ;
01425 parlist[6] = phi ;
01426
01427 return 0 ;
01428 }
01429
01453 float sinfo_new_determine_conversion_factor ( cpl_imagelist * cube,
01454 float mag,
01455 float exptime,
01456 int llx,
01457 int lly,
01458 int halfbox_x,
01459 int halfbox_y,
01460 int* check )
01461 {
01462 int row, col, i ;
01463 int first_row, first_col ;
01464 int last_row, last_col ;
01465 float factor ;
01466 int mpar[7] ;
01467 double fit_par[7] ;
01468 double derv_par[7] ;
01469 int fitInd ;
01470 double sum ;
01471 double xdat[2] ;
01472 cpl_image * summedIm ;
01473
01474 int ilx=0;
01475 int ily=0;
01476 int inp=0;
01477
01478 if ( NULL == cube )
01479 {
01480 sinfo_msg_error(" no cube given!\n") ;
01481 return -FLT_MAX ;
01482 }
01483
01484 ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01485 ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01486 inp=cpl_imagelist_get_size(cube);
01487
01488 if ( halfbox_x <= 0 || halfbox_y <= 0 ||
01489 2*halfbox_x > ilx || 2*halfbox_y > ily)
01490 {
01491 sinfo_msg_error(" wrong width of halfbox given!") ;
01492 return -FLT_MAX ;
01493 }
01494 if ( exptime <= 0. )
01495 {
01496 sinfo_msg_error(" impossible exposure time given !") ;
01497 return -FLT_MAX ;
01498 }
01499
01500
01501 if ( NULL == (summedIm = sinfo_new_sum_cube_to_image(cube)) )
01502 {
01503 sinfo_msg_error(" sinfo_averageCubeToImage failed!") ;
01504 return -FLT_MAX ;
01505 }
01506
01507
01508 for ( i = 0 ; i < 7 ; i++ )
01509 {
01510 mpar[i] = 1 ;
01511 }
01512 if ( -1 == (fitInd = sinfo_new_fit_2d_gaussian(summedIm, fit_par, derv_par,
01513 mpar, llx, lly, halfbox_x,
01514 halfbox_y, check)) )
01515 {
01516 sinfo_msg_warning("sinfo_fit2dGaussian failed!") ;
01517 cpl_image_delete( summedIm) ;
01518 return -FLT_MAX ;
01519 }
01520 cpl_image_delete(summedIm) ;
01521
01522
01523
01524 if ((fit_par[0] - halfbox_x) < 0) {
01525 first_col=0;
01526 check++;
01527 } else {
01528 first_col=(fit_par[0] - halfbox_x);
01529 }
01530
01531 if ((fit_par[0] + halfbox_x) < ilx) {
01532 last_col = (fit_par[0] + halfbox_x);
01533 } else {
01534 last_col = (ilx-1) ;
01535 check++;
01536 }
01537
01538 if ((fit_par[1] - halfbox_y) < 0) {
01539 first_row=0;
01540 check++;
01541 } else {
01542 first_row=(fit_par[1] - halfbox_y) ;
01543 }
01544
01545 if ((fit_par[1] + halfbox_y) < ily) {
01546 last_row=(fit_par[1] + halfbox_y);
01547 } else {
01548 last_row= (ily-1);
01549 check++;
01550 }
01551
01552
01553 if ( first_col < 0 || first_row < 0 || last_col >= ilx || last_row >= ily )
01554 {
01555 sinfo_msg_error("star badly centered in FOV or fitting box too big!") ;
01556 return -FLT_MAX ;
01557 }
01558 sum = 0. ;
01559 for ( row = first_row ; row < last_row ; row++ )
01560 {
01561 for( col = first_col ; col < last_col ; col++ )
01562 {
01563 xdat[0] = (double) col ;
01564 xdat[1] = (double) row ;
01565 sum += (sinfo_new_gaussian_ellipse( xdat, fit_par ) - fit_par[3]) ;
01566 }
01567 }
01568 if ( sum <= 0. )
01569 {
01570 sinfo_msg_error("zero or negative sum of counts!") ;
01571 return -FLT_MAX ;
01572 }
01573 factor = mag / (float)sum * exptime ;
01574 return factor ;
01575 }
01576
01577