53#define INV_DOUBLE -9999.0
54#define LIGHTSPEED1000 299792458
67 xtab=cpl_table_duplicate(tab);
68 int norg=cpl_table_get_nrow(xtab);
70 double* pwave=cpl_table_get_data_double(xtab,wname);
71 double* pflux=cpl_table_get_data_double(xtab,fname);
76 for(j=0;ninv>0,j<4;j++) {
77 nrow=cpl_table_get_nrow(xtab);
78 for(
int i=1;i < nrow; i++) {
79 if (!(pwave[i-1] < pwave[i])) {
80 if(pflux[i-1]<= pflux[i]) {
81 cpl_table_set_invalid(xtab,wname,i-1);
83 cpl_table_set_invalid(xtab,wname,i);
89 ninv=cpl_table_count_invalid(xtab,wname);
90 xsh_msg(
"iter=%d nrow=%d nbad=%d ninv=%d",j,nrow,nbad,ninv);
92 cpl_table_erase_invalid(xtab);
99 int nnew=cpl_table_get_nrow(xtab);
101 xsh_msg(
"N orig %d flagged %d expected %d new %d",norg,nbad,norg-nbad,nnew);
119 cpl_table* spec_tab=NULL;
121 double vel_step=300.;
125 return cpl_error_get_code();
128 sprintf(fname,argv[1]);
131 else if((
size_t)argc>2){
133 hwidth=atof(argv[2]);
134 overlap=atof(argv[3]);
138 smwidth=atoi(argv[7]);
142 xsh_msg_warning(
"hwidth=%f overlap=%f niter=%d thres=%f resol=%f smdiff=%d wdiff=%f",hwidth,overlap,
niter,thres,resol,smwidth,wdiff);
145 cpl_table* org_tab=cpl_table_load(fname, 1, 0);
150 double max=cpl_table_get_column_max(spec_tab,
"FLUX");
151 check(cpl_table_add_scalar(spec_tab,
"FLUX",
max));
152 check(cpl_table_duplicate_column(spec_tab,
"INV_FLUX",spec_tab,
"FLUX"));
153 int nrow=cpl_table_get_nrow(spec_tab);
154 check(cpl_table_fill_column_window_double(spec_tab,
"INV_FLUX",0,nrow,1.));
155 check(cpl_table_divide_columns(spec_tab,
"INV_FLUX",
"FLUX"));
156 cpl_table_erase_column(spec_tab,
"FLUX");
158 cpl_table_name_column(spec_tab,
"INV_FLUX",
"FLUX");
160 cpl_table_name_column(spec_tab,
"WAVE",
"WAVEL");
162 cpl_table_save(spec_tab,NULL,NULL,
"spec_tab.fits",CPL_IO_DEFAULT);
166 double wavel_min = cpl_table_get_double(spec_tab,
"WAVEL", 0, NULL);
167 double wavel_max = cpl_table_get_double(spec_tab,
"WAVEL",
168 cpl_table_get_nrow(spec_tab) - 1, NULL);
169 double pos_start = wavel_min + hwidth;
170 double pos_end = wavel_max - hwidth;
171 if (wavel_min < cpl_table_get_column_min(spec_tab,
"WAVEL")) {
172 pos_start = cpl_table_get_column_min(spec_tab,
"WAVEL") + hwidth;
174 if (wavel_max > cpl_table_get_column_max(spec_tab,
"WAVEL")) {
175 pos_end = cpl_table_get_column_max(spec_tab,
"WAVEL") - hwidth;
180 cpl_table *spec_proc = NULL;
181 cpl_table *line = NULL;
182 cpl_size line_num = 0;
183 cpl_size line_size = 0;
184 if (pos_end < pos_start) {
185 cpl_msg_warning(cpl_func,
"Chunks size is too large w.r.t. the "
186 "wavelength range of the spectrum! It should be lower "
187 "than %f nm.", 0.5 * (wavel_max - wavel_min));
191 double pos_step = hwidth * 2.0 * (1.0 - overlap);
192 int chunk_num = (int)ceil((pos_end - pos_start)/pos_step);
193 cpl_table *line_chunk = NULL;
194 cpl_table *line_temp = cpl_table_new(10000);
197 cpl_table_new_column(line_temp,
"WAVEL", CPL_TYPE_DOUBLE);
198 cpl_table_new_column(line_temp,
"PEAK", CPL_TYPE_DOUBLE);
199 cpl_table_new_column(line_temp,
"CONT", CPL_TYPE_DOUBLE);
200 cpl_table_new_column(line_temp,
"CONTERR", CPL_TYPE_DOUBLE);
201 cpl_table_fill_column_window_double(line_temp,
"CONT", 0, 10000,
203 cpl_table_fill_column_window_double(line_temp,
"CONTERR", 0, 10000,
209 cpl_msg_info(cpl_func,
"*** Undersampling spectrum ***");
210 double vel_step_test = 2.0 * hwidth / (wavel_min *
212 if (vel_step_test < 3.0) {
213 cpl_msg_warning(cpl_func,
"Undersampling of the spectrum is "
214 "incompatible with the adopted chunk size!");
216 log(2.0 * hwidth / (3.0 * wavel_min) + 1.0));
217 cpl_msg_info(cpl_func,
"Parameter vel-step is too low: redefined "
218 "to %6.1f.", vel_step);
227 spec_proc = cpl_table_duplicate(spec_tab);
231 cpl_msg_info(cpl_func,
"*** Creating a line list ***");
232 cpl_msg_info(cpl_func,
"Processing chunks...");
233 for (
double pos = pos_start; pos < pos_end; pos += pos_step) {
236 cpl_table *chunk = NULL;
243 &chunk) == CPL_ERROR_NONE,
244 cpl_error_get_code());
245 cpl_table_unselect_all(chunk);
247 double cont_rejt = 0.95;
249 cpl_propertylist *chunk_col = cpl_propertylist_new();
250 cpl_propertylist_append_bool(chunk_col,
"WAVEL", FALSE);
251 cpl_table_sort(chunk, chunk_col);
252 cpl_propertylist_delete(chunk_col);
255 == CPL_ERROR_NONE, cpl_error_get_code());
257 cpl_ensure_code(
esp_det_line(chunk, thres, resol, smwidth,
258 &line_chunk) == CPL_ERROR_NONE,
259 cpl_error_get_code());
261 cpl_table_unselect_all(line_chunk);
262 cpl_table_or_selected_double (line_chunk,
"WAVEL",
263 CPL_GREATER_THAN, pos - hwidth * (1.0 - overlap));
264 cpl_table_and_selected_double(line_chunk,
"WAVEL",
265 CPL_NOT_GREATER_THAN, pos + hwidth * (1.0 - overlap));
266 if (cpl_table_count_selected(line_chunk) > 0) {
267 cpl_table *line_part = cpl_table_extract_selected(line_chunk);
268 if (flag == 0 && cpl_table_get_nrow(line_part) != 0) {
269 line = cpl_table_duplicate(line_part);
273 cpl_table_insert(line, line_part, line_num);
275 line_num += cpl_table_get_nrow(line_part);
276 cpl_table_delete(line_part);
279 cpl_table_delete(line_chunk);
286 &chunk) == CPL_ERROR_NONE,
287 cpl_error_get_code());
288 cpl_table_unselect_all(chunk);
308 cpl_propertylist *chunk_col = cpl_propertylist_new();
309 cpl_propertylist_append_bool(chunk_col,
"FLUX", FALSE);
310 cpl_table_sort(chunk, chunk_col);
311 cpl_propertylist_delete(chunk_col);
312 int med_row = floor((
int)cpl_table_get_nrow(chunk) / 2.0);
313 double flux_ave = cpl_table_get_column_mean(chunk,
"FLUX");
315 (cpl_table_get_double(chunk,
"FLUX", med_row, NULL) +
316 cpl_table_get_double(chunk,
"FLUX", med_row + 1, NULL))
318 if (flux_med - flux_ave > thres) {
319 cpl_table_set_double(line_temp,
"WAVEL", line_num,
320 cpl_table_get_double(chunk,
"WAVEL", 0, NULL));
321 cpl_table_set_double(line_temp,
"PEAK", line_num,
322 cpl_table_get_double(chunk,
"FLUX", 0, NULL));
326 cpl_table_delete(chunk);
329 int chunk_ord = (int)ceil(log10(chunk_num));
331 if ((i + 1) % (int)ceil(chunk_num/10.0) == 0 && i < chunk_num) {
332 cpl_msg_warning(cpl_func,
" %-*i chunks processed; %-*i remaining... ",
333 chunk_ord, i, chunk_ord, chunk_num - i);
335 if (i == chunk_num) {
336 cpl_msg_warning(cpl_func,
"%i lines found...", (
int)line_num);
339 line = cpl_table_extract(line_temp, 0, line_num);
340 cpl_table_save(line,NULL,NULL,
"line.fits",CPL_IO_DEFAULT);
342 cpl_table_delete(line_temp);
347 return cpl_error_get_code();
357int main(
int argc,
char* argv[])
360 cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
363 return cpl_test_end(0);
int main()
Unit test of xsh_bspline_interpol.
#define xsh_msg_warning(...)
Print an warning message.
#define xsh_msg(...)
Print a message on info level.
static cpl_table * xsh_table_unique_wave(cpl_table *tab, const char *wname, const char *fname)
cpl_error_code test_spectrum_detect_lines(int argc, char *argv[])
cpl_error_code xsh_sort_table_1(cpl_table *t, const char *column, cpl_boolean reverse)
Sort a table by one column.
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
cpl_error_code esp_det_line(cpl_table *spec_cont_region, double det_line_thres, double det_line_resol, int det_line_smwidth, cpl_table **line_table)
Performs a local normalization of the spectrum region.
cpl_error_code esp_fit_lcont(cpl_table *spec_region, double cont_rejt, int cont_iter)
Performs a local normalization of the spectrum region.
cpl_error_code select_local_spec(cpl_table *spec_total, double ew_space, double lambda, cpl_table **spec_region)
Select_local_spec.