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
00144
00145
00146
00147
00148
00149
00150 #ifdef HAVE_CONFIG_H
00151 # include <config.h>
00152 #endif
00153 #include "sinfo_vltPort.h"
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 #include "sinfo_absolute.h"
00164 #include "sinfo_recipes.h"
00165
00166
00167
00168
00169
00170 #define XDIMA 1
00171 #define TOLA 0.001
00172 #define LABA 0.1
00173 #define ITSA 200
00174 #define LABFACA 10.0
00175 #define LABMAXA 1.0e+10
00176 #define LABMINA 1.0e-10
00177 #define NPAR 4
00178
00179
00180
00181
00182
00183 static double chi1 ;
00184 static double chi2 ;
00185 static double labda ;
00186 static double vec[NPAR] ;
00187 static double matrix1[NPAR][NPAR] ;
00188 static double matrix2[NPAR][NPAR] ;
00189 static int nfree ;
00190 static int parptr[NPAR] ;
00191
00192
00193
00194
00195
00196 static int sinfo_new_inv_mat (void) ;
00197
00198 static void sinfo_new_get_mat ( float * xdat,
00199 int * xdim,
00200 float * ydat,
00201 float * wdat,
00202 int * ndat,
00203 float * fpar,
00204 float * epar
00205 ) ;
00206
00207 static int sinfo_new_get_vec ( float * xdat,
00208 int * xdim,
00209 float * ydat,
00210 float * wdat,
00211 int * ndat,
00212 float * fpar,
00213 float * epar,
00214 int * npar ) ;
00222
00223
00224
00225
00245 float sinfo_new_boltz ( float * xdat, float * parlist )
00246 {
00247 float return_value ;
00248
00249
00250 return_value =
00251 (parlist[0] - parlist[1]) / (1 + exp(( xdat[0] - parlist[2] ) /
00252 parlist[3])) + parlist[1] ;
00253
00254 return return_value ;
00255 }
00256
00278 void sinfo_new_boltz_deriv( float * xdat, float * parlist, float * dervs )
00279 {
00280 float subst ;
00281
00282 subst = (xdat[0] - parlist[2]) / parlist[3] ;
00283
00284 dervs[0] = 1. / ( 1. + exp(subst) ) ;
00285
00286 dervs[1] = -1. / ( 1. + exp(subst) ) + 1. ;
00287
00288 dervs[2] = ( (parlist[0] - parlist[1]) / parlist[3] * exp(subst) ) /
00289 ( (1. + exp(subst)) * (1. + exp(subst)) ) ;
00290
00291 dervs[3] = ( (parlist[0] - parlist[1]) * (xdat[0] - parlist[2]) /
00292 (parlist[3]*parlist[3]) * exp(subst) ) /
00293 ( (1. + exp(subst)) * (1. + exp(subst)) ) ;
00294 }
00295
00306 static int sinfo_new_inv_mat (void)
00307 {
00308 double even ;
00309 double hv[NPAR] ;
00310 double mjk ;
00311 double rowmax ;
00312 int evin ;
00313 int i, j, k, row ;
00314 int per[NPAR] ;
00315
00316
00317 for ( i = 0 ; i < nfree ; i++ )
00318 {
00319 per[i] = i ;
00320 }
00321
00322 for ( j = 0 ; j < nfree ; j++ )
00323 {
00324
00325 rowmax = fabs ( matrix2[j][j] ) ;
00326 row = j ;
00327
00328 for ( i = j + 1 ; i < nfree ; i++ )
00329 {
00330 if ( fabs ( matrix2[i][j] ) > rowmax )
00331 {
00332 rowmax = fabs( matrix2[i][j] ) ;
00333 row = i ;
00334 }
00335 }
00336
00337
00338 if ( matrix2[row][j] == 0.0 )
00339 {
00340 return -6 ;
00341 }
00342
00343
00344 if ( row > j )
00345 {
00346 for ( k = 0 ; k < nfree ; k++ )
00347 {
00348 even = matrix2[j][k] ;
00349 matrix2[j][k] = matrix2[row][k] ;
00350 matrix2[row][k] = even ;
00351 }
00352
00353 evin = per[j] ;
00354 per[j] = per[row] ;
00355 per[row] = evin ;
00356 }
00357
00358
00359 even = 1.0 / matrix2[j][j] ;
00360 for ( i = 0 ; i < nfree ; i++ )
00361 {
00362 matrix2[i][j] *= even ;
00363 }
00364 matrix2[j][j] = even ;
00365
00366 for ( k = 0 ; k < j ; k++ )
00367 {
00368 mjk = matrix2[j][k] ;
00369 for ( i = 0 ; i < j ; i++ )
00370 {
00371 matrix2[i][k] -= matrix2[i][j] * mjk ;
00372 }
00373 for ( i = j + 1 ; i < nfree ; i++ )
00374 {
00375 matrix2[i][k] -= matrix2[i][j] * mjk ;
00376 }
00377 matrix2[j][k] = -even * mjk ;
00378 }
00379
00380 for ( k = j + 1 ; k < nfree ; k++ )
00381 {
00382 mjk = matrix2[j][k] ;
00383 for ( i = 0 ; i < j ; i++ )
00384 {
00385 matrix2[i][k] -= matrix2[i][j] * mjk ;
00386 }
00387 for ( i = j + 1 ; i < nfree ; i++ )
00388 {
00389 matrix2[i][k] -= matrix2[i][j] * mjk ;
00390 }
00391 matrix2[j][k] = -even * mjk ;
00392 }
00393 }
00394
00395
00396 for ( i = 0 ; i < nfree ; i++ )
00397 {
00398 for ( k = 0 ; k < nfree ; k++ )
00399 {
00400 hv[per[k]] = matrix2[i][k] ;
00401 }
00402 for ( k = 0 ; k < nfree ; k++ )
00403 {
00404 matrix2[i][k] = hv[k] ;
00405 }
00406 }
00407
00408
00409 return 0 ;
00410 }
00411
00426 static void sinfo_new_get_mat ( float * xdat,
00427 int * xdim,
00428 float * ydat,
00429 float * wdat,
00430 int * ndat,
00431 float * fpar,
00432 float * epar
00433 )
00434 {
00435 double wd ;
00436 double wn ;
00437 double yd ;
00438 int i, j, n ;
00439
00440 for ( j = 0 ; j < nfree ; j++ )
00441 {
00442 vec[j] = 0.0 ;
00443 for ( i = 0 ; i<= j ; i++ )
00444
00445 {
00446 matrix1[j][i] = 0.0 ;
00447 }
00448 }
00449 chi2 = 0.0 ;
00450
00451
00452 for ( n = 0 ; n < (*ndat) ; n++ )
00453 {
00454 wn = wdat[n] ;
00455 if ( wn > 0.0 )
00456 {
00457 yd = ydat[n] - sinfo_new_boltz( &xdat[(*xdim) * n], fpar ) ;
00458 sinfo_new_boltz_deriv( &xdat[(*xdim) * n], fpar, epar ) ;
00459 chi2 += yd * yd * wn ;
00460 for ( j = 0 ; j < nfree ; j++ )
00461 {
00462 wd = epar[parptr[j]] * wn ;
00463 vec[j] += yd * wd ;
00464 for ( i = 0 ; i <= j ; i++ )
00465 {
00466 matrix1[j][i] += epar[parptr[i]] * wd ;
00467 }
00468 }
00469 }
00470 }
00471 }
00472
00473
00495 static int sinfo_new_get_vec ( float * xdat,
00496 int * xdim,
00497 float * ydat,
00498 float * wdat,
00499 int * ndat,
00500 float * fpar,
00501 float * epar,
00502 int * npar )
00503 {
00504 double dj ;
00505 double dy ;
00506 double mii ;
00507 double mji ;
00508 double mjj ;
00509 double wn ;
00510 int i, j, n, r ;
00511
00512
00513 for ( j = 0 ; j < nfree ; j++ )
00514 {
00515 mjj = matrix1[j][j] ;
00516 if ( mjj <= 0.0 )
00517 {
00518 return -5 ;
00519 }
00520 mjj = sqrt( mjj ) ;
00521 for ( i = 0 ; i < j ; i++ )
00522 {
00523 mji = matrix1[j][i] / mjj / sqrt( matrix1[i][i] ) ;
00524 matrix2[i][j] = matrix2[j][i] = mji ;
00525 }
00526 matrix2[j][j] = 1.0 + labda ;
00527 }
00528
00529 if ( (r = sinfo_new_inv_mat()) )
00530 {
00531 return r ;
00532 }
00533
00534 for ( i = 0 ; i < (*npar) ; i ++ )
00535 {
00536 epar[i] = fpar[i] ;
00537 }
00538
00539
00540 for ( j = 0 ; j < nfree ; j++ )
00541 {
00542 dj = 0.0 ;
00543 mjj = matrix1[j][j] ;
00544 if ( mjj <= 0.0)
00545 {
00546 return -7 ;
00547 }
00548 mjj = sqrt ( mjj ) ;
00549 for ( i = 0 ; i < nfree ; i++ )
00550 {
00551 mii = matrix1[i][i] ;
00552 if ( mii <= 0.0 )
00553 {
00554 return -7 ;
00555 }
00556 mii = sqrt( mii ) ;
00557 dj += vec[i] * matrix2[j][i] / mjj / mii ;
00558 }
00559 epar[parptr[j]] += dj ;
00560 }
00561 chi1 = 0.0 ;
00562
00563
00564 for ( n = 0 ; n < (*ndat) ; n++ )
00565 {
00566 wn = wdat[n] ;
00567 if ( wn > 0.0 )
00568 {
00569 dy = ydat[n] - sinfo_new_boltz( &xdat[(*xdim) * n], epar) ;
00570 chi1 += wdat[n] * dy * dy ;
00571 }
00572 }
00573 return 0 ;
00574 }
00575
00576
00577
00627 int sinfo_new_lsqfit ( float * xdat,
00628 int * xdim,
00629 float * ydat,
00630 float * wdat,
00631 int * ndat,
00632 float * fpar,
00633 float * epar,
00634 int * mpar,
00635 int * npar,
00636 float * tol ,
00637 int * its ,
00638 float * lab )
00639 {
00640 int i, n, r ;
00641 int itc ;
00642 int found ;
00643 int nuse ;
00644 double tolerance ;
00645
00646 itc = 0 ;
00647 found = 0 ;
00648 nfree = 0 ;
00649 nuse = 0 ;
00650
00651 if ( *tol < (FLT_EPSILON * 10.0 ) )
00652 {
00653 tolerance = FLT_EPSILON * 10.0 ;
00654 }
00655 else
00656 {
00657 tolerance = *tol ;
00658 }
00659
00660 labda = fabs( *lab ) * LABFACA ;
00661 for ( i = 0 ; i < (*npar) ; i++ )
00662 {
00663 if ( mpar[i] )
00664 {
00665 if ( nfree > NPAR )
00666 {
00667 return -1 ;
00668 }
00669 parptr[nfree++] = i ;
00670 }
00671 }
00672
00673 if (nfree == 0)
00674 {
00675 return -2 ;
00676 }
00677
00678 for ( n = 0 ; n < (*ndat) ; n++ )
00679 {
00680 if ( wdat[n] > 0.0 )
00681 {
00682 nuse ++ ;
00683 }
00684 }
00685
00686 if ( nfree >= nuse )
00687 {
00688 return -3 ;
00689 }
00690 if ( labda == 0.0 )
00691 {
00692
00693 for ( i = 0 ; i < nfree ; fpar[parptr[i++]] = 0.0 ) ;
00694 sinfo_new_get_mat(xdat,xdim,ydat,wdat,ndat,fpar,epar ) ;
00695 r = sinfo_new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar) ;
00696 if ( r )
00697 {
00698 return r ;
00699 }
00700 for ( i = 0 ; i < (*npar) ; i++ )
00701 {
00702 fpar[i] = epar[i] ;
00703 epar[i] = 0.0 ;
00704 }
00705 chi1 = sqrt( chi1 / (double) (nuse - nfree) ) ;
00706 for ( i = 0 ; i < nfree ; i++ )
00707 {
00708 if ( (matrix1[i][i] <= 0.0 ) || (matrix2[i][i] <= 0.0) )
00709 {
00710 return -7 ;
00711 }
00712 epar[parptr[i]] = chi1 * sqrt( matrix2[i][i] ) /
00713 sqrt( matrix1[i][i] ) ;
00714 }
00715 }
00716 else
00717 {
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733 while ( !found )
00734 {
00735 if ( itc++ == (*its) )
00736 {
00737 return -4 ;
00738 }
00739 sinfo_new_get_mat(xdat,xdim,ydat,wdat,ndat,fpar,epar) ;
00740
00741
00742
00743
00744
00745 if ( labda > LABMINA )
00746 {
00747 labda = labda / LABFACA ;
00748 }
00749 r = sinfo_new_get_vec ( xdat, xdim, ydat, wdat,
00750 ndat, fpar, epar, npar ) ;
00751
00752 if ( r )
00753 {
00754 return r ;
00755 }
00756
00757 while ( chi1 >= chi2 )
00758 {
00759
00760
00761
00762
00763
00764
00765 if ( labda > LABMAXA )
00766 {
00767 break ;
00768 }
00769 labda = labda * LABFACA ;
00770 r = sinfo_new_get_vec ( xdat, xdim, ydat, wdat,
00771 ndat, fpar, epar, npar ) ;
00772
00773 if ( r )
00774 {
00775 return r ;
00776 }
00777 }
00778
00779 if ( labda <= LABMAXA )
00780 {
00781 for ( i = 0 ; i < *npar ; i++ )
00782 {
00783 fpar[i] = epar[i] ;
00784 }
00785 }
00786 if ( (fabs( chi2 - chi1 ) <= (tolerance * chi1)) ||
00787 (labda > LABMAXA) )
00788 {
00789
00790
00791
00792
00793
00794
00795 labda = LABMINA ;
00796 sinfo_new_get_mat(xdat,xdim,ydat,wdat,ndat,fpar,epar);
00797 r = sinfo_new_get_vec(xdat,xdim,ydat,wdat,ndat,fpar,epar,npar);
00798
00799 if ( r )
00800 {
00801 return r ;
00802 }
00803 for ( i = 0 ; i < (*npar) ; i++ )
00804 {
00805 epar[i] = 0.0 ;
00806 }
00807 chi2 = sqrt ( chi2 / (double) (nuse - nfree) ) ;
00808
00809 for ( i = 0 ; i < nfree ; i++ )
00810 {
00811 if ( (matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0) )
00812 {
00813 return -7 ;
00814 }
00815 epar[parptr[i]] = chi2 * sqrt( matrix2[i][i] ) /
00816 sqrt( matrix1[i][i] ) ;
00817 }
00818 found = 1 ;
00819 }
00820 }
00821 }
00822 return itc ;
00823 }
00824
00865 int sinfo_new_fit_slits_boltz ( cpl_image * lineImage,
00866 FitParams ** par,
00867 float ** slit_pos,
00868 int box_length,
00869 float y_box,
00870 float diff_tol )
00871 {
00872 float* position=NULL ;
00873 int * sinfo_edge, * edgeclean ;
00874 int * dummyedge ;
00875 int * pos_row, * pos_rowclean ;
00876 Vector * box_buffer ;
00877 Vector * half_buffer ;
00878 Vector * in_buffer ;
00879 float max_intensity ;
00880 float row_pos ;
00881 int row, col ;
00882 int i, j, k, m, n, ed ;
00883 int found, init1 ;
00884 int line ;
00885 int nel, n_right, left_right ;
00886 int n_buf, edge_ind, shift ;
00887 int column ;
00888 int slit_length ;
00889 int agreed ;
00890 int bad_line ;
00891 int margin ;
00892 int iters, xdim, ndat ;
00893 int numpar, its ;
00894 int * mpar ;
00895 float * xdat, * wdat ;
00896 float tol, lab ;
00897 float fitpar[NPAR] ;
00898 float dervpar[NPAR] ;
00899 float minval, maxval ;
00900 float min ;
00901 float pos, last_pos ;
00902 int old_col=0;
00903 int old_pos=0;
00904 int ilx=0;
00905 int ily=0;
00906 float* pidata=NULL;
00907
00908
00909 slit_length = SLITLENGTH ;
00910 if ( NULL == lineImage )
00911 {
00912 sinfo_msg_error(" no line image given!" ) ;
00913 return -1 ;
00914 }
00915
00916 if ( NULL == par )
00917 {
00918 sinfo_msg_error(" no line fit parameters given!" ) ;
00919 return -2 ;
00920 }
00921
00922 if ( NULL == slit_pos )
00923 {
00924 sinfo_msg_error(" no position array allocated!" ) ;
00925 return -3 ;
00926 }
00927
00928 if ( box_length < 4 ||
00929 box_length > 2*slit_length )
00930 {
00931 sinfo_msg_error(" wrong fitting box length given!" ) ;
00932 return -4 ;
00933 }
00934
00935 if ( y_box <= 0. || y_box > 6. )
00936 {
00937 sinfo_msg_error(" wrong y box length given!" ) ;
00938 return -5 ;
00939 }
00940
00941 if ( diff_tol < 1. )
00942 {
00943 sinfo_msg_error(" diff_tol too small!" ) ;
00944 return -6 ;
00945 }
00946
00947
00948 sinfo_edge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
00949 dummyedge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
00950 edgeclean = (int*) cpl_calloc( slit_length-1, sizeof(int) ) ;
00951 pos_row = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
00952 pos_rowclean = (int*) cpl_calloc( slit_length, sizeof(int) ) ;
00953
00954
00955
00956
00957
00958
00959 agreed = -1 ;
00960 bad_line = -1 ;
00961 while( agreed == -1 )
00962 {
00963 found = -1 ;
00964 max_intensity = -FLT_MAX ;
00965 for ( col = 0 ; col < slit_length ; col++ )
00966 {
00967 for ( i = 0 ; i < par[0]->n_params ; i++ )
00968 {
00969 if ( par[i]->column == col && par[i]->line != bad_line )
00970 {
00971 if ( par[i]->fit_par[0] > max_intensity )
00972 {
00973 if ( par[i]->fit_par[1] >= 1. &&
00974 par[i]->fit_par[2] > 0. )
00975 {
00976 max_intensity = par[i]->fit_par[0] ;
00977 found = i ;
00978 }
00979 }
00980 }
00981 }
00982 }
00983
00984
00985
00986
00987
00988 line = par[found]->line ;
00989 column = par[found]->column ;
00990 row_pos = par[found]->fit_par[2] ;
00991 if ( found >= 0 && max_intensity > 0. )
00992 {
00993 for ( i = 0 ; i < par[0]->n_params ; i++ )
00994 {
00995 if ( par[i]->line == line-1 &&
00996 par[i]->column == column + slit_length )
00997 {
00998 if ( par[i]->fit_par[2] <= (row_pos + y_box) &&
00999 par[i]->fit_par[2] >= (row_pos - y_box) )
01000 {
01001 bad_line = line ;
01002 }
01003 }
01004 }
01005 if ( bad_line != line )
01006 {
01007 agreed = 1 ;
01008 break ;
01009 }
01010 }
01011 else
01012 {
01013 sinfo_msg_error("no emission line found in the first image columns") ;
01014 cpl_free( sinfo_edge ) ;
01015 cpl_free( pos_row ) ;
01016 cpl_free( edgeclean ) ;
01017 cpl_free( dummyedge ) ;
01018 cpl_free( pos_rowclean ) ;
01019 return -7 ;
01020 }
01021 }
01022
01023
01024
01025 if ( agreed == -1 )
01026 {
01027 sinfo_msg_error(" no emission line found in the first image columns") ;
01028 cpl_free( sinfo_edge ) ;
01029 cpl_free( pos_row ) ;
01030 cpl_free( edgeclean ) ;
01031 cpl_free( dummyedge ) ;
01032 cpl_free( pos_rowclean ) ;
01033 return -7 ;
01034 }
01035
01036 ilx=cpl_image_get_size_x(lineImage);
01037 ily=cpl_image_get_size_y(lineImage);
01038 pidata=cpl_image_get_data_float(lineImage);
01039
01040
01041 n = 0 ;
01042 ed = 0 ;
01043 position=cpl_calloc(ilx,sizeof(float)) ;
01044
01045
01046 for ( col = slit_length/2 ; col < ilx - slit_length/2 ; col++ )
01047 {
01048 for ( i = 0 ; i < par[0]->n_params ; i++ )
01049 {
01050
01051
01052
01053
01054 if ( par[i]->column == col && par[i]->line == line )
01055 {
01056 if ( par[i]->fit_par[0] > 0. &&
01057 par[i]->fit_par[1] >= 1. &&
01058 par[i]->fit_par[2] > 0. )
01059 {
01060 position[n] = par[i]->fit_par[2] ;
01061 old_pos=position[n];
01062 if ( n > 0 &&
01063 fabs(position[n] - position[n-1]) > y_box &&
01064 (col-old_col) > (slit_length-SLIT_POS_ERR) )
01065 {
01066
01067 old_col=col;
01068 sinfo_edge[ed] = col ;
01069 pos_row[ed] = sinfo_new_nint( position[n-1] ) ;
01070
01071
01072 ed++ ;
01073 if ( col >= ilx - slit_length - SLIT_POS_ERR ) {
01074 pos_row[ed] = sinfo_new_nint( position[n] ) ;
01075 }
01076 } else if ( ((col-old_col) >
01077 (slit_length+SLIT_POS_ERR)) &&
01078 (col>120) ) {
01079 old_col=col;
01080 sinfo_edge[ed] = col ;
01081 pos_row[ed] = sinfo_new_nint( position[n-1] ) ;
01082 sinfo_msg_warning("add1 slitlet edge[%d]=%d, pos_row=%d",
01083 ed,sinfo_edge[ed],pos_row[ed]);
01084 ed++ ;
01085 if ( col >= ilx - slit_length - SLIT_POS_ERR ) {
01086 pos_row[ed] = sinfo_new_nint( position[n] ) ;
01087 }
01088 }
01089 n++ ;
01090 }
01091 } else if ( ((col-old_col) > (slit_length+SLIT_POS_ERR)) &&
01092 (col>120) ) {
01093
01094
01095
01096
01097 position[n] = old_pos ;
01098
01099 old_col+=slit_length;
01100 sinfo_edge[ed] = old_col; ;
01101 pos_row[ed] = sinfo_new_nint( position[n-1] ) ;
01102
01103
01104 sinfo_msg_warning("added2 slitlet sinfo_edge[%d]=%d, pos_row=%d",
01105 ed,sinfo_edge[ed],pos_row[ed]);
01106 ed++ ;
01107 if ( old_col >= ilx - slit_length - SLIT_POS_ERR ) {
01108 pos_row[ed] = old_pos ;
01109 }
01110 n++;
01111 }
01112 }
01113 }
01114
01115
01116 if ( ed < (N_SLITLETS - 1) )
01117 {
01118 sinfo_msg_error(" not enough slitlets, found: %d", ed) ;
01119 cpl_free( sinfo_edge ) ;
01120 cpl_free( pos_row ) ;
01121 cpl_free( edgeclean ) ;
01122 cpl_free( dummyedge ) ;
01123 cpl_free( pos_rowclean ) ;
01124 return -8 ;
01125 }
01126
01127
01128
01129 for ( i = 1 ; i <= ed ; i ++ )
01130 {
01131 if ( i == ed )
01132 {
01133 if ( (sinfo_edge[i-1] - sinfo_edge[i-2]) <
01134 slit_length - SLIT_LEN_ERR ||
01135 (sinfo_edge[i-1] - sinfo_edge[i-2]) >
01136 slit_length + SLIT_LEN_ERR )
01137 {
01138
01139
01140 dummyedge[i-1] = -1 ;
01141 }
01142 }
01143 if (dummyedge[i-1] != -1)
01144 {
01145 dummyedge[i-1] = sinfo_edge[i-1] ;
01146 }
01147 else
01148 {
01149 continue ;
01150 }
01151 if ( i < ed )
01152 {
01153 if ( (sinfo_edge[i] - sinfo_edge[i-1]) <
01154 slit_length - SLIT_LEN_ERR ||
01155 (sinfo_edge[i] - sinfo_edge[i-1]) >
01156 slit_length + SLIT_LEN_ERR )
01157 {
01158
01159 dummyedge[i] = -1 ;
01160 }
01161 }
01162 if ( i+1 < ed && dummyedge[i] != -1 )
01163 {
01164 if ( (sinfo_edge[i+1] - sinfo_edge[i]) <
01165 slit_length - SLIT_LEN_ERR ||
01166 (sinfo_edge[i+1] - sinfo_edge[i]) >
01167 slit_length + SLIT_LEN_ERR )
01168 {
01169
01170 dummyedge[i+1] = -1 ;
01171 }
01172 }
01173 }
01174
01175 k = 0 ;
01176 for ( i = 0 ; i < ed ; i++ )
01177 {
01178 if ( dummyedge[i] != -1 && dummyedge[i] != 0 )
01179 {
01180 edgeclean[k] = dummyedge[i] ;
01181 pos_rowclean[k] = pos_row[i] ;
01182 k++ ;
01183 if( edgeclean[k-1] > (ilx - slit_length -2*SLIT_LEN_ERR ) )
01184 {
01185 pos_rowclean[k] = pos_row[ed] ;
01186 }
01187 }
01188 }
01189
01190
01191
01192
01193
01194
01195 if ( k != N_SLITLETS - 1 )
01196 {
01197 sinfo_msg_error(" wrong number of clean slitlets found: %d", k+1) ;
01198 cpl_free( sinfo_edge ) ;
01199 cpl_free( pos_row ) ;
01200 cpl_free( edgeclean ) ;
01201 cpl_free( dummyedge ) ;
01202 cpl_free( pos_rowclean ) ;
01203 return -7 ;
01204 }
01205
01206
01207 margin = box_length / 2 ;
01208
01209
01210
01211
01212
01213
01214 if(
01215 ( (pos_rowclean[0]-sinfo_new_nint(y_box)) < 0 ) ||
01216 ( (pos_rowclean[0]+sinfo_new_nint(y_box)) >ily )
01217 ) {
01218
01219 sinfo_msg_error("pos_rowclean[0] <0 something wrong!") ;
01220 cpl_free( sinfo_edge ) ;
01221 cpl_free( pos_row ) ;
01222 cpl_free( edgeclean ) ;
01223 cpl_free( dummyedge ) ;
01224 cpl_free( pos_rowclean ) ;
01225 return -7 ;
01226
01227 }
01228
01229 for ( j = 0 ; j <= k ; j++ )
01230 {
01231 m = 0 ;
01232 if ( j == 0 )
01233 {
01234 box_buffer = sinfo_new_vector( edgeclean[0] + margin ) ;
01235 for( col = 0 ; col < edgeclean[0] + margin ; col++ )
01236 {
01237 maxval = -FLT_MAX ;
01238 for ( row = pos_rowclean[0] - sinfo_new_nint(y_box) ;
01239 row <= pos_rowclean[0] + sinfo_new_nint(y_box) ; row++ )
01240 {
01241 if ( maxval < pidata[col + ilx*row] )
01242 {
01243 maxval = pidata[col + ilx*row] ;
01244 }
01245 }
01246 box_buffer->data[m] = maxval ;
01247 m++ ;
01248 }
01249 }
01250 else if ( j < k )
01251 {
01252 box_buffer = sinfo_new_vector( edgeclean[j] -
01253 edgeclean[j-1] + 2*margin ) ;
01254 for ( col = edgeclean[j - 1] - margin ;
01255 col < edgeclean[j] + margin ; col++ )
01256 {
01257 maxval = -FLT_MAX ;
01258 for ( row = pos_rowclean[j] - sinfo_new_nint(y_box) ;
01259 row <= pos_rowclean[j] + sinfo_new_nint(y_box) ; row++ )
01260 {
01261 if ( maxval < pidata[col + ilx*row] )
01262 {
01263 maxval = pidata[col + ilx*row] ;
01264 }
01265 }
01266 box_buffer->data[m] = maxval ;
01267 m++ ;
01268 }
01269 }
01270 else
01271 {
01272 box_buffer = sinfo_new_vector( ilx - edgeclean[k-1] + margin ) ;
01273 for ( col = edgeclean[k - 1] - margin ; col < ilx ; col++ )
01274 {
01275 maxval = -FLT_MAX ;
01276 for ( row = pos_rowclean[k-2] - sinfo_new_nint(y_box) ;
01277 row <= pos_rowclean[k-2] + sinfo_new_nint(y_box) ; row++ )
01278 {
01279 if ( maxval < pidata[col + ilx*row] )
01280 {
01281 maxval = pidata[col + ilx*row] ;
01282 }
01283 }
01284 if(maxval>0) box_buffer->data[m] = maxval ;
01285 else box_buffer->data[m] = 0;
01286 m++ ;
01287 }
01288 }
01289
01290
01291
01292 min = FLT_MAX ;
01293 for ( i = 0 ; i < box_buffer->n_elements ; i++ )
01294 {
01295 if ( box_buffer -> data[i] < min )
01296 {
01297 min = box_buffer -> data[i] ;
01298 }
01299 }
01300
01301 for ( left_right = 0 ; left_right <= 1 ; left_right++ )
01302 {
01303 nel = 0 ;
01304 if ( left_right == 0 )
01305 {
01306 nel = box_buffer -> n_elements / 2 ;
01307 }
01308 else
01309 {
01310 if ( box_buffer -> n_elements % 2 == 0 )
01311 {
01312 nel = box_buffer -> n_elements / 2 ;
01313 }
01314 else
01315 {
01316 nel = box_buffer -> n_elements / 2 + 1 ;
01317 }
01318 }
01319
01320
01321
01322 half_buffer = sinfo_new_vector( nel ) ;
01323 if ( left_right == 0 )
01324 {
01325 for ( i = 0 ; i < nel ; i++ )
01326 {
01327 half_buffer -> data[i] = box_buffer -> data[i] ;
01328 }
01329 }
01330 else
01331 {
01332 n_right = 0 ;
01333 for ( i = box_buffer -> n_elements - 1 ;
01334 i >= box_buffer -> n_elements - nel ; i-- )
01335 {
01336 half_buffer -> data[n_right] = box_buffer -> data[i] ;
01337 n_right++ ;
01338 }
01339 }
01340
01341 xdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
01342 wdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
01343 mpar = (int *) cpl_calloc( NPAR, sizeof (int) ) ;
01344
01345
01346 minval = FLT_MAX ;
01347 maxval = -FLT_MAX ;
01348 for ( i = 0 ; i < nel ; i++ )
01349 {
01350 xdat[i] = i ;
01351 wdat[i] = 1.0 ;
01352 if ( half_buffer -> data[i] < minval )
01353 {
01354 minval = half_buffer -> data[i] ;
01355 }
01356 if ( half_buffer -> data[i] > maxval )
01357 {
01358 maxval = half_buffer -> data[i] ;
01359 }
01360 }
01361
01362 fitpar[0] = minval ;
01363 fitpar[1] = maxval ;
01364
01365
01366
01367 init1 = -1 ;
01368 for ( i = 0 ; i < nel ; i++ )
01369 {
01370 if ( half_buffer -> data[i] >= ( maxval + minval ) / 2. )
01371 {
01372 init1 = i ;
01373 break ;
01374 }
01375 }
01376
01377
01378
01379
01380
01381
01382
01383 edge_ind = 0 ;
01384 if ( init1 < 3 )
01385 {
01386 n_buf = half_buffer->n_elements + margin ;
01387 in_buffer = sinfo_new_vector( n_buf ) ;
01388 for ( i = 0 ; i < margin ; i++ )
01389 {
01390 in_buffer -> data[i] = min ;
01391 }
01392 shift = 0 ;
01393 for ( i = margin ; i < n_buf ; i++ )
01394 {
01395 in_buffer -> data[i] = half_buffer -> data[shift] ;
01396 shift++ ;
01397 }
01398 sinfo_new_destroy_vector ( half_buffer ) ;
01399 half_buffer = sinfo_new_vector ( n_buf ) ;
01400 for ( i = 0 ; i < n_buf ; i++ )
01401 {
01402 half_buffer -> data[i] = in_buffer -> data[i] ;
01403 }
01404 edge_ind = 1 ;
01405 init1 += margin ;
01406 sinfo_new_destroy_vector ( in_buffer ) ;
01407 }
01408
01409
01410 if ( init1 != -1 )
01411 {
01412 fitpar[2] = (float)init1 ;
01413 }
01414 fitpar[3] = 1. ;
01415
01416 for ( i = 0 ; i < NPAR ; i++ )
01417 {
01418 mpar[i] = 1 ;
01419 dervpar[i] = 0. ;
01420 }
01421
01422 xdim = XDIMA ;
01423 ndat = nel ;
01424 numpar = NPAR ;
01425 tol = TOLA ;
01426 lab = LABA ;
01427 its = ITSA ;
01428
01429
01430 if ( 0 > ( iters = sinfo_new_lsqfit( xdat, &xdim,
01431 half_buffer -> data,
01432 wdat, &ndat, fitpar,
01433 dervpar, mpar, &numpar,
01434 &tol, &its, &lab )) )
01435 {
01436
01437 sinfo_msg_warning (" least squares fit failed,"
01438 " error no.: %d in slitlet: %d", iters, j) ;
01439 fitpar[2] = (float)init1 ;
01440 }
01441
01442 pos = fitpar[2] ;
01443 if ( edge_ind == 1 )
01444 {
01445 pos -= (float)margin ;
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455 if ( left_right == 0 )
01456 {
01457
01458
01459 if ( j == 0 )
01460 {
01461 if ( fabs(pos - ((float)edgeclean[0] - 1. -
01462 (float)slit_length)) < diff_tol )
01463 {
01464 slit_pos[0][0] = pos ;
01465 }
01466 else
01467 {
01468 sinfo_msg_warning("something wrong with fitted "
01469 "left position of slitlet 0") ;
01470 if ( (float) edgeclean[0] - 1. -
01471 (float)slit_length < 0. )
01472 {
01473 slit_pos[0][0] = 0. ;
01474 }
01475 else
01476 {
01477 slit_pos[0][0] = (float)edgeclean[0] - 1. -
01478 (float)slit_length ;
01479 }
01480 }
01481 }
01482 else if ( j < k )
01483 {
01484 if ( fabs( pos - (float)margin ) < diff_tol )
01485 {
01486 slit_pos[j][0] = pos + (float)edgeclean[j-1] -
01487 (float)margin ;
01488 }
01489 else
01490 {
01491 sinfo_msg_warning("something wrong with fitted "
01492 "left position of slitlet %d", j) ;
01493 slit_pos[j][0] = (float)edgeclean[j-1] - 1. ;
01494 }
01495 }
01496 else
01497 {
01498 if ( fabs( pos - (float)margin ) < diff_tol )
01499 {
01500 slit_pos[k][0] = pos + (float)edgeclean[k-1] -
01501 (float)margin ;
01502 }
01503 else
01504 {
01505 sinfo_msg_warning("something wrong with fitted "
01506 "left position of slitlet %d", j) ;
01507 slit_pos[k][0] = (float)edgeclean[k-1] - 1. ;
01508 }
01509 }
01510 }
01511 else
01512 {
01513
01514
01515 if ( j == 0 )
01516 {
01517 if ( fabs( (float)box_buffer->n_elements - pos -
01518 (float)edgeclean[0] ) < diff_tol )
01519 {
01520 slit_pos[0][1] = (float)(box_buffer->n_elements - 1) -
01521 pos ;
01522 }
01523 else
01524 {
01525 sinfo_msg_warning("something wrong with fitted "
01526 "right position of slitlet 0") ;
01527 slit_pos[0][1] = (float)edgeclean[0] - 1. ;
01528 }
01529 }
01530 else if ( j < k )
01531 {
01532 if ( fabs( (float)box_buffer->n_elements - pos
01533 + (float)edgeclean[j-1] - (float)margin -
01534 (float)edgeclean[j] ) < diff_tol )
01535 {
01536 slit_pos[j][1] = (float)(box_buffer->n_elements - 1) -
01537 pos
01538 + (float)edgeclean[j-1] - (float)margin ;
01539 }
01540 else
01541 {
01542 sinfo_msg_warning("something wrong with fitted "
01543 "right position of slitlet %d", j) ;
01544 slit_pos[j][1] = (float)edgeclean[j] - 1. ;
01545 }
01546 }
01547 else
01548 {
01549 if ( edgeclean[k-1] + slit_length > ilx )
01550 {
01551 last_pos = (float)(ilx - 1) ;
01552 }
01553 else
01554 {
01555 last_pos = (float)(edgeclean[k-1] - 1 + slit_length) ;
01556 }
01557 if ( fabs( (float)(box_buffer->n_elements - 1) - pos
01558 + (float)edgeclean[k-1] - (float)margin -
01559 last_pos ) < diff_tol )
01560 {
01561 slit_pos[k][1] = (float)(box_buffer->n_elements - 1) -
01562 pos
01563 + (float)edgeclean[k-1] - (float)margin ;
01564 }
01565 else
01566 {
01567 sinfo_msg_warning("something wrong with fitted "
01568 "right position of slitlet %d", j) ;
01569 slit_pos[k][1] = last_pos ;
01570 }
01571 }
01572 }
01573
01574 sinfo_new_destroy_vector ( half_buffer ) ;
01575 cpl_free( xdat ) ;
01576 cpl_free( wdat ) ;
01577 cpl_free( mpar ) ;
01578 }
01579 sinfo_new_destroy_vector ( box_buffer ) ;
01580 }
01581
01582
01583 cpl_free( sinfo_edge ) ;
01584 cpl_free( pos_row ) ;
01585 cpl_free( edgeclean ) ;
01586 cpl_free( dummyedge ) ;
01587 cpl_free( pos_rowclean ) ;
01588 cpl_free( position);
01589 return 0 ;
01590 }
01591
01619 int
01620 sinfo_new_fit_slits_boltz_single_line ( cpl_image * lineImage,
01621 float ** slit_pos,
01622 int box_length,
01623 float y_box,
01624 int low_pos,
01625 int high_pos )
01626 {
01627 int* position=NULL ;
01628 int * sinfo_edge, * edgeclean ;
01629 int * dummyedge ;
01630 int * pos_row, * pos_rowclean ;
01631 Vector * box_buffer ;
01632 Vector * half_buffer ;
01633 Vector * in_buffer ;
01634 int found_row ;
01635 int row, col ;
01636 int i, j, k, m, ed ;
01637 int init1 ;
01638 int nel, n_right, left_right ;
01639 int n_buf, edge_ind, shift ;
01640 int slit_length ;
01641 int margin ;
01642 int iters, xdim, ndat ;
01643 int numpar, its ;
01644 int * mpar ;
01645 float * xdat, * wdat ;
01646 float tol, lab ;
01647 float fitpar[NPAR] ;
01648 float dervpar[NPAR] ;
01649 float minval, maxval ;
01650 float min ;
01651 float pos, last_pos ;
01652 int ilx=0;
01653 int ily=0;
01654 float* pidata=NULL;
01655
01656 slit_length = SLITLENGTH ;
01657
01658 if ( NULL == lineImage )
01659 {
01660 sinfo_msg_error(" no line image given!" ) ;
01661 return -1 ;
01662 }
01663
01664 if ( NULL == slit_pos )
01665 {
01666 sinfo_msg_error(" no position array allocated!" ) ;
01667 return -1 ;
01668 }
01669
01670 if ( box_length < 4 ||
01671 box_length > 2*slit_length )
01672 {
01673 sinfo_msg_error(" wrong fitting box length given!" ) ;
01674 return -1 ;
01675 }
01676
01677 if ( y_box <= 0. || y_box > 6. )
01678 {
01679 sinfo_msg_error(" wrong y box length given!" ) ;
01680 return -1 ;
01681 }
01682
01683 ilx=cpl_image_get_size_x(lineImage);
01684 ily=cpl_image_get_size_y(lineImage);
01685 pidata=cpl_image_get_data_float(lineImage);
01686
01687 if ( low_pos >= high_pos || low_pos < 0 ||
01688 high_pos <= 0 || high_pos >= ilx )
01689 {
01690 sinfo_msg_error(" wrong user given search positions!" ) ;
01691 return -1 ;
01692 }
01693
01694
01695 sinfo_edge = (int*) cpl_calloc( ilx/2, sizeof(int) ) ;
01696 dummyedge = (int*) cpl_calloc( ilx/2, sizeof(int) ) ;
01697 edgeclean = (int*) cpl_calloc( ilx/2, sizeof(int) ) ;
01698 pos_row = (int*) cpl_calloc( ilx/2, sizeof(int) ) ;
01699 pos_rowclean = (int*) cpl_calloc( ilx/2, sizeof(int) ) ;
01700
01701
01702 position=cpl_calloc(ilx,sizeof(int)); ;
01703
01704 for ( col = 0 ; col < ilx ; col++ )
01705 {
01706 found_row = -1 ;
01707 maxval = -FLT_MAX ;
01708 for ( row = low_pos ; row <= high_pos ; row++ )
01709 {
01710 if ( maxval < pidata[col+row*ilx] )
01711 {
01712 maxval = pidata[col+row*ilx] ;
01713 found_row = row ;
01714 }
01715 }
01716 if ( maxval > -FLT_MAX && found_row > low_pos )
01717 {
01718 position[col] = found_row ;
01719 }
01720 else
01721 {
01722 position[col] = 0 ;
01723 }
01724 }
01725
01726
01727 ed = 0 ;
01728 for ( col = 0 ; col < (ilx) - 1 ; col++ )
01729 {
01730 if ( position[col] > 0 && position[col+1] > 0 &&
01731 abs(position[col+1] - position[col]) > 10 )
01732 {
01733 sinfo_edge[ed] = col ;
01734 pos_row[ed] = position[col] ;
01735 ed++ ;
01736 }
01737
01738 }
01739 if (ed <= 1)
01740 {
01741 sinfo_msg_error(" no slitlets found!" ) ;
01742 cpl_free( sinfo_edge ) ;
01743 cpl_free( pos_row ) ;
01744 cpl_free( edgeclean ) ;
01745 cpl_free( dummyedge ) ;
01746 cpl_free( pos_rowclean ) ;
01747 return -1 ;
01748 }
01749
01750
01751 for ( i = 1 ; i <= ed ; i ++ )
01752 {
01753 if ( i == ed )
01754 {
01755 if ( (sinfo_edge[i-1] - sinfo_edge[i-2]) <
01756 slit_length - SLIT_LEN_ERR ||
01757 (sinfo_edge[i-1] - sinfo_edge[i-2]) >
01758 slit_length + SLIT_LEN_ERR )
01759 {
01760 dummyedge[i-1] = -1 ;
01761 }
01762 }
01763 if (dummyedge[i-1] != -1)
01764 {
01765 dummyedge[i-1] = sinfo_edge[i-1] ;
01766 }
01767 else
01768 {
01769 continue ;
01770 }
01771 if ( i < ed )
01772 {
01773 if ( (sinfo_edge[i] - sinfo_edge[i-1]) <
01774 slit_length - SLIT_LEN_ERR ||
01775 (sinfo_edge[i] - sinfo_edge[i-1]) >
01776 slit_length + SLIT_LEN_ERR )
01777 {
01778 dummyedge[i] = -1 ;
01779 }
01780 }
01781 if ( i+1 < ed && dummyedge[i] != -1 )
01782 {
01783 if ( (sinfo_edge[i+1] - sinfo_edge[i]) <
01784 slit_length - SLIT_LEN_ERR ||
01785 (sinfo_edge[i+1] - sinfo_edge[i]) >
01786 slit_length + SLIT_LEN_ERR )
01787 {
01788 dummyedge[i+1] = -1 ;
01789 }
01790 }
01791 }
01792
01793 k = 0 ;
01794 for ( i = 0 ; i < ed ; i++ )
01795 {
01796 if ( dummyedge[i] != -1 && dummyedge[i] != 0 )
01797 {
01798 edgeclean[k] = dummyedge[i] ;
01799 pos_rowclean[k] = pos_row[i] ;
01800 k++ ;
01801 if( edgeclean[k-1] > (ilx - slit_length - 2*SLIT_LEN_ERR ) )
01802 {
01803 pos_rowclean[k] = pos_row[ed] ;
01804 }
01805 }
01806 }
01807
01808
01809 margin = box_length / 2 ;
01810
01811
01812
01813
01814
01815
01816 for ( j = 0 ; j <= k ; j++ )
01817 {
01818 m = 0 ;
01819 if ( j == 0 )
01820 {
01821 box_buffer = sinfo_new_vector( edgeclean[0] + margin ) ;
01822 for( col = 0 ; col < edgeclean[0] + margin ; col++ )
01823 {
01824 maxval = -FLT_MAX ;
01825 for ( row = pos_rowclean[0] - sinfo_new_nint(y_box) ;
01826 row <= pos_rowclean[0] + sinfo_new_nint(y_box) ; row++ )
01827 {
01828 if ( maxval < pidata[col + ilx*row] )
01829 {
01830 maxval = pidata[col + ilx*row] ;
01831 }
01832 }
01833 box_buffer->data[m] = maxval ;
01834 m++ ;
01835 }
01836 }
01837 else if ( j < k )
01838 {
01839 box_buffer = sinfo_new_vector( edgeclean[j] -
01840 edgeclean[j-1] + 2*margin ) ;
01841 for ( col = edgeclean[j - 1] - margin ;
01842 col < edgeclean[j] + margin ; col++ )
01843 {
01844 maxval = -FLT_MAX ;
01845 for ( row = pos_rowclean[j] - sinfo_new_nint(y_box) ;
01846 row <= pos_rowclean[j] + sinfo_new_nint(y_box) ; row++ )
01847 {
01848 if ( maxval < pidata[col + ilx*row] )
01849 {
01850 maxval = pidata[col + ilx*row] ;
01851 }
01852 }
01853 box_buffer->data[m] = maxval ;
01854 m++ ;
01855 }
01856 }
01857 else
01858 {
01859 box_buffer = sinfo_new_vector( ilx - edgeclean[k-1] + margin ) ;
01860 for ( col = edgeclean[k - 1] - margin ; col < ilx ; col++ )
01861 {
01862 if ( col < 0 )
01863 {
01864 col = 0 ;
01865 }
01866
01867 maxval = -FLT_MAX ;
01868 for ( row = pos_rowclean[k] - sinfo_new_nint(y_box) ;
01869 row <= pos_rowclean[k] + sinfo_new_nint(y_box) ; row++ )
01870 {
01871 if ( row < 0 )
01872 {
01873 continue ;
01874 }
01875 if ( maxval < pidata[col + row * ilx] )
01876 {
01877 maxval = pidata[col + row * ilx] ;
01878 }
01879 }
01880 box_buffer->data[m] = maxval ;
01881 m++ ;
01882 }
01883 }
01884
01885
01886
01887 min = FLT_MAX ;
01888 for ( i = 0 ; i < box_buffer->n_elements ; i++ )
01889 {
01890 if ( box_buffer -> data[i] < min )
01891 {
01892 min = box_buffer -> data[i] ;
01893 }
01894 }
01895
01896 for ( left_right = 0 ; left_right <= 1 ; left_right++ )
01897 {
01898 nel = 0 ;
01899 if ( left_right == 0 )
01900 {
01901 nel = box_buffer -> n_elements / 2 ;
01902 }
01903 else
01904 {
01905 if ( box_buffer -> n_elements % 2 == 0 )
01906 {
01907 nel = box_buffer -> n_elements / 2 ;
01908 }
01909 else
01910 {
01911 nel = box_buffer -> n_elements / 2 + 1 ;
01912 }
01913 }
01914
01915
01916
01917 half_buffer = sinfo_new_vector( nel ) ;
01918 if ( left_right == 0 )
01919 {
01920 for ( i = 0 ; i < nel ; i++ )
01921 {
01922 half_buffer -> data[i] = box_buffer -> data[i] ;
01923 }
01924 }
01925 else
01926 {
01927 n_right = 0 ;
01928 for ( i = box_buffer -> n_elements - 1 ;
01929 i >= box_buffer -> n_elements - nel ; i-- )
01930 {
01931 half_buffer -> data[n_right] = box_buffer -> data[i] ;
01932 n_right++ ;
01933 }
01934 }
01935
01936 xdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
01937 wdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
01938 mpar = (int *) cpl_calloc( NPAR, sizeof (int) ) ;
01939
01940
01941 minval = FLT_MAX ;
01942 maxval = -FLT_MAX ;
01943 for ( i = 0 ; i < nel ; i++ )
01944 {
01945 xdat[i] = i ;
01946 wdat[i] = 1.0 ;
01947 if ( half_buffer -> data[i] < minval )
01948 {
01949 minval = half_buffer -> data[i] ;
01950 }
01951 if ( half_buffer -> data[i] > maxval )
01952 {
01953 maxval = half_buffer -> data[i] ;
01954 }
01955 }
01956 fitpar[0] = minval ;
01957 fitpar[1] = maxval ;
01958
01959
01960
01961 init1 = -1 ;
01962 for ( i = 0 ; i < nel ; i++ )
01963 {
01964 if ( half_buffer -> data[i] >= ( maxval + minval ) / 2. )
01965 {
01966 init1 = i ;
01967 break ;
01968 }
01969 }
01970
01971
01972
01973
01974
01975
01976
01977 edge_ind = 0 ;
01978 if ( init1 < 3 )
01979 {
01980 n_buf = half_buffer->n_elements + margin ;
01981 in_buffer = sinfo_new_vector( n_buf ) ;
01982 for ( i = 0 ; i < margin ; i++ )
01983 {
01984 in_buffer -> data[i] = min ;
01985 }
01986 shift = 0 ;
01987 for ( i = margin ; i < n_buf ; i++ )
01988 {
01989 in_buffer -> data[i] = half_buffer -> data[shift] ;
01990 shift++ ;
01991 }
01992 sinfo_new_destroy_vector ( half_buffer ) ;
01993 half_buffer = sinfo_new_vector ( n_buf ) ;
01994 for ( i = 0 ; i < n_buf ; i++ )
01995 {
01996 half_buffer -> data[i] = in_buffer -> data[i] ;
01997 }
01998 edge_ind = 1 ;
01999 init1 += margin ;
02000 sinfo_new_destroy_vector ( in_buffer ) ;
02001 }
02002
02003
02004 if ( init1 != -1 )
02005 {
02006 fitpar[2] = (float)init1 ;
02007 }
02008 fitpar[3] = 1. ;
02009
02010 for ( i = 0 ; i < NPAR ; i++ )
02011 {
02012 mpar[i] = 1 ;
02013 dervpar[i] = 0. ;
02014 }
02015
02016 xdim = XDIMA ;
02017 ndat = nel ;
02018 numpar = NPAR ;
02019 tol = TOLA ;
02020 lab = LABA ;
02021 its = ITSA ;
02022
02023
02024 if ( 0 > ( iters = sinfo_new_lsqfit( xdat, &xdim,
02025 half_buffer -> data,
02026 wdat, &ndat, fitpar,
02027 dervpar, mpar, &numpar,
02028 &tol, &its, &lab )) )
02029 {
02030 sinfo_msg_warning (" least squares fit failed, error "
02031 "no.: %d in slitlet: %d", iters, j) ;
02032 fitpar[2] = 0. ;
02033 }
02034 if ( fitpar[3] <=0. )
02035 {
02036 sinfo_msg_warning(" fit failed due to negative width"
02037 " of boltzmann function in slitlet: %d", j) ;
02038 fitpar[2] = 0. ;
02039 }
02040
02041 pos = fitpar[2] ;
02042 if ( edge_ind == 1 )
02043 {
02044 pos -= (float)margin ;
02045 }
02046
02047
02048
02049
02050
02051
02052
02053
02054 if ( left_right == 0 )
02055 {
02056
02057
02058 if ( j == 0 )
02059 {
02060 slit_pos[0][0] = pos ;
02061 if ( slit_pos[0][0] - (int) slit_pos[0][0] == 0.)
02062 {
02063 slit_pos[0][0] = 0. ;
02064 }
02065 }
02066 else if ( j < k )
02067 {
02068 slit_pos[j][0] = pos + (float)edgeclean[j-1] -
02069 (float)margin ;
02070 if ( slit_pos[j][0] - (int) slit_pos[j][0] == 0.)
02071 {
02072 slit_pos[j][0] = 0. ;
02073 }
02074 }
02075 else
02076 {
02077 slit_pos[k][0] = pos + (float)edgeclean[k-1] -
02078 (float)margin ;
02079 if ( slit_pos[k][0] - (int) slit_pos[k][0] == 0.)
02080 {
02081 slit_pos[k][0] = 0. ;
02082 }
02083 }
02084 }
02085 else
02086 {
02087
02088
02089 if ( j == 0 )
02090 {
02091 slit_pos[0][1] = (float)(box_buffer->n_elements - 1) - pos;
02092 if ( slit_pos[0][1] - (int) slit_pos[0][1] == 0.)
02093 {
02094 slit_pos[0][1] = 0. ;
02095 }
02096 }
02097 else if ( j < k )
02098 {
02099 slit_pos[j][1] = (float)(box_buffer->n_elements - 1) - pos
02100 + (float)edgeclean[j-1] - (float)margin ;
02101 if ( slit_pos[j][1] - (int) slit_pos[j][1] == 0.)
02102 {
02103 slit_pos[j][1] = 0. ;
02104 }
02105 }
02106 else
02107 {
02108 last_pos = (float)(edgeclean[k-1] - 1 + slit_length) ;
02109 slit_pos[k][1] = (float)(box_buffer->n_elements - 1) - pos
02110 + (float)edgeclean[k-1] - (float)margin ;
02111 if ( slit_pos[k][1] - (int) slit_pos[k][1] == 0.)
02112 {
02113 slit_pos[k][1] = 0. ;
02114 }
02115 }
02116 }
02117
02118 sinfo_new_destroy_vector ( half_buffer ) ;
02119 cpl_free( xdat ) ;
02120 cpl_free( wdat ) ;
02121 cpl_free( mpar ) ;
02122 }
02123 sinfo_new_destroy_vector ( box_buffer ) ;
02124 }
02125
02126 cpl_free( sinfo_edge ) ;
02127 cpl_free( pos_row ) ;
02128 cpl_free( edgeclean ) ;
02129 cpl_free( dummyedge ) ;
02130 cpl_free( pos_rowclean ) ;
02131 cpl_free( position );
02132 return 0 ;
02133 }
02134
02163 int
02164 sinfo_new_fit_slits_boltz_with_estimate ( cpl_image * lineImage,
02165 float ** slit_pos,
02166 int box_length,
02167 float y_box,
02168 float diff_tol,
02169 int low_pos,
02170 int high_pos )
02171 {
02172 int* position=NULL ;
02173 Vector * box_buffer ;
02174 Vector * in_buffer ;
02175 int found_row ;
02176 int row, col ;
02177 int col_first, col_last ;
02178 int row_first, row_last ;
02179 int i, j, m, n ;
02180 int init1 ;
02181 int left_right ;
02182 int n_buf, shift ;
02183 int slit_length ;
02184 int iters, xdim, ndat ;
02185 int numpar, its ;
02186 int * mpar ;
02187 float * xdat, * wdat ;
02188 float tol, lab ;
02189 float fitpar[NPAR] ;
02190 float dervpar[NPAR] ;
02191 float minval, maxval ;
02192 float pos ;
02193 float new_pos ;
02194 int slitposition[SLITLENGTH] ;
02195 pixelvalue rowpos[SLITLENGTH] ;
02196
02197 int ilx=0;
02198 int ily=0;
02199 float* pidata=NULL;
02200
02201 slit_length = SLITLENGTH ;
02202 slit_length = N_SLITLETS ;
02203
02204 if ( NULL == lineImage )
02205 {
02206 sinfo_msg_error(" no line image given!" ) ;
02207 return -1 ;
02208 }
02209
02210 if ( NULL == slit_pos )
02211 {
02212 sinfo_msg_error(" no position array allocated!" ) ;
02213 return -1 ;
02214 }
02215
02216 if ( box_length < 4 ||
02217 box_length > 2*slit_length )
02218 {
02219 sinfo_msg_error(" wrong fitting box length given!" ) ;
02220 return -1 ;
02221 }
02222
02223 if ( y_box <= 0. || y_box > 6. )
02224 {
02225 sinfo_msg_error(" wrong y box length given!" ) ;
02226 return -1 ;
02227 }
02228 if ( diff_tol <= 0. )
02229 {
02230 sinfo_msg_error(" wrong diff_tol given!" ) ;
02231 return -1 ;
02232 }
02233
02234 ilx=cpl_image_get_size_x(lineImage);
02235 ily=cpl_image_get_size_y(lineImage);
02236 pidata=cpl_image_get_data_float(lineImage);
02237
02238 if ( low_pos >= high_pos || low_pos < 0 ||
02239 high_pos <= 0 || high_pos > ily )
02240 {
02241 sinfo_msg_error(" wrong user given search positions!" ) ;
02242 return -1 ;
02243 }
02244
02245
02246 position=cpl_calloc(ilx,sizeof(int)) ;
02247 for ( col = 0 ; col < ilx ; col++ )
02248 {
02249 found_row = -1 ;
02250 maxval = -FLT_MAX ;
02251 for ( row = low_pos ; row <= high_pos ; row++ )
02252 {
02253 if ( maxval < pidata[col+row*ilx] )
02254 {
02255 maxval = pidata[col+row*ilx] ;
02256 found_row = row ;
02257 }
02258 }
02259 if ( maxval > -FLT_MAX && found_row > low_pos )
02260 {
02261 position[col] = found_row ;
02262 }
02263 else
02264 {
02265 position[col] = 0 ;
02266 }
02267 }
02268
02269
02270
02271
02272
02273
02274 for ( j = 0 ; j < slit_length ; j++ )
02275 {
02276
02277
02278
02279 n = 0 ;
02280
02281 for ( col = sinfo_new_nint(slit_pos[j][0])+ 1 ;
02282 col < sinfo_new_nint(slit_pos[j][1]) -1 ; col++ )
02283 {
02284 rowpos[n] = (pixelvalue)position[col] ;
02285 n++ ;
02286 }
02287
02288 slitposition[j] = (int)sinfo_new_median(rowpos, n) ;
02289 for ( left_right = 0 ; left_right <= 1 ; left_right++ )
02290 {
02291 init1 = 0 ;
02292 col_first = sinfo_new_nint( slit_pos[j][left_right] ) -
02293 box_length/2 ;
02294 col_last = sinfo_new_nint( slit_pos[j][left_right] ) +
02295 box_length/2 ;
02296 if ( col_first < 0 )
02297 {
02298 col_first = 0 ;
02299 init1 = 1 ;
02300 }
02301 if ( col_last > ilx )
02302 {
02303 col_last = ilx ;
02304 init1 = 1 ;
02305 }
02306 if ( col_last - col_first <= 0 )
02307 {
02308 sinfo_msg_error(" first and last column wrong!" ) ;
02309 return -1 ;
02310 }
02311 box_buffer = sinfo_new_vector( col_last - col_first ) ;
02312 m = 0 ;
02313
02314
02315 if ( left_right == 0 )
02316 {
02317 for( col = col_first ; col < col_last ; col++ )
02318 {
02319 row_first = slitposition[j] - sinfo_new_nint(y_box) ;
02320 row_last = slitposition[j] + sinfo_new_nint(y_box) ;
02321 if ( row_first < 0 )
02322 {
02323 row_first = 0 ;
02324 }
02325 if ( row_last >= ily )
02326 {
02327 row_last = ily - 1 ;
02328 }
02329 maxval = -FLT_MAX ;
02330 for ( row = row_first ; row <= row_last ; row++ )
02331 {
02332 if ( maxval < pidata[col + ilx*row] )
02333 {
02334 maxval = pidata[col + ilx*row] ;
02335 }
02336 }
02337 box_buffer->data[m] = maxval ;
02338 m++ ;
02339 }
02340
02341 }
02342 else
02343 {
02344
02345 for( col = col_last-1 ; col >= col_first ; col-- )
02346 {
02347 row_first = slitposition[j] - sinfo_new_nint(y_box) ;
02348 row_last = slitposition[j] + sinfo_new_nint(y_box) ;
02349 if ( row_first < 0 )
02350 {
02351 row_first = 0 ;
02352 }
02353 if ( row_last >= ily )
02354 {
02355 row_last = ily - 1 ;
02356 }
02357 maxval = -FLT_MAX ;
02358 for ( row = row_first ; row <= row_last ; row++ )
02359 {
02360 if ( maxval < pidata[col + ilx*row] )
02361 {
02362 maxval = pidata[col + ilx*row] ;
02363 }
02364 }
02365 box_buffer->data[m] = maxval ;
02366 m++ ;
02367 }
02368
02369 }
02370
02371 xdat=(float *) cpl_calloc(box_buffer->n_elements, sizeof (float) );
02372 wdat=(float *) cpl_calloc(box_buffer->n_elements, sizeof (float) );
02373 mpar=(int *) cpl_calloc(NPAR, sizeof (int) ) ;
02374
02375
02376 minval = FLT_MAX ;
02377 maxval = -FLT_MAX ;
02378
02379 for ( i = 0 ; i < box_buffer->n_elements ; i++ )
02380 {
02381 xdat[i] = i ;
02382 wdat[i] = 1.0 ;
02383 if ( box_buffer -> data[i] < minval )
02384 {
02385 minval = box_buffer -> data[i] ;
02386 }
02387 if ( box_buffer -> data[i] > maxval )
02388 {
02389 maxval = box_buffer -> data[i] ;
02390 }
02391 }
02392 fitpar[0] = minval ;
02393 fitpar[1] = maxval ;
02394
02395
02396
02397
02398
02399
02400
02401
02402 if ( init1 == 1 )
02403 {
02404 n_buf = box_buffer->n_elements + box_length/2 ;
02405 in_buffer = sinfo_new_vector( n_buf ) ;
02406 for ( i = 0 ; i < box_length/2 ; i++ )
02407 {
02408 in_buffer -> data[i] = minval ;
02409 }
02410 shift = 0 ;
02411 for ( i = box_length/2 ; i < n_buf ; i++ )
02412 {
02413 in_buffer -> data[i] = box_buffer -> data[shift] ;
02414 shift++ ;
02415 }
02416 sinfo_new_destroy_vector ( box_buffer ) ;
02417 box_buffer = sinfo_new_vector ( n_buf ) ;
02418 for ( i = 0 ; i < n_buf ; i++ )
02419 {
02420 box_buffer -> data[i] = in_buffer -> data[i] ;
02421 }
02422 sinfo_new_destroy_vector ( in_buffer ) ;
02423 }
02424
02425
02426 fitpar[2] = (float)box_buffer->n_elements/2. ;
02427 fitpar[3] = 1. ;
02428
02429 for ( i = 0 ; i < NPAR ; i++ )
02430 {
02431 mpar[i] = 1 ;
02432 dervpar[i] = 0. ;
02433 }
02434
02435 xdim = XDIMA ;
02436 ndat = box_buffer->n_elements ;
02437 numpar = NPAR ;
02438 tol = TOLA ;
02439 lab = LABA ;
02440 its = ITSA ;
02441
02442
02443 if ( 0 > ( iters = sinfo_new_lsqfit( xdat, &xdim,
02444 box_buffer -> data,
02445 wdat, &ndat, fitpar,
02446 dervpar, mpar, &numpar,
02447 &tol, &its, &lab )) )
02448 {
02449 sinfo_msg_warning ("least squares fit failed, error "
02450 "no.: %d in slitlet: %d\n", iters, j) ;
02451 sinfo_new_destroy_vector(box_buffer) ;
02452 cpl_free( xdat ) ;
02453 cpl_free( wdat ) ;
02454 cpl_free( mpar ) ;
02455 continue ;
02456 }
02457
02458 if ( fitpar[3] <=0. )
02459 {
02460 sinfo_msg_warning ("fit failed due to negative width of "
02461 "boltzmann function in slitlet: %d\n", j) ;
02462 sinfo_new_destroy_vector(box_buffer) ;
02463 cpl_free( xdat ) ;
02464 cpl_free( wdat ) ;
02465 cpl_free( mpar ) ;
02466 continue ;
02467 }
02468 pos = fitpar[2] ;
02469 if ( init1 == 1 )
02470 {
02471 pos -= (float)box_length/2. ;
02472 }
02473
02474
02475
02476
02477
02478
02479 if ( pos != 0. )
02480 {
02481 if ( left_right == 0 )
02482 {
02483 new_pos = (float)col_first + pos ;
02484 }
02485 else
02486 {
02487 new_pos = (float)col_last-1 - pos ;
02488 }
02489 if ( fabs(new_pos - slit_pos[j][left_right]) < diff_tol )
02490 {
02491 slit_pos[j][left_right] = new_pos ;
02492 }
02493 else
02494 {
02495 sinfo_msg_warning (" deviation bigger than tolerance,"
02496 " take the estimated slitlet position "
02497 " in slitlet: %d\n", j) ;
02498 }
02499 }
02500
02501 cpl_free( xdat ) ;
02502 cpl_free( wdat ) ;
02503 cpl_free( mpar ) ;
02504 sinfo_new_destroy_vector ( box_buffer ) ;
02505
02506 }
02507 }
02508 cpl_free(position);
02509 return 0 ;
02510 }
02511
02512