Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

U/troxel/diffsky #81

Merged
merged 22 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
567cd33
Added diffsky object types
matroxel Nov 21, 2023
10487dd
Added diffsky compatitbility and functionality to calculate roman gal…
matroxel Nov 21, 2023
e15cf82
Added functionality to calculate roman fluxes
matroxel Nov 21, 2023
7813241
Fixed bug with inhereting random seed for knot positions. Added non-p…
matroxel Nov 21, 2023
0dc04b5
New diffsky object class
matroxel Nov 21, 2023
db907cb
Added functionality to calculate roman fluxes
matroxel Nov 21, 2023
7e4484b
Added diffsky functionality
matroxel Nov 21, 2023
16313f4
Added diffsky functionality. Added roman flux functionality.
matroxel Nov 21, 2023
4169661
Updated schema to allow for diffsky objects and roman fluxes
matroxel Nov 21, 2023
da65785
Added diffsky sed class.
matroxel Nov 21, 2023
d123304
Updated null test for n_knots to be compatible with non-zero knot size.
matroxel Nov 21, 2023
57ac013
Added class to generate diffsky SEDs and write to hdf5 files.
matroxel Nov 21, 2023
a817e70
Fix for bug in knot implementation for galaxy obj type. Adds knot com…
matroxel Nov 27, 2023
75b5be7
Fix comment text; other cosmetic changes
JoanneBogart Nov 27, 2023
fb48391
Factor out common flux correction code for LSST, Roman
JoanneBogart Nov 27, 2023
b6232d9
factor out repeated code in parquet_schema_utils.py; other cosmetic c…
JoanneBogart Nov 27, 2023
ec0d34f
Change classnames diffSkySedFactory, diffSkySedGenerator to DiffskySe…
JoanneBogart Nov 27, 2023
bfe72b4
slightly increment version
JoanneBogart Nov 27, 2023
7a23c86
attempt to fix broken ci by following imSim model
JoanneBogart Nov 28, 2023
b404d97
attempt #2 to fix broken ci
JoanneBogart Nov 28, 2023
dafef5c
attempt #3 to fix broken ci
JoanneBogart Nov 28, 2023
79ea203
1. For cat. creation include option for Roman fluxes 2. Use standard …
JoanneBogart Nov 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ jobs:

- name: Install conda deps
run: |
conda update -n base conda
conda info
conda list
conda install -y mamba
mamba install -y --file etc/conda_requirements.txt
conda install -y --file etc/conda_requirements.txt
conda info
mamba list

- name: Install rubin_sim_data
run: |
Expand Down
33 changes: 33 additions & 0 deletions cfg/object_types.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,39 @@ object_types :
internal_extinction : CCM
MW_extinction : F19
spatial_model : knots
diffsky_galaxy :
file_template : 'galaxy_(?P<healpix>\d+).parquet'
flux_file_template : 'galaxy_flux_(?P<healpix>\d+).parquet'
sed_file_template : 'galaxy_sed_(?P<healpix>\d+).hdf5'
data_file_type : parquet
area_partition :
{ type: healpix, ordering : ring, nside : 32}
composite :
bulge : required
disk : required
knots : optional
diffsky_bulge :
subtype : bulge
parent : diffsky_galaxy
sed_model : TBD
internal_extinction : CCM
MW_extinction : F19
spatial_model : sersic2D
diffsky_disk :
subtype : disk
parent : diffsky_galaxy
sed_model : TBD
internal_extinction : CCM
MW_extinction : F19
spatial_model : sersic2D
diffsky_knots :
subtype : knots
parent : diffsky_galaxy
sed_model : TBD
internal_extinction : CCM
MW_extinction : F19
spatial_model : knots

star :
file_template : 'pointsource_(?P<healpix>\d+).parquet'
flux_file_template : 'pointsource_flux_(?P<healpix>\d+).parquet'
Expand Down
2 changes: 1 addition & 1 deletion skycatalogs/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.7.0-rc1"
__version__ = "1.7.0-rc2"
278 changes: 157 additions & 121 deletions skycatalogs/catalog_creator.py

Large diffs are not rendered by default.

Binary file added skycatalogs/data/dsps_ssp_data_singlemet.h5
Binary file not shown.
400 changes: 400 additions & 0 deletions skycatalogs/diffsky_sedgen.py

