Skip to content

Commit 109ac21

Browse files
authored
Merge pull request #323 from superphy/322-vf
Merge: more descriptive VF results
2 parents 2c03635 + 579c726 commit 109ac21

8 files changed

Lines changed: 50 additions & 125 deletions

File tree

app/middleware/display/beautify.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import logging
2+
import re
23
import pandas as pd
34
import cPickle as pickle
45
from modules.loggingFunctions import initialize_logging
56
from middleware.display.find_widest import check_alleles
67
from middleware.graphers.turtle_utils import actual_filename
7-
from middleware.models import SubtypingResult, model_to_json, unpickle
8+
from middleware.models import unpickle
89
from middleware.modellers import model_vf
910

1011
# logging
@@ -66,6 +67,37 @@ def json_return(gene_dict, args_dict):
6667
instance_dict['hitorientation'] = item['ORIENTATION']
6768
instance_dict['hitstart'] = item['START']
6869
instance_dict['hitstop'] = item['STOP']
70+
# For VF.
71+
if 'RAW' in item:
72+
# Search the GI.
73+
pattern = r'gi:\d*'
74+
a = re.search(pattern, item['RAW'])
75+
# Try searching for other format.
76+
if not a:
77+
pattern = r'gi\|\d*'
78+
a = re.search(pattern, item['RAW'])
79+
# Try searching for GB.
80+
if not a:
81+
pattern = r'gi\|\d*'
82+
b = re.search(pattern, item['RAW'])
83+
if a:
84+
gi = a.group()
85+
# Calling it 'aro' for now.
86+
# TODO: rename to something generic (have to modify grouch).
87+
instance_dict['aro'] = 'https://www.ncbi.nlm.nih.gov/protein/' + gi
88+
# Find the longname.
89+
longname = item['RAW'].split(gi)[-1][2:]
90+
instance_dict['longname'] = longname
91+
elif b:
92+
s = b.group()
93+
gb = s.split('|')[-1]
94+
instance_dict[
95+
'aro'] = 'https://www.ncbi.nlm.nih.gov/nuccore/' + gb
96+
# Too many cases to parse.
97+
instance_dict['longname'] = item['RAW']
98+
else:
99+
instance_dict['aro'] = 'n/a'
100+
instance_dict['longname'] = item['RAW']
69101
if analysis == 'Antimicrobial Resistance':
70102
instance_dict['hitcutoff'] = item['CUT_OFF']
71103
else:
@@ -132,20 +164,17 @@ def beautify(gene_dict, args_dict=None):
132164
return handle_failed(json_r, args_dict)
133165
else:
134166
return json_r
135-
# Everything worked, cast result into a model.
136-
# model = model_vf(json_r)
137-
# return model_to_json(model)
138167

139168
def display_subtyping(pickled_result, args_dict=None):
140169
result = unpickle(pickled_result)
141170
if isinstance(result, dict):
142171
# VF.
143172
list_return = beautify(gene_dict=result, args_dict=args_dict)
144173
assert isinstance(list_return, list)
145-
model = model_vf(list_return)
146-
return model_to_json(model)
174+
l = model_vf(list_return)
175+
return l
147176
elif isinstance(result, list):
148177
# Serotyping.
149-
return model_to_json(result)
178+
return result
150179
else:
151180
raise Exception("beautify() could not handle pickled file: {0}.".format(pickled_result))

app/middleware/graphers/datastruct_savvy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from middleware.graphers.turtle_grapher import generate_graph
55
from middleware.blazegraph.upload_graph import queue_upload
66
from modules.PanPredic.pan_utils import contig_name_parse
7-
from middleware.models import SubtypingResult, unpickle
7+
from middleware.models import unpickle
88
# working with Serotype, Antimicrobial Resistance, & Virulence Factor data
99
# structures
1010

app/middleware/modellers.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
# We try to keep all model creation in this file so it's easier to reference.
22
import pandas as pd
3-
from middleware.models import SubtypingRow, SubtypingResult
43
from middleware.graphers.turtle_utils import actual_filename
54

65

76
def model_serotype(pi, pl, output_file):
87
"""
9-
Creates a SubtypingResult model from ECTYper's serotyping output.
8+
Creates a list from ECTYper's serotyping output.
109
"""
1110
# Read the vanilla output_file from ECTyper.
1211
df = pd.read_csv(output_file)
@@ -28,17 +27,13 @@ def model_serotype(pi, pl, output_file):
2827
}
2928
for index, row in df.iterrows()]
3029

