;+ ; NAME: ; oc_getstar_bs ; ; PURPOSE: (one line) ; Returns BS star structures given their ID's. ; ; DESCRIPTION: ; Returns a fully-populated BS star structure for each ID supplied. ; The ID's must be in the BS format. The star structure is returned in ; the standard format, and includes the raw BS catalog line as well as ; standard-format RA, DEC, magnitudes, etc. ; ; CATEGORY: ; Star catalogs ; ; CALLING SEQUENCE: ; stars = oc_getstar_bs(ids [, NSTARS=nstars] [, /VERBOSE]) ; ; INPUTS: ; ids -- BS id's in string format. Can be either scalar or vector. ; Either SCAT-format SCAT-format ('221.00434') or standard UCAC2 ; format ('00534450'), but all ids must be in the same format. ; ; OPTIONAL INPUT PARAMETERS: ; None ; ; KEYWORD INPUT PARAMETERS: ; VERBOSE -- Print messages about incorrect/missing ID's to screen if set. ; ; KEYWORD OUTPUT PARAMETERS: ; NSTARS -- Returns the number of successfully-retrieved stars ; ; OUTPUTS: ; Structures of type 'star' with fields filled in. ; Returns either a vector or a scalar depending on input value 'ids'. ; Length of returned value is the same as that of input 'ids.' ; ; The field star.bs.record is the BS text catalog entry. ; The fields in star.bs.* are exactly as described in the ; BS Vizier ReadMe file. ; If a star is not found, that entry is blank. ; ; COMMON BLOCKS: ; None ; ; SIDE EFFECTS: ; None ; ; RESTRICTIONS: ; BS catalog must be available at $WCS_CATDIR/bs/catalog.dat . ; ; EXAMPLE: ; print, (oc_getstar_bs(['0', '1000', '10000'])).id ; [Prints "none 1000 10000"] ; ; MODIFICATION HISTORY: ; Written 26-Oct-2005 by Leslie Young, SwRI ; ;- function oc_getstar_bs, ids, NSTARS=nstars, VERBOSE=verbose, CAT=cat ; ** BS catalog file format, from Vizier's ReadMe file. ** ; ;Byte-by-byte Description of file: catalog ;-------------------------------------------------------------------------------- ; Bytes Format Units Label Explanations ;-------------------------------------------------------------------------------- ; 1- 4 I4 --- HR [1/9110]+ Harvard Revised Number ; = Bright Star Number ; 5- 14 A10 --- Name Name, generally Bayer and/or Flamsteed name ; 15- 25 A11 --- DM Durchmusterung Identification (zone in ; bytes 17-19) ; 26- 31 I6 --- HD [1/225300]? Henry Draper Catalog Number ; 32- 37 I6 --- SAO [1/258997]? SAO Catalog Number ; 38- 41 I4 --- FK5 ? FK5 star Number ; 42 A1 --- IRflag [I] I if infrared source ; 43 A1 --- r_IRflag *[ ':] Coded reference for infrared source ; 44 A1 --- Multiple *[AWDIRS] Double or multiple-star code ; 45- 49 A5 --- ADS Aitken's Double Star Catalog (ADS) designation ; 50- 51 A2 --- ADScomp ADS number components ; 52- 60 A9 --- VarID Variable star identification ; 61- 62 I2 h RAh1900 ?Hours RA, equinox B1900, epoch 1900.0 (1) ; 63- 64 I2 min RAm1900 ?Minutes RA, equinox B1900, epoch 1900.0 (1) ; 65- 68 F4.1 s RAs1900 ?Seconds RA, equinox B1900, epoch 1900.0 (1) ; 69 A1 --- DE-1900 ?Sign Dec, equinox B1900, epoch 1900.0 (1) ; 70- 71 I2 deg DEd1900 ?Degrees Dec, equinox B1900, epoch 1900.0 (1) ; 72- 73 I2 arcmin DEm1900 ?Minutes Dec, equinox B1900, epoch 1900.0 (1) ; 74- 75 I2 arcsec DEs1900 ?Seconds Dec, equinox B1900, epoch 1900.0 (1) ; 76- 77 I2 h RAh ?Hours RA, equinox J2000, epoch 2000.0 (1) ; 78- 79 I2 min RAm ?Minutes RA, equinox J2000, epoch 2000.0 (1) ; 80- 83 F4.1 s RAs ?Seconds RA, equinox J2000, epoch 2000.0 (1) ; 84 A1 --- DE- ?Sign Dec, equinox J2000, epoch 2000.0 (1) ; 85- 86 I2 deg DEd ?Degrees Dec, equinox J2000, epoch 2000.0 (1) ; 87- 88 I2 arcmin DEm ?Minutes Dec, equinox J2000, epoch 2000.0 (1) ; 89- 90 I2 arcsec DEs ?Seconds Dec, equinox J2000, epoch 2000.0 (1) ; 91- 96 F6.2 deg GLON ?Galactic longitude (1) ; 97-102 F6.2 deg GLAT ?Galactic latitude (1) ; 103-107 F5.2 mag Vmag ?Visual magnitude (1) ; 108 A1 --- n_Vmag *[ HR] Visual magnitude code ; 109 A1 --- u_Vmag [ :?] Uncertainty flag on V ; 110-114 F5.2 mag B-V ? B-V color in the UBV system ; 115 A1 --- u_B-V [ :?] Uncertainty flag on B-V ; 116-120 F5.2 mag U-B ? U-B color in the UBV system ; 121 A1 --- u_U-B [ :?] Uncertainty flag on U-B ; 122-126 F5.2 mag R-I ? R-I in system specified by n_R-I ; 127 A1 --- n_R-I [CE:?D] Code for R-I system (Cousin, Eggen) ; 128-147 A20 --- SpType Spectral type ; 148 A1 --- n_SpType [evt] Spectral type code ; 149-154 F6.3 arcsec/yr pmRA *?Annual proper motion in RA J2000, FK5 system ; 155-160 F6.3 arcsec/yr pmDE ?Annual proper motion in Dec J2000, FK5 system ; 161 A1 --- n_Parallax [D] D indicates a dynamical parallax, ; otherwise a trigonometric parallax ; 162-166 F5.3 arcsec Parallax ? Trigonometric parallax (unless n_Parallax) ; 167-170 I4 km/s RadVel ? Heliocentric Radial Velocity ; 171-174 A4 --- n_RadVel *[V?SB123O ] Radial velocity comments ; 175-176 A2 --- l_RotVel [<=> ] Rotational velocity limit characters ; 177-179 I3 km/s RotVel ? Rotational velocity, v sin i ; 180 A1 --- u_RotVel [ :v] uncertainty and variability flag on ; RotVel ; 181-184 F4.1 mag Dmag ? Magnitude difference of double, ; or brightest multiple ; 185-190 F6.1 arcsec Sep ? Separation of components in Dmag ; if occultation binary. ; 191-194 A4 --- MultID Identifications of components in Dmag ; 195-196 I2 --- MultCnt ? Number of components assigned to a multiple ; 197 A1 --- NoteFlag [*] a star indicates that there is a note ; (see file notes) ;-------------------------------------------------------------------------------- d2r = 2*!dpi / 360d ; Degrees -> radians as2d = 1/(60d * 60d) ; Arcsec -> degrees mas2d = as2d / 1000d ; mArcsec -> degrees as2d = 1/(60d * 60d) ; Arcsec -> degrees as2r = as2d*d2r ; Arcsec -> radians mas2r = mas2d*d2r ; mArcsec -> radians yr2sec = 31557600d ; Year -> seconds. ; 31557600. from cspice_jyear. ; Initialize all of the proper *STAR* variables ; Ideally we would call oc_struct_star to set this up, but this does not work ; here because it is not possible to add new fields (e.g., .hd) to an existing ; structure. nid = 6 idcat = replicate('',nid) id = replicate('',nid) poscat = '' et = 0d ra = 0d dec = 0d raerr = 0d decerr = 0d radot = 0d decdot = 0d radoterr = 0d decdoterr = 0d etpm = [0d, 0d] ra_etpm = 0d ; RA at PM=0 dec_etpm = 0d ; DEC at PM=0 raerr_etpm = 0d ; RA err at PM=0 decerr_etpm = 0d ; Dec err at PM=0 nmag = 3 magcat = replicate('', nmag) magname = replicate('', nmag) mag = replicate(0., nmag) magerr = replicate(0., nmag) SpTcat = '' SpT = '' notecat = [''] note = [''] ; Initialize all of the proper *BS* variables. All values are kept as their ; original format, even if this is a little unusual (e.g., RA is integer, in ; tenths of a minute). hr = 0 name = '' dm = '' hd = 0L & hd_str = '' sao = 0L & sao_str = '' fk5 = 0L & fk5_str = '' irflag = '' r_irflag = '' multiple = '' ads = '' adscomp = '' varid = '' RAh1900 = 0 & RAh1900_str = '' RAm1900 = 0 & RAm1900_str = '' RAs1900 = 0.0 & RAs1900_str = '' DE_1900 = '' DEd1900 = 0 & DEd1900_str = '' DEm1900 = 0 & DEm1900_str = '' DEs1900 = 0 & DEs1900_str = '' RAh = 0 & RAh_str = '' RAm = 0 & RAm_str = '' RAs = 0.0 & RAs_str = '' DE_ = '' DEd = 0 & DEd_str = '' DEm = 0 & DEm_str = '' DEs = 0 & DEs_str = '' glon = 0.0 & glon_str = '' glat = 0.0 & glat_str = '' Vmag = 0.0 & Vmag_str = '' n_Vmag = '' u_Vmag = '' B_V = 0.0 & B_V_str = '' u_B_V = '' U_B = 0.0 & U_B_str = '' u_U_B = '' R_I = 0.0 & R_I_str = '' n_R_I = '' SpType = '' n_SpType = '' pmRA = 0.0 & pmRA_str = '' pmDE = 0.0 & pmDE_str = '' n_Parallax = '' Parallax = 0.0 & Parallax_str = '' RadVel = 0 & RadVel_str = '' n_RadVel = '' l_RotVel = '' RotVel = 0 & RotVel_str = '' u_RotVel = '' DMag = 0.0 & DMag_str = '' Sep = 0.0 & Sep_str = '' MultID = '' MultCnt = 0 & MultCnt_str = '' NoteFlag = '' ; Not an Yale Bright Star field. This field stores the entire HD catalog line entry. record = '' bs = {hr:hr, name:name, dm:dm, hd:hd, sao:sao, fk5:fk5, irflag:irflag, $ r_irflag:r_irflag, multiple:multiple, ads:ads, adscomp:adscomp, $ varid:varid, RAh1900:RAh1900, RAm1900:RAm1900, RAs1900:RAs1900, $ DE_1900:DE_1900, DEd1900:DEd1900, DEm1900:DEm1900, DEs1900:DEs1900, $ RAh:RAh, RAm:RAm, RAs:RAs, DE_:DE_, DEd:DEd, DEm:DEm, DEs:DEs, $ glon:glon, glat:glat, Vmag:Vmag, n_Vmag:n_Vmag, u_Vmag:u_Vmag, $ B_V:B_V, u_B_V:u_B_V, U_B:U_B, u_U_B:u_U_B, R_I:R_I, n_R_I:n_R_I, $ SpType:SpType, n_SpType:n_SpType, pmRA:pmRA, pmDE:pmDE, $ n_Parallax:n_Parallax, Parallax:Parallax, $ RadVel:RadVel, n_RadVel:n_RadVel, l_RotVel:l_RotVel, $ RotVel:RotVel, u_RotVel:u_RotVel, DMag:DMag, Sep:Sep, $ MultID:MultID, MultCnt:MultCnt, NoteFlag:NoteFlag, record:record} star = {idcat:idcat, id:id, poscat:poscat, et:et, ra:ra, dec:dec,$ raerr:raerr, decerr:decerr, radot:radot, $ decdot:decdot, radoterr:radoterr, decdoterr:decdoterr, $ etpm:etpm, ra_etpm:ra_etpm, dec_etpm:dec_etpm, $ raerr_etpm:raerr_etpm, decerr_etpm:decerr_etpm, $ magcat:magcat, magname:magname, mag:mag, $ magerr:magerr, sptcat:sptcat, spt:spt, notecat:notecat, $ note:note, $ bs:bs} bs_init = bs star_init = star num_ids = sizex(ids) stars = make_array(num_ids, value=star) ; Get the raw catalog lines from the BS catalog lines = oc_getline_bs(ids, NSTARS=nstars, VERBOSE=verbose, cat=cat) ; Now process each line for i = 0L, num_ids-1 do begin id = ids[i] line = lines[i] ; Check to make sure it's valid if (line eq '') then begin star = oc_star_set_empty(star_init) goto, parse_end end ; Set the string from the Vizier ReadMe catalog description file ; but set floats and integers to strings since they may be BLANK ; string_bs = '(I4,A10,A11,A6,A6,A5,A1,A1,A1,A5,A2,A9,A2,A2,A4,A1,A2,A2,A2,A2,A2,'+$ ; 'A4,A1,A2,A2,A2,A6,A6,A5,A1,A1,A5,A1,A5,A1,A5,A1,A20,A1,A6,A6,A1,A5,A4,A2,A3,A1,A4,'+$ ; 'A2,A3,A1,A4,A6,A4,A2,A1)' string_bs = '(I4, A10,A11,A6,A6,A4 '+$ ',A1,A1,A1,A5,A2,A9' +$ ',A2,A2,A4'+$ ; RA1900 ',A1,A2,A2,A2' + $ ; DE1900 ',A2,A2,A4'+$ ; RA ',A1,A2,A2,A2' + $ ; Dec ',A6, A6'+$ ; Glat, Glon ',A5, A1, A1, A5, A1, A5, A1, A5, A1' + $ ; mags ',A20, A1' + $ ; spectral type ',A6,A6,A1,A5'+$ ; pm, parallax ',A4,A4,A2,A3,A1'+$ ; rad & rot vel ',A4,A6,A4,A2,A1'+$ ; double information ')' ; Parse the raw catalog line into a bunch of variables ; Pad the string line = strmid(line + ' ',$ 0, 197) ; help, hr, name, dm, hd_str, sao_str reads, line, format=string_bs, hr, name, dm, hd_str, sao_str, fk5_str, $ IRflag, r_IRflag, Multiple, ADS, ADScomp, VarID, $ RAh1900_str, RAm1900_str, RAs1900_str, $ DE_1900, DEd1900_str, DEm1900_str, DEs1900_str, $ RAh_str, RAm_str, RAs_str, $ DE_, DEd_str, DEm_str, DEs_str, $ glon_str, glat_str, $ Vmag_str, N_Vmag, u_Vmag, B_V_str, u_B_V, U_B_str, u_U_B, R_I_str, n_R_I, $ SpType, n_SpType, $ pmRA_str, pmDE_str, n_Parallax, Parallax_str,$ RadVel_str, n_RadVel, l_RotVel, RotVel_str, u_RotVel, $ dmag_str, sep_str, multID, MultCnt_str, noteflag ; help, hr, name, dm, hd_str, sao_str, fk5_str, $ ; IRflag, r_IRflag, Multiple, ADS, ADScomp, VarID, $ ; RAh1900_str, RAm1900_str, RAs1900_str, $ ; DE_1900, DEd1900_str, DEm1900_str, DEs1900_str, $ ; RAh_str, RAm_str, RAs_str, $ ; DE_, DEd_str, DEm_str, DEs_str, $ ; glon_str, glat_str, $ ; Vmag_str, N_Vmag, u_Vmag, B_V_str, u_B_V, U_B_str, u_U_B, R_I_str, n_R_I, $ ; SpType, n_SpType, $ ; pmRA_str, pmDE_str, n_Parallax, Parallax_str,$ ; RadVel_str, n_RadVel, l_RotVel, RotVel_str, u_RotVel, $ ; dmag_str, sep_str, multID, multCnt_str, noteflag ; Clear the star structure, then stick each variable into its proper *BS* ; structure location ; ; Assigning a string to a float or int tag will do the correct ; conversion of the string is a float or int. ; In case the string is a blank, append the desired "bad field" number ; to the string. bs = bs_init star = star_init bs.record = line bs.hr = hr bs.name = name bs.dm = dm bs.hd = hd_str + ' -999' bs.sao = sao_str + ' -999' bs.fk5 = fk5_str + ' -999' bs.IRflag = IRflag bs.r_IRflag = r_IRflag bs.Multiple = Multiple bs.ADS = ADS bs.ADScomp = ADScomp bs.VarID = VarID bs.RAh1900 = RAh1900_str + ' -999' bs.RAm1900 = RAm1900_str + ' -999' bs.RAs1900 = RAs1900_str + ' -999' bs.DE_1900 = DE_1900 bs.DEd1900 = DEd1900_str + ' -999' bs.DEm1900 = DEm1900_str + ' -999' bs.DEs1900 = DEs1900_str + ' -999' bs.RAh = RAh_str + ' -999' bs.RAm = RAm_str + ' -999' bs.RAs = RAs_str + ' -999' bs.DE_ = DE_ bs.DEd = DEd_str + ' -999' bs.DEm = DEm_str + ' -999' bs.DEs = DEs_str + ' -999' bs.glon = glon_str + ' -999' bs.glat = glat_str + ' -999' bs.Vmag = Vmag_str + ' -999' bs.n_Vmag = n_Vmag bs.u_Vmag = u_Vmag bs.B_V = B_V_str + ' -999' bs.u_B_V = u_B_V bs.U_B = U_B_str + ' -999' bs.u_U_B = u_U_B bs.R_I = R_I_str + ' -999' bs.n_R_I = n_R_I bs.SpType = SpType bs.n_SpType = n_SpType bs.pmRA = pmRA_str + ' -999' bs.pmDE = pmDE_str + ' -999' bs.n_Parallax = n_Parallax bs.Parallax = Parallax_str + ' -999' bs.RadVel = RadVel_str + ' -999' bs.n_RadVel = n_RadVel bs.l_RotVel = l_RotVel bs.RotVel = RotVel_str + ' -999' bs.u_RotVel = u_RotVel bs.dmag = dmag_str + ' -999' bs.sep = sep_str + ' -999' bs.multID = multID bs.multCnt = multCnt_str + ' -999' bs.noteflag = noteflag ; Process the variables, precess the coords, and stick them all into the ; proper *STAR* structure location. ; IDs. The ID cat is 'bs' (bright star) for all; this is the source ; of the information. Format of ids is to match SINBAD. star.idcat = replicate('bs', nid) star.id = [ 'HR ' + strcompress(string(bs.hr), /REMOVE), $ strtrim(strcompress(bs.name), 2), $ strtrim(bs.dm,2), $ 'HD ' + strcompress(string(bs.hd), /REMOVE), $ 'SAO ' + strcompress(string(bs.sao), /REMOVE), $ 'FK5 ' + strcompress(string(bs.fk5), /REMOVE) ] ; Fill in positional information ; Note that the BS catalog is limited intrinsically in its ; precision, and better coordinates for BS stars can be taken from the ; cross-referencing to other catalogs. star.poscat = 'bs' star.et = 0.d ; RA, J2000, radians if bs.rah eq -999 then begin ra = -999.d endif else begin ra = (bs.RAh + bs.RAm/60d + bs.RAs/3600d) * (!dpi/12d) endelse ; Dec, J2000, radians if bs.DEd eq -999 then begin dec = -999.d endif else begin dec = (bs.DE_ eq '-' ? -1d : 1d) * $ ( bs.DEd + (bs.DEm/60d) + (bs.DEs/3600d) ) * (!dpi/180d) endelse star.ra = ra star.dec = dec star.raerr = -999 star.decerr = -999 star.radot = pmRA*as2r/yr2sec star.decdot = pmDE*as2r/yr2sec star.raerr = -999 star.decerr = -999 star.etpm = [0.d, 0.d] star.ra_etpm = ra star.dec_etpm = dec star.raerr_etpm = -999. star.decerr_etpm = -999. ; Fill in the magnitude information ; Bright Star Catalog has ; V ; B-V ; U-B ; R-I star.magcat = ['bs', 'bs', 'bs'] star.magname = ['V','B','U'] star.mag[0] = bs.Vmag if star.mag[0] gt -998 and bs.B_V gt -998 then begin star.mag[1] = star.mag[0] + bs.B_V endif else begin star.mag[1] = -999 endelse if star.mag[1] gt -998 and bs.U_B gt -998 then begin star.mag[2] = star.mag[1] + bs.U_B endif else begin star.mag[2] = -999 endelse star.magerr = replicate(-999,nmag) star.SpTcat = ['bs'] star.SpT = bs.sptype star.notecat = 'bs' ; Fill in the notes. ; Use grep to search the notes file star.notecat = '' ; if strtrim(bs.noteflag,2) ne '' then begin if (0) then begin id_pad = string(long(id), format='(I5)') noteline = '' notesfn = 'bs/notes' path_catalog = getenv('WCS_CATDIR') spawn, /NOSHELL, ['grep', '^' + id_pad, path_catalog + '/' + notesfn],noteline nnotes = n_elements(noteline) eol = replicate(string(13b), nnotes) star.note = '' for inote = 0, nnotes-1 do star.note = star.note + noteline[inote] + eol[inote] endif else begin star.note = '' endelse star.bs = bs parse_end: ; Store the structure in an array stars[i] = star endfor ; Based on whether a scalar or an array was passed in, return the same. (In ; reality, it appears to always return a one-element array of structures, but ; this makes no difference to the user.) if is_scalar(ids) then return, stars[0] if is_array(ids) then return, stars end