Large diffs are not rendered by default.

59 changes: 57 additions & 2 deletions skycatalogs/objects/base_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import itertools
import numpy as np
import galsim
from galsim.roman import longwave_bands as roman_longwave_bands
from galsim.roman import shortwave_bands as roman_shortwave_bands
from galsim.roman import getBandpasses as roman_getBandpasses

from skycatalogs.utils.translate_utils import form_object_string
from skycatalogs.utils.config_utils import Config
Expand All @@ -15,9 +18,11 @@
'''

__all__ = ['BaseObject', 'ObjectCollection', 'ObjectList',
'LSST_BANDS', 'load_lsst_bandpasses']
'LSST_BANDS', 'ROMAN_BANDS',
'load_lsst_bandpasses', 'load_roman_bandpasses']

LSST_BANDS = ('ugrizy')
ROMAN_BANDS = roman_shortwave_bands+roman_longwave_bands

# global for easy access for code run within mp

Expand Down Expand Up @@ -68,6 +73,16 @@ def load_lsst_bandpasses():
return lsst_bandpasses


def load_roman_bandpasses():
'''
Read in Roman bandpasses from standard place, trim, and store in global dict
Returns: The dict
'''
global roman_bandpasses
roman_bandpasses = roman_getBandpasses()
return roman_bandpasses


class BaseObject(object):
'''
Abstract base class for static (in position coordinates) objects.
Expand Down Expand Up @@ -187,7 +202,6 @@ def _get_sed(self, component=None, resolution=None, mjd=None):

Must be implemented by subclass
'''

raise NotImplementedError('Must be implemented by BaseObject subclass if needed')

def write_sed(self, sed_file_path, component=None, resolution=None,
Expand Down Expand Up @@ -340,6 +354,45 @@ def get_LSST_fluxes(self, cache=True, as_dict=True, mjd=None):
else:
return list(fluxes.values())

def get_roman_flux(self, band, sed=None, cache=True, mjd=None):
if band not in ROMAN_BANDS:
return None
att = f'roman_flux_{band}'

# Check if it's already an attribute
val = getattr(self, att, None)
if val is not None:
return val

if att in self.native_columns:
return self.get_native_attribute(att)

val = self.get_flux(roman_bandpasses[band], sed=sed, mjd=mjd)

if cache:
setattr(self, att, val)
return val

def get_roman_fluxes(self, cache=True, as_dict=True, mjd=None):
'''
Return a dict of fluxes for Roman bandpasses or, if as_dict is False,
just a list in the same order as ROMAN_BANDS
'''
fluxes = dict()
sed = self.get_total_observer_sed(mjd=mjd)

if sed is None:
for band in ROMAN_BANDS:
fluxes[band] = 0.0
else:
for band in ROMAN_BANDS:
fluxes[band] = self.get_roman_flux(band, sed=sed,
cache=cache, mjd=mjd)
if as_dict:
return fluxes
else:
return list(fluxes.values())


class ObjectCollection(Sequence):
'''
Expand Down Expand Up @@ -436,6 +489,8 @@ def subcomponents(self):
for s in ['bulge', 'disk', 'knots']:
if f'sed_val_{s}' in self.native_columns:
subs.append(s)
elif self._object_type_unique == 'diffsky_galaxy':
subs = ['bulge', 'disk', 'knots']
else:
return ['this_object']
return subs
Expand Down
153 changes: 153 additions & 0 deletions skycatalogs/objects/diffsky_object.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# import numpy as np
import galsim
import numpy as np
from .base_object import BaseObject

__all__ = ['DiffskyObject']


class DiffskyObject(BaseObject):
_type_name = 'diffsky_galaxy'

# sersic values are constant for diffsky galaxies
_sersic_disk = 1
_sersic_bulge = 4

def _get_sed(self, component=None, resolution=None):
'''
Return sed and mag_norm for a galaxy component or for a star
Parameters
----------
component one of 'bulge', 'disk', 'knots' for now. Other components
may be supported. Ignored for stars
resolution desired resolution of lambda in nanometers. Ignored
for stars.

Returns
-------
A pair (sed, mag_norm)
'''

if component not in ['disk', 'bulge', 'knots']:
raise ValueError(f'Cannot fetch SED for component type {component}')

if not hasattr(self, '_seds'):
z_h = self.get_native_attribute('redshiftHubble')
z = self.get_native_attribute('redshift')
pixel = self.partition_id

