Skip to content

Commit

Permalink
Merge pull request #133 from tom-and-the-toothfairies/iteration1-2
Browse files Browse the repository at this point in the history
Iteration 1 - Again
  • Loading branch information
houli authored Mar 19, 2017
2 parents 1dc8cd2 + afc1eee commit 3a84879
Show file tree
Hide file tree
Showing 60 changed files with 2,653 additions and 194 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ maximum conveniece - the ability to click links for example.*
This file contains instructions on how to install and run the project, as well
as an overview of the project's design. The target platform is Ubuntu 16.04.

At the time of writing the current release is `1.0`
At the time of writing the current release is `1.1`

## Installing Dependencies

Expand Down
6 changes: 4 additions & 2 deletions asclepius/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Endpoints
| Description | Find all drug-drug interactions (DDI) in the DINTO ontology which involve only the *given* drugs |
| Methods | `POST` |
| Request Body | An object containing a list of *DINTO URIs* |
| Returns | A list of DDI objects; its label, its URI, and the identifiers of the two drugs involved |
| Returns | A list of DDI objects; its label, its URI, the identifiers of the two drugs involved, the spacing between dosages required to avoid the DDI (in days) as well as whether or not it is a harmful interaction |

#### Example
##### Request Body
Expand All @@ -100,7 +100,9 @@ Endpoints
"drug_a": "http://purl.obolibrary.org/obo/DINTO_DB00214",
"drug_b": "http://purl.obolibrary.org/obo/DINTO_DB00519",
"label": "torasemide/trandolapril DDI",
"uri": "http://purl.obolibrary.org/obo/DINTO_11031"
"uri": "http://purl.obolibrary.org/obo/DINTO_11031",
"harmful": false,
"spacing": 3
}
]
```
Expand Down
8 changes: 8 additions & 0 deletions asclepius/asclepius/enrich.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def enrich(ddis):
def _enrich(ddi):
result = {'harmful': bool(hash(ddi['uri']) % 2),
'spacing': abs(hash(ddi['uri']))%14 + 1}
result.update(ddi)
return result

return [_enrich(ddi) for ddi in ddis]
4 changes: 2 additions & 2 deletions asclepius/asclepius/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from app import app
import dinto

from enrich import enrich

class InvalidUsage(Exception):
status_code = 400
Expand Down Expand Up @@ -61,7 +61,7 @@ def ddis():
except ValueError as e:
raise InvalidUsage(str(e))

return jsonify(dinto_res)
return jsonify(enrich(dinto_res))


@app.route('/uris', methods=["POST"])
Expand Down
22 changes: 22 additions & 0 deletions athloi/features/fixtures/analysis_test.pml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
process foo {
task {
action baz {
tool { "pills" }
script { "eat the pills" }
agent { "patient" }
requires {
drug { "paracetamol" }
}
provides { "a cured patient" }
}
action baz2 {
tool { "pills" }
script { "eat the pills" }
agent { "patient" }
requires {
drug { "cocaine" }
}
provides { "a cured patient" }
}
}
}
2 changes: 1 addition & 1 deletion athloi/features/fixtures/ddis.pml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ process foo {
action baz2 {
tool { "pills" }
script { "eat the pills" }
agent { "patient" }
agent { (intangible)(inscrutable) pml.wtf && ("foo" || 1 != 2) }
requires {
drug { "trandolapril" }
}
Expand Down
11 changes: 11 additions & 0 deletions athloi/features/pml_download.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Feature: PML Download
In order to refine PML analysis
As a clinician
I should be able to download the PML file resulting from PML TX transformations

Scenario: uploading a valid PML file
Given I am on the home page
When I select "ddis.pml"
And I submit the upload form
Then I should see the PML download button
And the PML download button should have the correct href
4 changes: 0 additions & 4 deletions athloi/features/step_definitions/file_upload_steps.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
When(/^I submit the upload form$/) do
click_on 'Submit'
end

Then(/^I should see the found drugs panel$/) do
panel = find('#drugs-panel', wait: 15)

Expand Down
12 changes: 12 additions & 0 deletions athloi/features/step_definitions/pml_download_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Then(/^I should see the PML download button$/) do
button = find('#pml-download-anchor')

expect(button).to be_visible
end

Then(/^the PML download button should have the correct href$/) do
button = find('#pml-download-anchor')

expect(button[:href]).to have_content('authorization_token=')
expect(button[:href]).to have_content('ast=')
end
4 changes: 4 additions & 0 deletions athloi/features/step_definitions/shared_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@

execute_script("document.getElementById('file-input').classList.add('hidden')")
end

When(/^I submit the upload form$/) do
click_on 'Submit'
end
19 changes: 12 additions & 7 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ dependencies:

compile:
override:
- echo "panacea asclepius athloi" | parallel --trim r -d " " "docker build --rm=false -t tomtoothfairies/{} {}"
- docker build --rm=false -t tomtoothfairies/panacea panacea
- docker build --rm=false -t tomtoothfairies/asclepius asclepius
- docker build --rm=false -t tomtoothfairies/athloi athloi

test:
pre:
- mkdir -p $CIRCLE_TEST_REPORTS/exunit
- mkdir -p $CIRCLE_TEST_REPORTS/pytest
- mkdir -p $CIRCLE_TEST_REPORTS/cucumber
- mkdir -p $CIRCLE_ARTIFACTS/screenshots
- mkdir -p $CIRCLE_TEST_REPORTS/{exunit,pytest,cucumber}
- mkdir -p $CIRCLE_ARTIFACTS/{screenshots,logs}

override:
- docker-compose -f docker-compose.e2e.yml -f docker-compose.e2e.ci.yml up -d
- docker run -t -e "MIX_ENV=test" -e "CI=true" -v $CIRCLE_TEST_REPORTS/exunit:/test-reports tomtoothfairies/panacea mix test
- docker run -t -v $CIRCLE_TEST_REPORTS/pytest:/test-reports tomtoothfairies/asclepius pytest --junitxml=/test-reports/test-junit-report.xml
- ./end-2-end.sh
- docker-compose -f docker-compose.e2e.yml -f docker-compose.e2e.ci.yml run athloi

post:
- docker logs pathways_panacea_1 > $CIRCLE_ARTIFACTS/logs/panacea.log
- docker logs pathways_asclepius_1 > $CIRCLE_ARTIFACTS/logs/asclepius.log
- docker logs pathways_chiron_1 > $CIRCLE_ARTIFACTS/logs/chiron.log
- docker logs pathways_selenium_1 > $CIRCLE_ARTIFACTS/logs/selenium.log
9 changes: 8 additions & 1 deletion doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## [1.1] 2017-03-19

### Added
- Added support for PML TX file downloads. Valid pml files uploaded to the
system for transformation can now be downloaded via the UI.

## [1.0] 2017-03-12

### Changed
Expand Down Expand Up @@ -114,7 +120,8 @@ All notable changes to this project will be documented in this file.
docker service: pathways.
- Installation instructions in README

[Unreleased]: https://github.com/tom-and-the-toothfairies/pathways/compare/1.0...iteration1-2
[Unreleased]: https://github.com/tom-and-the-toothfairies/pathways/compare/1.1...iteration-6
[1.1]: https://github.com/tom-and-the-toothfairies/pathways/compare/1.0...1.1
[1.0]: https://github.com/tom-and-the-toothfairies/pathways/compare/0.3...1.0
[0.3]: https://github.com/tom-and-the-toothfairies/pathways/compare/0.2...0.3
[0.2]: https://github.com/tom-and-the-toothfairies/pathways/compare/0.1...0.2
Expand Down
12 changes: 12 additions & 0 deletions doc/FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,18 @@ http://chiron:3030/dinto/query`) and the contents of those queries.

