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
00029
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 #ifdef HAVE_CONFIG_H
00145 # include <config.h>
00146 #endif
00147 #include "sinfo_vltPort.h"
00148
00149
00150
00151
00152
00153
00154
00155
00156 #include "sinfo_absolute.h"
00157 #include "sinfo_recipes.h"
00158
00159
00160
00161 static float sqrarg ;
00162 #define SQR(a) (sqrarg = (a) , sqrarg*sqrarg)
00163
00164 #define XDIMA 1
00165 #define TOLA 0.001
00166 #define LABA 0.1
00167 #define ITSA 200
00168 #define LABFACA 10.0
00169 #define LABMAXA 1.0e+10
00170 #define LABMINA 1.0e-10
00171 #define NPAR 4
00172
00173
00174
00175
00176
00177 static double chi1 ;
00178 static double chi2 ;
00179 static double labda ;
00180 static double vec[NPAR] ;
00181 static double matrix1[NPAR][NPAR] ;
00182 static double matrix2[NPAR][NPAR] ;
00183 static int nfree ;
00184 static int parptr[NPAR] ;
00185 static float slopewidth ;
00186
00187
00188
00189
00190
00191 static int sinfo_new_inv_mat_edge (void) ;
00192
00193 static void sinfo_new_get_mat_edge ( float * xdat,
00194 int * xdim,
00195 float * ydat,
00196 float * wdat,
00197 int * ndat,
00198 float * fpar,
00199 float * epar
00200 ) ;
00201
00202 static int sinfo_new_get_vec_edge ( float * xdat,
00203 int * xdim,
00204 float * ydat,
00205 float * wdat,
00206 int * ndat,
00207 float * fpar,
00208 float * epar,
00209 int * npar ) ;
00210 float
00211 sinfo_new_hat2 ( float * xdat, float * parlist );
00212
00213 float
00214 sinfo_new_hat1 ( float * xdat, float * parlist );
00215
00216 void
00217 sinfo_new_hat_deriv2(float * xdat, float * parlist,
00218 float * dervs );
00219
00220 void
00221 sinfo_new_hat_deriv1( float * xdat, float * parlist,
00222 float * dervs );
00223
00224 int
00225 sinfo_new_fit_slits1( cpl_image * lineImage,
00226 FitParams ** par,
00227 float ** sinfo_slit_pos,
00228 int box_length,
00229 float y_box );
00230
00231 int
00232 sinfo_new_fit_slits( cpl_image * lineImage,
00233 FitParams ** par,
00234 float ** sinfo_slit_pos,
00235 int box_length,
00236 float y_box,
00237 float slope_width );
00238
00239
00240
00241 int
00242 sinfo_new_fit_slits2( cpl_image * lineImage,
00243 FitParams ** par,
00244 float ** sinfo_slit_pos,
00245 int box_length,
00246 float y_box,
00247 float diff_tol );
00248
00249
00250
00251
00270 float
00271 sinfo_new_edge ( float * xdat, float * parlist )
00272 {
00273 float return_value ;
00274 float slope1 ;
00275
00276
00277 slope1 = ( parlist[3] - parlist[2] ) / ( parlist[1] - parlist[0] ) ;
00278
00279
00280 if ( xdat[0] <= parlist[0] )
00281 {
00282 return_value = parlist[2] ;
00283 }
00284 else if ( xdat[0] > parlist[0] && xdat[0] <= parlist[1] )
00285 {
00286 return_value = (xdat[0] - parlist[0]) * slope1 + parlist[2] ;
00287 }
00288 else if ( xdat[0] > parlist[1] )
00289 {
00290 return_value = parlist[3] ;
00291 }
00292 else
00293 {
00294 return_value = 0. ;
00295 }
00296
00297 return return_value ;
00298 }
00299
00329 float
00330 sinfo_new_hat2 ( float * xdat, float * parlist )
00331 {
00332 float return_value ;
00333 float slope1, slope2, slope3 ;
00334
00335
00336 slope1 = ( parlist[6] - parlist[4] ) / ( parlist[1] - parlist[0] ) ;
00337 slope2 = ( parlist[7] - parlist[5] ) / ( parlist[3] - parlist[2] ) ;
00338 slope3 = ( parlist[7] - parlist[6] ) / ( parlist[2] - parlist[1] ) ;
00339
00340
00341 if ( xdat[0] <= parlist[0] )
00342 {
00343 return_value = parlist[4] ;
00344 }
00345 else if ( xdat[0] > parlist[0] && xdat[0] <= parlist[1] )
00346 {
00347 return_value = (xdat[0] - parlist[0]) * slope1 + parlist[4] ;
00348 }
00349 else if ( xdat[0] > parlist[1] && xdat[0] <= parlist[2] )
00350 {
00351 return_value = (xdat[0] - parlist[1]) * slope3 + parlist[6] ;
00352 }
00353 else if ( xdat[0] > parlist[2] && xdat[0] <= parlist[3] )
00354 {
00355 return_value = (parlist[3] - xdat[0]) * slope2 + parlist[5] ;
00356 }
00357 else if ( xdat[0] > parlist[3] )
00358 {
00359 return_value = parlist[5] ;
00360 }
00361 else
00362 {
00363 return_value = 0. ;
00364 }
00365
00366 return return_value ;
00367 }
00368
00369
00399 float
00400 sinfo_new_hat1 ( float * xdat, float * parlist )
00401 {
00402 float return_value=0 ;
00403 float slope1, slope2 ;
00404
00405
00406
00407
00408 slope1 = (parlist[4] - parlist[2]) / slopewidth ;
00409 slope2 = (parlist[4] - parlist[3]) / slopewidth ;
00410
00411
00412 if ( xdat[0] <= parlist[0] )
00413 {
00414 return_value = parlist[2] ;
00415 }
00416 else if ( xdat[0] > parlist[0] && xdat[0] <= parlist[0] + slopewidth )
00417 {
00418 return_value = (xdat[0] - parlist[0]) * slope1 + parlist[2] ;
00419 }
00420 else if ( xdat[0] > parlist[0] + slopewidth &&
00421 xdat[0] <= parlist[1] - slopewidth )
00422 {
00423 return_value = parlist[4] ;
00424 }
00425 else if ( xdat[0] > parlist[1] - slopewidth && xdat[0] <= parlist[1] )
00426 {
00427 return_value = (parlist[1] - xdat[0]) * slope2 + parlist[3] ;
00428 }
00429 else if ( xdat[0] > parlist[1] )
00430 {
00431 return_value = parlist[3] ;
00432 }
00433
00434 return return_value ;
00435 }
00436
00437
00464 void
00465 sinfo_new_edge_deriv( float * xdat, float * parlist,
00466 float * dervs )
00467 {
00468 float deriv1_slope1 ;
00469
00470
00471 deriv1_slope1 =( parlist[3] - parlist[2] ) / SQR(parlist[1] - parlist[0]) ;
00472
00473
00474 if ( xdat[0] <= parlist[0] )
00475 {
00476 dervs[0] = 0. ;
00477 dervs[1] = 0. ;
00478 dervs[2] = 1. ;
00479 dervs[3] = 0. ;
00480 }
00481 else if ( xdat[0] > parlist[0] && xdat[0] <= parlist[1] )
00482 {
00483 dervs[0] = ( xdat[0] - parlist[1] ) * deriv1_slope1 ;
00484 dervs[1] = ( parlist[0] - xdat[0] ) * deriv1_slope1 ;
00485 dervs[2] = ( parlist[0] - xdat[0] ) / ( parlist[1] - parlist[0] ) + 1.;
00486 dervs[3] = ( xdat[0] - parlist[0] ) / ( parlist[1] - parlist[0] ) ;
00487 }
00488 else if ( xdat[0] > parlist[1] )
00489 {
00490 dervs[0] = 0. ;
00491 dervs[1] = 0. ;
00492 dervs[2] = 0. ;
00493 dervs[3] = 1. ;
00494 }
00495 }
00530 void
00531 sinfo_new_hat_deriv2(float * xdat, float * parlist,
00532 float * dervs )
00533 {
00534 float deriv1_slope1 ;
00535 float deriv1_slope2 ;
00536 float deriv1_slope3 ;
00537
00538
00539 deriv1_slope1 = ( parlist[6] - parlist[4] ) / SQR(parlist[1] - parlist[0]);
00540 deriv1_slope2 = ( parlist[7] - parlist[5] ) / SQR(parlist[3] - parlist[2]);
00541 deriv1_slope3 = ( parlist[7] - parlist[6] ) / SQR(parlist[2] - parlist[1]);
00542
00543
00544 if ( xdat[0] <= parlist[0] )
00545 {
00546 dervs[0] = 0. ;
00547 dervs[1] = 0. ;
00548 dervs[2] = 0. ;
00549 dervs[3] = 0. ;
00550 dervs[4] = 1. ;
00551 dervs[5] = 0. ;
00552 dervs[6] = 0. ;
00553 dervs[7] = 0. ;
00554 }
00555 else if ( xdat[0] > parlist[0] && xdat[0] <= parlist[1] )
00556 {
00557 dervs[0] = ( xdat[0] - parlist[1] ) * deriv1_slope1 ;
00558 dervs[1] = ( parlist[0] - xdat[0] ) * deriv1_slope1 ;
00559 dervs[2] = 0. ;
00560 dervs[3] = 0. ;
00561 dervs[4] = ( parlist[0] - xdat[0] ) / ( parlist[1] - parlist[0] ) + 1.;
00562 dervs[5] = 0. ;
00563 dervs[6] = ( xdat[0] - parlist[0] ) / ( parlist[1] - parlist[0] ) ;
00564 dervs[7] = 0. ;
00565 }
00566 else if ( xdat[0] > parlist[1] && xdat[0] <= parlist[2] )
00567 {
00568 dervs[0] = 0. ;
00569 dervs[1] = (xdat[0] - parlist[2]) * deriv1_slope3 ;
00570 dervs[2] = (parlist[1] - xdat[0]) * deriv1_slope3 ;
00571 dervs[3] = 0. ;
00572 dervs[4] = 0. ;
00573 dervs[5] = 0. ;
00574 dervs[6] = (parlist[1] - xdat[0]) / (parlist[2] - parlist[1]) + 1. ;
00575 dervs[7] = (xdat[0] - parlist[1]) / (parlist[2] - parlist[1]) ;
00576 }
00577 else if ( xdat[0] > parlist[2] && xdat[0] <= parlist[3] )
00578 {
00579 dervs[0] = 0. ;
00580 dervs[1] = 0. ;
00581 dervs[2] = ( parlist[3] - xdat[0] ) * deriv1_slope2 ;
00582 dervs[3] = ( xdat[0] - parlist[2] ) * deriv1_slope2 ;
00583 dervs[4] = 0. ;
00584 dervs[5] = ( xdat[0] - parlist[3] ) / ( parlist[3] - parlist[2] ) + 1.;
00585 dervs[6] = 0. ;
00586 dervs[7] = ( parlist[3] - xdat[0] ) / ( parlist[3] - parlist[2] ) ;
00587 }
00588 else if ( xdat[0] > parlist[3] )
00589 {
00590 dervs[0] = 0. ;
00591 dervs[1] = 0. ;
00592 dervs[2] = 0. ;
00593 dervs[3] = 0. ;
00594 dervs[4] = 0. ;
00595 dervs[5] = 1. ;
00596 dervs[6] = 0. ;
00597 dervs[7] = 0. ;
00598 }
00599 }
00600
00629 void
00630 sinfo_new_hat_deriv1( float * xdat, float * parlist,
00631 float * dervs )
00632 {
00633
00634 if ( xdat[0] <= parlist[0] )
00635 {
00636 dervs[0] = 0. ;
00637 dervs[1] = 0. ;
00638 dervs[2] = 1. ;
00639 dervs[3] = 0. ;
00640 dervs[4] = 0. ;
00641 }
00642 else if ( xdat[0] > parlist[0] && xdat[0] <= parlist[0] + slopewidth )
00643 {
00644 dervs[0] = ( parlist[2] - parlist[4] ) / slopewidth ;
00645 dervs[1] = 0. ;
00646 dervs[2] = (( parlist[0] - xdat[0] ) / slopewidth ) + 1. ;
00647 dervs[3] = 0. ;
00648 dervs[4] = ( xdat[0] - parlist[0] ) / slopewidth ;
00649 }
00650 else if ( xdat[0] > parlist[0] + slopewidth && xdat[0] <=
00651 parlist[1] - slopewidth )
00652 {
00653 dervs[0] = 0. ;
00654 dervs[1] = 0. ;
00655 dervs[2] = 0. ;
00656 dervs[3] = 0. ;
00657 dervs[4] = 1. ;
00658 }
00659 else if ( xdat[0] > parlist[1] - slopewidth && xdat[0] <= parlist[1] )
00660 {
00661 dervs[0] = 0. ;
00662 dervs[1] = ( parlist[4] - parlist[3] ) / slopewidth ;
00663 dervs[2] = 0. ;
00664 dervs[3] = (( xdat[0] - parlist[1] ) / slopewidth ) + 1. ;
00665 dervs[4] = ( parlist[1] - xdat[0] ) / slopewidth ;
00666 }
00667 else if ( xdat[0] > parlist[1] )
00668 {
00669 dervs[0] = 0. ;
00670 dervs[1] = 0. ;
00671 dervs[2] = 0. ;
00672 dervs[3] = 1. ;
00673 dervs[4] = 0. ;
00674 }
00675 }
00676
00688 static int
00689 sinfo_new_inv_mat_edge (void)
00690 {
00691 double even ;
00692 double hv[NPAR] ;
00693 double mjk ;
00694 double rowmax ;
00695 int evin ;
00696 int i, j, k, row ;
00697 int per[NPAR] ;
00698
00699
00700 for ( i = 0 ; i < nfree ; i++ )
00701 {
00702 per[i] = i ;
00703 }
00704
00705 for ( j = 0 ; j < nfree ; j++ )
00706 {
00707
00708 rowmax = fabs ( matrix2[j][j] ) ;
00709 row = j ;
00710
00711 for ( i = j + 1 ; i < nfree ; i++ )
00712 {
00713 if ( fabs ( matrix2[i][j] ) > rowmax )
00714 {
00715 rowmax = fabs( matrix2[i][j] ) ;
00716 row = i ;
00717 }
00718 }
00719
00720
00721 if ( matrix2[row][j] == 0.0 )
00722 {
00723 return -6 ;
00724 }
00725
00726
00727 if ( row > j )
00728 {
00729 for ( k = 0 ; k < nfree ; k++ )
00730 {
00731 even = matrix2[j][k] ;
00732 matrix2[j][k] = matrix2[row][k] ;
00733 matrix2[row][k] = even ;
00734 }
00735
00736 evin = per[j] ;
00737 per[j] = per[row] ;
00738 per[row] = evin ;
00739 }
00740
00741
00742 even = 1.0 / matrix2[j][j] ;
00743 for ( i = 0 ; i < nfree ; i++ )
00744 {
00745 matrix2[i][j] *= even ;
00746 }
00747 matrix2[j][j] = even ;
00748
00749 for ( k = 0 ; k < j ; k++ )
00750 {
00751 mjk = matrix2[j][k] ;
00752 for ( i = 0 ; i < j ; i++ )
00753 {
00754 matrix2[i][k] -= matrix2[i][j] * mjk ;
00755 }
00756 for ( i = j + 1 ; i < nfree ; i++ )
00757 {
00758 matrix2[i][k] -= matrix2[i][j] * mjk ;
00759 }
00760 matrix2[j][k] = -even * mjk ;
00761 }
00762
00763 for ( k = j + 1 ; k < nfree ; k++ )
00764 {
00765 mjk = matrix2[j][k] ;
00766 for ( i = 0 ; i < j ; i++ )
00767 {
00768 matrix2[i][k] -= matrix2[i][j] * mjk ;
00769 }
00770 for ( i = j + 1 ; i < nfree ; i++ )
00771 {
00772 matrix2[i][k] -= matrix2[i][j] * mjk ;
00773 }
00774 matrix2[j][k] = -even * mjk ;
00775 }
00776 }
00777
00778
00779 for ( i = 0 ; i < nfree ; i++ )
00780 {
00781 for ( k = 0 ; k < nfree ; k++ )
00782 {
00783 hv[per[k]] = matrix2[i][k] ;
00784 }
00785 for ( k = 0 ; k < nfree ; k++ )
00786 {
00787 matrix2[i][k] = hv[k] ;
00788 }
00789 }
00790
00791
00792 return 0 ;
00793 }
00794
00813 static void
00814 sinfo_new_get_mat_edge ( float * xdat,
00815 int * xdim,
00816 float * ydat,
00817 float * wdat,
00818 int * ndat,
00819 float * fpar,
00820 float * epar
00821 )
00822 {
00823 double wd ;
00824 double wn ;
00825 double yd ;
00826 int i, j, n ;
00827
00828 for ( j = 0 ; j < nfree ; j++ )
00829 {
00830 vec[j] = 0.0 ;
00831 for ( i = 0 ; i<= j ; i++ )
00832
00833 {
00834 matrix1[j][i] = 0.0 ;
00835 }
00836 }
00837 chi2 = 0.0 ;
00838
00839
00840 for ( n = 0 ; n < (*ndat) ; n++ )
00841 {
00842 wn = wdat[n] ;
00843 if ( wn > 0.0 )
00844 {
00845 yd = ydat[n] - sinfo_new_edge( &xdat[(*xdim) * n],
00846 fpar ) ;
00847 sinfo_new_edge_deriv( &xdat[(*xdim) * n], fpar, epar) ;
00848 chi2 += yd * yd * wn ;
00849 for ( j = 0 ; j < nfree ; j++ )
00850 {
00851 wd = epar[parptr[j]] * wn ;
00852 vec[j] += yd * wd ;
00853 for ( i = 0 ; i <= j ; i++ )
00854 {
00855 matrix1[j][i] += epar[parptr[i]] * wd ;
00856 }
00857 }
00858 }
00859 }
00860 }
00861
00862
00863
00893 static int
00894 sinfo_new_get_vec_edge ( float * xdat,
00895 int * xdim,
00896 float * ydat,
00897 float * wdat,
00898 int * ndat,
00899 float * fpar,
00900 float * epar,
00901 int * npar )
00902 {
00903 double dj ;
00904 double dy ;
00905 double mii ;
00906 double mji ;
00907 double mjj ;
00908 double wn ;
00909 int i, j, n, r ;
00910
00911
00912 for ( j = 0 ; j < nfree ; j++ )
00913 {
00914 mjj = matrix1[j][j] ;
00915 if ( mjj <= 0.0 )
00916 {
00917 return -5 ;
00918 }
00919 mjj = sqrt( mjj ) ;
00920 for ( i = 0 ; i < j ; i++ )
00921 {
00922 mji = matrix1[j][i] / mjj / sqrt( matrix1[i][i] ) ;
00923 matrix2[i][j] = matrix2[j][i] = mji ;
00924 }
00925 matrix2[j][j] = 1.0 + labda ;
00926 }
00927
00928 if ( (r = sinfo_new_inv_mat_edge()) )
00929 {
00930 return r ;
00931 }
00932
00933 for ( i = 0 ; i < (*npar) ; i ++ )
00934 {
00935 epar[i] = fpar[i] ;
00936 }
00937
00938
00939 for ( j = 0 ; j < nfree ; j++ )
00940 {
00941 dj = 0.0 ;
00942 mjj = matrix1[j][j] ;
00943 if ( mjj <= 0.0)
00944 {
00945 return -7 ;
00946 }
00947 mjj = sqrt ( mjj ) ;
00948 for ( i = 0 ; i < nfree ; i++ )
00949 {
00950 mii = matrix1[i][i] ;
00951 if ( mii <= 0.0 )
00952 {
00953 return -7 ;
00954 }
00955 mii = sqrt( mii ) ;
00956 dj += vec[i] * matrix2[j][i] / mjj / mii ;
00957 }
00958 epar[parptr[j]] += dj ;
00959 }
00960 chi1 = 0.0 ;
00961
00962
00963 for ( n = 0 ; n < (*ndat) ; n++ )
00964 {
00965 wn = wdat[n] ;
00966 if ( wn > 0.0 )
00967 {
00968 dy = ydat[n] - sinfo_new_edge( &xdat[(*xdim) * n], epar
00969 ) ;
00970 chi1 += wdat[n] * dy * dy ;
00971 }
00972 }
00973 return 0 ;
00974 }
00975
00976
01030 int
01031 sinfo_new_lsqfit_edge ( float * xdat,
01032 int * xdim,
01033 float * ydat,
01034 float * wdat,
01035 int * ndat,
01036 float * fpar,
01037 float * epar,
01038 int * mpar,
01039 int * npar,
01040 float * tol ,
01041 int * its ,
01042 float * lab )
01043 {
01044 int i, n, r ;
01045 int itc ;
01046 int found ;
01047 int nuse ;
01048 double tolerance ;
01049
01050 itc = 0 ;
01051 found = 0 ;
01052 nfree = 0 ;
01053 nuse = 0 ;
01054
01055 if ( *tol < (FLT_EPSILON * 10.0 ) )
01056 {
01057 tolerance = FLT_EPSILON * 10.0 ;
01058 }
01059 else
01060 {
01061 tolerance = *tol ;
01062 }
01063
01064 labda = fabs( *lab ) * LABFACA ;
01065 for ( i = 0 ; i < (*npar) ; i++ )
01066 {
01067 if ( mpar[i] )
01068 {
01069 if ( nfree > NPAR )
01070 {
01071 return -1 ;
01072 }
01073 parptr[nfree++] = i ;
01074 }
01075 }
01076
01077 if (nfree == 0)
01078 {
01079 return -2 ;
01080 }
01081
01082 for ( n = 0 ; n < (*ndat) ; n++ )
01083 {
01084 if ( wdat[n] > 0.0 )
01085 {
01086 nuse ++ ;
01087 }
01088 }
01089
01090 if ( nfree >= nuse )
01091 {
01092 return -3 ;
01093 }
01094 if ( labda == 0.0 )
01095 {
01096
01097 for ( i = 0 ; i < nfree ; fpar[parptr[i++]] = 0.0 ) ;
01098 sinfo_new_get_mat_edge(xdat,xdim,ydat,wdat,ndat,fpar,epar) ;
01099 r = sinfo_new_get_vec_edge ( xdat, xdim, ydat, wdat, ndat,
01100 fpar, epar, npar ) ;
01101 if ( r )
01102 {
01103 return r ;
01104 }
01105 for ( i = 0 ; i < (*npar) ; i++ )
01106 {
01107 fpar[i] = epar[i] ;
01108 epar[i] = 0.0 ;
01109 }
01110 chi1 = sqrt( chi1 / (double) (nuse - nfree) ) ;
01111 for ( i = 0 ; i < nfree ; i++ )
01112 {
01113 if ( (matrix1[i][i] <= 0.0 ) || (matrix2[i][i] <= 0.0) )
01114 {
01115 return -7 ;
01116 }
01117 epar[parptr[i]] = chi1 * sqrt( matrix2[i][i] ) /
01118 sqrt( matrix1[i][i] ) ;
01119 }
01120 }
01121 else
01122 {
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137 while ( !found )
01138 {
01139 if ( itc++ == (*its) )
01140 {
01141 return -4 ;
01142 }
01143 sinfo_new_get_mat_edge( xdat, xdim, ydat, wdat, ndat,
01144 fpar, epar ) ;
01145
01146
01147
01148
01149
01150 if ( labda > LABMINA )
01151 {
01152 labda = labda / LABFACA ;
01153 }
01154 r = sinfo_new_get_vec_edge ( xdat, xdim, ydat, wdat, ndat,
01155 fpar, epar, npar ) ;
01156 if ( (int)fpar[1] - (int)fpar[0] <= 0 && fpar[1] / fpar[0] > 0. )
01157 {
01158 fpar[1] += 1. ;
01159 continue ;
01160 }
01161 if ( r )
01162 {
01163 return r ;
01164 }
01165
01166 while ( chi1 >= chi2 )
01167 {
01168
01169
01170
01171
01172
01173
01174 if ( labda > LABMAXA )
01175 {
01176 break ;
01177 }
01178 labda = labda * LABFACA ;
01179 r = sinfo_new_get_vec_edge ( xdat, xdim, ydat, wdat,
01180 ndat, fpar, epar, npar ) ;
01181 if ( (int)fpar[1] - (int)fpar[0] <= 0 &&
01182 fpar[1] / fpar[0] > 0. )
01183 {
01184 fpar[1] += 1. ;
01185 continue ;
01186 }
01187 if ( r )
01188 {
01189 return r ;
01190 }
01191 }
01192
01193 if ( labda <= LABMAXA )
01194 {
01195 for ( i = 0 ; i < *npar ; i++ )
01196 {
01197 fpar[i] = epar[i] ;
01198 }
01199 }
01200 if ( (fabs( chi2 - chi1 ) <= (tolerance * chi1)) ||
01201 (labda > LABMAXA) )
01202 {
01203
01204
01205
01206
01207
01208
01209 labda = LABMINA ;
01210 sinfo_new_get_mat_edge ( xdat, xdim, ydat, wdat, ndat,
01211 fpar, epar) ;
01212 r = sinfo_new_get_vec_edge ( xdat, xdim, ydat, wdat,
01213 ndat, fpar, epar, npar ) ;
01214
01215 if ( r )
01216 {
01217 return r ;
01218 }
01219 for ( i = 0 ; i < (*npar) ; i++ )
01220 {
01221 epar[i] = 0.0 ;
01222 }
01223 chi2 = sqrt ( chi2 / (double) (nuse - nfree) ) ;
01224
01225 for ( i = 0 ; i < nfree ; i++ )
01226 {
01227 if ( (matrix1[i][i] <= 0.0) || (matrix2[i][i] <= 0.0) )
01228 {
01229 return -7 ;
01230 }
01231 epar[parptr[i]] = chi2 * sqrt( matrix2[i][i] ) /
01232 sqrt( matrix1[i][i] ) ;
01233 }
01234 found = 1 ;
01235 }
01236 }
01237 }
01238 return itc ;
01239 }
01268 int
01269 sinfo_new_fit_slits1( cpl_image * lineImage,
01270 FitParams ** par,
01271 float ** sinfo_slit_pos,
01272 int box_length,
01273 float y_box )
01274 {
01275 float* position=NULL ;
01276 int * sinfo_edge, * edgeclean ;
01277 int * dummyedge ;
01278 int * pos_row, * pos_rowclean ;
01279 Vector * box_buffer ;
01280 float max_intensity ;
01281 float row_pos ;
01282 int col ;
01283 int i, j, k, m, n, ed ;
01284 int found, init1, init2 ;
01285 int line ;
01286 int column ;
01287 int slit_length ;
01288 int agreed ;
01289 int bad_line ;
01290 int margin ;
01291 int iters, xdim, ndat ;
01292 int numpar, its ;
01293 int * mpar ;
01294 float * xdat, * wdat ;
01295 float tol, lab ;
01296 float fitpar[2*NPAR] ;
01297 float dervpar[NPAR] ;
01298 float minval, maxval ;
01299 int ilx=0;
01300 int ily=0;
01301 float* pidata=NULL;
01302
01303
01304 if ( NULL == lineImage )
01305 {
01306 sinfo_msg_error("no line image given!" ) ;
01307 return -1 ;
01308 }
01309 ilx=cpl_image_get_size_x(lineImage);
01310 ily=cpl_image_get_size_y(lineImage);
01311 pidata=cpl_image_get_data_float(lineImage);
01312
01313 slit_length = (int) sqrt (ilx) ;
01314 if ( NULL == par )
01315 {
01316 sinfo_msg_error("no line fit parameters given!") ;
01317 return -2 ;
01318 }
01319
01320 if ( NULL == sinfo_slit_pos )
01321 {
01322 sinfo_msg_error("no position array allocated!") ;
01323 return -3 ;
01324 }
01325
01326 if ( box_length < slit_length ||
01327 box_length >= 3*slit_length )
01328 {
01329 sinfo_msg_error("wrong fitting box length given!" ) ;
01330 return -4 ;
01331 }
01332
01333 if ( y_box <= 0. || y_box > 3. )
01334 {
01335 sinfo_msg_error("wrong y box length given!" ) ;
01336 return -5 ;
01337 }
01338
01339
01340 sinfo_edge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
01341 dummyedge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
01342 edgeclean = (int*) cpl_calloc( slit_length-1, sizeof(int) ) ;
01343 pos_row = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
01344 pos_rowclean = (int*) cpl_calloc( slit_length, sizeof(int) ) ;
01345
01346
01347
01348
01349
01350 agreed = -1 ;
01351 bad_line = -1 ;
01352 while( agreed == -1 )
01353 {
01354 found = -1 ;
01355 max_intensity = -FLT_MAX ;
01356 for ( col = 0 ; col < box_length ; col++ )
01357 {
01358 for ( i = 0 ; i < par[0]->n_params ; i++ )
01359 {
01360 if ( par[i]->column == col && par[i]->line != bad_line )
01361 {
01362 if ( par[i]->fit_par[0] > max_intensity )
01363 {
01364 if ( par[i]->fit_par[1] > 0. )
01365 {
01366 max_intensity = par[i]->fit_par[0] ;
01367 found = i ;
01368 }
01369 }
01370 }
01371 }
01372 }
01373
01374
01375
01376
01377
01378 line = par[found]->line ;
01379 column = par[found]->column ;
01380 row_pos = par[found]->fit_par[2] ;
01381 if ( found >= 0 && max_intensity > 0. )
01382 {
01383 for ( i = 0 ; i < par[0]->n_params ; i++ )
01384 {
01385 if ( par[i]->line == line-1 &&
01386 par[i]->column == column + slit_length )
01387 {
01388 if ( par[i]->fit_par[2] <= (row_pos + y_box) &&
01389 par[i]->fit_par[2] >= (row_pos - y_box) )
01390 {
01391 bad_line = line ;
01392 }
01393 }
01394 }
01395 if ( bad_line != line )
01396 {
01397 agreed = 1 ;
01398 break ;
01399 }
01400 }
01401 else
01402 {
01403 sinfo_msg_error("no emission line found in the first image columns");
01404 return -6 ;
01405 }
01406 }
01407
01408
01409 if ( agreed == -1 )
01410 {
01411 sinfo_msg_error("no emission line found in the first image columns") ;
01412 return -6 ;
01413 }
01414
01415
01416 n = 0 ;
01417 ed = 0 ;
01418
01419
01420 position=cpl_calloc(ilx,sizeof(float));
01421 for ( col = 0 ; col < ilx ; col++ )
01422 {
01423 for ( i = 0 ; i < par[0]->n_params ; i++ )
01424 {
01425 if ( par[i]->column == col && par[i] -> line == line )
01426 {
01427 if ( par[i]->fit_par[0] > 0. && par[i]->fit_par[1] > 0. )
01428 {
01429 position[n] = par[i]->fit_par[2] ;
01430 if ( n > 0 && fabs(position[n] - position[n-1]) > y_box )
01431 {
01432 sinfo_edge[ed] = col ;
01433 pos_row[ed] = sinfo_new_nint( position[n-1] ) ;
01434 ed++ ;
01435 if ( col >= ilx - slit_length - 5 )
01436 {
01437 pos_row[ed] = sinfo_new_nint( position[n] ) ;
01438 }
01439 }
01440 n++ ;
01441 }
01442 }
01443 }
01444 }
01445 if ( ed < (slit_length - 1) )
01446 {
01447 sinfo_msg_error("not enough slitlets found") ;
01448 return -7 ;
01449 }
01450
01451
01452 for ( i = 1 ; i <= ed ; i ++ )
01453 {
01454 if (dummyedge[i-1] != -1)
01455 {
01456 dummyedge[i-1] = sinfo_edge[i-1] ;
01457 }
01458 if ( (sinfo_edge[i] - sinfo_edge[i-1]) < slit_length - 3 ||
01459 (sinfo_edge[i] - sinfo_edge[i-1]) > slit_length + 3 )
01460 {
01461 dummyedge[i] = -1 ;
01462 }
01463 if ( (sinfo_edge[i+1] - sinfo_edge[i]) < slit_length - 3 ||
01464 (sinfo_edge[i+1] - sinfo_edge[i]) > slit_length + 3 )
01465 {
01466 dummyedge[i+1] = -1 ;
01467 }
01468 }
01469
01470 k = 0 ;
01471 for ( i = 0 ; i < ed ; i++ )
01472 {
01473 if ( dummyedge[i] != -1 && dummyedge[i] != 0 )
01474 {
01475 edgeclean[k] = dummyedge[i] ;
01476 pos_rowclean[k] = pos_row[i] ;
01477 k++ ;
01478 if( edgeclean[k-1] > (ilx - slit_length - 6 ) )
01479 {
01480 pos_rowclean[k] = pos_row[ed] ;
01481 }
01482 }
01483 }
01484
01485 if ( k != slit_length - 1 )
01486 {
01487 sinfo_msg_error("not enough clean slitlets found") ;
01488 return -7 ;
01489 }
01490
01491
01492 margin = ( box_length - slit_length ) / 2 ;
01493
01494
01495
01496 for ( j = 0 ; j < k ; j++ )
01497 {
01498 m = 0 ;
01499 if ( j == 0 )
01500 {
01501 box_buffer = sinfo_new_vector( edgeclean[0] + margin ) ;
01502 for( col = 0 ; col < edgeclean[0] + margin ; col++ )
01503 {
01504 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[0]] ;
01505 m++ ;
01506 }
01507 fitpar[0] = 3. ;
01508 fitpar[1] = 5. ;
01509 fitpar[2] = (float) edgeclean[0] - 1. ;
01510 fitpar[3] = (float) edgeclean[0] + 1. ;
01511
01512 }
01513 else if ( j < k - 1 )
01514 {
01515 box_buffer = sinfo_new_vector( edgeclean[j] -
01516 edgeclean[j-1] + 2*margin ) ;
01517 for ( col = edgeclean[j - 1] - margin ;
01518 col < edgeclean[j] + margin ; col++ )
01519 {
01520 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[j]] ;
01521 m++ ;
01522 }
01523 fitpar[0] = (float) margin - 1. ;
01524 fitpar[1] = (float) margin + 1. ;
01525 fitpar[2] = (float) (edgeclean[j] - edgeclean[j-1] + margin) - 1. ;
01526 fitpar[3] = (float) (edgeclean[j] - edgeclean[j-1] + margin) + 1. ;
01527 }
01528
01529 else
01530 {
01531 box_buffer = sinfo_new_vector( ilx - edgeclean[k-1] + margin ) ;
01532 for ( col = edgeclean[k - 1] - margin ; col < ilx ; col++ )
01533 {
01534 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[k]] ;
01535 m++ ;
01536 }
01537 fitpar[0] = (float) margin - 1. ;
01538 fitpar[1] = (float) margin + 1. ;
01539 fitpar[2] = (float) (ilx - edgeclean[k-1] + margin) - 3. ;
01540 fitpar[3] = (float) (ilx - edgeclean[k-1] + margin) - 1. ;
01541 }
01542
01543 xdat = (float *) cpl_calloc(box_buffer -> n_elements,sizeof (float) ) ;
01544 wdat = (float *) cpl_calloc(box_buffer -> n_elements,sizeof (float) ) ;
01545 mpar = (int *) cpl_calloc(NPAR, sizeof (int) ) ;
01546
01547
01548 minval = FLT_MAX ;
01549 maxval = -FLT_MAX ;
01550 for ( i = 0 ; i < box_buffer->n_elements ; i++ )
01551 {
01552 xdat[i] = i ;
01553 wdat[i] = 1.0 ;
01554 if ( box_buffer -> data[i] < minval )
01555 {
01556 minval = box_buffer -> data[i] ;
01557 }
01558 if ( box_buffer -> data[i] > maxval )
01559 {
01560 maxval = box_buffer -> data[i] ;
01561 }
01562 }
01563
01564 fitpar[4] = minval ;
01565 fitpar[5] = minval ;
01566 fitpar[6] = maxval ;
01567 fitpar[7] = maxval ;
01568
01569
01570
01571 init1 = -1 ;
01572 init2 = -1 ;
01573 for ( i = 0 ; i < box_buffer->n_elements ; i++ )
01574 {
01575 if ( box_buffer -> data[i] >= ( maxval - minval ) / 2. )
01576 {
01577 init1 = i ;
01578 break ;
01579 }
01580 }
01581
01582 for ( i = box_buffer->n_elements - 1 ; i >= 0 ; i-- )
01583 {
01584 if ( box_buffer -> data[i] >= ( maxval + minval ) / 2. )
01585 {
01586 init2 = i ;
01587 break ;
01588 }
01589 }
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603 for ( i = 0 ; i < NPAR ; i++ )
01604 {
01605 mpar[i] = 1 ;
01606 dervpar[i] = 0. ;
01607 }
01608
01609 xdim = XDIMA ;
01610 ndat = box_buffer -> n_elements ;
01611 numpar = NPAR ;
01612 tol = TOLA ;
01613 lab = LABA ;
01614 its = ITSA ;
01615
01616
01617 if ( 0 > ( iters = sinfo_new_lsqfit_edge( xdat, &xdim,
01618 box_buffer -> data,
01619 wdat, &ndat, fitpar,
01620 dervpar, mpar,
01621 &numpar, &tol,
01622 &its, &lab )) )
01623 {
01624 sinfo_msg_warning("least squares fit failed, error no.: %d",
01625 iters) ;
01626 return -8 ;
01627 }
01628
01629
01630
01631
01632 if ( j == 0 )
01633 {
01634 sinfo_slit_pos[0][0] = (fitpar[0] + fitpar[1]) / 2. ;
01635 sinfo_slit_pos[0][1] = (fitpar[2] + fitpar[3]) / 2. ;
01636 }
01637 else
01638 {
01639 sinfo_slit_pos[j][0] = (fitpar[0] + fitpar[1]) / 2. +
01640 (float)edgeclean[j-1] - (float)margin ;
01641 sinfo_slit_pos[j][1] = (fitpar[2] + fitpar[3]) / 2. +
01642 (float)edgeclean[j-1] - (float)margin ;
01643 }
01644
01645 sinfo_slit_pos[k][0] = (fitpar[0] + fitpar[1]) / 2. +
01646 (float)edgeclean[k-1] - (float)margin ;
01647 sinfo_slit_pos[k][1] = (fitpar[2] + fitpar[3]) / 2. +
01648 (float)edgeclean[k-1] - (float)margin ;
01649
01650 sinfo_new_destroy_vector ( box_buffer ) ;
01651 cpl_free( xdat ) ;
01652 cpl_free( wdat ) ;
01653 cpl_free( mpar ) ;
01654 }
01655
01656 cpl_free( sinfo_edge ) ;
01657 cpl_free( pos_row ) ;
01658 cpl_free( edgeclean ) ;
01659 cpl_free( dummyedge ) ;
01660 cpl_free( pos_rowclean ) ;
01661 cpl_free( position );
01662
01663 return 0 ;
01664 }
01665
01697 int
01698 sinfo_new_fit_slits( cpl_image * lineImage,
01699 FitParams ** par,
01700 float ** sinfo_slit_pos,
01701 int box_length,
01702 float y_box,
01703 float slope_width )
01704 {
01705 float* position=NULL ;
01706
01707 int * sinfo_edge, * edgeclean ;
01708 int * dummyedge ;
01709 int * pos_row, * pos_rowclean ;
01710 Vector * box_buffer ;
01711 float max_intensity ;
01712 float row_pos ;
01713 int col ;
01714 int i, j, k, m, n, ed ;
01715 int found ;
01716 int line ;
01717 int column ;
01718 int slit_length ;
01719 int agreed ;
01720 int bad_line ;
01721 int margin ;
01722 int iters, xdim, ndat ;
01723 int numpar, its ;
01724 int * mpar ;
01725 float * xdat, * wdat ;
01726 float tol, lab ;
01727 float fitpar[NPAR] ;
01728 float dervpar[NPAR] ;
01729 float minval, maxval ;
01730 int ilx=0;
01731 int ily=0;
01732 float* pidata=NULL;
01733
01734
01735 if ( NULL == lineImage )
01736 {
01737 sinfo_msg_error("no line image given!" ) ;
01738 return -1 ;
01739 }
01740 ilx=cpl_image_get_size_x(lineImage);
01741 ily=cpl_image_get_size_y(lineImage);
01742 pidata=cpl_image_get_data_float(lineImage);
01743
01744 slit_length = (int) sqrt (ilx) ;
01745 if ( NULL == par )
01746 {
01747 sinfo_msg_error("no line fit parameters given!" ) ;
01748 return -2 ;
01749 }
01750
01751 if ( NULL == sinfo_slit_pos )
01752 {
01753 sinfo_msg_error("no position array allocated!" ) ;
01754 return -3 ;
01755 }
01756
01757 if ( box_length < slit_length ||
01758 box_length >= 3*slit_length )
01759 {
01760 sinfo_msg_error("wrong fitting box length given!" ) ;
01761 return -4 ;
01762 }
01763
01764 if ( y_box <= 0. || y_box > 3. )
01765 {
01766 sinfo_msg_error("wrong y box length given!" ) ;
01767 return -5 ;
01768 }
01769
01770 if ( slope_width <= 0. )
01771 {
01772 sinfo_msg_error("wrong width of linear slope given!") ;
01773 return -6 ;
01774 }
01775
01776
01777 slopewidth = slope_width ;
01778
01779
01780 sinfo_edge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
01781 dummyedge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
01782 edgeclean = (int*) cpl_calloc( slit_length-1, sizeof(int) ) ;
01783 pos_row = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
01784 pos_rowclean = (int*) cpl_calloc( slit_length, sizeof(int) ) ;
01785
01786
01787
01788
01789
01790 agreed = -1 ;
01791 bad_line = -1 ;
01792 while( agreed == -1 )
01793 {
01794 found = -1 ;
01795 max_intensity = -FLT_MAX ;
01796 for ( col = 0 ; col < box_length ; col++ )
01797 {
01798 for ( i = 0 ; i < par[0]->n_params ; i++ )
01799 {
01800 if ( par[i]->column == col && par[i]->line != bad_line )
01801 {
01802 if ( par[i]->fit_par[0] > max_intensity )
01803 {
01804 if ( par[i]->fit_par[1] > 0. )
01805 {
01806 max_intensity = par[i]->fit_par[0] ;
01807 found = i ;
01808 }
01809 }
01810 }
01811 }
01812 }
01813
01814
01815
01816
01817
01818 line = par[found]->line ;
01819 column = par[found]->column ;
01820 row_pos = par[found]->fit_par[2] ;
01821 if ( found >= 0 && max_intensity > 0. )
01822 {
01823 for ( i = 0 ; i < par[0]->n_params ; i++ )
01824 {
01825 if ( par[i]->line == line-1 &&
01826 par[i]->column == column + slit_length )
01827 {
01828 if ( par[i]->fit_par[2] <= (row_pos + y_box) &&
01829 par[i]->fit_par[2] >= (row_pos - y_box) )
01830 {
01831 bad_line = line ;
01832 }
01833 }
01834 }
01835 if ( bad_line != line )
01836 {
01837 agreed = 1 ;
01838 break ;
01839 }
01840 }
01841 else
01842 {
01843 sinfo_msg_error("no emission line found in the first image columns");
01844 return -7 ;
01845 }
01846 }
01847
01848
01849 if ( agreed == -1 )
01850 {
01851 sinfo_msg_error("no emission line found in the first image columns") ;
01852 return -7 ;
01853 }
01854
01855
01856 n = 0 ;
01857 ed = 0 ;
01858 position=cpl_calloc(ilx,sizeof(float)) ;
01859
01860 for ( col = 0 ; col < ilx ; col++ )
01861 {
01862 for ( i = 0 ; i < par[0]->n_params ; i++ )
01863 {
01864 if ( par[i]->column == col && par[i] -> line == line )
01865 {
01866 if ( par[i]->fit_par[0] > 0. && par[i]->fit_par[1] > 0. )
01867 {
01868 position[n] = par[i]->fit_par[2] ;
01869 if ( n > 0 && fabs(position[n] - position[n-1]) > y_box )
01870 {
01871 sinfo_edge[ed] = col ;
01872 pos_row[ed] = sinfo_new_nint( position[n-1] ) ;
01873 ed++ ;
01874 if ( col >= ilx - slit_length - 5 )
01875 {
01876 pos_row[ed] = sinfo_new_nint( position[n] ) ;
01877 }
01878 }
01879 n++ ;
01880 }
01881 }
01882 }
01883 }
01884 if ( ed < (slit_length - 1) )
01885 {
01886 sinfo_msg_error("not enough slitlets found") ;
01887 return -8 ;
01888 }
01889
01890
01891 for ( i = 1 ; i <= ed ; i ++ )
01892 {
01893 if (dummyedge[i-1] != -1)
01894 {
01895 dummyedge[i-1] = sinfo_edge[i-1] ;
01896 }
01897 if ( (sinfo_edge[i] - sinfo_edge[i-1]) < slit_length - 3 ||
01898 (sinfo_edge[i] - sinfo_edge[i-1]) > slit_length + 3 )
01899 {
01900 dummyedge[i] = -1 ;
01901 }
01902 if ( (sinfo_edge[i+1] - sinfo_edge[i]) < slit_length - 3 ||
01903 (sinfo_edge[i+1] - sinfo_edge[i]) > slit_length + 3 )
01904 {
01905 dummyedge[i+1] = -1 ;
01906 }
01907 }
01908
01909 k = 0 ;
01910 for ( i = 0 ; i < ed ; i++ )
01911 {
01912 if ( dummyedge[i] != -1 && dummyedge[i] != 0 )
01913 {
01914 edgeclean[k] = dummyedge[i] ;
01915 pos_rowclean[k] = pos_row[i] ;
01916 k++ ;
01917 if( edgeclean[k-1] > (ilx - slit_length - 6 ) )
01918 {
01919 pos_rowclean[k] = pos_row[ed] ;
01920 }
01921 }
01922 }
01923
01924 if ( k != slit_length - 1 )
01925 {
01926 sinfo_msg_error ("not enough clean slitlets found") ;
01927 return -7 ;
01928 }
01929
01930
01931 margin = ( box_length - slit_length ) / 2 ;
01932
01933
01934
01935 for ( j = 0 ; j < k ; j++ )
01936 {
01937 m = 0 ;
01938 if ( j == 0 )
01939 {
01940 box_buffer = sinfo_new_vector( edgeclean[0] + margin ) ;
01941 for( col = 0 ; col < edgeclean[0] + margin ; col++ )
01942 {
01943 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[0]] ;
01944 m++ ;
01945 }
01946
01947 fitpar[0] = 1. ;
01948 fitpar[1] = (float)edgeclean[0] ;
01949
01950 }
01951 else if ( j < k - 1 )
01952 {
01953 box_buffer = sinfo_new_vector( edgeclean[j] -
01954 edgeclean[j-1] + 2*margin ) ;
01955 for ( col = edgeclean[j - 1] - margin ;
01956 col < edgeclean[j] + margin ; col++ )
01957 {
01958 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[j]] ;
01959 m++ ;
01960 }
01961
01962 fitpar[0] = (float)margin ;
01963 fitpar[1] = (float)(edgeclean[j] - edgeclean[j-1] + margin ) ;
01964 }
01965
01966 else
01967 {
01968 box_buffer = sinfo_new_vector( ilx - edgeclean[k-1] + margin ) ;
01969 for ( col = edgeclean[k - 1] - margin ; col < ilx ; col++ )
01970 {
01971 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[k]] ;
01972 m++ ;
01973 }
01974
01975 fitpar[0] = (float)margin ;
01976 fitpar[1] = (float)(m - 1) ;
01977 }
01978
01979 xdat=(float *) cpl_calloc( box_buffer -> n_elements, sizeof (float) ) ;
01980 wdat=(float *) cpl_calloc( box_buffer -> n_elements, sizeof (float) ) ;
01981 mpar=(int *) cpl_calloc( NPAR, sizeof (int) ) ;
01982
01983
01984 minval = FLT_MAX ;
01985 maxval = -FLT_MAX ;
01986 for ( i = 0 ; i < box_buffer->n_elements ; i++ )
01987 {
01988 xdat[i] = i ;
01989 wdat[i] = 1.0 ;
01990 if ( box_buffer -> data[i] < minval )
01991 {
01992 minval = box_buffer -> data[i] ;
01993 }
01994 if ( box_buffer -> data[i] > maxval )
01995 {
01996 maxval = box_buffer -> data[i] ;
01997 }
01998 }
01999
02000 for ( i = 0 ; i < NPAR ; i++ )
02001 {
02002 mpar[i] = 1 ;
02003 dervpar[i] = 0. ;
02004 }
02005
02006 xdim = XDIMA ;
02007 ndat = box_buffer -> n_elements ;
02008 numpar = NPAR ;
02009 tol = TOLA ;
02010 lab = LABA ;
02011 its = ITSA ;
02012
02013 fitpar[2] = minval ;
02014 fitpar[3] = minval ;
02015 fitpar[4] = maxval ;
02016
02017
02018 if ( 0 > ( iters = sinfo_new_lsqfit_edge( xdat, &xdim,
02019 box_buffer -> data,
02020 wdat, &ndat, fitpar,
02021 dervpar, mpar, &numpar,
02022 &tol, &its, &lab )) )
02023 {
02024 sinfo_msg_warning("least squares fit failed, error no.: %d",
02025 iters) ;
02026 return -9 ;
02027 }
02028
02029
02030
02031
02032 if ( j == 0 )
02033 {
02034 sinfo_slit_pos[0][0] = fitpar[0] + slopewidth/2. ;
02035 sinfo_slit_pos[0][1] = fitpar[1] - slopewidth/2. ;
02036 }
02037 else
02038 {
02039 sinfo_slit_pos[j][0] = fitpar[0] + slopewidth/2. +
02040 (float)edgeclean[j-1] - (float)margin ;
02041 sinfo_slit_pos[j][1] = fitpar[1] - slopewidth/2. +
02042 (float)edgeclean[j-1] - (float)margin ;
02043 }
02044
02045 sinfo_slit_pos[k][0] = fitpar[0] + slopewidth/2. +
02046 (float)edgeclean[k-1] - (float)margin ;
02047 sinfo_slit_pos[k][1] = fitpar[1] - slopewidth/2. +
02048 (float)edgeclean[k-1] - (float)margin ;
02049
02050 sinfo_new_destroy_vector ( box_buffer ) ;
02051 cpl_free( xdat ) ;
02052 cpl_free( wdat ) ;
02053 cpl_free( mpar ) ;
02054 }
02055
02056
02057 cpl_free( sinfo_edge ) ;
02058 cpl_free( pos_row ) ;
02059 cpl_free( edgeclean ) ;
02060 cpl_free( dummyedge ) ;
02061 cpl_free( pos_rowclean ) ;
02062 cpl_free( position );
02063 return 0 ;
02064 }
02065
02110 int
02111 sinfo_new_fit_slits2( cpl_image * lineImage,
02112 FitParams ** par,
02113 float ** sinfo_slit_pos,
02114 int box_length,
02115 float y_box,
02116 float diff_tol )
02117 {
02118 float* position=NULL ;
02119 int * sinfo_edge, * edgeclean ;
02120 int * dummyedge ;
02121 int * pos_row, * pos_rowclean ;
02122 Vector * box_buffer ;
02123 Vector * half_buffer ;
02124 float max_intensity ;
02125 float row_pos ;
02126 int col ;
02127 int i, j, k, m, n, ed ;
02128 int found, init1 ;
02129 int line ;
02130 int nel, n_right, left_right ;
02131 int column ;
02132 int slit_length ;
02133 int agreed ;
02134 int bad_line ;
02135 int margin ;
02136 int iters, xdim, ndat ;
02137 int numpar, its ;
02138 int * mpar ;
02139 float * xdat, * wdat ;
02140 float tol, lab ;
02141 float fitpar[NPAR] ;
02142 float dervpar[NPAR] ;
02143 float minval, maxval ;
02144 float pos, last_pos ;
02145 int ilx=0;
02146 int ily=0;
02147 float* pidata=NULL;
02148
02149
02150 if ( NULL == lineImage )
02151 {
02152 sinfo_msg_error("no line image given!" ) ;
02153 return -1 ;
02154 }
02155 ilx=cpl_image_get_size_x(lineImage);
02156 ily=cpl_image_get_size_y(lineImage);
02157 pidata=cpl_image_get_data_float(lineImage);
02158
02159 slit_length = (int) sqrt (ilx) ;
02160
02161 if ( NULL == par )
02162 {
02163 sinfo_msg_error("no line fit parameters given!" ) ;
02164 return -2 ;
02165 }
02166
02167 if ( NULL == sinfo_slit_pos )
02168 {
02169 sinfo_msg_error("no position array allocated!" ) ;
02170 return -3 ;
02171 }
02172
02173 if ( box_length < slit_length ||
02174 box_length >= 3*slit_length )
02175 {
02176 sinfo_msg_error("wrong fitting box length given!" ) ;
02177 return -4 ;
02178 }
02179
02180 if ( y_box <= 0. || y_box > 3. )
02181 {
02182 sinfo_msg_error("wrong y box length given!" ) ;
02183 return -5 ;
02184 }
02185
02186 if ( diff_tol < 1. )
02187 {
02188 sinfo_msg_error("diff_tol too small!" ) ;
02189 return -6 ;
02190 }
02191
02192
02193 sinfo_edge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
02194 dummyedge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
02195 edgeclean = (int*) cpl_calloc( slit_length-1, sizeof(int) ) ;
02196 pos_row = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
02197 pos_rowclean = (int*) cpl_calloc( slit_length, sizeof(int) ) ;
02198
02199
02200
02201
02202
02203 agreed = -1 ;
02204 bad_line = -1 ;
02205 while( agreed == -1 )
02206 {
02207 found = -1 ;
02208 max_intensity = -FLT_MAX ;
02209 for ( col = 0 ; col < box_length ; col++ )
02210 {
02211 for ( i = 0 ; i < par[0]->n_params ; i++ )
02212 {
02213 if ( par[i]->column == col && par[i]->line != bad_line )
02214 {
02215 if ( par[i]->fit_par[0] > max_intensity )
02216 {
02217 if ( par[i]->fit_par[1] > 0. )
02218 {
02219 max_intensity = par[i]->fit_par[0] ;
02220 found = i ;
02221 }
02222 }
02223 }
02224 }
02225 }
02226
02227
02228
02229
02230
02231 line = par[found]->line ;
02232 column = par[found]->column ;
02233 row_pos = par[found]->fit_par[2] ;
02234 if ( found >= 0 && max_intensity > 0. )
02235 {
02236 for ( i = 0 ; i < par[0]->n_params ; i++ )
02237 {
02238 if ( par[i]->line == line-1 &&
02239 par[i]->column == column + slit_length )
02240 {
02241 if ( par[i]->fit_par[2] <= (row_pos + y_box) &&
02242 par[i]->fit_par[2] >= (row_pos - y_box) )
02243 {
02244 bad_line = line ;
02245 }
02246 }
02247 }
02248 if ( bad_line != line )
02249 {
02250 agreed = 1 ;
02251 break ;
02252 }
02253 }
02254 else
02255 {
02256 sinfo_msg_error("no emission line found in the first image columns");
02257 return -7 ;
02258 }
02259 }
02260
02261
02262 if ( agreed == -1 )
02263 {
02264 sinfo_msg_error("no emission line found in the first image columns") ;
02265 return -7 ;
02266 }
02267
02268
02269 n = 0 ;
02270 ed = 0 ;
02271 position=cpl_calloc(ilx,sizeof(float)) ;
02272
02273 for ( col = 0 ; col < ilx ; col++ )
02274 {
02275 for ( i = 0 ; i < par[0]->n_params ; i++ )
02276 {
02277 if ( par[i]->column == col && par[i]->line == line )
02278 {
02279 if ( par[i]->fit_par[0] > 0. && par[i]->fit_par[1] > 0. )
02280 {
02281 position[n] = par[i]->fit_par[2] ;
02282 if ( n > 0 && fabs(position[n] - position[n-1]) > y_box )
02283 {
02284 sinfo_edge[ed] = col ;
02285 pos_row[ed] = sinfo_new_nint( position[n-1] ) ;
02286 ed++ ;
02287 if ( col >= ilx - slit_length - 5 )
02288 {
02289 pos_row[ed] = sinfo_new_nint( position[n] ) ;
02290 }
02291 }
02292 n++ ;
02293 }
02294 }
02295 }
02296 }
02297 if ( ed < (slit_length - 1) )
02298 {
02299 sinfo_msg_error("not enough slitlets found") ;
02300 return -8 ;
02301 }
02302
02303
02304 for ( i = 1 ; i <= ed ; i ++ )
02305 {
02306 if (dummyedge[i-1] != -1)
02307 {
02308 dummyedge[i-1] = sinfo_edge[i-1] ;
02309 }
02310 if ( (sinfo_edge[i] - sinfo_edge[i-1]) < slit_length - 3 ||
02311 (sinfo_edge[i] - sinfo_edge[i-1]) > slit_length + 3 )
02312 {
02313 dummyedge[i] = -1 ;
02314 }
02315 if ( (sinfo_edge[i+1] - sinfo_edge[i]) < slit_length - 3 ||
02316 (sinfo_edge[i+1] - sinfo_edge[i]) > slit_length + 3 )
02317 {
02318 dummyedge[i+1] = -1 ;
02319 }
02320 }
02321
02322 k = 0 ;
02323 for ( i = 0 ; i < ed ; i++ )
02324 {
02325 if ( dummyedge[i] != -1 && dummyedge[i] != 0 )
02326 {
02327 edgeclean[k] = dummyedge[i] ;
02328 pos_rowclean[k] = pos_row[i] ;
02329 k++ ;
02330 if( edgeclean[k-1] > (ilx - slit_length - 6 ) )
02331 {
02332 pos_rowclean[k] = pos_row[ed] ;
02333 }
02334 }
02335 }
02336
02337 if ( k != slit_length - 1 )
02338 {
02339 sinfo_msg_error("not enough clean slitlets found") ;
02340 return -7 ;
02341 }
02342
02343
02344 margin = ( box_length - slit_length ) / 2 ;
02345
02346
02347
02348 for ( j = 0 ; j <= k ; j++ )
02349 {
02350 m = 0 ;
02351 if ( j == 0 )
02352 {
02353 box_buffer = sinfo_new_vector( edgeclean[0] + margin ) ;
02354 for( col = 0 ; col < edgeclean[0] + margin ; col++ )
02355 {
02356 box_buffer->data[m] = pidata[col +ilx*pos_rowclean[0]] ;
02357 m++ ;
02358 }
02359 }
02360 else if ( j < k )
02361 {
02362 box_buffer = sinfo_new_vector( edgeclean[j] -
02363 edgeclean[j-1] + 2*margin ) ;
02364 for ( col = edgeclean[j - 1] - margin ;
02365 col < edgeclean[j] + margin ; col++ )
02366 {
02367 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[j]] ;
02368 m++ ;
02369 }
02370 }
02371 else
02372 {
02373 box_buffer = sinfo_new_vector( ilx - edgeclean[k-1] + margin ) ;
02374 for ( col = edgeclean[k - 1] - margin ; col < ilx ; col++ )
02375 {
02376 box_buffer->data[m] = pidata[col + ilx*pos_rowclean[k]] ;
02377 m++ ;
02378 }
02379 }
02380
02381 for ( left_right = 0 ; left_right <= 1 ; left_right++ )
02382 {
02383 nel = 0 ;
02384 if ( left_right == 0 )
02385 {
02386 nel = box_buffer -> n_elements / 2 ;
02387 }
02388 else
02389 {
02390 if ( box_buffer -> n_elements % 2 == 0 )
02391 {
02392 nel = box_buffer -> n_elements / 2 ;
02393 }
02394 else
02395 {
02396 nel = box_buffer -> n_elements / 2 + 1 ;
02397 }
02398 }
02399
02400
02401
02402 half_buffer = sinfo_new_vector( nel ) ;
02403 if ( left_right == 0 )
02404 {
02405 for ( i = 0 ; i < nel ; i++ )
02406 {
02407 half_buffer -> data[i] = box_buffer -> data[i] ;
02408 }
02409 }
02410 else
02411 {
02412 n_right = 0 ;
02413 for ( i = box_buffer -> n_elements - 1 ;
02414 i >= box_buffer -> n_elements - nel ; i-- )
02415 {
02416 half_buffer -> data[n_right] = box_buffer -> data[i] ;
02417 n_right++ ;
02418 }
02419 }
02420
02421 xdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
02422 wdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
02423 mpar = (int *) cpl_calloc( NPAR, sizeof (int) ) ;
02424
02425
02426 minval = FLT_MAX ;
02427 maxval = -FLT_MAX ;
02428 for ( i = 0 ; i < nel ; i++ )
02429 {
02430 xdat[i] = i ;
02431 wdat[i] = 1.0 ;
02432 if ( half_buffer -> data[i] < minval )
02433 {
02434 minval = half_buffer -> data[i] ;
02435 }
02436 if ( half_buffer -> data[i] > maxval )
02437 {
02438 maxval = half_buffer -> data[i] ;
02439 }
02440 }
02441
02442 fitpar[2] = minval ;
02443 fitpar[3] = maxval ;
02444
02445
02446
02447 init1 = -1 ;
02448 for ( i = 0 ; i < nel ; i++ )
02449 {
02450 if ( half_buffer -> data[i] >= ( maxval + minval ) / 2. )
02451 {
02452 init1 = i ;
02453 break ;
02454 }
02455 }
02456
02457
02458 if ( init1 != -1 )
02459 {
02460 fitpar[0] = ((float)init1 - 1.) ;
02461 fitpar[1] = ((float)init1 + 1.) ;
02462 }
02463
02464 for ( i = 0 ; i < NPAR ; i++ )
02465 {
02466 mpar[i] = 1 ;
02467 dervpar[i] = 0. ;
02468 }
02469
02470 xdim = XDIMA ;
02471 ndat = nel ;
02472 numpar = NPAR ;
02473 tol = TOLA ;
02474 lab = LABA ;
02475 its = ITSA ;
02476
02477
02478 if ( 0 > ( iters = sinfo_new_lsqfit_edge( xdat, &xdim,
02479 half_buffer -> data,
02480 wdat, &ndat, fitpar,
02481 dervpar, mpar, &numpar,
02482 &tol, &its, &lab )) )
02483 {
02484
02485 sinfo_msg_warning (" least squares fit failed, error"
02486 " no.: %d in slitlet: %d\n", iters, j) ;
02487 fitpar[0] = ((float)init1 - 1.) ;
02488 fitpar[1] = ((float)init1 + 1.) ;
02489 }
02490
02491 pos = (fitpar[0] + fitpar[1]) / 2. ;
02492
02493
02494
02495
02496
02497
02498
02499
02500 if ( left_right == 0 )
02501 {
02502
02503
02504 if ( j == 0 )
02505 {
02506 if ( fabs(pos - ((float)edgeclean[0] - 1. -
02507 (float)slit_length)) < diff_tol )
02508 {
02509 sinfo_slit_pos[0][0] = pos ;
02510 }
02511 else
02512 {
02513 sinfo_msg_warning("something wrong with fitted left"
02514 " position of slitlet 0") ;
02515 if ( (float) edgeclean[0] - 1. -
02516 (float)slit_length < 0. )
02517 {
02518 sinfo_slit_pos[0][0] = 0. ;
02519 }
02520 else
02521 {
02522 sinfo_slit_pos[0][0] = (float)edgeclean[0] - 1. -
02523 (float)slit_length ;
02524 }
02525 }
02526 }
02527 else if ( j < k )
02528 {
02529 if ( fabs( pos - (float)margin ) < diff_tol )
02530 {
02531 sinfo_slit_pos[j][0] = pos + (float)edgeclean[j-1] -
02532 (float)margin ;
02533 }
02534 else
02535 {
02536 sinfo_msg_warning("something wrong with fitted left"
02537 " position of slitlet %d", j) ;
02538 sinfo_slit_pos[j][0] = (float)edgeclean[j-1] - 1. ;
02539 }
02540 }
02541 else
02542 {
02543 if ( fabs( pos - (float)margin ) < diff_tol )
02544 {
02545 sinfo_slit_pos[k][0] = pos + (float)edgeclean[k-1] -
02546 (float)margin ;
02547 }
02548 else
02549 {
02550 sinfo_msg_warning("something wrong with fitted left"
02551 " position of slitlet %d", j) ;
02552 sinfo_slit_pos[k][0] = (float)edgeclean[k-1] - 1. ;
02553 }
02554 }
02555 }
02556 else
02557 {
02558
02559
02560 if ( j == 0 )
02561 {
02562 if ( fabs( (float)box_buffer->n_elements - pos -
02563 (float)edgeclean[0] ) < diff_tol )
02564 {
02565 sinfo_slit_pos[0][1] = (float)(box_buffer->n_elements -
02566 1) - pos ;
02567 }
02568 else
02569 {
02570 sinfo_msg_warning("something wrong with fitted "
02571 "right position of slitlet 0") ;
02572 sinfo_slit_pos[0][1] = (float)edgeclean[0] - 1. ;
02573 }
02574 }
02575 else if ( j < k )
02576 {
02577 if ( fabs( (float)box_buffer->n_elements - pos
02578 + (float)edgeclean[j-1] - (float)margin -
02579 (float)edgeclean[j] ) < diff_tol )
02580 {
02581 sinfo_slit_pos[j][1] = (float)(box_buffer->n_elements -
02582 1) - pos
02583 + (float)edgeclean[j-1] - (float)margin ;
02584 }
02585 else
02586 {
02587 sinfo_msg_warning("something wrong with fitted right "
02588 "position of slitlet %d", j) ;
02589 sinfo_slit_pos[j][1] = (float)edgeclean[j] - 1. ;
02590 }
02591 }
02592 else
02593 {
02594 if ( edgeclean[k-1] + slit_length > ilx )
02595 {
02596 last_pos = (float)(ilx - 1) ;
02597 }
02598 else
02599 {
02600 last_pos = (float)(edgeclean[k-1] - 1 + slit_length) ;
02601 }
02602 if ( fabs( (float)(box_buffer->n_elements - 1) - pos
02603 + (float)edgeclean[k-1] - (float)margin -
02604 last_pos ) < diff_tol )
02605 {
02606 sinfo_slit_pos[k][1] = (float)(box_buffer->n_elements -
02607 1) - pos
02608 + (float)edgeclean[k-1] - (float)margin ;
02609 }
02610 else
02611 {
02612 sinfo_msg_warning("something wrong with fitted right "
02613 "position of slitlet %d\n", j) ;
02614 sinfo_slit_pos[k][1] = last_pos ;
02615 }
02616 }
02617 }
02618
02619 sinfo_new_destroy_vector ( half_buffer ) ;
02620 cpl_free( xdat ) ;
02621 cpl_free( wdat ) ;
02622 cpl_free( mpar ) ;
02623 }
02624 sinfo_new_destroy_vector ( box_buffer ) ;
02625 }
02626
02627 cpl_free( sinfo_edge ) ;
02628 cpl_free( pos_row ) ;
02629 cpl_free( edgeclean ) ;
02630 cpl_free( dummyedge ) ;
02631 cpl_free( pos_rowclean ) ;
02632 cpl_free(position);
02633 return 0 ;
02634 }
02635
02670 int
02671 sinfo_new_fit_slits_edge( cpl_image * lineImage,
02672 FitParams ** par,
02673 float ** sinfo_slit_pos,
02674 int box_length,
02675 float y_box,
02676 float diff_tol )
02677 {
02678 float* position=NULL ;
02679 int * sinfo_edge, * edgeclean ;
02680 int * dummyedge ;
02681 int * pos_row, * pos_rowclean ;
02682 Vector * box_buffer ;
02683 Vector * half_buffer ;
02684 float max_intensity ;
02685 float row_pos ;
02686 int row, col ;
02687 int i, j, k, m, n, ed ;
02688 int found, init1 ;
02689 int line ;
02690 int nel, n_right, left_right ;
02691 int column ;
02692 int slit_length ;
02693 int agreed ;
02694 int bad_line ;
02695 int margin ;
02696 int iters, xdim, ndat ;
02697 int numpar, its ;
02698 int * mpar ;
02699 float * xdat, * wdat ;
02700 float tol, lab ;
02701 float fitpar[NPAR] ;
02702 float dervpar[NPAR] ;
02703 float minval, maxval ;
02704 float pos, last_pos ;
02705 int ilx=0;
02706 int ily=0;
02707 float* pidata=NULL;
02708
02709
02710 if ( NULL == lineImage )
02711 {
02712 sinfo_msg_error(" no line image given!" ) ;
02713 return -1 ;
02714 }
02715 ilx=cpl_image_get_size_x(lineImage);
02716 ily=cpl_image_get_size_y(lineImage);
02717 pidata=cpl_image_get_data_float(lineImage);
02718
02719 slit_length = (int) sqrt (ilx) ;
02720
02721 if ( NULL == par )
02722 {
02723 sinfo_msg_error(" no line fit parameters given!" ) ;
02724 return -2 ;
02725 }
02726
02727 if ( NULL == sinfo_slit_pos )
02728 {
02729 sinfo_msg_error(" no position array allocated!" ) ;
02730 return -3 ;
02731 }
02732
02733 if ( box_length < 4 ||
02734 box_length >= 2*slit_length )
02735 {
02736 sinfo_msg_error(" wrong fitting box length given!" ) ;
02737 sinfo_msg_error(" Must be 4 <= box_length < %d ",2*slit_length ) ;
02738 sinfo_msg_error(" You have chosen box_length = %d ",box_length);
02739 return -4 ;
02740 }
02741
02742 if ( y_box <= 0. || y_box > 3. )
02743 {
02744 sinfo_msg_error(" wrong y box length given!" ) ;
02745 sinfo_msg_error(" y_box=%f not in range (0,3]!",y_box);
02746 return -5 ;
02747 }
02748
02749 if ( diff_tol < 1. )
02750 {
02751 sinfo_msg_error(" diff_tol too small!" ) ;
02752 return -6 ;
02753 }
02754
02755
02756 sinfo_edge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
02757 dummyedge = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
02758 edgeclean = (int*) cpl_calloc( slit_length-1, sizeof(int) ) ;
02759 pos_row = (int*) cpl_calloc( 3*slit_length, sizeof(int) ) ;
02760 pos_rowclean = (int*) cpl_calloc( slit_length, sizeof(int) ) ;
02761
02762
02763
02764
02765
02766 agreed = -1 ;
02767 bad_line = -1 ;
02768 while( agreed == -1 )
02769 {
02770 found = -1 ;
02771 max_intensity = -FLT_MAX ;
02772 for ( col = 0 ; col < slit_length ; col++ )
02773 {
02774 for ( i = 0 ; i < par[0]->n_params ; i++ )
02775 {
02776 if ( par[i]->column == col && par[i] -> line != bad_line )
02777 {
02778 if ( par[i]->fit_par[0] > max_intensity )
02779 {
02780 if ( par[i]->fit_par[1] >= 1. &&
02781 par[i]->fit_par[2] > 0. )
02782 {
02783 max_intensity = par[i]->fit_par[0] ;
02784 found = i ;
02785 }
02786 }
02787 }
02788 }
02789 }
02790
02791
02792
02793
02794
02795 line = par[found]->line ;
02796 column = par[found]->column ;
02797 row_pos = par[found]->fit_par[2] ;
02798 if ( found >= 0 && max_intensity > 0. )
02799 {
02800 for ( i = 0 ; i < par[0]->n_params ; i++ )
02801 {
02802 if ( par[i]->line == line-1 &&
02803 par[i]->column == column + slit_length )
02804 {
02805 if ( par[i]->fit_par[2] <= (row_pos + y_box) &&
02806 par[i]->fit_par[2] >= (row_pos - y_box) )
02807 {
02808 bad_line = line ;
02809 }
02810 }
02811 }
02812 if ( bad_line != line )
02813 {
02814 agreed = 1 ;
02815 break ;
02816 }
02817 }
02818 else
02819 {
02820 sinfo_msg_error("no emission line found in "
02821 "the first image columns") ;
02822 cpl_free( sinfo_edge ) ;
02823 cpl_free( pos_row ) ;
02824 cpl_free( edgeclean ) ;
02825 cpl_free( dummyedge ) ;
02826 cpl_free( pos_rowclean ) ;
02827 return -7 ;
02828 }
02829 }
02830
02831
02832 if ( agreed == -1 )
02833 {
02834 sinfo_msg_error(" no emission line found in the first image columns") ;
02835 cpl_free( sinfo_edge ) ;
02836 cpl_free( pos_row ) ;
02837 cpl_free( edgeclean ) ;
02838 cpl_free( dummyedge ) ;
02839 cpl_free( pos_rowclean ) ;
02840 return -7 ;
02841 }
02842
02843
02844 n = 0 ;
02845 ed = 0 ;
02846 position=cpl_calloc(ilx,sizeof(float)) ;
02847
02848 for ( col = 0 ; col < ilx ; col++ )
02849 {
02850 for ( i = 0 ; i < par[0]->n_params ; i++ )
02851 {
02852 if ( par[i]->column == col && par[i]->line == line )
02853 {
02854 if ( par[i]->fit_par[0] > 0. &&
02855 par[i]->fit_par[1] >= 1. &&
02856 par[i]->fit_par[2] > 0. )
02857 {
02858 position[n] = par[i]->fit_par[2] ;
02859 if ( n > 0 && fabs(position[n] - position[n-1]) > y_box )
02860 {
02861 sinfo_edge[ed] = col ;
02862 pos_row[ed] = sinfo_new_nint( position[n-1] ) ;
02863 ed++ ;
02864 if ( col >= ilx - slit_length - 5 )
02865 {
02866 pos_row[ed] = sinfo_new_nint( position[n] ) ;
02867 }
02868 }
02869 n++ ;
02870 }
02871 }
02872 }
02873 }
02874 if ( ed < (slit_length - 1) )
02875 {
02876 sinfo_msg_error(" not enough slitlets found") ;
02877 cpl_free( sinfo_edge ) ;
02878 cpl_free( pos_row ) ;
02879 cpl_free( edgeclean ) ;
02880 cpl_free( dummyedge ) ;
02881 cpl_free( pos_rowclean ) ;
02882 return -8 ;
02883 }
02884
02885
02886 for ( i = 1 ; i <= ed ; i ++ )
02887 {
02888 if ( i == ed )
02889 {
02890 if ( (sinfo_edge[i-1] - sinfo_edge[i-2]) < slit_length - 3 ||
02891 (sinfo_edge[i-1] - sinfo_edge[i-2]) > slit_length + 3 )
02892 {
02893 dummyedge[i-1] = -1 ;
02894 }
02895
02896 }
02897 if (dummyedge[i-1] != -1)
02898 {
02899 dummyedge[i-1] = sinfo_edge[i-1] ;
02900 }
02901 else
02902 {
02903 continue ;
02904 }
02905 if ( i < ed )
02906 {
02907 if ( (sinfo_edge[i] - sinfo_edge[i-1]) < slit_length - 3 ||
02908 (sinfo_edge[i] - sinfo_edge[i-1]) > slit_length + 3 )
02909 {
02910 dummyedge[i] = -1 ;
02911 }
02912 }
02913 if ( i + 1 < ed && dummyedge[i] != -1 )
02914 {
02915 if ( (sinfo_edge[i+1] - sinfo_edge[i]) < slit_length - 3 ||
02916 (sinfo_edge[i+1] - sinfo_edge[i]) > slit_length + 3 )
02917 {
02918 dummyedge[i+1] = -1 ;
02919 }
02920 }
02921 }
02922
02923 k = 0 ;
02924 for ( i = 0 ; i < ed ; i++ )
02925 {
02926 if ( dummyedge[i] != -1 && dummyedge[i] != 0 )
02927 {
02928 edgeclean[k] = dummyedge[i] ;
02929 pos_rowclean[k] = pos_row[i] ;
02930 k++ ;
02931 if( edgeclean[k-1] > (ilx - slit_length - 6 ) )
02932 {
02933 pos_rowclean[k] = pos_row[ed] ;
02934 }
02935 }
02936 }
02937
02938 if ( k != slit_length - 1 )
02939 {
02940 sinfo_msg_error(" not enough clean slitlets found") ;
02941 cpl_free( sinfo_edge ) ;
02942 cpl_free( pos_row ) ;
02943 cpl_free( edgeclean ) ;
02944 cpl_free( dummyedge ) ;
02945 cpl_free( pos_rowclean ) ;
02946 return -8 ;
02947 }
02948
02949
02950 margin = box_length / 2 ;
02951
02952
02953
02954
02955
02956
02957 for ( j = 0 ; j <= k ; j++ )
02958 {
02959 m = 0 ;
02960 if ( j == 0 )
02961 {
02962 box_buffer = sinfo_new_vector( edgeclean[0] + margin ) ;
02963 for( col = 0 ; col < edgeclean[0] + margin ; col++ )
02964 {
02965 maxval = -FLT_MAX ;
02966 for ( row = pos_rowclean[0] - sinfo_new_nint(y_box) ;
02967 row <= pos_rowclean[0] + sinfo_new_nint(y_box) ; row++ )
02968 {
02969 if ( maxval < pidata[col + ilx*row] )
02970 {
02971 maxval = pidata[col + ilx*row] ;
02972 }
02973 }
02974 box_buffer->data[m] = maxval ;
02975 m++ ;
02976 }
02977 }
02978 else if ( j < k )
02979 {
02980 box_buffer = sinfo_new_vector( edgeclean[j] -
02981 edgeclean[j-1] + 2*margin ) ;
02982 for ( col = edgeclean[j - 1] - margin ;
02983 col < edgeclean[j] + margin ; col++ )
02984 {
02985 maxval = -FLT_MAX ;
02986 for ( row = pos_rowclean[j] - sinfo_new_nint(y_box) ;
02987 row <= pos_rowclean[j] + sinfo_new_nint(y_box) ; row++ )
02988 {
02989 if ( maxval < pidata[col + ilx*row] )
02990 {
02991 maxval = pidata[col + ilx*row] ;
02992 }
02993 }
02994 box_buffer->data[m] = maxval ;
02995 m++ ;
02996 }
02997 }
02998 else
02999 {
03000 box_buffer = sinfo_new_vector( ilx - edgeclean[k-1] + margin ) ;
03001 for ( col = edgeclean[k - 1] - margin ; col < ilx ; col++ )
03002 {
03003 maxval = -FLT_MAX ;
03004 for ( row = pos_rowclean[k] - sinfo_new_nint(y_box) ;
03005 row <= pos_rowclean[k] + sinfo_new_nint(y_box) ; row++ )
03006 {
03007 if ( maxval < pidata[col + ilx*row] )
03008 {
03009 maxval = pidata[col + ilx*row] ;
03010 }
03011 }
03012 box_buffer->data[m] = maxval ;
03013 m++ ;
03014 }
03015 }
03016
03017 for ( left_right = 0 ; left_right <= 1 ; left_right++ )
03018 {
03019 nel = 0 ;
03020 if ( left_right == 0 )
03021 {
03022 nel = box_buffer -> n_elements / 2 ;
03023 }
03024 else
03025 {
03026 if ( box_buffer -> n_elements % 2 == 0 )
03027 {
03028 nel = box_buffer -> n_elements / 2 ;
03029 }
03030 else
03031 {
03032 nel = box_buffer -> n_elements / 2 + 1 ;
03033 }
03034 }
03035
03036
03037
03038 half_buffer = sinfo_new_vector( nel ) ;
03039 if ( left_right == 0 )
03040 {
03041 for ( i = 0 ; i < nel ; i++ )
03042 {
03043 half_buffer -> data[i] = box_buffer -> data[i] ;
03044 }
03045 }
03046 else
03047 {
03048 n_right = 0 ;
03049 for ( i = box_buffer -> n_elements - 1 ;
03050 i >= box_buffer -> n_elements - nel ; i-- )
03051 {
03052 half_buffer -> data[n_right] = box_buffer -> data[i] ;
03053 n_right++ ;
03054 }
03055 }
03056
03057 xdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
03058 wdat = (float *) cpl_calloc( nel, sizeof (float) ) ;
03059 mpar = (int *) cpl_calloc( NPAR, sizeof (int) ) ;
03060
03061
03062 minval = FLT_MAX ;
03063 maxval = -FLT_MAX ;
03064 for ( i = 0 ; i < nel ; i++ )
03065 {
03066 xdat[i] = i ;
03067 wdat[i] = 1.0 ;
03068 if ( half_buffer -> data[i] < minval )
03069 {
03070 minval = half_buffer -> data[i] ;
03071 }
03072 if ( half_buffer -> data[i] > maxval )
03073 {
03074 maxval = half_buffer -> data[i] ;
03075 }
03076 }
03077
03078 fitpar[2] = minval ;
03079 fitpar[3] = maxval ;
03080
03081
03082
03083 init1 = -1 ;
03084 for ( i = 0 ; i < nel ; i++ )
03085 {
03086 if ( half_buffer -> data[i] >= ( maxval + minval ) / 2. )
03087 {
03088 init1 = i ;
03089 break ;
03090 }
03091 }
03092
03093
03094 if ( init1 != -1 )
03095 {
03096 fitpar[0] = ((float)init1 - 1.) ;
03097 fitpar[1] = ((float)init1 + 1.) ;
03098 }
03099
03100 for ( i = 0 ; i < NPAR ; i++ )
03101 {
03102 mpar[i] = 1 ;
03103 dervpar[i] = 0. ;
03104 }
03105
03106 xdim = XDIMA ;
03107 ndat = nel ;
03108 numpar = NPAR ;
03109 tol = TOLA ;
03110 lab = LABA ;
03111 its = ITSA ;
03112
03113
03114 if ( 0 > ( iters = sinfo_new_lsqfit_edge( xdat, &xdim,
03115 half_buffer -> data,
03116 wdat, &ndat, fitpar,
03117 dervpar, mpar, &numpar,
03118 &tol, &its, &lab )) )
03119 {
03120
03121 sinfo_msg_warning ("least squares fit failed, error "
03122 "no.: %d in slitlet: %d", iters, j) ;
03123 fitpar[0] = ((float)init1 - 1.) ;
03124 fitpar[1] = ((float)init1 + 1.) ;
03125 }
03126
03127 pos = (fitpar[0] + fitpar[1]) / 2. ;
03128
03129
03130
03131
03132
03133
03134
03135
03136 if ( left_right == 0 )
03137 {
03138
03139
03140 if ( j == 0 )
03141 {
03142 if ( fabs(pos - ((float)edgeclean[0] - 1. -
03143 (float)slit_length)) < diff_tol )
03144 {
03145 sinfo_slit_pos[0][0] = pos ;
03146 }
03147 else
03148 {
03149 sinfo_msg_warning("something wrong with fitted "
03150 "left position of slitlet 0") ;
03151 if ((float) edgeclean[0] - 1. -
03152 (float)slit_length < 0. )
03153 {
03154 sinfo_slit_pos[0][0] = 0. ;
03155 }
03156 else
03157 {
03158 sinfo_slit_pos[0][0] = (float)edgeclean[0] - 1. -
03159 (float)slit_length ;
03160 }
03161 }
03162 }
03163 else if ( j < k )
03164 {
03165 if ( fabs( pos - (float)margin ) < diff_tol )
03166 {
03167 sinfo_slit_pos[j][0] = pos + (float)edgeclean[j-1] -
03168 (float)margin ;
03169 }
03170 else
03171 {
03172 sinfo_msg_warning("something wrong with fitted "
03173 "left position of slitlet %d", j) ;
03174 sinfo_slit_pos[j][0] = (float)edgeclean[j-1] - 1. ;
03175 }
03176 }
03177 else
03178 {
03179 if ( fabs( pos - (float)margin ) < diff_tol )
03180 {
03181 sinfo_slit_pos[k][0] = pos + (float)edgeclean[k-1] -
03182 (float)margin ;
03183 }
03184 else
03185 {
03186 sinfo_msg_warning("something wrong with fitted left "
03187 "position of slitlet %d", j) ;
03188 sinfo_slit_pos[k][0] = (float)edgeclean[k-1] - 1. ;
03189 }
03190 }
03191 }
03192 else
03193 {
03194
03195
03196 if ( j == 0 )
03197 {
03198 if ( fabs( (float)box_buffer->n_elements - pos -
03199 (float)edgeclean[0] ) < diff_tol )
03200 {
03201 sinfo_slit_pos[0][1] = (float)(box_buffer->n_elements -
03202 1) - pos ;
03203 }
03204 else
03205 {
03206 sinfo_msg_warning("something wrong with fitted "
03207 "right position of slitlet 0") ;
03208 sinfo_slit_pos[0][1] = (float)edgeclean[0] - 1. ;
03209 }
03210 }
03211 else if ( j < k )
03212 {
03213 if ( fabs( (float)box_buffer->n_elements - pos
03214 + (float)edgeclean[j-1] - (float)margin -
03215 (float)edgeclean[j] ) < diff_tol )
03216 {
03217 sinfo_slit_pos[j][1] = (float)(box_buffer->n_elements -
03218 1) - pos
03219 + (float)edgeclean[j-1] - (float)margin;
03220 }
03221 else
03222 {
03223 sinfo_msg_warning("something wrong with fitted "
03224 "right position of slitlet %d", j) ;
03225 sinfo_slit_pos[j][1] = (float)edgeclean[j] - 1. ;
03226 }
03227 }
03228 else
03229 {
03230 if ( edgeclean[k-1] + slit_length > ilx )
03231 {
03232 last_pos = (float)(ilx - 1) ;
03233 }
03234 else
03235 {
03236 last_pos = (float)(edgeclean[k-1] - 1 + slit_length) ;
03237 }
03238 if ( fabs( (float)(box_buffer->n_elements - 1) - pos
03239 + (float)edgeclean[k-1] - (float)margin -
03240 last_pos ) < diff_tol )
03241 {
03242 sinfo_slit_pos[k][1] = (float)(box_buffer->n_elements -
03243 1) - pos
03244 + (float)edgeclean[k-1] - (float)margin ;
03245 }
03246 else
03247 {
03248 sinfo_msg_warning("something wrong with fitted "
03249 "right position of slitlet %d", j) ;
03250 sinfo_slit_pos[k][1] = last_pos ;
03251 }
03252 }
03253 }
03254
03255 sinfo_new_destroy_vector ( half_buffer ) ;
03256 cpl_free( xdat ) ;
03257 cpl_free( wdat ) ;
03258 cpl_free( mpar ) ;
03259 }
03260 sinfo_new_destroy_vector ( box_buffer ) ;
03261 }
03262
03263 cpl_free( sinfo_edge ) ;
03264 cpl_free( pos_row ) ;
03265 cpl_free( edgeclean ) ;
03266 cpl_free( dummyedge ) ;
03267 cpl_free( pos_rowclean ) ;
03268 cpl_free( position );
03269 return 0 ;
03270 }
03271
03294 int
03295 sinfo_new_fit_slits_edge_with_estimate ( cpl_image * lineImage,
03296 float ** sinfo_slit_pos,
03297 int box_length,
03298 float y_box,
03299 float diff_tol,
03300 int low_pos,
03301 int high_pos )
03302 {
03303 int* position=NULL ;
03304 Vector * box_buffer ;
03305 Vector * in_buffer ;
03306 int found_row ;
03307 int row, col ;
03308 int col_first, col_last ;
03309 int row_first, row_last ;
03310 int i, j, m, n ;
03311 int init1 ;
03312 int left_right ;
03313 int n_buf, shift ;
03314 int slit_length ;
03315 int iters, xdim, ndat ;
03316 int numpar, its ;
03317 int * mpar ;
03318 float * xdat, * wdat ;
03319 float tol, lab ;
03320 float fitpar[NPAR] ;
03321 float dervpar[NPAR] ;
03322 float minval, maxval ;
03323 float pos ;
03324 float new_pos ;
03325 int slitposition[SLITLENGTH] ;
03326 pixelvalue rowpos[SLITLENGTH] ;
03327 int ilx=0;
03328 int ily=0;
03329 float* pidata=NULL;
03330
03331 slit_length = SLITLENGTH ;
03332 slit_length = N_SLITLETS ;
03333
03334
03335 if ( NULL == lineImage )
03336 {
03337 sinfo_msg_error(" no line image given!" ) ;
03338 return -1 ;
03339 }
03340 ilx=cpl_image_get_size_x(lineImage);
03341 ily=cpl_image_get_size_y(lineImage);
03342 pidata=cpl_image_get_data_float(lineImage);
03343
03344 if ( NULL == sinfo_slit_pos )
03345 {
03346 sinfo_msg_error(" no position array allocated!" ) ;
03347 return -1 ;
03348 }
03349
03350 if ( box_length < 4 ||
03351 box_length > 2*slit_length )
03352 {
03353 sinfo_msg_error(" wrong fitting box length given!" ) ;
03354 sinfo_msg_error(" Must be 4 <= box_length < %d ",2*slit_length ) ;
03355 sinfo_msg_error(" You have chosen box_length = %d",box_length);
03356
03357
03358 return -1 ;
03359 }
03360
03361 if ( y_box <= 0. || y_box > 6. )
03362 {
03363 sinfo_msg_error("wrong y box length given!" ) ;
03364 sinfo_msg_error("You have chosen y_box=%f not in range (0,6]!",y_box);
03365 return -1 ;
03366 }
03367 if ( diff_tol <= 0. )
03368 {
03369 sinfo_msg_error(" wrong diff_tol given!" ) ;
03370 return -1 ;
03371 }
03372
03373 if ( low_pos >= high_pos || low_pos < 0 ||
03374 high_pos <= 0 || high_pos > ily )
03375 {
03376 sinfo_msg_error(" wrong user given search positions!" ) ;
03377 return -1 ;
03378 }
03379
03380
03381 position=cpl_calloc(ilx,sizeof(int)) ;
03382
03383 for ( col = 0 ; col < ilx ; col++ )
03384 {
03385 found_row = -1 ;
03386 maxval = -FLT_MAX ;
03387 for ( row = low_pos ; row <= high_pos ; row++ )
03388 {
03389 if ( maxval < pidata[col+row*ilx] )
03390 {
03391 maxval = pidata[col+row*ilx] ;
03392 found_row = row ;
03393 }
03394 }
03395 if ( maxval > -FLT_MAX && found_row > low_pos )
03396 {
03397 position[col] = found_row ;
03398 }
03399 else
03400 {
03401 position[col] = 0 ;
03402 }
03403 }
03404
03405
03406
03407
03408
03409
03410 for ( j = 0 ; j < slit_length ; j++ )
03411 {
03412
03413
03414
03415 n = 0 ;
03416 for ( col = sinfo_new_nint(sinfo_slit_pos[j][0])+ 1 ;
03417 col < sinfo_new_nint(sinfo_slit_pos[j][1]) -1 ; col++ )
03418 {
03419 rowpos[n] = (pixelvalue)position[col] ;
03420 n++ ;
03421 }
03422 slitposition[j] = (int)sinfo_new_median(rowpos, n) ;
03423 for ( left_right = 0 ; left_right <= 1 ; left_right++ )
03424
03425 {
03426 init1 = 0 ;
03427 col_first = sinfo_new_nint( sinfo_slit_pos[j][left_right] ) -
03428 box_length/2 ;
03429 col_last = sinfo_new_nint( sinfo_slit_pos[j][left_right] ) +
03430 box_length/2 ;
03431 if ( col_first < 0 )
03432 {
03433 col_first = 0 ;
03434 init1 = 1 ;
03435 }
03436 if ( col_last > ilx )
03437 {
03438 col_last = ilx ;
03439 init1 = 1 ;
03440 }
03441 if ( col_last - col_first <= 0 )
03442 {
03443 sinfo_msg_error(" first and last column wrong!" ) ;
03444 return -1 ;
03445 }
03446 box_buffer = sinfo_new_vector( col_last - col_first ) ;
03447 m = 0 ;
03448 if ( left_right == 0 )
03449 {
03450 for( col = col_first ; col < col_last ; col++ )
03451 {
03452 row_first = slitposition[j] - sinfo_new_nint(y_box) ;
03453 row_last = slitposition[j] + sinfo_new_nint(y_box) ;
03454 if ( row_first < 0 )
03455 {
03456 row_first = 0 ;
03457 }
03458 if ( row_last >= ily )
03459 {
03460 row_last = ily - 1 ;
03461 }
03462 maxval = -FLT_MAX ;
03463 for ( row = row_first ; row <= row_last ; row++ )
03464 {
03465 if ( maxval < pidata[col + ilx*row] )
03466 {
03467 maxval = pidata[col + ilx*row] ;
03468 }
03469 }
03470 box_buffer->data[m] = maxval ;
03471 m++ ;
03472 }
03473 }
03474 else
03475 {
03476 for( col = col_last-1 ; col >= col_first ; col-- )
03477 {
03478 row_first = slitposition[j] - sinfo_new_nint(y_box) ;
03479 row_last = slitposition[j] + sinfo_new_nint(y_box) ;
03480 if ( row_first < 0 )
03481 {
03482 row_first = 0 ;
03483 }
03484 if ( row_last >= ily )
03485 {
03486 row_last = ily - 1 ;
03487 }
03488 maxval = -FLT_MAX ;
03489 for ( row = row_first ; row <= row_last ; row++ )
03490 {
03491 if ( maxval < pidata[col + ilx*row] )
03492 {
03493 maxval = pidata[col + ilx*row] ;
03494 }
03495 }
03496 box_buffer->data[m] = maxval ;
03497 m++ ;
03498 }
03499 }
03500
03501 xdat=(float *)cpl_calloc( box_buffer->n_elements, sizeof (float));
03502 wdat=(float *)cpl_calloc( box_buffer->n_elements, sizeof (float));
03503 mpar=(int *) cpl_calloc( NPAR, sizeof (int) ) ;
03504
03505
03506 minval = FLT_MAX ;
03507 maxval = -FLT_MAX ;
03508 for ( i = 0 ; i < box_buffer->n_elements ; i++ )
03509 {
03510 xdat[i] = i ;
03511 wdat[i] = 1.0 ;
03512 if ( box_buffer -> data[i] < minval )
03513 {
03514 minval = box_buffer -> data[i] ;
03515 }
03516 if ( box_buffer -> data[i] > maxval )
03517 {
03518 maxval = box_buffer -> data[i] ;
03519 }
03520 }
03521 fitpar[2] = minval ;
03522 fitpar[3] = maxval ;
03523
03524
03525
03526
03527
03528
03529 if ( init1 == 1 )
03530 {
03531 n_buf = box_buffer->n_elements + box_length/2 ;
03532 in_buffer = sinfo_new_vector( n_buf ) ;
03533 for ( i = 0 ; i < box_length/2 ; i++ )
03534 {
03535 in_buffer -> data[i] = minval ;
03536 }
03537 shift = 0 ;
03538 for ( i = box_length/2 ; i < n_buf ; i++ )
03539 {
03540 in_buffer -> data[i] = box_buffer -> data[shift] ;
03541 shift++ ;
03542 }
03543 sinfo_new_destroy_vector ( box_buffer ) ;
03544 box_buffer = sinfo_new_vector ( n_buf ) ;
03545 for ( i = 0 ; i < n_buf ; i++ )
03546 {
03547 box_buffer -> data[i] = in_buffer -> data[i] ;
03548 }
03549 sinfo_new_destroy_vector ( in_buffer ) ;
03550 }
03551
03552 fitpar[0] = (float)box_buffer->n_elements/2. - 1. ;
03553 fitpar[1] = (float)box_buffer->n_elements/2. + 1. ;
03554
03555 for ( i = 0 ; i < NPAR ; i++ )
03556 {
03557 mpar[i] = 1 ;
03558 dervpar[i] = 0. ;
03559 }
03560
03561 xdim = XDIMA ;
03562 ndat = box_buffer->n_elements ;
03563 numpar = NPAR ;
03564 tol = TOLA ;
03565 lab = LABA ;
03566 its = ITSA ;
03567
03568
03569 if ( 0 > ( iters = sinfo_new_lsqfit_edge( xdat, &xdim,
03570 box_buffer -> data,
03571 wdat, &ndat, fitpar,
03572 dervpar, mpar, &numpar,
03573 &tol, &its, &lab )) )
03574 {
03575 sinfo_msg_warning (" least squares fit failed, error "
03576 "no.: %d in slitlet: %d\n", iters, j) ;
03577 sinfo_new_destroy_vector(box_buffer) ;
03578 cpl_free( xdat ) ;
03579 cpl_free( wdat ) ;
03580 cpl_free( mpar ) ;
03581 continue ;
03582 }
03583 if ( fitpar[1] <= fitpar[0] )
03584 {
03585 sinfo_msg_warning ("fit failed due to negative slope of "
03586 "sinfo_new_edge function in slitlet: %d",j);
03587 sinfo_new_destroy_vector(box_buffer) ;
03588 cpl_free( xdat ) ;
03589 cpl_free( wdat ) ;
03590 cpl_free( mpar ) ;
03591 continue ;
03592 }
03593
03594 pos = (fitpar[0] + fitpar[1])/2. ;
03595 if ( init1 == 1 )
03596 {
03597 pos -= (float)box_length/2. ;
03598 }
03599
03600
03601
03602
03603
03604
03605 if ( pos != 0. )
03606 {
03607 if ( left_right == 0 )
03608 {
03609 new_pos = (float)col_first + pos ;
03610 }
03611 else
03612 {
03613 new_pos = (float)col_last-1 - pos ;
03614 }
03615 if ( fabs(new_pos - sinfo_slit_pos[j][left_right]) < diff_tol )
03616 {
03617 sinfo_slit_pos[j][left_right] = new_pos ;
03618 }
03619 else
03620 {
03621 sinfo_msg_warning (" deviation bigger than tolerance,"
03622 " take the estimated slitlet positiona"
03623 " in slitlet: %d\n", j) ;
03624 }
03625 }
03626
03627 cpl_free( xdat ) ;
03628 cpl_free( wdat ) ;
03629 cpl_free( mpar ) ;
03630 sinfo_new_destroy_vector ( box_buffer ) ;
03631 }
03632 }
03633 cpl_free(position);
03634 return 0 ;
03635 }
03636
03637