Exemplo n.º 1
0
def test_observability_table():
    subaru = Observer.at_site("Subaru")
    time_ranges = [
        Time(["2001-02-03 04:05:06", "2001-02-04 04:05:06"]),  # 1 day
        Time(["2007-08-09 10:11:12", "2007-08-09 11:11:12"]),
    ]  # 1 hr
    targets = [vega, rigel, polaris]

    time_range = Time(["2001-02-03 04:05:06", "2001-02-04 04:05:06"])
    # note that this uses the AirmassConstraint in None min mode - that means
    # targets below the horizon will pass the airmass constraint
    constraints = [AtNightConstraint(), AirmassConstraint(3, None)]

    obstab = observability_table(constraints, subaru, targets, time_range=time_range)

    assert len(obstab) == 3
    assert np.all(obstab["target name"] == ["Vega", "Rigel", "Polaris"])

    assert "times" in obstab.meta
    assert "observer" in obstab.meta
    assert "constraints" in obstab.meta
    assert len(obstab.meta["constraints"]) == 2

    np.testing.assert_allclose(obstab["fraction of time observable"], np.array([21, 22, 15]) / 48)

    # now compare to is_observable and is_always_observable
    is_obs = is_observable(constraints, subaru, targets, time_range=time_range)
    np.testing.assert_allclose(obstab["ever observable"], is_obs)
    all_obs = is_always_observable(constraints, subaru, targets, time_range=time_range)
    np.testing.assert_allclose(obstab["always observable"], all_obs)
Exemplo n.º 2
0
def test_observability_table():
    subaru = Observer.at_site("Subaru")
    time_ranges = [Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06']),  # 1 day
                   Time(['2007-08-09 10:11:12', '2007-08-09 11:11:12'])]  # 1 hr
    targets = [vega, rigel, polaris]

    time_range = Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06'])
    # note that this uses the AirmassConstraint in None min mode - that means
    # targets below the horizon will pass the airmass constraint
    constraints = [AtNightConstraint(), AirmassConstraint(3, None)]

    obstab = observability_table(constraints, subaru, targets,
                                 time_range=time_range)

    assert len(obstab) == 3
    assert np.all(obstab['target name'] == ['Vega', 'Rigel', 'Polaris'])

    assert 'times' in obstab.meta
    assert 'observer' in obstab.meta
    assert 'constraints' in obstab.meta
    assert len(obstab.meta['constraints']) == 2

    np.testing.assert_allclose(obstab['fraction of time observable'],
                               np.array([21, 22, 15])/48)

    # now compare to is_observable and is_always_observable
    is_obs = is_observable(constraints, subaru, targets, time_range=time_range)
    np.testing.assert_allclose(obstab['ever observable'], is_obs)
    all_obs = is_always_observable(constraints, subaru, targets,
                                   time_range=time_range)
    np.testing.assert_allclose(obstab['always observable'], all_obs)
Exemplo n.º 3
0
def check_observability(alerts, constraints, observer, targets, earliestObs,
                        latestObs):
    """
    Check observability from observatory given the observational constraints.

    Parameters
    ----------
    alerts : pandas DataFrame
        table containing alerts
    constraints : list
        list of constraints
    observer : astroplan Observer object
        e.g. Calar Alto Observatory, Spain
    targets : list
        list containing astroplan targets
    earliestObs : Time object
        Earliest time of observation
    latestObs : Time object
        Latest time of observation

    Returns
    -------
    alerts : pandas DataFrame
        filtered alerts table containing observable targets
    """
    observabilityMask = is_observable(constraints, observer,
                                  targets, time_range=[earliestObs, latestObs])
    return alerts[observabilityMask]
Exemplo n.º 4
0
def test_docs_example():
    # Test the example in astroplan/docs/tutorials/constraints.rst
    target_table_string = """# name ra_degrees dec_degrees
    Polaris 37.95456067 89.26410897
    Vega 279.234734787 38.783688956
    Albireo 292.68033548 27.959680072
    Algol 47.042218553 40.955646675
    Rigel 78.634467067 -8.201638365
    Regulus 152.092962438 11.967208776"""

    from astroplan import Observer, FixedTarget
    from astropy.time import Time
    subaru = Observer.at_site("Subaru")
    time_range = Time(["2015-08-01 06:00", "2015-08-01 12:00"])

    # Read in the table of targets
    from astropy.io import ascii
    target_table = ascii.read(target_table_string)

    # Create astroplan.FixedTarget objects for each one in the table
    from astropy.coordinates import SkyCoord
    import astropy.units as u
    targets = [FixedTarget(coord=SkyCoord(ra=ra*u.deg, dec=dec*u.deg), name=name)
               for name, ra, dec in target_table]

    from astroplan import Constraint, is_observable

    class VegaSeparationConstraint(Constraint):
        """
        Constraint the separation from Vega
        """
        def __init__(self, min=None, max=None):
            """
            min : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            max : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            """
            self.min = min if min else 0*u.deg
            self.max = max if max else 180*u.deg

        def compute_constraint(self, times, observer, targets):
            vega = SkyCoord(ra=279.23473479*u.deg, dec=38.78368896*u.deg)

            # Calculate separation between target and vega
            # Targets are automatically converted to SkyCoord objects
            # by __call__ before compute_constraint is called.
            vega_separation = vega.separation(targets)

            # Return an array that is True where the target is observable and
            # False where it is not
            return (self.min < vega_separation) & (vega_separation < self.max)

    constraints = [VegaSeparationConstraint(min=5*u.deg, max=30*u.deg)]
    observability = is_observable(constraints, subaru, targets,
                                  time_range=time_range)

    assert all(observability == [False, False, True, False, False, False])
Exemplo n.º 5
0
    def get_next_observable_target(self, target_list, obs_time, max_time=-1,
                                   airmass=(1, 2.2),  moon_sep=(30, 180),
                                   block_type=''):
        """
        
        :return: 
        """

        # If the target_list is empty then all we can do is return back no
        # target and do a standard for the time being
        next_target = False

        if target_list.empty:
            return next_target, ""

        for row in target_list.itertuples():

            constraint = astroplan.AirmassConstraint(min=airmass[0],
                                                     max=airmass[1])

            if row.typedesig == 'f':
                if astroplan.is_observable(constraint, self.obs_site,
                                           row.FixedObject,
                                           times=[obs_time]):

                    return_dict = {'name': row.objname,
                                   'priority': row.priority}

                    return row.req_id, {**row.obs_dict, **return_dict}

        return False, False
Exemplo n.º 6
0
def test_observability_table():
    subaru = Observer.at_site("Subaru")
    time_ranges = [
        Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06']),  # 1 day
        Time(['2007-08-09 10:11:12', '2007-08-09 11:11:12'])
    ]  # 1 hr
    targets = [vega, rigel, polaris]

    time_range = Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06'])
    constraints = [AtNightConstraint(), AirmassConstraint(3)]

    obstab = observability_table(constraints,
                                 subaru,
                                 targets,
                                 time_range=time_range)

    assert len(obstab) == 3
    assert np.all(obstab['target name'] == ['Vega', 'Rigel', 'Polaris'])

    assert 'times' in obstab.meta
    assert 'observer' in obstab.meta
    assert 'constraints' in obstab.meta
    assert len(obstab.meta['constraints']) == 2

    np.testing.assert_allclose(obstab['fraction of time observable'],
                               np.array([21, 22, 15]) / 48)

    #now compare to is_observable and is_always_observable
    is_obs = is_observable(constraints, subaru, targets, time_range=time_range)
    np.testing.assert_allclose(obstab['ever observable'], is_obs)
    all_obs = is_always_observable(constraints,
                                   subaru,
                                   targets,
                                   time_range=time_range)
    np.testing.assert_allclose(obstab['always observable'], all_obs)
Exemplo n.º 7
0
def test_docs_example():
    # Test the example in astroplan/docs/tutorials/constraints.rst
    target_table_string = """# name ra_degrees dec_degrees
    Polaris 37.95456067 89.26410897
    Vega 279.234734787 38.783688956
    Albireo 292.68033548 27.959680072
    Algol 47.042218553 40.955646675
    Rigel 78.634467067 -8.201638365
    Regulus 152.092962438 11.967208776"""

    from astroplan import Observer, FixedTarget
    from astropy.time import Time
    subaru = Observer.at_site("Subaru")
    time_range = Time(["2015-08-01 06:00", "2015-08-01 12:00"])

    # Read in the table of targets
    from astropy.io import ascii
    target_table = ascii.read(target_table_string)

    # Create astroplan.FixedTarget objects for each one in the table
    from astropy.coordinates import SkyCoord
    import astropy.units as u
    targets = [FixedTarget(coord=SkyCoord(ra=ra*u.deg, dec=dec*u.deg), name=name)
               for name, ra, dec in target_table]

    from astroplan import Constraint, is_observable

    class VegaSeparationConstraint(Constraint):
        """
        Constraint the separation from Vega
        """
        def __init__(self, min=None, max=None):
            """
            min : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            max : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            """
            self.min = min if min else 0*u.deg
            self.max = max if max else 180*u.deg

        def compute_constraint(self, times, observer, targets):
            vega = SkyCoord(ra=279.23473479*u.deg, dec=38.78368896*u.deg)

            # Calculate separation between target and vega
            # Targets are automatically converted to SkyCoord objects
            # by __call__ before compute_constraint is called.
            vega_separation = vega.separation(targets)

            # Return an array that is True where the target is observable and
            # False where it is not
            return (self.min < vega_separation) & (vega_separation < self.max)

    constraints = [VegaSeparationConstraint(min=5*u.deg, max=30*u.deg)]
    observability = is_observable(constraints, subaru, targets,
                                  time_range=time_range)

    assert all(observability == [False, False, True, False, False, False])
Exemplo n.º 8
0
def filter_targets(obs, i, target_list, date_time, roof=2.5):
    """

    A function that filters a list of targets and returns a list with airmass
    less than < 2.5.

    TO IMPLEMENT:
        Move the testing to a different file or into a different function

    Args:
        obs: List of Observer objects that represent observatories
        target_list: List of FixedTarget objects that represent target coords
        date_time: The date and time range over which we check for
            observability
        roof: Float defining the maximum airmass we'll allow for our targets;
            will exclude targets with airmass larger than 2.5

    Returns:
        None

    """
    targets = format_targets(target_list)
    observers = format_observatories(obs)
    airmass_max = AirmassConstraint(roof)
    observability = is_observable(airmass_max, observers[i], targets,
                                  date_time)
    print(observability)
    print("Success!!")
Exemplo n.º 9
0
def compute_is_up(name, time):
    '''
    Computes what V<11 objects in a catalog are up right now.

    args:
        name (str): one in: ['messier', 'ngc']
        time (str): in 24hr format, e.g. "2017-04-17 21:00:00"

    returns:
        catalog with is_up calculated, sorted by v_mag.
    '''

    import datetime
    from astropy.time import Time
    from astroplan import FixedTarget
    from astropy.coordinates import SkyCoord
    from astroplan import Observer, FixedTarget, AltitudeConstraint, \
        AtNightConstraint, is_observable, is_always_observable, \
        months_observable

    assert name in ['messier', 'ngc']

    if name == 'messier':
        data_path = '../data/catalogs/messier.csv'
    elif name == 'ngc':
        data_path = '../data/catalogs/ngc.csv'

    df = pd.read_csv(data_path)
    # The search & target creation is slow for >~thousands of FixedTargets. NGC
    # catalog is 13226 objects. Take those with v_mag<11, since from Peyton we
    # likely won't go fainter.
    df = df.sort_values('v_mag')
    df = df[df['v_mag']<11]

    peyton = Observer(longitude=74.65139*u.deg, latitude=40.34661*u.deg,
        elevation=62*u.m, name='Peyton', timezone='US/Eastern')

    if name == 'ngc':
        ras = np.array(df['ra'])*u.hourangle
        decs = np.array(df['dec'])*u.degree
        names = np.array(df['ngc_id'])
    elif name == 'messier':
        ras = np.array(df['ra'])*u.hourangle
        decs = np.array(df['dec'])*u.degree
        names = np.array(df['messier_id'])

    targets = [FixedTarget(SkyCoord(ra=r, dec=d), name=n) for r, d, n in
            tuple(zip(ras, decs, names))]

    constraints = [AltitudeConstraint(10*u.deg, 82*u.deg),
            AtNightConstraint(max_solar_altitude=-3.*u.deg)]

    t_obs = Time(time)
    is_up = is_observable(constraints, peyton, targets, times=t_obs)

    df['is_up'] = is_up

    return df
Exemplo n.º 10
0
    def objVis(self):
        """
        Checks if transit is in between twilight hours. If not return error
        Returns the amount of time the object is above given airmass
        """

        objVis = is_observable(self.constraints,
                               self.observer,
                               self.target,
                               time_range=(self.discDate,
                                           self.discDate + 1 * u.day))[0]
        return objVis
Exemplo n.º 11
0
def test_observability_table():
    subaru = Observer.at_site("Subaru")
    time_ranges = [
        Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06']),  # 1 day
        Time(['2007-08-09 10:11:12', '2007-08-09 11:11:12'])
    ]  # 1 hr
    targets = [vega, rigel, polaris]

    time_range = Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06'])
    # note that this uses the AirmassConstraint in None min mode - that means
    # targets below the horizon will pass the airmass constraint
    constraints = [AtNightConstraint(), AirmassConstraint(3, None)]

    obstab = observability_table(constraints,
                                 subaru,
                                 targets,
                                 time_range=time_range)

    assert len(obstab) == 3
    assert np.all(obstab['target name'] == ['Vega', 'Rigel', 'Polaris'])

    assert 'times' in obstab.meta
    assert 'observer' in obstab.meta
    assert 'constraints' in obstab.meta
    assert len(obstab.meta['constraints']) == 2

    np.testing.assert_allclose(obstab['fraction of time observable'],
                               np.array([21, 22, 15]) / 48)

    # now compare to is_observable and is_always_observable
    is_obs = is_observable(constraints, subaru, targets, time_range=time_range)
    np.testing.assert_allclose(obstab['ever observable'], is_obs)
    all_obs = is_always_observable(constraints,
                                   subaru,
                                   targets,
                                   time_range=time_range)
    np.testing.assert_allclose(obstab['always observable'], all_obs)

    # try the scalar time_range case
    ttab = observability_table(constraints,
                               subaru,
                               targets,
                               time_range=(time_range[0] - 12 * u.hour,
                                           time_range[0] + 12 * u.hour))
    stab = observability_table(constraints,
                               subaru,
                               targets,
                               time_range=time_range[0])

    assert all(ttab['fraction of time observable'] ==
               stab['fraction of time observable'])
    assert 'time observable' in stab.colnames
Exemplo n.º 12
0
def test_at_night_basic():
    subaru = Observer.at_site("Subaru")
    time_ranges = [Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06']),  # 1 day
                   Time(['2007-08-09 10:11:12', '2007-08-09 11:11:12'])]  # 1 hr
    targets = [vega, rigel, polaris]
    for time_range in time_ranges:
        # Calculate constraint using methods on astroplan.Observer:
        observer_is_night = subaru.is_night(time_grid_from_range(time_range))
        observer_is_night_any = any(observer_is_night)
        observer_is_night_all = all(observer_is_night)

        assert all(is_observable(AtNightConstraint(), subaru, targets,
                                 time_range=time_range) ==
                   len(targets)*[observer_is_night_any])

        assert all(is_always_observable(AtNightConstraint(), subaru, targets,
                                        time_range=time_range) ==
                   len(targets)*[observer_is_night_all])
Exemplo n.º 13
0
def test_at_night_basic():
    subaru = Observer.at_site("Subaru")
    time_ranges = [Time(['2001-02-03 04:05:06', '2001-02-04 04:05:06']),  # 1 day
                   Time(['2007-08-09 10:11:12', '2007-08-09 11:11:12'])]  # 1 hr
    targets = [vega, rigel, polaris]
    for time_range in time_ranges:
        # Calculate constraint using methods on astroplan.Observer:
        observer_is_night = subaru.is_night(time_grid_from_range(time_range))
        observer_is_night_any = any(observer_is_night)
        observer_is_night_all = all(observer_is_night)

        assert all(is_observable(AtNightConstraint(), subaru, targets,
                                 time_range=time_range) ==
                   len(targets)*[observer_is_night_any])

        assert all(is_always_observable(AtNightConstraint(), subaru, targets,
                                        time_range=time_range) ==
                   len(targets)*[observer_is_night_all])
Exemplo n.º 14
0
def observability(self, json_exoplanet_array, longitude, latitude, elevation, start_date, end_date, min_altitude, max_altitude, resolution):
    '''background task to (slowly) find planet observabilities'''
    
    # create Observer instance
    if elevation is None: elevation = 0
    custom_location = Observer(longitude=longitude*u.deg, latitude=latitude*u.deg, elevation=elevation*u.m)

    # time range
    if start_date is not None: start_date = Time(datetime.combine(datetime.fromisoformat(start_date), datetime.min.time()), out_subfmt='date')
    else: start_date = Time(datetime.combine(datetime.now(), datetime.min.time()), out_subfmt='date')
    if end_date is not None: end_date = Time(datetime.combine(datetime.fromisoformat(end_date), datetime.min.time()), out_subfmt='date')
    else: end_date = start_date + 30*u.day
    time_range = Time([start_date, end_date])

    # altitude and night time constraints
    if min_altitude is None: min_altitude = 0
    if max_altitude is None: max_altitude = 90
    constraints = [AltitudeConstraint(min_altitude*u.deg, max_altitude*u.deg), AtNightConstraint.twilight_astronomical()]
    
    # calculate if observable within lookahead time from now
    if resolution is None: resolution = 0.5
    
    # since we had to use a json string as argument, recreate the custom_exoplanet_array from the json
    custom_exoplanet_array = []
    json_unload = json.loads(json_exoplanet_array) # unpack json to make a dictionary
    for dict_ in json_unload:
        planet = Exoplanet()
        # copy properties back over from dictionary
        for prop, val in dict_.items(): functions.rsetattr(planet, prop, val)
        custom_exoplanet_array.append(planet)

    # trying to split array into chunks so we can say the task has been completed to the nearest percent
    num_chunks = round(len(custom_exoplanet_array)/800 * (resolution/0.5)**-1 * ((end_date-start_date).jd/30)**2 * 10)
    if num_chunks == 0: num_chunks = 1
    exoplanet_array_chunks = np.array_split(custom_exoplanet_array, num_chunks) # split exoplanet array into num_chunk parts

    planets_done = 0 # planets calculated for so far
    planets_lost = 0 # planets removed so far

    recombined_chunks = []
    for chunk in exoplanet_array_chunks:
        # make an array of FixedTarget instances
        target_table = []
        for planet in chunk:
            target_table.append((planet.name, planet.host.ra, planet.host.dec))
        targets = [FixedTarget(coord=SkyCoord(ra=ra*u.deg, dec=dec*u.deg), name=name)
                   for name, ra, dec in target_table]

        # calculate
        ever_observable = is_observable(constraints, custom_location, targets, time_range=time_range, time_grid_resolution=resolution*u.hour)

        # note unobservables
        to_pop = []
        for i in range(len(chunk)):
            chunk[i].observable = bool(ever_observable[i])
            if chunk[i].observable == False:
                to_pop.append(i)
        # remove unobservables
        chunk = np.delete(chunk, to_pop)

        # record numbers
        planets_done += len(targets)
        planets_lost += len(targets) - len(chunk)

        # write json
        recombined_chunks += chunk.tolist()
        observable_exoplanet_array = [planet for planet in recombined_chunks if planet.observable]
        json_exoplanet_array = functions.planet_array_to_json_array(observable_exoplanet_array, 'host_')

        # graph of decision metric vs rank
        tooltip_dict = {
            'name'            : [],
            'mass'            : [],
            'radius'          : [],
            'orbital_period'  : [],
            'semi_major_axis' : [],
            'temp_calculated' : [],
            'detection_type'  : [],
            'decision_metric' : [],
            'filter'          : [],
            't_exp'           : [],
        }
        graph = functions.metric_rank_bar_graph(observable_exoplanet_array, tooltip_dict)

        # update status
        self.update_state(state='PROGRESS',
                          meta={'current'         : planets_done,
                                'removed'         : planets_lost,
                                'total'           : len(custom_exoplanet_array),
                                'exoplanet_array' : json_exoplanet_array,
                                'graph'           : graph,
                                'finished'        : 'n'})
    
    return {'current': planets_done, 'removed': planets_lost, 'total': len(custom_exoplanet_array), 'exoplanet_array': json_exoplanet_array, 'graph': graph, 'finished': 'y'}
Exemplo n.º 15
0
def find_observability(exoplanet_array, default_lookahead, longitude, latitude,
                       elevation, start_date, end_date, min_altitude,
                       max_altitude, resolution, flash, display):
    '''Function to calculate'''
    '''# find timezone
    timezone_name = tf.timezone_at(lng=longitude, lat=latitude)
    delta_degree = 1
    while timezone_name is None:
        delta_degree += 1
        timezone_name = tf.closest_timezone_at(lng=longitude, lat=latitude, delta_degree=delta_degree)
    if flash: flash.append('Timezone   : ' + timezone_name)
    print(timezone_name)'''

    # create Observer instance
    if elevation is None: elevation = 0
    custom_location = Observer(longitude=longitude * u.deg,
                               latitude=latitude * u.deg,
                               elevation=elevation * u.m)

    # make an array of FixedTarget instances
    target_table = []
    for planet in exoplanet_array:
        target_table.append((planet.name, planet.host.ra, planet.host.dec))
    targets = [
        FixedTarget(coord=SkyCoord(ra=ra * u.deg, dec=dec * u.deg), name=name)
        for name, ra, dec in target_table
    ]

    # time range
    if start_date is not None:
        start_date = Time(datetime.combine(start_date, datetime.min.time()),
                          out_subfmt='date')
    else:
        start_date = Time(datetime.combine(datetime.now(),
                                           datetime.min.time()),
                          out_subfmt='date')
    if end_date is not None:
        end_date = Time(datetime.combine(end_date, datetime.min.time()),
                        out_subfmt='date')
    else:
        end_date = start_date + default_lookahead * u.day
    time_range = Time([start_date, end_date])
    #time_range_int = # no. days as an int
    if display:
        flash.append('Start date : ' + str(start_date.iso))
        flash.append('End date   : ' + str(end_date.iso))

    # altitude and night time constraints
    if min_altitude is None: min_altitude = 0
    if max_altitude is None: max_altitude = 90
    constraints = [
        AltitudeConstraint(min_altitude * u.deg, max_altitude * u.deg),
        AtNightConstraint.twilight_astronomical()
    ]

    # calculate if observable within lookahead time from now
    if resolution is None: resolution = 0.5

    # new route, faster by not bothering to recheck planets already found to be observable
    # UPDATE, ASTROPY IS ALREADY OPTIMISED FOR THIS, THIS TAKES 10 TIMES LONGER, LEAVING IN FOR DEMONSTRATION PURPOSES ONLY (commented out lines in 'old route' are also only for demonstrating the difference)
    # start = time.perf_counter()
    # ever_observable = [False] * len(exoplanet_array)
    # day = 0
    # while start_date + day*u.day != end_date:
    #     print(str(start_date + day*u.day) + ', ' + str(end_date))
    #     for i in range(len(ever_observable)):
    #         if ever_observable[i] == False:
    #             ever_observable[i] = is_observable(constraints, custom_location, [targets[i]], time_range=Time([start_date+day*u.day, start_date+(day+1)*u.day]), time_grid_resolution=resolution*u.hour)[0]
    #             print(str(day) + ', ' + str(i) + ', ' + targets[i].name + ', ' + str(ever_observable[i]))
    #     day += 1
    # end = time.perf_counter()
    # print(str(end - start) + ' seconds fast')

    # new route, faster by not bothering to recheck planets already found to be observable
    # UPDATE, ASTROPY IS ALREADY OPTIMISED FOR THIS, THIS TAKES 10 TIMES LONGER, LEAVING IN FOR DEMONSTRATION PURPOSES ONLY (commented out lines in 'old route' are also only for demonstrating the difference)
    # start = time.perf_counter()
    # ever_observable = [False] * len(exoplanet_array)
    # day = 0
    # for i in range(len(ever_observable)):
    #     for day in range(30):
    #         print(str(start_date + day*u.day) + ', ' + str(end_date))

    #         if ever_observable[i] == False:
    #             ever_observable[i] = is_observable(constraints, custom_location, [targets[i]], time_range=Time([start_date+day*u.day, start_date+(day+1)*u.day]), time_grid_resolution=resolution*u.hour)[0]
    #             print(str(day) + ', ' + str(i) + ', ' + targets[i].name + ', ' + str(ever_observable[i]))
    #         else: break
    # end = time.perf_counter()
    # print(str(end - start) + ' seconds fast')

    # trying to split array into chunks so we can say the task has been completed to the nearest percent
    # tosplit_target_array = copy.deepcopy(targets)
    # start = time.perf_counter()
    # target_chunks = np.array_split(tosplit_target_array, 10) # split targets into 10 parts (not 100, this makes the calculation time too long)
    # for i in range(len(target_chunks)):
    #     is_observable(constraints, custom_location, target_chunks[i].tolist(), time_range=time_range, time_grid_resolution=resolution*u.hour)
    #     #print('%i calculated' %i)
    # end = time.perf_counter()
    # print(str(end - start) + ' seconds fast')

    # old route, slow, commented out lines are for demonstrating that it is better than a manual method by a factor of 10
    start = time.perf_counter()
    ever_observable = is_observable(constraints,
                                    custom_location,
                                    targets,
                                    time_range=time_range,
                                    time_grid_resolution=resolution * u.hour)
    end = time.perf_counter()
    print(str(end - start) + ' seconds slow')

    for i in range(len(exoplanet_array)):
        exoplanet_array[i].observable = ever_observable[i]
    if display: flash.append('Timing resolution = {} hrs'.format(resolution))
Exemplo n.º 16
0
from mop.toolbox.LCO_obs_locs import choose_loc

OGG = choose_loc('OGG')
v_test_target = ['Sirius', 100.7362500 * u.deg, -16.6459444 * u.deg]
v_date = Time("2019-12-25 00:00:00", scale='utc')
v_coords = SkyCoord(v_test_target[1], v_test_target[2], frame='icrs')
v_obs_begin = OGG.twilight_evening_astronomical(v_date, which='nearest')
v_obs_end = OGG.twilight_morning_astronomical(v_date, which='next')
v_observing_range = [v_obs_begin, v_obs_end]
constraints = [
    AirmassConstraint(2.0),
    AltitudeConstraint(20 * u.deg, 85 * u.deg),
    AtNightConstraint.twilight_astronomical()
]
ever_observable = is_observable(constraints,
                                OGG,
                                v_coords,
                                time_range=v_observing_range)

v_fail_start = Time("2019-12-24 10:00:00", scale='utc')
v_fail_end = Time("2019-12-25 10:00:00", scale='utc')


class TestVisibilityCalc(TestCase):
    def test_timeobj(self):
        self.assertEqual(v_date.scale, 'utc')
        self.assertEqual(v_date.value, '2019-12-25 00:00:00.000')

    def test_coords(self):
        self.assertEqual(v_coords.ra, v_test_target[1])
        self.assertEqual(v_coords.dec, v_test_target[2])
Exemplo n.º 17
0
def vis(date, objects, obj_tab):

    #This tool is designed for the Magellan Telescope @ Las Camapanas Observatory, in Chile
    las = Observer.at_site('LCO')
    #both las and los are the locations of MagAO, but one is used for the plot and the other for the time
    lco = EarthLocation.of_site('Las Campanas Observatory')

    userEntered_list = list(objects.split(","))
    target_list = userEntered_list

    targets = []
    for i in range(1, len(obj_tab)):
        ra = (obj_tab.iloc[i, 2])[1:] + ' hours'
        dec = (obj_tab.iloc[i, 3])[1:] + ' degrees'
        print(ra + ',' + dec)
        targets.append(
            FixedTarget(coord=SkyCoord(ra=ra, dec=dec),
                        name=target_list[i - 1]))

    constraints = [
        AltitudeConstraint(10 * u.deg, 80 * u.deg),
        AirmassConstraint(5),
        AtNightConstraint.twilight_civil()
    ]

    start_time = las.sun_set_time(Time(date), which='nearest')
    end_time = las.sun_rise_time(Time(date), which='nearest')
    date = start_time.iso[:10] + ' to ' + end_time.iso[:10]

    time_range = Time([start_time, end_time])

    # In[ ]:

    delta_t = end_time - start_time
    observe_time = start_time + delta_t * np.linspace(0, 1, 75)

    # In[ ]:

    # Are targets *ever* observable in the time range?
    ever_observable = is_observable(constraints,
                                    las,
                                    targets,
                                    time_range=time_range)

    # Are targets *always* observable in the time range?
    always_observable = is_always_observable(constraints,
                                             las,
                                             targets,
                                             time_range=time_range)

    # During what months are the targets ever observable?
    best_months = months_observable(constraints, las, targets)

    # In[ ]:

    table = observability_table(constraints,
                                las,
                                targets,
                                time_range=time_range)
    print(table)

    table = table.to_pandas()

    np.savetxt(
        'static/data/visibility.txt',
        table,
        fmt="%-30s",
        header=
        'Target name                  ever observable                always observable              fraction of time observable'
    )
Exemplo n.º 18
0
def get_obs_data(target, observers, current_time, alt_limit=30):
    """Compile infomation about the target's visibility from the given observers."""
    all_data = {}
    if target is None:
        return all_data

    for observer in observers:
        data = {}
        data['observer'] = observer
        data['current_time'] = current_time

        # Get midnight and astronomical twilight times
        midnight = observer.midnight(current_time, which='next')
        sun_set = observer.twilight_evening_astronomical(midnight,
                                                         which='previous')
        sun_rise = observer.twilight_morning_astronomical(midnight,
                                                          which='next')
        dark_time = Time([sun_set, sun_rise])
        data['midnight'] = midnight
        data['sun_set'] = sun_set
        data['sun_rise'] = sun_rise

        # Apply a constraint on altitude
        min_alt = alt_limit * u.deg
        alt_constraint = AltitudeConstraint(min=min_alt, max=None)
        alt_observable = is_observable(alt_constraint,
                                       observer,
                                       target,
                                       time_range=dark_time)[0]
        data['alt_constraint'] = alt_constraint
        data['alt_observable'] = alt_observable

        # Get target rise and set times
        if alt_observable:
            with warnings.catch_warnings():
                warnings.simplefilter('ignore')
                target_rise = observer.target_rise_time(midnight,
                                                        target,
                                                        which='nearest',
                                                        horizon=min_alt)
                target_set = observer.target_set_time(target_rise,
                                                      target,
                                                      which='next',
                                                      horizon=min_alt)

            # Get observation times
            observation_start = target_rise
            observation_end = target_set
            if target_rise.jd < 0 or target_set.jd < 0:
                # target is always above the horizon, so visible all night
                observation_start = sun_set
                observation_end = sun_rise
            if target_rise < sun_set:
                # target is already up when the sun sets
                observation_start = sun_set
            if target_set > sun_rise:
                # target sets after the sun rises
                observation_end = sun_rise

            data['target_rise'] = target_rise
            data['target_set'] = target_set
            data['observation_start'] = observation_start
            data['observation_end'] = observation_end
        else:
            data['target_rise'] = None
            data['target_set'] = None
            data['observation_start'] = None
            data['observation_end'] = None

        # Apply a constraint on distance from the Moon
        min_moon = 5 * u.deg
        moon_constraint = MoonSeparationConstraint(min=min_moon, max=None)
        moon_observable = is_observable(moon_constraint,
                                        observer,
                                        target,
                                        time_range=dark_time)[0]
        data['moon_constraint'] = moon_constraint
        data['moon_observable'] = moon_observable

        all_data[observer.name] = data

    return all_data