31-
# Convert the list of rows into a SubtypingResult model.
32-
# subtyping_result = SubtypingResult(
33-
# rows = subtyping_list
34-
# )
3530
assert subtyping_list
3631
assert subtyping_list[0]
3732
return subtyping_list
3833

3934
def model_vf(lst):
4035
"""
41-
Casts the output from display.beautify into a SubtypingResult object.
36+
Casts the output from display.beautify into a list.
4237
"""
4338
# Type check.
4439
assert isinstance(lst, list)
@@ -54,13 +49,11 @@ def model_vf(lst):
5449
'hitorientation':item['hitorientation'],
5550
'hitstart':item['hitstart'],
5651
'hitstop':item['hitstop'],
57-
'probability':'n/a'
52+
'probability':'n/a',
53+
'longname':item['longname'],
54+
'aro': item['aro']
5855
}
5956
for item in lst]
60-
# Convert the list of rows into a SubtypingResult model.
61-
# subtyping_result = SubtypingResult(
62-
# rows = subtyping_list
63-
# )
6457
return subtyping_list
6558

6659
def model_phylotyper(lst):

app/middleware/models.py

Lines changed: 3 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,6 @@
1212
from middleware.graphers.turtle_utils import actual_filename
1313
from routes.job_utils import fetch_job
1414

15-
# def _convert_model(model):
16-
# # Convert the model to a generic JSON structure.
17-
# struct = model.to_struct()
18-
# # Check that struct isn't empty.
19-
# assert struct
20-
# if 'rows' in struct:
21-
# # This is not strictly json; more like a list than a dict structure.
22-
# rows_list = struct['rows']
23-
# return rows_list
24-
# else:
25-
# return struct
26-
27-
def model_to_json(model):
28-
"""
29-
Converts models to json for the front-end.
30-
"""
31-
#TODO: can access the list directly, no longer need this.
32-
# Validate the model submitted before processing.
33-
assert isinstance(model, list)
34-
# model.validate()
35-
# Conversion.
36-
# print("model_to_json() called with model: {0}".format(str(model)))
37-
return model
38-
# if isinstance(model, models.Base):
39-
# return _convert_model(model)
40-
# else:
41-
# raise Exception('model_to_json() called for a model without a handler.')
42-
4315
def store(pipeline):
4416
"""
4517
Stores the pipeline (via Pickle) to Redis DB and creates a pipeline id for return.
@@ -95,39 +67,6 @@ def unpickle(pickled_file):
9567
def dump(obj, path):
9668
dill.dump(obj, open(path, 'wb'))
9769

98-
class SubtypingRow(models.Base):
99-
def __init__(self, analysis="", contigid="", filename="", hitcutoff="", hitname="", hitorientation="", hitstart="",hitstop=""):
100-
self.analysis = analysis
101-
self.contigid = contigid
102-
self.filename = filename
103-
self.hitcutoff = hitcutoff
104-
self.hitname = hitname
105-
self.hitorientation = hitorientation
106-
self.hitstart = hitstart
107-
self.hitstop = hitstop
108-
109-
110-
class SubtypingResult(models.Base):
111-
def __init__(self, rows=None):
112-
if not rows:
113-
rows = []
114-
self.rows = rows
115-
116-
class PhylotyperRow(models.Base):
117-
def __init__(self):
118-
self.contig = fields.StringField(nullable=True)
119-
self.genome = fields.StringField()
120-
self.probability = fields.StringField(nullable=True) # actually float
121-
self.start = fields.StringField(nullable=True) # actually int
122-
self.stop = fields.StringField(nullable=True) # actually int
123-
self.subtype = fields.StringField()
124-
self.subtype_gene = fields.StringField(nullable=True)
125-
126-
class PhylotyperResult(models.Base):
127-
def __init__(self):
128-
self.rows = fields.ListField([PhylotyperRow], nullable=True)
129-
130-
13170
class Job():
13271
def __init__(self, rq_job, name="", transitory=True, backlog=True, display=False):
13372
"""
@@ -385,14 +324,12 @@ def to_json(self):
385324
l = []
386325
for j in completed_jobs:
387326
rq_job = j.rq_job
388-
model = rq_job.result
327+
lr = rq_job.result
389328
try:
390-
# TODO: This is not correct as while the new ECTYper call does return a model, the display_subtyping() call that the return job is associated with will already convert the result to a list and return it.
391-
assert isinstance(model, (models.Base,list))
329+
assert isinstance(l, (models.Base,list))
392330
except:
393331
raise Exception("to_json() called for job {0} with result of type {1} and info {2}".format(j.name, type(model), str(model)))
394-
list_json = model_to_json(model)
395-
l += list_json
332+
l += lr
396333
return jsonify(l)
397334

