Exemple #1
0
 def compute_constraint(self, times, observer, targets):
     """
     Computes the observability of the moon given a minimum distance to the moon between self.min_dist (for
     illumination = 0) and self.max_dist (for illumination = 1) by interpolating an intermediate distance from those
     two values following a linear regression.
     @param times: the times to compute the constraint for
     @param observer: the observer to compute the constraint for
     @param targets: the list of targets to compute the constraint for
     @return: the positive mask for target being observable for the given times and observer given the constraint
     is matched
     """
     # removed the location argument here, which causes small <1 deg
     # inaccuracies, but it is needed until astropy PR #5897 is released
     # which should be astropy 1.3.2
     moon = get_moon(times)
     # note to future editors - the order matters here
     # moon.separation(targets) is NOT the same as targets.separation(moon)
     # the former calculates the separation in the frame of the moon coord
     # which is GCRS, and that is what we want.
     moon_separation = moon.separation(targets)
     illumination = moon_illumination(times)
     min_dist = self.min_dist.value + (self.max_dist.value -
                                       self.min_dist.value) * illumination
     mask = min_dist <= moon_separation.degree
     return mask
Exemple #2
0
    def moonlight_veto(self, dt, debug=False):
        """
        Check if the Moon period defined by the rise and set time correspond
        to a situation where the moon is too bright or too close from the
        source.
        If this is the case (too bright or too close), returns True
        (the veto is confirmed).

        """
        too_bright = False
        too_close = False

        # Check moon illumination
        for t in dt:
            moonlight = moon_illumination(Df(t))
            if (moonlight >= self.moon_maxlight):
                too_bright = True
                if (debug):
                    print("Moonlight :", moonlight,
                          " too bright ! -> confirmed")
                break

        # Check distance to source at rise and set
        for t in dt:
            moon_radec = get_moon(Df(t), self.site)
            dist = moon_radec.separation(self.target.coord)
            if dist <= self.moon_mindist:
                too_close = True
                if (debug): print(" Moon Distance : ", dist, "too close !")
                break

        return (too_bright, too_close)
def get_moon_illumination(time):
    """
    Get moon illumination (number from 0 to 1) at a given time
    INPUT:
        time - astropy.time.Time object
    
    OUTPUT:
        moon illumination from 0 to 1
    """
    return moon_illumination(time)
Exemple #4
0
 def previous_obs_func(illum_min, illum_max):
     filt = []
     for p in previous_obs:
         if p.obs_mjd: mjd_prev = p.obs_mjd
         elif p.mjd_requested: mjd_prev = p.mjd_requested
         t_prev = Time(mjd_prev, format='mjd')
         illum_prev = moon_illumination(t_prev)
         if illum_prev >= illum_min and illum_prev <= illum_max:
             filt += [p.photometric_band.name]
         if len(filt) == 2: return filt
     return None
Exemple #5
0
def moon_vis(target):

    day_range = 30
    times = Time([
        str(datetime.datetime.utcnow() + datetime.timedelta(days=delta))
        for delta in np.arange(0, day_range, 0.2)
    ],
                 format='iso',
                 scale='utc')

    obj_pos = SkyCoord(target.ra, target.dec, unit=u.deg)
    moon_pos = get_moon(times)

    separations = moon_pos.separation(obj_pos).deg
    phases = moon_illumination(times)

    distance_color = 'rgb(0, 0, 255)'
    phase_color = 'rgb(255, 0, 0)'
    plot_data = [
        go.Scatter(x=times.mjd - times[0].mjd,
                   y=separations,
                   mode='lines',
                   name='Moon distance (degrees)',
                   line=dict(color=distance_color)),
        go.Scatter(x=times.mjd - times[0].mjd,
                   y=phases,
                   mode='lines',
                   name='Moon phase',
                   yaxis='y2',
                   line=dict(color=phase_color))
    ]
    layout = go.Layout(
        xaxis=dict(title='Days from now'),
        yaxis=dict(range=[0., 180.],
                   tick0=0.,
                   dtick=45.,
                   tickfont=dict(color=distance_color)),
        yaxis2=dict(range=[0., 1.],
                    tick0=0.,
                    dtick=0.25,
                    overlaying='y',
                    side='right',
                    tickfont=dict(color=phase_color)),
        margin=dict(l=20, r=10, b=30, t=40),
        #hovermode='compare',
        width=600,
        height=300,
        autosize=True)
    figure = offline.plot(go.Figure(data=plot_data, layout=layout),
                          output_type='div',
                          show_link=False)

    return {'plot': figure}
def moon_distance(target, day_range=30):
    """
    Renders plot for lunar distance from sidereal target.

    Adapted from Jamison Frost Burke's moon visibility code in Supernova Exchange 2.0, as seen here:
    https://github.com/jfrostburke/snex2/blob/0c1eb184c942cb10f7d54084e081d8ac11700edf/custom_code/templatetags/custom_code_tags.py#L196

    :param target: Target object for which moon distance is calculated
    :type target: tom_targets.models.Target

    :param day_range: Number of days to plot lunar distance
    :type day_range: int
    """
    if target.type != 'SIDEREAL':
        return {'plot': None}

    day_range = 30
    times = Time(
        [str(datetime.utcnow() + timedelta(days=delta)) for delta in np.arange(0, day_range, 0.2)],
        format='iso', scale='utc'
    )

    obj_pos = SkyCoord(target.ra, target.dec, unit=u.deg)
    moon_pos = get_moon(times)

    separations = moon_pos.separation(obj_pos).deg
    phases = moon_illumination(times)

    distance_color = 'rgb(0, 0, 255)'
    phase_color = 'rgb(255, 0, 0)'
    plot_data = [
        go.Scatter(x=times.mjd-times[0].mjd, y=separations, mode='lines', name='Moon distance (degrees)',
                   line=dict(color=distance_color)),
        go.Scatter(x=times.mjd-times[0].mjd, y=phases, mode='lines', name='Moon phase', yaxis='y2',
                   line=dict(color=phase_color))
    ]
    layout = go.Layout(
                xaxis={'title': 'Days from now'},
                yaxis={'range': [0, 180], 'tick0': 0, 'dtick': 45, 'tickfont': {'color': distance_color}},
                yaxis2={'range': [0, 1], 'tick0': 0, 'dtick': 0.25, 'overlaying': 'y', 'side': 'right',
                        'tickfont': {'color': phase_color}},
                margin={'l': 20, 'r': 10, 'b': 30, 't': 40},
                width=600,
                height=300,
                autosize=True
            )
    moon_distance_plot = offline.plot(
        go.Figure(data=plot_data, layout=layout), output_type='div', show_link=False
    )

    return {'plot': moon_distance_plot}
Exemple #7
0
def moonlight_plot(vis, times, ax=None, color="tab:orange"):

    if (ax == None): fig, ax = plt.subplots(figsize=(21, 5))

    with quantity_support():
        ax.plot(times.datetime,
                moon_illumination(times),
                color=color,
                label="Illumination")
        ax.axhline(y=vis.moon_maxlight,
                   color=color,
                   ls=":",
                   label="Max. illumination")

    ax.set_ylabel("Illumination")
    ax.set_ylim(ymin=0, ymax=1.)
    ax.legend(loc="lower right")

    return ax
    def eop(self):

        IERS_A_in_cache()
        # astroplan.get_IERS_A_or_workaround()
        iers.conf.auto_download = False
        iers.conf.auto_max_age = None
        now = Time.now()

        longitude = '78d57m53s'
        latitude = '32d46m44s'
        elevation = 4500 * u.m
        location = EarthLocation.from_geodetic(longitude, latitude, elevation)
        iaohanle = Observer(location=location,
                            timezone='Asia/Kolkata',
                            name="IAO",
                            description="IAO Hanle telescopes")
        iaohanle
        # Calculating the sunset, midnight and sunrise times for our observatory
        sunset_iao = iaohanle.sun_set_time(now, which='nearest')
        eve_twil_iao = iaohanle.twilight_evening_astronomical(now,
                                                              which='nearest')
        midnight_iao = iaohanle.midnight(now, which='next')
        morn_twil_iao = iaohanle.twilight_morning_astronomical(now,
                                                               which='next')
        sunrise_iao = iaohanle.sun_rise_time(now, which='next')
        moon_rise = iaohanle.moon_rise_time(eve_twil_iao, which='nearest')
        moon_set = iaohanle.moon_set_time(now, which='nearest')
        # moon_alt = iaohanle.moon_altaz(now).alt
        # moon_az = iaohanle.moon_altaz(now).az
        #lst_now = iaohanle.local_sidereal_time(now)
        #lst_mid = iaohanle.local_sidereal_time(midnight_iao)
        #print("LST at IAO now is {0:.2f}".format(lst_now))
        #print("LST at IAO at local midnight will be {0:.2f}".format(lst_mid))

        Automation.moon_strength = moon_illumination(midnight_iao)

        observing_time = (morn_twil_iao - eve_twil_iao).to(u.h)
        #print("Total Night hours at IAO tonight  {0:.1f}  ".format(observing_time))

        img = Image.new('RGB', (850, 320), color=(0, 0, 0))
        fnt = ImageFont.truetype(
            '/var/lib/defoma/gs.d/dirs/fonts/DejaVuSerif.ttf', 15)
        d = ImageDraw.Draw(img)
        d.text((10, 11),
               "IAO Hanle Coordinates:   " + str(iaohanle),
               font=fnt,
               fill=(255, 255, 255))

        d.text((10, 71),
               "Moon Illumination Strength          : " +
               str(moon_illumination(midnight_iao)),
               font=fnt,
               fill=(255, 255, 255))
        d.text((10, 101),
               "Sunset                                       : " +
               Time(sunset_iao, out_subfmt='date_hms').iso + " UTC",
               font=fnt,
               fill=(255, 255, 255))
        d.text((10, 131),
               "Astronomical evening twilight : " +
               Time(eve_twil_iao, out_subfmt='date_hms').iso + " UTC",
               font=fnt,
               fill=(255, 255, 255))
        d.text((10, 161),
               "Astronomical morning twilight : " +
               Time(morn_twil_iao, out_subfmt='date_hms').iso + " UTC",
               font=fnt,
               fill=(255, 255, 255))
        d.text((10, 191),
               "Sunrise                                   : " +
               Time(sunrise_iao, out_subfmt='date_hms').iso + " UTC",
               font=fnt,
               fill=(255, 255, 255))
        d.text((10, 221),
               "Moon Rise                    : " +
               Time(moon_rise, out_subfmt='date_hms').iso + " UTC",
               font=fnt,
               fill=(255, 255, 255))

        d.text((10, 251),
               "Moon Set                    : " +
               Time(moon_set, out_subfmt='date_hms').iso + " UTC",
               font=fnt,
               fill=(255, 255, 255))
        d.text((10, 281),
               "Total Astronomical hours tonight                    : " +
               str(observing_time),
               font=fnt,
               fill=(255, 255, 255))
        img.save('tonight.png')
        img.close()

        t_start = eve_twil_iao
        t_end = morn_twil_iao

        # We can turn solar system objects into 'pseudo-fixed' targets to plan observations
        mercury_midnight = FixedTarget(name='Mercury',
                                       coord=get_body('mercury', midnight_iao))
        mercury_midnight.coord
        venus_midnight = FixedTarget(name='Venus',
                                     coord=get_body('venus', midnight_iao))
        venus_midnight.coord

        uranus_midnight = FixedTarget(name='Uranus',
                                      coord=get_body('uranus', midnight_iao))
        uranus_midnight.coord
        neptune_midnight = FixedTarget(name='Neptune',
                                       coord=get_body('neptune', midnight_iao))
        neptune_midnight.coord

        saturn_midnight = FixedTarget(name='Saturn',
                                      coord=get_body('saturn', midnight_iao))
        saturn_midnight.coord

        jupiter_midnight = FixedTarget(name='Jupiter',
                                       coord=get_body('jupiter', midnight_iao))
        jupiter_midnight.coord

        mars_midnight = FixedTarget(name='Mars',
                                    coord=get_body('mars', midnight_iao))
        mars_midnight.coord

        targets = [
            mercury_midnight, venus_midnight, mars_midnight, jupiter_midnight,
            saturn_midnight, uranus_midnight, neptune_midnight
        ]
        targets

        #for target in targets:
        #print(iaohanle.target_rise_time(now, target, which='next', horizon=10 * u.deg).iso)

        # iaohanle.altaz(now, targets[0])

        # print(iaohanle.target_rise_time(now, target, which='next', horizon=10 * u.deg).iso)

        # iaohanle.altaz(now, targets[0])

        times = (t_start - 0.5 * u.h) + (t_end - t_start +
                                         1 * u.h) * np.linspace(0.0, 1.0, 20)
        for target in targets:
            plot_sky(target, iaohanle, times)
        plt.legend(loc=[1.0, 0])
        plt.xlabel('Planets motion tonight')

        # plt.ylim(4,0.5)
        # plt.legend()
        plt.savefig('planets_motion.png')
        plt.close()

        # plt.legend(loc=[1.1,0])

        coords1 = SkyCoord(
            '15h58m3s', '-18d10m0.0s',
            frame='icrs')  # coordinates of Andromeda Galaxy (M32)
        tt1 = FixedTarget(name='Moon', coord=coords1)

        tt1.coord
        t_observe = t_start + (t_end - t_start) * np.linspace(0.0, 1.0, 20)
        plot_sky(tt1, iaohanle, t_observe)
        plt.xlabel('Moon motion tonight')
        plt.savefig('moon_motion.png')
        plt.close()

        if (eve_twil_iao <= now):
            Automation.eve_twilight_flag = 1
            Automation.mor_twilight_flag = 0
            Automation.moon_setting_flag = 0
        elif (morn_twil_iao <= now):
            Automation.eve_twilight_flag = 0
            Automation.mor_twilight_flag = 1
            Automation.moon_setting_flag = 0
        elif (Automation.moon_strength > 0.30):
            if (moon_rise <= now):
                Automation.eve_twilight_flag = 0
                Automation.mor_twilight_flag = 0
                Automation.moon_setting_flag = 1
            elif (moon_set <= now):
                Automation.eve_twilight_flag = 1
                Automation.mor_twilight_flag = 0
                Automation.moon_setting_flag = 0
