def read_binary_mask(self, tf: tarfile.TarFile) -> bm.BinaryMaskCollection: log: Optional[Log] = None masks: MutableSequence[bm.MaskData] = [] pixel_ticks: Optional[Mapping[Axes, ArrayLike[int]]] = None physical_ticks: Optional[Mapping[Coordinates, ArrayLike[Number]]] = None while True: tarinfo: Optional[tarfile.TarInfo] = tf.next() if tarinfo is None: break # wrap it in a BytesIO object to ensure we never seek backwards. extracted_fh = tf.extractfile(tarinfo) if extracted_fh is None: raise ValueError(f"Unable to extract file {tarinfo.name}") byte_stream = io.BytesIO(extracted_fh.read()) if tarinfo.name == v0_0.LOG_FILENAME: string_stream = codecs.getreader("utf-8")(byte_stream) log = Log.decode(string_stream.read()) elif tarinfo.name == v0_0.PIXEL_TICKS_FILE: pixel_ticks = pickle.load(byte_stream) elif tarinfo.name == v0_0.PHYSICAL_TICKS_FILE: physical_ticks = pickle.load(byte_stream) elif tarinfo.name.startswith(v0_0.MASK_PREFIX): mask_on_disk: v0_0.MaskOnDisk = pickle.load(byte_stream) if not isinstance(mask_on_disk, v0_0.MaskOnDisk): raise TypeError( f"mask does not conform to expected mask structure") masks.append( bm.MaskData(mask_on_disk.binary_mask, mask_on_disk.offsets, None)) else: warnings.warn( f"Unexpected file in binary mask collection {tarinfo.name}", DataFormatWarning) if pixel_ticks is None: raise ValueError("pixel coordinates not found") if physical_ticks is None: raise ValueError("physical coordinates not found") return bm.BinaryMaskCollection(pixel_ticks, physical_ticks, masks, log)
def log(self) -> Log: """Returns a copy of the provenance data. Modifications to this copy will not affect the log stored on this label image.""" return Log.decode(self.label_image.attrs[AttrKeys.LOG])