Skip to content

Commit 000a824

Browse files
author
Victor
committed
Added serology, host_epigenetics_raw_seq_set and host_variant_call nodes, tests, and examples.
1 parent 888efd6 commit 000a824

15 files changed

Lines changed: 3982 additions & 136 deletions

cutlass/HostEpigeneticsRawSeqSet.py

Lines changed: 806 additions & 0 deletions
Large diffs are not rendered by default.

cutlass/HostVariantCall.py

Lines changed: 802 additions & 0 deletions
Large diffs are not rendered by default.

cutlass/Serology.py

Lines changed: 680 additions & 0 deletions
Large diffs are not rendered by default.

cutlass/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
from .Cytokine import Cytokine
66
from .HostSeqPrep import HostSeqPrep
77
from .HostAssayPrep import HostAssayPrep
8+
from .HostEpigeneticsRawSeqSet import HostEpigeneticsRawSeqSet
89
from .HostTranscriptomicsRawSeqSet import HostTranscriptomicsRawSeqSet
10+
from .HostVariantCall import HostVariantCall
911
from .HostWgsRawSeqSet import HostWgsRawSeqSet
1012
from .Lipidome import Lipidome
1113
from .Metabolome import Metabolome
@@ -16,6 +18,7 @@
1618
from .ProteomeNonPride import ProteomeNonPride
1719
from .Sample import Sample
1820
from .SampleAttribute import SampleAttribute
21+
from .Serology import Serology
1922
from .SixteenSDnaPrep import SixteenSDnaPrep
2023
from .SixteenSRawSeqSet import SixteenSRawSeqSet
2124
from .SixteenSTrimmedSeqSet import SixteenSTrimmedSeqSet

cutlass/aspera/aspera.py

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#!/usr/bin/python
22

3+
""" Wrapper module for ascp usage. """
4+
35
import os
46
import re
57
import subprocess
68
import logging
79

8-
# Test wrapper code for ascp
9-
1010
# download example command(s):
1111
#
1212
# only getting ~ 10Mb/s (on 20-30Mb connection): with defaults:
@@ -29,35 +29,47 @@
2929

3030
# compare version numbers
3131
def version_cmp(v1, v2):
32+
"""
33+
Compare version/release numbers.
34+
"""
3235
logger.debug("In version_cmp.")
3336
def normalize(v):
34-
return [int(x) for x in re.sub(r'(\.0+)*$','', v).split(".")]
37+
""" Normalize a dotted version string. """
38+
return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")]
3539
return cmp(normalize(v1), normalize(v2))
3640

37-
# Return version number of ascp executable referenced by ascp_command.
38-
# May raise an exception if the path is invalid.
39-
def get_ascp_version(ascp_command):
41+
def get_ascp_version():
42+
"""
43+
Return version number of ascp executable referenced by ascp_command.
44+
May raise an exception if the path is invalid.
45+
"""
4046
logger.debug("In get_ascp_version.")
4147

4248
version = None
43-
output = subprocess.check_output([ascp_command, "--version"],
44-
universal_newlines = True)
49+
output = subprocess.check_output([ASCP_COMMAND, "--version"],
50+
universal_newlines=True)
51+
4552
cre = re.compile(r"^.+version (\d[\d\.]+)", re.MULTILINE)
4653
for match in cre.finditer(output):
4754
version = match.groups()[0]
4855

4956
if version is None:
50-
raise Exception("Output from ascp command ('" + ascp_command + \
57+
raise Exception("Output from ascp command ('" + ASCP_COMMAND + \
5158
" --version') did not contain a recognizable " + \
5259
"version number.")
5360
return version
5461

55-
def check_ascp_version(ascp_command="ascp"):
62+
def check_ascp_version():
63+
"""
64+
Check that the ascp utility is installed and that its version
65+
is within an acceptable range. If the utility is not present,
66+
or the version is unacceptable, an exception is raised.
67+
"""
5668
logger.debug("In check_ascp_version.")
5769

5870
# check ascp version, raise error if too low
5971
try:
60-
ascp_ver = get_ascp_version(ascp_command)
72+
ascp_ver = get_ascp_version()
6173
except:
6274
raise Exception("Unable to determine ascp version. Is it installed?")
6375

@@ -67,40 +79,49 @@ def check_ascp_version(ascp_command="ascp"):
6779
return True
6880

6981
def get_ascp_env(password):
82+
"""
83+
Get the environment dictionary after adding the ASPERA_SCP_PASS variable
84+
(and value) to it.
85+
"""
7086
logger.debug("In get_ascp_env.")
7187

72-
e = os.environ.copy()
73-
if 'ASPERA_SCP_PASS' in e:
88+
environment = os.environ.copy()
89+
if 'ASPERA_SCP_PASS' in environment:
7490
logger.info("Honoring previously set ASPERA_SCP_PASS environment variable.")
7591
else:
7692
if password != None:
7793
logger.info("Setting ASPERA_SCP_PASS environment variable.")
78-
e['ASPERA_SCP_PASS'] = password
94+
environment['ASPERA_SCP_PASS'] = password
7995

80-
return e
96+
return environment
8197

82-
# run ascp command, returning True for success or False for failure
8398
def run_ascp(ascp_cmd, password, keyfile=None):
99+
"""
100+
Run the ascp command, returning True for success or False for failure.
101+
"""
84102
logger.debug("In run_ascp.")
85103

86104
if keyfile:
87105
if not os.path.exists(keyfile):
88106
raise IOError(
89-
"Can't use private key. No such file or directory: "+keyfile)
107+
"Can't use private key. No such file or directory: " + keyfile)
90108
ascp_cmd = [ascp_cmd[0], "-i", keyfile] + ascp_cmd[1:]
91109

