def read_simbad_data(star_name):
    '''
    Query SIMBAD for a given star parallax, vsini, bump and references.

    :param star_name: star's name (string)
    :return: txt file with star's parallax, vsini, bump, the respective
    errors and references for vsini and E(B-V)
    '''

    customSimbad = Simbad()
    # customSimbad.list_votable_fields() #  to list all avaiable fields
    customSimbad.get_votable_fields()
    customSimbad.add_votable_fields('plx', 'plx_error', 'rot', 'sptype')
    customSimbad.get_votable_fields()
    result_table = customSimbad.query_object(star_name)
    # star = result_table['MAIN_ID']
    star = np.copy(star_name)
    plx = result_table['PLX_VALUE'][0]
    plx_error = result_table['PLX_ERROR'][0]
    vsini = result_table['ROT_Vsini'][0]
    vsini_err = result_table['ROT_err'].item()
    rot_bibcode = result_table['ROT_bibcode']
    sptype = result_table['SP_TYPE']
    sptype_ref = sptype.item()
    bump = True
    ebmv_ref = 0.0

    return star.item(), plx, plx_error, vsini, vsini_err, bump,\
        rot_bibcode.item(), ebmv_ref, sptype_ref
def query_simbad(ra, dec, radius=1. / 60):
    fcache = "simbad_cache/{:.6f}_{:.6f}_{:.6f}.pickle".format(ra, dec, radius)
    customSimbad = Simbad()

    customSimbad.get_votable_fields()

    if os.path.exists(fcache):
        print("Found SIMBAD cache file {} ...".format(fcache))
        return pickle.load(open(fcache, "rb"))
    # else

    # To set other fields

    customSimbad.add_votable_fields('mk', 'rot', 'bibcodelist(1800-2014)',
                                    'z_value', 'pmra')
    customSimbad.get_votable_fields()
    customSimbad.add_votable_fields('ra(2;A;ICRS;J2017.5;2000)',
                                    'dec(2;D;ICRS;2017.5;2000)')
    customSimbad.remove_votable_fields('coordinates')
    #customSimbad.query_object("HD189733")

    #result_table = customSimbad.query_region("150.143175 2.114586")

    #result_table = customSimbad.query_region(coord.SkyCoord("150.143175 2.114586", frame='fk5'), radius='0d0m10s')

    result = customSimbad.query_region(coord.SkyCoord(ra=ra,
                                                      dec=dec,
                                                      unit=(u.deg, u.deg),
                                                      frame='fk5'),
                                       radius=radius * u.deg,
                                       epoch='J2000',
                                       equinox=2000)

    cc = [
        SkyCoord(r, a, unit=(u.hourangle, u.deg))
        for r, a in zip(result["RA_2_A_ICRS_J2017_5_2000"],
                        result["DEC_2_D_ICRS_2017_5_2000"])
    ]

    aa = [c.ra.deg for c in cc]
    dd = [c.dec.deg for c in cc]

    result = [[
        id, a, d, z
    ] for id, a, d, z in zip(result["MAIN_ID"], aa, dd, result["Z_VALUE"])]

    pickle.dump(result, open(fcache, "wb"))

    return result
Beispiel #3
0
def read_simbad_coodr(star_name):
    '''
    Query SIMBAD for the coordinates of a given star.

    :param star_name: star's name (string)
    :return: right ascencion and declination coordinates
    '''

    customSimbad = Simbad()
    customSimbad.get_votable_fields()
    result_table = customSimbad.query_object(star_name)

    ra = result_table['RA'][0]
    dec = result_table['DEC'][0]

    return ra, dec
Beispiel #4
0
def sptype_from_simbad(star_name):
    '''
    query sptype from SIMBAD
    '''

    customSimbad = Simbad()
    customSimbad.get_votable_fields()
    customSimbad.add_votable_fields('plx', 'plx_error', 'rot', 'sptype',
                                    'measurements')

    # print(customSimbad.get_votable_fields())
    result_table = customSimbad.query_object(star_name)

    sptype = result_table['SP_TYPE']
    sptype = sptype.item()

    return sptype
