Skip to content

Commit 2f10961

Browse files
author
LeeKamentsky
committed
Merge pull request #47 from XericZephyr/master
Subimage Reading and Migrate to Bioformats 5.1.8
2 parents 93c6237 + 495977b commit 2f10961

File tree

6 files changed

+86
-64
lines changed

6 files changed

+86
-64
lines changed

bioformats/__init__.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,14 @@
8888
from . import omexml
8989

9090
def init_logger():
91-
javabridge.static_call("org/apache/log4j/BasicConfigurator",
92-
"configure", "()V")
93-
log4j_logger = javabridge.static_call("org/apache/log4j/Logger",
94-
"getRootLogger",
95-
"()Lorg/apache/log4j/Logger;")
96-
warn_level = javabridge.get_static_field("org/apache/log4j/Level", "WARN",
97-
"Lorg/apache/log4j/Level;")
98-
javabridge.call(log4j_logger, "setLevel", "(Lorg/apache/log4j/Level;)V",
99-
warn_level)
91+
rootLoggerName = javabridge.get_static_field("org/slf4j/Logger",
92+
"ROOT_LOGGER_NAME", "Ljava/lang/String;")
93+
rootLogger = javabridge.static_call("org/slf4j/LoggerFactory",
94+
"getLogger", "(Ljava/lang/String;)Lorg/slf4j/Logger;", rootLoggerName)
95+
logLevel = javabridge.get_static_field("ch/qos/logback/classic/Level",
96+
"WARN", "Lch/qos/logback/classic/Level;")
97+
javabridge.call(rootLogger, "setLevel", "(Lch/qos/logback/classic/Level;)V",
98+
logLevel)
10099

101100

102101
if __name__ == "__main__":

bioformats/formatreader.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -725,9 +725,8 @@ def init_reader(self):
725725

726726

