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 #ifdef HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029
00030
00036
00039
00040
00041
00042
00043
00044 #include <xsh_error.h>
00045 #include <xsh_msg.h>
00046 #include <xsh_utils.h>
00047 #include <xsh_dfs.h>
00048 #include <tests.h>
00049 #include <cpl.h>
00050 #include <math.h>
00051 #include <getopt.h>
00052 #include <string.h>
00053
00054
00055
00056 #define MODULE_ID "XSH_CORRELATE_GAUSSIANS"
00057
00058 enum {
00059 DEBUG_OPT, HELP_OPT
00060 };
00061
00062 static struct option LongOptions[] = {
00063 {"debug", required_argument, 0, DEBUG_OPT},
00064 {"help", 0, 0, HELP_OPT},
00065 {NULL, 0, 0, 0}
00066 };
00067
00068 static void Help( void )
00069 {
00070 puts ("Unitary test : Create two Gaussians one shifted to the other of a given quantity, then correlate them to check if correlation returns expected shift");
00071 puts( "Usage : ./tetst_xsh_correl_gaussians [options]");
00072
00073 puts( "Options" ) ;
00074 puts( " --debug=<n> : Level of debug LOW | MEDIUM | HIGH [MEDIUM]" );
00075 puts( " --help : What you see" ) ;
00076
00077 puts( "The input files argument MUST be in this order:" );
00078 puts( " 1. PRE frame");
00079 puts( " 2. SOF a) MODEL : [XSH_MOD_CFG_TAB_UVB]");
00080 puts( " b) POLYNOMIAL: [DISP_TAB, ORDER_TAB_EDGES]");
00081
00082 TEST_END();
00083 exit(0);
00084 }
00085
00086 static void HandleOptions( int argc, char ** argv)
00087 {
00088 int opt ;
00089 int option_index = 0;
00090
00091 while( (opt = getopt_long( argc, argv, "debug:help",
00092 LongOptions, &option_index )) != EOF){
00093 switch( opt ) {
00094 case DEBUG_OPT:
00095 if ( strcmp( optarg, "LOW")==0){
00096 xsh_debug_level_set( XSH_DEBUG_LEVEL_LOW);
00097 }
00098 else if ( strcmp( optarg, "HIGH")==0){
00099 xsh_debug_level_set( XSH_DEBUG_LEVEL_HIGH);
00100 }
00101 break;
00102 case HELP_OPT:
00103 Help();
00104 break;
00105 default:
00106 break;
00107 }
00108 }
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 static double
00123 xsh_correlate_profiles2(const double* prof1, const double* prof2,
00124 double* correl,const int length, const int hsize) {
00125
00126 XSH_ASSURE_NOT_NULL_MSG(prof1,"NULL input prof1");
00127 XSH_ASSURE_NOT_NULL_MSG(prof2,"NULL input prof2");
00128 XSH_ASSURE_NOT_NULL_MSG(correl,"NULL input correl");
00129 XSH_ASSURE_NOT_ILLEGAL_MSG(length>2*hsize,"length<=2*hsize");
00130
00131 double *profile1 = cpl_calloc(length, sizeof(double));
00132 double *profile2 = cpl_calloc(length, sizeof(double));
00133 int i=0;
00134 double norm=0;
00135
00136
00137
00138
00139
00140
00141 for (i = 0; i < length; i++)
00142 if (norm < prof1[i]){
00143 norm = prof1[i];
00144
00145 }
00146 if (norm < prof2[i]){
00147 norm = prof2[i];
00148
00149 }
00150
00151 for (i = 0; i < length; i++) {
00152 profile1[i] = prof1[i]/norm;
00153 profile2[i] = prof2[i]/norm;
00154
00155
00156 }
00157 int short_length = length - 2*hsize - 1;
00158 xsh_msg("mk4 short_len=%d",short_length);
00159
00160
00161
00162
00163
00164 int step_min=-hsize;
00165 int step_max=+hsize;
00166 int nsteps=step_max-step_min+1;
00167 double max=0;
00168 double value=0;
00169 int maxpos=0;
00170 int j=0;
00171 int k=0;
00172
00173 max = -1;
00174 for (i = step_min; i <= step_max; i++) {
00175 value = 0;
00176 for (j = 0; j < length; j++) {
00177 k=i-step_min;
00178 value += profile1[k] * profile2[k+j];
00179 }
00180 correl[i-step_min]=value;
00181
00182 if (max < value) {
00183
00184 max = value;
00185 maxpos = i;
00186 }
00187 }
00188 max=-1;
00189 for (i=0 ; i<nsteps ; i++) {
00190 if (correl[i]>max) {
00191 maxpos = i ;
00192 max = correl[i];
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201 xsh_msg("correl max[%d]=%g",maxpos,max);
00202 xsh_msg("nsteps %d",nsteps);
00203
00204 double a=correl[maxpos-1];
00205 double b=correl[maxpos+1];
00206 double c=correl[maxpos];
00207 double fraction=(a-b)/(2.*a+2.*b-4.*c);
00208 double shift=0;
00209 xsh_msg("fraction=%g",fraction);
00210 shift=maxpos+fraction;
00211 cleanup:
00212 cpl_free(profile1);
00213 cpl_free(profile2);
00214
00215 return shift;
00216
00217 }
00218
00219
00220 static double
00221 xsh_correlate_profiles(const double* prof1, const double* prof2,
00222 double* correl,const int length, const int hsize) {
00223
00224 int short_length = length - 2*hsize - 1;
00225 int i=0;
00226 int j=0;
00227 int k=0;
00228 double shift=0;
00229 int maxpos=0;
00230 double norm=0;
00231 double max=0;
00232 double value=0;
00233
00234 double *profile1 = cpl_calloc(length, sizeof(double));
00235 double *profile2 = cpl_calloc(length, sizeof(double));
00236
00237
00238
00239
00240
00241
00242 for (i = 0; i < length; i++)
00243 if (norm < prof1[i]){
00244 norm = prof1[i];
00245
00246 }
00247 if (norm < prof2[i]){
00248 norm = prof2[i];
00249
00250 }
00251
00252 for (i = 0; i < length; i++) {
00253 profile1[i] = prof1[i]/norm;
00254 profile2[i] = prof2[i]/norm;
00255
00256
00257 }
00258 xsh_msg("mk4 short_len=%d",short_length);
00259
00260
00261
00262
00263
00264 max = -11;
00265 for (i = 0; i <= hsize; i++) {
00266 value = 0;
00267 for (j = 0; j < short_length; j++) {
00268 k = hsize+j;
00269 value += profile1[k] * profile2[k+i];
00270 }
00271 correl[i]=value;
00272
00273 if (max < value) {
00274
00275 max = value;
00276 maxpos = i;
00277 }
00278 }
00279
00280
00281
00282
00283
00284 xsh_msg("correl max[%d]=%g",maxpos,max);
00285 cpl_free(profile1);
00286 cpl_free(profile2);
00287
00288 double a=correl[maxpos-1];
00289 double b=correl[maxpos+1];
00290 double c=correl[maxpos];
00291 double fraction=(a-b)/(2.*a+2.*b-4.*c);
00292 xsh_msg("fraction=%g",fraction);
00293 shift=maxpos+fraction;
00294
00295 return shift;
00296
00297 }
00298
00299
00300
00301 static double
00302 xsh_function1d_xcorrelate2(
00303 double * line_i,
00304 int width_i,
00305 double * line_t,
00306 int width_t,
00307 int half_search,
00308 double * delta
00309 )
00310 {
00311 double * xcorr ;
00312 double xcorr_max ;
00313 double mean_i, mean_t ;
00314 double rms_i, rms_t ;
00315 double sum, sqsum ;
00316 double norm ;
00317 int maxpos ;
00318 int nsteps ;
00319 int i ;
00320 int step ;
00321 int nval ;
00322 int STEP_MIN=-half_search;
00323 int STEP_MAX=half_search;
00324
00325
00326
00327
00328 for (i = 0; i < width_i; i++)
00329 if (norm < line_i[i]){
00330 norm = line_i[i];
00331
00332 }
00333
00334 for (i = 0; i < width_t; i++)
00335 if (norm < line_t[i]){
00336 norm = line_t[i];
00337
00338 }
00339
00340 for (i = 0; i < width_i; i++) {
00341 line_i[i] /= norm;
00342 line_t[i] /= norm;
00343 }
00344
00345 for (i = 0; i < width_t; i++) {
00346 line_t[i] /= norm;
00347 }
00348
00349
00350
00351 nsteps = (STEP_MAX - STEP_MIN) +1 ;
00352 xcorr = cpl_malloc(nsteps * sizeof(double));
00353 for (step=STEP_MIN ; step<=STEP_MAX ; step++) {
00354 xcorr[step-STEP_MIN] = 0.00 ;
00355 nval = 0 ;
00356 for (i=0 ; i<width_t ; i++) {
00357 if ((i+step > 0) &&
00358 (i+step < width_i)) {
00359 xcorr[step-STEP_MIN] += line_t[i] * line_i[i+step];
00360 nval++ ;
00361 }
00362 }
00363 xcorr[step-STEP_MIN] /= (double) nval ;
00364 }
00365 xcorr_max = xcorr[0] ;
00366 maxpos = 0 ;
00367 for (i=0 ; i<nsteps ; i++) {
00368 if (xcorr[i]>xcorr_max) {
00369 maxpos = i ;
00370 xcorr_max = xcorr[i];
00371 }
00372 }
00373 cpl_vector* vcor=cpl_vector_wrap(nsteps,xcorr);
00374 double a=xcorr[maxpos-1];
00375 double b=xcorr[maxpos+1];
00376 double c=xcorr[maxpos];
00377 double fraction=(a-b)/(2.*a+2.*b-4.*c);
00378 cpl_vector_save(vcor,"vcor.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00379 cpl_vector_unwrap(vcor);
00380 cpl_free(xcorr);
00381 xsh_msg("STEP_MIN=%d maxpos=%d",STEP_MIN,maxpos);
00382 (*delta) = (double)STEP_MIN + (double)maxpos;
00383 xsh_msg("a=%g b=%g c=%g fraction=%g",a,b,c,fraction);
00384 xsh_msg("maxpos=%d width_i=%d",maxpos,width_i);
00385 xsh_msg("fractionary delta=%g",*delta+fraction);
00386 return xcorr_max ;
00387 }
00388
00389
00390
00391
00392
00393 cpl_error_code
00394 xsh_gauss_gen(double* data,const double center,const double sigma, const int size)
00395 {
00396
00397 int i=0;
00398 double x=0;
00399 double inv_2_c2=0.5/sigma/sigma;
00400 double norm=sigma*sqrt(2*CPL_MATH_PI);
00401 double a=1./norm;
00402
00403 for(i=0;i<size;i++) {
00404 x=i;
00405 data[i]=a*exp(-(x-center)*(x-center)*inv_2_c2);
00406 }
00407
00408 return cpl_error_get_code();
00409 }
00410
00411
00412
00413
00414
00415
00422
00423
00424 int main( int argc, char** argv)
00425 {
00426
00427 TESTS_INIT( MODULE_ID);
00428 cpl_msg_set_level( CPL_MSG_DEBUG);
00429 xsh_debug_level_set( XSH_DEBUG_LEVEL_MEDIUM) ;
00430
00431 HandleOptions( argc, argv);
00432
00433
00434 if ( (argc-optind) >= 2) {
00435 Help();
00436 }
00437
00438 int ret=0;
00439 double shift_i=5.15;
00440 double shift_o=0;
00441 double gauss_c=50.;
00442 double gauss_s=10.;
00443 double* gauss_d1=NULL;
00444 double* gauss_d2=NULL;
00445
00446 int size=100;
00447 cpl_vector* gauss_v1=cpl_vector_new(size);
00448 cpl_vector* gauss_v2=cpl_vector_new(size);
00449
00450 gauss_d1=cpl_vector_get_data(gauss_v1);
00451 gauss_d2=cpl_vector_get_data(gauss_v2);
00452
00453 check(xsh_gauss_gen(gauss_d1,gauss_c,gauss_s,size));
00454 check(xsh_gauss_gen(gauss_d2,gauss_c+shift_i,gauss_s,size));
00455
00456
00457 int half_search=(int)(2*gauss_s+1);
00458
00459
00460 int len_corr=199;
00461
00462
00463
00464 double corr=0;
00465 corr=xsh_function1d_xcorrelate2(gauss_d1,size,gauss_d2,size,half_search,&shift_o);
00466 xsh_msg("function1d corerel: shift %g",shift_o);
00467
00468 double moses_shift=0;
00469 double* moses_correl=NULL;
00470
00471 moses_correl = cpl_calloc(len_corr, sizeof(double));
00472 check(moses_shift=xsh_correlate_profiles2(gauss_d1, gauss_d2,moses_correl,size,half_search));
00473 xsh_msg("moses_shift=%g",moses_shift);
00474 cpl_vector* mc=cpl_vector_wrap(len_corr,moses_correl);
00475 cpl_vector_save(mc,"moses_correl.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00476 xsh_free_vector(&mc);
00477
00478 cpl_vector_save(gauss_v1,"gauss_v1.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00479 cpl_vector_save(gauss_v2,"gauss_v2.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00480
00481
00482
00483
00484
00485
00486 cpl_vector* correl=cpl_vector_new(len_corr);
00487 double shift=cpl_vector_correlate(correl,gauss_v1,gauss_v2);
00488
00489 cpl_vector_save(correl,"correl.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
00490 xsh_msg("shift=%g",shift);
00491
00492 int maxpos=(int)(shift-1);
00493 xsh_msg("correl max=%g",cpl_vector_get(correl,shift));
00494 xsh_msg( "Shift: expected: %g computed: %g accuracy:%g ",
00495 shift_i,shift_o,fabs((shift_i-shift_o)/shift_i));
00496 double max=0;
00497
00498 check(max = cpl_vector_get_max(correl));
00499
00500 xsh_msg("max=%g maxpos=%d",max,maxpos);
00501 double* pvec=NULL;
00502 pvec=cpl_vector_get_data(correl);
00503 max=-100;
00504 int i=0;
00505 for(i=1;i<len_corr;i++) {
00506 if(max<pvec[i] ) {
00507 max=pvec[i];
00508 maxpos=i;
00509 }
00510 }
00511 xsh_msg("maxpos my determination: %d",maxpos);
00512
00513 double a=0;
00514 double b=0;
00515 double c=0;
00516 double fraction=0;
00517
00518 a=cpl_vector_get(correl,maxpos-1);
00519 b=cpl_vector_get(correl,maxpos+1);
00520 c=cpl_vector_get(correl,maxpos);
00521 fraction=(a-b)/(2.*a+2.*b-4.*c);
00522 xsh_msg("len_corr=%d",len_corr);
00523 xsh_msg("a=%g b=%g c=%g fraction=%g",a,b,c,fraction);
00524
00525
00526
00527 cleanup:
00528 xsh_free_vector(&gauss_v1);
00529 xsh_free_vector(&gauss_v2);
00530 xsh_free_vector(&correl);
00531
00532
00533 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00534 xsh_error_dump( CPL_MSG_ERROR);
00535 ret=1;
00536 }
00537 TEST_END();
00538 return ret;
00539 }
00540