146 #include "sinfo_vltPort.h"
156 #include "sinfo_focus.h"
157 #include "sinfo_recipes.h"
169 #define LABMAXG 1.0e+10
170 #define LABMING 1.0e-10
172 #define PI_NUMB (3.1415926535897932384626433832795)
181 static double labda ;
182 static double vec[NPAR] ;
183 static double matrix1[NPAR][NPAR] ;
184 static double matrix2[NPAR][NPAR] ;
186 static int parptr[NPAR] ;
192 static int new_inv_mat (
void) ;
194 static void new_get_mat (
double * xdat,
203 static int new_get_vec (
double * xdat,
212 static int new_gauss2Ellipse (
double * parlist ) ;
251 double sinfo_new_gaussian_ellipse(
double * xdat,
double * parlist)
264 x = xdat[0] - parlist[0] ;
265 y = xdat[1] - parlist[1] ;
267 fwhmx = fabs(parlist[4]) ;
268 fwhmy = fabs(parlist[5]) ;
270 costheta = cos ( parlist[6] ) ;
271 sintheta = sin ( parlist[6] ) ;
273 argX = x * costheta + y * sintheta ;
274 argY = -x * sintheta + y * costheta ;
277 result = parlist[2] * exp(-4.*log(2.0)*((argX/fwhmx)*(argX/fwhmx)+
278 (argY/fwhmy)*(argY/fwhmy))) +
309 sinfo_new_gaussian_ellipse_deriv(
double * xdat,
327 x = xdat[0] - parlist[0] ;
328 y = xdat[1] - parlist[1] ;
330 fwhmx = fabs(parlist[4]) ;
331 fwhmy = fabs(parlist[5]) ;
332 fwx2 = fwhmx * fwhmx ;
333 fwy2 = fwhmy * fwhmy ;
335 costheta = cos ( parlist[6] ) ;
336 sintheta = sin ( parlist[6] ) ;
338 argX = x * costheta + y * sintheta ;
339 argY = -x * sintheta + y * costheta ;
341 expon = exp ( -4.0 * log(2.0) * ((argX/fwhmx)*(argX/fwhmx) +
342 (argY/fwhmy)*(argY/fwhmy)) ) ;
343 e8log2 = expon * 8.0 * log(2.0) ;
347 dervs[0] = -parlist[2]*e8log2 * (-argX*costheta/fwx2 + argY*sintheta/fwy2);
349 dervs[1] = -parlist[2]*e8log2 * (-argX*sintheta/fwx2 - argY*costheta/fwy2);
355 dervs[4] = parlist[2]*e8log2 * argX*argX/(fwx2*fwhmx) ;
357 dervs[5] = parlist[2]*e8log2 * argY*argY/(fwy2*fwhmy) ;
359 dervs[6] = -parlist[2]*e8log2 * argY * argX * (1.0/fwx2 - 1.0/fwy2) ;
373 static int new_inv_mat (
void)
384 for ( i = 0 ; i < nfree ; i++ )
389 for ( j = 0 ; j < nfree ; j++ )
392 rowmax = fabs ( matrix2[j][j] ) ;
395 for ( i = j + 1 ; i < nfree ; i++ )
397 if ( fabs ( matrix2[i][j] ) > rowmax )
399 rowmax = fabs( matrix2[i][j] ) ;
405 if ( matrix2[row][j] == 0.0 )
414 for ( k = 0 ; k < nfree ; k++ )
416 even = matrix2[j][k] ;
417 matrix2[j][k] = matrix2[row][k] ;
418 matrix2[row][k] = even ;
427 even = 1.0 / matrix2[j][j] ;
428 for ( i = 0 ; i < nfree ; i++ )
430 matrix2[i][j] *= even ;
432 matrix2[j][j] = even ;
434 for ( k = 0 ; k < j ; k++ )
436 mjk = matrix2[j][k] ;
437 for ( i = 0 ; i < j ; i++ )
439 matrix2[i][k] -= matrix2[i][j] * mjk ;
441 for ( i = j + 1 ; i < nfree ; i++ )
443 matrix2[i][k] -= matrix2[i][j] * mjk ;
445 matrix2[j][k] = -even * mjk ;
448 for ( k = j + 1 ; k < nfree ; k++ )
450 mjk = matrix2[j][k] ;
451 for ( i = 0 ; i < j ; i++ )
453 matrix2[i][k] -= matrix2[i][j] * mjk ;
455 for ( i = j + 1 ; i < nfree ; i++ )
457 matrix2[i][k] -= matrix2[i][j] * mjk ;
459 matrix2[j][k] = -even * mjk ;
464 for ( i = 0 ; i < nfree ; i++ )
466 for ( k = 0 ; k < nfree ; k++ )
468 hv[per[k]] = matrix2[i][k] ;
470 for ( k = 0 ; k < nfree ; k++ )
472 matrix2[i][k] = hv[k] ;
495 static void new_get_mat (
double * xdat,
509 for ( j = 0 ; j < nfree ; j++ )
512 for ( i = 0 ; i<= j ; i++ )
515 matrix1[j][i] = 0.0 ;
521 for ( n = 0 ; n < (*ndat) ; n++ )
526 yd=ydat[n] - sinfo_new_gaussian_ellipse(&xdat[(*xdim) * n],fpar) ;
527 sinfo_new_gaussian_ellipse_deriv( &xdat[(*xdim) * n], fpar, epar ) ;
528 chi2 += yd * yd * wn ;
529 for ( j = 0 ; j < nfree ; j++ )
531 wd = epar[parptr[j]] * wn ;
533 for ( i = 0 ; i <= j ; i++ )
535 matrix1[j][i] += epar[parptr[i]] * wd ;
568 static int new_get_vec (
double * xdat,
586 for ( j = 0 ; j < nfree ; j++ )
588 mjj = matrix1[j][j] ;
594 for ( i = 0 ; i < j ; i++ )
596 mji = matrix1[j][i] / mjj / sqrt( matrix1[i][i] ) ;
597 matrix2[i][j] = matrix2[j][i] = mji ;
599 matrix2[j][j] = 1.0 + labda ;
602 if ( (r = new_inv_mat()) )
607 for ( i = 0 ; i < (*npar) ; i ++ )
613 for ( j = 0 ; j < nfree ; j++ )
616 mjj = matrix1[j][j] ;
622 for ( i = 0 ; i < nfree ; i++ )
624 mii = matrix1[i][i] ;
630 dj += vec[i] * matrix2[j][i] / mjj / mii ;
632 epar[parptr[j]] += dj ;
637 for ( n = 0 ; n < (*ndat) ; n++ )
642 dy=ydat[n] - sinfo_new_gaussian_ellipse(&xdat[(*xdim) * n],epar);
643 chi1 += wdat[n] * dy * dy ;
698 int sinfo_new_lsqfitd (
double * xdat,
722 if ( *tol < (DBL_EPSILON * 10.0 ) )
724 tolerance = DBL_EPSILON * 10.0 ;
731 labda = fabs( *lab ) * LABFACG ;
732 for ( i = 0 ; i < (*npar) ; i++ )
740 parptr[nfree++] = i ;
749 for ( n = 0 ; n < (*ndat) ; n++ )
764 for ( i = 0 ; i < nfree ; fpar[parptr[i++]] = 0.0 ) ;
765 new_get_mat ( xdat, xdim, ydat, wdat, ndat, fpar, epar) ;
766 r = new_get_vec ( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
771 for ( i = 0 ; i < (*npar) ; i++ )
776 chi1 = sqrt( chi1 / (
double) (nuse - nfree) ) ;
777 for ( i = 0 ; i < nfree ; i++ )
779 if ( (matrix1[i][i] <= 0.0 ) || (matrix2[i][i] <= 0.0) )
783 epar[parptr[i]] = chi1 * sqrt( matrix2[i][i] ) /
784 sqrt( matrix1[i][i] ) ;
805 if ( itc++ == (*its) )
809 new_get_mat( xdat, xdim, ydat, wdat, ndat, fpar, epar ) ;
815 if ( labda > LABMING )
817 labda = labda / LABFACG ;
819 r = new_get_vec ( xdat, xdim, ydat, wdat, ndat, fpar, epar, npar ) ;
826 while ( chi1 >= chi2 )
834 if ( labda > LABMAXG )
838 labda = labda * LABFACG ;
839 r = new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar) ;
847 if ( labda <= LABMAXG )
849 for ( i = 0 ; i < *npar ; i++ )
854 if ( (fabs( chi2 - chi1 ) <= (tolerance * chi1)) ||
864 new_get_mat(xdat,xdim,ydat,wdat,ndat,fpar,epar) ;
865 r=new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar ) ;
871 for ( i = 0 ; i < (*npar) ; i++ )
875 chi2 = sqrt ( chi2 / (
double) (nuse - nfree) ) ;
877 for ( i = 0 ; i < nfree ; i++ )
879 if ( (matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0) )
883 epar[parptr[i]] = chi2 * sqrt( matrix2[i][i] ) /
884 sqrt( matrix1[i][i] ) ;
923 sinfo_new_fit_2d_gaussian ( cpl_image * image,
946 float * backarray=NULL ;
948 double Mxx, Mxy, Myy ;
950 double xydat[4 *halfbox_x*halfbox_y][XDIMG] ;
951 double zdat[4*halfbox_x*halfbox_y] ;
952 double wdat[4*halfbox_x*halfbox_y] ;
965 memset(&wdat[0], 0, (4*halfbox_x*halfbox_y)*
sizeof(
double));
972 ilx=cpl_image_get_size_x(image);
973 ily=cpl_image_get_size_y(image);
975 if ( NULL == fit_par )
980 if ( NULL == derv_par )
985 if ( lleftx < 0 || lleftx + 2*halfbox_x >= ilx ||
986 llefty < 0 || llefty + 2*halfbox_y >= ily )
991 if ( halfbox_x <= 1 || halfbox_y <= 1 )
997 if ( NULL == (backarray = (
float*) cpl_calloc(4*halfbox_x+4*halfbox_y,
1011 maxval = -SINFO_DBL_MAX ;
1012 pidata=cpl_image_get_data_float(image);
1013 for ( col = lleftx ; col < lleftx + 2*halfbox_x ; col++ )
1015 for ( row = llefty ; row < llefty + 2*halfbox_y ; row++ )
1017 if ( isnan(pidata[col+row*ilx]) )
1021 if ( maxval < pidata[col+row*ilx] )
1023 maxval = pidata[col+row*ilx] ;
1030 if ( foundrow == 0 || foundcol == 0 || maxval <= 0. ||
1031 foundrow == ilx-1 || foundcol == ily-1 )
1034 cpl_free(backarray) ;
1040 llx = foundcol - halfbox_x ;
1041 lly = foundrow - halfbox_y ;
1042 if ((foundcol - halfbox_x) > 0) {
1043 llx = (foundcol - halfbox_x);
1049 if ((foundrow - halfbox_y) > 0) {
1050 lly = (foundrow - halfbox_y);
1056 if ( ( llx + 2*halfbox_x) < ilx-1 ) {
1059 halfbox_x=(int) (ilx-2-llx)/2;
1063 if ( ( lly + 2*halfbox_y) < ily-1 ) {
1066 halfbox_y=(int) (ily-2-lly)/2;
1070 if ( llx <= 0 || lly < 0 || llx + 2*halfbox_x >= ilx-1 ||
1071 lly + 2*halfbox_y >= ily )
1074 cpl_free(backarray) ;
1083 for ( j = lly ; j < lly + 2*halfbox_y ; j++ )
1086 for ( i = llx ; i < llx + 2*halfbox_x ; i++ )
1089 if ( !isnan(pidata[i+j*ilx]) )
1091 M += pidata[i+j*ilx] ;
1092 Mx += (double)boxi * pidata[i+j*ilx] ;
1093 My += (double)boxj * pidata[i+j*ilx] ;
1100 if ( i == llx || i == llx + 2*halfbox_x -1 ||
1101 j == lly || j == lly + 2*halfbox_y -1 )
1103 backarray[n] = pidata[i+j*ilx] ;
1112 cpl_free(backarray) ;
1118 cpl_free(backarray) ;
1122 if (FLT_MAX==(background=sinfo_new_clean_mean(backarray,n,10.,10.)))
1125 "clean mean of the background values") ;
1126 cpl_free(backarray) ;
1129 cpl_free (backarray) ;
1131 amplitude = maxval - background ;
1132 if ( amplitude < 1e-12 )
1142 if ( X0 <= 0. || Y0 <= 0. || X0 >= 2.*(
double)halfbox_x ||
1143 Y0 >= 2.*(
double)halfbox_y )
1154 M = Mx = Mxx = My = Myy = Mxy = 0. ;
1156 for ( j = lly ; j < lly + 2*halfbox_y ; j++ )
1159 for ( i = llx ; i < llx + 2*halfbox_x ; i++ )
1162 value = pidata[i+j*ilx] ;
1163 if ( !isnan(value) )
1165 xydat[n][0] = (double) boxi ;
1166 xydat[n][1] = (double) boxj ;
1173 value -= background ;
1174 xco = (double) boxi - X0 ;
1175 yco = (double) boxj - Y0 ;
1179 Mxx += xco * xco * value ;
1180 Myy += yco * yco * value ;
1181 Mxy += xco * yco * value ;
1203 denom = 2. * (Mxx*Myy - Mxy*Mxy) ;
1213 fit_par[2] = amplitude ;
1214 fit_par[3] = background ;
1215 fit_par[4] = Myy/denom ;
1216 fit_par[5] = Mxx/denom ;
1217 fit_par[6] = -Mxy/denom ;
1220 if ( 0 > new_gauss2Ellipse (fit_par) )
1227 ndata = 4 * halfbox_x * halfbox_y ;
1233 for ( i = 0 ; i < NPAR ; i++ )
1238 if ( 0 > ( iters = sinfo_new_lsqfitd ( &xydat[0][0],
1256 if ( fit_par[2] <= 0. || fit_par[4] < 0. || fit_par[5] < 0. )
1263 if ( fit_par[0] < llx || fit_par[0] >= llx + 2*halfbox_x ||
1264 fit_par[1] < lly || fit_par[1] >= lly + 2*halfbox_y )
1267 "outside the fitting box") ;
1273 if ( fabs ( fit_par[6] ) > PI_NUMB / 4. )
1276 if ( fabs (fit_par[6]) >= 2. * PI_NUMB )
1278 k = (int) (fit_par[6] / (2.*PI_NUMB)) ;
1281 fit_par[6] -= k*2.*PI_NUMB ;
1285 fit_par[6] += k*2.*PI_NUMB ;
1289 if ( fabs (fit_par[6]) > PI_NUMB / 2. )
1291 if ( fit_par[6] > 0. )
1293 fit_par[6] -= PI_NUMB ;
1297 fit_par[6] += PI_NUMB ;
1301 if ( fabs (fit_par[6]) > PI_NUMB / 4. )
1304 fit_par[4] = fit_par[5] ;
1306 if ( fit_par[6] < 0. )
1308 fit_par[6] += PI_NUMB / 2. ;
1312 fit_par[6] -= PI_NUMB / 2. ;
1330 sinfo_new_plot_gaussian (cpl_image * image,
1334 cpl_image * retImage ;
1340 if ( image == NULL )
1345 ilx=cpl_image_get_size_x(image);
1346 ily=cpl_image_get_size_y(image);
1348 if ( parlist == NULL )
1354 retImage = cpl_image_new (ilx, ily, CPL_TYPE_FLOAT) ;
1355 podata=cpl_image_get_data_float(retImage);
1356 for ( row = 0 ; row < ily ; row++ )
1358 for ( col = 0 ; col < ilx ; col++ )
1360 xdat[0] = (double) col ;
1361 xdat[1] = (double) row ;
1362 podata[col+row*ilx] = sinfo_new_gaussian_ellipse( xdat , parlist) ;
1376 static int new_gauss2Ellipse (
double * parlist )
1379 double ellipseconst ;
1380 double axisX, axisY, phi ;
1383 if ( parlist == NULL )
1393 ellipseconst = 2. * log(2.) ;
1395 if ( a*b - c*c <= 0. )
1398 "they do not make an ellipse!") ;
1408 phi = 0.5 * atan( 2. * c / (a-b) ) ;
1411 p = sqrt ( (a-b) * (a-b) + 4. * c*c ) ;
1415 axisX = 2. * sqrt ( ellipseconst / (a+b+p) ) ;
1416 axisY = 2. * sqrt ( ellipseconst / (a+b-p) ) ;
1420 axisX = 2. * sqrt ( ellipseconst / (a+b-p) ) ;
1421 axisY = 2. * sqrt ( ellipseconst / (a+b+p) ) ;
1424 parlist[4] = axisX ;
1425 parlist[5] = axisY ;
1454 float sinfo_new_determine_conversion_factor ( cpl_imagelist * cube,
1464 int first_row, first_col ;
1465 int last_row, last_col ;
1469 double derv_par[7] ;
1473 cpl_image * summedIm ;
1485 ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1486 ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1489 if ( halfbox_x <= 0 || halfbox_y <= 0 ||
1490 2*halfbox_x > ilx || 2*halfbox_y > ily)
1495 if ( exptime <= 0. )
1502 if ( NULL == (summedIm = sinfo_new_sum_cube_to_image(cube)) )
1509 for ( i = 0 ; i < 7 ; i++ )
1513 if ( -1 == (fitInd = sinfo_new_fit_2d_gaussian(summedIm, fit_par, derv_par,
1514 mpar, llx, lly, halfbox_x,
1515 halfbox_y, check)) )
1518 cpl_image_delete( summedIm) ;
1521 cpl_image_delete(summedIm) ;
1525 if ((fit_par[0] - halfbox_x) < 0) {
1529 first_col=(fit_par[0] - halfbox_x);
1532 if ((fit_par[0] + halfbox_x) < ilx) {
1533 last_col = (fit_par[0] + halfbox_x);
1535 last_col = (ilx-1) ;
1539 if ((fit_par[1] - halfbox_y) < 0) {
1543 first_row=(fit_par[1] - halfbox_y) ;
1546 if ((fit_par[1] + halfbox_y) < ily) {
1547 last_row=(fit_par[1] + halfbox_y);
1554 if ( first_col < 0 || first_row < 0 || last_col >= ilx || last_row >= ily )
1556 sinfo_msg_error(
"star badly centered in FOV or fitting box too big!") ;
1560 for ( row = first_row ; row < last_row ; row++ )
1562 for( col = first_col ; col < last_col ; col++ )
1564 xdat[0] = (double) col ;
1565 xdat[1] = (double) row ;
1566 sum += (sinfo_new_gaussian_ellipse( xdat, fit_par ) - fit_par[3]) ;
1574 factor = mag / (float)sum * exptime ;