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 create_cooling_fields(self): num = os.path.basename( self.ds.parameter_filename).split(".")[0].split("_")[1] filename = "%s/cooling_%05i.out" % (os.path.dirname( self.ds.parameter_filename), int(num)) if not os.path.exists(filename): return def _create_field(name, interp_object): def _func(field, data): shape = data["temperature"].shape d = { 'lognH': np.log10(_X * data["density"] / mh).ravel(), 'logT': np.log10(data["temperature"]).ravel() } rv = 10**interp_object(d).reshape(shape) # Return array in unit 'per volume' consistently with line below return data.ds.arr(rv, 'code_length**-3') self.add_field(name=name, sampling_type="cell", function=_func, units="code_length**-3") avals = {} tvals = {} with open(filename, "rb") as f: n1, n2 = fpu.read_vector(f, 'i') n = n1 * n2 for ax in _cool_axes: avals[ax] = fpu.read_vector(f, 'd') for tname in _cool_arrs: var = fpu.read_vector(f, 'd') if var.size == n1 * n2: tvals[tname] = var.reshape((n1, n2), order='F') else: var = var.reshape((n1, n2, var.size // (n1 * n2)), order='F') for i in range(var.shape[-1]): tvals[_cool_species[i]] = var[:, :, i] for n in tvals: interp = BilinearFieldInterpolator(tvals[n], (avals["lognH"], avals["logT"]), ["lognH", "logT"], truncate=True) _create_field(("gas", n), interp)
def create_cooling_fields(self): num = os.path.basename( self.ds.parameter_filename).split(".")[0].split("_")[1] filename = "%s/cooling_%05i.out" % (os.path.dirname( self.ds.parameter_filename), int(num)) if not os.path.exists(filename): mylog.warning('This output has no cooling fields') return #Function to create the cooling fields def _create_field(name, interp_object, unit): def _func(field, data): shape = data["temperature"].shape d = { 'lognH': np.log10(_X * data["density"] / mh).ravel(), 'logT': np.log10(data["temperature"]).ravel() } rv = interp_object(d).reshape(shape) if name[-1] != 'mu': rv = 10**interp_object(d).reshape(shape) cool = data.ds.arr(rv, unit) if 'metal' in name[-1].split('_'): cool = cool * data[ 'metallicity'] / 0.02 #Ramses uses Zsolar=0.02 elif 'compton' in name[-1].split('_'): cool = data.ds.arr(rv, unit + '/cm**3') cool = cool / data[ 'number_density'] #Compton cooling/heating is written to file in erg/s return cool self.add_field(name=name, sampling_type="cell", function=_func, units=unit) #Load cooling files avals = {} tvals = {} with FortranFile(filename) as fd: n1, n2 = fd.read_vector('i') for ax in _cool_axes: avals[ax] = fd.read_vector('d') for i, (tname, unit) in enumerate(_cool_arrs): var = fd.read_vector('d') if var.size == n1 and i == 0: #If this case occurs, the cooling files were produced pre-2010 in a format #that is no longer supported mylog.warning( 'This cooling file format is no longer supported. Cooling field loading skipped.' ) return if var.size == n1 * n2: tvals[tname] = dict(data=var.reshape((n1, n2), order='F'), unit=unit) else: var = var.reshape((n1, n2, var.size // (n1 * n2)), order='F') for i in range(var.shape[-1]): tvals[_cool_species[i]] = dict(data=var[:, :, i], unit="1/cm**3") #Add the mu field first, as it is needed for the number density interp = BilinearFieldInterpolator(tvals['mu']['data'], (avals["lognH"], avals["logT"]), ["lognH", "logT"], truncate=True) _create_field(("gas", 'mu'), interp, tvals['mu']['unit']) #Add the number density field, based on mu def _number_density(field, data): return data[('gas', 'density')] / mp / data['mu'] self.add_field(name=('gas', 'number_density'), sampling_type="cell", function=_number_density, units=number_density_unit) #Add the cooling and heating fields, which need the number density field for key in tvals: if key != 'mu': interp = BilinearFieldInterpolator( tvals[key]['data'], (avals["lognH"], avals["logT"]), ["lognH", "logT"], truncate=True) _create_field(("gas", key), interp, tvals[key]['unit']) #Add total cooling and heating fields def _all_cool(field, data): return data['cooling_primordial'] + data['cooling_metal'] + data[ 'cooling_compton'] def _all_heat(field, data): return data['heating_primordial'] + data['heating_compton'] self.add_field(name=('gas', 'cooling_total'), sampling_type="cell", function=_all_cool, units=cooling_function_units) self.add_field(name=('gas', 'heating_total'), sampling_type="cell", function=_all_heat, units=cooling_function_units) #Add net cooling fields def _net_cool(field, data): return data['cooling_total'] - data['heating_total'] self.add_field(name=('gas', 'cooling_net'), sampling_type="cell", function=_net_cool, units=cooling_function_units)
def create_cooling_fields(self): num = os.path.basename( self.ds.parameter_filename).split(".")[0].split("_")[1] filename = "%s/cooling_%05i.out" % ( os.path.dirname(self.ds.parameter_filename), int(num), ) if not os.path.exists(filename): mylog.warning("This output has no cooling fields") return # Function to create the cooling fields def _create_field(name, interp_object, unit): def _func(field, data): shape = data[("gas", "temperature")].shape d = { "lognH": np.log10(_X * data[("gas", "density")] / mh).ravel(), "logT": np.log10(data[("gas", "temperature")]).ravel(), } rv = interp_object(d).reshape(shape) if name[-1] != "mu": rv = 10**interp_object(d).reshape(shape) cool = data.ds.arr(rv, unit) if "metal" in name[-1].split("_"): cool = (cool * data[("gas", "metallicity")] / 0.02 ) # Ramses uses Zsolar=0.02 elif "compton" in name[-1].split("_"): cool = data.ds.arr(rv, unit + "/cm**3") cool = ( cool / data[("gas", "number_density")] ) # Compton cooling/heating is written to file in erg/s return cool self.add_field(name=name, sampling_type="cell", function=_func, units=unit) # Load cooling files avals = {} tvals = {} with FortranFile(filename) as fd: n1, n2 = fd.read_vector("i") for ax in _cool_axes: avals[ax] = fd.read_vector("d") for i, (tname, unit) in enumerate(_cool_arrs): var = fd.read_vector("d") if var.size == n1 and i == 0: # If this case occurs, the cooling files were produced pre-2010 in # a format that is no longer supported mylog.warning( "This cooling file format is no longer supported. " "Cooling field loading skipped.") return if var.size == n1 * n2: tvals[tname] = dict(data=var.reshape((n1, n2), order="F"), unit=unit) else: var = var.reshape((n1, n2, var.size // (n1 * n2)), order="F") for i in range(var.shape[-1]): tvals[_cool_species[i]] = dict(data=var[:, :, i], unit="1/cm**3") # Add the mu field first, as it is needed for the number density interp = BilinearFieldInterpolator( tvals["mu"]["data"], (avals["lognH"], avals["logT"]), ["lognH", "logT"], truncate=True, ) _create_field(("gas", "mu"), interp, tvals["mu"]["unit"]) # Add the number density field, based on mu def _number_density(field, data): return data[("gas", "density")] / mp / data[("gas", "mu")] self.add_field( name=("gas", "number_density"), sampling_type="cell", function=_number_density, units=number_density_unit, ) # Add the cooling and heating fields, which need the number density field for key in tvals: if key != "mu": interp = BilinearFieldInterpolator( tvals[key]["data"], (avals["lognH"], avals["logT"]), ["lognH", "logT"], truncate=True, ) _create_field(("gas", key), interp, tvals[key]["unit"]) # Add total cooling and heating fields def _all_cool(field, data): return (data[("gas", "cooling_primordial")] + data[("gas", "cooling_metal")] + data[("gas", "cooling_compton")]) def _all_heat(field, data): return (data[("gas", "heating_primordial")] + data[("gas", "heating_compton")]) self.add_field( name=("gas", "cooling_total"), sampling_type="cell", function=_all_cool, units=cooling_function_units, ) self.add_field( name=("gas", "heating_total"), sampling_type="cell", function=_all_heat, units=cooling_function_units, ) # Add net cooling fields def _net_cool(field, data): return data[("gas", "cooling_total")] - data[("gas", "heating_total")] self.add_field( name=("gas", "cooling_net"), sampling_type="cell", function=_net_cool, units=cooling_function_units, )