2017-02-09 23 views
3

Ellipse2Dモデルを使って楕円をastropyライブラリに収めようとしています。フィットは機能しません。モデル化されたパラメータは初期パラメータと同じです(振幅パラメータを除いて)。以下のコードを参照してください:天体を使って楕円をフィッティングする[Ellipse2d model]

import numpy as np 
from astropy.modeling import models, fitting 
import matplotlib.pyplot as pl 

# fake data 
num = 100 
x, y = np.meshgrid(np.linspace(-5., 5., num), np.linspace(-5, 5, num)) 
e0 = models.Ellipse2D(amplitude=1., x_0=0., y_0=0., a=2, b=1, theta=0.) 
z0 = e0(x, y) 
print 'DATA:\n', e0, '\n\n' 

# initial model 
ei = models.Ellipse2D(amplitude=1., x_0=0.0, y_0=0.0, a=2, b=2, theta=0.2) 

fi = fitting.LevMarLSQFitter() 

#fitted model? 
e1 = fi(ei, x, y, z0) 
z1 = e1(x, y) 
print 'MODEL:\n', e1, '\n\n' 

pl.imshow(z0, extent=[-5, 5, -5, 5], alpha=0.5) 
pl.imshow(z1, extent=[-5, 5, -5, 5], alpha=0.2) 
pl.show() 
+0

あなたは異なるフィッタを試したことがありますか? Ellipse2Dモデルがしっかりした楕円を描いているようだから、これが本当にうまくいくのだろうかと思います。 – Iguananaut

+0

はい私はそれらのすべてを試みました。 SimplexLSQFitter(下を参照)は、何らかの良い結果をもたらしますが、それでもなお満足できるものはありません。 –

答えて

0

としては、すでに別のフィッターがSimplexLSQFitter例えば、この作業に適しかもしれません指摘しました。

これは完全に楕円を適合しませんが、少なくともbパラメータは、ほぼ良い一致が得られます。

... 
fi = fitting.SimplexLSQFitter() 
e1 = fi(ei, x, y, z0) 
z1 = e1(x, y) 
print(repr(e1)) 
# <Ellipse2D(amplitude=0.8765330382805181, 
#   x_0=0.00027076793418705464, 
#   y_0=0.0008061856852329963, 
#   a=2.0019138872185174, 
#   b=1.0985760645823452, 
#   theta=0.22591442574477916)> 

しかし、私はEllipse2Dthetaの間に異なる場合は特に、嵌合する良いモデルではないと思いますモデル。

+0

ありがとう、実際にはSimplexLSQFitterはより良い(任意の)結果を示しますが、私が見つけようとしている主なパラメータは傾き(シータ)であり、そこでは失敗します。 私はEllipse2Dが楕円の傾きを見つけるのに最適であるべきだと思ったが、明らかに間違っていた。あなたはそれを行うためのより良い方法を知っていますか? –

2

私はこの時点でまったく同じ問題を抱えていたので、この質問やAstropyメーリングリストの回答を待っていました。

私は答えを見つけることができませんでしたので、自分の/ myコードの問題を理解するまでパラメータを取得するためにGaussian2Dを使用するまでEllipse2Dを使用しないことにしました。

次のコードを試してみてください。私はちょっとしたコードを変更しました。

import numpy as np 
from astropy.modeling import models, fitting 
import matplotlib.pyplot as pl 

#%% 
# data 
num = 100 
x, y = np.meshgrid(np.linspace(-5., 5., num), np.linspace(-5, 5, num)) 
e0 = models.Ellipse2D(amplitude=1., x_0=0., y_0=0., a=2, b=1, theta=0.) 
z0 = e0(x, y) 
print ('DATA:\n', e0, '\n\n') 

#%% 
# initial model 
ei = models.Ellipse2D(amplitude=1., x_0=0.1, y_0=0.1, a=3, b=2, theta=0.2) 
gi = models.Gaussian2D(amplitude=1., x_mean=0.1, y_mean=0.1, 
         x_stddev=3, y_stddev=2, theta=0.2) 
fi = fitting.LevMarLSQFitter() 

#%% 
# fitted model? 
e1 = fi(ei, x, y, z0) 
g1 = fi(gi, x, y, z0) 
z1 = e1(x, y) 
z2 = g1(x, y) 
print('MODEL:\n', e1, '\n\n') 
print('MODEL:\n', g1, '\n\n') 

pl.imshow(z0, extent=[-5, 5, -5, 5], alpha=0.5) 
pl.imshow(z1, extent=[-5, 5, -5, 5], alpha=0.2) 
pl.imshow(z2, extent=[-5, 5, -5, 5], alpha=0.5) 
pl.colorbar() 
pl.show() 
print(g1.theta.value) 

それは一定の振幅で与えられた楕円形の台地に適合していませんが、まだそれは実質的にゼロである正しいtheta1.23386185422e-10を与えるが。 thetae0をいくつかの異なる値に変更すると、正しい値が得られます。

希望しました!ここでは、@ yoonsoo-P-バッハの提案に

+0

お手伝い、ありがとうございました。 –

0

おかげで作業例です:

import numpy as np 
from astropy.modeling import models, fitting 
import matplotlib.pyplot as pl 

# data 
num = 100 
x, y = np.meshgrid(np.linspace(-5., 5., num), np.linspace(-5, 5, num)) 
e0 = models.Ellipse2D(amplitude=1., x_0=0.2, y_0=0.3, a=2, b=1, theta=0.4) 
z0 = e0(x, y) 
print 'DATA:\n', e0, '\n\n' 

# fitting procedure 
fi = fitting.SimplexLSQFitter() 
#fi = fitting.LevMarLSQFitter() 

# gaussian fit (to estimate x_0, y_0 and theta) 
gi = models.Gaussian2D(amplitude=1., x_mean=0.1, y_mean=0.2, x_stddev=1, y_stddev=1, theta=0.0) 
g1 = fi(gi, x, y, z0, maxiter=1000) 
print 'Gaussian:\n', g1, '\n\n' 

# initial model 
ei = models.Ellipse2D(amplitude=1., x_0=g1.x_mean, y_0=g1.y_mean, a=g1.x_stddev, b=g1.y_stddev, theta=g1.theta, fixed={'x_0': True, 'y_0':True, 'theta':True}) 

#fitted model 
e1 = fi(ei, x, y, z0, maxiter=1000) 
z1 = e1(x, y) 
print 'MODEL:\n', e1, '\n\n' 

pl.imshow(z0-z1, extent=[-5, 5, -5, 5]) 
pl.show() 
関連する問題