The package rpms/python-mrcfile.git has added or updated architecture specific content in its spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s): https://src.fedoraproject.org/cgit/rpms/python-mrcfile.git/commit/?id=6b478d... https://src.fedoraproject.org/cgit/rpms/python-mrcfile.git/commit/?id=ef9da3....
Change: -%ifarch s390x +%ifarch s390x
Thanks.
Full change: ============
commit 6b478d1c17fc82ca5f24623555374b54a267ccb9 Author: Dominik 'Rathann' Mierzejewski dominik@greysector.net Date: Wed Apr 27 09:58:26 2022 +0200
backport upstream endiannes fixes
backport upstream numpy deprecation warning fix
diff --git a/0001-Switch-to-built-in-bool-type-to-avoid-numpy-deprecat.patch b/0001-Switch-to-built-in-bool-type-to-avoid-numpy-deprecat.patch new file mode 100644 index 0000000..e7b43bc --- /dev/null +++ b/0001-Switch-to-built-in-bool-type-to-avoid-numpy-deprecat.patch @@ -0,0 +1,26 @@ +From 085794f7ae78b5722d847baa5d76e4d4692e9ca2 Mon Sep 17 00:00:00 2001 +From: Colin Palmer colin.palmer@stfc.ac.uk +Date: Fri, 19 Feb 2021 11:07:12 +0000 +Subject: [PATCH] Switch to built-in bool type to avoid numpy deprecation + warning + +--- + tests/test_utils.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/test_utils.py b/tests/test_utils.py +index bbc4eb0..bab0c9e 100644 +--- a/tests/test_utils.py ++++ b/tests/test_utils.py +@@ -136,7 +136,7 @@ class UtilsTest(AssertRaisesRegexMixin, unittest.TestCase): + + def test_bool_dtype_raises_exception(self): + with self.assertRaises(ValueError): +- utils.mode_from_dtype(np.dtype(np.bool)) ++ utils.mode_from_dtype(np.dtype(bool)) + + def test_object_dtype_raises_exception(self): + with self.assertRaises(ValueError): +-- +2.36.0 + diff --git a/0001-Use-explicit-endianness-for-FEI-extended-header-dtyp.patch b/0001-Use-explicit-endianness-for-FEI-extended-header-dtyp.patch new file mode 100644 index 0000000..ba05ee9 --- /dev/null +++ b/0001-Use-explicit-endianness-for-FEI-extended-header-dtyp.patch @@ -0,0 +1,436 @@ +From b0d806dc163607508f71da69f1c34b98a07d7c6c Mon Sep 17 00:00:00 2001 +From: Colin Palmer colin.palmer@stfc.ac.uk +Date: Tue, 26 Apr 2022 16:35:02 +0100 +Subject: [PATCH 1/3] Use explicit endianness for FEI extended header dtypes + +This fixes https://github.com/ccpem/mrcfile/issues/35 + +The FEI documentation is unclear about endianness. It's quite likely +that no MRC files will ever exist that have big-endian data in the FEI +extended header so perhaps we could have just assumed little-endianness +in all cases, but nonetheless it felt safer to make the extended +header's endianness match the standard header (except for the bitmask +fields that are specified as little-endian and required a bit of +complexity to get right). +--- + mrcfile/dtypes.py | 224 +++++++++++++++++++++----------------- + mrcfile/mrcinterpreter.py | 19 ++-- + tests/test_dtypes.py | 100 +++++++++++++++++ + 3 files changed, 236 insertions(+), 107 deletions(-) + create mode 100644 tests/test_dtypes.py + +diff --git a/mrcfile/dtypes.py b/mrcfile/dtypes.py +index 5197a6c..8db93aa 100644 +--- a/mrcfile/dtypes.py ++++ b/mrcfile/dtypes.py +@@ -19,6 +19,8 @@ from __future__ import absolute_import, division, print_function + + import numpy as np + ++from .utils import normalise_byte_order ++ + + HEADER_DTYPE = np.dtype([ + ('nx', 'i4'), # Number of columns +@@ -95,130 +97,158 @@ NSTART_DTYPE = np.dtype([ + + # FEI extended header dtype for metadata version 0, as described in the EPU + # manual. Note that the FEI documentation is unclear about the endianness of +-# the data in the extended header. Probably, it is always little-endian, and +-# therefore the data might be misinterpreted on a big-endian machine, but this +-# has not been tested. ++# the data in the extended header, except for the bitmask fields which are ++# specified as little-endian. To construct mixed-endian dtypes, we initially ++# construct a big-endian type, with only the bitmasks little-endian, then we ++# swap all fields to little-endian if we need a fully little-endian type. + fei_dtype_dict = [ +- ('Metadata size', 'i4'), +- ('Metadata version', 'i4'), +- ('Bitmask 1', 'u4'), +- ('Timestamp', 'f8'), # Not specified, but suspect this is in days after 1/1/1900 ++ ('Metadata size', '>i4'), ++ ('Metadata version', '>i4'), ++ ('Bitmask 1', '<u4'), ++ ('Timestamp', '>f8'), # Not specified, but suspect this is in days after 1/1/1900 + ('Microscope type', 'S16'), + ('D-Number', 'S16'), + ('Application', 'S16'), + ('Application version', 'S16'), +- ('HT', 'f8'), +- ('Dose', 'f8'), +- ('Alpha tilt', 'f8'), +- ('Beta tilt', 'f8'), +- ('X-Stage', 'f8'), +- ('Y-Stage', 'f8'), +- ('Z-Stage', 'f8'), +- ('Tilt axis angle', 'f8'), +- ('Dual axis rotation', 'f8'), +- ('Pixel size X', 'f8'), +- ('Pixel size Y', 'f8'), ++ ('HT', '>f8'), ++ ('Dose', '>f8'), ++ ('Alpha tilt', '>f8'), ++ ('Beta tilt', '>f8'), ++ ('X-Stage', '>f8'), ++ ('Y-Stage', '>f8'), ++ ('Z-Stage', '>f8'), ++ ('Tilt axis angle', '>f8'), ++ ('Dual axis rotation', '>f8'), ++ ('Pixel size X', '>f8'), ++ ('Pixel size Y', '>f8'), + ('Unused range', 'S48'), +- ('Defocus', 'f8'), +- ('STEM Defocus', 'f8'), +- ('Applied defocus', 'f8'), +- ('Instrument mode', 'i4'), +- ('Projection mode', 'i4'), ++ ('Defocus', '>f8'), ++ ('STEM Defocus', '>f8'), ++ ('Applied defocus', '>f8'), ++ ('Instrument mode', '>i4'), ++ ('Projection mode', '>i4'), + ('Objective lens mode', 'S16'), + ('High magnification mode', 'S16'), +- ('Probe mode', 'i4'), ++ ('Probe mode', '>i4'), + ('EFTEM On', '?'), +- ('Magnification', 'f8'), +- ('Bitmask 2', 'u4'), +- ('Camera length', 'f8'), +- ('Spot index', 'i4'), +- ('Illuminated area', 'f8'), +- ('Intensity', 'f8'), +- ('Convergence angle', 'f8'), ++ ('Magnification', '>f8'), ++ ('Bitmask 2', '<u4'), ++ ('Camera length', '>f8'), ++ ('Spot index', '>i4'), ++ ('Illuminated area', '>f8'), ++ ('Intensity', '>f8'), ++ ('Convergence angle', '>f8'), + ('Illumination mode', 'S16'), + ('Wide convergence angle range', '?'), + ('Slit inserted', '?'), +- ('Slit width', 'f8'), +- ('Acceleration voltage offset', 'f8'), +- ('Drift tube voltage', 'f8'), +- ('Energy shift', 'f8'), +- ('Shift offset X', 'f8'), +- ('Shift offset Y', 'f8'), +- ('Shift X', 'f8'), +- ('Shift Y', 'f8'), +- ('Integration time', 'f8'), +- ('Binning Width', 'i4'), +- ('Binning Height', 'i4'), ++ ('Slit width', '>f8'), ++ ('Acceleration voltage offset', '>f8'), ++ ('Drift tube voltage', '>f8'), ++ ('Energy shift', '>f8'), ++ ('Shift offset X', '>f8'), ++ ('Shift offset Y', '>f8'), ++ ('Shift X', '>f8'), ++ ('Shift Y', '>f8'), ++ ('Integration time', '>f8'), ++ ('Binning Width', '>i4'), ++ ('Binning Height', '>i4'), + ('Camera name', 'S16'), +- ('Readout area left', 'i4'), +- ('Readout area top', 'i4'), +- ('Readout area right', 'i4'), +- ('Readout area bottom', 'i4'), ++ ('Readout area left', '>i4'), ++ ('Readout area top', '>i4'), ++ ('Readout area right', '>i4'), ++ ('Readout area bottom', '>i4'), + ('Ceta noise reduction', '?'), +- ('Ceta frames summed', 'i4'), ++ ('Ceta frames summed', '>i4'), + ('Direct detector electron counting', '?'), + ('Direct detector align frames', '?'), +- ('Camera param reserved 0', 'i4'), +- ('Camera param reserved 1', 'i4'), +- ('Camera param reserved 2', 'i4'), +- ('Camera param reserved 3', 'i4'), +- ('Bitmask 3', 'u4'), +- ('Camera param reserved 4', 'i4'), +- ('Camera param reserved 5', 'i4'), +- ('Camera param reserved 6', 'i4'), +- ('Camera param reserved 7', 'i4'), +- ('Camera param reserved 8', 'i4'), +- ('Camera param reserved 9', 'i4'), ++ ('Camera param reserved 0', '>i4'), ++ ('Camera param reserved 1', '>i4'), ++ ('Camera param reserved 2', '>i4'), ++ ('Camera param reserved 3', '>i4'), ++ ('Bitmask 3', '<u4'), ++ ('Camera param reserved 4', '>i4'), ++ ('Camera param reserved 5', '>i4'), ++ ('Camera param reserved 6', '>i4'), ++ ('Camera param reserved 7', '>i4'), ++ ('Camera param reserved 8', '>i4'), ++ ('Camera param reserved 9', '>i4'), + ('Phase Plate', '?'), + ('STEM Detector name', 'S16'), +- ('Gain', 'f8'), +- ('Offset', 'f8'), +- ('STEM param reserved 0', 'i4'), +- ('STEM param reserved 1', 'i4'), +- ('STEM param reserved 2', 'i4'), +- ('STEM param reserved 3', 'i4'), +- ('STEM param reserved 4', 'i4'), +- ('Dwell time', 'f8'), +- ('Frame time', 'f8'), +- ('Scan size left', 'i4'), +- ('Scan size top', 'i4'), +- ('Scan size right', 'i4'), +- ('Scan size bottom', 'i4'), +- ('Full scan FOV X', 'f8'), +- ('Full scan FOV Y', 'f8'), ++ ('Gain', '>f8'), ++ ('Offset', '>f8'), ++ ('STEM param reserved 0', '>i4'), ++ ('STEM param reserved 1', '>i4'), ++ ('STEM param reserved 2', '>i4'), ++ ('STEM param reserved 3', '>i4'), ++ ('STEM param reserved 4', '>i4'), ++ ('Dwell time', '>f8'), ++ ('Frame time', '>f8'), ++ ('Scan size left', '>i4'), ++ ('Scan size top', '>i4'), ++ ('Scan size right', '>i4'), ++ ('Scan size bottom', '>i4'), ++ ('Full scan FOV X', '>f8'), ++ ('Full scan FOV Y', '>f8'), + ('Element', 'S16'), +- ('Energy interval lower', 'f8'), +- ('Energy interval higher', 'f8'), +- ('Method', 'i4'), ++ ('Energy interval lower', '>f8'), ++ ('Energy interval higher', '>f8'), ++ ('Method', '>i4'), + ('Is dose fraction', '?'), +- ('Fraction number', 'i4'), +- ('Start frame', 'i4'), +- ('End frame', 'i4'), ++ ('Fraction number', '>i4'), ++ ('Start frame', '>i4'), ++ ('End frame', '>i4'), + ('Input stack filename', 'S80'), +- ('Bitmask 4', 'u4'), +- ('Alpha tilt min', 'f8'), +- ('Alpha tilt max', 'f8') ++ ('Bitmask 4', '<u4'), ++ ('Alpha tilt min', '>f8'), ++ ('Alpha tilt max', '>f8') + ] +-FEI1_EXTENDED_HEADER_DTYPE = np.dtype(fei_dtype_dict) ++fei1_dtype_big_endian = np.dtype(fei_dtype_dict) + + + # Additional metadata entries for FEI extended header dtype for metadata version 2, + # as described in https://www.fei-software-center.com/tem-apps/MRC-2014-Specifications/ + fei_dtype_dict.extend([ +- ('Scan rotation', 'f8'), +- ('Diffraction pattern rotation', 'f8'), +- ('Image rotation', 'f8'), +- ('Scan mode enumeration', 'i4'), +- ('Acquisition time stamp', 'i8'), ++ ('Scan rotation', '>f8'), ++ ('Diffraction pattern rotation', '>f8'), ++ ('Image rotation', '>f8'), ++ ('Scan mode enumeration', '>i4'), ++ ('Acquisition time stamp', '>i8'), + ('Detector commercial name', 'S16'), +- ('Start tilt angle', 'f8'), +- ('End tilt angle', 'f8'), +- ('Tilt per image', 'f8'), +- ('Tilt speed', 'f8'), +- ('Beam center X pixel', 'i4'), +- ('Beam center Y pixel', 'i4'), +- ('CFEG flash timestamp', 'i8'), +- ('Phase plate position index', 'i4'), ++ ('Start tilt angle', '>f8'), ++ ('End tilt angle', '>f8'), ++ ('Tilt per image', '>f8'), ++ ('Tilt speed', '>f8'), ++ ('Beam center X pixel', '>i4'), ++ ('Beam center Y pixel', '>i4'), ++ ('CFEG flash timestamp', '>i8'), ++ ('Phase plate position index', '>i4'), + ('Objective aperture name', 'S16') + ]) +-FEI2_EXTENDED_HEADER_DTYPE = np.dtype(fei_dtype_dict) ++fei2_dtype_big_endian = np.dtype(fei_dtype_dict) ++ ++ ++def get_ext_header_dtype(exttyp, byte_order='='): ++ """Get a dtype for an extended header. ++ ++ Args: ++ exttyp: One of ``b'FEI1'`` or ``b'FEI2'``, which are currently the only ++ supported extended header types. ++ byte_order: One of ``=``, ``<`` or ``>``. ++ ++ Returns: ++ A :class:`numpy dtype <numpy.dtype>` object for the extended header, or ++ :data:`None` ++ ++ Raises: ++ :exc:`ValueError`: If ``byte_order`` is not one of ``=``, ``<`` or ``>``. ++ """ ++ normalised_byte_order = normalise_byte_order(byte_order) ++ dtype = None ++ if exttyp == b'FEI1': ++ dtype = fei1_dtype_big_endian ++ elif exttyp == b'FEI2': ++ dtype = fei2_dtype_big_endian ++ # If returning a little-endian FEI1 or FEI2 dtype, need to swap the byte order ++ if dtype is not None and normalised_byte_order == '<': ++ dtype = dtype.newbyteorder('<') ++ return dtype +diff --git a/mrcfile/mrcinterpreter.py b/mrcfile/mrcinterpreter.py +index 0dab80d..8388da1 100644 +--- a/mrcfile/mrcinterpreter.py ++++ b/mrcfile/mrcinterpreter.py +@@ -21,7 +21,7 @@ import warnings + import numpy as np + + from . import utils +-from .dtypes import HEADER_DTYPE, FEI1_EXTENDED_HEADER_DTYPE, FEI2_EXTENDED_HEADER_DTYPE ++from .dtypes import HEADER_DTYPE, get_ext_header_dtype + from .mrcobject import MrcObject + from .constants import MAP_ID + +@@ -284,15 +284,14 @@ class MrcInterpreter(MrcObject): + + self._extended_header = np.frombuffer(ext_header_arr, dtype='V1') + +- try: +- if self.header.exttyp == b'FEI1': +- self._extended_header.dtype = FEI1_EXTENDED_HEADER_DTYPE +- elif self.header.exttyp == b'FEI2': +- self._extended_header.dtype = FEI2_EXTENDED_HEADER_DTYPE +- except ValueError: +- warnings.warn("File has exttyp '{}' but the extended header " +- "cannot be interpreted as that type" +- .format(self.header.exttyp), RuntimeWarning) ++ dtype = get_ext_header_dtype(self.header.exttyp) ++ if dtype is not None: ++ try: ++ self._extended_header.dtype = dtype ++ except ValueError: ++ warnings.warn("File has exttyp '{}' but the extended header " ++ "cannot be interpreted as that type" ++ .format(self.header.exttyp), RuntimeWarning) + + self._extended_header.flags.writeable = not self._read_only + +diff --git a/tests/test_dtypes.py b/tests/test_dtypes.py +new file mode 100644 +index 0000000..7b7988f +--- /dev/null ++++ b/tests/test_dtypes.py +@@ -0,0 +1,100 @@ ++# Copyright (c) 2022, Science and Technology Facilities Council ++# This software is distributed under a BSD licence. See LICENSE.txt. ++ ++""" ++Tests for dtypes.py ++""" ++ ++# Import Python 3 features for future-proofing ++# Deliberately do NOT import unicode_literals due to a bug in numpy dtypes: ++# https://github.com/numpy/numpy/issues/2407 ++from __future__ import absolute_import, division, print_function ++ ++import unittest ++ ++import mrcfile.dtypes as dtypes ++import mrcfile.utils as utils ++from .helpers import AssertRaisesRegexMixin ++ ++ ++class DtypesTest(AssertRaisesRegexMixin, unittest.TestCase): ++ ++ """Unit tests for mrcfile.dtypes""" ++ ++ def test_invalid_byte_order_raises_exception(self): ++ with self.assertRaisesRegex(ValueError, "Unrecognised byte order indicator"): ++ _ = dtypes.get_ext_header_dtype('', 'a') ++ ++ def test_fei1_ext_header_with_native_byte_order(self): ++ dtype = dtypes.get_ext_header_dtype(b'FEI1') ++ assert dtype.itemsize == 768 ++ assert utils.byte_orders_equal(dtype['Metadata size'].byteorder, '=') ++ with self.assertRaises(KeyError): ++ _ = dtype['Scan rotation'] ++ # Bitmasks should always be little-endian ++ assert utils.byte_orders_equal(dtype['Bitmask 1'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 2'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 3'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 4'].byteorder, '<') ++ ++ def test_fei2_ext_header_with_native_byte_order(self): ++ dtype = dtypes.get_ext_header_dtype(b'FEI2') ++ assert dtype.itemsize == 888 ++ assert utils.byte_orders_equal(dtype['Metadata size'].byteorder, '=') ++ assert dtype['Scan rotation'] is not None ++ assert utils.byte_orders_equal(dtype['Scan rotation'].byteorder, '=') ++ # Bitmasks should always be little-endian ++ assert utils.byte_orders_equal(dtype['Bitmask 1'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 2'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 3'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 4'].byteorder, '<') ++ ++ def test_fei1_ext_header_with_little_endian_byte_order(self): ++ dtype = dtypes.get_ext_header_dtype(b'FEI1', '<') ++ # Normal fields should match the requested byte order ++ assert utils.byte_orders_equal(dtype['Metadata size'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Alpha tilt'].byteorder, '<') ++ # Bitmasks should always be little-endian ++ assert utils.byte_orders_equal(dtype['Bitmask 1'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 2'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 3'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 4'].byteorder, '<') ++ ++ def test_fei2_ext_header_with_little_endian_byte_order(self): ++ dtype = dtypes.get_ext_header_dtype(b'FEI2', '<') ++ # Normal fields should match the requested byte order ++ assert utils.byte_orders_equal(dtype['Metadata size'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Alpha tilt'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Scan rotation'].byteorder, '<') ++ # Bitmasks should always be little-endian ++ assert utils.byte_orders_equal(dtype['Bitmask 1'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 2'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 3'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 4'].byteorder, '<') ++ ++ def test_fei1_ext_header_with_big_endian_byte_order(self): ++ dtype = dtypes.get_ext_header_dtype(b'FEI1', '>') ++ # Normal fields should match the requested byte order ++ assert utils.byte_orders_equal(dtype['Metadata size'].byteorder, '>') ++ assert utils.byte_orders_equal(dtype['Alpha tilt'].byteorder, '>') ++ # Bitmasks should always be little-endian ++ assert utils.byte_orders_equal(dtype['Bitmask 1'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 2'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 3'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 4'].byteorder, '<') ++ ++ def test_fei2_ext_header_with_big_endian_byte_order(self): ++ dtype = dtypes.get_ext_header_dtype(b'FEI2', '>') ++ # Normal fields should match the requested byte order ++ assert utils.byte_orders_equal(dtype['Metadata size'].byteorder, '>') ++ assert utils.byte_orders_equal(dtype['Alpha tilt'].byteorder, '>') ++ assert utils.byte_orders_equal(dtype['Scan rotation'].byteorder, '>') ++ # Bitmasks should always be little-endian ++ assert utils.byte_orders_equal(dtype['Bitmask 1'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 2'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 3'].byteorder, '<') ++ assert utils.byte_orders_equal(dtype['Bitmask 4'].byteorder, '<') ++ ++ ++if __name__ == '__main__': ++ unittest.main() +-- +2.36.0 + diff --git a/0002-Finish-applying-extended-header-byte-order-fix.patch b/0002-Finish-applying-extended-header-byte-order-fix.patch new file mode 100644 index 0000000..7e6d87b --- /dev/null +++ b/0002-Finish-applying-extended-header-byte-order-fix.patch @@ -0,0 +1,28 @@ +From f6a1f460558822b0029f1e74d94755d7816ff243 Mon Sep 17 00:00:00 2001 +From: Colin Palmer colin.palmer@stfc.ac.uk +Date: Tue, 26 Apr 2022 16:58:55 +0100 +Subject: [PATCH 2/3] Finish applying extended header byte order fix + +https://github.com/ccpem/mrcfile/issues/35 +--- + mrcfile/mrcinterpreter.py | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/mrcfile/mrcinterpreter.py b/mrcfile/mrcinterpreter.py +index 8388da1..ad3132f 100644 +--- a/mrcfile/mrcinterpreter.py ++++ b/mrcfile/mrcinterpreter.py +@@ -284,7 +284,9 @@ class MrcInterpreter(MrcObject): + + self._extended_header = np.frombuffer(ext_header_arr, dtype='V1') + +- dtype = get_ext_header_dtype(self.header.exttyp) ++ # Use the header's byte order for the extended header ++ dtype = get_ext_header_dtype(self.header.exttyp, ++ self.header.mode.dtype.byteorder) + if dtype is not None: + try: + self._extended_header.dtype = dtype +-- +2.36.0 + diff --git a/0003-Check-that-test-file-extended-header-is-always-littl.patch b/0003-Check-that-test-file-extended-header-is-always-littl.patch new file mode 100644 index 0000000..9adbe98 --- /dev/null +++ b/0003-Check-that-test-file-extended-header-is-always-littl.patch @@ -0,0 +1,45 @@ +From 6f697a2cbd3d4d07c4f5a90029c6a994d07dc6b9 Mon Sep 17 00:00:00 2001 +From: Colin Palmer colin.palmer@stfc.ac.uk +Date: Tue, 26 Apr 2022 17:08:59 +0100 +Subject: [PATCH 3/3] Check that test file extended header is always + little-endian + +Previously, these tests passed on little-endian hardware but failed +on big-endian hardware. + +https://github.com/ccpem/mrcfile/issues/35 +--- + tests/test_mrcfile.py | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/tests/test_mrcfile.py b/tests/test_mrcfile.py +index 9f6eab7..2b7e7b7 100644 +--- a/tests/test_mrcfile.py ++++ b/tests/test_mrcfile.py +@@ -172,7 +172,10 @@ class MrcFileTest(MrcObjectTest): + ext = mrc.extended_header + assert ext.nbytes == 786432 + assert ext.dtype.kind == 'V' +- assert ext.dtype['Metadata size'] == np.dtype('|i') ++ # Most fields (e.g. Metadata size) are little-endian in this file ++ assert ext.dtype['Metadata size'] == np.dtype('<i4') ++ # Bitmasks should always be little-endian ++ assert ext.dtype['Bitmask 1'] == np.dtype('<u4') + assert ext.dtype['Microscope type'] == np.dtype('|S16') + assert ext[0]['Metadata size'] == 768 + assert ext[0]['Metadata version'] == 0 +@@ -188,7 +191,10 @@ class MrcFileTest(MrcObjectTest): + ext = mrc.extended_header + assert ext.nbytes == 909312 + assert ext.dtype.kind == 'V' +- assert ext.dtype['Metadata size'] == np.dtype('|i') ++ # Most fields (e.g. Metadata size) are little-endian in this file ++ assert ext.dtype['Metadata size'] == np.dtype('<i4') ++ # Bitmasks should always be little-endian ++ assert ext.dtype['Bitmask 1'] == np.dtype('<u4') + assert ext.dtype['Microscope type'] == np.dtype('|S16') + assert ext[0]['Metadata size'] == 888 + assert ext[0]['Metadata version'] == 2 +-- +2.36.0 + diff --git a/python-mrcfile.spec b/python-mrcfile.spec index db43612..b6eed77 100644 --- a/python-mrcfile.spec +++ b/python-mrcfile.spec @@ -19,11 +19,15 @@ larger software packages to provide basic MRC file I/O functions.
Name: python-%{pname} Version: 1.3.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: MRC2014 file format used in structural biology to store image and volume data License: BSD URL: https://github.com/ccpem/mrcfile Source0: https://github.com/ccpem/mrcfile/archive/v%%7Bversion%7D/%%7Bpname%7D-%%7Bve... +Patch0: 0001-Use-explicit-endianness-for-FEI-extended-header-dtyp.patch +Patch1: 0002-Finish-applying-extended-header-byte-order-fix.patch +Patch2: 0003-Check-that-test-file-extended-header-is-always-littl.patch +Patch3: 0001-Switch-to-built-in-bool-type-to-avoid-numpy-deprecat.patch
%description %{desc} @@ -56,12 +60,7 @@ BuildArch: noarch PYTHONDONTWRITEBYTECODE=1 \ PATH=%{buildroot}/usr/bin:${PATH} \ PYTHONPATH=%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib} \ -python3 -m unittest tests \ -%ifarch s390x - -k 'not test_extended_header_from_FEI1_file \ - and not test_extended_header_from_FEI2_file' -%endif - +python3 -m unittest tests %endif
%files -n python3-%{pname} @@ -73,5 +72,9 @@ python3 -m unittest tests \ %{python3_sitelib}/%{pname}
%changelog +* Wed Apr 27 2022 Dominik Mierzejewski dominik@greysector.net - 1.3.0-2 +- backport upstream endiannes fixes +- backport upstream numpy deprecation warning fix + * Fri Mar 11 2022 Dominik Mierzejewski dominik@greysector.net 1.3.0-1 - initial build
commit ef9da3825d41d23f179d2803f69cccca6e49d328 Author: Dominik 'Rathann' Mierzejewski dominik@greysector.net Date: Tue Apr 26 09:53:13 2022 +0200
initial import (#2063369)
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9dff4b6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/mrcfile-1.3.0.tar.gz diff --git a/python-mrcfile.spec b/python-mrcfile.spec new file mode 100644 index 0000000..db43612 --- /dev/null +++ b/python-mrcfile.spec @@ -0,0 +1,77 @@ +# main package is archful to run tests everywhere but produces noarch packages +%global debug_package %{nil} +%bcond_without check +%global pname mrcfile + +%global desc \ +mrcfile is a Python implementation of the MRC2014 file format, which is used in\ +structural biology to store image and volume data.\ +\ +It allows MRC files to be created and opened easily using a very simple API,\ +which exposes the file's header and data as numpy arrays. The code runs in\ +Python 2 and 3 and is fully unit-tested.\ +\ +This library aims to allow users and developers to read and write\ +standard-compliant MRC files in Python as easily as possible, and with no\ +dependencies on any compiled libraries except numpy. You can use it\ +interactively to inspect files, correct headers and so on, or in scripts and\ +larger software packages to provide basic MRC file I/O functions. + +Name: python-%{pname} +Version: 1.3.0 +Release: 1%{?dist} +Summary: MRC2014 file format used in structural biology to store image and volume data +License: BSD +URL: https://github.com/ccpem/mrcfile +Source0: https://github.com/ccpem/mrcfile/archive/v%%7Bversion%7D/%%7Bpname%7D-%%7Bve... + +%description +%{desc} + +%package -n python3-%{pname} +Summary: %{summary} +BuildRequires: python3-devel +BuildRequires: python3-setuptools +%if %{with check} +BuildRequires: python3-numpy +%endif +%{?python_provide:%python_provide python3-%{pname}} +BuildArch: noarch + +%description -n python3-%{pname} +%{desc} + +%prep +%autosetup -p1 -n %{pname}-%{version} + +%build +%py3_build + +%install +%py3_install + +%if %{with check} +%check +# 8 tests are failing on s390x: https://github.com/ccpem/mrcfile/issues/35 +PYTHONDONTWRITEBYTECODE=1 \ +PATH=%{buildroot}/usr/bin:${PATH} \ +PYTHONPATH=%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib} \ +python3 -m unittest tests \ +%ifarch s390x + -k 'not test_extended_header_from_FEI1_file \ + and not test_extended_header_from_FEI2_file' +%endif + +%endif + +%files -n python3-%{pname} +%license LICENSE.txt +%doc CHANGELOG.txt README.rst +%{_bindir}/mrcfile-header +%{_bindir}/mrcfile-validate +%{python3_sitelib}/%{pname}-%{version}-py%{python3_version}.egg-info +%{python3_sitelib}/%{pname} + +%changelog +* Fri Mar 11 2022 Dominik Mierzejewski dominik@greysector.net 1.3.0-1 +- initial build diff --git a/sources b/sources new file mode 100644 index 0000000..11f88fb --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (mrcfile-1.3.0.tar.gz) = 57fff6e7c71b41681c94c60fbb69d0712ec7e342329624d8c20e212560eaa0f2b573d02ec5fcce39b9b7077e66d9bab463afc227d6b1f24134eddb17e56fdff1