00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #include <math.h>
00037 #include <cpl.h>
00038
00039 #include "irplib_wlxcorr.h"
00040 #include "irplib_plot.h"
00041
00042
00047
00048
00049 static cpl_bivector * irplib_wlxcorr_gen_signal(const cpl_bivector *, double,
00050 double, const cpl_polynomial *, int, int, int *) ;
00051 static int irplib_wlxcorr_signal_resample(cpl_vector *, const cpl_vector *,
00052 const cpl_bivector *) ;
00053
00056
00076
00077 cpl_polynomial * irplib_wlxcorr_best_poly(
00078 const cpl_vector * spectrum,
00079 const cpl_bivector * lines_catalog,
00080 int degree,
00081 const cpl_polynomial * guess_poly,
00082 const cpl_vector * wl_error,
00083 int nsamples,
00084 double slitw,
00085 double fwhm,
00086 double * xc,
00087 cpl_table ** wlres,
00088 cpl_vector ** xcorrs)
00089 {
00090 int ntests ;
00091 int spec_sz ;
00092 cpl_polynomial ** candidates ;
00093 double xpos, wl_pos ;
00094 cpl_vector * init_pts_wl ;
00095 cpl_vector * init_pts_x ;
00096 cpl_vector * pts_wl ;
00097 cpl_vector * vxcorrs ;
00098 int best_ind ;
00099 cpl_polynomial * poly_sol ;
00100 cpl_table * spc_table ;
00101 double xc_cur ;
00102 cpl_vector * vxc ;
00103 cpl_bivector * gen_init ;
00104 double * pwl_error ;
00105 int i, j, k, l ;
00106
00107
00108 if (!spectrum || !lines_catalog || !guess_poly || !xc || !wl_error)
00109 return NULL;
00110 if (degree < 1 || degree > 3) return NULL ;
00111 if (cpl_vector_get_size(wl_error) != degree+1) return NULL ;
00112
00113
00114 ntests = (int)pow(nsamples, (degree + 1)) ;
00115 spec_sz = cpl_vector_get_size(spectrum) ;
00116 pwl_error = cpl_vector_get_data(wl_error) ;
00117 if (wlres != NULL) *wlres = NULL ;
00118 if (xcorrs != NULL) *xcorrs = NULL ;
00119
00120
00121 init_pts_x = cpl_vector_new(degree + 1) ;
00122 init_pts_wl = cpl_vector_new(degree + 1) ;
00123 for (i=0 ; i<degree + 1 ; i++) {
00124 xpos = i*spec_sz/degree ;
00125 cpl_vector_set(init_pts_x, i, xpos) ;
00126 cpl_vector_set(init_pts_wl, i,
00127 cpl_polynomial_eval_1d(guess_poly, xpos, NULL)) ;
00128 }
00129
00130
00131 candidates = cpl_malloc(ntests * sizeof(cpl_polynomial*)) ;
00132 pts_wl = cpl_vector_new(degree + 1) ;
00133 for (i=0 ; i<nsamples ; i++) {
00134 wl_pos = cpl_vector_get(init_pts_wl, 0)
00135 - pwl_error[0]/2 + i*pwl_error[0]/nsamples ;
00136 cpl_vector_set(pts_wl, 0, wl_pos) ;
00137 for (j=0 ; j<nsamples ; j++) {
00138 wl_pos = cpl_vector_get(init_pts_wl, 1)
00139 - pwl_error[1]/2 + j*pwl_error[1]/nsamples ;
00140 cpl_vector_set(pts_wl, 1, wl_pos) ;
00141 if (degree == 1) {
00142 candidates[j+i*nsamples] =
00143 cpl_polynomial_fit_1d_create(init_pts_x, pts_wl, degree,
00144 NULL);
00145 } else {
00146 for (k=0 ; k<nsamples ; k++) {
00147 wl_pos = cpl_vector_get(init_pts_wl, 2)
00148 - pwl_error[2]/2 + k*pwl_error[2]/nsamples ;
00149 cpl_vector_set(pts_wl, 2, wl_pos) ;
00150 if (degree == 2) {
00151 candidates[k+(j+i*nsamples)*nsamples] =
00152 cpl_polynomial_fit_1d_create(init_pts_x,
00153 pts_wl, degree, NULL);
00154 } else {
00155 for (l=0 ; l<nsamples ; l++) {
00156 wl_pos = cpl_vector_get(init_pts_wl, 3)
00157 - pwl_error[3]/2 + l*pwl_error[3]/nsamples ;
00158 cpl_vector_set(pts_wl, 3, wl_pos) ;
00159 if (degree == 3) {
00160 candidates[l+(k+(j+i*nsamples)*nsamples)*nsamples]=
00161 cpl_polynomial_fit_1d_create(init_pts_x,
00162 pts_wl, degree, NULL);
00163 } else {
00164
00165 }
00166 }
00167 }
00168 }
00169 }
00170 }
00171 }
00172 cpl_vector_delete(pts_wl) ;
00173 cpl_vector_delete(init_pts_x) ;
00174 cpl_vector_delete(init_pts_wl) ;
00175
00176
00177 best_ind = 0 ;
00178 *xc = -1 ;
00179 vxc = cpl_vector_new(1) ;
00180 vxcorrs = cpl_vector_new(ntests) ;
00181 for (i=0 ; i<ntests ; i++) {
00182
00183 if ((gen_init=irplib_wlxcorr_gen_signal(lines_catalog, slitw, fwhm,
00184 candidates[i], spec_sz, 0, NULL)) != NULL) {
00185
00186 cpl_vector_correlate(vxc, cpl_bivector_get_y(gen_init),spectrum);
00187 cpl_bivector_delete(gen_init);
00188 xc_cur = cpl_vector_get(vxc, 0);
00189 if (xc_cur > *xc) {
00190 *xc = xc_cur ;
00191 best_ind = i ;
00192 }
00193 cpl_vector_set(vxcorrs, i, xc_cur) ;
00194 } else {
00195 cpl_msg_error(cpl_func, "Cannot generate the signal - abort") ;
00196 cpl_vector_delete(vxcorrs) ;
00197 cpl_vector_delete(vxc) ;
00198 for (i=0 ; i<ntests ; i++) {
00199 cpl_polynomial_delete(candidates[i]) ;
00200 }
00201 cpl_free(candidates) ;
00202 return NULL ;
00203 }
00204 }
00205 cpl_vector_delete(vxc) ;
00206
00207
00208 poly_sol = cpl_polynomial_duplicate(candidates[best_ind]) ;
00209
00210 for (i=0 ; i<ntests ; i++) {
00211 cpl_polynomial_delete(candidates[i]) ;
00212 }
00213 cpl_free(candidates) ;
00214
00215
00216 if ((spc_table = irplib_wlxcorr_gen_spc_table(spectrum, lines_catalog,
00217 slitw, fwhm, guess_poly, poly_sol)) == NULL) {
00218 cpl_msg_error(cpl_func, "Cannot generate infos table") ;
00219 cpl_polynomial_delete(poly_sol) ;
00220 cpl_vector_delete(vxcorrs) ;
00221 return NULL ;
00222 }
00223
00224
00225 if (wlres != NULL) *wlres = spc_table ;
00226 else cpl_table_delete(spc_table) ;
00227
00228 if (xcorrs != NULL) *xcorrs = vxcorrs ;
00229 else cpl_vector_delete(vxcorrs) ;
00230
00231 return poly_sol ;
00232 }
00233
00234
00247
00248 cpl_table * irplib_wlxcorr_gen_spc_table(
00249 const cpl_vector * spectrum,
00250 const cpl_bivector * lines_catalog,
00251 double slitw,
00252 double fwhm,
00253 const cpl_polynomial * guess_poly,
00254 const cpl_polynomial * corr_poly)
00255 {
00256 cpl_bivector * gen_init ;
00257 cpl_bivector * gen_corr ;
00258 int nsamples ;
00259 cpl_table * spc_table ;
00260 double * pgen ;
00261
00262
00263 if (spectrum == NULL) return NULL ;
00264 if (lines_catalog == NULL) return NULL ;
00265 if (guess_poly == NULL) return NULL ;
00266 if (corr_poly == NULL) return NULL ;
00267
00268
00269 nsamples = cpl_vector_get_size(spectrum) ;
00270
00271
00272 if ((gen_init=irplib_wlxcorr_gen_signal(lines_catalog, slitw, fwhm,
00273 guess_poly, nsamples, 0, NULL)) == NULL) {
00274 cpl_msg_error(cpl_func, "Cannot get the emission spectrum") ;
00275 return NULL ;
00276 }
00277
00278
00279 if ((gen_corr=irplib_wlxcorr_gen_signal(lines_catalog, slitw, fwhm,
00280 corr_poly, nsamples, 0, NULL)) == NULL) {
00281 cpl_msg_error(cpl_func, "Cannot get the emission spectrum") ;
00282 cpl_bivector_delete(gen_init) ;
00283 return NULL ;
00284 }
00285
00286
00287 spc_table = cpl_table_new(nsamples);
00288 cpl_table_new_column(spc_table, IRPLIB_COL_XC_WAVELENGTH, CPL_TYPE_DOUBLE);
00289 cpl_table_new_column(spc_table, IRPLIB_COL_XC_CAT_INIT, CPL_TYPE_DOUBLE);
00290 cpl_table_new_column(spc_table, IRPLIB_COL_XC_CAT_FINAL, CPL_TYPE_DOUBLE);
00291 cpl_table_new_column(spc_table, IRPLIB_COL_XC_OBS, CPL_TYPE_DOUBLE);
00292
00293
00294 pgen = cpl_bivector_get_x_data(gen_corr) ;
00295 cpl_table_copy_data_double(spc_table, IRPLIB_COL_XC_WAVELENGTH, pgen) ;
00296 pgen = cpl_bivector_get_y_data(gen_corr) ;
00297 cpl_table_copy_data_double(spc_table, IRPLIB_COL_XC_CAT_FINAL, pgen) ;
00298 pgen = cpl_vector_get_data(spectrum) ;
00299 cpl_table_copy_data_double(spc_table, IRPLIB_COL_XC_OBS, pgen) ;
00300 pgen = cpl_bivector_get_y_data(gen_init) ;
00301 cpl_table_copy_data_double(spc_table, IRPLIB_COL_XC_CAT_INIT, pgen);
00302 cpl_bivector_delete(gen_init);
00303 cpl_bivector_delete(gen_corr);
00304
00305 return spc_table ;
00306 }
00307
00308
00316
00317 cpl_bivector * irplib_wlxcorr_cat_extract(
00318 const cpl_bivector * lines_catalog,
00319 double wave_min,
00320 double wave_max)
00321 {
00322 int wave_min_id, wave_max_id ;
00323 double wave_cur ;
00324 cpl_vector * sub_cat_wl ;
00325 cpl_vector * sub_cat_int ;
00326 cpl_bivector * sub_cat ;
00327 int i ;
00328
00329 wave_min_id = wave_max_id = -1 ;
00330 for (i=0 ; i<cpl_bivector_get_size(lines_catalog) ; i++) {
00331 wave_cur = cpl_vector_get(cpl_bivector_get_x(lines_catalog), i) ;
00332 if ((wave_min_id<0) && (wave_cur>wave_min)) wave_min_id = i ;
00333 if (wave_cur<wave_max) wave_max_id = i ;
00334 }
00335 if (wave_min_id<0 || wave_max_id<0) {
00336 cpl_msg_error(cpl_func, "Cannot extract from the catalog spectrum") ;
00337 return NULL ;
00338 }
00339 if (wave_min_id >= wave_max_id) return NULL ;
00340 sub_cat_wl = cpl_vector_extract(cpl_bivector_get_x(lines_catalog),
00341 wave_min_id, wave_max_id, 1) ;
00342 sub_cat_int = cpl_vector_extract(cpl_bivector_get_y(lines_catalog),
00343 wave_min_id, wave_max_id, 1) ;
00344 sub_cat = cpl_bivector_wrap_vectors(sub_cat_wl, sub_cat_int) ;
00345
00346 return sub_cat ;
00347 }
00348
00349
00359
00360 int irplib_wlxcorr_plot_solution(
00361 const cpl_polynomial * init,
00362 const cpl_polynomial * comp,
00363 const cpl_polynomial * sol,
00364 int pix_start,
00365 int pix_stop)
00366 {
00367 int nsamples, nplots ;
00368 cpl_vector ** vectors ;
00369 cpl_bivector * bivector ;
00370 double diff ;
00371 int i ;
00372
00373
00374 if (init == NULL || comp == NULL) return -1 ;
00375
00376
00377 nsamples = pix_stop - pix_start + 1 ;
00378 if (sol != NULL) nplots = 3 ;
00379 else nplots = 2 ;
00380
00381
00382 vectors = cpl_malloc((nplots+1)*sizeof(cpl_vector*)) ;
00383 for (i=0 ; i<nplots+1 ; i++) vectors[i] = cpl_vector_new(nsamples) ;
00384
00385
00386
00387 for (i=0 ; i<nsamples ; i++) {
00388 cpl_vector_set(vectors[0], i, pix_start+i) ;
00389 cpl_vector_set(vectors[1], i,
00390 cpl_polynomial_eval_1d(init, (double)(pix_start+i), NULL)) ;
00391 cpl_vector_set(vectors[2], i,
00392 cpl_polynomial_eval_1d(comp, (double)(pix_start+i), NULL)) ;
00393 if (sol != NULL)
00394 cpl_vector_set(vectors[3], i,
00395 cpl_polynomial_eval_1d(sol, (double)(pix_start+i), NULL)) ;
00396 }
00397
00398
00399 irplib_vectors_plot("set grid;set xlabel 'Position (pixels)';",
00400 "t '1-Initial / 2-Computed / 3-Solution' w lines",
00401 "", (const cpl_vector **)vectors, nplots+1);
00402
00403
00404 for (i=0 ; i<nplots+1 ; i++) cpl_vector_delete(vectors[i]) ;
00405 cpl_free(vectors) ;
00406
00407
00408 nplots -- ;
00409 vectors = cpl_malloc((nplots+1)*sizeof(cpl_vector*)) ;
00410 for (i=0 ; i<nplots+1 ; i++) vectors[i] = cpl_vector_new(nsamples) ;
00411
00412
00413
00414 for (i=0 ; i<nsamples ; i++) {
00415 cpl_vector_set(vectors[0], i, pix_start+i) ;
00416 diff = cpl_polynomial_eval_1d(comp, (double)(pix_start+i), NULL) -
00417 cpl_polynomial_eval_1d(init, (double)(pix_start+i), NULL) ;
00418 cpl_vector_set(vectors[1], i, diff) ;
00419 if (sol != NULL) {
00420 diff = cpl_polynomial_eval_1d(sol, (double)(pix_start+i), NULL) -
00421 cpl_polynomial_eval_1d(init, (double)(pix_start+i), NULL) ;
00422 cpl_vector_set(vectors[2], i, diff) ;
00423 }
00424 }
00425
00426
00427 if (sol == NULL) {
00428 bivector = cpl_bivector_wrap_vectors(vectors[0], vectors[1]) ;
00429 irplib_bivector_plot(
00430 "set grid;set xlabel 'Position (pixels)';set ylabel 'Wavelength difference';",
00431 "t 'Computed-Initial wavelenth' w lines", "", bivector);
00432 cpl_bivector_unwrap_vectors(bivector) ;
00433 } else {
00434 irplib_vectors_plot("set grid;set xlabel 'Position (pixels)';",
00435 "t '1-Computed - Initial / 2--Solution - Initial' w lines",
00436 "", (const cpl_vector **)vectors, nplots+1);
00437 }
00438
00439
00440 for (i=0 ; i<nplots+1 ; i++) cpl_vector_delete(vectors[i]) ;
00441 cpl_free(vectors) ;
00442
00443
00444 return 0 ;
00445 }
00446
00447
00454
00455 int irplib_wlxcorr_plot_spc_table(
00456 const cpl_table * spc_table,
00457 const char * title)
00458 {
00459 char title_loc[1024] ;
00460 cpl_vector ** vectors ;
00461 cpl_vector ** sub_vectors ;
00462 cpl_vector * tmp_vec ;
00463 int nsamples ;
00464 double hsize_nm, max, mean1, mean3 ;
00465 int start_ind, stop_ind, nblines, hsize_pix ;
00466 int i, j ;
00467
00468
00469 if (spc_table == NULL) return -1 ;
00470
00471
00472 nsamples = cpl_table_get_nrow(spc_table) ;
00473 hsize_nm = 0.2 ;
00474 hsize_pix = 10 ;
00475 nblines = 0 ;
00476 sprintf(title_loc,
00477 "t '%s - 1-Initial catalog/2-Corrected catalog/3-Observed' w lines",
00478 title) ;
00479 title_loc[1023] = (char)0 ;
00480
00481 vectors = cpl_malloc(4*sizeof(cpl_vector*)) ;
00482 vectors[0] = cpl_vector_wrap(nsamples,
00483 cpl_table_get_data_double(spc_table, IRPLIB_COL_XC_WAVELENGTH)) ;
00484 vectors[1] = cpl_vector_wrap(nsamples,
00485 cpl_table_get_data_double(spc_table, IRPLIB_COL_XC_CAT_INIT)) ;
00486 vectors[2] = cpl_vector_wrap(nsamples,
00487 cpl_table_get_data_double(spc_table, IRPLIB_COL_XC_CAT_FINAL)) ;
00488 vectors[3] = cpl_vector_wrap(nsamples,
00489 cpl_table_get_data_double(spc_table, IRPLIB_COL_XC_OBS)) ;
00490
00491
00492 mean1 = cpl_vector_get_mean(vectors[1]) ;
00493 mean3 = cpl_vector_get_mean(vectors[3]) ;
00494 if (fabs(mean3) > 1)
00495 cpl_vector_multiply_scalar(vectors[3], fabs(mean1/mean3)) ;
00496
00497 irplib_vectors_plot("set grid;set xlabel 'Wavelength (nm)';", title_loc,
00498 "", (const cpl_vector **)vectors, 4);
00499
00500
00501 if (fabs(mean3) > 1)
00502 cpl_vector_multiply_scalar(vectors[3], mean3/mean1) ;
00503
00504
00505 sprintf(title_loc,
00506 "t '%s - 1-Initial catalog/2-Corrected catalog/3-Observed (ZOOMED)' w lines",
00507 title) ;
00508 title_loc[1023] = (char)0 ;
00509 tmp_vec = cpl_vector_duplicate(vectors[2]) ;
00510 for (i=0 ; i<nblines ; i++) {
00511
00512 if ((max = cpl_vector_get_max(tmp_vec)) <= 0.0) break ;
00513 for (j=0 ; i<nsamples ; j++) {
00514 if (cpl_vector_get(tmp_vec, j) == max) break ;
00515 }
00516 if (j-hsize_pix < 0) start_ind = 0 ;
00517 else start_ind = j-hsize_pix ;
00518 if (j+hsize_pix > nsamples-1) stop_ind = nsamples-1 ;
00519 else stop_ind = j+hsize_pix ;
00520 for (j=start_ind ; j<=stop_ind ; j++) cpl_vector_set(tmp_vec, j, 0.0) ;
00521
00522 sub_vectors = cpl_malloc(4*sizeof(cpl_vector*)) ;
00523 sub_vectors[0]=cpl_vector_extract(vectors[0],start_ind,stop_ind,1);
00524 sub_vectors[1]=cpl_vector_extract(vectors[1],start_ind,stop_ind,1);
00525 sub_vectors[2]=cpl_vector_extract(vectors[2],start_ind,stop_ind,1);
00526 sub_vectors[3]=cpl_vector_extract(vectors[3],start_ind,stop_ind,1);
00527
00528 irplib_vectors_plot("set grid;set xlabel 'Wavelength (nm)';", title_loc,
00529 "", (const cpl_vector **)sub_vectors, 4);
00530
00531 cpl_vector_delete(sub_vectors[0]) ;
00532 cpl_vector_delete(sub_vectors[1]) ;
00533 cpl_vector_delete(sub_vectors[2]) ;
00534 cpl_vector_delete(sub_vectors[3]) ;
00535 cpl_free(sub_vectors) ;
00536 }
00537 cpl_vector_delete(tmp_vec) ;
00538
00539 cpl_vector_unwrap(vectors[0]) ;
00540 cpl_vector_unwrap(vectors[1]) ;
00541 cpl_vector_unwrap(vectors[2]) ;
00542 cpl_vector_unwrap(vectors[3]) ;
00543 cpl_free(vectors) ;
00544
00545 return 0 ;
00546 }
00547
00548
00556
00557 int irplib_wlxcorr_catalog_plot(
00558 const cpl_bivector * cat,
00559 double wmin,
00560 double wmax)
00561 {
00562 int start, stop ;
00563 cpl_bivector * subcat ;
00564 cpl_vector * subcat_x ;
00565 cpl_vector * subcat_y ;
00566 double * pwave ;
00567 int nvals, nvals_tot ;
00568 int i ;
00569
00570
00571 if (cat == NULL) return -1 ;
00572 if (wmax <= wmin) return -1 ;
00573
00574
00575 nvals_tot = cpl_bivector_get_size(cat) ;
00576
00577
00578 pwave = cpl_bivector_get_x_data(cat) ;
00579 if (pwave[0] >= wmin) start = 0 ;
00580 else start = -1 ;
00581 if (pwave[nvals_tot-1] <= wmax) stop = nvals_tot-1 ;
00582 else stop = -1 ;
00583 i=0 ;
00584 while ((pwave[i] < wmin) && (i<nvals_tot-1)) i++ ;
00585 start = i ;
00586 i= nvals_tot-1 ;
00587 while ((pwave[i] > wmax) && (i>0)) i-- ;
00588 stop = i ;
00589
00590 if (start>=stop) {
00591 cpl_msg_error(cpl_func, "Cannot plot the catalog") ;
00592 return -1 ;
00593 }
00594 nvals = start - stop + 1 ;
00595
00596
00597 subcat_x = cpl_vector_extract(cpl_bivector_get_x(cat), start, stop, 1) ;
00598 subcat_y = cpl_vector_extract(cpl_bivector_get_y(cat), start, stop, 1) ;
00599 subcat = cpl_bivector_wrap_vectors(subcat_x, subcat_y) ;
00600
00601
00602 irplib_bivector_plot(
00603 "set grid;set xlabel 'Wavelength (nm)';set ylabel 'Emission';",
00604 "t 'Catalog Spectrum' w lines", "", subcat);
00605 cpl_bivector_unwrap_vectors(subcat) ;
00606 cpl_vector_delete(subcat_x) ;
00607 cpl_vector_delete(subcat_y) ;
00608
00609 return 0 ;
00610 }
00611
00612
00626
00627 cpl_vector * irplib_wlxcorr_convolve_create_kernel(
00628 double slitw,
00629 double fwhm)
00630 {
00631 double sigma ;
00632 int ihtophat, gausshlen, convolen ;
00633 cpl_vector * self ;
00634 cpl_vector * tophat ;
00635 cpl_image * iself ;
00636 int i ;
00637
00638
00639 sigma = fwhm / (2.0 * sqrt(2.0*log(2.0)));
00640 ihtophat = (int)slitw/2 ;
00641 gausshlen = 1 + 5 * sigma + ihtophat ;
00642
00643
00644 convolen = 1 + 10 * sigma + 8 * ihtophat ;
00645
00646
00647 if ((slitw <= 0.0) || (fwhm <= 0.0) ||(convolen < 2 * gausshlen))
00648 return NULL ;
00649
00650
00651 self = cpl_vector_new(gausshlen) ;
00652 tophat = cpl_vector_new(convolen) ;
00653
00654
00655 iself = cpl_image_wrap_double(gausshlen, 1, cpl_vector_get_data(self));
00656
00657
00658 cpl_image_fill_gaussian(iself, 1.0, 1.0, sqrt(2.0*atan(1.0)*4.0),sigma,1.0);
00659 cpl_image_unwrap(iself) ;
00660
00661
00662 cpl_vector_fill(tophat, 0.0);
00663
00664 for (i = convolen/2-ihtophat; i < 1+convolen/2+ihtophat; i++)
00665 cpl_vector_set(tophat, i, 1.0/(1.0+2.0*ihtophat));
00666
00667
00668 if (irplib_wlxcorr_convolve(tophat, self)) {
00669 cpl_msg_error(cpl_func, "Cannot convolve") ;
00670 cpl_vector_delete(self) ;
00671 cpl_vector_delete(tophat) ;
00672 return NULL ;
00673 }
00674
00675
00676
00677 for (i = 0 ; i < gausshlen; i++)
00678 cpl_vector_set(self, i, cpl_vector_get(tophat, i + convolen/2));
00679 cpl_vector_delete(tophat) ;
00680
00681 return self;
00682 }
00683
00684
00693
00694 int irplib_wlxcorr_convolve(
00695 cpl_vector * smoothed,
00696 const cpl_vector * conv_kernel)
00697 {
00698 int nsamples ;
00699 int ihwidth ;
00700 cpl_vector * raw ;
00701 double * psmoothe ;
00702 double * praw ;
00703 double * psymm ;
00704 int i, j ;
00705
00706
00707 if ((!smoothed) || (!conv_kernel)) return -1 ;
00708
00709
00710 nsamples = cpl_vector_get_size(smoothed) ;
00711 ihwidth = cpl_vector_get_size(conv_kernel) - 1 ;
00712 if (ihwidth >= nsamples) return -1 ;
00713 psymm = cpl_vector_get_data(conv_kernel) ;
00714 psmoothe = cpl_vector_get_data(smoothed) ;
00715
00716
00717 raw = cpl_vector_duplicate(smoothed) ;
00718 praw = cpl_vector_get_data(raw) ;
00719
00720
00721 for (i=0 ; i<ihwidth ; i++) {
00722 psmoothe[i] = praw[i] * psymm[0];
00723 for (j=1 ; j <= ihwidth ; j++) {
00724 const int k = i-j < 0 ? 0 : i-j;
00725 psmoothe[i] += (praw[k]+praw[i+j]) * psymm[j];
00726 }
00727 }
00728
00729 for (i=ihwidth ; i<nsamples-ihwidth ; i++) {
00730 psmoothe[i] = praw[i] * psymm[0];
00731 for (j=1 ; j<=ihwidth ; j++)
00732 psmoothe[i] += (praw[i-j]+praw[i+j]) * psymm[j];
00733 }
00734 for (i=nsamples-ihwidth ; i<nsamples ; i++) {
00735 psmoothe[i] = praw[i] * psymm[0];
00736 for (j=1 ; j<=ihwidth ; j++) {
00737 const int k = i+j > nsamples-1 ? nsamples - 1 : i+j;
00738 psmoothe[i] += (praw[k]+praw[i-j]) * psymm[j];
00739 }
00740 }
00741 cpl_vector_delete(raw) ;
00742 return 0 ;
00743 }
00744
00747
00763
00764 static cpl_bivector * irplib_wlxcorr_gen_signal(
00765 const cpl_bivector * lines_catalog,
00766 double slitw,
00767 double fwhm,
00768 const cpl_polynomial * poly,
00769 int nsamples,
00770 int search_hs,
00771 int * nb_lines)
00772 {
00773 int size, nlines ;
00774 cpl_vector * conv_kernel ;
00775 cpl_bivector * gen_spectrum ;
00776 cpl_bivector * sub_cat ;
00777 double wave_min, wave_max ;
00778 cpl_vector * wl_limits ;
00779 int ind ;
00780 double new_val, wl ;
00781 int i ;
00782
00783
00784 size = nsamples + 2 * search_hs ;
00785
00786
00787 if (!lines_catalog || !poly) return NULL ;
00788 if (size <= 1) return NULL ;
00789
00790
00791 gen_spectrum = cpl_bivector_new(size) ;
00792 cpl_vector_fill_polynomial(cpl_bivector_get_x(gen_spectrum), poly,
00793 -search_hs+1, 1) ;
00794
00795
00796 wave_min = cpl_vector_get(cpl_bivector_get_x(gen_spectrum), 0) ;
00797 wave_max = cpl_vector_get(cpl_bivector_get_x(gen_spectrum), size-1) ;
00798 sub_cat = irplib_wlxcorr_cat_extract(lines_catalog, wave_min, wave_max) ;
00799 if (sub_cat == NULL) {
00800 cpl_bivector_delete(gen_spectrum) ;
00801 return NULL ;
00802 }
00803 nlines = cpl_bivector_get_size(sub_cat) ;
00804 if (nb_lines) *nb_lines = nlines ;
00805
00806
00807 wl_limits = cpl_vector_new(size + 1);
00808 cpl_vector_fill_polynomial(wl_limits, poly, -search_hs+0.5, 1) ;
00809 if (nlines < size) {
00810
00811 cpl_vector_fill(cpl_bivector_get_y(gen_spectrum), 0.0) ;
00812 for (i=0 ; i<nlines ; i++) {
00813 wl = cpl_vector_get(cpl_bivector_get_x(sub_cat), i) ;
00814 ind = 0 ;
00815 while (wl>cpl_vector_get(wl_limits, ind) && ind<size-1)
00816 ind++ ;
00817 new_val = cpl_vector_get(cpl_bivector_get_y(gen_spectrum), ind) ;
00818 new_val += cpl_vector_get(cpl_bivector_get_y(sub_cat), i) ;
00819 cpl_vector_set(cpl_bivector_get_y(gen_spectrum), ind, new_val) ;
00820 }
00821 } else {
00822
00823 if (irplib_wlxcorr_signal_resample(cpl_bivector_get_y(gen_spectrum),
00824 wl_limits, lines_catalog)) {
00825 cpl_msg_error(cpl_func, "Cannot resample the signal") ;
00826 cpl_bivector_delete(gen_spectrum) ;
00827 cpl_vector_delete(wl_limits) ;
00828 cpl_bivector_delete(sub_cat) ;
00829 return NULL ;
00830 }
00831 }
00832 cpl_bivector_delete(sub_cat) ;
00833 cpl_vector_delete(wl_limits) ;
00834
00835
00836 if ((conv_kernel = irplib_wlxcorr_convolve_create_kernel(slitw,
00837 fwhm)) == NULL) {
00838 cpl_msg_error(cpl_func, "Cannot create convolution kernel") ;
00839 cpl_bivector_delete(gen_spectrum) ;
00840 return NULL ;
00841 }
00842
00843
00844 if (irplib_wlxcorr_convolve(cpl_bivector_get_y(gen_spectrum),conv_kernel)) {
00845 cpl_msg_error(cpl_func, "Cannot smoothe the signal");
00846 cpl_bivector_delete(gen_spectrum) ;
00847 return NULL ;
00848 }
00849 cpl_vector_delete(conv_kernel) ;
00850
00851 return gen_spectrum ;
00852 }
00853
00854
00864
00865 static int irplib_wlxcorr_signal_resample(
00866 cpl_vector * resampled,
00867 const cpl_vector * xbounds,
00868 const cpl_bivector * hires)
00869 {
00870 cpl_vector * xhires ;
00871 cpl_vector * yhires ;
00872 double * pxhires ;
00873 double * pyhires ;
00874 double * pxbounds ;
00875 cpl_vector * ybounds ;
00876 cpl_bivector * boundary ;
00877 double * pybounds ;
00878 double * presampled ;
00879 int nsamples ;
00880 int i, itt ;
00881
00882
00883 if ((!resampled) || (!xbounds) || (!hires)) return -1 ;
00884
00885
00886 nsamples = cpl_vector_get_size(resampled) ;
00887
00888
00889 presampled = cpl_vector_get_data(resampled) ;
00890 pxbounds = cpl_vector_get_data(xbounds) ;
00891 xhires = cpl_bivector_get_x(hires) ;
00892 yhires = cpl_bivector_get_y(hires) ;
00893 pxhires = cpl_vector_get_data(xhires) ;
00894 pyhires = cpl_vector_get_data(yhires) ;
00895
00896
00897 ybounds = cpl_vector_new(cpl_vector_get_size(xbounds)) ;
00898 boundary = cpl_bivector_wrap_vectors((cpl_vector*)xbounds,ybounds) ;
00899 pybounds = cpl_vector_get_data(ybounds) ;
00900
00901
00902 if (cpl_bivector_get_size(boundary) != nsamples + 1) {
00903 cpl_bivector_unwrap_vectors(boundary) ;
00904 cpl_vector_delete(ybounds) ;
00905 return -1 ;
00906 }
00907
00908
00909 itt = cpl_vector_find(xhires, pxbounds[0]);
00910
00911
00912 if (cpl_bivector_interpolate_linear(boundary, hires)) {
00913 cpl_msg_error(cpl_func, "Cannot interpolate the signal") ;
00914 cpl_bivector_unwrap_vectors(boundary) ;
00915 cpl_vector_delete(ybounds) ;
00916 return -1 ;
00917 }
00918
00919
00920
00921 while (pxhires[itt] < pxbounds[0]) itt++;
00922
00923 for (i=0; i < nsamples; i++) {
00924
00925
00926
00927
00928 double xlow = pxbounds[i];
00929 double x = pxhires[itt];
00930
00931 if (x > pxbounds[i+1]) x = pxbounds[i+1];
00932
00933
00934 presampled[i] = pybounds[i] * (x - xlow);
00935
00936
00937 while ((pxhires[itt] < pxbounds[i+1]) &&
00938 (itt < cpl_bivector_get_size(hires))) {
00939 const double xprev = x;
00940 x = pxhires[itt+1];
00941 if (x > pxbounds[i+1]) x = pxbounds[i+1];
00942 presampled[i] += pyhires[itt] * (x - xlow);
00943 xlow = xprev;
00944 itt++;
00945 }
00946
00947
00948
00949 presampled[i] += pybounds[i+1] * (pxbounds[i+1] - xlow);
00950
00951
00952
00953 presampled[i] /= 2 * (pxbounds[i+1] - pxbounds[i]);
00954 }
00955 cpl_bivector_unwrap_vectors(boundary) ;
00956 cpl_vector_delete(ybounds) ;
00957 return 0 ;
00958 }
00959