def apokasc_load(combine=True): """ NAME: apokasc_load PURPOSE: load apokasc result (Precise surface gravity measurement) INPUT: combine (boolean): True to combine gold snd basic standard OUTPUT: HISTORY: 2017-Dec-23 - Written - Henry Leung (University of Toronto) """ catalog_list = Vizier.find_catalogs('apokasc') Vizier.ROW_LIMIT = 99999 catalogs_gold = Vizier.get_catalogs(catalog_list.keys())[1] catalogs_basic = Vizier.get_catalogs(catalog_list.keys())[2] gold_ra = catalogs_gold['_RA'] gold_dec = catalogs_gold['_DE'] gold_logg = catalogs_gold['log_g_'] basic_ra = catalogs_basic['_RA'] basic_dec = catalogs_basic['_DE'] basic_logg = catalogs_basic['log.g2'] if combine is True: ra = np.append(np.array(gold_ra), np.array(basic_ra)) dec = np.append(np.array(gold_dec), np.array(basic_dec)) logg = np.append(np.array(gold_logg), np.array(basic_logg)) return ra, dec, logg else: return gold_ra, gold_dec, gold_logg, basic_ra, basic_dec, basic_logg
def load_apokasc(combine=True): """ Load APOKASC asteroseismic surface gravity measurement :param combine: True to combine gold and basic standard, otherwise only get gold standard log(g) :type combine: boolean :return: numpy array of ra, dec, array :rtype: ndarrays :History: | 2017-Dec-23 - Written - Henry Leung (University of Toronto) """ catalog_list = Vizier.find_catalogs('apokasc') Vizier.ROW_LIMIT = 99999 catalogs_gold = Vizier.get_catalogs(catalog_list.keys())[1] catalogs_basic = Vizier.get_catalogs(catalog_list.keys())[2] gold_ra = catalogs_gold['_RA'] gold_dec = catalogs_gold['_DE'] gold_logg = catalogs_gold['log_g_'] basic_ra = catalogs_basic['_RA'] basic_dec = catalogs_basic['_DE'] basic_logg = catalogs_basic['log.g2'] if combine is True: ra = np.append(np.array(gold_ra), np.array(basic_ra)) dec = np.append(np.array(gold_dec), np.array(basic_dec)) logg = np.append(np.array(gold_logg), np.array(basic_logg)) return ra, dec, logg else: return gold_ra, gold_dec, gold_logg, basic_ra, basic_dec, basic_logg
def get_vizier_table_as_dataframe(vizier_search_str, srccolumns, dstcolumns, table_num=0, verbose=1, whichcataloglist='default'): """ Download a table from Vizier (specified by `vizier_search_str`). Get columns specified by the |-separated string, `columns`. Write the resulting table to a CSV file, `outcsvpath`. Sometimes, the table number on Vizier (`table_num`) must be specified. In the context of CDIPS catalog construction, this is mostly for making "source|cluster|age" output. Args: vizier_search_str (str): specifies Vizier search. srccolumns (str): columns in the Vizier catalog to get e.g., "RA|DE|age" dstcolumns (str): columns to rename them to, e.g., "ra|dec|log10age". whichcataloglist (str): "default", else a string to specify the catalog, e.g., ""J/A+A/640/A1"" """ Vizier.ROW_LIMIT = -1 catalog_list = Vizier.find_catalogs(vizier_search_str) if whichcataloglist == 'default': catalogs = Vizier.get_catalogs(catalog_list.keys()) else: catalogs = Vizier.get_catalogs(whichcataloglist) tab = catalogs[table_num] if verbose: print(f'initial number of members: {len(tab)}') df = tab.to_pandas() # rename columns to homogeneous format. e.g., # df = df.rename(columns={"Gaia": "source_id", "Group": "cluster"}) df = df.rename( columns={ k:v for k,v in zip(srccolumns.split("|"), dstcolumns.split("|")) } ) if 'source_id' in dstcolumns.split("|"): # strip "Gaia DR2 6083332579305755520" style format if present try: if np.any(df.source_id.str.contains('Gaia DR2 ')): df['source_id'] = df.source_id.str.replace('Gaia DR2 ', '') except AttributeError: pass # if NaNs are present, omit them. (e.g., from EsplinLuhman19) if np.any(pd.isnull(df.source_id)): N = len(df[pd.isnull(df.source_id)]) print(f'WRN! Found {N} null source_id values of {len(df)}. Omitting.') df = df[~pd.isnull(df.source_id)] df['source_id'] = df['source_id'].astype('int64') sdf = df[dstcolumns.split("|")] return sdf
def query_ids_1(inp_ids, catalog="II/246", radius=1.0 * u.arcsecond, verbose=True): # "" # NOTEBOOK: "01_read_opf_cats" [/sample_initial/] # "Level-1 code to perform multiple VizieR searches" # "" # 1) Construct Dummy Row =========== Vizier.ROW_LIMIT = 1 cat_0 = Vizier.get_catalogs(catalog) dummy_tb = cat_0[0] dummy_tb['_r'] = 0 dummy_tb['dummy'] = 'Y' Vizier.ROW_LIMIT = -1 # 2) Construct Seed Table ========== viz_tb = dummy_tb.copy() # 3) Add rows to Seed Table ======== for inp in inp_ids: result = sample_initial.query_ids_0(inp, catalog=catalog, radius=radius, verbose=verbose) viz_tb = vstack([viz_tb, Table(result)]) viz_tb = viz_tb[viz_tb['dummy'] != 'Y'] viz_tb['_r'] = viz_tb['_r'].to(u.arcsecond) viz_tb['_r'].format = '3.2f' viz_tb.sort('inp_id') return viz_tb
def get_catalog(params, map_struct): cat, = Vizier.get_catalogs('J/ApJS/199/26/table3') completeness = 0.5 alpha = -1.0 MK_star = -23.55 MK_max = MK_star + 2.5 * np.log10(gammaincinv(alpha + 2, completeness)) z = (u.Quantity(cat['cz']) / c.c).to(u.dimensionless_unscaled) MK = cat['Ktmag'] - cosmo.distmod(z) keep = (z > 0) & (MK < MK_max) cat = cat[keep] z = z[keep] r = cosmo.luminosity_distance(z).to('Mpc').value theta = 0.5 * np.pi - cat['DEJ2000'].to('rad').value phi = cat['RAJ2000'].to('rad').value ipix = hp.ang2pix(map_struct["nside"], theta, phi) if "distnorm" in map_struct: dp_dV = map_struct["prob"][ipix] * map_struct["distnorm"][ipix] * norm( map_struct["distmu"][ipix], map_struct["distsigma"][ipix]).pdf(r) / map_struct["pixarea"] top50 = cat[np.flipud(np.argsort(dp_dV))][:50] else: top50 = cat[np.flipud(np.argsort(map_struct["prob"][ipix]))][:50] catalogfile = os.path.join(params["outputDir"], 'catalog.dat') top50['RAJ2000', 'DEJ2000', 'Ktmag'].write(catalogfile, format='ascii') return top50
def get_tess_limb_darkening_guesses(teff, logg): ''' Given Teff and log(g), query the Claret+2017 limb darkening coefficient grid. Return the nearest match. TODO: interpolate instead of doing the nearest match. Nearest match is good to maybe only ~200 K and ~0.3 in log(g). ''' if not vizier_dependency: raise ImportError('This function requires astroquery.' 'Try: `conda install -c astropy astroquery`') # Assume solar metallicity. metallicity = 0 # Get the Claret quadratic priors for TESS bandpass. The table below is # good from Teff = 1500 - 12000K, logg = 2.5 to 6. We choose values # computed with the "r method", see # http://vizier.u-strasbg.fr/viz-bin/VizieR-n?-source=METAnot&catid=36000030¬id=1&-out=text if not 2300 < teff < 12000: if teff < 15000: LOGWARNING( 'using 12000K atmosphere LD coeffs even tho teff={}'.format( teff)) else: LOGERROR('got teff error') if not 2.5 < logg < 6: if teff < 15000: # Rough guess: assume star is B6V, Pecaut & Mamajek (2013) table. _Mstar = 4 * units.Msun _Rstar = 2.9 * units.Rsun logg = np.log10((const.G * _Mstar / _Rstar**2).cgs.value) else: LOGERROR('got logg error') Vizier.ROW_LIMIT = -1 catalog_list = Vizier.find_catalogs('J/A+A/600/A30') catalogs = Vizier.get_catalogs(catalog_list.keys()) t = catalogs[1] sel = (t['Type'] == 'r') df = t[sel].to_pandas() # Each Teff has 8 tabulated logg values. First, find the best teff match. foo = df.iloc[(df['Teff'] - teff).abs().argsort()[:8]] # Then, among those best 8, get the best logg match. bar = foo.iloc[(foo['logg'] - logg).abs().argsort()].iloc[0] # TODO: should probably determine these coefficients by INTERPOLATING. # (especially in cases when you're FIXING them, rather than letting them # float). LOGWARNING('skipping interpolation for Claret coefficients.') LOGWARNING('data logg={:.3f}, teff={:.1f}'.format(logg, teff)) LOGWARNING('Claret logg={:.3f}, teff={:.1f}'.format( bar['logg'], bar['Teff'])) u_linear = bar['aLSM'] u_quad = bar['bLSM'] return float(u_linear), float(u_quad)
def main(): path = os.path.dirname(os.path.abspath(__file__)) sne_table = ascii.read(os.path.join(path, 'Pantheon.FITRES')) sne_table = sne_table[sne_table['RA'] != 0] vizier = Vizier(row_limit=2000) mcxc_table = vizier.get_catalogs('J/A+A/534/A109/mcxc')[0] namespace = parser().parse_args(sys.argv[1:]) sep = namespace.sep z = namespace.z table = crossmatch(catalog1=sne_table, catalog2=mcxc_table, colRA1='RA', colDec1='DECL', colZ1='zCMB', colRA2='RAJ2000', colDec2='DEJ2000', colZ2='z', max_sep=sep, use_z=z) final_table = table['CID', 'MCXC', 'RAJ2000', 'RA', 'DEJ2000', 'DECL', 'DELTA_Z'] final_table['CID'].name, final_table['MCXC'].name = 'SN name', 'Cluster' ascii.write(final_table, os.path.join(path, 'CrossTable.csv'), format='csv', overwrite=True)
def OS_from_viz(viz_ID, file_name, extraCols=['default'], GUI_name='default', GUI_path='default', use_redshift='OFF'): from astroquery.vizier import Vizier v = Vizier() v.ROW_LIMIT = -1 Cats = v.get_catalogs(viz_ID) grbCat = Cats[0] grbAstroCat = Table(grbCat) global colNames colNames = ["RAJ2000", "DEJ2000"] if extraCols == ['default']: otherCols(grbAstroCat) else: for i in range(len(extraCols)): colNames.append(extraCols[i]) hasDistance(grbAstroCat, use_redshift) deleteCols(grbAstroCat) # global viz_key viz_key = 1996 global vizID vizID = viz_ID #guiforasset = GUI_name files2ops.createFiles(grbAstroCat, file_name, GUI_name, GUI_path, "Vizier:" + viz_ID)
def download_furlan_radius_correction_table(): # Furlan et al 2017 catalog_list = Vizier.find_catalogs('J/AJ/153/71') print({k: v.description for k, v in catalog_list.items()}) Vizier.ROW_LIMIT = -1 f17_tablelist = Vizier.get_catalogs(catalog_list.keys()) companiontab = f17_tablelist[-1] df = companiontab.to_pandas() for colname in ['KOI', 'Nc', 'Nobs']: df[colname] = df[colname].astype(int) # Assume planet orbits primary; this is lower bound on contamination. # Therefore it's weaker than assuming the planet orbits the next-brightest # companion. However, it's what Petigura+ 2018 did. (Probably b/c the converse # would throw out too many). df = df[df['Orbit'] == b'primary'] outname = '../data/Furlan_2017_table9.csv' df.to_csv(outname, index=False) print('saved to {:s}'.format(outname))
def _load(self, filename): raw = Vizier.get_catalogs('VII/26D')[0] if FILTER_DWARFS: raw = raw[raw['UGC'] != 10822] # Draco (UGC 10822) raw = raw[raw['UGC'] != 9749] # Ursa Minor (UGC 9749) raw = raw[raw['UGC'] != 5470] # Leo I (UGC 5470) raw = raw[raw['UGC'] != 6253] # Leo II (UGC 6253) self.data.resize(len(raw)) self.data['name'] = np.char.mod('UGC %s', raw['UGC']) ra = np.array([map(float, hms.split()) for hms in raw['RA1950']]) dec = np.array([map(float, dms.split()) for dms in raw['DE1950']]) ra = np.vstack([ra.T, np.zeros(len(raw))]).T dec = np.vstack([dec.T, np.zeros(len(raw))]).T ra1950 = ugali.utils.projector.hms2dec(ra) dec1950 = ugali.utils.projector.dms2dec(dec) ra2000, dec2000 = ugali.utils.idl.jprecess(ra1950, dec1950) self.data['ra'] = ra2000 self.data['dec'] = dec2000 self.data[ 'radius'] = raw['MajAxis'] / 60.0 # Major axis on POSS blue print # Could also use minor axis 'MinAxis' (no position angle given) glon, glat = cel2gal(self.data['ra'], self.data['dec']) self.data['glon'], self.data['glat'] = glon, glat
def __init__(self, *attributes): self.attributes = attributes Vizier.ROW_LIMIT = -1 dias_catalog = Vizier.get_catalogs('/B/ocl/clusters') if attributes == (): self.table = dias_catalog['B/ocl/clusters'] else: self.table = dias_catalog['B/ocl/clusters'][attributes]
def build_constellation_boundary_database(): print() print("Creating constellation boundary database") db = SkyMapDatabase() db.drop_table("skymap_constellation_boundaries") db.create_table( "skymap_constellation_boundaries", ["ra1", "dec1", "ra2", "dec2"], [float, float, float, float], ) # Retrieve data from Vizier print() print("Retrieving data from Vizier") Vizier.ROW_LIMIT = -1 catalog = Vizier.get_catalogs("VI/49") constbnd = catalog["VI/49/constbnd"] print() print("Building edges from {} points".format(len(constbnd))) prev_hash = None edges = [] for row in constbnd: if not row["adj"]: prev_hash = None current_hash = point_hash(row["RAB1875"], row["DEB1875"]) if prev_hash is not None: e = QuickEdge(prev_hash, current_hash) if e not in edges: edges.append(e) prev_hash = current_hash print() print("Connecting {} edges".format(len(edges))) for i, e1 in enumerate(edges): for e2 in edges[i + 1 :]: e1.connect(e2) print() print("Building extended edges") new_edges = [] for i, e in enumerate(edges): new_edge = e.extended_edge if new_edge not in new_edges: new_edges.append(new_edge) print() print(f"Loading {len(new_edges)} edges to database") for i, e in enumerate(new_edges): db.insert_row( "skymap_constellation_boundaries", ["ra1", "dec1", "ra2", "dec2"], e.coordinates, )
def make_Rizzuto15_GaiaDR2_crossmatch(): ''' Aaron Rizzuto et al (2015) picked out ~400 candidate USco members, then surveyed them for Li absorption. Led to 237 spectroscopically confirmed members. see http://vizier.cfa.harvard.edu/viz-bin/VizieR?-source=J/MNRAS/448/2737 ''' Vizier.ROW_LIMIT = -1 catalog_list = Vizier.find_catalogs('J/MNRAS/448/2737') catalogs = Vizier.get_catalogs(catalog_list.keys()) cands = catalogs[0] usco_pms = catalogs[1] # pre-MS stars in USco usco_disk = catalogs[2] # members of USco w/ circumstellar disk c = SkyCoord([ra.replace(' ',':') for ra in list(map(str,usco_pms['RAJ2000']))], [de.replace(' ',':') for de in list(map(str,usco_pms['DEJ2000']))], unit=(u.hourangle, u.deg)) usco_pms['RA'] = c.ra.value usco_pms['DEC'] = c.dec.value usco_pms.remove_column('RAJ2000') usco_pms.remove_column('DEJ2000') foo = usco_pms.to_pandas() outname = '../data/cluster_data/moving_groups/Rizzuto_15_table_2_USco_PMS.csv' foo.to_csv(outname,index=False) print('saved {:s}'.format(outname)) c = SkyCoord([ra.replace(' ',':') for ra in list(map(str,usco_disk['RAJ2000']))], [de.replace(' ',':') for de in list(map(str,usco_disk['DEJ2000']))], unit=(u.hourangle, u.deg)) usco_disk['RA'] = c.ra.value usco_disk['DEC'] = c.dec.value usco_disk.remove_column('RAJ2000') usco_disk.remove_column('DEJ2000') foo = usco_disk.to_pandas() outname = os.path.join(datadir, 'Rizzuto_15_table_3_USco_hosts_disk.csv') foo.to_csv(outname,index=False) print('saved {:s}'.format(outname)) print( ''' I then uploaded these lists to MAST, and used their spatial cross-matching with a 3 arcsecond cap, following https://archive.stsci.edu/tess/tutorials/upload_list.html This crossmatch is the output that I then saved to '../results/Rizzuto_15_table_2_USco_PMS_GaiaDR2_crossmatched_2arcsec_MAST.csv' '../results/Rizzuto_15_table_3_USco_disks_GaiaDR2_crossmatched_2arcsec_MAST.csv' ''' )
def green_catalog_download(): # This allows easy access to Vizier tables: # https://astroquery.readthedocs.org/en/latest/vizier/vizier.html from astroquery.vizier import Vizier Vizier.ROW_LIMIT = -1 # This is the 2014-05 version of Green's catalog # http://vizier.u-strasbg.fr/viz-bin/VizieR?-source=VII/272 results = Vizier.get_catalogs(['VII/272']) table = results[0] return table
def __init__(self, *attributes, ra_0=0, dec_0=0, r_0=0.5, entire=False, galactic=False): """ Bruno Femenia Castella: in order to speed up calcularions it does not make sense to scan the whole catalog but only those clusters found within 1.5*r_0 [degs] around coordinates [ra_0, dec_0] """ self.attributes = attributes Vizier.ROW_LIMIT = -1 if entire: dias_catalog = Vizier.get_catalogs('B/ocl/clusters') else: center_coord = SkyCoord(ra=ra_0, dec=dec_0, unit=(u.deg, u.deg), frame='icrs') dias_catalog = Vizier.query_region(center_coord, radius=1.5 * r_0 * u.deg, catalog='B/ocl/clusters') if attributes == (): self.table = dias_catalog['B/ocl/clusters'] else: self.table = dias_catalog['B/ocl/clusters'][attributes] if galactic: nel = len(self.table) Col_l = Column(name='l', unit=u.deg, dtype=np.float32, description='Galactic longitude', length=nel) Col_b = Column(name='b', unit=u.deg, dtype=np.float32, description='Galactic latitude', length=nel) for i, row in enumerate(self.table): ra = Angle(row['RAJ2000'], unit=u.hourangle) dec = Angle(row['DEJ2000'], unit=u.deg) cl_radec = SkyCoord(ra, dec, frame='icrs') # ra_hms, dec_deg = parse_radec(row['RAJ2000'], row['DEJ2000']) # cl_radec=SkyCoord(ra_hms, dec_deg,frame='icrs') Col_l[i] = cl_radec.galactic.l.deg Col_b[i] = cl_radec.galactic.b.deg self.table.add_columns([Col_l, Col_b])
def make_Casagrande_11_GaiaDR2_crossmatch(): ''' Casagrande et al (2011) re-analyzed the Geneva-Copenhagen survey, and got a kinematically unbiased sample of solar neighborhood stars with kinematics, metallicites, and ages. If Casagrande's reported max likelihood ages (from Padova isochrones) are below 1 Gyr, then that's interesting enough to look into. NOTE that this age cut introduces serious biases into the stellar mass distribution -- see Casagrande+2011, Figure 14. http://vizier.cfa.harvard.edu/viz-bin/VizieR?-source=J/A+A/530/A138 ''' vizier_search_str = 'J/A+A/530/A138' table_num = 0 ra_str = 'RAJ2000' dec_str = 'DEJ2000' outname = os.path.join(datadir, 'Casagrande_2011_table_1_GCS_ages_lt_1Gyr.csv') Vizier.ROW_LIMIT = -1 catalog_list = Vizier.find_catalogs(vizier_search_str) catalogs = Vizier.get_catalogs(catalog_list.keys()) tab = catalogs[0] # ageMLP: max-likelihood padova isochrone ages # ageMLB: max-likelihood BASTI isochrone ages. not queried. sel = (tab['ageMLP'] > 0) sel &= (tab['ageMLP'] < 1) coords = SkyCoord(ra=tab[ra_str], dec=tab[dec_str], frame='icrs', unit=(u.hourangle, u.deg)) # MAST uploads need these two column names tab['RA'] = coords.ra.value tab['DEC'] = coords.dec.value tab.remove_column('RAJ2000') tab.remove_column('DEJ2000') foo = tab[sel].to_pandas() foo.to_csv(outname,index=False) print('saved {:s}'.format(outname)) print( ''' I then uploaded these lists to MAST, and used their spatial cross-matching with a 3 arcsecond cap, following https://archive.stsci.edu/tess/tutorials/upload_list.html This crossmatch is the output that I then saved to {:s} '''.format(outname.replace('data','results').replace('.csv','_GaiaDR2_3arcsec_crossmatch_MAST.csv')) )
def getRandomVizier(numResults): from astroquery.vizier import Vizier from astropy import units as u v = Vizier(columns=["all"], catalog='I/345/gaia2', column_filters={ "RandomI": "830339102..840339102", "e_Plx": "<0.1" }) v.ROW_LIMIT = numResults result = v.get_catalogs('I/345/gaia2') result[0].pprint() return result[0].keys(), result[0]
def get_k13_index(): # # the ~3784 row table # Vizier.ROW_LIMIT = -1 catalog_list = Vizier.find_catalogs('J/A+A/558/A53') catalogs = Vizier.get_catalogs(catalog_list.keys()) k13_index = catalogs[1].to_pandas() for c in k13_index.columns: if c != 'N': k13_index[c] = k13_index[c].str.decode('utf-8') return k13_index
def get_duncan_catalog(): """ Parameters ---------- Returns ------- """ global sindex_catalog if sindex_catalog is None: catalogs = Vizier.get_catalogs(duncan1991) sindex_catalog = catalogs[0] # This is the table with the data return sindex_catalog
def get_k2_epic_catalog(): """ Parameters ---------- Returns ------- """ global k2_epic_table if k2_epic_table is None: catalogs = Vizier.get_catalogs(huber2016) k2_epic_table = catalogs[0] # This is the table with the data k2_epic_table.add_index('EPIC') return k2_epic_table
def flux_star_type(mag, band, star_type, wvl, wvlBand): """ Calculates the flux over a custom wave band, for a given star of a given magnitude in one of the standard bands (I, H, J, etc.) Parameters: mag (float): magnitude in the band defined by "band" band (str): band in which the magnitude is expressed, can be B, J, H, K, L, M, N, R, I star_type (str): must be the full star type, i.e. "A0V" wvl (float): central wavelength in microns wvlBand (float): length of wavelength band in microns Returns: float: flux of photons (ph/m2/s) """ # get star spectrum, will correspond to a V=0 Vizier.ROW_LIMIT = -1 catalog = Vizier.get_catalogs('J/PASP/110/863/synphot')[0] pickles_index = numpy.where(catalog["SpType"] == star_type)[0][0] + 1 ftp = FTP('ftp.stsci.edu') ftp.login() ss = BytesIO() message = ftp.retrbinary('RETR cdbs/grid/pickles/dat_uvk/pickles_uk_' + str(pickles_index) + '.ascii', ss.write) ftp.quit() # spectrum is in erg/s/cm2/A, first column are wavelengths in A, second column is the spectrum erg_spec = numpy.asarray([numpy.asarray(row.split(' '), dtype='float') for row in str(ss.getvalue()).split("\\n")[39:-1]], dtype='float') wavelengths = erg_spec[:, 0] * 1e-4 # translate spectrum in photon/s/m2/micron phot_spec = erg_spec[:, 1] * wavelengths / (c.h.value * c.c.value) * 1e-5 # translate magnitude of band in V magV = get_magV(star_type, mag, band) # normalise spectrum to correspond to that magnitude fac = 10 ** (-magV / 2.5) norm_spec = phot_spec * fac # integrate over band ind = numpy.where((wavelengths >= wvl - wvlBand/2) & (wavelengths <= wvl + wvlBand/2)) selection = norm_spec[ind] flux = (numpy.sum(selection) - (selection[0] + selection[-1]) / 2) * \ numpy.mean(numpy.diff(wavelengths[ind])) return flux
def _load(self, filename): raw = Vizier.get_catalogs('J/MNRAS/389/678')[0] self.data.resize(len(raw)) self.data['name'] = np.char.strip(raw['Names']) ra = np.array([map(float, hms.split()) for hms in raw['RAJ2000']]) dec = np.array([map(float, dms.split()) for dms in raw['DEJ2000']]) self.data['ra'] = ugali.utils.projector.hms2dec(ra) self.data['dec'] = ugali.utils.projector.dms2dec(dec) self.data['radius'] = raw['amaj'] / 60.0 # Major axis # Could also use minor axis 'amin' and position angle 'PA' glon, glat = cel2gal(self.data['ra'], self.data['dec']) self.data['glon'], self.data['glat'] = glon, glat
def _load(self, filename): raw = Vizier.get_catalogs('J/AJ/144/4')[0] self.data.resize(len(raw)) self.data['name'] = raw['Name'] ra = np.array([map(float, hms.split()) for hms in raw['RAJ2000']]) dec = np.array([map(float, dms.split()) for dms in raw['DEJ2000']]) self.data['ra'] = ugali.utils.projector.hms2dec(ra) self.data['dec'] = ugali.utils.projector.dms2dec(dec) self.data[ 'radius'] = raw['R1'] / 60.0 # Half-light radius along major axis # Could also include elliticity 'Ell' and position angle 'PA' glon, glat = cel2gal(self.data['ra'], self.data['dec']) self.data['glon'], self.data['glat'] = glon, glat
def get_k13_param_table(): # # the ~3000 row table with determined parameters # cols = [ 'map', 'cmd', 'stars', 'Name', 'MWSC', 'Type', 'RAJ2000', 'DEJ2000', 'r0', 'r1', 'r2', 'pmRA', 'pmDE', 'RV', 'e_RV', 'o_RV', 'd', 'E_B-V_', 'logt', 'N1sr2', 'rc', 'rt', 'k', 'SType', '__Fe_H_', 'Simbad' ] v = Vizier(columns=cols) v.ROW_LIMIT = -1 catalog_list = v.find_catalogs('J/A+A/558/A53') catalogs = v.get_catalogs(catalog_list.keys()) k13 = catalogs[0].to_pandas() k13['Name'] = k13['Name'].str.decode('utf-8') return k13
def read_McLaughlin_vanderMarel2005_data(verbose=True): """ We present a database of structural and dynamical properties for 153 spatially resolved star clusters in the Milky Way, the Large and Small Magellanic Clouds, and the Fornax dwarf spheroidal. This database complements and extends others in the literature, such as those of Harris and Mackey & Gilmore. Our cluster sample comprises 50 young massive clusters in the LMC and SMC, and 103 old globular clusters between the four galaxies """ # This means that by excluding LMC, SMC data we automatically exclude # YMCs, thus, we should be left /w only GCs... # Am confused though, as to why catalog contains 216 items (not 153?) # Also, there's 0: clusters (10 cols/216 rows), 1: table5 (9 cols/4689 rows), # 2: models (17 cols/459 rows), 3: table13 (12 cols/67 rows) cat_name = "J/ApJS/161/304" if verbose: print("Retrieving Vizier catalog: '{0}'".format(cat_name)) Vizier.ROW_LIMIT = -1 # default 50. Now unlimited :) return Vizier.get_catalogs(cat_name)[0]
def get_soubiran_19_rv_table(): cols = [ 'ID', 'ID2', 'RA_ICRS', 'DE_ICRS', 'dmode', 'Nmemb', 'Nsele', 'RV', 'e_RV', 's_RV', 'X', 'e_X', 'Y', 'e_Y', 'Z', 'e_Z', 'U', 'e_U', 'V', 'e_V', 'W', 'e_W', 'Vr', 'e_Vr', 'Vphi', 'e_Vphi', 'Vz', 'e_Vz', 'Simbad' ] v = Vizier(columns=cols) v.ROW_LIMIT = -1 catalog_list = v.find_catalogs('J/A+A/619/A155') catalogs = v.get_catalogs(catalog_list.keys()) df = catalogs[0].to_pandas() df['ID'] = df['ID'].str.decode('utf-8') return df
def _load(self, filename): raw = Vizier.get_catalogs('J/A+A/558/A53') if FILTER_DWARFS: raw = [raw[0][raw[0]['MWSC'] != '2020'], raw[1], raw[2]] # Coma Berenices (Melotte_111) self.data.resize(len(raw[0])) ids = np.array(map(int, raw[0]['MWSC'])) - 1 self.data['name'] = raw[1]['Name'][ids] self.data['ra'] = raw[0]['RAJ2000'] self.data['dec'] = raw[0]['DEJ2000'] self.data['radius'] = raw[0]['r1'] # Radius of central part # Could also use core radius 'r0' or radius 'r2' glon, glat = cel2gal(self.data['ra'], self.data['dec']) self.data['glon'], self.data['glat'] = glon, glat
def CantatGaudin2019_velaOB2_to_csv(): # https://ui.adsabs.harvard.edu/abs/2019A%26A...626A..17C/abstract Vizier.ROW_LIMIT = -1 catalog_list = Vizier.find_catalogs('J/A+A/626/A17') catalogs = Vizier.get_catalogs(catalog_list.keys()) tab = catalogs[0] df = tab.to_pandas() outdf = df[['Source','Pop']] outdf = outdf.rename(columns={"Source": "source_id", "Pop": "cluster"}) # Quoting Tristan, discussing Fig3 from the paper: # """ # the clumps that are labeled are known "open clusters". The diffuse # stellar distribution in the middle and around was called the Vela OB2 # association, supposed to be in front of the clusters or maybe in # between, and everyone thought they were unrelated objects, different # age, different history. In the figure, the colour code indicates stars # that have the same age and velocity. # My conclusion is that there is no object that can be called "Vela OB2" # association. There are clusters, and a diffuse distribution of stars around # each cluster. And the sum of all those fluffy distributions is "the # association". Aggregates of young stars are so sub-structured that it # doesn't even make sense to label all the clumps, and it can even be # difficult to guess which clump observers referred to when they looked at # those regions in the 19th century. There are ongoing debates over whether # NGC 1746 exists, for instance. Which are the stars that were originally # classified as NGC 1746, and does it even matter? # """ outdf['cluster'] = np.core.defchararray.add( np.repeat('cg19velaOB2_pop', len(outdf)), nparr(outdf['cluster']).astype(str) ) outpath = os.path.join(clusterdatadir, 'moving_groups', 'CantatGaudin2019_velaOB2_MATCH.csv') outdf.to_csv(outpath, index=False) print('made {}'.format(outpath))
def _load(self, filename): catalog = Vizier.get_catalogs('VII/151') raw = astropy.table.vstack([catalog[0], catalog[2]], metadata_conflicts='silent') self.data.resize(len(raw)) self.data['name'] = np.char.join(' ', np.char.split(raw['Name1'])) ra = np.array([map(float, hms.split()) for hms in raw['RA1950']]) dec = np.array([map(float, dms.split()) for dms in raw['DE1950']]) dec = np.vstack([dec.T, np.zeros(len(raw))]).T ra1950 = ugali.utils.projector.hms2dec(ra) dec1950 = ugali.utils.projector.dms2dec(dec) ra2000, dec2000 = ugali.utils.idl.jprecess(ra1950, dec1950) self.data['ra'] = ra2000 self.data['dec'] = dec2000 self.data['radius'] = (10**np.array(raw['lgtt'])) / 60.0 # log(radius) # Could also use log(core radius) 'lgtc' glon, glat = cel2gal(self.data['ra'], self.data['dec']) self.data['glon'], self.data['glat'] = glon, glat
def get_glade(): if not os.path.isdir('catalogs/'): os.makedirs('catalogs/') catalogFile = os.path.join('catalogs/', "glade.hdf5") if not os.path.isfile(catalogFile): # Unset row limits when querying Vizier Vizier.ROW_LIMIT = -1 cat, = Vizier.get_catalogs('VII/281/glade2') ra, dec = cat["RAJ2000"], cat["DEJ2000"] distmpc, z, flag1 = cat["Dist"], cat["z"], cat["Flag1"] magb, BMAG = cat["Bmag"], cat["BMAG"] Jmag, Hmag, Kmag = cat["Jmag"], cat["Hmag"], cat['Kmag'] flag2, flag3 = cat["Flag2"], cat["Flag3"] # Keep track of galaxy identifier GWGC, PGC, HyperLEDA = cat["GWGC"], cat["PGC"], cat["HyperLEDA"] _2MASS, SDSS = cat["_2MASS"], cat["SDSS-DR12"] with h5py.File(catalogFile, 'w') as f: f.create_dataset('ra', data=ra) f.create_dataset('dec', data=dec) f.create_dataset('distmpc', data=distmpc) f.create_dataset('Flag1', data=flag1) f.create_dataset('magb', data=magb) f.create_dataset('BMAG', data=BMAG) f.create_dataset('Jmag', data=Jmag) f.create_dataset('Hmag', data=Hmag) f.create_dataset('Kmag', data=Kmag) f.create_dataset('Flag2', data=flag2) f.create_dataset('Flag3', data=flag3) f.create_dataset('z', data=z) # Add galaxy identifier f.create_dataset('GWGC', data=GWGC) f.create_dataset('PGC', data=PGC) f.create_dataset('HyperLEDA', data=HyperLEDA) f.create_dataset('2MASS', data=_2MASS) f.create_dataset('SDSS', data=SDSS)
def download_catalog(self): """ Downloads the flare catalog using Vizier. The flare catalog is named 'Guenther_2020_flare_catalog.txt'. The star catalog is named 'Guenther_2020_star_catalog.txt'. Attributes ---------- flare_table : astropy.table.Table Flare catalog that was downloaded. """ Vizier.ROW_LIMIT = -1 catalog_list = Vizier.find_catalogs('TESS flares sectors') catalogs = Vizier.get_catalogs(catalog_list.keys()) self.flare_table = catalogs[1] self.flare_table.rename_column('_tab2_5', 'tpeak') self.flare_table.write(os.path.join(self.fn_dir, self.flare_catalog_name), format='csv') return
def main(): """Main function""" import argparse parser = argparse.ArgumentParser(description="Create a starlist of UKIRT Faint Stanadards") parser.add_argument("-o", "--output", type=argparse.FileType("w"), default="-", help="Output file") parser.add_argument("--fs", action='store_false', dest='full', help="Collect FS stars only") opt = parser.parse_args() date = datetime.datetime.now().isoformat() try: from astroquery.vizier import Vizier except ImportError as e: parser.error("Requires 'astroquery' to be installed.\n{0!r}".format(e)) table = Vizier.get_catalogs([VIZIER_UKIRT_FS_CATALOG])[0] tl = TargetList([row_to_target(row) for row in table if (str(row['SimbadName'].decode('ascii')).startswith("FS") or opt.full)]) tl.sort(key = lambda t : t.position.ra) # Write a header for the starlist so that we know the source. opt.output.write("# UKIRT Faint Standard Stars\n") opt.output.write("# Data from VIZIER catalog '{0:s}'\n".format(VIZIER_UKIRT_FS_CATALOG)) opt.output.write("# ADS Reference: '{0:s}'\n".format(VIZIER_ADS_REFERENCE)) opt.output.write("# Data collected on {0:s}\n".format(date)) tl.to_starlist(opt.output)
Save both a png and a pdf version of the image """ pl.savefig(p3(savename.replace("pdf","png")), **kwargs) pl.savefig(p3(savename.replace("png","pdf")), **kwargs) zoomargs = {'x': 49.31, 'y':-0.35, 'width': 0.55, 'height':0.34} # copied from projection_figures zoomargs = {'x': 49.23, 'y': -0.28, 'width':1, 'height':0.5} zoomargs = dict(x=49.27, y=-0.32, width=0.9, height=0.4) for fignum in (1,2,3): if pl.fignum_exists(fignum): pl.close(fignum) Vizier.ROW_LIMIT = 999999 ysos = Vizier.get_catalogs('J/ApJ/706/83/ysos')['J/ApJ/706/83/ysos'] masers = Vizier.query_region('W51', radius='2 deg', catalog='J/A+A/291/261/table1')['J/A+A/291/261/table1'] masers2 = Vizier.query_region('W51', radius='2 deg', catalog='J/MNRAS/418/1689/table2')['J/MNRAS/418/1689/table2'] radec = [coordinates.SkyCoord(r,d,unit=('deg','deg'),frame='icrs') for r,d in zip(masers2['RAJ2000'],masers2['DEJ2000'])] glon,glat = np.array(zip(*[(rd.galactic.l.degree, rd.galactic.b.degree) for rd in radec])) # Added 5/23/2014 mask = fits.getdata(p1('mask_h2co_signal.fits')) for suffix,extrastr in ((".fits",""), ):#("_prefiltered.fits", "filtered")): parcubefile = fits.open(p1('W51_taucube_fit_parcube_try11'+suffix))
class S4G(Configurable): """ This class ... """ def __init__(self, *args, **kwargs): """ The constructor ... :param kwargs: """ # Call the constructor of the base class super(S4G, self).__init__(*args, **kwargs) # The inclination self.inclination = None # The galaxy properties object self.properties = None # The dictionary of components self.components = dict() # The Vizier service self.vizier = None # ----------------------------------------------------------------- def _run(self, **kwargs): """ This function ... :return: """ # 2. Get galaxy properties self.get_properties() # 3. Get the components self.get_components() # 4. Show if self.config.show: self.show() # 5. Writing if self.config.write: self.write() # ----------------------------------------------------------------- def setup(self, **kwargs): """ This function ... :param kwargs: :return: """ # Call the setup function of the base class super(S4G, self).setup(**kwargs) # Get the inclination self.inclination = kwargs.pop("inclination", None) # Create the galaxy properties object self.properties = GalaxyProperties() self.properties.name = self.config.galaxy_name # Get the NGC name of the galaxy self.properties.ngc_name = self.ngc_name # ----------------------------------------------------------------- @lazyproperty def ngc_name(self): """ This function ... :return: """ return catalogs.get_ngc_name(self.config.galaxy_name) # ----------------------------------------------------------------- @property def ngc_name_nospaces(self): """ This function ... :return: """ return self.ngc_name.replace(" ", "") # ----------------------------------------------------------------- def get_properties(self): """ This function ... :return: """ # Inform the user log.info("Getting the galaxy properties ...") # S4G self.get_s4g_properties() # To first order, cos i = b/a where a & b # are the observed major and minor # axes (assume disk is intrinsically # circular) # But this implies galaxies have zero # thickness at i = 90°! Better to assume # that spirals are oblate ellipsoids with # intrinsic axis ratios a:a:c. If q = c/a, # then after a bit a simple geometry # cos^2(i) = [ (b/a)^2 - q^2 ] / (1-q^2) # The best fit to observed spirals yields # q = 0.13 for Sc galaxies # Ellipticity (1-b/a) # b_to_a = 1. - self.properties.ellipticity # # # Calculate the inclination # inclination_deg = 90. - math.degrees(math.acos(b_to_a)) # inclination = Angle(inclination_deg, "deg") # # # Check the inclination # if self.inclination is not None: # difference = abs(self.inclination - inclination) # rel_difference = difference / self.inclination # if rel_difference > 0.1: # log.warning("The inclination angle calculated based on the decomposition differs by " + str(rel_difference*100) + "% from the specified inclination") # # # Set the incliantion # self.properties.inclination = inclination # ----------------------------------------------------------------- def get_s4g_properties(self): """ This function ... :return: """ # Inform the user log.info("Querying the S4G catalog ...") # The Vizier querying object, specifying the necessary columns for this class self.vizier = Vizier(columns=['Name', 'RAJ2000', 'DEJ2000', 'Dmean', 'e_Dmean', 'amaj', 'ell', '[3.6]', '[4.5]', 'e_[3.6]', 'e_[4.5]', 'PA']) self.vizier.ROW_LIMIT = -1 # Get parameters from S4G catalog result = self.vizier.query_object(self.config.galaxy_name, catalog=["J/PASP/122/1397/s4g"]) table = result[0] # Galaxy name for S4G catalog self.properties.name = table["Name"][0] # Galaxy center from decomposition (?) ra_center = table["RAJ2000"][0] dec_center = table["DEJ2000"][0] center = SkyCoordinate(ra=ra_center, dec=dec_center, unit="deg", frame='fk5') self.properties.center = center # Center position #self.properties.center = SkyCoordinate(ra=self.info["RA"][0], dec=self.info["DEC"][0], unit="deg") # center position from DustPedia # Distance self.properties.distance = table["Dmean"][0] * u("Mpc") self.properties.distance_error = table["e_Dmean"][0] * u("Mpc") # Major axis, ellipticity, position angle self.properties.major_arcsec = table["amaj"][0] * u("arcsec") self.properties.major = (self.properties.distance * self.properties.major_arcsec).to("pc", equivalencies=dimensionless_angles()) # Ellipticity self.properties.ellipticity = table["ell"][0] self.properties.position_angle = Angle(table["PA"][0] + 90.0, u("deg")) # Magnitudes asymptotic_ab_magnitude_i1 = table["__3.6_"][0] asymptotic_ab_magnitude_i2 = table["__4.5_"][0] asymptotic_ab_magnitude_i1_error = table["e__3.6_"][0] asymptotic_ab_magnitude_i2_error = table["e__4.5_"][0] #self.properties.i1_mag = asymptotic_ab_magnitude_i1 #self.properties.i1_mag_error = asymptotic_ab_magnitude_i1_error #self.properties.i2_mag = asymptotic_ab_magnitude_i2 #self.properties.i2_mag_error = asymptotic_ab_magnitude_i2_error #self.properties.i1_fluxdensity = unitconversion.ab_to_jansky(self.properties.i1_mag) * Unit("Jy") #i1_fluxdensity_lower = unitconversion.ab_to_jansky( # self.properties.i1_mag + self.properties.i1_mag_error) * Unit("Jy") #i1_fluxdensity_upper = unitconversion.ab_to_jansky( # self.properties.i1_mag - self.properties.i1_mag_error) * Unit("Jy") #i1_error = ErrorBar(i1_fluxdensity_lower, i1_fluxdensity_upper, at=self.properties.i1_fluxdensity) #self.properties.i1_error = i1_error.average #self.properties.i2_fluxdensity = unitconversion.ab_to_jansky(self.properties.i2_mag) * Unit("Jy") #i2_fluxdensity_lower = unitconversion.ab_to_jansky( # self.properties.i2_mag + self.properties.i2_mag_error) * Unit("Jy") #i2_fluxdensity_upper = unitconversion.ab_to_jansky( # self.properties.i2_mag - self.properties.i2_mag_error) * Unit("Jy") #i2_error = ErrorBar(i2_fluxdensity_lower, i2_fluxdensity_upper, at=self.properties.i2_fluxdensity) #self.properties.i2_error = i2_error.average # Other ... # absolute_magnitude_i1 = table["M3.6"][0] # absolute_magnitude_i2 = table["M4.5"][0] # stellar_mass = 10.0**table["logM_"][0] * u.Unit("Msun") # ----------------------------------------------------------------- def get_components(self): """ This function ... :return: """ # Inform the user log.info("Getting the components ...") # self.get_p4() # currently (writing on the 31th of march 2016) there is a problem with the effective radius values # (at least for M81) on Vizier as well as in the PDF version of table 7 (S4G models homepage). # Parse the S4G table 8 to get the decomposition parameters self.get_parameters_from_table() # ----------------------------------------------------------------- def get_p4(self): """ This function ... :return: """ #http://vizier.cfa.harvard.edu/viz-bin/VizieR?-source=J/ApJS/219/4 # J/ApJS/219/4: S4G pipeline 4: multi-component decompositions (Salo+, 2015) # - J/ApJS/219/4/galaxies: Parameters of the galaxies; center, outer orientation, sky background; and 1-component Sersic fits (tables 1 and 6) (2352 rows) # - J/ApJS/219/4/table7: *Parameters of final multicomponent decompositions (Note) (4629 rows) # Inform the user log.info("Querying the S4G pipeline 4 catalog ...") # Get the "galaxies" table result = self.vizier.query_object(self.config.galaxy_name, catalog=["J/ApJS/219/4/galaxies"]) table = result[0] # PA: [0.2/180] Outer isophote position angle # e_PA: [0/63] Standard deviation in PA # Ell: [0.008/1] Outer isophote ellipticity # e_Ell: [0/0.3] Standard deviation in Ell pa = Angle(table["PA"][0] - 90., "deg") pa_error = Angle(table["e_PA"][0], "deg") ellipticity = table["Ell"][0] ellipticity_error = table["e_Ell"][0] # Get the "table7" table result = self.vizier.get_catalogs("J/ApJS/219/4/table7") table = result[0] # Name: Galaxy name # Mod: Type of final decomposition model # Nc: [1/4] Number of components in the model (1-4) # Q: [3/5] Quality flag, 5=most reliable # C: Physical interpretation of the component # Fn: The GALFIT function used for the component (sersic, edgedisk, expdisk, ferrer2 or psf) # f1: [0.006/1] "sersic" fraction of the total model flux # mag1: [7/19.4] "sersic" total 3.6um AB magnitude # q1: [0.1/1] "sersic" axis ratio # PA1: [0.08/180] "sersic" position angle [deg] # Re: [0.004/430] "sersic" effective radius (Re) [arcsec] # n: [0.01/20] "sersic" parameter n # f2: [0.02/1] "edgedisk" fraction of the total model flux # mu02: [11.8/24.6] "edgedisk" central surface face-on brightness (µ0) [mag/arcsec2] # PA2: [-90/90] "edgedisk" PA [deg] # hr2: [1/153] "edgedisk" exponential scale length (hr) [arcsec] # hz2: [0.003/39] "edgedisk" z-scale hz [arcsec] # f3: [0.02/1] "expdisk" fraction of the total model flux # mag3: [6.5/18.1] "expdisk" total 3.6um AB magnitude [mag] # q3: [0.1/1] "expdisk" axis ratio # PA3: [-90/90] "expdisk" position angle [deg] # hr3: [0.7/332] "expdisk" exponential scale length (hr) [arcsec] # mu03: [16.4/25.3] "expdisk" central surface face-on brightness (µ0) [mag/arcsec2] # f4: [0.003/0.6] "ferrer2" fraction of the total model flux # mu04: [16/24.8] "ferrer2" central surface sky brightness (µ0) [mag/arcsec2] # q4: [0.01/1] "ferrer2" axis ratio # PA4: [-90/90] "ferrer2" position angle [deg] # Rbar: [3.7/232.5] "ferrer2" outer truncation radius of the bar (Rbar) [arcsec] # f5: [0.001/0.4] "psf" fraction of the total model flux # mag5: [11.5/21.1] "psf" total 3.6um AB magnitude [mag] indices = tables.find_indices(table, self.ngc_name_nospaces, "Name") labels = {"sersic": 1, "edgedisk": 2, "expdisk": 3, "ferrer2": 4, "psf": 5} #units = {"f": None, "mag": "mag", "q": None, "PA": "deg", } # Loop over the indices for index in indices: model_type = table["Mod"][index] number_of_components = table["Nc"][index] quality = table["Q"][index] interpretation = table["C"][index] functionname = table["Fn"][index] component_parameters = Map() if self.parameters.model_type is not None: assert model_type == self.parameters.model_type if self.parameters.number_of_components is not None: assert number_of_components == self.parameters.number_of_components if self.parameters.quality is not None: assert quality == self.parameters.quality self.parameters.model_type = model_type self.parameters.number_of_components = number_of_components self.parameters.quality = quality for key in table.colnames: if not key.endswith(str(labels[functionname])): continue parameter = key[:-1] value = table[key][index] if parameter == "PA": value = Angle(value + 90., "deg") if quadrant(value) == 2: value = value - Angle(180., "deg") elif quadrant(value) == 3: value = value + Angle(180., "deg") if value.to("deg").value > 180.: value = value - Angle(360., "deg") elif value.to("deg").value < -180.: value = value + Angle(360., "deg") elif parameter == "mag": parameter = "fluxdensity" value = unitconversion.ab_to_jansky(value) * u("Jy") elif parameter == "mu0": value = value * u("mag/arcsec2") elif parameter == "hr": value = value * u("arcsec") value = (self.parameters.distance * value).to("pc", equivalencies=dimensionless_angles()) elif parameter == "hz": value = value * u("arcsec") value = (self.parameters.distance * value).to("pc", equivalencies=dimensionless_angles()) component_parameters[parameter] = value if functionname == "sersic": re = table["Re"][index] * u("arcsec") component_parameters["Re"] = (self.parameters.distance * re).to("pc", equivalencies=dimensionless_angles()) component_parameters["n"] = table["n"][index] elif functionname == "ferrer2": rbar = table["Rbar"][index] * u("arcsec") component_parameters["Rbar"] = (self.parameters.distance * rbar).to("pc", equivalencies=dimensionless_angles()) if interpretation == "B": # bulge self.parameters.bulge = component_parameters elif interpretation == "D": # disk self.parameters.disk = component_parameters else: raise RuntimeError("Unrecognized component: " + interpretation) # Determine the full path to the parameters file #path = fs.join(self.components_path, "parameters.dat") # Write the parameters to the specified location #write_parameters(self.parameters, path) # ----------------------------------------------------------------- def get_parameters_from_table(self): """ This function ... :return: """ # Inform the user log.info("Getting the structural galaxy parameters from the S4G catalog ...") # Inform the user log.info("Parsing S4G table 8 to get the decomposition parameters ...") #The table columns are: # (1) the running number (1-2352), # (2) the galaxy name, # (3) the type of final decomposition model, # (4) the number N of components in the final model , and # (5) the quality flag Q. # 6- 8 for unresolved central component ('psf'; phys, frel, mag), # 9-15 for inner sersic-component ('sersic1'; phys, frel, mag, re, ar, pa, n), # 16-22 for inner disk-component ('expo1'; phys, frel, mag, hr, ar, pa, mu0), # 23-28 for inner ferrers-component ('ferrers1'; phys, frel, mu0, rout, ar, pa), # 29-34 for inner edge-on disk component ('edgedisk1'; phys, frel, mu0, rs, hs, pa ). # 35-41 for outer sersic-component ('sersic2'; phys, frel, mag, re, ar, pa, n), # 42-49 for outer disk-component ('expo2'; phys, frel, mag, hr, ar, pa, mu0), # 50-55 for outer ferrers-component ('ferrers2'; phys, frel, mu0, rout, ar, pa), # 56-61 for outer edge-on disk component ('edgedisk2'; phys, frel, mu0, rs, hs, pa ). sersic_1_index = 8 disk_1_index = 15 edgedisk_1_index = 28 #For each function: #the first entry stands for the physical intepretation of the component: #'N' for a central source (or unresolved bulge), 'B' for a bulge (or elliptical), 'D' for a disk, 'BAR' for a bar, and 'Z' for an edge-on disk. # 'rel = the relative contribution of the component to the total model flux, # mag = the component's total 3.6 micron AB magnitude, # mu0 = the central surface brightness (mag/arcsec^2; de-projected central surface brightness for expdisk and edgedisk, and # sky-plane central surface brightness for ferrer) # ar = axial ratio # pa = position angle (degrees ccw from North) # n = sersic index # hr = exponential scale lenght (arcsec) # rs = radial scale lenght (arcsec) # hs = vertical scale height (arcsec) # rout = bar outer truncation radius (arcsec) # SERSIC: phys, frel, mag, re, ar, pa, n # DISK: phys, frel, mag, hr, ar, pa, mu0 # EDGEDISK: phys frel mu0 rs hs pa with open(local_table_path, 'r') as s4g_table: for line in s4g_table: splitted = line.split() if len(splitted) < 2: continue name = splitted[1] #print(list(name)) # Only look at the line corresponding to the galaxy if name != self.ngc_name_nospaces: continue #if self.ngc_name_nospaces not in name: continue #self.parameters.model_type = splitted[2] #self.parameters.number_of_components = splitted[3] #self.parameters.quality = splitted[4] ## BULGE #self.parameters.bulge.interpretation = splitted[sersic_1_index].split("|")[1] bulge_f = float(splitted[sersic_1_index + 1]) mag = float(splitted[sersic_1_index + 2]) bulge_fluxdensity = unitconversion.ab_to_jansky(mag) * u("Jy") # Effective radius in pc re_arcsec = float(splitted[sersic_1_index + 3]) * u("arcsec") bulge_re = (self.properties.distance * re_arcsec).to("pc", equivalencies=dimensionless_angles()) bulge_q = float(splitted[sersic_1_index + 4]) bulge_pa = Angle(float(splitted[sersic_1_index + 5]) - 90., "deg") bulge_n = float(splitted[sersic_1_index + 6]) # Create the bulge component bulge = SersicModel2D(rel_contribution=bulge_f, fluxdensity=bulge_fluxdensity, effective_radius=bulge_re, axial_ratio=bulge_q, position_angle=bulge_pa, index=bulge_n) # Add the bulge to the components dictionary self.components["bulge"] = bulge ## DISK if splitted[disk_1_index + 1] != "-": #self.parameters.disk.interpretation = splitted[disk_1_index].split("|")[1] disk_f = float(splitted[disk_1_index + 1]) mag = float(splitted[disk_1_index + 2]) disk_fluxdensity = unitconversion.ab_to_jansky(mag) * u("Jy") # Scale length in pc hr_arcsec = float(splitted[disk_1_index + 3]) * u("arcsec") disk_hr = (self.properties.distance * hr_arcsec).to("pc", equivalencies=dimensionless_angles()) disk_q = float(splitted[disk_1_index + 4]) # axial ratio disk_pa = Angle(float(splitted[disk_1_index + 5]) - 90., "deg") disk_mu0 = float(splitted[disk_1_index + 6]) * u("mag/arcsec2") # Create the disk component disk = ExponentialDiskModel2D(rel_contribution=disk_f, fluxdensity=disk_fluxdensity, scalelength=disk_hr, axial_ratio=disk_q, position_angle=disk_pa, mu0=disk_mu0) else: # phys frel mu0 rs hs pa disk_f = float(splitted[edgedisk_1_index + 1]) mag = None fluxdensity = None # frel mu0 rs hs pa #print(disk_f) disk_mu0 = float(splitted[edgedisk_1_index + 2]) * u("mag/arcsec2") # rs hs pa # rs = radial scale lenght (arcsec) # hs = vertical scale height (arcsec) rs = float(splitted[edgedisk_1_index + 3]) hs = float(splitted[edgedisk_1_index + 4]) #print(rs) #print(hs) disk_pa = Angle(float(splitted[edgedisk_1_index + 5]) - 90., "deg") #print(disk_pa) disk_q = hs / rs # Create the disk component disk = ExponentialDiskModel2D(rel_contribution=disk_f, scalelength=rs, axial_ratio=disk_q, position_angle=disk_pa, mu0=disk_mu0) # Add the disk to the components dictionary self.components["disk"] = disk # ----------------------------------------------------------------- @property def disk_pa(self): """ This function ... :return: """ return self.components["disk"].position_angle # ----------------------------------------------------------------- def show(self): """ This function ... :return: """ print(fmt.green + "Galaxy properties" + fmt.reset + ":") print("") print(self.properties) print("") for name in self.components: print(fmt.green + name + fmt.reset + ":") print("") print(self.components[name]) print("") # ----------------------------------------------------------------- def write(self): """ This function ... :return: """ # Inform the user log.info("Writing ...") # Write the properties self.write_properties() # Write the components self.write_components() # ----------------------------------------------------------------- def write_properties(self): """ This function ... :return: """ # Inform the user log.info("Writing the properties ...") # Determine the path and save path = self.output_path_file("properties.dat") self.properties.saveto(path) # ----------------------------------------------------------------- def write_components(self): """ This function ... :return: """ # Inform the user log.info("Writing the components ...") # Loop over the components for name in self.components: # Determine the path path = self.output_path_file(name + ".mod") # Save the model self.components[name].saveto(path)
#v = Vizier(columns = ['Vmag','B-V','U-B','V-Rc','Rc-Ic','e_Vmag','e_B-V','e_U-B','e_V-Rc','e_Rc-Ic'] keys = [] Vizier.ROW_LIMIT = -1 if not os.path.exists(directory): os.mkdir(directory) for page in catalogs: keys.append(page) #v = Vizier(columns=['Name','Nova','JD', 'Band', 'mag', 'e_mag', 'Source']) dataTables = Vizier.get_catalogs(keys) keys = dataTables.keys() keyRepeatDict = {} filename_dict = {} for key in keys: if key not in keyRepeatDict: keyRepeatDict[key] = 0 else: keyRepeatDict[key] += 1 names = () for catalogKey in catalogs: if re.search(catalogKey.replace("+", "\+").replace(".", "\."), key): names = catalogs[catalogKey]
class SEDFetcher(OldConfigurable): """ This class ... """ def __init__(self, config=None): """ The constructor ... """ # Call the constructor of the base class super(SEDFetcher, self).__init__(config, "modeling") # -- Attributes -- # The name of the galaxy self.galaxy_name = None # The NGC ID of the galaxy self.ngc_id = None # The Vizier querying object self.vizier = Vizier(keywords=["galaxies"]) self.vizier.ROW_LIMIT = -1 # The observed SED self.seds = dict() # The filters self.filters = dict() # ----------------------------------------------------------------- @classmethod def from_arguments(cls, arguments): """ This function ... :param arguments: :return: """ # Create a new SEDFetcher instance if arguments.config is not None: fetcher = cls(arguments.config) elif arguments.settings is not None: fetcher = cls(arguments.settings) else: fetcher = cls() # Set the output path if arguments.output_path is not None: fetcher.config.output_path = arguments.output_path # Run from the command line, so always write out the SEDs fetcher.config.write_seds = True fetcher.config.writing.seds_path = "SEDs" # Return the new instance return fetcher # ----------------------------------------------------------------- def run(self, galaxy_name): """ This function ... :param galaxy_name """ # 1. Call the setup function self.setup(galaxy_name) # 2. If requested, query the GALEX ultraviolet atlas of nearby galaxies catalog (Gil de Paz+, 2007) if "GALEX" in self.config.catalogs: self.get_galex() # 3. If requested, query the 2MASS Extended sources catalog (IPAC/UMass, 2003-2006) if "2MASS" in self.config.catalogs: self.get_2mass() # SDSS ? # Ilse "Voor de galaxieen in de noordelijke hemisfeer heb je SDSS data beschikbaar, en die kan je dan # beter gebruiken (ipv. SINGS) om je fit te constrainen in het optische gebied. Er zal binnenkort een nieuwe # paper van Daniel Dale uitkomen met gehercalibreerde fluxen in de optische banden, die je dan kan gebruiken. # 5. If requested, query the Radial distribution in SINGS galaxies (I.) catalogs (Munoz-Mateos+, 2009) # Opm. Ilse: "voor vele SINGS galaxieen is de calibratie van de optische data heel slecht, dus krijg je een # offset en datapunten die een beetje random blijken te zijn." if "SINGS" in self.config.catalogs: self.get_sings() # If requested, query the LVL global optical photometry (Cook+, 2014) catalog if "LVL" in self.config.catalogs: self.get_lvl() # If requested, query the Spitzer Local Volume Legacy: IR photometry (Dale+, 2009) if "Spitzer" in self.config.catalogs: self.get_spitzer() # If requested, query the Spitzer/IRS ATLAS project source (Hernan-Caballero+, 2011) if "Spitzer/IRS" in self.config.catalogs: self.get_spitzer_irs() # If requested, query the Compendium of ISO far-IR extragalactic data (Brauher+, 2008) if "IRAS" in self.config.catalogs: self.get_iras() # If requested, query the Imperial IRAS-FSC redshift catalogue (IIFSCz) (Wang+, 2009) if "IRAS-FSC" in self.config.catalogs: self.get_iras_fsc() # If requested, query the S4G catalog for IRAC fluxes if "S4G" in self.config.catalogs: self.get_s4g() # If requested, query the Spectroscopy and abundances of SINGS galaxies (Moustakas+, 2010) catalog if "Emission lines" in self.config.catalogs: self.get_emission_lines() # If requested, query the Atlas of UV-to-MIR galaxy SEDs (Brown+, 2014) if "Brown" in self.config.catalogs: self.get_brown() # If requested, query the Planck Catalog of Compact Sources Release 1 (Planck, 2013) if "Planck" in self.config.catalogs: self.get_planck() # SPECIFIC for M81: not enabled, no time to figure out the unit conversion now #if self.ngc_id == "NGC 3031": self.get_m81() # Other interesting catalogs: # http://vizier.cfa.harvard.edu/viz-bin/VizieR-3?-source=J/ApJS/199/22 # http://vizier.cfa.harvard.edu/viz-bin/VizieR-3?-source=J/ApJS/212/18/sample&-c=NGC%203031&-c.u=arcmin&-c.r=2&-c.eq=J2000&-c.geom=r&-out.max=50&-out.form=HTML%20Table&-oc.form=sexa # http://vizier.cfa.harvard.edu/viz-bin/VizieR-3?-source=J/ApJS/220/6 # Writing self.write() # ----------------------------------------------------------------- def setup(self, galaxy_name): """ This function ... :param galaxy_name: :return: """ # Call the setup function of the base class super(SEDFetcher, self).setup() # Set the galaxy name self.galaxy_name = galaxy_name # Get the NGC ID of the galaxy self.ngc_id = catalogs.get_ngc_name(self.galaxy_name) # Create a dictionary of filters keys = ["Ha", "FUV", "NUV", "U", "B", "V", "R", "J", "H", "K", "IRAS 12", "IRAS 25", "IRAS 60", "IRAS 100", "I1", "I2", "I3", "I4", "MIPS 24", "MIPS 70", "MIPS 160", "SDSS u", "SDSS g", "SDSS r", "SDSS i", "SDSS z"] for key in keys: self.filters[key] = Filter.from_string(key) # ----------------------------------------------------------------- def get_galex(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the GALEX ultraviolet atlas of nearby galaxies ...") # GALEX: "J/ApJS/173/185" of "J/ApJS/173/185/galex": B and V (2007ApJS..173..185G) # Interesting columns: # # - "MajAxis": Major-axis diameter of the D25 ellipse [arcmin] # - "MinAxis": Minor-axis diameter of the D25 ellipse [arcmin] # - "PA": Position angle of the D25 ellipse [deg] # - "Dist": Distance to the galaxy [Mpc] # - "Morph": Morphological type # - "T": Morphological type T # - "FUV": FUV (120-177nm) image mean sky background [ct/s] # - "sigFUV": Mean standard deviation of the FUV sky. Note (2): Measured by averaging the standard deviation within several regions around the position of the object. [ct/s] # - "e_FUV": The standard deviation of the mean FUV sky [ct/s] # - "NUV": Mean NUV (177-300nm) sky background [ct/s] # - "sigNUV": Mean standard deviation of the NUV sky [ct/s] # - "e_NUV": The standard deviation of the mean NUV sky [ct/s] # - "D25FUV": Observed D25 ellipse FUV band AB magnitude [mag] # - "e_D25FUV": Uncertainty in D25FUV [mag] # - "D25NUV": Observed D25 ellipse NUV band AB magnitude [mag] # - "e_D25NUV": Uncertainty in D25NUV [mag] # - "AFUV": Foreground FUV extinction [mag] # - "ANUV": Foreground NUV extinction [mag] # - "asyFUV": Observed asymptotic FUV (120-177nm) AB magnitude [mag] # - "e_asyFUV": Uncertainty in asyFUV [mag] # - "asyNUV": Observed asymptotic NUV (177-300nm) AB magnitude [mag] # - "e_asyNUV": Uncertainty in asyNUV [mag] # - "logFUV": Log of the FUV (120-177nm) luminosity [W] # - "logNUV": Log of the NUV (177-300nm) luminosity [W] # - "Umag": Johnson U band integrated magnitude [mag] Note (1): In the Vega scale. Published as part of the RC3 catalog, Cat. VII/155) # - "e_Umag": Uncertainty in Umag [mag] # - "Bmag": Johnson B band integrated magnitude [mag] # - "e_Bmag": Uncertainty in Bmag [mag] # - "Vmag": Johnson V band integrated magnitude [mag] # - "e_Vmag": Uncertainty in Vmag [mag] # - "Jmag": 2MASS J band total magnitude [mag] # - "e_Jmag": Uncertainty in Jmag [mag] # - "Hmag": 2MASS H band total magnitude [mag] # - "e_Hmag": Uncertainty in Hmag [mag] # - "Kmag": 2MASS K band total magnitude [mag] # - "e_Kmag": Uncertainty in Kmag [mag] # - "F12um": IRAS 12 micron flux density [Jy] # - "e_F12um": Uncertainty in F12um [Jy] # - "F25um": IRAS 25 micron flux density [Jy] # - "e_F25um": Uncertainty in F25um [Jy] # - "F60um": IRAS 60 micron flux density [Jy] # - "e_F60um": Uncertainty in F60um [Jy] # - "F100um": IRAS 100 micron flux density [Jy] # - "e_F100um": Uncertainty in F100um [Jy] result = self.vizier.query_object(self.galaxy_name, catalog="J/ApJS/173/185/galex") # Result is a list of tables, we only have one table with one entry # Create an SED sed = ObservedSED() # All AB magnitudes # FUV -- if not result[0]["asyFUV"].mask[0]: fuv_mag = result[0]["asyFUV"][0] fuv_mag_error = result[0][0]["e_asyFUV"] fuv_mag_lower = fuv_mag - fuv_mag_error fuv_mag_upper = fuv_mag + fuv_mag_error # flux fuv = unitconversion.ab_to_jansky(fuv_mag) fuv_lower = unitconversion.ab_to_jansky(fuv_mag_upper) fuv_upper = unitconversion.ab_to_jansky(fuv_mag_lower) fuv_error = ErrorBar(fuv_lower, fuv_upper, at=fuv) sed.add_entry(self.filters["FUV"], fuv, fuv_error) # NUV -- if not result[0]["asyNUV"].mask[0]: nuv_mag = result[0][0]["asyNUV"] nuv_mag_error = result[0][0]["e_asyNUV"] nuv_mag_lower = nuv_mag - nuv_mag_error nuv_mag_upper = nuv_mag + nuv_mag_error # flux nuv = unitconversion.ab_to_jansky(nuv_mag) nuv_lower = unitconversion.ab_to_jansky(nuv_mag_upper) nuv_upper = unitconversion.ab_to_jansky(nuv_mag_lower) nuv_error = ErrorBar(nuv_lower, nuv_upper, at=nuv) sed.add_entry(self.filters["NUV"], nuv, nuv_error) # U band -- if not result[0]["Umag"].mask[0]: # From Vega magnitude system to AB magnitudes u_mag = unitconversion.vega_to_ab(result[0][0]["Umag"], "U") u_mag_error = unitconversion.vega_to_ab(result[0][0]["e_Umag"], "U") u_mag_lower = u_mag - u_mag_error u_mag_upper = u_mag + u_mag_error # U band flux u = unitconversion.ab_to_jansky(u_mag) u_lower = unitconversion.ab_to_jansky(u_mag_upper) u_upper = unitconversion.ab_to_jansky(u_mag_lower) u_error = ErrorBar(u_lower, u_upper, at=u) sed.add_entry(self.filters["U"], u, u_error) # B band -- if not result[0]["Bmag"].mask[0]: b_mag = unitconversion.vega_to_ab(result[0][0]["Bmag"], "B") b_mag_error = unitconversion.vega_to_ab(result[0][0]["e_Bmag"], "B") b_mag_lower = b_mag - abs(b_mag_error) b_mag_upper = b_mag + abs(b_mag_error) #print("bmag", b_mag) #print("bmagerror", b_mag_error) #print("bmaglower", b_mag_lower) #print("bmagupper", b_mag_upper) # B band flux b = unitconversion.ab_to_jansky(b_mag) b_lower = unitconversion.ab_to_jansky(b_mag_upper) b_upper = unitconversion.ab_to_jansky(b_mag_lower) b_error = ErrorBar(b_lower, b_upper, at=b) sed.add_entry(self.filters["B"], b, b_error) # V band -- if not result[0]["Vmag"].mask[0]: v_mag = unitconversion.vega_to_ab(result[0][0]["Vmag"], "V") v_mag_error = unitconversion.vega_to_ab(result[0][0]["e_Vmag"], "V") v_mag_lower = v_mag - v_mag_error v_mag_upper = v_mag + v_mag_error # V band flux v = unitconversion.ab_to_jansky(v_mag) v_lower = unitconversion.ab_to_jansky(v_mag_upper) v_upper = unitconversion.ab_to_jansky(v_mag_lower) v_error = ErrorBar(v_lower, v_upper, at=v) sed.add_entry(self.filters["V"], v, v_error) # In 2MASS magnitude system -> can be converted directly into Jy (see below) # J band -- if not result[0]["Jmag"].mask[0]: j_mag = result[0][0]["Jmag"] j_mag_error = result[0][0]["e_Jmag"] j_mag_lower = j_mag - j_mag_error j_mag_upper = j_mag + j_mag_error # J band flux j = unitconversion.photometry_2mass_mag_to_jy(j_mag, "J") j_lower = unitconversion.photometry_2mass_mag_to_jy(j_mag_upper, "J") j_upper = unitconversion.photometry_2mass_mag_to_jy(j_mag_lower, "J") j_error = ErrorBar(j_lower, j_upper, at=j) sed.add_entry(self.filters["J"], j, j_error) # H band -- if not result[0]["Hmag"].mask[0]: h_mag = result[0][0]["Hmag"] h_mag_error = result[0][0]["e_Hmag"] h_mag_lower = h_mag - h_mag_error h_mag_upper = h_mag + h_mag_error # H band flux h = unitconversion.photometry_2mass_mag_to_jy(h_mag, "H") h_lower = unitconversion.photometry_2mass_mag_to_jy(h_mag_upper, "H") h_upper = unitconversion.photometry_2mass_mag_to_jy(h_mag_lower, "H") h_error = ErrorBar(h_lower, h_upper, at=h) sed.add_entry(self.filters["H"], h, h_error) # K band -- if not result[0]["Kmag"].mask[0]: k_mag = result[0][0]["Kmag"] k_mag_error = result[0][0]["e_Kmag"] k_mag_lower = k_mag - k_mag_error k_mag_upper = k_mag + k_mag_error # K band flux k = unitconversion.photometry_2mass_mag_to_jy(k_mag, "Ks") k_lower = unitconversion.photometry_2mass_mag_to_jy(k_mag_upper, "Ks") k_upper = unitconversion.photometry_2mass_mag_to_jy(k_mag_lower, "Ks") k_error = ErrorBar(k_lower, k_upper, at=k) sed.add_entry(self.filters["K"], k, k_error) # F12 band flux if not result[0]["F12um"].mask[0]: f12 = result[0][0]["F12um"] f12_error = ErrorBar(result[0][0]["e_F12um"]) sed.add_entry(self.filters["IRAS 12"], f12, f12_error) # F25 band flux if not result[0]["F25um"].mask[0]: f25 = result[0][0]["F25um"] f25_error = ErrorBar(result[0][0]["e_F25um"]) sed.add_entry(self.filters["IRAS 25"], f25, f25_error) # F60 band flux if not result[0]["F60um"].mask[0]: f60 = result[0][0]["F60um"] f60_error = ErrorBar(result[0][0]["e_F60um"]) sed.add_entry(self.filters["IRAS 60"], f60, f60_error) # F100 band flux if not result[0]["F100um"].mask[0]: f100 = result[0][0]["F100um"] f100_error = ErrorBar(result[0][0]["e_F100um"]) sed.add_entry(self.filters["IRAS 100"], f100, f100_error) # Add the SED to the dictionary self.seds["GALEX"] = sed # ----------------------------------------------------------------- def get_2mass(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the 2MASS Extended Catalog ...") # 2MASS Extended Catalog: "VII/233/xsc": J, H, K (2006AJ....131.1163S) # Interesting columns: # # - "J.ext": J magnitude in r.ext (j_m_ext) [mag] # - "e_J.ext": σ(J.ext) (j_msig_ext) [mag] # - "H.ext": H magnitude in r.ext (h_m_ext) [mag] # - "e_H.ext": σ(H.ext) (h_msig_ext) [mag] # - "K.ext": J magnitude in r.ext (k_m_ext) [mag] # - "e_K.ext": σ(K.ext) (k_msig_ext) [mag] result = self.vizier.query_object(self.galaxy_name, catalog="VII/233/xsc") # Create an SED sed = ObservedSED() # In 2MASS magnitude system -> can be converted directly into Jy (see below) j_mag = result[0][0]["J.ext"] j_mag_error = result[0][0]["e_J.ext"] j_mag_lower = j_mag - j_mag_error j_mag_upper = j_mag + j_mag_error h_mag = result[0][0]["H.ext"] h_mag_error = result[0][0]["e_H.ext"] h_mag_lower = h_mag - h_mag_error h_mag_upper = h_mag + h_mag_error k_mag = result[0][0]["K.ext"] k_mag_error = result[0][0]["e_K.ext"] k_mag_lower = k_mag - k_mag_error k_mag_upper = k_mag + k_mag_error # J band flux j = unitconversion.photometry_2mass_mag_to_jy(j_mag, "J") j_lower = unitconversion.photometry_2mass_mag_to_jy(j_mag_upper, "J") j_upper = unitconversion.photometry_2mass_mag_to_jy(j_mag_lower, "J") j_error = ErrorBar(j_lower, j_upper, at=j) sed.add_entry(self.filters["J"], j, j_error) # H band flux h = unitconversion.photometry_2mass_mag_to_jy(h_mag, "H") h_lower = unitconversion.photometry_2mass_mag_to_jy(h_mag_upper, "H") h_upper = unitconversion.photometry_2mass_mag_to_jy(h_mag_lower, "H") h_error = ErrorBar(h_lower, h_upper, at=h) sed.add_entry(self.filters["H"], h, h_error) # K band flux k = unitconversion.photometry_2mass_mag_to_jy(k_mag, "Ks") k_lower = unitconversion.photometry_2mass_mag_to_jy(k_mag_upper, "Ks") k_upper = unitconversion.photometry_2mass_mag_to_jy(k_mag_lower, "Ks") k_error = ErrorBar(k_lower, k_upper, at=k) sed.add_entry(self.filters["K"], k, k_error) # Add the SED to the dictionary self.seds["2MASS"] = sed # ----------------------------------------------------------------- def get_sings(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the SINGS catalog ...") # Radial distribution in SINGS galaxies. I. # J/ApJ/703/1569/table1 (c)Sample (75 rows) # J/ApJ/703/1569/table2 UV, optical and NIR surface photometry profiles (2206 rows) # J/ApJ/703/1569/table3 UV, optical (SDSS) and NIR photometry profiles (2161 rows) # J/ApJ/703/1569/table4 IRAC and MIPS surface photometry (4319 rows) # J/ApJ/703/1569/table5 UV, optical, and near-IR asymptotic magnitudes for SINGS galaxies lacking SDSS data (43 rows) # J/ApJ/703/1569/table6 UV, optical (SDSS), and near-IR asymptotic magnitudes (32 rows) # J/ApJ/703/1569/table7 IRAC and MIPS asymptotic magnitudes (75 rows) # J/ApJ/703/1569/table8 Non-parametrical morphological estimators (300 rows) result = self.vizier.get_catalogs("J/ApJ/703/1569") # Result is a TableList with 8 tables (0 to 7) # We need: # - Table6 -> index 5 # - Table7 -> index 6 # Table6 # - "Name": Galaxy name (NGC ...) # - "FUV": GALEX FUV 0.153um-band AB magnitude [mag] # - "e_FUV": FUV uncertainty [mag] # - "NUV": GALEX NUV 0.227um-band AB magnitude [mag] # - "e_NUV": NUV uncertainty [mag] # - "umag": SDSS u-band 0.354um AB magnitude [mag] # - "e_umag": umag uncertainty [mag] # - "gmag": SDSS g-band 0.477um AB magnitude [mag] # - "e_gmag": gmag uncertainty [mag] # - "rmag": SDSS r-band 0.623um AB magnitude [mag] # - "e_rmag": rmag uncertainty [mag] # - "imag": SDSS i-band 0.762um AB magnitude [mag] # - "e_imag": imag uncertainty [mag] # - "zmag": SDSS z-band 0.913um AB magnitude [mag] # - "e_zmag": zmag uncertainty [mag] # - "Jmag": 2MASS J-band 1.25um AB magnitude [mag] # - "e_Jmag": Jmag uncertainty [mag] # - "Hmag": 2MASS H-band 1.65um AB magnitude [mag] # - "e_Hmag": Hmag uncertainty [mag] # - "Ksmag": 2MASS Ks-band 2.17um AB magnitude [mag] # - "e_Ksmag": Ksmag uncertainty [mag] # Find the row index that corresponds with the specified galaxy galaxy_index = tables.find_index(result[5], self.ngc_id) # FUV fuv_mag = result[5][galaxy_index]["FUV"] fuv_mag_error = result[5][galaxy_index]["e_FUV"] fuv_mag_lower = fuv_mag - fuv_mag_error fuv_mag_upper = fuv_mag + fuv_mag_error # NUV nuv_mag = result[5][galaxy_index]["NUV"] nuv_mag_error = result[5][galaxy_index]["e_NUV"] nuv_mag_lower = nuv_mag - nuv_mag_error nuv_mag_upper = nuv_mag + nuv_mag_error # u u_mag = result[5][galaxy_index]["umag"] u_mag_error = result[5][galaxy_index]["e_umag"] u_mag_lower = u_mag - u_mag_error u_mag_upper = u_mag + u_mag_error # g g_mag = result[5][galaxy_index]["gmag"] g_mag_error = result[5][galaxy_index]["e_gmag"] g_mag_lower = g_mag - abs(g_mag_error) g_mag_upper = g_mag + abs(g_mag_error) #print("gmag", g_mag) #print("gmagerror", g_mag_error) #print("gmaglower", g_mag_lower) #print("gmagupper", g_mag_upper) # r r_mag = result[5][galaxy_index]["rmag"] r_mag_error = result[5][galaxy_index]["e_rmag"] r_mag_lower = r_mag - r_mag_error r_mag_upper = r_mag + r_mag_error # i i_mag = result[5][galaxy_index]["imag"] i_mag_error = result[5][galaxy_index]["e_imag"] i_mag_lower = i_mag - i_mag_error i_mag_upper = i_mag + i_mag_error # z z_mag = result[5][galaxy_index]["zmag"] z_mag_error = result[5][galaxy_index]["e_zmag"] z_mag_lower = z_mag - z_mag_error z_mag_upper = z_mag + z_mag_error # J j_mag = result[5][galaxy_index]["Jmag"] j_mag_error = result[5][galaxy_index]["e_Jmag"] j_mag_lower = j_mag - j_mag_error j_mag_upper = j_mag + j_mag_error # H h_mag = result[5][galaxy_index]["Hmag"] h_mag_error = result[5][galaxy_index]["e_Hmag"] h_mag_lower = h_mag - h_mag_error h_mag_upper = h_mag + h_mag_error # Ks k_mag = result[5][galaxy_index]["Ksmag"] k_mag_error = result[5][galaxy_index]["e_Ksmag"] k_mag_lower = k_mag - k_mag_error k_mag_upper = k_mag + k_mag_error # Create an SED sed = ObservedSED() # FUV fuv = unitconversion.ab_to_jansky(fuv_mag) fuv_lower = unitconversion.ab_to_jansky(fuv_mag_upper) fuv_upper = unitconversion.ab_to_jansky(fuv_mag_lower) fuv_error = ErrorBar(fuv_lower, fuv_upper, at=fuv) sed.add_entry(self.filters["FUV"], fuv, fuv_error) # NUV nuv = unitconversion.ab_to_jansky(nuv_mag) nuv_lower = unitconversion.ab_to_jansky(nuv_mag_upper) nuv_upper = unitconversion.ab_to_jansky(nuv_mag_lower) nuv_error = ErrorBar(nuv_lower, nuv_upper, at=nuv) sed.add_entry(self.filters["NUV"], nuv, nuv_error) # u u = unitconversion.ab_to_jansky(u_mag) u_lower = unitconversion.ab_to_jansky(u_mag_upper) u_upper = unitconversion.ab_to_jansky(u_mag_lower) u_error = ErrorBar(u_lower, u_upper, at=u) sed.add_entry(self.filters["SDSS u"], u, u_error) # g g = unitconversion.ab_to_jansky(g_mag) g_lower = unitconversion.ab_to_jansky(g_mag_upper) g_upper = unitconversion.ab_to_jansky(g_mag_lower) g_error = ErrorBar(g_lower, g_upper, at=g) sed.add_entry(self.filters["SDSS g"], g, g_error) # r r = unitconversion.ab_to_jansky(r_mag) r_lower = unitconversion.ab_to_jansky(r_mag_upper) r_upper = unitconversion.ab_to_jansky(r_mag_lower) r_error = ErrorBar(r_lower, r_upper, at=r) sed.add_entry(self.filters["SDSS r"], r, r_error) # i i = unitconversion.ab_to_jansky(i_mag) i_lower = unitconversion.ab_to_jansky(i_mag_upper) i_upper = unitconversion.ab_to_jansky(i_mag_lower) i_error = ErrorBar(i_lower, i_upper, at=i) sed.add_entry(self.filters["SDSS i"], i, i_error) # z z = unitconversion.ab_to_jansky(z_mag) z_lower = unitconversion.ab_to_jansky(z_mag_upper) z_upper = unitconversion.ab_to_jansky(z_mag_lower) z_error = ErrorBar(z_lower, z_upper, at=z) sed.add_entry(self.filters["SDSS z"], z, z_error) # J j = unitconversion.ab_to_jansky(j_mag) j_lower = unitconversion.ab_to_jansky(j_mag_upper) j_upper = unitconversion.ab_to_jansky(j_mag_lower) j_error = ErrorBar(j_lower, j_upper, at=j) sed.add_entry(self.filters["J"], j, j_error) # H h = unitconversion.ab_to_jansky(h_mag) h_lower = unitconversion.ab_to_jansky(h_mag_upper) h_upper = unitconversion.ab_to_jansky(h_mag_lower) h_error = ErrorBar(h_lower, h_upper, at=h) sed.add_entry(self.filters["H"], h, h_error) # Ks k = unitconversion.ab_to_jansky(k_mag) k_lower = unitconversion.ab_to_jansky(k_mag_upper) k_upper = unitconversion.ab_to_jansky(k_mag_lower) k_error = ErrorBar(k_lower, k_upper, at=k) sed.add_entry(self.filters["K"], k, k_error) # Table7: IRAC and MIPS asymptotic magnitudes # - "logF3.6": Spitzer/IRAC 3.6um flux density [logJy] # - "e_logF3.6": logF3.6 uncertainty [logJy] # - "logF4.5": Spitzer/IRAC 4.5um flux density [logJy] # - "e_logF4.5": logF4.5 uncertainty [logJy] # - "logF5.8": Spitzer/IRAC 5.8um flux density [logJy] # - "e_logF5.8": logF5.8 uncertainty [logJy] # - "logF8.0": Spiter/IRAC 8.0um flux density [logJy] # - "e_logF8.0": logF8.0 uncertainty [logJy] # - "logF24": Spiter/MIPS 24um flux density [logJy] # - "e_logF24": logF24 uncertainty [logJy] # - "logF70": Spiter/MIPS 70um flux density [logJy] # - "e_logF70": logF70 uncertainty [logJy] # - "logF160": Spiter/MIPS 160um flux density [logJy] # - "e_logF160": logF160 uncertainty [logJy] # Table7 -> index 6 galaxy_index = tables.find_index(result[6], self.ngc_id) # 3.6 micron i1_log = result[6][galaxy_index]["logF3.6"] i1_log_error = result[6][galaxy_index]["e_logF3.6"] i1_log_lower = i1_log - i1_log_error i1_log_upper = i1_log + i1_log_error # 4.5 micron i2_log = result[6][galaxy_index]["logF4.5"] i2_log_error = result[6][galaxy_index]["e_logF4.5"] i2_log_lower = i2_log - i2_log_error i2_log_upper = i2_log + i2_log_error # 5.8 micron i3_log = result[6][galaxy_index]["logF5.8"] i3_log_error = result[6][galaxy_index]["e_logF5.8"] i3_log_lower = i3_log - i3_log_error i3_log_upper = i3_log + i3_log_error # 8.0 micron i4_log = result[6][galaxy_index]["logF8.0"] i4_log_error = result[6][galaxy_index]["e_logF8.0"] i4_log_lower = i4_log - i4_log_error i4_log_upper = i4_log + i4_log_error #print("i4log", i4_log) #print("i4_log_error", i4_log_error) #print("i4_log_lower", i4_log_lower) #print("i4_log_upper", i4_log_upper) # 24 micron mips24_log = result[6][galaxy_index]["logF24"] mips24_log_error = result[6][galaxy_index]["e_logF24"] mips24_log_lower = mips24_log - mips24_log_error mips24_log_upper = mips24_log + mips24_log_error # 70 micron mips70_log = result[6][galaxy_index]["logF70"] mips70_log_error = result[6][galaxy_index]["e_logF70"] mips70_log_lower = mips70_log - mips70_log_error mips70_log_upper = mips70_log + mips70_log_error # 160 micron mips160_log = result[6][galaxy_index]["logF160"] mips160_log_error = result[6][galaxy_index]["e_logF160"] mips160_log_lower = mips160_log - mips160_log_error mips160_log_upper = mips160_log + mips160_log_error # Calculate data points and errobars in Janskys, add to the SED # 3.6 micron i1 = 10.**i1_log i1_lower = 10.**i1_log_lower i1_upper = 10.**i1_log_upper i1_error = ErrorBar(i1_lower, i1_upper, at=i1) sed.add_entry(self.filters["I1"], i1, i1_error) # 4.5 micron i2 = 10.**i2_log i2_lower = 10.**i2_log_lower i2_upper = 10.**i2_log_upper i2_error = ErrorBar(i2_lower, i2_upper, at=i2) sed.add_entry(self.filters["I2"], i2, i2_error) # 5.8 micron i3 = 10.**i3_log i3_lower = 10.**i3_log_lower i3_upper = 10.**i3_log_upper i3_error = ErrorBar(i3_lower, i3_upper, at=i3) sed.add_entry(self.filters["I3"], i3, i3_error) # 8.0 micron i4 = 10.**i4_log i4_lower = 10.**i4_log_lower i4_upper = 10.**i4_log_upper i4_error = ErrorBar(i4_lower, i4_upper, at=i4) sed.add_entry(self.filters["I4"], i4, i4_error) # 24 micron mips24 = 10.**mips24_log mips24_lower = 10.**mips24_log_lower mips24_upper = 10.**mips24_log_upper mips24_error = ErrorBar(mips24_lower, mips24_upper, at=mips24) sed.add_entry(self.filters["MIPS 24"], mips24, mips24_error) # 70 micron mips70 = 10.**mips70_log mips70_lower = 10.**mips70_log_lower mips70_upper = 10.**mips70_log_upper mips70_error = ErrorBar(mips70_lower, mips70_upper, at=mips70) sed.add_entry(self.filters["MIPS 70"], mips70, mips70_error) # 160 micron mips160 = 10.**mips160_log mips160_lower = 10.**mips160_log_lower mips160_upper = 10.**mips160_log_upper mips160_error = ErrorBar(mips160_lower, mips160_upper, at=mips160) sed.add_entry(self.filters["MIPS 160"], mips160, mips160_error) # Add the SED to the dictionary self.seds["SINGS"] = sed # ----------------------------------------------------------------- def get_lvl(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the LVL catalog ...") # Create an SED sed = ObservedSED() # "J/MNRAS/445/881": LVL global optical photometry (Cook+, 2014) # - "J/MNRAS/445/881/sample": Galaxies of the Spitzer Local Volume Legacy (LVL): properties (table1) and R25 photometry # - "J/MNRAS/445/881/table3": Photometry within the IR apertures of Dale et al. (2009, Cat. J/ApJ/703/517) (258 rows) # - "J/MNRAS/445/881/table4": Photometry within the UV apertures of Lee et al. (2011, Cat. J/ApJS/192/6) (258 rows) result = self.vizier.query_object(self.galaxy_name, catalog="J/MNRAS/445/881/sample") # ALL IN AB MAGNITUDE SYSTEM # Umag # Bmag # Vmag # Rmag # umag # gmag # rmag # imag # zmag # On SimBad, only sdss bands are used, from /sample ... relevant_bands = [("U", "U"), ("B", "B"), ("V", "V"), ("R", "R"), ("u", "SDSS u"), ("g", "SDSS g"), ("r", "SDSS r"), ("i", "SDSS i"), ("z", "SDSS z")] for band_prefix_catalog, filter_name in relevant_bands: column_name = band_prefix_catalog + "mag" error_column_name = "e_" + column_name # Skip masked values if result[0][column_name].mask[0]: continue # AB magnitude magnitude = result[0][0][column_name] magnitude_error = result[0][0][error_column_name] magnitude_lower = magnitude - magnitude_error magnitude_upper = magnitude + magnitude_error # Convert to Jy fluxdensity = unitconversion.ab_to_jansky(magnitude) fluxdensity_lower = unitconversion.ab_to_jansky(magnitude_upper) fluxdensity_upper = unitconversion.ab_to_jansky(magnitude_lower) fluxdensity_error = ErrorBar(fluxdensity_lower, fluxdensity_upper, at=fluxdensity) # Add data point to SED sed.add_entry(self.filters[filter_name], fluxdensity, fluxdensity_error) # Add the SED to the dictionary self.seds["LVL"] = sed # ----------------------------------------------------------------- def get_spitzer(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the Spitzer catalog ...") # "J/ApJ/703/517": The Spitzer Local Volume Legacy: IR photometry (Dale+, 2009) # "J/ApJ/703/517/sample": Galaxy sample (table 1) and infrared flux densities (table 2) (258 rows) # Create an SED sed = ObservedSED() result = self.vizier.query_object(self.galaxy_name, catalog="J/ApJ/703/517/sample") # F1.25: 2MASS J band (1.25 micron) flux density [Jy] # e_F1.25: Uncertainty in F1.25 [Jy] # F1.65: 2MASS H band (1.65 micron) flux density [Jy] # e_F1.65: Uncertainty in F1.65 [Jy] # F2.17: 2MASS Ks band (2.17 micron) flux density [Jy] # e_F2.17: Uncertainty in F2.17 [Jy] # F3.6: Spitzer/IRAC 3.5 micron band flux density [Jy] # e_F3.6: Uncertainty in F3.6 [Jy] # F4.5: Spitzer/IRAC 4.5 micron band flux density [Jy] # e_F4.5: Uncertainty in F4.5 [Jy] # F5.8: Spitzer/IRAC 5.8 micron band flux density [Jy] # e_F5.8: Uncertainty in F5.8 [Jy] # F8.0: Spitzer/IRAC 8.0 micron band flux density [Jy] # e_F8.0: Uncertainty in F8.0 [Jy] # F24: Spitzer/MIPS 24 micron flux density [Jy] # e_F24: Uncertainty in F24 [Jy] # F70: Spitzer/MIPS 70 micron band flux density [Jy] # e_F70: Uncertainty in F70 [Jy] # F160: Spitzer/MIPS 160 micron band flux density [Jy] # e_F160: Uncertainty in F160 [Jy] relevant_bands = [("1.25", "J"), ("1.65", "H"), ("2.17", "K"), ("3.6", "I1"), ("4.5", "I2"), ("5.8", "I3"), ("8.0", "I4"), ("24", "MIPS 24"), ("70", "MIPS 70"), ("160", "MIPS 160")] for band_prefix_catalog, filter_name in relevant_bands: column_name = "F" + band_prefix_catalog error_column_name = "e_" + column_name # Skip masked values if result[0][column_name].mask[0]: continue # Flux and error already in Jy fluxdensity = result[0][0][column_name] fluxdensity_error = ErrorBar(result[0][0][error_column_name]) # Add data point to SED sed.add_entry(self.filters[filter_name], fluxdensity, fluxdensity_error) # Add the SED to the dictionary self.seds["Spitzer"] = sed # ----------------------------------------------------------------- def get_spitzer_irs(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the Spitzer/IRS catalog ...") # "J/MNRAS/414/500": Spitzer/IRS ATLAS project source (Hernan-Caballero+, 2011) # - "J/MNRAS/414/500/catalog": Spitzer/IRS ATLAS project source catalog, version 1.0 (739 rows) # !! Parentheses () are converted into underscores _ in the resulting Astropy tables!! # F(3.6): IRAC1 (3.6um) flux density [Jy] # e_F(3.6): rms uncertainty on F(3.6) [Jy] # F(8.0): IRAC4 (8.0um) flux density [Jy] # e_F(8.0): rms uncertainty on F(8.0) [Jy] # F(24): 24um flux density [Jy] # e_F(24): rms uncertainty on F(24) [Jy] # F(70): 70um or similar band flux density [Jy] # e_F(70): rms uncertainty on F(70) [Jy] # Create an SED sed = ObservedSED() result = self.vizier.query_object(self.galaxy_name, catalog="J/MNRAS/414/500/catalog") relevant_bands = [("3.6", "I1"), ("8.0", "I4"), ("24", "MIPS 24"), ("70", "MIPS 70")] for band_prefix_catalog, filter_name in relevant_bands: column_name = "F_" + band_prefix_catalog + "_" error_column_name = "e_" + column_name # Skip masked values if result[0][column_name].mask[0]: continue # Flux and error already in Jy fluxdensity = result[0][0][column_name] fluxdensity_error = ErrorBar(result[0][0][error_column_name]) # Add data point to SED sed.add_entry(self.filters[filter_name], fluxdensity, fluxdensity_error) # Add the SED to the dictionary self.seds["Spitzer-IRS"] = sed # ----------------------------------------------------------------- def get_iras(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the IRAS catalog ...") # "J/ApJS/178/280": Compendium of ISO far-IR extragalactic data (Brauher+, 2008) # - "J/ApJS/178/280/table1": *Galaxies and properties # F12: IRAS 12um band flux density [Jy] # F25: IRAS 25um band flux density [Jy] # F60: IRAS 60um band flux density [Jy] # F100: IRAS 100um band flux density [Jy] # No errors ... # Create an SED sed = ObservedSED() result = self.vizier.query_object(self.galaxy_name, catalog="J/ApJS/178/280/table1") relevant_bands = [("12", "IRAS 12"), ("25", "IRAS 25"), ("60", "IRAS 60"), ("100", "IRAS 100")] for band_prefix_catalog, filter_name in relevant_bands: column_name = "F" + band_prefix_catalog # Skip masked values if result[0][column_name].mask[0]: continue # Flux and error already in Jy fluxdensity = result[0][0][column_name] fluxdensity_error = ErrorBar(0.0) # Add data point to SED sed.add_entry(self.filters[filter_name], fluxdensity, fluxdensity_error) # Add the SED to the dictionary self.seds["IRAS"] = sed # ----------------------------------------------------------------- def get_iras_fsc(self): """ This function ... :return: """ # Inform the user log.info("Getting fluxes from the IRAS-FSC catalog ...") # "J/MNRAS/398/109": Imperial IRAS-FSC redshift catalogue (IIFSCz) (Wang+, 2009) # - "J/MNRAS/398/109/iifsczv4": IIFSCz Catalogue (MRR+LW 18/04/09)[spectrum/SED] (60303 rows) # S12um: IRAS-FSC flux at 12um [Jy] # S25um: IRAS-FSC flux at 25um [Jy] # S60um: IRAS-FSC flux at 60um [Jy] # S100um: IRAS-FSC flux at 100um [Jy] # not used in Simbad: # umag: SDSS u magnitude [mag: which system??] # e_umag: # gmag: # e_gmag: # rmag: # e_rmag: # imag: # e_imag: # zmag: # e_zmag: # Jmag: 2MASS J magnitude [mag: which system??] # e_Jmag: rms uncertainty on Jmag [mag: which system??] # Hmag: 2MASS H magnitude [mag] # e_Hmag: rms uncertainty on Hmag [mag] # Kmag: 2MASS K magnitude [mag] # e_Kmag rms uncertainty on Kmag [mag] # Create an SED sed = ObservedSED() result = self.vizier.query_object(self.galaxy_name, catalog="J/MNRAS/398/109/iifsczv4") relevant_bands = [("12", "IRAS 12"), ("25", "IRAS 25"), ("60", "IRAS 60"), ("100", "IRAS 100")] for band_prefix_catalog, filter_name in relevant_bands: # Flux and error already in Jy fluxdensity = result[0][0]["S" + band_prefix_catalog + "um"] fluxdensity_error = ErrorBar(0.0) # Add data point to SED sed.add_entry(self.filters[filter_name], fluxdensity, fluxdensity_error) # Add the SED to the dictionary self.seds["IRAS-FSC"] = sed # ----------------------------------------------------------------- def get_s4g(self): """ This function ... :return: """ # Create an SED sed = ObservedSED() # Get parameters from S4G catalog result = self.vizier.query_object(self.galaxy_name, catalog=["J/PASP/122/1397/s4g"]) table = result[0] # Magnitudes i1_mag = table["__3.6_"][0] i2_mag = table["__4.5_"][0] i1_mag_error = table["e__3.6_"][0] i2_mag_error = table["e__4.5_"][0] i1_fluxdensity = unitconversion.ab_to_jansky(i1_mag) i1_fluxdensity_lower = unitconversion.ab_to_jansky(i1_mag + i1_mag_error) i1_fluxdensity_upper = unitconversion.ab_to_jansky(i1_mag - i1_mag_error) i1_error = ErrorBar(i1_fluxdensity_lower, i1_fluxdensity_upper, at=i1_fluxdensity) # Add data point to SED sed.add_entry(self.filters["I1"], i1_fluxdensity, i1_error) i2_fluxdensity = unitconversion.ab_to_jansky(i2_mag) i2_fluxdensity_lower = unitconversion.ab_to_jansky(i2_mag + i2_mag_error) i2_fluxdensity_upper = unitconversion.ab_to_jansky(i2_mag - i2_mag_error) i2_error = ErrorBar(i2_fluxdensity_lower, i2_fluxdensity_upper, at=i2_fluxdensity) # Add data point to SED sed.add_entry(self.filters["I2"], i2_fluxdensity, i2_error) # Add the SED to the dictionary self.seds["S4G"] = sed # ----------------------------------------------------------------- def get_brown(self): """ This function ... :return: """ # J/ApJS/212/18/sample # AB magnitudes for the sample with neither foreground nor intrinsic dust extinction corrections, and modeled Milky Way foreground dust extinction # Create an SED sed = ObservedSED() # FUV: [12.5/22.9] GALEX FUV AB band magnitude # e_FUV: # UVW2: # e_UVW2: # UVM2: # e_UVM2: # NUV: # e_NUV: # UVW1: # e_UVW1: # Umag: [11.9/15.7] Swift/UVOT U AB band magnitude # e_Umag: # umag: # e_umag: # gmag: # e_gmag: # Vmag: # e_Vmag: # rmag: # e_rmag: # imag: # e_imag: # zmag: # e_zmag: # Jmag: # e_Jmag: # Hmag: # e_Hmag: # Ksmag: # e_Ksmag: # W1mag: # e_W1mag: # [3.6]: # e_[3.6]: # [4.5]: # e_[4.5]: # W2mag: # e_W2mag: # [5.8]: # e_[5.8]: # [8.0]: # e_[8.0]: # W3mag: # e_W3mag: # W4mag: # e_W4mag: # W4'mag: Corrected WISE W4 AB band magnitude # e_W4'mag: # [24]: # e_[24]: pass # ----------------------------------------------------------------- def get_planck(self): """ This function ... :return: """ # Create an SED sed = ObservedSED() # The second release is not yet available ... ?? # ----------------------------------------------------------------- def get_emission_lines(self): """ This function ... :return: """ # Create an SED sed = ObservedSED() # J/ApJS/190/233/Opt # Get result result = self.vizier.get_catalogs("J/ApJS/190/233/Opt") table = result[0] galaxy_index = tables.find_index(table, self.ngc_id, "Name") # FHa: The Hα 6563 Angstrom line flux (aW/m2) # e_FHa: Uncertainty in Ha (aW/m2) # FNII: The [NII] 6584Å line flux (aW/m2) # e_FNII: Uncertainty in NII (aW/m2) # H alpha ha_flux = table["FHa"][galaxy_index] * Unit("aW/m2") ha_flux_error = table["e_FHa"][galaxy_index] * Unit("aW/m2") # NII n2_flux = table["FNII"][galaxy_index] * Unit("aW/m2") n2_flux_error = table["e_FNII"][galaxy_index] * Unit("aW/m2") ha_filter = self.filters["Ha"] ha_wavelength = ha_filter.centerwavelength() * Unit("micron") ha_frequency = ha_wavelength.to("Hz", equivalencies=spectral()) # Calculate flux density ha_fluxdensity = (ha_flux / ha_frequency).to("Jy") ha_fluxdensity_error = (ha_flux_error / ha_frequency).to("Jy") ha_errorbar = ErrorBar(ha_fluxdensity_error) # Add entry sed.add_entry(ha_filter, ha_fluxdensity, ha_errorbar) # Add the SED to the dictionary self.seds["Lines"] = sed # ----------------------------------------------------------------- def get_m81(self): """ This function ... :return: """ # UV through far-IR analysis of M81 (Perez-Gonzalez+, 2006) # "J/ApJ/648/987" # Two tables: # - "J/ApJ/648/987/table1": Positions and photometry (GLOBALBKG and LOCALBKG cases) for the regions selected at 160um resolution # - "J/ApJ/648/987/table2": Positions and photometry for the regions selected at 24um resolution # Table 1 #result = self.vizier.query_object(self.galaxy_name, catalog="J/ApJ/648/987/table1") # Looks like this (only 3 matches) #1 M81 09 55 32.2 +69 03 59.0 680.0 40.78 43.18 42.84 42.63 42.61 41.98 42.67 42.99 #2 Reg02 09 55 32.2 +69 03 59.0 64.0 39.67 42.63 42.28 41.98 41.76 41.25 41.83 41.78 #3 Reg03 09 55 32.2 +69 03 59.0 104.0 39.40 42.38 42.03 41.76 41.58 40.90 41.62 41.78 #galaxy_index = tables.find_index(result, self.galaxy_name) # Table 2 # Interesting rows: # - logLFUV: Log of the FUV luminosity [1e-7 W] or [erg/s] # - logLNUV: Log of the NUV luminosity [1e-7 W] or [erg/s] # - logLHa: Log of the H-alpha luminosity [1e-7 W] or [erg/s] # - logL8: Log of the 8um luminosity [1e-7 W] or [erg/s] # - logL24: Log of the 24um luminosity [1e-7 W] or [erg/s] result = self.vizier.query_object(self.galaxy_name, catalog="J/ApJ/648/987/table2") galaxy_index = tables.find_index(result[0], self.galaxy_name) # Create an SED sed = ObservedSED() relevant_bands = [("FUV", "FUV"), ("NUV", "NUV"), ("Ha", "Ha"), ("8", "I4"), ("24", "MIPS 24")] for band_prefix_catalog, filter_name in relevant_bands: # Flux and error already in Jy log = result[0][galaxy_index]["logL" + band_prefix_catalog] flux = 10.**log # In erg/s frequency = 0.0 # TODO: calculate this! # Also: calculate the amount of flux per unit area ! : divide also by 4 pi d_galaxy**2 ! fluxdensity = flux / frequency fluxdensity_error = ErrorBar(0.0) # Add data point to SED sed.add_entry(self.filters[filter_name], fluxdensity, fluxdensity_error) # Add the SED to the dictionary self.seds["IRAS-FSC"] = sed # ----------------------------------------------------------------- def write(self): """ This function ... :return: """ # Inform the user log.info("Writing ...") # If requested, write out the SEDs if self.config.write_seds: self.write_seds() # ----------------------------------------------------------------- def write_seds(self): """ This function ... :return: """ # Inform the user log.info("Writing the SEDs ...") # Determine the full path to the SEDs directory path = self.full_output_path(self.config.writing.seds_path) # Create the SEDs directory if necessary fs.create_directory(path) # Loop over the different SEDs for label in self.seds: # Debugging info log.debug("Writing SED from " + label) # Determine the path to the new SED file sed_path = fs.join(path, label + ".dat") # Save the SED at the specified location self.seds[label].save(sed_path)
delete_old_event_files() # Import data provided directly to OSC #if do_task('internal'): # for datafile in sorted(glob.glob("../tde-internal/*.json"), key=lambda s: s.lower()): # if not load_event_from_file(location = datafile, clean = True, delete = False): # raise IOError('Failed to find specified file.') # journal_events() # Import primary data sources from Vizier if do_task('vizier'): Vizier.ROW_LIMIT = -1 # VizieR imports go here # 2010ApJ...725..331Y result = Vizier.get_catalogs("J/ApJ/725/331/table7") table = result[list(result.keys())[0]] table.convert_bytestring_to_unicode(python3_only=True) for row in table: name = row['Name'] name = add_event(name) source = get_source(name, bibcode = '2010ApJ...725..331Y') add_quanta(name, 'ra', str(row['_RA']), source, unit = 'radeg') add_quanta(name, 'dec', str(row['_DE']), source, unit = 'decdeg') add_quanta(name, 'ora', str(row['oRA']), source) add_quanta(name, 'odec', str(row['oDE']), source) journal_events() if do_task('writeevents'): files = [] for rep in repfolders:
mass-luminosity and mass-temperature diagrams populating the main sequence only with data from Ekström+ 2012 (Vizier catalog J/A+A/537/A146/iso). Colors come from vendian.org. """ import numpy as np import imf import pylab as pl from astroquery.vizier import Vizier from labellines import labelLine, labelLines pl.rcParams['font.size'] = 20 Vizier.ROW_LIMIT=1e7 tbl = Vizier.get_catalogs('J/A+A/537/A146/iso')[0] agemass = {} agelum = {} for age in np.unique(tbl['logAge']): agemass[age] = tbl[tbl['logAge']==age]['Mass'].max() agelum[age] = tbl[tbl['logAge']==age]['logL'].max() # mass-temperature diagram pl.figure(2, figsize=(8,8)).clf() # select a specific population age to plot - this is the youngest, with all # stars alive and main-sequence ok = tbl['logAge'] == 6.5
# '<f4', # '<i2', # '<f4', # '<f4', # '<f4', # '<f4', # '<f4'] # Try the *UPDATED* catalog (2009AJ....137.4186L) # but update the "outputNames" to match ########### # It should be possible to significantly increase the sample by using the more # recent data at +50 deg. declination found in "2013AJ....146..131L" ########### landoltStars = (Vizier.get_catalogs('J/AJ/137/4186'))[0] outputNames = ['_RAJ2000', '_DEJ2000', 'Name', 'Vmag', 'e_Vmag', 'B-V', 'e_B-V', 'U-B', 'e_U-B', 'V-R', 'e_V-R', 'R-I', 'e_R-I', 'V-I',
class GalaxyDecomposer(DecompositionComponent): """ This class... """ def __init__(self, config=None): """ The constructor ... :param config: :return: """ # Call the constructor of the base class super(GalaxyDecomposer, self).__init__(config) # The NGC name of the galaxy self.ngc_id = None self.ngc_id_nospaces = None # The Vizier querying object self.vizier = Vizier() self.vizier.ROW_LIMIT = -1 # The bulge and disk parameters self.parameters = Map() # The SKIRT execution context self.skirt = SkirtExec() # The bulge and disk model self.bulge = None self.disk = None # The bulge and disk image self.bulge_image = None self.disk_image = None self.model_image = None # The projection systems self.projections = dict() # The instruments self.instruments = dict() # The reference coordinate system self.reference_wcs = None # The PSF (of the reference image) for convolution with the simulated images self.psf = None # ----------------------------------------------------------------- @classmethod def from_arguments(cls, arguments): """ This function ... :param arguments: :return: """ # Create a new GalaxyDecomposer instance decomposer = cls(arguments.config) # Set the input and output path decomposer.config.path = arguments.path # Return the new instance return decomposer # ----------------------------------------------------------------- def run(self): """ This function ... :return: """ # 1. Call the setup function self.setup() # 2. Get the parameters self.get_parameters() # 3. Create the models self.create_models() # 4. Create the projection systems self.create_projections() # 4. Create the instruments self.create_instruments() # 2. Simulate the bulge and disk images self.simulate() # 3. Writing self.write() # ----------------------------------------------------------------- def setup(self): """ This function ... :return: """ # Call the setup function of the base class super(GalaxyDecomposer, self).setup() # TEMP: provide a cfg file for this class self.config.bulge_packages = 1e7 self.config.disk_packages = 1e8 # Get the NGC name of the galaxy self.ngc_id = catalogs.get_ngc_name(self.galaxy_name) self.ngc_id_nospaces = self.ngc_id.replace(" ", "") # Get the coordinate system describing the pixel grid of the prepared images reference_path = fs.join(self.prep_path, self.reference_image, "result.fits") self.reference_wcs = CoordinateSystem.from_file(reference_path) # Load the PSF aniano = AnianoKernels() self.psf = aniano.get_psf("PACS_160") # ----------------------------------------------------------------- def get_parameters(self): """ This function ... :return: """ # Inform the user log.info("Getting the structural galaxy parameters from the S4G catalog ...") # Tracing spiral density waves in M81: (Kendall et. al, 2008) # - Sersic bulge: # n = 2.62 # Re = 46.2 arcsec # b/a = 0.71 # PA = −31.9° # - Exponential disk: # Rs = 155.4 arcsec # b/a = 0.52 # PA = −28.3° # Query the S4G catalog using Vizier for general parameters self.get_general_parameters() # Get the decomposition parameters #self.get_p4() currently (writing on 31 of march 2016) there is a problem with the effective radius values # (at least for M81) on Vizier as well as in the PDF version of table 7 (S4G models homepage). # Parse the S4G table 8 to get the decomposition parameters self.get_parameters_from_table() #self.parameters.bulge.n = 2.62 #self.parameters.bulge.PA = Angle(-31.9 + 90., "deg") #self.parameters.bulge.q = 0.71 #value = 46.2 * Unit("arcsec") #self.parameters.bulge.Re = (self.parameters.distance * value).to("pc", equivalencies=dimensionless_angles()) #value = 155.4 * Unit("arcsec") #self.parameters.disk.hr = (self.parameters.distance * value).to("pc", equivalencies=dimensionless_angles()) #self.parameters.disk.q = 0.52 #self.parameters.disk.PA = Angle(-28.3 + 90., "deg") # ----------------------------------------------------------------- def get_general_parameters(self): """ This function ... :return: """ # Inform the user log.info("Querying the S4G catalog ...") # Get parameters from S4G catalog result = self.vizier.query_object(self.galaxy_name, catalog=["J/PASP/122/1397/s4g"]) table = result[0] # Galaxy name for S4G catalog self.parameters.galaxy_name = table["Name"][0] # Galaxy center from decomposition (?) ra_center = table["_RAJ2000"][0] dec_center = table["_DEJ2000"][0] center = SkyCoordinate(ra=ra_center, dec=dec_center, unit="deg", frame='fk5') self.parameters.center = center # Distance self.parameters.distance = table["Dmean"][0] * Unit("Mpc") self.parameters.distance_error = table["e_Dmean"][0] * Unit("Mpc") # Major axis, ellipticity, position angle self.parameters.major_arcsec = table["amaj"][0] * Unit("arcsec") self.parameters.major = (self.parameters.distance * self.parameters.major_arcsec).to("pc", equivalencies=dimensionless_angles()) # Ellipticity self.parameters.ellipticity = table["ell"][0] self.parameters.position_angle = Angle(table["PA"][0] + 90.0, Unit("deg")) # Magnitudes asymptotic_ab_magnitude_i1 = table["__3.6_"][0] asymptotic_ab_magnitude_i2 = table["__4.5_"][0] asymptotic_ab_magnitude_i1_error = table["e__3.6_"][0] asymptotic_ab_magnitude_i2_error = table["e__4.5_"][0] self.parameters.i1_mag = asymptotic_ab_magnitude_i1 self.parameters.i1_mag_error = asymptotic_ab_magnitude_i1_error self.parameters.i2_mag = asymptotic_ab_magnitude_i2 self.parameters.i2_mag_error = asymptotic_ab_magnitude_i2_error self.parameters.i1_fluxdensity = unitconversion.ab_to_jansky(self.parameters.i1_mag) * Unit("Jy") i1_fluxdensity_lower = unitconversion.ab_to_jansky(self.parameters.i1_mag + self.parameters.i1_mag_error) * Unit("Jy") i1_fluxdensity_upper = unitconversion.ab_to_jansky(self.parameters.i1_mag - self.parameters.i1_mag_error) * Unit("Jy") i1_error = ErrorBar(i1_fluxdensity_lower, i1_fluxdensity_upper, at=self.parameters.i1_fluxdensity) self.parameters.i1_error = i1_error.average self.parameters.i2_fluxdensity = unitconversion.ab_to_jansky(self.parameters.i2_mag) * Unit("Jy") i2_fluxdensity_lower = unitconversion.ab_to_jansky(self.parameters.i2_mag + self.parameters.i2_mag_error) * Unit("Jy") i2_fluxdensity_upper = unitconversion.ab_to_jansky(self.parameters.i2_mag - self.parameters.i2_mag_error) * Unit("Jy") i2_error = ErrorBar(i2_fluxdensity_lower, i2_fluxdensity_upper, at=self.parameters.i2_fluxdensity) self.parameters.i2_error = i2_error.average # Other ... #absolute_magnitude_i1 = table["M3.6"][0] #absolute_magnitude_i2 = table["M4.5"][0] #stellar_mass = 10.0**table["logM_"][0] * u.Unit("Msun") # Inform the user log.info("Querying the catalog of radial profiles for 161 face-on spirals ...") # Radial profiles for 161 face-on spirals (Munoz-Mateos+, 2007) radial_profiles_result = self.vizier.query_object(self.galaxy_name, catalog="J/ApJ/658/1006") distance = float(radial_profiles_result[0][0]["Dist"]) inclination = Angle(float(radial_profiles_result[0][0]["i"]), "deg") # Set the inclination self.parameters.inclination = inclination # ----------------------------------------------------------------- def get_p4(self): """ This function ... :return: """ #http://vizier.cfa.harvard.edu/viz-bin/VizieR?-source=J/ApJS/219/4 # J/ApJS/219/4: S4G pipeline 4: multi-component decompositions (Salo+, 2015) # - J/ApJS/219/4/galaxies: Parameters of the galaxies; center, outer orientation, sky background; and 1-component Sersic fits (tables 1 and 6) (2352 rows) # - J/ApJS/219/4/table7: *Parameters of final multicomponent decompositions (Note) (4629 rows) # Inform the user log.info("Querying the S4G pipeline 4 catalog ...") # Get the "galaxies" table result = self.vizier.query_object(self.galaxy_name, catalog=["J/ApJS/219/4/galaxies"]) table = result[0] # PA: [0.2/180] Outer isophote position angle # e_PA: [0/63] Standard deviation in PA # Ell: [0.008/1] Outer isophote ellipticity # e_Ell: [0/0.3] Standard deviation in Ell pa = Angle(table["PA"][0] - 90., "deg") pa_error = Angle(table["e_PA"][0], "deg") ellipticity = table["Ell"][0] ellipticity_error = table["e_Ell"][0] # Get the "table7" table result = self.vizier.get_catalogs("J/ApJS/219/4/table7") table = result[0] # Name: Galaxy name # Mod: Type of final decomposition model # Nc: [1/4] Number of components in the model (1-4) # Q: [3/5] Quality flag, 5=most reliable # C: Physical interpretation of the component # Fn: The GALFIT function used for the component (sersic, edgedisk, expdisk, ferrer2 or psf) # f1: [0.006/1] "sersic" fraction of the total model flux # mag1: [7/19.4] "sersic" total 3.6um AB magnitude # q1: [0.1/1] "sersic" axis ratio # PA1: [0.08/180] "sersic" position angle [deg] # Re: [0.004/430] "sersic" effective radius (Re) [arcsec] # n: [0.01/20] "sersic" parameter n # f2: [0.02/1] "edgedisk" fraction of the total model flux # mu02: [11.8/24.6] "edgedisk" central surface face-on brightness (µ0) [mag/arcsec2] # PA2: [-90/90] "edgedisk" PA [deg] # hr2: [1/153] "edgedisk" exponential scale length (hr) [arcsec] # hz2: [0.003/39] "edgedisk" z-scale hz [arcsec] # f3: [0.02/1] "expdisk" fraction of the total model flux # mag3: [6.5/18.1] "expdisk" total 3.6um AB magnitude [mag] # q3: [0.1/1] "expdisk" axis ratio # PA3: [-90/90] "expdisk" position angle [deg] # hr3: [0.7/332] "expdisk" exponential scale length (hr) [arcsec] # mu03: [16.4/25.3] "expdisk" central surface face-on brightness (µ0) [mag/arcsec2] # f4: [0.003/0.6] "ferrer2" fraction of the total model flux # mu04: [16/24.8] "ferrer2" central surface sky brightness (µ0) [mag/arcsec2] # q4: [0.01/1] "ferrer2" axis ratio # PA4: [-90/90] "ferrer2" position angle [deg] # Rbar: [3.7/232.5] "ferrer2" outer truncation radius of the bar (Rbar) [arcsec] # f5: [0.001/0.4] "psf" fraction of the total model flux # mag5: [11.5/21.1] "psf" total 3.6um AB magnitude [mag] indices = tables.find_indices(table, self.ngc_id_nospaces, "Name") labels = {"sersic": 1, "edgedisk": 2, "expdisk": 3, "ferrer2": 4, "psf": 5} #units = {"f": None, "mag": "mag", "q": None, "PA": "deg", } # Loop over the indices for index in indices: model_type = table["Mod"][index] number_of_components = table["Nc"][index] quality = table["Q"][index] interpretation = table["C"][index] functionname = table["Fn"][index] component_parameters = Map() if self.parameters.model_type is not None: assert model_type == self.parameters.model_type if self.parameters.number_of_components is not None: assert number_of_components == self.parameters.number_of_components if self.parameters.quality is not None: assert quality == self.parameters.quality self.parameters.model_type = model_type self.parameters.number_of_components = number_of_components self.parameters.quality = quality for key in table.colnames: if not key.endswith(str(labels[functionname])): continue parameter = key[:-1] value = table[key][index] if parameter == "PA": value = Angle(value + 90., "deg") if quadrant(value) == 2: value = value - Angle(180., "deg") elif quadrant(value) == 3: value = value + Angle(180., "deg") if value.to("deg").value > 180.: value = value - Angle(360., "deg") elif value.to("deg").value < -180.: value = value + Angle(360., "deg") elif parameter == "mag": parameter = "fluxdensity" value = unitconversion.ab_to_jansky(value) * Unit("Jy") elif parameter == "mu0": value = value * Unit("mag/arcsec2") elif parameter == "hr": value = value * Unit("arcsec") value = (self.parameters.distance * value).to("pc", equivalencies=dimensionless_angles()) elif parameter == "hz": value = value * Unit("arcsec") value = (self.parameters.distance * value).to("pc", equivalencies=dimensionless_angles()) component_parameters[parameter] = value if functionname == "sersic": re = table["Re"][index] * Unit("arcsec") component_parameters["Re"] = (self.parameters.distance * re).to("pc", equivalencies=dimensionless_angles()) component_parameters["n"] = table["n"][index] elif functionname == "ferrer2": rbar = table["Rbar"][index] * Unit("arcsec") component_parameters["Rbar"] = (self.parameters.distance * rbar).to("pc", equivalencies=dimensionless_angles()) if interpretation == "B": # bulge self.parameters.bulge = component_parameters elif interpretation == "D": # disk self.parameters.disk = component_parameters else: raise RuntimeError("Unrecognized component: " + interpretation) # Determine the full path to the parameters file path = fs.join(self.components_path, "parameters.dat") # Write the parameters to the specified location write_parameters(self.parameters, path) # ----------------------------------------------------------------- def get_parameters_from_table(self): """ This function ... :return: """ # Inform the user log.info("Parsing S4G table 8 to get the decomposition parameters ...") #The table columns are: # (1) the running number (1-2352), # (2) the galaxy name, # (3) the type of final decomposition model, # (4) the number N of components in the final model , and # (5) the quality flag Q. # 6- 8 for unresolved central component ('psf'; phys, frel, mag), # 9-15 for inner sersic-component ('sersic1'; phys, frel, mag, re, ar, pa, n), # 16-22 for inner disk-component ('expo1'; phys, frel, mag, hr, ar, pa, mu0), # 23-28 for inner ferrers-component ('ferrers1'; phys, frel, mu0, rout, ar, pa), # 29-34 for inner edge-on disk component ('edgedisk1'; phys, frel, mu0, rs, hs, pa ). # 35-41 for outer sersic-component ('sersic2'; phys, frel, mag, re, ar, pa, n), # 42-49 for outer disk-component ('expo2'; phys, frel, mag, hr, ar, pa, mu0), # 50-55 for outer ferrers-component ('ferrers2'; phys, frel, mu0, rout, ar, pa), # 56-61 for outer edge-on disk component ('edgedisk2'; phys, frel, mu0, rs, hs, pa ). sersic_1_index = 8 disk_1_index = 15 #For each function: #the first entry stands for the physical intepretation of the component: #'N' for a central source (or unresolved bulge), 'B' for a bulge (or elliptical), 'D' for a disk, 'BAR' for a bar, and 'Z' for an edge-on disk. # 'rel = the relative contribution of the component to the total model flux, # mag = the component's total 3.6 micron AB magnitude, # mu0 = the central surface brightness (mag/arcsec^2; de-projected central surface brightness for expdisk and edgedisk, and # sky-plane central surface brightness for ferrer) # ar = axial ratio # pa = position angle (degrees ccw from North) # n = sersic index # hr = exponential scale lenght (arcsec) # rs = radial scale lenght (arcsec) # hs = vertical scale height (arcsec) # rout = bar outer truncation radius (arcsec) # SERSIC: phys, frel, mag, re, ar, pa, n # DISK: phys, frel, mag, hr, ar, pa, mu0 with open(local_table_path, 'r') as s4g_table: for line in s4g_table: splitted = line.split() if len(splitted) < 2: continue name = splitted[1] # Only look at the line corresponding to the galaxy if name != self.ngc_id_nospaces: continue self.parameters.model_type = splitted[2] self.parameters.number_of_components = splitted[3] self.parameters.quality = splitted[4] # BULGE self.parameters.bulge = Map() #self.parameters.bulge.interpretation = splitted[sersic_1_index].split("|")[1] self.parameters.bulge.f = float(splitted[sersic_1_index + 1]) mag = float(splitted[sersic_1_index + 2]) self.parameters.bulge.fluxdensity = unitconversion.ab_to_jansky(mag) * Unit("Jy") # Effective radius in pc re_arcsec = float(splitted[sersic_1_index + 3]) * Unit("arcsec") self.parameters.bulge.Re = (self.parameters.distance * re_arcsec).to("pc", equivalencies=dimensionless_angles()) self.parameters.bulge.q = float(splitted[sersic_1_index + 4]) self.parameters.bulge.PA = Angle(float(splitted[sersic_1_index + 5]) - 90., "deg") self.parameters.bulge.n = float(splitted[sersic_1_index + 6]) # DISK self.parameters.disk = Map() #self.parameters.disk.interpretation = splitted[disk_1_index].split("|")[1] self.parameters.disk.f = float(splitted[disk_1_index + 1]) mag = float(splitted[disk_1_index + 2]) self.parameters.disk.fluxdensity = unitconversion.ab_to_jansky(mag) * Unit("Jy") # Scale length in pc hr_arcsec = float(splitted[disk_1_index + 3]) * Unit("arcsec") self.parameters.disk.hr = (self.parameters.distance * hr_arcsec).to("pc", equivalencies=dimensionless_angles()) self.parameters.disk.q = float(splitted[disk_1_index + 4]) # axial ratio self.parameters.disk.PA = Angle(float(splitted[disk_1_index + 5]) - 90., "deg") self.parameters.disk.mu0 = float(splitted[disk_1_index + 6]) * Unit("mag/arcsec2") # ----------------------------------------------------------------- def get_spiral_properties(self): """ This function ... :return: """ # http://vizier.cfa.harvard.edu/viz-bin/VizieR?-source=J/A+A/582/A86 # J/A+A/582/A86: Catalogue of features in the S4G (Herrera-Endoqui+, 2015) # - J/A+A/582/A86/table2: Properties of bars, ring- and lens-structures in the S4G (2387 rows) # - J/A+A/582/A86/table3: Properties of spiral arms in the S4G (1854 rows) # Get table2 result = self.vizier.query_object(self.galaxy_name, catalog=["J/A+A/582/A86/table2"]) table = result[0] # Name: Galaxy name # Class: Morphological classification # Type: Type of feature # sma: Semi-major axis [arcsec] # PA: Position angle [deg] # Ell: Ellipticity # smaEll: Semi-major axis from ellipticity [arcsec] # dsma: Deprojected semi-major axis [arcsec] # dPA: Deprojected position angle [deg] # dEll: Deprojected ellipticity # dsmaEll: Deprojexted semi-major axis from Ell [arcsec] # Qual: [1/3] Quality flag # Get table 3 result = self.vizier.query_object(self.galaxy_name, catalog=["J/A+A/582/A86/table3"]) table = result[0] # Name: Galaxy name # Class: Morphological classification # Type: Type of arms # Segment: Segment # Pitchang: Pitch angle [deg] # ri: Inner radius [arcsec] # ro: Outer radius [arcsec] # Qual: [1/2] Quality flag # ----------------------------------------------------------------- def create_models(self): """ :return: """ # Create the bulge model self.create_bulge_model() # Create the disk model self.create_disk_model() # ----------------------------------------------------------------- def create_bulge_model(self): """ :return: """ # Create a Sersic model for the bulge self.bulge = SersicModel.from_galfit(self.parameters.bulge, self.parameters.inclination, self.parameters.disk.PA) # ----------------------------------------------------------------- def create_disk_model(self): """ :return: """ # Create an exponential disk model for the disk self.disk = ExponentialDiskModel.from_galfit(self.parameters.disk, self.parameters.inclination, self.parameters.disk.PA) # ----------------------------------------------------------------- def create_projections(self): """ This function ... :return: """ # Inform the user log.info("Creating the projection systems ...") # Create the 'earth' projection system azimuth = 0.0 self.projections["earth"] = GalaxyProjection.from_wcs(self.reference_wcs, self.parameters.center, self.parameters.distance, self.parameters.inclination, azimuth, self.parameters.disk.PA) # Create the face-on projection system self.projections["faceon"] = FaceOnProjection.from_wcs(self.reference_wcs, self.parameters.center, self.parameters.distance) # Create the edge-on projection system self.projections["edgeon"] = EdgeOnProjection.from_wcs(self.reference_wcs, self.parameters.center, self.parameters.distance) # ----------------------------------------------------------------- def create_instruments(self): """ This function ... :return: """ # Inform the user log.info("Creating the instruments ...") # Loop over the projection systems for name in self.projections: # Create the instrument from the projection system self.instruments[name] = SimpleInstrument.from_projection(self.projections[name]) # ----------------------------------------------------------------- def simulate(self): """ This function ... :return: """ # Simulate the stellar bulge without deprojection self.simulate_bulge_simple() # Simulate the stellar bulge self.simulate_bulge() # Simulate the stellar disk self.simulate_disk() # Simulate the bulge + disk model self.simulate_model() # ----------------------------------------------------------------- def simulate_bulge_simple(self): """ :return: """ # Inform the user log.info("Creating ski file to simulate the bulge image ...") # Load the bulge ski file template bulge_template_path = fs.join(template_path, "bulge.ski") ski = SkiFile(bulge_template_path) # Set the number of photon packages ski.setpackages(self.config.bulge_packages) # Change the ski file parameters # component_id, index, radius, y_flattening=1, z_flattening=1 ski.set_stellar_component_sersic_geometry(0, self.parameters.bulge.n, self.parameters.bulge.Re, y_flattening=self.parameters.bulge.q) # Remove all existing instruments ski.remove_all_instruments() # Create the instrument distance = self.parameters.distance inclination = 0.0 azimuth = Angle(90., "deg") #position_angle = self.parameters.bulge.PA + Angle(90., "deg") # + 90° because we can only do y_flattening and not x_flattening position_angle = self.parameters.bulge.PA pixels_x = self.reference_wcs.xsize pixels_y = self.reference_wcs.ysize pixel_center = self.parameters.center.to_pixel(self.reference_wcs) center = Position(0.5*pixels_x - pixel_center.x - 0.5, 0.5*pixels_y - pixel_center.y - 0.5) center_x = center.x * Unit("pix") center_y = center.y * Unit("pix") center_x = (center_x * self.reference_wcs.pixelscale.x.to("deg/pix") * distance).to("pc", equivalencies=dimensionless_angles()) center_y = (center_y * self.reference_wcs.pixelscale.y.to("deg/pix") * distance).to("pc", equivalencies=dimensionless_angles()) field_x_angular = self.reference_wcs.pixelscale.x.to("deg/pix") * pixels_x * Unit("pix") field_y_angular = self.reference_wcs.pixelscale.y.to("deg/pix") * pixels_y * Unit("pix") field_x_physical = (field_x_angular * distance).to("pc", equivalencies=dimensionless_angles()) field_y_physical = (field_y_angular * distance).to("pc", equivalencies=dimensionless_angles()) fake = SimpleInstrument(distance, inclination, azimuth, position_angle, field_x_physical, field_y_physical, pixels_x, pixels_y, center_x, center_y) # Add the instrument ski.add_instrument("earth", fake) # Create the directory to simulate the bulge simple_bulge_directory = fs.join(self.components_path, "bulge_simple") fs.create_directory(simple_bulge_directory) # Determine the path to the ski file ski_path = fs.join(simple_bulge_directory, "bulge.ski") # Save the ski file to the new path ski.saveto(ski_path) # Determine the path to the simulation output directory out_path = fs.join(simple_bulge_directory, "out") # Create the output directory fs.create_directory(out_path) # Create a SkirtArguments object arguments = SkirtArguments() # Adjust the parameters arguments.ski_pattern = ski_path arguments.output_path = out_path arguments.single = True # we expect a single simulation from the ski pattern # Inform the user log.info("Running the bulge simulation ...") # Run the simulation simulation = self.skirt.run(arguments, silent=False if log.is_debug() else True) # Determine the path to the output FITS file bulge_image_path = fs.join(out_path, "bulge_earth_total.fits") # Check if the output contains the "bulge_earth_total.fits" file if not fs.is_file(bulge_image_path): raise RuntimeError("Something went wrong with the simple bulge simulation: output FITS file missing") # ----------------------------------------------------------------- def simulate_bulge(self): """ This function ... :return: """ # Inform the user log.info("Creating ski file to simulate the bulge image ...") # Load the bulge ski file template bulge_template_path = fs.join(template_path, "bulge.ski") ski = SkiFile(bulge_template_path) # Set the number of photon packages ski.setpackages(self.config.bulge_packages) # Set the bulge geometry ski.set_stellar_component_geometry(0, self.bulge) # Remove all existing instruments ski.remove_all_instruments() # Add the instruments for name in self.instruments: ski.add_instrument(name, self.instruments[name]) # Determine the path to the ski file ski_path = fs.join(self.bulge_path, "bulge.ski") # Save the ski file to the new path ski.saveto(ski_path) # Determine the path to the simulation output directory out_path = fs.join(self.bulge_path, "out") # Create the output directory fs.create_directory(out_path) # Create a SkirtArguments object arguments = SkirtArguments() # Adjust the parameters arguments.ski_pattern = ski_path arguments.output_path = out_path arguments.single = True # we expect a single simulation from the ski pattern # Inform the user log.info("Running the bulge simulation ...") # Run the simulation simulation = self.skirt.run(arguments, silent=False if log.is_debug() else True) # Determine the path to the output FITS file bulge_image_path = fs.join(out_path, "bulge_earth_total.fits") # Check if the output contains the "bulge_earth_total.fits" file if not fs.is_file(bulge_image_path): raise RuntimeError("Something went wrong with the bulge simulation: output FITS file missing") # Open the bulge image self.bulge_image = Frame.from_file(bulge_image_path) # Set the coordinate system of the bulge image self.bulge_image.wcs = self.reference_wcs # Debugging log.debug("Rescaling the bulge image to the bulge flux density at 3.6 micron ...") # Rescale to the 3.6um flux density fluxdensity = self.parameters.bulge.fluxdensity self.bulge_image *= fluxdensity.to("Jy").value / np.sum(self.bulge_image) self.bulge_image.unit = "Jy" # Debugging log.debug("Convolving the bulge image to the PACS 160 resolution ...") # Convolve the frame to the PACS 160 resolution self.bulge_image = self.bulge_image.convolved(self.psf) # ----------------------------------------------------------------- def simulate_disk(self): """ This function ... :return: """ # Inform the user log.info("Creating ski file to simulate the disk image ...") # Load the disk ski file template disk_template_path = fs.join(template_path, "disk.ski") ski = SkiFile(disk_template_path) # Set the number of photon packages ski.setpackages(self.config.disk_packages) # Change the ski file parameters ski.set_stellar_component_geometry(0, self.disk) # Remove all existing instruments ski.remove_all_instruments() # Add the instruments for name in self.instruments: ski.add_instrument(name, self.instruments[name]) # Determine the path to the ski file ski_path = fs.join(self.disk_path, "disk.ski") # Save the ski file to the new path ski.saveto(ski_path) # Determine the path to the simulation output directory out_path = fs.join(self.disk_path, "out") # Create the output directory fs.create_directory(out_path) # Create a SkirtArguments object arguments = SkirtArguments() # Adjust the parameters arguments.ski_pattern = ski_path arguments.output_path = out_path arguments.single = True # we expect a single simulation from the ski pattern # Inform the user log.info("Running the disk simulation ...") # Run the simulation simulation = self.skirt.run(arguments, silent=False if log.is_debug() else True) # Determine the path to the output FITS file disk_image_path = fs.join(out_path, "disk_earth_total.fits") # Check if the output contains the "disk_earth_total.fits" file if not fs.is_file(disk_image_path): raise RuntimeError("Something went wrong with the disk simulation: output FITS file missing") # Open the disk image self.disk_image = Frame.from_file(disk_image_path) # Set the coordinate system of the disk image self.disk_image.wcs = self.reference_wcs # Debugging log.debug("Rescaling the disk image to the disk flux density at 3.6 micron ...") # Rescale to the 3.6um flux density fluxdensity = self.parameters.disk.fluxdensity self.disk_image *= fluxdensity.to("Jy").value / np.sum(self.disk_image) self.disk_image.unit = "Jy" # Debugging log.debug("Convolving the disk image to the PACS 160 resolution ...") # Convolve the frame to the PACS 160 resolution self.disk_image = self.disk_image.convolved(self.psf) # ----------------------------------------------------------------- def simulate_model(self): """ This function ... """ # Inform the user log.info("Creating ski file to simulate the bulge+disk model image ...") # Load the disk ski file template disk_template_path = fs.join(template_path, "model.ski") ski = SkiFile(disk_template_path) # Set the number of photon packages ski.setpackages(self.config.disk_packages) # Change the ski file parameters ski.set_stellar_component_geometry(0, self.disk) ski.set_stellar_component_geometry(1, self.bulge) # Set the luminosities of the two components ski.set_stellar_component_luminosities(0, [self.parameters.disk.f]) ski.set_stellar_component_luminosities(1, [self.parameters.bulge.f]) # Remove all existing instruments ski.remove_all_instruments() # Add the instruments for name in self.instruments: ski.add_instrument(name, self.instruments[name]) # Determine the path to the ski file ski_path = fs.join(self.model_path, "model.ski") # Save the ski file to the new path ski.saveto(ski_path) # Determine the path to the simulation output directory out_path = fs.join(self.model_path, "out") # Create the output directory fs.create_directory(out_path) # Create a SkirtArguments object arguments = SkirtArguments() # Adjust the parameters arguments.ski_pattern = ski_path arguments.output_path = out_path arguments.single = True # we expect a single simulation from the ski pattern # Inform the user log.info("Running the disk+bulge simulation ...") # Run the simulation simulation = self.skirt.run(arguments, silent=False if log.is_debug() else True) # Determine the path to the output FITS file model_image_path = fs.join(out_path, "model_earth_total.fits") # Check if the output contains the "model_earth_total.fits" file if not fs.is_file(model_image_path): raise RuntimeError("Something went wrong with the disk+bulge simulation: output FITS file missing") # Open the model image self.model_image = Frame.from_file(model_image_path) # Set the coordinate system of the model image self.model_image.wcs = self.reference_wcs # Debugging log.debug("Rescaling the model image to the bulge+disk flux density at 3.6 micron ...") # Rescale to the 3.6um flux density fluxdensity = self.parameters.bulge.fluxdensity + self.parameters.disk.fluxdensity # sum of bulge and disk component flux density self.model_image *= fluxdensity.to("Jy").value / np.sum(self.model_image) self.model_image.unit = "Jy" # Debugging log.debug("Convolving the model image to the PACS 160 resolution ...") # Convolve the frame to the PACS 160 resolution self.model_image = self.model_image.convolved(self.psf) # ----------------------------------------------------------------- def write(self): """ This function ... :return: """ # Inform the user log.info("Writing ...") # Write out the final bulge and disk images self.write_images() # Write out the parameters in a data file self.write_parameters() # Write the projection systems self.write_projections() # Write out the disk ellipse self.write_disk_ellipse() # ----------------------------------------------------------------- def write_images(self): """ This function ... :return: """ # Determine the path to the bulge image and save it final_bulge_path = fs.join(self.components_path, "bulge.fits") self.bulge_image.save(final_bulge_path) # Determine the path to the disk image and save it final_disk_path = fs.join(self.components_path, "disk.fits") self.disk_image.save(final_disk_path) # Determine the path to the model image and save it final_model_path = fs.join(self.components_path, "model.fits") self.model_image.save(final_model_path) # ----------------------------------------------------------------- def write_parameters(self): """ This function ... :return: """ # Inform the user log.info("Writing data file with parameters ...") # Determine the full path to the parameters file path = fs.join(self.components_path, "parameters.dat") # Write the parameters to the specified location write_parameters(self.parameters, path) # ----------------------------------------------------------------- def write_projections(self): """ This function ... :return: """ # Inform the user log.info("Writing the projection systems ...") # Loop over the projection systems for name in self.projections: # Determine the path to the projection file path = fs.join(self.components_path, name + ".proj") # Write the projection system self.projections[name].save(path) # ----------------------------------------------------------------- def write_disk_ellipse(self): """ This function ... :return: """ # Inform the user log.info("Writing regions file with disk ellipse ...") minor = (1.0 - self.parameters.ellipticity) * self.parameters.major_arcsec # Ellipse radius radius = Extent(self.parameters.major_arcsec, minor) # Create sky ellipse sky_ellipse = SkyEllipse(self.parameters.center, radius, self.parameters.position_angle) # Create region region = SkyRegion() region.append(sky_ellipse) region_path = fs.join(self.components_path, "disk.reg") region.save(region_path)
def do_snls_spectra(catalog): """ """ task_str = catalog.get_current_task_str() result = Vizier.get_catalogs('J/A+A/507/85/table1') table = result[list(result.keys())[0]] table.convert_bytestring_to_unicode(python3_only=True) datedict = {} for row in table: datedict['SNLS-' + row['SN']] = str(astrotime(row['Date']).mjd) oldname = '' file_names = glob(os.path.join(catalog.get_current_task_repo(), 'SNLS/*')) for fi, fname in enumerate(pbar_strings(file_names, task_str)): filename = os.path.basename(fname) fileparts = filename.split('_') name = 'SNLS-' + fileparts[1] name = catalog.get_preferred_name(name) if oldname and name != oldname: catalog.journal_entries() oldname = name name = catalog.add_entry(name) source = catalog.entries[name].add_source( bibcode='2009A&A...507...85B') catalog.entries[name].add_quantity(SUPERNOVA.ALIAS, name, source) catalog.entries[name].add_quantity( SUPERNOVA.DISCOVER_DATE, '20' + fileparts[1][:2], source) f = open(fname, 'r') data = csv.reader(f, delimiter=' ', skipinitialspace=True) specdata = [] for r, row in enumerate(data): if row[0] == '@TELESCOPE': telescope = row[1].strip() elif row[0] == '@REDSHIFT': catalog.entries[name].add_quantity( SUPERNOVA.REDSHIFT, row[1].strip(), source) if r < 14: continue specdata.append(list(filter(None, [x.strip(' \t') for x in row]))) specdata = [list(i) for i in zip(*specdata)] wavelengths = specdata[1] fluxes = [pretty_num(float(x) * 1.e-16, sig=get_sig_digits(x)) for x in specdata[2]] # FIX: this isnt being used # errors = [pretty_num(float(x)*1.e-16, sig=get_sig_digits(x)) for x in # specdata[3]] catalog.entries[name].add_spectrum( u_wavelengths='Angstrom', u_fluxes='erg/s/cm^2/Angstrom', wavelengths=wavelengths, fluxes=fluxes, u_time='MJD' if name in datedict else '', time=datedict[name] if name in datedict else '', telescope=telescope, source=source, filename=filename) if catalog.args.travis and fi >= catalog.TRAVIS_QUERY_LIMIT: break catalog.journal_entries() return
from astroquery.vizier import Vizier catalog_list = Vizier.find_catalogs('J/ApJS/204/5') Vizier.ROW_LIMIT = -1 cata = Vizier.get_catalogs(catalog_list.keys())[0] print len(cata)