comparison tomo_setup.py @ 0:cb1b0d757704 draft

"planemo upload for repository https://github.com/rolfverberg/galaxytools commit 2da52c7db6def807073a1d437a00e0e2a8e7e72e"
author rv43
date Tue, 29 Mar 2022 16:10:16 +0000
parents
children b8977c98800b
comparison
equal deleted inserted replaced
-1:000000000000 0:cb1b0d757704
1 #!/usr/bin/env python3
2
3 import logging
4
5 import os
6 import sys
7 import re
8 import yaml
9 import argparse
10 import numpy as np
11
12 from tomo import Tomo
13 import msnc_tools as msnc
14
15 def __main__():
16
17 # Parse command line arguments
18 parser = argparse.ArgumentParser(
19 description='Setup tomography reconstruction')
20 parser.add_argument('-i', '--inputfiles',
21 default='inputfiles.txt',
22 help='Input file collections')
23 parser.add_argument('-c', '--config',
24 help='Input config')
25 parser.add_argument('--theta_range',
26 help='Theta range (lower bound, upper bound, number of angles)')
27 parser.add_argument('--dark',
28 help='Dark field')
29 parser.add_argument('--bright',
30 help='Bright field')
31 parser.add_argument('--tomo',
32 help='First tomography image')
33 parser.add_argument('--detectorbounds',
34 help='Detector bounds')
35 parser.add_argument('--output_config',
36 help='Output config')
37 parser.add_argument('--output_data',
38 help='Preprocessed tomography data')
39 parser.add_argument('-l', '--log',
40 type=argparse.FileType('w'),
41 default=sys.stdout,
42 help='Log file')
43 parser.add_argument('tomo_ranges', metavar='N', type=int, nargs='+')
44 args = parser.parse_args()
45
46 # Set basic log configuration
47 logging_format = '%(asctime)s : %(levelname)s - %(module)s : %(funcName)s - %(message)s'
48 log_level = 'INFO'
49 level = getattr(logging, log_level.upper(), None)
50 if not isinstance(level, int):
51 raise ValueError(f'Invalid log_level: {log_level}')
52 logging.basicConfig(format=logging_format, level=level, force=True,
53 handlers=[logging.StreamHandler()])
54
55 logging.info(f'config = {args.config}')
56 logging.info(f'theta_range = {args.theta_range.split()}')
57 logging.info(f'dark = {args.dark}')
58 logging.info(f'bright = {args.bright}')
59 logging.info(f'tomo = {args.tomo}')
60 logging.info(f'detectorbounds = {args.detectorbounds}')
61 logging.info(f'output_config = {args.output_config}')
62 logging.info(f'output_data = {args.output_data}')
63 logging.info(f'log = {args.log}')
64 logging.info(f'is log stdout? {args.log is sys.stdout}')
65 logging.info(f'tomoranges = {args.tomo_ranges}')
66
67 # Read input files and collect data files info
68 datasets = []
69 with open(args.inputfiles) as cf:
70 for line in cf:
71 if not line.strip() or line.startswith('#'):
72 continue
73 fields = [x.strip() for x in line.split('\t')]
74 filepath = fields[0]
75 element_identifier = fields[1] if len(fields) > 1 else fields[0].split('/')[-1]
76 datasets.append({'element_identifier' : fields[1], 'filepath' : filepath})
77 logging.debug(f'datasets:\n{datasets}')
78
79 # Read and sort data files
80 collections = []
81 for dataset in datasets:
82 element_identifier = [x.strip() for x in dataset['element_identifier'].split('_')]
83 if len(element_identifier) > 1:
84 name = element_identifier[0]
85 else:
86 name = 'other'
87 filepath = dataset['filepath']
88 if not len(collections):
89 collections = [{'name' : name, 'filepaths' : [filepath]}]
90 else:
91 collection = [c for c in collections if c['name'] == name]
92 if len(collection):
93 collection[0]['filepaths'].append(filepath)
94 else:
95 collection = {'name' : name, 'filepaths' : [filepath]}
96 collections.append(collection)
97 logging.debug(f'collections:\n{collections}')
98 if len(args.tomo_ranges) != 2*len(collections):
99 raise ValueError('Inconsistent tomo ranges size.')
100
101 # Instantiate Tomo object
102 tomo = Tomo(config_file=args.config, config_out=args.output_config, log_level=log_level,
103 log_stream=args.log, galaxy_flag=True)
104 if not tomo.is_valid:
105 raise ValueError('Invalid config file provided.')
106 logging.debug(f'config:\n{tomo.config}')
107
108 # Set theta inputs
109 theta_range = args.theta_range.split()
110 config_theta_range = tomo.config.get('theta_range')
111 if config_theta_range is None:
112 config_tomo.config['theta_range'] = {'start' : float(theta_range[0]),
113 'end' : float(theta_range[1]), 'num' : int(theta_range[2])}
114 else:
115 config_theta_range['start'] = float(theta_range[0])
116 config_theta_range['end'] = float(theta_range[1])
117 config_theta_range['num'] = int(theta_range[2])
118
119 # Find dark field files
120 dark_field = tomo.config['dark_field']
121 tdf_files = [c['filepaths'] for c in collections if c['name'] == 'tdf']
122 if len(tdf_files) != 1 or len(tdf_files[0]) < 1:
123 logging.warning('Unable to obtain dark field files')
124 assert(dark_field['data_path'] is None)
125 assert(dark_field['img_start'] == -1)
126 assert(not dark_field['num'])
127 tdf_files = [None]
128 num_collections = 0
129 else:
130 dark_field['img_offset'] = args.tomo_ranges[0]
131 dark_field['num'] = args.tomo_ranges[1]
132 num_collections = 1
133
134 # Find bright field files
135 bright_field = tomo.config['bright_field']
136 bright_field['img_offset'] = args.tomo_ranges[2*num_collections]
137 bright_field['num'] = args.tomo_ranges[2*num_collections+1]
138 tbf_files = [c['filepaths'] for c in collections if c['name'] == 'tbf']
139 if len(tbf_files) != 1 or len(tbf_files[0]) < 1:
140 exit('Unable to obtain bright field files')
141 num_collections += 1
142
143 # Find tomography files
144 stack_info = tomo.config['stack_info']
145 if stack_info['num'] != len(collections) - num_collections:
146 raise ValueError('Inconsistent number of tomography data image sets')
147 tomo_stack_files = []
148 for stack in stack_info['stacks']:
149 stack['img_offset'] = args.tomo_ranges[2*num_collections]
150 stack['num'] = args.tomo_ranges[2*num_collections+1]
151 tomo_files = [c['filepaths'] for c in collections if c['name'] == f'set{stack["index"]}']
152 if len(tomo_files) != 1 or len(tomo_files[0]) < 1:
153 exit(f'Unable to obtain tomography images for set {stack["index"]}')
154 tomo_stack_files.append(tomo_files[0])
155 num_collections += 1
156
157 # Preprocess the image files
158 tomo.genTomoStacks(tdf_files[0], tbf_files[0], tomo_stack_files, args.dark, args.bright,
159 args.tomo, args.detectorbounds, args.output_data)
160 if not tomo.is_valid:
161 IOError('Unable to load all required image files.')
162
163 if __name__ == "__main__":
164 __main__()
165