2017-07-14 81 views
1

我试图编写一个程序,该程序将从用户处获取一组经度为&的纬度坐标,将它们转换为x & y Mollweide投影映射的坐标,然后报告这些坐标处的像素值(在本例中为噪声温度)。将经度和纬度转换为x和y使用Python中的Newton-Raphson迭代转换Mollweide地图坐标

我正在使用的地图/数据是作为Mollweide投影图提供的Haslam 408 MHz All Sky Survey。这些数据采用.fits格式,是对408 MHz频段噪声的全天候调查。

根据Mollweide projection Wikipedia page,可以使用Newton-Raphson迭代将经度/纬度转换为x/y地图坐标。我在我的程序中基于维基百科页面和this GitHub post中的方法基于迭代方案。

但是,我的程序似乎没有报告我正在输入的经度和纬度的正确值。我基本上怀疑有两个(或两个)因素中的一个导致了这个错误:

  1. 我实现迭代方案的方式不正确,从而导致报告不正确的值。
  2. 我没有正确理解半径值R在迭代方案中的含义。我找不到任何关于如何确定超出“R是要投影的地球半径”的适当R值的文献。我认为这将基于像素大小的地图;在这种情况下,地图图像是4096x2048像素,所以我尝试过使用2048,1024,并且只是1作为R值,但无济于事。

下面我提供我的代码进行审核:如果

from math import sin, cos, pi, sqrt, asin 
from astropy.io import fits 

hdulist = fits.open('data.fits') 
hdulist.info() 
data = hdulist[1].data 

sqrt2 = sqrt(2) 

def solveNR(lat, epsilon=1e-6): #this solves the Newton Raphson iteration 
    if abs(lat) == pi/2: 
     return lat # avoid division by zero 
    theta = lat 
    while True: 
     nexttheta = theta - (
      (2 * theta + sin(2 * theta) - pi * sin(lat))/
      (2 + 2 * cos(2 * theta)) 
     ) 
     if abs(theta - nexttheta) < epsilon: 
      break 
     theta = nexttheta 
    return nexttheta 


def checktheta(theta, lat): #this function is also currently unused while debugging 
    return (2 * theta + sin(2 * theta), pi * sin(lat)) 


def mollweide(lat, lon, lon_0=0, R=1024): 
    lat = lat * pi/180 
    lon = lon * pi/180 
    lon_0 = lon_0 * pi/180 # convert to radians 
    theta = solveNR(lat) 
    return (R * 2 * sqrt2 * (lon - lon_0) * cos(theta)/pi, 
      R * sqrt2 * sin(theta)) 


def inv_mollweide(x, y, lon_0=0, R=1024, degrees=True): # inverse procedure (x, y to lat, long). Currently unused 

    theta = asin(y/(R * sqrt2)) 
    if degrees: 
     factor = 180/pi 
    else: 
     factor = 1 
    return (
     asin((2 * theta + sin(2 * theta))/pi) * factor, 
     (lon_0 + pi * x/(2 * R * sqrt(2) * cos(theta))) * factor 
    ) 
def retrieve_temp(lat, long): #retrieves the noise temp from the data file after calling the mollweide function 
    lat = int(round(lat)) 
    long = int(round(long)) 
    coords = mollweide(lat, long) 
    x, y= coords 
    x = int(round(x)) 
    y= int(round(y)) 
    x = x-1 
    y = y-1 
    if x < 0: 
     x = x*(-1) 
    if y < 0: 
     y = y*(-1) 
    print("The noise temperature is: ",data[y, x],"K") 

def prompt(): #this is the terminal UI 
    cont = 1 
    while cont == 1: 
     lat_cont = 1 
     while lat_cont == 1: 
      lat = float(input('Please enter the latitude: ')) 
      lat_val = 1 
      while lat_val == 1: 
       if lat > 180 or lat < -180: 
        lat = float(input('Invalid input. Make sure your latitude value is in range -180 to 180 degrees \n' 
          'Please enter the latitude: ')) 
       else: 
        lat_val = 0 
        lat_cont = 0 
     long_cont = 1 
     while long_cont == 1: 
      long = float(input('Please enter the longitude: ')) 
      long_val = 1 
      while long_val == 1: 
       if long > 90 or long < -90: 
        long = float(input('Invalid input. Make sure your latitude value is in range -90 to 90 degrees \n' 
          'Please enter the latitude: ')) 
       else: 
        long_val = 0 
        long_cont = 0 
     retrieve_temp(lat, long) 
     valid = 1 
     while valid == 1: 
      ans = input('Would you like to continue? Y or N: ').lower() 
      ans_val = 1 
      while ans_val ==1: 
       if not (ans == 'y' or ans == 'n'): 
        ans = input('Invalid input. Please answer Y or N to continue or exit: ') 
       elif ans == 'y': 
        ans_val = 0 
        cont = 1 
        valid = 0 
       elif ans == 'n': 
        ans_val = 0 
        cont = 0 
        valid = 0 

prompt() 
hdulist.close() 

道歉我没能按照上面的代码典型的Python公约;我是Python的新手。

+0

只是为了确认,你是在做这个个人项目,而不想使用任何现有的工具包,特别是像proj4的东西? – barrycarter

+0

@barrycarter是的,我是一名本科Astro学生,将其作为一个个人夏季项目,以保持我的编码技能与Astro相关。 –

回答

0

你的代码看起来很合理。我的建议是要弄清楚什么是错误的:

(1)尝试评估你的mollweideinv_mollweide函数,你知道结果应该是哪些点。例如。点赤道或主要子午线或类似的东西。

(2)您的mollweideinv_mollweide实际上是反转吗?即如果你从你的输出中取出你的输出并把它放到另一个中,你应该再次得到原始输入。

(3)当您在地图上移动时结果如何变化?你在某些地区(如地图中部附近)获得了正确的结果,而不是其他地区?当你接近边缘会发生什么?它是逐渐变得更加不准确还是有一些门槛,超过这个门槛你会得到非常不正确的答案?

我认为牛顿方法的一个特点是,只有当你足够接近解决方案才能收敛,否则你可以得到任何东西。我不知道你有多接近这个问题。

这似乎是一个很大的问题。祝好运并玩得开心点。

+0

感谢您的咨询!为了回答(3),我知道这种方法不能正常工作的部分原因是某些(有效的)长/经纬度输入返回0.00的值(噪音温度),除非xy对超出了被认为是地图的范围。我会研究确保我足够接近解决方案以获得有意义的答案。 –

+0

好的。我的建议是在查看输出之前验证坐标转换(噪声温度值)。 –

相关问题