Skip to content

Commit

Permalink
Change: Add install and init subcommands to CLI
Browse files Browse the repository at this point in the history
1. `install` subcommand will set up conda environments
2. `init` subcommand will set up the nextflow pipeline for the micone workflow
  • Loading branch information
dileep-kishore committed May 12, 2023
1 parent 8d53a30 commit a58163b
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 67 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Other example `config` files can be found at `tests/data/pipelines`
## Know issues

1. If you have a version of `julia` that is preinstalled, make sure that it does not conflict with the version downloaded by the `micone-flashweave` environment
2. The data directory (`nf_micone/data`) needs to be manually downloaded (link here).

## Credits

Expand Down
88 changes: 24 additions & 64 deletions micone/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import click

from .logging import LOG
from .setup import Environments
from .setup import Environments, Initialize
from .utils import Spinner
from .validation import check_results

Expand Down Expand Up @@ -70,83 +70,43 @@ def install(ctx, env: str):

@cli.command()
@click.option(
"--profile",
"-p",
default="local",
"--workflow",
"-w",
default="full",
type=str,
help="The execution profile. Either 'local' or 'sge'",
)
@click.option(
"--config",
"-c",
type=click.Path(exists=True),
help="The config file that defines the pipeline run",
help="The micone workflow initialize: 'full', 'ta_op_ni', 'op_ni', or 'ni'",
)
@click.option(
"--output_location",
"-o",
type=click.Path(exists=True),
default=None,
help="The base output location to store pipeline results",
)
@click.option(
"--base_dir",
"-b",
type=click.Path(exists=True),
default=None,
help="The location of base directory for input files",
)
@click.option(
"--max_procs",
"-m",
type=click.INT,
default=4,
help="Maximum number of processes allowed to run in parallel",
)
@click.option(
"--resume",
is_flag=True,
help="The flag to determine whether a previous execution is resumed",
help="The output path to initialize workflow",
)
@click.pass_context
def init(
ctx,
profile: str,
config: click.Path,
workflow: str,
output_location: click.Path,
base_dir: click.Path,
max_procs: int,
resume: bool,
):
"""Run the pipeline"""
"""Initialize the nextflow templates for the micone workflow"""
spinner = ctx.obj["SPINNER"]
pipeline = Pipeline(
str(config), profile, str(base_dir), resume, output_location=output_location
)
spinner.start()
spinner.text = "Starting pipeline execution"
try:
for process in pipeline.run(max_procs=max_procs):
if pipeline.process_queue is None:
raise ValueError("Pipeline process queue is empty")
process_list = " and ".join(
[proc.id_.split(".", 2)[-1] for proc in pipeline.process_queue]
)
if resume and process.io_exist:
spinner.start()
spinner.text = f"Executing {process_list}"
spinner.succeed(f"Resumed {process}")
spinner.start()
spinner.text = f"Executing {process_list}"
updated_processes = pipeline.wait()
for proc in updated_processes:
proc.log()
if proc.status == "success":
spinner.succeed(f"Completed {proc}")
else:
spinner.fail(f"Failed to execute {proc}")
finally:
LOG.cleanup()
initializer = Initialize()
if not output_location:
output_path = pathlib.Path()
else:
output_path = pathlib.Path(output_location)
for init_cmd in initializer.init(workflow, output_path):
spinner.start()
spinner.text = f"Initializing the {workflow} workflow"
init_cmd.wait()
init_cmd.log()
if init_cmd.status == "failure":
spinner.fail(f"{init_cmd} Failed")
elif init_cmd.status == "success":
spinner.succeed(f"{init_cmd} Passed")
click.secho(f"Log file is at {LOG.path}")
LOG.cleanup()


@cli.command()
Expand Down
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions micone/setup/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .environments import Environments
from .initialize import Initialize
3 changes: 0 additions & 3 deletions micone/setup/environments.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ class Environments:
"""
A class that creates, lists and loads conda environments
Parameters
----------
Attributes
----------
configs : List[pathlib.Path]
Expand Down
82 changes: 82 additions & 0 deletions micone/setup/initialize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""
Module that defines the initialization for micone
"""

import pathlib
from typing import Iterable

from ..pipelines import Command
from ..logging import LOG


PIPELINE_DIR = pathlib.Path(__file__).parent.parent / "pipelines"


class Initialize:
"""A class that initializes the nextflow pipeline for a micone workflow"""

def __init__(self) -> None:
self.workflows_dir = PIPELINE_DIR / "workflows"
self.templates_dir = PIPELINE_DIR / "templates"
self.modules_dir = PIPELINE_DIR / "modules"
self.functions_dir = PIPELINE_DIR / "functions"
self.configs_dir = PIPELINE_DIR / "configs"
# FIXME: This is does not exist right now
self.data_dir = PIPELINE_DIR / "data"
self.workflows = [w.stem for w in self.workflows_dir.iterdir()]

def init(self, workflow: str, output_path: pathlib.Path) -> Iterable[Command]:
"""
Initialize the requested workflow
Parameters
----------
workflow: str
The workflow template to be used for initialization
output_path : pathlib.Path
The location where the pipeline template is to be created
Yields
------
Command
The currently running initialization command
"""
if workflow in self.workflows:
LOG.logger.info(f"Initializing {workflow} workflow")
nf_micone = output_path / "nf_micone"
# mkdir -p nf_micone
cmd1 = Command(f"mkdir -p {nf_micone}", profile="local")
cmd1.run()
yield cmd1
# cp -r "${BASE_DIR}/templates" .
cmd2 = Command(f"cp -r {self.templates_dir} {output_path}", profile="local")
cmd2.run()
yield cmd2
# cp -r "${BASE_DIR}/modules" nf_micone
cmd3 = Command(f"cp -r {self.modules_dir} {nf_micone}", profile="local")
cmd3.run()
yield cmd3
# cp -r "${BASE_DIR}/functions" nf_micone
cmd4 = Command(f"cp -r {self.functions_dir} {nf_micone}", profile="local")
cmd4.run()
yield cmd4
# cp -r "${BASE_DIR}/configs" nf_micone
cmd5 = Command(f"cp -r {self.configs_dir} {nf_micone}", profile="local")
cmd5.run()
yield cmd5
# cp -r "${BASE_DIR}/data" nf_micone # this folder doesn't exist
cmd6 = Command(f"mkdir -p {nf_micone}/data", profile="local")
cmd6.run()
yield cmd6
# copy main.nf and nextflow.config
workflow_dir = self.workflows_dir / workflow
cmd7 = Command(
f"cp {workflow_dir}/main.nf {workflow_dir}/nextflow.config {output_path}",
profile="local",
)
cmd7.run()
yield cmd7
else:
raise ValueError(
f"{workflow} not a supported workflow. Use one of {self.workflows}"
)

0 comments on commit a58163b

Please sign in to comment.