Exemple #9
0
    def form_valid(self, form):
        response = super(AddSurveyObsFormView, self).form_valid(form)
        if 'hi':  #self.request.is_ajax():
            instance = form.save(commit=False)

            telescope = Telescope.objects.get(name='Pan-STARRS1')
            location = EarthLocation.from_geodetic(telescope.longitude * u.deg,
                                                   telescope.latitude * u.deg,
                                                   telescope.elevation * u.m)
            tel = Observer(location=location, timezone="US/Hawaii")

            m = date_to_mjd(form.cleaned_data['survey_obs_date'])
            time = Time(m, format='mjd')
            sunset_forobs = mjd_to_date(tel.sun_set_time(time, which="next"))
            survey_field_blocks = SurveyFieldMSB.objects.filter(
                name__in=form.cleaned_data['ztf_field_id'])
            #survey_field = SurveyField.objects.filter(ztf_field_id__in=form.cleaned_data['ztf_field_id'])
            for sb in survey_field_blocks:
                for s in sb.survey_fields.all():
                    t = Time(m, format='mjd')
                    illum = moon_illumination(t)

                    # need to see what was observed in the previous obs w/ the same moon illumination
                    # first have to grab the MSB associated with this observation, if it exists
                    # otherwise it's gonna schedule different filters for different pointings

                    previous_msb = SurveyFieldMSB.objects.filter(
                        survey_fields__in=[s])
                    if len(previous_msb):
                        previous_field = previous_msb[0].survey_fields.all()[0]
                        previous_obs = SurveyObservation.objects.filter(survey_field=previous_field).\
                         filter(Q(obs_mjd__lt=m) | Q(mjd_requested__lt=m)).order_by('-obs_mjd').\
                         order_by('-mjd_requested').select_related()
                    else:
                        previous_obs = SurveyObservation.objects.filter(survey_field=s).\
                         filter(Q(obs_mjd__lt=m) | Q(mjd_requested__lt=m)).order_by('-obs_mjd').\
                         order_by('-mjd_requested').select_related()

                    def previous_obs_func(illum_min, illum_max):
                        filt = []
                        for p in previous_obs:
                            if p.obs_mjd: mjd_prev = p.obs_mjd
                            elif p.mjd_requested: mjd_prev = p.mjd_requested
                            t_prev = Time(mjd_prev, format='mjd')
                            illum_prev = moon_illumination(t_prev)
                            if illum_prev >= illum_min and illum_prev <= illum_max:
                                filt += [p.photometric_band.name]
                            if len(filt) == 2: return filt
                        return None

                    if s.field_id.lower().startswith('virgo'):
                        if illum < 0.66:
                            filt = previous_obs_func(0, 0.66)
                            if filt is None: band1name, band2name = 'g', 'r'
                            elif 'r' in filt: band1name, band2name = 'g', 'i'
                            elif 'i' in filt: band1name, band2name = 'g', 'z'
                            else: band1name, band2name = 'g', 'r'
                        else:
                            filt = previous_obs_func(0.66, 1)
                            if filt is None or 'z' in filt:
                                band1name, band2name = 'r', 'i'
                            else:
                                band1name, band2name = 'r', 'z'
                    else:
                        if illum < 0.33:
                            filt = previous_obs_func(0, 0.33)
                            if filt is None or 'i' in filt:
                                band1name, band2name = 'g', 'r'
                            else:
                                band1name, band2name = 'g', 'i'
                        elif illum < 0.66:
                            filt = previous_obs_func(0.33, 0.66)
                            if filt is None or 'z' in filt:
                                band1name, band2name = 'g', 'i'
                            else:
                                band1name, band2name = 'g', 'z'
                        else:
                            filt = previous_obs_func(0.66, 1)
                            if filt is None or 'z' in filt:
                                band1name, band2name = 'r', 'i'
                            else:
                                band1name, band2name = 'r', 'z'

                    band1 = PhotometricBand.objects.filter(
                        name=band1name, instrument__name=s.instrument.name)[0]
                    band2 = PhotometricBand.objects.filter(
                        name=band2name, instrument__name=s.instrument.name)[0]

                    SurveyObservation.objects.create(
                        mjd_requested=date_to_mjd(sunset_forobs),
                        survey_field=s,
                        status=TaskStatus.objects.get(name='Requested'),
                        exposure_time=27,
                        photometric_band=band1,
                        created_by=self.request.user,
                        modified_by=self.request.user)
                    SurveyObservation.objects.create(
                        mjd_requested=date_to_mjd(sunset_forobs),
                        survey_field=s,
                        status=TaskStatus.objects.get(name='Requested'),
                        exposure_time=27,
                        photometric_band=band2,
                        created_by=self.request.user,
                        modified_by=self.request.user)

            # for key,value in form.cleaned_data.items():
            data = {
                'message': "Successfully submitted form data.",
            }
            return JsonResponse(data)
        else:
            return response
