Ejemplo n.º 1
0
def select_stars(magnitude, constellation=None, ra_range=None, dec_range=None):
    """
    Select a set of stars brighter than the given magnitude, based on coordinate range and/or constellation membership.

    Args:
        magnitude (float): The maximum magnitude to include
        constellation (string): The constellation name; if given, only stars from that constellation are returned
        ra_range (tuple): The range (min_ra, max_ra) of right ascension to include, in degrees
        dec_range (tuple): The range (min_dec, max_dec) of declination to include, in degrees

    Returns:
        list: All Star objects in the database matching the criteria
    """

    # Build the query
    q = """SELECT * FROM skymap_stars WHERE magnitude<={0}""".format(magnitude)

    if constellation:
        q += """ AND constellation='{0}'""".format(constellation)

    if ra_range:
        min_ra, max_ra = ra_range
        min_ra = ensure_angle_range(min_ra)
        max_ra = ensure_angle_range(max_ra)

        if min_ra < max_ra:
            q += """ AND right_ascension>={0} AND right_ascension<={1}""".format(
                min_ra, max_ra
            )
        elif max_ra < min_ra:
            q += """ AND (right_ascension>={0} OR right_ascension<={1})""".format(
                min_ra, max_ra
            )
        else:
            # min_ra is equal to max_ra: full circle: no ra limits
            pass

    if dec_range:
        min_dec, max_dec = dec_range

        if (
            min_dec < -90
            or min_dec > 90
            or max_dec < -90
            or max_dec > 90
            or max_dec <= min_dec
        ):
            raise ValueError("Illegal DEC range!")
        q += """ AND declination>={0} AND declination<={1}""".format(min_dec, max_dec)

    # Order stars from brightest to weakest so displaying them is easier
    q += """ ORDER BY magnitude ASC"""

    # Execute the query
    db = SkyMapDatabase()
    rows = db.query(q)
    result = [Star(row) for row in rows]
    db.close()

    return result
Ejemplo n.º 2
0
 def inside_coordinate_range(self, sp):
     ra = ensure_angle_range(
         sp.ra.degree, 0.5 * (self.min_longitude + self.max_longitude))
     dec = ensure_angle_range(sp.dec.degree,
                              0.5 * (self.min_latitude + self.max_latitude))
     longitude_inside = self.min_longitude <= ra <= self.max_longitude
     latitude_inside = self.min_latitude <= dec <= self.max_latitude
     return longitude_inside and latitude_inside
Ejemplo n.º 3
0
 def tickangle2(self):
     if hasattr(self._curve, "angle"):
         return ensure_angle_range(self._curve.angle)
     try:
         p = self._curve.p2 - self._curve.center
     except AttributeError:
         return None
     if self.config.center_latitude < 0:
         return ensure_angle_range(p.angle + 90)
     return ensure_angle_range(p.angle - 90)
Ejemplo n.º 4
0
    def backproject(self, point):
        rho = self.origin.distance(point)
        theta = ensure_angle_range(math.degrees(math.atan2(point.y, point.x)))

        if self.reverse_polar_direction:
            theta *= -1

        longitude = ensure_angle_range(theta + self.center_longitude)
        latitude = (-rho * self.reference_scale / self.horizontal_stretch +
                    self.center_latitude)
        return SkyCoordDeg(longitude, latitude)
Ejemplo n.º 5
0
    def inverse_project(self, point):
        rho = self.origin.distance(point)
        theta = ensure_angle_range(math.degrees(math.atan2(point.y, point.x)))

        if self.reverse_polar_direction:
            longitude = ensure_angle_range(-theta + self.reference_longitude)
        else:
            longitude = ensure_angle_range(theta + self.reference_longitude)

        return SphericalPoint(
            longitude, -rho * self.reference_scale + self.origin_latitude)
