38 #include "sinfo_vltPort.h"
48 #include "sinfo_focus.h"
49 #include "sinfo_recipes.h"
61 #define LABMAXG 1.0e+10
62 #define LABMING 1.0e-10
64 #define PI_NUMB (3.1415926535897932384626433832795)
74 static double vec[NPAR] ;
75 static double matrix1[NPAR][NPAR] ;
76 static double matrix2[NPAR][NPAR] ;
78 static int parptr[NPAR] ;
84 static int new_inv_mat (
void) ;
86 static void new_get_mat (
double * xdat,
95 static int new_get_vec (
double * xdat,
104 static int new_gauss2Ellipse (
double * parlist ) ;
143 double sinfo_new_gaussian_ellipse(
double * xdat,
double * parlist)
156 x = xdat[0] - parlist[0] ;
157 y = xdat[1] - parlist[1] ;
159 fwhmx = fabs(parlist[4]) ;
160 fwhmy = fabs(parlist[5]) ;
162 costheta = cos ( parlist[6] ) ;
163 sintheta = sin ( parlist[6] ) ;
165 argX = x * costheta + y * sintheta ;
166 argY = -x * sintheta + y * costheta ;
169 result = parlist[2] * exp(-4.*log(2.0)*((argX/fwhmx)*(argX/fwhmx)+
170 (argY/fwhmy)*(argY/fwhmy))) +
201 sinfo_new_gaussian_ellipse_deriv(
double * xdat,
219 x = xdat[0] - parlist[0] ;
220 y = xdat[1] - parlist[1] ;
222 fwhmx = fabs(parlist[4]) ;
223 fwhmy = fabs(parlist[5]) ;
224 fwx2 = fwhmx * fwhmx ;
225 fwy2 = fwhmy * fwhmy ;
227 costheta = cos ( parlist[6] ) ;
228 sintheta = sin ( parlist[6] ) ;
230 argX = x * costheta + y * sintheta ;
231 argY = -x * sintheta + y * costheta ;
233 expon = exp ( -4.0 * log(2.0) * ((argX/fwhmx)*(argX/fwhmx) +
234 (argY/fwhmy)*(argY/fwhmy)) ) ;
235 e8log2 = expon * 8.0 * log(2.0) ;
239 dervs[0] = -parlist[2]*e8log2 * (-argX*costheta/fwx2 + argY*sintheta/fwy2);
241 dervs[1] = -parlist[2]*e8log2 * (-argX*sintheta/fwx2 - argY*costheta/fwy2);
247 dervs[4] = parlist[2]*e8log2 * argX*argX/(fwx2*fwhmx) ;
249 dervs[5] = parlist[2]*e8log2 * argY*argY/(fwy2*fwhmy) ;
251 dervs[6] = -parlist[2]*e8log2 * argY * argX * (1.0/fwx2 - 1.0/fwy2) ;
266 static int new_inv_mat (
void)
277 for ( i = 0 ; i < nfree ; i++ )
282 for ( j = 0 ; j < nfree ; j++ )
285 double rowmax = fabs ( matrix2[j][j] ) ;
288 for ( i = j + 1 ; i < nfree ; i++ )
290 if ( fabs ( matrix2[i][j] ) > rowmax )
292 rowmax = fabs( matrix2[i][j] ) ;
298 if ( matrix2[row][j] == 0.0 )
307 for ( k = 0 ; k < nfree ; k++ )
309 even = matrix2[j][k] ;
310 matrix2[j][k] = matrix2[row][k] ;
311 matrix2[row][k] = even ;
320 even = 1.0 / matrix2[j][j] ;
321 for ( i = 0 ; i < nfree ; i++ )
323 matrix2[i][j] *= even ;
325 matrix2[j][j] = even ;
327 for ( k = 0 ; k < j ; k++ )
329 mjk = matrix2[j][k] ;
330 for ( i = 0 ; i < j ; i++ )
332 matrix2[i][k] -= matrix2[i][j] * mjk ;
334 for ( i = j + 1 ; i < nfree ; i++ )
336 matrix2[i][k] -= matrix2[i][j] * mjk ;
338 matrix2[j][k] = -even * mjk ;
341 for ( k = j + 1 ; k < nfree ; k++ )
343 mjk = matrix2[j][k] ;
344 for ( i = 0 ; i < j ; i++ )
346 matrix2[i][k] -= matrix2[i][j] * mjk ;
348 for ( i = j + 1 ; i < nfree ; i++ )
350 matrix2[i][k] -= matrix2[i][j] * mjk ;
352 matrix2[j][k] = -even * mjk ;
357 for ( i = 0 ; i < nfree ; i++ )
359 for ( k = 0 ; k < nfree ; k++ )
361 hv[per[k]] = matrix2[i][k] ;
363 for ( k = 0 ; k < nfree ; k++ )
365 matrix2[i][k] = hv[k] ;
388 static void new_get_mat (
double * xdat,
402 for ( j = 0 ; j < nfree ; j++ )
405 for ( i = 0 ; i<= j ; i++ )
408 matrix1[j][i] = 0.0 ;
414 for ( n = 0 ; n < (*ndat) ; n++ )
416 double wn = wdat[n] ;
419 yd=ydat[n] - sinfo_new_gaussian_ellipse(&xdat[(*xdim) * n],fpar) ;
420 sinfo_new_gaussian_ellipse_deriv( &xdat[(*xdim) * n], fpar, epar ) ;
421 chi2 += yd * yd * wn ;
422 for ( j = 0 ; j < nfree ; j++ )
424 wd = epar[parptr[j]] * wn ;
426 for ( i = 0 ; i <= j ; i++ )
428 matrix1[j][i] += epar[parptr[i]] * wd ;
463 static int new_get_vec (
double * xdat,
481 for ( j = 0 ; j < nfree ; j++ )
483 mjj = matrix1[j][j] ;
489 for ( i = 0 ; i < j ; i++ )
491 mji = matrix1[j][i] / mjj / sqrt( matrix1[i][i] ) ;
492 matrix2[i][j] = matrix2[j][i] = mji ;
494 matrix2[j][j] = 1.0 + labda ;
497 if ( (r = new_inv_mat()) )
502 for ( i = 0 ; i < (*npar) ; i ++ )
508 for ( j = 0 ; j < nfree ; j++ )
511 mjj = matrix1[j][j] ;
517 for ( i = 0 ; i < nfree ; i++ )
519 mii = matrix1[i][i] ;
525 dj += vec[i] * matrix2[j][i] / mjj / mii ;
527 epar[parptr[j]] += dj ;
532 for ( n = 0 ; n < (*ndat) ; n++ )
534 double wn = wdat[n] ;
537 dy=ydat[n] - sinfo_new_gaussian_ellipse(&xdat[(*xdim) * n],epar);
538 chi1 += wdat[n] * dy * dy ;
594 int sinfo_new_lsqfitd (
double * xdat,
618 if ( *tol < (DBL_EPSILON * 10.0 ) )
620 tolerance = DBL_EPSILON * 10.0 ;
627 labda = fabs( *lab ) * LABFACG ;
628 for ( i = 0 ; i < (*npar) ; i++ )
636 parptr[nfree++] = i ;
645 for ( n = 0 ; n < (*ndat) ; n++ )
660 for ( i = 0 ; i < nfree ; fpar[parptr[i++]] = 0.0 ) ;
661 new_get_mat ( xdat, xdim, ydat, wdat, ndat, fpar, epar) ;
662 r = new_get_vec ( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
667 for ( i = 0 ; i < (*npar) ; i++ )
672 chi1 = sqrt( chi1 / (
double) (nuse - nfree) ) ;
673 for ( i = 0 ; i < nfree ; i++ )
675 if ( (matrix1[i][i] <= 0.0 ) || (matrix2[i][i] <= 0.0) )
679 epar[parptr[i]] = chi1 * sqrt( matrix2[i][i] ) /
680 sqrt( matrix1[i][i] ) ;
701 if ( itc++ == (*its) )
705 new_get_mat( xdat, xdim, ydat, wdat, ndat, fpar, epar ) ;
711 if ( labda > LABMING )
713 labda = labda / LABFACG ;
715 r = new_get_vec ( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
722 while ( chi1 >= chi2 )
730 if ( labda > LABMAXG )
734 labda = labda * LABFACG ;
735 r = new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar) ;
743 if ( labda <= LABMAXG )
745 for ( i = 0 ; i < *npar ; i++ )
750 if ( (fabs( chi2 - chi1 ) <= (tolerance * chi1)) ||
760 new_get_mat(xdat,xdim,ydat,wdat,ndat,fpar,epar) ;
761 r=new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar ) ;
767 for ( i = 0 ; i < (*npar) ; i++ )
771 chi2 = sqrt ( chi2 / (
double) (nuse - nfree) ) ;
773 for ( i = 0 ; i < nfree ; i++ )
775 if ( (matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0) )
779 epar[parptr[i]] = chi2 * sqrt( matrix2[i][i] ) /
780 sqrt( matrix1[i][i] ) ;
821 sinfo_new_fit_2d_gaussian ( cpl_image * image,
844 float * backarray=NULL ;
846 double Mxx, Mxy, Myy ;
848 double xydat[4 *halfbox_x*halfbox_y][XDIMG] ;
849 double zdat[4*halfbox_x*halfbox_y] ;
850 double wdat[4*halfbox_x*halfbox_y] ;
863 memset(&wdat[0], 0, (4*halfbox_x*halfbox_y)*
sizeof(
double));
870 ilx=cpl_image_get_size_x(image);
871 ily=cpl_image_get_size_y(image);
873 if ( NULL == fit_par )
878 if ( NULL == derv_par )
883 if ( lleftx < 0 || lleftx + 2*halfbox_x >= ilx ||
884 llefty < 0 || llefty + 2*halfbox_y >= ily )
889 if ( halfbox_x <= 1 || halfbox_y <= 1 )
895 if ( NULL == (backarray = (
float*) cpl_calloc(4*halfbox_x+4*halfbox_y,
909 maxval = -SINFO_DBL_MAX ;
910 pidata=cpl_image_get_data_float(image);
911 for ( col = lleftx ; col < lleftx + 2*halfbox_x ; col++ )
913 for ( row = llefty ; row < llefty + 2*halfbox_y ; row++ )
915 if ( isnan(pidata[col+row*ilx]) )
919 if ( maxval < pidata[col+row*ilx] )
921 maxval = pidata[col+row*ilx] ;
928 if ( foundrow == 0 || foundcol == 0 || maxval <= 0. ||
929 foundrow == ilx-1 || foundcol == ily-1 )
932 cpl_free(backarray) ;
938 llx = foundcol - halfbox_x ;
939 lly = foundrow - halfbox_y ;
940 if ((foundcol - halfbox_x) > 0) {
941 llx = (foundcol - halfbox_x);
947 if ((foundrow - halfbox_y) > 0) {
948 lly = (foundrow - halfbox_y);
954 if ( ( llx + 2*halfbox_x) < ilx-1 ) {
957 halfbox_x=(int) (ilx-2-llx)/2;
961 if ( ( lly + 2*halfbox_y) < ily-1 ) {
964 halfbox_y=(int) (ily-2-lly)/2;
968 if ( llx <= 0 || lly < 0 || llx + 2*halfbox_x >= ilx-1 ||
969 lly + 2*halfbox_y >= ily )
972 cpl_free(backarray) ;
981 for ( j = lly ; j < lly + 2*halfbox_y ; j++ )
984 for ( i = llx ; i < llx + 2*halfbox_x ; i++ )
987 if ( !isnan(pidata[i+j*ilx]) )
989 M += pidata[i+j*ilx] ;
990 Mx += (double)boxi * pidata[i+j*ilx] ;
991 My += (double)boxj * pidata[i+j*ilx] ;
998 if ( i == llx || i == llx + 2*halfbox_x -1 ||
999 j == lly || j == lly + 2*halfbox_y -1 )
1001 backarray[n] = pidata[i+j*ilx] ;
1010 cpl_free(backarray) ;
1016 cpl_free(backarray) ;
1020 if (FLT_MAX==(background=sinfo_new_clean_mean(backarray,n,10.,10.)))
1023 "clean mean of the background values") ;
1024 cpl_free(backarray) ;
1027 cpl_free (backarray) ;
1029 amplitude = maxval - background ;
1030 if ( amplitude < 1e-12 )
1040 if ( X0 <= 0. || Y0 <= 0. || X0 >= 2.*(
double)halfbox_x ||
1041 Y0 >= 2.*(
double)halfbox_y )
1052 M = Mx = Mxx = My = Myy = Mxy = 0. ;
1054 for ( j = lly ; j < lly + 2*halfbox_y ; j++ )
1057 for ( i = llx ; i < llx + 2*halfbox_x ; i++ )
1060 value = pidata[i+j*ilx] ;
1061 if ( !isnan(value) )
1063 xydat[n][0] = (double) boxi ;
1064 xydat[n][1] = (double) boxj ;
1071 value -= background ;
1072 xco = (double) boxi - X0 ;
1073 yco = (double) boxj - Y0 ;
1077 Mxx += xco * xco * value ;
1078 Myy += yco * yco * value ;
1079 Mxy += xco * yco * value ;
1101 denom = 2. * (Mxx*Myy - Mxy*Mxy) ;
1111 fit_par[2] = amplitude ;
1112 fit_par[3] = background ;
1113 fit_par[4] = Myy/denom ;
1114 fit_par[5] = Mxx/denom ;
1115 fit_par[6] = -Mxy/denom ;
1118 if ( 0 > new_gauss2Ellipse (fit_par) )
1125 ndata = 4 * halfbox_x * halfbox_y ;
1131 for ( i = 0 ; i < NPAR ; i++ )
1136 if ( 0 > ( iters = sinfo_new_lsqfitd ( &xydat[0][0],
1154 if ( fit_par[2] <= 0. || fit_par[4] < 0. || fit_par[5] < 0. )
1161 if ( fit_par[0] < llx || fit_par[0] >= llx + 2*halfbox_x ||
1162 fit_par[1] < lly || fit_par[1] >= lly + 2*halfbox_y )
1165 "outside the fitting box") ;
1171 if ( fabs ( fit_par[6] ) > PI_NUMB / 4. )
1174 if ( fabs (fit_par[6]) >= 2. * PI_NUMB )
1176 int k = (int) (fit_par[6] / (2.*PI_NUMB)) ;
1179 fit_par[6] -= k*2.*PI_NUMB ;
1183 fit_par[6] += k*2.*PI_NUMB ;
1187 if ( fabs (fit_par[6]) > PI_NUMB / 2. )
1189 if ( fit_par[6] > 0. )
1191 fit_par[6] -= PI_NUMB ;
1195 fit_par[6] += PI_NUMB ;
1199 if ( fabs (fit_par[6]) > PI_NUMB / 4. )
1201 double temp = fit_par[4] ;
1202 fit_par[4] = fit_par[5] ;
1204 if ( fit_par[6] < 0. )
1206 fit_par[6] += PI_NUMB / 2. ;
1210 fit_par[6] -= PI_NUMB / 2. ;
1228 sinfo_crea_gaussian (cpl_image * image,
1232 cpl_image * retImage ;
1238 if ( image == NULL )
1243 ilx=cpl_image_get_size_x(image);
1244 ily=cpl_image_get_size_y(image);
1246 if ( parlist == NULL )
1252 retImage = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT) ;
1253 podata=cpl_image_get_data_float(retImage);
1254 for ( row = 0 ; row < ily ; row++ )
1256 for ( col = 0 ; col < ilx ; col++ )
1258 xdat[0] = (double) col ;
1259 xdat[1] = (double) row ;
1260 podata[col+row*ilx] = sinfo_new_gaussian_ellipse( xdat , parlist) ;
1274 static int new_gauss2Ellipse (
double * parlist )
1277 double ellipseconst ;
1278 double axisX, axisY, phi ;
1281 if ( parlist == NULL )
1291 ellipseconst = 2. * log(2.) ;
1293 if ( a*b - c*c <= 0. )
1296 "they do not make an ellipse!") ;
1306 phi = 0.5 * atan( 2. * c / (a-b) ) ;
1309 p = sqrt ( (a-b) * (a-b) + 4. * c*c ) ;
1313 axisX = 2. * sqrt ( ellipseconst / (a+b+p) ) ;
1314 axisY = 2. * sqrt ( ellipseconst / (a+b-p) ) ;
1318 axisX = 2. * sqrt ( ellipseconst / (a+b-p) ) ;
1319 axisY = 2. * sqrt ( ellipseconst / (a+b+p) ) ;
1322 parlist[4] = axisX ;
1323 parlist[5] = axisY ;
1354 float sinfo_new_determine_conversion_factor ( cpl_imagelist * cube,
1364 int first_row, first_col ;
1365 int last_row, last_col ;
1369 double derv_par[7] ;
1373 cpl_image * summedIm ;
1385 ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1386 ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1389 if ( halfbox_x <= 0 || halfbox_y <= 0 ||
1390 2*halfbox_x > ilx || 2*halfbox_y > ily)
1395 if ( exptime <= 0. )
1402 if ( NULL == (summedIm = sinfo_new_sum_cube_to_image(cube)) )
1409 for ( i = 0 ; i < 7 ; i++ )
1414 if ( -1 == (fitInd = sinfo_new_fit_2d_gaussian(summedIm, fit_par, derv_par,
1415 mpar, llx, lly, halfbox_x,
1416 halfbox_y, check)) )
1419 cpl_image_delete( summedIm) ;
1422 cpl_image_delete(summedIm) ;
1426 if ((fit_par[0] - halfbox_x) < 0) {
1430 first_col=(fit_par[0] - halfbox_x);
1433 if ((fit_par[0] + halfbox_x) < ilx) {
1434 last_col = (fit_par[0] + halfbox_x);
1436 last_col = (ilx-1) ;
1440 if ((fit_par[1] - halfbox_y) < 0) {
1444 first_row=(fit_par[1] - halfbox_y) ;
1447 if ((fit_par[1] + halfbox_y) < ily) {
1448 last_row=(fit_par[1] + halfbox_y);
1455 if ( first_col < 0 || first_row < 0 || last_col >= ilx || last_row >= ily )
1457 sinfo_msg_error(
"star badly centered in FOV or fitting box too big!") ;
1461 for ( row = first_row ; row < last_row ; row++ )
1463 for( col = first_col ; col < last_col ; col++ )
1465 xdat[0] = (double) col ;
1466 xdat[1] = (double) row ;
1467 sum += (sinfo_new_gaussian_ellipse( xdat, fit_par ) - fit_par[3]) ;
1475 factor = mag / (float)sum * exptime ;
#define sinfo_msg_error(...)
Print an error message.
#define sinfo_msg_warning(...)
Print an warning message.