Exemple #10
0
    def form_valid(self, form):
        response = super(AddSurveyFieldFormView, self).form_valid(form)
        if self.request.is_ajax():
            instance = form.save(commit=False)
            instance.created_by = self.request.user
            instance.modified_by = self.request.user
            instance.obs_group = ObservationGroup.objects.get(name='YSE')
            instance.width_deg = 3.3
            instance.height_deg = 3.3
            instance.first_mjd = date_to_mjd(form.cleaned_data['valid_start'])
            instance.last_mjd = date_to_mjd(form.cleaned_data['valid_stop'])
            instance.ra_cen, instance.dec_cen = coordstr_to_decimal(
                form.cleaned_data['coord'])

            instance.save()  #update_fields=['created_by','modified_by']

            print(form.cleaned_data)

            # clear out the conflicting SurveyObservationTasks
            # danger!
            obs_requests = SurveyObservation.objects.\
                  filter(survey_field__field_id=instance.field_id).\
                  filter(mjd_requested__range=(instance.first_mjd,
                       instance.last_mjd))
            obs_requests.delete()

            # use the SurveyField to populate the SurveyObservationTask list
            # rules: follow cad
            #import pdb; pdb.set_trace()
            mjd = np.arange(instance.first_mjd, instance.last_mjd,
                            instance.cadence)
            #if len(mjd) > 1: import pdb; pdb.set_trace()
            for i, m in enumerate(mjd):
                t = Time(m, format='mjd')
                illum = moon_illumination(t)
                if illum < 0.33:
                    if i % 2: band1name, band2name = 'g', 'r'
                    else: band1name, band2name = 'g', 'i'
                elif illum < 0.66:
                    if i % 2: band1name, band2name = 'g', 'i'
                    else: band1name, band2name = 'g', 'z'
                else:
                    if i % 2: band1name, band2name = 'r', 'i'
                    else: band1name, band2name = 'r', 'z'

                band1 = PhotometricBand.objects.filter(
                    name=band1name,
                    instrument__name=instance.instrument.name)[0]
                band2 = PhotometricBand.objects.filter(
                    name=band2name,
                    instrument__name=instance.instrument.name)[0]
                SurveyObservation.objects.create(
                    mjd_requested=m,
                    survey_field=instance,
                    status=TaskStatus.objects.get(name='Requested'),
                    exposure_time=27,
                    photometric_band=band1,
                    created_by=self.request.user,
                    modified_by=self.request.user)
                SurveyObservation.objects.create(
                    mjd_requested=m,
                    survey_field=instance,
                    status=TaskStatus.objects.get(name='Requested'),
                    exposure_time=27,
                    photometric_band=band2,
                    created_by=self.request.user,
                    modified_by=self.request.user)

            # for key,value in form.cleaned_data.items():
            data = {
                'message': "Successfully submitted form data.",
            }
            return JsonResponse(data)
        else:
            return response
Exemple #11
0
def airmass(ra=0.,
            dec=0.,
            obs='apo',
            date='2019-10-01',
            name='object',
            plot=False,
            tz='US/Mountain'):
    """  Get airmass table for specified object position, observatory, date
    """

    # set the site
    site = Observer.at_site(obs, timezone=tz)

    # set the objects
    if type(ra) is float:
        obj = FixedTarget(name=name,
                          coord=SkyCoord(str(ra) + 'd',
                                         str(dec) + 'd'))
    else:
        obj = FixedTarget(name=name, coord=SkyCoord(ra + 'h', dec + 'd'))

    time = Time('{:s} 00:00:00'.format(date),
                scale='utc',
                location=(site.location.lon, site.location.lat),
                precision=0)
    sunset = site.sun_set_time(time)
    civil = site.twilight_evening_civil(time)
    nautical = site.twilight_evening_nautical(time)
    astronomical = site.twilight_evening_astronomical(time)
    for t in [sunset, civil, nautical, astronomical]:
        t.format = 'isot'
        t.precision = 0
    print('Observatory: ', obs)
    print('Sunset: ', sunset)
    print('Civil twilight: ', civil)
    print('Nautical twilight: ', nautical)
    print('Astronomical twilight: ', astronomical)

    # loop over all UTC hours for this date (would prefer local!)
    print('{:8s}{:8s}{:8s}{:8s}{:8s}{:9s}{:8s}{:8s} {:16s}{:20s}'.format(
        'Local', 'UT', 'LST', 'HA', 'Airmass', 'ParAng', 'Phase', 'Moon Alt',
        'Moon RA', 'Moon DEC'))
    for hr in np.arange(24):
        time = Time('{:s} {:d}:00:00'.format(date, hr),
                    scale='utc',
                    location=(site.location.lon, site.location.lat),
                    precision=0)
        sun = get_sun(time)
        if site.sun_altaz(time).alt.value > 10: continue

        moon = get_moon(time)

        val = site.altaz(time, obj).secz
        if val < 0:
            airmass = '     ...'
        else:
            airmass = '{:8.2f}'.format(val)
        val = site.moon_altaz(time).alt.value
        if val < 0:
            moonalt = '     ...'
        else:
            moonalt = '{:8.2f}'.format(val)
        lst = time.sidereal_time('mean').hms
        ha = site.target_hour_angle(time, obj)
        ha.wrap_angle = 180 * units.deg
        local = site.astropy_time_to_datetime(time)
        print(
            '{:02d}:{:02d}  {:02d}:{:02d}  {:02d}:{:02d} {:3d}:{:02d} {:8s} {:8.2f} {:8.2f} {:8s} {:s} {:s}'
            .format(
                local.hour,
                local.minute,
                time.datetime.hour,
                time.datetime.minute,
                int(round(lst[0])),
                int(round(lst[1])),
                int(round(ha.hms[0])),
                int(abs(round(ha.hms[1]))),
                airmass,
                #site.altaz(time,obj).secz,
                site.parallactic_angle(time, obj).deg,
                astroplan.moon_illumination(time),
                moonalt,
                str(moon.ra.to_string(units.hour)),
                str(moon.dec)))

    if plot:
        fig, ax = plt.subplots(2, 1)
        fig.subplots_adjust(hspace=0.001)

        plot_airmass(obj, site, time, ax=ax[0])
        plot_parallactic(obj, site, time, ax=ax[1])
