def get_data(name, output_directory): baseurl = 'http://gsaweb.ast.cam.ac.uk/alerts/alert' content = aud.get_file_contents("{}/{}".format(baseurl, name), cache=True) htmldoc = bs4.BeautifulSoup(content, 'html5lib') for line in htmldoc.strings: if 'var spectra' in line: spectra_data = line.split('=')[1].strip() spectra_data = Table(eval(spectra_data[1:-2])) try: spectra_meta = Table.read(content, format='ascii.html') except InconsistentTableError: if "Not found" in content: warnings.warn("data is not found for {}, check whether it's a " "valid GaiaAlerts object".format(name)) return None spectra = hstack([spectra_meta, spectra_data], join_type='outer') spectra['Name'] = name if output_directory is not None: spectra.write(os.path.join(output_directory, '{}.fits'.format(name)), overwrite=True) return spectra
def reload_votable_fields_json(): content = aud.get_file_contents("http://simbad.u-strasbg.fr/simbad/sim-help?Page=sim-fscript#VotableFields") import bs4 htmldoc = bs4.BeautifulSoup(content, 'html5lib') search_text = re.compile(r'Field names for VOTable output', re.IGNORECASE) foundtext = htmldoc.find('h2', text=search_text) # Find the first <table> tag that follows it table = foundtext.findNext('table') outd = {} for row in table.findAll('tr'): cols = row.findChildren('td') if len(cols) > 1: smallest_child = cols[0].find_all()[-1] if cols[0].findChild("ul"): text1 = cols[0].findChild('ul').getText() elif cols[0].find_all(): text1 = smallest_child.getText() else: text1 = cols[0].getText() if cols[1].findChild("ul"): text2 = cols[1].findChild('ul').getText() else: text2 = cols[1].getText() # ignore blank entries & headers if (text2.strip() != '' and not (smallest_child.name == 'font' and 'size' in smallest_child.attrs and smallest_child.attrs['size'] == '+2')): outd[text1.strip()] = text2.strip() with open('data/votable_fields_dict.json', 'w') as f: json.dump(outd, f, indent=2, sort_keys=True)
def get_data(name, output_directory): baseurl = 'http://gsaweb.ast.cam.ac.uk/alerts/alert' content = aud.get_file_contents("{}/{}".format(baseurl, name), cache=True) htmldoc = bs4.BeautifulSoup(content, 'html5lib') search_text = re.compile('var spectra') line = htmldoc.find('script', text=search_text) try: spectra_data = line.string.split('=')[1].strip() except AttributeError: warnings.warn("data is not found for {}, check whether it's a " "valid GaiaAlerts object".format(name)) return None spectra_data = Table(ast.literal_eval(spectra_data[1:-2])) spectra_meta = Table.read(content, format='ascii.html') spectra = hstack([spectra_meta, spectra_data], join_type='outer') spectra['Name'] = name if output_directory is not None: spectra.write(os.path.join(output_directory, '{}.fits'.format(name)), overwrite=True) return spectra
def reload_votable_fields_json(): content = aud.get_file_contents("http://simbad.u-strasbg.fr/simbad/sim-help?Page=sim-fscript#VotableFields") import bs4 htmldoc = bs4.BeautifulSoup(content) search_text = re.compile(r"Field names for VOTable output", re.IGNORECASE) foundtext = htmldoc.find("h2", text=search_text) table = foundtext.findNext("table") # Find the first <table> tag that follows it outd = {} for row in table.findAll("tr"): cols = row.findChildren("td") if len(cols) > 1: smallest_child = cols[0].find_all()[-1] if cols[0].findChild("ul"): text1 = cols[0].findChild("ul").getText() elif cols[0].find_all(): text1 = smallest_child.getText() else: text1 = cols[0].getText() if cols[1].findChild("ul"): text2 = cols[1].findChild("ul").getText() else: text2 = cols[1].getText() # ignore blank entries & headers if text2.strip() != "" and not ( smallest_child.name == "font" and "size" in smallest_child.attrs and smallest_child.attrs["size"] == "+2" ): outd[text1.strip()] = text2.strip() with open("data/votable_fields_dict.json", "w") as f: json.dump(outd, f, indent=2, sort_keys=True)
def observing_sites(): """Returns a dict of observatory sites based on astropy's database.""" jsonurl = 'http://data.astropy.org/coordinates/sites.json' js = json.loads(get_file_contents(jsonurl, show_progress=False, cache=True)) sitedict = {} for sitekey, site in js.items(): sitedict[sitekey] = site['name'] return sitedict
def get_downloaded_sites(jsonurl=None): """ Load observatory database from data.astropy.org and parse into a SiteRegistry """ # we explicitly set the encoding because the default is to leave it set by # the users' locale, which may fail if it's not matched to the sites.json if jsonurl is None: content = get_pkg_data_contents('coordinates/sites.json', encoding='UTF-8') else: content = get_file_contents(jsonurl, encoding='UTF-8') jsondb = json.loads(content) return SiteRegistry.from_json(jsondb)
def main(project=None, unit=None, folders_file=None, parallel=False, remote=False, remove_after=False, verbose=False, **kwargs): pan = Panoptes(simulator=['all']) folders = get_file_contents(folders_file).strip().split('\n') # See if the remote path exists in the HDF5 data store store = pd.HDFStore(kwargs.get('hdf5_file')) with console.ProgressBarOrSpinner(len(folders), "Folders") as bar: for idx, folder in enumerate(folders): folder = folder.rstrip('/') hdf_path = '/observing/{}'.format(folder) if hdf_path not in store.keys(): local_dir = '/var/panoptes/images/fields/{}/'.format(folder) if not os.path.exists(local_dir) and remote: # Get the data remote_path = 'gs://{}/{}/{}'.format(project, unit, folder) get_remote_dir(remote_path, local_dir=local_dir, extension='cr2') # Make data make_pec_data(folder, observer=pan.observatory.scheduler, parallel=parallel, verbose=verbose) if remove_after: # Remove the data try: shutil.rmtree(local_dir) except Exception as e: if verbose: print("Error removing dir: {}".format(e)) else: if verbose: print("{} already in HDF5 table".format(folder)) bar.update(idx)
def get_data(name, output): baseurl = 'http://gsaweb.ast.cam.ac.uk/alerts/alert' content = aud.get_file_contents("{}/{}".format(baseurl, name), cache=True) htmldoc = bs4.BeautifulSoup(content, 'html5lib') for line in htmldoc.strings: if 'var spectra' in line: spectra_data = line.split('=')[1].strip() spectra_data = Table(eval(spectra_data[1:-2])) spectra_meta = Table.read(content, format='ascii.html') spectra = hstack([spectra_meta, spectra_data], join_type='outer') if output is not None: spectra.write(os.path.join(output, '{}.fits'.format(name)), overwrite=True) return spectra
def reload_votable_fields_json(): content = aud.get_file_contents( "http://simbad.u-strasbg.fr/simbad/sim-help?Page=sim-fscript#VotableFields" ) import bs4 htmldoc = bs4.BeautifulSoup(content, 'html5lib') search_text = re.compile(r'Field names for VOTable output', re.IGNORECASE) foundtext = htmldoc.find('h2', text=search_text) # Find the first <table> tag that follows it table = foundtext.findNext('table') outd = {} for row in table.findAll('tr'): cols = row.findChildren('td') if len(cols) > 1: smallest_child = cols[0].find_all()[-1] if cols[0].findChild("ul"): text1 = cols[0].findChild('ul').getText() elif cols[0].find_all(): text1 = smallest_child.getText() else: text1 = cols[0].getText() if cols[1].findChild("ul"): text2 = cols[1].findChild('ul').getText() else: text2 = cols[1].getText() # ignore blank entries & headers if (text2.strip() != '' and not (smallest_child.name == 'font' and 'size' in smallest_child.attrs and smallest_child.attrs['size'] == '+2')): outd[text1.strip()] = text2.strip() with open('data/votable_fields_dict.json', 'w') as f: json.dump(outd, f, indent=2, sort_keys=True)
def get_icrs_coordinates(name, parse=False, cache=False): """ Retrieve an ICRS object by using an online name resolving service to retrieve coordinates for the specified name. By default, this will search all available databases until a match is found. If you would like to specify the database, use the science state ``astropy.coordinates.name_resolve.sesame_database``. You can also specify a list of servers to use for querying Sesame using the science state ``astropy.coordinates.name_resolve.sesame_url``. This will try each one in order until a valid response is returned. By default, this list includes the main Sesame host and a mirror at vizier. The configuration item `astropy.utils.data.Conf.remote_timeout` controls the number of seconds to wait for a response from the server before giving up. Parameters ---------- name : str The name of the object to get coordinates for, e.g. ``'M42'``. parse : bool Whether to attempt extracting the coordinates from the name by parsing with a regex. For objects catalog names that have J-coordinates embedded in their names eg: 'CRTS SSS100805 J194428-420209', this may be much faster than a sesame query for the same object name. The coordinates extracted in this way may differ from the database coordinates by a few deci-arcseconds, so only use this option if you do not need sub-arcsecond accuracy for coordinates. cache : bool, str, optional Determines whether to cache the results or not. Passed through to `~astropy.utils.data.download_file`, so pass "update" to update the cached value. Returns ------- coord : `astropy.coordinates.ICRS` object The object's coordinates in the ICRS frame. """ # if requested, first try extract coordinates embedded in the object name. # Do this first since it may be much faster than doing the sesame query if parse: from . import jparser if jparser.search(name): return jparser.to_skycoord(name) else: # if the parser failed, fall back to sesame query. pass # maybe emit a warning instead of silently falling back to sesame? database = sesame_database.get() # The web API just takes the first letter of the database name db = database.upper()[0] # Make sure we don't have duplicates in the url list urls = [] domains = [] for url in sesame_url.get(): domain = urllib.parse.urlparse(url).netloc # Check for duplicates if domain not in domains: domains.append(domain) # Add the query to the end of the url, add to url list fmt_url = os.path.join(url, "{db}?{name}") fmt_url = fmt_url.format(name=urllib.parse.quote(name), db=db) urls.append(fmt_url) exceptions = [] for url in urls: try: resp_data = get_file_contents( download_file(url, cache=cache, show_progress=False)) break except urllib.error.URLError as e: exceptions.append(e) continue except socket.timeout as e: # There are some cases where urllib2 does not catch socket.timeout # especially while receiving response data on an already previously # working request e.reason = ("Request took longer than the allowed " f"{data.conf.remote_timeout:.1f} seconds") exceptions.append(e) continue # All Sesame URL's failed... else: messages = [f"{url}: {e.reason}" for url, e in zip(urls, exceptions)] raise NameResolveError("All Sesame queries failed. Unable to " "retrieve coordinates. See errors per URL " f"below: \n {os.linesep.join(messages)}") ra, dec = _parse_response(resp_data) if ra is None or dec is None: if db == "A": err = f"Unable to find coordinates for name '{name}' using {url}" else: err = f"Unable to find coordinates for name '{name}' in database {database} using {url}" raise NameResolveError(err) # Return SkyCoord object sc = SkyCoord(ra=ra, dec=dec, unit=(u.degree, u.degree), frame='icrs') return sc
def load_mccon12_table(mcconn_url='https://www.astrosci.ca/users/alan/Nearby_Dwarfs_Database_files/NearbyGalaxies.dat', qtable=True): from astropy.utils import data from astropy.io import ascii # have to do SSL stuff because astrosci.ca has expired SSL import ssl from urllib.error import URLError baseline_create = ssl._create_default_https_context try: mcconn_tab_str = data.get_file_contents(mcconn_url, cache=True) except URLError as e: ee[0] = e if 'SSL: CERTIFICATE_VERIFY_FAILED' in str(e.args): ssl._create_default_https_context = ssl._create_unverified_context exec(toexec) else: raise finally: ssl._create_default_https_context = baseline_create headerrow = mcconn_tab_str.split('\n')[32] colnames = headerrow.split() colidxs = [headerrow.rindex(col) for col in colnames] # this *removes* the references col_starts = colidxs[:-1] col_ends = [i-1 for i in colidxs[1:]] colnames = colnames[:-1] str_tab = ascii.read(mcconn_tab_str.split('\n')[34:], format='fixed_width_no_header', names=colnames, col_starts=col_starts, col_ends=col_ends) mcconn_tab = (QTable if qtable else Table)() mcconn_tab['Name'] = [s.strip() for s in str_tab['GalaxyName']] scs = [] for row in str_tab: dm = float(row['(m-M)o'].split()[0]) scs.append(SkyCoord(row['RA'], row['Dec'], unit=(u.hour, u.deg), distance=Distance(distmod=dm))) mcconn_tab['Coords'] = SkyCoord(scs) for col in str_tab.colnames[3:]: if col in ('EB-V', 'F', 'MHI'): #single number mcconn_tab[col] = [float(s) for s in str_tab[col]] else: # num + - vals, ps, ms = [], [], [] for s in str_tab[col]: val, p, m = s.split() vals.append(float(val)) ps.append(float(p)) ms.append(float(m)) mcconn_tab[col] = vals mcconn_tab[col + '+'] = ps mcconn_tab[col + '-'] = ms return mcconn_tab
def load_mccon12_table( mcconn_url='https://www.astrosci.ca/users/alan/Nearby_Dwarfs_Database_files/NearbyGalaxies.dat', qtable=True): from astropy.utils import data from astropy.io import ascii # have to do SSL stuff because astrosci.ca has expired SSL import ssl from urllib.error import URLError baseline_create = ssl._create_default_https_context try: mcconn_tab_str = data.get_file_contents(mcconn_url, cache=True) except URLError as e: ee[0] = e if 'SSL: CERTIFICATE_VERIFY_FAILED' in str(e.args): ssl._create_default_https_context = ssl._create_unverified_context exec(toexec) else: raise finally: ssl._create_default_https_context = baseline_create headerrow = mcconn_tab_str.split('\n')[32] colnames = headerrow.split() colidxs = [headerrow.rindex(col) for col in colnames] # this *removes* the references col_starts = colidxs[:-1] col_ends = [i - 1 for i in colidxs[1:]] colnames = colnames[:-1] str_tab = ascii.read(mcconn_tab_str.split('\n')[34:], format='fixed_width_no_header', names=colnames, col_starts=col_starts, col_ends=col_ends) mcconn_tab = (QTable if qtable else Table)() mcconn_tab['Name'] = [s.strip() for s in str_tab['GalaxyName']] scs = [] for row in str_tab: dm = float(row['(m-M)o'].split()[0]) scs.append( SkyCoord(row['RA'], row['Dec'], unit=(u.hour, u.deg), distance=Distance(distmod=dm))) mcconn_tab['Coords'] = SkyCoord(scs) for col in str_tab.colnames[3:]: if col in ('EB-V', 'F', 'MHI'): #single number mcconn_tab[col] = [float(s) for s in str_tab[col]] else: # num + - vals, ps, ms = [], [], [] for s in str_tab[col]: val, p, m = s.split() vals.append(float(val)) ps.append(float(p)) ms.append(float(m)) mcconn_tab[col] = vals mcconn_tab[col + '+'] = ps mcconn_tab[col + '-'] = ms return mcconn_tab
def get_mcconn_table(fnorurl='http://www.astro.uvic.ca/~alan/Nearby_Dwarfs_Database_files/NearbyGalaxies.dat', dropmw=True, sanitizenames=False): """ Gets the Mcconnachie 12 table from the file. Parameters ---------- fnorurl : str, optional Local file or URL. If URL, will be cached. dropmw : bool, optional If true, the entry for the MW will be skipped. sanitizenames : bool, optional If True, names like "gal (I)" will be changed to "gal I" Returns ------- mctab : astropy.table.Table The Mcconnachie 12 "database" as an astropy table """ import os from astropy.coordinates import Angle, ICRS, SkyCoord from astropy.table import Table, Column from astropy.utils import data from astropy import units as u if fnorurl is None: if os.path.isfile('NearbyGalaxies.dat'): fnorurl = 'NearbyGalaxies.dat' else: fnorurl = 'https://www.astrosci.ca/users/alan/Nearby_Dwarfs_Database_files/NearbyGalaxies.dat' datstr = data.get_file_contents(fnorurl, cache=True) datlines = datstr.split('\n') # pull from the header. for hdri, hdrstr in enumerate(datlines): if hdrstr.startswith('GalaxyName'): break else: raise ValueError('No field name line found') # hdrstr now is the line with the field names # type is 'pm' for float w/ err+/- or 'coord' fieldinfo = [('name', 'S19', None), ('center', 'coord', None), ('EBmV', float, u.mag), ('distmod', 'pm', u.mag), ('vh', 'pm', u.km / u.s), ('Vmag', 'pm', u.mag), ('PA', 'pm', u.degree), ('e', 'pm', u.dimensionless_unscaled), ('muV0', 'pm', u.mag * u.arcsec ** -2), ('rh', 'pm', u.arcmin), ('sigma_s', 'pm', u.km / u.s), ('vrot_s', 'pm', u.km / u.s), ('MHI', float, u.Unit('1e6 solMass')), ('sigma_g', 'pm', u.km / u.s), ('vrot_g', 'pm', u.km / u.s), ('[Fe/H]', 'pm', u.dimensionless_unscaled), ('F', int, None), ('References', 'S40', None)] fieldnames = [] fielddtypes = [] fieldunits = [] for nm, tp, un in fieldinfo: if tp == 'coord': fieldnames.append(nm) fielddtypes.append(object) fieldunits.append(None) elif tp == 'pm': fieldnames.append(nm) fielddtypes.append(float) fieldunits.append(un) fieldnames.append(nm + '+') fielddtypes.append(float) fieldunits.append(un) fieldnames.append(nm + '-') fielddtypes.append(float) fieldunits.append(un) else: fieldnames.append(nm) fielddtypes.append(tp) fieldunits.append(un) t = Table(names=fieldnames, dtype=fielddtypes) for nm, un in zip(fieldnames, fieldunits): t[nm].units = un for l in datlines[(hdri + 2 + int(dropmw)):]: if l.strip() == '': continue vals = l[19:].split() ra = Angle(tuple([float(v) for v in vals[0:3]]), unit=u.hour) dec = Angle(tuple([float(v) for v in vals[3:6]]), unit=u.degree) vals = vals[6:] vals.insert(0, ICRS(ra, dec)) vals.insert(0, l[:19].strip()) if '(' not in vals[-1]: vals.append('') t.add_row(vals) # now add derived columns t.add_column(Column(name='Vabs', data=t['Vmag'] - t['distmod'], unit=u.mag)) # Vmag apparently already includes dereddening? t.add_column(Column(name='logLV', data=(t['Vabs'] - 4.83) / -2.5, unit=u.solLum)) t.add_column(Column(name='distance', data=10 ** (t['distmod'] / 5. - 2), unit=u.kpc)) t.add_column(Column(name='distance+', data=t['distmod+'] * t['distance'] * np.log(10) / 5, unit=u.kpc)) t.add_column(Column(name='distance-', data=t['distmod-'] * t['distance'] * np.log(10) / 5, unit=u.kpc)) t.add_column(Column(name='rh_phys', data=t['distance'] * np.radians(t['rh'] / 60.), unit=u.kpc)) t.add_column(Column(name='radeg', data=[((ti.ra.degree + 180) % 360 - 180) for ti in t['center']], unit=u.degree)) t.add_column(Column(name='decdeg', data=[ti.dec.degree for ti in t['center']], unit=u.degree)) # Now replace the 'center' with a version that includes the distance. newscs = [] xs = [] ys = [] zs = [] for ic in t['center']: newscs.append(SkyCoord(ic.ra, ic.dec, distance=t['distance'])) xs.append(newscs[-1].cartesian.x) ys.append(newscs[-1].cartesian.y) zs.append(newscs[-1].cartesian.z) t.add_column(Column(name='x', data=xs, unit=u.kpc)) t.add_column(Column(name='y', data=ys, unit=u.kpc)) t.add_column(Column(name='z', data=zs, unit=u.kpc)) # andromeda dSph numbers andnum = [] for nm in t['name']: if nm.startswith('Andromeda '): andnum.append(roman_to_int(nm.replace('Andromeda ', ''))) elif nm == 'Andromeda': andnum.append(0) elif nm in ('M32', 'NGC 205', 'NGC 185', 'NGC 147'): andnum.append(-1) elif nm in ('IC 10', 'LGS 3'): andnum.append(-2) elif nm in ('IC 1613', 'Pegasus dIrr'): andnum.append(-3) else: andnum.append(-99) t.add_column(Column(name='and_number', data=andnum, unit=None)) if sanitizenames: t['name'] = [nm.replace('(I)', 'I') for nm in t['name']] return t
def get_mcconn_table( fnorurl='http://www.astro.uvic.ca/~alan/Nearby_Dwarfs_Database_files/NearbyGalaxies.dat', dropmw=True, sanitizenames=False): """ Gets the Mcconnachie 12 table from the file. Parameters ---------- fnorurl : str, optional Local file or URL. If URL, will be cached. dropmw : bool, optional If true, the entry for the MW will be skipped. sanitizenames : bool, optional If True, names like "gal (I)" will be changed to "gal I" Returns ------- mctab : astropy.table.Table The Mcconnachie 12 "database" as an astropy table """ import os from astropy.coordinates import Angle, ICRS, SkyCoord from astropy.table import Table, Column from astropy.utils import data from astropy import units as u if fnorurl is None: if os.path.isfile('NearbyGalaxies.dat'): fnorurl = 'NearbyGalaxies.dat' else: fnorurl = 'https://www.astrosci.ca/users/alan/Nearby_Dwarfs_Database_files/NearbyGalaxies.dat' datstr = data.get_file_contents(fnorurl, cache=True) datlines = datstr.split('\n') # pull from the header. for hdri, hdrstr in enumerate(datlines): if hdrstr.startswith('GalaxyName'): break else: raise ValueError('No field name line found') # hdrstr now is the line with the field names # type is 'pm' for float w/ err+/- or 'coord' fieldinfo = [('name', 'S19', None), ('center', 'coord', None), ('EBmV', float, u.mag), ('distmod', 'pm', u.mag), ('vh', 'pm', u.km / u.s), ('Vmag', 'pm', u.mag), ('PA', 'pm', u.degree), ('e', 'pm', u.dimensionless_unscaled), ('muV0', 'pm', u.mag * u.arcsec**-2), ('rh', 'pm', u.arcmin), ('sigma_s', 'pm', u.km / u.s), ('vrot_s', 'pm', u.km / u.s), ('MHI', float, u.Unit('1e6 solMass')), ('sigma_g', 'pm', u.km / u.s), ('vrot_g', 'pm', u.km / u.s), ('[Fe/H]', 'pm', u.dimensionless_unscaled), ('F', int, None), ('References', 'S40', None)] fieldnames = [] fielddtypes = [] fieldunits = [] for nm, tp, un in fieldinfo: if tp == 'coord': fieldnames.append(nm) fielddtypes.append(object) fieldunits.append(None) elif tp == 'pm': fieldnames.append(nm) fielddtypes.append(float) fieldunits.append(un) fieldnames.append(nm + '+') fielddtypes.append(float) fieldunits.append(un) fieldnames.append(nm + '-') fielddtypes.append(float) fieldunits.append(un) else: fieldnames.append(nm) fielddtypes.append(tp) fieldunits.append(un) t = Table(names=fieldnames, dtype=fielddtypes) for nm, un in zip(fieldnames, fieldunits): t[nm].units = un for l in datlines[(hdri + 2 + int(dropmw)):]: if l.strip() == '': continue vals = l[19:].split() ra = Angle(tuple([float(v) for v in vals[0:3]]), unit=u.hour) dec = Angle(tuple([float(v) for v in vals[3:6]]), unit=u.degree) vals = vals[6:] vals.insert(0, ICRS(ra, dec)) vals.insert(0, l[:19].strip()) if '(' not in vals[-1]: vals.append('') t.add_row(vals) # now add derived columns t.add_column( Column(name='Vabs', data=t['Vmag'] - t['distmod'], unit=u.mag)) # Vmag apparently already includes dereddening? t.add_column( Column(name='logLV', data=(t['Vabs'] - 4.83) / -2.5, unit=u.solLum)) t.add_column( Column(name='distance', data=10**(t['distmod'] / 5. - 2), unit=u.kpc)) t.add_column( Column(name='distance+', data=t['distmod+'] * t['distance'] * np.log(10) / 5, unit=u.kpc)) t.add_column( Column(name='distance-', data=t['distmod-'] * t['distance'] * np.log(10) / 5, unit=u.kpc)) t.add_column( Column(name='rh_phys', data=t['distance'] * np.radians(t['rh'] / 60.), unit=u.kpc)) t.add_column( Column(name='radeg', data=[((ti.ra.degree + 180) % 360 - 180) for ti in t['center']], unit=u.degree)) t.add_column( Column(name='decdeg', data=[ti.dec.degree for ti in t['center']], unit=u.degree)) # Now replace the 'center' with a version that includes the distance. newscs = [] xs = [] ys = [] zs = [] for ic in t['center']: newscs.append(SkyCoord(ic.ra, ic.dec, distance=t['distance'])) xs.append(newscs[-1].cartesian.x) ys.append(newscs[-1].cartesian.y) zs.append(newscs[-1].cartesian.z) t.add_column(Column(name='x', data=xs, unit=u.kpc)) t.add_column(Column(name='y', data=ys, unit=u.kpc)) t.add_column(Column(name='z', data=zs, unit=u.kpc)) # andromeda dSph numbers andnum = [] for nm in t['name']: if nm.startswith('Andromeda '): andnum.append(roman_to_int(nm.replace('Andromeda ', ''))) elif nm == 'Andromeda': andnum.append(0) elif nm in ('M32', 'NGC 205', 'NGC 185', 'NGC 147'): andnum.append(-1) elif nm in ('IC 10', 'LGS 3'): andnum.append(-2) elif nm in ('IC 1613', 'Pegasus dIrr'): andnum.append(-3) else: andnum.append(-99) t.add_column(Column(name='and_number', data=andnum, unit=None)) if sanitizenames: t['name'] = [nm.replace('(I)', 'I') for nm in t['name']] return t