Download WFDB record (and optionally annotation) files from a
    Physiobank database. The database must contain a 'RECORDS' file in
    its base directory which lists its WFDB records.

    Parameters
    ----------
    db_dir : str
        The Physiobank database directory to download. eg. For database:
        'http://physionet.org/physiobank/database/mitdb', db_dir='mitdb'.
    dl_dir : str
        The full local directory path in which to download the files.
    records : list, or 'all', optional
        A list of strings specifying the WFDB records to download. Leave
        as 'all' to download all records listed in the database's
        RECORDS file.
        eg. records=['test01_00s', test02_45s] for database:
        https://physionet.org/physiobank/database/macecgdb/
    annotators : list, 'all', or None, optional
        A list of strings specifying the WFDB annotation file types to
        download along with the record files. Is either None to skip
        downloading any annotations, 'all' to download all annotation
        types as specified by the ANNOTATORS file, or a list of strings
        which each specify an annotation extension.
        eg. annotators = ['anI'] for database:
        https://physionet.org/physiobank/database/prcp/
    keep_subdirs : bool, optional
        Whether to keep the relative subdirectories of downloaded files
        as they are organized in Physiobank (True), or to download all
        files into the same base directory (False).
    overwrite : bool, optional
        If True, all files will be redownloaded regardless. If False,
        existing files with the same name and relative subdirectory will
        be checked. If the local file is the same size as the online
        file, the download is skipped. If the local file is larger, it
        will be deleted and the file will be redownloaded. If the local
        file is smaller, the file will be assumed to be partially
        downloaded and the remaining bytes will be downloaded and
        appended.

    Examples
    --------
    >>> wfdb.dl_database('ahadb', os.getcwd())

def dl_database(db_dir, dl_dir, records='all', annotators='all',
                keep_subdirs=True, overwrite=False):
    """
    Download WFDB record (and optionally annotation) files from a
    Physiobank database. The database must contain a 'RECORDS' file in
    its base directory which lists its WFDB records.

    Parameters
    ----------
    db_dir : str
        The Physiobank database directory to download. eg. For database:
        'http://physionet.org/physiobank/database/mitdb', db_dir='mitdb'.
    dl_dir : str
        The full local directory path in which to download the files.
    records : list, or 'all', optional
        A list of strings specifying the WFDB records to download. Leave
        as 'all' to download all records listed in the database's
        RECORDS file.
        eg. records=['test01_00s', test02_45s] for database:
        https://physionet.org/physiobank/database/macecgdb/
    annotators : list, 'all', or None, optional
        A list of strings specifying the WFDB annotation file types to
        download along with the record files. Is either None to skip
        downloading any annotations, 'all' to download all annotation
        types as specified by the ANNOTATORS file, or a list of strings
        which each specify an annotation extension.
        eg. annotators = ['anI'] for database:
        https://physionet.org/physiobank/database/prcp/
    keep_subdirs : bool, optional
        Whether to keep the relative subdirectories of downloaded files
        as they are organized in Physiobank (True), or to download all
        files into the same base directory (False).
    overwrite : bool, optional
        If True, all files will be redownloaded regardless. If False,
        existing files with the same name and relative subdirectory will
        be checked. If the local file is the same size as the online
        file, the download is skipped. If the local file is larger, it
        will be deleted and the file will be redownloaded. If the local
        file is smaller, the file will be assumed to be partially
        downloaded and the remaining bytes will be downloaded and
        appended.

    Examples
    --------
    >>> wfdb.dl_database('ahadb', os.getcwd())

    """
    # Full url physiobank database
    db_url = posixpath.join(download.config.db_index_url, db_dir)
    # Check if the database is valid
    r = requests.get(db_url)
    r.raise_for_status()

    # Get the list of records
    recordlist = download.get_record_list(db_dir, records)
    # Get the annotator extensions
    annotators = download.get_annotators(db_dir, annotators)

    # All files to download (relative to the database's home directory)
    allfiles = []

    for rec in recordlist:
        # Check out whether each record is in MIT or EDF format
        if rec.endswith('.edf'):
            allfiles.append(rec)
        else:
            # May be pointing to directory
            if rec.endswith('/'):
                rec = rec + rec[:-1]
            # If MIT format, have to figure out all associated files
            allfiles.append(rec+'.hea')
            dir_name, baserecname = os.path.split(rec)
            record = rdheader(baserecname, pb_dir=posixpath.join(db_dir, dir_name))

            # Single segment record
            if isinstance(record, Record):
                # Add all dat files of the segment
                for file in (record.file_name if record.file_name else []):
                    allfiles.append(posixpath.join(dir_name, file))

            # Multi segment record
            else:
                for seg in record.seg_name:
                    # Skip empty segments
                    if seg == '~':
                        continue
                    # Add the header
                    allfiles.append(posixpath.join(dir_name, seg+'.hea'))
                    # Layout specifier has no dat files
                    if seg.endswith('_layout'):
                        continue
                    # Add all dat files of the segment
                    recseg = rdheader(seg, pb_dir=posixpath.join(db_dir, dir_name))
                    for file in recseg.file_name:
                        allfiles.append(posixpath.join(dir_name, file))
        # check whether the record has any requested annotation files
        if annotators is not None:
            for a in annotators:
                annfile = rec+'.'+a
                url = posixpath.join(download.config.db_index_url, db_dir, annfile)
                rh = requests.head(url)

                if rh.status_code != 404:
                    allfiles.append(annfile)

    dlinputs = [(os.path.split(file)[1], os.path.split(file)[0], db_dir, dl_dir, keep_subdirs, overwrite) for file in allfiles]

    # Make any required local directories
    download.make_local_dirs(dl_dir, dlinputs, keep_subdirs)

    print('Downloading files...')
    # Create multiple processes to download files.
    # Limit to 2 connections to avoid overloading the server
    pool = multiprocessing.Pool(processes=2)
    pool.map(download.dl_pb_file, dlinputs)
    print('Finished downloading files')

    return