def test_name_from_coord(): coord = SkyCoord(ra=15.4, dec=-23.1, unit='deg') name = ltu.name_from_coord(coord) assert name == 'J010136.00-230600.0' # Name 2 name2 = ltu.name_from_coord(coord, precision=(0, 0)) assert name2 == 'J010136-230600'
def main(pargs): """ Run """ import json from linetools import utils as ltu from frb import frb # Load frb_name = pargs.frb_name if pargs.frb_name[:3].upper() == 'FRB' else 'FRB'+pargs.frb_name try: FRB = frb.FRB.by_name(frb_name.upper()) except FileNotFoundError: print("Your desired FRB is not in this Repo. Sorry..") return def pjson(obj): return json.dumps(obj, sort_keys=True, indent=4, separators=(',', ': ')) # Coords print("=========================================================\n") print(frb_name) print(ltu.name_from_coord(FRB.coord, precision=(4,4)), '\n ra,dec = {:0.7f},{:0.7f} deg'.format(FRB.coord.ra.value, FRB.coord.dec.value)) print('sig_a = {:0.3f} arcsec'.format(FRB.sig_a)) print('sig_b = {:0.3f} arcsec'.format(FRB.sig_b)) print('PA = {:0.1f} deg'.format(FRB.eellipse['theta'])) print('') print('DM={}'.format(FRB.DM)) print('Repeater={}'.format(FRB.repeater)) if pargs.verbose: print('ee={}'.format(pjson(FRB.eellipse))) print('DM_ISM(ne2001)={:0.1f}'.format(FRB.DMISM)) # Host hg = FRB.grab_host() if hg is not None: print("") print("=========================================================\n") print("Host\n") print(ltu.name_from_coord(hg.coord)) print('z: \n {}'.format(pjson(hg.redshift))) if pargs.verbose: # photometry print('photom: \n {}'.format(pjson(hg.photom))) print('derived: \n {}'.format(pjson(hg.derived))) print('morphology: \n {}'.format(pjson(hg.morphology))) print('neb_lines: \n {}'.format(pjson(hg.neb_lines)))
def __init__(self, radec, sl_type=None, em_type=None, comment=None, name=None, **kwargs): """ Initiator Parameters ---------- radec : tuple or SkyCoord (RA,DEC) in deg or astropy.coordinate.SkyCoord sl_type : str, optional Sightline type, e.g. IGM em_type : str, optional Type of emission source for absorption sightline, e.g. QSO comment : str, optional A comment, default is `` name : str, optional Name of the sightline, e.g. '3C273' """ # Required self.coord = ltu.radec_to_coord(radec) # Lists self._components = [] # Name if name is None: self.name = ltu.name_from_coord(self.coord) else: self.name = name # Others self.em_type = em_type self.sl_type = sl_type self._abssystems = None # Saving the namespace for future usage
def __init__(self, radec, sl_type='', em_type='', comment=None, name=None, **kwargs): """ Initiator Parameters ---------- radec : tuple or SkyCoord (RA,DEC) in deg or astropy.coordinate.SkyCoord sl_type : str, optional Sightline type, e.g. IGM em_type : str, optional Type of emission source for absorption sightline, e.g. QSO comment : str, optional A comment, default is `` name : str, optional Name of the sightline, e.g. '3C273' """ # Required self.coord = ltu.radec_to_coord(radec) # Lists self._components = [] # Name if name is None: self.name = ltu.name_from_coord(self.coord) else: self.name = name # Others self.em_type = em_type self.sl_type = sl_type self._abssystems = [] # Saving the namespace for future usage
def plot_spec(specDB, meta, frb=None): import numpy as np from astropy.coordinates import SkyCoord from linetools import utils as ltu """ Plot galaxy spectra """ # Grab spectra spec = specDB.spectra_from_meta(meta) # Add labels lbls = ['None'] * len(meta) ugroups = np.unique(meta['GROUP']) for ugroup in ugroups: rows = np.where(meta['GROUP'] == ugroup)[0] coords = SkyCoord(ra=meta['RA_GROUP'][rows], dec=meta['DEC_GROUP'][rows], unit='deg') if frb is None: for kk, row, imeta in zip(range(len(rows)), rows, meta): # JNAME jname = ltu.name_from_coord(coords[kk]) lbls[row] = '{:s}_{:s}'.format(jname, meta['INSTR'][row]) else: seps = frb.coord.separation(coords).to('arcsec') pas = frb.coord.position_angle(coords).to('deg') for row, sep, pa, imeta in zip(rows, seps, pas, meta): # Separation and PA lbls[row] = '{:s}_{:s}_{:d}_{:d}'.format( frb.frb_name, meta['INSTR'][row], int(pa.value), int(sep.value)) spec.labels = lbls # Add object type spec.stypes = ['Galaxy'] * len(lbls) # Add redshift spec.z = meta['zem_GROUP'] # Plot spec.plot(xspec=True) #, scale=1.5)
def __init__(self, radec, igal_rand=10, iabs_rand=100, proper=False, field_name='', wrapped=True, cosmo=None, **kwargs): IgmGalaxyField.__init__(self, radec, **kwargs) self.igal_rand = igal_rand self.iabs_rand = iabs_rand self.absreal = None # absreal # np rec array with absorber properties (single ion) self.absrand = None # Cosmology if cosmo is None: cosmo = Planck15 self.cosmo = cosmo # Central coordiantes self.CRA = self.coord.ra.value #np.mean(self.absreal.RA) self.CDEC = self.coord.dec.value # np.mean(self.absreal.DEC) if len(field_name) == 0: self.name = ltu.name_from_coord(self.coord) else: self.name = field_name self.proper = proper self.wrapped = wrapped self.galreal = None # Filled with addGal self.absreal = None # Filled with addAbs self.ion = None
def plot_spec(specDB, meta, frb, dust_correct=False): import numpy as np from astropy.coordinates import SkyCoord from linetools import utils as ltu from frb.galaxies import nebular """ Plot galaxy spectra """ # Grab spectra spec = specDB.spectra_from_meta(meta) # Dust? if dust_correct: import extinction EBV = nebular.get_ebv(frb.coord)['meanValue'] # AV = EBV * 3.1 # RV for kk in range(spec.nspec): spec.select = kk Al = extinction.fm07(spec.wavelength.value, AV)#, 3.1) spec.flux = spec.flux * 10 ** (Al / 2.5) spec.sig = spec.sig * 10 ** (Al / 2.5) # Add labels lbls = ['None']*len(meta) ugroups = np.unique(meta['GROUP']) for ugroup in ugroups: rows = np.where(meta['GROUP'] == ugroup)[0] coords = SkyCoord(ra=meta['RA_GROUP'][rows], dec=meta['DEC_GROUP'][rows], unit='deg') if frb is None: for kk, row, imeta in zip(range(len(rows)), rows, meta): # JNAME jname = ltu.name_from_coord(coords[kk]) lbls[row]='{:s}_{:s}'.format(jname, meta['INSTR'][row]) else: seps = frb.coord.separation(coords).to('arcsec') pas = frb.coord.position_angle(coords).to('deg') for row, sep, pa, imeta in zip(rows, seps, pas, meta): # Separation and PA lbls[row]='{:s}_{:s}_{:d}_{:d}'.format(frb.frb_name, meta['INSTR'][row], int(pa.value), int(sep.value)) spec.labels = lbls # Add object type spec.stypes = ['Galaxy']*len(lbls) # Add redshift spec.z = meta['zem_GROUP'] # Plot spec.plot(xspec=True)#, scale=1.5)
def generate(image, wcs, title, flip_ra=False, flip_dec=False, log_stretch=False, cutout=None, primary_coord=None, secondary_coord=None, third_coord=None, slit=None, vmnx=None, extra_text=None, outfile=None): """ Basic method to generate a Finder chart figure Args: image (np.ndarray): Image for the finder wcs (astropy.wcs.WCS): WCS solution title (str): Title; typically the name of the primary source flip_ra (bool, default False): Flip the RA (x-axis). Useful for southern hemisphere finders. flip_dec (bool, default False): Flip the Dec (y-axis). Useful for southern hemisphere finders. log_stretch (bool, optional): Use a log stretch for the image display cutout (tuple, optional): SkyCoord (center coordinate) and Quantity (image angular size) for a cutout from the input image. primary_coord (astropy.coordinates.SkyCoord, optional): If provided, place a mark in red at this coordinate secondary_coord (astropy.coordinates.SkyCoord, optional): If provided, place a mark in cyan at this coordinate Assume it is an offset star (i.e. calculate offsets) third_coord (astropy.coordinates.SkyCoord, optional): If provided, place a mark in yellow at this coordinate slit (tuple, optional): If provided, places a rectangular slit with specified coordinates, width, length, and position angle on image (from North to East) [SkyCoords('21h44m25.255s',-40d54m00.1s', frame='icrs'), 1*u.arcsec, 10*u.arcsec, 20*u.deg] vmnx (tuple, optional): Used for scaling the image. Otherwise, the image is analyzed for these values. extra_text : str Extra text to be added at the bottom of the Figure. e.g. `DSS r-filter` outfile (str, optional): Filename for the figure. File type will be according to the extension Returns: matplotlib.pyplot.figure, matplotlib.pyplot.Axis """ utils.set_mplrc() plt.clf() fig = plt.figure(figsize=(7, 8.5)) # fig.set_size_inches(7.5,10.5) # Cutout? if cutout is not None: cutout_img = Cutout2D(image, cutout[0], cutout[1], wcs=wcs) # Overwrite wcs = cutout_img.wcs image = cutout_img.data # Axis ax = fig.add_axes([0.10, 0.20, 0.75, 0.5], projection=wcs) # Show if log_stretch: norm = mplnorm.ImageNormalize(stretch=LogStretch()) else: norm = None cimg = ax.imshow(image, cmap='Greys', norm=norm) # Flip so RA increases to the left if flip_ra is True: ax.invert_xaxis() if flip_dec is True: ax.invert_yaxis() # N/E overlay = ax.get_coords_overlay('icrs') overlay['ra'].set_ticks(color='white') overlay['dec'].set_ticks(color='white') overlay['ra'].set_axislabel('Right Ascension') overlay['dec'].set_axislabel('Declination') overlay.grid(color='green', linestyle='solid', alpha=0.5) # Contrast if vmnx is None: mean, median, stddev = sigma_clipped_stats( image ) # Also set clipping level and number of iterations here if necessary # vmnx = (median - stddev, median + 2 * stddev ) # sky level - 1 sigma and +2 sigma above sky level print("Using vmnx = {} based on the image stats".format(vmnx)) cimg.set_clim(vmnx[0], vmnx[1]) # Add Primary if primary_coord is not None: c = SphericalCircle((primary_coord.ra, primary_coord.dec), 2 * units.arcsec, transform=ax.get_transform('icrs'), edgecolor='red', facecolor='none') ax.add_patch(c) # Text jname = ltu.name_from_coord(primary_coord) ax.text(0.5, 1.34, jname, fontsize=28, horizontalalignment='center', transform=ax.transAxes) # Secondary if secondary_coord is not None: c_S1 = SphericalCircle((secondary_coord.ra, secondary_coord.dec), 2 * units.arcsec, transform=ax.get_transform('icrs'), edgecolor='cyan', facecolor='none') ax.add_patch(c_S1) # Text jname = ltu.name_from_coord(secondary_coord) ax.text(0.5, 1.24, jname, fontsize=22, color='blue', horizontalalignment='center', transform=ax.transAxes) # Print offsets if primary_coord is not None: sep = primary_coord.separation(secondary_coord).to('arcsec') PA = primary_coord.position_angle(secondary_coord) # RA/DEC dec_off = np.cos(PA) * sep # arcsec ra_off = np.sin(PA) * sep # arcsec (East is *higher* RA) ax.text( 0.5, 1.22, 'Offset from Ref. Star (cyan) to Target (red):\nRA(to targ) = {:.2f} DEC(to targ) = {:.2f}' .format(-1 * ra_off.to('arcsec'), -1 * dec_off.to('arcsec')), fontsize=15, horizontalalignment='center', transform=ax.transAxes, color='blue', va='top') # Add tertiary if third_coord is not None: c = SphericalCircle((third_coord.ra, third_coord.dec), 2 * units.arcsec, transform=ax.get_transform('icrs'), edgecolor='yellow', facecolor='none') ax.add_patch(c) # Slit if ((slit is not None) and (flag_photu is True)): # List of values - [coodinates, width, length, PA], # e.g. [SkyCoords('21h44m25.255s',-40d54m00.1s', frame='icrs'), 1*u.arcsec, 10*u.arcsec, 20*u.deg] slit_coords, width, length, pa = slit pa_deg = pa.to('deg').value aper = SkyRectangularAperture( positions=slit_coords, w=length, h=width, theta=pa ) # For theta=0, width goes North-South, which is slit length apermap = aper.to_pixel(wcs) apermap.plot(color='purple', lw=1) plt.text(0.5, -0.1, 'Slit PA={} deg'.format(pa_deg), color='purple', fontsize=15, ha='center', va='top', transform=ax.transAxes) if ((slit is not None) and (flag_photu is False)): raise IOError('Slit cannot be placed without photutils package') # Title ax.text(0.5, 1.44, title, fontsize=32, horizontalalignment='center', transform=ax.transAxes) # Extra text if extra_text is not None: ax.text(-0.1, -0.25, extra_text, fontsize=20, horizontalalignment='left', transform=ax.transAxes) # Sources # Labels #ax.set_xlabel(r'\textbf{DEC (EAST direction)}') #ax.set_ylabel(r'\textbf{RA (SOUTH direction)}') if outfile is not None: plt.savefig(outfile) plt.close() else: plt.show() # Return return fig, ax
def generate(image, wcs, title, log_stretch=False, cutout=None, primary_coord=None, secondary_coord=None, third_coord=None, vmnx=None, outfile=None): """ Basic method to generate a Finder chart figure Args: image (np.ndarray): Image for the finder wcs (astropy.wcs.WCS): WCS solution title (str): TItle; typically the name of the primry source log_stretch (bool, optional): Use a log stretch for the image display cutout (tuple, optional): SkyCoord (center coordinate) and Quantity (image angular size) for a cutout from the input image. primary_coord (astropy.coordinates.SkyCoord, optional): If provided, place a mark in red at this coordinate secondary_coord (astropy.coordinates.SkyCoord, optional): If provided, place a mark in cyan at this coordinate Assume it is an offset star (i.e. calculate offsets) third_coord (astropy.coordinates.SkyCoord, optional): If provided, place a mark in yellow at this coordinate vmnx (tuple, optional): Used for scaling the image. Otherwise, the image is analyzed for these values. outfile (str, optional): Filename for the figure. File type will be according to the extension Returns: matplotlib.pyplot.figure, matplotlib.pyplot.Axis """ utils.set_mplrc() plt.clf() fig = plt.figure(dpi=600) fig.set_size_inches(7.5, 10.5) # Cutout? if cutout is not None: cutout_img = Cutout2D(image, cutout[0], cutout[1], wcs=wcs) # Overwrite wcs = cutout_img.wcs image = cutout_img.data # Axis ax = fig.add_axes([0.10, 0.20, 0.80, 0.5], projection=wcs) # Show if log_stretch: norm = mplnorm.ImageNormalize(stretch=LogStretch()) else: norm = None cimg = ax.imshow(image, cmap='Greys', norm=norm) # Flip so RA increases to the left ax.invert_xaxis() # N/E overlay = ax.get_coords_overlay('icrs') overlay['ra'].set_ticks(color='white') overlay['dec'].set_ticks(color='white') overlay['ra'].set_axislabel('Right Ascension') overlay['dec'].set_axislabel('Declination') overlay.grid(color='green', linestyle='solid', alpha=0.5) # Contrast if vmnx is None: mean, median, stddev = sigma_clipped_stats( image ) # Also set clipping level and number of iterations here if necessary # vmnx = (median - stddev, median + 2 * stddev ) # sky level - 1 sigma and +2 sigma above sky level print("Using vmnx = {} based on the image stats".format(vmnx)) cimg.set_clim(vmnx[0], vmnx[1]) # Add Primary if primary_coord is not None: c = SphericalCircle((primary_coord.ra, primary_coord.dec), 2 * units.arcsec, transform=ax.get_transform('icrs'), edgecolor='red', facecolor='none') ax.add_patch(c) # Text jname = ltu.name_from_coord(primary_coord) ax.text(0.5, 1.34, jname, fontsize=28, horizontalalignment='center', transform=ax.transAxes) # Secondary if secondary_coord is not None: c_S1 = SphericalCircle((secondary_coord.ra, secondary_coord.dec), 2 * units.arcsec, transform=ax.get_transform('icrs'), edgecolor='cyan', facecolor='none') ax.add_patch(c_S1) # Text jname = ltu.name_from_coord(secondary_coord) ax.text(0.5, 1.24, jname, fontsize=22, color='blue', horizontalalignment='center', transform=ax.transAxes) # Print offsets if primary_coord is not None: sep = primary_coord.separation(secondary_coord).to('arcsec') PA = primary_coord.position_angle(secondary_coord) # RA/DEC dec_off = np.cos(PA) * sep # arcsec ra_off = np.sin(PA) * sep # arcsec (East is *higher* RA) ax.text(0.5, 1.14, 'RA(to targ) = {:.2f} DEC(to targ) = {:.2f}'.format( -1 * ra_off.to('arcsec'), -1 * dec_off.to('arcsec')), fontsize=18, horizontalalignment='center', transform=ax.transAxes) # Add tertiary if third_coord is not None: c = SphericalCircle((third_coord.ra, third_coord.dec), 2 * units.arcsec, transform=ax.get_transform('icrs'), edgecolor='yellow', facecolor='none') ax.add_patch(c) # Slit? ''' if slit is not None: r = Rectangle((primary_coord.ra.value, primary_coord.dec.value), slit[0]/3600., slit[1]/3600., angle=360-slit[2], transform=ax.get_transform('icrs'), facecolor='none', edgecolor='red') ax.add_patch(r) ''' # Title ax.text(0.5, 1.44, title, fontsize=32, horizontalalignment='center', transform=ax.transAxes) # Sources # Labels #ax.set_xlabel(r'\textbf{DEC (EAST direction)}') #ax.set_ylabel(r'\textbf{RA (SOUTH direction)}') if outfile is not None: plt.savefig(outfile) plt.close() else: plt.show() # Return return fig, ax
def write_to_igmguesses(self, outfile, fwhm=3., specfilename=None, creator=None, instrument='unknown', altname='unknown', date=None, overwrite=False): import json """ Writes an IGMGuesses formatted JSON file Parameters ---------- outfile : str Name of the IGMGuesses JSON file to write to. fwhm : int FWHM for IGMguesses specfilename : str Name of the spectrum file these guesses are associated to. altname : str Alternative name for the sightline. e.g. 3C273 creator : str Name of the person who is creating the file. Important for tracking. instrument : str String indicating the instrument and its configuration associated to the specfilename. e.g. HST/COS/G130M+G160M/LP2 overwrite : bool Wthether to overwrite output Returns ------- """ import datetime # Slurp IGMGuesses component attributes from pyigm.guis.igmguesses import comp_init_attrib from linetools.isgm.abscomponent import AbsComponent tmp = AbsComponent((10.0 * u.deg, 45 * u.deg), (14, 2), 1.0, [-300, 300] * u.km / u.s) comp_init_attrib(tmp) igmg_akeys = list(tmp.attrib.keys()) # components comp_list = self._components coord_ref = comp_list[0].coord if date is None: date = str(datetime.date.today().strftime('%Y-%b-%d')) # spec_file, meta if hasattr(self, 'igmg_dict'): spec_file = self.igmg_dict['spec_file'] meta = self.igmg_dict['meta'] # Updates meta['Date'] = date if creator is not None: meta['Creator'] = creator # fwhm = self.igmg_dict['fwhm'] else: spec_file = specfilename # coordinates and meta RA = coord_ref.ra.to('deg').value DEC = coord_ref.dec.to('deg').value jname = ltu.name_from_coord(coord_ref, precision=(2, 1)) if self.zem is None: zem = 0. # IGMGuesses rules else: zem = self.zem if creator is None: creator = 'unknown' meta = { 'RA': RA, 'DEC': DEC, 'ALTNAME': altname, 'zem': zem, 'Creator': creator, 'Instrument': instrument, 'Date': date, 'JNAME': jname } # Create dict of the components out_dict = dict(cmps={}, spec_file=spec_file, fwhm=fwhm, bad_pixels=[], meta=meta) for comp in comp_list: key = comp.name out_dict['cmps'][key] = comp.to_dict() # import pdb; pdb.set_trace() # check coordinate if comp.coord != coord_ref: raise ValueError( "All AbsComponent objects must have the same coordinates!") out_dict['cmps'][key]['zcomp'] = comp.zcomp # IGMGuesses specific component attr for igm_key in [ 'zfit', 'Nfit', 'bfit', 'wrest', 'mask_abslines', 'vlim' ]: out_dict['cmps'][key][igm_key] = comp.igmg_attrib['top_level'][ igm_key] # IGMGuesses attribute dict out_dict['cmps'][key]['attrib'] = {} for igm_key in igmg_akeys: try: out_dict['cmps'][key]['attrib'][ igm_key] = comp.igmg_attrib[igm_key] except KeyError: out_dict['cmps'][key]['attrib'][igm_key] = comp.attrib[ igm_key] #out_dict['cmps'][key]['vlim'] = list(comp.vlim.value) out_dict['cmps'][key]['reliability'] = str(comp.reliability) out_dict['cmps'][key]['comment'] = str(comp.comment) # Compatability on sig_logN out_dict['cmps'][key]['attrib']['sig_logN'] = comp.attrib[ 'sig_logN'][0] # JSONify gd_dict = ltu.jsonify(out_dict) # Write file ltu.savejson(outfile, gd_dict, overwrite=overwrite, sort_keys=True, indent=4, separators=(',', ': ')) print('Wrote: {:s}'.format(outfile))