| galpak3d.py | galpak3d.py | |||
|---|---|---|---|---|
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | |||
| from __future__ import absolute_import | from __future__ import absolute_import | |||
| from __future__ import division | from __future__ import division | |||
| from __future__ import print_function | from __future__ import print_function | |||
| from distutils.version import LooseVersion, StrictVersion | ||||
| import pkg_resources | ||||
| import os,re | import os | |||
| import sys | import sys | |||
| from copy import deepcopy | from copy import deepcopy | |||
| import configparser | import configparser | |||
| from astropy.io.fits import Header | from astropy.io.fits import Header | |||
| import astropy.io.ascii as asciitable | import astropy.io.ascii as asciitable | |||
| from astropy.table import Table, Column | from astropy.table import Table, Column | |||
| import math | import math | |||
| import numpy as np | import numpy as np | |||
| np.random.seed(seed=1234) | np.random.seed(seed=1234) | |||
| # LOCAL IMPORTS | # LOCAL IMPORTS | |||
| from .__version__ import __version__ | from .__version__ import __version__ | |||
| from .math_utils import merge_where_nan, median_clip, safe_exp | from .math_utils import merge_where_nan, median_clip | |||
| from .instruments import * | from .instruments import Instrument, _read_instrument, MUSE, MUSEWFM, MUSEN FM, ALMA, SINFOK250, SINFOK100, SINFOJ250, SINFOJ100, HARMONI, KMOS, OSIRIS , Generic | |||
| from .hyperspectral_cube import HyperspectralCube as HyperCube | from .hyperspectral_cube import HyperspectralCube as HyperCube | |||
| from .string_stdout import StringStdOut | from .string_stdout import StringStdOut | |||
| from .model_class import Model | from .model_class import Model | |||
| from .model_sersic3d import ModelSersic | from .model_sersic3d import ModelSersic | |||
| from .galaxy_parameters import GalaxyParameters, GalaxyParametersError | from .galaxy_parameters import GalaxyParameters, GalaxyParametersError | |||
| from .plot_utilities import Plots | from .plot_utilities import Plots | |||
| from .mcmc import MCMC | from .mcmc import MCMC | |||
| from .galpak3d_utils import _save_to_file,_read_file, _read_instrument, _re ad_model | from .galpak3d_utils import _save_to_file, _read_model | |||
| #will be removed | #will be removed | |||
| DiskModel = ModelSersic #for backward compatibility | DiskModel = ModelSersic #for backward compatibility | |||
| DefaultModel = ModelSersic | DefaultModel = ModelSersic | |||
| OII = {'wave': [3726.2, 3728.9], 'ratio':[0.8,1.0]} | OII = {'wave': [3726.2, 3728.9], 'ratio':[0.8,1.0]} | |||
| # LOGGING CONFIGURATION | # LOGGING CONFIGURATION | |||
| import logging | import logging | |||
| logging.basicConfig(level=logging.INFO) | logging.basicConfig(level=logging.INFO) | |||
| logger = logging.getLogger('GalPaK') | ||||
| try: | ||||
| from distutils.version import LooseVersion as Version | ||||
| except ImportError: | ||||
| # python3.13 | ||||
| from packaging.version import Version | ||||
| # OPTIONAL IMPORTS | # OPTIONAL IMPORTS | |||
| try: | try: | |||
| import bottleneck as bn | import bottleneck as bn | |||
| except ImportError: | except ImportError: | |||
| logger.info(" bottleneck (optional) not installed, performances will be degraded") | logging.info(" bottleneck (optional) not installed, performances will b e degraded") | |||
| import numpy as bn | import numpy as bn | |||
| try: | try: | |||
| import pyfftw | import pyfftw | |||
| except ImportError: | except ImportError: | |||
| logger.info(" PyFFTW (optional) not installed, performances will be deg raded") | logging.info(" PyFFTW (optional) not installed, performances will be de graded") | |||
| try: | try: | |||
| import mpdaf | import mpdaf | |||
| logger.info("Found MPDAF version %s" % (mpdaf.__version__)) | logging.info("Found MPDAF version %s" % (mpdaf.__version__)) | |||
| mpdaf_there=True | mpdaf_there=True | |||
| except ImportError: | except ImportError: | |||
| mpdaf_there=False | mpdaf_there=False | |||
| logger.warning(" MPDAF (optional) not installed / not required") | logging.warning(" MPDAF (optional) not installed / not required") | |||
| try: | try: | |||
| import emcee | import emcee | |||
| emcee_there=True | emcee_there=True | |||
| logger.info("Found EMCEE version %s" % (emcee.__version__)) | logging.info("Found EMCEE version %s" % (emcee.__version__)) | |||
| logger.warning("EMCEE tested for version > 3.0") | logging.warning("EMCEE tested for version > 3.0") | |||
| except ImportError: | except ImportError: | |||
| emcee_there=False | emcee_there=False | |||
| logger.warning(" EMCEE (optional) not installed / not required. So opti on use_emcee is disabled") | logging.warning(" EMCEE (optional) not installed / not required. So opt ion use_emcee is disabled") | |||
| try: | try: | |||
| import dynesty | import dynesty | |||
| dynesty_there=True | dynesty_there=True | |||
| logger.info("Found Dynesty version %s \n EXPERIMENTAL and UNSUPPORTED" % (dynesty.__version__)) | logging.info("Found Dynesty version %s \n EXPERIMENTAL and UNSUPPORTED" % (dynesty.__version__)) | |||
| except ImportError: | except ImportError: | |||
| dynesty_there=False | dynesty_there=False | |||
| logger.warning(" Dynesty (optional) not installed / not required. ") | logging.warning(" Dynesty (optional) not installed / not required. ") | |||
| try: | try: | |||
| import pymultinest | import pymultinest | |||
| multinest_there=True | multinest_there=True | |||
| logger.info("Found PyMultinest version %s" % (pkg_resources.get_distrib ution("pymultinest").version)) | logging.info("Found PyMultinest version %s" % (importlib.metadata.versi on("pymultinest"))) | |||
| except ImportError: | except ImportError: | |||
| multinest_there=False | multinest_there=False | |||
| logger.warning(" PyMultinest (optional) not installed / not required. " ) | logging.warning(" PyMultinest (optional) not installed / not required. ") | |||
| try: | try: | |||
| import corner | import corner | |||
| except ImportError: | except ImportError: | |||
| logger.info("corner (optional) not installed, corner plots will be disa bled") | logging.info("corner (optional) not installed, corner plots will be dis abled") | |||
| #Python3 compatibility | #Python3 compatibility | |||
| try: | try: | |||
| basestring | basestring | |||
| except NameError: | except NameError: | |||
| basestring = str | basestring = str | |||
| if sys.version>=LooseVersion('2.7') and sys.version<LooseVersion('3.5'): | from importlib import reload # Python 3.4+ | |||
| reload(sys) | ||||
| sys.setdefaultencoding('utf-8') | #reload(sys) | |||
| #sys.setdefaultencoding('utf-8') | ||||
| class GalPaK3D(Plots, MCMC): | class GalPaK3D(Plots, MCMC): | |||
| """ | """ | |||
| GalPaK3D is a tool to extract Galaxy Parameters and Kinematics from | GalPaK3D is a tool to extract Galaxy Parameters and Kinematics from | |||
| 3-Dimensional data, using reverse deconvolution with Bayesian analysis | 3-Dimensional data, using reverse deconvolution with Bayesian analysis | |||
| Markov Chain Monte Carlo. (random walk) | Markov Chain Monte Carlo. (random walk) | |||
| cube: HyperspectralCube|string | cube: HyperspectralCube|string | |||
| The actual data on which we'll work ; it should contain only one ga laxy. | The actual data on which we'll work ; it should contain only one ga laxy. | |||
| Can be a HyperspectralCube object, a string filename to a FITS file , or | Can be a HyperspectralCube object, a string filename to a FITS file , or | |||
| skipping to change at line 141 | skipping to change at line 144 | |||
| You should update your cube's header. | You should update your cube's header. | |||
| cunit1: float | cunit1: float | |||
| A value for the cube's header's CUNIT1 (&2) when it is missing. | A value for the cube's header's CUNIT1 (&2) when it is missing. | |||
| You should update your cube's header. | You should update your cube's header. | |||
| force_header_update: bool | force_header_update: bool | |||
| Set to True to force the update of the above header cards, | Set to True to force the update of the above header cards, | |||
| when their values are not missing. | when their values are not missing. | |||
| Note: These will not be saved into the FITS file. (if the cube is o ne) | Note: These will not be saved into the FITS file. (if the cube is o ne) | |||
| """ | """ | |||
| logger = logging.getLogger('GalPaK') | ||||
| logger.info(' Running galpak ' + __version__) | logger.info(' Running galpak ' + __version__) | |||
| def __init__(self, cube, variance=None, model=None, | def __init__(self, cube, variance=None, model=None, | |||
| seeing=None, instrument=None, quiet=False, | seeing=None, instrument=None, quiet=False, | |||
| crval3=None, crpix3=None, cunit3=None, cdelt3=None, ctype3 =None, cunit1=None, | crval3=None, crpix3=None, cunit3=None, cdelt3=None, ctype3 =None, cunit1=None, | |||
| force_header_update=False): | force_header_update=False): | |||
| # DEVS : If you change the signature above, | # DEVS : If you change the signature above, | |||
| # remember to update the run() in api.py | # remember to update the run() in api.py | |||
| skipping to change at line 198 | skipping to change at line 202 | |||
| self.chi_at_p = None | self.chi_at_p = None | |||
| self.best_chisq = None | self.best_chisq = None | |||
| self.stats = None | self.stats = None | |||
| self.BIC = None | self.BIC = None | |||
| self.DIC = None | self.DIC = None | |||
| self.mcmc_method = None | self.mcmc_method = None | |||
| self.mcmc_sampling = None | self.mcmc_sampling = None | |||
| #self.redshift = None | #self.redshift = None | |||
| # Assign the logger to a property for convenience, and set verbosit y | # Assign the logger to a property for convenience, and set verbosit y | |||
| self.logger = logger | ||||
| self.version = __version__ | self.version = __version__ | |||
| self.config = configparser.RawConfigParser() | self.config = configparser.RawConfigParser() | |||
| self.model = None | self.model = None | |||
| if quiet: | if quiet: | |||
| self._set_verbose(None) | self._set_verbose(None) | |||
| self.verbose=None | self.verbose=None | |||
| else: | else: | |||
| self._set_verbose(True) | self._set_verbose(True) | |||
| skipping to change at line 293 | skipping to change at line 296 | |||
| cdelt3=cdelt3, ctype3=ctype3, cunit1=cunit1, force=force_he ader_update | cdelt3=cdelt3, ctype3=ctype3, cunit1=cunit1, force=force_he ader_update | |||
| ) | ) | |||
| except ValueError: | except ValueError: | |||
| raise ValueError("The cube already has one of the header cards " | raise ValueError("The cube already has one of the header cards " | |||
| "you're trying to provide. " | "you're trying to provide. " | |||
| "Use force_header_update=True to override.") | "Use force_header_update=True to override.") | |||
| self.logger.debug('Header after patch : %s' % self.cube) | self.logger.debug('Header after patch : %s' % self.cube) | |||
| #set xy_step z_step and z_central | #set xy_step z_step and z_central | |||
| # 2. Set cube metadata from the the instrument if header is incompl ete | # 2. Set cube metadata from the instrument if header is incomplete | |||
| self.cube.defaults_from_instrument(instrument=instrument) | self.cube.defaults_from_instrument(instrument=instrument) | |||
| # 3. Initialize steps xy_steps z_steps z_cunnit and z_central | # 3. Initialize steps xy_steps z_steps z_cunnit and z_central | |||
| self.cube.initialize_self_cube() | self.cube.initialize_self_cube() | |||
| # 4. Calibrate the instrument with the cube | # 4. Calibrate the instrument with the cube | |||
| self.instrument.use_pixelsize_from_cube(self.cube) | self.instrument.use_pixelsize_from_cube(self.cube) | |||
| self.logger.debug('z central : %4.e' % (self.cube.z_central) ) | self.logger.debug('z central : %4.e' % (self.cube.z_central) ) | |||
| skipping to change at line 349 | skipping to change at line 352 | |||
| # Set up the model context | # Set up the model context | |||
| # Set up the model context | # Set up the model context | |||
| if isinstance(model, basestring)==True: | if isinstance(model, basestring)==True: | |||
| model = _read_model(deepcopy(model)) | model = _read_model(deepcopy(model)) | |||
| if model is not None: | if model is not None: | |||
| self._init_model(model) | self._init_model(model) | |||
| self.logger.info("Setting up the model : %s" % (self.model.__na me__())) | self.logger.info("Setting up the model : %s" % (self.model.__na me__())) | |||
| self.logger.info("Model setup :\n%s" % (self.model) ) | self.logger.info("Model setup :\n%s" % (self.model) ) | |||
| def _init_model(self, model): | def _init_model(self, model): | |||
| # Set up the simulation model | # Set up the simulation model | |||
| if model is not None: | if model is not None: | |||
| self.model = model | self.model = model | |||
| self.logger.info("Init boundaries from model '%s'" %(self.model .__name__())) | self.logger.info("Init boundaries from model '%s'" %(self.model .__name__())) | |||
| self.model_dict = self.model.__dict__ | self.model_dict = self.model.__dict__ | |||
| #important: | #important: | |||
| self.model.pixscale = self.cube.xy_step | self.model.pixscale = self.cube.xy_step | |||
| # Compute a flux estimation | # Compute a flux estimation | |||
| skipping to change at line 396 | skipping to change at line 398 | |||
| last_chain_fraction=60, | last_chain_fraction=60, | |||
| percentile=95, | percentile=95, | |||
| model=None, | model=None, | |||
| chi_stat='gaussian', | chi_stat='gaussian', | |||
| mcmc_method='galpak', | mcmc_method='galpak', | |||
| mcmc_sampling=None, | mcmc_sampling=None, | |||
| min_boundaries=None, | min_boundaries=None, | |||
| max_boundaries=None, | max_boundaries=None, | |||
| known_parameters=None, | known_parameters=None, | |||
| initial_parameters=None, | initial_parameters=None, | |||
| gprior_parameters=None, | ||||
| random_scale=None, | random_scale=None, | |||
| min_acceptance_rate=10, | min_acceptance_rate=10, | |||
| verbose=True, | verbose=True, | |||
| emcee_nwalkers=30, | emcee_nwalkers=30, | |||
| **kwargs): | **kwargs): | |||
| # DEVS : If you change the signature above, | # DEVS : If you change the signature above, | |||
| # remember to update the run() in api.py | # remember to update the run() in api.py | |||
| """ | """ | |||
| Main method_chain of GalPak, computes and returns the galaxy parame ters | Main method_chain of GalPak, computes and returns the galaxy parame ters | |||
| as a :class:`GalaxyParameters <galpak.GalaxyParameters>` object | as a :class:`GalaxyParameters <galpak.GalaxyParameters>` object | |||
| skipping to change at line 485 | skipping to change at line 488 | |||
| max_boundaries: ndarray|GalaxyParameters | max_boundaries: ndarray|GalaxyParameters | |||
| The galaxy parameters will never be more than these values. | The galaxy parameters will never be more than these values. | |||
| Will override the default minimum boundaries for the parameters . | Will override the default minimum boundaries for the parameters . | |||
| If any of these values are NaN, they will be replaced by the de fault ones. | If any of these values are NaN, they will be replaced by the de fault ones. | |||
| known_parameters: ndarray|GalaxyParameters | known_parameters: ndarray|GalaxyParameters | |||
| All set parameters in this array will be skipped in the MCMC, | All set parameters in this array will be skipped in the MCMC, | |||
| the algorithm will not try to guess them. | the algorithm will not try to guess them. | |||
| initial_parameters: ndarray|GalaxyParameters | gprior_parameters: ndarray | [2x GalaxyParameters] | |||
| Gaussian prior parameters | ||||
| the algorithm will not try to guess them. | ||||
| initial_parameters: ndarray|ModelParameters | ||||
| The initial galaxy parameters of the MCMC chain. | The initial galaxy parameters of the MCMC chain. | |||
| If None, will use the inital parameters provided by the model. | If None, will use the inital parameters provided by the model. | |||
| The galaxy parameters not initialized by the model or by this | The galaxy parameters not initialized by the model or by this | |||
| parameter will be set to the mean of the boundaries. | parameter will be set to the mean of the boundaries. | |||
| random_scale: float | random_scale: float | |||
| Scale the amplitude of the MCMC sampling by these values. | Scale the amplitude of the MCMC sampling by these values. | |||
| This is an important parameter to adjust for reasonable accepta nce rate. | This is an important parameter to adjust for reasonable accepta nce rate. | |||
| The acceptance rate should be around 30-50%. | The acceptance rate should be around 30-50%. | |||
| If the acceptance rate is <20-30% (too low), decrease random_sc ale | If the acceptance rate is <20-30% (too low), decrease random_sc ale | |||
| skipping to change at line 615 | skipping to change at line 622 | |||
| # Merge provided initial parameters (if any) with the defaults | # Merge provided initial parameters (if any) with the defaults | |||
| if initial_parameters is not None: | if initial_parameters is not None: | |||
| #complete input with default values | #complete input with default values | |||
| template = self.model.Parameters() | template = self.model.Parameters() | |||
| merge_where_nan(template, initial_parameters) | merge_where_nan(template, initial_parameters) | |||
| merge_where_nan(template, self.initial_parameters) | merge_where_nan(template, self.initial_parameters) | |||
| self.initial_parameters = template | self.initial_parameters = template | |||
| self.logger.info("Initial parameters : %s", self.initial_parameters ) | self.logger.info("Initial parameters : %s", self.initial_parameters ) | |||
| if gprior_parameters is not None: | ||||
| if isinstance(gprior_parameters, np.ndarray) and gprior_paramet | ||||
| ers.shape[0] !=2: | ||||
| self.logger.error("gprior parameter should be an array of s | ||||
| hape 2xNparam ") | ||||
| if isinstance(gprior_parameters, list) and len(gprior_parameter | ||||
| s)!=2: | ||||
| self.logger.error("gprior parameter should be a list of 2 P | ||||
| arameters ") | ||||
| template_mu = self.model.Parameters() | ||||
| template_sig= self.model.Parameters() | ||||
| merge_where_nan(template_mu, gprior_parameters[0]) | ||||
| merge_where_nan(template_sig, gprior_parameters[1]) | ||||
| gprior_parameters = np.array([template_mu, template_sig]) | ||||
| self.gprior_parameters = gprior_parameters | ||||
| # By default, try to guess all parameters | # By default, try to guess all parameters | |||
| should_guess_flags = np.ones(dim_p) # 0: we know it / 1: try to gu ess | should_guess_flags = np.ones(dim_p) # 0: we know it / 1: try to gu ess | |||
| #if using input image | #if using input image | |||
| # @fixme; this is unused | # @fixme; this is unused | |||
| if self.model_dict['flux_profile'] == 'user' and known_parameters i s None: | if self.model_dict['flux_profile'] == 'user' and known_parameters i s None: | |||
| raise self.logger.error( | raise self.logger.error( | |||
| "With an input image it is advised to freeze " | "With an input image it is advised to freeze " | |||
| "the `inclination`, using `known_parameters=`.") | "the `inclination`, using `known_parameters=`.") | |||
| skipping to change at line 711 | skipping to change at line 730 | |||
| 'tune': True, \ | 'tune': True, \ | |||
| 'thin': 30 | 'thin': 30 | |||
| } | } | |||
| #update default parameters | #update default parameters | |||
| kwargs_emcee.update(kwargs) | kwargs_emcee.update(kwargs) | |||
| #@fixme: need to accept parallelize | #@fixme: need to accept parallelize | |||
| pos0 = np.array([self.initial_parameters * (1+1e-3*np.random.ra ndn(dim_p)) for i in range(emcee_nwalkers) ]) | pos0 = np.array([self.initial_parameters * (1+1e-3*np.random.ra ndn(dim_p)) for i in range(emcee_nwalkers) ]) | |||
| self.logger.critical("Running EMCEE with %d walkers on %d itera tions" % (emcee_nwalkers, self.max_iterations)) | self.logger.critical("Running EMCEE with %d walkers on %d itera tions" % (emcee_nwalkers, self.max_iterations)) | |||
| if LooseVersion(emcee.__version__)<LooseVersion('3.0'): | if Version(emcee.__version__)<Version('3.0'): | |||
| raise Exception("EMCEE version not supported ", emcee.__ver sion__) | raise Exception("EMCEE version not supported ", emcee.__ver sion__) | |||
| #EMCE version3 | #EMCE version3 | |||
| if mcmc_sampling == 'Cauchy': | if mcmc_sampling == 'Cauchy': | |||
| from .mcmc import CauchyMove | from .mcmc import CauchyMove | |||
| myMove=CauchyMove(self.random_amplitude.as_vector()**2) | myMove=CauchyMove(self.random_amplitude.as_vector()**2) | |||
| self.logger.critical("Running EMCEE Walkers with Cauchy Sam pling") | self.logger.critical("Running EMCEE Walkers with Cauchy Sam pling") | |||
| elif mcmc_sampling == 'Normal': | elif mcmc_sampling == 'Normal': | |||
| from emcee.moves import GaussianMove | from emcee.moves import GaussianMove | |||
| myMove=GaussianMove(self.random_amplitude.as_vector()**2) | myMove=GaussianMove(self.random_amplitude.as_vector()**2) | |||
| skipping to change at line 823 | skipping to change at line 842 | |||
| seed=-1, verbose=False, resume=True, context=0, write_outpu t=True, | seed=-1, verbose=False, resume=True, context=0, write_outpu t=True, | |||
| log_zero=-1e+100, max_iter=0, init_MPI=True, dump_callback= None) | log_zero=-1e+100, max_iter=0, init_MPI=True, dump_callback= None) | |||
| """ | """ | |||
| if 'outpath' not in kwargs.keys(): | if 'outpath' not in kwargs.keys(): | |||
| outpath = './pymulti' | outpath = './pymulti' | |||
| if os.path.isdir(outpath) is False: | if os.path.isdir(outpath) is False: | |||
| os.mkdir(outpath) | os.mkdir(outpath) | |||
| output = outpath + '/out' | output = outpath + '/out' | |||
| else: | else: | |||
| output = kwargs['outpath'] | outpath = kwargs['outpath'] | |||
| if os.path.isdir(outpath) is False: | ||||
| os.mkdir(outpath) | ||||
| output = outpath + '/out' | ||||
| kwargs.pop('outpath') | kwargs.pop('outpath') | |||
| #default parameters | #default parameters | |||
| kwargs_multi={'n_live_points': 200, \ | kwargs_multi={'n_live_points': 200, \ | |||
| 'evidence_tolerance':0.5, \ | 'evidence_tolerance':0.5, \ | |||
| 'n_iter_before_update' : 200, \ | 'n_iter_before_update' : 200, \ | |||
| 'const_efficiency_mode' : False, \ | 'const_efficiency_mode' : False, \ | |||
| 'sampling_efficiency':0.8, \ | 'sampling_efficiency':0.8, \ | |||
| 'resume' : False} | 'resume' : False} | |||
| kwargs_multi.update(kwargs) | kwargs_multi.update(kwargs) | |||
| skipping to change at line 881 | skipping to change at line 903 | |||
| #bestfit_params = stats['modes'][0]['mean'] | #bestfit_params = stats['modes'][0]['mean'] | |||
| #bestfit_params = stats['modes'][0]['maximum'] | #bestfit_params = stats['modes'][0]['maximum'] | |||
| #bestfit_params = stats['modes'][0]['maximum a posterior'] | #bestfit_params = stats['modes'][0]['maximum a posterior'] | |||
| #OR | #OR | |||
| #bestfit_params = stats.get_best_fit()['parameters'] | #bestfit_params = stats.get_best_fit()['parameters'] | |||
| self.sampler = dict(samples = samples, stats=stats, \ | self.sampler = dict(samples = samples, stats=stats, \ | |||
| kwargs=kwargs_multi | kwargs=kwargs_multi | |||
| ) | ) | |||
| #clean | ||||
| os.system('rm -rf {}/'.format(outpath)) | ||||
| elif mcmc_method == 'pymc3': | elif mcmc_method == 'pymc3': | |||
| raise NotImplementedError | raise NotImplementedError | |||
| elif mcmc_method == 'pynuts': | elif mcmc_method == 'pynuts': | |||
| raise NotImplementedError | raise NotImplementedError | |||
| else: | else: | |||
| raise Exception("method_mcmc %s not valid. Used of of %s" % (mc mc_method, self.MCMC_VALID)) | raise Exception("method_mcmc %s not valid. Used of of %s" % (mc mc_method, self.MCMC_VALID)) | |||
| # Store chain | # Store chain | |||
| self.logger.info("self.chain : full Markov chain") | self.logger.info("self.chain : full Markov chain") | |||
| skipping to change at line 1152 | skipping to change at line 1177 | |||
| good[snr<snr_min] = 0 | good[snr<snr_min] = 0 | |||
| dim_good = good.sum() #count only pixels with snr >snr_min and abov e | dim_good = good.sum() #count only pixels with snr >snr_min and abov e | |||
| Nd_good = (dim_good - self.dim_p_free - 1) # degree of freedom | Nd_good = (dim_good - self.dim_p_free - 1) # degree of freedom | |||
| # like = -0.5*np.nansum(self.variance_chi)-0.5*self.compute_chi(par ams) | # like = -0.5*np.nansum(self.variance_chi)-0.5*self.compute_chi(par ams) | |||
| #BIC = -2 * like(theta) | #BIC = -2 * like(theta) | |||
| self.BIC = self.chi_at_p * self.Ndegree + self.dim_p_free * np.log( dim_data) | self.BIC = self.chi_at_p * self.Ndegree + self.dim_p_free * np.log( dim_data) | |||
| #AIC = -2 * like + 2 dim_p | #AIC = -2 * like + 2 dim_p | |||
| self.AIC = self.chi_at_p * self.Ndegree + 2* self.dim_p_free | self.AIC = self.chi_at_p * self.Ndegree + 2 * self.dim_p_free | |||
| #DIC | #DIC | |||
| if self.method != 'chi_sorted': | if self.method != 'chi_sorted': | |||
| log_Lp = -0.5 * self.sub_chain['reduced_chi'] * self.Ndegree | log_Lp = -0.5 * self.sub_chain['reduced_chi'] * self.Ndegree | |||
| if np.isfinite(log_Lp).all(): | if np.isfinite(log_Lp).all(): | |||
| pD = 2 * np.var(log_Lp) | pD = 2 * np.var(log_Lp) | |||
| else: | else: | |||
| pD = 2 * np.nanvar(log_Lp[np.isfinite(log_Lp)==True]) | pD = 2 * np.nanvar(log_Lp[np.isfinite(log_Lp)==True]) | |||
| # P = 2 * (logp_max-np.mean(self.lnp)) | # P = 2 * (logp_max-np.mean(self.lnp)) | |||
| #pD = 2 * -0.5 * (self.chi_at_p - np.mean(self.sub_chain['reduc ed_chi'])) * self.Ndegree | #pD = 2 * -0.5 * (self.chi_at_p - np.mean(self.sub_chain['reduc ed_chi'])) * self.Ndegree | |||
| #DIC = -2 * like + 2 pd | #DIC = -2 * like + 2 pd | |||
| self.DIC = self.chi_at_p * self.Ndegree + 2 * pD | self.DIC = self.chi_at_p * self.Ndegree + 2 * pD | |||
| else: | else: | |||
| self.DIC = 0 | self.DIC = 0 | |||
| pD=0 | pD=0 | |||
| self.stats = Table(np.array(['%.8f' % (self.best_chisq), '%.8f' % ( self.chi_at_p), | self.stats = Table(np.array(['%.8f' % (self.best_chisq), '%.8f' % ( self.chi_at_p), | |||
| int(self.BIC), self.Ndegree, | '%.2f' % (self.BIC), self.Ndegree, | |||
| int(self.AIC), self.dim_p_free, | '%.2f' % (self.AIC), self.dim_p_free, | |||
| '%.2f' % (pD), int(self.DIC), | '%.2f' % (pD), | |||
| '%.2f' % (self.DIC), | ||||
| np.max(snr)] | np.max(snr)] | |||
| ), \ | ), \ | |||
| names=['best_chi2', 'chi2_at_p', 'BIC', 'Ndegree ', \ | names=['best_chi2', 'chi2_at_p', 'BIC', 'Ndegree ', \ | |||
| 'AIC', 'k', \ | 'AIC', 'k', \ | |||
| 'pD', 'DIC', 'SNRmax']) | 'pD', 'DIC', 'SNRmax']) | |||
| if self.mcmc_method is 'multinest': | if self.mcmc_method == 'multinest': | |||
| evidence = self.sampler['stats']['global evidence'] | evidence = self.sampler['stats']['global evidence'] | |||
| self.stats.add_column(evidence*-2,name='log Z') | self.stats.add_column(evidence*-2,name='log Z') | |||
| return self.stats | return self.stats | |||
| def create_clean_cube(self, galaxy, shape, final=False): | def create_clean_cube(self, galaxy, shape, final=False): | |||
| """ | """ | |||
| Creates a cube containing a clean simulation of a galaxy according to | Creates a cube containing a clean simulation of a galaxy according to | |||
| the provided model. | the provided model. | |||
| skipping to change at line 1512 | skipping to change at line 1538 | |||
| def _chain_as_asciitable(self): | def _chain_as_asciitable(self): | |||
| """ | """ | |||
| Exports the chain as an `asciitable`. | Exports the chain as an `asciitable`. | |||
| See the public API `import_chain()` for the reverse operation of lo ading | See the public API `import_chain()` for the reverse operation of lo ading | |||
| the chain from an `asciitable` file. | the chain from an `asciitable` file. | |||
| """ | """ | |||
| out = StringStdOut() | out = StringStdOut() | |||
| asciitable.write(self.chain, | asciitable.write(self.chain, | |||
| output=out, | output=out, | |||
| Writer=asciitable.FixedWidth, | format='fixed_width', | |||
| names=self.chain.dtype.names) | names=self.chain.dtype.names) | |||
| return out.content | return out.content | |||
| def _get_min_chi_index(self): | def _get_min_chi_index(self): | |||
| """ | """ | |||
| Gets the index in the chain of the parameters with the minimal chi. | Gets the index in the chain of the parameters with the minimal chi. | |||
| """ | """ | |||
| if self.chain is None: | if self.chain is None: | |||
| raise RuntimeError("No chain! Run `run_mcmc()` first.") | raise RuntimeError("No chain! Run `run_mcmc()` first.") | |||
| End of changes. 33 change blocks. | ||||
| 34 lines changed or deleted | 64 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||