diff --git a/src/geomtools/__init__.py b/src/geomtools/__init__.py index 28a9d3ea297692a2b9681e2b30aa9d2e9c6b6b00..5652b69a86571e3702f10db83b36801d962ffe68 100644 --- a/src/geomtools/__init__.py +++ b/src/geomtools/__init__.py @@ -1,10 +1,11 @@ # flake8: noqa E401 from .sfx import ( parse_crystfel_streamfile, read_crystfel_streamfile, extract_geometry, - plot_center_shift, plot_cell_parameters, plot_peakogram, plot_powder, - ph_en_to_lambda, get_q_from_xyz, get_min_bragg_dist, spacing, - gauss2d_fit, ellipse, parse_xwiz_summary, get_peak_position, - plot_geoptimiser_errormap, avg_pixel_displacement, rmsd_per_group, + extract_cell, plot_center_shift, plot_cell_parameters, plot_peakogram, + plot_powder, ph_en_to_lambda, get_q_from_xyz, get_min_bragg_dist, + spacing, cell_volume, gauss2d_fit, ellipse, parse_xwiz_summary, + get_peak_position, plot_geoptimiser_errormap, avg_pixel_displacement, + rmsd_per_group, read_crystfel_cell, ) from .detector import ( read_crystfel_geom, get_pixel_positions, assemble_data, diff --git a/src/geomtools/sfx/__init__.py b/src/geomtools/sfx/__init__.py index 5095366d7bf516e0f47b2bdb7bad8e37eda215d3..56452e10030127ce53d9aca1c72a5be6a15650fa 100644 --- a/src/geomtools/sfx/__init__.py +++ b/src/geomtools/sfx/__init__.py @@ -1,13 +1,15 @@ # flake8: noqa E401 from .crystfelio import ( parse_crystfel_streamfile, read_crystfel_streamfile, extract_geometry, + extract_cell, ) from .draw import ( plot_center_shift, plot_cell_parameters, plot_peakogram, plot_powder, plot_geoptimiser_errormap, ) from .lattice import ( - spacing, ph_en_to_lambda, get_q_from_xyz, get_min_bragg_dist, + cell_volume, spacing, ph_en_to_lambda, get_q_from_xyz, + get_min_bragg_dist, read_crystfel_cell, ) from .misc import ( gauss2d_fit, ellipse, get_peak_position, avg_pixel_displacement, diff --git a/src/geomtools/sfx/crystfelio.py b/src/geomtools/sfx/crystfelio.py index 2adc6fe910ea73cd160d949f308fee0a7916aa3b..232e5b03fce718903bf95256ce55324149965d49 100644 --- a/src/geomtools/sfx/crystfelio.py +++ b/src/geomtools/sfx/crystfelio.py @@ -13,6 +13,8 @@ from cfelpyutils.crystfel_stream import ( GEOM_START_MARKER = "----- Begin geometry file -----" GEOM_END_MARKER = "----- End geometry file -----" +CELL_START_MARKER = "----- Begin unit cell -----" +CELL_END_MARKER = "----- End unit cell -----" PEAK_COLUMN_MAP = { "fs/px": "fs", "ss/px": "ss", "(1/d)/nm^-1": "res", @@ -49,7 +51,8 @@ def match_reflexes_to_peaks(reflexes, peaks, lattices, # 2. one reflex to one peak # 3. one peak to one reflex in the same crystal # but to can also match refelex in other crystals - re = reflexes[['fs', 'ss', 'panel', 'frame', 'cryst', 'reflno']].copy() + re = reflexes[['fs', 'ss', 'panel', 'frame', 'cryst', 'reflno', + 'xa', 'ya']].copy() if group_name != 'panel': re = re.join(panels[[group_name]], on='panel') re = re.join(get_peak_position(re, panels)) @@ -83,7 +86,8 @@ def match_reflexes_to_peaks(reflexes, peaks, lattices, def parse_crystfel_streamfile(stream_filename, panels, connected_groups, begin=0, end=None): - lattice_params = ['lattice_type', 'centering', 'unique_axis'] + lattice_params = ['lattice_type', 'centering', 'unique_axis', + 'astar', 'bstar', 'cstar'] lattice_arrays = { 'Cell parameters/lengths': ['a', 'b', 'c'], 'Cell parameters/angles': ['alpha', 'beta', 'gamma'], @@ -143,12 +147,22 @@ def parse_crystfel_streamfile(stream_filename, panels, connected_groups, 1. / res_avg, clen_avg, lmd, cell) lattices.append(la) + la_kwargs = dict((name, la[name]) for name in cell_columns) re = crystal['reflections'] re['res'] = np.sqrt(spacing( re.h.values, re.k.values, re.l.values, **la_kwargs)) + M = np.array([ + crystal['astar'], crystal['bstar'], crystal['cstar'] + ]) + hkl = np.array([re.h.values, re.k.values, re.l.values]) + u, v, w = M.T @ hkl + s = clen / (1e-9 / lmd + w) / 200e-6 + re['xa'] = u * s + re['ya'] = v * s + re['frame'] = frame_ix re['cryst'] = cryst_ix reflexes.append(re) @@ -176,29 +190,63 @@ def parse_crystfel_streamfile(stream_filename, panels, connected_groups, return frames, peaks, lattices, reflexes, match -def extract_geometry(stream_filename): - """Extracts geometry from Crystfel stream file. +def extract_chunk(stream_filename, start_marker, end_marker): + """Extracts text bracketed with markers from Crystfel stream file. Input ----- stream_filename: str Crystfel stream file name + start_marker: str + String indicated begin of the text + end_marker: str + String indicated end of the text Returns ------- - StringIO buffer with geometry file + StringIO buffer with text """ with open(stream_filename, 'r') as f: line = f.readline() - while line and line.strip() != GEOM_START_MARKER: + while line and line.strip() != start_marker: if line.strip() == CHUNK_START_MARKER: return line = f.readline() - geom = _buffer_to_line(f, GEOM_END_MARKER) + geom = _buffer_to_line(f, end_marker) return geom +def extract_geometry(stream_filename): + """Extracts geometry from Crystfel stream file. + + Input + ----- + stream_filename: str + Crystfel stream file name + + Returns + ------- + StringIO buffer with geometry file + """ + return extract_chunk(stream_filename, GEOM_START_MARKER, GEOM_END_MARKER) + + +def extract_cell(stream_filename): + """Extracts unit cell from Crystfel stream file. + + Input + ----- + stream_filename: str + Crystfel stream file name + + Returns + ------- + StringIO buffer with crystfel cell file + """ + return extract_chunk(stream_filename, CELL_START_MARKER, CELL_END_MARKER) + + def _split_file(filename, nproc=20, partsize=None, nbytes=None): """Split file on portions.""" if nbytes is None: