diff --git a/README.md b/README.md index 67d6017..17d06bf 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,29 @@ # issfile -LIbrary for opening ISS (iss.com) files and conversion to tiff. +Library for opening [ISS](https://iss.com) files and their conversion to tiff. + +## Installation + + pip install git+https://github.com/wimpomp/issfile.git + +## Converting .iss-pt files to .tiff files + + iss2tiff --help + + iss2tiff file.iss-pt + +this will create file.tiff and file.carpet.tiff containing images and carpets respectively. +Metadata is also saved in the tiffs in the description tag. + +## Use as a library + + from matplotlib import pyplot as plt + from issfile import IssFile + + with IssFile(file) as iss: + image = iss.get_image(c=1, t=5) + carpet = iss.get_carpet(c=1, t=5) + + plt.figure() + plt.imshow(image) + plt.figure() + plt.plot(carpet.sum(1)) diff --git a/example_v388.iss-pt b/example_v388.iss-pt new file mode 100755 index 0000000..e5d4849 Binary files /dev/null and b/example_v388.iss-pt differ diff --git a/issfile/__init__.py b/issfile/__init__.py index 022a35a..b146250 100644 --- a/issfile/__init__.py +++ b/issfile/__init__.py @@ -1,18 +1,21 @@ -import sys import zipfile +import re +import pickle import xml.etree.ElementTree as ET import numpy as np -import re from struct import unpack from tiffwrite import IJTiffFile from tqdm.auto import tqdm from itertools import product from yaml import safe_load +from argparse import ArgumentParser -class IssTrack: - def __init__(self, file): - self.zip = zipfile.ZipFile(file) +class IssFile: + def __init__(self, file, version=388): + self.file = file + self.version = version + self.zip = zipfile.ZipFile(self.file) self.data = self.zip.open('data/PrimaryDecayData.bin') self.metadata = ET.fromstring(self.zip.read('dataProps/Core.xml')) dimensions = self.metadata.find('Dimensions') @@ -24,19 +27,16 @@ class IssTrack: self.shape = size_x, size_y, size_c, size_t // 2 + size_t % 2, size_t // 2 self.exposure_time = float(self.metadata.find('FrameIntervalTime').text) self.pxsize = float(self.metadata.find('Boundary').find('FrameWidth').text) / self.shape[0] - - self.alba_metadata = safe_load('\n'.join([IssTrack.parse_line(line) + self.alba_metadata = safe_load('\n'.join([IssFile.parse_line(line) for line in self.metadata.find('AlbaSystemSettings').find('withComments').text.splitlines()])) particle_tracking = self.alba_metadata['ParticleTracking'] self.points_per_orbit = particle_tracking['ScanCirclePointCount'] - self.n_orbits = particle_tracking['OrbitCountPerTrack'] - self.orbit_time = particle_tracking['PacketTrackTime_ms'] - self.start_times = [float(re.match(r'[.\d]+', value).group(0)) - for key, value in self.alba_metadata.items() - if re.match(r'Time Series (\d+) started at', key)] - self.time_interval = np.mean(np.diff(self.start_times)[1::2]) - self.delta = self.shape[2] * 2 ** int(np.ceil(np.log2(self.time_interval * 1000 / self.orbit_time))) - self.delta = 768 # TODO: figure out if this number is the same for all files + self.orbits_per_cycle = particle_tracking['OrbitCountPerTrack'] + self.radius = particle_tracking['ScanRadius_um'] + self.orbit_pxsize = self.radius * 2 * np.pi / self.points_per_orbit + self.data_bytes_len = self.zip.getinfo('data/PrimaryDecayData.bin').file_size + self.delta = self.data_bytes_len // (self.shape[0] * self.shape[1] * self.shape[2] * + (self.shape[3] + self.shape[4])) def __enter__(self): return self @@ -44,6 +44,14 @@ class IssTrack: def __exit__(self, *args, **kwargs): self.close() + def __getstate__(self): + return {key: value for key, value in self.__dict__.items() if key not in ('zip', 'data')} + + def __setstate__(self, state): + self.__dict__.update(state) + self.zip = zipfile.ZipFile(self.file) + self.data = self.zip.open('data/PrimaryDecayData.bin') + def close(self): try: self.data.close() @@ -61,32 +69,58 @@ class IssTrack: data.append(unpack('=2022.10.0'], + install_requires=['numpy', 'tqdm', 'pyyaml', 'tiffwrite>=2022.10.1'], entry_points={'console_scripts': ['iss2tiff=issfile:main']} )