Esempio n. 1
0
def spitztiming(jdstart, jdend):
    """
NAME:
      SPITZTIMING

PURPOSE:
      This function prints a list, in Spitzer AOR format, of timing
      constraints.  Also returns the output as a string.  Originally
      adapted from Dr. Joe Harrington's IDL routine, spitztiming.pro.

INPUTS:
      jdstart: Julian date of the start of the timing window (may be array).
      jdend:   Julian date of the end of the timing window (may be array).

OUTPUTS:
      This function returns a list of strings. Each cell of the list represents
      a separate constraint.

SIDE EFFECTS:
      None.

RESTRICTIONS:
     Numpy must be imported.
     Caldat must be imported.
     Jdstart and Jdend must both be arrays of the same shape.  Each element of
     of jdstart must be less than the corresponding element of jdend.

EXAMPLE/TEST:
     import numpy
     from julday import *
     from spitztiming import *
     print spitztiming(julday(10, 10, 2005, 2, 34, 56),
                       julday(12, 12, 2006, 3, 45, 34)

MODIFICATION HISTORY:
2008-12-29 0.1  Christopher Campo, UCF     Initial version.
                [email protected]

2009-01-06 0.2  Christopher Campo, UCF     Added support for arrays
                [email protected]

2009-01-06 0.3  Christopher Campo, UCF     Added support for scalars
                [email protected]
    """
    
    # default assumes input is a scalar
    scalar = True

    # check if input is an array
    if type(jdstart) == np.ndarray and type(jdend) == np.ndarray:
        scalar = False
        # check shape of arrays
        if(jdstart.shape != jdend.shape):
            raise TypeError, 'Error: arrays jdstart and jdend must have the same shape'
    else:
        try:
            # simple arithmetic test; lists and tupples do not
            # support this action however, and will throw an
            # exception.
            test = jdend * jdstart
        except:
            raise IOError, 'Error: input must be either scalars or arrays'
  
    dif = jdend - jdstart

    if scalar == False:
        # make sure each end date is after the start date
        difar = dif < 0
        if(difar.all() == True):
            raise TypeError, 'Error: each end time must be later than corresponding start time'
    elif dif < 0:
        raise TypeError, 'Error: each end time must be later than corresponding start time'

    if scalar == False:
        # number of timing constraints to be generated
        ntime = jdstart.size
    else:
        ntime = 1

    # the list of strings (constraints) to be returned
    tlist = []
  
    # converts julian to gregorian
    sdate = caldat.caldat(jdstart, verbose=True)
    edate = caldat.caldat(jdend, verbose=True)

    # append the list with each timing constraint;
    # loops through the entire range of timing constraints.
    for i in range(ntime):
        if scalar == True:
            hr  = np.array([sdate[3], edate[3]])
            min = np.array([sdate[4], edate[4]])
            sec = np.array([sdate[5], edate[5]])
        else:
            hr  = np.array([sdate[i][3], edate[i][3]])
            min = np.array([sdate[i][4], edate[i][4]])
            sec = np.array([sdate[i][5], edate[i][5]])

        # FINDME: 7/20/2010 remove 60 seconds bug
        if np.round(sec[0]) == 60:
            min[0] += 1
            sec[0]  = 0
        if np.round(sec[1]) == 60:
            min[1] += 1
            sec[1]  = 0

        # FINDME: 7/28/2011 remove 60 minute bug
        if np.round(min[0]) == 60:
            hr[0] += 1
            min[0] = 0
        if np.round(min[1]) == 60:
            hr[1] += 1
            min[1] = 0

        # get start and end times
        stvals = (hr[0], min[0], sec[0])
        etvals = (hr[1], min[1], sec[1])
        stime  = '%02d:%02d:%02.0f' % (stvals) 
        etime  = '%02d:%02d:%02.0f' % (etvals)
        
        if scalar == False:
            str_var = (i+1, sdate[i][2], sdate[i][0], sdate[i][1], stime, \
                         edate[i][2], edate[i][0], edate[i][1], etime)
        else:
            str_var = (i+1, sdate[2], sdate[0], sdate[1], stime, edate[2],\
                         edate[0], edate[1], etime)
      
        tstr = 'TIMING%d:  START_DATE=%d %s %2d, START_TIME=%8s, END_DATE=%d %s %2d, END_TIME=%s' % str_var
        tlist.append(tstr)
      
    # the list of strings (timing constraints)
    return tlist
Esempio n. 2
0
def spitztimingrep(planet, event, evphase, obsdur, startwin, obswin,\
                       teph, period, toff=0, ctrshift=0,\
                       type='ingress', errphase=0, ecldur=None):
    """
NAME:
      spitztimingrep

PURPOSE:
      This function calculates when planetary transit and eclipse
      events occur within a set of observing windows.  It also
      prints the corresponding Spitzer timing constraints in AOR
      format.  It returns the timing constraint string list. It can
      also return the event mid-times with their error estimates.

INPUTS:
      planet:   String name of the planet

      event:    String name of the event
      
      evphase:  Float, in range [0,1), giving phase of event to
                be reported.
      
      obsdur:   Duration (in seconds) of observations

      startwin: Duration (in seconds) of observation start-time
                window.

      obswin:   [2,nwin] array of Julian dates for the start and end
                of each observing window.  Only events within these 
                pairs of times will be returned.

      teph:     Passed to routine circorbphase; see that routine's header.

      period:   Passed to routine circorbphase; see that routine's header.

      toff:     Optional parameter; Passed to routine circorbphase; see 
                that routine's header.

      ctrshift: Shift (in seconds) of event center relative to observation
                center.  Positive shift puts more time before the event.

      type:     Optional; the type of constraints you want returned
                (ingress / egress) or the mid-times (midtimes). All
                other inputs will return the ingress timing constraints
                by default.

OUTPUTS:
      This function returns the spitzer timing constraint string
      for ingress or egress OR the event mid-times with error estimates.

RESTRICTIONS:
      Numpy must be installed, and the routines circorbphase, spitztiming,
      and caldat must be in Python's search path.

SIDE EFFECTS:
      None.

EXAMPLE/TEST:

import spitztimingrep as sptr
import julday as jd
import numpy as np

teph = np.array([24445678.0, 0.04])
period = np.array([2.18575, 0.000003])
planet = 'mars'
obswin = np.array([[jd.julday(11, 12, 2005, 15, 34, 0),\
                        jd.julday(12, 27, 2005, 8, 14, 0)]])
obsdur = 6 * 3600.
startwin = 60. * 60.
evphase = .5
event = 'secl'
sptr.spitztimingrep(planet, event, evphase, obsdur, startwin, obswin, \
                    teph, period)


NOTES:
      This routine is adopted from Dr. Joseph Harrington's original IDL
      routine, spitztimingrep.pro.

MODIFICATION HISTORY:
     2009-01-07   0.1    Christopher Campo, UCF    Initial version
                         [email protected]

     2009-01-11   0.2    Christopher Campo, UCF    Added mid-times
                         [email protected]
    """
    import numpy as np
    import circorbphase as cop
    import spitztiming as st
    import caldat as cal

    if ecldur == None:
        ecldur = obsdur - 3600.
        
    ictrshift = 0

    if ctrshift != 0:
        ictrshift = ctrshift

    s2d = 1. / 86400. # conversion factor for seconds to days
  
    for i in range(len(obswin)):
        if i == 0:
            ecl = cop.circorbphase(teph, period, obswin[i][0], obswin[i][1], \
                                       toff, evphase, errphase=errphase)
        else:
            ecl = np.concatenate((ecl, cop.circorbphase(teph, \
                                                            period, obswin[i][0], \
                                                            obswin[i][1], toff, \
                                                            evphase, errphase=errphase)), axis=1)

    # event mid-times with errors
    dates = np.array(cal.caldat(ecl[0][:]), dtype=np.float64)
    dates = np.transpose(dates)
    mon   = dates[0]
    day   = dates[1]
    year  = dates[2]
    hour  = dates[3]
    min   = dates[4]
    sec   = dates[5]

    uncert = ecl[1][:] * 24. * 60. * 60.
    mid    = np.transpose([year, mon, day, hour, min, sec, \
                            uncert])
    
    midtimes = 'Times of %s %s, solar-system barycenter:\n'  % (planet, event)
    
    # format the string of event midtimes and errors
    for i in range(len(mid)):
        midtimes += '%4.0f   %2.0f   %2.0f   %4.0f   %2.0f   %6.3f  +- %10.3f sec\n' % \
            (mid[i][0], mid[i][1], mid[i][2], mid[i][3], mid[i][4], mid[i][5],\
                 mid[i][6])
            
    # constraints for ingress
    dt      = np.max((ecldur/2., 2*3600.)) # ecl offset FINDME
    jdstart = ecl[0][:] - (dt + ictrshift + ecldur/2. + startwin / 2.) * s2d  # start evnt before baseline 
    jdend   = jdstart + startwin * s2d
    iconst  = st.spitztiming(jdstart, jdend)

    # constraints for egress
    jdstart = ecl[0][:] - (ictrshift + startwin / 2.) * s2d
    jdend   = jdstart + startwin * s2d
    econst  = st.spitztiming(jdstart, jdend)

    if type == 'midtimes':
        return midtimes
    elif type == 'egress':
        return econst
    elif type == 'ingress':
        return iconst