Mercurial > repos > perssond > ashlar
comparison pyramid_upgrade.py @ 1:f183d9de4622 draft
planemo upload for repository https://github.com/ohsu-comp-bio/ashlar commit 95998c84e130c9f3d2183591957464df7d90dd53
author | goeckslab |
---|---|
date | Wed, 24 Aug 2022 19:19:40 +0000 |
parents | b3054f3d42b2 |
children |
comparison
equal
deleted
inserted
replaced
0:b3054f3d42b2 | 1:f183d9de4622 |
---|---|
1 import sys | |
2 import os | |
3 import argparse | 1 import argparse |
4 import struct | 2 import dataclasses |
5 import re | |
6 import fractions | 3 import fractions |
7 import io | 4 import io |
5 import os | |
6 import re | |
7 import reprlib | |
8 import struct | |
9 import sys | |
8 import xml.etree.ElementTree | 10 import xml.etree.ElementTree |
9 import collections | 11 from typing import Any, List |
10 import reprlib | |
11 import dataclasses | |
12 from typing import List, Any | |
13 | 12 |
14 | 13 |
15 datatype_formats = { | 14 datatype_formats = { |
16 1: "B", # BYTE | 15 1: "B", # BYTE |
17 2: "s", # ASCII | 16 2: "s", # ASCII |
18 3: "H", # SHORT | 17 3: "H", # SHORT |
19 4: "I", # LONG | 18 4: "I", # LONG |
20 5: "I", # RATIONAL (pairs) | 19 5: "I", # RATIONAL (pairs) |
21 6: "b", # SBYTE | 20 6: "b", # SBYTE |
22 7: "B", # UNDEFINED | 21 7: "B", # UNDEFINED |
23 8: "h", # SSHORT | 22 8: "h", # SSHORT |
24 9: "i", # SLONG | 23 9: "i", # SLONG |
25 10: "i", # SRATIONAL (pairs) | 24 10: "i", # SRATIONAL (pairs) |
26 11: "f", # FLOAT | 25 11: "f", # FLOAT |
27 12: "d", # DOUBLE | 26 12: "d", # DOUBLE |
28 13: "I", # IFD | 27 13: "I", # IFD |
29 16: "Q", # LONG8 | 28 16: "Q", # LONG8 |
30 17: "q", # SLONG8 | 29 17: "q", # SLONG8 |
31 18: "Q", # IFD8 | 30 18: "Q", # IFD8 |
32 } | 31 } |
33 rational_datatypes = {5, 10} | 32 rational_datatypes = {5, 10} |
34 | 33 |
35 | 34 |
36 class TiffSurgeon: | 35 class TiffSurgeon: |
251 + f"count={self.count!r}, data={self.data!r}, " | 250 + f"count={self.count!r}, data={self.data!r}, " |
252 + f"value={self.vrepr(self.value)}" | 251 + f"value={self.vrepr(self.value)}" |
253 + ")" | 252 + ")" |
254 ) | 253 ) |
255 | 254 |
255 | |
256 @dataclasses.dataclass(frozen=True) | 256 @dataclasses.dataclass(frozen=True) |
257 class TagSet: | 257 class TagSet: |
258 """Container for Tag objects as stored in a TIFF IFD. | 258 """Container for Tag objects as stored in a TIFF IFD. |
259 | 259 |
260 Tag objects are maintained in a list that's always sorted in ascending order | 260 Tag objects are maintained in a list that's always sorted in ascending order |
291 def __delitem__(self, code): | 291 def __delitem__(self, code): |
292 try: | 292 try: |
293 i = self.codes.index(code) | 293 i = self.codes.index(code) |
294 except ValueError: | 294 except ValueError: |
295 raise KeyError(code) from None | 295 raise KeyError(code) from None |
296 self.tags[:] = self.tags[:i] + self.tags[i+1:] | 296 self.tags[:] = self.tags[:i] + self.tags[i + 1:] |
297 | 297 |
298 def __contains__(self, code): | 298 def __contains__(self, code): |
299 return code in self.codes | 299 return code in self.codes |
300 | 300 |
301 def __len__(self): | 301 def __len__(self): |
326 elif tag.code < t.code: | 326 elif tag.code < t.code: |
327 break | 327 break |
328 else: | 328 else: |
329 i = len(self.tags) | 329 i = len(self.tags) |
330 n = len(self.tags) | 330 n = len(self.tags) |
331 self.tags[i:n+1] = [tag] + self.tags[i:n] | 331 self.tags[i:n + 1] = [tag] + self.tags[i:n] |
332 | 332 |
333 | 333 |
334 @dataclasses.dataclass(frozen=True) | 334 @dataclasses.dataclass(frozen=True) |
335 class Ifd: | 335 class Ifd: |
336 tags: TagSet | 336 tags: TagSet |
370 | 370 |
371 | 371 |
372 def parse_args(): | 372 def parse_args(): |
373 parser = argparse.ArgumentParser( | 373 parser = argparse.ArgumentParser( |
374 description="Convert an OME-TIFF legacy pyramid to the BioFormats 6" | 374 description="Convert an OME-TIFF legacy pyramid to the BioFormats 6" |
375 " OME-TIFF pyramid format in-place.", | 375 " OME-TIFF pyramid format in-place.", |
376 ) | 376 ) |
377 parser.add_argument("image", help="OME-TIFF file to convert") | 377 parser.add_argument("image", help="OME-TIFF file to convert") |
378 parser.add_argument( | 378 parser.add_argument( |
379 "-n", | 379 "-n", |
380 dest="channel_names", | 380 dest="channel_names", |
381 nargs="+", | 381 nargs="+", |
382 default=[], | 382 default=[], |
383 metavar="NAME", | 383 metavar="NAME", |
384 help="Channel names to be inserted into OME metadata. Number of names" | 384 help="Channel names to be inserted into OME metadata. Number of names" |
385 " must match number of channels in image. Be sure to put quotes" | 385 " must match number of channels in image. Be sure to put quotes" |
386 " around names containing spaces or other special shell characters." | 386 " around names containing spaces or other special shell characters." |
387 ) | 387 ) |
388 args = parser.parse_args() | 388 args = parser.parse_args() |
389 return args | 389 return args |
390 | 390 |
391 | 391 |
449 sys.exit(1) | 449 sys.exit(1) |
450 if any(dims != (size_x, size_y) for dims in page_dims[:size_c]): | 450 if any(dims != (size_x, size_y) for dims in page_dims[:size_c]): |
451 print(f"TIFF does not begin with SizeC={size_c} full-size pages.") | 451 print(f"TIFF does not begin with SizeC={size_c} full-size pages.") |
452 sys.exit(1) | 452 sys.exit(1) |
453 for level in range(1, num_levels): | 453 for level in range(1, num_levels): |
454 level_dims = page_dims[level * size_c : (level + 1) * size_c] | 454 level_dims = page_dims[level * size_c: (level + 1) * size_c] |
455 if len(set(level_dims)) != 1: | 455 if len(set(level_dims)) != 1: |
456 print( | 456 print( |
457 f"Pyramid level {level + 1} out of {num_levels} has inconsistent" | 457 f"Pyramid level {level + 1} out of {num_levels} has inconsistent" |
458 f" sizes:\n{level_dims}" | 458 f" sizes:\n{level_dims}" |
459 ) | 459 ) |
511 new_omexml = xml_file.getvalue() | 511 new_omexml = xml_file.getvalue() |
512 | 512 |
513 print("Writing new TIFF headers...") | 513 print("Writing new TIFF headers...") |
514 stale_ranges = [ifd.offset_range for ifd in tiff.ifds] | 514 stale_ranges = [ifd.offset_range for ifd in tiff.ifds] |
515 main_ifds = tiff.ifds[:size_c] | 515 main_ifds = tiff.ifds[:size_c] |
516 channel_sub_ifds = [tiff.ifds[c + size_c : : size_c] for c in range(size_c)] | 516 channel_sub_ifds = [tiff.ifds[c + size_c::size_c] for c in range(size_c)] |
517 for i, (main_ifd, sub_ifds) in enumerate(zip(main_ifds, channel_sub_ifds)): | 517 for i, (main_ifd, sub_ifds) in enumerate(zip(main_ifds, channel_sub_ifds)): |
518 for ifd in sub_ifds: | 518 for ifd in sub_ifds: |
519 if 305 in ifd.tags: | 519 if 305 in ifd.tags: |
520 stale_ranges.append(ifd.tags[305].offset_range) | 520 stale_ranges.append(ifd.tags[305].offset_range) |
521 del ifd.tags[305] | 521 del ifd.tags[305] |