398335
def _function_signature(self):

app/modules/ectyper/call_ectyper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def call_ectyper_serotype(args_dict, pickle=True):
9999
])
100100
if ret_code == 0:
101101
output_file = os.path.join(output_dir, 'output.csv')
102-
# Create a SubtypingResult model from the output.
102+
# Create a list from the output.
103103
subtyping_result = model_serotype(
104104
pi=pi,
105105
pl=pl,

app/tests/test_models.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,6 @@ def test_subtyping_model_direct(l=constants.BEAUTIFY_VF_SEROTYPE):
2424
# Return for incorporation into later tests.
2525
return subtyping_list
2626

27-
# def test_phylotyper_model_direct(l=constants.BEAUTIFY_STX1):
28-
# """
29-
# Use our dataset to directly create a phylotyper results model and validate it.
30-
# """
31-
# phylotyper_list = [
32-
# models.PhylotyperRow(
33-
# contig=d['contig'],
34-
# genome=d['genome'],
35-
# probability=str(d['probability']),
36-
# start=str(d['start']),
37-
# stop=str(d['stop']),
38-
# subtype=d['subtype'],
39-
# subtype_gene=d['subtype_gene']
40-
# )
41-
# for d in l]
42-
# phylotyper_result = models.PhylotyperResult(
43-
# rows = phylotyper_list
44-
# )
45-
# phylotyper_result.validate()
46-
# # Return for incorporation into later tests.
47-
# return phylotyper_result
48-
4927
def _create_example_pipeline():
5028
p = models.Pipeline(
5129
func=spfy,

app/tests/test_modules.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from modules.ectyper.call_ectyper import call_ectyper_vf, call_ectyper_serotype
1313
from modules.amr.amr import amr
1414
from modules.amr.amr_to_dict import amr_to_dict
15-
from middleware.display.beautify import beautify, model_to_json
15+
from middleware.display.beautify import beautify
1616
from middleware.graphers.datastruct_savvy import datastruct_savvy
1717
from middleware.graphers.turtle_grapher import turtle_grapher
1818
from middleware.models import unpickle
@@ -69,18 +69,6 @@ def test_ectyper_vf(return_one=False):
6969
if return_one:
7070
return json_return
7171

72-
def _validate_model(model):
73-
# Validate (throws error if invalidate).
74-
# model.validate()
75-
# Check that the return rows is not some random empty list.
76-
# assert model.rows
77-
# Check the conversion for the front-end.
78-
# r = model_to_json(model)
79-
# This is not really json; more like a list than a dict structure.
80-
assert isinstance(model, list)
81-
# Check that this isn't empty.
82-
assert model
83-
8472
def test_ectyper_serotype_direct():
8573
"""Check the ECTyper from `master` which only performs serotyping.
8674
Installed in the conda environment.
@@ -99,7 +87,7 @@ def test_ectyper_serotype_call_nopickle():
9987
single_dict.update({'i':ecoli_genome})
10088
# Have the call return the model without pickling.
10189
serotype_model = call_ectyper_serotype(single_dict, pickle=False)
102-
_validate_model(serotype_model)
90+
assert isinstance(serotype_model, list)
10391

10492
def test_ectyper_serotype_call_pickle(return_one=False):
10593
"""
@@ -111,7 +99,7 @@ def test_ectyper_serotype_call_pickle(return_one=False):
11199
# Pickle the model, and return the path to the file.
112100
pickled_serotype_model = call_ectyper_serotype(single_dict)
113101
ectyper_serotype_model = unpickle(pickled_serotype_model)
114-
_validate_model(ectyper_serotype_model)
102+
assert isinstance(ectyper_serotype_model, list)
115103
if return_one:
116104
return ectyper_serotype_model
117105

0 commit comments

Comments
 (0)