Mercurial > repos > gregor.m > spyboat
comparison cl_wrapper.py @ 0:1d62de03829d draft
"planemo upload commit c6cd06d44dce1eef9136017289d362f144687dc1"
| author | gregor.m |
|---|---|
| date | Mon, 23 Nov 2020 13:31:47 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:1d62de03829d |
|---|---|
| 1 #!/usr/bin/env python | |
| 2 | |
| 3 ## Gets interfaced by Galaxy or bash scripting | |
| 4 import argparse | |
| 5 import sys, os | |
| 6 import logging | |
| 7 | |
| 8 from skimage import io | |
| 9 from numpy import float32 | |
| 10 | |
| 11 import spyboat | |
| 12 import output_report | |
| 13 | |
| 14 logging.basicConfig(level=logging.INFO, stream=sys.stdout, force=True) | |
| 15 logger = logging.getLogger('wrapper') | |
| 16 | |
| 17 # ----------command line parameters --------------- | |
| 18 | |
| 19 parser = argparse.ArgumentParser(description='Process some arguments.') | |
| 20 | |
| 21 # I/O | |
| 22 parser.add_argument('--input_path', help="Input movie location", required=True) | |
| 23 parser.add_argument('--phase_out', help='Phase output file name', required=True) | |
| 24 parser.add_argument('--period_out', help='Period output file name', required=True) | |
| 25 parser.add_argument('--power_out', help='Power output file name', required=True) | |
| 26 parser.add_argument('--amplitude_out', help='Amplitude output file name', required=True) | |
| 27 parser.add_argument('--preprocessed_out', help="Preprocessed-input output file name, 'None'", required=False) | |
| 28 | |
| 29 | |
| 30 # (Optional) Multiprocessing | |
| 31 | |
| 32 parser.add_argument('--ncpu', help='Number of processors to use', | |
| 33 required=False, type=int, default=1) | |
| 34 | |
| 35 # Optional spatial downsampling | |
| 36 parser.add_argument('--rescale', help='Rescale the image by a factor given in %%, None means no rescaling', | |
| 37 required=False, type=int) | |
| 38 # Optional Gaussian smoothing | |
| 39 parser.add_argument('--gauss_sigma', help='Gaussian smoothing parameter, None means no smoothing', required=False, type=float) | |
| 40 | |
| 41 # Wavelet Analysis Parameters | |
| 42 parser.add_argument('--dt', help='Sampling interval', required=True, type=float) | |
| 43 parser.add_argument('--Tmin', help='Smallest period', required=True, type=float) | |
| 44 parser.add_argument('--Tmax', help='Biggest period', required=True, type=float) | |
| 45 parser.add_argument('--nT', help='Number of periods to scan for', required=True, type=int) | |
| 46 | |
| 47 parser.add_argument('--Tcutoff', help='Sinc cut-off period, disables detrending if not set', required=False, type=float) | |
| 48 parser.add_argument('--win_size', help='Sliding window size for amplitude normalization, None means no normalization', | |
| 49 required=False, type=float) | |
| 50 | |
| 51 # Optional masking | |
| 52 parser.add_argument('--masking', help="Set to either 'dynamic', 'fixed' or 'None' which is the default", default='None', required=False, type=str) | |
| 53 | |
| 54 parser.add_argument('--mask_frame', | |
| 55 help="The frame of the input movie to create a fixed mask from, needs masking set to 'fixed'", | |
| 56 required=False, type=int) | |
| 57 | |
| 58 | |
| 59 parser.add_argument('--mask_thresh', help='The threshold of the mask, all pixels with less than this value get masked (if masking enabled).', | |
| 60 required=False, type=float, | |
| 61 default=0) | |
| 62 | |
| 63 # output overview/snapshots | |
| 64 parser.add_argument('--html_fname', help="Name of the html report.", | |
| 65 default='OutputReport.html', required=False, type=str) | |
| 66 | |
| 67 parser.add_argument('--report_img_path', help="For the html report, can be set in Galaxy. Defaults to cwd.", default='.', required=False, type=str) | |
| 68 | |
| 69 parser.add_argument('--version', action='version', version='0.0.1') | |
| 70 | |
| 71 arguments = parser.parse_args() | |
| 72 | |
| 73 logger.info("Received following arguments:") | |
| 74 for arg in vars(arguments): | |
| 75 logger.info(f'{arg} -> {getattr(arguments, arg)}') | |
| 76 | |
| 77 # ------------Read the input---------------------------------------- | |
| 78 try: | |
| 79 movie = spyboat.open_tif(arguments.input_path) | |
| 80 except FileNotFoundError: | |
| 81 logger.critical(f"Couldn't open {arguments.input_path}, check movie storage directory!") | |
| 82 | |
| 83 sys.exit(1) | |
| 84 | |
| 85 # -------- Do (optional) spatial downsampling --------------------------- | |
| 86 | |
| 87 scale_factor = arguments.rescale | |
| 88 | |
| 89 # defaults to None | |
| 90 if not scale_factor: | |
| 91 logger.info('No downsampling requested..') | |
| 92 | |
| 93 elif 0 < scale_factor < 100: | |
| 94 logger.info(f'Downsampling the movie to {scale_factor:d}% of its original size..') | |
| 95 movie = spyboat.down_sample(movie, scale_factor / 100) | |
| 96 else: | |
| 97 raise ValueError('Scale factor must be between 0 and 100!') | |
| 98 | |
| 99 # -------- Do (optional) pre-smoothing ------------------------- | |
| 100 # note that downsampling already is a smoothing operation.. | |
| 101 | |
| 102 # check if pre-smoothing requested | |
| 103 if not arguments.gauss_sigma: | |
| 104 logger.info('No pre-smoothing requested..') | |
| 105 else: | |
| 106 logger.info(f'Pre-smoothing the movie with Gaussians, sigma = {arguments.gauss_sigma:.2f}..') | |
| 107 | |
| 108 movie = spyboat.gaussian_blur(movie, arguments.gauss_sigma) | |
| 109 | |
| 110 # ----- Set up Masking before processing ---- | |
| 111 | |
| 112 mask = None | |
| 113 if arguments.masking == 'fixed': | |
| 114 if not arguments.mask_frame: | |
| 115 logger.critical("Frame number for fixed masking is missing!") | |
| 116 sys.exit(1) | |
| 117 | |
| 118 if (arguments.mask_frame > movie.shape[0]) or (arguments.mask_frame < 0): | |
| 119 logger.critical(f'Requested frame does not exist, input only has {movie.shape[0]} frames.. exiting') | |
| 120 sys.exit(1) | |
| 121 | |
| 122 else: | |
| 123 logger.info(f'Creating fixed mask from frame {arguments.mask_frame} with threshold {arguments.mask_thresh}') | |
| 124 mask = spyboat.create_fixed_mask(movie, arguments.mask_frame, | |
| 125 arguments.mask_thresh) | |
| 126 elif arguments.masking == 'dynamic': | |
| 127 logger.info(f'Creating dynamic mask with threshold {arguments.mask_thresh}') | |
| 128 mask = spyboat.create_dynamic_mask(movie, arguments.mask_thresh) | |
| 129 | |
| 130 else: | |
| 131 logger.info('No masking requested..') | |
| 132 | |
| 133 # ------ Retrieve wavelet parameters --------------------------- | |
| 134 | |
| 135 Wkwargs = {'dt': arguments.dt, | |
| 136 'Tmin': arguments.Tmin, | |
| 137 'Tmax': arguments.Tmax, | |
| 138 'nT': arguments.nT, | |
| 139 'T_c' : arguments.Tcutoff, # defaults to None | |
| 140 'win_size' : arguments.win_size # defaults to None | |
| 141 } | |
| 142 | |
| 143 # start parallel processing | |
| 144 results = spyboat.run_parallel(movie, arguments.ncpu, **Wkwargs) | |
| 145 | |
| 146 # --- masking? --- | |
| 147 | |
| 148 if mask is not None: | |
| 149 # mask all output movies (in place!) | |
| 150 for key in results: | |
| 151 logger.info(f'Masking {key}') | |
| 152 spyboat.apply_mask(results[key], mask, fill_value=-1) | |
| 153 | |
| 154 # --- Produce Output Report Figures/png's --- | |
| 155 | |
| 156 # create the directory, yes we have to do that ourselves :) | |
| 157 # galaxy then magically renders the html from that | |
| 158 try: | |
| 159 | |
| 160 if arguments.report_img_path != '.': | |
| 161 logger.info(f'Creating report directory {arguments.report_img_path}') | |
| 162 os.mkdir(arguments.report_img_path) | |
| 163 | |
| 164 # jump to the middle of the movie | |
| 165 snapshot_frame = int(movie.shape[0]/2) | |
| 166 output_report.produce_snapshots(movie, results, snapshot_frame, Wkwargs, img_path=arguments.report_img_path) | |
| 167 | |
| 168 output_report.produce_distr_plots(results, Wkwargs, img_path=arguments.report_img_path) | |
| 169 | |
| 170 output_report.create_html(snapshot_frame, arguments.html_fname) | |
| 171 | |
| 172 | |
| 173 except FileExistsError as e: | |
| 174 logger.critical(f"Could not create html report directory: {repr(e)}") | |
| 175 | |
| 176 | |
| 177 # --- save out result movies --- | |
| 178 | |
| 179 # save phase movie | |
| 180 io.imsave(arguments.phase_out, results['phase'], plugin="tifffile") | |
| 181 logger.info(f'Written {arguments.phase_out}') | |
| 182 # save period movie | |
| 183 io.imsave(arguments.period_out, results['period'], plugin="tifffile") | |
| 184 logger.info(f'Written {arguments.period_out}') | |
| 185 # save power movie | |
| 186 io.imsave(arguments.power_out, results['power'], plugin="tifffile") | |
| 187 logger.info(f'Written {arguments.power_out}') | |
| 188 # save amplitude movie | |
| 189 io.imsave(arguments.amplitude_out, results['amplitude'], plugin="tifffile") | |
| 190 logger.info(f'Written {arguments.amplitude_out}') | |
| 191 | |
| 192 # save out the probably pre-processed (scaled and blurred) input movie for | |
| 193 # direct comparison to results and coordinate mapping etc. | |
| 194 if arguments.preprocessed_out: | |
| 195 io.imsave(arguments.preprocessed_out, movie, plugin='tifffile') | |
| 196 logger.info(f'Written {arguments.preprocessed_out}') |