def main():

    # VIZIER whole catalog
    Vizier.ROW_LIMIT = -1
    cat = ['V/50', 'V/36B']
    catalogs = Vizier.get_catalogs(cat)
    catalog = catalogs[0]
    catalog_compl = catalogs[2]

    # Operating with the data
    data = catalog.as_array()
    data_compl = catalog_compl.as_array()

    # Print available data
    data.dtype
    data_compl.dtype

    # Filtering the SpType
    sptype = list(data['SpType'].data)
    sptype_compl = list(data_compl['SpType'].data)
    # indexes = np.where(conc_flux[0] > 0)

    indexes = []
    for i in range(len(sptype)):
        sptyp = sptype[i].decode('UTF-8')
        if len(sptyp) != 0:
            if sptyp[0] == 'O':
                if ('V' in sptyp) is True:
                    if ('I' in sptyp) is False:
                        if ('Hg' in sptyp) is False:
                            if ('Mn' in sptyp) is False:
                                indexes.append(i)

    indexes_compl = []
    for i in range(len(sptype_compl)):
        sptyp_compl = sptype_compl[i].decode('UTF-8')
        if len(sptyp_compl) != 0:
            if sptyp_compl[0] == 'O':
                if ('V' in sptyp_compl) is True:
                    if ('I' in sptyp_compl) is False:
                        if ('Hg' in sptyp_compl) is False:
                            if ('Mn' in sptyp_compl) is False:
                                indexes_compl.append(i)

# ==============================================================================
# Selecting the data with the B stars
    selected_data = data[indexes]
    sptyp_selected = list(selected_data['SpType'])
    name_selected = selected_data['Name']
    hd_selected = selected_data['HD']
    plx = selected_data['Parallax']
    bmv = selected_data['B-V']
    err_bmv = selected_data['u_B-V']
    umb = selected_data['U-B']
    err_umb = selected_data['u_U-B']
    rmi = selected_data['R-I']
    vsini = selected_data['RotVel']
    err_vsini = selected_data['u_RotVel']
    companions = selected_data['MultCnt']

    selected_data_compl = data_compl[indexes_compl]
    sptyp_selected_compl = list(selected_data_compl['SpType'])
    hd_selected_compl = selected_data_compl['HD']
    plx_compl = selected_data_compl['Plx']
    bmv_compl = selected_data_compl['B-V']
    umb_compl = selected_data_compl['U-B']
    rmi_compl = selected_data_compl['R-I']
    vsini_compl = selected_data_compl['vsini']
    err_vsini_compl = selected_data_compl['u_vsini']

    # ==============================================================================
    # Checking if there are IUE data
    customSimbad = Simbad()
    customSimbad.TIMEOUT = 2000  # sets the timeout to 2000s

    # see which fields are currently set
    customSimbad.get_votable_fields()

    # To set other fields
    customSimbad.add_votable_fields('measurements')

    # ==============================================================================
    # Selecting the stars with IUE data
    data = data[indexes]
    obs_iue_date = []
    stars = []
    indexes = []
    print('selected stars: %d' % len(hd_selected))
    for i in range(len(hd_selected)):
        try:
            star = "HD " + str(hd_selected[i])
            result_table = customSimbad.query_object(star)
            obs_date = result_table['IUE_ObsDate']
            if len(obs_date.item()) != 0:
                print(num_spa * '-')
                print('\n' + star)
                print('%0.2f perc. concluded' % (100 * i / len(hd_selected)))
                print(obs_date)
                obs_iue_date.append(obs_date.item())
                stars.append(star)
                indexes.append(i)
        except:
            pass

    data_compl = data_compl[indexes_compl]
    obs_iue_date_compl = []
    stars_compl = []
    indexes_compl = []
    print('selected stars compl: %d' % len(hd_selected_compl))
    for i in range(len(hd_selected_compl)):
        try:
            star = "HD " + str(hd_selected_compl[i])
            result_table = customSimbad.query_object(star)
            obs_date = result_table['IUE_ObsDate']
            if len(obs_date.item()) != 0:
                print(num_spa * '-')
                print('\n' + star)
                print('%0.2f perc. concluded' % (100 * i / len(hd_selected)))
                print(obs_date)
                obs_iue_date_compl.append(obs_date.item())
                stars_compl.append(star)
                indexes_compl.append(i)
        except:
            pass