See [On Screen DINTO Reporting](#on-screen-dinto-reporting---complete)

## PML-TX Save PML to File - Complete

### Description
The system should be able to allow saving of transformed PML files.

### Testing
Visit the [homepage] and select a valid PML file; for example
`panacea/text/fixtures/ddis.pml`. Press the `Submit` button. You should now see
a `Download PML TX File` button. Clicking the button, depending on your
browser, will either download the file automatically or prompt you to provide a
filename and location and download the file.

[README]: ../README.md
[homepage]: http://localhost:4000
[fixtures directory]: ../panacea/test/fixtures
Expand Down
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ services:
asclepius:
depends_on:
- chiron
image: tomtoothfairies/asclepius:1.0
image: tomtoothfairies/asclepius:1.1

panacea:
depends_on:
- asclepius
image: tomtoothfairies/panacea:1.0
image: tomtoothfairies/panacea:1.1
ports:
- '4000:4000'

chiron:
image: tomtoothfairies/chiron:1.0
image: tomtoothfairies/chiron:1.1
4 changes: 0 additions & 4 deletions end-2-end.sh

This file was deleted.

33 changes: 29 additions & 4 deletions panacea/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ Chiron to provide DDI analysis, these must be running for Panacea to work.
Api Endpoints
-------------

All API endpoints require the *Authorization* header to contain a valid token.
All API endpoints require a valid *authorization token* to be provided. The
*token* can be sent in the *Authorization* header or as the
*authorization_token* query parameter.

Tokens can be generated using: `Panacea.AccessToken.generate()`

### `/api/pml`
Expand Down Expand Up @@ -36,11 +39,22 @@ Tokens can be generated using: `Panacea.AccessToken.generate()`
"label": "cocaine",
"line": 2
}
]
],
"unnamed": [
{
"type": "task",
"line": 3
},
{
"type": "sequence",
"line": 6
}
],
"ast": "AST representation of the provided PML file - base64 encoded"
}
```

### `api/uris`
### `/api/uris`

| | |
|--------------|-------------------------------------------------------------|
Expand Down Expand Up @@ -108,7 +122,9 @@ Tokens can be generated using: `Panacea.AccessToken.generate()`
"drug_a": "http://purl.obolibrary.org/obo/DINTO_DB00214",
"drug_b": "http://purl.obolibrary.org/obo/DINTO_DB00519",
"label": "torasemide/trandolapril DDI",
"uri": "http://purl.obolibrary.org/obo/DINTO_11031"
"uri": "http://purl.obolibrary.org/obo/DINTO_11031",
"harmful": false,
"spacing": 3
}
]
}
Expand All @@ -128,3 +144,12 @@ All error responses take have the following format:
}
}
```

