annotate tomo_setup.py @ 2:d13fd27cb206 draft

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