-
Notifications
You must be signed in to change notification settings - Fork 12
/
upload.py
156 lines (136 loc) · 4.93 KB
/
upload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import pandas as pd
from pynv import Client
import re
from pathlib import Path
from ..utils.db import get_or_create
from ..database import db
from ..models import (
Predictor, PredictorCollection, PredictorEvent, PredictorRun,
NeurovaultFileUpload)
from .utils import update_record
def upload_collection(flask_app, filenames, runs, dataset_id, collection_id,
descriptions=None, cache=None):
""" Create new Predictors from TSV files
Args:
filenames list of (str): List of paths to TSVs
runs list of (int): List of run ids to apply events to
dataset_id (int): Dataset id.
collection_id (int): Id of collection object
descriptions (dict): Optional descriptions for each column
cache (obj): Optional flask cache object
"""
if cache is None:
from ..core import cache as cache
if descriptions is None:
descriptions = {}
collection_object = PredictorCollection.query.filter_by(
id=collection_id).one()
# Load into pandas
try:
events = [pd.read_csv(f, sep='\t') for f in filenames]
except Exception as e:
update_record(
collection_object,
exception=e,
traceback='Error reading event files'
)
raise
# Check columns are all the same across all files
cols = [set(e.columns) for e in events]
common_cols = set.intersection(*cols)
if not len(common_cols) == len(cols[0]):
update_record(
collection_object,
traceback='Event files contain distinct columns'
)
raise Exception('Event files contain distinct columns')
if not set(['onset', 'duration']).issubset(common_cols):
update_record(
collection_object,
traceback='Not all columns have "onset" and "duration"'
)
raise Exception('Not all columns have "onset" and "duration"')
pe_objects = []
try:
for col in common_cols - set(['onset', 'duration']):
predictor = Predictor(
name=col,
source=f'Collection: {collection_object.collection_name}',
dataset_id=dataset_id,
predictor_collection_id=collection_object.id,
private=True,
description=descriptions.get(col))
db.session.add(predictor)
db.session.commit()
for ix, e in enumerate(events):
select = e[['onset', 'duration', col]].dropna()
for run_id in runs[ix]:
# Add PredictorRun
pr, _ = get_or_create(
PredictorRun, predictor_id=predictor.id, run_id=run_id)
for _, row in select.iterrows():
row = row.to_dict()
pe_objects.append(
PredictorEvent(
predictor_id=predictor.id,
run_id=run_id, onset=row['onset'],
duration=row['duration'], value=row[col])
)
collection_object.predictors.append(predictor)
db.session.bulk_save_objects(pe_objects)
db.session.commit()
except Exception as e:
cache.clear()
db.session.rollback()
update_record(
collection_object,
exception=e,
traceback=f'Error creating predictors. Failed processing {col}'
)
raise
cache.clear()
return update_record(
collection_object,
status='OK'
)
MAP_TYPE_CHOICES = {
't': 'T',
'p': 'P',
'effect': 'U',
'variance': 'Variance',
}
def upload_neurovault(flask_app, file_id, n_subjects=None):
""" Upload image file to NeuroVault
Args:
file_id (int): NeurovaultFileUpload object id
n_subjects (int): Number of subjects in analysis
"""
api = Client(access_token=flask_app.config['NEUROVAULT_ACCESS_TOKEN'])
file_object = NeurovaultFileUpload.query.filter_by(id=file_id).one()
basename = Path(file_object.path).parts[-1]
contrast_name = re.findall('contrast-(.*)_', str(basename))[0]
map_type = re.findall('stat-(.*)_', str(basename))[0]
map_type = MAP_TYPE_CHOICES[map_type]
if file_object.level == 'GROUP':
analysis_level = 'G'
else:
analysis_level = 'S'
n_subjects = None
try:
api.add_image(
file_object.collection.collection_id, file_object.path,
name=contrast_name,
modality="fMRI-BOLD", map_type=map_type,
analysis_level=analysis_level, cognitive_paradigm_cogatlas='None',
number_of_subjects=n_subjects, is_valid=True)
except Exception as e:
update_record(
file_object,
exception=e,
traceback='Error adding image to collection'
)
raise
return update_record(
file_object,
status='OK'
)