diff --git a/pyzebra/app/panel_ccl_integrate.py b/pyzebra/app/panel_ccl_integrate.py index 5ed46ce..cb78aaf 100644 --- a/pyzebra/app/panel_ccl_integrate.py +++ b/pyzebra/app/panel_ccl_integrate.py @@ -43,6 +43,7 @@ from bokeh.models import ( ) import pyzebra +from pyzebra.ccl_io import EXPORT_TARGETS from pyzebra.ccl_process import AREA_METHODS @@ -57,7 +58,7 @@ for (let i = 0; i < js_data.data['fname'].length; i++) { document.body.appendChild(link); const url = window.URL.createObjectURL(blob); link.href = url; - link.download = js_data.data['fname'][i]; + link.download = js_data.data['fname'][i] + js_data.data['ext'][i]; link.click(); window.URL.revokeObjectURL(url); document.body.removeChild(link); @@ -71,7 +72,7 @@ for (let i = 0; i < js_data.data['fname'].length; i++) { def create(): det_data = {} fit_params = {} - js_data = ColumnDataSource(data=dict(content=["", ""], fname=["", ""])) + js_data = ColumnDataSource(data=dict(content=["", ""], fname=["", ""], ext=["", ""])) def proposal_textinput_callback(_attr, _old, new): proposal = new.strip() @@ -118,7 +119,7 @@ def create(): det_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(det_data, monitor_spinner.value) pyzebra.merge_duplicates(det_data) - js_data.data.update(fname=[base + ".comm", base + ".incomm"]) + js_data.data.update(fname=[base, base]) _init_datatable() @@ -153,7 +154,7 @@ def create(): det_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(det_data, monitor_spinner.value) pyzebra.merge_duplicates(det_data) - js_data.data.update(fname=[base + ".comm", base + ".incomm"]) + js_data.data.update(fname=[base, base]) _init_datatable() @@ -511,12 +512,15 @@ def create(): export_data.append(s) pyzebra.export_1D( - export_data, temp_file, hkl_precision=int(hkl_precision_select.value), + export_data, + temp_file, + export_target_select.value, + hkl_precision=int(hkl_precision_select.value), ) exported_content = "" file_content = [] - for ext in (".comm", ".incomm"): + for ext in EXPORT_TARGETS[export_target_select.value]: fname = temp_file + ext if os.path.isfile(fname): with open(fname) as f: @@ -529,6 +533,16 @@ def create(): js_data.data.update(content=file_content) export_preview_textinput.value = exported_content + def export_target_select_callback(_attr, _old, new): + js_data.data.update(ext=EXPORT_TARGETS[new]) + _update_preview() + + export_target_select = Select( + title="Export target:", options=list(EXPORT_TARGETS.keys()), value="fullprof", width=80 + ) + export_target_select.on_change("value", export_target_select_callback) + js_data.data.update(ext=EXPORT_TARGETS[export_target_select.value]) + def hkl_precision_select_callback(_attr, _old, _new): _update_preview() @@ -569,7 +583,9 @@ def create(): export_layout = column( export_preview_textinput, - row(hkl_precision_select, column(Spacer(height=19), row(save_button))), + row( + export_target_select, hkl_precision_select, column(Spacer(height=19), row(save_button)) + ), ) tab_layout = column( diff --git a/pyzebra/app/panel_param_study.py b/pyzebra/app/panel_param_study.py index dceff00..3ce5195 100644 --- a/pyzebra/app/panel_param_study.py +++ b/pyzebra/app/panel_param_study.py @@ -600,7 +600,7 @@ def create(): if export: export_data.append(s) - pyzebra.export_1D(export_data, temp_file) + pyzebra.export_1D(export_data, temp_file, "fullprof") exported_content = "" file_content = [] diff --git a/pyzebra/ccl_io.py b/pyzebra/ccl_io.py index bf27d6f..c4f12fd 100644 --- a/pyzebra/ccl_io.py +++ b/pyzebra/ccl_io.py @@ -76,6 +76,8 @@ CCL_SECOND_LINE = ( ("scan_motor", str), ) +EXPORT_TARGETS = {"fullprof": (".comm", ".incomm"), "jana": (".col", ".incol")} + def load_1D(filepath): """ @@ -241,14 +243,19 @@ def parse_1D(fileobj, data_type): return scan -def export_1D(data, path, hkl_precision=2): - """Exports data in the .comm/.incomm format +def export_1D(data, path, export_target, hkl_precision=2): + """Exports data in the .comm/.incomm format for fullprof or .col/.incol format for jana. - Scans with integer/real hkl values are saved in .comm/.incomm files correspondingly. If no scans - are present for a particular output format, that file won't be created. + Scans with integer/real hkl values are saved in .comm/.incomm or .col/.incol files + correspondingly. If no scans are present for a particular output format, that file won't be + created. """ + if export_target not in EXPORT_TARGETS: + raise ValueError(f"Unknown export target: {export_target}.") + zebra_mode = data[0]["zebra_mode"] - file_content = {".comm": [], ".incomm": []} + exts = EXPORT_TARGETS[export_target] + file_content = {ext: [] for ext in exts} for scan in data: if "fit" not in scan: @@ -272,9 +279,16 @@ def export_1D(data, path, hkl_precision=2): angle_center = (np.min(scan[angle]) + np.max(scan[angle])) / 2 else: angle_center = scan[angle] + + if angle == "twotheta" and export_target == "jana": + angle_center /= 2 + ang_str = ang_str + f"{angle_center:8g}" - ref = file_content[".comm"] if hkl_are_integers else file_content[".incomm"] + if export_target == "jana": + ang_str = ang_str + f"{scan['temp']:8}" + f"{scan['monitor']:8}" + + ref = file_content[exts[0]] if hkl_are_integers else file_content[exts[1]] ref.append(idx_str + hkl_str + area_str + ang_str + "\n") for ext, content in file_content.items():