annotate update_stag_database.py @ 7:75ae6c480918 draft

Uploaded
author greg
date Mon, 18 Jan 2021 13:52:55 +0000
parents c34d08494c35
children e3d8b5bfdc11
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
572cf766c59d Uploaded
greg
parents:
diff changeset
1 #!/usr/bin/env python
4
852b9fd0e3cd Uploaded
greg
parents: 3
diff changeset
2
0
572cf766c59d Uploaded
greg
parents:
diff changeset
3
572cf766c59d Uploaded
greg
parents:
diff changeset
4 import argparse
572cf766c59d Uploaded
greg
parents:
diff changeset
5 import datetime
572cf766c59d Uploaded
greg
parents:
diff changeset
6 import os
572cf766c59d Uploaded
greg
parents:
diff changeset
7 import subprocess
572cf766c59d Uploaded
greg
parents:
diff changeset
8 import sys
572cf766c59d Uploaded
greg
parents:
diff changeset
9
5
c34d08494c35 Uploaded
greg
parents: 4
diff changeset
10 import dateutil.parser
c34d08494c35 Uploaded
greg
parents: 4
diff changeset
11
c34d08494c35 Uploaded
greg
parents: 4
diff changeset
12 import psycopg2
c34d08494c35 Uploaded
greg
parents: 4
diff changeset
13
0
572cf766c59d Uploaded
greg
parents:
diff changeset
14 from six.moves import configparser
572cf766c59d Uploaded
greg
parents:
diff changeset
15
5
c34d08494c35 Uploaded
greg
parents: 4
diff changeset
16 from sqlalchemy import MetaData
0
572cf766c59d Uploaded
greg
parents:
diff changeset
17 from sqlalchemy import create_engine
572cf766c59d Uploaded
greg
parents:
diff changeset
18 from sqlalchemy.engine.url import make_url
572cf766c59d Uploaded
greg
parents:
diff changeset
19
572cf766c59d Uploaded
greg
parents:
diff changeset
20 now = datetime.datetime.utcnow
572cf766c59d Uploaded
greg
parents:
diff changeset
21 metadata = MetaData()
572cf766c59d Uploaded
greg
parents:
diff changeset
22
572cf766c59d Uploaded
greg
parents:
diff changeset
23 DEFAULT_MISSING_NUMERIC_VALUE = -9.000000
572cf766c59d Uploaded
greg
parents:
diff changeset
24
572cf766c59d Uploaded
greg
parents:
diff changeset
25
572cf766c59d Uploaded
greg
parents:
diff changeset
26 def check_execution_errors(rc, fstderr, fstdout):
572cf766c59d Uploaded
greg
parents:
diff changeset
27 if rc != 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
28 fh = open(fstdout, 'rb')
572cf766c59d Uploaded
greg
parents:
diff changeset
29 out_msg = fh.read()
572cf766c59d Uploaded
greg
parents:
diff changeset
30 fh.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
31 fh = open(fstderr, 'rb')
572cf766c59d Uploaded
greg
parents:
diff changeset
32 err_msg = fh.read()
572cf766c59d Uploaded
greg
parents:
diff changeset
33 fh.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
34 msg = '%s\n%s\n' % (str(out_msg), str(err_msg))
572cf766c59d Uploaded
greg
parents:
diff changeset
35 sys.exit(msg)
572cf766c59d Uploaded
greg
parents:
diff changeset
36
572cf766c59d Uploaded
greg
parents:
diff changeset
37
572cf766c59d Uploaded
greg
parents:
diff changeset
38 def get_config_settings(config_file, section='defaults'):
572cf766c59d Uploaded
greg
parents:
diff changeset
39 # Return a dictionary consisting of the key / value pairs
572cf766c59d Uploaded
greg
parents:
diff changeset
40 # of the defaults section of config_file.
572cf766c59d Uploaded
greg
parents:
diff changeset
41 d = {}
572cf766c59d Uploaded
greg
parents:
diff changeset
42 config_parser = configparser.ConfigParser()
572cf766c59d Uploaded
greg
parents:
diff changeset
43 config_parser.read(config_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
44 for key, value in config_parser.items(section):
572cf766c59d Uploaded
greg
parents:
diff changeset
45 if section == 'defaults':
5
c34d08494c35 Uploaded
greg
parents: 4
diff changeset
46 d[key.upper()] = value
0
572cf766c59d Uploaded
greg
parents:
diff changeset
47 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
48 d[key] = value
572cf766c59d Uploaded
greg
parents:
diff changeset
49 return d
572cf766c59d Uploaded
greg
parents:
diff changeset
50
572cf766c59d Uploaded
greg
parents:
diff changeset
51
572cf766c59d Uploaded
greg
parents:
diff changeset
52 def get_response_buffers():
572cf766c59d Uploaded
greg
parents:
diff changeset
53 fstderr = os.path.join(os.getcwd(), 'stderr.txt')
572cf766c59d Uploaded
greg
parents:
diff changeset
54 fherr = open(fstderr, 'wb')
572cf766c59d Uploaded
greg
parents:
diff changeset
55 fstdout = os.path.join(os.getcwd(), 'stdout.txt')
572cf766c59d Uploaded
greg
parents:
diff changeset
56 fhout = open(fstdout, 'wb')
572cf766c59d Uploaded
greg
parents:
diff changeset
57 return fstderr, fherr, fstdout, fhout
572cf766c59d Uploaded
greg
parents:
diff changeset
58
572cf766c59d Uploaded
greg
parents:
diff changeset
59
572cf766c59d Uploaded
greg
parents:
diff changeset
60 def get_sql_param_val_str(column_val, default):
572cf766c59d Uploaded
greg
parents:
diff changeset
61 if set_to_null(column_val):
572cf766c59d Uploaded
greg
parents:
diff changeset
62 val = default
572cf766c59d Uploaded
greg
parents:
diff changeset
63 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
64 val = column_val
572cf766c59d Uploaded
greg
parents:
diff changeset
65 return "= '%s'" % val
572cf766c59d Uploaded
greg
parents:
diff changeset
66
572cf766c59d Uploaded
greg
parents:
diff changeset
67
572cf766c59d Uploaded
greg
parents:
diff changeset
68 def get_value_from_config(config_defaults, value):
572cf766c59d Uploaded
greg
parents:
diff changeset
69 return config_defaults.get(value, None)
572cf766c59d Uploaded
greg
parents:
diff changeset
70
572cf766c59d Uploaded
greg
parents:
diff changeset
71
572cf766c59d Uploaded
greg
parents:
diff changeset
72 def get_year_from_now():
572cf766c59d Uploaded
greg
parents:
diff changeset
73 # Get current date plus one year for possible insertion
572cf766c59d Uploaded
greg
parents:
diff changeset
74 # into the public_after_date column of the sample table.
572cf766c59d Uploaded
greg
parents:
diff changeset
75 # The default behavior is for the value of the public
572cf766c59d Uploaded
greg
parents:
diff changeset
76 # column to be True and the public_after_date to be NULL,
572cf766c59d Uploaded
greg
parents:
diff changeset
77 # making the sample "public". However, the user can
572cf766c59d Uploaded
greg
parents:
diff changeset
78 # set the value of the public column to False and optionally
572cf766c59d Uploaded
greg
parents:
diff changeset
79 # set a date after which the sample becomes public in the
572cf766c59d Uploaded
greg
parents:
diff changeset
80 # Affymetrix 96 well plate metadata file associated with
572cf766c59d Uploaded
greg
parents:
diff changeset
81 # the sample. If the value of the public column is set
572cf766c59d Uploaded
greg
parents:
diff changeset
82 # to False, but no date is set, the default date will be 1
572cf766c59d Uploaded
greg
parents:
diff changeset
83 # year from the time the row is inserted into the table.
572cf766c59d Uploaded
greg
parents:
diff changeset
84 today = datetime.date.today()
572cf766c59d Uploaded
greg
parents:
diff changeset
85 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
86 # Return the same day of the year.
572cf766c59d Uploaded
greg
parents:
diff changeset
87 year = today.year + 1
572cf766c59d Uploaded
greg
parents:
diff changeset
88 return today.replace(year=year)
572cf766c59d Uploaded
greg
parents:
diff changeset
89 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
90 # Handle leap years.
572cf766c59d Uploaded
greg
parents:
diff changeset
91 return today + (datetime.date(today.year + 1, 1, 1) - datetime.date(today.year, 1, 1))
572cf766c59d Uploaded
greg
parents:
diff changeset
92
572cf766c59d Uploaded
greg
parents:
diff changeset
93
572cf766c59d Uploaded
greg
parents:
diff changeset
94 def handle_column_value(val, get_sql_param=True, default=''):
572cf766c59d Uploaded
greg
parents:
diff changeset
95 # Regarding the default value, a NULL value indicates an unknown value
572cf766c59d Uploaded
greg
parents:
diff changeset
96 # and typically should not be confused with an empty string. Our application
572cf766c59d Uploaded
greg
parents:
diff changeset
97 # does not need the concept of unknown value, so most columns are
572cf766c59d Uploaded
greg
parents:
diff changeset
98 # non-nullable and our default is an empty string.
572cf766c59d Uploaded
greg
parents:
diff changeset
99 param = handle_null(val)
572cf766c59d Uploaded
greg
parents:
diff changeset
100 if get_sql_param:
572cf766c59d Uploaded
greg
parents:
diff changeset
101 param_val_str = get_sql_param_val_str(val, default)
572cf766c59d Uploaded
greg
parents:
diff changeset
102 if param is None:
572cf766c59d Uploaded
greg
parents:
diff changeset
103 if get_sql_param:
572cf766c59d Uploaded
greg
parents:
diff changeset
104 return default, param_val_str
572cf766c59d Uploaded
greg
parents:
diff changeset
105 return default
572cf766c59d Uploaded
greg
parents:
diff changeset
106 if get_sql_param:
572cf766c59d Uploaded
greg
parents:
diff changeset
107 return param, param_val_str
572cf766c59d Uploaded
greg
parents:
diff changeset
108 return param
572cf766c59d Uploaded
greg
parents:
diff changeset
109
572cf766c59d Uploaded
greg
parents:
diff changeset
110
572cf766c59d Uploaded
greg
parents:
diff changeset
111 def handle_null(val):
572cf766c59d Uploaded
greg
parents:
diff changeset
112 if set_to_null(val):
572cf766c59d Uploaded
greg
parents:
diff changeset
113 return None
572cf766c59d Uploaded
greg
parents:
diff changeset
114 return val
572cf766c59d Uploaded
greg
parents:
diff changeset
115
572cf766c59d Uploaded
greg
parents:
diff changeset
116
572cf766c59d Uploaded
greg
parents:
diff changeset
117 def run_command(cmd):
572cf766c59d Uploaded
greg
parents:
diff changeset
118 fstderr, fherr, fstdout, fhout = get_response_buffers()
572cf766c59d Uploaded
greg
parents:
diff changeset
119 proc = subprocess.Popen(args=cmd, stderr=fherr, stdout=fhout, shell=True)
572cf766c59d Uploaded
greg
parents:
diff changeset
120 rc = proc.wait()
572cf766c59d Uploaded
greg
parents:
diff changeset
121 # Check results.
572cf766c59d Uploaded
greg
parents:
diff changeset
122 fherr.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
123 fhout.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
124 check_execution_errors(rc, fstderr, fstdout)
572cf766c59d Uploaded
greg
parents:
diff changeset
125
572cf766c59d Uploaded
greg
parents:
diff changeset
126
572cf766c59d Uploaded
greg
parents:
diff changeset
127 def set_to_null(val):
572cf766c59d Uploaded
greg
parents:
diff changeset
128 if val in ["", "NA", "NULL"]:
572cf766c59d Uploaded
greg
parents:
diff changeset
129 return True
572cf766c59d Uploaded
greg
parents:
diff changeset
130 return False
572cf766c59d Uploaded
greg
parents:
diff changeset
131
572cf766c59d Uploaded
greg
parents:
diff changeset
132
572cf766c59d Uploaded
greg
parents:
diff changeset
133 def split_line(line, sep="\t"):
572cf766c59d Uploaded
greg
parents:
diff changeset
134 # Remove R quote chars.
572cf766c59d Uploaded
greg
parents:
diff changeset
135 items = line.split(sep)
572cf766c59d Uploaded
greg
parents:
diff changeset
136 unquoted_items = []
572cf766c59d Uploaded
greg
parents:
diff changeset
137 for item in items:
572cf766c59d Uploaded
greg
parents:
diff changeset
138 unquoted_items.append(item.strip('"'))
572cf766c59d Uploaded
greg
parents:
diff changeset
139 return unquoted_items
572cf766c59d Uploaded
greg
parents:
diff changeset
140
572cf766c59d Uploaded
greg
parents:
diff changeset
141
572cf766c59d Uploaded
greg
parents:
diff changeset
142 def string_as_bool(string):
572cf766c59d Uploaded
greg
parents:
diff changeset
143 if str(string).lower() in ('true', 'yes', 'on', '1'):
572cf766c59d Uploaded
greg
parents:
diff changeset
144 return True
572cf766c59d Uploaded
greg
parents:
diff changeset
145 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
146 return False
572cf766c59d Uploaded
greg
parents:
diff changeset
147
572cf766c59d Uploaded
greg
parents:
diff changeset
148
572cf766c59d Uploaded
greg
parents:
diff changeset
149 class StagDatabaseUpdater(object):
572cf766c59d Uploaded
greg
parents:
diff changeset
150 def __init__(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
151 self.args = None
572cf766c59d Uploaded
greg
parents:
diff changeset
152 self.conn = None
572cf766c59d Uploaded
greg
parents:
diff changeset
153 self.parse_args()
572cf766c59d Uploaded
greg
parents:
diff changeset
154 self.year_from_now = get_year_from_now()
572cf766c59d Uploaded
greg
parents:
diff changeset
155 self.db_name = None
572cf766c59d Uploaded
greg
parents:
diff changeset
156 self.db_storage_dir = None
572cf766c59d Uploaded
greg
parents:
diff changeset
157 self.get_config_settings()
572cf766c59d Uploaded
greg
parents:
diff changeset
158 self.outfh = open(self.args.output, "w")
572cf766c59d Uploaded
greg
parents:
diff changeset
159 self.connect_db()
572cf766c59d Uploaded
greg
parents:
diff changeset
160 self.engine = create_engine(self.args.database_connection_string)
572cf766c59d Uploaded
greg
parents:
diff changeset
161 self.metadata = MetaData(self.engine)
572cf766c59d Uploaded
greg
parents:
diff changeset
162 self.affy_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
163 self.allele_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
164 self.colony_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
165 self.experiment_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
166 self.genotype_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
167 self.person_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
168 self.phenotype_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
169 self.reef_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
170 self.taxonomy_ids = []
572cf766c59d Uploaded
greg
parents:
diff changeset
171
572cf766c59d Uploaded
greg
parents:
diff changeset
172 def connect_db(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
173 url = make_url(self.args.database_connection_string)
572cf766c59d Uploaded
greg
parents:
diff changeset
174 self.log('Attempting to connect to the database...')
572cf766c59d Uploaded
greg
parents:
diff changeset
175 args = url.translate_connect_args(username='user')
572cf766c59d Uploaded
greg
parents:
diff changeset
176 args.update(url.query)
572cf766c59d Uploaded
greg
parents:
diff changeset
177 assert url.get_dialect().name == 'postgresql', 'This script can only be used with PostgreSQL.'
572cf766c59d Uploaded
greg
parents:
diff changeset
178 self.conn = psycopg2.connect(**args)
572cf766c59d Uploaded
greg
parents:
diff changeset
179 self.log("Successfully connected to the database...")
572cf766c59d Uploaded
greg
parents:
diff changeset
180
572cf766c59d Uploaded
greg
parents:
diff changeset
181 def convert_date_string_for_database(self, date_string):
572cf766c59d Uploaded
greg
parents:
diff changeset
182 # The value of date_string is %y/%m/%d with
572cf766c59d Uploaded
greg
parents:
diff changeset
183 # the year being 2 digits (yikes!).
572cf766c59d Uploaded
greg
parents:
diff changeset
184 fixed_century = "20%s" % date_string
572cf766c59d Uploaded
greg
parents:
diff changeset
185 fixed_date = fixed_century.replace("/", "-")
572cf766c59d Uploaded
greg
parents:
diff changeset
186 # Convert the string to a format required for
572cf766c59d Uploaded
greg
parents:
diff changeset
187 # inserting into the database.
572cf766c59d Uploaded
greg
parents:
diff changeset
188 database_format = dateutil.parser.parse(fixed_date)
572cf766c59d Uploaded
greg
parents:
diff changeset
189 return str(database_format)
572cf766c59d Uploaded
greg
parents:
diff changeset
190
572cf766c59d Uploaded
greg
parents:
diff changeset
191 def flush(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
192 self.conn.commit()
572cf766c59d Uploaded
greg
parents:
diff changeset
193
572cf766c59d Uploaded
greg
parents:
diff changeset
194 def export_database(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
195 # Export the database to the configured storage location.
572cf766c59d Uploaded
greg
parents:
diff changeset
196 if not os.path.isdir(self.db_storage_dir):
572cf766c59d Uploaded
greg
parents:
diff changeset
197 os.makedirs(self.db_storage_dir)
572cf766c59d Uploaded
greg
parents:
diff changeset
198 db_storage_path = os.path.join(self.db_storage_dir, "exported_%s_db" % self.db_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
199 cmd = "pg_dump %s -f %s" % (self.db_name, db_storage_path)
572cf766c59d Uploaded
greg
parents:
diff changeset
200 run_command(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
201
572cf766c59d Uploaded
greg
parents:
diff changeset
202 def get_config_settings(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
203 config_defaults = get_config_settings(self.args.config_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
204 self.db_name = get_value_from_config(config_defaults, 'DB_NAME')
1
f0c4f7f2ecd4 Uploaded
greg
parents: 0
diff changeset
205 base_storage_dir = get_value_from_config(config_defaults, 'DB_STORAGE_DIR')
f0c4f7f2ecd4 Uploaded
greg
parents: 0
diff changeset
206 # Use the date to name the storage directory to
f0c4f7f2ecd4 Uploaded
greg
parents: 0
diff changeset
207 # enable storing a file per day (multiple runs
f0c4f7f2ecd4 Uploaded
greg
parents: 0
diff changeset
208 # per day will overwrite the existing file.
f0c4f7f2ecd4 Uploaded
greg
parents: 0
diff changeset
209 date_str = datetime.datetime.now().strftime("%Y_%m_%d")
f0c4f7f2ecd4 Uploaded
greg
parents: 0
diff changeset
210 self.db_storage_dir = os.path.join(base_storage_dir, date_str)
0
572cf766c59d Uploaded
greg
parents:
diff changeset
211
572cf766c59d Uploaded
greg
parents:
diff changeset
212 def get_next_sample_id(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
213 cmd = "SELECT sample_id FROM sample ORDER by id DESC;"
572cf766c59d Uploaded
greg
parents:
diff changeset
214 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
215 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
216 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
217 last_sample_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
218 # The value of last_sample_id will be something like A10171.
572cf766c59d Uploaded
greg
parents:
diff changeset
219 last_sample_id_num = int(last_sample_id.lstrip("A"))
572cf766c59d Uploaded
greg
parents:
diff changeset
220 next_sample_id_num = last_sample_id_num + 1
572cf766c59d Uploaded
greg
parents:
diff changeset
221 next_sample_id = "A%d" % next_sample_id_num
572cf766c59d Uploaded
greg
parents:
diff changeset
222 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
223 next_sample_id = "A10000"
572cf766c59d Uploaded
greg
parents:
diff changeset
224 return next_sample_id
572cf766c59d Uploaded
greg
parents:
diff changeset
225
572cf766c59d Uploaded
greg
parents:
diff changeset
226 def log(self, msg):
572cf766c59d Uploaded
greg
parents:
diff changeset
227 self.outfh.write("%s\n" % msg)
572cf766c59d Uploaded
greg
parents:
diff changeset
228
572cf766c59d Uploaded
greg
parents:
diff changeset
229 def update_allele_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
230 self.log("Updating the allele table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
231 # Columns in the experiment file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
232 # affy_id allele
572cf766c59d Uploaded
greg
parents:
diff changeset
233 allele_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
234 # The allele.tabular file contains a subset of the number of samples
572cf766c59d Uploaded
greg
parents:
diff changeset
235 # to be inserted. This is because those samples that failed will not
572cf766c59d Uploaded
greg
parents:
diff changeset
236 # be included in the file. Failed samples will have an affy_id value
572cf766c59d Uploaded
greg
parents:
diff changeset
237 # of NA in self.affy_ids, which was generated when the genotype.tabular
572cf766c59d Uploaded
greg
parents:
diff changeset
238 # file was processed, so we'll use that list to build the correct list
572cf766c59d Uploaded
greg
parents:
diff changeset
239 # of self.allele_ids for later use when inserting into the sample table.
572cf766c59d Uploaded
greg
parents:
diff changeset
240 fh = open(file_path, "r")
572cf766c59d Uploaded
greg
parents:
diff changeset
241 # Skip the header
572cf766c59d Uploaded
greg
parents:
diff changeset
242 fh.readline()
572cf766c59d Uploaded
greg
parents:
diff changeset
243 for id_index, affy_id in enumerate(self.affy_ids):
572cf766c59d Uploaded
greg
parents:
diff changeset
244 if set_to_null(affy_id):
572cf766c59d Uploaded
greg
parents:
diff changeset
245 # This is a failed sample, so no allele strings will be
572cf766c59d Uploaded
greg
parents:
diff changeset
246 # inserted, and we'll set the allele_id to the default
572cf766c59d Uploaded
greg
parents:
diff changeset
247 # empty string.
572cf766c59d Uploaded
greg
parents:
diff changeset
248 self.allele_ids.append("")
572cf766c59d Uploaded
greg
parents:
diff changeset
249 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
250 # See if we need to add a row to the table. The affy_id value
572cf766c59d Uploaded
greg
parents:
diff changeset
251 # should not exist in the sample table.
572cf766c59d Uploaded
greg
parents:
diff changeset
252 cmd = "SELECT allele_id FROM sample WHERE affy_id = '%s';" % affy_id
572cf766c59d Uploaded
greg
parents:
diff changeset
253 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
254 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
255 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
256 allele_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
257 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
258 # Insert a row into the allele table.
572cf766c59d Uploaded
greg
parents:
diff changeset
259 line = fh.readline()
572cf766c59d Uploaded
greg
parents:
diff changeset
260 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
261 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
262 allele = items[1]
572cf766c59d Uploaded
greg
parents:
diff changeset
263 cmd = "INSERT INTO allele VALUES (nextval('allele_id_seq'), %s, %s, %s) RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
264 args = ['NOW()', 'NOW()', allele]
572cf766c59d Uploaded
greg
parents:
diff changeset
265 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
266 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
267 allele_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
268 allele_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
269 self.allele_ids.append(allele_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
270 self.log("Inserted %d rows into the allele table..." % allele_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
271
572cf766c59d Uploaded
greg
parents:
diff changeset
272 def update_colony_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
273 self.log("Updating the colony table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
274 # Columns in the colony file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
275 # latitude longitude depth geographic_origin
572cf766c59d Uploaded
greg
parents:
diff changeset
276 # The geographic_origin value is used for deciding into which table
572cf766c59d Uploaded
greg
parents:
diff changeset
277 # to insert the latitude and longitude values. If the geographic_origin
572cf766c59d Uploaded
greg
parents:
diff changeset
278 # is "colony", the values will be inserted into the colony table.
572cf766c59d Uploaded
greg
parents:
diff changeset
279 colony_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
280 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
281 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
282 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
283 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
284 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
285 # Keep track of foreign keys since we skip the header line.
572cf766c59d Uploaded
greg
parents:
diff changeset
286 id_index = i - 1
572cf766c59d Uploaded
greg
parents:
diff changeset
287 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
288 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
289 geographic_origin = items[3]
572cf766c59d Uploaded
greg
parents:
diff changeset
290 if set_to_null(geographic_origin):
572cf766c59d Uploaded
greg
parents:
diff changeset
291 geographic_origin = "reef"
572cf766c59d Uploaded
greg
parents:
diff changeset
292 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
293 geographic_origin = geographic_origin.lower()
572cf766c59d Uploaded
greg
parents:
diff changeset
294 if geographic_origin == "colony":
572cf766c59d Uploaded
greg
parents:
diff changeset
295 latitude = "%6f" % float(items[0])
572cf766c59d Uploaded
greg
parents:
diff changeset
296 longitude = "%6f" % float(items[1])
572cf766c59d Uploaded
greg
parents:
diff changeset
297 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
298 latitude = DEFAULT_MISSING_NUMERIC_VALUE
572cf766c59d Uploaded
greg
parents:
diff changeset
299 longitude = DEFAULT_MISSING_NUMERIC_VALUE
2
681d8497a691 Uploaded
greg
parents: 1
diff changeset
300 depth = handle_column_value(items[2], get_sql_param=False, default=-9.0)
0
572cf766c59d Uploaded
greg
parents:
diff changeset
301 reef_id = self.reef_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
302 # See if we need to add a row to the table.
572cf766c59d Uploaded
greg
parents:
diff changeset
303 cmd = "SELECT id FROM colony WHERE latitude = %s " % latitude
572cf766c59d Uploaded
greg
parents:
diff changeset
304 cmd += "AND longitude = %s AND depth = %s " % (longitude, depth)
572cf766c59d Uploaded
greg
parents:
diff changeset
305 cmd += "AND reef_id = %s;" % reef_id
572cf766c59d Uploaded
greg
parents:
diff changeset
306 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
307 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
308 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
309 colony_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
310 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
311 # Insert a row into the colony table.
572cf766c59d Uploaded
greg
parents:
diff changeset
312 cmd = "INSERT INTO colony VALUES (nextval('colony_id_seq'), %s, %s, %s, %s, %s, %s) RETURNING id;"
7
75ae6c480918 Uploaded
greg
parents: 5
diff changeset
313 args = ['NOW()', 'NOW()', latitude, longitude, depth, reef_id]
0
572cf766c59d Uploaded
greg
parents:
diff changeset
314 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
315 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
316 colony_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
317 colony_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
318 self.colony_ids.append(colony_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
319 self.log("Inserted %d rows into the colony table..." % colony_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
320
572cf766c59d Uploaded
greg
parents:
diff changeset
321 def update_experiment_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
322 self.log("Updating the experiment table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
323 # Columns in the experiment file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
324 # seq_facility array_version result_folder_name plate_barcode
572cf766c59d Uploaded
greg
parents:
diff changeset
325 experiment_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
326 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
327 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
328 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
329 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
330 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
331 # Keep track of foreign keys since we skip the header line.
572cf766c59d Uploaded
greg
parents:
diff changeset
332 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
333 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
334 seq_facility, seq_facility_param_val_str = handle_column_value(items[0])
572cf766c59d Uploaded
greg
parents:
diff changeset
335 array_version, array_version_param_val_str = handle_column_value(items[1])
572cf766c59d Uploaded
greg
parents:
diff changeset
336 result_folder_name, result_folder_name_param_val_str = handle_column_value(items[2])
572cf766c59d Uploaded
greg
parents:
diff changeset
337 plate_barcode, plate_barcode_param_val_str = handle_column_value(items[3])
572cf766c59d Uploaded
greg
parents:
diff changeset
338 # See if we need to add a row to the table.
572cf766c59d Uploaded
greg
parents:
diff changeset
339 cmd = "SELECT id FROM experiment WHERE seq_facility %s " % seq_facility_param_val_str
572cf766c59d Uploaded
greg
parents:
diff changeset
340 cmd += "AND array_version %s " % array_version_param_val_str
572cf766c59d Uploaded
greg
parents:
diff changeset
341 cmd += "AND result_folder_name %s " % result_folder_name_param_val_str
572cf766c59d Uploaded
greg
parents:
diff changeset
342 cmd += "AND plate_barcode %s;" % plate_barcode_param_val_str
572cf766c59d Uploaded
greg
parents:
diff changeset
343 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
344 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
345 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
346 experiment_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
347 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
348 # Insert a row into the experiment table.
572cf766c59d Uploaded
greg
parents:
diff changeset
349 cmd = "INSERT INTO experiment VALUES (nextval('experiment_id_seq'), %s, %s, %s, %s, %s, %s) RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
350 args = ['NOW()', 'NOW()', seq_facility, array_version, result_folder_name, plate_barcode]
572cf766c59d Uploaded
greg
parents:
diff changeset
351 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
352 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
353 experiment_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
354 experiment_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
355 self.experiment_ids.append(experiment_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
356 self.log("Inserted %d rows into the experiment table..." % experiment_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
357
572cf766c59d Uploaded
greg
parents:
diff changeset
358 def update_genotype_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
359 self.log("Updating the genotype table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
360 # Columns in the genotype file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
361 # affy_id coral_mlg_clonal_id user_specimen_id db_match genetic_coral_species_call
572cf766c59d Uploaded
greg
parents:
diff changeset
362 # coral_mlg_rep_sample_id
572cf766c59d Uploaded
greg
parents:
diff changeset
363 genotype_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
364 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
365 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
366 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
367 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
368 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
369 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
370 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
371 # Keep an in-memory list of affy_ids for use
572cf766c59d Uploaded
greg
parents:
diff changeset
372 # when updating the allele table.
572cf766c59d Uploaded
greg
parents:
diff changeset
373 self.affy_ids.append(items[0])
572cf766c59d Uploaded
greg
parents:
diff changeset
374 coral_mlg_clonal_id = items[1]
572cf766c59d Uploaded
greg
parents:
diff changeset
375 # The value of db_match will be "no_match" if
572cf766c59d Uploaded
greg
parents:
diff changeset
376 # a new row should be inserted into the table.
572cf766c59d Uploaded
greg
parents:
diff changeset
377 db_match = items[3].lower()
572cf766c59d Uploaded
greg
parents:
diff changeset
378 genetic_coral_species_call = handle_column_value(items[4], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
379 coral_mlg_rep_sample_id = handle_column_value(items[5], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
380 if db_match == "failed":
572cf766c59d Uploaded
greg
parents:
diff changeset
381 # Handle the special case of a failed sample.
572cf766c59d Uploaded
greg
parents:
diff changeset
382 cmd = "SELECT id FROM genotype WHERE coral_mlg_clonal_id = 'failed'"
572cf766c59d Uploaded
greg
parents:
diff changeset
383 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
384 cmd = "SELECT id FROM genotype WHERE coral_mlg_clonal_id = '%s'" % coral_mlg_clonal_id
572cf766c59d Uploaded
greg
parents:
diff changeset
385 # See if we need to add a row to the table.
572cf766c59d Uploaded
greg
parents:
diff changeset
386 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
387 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
388 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
389 genotype_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
390 if db_match == "failed":
572cf766c59d Uploaded
greg
parents:
diff changeset
391 val = db_match
572cf766c59d Uploaded
greg
parents:
diff changeset
392 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
393 val = "match"
572cf766c59d Uploaded
greg
parents:
diff changeset
394 self.log("Found genotype row with id %d, value of db_match: %s, should be %s." % (genotype_id, db_match, val))
572cf766c59d Uploaded
greg
parents:
diff changeset
395 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
396 # Insert a row into the genotype table.
572cf766c59d Uploaded
greg
parents:
diff changeset
397 cmd = "INSERT INTO genotype VALUES (nextval('genotype_id_seq'), NOW(), NOW(), "
572cf766c59d Uploaded
greg
parents:
diff changeset
398 cmd += "'%s', '%s', '%s') RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
399 cmd = cmd % (coral_mlg_clonal_id, coral_mlg_rep_sample_id, genetic_coral_species_call)
572cf766c59d Uploaded
greg
parents:
diff changeset
400 args = [coral_mlg_clonal_id, coral_mlg_rep_sample_id, genetic_coral_species_call]
572cf766c59d Uploaded
greg
parents:
diff changeset
401 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
402 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
403 genotype_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
404 if db_match == "failed":
572cf766c59d Uploaded
greg
parents:
diff changeset
405 val = db_match
572cf766c59d Uploaded
greg
parents:
diff changeset
406 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
407 val = "no_match"
572cf766c59d Uploaded
greg
parents:
diff changeset
408 self.log("Inserted genotype row with id %d, value of db_match: %s, should be %s." % (genotype_id, db_match, val))
572cf766c59d Uploaded
greg
parents:
diff changeset
409 genotype_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
410 self.genotype_ids.append(genotype_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
411 self.log("Inserted %d rows into the genotype table..." % genotype_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
412
572cf766c59d Uploaded
greg
parents:
diff changeset
413 def update_person_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
414 self.log("Updating the person table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
415 # Columns in the person file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
416 # last_name first_name organization email
572cf766c59d Uploaded
greg
parents:
diff changeset
417 person_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
418 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
419 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
420 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
421 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
422 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
423 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
424 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
425 last_name = items[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
426 first_name = items[1]
572cf766c59d Uploaded
greg
parents:
diff changeset
427 organization = items[2]
572cf766c59d Uploaded
greg
parents:
diff changeset
428 email = items[3]
572cf766c59d Uploaded
greg
parents:
diff changeset
429 # See if we need to add a row to the table.
572cf766c59d Uploaded
greg
parents:
diff changeset
430 cmd = "SELECT id FROM person WHERE email = '%s';" % email
572cf766c59d Uploaded
greg
parents:
diff changeset
431 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
432 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
433 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
434 person_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
435 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
436 # Insert a row into the person table.
572cf766c59d Uploaded
greg
parents:
diff changeset
437 cmd = "INSERT INTO person VALUES (nextval('person_id_seq'), NOW(), NOW(), "
572cf766c59d Uploaded
greg
parents:
diff changeset
438 cmd += "%s, %s, %s, %s) RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
439 args = [last_name, first_name, organization, email]
572cf766c59d Uploaded
greg
parents:
diff changeset
440 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
441 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
442 person_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
443 person_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
444 self.person_ids.append(person_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
445 self.log("Inserted %d rows into the person table..." % person_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
446
572cf766c59d Uploaded
greg
parents:
diff changeset
447 def update_phenotype_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
448 self.log("Updating the phenotype table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
449 # Columns in the phenotype file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
450 # disease_resist bleach_resist mortality tle spawning sperm_motility healing_time
572cf766c59d Uploaded
greg
parents:
diff changeset
451 phenotype_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
452 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
453 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
454 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
455 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
456 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
457 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
458 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
459 disease_resist, disease_resist_param_val_str = handle_column_value(items[0], default=-9)
572cf766c59d Uploaded
greg
parents:
diff changeset
460 bleach_resist, bleach_resist_param_val_str = handle_column_value(items[1], default=-9)
572cf766c59d Uploaded
greg
parents:
diff changeset
461 mortality, mortality_param_val_str = handle_column_value(items[2], default=-9)
572cf766c59d Uploaded
greg
parents:
diff changeset
462 tle, tle_param_val_str = handle_column_value(items[3], default=-9)
572cf766c59d Uploaded
greg
parents:
diff changeset
463 spawning, spawning_param_val_str = handle_column_value(items[4])
572cf766c59d Uploaded
greg
parents:
diff changeset
464 sperm_motility, sperm_motility_param_val_str = handle_column_value(items[5], default=-9.0)
572cf766c59d Uploaded
greg
parents:
diff changeset
465 healing_time, healing_time_param_val_str = handle_column_value(items[6], default=-9.0)
572cf766c59d Uploaded
greg
parents:
diff changeset
466 # See if we need to add a row to the phenotype table.
572cf766c59d Uploaded
greg
parents:
diff changeset
467 cmd = " SELECT id FROM phenotype WHERE disease_resist %s "
572cf766c59d Uploaded
greg
parents:
diff changeset
468 cmd += "AND bleach_resist %s AND mortality %s AND tle %s "
572cf766c59d Uploaded
greg
parents:
diff changeset
469 cmd += "AND spawning %s AND sperm_motility %s AND healing_time %s;"
572cf766c59d Uploaded
greg
parents:
diff changeset
470 cmd = cmd % (disease_resist_param_val_str, bleach_resist_param_val_str,
572cf766c59d Uploaded
greg
parents:
diff changeset
471 mortality_param_val_str, tle_param_val_str, spawning_param_val_str,
572cf766c59d Uploaded
greg
parents:
diff changeset
472 sperm_motility_param_val_str, healing_time_param_val_str)
572cf766c59d Uploaded
greg
parents:
diff changeset
473 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
474 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
475 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
476 phenotype_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
477 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
478 # Insert a row into the phenotype table.
572cf766c59d Uploaded
greg
parents:
diff changeset
479 cmd = "INSERT INTO phenotype VALUES (nextval('phenotype_id_seq'), NOW(), NOW(), "
572cf766c59d Uploaded
greg
parents:
diff changeset
480 cmd += "%s, %s, %s, %s, %s, %s, %s) RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
481 args = [disease_resist, bleach_resist, mortality, tle, spawning, sperm_motility, healing_time]
572cf766c59d Uploaded
greg
parents:
diff changeset
482 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
483 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
484 phenotype_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
485 phenotype_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
486 self.phenotype_ids.append(phenotype_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
487 self.log("Inserted %d rows into the phenotype table..." % phenotype_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
488
572cf766c59d Uploaded
greg
parents:
diff changeset
489 def update_reef_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
490 self.log("Updating the reef table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
491 # Columns in the reef file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
492 # name region latitude longitude geographic_origin
572cf766c59d Uploaded
greg
parents:
diff changeset
493 # The geographic_origin value is used for deciding into which table
572cf766c59d Uploaded
greg
parents:
diff changeset
494 # to insert the latitude and longitude values. If the geographic_origin
572cf766c59d Uploaded
greg
parents:
diff changeset
495 # is "reef", the values will be inserted into the reef table.
572cf766c59d Uploaded
greg
parents:
diff changeset
496 reef_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
497 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
498 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
499 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
500 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
501 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
502 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
503 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
504 name = items[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
505 region = items[1]
572cf766c59d Uploaded
greg
parents:
diff changeset
506 geographic_origin = items[4]
572cf766c59d Uploaded
greg
parents:
diff changeset
507 if set_to_null(geographic_origin):
572cf766c59d Uploaded
greg
parents:
diff changeset
508 geographic_origin = "reef"
572cf766c59d Uploaded
greg
parents:
diff changeset
509 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
510 geographic_origin = geographic_origin.lower()
572cf766c59d Uploaded
greg
parents:
diff changeset
511 if geographic_origin == "reef":
572cf766c59d Uploaded
greg
parents:
diff changeset
512 latitude = "%6f" % float(items[2])
572cf766c59d Uploaded
greg
parents:
diff changeset
513 longitude = "%6f" % float(items[3])
572cf766c59d Uploaded
greg
parents:
diff changeset
514 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
515 latitude = DEFAULT_MISSING_NUMERIC_VALUE
572cf766c59d Uploaded
greg
parents:
diff changeset
516 longitude = DEFAULT_MISSING_NUMERIC_VALUE
572cf766c59d Uploaded
greg
parents:
diff changeset
517 # See if we need to add a row to the reef table.
572cf766c59d Uploaded
greg
parents:
diff changeset
518 cmd = "SELECT id FROM reef WHERE name = $$%s$$ AND region = '%s' " % (name, region)
572cf766c59d Uploaded
greg
parents:
diff changeset
519 cmd += "AND latitude = %s AND longitude = %s " % (latitude, longitude)
572cf766c59d Uploaded
greg
parents:
diff changeset
520 cmd += "AND geographic_origin = '%s';" % geographic_origin
572cf766c59d Uploaded
greg
parents:
diff changeset
521 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
522 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
523 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
524 reef_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
525 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
526 # Insert a row into the reef table.
572cf766c59d Uploaded
greg
parents:
diff changeset
527 cmd = "INSERT INTO reef VALUES (nextval('reef_id_seq'), %s, %s, %s, %s, %s, %s, %s) RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
528 args = ['NOW()', 'NOW()', name, region, latitude, longitude, geographic_origin]
572cf766c59d Uploaded
greg
parents:
diff changeset
529 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
530 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
531 reef_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
532 reef_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
533 self.reef_ids.append(reef_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
534 self.log("Inserted %d rows into the reef table..." % reef_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
535
572cf766c59d Uploaded
greg
parents:
diff changeset
536 def update_sample_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
537 self.log("Updating the sample table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
538 # Columns in the sample file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
539 # affy_id colony_location collection_date user_specimen_id registry_id
572cf766c59d Uploaded
greg
parents:
diff changeset
540 # depth dna_extraction_method dna_concentration public public_after_date
3
18a1fae17003 Uploaded
greg
parents: 2
diff changeset
541 # percent_missing_data_coral percent_missing_data_sym percent_acerv_coral percent_reference_sym percent_apalm_coral
0
572cf766c59d Uploaded
greg
parents:
diff changeset
542 # percent_alternative_sym percent_heterozygous_coral percent_heterozygous_sym field_call, bcoral_genet_id
572cf766c59d Uploaded
greg
parents:
diff changeset
543 sample_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
544 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
545 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
546 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
547 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
548 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
549 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
550 # Keep track of foreign keys since we skip the header line.
572cf766c59d Uploaded
greg
parents:
diff changeset
551 id_index = i - 1
572cf766c59d Uploaded
greg
parents:
diff changeset
552 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
553 sample_id = self.get_next_sample_id()
572cf766c59d Uploaded
greg
parents:
diff changeset
554 allele_id = self.allele_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
555 genotype_id = self.genotype_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
556 phenotype_id = self.phenotype_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
557 experiment_id = self.experiment_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
558 colony_id = self.colony_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
559 colony_location = handle_column_value(items[1], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
560 taxonomy_id = self.taxonomy_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
561 collector_id = self.person_ids[id_index]
572cf766c59d Uploaded
greg
parents:
diff changeset
562 collection_date = items[2]
572cf766c59d Uploaded
greg
parents:
diff changeset
563 user_specimen_id = items[3]
572cf766c59d Uploaded
greg
parents:
diff changeset
564 affy_id = handle_column_value(items[0], get_sql_param=False, default="%s_%s" % (sample_id, user_specimen_id))
572cf766c59d Uploaded
greg
parents:
diff changeset
565 registry_id = handle_column_value(items[4], get_sql_param=False, default=-9)
2
681d8497a691 Uploaded
greg
parents: 1
diff changeset
566 depth = handle_column_value(items[5], get_sql_param=False, default=-9.0)
0
572cf766c59d Uploaded
greg
parents:
diff changeset
567 dna_extraction_method = handle_column_value(items[6], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
568 dna_concentration = handle_column_value(items[7], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
569 public = items[8]
572cf766c59d Uploaded
greg
parents:
diff changeset
570 if string_as_bool(public):
572cf766c59d Uploaded
greg
parents:
diff changeset
571 public_after_date = ''
572cf766c59d Uploaded
greg
parents:
diff changeset
572 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
573 if set_to_null(items[9]):
572cf766c59d Uploaded
greg
parents:
diff changeset
574 public_after_date = self.year_from_now
572cf766c59d Uploaded
greg
parents:
diff changeset
575 else:
572cf766c59d Uploaded
greg
parents:
diff changeset
576 public_after_date = items[9]
572cf766c59d Uploaded
greg
parents:
diff changeset
577 percent_missing_data_coral = handle_column_value(items[10], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
578 percent_missing_data_sym = handle_column_value(items[11], get_sql_param=False)
3
18a1fae17003 Uploaded
greg
parents: 2
diff changeset
579 percent_acerv_coral = handle_column_value(items[12], get_sql_param=False)
0
572cf766c59d Uploaded
greg
parents:
diff changeset
580 percent_reference_sym = handle_column_value(items[13], get_sql_param=False)
3
18a1fae17003 Uploaded
greg
parents: 2
diff changeset
581 percent_apalm_coral = handle_column_value(items[14], get_sql_param=False)
0
572cf766c59d Uploaded
greg
parents:
diff changeset
582 percent_alternative_sym = handle_column_value(items[15], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
583 percent_heterozygous_coral = handle_column_value(items[16], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
584 percent_heterozygous_sym = handle_column_value(items[17], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
585 field_call = handle_column_value(items[18], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
586 bcoral_genet_id = handle_column_value(items[19], get_sql_param=False)
572cf766c59d Uploaded
greg
parents:
diff changeset
587 # Insert a row into the sample table.
572cf766c59d Uploaded
greg
parents:
diff changeset
588 cmd = "INSERT INTO sample VALUES (nextval('sample_id_seq'), %s, %s, %s, %s, %s, %s, %s, "
572cf766c59d Uploaded
greg
parents:
diff changeset
589 cmd += "%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
572cf766c59d Uploaded
greg
parents:
diff changeset
590 cmd += "%s, %s, %s, %s) RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
591 args = ['NOW()', 'NOW()', affy_id, sample_id, allele_id, genotype_id, phenotype_id,
572cf766c59d Uploaded
greg
parents:
diff changeset
592 experiment_id, colony_id, colony_location, taxonomy_id, collector_id,
572cf766c59d Uploaded
greg
parents:
diff changeset
593 collection_date, user_specimen_id, registry_id, depth,
572cf766c59d Uploaded
greg
parents:
diff changeset
594 dna_extraction_method, dna_concentration, public, public_after_date,
3
18a1fae17003 Uploaded
greg
parents: 2
diff changeset
595 percent_missing_data_coral, percent_missing_data_sym, percent_acerv_coral,
18a1fae17003 Uploaded
greg
parents: 2
diff changeset
596 percent_reference_sym, percent_apalm_coral, percent_alternative_sym,
0
572cf766c59d Uploaded
greg
parents:
diff changeset
597 percent_heterozygous_coral, percent_heterozygous_sym, field_call, bcoral_genet_id]
572cf766c59d Uploaded
greg
parents:
diff changeset
598 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
599 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
600 sample_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
601 sample_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
602 self.log("Inserted %d rows into the sample table..." % sample_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
603
572cf766c59d Uploaded
greg
parents:
diff changeset
604 def update_taxonomy_table(self, file_path):
572cf766c59d Uploaded
greg
parents:
diff changeset
605 self.log("Updating the taxonomy table...")
572cf766c59d Uploaded
greg
parents:
diff changeset
606 # Columns in the taxonomy file are:
572cf766c59d Uploaded
greg
parents:
diff changeset
607 # genetic_coral_species_call affy_id genus_name species_name"
572cf766c59d Uploaded
greg
parents:
diff changeset
608 taxonomy_table_inserts = 0
572cf766c59d Uploaded
greg
parents:
diff changeset
609 with open(file_path) as fh:
572cf766c59d Uploaded
greg
parents:
diff changeset
610 for i, line in enumerate(fh):
572cf766c59d Uploaded
greg
parents:
diff changeset
611 if i == 0:
572cf766c59d Uploaded
greg
parents:
diff changeset
612 # Skip header
572cf766c59d Uploaded
greg
parents:
diff changeset
613 continue
572cf766c59d Uploaded
greg
parents:
diff changeset
614 line = line.rstrip()
572cf766c59d Uploaded
greg
parents:
diff changeset
615 items = split_line(line)
572cf766c59d Uploaded
greg
parents:
diff changeset
616 genus_name = handle_column_value(items[2], get_sql_param=False, default='unknown')
572cf766c59d Uploaded
greg
parents:
diff changeset
617 species_name = handle_column_value(items[3], get_sql_param=False, default='unknown')
572cf766c59d Uploaded
greg
parents:
diff changeset
618 # See if we need to add a row to the taxonomy table.
572cf766c59d Uploaded
greg
parents:
diff changeset
619 cmd = "SELECT id FROM taxonomy WHERE species_name = '%s' AND genus_name = '%s';" % (species_name, genus_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
620 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
621 cur.execute(cmd)
572cf766c59d Uploaded
greg
parents:
diff changeset
622 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
623 taxonomy_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
624 except Exception:
572cf766c59d Uploaded
greg
parents:
diff changeset
625 # Insert a row into the taxonomy table.
572cf766c59d Uploaded
greg
parents:
diff changeset
626 cmd = "INSERT INTO taxonomy VALUES (nextval('taxonomy_id_seq'), %s, %s, %s, %s) RETURNING id;"
572cf766c59d Uploaded
greg
parents:
diff changeset
627 args = ['NOW()', 'NOW()', species_name, genus_name]
572cf766c59d Uploaded
greg
parents:
diff changeset
628 cur = self.update(cmd, args)
572cf766c59d Uploaded
greg
parents:
diff changeset
629 self.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
630 taxonomy_id = cur.fetchone()[0]
572cf766c59d Uploaded
greg
parents:
diff changeset
631 taxonomy_table_inserts += 1
572cf766c59d Uploaded
greg
parents:
diff changeset
632 self.taxonomy_ids.append(taxonomy_id)
572cf766c59d Uploaded
greg
parents:
diff changeset
633 self.log("Inserted %d rows into the taxonomy table..." % taxonomy_table_inserts)
572cf766c59d Uploaded
greg
parents:
diff changeset
634
572cf766c59d Uploaded
greg
parents:
diff changeset
635 def parse_args(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
636 parser = argparse.ArgumentParser()
572cf766c59d Uploaded
greg
parents:
diff changeset
637 parser.add_argument('--config_file', dest='config_file', help='usd_config.ini'),
572cf766c59d Uploaded
greg
parents:
diff changeset
638 parser.add_argument('--database_connection_string', dest='database_connection_string', help='Postgres database connection string'),
572cf766c59d Uploaded
greg
parents:
diff changeset
639 parser.add_argument('--input_dir', dest='input_dir', help='Input datasets for database insertion')
572cf766c59d Uploaded
greg
parents:
diff changeset
640 parser.add_argument('--output', dest='output', help='Output dataset'),
572cf766c59d Uploaded
greg
parents:
diff changeset
641 self.args = parser.parse_args()
572cf766c59d Uploaded
greg
parents:
diff changeset
642
572cf766c59d Uploaded
greg
parents:
diff changeset
643 def run(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
644 self.export_database()
572cf766c59d Uploaded
greg
parents:
diff changeset
645 input_dir = self.args.input_dir
572cf766c59d Uploaded
greg
parents:
diff changeset
646 for file_name in os.listdir(input_dir):
572cf766c59d Uploaded
greg
parents:
diff changeset
647 # Tables must be loaded in such a way that foreign keys
572cf766c59d Uploaded
greg
parents:
diff changeset
648 # are properly handled. The sample table must be loaded
572cf766c59d Uploaded
greg
parents:
diff changeset
649 # last.
572cf766c59d Uploaded
greg
parents:
diff changeset
650 if file_name.startswith("allele"):
572cf766c59d Uploaded
greg
parents:
diff changeset
651 allele_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
652 if file_name.startswith("colony"):
572cf766c59d Uploaded
greg
parents:
diff changeset
653 colony_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
654 if file_name.startswith("experiment"):
572cf766c59d Uploaded
greg
parents:
diff changeset
655 experiment_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
656 if file_name.startswith("genotype"):
572cf766c59d Uploaded
greg
parents:
diff changeset
657 genotype_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
658 elif file_name.startswith("person"):
572cf766c59d Uploaded
greg
parents:
diff changeset
659 person_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
660 elif file_name.startswith("phenotype"):
572cf766c59d Uploaded
greg
parents:
diff changeset
661 phenotype_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
662 elif file_name.startswith("reef"):
572cf766c59d Uploaded
greg
parents:
diff changeset
663 reef_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
664 elif file_name.startswith("sample"):
572cf766c59d Uploaded
greg
parents:
diff changeset
665 sample_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
666 elif file_name.startswith("taxonomy"):
572cf766c59d Uploaded
greg
parents:
diff changeset
667 taxonomy_file = os.path.join(input_dir, file_name)
572cf766c59d Uploaded
greg
parents:
diff changeset
668 # Now tables can be loaded in the appropriate order.
572cf766c59d Uploaded
greg
parents:
diff changeset
669 self.update_experiment_table(experiment_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
670 self.update_genotype_table(genotype_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
671 self.update_allele_table(allele_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
672 self.update_person_table(person_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
673 self.update_phenotype_table(phenotype_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
674 self.update_reef_table(reef_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
675 self.update_colony_table(colony_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
676 self.update_taxonomy_table(taxonomy_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
677 self.update_sample_table(sample_file)
572cf766c59d Uploaded
greg
parents:
diff changeset
678
572cf766c59d Uploaded
greg
parents:
diff changeset
679 def shutdown(self):
572cf766c59d Uploaded
greg
parents:
diff changeset
680 self.log("Shutting down...")
572cf766c59d Uploaded
greg
parents:
diff changeset
681 self.outfh.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
682 self.outfh.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
683 self.conn.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
684
572cf766c59d Uploaded
greg
parents:
diff changeset
685 def update(self, cmd, args):
572cf766c59d Uploaded
greg
parents:
diff changeset
686 for i, arg in enumerate(args):
572cf766c59d Uploaded
greg
parents:
diff changeset
687 args[i] = handle_null(arg)
572cf766c59d Uploaded
greg
parents:
diff changeset
688 try:
572cf766c59d Uploaded
greg
parents:
diff changeset
689 cur = self.conn.cursor()
572cf766c59d Uploaded
greg
parents:
diff changeset
690 cur.execute(cmd, tuple(args))
572cf766c59d Uploaded
greg
parents:
diff changeset
691 except Exception as e:
572cf766c59d Uploaded
greg
parents:
diff changeset
692 msg = "Caught exception executing SQL:\n%s\nException:\n%s\n" % (cmd.format(args), e)
572cf766c59d Uploaded
greg
parents:
diff changeset
693 sys.stderr.write(msg)
572cf766c59d Uploaded
greg
parents:
diff changeset
694 self.outfh.flush()
572cf766c59d Uploaded
greg
parents:
diff changeset
695 self.outfh.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
696 self.conn.close()
572cf766c59d Uploaded
greg
parents:
diff changeset
697 sys.exit(1)
572cf766c59d Uploaded
greg
parents:
diff changeset
698 return cur
572cf766c59d Uploaded
greg
parents:
diff changeset
699
572cf766c59d Uploaded
greg
parents:
diff changeset
700
572cf766c59d Uploaded
greg
parents:
diff changeset
701 if __name__ == '__main__':
572cf766c59d Uploaded
greg
parents:
diff changeset
702 sdu = StagDatabaseUpdater()
572cf766c59d Uploaded
greg
parents:
diff changeset
703 sdu.run()
572cf766c59d Uploaded
greg
parents:
diff changeset
704 sdu.shutdown()