def _execute_data_download(self, data_filter, redownload, max_threads, raise_download_errors):
        """Calls download module and executes the download process

        :param data_filter: Used to specify which items will be returned by the method and in which order. E.g. with
            `data_filter=[0, 2, -1]` the method will return only 1st, 3rd and last item. Default filter is ``None``.
        :type data_filter: list(int) or None
        :param redownload: data is redownloaded if ``redownload=True``. Default is ``False``
        :type redownload: bool
        :param max_threads: the number of workers to use when downloading, default ``max_threads=None``
        :type max_threads: int
        :param raise_download_errors: If ``True`` any error in download process should be raised as
            ``DownloadFailedException``. If ``False`` failed downloads will only raise warnings.
        :type raise_download_errors: bool
        :return: List of data obtained from download
        :rtype: list
        """
        is_repeating_filter = False
        if data_filter is None:
            filtered_download_list = self.download_list
        elif isinstance(data_filter, (list, tuple)):
            try:
                filtered_download_list = [self.download_list[index] for index in data_filter]
            except IndexError:
                raise IndexError('Indices of data_filter are out of range')

            filtered_download_list, mapping_list = self._filter_repeating_items(filtered_download_list)
            is_repeating_filter = len(filtered_download_list) < len(mapping_list)
        else:
            raise ValueError('data_filter parameter must be a list of indices')

        data_list = []
        for future in download_data(filtered_download_list, redownload=redownload, max_threads=max_threads):
            try:
                data_list.append(future.result(timeout=SHConfig().download_timeout_seconds))
            except ImageDecodingError as err:
                data_list.append(None)
                LOGGER.debug('%s while downloading data; will try to load it from disk if it was saved', err)
            except DownloadFailedException as download_exception:
                if raise_download_errors:
                    raise download_exception
                warnings.warn(str(download_exception))
                data_list.append(None)

        if is_repeating_filter:
            data_list = [copy.deepcopy(data_list[index]) for index in mapping_list]

        return data_list
Calls download module and executes the download process

        :param data_filter: Used to specify which items will be returned by the method and in which order. E.g. with
            `data_filter=[0, 2, -1]` the method will return only 1st, 3rd and last item. Default filter is ``None``.
        :type data_filter: list(int) or None
        :param redownload: data is redownloaded if ``redownload=True``. Default is ``False``
        :type redownload: bool
        :param max_threads: the number of workers to use when downloading, default ``max_threads=None``
        :type max_threads: int
        :param raise_download_errors: If ``True`` any error in download process should be raised as
            ``DownloadFailedException``. If ``False`` failed downloads will only raise warnings.
        :type raise_download_errors: bool
        :return: List of data obtained from download
        :rtype: list