X-shooter Pipeline Reference Manual 3.8.15
xsh_utils_table.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: 2013-01-03 15:39:30 $
23 * $Revision: 1.33 $
24 * $Name: not supported by cvs2svn $
25 */
26
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30/*----------------------------------------------------------------------------
31 Includes
32 ----------------------------------------------------------------------------*/
33#include <xsh_utils_table.h>
34#include <xsh_utils.h>
35#include <xsh_error.h>
36#include <xsh_pfits.h>
37#include <xsh_msg.h>
38#include <xsh_data_resid_tab.h>
39#include <xsh_data_arclist.h>
40#include <math.h>
41
42#define LINETAB_PIXELSIZE "Pixel"
43#define TWOSQRT2LN2 2.35482004503095
44
45/*----------------------------------------------------------------------------
46 Variables
47 ----------------------------------------------------------------------------*/
48
49/*---------------------------------------------------------------------------*/
57/*---------------------------------------------------------------------------*/
58
61/*-------------------------------------------------------------------------*/
85/*--------------------------------------------------------------------------*/
86
87cpl_table*
88xsh_histogram(const cpl_table* data,
89 const char* cname,
90 const int nbins,
91 const double min,
92 const double max)
93{
94 cpl_table* histo=NULL;
95 cpl_table* tmp_tbl1=NULL;
96 cpl_table* tmp_tbl2=NULL;
97 int ntot=0;
98 int i=0;
99 int* phy=NULL;
100 const double* pdt=NULL;
101 /* double* phx=NULL; */
102
103 double vtmp=0;
104 double vstp=0;
105 double vmax=0;
106 double vmin=0;
107
108 int h=0;
109
110
111 cpl_table_and_selected_double(data,cname,CPL_NOT_GREATER_THAN,max);
112
113 tmp_tbl1=cpl_table_extract_selected(data);
114 cpl_table_and_selected_double(tmp_tbl1,cname,CPL_GREATER_THAN,min);
115 tmp_tbl2=cpl_table_extract_selected(tmp_tbl1);
116 xsh_free_table(&tmp_tbl1);
117
118 ntot=cpl_table_get_nrow(tmp_tbl2);
119 /* not necessry to sort:
120 check_nomsg(sinfo_sort_table_1(tmp_tbl2,cname,FALSE));*/
121 vmin=cpl_table_get_column_min(tmp_tbl2,cname);
122 vmax=cpl_table_get_column_max(tmp_tbl2,cname);
123 vstp=(vmax-vmin)/(nbins-1);
124
125 histo=cpl_table_new(nbins);
126 cpl_table_new_column(histo,"HL",CPL_TYPE_DOUBLE);
127 cpl_table_new_column(histo,"HY",CPL_TYPE_INT);
128 cpl_table_new_column(histo,"HX",CPL_TYPE_DOUBLE);
129
130 cpl_table_fill_column_window(histo,"HL",0,nbins,0);
131 cpl_table_fill_column_window(histo,"HY",0,nbins,0);
132
133 phy=cpl_table_get_data_int(histo,"HY");
134
135 pdt=cpl_table_get_data_double_const(data,cname);
136 //cpl_table_save(data, NULL, NULL, "histo_data.fits", CPL_IO_DEFAULT);
137 for(i=0;i<nbins;i++) {
138 cpl_table_set_double(histo,"HX",i,(double)i);
139 vtmp=vmin+i*vstp;
140 cpl_table_set_double(histo,"HL",i,vtmp);
141 }
142 h=0;
143 for(i=0;i<ntot;i++) {
144 h=floor((pdt[i]-vmin)/vstp);
145 if((h<nbins) && (h>-1)) {
146 phy[h]++;
147 }
148 }
149 //cpl_table_save(histo, NULL, NULL, "histogram.fits", CPL_IO_DEFAULT);
150
151 xsh_free_table(&tmp_tbl2);
152
153
154 return histo;
155
156
157}
158
159
160/*----------------------------------------------------------------------------*/
176/*----------------------------------------------------------------------------*/
177static int
178xsh_wavecal_find_nearest(const cpl_table *line_refer, const char* col_ref,double lambda, int lo, int hi)
179{
180
181 if (lo == hi) /* One-row interval */
182 {
183 return lo;
184 }
185 else if (lo + 1 == hi)
186 { /* Two-row interval */
187 double llo, lhi;
188 check(lhi = cpl_table_get_double(line_refer, col_ref, hi, NULL));
189 check(llo = cpl_table_get_double(line_refer, col_ref, lo, NULL));
190
191 /* Return the one of 'llo' and 'lhi' that is closest to 'lambda' */
192 return ((llo-lambda)*(llo-lambda) < (lhi-lambda)*(lhi-lambda)) ? lo : hi;
193 }
194 else
195 { /* Three or more rows to consider */
196 double lmid;
197 int mid = (lo + hi)/2;
198 /* mid is different from both 'lo' and 'hi', so this will terminate */
199
200 check(lmid = cpl_table_get_double(line_refer, col_ref, mid, NULL));
201
202 if (lmid < lambda)
203 {
204 return xsh_wavecal_find_nearest(line_refer, col_ref, lambda, mid, hi);
205 }
206 else
207 {
208 return xsh_wavecal_find_nearest(line_refer, col_ref, lambda, lo, mid);
209 }
210 }
211
212 cleanup:
213 return -1;
214}
215
216
224static cpl_error_code
226 cpl_propertylist** header_check,
227 const char* element,
228 const double exptime)
229
230{
231 char qc_intavg_name[40];
232 char qc_nlinint_name[40];
233 char comment[40];
234
235 double mean;
236 int nrows=cpl_table_get_nrow(temp);
237 if (nrows == 0)
238 {
239 xsh_msg_warning("No bright lines found!");
240 mean = 0;
241 }
242 else
243 {
244 mean = cpl_table_get_column_mean(temp, "Intensity");
245 }
246
247 sprintf(qc_intavg_name,"%s %s",QC_WAVECAL_INTAVG,element);
248 sprintf(comment,QC_WAVECAL_INTAVG_C);
249 check(cpl_propertylist_append_double(*header_check,qc_intavg_name,mean));
250 check(cpl_propertylist_set_comment(*header_check,qc_intavg_name,comment));
251
252 if(exptime > 0.0){
253 sprintf(qc_intavg_name,"%s NORM%s",QC_WAVECAL_INTAVG,element);
254 sprintf(comment,"exp norm avg int of line list");
255 check(cpl_propertylist_append_double(*header_check,qc_intavg_name,mean/exptime));
256 check(cpl_propertylist_set_comment(*header_check,qc_intavg_name,comment));
257 }
258
259 sprintf(qc_nlinint_name,"%s %s",QC_WAVECAL_NLININT,element);
260 sprintf(comment,QC_WAVECAL_NLININT_C);
261 check(cpl_propertylist_append_int(*header_check,qc_nlinint_name,nrows));
262 check(cpl_propertylist_set_comment(*header_check,qc_nlinint_name,comment));
263
264 cleanup:
265 return cpl_error_get_code();
266
267}
268
276static cpl_table*
277xsh_table_select_matching_waves(cpl_table* table_intmon,
278 const char* col_wave_intmon,
279 cpl_table* table_check,
280 const char* col_wave_intcheck,
281 const double exptime)
282
283{
284
285
286 double tolerance = 0.001; /* (A)
287 The lines in the line table
288 and intmon table are considered
289 identical if the difference
290 is less than this number.
291 */
292
293 int N_bright = cpl_table_get_nrow(table_intmon);
294
295 int i=0;
296 double wmin=cpl_table_get_column_min(table_intmon,"WAVELENGTH");
297 double wmax=cpl_table_get_column_max(table_intmon,"WAVELENGTH");
298 check(cpl_table_and_selected_double(table_check,"Wavelength",CPL_LESS_THAN,wmax+tolerance));
299 check(cpl_table_and_selected_double(table_check,"Wavelength",CPL_GREATER_THAN,wmin-tolerance));
300
301 cpl_table* table_ext=cpl_table_extract_selected(table_check);
302
303 check(cpl_table_new_column(table_ext, "Intensity", CPL_TYPE_DOUBLE));
304 for (i = 0; i < cpl_table_get_nrow(table_ext); i++)
305 {
306 int is_null=0;
307 double ident=0;
308 check(ident=cpl_table_get_double(table_ext, "Wavelength", i, &is_null));
309
310 if (!is_null)
311 {
312 int bright_index = 0;
313 check(bright_index=xsh_wavecal_find_nearest(table_intmon, "WAVELENGTH",
314 ident, 0, N_bright-1));
315
316
317 double bright = 0;
318 check(bright=cpl_table_get_double(table_intmon, "WAVELENGTH", bright_index, NULL));
319
320 if (fabs(bright - ident) < tolerance)
321 {
322 /*
323 double peak = 0;
324 check(peak=cpl_table_get_double(table_ext, "Peak", i, NULL));
325 double pixelsize =
326 fabs(cpl_table_get_double(table_ext, LINETAB_PIXELSIZE, i, NULL));
327
328 double lambda_fwhm = 0;
329 check(lambda_fwhm = cpl_table_get_double(table_ext, "FwhmYGauss", i, NULL)
330 * TWOSQRT2LN2 * pixelsize);
331 */
332 // Line FWHM in wlu
333 double norm=0;
334 check(norm=cpl_table_get_double(table_ext, "NormGauss", i, NULL));
335
336
337 //double intensity = peak * lambda_fwhm / exptime;
338 double intensity=norm/exptime;
339 /* Same formula as in MIDAS */
340
341 check(cpl_table_set_double(table_ext, "Intensity", i, intensity));
342
343 }
344 else
345 {
346 check(cpl_table_set_invalid(table_ext, "Intensity", i));
347 }
348 }
349 else
350 {
351 check(cpl_table_set_invalid(table_ext, "Intensity", i));
352 }
353 }
354
355 cleanup:
356 return table_ext;
357}
358
359
360
369static cpl_error_code
370xsh_wavecal_qclog_element(cpl_table* table_intmon,
371 cpl_table *table_check,
372 const double exptime,
373 const char* atom_name,
374 cpl_propertylist** header_check)
375{
376 cpl_table *ext_intmon = NULL;
377 cpl_table* table_ext=NULL;
378 cpl_table *temp = NULL;
379
380 cpl_table_and_selected_string(table_intmon,"element",CPL_EQUAL_TO,atom_name);
381 ext_intmon=cpl_table_extract_selected(table_intmon);
382
383 table_ext=xsh_table_select_matching_waves(ext_intmon,
384 "WAVELENGTH",
385 table_check,
386 "Wavelength",exptime);
387 xsh_free_table(&temp);
388 temp = cpl_table_duplicate(table_ext);
389 cpl_table_erase_invalid(temp);
390 xsh_wavecal_qclog_compute(temp,header_check,atom_name,exptime);
391 cpl_table_select_all(table_intmon);
392
393
394 xsh_free_table(&temp);
395 xsh_free_table(&ext_intmon);
396 xsh_free_table(&table_ext);
397 return cpl_error_get_code();
398
399}
400
408cpl_error_code
409xsh_wavecal_qclog_intmon(cpl_frame* line_check,
410 const cpl_frame *line_intmon,
411 const double exptime,
412 xsh_instrument* inst)
413{
414 cpl_table *temp = NULL;
415 cpl_table *table_check = NULL;
416 cpl_table *table_intmon = NULL;
417 const char* name_check=NULL;
418 const char* name_intmon=NULL;
419 cpl_propertylist* header_check=NULL;
420 cpl_table* table_ext=NULL;
421
422 check(name_check=cpl_frame_get_filename(line_check));
423 check(table_check=cpl_table_load(name_check,1,0));
424 check(header_check=cpl_propertylist_load(name_check,0));
425
426 check(name_intmon=cpl_frame_get_filename(line_intmon));
427 check(table_intmon=cpl_table_load(name_intmon,1,0));
428
429 if( xsh_instrument_get_arm(inst) == XSH_ARM_NIR) {
430
431 check(xsh_wavecal_qclog_element(table_intmon,table_check,exptime,
432 "AR",&header_check));
433
434 check(xsh_wavecal_qclog_element(table_intmon,table_check,exptime,
435 "NE",&header_check));
436
437 check(xsh_wavecal_qclog_element(table_intmon,table_check,exptime,
438 "XE",&header_check));
439
440 } else {
441
442 check(xsh_wavecal_qclog_element(table_intmon,table_check,exptime,
443 "THAR",&header_check));
444
445 }
446 check(cpl_table_save(table_check,header_check,NULL,name_check,CPL_IO_DEFAULT));
447
448 cleanup:
449 xsh_free_table(&temp);
450 xsh_free_propertylist(&header_check);
451 xsh_free_table(&table_check);
452 xsh_free_table(&table_ext);
453 xsh_free_table(&table_intmon);
454
455 return cpl_error_get_code();
456}
457
458
459/*---------------------------------------------------------------------------*/
471/*---------------------------------------------------------------------------*/
472cpl_error_code xsh_get_table_value (const cpl_table* table,
473 const char *colname, cpl_type coltype, int i, void* result)
474{
475 int flag = 0;
476 /* Check input */
477 XSH_ASSURE_NOT_NULL( table);
478 XSH_ASSURE_NOT_NULL( colname);
479 XSH_ASSURE_NOT_NULL( result);
480
481 /* Read the column */
482
483 switch (coltype) {
484 case CPL_TYPE_INT:
485 check_msg (*((int *) result) = cpl_table_get_int(table,colname,i,&flag),
486 "Could not get (integer) value of %s at row %d", colname,i);
487 break;
488 case CPL_TYPE_FLOAT:
489 check_msg (*((float *) result) = cpl_table_get_float( table,
490 colname,i,&flag),
491 "Could not get (float) value of %s at row %d",colname,i);
492 break;
493 case CPL_TYPE_DOUBLE:
494 check_msg (*((double *) result) = cpl_table_get_double (table,
495 colname,i,&flag),
496 "Could not get (double) value of %s at row %d",colname,i);
497 break;
498 case CPL_TYPE_STRING:
499 check_msg (*((const char **) result) =
500 cpl_table_get_string (table, colname,i),
501 "Could not get (string) value of %s at row %d",colname,i);
502 break;
503 default:
504 assure (false, CPL_ERROR_INVALID_TYPE, "Unknown type");
505 }
506
507cleanup:
508 return cpl_error_get_code ();
509}
510
514
515/*---------------------------------------------------------------------------*/
528/*---------------------------------------------------------------------------*/
529cpl_error_code
530xsh_sort_table_1(cpl_table *t, const char *column, cpl_boolean reverse)
531{
532 cpl_propertylist *plist = NULL;
533
534 assure(t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
535 assure(cpl_table_has_column(t, column), CPL_ERROR_ILLEGAL_INPUT,
536 "No column '%s'", column);
537
538 check_msg(( plist = cpl_propertylist_new(),
539 cpl_propertylist_append_bool(plist, column, reverse)),
540 "Could not create property list for sorting");
541
542 check_msg( cpl_table_sort(t, plist), "Could not sort table");
543
544 cleanup:
545 xsh_free_propertylist(&plist);
546 return cpl_error_get_code();
547}
548
549/*---------------------------------------------------------------------------*/
566/*---------------------------------------------------------------------------*/
567cpl_error_code
568xsh_sort_table_2(cpl_table *t, const char *column1, const char *column2,
569 cpl_boolean reverse1, cpl_boolean reverse2)
570{
571 cpl_propertylist *plist = NULL;
572
573 assure(t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
574 assure(cpl_table_has_column(t, column1), CPL_ERROR_ILLEGAL_INPUT,
575 "No column '%s'", column1);
576 assure(cpl_table_has_column(t, column2), CPL_ERROR_ILLEGAL_INPUT,
577 "No column '%s'", column2);
578
579 check_msg(( plist = cpl_propertylist_new(),
580 cpl_propertylist_append_bool(plist, column1, reverse1),
581 cpl_propertylist_append_bool(plist, column2, reverse2)),
582 "Could not create property list for sorting");
583 check_msg( cpl_table_sort(t, plist), "Could not sort table");
584
585 cleanup:
586 xsh_free_propertylist(&plist);
587 return cpl_error_get_code();
588}
589
590/*---------------------------------------------------------------------------*/
610/*---------------------------------------------------------------------------*/
611cpl_error_code
612xsh_sort_table_3(cpl_table *t, const char *column1, const char *column2,
613 const char *column3,
614 cpl_boolean reverse1, cpl_boolean reverse2,cpl_boolean reverse3)
615{
616 cpl_propertylist *plist = NULL;
617
618 assure(t != NULL, CPL_ERROR_NULL_INPUT, "Null table");
619 assure(cpl_table_has_column(t, column1), CPL_ERROR_ILLEGAL_INPUT,
620 "No column '%s'", column1);
621 assure(cpl_table_has_column(t, column2), CPL_ERROR_ILLEGAL_INPUT,
622 "No column '%s'", column2);
623 assure(cpl_table_has_column(t, column3), CPL_ERROR_ILLEGAL_INPUT,
624 "No column '%s'", column3);
625
626 check_msg(( plist = cpl_propertylist_new(),
627 cpl_propertylist_append_bool(plist, column1, reverse1),
628 cpl_propertylist_append_bool(plist, column2, reverse2),
629 cpl_propertylist_append_bool(plist, column3, reverse3)),
630 "Could not create property list for sorting");
631 check_msg( cpl_table_sort(t, plist), "Could not sort table");
632
633 cleanup:
634 xsh_free_propertylist(&plist);
635 return cpl_error_get_code();
636}
637
638/*---------------------------------------------------------------------------*/
647/*---------------------------------------------------------------------------*/
648double
650 double wav,
651 int nrow,
652 double* pw,
653 double* pe
654 )
655{
656 double y = 0;
657 double w1=pw[0];
658 double w2=pw[nrow-1];
659 double y1_=pe[0]; /*was changed from y1 to y1_ due a warning from compiler - shadowed variable*/
660 double y2=pe[nrow-1];
661 if(wav < pw[0])
662 {
663 w1=pw[0];
664 w2=pw[1];
665 y1_=pe[0];
666 y2=pe[1];
667 }
668 else if (wav > pw[nrow - 1])
669 {
670 w1=pw[nrow - 2];
671 w2=pw[nrow - 1];
672 y1_=pe[nrow - 2];
673 y2=pe[nrow - 1];
674 }
675 else
676 {
677 int l = 0;
678 int h = nrow - 1;
679 int curr_row = 0;
680 curr_row = (h-l) / 2;
681 while( h-l >1 )
682 {
683 if(wav < pw[curr_row])
684 {
685 h = curr_row;
686 }
687 else
688 {
689 l = curr_row;
690 }
691 curr_row = (h-l) / 2 + l;
692 }
693 w1=pw[curr_row];
694 w2=pw[curr_row + 1];
695 y1_=pe[curr_row];
696 y2=pe[curr_row + 1];
697 }
698 y=y1_+(y2-y1_)/(w2-w1)*(wav-w1);
699 return y;
700}
701
702/*---------------------------------------------------------------------------*/
713/*---------------------------------------------------------------------------*/
714double
716 double wav,
717 const char* colx,
718 const char* coly)
719{
720
721 double y=0;
722 double* pe=NULL;
723 double* pw=NULL;
724 int nrow=0;
725
726 check(pw=cpl_table_get_data_double(tbl,colx));
727 check(pe=cpl_table_get_data_double(tbl,coly));
728 check(nrow=cpl_table_get_nrow(tbl));
729
730 y = xsh_data_interpolate(wav, nrow, pw, pe);
731 cleanup:
732 return y;
733
734}
735
746static cpl_error_code
748 const double ws,
749 const double we,
750 const char* prefix,
751 const int index,
752 cpl_propertylist** header)
753{
754
755 double flux=0;
756 cpl_table* ext=NULL;
757 char comment[40];
758 char qc_key[20];
759 int next=0;
760
761 check(cpl_table_and_selected_double(table,"W",CPL_GREATER_THAN,ws));
762 check(next=cpl_table_and_selected_double(table,"W",CPL_LESS_THAN,we));
763 if(next>0) {
764 check(ext=cpl_table_extract_selected(table));
765 check(cpl_table_select_all(table));
766 if(cpl_table_has_valid(ext,"F")) {
767 check(flux=cpl_table_get_column_mean(ext,"F"));
768 } else {
769 flux=-999;
770 }
771 sprintf(qc_key,"ESO QC %s%d",prefix,index);
772 sprintf(comment,"Mean value of %s in %4.0f-%4.0f nm",prefix,ws,we);
773 check(cpl_propertylist_append_double(*header,qc_key,flux));
774 check(cpl_propertylist_set_comment(*header,qc_key,comment));
775 }
776
777
778 cleanup:
779 xsh_free_table(&ext);
780
781 return cpl_error_get_code();
782
783}
784
785
786
787/*---------------------------------------------------------------------------*/
788/*---------------------------------------------------------------------------*/
798static cpl_propertylist*
800 const char* colw,
801 const char* colf,
802 const char* prefix,
804{
805 cpl_propertylist* header=NULL;
806
807 XSH_ASSURE_NOT_NULL_MSG(table,"Null input table");
808 header=cpl_propertylist_new();
809 check(cpl_table_cast_column(table,colw,"W",CPL_TYPE_DOUBLE));
810 check(cpl_table_cast_column(table,colf,"F",CPL_TYPE_DOUBLE));
811
813
814 check( xsh_table_monitor_flux_qc(table,450,470,prefix,1,&header));
815 check( xsh_table_monitor_flux_qc(table,510,530,prefix,2,&header));
816
817 }
819
820 check( xsh_table_monitor_flux_qc(table,672,680,prefix,1,&header));
821 check( xsh_table_monitor_flux_qc(table,745,756,prefix,2,&header));
822 check( xsh_table_monitor_flux_qc(table,992,999,prefix,3,&header));
823
824 }
826
827 check( xsh_table_monitor_flux_qc(table,1514,1548,prefix,1,&header));
828 check( xsh_table_monitor_flux_qc(table,2214,2243,prefix,2,&header));
829
830 }
831
832 cpl_table_erase_column(table,"W");
833 cpl_table_erase_column(table,"F");
834
835cleanup:
836 if(cpl_error_get_code() != CPL_ERROR_NONE) {
837 return NULL;
838 } else {
839 return header;
840 }
841}
842
843
844/*---------------------------------------------------------------------------*/
854/*---------------------------------------------------------------------------*/
855cpl_error_code
857 const char* colw,
858 const char* colf,
859 const char* prefix,
861{
862
863 const char* name=NULL;
864 cpl_table* table=NULL;
865 cpl_propertylist* header=NULL;
866 cpl_propertylist* qc_header=NULL;
867
868 int next=0;
869 int ext=0;
870
871 XSH_ASSURE_NOT_NULL_MSG(frm,"Null input spectrum frame");
872 next=cpl_frame_get_nextensions(frm);
873 name=cpl_frame_get_filename(frm);
874
875 /* compute QC */
876
877 if (next) {
878 for(ext=1;ext<=next;ext++) {
879
880 table=cpl_table_load(name,1,ext);
881 check(header=cpl_propertylist_load(name,0));
882 check(qc_header=xsh_frame_table_monitor_flux_qc_ext(table,colw,colf,
883 prefix,instrument));
884 cpl_propertylist_append(header,qc_header);
885 if(next==1) {
886 check(cpl_table_save(table,header,NULL,name,CPL_IO_DEFAULT));
887 } else {
888 check(cpl_table_save(table,header,NULL,name,CPL_IO_EXTEND));
889 }
890 xsh_free_table(&table);
891 xsh_free_propertylist(&qc_header);
892 xsh_free_propertylist(&header);
893 }
894 } else {
895 table=cpl_table_load(name,1,0);
896 check(header=cpl_propertylist_load(name,0));
897 check(qc_header=xsh_frame_table_monitor_flux_qc_ext(table,colw,colf,
898 prefix,instrument));
899 cpl_propertylist_append(header,qc_header);
900 check(cpl_table_save(table,header,NULL,name,CPL_IO_DEFAULT));
901 xsh_free_propertylist(&qc_header);
902 xsh_free_propertylist(&header);
903 }
904
905 cleanup:
906 xsh_free_table(&table);
907 xsh_free_propertylist(&qc_header);
908 xsh_free_propertylist(&header);
909
910 return cpl_error_get_code();
911
912}
913
914cpl_error_code
915xsh_table_merge_clean_and_resid_tabs(cpl_frame* frm_resid,cpl_frame* frm_clean)
916{
917
918 double* pwav_resid=NULL;
919 float* pwav_clean=NULL;
920 double* pwav_extra=NULL;
921 cpl_table* resid=NULL;
922 cpl_table* clean=NULL;
923
924 int nrows_clean=0;
925 int nrows_resid=0;
926 int i=0;
927 int k=0;
928 double wave_acc=0.001; /* [nm] */
929 const char* name=NULL;
930 cpl_propertylist* rhead=NULL;
931 cpl_propertylist* qc_head=NULL;
932 //cpl_propertylist* chead=NULL;
933
934 XSH_ASSURE_NOT_NULL_MSG(frm_resid, "Null input resid table frame");
935 XSH_ASSURE_NOT_NULL_MSG(frm_clean, "Null input clean table frame");
936
937 check(name = cpl_frame_get_filename(frm_clean));
938 check(clean = cpl_table_load(name, 1, 0));
939 check(nrows_clean = cpl_table_get_nrow(clean));
940 check(name = cpl_frame_get_filename(frm_resid));
941 resid = cpl_table_load(name, 1, 0);
942
943 rhead = cpl_propertylist_load(name, 0);
944
945 qc_head=cpl_propertylist_load_regexp(cpl_frame_get_filename(frm_clean),0,"^ESO QC",0);
946 cpl_propertylist_append(rhead,qc_head);
947
948 cpl_frame_get_nextensions(frm_resid);
949 check(nrows_resid=cpl_table_get_nrow(resid));
950 cpl_table_new_column(resid,"WavelengthClean",CPL_TYPE_DOUBLE);
951 cpl_table_fill_column_window_double(resid,"WavelengthClean",0,nrows_resid,0);
952 check(pwav_resid=cpl_table_get_data_double(resid,XSH_RESID_TAB_TABLE_COLNAME_WAVELENGTH));
953 check(pwav_clean=cpl_table_get_data_float(clean,XSH_ARCLIST_TABLE_COLNAME_WAVELENGTH));
954 check(pwav_extra=cpl_table_get_data_double(resid,"WavelengthClean"));
955
956 for (i = 0; i < nrows_clean; i++) {
957 for (k = 0; k < nrows_resid; k++) {
958 if (fabs(pwav_resid[k] - pwav_clean[i]) < wave_acc) {
959 pwav_extra[i] = pwav_clean[i];
960 }
961 }
962 }
963
964 check(cpl_table_save(resid,rhead,NULL,name,CPL_IO_DEFAULT));
965
966 cleanup:
967
968 xsh_free_table(&resid);
969 xsh_free_table(&clean);
970 xsh_free_propertylist(&rhead);
971 xsh_free_propertylist(&qc_head);
972 return cpl_error_get_code();
973}
974
975
976cpl_table*
977xsh_table_shift_rv(cpl_table* orig, const char* col_wave,const double offset) {
978 cpl_table* shifted = NULL;
979 double* pwav = NULL;
980 int nrows=0;
981 int i=0;
982 XSH_ASSURE_NOT_NULL_MSG(orig, "Null input table");
983
984 shifted=cpl_table_duplicate(orig);
985 pwav = cpl_table_get_data_double(shifted, col_wave);
986 nrows=cpl_table_get_nrow(shifted);
987 for(i=0;i<nrows;i++){
988 pwav[i] *= (1.+offset);
989 }
990cleanup:
991 return shifted;
992}
static double exptime
static xsh_instrument * instrument
#define XSH_ASSURE_NOT_NULL_MSG(pointer, msg)
Definition: xsh_error.h:103
#define assure(CONDITION, ERROR_CODE,...)
Definition: xsh_error.h:54
#define check(COMMAND)
Definition: xsh_error.h:71
#define check_msg(COMMAND,...)
Definition: xsh_error.h:62
#define XSH_ASSURE_NOT_NULL(pointer)
Definition: xsh_error.h:99
XSH_ARM xsh_instrument_get_arm(xsh_instrument *i)
Get an arm on instrument structure.
int * y
#define xsh_msg_warning(...)
Print an warning message.
Definition: xsh_msg.h:88
cpl_error_code xsh_wavecal_qclog_intmon(cpl_frame *line_check, const cpl_frame *line_intmon, const double exptime, xsh_instrument *inst)
computes intmon QC log
static cpl_error_code xsh_wavecal_qclog_element(cpl_table *table_intmon, cpl_table *table_check, const double exptime, const char *atom_name, cpl_propertylist **header_check)
computes intmon QC log
static cpl_table * xsh_table_select_matching_waves(cpl_table *table_intmon, const char *col_wave_intmon, cpl_table *table_check, const char *col_wave_intcheck, const double exptime)
Match reference and actual table via wavelength column.
cpl_error_code xsh_table_merge_clean_and_resid_tabs(cpl_frame *frm_resid, cpl_frame *frm_clean)
cpl_error_code xsh_sort_table_2(cpl_table *t, const char *column1, const char *column2, cpl_boolean reverse1, cpl_boolean reverse2)
Sort a table by two columns.
static cpl_error_code xsh_table_monitor_flux_qc(cpl_table *table, const double ws, const double we, const char *prefix, const int index, cpl_propertylist **header)
Computes statistics on spectrum for QC.
cpl_error_code xsh_sort_table_1(cpl_table *t, const char *column, cpl_boolean reverse)
Sort a table by one column.
double xsh_data_interpolate(double wav, int nrow, double *pw, double *pe)
Interpolate data points.
cpl_table * xsh_table_shift_rv(cpl_table *orig, const char *col_wave, const double offset)
static cpl_propertylist * xsh_frame_table_monitor_flux_qc_ext(cpl_table *table, const char *colw, const char *colf, const char *prefix, xsh_instrument *instrument)
Computes statistics on spectrum for QC.
cpl_table * xsh_histogram(const cpl_table *data, const char *cname, const int nbins, const double min, const double max)
cpl_error_code xsh_frame_table_monitor_flux_qc(cpl_frame *frm, const char *colw, const char *colf, const char *prefix, xsh_instrument *instrument)
Computes statistics on spectrum for QC.
double xsh_table_interpolate(cpl_table *tbl, double wav, const char *colx, const char *coly)
Interpolate table columns.
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
Definition: xsh_utils.c:2133
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
Definition: xsh_utils.c:2179
cpl_error_code xsh_get_table_value(const cpl_table *table, const char *colname, cpl_type coltype, int i, void *result)
Read a table value from a fits table.
cpl_error_code xsh_sort_table_3(cpl_table *t, const char *column1, const char *column2, const char *column3, cpl_boolean reverse1, cpl_boolean reverse2, cpl_boolean reverse3)
Sort a table by two columns.
static cpl_error_code xsh_wavecal_qclog_compute(cpl_table *temp, cpl_propertylist **header_check, const char *element, const double exptime)
computes intmon QC log
static int xsh_wavecal_find_nearest(const cpl_table *line_refer, const char *col_ref, double lambda, int lo, int hi)
Find best matching catalogue wavelength.
#define XSH_ARCLIST_TABLE_COLNAME_WAVELENGTH
@ XSH_ARM_UVB
@ XSH_ARM_NIR
@ XSH_ARM_VIS
#define XSH_RESID_TAB_TABLE_COLNAME_WAVELENGTH
double tolerance
#define max(a, b)
#define QC_WAVECAL_NLININT
Definition: xsh_pfits_qc.h:198
#define QC_WAVECAL_NLININT_C
Definition: xsh_pfits_qc.h:199
#define QC_WAVECAL_INTAVG
Definition: xsh_pfits_qc.h:202
#define QC_WAVECAL_INTAVG_C
Definition: xsh_pfits_qc.h:203
#define XSH_TABLE_GET_ARRAY(TYPE)