X-shooter Pipeline Reference Manual 3.8.15
test-xsh_sky_lines_sampling.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: 2011-12-02 14:13:14 $
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#include <string.h>
43#include <stdio.h>
44#include <math.h>
45#include <cpl.h>
46#include <xsh_msg.h>
47#include <xsh_utils.h>
48#include <xsh_dfs.h>
49#include <xsh_utils_table.h>
50
51static cpl_error_code
52xsh_line_group_stat(const int nbins, const int local_sz, const int nside,
53 const double* xbin, cpl_table* tab, double* local_median,
54 double* local_stdev, int* group_nbin, double* group_mean,
55 double* group_median)
56{
57 int j_lo=0;
58 int j_hi=0;
59 int ilo=0;
60 int ihi=0;
61 double wmin;
62 double wmax;
63 cpl_table* xtab;
64
65 for (int i = 0; i < nbins; i++) {
66 j_lo = (0 > (i - local_sz / 2)) ? 0 : (i - local_sz / 2);
67 j_hi = ((j_lo + local_sz) < (nbins - 1)) ?
68 (j_lo + local_sz) : (nbins - 1);
69 //xsh_msg_warning("j_lo=%d j_hi=%d",j_lo,j_hi);
70 wmin = xbin[j_lo];
71 wmax = xbin[j_hi];
72 //xsh_msg_warning("wmin=%16.14g wmax=%16.14g nbins=%d",wmin,wmax,nbins);
73 cpl_table_and_selected_double(tab, "WAVE", CPL_GREATER_THAN, wmin);
74 cpl_table_and_selected_double(tab, "WAVE", CPL_LESS_THAN, wmax);
75 xtab = cpl_table_extract_selected(tab);
76 local_median[i] = cpl_table_get_column_median(xtab, "FLUX");
77 local_stdev[i] = cpl_table_get_column_stdev(xtab, "FLUX");
78 cpl_table_select_all(tab);
79 xsh_free_table(&xtab);
80
81 ilo = ((i - nside) > 0) ? (i - nside) : 0;
82 ihi = ((i + nside) < (nbins - 1)) ? (i + nside) : nbins - 1;
83 //xsh_msg_warning("ilo=%d ihi=%d",ilo,ihi);
84 wmin = xbin[ilo];
85 wmax = xbin[ihi];
86 cpl_table_and_selected_double(tab, "WAVE", CPL_GREATER_THAN, wmin);
87 cpl_table_and_selected_double(tab, "WAVE", CPL_LESS_THAN, wmax);
88 xtab = cpl_table_extract_selected(tab);
89 group_nbin[i] = ihi - ilo + 1;
90 group_mean[i] = cpl_table_get_column_mean(xtab, "FLUX");
91 group_median[i] = cpl_table_get_column_median(xtab, "FLUX");
92 if(i<5) {
93 xsh_msg_warning("nbin=%d mean=%g median=%g",
94 group_nbin[i],group_mean[i],group_median[i]);
95
96 }
97 cpl_table_select_all(tab);
98 xsh_free_table(&xtab);
99 }
100 return cpl_error_get_code();
101}
102
103static cpl_error_code
104xsh_line_fill_xbin_ybin_ysig(const int nbins, const double wmin,
105 const double bin, cpl_table* tab,
106 const int* h, double* xbin, double* ybin,
107 double* ysig)
108
109{
110 cpl_table* xtab;
111 //ybin=cpl_array_get_data_double(ybin_array);
112 double fct = 0;
113 for (int i = 0; i < nbins; i++) {
114 xbin[i] = wmin + bin * (i + 0.5);
115 cpl_table_and_selected_double(tab, "WAVE", CPL_GREATER_THAN,
116 xbin[i] - bin);
117 cpl_table_and_selected_double(tab, "WAVE", CPL_LESS_THAN,
118 xbin[i] + bin);
119 xtab = cpl_table_extract_selected(tab);
120 ybin[i] = cpl_table_get_column_median(xtab, "FLUX");
121
122 fct = (h[i] > 0) ? h[i] : 1;
123 //xsh_msg_warning("h=%d dh=%g fct=%g",h[i],(double)h[i],fct);
124 ysig[i] = cpl_table_get_column_stdev(xtab, "FLUX");
125 if(i<5) {
126 xsh_msg_warning("ysig=%g",ysig[i]);
127 }
128
129
130 ysig[i] /= sqrt(fct);
131 if(i<5) {
132 xsh_msg_warning("Normalisation");
133 xsh_msg_warning("ysig=%g",ysig[i]);
134 }
135 //xsh_msg_warning("xbin=%g",xbin[i]);
136 //xsh_msg_warning("ybin=%g",ybin[i]);
137 //xsh_msg_warning("ysig=%g",ysig[i]);
138 cpl_table_select_all(tab);
139 xsh_free_table(&xtab);
140 }
141 return cpl_error_get_code();
142}
143
144double*
145xsh_find_em_lines(const int nbins, const int nside, const double min_bk_space,
146 const double intermed_bk_space, const double* local_median,
147 const double* local_stdev, const int* group_nbin,
148 const double* group_mean, const double* group_median,
149 int* pltype, double* bk_space_list)
150{
151 /* Groups that look like emission lines */
152 double* em_lines_thresh = cpl_calloc(nbins, sizeof(double));
153 for (int i = 0; i < nbins; i++) {
154 em_lines_thresh[i] = local_median[i]
155 + 3. * local_stdev[i] / sqrt(group_nbin[i]);
156 //xsh_msg_warning("em_lines_thresh[%d]=%g", i, em_lines_thresh[i]);
157 }
158 int n_em_lines = 0;
159 for (int i = 0; i < nbins; i++) {
160 if (((group_mean[i] >= em_lines_thresh[i])
161 && (group_median[i] >= local_median[i] + local_stdev[i]))) {
162 pltype[i] = 1;
163 n_em_lines++;
164 xsh_msg_warning("em line i=%d",i);
165 }
166 }
167 xsh_msg_warning("emission lines %d",n_em_lines);
168 if (n_em_lines != 0) {
169 for (int j = 0; j < nbins; j++) {
170 /* adding extra pixels to the side of groups may cause ringing in
171 * the sky fit at line edges */
172 if (pltype[j] == 1) {
173 int i = j;
174 int ilo = ((i - nside) > 0) ? (i - nside) : 0;
175 int ihi = ((i + nside) < (nbins - 1)) ? (i + nside) : nbins - 1;
176 bk_space_list[i] = min_bk_space;
177 for (int k = ilo; k < ihi; k++) {
178 bk_space_list[k] =
179 (intermed_bk_space < bk_space_list[k]) ?
180 intermed_bk_space :
181 bk_space_list[k];
182 }
183 }
184 }
185 }
186 return em_lines_thresh;
187}
188
189double*
190xsh_find_abs_lines(const int nbins, const int nside, const double min_bk_space,
191 const double intermed_bk_space, const double* local_median,
192 const double* local_stdev, const int* group_nbin,
193 const double* group_mean, const double* group_median,
194 int* pltype, double* bk_space_list)
195{
196 /* Groups that look like absorbtion lines */
197 double* abs_lines_thresh = cpl_calloc(nbins, sizeof(double));
198 for (int i = 0; i < nbins; i++) {
199 abs_lines_thresh[i] = local_median[i]
200 - 3. * local_stdev[i] / sqrt(group_nbin[i]);
201 //xsh_msg_warning("em_lines_thresh[%d]=%g", i, em_lines_thresh[i]);
202 }
203 int n_abs_lines = 0;
204 for (int i = 0; i < nbins; i++) {
205 if (((group_mean[i] <= abs_lines_thresh[i])
206 && (group_median[i] <= local_median[i] + local_stdev[i]))) {
207 pltype[i] = 2;
208 n_abs_lines++;
209 }
210 }
211 xsh_msg_warning("absorbtion lines %d",n_abs_lines);
212 if (n_abs_lines != 0) {
213 for (int j = 0; j < nbins; j++) {
214 /* adding extra pixels to the side of groups may cause ringing in
215 * the sky fit at line edges */
216 if (pltype[j] == 2) {
217 int i = j;
218 int ilo = ((i - nside) > 0) ? (i - nside) : 0;
219 int ihi = ((i + nside) < (nbins - 1)) ? (i + nside) : nbins - 1;
220 bk_space_list[i] = min_bk_space;
221 for (int k = ilo; k < ihi; k++) {
222 bk_space_list[k] =
223 (intermed_bk_space < bk_space_list[k]) ?
224 intermed_bk_space :
225 bk_space_list[k];
226 }
227 }
228 }
229 }
230 return abs_lines_thresh;
231}
232
233static cpl_error_code
234xsh_find_spectrum_slope_changes(const int nbins, const int nside,
235 const double min_bk_space,
236 const double* ybin, const double* ysig,
237 int* pltype, double* bk_space_list)
238{
239 /*
240 for(int i=0; i< nbins; i++) {
241 xsh_msg_warning("bk_space=%g",bk_space_list[i]);
242 }
243 */
244 /*
245 xsh_msg_warning("bk_space=%g min_bk_space=%g intermed_bk_space=%g",
246 bk_space,min_bk_space,intermed_bk_space);
247 */
248 /* other points where the slope appears to change rapidly */
249 double* ker1 = cpl_calloc(3, sizeof(double));
250 ker1[0] = -1;
251 ker1[1] = 2;
252 ker1[2] = -1;
253 double* d2y = cpl_calloc(nbins, sizeof(double));
254 memcpy(d2y, ybin, nbins * sizeof(double));
255 for (int i = 1; i < nbins - 1; i++) {
256 d2y[i] = ybin[i - 1] * ker1[0] + ybin[i] * ker1[1]
257 + ybin[i + 1] * ker1[1];
258 }
259 cpl_free(ker1);
260 double* d2y_var = cpl_calloc(nbins, sizeof(double));
261 double* yvar = cpl_calloc(nbins, sizeof(double));
262 memcpy(yvar, ysig, nbins * sizeof(double));
263 for (int i = 1; i < nbins - 1; i++) {
264 yvar[i] *= yvar[i];
265 }
266 double* ker2 = cpl_calloc(3, sizeof(double));
267 ker2[0] = 1;
268 ker2[1] = 2;
269 ker2[2] = 1;
270 for (int i = 1; i < nbins - 1; i++) {
271 d2y_var[i] = yvar[i - 1] * ker2[0] + yvar[i] * ker2[1]
272 + yvar[i + 1] * ker2[1];
273 }
274 cpl_free(ker2);
275 cpl_free(yvar);
276 double* d2y_sig = cpl_calloc(nbins, sizeof(double));
277 for (int i = 1; i < nbins - 1; i++) {
278 d2y_sig[i] = sqrt(d2y_var[i]);
279 }
280
281 cpl_free(d2y_var);
282 int n_slope_change = 0;
283 for (int i = 0; i < nbins; i++) {
284 if (fabs(d2y[i]) >= (4 * d2y_sig[i]) && pltype[i] == 0) {
285 pltype[i] = 3;
286 n_slope_change++;
287 }
288 }
289 xsh_msg_warning("slope changes %d/%d",n_slope_change,nbins);
290 cpl_free(d2y_sig);
291 cpl_free(d2y);
292 if (n_slope_change != 0) {
293 for (int j = 0; j < nbins; j++) {
294 /* adding extra pixels to the side of groups may cause ringing in
295 * the sky fit at line edges */
296 if (pltype[j] == 3) {
297 int i = j;
298 int ilo = ((i - nside) > 0) ? (i - nside) : 0;
299 int ihi = ((i + nside) < (nbins - 1)) ? (i + nside) : nbins - 1;
300 //bk_space_list[i] = min_bk_space;
301 for (int k = ilo; k < ihi; k++) {
302 bk_space_list[k] =
303 (min_bk_space < bk_space_list[k]) ?
304 min_bk_space :
305 bk_space_list[k];
306
307 }
308 //xsh_msg_warning("slope changes %g",bk_space_list[j]);
309 }
310 }
311 }
312 xsh_msg_warning("min_bk_space %g",min_bk_space);
313 return cpl_error_get_code();
314}
315
316static cpl_error_code
318{
319 double* wave = cpl_table_get_data_double(stab, "WAVE");
320 double* flux = cpl_table_get_data_double(stab, "FLUX");
321 double wmin = cpl_table_get_column_min(stab, "WAVE");
322 double wmax = cpl_table_get_column_max(stab, "WAVE");
323 int nrow=cpl_table_get_nrow(stab);
324 xsh_msg_warning("nrow=%d",nrow);
325
326 /* Place points break points. Attempt to identify and place extra break
327 * points around skylines. x=wavelength, y=sky counts.
328 * This method misses closely spaced sky lines.
329 */
330 double dispersion = 0.049439349;
331 double bin = dispersion;
332 int nbins = (wmax - wmin) / bin+1;
333 xsh_msg_warning("nbins=%d",nbins);
334 xsh_msg_warning("bin=%16.14g",bin);
335 //xsh_msg_warning("wmin=%16.14g wmax=%16.14g nbins=%d",wmin,wmax,nbins);
336 cpl_table* histogram = xsh_histogram(stab, "WAVE", nbins, wmin, wmax);
337 cpl_table_save(histogram, NULL, NULL, "histogram.fits", CPL_IO_DEFAULT);
338 double* xbin = cpl_calloc(nbins, sizeof(double));
339 double* ybin = cpl_calloc(nbins, sizeof(double));
340 double* ysig = cpl_calloc(nbins, sizeof(double));
341 int* h = cpl_table_get_data_int(histogram, "HY");
342 xsh_line_fill_xbin_ybin_ysig(nbins, wmin, bin, stab, h, xbin, ybin, ysig);
343 xsh_msg_warning("xbin=%16.14g,%16.14g,%16.14g,%16.14g,%16.14g",xbin[0],xbin[1],xbin[2],xbin[nbins-2],xbin[nbins-1]);
344 xsh_msg_warning("ybin=%16.14g,%16.14g,%16.14g,%16.14g,%16.14g",ybin[0],ybin[1],ybin[2],ybin[nbins-2],ybin[nbins-1]);
345 xsh_msg_warning("h=%d,%d,%d,%d,%d,%d,%d",h[0],h[1],h[2],h[3],h[4],h[nbins-2],h[nbins-1]);
346
347
348 /* compute local quantities for group pixels
349 */
350 int local_sz = nbins / 10.;
351 int nside = 2;
352 /* ideal number of bins per group */
353 int bin_per_group = 2 * nside + 1;
354 int* group_nbin = cpl_calloc(nbins, sizeof(int));
355 double* group_mean = cpl_calloc(nbins, sizeof(double));
356 double* group_median = cpl_calloc(nbins, sizeof(double));
357 double* local_median = cpl_calloc(nbins, sizeof(double));
358 double* local_stdev = cpl_calloc(nbins, sizeof(double));
359 double* bk_space_list = (double*) cpl_calloc(nbins, sizeof(double));
360 xsh_line_group_stat(nbins, local_sz, nside, xbin, stab, local_median,
361 local_stdev, group_nbin, group_mean, group_median);
362
363
364 cpl_table* lines_tab=cpl_table_new(nbins);
365 cpl_table_wrap_double(lines_tab,group_mean,"YBIN");
366 cpl_table_wrap_int(lines_tab,group_nbin,"GNBIN");
367 cpl_table_wrap_double(lines_tab,group_mean,"GMEDIAN");
368 cpl_table_wrap_double(lines_tab,group_mean,"GMEAN");
369 cpl_table_wrap_double(lines_tab,local_median,"LMEDIAN");
370 cpl_table_wrap_double(lines_tab,local_stdev,"LSTDEV");
371 cpl_table_wrap_double(lines_tab,bk_space_list,"BKSPACE");
372 cpl_table_new_column(lines_tab,"LTYPE",CPL_TYPE_INT);
373
374 cpl_table_fill_column_window_int(lines_tab,"LTYPE",0,nbins,0);
375 int* pltype=cpl_table_get_data_int(lines_tab,"LTYPE");
376 double* pbk_space_list=cpl_table_get_data_double(lines_tab,"BKSPACE");
377 int status=0; /* make sure bk_space is > min_bk_space */
378 double bk_space = 0.015262156;
379 double min_bk_space = 0.0025436927;
380 bk_space = (bk_space > min_bk_space) ? bk_space : min_bk_space;
381 /* Buffer pixels at the edges of lines and in slowly varying regions
382 * with break points at the intermediate spacing
383 */
384 double intermed_bk_space = min_bk_space + 0.3 * (bk_space - min_bk_space);
385 xsh_msg_warning("bk_space=%g",bk_space);
386 /* Default is the max break point spacing */
387
388 for(int i=0;i<nbins; i++) {
389 pbk_space_list[i] = bk_space;
390
391 }
392
393 /* Groups that look like emission lines */
394 double* em_lines_thresh = xsh_find_em_lines(nbins, nside, min_bk_space,
395 intermed_bk_space, local_median, local_stdev, group_nbin,
396 group_mean, group_median, pltype, pbk_space_list);
397 cpl_table_save(lines_tab,NULL,NULL,"lines_tab.fits",CPL_IO_DEFAULT);
398
399 /* Groups that look like absorbtion lines */
400 double* abs_lines_thresh = xsh_find_abs_lines(nbins, nside, min_bk_space,
401 intermed_bk_space, local_median, local_stdev, group_nbin,
402 group_mean, group_median, pltype, pbk_space_list);
403
404 /*
405 for(int i=0; i< nbins; i++) {
406 xsh_msg_warning("bk_space=%g",bk_space_list[i]);
407 }
408 */
409
410 /*
411 xsh_msg_warning("bk_space=%g min_bk_space=%g intermed_bk_space=%g",
412 bk_space,min_bk_space,intermed_bk_space);
413 */
414
415 /* other points where the slope appears to change rapidly */
416 xsh_find_spectrum_slope_changes(nbins, nside, min_bk_space, ybin, ysig,
417 pltype, pbk_space_list);
418
419 /* additional regions that do not appear constant */
421 int region_nside = 10;
422 cpl_table* xtab=NULL;
423 for (int i = 0; i < nbins; i++) {
425 int ilo = ((i - region_nside) > 0) ? (i - region_nside) : 0;
426 int ihi = ((i + region_nside) < (nbins - 1)) ? (i + region_nside) : (nbins - 1);
427 //xsh_msg_warning("ilo=%d ihi=%d",ilo,ihi);
428 wmin = xbin[ilo];
429 wmax = xbin[ihi];
431 cpl_table_dump_structure(lines_tab,stdout);
432 cpl_table_and_selected_double(lines_tab, "WAVE", CPL_GREATER_THAN, wmin);
434 cpl_table_and_selected_double(lines_tab, "WAVE", CPL_LESS_THAN, wmax);
436 xtab = cpl_table_extract_selected(lines_tab);
438 double* region_bkspace = NULL;
439 int nrow = cpl_table_get_nrow(xtab) ;
440 double* pregion_bkspace = cpl_table_get_data_double(lines_tab,"BKSPACE");
442 double* pregion_ybin = cpl_table_get_data_double(lines_tab,"YBIN");
444 for (int j = 0; j< nrow; j++ ) {
445 // Bins were spacing is still the maximum
446 int n_max=0;
447 if ( pregion_bkspace[j] == bk_space ) {
448 pltype[j] = 4;
449 n_max++;
450 }
451 cpl_table_and_selected_int(xtab,"LTYPE",CPL_EQUAL_TO,4);
452 cpl_table* stab=cpl_table_extract_selected(xtab);
453 if(n_max >= region_nside) {
454 // determine weather scatter goes down with the binning
455 double stdev_bin = cpl_table_get_column_stdev(stab,"YBIN");
456 double stdev_group = cpl_table_get_column_stdev(stab,"GMEAN");
457 if( stdev_bin/stdev_group <= 0.7 * sqrt (bin_per_group) ) {
458 // scatter not decreasing with binning as expected for a
459 // constant sky bkg
460
461 for (int k = ilo; k< ihi; k++ ) {
462 pltype[k] = 5;
463 pbk_space_list[k] = ( (pregion_bkspace[k] < intermed_bk_space) )? pregion_bkspace[k] : intermed_bk_space;
464 }
465 }
466 }
467 xsh_free_table(&stab);
468 cpl_table_select_all(lines_tab);
469 xsh_free_table(&xtab);
471 //exit(0);
472 }
473
474 }
475
476
477 exit(0);
478
479
480
481
482/*
483
484 for(int i=0; i< nbins; i++) {
485 xsh_msg_warning("bk_space=%g",bk_space_list[i]);
486 }
487*/
488
489
490 /* free memory */
491 cpl_table_unwrap(lines_tab,"YBIN");
492 cpl_table_unwrap(lines_tab,"GNBIN");
493 cpl_table_unwrap(lines_tab,"GMEDIAN");
494 cpl_table_unwrap(lines_tab,"GMEAN");
495 cpl_table_unwrap(lines_tab,"LMEDIAN");
496 cpl_table_unwrap(lines_tab,"LSTDEV");
497 cpl_table_unwrap(lines_tab,"BKSPACE");
498 xsh_free_table(&lines_tab);
499
500
501 cpl_free(xbin);
502 cpl_free(ybin);
503 cpl_free(ysig);
504 cpl_free(group_nbin);
505 cpl_free(group_mean);
506 cpl_free(group_median);
507 cpl_free(local_median);
508 cpl_free(local_stdev);
509 cpl_free(bk_space_list);
510 cpl_free(em_lines_thresh);
511 cpl_free(abs_lines_thresh);
512
513
514 xsh_msg_warning("ok1");
515 xsh_free_table(&histogram);
516 return cpl_error_get_code();
517}
518
519/*---------------------------------------------------------------------------
520 Defines
521 ---------------------------------------------------------------------------*/
522/*--------------------------------------------------------------------------*/
528/*--------------------------------------------------------------------------*/
529int main(int argc, char **argv)
530{
531
532 char *fname = NULL;
533 char *arm = NULL;
534 cpl_test_init(PACKAGE_BUGREPORT,CPL_MSG_WARNING);
535
536 if (argc > 1){
537 fname = argv[1];
538 }
539 else{
540 return 0;
541 }
542 xsh_msg_warning("fname=%s",fname);
543 cpl_table* tab=cpl_table_load(fname,1,0);
545 xsh_free_table(&tab);
546 return cpl_test_end(0);
547}
548
549
int main()
Unit test of xsh_bspline_interpol.
#define xsh_msg_warning(...)
Print an warning message.
Definition: xsh_msg.h:88
static cpl_error_code xsh_line_fill_xbin_ybin_ysig(const int nbins, const double wmin, const double bin, cpl_table *tab, const int *h, double *xbin, double *ybin, double *ysig)
double * xsh_find_em_lines(const int nbins, const int nside, const double min_bk_space, const double intermed_bk_space, const double *local_median, const double *local_stdev, const int *group_nbin, const double *group_mean, const double *group_median, int *pltype, double *bk_space_list)
static cpl_error_code xsh_line_group_stat(const int nbins, const int local_sz, const int nside, const double *xbin, cpl_table *tab, double *local_median, double *local_stdev, int *group_nbin, double *group_mean, double *group_median)
double * xsh_find_abs_lines(const int nbins, const int nside, const double min_bk_space, const double intermed_bk_space, const double *local_median, const double *local_stdev, const int *group_nbin, const double *group_mean, const double *group_median, int *pltype, double *bk_space_list)
static cpl_error_code xsh_lines_set_breakpoints(cpl_table *stab)
static cpl_error_code xsh_find_spectrum_slope_changes(const int nbins, const int nside, const double min_bk_space, const double *ybin, const double *ysig, int *pltype, double *bk_space_list)
cpl_table * xsh_histogram(const cpl_table *data, const char *cname, const int nbins, const double min, const double max)
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
Definition: xsh_utils.c:2133
int xsh_print_rec_status(const int val)
Check if an error has happened and returns error kind and location.
Definition: xsh_dfs.c:877