-
Notifications
You must be signed in to change notification settings - Fork 0
/
plateproc.py
executable file
·160 lines (144 loc) · 5.78 KB
/
plateproc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/python3
# vim:ts=4:et
# process data sets related to one dish and
# Identify dishes in each time step and align them
#
#and the outDirName/NNN directory and store the results there
# Copyright (C) 2013 Milos Sramek <[email protected]>
# Licensed under the GNU LGPL v3 - http://www.gnu.org/licenses/gpl.html
# - or any later version.
from tifffile import TiffWriter, TiffFile
from importlib import reload
import sys, glob, shutil, os, getopt,time
import imutils
import configparser, imageio
import ipdb
import platealign
import platesegseed
import platesplit
reload(platealign)
reload(platesegseed)
reload(platesplit)
desc="Identify dish and align plates"
outDirName=os.environ.get('APOGWAS_PATH')
inDirName=os.environ.get('APOGWAS_SOURCE_PATH')
dishId=0 # a NNN identifier od a dish
verbose=False
rWidth = 120 # %
namePrefix="apogwas1"
def loadTiff(ifile):
try:
with TiffFile(str(ifile)) as tfile:
vol = tfile.asarray()
return vol
except IOError as err:
return None
def usage(desc):
global inDirName, outDirName, dishId, verbose, rWidth,namePrefix
print(sys.argv[0]+":", desc)
print("Usage: ", sys.argv[0], "[switches]")
print("Switches:")
print("\t-h .......... this usage")
print("\t-v .......... be verbose")
print("\t-s path...... directory with plant scans {taken from the APOGWAS_SOURCE_PATH environment variable}")
print("\t-d path...... directory to store the result to (in a batchX/NNN subdirecory) {taken from the APOGWAS_PATH environment variable}")
print("\t-e string ... file name prefix (%s)"%namePrefix)
print("\t-p NNN ...... ID of a dish (NNN) to start from (all dishes)")
print("\t-w INT ...... region width in %% of inter seed distance (%d %%)"%rWidth)
def parsecmd(desc):
global inDirName, outDirName, dishId, verbose, rWidth, namePrefix
try:
opts, Names = getopt.getopt(sys.argv[1:], "hvd:p:o:w:e:", ["help"])
except getopt.GetoptError as err:
# print help information and exit:
print(str(err)) # will print something like "option -a not recognized"
sys.exit()
for o, a in opts:
if o in ("-h", "--help"):
usage(desc)
sys.exit()
elif o in ("-v"):
verbose=True
elif o in ("-s"):
inDirName = a
elif o in ("-e"):
namePrefix = a
elif o in ("-d"):
outDirName = a
elif o in ("-p"):
dishId = a
elif o in ("-w"):
rWidth = int(a)
def procAll(inDirName, outDirName, dishId, prefix):
global verbose, rWidth
ofpath = "%s/%s/%s"%(outDirName, prefix.replace("apogwas","batch"), dishId)
#reg_file="%s/plant-regions-%s.png"%(outDirName,dishId,dishId)
reg_file="%s/plant-regions-%s.png"%(ofpath,dishId)
if os.path.isfile(reg_file):
if verbose:
print("Skipping dish %s (all done, file %s exists)"%(dishId, reg_file))
return
now = time.strftime("%Y-%b-%d_%H:%M:%S")
reportLogs = configparser.ConfigParser()
try:
reportLogs.read(f"{ofpath}/plateprocsplit.txt")
except:
pass
if verbose:
print("Input directory: %s/%s"%(inDirName,prefix))
print("Output directory/set: %s"%(ofpath))
# align the dishes, first check if a file with aligned dishes exists
plates_file = "%s/plates-%s.tif"%(ofpath,dishId)
plates = loadTiff(plates_file)
if plates is None:
if verbose:
print("Detecting and aligning dishes for set %s*%s in %s"%(prefix,dishId,inDirName))
plates, reportLog = platealign.procPlateSet(inDirName, ofpath, dishId, prefix)
with TiffWriter("%s/plates-%s.tif"%(ofpath, dishId)) as tif: tif.save(plates)
imageio.imwrite("%s/plates-%s.png"%(ofpath, dishId), plates.max(axis=0)[::4,::4,:])
else:
if verbose:
print("Reusing aligned plates: %s"%plates_file)
reportLog = {"Reusing aligned plates": "%s"%plates_file}
reportLogs["platealign %s"%now] = reportLog
# identify seeds, first check if (inverted) file with seed masks exists
mask_file = "%s/seeds-mask-%s.tif"%(ofpath,dishId)
invmask = loadTiff(mask_file)
if invmask is None:
if verbose:
print("Detecting seeds in %s"%plates_file)
#ipdb.set_trace()
mask, reportLog = platesegseed.procPlateSet(plates)
with TiffWriter("%s/seeds-mask-%s.tif"%(ofpath,dishId)) as tif:
tif.save(platesegseed.img3mask(plates[0]+1,1-mask),compress=5)
else:
if verbose:
print("Reusing seed mask: %s"%mask_file)
mask = invmask[...,0] > 0
reportLog = ("Reusing seed mask: %s"%mask_file)
#write in both cases, eventually to reflect manual changes in the seeds-mask file
with TiffWriter("%s/seeds-%s.tif"%(ofpath,dishId)) as tif:
tif.save(platesegseed.img3mask(plates[0],mask),compress=5)
#Save regions
if verbose:
print("Saving regions to %s/%s/%s"%(outDirName, prefix, dishId))
#ipdb.set_trace()
reportLog = platesplit.procPlateSet(ofpath, dishId, plates, mask, rWidth)
reportLogs["platesplit %s"%now] = reportLog
with open("%s/plateprocsplit.txt"%(ofpath), 'w') as reportfile: reportLogs.write(reportfile)
def main():
global inDirName, outDirName, dishId, namePrefix
parsecmd(desc)
outDirName = outDirName if outDirName else inDirName
if dishId:
procAll(inDirName, outDirName, dishId, namePrefix)
else:
for p in range(dishId,200):
dishId = "%03d"%p
# check if dishId images exist
pnames = glob.glob("%s/%s*%s.tif"%(inDirName, namePrefix,dishId))
#ipdb.set_trace()
if pnames == []: continue # no such plant
procAll(inDirName, outDirName, dishId, namePrefix)
if __name__ == "__main__":
main()