Module diskchef.engine.ctable
Class CTable(astropy.table.QTable) with additional features for CheF
Classes
class CTable (data=None, masked=False, names=None, dtype=None, meta=None, copy=True, rows=None, copy_indices=True, units=None, descriptions=None, coord_base: Literal['cylinder', 'sphere'] = 'cylinder', coord_style: Literal['center', 'edge'] = 'center', dims: Literal['2d', '3d'] = '2d')-
Subclass of astropy.table.Qtable for DiskCheF
Features
puts
nameattribute to the__getitem__outputreturns appropriate columns with
randzpropertiesprovides
interpolatemethod that returns aCallable(r,z)repr() call sets formats to "e"
Usage:
>>> tbl = CTable() >>> tbl['Radius'] = [1, 2] * u.m; tbl['Data'] = [3e-4, 4e3] >>> tbl # doctest: +NORMALIZE_WHITESPACE <CTable length=2> Radius Data m float64 float64 ------------ ------------ 1.000000e+00 3.000000e-04 2.000000e+00 4.000000e+03 >>> # Radius, Height, and some other keywords are achievable with r, z, and other respective properties >>> tbl.r <Quantity [1., 2.] m>>>> # .name attribute is properly set for the returned Quantity >>> tbl['Data'].name 'Data' >>> tbl.r.name 'Radius'>>> # Adding rows is not possible >>> tbl.add_row([1*u.cm, 10]) Traceback (most recent call last): ... diskchef.engine.exceptions.CHEFNotImplementedError: Adding rows (grid points) is not possible in CTable>>> # Interpolation >>> tbl = CTable() >>> tbl["Radius"] = [1, 2, 3, 1, 2, 3] * u.au >>> tbl["Height"] = [0, 0, 0, 1, 1, 1] * u.au >>> tbl["Data"] = [2, 4, 6, 3, 5, 7] * u.K >>> tbl # doctest: +NORMALIZE_WHITESPACE <CTable length=6> Radius Height Data AU AU K float64 float64 float64 ------------ ------------ ------------ 1.000000e+00 0.000000e+00 2.000000e+00 2.000000e+00 0.000000e+00 4.000000e+00 3.000000e+00 0.000000e+00 6.000000e+00 1.000000e+00 1.000000e+00 3.000000e+00 2.000000e+00 1.000000e+00 5.000000e+00 3.000000e+00 1.000000e+00 7.000000e+00 >>> tbl.interpolate("Data")(1.5 * u.au, 0 * u.au) <Quantity [3.] K> >>> tbl.interpolate("Data")([1, 2.5] * u.au, [0.2, 0.8] * u.au) <Quantity [2.2, 5.8] K> >>> # Compatible units are allowed >>> tbl.interpolate("Data")(1.5e8 * u.km, [0.2, 0.8] * u.au) <Quantity [2.20537614, 2.80537614] K>Expand source code
class CTable(QTable): """ Subclass of astropy.table.Qtable for DiskCheF Features: puts `name` attribute to the `__getitem__` output returns appropriate columns with `r` and `z` properties provides `interpolate` method that returns a `Callable(r,z)` __repr__() call sets formats to "e" Usage: >>> tbl = CTable() >>> tbl['Radius'] = [1, 2] * u.m; tbl['Data'] = [3e-4, 4e3] >>> tbl # doctest: +NORMALIZE_WHITESPACE <CTable length=2> Radius Data m float64 float64 ------------ ------------ 1.000000e+00 3.000000e-04 2.000000e+00 4.000000e+03 >>> # Radius, Height, and some other keywords are achievable with r, z, and other respective properties >>> tbl.r <Quantity [1., 2.] m> >>> # .name attribute is properly set for the returned Quantity >>> tbl['Data'].name 'Data' >>> tbl.r.name 'Radius' >>> # Adding rows is not possible >>> tbl.add_row([1*u.cm, 10]) Traceback (most recent call last): ... diskchef.engine.exceptions.CHEFNotImplementedError: Adding rows (grid points) is not possible in CTable >>> # Interpolation >>> tbl = CTable() >>> tbl["Radius"] = [1, 2, 3, 1, 2, 3] * u.au >>> tbl["Height"] = [0, 0, 0, 1, 1, 1] * u.au >>> tbl["Data"] = [2, 4, 6, 3, 5, 7] * u.K >>> tbl # doctest: +NORMALIZE_WHITESPACE <CTable length=6> Radius Height Data AU AU K float64 float64 float64 ------------ ------------ ------------ 1.000000e+00 0.000000e+00 2.000000e+00 2.000000e+00 0.000000e+00 4.000000e+00 3.000000e+00 0.000000e+00 6.000000e+00 1.000000e+00 1.000000e+00 3.000000e+00 2.000000e+00 1.000000e+00 5.000000e+00 3.000000e+00 1.000000e+00 7.000000e+00 >>> tbl.interpolate("Data")(1.5 * u.au, 0 * u.au) <Quantity [3.] K> >>> tbl.interpolate("Data")([1, 2.5] * u.au, [0.2, 0.8] * u.au) <Quantity [2.2, 5.8] K> >>> # Compatible units are allowed >>> tbl.interpolate("Data")(1.5e8 * u.km, [0.2, 0.8] * u.au) <Quantity [2.20537614, 2.80537614] K> """ def __init__(self, data=None, masked=False, names=None, dtype=None, meta=None, copy=True, rows=None, copy_indices=True, units=None, descriptions=None, coord_base: Literal['cylinder', 'sphere'] = 'cylinder', coord_style: Literal['center', 'edge'] = 'center', dims: Literal['2d', '3d'] = '2d', ): super().__init__(data, masked, names, dtype, meta, copy, rows, copy_indices, units, descriptions) self.dust_list = [] self.coord_base = coord_base self.coord_style = coord_style self.dims = dims for column in self.columns: try: self[column].info.format = "e" except ValueError: pass def __getitem__(self, item): try: column_quantity = super().__getitem__(item) except KeyError as e: if " number density" in item: column_quantity = self[item[:-len(" number density")]] * self["n(H+2H2)"] else: raise e if isinstance(column_quantity, (astropy.table.Column, u.Quantity)): column_quantity.name = item return column_quantity @property def r(self): """Column with radius coordinate""" return self['Radius'] @cached_property def r_grid(self): """Column with radius coordinate""" return np.sort(np.unique(self.r)).to(u.au) @property def z(self): """Column with height coordinate""" return self['Height'] @cached_property def z_grid(self): """Column with height coordinate""" return np.sort(np.unique(self.z)).to(u.au) @property def zr(self): return self['Height to radius'] @cached_property def zr_grid(self): """Column with height coordinate""" return np.sort(np.unique(self.zr)) @property def d(self): return self['Distance to star'] @cached_property def d_grid(self): """Column with radius coordinate""" return np.sort(np.unique(self.d)).to(u.au) @property def theta(self): return self['Theta'] @property def phi(self): return self['Phi'] @cached_property def phi_grid(self): return np.sort(np.unique(self.phi)).to(u.rad) @cached_property def theta_grid(self): return np.sort(np.unique(self.theta)).to(u.rad) def interpolate( self, column: str, method: Literal['linear', 'nearest', 'cubic'] = 'linear', rescale: bool = False, fill_value: float = 0.0 ) -> Callable[[u.Quantity, u.Quantity], u.Quantity]: """ Interpolate the selected quantity Args: column: str -- column name of the table to interpolate method: to be passed to scipy.interpolation.griddata rescale: to be passed to scipy.interpolation.griddata fill_value: to be passed to scipy.interpolation.griddata Returns: callable(r, z) with interpolated value of column """ def _interpolation(r: u.au, z: u.au): is_ordered = 0 if self.coord_base == 'sphere': is_ordered += int(self.is_in_theta_regular_grid) elif self.coord_base == 'cylinder': is_ordered += int(self.is_in_z_regular_grid) + int(self.is_in_zr_regular_grid) if is_ordered == 0: interpolated = griddata( points=(self.r.to(u.au).value, self.z.to(u.au).value), values=self[column], xi=(r.to(u.au).value, z.to(u.au).value), method=method, rescale=rescale, fill_value=fill_value ) elif is_ordered > 0: d = np.sqrt(r**2 + z**2) theta = np.pi / 2 * u.rad - np.arctan(z/r) if self.coord_base == 'sphere': x_point = d.to(u.au).value x_grid = self.d_grid.value z_point = theta.to(u.rad).value z_grid = self.theta_grid.value elif self.coord_base == 'cylinder': x_point = r.to(u.au).value x_grid = self.r_grid.value if self.is_in_z_regular_grid: z_point = z.to(u.au).value z_grid = self.z_grid.value elif self.is_in_zr_regular_grid: z_point = z.to(u.au).value/r.to(u.au).value z_grid = self.zr_grid.value values = np.array(self[column]).reshape((len(z_grid), len(x_grid))) interpolated = interpn( points=(z_grid, x_grid), values=values, xi=(z_point, x_point), method=method, bounds_error=False, fill_value=fill_value ) if self[column].unit: interpolated = interpolated << self[column].unit return interpolated return _interpolation def interpolate3d( self, column: str, method: Literal['linear', 'nearest', 'cubic'] = 'linear', rescale: bool = False, fill_value: float = 0.0 ) -> Callable[[u.Quantity, u.Quantity, u.Quantity], u.Quantity]: """ Interpolate the selected quantity Args: column: str -- column name of the table to interpolate method: to be passed to scipy.interpolation.griddata rescale: to be passed to scipy.interpolation.griddata fill_value: to be passed to scipy.interpolation.griddata Returns: callable(r, z, phi) with interpolated value of column """ def _interpolation(r: u.au, z: u.au, phi: u.rad): is_ordered = 0 if self.coord_base == 'sphere': is_ordered += int(self.is_in_theta_regular_grid) elif self.coord_base == 'cylinder': is_ordered += int(self.is_in_z_regular_grid) + int(self.is_in_zr_regular_grid) if is_ordered == 0: interpolated = griddata( points=(self.r.to(u.au).value, self.z.to(u.au).value, self.phi.to(u.rad).value), values=self[column], xi=(r.to(u.au).value, z.to(u.au).value, phi.to(u.rad).value), method=method, rescale=rescale, fill_value=fill_value ) elif is_ordered > 0: d = np.sqrt(r**2 + z**2) theta = np.pi / 2 * u.rad - np.arctan(z/r) if self.coord_base == 'sphere': x_point = d.to(u.au).value x_grid = self.d_grid.value z_point = theta.to(u.rad).value z_grid = self.theta_grid.value elif self.coord_base == 'cylinder': x_point = r.to(u.au).value x_grid = self.r_grid.value if self.is_in_z_regular_grid: z_point = z.to(u.au).value z_grid = self.z_grid.value elif self.is_in_zr_regular_grid: z_point = z.to(u.au).value/r.to(u.au).value z_grid = self.zr_grid.value values = np.array(self[column]).reshape((len(self.phi_grid), len(z_grid), len(x_grid))) interpolated = interpn( points=(self.phi_grid.value, z_grid, x_grid), values=values, xi=(phi.to(u.rad).value, z_point, x_point), method=method, bounds_error=False, fill_value=fill_value ) if self[column].unit: interpolated = interpolated << self[column].unit return interpolated return _interpolation @cached_property def is_in_zr_regular_grid(self) -> bool: """ Returns: whether the table is on a grid of (R, z/R) or (r, z/R) for 2D or a grid of (R, z/R, phi) or (r, z/R, phi) for 3D """ if 'Height to radius' not in self.colnames: return False if self.dims == '2d': if self.coord_base == 'cylinder': return len(self.r_grid) * len(self.zr_grid) == len(self) elif self.coord_base == 'sphere': return len(set(self.d)) * len(self.zr_grid) == len(self) elif self.dims == '3d': if self.coord_base == 'cylinder': return len(self.r_grid) * len(self.zr_grid) * len(self.phi_grid) == len(self) elif self.coord_base == 'sphere': return len(set(self.d)) * len(self.zr_grid) * len(self.phi_grid) == len(self) @cached_property def is_in_theta_regular_grid(self) -> bool: """ Returns: whether the table is on a grid of (R, z/R) or (r, z/R) for 2D or a grid of (R, z/R, phi) or (r, z/R, phi) for 3D """ if 'Theta' not in self.colnames: return False if self.dims == '2d': if self.coord_base == 'cylinder': return len(self.r_grid) * len(self.theta_grid) == len(self) elif self.coord_base == 'sphere': return len(set(self.d)) * len(self.theta_grid) == len(self) elif self.dims == '3d': if self.coord_base == 'cylinder': return len(self.r_grid) * len(self.theta_grid) * len(self.phi_grid) == len(self) elif self.coord_base == 'sphere': return len(set(self.d)) * len(self.theta_grid) * len(self.phi_grid) == len(self) @cached_property def is_in_z_regular_grid(self) -> bool: """ Returns: whether the table is on a grid of (R, z) or (r, z) for 2D or a grid of (R, z, phi) or (r, z, phi) for 3D """ if 'Height' not in self.colnames: return False if self.dims == '2d': if self.coord_base == 'cylinder': return len(self.r_grid) * len(self.z_grid) == len(self) elif self.coord_base == 'sphere': if len(set(self.d)) * len(self.z_grid) == len(self): print('Girl get help') return True else: return False elif self.dims == '3d': if self.coord_base == 'cylinder': return len(self.r_grid) * len(self.z_grid) * len(self.phi_grid) == len(self) elif self.coord_base == 'sphere': if len(set(self.d)) * len(self.z_grid) * len(self.phi_grid) == len(self): print('Girl get help') return True else: return False def add_row(self, vals=None, mask=None): """ Adding rows (grid points) is not possible in CTable Raises: CHEFNotImplementedError """ raise CHEFNotImplementedError("Adding rows (grid points) is not possible in CTable") def __setitem__(self, key, value): super().__setitem__(key, value) try: self[key].info.format = "e" except ValueError: pass def __repr__(self): return self._base_repr_(html=False, max_width=-1, max_lines=-1) def __str__(self): return repr(self) @property def _dust_pop_sum(self): return sum([self[f"{dust.name} mass fraction"] for dust in self.dust_list]) @property def dust_population_fully_set(self, atol=1e-5): """ Check whether sum of mass fractions of dust populations is equal to 1 """ return np.all(abs(1 - self._dust_pop_sum) < atol) def normalize_dust(self): """ Normalize the dust fractions so that the sum is 1 """ pop_sum = self._dust_pop_sum for dust in self.dust_list: dust.mass_fraction /= pop_sum dust.write_to_table() if not self.dust_population_fully_set: raise CHEFRuntimeError def column_density(self, colname: str, r: u.au = None) -> u.Quantity: """ Calculate column density of `colname` on `r` grid Args: colname: name of the column to collapse r: grid (centers) for the output. If not specified, defaults to `sorted(set(self.r))` Returns: column density of `self[colname]` on `r` grid """ if r is None: r = sorted(set(self.r)) if self.is_in_zr_regular_grid: r_grid = sorted(set(self.r)) coldenses = [] for _r in r_grid: indices = self.r == _r value = self[colname][indices] z = self.z[indices] coldenses.append(np.trapz(value, z)) coldenses = u.Quantity(coldenses) return np.interp(r, r_grid, coldenses) else: raise NotImplementedError("Column density is currently only implemented for zr grids") def check_zeros(self, column, nearest=True, warnings_on=False): """Replaces zeros in `self.table[column]` with the second smallest by absolute value element""" values_set = sorted(set(np.abs(self[column]))) if 0 in u.Quantity(self[column]).value: if warnings_on: warnings.warn("Found zeros in %s" % column) index = self[column].value == 0 if nearest: data = self[column][~index] if self.dims == '3d': self[column] = griddata( points=(self.r[~index].to(u.au).value, self.z[~index].to(u.au).value, self.phi[~index].to(u.rad).value), values=data, xi=(self.r.to(u.au).value, self.z.to(u.au).value, self.phi.to(u.rad).value), method="nearest", ) << self[column].unit elif self.dims == '2d': self[column] = griddata( points=( self.r[~index].to(u.au).value, self.z[~index].to(u.au).value), values=data, xi=(self.r.to(u.au).value, self.z.to(u.au).value), method="nearest", ) << self[column].unit else: if len(values_set) > 2: self[column][index] = values_set[1] else: self[column][index] = values_set[1] / 1e6Ancestors
- astropy.table.table.QTable
- astropy.table.table.Table
Instance variables
prop d-
Expand source code
@property def d(self): return self['Distance to star'] var d_grid-
Column with radius coordinate
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val prop dust_population_fully_set-
Check whether sum of mass fractions of dust populations is equal to 1
Expand source code
@property def dust_population_fully_set(self, atol=1e-5): """ Check whether sum of mass fractions of dust populations is equal to 1 """ return np.all(abs(1 - self._dust_pop_sum) < atol) var is_in_theta_regular_grid-
Returns: whether the table is on a grid of (R, z/R) or (r, z/R) for 2D or a grid of (R, z/R, phi) or (r, z/R, phi) for 3D
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val var is_in_z_regular_grid-
Returns: whether the table is on a grid of (R, z) or (r, z) for 2D or a grid of (R, z, phi) or (r, z, phi) for 3D
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val var is_in_zr_regular_grid-
Returns: whether the table is on a grid of (R, z/R) or (r, z/R) for 2D or a grid of (R, z/R, phi) or (r, z/R, phi) for 3D
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val prop phi-
Expand source code
@property def phi(self): return self['Phi'] var phi_grid-
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val prop r-
Column with radius coordinate
Expand source code
@property def r(self): """Column with radius coordinate""" return self['Radius'] var r_grid-
Column with radius coordinate
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val prop theta-
Expand source code
@property def theta(self): return self['Theta'] var theta_grid-
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val prop z-
Column with height coordinate
Expand source code
@property def z(self): """Column with height coordinate""" return self['Height'] var z_grid-
Column with height coordinate
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val prop zr-
Expand source code
@property def zr(self): return self['Height to radius'] var zr_grid-
Column with height coordinate
Expand source code
def __get__(self, instance, owner=None): if instance is None: return self if self.attrname is None: raise TypeError( "Cannot use cached_property instance without calling __set_name__ on it.") try: cache = instance.__dict__ except AttributeError: # not all objects have __dict__ (e.g. class defines slots) msg = ( f"No '__dict__' attribute on {type(instance).__name__!r} " f"instance to cache {self.attrname!r} property." ) raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: with self.lock: # check if another thread filled cache while we awaited lock val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: val = self.func(instance) try: cache[self.attrname] = val except TypeError: msg = ( f"The '__dict__' attribute on {type(instance).__name__!r} instance " f"does not support item assignment for caching {self.attrname!r} property." ) raise TypeError(msg) from None return val
Methods
def add_row(self, vals=None, mask=None)-
Adding rows (grid points) is not possible in CTable
Raises: CHEFNotImplementedError
def check_zeros(self, column, nearest=True, warnings_on=False)-
Replaces zeros in
self.table[column]with the second smallest by absolute value element def column_density(self, colname: str, r: Unit("AU") = None)-
Calculate column density of
colnameonrgridArgs
colname- name of the column to collapse
r- grid (centers) for the output. If not specified, defaults to
sorted(set(self.r))
Returns
column density of
self[colname]onrgrid def interpolate(self, column: str, method: Literal['linear', 'nearest', 'cubic'] = 'linear', rescale: bool = False, fill_value: float = 0.0) ‑> Callable[[astropy.units.quantity.Quantity, astropy.units.quantity.Quantity], astropy.units.quantity.Quantity]-
Interpolate the selected quantity
Args
column- str – column name of the table to interpolate
method- to be passed to scipy.interpolation.griddata
rescale- to be passed to scipy.interpolation.griddata
fill_value- to be passed to scipy.interpolation.griddata
Returns: callable(r, z) with interpolated value of column
def interpolate3d(self, column: str, method: Literal['linear', 'nearest', 'cubic'] = 'linear', rescale: bool = False, fill_value: float = 0.0) ‑> Callable[[astropy.units.quantity.Quantity, astropy.units.quantity.Quantity, astropy.units.quantity.Quantity], astropy.units.quantity.Quantity]-
Interpolate the selected quantity
Args
column- str – column name of the table to interpolate
method- to be passed to scipy.interpolation.griddata
rescale- to be passed to scipy.interpolation.griddata
fill_value- to be passed to scipy.interpolation.griddata
Returns: callable(r, z, phi) with interpolated value of column
def normalize_dust(self)-
Normalize the dust fractions so that the sum is 1