Recently, the CellProfiler team at the Broad Institute announced pre-release versions of the python-javabridge and python-bioformats packages available on PyPI. The latter enables easy import of many biological image formats into numpy arrays, without any of the flailing around with converters in Jython that I'd fiddled with in the past.

Before starting, you'll need Java development headers on your machine. I imagine that on Linux systems you'd do something like sudo apt-get install java-devel, but on OSX you head to Apple's Developer downloads page, which requires your Apple ID, and download a "Java for OS X <version> Developer Package".

Then, simply run pip install python-bioformats, and you'll get both packages!

Next, I follow the examples in the python-bioformats documentation to try to read parts of a massive, 400+GB Leica file without giving my RAM a heart attack.


In [1]:
%matplotlib inline
import javabridge as jv
import bioformats as bf
jv.start_vm(class_path=bf.JARS, max_heap_size="8G")

It is imperative to specify the max_heap_size to be something bigger than the anemic default of 256MB. Otherwise, even reading in a small amount of metadata (in our case, a 27MB XML string) will fail. See the following post for more details:

https://github.com/CellProfiler/python-bioformats/issues/8


In [2]:
# Change to the appropriate directory and get the file information
%cd /Volumes/LaCie/Data/zebrafish-lesion
%ls


/Volumes/LaCie/Data/zebrafish-lesion
2d-post-SCI.lif-cut-PTZ-1.tif* sci-quant.lzf.h5*
Long time Gfap 260314.lif*     sci-quant.tif*
im.png*                        tifffile.py*
im.tif*                        tifffile.pyc*
lineprofile.py*                time-series/
lineprofile.pyc*

In [3]:
filename = 'Long time Gfap 260314.lif'
rdr = bf.ImageReader(filename, perform_init=True)
reader = rdr.rdr
print("The number of series is %d." % reader.getSeriesCount())


The number of series is 179.

In the next cell, we measure the size of the metadata. I'm maintaining it just for future reference.


In [4]:
import numpy as np
with open('Long time Gfap 260314.lif', "rb") as fd:
    fd.read(9)
    length = np.frombuffer(fd.read(4), "<i4")
    print(length[0])


27594197

In [5]:
reader.setSeries(0)
print reader.getMetadataValue('Name')


None

In [5]:

Let's try the XML approach again, see if it can be read with the new heap size:


In [6]:
md = bf.get_omexml_metadata('Long time Gfap 260314.lif')

It works! Let's see if we can parse it...


In [7]:
print(type(md))
print(len(md))
print(md[:10])


<type 'unicode'>
66620949
<?xml vers

Okay, so we have an XML string. Let's whip out an XML parser to make sense of it.


In [8]:
import xml
import xml.etree.ElementTree as ET
mdroot = ET.fromstring(md)

We figure out the parsing from the xml package doc here. In our case, we are (for now) only interested in the 'Name' attribute of each Image child of the root:


In [9]:
print([(a.tag, a.attrib) for a in list(list(mdroot[300]))])


[('{http://www.openmicroscopy.org/Schemas/OME/2011-06}AcquiredDate', {}), ('{http://www.openmicroscopy.org/Schemas/OME/2011-06}InstrumentRef', {'ID': 'Instrument:121'}), ('{http://www.openmicroscopy.org/Schemas/OME/2011-06}ObjectiveSettings', {'RefractiveIndex': '1.33', 'ID': 'Objective:121:0'}), ('{http://www.openmicroscopy.org/Schemas/OME/2011-06}Pixels', {'SizeT': '14', 'DimensionOrder': 'XYCZT', 'PhysicalSizeY': '0.445197265625', 'PhysicalSizeX': '0.445197265625', 'PhysicalSizeZ': '1.9912714979001302', 'SizeX': '1024', 'SizeY': '1024', 'SizeZ': '108', 'SizeC': '2', 'Type': 'uint8', 'ID': 'Pixels:121'})]

In [10]:
image_names = []
sizes_tzyxc = []
res_zyx = []
size_tags = ['Size' + c for c in ['T', 'Z', 'Y', 'X', 'C']]
res_tags = ['PhysicalSize' + c for c in ['Z', 'Y', 'X']]
for child in mdroot:
    if child.tag.endswith('Image'):
        image_names.append(child.attrib['Name'])
        for grandchild in child:
            if grandchild.tag.endswith('Pixels'):
                att = grandchild.attrib
                sizes_tzyxc.append(tuple([int(att[t])
                                          for t in size_tags]))
                res_zyx.append(tuple([float(att[t]) for t in res_tags]))

