Skip to content

Commit 705e140

Browse files
authored
Merge pull request #19 from jdkent/add_logging
[ENH] add logging system to write results to files
2 parents 0cb3653 + 4bce4fb commit 705e140

File tree

7 files changed

+155
-46
lines changed

7 files changed

+155
-46
lines changed

Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Your version: 0.6.0 Latest version: 0.6.0
1+
# Your version: 0.6.0 Latest version: 0.7.0
22
# Generated by Neurodocker version 0.6.0
3-
# Timestamp: 2020-04-07 02:17:31 UTC
3+
# Timestamp: 2020-04-30 13:55:19 UTC
44
#
55
# Thank you for using Neurodocker. If you discover any issues
66
# or ways to improve this software, please submit an issue or
@@ -65,7 +65,7 @@ RUN echo '{ \
6565
\n "instructions": [ \
6666
\n [ \
6767
\n "base", \
68-
\n "hbclab/accel-bids" \
68+
\n "hbclab/accel-bids:unstable" \
6969
\n ], \
7070
\n [ \
7171
\n "user", \

Dockerfile_exec

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,9 @@ RUN conda env create -f environment.yml
4242

4343
RUN bash -c 'conda init && . /home/coder/.bashrc && . activate accel && pip install -e /home/coder/projects'
4444

45+
USER root
46+
RUN chown -R coder:coder /home/coder/projects
47+
48+
USER coder
4549
# Run as executable
4650
ENTRYPOINT ["/neurodocker/startup.sh", "accel_transform"]

accel_code/run.py

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import argparse
77
from argparse import RawTextHelpFormatter
88
import os
9+
import logging
910

1011

1112
# This function builds a parser that allows this tool to be used
@@ -30,6 +31,8 @@ def get_parser():
3031
parser.add_argument('--replace', default='no',
3132
choices=['yes', 'no'],
3233
help='replace current output file')
34+
parser.add_argument('--logging-directory',
35+
help='directory to place logging files')
3336

3437
return parser
3538

@@ -39,18 +42,66 @@ def main():
3942
opts = get_parser().parse_args()
4043
root = opts.project_root_directory
4144

45+
logging_directory = opts.logging_directory if opts.logging_directory else os.getcwd()
46+
47+
# assume we can get lab_id and date for the log file
4248
lab_id = utils.get_lab_id(opts.old_file_path)
4349
date = utils.get_date(opts.old_file_path)
4450

45-
ses_id, project = excel_lookup.excel_lookup(lab_id, date, opts.excel_file_path)
46-
47-
sub_id = redcap_query.redcap_query(lab_id, project, opts.api_key)
48-
49-
new_file_name = bids_transform.bids_transform(project, sub_id, ses_id)
51+
# set up the logging configuration
52+
logging_fname = '_'.join([str(lab_id), str(date.date())]) + '.log'
53+
logging_path = os.path.join(logging_directory, logging_fname)
54+
55+
logger = logging.getLogger(__name__)
56+
logger.level = 10
57+
# create file handler which logs even debug messages
58+
fh = logging.FileHandler(logging_path)
59+
fh.setLevel(logging.DEBUG)
60+
# create console handler with a higher log level
61+
ch = logging.StreamHandler()
62+
ch.setLevel(logging.INFO)
63+
# create formatter and add it to the handlers
64+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
65+
fh.setFormatter(formatter)
66+
ch.setFormatter(formatter)
67+
# add the handlers to the logger
68+
logger.addHandler(fh)
69+
logger.addHandler(ch)
70+
71+
# get session and project information
72+
try:
73+
ses_id, project = excel_lookup.excel_lookup(lab_id, date, opts.excel_file_path)
74+
except Exception as e:
75+
logger.exception("could not lookup {} ({}) in {}".format(
76+
lab_id, str(date), opts.excel_file_path))
77+
raise(e)
78+
79+
# find subject id from redcap
80+
try:
81+
sub_id = redcap_query.redcap_query(lab_id, project, opts.api_key)
82+
except Exception as e:
83+
msg = "could not get subject id from redcap for {} ({})"
84+
logger.exception(msg.format(lab_id, str(date)))
85+
raise(e)
86+
# create a new path/filename using this information
87+
try:
88+
new_file_name = bids_transform.bids_transform(project, sub_id, ses_id)
89+
except Exception as e:
90+
msg = "could not create new filename: {} ({})"
91+
logger.exception(msg.format(lab_id, str(date)))
92+
raise(e)
5093

5194
new_file_path = os.path.join(root, new_file_name)
5295

53-
utils.make_directory(opts.old_file_path, new_file_path, opts.replace)
96+
# copy the file to the new project specific location
97+
try:
98+
utils.make_directory(opts.old_file_path, new_file_path, opts.replace)
99+
except Exception as e:
100+
msg = "could not copy file: {} ({})"
101+
logger.exception(msg.format(lab_id, str(date)))
102+
raise(e)
103+
104+
logger.info("{of} -> {nf}".format(of=opts.old_file_path, nf=new_file_path))
54105

55106
return
56107

accel_code/tests/conftest.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import os
2+
import pandas as pd
3+
4+
5+
class MockProject:
6+
7+
def __init__(self, url, key):
8+
pass
9+
10+
@staticmethod
11+
def export_records(fields, records=None, format='df'):
12+
test_path = os.path.dirname(os.path.realpath(__file__))
13+
if "extend_id" in fields:
14+
mock_file = "mock_redcap_extend.tsv"
15+
elif "better_id" in fields:
16+
mock_file = "mock_redcap_better.tsv"
17+
elif "bike_id" in fields:
18+
mock_file = "mock_redcap_bikeatrain.tsv"
19+
elif "ambi_id" in fields:
20+
mock_file = "mock_redcap_ambi.tsv"
21+
elif "pacr_id" in fields:
22+
mock_file = "mock_redcap_pacr.tsv"
23+
elif "alertid" in fields:
24+
mock_file = "mock_redcap_alert.tsv"
25+
elif "normative_id" in fields:
26+
mock_file = "mock_redcap_normative.tsv"
27+
else:
28+
raise ValueError("project not found!")
29+
30+
df = pd.read_csv(os.path.join(test_path,
31+
"data",
32+
"mock_redcap",
33+
mock_file),
34+
sep="\t", index_col="lab_id")
35+
return df

accel_code/tests/test_redcap_query.py

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,8 @@
1-
import os
2-
import pandas as pd
31
import redcap
42
import pytest
53

64
from ..redcap_query import redcap_query
7-
8-
9-
class MockProject:
10-
11-
def __init__(self, url, key):
12-
pass
13-
14-
@staticmethod
15-
def export_records(fields, records=None, format='df'):
16-
test_path = os.path.dirname(os.path.realpath(__file__))
17-
if "extend_id" in fields:
18-
mock_file = "mock_redcap_extend.tsv"
19-
elif "better_id" in fields:
20-
mock_file = "mock_redcap_better.tsv"
21-
elif "bike_id" in fields:
22-
mock_file = "mock_redcap_bikeatrain.tsv"
23-
elif "ambi_id" in fields:
24-
mock_file = "mock_redcap_ambi.tsv"
25-
elif "pacr_id" in fields:
26-
mock_file = "mock_redcap_pacr.tsv"
27-
elif "alertid" in fields:
28-
mock_file = "mock_redcap_alert.tsv"
29-
elif "normative_id" in fields:
30-
mock_file = "mock_redcap_normative.tsv"
31-
else:
32-
raise ValueError("project not found!")
33-
34-
df = pd.read_csv(os.path.join(test_path,
35-
"data",
36-
"mock_redcap",
37-
mock_file),
38-
sep="\t", index_col="lab_id")
39-
return df
5+
from .conftest import MockProject
406

417

428
@pytest.mark.parametrize("lab_id,project,expected_participant_id",

accel_code/tests/test_run.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import os
2+
import sys
3+
4+
import redcap
5+
6+
from .conftest import MockProject
7+
from ..run import main
8+
9+
10+
def test_main(monkeypatch):
11+
12+
# patch the redcap project
13+
monkeypatch.setattr(redcap, "Project", MockProject)
14+
15+
project_root_directory = os.path.join(
16+
os.path.dirname(__file__),
17+
'data',
18+
'vosslabhpc',
19+
)
20+
21+
old_file_path = os.path.join(
22+
os.path.dirname(__file__),
23+
'data',
24+
'827 (2018-11-29)RAW.csv',
25+
)
26+
27+
api_key = 'fake_api_key'
28+
29+
excel_file_path = os.path.join(
30+
os.path.dirname(__file__),
31+
'data',
32+
'ActiGraph_analysis_summary.xlsx',
33+
)
34+
35+
logging_directory = os.path.join(
36+
os.path.dirname(__file__),
37+
'data',
38+
)
39+
40+
args = [
41+
"accel_transform",
42+
project_root_directory,
43+
old_file_path,
44+
api_key,
45+
excel_file_path,
46+
"--logging-directory", logging_directory,
47+
"--replace", "yes",
48+
]
49+
50+
# pass arguments to be parsed by main
51+
monkeypatch.setattr(sys, 'argv', args)
52+
53+
assert main() is None

scripts/make_dockerfile.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -e
55
# Generate Dockerfile.
66
generate_docker() {
77
docker run --rm jdkent/neurodocker:dev generate docker \
8-
--base=hbclab/accel-bids \
8+
--base=hbclab/accel-bids:unstable \
99
--pkg-manager=apt \
1010
--user=coder \
1111
--workdir="/home/coder" \
@@ -20,4 +20,4 @@ generate_docker() {
2020

2121
generate_docker > Dockerfile
2222

23-
docker build -t hbclab/accel-dev .
23+
docker build -t hbclab/accel-dev .

0 commit comments

Comments
 (0)