diff --git a/.github/workflows/code.yml b/.github/workflows/code.yml index 6fc888c7..09d4ba18 100644 --- a/.github/workflows/code.yml +++ b/.github/workflows/code.yml @@ -46,7 +46,7 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest"] # can add windows-latest, macos-latest - python: ["3.12"] + python: ["3.12", "3.13"] install: ["-e .[dev]"] # Make one version be non-editable to test both paths of version code include: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 67908e98..ff8fdb99 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,22 +1,21 @@ repos: -# Automatic source code formatting -- repo: https://github.com/psf/black - rev: 24.1.1 - hooks: - - id: black - args: [--safe, --quiet] - - # Linter - repo: local hooks: - id: ruff - name: Run ruff - stages: [pre-commit] + name: lint with ruff + language: system + entry: ruff check --force-exclude --fix + types: [python] + require_serial: true + + - id: ruff-format + name: format with ruff language: system - entry: ruff check + entry: ruff format --force-exclude types: [python] + require_serial: true # Other syntax checks diff --git a/pyproject.toml b/pyproject.toml index 07c3236f..19d533ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ classifiers = [ "Natural Language :: English", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] keywords = ["nexus", "NXmx"] dependencies = [ diff --git a/src/nexgen/command_line/ED_mrc_to_nexus.py b/src/nexgen/command_line/ED_mrc_to_nexus.py index e65e14e6..bd7f621c 100644 --- a/src/nexgen/command_line/ED_mrc_to_nexus.py +++ b/src/nexgen/command_line/ED_mrc_to_nexus.py @@ -344,7 +344,6 @@ def overwrite_from_command_line( def log_dict(logger: Logger, dictionary: dict, skip: list = None) -> None: - if skip is None: skip = [1] @@ -366,7 +365,6 @@ def log_dict(logger: Logger, dictionary: dict, skip: list = None) -> None: def main(): - args = parse_input_arguments() metadata_template = Metadata(args.input_files) logger.info("Starting MRC to Nexus conversion.") @@ -478,7 +476,6 @@ def main(): def parse_input_arguments(): - msg = "Convert electron diffraction data from an MRC format " msg += "to a NeXus format" parser = ArgumentParser(description=msg, add_help=True) diff --git a/src/nexgen/command_line/ED_nexus.py b/src/nexgen/command_line/ED_nexus.py index ba270535..7e7504e5 100644 --- a/src/nexgen/command_line/ED_nexus.py +++ b/src/nexgen/command_line/ED_nexus.py @@ -25,7 +25,6 @@ def write_from_SINGLA(args): - singla_nexus_writer( args.master_file, args.det_distance, @@ -60,7 +59,7 @@ def write_from_SINGLA_from_config(args): ) ED_coord_system["convention"] = params.coord_system.convention else: - logger.info("The following convention will be applied:\n" f"{ED_coord_system}") + logger.info(f"The following convention will be applied:\n{ED_coord_system}") if params.coord_system.origin: logger.info( diff --git a/src/nexgen/command_line/I19_2_cli.py b/src/nexgen/command_line/I19_2_cli.py index 30f2e7be..f0eb1266 100644 --- a/src/nexgen/command_line/I19_2_cli.py +++ b/src/nexgen/command_line/I19_2_cli.py @@ -307,7 +307,7 @@ def nexgen_writer(args): help="Data entry key of dataset in raw .h5 file. Defaults to data.", ) parser_nex.add_argument( - "-bits" "--bit-depth", + "-bits--bit-depth", type=int, choices=[8, 16, 32], default=32, diff --git a/src/nexgen/command_line/nexus_generator.py b/src/nexgen/command_line/nexus_generator.py index c2ce24c5..41bc725f 100644 --- a/src/nexgen/command_line/nexus_generator.py +++ b/src/nexgen/command_line/nexus_generator.py @@ -393,7 +393,8 @@ def _parse_cli() -> argparse.ArgumentParser: help="Data entry key of dataset in raw .h5 file. Defaults to data.", ) nxmx_parser.add_argument( - "-bits" "--bit-depth", + "-bits", + "--bit-depth", type=int, choices=[8, 16, 32], default=32, diff --git a/src/nexgen/nxs_copy/copy_nexus.py b/src/nexgen/nxs_copy/copy_nexus.py index c4eb61e8..79f9f024 100644 --- a/src/nexgen/nxs_copy/copy_nexus.py +++ b/src/nexgen/nxs_copy/copy_nexus.py @@ -41,7 +41,10 @@ def images_nexus( original_nexus = Path(original_nexus).expanduser().resolve() nxs_filename = get_nexus_filename(data_file[0], copy=True) copy_logger.debug(f"New NeXus file name: {nxs_filename}") - with h5py.File(original_nexus, "r") as nxs_in, h5py.File(nxs_filename, "x") as nxs_out: + with ( + h5py.File(original_nexus, "r") as nxs_in, + h5py.File(nxs_filename, "x") as nxs_out, + ): if simple_copy is True: # Copy the whole tree get_nexus_tree(nxs_in, nxs_out, skip=False) @@ -92,9 +95,10 @@ def pseudo_events_nexus( original_nexus = Path(original_nexus).expanduser().resolve() nxs_filename = get_nexus_filename(data_file[0], copy=True) copy_logger.debug(f"New NeXus file name: {nxs_filename}") - with h5py.File(original_nexus, "r") as nxs_in, h5py.File( - nxs_filename, "x" - ) as nxs_out: + with ( + h5py.File(original_nexus, "r") as nxs_in, + h5py.File(nxs_filename, "x") as nxs_out, + ): nxs_out.attrs["default"] = "entry" # Copy the whole tree except for nxdata nxentry = get_nexus_tree(nxs_in, nxs_out) diff --git a/src/nexgen/nxs_utils/__init__.py b/src/nexgen/nxs_utils/__init__.py index e21ef085..fec761f6 100644 --- a/src/nexgen/nxs_utils/__init__.py +++ b/src/nexgen/nxs_utils/__init__.py @@ -34,5 +34,5 @@ "TransformationType", "Facility", "CetaDetector", - "TVIPSDetector" + "TVIPSDetector", ] diff --git a/src/nexgen/nxs_write/write_utils.py b/src/nexgen/nxs_write/write_utils.py index 56a1d833..3ac1047d 100644 --- a/src/nexgen/nxs_write/write_utils.py +++ b/src/nexgen/nxs_write/write_utils.py @@ -239,8 +239,7 @@ def mask_and_flatfield_writer_for_event_data( ) else: NXclassUtils_logger.warning( - f"No {dset_name} file found in working directory." - "Writing an ExternalLink." + f"No {dset_name} file found in working directory.Writing an ExternalLink." ) file_loc = Path(dset_data_file) image_key = "image" if "tristan" in detector_name.lower() else "/" diff --git a/src/nexgen/tools/data_writer.py b/src/nexgen/tools/data_writer.py index 8ccd7ce9..99f33f8e 100644 --- a/src/nexgen/tools/data_writer.py +++ b/src/nexgen/tools/data_writer.py @@ -57,14 +57,14 @@ def build_an_eiger( for i in range(1, n_modules[0] + 1): IM[ :, - i * eiger_mod_size[1] - + (i - 1) * eiger_gap_size[1] : i * (eiger_mod_size[1] + eiger_gap_size[1]), + i * eiger_mod_size[1] + (i - 1) * eiger_gap_size[1] : i + * (eiger_mod_size[1] + eiger_gap_size[1]), ] = 65535 # Vertical modules for j in range(1, n_modules[1] + 1): IM[ - j * eiger_mod_size[0] - + (j - 1) * eiger_gap_size[0] : j * (eiger_mod_size[0] + eiger_gap_size[0]), + j * eiger_mod_size[0] + (j - 1) * eiger_gap_size[0] : j + * (eiger_mod_size[0] + eiger_gap_size[0]), :, ] = 65535 @@ -104,17 +104,13 @@ def build_a_tristan( for i in range(1, n_modules[0] + 1): IM[ :, - i * tristan_mod_size[1] - + (i - 1) - * tristan_gap_size[1] : i + i * tristan_mod_size[1] + (i - 1) * tristan_gap_size[1] : i * (tristan_mod_size[1] + tristan_gap_size[1]), ] = 65535 # Vertical modules for j in range(1, n_modules[1] + 1): IM[ - j * tristan_mod_size[0] - + (j - 1) - * tristan_gap_size[0] : j + j * tristan_mod_size[0] + (j - 1) * tristan_gap_size[0] : j * (tristan_mod_size[0] + tristan_gap_size[0]), :, ] = 65535 @@ -268,7 +264,7 @@ def generate_event_files( ) EV_dict[(i, j)] = pseudo_event_list(I, J, exp_time) t1 = time.process_time() - data_logger.info(f"Time taken to generate pseudo-event list: {t1-t0:.2f} s.") + data_logger.info(f"Time taken to generate pseudo-event list: {t1 - t0:.2f} s.") # Find total number of events to be written to file num_events = tristan_chunk * num_chunks diff --git a/src/nexgen/tools/mrc_tools.py b/src/nexgen/tools/mrc_tools.py index dbe09988..5aed4fcc 100644 --- a/src/nexgen/tools/mrc_tools.py +++ b/src/nexgen/tools/mrc_tools.py @@ -1,4 +1,4 @@ -""" Helper functions for the MRC to Nexus converter """ +"""Helper functions for the MRC to Nexus converter""" import logging import os @@ -198,9 +198,7 @@ def to_hdf5_data_file( # Input is a single MRC file with a stack of images if (len(data_shape) == 3) and (n == 1): - with h5py.File(out_file, "w") as hdf5_file: - mrc = mrcfile.open(files[0], mode="r") bs = hdf5plugin.Bitshuffle @@ -234,7 +232,6 @@ def to_hdf5_data_file( # Input is a list of MRC files containing single images elif (len(data_shape) == 2) and (n >= 1): - with h5py.File(out_file, "w") as hdf5_file: dataset_shape = (n, data_shape[0], data_shape[1]) dataset = hdf5_file.create_dataset( diff --git a/tests/tools/test_mrc_tools.py b/tests/tools/test_mrc_tools.py index b6ee8db5..1da748f2 100644 --- a/tests/tools/test_mrc_tools.py +++ b/tests/tools/test_mrc_tools.py @@ -10,14 +10,12 @@ def test_cal_wavelength(): - a = 0.025082356047905176 epsilon = 1.0e-15 assert abs(cal_wavelength(200000) - a) < epsilon def test_get_metadata(): - make_mrc_file("images.mrc") h = get_metadata("images.mrc") assert isinstance(h, dict) @@ -26,7 +24,6 @@ def test_get_metadata(): def test_collect_data(): - make_mrc_file("images_00001.mrc") make_mrc_file("images_00002.mrc") @@ -41,7 +38,6 @@ def test_collect_data(): def make_mrc_file(filename): - images = np.zeros((1, 1), dtype=np.int16) with mrcfile.new(filename, overwrite=True) as mrc: