Skip to content

Commit

Permalink
working lld analysis checker
Browse files Browse the repository at this point in the history
  • Loading branch information
Sandip117 committed May 21, 2024
1 parent a95a5c9 commit 430ef6c
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 116 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ jobs:
build:
name: Build
if: false # delete this line and uncomment the line below to enable automatic builds
# if: github.event_name == 'push' || github.event_name == 'release'
if: github.event_name == 'push' || github.event_name == 'release'
# needs: [ test ] # uncomment to require passing tests
runs-on: ubuntu-22.04

Expand Down
11 changes: 6 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
# Python version can be changed, e.g.
# FROM python:3.8
# FROM ghcr.io/mamba-org/micromamba:1.5.1-focal-cuda-11.3.1
FROM docker.io/python:3.12.1-slim-bookworm
FROM docker.io/python:latest

LABEL org.opencontainers.image.authors="FNNDSC <dev@babyMRI.org>" \
org.opencontainers.image.title="ChRIS Plugin Title" \
org.opencontainers.image.description="A ChRIS plugin that..."
org.opencontainers.image.title="A ChRIS plugin to analyze the result produced by an LLD analysis " \
org.opencontainers.image.description="A ChRIS plugin to analyze the result produced by an LLD analysis "

ARG SRCDIR=/usr/local/src/app
ARG SRCDIR=/usr/local/src/pl-lld_chxr
WORKDIR ${SRCDIR}

COPY requirements.txt .
RUN --mount=type=cache,sharing=private,target=/root/.cache/pip pip install -r requirements.txt
RUN apt-get update ; apt-get install docker.io -y ; bash

COPY . .
ARG extras_require=none
RUN pip install ".[${extras_require}]" \
&& cd / && rm -rf ${SRCDIR}
WORKDIR /

CMD ["commandname"]
CMD ["lld_chxr"]
107 changes: 20 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,76 +1,10 @@
# _ChRIS_ Plugin Template
# A ChRIS plugin to analyze the result produced by an LLD analysis

