diff --git a/gsselect/gemcats.py b/gsselect/gemcats.py index a7cc1bb..8ff8d2b 100644 --- a/gsselect/gemcats.py +++ b/gsselect/gemcats.py @@ -1,11 +1,11 @@ #!/usr/bin/env python from __future__ import print_function -import os import subprocess from astropy.coordinates import SkyCoord import astropy.units as u + def gemdssfile(ra, dec, outfile, xsiz, ysiz, site='cpo'): """Runs a search of the Gemini DSS server and downloads a FITS image of the field Bryan Miller @@ -35,8 +35,7 @@ def gemdssfile(ra, dec, outfile, xsiz, ysiz, site='cpo'): url += '&x=' + l_xsiz + '&y=' + l_ysiz p = subprocess.Popen(["curl", "-k", "-s", "-o", l_outfile, url], - stdout = subprocess.PIPE, stderr = subprocess.PIPE) - + stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() if err.decode() != '': print(err.decode()) @@ -81,7 +80,6 @@ def gemgstable(ra, dec, outfile, cat='ucac4', radius=0.12, site='gs'): p = subprocess.Popen(["curl", "-k", "-s", "-o", l_outfile, url], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, err = p.communicate() if err.decode() != '': print(err.decode()) @@ -92,17 +90,3 @@ def gemgstable(ra, dec, outfile, cat='ucac4', radius=0.12, site='gs'): status = 1 return status - -if __name__ == "__main__": - - sra = '01:50:16.430' - sdec = '00:57:01.90' - xsiz = 15. - ysiz = 15. - home = os.environ['PWD'] - - res1 = gemdssfile(sra, sdec, home + '/test/cpodss_test.fits', xsiz, ysiz, site='cpo') - print(res1) - - res2 = gemgstable(sra, sdec, home + '/test/cpoucac4_test.vot', cat='ucac4', radius=0.1, site='cpo') - print(res2) \ No newline at end of file diff --git a/gsselect/gsselect.py b/gsselect/gsselect.py index a87ce6c..f409648 100644 --- a/gsselect/gsselect.py +++ b/gsselect/gsselect.py @@ -19,7 +19,8 @@ # local scripts from gsselect.inpoly import inpoly -from gsselect.gemcats import gemdssfile,gemgstable +from gsselect.gemcats import gemdssfile, gemgstable + def rlimits(inst, wfs, site, verbose=False): @@ -40,22 +41,22 @@ def rlimits(inst, wfs, site, verbose=False): rmin = 0.0 rmax = 0.0 - # oimin = {'GMOS-N':0.33, 'GMOS-S':0.33, 'F2':0.33, 'GNIRS':0.2} - # oimax = {'GMOS-N':4.8, 'GMOS-S':4.8, 'F2':3.75, 'GNIRS':1.5} - oimin = {'GMOS-N':0.33, 'GMOS-S':0.33, 'F2':0.33} - oimax = {'GMOS-N':4.8, 'GMOS-S':4.8, 'F2':3.75} + # oimin = {'GMOS-N': 0.33, 'GMOS-S': 0.33, 'F2':0.33, 'GNIRS': 0.2} + # oimax = {'GMOS-N': 4.8, 'GMOS-S': 4.8, 'F2':3.75, 'GNIRS': 1.5} + oimin = {'GMOS-N': 0.33, 'GMOS-S': 0.33, 'F2': 0.33} + oimax = {'GMOS-N': 4.8, 'GMOS-S': 4.8, 'F2': 3.75} - p2min = {'GMOS-N':5.3, 'GMOS-S':5.3, 'F2':5.3, 'GNIRS':4.8, 'NIFS':4.0, - 'NIRIF/6':5.2, 'NIRIF/14':4.8, 'NIRIF/32':4.3} - p1min = {'GMOS-N':5.8, 'GMOS-S':5.8, 'F2':5.8, 'GNIRS':5.0, 'NIFS':4.8, - 'NIRIF/6':5.7, 'NIRIF/14':5.3, 'NIRIF/32':4.8} + p2min = {'GMOS-N': 5.3, 'GMOS-S': 5.3, 'F2': 5.3, 'GNIRS': 4.8, 'NIFS': 4.0, + 'NIRIF/6': 5.2, 'NIRIF/14': 4.8, 'NIRIF/32': 4.3} + p1min = {'GMOS-N': 5.8, 'GMOS-S': 5.8, 'F2': 5.8, 'GNIRS': 5.0, 'NIFS': 4.8, + 'NIRIF/6': 5.7, 'NIRIF/14': 5.3, 'NIRIF/32': 4.8} pmax = 6.9 if wfs == 'OIWFS': try: rmin = oimin[inst] rmax = oimax[inst] - except: + except Exception: if verbose: print('Only GMOS-N, GMOS-S, and F2 have supported OIs.') elif wfs == 'PWFS2': @@ -67,17 +68,18 @@ def rlimits(inst, wfs, site, verbose=False): return rmin, rmax + def maglimits(inst, wfs, site, iq, cc, sb, verbose=False): """ Magnitude correction for conditions Parameters - inst: Instrument ['GMOS','F2'] + inst: Instrument ['GMOS', 'F2'] wfs: Wavefront sensor ['OIWFS', 'PWFS1', 'PWFS2'] - site: Gemini site ['N','S','mko','cpo'] - iq: Image quality constraint ['20','70','85','Any'] + site: Gemini site ['N', 'S', 'mko', 'cpo'] + iq: Image quality constraint ['20', '70', '85', 'Any'] cc: Cloud cover constraint [0.0, -0.3, -1.0, -3.0] - sb: Sky brightness constraint ['20','50','80','Any'] + sb: Sky brightness constraint ['20', '50', '80', 'Any'] verbose Verbose output? Return @@ -89,23 +91,23 @@ def maglimits(inst, wfs, site, iq, cc, sb, verbose=False): magfaint = 9999. # limiting magnitudes are r-band except GNIRS OI (K-band) - # oifaint = {'GMOS-N':16.95, 'GMOS-S':15.65, 'F2':16.15, 'GNIRS':0.0} - # oibright = {'GMOS-N':6.0, 'GMOS-S':6.0, 'F2':6.0, 'GNIRS':14.0} - oifaint = {'GMOS-N':16.95, 'GMOS-S':15.65, 'F2':16.15} - oibright = {'GMOS-N':6.0, 'GMOS-S':6.0, 'F2':6.0} + # oifaint = {'GMOS-N': 16.95, 'GMOS-S': 15.65, 'F2': 16.15, 'GNIRS': 0.0} + # oibright = {'GMOS-N': 6.0, 'GMOS-S': 6.0, 'F2': 6.0, 'GNIRS': 14.0} + oifaint = {'GMOS-N': 16.95, 'GMOS-S': 15.65, 'F2': 16.15} + oibright = {'GMOS-N': 6.0, 'GMOS-S': 6.0, 'F2': 6.0} - p1faint = {'N':15.65, 'S':14.15} - p1bright = {'N':7.0, 'S':7.0} + p1faint = {'N': 15.65, 'S': 14.15} + p1bright = {'N': 7.0, 'S': 7.0} - p2faint = {'N':15.65, 'S':15.65} - p2bright = {'N':7.0, 'S':7.0} + p2faint = {'N': 15.65, 'S': 15.65} + p2bright = {'N': 7.0, 'S': 7.0} # Magnitude corrections for conditions dmag = 0.0 dmcc = [0.0, -0.3, -1.0, -3.0] try: - ii = ['50','70','80','Any'].index(cc) - except: + ii = ['50', '70', '80', 'Any'].index(cc) + except Exception: if verbose: print("cc must be one of '50','70','80','Any'") return magbright, magfaint @@ -113,8 +115,8 @@ def maglimits(inst, wfs, site, iq, cc, sb, verbose=False): dmiq = [0.25, 0.0, -0.25, -1.25] try: - ii = ['20','70','85','Any'].index(iq) - except: + ii = ['20', '70', '85', 'Any'].index(iq) + except Exception: if verbose: print("iq must be one of '20','70','85','Any'") return magbright, magfaint @@ -122,8 +124,8 @@ def maglimits(inst, wfs, site, iq, cc, sb, verbose=False): dmsb = [0.1, 0.0, -0.1, -0.2] try: - ii = ['20','50','80','Any'].index(sb) - except: + ii = ['20', '50', '80', 'Any'].index(sb) + except Exception: if verbose: print("sb must be one of '20','50','80','Any'") return magbright, magfaint @@ -135,7 +137,7 @@ def maglimits(inst, wfs, site, iq, cc, sb, verbose=False): try: magbright = oibright[inst] + dmag magfaint = oifaint[inst] + dmag - except: + except Exception: if verbose: print('Only GMOS-N, GMOS-S, and F2 have supported OIs.') elif wfs == 'PWFS1': @@ -147,6 +149,7 @@ def maglimits(inst, wfs, site, iq, cc, sb, verbose=False): return magbright, magfaint + def f2oifov(pad=0.0, mcao=False, port='side', verbose=False): """ Make a polygon of the F2 OI FOV @@ -158,13 +161,13 @@ def f2oifov(pad=0.0, mcao=False, port='side', verbose=False): verbose: Verbose output Returns xc, yc Coordinates of vertices [arcmin] - """ + """ # From f2oifov.pro # 2018oct27 - + try: - ii = ['side','up'].index(port.lower()) - except: + ii = ['side', 'up'].index(port.lower()) + except Exception: print('PORT must be "side" or "up".') return @@ -192,7 +195,7 @@ def f2oifov(pad=0.0, mcao=False, port='side', verbose=False): # angle of intersection, use law of cosines aisect = np.arccos((x2**2 + r1**2 - r2**2)/(2.*x2*r1)) - aisect2= np.arcsin(r1*np.sin(aisect)/r2) + aisect2 = np.arcsin(r1*np.sin(aisect)/r2) if (verbose): print(aisect*degrad, aisect2*degrad) @@ -220,24 +223,24 @@ def f2oifov(pad=0.0, mcao=False, port='side', verbose=False): yc = np.append(yc, yc[0]) if (verbose): - [print(xc[jj],yc[jj]) for jj in range(len(xc))] + [print(xc[jj], yc[jj]) for jj in range(len(xc))] if (verbose): - plt.plot(xc2,yc2) - plt.xlim = (-5,11) - plt.ylim = (-6,6) - plt.plot(xc1,yc1) - plt.plot(xc,yc,linewidth=4,linestyle='--') + plt.plot(xc2, yc2) + plt.xlim = (-5, 11) + plt.ylim = (-6, 6) + plt.plot(xc1, yc1) + plt.plot(xc, yc, linewidth=4, linestyle='--') plt.show() - #output + # output if (port == 'side'): - xc = -xc # make lozenge west of base - + xc = -xc # make lozenge west of base + return xc, yc -def gspick(xgs,ygs,xfov,yfov,mag,mmin,mmax,r,rmin,rweight): +def gspick(xgs, ygs, xfov, yfov, mag, mmin, mmax, r, rmin, rweight): """ Function for selecting guide star within WFS FOV Bryan Miller @@ -266,7 +269,7 @@ def gspick(xgs,ygs,xfov,yfov,mag,mmin,mmax,r,rmin,rweight): nv = len(xfov) if (xfov[0] == xfov[-1]) and (yfov[0] == yfov[-1]): nv -= 1 - ib = inpoly(xfov[:nv],yfov[:nv],xgs,ygs) + ib = inpoly(xfov[:nv], yfov[:nv], xgs, ygs) iin = np.where(ib)[0] if (True in ib): @@ -279,6 +282,7 @@ def gspick(xgs,ygs,xfov,yfov,mag,mmin,mmax,r,rmin,rweight): return iout + def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', site='N', pamode='flip', cat='UCAC4', chopping=False, imdir='./', overwrite=False, rmin=-1.0, pad=0.0, inst='GMOS', port='side', @@ -339,7 +343,7 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', l_pamode = pamode.lower() try: ii = ['fixed', 'flip', 'find'].index(l_pamode) - except: + except Exception: if verbose: print("PA modes are: 'fixed', 'flip', 'find'") return gstarg, gsra, gsdec, gsmag, l_pa @@ -366,39 +370,40 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', if 'GMOS' in l_inst: l_inst = 'GMOS-' + l_site try: - ii = ['GMOS-S','GMOS-N','F2','GNIRS','NIFS','NIRIF/6', 'NIRIF/14', 'NIRIF/32'].index(l_inst) - except: + ii = ['GMOS-S', 'GMOS-N', 'F2', 'GNIRS', 'NIFS', 'NIRIF/6', 'NIRIF/14', 'NIRIF/32'].index(l_inst) + except Exception: if verbose: - print("Currently supported instruments are: 'GMOS-S', 'GMOS-N', 'F2', 'GNIRS', 'NIFS', 'NIRIF/6', 'NIRIF/14', 'NIRIF/32'") + print("Currently supported instruments are: 'GMOS-S', 'GMOS-N', 'F2', 'GNIRS', 'NIFS', 'NIRIF/6', " + "'NIRIF/14', 'NIRIF/32'") return gstarg, gsra, gsdec, gsmag, l_pa if verbose: - print('Instrument: ',l_inst) + print('Instrument: ', l_inst) # IFU try: - iifu = ['none','two', 'red', 'blue'].index(ifu.lower()) - except: + iifu = ['none', 'two', 'red', 'blue'].index(ifu.lower()) + except Exception: if verbose: print("IFU options: 'none','two', 'red', 'blue'") return gstarg, gsra, gsdec, gsmag, l_pa - # WFS l_wfs = wfs.upper() try: ii = ['OIWFS', 'PWFS1', 'PWFS2'].index(l_wfs) - except: + except Exception: if verbose: print("Supported WFS are: 'OIWFS','PWFS1','PWFS2'") return gstarg, gsra, gsdec, gsmag, l_pa + if verbose: print('WFS: ', l_wfs) - l_target = re.sub(' ','',target) + l_target = re.sub(' ', '', target) - tcoo = SkyCoord(ra.strip(),dec.strip(),frame='icrs',unit = (u.hr, u.deg)) - l_ra = tcoo.ra.to_string(u.hour,sep=':') - l_dec = tcoo.dec.to_string(u.deg,sep=':') + tcoo = SkyCoord(ra.strip(), dec.strip(), frame='icrs', unit=(u.hr, u.deg)) + l_ra = tcoo.ra.to_string(u.hour, sep=':') + l_dec = tcoo.dec.to_string(u.deg, sep=':') if '-' not in l_dec and l_dec[0] != '+': l_dec = '+' + l_dec @@ -408,18 +413,18 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', # degstep = 10. # elif inst == 'F2': # degstep = 90. - + # Magnitude corrections for conditions mmin, mmax = maglimits(l_inst, l_wfs, l_site, iq, cc, sb, verbose=verbose) if verbose: - print('Mag min/max: ',mmin, mmax) + print('Mag min/max: ', mmin, mmax) if mmin == 9999. or mmax == 9999.: if verbose: print('Problem with magnitude limits.') return gstarg, gsra, gsdec, gsmag, l_pa # Radius limits - tmp_rmin, l_rmax = rlimits(l_inst,l_wfs,l_site,verbose=verbose) + tmp_rmin, l_rmax = rlimits(l_inst, l_wfs, l_site, verbose=verbose) if tmp_rmin == 0.0 or l_rmax == 0.0: if verbose: print('Problem with radius limits.') @@ -437,12 +442,12 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', if overwrite or not os.path.exists(imfile): if os.path.exists(imfile): os.remove(imfile) - gemdssfile(l_ra,l_dec,imfile,15.,15.,site=l_site) + gemdssfile(l_ra, l_dec, imfile, 15., 15., site=l_site) hdu = pyfits.open(imfile) h = hdu[0].header - cdelt = [h['CD1_1'],h['CD2_2']] - rot = np.arctan2(-1.*h['CD2_1'],h['CD2_2']) * degrad + cdelt = [h['CD1_1'], h['CD2_2']] + rot = np.arctan2(-1.*h['CD2_1'], h['CD2_2']) * degrad # print(cdelt) # print(rot) @@ -468,8 +473,8 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', # l_rmax = np.sqrt((3.31 - pad / 60.) ** 2 + (3.64 - pad / 60.) ** 2) elif (l_inst == 'F2'): # F2 - x, y = f2oifov (port = port, verbose=False) - xpad, ypad = f2oifov (pad = pad, port = port) + x, y = f2oifov(port=port, verbose=False) + xpad, ypad = f2oifov(pad=pad, port=port) dpa = 90. # l_rmax = l_rmax - pad / 60. @@ -497,12 +502,12 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', ang = np.array(range(101)) * 2. * np.pi / 100. # inner radius - xpr = l_rmin.to(u.degree).data * np.cos(ang)/np.cos(tcoo.dec) + tcoo.ra.degree - ypr = l_rmin.to(u.degree).data * np.sin(ang) + tcoo.dec.degree + xpr = l_rmin.to(u.degree).data * np.cos(ang)/np.cos(tcoo.dec) + tcoo.ra.degree + ypr = l_rmin.to(u.degree).data * np.sin(ang) + tcoo.dec.degree # plots, xpr / naxis1, ypr / naxis2, / norm, line = 2 # outer radius - xppr = l_rmax.to(u.degree).data * np.cos(ang)/np.cos(tcoo.dec) + tcoo.ra.degree - yppr = l_rmax.to(u.degree).data * np.sin(ang) + tcoo.dec.degree + xppr = l_rmax.to(u.degree).data * np.cos(ang)/np.cos(tcoo.dec) + tcoo.ra.degree + yppr = l_rmax.to(u.degree).data * np.sin(ang) + tcoo.dec.degree # Query catalog if cat == 'UCAC4': @@ -513,7 +518,7 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', gsres = gemgstable(l_ra, l_dec, gsfile, cat='ucac4', radius=0.12, site='cpo') gsq = parse_single_table(gsfile).to_table(use_names_over_ids=True) id = gsq['ucac4'] - gscoo = SkyCoord(gsq['raj2000'],gsq['dej2000'],frame='icrs',unit = (u.deg, u.deg)) + gscoo = SkyCoord(gsq['raj2000'], gsq['dej2000'], frame='icrs', unit=(u.deg, u.deg)) if l_inst == 'GNIRS' and l_wfs == 'OIWFS': mag = gsq['kmag'] else: @@ -530,27 +535,26 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', # Distance from center of field rsep = tcoo.separation(gscoo) if verbose: - print('Rsep:',rsep.arcmin.min(),rsep.arcmin.max()) + print('Rsep:', rsep.arcmin.min(), rsep.arcmin.max()) # PA gspa = tcoo.position_angle(gscoo) if verbose: - print('PA min/max: ',gspa.degree.min(), gspa.degree.max()) - + print('PA min/max: ', gspa.degree.min(), gspa.degree.max()) - ir = np.where(np.logical_and(np.logical_and(np.logical_and(mag > mmin, mag <= mmax),rsep.arcmin > l_rmin.data), + ir = np.where(np.logical_and(np.logical_and(np.logical_and(mag > mmin, mag <= mmax), rsep.arcmin > l_rmin.data), rsep.arcmin <= l_rmax.data))[0] ngs = len(ir) if verbose: print('Number of guide star candidates: ', ngs) # Pick guide star - iis = gspick(gscoo.ra.degree,gscoo.dec.degree,xppr,yppr,mag,mmin,mmax,rsep.degree, - l_rmin.to(u.degree),l_rweight) + iis = gspick(gscoo.ra.degree, gscoo.dec.degree, xppr, yppr, mag, mmin, mmax, rsep.degree, + l_rmin.to(u.degree), l_rweight) # If OIWFS, perhaps adjust PA if (l_wfs == 'OIWFS'): - if (iis != -1) and l_pamode=='find': + if (iis != -1) and l_pamode == 'find': # This puts the guide star near the center of the FoV l_pa = gspa[iis].degree + dpa elif (l_pamode != 'fixed'): @@ -568,8 +572,8 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', l_xppr = l_xppr/np.cos(tcoo.dec) + tcoo.ra.degree l_yppr += tcoo.dec.degree - l_iis = gspick(gscoo.ra.degree,gscoo.dec.degree,l_xppr,l_yppr,mag,mmin,mmax,rsep.degree, - l_rmin.to(u.degree),l_rweight) + l_iis = gspick(gscoo.ra.degree, gscoo.dec.degree, l_xppr, l_yppr, mag, mmin, mmax, rsep.degree, + l_rmin.to(u.degree), l_rweight) if (l_iis != -1): if mag[l_iis] < l_mag: @@ -591,8 +595,8 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', print('No guide star in FoV.') else: gstarg = str(id[iis].decode('UTF-8')) - gsra = gscoo.ra[iis].to_string(u.hour,sep=':') - gsdec = gscoo.dec[iis].to_string(u.degree,sep=':') + gsra = gscoo.ra[iis].to_string(u.hour, sep=':') + gsdec = gscoo.dec[iis].to_string(u.degree, sep=':') gsmag = mag[iis] # Plot @@ -606,84 +610,34 @@ def gsselect(target, ra, dec, pa=0.0, wfs='OIWFS', ifu='none', fig.show_grayscale(invert=True) fig.add_grid() fig.grid.set_color('white') - fig.show_markers(tcoo.ra,tcoo.dec,edgecolor='orange',marker='P',s=60) + fig.show_markers(tcoo.ra, tcoo.dec, edgecolor='orange', marker='P', s=60) if ngs > 0: - fig.show_markers(gscoo.ra[ir],gscoo[ir].dec,edgecolor='green',marker='o',s=60) + fig.show_markers(gscoo.ra[ir], gscoo[ir].dec, edgecolor='green', marker='o', s=60) if iis != -1: - fig.show_markers(gscoo.ra[iis],gscoo.dec[iis],edgecolor='blue',marker='s',s=80) + fig.show_markers(gscoo.ra[iis], gscoo.dec[iis], edgecolor='blue', marker='s', s=80) # WFS FOV - wfspoly_p = np.zeros((len(xpr),2)) + wfspoly_p = np.zeros((len(xpr), 2)) for ii in range(len(xpr)): - wfspoly_p[ii,0] = xpr[ii] - wfspoly_p[ii,1] = ypr[ii] - wfspoly_pp = np.zeros((len(xppr),2)) + wfspoly_p[ii, 0] = xpr[ii] + wfspoly_p[ii, 1] = ypr[ii] + wfspoly_pp = np.zeros((len(xppr), 2)) for ii in range(len(xppr)): wfspoly_pp[ii, 0] = xppr[ii] wfspoly_pp[ii, 1] = yppr[ii] - lstyle = {'OIWFS':{'p':'-', 'pp':'--'}, - 'PWFS2':{'p':'--', 'pp':'-'}, - 'PWFS1':{'p':'--', 'pp':'-'}} - fig.show_polygons([wfspoly_p], edgecolor='red',linestyle=lstyle[l_wfs]['p']) - fig.show_polygons([wfspoly_pp], edgecolor='red',linestyle=lstyle[l_wfs]['pp']) + lstyle = {'OIWFS': {'p': '-', 'pp': '--'}, + 'PWFS2': {'p': '--', 'pp': '-'}, + 'PWFS1': {'p': '--', 'pp': '-'}} + fig.show_polygons([wfspoly_p], edgecolor='red', linestyle=lstyle[l_wfs]['p']) + fig.show_polygons([wfspoly_pp], edgecolor='red', linestyle=lstyle[l_wfs]['pp']) if figout: if figfile.lower() == 'default': l_figfile = imdir + '/' + l_target + '_fov.png' else: l_figfile = imdir + '/' + figfile - # plt.savefig(l_figfile,dpi=dpi) - fig.save(l_figfile,dpi=dpi) + fig.save(l_figfile, dpi=dpi) if display: plt.show() fig.close() hdu.close() return gstarg, gsra, gsdec, gsmag, l_pa - - -# if __name__ == "__main__": -# -# target = 'TNO12345 url' # new target name -# ra = '12:22:22.860' # RA (J2000) -# dec = ' 4:31:03.23' # Dec (J2000) -# smags = '22.4/r/AB' -# utdate = '2018-03-15' -# # uttime = '05:35:00' # parang = 0, el=55 -# uttime = '03:24:00' # parang = -140, el = 43.2 -# pa = 310. -# -# # gstar, gsra, gsdec, gsmag, gspa = gsselect(target,ra,dec,pa,imdir='test/', site='south', pad=5., -# # inst='GMOS', ifu='none', wfs='OIWFS', pamode='flip', overwrite=False, -# # display=True, figout=True, dpi=75, verbose=True) -# # print(gstar, gsra, gsdec, gsmag, gspa) -# # -# # gstar, gsra, gsdec, gsmag, gspa = gsselect(target,ra,dec,pa,imdir='test/', site='north', pad=5., -# # inst='GNIRS', wfs='PWFS2', overwrite=False, -# # pamode='flip', display=True, verbose=True, figout=True, figfile='gsselect.pdf') -# # print(gstar, gsra, gsdec, gsmag, gspa) -# # -# # gstar, gsra, gsdec, gsmag, gspa = gsselect(target,ra,dec,pa,imdir='test/', site='north', pad=5., -# # inst='NIRIf/6', wfs='PWFS2', overwrite=False, -# # pamode='flip', display=True, verbose=True) -# # print(gstar, gsra, gsdec, gsmag, gspa) -# -# target = 'NGC4833' # new target name -# ra = '12:59:33.919' # RA (J2000) -# dec = '-70:52:35.4' # Dec (J2000) -# smags = '22.4/r/AB' -# pa = 300. -# -# gstar, gsra, gsdec, gsmag, gspa = gsselect(target,ra,dec,pa,imdir='test/', site='south', pad=5., -# inst='GMOS', ifu='none', wfs='OIWFS', pamode='flip', overwrite=False, -# display=True, figout=False, dpi=75, verbose=True) -# print(gstar, gsra, gsdec, gsmag, gspa) -# -# -# gstar, gsra, gsdec, gsmag, gspa = gsselect(target,ra,dec,pa,imdir='test/', site='south', pad=5., -# inst='F2', ifu='none', wfs='PWFS2', pamode='flip', overwrite=False, -# display=True, figout=False, dpi=75, verbose=True) -# print(gstar, gsra, gsdec, gsmag, gspa) -# -# gstar, gsra, gsdec, gsmag, gspa = gsselect(target,ra,dec,pa,imdir='test/', site='south', pad=5., -# inst='F2', ifu='none', wfs='OIWFS', pamode='flip', overwrite=False, -# display=True, figout=False, dpi=75, verbose=True) -# print(gstar, gsra, gsdec, gsmag, gspa) \ No newline at end of file diff --git a/gsselect/inpoly.py b/gsselect/inpoly.py index 417f799..b4be303 100644 --- a/gsselect/inpoly.py +++ b/gsselect/inpoly.py @@ -1,5 +1,4 @@ -def inpoly(xv,yv,xt,yt): - +def inpoly(xv, yv, xt, yt): """ Originally in C by Bob Stein and Craig Yap http://www.visibone.com/inpoly/ @@ -13,6 +12,7 @@ def inpoly(xv,yv,xt,yt): # 2016.06.25 - generalize to handle input arrays """ + nvert = len(xv) if nvert != len(yv) or nvert < 3: return -1 @@ -22,12 +22,12 @@ def inpoly(xv,yv,xt,yt): try: npoints = len(l_xt) - except: + except Exception: l_xt = [l_xt] npoints = len(l_xt) try: npointsy = len(l_yt) - except: + except Exception: l_yt = [l_yt] npointsy = len(l_yt) @@ -37,29 +37,28 @@ def inpoly(xv,yv,xt,yt): inside = [False for ii in range(npoints)] for jj in range(npoints): - xold=xv[nvert-1] - yold=yv[nvert-1] + xold = xv[nvert-1] + yold = yv[nvert-1] for i in range(nvert): - xnew=xv[i] - ynew=yv[i] + xnew = xv[i] + ynew = yv[i] if xnew > xold: - x1=xold - x2=xnew - y1=yold - y2=ynew + x1 = xold + x2 = xnew + y1 = yold + y2 = ynew else: - x1=xnew - x2=xold - y1=ynew - y2=yold + x1 = xnew + x2 = xold + y1 = ynew + y2 = yold # /* edge "open" at one end */ if (xnew < l_xt[jj]) == (l_xt[jj] <= xold) and (l_yt[jj]-y1)*(x2-x1) < ((y2-y1)*(l_xt[jj]-x1)): inside[jj] = not inside[jj] - xold=xnew - yold=ynew + xold = xnew + yold = ynew if npoints == 1: inside = inside[0] - return inside - + return inside diff --git a/gsselect/parangle.py b/gsselect/parangle.py index 144c26e..768de14 100644 --- a/gsselect/parangle.py +++ b/gsselect/parangle.py @@ -5,6 +5,7 @@ from astropy.time import Time import astropy.units as u + def parangle(ra, dec, utdate, uttime, site, verbose=False): """ Compute the parallactic angle of a position at a given date-time. @@ -54,17 +55,3 @@ def parangle(ra, dec, utdate, uttime, site, verbose=False): np.cos(coord.dec) * np.tan(location.lat) - np.sin(coord.dec) * np.cos(ha)) return parang - -if __name__ == "__main__": - - target = 'TNO12345 url' # new target name - ra = '12:22:22.860' # RA (J2000) - dec = ' 4:31:03.23' # Dec (J2000) - smags = '22.4/r/AB' - utdate = '2018-03-15' - uttime = '05:35:00' # parang = 0, el=55 - # uttime = '03:24:00' # parang = -140, el = 43.2 - pa = 310. - - parang = parangle(ra,dec,utdate,uttime,'Gemini South',verbose=True) - print('parang = ', parang) \ No newline at end of file diff --git a/setup.py b/setup.py index 805bd19..0cfd7a3 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name='gsselect', - version='1.1.1', + version='1.1.2', author="Bryan Miller", author_email="millerwbryan@gmail.com", description="Gemini guide star selection and URL TOO triggering", diff --git a/urltoo_readme.txt b/urltoo_readme.txt index 7497724..9bae11a 100644 --- a/urltoo_readme.txt +++ b/urltoo_readme.txt @@ -1,22 +1,30 @@ Gemini URL-based Submission of ToO Triggers Bryan Miller and Shane Walker -2019feb13 +2019sep12 Gemini has implemented a web-based service for receiving -target-of-opportunity triggers. This aleviates the need for PIs to -fetch and then store their programs to submit a trigger and allows the +target-of-opportunity (ToO) observation triggers. This alleviates the need for teams to +fetch and then store their programs manually to submit a trigger and allows the triggering process to be better automated, thus improving the overall -response time. +response time. The Gemini ToO process is described at -The details of the trigger are formatted as an URL string which can be -submitted to Gemini using any browser or URL tool such as wget. The -following parameters are available. +https://www.gemini.edu/node/11005 + +The team must have have an approved ToO program on Gemini and define ToO template observations, +complete observations without defined targets, during the Phase 2 process. Authentication +is done via a "User key" tied to an email address. See the following page for help on getting +a user key and the password needed for the trigger request. + +https://www.gemini.edu/node/12109 + +The details of the trigger are formatted as a URL string which can be +submitted to Gemini using any browser or URL tool such as wget or the 'requests' +package in Python. The following parameters are available. prog - program id email - email address for user key -password - password for user key associated with email, site specific -obsnum - id of the template observation to clone and update, - must be 'On hold' +password - password for user key associated with email, site specific, emailed by the ODB +obsnum - id of the template observation to clone and update, must be 'On Hold' target - name of the target ra - target RA [J2000], format 'HH:MM:SS.SS' dec - target Dec[J2000], format 'DD:MM:SS.SSS' @@ -30,7 +38,7 @@ gsra - guide star RA [J2000] (optional, but must be set if any gs* parame gsdec - guide star Dec[J2000] (optional, but must be set if any gs* parameter given) gsmags - guide star magnitude (optional) gsprobe - PWFS1, PWFS2, OIWFS, or AOWFS (optional, but must be set if any gs* parameter given) -ready - if "true" set the status to "Prepared/Ready" (defaults to true) +ready - if "true" set the status to "Prepared/Ready", otherwise remains at "On Hold" (default "true") windowDate - interpreted in UTC in the format 'YYYY-MM-DD' windowTime - interpreted in UTC in the format 'HH:MM' windowDuration - integer hours @@ -44,8 +52,8 @@ information. That way the template observation can be reused in the future. The target name, ra, and dec are straightforward. The note text is added to a new note, the identified purpose of which is to contain a link to a finding chart. The "ready" parameter is used to -determine whether to mark the observation as Prepared (Ready) or not -(and thereby generate the TOO trigger). +determine whether to mark the observation as "Prepared" (and thereby generate +the TOO trigger) or keep it "On Hold". The exposure time parameter, if given, only sets the exposure time in the instrument "static component", which is tied to the first sequence step. diff --git a/urltrigger.py b/urltrigger.py index 38a7646..7640ac8 100644 --- a/urltrigger.py +++ b/urltrigger.py @@ -5,6 +5,7 @@ # Bryan Miller # 2018-01-30 created # 2019-02-13 added exptime parameter +# 2019-09-12 improve code style from __future__ import print_function import requests @@ -43,7 +44,7 @@ # server = 'https://gnodbtest.hi.gemini.edu:8443' # Observation selection - obsid=1 # obsid of On-hold observation to copy + obsid = 1 # obsid of On-Hold observation to copy # Target parameters obsnum = str(obsid).strip() # obsid to clone, string @@ -53,21 +54,21 @@ smags = '22.4/r/AB' # Target brightness l_pa = 180. l_pamode = 'parallactic' # Options: fixed, flip, find, parallactic - l_exptime = 0 # exposure time [seconds], if 0 then the value in the template observation is used + l_exptime = 0 # exposure time [seconds], if 0 then use the value in the template # l_wDate = '' - l_wDate='2018-03-15' # UTC date YYYY-MM-DD for timing window - l_wTime='01:00' # UTC time HH:MM for timing window - l_wDur=48 # Timing window duration, integer hours + l_wDate = '2018-03-15' # UTC date YYYY-MM-DD for timing window + l_wTime = '01:00' # UTC time HH:MM for timing window + l_wDur = 48 # Timing window duration, integer hours l_obsdate = l_wDate # UT date for parallactic angle calculation # l_obsime = '05:35:00' # UT time for parallactic angle calculation, gives parang = 0, el=55 l_obstime = '03:24:00' # UT time for parallactic angle calculation, gives parang = -140, el = 43.2 - l_site = 'Gemini South' # Site, 'Gemini South' or 'Gemini North' - l_eltype='airmass' # Elevation constraint, "none", "hourAngle", or "airmass" - l_elmin=1.0 # minimum value for hourAngle/airmass - l_elmax=1.6 # maximum value for hourAngle/airmas + l_site = 'Gemini South' # Site, 'Gemini South' or 'Gemini North' + l_eltype = 'airmass' # Elevation constraint, "none", "hourAngle", or "airmass" + l_elmin = 1.0 # minimum value for hourAngle/airmass + l_elmax = 1.6 # maximum value for hourAngle/airmas - note = 'This is a test note. URL triggered.' + eol + 'Add URL to finder chart here.' # Text for note, optional - group = 'New LIGO event' # optional, created if does not exist, case-sensitive match + note = 'This is a test note. URL triggered.' + eol + 'Add URL to finder chart here.' # Text for note, optional + group = 'New LIGO event' # optional, created if does not exist, case-sensitive match # Guidestar parameters # If gstarget is missing but other gs* parameters are present, then it defaults to "GS". @@ -75,19 +76,19 @@ # gsra='12:22:30.212' # Guide star RA (J2000) # gsdec='04:29:35.59' # Guide star Dec (J2000) # gsmag = 11.83 # Guide star mag - gstarg='' # Guide star target + gstarg = '' # Guide star target gsra = '' # Guide star RA (J2000) - gsdec='' # Guide star Dec (J2000) + gsdec = '' # Guide star Dec (J2000) gsmag = 0.0 # Guide star mag - gsprobe='OIWFS' # Guide star probe (PWFS1/PWFS2/OIWFS/AOWFS) - #gsprobe='PWFS2' # Guide star probe (PWFS1/PWFS2/OIWFS/AOWFS) - l_inst='GMOS' # Instrument: 'GMOS', 'F2', 'GNIRS','NIFS','NIRIF/6','NIRIF/14','NIRIF/32' - l_port='side' # ISS port, options: 'side', 'up', use 'side' for GMOS/F2 + gsprobe = 'OIWFS' # Guide star probe (PWFS1/PWFS2/OIWFS/AOWFS) + # gsprobe = 'PWFS2' # Guide star probe (PWFS1/PWFS2/OIWFS/AOWFS) + l_inst = 'GMOS' # Instrument: 'GMOS', 'F2', 'GNIRS','NIFS','NIRIF/6','NIRIF/14','NIRIF/32' + l_port = 'side' # ISS port, options: 'side', 'up', use 'side' for GMOS/F2 l_ifu = 'none' # IFU option: 'none', 'two', 'red', 'blue' l_overw = False # Overwrite image/catalog table, if False, will read existing files l_display = True # Display image of field and selected guide star l_chop = False # Chopping (no longer used, should be False) - l_pad = 5. # Padding applied to WFS FoV (to account for uncertainties in shape) [arcsec] + l_pad = 5. # Padding applied to WFS FoV (accounts for uncertainties in shape) [arcsec] l_rmin = -1. # Minimum radius for guide star search [arcmin], -1 to use default # Conditions l_iq = 'Any' # Image quality constraint ['20','70','85','Any'] @@ -102,13 +103,13 @@ # Parallactic angle? if l_pamode == 'parallactic': l_pa = parangle(ra, dec, l_obsdate, l_obstime, l_site).value - l_pamode = 'flip' # in case of guide star selection + l_pamode = 'flip' # in case of guide star selection # Guide star selection gstarg, gsra, gsdec, gsmag, gspa = gsselect(target, ra, dec, pa=l_pa, imdir='./', site=l_site, pad=l_pad, - inst=l_inst, ifu=l_ifu, wfs=gsprobe, chopping=l_chop, cat='UCAC4', pamode=l_pamode, - iq=l_iq, cc=l_cc, sb=l_sb, - overwrite=l_overw, display=l_display, verbose=False) + inst=l_inst, ifu=l_ifu, wfs=gsprobe, chopping=l_chop, cat='UCAC4', + pamode=l_pamode, iq=l_iq, cc=l_cc, sb=l_sb, overwrite=l_overw, + display=l_display, verbose=False) print(gstarg, gsra, gsdec, gsmag, gspa) # form URL command @@ -166,5 +167,3 @@ except requests.exceptions.HTTPError as exc: print('Request failed: {}'.format(response.content)) raise exc - -