Skip to content

Commit

Permalink
integrate documentation of the command line interface
Browse files Browse the repository at this point in the history
  • Loading branch information
rgutzen committed Oct 30, 2023
1 parent 4db1a9a commit 6e425c0
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 82 deletions.
3 changes: 1 addition & 2 deletions ACKNOWLEDGEMENTS
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
This research has been co-funded by:
- the European Union’s Horizon 2020 Framework Programme for Research and Innovation under the
Specific Grant Agreement No. 945539 (Human Brain Project SGA3) and No. 785907 (Human Brain Project SGA2);
- the European Union’s Horizon 2020 Framework Programme for Research and Innovation under the Specific Grant Agreement No. 945539 (Human Brain Project SGA3) and No. 785907 (Human Brain Project SGA2);
- the European Commission-NextGeneration EU (MUR CUP B51E22000150006), project "EBRAINS-Italy PNNR".
3 changes: 1 addition & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ Collaborative Brain Wave Analysis Pipeline (Cobrawap)
:target: https://cobrawap.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
:align: left
|
|


.. image:: https://raw.githubusercontent.com/INM-6/cobrawap/master/doc/images/cobrawap_logo.png
:height: 150px
Expand Down
130 changes: 89 additions & 41 deletions cobrawap/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
import re
from pprint import pformat
from pathlib import Path
sys.path.append(str(Path(__file__).parent))
sys.path.append(str(Path(__file__).parents[1] / 'pipeline'))
import inspect
sys.path.append(str(Path(inspect.getfile(lambda: None)).parent))
sys.path.append(str(Path(inspect.getfile(lambda: None)).parents[1] / 'cobrawap'))
sys.path.append(str(Path(inspect.getfile(lambda: None)).parents[1] / 'pipeline'))
from cmd_utils import get_setting, set_setting, get_initial_available_stages
from cmd_utils import is_profile_name_valid, create_new_configfile
from cmd_utils import input_profile, get_profile, setup_entry_stage
Expand All @@ -36,6 +38,9 @@

CLI = argparse.ArgumentParser(prog='cobrawap')

def get_parser():
return CLI

# Utility arguments
CLI.add_argument("-v", "--verbose", action='store_true',
help="print additional logging information")
Expand Down Expand Up @@ -92,18 +97,27 @@
'input and with the specified configurations')
CLI_run.set_defaults(command='run')
CLI_run.add_argument("--profile", type=str, nargs='?', default=None,
help="profile name of the dataset to be analyzed")
CLI_run.add_argument("--stage", type=str, nargs='?', default=None,
choices=list(STAGES.keys()),
help="select individual stage to execute; "\
"runs all if not specified [default: run all]")
help="name of the config profile to be analyzed")

# Stage
CLI_stage = subparsers.add_parser('run_stage',
help='execute an individual stage')
CLI_stage.set_defaults(command='run_stage')
CLI_stage.add_argument("--profile", type=str, nargs='?', default=None,
help="name of the config profile to be analyzed")
CLI_stage.add_argument("--stage", type=str, nargs='?', default=None,
choices=list(STAGES.keys()),
help="select individual stage to execute")

# Block
CLI_block = subparsers.add_parser('run_block',
help='execute an individual block method on some input')
CLI_block.set_defaults(command='run_block')
CLI_block.add_argument("block", type=str, nargs='?', default=None,
help="block specified as <stage_name>.<block_name>")
CLI_block.add_argument("block_help", action='store_true',
help="display the help text of the block script")


def main():
'Start main CLI entry point.'
Expand Down Expand Up @@ -131,9 +145,13 @@ def main():
log.info("executing Cobrawap")
run(**vars(args), extra_args=unknown)

elif args.command == 'run_stage':
log.info("executing Cobrawap stage")
run_stage(**vars(args), extra_args=unknown)

elif args.command == 'run_block':
log.info("executing Cobrawap block")
run_block(block=args.block, block_args=unknown)
run_block(**vars(args), block_args=unknown)