# ==============================================================================
# Selecting the data with the B stars in IUE database

    selected_data = data[indexes]
    sptyp_selected = list(selected_data['SpType'])
    name_selected = selected_data['Name']
    hd_selected = selected_data['HD']
    plx = selected_data['Parallax']
    bmv = selected_data['B-V']
    err_bmv = selected_data['u_B-V']
    umb = selected_data['U-B']
    err_umb = selected_data['u_U-B']
    rmi = selected_data['R-I']
    vsini = selected_data['RotVel']
    err_vsini = selected_data['u_RotVel']
    companions = selected_data['MultCnt']

    selected_data_compl = data_compl[indexes_compl]
    sptyp_selected_compl = list(selected_data_compl['SpType'])
    hd_selected_compl = selected_data_compl['HD']
    plx_compl = selected_data_compl['Plx']
    bmv_compl = selected_data_compl['B-V']
    umb_compl = selected_data_compl['U-B']
    rmi_compl = selected_data_compl['R-I']
    vsini_compl = selected_data_compl['vsini']
    err_vsini_compl = selected_data_compl['u_vsini']

    # ==============================================================================
    # Plotting correlations

    # Plot B-V vs U-B
    plt.clf()
    plt.scatter(bmv, umb, label='V/50', marker='o')
    plt.scatter(bmv_compl, umb_compl, label='V/36B', color='red', marker='o')
    plt.xlabel(r'(B-V) [mag]')
    plt.ylabel(r'(U-B) [mag]')
    plt.legend()
    plt.savefig(folder_fig + 'bmvVSumb.png')

    # ------------------------------------------------------------------------------
    # Plot R-I vs U-B
    plt.clf()
    plt.scatter(rmi, umb, label='V/50', marker='o')
    plt.scatter(rmi_compl, umb_compl, label='V/36B', color='red', marker='o')
    plt.xlabel(r'(R-I) [mag]')
    plt.ylabel(r'(U-B) [mag]')
    plt.legend()
    plt.savefig(folder_fig + 'rmiVSumb.png')

    # ------------------------------------------------------------------------------
    # Plot B-V vs R-I
    plt.clf()
    plt.scatter(bmv, rmi, label='V/50', marker='o')
    plt.scatter(bmv_compl, rmi_compl, label='V/36B', color='red', marker='o')
    plt.xlabel(r'(B-V) [mag]')
    plt.ylabel(r'(R-I) [mag]')
    plt.legend()
    plt.savefig(folder_fig + 'bmvVSrmi.png')

    # ------------------------------------------------------------------------------
    # Plot B-V vs vsini
    plt.clf()
    plt.scatter(bmv, vsini, label='V/50', marker='o')
    plt.scatter(bmv_compl, vsini_compl, label='V/36B', color='red', marker='o')
    plt.xlabel(r'(B-V) [mag]')
    plt.ylabel(r'$v \sin i$ [km/s]')
    plt.legend()
    plt.savefig(folder_fig + 'bmvVSvsini.png')

    # ==============================================================================

    create_txt_file(a=hd_selected,
                    b=bmv,
                    c=umb,
                    d=rmi,
                    e=vsini,
                    f=err_bmv,
                    g=err_umb,
                    h=err_vsini,
                    i=companions.data,
                    j=obs_iue_date,
                    l=sptyp_selected,
                    file_name=commum_folder + 'selected_oe_stars.txt')

    create_txt_file_compl(a=hd_selected_compl,
                          b=bmv_compl,
                          c=umb_compl,
                          d=rmi_compl,
                          e=vsini_compl,
                          f=err_vsini_compl,
                          g=obs_iue_date_compl,
                          h=sptyp_selected_compl,
                          file_name=commum_folder +
                          'selected_oe_stars_compl.txt')

    # ==============================================================================
    # example
    if False:
        R = np.array((data['Vc'] * 1e5)**2 / 10**data['logg'] / phc.Rsun.cgs)
        L = phc.sigma.cgs * np.array(data['Teff'], dtype=float)**4 * 4 *\
            np.pi * (R * phc.Rsun.cgs)**2 * phc.Lsun.cgs
        M = np.array((data['Vc'] * 1e5)**2 * (R * phc.Rsun.cgs) / phc.G.cgs /
                     phc.Msun.cgs)
