<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def fetch_losc_data(detector, start, end, cls=TimeSeries, **kwargs):
 """Fetch LOSC data for a given detector This function is for internal purposes only, all users should instead use the interface provided by `TimeSeries.fetch_open_data` (and similar for `StateVector.fetch_open_data`). """

    # format arguments
    start = to_gps(start)
    end = to_gps(end)
    span = Segment(start, end)
    kwargs.update({
        'start': start,
        'end': end,
    })

    # find URLs (requires gwopensci)
    url_kw = {key: kwargs.pop(key) for key in GWOSC_LOCATE_KWARGS if
              key in kwargs}
    if 'sample_rate' in url_kw:  # format as Hertz
        url_kw['sample_rate'] = Quantity(url_kw['sample_rate'], 'Hz').value
    cache = get_urls(detector, int(start), int(ceil(end)), **url_kw)
    # if event dataset, pick shortest file that covers the request
    # -- this is a bit hacky, and presumes that only an event dataset
    # -- would be produced with overlapping files.
    # -- This should probably be improved to use dataset information
    if len(cache) and _overlapping(cache):
        cache.sort(key=lambda x: abs(file_segment(x)))
        for url in cache:
            a, b = file_segment(url)
            if a <= start and b >= end:
                cache = [url]
                break
    if kwargs.get('verbose', False):  # get_urls() guarantees len(cache) >= 1
        host = urlparse(cache[0]).netloc
        print("Fetched {0} URLs from {1} for [{2} .. {3}))".format(
            len(cache), host, int(start), int(ceil(end))))

    is_gwf = cache[0].endswith('.gwf')
    if is_gwf and len(cache):
        args = (kwargs.pop('channel', None),)
    else:
        args = ()

    # read data
    out = None
    kwargs['cls'] = cls
    for url in cache:
        keep = file_segment(url) & span
        new = _fetch_losc_data_file(url, *args, **kwargs).crop(
            *keep, copy=False)
        if is_gwf and (not args or args[0] is None):
            args = (new.name,)
        if out is None:
            out = new.copy()
        else:
            out.append(new, resize=True)
    return out