For all products in products, will call the correct fetch routine and download an image
        :param multithread: if true will fetch the files simultaneously
        :type multithread: bool
        :param median_kernel: the size of the kernel to smooth by
        :type median_kernel: int >= 0
        :return: a dictionary of all fetched products
        :rtype: dict from product string to (header, data) tuple

def fetch(self, multithread=True, median_kernel=5, solar_diam=740):
        """
        For all products in products, will call the correct fetch routine and download an image
        :param multithread: if true will fetch the files simultaneously
        :type multithread: bool
        :param median_kernel: the size of the kernel to smooth by
        :type median_kernel: int >= 0
        :return: a dictionary of all fetched products
        :rtype: dict from product string to (header, data) tuple
        """

        # helper function to pull data
        def func_map(product):
            """
            determines which function to call for a specific product and gets
            :param product: which product to fetch
            :type product: str
            :return: product tuple
            :rtype: (header, data)
            """
            if "halpha" in product:
                result = self.fetch_halpha(median_kernel=median_kernel)
            elif "aia" in product:
                result = self.fetch_aia(product, median_kernel=median_kernel)
            elif "l1b" in product:
                result = self.fetch_suvi_l1b(product, median_kernel=median_kernel)
            elif "l2-ci" in product:
                result = self.fetch_suvi_composite(product, median_kernel=median_kernel)
            elif "limb" in product:
                result = self.fetch_limb(solar_diam)
            else:
                raise ValueError("{} is not a valid product.".format(product))
            return result

        if multithread:
            pool = ThreadPool()
            results = pool.map(func_map, self.products)
        else:
            results = [func_map(product) for product in self.products]

        results = {product: (head, data) for product, head, data in results}
        return results