Beispiel #6
0
    def query_region(self,
                     objectname,
                     match_tol=1.0,
                     obj_radius=1.0,
                     bycoord=False):
        '''
        Fetch remote data from NED and SIMBAD matching coordinates and build table.
        '''
        # Create custom query objects.
        customSimbad = Simbad()
        customNed = Ned()

        # Log SIMBAD votable (changeable) fields.
        logging.debug("SIMBAD votable fields")
        logging.debug(customSimbad.get_votable_fields())

        customSimbad.remove_votable_fields('coordinates')
        # customSimbad.add_votable_fields("otype(3)", "ra(d)", "dec(d)")
        customSimbad.add_votable_fields("otype", "ra(d)", "dec(d)")

        # Download object data from both SIMBAD and NED.
        logging.info(
            "Querying SIMBAD and NED for region {}".format(objectname))

        if bycoord:
            try:
                objectcoords = SkyCoord(objectname)
            except (ValueError, u.UnitsError):
                logging.info("Invalid coordinates.")
                return
        else:
            # Resolve the object name into sky coordinate using NED
            # ensures that NED and SIMBAD searches are using the same position
            sesame_database.set('ned')
            try:
                objectcoords = get_icrs_coordinates(objectname)
            except NameResolveError:
                logging.info("Name resolution failed.")
                return

        logging.info("Name resolved to coordinates {}".format(objectcoords))

        # SIMBAD
        logging.info("SIMBAD is currently being queried...")
        try:
            with warnings.catch_warnings(
            ):  # suppress warnings generated by SIMBAD query
                warnings.simplefilter("ignore")
                simbad_table = customSimbad.query_region(objectcoords,
                                                         radius=obj_radius *
                                                         u.arcmin)
        # workaround. If SIMBAD query finds nothing, returns None but we want a zero-length table
            if type(simbad_table) is not Table:
                logging.debug("No SIMBAD objects")
                simbad_table = Table(data=None,
                                     names=DataController.simbad_table_cols,
                                     dtype=DataController.simbad_table_dtypes,
                                     masked=True)
            logging.info("SUCCESS: SIMBAD Data retrieved.")
        except Timeout:
            logging.debug("SIMBAD timeout error")
            return

    # NED
        logging.info("NED is currently being queried...")
        for attempt in range(
                3):  # sometimes NED times out, so try a couple of times
            Ned.TIMEOUT = (attempt + 1) * DataController.ned_timeout_default
            try:
                ned_table = Ned.query_region(objectcoords,
                                             radius=obj_radius * u.arcmin)
                logging.info("SUCCESS: NED Data retrieved.")
            except RequestException:
                logging.debug("NED problem, retrying")
            else:  # if attempt successful break out of loop, no need to try again
                break
        else:  # closes for loop: executes only if all attempts fail
            logging.debug("NED query failed")
            return

# Save some query stats.
        self.stats.query_name = objectname
        self.stats.sim_count = len(simbad_table)
        self.stats.ned_count = len(ned_table)

        # process tables
        ned_table = self.reformat_table(
            ned_table,
            keepcolsifpresent=[
                'Object Name',
                # cover NED changing names of cols
                'RA(deg)',
                'RA',
                'DEC(deg)',
                'DEC',
                'Type'
            ],
            old_name='Object Name',
            new_name='Name_N',
            old_type='Type',
            new_type='Type_N')

        logging.info("Reformatting tables.")
        simbad_table = self.reformat_table(
            simbad_table,
            keepcolsifpresent=["MAIN_ID", "RA_d", "DEC_d", "OTYPE"],
            old_name='MAIN_ID',
            new_name='Name_S',
            old_type='OTYPE',
            new_type='Type_S')

        logging.info("Building sky coordinates.")
        # Build SkyCoord from appropriate ned and simbad col's with matching units
        ned_coo = SkyCoord(ra=ned_table['RA(deg)'], dec=ned_table['DEC(deg)'])
        sim_coo = SkyCoord(ra=simbad_table['RA_d'], dec=simbad_table['DEC_d'])

        logging.info("Finding object matches.")
        # Find object matches
        if len(ned_coo) > 0 and len(sim_coo) > 0:
            matched_ned, matched_sim, ned_only, sim_only = self.symmetric_match_sky_coords_v2(
                ned_coo, sim_coo, match_tol * u.arcsec)
        else:
            matched_ned = []
            matched_sim = []
            ned_only = []
            sim_only = []
        logging.debug("")
        logging.debug("Matched NED rows:")
        logging.debug(ned_table[matched_ned])
        logging.debug("Matched SIMBAD rows:")
        logging.debug(simbad_table[matched_sim])
        logging.debug("")

        self.stats.overlap_count = len(matched_ned)

        # Explore results
        logging.debug("Matched NED:")
        logging.debug(matched_ned)
        logging.debug("Matched SIMBAD")
        logging.debug(matched_sim)
        logging.debug("NED ONLY")
        logging.debug(ned_only)
        logging.debug("SIMBAD ONLY")
        logging.debug(sim_only)

        # Generate the matched table and save the result.
        logging.info("Building combined table.")
        matched_table = hstack(
            [ned_table[matched_ned], simbad_table[matched_sim]],
            join_type='outer',
            metadata_conflicts='silent')  # Hide the metadata warning.
        self.combined_table = matched_table
