Skip to content

Commit

Permalink
Merge pull request #10 from PlethoraChutney/gooey
Browse files Browse the repository at this point in the history
Gooey GUI
  • Loading branch information
PlethoraChutney authored Nov 1, 2021
2 parents 998bb6a + e3ca20d commit 17b7199
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 66 deletions.
7 changes: 7 additions & 0 deletions GUI.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@echo off

python appia.py

if %ERRORLEVEL%==1 (
PAUSE
)
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ to install R and RStudio.
4. *(Optional) Install [R Studio](https://www.rstudio.com/) for easier use of the
manual plot scripts*

## GUI
Appia has a GUI built using [Gooey](https://github.com/chriskiehl/Gooey) which can
be launched by running `appia` with no arguments. If you wish to use the command
line interface instead include `--ignore-gooey`.

## HPLC Processing
Appia reads `.arw` or `.asc` files (from Waters and Shimadzu HPLCs, respectively)
for information about the sample and how it was run, then optionally collects all the indicated
Expand Down
46 changes: 39 additions & 7 deletions appia.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
#!/usr/bin/env python3
import argparse
import logging
from gooey import Gooey, GooeyParser

from parsers.process_parser import parser as process_parser
from parsers.database_parser import parser as db_parser

main_parser = argparse.ArgumentParser(
main_parser = GooeyParser(
description = 'Process chromatography data and visualize it on the web.'
)
subparsers = main_parser.add_subparsers()

main_parser.add_argument(
verbosity = main_parser.add_argument_group('Verbosity')
vxg = verbosity.add_mutually_exclusive_group()
vxg.add_argument(
'-q', '--quiet',
help = 'Print Errors only',
action = 'store_const',
dest = 'verbosity',
const = 'q'
)
vxg.add_argument(
'-v', '--verbose',
help = 'Get more informational messages',
action = 'count',
default = 0
help = 'Print Info, Warnings, and Errors. Default state.',
action = 'store_const',
dest = 'verbosity',
const = 'v'
)
vxg.add_argument(
'--debug',
help = 'Print debug output.',
action = 'store_const',
dest = 'verbosity',
const = 'd'
)

subparsers.add_parser(
name = 'process',
help = 'Process data',
Expand All @@ -27,11 +46,24 @@
parents = [db_parser]
)

@Gooey(
program_name = 'Appia',
default_size = (1080,720)
)
def main():
args = main_parser.parse_args()

levels = [logging.WARNING, logging.INFO, logging.DEBUG]
level = levels[min(len(levels) - 1, args.verbose)]
levels = {
'q': logging.ERROR,
'v': logging.INFO,
'd': logging.DEBUG
}
try:
level = levels[args.verbosity]
except KeyError:
level = logging.INFO
print(level)

logging.basicConfig(
level = level,
format = '{levelname}: {message} ({filename})',
Expand Down
6 changes: 4 additions & 2 deletions parsers/database_parser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argparse
from gooey import GooeyParser
from processors.database import Database, Config
from processors.core import three_column_print

Expand Down Expand Up @@ -26,15 +27,16 @@ def main(args):
exp = db.pull_experiment(id)
exp.save_csvs('.')

parser = argparse.ArgumentParser(
parser = GooeyParser(
description = 'Database management',
add_help=False
)
parser.set_defaults(func = main)
parser.add_argument(
'config',
help = 'Config JSON file',
type = str
type = str,
widget = 'FileChooser'
)
parser.add_argument(
'-l', '--list',
Expand Down
114 changes: 63 additions & 51 deletions parsers/process_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
import subprocess
import shutil
from gooey import GooeyParser
from processors import hplc, fplc, experiment, core
from processors.database import Database, Config
from plotters import auto_plot
Expand Down Expand Up @@ -165,111 +166,122 @@ def main(args):
)


parser = argparse.ArgumentParser(
parser = GooeyParser(
description = 'Process chromatography data',
add_help = False
)
parser.set_defaults(func = main)

file_io = parser.add_argument_group('File IO')

parser.add_argument(
'files',
default = os.path.join(os.getcwd(), '*'),
help = 'Glob or globs to find data files. For instance, "traces/*.arw"',
nargs = '+'
nargs = '+',
widget = 'MultiFileChooser'
)
parser.add_argument(
file_io.add_argument(
'-i', '--id',
help = 'Experiment ID. Default to name of HPLC Sample Set (Waters over Shimadzu, if present) or FPLC file name.',
type = str
)
parser.add_argument(
file_io.add_argument(
'-o', '--output-dir',
help = 'Directory in which to save CSVs and plots. Default makes a new dir with experiment name.'
help = 'Directory in which to save CSVs and plots. Default makes a new dir with experiment name.',
widget = 'DirChooser'
)
parser.add_argument(
'-r', '--reduce',
help = 'Reduce web HPLC data points to this many total. Default 1000. CSV files are saved at full temporal resolution regardless.',
type = int,
default = 1000
file_io.add_argument(
'-k', '--no-move',
help = 'Process data files in place (do not move to new directory)',
action = 'store_true',
default = False
)
parser.add_argument(
'-d', '--database',
help = '''Upload experiment to couchdb. Optionally, provide config file location.
Default config location is "config.json" in appia directory.
Pass "env" to pull from environment variables.''',
dest = 'config',
nargs = '?',
const = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'config.json')
file_io.add_argument(
'-c', '--copy-manual',
help = 'Copy R template file for manual plot editing. Argument is directory relative to Appia root in which templates reside.',
nargs = '?',
const = 'plotters'
)
parser.add_argument(
file_io.add_argument(
'-s', '--post-to-slack',
help = "Send completed plots to Slack. Need a config JSON with slack token and channel.",
nargs = '?',
const = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'config.json'),
widget = 'FileChooser'
)

process_args = parser.add_argument_group('Processing Options')
process_args.add_argument(
'--hplc-flow-rate',
help = 'Manually override flow rate. Provide a single number in mL/min',
type = float
)
parser.add_argument(
process_args.add_argument(
'--fplc-cv',
help = 'Column volume for FPLC data. Default is 24 mL (GE/Cytiva 10/300 column).',
type = int,
default = 24
)
parser.add_argument(
'--overwrite',
help = 'Overwrite database copy of experiment with same name without asking',
action = 'store_true'
)
parser.add_argument(
process_args.add_argument(
'-n', '--normalize',
help = 'Set maximum of this range (in mL) to 1',
nargs = 2,
type = float,
default = [0.5, 1000]
)
parser.add_argument(
process_args.add_argument(
'--strict-normalize',
help = 'Also set minimum of normalization range to 0',
action = 'store_true',
default = False
)
parser.add_argument(
'-k', '--no-move',
help = 'Process data files in place (do not move to new directory)',
action = 'store_true',
default = False
)
parser.add_argument(
process_args.add_argument(
'--channel-mapping',
nargs = '+',
default = ['A', 'Trp', 'B', 'GFP'],
help = 'Channel mappings for Shimadzu instruments. Default: A Trp B GFP'
help = 'Channel mappings for old Shimadzu instruments. Default: A Trp B GFP'
)
parser.add_argument(
'-c', '--copy-manual',
help = 'Copy R template file for manual plot editing. Argument is directory relative to Appia root in which templates reside. No argument uses default `plotters/`.',
nargs = '?',
const = 'plotters'

web_up = parser.add_argument_group('Web Upload')

web_up.add_argument(
'-r', '--reduce',
help = 'Reduce web HPLC data points to this many total. Default 1000. CSV files are saved at full temporal resolution regardless.',
type = int,
default = 1000
)
parser.add_argument(
web_up.add_argument(
'-d', '--database',
help = '''Upload experiment to couchdb. Optionally, provide config file location. Default config location is "config.json" in appia directory. Enter "env" to use environment variables instead.''',
dest = 'config',
nargs = '?',
const = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'config.json'),
widget = 'FileChooser'
)
web_up.add_argument(
'--overwrite',
help = 'Overwrite database copy of experiment with same name without asking',
action = 'store_true'
)

auto_plots = parser.add_argument_group('Auto Plots')
auto_plots.add_argument(
'-p', '--plots',
help = 'Make default plots',
action = 'store_true',
default = False
)
parser.add_argument(
auto_plots.add_argument(
'-f', '--fractions',
nargs = '+',
default = None,
help = 'SEC fractions to fill in. Default is none. Giving two numbers will fill all fractions between those, inclusive. `auto` sets no limit for that side, e.g., -f auto auto fills all fractions. A third N will fill every Nth fraction, e.g., 2 for every other.'
help = 'SEC fractions to fill in. Default is none. Giving two numbers fills inclusive range; a third sets interval. E.g., 2 10 2 fills even fractions between 2 and 10.'
)
parser.add_argument(
auto_plots.add_argument(
'-m', '--ml',
nargs = 2,
default = ['5', '25'],
type = str,
help = 'Inclusive range for auto-plot x-axis, in mL. Default is 5 to 25. To auto-set one limit, type `auto` instead of a number.'
)
parser.add_argument(
'-s', '--post-to-slack',
help = "Send completed plots to Slack. Need a config JSON with slack token and channel.",
nargs = '?',
const = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'config.json')
)

2 changes: 1 addition & 1 deletion process-and-rename.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set /P new_name="Rename experiment to: "

python appia.py -v process ./* --id "%new_name%" --output-dir "%new_name%" --database
python appia.py --ignore-gooey process ./* --id "%new_name%" --output-dir "%new_name%" --database

if %ERRORLEVEL%==1 (
PAUSE
Expand Down
2 changes: 1 addition & 1 deletion process.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@echo off

python appia.py -v process ./* --database
python appia.py --ignore-gooey process ./* --database

if %ERRORLEVEL%==1 (
PAUSE
Expand Down
8 changes: 6 additions & 2 deletions processors/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,13 @@ def reduction_factor(df, num_ponts):
total_points = df.shape[0]
reduction_factor = floor(total_points/num_points)
return df[::reduction_factor]

try:
self.hplc = self.hplc.groupby(['Channel', 'Sample', 'Normalization']).apply(lambda x: reduction_factor(x, num_points))
self.hplc = self.hplc.groupby(
['Channel', 'Sample', 'Normalization'],
as_index = False
).apply(
lambda x: reduction_factor(x, num_points)
)
self.hplc = self.hplc.reset_index(drop = True)
except AttributeError:
return
Expand Down
Binary file modified requirements.txt
Binary file not shown.
4 changes: 2 additions & 2 deletions web.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import logging
import dash
from dash import dependencies
import dash_core_components as dcc
import dash_html_components as html
from dash import dcc
from dash import html
import plotly.express as px
import plotly.graph_objects as go
from urllib.parse import parse_qs
Expand Down

0 comments on commit 17b7199

Please sign in to comment.