sky_cat = self._belongs_to._sky_catalog
self._seds = sky_cat.observed_sed_factory.create(pixel, self.id, z_h, z)

magnorm = None
return self._seds[component], magnorm

def get_knot_size(self,z):
"""
Return the angular knot size. Knots are modelled as the same physical size
"""
# Deceleration paramameter
q = -0.5
# Angular diameter scaling approximation in pc
dA = (3e9/q**2)*(z*q+(q-1)*(np.sqrt(2*q*z+1)-1))/(1+z)**2*(1.4-0.53*z)
# Using typical knot size 250pc, convert to sigma in arcmin
if z<0.6:
return 206264.8*250/dA/2.355
else:
# Above z=0.6, fractional contribution to post-convolved size
# is <20% for smallest Roman PSF size, so can treat as point source
return None

def get_knot_n(self,rng=None):
"""
Return random value for number of knots based on galaxy sm.
"""
if rng is not None:
ud = galsim.UniformDeviate(rng)
else:
ud = galsim.UniformDeviate(int(self.id))
sm = np.log10(self.get_native_attribute('um_source_galaxy_obs_sm'))
m = (50-3)/(12-6) # (knot_n range)/(logsm range)
n_knot_max = m*(sm-6)+3
n_knot = int(ud()*n_knot_max) # random n up to n_knot_max
if n_knot==0:
n_knot+=1 # need at least 1 knot
return n_knot

def get_wl_params(self):
"""Return the weak lensing parameters, g1, g2, mu."""
gamma1 = self.get_native_attribute('shear1')
gamma2 = self.get_native_attribute('shear2')
kappa = self.get_native_attribute('convergence')
# Compute reduced shears and magnification.
g1 = gamma1/(1. - kappa) # real part of reduced shear
g2 = gamma2/(1. - kappa) # imaginary part of reduced shear
mu = 1./((1. - kappa)**2 - (gamma1**2 + gamma2**2)) # magnification
return g1, g2, mu

def get_total_observer_sed(self, mjd=None):
"""
Return the SED summed over SEDs for the individual SkyCatalog
components.
"""
sed = super().get_total_observer_sed()

if sed is None:
return sed

_, _, mu = self.get_wl_params()
sed *= mu
return sed

def get_gsobject_components(self, gsparams=None, rng=None):

if gsparams is not None:
gsparams = galsim.GSParams(**gsparams)

if rng is None:
rng = galsim.BaseDeviate(int(self.id))

obj_dict = {}
for component in self.subcomponents:
# knots use the same major/minor axes as the disk component.
my_cmp = 'disk' if component != 'bulge' else 'spheroid'
hlr = self.get_native_attribute(f'{my_cmp}HalfLightRadiusArcsec')

# Get ellipticities saved in catalog. Not sure they're what
# we need
e1 = self.get_native_attribute(f'{my_cmp}Ellipticity1')
e2 = self.get_native_attribute(f'{my_cmp}Ellipticity2')
shear = galsim.Shear(g1=e1, g2=e2)

if component == 'knots':
npoints = self.get_knot_n()
assert npoints > 0
knot_profile = galsim.Sersic(n=self._sersic_disk,
half_light_radius=hlr/2.,
gsparams=gsparams)
knot_profile = knot_profile._shear(shear)
obj = galsim.RandomKnots(npoints=npoints,
profile=knot_profile, rng=rng,
gsparams=gsparams)
z = self.get_native_attribute('redshift')
size = self.get_knot_size(z) # get knot size
if size is not None:
obj = galsim.Convolve(obj, galsim.Gaussian(sigma=size))
obj_dict[component] = obj
else:
n = self._sersic_disk if component == 'disk' else self._sersic_bulge
obj = galsim.Sersic(n=n, half_light_radius=hlr,
gsparams=gsparams)
obj_dict[component] = obj._shear(shear)

# Apply lensing
g1, g2, mu = self.get_wl_params()
for component in self.subcomponents:
obj_dict[component] = obj_dict[component]._lens(g1, g2, mu)
return obj_dict

def get_observer_sed_component(self, component, mjd=None, resolution=None):
sed, _ = self._get_sed(component)
if sed is not None:
sed = self._apply_component_extinction(sed)
return sed
Loading
Loading