Exemplo n.º 19
0
def construct_plan(data,
                   site,
                   start_time,
                   end_time,
                   constraints=None,
                   max_priority=3):
    if constraints is None:
        constraints = [
            AltitudeConstraint(10 * u.deg, 80 * u.deg),
            AirmassConstraint(5),
            AtNightConstraint.twilight_civil()
        ]

    data = data.sort_values(by=["Add. Data Priority", "RA"], ascending=[1, 1])

    time_range = Time([start_time, end_time])

    # targets.lis format:
    # NAME
    # <RA hh:mm:ss.ss> <DEC dd:mm:ss.s>
    # <HMJD/BMJD T0 err P err
    #
    # NAME...
    # ENTRY = "{}\n{} {}\n{} linear {} {} {} {}\n\n"
    targets_list = ""
    targets_prg = ""
    targets_notes = ""
    for name, row in data.iterrows():
        row['RA'], row['Dec'] = row['RA'].replace(" ",
                                                  ":"), row['Dec'].replace(
                                                      " ", ":")

        target = FixedTarget(coord=SkyCoord(ra=Angle(row['RA'],
                                                     unit='hourangle'),
                                            dec=Angle(row['Dec'],
                                                      unit='degree')),
                             name=name)

        # Does the target rise above the horizon?
        ever_observable = is_observable(constraints,
                                        site,
                                        target,
                                        time_range=time_range)

        # Parse the ephemeris data
        try:
            T0, T0_err = row['T(0) +/- (d)'].replace(" ", "").split("(")
            calendar, T0 = T0.split("=")
            T0_err = T0_err.replace(")", "")

            N = len(T0.split(".")[1]) - len(T0_err)
            T0_err = "0.{}{}".format(("0" * N), T0_err)

            P, P_err = row['P +/- (d)'].split("(")
            P_err = P_err.replace(")", "")

            M = len(P.split(".")[1]) - len(P_err)
            P_err = "0.{}{}".format(("0" * M), P_err)
        except ValueError:
            print("Failed to extract row! {}".format(name))
            continue

        # Get the priority of this system
        try:
            priority = int(row['Add. Data Priority'])
        except ValueError:
            continue

        # Logic about if we want to use this target
        writeme = ever_observable[0] and (priority <= max_priority)

        # If true, add to the list
        if writeme:
            # Output data formats
            line = "{}\n{} {}\n{} linear {} {} {} {}\n\n".format(
                name, row['RA'], row['Dec'], calendar, T0, T0_err, P, P_err)
            prgline = "{}\n0.7 1.3 3 8\n\n".format(name)
            notesline = '{}: "{}"\n\n\n'.format(name, row['Target Notes'])

            targets_list += line
            targets_prg += prgline
            targets_notes += notesline

    # Write out files
    with open(os.path.join('OUTPUT', 'targets.lis'), 'w') as f:
        f.write(targets_list)
    with open(os.path.join('OUTPUT', 'targets.prg'), 'w') as f:
        f.write(targets_prg)
    with open(os.path.join('OUTPUT', 'targets.txt'), 'w') as f:
        f.write(targets_notes)
Exemplo n.º 20
0
def observability(data):
    """
    Test the observability of a list of objects for a single date

    Parameters
    ----------
    data : POST data format

        Observatory, date, limits and objects
        data = {
            'observatory' : 'OT',
            'date' : '2020-06-11 00:16:30',
            'date_end' : '2020-06-11 03:44:26',
            'altitude_lower_limit' : '30',
            'altitude_higher_limit' : '90',
            'twilight_type' : 'astronomical',
            'objects' : [{
                    'name' : 'Kelt 8b',
                    'RA' : 283.30551667 ,
                    'Dec' : 24.12738139
                    },
                    (more objects...)
                ]
            }

    Returns
    -------
    observability : dict
        Dictionary with the observability and moon distance for all objects
        {
            'V0879 Cas' : {
                'observability' : 'True', 'moon_separation' : 30.4
            },
            'RU Scl' : {
                'observability' : 'True', 'moon_separation' : 10.8
            }
        }

    """

    import astropy.units as u
    from astroplan import FixedTarget
    from astroplan import (AltitudeConstraint, AtNightConstraint)
    from astroplan import is_observable, is_always_observable

    # Site location
    location = get_location(data['observatory'])

    time_range = Time([data['date'], data['date_end']])

    if 'twilight_type' not in data.keys():
        data['twilight_type'] = 'astronomical'

    if data['twilight_type'] == 'civil':
        twilight_constraint = AtNightConstraint.twilight_civil()
    elif data['twilight_type'] == 'nautical':
        twilight_constraint = AtNightConstraint.twilight_nautical()
    else:
        twilight_constraint = AtNightConstraint.twilight_astronomical()

    # Observation constraints
    constraints = [
        AltitudeConstraint(
            int(data['altitude_lower_limit']) * u.deg,
            int(data['altitude_higher_limit']) * u.deg), twilight_constraint
    ]

    # Dictionary with star name and observability (bool str)
    result = {}

    # Moon location for the observation date
    middle_observing_time = time_range[-1] - (time_range[-1] -
                                              time_range[0]) / 2
    moon = location.moon_altaz(middle_observing_time)

    for target in data['objects']:
        # Object coordinates
        coords = SkyCoord(ra=target['RA'] * u.deg, dec=target['Dec'] * u.deg)
        fixed_target = [FixedTarget(coord=coords, name=target['name'])]

        if 'transit' in target.keys():
            time_range = Time(
                [target['transit']['t_early'], target['transit']['t_late']])
            # Are targets *always* observable in the time range?
            observable = is_always_observable(constraints,
                                              location,
                                              fixed_target,
                                              time_range=time_range)
        else:
            time_range = Time([data['date'], data['date_end']])
            # Are targets *ever* observable in the time range?
            observable = is_observable(constraints,
                                       location,
                                       fixed_target,
                                       time_range=time_range)

        moon_separation = moon.separation(coords)

        result[target['name']] = {
            'observable': str(observable[0]),
            'moon_separation': moon_separation.degree
        }

    return result
Exemplo n.º 21
0
def plan_when_transits_will_occur(
        filename='targets.txt',
        observatory='Southern African Large Telescope',
        start='2017-06-22',
        end='2017-06-28',
        airmass_limit=2.5,
        moon_distance=10,
        do_secondary=True,
        method='by_night'):
    '''
    Plan when targets will be visibile and transiting from a site. 
    
    Inputs
    ------
    filename : str
        A plain text file with the following columns:
            target : The name of the target (e.g. J0555-57).
            RA     : The right ascension of the target (e.g. 05h55m32.62s).
            DEC    : The declination of the target (e.g. -57d17m26.1s).
            epoch* : The epoch of the transit. Youc can either use:
                         epoch_HJD-2400000 : HJD - 24500000
                         epoch_BJD-2455000 : MJD
            Period : The period of the system (days).
            Secondary : can be True or False depending on whether you want
                        to see when the secondary transits will be.
    observatory : str
        The observatory you are observing from. See later for list of available
        observatories (accepted by astropy).    
    start : str
        The first night of observation (e.g. 2017-08-31).
    end : str
        The last night of observation (e.g. 2017-09-10).
    airmass_limit : float
        The maximum airmass you want to observe through. 
    moon_distance : float
        The closest the target can be t the moon in arcmins.
    do_secondary = True:
        Look for secondary eclipses assuming circularised orbits. 
        
    Available observator names are:
         'ALMA',
         'Anglo-Australian Observatory',
         'Apache Point',
         'Apache Point Observatory',
         'Atacama Large Millimeter Array',
         'BAO',
         'Beijing XingLong Observatory',
         'Black Moshannon Observatory',
         'CHARA',
         'Canada-France-Hawaii Telescope',
         'Catalina Observatory',
         'Cerro Pachon',
         'Cerro Paranal',
         'Cerro Tololo',
         'Cerro Tololo Interamerican Observatory',
         'DCT',
         'Discovery Channel Telescope',
         'Dominion Astrophysical Observatory',
         'Gemini South',
         'Hale Telescope',
         'Haleakala Observatories',
         'Happy Jack',
         'Jansky Very Large Array',
         'Keck Observatory',
         'Kitt Peak',
         'Kitt Peak National Observatory',
         'La Silla Observatory',
         'Large Binocular Telescope',
         'Las Campanas Observatory',
         'Lick Observatory',
         'Lowell Observatory',
         'Manastash Ridge Observatory',
         'McDonald Observatory',
         'Medicina',
         'Medicina Dish',
         'Michigan-Dartmouth-MIT Observatory',
         'Mount Graham International Observatory',
         'Mt Graham',
         'Mt. Ekar 182 cm. Telescope',
         'Mt. Stromlo Observatory',
         'Multiple Mirror Telescope',
         'NOV',
         'National Observatory of Venezuela',
         'Noto',
         'Observatorio Astronomico Nacional, San Pedro Martir',
         'Observatorio Astronomico Nacional, Tonantzintla',
         'Palomar',
         'Paranal Observatory',
         'Roque de los Muchachos',
         'SAAO',
         'SALT',
         'SRT',
         'Siding Spring Observatory',
         'Southern African Large Telescope',
         'Subaru',
         'Subaru Telescope',
         'Sutherland',
         'Vainu Bappu Observatory',
         'Very Large Array',
         'W. M. Keck Observatory',
         'Whipple',
         'Whipple Observatory',
         'aao',
         'alma',
         'apo',
         'bmo',
         'cfht',
         'ctio',
         'dao',
         'dct',
         'ekar',
         'example_site',
         'flwo',
         'gemini_north',
         'gemini_south',
         'gemn',
         'gems',
         'greenwich',
         'haleakala',
         'irtf',
         'keck',
         'kpno',
         'lapalma',
         'lasilla',
         'lbt',
         'lco',
         'lick',
         'lowell',
         'mcdonald',
         'mdm',
         'medicina',
         'mmt',
         'mro',
         'mso',
         'mtbigelow',
         'mwo',
         'noto',
         'ohp',
         'paranal',
         'salt',
         'sirene',
         'spm',
         'srt',
         'sso',
         'tona',
         'vbo',
         'vla'.
    '''
    ###################
    # Try reading table
    ###################
    try:
        target_table = Table.read(filename, format='ascii')
    except:
        raise ValueError(
            'I cant open the target file (make sure its ascii with the following first line:\ntarget		RA		DEC		epoch_HJD-2400000	Period		Secondary'
        )

##############################
# try reading observation site
##############################
    try:
        observation_site = coord.EarthLocation.of_site(observatory)
        observation_handle = Observer(location=observation_site)
        observation_handle1 = Observer.at_site(observatory)
    except:
        print(coord.EarthLocation.get_site_names())
        raise ValueError('The site is not understood')

###################################
# Try reading start and end times
###################################
    try:
        start_time = Time(start + ' 12:01:00', location=observation_site)
        end_time = Time(end + ' 12:01:00', location=observation_site)
        number_of_nights = int(end_time.jd - start_time.jd)
        time_range = Time([start + ' 12:01:00', end + ' 12:01:00'])
        print('Number of nights: {}'.format(number_of_nights))
    except:
        raise ValueError('Start and end times not understood')

