max_mac_ll.py.html | mathcode2html |
Source file: max_mac_ll.py | |
Converted: Sun Aug 7 2016 at 13:47:28 | |
This documentation file will not reflect any later changes in the source file. |
$$\phantom{******** If you see this on the webpage then the
browser could not locate *********}$$
$$\phantom{******** jsMath/easy/load.js or the variable root
is set wrong in this file *********}$$
$$\newcommand{\vector}[1]{\left[\begin{array}{c} #1 \end{array}\right]}$$
$$\newenvironment{matrix}{\left[\begin{array}{cccccccccc}} {\end{array}\right]}$$
$$\newcommand{\A}{{\cal A}}$$
$$\newcommand{\W}{{\cal W}}$$
#/* Copyright 2008-2013 Research Foundation State University of New York */ # #/* This file is part of QUB Express. */ # #/* QUB Express is free software; you can redistribute it and/or modify */ #/* it under the terms of the GNU General Public License as published by */ #/* the Free Software Foundation, either version 3 of the License, or */ #/* (at your option) any later version. */ # #/* QUB Express is distributed in the hope that it will be useful, */ #/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ #/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ #/* GNU General Public License for more details. */ # #/* You should have received a copy of the GNU General Public License, */ #/* named LICENSE.txt, in the QUB Express program directory. If not, see */ #/* <http://www.gnu.org/licenses/>. */ import numpy import scipy import traceback from qubx.fast.model import * try: importer = ctypes.windll base, ext = '','.dll' except: importer = ctypes.cdll base, ext = 'lib','.so' try: if ext == '.dll': importer.LoadLibrary(base+'OpenCL'+ext) # windows complains if dll's sub-dependencies are missing maxmll = importer.LoadLibrary(base+'maxmll_opencl'+ext) except: try: maxmll = importer.LoadLibrary(base+'maxmll'+ext) except OSError: maxmll = importer.LoadLibrary('@executable_path/../Frameworks/libmaxmll_opencl.so') # , mode=ctypes.RTLD_GLOBAL) to be visible from subsequently-loaded libs class SampleStruct(Structure): _fields_ = [('time', c_float), ('cur', c_float), ('var', c_float)] PSample = POINTER(SampleStruct) class SampleOutStruct(Structure): _fields_ = [('fit', c_float), ('fit_var', c_float), ('ll', c_int)] PSampleOut = POINTER(SampleOutStruct) maxmll.qubx_mac_data_create.argtypes = (c_int, c_int) maxmll.qubx_mac_data_create.restype = c_void_p maxmll.qubx_mac_data_reset.argtypes = (c_void_p, c_int, c_int) maxmll.qubx_mac_data_reset.restype = None maxmll.qubx_mac_data_free.argtypes = (c_void_p,) maxmll.qubx_mac_data_free.restype = None maxmll.qubx_mac_data_append_segment.argtypes = (c_void_p,) maxmll.qubx_mac_data_append_segment.restype = c_int maxmll.qubx_mac_data_append_chunk.argtypes = (c_void_p, c_int, c_double, c_int, c_float_p, c_float_p, c_float_p, c_int_p, c_int_pp, c_float_pp, c_double_pp) maxmll.qubx_mac_data_append_chunk.restype = None maxmll.qubx_mac_data_get_stimclasses.argtypes = (c_void_p, c_int_p) maxmll.qubx_mac_data_get_stimclasses.restype = c_double_p maxmll.qubx_mac_data_get_stimclass_frac.argtypes = (c_void_p,) maxmll.qubx_mac_data_get_stimclass_frac.restype = c_double_p maxmll.qubx_mac_data_get_buffer.argtypes = (c_void_p,) maxmll.qubx_mac_data_get_buffer.restype = PSampleOut class Data(object): def __init__(self, Nstimsig, data_cap=2**16, file_index=0): self.obj = maxmll.qubx_mac_data_create(Nstimsig, data_cap) self.Nstimsig = Nstimsig self.file_index = file_index self.Nsig = Nstimsig + 1 self.Ndata = 0 def __del__(self): maxmll.qubx_mac_data_free(self.obj) def reset(self, Nstimsig, data_cap=2**16): maxmll.qubx_mac_data_reset(self.obj, Nstimsig, data_cap) self.Nstimsig = Nstimsig self.Ndata = 0 def append_segment(self): maxmll.qubx_mac_data_append_segment(self.obj) def append_chunk(self, seg_ix, dur_sec, Nd, T, I, V, dwellCounts, classeses, durationses, ampses): dcs = numpy.array(dwellCounts, dtype='int32') # assuming the elements of classeses and durationses are numpy.arrays of int, float, double respectively ccs = (c_int_p*self.Nstimsig)(*[cdata(classes, c_int_p) for classes in classeses]) dds = (c_float_p*self.Nstimsig)(*[cdata(durations, c_float_p) for durations in durationses]) aas = (c_double_p*self.Nstimsig)(*[cdata(amps, c_double_p) for amps in ampses]) maxmll.qubx_mac_data_append_chunk(self.obj, seg_ix, dur_sec, Nd, cdata(T, c_float_p), cdata(I, c_float_p), cdata(V, c_float_p), cdata(dcs, c_int_p), ccs, dds, aas) self.Ndata += Nd def get_stimclasses(self): Nstim = c_int() self.stimclasses = maxmll.qubx_mac_data_get_stimclasses(self.obj, byref(Nstim)) self.Nstim = Nstim.value return self.stimclasses def get_stimclass_frac(self): self.sc_frac = maxmll.qubx_mac_data_get_stimclass_frac(self.obj) return self.sc_frac def get_buffer(self): return numpy.frombuffer(pybuf(maxmll.qubx_mac_data_get_buffer(self.obj), int(3*self.Ndata*sizeof(c_float))), dtype='float32', count=3*self.Ndata).reshape((self.Ndata, 3)) class ParamStruct(Structure): _fields_ = [('storage', c_void_p), ('data', c_void_p), ('useVar', c_int), ('optNchannel', c_int), ('accel', c_int), ('Npar', c_int), ('NfPar', c_int), ('pars', c_double_p), ('fPars', c_double_p), ('gpu_fail', c_int), ('ll', c_double), ('float_Nchannel', c_double)] PParam = POINTER(ParamStruct) maxmll.qubx_mac_param_create.argtypes = (c_int,) maxmll.qubx_mac_param_create.restype = PParam maxmll.qubx_mac_param_free.argtypes = (PParam,) maxmll.qubx_mac_param_free.restype = None maxmll.qubx_mac_param_add_model.argtypes = (PParam, PModel, PStimAmps, PStimRates) maxmll.qubx_mac_param_add_model.restype = None maxmll.qubx_mac_setup_constraints.argtypes = (PParam,) maxmll.qubx_mac_setup_constraints.restype = c_int maxmll.qubx_mac_do_fPars_to_model.argtypes = (PParam,) maxmll.qubx_mac_do_fPars_to_model.restype = None maxmll.qubx_mac_calc_std.argtypes = (PParam, c_double_p) maxmll.qubx_mac_calc_std.restype = None class Param(object): def __init__(self, Nmodel): self.obj = maxmll.qubx_mac_param_create(Nmodel) self.pars_ = self.fPars_ = [] self.__data = None self.models = [] self.ampms = [] self.ratesms = [] def set_data(self, x): self.obj[0].data = x.obj self.__data = x def add_model(self, fastmodel, ampm, ratesm): maxmll.qubx_mac_param_add_model(self.obj, fastmodel.obj, ampm.obj, ratesm.obj) self.models.append(fastmodel) self.ampms.append(ampm) self.ratesms.append(ratesm) data = property(lambda self: self.__data, lambda self, x: self.set_data(x)) def set_useVar(self, x): self.obj[0].useVar = x useVar = property(lambda self: self.obj[0].useVar, lambda self, x: self.set_useVar(x)) def set_optNchannel(self, x): self.obj[0].optNchannel = x optNchannel = property(lambda self: self.obj[0].optNchannel, lambda self, x: self.set_optNchannel(x)) def set_accel(self, x): self.obj[0].accel = x accel = property(lambda self: self.obj[0].accel, lambda self, x: self.set_accel(x)) def set_float_Nchannel(self, x): self.obj[0].float_Nchannel = x float_Nchannel = property(lambda self: self.obj[0].float_Nchannel, lambda self, x: self.set_float_Nchannel(x)) Npar = property(lambda self: self.obj[0].Npar) NfPar = property(lambda self: self.obj[0].NfPar) pars = property(lambda self: self.pars_) fPars = property(lambda self: self.fPars_) ll = property(lambda self: self.obj[0].ll) gpu_fail = property(lambda self: self.obj[0].gpu_fail) def __del__(self): maxmll.qubx_mac_param_free(self.obj) def setup_constraints(self): result = maxmll.qubx_mac_setup_constraints(self.obj) self.pars_ = numpy.frombuffer(pybuf(self.obj[0].pars, self.Npar*sizeof(c_double)), dtype='float64', count=self.Npar) self.fPars_ = numpy.frombuffer(pybuf(self.obj[0].fPars, max(1, self.NfPar)*sizeof(c_double)), dtype='float64', count=max(1, self.NfPar)) return result def do_fPars_to_model(self): maxmll.qubx_mac_do_fPars_to_model(self.obj) def calc_std(self, InvHessian): hess = numpy.array(InvHessian, dtype='float64', copy=True) maxmll.qubx_mac_calc_std(self.obj, cdata(hess, c_double_p)) maxmll.qubx_mac_ll.argtypes = (PParam,) maxmll.qubx_mac_ll.restype = c_int def mac_ll(param): if param.data.Ndata == 0: return 0.0 ll = c_double() result = maxmll.qubx_mac_ll(param.obj) if (0 != result) and (-8 != result): raise Exception('Mac error code: %d' % result) return param.ll def setup_test(): def pr(x): print x array = numpy.array data = Data(1) # TODO: test 0 stim signals data.append_segment() data.append_chunk(0, .0023, 0, None, None, None, [1], [array([1])], [array([2.3], dtype='float32')], [array([-40.0, 10.0])]) data.append_chunk(0, .001, 1, array([.003], dtype='float32'), array([50.0], dtype='float32'), array([0.0], dtype='float32'), [1], [array([0])], [array([1.0], dtype='float32')], [array([-40.0, 10.0])]) model = Model(2, 2, [0, 1], pr) model.usePeq = 1 model.useVar = 1 model.IeqFv = 1 model.amp0 = 0.0 model.var0 = 0.01 model.Nchannel = 100 model.iVoltage = 1 model.Gleak = 0.0 model.Vrev = -80.0 model.amp[1] = 10.0 model.var[1] = 1.0 model.K0[0,1] = 1000.0 model.K0[1,0] = 1000.0 model.K1[0,1] = 0.1 model.V[0,1] = 1 model.setup_stim(data) model.fix_channelcount() model.setup_constraints() return model, data def setup_data(data_path, delta): file = qubx.data_types.Open(data_path) for f,l,n in file.segmentation.segments: pass ### data = Data(Nstimsig) # TODO: test 0 stim signals data.append_segment() data.append_chunk(0, .0023, 0, None, None, None, [1], [array([1])], [array([2.3], dtype='float32')], [array([-40.0, 10.0])]) data.append_chunk(0, .001, 1, array([.003], dtype='float32'), array([50.0], dtype='float32'), array([0.0], dtype='float32'), [1], [array([0])], [array([1.0], dtype='float32')], [array([-40.0, 10.0])]) def setup_model(model_path, data): def pr(x): print x array = numpy.array model, model_file = setup_model(model_path) file = qubx.model.QubModel() file.from_tree(qubx.tree.Open(model_path, True)) clazz = ModelToClazz(file) Nclass = int(max(clazz) + 1) model = max_mac_ll.Model(model.states.size, Nclass, clazz, pr) model.usePeq = Peq if notPeq: model.P0[:] = ModelToP0(file) model.useVar = True ## model.IeqFv = file.IeqFv model.Nchannel = file.channelCount model.iVoltage = data.iVoltage model.Gleak =Gleak model.Vleak =Vleak model.Vrev = file.vRev if model.IeqFv: for s in xrange(Nclass): model.amp[s] = file.classes.get(s, 'Cond') model.var[s] = file.classes.get(s, 'CondStd')**2 model.amp0 = file.classes.get(0, 'Amp') model.var0 = file.classes.get(0, 'Std')**2 else: for s in xrange(Nclass): model.amp[s] = file.classes.get(s, 'Amp') model.var[s] = file.classes.get(s, 'Std')**2 K0, K1, L, V = ModelToRateMatrices(file, data.signal_names) model.K0[:] = K0[:] model.K1[:] = K1[:] model.L[:] = L[:] model.V[:] = V[:] model.setup_stim(data) A, B = file.constraints_kin.get_matrices(K0, K1, L, V) model.Ain[:A.shape[0],:A.shape[1]] = A model.Bin[:B.shape[0]] = B.flatten() model.Ncns = B.shape[0] model.setup_constraints() return model, file def setup_files(data_path, model_path, delta): def pr(x): print x array = numpy.array data = setup_data(data_path, delta) model, model_file = setup_model(model_path, data) return model, data if __name__ == '__main__': try: import datetime import optparse import sys import qubx.fast import qubx.model import qubx.model_constraints import qubx.data_types usage = "usage: %prog [options] file(s)" parser = optparse.OptionParser(usage) parser.add_option("-a", "--accel-level", dest="accel", action="store", default=2, help="0: single-thread; 1: openmp; 2: opencl") parser.add_option("-r", "--resample-delta", dest="delta", action="store", default=0.0, help="if nonzero, resample-by delta") parser.add_option("-d", "--data", dest="data_path", action="store", default="", help="/path/to/data.qdf") parser.add_option("-m", "--model", dest="model_path", action="store", default="", help="/path/to/model.qmf") options, args = parser.parse_args() model, data = setup_files(options.data_path, options.model_path, options.delta) mac_ll(model, data, options.accel) # get it warmed up before = datetime.datetime.now() print mac_ll(model, data, options.accel), delta = datetime.datetime.now() - before print delta.seconds, (delta.microseconds / 1000), (delta.microseconds % 1000) except: traceback.print_exc() model, data = setup_test() print 'K0',model.K0 print 'K1',model.K1 print 'Nchannel',model.Nchannel print 'xamp',model.xamp print 'xvar',model.xvar print 'fPars',model.fPars print 'a' print mac_ll(model, data) print 'b' del data, model print 'c'