else:
log.info(f"{args.command} not known!")
Expand Down Expand Up @@ -219,8 +237,8 @@ def create(profile=None, parent_profile=None, data_path=None,
return None


def add_profile(profile=None, parent_profile=None, data_path=None,
stages=None, loading_script_name=None, **kwargs):
def add_profile(profile=None, parent_profile=None, stages=None,
data_path=None, loading_script_name=None, **kwargs):
profile, parent_profile = get_profile(profile=profile,
parent_profile=parent_profile)
# get stage selection
Expand Down Expand Up @@ -248,7 +266,7 @@ def add_profile(profile=None, parent_profile=None, data_path=None,
return None


def run(profile=None, stage=None, extra_args=None, **kwargs):
def run(profile=None, extra_args=None, **kwargs):
# select profile
if not is_profile_name_valid(profile) and profile is not None:
log.info(f"profile name {profile} is not valid!")
Expand All @@ -258,36 +276,64 @@ def run(profile=None, stage=None, extra_args=None, **kwargs):

# set runtime config
pipeline_path = Path(get_setting('pipeline_path'))

# execute snakemake
snakemake_args = ['snakemake','-c1','--config',f'PROFILE={profile}']
log.info(f'Executing `{" ".join(snakemake_args+extra_args)}`')

with working_directory(pipeline_path):
subprocess.run(snakemake_args + extra_args)

return None


def run_stage(profile=None, stage=None, extra_args=None, **kwargs):
# select profile
if not is_profile_name_valid(profile) and profile is not None:
log.info(f"profile name {profile} is not valid!")
profile = None
if profile is None:
profile = input_profile()

# get settings
pipeline_path = Path(get_setting('pipeline_path'))
config_path = Path(get_setting('config_path'))
output_path = Path(get_setting('output_path'))
stages = get_setting('stages')

# select stage
if stage:
stages = get_setting('stages')
stage = stages[stage]
config_path = Path(get_setting('config_path'))
output_path = Path(get_setting('output_path'))

# lookup stage input file
pipeline_config_path = config_path / 'configs' / 'config.yaml'
config_dict = load_config_file(pipeline_config_path)
stage_idx = locate_str_in_list(config_dict['STAGES'], stage)
prev_stage = config_dict['STAGES'][stage_idx-1]
prev_stage_config_path = get_config(config_dir=config_path / prev_stage,
config_name=f'config_{profile}.yaml',
get_path_instead=True)
prev_config_name = Path(prev_stage_config_path).name
output_name = read_stage_output(stage=prev_stage,
config_dir=config_path,
config_name=prev_config_name)
stage_input = output_path / prev_stage / output_name

# descend into stage folder
pipeline_path = pipeline_path / stage

# append stage specific arguments
extra_args = [f'STAGE_INPUT={stage_input}'] \
+ extra_args \
+ ['--configfile', f'{prev_stage_config_path}']

while stage not in stages.keys():
stage = input("Which stage should be executed?\n"
+"\n ".join(f"{k} {v}" for k,v in get_setting('stages').items())
+"\nSelect the stage index: ")
stage = stages[stage]

# lookup stage input file
pipeline_config_path = config_path / 'configs' / 'config.yaml'
config_dict = load_config_file(pipeline_config_path)
stage_idx = locate_str_in_list(config_dict['STAGES'], stage)
if stage_idx is None:
raise IndexError("Make sure that the selected stage is also specified "\
"in your top-level config in the list `STAGES`!")

prev_stage = config_dict['STAGES'][stage_idx-1]
prev_stage_config_path = get_config(config_dir=config_path / prev_stage,
config_name=f'config_{profile}.yaml',
get_path_instead=True)
prev_config_name = Path(prev_stage_config_path).name
output_name = read_stage_output(stage=prev_stage,
config_dir=config_path,
config_name=prev_config_name)
stage_input = output_path / prev_stage / output_name

# descend into stage folder
pipeline_path = pipeline_path / stage

# append stage specific arguments
extra_args = [f'STAGE_INPUT={stage_input}'] \
+ extra_args \
+ ['--configfile', f'{prev_stage_config_path}']

# execute snakemake
snakemake_args = ['snakemake','-c1','--config',f'PROFILE={profile}']
log.info(f'Executing `{" ".join(snakemake_args+extra_args)}`')
Expand All @@ -298,7 +344,7 @@ def run(profile=None, stage=None, extra_args=None, **kwargs):
return None


def run_block(block=None, block_args=None):
def run_block(block=None, block_args=None, block_help=False, **kwargs):
while not block:
block = input("Specify a block to execute (<stage_name>.<block_name>):")

Expand All @@ -319,10 +365,12 @@ def run_block(block=None, block_args=None):
f"Available blocks are: {', '.join(available_blocks)}.")
block = input("Specify block:")

if block_help:
block_args += ['--help']

# execute block
myenv = os.environ.copy()
myenv['PYTHONPATH'] = ':'.join(sys.path)
breakpoint()
subprocess.run(['python', str(block_dir / f'{block}.py')]
+ block_args,
env=myenv)
Expand Down
2 changes: 1 addition & 1 deletion cobrawap/cmd_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def setup_entry_stage(profile, parent_profile=None,
# set data path
if data_path is None:
data_path = (input("Path to dataset [optional, "\
"can be set later in the stage01 config file]:")
"can be set later in the stage01 config file]:")
or None)
if data_path is not None:
stage01_update_dict.update({'DATA_SETS': {profile: data_path}})
Expand Down
Binary file modified doc/images/pipeline_illustration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions doc/source/command_line_interface.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

Command Line Interface
======================

.. argparse::
:filename: ../cobrawap/__main__.py
:func: get_parser
9 changes: 2 additions & 7 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
:hidden:

pipeline
stage01_data_entry
stage02_processing
stage03_trigger_detection
stage04_wave_detection
stage05_wave_characterization
stage05_channel_wave_characterization
stageXY_template
command_line_interface
pipeline_stages

.. include:: ../../README.rst

Expand Down
10 changes: 10 additions & 0 deletions doc/source/pipeline_stages.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

Pipeline Stages
===============

.. toctree::
:maxdepth: 1
:glob:

stage*

Loading

0 comments on commit 6e425c0

Please sign in to comment.