#####################
# Now do constraints
#####################
#try:

    constraints = [
        AltitudeConstraint(0 * u.deg, 90 * u.deg),
        AirmassConstraint(3),
        AtNightConstraint.twilight_civil()
    ]
    #except:
    #	raise ValueError('Unable to get set constraints')

    if method == 'by_night':
        for i in range(number_of_nights):
            start_time_tmp = start_time + TimeDelta(
                i,
                format='jd')  #  get start time (doesent need to be accurate)
            end_time_tmp = start_time + TimeDelta(
                i + 1,
                format='jd')  #  get start time (doesent need to be accurate)
            print('#' * 80)
            start_time_tmpss = start_time_tmp.datetime.ctime().split(
            )  # ['Fri', 'Dec', '24', '12:00:00', '2010']
            print('Night {} - {} {} {} {}'.format(i + 1, start_time_tmpss[0],
                                                  start_time_tmpss[2],
                                                  start_time_tmpss[1],
                                                  start_time_tmpss[-1]))
            print('#' * 80)

            # Now print Almnac information (sunset and end of evening twilight
            print('Almnac:')
            sun_set = observation_handle.sun_set_time(start_time_tmp,
                                                      which='next')
            print('Sunset:\t\t\t\t\t\t\t' + sun_set.utc.datetime.ctime())

            twilight_evening_astronomical = observation_handle.twilight_evening_astronomical(
                start_time_tmp, which='next')  # -18
            twilight_evening_nautical = observation_handle.twilight_evening_nautical(
                start_time_tmp, which='next')  # -12
            twilight_evening_civil = observation_handle.twilight_evening_civil(
                start_time_tmp, which='next')  # -6 deg
            print('Civil evening twilight (-6 deg) (U.T.C):\t\t' +
                  twilight_evening_civil.utc.datetime.ctime())
            print('Nautical evening twilight (-12 deg) (U.T.C):\t\t' +
                  twilight_evening_nautical.utc.datetime.ctime())
            print('Astronomical evening twilight (-18 deg) (U.T.C):\t' +
                  twilight_evening_astronomical.utc.datetime.ctime())
            print('\n')

            twilight_morning_astronomical = observation_handle.twilight_morning_astronomical(
                start_time_tmp, which='next')  # -18
            twilight_morning_nautical = observation_handle.twilight_morning_nautical(
                start_time_tmp, which='next')  # -12
            twilight_morning_civil = observation_handle.twilight_morning_civil(
                start_time_tmp, which='next')  # -6 deg
            print('Astronomical morning twilight (-18 deg) (U.T.C):\t' +
                  twilight_morning_astronomical.utc.datetime.ctime())
            print('Nautical morning twilight (-12 deg) (U.T.C):\t\t' +
                  twilight_morning_nautical.utc.datetime.ctime())
            print('Civil morning twilight (-6 deg) (U.T.C):\t\t' +
                  twilight_morning_civil.utc.datetime.ctime())
            sun_rise = observation_handle.sun_rise_time(start_time_tmp,
                                                        which='next')
            print('Sunrise:\t\t\t\t\t\t' + sun_rise.utc.datetime.ctime())
            print('\n')

            # stuff for creating plot
            plot_mids = []
            plot_names = []
            plot_widths = []

            for j in range(len(target_table)):
                # Extract information
                star_coordinates = coord.SkyCoord('{} {}'.format(
                    target_table['RA'][j], target_table['DEC'][j]),
                                                  unit=(u.hourangle, u.deg),
                                                  frame='icrs')
                star_fixed_coord = FixedTarget(coord=star_coordinates,
                                               name=target_table['target'][j])

                ####################
                # Get finder image
                ####################
                '''
                plt.close()
                try:
                finder_image = plot_finder_image(star_fixed_coord,reticle=True,fov_radius=10*u.arcmin)
                except:
                pass
                plt.savefig(target_table['target'][j]+'_finder_chart.eps')
                '''

                P = target_table['Period'][j]
                Secondary_transit = target_table['Secondary'][j]
                transit_half_width = TimeDelta(
                    target_table['width'][j] * 60 * 60 / 2,
                    format='sec')  # in seconds for a TimeDelta

                # now convert T0 to HJD -> JD -> BJD so we can cout period
                if 'epoch_HJD-2400000' in target_table.colnames:
                    #print('Using HJD-2400000')
                    T0 = target_table['epoch_HJD-2400000'][j]
                    T0 = Time(T0 + 2400000, format='jd')  # HJD given by WASP
                    ltt_helio = T0.light_travel_time(star_coordinates,
                                                     'heliocentric',
                                                     location=observation_site)
                    T0 = T0 - ltt_helio  # HJD -> JD
                    ltt_bary = T0.light_travel_time(star_coordinates,
                                                    'barycentric',
                                                    location=observation_site)
                    T0 = T0 + ltt_bary  # JD -> BJD
                elif 'epoch_BJD-2455000' in target_table.colnames:
                    #print('Using BJD-2455000')
                    T0 = target_table['epoch_BJD-2455000'][j] + 2455000
                    T0 = Time(T0, format='jd')  # BJD
                else:
                    print('\n\n\n\n FAILE\n\n\n\n')
                    continue

                ##########################################################
                # Now start from T0 and count in periods to find transits
                ##########################################################
                # convert star and end time to BJD
                ltt_bary_start_time = start_time_tmp.light_travel_time(
                    star_coordinates, 'barycentric',
                    location=observation_site)  # + TimeDelta(i,format='jd')
                start_time_bary = start_time_tmp + ltt_bary_start_time  # + TimeDelta(i,format='jd') #  convert start time to BJD

                ltt_bary_end_time_tmp = end_time_tmp.light_travel_time(
                    star_coordinates, 'barycentric',
                    location=observation_site)  # + TimeDelta(i,format='jd')
                end_time_bary = end_time_tmp + ltt_bary_start_time  #+ TimeDelta(i+1,format='jd') #  convert end time to BJD and add 1 day 12pm -> 12pm the next day

                elapsed = end_time_bary - start_time_bary  # now this is 24 hours from the start day 12:00 pm

                # now count transits
                time = Time(T0.jd, format='jd')  # make a temporary copy
                transits = []
                primary_count, secondary_count = 0, 0
                while time.jd < end_time_bary.jd:
                    if (time.jd > start_time_bary.jd) and (time.jd <
                                                           end_time_bary.jd):
                        if is_observable(constraints,
                                         observation_handle,
                                         [star_fixed_coord],
                                         times=[time])[0] == True:
                            transits.append(time)
                            primary_count += 1
                    if Secondary_transit == 'yes':
                        timesecondary = time + TimeDelta(P / 2, format='jd')
                        if (timesecondary.jd > start_time_bary.jd) and (
                                timesecondary.jd < end_time_bary.jd):
                            if is_observable(constraints,
                                             observation_handle,
                                             [star_fixed_coord],
                                             times=[timesecondary])[0] == True:
                                transits.append(timesecondary)
                                secondary_count += 1

                    time = time + TimeDelta(P,
                                            format='jd')  # add another P to T0

                # Now find visible transits
                transits = [
                    i for i in transits
                    if is_observable(constraints,
                                     observation_handle, [star_fixed_coord],
                                     times=[i])[0] == True
                ]

                if len(transits) == 0:
                    message = '{} has no transits.'.format(
                        target_table['target'][j])
                    print('-' * len(message))
                    print(message)
                    print('-' * len(message))
                    print('\n')
                    plt.close()
                    continue
                else:
                    message = '{} has {} primary transits and {} secondary transits.'.format(
                        target_table['target'][j], primary_count,
                        secondary_count)
                    print('-' * len(message))
                    print(message)
                    print('RA: {}'.format(target_table['RA'][j]))
                    print('DEC: {}'.format(target_table['DEC'][j]))
                    print('Epoch: 2000')
                    print('T0 (BJD): {}'.format(T0.jd))
                    print('Period: {}'.format(P))
                    print('Transit width (hr): {}'.format(
                        target_table['width'][j]))
                    print('-' * len(message))
                    print('\n')

                for i in transits:
                    # currently transit times are in BJD (need to convert to HJD to check
                    ltt_helio = i.light_travel_time(star_coordinates,
                                                    'barycentric',
                                                    location=observation_site)
                    ii = i - ltt_helio
                    ltt_helio = ii.light_travel_time(star_coordinates,
                                                     'heliocentric',
                                                     location=observation_site)
                    ii = ii + ltt_helio

                    transit_1 = i - transit_half_width - TimeDelta(
                        7200, format='sec')  # ingress - 2 hr
                    transit_2 = i - transit_half_width - TimeDelta(
                        3600, format='sec')  # ingress - 2 hr
                    transit_3 = i - transit_half_width  # ingress
                    transit_4 = i + transit_half_width  # egress
                    transit_5 = i + transit_half_width + TimeDelta(
                        3600, format='sec')  # ingress - 2 hr
                    transit_6 = i + transit_half_width + TimeDelta(
                        7200, format='sec')  # ingress - 2 hr

                    if (((i.jd - time.jd) / P) - np.floor(
                        (i.jd - time.jd) / P) < 0.1) or ((
                            (i.jd - time.jd) / P) - np.floor(
                                (i.jd - time.jd) / P) > 0.9):
                        print('Primary Transit:')
                        print('-' * len('Primary Transit'))
                    if 0.4 < ((i.jd - time.jd) / P) - np.floor(
                        (i.jd - time.jd) / P) < 0.6:
                        print('Secondary Transit')
                        print('-' * len('Secondary Transit'))

                    ##################
                    # now get sirmass
                    ##################
                    altaz = star_coordinates.transform_to(
                        AltAz(obstime=transit_1, location=observation_site))
                    hourangle = observation_handle1.target_hour_angle(
                        transit_1, star_coordinates)
                    hourangle = 24 * hourangle.degree / 360
                    if hourangle > 12:
                        hourangle -= 24
                    print('Ingress - 2hr (U.T.C):\t\t\t\t\t' +
                          transit_1.utc.datetime.ctime() +
                          '\tAirmass: {:.2f}\tHA:{:.2f}'.format(
                              altaz.secz, hourangle))

                    altaz = star_coordinates.transform_to(
                        AltAz(obstime=transit_2, location=observation_site))
                    hourangle = observation_handle1.target_hour_angle(
                        transit_2, star_coordinates)
                    hourangle = 24 * hourangle.degree / 360
                    if hourangle > 12:
                        hourangle -= 24
                    print('Ingress - 1hr (U.T.C):\t\t\t\t\t' +
                          transit_2.utc.datetime.ctime() +
                          '\tAirmass: {:.2f}\tHA:{:.2f}'.format(
                              altaz.secz, hourangle))

                    altaz = star_coordinates.transform_to(
                        AltAz(obstime=transit_3, location=observation_site))
                    hourangle = observation_handle1.target_hour_angle(
                        transit_3, star_coordinates)
                    hourangle = 24 * hourangle.degree / 360
                    if hourangle > 12:
                        hourangle -= 24
                    print('Ingress (U.T.C):\t\t\t\t\t' +
                          transit_3.utc.datetime.ctime() +
                          '\tAirmass: {:.2f}\tHA:{:.2f}'.format(
                              altaz.secz, hourangle))

                    altaz = star_coordinates.transform_to(
                        AltAz(obstime=i, location=observation_site))
                    hourangle = observation_handle1.target_hour_angle(
                        i, star_coordinates)
                    hourangle = 24 * hourangle.degree / 360
                    if hourangle > 12:
                        hourangle -= 24
                    print('Mid transit (U.T.C):\t\t\t\t\t' +
                          i.utc.datetime.ctime() +
                          '\tAirmass: {:.2f}\tHA:{:.2f}'.format(
                              altaz.secz, hourangle))

                    altaz = star_coordinates.transform_to(
                        AltAz(obstime=transit_4, location=observation_site))
                    hourangle = observation_handle1.target_hour_angle(
                        transit_4, star_coordinates)
                    hourangle = 24 * hourangle.degree / 360
                    if hourangle > 12:
                        hourangle -= 24
                    print('Egress (U.T.C):\t\t\t\t\t\t' +
                          transit_4.utc.datetime.ctime() +
                          '\tAirmass: {:.2f}\tHA:{:.2f}'.format(
                              altaz.secz, hourangle))

                    altaz = star_coordinates.transform_to(
                        AltAz(obstime=transit_5, location=observation_site))
                    hourangle = observation_handle1.target_hour_angle(
                        transit_5, star_coordinates)
                    hourangle = 24 * hourangle.degree / 360
                    if hourangle > 12:
                        hourangle -= 24
                    print('Egress + 1hr (U.T.C):\t\t\t\t\t' +
                          transit_5.utc.datetime.ctime() +
                          '\tAirmass: {:.2f}\tHA:{:.2f}'.format(
                              altaz.secz, hourangle))

                    altaz = star_coordinates.transform_to(
                        AltAz(obstime=transit_6, location=observation_site))
                    hourangle = observation_handle1.target_hour_angle(
                        transit_6, star_coordinates)
                    hourangle = 24 * hourangle.degree / 360
                    if hourangle > 12:
                        hourangle -= 24
                    print('Egress + 2hr (U.T.C):\t\t\t\t\t' +
                          transit_6.utc.datetime.ctime() +
                          '\tAirmass: {:.2f}\tHA:{:.2f}'.format(
                              altaz.secz, hourangle))
                    print('HJD {} (to check with http://var2.astro.cz/)\n'.
                          format(ii.jd))

                    # append stuff for plots
                    plot_mids.append(i)  # astropy Time
                    plot_names.append(target_table['target'][j])
                    plot_widths.append(target_table['width'][j])

            # Now plot

            plt.close()
            if len(plot_mids) == 0:
                continue
            date_formatter = dates.DateFormatter('%H:%M')
            #ax.xaxis.set_major_formatter(date_formatter)

            # now load dummy transit lightcurves
            xp, yp = np.load('lc.npy')
            xs, ys = np.load('lcs.npy')

            # x = np.linspace(0, 2*np.pi, 400)
            # y = np.sin(x**2)

            subplots_adjust(hspace=0.000)
            number_of_subplots = len(
                plot_names)  # number of targets transiting that night

            time = sun_set + np.linspace(-1, 14,
                                         100) * u.hour  # take us to sunset
            for i, v in enumerate(xrange(number_of_subplots)):
                # exctract params
                width = plot_widths[v]
                name = plot_names[v]
                mid = plot_mids[v]

                # now set up dummy lc plot
                x_tmp = mid + xp * (width /
                                    2) * u.hour  # get right width in hours

                # now set up axis
                v = v + 1
                ax1 = subplot(number_of_subplots, 1, v)
                ax1.xaxis.set_major_formatter(date_formatter)

                if v == 1:
                    ax1.set_title(start)

                # plot transit model
                ax1.plot_date(x_tmp.plot_date, ys, 'k-')

                # plot continuum
                #xx  =time.plot_date
                #xx = [uu for uu in xx if (uu<min(x_tmp.plot_date)) or (uu>max(x_tmp.plot_date))]

                #ax1.plot_date(xx, np.ones(len(xx)),'k--', alpha=0.3)
                ax1.set_xlim(min(time.plot_date), max(time.plot_date))
                #ax1.plot_date(mid.plot_date, 0.5, 'ro')
                plt.setp(ax1.get_xticklabels(), rotation=30, ha='right')
                ax1.set_ylabel(name, rotation=45, labelpad=20)

                twilights = [
                    (sun_set.datetime, 0.0),
                    (twilight_evening_civil.datetime, 0.1),
                    (twilight_evening_nautical.datetime, 0.2),
                    (twilight_evening_astronomical.datetime, 0.3),
                    (twilight_morning_astronomical.datetime, 0.4),
                    (twilight_morning_nautical.datetime, 0.3),
                    (twilight_morning_civil.datetime, 0.2),
                    (sun_rise.datetime, 0.1),
                ]

                for ii, twii in enumerate(twilights[1:], 1):
                    ax1.axvspan(twilights[ii - 1][0],
                                twilights[ii][0],
                                ymin=0,
                                ymax=1,
                                color='grey',
                                alpha=twii[1])

                ax1.grid(alpha=0.5)
                ax1.get_yaxis().set_ticks([])
                if v != number_of_subplots:
                    ax1.get_xaxis().set_ticks([])

            plt.xlabel('Time [U.T.C]')
            #plt.tight_layout()
            #plt.savefig('test.eps',format='eps')
            plt.show()
Exemplo n.º 22
0
# first we define the conditions
from astroplan import TimeWindow, AltitudeWindow, AboveAirmass, is_observable

# times can be passed in as strings (interpreted as for get_date()) or
# as astropy Time or datetime objects
constraint_list = [TimeWindow("2015-05-01 18:30", "2015-05-02 05:30"),
                   AltitudeWindow(15.0*u.deg, 89.0*u.deg), AboveAirmass(1.2)]
# (AboveAirmass will be a subclass of AltitudeWindow)

# Define a target
tgt = FixedTarget(name='S5', ra='14:20:00.00', dec='48:00:00.00')

# Combine a list of constraints to run on Observer, FixedTarget, and time to 
# determine the observability of target
constraints = is_observable(constraint_list, obs, tgt, time_obs)

# Test only a single constraint:
constraints = is_observable(AboveAirmass(1.2), obs, tgt, time_obs)

# `constraints` will be a boolean where True=observable. For a list of 
# targets, observatories, or times, `constraints` may be a booleans array

# We will eventually need a more complicated method that minimizes a cost 
# function when optimizing an observing schedule given the results of 
# `is_observable`.

# ======================================================
# Other useful calculations wrt an observer and a target
#=======================================================
Exemplo n.º 23
0
# convert everything to UTC
start_time_utc = mst2utc(start_time_mst)
end_time_utc = mst2utc(end_time_mst)
observable_time_utc = mst2utc(observable_time_mst)

time_range = Time([start_time_utc, end_time_utc])

# now we figure out what is observable at all with some simple constraints
constraint = [
    AtNightConstraint.twilight_civil(),
    AirmassConstraint(max=2.5, boolean_constraint=True)
]

observable = astroplan.is_observable(constraint,
                                     kpno,
                                     targets,
                                     time_range=time_range)

data['Observable'] = observable
data.to_csv('updated.csv')

if 0:

    # now we make the exposure times
    exp_time_single = 12 * u.second
    readout_time = 1.7 * u.second
    n_coadd = 5
    n_dither = 12
    exp_time_tot = n_coadd * n_dither * exp_time_single + readout_time

    no_optical_data = pd.isnull(data['Optical run1'])
Exemplo n.º 24
0
def send_database_report(event):
    """Send a message to Slack with details of the database pointings and visibility."""
    title = ['*Visibility for event {}*'.format(event.name)]

    # Basic details
    details = []
    filepath = None
    with db.open_session() as session:
        # Query Event table entries
        db_events = session.query(
            db.Event).filter(db.Event.name == event.name).all()

        details += [
            'Number of entries in the events table: {}'.format(len(db_events))
        ]

        if len(db_events) == 0:
            # Uh-oh
            details += ['*ERROR: Nothing found in database*']
        else:
            # This event should be the latest added
            db_event = db_events[-1]

            # Get Mpointings
            db_mpointings = db_event.mpointings

            details += [
                'Number of targets for this event: {}'.format(
                    len(db_mpointings))
            ]

            if len(db_mpointings) == 0:
                # It might be because it's a retraction, so we've removed the previous pointings
                if event.type == 'GW_RETRACTION':
                    details += ['- Previous targets removed successfully']
                # Or it might be because no tiles passed the filter
                elif (event.strategy['on_grid']
                      and event.strategy['prob_limit'] > 0
                      and max(event.full_table['prob']) <
                      event.strategy['prob_limit']):
                    details += [
                        '- No tiles passed the probability limit ' +
                        '({:.1f}%, '.format(event.strategy['prob_limit'] * 100)
                        + 'highest had {:.1f}%)'.format(
                            max(event.full_table['prob']) * 100),
                    ]
                else:
                    # Uh-oh
                    details += ['- *ERROR: No Mpointings found in database*']

            else:
                # Get the Mpointing coordinates
                ras = [mpointing.ra for mpointing in db_mpointings]
                decs = [mpointing.dec for mpointing in db_mpointings]
                coords = SkyCoord(ras, decs, unit='deg')

                for site in ['La Palma']:  # TODO: should be in params
                    details += ['Predicted visibility from {}:'.format(site)]

                    # Create Astroplan Observer
                    observer = Observer.at_site(site.lower().replace(' ', ''))

                    # Create visibility constraints
                    min_alt = float(
                        event.strategy['constraints_dict']['min_alt']) * u.deg
                    max_sunalt = float(event.strategy['constraints_dict']
                                       ['max_sunalt']) * u.deg
                    alt_constraint = AltitudeConstraint(min=min_alt)
                    night_constraint = AtNightConstraint(
                        max_solar_altitude=max_sunalt)
                    constraints = [alt_constraint, night_constraint]

                    # Check visibility until the stop time
                    start_time = event.strategy['start_time']
                    stop_time = event.strategy['stop_time']
                    details += [
                        '- Valid dates: {} to {}'.format(
                            start_time.datetime.strftime('%Y-%m-%d'),
                            stop_time.datetime.strftime('%Y-%m-%d'))
                    ]

                    if event.strategy['stop_time'] < Time.now():
                        # The Event pointings will have expired
                        delta = Time.now() - event.strategy['stop_time']
                        details[-1] += ' _(expired {:.1f} days ago)_'.format(
                            delta.to('day').value)

                    mps_visible_mask = is_observable(
                        constraints,
                        observer,
                        coords,
                        time_range=[start_time, stop_time])
                    details += [
                        '- Targets visible during valid period: {}/{}'.format(
                            sum(mps_visible_mask), len(db_mpointings))
                    ]

                    if event.strategy['on_grid']:
                        # Find the total probibility for all tiles
                        mp_tiles = np.array(
                            [mp.grid_tile.name for mp in db_mpointings])
                        total_prob = event.grid.get_probability(
                            list(mp_tiles)) * 100
                        details += [
                            '- Total probability in all tiles: {:.1f}%'.format(
                                total_prob)
                        ]

                        # Get visible mp tile names
                        mp_tiles_visible = mp_tiles[mps_visible_mask]
                        visible_prob = event.grid.get_probability(
                            list(mp_tiles_visible)) * 100
                        details += [
                            '- Probability in visible tiles: {:.1f}%'.format(
                                visible_prob)
                        ]

                        # Get non-visible mp tile names
                        mps_notvisible_tonight_mask = np.invert(
                            mps_visible_mask)
                        mp_tiles_notvisible = mp_tiles[
                            mps_notvisible_tonight_mask]

                        # Get all non-visible tiles
                        tiles_visible_mask = is_observable(
                            constraints,
                            observer,
                            event.grid.coords,
                            time_range=[start_time, stop_time])
                        tiles_notvisible_mask = np.invert(tiles_visible_mask)
                        tiles_notvisible = np.array(
                            event.grid.tilenames)[tiles_notvisible_mask]

                        # Create a plot of the tiles, showing visibility tonight
                        # TODO: multiple sites? Need multiple plots or one combined?
                        filename = event.name + '_tiles.png'
                        filepath = os.path.join(params.FILE_PATH, filename)
                        event.grid.plot(
                            filename=filepath,
                            plot_skymap=True,
                            highlight=[mp_tiles_visible, mp_tiles_notvisible],
                            highlight_color=['blue', 'red'],
                            color={
                                tilename: '0.5'
                                for tilename in tiles_notvisible
                            },
                        )

    message_text = '\n'.join(title + details)

    # Send the message, with the plot attached if one was generated
    send_slack_msg(message_text, filepath=filepath)
Exemplo n.º 25
0
# first we define the conditions
from astroplan import TimeRange, AltitudeRange, AirmassRange, is_observable
# `is_observable` is a temporary function which will eventually be a method of
# something to support caching

# Times in TimeRange can be passed in as strings, will be passed to the
# Time constructor.
constraint_list = [TimeRange("2015-05-01 18:30", "2015-05-02 05:30"),
                   AirmassRange(1.2), AltitudeRange(15.0*u.deg, 89.0*u.deg)]

# (AboveAirmass will be a subclass of AltitudeWindow)

# Combine a list of constraints to run on Observer, FixedTarget, and time to
# determine the observability of target
constraints = is_observable(constraint_list, obs, t1, time_obs)

# Test only a single constraint:
constraints = is_observable(AirmassRange(1.2), obs, t1, time_obs)

# AirmassRange can accept two bounding airmasses, assumes single argument is
# an upper limit, lower limit = 1.

# `constraints` will be a boolean where True=observable. For a list of
# targets, observatories, or times, `constraints` may be a booleans array

# We will eventually need a more complicated method that minimizes a cost
# function when optimizing an observing schedule given the results of
# `is_observable`.

# ======================================================
Exemplo n.º 26
0
def observability_dates(data):
    """
    Test the observability of a single objects for several nights

    If the first element of 'dates' contains a single date, then
    the observability is test as *ever* for the night. 
    If a time range is given, observability is test as *always* for the time range

    Parameters
    ----------
    data : POST data format

        # data for transiting planet, time range constrained
        data = {
            'name' : 'Kelt 8b',
            'RA' : 283.30551667 ,
            'Dec' : 24.12738139,
            'observatory' : 'OT',
            'altitude_lower_limit' : '30',
            'altitude_higher_limit' : '90',
            'twilight_type' : 'astronomical',
            'dates' : [
                    ['2020-06-11 00:16:30', '2020-06-11 03:44:26'],
                    ['2020-06-14 06:07:56', '2020-06-14 09:35:53']
                ]
            }
        
        # data for ordinary target, twilight constrained
        # single date list

        data = {
            'name' : 'KIC8012732',
            'RA' : 284.72949583 ,
            'Dec' : 43.86421667,
            'observatory' : 'OT',
            'altitude_lower_limit' : '30',
            'altitude_higher_limit' : '90',
            'dates' : [
                        ['2020-06-11 23:00:00']
                    ]
            }

    Returns
    -------
    observability : dict
        Dictionary with the observability and moon distance for all objects

        {'V0879 Cas' : {
                'observability' : 'True', 'moon_separation' : 30.4
            },
        'RU Scl' : {
                'observability' : 'True', 'moon_separation' : 10.8
            }
        }

    """

    import astropy.units as u
    from astroplan import FixedTarget
    from astroplan import (AltitudeConstraint, AtNightConstraint)
    from astroplan import is_observable, is_always_observable

    # Site location
    location = get_location(data['observatory'])

    coords = SkyCoord(ra=data['RA'] * u.deg, dec=data['Dec'] * u.deg)
    fixed_target = [FixedTarget(coord=coords, name=data['name'])]

    # List of dates of observability
    observabilities = []

    if 'twilight_type' not in data.keys():
        data['twilight_type'] = 'astronomical'

    if data['twilight_type'] == 'civil':
        twilight_constraint = AtNightConstraint.twilight_civil()
    elif data['twilight_type'] == 'nautical':
        twilight_constraint = AtNightConstraint.twilight_nautical()
    else:
        twilight_constraint = AtNightConstraint.twilight_astronomical()

    # Observation constraints
    constraints = [
        AltitudeConstraint(
            float(data['altitude_lower_limit']) * u.deg,
            float(data['altitude_higher_limit']) * u.deg), twilight_constraint
    ]

    for date in data['dates']:

        # time range for transits
        # Always observable for time range
        if len(data['dates'][0]) > 0:

            # If exoplanet transits, check for observability always during transit,
            # if not, check observability *ever* during night
            time_range = Time([date[0], date[1]])

            # Are targets *always* observable in the time range?
            observable = is_always_observable(constraints,
                                              location,
                                              fixed_target,
                                              time_range=time_range)

        # No time range, *ever* observabable during the night
        else:
            observable = is_observable(constraints,
                                       location,
                                       fixed_target,
                                       times=Time(date[0]))

        # Moon location for the observation date
        moon = location.moon_altaz(Time(date[0]))
        moon_separation = moon.separation(coords)

        observabilities.append({
            'observable': str(observable[0]),
            'moon_separation': moon_separation.degree
        })

    return observabilities
Exemplo n.º 27
0
def test_docs_example():
    # Test the example in astroplan/docs/tutorials/constraints.rst
    target_table_string = """# name ra_degrees dec_degrees
    Polaris 37.95456067 89.26410897
    Vega 279.234734787 38.783688956
    Albireo 292.68033548 27.959680072
    Algol 47.042218553 40.955646675
    Rigel 78.634467067 -8.201638365
    Regulus 152.092962438 11.967208776"""

    from astroplan import Observer, FixedTarget
    from astropy.time import Time
    subaru = Observer.at_site("Subaru")
    time_range = Time(["2015-08-01 06:00", "2015-08-01 12:00"])

    # Read in the table of targets
    from astropy.io import ascii
    target_table = ascii.read(target_table_string)

    # Create astroplan.FixedTarget objects for each one in the table
    from astropy.coordinates import SkyCoord
    import astropy.units as u
    targets = [
        FixedTarget(coord=SkyCoord(ra=ra * u.deg, dec=dec * u.deg), name=name)
        for name, ra, dec in target_table
    ]

    from astroplan import Constraint, is_observable
    from astropy.coordinates import Angle

    class VegaSeparationConstraint(Constraint):
        """
        Constraint the separation from Vega
        """
        def __init__(self, min=None, max=None):
            """
            min : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            max : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            """
            self.min = min
            self.max = max

        def compute_constraint(self, times, observer, targets):

            # Vega's coordinate must be non-scalar for the dimensions
            # to work out properly when combined with other constraints which
            # test multiple times
            vega = SkyCoord(ra=[279.23473479] * u.deg,
                            dec=[38.78368896] * u.deg)

            # Calculate separation between target and vega
            vega_separation = Angle(
                [vega.separation(target.coord) for target in targets])

            # If a maximum is specified but no minimum
            if self.min is None and self.max is not None:
                mask = vega_separation < self.max

            # If a minimum is specified but no maximum
            elif self.max is None and self.min is not None:
                mask = self.min < vega_separation

            # If both a minimum and a maximum are specified
            elif self.min is not None and self.max is not None:
                mask = ((self.min < vega_separation) &
                        (vega_separation < self.max))

            # Otherwise, raise an error
            else:
                raise ValueError("No max and/or min specified in "
                                 "VegaSeparationConstraint.")

            # Return an array that is True where the target is observable and
            # False where it is not
            return mask

    constraints = [VegaSeparationConstraint(min=5 * u.deg, max=30 * u.deg)]
    observability = is_observable(constraints,
                                  subaru,
                                  targets,
                                  time_range=time_range)

    assert all(observability == [False, False, True, False, False, False])
Exemplo n.º 28
0
def observability_objects(data):
    """
    Test the observability of a list of objects for a single date

    Parameters
    ----------
    data : POST data format

    data = {
        'observatory' : 'OT',
        'altitude_lower_limit' : '30',
        'altitude_higher_limit' : '90',
        'objects' : [{
                'name' : 'Kelt 8b',
                'RA' : 283.30551667 ,
                'Dec' : 24.12738139,
                'dates' : [
                        ['2020-06-11 00:16:30', '2020-06-11 03:44:26'],
                        ['2020-06-14 06:07:56', '2020-06-14 09:35:53']
                    ]
                },
                {
                    'name' : 'TIC 123456789',
                    'RA' : 13.13055667 ,
                    'Dec' : 24.13912738,
                    'dates' : [
                        ['2020-06-11 23:59:59']
                    ]
                }
            ]
        }

    Returns
    -------
    observability : dict
        Dictionary with the observability and moon distance for all objects

        {'V0879 Cas' : {
                'observability' : 'True', 'moon_separation' : 30.4
            },
        'RU Scl' : {
            'observability' : 'True', 'moon_separation' : 10.8
            }
        }

    """

    import astropy.units as u
    from astroplan import FixedTarget
    from astroplan import (AltitudeConstraint, AtNightConstraint)
    from astroplan import is_observable, is_always_observable

    # Site location
    location = get_location(data['observatory'])

    # dict of observability for each target
    observabilities = {}

    if 'twilight_type' not in data.keys():
        data['twilight_type'] = 'astronomical'

    if data['twilight_type'] == 'civil':
        twilight_constraint = AtNightConstraint.twilight_civil()
    elif data['twilight_type'] == 'nautical':
        twilight_constraint = AtNightConstraint.twilight_nautical()
    else:
        twilight_constraint = AtNightConstraint.twilight_astronomical()

    # Observation constraints
    constraints = [
        AltitudeConstraint(
            float(data['altitude_lower_limit']) * u.deg,
            float(data['altitude_higher_limit']) * u.deg), twilight_constraint
    ]

    for target in data['objects']:

        coords = SkyCoord(ra=target['RA'] * u.deg, dec=target['Dec'] * u.deg)
        fixed_target = [FixedTarget(coord=coords, name=target['name'])]

        observabilities[target['name']] = []

        for date in target['dates']:

            # time range for transits
            # Always observable for time range
            if len(date) > 1:
                # If exoplanet transit, test observability always during transit,
                # if not, test observability *ever* during night
                time_range = Time([date[0], date[1]])

                # Are targets *always* observable in the time range?
                observable = is_always_observable(constraints,
                                                  location,
                                                  fixed_target,
                                                  time_range=time_range)

            # No time range, *ever* observabable during the night
            # Observability is test from sunset to sunrise
            # Default time resolution is 0.5h
            else:
                sunset = location.sun_set_time(Time(date[0]))
                sunrise = location.sun_rise_time(Time(date[0]), 'next')
                time_range = Time([sunset, sunrise])
                observable = is_observable(constraints,
                                           location,
                                           fixed_target,
                                           time_range=time_range)

            # Moon location for the observation date
            moon = location.moon_altaz(Time(date[0]))
            moon_separation = moon.separation(coords)

            observabilities[target['name']].append({
                'observable':
                str(observable[0]),
                'moon_separation':
                moon_separation.degree
            })

    return observabilities
Exemplo n.º 29
0
obstime = midnight + delta_midnight

paranal = astroplan.Observer(paranal_loc, timezone='Etc/GMT-4')

Altcons = astroplan.AltitudeConstraint(min=+30 * u.deg, max=None)
Airmasscons = astroplan.AirmassConstraint(min=None, max=3.0)

Alt_constraints = Altcons.compute_constraint(times=obstime,
                                             observer=paranal,
                                             targets=GJ9827b)
Airmass_constraints = Airmasscons.compute_constraint(times=obstime,
                                                     observer=paranal,
                                                     targets=GJ9827b)

observable = astroplan.is_observable(constraints=[Altcons, Airmasscons],
                                     observer=paranal,
                                     targets=GJ9827b,
                                     times=obstime)

midnight1 = Time('2020-7-13 00:00:00') - utcoffset
midnight2 = Time('2021-1-13 00:00:00') - utcoffset

frame_July13night1 = AltAz(obstime=midnight1 + delta_midnight,
                           location=paranal_loc)
frame_July13night2 = AltAz(obstime=midnight2 + delta_midnight,
                           location=paranal_loc)
GJ9827baltazs_July13night1 = GJ9827b.transform_to(frame_July13night1)
GJ9827baltazs_July13night2 = GJ9827b.transform_to(frame_July13night2)

GJ9827bairmasss_July13night = GJ9827baltazs_July13night1.secz

plt.plot(delta_midnight, GJ9827bairmasss_July13night)
Exemplo n.º 30
0
    print("Target: ", target.name)
    if False:
        print("Posang: ", target.posang)


# constraints = [AltitudeConstraint(10*u.deg, 80*u.deg),
#	       AzimuthConstraint(0*u.deg, 180*u.deg),
#               AirmassConstraint(5), AtNightConstraint.twilight_civil()]
constraints = [AltitudeConstraint(10*u.deg, 80*u.deg),
               AirmassConstraint(5), 
               AzimuthConstraint(0*u.deg, 10*u.deg),	       
               AtNightConstraint.twilight_civil()]

from astroplan import is_observable, is_always_observable, months_observable
# Are targets *ever* observable in the time range?
ever_observable = is_observable(constraints, subaru, targets, time_range=time_range)

# Are targets *always* observable in the time range?
always_observable = is_always_observable(constraints, subaru, targets, time_range=time_range)

# During what months are the targets ever observable?
# best_months = months_observable(constraints, subaru, targets)

import numpy as np
observability_table = Table()
observability_table['targets'] = [target.name for target in targets]
observability_table['ever_observable'] = ever_observable
observability_table['always_observable'] = always_observable
print(observability_table)

Exemplo n.º 31
0
def test_docs_example():
    # Test the example in astroplan/docs/tutorials/constraints.rst
    target_table_string = """# name ra_degrees dec_degrees
    Polaris 37.95456067 89.26410897
    Vega 279.234734787 38.783688956
    Albireo 292.68033548 27.959680072
    Algol 47.042218553 40.955646675
    Rigel 78.634467067 -8.201638365
    Regulus 152.092962438 11.967208776"""

    from astroplan import Observer, FixedTarget
    from astropy.time import Time

    subaru = Observer.at_site("Subaru")
    time_range = Time(["2015-08-01 06:00", "2015-08-01 12:00"])

    # Read in the table of targets
    from astropy.io import ascii

    target_table = ascii.read(target_table_string)

    # Create astroplan.FixedTarget objects for each one in the table
    from astropy.coordinates import SkyCoord
    import astropy.units as u

    targets = [FixedTarget(coord=SkyCoord(ra=ra * u.deg, dec=dec * u.deg), name=name) for name, ra, dec in target_table]

    from astroplan import Constraint, is_observable
    from astropy.coordinates import Angle

    class VegaSeparationConstraint(Constraint):
        """
        Constraint the separation from Vega
        """

        def __init__(self, min=None, max=None):
            """
            min : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            max : `~astropy.units.Quantity` or `None` (optional)
                Minimum acceptable separation between Vega and target. `None`
                indicates no limit.
            """
            self.min = min
            self.max = max

        def compute_constraint(self, times, observer, targets):

            # Vega's coordinate must be non-scalar for the dimensions
            # to work out properly when combined with other constraints which
            # test multiple times
            vega = SkyCoord(ra=[279.23473479] * u.deg, dec=[38.78368896] * u.deg)

            # Calculate separation between target and vega
            vega_separation = Angle([vega.separation(target.coord) for target in targets])

            # If a maximum is specified but no minimum
            if self.min is None and self.max is not None:
                mask = vega_separation < self.max

            # If a minimum is specified but no maximum
            elif self.max is None and self.min is not None:
                mask = self.min < vega_separation

            # If both a minimum and a maximum are specified
            elif self.min is not None and self.max is not None:
                mask = (self.min < vega_separation) & (vega_separation < self.max)

            # Otherwise, raise an error
            else:
                raise ValueError("No max and/or min specified in " "VegaSeparationConstraint.")

            # Return an array that is True where the target is observable and
            # False where it is not
            return mask

    constraints = [VegaSeparationConstraint(min=5 * u.deg, max=30 * u.deg)]
    observability = is_observable(constraints, subaru, targets, time_range=time_range)

    assert all(observability == [False, False, True, False, False, False])
Exemplo n.º 32
0
def create_selection_coumpound_list(session_plan, schedule_form, observer, observation_time, time_from, time_to, tz_info,
                                    page, offset, per_page, sort_by, mag_scale, sort_def):

    global rise_set_cache

    if session_plan.is_anonymous and (schedule_form.obj_source.data is None or schedule_form.obj_source.data == 'WL'):
        schedule_form.obj_source.data = 'M'  # set Messier

    if schedule_form.obj_source.data is None or schedule_form.obj_source.data == 'WL':
        wishlist_subquery = db.session.query(WishListItem.dso_id) \
            .join(WishListItem.wish_list) \
            .filter(WishList.user_id==current_user.id)

        dso_query = DeepskyObject.query \
            .filter(DeepskyObject.id.in_(wishlist_subquery))

    elif schedule_form.obj_source.data.startswith('DL_'):
        dso_list_id = int(schedule_form.obj_source.data[3:])

        dsolist_subquery = db.session.query(DsoListItem.dso_id) \
            .join(DsoListItem.dso_list) \
            .filter(DsoList.id==dso_list_id)

        dso_query = DeepskyObject.query \
            .filter(DeepskyObject.id.in_(dsolist_subquery))
    else:
        dso_query = DeepskyObject.query
        cat_id = Catalogue.get_catalogue_id_by_cat_code(schedule_form.obj_source.data)
        if cat_id:
            dso_query = dso_query.filter_by(catalogue_id=cat_id)

    scheduled_subquery = db.session.query(SessionPlanItem.dso_id) \
        .filter(SessionPlanItem.session_plan_id==session_plan.id)

    # Subtract already scheduled dsos
    dso_query = dso_query.filter(DeepskyObject.id.notin_(scheduled_subquery))

    # Subtract observed dsos
    if not session_plan.is_anonymous and schedule_form.not_observed.data:
        observed_subquery = db.session.query(ObservedListItem.dso_id) \
            .join(ObservedListItem.observed_list) \
            .filter(ObservedList.user_id==current_user.id)
        dso_query = dso_query.filter(DeepskyObject.id.notin_(observed_subquery))
        dso_query = dso_query.filter(or_(DeepskyObject.master_id.is_(None), DeepskyObject.master_id.notin_(observed_subquery)))


    # filter by type
    if schedule_form.dso_type.data and schedule_form.dso_type.data != 'All':
        dso_query = dso_query.filter(DeepskyObject.type==schedule_form.dso_type.data)

    # filter by magnitude limit
    if schedule_form.maglim.data is not None and schedule_form.maglim.data < mag_scale[1]:
        dso_query = dso_query.filter(DeepskyObject.mag<schedule_form.maglim.data)

    # filter by constellation
    if schedule_form.constellation_id.data is not None:
        dso_query = dso_query.filter(DeepskyObject.constellation_id==schedule_form.constellation_id.data)

    order_by_field = None
    if sort_by:
        desc = sort_by[0] == '-'
        sort_by_name = sort_by[1:] if desc else sort_by
        order_by_field = sort_def.get(sort_by_name)
        if order_by_field and desc:
            order_by_field = order_by_field.desc()

    if order_by_field is None:
        order_by_field = DeepskyObject.id

    all_count = dso_query.count()

    if all_count > 500:
        selection_list = dso_query.order_by(order_by_field).limit(per_page).offset(offset).all().copy()
        use_time_filter = False
    else:
        selection_list = dso_query.order_by(order_by_field).all().copy()
        use_time_filter = True

    # filter by rise-set time
    if use_time_filter:
        key_suffix = '/' + str(observer.location.lat) + '/' + str(observer.location.lon) + '/' + observation_time.strftime('%Y-%m-%d')
        index_table = []
        i = 0
        composed_selection_rms_list = []
        to_process_list = []
        for x in selection_list:
            key = str(x.id) + key_suffix
            cached = rise_set_cache.get(key, None)
            if cached is None:
                index_table.append(i)
                composed_selection_rms_list.append(None)
                to_process_list.append((x.ra, x.dec))
            else:
                composed_selection_rms_list.append(cached)
            i += 1

        if to_process_list:
            selection_rms_list = rise_merid_set_up(time_from, time_to, observer, to_process_list)
            for i in range(len(selection_rms_list)):
                index = index_table[i]
                val = selection_rms_list[i]
                composed_selection_rms_list[index] = val
                key = str(selection_list[index].id) + key_suffix
                rise_set_cache[key] = val

        time_filtered_list = []
        i = 0
        for rise_t, merid_t, set_t, is_up in composed_selection_rms_list:
            if is_up or rise_t < time_to or set_t>time_from:
                time_filtered_list.append((selection_list[i], _to_HM_format(rise_t, tz_info), _to_HM_format(merid_t, tz_info), _to_HM_format(set_t, tz_info)))
            i += 1

        # filter by altitude
        if len(time_filtered_list) > 0 and schedule_form.min_altitude.data is not None and schedule_form.min_altitude.data > 0:
            constraints = [AltitudeConstraint(schedule_form.min_altitude.data*u.deg)]
            targets = []
            for item in time_filtered_list:
                dso = item[0]
                target = FixedTarget(coord=SkyCoord(ra=dso.ra * u.rad, dec=dso.dec * u.rad), name=dso.name)
                targets.append(target)
            time_range = Time([time_from, time_to])
            observable_list = is_observable(constraints, observer, targets, time_range=time_range)
            time_filtered_list = [ time_filtered_list[i] for i in range(len(time_filtered_list)) if observable_list[i] ]

        all_count = len(time_filtered_list)
        if offset>=all_count:
            offset = 0
            page = 1
        selection_compound_list = time_filtered_list[offset:offset+per_page]
    else:
        selection_rms_list = rise_merid_set_time_str(observation_time, observer, [ (x.ra, x.dec) for x in selection_list], tz_info)
        selection_compound_list = [ (selection_list[i], *selection_rms_list[i]) for i in range(len(selection_list))]

    return selection_compound_list, page, all_count