model_class.py | model_class.py | |||
---|---|---|---|---|
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | |||
import numpy as np | import numpy as np | |||
from scipy.interpolate import interp1d | from scipy.interpolate import interp1d | |||
from scipy import ndimage | from scipy import ndimage | |||
from copy import deepcopy | from copy import deepcopy | |||
from distutils.version import LooseVersion, StrictVersion | try: | |||
from distutils.version import LooseVersion as Version | ||||
except ImportError: | ||||
# python3.13 | ||||
from packaging.version import Version | ||||
try: | try: | |||
import bottleneck as bn | import bottleneck as bn | |||
except ImportError: | except ImportError: | |||
import numpy as bn | import numpy as bn | |||
from .hyperspectral_cube import HyperspectralCube as HyperCube | from .hyperspectral_cube import HyperspectralCube as HyperCube | |||
from .galaxy_parameters import GalaxyParameters | from .galaxy_parameters import GalaxyParameters | |||
# CONSTANTS | # CONSTANTS | |||
G = 6.67384e-11 # Gravitational Constant (m^3.kg^-1.s^-2) | G = 6.67384e-11 # Gravitational Constant (m^3.kg^-1.s^-2) | |||
SOL_MASS = 1.98e30 # Solar Mass (kg) | SOL_MASS = 1.9884e30 # Solar Mass (kg) | |||
PARSEC = 3e16 # Parsec (m) | PARSEC = 3.08567e16 # Parsec (m) | |||
# LOGGING CONFIGURATION | # LOGGING CONFIGURATION | |||
import logging | import logging | |||
logging.basicConfig(level=logging.INFO) | ||||
logger = logging.getLogger('GalPaK: DiskModel ') | ||||
#Python3 compatibility | #Python3 compatibility | |||
try: | try: | |||
basestring | basestring | |||
except NameError: | except NameError: | |||
basestring = str | basestring = str | |||
class Model: | class Model: | |||
""" | """ | |||
An **interface** for your simulation models. | An **interface** for your simulation models. | |||
The `runner` parameter is the instance of `galpak.Runner` using this mo del. | The `runner` parameter is the instance of `galpak.Runner` using this mo del. | |||
""" | """ | |||
logger = logger | logging.basicConfig(level=logging.INFO) | |||
logger = logging.getLogger('GalPaK: DiskModel ') | ||||
flux_map_user = None | flux_map_user = None | |||
def set_cosmology(self, cosmo_string='planck15'): | def set_cosmology(self, cosmo_string='planck15'): | |||
try: | try: | |||
from colossus.cosmology import cosmology | from colossus.cosmology import cosmology | |||
from colossus import halo | from colossus import halo | |||
from colossus.halo import mass_defs, mass_adv, mass_so, concent ration | from colossus.halo import mass_defs, mass_adv, mass_so, concent ration | |||
self.logger.info("setting cosmology with colossus package") | self.logger.info("setting cosmology with colossus package") | |||
if cosmo_string in cosmology.cosmologies.keys(): | if cosmo_string in cosmology.cosmologies.keys(): | |||
cosmo=cosmology.setCosmology(cosmo_string) | cosmo=cosmology.setCosmology(cosmo_string) | |||
skipping to change at line 68 | skipping to change at line 71 | |||
self.h = cosmo.h | self.h = cosmo.h | |||
self.Ez = cosmo.Ez(self.redshift) | self.Ez = cosmo.Ez(self.redshift) | |||
DA = cosmo.angularDiameterDistance(self.redshift) / self.h ### #!! | DA = cosmo.angularDiameterDistance(self.redshift) / self.h ### #!! | |||
self.DeltaVir = halo.mass_so.deltaVir(self.redshift) | self.DeltaVir = halo.mass_so.deltaVir(self.redshift) | |||
self.halo = halo #Diemer Halo module for NFW halo models | self.halo = halo #Diemer Halo module for NFW halo models | |||
except ImportError: | except ImportError: | |||
try: | try: | |||
# using astropy | # using astropy | |||
import astropy | import astropy | |||
from astropy import cosmology | from astropy import cosmology | |||
if astropy.__version__ < LooseVersion('5.1'): | if astropy.__version__ < Version('5.1'): | |||
cosmo_available = cosmology.parameters.available | cosmo_available = cosmology.parameters.available | |||
cosmo_get = cosmology.default_cosmology.get_cosmology_f rom_string | cosmo_get = cosmology.default_cosmology.get_cosmology_f rom_string | |||
else: | else: | |||
cosmo_available = cosmology.available | cosmo_available = cosmology.available | |||
cosmo_get = cosmology.default_cosmology.get_cosmology_f rom_string | cosmo_get = lambda x: getattr(cosmology, x) | |||
if cosmo_string in cosmo_available: | if cosmo_string in cosmo_available: | |||
cosmo = cosmo_get(cosmo_string) | cosmo = cosmo_get(cosmo_string) | |||
else: | else: | |||
self.logger.info("Astropy: Parameter %s is not availabl e\n " | self.logger.info("Astropy: Parameter %s is not availabl e\n " | |||
"Please use one of %s \n" | "Please use one of %s \n" | |||
"Will be uing astropy.cosmology Planck 15 as default" \ | "Will be uing astropy.cosmology Planck 15 as default" \ | |||
% (cosmo_string, cosmo_available)) | % (cosmo_string, cosmo_available)) | |||
cosmo = cosmo_get('Planck15') | cosmo = cosmo_get('Planck15') | |||
cosmo_string = cosmo.name | cosmo_string = cosmo.name | |||
skipping to change at line 163 | skipping to change at line 166 | |||
# parameters.maximum_velocity *= -1 | # parameters.maximum_velocity *= -1 | |||
inc = parameters['inclination'] | inc = parameters['inclination'] | |||
if inc<0: | if inc<0: | |||
parameters.pa +=180 | parameters.pa +=180 | |||
parameters.pa = parameters.pa % 360. #to deal with circularity | parameters.pa = parameters.pa % 360. #to deal with circularity | |||
def sanitize_chain(self, chain): | def sanitize_chain(self, chain): | |||
""" | """ | |||
Mutates the `chain` with custom logic. | to force maxvelocity to be positive ; using circularity symmetry | |||
This is called at the end of the loop, before storing the chain. | This is called at the end of the loop, before storing the chain. | |||
""" | """ | |||
pa = chain['pa'] | pa = chain['pa'] | |||
pa_corr = pa % 360 | pa_corr = pa % 360 | |||
chain['pa'] = pa_corr | chain['pa'] = pa_corr | |||
def setup_random_amplitude(self, amplitude): | def setup_random_amplitude(self, amplitude): | |||
""" | """ | |||
Mutates the random `amplitude` of the parameter jump with custom lo gic. | Mutates the random `amplitude` of the parameter jump with custom lo gic. | |||
This is called during the setup of the MCMC runner. | This is called during the setup of the MCMC runner. | |||
skipping to change at line 458 | skipping to change at line 461 | |||
radius_cube = np.hypot(nx,ny) #np.sqrt(nx**2. + ny**2.) | radius_cube = np.hypot(nx,ny) #np.sqrt(nx**2. + ny**2.) | |||
flux_cube = self.set_flux_profile(parameters, radius_cube) | flux_cube = self.set_flux_profile(parameters, radius_cube) | |||
# Adjust disk thickness | # Adjust disk thickness | |||
flux_cube = self.set_thickness_profile(nz, hz, flux_cube) | flux_cube = self.set_thickness_profile(nz, hz, flux_cube) | |||
# Normalize by flux | # Normalize by flux | |||
total = bn.nansum(flux_cube) #should always be >0 | total = bn.nansum(flux_cube) #should always be >0 | |||
if total>0: | if total>0: | |||
flux_cube = flux_cube / total | flux_cube = flux_cube / total | |||
else: | else: | |||
raise ValueError("Something is wrong. Total flux is zero") | raise ValueError("Something is wrong. Total flux is zero") | |||
# Flux weighted | # Flux weighted | |||
flux_map = bn.nansum(flux_cube, 0) | flux_map = bn.nansum(flux_cube, 0) | |||
bad = (flux_map**2 == 0) | bad = (flux_map**2 == 0) | |||
vz_map = bn.nansum(vz_cube * flux_cube / flux_map, 0) | vz_map = bn.nansum(vz_cube * flux_cube / flux_map, 0) | |||
vz_map[bad] = np.nan #force outer to 0 | vz_map[bad] = np.nan #force outer to 0 | |||
skipping to change at line 490 | skipping to change at line 493 | |||
# c) Normalized with flux squared | # c) Normalized with flux squared | |||
norm = bn.nansum(flux_cube * flux_cube, 0) | norm = bn.nansum(flux_cube * flux_cube, 0) | |||
sigz_map_ale = np.sqrt(bn.nansum(sig_ale_disk ** 2 * flux_cube ** 2 , 0) / norm) | sigz_map_ale = np.sqrt(bn.nansum(sig_ale_disk ** 2 * flux_cube ** 2 , 0) / norm) | |||
# Intrinsic Dispersionmodel | # Intrinsic Dispersionmodel | |||
if 'velocity_dispersion' in parameters.names: | if 'velocity_dispersion' in parameters.names: | |||
sig_intr = np.ones_like(sigz_map_ale) * parameters.velocity_dis persion | sig_intr = np.ones_like(sigz_map_ale) * parameters.velocity_dis persion | |||
else: | else: | |||
sig_intr = np.ones_like(sigz_map_ale) | sig_intr = np.ones_like(sigz_map_ale) | |||
#correct outer regions | ||||
#sigz_map_ale = np.where(bad, sig_intr, sigz_map_ale) | ||||
# Total S-map | # Total S-map | |||
s_map = np.sqrt(sig_map_disk ** 2 + sigz_map_ale ** 2 + sig_intr ** 2) | s_map = np.sqrt(sig_map_disk ** 2 + sigz_map_ale ** 2 + sig_intr ** 2) | |||
s_map[bad]=np.nan | s_map[bad]=np.nan | |||
return flux_cube, vz_cube, vz_map, s_map, \ | return flux_cube, vz_cube, vz_map, s_map, \ | |||
sig_map_disk, sigz_map_ale, sig_intr | sig_map_disk, sigz_map_ale, sig_intr | |||
def _map_indices(self, xx, yy, zz, parameters): | def _map_indices(self, xx, yy, zz, parameters): | |||
""" | """ | |||
Takes arrays of indices, galaxy parameters, and rotates accordingly . | Takes arrays of indices, galaxy parameters, and rotates accordingly . | |||
End of changes. 9 change blocks. | ||||
13 lines changed or deleted | 13 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/ |