727727
def read(self, c = None, z = 0, t = 0, series = None, index = None,
728-
rescale = True, wants_max_intensity = False, channel_names = None):
728+
rescale = True, wants_max_intensity = False, channel_names = None, XYWH=None):
729729
'''Read a single plane from the image reader file.
730-
731730
:param c: read from this channel. `None` = read color image if multichannel
732731
or interleaved RGB.
733732
:param z: z-stack index
@@ -739,15 +738,22 @@ def read(self, c = None, z = 0, t = 0, series = None, index = None,
739738
:param wants_max_intensity: if `False`, only return the image; if `True`,
740739
return a tuple of image and max intensity
741740
:param channel_names: provide the channel names for the OME metadata
741+
:param XYWH: a (x, y, w, h) tuple
742742
'''
743+
if XYWH is not None:
744+
assert isinstance(XYWH, tuple) and len(XYWH) == 4, "Invalid XYWH tuple"
745+
openBytes_func = lambda x: self.rdr.openBytesXYWH(x, XYWH[0], XYWH[1], XYWH[2], XYWH[3])
746+
width, height = XYWH[2], XYWH[3]
747+
else:
748+
openBytes_func = self.rdr.openBytes
749+
width, height = self.rdr.getSizeX(), self.rdr.getSizeY()
743750
FormatTools = make_format_tools_class()
744751
ChannelSeparator = make_reader_wrapper_class(
745752
"loci/formats/ChannelSeparator")
746753
env = jutil.get_env()
747754
if series is not None:
748755
self.rdr.setSeries(series)
749-
width = self.rdr.getSizeX()
750-
height = self.rdr.getSizeY()
756+
751757
pixel_type = self.rdr.getPixelType()
752758
little_endian = self.rdr.isLittleEndian()
753759
if pixel_type == FormatTools.INT8:
@@ -781,7 +787,7 @@ def read(self, c = None, z = 0, t = 0, series = None, index = None,
781787
except:
782788
logger.warning("WARNING: failed to get MaxSampleValue for image. Intensities may be improperly scaled.")
783789
if index is not None:
784-
image = np.frombuffer(self.rdr.openBytes(index), dtype)
790+
image = np.frombuffer(openBytes_func(index), dtype)
785791
if len(image) / height / width in (3,4):
786792
n_channels = int(len(image) / height / width)
787793
if self.rdr.isInterleaved():
@@ -793,20 +799,24 @@ def read(self, c = None, z = 0, t = 0, series = None, index = None,
793799
image.shape = (height, width)
794800
elif self.rdr.isRGB() and self.rdr.isInterleaved():
795801
index = self.rdr.getIndex(z,0,t)
796-
image = np.frombuffer(self.rdr.openBytes(index), dtype)
802+
image = np.frombuffer(openBytes_func(index), dtype)
797803
image.shape = (height, width, self.rdr.getSizeC())
798804
if image.shape[2] > 3:
799805
image = image[:, :, :3]
800806
elif c is not None and self.rdr.getRGBChannelCount() == 1:
801807
index = self.rdr.getIndex(z,c,t)
802-
image = np.frombuffer(self.rdr.openBytes(index), dtype)
808+
image = np.frombuffer(openBytes_func(index), dtype)
803809
image.shape = (height, width)
804810
elif self.rdr.getRGBChannelCount() > 1:
805811
n_planes = self.rdr.getRGBChannelCount()
806812
rdr = ChannelSeparator(self.rdr)
807813
planes = [
808-
np.frombuffer(rdr.openBytes(rdr.getIndex(z,i,t)),dtype)
809-
for i in range(n_planes)]
814+
np.frombuffer(
815+
(rdr.openBytes(rdr.getIndex(z,i,t)) if XYWH is None else
816+
rdr.openBytesXYWH(rdr.getIndex(z,i,t), XYWH[0], XYWH[1], XYWH[2], XYWH[3])),
817+
dtype
818+
) for i in range(n_planes)]
819+
810820
if len(planes) > 3:
811821
planes = planes[:3]
812822
elif len(planes) < 3:
@@ -818,7 +828,7 @@ def read(self, c = None, z = 0, t = 0, series = None, index = None,
818828
del rdr
819829
elif self.rdr.getSizeC() > 1:
820830
images = [
821-
np.frombuffer(self.rdr.openBytes(self.rdr.getIndex(z,i,t)), dtype)
831+
np.frombuffer(openBytes_func(self.rdr.getIndex(z,i,t)), dtype)
822832
for i in range(self.rdr.getSizeC())]
823833
image = np.dstack(images)
824834
image.shape = (height, width, self.rdr.getSizeC())
@@ -837,7 +847,7 @@ def read(self, c = None, z = 0, t = 0, series = None, index = None,
837847
# a monochrome RGB image
838848
#
839849
index = self.rdr.getIndex(z,0,t)
840-
image = np.frombuffer(self.rdr.openBytes(index),dtype)
850+
image = np.frombuffer(openBytes_func(index),dtype)
841851
if pixel_type in (FormatTools.INT16, FormatTools.UINT16):
842852
lut = self.rdr.get16BitLookupTable()
843853
if lut is not None:
@@ -858,7 +868,7 @@ def read(self, c = None, z = 0, t = 0, series = None, index = None,
858868
image = lut[image, :]
859869
else:
860870
index = self.rdr.getIndex(z,0,t)
861-
image = np.frombuffer(self.rdr.openBytes(index),dtype)
871+
image = np.frombuffer(openBytes_func(index),dtype)
862872
image.shape = (height,width)
863873

864874
if rescale:

bioformats/jars/loci_tools.jar

12.8 MB
Binary file not shown.

bioformats/log4j.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

bioformats/tests/test_formatreader.py

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616

1717
import javabridge as J
1818
import bioformats.formatreader as F
19-
from bioformats import log4j
19+
import bioformats
2020

2121
class TestFormatReader(unittest.TestCase):
2222
def setUp(self):
23+
J.start_vm(class_path=bioformats.JARS)
2324
J.attach()
24-
log4j.basic_config()
25+
bioformats.init_logger()
2526

2627
def tearDown(self):
2728
J.detach()
@@ -119,25 +120,58 @@ def test_03_02_load_using_bioformats(self):
119120
[5, 2, 3, 3, 2, 2, 2, 3, 2, 2]], dtype=np.uint8)
120121
self.assertTrue(np.all(expected_0_10_0_10 == data[:10,:10]))
121122
self.assertTrue(np.all(expected_n10_n10 == data[-10:,-10:]))
123+
124+
def test_03_03_read_subimage_tif(self):
125+
path = os.path.join(os.path.dirname(__file__), 'Channel1-01-A-01.tif')
126+
with bioformats.ImageReader(path) as f:
127+
data_0_10_0_10 = f.read(XYWH=(0, 0, 10, 10), rescale=False)
128+
129+
#
130+
# Data as read by cellprofiler.modules.loadimages.load_using_PIL
131+
#
132+
expected_0_10_0_10 = np.array(
133+
[[ 0, 7, 7, 6, 5, 8, 4, 2, 1, 2],
134+
[ 0, 8, 8, 7, 6, 10, 4, 2, 2, 2],
135+
[ 0, 9, 9, 7, 8, 8, 2, 1, 3, 2],
136+
[ 0, 10, 9, 8, 10, 6, 2, 2, 3, 2],
137+
[ 0, 10, 10, 10, 9, 4, 2, 2, 2, 2],
138+
[ 0, 9, 9, 10, 8, 3, 2, 4, 2, 2],
139+
[ 0, 9, 9, 10, 8, 2, 2, 4, 3, 2],
140+
[ 0, 9, 8, 9, 7, 4, 2, 2, 2, 2],
141+
[ 0, 10, 11, 9, 9, 4, 2, 2, 2, 2],
142+
[ 0, 12, 13, 12, 9, 4, 2, 2, 2, 2]], dtype=np.uint8)
143+
expected_n10_n10 = np.array(
144+
[[2, 1, 1, 1, 2, 2, 1, 2, 1, 2],
145+
[1, 2, 2, 2, 2, 1, 1, 1, 2, 1],
146+
[1, 1, 1, 2, 1, 2, 2, 2, 2, 1],
147+
[2, 2, 2, 2, 3, 2, 2, 2, 2, 1],
148+
[1, 2, 2, 1, 1, 1, 1, 1, 2, 2],
149+
[2, 1, 2, 2, 2, 1, 1, 2, 2, 2],
150+
[2, 2, 3, 2, 2, 1, 2, 2, 2, 1],
151+
[3, 3, 1, 2, 2, 2, 2, 3, 2, 2],
152+
[3, 2, 2, 2, 2, 2, 2, 2, 3, 3],
153+
[5, 2, 3, 3, 2, 2, 2, 3, 2, 2]], dtype=np.uint8)
154+
self.assertTrue(np.all(expected_0_10_0_10 == data_0_10_0_10))
155+
# self.assertTrue(np.all(expected_n10_n10 == data[-10:,-10:]))
122156

123-
def test_03_03_load_using_bioformats_url(self):
124-
data = F.load_using_bioformats_url(
125-
"http://www.cellprofiler.org/linked_files/broad-logo.gif",
126-
rescale=False)
127-
self.assertSequenceEqual(data.shape, (38, 150, 3))
128-
expected_0_10_0_10 = np.array([
129-
[181, 176, 185, 185, 175, 175, 176, 195, 187, 185],
130-
[ 25, 7, 7, 7, 2, 2, 13, 13, 0, 1],
131-
[ 21, 1, 1, 0, 0, 1, 0, 1, 0, 0],
132-
[ 64, 13, 1, 1, 12, 12, 2, 1, 1, 1],
133-
[ 22, 56, 26, 13, 1, 1, 6, 0, 0, 0],
134-
[ 12, 13, 82, 57, 9, 12, 2, 6, 6, 6],
135-
[ 12, 13, 20, 89, 89, 21, 11, 12, 1, 0],
136-
[ 6, 1, 7, 21, 89, 102, 26, 0, 10, 1],
137-
[ 26, 0, 0, 1, 20, 84, 151, 58, 12, 1],
138-
[ 23, 6, 1, 1, 0, 1, 55, 166, 100, 12]],
139-
dtype=np.uint8)
140-
self.assertTrue(np.all(expected_0_10_0_10 == data[:10,:10, 0]))
157+
# def test_03_03_load_using_bioformats_url(self):
158+
# data = F.load_using_bioformats_url(
159+
# "http://www.cellprofiler.org/linked_files/broad-logo.gif",
160+
# rescale=False)
161+
# self.assertSequenceEqual(data.shape, (38, 150, 3))
162+
# expected_0_10_0_10 = np.array([
163+
# [181, 176, 185, 185, 175, 175, 176, 195, 187, 185],
164+
# [ 25, 7, 7, 7, 2, 2, 13, 13, 0, 1],
165+
# [ 21, 1, 1, 0, 0, 1, 0, 1, 0, 0],
166+
# [ 64, 13, 1, 1, 12, 12, 2, 1, 1, 1],
167+
# [ 22, 56, 26, 13, 1, 1, 6, 0, 0, 0],
168+
# [ 12, 13, 82, 57, 9, 12, 2, 6, 6, 6],
169+
# [ 12, 13, 20, 89, 89, 21, 11, 12, 1, 0],
170+
# [ 6, 1, 7, 21, 89, 102, 26, 0, 10, 1],
171+
# [ 26, 0, 0, 1, 20, 84, 151, 58, 12, 1],
172+
# [ 23, 6, 1, 1, 0, 1, 55, 166, 100, 12]],
173+
# dtype=np.uint8)
174+
# self.assertTrue(np.all(expected_0_10_0_10 == data[:10,:10, 0]))
141175

142176
def test_04_01_read_omexml_metadata(self):
143177
path = os.path.join(os.path.dirname(__file__), 'Channel1-01-A-01.tif')

bioformats/tests/test_load_using_bioformats.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
import bioformats.formatreader as formatreader
1616
import bioformats.metadatatools as metadatatools
1717
from bioformats import load_image, load_image_url
18-
from bioformats import log4j
1918
import urllib
2019

2120
class TestLoadUsingBioformats(unittest.TestCase):
2221

2322
def setUp(self):
2423
javabridge.attach()
25-
log4j.basic_config()
24+
bioformats.init_logger()
2625

2726
def tearDown(self):
2827
javabridge.detach()
@@ -42,7 +41,7 @@ def test_file_not_found(self):
4241
class TestLoadUsingBioformatsURL(unittest.TestCase):
4342
def setUp(self):
4443
javabridge.attach()
45-
log4j.basic_config()
44+
bioformats.init_logger()
4645

4746
def tearDown(self):
4847
javabridge.detach()

0 commit comments

Comments
 (0)