Ejemplo n.º 6
0
def ecliptic_to_equatorial(p, epoch=REFERENCE_EPOCH):
    """Returns the equatorial coordinates for the given point in ecliptic coordinates.

    Equations taken from:
    Practical Astronomy with your Calculator or Spreadsheet
    Peter Duffett-Smith and Jonathan Zwart
    Cambridge University Press, 2011
    Paragraph 27 (page 51)

    Only used to draw the ecliptic.
    """
    eps = math.radians(obliquity_of_the_ecliptic(REFERENCE_EPOCH))
    ceps = math.cos(eps)
    seps = math.sin(eps)

    l = math.radians(p.ra.degree)
    b = math.radians(p.dec.degree)

    longitude = math.degrees(
        math.atan2(math.sin(l) * ceps - math.tan(b) * seps, math.cos(l)))
    latitude = math.degrees(
        math.asin(math.sin(b) * ceps + math.cos(b) * seps * math.sin(l)))

    # Precess to the current epoch
    pc = PrecessionCalculator(REFERENCE_EPOCH, epoch)
    longitude, latitude = pc.precess(longitude, latitude)

    return SkyCoordDeg(ensure_angle_range(longitude), latitude)
Ejemplo n.º 7
0
def get_constellation_boundaries_for_area(min_longitude,
                                          max_longitude,
                                          min_latitude,
                                          max_latitude,
                                          epoch=REFERENCE_EPOCH):
    # Convert longitude to 0-360 values
    # TODO: sometimes boundaries cross the map but have no vertices within the map area + margin and are not plotted
    min_longitude = ensure_angle_range(min_longitude)
    max_longitude = ensure_angle_range(max_longitude)
    if max_longitude == min_longitude:
        max_longitude += 360

    db = SkyMapDatabase()
    q = "SELECT * FROM skymap_constellation_boundaries WHERE"

    if min_longitude < max_longitude:
        q += " ((ra1>={0} AND ra1<={1}".format(min_longitude, max_longitude)
    else:
        q += " (((ra1>={0} OR ra1<={1})".format(min_longitude, max_longitude)

    q += " AND dec1>={0} AND dec1<={1}) OR".format(min_latitude, max_latitude)

    if min_longitude < max_longitude:
        q += " (ra2>={0} AND ra2<={1}".format(min_longitude, max_longitude)
    else:
        q += " ((ra2>={0} OR ra2<={1})".format(min_longitude, max_longitude)

    q += " AND dec2>={0} AND dec2<={1}))".format(min_latitude, max_latitude)

    res = db.query(q)

    result = []
    pc = PrecessionCalculator(CONST_BOUND_EPOCH, epoch)
    for row in res:
        p1 = SphericalPoint(row['ra1'], row['dec1'])
        p2 = SphericalPoint(row['ra2'], row['dec2'])
        e = BoundaryEdge(p1, p2)
        e.precess(pc)
        result.append(e)

    db.close()
    return result
Ejemplo n.º 8
0
 def draw_meridians(self, origin_offsets={}, include_endpoint=True):
     start_longitude = self.gridline_factory.meridian_tick_interval * math.ceil(
         self.min_longitude / self.gridline_factory.meridian_tick_interval)
     if include_endpoint:
         stop_longitude = self.max_longitude + 0.5 * self.gridline_factory.meridian_tick_interval
     else:
         stop_longitude = self.max_longitude
     for longitude in numpy.arange(
             start_longitude, stop_longitude,
             self.gridline_factory.meridian_tick_interval):
         self.draw_meridian(ensure_angle_range(longitude), origin_offsets)
