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

Source Code for Module qubx.model_charts

  1  """Model visualizations and matrices. 
  2   
  3  Copyright 2008-2011 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  from __future__ import with_statement 
 23   
 24  import os 
 25  import sys 
 26  import traceback 
 27  import numpy 
 28  import scipy 
 29  import gobject 
 30  import cairo 
 31  import gtk 
 32  import qubx.GTK 
 33  import qubx.pyenv 
 34  import qubx.fit_space 
 35  import qubx.faces 
 36  import qubx.model 
 37  import qubx.settings 
 38  import qubx.task 
 39  import qubx.dataGTK 
 40   
 41  from gtk import gdk, keysyms 
 42  from itertools import izip, count, chain 
 43  from qubx.util_types import * 
 44  from qubx.accept import acceptFloatGreaterThan 
 45   
 46  expm = scipy.linalg.matfuncs.expm 
 47   
48 -class ModelChartsFace(qubx.faces.ToolsFace):
49 """Container for model charts; on model event, calls face.update(model) on active face.""" 50 __explore_featured = ['model', 'format_stimulus', 'build_Q', 'build_A', 'build_Peq', 'build_mfp', 'build_Keq', 51 'build_delG', 'build_Qflux']
52 - def __init__(self, QubX, name='Model'):
53 qubx.faces.ToolsFace.__init__(self, name, pos=qubx.faces.POS_DROPDOWN) 54 self.__ref = Reffer() 55 # sampling and tdead on self.mnu_line? 56 QubX.Models.OnSwitch += self.__ref(self.__onSwitchModel) 57 self.OnSwitchFace += self.__ref(self.__onSwitchFace) 58 QubX.DataSource.OnChangeSamples += self.__ref(self.__onChangeStimulus) 59 self.__model = None 60 self.serial = 0 61 #self.append_face(ModelTextFace('Stimulus', self.format_stimulus)) 62 self.append_face(MatrixFace('Q', self.build_Q)) 63 self.append_face(MatrixFace('A', self.build_A)) 64 self.append_face(MatrixFace('Peq', self.build_Peq)) 65 self.append_face(MatrixFace('Equilibrium constants', self.build_Keq)) 66 self.append_face(MatrixFace('Delta free energy (log10)', self.build_delG)) 67 self.append_face(MatrixFace('Mean first passage', self.build_mfp)) 68 self.append_face(MatrixFace('Qflux', self.build_Qflux))
69 - def __onSwitchModel(self, models, model):
70 self.model = model
71 - def set_model(self, model):
72 if model == self.__model: return 73 if self.__model: 74 for event in (self.__model.classes.OnSet, 75 self.__model.states.OnInsert, 76 self.__model.states.OnRemoved, 77 self.__model.states.OnSet, 78 self.__model.rates.OnInsert, 79 self.__model.rates.OnRemoved, 80 self.__model.rates.OnSet, 81 self.__model.OnSetChannelCount, 82 self.__model.OnSetIeqFv, 83 self.__model.OnSetVRev): 84 event -= self.__ref(self.__onSetModel) 85 self.__model = model 86 if self.__model: 87 for event in (self.__model.classes.OnSet, 88 self.__model.states.OnInsert, 89 self.__model.states.OnRemoved, 90 self.__model.states.OnSet, 91 self.__model.rates.OnInsert, 92 self.__model.rates.OnRemoved, 93 self.__model.rates.OnSet, 94 self.__model.OnSetChannelCount, 95 self.__model.OnSetIeqFv, 96 self.__model.OnSetVRev): 97 event += self.__ref(self.__onSetModel)
98 model = property(lambda self: self.__model, lambda self, x: self.set_model(x))
99 - def __onChangeStimulus(self):
100 self.__onSetModel()
101 - def __onSwitchFace(self, selfy, face_name):
102 self.__onSetModel()
103 - def onShow(self, showing):
104 self.__onSetModel()
105 - def __onSetModel(self, *args):
106 if self.model and self.showing and self._face: 107 self.serial += 1 108 gobject.idle_add(self.__update, self.serial)
109 - def __update(self, serial):
110 if serial < self.serial: return 111 self._face.update(self.model)
112 - def format_stimulus(self, model):
113 QubX = qubx.pyenv.env.globals['QubX'] 114 return str(QubX.Models.view.get_stimulus( QubX.Data.view ))
115 - def build_Q(self, model):
116 QubX = qubx.pyenv.env.globals['QubX'] 117 return qubx.model.ModelToQ(model, QubX.Models.view.get_stimulus( QubX.Data.view ))
118 - def build_A(self, model):
119 QubX = qubx.pyenv.env.globals['QubX'] 120 return expm(QubX.Data.file.sampling * self.build_Q(model))
121 - def build_Peq(self, model):
122 return qubx.model.QtoPe(self.build_Q(model))
123 - def build_mfp(self, model):
124 QubX = qubx.pyenv.env.globals['QubX'] 125 dt = QubX.Data.file.sampling 126 Q = self.build_Q(model) 127 P = qubx.model.QtoPe(Q) 128 A = expm(dt * Q) 129 return qubx.model.MeanFirstPassage(A, P, dt)
130 - def build_Keq(self, model):
131 Q = self.build_Q(model) 132 Keq = numpy.identity(Q.shape[0]) 133 for i in xrange(Q.shape[0]): 134 for j in xrange(i+1,Q.shape[0]): 135 if Q[i,j] and Q[j,i]: 136 Keq[i,j] = Q[i,j] / Q[j,i] 137 Keq[j,i] = 1.0 / Keq[i,j] 138 return Keq
139 - def build_delG(self, model):
140 Keq = self.build_Keq(model) 141 delG = numpy.zeros(shape=Keq.shape) 142 for i in xrange(Keq.shape[0]): 143 for j in xrange(Keq.shape[1]): 144 if Keq[i,j]: 145 delG[i,j] = numpy.log10(Keq[i,j]) 146 return delG
147 - def build_Qflux(self, model):
148 Q = self.build_Q(model) 149 Peq = self.build_Peq(model) 150 W = numpy.matrix(numpy.diag(Peq)) 151 Qflux = W * Q 152 return Qflux
153 154 155
156 -class ModelTextFace(qubx.faces.TextFace):
157 """Displays one model factoid as plain text.""" 158 __explore_featured = ['format_model', 'update']
159 - def __init__(self, name, format_model):
160 """ 161 @param name: label for this face 162 @param format_model: f(L{qubx.model.QubModel}) -> str 163 """ 164 qubx.faces.TextFace.__init__(self, name) 165 qubx.GTK.SetFixedWidth(self.textView) 166 self.format_model = format_model
167 - def update(self, model):
168 """Passes the latest model to the format_model function and displays the result.""" 169 self.set_text( self.format_model(model) )
170
171 -class MatrixFace(ModelTextFace):
172 """Displays one matrix or vector, with a copy button for higher-precision tab-separated text. 173 174 @ivar matrix: numpy.matrix that is displayed 175 """ 176 __explore_featured = ['build_matrix', 'btnCopy', 'matrix', 'update']
177 - def __init__(self, name, build_matrix):
178 """ 179 @param name: label for this face 180 @param build_matrix: f(L{qubx.model.QubModel}) -> numpy.matrix 181 """ 182 ModelTextFace.__init__(self, name, self.__format) 183 self.build_matrix = build_matrix 184 self.__matrix = None 185 line = gtk.HBox() 186 line.show() 187 self.pack_start(line, False, True) 188 self.btnCopy = gtk.Button('Copy') 189 self.btnCopy.connect('clicked', self.__onClickCopy) 190 self.btnCopy.show() 191 line.pack_end(self.btnCopy, False, True)
192 - def set_matrix(self, matrix):
193 self.__matrix = matrix 194 ModelTextFace.update(self, matrix)
195 matrix = property(lambda self: self.__matrix, lambda self, x: self.set_matrix(x))
196 - def __format(self, matrix):
197 fmt = "%12.4g" 198 if len(matrix.shape) == 1: 199 return "\n".join((fmt % x) for x in matrix) + "\n" 200 elif matrix.shape[0] == 1: 201 return " ".join(('%s' % x) for x in numpy.array(matrix[0,:])) + "\n" 202 else: 203 return "\n".join(" ".join(fmt % x for x in row) for row in numpy.array(matrix)) + "\n"
204 - def update(self, model):
205 """Passes the latest model to the build_matrix function and displays the result.""" 206 self.matrix = self.build_matrix(model)
207 - def __onClickCopy(self, btn):
208 clipboard = gtk.clipboard_get(gdk.SELECTION_CLIPBOARD) 209 clipboard.set_text("\n".join("\t".join("%.9g" % x for x in row) for row in numpy.array(self.matrix))+"\n")
210