[![test status](https://github.com/FNNDSC/python-chrisapp-template/actions/workflows/src.yml/badge.svg)](https://github.com/FNNDSC/python-chrisapp-template/actions/workflows/src.yml)
[![MIT License](https://img.shields.io/github/license/FNNDSC/python-chrisapp-template)](LICENSE)
[![Version](https://img.shields.io/docker/v/fnndsc/pl-lld_chxr?sort=semver)](https://hub.docker.com/r/fnndsc/pl-lld_chxr)
[![MIT License](https://img.shields.io/github/license/fnndsc/pl-lld_chxr)](https://github.com/FNNDSC/pl-lld_chxr/blob/main/LICENSE)
[![ci](https://github.com/FNNDSC/pl-lld_chxr/actions/workflows/ci.yml/badge.svg)](https://github.com/FNNDSC/pl-lld_chxr/actions/workflows/ci.yml)

This is a minimal template repository for _ChRIS_ plugin applications in Python.

## About _ChRIS_ Plugins

A _ChRIS_ plugin is a scientific data-processing software which can run anywhere all-the-same:
in the cloud via a [web app](https://github.com/FNNDSC/ChRIS_ui/), or on your own laptop
from the terminal. They are easy to build and easy to understand: most simply, a
_ChRIS_ plugin is a command-line program which processes data from an input directory
and creates data to an output directory with the usage
`commandname [options...] inputdir/ outputdir/`.

For more information, visit our website https://chrisproject.org

## How to Use This Template

Go to https://github.com/FNNDSC/python-chrisapp-template and click "Use this template".
The newly created repository is ready to use right away.

A script `bootstrap.sh` is provided to help fill in and rename values for your new project.
It is optional to use.

1. Edit the variables in `bootstrap.sh`
2. Run `./bootstrap.sh`
3. Follow the instructions it will print out

## Example Plugins

Here are some good, complete examples of _ChRIS_ plugins created from this template.

- https://github.com/FNNDSC/pl-dcm2niix (basic command wrapper example)
- <https://github.com/FNNDSC/pl-adapt_object_mesh> (parallelizes a command)
- https://github.com/FNNDSC/pl-mri-preview (uses [NiBabel](https://nipy.org/nibabel/))
- https://github.com/FNNDSC/pl-pyvista-volume (example using Python package project structure and pytest)
- https://github.com/FNNDSC/pl-fetal-cp-surface-extract (has a good README.md)

## What's Inside

| Path | Purpose |
|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `app.py` | Main script: start editing here! |
| `tests/` | Unit tests |
| `setup.py` | [Python project metadata and installation script](https://packaging.python.org/en/latest/guides/distributing-packages-using-setuptools/#setup-py) |
| `requirements.txt` | List of Python dependencies |
| `Dockerfile` | [Container image build recipe](https://docs.docker.com/engine/reference/builder/) |
| `.github/workflows/ci.yml` | "continuous integration" using [Github Actions](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions): automatic testing, building, and uploads to https://chrisstore.co |

## Contributing

The source code for the `main` branch of this repository is on the
[src](https://github.com/fnndsc/python-chrisapp-template/tree/src)
branch, which has an additional file
[`.github/workflows/src.yml`](https://github.com/FNNDSC/python-chrisapp-template/blob/src/.github/workflows/src.yml)
When tests pass, changes are automatically merged into `main`.
Developers should commit to or make pull requests targeting `src`.
Do not push directly to `main`.

This is a workaround in order to do automatic testing of this template
without including the `.github/workflows/src.yml` file in the template itself.

<!-- BEGIN README TEMPLATE
# ChRIS Plugin Title
[![Version](https://img.shields.io/docker/v/fnndsc/pl-appname?sort=semver)](https://hub.docker.com/r/fnndsc/pl-appname)
[![MIT License](https://img.shields.io/github/license/fnndsc/pl-appname)](https://github.com/FNNDSC/pl-appname/blob/main/LICENSE)
[![ci](https://github.com/FNNDSC/pl-appname/actions/workflows/ci.yml/badge.svg)](https://github.com/FNNDSC/pl-appname/actions/workflows/ci.yml)
`pl-appname` is a [_ChRIS_](https://chrisproject.org/)
`pl-lld_chxr` is a [_ChRIS_](https://chrisproject.org/)
_ds_ plugin which takes in ... as input files and
creates ... as output files.

Expand All @@ -80,34 +14,34 @@ creates ... as output files.

## Installation

`pl-appname` is a _[ChRIS](https://chrisproject.org/) plugin_, meaning it can
`pl-lld_chxr` is a _[ChRIS](https://chrisproject.org/) plugin_, meaning it can
run from either within _ChRIS_ or the command-line.

## Local Usage

To get started with local command-line usage, use [Apptainer](https://apptainer.org/)
(a.k.a. Singularity) to run `pl-appname` as a container:
(a.k.a. Singularity) to run `pl-lld_chxr` as a container:

```shell
apptainer exec docker://fnndsc/pl-appname commandname [--args values...] input/ output/
apptainer exec docker://fnndsc/pl-lld_chxr lld_chxr [--args values...] input/ output/
```

To print its available options, run:

```shell
apptainer exec docker://fnndsc/pl-appname commandname --help
apptainer exec docker://fnndsc/pl-lld_chxr lld_chxr --help
```

## Examples

`commandname` requires two positional arguments: a directory containing
`lld_chxr` requires two positional arguments: a directory containing
input data, and a directory where to create output data.
First, create the input directory and move input data into it.

```shell
mkdir incoming/ outgoing/
mv some.dat other.dat incoming/
apptainer exec docker://fnndsc/pl-appname:latest commandname [--args] incoming/ outgoing/
apptainer exec docker://fnndsc/pl-lld_chxr:latest lld_chxr [--args] incoming/ outgoing/
```

## Development
Expand All @@ -119,18 +53,18 @@ Instructions for developers.
Build a local container image:

```shell
docker build -t localhost/fnndsc/pl-appname .
docker build -t localhost/fnndsc/pl-lld_chxr .
```

### Running

Mount the source code `app.py` into a container to try out changes without rebuild.
Mount the source code `lld_chxr.py` into a container to try out changes without rebuild.

```shell
docker run --rm -it --userns=host -u $(id -u):$(id -g) \
-v $PWD/app.py:/usr/local/lib/python3.12/site-packages/app.py:ro \
-v $PWD/lld_chxr.py:/usr/local/lib/python3.12/site-packages/lld_chxr.py:ro \
-v $PWD/in:/incoming:ro -v $PWD/out:/outgoing:rw -w /outgoing \
localhost/fnndsc/pl-appname commandname /incoming /outgoing
localhost/fnndsc/pl-lld_chxr lld_chxr /incoming /outgoing
```

### Testing
Expand All @@ -140,8 +74,8 @@ It's recommended to rebuild the image to ensure that sources are up-to-date.
Use the option `--build-arg extras_require=dev` to install extra dependencies for testing.

```shell
docker build -t localhost/fnndsc/pl-appname:dev --build-arg extras_require=dev .
docker run --rm -it localhost/fnndsc/pl-appname:dev pytest
docker build -t localhost/fnndsc/pl-lld_chxr:dev --build-arg extras_require=dev .
docker run --rm -it localhost/fnndsc/pl-lld_chxr:dev pytest
```

## Release
Expand All @@ -158,8 +92,8 @@ Increase the version number in `setup.py` and commit this file.
Build and push an image tagged by the version. For example, for version `1.2.3`:

```
docker build -t docker.io/fnndsc/pl-appname:1.2.3 .
docker push docker.io/fnndsc/pl-appname:1.2.3
docker build -t docker.io/fnndsc/pl-lld_chxr:1.2.3 .
docker push docker.io/fnndsc/pl-lld_chxr:1.2.3
```

### Get JSON Representation
Expand All @@ -168,10 +102,9 @@ Run [`chris_plugin_info`](https://github.com/FNNDSC/chris_plugin#usage)
to produce a JSON description of this plugin, which can be uploaded to _ChRIS_.

```shell
docker run --rm docker.io/fnndsc/pl-appname:1.2.3 chris_plugin_info -d docker.io/fnndsc/pl-appname:1.2.3 > chris_plugin_info.json
docker run --rm docker.io/fnndsc/pl-lld_chxr:1.2.3 chris_plugin_info -d docker.io/fnndsc/pl-lld_chxr:1.2.3 > chris_plugin_info.json
```

Intructions on how to upload the plugin to _ChRIS_ can be found here:
https://chrisproject.org/docs/tutorials/upload_plugin

END README TEMPLATE -->
53 changes: 37 additions & 16 deletions app.py → lld_chxr.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,30 @@

from pathlib import Path
from argparse import ArgumentParser, Namespace, ArgumentDefaultsHelpFormatter

import json
from chris_plugin import chris_plugin, PathMapper
import subprocess

__version__ = '1.0.0'

DISPLAY_TITLE = r"""
ChRIS Plugin Template Title
_ _ _ _ _
| | | | | | | | |
_ __ | |______| | | __| | ___| |__ __ ___ __
| '_ \| |______| | |/ _` | / __| '_ \\ \/ / '__|
| |_) | | | | | (_| || (__| | | |> <| |
| .__/|_| |_|_|\__,_| \___|_| |_/_/\_\_|
| | ______
|_| |______|
"""


parser = ArgumentParser(description='!!!CHANGE ME!!! An example ChRIS plugin which '
'counts the number of occurrences of a given '
'word in text files.',
parser = ArgumentParser(description='A ChRIS plugin to analyze the result produced by an LLD analysis ',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('-w', '--word', required=True, type=str,
help='word to count')
parser.add_argument('-p', '--pattern', default='**/*.txt', type=str,
parser.add_argument('-f', '--fileFilter', default='json', type=str,
help='input file filter glob')
parser.add_argument('-e', '--marginOfError', default=0.02, type=float,
help='Accepted margin of error in tibia to femur ratio')
parser.add_argument('-V', '--version', action='version',
version=f'%(prog)s {__version__}')

Expand All @@ -30,7 +36,7 @@
# documentation: https://fnndsc.github.io/chris_plugin/chris_plugin.html#chris_plugin
@chris_plugin(
parser=parser,
title='My ChRIS plugin',
title='A ChRIS plugin to analyze the result produced by an LLD analysis',
category='', # ref. https://chrisstore.co/plugins
min_memory_limit='100Mi', # supported units: Mi, Gi
min_cpu_limit='1000m', # millicores, e.g. "1000m" = 1 CPU core
Expand All @@ -56,14 +62,29 @@ def main(options: Namespace, inputdir: Path, outputdir: Path):
#
# Refer to the documentation for more options, examples, and advanced uses e.g.
# adding a progress bar and parallelism.
mapper = PathMapper.file_mapper(inputdir, outputdir, glob=options.pattern, suffix='.count.txt')
mapper = PathMapper.file_mapper(inputdir, outputdir, glob=f"**/*.{options.fileFilter}",fail_if_empty=False)
for input_file, output_file in mapper:
# The code block below is a small and easy example of how to use a ``PathMapper``.
# It is recommended that you put your functionality in a helper function, so that
# it is more legible and can be unit tested.
data = input_file.read_text()
frequency = data.count(options.word)
output_file.write_text(str(frequency))
with open(input_file) as f:
data = json.load(f)
analyze_measurements(data,options.marginOfError)


def analyze_measurements(data, margin_error):
"""
Analyze the measurements of lower limbs and verify
if the measurements are correct.
"""
AVG_RATIO = 0.8
for row in data:
rt = data[row]["pixel_distance"]["Right tibia"]
rf = data[row]["pixel_distance"]["Right femur"]
ratio = round(rt / rf, 2)
print(f"Calculated tibia to femur ratio: {ratio} [Average ratio: {AVG_RATIO} ± {margin_error}]")
if ratio > AVG_RATIO + margin_error or ratio < AVG_RATIO - margin_error:
print("Measurements are incorrect.")
else:
print("Measurements are correct.")



if __name__ == '__main__':
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
chris_plugin==0.4.0
plugin2cube
python-chrisclient==2.9.1
12 changes: 6 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ def get_version(rel_path: str) -> str:


setup(
name='chris-plugin-template',
version=get_version('app.py'),
description='A ChRIS DS plugin template',
name='lld_chxr',
version=get_version('lld_chxr.py'),
description='A ChRIS plugin to analyze the result produced by an LLD analysis ',
author='FNNDSC',
author_email='dev@babyMRI.org',
url='https://github.com/FNNDSC/python-chrisapp-template',
py_modules=['app'],
url='https://github.com/FNNDSC/pl-lld_',
py_modules=['lld_chxr'],
install_requires=['chris_plugin'],
license='MIT',
entry_points={
'console_scripts': [
'commandname = app:main'
'lld_chxr = lld_chxr:main'
]
},
classifiers=[
Expand Down

0 comments on commit 430ef6c

Please sign in to comment.