如何加速此功能

2024-09-28 22:12:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在从维齐尔下载星表(使用astroquery)。有关的星表不包括恒星名称,所以我是从辛巴德(也使用astroquery)通过查询我的维齐尔星表中每颗恒星1弧秒范围内的所有辛巴德恒星得到这些名称的。你知道吗

然后我需要按ra/dec坐标进行匹配。然而维齐尔和西姆巴德的坐标可能有点不准确,所以我不能做一个精确的匹配。你知道吗

我目前的解决方案是指定一个公差,对于每一个维齐尔星,调用下面的函数在西姆巴德星之间循环,测试坐标是否在指定的公差范围内一致。作为一个双重检查,因为恒星可以非常接近,我还检查了星等是否匹配到0.1 mag以内

这一切工作,但维齐尔目录的c.2000恒星和类似大小的辛巴德数据集需要2分钟以上运行。我在想办法加快速度。你知道吗

    def get_simbad_name(self, vizier_star, simbad_stars, tolerance):
        """
        Searches simbad_stars to find the SIMBAD name of the star 
        referenced in vizier_star.

        A match is deemed to exist if a star in simbad_stars has both 
        ra and dec +/- tolerance of the target vizier_star and if their V 
        magnitudes, rounded to one decimal place, also match.

        Parameters
        ==========
        vizier_star : astropy.table.Row
            Row of results from Vizier query, corresponding to a star in a 
            Vizier catalog. Columns of interest to this function are:

            '_RAJ2000' : float [Right ascension in decimal degrees]
            '_DEJ2000' : float [Declination in decimal degrees]
            'Vmag' : float [V magnitude (to 3 decimal places)]

        simbad_stars : list of dict
            List of star data derived from a Vizier query. Keys of interest 
            to this function are:

            'ra' : float [Right ascension in decimal degrees (ICRS/J2000)]
            'dec' : float [Declination in decimal degrees (ICRS/J2000)]
            'Vmag' : float [V magnitude (to 3 decimal places)]
            'name' : str [SIMBAD primary id of star]

        tolerance : float
            The tolerance, in degrees, to be used in determining whether 
            the ra/dec coordinates match.

        Returns
        =======
        name : str
            If match then returns the SIMBAD name. If no match returns 
            an empty string.

        Notes
        =====
        simbad_stars are not all guaranteed to have Vmag. Any that don't are 
        ignored.
        """
        for item in simbad_stars:
            try:
                approx_Vmag = round(item['Vmag'],1)
            except KeyError:
                continue
            if ((vizier_star['_RAJ2000'] > item['ra'] - tolerance) and
                (vizier_star['_RAJ2000'] < item['ra'] + tolerance) and
                (vizier_star['_DEJ2000'] > item['dec'] - tolerance) and
                (vizier_star['_DEJ2000'] < item['dec'] + tolerance) and
                (round(vizier_star['Vmag'],1) == approx_Vmag)):
                return item['name']
        return ''

评论之后还有一些想法:

比赛的成功率很高(约99%),所以在几乎所有情况下,循环都会提前退出。它不必迭代所有的星。你知道吗

如果我按ra对simbadè星进行预排序,并使用二进制切分得到循环开始位置的索引,我可以进一步改进。你知道吗


Tags: oftonameinfloatitemtolerancedec
2条回答

这个问题看起来会因为如何提问而结束,但有两个有用的答案:

(1)有关位置交叉匹配,请参见https://docs.astropy.org/en/stable/coordinates/matchsep.html

(2)对于您在这里所做的一般情况,您应该使用矢量化操作,而不是在源上循环。你知道吗

我已经设法实现了20倍的速度提高预排序辛巴德\u星和使用平分\u左和平分\u右定义开始和停止索引内。你知道吗

如果有人感兴趣,我可以发布代码(它比原来的代码要长一些,因为它是一个使用自定义类的更通用的解决方案)。你知道吗

相关问题 更多 >