def delete_sample_template(self, study, user, callback):
"""Delete sample template
Parameters
----------
study : Study
The current study object
user : User
The current user object
callback : function
The callback function to call with the results once the processing
is done
"""
sample_template_id = int(self.get_argument('sample_template_id'))
try:
SampleTemplate.delete(sample_template_id)
msg = ("Sample template %d has been deleted from study: "
"<b><i>%s</i></b>" % (sample_template_id, study.title))
msg_level = "success"
except Exception as e:
msg = "Couldn't remove %d sample template: %s" % (
sample_template_id, str(e))
msg_level = "danger"
callback((msg, msg_level, 'study_information_tab', None, None))
def submit_VAMPS(preprocessed_data_id):
"""Submit preprocessed data to VAMPS
Parameters
----------
preprocessed_data_id : int
The preprocesssed data id
"""
preprocessed_data = PreprocessedData(preprocessed_data_id)
study = Study(preprocessed_data.study)
sample_template = SampleTemplate(study.sample_template)
prep_template = PrepTemplate(preprocessed_data.prep_template)
status = preprocessed_data.submitted_to_vamps_status()
if status in ('submitting', 'success'):
raise ValueError("Cannot resubmit! Current status is: %s" % status)
preprocessed_data.update_vamps_status('submitting')
# Generating a tgz
targz_folder = mkdtemp(prefix=qiita_config.working_dir)
targz_fp = join(targz_folder, '%d_%d_%d.tgz' % (study.id,
prep_template.id,
preprocessed_data.id))
targz = taropen(targz_fp, mode='w:gz')
# adding sample/prep
samp_fp = join(targz_folder, 'sample_metadata.txt')
sample_template.to_file(samp_fp)
targz.add(samp_fp, arcname='sample_metadata.txt')
prep_fp = join(targz_folder, 'prep_metadata.txt')
prep_template.to_file(prep_fp)
targz.add(prep_fp, arcname='prep_metadata.txt')
# adding preprocessed data
for _, fp, fp_type in preprocessed_data.get_filepaths():
if fp_type == 'preprocessed_fasta':
targz.add(fp, arcname='preprocessed_fasta.fna')
targz.close()
# submitting
cmd = ("curl -F user=%s -F pass='%s' -F [email protected]%s -F "
"press=UploadFile %s" % (qiita_config.vamps_user,
qiita_config.vamps_pass,
targz_fp,
qiita_config.vamps_url))
obs, _, _ = system_call(cmd)
exp = ("<html>\n<head>\n<title>Process Uploaded File</title>\n</head>\n"
"<body>\n</body>\n</html>")
if obs != exp:
preprocessed_data.update_vamps_status('failure')
return False
else:
preprocessed_data.update_vamps_status('success')
return True
开发者ID:jenwei,项目名称:qiita,代码行数:58,代码来源:commands.py
示例3: update_sample_template
def update_sample_template(self, study, user, callback):
"""Update a sample template from the POST method
Parameters
----------
study : Study
The current study object
user : User
The current user object
callback : function
The callback function to call with the results once the processing
is done
Raises
------
HTTPError
If the sample template file does not exists
"""
# If we are on this function, the argument "sample_template" must
# defined. If not, let tornado raise its error
sample_template = self.get_argument('sample_template')
# Define here the message and message level in case of success
msg = "The sample template '%s' has been updated" % sample_template
msg_level = "success"
# Get the uploads folder
_, base_fp = get_mountpoint("uploads")[0]
# Get the path of the sample template in the uploads folder
fp_rsp = join(base_fp, str(study.id), sample_template)
if not exists(fp_rsp):
# The file does not exist, fail nicely
raise HTTPError(400, "This file doesn't exist: %s" % fp_rsp)
try:
with warnings.catch_warnings(record=True) as warns:
# deleting previous uploads and inserting new one
st = SampleTemplate(study.id)
df = load_template_to_dataframe(fp_rsp)
st.extend(df)
st.update(df)
remove(fp_rsp)
# join all the warning messages into one. Note that this info
# will be ignored if an exception is raised
if warns:
msg = '\n'.join(set(str(w.message) for w in warns))
msg_level = 'warning'
except (TypeError, QiitaDBColumnError, QiitaDBExecutionError,
QiitaDBDuplicateError, IOError, ValueError, KeyError,
CParserError, QiitaDBDuplicateHeaderError, QiitaDBError) as e:
# Some error occurred while processing the sample template
# Show the error to the user so they can fix the template
msg = html_error_message % ('updating the sample template:',
basename(fp_rsp), str(e))
msg = convert_text_html(msg)
msg_level = "danger"
callback((msg, msg_level, None, None, None))
def remove_add_study_template(self, raw_data, study_id, fp_rsp):
"""Replace prep templates, raw data, and sample template with a new one
"""
for rd in raw_data():
rd = RawData(rd)
for pt in rd.prep_templates:
if PrepTemplate.exists(pt):
PrepTemplate.delete(pt)
if SampleTemplate.exists(study_id):
SampleTemplate.delete(study_id)
SampleTemplate.create(load_template_to_dataframe(fp_rsp),
Study(study_id))
remove(fp_rsp)
def render(self, study):
study_info = study.info
id = study.id
abstract = study_info['study_abstract']
description = study_info['study_description']
pmids = ", ".join([pubmed_linkifier([pmid]) for pmid in study.pmids])
princ_inv = StudyPerson(study_info['principal_investigator_id'])
pi_link = study_person_linkifier((princ_inv.email, princ_inv.name))
number_samples_promised = study_info['number_samples_promised']
number_samples_collected = study_info['number_samples_collected']
metadata_complete = study_info['metadata_complete']
data_types = sorted(viewitems(get_data_types()), key=itemgetter(1))
# Retrieve the files from the uploads folder, so the user can choose
# the sample template of the study. Filter them to only include the
# ones that ends with 'txt' or 'tsv'.
files = [f for _, f in get_files_from_uploads_folders(str(study.id))
if f.endswith(('txt', 'tsv'))]
# If the sample template exists, retrieve all its filepaths
if SampleTemplate.exists(study.id):
sample_templates = SampleTemplate(study.id).get_filepaths()
else:
# If the sample template does not exist, just pass an empty list
sample_templates = []
# Check if the request came from a local source
is_local_request = is_localhost(self.request.headers['host'])
# The user can choose the sample template only if the study is
# sandboxed or the current user is an admin
show_select_sample = (
study.status == 'sandbox' or self.current_user.level == 'admin')
# Ebi information
ebi_status = study.ebi_submission_status
ebi_accession = study.ebi_study_accession
if ebi_accession:
ebi_accession = (EBI_LINKIFIER.format(ebi_accession))
return self.render_string(
"study_description_templates/study_information_tab.html",
abstract=abstract,
description=description,
id=id,
pmids=pmids,
principal_investigator=pi_link,
number_samples_promised=number_samples_promised,
number_samples_collected=number_samples_collected,
metadata_complete=metadata_complete,
show_select_sample=show_select_sample,
files=files,
study_id=study.id,
sample_templates=sample_templates,
is_local_request=is_local_request,
data_types=data_types,
ebi_status=ebi_status,
ebi_accession=ebi_accession)
def test_to_file(self):
"""to file writes a tab delimited file with all the metadata"""
fd, fp = mkstemp()
close(fd)
st = SampleTemplate.create(self.metadata, self.new_study)
st.to_file(fp)
self._clean_up_files.append(fp)
with open(fp, 'U') as f:
obs = f.read()
self.assertEqual(obs, EXP_SAMPLE_TEMPLATE)
def display_template(self, study, user, msg, msg_level, full_access, top_tab=None, sub_tab=None, prep_tab=None):
"""Simple function to avoid duplication of code"""
study_status = study.status
user_level = user.level
sample_template_exists = SampleTemplate.exists(study.id)
if sample_template_exists:
st = SampleTemplate(study.id)
missing_cols = st.check_restrictions([SAMPLE_TEMPLATE_COLUMNS["qiita_main"]])
allow_approval = len(missing_cols) == 0
approval_deny_msg = (
"Processed data approval request is disabled due to missing "
"columns in the sample template: %s" % ", ".join(missing_cols)
)
else:
allow_approval = False
approval_deny_msg = ""
# The general information of the study can be changed if the study is
# not public or if the user is an admin, in which case they can always
# modify the information of the study
show_edit_btn = study_status != "public" or user_level == "admin"
# Make the error message suitable for html
msg = msg.replace("\n", "<br/>")
self.render(
"study_description.html",
message=msg,
level=msg_level,
study=study,
study_title=study.title,
study_alias=study.info["study_alias"],
show_edit_btn=show_edit_btn,
show_data_tabs=sample_template_exists,
full_access=full_access,
allow_approval=allow_approval,
approval_deny_msg=approval_deny_msg,
top_tab=top_tab,
sub_tab=sub_tab,
prep_tab=prep_tab,
)
def remove_add_study_template(self, raw_data, study_id, fp_rsp, data_type, is_mapping_file):
"""Replace prep templates, raw data, and sample template with a new one
"""
if is_mapping_file and data_type == "":
raise ValueError("Please, choose a data type if uploading a QIIME " "mapping file")
for rd in raw_data():
rd = RawData(rd)
for pt in rd.prep_templates:
if PrepTemplate.exists(pt):
PrepTemplate.delete(pt)
if SampleTemplate.exists(study_id):
SampleTemplate.delete(study_id)
if is_mapping_file:
create_templates_from_qiime_mapping_file(fp_rsp, Study(study_id), int(data_type))
else:
SampleTemplate.create(load_template_to_dataframe(fp_rsp), Study(study_id))
remove(fp_rsp)
def get(self):
userobj = self.current_user
analysis = Analysis(int(self.get_argument("aid")))
# make sure user has access to the analysis
check_analysis_access(userobj, analysis)
# get the dictionaries of selected samples and data types
selproc_data, selsamples = self._selected_parser(analysis)
self.render('search_studies.html', aid=analysis.id,
selsamples=selsamples, selproc_data=selproc_data,
counts={}, fullcounts={}, searchmsg="", query="",
results={}, availmeta=SampleTemplate.metadata_headers() +
get_table_cols("study"))
def render(self, study):
study_info = study.info
abstract = study_info['study_abstract']
description = study_info['study_description']
pmids = ", ".join([pubmed_linkifier([pmid]) for pmid in study.pmids])
princ_inv = StudyPerson(study_info['principal_investigator_id'])
pi_link = study_person_linkifier((princ_inv.email, princ_inv.name))
number_samples_promised = study_info['number_samples_promised']
number_samples_collected = study_info['number_samples_collected']
metadata_complete = study_info['metadata_complete']
# Retrieve the files from the uploads folder, so the user can choose
# the sample template of the study
files = [f for _, f in get_files_from_uploads_folders(str(study.id))]
# If the sample template exists, retrieve all its filepaths
if SampleTemplate.exists(study.id):
sample_templates = SampleTemplate(study.id).get_filepaths()
else:
# If the sample template does not exist, just pass an empty list
sample_templates = []
# Check if the request came from a local source
is_local_request = self._is_local()
# The user can choose the sample template only if the study is
# sandboxed or the current user is an admin
show_select_sample = (
study.status == 'sandbox' or self.current_user.level == 'admin')
return self.render_string(
"study_description_templates/study_information_tab.html",
abstract=abstract,
description=description,
pmids=pmids,
principal_investigator=pi_link,
number_samples_promised=number_samples_promised,
number_samples_collected=number_samples_collected,
metadata_complete=metadata_complete,
show_select_sample=show_select_sample,
files=files,
study_id=study.id,
sample_templates=sample_templates,
is_local_request=is_local_request)
def display_template(self, study, user, msg, msg_level, full_access,
top_tab=None, sub_tab=None, prep_tab=None):
"""Simple function to avoid duplication of code"""
study_status = study.status
user_level = user.level
sample_template_exists = SampleTemplate.exists(study.id)
# The general information of the study can be changed if the study is
# not public or if the user is an admin, in which case they can always
# modify the information of the study
show_edit_btn = study_status != 'public' or user_level == 'admin'
self.render('study_description.html',
message=msg,
level=msg_level,
study=study,
study_title=study.title,
study_alias=study.info['study_alias'],
show_edit_btn=show_edit_btn,
show_data_tabs=sample_template_exists,
full_access=full_access,
top_tab=top_tab,
sub_tab=sub_tab,
prep_tab=prep_tab)
def process_sample_template(self, study, user, callback):
"""Process a sample template from the POST method
Parameters
----------
study : Study
The current study object
user : User
The current user object
callback : function
The callback function to call with the results once the processing
is done
Raises
------
HTTPError
If the sample template file does not exists
"""
# If we are on this function, the arguments "sample_template" and
# "data_type" must be defined. If not, let tornado raise its error
sample_template = self.get_argument('sample_template')
data_type = self.get_argument('data_type')
# Get the uploads folder
_, base_fp = get_mountpoint("uploads")[0]
# Get the path of the sample template in the uploads folder
fp_rsp = join(base_fp, str(study.id), sample_template)
if not exists(fp_rsp):
# The file does not exist, fail nicely
raise HTTPError(404, "This file doesn't exist: %s" % fp_rsp)
# Define here the message and message level in case of success
msg = "The sample template '%s' has been added" % sample_template
msg_level = "success"
is_mapping_file = looks_like_qiime_mapping_file(fp_rsp)
try:
if is_mapping_file and not data_type:
raise ValueError("Please, choose a data type if uploading a "
"QIIME mapping file")
with warnings.catch_warnings(record=True) as warns:
if is_mapping_file:
create_templates_from_qiime_mapping_file(fp_rsp, study,
int(data_type))
else:
SampleTemplate.create(load_template_to_dataframe(fp_rsp),
study)
remove(fp_rsp)
# join all the warning messages into one. Note that this
# info will be ignored if an exception is raised
if warns:
msg = '; '.join([convert_text_html(str(w.message))
for w in warns])
msg_level = 'warning'
except (TypeError, QiitaDBColumnError, QiitaDBExecutionError,
QiitaDBDuplicateError, IOError, ValueError, KeyError,
CParserError, QiitaDBDuplicateHeaderError,
QiitaDBError, QiitaWareError) as e:
# Some error occurred while processing the sample template
# Show the error to the user so they can fix the template
error_msg = ('parsing the QIIME mapping file'
if is_mapping_file
else 'parsing the sample template')
msg = html_error_message % (error_msg, basename(fp_rsp),
str(e))
msg = convert_text_html(msg)
msg_level = "danger"
callback((msg, msg_level, None, None, None))
def submit_EBI(preprocessed_data_id, action, send, fastq_dir_fp=None):
"""Submit a preprocessed data to EBI
Parameters
----------
preprocessed_data_id : int
The preprocesssed data id
action : %s
The action to perform with this data
send : bool
True to actually send the files
fastq_dir_fp : str, optional
The fastq filepath
Notes
-----
If fastq_dir_fp is passed, it must not contain any empty files, or
gzipped empty files
"""
preprocessed_data = PreprocessedData(preprocessed_data_id)
preprocessed_data_id_str = str(preprocessed_data_id)
study = Study(preprocessed_data.study)
sample_template = SampleTemplate(study.sample_template)
prep_template = PrepTemplate(preprocessed_data.prep_template)
investigation_type = None
new_investigation_type = None
status = preprocessed_data.submitted_to_insdc_status()
if status in ("submitting", "success"):
raise ValueError("Cannot resubmit! Current status is: %s" % status)
if send:
# If we intend actually to send the files, then change the status in
# the database
preprocessed_data.update_insdc_status("submitting")
# we need to figure out whether the investigation type is a known one
# or if we have to submit a "new_investigation_type" to EBI
current_type = prep_template.investigation_type
ena_ontology = Ontology(convert_to_id("ENA", "ontology"))
if current_type in ena_ontology.terms:
investigation_type = current_type
elif current_type in ena_ontology.user_defined_terms:
investigation_type = "Other"
new_investigation_type = current_type
else:
# This should never happen
raise ValueError(
"Unrecognized investigation type: '%s'. This term "
"is neither one of the official terms nor one of the "
"user-defined terms in the ENA ontology"
)
if fastq_dir_fp is not None:
# If the user specifies a FASTQ directory, use it
# Set demux_samples to None so that MetadataTemplate.to_file will put
# all samples in the template files
demux_samples = None
else:
# If the user does not specify a FASTQ directory, create one and
# re-serialize the per-sample FASTQs from the demux file
fastq_dir_fp = mkdtemp(prefix=qiita_config.working_dir)
demux = [path for _, path, ftype in preprocessed_data.get_filepaths() if ftype == "preprocessed_demux"][0]
# Keep track of which files were actually in the demux file so that we
# can write those rows to the prep and samples templates
demux_samples = set()
with open_file(demux) as demux_fh:
for samp, iterator in to_per_sample_ascii(demux_fh, list(sample_template)):
demux_samples.add(samp)
sample_fp = join(fastq_dir_fp, "%s.fastq.gz" % samp)
wrote_sequences = False
with gzopen(sample_fp, "w") as fh:
for record in iterator:
fh.write(record)
wrote_sequences = True
if not wrote_sequences:
remove(sample_fp)
output_dir = fastq_dir_fp + "_submission"
samp_fp = join(fastq_dir_fp, "sample_metadata.txt")
prep_fp = join(fastq_dir_fp, "prep_metadata.txt")
sample_template.to_file(samp_fp, demux_samples)
prep_template.to_file(prep_fp, demux_samples)
# Get specific output directory and set filepaths
get_output_fp = partial(join, output_dir)
study_fp = get_output_fp("study.xml")
sample_fp = get_output_fp("sample.xml")
experiment_fp = get_output_fp("experiment.xml")
run_fp = get_output_fp("run.xml")
submission_fp = get_output_fp("submission.xml")
if not isdir(output_dir):
#.........这里部分代码省略.........
请发表评论