def spSpec_loader(file_obj, **kwargs): """ Loader for SDSS-I/II spSpec files. Parameters ---------- file_obj: str, file-like, or HDUList FITS file name, object (provided from name by Astropy I/O Registry), or HDUList (as resulting from astropy.io.fits.open()). Returns ------- data: Spectrum1D The spectrum that is represented by the wavelength solution from the header WCS and data array of the primary HDU. """ with read_fileobj_or_hdulist(file_obj, **kwargs) as hdulist: header = hdulist[0].header # name = header.get('NAME') meta = {'header': header} wcs = WCS(header).dropaxis(1) bunit = header.get('BUNIT', '1e-17 erg / (Angstrom cm2 s)') # fix mutilated flux unit bunit = bunit.replace('/cm/s/Ang', '/ (Angstrom cm2 s)') if 'Ang' in bunit and 'strom' not in bunit: bunit = bunit.replace('Ang', 'Angstrom') flux_unit = Unit(bunit) flux = hdulist[0].data[0, :] * flux_unit uncertainty = StdDevUncertainty(hdulist[0].data[2, :] * flux_unit) # Fix the WCS if it is claimed to be linear if header.get('DC-Flag', 1) == 1: fixed_wcs = _sdss_wcs_to_log_wcs(wcs) else: fixed_wcs = wcs mask = hdulist[0].data[3, :] != 0 return Spectrum1D(flux=flux, wcs=fixed_wcs, uncertainty=uncertainty, meta=meta, mask=mask)
def __init__(self, wavelengths=None, transmissions=None): """ This function ... :param wavelengths: :param transmissions: :return: """ # Column names names = ["Wavelength", "Transmission"] # Create the table if wavelengths is None or transmissions is None: self.table = Table(names=names, dtype=('f8', 'f8')) else: self.table = tables.new([wavelengths, transmissions], names) # Set column units self.table["Wavelength"].unit = Unit("micron")
def __init__( self, default=None, description="", unit=None, ucd=None, dtype=None, ndim=None, allow_none=True, ): self.default = default self.description = description self.unit = Unit(unit) if unit is not None else None self.ucd = ucd self.dtype = np.dtype(dtype) if dtype is not None else None self.ndim = ndim self.allow_none = allow_none
def test_psf_map_from_gauss_const_sigma(): energy_axis = MapAxis.from_nodes([1, 3, 10], name="energy_true", interp="log", unit="TeV") rad = np.linspace(0, 1.5, 100) * u.deg rad_axis = MapAxis.from_nodes(rad, name="rad", unit="deg") # with constant sigma psfmap = PSFMap.from_gauss(energy_axis, rad_axis, sigma=0.1 * u.deg) assert psfmap.psf_map.geom.axes[0] == rad_axis assert psfmap.psf_map.geom.axes[1] == energy_axis assert psfmap.psf_map.unit == Unit("sr-1") assert psfmap.psf_map.data.shape == (3, 100, 1, 2) radius = psfmap.containment_radius(energy_true=[1, 3, 10] * u.TeV, fraction=0.394) assert_allclose(radius, 0.1 * u.deg, rtol=0.01)
def unit(self, value): from . import conf try: if self._unit is not None and conf.warn_setting_unit_directly: log.info('Setting the unit directly changes the unit without ' 'updating the data or uncertainty. Use the ' '.convert_unit_to() method to change the unit and ' 'scale values appropriately.') except AttributeError: # raised if self._unit has not been set yet, in which case the # warning is irrelevant pass if value is None: self._unit = None else: self._unit = Unit(value)
def test_make_edisp_map(): energy_axis = MapAxis( nodes=[0.2, 0.7, 1.5, 2.0, 10.0], unit="TeV", name="energy_true", node_type="edges", interp="log", ) migra_axis = MapAxis(nodes=np.linspace(0.0, 3.0, 51), unit="", name="migra") edmap = make_edisp_map_test() assert edmap.edisp_map.geom.axes[0] == migra_axis assert edmap.edisp_map.geom.axes[1] == energy_axis assert edmap.edisp_map.unit == Unit("") assert edmap.edisp_map.data.shape == (4, 50, 5, 5)
def simple_generic_loader(file_name, **kwargs): name = os.path.basename(file_name.name.rstrip(os.sep)).rsplit('.', 1)[0] hdulist = fits.open(file_name, **kwargs) header = hdulist[0].header tab = Table.read(file_name) meta = {'header': header} wcs = WCS(hdulist[0].header) unit = Unit('Jy') uncertainty = StdDevUncertainty(tab["err"]) data = tab["flux"] hdulist.close() return Spectrum1DRef(data=data, name=name, wcs=wcs, uncertainty=uncertainty, unit=unit, meta=meta)
def get_quantity(entry, default_unit=None): """ This function ... :param entry: :param default_unit: :return: """ splitted = entry.split() value = float(splitted[0]) try: unit = splitted[1] except IndexError: unit = default_unit # Create a quantity object and return it if unit is not None: value = value * Unit(unit) return value
def _map_transforms_from_table_header(self, table_name): """ create any transforms needed to "undo" ones in the writer """ tab = self._tables[table_name] attrs = tab.attrs._f_list() for attr in attrs: if attr.endswith("_UNIT"): colname = attr[:-5] tr = QuantityColumnTransform(unit=Unit(tab.attrs[attr])) self.add_column_transform(table_name, colname, tr) elif attr.endswith("_ENUM"): colname = attr[:-5] tr = EnumColumnTransform(tab.attrs[attr]) self.add_column_transform(table_name, colname, tr) elif attr.endswith("_TIME_SCALE"): colname, _, _ = attr.rpartition("_TIME_SCALE") scale = tab.attrs[attr] time_format = get_hdf5_attr(tab.attrs, colname + "_TIME_FORMAT", "mjd") transform = TimeColumnTransform(scale=scale, format=time_format) self.add_column_transform(table_name, colname, transform) elif attr.endswith("_TRANSFORM_SCALE"): colname, _, _ = attr.rpartition("_TRANSFORM_SCALE") tr = FixedPointColumnTransform( scale=tab.attrs[attr], offset=get_hdf5_attr(tab.attrs, colname + "_TRANSFORM_OFFSET", 0), source_dtype=get_hdf5_attr(tab.attrs, colname + "_TRANSFORM_DTYPE", "float32"), target_dtype=tab.dtype[colname].base, ) self.add_column_transform(table_name, colname, tr) elif attr.endswith("_TRANSFORM"): colname, _, _ = attr.rpartition("_TRANSFORM") if tab.attrs[attr] == "string": maxlen = tab.attrs[f"{colname}_MAXLEN"] tr = StringTransform(maxlen) self.add_column_transform(table_name, colname, tr)
def from_fitspectrum_json(cls, filename, model=0): import json with open(filename) as fh: data = json.load(fh) val = data['fit_functions']['fit_functions'][model] e_range = (val['energy_min'], val['energy_max']) energy_range = EnergyBounds(e_range, 'TeV') spectral_model = val['type'] parameters = Bunch() parameters_errors = Bunch() for par in val['parameters']: pname = par['name'] if pname == 'Index': unit = Unit('') name = 'index' elif pname == 'Norm': unit = val['norm_scale'] * Unit('cm-2 s-1 TeV-1') name = 'norm' elif pname == 'E0': unit = Unit('TeV') name = 'reference' elif pname == 'Alpha': unit = Unit('') name = 'alpha' elif pname == 'Beta': unit = Unit('') name = 'beta' else: raise ValueError('Unkown Parameter: {}'.format(pname)) parameters[name] = par['value'] * unit parameters_errors[name] = par['error'] * unit fluxes = Bunch() fluxes['1TeV'] = val['flux_at_1'] * Unit('cm-2 s-1 TeV-1') flux_errors = Bunch() flux_errors['1TeV'] = val['flux_at_1_err'] * Unit('cm-2 s-1 TeV-1') return cls(fit_range=energy_range, parameters=parameters, parameter_errors=parameters_errors, spectral_model=spectral_model, fluxes=fluxes, flux_errors=flux_errors)
def fluxdensity_to_luminosity(fluxdensity, wavelength, distance): """ This function ... :param fluxdensity: :param wavelength: :param distance: :return: """ luminosity = (fluxdensity * 4. * math.pi * distance**2.).to("W/Hz") # 3 ways: #luminosity_ = luminosity.to("W/micron", equivalencies=spectral_density(wavelength)) # does not work luminosity_ = (speed_of_light * luminosity / wavelength**2).to("W/micron") luminosity = luminosity.to("W/Hz").value * spectral_factor_hz_to_micron( wavelength) * Unit("W/micron") #print(luminosity_, luminosity) # is OK! return luminosity
def test_make_psf_map(): psf = fake_psf3d(0.3 * u.deg) pointing = SkyCoord(0, 0, unit="deg") energy_axis = MapAxis( nodes=[0.2, 0.7, 1.5, 2.0, 10.0], unit="TeV", name="energy_true" ) rad_axis = MapAxis(nodes=np.linspace(0.0, 1.0, 51), unit="deg", name="theta") geom = WcsGeom.create( skydir=pointing, binsz=0.2, width=5, axes=[rad_axis, energy_axis] ) psfmap = make_psf_map(psf, pointing, geom) assert psfmap.psf_map.geom.axes[0] == rad_axis assert psfmap.psf_map.geom.axes[1] == energy_axis assert psfmap.psf_map.unit == Unit("sr-1") assert psfmap.psf_map.data.shape == (4, 50, 25, 25)
def parse_unit(argument, density=False, brightness=False, density_strict=False, brightness_strict=False): """ This function ... :param argument: :param density: :param brightness: :param density_strict: :param brightness_strict: :return: """ from .unit import PhotometricUnit try: unit = PhotometricUnit(argument, density=density, brightness=brightness, density_strict=density_strict, brightness_strict=brightness_strict) except ValueError: if types.is_string_type(argument): argument = clean_unit_string(argument) unit = Unit(argument) return unit
def unit(self, unit): """ This function ... :param unit: :return: """ # Convert string units to Astropy unit objects if isinstance(unit, basestring): unit = Unit(unit) # Loop over all frames for frame_name in self.frames: # Inform the user log.debug("Setting the unit of the " + frame_name + " frame to " + str(unit) + " ...") # Set the unit for this frame self.frames[frame_name].unit = unit
def flux_for_band(self, instrument, band, unit=None, add_unit=True): """ This function ... :param instrument: :param band: :param unit: :param add_unit: :return: """ has_unit = self.table["Flux"].unit is not None has_mask = hasattr(self.table["Flux"], "mask") # If unit has to be converted, check whether the original unit is specified if not has_unit and unit is not None: raise ValueError( "Cannot determine the unit of the flux column so values cannot be converted to " + str(unit)) # Loop over all the entries in the table for i in range(len(self.table)): instrument_entry = self.table["Instrument"][i] band_entry = self.table["Band"][i] if not (instrument_entry == instrument and band_entry == band): continue if has_unit: # Add the unit initially to be able to convert flux = self.table["Flux"][i] * self.table["Flux"].unit # If a target unit is specified, convert if unit is not None: flux = flux.to(unit).value * Unit(unit) if not add_unit: flux = flux.value else: flux = self.table["Flux"][i] return flux # If no match is found, return None return None
def plot_spectra(what="flux"): import matplotlib.pyplot as plt plt.clf() e = np.logspace(-2, 3, 100) for reference in crab.CRAB_REFERENCES: if what == 'flux': y = Unit('TeV').to('erg') * e**2 * crab.crab_flux(e, reference) elif what == 'int_flux': # @todo there are integration problems! e2 = 1e4 * np.ones_like(e) y = crab.crab_integral_flux(e, e2, reference=reference) if what == 'ratio': y = (crab.crab_flux(e, reference) / crab.crab_flux(e, 'meyer')) elif what == 'index': y = crab.crab_spectral_index(e, reference) plt.plot(e, y, label=reference) plt.xlabel('Energy (TeV)') if what == 'int_flux': plt.ylabel('Integral Flux (cm^-2 s^-1)') plt.ylim(1e-15, 1e-8) plt.loglog() filename = 'crab_int_flux.pdf' elif what == 'flux': plt.ylabel('Flux (erg cm^-2 s^-1)') plt.ylim(1e-12, 1e-9) plt.loglog() filename = 'crab_flux.pdf' elif what == 'ratio': plt.ylabel('Flux Ratio wrt. Meyer') plt.ylim(1e-1, 1e1) plt.loglog() filename = 'crab_ratio.pdf' elif what == 'index': plt.ylabel('Flux (erg cm^-2 s^-1)') plt.ylim(1, 5) plt.semilogx() filename = 'crab_index.pdf' plt.grid(which='both') plt.legend(loc='best') plt.savefig(filename)
def sixdfgs_tabular_fits_loader(file_obj, **kwargs): """ Load the tabular variant of a 6dF Galaxy Survey (6dFGS) file. 6dFGS used the Six-degree Field instrument on the UK Schmidt Telescope (UKST) at the Siding Spring Observatory (SSO) near Coonabarabran, Australia. Further details can be found at http://www.6dfgs.net/, or https://docs.datacentral.org.au/6dfgs/. Catalogues and spectra were produced, with the spectra being provided as both fits tables and as fits images. This loads the tabular variant of the spectra. Note that this does not include uncertainties - uncertainties are only provided in the image variants. Parameters ---------- file_obj: str, file-like or HDUList FITS file name, object (provided from name by Astropy I/O Registry), or HDUList (as resulting from astropy.io.fits.open()). Returns ------- data: Spectrum1D The 6dF spectrum that is represented by the data in this table. """ if isinstance(file_obj, fits.hdu.hdulist.HDUList): hdulist = file_obj else: hdulist = fits.open(file_obj, **kwargs) header = hdulist[0].header table = Table.read(hdulist) flux = Quantity(table["FLUX"]) wavelength = Quantity(table["WAVE"]) if flux.unit == COUNTS_PER_SECOND: flux._unit = Unit("count/s") meta = {"header": header} if not isinstance(file_obj, fits.hdu.hdulist.HDUList): hdulist.close() return Spectrum1D(flux=flux, spectral_axis=wavelength, meta=meta)
def Keplerian1D(x, mass=1., v0=0., r0=0.): """Computes the Keplerian velocity at requested distances from a massive object. Args: x (array_like): Distances to the central object. mass (float, optional): Mass of the central object in solar masses. v0 (float, optional): Velocity offset or systemic velocity. r0 (float, optional): Position offset, the position of the central object. Returns: v (np.ndarray): Keplerian velocity at the positions x. """ v = np.sign(x - r0) * np.sqrt(const.G * mass * const.M_sun / np.abs(x - r0) / Unit('AU')).to('km/ s').value + v0 return v
def test_make_psf_map(): psf = fake_psf3d(0.3 * u.deg) pointing = SkyCoord(0, 0, unit='deg') energy_axis = MapAxis(nodes=[0.2, 0.7, 1.5, 2., 10.], unit='TeV', name='energy_true') rad_axis = MapAxis(nodes=np.linspace(0., 1., 51), unit='deg', name='theta') geom = WcsGeom.create(skydir=pointing, binsz=0.2, width=5, axes=[rad_axis, energy_axis]) psfmap = make_psf_map(psf, pointing, geom, 3 * u.deg) assert psfmap.psf_map.geom.axes[0] == rad_axis assert psfmap.psf_map.geom.axes[1] == energy_axis assert psfmap.psf_map.unit == Unit('sr-1') assert psfmap.data.shape == (4, 50, 25, 25)
def magnitude_to_flux(self, magnitude): """Convert magnitudes to flux values. Args: magnitude (int, float, or Quantity): Magnitude value Returns: flux (Quantity): Brightness converted into flux units. """ if isinstance(magnitude, (int, float, np.ndarray)): return 10**(magnitude / -2.5) * self.band_reference_flux elif isinstance(magnitude, Quantity): if magnitude.unit != Unit('mag'): raise SpecklepyValueError('magnitude_to_flux()', 'magnitude unit', magnitude.unit, 'mag') else: return 10**(magnitude.value / -2.5) * self.band_reference_flux
def _info_flux_points(self): """Print flux point results""" d = self.data ss = '\n*** Flux points info ***\n\n' ss += 'Number of flux points: {}\n'.format(d['N_Flux_Points']) ss += 'Flux points table: \n\n\t' flux_points = self.flux_points.table.copy() flux_points = flux_points[['e_ref', 'dnde', 'dnde_errn', 'dnde_errp']] flux_points['e_ref'].format = '.3f' flux_unit = Unit('1e-12 cm-2 s-1 TeV-1') for _ in ['dnde', 'dnde_errp', 'dnde_errn']: flux_points[_] = flux_points[_].to(flux_unit) flux_points[_].format = '.3f' flux_points[_].unit = flux_unit # convert table to string ss += '\n\t'.join(flux_points.pformat(-1)) return ss + '\n'
def __init__(self, value, uncertainty, unit=None): if isinstance(value, self.__class__): self._uncertainty = value.uncertainty else: if isinstance(value, Quantity): if unit is not None: raise ValueError('cannot use the unit argument when ' '`value` is a Quantity') else: self._unit = (dimensionless_unscaled if unit is None else Unit(unit)) if hasattr(uncertainty, 'unit'): if (uncertainty.unit != dimensionless_unscaled and self._unit != dimensionless_unscaled): try: uncertainty = uncertainty.to(self._unit) except: raise UnitsError('cannot convert unit of uncertainty ' 'to unit of the `Data` instance') if (self._unit == dimensionless_unscaled and uncertainty.unit != dimensionless_unscaled): raise UnitsError('cannot assign an uncertainty with units ' 'to a `Data` instance without a unit') uncertainty = Uncertainty(uncertainty) else: uncertainty = Uncertainty(uncertainty, self._unit) if uncertainty.size != self.size: raise ValueError('uncertainty must have the same shape as ' 'the `Data` instance') self._uncertainty = uncertainty self._uncertainty.parent_data = self
def aspcapStar_loader(file_obj, **kwargs): """ Loader for APOGEE aspcapStar files. Parameters ---------- file_obj: str or file-like FITS file name or object (provided from name by Astropy I/O Registry). Returns ------- data: Spectrum1D The spectrum that is represented by the data in this table. """ if isinstance(file_obj, fits.hdu.hdulist.HDUList): close_hdulist = False hdulist = file_obj else: close_hdulist = True hdulist = fits.open(file_obj, **kwargs) header = hdulist[0].header meta = {'header': header} wcs = WCS(hdulist[1].header) data = hdulist[1].data # spectrum in the first extension unit = def_unit('arbitrary units') uncertainty = StdDevUncertainty(hdulist[2].data) # dispersion from the WCS but convert out of logspace dispersion = 10**wcs.all_pix2world(np.arange(data.shape[0]), 0)[0] dispersion_unit = Unit('Angstrom') if close_hdulist: hdulist.close() return Spectrum1D(data=data * unit, uncertainty=uncertainty, spectral_axis=dispersion * dispersion_unit, meta=meta, wcs=wcs)
def get_wave_unit(tag, hdulist, idx=None): """ Attempt to pull wavelength unit from the Table Parameters ---------- tag : str Tag used for wavelengths hdulist : fits header data unit list idx : int, optional Index of list for Table input Returns ------- unit : astropy Unit Defaults to None """ from astropy.units import Unit if idx is None: idx = 1 # Use Table if isinstance(hdulist[idx], BinTableHDU): tab = Table(hdulist[idx].data) header = hdulist[idx].header else: # NEED HEADER INFO return None # Try table header (following VLT/X-Shooter here) keys = list(header) # Python 3 values = list(itervalues(header)) # Python 3 hidx = values.index(tag) if keys[hidx][0:5] == 'TTYPE': try: tunit = header[keys[hidx].replace('TYPE', 'UNIT')] except KeyError: return None else: if tunit in ['Angstroem', 'Angstroms', 'ANGSTROMS']: tunit = 'Angstrom' unit = Unit(tunit) return unit else: return None
def crab_flux(energy=1, reference=CRAB_DEFAULT_REFERENCE): """Differential Crab flux. See the ``gammapy.spectrum.crab`` module docstring for a description of the available reference spectra. Parameters ---------- energy : array_like Energy (TeV) reference : {{'hegra', 'hess_pl', 'hess_ecpl', 'meyer'}} Published Crab reference spectrum Returns ------- flux : array Differential flux (cm^-2 s^-1 TeV^-1) at ``energy`` """ if reference == 'hegra': f = hegra['diff_flux'] g = hegra['index'] return f * energy**(-g) elif reference == 'hess_pl': f = hess_pl['diff_flux'] g = hess_pl['index'] return f * energy**(-g) elif reference == 'hess_ecpl': f = hess_ecpl['diff_flux'] g = hess_ecpl['index'] e_c = hess_ecpl['cutoff'] return f * energy**(-g) * np.exp(-energy / e_c) elif reference == 'meyer': # Meyer et al., 2010arXiv1008.4524M, Appendix D p = np.array( [-0.00449161, 0, 0.0473174, -0.179475, -0.53616, -10.2708]) log_energy = np.log10(np.asarray(energy)) log_flux = np.poly1d(p)(log_energy) flux = 10**log_flux return Unit('erg').to('TeV') * flux / energy**2 else: raise ValueError('Unknown reference: {0}'.format(reference))
def project_azimuth_to_pa(azimuth, inclination): """ This function ... :param azimuth: :param inclination: """ # Get the azimuth angle and inclination in radians azimuth_radian = azimuth.to("radian").value i_radian = inclination.to("radian").value denominator = math.sqrt( math.cos(azimuth_radian)**2 * math.cos(i_radian)**2 + math.sin(azimuth_radian)**2) cos_pa = math.cos(azimuth_radian) * math.cos(i_radian) / denominator sin_pa = math.sin(azimuth_radian) / denominator pa_radian = math.atan2(sin_pa, cos_pa) * Unit("radian") return pa_radian.to("deg")
def fwhms(self): """ This function ... :return: """ # Initialize a list to contain the fwhm of the fitted stars fwhms = [] # Loop over all stars for star in self.stars: # If the star contains a model, add the fwhm of that model to the list if star.has_model: fwhm_pix = star.fwhm * Unit("pix") fwhm_arcsec = fwhm_pix * self.frame.average_pixelscale.to( "arcsec/pix") fwhms.append(fwhm_arcsec) # Return the list return fwhms
def _summary_flux_points(self): """Print flux point results""" d = self.data ss = '\n*** Flux points info ***\n\n' ss += 'Number of flux points: {}\n'.format(d['N_Flux_Points']) ss += 'Flux points table: \n\n\t' flux_points = self.flux_points['ENERGY', 'DIFF_FLUX', 'DIFF_FLUX_ERR_HI', 'DIFF_FLUX_ERR_LO'][:int(d['N_Flux_Points'])] flux_points['ENERGY'].format = '.3f' flux_unit = Unit('1E-12 cm^-2 s^-1 TeV^-1') for _ in ['DIFF_FLUX', 'DIFF_FLUX_ERR_HI', 'DIFF_FLUX_ERR_LO']: flux_points[_] = flux_points[_].to(flux_unit) flux_points[_].format = '.3f' flux_points[_].unit = flux_unit # convert table to string ss += '\n\t'.join(flux_points.pformat(-1)) return ss + '\n'
def generic_spectrum1d_loader(file_name, **kwargs): name = os.path.basename(file_name.rstrip(os.sep)).rsplit('.', 1)[0] hdulist = fits.open(file_name, **kwargs) header = hdulist[0].header meta = {'header': header} wcs = WCS(hdulist[0].header) unit = Unit('Jy') uncertainty = StdDevUncertainty(hdulist[3].data) data = hdulist[1].data mask = hdulist[2].data hdulist.close() return MOSSpectrum2D(data=data, name=name, wcs=wcs, uncertainty=uncertainty, unit=unit, meta=meta, mask=mask)
def __init__(self): path = os.path.dirname(pyfoxsi.__file__) for i in np.arange(3): path = os.path.dirname(path) path = os.path.join(path, 'data/') filename = 'shell_parameters.csv' params_file = os.path.join(path, filename) self.shell_params = pd.read_csv(params_file, index_col=0) the_units = [ Unit(this_unit) for this_unit in self.shell_params.loc[np.nan].values ] self.units = {} for i, col in enumerate(self.shell_params): self.units.update({col: the_units[i]}) self.shell_params.drop(self.shell_params.index[0], inplace=True) missing_shells = np.setdiff1d(self.shell_params.index, pyfoxsi.shell_ids) self.shell_params.drop(missing_shells) for col in self.shell_params.columns: self.shell_params[col] = self.shell_params[col].astype(float)