def get_interpolator(self, data_type, e_min, e_max, energy=True): data = getattr(self, "emissivity_%s" % data_type) if not energy: data = data[..., :] / self.emid.v e_min = YTQuantity(e_min, "keV")*(1.0+self.redshift) e_max = YTQuantity(e_max, "keV")*(1.0+self.redshift) if (e_min - self.ebin[0]) / e_min < -1e-3 or \ (e_max - self.ebin[-1]) / e_max > 1e-3: raise EnergyBoundsException(self.ebin[0], self.ebin[-1]) e_is, e_ie = np.digitize([e_min, e_max], self.ebin) e_is = np.clip(e_is - 1, 0, self.ebin.size - 1) e_ie = np.clip(e_ie, 0, self.ebin.size - 1) my_dE = self.dE[e_is: e_ie].copy() # clip edge bins if the requested range is smaller my_dE[0] -= e_min - self.ebin[e_is] my_dE[-1] -= self.ebin[e_ie] - e_max interp_data = (data[..., e_is:e_ie]*my_dE).sum(axis=-1) if data.ndim == 2: emiss = UnilinearFieldInterpolator(np.log10(interp_data), [self.log_T[0], self.log_T[-1]], "log_T", truncate=True) else: emiss = BilinearFieldInterpolator(np.log10(interp_data), [self.log_nH[0], self.log_nH[-1], self.log_T[0], self.log_T[-1]], ["log_nH", "log_T"], truncate=True) return emiss
def get_interpolator(self, data, e_min, e_max): e_min = YTQuantity(e_min, "keV") e_max = YTQuantity(e_max, "keV") if (e_min - self.E_bins[0]) / e_min < -1e-3 or \ (e_max - self.E_bins[-1]) / e_max > 1e-3: raise EnergyBoundsException(self.E_bins[0], self.E_bins[-1]) e_is, e_ie = np.digitize([e_min, e_max], self.E_bins) e_is = np.clip(e_is - 1, 0, self.E_bins.size - 1) e_ie = np.clip(e_ie, 0, self.E_bins.size - 1) my_dnu = self.dnu[e_is:e_ie].copy() # clip edge bins if the requested range is smaller my_dnu[0] -= ((e_min - self.E_bins[e_is]) / hcgs).in_units("Hz") my_dnu[-1] -= ((self.E_bins[e_ie] - e_max) / hcgs).in_units("Hz") interp_data = (data[..., e_is:e_ie] * my_dnu).sum(axis=-1) if len(data.shape) == 2: emiss = UnilinearFieldInterpolator(np.log10(interp_data), [self.log_T[0], self.log_T[-1]], "log_T", truncate=True) else: emiss = BilinearFieldInterpolator(np.log10(interp_data), [ self.log_nH[0], self.log_nH[-1], self.log_T[0], self.log_T[-1] ], ["log_nH", "log_T"], truncate=True) return emiss
def _ion_fraction_field(field, data): """ Creates the function for a derived field for following the ion_fraction of an ion over a dataset by plugging in the density, temperature, metallicity and redshift of the output into the ionization table. """ if isinstance(field.name, tuple): ftype = field.name[0] field_name = field.name[1] else: ftype = "gas" field_name = field.name n_parameters = len(table_store[field_name]['parameters']) if n_parameters == 1: ionFraction = table_store[field_name]['fraction'] t_param = table_store[field_name]['parameters'][0] bds = t_param.astype("=f8") interp = UnilinearFieldInterpolator(ionFraction, bds, 'log_T', truncate=True) elif n_parameters == 3: ionFraction = table_store[field_name]['fraction'] n_param = table_store[field_name]['parameters'][0] z_param = table_store[field_name]['parameters'][1] t_param = table_store[field_name]['parameters'][2] bds = [ n_param.astype("=f8"), z_param.astype("=f8"), t_param.astype("=f8") ] interp = TrilinearFieldInterpolator(ionFraction, bds, [(ftype, "log_nH"), (ftype, "redshift"), (ftype, "log_T")], truncate=True) else: raise RuntimeError("This data file format is not supported.") fraction = np.power(10, interp(data)) fraction[fraction <= fraction_zero_point] = 0.0 if not isinstance(data, FieldDetector) and (fraction > 1.0).any(): greater_than = fraction > 1.0 mylog.warning("%s > 1 was calculated. Capping values at 1." % field_name) mylog.warning( "%d offenders: median = %f; maximum = %f" % (len(fraction[greater_than]), np.median( fraction[greater_than]), np.max(fraction[greater_than]))) fraction = np.clip(fraction, 0.0, 1.0) return fraction