92110
try:
93-
logger.debug("Command: " + " ".join(ascp_cmd))
94-
process = subprocess.Popen(ascp_cmd, stdout=subprocess.PIPE,
95-
stdin=subprocess.PIPE,
96-
stderr=subprocess.PIPE,
97-
universal_newlines = True,
98-
env = get_ascp_env(password))
111+
logger.debug("Command: %s", " ".join(ascp_cmd))
112+
process = subprocess.Popen(
113+
ascp_cmd,
114+
stdout=subprocess.PIPE,
115+
stdin=subprocess.PIPE,
116+
stderr=subprocess.PIPE,
117+
universal_newlines=True,
118+
env=get_ascp_env(password)
119+
)
99120

100121
logger.info("Beginning transfer.")
101122
(s_out, s_err) = process.communicate()
102123
rc = process.returncode
103-
logger.info("Invocation of ascp complete. Return code: %s." % str(rc))
124+
logger.info("Invocation of ascp complete. Return code: %s.", str(rc))
104125

105126
success = False
106127

@@ -112,36 +133,46 @@ def run_ascp(ascp_cmd, password, keyfile=None):
112133
logger.error("Aspera authentication failure.")
113134
else:
114135
if s_err != None:
115-
logger.error("Unexpected STDERR from ascp: %s" % s_err)
136+
logger.error("Unexpected STDERR from ascp: %s", s_err)
116137
if s_out != None:
117-
logger.error("Unexpected STDOUT from ascp: %s" % s_out)
138+
logger.error("Unexpected STDOUT from ascp: %s", s_out)
118139
except subprocess.CalledProcessError as cpe:
119-
logger.error("Encountered an error when running ascp: ", cpe)
140+
logger.error("Encountered an error when running ascp: %s", cpe)
120141

121142
return success
122143

123-
# download a single file via Aspera. return True if successful, False if not
124144
def download_file(server, username, password, remote_path, local_path,
125145
keyfile=None):
146+
"""
147+
Download a single remote file using the aspera ascp utility.
148+
Returns True if successful, False if not.
149+
"""
126150
logger.debug("In download_file.")
127151

128-
check_ascp_version(ASCP_COMMAND)
129-
ascp_cmd = [ ASCP_COMMAND, "-T", "-v", "-l", "300M", username + "@" +
130-
server + ":" + remote_path, local_path ]
152+
check_ascp_version()
153+
ascp_cmd = [
154+
ASCP_COMMAND, "-T", "-v", "-l", "300M",
155+
username + "@" + server + ":" + remote_path,
156+
local_path
157+
]
158+
131159
return run_ascp(ascp_cmd, password, keyfile)
132160

133-
# upload a single file via Aspera. return True if successful, False if not
134161
def upload_file(server, username, password, local_file, remote_path,
135162
keyfile=None):
163+
"""
164+
Upload a single file with the Aspera ascp utility.
165+
Return True if successful, False if not.
166+
"""
136167
logger.debug("In upload_file.")
137-
check_ascp_version(ASCP_COMMAND)
168+
check_ascp_version()
138169

139170
# check that local file exists
140171
if not os.path.isfile(local_file):
141172
logger.warn("local file " + local_file + " does not exist")
142173
return False
143174

144175
remote_clause = username + "@" + server + ":" + remote_path
145-
ascp_cmd = [ ASCP_COMMAND, "-T", "-v", "-l", "300M", local_file, remote_clause ]
176+
ascp_cmd = [ASCP_COMMAND, "-T", "-v", "-l", "300M", local_file, remote_clause]
146177

147178
return run_ascp(ascp_cmd, password, keyfile)

