Mercurial > repos > rv43 > tomo
comparison tomo_setup.py @ 60:52db7707ff48 draft
"planemo upload for repository https://github.com/rolfverberg/galaxytools commit 9a07ab3099737ee0d99e82739b55048f89c36bc6-dirty"
author | rv43 |
---|---|
date | Tue, 16 Aug 2022 21:23:10 +0000 |
parents | feb2a5fc7c76 |
children | 75dd6e15f628 |
comparison
equal
deleted
inserted
replaced
59:feb2a5fc7c76 | 60:52db7707ff48 |
---|---|
9 import argparse | 9 import argparse |
10 import numpy as np | 10 import numpy as np |
11 import tracemalloc | 11 import tracemalloc |
12 | 12 |
13 from tomo import Tomo | 13 from tomo import Tomo |
14 from general import get_trailing_int | |
14 | 15 |
15 #from memory_profiler import profile | 16 #from memory_profiler import profile |
16 #@profile | 17 #@profile |
17 def __main__(): | 18 def __main__(): |
18 | 19 |
25 parser.add_argument('--inputfiles', | 26 parser.add_argument('--inputfiles', |
26 default='inputfiles.txt', | 27 default='inputfiles.txt', |
27 help='Input file collections') | 28 help='Input file collections') |
28 parser.add_argument('-c', '--config', | 29 parser.add_argument('-c', '--config', |
29 help='Input config file') | 30 help='Input config file') |
31 parser.add_argument('--detector', | |
32 help='Detector info (number of rows and columns, and pixel size)') | |
30 parser.add_argument('--num_theta', | 33 parser.add_argument('--num_theta', |
31 help='Number of theta angles') | 34 help='Number of theta angles') |
32 parser.add_argument('--theta_range', | 35 parser.add_argument('--theta_range', |
33 help='Theta range (lower bound, upper bound)') | 36 help='Theta range (lower bound, upper bound)') |
34 parser.add_argument('--output_config', | 37 parser.add_argument('--output_config', |
51 if not isinstance(level, int): | 54 if not isinstance(level, int): |
52 raise ValueError(f'Invalid log_level: {log_level}') | 55 raise ValueError(f'Invalid log_level: {log_level}') |
53 logging.basicConfig(format=logging_format, level=level, force=True, | 56 logging.basicConfig(format=logging_format, level=level, force=True, |
54 handlers=[logging.StreamHandler()]) | 57 handlers=[logging.StreamHandler()]) |
55 | 58 |
59 # Check command line arguments | |
56 logging.info(f'config = {args.config}') | 60 logging.info(f'config = {args.config}') |
61 if args.detector is None: | |
62 logging.info(f'detector = {args.detector}') | |
63 else: | |
64 logging.info(f'detector = {args.detector.split()}') | |
57 logging.info(f'num_theta = {args.num_theta}') | 65 logging.info(f'num_theta = {args.num_theta}') |
58 if args.theta_range is None: | 66 if args.theta_range is None: |
59 logging.info(f'theta_range = {args.theta_range}') | 67 logging.info(f'theta_range = {args.theta_range}') |
60 else: | 68 else: |
61 logging.info(f'theta_range = {args.theta_range.split()}') | 69 logging.info(f'theta_range = {args.theta_range.split()}') |
62 logging.info(f'output_config = {args.output_config}') | 70 logging.info(f'output_config = {args.output_config}') |
63 logging.info(f'output_data = {args.output_data}') | 71 logging.info(f'output_data = {args.output_data}') |
64 logging.info(f'log = {args.log}') | 72 logging.info(f'log = {args.log}') |
65 logging.debug(f'is log stdout? {args.log is sys.stdout}') | 73 logging.debug(f'is log stdout? {args.log is sys.stdout}') |
66 | 74 if args.detector is not None and len(args.detector.split()) != 3: |
67 # Read tool config input | 75 raise ValueError(f'Invalid detector: {args.detector}') |
76 if args.num_theta is None or int(args.num_theta) < 1: | |
77 raise ValueError(f'Invalid num_theta: {args.num_theta}') | |
78 if args.theta_range is not None and len(args.theta_range.split()) != 2: | |
79 raise ValueError(f'Invalid theta_range: {args.theta_range}') | |
80 num_theta = int(args.num_theta) | |
81 | |
82 # Read and check tool config input | |
68 inputconfig = [] | 83 inputconfig = [] |
69 with open(args.inputconfig) as f: | 84 with open(args.inputconfig) as f: |
70 inputconfig = [line.strip() for line in f if line.strip() and not line.startswith('#')] | 85 inputconfig = [line.strip() for line in f if line.strip() and not line.startswith('#')] |
71 assert(len(inputconfig) >= 6) | 86 assert(len(inputconfig) >= 6) |
72 config_type = inputconfig[0] | 87 config_type = inputconfig[0] |
76 num_imgs = [int(x.strip()) for x in inputconfig[4].split()] | 91 num_imgs = [int(x.strip()) for x in inputconfig[4].split()] |
77 img_offsets = [int(x.strip()) for x in inputconfig[5].split()] | 92 img_offsets = [int(x.strip()) for x in inputconfig[5].split()] |
78 if config_type == 'config_manual': | 93 if config_type == 'config_manual': |
79 assert(len(inputconfig) == 7) | 94 assert(len(inputconfig) == 7) |
80 ref_heights = [float(x.strip()) for x in inputconfig[6].split()] | 95 ref_heights = [float(x.strip()) for x in inputconfig[6].split()] |
96 assert(args.detector is not None) | |
97 assert(args.theta_range is not None) | |
81 else: | 98 else: |
82 ref_heights = None | 99 ref_heights = None |
83 logging.info(f'config_type = {config_type} {type(config_type)}') | 100 logging.info(f'config_type = {config_type} {type(config_type)}') |
84 logging.info(f'input_type = {input_type} {type(input_type)}') | 101 logging.info(f'input_type = {input_type} {type(input_type)}') |
85 logging.info(f'num_stack = {num_stack} {type(num_stack)}') | 102 logging.info(f'num_stack = {num_stack} {type(num_stack)}') |
86 logging.info(f'stack_types = {stack_types} {type(stack_types)}') | 103 logging.info(f'stack_types = {stack_types} {type(stack_types)}') |
87 logging.info(f'num_imgs = {num_imgs} {type(num_imgs)}') | 104 logging.info(f'num_imgs = {num_imgs} {type(num_imgs)}') |
88 logging.info(f'img_offsets = {img_offsets} {type(img_offsets)}') | 105 logging.info(f'img_offsets = {img_offsets} {type(img_offsets)}') |
89 logging.info(f'ref_heights = {ref_heights} {type(ref_heights)}') | 106 logging.info(f'ref_heights = {ref_heights} {type(ref_heights)}') |
107 if config_type != 'config_file' and config_type != 'config_manual': | |
108 raise ValueError('Invalid input config provided.') | |
109 if input_type != 'collections' and input_type != 'files': | |
110 raise ValueError('Invalid input config provided.') | |
111 if len(stack_types) != num_stack: | |
112 raise ValueError('Invalid input config provided.') | |
113 if len(num_imgs) != num_stack: | |
114 raise ValueError('Invalid input config provided.') | |
115 if len(img_offsets) != num_stack: | |
116 raise ValueError('Invalid input config provided.') | |
117 if ref_heights is not None and len(ref_heights) != num_stack: | |
118 raise ValueError('Invalid input config provided.') | |
90 | 119 |
91 # Read input files and collect data files info | 120 # Read input files and collect data files info |
92 datasets = [] | 121 datasets = [] |
93 with open(args.inputfiles) as f: | 122 with open(args.inputfiles) as f: |
94 for line in f: | 123 for line in f: |
95 if not line.strip() or line.startswith('#'): | 124 if not line.strip() or line.startswith('#'): |
96 continue | 125 continue |
97 fields = [x.strip() for x in line.split('\t')] | 126 fields = [x.strip() for x in line.split('\t')] |
98 filepath = fields[0] | 127 filepath = fields[0] |
99 element_identifier = fields[1] if len(fields) > 1 else fields[0].split('/')[-1] | 128 element_identifier = fields[1] if len(fields) > 1 else fields[0].split('/')[-1] |
100 datasets.append({'element_identifier' : fields[1], 'filepath' : filepath}) | 129 datasets.append({'element_identifier' : element_identifier, 'filepath' : filepath}) |
130 print(f'datasets:\n{datasets}') | |
101 logging.debug(f'datasets:\n{datasets}') | 131 logging.debug(f'datasets:\n{datasets}') |
102 print(f'datasets:\n{datasets}') | 132 if input_type == 'files' and len(datasets) != num_stack: |
133 raise ValueError('Inconsistent number of input files provided.') | |
103 | 134 |
104 # Read and sort data files | 135 # Read and sort data files |
105 collections = [] | 136 collections = [] |
106 for dataset in datasets: | 137 stack_index = 1 |
107 element_identifier = [x.strip() for x in dataset['element_identifier'].split('_')] | 138 for i, dataset in enumerate(datasets): |
108 if len(element_identifier) > 1: | 139 if input_type == 'collections': |
109 name = element_identifier[0] | 140 element_identifier = [x.strip() for x in dataset['element_identifier'].split('_')] |
141 if len(element_identifier) > 1: | |
142 name = element_identifier[0] | |
143 else: | |
144 name = 'other' | |
110 else: | 145 else: |
111 name = 'other' | 146 if stack_types[i] == 'tdf' or stack_types[i] == 'tbf': |
147 name = stack_types[i] | |
148 elif stack_types[i] == 'data': | |
149 name = f'set{stack_index}' | |
150 stack_index += 1 | |
151 else: | |
152 raise ValueError('Invalid input config provided.') | |
112 filepath = dataset['filepath'] | 153 filepath = dataset['filepath'] |
113 print(f'element_identifier = {element_identifier} {len(element_identifier)}') | |
114 print(f'name = {name}') | |
115 print(f'filepath = {filepath}') | |
116 if not len(collections): | 154 if not len(collections): |
117 collections = [{'name' : name, 'filepaths' : [filepath]}] | 155 collections = [{'name' : name, 'filepaths' : [filepath]}] |
118 else: | 156 else: |
119 collection = [c for c in collections if c['name'] == name] | 157 collection = [c for c in collections if c['name'] == name] |
120 if len(collection): | 158 if len(collection): |
121 collection[0]['filepaths'].append(filepath) | 159 collection[0]['filepaths'].append(filepath) |
122 else: | 160 else: |
123 collection = {'name' : name, 'filepaths' : [filepath]} | 161 collection = {'name' : name, 'filepaths' : [filepath]} |
124 collections.append(collection) | 162 collections.append(collection) |
163 print(f'collections:\n{collections}') | |
125 logging.debug(f'collections:\n{collections}') | 164 logging.debug(f'collections:\n{collections}') |
126 print(f'collections:\n{collections}') | |
127 return | |
128 | 165 |
129 # Instantiate Tomo object | 166 # Instantiate Tomo object |
130 tomo = Tomo(config_file=args.config, config_out=args.output_config, log_level=log_level, | 167 tomo = Tomo(config_file=args.config, config_out=args.output_config, log_level=log_level, |
131 log_stream=args.log, galaxy_flag=True) | 168 log_stream=args.log, galaxy_flag=True) |
132 if not tomo.is_valid: | 169 if config_type == 'config_file': |
133 raise ValueError('Invalid config file provided.') | 170 if not tomo.is_valid: |
171 raise ValueError('Invalid config file provided.') | |
172 else: | |
173 assert(tomo.config is None) | |
174 tomo.config = {} | |
134 logging.debug(f'config:\n{tomo.config}') | 175 logging.debug(f'config:\n{tomo.config}') |
135 | 176 |
177 # Set detector inputs | |
178 if config_type == 'config_manual': | |
179 detector = args.detector.split() | |
180 tomo.config['detector'] = {'rows' : int(detector[0]), | |
181 'columns' : int(detector[1]), 'pixel_size' : float(detector[2])} | |
182 | |
136 # Set theta inputs | 183 # Set theta inputs |
137 theta_range = args.theta_range.split() | |
138 config_theta_range = tomo.config.get('theta_range') | 184 config_theta_range = tomo.config.get('theta_range') |
139 if config_theta_range is None: | 185 if config_theta_range is None: |
140 config_tomo.config['theta_range'] = {'start' : float(theta_range[0]), | 186 tomo.config['theta_range'] = {'num' : num_theta} |
141 'end' : float(theta_range[1]), 'num' : int(theta_range[2])} | 187 config_theta_range = tomo.config['theta_range'] |
142 else: | 188 else: |
189 config_theta_range['num'] = num_theta | |
190 if config_type == 'config_manual': | |
191 theta_range = args.theta_range.split() | |
143 config_theta_range['start'] = float(theta_range[0]) | 192 config_theta_range['start'] = float(theta_range[0]) |
144 config_theta_range['end'] = float(theta_range[1]) | 193 config_theta_range['end'] = float(theta_range[1]) |
145 config_theta_range['num'] = int(theta_range[2]) | |
146 | 194 |
147 # Find dark field files | 195 # Find dark field files |
148 dark_field = tomo.config['dark_field'] | 196 dark_field = tomo.config.get('dark_field') |
149 tdf_files = [c['filepaths'] for c in collections if c['name'] == 'tdf'] | 197 tdf_files = [c['filepaths'] for c in collections if c['name'] == 'tdf'] |
150 if len(tdf_files) != 1 or len(tdf_files[0]) < 1: | 198 if len(tdf_files) != 1 or len(tdf_files[0]) < 1: |
151 logging.warning('Unable to obtain dark field files') | 199 logging.warning('Unable to obtain dark field files') |
152 assert(dark_field['data_path'] is None) | 200 if config_type == 'config_file': |
153 assert(dark_field['img_start'] == -1) | 201 assert(dark_field is not None) |
154 assert(not dark_field['num']) | 202 assert(dark_field['data_path'] is None) |
203 assert(dark_field['img_start'] == -1) | |
204 assert(not dark_field['num']) | |
205 else: | |
206 tomo.config['dark_field'] = {'data_path' : None, 'img_start' : -1, 'num' : 0} | |
155 tdf_files = [None] | 207 tdf_files = [None] |
156 num_collections = 0 | 208 num_collections = 0 |
157 else: | 209 else: |
158 dark_field['img_offset'] = args.tomo_ranges[0] | 210 if config_type == 'config_file': |
159 dark_field['num'] = args.tomo_ranges[1] | 211 assert(dark_field is not None) |
212 assert(dark_field['data_path'] is not None) | |
213 assert(dark_field.get('img_start') is not None) | |
214 else: | |
215 tomo.config['dark_field'] = {'data_path' : tdf_files[0], 'img_start' : 0} | |
216 dark_field = tomo.config['dark_field'] | |
217 tdf_index = [i for i,c in enumerate(collections) if c['name'] == 'tdf'] | |
218 tdf_index_check = [i for i,s in enumerate(stack_types) if s == 'tdf'] | |
219 if tdf_index != tdf_index_check: | |
220 raise ValueError(f'Inconsistent tdf_index ({tdf_index} vs. {tdf_index_check}).') | |
221 tdf_index = tdf_index[0] | |
222 dark_field['img_offset'] = img_offsets[tdf_index] | |
223 dark_field['num'] = num_imgs[tdf_index] | |
160 num_collections = 1 | 224 num_collections = 1 |
161 | 225 |
162 # Find bright field files | 226 # Find bright field files |
163 bright_field = tomo.config['bright_field'] | 227 bright_field = tomo.config.get('bright_field') |
164 bright_field['img_offset'] = args.tomo_ranges[2*num_collections] | |
165 bright_field['num'] = args.tomo_ranges[2*num_collections+1] | |
166 tbf_files = [c['filepaths'] for c in collections if c['name'] == 'tbf'] | 228 tbf_files = [c['filepaths'] for c in collections if c['name'] == 'tbf'] |
167 if len(tbf_files) != 1 or len(tbf_files[0]) < 1: | 229 if len(tbf_files) != 1 or len(tbf_files[0]) < 1: |
168 exit('Unable to obtain bright field files') | 230 exit('Unable to obtain bright field files') |
231 if config_type == 'config_file': | |
232 assert(bright_field is not None) | |
233 assert(bright_field['data_path'] is not None) | |
234 assert(bright_field.get('img_start') is not None) | |
235 else: | |
236 tomo.config['bright_field'] = {'data_path' : tbf_files[0], 'img_start' : 0} | |
237 bright_field = tomo.config['bright_field'] | |
238 tbf_index = [i for i,c in enumerate(collections) if c['name'] == 'tbf'] | |
239 tbf_index_check = [i for i,s in enumerate(stack_types) if s == 'tbf'] | |
240 if tbf_index != tbf_index_check: | |
241 raise ValueError(f'Inconsistent tbf_index ({tbf_index} vs. {tbf_index_check}).') | |
242 tbf_index = tbf_index[0] | |
243 bright_field['img_offset'] = img_offsets[tbf_index] | |
244 bright_field['num'] = num_imgs[tbf_index] | |
169 num_collections += 1 | 245 num_collections += 1 |
170 | 246 |
171 # Find tomography files | 247 # Find tomography files |
172 stack_info = tomo.config['stack_info'] | 248 stack_info = tomo.config.get('stack_info') |
173 if stack_info['num'] != len(collections) - num_collections: | 249 if config_type == 'config_file': |
174 raise ValueError('Inconsistent number of tomography data image sets') | 250 assert(stack_info is not None) |
251 if stack_info['num'] != len(collections) - num_collections: | |
252 raise ValueError('Inconsistent number of tomography data image sets') | |
253 assert(stack_info.get('stacks') is not None) | |
254 for stack in stack_info['stacks']: | |
255 assert(stack['data_path'] is not None) | |
256 assert(stack.get('img_start') is not None) | |
257 assert(stack.get('index') is not None) | |
258 assert(stack.get('ref_height') is not None) | |
259 else: | |
260 tomo.config['stack_info'] = {'num' : len(collections) - num_collections, 'stacks' : []} | |
261 stack_info = tomo.config['stack_info'] | |
262 for i in range(stack_info['num']): | |
263 stack_info['stacks'].append({'img_start' : 0, 'index' : i+1}) | |
175 tomo_stack_files = [] | 264 tomo_stack_files = [] |
176 for stack in stack_info['stacks']: | 265 for stack in stack_info['stacks']: |
177 stack['img_offset'] = args.tomo_ranges[2*num_collections] | 266 index = stack['index'] |
178 stack['num'] = args.tomo_ranges[2*num_collections+1] | 267 tomo_files = [c['filepaths'] for c in collections if c['name'] == f'set{index}'] |
179 tomo_files = [c['filepaths'] for c in collections if c['name'] == f'set{stack["index"]}'] | |
180 if len(tomo_files) != 1 or len(tomo_files[0]) < 1: | 268 if len(tomo_files) != 1 or len(tomo_files[0]) < 1: |
181 exit(f'Unable to obtain tomography images for set {stack["index"]}') | 269 exit(f'Unable to obtain tomography images for set {index}') |
270 tomo_index = [i for i,c in enumerate(collections) if c['name'] == f'set{index}'] | |
271 if len(tomo_index) != 1: | |
272 raise ValueError(f'Illegal tomo_index ({tomo_index}).') | |
273 tomo_index = tomo_index[0] | |
274 stack['img_offset'] = img_offsets[tomo_index] | |
275 assert(num_imgs[tomo_index] == -1) | |
276 stack['num'] = num_theta | |
277 if config_type == 'config_manual': | |
278 if len(tomo_files) == 1: | |
279 stack['data_path'] = tomo_files[0] | |
280 stack['ref_height'] = ref_heights[tomo_index] | |
182 tomo_stack_files.append(tomo_files[0]) | 281 tomo_stack_files.append(tomo_files[0]) |
183 num_collections += 1 | 282 num_collections += 1 |
283 if num_collections != num_stack: | |
284 raise ValueError('Inconsistent number of data image sets') | |
285 print(f'config:\n{tomo.config}') | |
286 return | |
184 | 287 |
185 # Preprocess the image files | 288 # Preprocess the image files |
186 galaxy_param = {'tdf_files' : tdf_files[0], 'tbf_files' : tbf_files[0], | 289 galaxy_param = {'tdf_files' : tdf_files[0], 'tbf_files' : tbf_files[0], |
187 'tomo_stack_files' : tomo_stack_files, 'output_name' : args.output_data} | 290 'tomo_stack_files' : tomo_stack_files, 'output_name' : args.output_data} |
188 tomo.genTomoStacks(galaxy_param) | 291 tomo.genTomoStacks(galaxy_param) |