|
a |
|
b/qiita_db/commands.py |
|
|
1 |
# ----------------------------------------------------------------------------- |
|
|
2 |
# Copyright (c) 2014--, The Qiita Development Team. |
|
|
3 |
# |
|
|
4 |
# Distributed under the terms of the BSD 3-clause License. |
|
|
5 |
# |
|
|
6 |
# The full license is in the file LICENSE, distributed with this software. |
|
|
7 |
# ----------------------------------------------------------------------------- |
|
|
8 |
|
|
|
9 |
from functools import partial |
|
|
10 |
from json import loads |
|
|
11 |
|
|
|
12 |
import qiita_db as qdb |
|
|
13 |
|
|
|
14 |
from configparser import ConfigParser |
|
|
15 |
|
|
|
16 |
|
|
|
17 |
SUPPORTED_PARAMS = ['preprocessed_sequence_illumina_params', |
|
|
18 |
'preprocessed_sequence_454_params', |
|
|
19 |
'processed_params_sortmerna'] |
|
|
20 |
|
|
|
21 |
|
|
|
22 |
def load_study_from_cmd(owner, title, info): |
|
|
23 |
r"""Adds a study to the database |
|
|
24 |
|
|
|
25 |
Parameters |
|
|
26 |
---------- |
|
|
27 |
owner : str |
|
|
28 |
The email address of the owner of the study_abstract |
|
|
29 |
title : str |
|
|
30 |
The title of the study_abstract |
|
|
31 |
info : file-like object |
|
|
32 |
File-like object containing study information |
|
|
33 |
|
|
|
34 |
""" |
|
|
35 |
# Parse the configuration file |
|
|
36 |
config = ConfigParser() |
|
|
37 |
config.readfp(info) |
|
|
38 |
|
|
|
39 |
optional = dict(config.items('optional')) |
|
|
40 |
|
|
|
41 |
def get_optional(name): |
|
|
42 |
return optional.get(name, None) |
|
|
43 |
|
|
|
44 |
get_required = partial(config.get, 'required') |
|
|
45 |
required_fields = ['timeseries_type_id', 'mixs_compliant', |
|
|
46 |
'reprocess', 'study_alias', |
|
|
47 |
'study_description', 'study_abstract', |
|
|
48 |
'metadata_complete', 'principal_investigator'] |
|
|
49 |
optional_fields = ['funding', 'most_recent_contact', 'spatial_series', |
|
|
50 |
'vamps_id', 'study_id'] |
|
|
51 |
infodict = {} |
|
|
52 |
for value in required_fields: |
|
|
53 |
infodict[value] = get_required(value) |
|
|
54 |
|
|
|
55 |
for value in optional_fields: |
|
|
56 |
optvalue = get_optional(value) |
|
|
57 |
if optvalue is not None: |
|
|
58 |
infodict[value] = optvalue |
|
|
59 |
|
|
|
60 |
with qdb.sql_connection.TRN: |
|
|
61 |
lab_name_email = get_optional('lab_person') |
|
|
62 |
if lab_name_email is not None: |
|
|
63 |
lab_name, lab_email, lab_affiliation = lab_name_email.split(',') |
|
|
64 |
infodict['lab_person_id'] = qdb.study.StudyPerson.create( |
|
|
65 |
lab_name.strip(), lab_email.strip(), lab_affiliation.strip()) |
|
|
66 |
|
|
|
67 |
pi_name_email = infodict.pop('principal_investigator') |
|
|
68 |
pi_name, pi_email, pi_affiliation = pi_name_email.split(',', 2) |
|
|
69 |
infodict['principal_investigator_id'] = qdb.study.StudyPerson.create( |
|
|
70 |
pi_name.strip(), pi_email.strip(), pi_affiliation.strip()) |
|
|
71 |
|
|
|
72 |
return qdb.study.Study.create(qdb.user.User(owner), title, infodict) |
|
|
73 |
|
|
|
74 |
|
|
|
75 |
def load_artifact_from_cmd(filepaths, filepath_types, artifact_type, |
|
|
76 |
prep_template=None, parents=None, |
|
|
77 |
dflt_params_id=None, required_params=None, |
|
|
78 |
optional_params=None): |
|
|
79 |
r"""Adds an artifact to the system |
|
|
80 |
|
|
|
81 |
Parameters |
|
|
82 |
---------- |
|
|
83 |
filepaths : iterable of str |
|
|
84 |
Paths to the artifact files |
|
|
85 |
filepath_types : iterable of str |
|
|
86 |
Describes the contents of the files |
|
|
87 |
artifact_type : str |
|
|
88 |
The type of artifact |
|
|
89 |
prep_template : int, optional |
|
|
90 |
The prep template id |
|
|
91 |
parents : list of int, optional |
|
|
92 |
The list of artifacts id of the parent artifacts |
|
|
93 |
dflt_params_id : int, optional |
|
|
94 |
The id of the default parameter set used to process the artifact |
|
|
95 |
required_params : str, optional |
|
|
96 |
JSON string with the required parameters used to process the artifact |
|
|
97 |
optional_params : str, optional |
|
|
98 |
JSON string with the optional parameters used to process the artifact |
|
|
99 |
|
|
|
100 |
Returns |
|
|
101 |
------- |
|
|
102 |
qiita_db.artifact.Artifact |
|
|
103 |
The newly created artifact |
|
|
104 |
|
|
|
105 |
Raises |
|
|
106 |
------ |
|
|
107 |
ValueError |
|
|
108 |
If the lists `filepaths` and `filepath_types` don't have the same |
|
|
109 |
length |
|
|
110 |
""" |
|
|
111 |
if len(filepaths) != len(filepath_types): |
|
|
112 |
raise ValueError("Please provide exactly one filepath_type for each " |
|
|
113 |
"and every filepath") |
|
|
114 |
with qdb.sql_connection.TRN: |
|
|
115 |
fp_types_dict = qdb.util.get_filepath_types() |
|
|
116 |
fps = [(fp, fp_types_dict[ftype]) |
|
|
117 |
for fp, ftype in zip(filepaths, filepath_types)] |
|
|
118 |
|
|
|
119 |
if prep_template: |
|
|
120 |
prep_template = qdb.metadata_template.prep_template.PrepTemplate( |
|
|
121 |
prep_template) |
|
|
122 |
|
|
|
123 |
if parents: |
|
|
124 |
if len(parents) > 1 and required_params is None: |
|
|
125 |
raise ValueError("When you pass more than 1 parent you need " |
|
|
126 |
"to also pass required_params") |
|
|
127 |
parents = [qdb.artifact.Artifact(pid) for pid in parents] |
|
|
128 |
|
|
|
129 |
params = None |
|
|
130 |
if dflt_params_id: |
|
|
131 |
if required_params: |
|
|
132 |
required_dict = loads(required_params) |
|
|
133 |
else: |
|
|
134 |
# if we reach this point we know tha we only have one parent |
|
|
135 |
required_dict = loads('{"input_data": %d}' % parents[0].id) |
|
|
136 |
optional_dict = loads(optional_params) if optional_params else None |
|
|
137 |
params = qdb.software.Parameters.from_default_params( |
|
|
138 |
qdb.software.DefaultParameters(dflt_params_id), |
|
|
139 |
required_dict, optional_dict) |
|
|
140 |
|
|
|
141 |
return qdb.artifact.Artifact.create( |
|
|
142 |
fps, artifact_type, prep_template=prep_template, parents=parents, |
|
|
143 |
processing_parameters=params) |
|
|
144 |
|
|
|
145 |
|
|
|
146 |
def load_sample_template_from_cmd(sample_temp_path, study_id): |
|
|
147 |
r"""Adds a sample template to the database |
|
|
148 |
|
|
|
149 |
Parameters |
|
|
150 |
---------- |
|
|
151 |
sample_temp_path : str |
|
|
152 |
Path to the sample template file |
|
|
153 |
study_id : int |
|
|
154 |
The study id to which the sample template belongs |
|
|
155 |
""" |
|
|
156 |
sample_temp = qdb.metadata_template.util.load_template_to_dataframe( |
|
|
157 |
sample_temp_path) |
|
|
158 |
return qdb.metadata_template.sample_template.SampleTemplate.create( |
|
|
159 |
sample_temp, qdb.study.Study(study_id)) |
|
|
160 |
|
|
|
161 |
|
|
|
162 |
def load_prep_template_from_cmd(prep_temp_path, study_id, data_type): |
|
|
163 |
r"""Adds a prep template to the database |
|
|
164 |
|
|
|
165 |
Parameters |
|
|
166 |
---------- |
|
|
167 |
prep_temp_path : str |
|
|
168 |
Path to the prep template file |
|
|
169 |
study_id : int |
|
|
170 |
The study id to which the prep template belongs |
|
|
171 |
data_type : str |
|
|
172 |
The data type of the prep template |
|
|
173 |
""" |
|
|
174 |
prep_temp = qdb.metadata_template.util.load_template_to_dataframe( |
|
|
175 |
prep_temp_path) |
|
|
176 |
return qdb.metadata_template.prep_template.PrepTemplate.create( |
|
|
177 |
prep_temp, qdb.study.Study(study_id), data_type) |
|
|
178 |
|
|
|
179 |
|
|
|
180 |
def update_artifact_from_cmd(filepaths, filepath_types, artifact_id): |
|
|
181 |
"""Updates the artifact `artifact_id` with the given files |
|
|
182 |
|
|
|
183 |
Parameters |
|
|
184 |
---------- |
|
|
185 |
filepaths : iterable of str |
|
|
186 |
Paths to the artifact files |
|
|
187 |
filepath_types : iterable of str |
|
|
188 |
Describes the contents of the files |
|
|
189 |
artifact_id : int |
|
|
190 |
The id of the artifact to be updated |
|
|
191 |
|
|
|
192 |
Returns |
|
|
193 |
------- |
|
|
194 |
qiita_db.artifact.Artifact |
|
|
195 |
|
|
|
196 |
Raises |
|
|
197 |
------ |
|
|
198 |
ValueError |
|
|
199 |
If 'filepaths' and 'filepath_types' do not have the same length |
|
|
200 |
""" |
|
|
201 |
if len(filepaths) != len(filepath_types): |
|
|
202 |
raise ValueError("Please provide exactly one filepath_type for each " |
|
|
203 |
"and every filepath") |
|
|
204 |
with qdb.sql_connection.TRN: |
|
|
205 |
artifact = qdb.artifact.Artifact(artifact_id) |
|
|
206 |
fp_types_dict = qdb.util.get_filepath_types() |
|
|
207 |
fps = [(fp, fp_types_dict[ftype]) |
|
|
208 |
for fp, ftype in zip(filepaths, filepath_types)] |
|
|
209 |
old_fps = artifact.filepaths |
|
|
210 |
sql = "DELETE FROM qiita.artifact_filepath WHERE artifact_id = %s" |
|
|
211 |
qdb.sql_connection.TRN.add(sql, [artifact.id]) |
|
|
212 |
qdb.sql_connection.TRN.execute() |
|
|
213 |
qdb.util.move_filepaths_to_upload_folder(artifact.study.id, old_fps) |
|
|
214 |
fp_ids = qdb.util.insert_filepaths( |
|
|
215 |
fps, artifact.id, artifact.artifact_type) |
|
|
216 |
sql = """INSERT INTO qiita.artifact_filepath (artifact_id, filepath_id) |
|
|
217 |
VALUES (%s, %s)""" |
|
|
218 |
sql_args = [[artifact.id, fp_id] for fp_id in fp_ids] |
|
|
219 |
qdb.sql_connection.TRN.add(sql, sql_args, many=True) |
|
|
220 |
qdb.sql_connection.TRN.execute() |
|
|
221 |
|
|
|
222 |
return artifact |