Beispiel #7
0
def get_bv(star_id, alerts=True):
    """Obtain B-V colour from Simbad.

    Parameters:
    -----------
    star_id : string
        Target identification readable by Simbad.
    alerts : bool
        If 'True' (default), errors are printed on screen.

    Returns:
    --------
    bv : float
        B-V colour from Simbad.
    bv_err : float
        Error on 'bv'.
    bv_ref : string
        Reference of flux V magnitude (generally the same as B mag).
    err_msg : string
        Error message. If 'OK', there was no error.
    """
    customSimbad = Simbad()
    customSimbad.add_votable_fields('flux(V)')
    customSimbad.add_votable_fields('flux_error(V)')
    customSimbad.add_votable_fields('flux_bibcode(V)')
    customSimbad.add_votable_fields('flux(B)')
    customSimbad.add_votable_fields('flux_error(B)')
    customSimbad.get_votable_fields()

    err_msg = 'OK'

    try:
        query = customSimbad.query_object(star_id)
    except:
        err_msg = f"*** ERROR: Could not identify {star_id}."
        if alerts:
            print(err_msg)
        return np.nan, np.nan, np.nan, err_msg

    if query is None:
        err_msg = f"*** ERROR: Could not identify {star_id}."
        return np.nan, np.nan, np.nan, err_msg

    flux_v = query['FLUX_V'][0]
    flux_v_err = query['FLUX_ERROR_V'][0]
    flux_v_ref = query['FLUX_BIBCODE_V'][0].decode("UTF-8")
    flux_b = query['FLUX_B'][0]
    flux_b_err = query['FLUX_ERROR_B'][0]
    const = np.ma.core.MaskedConstant

    if isinstance(flux_b, const) or isinstance(flux_v, const):
        err_msg = f"*** ERROR: {star_id}: No values of B and/or V in Simbad to calculate B-V."
        if alerts:
            print(err_msg)
        return np.nan, np.nan, np.nan, err_msg
    else:
        bv = flux_b - flux_v

    if isinstance(flux_v_err, const): flux_v_err = np.nan
    if isinstance(flux_b_err, const): flux_b_err = np.nan
    if isinstance(flux_v_ref, const): flux_v_ref = np.nan

    bv_err = np.sqrt(flux_b_err**2 + flux_v_err**2)
    bv_ref = flux_v_ref

    return bv, bv_err, bv_ref, err_msg
