SINFONI Pipeline Reference Manual  2.5.2
irplib_stdstar.c
1 /* $Id: irplib_stdstar.c,v 1.45 2013-03-01 10:27:07 llundin Exp $
2  *
3  * This file is part of the irplib package
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: llundin $
23  * $Date: 2013-03-01 10:27:07 $
24  * $Revision: 1.45 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include "irplib_stdstar.h"
37 #include "irplib_utils.h"
38 #include "irplib_wcs.h"
39 #include <cpl.h>
40 
41 #include <string.h>
42 #include <math.h>
43 #include <float.h>
44 
45 /*-----------------------------------------------------------------------------
46  Defines
47  -----------------------------------------------------------------------------*/
48 
49 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(6, 3, 0)
50 #define IRPLIB_FRAMESET_GET_CONST cpl_frameset_get_position_const
51 #else
52 /* Remove this branch once CPL versions less than 6.3 are no longer supported */
53 #define IRPLIB_FRAMESET_GET_CONST cpl_frameset_get_frame_const
54 #endif
55 
56 
57 /*----------------------------------------------------------------------------*/
61 /*----------------------------------------------------------------------------*/
64 /*-----------------------------------------------------------------------------
65  Functions code
66  -----------------------------------------------------------------------------*/
67 
68 /*----------------------------------------------------------------------------*/
87 /*----------------------------------------------------------------------------*/
88 cpl_error_code
89 irplib_stdstar_write_catalogs(cpl_frameset * set_in,
90  const cpl_frameset * set_raw,
91  const char * recipe_name,
92  const char * pro_cat,
93  const char * pro_type,
94  const char * package_name,
95  const char * ins_name,
96  cpl_table * (*convert_ascii_table)(const char *))
97 {
98  /* Number of catalogs */
99  const cpl_size nb_catalogs = cpl_frameset_get_size(set_raw);
100  cpl_propertylist * plist_ext;
101  char * out_name;
102  cpl_error_code error = CPL_ERROR_NONE;
103  cpl_size i;
104 
105  /* Check entries */
106  if (set_in == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
107  if (set_raw == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
108  if (recipe_name == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
109  if (pro_cat == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
110  if (ins_name == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
111  if (convert_ascii_table == NULL) return
112  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
113 
114  /* Define the file name */
115  out_name = cpl_sprintf("%s" CPL_DFS_FITS, recipe_name);
116 
117  plist_ext = cpl_propertylist_new();
118 
119  /* Process the catalogs */
120  for (i = 0; i < nb_catalogs; i++) {
121  /* Get the catalog name */
122  const cpl_frame * cur_frame = IRPLIB_FRAMESET_GET_CONST(set_raw, i);
123  const char * cat_name = cpl_frame_get_filename(cur_frame);
124 
125  cpl_table * out = convert_ascii_table(cat_name);
126 
127  /* Create the output table */
128  if (out == NULL) {
129  error = cpl_error_get_code() ? cpl_error_set_where(cpl_func)
130  : cpl_error_set(cpl_func, CPL_ERROR_UNSPECIFIED);
131  break;
132  }
133 
134  if (cpl_table_get_nrow(out) == 0) {
135  cpl_table_delete(out);
136  error = cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
137  "Empty catalogue %d in '%s'",
138  (int)i+1, cat_name);
139  break;
140  }
141 
142  cpl_propertylist_update_string(plist_ext, "EXTNAME", cat_name);
143 
144  /* Write the table */
145  if (i == 0) {
146  cpl_parameterlist * parlist = cpl_parameterlist_new();
147  cpl_propertylist * plist = cpl_propertylist_new();
148 
149  /* Mandatory keywords */
150  cpl_propertylist_append_string(plist, "INSTRUME", ins_name);
151  cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG, pro_cat);
152  if (pro_type != NULL) {
153  cpl_propertylist_append_string(plist, CPL_DFS_PRO_TYPE,
154  pro_type);
155  }
156 
157  error = cpl_dfs_save_table(set_in, NULL, parlist, set_raw, NULL,
158  out, plist_ext, recipe_name, plist,
159  NULL, package_name, out_name);
160  cpl_parameterlist_delete(parlist);
161  cpl_propertylist_delete(plist);
162  } else {
163  error = cpl_table_save(out, NULL, plist_ext, out_name,
164  CPL_IO_EXTEND);
165  }
166 
167  cpl_table_delete(out);
168 
169  if (error) {
170  (void)cpl_error_set_where(cpl_func);
171  break;
172  }
173  }
174 
175  cpl_propertylist_delete(plist_ext);
176  cpl_free(out_name);
177 
178  return error;
179 }
180 
181 /*----------------------------------------------------------------------------*/
194 /*----------------------------------------------------------------------------*/
196  const char * filename,
197  const char * ext_name)
198 {
199  int next;
200  cpl_propertylist * plist;
201  const char * cur_name;
202  cpl_table * out;
203  cpl_table * out_cur;
204  cpl_frame * cur_frame;
205  int i;
206 
207  /* Check entries */
208  if (filename == NULL) return NULL;
209  if (ext_name == NULL) return NULL;
210 
211  /* Initialise */
212  out = NULL;
213 
214  /* Get the number of extensions in the catalog */
215  cur_frame = cpl_frame_new();
216  cpl_frame_set_filename(cur_frame, filename);
217  next = cpl_frame_get_nextensions(cur_frame);
218  cpl_frame_delete(cur_frame);
219 
220  /* Loop on the extentions */
221  for (i=0; i<next; i++) {
222  /* Check the name of the current extension */
223  if ((plist = cpl_propertylist_load_regexp(filename, i+1, "EXTNAME",
224  0)) == NULL) {
225  cpl_msg_error(cpl_func, "Cannot load header of %d th extension",
226  i+1);
227  return NULL;
228  }
229  cur_name = cpl_propertylist_get_string(plist, "EXTNAME");
230 
231  /* Check the current extension */
232  if (!strcmp(cur_name, ext_name)) {
233  /* Load the table */
234  if (out == NULL) {
235  out = cpl_table_load(filename, i+1, 1);
236  cpl_table_new_column(out, IRPLIB_STDSTAR_CAT_COL, CPL_TYPE_STRING);
237  cpl_table_fill_column_window_string(out, IRPLIB_STDSTAR_CAT_COL,
238  0, cpl_table_get_nrow(out),
239  cur_name);
240  if (out == NULL) {
241  cpl_msg_error(cpl_func, "Cannot load extension %d", i+1);
242  cpl_propertylist_delete(plist);
243  return NULL;
244  }
245  }
246  } else if (!strcmp(ext_name, "all")) {
247  /* Load the table and append it */
248  if (i==0) {
249  /* Load the first table */
250  out = cpl_table_load(filename, i+1, 1);
251  cpl_table_new_column(out, IRPLIB_STDSTAR_CAT_COL, CPL_TYPE_STRING);
252  cpl_table_fill_column_window_string(out, IRPLIB_STDSTAR_CAT_COL,
253  0, cpl_table_get_nrow(out),
254  cur_name);
255  if (out == NULL) {
256  cpl_msg_error(cpl_func, "Cannot load extension %d", i+1);
257  cpl_propertylist_delete(plist);
258  return NULL;
259  }
260  } else {
261  /* Load the current table */
262  out_cur = cpl_table_load(filename, i+1, 1);
263  if (out_cur == NULL) {
264  cpl_msg_error(cpl_func, "Cannot load extension %d", i+1);
265  cpl_table_delete(out);
266  cpl_propertylist_delete(plist);
267  return NULL;
268  }
269  cpl_table_new_column(out_cur, IRPLIB_STDSTAR_CAT_COL, CPL_TYPE_STRING);
270  cpl_table_fill_column_window_string(out_cur, IRPLIB_STDSTAR_CAT_COL,
271  0, cpl_table_get_nrow(out_cur),
272  cur_name);
273  /* Append the table */
274  if (cpl_table_insert(out, out_cur,
275  cpl_table_get_nrow(out)) != CPL_ERROR_NONE) {
276  cpl_msg_error(cpl_func, "Cannot merge table %d", i+1);
277  cpl_table_delete(out);
278  cpl_table_delete(out_cur);
279  cpl_propertylist_delete(plist);
280  return NULL;
281  }
282  cpl_table_delete(out_cur);
283  }
284  }
285  cpl_propertylist_delete(plist);
286  }
287  return out;
288 }
289 
290 /*----------------------------------------------------------------------------*/
299 /*----------------------------------------------------------------------------*/
301  const cpl_table * catal)
302 {
303  /* Check for all the mandatory columns */
304  if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_STAR_COL)) {
305  return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
306  "Missing column: %s",
307  IRPLIB_STDSTAR_STAR_COL);
308  }
309  if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_TYPE_COL)) {
310  return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
311  "Missing column: %s",
312  IRPLIB_STDSTAR_TYPE_COL);
313  }
314  if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_CAT_COL)) {
315  return cpl_error_set_message(cpl_func,
316  CPL_ERROR_ILLEGAL_INPUT,
317  "Missing column: %s",
318  IRPLIB_STDSTAR_CAT_COL);
319  }
320  if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_RA_COL)) {
321  return cpl_error_set_message(cpl_func,
322  CPL_ERROR_ILLEGAL_INPUT,
323  "Missing column: %s",
324  IRPLIB_STDSTAR_RA_COL);
325  }
326  if (!cpl_table_has_column(catal, IRPLIB_STDSTAR_DEC_COL)) {
327  return cpl_error_set_message(cpl_func,
328  CPL_ERROR_ILLEGAL_INPUT,
329  "Missing column: %s",
330  IRPLIB_STDSTAR_DEC_COL);
331  }
332  return CPL_ERROR_NONE;
333 }
334 
335 /*----------------------------------------------------------------------------*/
347 /*----------------------------------------------------------------------------*/
349  cpl_table * cat,
350  double ra,
351  double dec,
352  double dist)
353 {
354  double distance;
355  int nrows;
356  int i;
357 
358  /* Check entries */
359  if (cat == NULL) return -1;
360 
361  /* Get the number of selected rows */
362  nrows = cpl_table_get_nrow(cat);
363 
364  /* Check if the columns are there */
365  if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_RA_COL)) {
366  cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_RA_COL);
367  return -1;
368  }
369  if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_DEC_COL)) {
370  cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_DEC_COL);
371  return -1;
372  }
373 
374  /* Compute distances of the selected rows */
375  for (i=0; i<nrows; i++) {
376  if (cpl_table_is_selected(cat, i)) {
377  /* The row is selected - compute the distance */
378  distance = irplib_wcs_great_circle_dist(ra, dec,
379  cpl_table_get_double(cat, IRPLIB_STDSTAR_RA_COL, i, NULL),
380  cpl_table_get_double(cat, IRPLIB_STDSTAR_DEC_COL, i, NULL));
381  if (distance > dist) cpl_table_unselect_row(cat, i);
382  }
383  }
384  return 0;
385 }
386 
387 /*----------------------------------------------------------------------------*/
396 /*----------------------------------------------------------------------------*/
398  cpl_table * cat,
399  const char * mag_colname)
400 {
401  /* Check entries */
402  if (cat == NULL) return -1;
403  if (mag_colname == NULL) return -1;
404 
405  /* Check that the table has the mag column */
406  if (!cpl_table_has_column(cat, mag_colname)) {
407  cpl_msg_error(cpl_func, "Column %s does not exist in the catalog",
408  mag_colname);
409  return -1;
410  }
411 
412  /* Apply the selection */
413  if (cpl_table_and_selected_double(cat, mag_colname, CPL_NOT_GREATER_THAN,
414  98.0) <= 0) {
415  cpl_msg_error(cpl_func, "Column %s does not exist in the catalog",
416  mag_colname);
417  return -1;
418  }
419  return 0;
420 }
421 
422 /*----------------------------------------------------------------------------*/
432 /*----------------------------------------------------------------------------*/
434  const cpl_table * cat,
435  double ra,
436  double dec)
437 {
438  double min_dist, distance;
439  int nrows;
440  int ind;
441  int i;
442 
443  /* Check entries */
444  if (cat == NULL) return -1;
445 
446  /* Initialize */
447  min_dist = 1000.0;
448  ind = -1;
449 
450  /* Get the number of selected rows */
451  nrows = cpl_table_get_nrow(cat);
452 
453  /* Check if the columns are there */
454  if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_RA_COL)) {
455  cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_RA_COL);
456  return -1;
457  }
458  if (!cpl_table_has_column(cat, IRPLIB_STDSTAR_DEC_COL)) {
459  cpl_msg_error(cpl_func, "Missing %s column", IRPLIB_STDSTAR_DEC_COL);
460  return -1;
461  }
462 
463  /* Compute distances of the selected rows */
464  for (i=0; i<nrows; i++) {
465  if (cpl_table_is_selected(cat, i)) {
466  /* The row is selected - compute the distance */
467  distance = irplib_wcs_great_circle_dist(ra, dec,
468  cpl_table_get_double(cat, IRPLIB_STDSTAR_RA_COL, i, NULL),
469  cpl_table_get_double(cat, IRPLIB_STDSTAR_DEC_COL, i, NULL));
470  if (distance <= min_dist) {
471  min_dist = distance;
472  ind = i;
473  }
474  }
475  }
476  return ind;
477 }
478 
479 /*----------------------------------------------------------------------------*/
500 /*----------------------------------------------------------------------------*/
502  const char * catfile,
503  double ra,
504  double dec,
505  const char * band,
506  const char * catname,
507  double * mag,
508  char ** name,
509  char ** type,
510  char ** usedcatname,
511  double * star_ra,
512  double * star_dec,
513  double dist_am)
514 {
515  cpl_errorstate prestate = cpl_errorstate_get();
516  cpl_table * catal;
517  const double dist = dist_am / 60.0;
518  int ind;
519 
520  /* Check entries */
521  if (catfile == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
522  if (band == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
523  if (catname == NULL) return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
524 
525  /* Load the catalog */
526  if ((catal = irplib_stdstar_load_catalog(catfile, catname)) == NULL) {
527  return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_NOT_FOUND,
528  "Cannot load the catalog %s from %s",
529  catname, catfile);
530  }
531 
532  /* Check the columns are present */
533  if (irplib_stdstar_check_columns_exist(catal) != CPL_ERROR_NONE) {
534  cpl_table_delete(catal);
535  return cpl_error_set_where(cpl_func);
536  }
537 
538  /* Select stars with known magnitude */
539  if (irplib_stdstar_select_stars_mag(catal, band) == -1) {
540  cpl_table_delete(catal);
541  return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
542  "Cannot select stars in that band");
543  }
544 
545  /* Select stars within a given distance */
546  if (irplib_stdstar_select_stars_dist(catal, ra, dec, dist) == -1) {
547  cpl_table_delete(catal);
548  return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
549  "Cannot select close stars");
550  }
551 
552  /* Take the closest */
553  if ((ind=irplib_stdstar_find_closest(catal, ra, dec)) < 0) {
554  cpl_table_delete(catal);
555  return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
556  "Cannot get the closest star with "
557  "known %s magnitude",band);
558  }
559 
560  if(mag != NULL)
561  *mag = cpl_table_get_double(catal, band, ind, NULL);
562 
563  if(name != NULL)
564  {
565  *name = cpl_strdup(cpl_table_get_string(catal,
566  IRPLIB_STDSTAR_STAR_COL, ind));
567 
568  }
569  if(type != NULL)
570  {
571  *type = cpl_strdup(cpl_table_get_string(catal, IRPLIB_STDSTAR_TYPE_COL,
572  ind));
573  }
574  if(usedcatname != NULL)
575  {
576  if(strcmp(catname, "all"))
577  *usedcatname = cpl_strdup(catname);
578  else
579  {
580  *usedcatname = cpl_strdup(cpl_table_get_string
581  (catal, IRPLIB_STDSTAR_CAT_COL, ind));
582  }
583  }
584  if(star_ra != NULL)
585  *star_ra = cpl_table_get_double(catal, IRPLIB_STDSTAR_RA_COL, ind, NULL);
586  if(star_dec != NULL)
587  *star_dec = cpl_table_get_double(catal, IRPLIB_STDSTAR_DEC_COL, ind, NULL);
588 
589  /* Free and return */
590  cpl_table_delete(catal);
591  return cpl_errorstate_is_equal(prestate) ? CPL_ERROR_NONE
592  : cpl_error_set_where(cpl_func);
593 }
594 
595 /*----------------------------------------------------------------------------*/
608 /*----------------------------------------------------------------------------*/
610  const cpl_bivector * spec,
611  double dit,
612  double surface,
613  double gain,
614  double mag)
615 {
616  double h = 6.62e-27;
617  double c = 3e18;
618  const cpl_vector * wave;
619  const cpl_vector * extr;
620  cpl_vector * out;
621  double factor;
622 
623  /* Test entries */
624  if (spec == NULL) return NULL;
625  if (dit <= 0.0) return NULL;
626 
627  /* Get the extracted spectrum */
628  wave = cpl_bivector_get_x_const(spec);
629  extr = cpl_bivector_get_y_const(spec);
630 
631  /* Get the spectrum */
632  out = cpl_vector_duplicate(extr);
633 
634  /* Divide by DIT */
635  cpl_vector_divide_scalar(out, dit);
636 
637  /* Divide by the surface */
638  cpl_vector_divide_scalar(out, surface);
639 
640  /* Multiply by the gain */
641  cpl_vector_multiply_scalar(out, gain);
642 
643  /* Multiply by the difference magnitude */
644  factor = pow(10, mag/2.5);
645  cpl_vector_multiply_scalar(out, factor);
646 
647  /* Divide by the dispersion */
648  factor = (cpl_vector_get(wave, cpl_vector_get_size(wave)-1) -
649  cpl_vector_get(wave, 0)) / cpl_vector_get_size(wave);
650  cpl_vector_divide_scalar(out, factor);
651 
652  /* Multiply by the energy of the photon */
653  cpl_vector_multiply_scalar(out, h*c);
654  cpl_vector_divide(out, wave);
655 
656  return out;
657 }
658 
659 /*----------------------------------------------------------------------------*/
667 /*----------------------------------------------------------------------------*/
669  const cpl_bivector * sed,
670  const cpl_vector * waves,
671  double cent_wl)
672 {
673  double wmin, wmax, wstep;
674  int nb_sed;
675  const double * sed_x;
676  const double * sed_y;
677  cpl_bivector * sed_loc;
678  double * sed_loc_x;
679  double * sed_loc_y;
680  cpl_vector * out;
681  cpl_bivector * out_biv;
682  double f0_jan, f0_erg, cent_val;
683  int i;
684 
685  /* Test entries */
686  if (sed == NULL) return NULL;
687  if (waves == NULL) return NULL;
688 
689  /* Initialise */
690  nb_sed = cpl_bivector_get_size(sed);
691  sed_x = cpl_bivector_get_x_data_const(sed);
692  sed_y = cpl_bivector_get_y_data_const(sed);
693  wstep = sed_x[1] - sed_x[0];
694  wmin = cpl_vector_get(waves, 0);
695  wmax = cpl_vector_get(waves, cpl_vector_get_size(waves)-1);
696 
697  /* Expand sed with 0 to have it bigger than the required wavelengths */
698  sed_loc = cpl_bivector_new(nb_sed + 4);
699  sed_loc_x = cpl_bivector_get_x_data(sed_loc);
700  sed_loc_y = cpl_bivector_get_y_data(sed_loc);
701  for (i=0; i<nb_sed; i++) {
702  sed_loc_x[i+2] = sed_x[i];
703  sed_loc_y[i+2] = sed_y[i];
704  }
705 
706  /* Low bound */
707  sed_loc_x[1] = sed_loc_x[2] - wstep;
708  if (sed_loc_x[2] < wmin) {
709  sed_loc_x[0] = sed_loc_x[1] - wstep;
710  } else {
711  sed_loc_x[0] = wmin - wstep;
712  }
713  sed_loc_y[0] = 1e-20;
714  sed_loc_y[1] = 1e-20;
715 
716  /* High bound */
717  sed_loc_x[nb_sed+2] = sed_loc_x[nb_sed+1] + wstep;
718  if (sed_loc_x[nb_sed+1] > wmax) {
719  sed_loc_x[nb_sed+3] = sed_loc_x[nb_sed+2] + wstep;
720  } else {
721  sed_loc_x[nb_sed+3] = wmax + wstep;
722  }
723  sed_loc_y[nb_sed+2] = 1e-20;
724  sed_loc_y[nb_sed+3] = 1e-20;
725 
726  /* Create the output bivector */
727  out = cpl_vector_duplicate(waves);
728  IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
729  /* the X entry (waves) is not modified by cpl_bivector_interpolate_linear */
730  out_biv = cpl_bivector_wrap_vectors((cpl_vector*)waves, out);
731  IRPLIB_DIAG_PRAGMA_POP;
732  /* Interpolate */
733  if (cpl_bivector_interpolate_linear(out_biv, sed_loc) != CPL_ERROR_NONE) {
734  cpl_msg_error(cpl_func, "Cannot interpolate the wavelength");
735  cpl_bivector_unwrap_vectors(out_biv);
736  cpl_vector_delete(out);
737  cpl_bivector_delete(sed_loc);
738  return NULL;
739  }
740  cpl_bivector_unwrap_vectors(out_biv);
741  cpl_bivector_delete(sed_loc);
742 
743  /* Compute f0_jan */
744  f0_jan = 5513.15 / ( pow(cent_wl,3) * (exp(1.2848/cent_wl)-1) );
745 
746  /* Convert f0 Jansky -> ergs/s/cm^2/Angstrom */
747  f0_erg = f0_jan * 1e-26 * 1e7 * 3e18 / (1e4 * cent_wl*cent_wl*1e4*1e4);
748 
749  /* Scale out so that the central value is f0 */
750  cent_val = cpl_vector_get(out, cpl_vector_get_size(out)/2);
751  if (cent_val <= 0.0) {
752  cpl_msg_error(cpl_func, "Negative or 0 central value");
753  cpl_vector_delete(out);
754  return NULL;
755  }
756  cpl_vector_multiply_scalar(out, f0_erg/cent_val);
757 
758  /* Return */
759  return out;
760 }
761 
762 /*----------------------------------------------------------------------------*/
772 /*----------------------------------------------------------------------------*/
773 cpl_bivector * irplib_stdstar_get_sed(
774  const char * seds_file,
775  const char * sptype)
776 {
777  cpl_table * seds;
778  cpl_bivector * out;
779  cpl_vector * wave;
780  cpl_vector * sed;
781  cpl_bivector * tmp;
782  int nlines;
783 
784  /* Test entries */
785  if (seds_file == NULL) return NULL;
786  if (sptype == NULL) return NULL;
787 
788  /* Load the table */
789  if ((seds = cpl_table_load(seds_file, 1, 0)) == NULL) {
790  cpl_msg_error(cpl_func, "Cannot load the table");
791  return NULL;
792  }
793 
794  /* Check if the column is there */
795  if (!cpl_table_has_column(seds, sptype)) {
796  cpl_msg_error(cpl_func, "SED of the requested star not available");
797  cpl_table_delete(seds);
798  return NULL;
799  }
800 
801  /* Get the nb lines */
802  nlines = cpl_table_get_nrow(seds);
803 
804  /* Get the wavelength as a vector */
805  if ((wave = cpl_vector_wrap(nlines,
806  cpl_table_get_data_double(seds, "Wavelength"))) == NULL) {
807  cpl_msg_error(cpl_func, "Cannot get the Wavelength column");
808  cpl_table_delete(seds);
809  return NULL;
810  }
811 
812  /* Get the SED as a vector */
813  if ((sed = cpl_vector_wrap(nlines,
814  cpl_table_get_data_double(seds, sptype))) == NULL) {
815  cpl_msg_error(cpl_func, "Cannot get the SED column");
816  cpl_table_delete(seds);
817  cpl_vector_unwrap(wave);
818  return NULL;
819  }
820  tmp = cpl_bivector_wrap_vectors(wave, sed);
821 
822  /* Create the output bivector */
823  out = cpl_bivector_duplicate(tmp);
824 
825  /* Free */
826  cpl_bivector_unwrap_vectors(tmp);
827  cpl_vector_unwrap(wave);
828  cpl_vector_unwrap(sed);
829  cpl_table_delete(seds);
830 
831  /* Return */
832  return out;
833 }