# HG changeset patch # User gregor.m # Date 1606223186 0 # Node ID 4d7f30a7e2f6637596f3b24f38586e10aedfaf86 # Parent c59d1373230e60825e42dd79f19f648a4918cb46 "planemo upload commit d070f1ba04a5141a65487f45b29c22767639e44b" diff -r c59d1373230e -r 4d7f30a7e2f6 OutputReport.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OutputReport.html Tue Nov 24 13:06:26 2020 +0000 @@ -0,0 +1,247 @@ + + + SpyBOAT Output Report + + + + + + +

SpyBOAT Results Report

+
+

Distribution Dynamics

+ + +

Output Movie Snapshots

+ + +
+ + +
+ + + +
+

Frame Nr. 2

+ + +
+ +
+

Frame Nr. 18

+ + +
+ +
+

Frame Nr. 34

+ + +
+ +
+

Frame Nr. 50

+ + +
+ +
+

Frame Nr. 66

+ + +
+ +
+

Frame Nr. 82

+ + +
+ + + + + + + + \ No newline at end of file diff -r c59d1373230e -r 4d7f30a7e2f6 SpyBOAT.xml --- a/SpyBOAT.xml Mon Nov 23 14:38:37 2020 +0000 +++ b/SpyBOAT.xml Tue Nov 24 13:06:26 2020 +0000 @@ -1,10 +1,10 @@ - + - spyboat + spyboat - python $__tool_directory__/cl_wrapper.py --version + python $__tool_directory__/spyboat_cli.py --version - + - + + help="Creates a static mask from the chosen frame of the input movie."> {getattr(arguments, arg)}') - -# ------------Read the input---------------------------------------- -try: - movie = spyboat.open_tif(arguments.input_path) -except FileNotFoundError: - logger.critical(f"Couldn't open {arguments.input_path}, check movie storage directory!") - - sys.exit(1) - -# -------- Do (optional) spatial downsampling --------------------------- - -scale_factor = arguments.rescale - -# defaults to None -if not scale_factor: - logger.info('No downsampling requested..') - -elif 0 < scale_factor < 100: - logger.info(f'Downsampling the movie to {scale_factor:d}% of its original size..') - movie = spyboat.down_sample(movie, scale_factor / 100) -else: - raise ValueError('Scale factor must be between 0 and 100!') - -# -------- Do (optional) pre-smoothing ------------------------- -# note that downsampling already is a smoothing operation.. - -# check if pre-smoothing requested -if not arguments.gauss_sigma: - logger.info('No pre-smoothing requested..') -else: - logger.info(f'Pre-smoothing the movie with Gaussians, sigma = {arguments.gauss_sigma:.2f}..') - - movie = spyboat.gaussian_blur(movie, arguments.gauss_sigma) - -# ----- Set up Masking before processing ---- - -mask = None -if arguments.masking == 'fixed': - if not arguments.mask_frame: - logger.critical("Frame number for fixed masking is missing!") - sys.exit(1) - - if (arguments.mask_frame > movie.shape[0]) or (arguments.mask_frame < 0): - logger.critical(f'Requested frame does not exist, input only has {movie.shape[0]} frames.. exiting') - sys.exit(1) - - else: - logger.info(f'Creating fixed mask from frame {arguments.mask_frame} with threshold {arguments.mask_thresh}') - mask = spyboat.create_fixed_mask(movie, arguments.mask_frame, - arguments.mask_thresh) -elif arguments.masking == 'dynamic': - logger.info(f'Creating dynamic mask with threshold {arguments.mask_thresh}') - mask = spyboat.create_dynamic_mask(movie, arguments.mask_thresh) - -else: - logger.info('No masking requested..') - -# ------ Retrieve wavelet parameters --------------------------- - -Wkwargs = {'dt': arguments.dt, - 'Tmin': arguments.Tmin, - 'Tmax': arguments.Tmax, - 'nT': arguments.nT, - 'T_c' : arguments.Tcutoff, # defaults to None - 'win_size' : arguments.win_size # defaults to None -} - -# start parallel processing -results = spyboat.run_parallel(movie, arguments.ncpu, **Wkwargs) - -# --- masking? --- - -if mask is not None: - # mask all output movies (in place!) - for key in results: - logger.info(f'Masking {key}') - spyboat.apply_mask(results[key], mask, fill_value=-1) - -# --- Produce Output Report Figures/png's --- - -# create the directory, yes we have to do that ourselves :) -# galaxy then magically renders the html from that -try: - - if arguments.report_img_path != '.': - logger.info(f'Creating report directory {arguments.report_img_path}') - os.mkdir(arguments.report_img_path) - - # jump to the middle of the movie - snapshot_frame = int(movie.shape[0]/2) - output_report.produce_snapshots(movie, results, snapshot_frame, Wkwargs, img_path=arguments.report_img_path) - - output_report.produce_distr_plots(results, Wkwargs, img_path=arguments.report_img_path) - - output_report.create_html(snapshot_frame, arguments.html_fname) - - -except FileExistsError as e: - logger.critical(f"Could not create html report directory: {repr(e)}") - - -# --- save out result movies --- - -# save phase movie -io.imsave(arguments.phase_out, results['phase'], plugin="tifffile") -logger.info(f'Written {arguments.phase_out}') -# save period movie -io.imsave(arguments.period_out, results['period'], plugin="tifffile") -logger.info(f'Written {arguments.period_out}') -# save power movie -io.imsave(arguments.power_out, results['power'], plugin="tifffile") -logger.info(f'Written {arguments.power_out}') -# save amplitude movie -io.imsave(arguments.amplitude_out, results['amplitude'], plugin="tifffile") -logger.info(f'Written {arguments.amplitude_out}') - -# save out the probably pre-processed (scaled and blurred) input movie for -# direct comparison to results and coordinate mapping etc. -if arguments.preprocessed_out: - io.imsave(arguments.preprocessed_out, movie, plugin='tifffile') - logger.info(f'Written {arguments.preprocessed_out}') diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame0.png Binary file input_frame0.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame16.png Binary file input_frame16.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame18.png Binary file input_frame18.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame2.png Binary file input_frame2.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame20.png Binary file input_frame20.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame32.png Binary file input_frame32.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame34.png Binary file input_frame34.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame40.png Binary file input_frame40.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame48.png Binary file input_frame48.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame50.png Binary file input_frame50.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame60.png Binary file input_frame60.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame64.png Binary file input_frame64.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame66.png Binary file input_frame66.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame80.png Binary file input_frame80.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame82.png Binary file input_frame82.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 input_frame96.png Binary file input_frame96.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 output_report.py --- a/output_report.py Mon Nov 23 14:38:37 2020 +0000 +++ b/output_report.py Tue Nov 24 13:06:26 2020 +0000 @@ -39,11 +39,13 @@ fig = ppl.gcf() out_path = os.path.join(img_path, f'input_frame{frame}.png') fig.savefig(out_path, dpi=DPI) + ppl.close(fig) spyplot.phase_snapshot(results['phase'][frame]) fig = ppl.gcf() out_path = os.path.join(img_path, f'phase_frame{frame}.png') fig.savefig(out_path, dpi=DPI) + ppl.close(fig) spyplot.period_snapshot(results['period'][frame], Wkwargs, @@ -52,13 +54,14 @@ fig = ppl.gcf() out_path = os.path.join(img_path, f'period_frame{frame}.png') fig.savefig(out_path, dpi=DPI) + ppl.close(fig) spyplot.amplitude_snapshot(results['amplitude'][frame]) fig = ppl.gcf() out_path = os.path.join(img_path, f'amplitude_frame{frame}.png') fig.savefig(out_path, dpi=DPI) + ppl.close(fig) - logger.info(f'Produced 4 snapshots for frame {frame}..') def produce_distr_plots(results, Wkwargs, img_path='.'): @@ -87,14 +90,44 @@ logger.info(f'Produced 3 distribution plots..') -def create_html(frame_num, html_fname='OutputReport.html'): +def create_html(frame_nums, html_fname='OutputReport.html'): ''' - The html generated assumes the respective png's (7 in total) + The html generated assumes the respective png's have been created with 'produce_snapshots' and 'produce_distr_plots' and can be found at the cwd (that's how Galaxy works..) ''' + # -- create a gallery for every frame in frame_nums -- + + galleries = '' + for frame_num in frame_nums: + new_gal =f''' +
+