In [11]:
sizes_tzyxc[45]


Out[11]:
(1, 51, 1024, 1024, 2)

In [12]:
for name, size in zip(image_names, sizes_tzyxc):
    print(name + ' ' + str(size))


Pre lesion 2x/Pos001_S001 (1, 53, 1024, 1024, 2)
Pre lesion 2x/Pos002_S001 (1, 55, 1024, 1024, 2)
Pre lesion 2x/Pos003_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos004_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos005_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos006_S001 (1, 58, 1024, 1024, 2)
Pre lesion 2x/Pos007_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos008_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos009_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos010_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos011_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos012_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos013_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos014_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos015_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos016_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos017_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos018_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos019_S001 (1, 51, 1024, 1024, 2)
Pre lesion 2x/Pos020_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos021_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos022_S001 (1, 52, 1024, 1024, 2)
Pre lesion 2x/Pos023_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos001_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos002_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos003_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos004_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos005_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos006_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos007_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos008_S001 (1, 55, 1024, 1024, 2)
Mark_and_Find_001/Pos009_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos010_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos011_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos012_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos013_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos014_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos015_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos016_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos017_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos018_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos019_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos020_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos021_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos022_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos023_S001 (1, 51, 1024, 1024, 2)
Mark_and_Find_001/Pos024_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos025_S001 (1, 52, 1024, 1024, 2)
Mark_and_Find_001/Pos026_S001 (1, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos001_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos002_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos003_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos004_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos005_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos006_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos007_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos008_S001 (34, 55, 1024, 1024, 2)
0 to 16.5h pSCI/Pos009_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos010_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos011_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos012_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos013_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos014_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos015_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos016_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos017_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos018_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos019_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos020_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos021_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos022_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos023_S001 (34, 51, 1024, 1024, 2)
0 to 16.5h pSCI/Pos024_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos025_S001 (34, 52, 1024, 1024, 2)
0 to 16.5h pSCI/Pos026_S001 (34, 51, 1024, 1024, 2)
22.5h to 41h pSCI/Pos001_S001 (37, 54, 1024, 1024, 2)
22.5h to 41h pSCI/Pos002_S001 (37, 55, 1024, 1024, 2)
22.5h to 41h pSCI/Pos003_S001 (37, 54, 1024, 1024, 2)
22.5h to 41h pSCI/Pos004_S001 (37, 54, 1024, 1024, 2)
22.5h to 41h pSCI/Pos005_S001 (37, 53, 1024, 1024, 2)
22.5h to 41h pSCI/Pos006_S001 (37, 59, 1024, 1024, 2)
22.5h to 41h pSCI/Pos007_S001 (37, 54, 1024, 1024, 2)
22.5h to 41h pSCI/Pos008_S001 (37, 55, 1024, 1024, 2)
22.5h to 41h pSCI/Pos009_S001 (37, 52, 1024, 1024, 2)
22.5h to 41h pSCI/Pos010_S001 (37, 3, 1024, 1024, 2)
22.5h to 41h pSCI/Pos011_S001 (37, 53, 1024, 1024, 2)
22.5h to 41h pSCI/Pos012_S001 (37, 55, 1024, 1024, 2)
22.5h to 41h pSCI/Pos013_S001 (37, 52, 1024, 1024, 2)
22.5h to 41h pSCI/Pos014_S001 (37, 64, 1024, 1024, 2)
22.5h to 41h pSCI/Pos015_S001 (37, 55, 1024, 1024, 2)
22.5h to 41h pSCI/Pos016_S001 (37, 55, 1024, 1024, 2)
22.5h to 41h pSCI/Pos017_S001 (37, 54, 1024, 1024, 2)
22.5h to 41h pSCI/Pos018_S001 (37, 86, 1024, 1024, 2)
22.5h to 41h pSCI/Pos019_S001 (37, 51, 1024, 1024, 2)
22.5h to 41h pSCI/Pos020_S001 (37, 52, 1024, 1024, 2)
22.5h to 41h pSCI/Pos021_S001 (37, 129, 1024, 1024, 2)
22.5h to 41h pSCI/Pos022_S001 (37, 60, 1024, 1024, 2)
22.5h to 41h pSCI/Pos023_S001 (37, 61, 1024, 1024, 2)
22.5h to 41h pSCI/Pos024_S001 (37, 52, 1024, 1024, 2)
22.5h to 41h pSCI/Pos025_S001 (37, 96, 1024, 1024, 2)
22.5h to 41h pSCI/Pos026_S001 (37, 71, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos001_S001 (14, 64, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos002_S001 (14, 63, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos003_S001 (14, 64, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos004_S001 (14, 70, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos005_S001 (14, 64, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos006_S001 (14, 72, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos007_S001 (14, 68, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos008_S001 (14, 62, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos009_S001 (14, 3, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos010_S001 (14, 3, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos011_S001 (14, 65, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos012_S001 (14, 66, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos013_S001 (14, 3, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos014_S001 (14, 63, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos015_S001 (14, 62, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos016_S001 (14, 70, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos017_S001 (14, 65, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos018_S001 (14, 81, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos019_S001 (14, 3, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos020_S001 (14, 3, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos021_S001 (14, 108, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos022_S001 (14, 64, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos023_S001 (14, 61, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos024_S001 (14, 3, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos025_S001 (14, 84, 1024, 1024, 2)
41h to 47.5 hpSCI/Pos026_S001 (14, 69, 1024, 1024, 2)
47.5h to 63hpSCI/Pos001_S001 (31, 64, 1024, 1024, 2)
47.5h to 63hpSCI/Pos002_S001 (31, 63, 1024, 1024, 2)
47.5h to 63hpSCI/Pos003_S001 (31, 64, 1024, 1024, 2)
47.5h to 63hpSCI/Pos004_S001 (31, 70, 1024, 1024, 2)
47.5h to 63hpSCI/Pos005_S001 (31, 64, 1024, 1024, 2)
47.5h to 63hpSCI/Pos006_S001 (31, 72, 1024, 1024, 2)
47.5h to 63hpSCI/Pos007_S001 (31, 68, 1024, 1024, 2)
47.5h to 63hpSCI/Pos008_S001 (31, 62, 1024, 1024, 2)
47.5h to 63hpSCI/Pos009_S001 (31, 3, 1024, 1024, 2)
47.5h to 63hpSCI/Pos010_S001 (31, 3, 1024, 1024, 2)
47.5h to 63hpSCI/Pos011_S001 (31, 65, 1024, 1024, 2)
47.5h to 63hpSCI/Pos012_S001 (31, 66, 1024, 1024, 2)
47.5h to 63hpSCI/Pos013_S001 (31, 3, 1024, 1024, 2)
47.5h to 63hpSCI/Pos014_S001 (31, 63, 1024, 1024, 2)
47.5h to 63hpSCI/Pos015_S001 (31, 62, 1024, 1024, 2)
47.5h to 63hpSCI/Pos016_S001 (31, 70, 1024, 1024, 2)
47.5h to 63hpSCI/Pos017_S001 (31, 65, 1024, 1024, 2)
47.5h to 63hpSCI/Pos018_S001 (31, 81, 1024, 1024, 2)
47.5h to 63hpSCI/Pos019_S001 (31, 3, 1024, 1024, 2)
47.5h to 63hpSCI/Pos020_S001 (31, 3, 1024, 1024, 2)
47.5h to 63hpSCI/Pos021_S001 (31, 108, 1024, 1024, 2)
47.5h to 63hpSCI/Pos022_S001 (31, 64, 1024, 1024, 2)
47.5h to 63hpSCI/Pos023_S001 (31, 61, 1024, 1024, 2)
47.5h to 63hpSCI/Pos024_S001 (31, 3, 1024, 1024, 2)
47.5h to 63hpSCI/Pos025_S001 (31, 84, 1024, 1024, 2)
47.5h to 63hpSCI/Pos026_S001 (31, 69, 1024, 1024, 2)
63 to 72.5hpSCI/Pos001_S001 (20, 64, 1024, 1024, 2)
63 to 72.5hpSCI/Pos002_S001 (20, 63, 1024, 1024, 2)
63 to 72.5hpSCI/Pos003_S001 (20, 64, 1024, 1024, 2)
63 to 72.5hpSCI/Pos004_S001 (20, 70, 1024, 1024, 2)
63 to 72.5hpSCI/Pos005_S001 (20, 64, 1024, 1024, 2)
63 to 72.5hpSCI/Pos006_S001 (20, 72, 1024, 1024, 2)
63 to 72.5hpSCI/Pos007_S001 (20, 68, 1024, 1024, 2)
63 to 72.5hpSCI/Pos008_S001 (20, 62, 1024, 1024, 2)
63 to 72.5hpSCI/Pos009_S001 (20, 3, 1024, 1024, 2)
63 to 72.5hpSCI/Pos010_S001 (20, 3, 1024, 1024, 2)
63 to 72.5hpSCI/Pos011_S001 (20, 65, 1024, 1024, 2)
63 to 72.5hpSCI/Pos012_S001 (20, 66, 1024, 1024, 2)
63 to 72.5hpSCI/Pos013_S001 (20, 3, 1024, 1024, 2)
63 to 72.5hpSCI/Pos014_S001 (20, 63, 1024, 1024, 2)
63 to 72.5hpSCI/Pos015_S001 (20, 62, 1024, 1024, 2)
63 to 72.5hpSCI/Pos016_S001 (20, 70, 1024, 1024, 2)
63 to 72.5hpSCI/Pos017_S001 (20, 65, 1024, 1024, 2)
63 to 72.5hpSCI/Pos018_S001 (20, 81, 1024, 1024, 2)
63 to 72.5hpSCI/Pos019_S001 (20, 3, 1024, 1024, 2)
63 to 72.5hpSCI/Pos020_S001 (20, 3, 1024, 1024, 2)
63 to 72.5hpSCI/Pos021_S001 (20, 108, 1024, 1024, 2)
63 to 72.5hpSCI/Pos022_S001 (20, 64, 1024, 1024, 2)
63 to 72.5hpSCI/Pos023_S001 (20, 61, 1024, 1024, 2)
63 to 72.5hpSCI/Pos024_S001 (20, 3, 1024, 1024, 2)
63 to 72.5hpSCI/Pos025_S001 (20, 84, 1024, 1024, 2)
63 to 72.5hpSCI/Pos026_S001 (20, 69, 1024, 1024, 2)

In [15]:
len(np.arange(0, 17, 0.5))


Out[15]:
34

In [19]:
idx0 = 49
size0 = sizes_tzyxc[idx0]
nt, nz = size0[:2]
image5d0 = np.zeros(size0, np.uint8)
reader.setSeries(idx0)
for t in range(nt):
    for z in range(nz):
        image5d0[t, z] = rdr.read(z=z, t=t, series=idx0, rescale=False)

In [23]:
import vis
vis.cshow(image5d0[..., 0]) # success!


Out[23]:
<matplotlib.image.AxesImage at 0x24755f990>

In [24]:
import sys; sys.path.append('/Users/nuneziglesiasj/projects/lesion/')

In [25]:
squished = image5d0.sum(axis=1)

In [27]:
squished = squished[..., 0]
squished.shape


Out[27]:
(34, 1024, 1024)

In [28]:
from lesion import trace
profiles = [trace.trace_profile(img) for img in squished]


/Users/nuneziglesiasj/anaconda/lib/python2.7/site-packages/numpy/core/_methods.py:55: RuntimeWarning: Mean of empty slice.
  warnings.warn("Mean of empty slice.", RuntimeWarning)
/Users/nuneziglesiasj/anaconda/lib/python2.7/site-packages/numpy/core/_methods.py:65: RuntimeWarning: invalid value encountered in true_divide
  ret, rcount, out=ret, casting='unsafe', subok=False)

In [ ]:
from matplotlib import pyplot as plt
plt.imshow(squished[-1])

In [66]:
def read_image(rdr, idx, sizes):
    size = sizes[idx]
    nt, nz = size[:2]
    image = np.zeros(size[:-1], np.uint8)
    for t in range(nt):
        for z in range(nz):
            image[t, z] = rdr.read(z=z, t=t, c=0, series=idx, rescale=False)
    return image

In [35]:
reader.setSeries(0)
print(sizes_tzyxc[0])
reader.getSizeZ()


(1, 53, 1024, 1024, 2)
Out[35]:
53

In [68]:
im = read_image(rdr, 0, sizes_tzyxc)
im.shape


Out[68]:
(1, 53, 1024, 1024)

In [61]:
def parse_name(name):
    pstart = name.find('Pos') + 3
    pend = pstart + 3
    position = int(name[pstart:pend])
    if name.startswith('Pre'):
        times = np.array([-1.0])
    elif name.startswith('Mark'):
        times = np.array([np.nan])
    else:
        tstart = 0
        tend = min(name.find(' '), name.find('h'))
        t0 = float(name[tstart:tend])
        tstart = name.find('to ') + 3
        tend = name[tstart:].find('h')
        t1 = float(name[tstart:tstart + tend])
        times = np.arange(t0, t1 + 0.01, 0.5)
    return position, times

In [60]:
name = image_names[100]
tstart = 0
tend = min(name.find(' '), name.find('h'))
t0 = float(name[tstart:tend])
tstart = name.find('to ') + 3
tend = name[tstart:].find('h')
tend
print(name, name[tstart:tstart+tend])


('22.5h to 41h pSCI/Pos026_S001', '41')

In [63]:
postimes = map(parse_name, image_names)

In [69]:
def traces_from_image(imt):
    try:
        return [trace.trace_profile(im) for im in imt.sum(axis=1)]
    except:
        return None

In [75]:
imt = read_image(rdr, 100, sizes_tzyxc)
trs = traces_from_image(imt)

In [87]:
postimes[100]


Out[87]:
(26, array([ 22.5,  23. ,  23.5,  24. ,  24.5,  25. ,  25.5,  26. ,  26.5,
         27. ,  27.5,  28. ,  28.5,  29. ,  29.5,  30. ,  30.5,  31. ,
         31.5,  32. ,  32.5,  33. ,  33.5,  34. ,  34.5,  35. ,  35.5,
         36. ,  36.5,  37. ,  37.5,  38. ,  38.5,  39. ,  39.5,  40. ,
         40.5,  41. ]))

In [84]:
squished = imt.sum(axis=1)

In [ ]:
plt.plot(trs[-2])

In [ ]:
vis.cshow(squished[-2])

In [ ]:
prog = [np.min(a) / np.max(a) for a in trs]
plt.plot(prog)

In [88]:
all_traces = []
for series_idx in range(len(image_names)):
    try:
        imt = read_image(rdr, series_idx, sizes_tzyxc)
        trs = traces_from_image(imt)
    except:
        trs = None
    all_traces.append(trs)

In [90]:
len([x for x in all_traces if x is None])


Out[90]:
0

In [92]:
import cPickle as pck
with open('Gfap-traces.pck', 'w') as trs_file:
    pck.dump((postimes, all_traces), trs_file, protocol=-1)

In [93]:
def min_over_max(tr):
    return tr.min() / tr.max()

In [94]:
unique_positions = len(np.unique([pos for pos, time in postimes]))
unique_positions


Out[94]:
26

In [99]:
data = [None] * (unique_positions + 1)
for (pos, times), traces in zip(postimes, all_traces):
    stats = np.array(map(min_over_max, traces))
    xy = np.vstack((times[:len(stats)], stats))
    if data[pos] is None:
        data[pos] = xy
    else:
        data[pos] = np.hstack((data[pos], xy))

In [ ]:
ex = data[2]
sel = ~np.isnan(ex.sum(axis=0))
plt.plot(ex[0, sel], ex[1, sel])

In [128]:
import os
def make_plot(position, xydata, fn=os.path.expanduser('~/Desktop/fig.png')):
    fig = plt.figure(figsize=(7, 5), dpi=600)
    sel = ~np.isnan(xydata.sum(axis=0))
    times, ratios = xydata[:, sel]
    plt.plot(times, ratios, lw=2, c='k')
    for i in range(len(times) - 1):
        diff = times[i+1] - times[i]
        if diff > 0.5:
            print times[i], times[i+1]
            plt.fill_between((times[i] + 0.25, times[i+1] - 0.25), (1, 1),
                              color='k', alpha=0.3)
    plt.xlim(-2, times.max() + 1)
    plt.ylim(max(0, ratios.min() - 0.1), min(1, ratios.max() + 0.1))
    plt.title('Position ' + str(position))
    plt.savefig(fn, dpi=600)
    plt.show()

In [ ]:
make_plot(1, data[1])

In [ ]:
for position in range(1, len(data)):
    make_plot(position, data[position], fn='plots/position%02i.png' % position)

In [ ]:
# Kill the VM at the end! I actually edited this first
# because it's easy to forget!
jv.kill_vm()