Newer
Older
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
import os
import argparse
from subprocess import check_output, call
from scripts.attributes import make_cell_tables, make_nucleus_tables
from scripts.export import export_segmentation
from scripts.files import copy_tables, copy_segmentation, copy_static_files
# paths for paintera projects
# in order to get the new segmentation, changes need to be committed,
# s.t. they are stored in these files!
PAINTERA_ROOT = '/g/kreshuk/data/arendt/platyneris_v1/data.n5'
# TODO do we need the data postfix ???
PROJECT_CELLS = 'volumes/paintera/proofread_cells/data'
PROJECT_NUCLEI = 'volumes/paintera/nuclei/data'
# name for cell and nucleus segmentations
NAME_CELLS = 'em-segmented-cells-labels'
NAME_NUCLEI = 'em-segmented-nuclei-labels'
def check_inputs(update_cell_segmentation,
update_nucleus_segmentation,
update_cell_tables,
update_nucleus_tables):
inputs = (update_cell_segmentation, update_nucleus_segmentation,
update_cell_tables, update_nucleus_tables)
have_changes = any(inputs)
if update_cell_segmentation:
update_cell_tables = True
if update_nucleus_segmentation:
update_nucleus_tables = True
return have_changes, update_cell_tables, update_nucleus_tables
def get_tags():
tag = check_output(['git', 'describe', '--tags']).decode('utf-8').rstrip('\n')
new_tag = tag.split('.')
new_tag[-1] = str(int(new_tag[-1]) + 1)
new_tag = '.'.join(new_tag)
return tag, new_tag
def make_folder_structure(tag):
new_folder = os.makedirs('data', tag)
# make all sub-folders
os.makedirs(os.path.join(new_folder, 'tables'))
os.makedirs(os.path.join(new_folder, 'images'))
os.makedirs(os.path.join(new_folder, 'segmentations'))
os.makedirs(os.path.join(new_folder, 'misc'))
return new_folder
# TODO
# need lut from new to old segmentation ids
# to auto translate custom attributes
# also support extraction from paintera commit
def export_segmentations(folder, new_folder,
update_cell_segmentation,
update_nucleus_segmentation):
# update or copy cell segmentation
if update_cell_segmentation:
export_segmentation(PAINTERA_ROOT, PROJECT_CELLS,
folder, new_folder, NAME_CELLS,
resolution=[.025, .02, .02])
else:
copy_segmentation(folder, new_folder, NAME_CELLS)
# update or copy nucleus segmentation
if update_nucleus_segmentation:
export_segmentation(PAINTERA_ROOT, PROJECT_NUCLEI,
folder, new_folder, NAME_NUCLEI,
resolution=[.1, .08, .08])
else:
copy_segmentation(folder, new_folder, NAME_NUCLEI)
def make_attributes(folder, new_folder,
update_cell_tables, update_nucleus_tables):
# update or copy cell tables
if update_cell_tables:
make_cell_tables(new_folder, NAME_CELLS)
else:
copy_tables(folder, new_folder, NAME_CELLS)
# update or copy nucleus tables
if update_nucleus_tables:
make_nucleus_tables(new_folder, NAME_NUCLEI)
else:
copy_tables(folder, new_folder, NAME_NUCLEI)
# TODO check for errors
def make_release(tag, description=''):
call(['git', 'commit', '-m', 'Automatic platybrowser update'])
if description == '':
call(['git', 'tag', tag])
else:
call(['git', '-m', description, 'tag', tag])
# TODO autopush ???
# call(['git', 'push', 'origin', 'master', '--tags'])
# TODO catch all exceptions and re-roll if exception was caught
def update_platy_browser(update_cell_segmentation=False,
update_nucleus_segmentation=False,
update_cell_tables=False,
update_nucleus_tables=False,
description=''):
""" Generate new version of platy-browser derived data.
Arguments:
update_cell_segmentation: Update the cell segmentation volume.
update_nucleus_segmentation: Update the nucleus segmentation volume.
update_cell_tables: Update the cell tables. This needs to be specified if the cell
segmentation is not update, but the tables should be updated.
update_nucleus_tables: Update the nucleus tables. This needs to be specified if the nucleus
segmentation is not updated, but the tables should be updated.
description: Optional descrption for release message.
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
"""
# check inputs
have_changes, update_cell_tables, update_nucleus_tables = check_inputs(update_cell_segmentation,
update_nucleus_segmentation,
update_cell_tables,
update_nucleus_tables)
if not have_changes:
print("Nothing needs to be update, skipping ")
return
# we always increase the release tag (in the last digit)
# when making a new version of segmentation or attributes
tag, new_tag = get_tags()
# make new folder structure
folder = os.path.join('data', tag)
new_folder = make_folder_structure(new_tag)
# export new segmentation(s)
export_segmentations(folder, new_folder,
update_cell_segmentation,
update_nucleus_segmentation)
# generate new attribute tables (if necessary)
make_attributes(folder, new_folder,
update_cell_tables,
update_nucleus_tables)
# copy files that were not touched
copy_static_files(folder, new_folder)
# make new release
make_release(new_tag, description)
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')
def table_help_str(name):
help_str = """Update the %s tables.
Only needs to be specified if the %s segmentation is not updated,
but the tables should be updated."""
return help_str % (name, name)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Update derived data for the platy browser')
parser.add_argument('--update_cell_segmentation', type=str2bool,
default=False, help="Update the cell segmentation.")
parser.add_argument('--update_nucleus_segmentation', type=str2bool,
default=False, help="Update the nucleus segmentation.")
parser.add_argument('--update_cell_tables', type=str2bool,
default=False, help=table_help_str("cell"))
parser.add_argument('--update_nucleus_tables', type=str2bool,
default=False, help=table_help_str("nucleus"))
parser.add_argument('--description', type=str, default='',
help="Optional description for release message")
args = parser.parse_args()
update_platy_browser(args.update_cell_segmentation,
args.update_nucleus_segmentation,
args.update_cell_tables,
args.update_nucleus_tables,
args.description)