IMP logo
IMP Reference Guide  2.17.0
The Integrative Modeling Platform
solutions_io.py
1 """@namespace IMP.EMageFit.solutions_io
2  Utility functions to store and retrieve solution information.
3 """
4 
6 import IMP.EMageFit.database as database
7 
8 import heapq
9 import logging
10 import numpy as np
11 import collections
12 
13 log = logging.getLogger("solutions_io")
14 
15 unit_delim = "/" # separate units within a field (eg, reference frames).
16 field_delim = ","
17 
18 ClusterRecord = collections.namedtuple(
19  'ClusterRecord',
20  ['cluster_id', 'n_elements', 'representative', 'elements',
21  'solutions_ids'])
22 
23 
24 #
25 # INPUT/OUTPUT OF SOLUTIONS OBTAINED WITH DominoModel
26 #
27 class HeapRecord(tuple):
28 
29  """
30  The heapq algorithm is a min-heap. I want a max-heap, that pops the
31  larger values out of the heap.
32  For that I have to modify the comparison function and also set the
33  index that is used for the comparison. The index corresponds to
34  the restraint that we desired to order by
35  """
36 
37  def __new__(self, x, i):
38  """
39  Build from a tuple and the index used to compare
40  """
41  self.i = i
42  return tuple.__new__(self, x)
43 
44  def __lt__(self, other):
45  """
46  Compare. To convert the min-heap into a max-heap, the lower than
47  comparison is transformed into a greater-than
48  """
49  i = self.i
50  if(self[i] > other[i]):
51  return True
52  return False
53 
54  # Need __le__ as well for older Pythons
55  def __le__(self, other):
56  i = self.i
57  return self[i] >= other[i]
58 
59 
60 def gather_best_solution_results(fns, fn_output, max_number=50000,
61  raisef=0.1, orderby="em2d"):
62  """
63  Reads a set of database files and merge them into a single file.
64 
65  @param fns List of files with databases
66  @param fn_output The database to create
67  @param max_number Maximum number of records to keep, sorted according
68  to orderby
69  @param raisef Ratio of problematic database files tolerated before
70  raising an error. This option is to tolerate some files
71  of the databases being broken because the cluster fails,
72  fill the disks, etc
73  @param orderby Criterion used to sort the records
74  NOTE:
75  Makes sure to reorder all column names if necessary before merging
76  The record for the native solution is only added once (from first file).
77  """
78  tbl = "results"
79  # Get names and types of the columns from first database file
80  db = database.Database2()
81  db.connect(fns[0])
82  names = db.get_table_column_names(tbl)
83  types = db.get_table_types(tbl)
84  indices = get_sorting_indices(names)
85  sorted_names = [names[i] for i in indices]
86  sorted_types = [types[i] for i in indices]
87 
88  names.sort()
89  ind = names.index(orderby)
90  they_are_sorted = field_delim.join(names)
91  # Get the native structure data from the first database
92  sql_command = """SELECT %s FROM %s WHERE assignment="native"
93  LIMIT 1 """ % (they_are_sorted, tbl)
94  native_data = db.retrieve_data(sql_command)
95  db.close()
96  log.info("Gathering results. Saving to %s", fn_output)
97  out_db = database.Database2()
98  out_db.create(fn_output, overwrite=True)
99  out_db.connect(fn_output)
100  out_db.create_table(tbl, sorted_names, sorted_types)
101 
102  best_records = []
103  n_problems = 0
104  for fn in fns:
105  try:
106  log.info("Reading %s", fn)
107  db.connect(fn)
108 # log.debug("Retrieving %s", they_are_sorted)
109  sql_command = """SELECT %s FROM %s
110  WHERE assignment<>"native"
111  ORDER BY %s ASC LIMIT %s """ % (
112  they_are_sorted, tbl, orderby, max_number)
113  data = db.retrieve_data(sql_command)
114  log.info("%s records read from %s", len(data), fn)
115  db.close()
116  # Fill heap
117  for d in data:
118  a = HeapRecord(d, ind)
119  if(len(best_records) < max_number):
120  heapq.heappush(best_records, a)
121  else:
122  # remember that < here compares for greater em2d value,
123  # as a HeapRecord is used
124  if(best_records[0] < a):
125  heapq.heapreplace(best_records, a)
126  except Exception as e:
127  log.error("Error for %s: %s", fn, e)
128  n_problems += 1
129 
130  # If the number of problematic files is too high, report that something
131  # big is going on. Otherwise tolerate some errors from some tasks that
132  # failed (memory errors, locks, writing errors ...)
133  ratio = float(n_problems) / float(len(fns))
134  if ratio > raisef:
135  raise IOError("There are %8.1f %s of the database "
136  "files to merge with problems! " % (ratio * 100, "%"))
137  # append the native data to the best_records
138  heapq.heappush(best_records, native_data[0])
139  out_db.store_data(tbl, best_records)
140  out_db.close()
141 
142 
143 def gather_solution_results(fns, fn_output, raisef=0.1):
144  """
145  Reads a set of database files and puts them in a single file
146  Makes sure to reorder all column names if necessary before merging
147  @param fns List of database files
148  @param fn_output Name of the output database
149  @param raisef See help for gather_best_solution_results()
150  """
151  tbl = "results"
152  # Get names and types of the columns from first database file
153  db = database.Database2()
154  db.connect(fns[0])
155  names = db.get_table_column_names(tbl)
156  types = db.get_table_types(tbl)
157  indices = get_sorting_indices(names)
158  sorted_names = [names[i] for i in indices]
159  sorted_types = [types[i] for i in indices]
160  log.info("Gathering results. Saving to %s", fn_output)
161  out_db = database.Database2()
162  out_db.create(fn_output, overwrite=True)
163  out_db.connect(fn_output)
164  out_db.create_table(tbl, sorted_names, sorted_types)
165 
166  n_problems = 0
167  for fn in fns:
168  try:
169  log.info("Reading %s", fn)
170  db.connect(fn)
171  names = sorted(db.get_table_column_names(tbl))
172  they_are_sorted = field_delim.join(names)
173  log.debug("Retrieving %s", they_are_sorted)
174  sql_command = "SELECT %s FROM %s" % (they_are_sorted, tbl)
175  data = db.retrieve_data(sql_command)
176  out_db.store_data(tbl, data)
177  db.close()
178  except Exception as e:
179  log.error("Error for file %s: %s", fn, e)
180  n_problems += 1
181  ratio = float(n_problems) / float(len(fns))
182  if ratio > raisef:
183  raise IOError("There are %8.1f %s of the database "
184  "files to merge with problems! " % (ratio * 100, "%"))
185  out_db.close()
186 
187 
189  """ Return indices that sort the list ls"""
190  pairs = sorted([(element, i) for i, element in enumerate(ls)])
191  indices = [p[1] for p in pairs]
192  return indices
193 
194 
195 def get_best_solution(fn_database, Nth, fields=False, orderby=False,
196  tbl="results"):
197  """
198  Recover the reference frame of the n-th best solution from a database.
199  The index Nth stars at 0
200  """
201  f = get_fields_string(fields)
202  sql_command = """ SELECT %s FROM %s
203  ORDER BY %s
204  ASC LIMIT 1 OFFSET %d """ % (f, tbl, orderby, Nth)
205  data = database.read_data(fn_database, sql_command)
206  if len(data) == 0:
207  raise ValueError("The requested %s-th best solution does not exist. "
208  "Only %s solutions found" % (Nth, len(data)))
209  # the only field last record is the solution requested
210  return data[0][0]
211 
212 
213 def get_pca(string, delimiter="/"):
214  pca = string.split(delimiter)
215  pca = [float(p) for p in pca]
216  return pca
217 
218 
219 def get_fields_string(fields):
220  """
221  Get a list of fields and return a string with them. If there are no
222  fields, return an *, indicating SQL that all the fields are requested
223  @param fields A list of strings
224  @return a string
225  """
226 
227  if fields:
228  return field_delim.join(fields)
229  return "*"
230 
231 
233 
234  """
235  Class for managing the results of the experiments
236  """
237 
238  def __init__(self, ):
239  self.records = []
240  self.native_table_name = "native"
241  self.results_table = "results"
242  self.placements_table = "placements"
243  self.ccc_table_name = "ccc"
244  self.cluster_records = []
245 
246  # columns describing a solution in the results
247  self.results_description_columns = ["solution_id", "assignment",
248  "reference_frames"]
249  self.results_description_types = [int, str, str]
250  # columns describing measures for a result
251  self.results_measures_columns = ["drms", "cdrms", "crmsd"]
252  self.results_measures_types = [float, float, float]
253 
254  def add_results_table(self, restraints_names, add_measures=False):
255  """
256  Build the table of results
257  @param restraints_names The names given to the columns of the table
258  @param add_measures If True, add fields for comparing models
259  and native conformation
260  """
261  table_fields = self.results_description_columns + \
262  ["total_score"] + restraints_names
263  table_types = self.results_description_types + \
264  [float] + [float for r in restraints_names]
265  if add_measures:
266  # Add columns for measures
267  table_fields += self.results_measures_columns
268  table_types += self.results_measures_types
269  log.debug("Creating table %s\n%s", table_fields, table_types)
270  self.create_table(self.results_table, table_fields, table_types)
271  # create a table for the native assembly if we are benchmarking
272  if add_measures:
273  self.create_table(
274  self.native_table_name,
275  table_fields,
276  table_types)
277 
278  def get_solutions_results_table(self, fields=False,
279  max_number=None, orderby=False):
280  """
281  Recovers solutions
282  @param fields Fields to recover from the table
283  @param max_number Maximum number of solutions to recover
284  @param orderby Name of the restraint used for sorting the states
285  """
286  self.check_if_is_connected()
287  log.info("Getting %s from solutions", fields)
288  f = self.get_fields_string(fields)
289  sql_command = "SELECT %s FROM %s " % (f, self.results_table)
290  if orderby:
291  sql_command += " ORDER BY %s ASC" % orderby
292  if max_number not in (None, False):
293  sql_command += " LIMIT %d" % (max_number)
294  log.debug("Using %s", sql_command)
295  data = self.retrieve_data(sql_command)
296  return data
297 
298  def get_solutions(self, fields=False, max_number=None, orderby=False):
299  """
300  Get solutions from the database.
301  @param fields Fields requested. If the fields are in different
302  tables, a left join is done. Otherwise
303  get_solutions_results_table() is called. See
304  get_solutions_results_table() for the meaning
305  of the parameters.
306  @param max_number
307  @param orderby
308  """
309  tables = self.get_tables_names()
310  log.debug("tables %s", tables)
311  required_tables = set()
312  pairs_table_field = []
313 # fields_string = self.get_fields_string(fields)
314  if not fields:
315  fields = ["*", ]
316  for f, t in [(f, t) for f in fields for t in tables]:
317  if t == "native" or f == "solution_id":
318  continue
319  columns = self.get_table_column_names(t)
320  if f in columns:
321  required_tables.add(t)
322  pairs_table_field.append((t, f))
323  required_tables = list(required_tables)
324  log.debug("required_tables %s", required_tables)
325  log.debug("pairs_table_field %s", pairs_table_field)
326  if len(required_tables) == 0:
327  data = self.get_solutions_results_table(fields,
328  max_number, orderby)
329  return data
330  elif len(required_tables) == 1 and required_tables[0] == "results":
331  data = self.get_solutions_results_table(fields,
332  max_number, orderby)
333  return data
334  elif len(required_tables) > 1:
335  sql_command = self.get_left_join_command(pairs_table_field,
336  required_tables)
337  if orderby:
338  sql_command += " ORDER BY %s ASC" % orderby
339  log.debug("Using %s", sql_command)
340  data = self.retrieve_data(sql_command)
341  return data
342  else:
343  raise ValueError("Fields not found in the database")
344 
345  def get_native_solution(self, fields=False):
346  """
347  Recover data for the native solution
348  @param fields Fields to recover
349  """
350 
351  f = self.get_fields_string(fields)
352  sql_command = "SELECT %s FROM %s " % (f, self.native_table_name)
353  data = self.retrieve_data(sql_command)
354  return data
355 
356  def add_record(self, solution_id, assignment, RFs, total_score,
357  restraints_scores, measures):
358  """
359  Add a record to the database
360  @param solution_id The key for the solution
361  @param assignment The assignment for the solution provided by
362  domino
363  @param RFs Reference frames of the rigid bodies of the components
364  of the assembly in the solution
365  @param total_score Total value of the scoring function
366  @param restraints_scores A list with all the values for the
367  restraints
368  @param measures A list with the values of all the measures for
369  benchmark
370  """
371  words = [io.ReferenceFrameToText(ref).get_text() for ref in RFs]
372  RFs_txt = unit_delim.join(words)
373  record = [solution_id, assignment, RFs_txt, total_score] + \
374  restraints_scores
375  if measures is not None:
376  record = record + measures
377  self.records.append(record)
378 
379  def add_native_record(self, assignment, RFs, total_score,
380  restraints_scores):
381  """
382  Add a record for the native structure to the database
383  see add_record() for the meaning of the parameters
384  """
385  words = [io.ReferenceFrameToText(ref).get_text() for ref in RFs]
386  RFs_txt = unit_delim.join(words)
387  solution_id = 0
388  record = [solution_id, assignment, RFs_txt, total_score] + \
389  restraints_scores
390  measures = [0, 0, 0] # ["drms", "cdrms", "crmsd"]
391  record = record + measures
392  self.store_data(self.native_table_name, [record])
393 
394  def save_records(self, table="results"):
395  self.store_data(table, self.records)
396 
397  def format_placement_record(self, solution_id, distances, angles):
398  """ both distances and angles are expected to be a list of floats """
399  return [solution_id] + distances + angles
400 
401  def add_placement_scores_table(self, names):
402  """
403  Creates a table to store the values of the placement scores for the
404  models.
405  @param names Names of the components of the assembly
406  """
407  self.check_if_is_connected()
408  self.placement_table_name = self.placements_table
409  table_fields = ["solution_id"]
410  table_fields += ["distance_%s" % name for name in names]
411  table_fields += ["angle_%s" % name for name in names]
412  table_types = [int] + [float for f in table_fields]
413  self.drop_table(self.placement_table_name)
414  self.create_table(self.placement_table_name, table_fields, table_types)
415  self.add_columns(self.native_table_name,
416  table_fields, table_types, check=True)
417  # update all placements scores to 0 for the native assembly
418  native_values = [0 for t in table_fields]
419  log.debug("%s", self.native_table_name)
420  log.debug("table fields %s", table_fields)
421  self.update_data(self.native_table_name,
422  table_fields, native_values,
423  ["assignment"], ["\"native\""])
424 
426  """
427  Return the names of the placement score fields in the database
428  """
429  columns = self.get_table_column_names(self.placements_table)
430  fields = [
431  col for col in columns if "distance" in col or "angle" in col]
432  return fields
433 
434  def add_ccc_table(self):
435  """
436  Add a table to the database for store the values of the cross
437  correlation coefficient between a model and the native
438  configuration
439  """
440 
441  self.check_if_is_connected()
442  table_fields = ["solution_id", "ccc"]
443  table_types = [int, float]
444  self.drop_table(self.ccc_table_name)
445  self.create_table(self.ccc_table_name, table_fields, table_types)
446  # update values for the native assembly
447  self.add_columns(self.native_table_name,
448  table_fields, table_types, check=True)
449  self.update_data(self.native_table_name,
450  table_fields, [0, 1.00],
451  ["assignment"], ["\"native\""])
452 
453  def format_ccc_record(self, solution_id, ccc):
454  """ Format for the record to store in the ccc table """
455  return [solution_id, ccc]
456 
457  def get_ccc(self, solution_id):
458  """
459  Recover the cross-correlation coefficient for a solution
460  @param solution_id
461  """
462  sql_command = """ SELECT ccc FROM %s
463  WHERE solution_id=%d """ % (self.ccc_table_name,
464  solution_id)
465  data = self.retrieve_data(sql_command)
466  return data[0][0]
467 
468  def store_ccc_data(self, ccc_data):
469  self.store_data(self.ccc_table_name, ccc_data)
470 
471  def store_placement_data(self, data):
472  log.debug("store placement table %s", data)
473  self.store_data(self.placement_table_name, data)
474 
475  def get_left_join_command(self, pairs_table_field, tables_names):
476  """
477  Format a left join SQL command that recovers all fields from the
478  tables given
479  @param pairs_table_field Pairs of (table,field)
480  @param tables_names Names of the tables
481 
482  E.g. If pairs_table_filed = ((table1,a), (table2,b), (table3,c),
483  (table2,d)) and tables_names = (table1, table2, table3)
484 
485  The SQL command is:
486  SELECT table1.a, table2.b, table3.c, table2.d FROM table1
487  LEFT JOIN table2 ON table1.solution_id = table2.solution_id
488  LEFT JOIN table3 ON table1.solution_id = table3.solution_id
489  WHERE table1.solution_id IS NOT NULL AND
490  table2.solution_id IS NOT NULL AND
491  table3.solution_id IS NOT NULL
492  """
493 
494  txt = ["%s.%s" % (p[0], p[1]) for p in pairs_table_field]
495  fields_requested = field_delim.join(txt)
496  sql_command = " SELECT %s FROM %s " % (
497  fields_requested, tables_names[0])
498  n_tables = len(tables_names)
499  for i in range(1, n_tables):
500  a = tables_names[i - 1]
501  b = tables_names[i]
502  sql_command += " LEFT JOIN %s " \
503  "ON %s.solution_id = %s.solution_id " % (b, a, b)
504  # add the condition of solution_id being not null, so there are not
505  # problems if some solutions are missing in one table
506  for i in range(n_tables - 1):
507  sql_command += "WHERE %s.solution_id " \
508  "IS NOT NULL AND " % tables_names[
509  i]
510  sql_command += " %s.solution_id IS NOT NULL " % tables_names[
511  n_tables - 1]
512  log.debug("%s" % sql_command)
513  return sql_command
514 
515  def add_clusters_table(self, name):
516  """
517  Add a table to store information about the clusters of structures
518  @param name Name of the table
519  """
520  self.cluster_table_name = name
521  self.check_if_is_connected()
522  table_fields = ("cluster_id", "n_elements",
523  "representative", "elements", "solutions_ids")
524  table_types = (int, int, int, str, str)
525  self.drop_table(name)
526  self.create_table(name, table_fields, table_types)
527 
528  def add_cluster_record(self, cluster_id, n_elements, representative,
529  elements, solutions_ids):
530  """
531  Add a record to the cluster database. Actually, only stores it
532  in a list (that will be added later)
533  @param cluster_id Number with the id of the cluster
534  @param n_elements Number of elements in the cluster
535  @param representative Number with the id of the representative
536  element
537  @param elements List with the number of the elements of the cluster
538  @param solutions_ids The numbers above are provided by the
539  clustering algorithm. The solutions_ids are the ids of the models
540  in "elements".
541  """
542 
543  record = (cluster_id, n_elements, representative, elements,
544  solutions_ids)
545  log.debug("Adding cluster record: %s", record)
546  self.cluster_records.append(record)
547 
549  """
550  Store the data for the clusters
551  """
552  log.info("Storing data of clusters. Number of records %s",
553  len(self.cluster_records))
554  self.store_data(self.cluster_table_name, self.cluster_records)
555 
556  def get_solutions_from_list(self, fields=False, solutions_ids=[]):
557  """
558  Recover solutions for a specific list of results
559  @param fields Fields to recover fro the database
560  @param solutions_ids A list with the desired solutions.
561  E.g. [0,3,6]
562  """
563  sql_command = """ SELECT %s FROM %s WHERE solution_id IN (%s) """
564  f = self.get_fields_string(fields)
565  str_ids = ",".join(map(str, solutions_ids))
566  data = self.retrieve_data(
567  sql_command %
568  (f, self.results_table, str_ids))
569  return data
570 
571  def get_native_rank(self, orderby):
572  """
573  Get the position of the native configuration
574  @param orderby Criterion used to sort the solutions
575  """
576  import numpy as np
577 
578  data = self.get_native_solution([orderby, ])
579  native_value = data[0][0]
580  data = self.get_solutions_results_table(fields=[orderby, ],
581  orderby=orderby)
582  values = [row[0] for row in data]
583  rank = np.searchsorted(values, native_value)
584  return rank
585 
586  def get_nth_largest_cluster(self, position, table_name="clusters"):
587  """
588  Recover the information about the n-th largest cluster
589  @param position Cluster position (by size) requested
590  (1 is the largest cluster)
591  @param table_name Table where the information about the
592  clusters is stored
593  """
594  s = """ SELECT * FROM %s ORDER BY n_elements DESC """ % table_name
595  data = self.retrieve_data(s)
596  record = ClusterRecord(*data[position - 1])
597  return record
598 
599  def get_individual_placement_statistics(self, solutions_ids):
600  """
601  Recovers from the database the placement scores for a set of
602  solutions, and returns the mean and standard deviation of the
603  placement score for each of the components of the complex being
604  scored. This function will be typically used to compute the
605  variation of the placement of each component within a cluster
606  of solutions
607  @param solutions_ids The ids of the solutions used to compute
608  the statistics
609  @return The output are 4 numpy vectors:
610  placement_distances_mean - The mean placement distance for each
611  component
612  placement_distances_stddev - The standard deviation of the
613  placement distance for each
614  component
615  placement_angles_mean - The mean placement angle for each
616  component
617  placement_angles_stddev - The standard deviation of the
618  placement angle for each component.
619  """
620 
621  self.check_if_is_connected()
622  table = self.placements_table
623  fields = self.get_table_column_names(table)
624  distance_fields = [x for x in fields if 'distance' in x]
625  angle_fields = [x for x in fields if 'angle' in x]
626  sql_command = """ SELECT %s FROM %s WHERE solution_id IN (%s) """
627  # string with the solution ids to pass to the sql_command
628  str_ids = ",".join(map(str, solutions_ids))
629  log.debug("Solutions considered %s", solutions_ids)
630  s = sql_command % (",".join(distance_fields), table, str_ids)
631  data_distances = self.retrieve_data(s)
632  s = sql_command % (",".join(angle_fields), table, str_ids)
633  data_angles = self.retrieve_data(s)
634  D = np.array(data_distances)
635  placement_distances_mean = D.mean(axis=0)
636  placement_distances_stddev = D.std(axis=0)
637  A = np.array(data_angles)
638  placement_angles_mean = A.mean(axis=0)
639  placement_angles_stddev = A.std(axis=0)
640  return [placement_distances_mean, placement_distances_stddev,
641  placement_angles_mean, placement_angles_stddev]
642 
643  def get_placement_statistics(self, solutions_ids):
644  """
645  Calculate the placement score and its standard deviation for
646  the complexes in a set of solutions. The values returned are
647  averages, as the placement score for a complex is the average
648  of the placement scores of the components. This function is used
649  to obtain global placement for a cluster of solutions.
650  @param solutions_ids The ids of the solutions used to compute
651  the statistics
652  @return The output are 4 values:
653  plcd_mean - Average of the placement distance for the entire
654  complex over all the solutions.
655  plcd_std - Standard deviation of the placement distance for
656  the entire complex over all the solutions.
657  plca_mean - Average of the placement angle for the entire
658  complex over all the solutions.
659  plca_std - Standard deviation of the placement angle for
660  the entire complex over all the solutions.
661  """
662  [placement_distances_mean, placement_distances_stddev,
663  placement_angles_mean, placement_angles_stddev] = \
664  self.get_individual_placement_statistics(solutions_ids)
665  plcd_mean = placement_distances_mean.mean(axis=0)
666  plcd_std = placement_distances_stddev.mean(axis=0)
667  plca_mean = placement_angles_mean.mean(axis=0)
668  plca_std = placement_angles_stddev.mean(axis=0)
669  return [plcd_mean, plcd_std, plca_mean, plca_std]
def get_left_join_command
Format a left join SQL command that recovers all fields from the tables given.
def get_table_column_names
Get the names of the columns for a given table.
Definition: database.py:231
def __new__
Build from a tuple and the index used to compare.
Definition: solutions_io.py:37
Class to manage a SQL database built with sqlite3.
Definition: database.py:16
def gather_solution_results
Reads a set of database files and puts them in a single file Makes sure to reorder all column names i...
def add_clusters_table
Add a table to store information about the clusters of structures.
def get_placement_fields
Return the names of the placement score fields in the database.
def store_data
Inserts information in a given table of the database.
Definition: database.py:95
def add_ccc_table
Add a table to the database for store the values of the cross correlation coefficient between a model...
def format_placement_record
both distances and angles are expected to be a list of floats
The heapq algorithm is a min-heap.
Definition: solutions_io.py:27
def create_table
Creates a table.
Definition: database.py:48
def get_solutions
Get solutions from the database.
def retrieve_data
Retrieves data from the database using the sql_command returns the records as a list of tuples...
Definition: database.py:117
def add_record
Add a record to the database.
def gather_best_solution_results
Reads a set of database files and merge them into a single file.
Definition: solutions_io.py:62
Utility functions to handle IO.
Definition: io.py:1
Utility functions to manage SQL databases with sqlite3.
Definition: database.py:1
def add_placement_scores_table
Creates a table to store the values of the placement scores for the models.
def get_best_solution
Recover the reference frame of the n-th best solution from a database.
def drop_table
Delete a table if it exists.
Definition: database.py:64
def get_sorting_indices
Return indices that sort the list ls.
def get_individual_placement_statistics
Recovers from the database the placement scores for a set of solutions, and returns the mean and stan...
def get_native_solution
Recover data for the native solution.
def add_native_record
Add a record for the native structure to the database see add_record() for the meaning of the paramet...
Class for managing the results of the experiments.
def add_cluster_record
Add a record to the cluster database.
def get_placement_statistics
Calculate the placement score and its standard deviation for the complexes in a set of solutions...
def get_nth_largest_cluster
Recover the information about the n-th largest cluster.
def store_cluster_data
Store the data for the clusters.
def add_results_table
Build the table of results.
def get_fields_string
Get a list of fields and return a string with them.
def get_ccc
Recover the cross-correlation coefficient for a solution.
def format_ccc_record
Format for the record to store in the ccc table.
def add_columns
Add columns to the database.
Definition: database.py:257
def get_native_rank
Get the position of the native configuration.
def get_solutions_from_list
Recover solutions for a specific list of results.
def get_solutions_results_table
Recovers solutions.
def update_data
updates the register in the table identified by the condition values for the condition fields ...
Definition: database.py:125
def check_if_is_connected
Checks if the class is connected to the database filename.
Definition: database.py:42