Пример #1
0
def lunarDistance(fld, startTime, endTime):
    """Calculate the distance to the moon at starttime and end time."""
    # Position of the target cast into pyeEphem Angle
    tarRa = pyEphem.hours(fld['ra'].values[0])
    tarDec = pyEphem.degrees(fld['dec'].values[0])

    # Moon Position
    moonRa1, moonDec1 = MMTEphem.moonPosition(startTime)
    moonRa2, moonDec2 = MMTEphem.moonPosition(endTime)

    dist1 = angSep(moonRa1, moonDec1, tarRa, tarDec)
    dist2 = angSep(moonRa2, moonDec2, tarRa, tarDec)

    return (dist1 + dist2) / 2.0
Пример #2
0
def lunarDistance(fld, startTime, endTime):
    """Calculate the distance to the moon at starttime and end time."""
    # Position of the target cast into pyeEphem Angle
    tarRa = pyEphem.hours(fld['ra'].values[0])
    tarDec = pyEphem.degrees(fld['dec'].values[0])

    # Moon Position
    moonRa1, moonDec1 = MMTEphem.moonPosition(startTime)
    moonRa2, moonDec2 = MMTEphem.moonPosition(endTime)

    dist1 = angSep(moonRa1, moonDec1, tarRa, tarDec)
    dist2 = angSep(moonRa2, moonDec2, tarRa, tarDec)

    return (dist1+dist2)/2.0
Пример #3
0
def obsOneNight(fldPar, donePar, date):
    """Fully Schedules one night."""
    # Get the ephemeris for the night
    mmt = MMTEphem.ephem(date)
    startTime = mmt.eveningTwilight

    # Now, start at twilight and add observervations. Each
    # time increment currentTime by the observation time
    # If no observations are found, add 5 minutes and check again
    currentTime = startTime
    schedule = []  # Will contain scheduled fields
    allDone = False
    prevPos = None
    while (currentTime < mmt.morningTwilight) & (allDone is False):
        newSched, prevPos = obsUpdateRow(fldPar, donePar,
                                        currentTime, mmt, prevPos)
        # Check to see if something was observed
        if newSched is None:
            # Increment time and continue
            currentTime += datetime.timedelta(minutes=20)
        else:
            # Append new entry to schedule, increment currentTime
            # by exposure time.
            schedule.append(newSched)
            currentTime += datetime.timedelta(seconds=newSched[1])
            completed = donePar['complete'].values
            if min(completed) == 1:
                allDone = True

    return schedule
Пример #4
0
def readAllocatedTime(startDay="1900/1/1", endDay="3000/1/1"):
    """Read a log file to determine how much each PI was allocated."""
    filename = "AllocatedTime.dat"
    f = open(filename, 'r')

    if type(startDay) == str:
        startDay = pyEphem.date(startDay).datetime()
    if type(endDay) == str:
        endDay = pyEphem.date(endDay).datetime()

    allocatedTime = {}
    for line in f.readlines():
        if line[0] == '#':
            # Comment string, skip
            continue

        date, PI = line.strip().split()
        date = pyEphem.date(date).datetime()
        mmt = MMTEphem.ephem(date)
        if (abs((date-startDay).total_seconds()) < 24*3600.) | \
           (abs((date-endDay).total_seconds()) < 24*3600.):
            # This night is not in the current run
            continue

        nightLength = (mmt.morningTwilight - mmt.eveningTwilight)
        nightLength = nightLength.total_seconds() / 3600.0

        if PI in allocatedTime:
            allocatedTime[PI] += nightLength
        else:
            allocatedTime[PI] = nightLength

    return allocatedTime
Пример #5
0
def obsOneNight(fldPar, donePar, date):
    """Fully Schedules one night."""
    # Get the ephemeris for the night
    mmt = MMTEphem.ephem(date)
    startTime = mmt.eveningTwilight

    # Now, start at twilight and add observervations. Each
    # time increment currentTime by the observation time
    # If no observations are found, add 5 minutes and check again
    currentTime = startTime
    schedule = []  # Will contain scheduled fields
    allDone = False
    prevPos = None
    while (currentTime < mmt.morningTwilight) & (allDone is False):
        newSched, prevPos = obsUpdateRow(fldPar, donePar, currentTime, mmt,
                                         prevPos)
        # Check to see if something was observed
        if newSched is None:
            # Increment time and continue
            currentTime += datetime.timedelta(minutes=20)
        else:
            # Append new entry to schedule, increment currentTime
            # by exposure time.
            schedule.append(newSched)
            currentTime += datetime.timedelta(seconds=newSched[1])
            completed = donePar['complete'].values
            if min(completed) == 1:
                allDone = True

    return schedule
Пример #6
0
def readAllocatedTime(startDay="1900/1/1", endDay="3000/1/1"):
    """Read a log file to determine how much each PI was allocated."""
    filename = "AllocatedTime.dat"
    f = open(filename, 'r')

    if type(startDay) == str:
        startDay = pyEphem.date(startDay).datetime()
    if type(endDay) == str:
        endDay = pyEphem.date(endDay).datetime()

    allocatedTime = {}
    for line in f.readlines():
        if line[0] == '#':
            # Comment string, skip
            continue

        date, PI = line.strip().split()
        date = pyEphem.date(date).datetime()
        mmt = MMTEphem.ephem(date)
        if (abs((date-startDay).total_seconds()) < 24*3600.) | \
           (abs((date-endDay).total_seconds()) < 24*3600.):
            # This night is not in the current run
            continue

        nightLength = (mmt.morningTwilight - mmt.eveningTwilight)
        nightLength = nightLength.total_seconds() / 3600.0

        if PI in allocatedTime:
            allocatedTime[PI] += nightLength
        else:
            allocatedTime[PI] = nightLength

    return allocatedTime
Пример #7
0
def calcMoonFlag(fld, startTime, endTime, mmt):
    """Calculate the IGNORE_FLAG based on lunar brightness and position.

    Inputs:
        fld -- field parameter entry from obsPars
        startTime -- datetime formatted starting time
        endTime -- datetime formatted ending time

    Output:
        flag -- 0/1 flag marking if the field is too close to the moon or
                the moon is brighter than specified.
    """
    moonUp = moonUpDuringObs(startTime, endTime, mmt)
    moonAge = MMTEphem.moonAge(startTime)

    # Get the distance to the moon
    moonDist = lunarDistance(fld, startTime, endTime)

    # Now do brightness flag
    moonReq = fld['moon'].values[0]
    if (moonReq == 'bright') | (moonUp == 0):
        # Anything works, either we were asked for bright
        # time or the moon isn't up during
        # the entirety of the observation
        illumFlag = 1
    elif (moonReq == 'grey') & (abs(moonAge) < 9) & (moonDist < 90):
        # We were asked for grey time and it's grey time
        illumFlag = 1
    elif (moonReq == 'dark') & (abs(moonAge) < 4.5) & (moonDist > 90.0):
        # We were asked for dark time and it's dark time
        illumFlag = 1
    else:
        illumFlag = 0   # This isn't going to work here!

    # Flag things that are just plain too close to the moon
    if moonDist < 10:
        illumFlag = 0

    return illumFlag
Пример #8
0
def calcMoonFlag(fld, startTime, endTime, mmt):
    """Calculate the IGNORE_FLAG based on lunar brightness and position.

    Inputs:
        fld -- field parameter entry from obsPars
        startTime -- datetime formatted starting time
        endTime -- datetime formatted ending time

    Output:
        flag -- 0/1 flag marking if the field is too close to the moon or
                the moon is brighter than specified.
    """
    moonUp = moonUpDuringObs(startTime, endTime, mmt)
    moonAge = MMTEphem.moonAge(startTime)

    # Get the distance to the moon
    moonDist = lunarDistance(fld, startTime, endTime)

    # Now do brightness flag
    moonReq = fld['moon'].values[0]
    if (moonReq == 'bright') | (moonUp == 0):
        # Anything works, either we were asked for bright
        # time or the moon isn't up during
        # the entirety of the observation
        illumFlag = 1
    elif (moonReq == 'grey') & (abs(moonAge) < 9) & (moonDist < 90):
        # We were asked for grey time and it's grey time
        illumFlag = 1
    elif (moonReq == 'dark') & (abs(moonAge) < 4.5) & (moonDist > 90.0):
        # We were asked for dark time and it's dark time
        illumFlag = 1
    else:
        illumFlag = 0  # This isn't going to work here!

    # Flag things that are just plain too close to the moon
    if moonDist < 10:
        illumFlag = 0

    return illumFlag
Пример #9
0
def obsUpdateRow(fldPar, donePar, startTime, mmt, prevPos=None):
    """Calculate observing weight for given observation.

    Input:
        fldpar : DataFrame for a single observation. Comes from
                 readAllFLDFiles (i.e. not a single dictionary)
        donepar : Dataframe with stats pertaining to a fields doneness
        starTime : datetime string for beginning time for observation

    """
    # The idea here is to loop through all of the fields and calculate
    # the weight for this startTime.
    weightList = []  # Will store array of dicts with weight info

    for objID in fldPar["objid"]:
        # Is this already observed?
        donefld = donePar[donePar['objid'] == objID]
        fld = fldPar[fldPar["objid"] == objID]

        if donefld['complete'].values[0] == 1:
            continue

        # Initialize the weight dictionary
        obsWeight = {}
        obsWeight['objid'] = objID

        objEphem = MMTEphem.ObjEphem(fld['ra'].values[0], fld['dec'].values[0],
                                     startTime, mmt)
        fitWeight, endTime, fitVisits = willItFitWeight(
            fld, startTime, mmt, objEphem, donefld)
        moonFlag = calcMoonFlag(fld, startTime, endTime, mmt)

        # Does this observation have one very close by
        dist_weight = 1
        if prevPos is not None:

            dist = angSep(
                hms2dec(fld['ra'].values[0]) * 15.0,
                hms2dec(fld['dec'].values[0]), prevPos[0], prevPos[1])
            if dist < 10. / 3600.:
                dist_weight = 1000

        obsWeight['fitWeight'] = fitWeight
        obsWeight['obsTime'] = (endTime - startTime).total_seconds()
        obsWeight['moonFlag'] = moonFlag
        obsWeight['nVisits'] = fitVisits
        obsWeight['ra'] = fld['ra'].values[0]
        obsWeight['dec'] = fld['dec'].values[0]

        # Priority Weight
        priorFlag = 1.0 / float(fld['priority'])**3

        # Now combine the weights
        weightTAC = 1.0 - 1.0 * donefld['doneTime'].values[0] \
            / donefld['totalTime'].values[0]
        if weightTAC < 0:
            weightTAC = 0.001
        totalWeight = fitWeight * moonFlag * \
            (weightTAC) *dist_weight*priorFlag
        # We need to account for a few extra things.
        # 1. I want fields that have had previously observed
        #    fields to be the top priority if they are observable.
        # This modification will weight fields with no observations
        # at one (1+0) and those partially observed at 10
        partCompWeight = int(donefld['doneVisit'].values[0] > 0)
        #totalWeight = totalWeight * (1+0.5*partCompWeight)

        # Now account for weighting from preivous iteration of the
        # code. This should smooth things out
        totalWeight = totalWeight / donefld['prevWeight'].values[0]
        obsWeight['totalWeight'] = totalWeight
        # Append to weight listing
        weightList.append(obsWeight)

    obsWeights = pd.DataFrame(weightList)

    # Doing the O(n) problem here
    hasMax = []

    # Check to see there are actually targets!
    if len(obsWeights) == 0:
        return None, None

    maxWeight = max(obsWeights['totalWeight'])
    for ii in range(len(obsWeights)):
        if obsWeights['totalWeight'].values[ii] == maxWeight:
            hasMax.append(ii)

    # Now, check there are some with non-zero weight and
    # Observe a random one
    if maxWeight == 0:
        # No targets were done.
        return None, None
    else:

        # This allows for random choice.
        randIndex = hasMax[randint(0, len(hasMax) - 1)]

        diffTime = obsWeights['obsTime'].values[randIndex]
        # Increment the schedule
        schedule = []
        schedule.append(startTime)
        schedule.append(diffTime)
        schedule.append(obsWeights['objid'].values[randIndex])
        schedule.append(obsWeights['nVisits'].values[randIndex])
        outPos = [
            hms2dec(obsWeights['ra'].values[randIndex]) * 15.0,
            hms2dec(obsWeights['dec'].values[randIndex])
        ]

        # Update the done masks
        index = [i for i, x in enumerate(donePar['objid'] == schedule[2]) if x]

        # Donetime tracks total time for this PI.  We weight by
        # this, so let's increment all entries in donefld

        PI = donePar.loc[index, 'PI'].values[0]
        for ii in range(len(fldPar)):
            if donePar["PI"].values[ii] == PI:
                donePar.loc[ii, 'doneTime'] += diffTime / 3600.
                donePar.loc[ii, 'currentWeight'] = \
                    donePar.loc[ii, 'doneTime'] / \
                    donePar.loc[ii, 'totalTime']

        donePar.loc[index, 'doneVisit'] += \
            obsWeights['nVisits'].values[randIndex]

        # Check to see if the target is now done
        requested = int(
            fldPar[fldPar['objid'] == schedule[2]]["repeats"].values[0])
        if int(donePar.loc[index, 'doneVisit']) >= requested:
            donePar.loc[index, 'complete'] = 1
        return schedule, outPos