def read_simbad_data(star_name):
    '''
    SIMBAD query
    '''

    customSimbad = Simbad()
    # customSimbad.list_votable_fields() #  to list all avaiable fields
    customSimbad.get_votable_fields()
    customSimbad.add_votable_fields('plx', 'plx_error', 'rot', 'sptype',
                                    'measurements')

    # print(customSimbad.get_votable_fields())
    result_table = customSimbad.query_object(star_name)
    # star = result_table['MAIN_ID']
    star = np.copy(star_name)
    print(star)
    # print(result_table.keys())
    main_id = result_table['MAIN_ID'].item()
    plx = result_table['PLX_VALUE'][0]
    plx_error = result_table['PLX_ERROR'][0]
    vsini = result_table['ROT_Vsini'][0]
    vsini_err = result_table['ROT_err'].item()
    sptype = result_table['SP_TYPE']
    sptype = sptype.item()
    sptype_qual = result_table['SP_QUAL']
    sptype = sptype.decode('UTF-8')
    rot_bibcode = result_table['ROT_bibcode']
    dec = result_table['DEC'].item()
    ra = result_table['RA'].item()

    iras_f12 = result_table['IRAS_f12'].item()
    iras_e12 = result_table['IRAS_e12'].item()
    iras_f25 = result_table['IRAS_f25'].item()
    iras_e25 = result_table['IRAS_e25'].item()
    iras_f60 = result_table['IRAS_f60'].item()
    iras_e60 = result_table['IRAS_e60'].item()
    iras_f100 = result_table['IRAS_f100'].item()
    iras_e100 = result_table['IRAS_e100'].item()

    JP11_U_360 = result_table['JP11_U_360'].item()  # 3600 AA
    JP11_B_450 = result_table['JP11_B_450'].item()  # 4500 AA
    JP11_V_555 = result_table['JP11_V_555'].item()  # 5550 AA
    JP11_R_670 = result_table['JP11_R_670'].item()  # 6700 AA
    JP11_I_870 = result_table['JP11_I_870'].item()  # 8700 AA
    JP11_J_1200 = result_table['JP11_J_1200'].item()  # 12000 AA
    JP11_K_2200 = result_table['JP11_K_2200'].item()  # 22000 AA
    JP11_L_3500 = result_table['JP11_L_3500'].item()  # 35000 AA
    JP11_M_5000 = result_table['JP11_M_5000'].item()  # 50000 AA
    JP11_N_9000 = result_table['JP11_N_9000'].item()  # 90000 AA
    JP11_H_16200 = result_table['JP11_H_16200'].item()  # 162000 AA

    ROT_upVsini_1 = result_table['ROT_upVsini_1'].item()
    ROT_Vsini_1 = result_table['ROT_Vsini_1'].item()
    ROT_err_1 = result_table['ROT_err_1'].item()
    ROT_bibcode_1 = result_table['ROT_bibcode_1'].item()
    RVel_Rvel = result_table['RVel_Rvel'].item()
    RVel_bibcode = result_table['RVel_bibcode'].item()

    TD1_m2740 = result_table['TD1_m2740'].item()  # 27400 AA
    TD1_se_m2740 = result_table['TD1_se_m2740'].item()  # sigma
    TD1_m2365 = result_table['TD1_m2365'].item()  # 23650 AA
    TD1_se_m2365 = result_table['TD1_se_m2365'].item()  # sigma
    TD1_m1965 = result_table['TD1_m1965'].item()  # 19650 AA
    TD1_se_m1965 = result_table['TD1_se_m1965'].item()  # sigma
    TD1_m1565 = result_table['TD1_m1565'].item()  # 15650 AA
    TD1_se_m1565 = result_table['TD1_se_m1565'].item()  # sigma

    UBV_V = result_table['UBV_V'].item()
    UBV_B_V = result_table['UBV_B_V'].item()
    UBV_U_B = result_table['UBV_U_B'].item()
    UBV_bibcode = result_table['UBV_bibcode'].item()

    uvby_b_y = result_table['uvby_b_y'].item()
    uvby1_b_y = result_table['uvby1_b_y'].item()
    uvby1_m1 = result_table['uvby1_m1'].item()
    uvby1_bibcode = result_table['uvby1_bibcode'].item()

    simbad_data = [
        iras_f12, iras_e12, iras_f25, iras_e25, iras_f60, iras_e60, iras_f100,
        iras_e100, JP11_U_360, JP11_B_450, JP11_V_555, JP11_R_670, JP11_I_870,
        JP11_J_1200, JP11_K_2200, JP11_L_3500, JP11_M_5000, JP11_N_9000,
        JP11_H_16200, ROT_upVsini_1, ROT_Vsini_1, ROT_err_1, ROT_bibcode_1,
        RVel_Rvel, RVel_bibcode, TD1_m2740, TD1_se_m2740, TD1_m2365,
        TD1_se_m2365, TD1_m1965, TD1_se_m1965, TD1_m1565, TD1_se_m1565, UBV_V,
        UBV_B_V, UBV_U_B, UBV_bibcode, uvby_b_y, uvby1_b_y, uvby1_m1,
        uvby1_bibcode
    ]

    return main_id, star.item(), plx, plx_error, vsini, vsini_err, sptype, ra,\
        dec, rot_bibcode.item(), simbad_data