### `/api/ast`

| | |
|-------------|------------------------------------------------------------------------- |
| Description | Convert an PML AST into a PML Document |
| Methods | `POST` |
| Parameters | An object containing the *pml ast* to be converted |
| Returns | The PML document as an attachment named `pml-tx.pml`, or an error object |
18 changes: 18 additions & 0 deletions panacea/lib/panacea/pml/analysis.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule Panacea.Pml.Analysis do
alias __MODULE__
alias Panacea.Pml.Analysis.{Drugs, Unnamed}

defstruct [:drugs, :unnamed, :ast]

def run(ast) do
drugs = Drugs.run(ast)
unnamed = Unnamed.run(ast)

encoded_ast =
ast
|> :erlang.term_to_binary()
|> Base.encode64()

{:ok, %Analysis{drugs: drugs, unnamed: unnamed, ast: encoded_ast}}
end
end
22 changes: 22 additions & 0 deletions panacea/lib/panacea/pml/analysis/drugs.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Panacea.Pml.Analysis.Drugs do

def run(ast) do
analyse([], ast)
end

defp analyse(result, {:requires, _, {:drug, [line: line], label}}) do
[%{label: strip_quotes(label), line: line} | result]
end
defp analyse(result, {_, _, children}) when is_list(children) do
Enum.reduce(children, result, fn(child, acc) ->
analyse(acc, child)
end)
end
defp analyse(result, _), do: result

defp strip_quotes(char_list) do
char_list
|> :string.strip(:both, ?")
|> to_string()
end
end
22 changes: 22 additions & 0 deletions panacea/lib/panacea/pml/analysis/unnamed.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Panacea.Pml.Analysis.Unnamed do

@composite [:task, :sequence, :branch, :selection, :iteration, :action, :process]

def run(ast) do
analyse([], ast)
end

defp analyse(result, {type, attrs, children}) when type in @composite do
result =
if !Keyword.has_key?(attrs, :name) do
[%{type: type, line: Keyword.get(attrs, :line)} | result]
else
result
end

Enum.reduce(children, result, fn (child, acc) ->
analyse(acc, child)
end)
end
defp analyse(result, _), do: result
end
38 changes: 38 additions & 0 deletions panacea/lib/panacea/pml/ast.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule Panacea.Pml.Ast do
@multi_line_constructs ~w(process action task sequence selection branch iteration)a
@single_line_constructs ~w(requires provides agent tool script input output)a

@doc """
Takes an AST and returns the PML it represents in an IO-List
"""
def to_pml(ast) do
do_unquote(ast, 0)
end

defp do_unquote({type, attrs, children}, depth) when type in @multi_line_constructs do
optional_name = get_with_default(attrs, :name)
optional_type = get_with_default(attrs, :type)

[indent(depth), to_string(type), optional_name, optional_type, " {\n",
Enum.map(children, fn(child) -> [do_unquote(child, depth + 1), "\n"] end),
indent(depth), "}"
]
end

defp do_unquote({type, _, value}, depth) when type in @single_line_constructs do
[indent(depth), to_string(type), " { ", do_unquote(value), " }"]
end

defp do_unquote({:expression, _, value}), do: value
defp do_unquote({:drug, _, value}), do: ["drug { ", value, " }"]
defp do_unquote(x) when is_list(x), do: x

defp indent(depth), do: String.duplicate(" ", 2 * depth)

defp get_with_default(attrs, key) do
case Keyword.get(attrs, key) do
nil -> ""
x -> [" ", x]
end
end
end
Loading

0 comments on commit 3a84879

Please sign in to comment.