Frame Nr. {frame_num}

+ + +
+ ''' + galleries += new_gal + html_string =f''' SpyBOAT Output Report @@ -105,10 +138,11 @@ body{{ margin:10 100; background:whitesmoke; }} /*body{{ margin:10 100; background:darkslategrey; }}*/ .center{{ + text-align: center; display: block; margin-left: auto; margin-right: auto; - width: 40%;}} + width: 100%;}} /* matplotlib output at 1600x1200 */ .distr_gallery {{ @@ -117,7 +151,7 @@ text-align: center; /* border: 1px dashed rgba(4, 4, 4, 0.35); */ grid-template-columns: repeat(3,1fr); - grid-template-rows: 25vw; + grid-template-rows: 20vw; grid-gap: 0px; column-gap: 0px }} @@ -143,11 +177,16 @@ height: 100%; object-fit: contain; }} + .subheader{{ + text-align:center; + font-size: 160%; + color:#363333;}} -

SpyBOAT Results Report

+

SpyBOAT Results Report


+

Distribution Dynamics

-

Snapshots - Frame {frame_num}

- - + + ''' @@ -196,4 +246,4 @@ return html_string # for local testing -# create_html(125) +# create_html([0,20,40,60,80]) diff -r c59d1373230e -r 4d7f30a7e2f6 period_distr.png Binary file period_distr.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame0.png Binary file period_frame0.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame16.png Binary file period_frame16.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame18.png Binary file period_frame18.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame2.png Binary file period_frame2.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame20.png Binary file period_frame20.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame32.png Binary file period_frame32.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame34.png Binary file period_frame34.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame40.png Binary file period_frame40.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame48.png Binary file period_frame48.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame50.png Binary file period_frame50.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame60.png Binary file period_frame60.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame64.png Binary file period_frame64.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame66.png Binary file period_frame66.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame80.png Binary file period_frame80.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame82.png Binary file period_frame82.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_frame96.png Binary file period_frame96.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 period_twosines_out.tif Binary file period_twosines_out.tif has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_distr.png Binary file phase_distr.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame0.png Binary file phase_frame0.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame16.png Binary file phase_frame16.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame18.png Binary file phase_frame18.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame2.png Binary file phase_frame2.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame20.png Binary file phase_frame20.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame32.png Binary file phase_frame32.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame34.png Binary file phase_frame34.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame40.png Binary file phase_frame40.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame48.png Binary file phase_frame48.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame50.png Binary file phase_frame50.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame60.png Binary file phase_frame60.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame64.png Binary file phase_frame64.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame66.png Binary file phase_frame66.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame80.png Binary file phase_frame80.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame82.png Binary file phase_frame82.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_frame96.png Binary file phase_frame96.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 phase_twosines_out.tif Binary file phase_twosines_out.tif has changed diff -r c59d1373230e -r 4d7f30a7e2f6 power_distr.png Binary file power_distr.png has changed diff -r c59d1373230e -r 4d7f30a7e2f6 power_twosines_out.tif Binary file power_twosines_out.tif has changed diff -r c59d1373230e -r 4d7f30a7e2f6 preproc_two_sines.tif Binary file preproc_two_sines.tif has changed diff -r c59d1373230e -r 4d7f30a7e2f6 run_tests.sh --- a/run_tests.sh Mon Nov 23 14:38:37 2020 +0000 +++ b/run_tests.sh Tue Nov 24 13:06:26 2020 +0000 @@ -1,13 +1,10 @@ #!/usr/bin/env bash -# example command, minimal options: no detrending, -# no rescaling, no masking, no amplitude norm., no blurring INPUT_PATH='./test-data/test-movie.tif' -# INPUT_PATH='./test-data/SCN_L20_Evans2013-half.tif' SCRIPT_PATH='.' -python3 $SCRIPT_PATH/cl_wrapper.py --input_path $INPUT_PATH --phase_out phase_twosines_out.tif --period_out period_twosines_out.tif --power_out power_twosines_out.tif --amplitude_out amplitude_twosines_out.tif --dt .5 --Tmin 20 --Tmax 30 --nT 200 --ncpu 6 --masking dynamic --preprocessed_out preproc_two_sines.tif --gauss_sigma 3 --rescale 50 --Tcutoff 40 --masking fixed --mask_frame 10 --mask_thresh 8 +python3 $SCRIPT_PATH/spyboat_cli.py --input_path $INPUT_PATH --phase_out phase_twosines_out.tif --period_out period_twosines_out.tif --power_out power_twosines_out.tif --amplitude_out amplitude_twosines_out.tif --dt 1 --Tmin 2 --Tmax 30 --nT 200 --ncpu 6 --masking dynamic --preprocessed_out preproc_two_sines.tif --gauss_sigma 3 --rescale 80 --Tcutoff 40 --masking static --mask_frame 10 --mask_thresh 8 printf "\n" # printf "\nError examples:\n" diff -r c59d1373230e -r 4d7f30a7e2f6 spyboat_cli.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spyboat_cli.py Tue Nov 24 13:06:26 2020 +0000 @@ -0,0 +1,210 @@ +#!/usr/bin/env python + +## Gets interfaced by Galaxy or can be used for bash scripting +import argparse +import sys, os +import logging + +from skimage import io +from numpy import float32 + +import spyboat +import output_report + +logging.basicConfig(level=logging.INFO, stream=sys.stdout, force=True) +logger = logging.getLogger('wrapper') + +# ----------command line parameters --------------- + +parser = argparse.ArgumentParser(description='Process some arguments.') + +# I/O +parser.add_argument('--input_path', help="Input movie location", required=True) +parser.add_argument('--phase_out', help='Phase output file name', required=True) +parser.add_argument('--period_out', help='Period output file name', required=True) +parser.add_argument('--power_out', help='Power output file name', required=True) +parser.add_argument('--amplitude_out', help='Amplitude output file name', required=True) +parser.add_argument('--preprocessed_out', help="Preprocessed-input output file name, 'None'", required=False) + + +# (Optional) Multiprocessing + +parser.add_argument('--ncpu', help='Number of processors to use', + required=False, type=int, default=1) + +# Optional spatial downsampling +parser.add_argument('--rescale', help='Rescale the image by a factor given in %%, None means no rescaling', + required=False, type=int) +# Optional Gaussian smoothing +parser.add_argument('--gauss_sigma', help='Gaussian smoothing parameter, None means no smoothing', required=False, type=float) + +# Wavelet Analysis Parameters +parser.add_argument('--dt', help='Sampling interval', required=True, type=float) +parser.add_argument('--Tmin', help='Smallest period', required=True, type=float) +parser.add_argument('--Tmax', help='Biggest period', required=True, type=float) +parser.add_argument('--nT', help='Number of periods to scan for', required=True, type=int) + +parser.add_argument('--Tcutoff', help='Sinc cut-off period, disables detrending if not set', required=False, type=float) +parser.add_argument('--win_size', help='Sliding window size for amplitude normalization, None means no normalization', + required=False, type=float) + +# Optional masking +parser.add_argument('--masking', help="Set to either 'dynamic', 'static' or 'None' which is the default", default='None', required=False, type=str) + +parser.add_argument('--mask_frame', + help="The frame of the input movie to create a static mask from, needs masking set to 'static'", + required=False, type=int) + + +parser.add_argument('--mask_thresh', help='The threshold of the mask, all pixels with less than this value get masked (if masking enabled).', + required=False, type=float, + default=0) + +# output html report/snapshots +parser.add_argument('--html_fname', help="Name of the html report.", + default='OutputReport.html', required=False, type=str) + +parser.add_argument('--report_img_path', help="For the html report, to be set in Galaxy. Without galaxy leave at cwd!", default='.', required=False, type=str) + +parser.add_argument('--version', action='version', version='0.1.0') + +arguments = parser.parse_args() + +logger.info("Received following arguments:") +for arg in vars(arguments): + logger.info(f'{arg} -> {getattr(arguments, arg)}') + +# ------------Read the input---------------------------------------- +try: + movie = spyboat.open_tif(arguments.input_path) +except FileNotFoundError: + logger.critical(f"Couldn't open {arguments.input_path}, check movie storage directory!") + + sys.exit(1) + +# -------- Do (optional) spatial downsampling --------------------------- + +scale_factor = arguments.rescale + +# defaults to None +if not scale_factor: + logger.info('No downsampling requested..') + +elif 0 < scale_factor < 100: + logger.info(f'Downsampling the movie to {scale_factor:d}% of its original size..') + movie = spyboat.down_sample(movie, scale_factor / 100) +else: + raise ValueError('Scale factor must be between 0 and 100!') + +# -------- Do (optional) pre-smoothing ------------------------- +# note that downsampling already is a smoothing operation.. + +# check if pre-smoothing requested +if not arguments.gauss_sigma: + logger.info('No pre-smoothing requested..') +else: + logger.info(f'Pre-smoothing the movie with Gaussians, sigma = {arguments.gauss_sigma:.2f}..') + + movie = spyboat.gaussian_blur(movie, arguments.gauss_sigma) + +# ----- Set up Masking before processing ---- + +mask = None +if arguments.masking == 'static': + if not arguments.mask_frame: + logger.critical("Frame number for static masking is missing!") + sys.exit(1) + + if (arguments.mask_frame > movie.shape[0]) or (arguments.mask_frame < 0): + logger.critical(f'Requested frame does not exist, input only has {movie.shape[0]} frames.. exiting') + sys.exit(1) + + else: + logger.info(f'Creating static mask from frame {arguments.mask_frame} with threshold {arguments.mask_thresh}') + mask = spyboat.create_static_mask(movie, arguments.mask_frame, + arguments.mask_thresh) +elif arguments.masking == 'dynamic': + logger.info(f'Creating dynamic mask with threshold {arguments.mask_thresh}') + mask = spyboat.create_dynamic_mask(movie, arguments.mask_thresh) + +else: + logger.info('No masking requested..') + +# ------ Retrieve wavelet parameters --------------------------- + +Wkwargs = {'dt': arguments.dt, + 'Tmin': arguments.Tmin, + 'Tmax': arguments.Tmax, + 'nT': arguments.nT, + 'T_c' : arguments.Tcutoff, # defaults to None + 'win_size' : arguments.win_size # defaults to None +} + +# --- start parallel processing --- + +results = spyboat.run_parallel(movie, arguments.ncpu, **Wkwargs) + +# --- masking? --- + +if mask is not None: + # mask all output movies (in place!) + for key in results: + logger.info(f'Masking {key}') + spyboat.apply_mask(results[key], mask, fill_value=-1) + +# --- Produce Output HTML Report Figures/png's --- + +# create the directory, yes we have to do that ourselves :) +# galaxy then magically renders the html from that directory +try: + + if arguments.report_img_path != '.': + logger.info(f'Creating report directory {arguments.report_img_path}') + os.mkdir(arguments.report_img_path) + + # make 6 times 4 snapshots each + Nsnap = 6 + NFrames = movie.shape[0] + # show only frames at least one Tmin + # away from the edge (-effects) + start_frame = int(Wkwargs['Tmin']/Wkwargs['dt']) + + if (start_frame > NFrames//2): + logger.warning("Smallest period already is larger than half the observation time!") + # set to 0 in this case + start_frame = 0 + + frame_increment = int( (NFrames - 2*start_frame) / Nsnap) + snapshot_frames = range(start_frame, NFrames - start_frame, frame_increment) + + for snapshot_frame in snapshot_frames: + output_report.produce_snapshots(movie, results, snapshot_frame, Wkwargs, img_path=arguments.report_img_path) + + output_report.produce_distr_plots(results, Wkwargs, img_path=arguments.report_img_path) + + output_report.create_html(snapshot_frames, arguments.html_fname) + +except FileExistsError as e: + logger.critical(f"Could not create html report directory: {repr(e)}") + + +# --- save out result movies --- + +# save phase movie +io.imsave(arguments.phase_out, results['phase'], plugin="tifffile") +logger.info(f'Written {arguments.phase_out}') +# save period movie +io.imsave(arguments.period_out, results['period'], plugin="tifffile") +logger.info(f'Written {arguments.period_out}') +# save power movie +io.imsave(arguments.power_out, results['power'], plugin="tifffile") +logger.info(f'Written {arguments.power_out}') +# save amplitude movie +io.imsave(arguments.amplitude_out, results['amplitude'], plugin="tifffile") +logger.info(f'Written {arguments.amplitude_out}') + +# save out the probably pre-processed (scaled and blurred) input movie for +# direct comparison to results and coordinate mapping etc. +if arguments.preprocessed_out: + io.imsave(arguments.preprocessed_out, movie, plugin='tifffile') + logger.info(f'Written {arguments.preprocessed_out}')