cutlass/iHMPSession.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ def _get_cutlass_instance(self, name):
6767
"clustered_seq_set" : "ClusteredSeqSet",
6868
"cytokine" : "Cytokine",
6969
"host_assay_prep" : "HostAssayPrep",
70+
"host_epigenetics_raw_seq_set" : "HostEpigeneticsRawSeqSet",
7071
"host_seq_prep" : "HostSeqPrep",
7172
"host_transcriptomics_raw_seq_set" : "HostTranscriptomicsRawSeqSet",
73+
"host_variant_call" : "HostVariantCall",
7274
"host_wgs_raw_seq_set" : "HostWgsRawSeqSet",
7375
"lipidome" : "Lipidome",
7476
"metabolome" : "Metabolome",
@@ -79,6 +81,7 @@ def _get_cutlass_instance(self, name):
7981
"proteome_nonpride" : "ProteomeNonPride",
8082
"sample" : "Sample",
8183
"sample_attr" : "SampleAttribute",
84+
"serology" : "Serology",
8285
"study" : "Study",
8386
"subject" : "Subject",
8487
"subject_attr" : "SubjectAttribute",
@@ -210,7 +213,7 @@ def port(self):
210213
@enforce_int
211214
def port(self, port):
212215
"""
213-
The port setter
216+
The port setter.
214217
215218
Args:
216219
port (int): The new port for OSDF access.
@@ -237,7 +240,7 @@ def server(self):
237240
@enforce_string
238241
def server(self, server):
239242
"""
240-
The server setter
243+
The server setter.
241244
242245
Args:
243246
server (str): The new server for OSDF access.
@@ -264,7 +267,7 @@ def ssl(self):
264267
@enforce_bool
265268
def ssl(self, ssl):
266269
"""
267-
The ssl setter
270+
The ssl setter.
268271
269272
Args:
270273
ssl (bool): Whether to use encryption (SSL) or not.
@@ -291,7 +294,7 @@ def username(self):
291294
@enforce_string
292295
def username(self, username):
293296
"""
294-
The username setter
297+
The username setter.
295298
296299
Args:
297300
username (str): The new username for OSDF access.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python
2+
3+
# pylint: disable=C0111, C0325
4+
5+
import logging
6+
import sys
7+
import tempfile
8+
from pprint import pprint
9+
from cutlass import HostEpigeneticsRawSeqSet
10+
from cutlass import iHMPSession
11+
12+
username = "test"
13+
password = "test"
14+
15+
def set_logging():
16+
""" Setup logging. """
17+
root = logging.getLogger()
18+
root.setLevel(logging.DEBUG)
19+
ch = logging.StreamHandler(sys.stdout)
20+
ch.setLevel(logging.DEBUG)
21+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
22+
ch.setFormatter(formatter)
23+
root.addHandler(ch)
24+
25+
set_logging()
26+
27+
session = iHMPSession(username, password)
28+
29+
print("Required fields: ")
30+
print(HostEpigeneticsRawSeqSet.required_fields())
31+
32+
seq_set = HostEpigeneticsRawSeqSet()
33+
34+
seq_set.checksums = {"md5": "72bdc024d83226ccc90fbd2177e78d56"}
35+
seq_set.assay_type = "RRBS"
36+
seq_set.comment = "test comment. Hello world!"
37+
seq_set.exp_length = 2000
38+
seq_set.format = "fasta"
39+
seq_set.format_doc = "url"
40+
seq_set.seq_model = "a machine"
41+
seq_set.sequence_type = "nucleotide"
42+
seq_set.size = 3000
43+
seq_set.study = "prediabetes"
44+
45+
print("Creating a temp file for example/testing purposes.")
46+
temp_file = tempfile.NamedTemporaryFile(delete=False).name
47+
print("Local file: %s" % temp_file)
48+
49+
seq_set.local_file = temp_file
50+
51+
# Optional properties
52+
seq_set.private_files = False
53+
54+
seq_set.links = {"sequenced_from": ["88af6472fb03642dd5eaf8cddc70c8ec"]}
55+
56+
seq_set.tags = ["host_epigenetics_raw_seq_set", "ihmp"]
57+
seq_set.add_tag("another")
58+
seq_set.add_tag("and_another")
59+
60+
print(seq_set.to_json(indent=2))
61+
62+
if seq_set.is_valid():
63+
print("Valid!")
64+
65+
success = seq_set.save()
66+
67+
if success:
68+
seq_set_id = seq_set.id
69+
print("Successfully saved prep. ID: %s" % seq_set_id)
70+
71+
seq_set2 = HostEpigeneticsRawSeqSet.load(seq_set_id)
72+
73+
print(seq_set.to_json(indent=4))
74+
75+
deletion_success = seq_set.delete()
76+
77+
if deletion_success:
78+
print("Deleted sequence set with ID %s" % seq_set_id)
79+
else:
80+
print("Deletion of sequence set %s failed." % seq_set_id)
81+
else:
82+
print("Save failed")
83+
else:
84+
print("Invalid...")
85+
validation_errors = seq_set.validate()
86+
pprint(validation_errors)

0 commit comments

Comments
 (0)