<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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