Exemple #12
0
                                       dec=those_ten[i][1],
                                       unit=(u.hourangle, u.deg))))
    newOutput = observability_table(
        cons,
        kitt,
        newFixedTargs,
        time_range=Time(["2018-05-15 00:01", "2018-05-31 23:59"]))
    return [output, newOutput]


print(most_obs(10)[0])
print("\n ------------------ \n")
print(most_obs(10)[1])

# We can change it to whatever, obviously

moon_ang1 = moon_illumination(Time(['2018-04-15']))
moon_ang2 = moon_illumination(Time(['2018-04-30']))
# I changed the function here so now the variables are poorly named but I'm leaving it to build character

mrt1 = Time(kitt.moon_rise_time(Time(['2018-04-15']), 'nearest'),
            format='iso')[0]
mst1 = Time(kitt.moon_set_time(Time(['2018-04-15']), 'nearest'),
            format='iso')[0]
mrt2 = Time(kitt.moon_rise_time(Time(['2018-04-30']), 'nearest'),
            format='iso')[0]
mst2 = Time(kitt.moon_set_time(Time(['2018-04-30']), 'nearest'),
            format='iso')[0]

#print("moon illumination begins at: " + str(moon_ang1) + " and ends with: " + str(moon_ang2))
#print("In the middle of the month, the moon rises at " + str(mrt1) + " and sets at " + str(mst1) + ". At the end of the month, the moon rises at " + str(mrt2) + " and sets at " + str(mst2) + ".")
Exemple #13
0
def create_observation_observables(object_id,
                                   object_dir,
                                   since,
                                   name,
                                   epoch,
                                   epoch_low_err,
                                   epoch_up_err,
                                   period,
                                   period_low_err,
                                   period_up_err,
                                   duration,
                                   observatories_file,
                                   timezone,
                                   latitude,
                                   longitude,
                                   altitude,
                                   max_days,
                                   min_altitude,
                                   moon_min_dist,
                                   moon_max_dist,
                                   transit_fraction,
                                   baseline,
                                   error_alert=True):
    """

    @param object_id: the candidate id
    @param object_dir: the candidate directory
    @param since: starting plan date
    @param name: the name given to the candidate
    @param epoch: the candidate epoch
    @param epoch_low_err: the candidate epoch's lower error
    @param epoch_up_err: the candidate epoch's upper error
    @param period: the candidate period
    @param period_low_err: the candidate period's lower error
    @param period_up_err: the candidate period's upper error
    @param duration: the candidate duration
    @param observatories_file: the file containing the observatories file (csv format)
    @param timezone: the timezone of the observatory (if observatories_file=None)
    @param latitude: the latitude of the observatory (if observatories_file=None)
    @param longitude: the longitude of the observatory (if observatories_file=None)
    @param altitude: the altitude of the observatory (if observatories_file=None)
    @param max_days: the maximum number of days to compute the observables
    @param min_altitude: the minimum altitude of the target above the horizon
    @param moon_min_dist: the minimum moon distance for moon illumination = 0
    @param moon_max_dist: the minimum moon distance for moon illumination = 1
    @param transit_fraction: the minimum transit observability (0.25 for at least ingress/egress, 0.5 for ingress/egress
    + midtime, 1 for ingress, egress and midtime).
    @param baseline: the required baseline in hours.
    @param: error_alert: whether to create the alert date to signal imprecise observations
    @return: the generated data and target folders
    """
    if observatories_file is not None:
        observatories_df = pd.read_csv(observatories_file, comment='#')
    else:
        observatories_df = pd.DataFrame(
            columns=['name', 'tz', 'lat', 'long', 'alt'])
        observatories_df = observatories_df.append("Obs-1", timezone, latitude,
                                                   longitude, altitude)
    # TODO probably convert epoch to proper JD
    mission, mission_prefix, id_int = LcBuilder().parse_object_info(object_id)
    if mission == "TESS":
        primary_eclipse_time = Time(epoch, format='btjd', scale="tdb")
    elif mission == "Kepler" or mission == "K2":
        primary_eclipse_time = Time(epoch, format='bkjd', scale="tdb")
    else:
        primary_eclipse_time = Time(epoch, format='jd')
    target = FixedTarget(SkyCoord(coords, unit=(u.deg, u.deg)))
    n_transits = int(max_days // period)
    system = EclipsingSystem(primary_eclipse_time=primary_eclipse_time,
                             orbital_period=u.Quantity(period, unit="d"),
                             duration=u.Quantity(duration, unit="h"),
                             name=name)
    observables_df = pd.DataFrame(columns=[
        'observatory', 'timezone', 'start_obs', 'end_obs', 'ingress', 'egress',
        'midtime', "midtime_up_err_h", "midtime_low_err_h", 'twilight_evening',
        'twilight_morning', 'observable', 'moon_phase', 'moon_dist'
    ])
    plan_dir = object_dir + "/plan"
    images_dir = plan_dir + "/images"
    if os.path.exists(plan_dir):
        shutil.rmtree(plan_dir, ignore_errors=True)
    os.mkdir(plan_dir)
    if os.path.exists(images_dir):
        shutil.rmtree(images_dir, ignore_errors=True)
    os.mkdir(images_dir)
    alert_date = None
    for index, observatory_row in observatories_df.iterrows():
        observer_site = Observer(latitude=observatory_row["lat"],
                                 longitude=observatory_row["lon"],
                                 elevation=u.Quantity(observatory_row["alt"],
                                                      unit="m"))
        midtransit_times = system.next_primary_eclipse_time(
            since, n_eclipses=n_transits)
        ingress_egress_times = system.next_primary_ingress_egress_time(
            since, n_eclipses=n_transits)
        constraints = [
            AtNightConstraint.twilight_nautical(),
            AltitudeConstraint(min=min_altitude * u.deg),
            MoonIlluminationSeparationConstraint(
                min_dist=moon_min_dist * u.deg, max_dist=moon_max_dist * u.deg)
        ]
        moon_for_midtransit_times = get_moon(midtransit_times)
        moon_dist_midtransit_times = moon_for_midtransit_times.separation(
            SkyCoord(star_df.iloc[0]["ra"], star_df.iloc[0]["dec"],
                     unit="deg"))
        moon_phase_midtransit_times = np.round(
            astroplan.moon_illumination(midtransit_times), 2)
        transits_since_epoch = np.round(
            (midtransit_times - primary_eclipse_time).jd / period)
        midtransit_time_low_err = np.round(
            (((transits_since_epoch * period_low_err)**2 + epoch_low_err**2)
             **(1 / 2)) * 24, 2)
        midtransit_time_up_err = np.round(
            (((transits_since_epoch * period_up_err)**2 + epoch_up_err**2)
             **(1 / 2)) * 24, 2)
        low_err_delta = TimeDelta(midtransit_time_low_err * 3600, format='sec')
        up_err_delta = TimeDelta(midtransit_time_up_err * 3600, format='sec')
        i = 0
        for midtransit_time in midtransit_times:
            twilight_evening = observer_site.twilight_evening_nautical(
                midtransit_time)
            twilight_morning = observer_site.twilight_morning_nautical(
                midtransit_time)
            ingress = ingress_egress_times[i][0]
            egress = ingress_egress_times[i][1]
            lowest_ingress = ingress - low_err_delta[i]
            highest_egress = egress + up_err_delta[i]
            if error_alert and (highest_egress - lowest_ingress).jd > 0.33:
                alert_date = midtransit_time if (alert_date is None) or (
                    alert_date is not None
                    and alert_date >= midtransit_time) else alert_date
                break
            else:
                baseline_low = lowest_ingress - baseline * u.hour
                baseline_up = highest_egress + baseline * u.hour
                transit_times = baseline_low + (
                    baseline_up - baseline_low) * np.linspace(0, 1, 100)
                observable_transit_times = astroplan.is_event_observable(
                    constraints, observer_site, target, times=transit_times)[0]
                observable_transit_times_true = np.argwhere(
                    observable_transit_times)
                observable = len(observable_transit_times_true) / 100
                if observable < transit_fraction:
                    i = i + 1
                    continue
                start_obs = transit_times[observable_transit_times_true[0]][0]
                end_obs = transit_times[observable_transit_times_true[
                    len(observable_transit_times_true) - 1]][0]
                start_plot = baseline_low
                end_plot = baseline_up
                if twilight_evening > start_obs:
                    start_obs = twilight_evening
                if twilight_morning < end_obs:
                    end_obs = twilight_morning
            moon_dist = round(moon_dist_midtransit_times[i].degree)
            moon_phase = moon_phase_midtransit_times[i]
            # TODO get is_event_observable for several parts of the transit (ideally each 5 mins) to get the proper observable percent. Also with baseline
            if observatory_row["tz"] is not None and not np.isnan(
                    observatory_row["tz"]):
                observer_timezone = observatory_row["tz"]
            else:
                observer_timezone = get_offset(observatory_row["lat"],
                                               observatory_row["lon"],
                                               midtransit_time.datetime)
            observables_df = observables_df.append(
                {
                    "observatory":
                    observatory_row["name"],
                    "timezone":
                    observer_timezone,
                    "ingress":
                    ingress.isot,
                    "start_obs":
                    start_obs.isot,
                    "end_obs":
                    end_obs.isot,
                    "egress":
                    egress.isot,
                    "midtime":
                    midtransit_time.isot,
                    "midtime_up_err_h":
                    str(int(midtransit_time_up_err[i] // 1)) + ":" +
                    str(int(midtransit_time_up_err[i] % 1 * 60)).zfill(2),
                    "midtime_low_err_h":
                    str(int(midtransit_time_low_err[i] // 1)) + ":" +
                    str(int(midtransit_time_low_err[i] % 1 * 60)).zfill(2),
                    "twilight_evening":
                    twilight_evening.isot,
                    "twilight_morning":
                    twilight_morning.isot,
                    "observable":
                    observable,
                    "moon_phase":
                    moon_phase,
                    "moon_dist":
                    moon_dist
                },
                ignore_index=True)
            plot_time = start_plot + (end_plot - start_plot) * np.linspace(
                0, 1, 100)
            plt.tick_params(labelsize=6)
            airmass_ax = plot_airmass(target,
                                      observer_site,
                                      plot_time,
                                      brightness_shading=False,
                                      altitude_yaxis=True)
            airmass_ax.axvspan(twilight_morning.plot_date,
                               end_plot.plot_date,
                               color='white')
            airmass_ax.axvspan(start_plot.plot_date,
                               twilight_evening.plot_date,
                               color='white')
            airmass_ax.axvspan(twilight_evening.plot_date,
                               twilight_morning.plot_date,
                               color='gray')
            airmass_ax.axhspan(1. / np.cos(np.radians(90 - min_altitude)),
                               5.0,
                               color='green')
            airmass_ax.get_figure().gca().set_title("")
            airmass_ax.get_figure().gca().set_xlabel("")
            airmass_ax.get_figure().gca().set_ylabel("")
            airmass_ax.set_xlabel("")
            airmass_ax.set_ylabel("")
            xticks = []
            xticks_labels = []
            xticks.append(start_obs.plot_date)
            hour_min_sec_arr = start_obs.isot.split("T")[1].split(":")
            xticks_labels.append("T1_" + hour_min_sec_arr[0] + ":" +
                                 hour_min_sec_arr[1])
            plt.axvline(x=start_obs.plot_date, color="violet")
            xticks.append(end_obs.plot_date)
            hour_min_sec_arr = end_obs.isot.split("T")[1].split(":")
            xticks_labels.append("T1_" + hour_min_sec_arr[0] + ":" +
                                 hour_min_sec_arr[1])
            plt.axvline(x=end_obs.plot_date, color="violet")
            if start_plot < lowest_ingress < end_plot:
                xticks.append(lowest_ingress.plot_date)
                hour_min_sec_arr = lowest_ingress.isot.split("T")[1].split(":")
                xticks_labels.append("T1_" + hour_min_sec_arr[0] + ":" +
                                     hour_min_sec_arr[1])
                plt.axvline(x=lowest_ingress.plot_date, color="red")
            if start_plot < ingress < end_plot:
                xticks.append(ingress.plot_date)
                hour_min_sec_arr = ingress.isot.split("T")[1].split(":")
                xticks_labels.append("T1_" + hour_min_sec_arr[0] + ":" +
                                     hour_min_sec_arr[1])
                plt.axvline(x=ingress.plot_date, color="orange")
            if start_plot < midtransit_time < end_plot:
                xticks.append(midtransit_time.plot_date)
                hour_min_sec_arr = midtransit_time.isot.split("T")[1].split(
                    ":")
                xticks_labels.append("T0_" + hour_min_sec_arr[0] + ":" +
                                     hour_min_sec_arr[1])
                plt.axvline(x=midtransit_time.plot_date, color="black")
            if start_plot < egress < end_plot:
                xticks.append(egress.plot_date)
                hour_min_sec_arr = egress.isot.split("T")[1].split(":")
                xticks_labels.append("T4_" + hour_min_sec_arr[0] + ":" +
                                     hour_min_sec_arr[1])
                plt.axvline(x=egress.plot_date, color="orange")
            if start_plot < highest_egress < end_plot:
                xticks.append(highest_egress.plot_date)
                hour_min_sec_arr = highest_egress.isot.split("T")[1].split(":")
                xticks_labels.append("T4_" + hour_min_sec_arr[0] + ":" +
                                     hour_min_sec_arr[1])
                plt.axvline(x=highest_egress.plot_date, color="red")
            airmass_ax.xaxis.set_tick_params(labelsize=5)
            airmass_ax.set_xticks([])
            airmass_ax.set_xticklabels([])
            degrees_ax = get_twin(airmass_ax)
            degrees_ax.yaxis.set_tick_params(labelsize=6)
            degrees_ax.set_yticks([1., 1.55572383, 2.])
            degrees_ax.set_yticklabels([90, 50, 30])
            fig = matplotlib.pyplot.gcf()
            fig.set_size_inches(1.25, 0.75)
            plt.savefig(plan_dir + "/images/" + observatory_row["name"] + "_" +
                        str(midtransit_time.isot)[:-4] + ".png",
                        bbox_inches='tight')
            plt.close()
            i = i + 1
    observables_df = observables_df.sort_values(["midtime", "observatory"],
                                                ascending=True)
    observables_df.to_csv(plan_dir + "/observation_plan.csv", index=False)
    print("Observation plan created in directory: " + object_dir)
    return observatories_df, observables_df, alert_date, plan_dir, images_dir
def plot_target_radecs_and_moon(ras,
                                decs,
                                names,
                                time,
                                savename=None,
                                savefolder=""):
    """
    Plot and RA DEC plot of targets and Moon

    INPUT:
        ras - ras (degrees) of target stars
        decs - decs (degrees) of target stars
        names - names of target stars
        time - astropy time
        savename - output name of .png file to save the plot.

    EXAMPLE:
        time = Time("2018-02-25 00:00:00")
        plot_target_radecs_and_moon(ras,decs,df_all.SIMBADNAME.values,time)
    """

    mcd = Observer.at_site('McDonald Observatory')

    sun_rise = mcd.sun_rise_time(time, which="nearest")
    sun_set = mcd.sun_set_time(time, which="nearest")
    times = sun_set + (sun_rise - sun_set) * np.linspace(0, 1, 20)
    moon = get_moon(times)

    illum = moon_illumination(
        times[10])  # get moon illumination at middle of the time array

    fig, ax = plt.subplots(figsize=(12, 8), dpi=200)
    ax.plot(ras, decs, "k.")
    ax.plot(moon.ra.value, moon.dec.value, label="Moon")
    ax.plot(moon.ra.value[0],
            moon.dec.value[0],
            color="red",
            marker="o",
            label="Moon: Sunset",
            lw=0)
    ax.plot(moon.ra.value[-1],
            moon.dec.value[-1],
            color="orange",
            marker="o",
            label="Moon: Sunrise",
            lw=0)

    for i, name in enumerate(names):
        ax.text(ras[i], decs[i], name)

    ax.legend(loc="upper left")
    ax.minorticks_on()
    ax.grid(lw=0.5, alpha=0.3)
    ax.set_xlabel("RA (deg)")
    ax.set_ylabel("Dec (deg)")
    title = "Targets and Moon on {} UT".format(str(time)[0:10])
    title += "\n Sunset: {}".format(str(sun_set.iso))
    title += "\n Sunrise: {}".format(str(sun_rise.iso))
    title += "\n Moon illumination: {:0.3}%".format(illum * 100)

    ax.set_title(title)
    if savename is None:
        savename = "moondistance_" + str(time)[0:10] + ".png"
    savename = savefolder + savename
    fig.savefig(savename)
    print("saved to {}".format(savename))
def analyze_day(search_around, obs, FO, localtz, args, verbose=True):
    sunset = obs.sun_set_time(search_around, which='nearest')
    delta = (search_around.to_datetime() - sunset.to_datetime()).total_seconds()
    if abs(delta) > 12*60*60:
        sunset = obs.sun_set_time(search_around+TimeDelta(1800, format='sec'), which='nearest')
        delta = (search_around.to_datetime() - sunset.to_datetime()).total_seconds()
    if abs(delta) > 12*60*60:
        print('WARNING Delta = {:.0f} seconds'.format(delta))
    local_sunset = sunset.to_datetime(localtz)
    dusk = obs.twilight_evening_astronomical(sunset, which='next')
    local_dusk = dusk.to_datetime(localtz)
    description = [f"Sunset @ {local_sunset.strftime('%I:%M %p')}",
                   f"18 deg Twilight @ {local_dusk.strftime('%I:%M %p')}"]

    # Moon from astroplan
    illum = moon_illumination(sunset)
    mooncoord = moon.get_moon(sunset).transform_to(FK5())
    mooncoord.location = obs.location
    moonalt = mooncoord.transform_to(AltAz()).alt
    moon_down = moonalt.value < 0.
    moon_rise = obs.moon_rise_time(sunset)
    moon_set = obs.moon_set_time(sunset)

    ttup = local_sunset.timetuple()
    endtime = dt(ttup.tm_year, ttup.tm_mon, ttup.tm_mday, 23, 59, 00, 0, localtz)

    print(f"Sunset at {local_sunset.strftime('%Y/%m/%d %H:%M')}")#\
#           f" (Moon down: {moon_down} {moonalt:.1f} {illum*100:.1f}%)")

    if illum > 0.9:
        print(f"  Moon is bright ({illum*100:.0f}%)")
    elif illum < 0.1:
        title = f"Moon is dark ({illum*100:.0f}%)"
        description.append(f"Moon is dark ({illum*100:.0f}%)")
        ics_entry(FO, title, local_sunset-2*tdelta(seconds=60.*60.*1.), endtime,
                  description, verbose=True)
    elif moon_down is True:
        local_moon_rise = moon_rise.to_datetime(localtz)
        time_to_rise = moon_rise - dusk
        if time_to_rise.sec < 0:
            print('  Moon rises during twilight')
        if time_to_rise.sec*u.second > args.dark_time*u.hour:
            title = f"Dark until {local_moon_rise.strftime('%I:%M %p')} ({time_to_rise.sec/3600:.1f} hr)"
            description.append(f"{illum*100:.0f}% Moon Rises @ {local_moon_rise.strftime('%I:%M %p')}")
            ics_entry(FO, title, local_sunset-2*tdelta(seconds=60.*60.*1.), endtime,
                      description, verbose=True)
        elif time_to_rise.sec > 0:
            print(f"  Moon rises at {local_moon_rise.strftime('%Y/%m/%d %H:%M')},"\
                  f" only {time_to_rise.sec/3600:.1f} hours after dusk.")
    else:
        local_moon_set = moon_set.to_datetime(localtz)
        time_to_wait = moon_set - dusk
        if time_to_wait.sec < 0:
            print("  Moon sets during dusk.")
            title = f'Dark ({illum*100.:.0f}% moon)'
            ics_entry(FO, title, local_sunset-2*tdelta(seconds=60.*60.*1.), endtime,
                      description, verbose=True)
        elif time_to_wait.sec*u.second < args.wait_time*u.hour:
            title = f"Dark after {local_moon_set.strftime('%I:%M %p')}"
            description.append(f"{illum*100:.0f}% Moon Sets @ {local_moon_set.strftime('%I:%M %p')}")
            ics_entry(FO, title, local_sunset-2*tdelta(seconds=60.*60.*1.), endtime,
                      description, verbose=True)
        else:
            print(f"  {illum*100:.0f}% Moon is up in the evening")


    return sunset
Exemple #16
0
def moon_distance(target,
                  day_range=30,
                  width=600,
                  height=400,
                  background=None,
                  label_color=None,
                  grid=True):
    """
    Renders plot for lunar distance from sidereal target.

    Adapted from Jamison Frost Burke's moon visibility code in Supernova Exchange 2.0, as seen here:
    https://github.com/jfrostburke/snex2/blob/0c1eb184c942cb10f7d54084e081d8ac11700edf/custom_code/templatetags/custom_code_tags.py#L196

    :param target: Target object for which moon distance is calculated
    :type target: tom_targets.models.Target

    :param day_range: Number of days to plot lunar distance
    :type day_range: int

    :param width: Width of generated plot
    :type width: int

    :param height: Height of generated plot
    :type width: int

    :param background: Color of the background of generated plot. Can be rgba or hex string.
    :type background: str

    :param label_color: Color of labels/tick labels. Can be rgba or hex string.
    :type label_color: str

    :param grid: Whether to show grid lines.
    :type grid: bool
    """
    if target.type != 'SIDEREAL':
        return {'plot': None}

    day_range = 30
    times = Time([
        str(datetime.utcnow() + timedelta(days=delta))
        for delta in np.arange(0, day_range, 0.2)
    ],
                 format='iso',
                 scale='utc')

    obj_pos = SkyCoord(target.ra, target.dec, unit=u.deg)
    moon_pos = get_moon(times)

    separations = moon_pos.separation(obj_pos).deg
    phases = moon_illumination(times)

    distance_color = 'rgb(0, 0, 255)'
    phase_color = 'rgb(255, 0, 0)'
    plot_data = [
        go.Scatter(x=times.mjd - times[0].mjd,
                   y=separations,
                   mode='lines',
                   name='Moon distance (degrees)',
                   line=dict(color=distance_color)),
        go.Scatter(x=times.mjd - times[0].mjd,
                   y=phases,
                   mode='lines',
                   name='Moon phase',
                   yaxis='y2',
                   line=dict(color=phase_color))
    ]
    layout = go.Layout(xaxis={'title': 'Days from now'},
                       yaxis={
                           'range': [0, 180],
                           'tick0': 0,
                           'dtick': 45,
                           'tickfont': {
                               'color': distance_color
                           }
                       },
                       yaxis2={
                           'range': [0, 1],
                           'tick0': 0,
                           'dtick': 0.25,
                           'overlaying': 'y',
                           'side': 'right',
                           'tickfont': {
                               'color': phase_color
                           }
                       },
                       margin={
                           'l': 20,
                           'r': 10,
                           'b': 30,
                           't': 40
                       },
                       width=width,
                       height=height,
                       autosize=True,
                       paper_bgcolor=background,
                       plot_bgcolor=background)
    layout.legend.font.color = label_color
    fig = go.Figure(data=plot_data, layout=layout)
    fig.update_yaxes(showgrid=grid,
                     color=label_color,
                     showline=True,
                     linecolor=label_color,
                     mirror=True)
    fig.update_xaxes(showgrid=grid,
                     color=label_color,
                     showline=True,
                     linecolor=label_color,
                     mirror=True)
    moon_distance_plot = offline.plot(fig, output_type='div', show_link=False)

    return {'plot': moon_distance_plot}