From b5b484e117476432150ee6711ae0c12885e8da07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Sat, 9 Nov 2024 21:00:35 +0100 Subject: [PATCH 01/10] Update changelog and bump version to 0.12.dev0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- CHANGELOG.rst | 18 ++++++++++++++++++ src/kikuchipy/__init__.py | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3ab67997..73e76d42 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,24 @@ its best to adhere to `Semantic Versioning List entries are sorted in descending chronological order. Contributors to each release were listed in alphabetical order by first name until version 0.7.0. +Unreleased +========== + +Added +----- + +Changed +------- + +Removed +------- + +Deprecated +---------- + +Fixed +----- + 0.11.0 (2024-11-10) =================== diff --git a/src/kikuchipy/__init__.py b/src/kikuchipy/__init__.py index 17dc399b..ef1444fa 100644 --- a/src/kikuchipy/__init__.py +++ b/src/kikuchipy/__init__.py @@ -30,7 +30,7 @@ "Carter Francis", "Magnus Nord", ] -__version__ = "0.11.0" +__version__ = "0.12.dev0" __getattr__, __dir__, __all__ = lazy_loader.attach_stub(__name__, __file__) From 5c0a4e715cb5783727ff4193fccff60d7fd17446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Sun, 17 Nov 2024 10:56:27 +0100 Subject: [PATCH 02/10] Resolve path to datasets for testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conftest.py b/conftest.py index 38b5fc36..b84d44e3 100644 --- a/conftest.py +++ b/conftest.py @@ -51,6 +51,7 @@ DATA_PATH = Path(__file__).parent / "src/kikuchipy/data" +DATA_PATH = DATA_PATH.resolve() # ------------------------------ Setup ------------------------------ # From 0fb2098c42de1b7c93425d56c785cb8ba074bb6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Tue, 19 Nov 2024 22:05:11 +0100 Subject: [PATCH 03/10] Update pattern header in Oxford binary reader for *.ebsp > v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- .../io/plugins/oxford_binary/_api.py | 103 ++++++++++-------- 1 file changed, 58 insertions(+), 45 deletions(-) diff --git a/src/kikuchipy/io/plugins/oxford_binary/_api.py b/src/kikuchipy/io/plugins/oxford_binary/_api.py index c1773f74..d4aa47d1 100644 --- a/src/kikuchipy/io/plugins/oxford_binary/_api.py +++ b/src/kikuchipy/io/plugins/oxford_binary/_api.py @@ -88,15 +88,6 @@ class OxfordBinaryFileReader: patterns. """ - # Header for each pattern in the file - pattern_header_size: int = 16 - pattern_header_dtype: list = [ - ("is_compressed", np.int32, (1,)), - ("nrows", np.int32, (1,)), - ("ncols", np.int32, (1,)), - ("n_bytes", np.int32, (1,)), - ] - def __init__(self, file: BinaryIO) -> None: """Prepare to read EBSD patterns from an open Oxford Instruments' binary .ebsp file. @@ -106,12 +97,14 @@ def __init__(self, file: BinaryIO) -> None: self.version = self.get_version() _logger.debug(f"Reading Oxford binary file of version {self.version}") + self.pattern_header_size = self.get_pattern_header_size() + # If version > 3, read in the extra byte after file version and # add it to the debug log if self.version > 3: # pragma: no cover self.file.seek(self.pattern_starts_byte_position - 1) unknown_byte = np.fromfile(self.file, dtype=np.uint8, count=1)[0] - _logger.debug(f"Unknown byte (uint8) in file of version 4: {unknown_byte}") + _logger.debug(f"Unknown byte (uint8) in file of version>3: {unknown_byte}") # Number of patterns in the file is not known, so this is # guessed from the file header where the file byte positions of @@ -121,16 +114,14 @@ def __init__(self, file: BinaryIO) -> None: # Determine whether we can read the file, signal shape, and data # type - is_compressed, nrows, ncols, n_bytes = self.get_single_pattern_header( - self.first_pattern_position - ) - if is_compressed: + header = self.get_single_pattern_header(self.first_pattern_position) + if header["is_compressed"][0]: raise NotImplementedError( - f"Cannot read compressed EBSD patterns from {self.file.name}" + f"Cannot read compressed EBSD patterns from {self.file.name!r}" ) - self.signal_shape = (nrows, ncols) - self.n_bytes = n_bytes - if n_bytes == np.prod(self.signal_shape): + self.signal_shape = (header["nrows"][0], header["ncols"][0]) + self.n_bytes = header["n_bytes"][0] + if self.n_bytes == np.prod(self.signal_shape): self.dtype = np.uint8 else: self.dtype = np.uint16 @@ -138,9 +129,9 @@ def __init__(self, file: BinaryIO) -> None: # While the pattern header is always in the same format across # .ebsp file versions, this is not the case for the pattern # footer. Here we determine it's format. - self.pattern_footer_dtype = self.get_pattern_footer_dtype( - self.first_pattern_position - ) + pos = self.first_pattern_position + _logger.debug(f"First pattern byte position: {pos}") + self.pattern_footer_dtype = self.get_pattern_footer_dtype(pos) # Allow for reading of files where only non-indexed patterns are # stored in the file @@ -158,6 +149,8 @@ def __init__(self, file: BinaryIO) -> None: self.memmap = self.get_memmap() + # -------------------------- Properties -------------------------- # + @property def all_patterns_present(self) -> bool: """Whether all or only non-indexed patterns are stored in the @@ -213,6 +206,30 @@ def pattern_starts_byte_position(self) -> int: else: return 8 + @property + def pattern_header_dtype(self) -> list[tuple[str, type, tuple[int]]]: + dtypes = [ + ("map_x", np.int32, (1,)), + ("map_y", np.int32, (1,)), + ("is_compressed", np.int32, (1,)), + ("nrows", np.int32, (1,)), + ("ncols", np.int32, (1,)), + ("n_bytes", np.int32, (1,)), + ] + if self.version < 5: + # Remove map_x and map_y + _ = dtypes.pop(0) + _ = dtypes.pop(0) + return dtypes + + # --------------------------- Methods ---------------------------- # + + def get_pattern_header_size(self): + size = 0 + for _, dtype, _ in self.pattern_header_dtype: + size += np.dtype(dtype).itemsize + return size + def get_memmap(self) -> np.memmap: """Return a memory map of the pattern header, actual patterns, and a potential pattern footer. @@ -221,11 +238,13 @@ def get_memmap(self) -> np.memmap: patterns have the correct signal shape (n rows, n columns). If the pattern footer is available, the memory map has these - fields: + fields (some are new in version 5 of the *.ebsp file format): - ============= =============== =================== - Name Data type Shape - ============= =============== =================== + ============= =============== =================== ================ + Name Data type Shape New in version 5 + ============= =============== =================== ================ + map_x int32 (1,) x + map_y int32 (1,) x is_compressed int32 (1,) nrows int32 (1,) ncols int32 (1,) @@ -235,7 +254,7 @@ def get_memmap(self) -> np.memmap: beam_x float64 (1,) has_beam_y bool (1,) beam_y float64 (1,) - ============= =============== =================== + ============= =============== =================== ================ Returns ------- @@ -246,7 +265,6 @@ def get_memmap(self) -> np.memmap: file_dtype = self.pattern_header_dtype + [pattern_dtype] if len(footer_dtype) != 0: file_dtype += footer_dtype - return np.memmap( self.file.name, dtype=file_dtype, @@ -402,7 +420,7 @@ def get_single_pattern_footer(self, offset: int) -> np.ndarray: self.file.seek(offset + self.pattern_header_size + self.n_bytes) return np.fromfile(self.file, dtype=self.pattern_footer_dtype, count=1) - def get_single_pattern_header(self, offset: int) -> tuple[bool, int, int, int]: + def get_single_pattern_header(self, offset: int) -> np.ndarray: """Return a single pattern header. Parameters @@ -412,23 +430,12 @@ def get_single_pattern_header(self, offset: int) -> tuple[bool, int, int, int]: Returns ------- - is_compressed - Whether the pattern is compressed. - nrows - Number of signal (detector) rows. - ncols - Number of signal (detector) columns. - n_bytes - Number of pattern bytes. + header + The format of this depends on the file :attr:`version`. See + :attr:`pattern_header_dtype` for details. """ self.file.seek(offset) - header = np.fromfile(self.file, dtype=self.pattern_header_dtype, count=1)[0] - return ( - bool(header["is_compressed"][0]), - int(header["nrows"][0]), - int(header["ncols"][0]), - int(header["n_bytes"][0]), - ) + return np.fromfile(self.file, dtype=self.pattern_header_dtype, count=1)[0] def get_version(self) -> int: """Return the .ebsp file version. @@ -539,7 +546,7 @@ def guess_number_of_patterns(self, min_assumed_n_pixels: int = 1600) -> int: # It is assumed that a jump in bytes from one pattern position # to the next does not exceed a number of maximum bytes one # pattern can take up in the file. The array index where - # this happens (plus 2) is assumed to be the number of patterns + # this happens (plus 1) is assumed to be the number of patterns # in the file. diff_pattern_starts = np.diff(assumed_pattern_starts) max_assumed_n_pixels = 1024 * 1344 @@ -547,6 +554,12 @@ def guess_number_of_patterns(self, min_assumed_n_pixels: int = 1600) -> int: max_assumed_pattern_size = max_assumed_n_pixels * 2 + self.pattern_header_size # 20x is chosen as a sufficiently high jump in bytes pattern_start = abs(diff_pattern_starts) > 20 * max_assumed_pattern_size - n_patterns = np.nonzero(pattern_start)[0][0] + 1 + n_patterns = np.nonzero(pattern_start)[0][0] + + # Not sure why this is needed only for these versions... + if self.version < 5: + n_patterns += 1 + + _logger.debug(f"Guessed number of patterns: {n_patterns}") return n_patterns From 6b6b9ef615c069abf06a6c55b1e83f6b8e004747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Tue, 19 Nov 2024 22:54:30 +0100 Subject: [PATCH 04/10] Add map (x, y) from Oxford binary *.ebsp > v4 to original metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- .../io/plugins/oxford_binary/_api.py | 58 +++++++++++++------ 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/kikuchipy/io/plugins/oxford_binary/_api.py b/src/kikuchipy/io/plugins/oxford_binary/_api.py index d4aa47d1..66ed8138 100644 --- a/src/kikuchipy/io/plugins/oxford_binary/_api.py +++ b/src/kikuchipy/io/plugins/oxford_binary/_api.py @@ -230,6 +230,12 @@ def get_pattern_header_size(self): size += np.dtype(dtype).itemsize return size + def get_pattern_footer_size(self): + size = 0 + for _, dtype, _ in self.get_pattern_footer_dtype(self.first_pattern_position): + size += np.dtype(dtype).itemsize + return size + def get_memmap(self) -> np.memmap: """Return a memory map of the pattern header, actual patterns, and a potential pattern footer. @@ -326,7 +332,9 @@ def get_pattern_starts(self) -> np.ndarray: self.file.seek(self.pattern_starts_byte_position) return np.fromfile(self.file, dtype=np.int64, count=self.n_patterns) - def get_pattern_footer_dtype(self, offset: int) -> list[tuple]: + def get_pattern_footer_dtype( + self, offset: int + ) -> list[tuple[str, type, tuple[int]]]: """Return the pattern footer data types to be used when memory mapping. @@ -489,30 +497,34 @@ def get_scan(self, lazy: bool) -> dict: for i in range(data.ndim) ] fname = self.file.name - metadata = dict( - General=dict( - original_filename=fname, - title=os.path.splitext(os.path.split(fname)[1])[0], - ), - Signal=dict(signal_type="EBSD", record_by="image"), - ) + metadata = { + "General": { + "original_filename": fname, + "title": os.path.splitext(os.path.split(fname)[1])[0], + }, + "Signal": {"signal_type": "EBSD", "record_by": "image"}, + } order = self.pattern_order[self.pattern_is_present] - om = dict( - map1d_id=np.arange(self.n_patterns)[self.pattern_is_present], - file_order=order, - ) + om = { + "map1d_id": np.arange(self.n_patterns)[self.pattern_is_present], + "file_order": order, + } if "beam_y" in self.memmap.dtype.names: om["beam_y"] = self.memmap["beam_y"][..., 0][order] if "beam_x" in self.memmap.dtype.names: om["beam_x"] = self.memmap["beam_x"][..., 0][order] - - scan = dict( - axes=axes, - data=data, - metadata=metadata, - original_metadata=om, - ) + if "map_x" in self.memmap.dtype.names: + om["map_x"] = self.memmap["map_x"][..., 0][order] + if "map_y" in self.memmap.dtype.names: + om["map_y"] = self.memmap["map_y"][..., 0][order] + + scan = { + "axes": axes, + "data": data, + "metadata": metadata, + "original_metadata": om, + } return scan @@ -563,3 +575,11 @@ def guess_number_of_patterns(self, min_assumed_n_pixels: int = 1600) -> int: _logger.debug(f"Guessed number of patterns: {n_patterns}") return n_patterns + + def get_estimated_file_size(self) -> int: + n = self.n_patterns + file_header_size = self.pattern_starts_byte_position + n * 8 + pattern_header_size = self.get_pattern_header_size() + pattern_footer_size = self.get_pattern_footer_size() + pattern_section_size = pattern_header_size + self.n_bytes + pattern_footer_size + return file_header_size + n * pattern_section_size From 334e92e0fef0acb7dddc080a6cf026246dc64094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Tue, 19 Nov 2024 22:54:56 +0100 Subject: [PATCH 05/10] Update Oxford binary test fixture to allow mocking > v4 pattern header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- conftest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conftest.py b/conftest.py index b84d44e3..0acb99e6 100644 --- a/conftest.py +++ b/conftest.py @@ -512,6 +512,9 @@ def oxford_binary_file(tmpdir, request) -> Generator[TextIOWrapper, None, None]: for i in new_order: r, c = np.unravel_index(i, (nr, nc)) + if ver > 4: + extra_pattern_header = np.array([c, r], dtype=np.int32) + extra_pattern_header.tofile(f) pattern_header.tofile(f) data[r, c].tofile(f) if ver > 1: From 9215f56ee8981af86d38fcea841b9a783203e5c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Tue, 19 Nov 2024 22:55:26 +0100 Subject: [PATCH 06/10] Test reading of > v4 Oxford binary files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- tests/test_io/test_oxford_binary.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/test_io/test_oxford_binary.py b/tests/test_io/test_oxford_binary.py index 7e74b88e..67cf2cf1 100644 --- a/tests/test_io/test_oxford_binary.py +++ b/tests/test_io/test_oxford_binary.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU General Public License # along with kikuchipy. If not, see . +import os + import dask.array as da import numpy as np import pytest @@ -113,3 +115,30 @@ def test_guess_number_of_patterns(self, oxford_binary_file, n_patterns): with open(oxford_binary_file.name, mode="rb") as f: fox = OxfordBinaryFileReader(f) assert fox.n_patterns == n_patterns + + @pytest.mark.parametrize( + "oxford_binary_file", + [ + ((2, 3), (50, 50), np.uint8, 5, False, True), + ((2, 3), (50, 50), np.uint8, 6, False, True), + ], + indirect=["oxford_binary_file"], + ) + def test_version_5(self, oxford_binary_file): + with open(oxford_binary_file.name, mode="rb") as f: + fox = OxfordBinaryFileReader(f) + assert fox.n_patterns == 6 + + @pytest.mark.parametrize( + "oxford_binary_file, file_size", + [ + (((2, 3), (50, 50), np.uint8, 5, False, True), 15309), + (((2, 3), (50, 50), np.uint8, 4, False, True), 15261), + ], + indirect=["oxford_binary_file"], + ) + def test_estimated_file_size(self, oxford_binary_file, file_size): + with open(oxford_binary_file.name, mode="rb") as f: + fox = OxfordBinaryFileReader(f) + assert fox.get_estimated_file_size() == file_size + assert os.path.getsize(oxford_binary_file.name) == file_size From f50b6af19d2c3020c67239c292e74516f70c9da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Tue, 19 Nov 2024 23:27:28 +0100 Subject: [PATCH 07/10] Update IO tutorial with new original_metadata arrays for Oxford binary > v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- doc/tutorials/load_save_data.ipynb | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/doc/tutorials/load_save_data.ipynb b/doc/tutorials/load_save_data.ipynb index 89eda476..efcaa561 100644 --- a/doc/tutorials/load_save_data.ipynb +++ b/doc/tutorials/load_save_data.ipynb @@ -943,7 +943,13 @@ "Here, the Oxford Instruments binary [file_reader()](../reference/generated/kikuchipy.io.plugins.oxford_binary.file_reader.rst) is called.\n", "\n", "Every pattern's flattened index into the 2D navigation map, as well as their entry in the file (map order isn't always the same as file order) can be retrieved from `s_oxford.original_metadata.map1d_id` and `s_oxford.original_metadata.file_order`, respectively.\n", - "If available in the file, every pattern's row and column beam position in microns can be retrieved from `s_oxford.original_metadata.beam_y` and `s_oxford.original_metadata.beam_x`, respectively.\n", + "The following data may be read as well, depending on their presence in the file:\n", + "\n", + "* `s_oxford.original_metadata.beam_x`: Every pattern's column in microns\n", + "* `s_oxford.original_metadata.beam_y`: Every pattern's row in microns\n", + "* `s_oxford.original_metadata.map_x`: Every pattern's column\n", + "* `s_oxford.original_metadata.map_y`: Every pattern's row\n", + "\n", "All these are 1D arrays." ] }, @@ -1100,10 +1106,11 @@ "## Load and save virtual BSE images\n", "\n", "One or more virtual backscatter electron (BSE) images in a [VirtualBSEImage](../reference/generated/kikuchipy.signals.VirtualBSEImage.rst) signal can be read and written to file using one of HyperSpy's many readers and writers.\n", - "If they are only to be used internally in HyperSpy, they can be written to and read back from HyperSpy's HDF5/zarr specification [as explained above for EBSD master patterns](#Save-patterns).\n", "\n", + "If they are only to be used internally in HyperSpy, they can be written to and read back from HyperSpy's HDF5/zarr specification [as explained above for EBSD master patterns](#Save-patterns).\n", "If we want to write the images to image files, HyperSpy also provides a series of image readers/writers, as explained in their [IO user guide](https://hyperspy.org/hyperspy-doc/v1.7/user_guide/io.html#images).\n", - "If we wanted to write them as a stack of TIFF images" + "\n", + "Writing as a stack of TIFF images" ] }, { @@ -1146,7 +1153,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We can also write them to e.g. `png` or `bmp` files with `Matplotlib`" + "Read the TIFF stack back into a `VirtualBSEImage` signal" ] }, { @@ -1155,16 +1162,15 @@ "metadata": {}, "outputs": [], "source": [ - "nav_size = vbse.axes_manager.navigation_size\n", - "for i in range(nav_size):\n", - " plt.imsave(temp_dir / f\"vbse{i}.png\", vbse.inav[i].data)" + "vbse2 = hs.load(temp_dir / vbse_fname, signal_type=\"VirtualBSEImage\")\n", + "vbse2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Read the TIFF stack back into a `VirtualBSEImage` signal" + "We can also write them to e.g. `png` or `bmp` files with `Matplotlib`" ] }, { @@ -1173,8 +1179,9 @@ "metadata": {}, "outputs": [], "source": [ - "vbse2 = hs.load(temp_dir / vbse_fname, signal_type=\"VirtualBSEImage\")\n", - "vbse2" + "nav_size = vbse.axes_manager.navigation_size\n", + "for i in range(nav_size):\n", + " plt.imsave(temp_dir / f\"vbse{i}.png\", vbse.inav[i].data)" ] }, { @@ -1211,7 +1218,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.6" + "version": "3.12.7" }, "widgets": { "application/vnd.jupyter.widget-state+json": { From 2280a85bd628b91a99961f445a1bfc1782bb1e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Tue, 19 Nov 2024 23:30:17 +0100 Subject: [PATCH 08/10] Mention Oxford binary v6 fix in changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- CHANGELOG.rst | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 73e76d42..269ebc1d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,23 +13,13 @@ its best to adhere to `Semantic Versioning List entries are sorted in descending chronological order. Contributors to each release were listed in alphabetical order by first name until version 0.7.0. -Unreleased -========== - -Added ------ - -Changed -------- - -Removed -------- - -Deprecated ----------- +0.11.1 (2024-11-24) +=================== Fixed ----- +- Reading of Oxford binary `*.ebsp` files with version 6. + (`#700 `_) 0.11.0 (2024-11-10) =================== From 76dc0f0701087e51599c894eae16547e17249137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Tue, 19 Nov 2024 23:31:56 +0100 Subject: [PATCH 09/10] Set version to 0.11.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- src/kikuchipy/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kikuchipy/__init__.py b/src/kikuchipy/__init__.py index ef1444fa..21a9985b 100644 --- a/src/kikuchipy/__init__.py +++ b/src/kikuchipy/__init__.py @@ -30,7 +30,7 @@ "Carter Francis", "Magnus Nord", ] -__version__ = "0.12.dev0" +__version__ = "0.11.1" __getattr__, __dir__, __all__ = lazy_loader.attach_stub(__name__, __file__) From 96fb6214900061f10147583333e8f0aececfdee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Akon=20Wiik=20A=CC=8Anes?= Date: Wed, 20 Nov 2024 00:03:25 +0100 Subject: [PATCH 10/10] Add user agent to Pooch HTTP downloader to fix RTD-GH download error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håkon Wiik Ånes --- src/kikuchipy/data/_data.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/kikuchipy/data/_data.py b/src/kikuchipy/data/_data.py index f2aef16c..b504b3cf 100644 --- a/src/kikuchipy/data/_data.py +++ b/src/kikuchipy/data/_data.py @@ -629,7 +629,9 @@ def fetch_file_path( ) -> str: if show_progressbar is None: show_progressbar = hs.preferences.General.show_progressbar - downloader = pooch.HTTPDownloader(progressbar=show_progressbar) + downloader = pooch.HTTPDownloader( + progressbar=show_progressbar, headers={"User-Agent": "agent"} + ) if self.is_in_package: if self.has_correct_hash: