Package qubx :: Module trialset
[hide private]
[frames] | no frames]

Source Code for Module qubx.trialset

  1  """A trialset is a L{qubx.table.SimpleTable} with one stored model per row. 
  2   
  3  Copyright 2012 Research Foundation State University of New York  
  4  This file is part of QUB Express.                                           
  5   
  6  QUB Express is free software; you can redistribute it and/or modify           
  7  it under the terms of the GNU General Public License as published by  
  8  the Free Software Foundation, either version 3 of the License, or     
  9  (at your option) any later version.                                   
 10   
 11  QUB Express is distributed in the hope that it will be useful,                
 12  but WITHOUT ANY WARRANTY; without even the implied warranty of        
 13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         
 14  GNU General Public License for more details.                          
 15   
 16  You should have received a copy of the GNU General Public License,    
 17  named LICENSE.txt, in the QUB Express program directory.  If not, see         
 18  <http://www.gnu.org/licenses/>.                                       
 19   
 20   
 21  """ 
 22   
 23  import time 
 24  import traceback 
 25   
 26  import qubx.date 
 27  import qubx.global_namespace 
 28  import qubx.table 
 29  import qubx.tree 
 30  from qubx.accept import * 
 31  from qubx.tree import node_data_or_def 
 32  from qubx.util_types import WeakEvent, Reffer 
 33   
