ERIS Pipeline Reference Manual 1.9.2
sc_basic.c
Go to the documentation of this file.
1/*
2 * This file is part of the SKYCORR software package.
3 * Copyright (C) 2009-2013 European Southern Observatory
4 *
5 * This programme 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 programme 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 programme. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
39/*****************************************************************************
40 * INCLUDES *
41 ****************************************************************************/
42
43#include <sc_basic.h>
44
45#include <math.h>
46
47
48/*****************************************************************************
49 * CODE *
50 ****************************************************************************/
51
52cpl_error_code sc_basic_readline(FILE *stream, scpar par[], int *npar)
53{
84 char errtxt[SC_MAXLEN], line[SC_MAXLEN], **str = NULL;
85 cpl_boolean fl_data = CPL_FALSE;
86 int npar0 = 0, i = 0, nparx = 0;
87
88 /* Set maximum number of parameters */
89 npar0 = SC_MAXPAR;
90
91 /* Valid number of parameters? */
92
93 if (npar0 < 1) {
94 sprintf(errtxt, "%s: npar < 1 (parameters at line)",
95 SC_ERROR_IIP_TXT);
96 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IIP, "%s", errtxt);
97 }
98
99 /* Fill mfpar structure with 0 */
100
101 for (i = 0; i < npar0; i++) {
102 par[i].c[0] = '\0';
103 par[i].i = 0;
104 par[i].d = 0.;
105 }
106
107 /* Skip comments and empty lines and check existence of data */
108
109 while (fgets(line, SC_MAXLEN, stream) != NULL) {
110 if (line[0] != '#' && strspn(line, "\n\t ") != strlen(line)) {
111 fl_data = CPL_TRUE;
112 break;
113 }
114 }
115
116 if (fl_data == CPL_FALSE) {
117 sprintf(errtxt, "%s: FILE *stream (no parameters)",
118 SC_ERROR_UFS_TXT);
119 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_UFS, "%s", errtxt);
120 }
121
122 /* Allocate memory to string array */
123
124 str = (char **) calloc(npar0+1, sizeof(char *));
125 if (str == NULL) {
126 sprintf(errtxt, "%s: char **str", SC_ERROR_ISM_TXT);
127 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_ISM, "%s", errtxt);
128 }
129
130 /* Read parameter values in strings and check number of values */
131
132 str[0] = strtok(line, "\n\t ");
133 if (npar0 > 1) {
134 for (i = 1; i < npar0; i++) {
135 str[i] = strtok(NULL, "\n\t ");
136 if (str[i] == NULL) {
137 nparx = i;
138 break;
139 }
140 }
141 }
142
143 if (nparx == npar0) {
144 str[npar0] = strtok(NULL, "\n\t ");
145 if (str[npar0] != NULL) {
146 free(str);
147 str = NULL;
148 sprintf(errtxt, "%s: FILE *stream (more parameters than "
149 "expected)", SC_ERROR_UFS_TXT);
150 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_UFS, "%s",
151 errtxt);
152 }
153 }
154
155 /* Convert strings in integer and double numbers */
156
157 for (i = 0; i < nparx; i++) {
158 strcpy(par[i].c, str[i]);
159 strtok(par[i].c, "\r");
160 par[i].i = strtol(str[i], NULL, 10);
161 if (sc_basic_isnumber(str[i]) == CPL_TRUE) {
162 par[i].d = strtod(str[i], NULL);
163 } else {
164 par[i].d = 0.;
165 }
166 }
167
168 /* Free memory space of string array */
169 free(str);
170 str = NULL;
171
172 /* Return number of read parameters */
173 *npar = nparx;
174
175 return CPL_ERROR_NONE;
176}
177
178
179double sc_basic_mjd2fracyear(double mjd)
180{
185 double refjd = 0., ncycle = 0., rest = 0.;
186 double frac = 0., nyears = 0., date = 0.;
187
188 refjd = mjd - 51544.;
189 ncycle = floor(refjd / 1461.);
190 rest = refjd - ncycle * 1461.;
191
192 if (rest < 366.) {
193 frac = rest / 366.;
194 nyears = 4 * ncycle;
195 } else {
196 frac = modf((rest - 366.) / 365., &nyears);
197 nyears += 4 * ncycle + 1;
198 }
199
200 date = 2000. + nyears + frac;
201
202 return date;
203}
204
205
206double sc_basic_fracyear2date(int *year, int *month, int *day,
207 int *hh, int *mm, double *ss,
208 const double *fracyear)
209{
237 int i = 0;
238 int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
239 int days_in_year = 365;
240
241 double rest = 0.,
242 frac_day = 0.,
243 acc = 1e-10; /* corresponds to an accuracy of 0.01s */
244
245 /* calculate the year */
246 *year = floor(*fracyear);
247
248 /* calculate remaining fractional year */
249 rest = *fracyear - *year;
250
251 /* round to desired accuracy */
252 rest = floor(rest/acc + 1) * acc;
253
254 if (*year % 4 == 0 && *year % 100 != 0) {
255 /* leap year (February has 29 days) */
256 days_in_month[1]++;
257 days_in_year++;
258 }
259
260 /* calculate remaining fractional days */
261 rest *= days_in_year;
262
263 /* count months and subtract days from total */
264 for (i = 0; i < 12 && (rest-days_in_month[i]) >= 0; i++) {
265 rest -= days_in_month[i];
266 }
267
268 /* set month */
269 *month = i+1;
270
271 /* calculate days */
272 *day = floor(rest) + 1;
273
274 /* calculate remaining fractional day */
275 rest -= *day - 1;
276 frac_day = rest;
277
278 /* if requested calculate time hh:mm:ss */
279 if (hh != NULL) {
280 rest *= 24;
281 *hh = floor(rest);
282 rest -= *hh;
283
284 rest *= 60;
285 *mm = floor(rest);
286 rest -= *mm;
287
288 rest *= 60;
289 *ss = rest;
290 }
291
292 return frac_day;
293}
294
295
296cpl_error_code sc_basic_rebin(cpl_table *outspec, const char *outlam,
297 const char *outflux, const cpl_table *inspec,
298 const char *inlam, const char *influx)
299{
322 int n_in = 0, n_out = 0, i = 0, jo = -1, j = 0;
323 const double *inlamv = NULL, *influxv = NULL;
324 double *outlamv = NULL, *outfluxv = NULL;
325 double olmin = 0., olmax = 0., dol = 0., ilmin = 0., ilmax = 0., dil = 0.;
326 double rdl = 0.;
327
328 /* Get number of data points */
329 n_in = cpl_table_get_nrow(inspec);
330 n_out = cpl_table_get_nrow(outspec);
331
332 /* Create flux column in output CPL table if it is not present */
333 if (cpl_table_has_column(outspec, outflux) == 0) {
334 cpl_table_new_column(outspec, outflux, CPL_TYPE_DOUBLE);
335 }
336
337 /* Fill flux column of output spectrum with 0. */
338 cpl_table_fill_column_window(outspec, outflux, 0, n_out, 0.);
339
340 /* No data points -> no rebinning */
341 if (n_in <= 0 || n_out <= 0) {
342 return CPL_ERROR_NONE;
343 }
344
345 /* Get pointers to CPL table columns */
346 inlamv = cpl_table_get_data_double_const(inspec, inlam);
347 influxv = cpl_table_get_data_double_const(inspec, influx);
348 outlamv = cpl_table_get_data_double(outspec, outlam);
349 outfluxv = cpl_table_get_data_double(outspec, outflux);
350
351 /* One input data point only */
352 if (n_in == 1) {
353 cpl_table_fill_column_window(outspec, outflux, 0, n_out, influxv[0]);
354 return CPL_ERROR_NONE;
355 }
356
357 for (i = 0; i < n_out; i++) {
358
359 /* Limits of wavelength bin in output spectrum */
360
361 if (n_out == 1) {
362
363 /* Full range of input spectrum for one output data point */
364 olmin = 1.5 * inlamv[0] - 0.5 * inlamv[1];
365 olmax = 1.5 * inlamv[n_in-1] - 0.5 * inlamv[n_in-2];
366
367 } else {
368
369 if (i == 0) {
370 olmin = 1.5 * outlamv[i] - 0.5 * outlamv[i+1];
371 } else {
372 olmin = olmax;
373 }
374
375 if (i == n_out - 1) {
376 olmax = 1.5 * outlamv[i] - 0.5 * outlamv[i-1];
377 } else {
378 olmax = 0.5 * (outlamv[i] + outlamv[i+1]);
379 }
380
381 }
382
383 dol = olmax - olmin;
384
385 do {
386
387 /* Limits of wavelength bin in input spectrum */
388
389 if (j != jo) {
390
391 if (j == 0) {
392 ilmin = 1.5 * inlamv[j] - 0.5 * inlamv[j+1];
393 } else {
394 ilmin = ilmax;
395 }
396
397 if (j == n_in - 1) {
398 ilmax = 1.5 * inlamv[j] - 0.5 * inlamv[j-1];
399 } else {
400 ilmax = 0.5 * (inlamv[j] + inlamv[j+1]);
401 }
402
403 }
404
405 /* Effective range of flux value -> weight */
406
407 if (ilmin < olmin && ilmax <= olmax) {
408 dil = ilmax - olmin;
409 } else if (ilmin >= olmin && ilmax > olmax) {
410 dil = olmax - ilmin;
411 } else if (ilmin < olmin && ilmax > olmax) {
412 dil = olmax - olmin;
413 } else {
414 dil = ilmax - ilmin;
415 }
416
417 if (dil < 0.) {
418 dil = 0.;
419 }
420
421 /* Average flux of input spectrum in output bin */
422
423 if (dil > 0) {
424 rdl = dil / dol;
425 outfluxv[i] += influxv[j] * rdl;
426 }
427
428 j++;
429
430 } while (ilmax <= olmax && j < n_in);
431
432 j--;
433 jo = j;
434
435 }
436
437 return CPL_ERROR_NONE;
438}
439
440
441cpl_error_code sc_basic_convolve(cpl_table *spec, const char *colname,
442 const cpl_array *kernel)
443{
463 cpl_table *tempspec;
464 char errtxt[SC_MAXLEN];
465 int n = 0, nkpix = 0, k = 0, kmin = 0, kmax = 0, i = 0, j = 0;
466 const double *kern = NULL;
467 double *flux = NULL, *tflux = NULL;
468 double sum = 0., out = 0.;
469
470 /* No data points -> no convolution */
471
472 n = cpl_table_get_nrow(spec);
473 if (n <= 0) {
474 return CPL_ERROR_NONE;
475 }
476
477 /* No kernel data -> no convolution */
478
479 nkpix = cpl_array_get_size(kernel);
480 if (nkpix == 0) {
481 return CPL_ERROR_NONE;
482 }
483
484 /* Get pointer to CPL array */
485
486 kern = cpl_array_get_data_double_const(kernel);
487
488 /* Check kernel */
489
490 for (k = 0; k < nkpix; k++) {
491 if (kern[k] < 0 || kern[k] > 1) {
492 sprintf(errtxt, "%s: cpl_array *kernel "
493 "(kernel element(s) < 0 or > 1)", SC_ERROR_IOV_TXT);
494 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s",
495 errtxt);
496 }
497 sum += kern[k];
498 }
499
500 if (sum < 1 - SC_TOL || sum > 1 + SC_TOL) {
501 sprintf(errtxt, "%s: cpl_array *kernel (sum of kernel elements != 1)",
502 SC_ERROR_IOV_TXT);
503 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s", errtxt);
504 }
505
506 /* Skip convolution if number of kernel pixels is one */
507
508 if (nkpix == 1) {
509 return CPL_ERROR_NONE;
510 }
511
512 /* Create temporary spectrum and set flux to 0 in initial spectrum */
513
514 tempspec = cpl_table_duplicate(spec);
515 cpl_table_fill_column_window(spec, colname, 0, n, 0.);
516
517 /* Get pointers to CPL table columns */
518
519 flux = cpl_table_get_data_double(spec, colname);
520 tflux = cpl_table_get_data_double(tempspec, colname);
521
522 /* Kernel with even or odd pixel number?
523 Note: centre of kernel at -0.5 pixels for even pixel number */
524
525 if (nkpix % 2 == 0) {
526 kmin = - nkpix / 2;
527 } else {
528 kmin = - (nkpix - 1) / 2;
529 }
530 kmax = kmin + nkpix - 1;
531
532 /* Convolve spectrum with kernel */
533
534 for (i = 0; i < n; i++) {
535
536 for (out = 0., k = kmin; k <= kmax; k++) {
537
538 /* Central pixel of kernel */
539 j = i - k;
540
541 /* Flux of first or last valid pixel for invalid pixels */
542 if (j < 0) {
543 j = 0;
544 } else if (j >= n) {
545 j = n - 1;
546 }
547
548 out += tflux[j] * kern[k - kmin];
549
550 }
551
552 flux[i] += out;
553
554 }
555
556 /* Delete temporary spectrum */
557
558 cpl_table_delete(tempspec);
559
560 return CPL_ERROR_NONE;
561}
562
563
564cpl_error_code sc_basic_convolvewindow(cpl_array *convflux,
565 const cpl_array *flux,
566 const int range[2],
567 const cpl_array *kernel)
568{
595 char errtxt[SC_MAXLEN];
596 int n = 0, i = 0, nkpix = 0, k = 0, kmin = 0, kmax = 0, jmin = 0;
597 int jmax = 0, j = 0;
598 const double *influx = NULL, *kern = NULL;
599 double *outflux = NULL;
600 double sum = 0., in0 = 0., innm1 = 0., in = 0.;
601
602 /* No data points -> no convolution */
603
604 n = cpl_array_get_size(flux);
605 if (n <= 0) {
606 return CPL_ERROR_NONE;
607 }
608
609 /* Check correspondence of data points */
610
611 if (cpl_array_get_size(convflux) != n) {
612 sprintf(errtxt, "%s: cpl_array *convflux != cpl_array *flux (size)",
613 SC_ERROR_IOS_TXT);
614 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOS, "%s", errtxt);
615 }
616
617 /* Check range values */
618
619 if (range[0] > range[1]) {
620 sprintf(errtxt, "%s: range[2] (min. > max.)", SC_ERROR_IIP_TXT);
621 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IIP, "%s", errtxt);
622 }
623 if (range[0] < 0 || range[1] >= n) {
624 sprintf(errtxt, "%s: range[2] (invalid pixel)", SC_ERROR_IIP_TXT);
625 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IIP, "%s", errtxt);
626 }
627
628 /* Initialise output array if not done so far */
629
630 if (cpl_array_has_invalid(convflux) == 1) {
631 cpl_array_fill_window_double(convflux, 0, n, 0.);
632 }
633
634 /* Get pointers to CPL arrays */
635
636 influx = cpl_array_get_data_double_const(flux);
637 outflux = cpl_array_get_data_double(convflux);
638
639 /* No kernel data -> no convolution */
640
641 nkpix = cpl_array_get_size(kernel);
642 if (nkpix == 0) {
643 for (i = range[0]; i <= range[1]; i++) {
644 outflux[i] += influx[i];
645 }
646 return CPL_ERROR_NONE;
647 }
648
649 /* Get pointer to CPL array */
650
651 kern = cpl_array_get_data_double_const(kernel);
652
653 /* Check kernel */
654
655 for (k = 0; k < nkpix; k++) {
656 if (kern[k] < 0 || kern[k] > 1) {
657 for (i = range[0]; i <= range[1]; i++) {
658 outflux[i] += influx[i];
659 }
660 sprintf(errtxt, "%s: cpl_array *kernel "
661 "(kernel element(s) < 0 or > 1)", SC_ERROR_IOV_TXT);
662 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s",
663 errtxt);
664 }
665 sum += kern[k];
666 }
667
668 if (sum < 1 - SC_TOL || sum > 1 + SC_TOL) {
669 for (i = range[0]; i <= range[1]; i++) {
670 outflux[i] += influx[i];
671 }
672 sprintf(errtxt, "%s: cpl_array *kernel (sum of kernel elements != 1)",
673 SC_ERROR_IOV_TXT);
674 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s", errtxt);
675 }
676
677 /* Skip convolution if number of kernel pixels is one */
678
679 if (nkpix == 1) {
680 for (i = range[0]; i <= range[1]; i++) {
681 outflux[i] += influx[i];
682 }
683 return CPL_ERROR_NONE;
684 }
685
686 /* Kernel with even or odd pixel number?
687 Note: centre of kernel at -0.5 pixels for even pixel number */
688
689 if (nkpix % 2 == 0) {
690 kmin = - nkpix / 2;
691 } else {
692 kmin = - (nkpix - 1) / 2;
693 }
694 kmax = kmin + nkpix - 1;
695
696 /* Set pixel range (add virtual pixels for marginal ranges) */
697
698 if (range[0] == 0) {
699 jmin = -kmax;
700 } else {
701 jmin = range[0];
702 }
703 if (range[1] == n-1) {
704 jmax = n-1 - kmin;
705 } else {
706 jmax = range[1];
707 }
708
709 /* Set flux of virtual input pixels */
710
711 in0 = influx[0];
712 innm1 = influx[n-1];
713
714 /* Convolve array with kernel */
715
716 for (j = jmin; j <= jmax; j++) {
717
718 /* Flux of real and virtual input pixels */
719
720 if (j < 0) {
721 in = in0;
722 } else if (j >= n) {
723 in = innm1;
724 } else {
725 in = influx[j];
726 }
727
728 /* Calculate output flux for each kernel element and add it to the
729 corresponding output pixel */
730
731 for (k = SC_MAX(kmin, -j); k <= SC_MIN(kmax, n-1 - j); k++) {
732
733 i = j + k;
734
735 outflux[i] += in * kern[k - kmin];
736
737 }
738
739 }
740
741 return CPL_ERROR_NONE;
742}
743
744
745cpl_error_code sc_basic_filtermedian(cpl_table *spec, const char *colname,
746 const int npix)
747{
764 cpl_array *medpix;
765 cpl_table *tempspec;
766 int n = 0, urad = 0, j = 0, i = 0;
767 double *flux = NULL, *tflux = NULL, *mflux = NULL;
768
769 /* No data points -> no filtering */
770 n = cpl_table_get_nrow(spec);
771 if (n <= 0) {
772 return CPL_ERROR_NONE;
773 }
774
775 /* No pixels for median -> no filtering */
776 if (npix <= 0) {
777 return CPL_ERROR_NONE;
778 }
779
780 /* Create temporary spectrum and set flux to 0 in initial spectrum */
781 tempspec = cpl_table_duplicate(spec);
782 cpl_table_fill_column_window(spec, colname, 0, n, 0.);
783
784 /* Get pointers to CPL table columns */
785 flux = cpl_table_get_data_double(spec, colname);
786 tflux = cpl_table_get_data_double(tempspec, colname);
787
788 /* Create temporary array for median calculation and initialise it with
789 flux of first pixel */
790 medpix = cpl_array_new(npix, CPL_TYPE_DOUBLE);
791 cpl_array_fill_window(medpix, 0, n, tflux[0]);
792
793 /* Get pointer to CPL array */
794 mflux = cpl_array_get_data_double(medpix);
795
796 /* Get upper radius of pixel range */
797 urad = (int) floor(0.5 * npix);
798
799 /* Median filtering */
800
801 for (j = 0, i = -urad; i < n; i++) {
802
803 /* New pixel in array for median flux */
804 if (i+urad >= n) {
805 mflux[j] = tflux[n-1];
806 } else {
807 mflux[j] = tflux[i+urad];
808 }
809
810 /* Calculate median */
811 if (i >= 0) {
812 flux[i] = cpl_array_get_median(medpix);
813 }
814
815 /* New position in array for median flux to be filled */
816 j++;
817 if (j == npix) {
818 j = 0;
819 }
820
821 }
822
823 /* Delete temporary spectrum */
824 cpl_table_delete(tempspec);
825 cpl_array_delete(medpix);
826
827 return CPL_ERROR_NONE;
828}
829
830
831cpl_error_code sc_basic_linecount(long *n_lines, FILE *fp)
832{
849 char ch='\0';
850
851 *n_lines = 0;
852
853 if (fseek(fp, 0, 0) != 0) {
854 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_FILE_NOT_FOUND,
855 "Problem with file pointer");
856 } else {
857 while (ch != EOF) {
858 ch = fgetc(fp);
859 if (ch == '\n'){
860 (*n_lines)++;
861 }
862 }
863 fseek(fp, 0, 0);
864
865 return CPL_ERROR_NONE;
866 }
867}
868
869
870void sc_basic_rhum2ppmv(double *ppmv, const double *tem, const double *p,
871 const double *hum)
872{
895 double p_sat, /* water vapour pressure */
896 p_h2o; /* partial pressure of water in [hPa] */
897
898 double t, logt, log_ew, log_ei, log_e, log_dbl_max = log(DBL_MAX);
899
900 /* ensure that temperature is not absolute zero */
901 if (*tem <= 0.) {
902 t = DBL_MIN * 2;
903 cpl_msg_warning(cpl_func, "Temperatures must be larger than 0K");
904 } else {
905 t = *tem;
906 }
907
908 logt = log(t);
909
910 /* vapour pressure over water */
911 log_ew = 54.842763 - 6763.22 / t - 4.210 * logt + 0.000367 * t +
912 tanh(0.0415 * (t - 218.8)) * (53.878 - 1331.22 / t - 9.44523 *
913 logt + 0.014025 * t);
914
915 /* vapour pressure over hexagonal ice */
916 log_ei = 9.550426 - 5723.265 / t + 3.53068 * logt - 0.00728332 * t;
917
918 /* vapour pressure */
919 log_e = SC_MIN(log_ew, log_ei);
920
921 /* avoid overflow */
922 if (log_e < log_dbl_max) {
923 p_sat = exp(log_e) / 100.;
924 } else {
925 p_sat = DBL_MAX / 100.;
926 cpl_msg_warning(cpl_func, "Temperature value results in overflow");
927 }
928
929 p_h2o = SC_MIN(*hum, 100) / 100. * p_sat;
930
931 *ppmv = SC_MAX(p_h2o / *p * 1e6, 0);
932}
933
934
935cpl_error_code sc_basic_rhum2ppmv_old(const cpl_array *temp,
936 const cpl_array *pres,
937 const cpl_array *rhum,
938 cpl_array *ppmv)
939{
962 cpl_error_code err_code;
963
964 cpl_array *ewater,
965 *eice,
966 *e,
967 *tc, /* temperature in Deg C */
968 *a;
969
970// double m_h2o = 18.01534, /* g mol-1 molar mass of water */
971// m_dry = 28.9644, /* g mol-1 molar mass of dry air */
972 double aw[] = { 6.11583699e+00, 4.44606896e-01, 1.43177157e-02,
973 2.64224321e-04, 2.99291081e-06, 2.03154182e-08,
974 7.02620698e-11, 3.79534310e-14,-3.21582393e-16 },
975 ai[] = { 6.09868993e+00, 4.99320233e-01, 1.84672631e-02,
976 4.02737184e-04, 5.65392987e-06, 5.21693933e-08,
977 3.07839583e-10, 1.05785160e-12, 1.61444444e-15 },
978 val, p;
979
980 long i, j;
981
982 int sz = cpl_array_get_size(temp);
983
984 ewater = cpl_array_new(sz, CPL_TYPE_DOUBLE);
985 eice = cpl_array_new(sz, CPL_TYPE_DOUBLE);
986 e = cpl_array_new(sz, CPL_TYPE_DOUBLE);
987 tc = cpl_array_new(sz, CPL_TYPE_DOUBLE);
988
989 a = cpl_array_new(9, CPL_TYPE_DOUBLE); /* size of aw[], ai[] */
990
991 for (i = 0; i < sz; i++) {
992 cpl_array_set_double(tc, i,
993 cpl_array_get_double(temp, i, NULL) - 273.15);
994 cpl_array_set_double(ewater, i, 0);
995 cpl_array_set_double(eice, i, 0);
996 cpl_array_set_double(e, i, 0);
997 }
998
999 for (i = 0; i < 9; i++) {
1000 cpl_array_set_double(a, i, aw[i]);
1001 }
1002
1003 for (i = 8; i >= 0; i--) {
1004 for (j = 0; j < sz; j++) {
1005 val = cpl_array_get_double(a, i, NULL) +
1006 cpl_array_get_double(ewater, j, NULL) *
1007 cpl_array_get_double(tc, j, NULL);
1008 cpl_array_set_double(ewater, j, val);
1009 }
1010 }
1011
1012 for (i = 0; i < 9; i++) {
1013 cpl_array_set_double(a, i, ai[i]);
1014 }
1015
1016 for (i = 8; i >= 0; i--) {
1017 for (j = 0; j < sz; j++) {
1018 val = cpl_array_get_double(a, i, NULL) +
1019 cpl_array_get_double(eice, j, NULL) *
1020 cpl_array_get_double(tc, j, NULL);
1021 cpl_array_set_double(eice, j, val);
1022 }
1023 }
1024
1025 for (i = 0; i < sz; i++) {
1026 val = SC_MIN(cpl_array_get_double(ewater, i, NULL),
1027 cpl_array_get_double(eice, i, NULL));
1028 cpl_array_set_double(e, i, val);
1029 }
1030
1031 err_code = CPL_ERROR_NONE;
1032 for (i = 0; i < sz; i++) {
1033 p = cpl_array_get_double(pres, i, NULL);
1034 if (p == 0) {
1035 p = 1e-30;
1036 cpl_msg_warning(cpl_func, "sc_rhum2ppmv() encountered a problem:"
1037 " Division by zero");
1038 err_code = CPL_ERROR_DIVISION_BY_ZERO;
1039 }
1040 val = cpl_array_get_double(rhum, i, NULL) / 100. *
1041 cpl_array_get_double(e, i, NULL) / p * 1e6;
1042 if (val < 0) {
1043 val = 0.;
1044 }
1045 cpl_array_set_double(ppmv, i, val);
1046 }
1047
1048 cpl_array_delete(ewater);
1049 cpl_array_delete(eice);
1050 cpl_array_delete(e);
1051 cpl_array_delete(tc);
1052 cpl_array_delete(a);
1053
1054 return err_code;
1055}
1056
1057
1058cpl_error_code sc_basic_planck(cpl_array *bb, const cpl_array *wavelength,
1059 const double temp)
1060{
1075 long sz, i;
1076
1077 double c1 = 3.7417749e-5, /* = 2 * !DPI * h * c * c in cgs units */
1078 c2 = 1.4387687, /* = h * c / k in cgs units */
1079 log_dbl_max = log(DBL_MAX);
1080
1081 double wave, val;
1082
1083 /* ensure same size of wavelength and bb arrays */
1084 if ((sz = cpl_array_get_size(wavelength)) != cpl_array_get_size(bb)) {
1085 cpl_array_set_size(bb, sz);
1086 }
1087
1088 for (i = 0; i < sz; i++) {
1089 /* avoid division by zero */
1090 if ((wave = cpl_array_get_double(wavelength, i, NULL)) == 0) {
1091 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_DIVISION_BY_ZERO,
1092 "Zero wavelength value");
1093 }
1094 wave /= 1e4;
1095 val = c2 / wave / temp;
1096 /* avoid overflow */
1097 if (val < log_dbl_max) {
1098 cpl_array_set_double(bb, i, c1 / (pow(wave, 5) * (expm1(val)))
1099 * 1e-8);
1100 } else {
1101 cpl_array_set_double(bb, i, 0);
1102 }
1103 }
1104
1105 return CPL_ERROR_NONE;
1106}
1107
1108
1109void sc_basic_dirslash(char *dir)
1110{
1126 if ((unsigned) (strrchr(dir, '/')-dir) != (unsigned) strlen(dir)-1) {
1127 strcat(dir, "/"); // omit compiler warning -Wstringop-overflow
1128// strncat(dir, "/", 1);
1129 }
1130}
1131
1132
1133void sc_basic_abspath(char *out, const char *dir, const char *cwd)
1134{
1154 char *ptr, *p_out, tmp_dir[SC_MAXLEN] = "";
1155
1156 // ensure out is empty
1158
1159 // copy input for using strtok
1160 strcpy(tmp_dir, dir);
1161
1162 if (strncmp(tmp_dir, "/", 1) == 0) {
1163 // if dir is absolute path, out has to be absolute too
1164 strcat(out, "/");
1165 } else {
1166 // if dir is relative path, copy current working directory to out
1167 strcat(out, cwd);
1168 sc_basic_dirslash(out);
1169 }
1170
1171 // cut up tmp_dir using strtok
1172 ptr = strtok(tmp_dir, "/");
1173 while (ptr != NULL) {
1174 if (strcmp(ptr, "..") == 0) {
1175 // if ".." move up one level
1176 if ((p_out = strrchr(out, '/')) != NULL) { // remove trailing "/"
1177 sprintf(p_out, "%c", '\0');
1178 if ((p_out = strrchr(out, '/')) != NULL) { // now move up
1179 sprintf(p_out, "%c", '\0');
1180 }
1181 sc_basic_dirslash(out);
1182 }
1183 } else {
1184 // if "." do nothing
1185 if (strcmp(ptr, ".") != 0) {
1186 // else copy current level to out
1187 strcat(out, ptr);
1188 strcat(out, "/");
1189 }
1190 }
1191 // get next level
1192 ptr = strtok(NULL, "/");
1193 }
1194
1195 sc_basic_dirslash(out);
1196}
1197
1198
1199cpl_error_code sc_basic_access(const char *pathname, const int mode)
1200{
1234 int err;
1235
1236 errno = 0;
1237
1238 err = access(pathname, mode);
1239
1240 switch (errno) {
1241 case EROFS:
1242 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_ROFS,
1243 "%s: %s", SC_ERROR_ROFS_TXT, pathname);
1244 break;
1245 case EINVAL:
1246 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_INVAL,
1247 "%s: %s", SC_ERROR_INVAL_TXT, pathname);
1248 break;
1249 case ETXTBSY:
1250 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_TXTBSY,
1251 "%s: %s", SC_ERROR_TXTBSY_TXT, pathname);
1252 break;
1253 case EACCES:
1254 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_ACCES,
1255 "%s: %s", SC_ERROR_ACCES_TXT, pathname);
1256 break;
1257 case ELOOP:
1258 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_LOOP,
1259 "%s: %s", SC_ERROR_LOOP_TXT, pathname);
1260 break;
1261 case ENAMETOOLONG:
1262 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_NAMETOOLONG,
1263 "%s: %s", SC_ERROR_NAMETOOLONG_TXT,
1264 pathname);
1265 break;
1266 case ENOENT:
1267 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_NOENT,
1268 "%s: %s", SC_ERROR_NOENT_TXT, pathname);
1269 break;
1270 case ENOTDIR:
1271 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_NOTDIR,
1272 "%s: %s", SC_ERROR_NOTDIR_TXT, pathname);
1273 break;
1274 case EFAULT:
1275 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_FAULT,
1276 "%s: %s", SC_ERROR_FAULT_TXT, pathname);
1277 break;
1278 case EIO:
1279 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IO,
1280 "%s: %s", SC_ERROR_IO_TXT, pathname);
1281 break;
1282 case ENOMEM:
1283 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_NOMEM,
1284 "%s: %s", SC_ERROR_NOMEM_TXT, pathname);
1285 break;
1286 }
1287
1288 if (err != 0) {
1289 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_UNDEF,
1290 "%s: %s", SC_ERROR_UNDEF_TXT, pathname);
1291 }
1292
1293 return CPL_ERROR_NONE;
1294}
1295
1296
1297cpl_error_code sc_basic_greg2jd(long *jd, const int year, const int month,
1298 const int day)
1299{
1318 long jd1, jd2, jd3;
1319
1320 if ((year < 1) || (month < 1) || (month > 12) || (day < 1) || (day > 31)) {
1321 return (cpl_error_code)SC_ERROR_BADUSERINPUT;
1322 }
1323
1324 jd1 = day-32075+1461*(year+4800+(month-14)/12)/4;
1325 jd2 = 367*(month-2-(month-14)/12*12)/12;
1326 jd3 = 3*((year+4900+(month-14)/12)/100)/4;
1327
1328 *jd = jd1+jd2-jd3;
1329
1330 return CPL_ERROR_NONE;
1331}
1332
1333
1334cpl_error_code sc_basic_jd2greg(int *year, int *month, int *day,
1335 const long jd)
1336{
1355 long l, n, j, y;
1356
1357 l = jd + 68569;
1358 n = 4*l/146097;
1359 l -= (146097*n + 3)/4;
1360 y = 4000*(l + 1)/1461001;
1361 l += -1461*y/4 + 31;
1362 j = 80*l/2447;
1363 *day = (int)(l - 2447*j/80);
1364 l = j/11;
1365 j += 2 - 12*l;
1366 *year = (int)(100*(n - 49) + y + l);
1367 *month = (int)j;
1368
1369 if ((*year < 1) || (*month < 1) || (*month > 12) || (*day < 1) || (*day > 31)) {
1370 return (cpl_error_code)SC_ERROR_BADUSERINPUT;
1371 }
1372
1373 return CPL_ERROR_NONE;
1374}
1375
1376
1377cpl_error_code sc_basic_absfile(char *absfilename, const char *filename)
1378{
1379 char cwd[SC_MAXLEN] = "", basedir[SC_MAXLEN] = "", *d = NULL;
1380
1381 if (filename[0] != '/') {
1382 /* get current working directory */
1383 if ((d = getcwd(cwd, sizeof(cwd))) == NULL) {
1384 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_GETCWD,
1385 "%s: %s", SC_ERROR_GETCWD_TXT, cwd);
1386 }
1387 sc_basic_dirslash(cwd);
1388 }
1389
1390 if ((d = strrchr(filename, '/')) != NULL) {
1391 // filename conatins path
1392 strncpy(basedir, filename, (d-filename));
1393 sc_basic_abspath(absfilename, basedir, cwd);
1394 strcat(absfilename, (d+1));
1395 } else {
1396 // filename does NOT contain path
1397 strcpy(absfilename, cwd);
1398 strcat(absfilename, filename);
1399 }
1400
1401 return CPL_ERROR_NONE;
1402}
1403
1404
1405cpl_boolean sc_basic_parameterlists_same(cpl_parameterlist *list1,
1406 cpl_parameterlist *list2)
1407{
1408 cpl_boolean bool = CPL_TRUE;
1409 cpl_type type;
1410 cpl_parameter *p1, *p2;
1411
1412 p1 = cpl_parameterlist_get_first(list1);
1413 p2 = cpl_parameterlist_get_first(list2);
1414 type = cpl_parameter_get_type(p1);
1415 switch (type) {
1416 case CPL_TYPE_INT:
1417 if (cpl_parameter_get_int(p1) != cpl_parameter_get_int(p2)) {
1418 bool = CPL_FALSE;
1419 }
1420 break;
1421 case CPL_TYPE_DOUBLE:
1422 if (cpl_parameter_get_double(p1) != cpl_parameter_get_double(p2)) {
1423 bool = CPL_FALSE;
1424 }
1425 break;
1426 case CPL_TYPE_STRING:
1427 if (cpl_parameter_get_string(p1) != cpl_parameter_get_string(p2)) {
1428 bool = CPL_FALSE;
1429 }
1430 break;
1431 default:
1432 break;
1433 }
1434
1435 if (bool == CPL_TRUE) {
1436 while ((p1 = cpl_parameterlist_get_next(list1)) != NULL &&
1437 (p2 = cpl_parameterlist_get_next(list2)) != NULL) {
1438 type = cpl_parameter_get_type(p1);
1439 switch (type) {
1440 case CPL_TYPE_INT:
1441 if (cpl_parameter_get_int(p1) !=
1442 cpl_parameter_get_int(p2)) {
1443 bool = CPL_FALSE;
1444 }
1445 break;
1446 case CPL_TYPE_DOUBLE:
1447 if (cpl_parameter_get_double(p1) !=
1448 cpl_parameter_get_double(p2)) {
1449 bool = CPL_FALSE;
1450 }
1451 break;
1452 case CPL_TYPE_STRING:
1453 if (cpl_parameter_get_string(p1) !=
1454 cpl_parameter_get_string(p2)) {
1455 bool = CPL_FALSE;
1456 }
1457 break;
1458 default:
1459 break;
1460 }
1461 if (bool == CPL_FALSE) {
1462 break;
1463 }
1464 }
1465 }
1466 return bool;
1467}
1468
1469cpl_error_code sc_basic_status2txt(char *msg, const int status)
1470{
1471 // check MPFIT status
1472 switch (status) {
1473 // success
1474 case MP_OK_CHI:
1475 sprintf(msg, "Convergence in chi-square value");
1476 break;
1477 case MP_OK_PAR:
1478 sprintf(msg, "Convergence in parameter value");
1479 break;
1480 case MP_OK_BOTH:
1481 sprintf(msg, "Both MP_OK_PAR and MP_OK_CHI hold");
1482 break;
1483 case MP_OK_DIR:
1484 sprintf(msg, "Convergence in orthogonality");
1485 break;
1486 case MP_MAXITER:
1487 sprintf(msg, "Maximum number of iterations reached");
1488 break;
1489 case MP_FTOL:
1490 sprintf(msg, "ftol is too small; no further improvement");
1491 break;
1492 case MP_XTOL:
1493 sprintf(msg, "xtol is too small; no further improvement");
1494 break;
1495
1496 case MP_GTOL:
1497 sprintf(msg, "gtol is too small; no further improvement");
1498 break;
1499 // failure
1500 case MP_ERR_INPUT:
1501 sprintf(msg, "General input parameter error");
1502 break;
1503 case MP_ERR_NAN:
1504 sprintf(msg, "User function produced non-finite values");
1505 break;
1506 case MP_ERR_FUNC:
1507 sprintf(msg, "No user function was supplied");
1508 break;
1509 case MP_ERR_NPOINTS:
1510 sprintf(msg, "No user data points were supplied");
1511 break;
1512 case MP_ERR_NFREE:
1513 sprintf(msg, "No free parameters");
1514 break;
1515 case MP_ERR_MEMORY:
1516 sprintf(msg, "Memory allocation error");
1517 break;
1518 case MP_ERR_INITBOUNDS:
1519 sprintf(msg, "Initial values inconsistent w constraints");
1520 break;
1521 case MP_ERR_BOUNDS:
1522 sprintf(msg, "Initial constraints inconsistent");
1523 break;
1524 case MP_ERR_PARAM:
1525 sprintf(msg, "General input parameter error");
1526 break;
1527 case MP_ERR_DOF:
1528 sprintf(msg, "Not enough degrees of freedom");
1529 break;
1530 default:
1531 sprintf(msg, "Exception: unknown exit value");
1532 return (cpl_error_code)SC_ERROR_INVAL;
1533 }
1534
1535 return CPL_ERROR_NONE;
1536}
1537
1538
1539cpl_error_code sc_basic_clipmean(double *mean, double *rms,
1540 cpl_array *arr, const cpl_boolean clip) {
1572 cpl_array *mad_arr; // median absolute difference
1573
1574 double val_p, val_m, val = 0., mean_old, eps = 1e-4;
1575
1576 int i, j, // loop variables
1577 n, // size of arr
1578 nclip = 0, nclip_old = 0; // total number of clipped elements
1579
1580 // get size of array
1581 n = cpl_array_get_size(arr);
1582
1583 // initialise array for median absolute difference
1584 mad_arr = cpl_array_new(n, CPL_TYPE_DOUBLE);
1585
1586 // compute first guess for mean and rms using median absolute difference
1587 *mean = cpl_array_get_median(arr);
1588 for (i = 0; i < n; i++) {
1589 // compute MAD
1590 cpl_array_set_double(mad_arr, i,
1591 fabs(cpl_array_get_double(arr, i, NULL) - *mean));
1592 if (cpl_array_is_valid(arr, i) == 0) {
1593 // remember invalid values from arr in mad_arr
1594 cpl_array_set_invalid(mad_arr, i);
1595 }
1596 }
1597 *rms = cpl_array_get_median(mad_arr) * 1.5;
1598
1599 // now use Huber's method to improve estimate
1600
1601 // reset mad_arr
1602 for (i = 0; i < n; i++) {
1603 cpl_array_set_double(mad_arr, i, cpl_array_get_double(arr, i, NULL));
1604 if (cpl_array_is_valid(arr, i) == 0) {
1605 // remember invalid values from arr in mad_arr
1606 cpl_array_set_invalid(mad_arr, i);
1607 }
1608 }
1609
1610 // do at max 100 iterations (should converge much faster)
1611 for (j = 0, mean_old = *mean, nclip = 0, nclip_old = 0; j < 100; j++) {
1612 // re-compute outliers
1613 val_p = *mean + (1.5 * *rms);
1614 val_m = *mean - (1.5 * *rms);
1615 for (i = 0, *mean = 0; i < n; i++) {
1616 if (cpl_array_is_valid(mad_arr, i) == 1) {
1617 val = cpl_array_get_double(mad_arr, i, NULL);
1618 if (val > val_p) {
1619 // set outliers invalid in original array
1620 cpl_array_set_invalid(arr, i);
1621 cpl_array_set_double(mad_arr, i, val_p);
1622 nclip++;
1623 } else if (val < val_m) {
1624 // set outliers invalid in original array
1625 cpl_array_set_invalid(arr, i);
1626 cpl_array_set_double(mad_arr, i, val_m);
1627 nclip++;
1628 }
1629 }
1630 }
1631 *mean = cpl_array_get_mean(mad_arr);
1632 *rms = cpl_array_get_stdev(mad_arr)*1.134;
1633
1634 if (fabs(mean_old / *mean - 1) < eps || nclip == nclip_old) {
1635 break;
1636 }
1637 mean_old = *mean;
1638 nclip_old = nclip;
1639 }
1640
1641 if (clip == CPL_TRUE) {
1642 *mean = cpl_array_get_mean(arr);
1643 *rms = cpl_array_get_stdev(arr);
1644 }
1645
1646 cpl_array_delete(mad_arr);
1647
1648 return CPL_ERROR_NONE;
1649}
1650
1651
1652cpl_error_code sc_basic_col2arr(cpl_array *arr, const cpl_table *tab,
1653 const char *colname)
1654{
1676 int nrow_tab = 0; /* # of rows in input table */
1677 int nrow_arr = 0; /* # of rows in input table */
1678 int loop = 0; /* Loop variable */
1679 char err_msg[SC_MAXLEN]; /* Error message string */
1680
1681 cpl_type tabcoltype; /* Type of input table column */
1682 cpl_type arrcoltype; /* Type of target array */
1683
1684/*--------------------------------------------------------------------------*/
1685
1686 /* Checking validity of input */
1687 nrow_tab = cpl_table_get_nrow(tab);
1688 nrow_arr = cpl_array_get_size(arr);
1689 tabcoltype = cpl_table_get_column_type(tab, colname);
1690 arrcoltype = cpl_array_get_type(arr);
1691
1692 /* Input table size check */
1693 if (nrow_tab == 0) {
1694 sprintf(err_msg, "CPL input table has size = 0!\n"
1695 "Cannot continue. Emergency stop.");
1696 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_ILLEGAL_INPUT,
1697 "%s", err_msg);
1698 }
1699
1700 /* Existence of source column ? */
1701 if (cpl_table_has_column(tab, colname) == 0) {
1702 sprintf(err_msg, "CPL input table does not contain a column '%s'!\n"
1703 "Cannot continue. Emergency stop.",colname);
1704 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_ILLEGAL_INPUT,
1705 "%s", err_msg);
1706 }
1707
1708 /* Size of target array >0 ? */
1709 if (nrow_arr > 0) {
1710 cpl_msg_warning(cpl_func,"Input CPL array size > 0, existing data "
1711 "will be overwritten!");
1712 }
1713
1714 /* CPL types match ? */
1715 if (tabcoltype != arrcoltype) {
1716 sprintf(err_msg, "CPL types of table column and array do not match!\n"
1717 "Cannot continue. Emergency stop.");
1718 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_ILLEGAL_INPUT,
1719 "%s", err_msg);
1720 }
1721
1722 /* Copying data */
1723 cpl_array_set_size(arr, nrow_tab);
1724
1725 for (loop = 0; loop < nrow_tab; loop++)
1726 {
1727 switch (tabcoltype) {
1728 case CPL_TYPE_INT:
1729 cpl_array_set_int(arr, loop,
1730 cpl_table_get_int(tab,colname,loop,NULL));
1731 break;
1732 case CPL_TYPE_FLOAT:
1733 cpl_array_set_float(arr, loop,
1734 cpl_table_get_float(tab,colname,loop,NULL));
1735 break;
1736 case CPL_TYPE_DOUBLE:
1737 cpl_array_set_double(arr, loop,
1738 cpl_table_get_double(tab,colname,loop,NULL));
1739 break;
1740 case CPL_TYPE_STRING:
1741 cpl_array_set_string(arr, loop,
1742 cpl_table_get_string(tab,colname,loop));
1743 break;
1744 default:
1745 sprintf(err_msg, "CPL type not supported!\n"
1746 "Cannot continue. Emergency stop.");
1747 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_ILLEGAL_INPUT,
1748 "%s", err_msg);
1749 break;
1750 }
1751 }
1752
1753 return cpl_error_get_code();
1754}
1755
1756
1757cpl_error_code sc_basic_arr2col(cpl_table *tab, const char *colname,
1758 const cpl_array *arr)
1759{
1787 int nrow_arr = 0; /* # of rows in input array */
1788 int nrow_tab = 0; /* # of rows in target table */
1789 int loop = 0; /* Loop variable */
1790 char err_msg[SC_MAXLEN]; /* Error message string */
1791
1792 cpl_type arrcoltype; /* Type of target array */
1793
1794/*--------------------------------------------------------------------------*/
1795
1796 /* Checking validity of input */
1797 arrcoltype = cpl_array_get_type(arr);
1798 nrow_arr = cpl_array_get_size(arr);
1799 nrow_tab = cpl_table_get_nrow(tab);
1800
1801 /* Empty array ? */
1802 if (nrow_arr == 0) {
1803 sprintf(err_msg, "CPL array size = 0\n"
1804 "Cannot continue. Emergency stop.");
1805 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_ILLEGAL_INPUT,
1806 "%s", err_msg);
1807 }
1808
1809 /* Sizes match? */
1810 if ((nrow_arr != nrow_tab) && (nrow_tab > 0)) {
1811 sprintf(err_msg, "CPL array and table size do not coincide!\n"
1812 "Cannot continue. Emergency stop.");
1813 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_ILLEGAL_INPUT,
1814 "%s", err_msg);
1815 }
1816
1817
1818 /* Checking / creating column */
1819 if (cpl_table_has_column(tab, colname) == 0) {
1820 arrcoltype = cpl_array_get_type(arr);
1821 cpl_table_new_column(tab, colname, arrcoltype);
1822 if (nrow_tab == 0) {
1823 cpl_table_set_size(tab,nrow_arr);
1824 }
1825 }
1826
1827 /* Copying info */
1828 for (loop = 0; loop<nrow_arr; loop++) {
1829 switch (arrcoltype) {
1830 case CPL_TYPE_INT:
1831 cpl_table_set_int(tab, colname, loop,
1832 cpl_array_get_int(arr, loop, NULL));
1833 break;
1834 case CPL_TYPE_FLOAT:
1835 cpl_table_set_float(tab, colname, loop,
1836 cpl_array_get_float(arr, loop, NULL));
1837 break;
1838 case CPL_TYPE_DOUBLE:
1839 cpl_table_set_double(tab, colname, loop,
1840 cpl_array_get_double(arr, loop, NULL));
1841 break;
1842 case CPL_TYPE_STRING:
1843 cpl_table_set_string(tab, colname, loop,
1844 cpl_array_get_string(arr, loop));
1845 break;
1846 default:
1847 sprintf(err_msg, "CPL type not supported!\n"
1848 "Cannot continue. Emergency stop.");
1849 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_ILLEGAL_INPUT,
1850 "%s", err_msg);
1851 break;
1852 }
1853 }
1854
1855 return cpl_error_get_code();
1856}
1857
1858
1859int sc_basic_sortarr_double(const void *p1, const void *p2)
1860{
1861 if (*(double *)p1 > *(double *)p2) {
1862 return 1;
1863 } else if (*(double *)p1 < *(double *)p2) {
1864 return -1;
1865 } else {
1866 return 0;
1867 }
1868}
1869
1870
1871cpl_error_code sc_basic_sortarr(cpl_array *arr, cpl_type type)
1872{
1896 void *p = NULL;
1897
1898 if (cpl_array_get_size(arr) == 0) {
1899 return CPL_ERROR_DATA_NOT_FOUND;
1900 }
1901
1902 switch (type) {
1903 // Double array
1904 case CPL_TYPE_DOUBLE:
1905 // get pointer to data
1906 p = cpl_array_get_data_double(arr);
1907
1908 // sort data
1909 qsort(p, cpl_array_get_size(arr),
1910 cpl_type_get_sizeof(CPL_TYPE_DOUBLE),
1911 sc_basic_sortarr_double);
1912
1913 return CPL_ERROR_NONE;
1914 break;
1915 default:
1916 // type not supported
1917 return CPL_ERROR_INVALID_TYPE;
1918 break;
1919 }
1920}
1921
1922
1923cpl_error_code sc_basic_copytable_content(cpl_table *outtab,
1924 const cpl_table *intab)
1925{
1941 cpl_type type;
1942 cpl_array *colnames;
1943 char errtxt[SC_MAXLEN];
1944 char* colname = NULL;
1945 const char **sp;
1946 int ncol = 0, i = 0;
1947 const int *ip;
1948 const float *fp;
1949 const double *dp;
1950
1951 if (cpl_table_compare_structure(outtab, intab) != 0) {
1952 sprintf(errtxt, "%s: structure of cpl_table *outtab != *intab",
1953 SC_ERROR_IOS_TXT);
1954 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s", errtxt);
1955 }
1956
1957 /* Get column labels */
1958 colnames = cpl_table_get_column_names(intab);
1959 ncol = cpl_array_get_size(colnames);
1960
1961 /* Copy content of columns */
1962
1963 for (i = 0; i < ncol; i++) {
1964
1965 colname = cpl_sprintf("%s", cpl_array_get_string(colnames, i));
1966 type = cpl_table_get_column_type(intab, colname);
1967
1968 if (type == CPL_TYPE_STRING) {
1969 sp = cpl_table_get_data_string_const(intab, colname);
1970 cpl_table_copy_data_string(outtab, colname, sp);
1971 } else if (type == CPL_TYPE_INT) {
1972 ip = cpl_table_get_data_int_const(intab, colname);
1973 cpl_table_copy_data_int(outtab, colname, ip);
1974 } else if (type == CPL_TYPE_FLOAT) {
1975 fp = cpl_table_get_data_float_const(intab, colname);
1976 cpl_table_copy_data_float(outtab, colname, fp);
1977 } else if (type == CPL_TYPE_DOUBLE) {
1978 dp = cpl_table_get_data_double_const(intab, colname);
1979 cpl_table_copy_data_double(outtab, colname, dp);
1980 }
1981 cpl_free(colname);
1982 }
1983
1984 /* Free memory */
1985 cpl_array_delete(colnames);
1986
1987 return CPL_ERROR_NONE;
1988}
1989
1990
1991cpl_error_code sc_basic_copytable_full(cpl_table *outtab,
1992 const cpl_table *intab)
1993{
2010 cpl_type type;
2011 cpl_array *colnames;
2012 char* colname = NULL;
2013 const char **sp;
2014 int nrow = 0, ncol = 0, i = 0;
2015 const int *ip;
2016 const float *fp;
2017 const double *dp;
2018
2019 /* Set size of output table */
2020 nrow = cpl_table_get_nrow(intab);
2021 cpl_table_set_size(outtab, nrow);
2022
2023 /* Get column labels */
2024 colnames = cpl_table_get_column_names(intab);
2025 ncol = cpl_array_get_size(colnames);
2026
2027 /* Copy content of columns and create columns if necessary */
2028
2029 for (i = 0; i < ncol; i++) {
2030
2031 colname = cpl_sprintf("%s", cpl_array_get_string(colnames, i));
2032 type = cpl_table_get_column_type(intab, colname);
2033 if (cpl_table_has_column(outtab, colname) != 1) {
2034 cpl_table_new_column(outtab, colname, type);
2035 }
2036
2037 if (type == CPL_TYPE_STRING) {
2038 sp = cpl_table_get_data_string_const(intab, colname);
2039 cpl_table_copy_data_string(outtab, colname, sp);
2040 } else if (type == CPL_TYPE_INT) {
2041 ip = cpl_table_get_data_int_const(intab, colname);
2042 cpl_table_copy_data_int(outtab, colname, ip);
2043 } else if (type == CPL_TYPE_FLOAT) {
2044 fp = cpl_table_get_data_float_const(intab, colname);
2045 cpl_table_copy_data_float(outtab, colname, fp);
2046 } else if (type == CPL_TYPE_DOUBLE) {
2047 dp = cpl_table_get_data_double_const(intab, colname);
2048 cpl_table_copy_data_double(outtab, colname, dp);
2049 }
2050 cpl_free(colname);
2051 }
2052
2053 /* Free memory */
2054 cpl_array_delete(colnames);
2055
2056 return CPL_ERROR_NONE;
2057}
2058
2059
2060void sc_basic_initstring(char *str, const long n)
2061{
2078 long i;
2079
2080 for (i = 0; i < n; i++) {
2081 str[i] = '\0';
2082 }
2083}
2084
2085
2087{
2105 char *p; /* character pointer */
2106
2107 p = str + strlen(str); /* set at nominal '\0' of input string */
2108
2109 if (*p != '\0') { /* if not terminated properly */
2110 *p = '\0'; /* place string termination character */
2111 }
2112}
2113
2114
2115char *sc_basic_strtrim(char *str)
2116{
2131 if (str != NULL && *str != 0) {
2132 int i = 0, /* counter for start position of string */
2133 j = 0, /* counter for end position of string */
2134 len = strlen(str); /* length of input string */
2135
2136 char *p, *q, /* pointers for looping through the input string */
2137 *out = (char *)malloc(len + 1); /* new output string */
2138
2139 /* set pointers to beginning of input string */
2140 q = str;
2141 p = out;
2142
2143 /* skip over leading spaces */
2144 while (isspace(*q)) {
2145 i++;
2146 q++;
2147 }
2148 /* i now has start position of string */
2149
2150 /* skip over trailing spaces */
2151 q = str + len - 1;
2152 while (isspace(*q)) {
2153 j++;
2154 q--;
2155 }
2156 /* j now has end position of string */
2157
2158 j = len - j - i; /* count number of remaining characters */
2159 q = str + i; /* set pointer to beginning of trimmed string */
2160 for (; j>0; j--) {
2161 *p = *q; /* copy characters */
2162 p++;
2163 q++;
2164 }
2165
2166 *p = '\0'; /* terminate string */
2167
2168 return(out);
2169 } else {
2170 return(NULL);
2171 }
2172}
2173
2174
2176{
2192 int i = 0, /* counter for start position of string */
2193 j = 0, /* counter for end position of string */
2194 len = 0; /* length of input string */
2195
2196 char *p, *q; /* pointers for looping through the input string */
2197
2198 if (str != NULL && *str != 0) {
2199
2200 len = strlen(str);
2201 /* set pointers to beginning of input string */
2202 p = str;
2203 q = str;
2204
2205 /* skip over leading spaces */
2206 while (isspace(*q)) {
2207 i++;
2208 q++;
2209 }
2210 /* i now has start position of string */
2211
2212 /* skip over trailing spaces */
2213 q = str + len - 1;
2214 while (isspace(*q)) {
2215 j++;
2216 if (*q == *p) /* Avoids valgrind error */
2217 {
2218 break;
2219 }
2220 q--;
2221 }
2222 /* j now has end position of string */
2223
2224 j = len - j - i; /* count number of remaining characters */
2225 q = str + i; /* set pointer to beginning of trimmed string */
2226 for (; j>0; j--) {
2227 *p = *q; /* copy characters */
2228 p++;
2229 q++;
2230 }
2231
2232 *p = '\0'; /* terminate string */
2233 }
2234}
2235
2236
2237cpl_boolean sc_basic_isnumber(char *str)
2238{
2258 cpl_boolean issign = CPL_FALSE, ispoint = CPL_FALSE, isexp = CPL_FALSE;
2259 int length = 0, iexp = 0, i = 0;
2260
2261 if (str && *str) {
2262
2263 length = strlen(str);
2264
2265 for (iexp = 0, i = 0; i < length; i++) {
2266
2267 if (isdigit(str[i]) != 0) {
2268 /* Numbers are OK */
2269 continue;
2270 } else if (str[i] == '+' || str[i] == '-') {
2271 /* Correct position of sign */
2272 if (i == 0) {
2273 issign = CPL_TRUE;
2274 }
2275 if (i == length-1) {
2276 return CPL_FALSE;
2277 } else if (i > 1 && iexp != 1) {
2278 return CPL_FALSE;
2279 }
2280 } else if (str[i] == '.') {
2281 /* Correct position of decimal point */
2282 if (i == 0 && length == 1) {
2283 return CPL_FALSE;
2284 } else if (i > 0 && ispoint == CPL_TRUE) {
2285 return CPL_FALSE;
2286 } else if (i > 1 && iexp > 0) {
2287 return CPL_FALSE;
2288 }
2289 ispoint = CPL_TRUE;
2290 } else if (str[i] == 'e' || str[i] == 'E') {
2291 /* Correct position of exponent */
2292 if (i == length-1) {
2293 return CPL_FALSE;
2294 } else if (i == 1 &&
2295 (issign == CPL_TRUE || ispoint == CPL_TRUE)) {
2296 return CPL_FALSE;
2297 } else if (i > 0 && isexp == CPL_TRUE) {
2298 return CPL_FALSE;
2299 }
2300 isexp = CPL_TRUE;
2301 } else {
2302 return CPL_FALSE;
2303 }
2304
2305 /* Count number of characters after exponent sign */
2306 if (isexp == CPL_TRUE) {
2307 iexp++;
2308 }
2309
2310 }
2311
2312 } else {
2313
2314 return CPL_FALSE; // null pointer
2315
2316 }
2317
2318 return CPL_TRUE;
2319}
2320
2321
2322cpl_boolean sc_basic_isinteger(char *str)
2323{
2341 int i;
2342 int falseflag = 0;
2343
2344 /* include "-" and "+" as sign */
2345
2346 if (str && *str) {
2347 if (str[0] == '+' || str[0] == '-') {
2348 i = 1;
2349 } else {
2350 i = 0;
2351 }
2352
2353 for (;(unsigned)i < strlen(str); i++) {
2354 if (isdigit(str[i]) == 0) {
2355 falseflag = 1;
2356 }
2357 }
2358 }
2359
2360 if (falseflag == 1) {
2361 return CPL_FALSE;
2362 } else {
2363 return CPL_TRUE;
2364 }
2365
2366}
2367
2368
2369cpl_error_code sc_basic_interpollin(const double *x_out, double *y_out,
2370 const long n_out, const double *x_ref,
2371 const double *y_ref, const long n_ref,
2372 const int extrapolate)
2373{
2404 long out, ref; /* counter for length of output & reference array */
2405
2406 const double *xr,
2407 *yr; /* pointers for looping through the reference arrays */
2408 const double *xo;
2409 double *yo; /* pointers for looping through the output arrays */
2410
2411 int divide_by_zero = 0; /* at least one value has a divide by zero */
2412
2413 /* set pointers to start values */
2414 xr = x_ref;
2415 yr = y_ref;
2416 xo = x_out;
2417 yo = y_out;
2418
2419 for (ref = 0, out = 0; out < n_out; out++, xo++, yo++) {
2420 /*
2421 * find first element in ref that is larger than current out and
2422 * ensure that ref does not overshoot valid range
2423 */
2424 while (*xr < *xo && ref < n_ref) {
2425 xr++;
2426 yr++;
2427 ref++;
2428 }
2429
2430 /* if current out is larger than ref go one step back */
2431 if (xr-x_ref > 0) {
2432 xr--;
2433 yr--;
2434 ref--;
2435 }
2436
2437 /* if out is larger than last ref use last two points */
2438 if (ref == n_ref - 1) {
2439 if (extrapolate == 1) {
2440 xr = x_ref + n_ref - 2;
2441 yr = y_ref + n_ref - 2;
2442 } else {
2443 xr = x_ref + n_ref - 1;
2444 yr = y_ref + n_ref - 1;
2445 }
2446 }
2447
2448 /* calculate linear interpolation */
2449 if (*(xr + 1) - *xr == 0) {
2450 *yo = *yr;
2451 divide_by_zero = 1;
2452 } else {
2453 /* if out is smaller than last ref use first point */
2454 if (extrapolate != 1 && *xo < *xr) {
2455 *yo = *yr;
2456 } else {
2457 /* else use linear interpolation */
2458 *yo = (*xo - *xr) * (*(yr + 1) - *yr) /
2459 (*(xr + 1) - *xr) + *yr;
2460 }
2461 }
2462 }
2463
2464 if (divide_by_zero == 1) {
2465 return cpl_error_set_message(cpl_func, (cpl_error_code)CPL_ERROR_DIVISION_BY_ZERO,
2466 "Duplicate x-values");
2467 } else {
2468 return CPL_ERROR_NONE;
2469 }
2470}
2471
2472
2473inline int sc_basic_gaussfunc(double *fgauss, const double *xgauss,
2474 const int n_data, const double *par)
2475{
2491 // p[0]: Normalisation
2492 // p[1]: position
2493 // p[2]: width
2494
2495 int i;
2496
2497 /* Compute Gaussian */
2498 for (i = 0; i < n_data; i++) {
2499 fgauss[i] = par[0] * pow(CPL_MATH_E, -pow(xgauss[i] - par[1], 2) /
2500 (2 * pow(par[2], 2)));
2501 }
2502
2503 return 0;
2504}
2505
2506
2507cpl_error_code sc_basic_getfilename(char *dir, char *filename, char *suffix,
2508 const char *path)
2509{
2526 char str[SC_MAXLEN], *ptr;
2527 cpl_boolean hasdot = CPL_FALSE, hasslash = CPL_FALSE;
2528 size_t len;
2529 int i = 0;
2530
2531 /* Handle NULL input */
2532 if (path == NULL || path[0] == '\0') {
2533 dir = NULL;
2534 filename = NULL;
2535 suffix = NULL;
2536 return CPL_ERROR_NONE;
2537 }
2538
2539 /* Get string length */
2540 len = strlen(path);
2541
2542 /* Get copy of input string */
2543 strcpy(str, path);
2544
2545 /* Find separators and substitute them by spaces */
2546 for (i = len-1; i >= 0; i--) {
2547 if (str[i] == '.' && hasdot == CPL_FALSE && hasslash == CPL_FALSE) {
2548 str[i] = ' ';
2549 hasdot = CPL_TRUE;
2550 } else if (str[i] == '/' && hasslash == CPL_FALSE) {
2551 str[i] = ' ';
2552 hasslash = CPL_TRUE;
2553 }
2554 }
2555
2556 /* Handle the case without path and file suffix */
2557 if (hasdot == CPL_FALSE && hasslash == CPL_FALSE) {
2558 if (dir != NULL) {
2559 sprintf(dir, ".");
2560 }
2561 if (filename != NULL) {
2562 strcpy(filename, str);
2563 }
2564 suffix = NULL;
2565 return CPL_ERROR_NONE;
2566 }
2567
2568 /* Split string at spaces by means of strtok and return substrings */
2569
2570 /* Separation of directory path and file name */
2571 ptr = strtok(str, " ");
2572 if (hasslash == CPL_FALSE) {
2573 if (dir != NULL) {
2574 sprintf(dir, ".");
2575 }
2576 if (filename != NULL) {
2577 sprintf(filename, "%s", ptr);
2578 }
2579 } else {
2580 if (dir != NULL) {
2581 sprintf(dir, "%s", ptr);
2582 }
2583 ptr = strtok(NULL, " ");
2584 if (filename != NULL) {
2585 sprintf(filename, "%s", ptr);
2586 }
2587 }
2588
2589 /* Separation of file name and suffix */
2590 if (hasdot == CPL_TRUE && suffix != NULL) {
2591 ptr = strtok(NULL, " ");
2592 sprintf(suffix, "%s", ptr);
2593 } else {
2594 suffix = NULL;
2595 }
2596
2597 return CPL_ERROR_NONE;
2598}
2599
2600
2601cpl_error_code sc_basic_getmaskval_vector(double maskval[2],
2602 const cpl_vector *vector)
2603{
2622 char errtxt[SC_MAXLEN] = "";
2623 int n = 0;
2624 double maskmin = 0., maskmax = 0.;
2625
2626 /* Get size of vector */
2627 n = cpl_vector_get_size(vector);
2628 if (n <= 0) {
2629 sprintf(errtxt, "%s: cpl_vector *vector", SC_ERROR_NDA_TXT);
2630 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_NDA, "%s", errtxt);
2631 }
2632
2633 /* Get minimum and maximum value */
2634 maskmin = cpl_vector_get_min(vector);
2635 maskmax = cpl_vector_get_max(vector);
2636
2637 /* Identify good and bad mask values */
2638 if ((maskmin == 0. || maskmin == 1.) && maskmax == 1.) {
2639 /* Integer values: 0 = bad, 1 = good */
2640 maskval[0] = maskmin;
2641 maskval[1] = maskmax;
2642 } else if (maskmin == 0. && maskmax != 1.) {
2643 /* Real values: !0 = bad, 0 = good */
2644 maskval[0] = maskmax;
2645 maskval[1] = maskmin;
2646 } else {
2647 sprintf(errtxt, "%s: cpl_vector *vector (minimum != 0 and != 1)",
2648 SC_ERROR_IOV_TXT);
2649 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s",
2650 errtxt);
2651 }
2652
2653 return CPL_ERROR_NONE;
2654}
2655
2656
2657cpl_error_code sc_basic_getmaskval_image(double maskval[2],
2658 const cpl_image *image)
2659{
2678 char errtxt[SC_MAXLEN] = "";
2679 int nx = 0, ny = 0;
2680 double maskmin = 0., maskmax = 0.;
2681
2682 /* Get size of image */
2683 nx = cpl_image_get_size_x(image);
2684 ny = cpl_image_get_size_y(image);
2685 if (nx <= 0 || ny <= 0) {
2686 sprintf(errtxt, "%s: cpl_image *image", SC_ERROR_NDA_TXT);
2687 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_NDA, "%s", errtxt);
2688 }
2689
2690 /* Get minimum and maximum value */
2691 maskmin = cpl_image_get_min(image);
2692 maskmax = cpl_image_get_max(image);
2693
2694 /* Identify good and bad mask values */
2695 if ((maskmin == 0. || maskmin == 1.) && maskmax == 1.) {
2696 /* Integer values: 0 = bad, 1 = good */
2697 maskval[0] = 0.;
2698 maskval[1] = 1.;
2699 } else if (maskmin == 0. && maskmax != 1.) {
2700 /* Real values: !0 = bad, 0 = good */
2701 maskval[0] = maskmax;
2702 maskval[1] = 0.;
2703 } else {
2704 sprintf(errtxt, "%s: cpl_image *image (minimum != 0 and != 1)",
2705 SC_ERROR_IOV_TXT);
2706 return cpl_error_set_message(cpl_func, (cpl_error_code)SC_ERROR_IOV, "%s",
2707 errtxt);
2708 }
2709
2710 return CPL_ERROR_NONE;
2711}
2712
2713
2714cpl_error_code sc_basic_calcsinc(cpl_vector *sinc)
2715{
2736 int nsinc, nsinch, k;
2737 double dx;
2738 double *kern;
2739
2740 /* Get number of data points from header constants */
2741 nsinc = (2 * SC_SINCRAD_PRECOMP) * SC_SINCNBIN + 1;
2742 cpl_error_ensure((nsinc % 2 == 1), CPL_ERROR_ILLEGAL_INPUT,
2743 return CPL_ERROR_ILLEGAL_INPUT,
2744 "sc_basic_calcsinc requires odd number of points");
2745
2746 /* Initialise vector for function values */
2747 cpl_vector_set_size(sinc, nsinc);
2748 cpl_vector_fill(sinc, 0.);
2749
2750 /* Bisect number of data points */
2751 nsinch = nsinc / 2;
2752
2753 /* Set radius and step size of function */
2754 dx = (2. * SC_SINCRAD_PRECOMP) / (nsinc - 1.);
2755
2756 /* Get pointer to CPL array */
2757 kern = cpl_vector_get_data(sinc);
2758
2759 /* Calculate left-hand side of damped sinc function */
2760 for (k = 0; k < nsinch; k++) {
2761 double x = (k - nsinch) * dx;
2762 if (ceil(x) == x)
2763 kern[k] = 0.;
2764 else
2765 kern[k] = exp(- pow(x / SC_SINCDAMP, 2))
2766 * sin(CPL_MATH_PI * x) / (CPL_MATH_PI * x);
2767 }
2768
2769 /* Set central value */
2770 kern[nsinch] = 1.;
2771
2772 /* Mirror left-hand half to get right-hand function values */
2773 for (k = nsinch + 1; k < nsinc; k++) {
2774 kern[k] = kern[nsinc - k - 1];
2775 }
2776
2777 return CPL_ERROR_NONE;
2778}
2779
cpl_error_code sc_basic_rebin(cpl_table *outspec, const char *outlam, const char *outflux, const cpl_table *inspec, const char *inlam, const char *influx)
Definition: sc_basic.c:296
double sc_basic_mjd2fracyear(double mjd)
Definition: sc_basic.c:179
#define SC_MAXLEN
Definition: sc_basic.h:94
cpl_error_code sc_basic_linecount(long *n_lines, FILE *fp)
Definition: sc_basic.c:831
int sc_basic_gaussfunc(double *fgauss, const double *xgauss, const int n_data, const double *par)
Definition: sc_basic.c:2473
#define SC_MIN(a, b)
Definition: sc_basic.h:85
cpl_error_code sc_basic_access(const char *pathname, const int mode)
Definition: sc_basic.c:1199
cpl_error_code sc_basic_col2arr(cpl_array *arr, const cpl_table *tab, const char *colname)
Definition: sc_basic.c:1652
#define SC_SINCDAMP
Definition: sc_basic.h:122
cpl_boolean sc_basic_isnumber(char *str)
Definition: sc_basic.c:2237
cpl_error_code sc_basic_clipmean(double *mean, double *rms, cpl_array *arr, const cpl_boolean clip)
Definition: sc_basic.c:1539
cpl_error_code sc_basic_copytable_content(cpl_table *outtab, const cpl_table *intab)
Definition: sc_basic.c:1923
cpl_error_code sc_basic_greg2jd(long *jd, const int year, const int month, const int day)
Definition: sc_basic.c:1297
#define SC_SINCRAD_PRECOMP
Definition: sc_basic.h:118
cpl_error_code sc_basic_filtermedian(cpl_table *spec, const char *colname, const int npix)
Definition: sc_basic.c:745
cpl_error_code sc_basic_copytable_full(cpl_table *outtab, const cpl_table *intab)
Definition: sc_basic.c:1991
#define SC_TOL
Definition: sc_basic.h:96
cpl_error_code sc_basic_interpollin(const double *x_out, double *y_out, const long n_out, const double *x_ref, const double *y_ref, const long n_ref, const int extrapolate)
Definition: sc_basic.c:2369
cpl_error_code sc_basic_convolve(cpl_table *spec, const char *colname, const cpl_array *kernel)
Definition: sc_basic.c:441
#define SC_MAXPAR
Definition: sc_basic.h:99
char * sc_basic_strtrim(char *str)
Definition: sc_basic.c:2115
cpl_error_code sc_basic_getmaskval_image(double maskval[2], const cpl_image *image)
Definition: sc_basic.c:2657
cpl_error_code sc_basic_arr2col(cpl_table *tab, const char *colname, const cpl_array *arr)
Definition: sc_basic.c:1757
double sc_basic_fracyear2date(int *year, int *month, int *day, int *hh, int *mm, double *ss, const double *fracyear)
Definition: sc_basic.c:206
void sc_basic_abspath(char *out, const char *dir, const char *cwd)
Definition: sc_basic.c:1133
void sc_basic_dirslash(char *dir)
Definition: sc_basic.c:1109
void sc_basic_rhum2ppmv(double *ppmv, const double *tem, const double *p, const double *hum)
Definition: sc_basic.c:870
void sc_basic_initstring(char *str, const long n)
Definition: sc_basic.c:2060
cpl_error_code sc_basic_getfilename(char *dir, char *filename, char *suffix, const char *path)
Definition: sc_basic.c:2507
cpl_error_code sc_basic_convolvewindow(cpl_array *convflux, const cpl_array *flux, const int range[2], const cpl_array *kernel)
Definition: sc_basic.c:564
cpl_error_code sc_basic_rhum2ppmv_old(const cpl_array *temp, const cpl_array *pres, const cpl_array *rhum, cpl_array *ppmv)
Definition: sc_basic.c:935
void sc_basic_strtrim_inplace(char *str)
Definition: sc_basic.c:2175
cpl_error_code sc_basic_readline(FILE *stream, scpar par[], int *npar)
Definition: sc_basic.c:52
#define SC_MAX(a, b)
Definition: sc_basic.h:87
cpl_error_code sc_basic_getmaskval_vector(double maskval[2], const cpl_vector *vector)
Definition: sc_basic.c:2601
cpl_error_code sc_basic_calcsinc(cpl_vector *sinc)
Definition: sc_basic.c:2714
cpl_error_code sc_basic_planck(cpl_array *bb, const cpl_array *wavelength, const double temp)
Definition: sc_basic.c:1058
cpl_error_code sc_basic_jd2greg(int *year, int *month, int *day, const long jd)
Definition: sc_basic.c:1334
cpl_error_code sc_basic_sortarr(cpl_array *arr, cpl_type type)
Definition: sc_basic.c:1871
#define SC_SINCNBIN
Definition: sc_basic.h:120
void sc_basic_terminatestring(char *str)
Definition: sc_basic.c:2086
cpl_boolean sc_basic_isinteger(char *str)
Definition: sc_basic.c:2322