Ejemplo n.º 9
0
def get_constellation_boundaries_for_area(
    min_longitude, max_longitude, min_latitude, max_latitude, epoch="J2000.0"
):
    # Convert longitude to 0-360 values
    # TODO: sometimes boundaries cross the map but have no vertices within the map area + margin and are not plotted
    min_longitude = ensure_angle_range(min_longitude)
    max_longitude = ensure_angle_range(max_longitude)
    if max_longitude == min_longitude:
        max_longitude += 360

    db = SkyMapDatabase()
    q = "SELECT * FROM skymap_constellation_boundaries WHERE"

    if min_longitude < max_longitude:
        q += " ((ra1>={0} AND ra1<={1}".format(min_longitude, max_longitude)
    else:
        q += " (((ra1>={0} OR ra1<={1})".format(min_longitude, max_longitude)

    q += " AND dec1>={0} AND dec1<={1}) OR".format(min_latitude, max_latitude)

    if min_longitude < max_longitude:
        q += " (ra2>={0} AND ra2<={1}".format(min_longitude, max_longitude)
    else:
        q += " ((ra2>={0} OR ra2<={1})".format(min_longitude, max_longitude)

    q += " AND dec2>={0} AND dec2<={1}))".format(min_latitude, max_latitude)

    res = db.query(q)

    result = []
    for row in res:
        p1 = SkyCoordDeg(row["ra1"], row["dec1"])
        p2 = SkyCoordDeg(row["ra2"], row["dec2"])
        e = ConstellationBoundaryEdge(p1, p2)
        e.precess()
        result.append(e)

    db.close()
    return result
Ejemplo n.º 10
0
 def _latitude(self, longitude):
     longitude = ensure_angle_range(longitude)
     if longitude < self.LONGITUDES[self.frame][0]:
         i = -1
         long1 = self.LONGITUDES[self.frame][-1] - 360.0
         long2 = self.LONGITUDES[self.frame][0]
     elif longitude > self.LONGITUDES[self.frame][-1]:
         i = -1
         long1 = self.LONGITUDES[self.frame][-1]
         long2 = self.LONGITUDES[self.frame][0] + 360
     else:
         i = [x > longitude
              for x in self.LONGITUDES[self.frame]].index(True) - 1
         long1 = self.LONGITUDES[self.frame][i]
         long2 = self.LONGITUDES[self.frame][i + 1]
     lat1 = self.LATITUDES[self.frame][i]
     lat2 = self.LATITUDES[self.frame][i + 1]
     return lat1 + (lat2 - lat1) * (longitude - long1) / (long2 - long1)
Ejemplo n.º 11
0
def galactic_to_equatorial(p, epoch=REFERENCE_EPOCH):
    """Returns the equatorial coordinates for the given point in galactic coordinates.

    Equations taken from:
    Practical Astronomy with your Calculator or Spreadsheet
    Peter Duffett-Smith and Jonathan Zwart
    Cambridge University Press, 2011
    Paragraph 30 (page 58)

    Only used to draw the galactic equator.
    """

    l = math.radians(p.ra.degree)
    b = math.radians(p.dec.degree)

    # Get the longitude and latitude of the north galactic pole
    ngp = galactic_pole(GALACTIC_NORTH_POLE_EPOCH)
    pl = math.radians(ngp.ra.degree)
    pb = math.radians(ngp.dec.degree)

    # Get the galactic longitude offset
    l0 = math.radians(GALACTIC_LONGITUDE_NORTH_CELESTIAL_POLE - 90.0)

    # Determine the equatorial
    longitude = math.degrees(
        math.atan2(
            math.cos(b) * math.cos(l - l0),
            (math.sin(b) * math.cos(pb) -
             math.cos(b) * math.sin(pb) * math.sin(l - l0)),
        ) + pl)

    latitude = math.degrees(
        math.asin(
            math.cos(b) * math.cos(pb) * math.sin(l - l0) +
            math.sin(b) * math.sin(pb)))

    # Precess to the current epoch
    pc = PrecessionCalculator(GALACTIC_NORTH_POLE_EPOCH, epoch)
    longitude, latitude = pc.precess(longitude, latitude)

    return SkyCoordDeg(ensure_angle_range(longitude), latitude)
Ejemplo n.º 12
0
 def reduce_longitude(self, longitude):
     return ensure_angle_range(longitude, self.center_longitude)
