转换纬度&;经度至x&;Python中使用Newton-Raphson迭代的y-Mollweide映射坐标

转换纬度&;经度至x&;Python中使用Newton-Raphson迭代的y-Mollweide映射坐标,python,math,maps,astronomy,Python,Math,Maps,Astronomy,我正在尝试编写一个程序,从用户那里获取一组经纬度坐标,将它们转换为Mollweide投影地图的x&y坐标,然后报告这些坐标处的像素值(在本例中,是噪声温度) 我使用的地图/数据是作为Mollweide投影地图提供的。该数据采用.fits格式,是对408 MHz频段噪声的大型全天空测量 根据,可以使用Newton-Raphson迭代将经度/纬度转换为x/y地图坐标。我的程序中的迭代方案主要基于Wikipedia页面和中的方法 但是,我的程序似乎没有报告我输入的经度和纬度的正确值。我主要怀疑两个(或

我正在尝试编写一个程序,从用户那里获取一组经纬度坐标,将它们转换为Mollweide投影地图的x&y坐标,然后报告这些坐标处的像素值(在本例中,是噪声温度)

我使用的地图/数据是作为Mollweide投影地图提供的。该数据采用.fits格式,是对408 MHz频段噪声的大型全天空测量

根据,可以使用Newton-Raphson迭代将经度/纬度转换为x/y地图坐标。我的程序中的迭代方案主要基于Wikipedia页面和中的方法

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

  • 我实现迭代方案的方式是不正确的,因此会导致报告不正确的值
  • 我不能正确理解半径值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()
    
    从数学导入sin、cos、pi、sqrt、asin
    从astropy.io导入拟合
    hdulist=fits.open('data.fits')
    hdulist.info()
    data=hdulist[1]。数据
    sqrt2=sqrt(2)
    def solveNR(lat,epsilon=1e-6):#这解决了牛顿-拉斐逊迭代
    如果abs(lat)=pi/2:
    返回lat#避免被零除
    θ=纬度
    尽管如此:
    nexttheta=θ-(
    (2*theta+sin(2*theta)-pi*sin(lat))/
    (2+2*cos(2*theta))
    )
    如果abs(θ-nexttheta)180或lat<-180:
    lat=float(输入('无效输入。请确保纬度值在-180到180度范围内\n'
    '请输入纬度:'))
    其他:
    lat_val=0
    横向控制=0
    长续=1
    当long_cont==1时:
    long=float(输入('请输入经度:'))
    long_val=1
    当long_val==1时:
    如果长>90或长<-90:
    long=float(输入('无效输入。请确保纬度值在-90到90度之间\n'
    '请输入纬度:'))
    其他:
    long_val=0
    long_cont=0
    检索温度(横向、纵向)
    有效=1
    当valid==1时:
    ans=input('您想继续吗?Y还是N:')。lower()
    ans_val=1
    当ans_val==1时:
    如果不是(ans=='y'或ans=='n'):
    ans=input('无效输入。请回答Y或N以继续或退出:')
    elif ans==“y”:
    ans_val=0
    cont=1
    有效=0
    elif ans=='n':
    ans_val=0
    cont=0
    有效=0
    提示符()
    hdulist.close()
    

    如果我在上面的代码中没有遵循典型的Python约定,我深表歉意;我是Python新手。

    您的代码看起来很合理。关于找出问题所在,我的建议是:

    (1) 尝试在您知道结果的点上评估
    mollweide
    inv_mollweide
    函数。例如,赤道或本初子午线上的点或类似的简单点

    (2) 你的
    mollweide
    inv\u mollweide
    实际上是相反的吗?i、 e.如果你从一个输入中提取输出并将其放入另一个输入中,你应该再次获得原始输入

    (3) 当你在地图上移动时,结果是如何变化的?您是否在某些区域(例如地图中间附近)得到正确的结果,而在其他区域没有得到正确的结果?当你靠近边缘时会发生什么?它是否逐渐变得更加不准确,或者是否存在某个阈值,超过该阈值,您会得到严重错误的答案

    我认为纽托有一个特点