Exemplo n.º 1
0
Arquivo: filters.py Projeto: rc/elfpy
def detect_linear_regions(data, eps_r=0.01, run=10):
    """
    Detect linear-like regions of stress-strain curve (i.e. the regions of
    small and large deformations). The first and last regions are identified
    with small and large deformation linear regions.

    Notes
    -----
    Sets `strain_regions` and `strain_regions_iranges` attributes of `data`.
    """
    stress = data.stress
    window_size = max(int(0.001 * stress.shape[0]), 35)

    ds = savitzky_golay(stress, window_size, 3, 1)
    de = savitzky_golay(data.strain, window_size, 3, 1)
    dstress = ds / de
    ddstress = savitzky_golay(dstress, window_size, 3, 1)

    p1 = np.where(dstress >= 0)[0]
    p2 = np.ediff1d(p1, to_end=2)
    p3 = np.where(p2 > 1)[0]
    if p3[0] == 0 or p3[0] == 1:
        index_value = p1[-1]
    else:
        index_value = p1[p3][0]
    output('index_value:', index_value) # Usually equal to data.iult.

    ddstress = ddstress[:index_value]
    addstress = np.abs(ddstress)
    eps = eps_r * addstress.max()
    ii = np.where(addstress < eps)[0]
    idd = np.ediff1d(ii)
    ir = np.where(idd > 1)[0]

    run_len = int((run * index_value) / 100.)

    regions = []
    ic0 = 0
    for ic in ir:
        region = slice(ii[ic0], ii[ic] + 1)
        ic0 = ic + 1
        if (region.stop - region.start) >= run_len:
            regions.append(region)

    output('%d region(s)' % len(regions))

    data.strain_regions_iranges = regions
    data.strain_regions = [(data.strain[ii.start], data.strain[ii.stop])
                           for ii in data.strain_regions_iranges]

    return data
Exemplo n.º 2
0
Arquivo: filters.py Projeto: rc/elfpy
def list_commands(namespace=None, name='filters', arg0_name='data', ikw=1):
    """
    List all available commands in a given namespace.
    """
    if namespace is None: namespace = globals()

    head = 'available %s' % name
    output(head)
    output('-' * len(head))
    output.level += 1

    names = sorted(namespace.keys())
    for name in names:
        fun = namespace[name]
        if not inspect.isfunction(fun): continue
        if name.startswith('_'): continue

        (args, varargs, keywords, defaults) = inspect.getargspec(fun)
        if not len(args) or (args[0] != arg0_name): continue

        if defaults is not None:
            args_str = ', '.join(['%s=%s' % (args[ii], defaults[ii - ikw])
                                  for ii in range(ikw, len(args))])
        else:
            args_str = ''

        output('%s(%s)' % (name, args_str))

    output.level -= 1
    output('.')
Exemplo n.º 3
0
Arquivo: filters.py Projeto: rc/elfpy
def get_ultimate_values(data, eps=0.1):
    """
    Get ultimate stress and strain.
    """
    stress = data.stress
    dstress = np.diff(stress, n=1)/ np.diff(data.strain, n=1)

    ii = np.where(dstress < 0)[0]
    if len(ii) == 0:
        output('warning: stress does not decrease')
        iult = stress.shape[0] - 1

    else:
        iult = np.where(stress[ii] > (eps * stress.max()))[0]
        if len(iult) == 0:
            iult = ii[0]
            output('warning: ultimate stress is less then %f*max stress' % eps)

        else:
            iult = ii[iult[0]]

    data.iult = iult
    output('index of ultimate strength:', iult)

    data.ultimate_strain = data.strain[iult]
    data.ultimate_stress = stress[iult]
    output('ultim. strain, ultim. stress:',
           data.ultimate_strain, data.ultimate_stress)

    return data
Exemplo n.º 4
0
Arquivo: filters.py Projeto: rc/elfpy
def _find_irange(values, val0, val1, msg='wrong range'):
    """
    Find the first consecutive range [i0, i1] in `values` such that
    values[i0] is the first value such that `val0 <= values[i0]` and
    values[i1] is the last value such that `values[i1] <= val1`.
    """
    assert(val0 < val1)

    i0 = np.where((values[:-1] <= val0) & (val0 <= values[1:]))[0]
    i1 = np.where((values[:-1] <= val1) & (val1 <= values[1:]))[0]
    if len(i0) and len(i1):
        irange = slice(i0[0] + 1, i1[-1] + 1)

    else:
        raise ValueError('%s! ([%.2e, %.2e] in [%.2e, %.2e])'
                         % (msg, val0, val1, values.min(), values.max()))

    output('required: [%s, %s], found: [%s, %s]'
           % ((val0, val1, values[irange.start], values[irange.stop - 1])))

    return irange
Exemplo n.º 5
0
Arquivo: filters.py Projeto: rc/elfpy
def select_cycle(data, cycle=-1):
    """
    Select current cycle.

    Notes
    -----
    Calls automatically :func:`detect_strain_cycles()` if needed. Sets `irange`
    attribute of `data`.
    """
    if not len(data.cycles):
        data = detect_strain_cycles(data)

    data.icycle = cycle
    try:
        data.irange = data.cycles[cycle]

    except IndexError:
        output('cycle %d is not present, using the last one!' % cycle)
        data.icycle = -1
        data.irange = data.cycles[-1]

    return data
