Пример #1
0
 def datatypes(self, genotype):
     """Dict of Numpy data types for each Table in the HDF file."""
     li = self.li # save some typing
     ftype = dict(genotype=self.genotype.dtype, parameter=li.dtype.p, 
         convergence=[("period", np.int16), ("intervals", np.int16)], 
         steady=self.li.dtype.y, quiescent=self.li.dtype.y, 
         # Hacked by stepping through self.task(0), see comment there
         clamppheno=[(k, float) for k in 
             "i_Na_tau_m40 i_Na_tau_m20 i_Na_tau_0 i_Na_tau_20 i_Na_tau_40 "
             "i_CaL_tau_m40 i_CaL_tau_m20 i_CaL_tau_0 i_CaL_tau_20 "
             "i_CaL_tau_40 i_CaL_vg_max_m90 i_CaL_vg_thalf_m90 "
             "i_CaL_vg_max_m80 i_CaL_vg_thalf_m80 i_CaL_vg_max_m70 "
             "i_CaL_vg_thalf_m70".split()],
         timing=[(k, float) for k in 
             "waiting started finished error seconds attempts".split()])
     ftype["raw"] = [(k, float, self.raw_nap * self.raw_nthin) 
         for k in ("t",) + li.dtype.y.names + li.dtype.a.names]
     
     # Ion-current phenotypes: a few phenotypes for many variables.
     # Make one array per phenotype, with one column per variable.
     
     # Get field names for current phenotypes
     with li.autorestore():
         t, y, stats = li.ap_plain()
     curph = current_phenotypes_array(t, y.V)
     for k in curph.dtype.names:
         ftype[k] = [(i, float) for i in li.dtype.y.names + li.dtype.a.names]
     ap_stats = ap_cvode.ap_stats_array(stats)
     # Action potential and calcium transient statistics, including time 
     # to recovery.
     ftype["ap_stats"] = [(k, typ, self.raw_nap) for k, typ in eval(str(ap_stats.dtype))]
     return ftype
Пример #2
0
    def task(self, real_i):
        """
        Map genotype i to parameter to steady state.
        
        Input and output uses memmaps. To allow load balancing, the memmaps 
        have only a single element (one genotype, one parameter set, etc.).
        
        In case of alternans, a list of (t, y, stats, integrals) is stored as e.g.
        alternans/123.list.npy
        To retrieve the list, use "L = np.load(filename).item()"
        """
        m = Dotdict()
        for name in self.ftype:
            m[name] = open_memmap("%s.npy" % name, offset=real_i, shape=1)
        i = 0
        alog.debug("Workpiece: real_i=%s, i=%s", real_i, i)
        m.timing[i]["attempts"] += 1
        m.timing[i]["started"] = time()
        try:
            m.genotype[i] = gt = self.genotype[real_i]
            m.parameter[i] = par = self.gt2par(gt)
            
            li = self.li
            
            with li.autorestore(_p=par):
                
                # Compute quiescent state
                with li.autorestore(stim_amplitude=0):
                    t, y, flag = li.integrate(t=[0, 1e6])
                m.quiescent[i] = yq = y[-1:] # yq now has shape (1,)
                
                # Run voltage stepping protocols
                bp = li.bond_protocols()
                p3, p5, p7 = [listify(bp[j].protocol) for j in 3, 5, 7]
                p3[1][1] = -40, -20, 0, 20, 40
                p5[1][1] = -40, -20, 0, 20, 40
                p7[2][0] = 2, 127, 252, 377, 502
                with li.autorestore(_y=yq):
                    L3 = li.vecvclamp(p3) # P1-P2 voltage stepping for i_Na
                    L5 = li.vecvclamp(p5) # P1-P2 voltage stepping for i_CaL
                    L7 = li.vecvclamp(p7) # Variable-gap protocol for i_CaL
                
                d = OrderedDict() # to hold voltage-clamp phenotype characteristics
                
                # Time constant of inactivation: -1/slope of ln(current) vs t after P1 peak
                for curr, L in ("i_Na", L3), ("i_CaL", L5):
                    for v, tau in zip(*decayfits(L, 1, curr)):
                        sv = str(v).replace("-", "m") # avoid minus sign in field name
                        k = "%s_tau_%s" % (curr, sv)
                        d[k] = tau
                
                # Michaelis-Menten half-saturation and asymptote of peak current vs gap duration
                gaps, voltages = p7[2]
                proto, traj = [np.array(j, dtype=object) for j in zip(*L7)]
                # Vectorized voltage clamping returns a 1-d array.
                # Dimensions should be (gap length, interpulse voltage, pulse index, last)
                # where the last dimension has length 2 for proto (duration, voltage) 
                # and 4 for traj (t, y, dy, a).
                for j in proto, traj:
                    j.shape = [len(gaps), len(voltages)] + list(j.shape[1:])
                for j, v in enumerate(voltages):
                    imax, thalf = mmfits(zip(proto[:,j,:,:], traj[:,j,:,:]), k="i_CaL")
                    sv = str(v).replace("-", "m")
                    d["i_CaL_vg_max_" + sv] = imax
                    d["i_CaL_vg_thalf_" + sv] = thalf
                # print " ".join(dict2rec(d).dtype.names) # for self.datatypes()
                m.clamppheno[i] = dict2rec(d).view(np.recarray)
                
                # Steady state under regular pacing
                (period, intervals), steady = li.par2steady(y0=yq, reltol=self.reltol, max_nap=1000)

                # # oldintervals will be nonzero if an earlier run failed to converge
                # oldperiod, oldintervals = m.convergence[i]
                # y0 = m.steady[i] if (self.resumeconv and oldintervals) else None
                # 
                # # Run to convergence; steady is a list of (t, y, stats, integrals).
                # # The cycle is aligned so that it starts with the highest Cai peak.
                # (period, intervals), steady = self.par2steady(par, y0)
                # intervals += oldintervals
                
                m.convergence[i] = period, intervals
                if period and (len(steady) > 1):
                    with write_if_not_exists("alternans/%s.list.npy" % real_i, 
                        raise_if_exists=True) as f:
                        L = []
                        for t, y, stats, int_ in steady:
                            ix = thin(len(t), self.raw_nthin)
                            L.append((t[ix], y[ix], stats, int_))
                        np.save(f, L)
                t, y, stats, _ = steady[-1]
                m.steady[i] = y[0]
                
                # Phenotypes for steady-state dynamics
                aps = [(t, y, stats) for t, y, stats, int_ in steady[-self.raw_nap:]]
                m.raw[i], m.ap_stats[i] = self.thin_aps(aps, self.raw_nthin, par)
                # Ion-current phenotypes, also applied to other state variables.
                # One table/ndarray per phenotype, one column per variable.
                raw = m.raw[i]
                currstats = np.concatenate([current_phenotypes_array(raw["t"], raw[k]) 
                    for k in raw.dtype.names if k != "t"])
                for k in currstats.dtype.names:
                    m[k][i] = np.ascontiguousarray(currstats[k])
                m.timing[i]["finished"] = time()
                m.timing[i]["seconds"] = m.timing[i]["finished"] - m.timing[i]["started"]
        except Exception, exc:
            m.timing[i]["error"] = time()
            alog.exception("Error processing item %s", i)