Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LAM-GRD-public
maoppy
Commits
e5bc3070
Commit
e5bc3070
authored
Sep 19, 2020
by
rfetick
Browse files
Dynamically defined Instruments as attributes
parent
3c9cc925
Changes
6
Hide whitespace changes
Inline
Side-by-side
maoppy/example/create_muse_psf.py
View file @
e5bc3070
...
...
@@ -13,16 +13,14 @@ import matplotlib.pyplot as plt
import
numpy
as
np
from
maoppy.psfmodel
import
Psfao
from
maoppy.instrument
import
load
from
maoppy.instrument
import
muse_nfm
Npix
=
128
# pixel size of PSF
wvl
=
600
*
1e-9
# wavelength [m]
MUSE_NFM
=
load
(
'muse_nfm'
)
#%% Initialize PSF model
samp
=
MUSE_NFM
.
samp
(
wvl
)
# sampling (2.0 for Shannon-Nyquist)
Pmodel
=
Psfao
((
Npix
,
Npix
),
system
=
MUSE_NFM
,
samp
=
samp
)
samp
=
muse_nfm
.
samp
(
wvl
)
# sampling (2.0 for Shannon-Nyquist)
Pmodel
=
Psfao
((
Npix
,
Npix
),
system
=
muse_nfm
,
samp
=
samp
)
#%% Choose parameters and compute PSF
r0
=
0.15
# Fried parameter [m]
...
...
maoppy/example/fit_muse_simulated_psf.py
View file @
e5bc3070
...
...
@@ -18,20 +18,18 @@ import matplotlib.pyplot as plt
import
numpy
as
np
from
maoppy.psfmodel
import
Psfao
,
psffit
,
rmserror
from
maoppy.instrument
import
load
MUSE_NFM
=
load
(
'muse_nfm'
)
from
maoppy.instrument
import
muse_nfm
npix
=
128
# pixel size of PSF
wvl
=
600
*
1e-9
# wavelength [m]
flux
=
1e5
ron
=
MUSE_NFM
.
ron
ron
=
muse_nfm
.
ron
bckgd
=
1.0
#%% Initialize PSF model
samp
=
MUSE_NFM
.
samp
(
wvl
)
# sampling (2.0 for Shannon-Nyquist)
Pmodel
=
Psfao
((
npix
,
npix
),
system
=
MUSE_NFM
,
samp
=
samp
)
samp
=
muse_nfm
.
samp
(
wvl
)
# sampling (2.0 for Shannon-Nyquist)
Pmodel
=
Psfao
((
npix
,
npix
),
system
=
muse_nfm
,
samp
=
samp
)
#%% Generate a MUSE-NFM PSF
r0
=
0.15
# Fried parameter [m]
...
...
@@ -54,7 +52,7 @@ guess = [0.145,2e-7,1.2,0.08,ratio,theta,1.5]
w
=
np
.
ones_like
(
image
)
/
ron
**
2.0
fixed
=
[
False
,
False
,
False
,
False
,
True
,
True
,
False
]
out
=
psffit
(
image
,
Psfao
,
guess
,
weights
=
w
,
system
=
MUSE_NFM
,
samp
=
samp
,
fixed
=
fixed
)
out
=
psffit
(
image
,
Psfao
,
guess
,
weights
=
w
,
system
=
muse_nfm
,
samp
=
samp
,
fixed
=
fixed
)
flux_fit
,
bck_fit
=
out
.
flux_bck
fitao
=
flux_fit
*
out
.
psf
+
bck_fit
...
...
maoppy/example/fit_muse_simulated_psf_small_fov.py
View file @
e5bc3070
...
...
@@ -8,7 +8,7 @@ Show the possibility of fitting a PSF with Psfao on a small field of view
and to retrieve the PSF shape on an increased field of view.
--------------
This script is a more complex version of 'fit_muse_simulated_psf.py'
The other one should be run first.
The other one should be run first
for better understanding
.
--------------
Generate an observation of a star with MUSE-NFM, at a given wavelength
...
...
@@ -26,20 +26,18 @@ from matplotlib.patches import Rectangle
import
numpy
as
np
from
maoppy.psfmodel
import
Psfao
,
psffit
,
rmserror
from
maoppy.instrument
import
load
MUSE_NFM
=
load
(
'muse_nfm'
)
from
maoppy.instrument
import
muse_nfm
npix
=
128
# pixel size of PSF
wvl
=
600
*
1e-9
# wavelength [m]
flux
=
1e6
ron
=
MUSE_NFM
.
ron
ron
=
muse_nfm
.
ron
bckgd
=
1.0
#%% Initialize PSF model
samp
=
MUSE_NFM
.
samp
(
wvl
)
# sampling (2.0 for Shannon-Nyquist)
Pmodel
=
Psfao
((
npix
,
npix
),
system
=
MUSE_NFM
,
samp
=
samp
)
samp
=
muse_nfm
.
samp
(
wvl
)
# sampling (2.0 for Shannon-Nyquist)
Pmodel
=
Psfao
((
npix
,
npix
),
system
=
muse_nfm
,
samp
=
samp
)
#%% Generate a MUSE-NFM PSF
r0
=
0.15
# Fried parameter [m]
...
...
@@ -68,7 +66,7 @@ w = np.ones_like(im_crop)/ron**2.0
fixed
=
[
False
,
False
,
False
,
False
,
True
,
True
,
False
]
out
=
psffit
(
im_crop
,
Psfao
,
guess
,
weights
=
w
,
fixed
=
fixed
,
npixfit
=
npix
,
# fit keywords
system
=
MUSE_NFM
,
samp
=
samp
)
# Psfao keywords
system
=
muse_nfm
,
samp
=
samp
)
# Psfao keywords
flux_fit
,
bck_fit
=
out
.
flux_bck
fitao
=
flux_fit
*
out
.
psf
+
bck_fit
...
...
maoppy/example/fit_zimpol_psf.py
View file @
e5bc3070
...
...
@@ -15,13 +15,11 @@ import numpy as np
from
maoppy.utils
import
imcenter
,
circavgplt
from
maoppy.psfmodel
import
psffit
,
Psfao
from
maoppy.instrument
import
load
ZIMPOL
=
load
(
'zimpol'
)
from
maoppy.instrument
import
zimpol
# %% PARAMETERS TO MODIFY
psf_path
=
"path/to/your/zimpol_psf.fits"
# set the path to your PSF *.fits file
filt
=
ZIMPOL
.
filters
[
"N_R"
]
# ZIMPOL filter
filt
=
zimpol
.
filters
[
"N_R"
]
# ZIMPOL filter
Npix
=
512
# size of PSF for fitting [pixels]. The larger the better
r0
=
0.18
# Fried parameter [m]
...
...
@@ -37,11 +35,11 @@ fitsPSF = fits.open(psf_path)
hdr
=
fitsPSF
[
0
].
header
psf
=
fitsPSF
[
0
].
data
psf
=
imcenter
(
psf
,
(
Npix
,
Npix
),
maxi
=
True
)
*
ZIMPOL
.
gain
psf
=
imcenter
(
psf
,
(
Npix
,
Npix
),
maxi
=
True
)
*
zimpol
.
gain
# %% FIT PSFAO model
wvl
=
filt
[
0
]
samp
=
ZIMPOL
.
samp
(
wvl
)
samp
=
zimpol
.
samp
(
wvl
)
x0
=
[
r0
,
moff_C
,
moff_A
,
moff_alpha
,
moff_ratio
,
moff_theta
,
moff_beta
]
fixed
=
[
False
,
False
,
False
,
False
,
True
,
True
,
False
]
...
...
@@ -49,7 +47,7 @@ fixed = [False,False,False,False,True,True,False]
weights
=
np
.
ones_like
(
psf
)
print
(
"PSFAO fitting (please wait)"
)
out
=
psffit
(
psf
,
Psfao
,
x0
,
weights
=
weights
,
system
=
ZIMPOL
,
samp
=
samp
,
fixed
=
fixed
)
out
=
psffit
(
psf
,
Psfao
,
x0
,
weights
=
weights
,
system
=
zimpol
,
samp
=
samp
,
fixed
=
fixed
)
out
.
x
[
5
]
=
out
.
x
[
5
]
%
np
.
pi
# make angle between 0 and PI
...
...
maoppy/instrument.py
View file @
e5bc3070
...
...
@@ -6,31 +6,34 @@ Created on Mon May 27 17:30:51 2019
@author: rfetick
"""
from
maoppy.utils
import
circarr
,
RAD2ARCSEC
import
yaml
import
os
from
astropy.io
import
fits
import
numpy
as
np
from
scipy.interpolate
import
interp2d
from
maoppy.utils
import
circarr
as
_circarr
from
maoppy.utils
import
RAD2ARCSEC
as
_RAD2ARCSEC
import
sys
as
_sys
import
yaml
as
_yaml
import
os
as
_os
from
astropy.io
import
fits
as
_fits
import
numpy
as
_np
from
scipy.interpolate
import
interp2d
as
_interp2d
def
_get_data_folder
():
folder
=
os
.
path
.
abspath
(
__file__
)
folder
=
os
.
sep
.
join
(
folder
.
split
(
os
.
sep
)[
0
:
-
1
])
+
os
.
sep
+
'data'
+
os
.
sep
folder
=
_
os
.
path
.
abspath
(
__file__
)
folder
=
_
os
.
sep
.
join
(
folder
.
split
(
_
os
.
sep
)[
0
:
-
1
])
+
_
os
.
sep
+
'data'
+
_
os
.
sep
return
folder
def
load
(
name
):
"""Load an instrument saved in the `data` folder of MAOPPY"""
folder
=
_get_data_folder
()
with
open
(
folder
+
name
.
lower
()
+
".yml"
,
'r'
)
as
f
:
d
=
yaml
.
full_load
(
f
)
instru
=
Instrument
(
D
=
d
[
'd'
],
occ
=
d
[
'occ'
],
res
=
d
[
'res'
],
gain
=
d
[
'gain'
],
ron
=
d
[
'ron'
],
Nact
=
d
[
'nact'
])
instru
.
name
=
d
[
'name'
]
instru
.
fullname
=
d
[
'fullname'
]
instru
.
filters
=
d
[
'filters'
]
instru
.
phasemask_path
=
d
[
'phasemask_path'
]
instru
.
phasemask_shift
=
d
[
'phasemask_shift'
]
return
instru
#
def load(name):
#
"""Load an instrument saved in the `data` folder of MAOPPY"""
#
folder = _get_data_folder()
#
with open(folder+name.lower()+".yml",'r') as f:
#
d =
_
yaml.full_load(f)
#
instru = Instrument(D=d['d'],occ=d['occ'],res=d['res'],gain=d['gain'],ron=d['ron'],Nact=d['nact'])
#
instru.name = d['name']
#
instru.fullname = d['fullname']
#
instru.filters = d['filters']
#
instru.phasemask_path = d['phasemask_path']
#
instru.phasemask_shift = d['phasemask_shift']
#
return instru
#%% INSTRUMENT CLASS
class
Instrument
(
object
):
...
...
@@ -106,25 +109,25 @@ class Instrument(object):
@
property
def
resolution_mas
(
self
):
return
self
.
resolution_rad
*
RAD2ARCSEC
*
1e3
return
self
.
resolution_rad
*
_
RAD2ARCSEC
*
1e3
def
pupil
(
self
,
Npix
,
wvl
=
None
,
samp
=
None
):
"""Returns the 2D array of the pupil transmission function (complex data)"""
Dpix
=
min
(
Npix
)
/
2
pup
=
circarr
(
Npix
)
pup
=
_
circarr
(
Npix
)
if
self
.
phasemask_enable
:
if
self
.
_phasemask
is
None
:
if
self
.
phasemask_path
is
None
:
raise
ValueError
(
'phasemask_path must be defined'
)
p
=
fits
.
open
(
self
.
phasemask_path
)[
0
].
data
*
1e-9
# fits data in nm, converted here to meter
x
=
np
.
arange
(
p
.
shape
[
0
])
/
p
.
shape
[
0
]
y
=
np
.
arange
(
p
.
shape
[
1
])
/
p
.
shape
[
1
]
self
.
_phasemask
=
interp2d
(
x
,
y
,
p
)
p
=
_
fits
.
open
(
self
.
phasemask_path
)[
0
].
data
*
1e-9
# fits data in nm, converted here to meter
x
=
_
np
.
arange
(
p
.
shape
[
0
])
/
p
.
shape
[
0
]
y
=
_
np
.
arange
(
p
.
shape
[
1
])
/
p
.
shape
[
1
]
self
.
_phasemask
=
_
interp2d
(
x
,
y
,
p
)
cx
,
cy
=
self
.
phasemask_shift
x
=
np
.
arange
(
Npix
[
0
])
/
Npix
[
0
]
-
cx
/
Npix
[
0
]
y
=
np
.
arange
(
Npix
[
1
])
/
Npix
[
1
]
-
cy
/
Npix
[
1
]
x
=
_
np
.
arange
(
Npix
[
0
])
/
Npix
[
0
]
-
cx
/
Npix
[
0
]
y
=
_
np
.
arange
(
Npix
[
1
])
/
Npix
[
1
]
-
cy
/
Npix
[
1
]
wf
=
self
.
_phasemask
(
x
,
y
)
if
wvl
is
None
:
wvl
=
self
.
wvl
(
samp
)
# samp must be defined if wvl is None
wf
=
np
.
exp
(
2j
*
np
.
pi
/
wvl
*
wf
)
wf
=
_
np
.
exp
(
2j
*
_
np
.
pi
/
wvl
*
wf
)
else
:
wf
=
1.0
+
0j
# complex type for output array, even if real data
return
(
pup
<
Dpix
)
*
(
pup
>=
Dpix
*
self
.
occ
)
*
wf
...
...
@@ -151,18 +154,23 @@ class Instrument(object):
data
[
'filters'
]
=
self
.
filters
data
[
'phasemask_path'
]
=
self
.
phasemask_path
data
[
'phasemask_shift'
]
=
self
.
phasemask_shift
with
open
(
filename
,
'w'
)
as
f
:
yaml
.
dump
(
data
,
f
)
with
open
(
filename
,
'w'
)
as
f
:
_yaml
.
dump
(
data
,
f
)
#%% OLD WAY to LOAD INSTRUMENTS (now use the `load` function)
#%% LOAD INSTRUMENT INSTANCES (make them attributes of this module)
_this_module
=
_sys
.
modules
[
__name__
]
_d
=
_get_data_folder
()
_l
=
[
_f
for
_f
in
_os
.
listdir
(
_d
)
if
_f
.
endswith
(
'.yml'
)]
for
_f
in
_l
:
with
open
(
_d
+
_f
,
'r'
)
as
_fi
:
_i
=
_yaml
.
full_load
(
_fi
)
_instru
=
Instrument
(
D
=
_i
[
'd'
],
occ
=
_i
[
'occ'
],
res
=
_i
[
'res'
],
gain
=
_i
[
'gain'
],
ron
=
_i
[
'ron'
],
Nact
=
_i
[
'nact'
])
_instru
.
name
=
_i
[
'name'
]
_instru
.
fullname
=
_i
[
'fullname'
]
_instru
.
filters
=
_i
[
'filters'
]
_instru
.
phasemask_path
=
_i
[
'phasemask_path'
]
_instru
.
phasemask_shift
=
_i
[
'phasemask_shift'
]
_n
=
_i
[
'name'
].
lower
().
replace
(
" "
,
"_"
)
# format name
setattr
(
_this_module
,
_n
,
_instru
)
del
_this_module
,
_d
,
_l
,
_f
,
_instru
,
_fi
,
_i
,
_n
#ZIMPOL = Instrument(D=8.,occ=0.14,res=30*1e-6/1768.,gain=10.5,ron=20.,Nact=40)
#ZIMPOL.filters["V"] = (554*1e-9, 80.6*1e-9)
#ZIMPOL.filters["N_R"] = (645.9*1e-9, 56.7*1e-9)
#ZIMPOL.name = "ZIMPOL"
#ZIMPOL.fullname = "VLT SPHERE/ZIMPOL"
#
#
#MUSE_NFM = Instrument(D=8.,occ=0.14,res=237.15*1e-6/1980.,gain=5.,ron=15.,Nact=39)
#MUSE_NFM.name = "MUSE_NFM"
#MUSE_NFM.fullname = "VLT MUSE (NFM)"
maoppy/test/test_psfmodel.py
View file @
e5bc3070
...
...
@@ -9,7 +9,7 @@ Created on Fri May 8 20:21:20 2020
import
unittest
import
numpy
as
np
from
maoppy.psfmodel
import
lsq_flux_bck
,
moffat
,
gauss
,
Psfao
from
maoppy.instrument
import
load
from
maoppy.instrument
import
zimpol
,
muse_nfm
class
TestLsqFluxBck
(
unittest
.
TestCase
):
def
test_fluxbck
(
self
):
...
...
@@ -55,7 +55,7 @@ class TestPsfao(unittest.TestCase):
def
test_oversampling
(
self
):
npix
=
100
samp
=
0.3
P
=
Psfao
((
npix
,
npix
),
system
=
load
(
'
muse_nfm
'
)
,
samp
=
samp
)
P
=
Psfao
((
npix
,
npix
),
system
=
muse_nfm
,
samp
=
samp
)
self
.
assertEqual
(
samp
,
P
.
samp
)
self
.
assertGreaterEqual
(
P
.
_samp_over
,
2.0
)
self
.
assertEqual
(
P
.
_k
%
1
,
0
)
...
...
@@ -63,14 +63,14 @@ class TestPsfao(unittest.TestCase):
def
test_bounds_length
(
self
):
npix
=
100
samp
=
0.3
P
=
Psfao
((
npix
,
npix
),
system
=
load
(
'
muse_nfm
'
)
,
samp
=
samp
)
P
=
Psfao
((
npix
,
npix
),
system
=
muse_nfm
,
samp
=
samp
)
self
.
assertEqual
(
len
(
P
.
bounds
[
0
]),
7
)
self
.
assertEqual
(
len
(
P
.
bounds
[
1
]),
7
)
def
test_psd_integral
(
self
):
npix
=
1024
samp
=
2.0
P
=
Psfao
((
npix
,
npix
),
system
=
load
(
'
zimpol
'
)
,
samp
=
samp
)
P
=
Psfao
((
npix
,
npix
),
system
=
zimpol
,
samp
=
samp
)
fao
=
P
.
system
.
Nact
/
(
2.0
*
P
.
system
.
D
)
df
=
1.0
/
(
P
.
system
.
D
*
P
.
_samp_over
)
...
...
@@ -104,7 +104,7 @@ class TestPsfao(unittest.TestCase):
def
test_otf_max
(
self
):
npix
=
1024
samp
=
2.0
P
=
Psfao
((
npix
,
npix
),
system
=
load
(
'
zimpol
'
)
,
samp
=
samp
)
P
=
Psfao
((
npix
,
npix
),
system
=
zimpol
,
samp
=
samp
)
r0
=
0.25
C
=
1e-4
A
=
1.0
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment