if star['name'] not in obsinfo:
        print 'No phase range and exposure time specified for', star['name']
        exit(1)

# Loop through the targets in RA order
keys = peinfo.keys()
keys.sort()

for key in keys:
    star = peinfo[key]
    obs = obsinfo[star['name']]

    # Interpret dates
    start_year, start_month, start_day = obs['start'].split('-')
    end_year, end_month, end_day = obs['end'].split('-')
    mjd_start = sla.cldj(int(start_year), int(start_month), int(start_day))
    mjd_end = sla.cldj(int(end_year), int(end_month), int(end_day))
    if mjd_end <= mjd_start:
        print 'ERROR: end date should be after start date'
        exit(1)

    # middle used to estimate systematic uncert
    mjd_mid = (mjd_start + mjd_end) / 2.

    # Compute light travel time stuff at start, middle and end of date interval
    tt,tdb,btdb_start,hutc_start,htdb,vhel,vbar = \
        sla.utc2tdb(mjd_start,longit,latit,height,star['ra'],star['dec'])

    tt,tdb,btdb_mid,hutc_mid,htdb,vhel,vbar = \
        sla.utc2tdb(mjd_mid,longit,latit,height,star['ra'],star['dec'])
Example #2
0
else:
    print 'No target prefixes loaded.'

# Compute maximum length of the names
if len(prefixes):
    mpre = max([len(n) for n in prefixes.values()]) + 1
else:
    mpre = 0

left = max([len(n) for n in peinfo.keys()]) + mpre

# Compute maximum length of the names

# Rather primitive times to define sun down and up; won't work
# properly in far north or south or around the dateline
mjd_day1  = sla.cldj(year, month, day) - longit/360. + 0.5
mjd_night = mjd_day1 + 0.5
mjd_day2  = mjd_day1 + 1.0

sunset  = sla.sun_at_elev(longit, latit, height, mjd_day1, mjd_night, -0.25)
sunrise = sla.sun_at_elev(longit, latit, height, mjd_night, mjd_day2, -0.25)

twiset  = sla.sun_at_elev(longit, latit, height, mjd_day1, mjd_night,
                          args.twilight)
twirise = sla.sun_at_elev(longit, latit, height, mjd_night, mjd_day2,
                          args.twilight)

# really stop at these points
rset  = sla.sun_at_elev(longit, latit, height, mjd_day1, mjd_night, -10.)
rrise = sla.sun_at_elev(longit, latit, height, mjd_night, mjd_day2, -10.)
Example #3
0
def make_eso_chart(fname, cname, target, info, pid, pi, pos, field, scale,
                   stype='sec', source=None, angle=None, mark=True, s1=0.04,
                   s2=0.1, plo=50.0, phi=99.8, sloc=-0.43, pwidth=6,
                   fsize=12, aspect=0.6, pm=None, obsdate=None, 
                   lhead=0.02):
    """Make a chart suitable for VLT. Arguments::

    fname   : (string)
            fits file from DSS, e.g. 'PG1018-047.fits'

    cname   : (string)
            chart name (e.g. "name.pdf". The type of file is deduced 
            from the suffix. Either .pdf or .jpg are recognised)

    target  : (string)
            target name, e.g. 'PG1018-047'

    info    : (string or list of strings)
            extra information, e.g. 'Slit angle: parallactic'. 
            A list of strings will be printed line by line

    pid     : (string)
            programme ID, e.g. '088.D-0041(A)'

    pi      : (string)
            PI name, e.g. 'Marsh'

    pos     : (string)
            position, e.g. '10 21 10.6 -04 56 19.6' (assumed 2000)

    field   : (float)
            field width to display, arcmin, e.g. 1.0

    scale   : (float)
            size of scale to indicate in arcsec, e.g. 30

    stype   : (string)
            'sec' or 'min' to indicate how to mark the scale

    source  : (string)
            source of fits file, e.g. 'DSS blue'. Ignore for automatic version.

    angle   : (float)
            indicator / slit angle to display, degrees. None to ignore.

    mark    : (bool)
            True to indicate object

    s1      : (float)
            fraction of field for start of slit and object markers
            (displaced from object)

    s2      : (float)
            fraction of field for end of slit and object markers
            (displaced from object)

    plo     : (float)
            Low image display level, percentile

    phi     : (float)
            High image display level, percentile

    sloc    : (float) 
            vertical location of scale bar in terms of 'field'

    pwidth  : (float)
            (approx) plot width in inches

    fsize   : (int)
            fontsize, pt

    aspect  : (float)
            aspect (vertical/horizontal) [should be < 1]

    pm      : (tuple)
            proper motion in RA, and dec, arcsec/year in both
            coords. This is used to correct the predicted position of the
            target in the image by finding the date on which the image was
            taken.

    obsdate : (string)
            if you set pm, then if you also set date, an arrow
            arrow will be drawn from target to its expected position at
            obsdate and the chart will be centred on the head of the
            arrow. obsdate should be in YYYY-MM-DD format. 

    lhead   : (float)
            length of arrow head as fraction of field. If this turns out
            to be longer than the entire arrow, no arrow is drawn.

    Returns (ilo,ihi) display levels used
    """

    # ra, dec in degrees
    ra,dec,sys = subs.str2radec(pos)
    ra *= 15

    # Read data
    hdulist   = fits.open(fname)
    data      = hdulist[0].data
    head      = hdulist[0].header
    hdulist.close()

    arrow = False
    if pm:
        # try to correct position to supplied date or
        # date of chart

        if 'DATE-OBS' in head:
            dobs    = head['DATE-OBS']
            year    = int(dobs[:4])
            month   = int(dobs[5:7])
            day     = int(dobs[8:10])
            deltat  = (sla.cldj(year,month,day) - sla.cldj(2000,1,1))/365.25
            dra     = pm[0]*deltat/np.cos(np.radians(dec))/3600.
            ddec    = pm[1]*deltat/3600.
            ra  += dra
            dec += ddec
            if obsdate:
                yearp,monthp,dayp = obsdate.split('-')
                deltat  = (sla.cldj(int(yearp),int(monthp),int(dayp)) - \
                               sla.cldj(year,month,day))/365.25
                dra     = pm[0]*deltat/np.cos(np.radians(dec))/3600.
                ddec    = pm[1]*deltat/3600.
                ra += dra
                dec += ddec
                arrow   = True
        else:
            print 'WARNING: Could not find DATE-OBS in header'

    # Read WCS info
    wcs = astWCS.WCS(fname)
    dx  = 60.*wcs.getXPixelSizeDeg()
    dy  = 60.*wcs.getYPixelSizeDeg()
    rot = wcs.getRotationDeg()
    if rot > 180.:
        rot -= 360.
    if not wcs.coordsAreInImage(ra,dec):
        print 'WARNING: coordinates not inside image'

    # pixel position corresponding to desired ra and dec
    x,y = wcs.wcs2pix(ra, dec)
    if arrow:
        if not wcs.coordsAreInImage(ra-dra,dec-ddec):
            print 'WARNING: End of proper motion arrow is not inside image'
        xa,ya = wcs.wcs2pix(ra-dra, dec-ddec)

    ny, nx = data.shape

    # plot limits
    limits = (dx*(-0.5-x),dx*(nx-0.5-x),dy*(-0.5-y),dy*(ny-0.5-y))

    if source is None:
        if 'SURVEY' in head:
            source = head['SURVEY']
            if source == 'POSSII-F':
                source = 'POSS-II red'
            elif source == 'POSSII-J':
                source = 'POSS-II blue'
            elif source == 'POSSII-N':
                source = 'POSS-II ir'
            elif source == 'POSSI-E':
                source = 'POSS-I red'
            elif source == 'POSSI-O':
                source = 'POSS-I blue'
            elif source == 'SERC-I':
                source = 'SERC ir'
            elif source == 'SERC-J':
                source = 'SERC blue'
            elif source == 'AAO-SES':
                source = 'AAO red'
            elif source == 'AAO-GR':
                source = 'AAO red'
        else:
            source = 'UNKNOWN'

    # Start plotting
    fig  = plt.figure(figsize=(pwidth,pwidth))
    axes = fig.add_subplot(111,aspect='equal')
    mpl.rc('font', size=fsize)

    # Derive the plot range
    ilo  = stats.scoreatpercentile(data.flat, plo)
    ihi  = stats.scoreatpercentile(data.flat, phi)

    # Plot
    plt.imshow(data, vmin=ilo, vmax=ihi, cmap=cm.binary, extent=limits,
               interpolation='nearest', origin='lower')
    axes.autoscale(False)

    # draw slit angle
    if angle is not None:
        ca = m.cos(m.radians(angle+rot))
        sa = m.sin(m.radians(angle+rot))
        t1 = s1*field
        t2 = s2*field
        plt.plot([-sa*t1,-sa*t2],[+ca*t1,+ca*t2],BLUE,lw=3)
        plt.plot([+sa*t1,+sa*t2],[-ca*t1,-ca*t2],BLUE,lw=3)

    # Mark object
    if mark:
        t1 = s1*field
        t2 = s2*field
        plt.plot([t1,t2],[0,0],RED,lw=3)
        plt.plot([0,0],[t1,t2],RED,lw=3)

    # draw arrow
    if arrow:
        # Slightly complicated because matplotlib
        # arrow stupidly starts drawing the head of the
        # arrow at the end point so we need to shrink the
        # arrow. If it becomes negative, don't draw at all,
        # just issue a warning
        delx, dely = dx*(x-xa), dy*(y-ya)
        length = m.sqrt(delx**2+dely**2)
        hl = field*lhead
        lnew = length-hl
        if lnew > 0:
            shrink = lnew/length
            plt.arrow(-delx, -dely, shrink*delx, shrink*dely,
                       head_width=0.5*hl, head_length=hl)
        else:
            print 'WARNING: arrow head too long; arrow not drawn'

    # Draw scale bar
    if stype == 'sec' or stype == 'min':
        if stype == 'sec':
            plt.text(0, (sloc-0.05)*field, str(scale) + ' arcsec',
                     horizontalalignment='center',color=RED)
        elif stype == 'min':
            plt.text(0, (sloc-0.05)*field, str(scale/60) + ' arcmin',
                     horizontalalignment='center',color=RED)

        scale /= 60.
        plt.plot([-0.5*scale,+0.5*scale],[sloc*field,sloc*field],RED,lw=3)
        plt.plot([+0.5*scale,+0.5*scale],[(sloc+0.02)*field,(sloc-0.02)*field],
                 RED,lw=3)
        plt.plot([-0.5*scale,-0.5*scale],[(sloc+0.02)*field,(sloc-0.02)*field],
                 RED,lw=3)

    # North-East indicator. ev, nv = East / North vectors
    xc, yc = 0.4*field, -0.4*field
    rot   = m.radians(rot)
    rmat  = np.matrix(((m.cos(rot),-m.sin(rot)),(m.sin(rot),m.cos(rot))))

    nv = np.array((0.,0.2*field))
    nv = nv.reshape((2,1))
    nv = rmat*nv
    nv = np.array(nv).flatten()

    ev = np.array((-0.2*field,0.))
    ev = ev.reshape((2,1))
    ev = rmat*ev
    ev = np.array(ev).flatten()

    plt.plot([xc,xc+nv[0]],[yc,yc+nv[1]],RED,lw=3)
    plt.text(xc+1.1*nv[0], yc+1.1*nv[1], 'N', horizontalalignment='center',
             color=RED)
    plt.plot([xc,xc+ev[0]],[yc,yc+ev[1]],RED,lw=3)
    plt.text(xc+1.15*ev[0], yc+1.1*ev[1], 'E', verticalalignment='center',
             color=RED)

    # finally the textual info with a helper function
    def ptext(x, y, field, tstr):
        """
        Converts relative (0-1) x,y limits into data coords and plots
        a string.
        """
        xd = -field/2.+field*x
        yd = -field/2.+field*y
        plt.text(xd, yd, tstr, horizontalalignment='left',color=BLUE)

    xoff = 0.02
    dely = 0.035
    yoff = 0.96

    if pid != '':
        ptext(xoff, yoff, field, pid)
        yoff -= dely

    if pi != '':
        ptext(xoff, yoff, field, 'PI: ' + pi)
        yoff -= 1.5*dely

    if target != '':
        ptext(xoff, yoff, field, 'Target: ' + target)
        yoff -= 1.5*dely

    rah,ram,ras,decd,decm,decs = pos.split()
    ptext(xoff, yoff, field, 'RA (2000) : ' + rah + ' ' + ram + ' ' + ras)

    yoff -= dely
    ptext(xoff, yoff, field, 'Dec (2000): ' + decd + ' ' + decm + ' ' + decs)

    yoff -= 1.5*dely
    ptext(xoff, yoff, field, "Field: " + str(field) + "' x " + str(field) + "'")

    if 'DATE-OBS' in head:
        yoff -= dely
        ptext(xoff, yoff, field, 'Date: ' + head['DATE-OBS'][:10])

    if source != '':
        yoff -= dely
        ptext(xoff, yoff, field, 'Survey: ' + source)

    yoff -= 2.*dely
    if info is not None:
        if isinstance(info, list):
            for line in info:
                ptext(xoff, yoff, field, line)
                yoff -= dely
        else:
            ptext(xoff, yoff,  field, info)

    plt.xlim(-field/2.,field/2.)
    plt.ylim(-field/2.,field/2.)
    plt.savefig(cname,bbox_inches='tight')
    return (ilo,ihi)
