Пример #1
0
def _sensitivity(exposure, workspace, protocol, statistic, par=None, seed=None):
    """
    Sensitivity analysis.
    
    >>> _sensitivity("11df840d0150d34c9716cd4cbdd164c8", "bondarenko_szigeti_bett_kim_rasmusson_2004_apical", "protocol", "apd90", ("g_Na", "Nao"), seed=1)

    TODO: Make optional arguments of exposure, lower, upper, etc.
    TODO: Accept json dict of model_kwargs, morris_kwargs
    """
    m = Model(exposure + "/" + workspace, maxsteps=1e6, chunksize=1e5, reltol=1e-8)
    phenotypes(m, m.name)  # initialize and cache default
    par = [str(i) for i in par]  # Numpy cannot handle Unicode names
    if not par:
        # Default: sample within plus/minus 50% of all nonzero parameters
        par = [k for k in m.dtype.p.names if m.pr[k] != 0]
    baseline = unstruct(m.pr[par]).squeeze()
    lower = 0.5 * baseline
    upper = 1.5 * baseline
    if seed is not None:
        r.set_seed(seed)

    r("fun <- function(func, x) func(x)")
    raise Exception(str(r.fun(r.sum, baseline)))

    fun = scalar_pheno(m, statistic)
    r.as_vector(baseline)
    return r.morris(fun, factors=par, r=2, design={"type": "oat", "levels": 10, "grid.jump": 5}, binf=lower, bsup=upper)
Пример #2
0
 def cycle(self, index=0, tmax=None, tol=1e-4, n=None):
     """
     Find limit cycle (integrate until successive extrema are almost equal).
     
     :param str_or_int index: Index of state variable to base search on.
     :param float tmax: Time limit for aborting search for limit cycle.
     :param float tol: Tolerance for weighted root-mean-square norm of 
         change in state vector between successive extrema.
     :param int n: Keep history of up to n extrema while searching for 
         limit cycle.
     
     ..  plot::
         :include-source:
         
         >>> from matplotlib import pyplot as plt
         >>> from cgp.cvodeint.namedcvodeint import Namedcvodeint
         >>> from cgp.utils.unstruct import unstruct
         >>> from cgp.phenotyping.attractor import AttractorMixin
         >>> class Test(Namedcvodeint, AttractorMixin):
         ...     '''Inherits van der Pol equations as default example.'''
         ...     pass
         >>> test = Test(t=[0, 10000])
         >>> t, y, period = test.cycle()
         >>> period
         6.663...
         >>> h = plt.plot(t, unstruct(y), '-')
     """
     if tmax is None:
         tmax = self.t[-1]
     extrema = deque([self.next_extremum(tmax, index)], maxlen=n)
     while True:
         t, y, (te, ye) = tup = self.next_extremum(tmax, index)
         extrema.appendleft(tup)
         # pylint:disable=W0612,C0301
         for lag, (t_, y_, (te_, ye_)) in enumerate(extrema): #@UnusedVariable
             if lag == 0:
                 continue
             diff = unstruct(ye_) - unstruct(ye)
             if self.weighted_rms(diff) < tol:
                 L = reversed(list(extrema)[:lag])
                 t, y, _ = catrec(*L, globalize_time=False)
                 period = te - te_
                 return t, y.squeeze(), period
Пример #3
0
def test_dimensions():
    """Check relationship between dimensions of x and unstruct(x)."""
    # x has 2 fields and dimensions (3, 4)
    x = np.arange(24).view(dtype=[(i, int) for i in "ab"]).reshape(3, 4)
    # u has dimensions (3, 4, 2)
    u = unstruct(x)
    # change to u affects x
    u[:] += 10
    # Last dimension of u corresponds to fields of x
    np.testing.assert_equal(x["a"], u[..., 0])
    # First dimensions of u corresponds to first dimensions of x
    np.testing.assert_equal(x[0][0].item(), u[0][0])
