Check that it has the central wavelength z_central taken from the fits header,
which determines the right velocity ‘step’ (cdelt3 in km/s). If the header is not correct, you have
several options to set the central wavelength with z_central or cdelt3 or cunit3.

Check that the LSF and PSF parameters are ok - see below for how to tweak them.

Run with :

gk.run_mcmc()

Save everything with :

gk.save('my_output')

and check again that the 3D kernel gk.psf3d is correct !
A wrong kernel will lead to unphysical results.

Again, you can see the detaileddocumentationfortheavailableparameters,
but the most important parameters to tune are :

random_scale : a scale factor to the width of the proposal distribution (Cauchy).
A good practice is to tune this to have an acceptance rate of 30-50 %.
(for example, the value random_scale=2 sets a factor 2x from the defaults)

max_iterations : max number of (accepted) iterations [default=10000]

method:‘last’ or ‘chi_sorted’ or ‘chi_min’

Method used to determine the best parameters from the chain.

‘last’ (default) : mean of the last_chain_fraction(%) last parameters of the chain

‘chi_sorted’ : mean of the last_chain_fraction(%) best fit parameters of the chain

‘chi_min’ : mean of last_chain_fraction(%) of the chain around the min chi

last_chain_fraction : last fraction of chain (in %) to use to determine the best parameters [default=60]

You can (and should) tweak the random_scale parameter of the run_mcmc method
in order to get an acceptance rate around 30-40 %.
The value you provide is the a coefficient (default=1)
applied to the random walk of the parameters.

A bad chain, poorly scaled

But when you provide a random_scale with values greater than 1, say 5 :

Once a deconvolution has been computed, you can plot the resulting cubes :

fromgalpakimportGalPaK3Dglpk3d=GalPaK3D('my_muse_cube.fits')galaxy=glpk3d.run_mcmc()# Show plot on-screengalpak.plot_images()# Save plot to png or jpg filegalpak.plot_images(filepath='my_plot.png')# Crop the rendered cubes along z, around the galaxy's zgalpak.plot_images(z_crop=7)

Only the rest-wavelengths are needed regardless of redshift because the algorithm works in velocity space. Here, you specify the velocity difference for the two lines in the doublet, 3e5*(l2-l1)/(l1+l2)*2, so the redshift does not matter.

Warning

For version >= 1.9.0, this line parameter is now part of the DiskModel class.

You can either specify the seeing parameter as in the example above,
or change its attributes from the Instrument parameters :

fromgalpakimportGalPaK3D,SINFOK250,GaussianPointSpreadFunction# this one-linermy_instrument=SINFOK250(psf=GaussianPointSpreadFunction(fwhm=0.7,pa=0.1,ba=0.9))# is equivalent tomy_instrument=SINFOK250()my_instrument.psf.fwhm=1.5my_instrument.psf.pa=0.1my_instrument.psf.ba=0.9# and, as the gaussian PSF is the default, you can also fast-tweak it this waymy_instrument=SINFOK250(psf_fwhm=0.7,pa=0.1,ba=0.9)# then, whatever way you used to create your instrument, use it like thisglpk3d=GalPaK3D('my_sinfok250_cube.fits',instrument=my_instrument)galaxy=glpk3d.run_mcmc()

fromgalpakimportGalPaK3D,SINFOK250,NoPointSpreadFunctionglpk3d=GalPaK3D('my_sinfok250_cube.fits',instrument=SINFOK250())glpk3d.instrument.psf=Nonegalaxy=glpk3d.run_mcmc()# ... is the same asglpk3d=GalPaK3D('my_sinfok250_cube.fits',instrument=SINFOK250())glpk3d.instrument.psf=NoPointSpreadFunction()galaxy=glpk3d.run_mcmc()

You can create your own PSF, it just needs to implement PointSpreadFunction.

A good example of this is the NoPointSpreadFunction class :

fromgalpakimportPointSpreadFunctionclassNoPointSpreadFunction(PointSpreadFunction):""" A spread function that does not spread anything, and will leave the cube unchanged. Passing this class to the instrument's psf is the same as passing None. """def__init__(self):passdefas_image(self,for_cube):""" Return the identity PSF, chock-full of zeros. """# Here, you may create your own 2D PSF image and then return itshape=for_cube.shape[1:]returnnp.zeros(shape)

You can also create your own instrument, by extending galpak.Instrument.
You can override the calibrate and convolve methods :

fromgalpakimportInstrumentclassMyInstrument(Instrument):# This callback is called by GalPaK3D during its initdefcalibrate(self,cube):""" The cube is a HyperspectralCube, and it has additional attributes provided by GalPaK3D : - xy_step (in ") - z_step (in µm) - z_central (in µm) """# <Your logic here># Important : run the default calibration in the endInstrument.calibrate(self,cube)# Optionally, you may override the convolution method# By default it applies the PSF3D, see Instrument implementationdefconvolve(self,cube):""" Convolve the provided data cube. Should transform the input cube and return it, it is faster than copying. """# <convolve the cube>returncube

Note

If you do create your own instrument, please consider making a pull request !