forked from junlabucsd/mm3
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmm3_Track-Standard.py
132 lines (108 loc) · 5.07 KB
/
mm3_Track-Standard.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
#!/usr/bin/env python3
from __future__ import print_function, division
import six
# import modules
import sys
import os
import time
import inspect
import argparse
import yaml
from pprint import pprint # for human readable file output
try:
import cPickle as pickle
except:
import pickle
import numpy as np
from scipy.io import savemat
# user modules
# realpath() will make your script run, even if you symlink it
cmd_folder = os.path.realpath(os.path.abspath(
os.path.split(inspect.getfile(inspect.currentframe()))[0]))
if cmd_folder not in sys.path:
sys.path.insert(0, cmd_folder)
# This makes python look for modules in ./external_lib
cmd_subfolder = os.path.realpath(os.path.abspath(
os.path.join(os.path.split(inspect.getfile(
inspect.currentframe()))[0], "external_lib")))
if cmd_subfolder not in sys.path:
sys.path.insert(0, cmd_subfolder)
import mm3_helpers as mm3
# when using this script as a function and not as a library the following will execute
if __name__ == "__main__":
# set switches and parameters
parser = argparse.ArgumentParser(prog='python mm3_Segment.py',
description='Segment cells and create lineages.')
parser.add_argument('-f', '--paramfile', type=str,
required=True, help='Yaml file containing parameters.')
parser.add_argument('-o', '--fov', type=str,
required=False, help='List of fields of view to analyze. Input "1", "1,2,3", or "1-10", etc.')
parser.add_argument('-j', '--nproc', type=int,
required=False, help='Number of processors to use.')
parser.add_argument('-s', '--segmentsource', type=str,
required=False, help='Segmented images to use for tracking. "seg_otsu", "seg_unet", etc.')
namespace = parser.parse_args()
# Load the project parameters file
mm3.information('Loading experiment parameters.')
if namespace.paramfile:
param_file_path = namespace.paramfile
else:
mm3.warning('No param file specified. Using 100X template.')
param_file_path = 'yaml_templates/params_SJ110_100X.yaml'
p = mm3.init_mm3_helpers(param_file_path) # initialized the helper library
if namespace.fov:
if '-' in namespace.fov:
user_spec_fovs = range(int(namespace.fov.split("-")[0]),
int(namespace.fov.split("-")[1])+1)
else:
user_spec_fovs = [int(val) for val in namespace.fov.split(",")]
else:
user_spec_fovs = []
# number of threads for multiprocessing
if namespace.nproc:
p['num_analyzers'] = namespace.nproc
mm3.information('Using {} threads for multiprocessing.'.format(p['num_analyzers']))
# segmentation plane to be used for tracking
if namespace.segmentsource:
p['track']['seg_img'] = namespace.segmentsource
else:
if 'seg_img' not in p['track'].keys():
p['track']['seg_img'] = 'seg_otsu' # default to otsu. Good chance of error.
mm3.information("Using {} images for tracking.".format(p['track']['seg_img']))
# create segmenteation and cell data folder if they don't exist
if not os.path.exists(p['seg_dir']) and p['output'] == 'TIFF':
os.makedirs(p['seg_dir'])
if not os.path.exists(p['cell_dir']):
os.makedirs(p['cell_dir'])
# load specs file
specs = mm3.load_specs()
# make list of FOVs to process (keys of channel_mask file)
fov_id_list = sorted([fov_id for fov_id in specs.keys()])
# remove fovs if the user specified so
if user_spec_fovs:
fov_id_list[:] = [fov for fov in fov_id_list if fov in user_spec_fovs]
### Create cell lineages from segmented images
mm3.information("Creating cell lineages using standard algorithm.")
# Load time table, which goes into params
mm3.load_time_table()
# This dictionary holds information for all cells
Cells = {}
# do lineage creation per fov, so pooling can be done by peak
for fov_id in fov_id_list:
# update will add the output from make_lineages_function, which is a
# dict of Cell entries, into Cells
Cells.update(mm3.make_lineages_fov(fov_id, specs))
mm3.information("Finished lineage creation.")
### Now prune and save the data.
mm3.information("Curating and saving cell data.")
# this returns only cells with a parent and daughters
Complete_Cells = mm3.find_complete_cells(Cells)
### save the cell data. Use the script mm3_OutputData for additional outputs.
# All cell data (includes incomplete cells)
with open(p['cell_dir'] + '/all_cells.pkl', 'wb') as cell_file:
pickle.dump(Cells, cell_file, protocol=pickle.HIGHEST_PROTOCOL)
# Just the complete cells, those with mother and daugther
# This is a dictionary of cell objects.
with open(os.path.join(p['cell_dir'],'complete_cells.pkl'), 'wb') as cell_file:
pickle.dump(Complete_Cells, cell_file, protocol=pickle.HIGHEST_PROTOCOL)
mm3.information("Finished curating and saving cell data.")