Ejemplo n.º 13
0
                        poles=True)
        m.draw_galactic(linewidth=GALACTIC_LINEWIDTH,
                        tickinterval=1,
                        dashed=GALACTIC_DASH_PATTERN,
                        poles=True)

    # Legend
    rightlegend(f, chart_number, 0, 360, 84, 90)
    f.render(os.path.join(OUTPUT_FOLDER, "{:02}B.pdf".format(chart_number)),
             open=False)

    # North conic maps
    for conic in CONICS:
        n = 360 / abs(conic['longitude_step'])
        for i in range(n):
            center_longitude = ensure_angle_range(i * conic['longitude_step'])
            chart_number += 1

            # Left page
            chart_side = 'left'
            f, m = conic_map(chart_number, chart_side, center_longitude,
                             center_longitude + conic['longitude_range'],
                             conic['min_latitude'], conic['max_latitude'],
                             conic['meridian_interval'], conic['offset'])

            m.draw_meridians()
            m.draw_parallels()
            with m.clip(m.clipping_path):
                m.draw_constellations(linewidth=0.3)
                m.draw_ecliptic(linewidth=ECLIPTIC_LINEWIDTH,
                                tickinterval=1,
Ejemplo n.º 14
0
 def tickangle1(self):
     return ensure_angle_range(self._curve.angle - 180)
Ejemplo n.º 15
0
 def reduce_longitude(self, longitude):
     """Return the longitude within +/- 180 degrees from the center longitude."""
     return ensure_angle_range(longitude, self.center_longitude)
Ejemplo n.º 16
0
 def tickangle2(self):
     return ensure_angle_range(self._curve.angle)
Ejemplo n.º 17
0
 def labelangle2(self):
     if self.config.flip_labels:
         return ensure_angle_range(self.tickangle2 + 90)
     return ensure_angle_range(self.tickangle2 - 90)
Ejemplo n.º 18
0
 def labelangle1(self):
     return ensure_angle_range(self.tickangle1)
Ejemplo n.º 19
0
 def labelangle2(self):
     return ensure_angle_range(self.tickangle2 + 180)
Ejemplo n.º 20
0
    def parallels(self):
        config = self.config.parallel_config
        interval = config.tick_interval
        current_latitude = math.ceil(self.min_latitude / interval) * interval

        # Internal ticks and labels
        internal_longitude = self.config.center_longitude
        if self.config.internal_label_longitude is not None:
            internal_longitude = self.config.internal_label_longitude

        internal_meridian = self.projection.meridian(internal_longitude,
                                                     self.min_latitude,
                                                     self.max_latitude)
        internal_tickangle = internal_meridian.angle - 90
        if internal_tickangle < 0:
            internal_tickangle += 180

        while current_latitude <= self.max_latitude:
            # print(f"Parallel at {current_latitude}")
            parallel = self.projection.parallel(current_latitude,
                                                self.min_longitude,
                                                self.max_longitude)

            internal_point = self.projection.project(
                SkyCoordDeg(internal_longitude, current_latitude))
            if not self.clipper.point_inside(internal_point):
                internal_point = None

            if self.clip_at_border:
                parallel_parts, borders = self.clipper.clip(parallel)
                for p, b in zip(parallel_parts, borders):
                    yield Parallel(
                        current_latitude,
                        p,
                        b,
                        internal_point,
                        internal_tickangle,
                        config,
                    )
            else:
                if isinstance(parallel, Circle) and ensure_angle_range(
                        self.min_longitude) != ensure_angle_range(
                            self.max_longitude):
                    # Construct the arc from the endpoints
                    p1 = (self.projection.project(
                        SkyCoordDeg(self.min_longitude, current_latitude)) -
                          parallel.center)
                    p2 = (self.projection.project(
                        SkyCoordDeg(self.max_longitude, current_latitude)) -
                          parallel.center)
                    parallel = Arc(parallel.center, parallel.radius, p1.angle,
                                   p2.angle)

                yield Parallel(
                    current_latitude,
                    parallel,
                    ["right", "left"],
                    internal_point,
                    internal_tickangle,
                    config,
                )
            current_latitude += interval
Ejemplo n.º 21
0
 def reduce_longitude(self, longitude):
     return ensure_angle_range(longitude, self.reference_longitude)