Exemplo n.º 6
0
Arquivo: filters.py Projeto: rc/elfpy
def fit_stress_strain(data, region_kind='strain', which=[-999]):
    """
    Determine Young's modulus of elasticity in the selected regions.

    Special value of `which` equal to [-999] means all regions.

    Notes
    -----
    Sets `strain_regions_lin_fits` or `stress_regions_lin_fits` attribute of
    `data`, according to `region_kind`.
    """
    if region_kind == 'strain':
        iranges = data.strain_regions_iranges
        lin_fits = data.strain_regions_lin_fits = []

    elif region_kind == 'stress':
        iranges = data.stress_regions_iranges
        lin_fits = data.stress_regions_lin_fits = []

    else:
        raise ValueError('unknown region kind! (%s)' % region_kind)

    if which == [-999]:
        which = range(len(iranges))

    for ii in which:
        try:
            indx = iranges[ii]

        except IndexError:
            raise IndexError('%s region %d does not exist!' % (region_kind, ii))

        output('%s index range: (%d, %d)'
               % (region_kind, indx.start, indx.stop))
        out = _fit_stress_strain(data.stress[indx], data.strain[indx])
        lin_fits.append((ii, out))

    return data
Exemplo n.º 7
0
Arquivo: process.py Projeto: rc/elfpy
def run_pipeline(filters, plots, saves, datas):
    """
    Apply filters and then plots to datas.
    """
    for ii, flt in enumerate(filters):
        fun, kwargs = flt

        aux = ', '.join(['%s=%s' % kw for kw in kwargs.iteritems()])
        output('applying: %s(%s) ...' % (fun.__name__, aux))

        for ir, data in enumerate(datas):
            output('processing: %s ...' % data.name)

            # The filter action modifies data in-place.
            data = fun(data, **kwargs)

            output('...done')
        output('...done')

        datas[ir] = data

    ax = None
    for ii, plot in enumerate(plots):
        fun, kwargs = plot
        kwargs = copy.copy(kwargs)

        aux = ', '.join(['%s=%s' % kw for kw in kwargs.iteritems()])
        output('applying: %s(%s) ...' % (fun.__name__, aux))

        shared_ax = kwargs.pop('ax', None)
        if shared_ax is not None: # True plot command.
            ax = ax if shared_ax else None

        is_legend = False
        for ir, data in enumerate(datas):
            output('plotting: %s ...' % data.name)

            is_legend = is_legend or kwargs.get('label', '')
            _ax = fun(data, ax=ax, **kwargs)

            output('...done')
            if _ax is None:
                if len(datas) > 1:
                    output('non-plot command, skipping other data')
                    break

            else:
                ax = _ax

        output('...done')

        if is_legend:
            plt.legend()

    for ii, save in enumerate(saves):
        fun, kwargs = save

        aux = ', '.join(['%s=%s' % kw for kw in kwargs.iteritems()])
        output('executing: %s(%s) ...' % (fun.__name__, aux))

        fun(datas, **kwargs)

        output('...done')
Exemplo n.º 8
0
Arquivo: filters.py Projeto: rc/elfpy
def parse_filter_pipeline(commands, get=None, name='filters', ikw=1):
    """
    Parse commands string defining a pipeline.
    """
    if commands is None: return []

    cmds = commands.split(':')

    if get is None: get = globals().get

    output('parsing %s...' % name)

    filters = []
    for ic, cmd in enumerate(cmds):
        output('cmd %d: %s' % (ic, cmd))

        aux = cmd.split(',')
        filter_name = aux[0].strip()
        filter_args = aux[1:]

        fun = get(filter_name)
        if fun is None:
            raise ValueError('filter "%s" does not exist!' % filter_name)
        (args, varargs, keywords, defaults) = inspect.getargspec(fun)

        if defaults is None:
            defaults = []

        if len(defaults) < len(filter_args):
            raise ValueError('filter "%s" takes only %d arguments!'
                             % (filter_name, len(defaults)))

        # Process args after data.
        kwargs = {}
        arg_parser = getattr(fun, '_elfpy_arg_parsers', {})
        for ia, arg in enumerate(args[ikw:]):
            if ia < len(filter_args):
                farg = filter_args[ia].strip()
                if arg in arg_parser:
                    parser = arg_parser[arg]
                    try:
                        kwargs[arg] = parser(farg)

                    except ValueError:
                        msg = 'argument "%s" cannot be converted to %s(%s)!'
                        raise ValueError(msg % (arg, type(defaults[ia]),
                                                type(defaults[ia][0])))

                else:
                    try:
                        kwargs[arg] = type(defaults[ia])(farg)

                    except ValueError:
                        msg = 'argument "%s" cannot be converted to %s!'
                        raise ValueError(msg % (arg, type(defaults[ia])))

            else:
                kwargs[arg] = defaults[ia]

        output('using arguments:', kwargs)

        filters.append((fun, kwargs))

    output('...done')

    return filters