昨天在Youtube听了Brandon Rhodes的讲座 ,Skyfield and 15 Years of Bad APIs(https://www.youtube.com/watch?v=FVEEndIwOSA ),颇有感触。
Brandon Rhodes是Dropbox公司的高级架构师, 精通Python,同时也是一位天文爱好者( http://rhodesmill.org/brandon/ )。他在2000年左右编写了一个Python程序包PyEphem并且维护至今,这个程序包现在还在使用。PyEphem主要用于计算天体的位置与星历表,例如某地日出日落时刻,天体升降和中天时刻,给定轨道根数计算小行星、彗星和人造卫星在某一时刻、某一历元下的位置以及各种天文坐标系之间的转换等。
PyEphem程序包的名称来源于Ephem软件(http://www.clearskyinstitute.com/xephem/)。Ephem是用C语言写的, Ephem是Ephemeris,即历书的缩写。Ephem软件的作者Elwood C. Downey是位天文学家,在上世纪九十年代编写了Ephem软件并公布了源代码。经过Elwood允许,Brandon Rhodes将Ephem中用于天文计算的引擎libastro提出来, 利用Python胶水语言的特性,编写了一个Python外壳,用于历算。他将这些Python脚本打包发布,就是我们见到的PyEphem。
PyEphem程序包的星历表基于VSOP87行星运动理论(https://en.wikipedia.org/wiki/VSOP_(planets)#VSOP87), 精度已经非常高。在VSO87星历表中,在历元2000.0前后各4000年,水星、金星、地月质心和火星的精度在1角秒以内;木星、土星前后在历元2000.0各2000年,精度在1角秒内;天王星和海王星,前后各6000年,精度在1角秒以内。这样的精度对于绝大多数天文观测、望远镜控制以及中长期的日月食计算都绰绰有余了。但完美主义世家出身的Brandon Rhodes对PyEphem的表现并不满意。
一方面,由于PyEphem的运算核心是用C编写的,而C是一种编译语言,在不同的平台上编译时难免出现各种问题。而且Ephem本身编写的时间比较早,那时候C 语言有些特性现在某些版本的编译器可能已经不支持了,如Windows下用MinGW就不能正常编译PyEphem,而用Visual Studio就可以。虽然大部分人绝大多数时间都用不到Visual Studio,但为了从源代码编译PyEphem,Windows用户不得不安装几个G的Visual Studio。Brandon想了各种办法编译主要平台的二进制版本供用户下载使用,但是某些操作系统不能编译的情况仍然困扰着他。求助他的人太多,光PyEphem程序包相关的问题,他就收到2000多封邮件。
另一方面,随着Python语言的进一步发展,人们逐渐转移到Python3。而从Python3上调用代码的写法和方式的标准来看 (应用程序界面,Application programming interface, API), PyEphem的函数参数以及调用方法等有时让人十分费解。与此同时还有各种各样的潜在问题,一不留神, Python对象就可能因调用某种方法(Method)而发生了变化,以致而得到意想不到的结果,因此这些是要避免的。
为此,Brandon非常想用纯Python重新写一遍PyEphem,不过重新编写一个功能与PyEphem完全一样的程序包,本身就非常无聊,所以他一直没有动力。直到有一天,有位网友问他关于PyEphem结果精度的问题,咨询他怎样将计算结果与瑞士星历表比较,于是他进一步检索到了美国国家航空航天局喷气推进实验室(NASA JPL)的星历表源数据。他获得这些星历表后大喜过望 ,立即着手编写新工具。
JPL是干什么的?了解航空航天的朋友知道,JPL是负责为美国的太空探索计算星历表的,也就是说NASA所发射航天器的轨道,要经过JPL设计并计算,因此,JPL对星历表准确性的要求极高。JPL将一系列高精度星历表公开了,用户可以免费下载和使用(https://pypi.org/project/jplephem/), 其中,著名的 DE405星历表覆盖公元 1600年 到2200年的大行星运动数据。既然星历表的元数据已经公布了,就很容易通过说明文档,计算出星历表规定范围内行星的位置。而通过JPL的DE系列星历表计算大行星位置,直接写一个小程序包是最好不过了。于是Brandon编写了jplephem程序包。他说,与其用很长时间埋头写大项目的代码,一年的之中什么都拿不出来,不如将项目分割成小项目,写一段时间代码就先拿出来,以小项目的形式管理,这样才不至于让自己过于焦虑。
在使用JPL的星历表之后,Brandon不断编写PyEphem类似的功能,这次是用符合现代编码规范,且易于理解的python代码,于是就有了Skyfield程序包 (http://rhodesmill.org/skyfield/)。
Brandon非常看重skyfield。在Skyfield的主页上,他甚至直接说, skyfield对于天文计算来说是“优雅”的。而skyfield程序包,也确实是用优雅的方式进行各种星历表计算和转换,值得天文爱好者们了解和学习。有了它,在个人电脑上实现更高精度的天文计算成为可能。
PyEphem和skyfield受到天文爱好者的欢迎,在业余甚至专业天文学界都有很大的影响,这为Brandon Rhodes赢得了盛誉。他在演讲中提到,有一天,他收到一封求助邮件,发信人向他咨询,能不能帮忙解决美国海军天文台的NOVAS程序在Python中运行的问题,而发邮件的人居然是NASA某实验室的主管。这让他大为惊讶,不过这个忙最后还是帮了。现在在Pipy上novas的Python包 (https://pypi.org/project/novas/), 也是Brandon帮忙整理的。
这里再补充两句,美国海军天文台(United States Naval Observatory)成立于1830年,是天体测量学最为权威的机构之一,负责守时和授时,发布高精度的天文数据。香港天文台从1984年开始编写的《香港天文年历》(https://www.hko.gov.hk/gts/astron2018/almanac2018_index_uc.htm),部分内容就是根据美国海军天文台的数据而计算得出的。NASA的实验室主管请Brandon帮忙解决novas的问题,足以证明他的影响受到官方的重视。
不过,大家不要忘了,其实Brandon的正式职业是高级架构师,天文历算只是他的爱好,他只是一位天文爱好者而已。