X-shooter Pipeline Reference Manual 3.8.15
test-xsh_correl_gaussians.c
Go to the documentation of this file.
1/* *
2 * This file is part of the ESO X-shooter Pipeline *
3 * Copyright (C) 2006 European Southern Observatory *
4 * *
5 * This library is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18 * */
19
20/*
21 * $Author: amodigli $
22 * $Date: 2012-10-16 15:31:47 $
23 * $Revision: 1.3 $
24 * $Name: not supported by cvs2svn $
25 */
26#ifdef HAVE_CONFIG_H
27# include <config.h>
28#endif
29
30/*--------------------------------------------------------------------------*/
36/*--------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------
40 Includes
41 ---------------------------------------------------------------------------*/
42
43
44#include <xsh_error.h>
45#include <xsh_msg.h>
46#include <xsh_utils.h>
47#include <xsh_dfs.h>
48#include <tests.h>
49#include <cpl.h>
50#include <math.h>
51#include <getopt.h>
52#include <string.h>
53/*---------------------------------------------------------------------------
54 Defines
55 ---------------------------------------------------------------------------*/
56#define MODULE_ID "XSH_CORREL_GAUSSIANS"
57
58enum {
60};
61
62static struct option LongOptions[] = {
63 {"debug", required_argument, 0, DEBUG_OPT},
64 {"help", 0, 0, HELP_OPT},
65 {NULL, 0, 0, 0}
66};
67
68static void Help( void )
69{
70 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");
71 puts( "Usage : ./tetst_xsh_correl_gaussians [options]");
72
73 puts( "Options" ) ;
74 puts( " --debug=<n> : Level of debug LOW | MEDIUM | HIGH [MEDIUM]" );
75 puts( " --help : What you see" ) ;
76
77 puts( "The input files argument MUST be in this order:" );
78 puts( " 1. PRE frame");
79 puts( " 2. SOF a) MODEL : [XSH_MOD_CFG_TAB_UVB]");
80 puts( " b) POLYNOMIAL: [DISP_TAB, ORDER_TAB_EDGES]");
81
83 TEST_END();
84 exit(0);
85}
86
87static void HandleOptions( int argc, char ** argv)
88{
89 int opt ;
90 int option_index = 0;
91
92 while( (opt = getopt_long( argc, argv, "debug:help",
93 LongOptions, &option_index )) != EOF){
94 switch( opt ) {
95 case DEBUG_OPT:
96 if ( strcmp( optarg, "LOW")==0){
98 }
99 else if ( strcmp( optarg, "HIGH")==0){
101 }
102 break;
103 case HELP_OPT:
104 Help();
105 break;
106 default:
107 break;
108 }
109 }
110}
111
112/*
113static double
114xsh_correlate_julian(const double* prof1, const double* prof2,
115 double* correl,const int , const int hsize) {
116
117
118 double *correl = cpl_calloc(length, sizeof(double));
119 for(i=
120
121}
122*/
123static double
124xsh_correlate_profiles2(const double* prof1, const double* prof2,
125 double* correl,const int length, const int hsize) {
126
127 XSH_ASSURE_NOT_NULL_MSG(prof1,"NULL input prof1");
128 XSH_ASSURE_NOT_NULL_MSG(prof2,"NULL input prof2");
129 XSH_ASSURE_NOT_NULL_MSG(correl,"NULL input correl");
130 XSH_ASSURE_NOT_ILLEGAL_MSG(length>2*hsize,"length<=2*hsize");
131
132 double *profile1 = cpl_calloc(length, sizeof(double));
133 double *profile2 = cpl_calloc(length, sizeof(double));
134 memset( profile1,0,length);
135 memset( profile2,0,length);
136
137 int i=0;
138 double norm=0;
139
140 /*
141 * Profiles normalisation
142 */
143
144
145 for (i = 0; i < length; i++)
146 if (norm < prof1[i]){
147 norm = prof1[i];
148 //xsh_msg("found norm: %g",norm);
149 }
150 if (i < length && norm < prof2[i]){
151 norm = prof2[i];
152 //xsh_msg("found norm: %g",norm);
153 }
154
155 for (i = 0; i < length; i++) {
156 profile1[i] = prof1[i]/norm;
157 profile2[i] = prof2[i]/norm;
158 //xsh_msg("profile1[%d]: %g",i,profile1[i]);
159 //xsh_msg("profile2[%d]: %g",i,profile2[i]);
160 }
161 int short_length = length - 2*hsize - 1;
162 xsh_msg("mk4 short_len=%d",short_length);
163
164 /*
165 * Cross-correlation
166 */
167
168 int step_min=-hsize;
169 int step_max=+hsize;
170 int nsteps=step_max-step_min+1;
171 double max=0;
172 double value=0;
173 int maxpos=0;
174 int j=0;
175 int k=0;
176
177 max = -1;
178 for (i = step_min; i <= step_max; i++) {
179 value = 0;
180 k=i-step_min;
181 if (k >= length) break;
182 for (j = 0; j < length && k+j < length; j++) {
183 value += profile1[k] * profile2[k+j];
184 }
185 correl[k]=value;
186 //xsh_msg("correl value: %g",value);
187 if (max < value) {
188 //xsh_msg("found max: %g",max);
189 max = value;
190 maxpos = i;
191 }
192 }
193 max=-1;
194 for (i=0 ; i<nsteps ; i++) {
195 if (correl[i]>max) {
196 maxpos = i ;
197 max = correl[i];
198 }
199 }
200
201
202
203 /*
204 * search for correlation maximum
205 */
206 xsh_msg("correl max[%d]=%g",maxpos,max);
207 xsh_msg("nsteps %d",nsteps);
208
209 double a=correl[maxpos-1];
210 double b=correl[maxpos+1];
211 double c=correl[maxpos];
212 double fraction=(a-b)/(2.*a+2.*b-4.*c);
213 double shift=0;
214 xsh_msg("fraction=%g",fraction);
215 shift=maxpos+fraction;
216 cleanup:
217 cpl_free(profile1);
218 cpl_free(profile2);
219
220 return shift;
221
222}
223
224/*
225static double
226xsh_correlate_profiles(const double* prof1, const double* prof2,
227 double* correl,const int length, const int hsize) {
228
229 int short_length = length - 2*hsize - 1;
230 int i=0;
231 int j=0;
232 int k=0;
233 double shift=0;
234 int maxpos=0;
235 double norm=0;
236 double max=0;
237 double value=0;
238
239 double *profile1 = cpl_calloc(length, sizeof(double));
240 double *profile2 = cpl_calloc(length, sizeof(double));
241
242
243 // Profiles normalisation
244
245
246
247 for (i = 0; i < length; i++)
248 if (norm < prof1[i]){
249 norm = prof1[i];
250 //xsh_msg("found norm: %g",norm);
251 }
252 if (norm < prof2[i]){
253 norm = prof2[i];
254 //xsh_msg("found norm: %g",norm);
255 }
256
257 for (i = 0; i < length; i++) {
258 profile1[i] = prof1[i]/norm;
259 profile2[i] = prof2[i]/norm;
260 //xsh_msg("profile1[%d]: %g",i,profile1[i]);
261 //xsh_msg("profile2[%d]: %g",i,profile2[i]);
262 }
263 xsh_msg("mk4 short_len=%d",short_length);
264
265
266 // Cross-correlation
267
268
269 max = -11;
270 for (i = 0; i <= hsize; i++) {
271 value = 0;
272 for (j = 0; j < short_length; j++) {
273 k = hsize+j;
274 value += profile1[k] * profile2[k+i];
275 }
276 correl[i]=value;
277 //xsh_msg("correl value: %g",value);
278 if (max < value) {
279 //xsh_msg("found max: %g",max);
280 max = value;
281 maxpos = i;
282 }
283 }
284
285
286
287 // search for correlation maximum
288
289 xsh_msg("correl max[%d]=%g",maxpos,max);
290 cpl_free(profile1);
291 cpl_free(profile2);
292
293 double a=correl[maxpos-1];
294 double b=correl[maxpos+1];
295 double c=correl[maxpos];
296 double fraction=(a-b)/(2.*a+2.*b-4.*c);
297 xsh_msg("fraction=%g",fraction);
298 shift=maxpos+fraction;
299
300 return shift;
301
302}
303*/
304
305
306static double
308 double * line_i,
309 int width_i,
310 double * line_t,
311 int width_t,
312 int half_search,
313 double * delta
314 )
315{
316 double * xcorr ;
317 double xcorr_max ;
318 //double mean_i, double mean_t ;
319 //double rms_i, rms_t ;
320 //double sum, sqsum ;
321 double norm = 0;
322 int maxpos ;
323 int nsteps ;
324 int i ;
325 int step ;
326 int nval ;
327 int STEP_MIN=-half_search;
328 int STEP_MAX=half_search;
329
330
331 /* Compute normalization factors */
332
333 for (i = 0; i < width_i; i++)
334 if (norm < line_i[i]){
335 norm = line_i[i];
336 //xsh_msg("found norm: %g",norm);
337 }
338
339 for (i = 0; i < width_t; i++)
340 if (norm < line_t[i]){
341 norm = line_t[i];
342 //xsh_msg("found norm: %g",norm);
343 }
344
345 for (i = 0; i < width_i; i++) {
346 line_i[i] /= norm;
347 line_t[i] /= norm;
348 }
349
350 for (i = 0; i < width_t; i++) {
351 line_t[i] /= norm;
352 }
353
354
355 /* compute cross correlation */
356 nsteps = (STEP_MAX - STEP_MIN) +1 ;
357 xcorr = cpl_malloc(nsteps * sizeof(double));
358 for (step=STEP_MIN ; step<=STEP_MAX ; step++) {
359 xcorr[step-STEP_MIN] = 0.00 ;
360 nval = 0 ;
361 for (i=0 ; i<width_t ; i++) {
362 if ((i+step > 0) &&
363 (i+step < width_i)) {
364 xcorr[step-STEP_MIN] += line_t[i] * line_i[i+step];
365 nval++ ;
366 }
367 }
368 xcorr[step-STEP_MIN] /= (double) nval ;
369 }
370 xcorr_max = xcorr[0] ;
371 maxpos = 0 ;
372 for (i=0 ; i<nsteps ; i++) {
373 if (xcorr[i]>xcorr_max) {
374 maxpos = i ;
375 xcorr_max = xcorr[i];
376 }
377 }
378 cpl_vector* vcor=cpl_vector_wrap(nsteps,xcorr);
379 double a=xcorr[maxpos-1];
380 double b=xcorr[maxpos+1];
381 double c=xcorr[maxpos];
382 double fraction=(a-b)/(2.*a+2.*b-4.*c);
383 cpl_vector_save(vcor,"vcor.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
384 cpl_vector_unwrap(vcor);
385 cpl_free(xcorr);
386 xsh_msg("STEP_MIN=%d maxpos=%d",STEP_MIN,maxpos);
387 (*delta) = (double)STEP_MIN + (double)maxpos;
388 xsh_msg("a=%g b=%g c=%g fraction=%g",a,b,c,fraction);
389 xsh_msg("maxpos=%d width_i=%d",maxpos,width_i);
390 xsh_msg("fractionary delta=%g",*delta+fraction);
391 return xcorr_max ;
392}
393
394
395
396
397
398cpl_error_code
399xsh_gauss_gen(double* data,const double center,const double sigma, const int size)
400{
401
402 int i=0;
403 double x=0;
404 double inv_2_c2=0.5/sigma/sigma;
405 double norm=sigma*sqrt(2*CPL_MATH_PI);
406 double a=1./norm;
407
408 for(i=0;i<size;i++) {
409 x=i;
410 data[i]=a*exp(-(x-center)*(x-center)*inv_2_c2);
411 }
412
413 return cpl_error_get_code();
414}
415
416/*---------------------------------------------------------------------------
417 Functions prototypes
418 ---------------------------------------------------------------------------*/
419
420/*--------------------------------------------------------------------------*/
427/*--------------------------------------------------------------------------*/
428
429int main( int argc, char** argv)
430{
431 /* Initialize libraries */
434 cpl_msg_set_level( CPL_MSG_DEBUG);
436
437 HandleOptions( argc, argv);
438
439 /* Analyse parameters */
440 if ( (argc-optind) >= 2) {
441 Help();
442 }
443
444 int ret=0;
445 double shift_i=5.15;
446 double shift_o=0;
447 double gauss_c=50.;
448 double gauss_s=10.;
449 double* gauss_d1=NULL;
450 double* gauss_d2=NULL;
451
452 int size=100;
453 cpl_vector* gauss_v1=cpl_vector_new(size);
454 cpl_vector* gauss_v2=cpl_vector_new(size);
455
456 gauss_d1=cpl_vector_get_data(gauss_v1);
457 gauss_d2=cpl_vector_get_data(gauss_v2);
458
459 check(xsh_gauss_gen(gauss_d1,gauss_c,gauss_s,size));
460 check(xsh_gauss_gen(gauss_d2,gauss_c+shift_i,gauss_s,size));
461
462
463 int half_search=(int)(2*gauss_s+1);
464 //half_search=7;
465 //int len_corr=1+2*half_search;
466 int len_corr=199;
467
468
469
470 double corr=0;
471 corr=xsh_function1d_xcorrelate2(gauss_d1,size,gauss_d2,size,half_search,&shift_o);
472 xsh_msg("function1d corerel: shift %g",shift_o);
473
474 double moses_shift=0;
475 double* moses_correl=NULL;
476
477 moses_correl = cpl_calloc(len_corr, sizeof(double));
478 check(moses_shift=xsh_correlate_profiles2(gauss_d1, gauss_d2,moses_correl,size,half_search));
479 xsh_msg("moses_shift=%g",moses_shift);
480 cpl_vector* mc=cpl_vector_wrap(len_corr,moses_correl);
481 cpl_vector_save(mc,"moses_correl.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
482 xsh_free_vector(&mc);
483
484 cpl_vector_save(gauss_v1,"gauss_v1.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
485 cpl_vector_save(gauss_v2,"gauss_v2.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
486
487
488
489
490 /* CPL VECTOR */
491
492 cpl_vector* correl=cpl_vector_new(len_corr);
493 check(cpl_vector_fill(correl, 0.0));
494 double shift=cpl_vector_correlate(correl,gauss_v1,gauss_v2);
495
496 cpl_vector_save(correl,"correl.fits",CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
497 xsh_msg("shift=%g",shift);
498 //cpl_vector_dump(correl,stdout);
499 int maxpos=(int)(shift-1);
500 xsh_msg("correl max=%g",cpl_vector_get(correl,shift));
501 xsh_msg( "Shift: expected: %g computed: %g accuracy:%g ",
502 shift_i,shift_o,fabs((shift_i-shift_o)/shift_i));
503 double max=0;
504 //int maxpos=0;
505 check(max = cpl_vector_get_max(correl));
506 //check(maxpos=cpl_vector_find(correl,shift+1));
507 xsh_msg("max=%g maxpos=%d",max,maxpos);
508 double* pvec=NULL;
509 pvec=cpl_vector_get_data(correl);
510 max=-100;
511 int i=0;
512 for(i=1;i<len_corr;i++) {
513 if(max<pvec[i] ) {
514 max=pvec[i];
515 maxpos=i;
516 }
517 }
518 xsh_msg("maxpos my determination: %d",maxpos);
519
520 double a=0;
521 double b=0;
522 double c=0;
523 double fraction=0;
524 //maxpos +=1;
525 a=cpl_vector_get(correl,maxpos-1);
526 b=cpl_vector_get(correl,maxpos+1);
527 c=cpl_vector_get(correl,maxpos);
528 fraction=(a-b)/(2.*a+2.*b-4.*c);
529 xsh_msg("len_corr=%d",len_corr);
530 xsh_msg("a=%g b=%g c=%g fraction=%g",a,b,c,fraction);
531
532
533
534 cleanup:
535 xsh_free_vector(&gauss_v1);
536 xsh_free_vector(&gauss_v2);
537 xsh_free_vector(&correl);
538
539
540 if (cpl_error_get_code() != CPL_ERROR_NONE) {
541 xsh_error_dump( CPL_MSG_ERROR);
542 ret=1;
543 }
545 TEST_END();
546 return ret;
547}
548
int main()
Unit test of xsh_bspline_interpol.
static const double step
static double sigma
static void HandleOptions(int argc, char **argv)
static double xsh_correlate_profiles2(const double *prof1, const double *prof2, double *correl, const int length, const int hsize)
static double xsh_function1d_xcorrelate2(double *line_i, int width_i, double *line_t, int width_t, int half_search, double *delta)
cpl_error_code xsh_gauss_gen(double *data, const double center, const double sigma, const int size)
static void Help(void)
#define MODULE_ID
static struct option LongOptions[]
#define XSH_ASSURE_NOT_NULL_MSG(pointer, msg)
Definition: xsh_error.h:103
#define check(COMMAND)
Definition: xsh_error.h:71
#define xsh_error_dump(level)
Definition: xsh_error.h:92
#define XSH_ASSURE_NOT_ILLEGAL_MSG(cond, msg)
Definition: xsh_error.h:111
int size
int * x
#define xsh_msg(...)
Print a message on info level.
Definition: xsh_msg.h:121
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
Definition: xsh_utils.c:2284
int xsh_debug_level_set(int level)
set debug level
Definition: xsh_utils.c:3125
#define TESTS_CLEAN_WORKSPACE(DRL_ID)
Definition: tests.h:139
#define TESTS_INIT_WORKSPACE(DRL_ID)
Definition: tests.h:133
#define TEST_END()
Definition: tests.h:111
#define TESTS_INIT(DRL_ID)
Definition: tests.h:105
#define max(a, b)
@ XSH_DEBUG_LEVEL_HIGH
Definition: xsh_utils.h:138
@ XSH_DEBUG_LEVEL_LOW
Definition: xsh_utils.h:137
@ XSH_DEBUG_LEVEL_MEDIUM
Definition: xsh_utils.h:138