Пример #4
0
def test_zero_rank():
    """
    Handle intricacies of zero-rank arrays.
    
    `Zero-rank arrays 
    <http://projects.scipy.org/numpy/wiki/ZeroRankArray>`_ 
    are tricky; they can be structured, yet be of type numpy.void.

    Here, x0 and x1 are almost, but not completely, the same:
    
    >>> fieldtype = np.int32   # ensure same result on 32- and 64-bit platforms
    >>> dtype = [("a", fieldtype), ("b", fieldtype)]
    >>> x0 = np.array([(0, 1)], dtype=dtype)[0]
    >>> x1 = np.array((0, 1), dtype=dtype)

    Despite a lot of equalities below, x0 and x1 are of different type.
    
    >>> (x0 == x1) and (x0.shape == x1.shape) and (x0.dtype == x1.dtype)
    True
    >>> x0
    (0, 1)
    >>> x1
    array((0, 1), dtype=[('a', '<i4'), ('b', '<i4')])
    >>> type(x0), type(x1)
    (<type 'numpy.void'>, <type 'numpy.ndarray'>)
    
    Unstructuring them was tricky, but finally works.
    
    >>> unstruct(x0)
    array([0, 1])
    >>> unstruct(x1)
    array([0, 1])
    """
    fieldtype = np.int32   # ensure same result on 32- and 64-bit platforms
    dtype = [("a", fieldtype), ("b", fieldtype)]
    x0 = np.array([(0, 1)], dtype=dtype)[0]
    x1 = np.array((0, 1), dtype=dtype)
    np.testing.assert_equal(unstruct(x0), unstruct(x1))
Пример #5
0
def do_sensitivity(exposure, workspace, protocol, statistic, par=None, 
    seed=None, model=None, changeset=None, variant=None):
    """
    Sensitivity analysis.
    
    Callback from R.
    
    >>> r("fun <- function(func, x) func(x)")
    RClosure with name <return value from eval>:
    <R function>
    >>> r.fun(r.sum, range(5))
    array([10])
    (R-style, sealed)
    
    >>> m = Model(workspace="beeler_reuter_1977", rename=dict(
    ...     p=dict(IstimPeriod="stim_period", IstimAmplitude="stim_amplitude", 
    ...     IstimPulseDuration="stim_duration", IstimStart="stim_start")), 
    ...     reltol=1e-10, maxsteps=1e6, chunksize=100000)
    >>> m.pr.IstimStart = 0
    >>> print "Result:", do_sensitivity("", "", "protocol", "apbase", ("C", "g_Na"), seed=1, model=m)
    Result:...
    Model runs: 6 
                  mu    mu.star      sigma
    C     0.03672701 0.03672701 0.05130616
    g_Na -0.41200934 0.41200934 0.04219007

    TODO: Make optional arguments of exposure, lower, upper, etc.
    TODO: Accept json dict of model_kwargs, morris_kwargs
    """
    if model is None:
        m = Model(workspace, exposure, changeset, variant, 
            maxsteps=1e6, chunksize=1e5, reltol=1e-8)
        m.pr.stim_start = 0
    else:
        m = model
    phenotypes(m)  # initialize and cache default
    factors = [str(i) for i in par]  # Numpy cannot handle Unicode names
    if not factors:
        # Default: sample within plus/minus 50% of all nonzero parameters
        factors = [k for k in m.dtype.p.names if m.pr[k] != 0]
    baseline = unstruct(m.pr[factors]).squeeze()
    lower = 0.5 * baseline
    upper = 1.5 * baseline
    if seed is not None:
        r.set_seed(seed)
    fun = scalar_pheno(statistic, m, factors)
    design = {"type": "oat", "levels": 10, "grid.jump": 5}
    return r.morris(fun, factors=factors, r=2, design=design, 
        binf=lower, bsup=upper)
Пример #6
0
def shoehorn_recarray(x, ndim=1):
    """
    Shoehorn multi-dimensional record array into HDF-compatible form.
    
    Pytables does not allow table rows to be arrays. Thus, a record array with 
    dimension > 1 cannot be converted to an HDF table. However, it will accept 
    a 1-D record array whose *fields* are arrays. This function rearranges the 
    dimensions of the entire array and its fields, retaining *ndim* dimensions 
    and pushing the rest into the fields.
    
    One dimension is suitable for creating a table, whereas zero dimensions 
    is suitable for a table row.
    
    >>> x = np.arange(24.0).view([("a", float), ("b", float)]).reshape(4, 3)
    >>> y = shoehorn_recarray(x)
    >>> np.testing.assert_equal(x["a"], y["a"])
    
    >>> x.shape
    (4, 3)
    >>> x.dtype
    dtype([('a', '<f8'), ('b', '<f8')])
    >>> y.shape
    (4,)
    >>> y.dtype
    dtype([('a', '<f8', (3,)), ('b', '<f8', (3,))])
    
    >>> z = shoehorn_recarray(x, ndim=0)
    >>> np.testing.assert_equal(x["a"], z["a"])
    >>> z.shape
    ()
    >>> z.dtype
    dtype([('a', '<f8', (4, 3)), ('b', '<f8', (4, 3))])
    """
    u = unstruct(x)
    # The shape of u is x.shape + (#fields,) + fieldshape
    # Roll the #fields dimension to position ndim (note zero-based indexing)
    r = np.rollaxis(u, len(x.shape), ndim)
    dtype = [i[:2] + (r.shape[1 + ndim:],) 
        for i in ast.literal_eval(str(x.dtype))]
    return r.flatten().view(dtype).squeeze()