34 -class TrialSet(qubx.table.SimpleTable):
35 """A table with one model per row (in qubx.tree QMF format); each row represents one result such as an optimizer run. 36 Fields include LL, AIC, BIC, Date (as a string), Model (name), and Data (name), and additional ones will be added as needed when adding rows. 37 38 @ivar trialset_name: onscreen label, e.g. name of the algorithm that created it 39 @ivar models: list of L{qubx.tree.Node}s, one QMF model per row 40 """
41 - def __init__(self, trialset_name, in_qsf=False):
42 qubx.table.SimpleTable.__init__(self, 'Trials', auto_add_fields=True, global_name='QubX.Trials.trialset', sortable=True) 43 self.trialset_name = trialset_name 44 self.__in_qsf = in_qsf 45 self.models = [] 46 self.__ref = Reffer() 47 self.add_field('Label', '', str, str, '') 48 self.add_field('LL', 0.0, acceptNothing, '%.6g', '') 49 self.add_field('AIC', 0.0, acceptNothing, '%.6g', '') 50 self.add_field('BIC', 0.0, acceptNothing, '%.6g', '') 51 self.add_field('Date', 0, acceptNothing, qubx.date.formatUnixDate, '') 52 self.add_field('Model', '', acceptNothing, str, '') 53 self.add_field('Data', '', acceptNothing, str, '') 54 self.OnInsert += self.__ref(self.__onInsert) 55 self.OnRemoved += self.__ref(self.__onRemoved) 56 self.OnSetInQSF = WeakEvent()
57 - def dispose(self):
58 qubx.table.SimpleTable.dispose(self) 59 self.__ref.clear()
60 - def set_in_qsf(self, x):
61 if self.__in_qsf == x: return 62 self.__in_qsf = x 63 self.OnSetInQSF(self, x)
64 in_qsf = property(lambda self: self.__in_qsf, lambda self, x: self.set_in_qsf(x), doc="False if not saved in any session (qsf) file.")
65 - def append_trial(self, model_tree, row_dict):
66 """Appends a row. 67 68 @param model_tree: a model in qubx.tree QMF format (e.g. QubX.Models.file.as_tree()) 69 @param row_dict: {column_name : value} -- if column_name doesn't exist, it will be created. 70 """ 71 self.append(row_dict) 72 self.models[-1] = model_tree
73 - def __onInsert(self, i, undoing):
74 self.models.insert(i, qubx.tree.NullNode())
75 - def __onRemoved(self, i, undoing):
76 del self.models[i]
77 78
79 -class TrialSets(object):
80 """Collection of L{TrialSet} by name."""
81 - def __init__(self):
82 self.trialset_names = [] 83 self.trialsets = [] 84 self.OnInsert = WeakEvent() 85 self.OnRemoving = WeakEvent()
86 - def get_trialset(self, name, in_qsf=False):
87 """Request a named L{TrialSet}; it will be created if necessary. 88 89 @param name: 90 @param in_qsf: False if it does not belong to any session (qsf) file 91 """ 92 try: 93 return self.trialsets[self.trialset_names.index(name)] 94 except ValueError: 95 ts = TrialSet(name, in_qsf) 96 self.trialset_names.append(name) 97 self.trialsets.append(ts) 98 self.OnInsert(len(self.trialsets)-1, ts) 99 return ts
100 - def remove_trialset(self, name):
101 """Removes a named TrialSet; ok if there is none by that name.""" 102 try: 103 ix = self.trialset_names.index(name) 104 self.OnRemoving(ix, self.trialsets[ix]) 105 del self.trialset_names[ix] 106 self.trialsets[ix].dispose() 107 del self.trialsets[ix] 108 except ValueError: 109 pass
110 111
112 -def make_trial_row(model_path, data_path, LL, nParam, nData=0, **kw):
113 """Builds a dict representing one row in a L{TrialSet}; fills in AIC and BIC from LL and nParam; fills in Date from time.localtime(). 114 Copies any keyword args into the output. 115 116 @param model_path: copied into 'Model' field 117 @param data_path: copied into 'Data' field 118 @param LL: log likelihood 119 @param nParam: number of free parameters 120 @param nData: number of data points 121 """ 122 row = kw.copy() 123 row['Date'] = time.mktime(time.localtime()) 124 row['Model'] = model_path 125 row['Data'] = data_path 126 row['LL'] = LL 127 if nParam and LL: 128 row['nParam'] = nParam 129 row['AIC'] = 2*nParam - 2*LL 130 if nData: 131 row['BIC'] = nParam*log(nData) - 2*LL 132 return row
133
134 -def add_trial_rates(row, model_tree, prefix=""):
135 """Adds entries to a dict (representing one row in a L{TrialSet}) for all nonzero k0,k1,k2 rate constants. 136 137 @param model_tree: model in qubx.tree QMF format, e.g. QubX.Models.file.as_tree() 138 @param prefix: string to prepend to each rate constant, e.g. 'Initial ', or 'Final ' 139 """ 140 for rate in qubx.tree.children(model_tree.find('Rates'), 'Rate'): 141 states, k0, k1, k2, p, q, pressure, pnames, qnames, pressureNames, fmts = [rate.find(nm) for nm in ('States', 'k0', 'k1', 'k2', 'P', 'Q', 'Pressure', 'PNames', 'QNames', 'PressureNames', 'RateFormats')] 142 pname = pnames.find('PName') 143 qname = qnames.find('QName') 144 pressname = pressureNames.find("PressureName") 145 fmt = fmts.find('RateFormat') 146 for i in (0,1): 147 j = (i+1)%2 148 lig = node_data_or_def(p, 0, i) and str(pname.data) or "" 149 volt = node_data_or_def(q, 0, i) and str(qname.data) or "" 150 press = node_data_or_def(pressure, 0, i) and str(pressname.data) or "" 151 From = node_data_or_def(states, i, i) 152 To = node_data_or_def(states, j, j) 153 row['%sk0 %i_%i' % (prefix, From, To)] = float(node_data_or_def(k0, 10.0, i)) 154 if volt: 155 row['%sk1 %i_%i' % (prefix, From, To)] = float(node_data_or_def(k1, 0.0, i)) 156 if press: 157 row['%sk2 %i_%i' % (prefix, From, To)] = float(node_data_or_def(k2, 0.0, i)) 158 pname = pname.nextSameName() 159 qname = qname.nextSameName() 160 pressname = pressname.nextSameName() 161 fmt = fmt.nextSameName()
162
163 -def add_trial_amps(row, model_tree, prefix=""):
164 """Adds entries to a dict (representing one row in a L{TrialSet}) for relevant quantities from the Classes table. 165 166 @param model_tree: model in qubx.tree QMF format, e.g. QubX.Models.file.as_tree() 167 @param prefix: string to prepend to each entry, e.g. 'Initial ', or 'Final ' 168 """ 169 classes_present = set(state['Class'].data[0] for state in qubx.tree.children(model_tree.find('States'), 'State')) 170 if node_data_or_def(model_tree.find('Properties').find('IeqFv'), 0): 171 amp, std = 'Cond', 'CondStd' 172 amps, stds = model_tree['Conds'].data, model_tree['CondStds'].data 173 row['%sAmp 0' % prefix] = model_tree['Amps'].data[0] 174 row['%sStd 0' % prefix] = model_tree['Stds'].data[0] 175 else: 176 amp, std = 'Amp', 'Std' 177 amps, stds = model_tree['Amps'].data, model_tree['Stds'].data 178 for c in sorted(list(classes_present)): 179 row['%s%s %i' % (prefix, amp, c)] = amps[c] 180 row['%s%s %i' % (prefix, std, c)] = stds[c]
181
182 -def add_trial_nChannel(row, model_tree, prefix=""):
183 """Adds 'ChannelCount' from a model to a dict (representing one row in a L{TrialSet}).""" 184 row['%snChannel' % prefix] = model_tree['ChannelCount'].data[0]
185