Beispiel #9
0
    def from_simbad(cls, simbad_id, *, version=2, target_id=None,
        fits_keywords={}, **columns):
        """

Create an OI_TARGET table from simbad identifiers

Arguments
---------

version (int, optional)
    Version of the OIFITS standard if it cannot be deduced from context
simbad_id (str × NTARGET)
    IDs recognised by SIMBAD
target_id (int × NTARGET, optional, default: 1 .. NTARGET)
    target ID for cross-reference 
category (str × NTARGET, optional)
    target catogory, SCI or CAL
fits_keywords (dict, optional, default: {})
    additional FITS header keywords 

Additional arguments
--------------------

Any additional keyword argument will be appended as a non-standard FITS 
column with its name prefixed with NS_ 

        """
        from astroquery.simbad import Simbad 

        deg = np.deg2rad(1)
        mas = deg / 3_600_000

        simbad = Simbad()
        
        # at CDS is not working
        simbad.SIMBAD_URL = 'https://simbad.harvard.edu/simbad/sim-script' 

        simbad.remove_votable_fields(*simbad.get_votable_fields()[1:])
        # OIFITS standard imposes equinox = epoch for the frame which
        # de facto excludes ICRS, we use FK5.
        simbad.add_votable_fields(
            'ra(d;A;FK5;J2000;2000)', 'dec(d;D;FK5;J2000;2000)',
            'coo_err_angle', 'coo_err_maja', 'coo_err_mina',
            'plx', 'plx_error',
            'rvz_radvel', 'rvz_wavelength',
            'pmra', 'pmdec', 'pm_err_angle', 'pm_err_maja', 'pm_err_mina',
            'sp',
        )
        tab = simbad.query_objects(simbad_id)

        # target ID must be ascii, if not, pick simbad
        main_id = tab['MAIN_ID']
        target = [s if ascii(s)[1:-1] == s else decode(m)
                            for s, m in zip(simbad_id, main_id)]

        def tolist(x, deflt=np.nan):
            x = [decode(e) for e in x.tolist()]
            x = np.array([deflt if e in ['', None] else e for e in x])
            return x

        def ellipse_to_xy_err(a, b, theta):
            a2, b2 = a**2, b**2
            cos2, sin2 = np.cos(theta) ** 2, np.sin(theta) ** 2
            x = np.sqrt(a2 * cos2 + b2 * sin2)
            y = np.sqrt(a2 * sin2 + b2 * cos2)
            return x,y 

        # coordinates and parallaxes
        ra = tolist(tab['RA_d_A_FK5_J2000_2000'])
        dec = tolist(tab['DEC_d_D_FK5_J2000_2000'])
        a = mas / deg * tolist(tab['COO_ERR_MAJA'])
        b = mas  / deg * tolist(tab['COO_ERR_MINA'])
        theta = deg * tolist(tab['COO_ERR_ANGLE'])
        ra_err, dec_err  = ellipse_to_xy_err(a, b, theta)
        equinox = 2000.
 
        parallax = mas / deg * tolist(tab['PLX_VALUE'])
        para_err = mas / deg * tolist(tab['PLX_ERROR'])
        
        # velocity and proper motion
        sysvel = 1e3 * tolist(tab['RVZ_RADVEL'])
        veldef = tolist(tab['RVZ_WAVELENGTH'], 'OPTICAL')
        veltyp = 'BARYCENTRIC'
        
        pmra = mas / deg * tolist(tab['PMRA'])
        pmdec = mas / deg * tolist(tab['PMDEC'])
        a = mas / deg * tolist(tab['PM_ERR_MAJA'])
        b = mas / deg * tolist(tab['PM_ERR_MINA'])
        theta = deg * tolist(tab['PM_ERR_ANGLE'])
        pmra_err, pmdec_err = ellipse_to_xy_err(a, b, theta)
       
        # spectral type
        spectyp = tolist(tab['SP_TYPE'], 'UNKNOWN') 

        return cls.from_data(version=version, target_id=target_id,
                target=target, ra=ra, dec=dec, equinox=equinox,
                ra_err=ra_err, dec_err=dec_err,
                sysvel=sysvel, veltyp=veltyp, veldef=veldef,
                pmra=pmra, pmdec=pmdec, pmra_err=pmra_err, pmdec_err=pmdec_err,
                parallax=parallax, para_err=para_err, spectyp=spectyp,
                **columns)