Пример #7
0
def restruct(a, axes=0):
    """
    Convert shape dimensions to field dimensions.
    
    Converting a record array of shape (3,) with two scalar fields 
    to one of size () whose fields are shape (3,).
    
    >>> restruct(np.array([(0, 1), (2, 3), (4, 5)], 
    ...     dtype=[("a", "|i1"), ("b", "|i1")]))
    array(([0, 2, 4], [1, 3, 5]), dtype=[('a', '|i1', (3,)), ('b', '|i1', (3,))])
    
    This is an array of shape (2, 3) with two scalar fields.
    
    >>> a = np.array([[(0, 1), (2, 3),  (4,  5)],
    ...               [(6, 7), (8, 9), (10, 11)]], 
    ...               dtype=[('a', '|i1'), ('b', '|i1')])
    
    Folding the first dimension into each field gives an array of shape (3,) 
    whose fields have shape (2,).
    
    >>> restruct(a)
    array([([0, 6], [1, 7]), 
           ([2, 8], [3, 9]),
           ([4, 10], [5, 11])], dtype=[('a', '|i1', (2,)), ('b', '|i1', (2,))])
    """
    axes = np.atleast_1d(axes)
    u = unstruct(a)
    ax = range(u.ndim)
    # Move the given axes to the end
    for i in axes:
        ax.remove(i)
        ax.append(i)
    ut = u.transpose(ax).ravel()
    dtype = [(k, u.dtype, a.shape[axes]) for k in a.dtype.names]
    result = ut.view(dtype)
    result.shape = result.shape[:a.ndim - len(axes)]
    return result
Пример #8
0
    ph = np.concatenate([phenotypes(i) for i in mat2par(mat)])
    result = ph["apd90"]
    result[np.isnan(result)] = 0
    return py2ri(result)

@ri.rternalize
def appeak(mat):
    ph = np.concatenate([phenotypes(i) for i in mat2par(mat)])
    result = ph["appeak"]
    result[np.isnan(result)] = 0
    return py2ri(result)

#             mu   mu.star     sigma
#Cm   -0.4348831 0.6603604 0.9338907
#Vmyo  0.1264869 0.1264869 0.1657938
#             mu   mu.star     sigma
#Cm    0.6716927 0.6716927 0.3328038
#Vmyo -0.3135712 0.3135712 0.3033346

if __name__ == "__main__":
    binf = 0.5 * unstruct(m.pr[factors])
    bsup = 1.5 * unstruct(m.pr[factors])
    r.pdf("morrisplot.pdf")
    r.plot(r.morris(apd90, factors=factors, r=2, design={"type": "oat", "levels": 10, "grid.jump": 5}, binf=binf, bsup=bsup))
    r.dev_off()

#    saved = np.load("/tmp/saveme.npy")
#    ph = [phenotypes(i) for i in saved]
#    fail = [np.isnan(i).all() for i in ph]
#    result = np.logical_not(fail).astype(float)
Пример #9
0
    return par

def scalar_pheno(field):
    """Make a function to return a named field of the phenotype array."""
    
    @ri.rternalize
    def fun(rmatrix):
        """Scalar function for use with R's sensitivity::morris()."""
        ph = np.concatenate([phenotypes(i) for i in mat2par(rmatrix)])
        return py2ri(ph[field])
    
    return fun

if __name__ == "__main__":
    # Sensitivity analysis
    baseline = unstruct(m.pr[factors])
    lower = 0.5 * baseline
    upper = 1.5 * baseline
    result = dict()
    for field in "appeak", "apd90", "ctpeak", "ctbase", "ctd90":
        r.set_seed(20120221)  # repeatable random sampling
        result[field] = r.morris(scalar_pheno(field), factors=factors, r=2, 
            design={"type": "oat", "levels": 10, "grid.jump": 5}, 
            binf=lower, bsup=upper)
    # Print and visualize results
    r.png("sensitivity.png", width=1024, height=768, pointsize=24)
    r.par(mfrow=(2, 3))  # multiple figures in two rows, three columns
    for k, v in result.items():
        print "===================================================="
        print k
        print v
Пример #10
0
def test_dtypes():
    """Verify that unstruct() handles different dtypes correctly."""
    for fieldtype in np.int8, np.int32, float:
        dtype = [(i, fieldtype) for i in "ab"]
        x = np.arange(4, dtype=fieldtype).view(dtype)
        yield np.testing.assert_equal, unstruct(x), [[0, 1], [2, 3]]