diff --git a/src/geomtools/detector/crystfel_frm.py b/src/geomtools/detector/crystfel_frm.py index 77d94d6504caf2e3db6a267fef76b2a759fee0c7..6ae4e1b2dc16222c1ed9527dd36b783b187e86db 100644 --- a/src/geomtools/detector/crystfel_frm.py +++ b/src/geomtools/detector/crystfel_frm.py @@ -1,10 +1,9 @@ +import h5py import numpy as np import pandas as pd - from cfelpyutils.geometry import load_crystfel_geometry from natsort import natsorted - HEADER_TEMPLATE = """\ ; {detector} geometry file written by geomtools ; You may need to edit this file to add: @@ -39,7 +38,7 @@ def _format_vec(vec): ]) -def write_crystfel_geom(file, panels, beam, rigid_groups): +def write_crystfel_geom(file, panels, beam, rigid_groups, mask=None): """Writes geometry in CrystFEL format in file.""" # header clen = panels.clen[0] @@ -48,11 +47,19 @@ def write_crystfel_geom(file, panels, beam, rigid_groups): panels.data[0] if panels.data[0] else "/entry_1/data_1/data" ) - mask = panels['mask'][0] - if mask: - paths['mask'] = mask + if mask is None: + if 'mask' in panels.colums: + paths['mask'] = panels['mask'][0] + else: + paths['mask'] = "/entry_1/instrument_1/detector_1/mask" + if 'mask_file' in panels.columns: + paths['mask_file'] = panels.mask_file[0] else: - paths['mask'] = "/entry_1/instrument_1/detector_1/mask" + paths['mask'] = mask['path'] + paths['mask_file'] = mask['file'] + paths['mask_good'] = hex(mask['good']) + paths['mask_bad'] = hex(mask['bad']) + path_str = '\n'.join('{} = {} ;'.format(i, j) for i, j in paths.items()) header = HEADER_TEMPLATE.format( detector="AGIPD1M", resolution=1/200e-6, frame_dim=0, @@ -139,4 +146,22 @@ def read_crystfel_geom(filename, indexes=dict()): for column, dimno in indexes.items(): panels[column] = panels.dim_structure.apply(lambda x: x[dimno]) - return panels, geom.beam + if "mask_file" in panels.columns and panels.mask_file[0]: + mask_file = panels.mask_file[0] + else: + mask_file = None + if "mask" in panels.columns and panels['mask'][0]: + mask_path = panels['mask'][0] + else: + mask_path = "/entry_1/data_1/mask" + mask_goodbits = geom.detector.get('mask_good', 0) + mask_badbits = geom.detector.get('mask_bad', 0) + if mask_file: + with h5py.File(mask_file, "r") as f: + mask = f[mask_path][:] + mask = ( + (np.bitwise_and(mask, mask_goodbits) != mask_goodbits) | + (np.bitwise_and(mask, mask_badbits) != 0) + ) + + return panels, geom.beam, mask diff --git a/src/geomtools/sfx/optimiser.py b/src/geomtools/sfx/optimiser.py index 7802380f0cdb87a64f4aef8cb74c3e8e80ed3517..3bf6d2361662f50ba5c8ef22c2ce87606f1d82c8 100644 --- a/src/geomtools/sfx/optimiser.py +++ b/src/geomtools/sfx/optimiser.py @@ -32,7 +32,7 @@ def refine(): temp_geom_file.write(geom_file.read()) geom_file.seek(0) - panels, beam = read_crystfel_geom( + panels, beam, mask = read_crystfel_geom( temp_geom_file.name, indexes={'modno': 1}) temp_geom_file.close() @@ -45,15 +45,23 @@ def refine(): px = badpixels_mask(pe, panels) shape = get_detector_shape(panels) - msk = pixels_to_image(shape, px) + badpx = pixels_to_image(shape, px) geom_fn = args.output - with open(geom_fn.absolute(), "w") as f: - write_crystfel_geom(f, panels_new, beam, ["modules", "quads"]) + + mask_path = "/entry_1/data_1/mask" + mask_fn = geom_fn.parent / (geom_fn.stem + "_hotpixels.h5") + with h5py.File(mask_fn, "w") as f: + f[mask_path] = badpx.astype("u2") mask_fn = geom_fn.parent / (geom_fn.stem + "_mask.h5") with h5py.File(mask_fn, "w") as f: - f["/entry_1/data_1/mask"] = msk.astype("u2") + f[mask_path] = (mask | badpx).astype("u2") + + mask = dict(path=mask_path, file=mask_fn.resolve(), good=0, bad=0xffff) + + with open(geom_fn.absolute(), "w") as f: + write_crystfel_geom(f, panels_new, beam, ["modules", "quads"], mask) if __name__ == "__main__": diff --git a/src/geomtools/sfx/report.ipynb b/src/geomtools/sfx/report.ipynb index a266245165955dba25b1c2c9f13289fbac497f88..294804339c4fcc836a6309c2c96fe0b7e3cff4d5 100644 --- a/src/geomtools/sfx/report.ipynb +++ b/src/geomtools/sfx/report.ipynb @@ -52,7 +52,7 @@ "propno = int(xwiz_conf['data']['proposal'])\n", "runs = eval(xwiz_conf['data']['runs'])\n", "\n", - "panels, beam = read_crystfel_geom(geometry_file, indexes={'modno': 1})\n", + "panels, beam, mask = read_crystfel_geom(geometry_file, indexes={'modno': 1})\n", "\n", "panel_columns = panels.columns.tolist() + ['panel']\n", "if connected_groups not in panel_columns:\n",