def to_mef(data, channels, sc_list, sc_channels = None):
    """
    Transform flow cytometry data using a standard curve function.

    This function accepts a list of standard curves (`sc_list`) and a list
    of channels to which those standard curves should be applied
    (`sc_channels`). `to_mef` automatically checks whether a standard curve
    is available for each channel specified in `channels`, and throws an
    error otherwise.

    This function is intended to be reduced to the following signature::

        to_mef_reduced(data, channels)

    by using ``functools.partial`` once a list of standard curves and their
    respective channels is available.

    Parameters
    ----------
    data : FCSData or numpy array
        NxD flow cytometry data where N is the number of events and D is
        the number of parameters (aka channels).
    channels : int, str, list of int, list of str
        Channels on which to perform the transformation. If `channels` is
        None, perform transformation in all channels specified on
        `sc_channels`.
    sc_list : list of functions
        Functions implementing the standard curves for each channel in
        `sc_channels`.
    sc_channels : list of int or list of str, optional
        List of channels corresponding to each function in `sc_list`. If
        None, use all channels in `data`.

    Returns
    -------
    FCSData or numpy array
        NxD transformed flow cytometry data.

    Raises
    ------
    ValueError
        If any channel specified in `channels` is not in `sc_channels`.

    """
    # Default sc_channels
    if sc_channels is None:
        if data.ndim == 1:
            sc_channels = range(data.shape[0])
        else:
            sc_channels = range(data.shape[1])
    # Check that sc_channels and sc_list have the same length
    if len(sc_channels) != len(sc_list):
        raise ValueError("sc_channels and sc_list should have the same length")
    # Convert sc_channels to indices
    if hasattr(data, '_name_to_index'):
        sc_channels = data._name_to_index(sc_channels)

    # Default channels
    if channels is None:
        channels = sc_channels
    # Convert channels to iterable
    if not (hasattr(channels, '__iter__') \
            and not isinstance(channels, six.string_types)):
        channels = [channels]
    # Convert channels to index
    if hasattr(data, '_name_to_index'):
        channels_ind = data._name_to_index(channels)
    else:
        channels_ind = channels
    # Check if every channel is in sc_channels
    for chi, chs in zip(channels_ind, channels):
        if chi not in sc_channels:
            raise ValueError("no standard curve for channel {}".format(chs))

    # Copy data array
    data_t = data.copy().astype(np.float64)

    # Iterate over channels
    for chi, sc in zip(sc_channels, sc_list):
        if chi not in channels_ind:
            continue
        # Apply transformation
        data_t[:,chi] = sc(data_t[:,chi])
        # Apply transformation to range
        if hasattr(data_t, '_range') and data_t._range[chi] is not None:
            data_t._range[chi] = [sc(data_t._range[chi][0]),
                                  sc(data_t._range[chi][1])]

    return data_t
def to_mef ( data , channels , sc_list , sc_channels = None ) : if sc_channels is None : if data . ndim == 1 : sc_channels = range ( data . shape [ 0 ] ) else : sc_channels = range ( data . shape [ 1 ] ) if len ( sc_channels ) != len ( sc_list ) : raise ValueError ( "sc_channels and sc_list should have the same length" ) if hasattr ( data , '_name_to_index' ) : sc_channels = data . _name_to_index ( sc_channels ) if channels is None : channels = sc_channels if not ( hasattr ( channels , '__iter__' ) and not isinstance ( channels , six . string_types ) ) : channels = [ channels ] if hasattr ( data , '_name_to_index' ) : channels_ind = data . _name_to_index ( channels ) else : channels_ind = channels for chi , chs in zip ( channels_ind , channels ) : if chi not in sc_channels : raise ValueError ( "no standard curve for channel {}" . format ( chs ) ) data_t = data . copy ( ) . astype ( np . float64 ) for chi , sc in zip ( sc_channels , sc_list ) : if chi not in channels_ind : continue data_t [ : , chi ] = sc ( data_t [ : , chi ] ) if hasattr ( data_t , '_range' ) and data_t . _range [ chi ] is not None : data_t . _range [ chi ] = [ sc ( data_t . _range [ chi ] [ 0 ] ) , sc ( data_t . _range [ chi ] [ 1 ] ) ] return data_t
Transform flow cytometry data using a standard curve function.

    This function accepts a list of standard curves (`sc_list`) and a list
    of channels to which those standard curves should be applied
    (`sc_channels`). `to_mef` automatically checks whether a standard curve
    is available for each channel specified in `channels`, and throws an
    error otherwise.

    This function is intended to be reduced to the following signature::

        to_mef_reduced(data, channels)

    by using ``functools.partial`` once a list of standard curves and their
    respective channels is available.

    Parameters
    ----------
    data : FCSData or numpy array
        NxD flow cytometry data where N is the number of events and D is
        the number of parameters (aka channels).
    channels : int, str, list of int, list of str
        Channels on which to perform the transformation. If `channels` is
        None, perform transformation in all channels specified on
        `sc_channels`.
    sc_list : list of functions
        Functions implementing the standard curves for each channel in
        `sc_channels`.
    sc_channels : list of int or list of str, optional
        List of channels corresponding to each function in `sc_list`. If
        None, use all channels in `data`.

    Returns
    -------
    FCSData or numpy array
        NxD transformed flow cytometry data.

    Raises
    ------
    ValueError
        If any channel specified in `channels` is not in `sc_channels`.