29 #include "muse_utils.h" 30 #include "muse_cplwrappers.h" 31 #include "muse_data_format_z.h" 34 #define MUSE_SKY_T_VIBR 200.0 48 muse_sky_ohtransitions_load(
const char *aFile)
50 if (!cpl_fits_find_extension(aFile,
"OH_TRANSITIONS")) {
70 muse_sky_lines_reindex_groups(cpl_table *aLines)
72 cpl_ensure_code(aLines, CPL_ERROR_NULL_INPUT);
73 cpl_size n_rows = cpl_table_get_nrow(aLines);
76 int i_max = cpl_table_get_column_max(aLines,
"group");
77 int new_ids[i_max + 1];
78 for (i = 0; i <= i_max; i++) {
83 for (i_row = 0; i_row < n_rows; i_row++) {
84 int old_id = cpl_table_get_int(aLines,
"group", i_row, NULL);
85 if (new_ids[old_id] < 0) {
86 new_ids[old_id] = i_max++;
88 cpl_table_set_int(aLines,
"group", i_row, new_ids[old_id]);
91 return CPL_ERROR_NONE;
110 cpl_ensure_code(aLines, CPL_ERROR_NULL_INPUT);
111 #pragma omp critical(cpl_table_select) 112 cpl_table_unselect_all(aLines);
113 cpl_table_or_selected_double(aLines,
"lambda", CPL_LESS_THAN, aLow);
114 cpl_table_or_selected_double(aLines,
"lambda", CPL_GREATER_THAN, aHigh);
115 cpl_table_erase_selected(aLines);
116 muse_sky_lines_reindex_groups(aLines);
118 return CPL_ERROR_NONE;
137 cpl_propertylist *aHeader)
139 cpl_ensure_code(aProcessing && aLines && aHeader, CPL_ERROR_NULL_INPUT);
142 CPL_FRAME_TYPE_TABLE);
143 cpl_ensure_code(frame, CPL_ERROR_ILLEGAL_INPUT);
144 const char *filename = cpl_frame_get_filename(frame);
145 cpl_error_code rc = cpl_propertylist_save(aHeader, filename, CPL_IO_CREATE);
148 if (rc == CPL_ERROR_NONE) {
149 #pragma omp critical(muse_processing_output_frames) 150 cpl_frameset_insert(aProcessing->
outframes, frame);
152 cpl_frame_delete(frame);
171 cpl_ensure(aProcessing, CPL_ERROR_NULL_INPUT, NULL);
173 MUSE_TAG_SKY_LINES, 0, CPL_FALSE);
174 cpl_errorstate es = cpl_errorstate_get();
175 cpl_frame *frame = cpl_frameset_get_position(frames, 0);
177 cpl_frameset_delete(frames);
178 cpl_errorstate_set(es);
179 cpl_msg_warning(__func__,
"No sky lines found in input frameset!");
182 const char *fn = cpl_frame_get_filename(frame);
183 cpl_table *oh_transitions = muse_sky_ohtransitions_load(fn);
185 if (lines == NULL && oh_transitions == NULL) {
186 cpl_msg_warning(__func__,
"Could not load sky lines from \"%s\"", fn);
187 cpl_frameset_delete(frames);
193 cpl_msg_info(__func__,
"Loaded sky lines from \"%s\"", fn);
196 cpl_msg_indent_more();
197 const char *unit = cpl_table_get_column_unit(lines,
"flux");
199 cpl_msg_warning(__func__,
"No flux unit given!");
201 if (unit && strcmp(unit,
"erg/(s cm^2 arcsec^2)") == 0) {
202 cpl_msg_info(__func__,
"Scaling flux by 1e20.");
203 cpl_table_multiply_scalar(lines,
"flux", 1e20);
204 cpl_table_set_column_unit(lines,
"flux",
205 "10**(-20)*erg/(s cm^2 arcsec^2)");
207 if (unit && strcmp(unit,
"10**(-20)*erg/(s cm^2 arcsec^2)") != 0) {
208 cpl_msg_warning(__func__,
"Unsupported flux unit \"%s\".",
209 cpl_table_get_column_unit(lines,
"flux"));
211 cpl_msg_indent_less();
215 cpl_frameset_delete(frames);
219 cpl_table_delete(oh_transitions);
220 cpl_table_delete(lines);
241 cpl_ensure_code(aLines != NULL, CPL_ERROR_NULL_INPUT);
242 cpl_ensure_code(aStrength != NULL, CPL_ERROR_NULL_INPUT);
244 int *group = cpl_table_get_data_int(aLines,
"group");
245 cpl_ensure_code(group != NULL, CPL_ERROR_ILLEGAL_INPUT);
246 double *flux = cpl_table_get_data_double(aLines,
"flux");
247 cpl_ensure_code(flux != NULL, CPL_ERROR_ILLEGAL_INPUT);
248 cpl_size nRows = cpl_table_get_nrow(aLines);
250 for (i = 0; i < nRows; i++, group++, flux++) {
251 *flux *= cpl_array_get(aStrength, *group, NULL);
253 return CPL_ERROR_NONE;
270 cpl_ensure_code(aLines != NULL, CPL_ERROR_NULL_INPUT);
271 cpl_table_select_all(aLines);
272 cpl_table_and_selected_double(aLines,
"flux", CPL_LESS_THAN, aMinflux);
273 cpl_table_erase_selected(aLines);
274 return CPL_ERROR_NONE;
300 muse_sky_lines_create_oh(
const cpl_table *aTransitions,
double aTemperature)
302 if ((aTransitions == NULL) || (cpl_table_get_nrow(aTransitions) == 0)) {
306 const int max_level = cpl_table_get_column_max(aTransitions,
"v_u");
307 const int min_level = cpl_table_get_column_min(aTransitions,
"v_u");
308 cpl_ensure(max_level-min_level < 100, CPL_ERROR_UNSUPPORTED_MODE, NULL);
309 const int n_transitions = cpl_table_get_nrow(aTransitions);
313 cpl_table_copy_data_string(lines,
"name",
314 cpl_table_get_data_string_const(aTransitions,
316 cpl_table_copy_data_double(lines,
"lambda",
317 cpl_table_get_data_double_const(aTransitions,
319 cpl_table_copy_data_int(lines,
"group",
320 cpl_table_get_data_int_const(aTransitions,
"v_u"));
321 cpl_table_subtract_scalar(lines,
"group", min_level);
323 cpl_table_fill_column_window_double(lines,
"flux", 0, n_transitions, 0.0);
325 const double k_B = 1.3806504e-23;
326 const double hc = 1.98623e-8;
327 cpl_table_copy_data_double(lines,
"flux",
328 cpl_table_get_data_double_const(aTransitions,
"E_u"));
329 cpl_table_divide_scalar(lines,
"flux", -k_B * aTemperature);
330 cpl_table_exponential_column(lines,
"flux", CPL_MATH_E);
332 cpl_table_duplicate_column(lines,
"J_u", aTransitions,
"J_u");
333 cpl_table_multiply_scalar(lines,
"J_u", 2.0);
334 cpl_table_add_scalar(lines,
"J_u", 1.0);
335 cpl_table_multiply_columns(lines,
"flux",
"J_u");
336 cpl_table_erase_column(lines,
"J_u");
338 cpl_table_fill_column_window_int(lines,
"dq", 0, n_transitions, 0);
340 double *flux = cpl_table_get_data_double(lines,
"flux");
341 const int *group = cpl_table_get_data_int_const(lines,
"group");
343 double q[max_level - min_level + 1];
344 memset(q, 0, (max_level - min_level + 1)*
sizeof(
double));
346 for (i_transition = 0; i_transition < n_transitions; i_transition++,
351 cpl_table_duplicate_column(lines,
"A", aTransitions,
"A");
352 cpl_table_multiply_columns(lines,
"flux",
"A");
353 cpl_table_erase_column(lines,
"A");
354 cpl_table_multiply_scalar(lines,
"flux", 2.0 * hc);
355 cpl_table_divide_columns(lines,
"flux",
"lambda");
357 flux = cpl_table_get_data_double(lines,
"flux");
358 group = cpl_table_get_data_int_const(lines,
"group");
360 for (i_transition = 0; i_transition < n_transitions; i_transition++,
365 cpl_table_multiply_scalar(lines,
"flux", 1e20);
367 cpl_table_divide_scalar(lines,
"flux", 50);
369 muse_sky_lines_reindex_groups(lines);
390 const cpl_table *aOh_transitions,
double aT_vibr)
392 int group_start = (aLines && cpl_table_get_nrow(aLines) > 0)?
393 cpl_table_get_column_max(aLines,
"group") + 1: 0;
394 cpl_table *res = muse_sky_lines_create_oh(aOh_transitions, aT_vibr);
395 cpl_errorstate prestate = cpl_errorstate_get();
397 cpl_table_add_scalar(res,
"group", group_start);
398 cpl_table_insert(res, aLines, 0);
400 if (!cpl_errorstate_is_equal(prestate)) {
401 cpl_msg_error(__func__,
"while cpl_table_insert(): %s, %s",
402 cpl_table_get_column_unit(res,
"flux"),
403 cpl_table_get_column_unit(aLines,
"flux"));
404 cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
405 cpl_errorstate_set(prestate);
cpl_error_code muse_sky_lines_apply_strength(cpl_table *aLines, const cpl_array *aStrength)
Apply the line strengths to the lines.
cpl_error_code muse_sky_lines_save(muse_processing *aProcessing, const cpl_table *aLines, cpl_propertylist *aHeader)
Save sky lines table to file.
cpl_table * muse_sky_lines_create(const cpl_table *aLines, const cpl_table *aOh_transitions, double aT_vibr)
Create the emission lines from the OH transitions and other lines.
cpl_table * muse_sky_lines_load(muse_processing *aProcessing)
Load the sky data files.
cpl_table * muse_cpltable_load(const char *aFile, const char *aExtension, const muse_cpltable_def aDefinition[])
Load a table from disk (and check against definition).
cpl_table * muse_cpltable_new(const muse_cpltable_def *aDef, cpl_size aLength)
Create an empty table according to the specified definition.
cpl_frame * muse_processing_new_frame(muse_processing *aProcessing, int aIFU, cpl_propertylist *aHeader, const char *aTag, cpl_frame_type aType)
Create a new frame for a result file.
cpl_error_code muse_sky_lines_set_range(cpl_table *aLines, double aLow, double aHigh)
Limit the lines in the table to a wavelength range.
void muse_processing_append_used(muse_processing *aProcessing, cpl_frame *aFrame, cpl_frame_group aGroup, int aDuplicate)
Add a frame to the set of used frames.
cpl_error_code muse_sky_lines_cut(cpl_table *aLines, double aMinflux)
Remove all lines below a certain flux limit.
cpl_frameset * muse_frameset_find(const cpl_frameset *aFrames, const char *aTag, unsigned char aIFU, cpl_boolean aInvert)
return frameset containing data from an IFU/channel with a certain tag
cpl_error_code muse_cpltable_append_file(const cpl_table *aTable, const char *aFile, const char *aExtension, const muse_cpltable_def aDefinition[])
Save a table to disk (into a FITS extension)