Example #4
0
                elif abs(eq - 2000) > 0.001:
                    ra  = -1.
                    dec = -100.
                    print 'ERROR: unrecognised equinox ' + str(eq) + ' file = ' + mfile + ' nspec = ' + str(nspec)
                    nnopos  += 1
                    nbadeq  += 1
            else:
                ra   = -1.
                dec  = -100.
                nnopos += 1

            # Time
            if 'RJD' in mspec:
                mjd = mspec['RJD'] -2400000.5
            elif 'Day' in mspec and 'Month' in mspec and 'Year' in mspec and 'UTC' in mspec:
                mjd = sla.cldj(mspec['Year'],mspec['Month'],mspec['Day']) + mspec['UTC']/24.
                ntcalc += 1
            else:
                mjd = 0.
                nnojd += 1

            # Dwell
            if 'Dwell' in mspec:
                dwell = mspec['Dwell']
            else:
                dwell = -1.
                nnoexp += 1

            # Record number
            if 'Record' in mspec:
                nrec = mspec['Record']
Example #5
0
else:
    (ra,dec,system) = subs.str2radec(target)

dist  = options.dist
wave  = options.wave

import trm.sla as sla

dre = re.compile('(\d\d\d\d)-(\d\d)-(\d\d)$')
 
m = re.match(dre, options.start) 
if m:
    year  = int(m.group(1))
    month = int(m.group(2))
    day   = int(m.group(3))
    start_mjd = sla.cldj(year, month, day)
else:
    print 'Could not understand the start date:',options.start
    exit(1)

m = re.match(dre, options.end) 
if m:
    year  = int(m.group(1))
    month = int(m.group(2))
    day   = int(m.group(3))
    end_mjd = sla.cldj(year, month, day)
else:
    print 'Could not understand the end date:',options.end
    exit(1)

if start_mjd >= end_mjd: