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
def get_milky_way_curve(id): db = SkyMapDatabase() q = "SELECT * FROM milkyway WHERE curve_id={0} ORDER BY id ASC".format(id) result = db.query(q) curve = [] for row in result: curve.append(SphericalPoint(row['ra'], row['dec'])) if curve[0] == curve[-1]: curve = curve[:-1] db.close() return curve
def build_label_database(): db = SkyMapDatabase() db.drop_table("skymap_labels") # Create table db.commit_query("""CREATE TABLE skymap_labels ( label_id INT PRIMARY KEY, label_text TEXT, fontsize TEXT, width REAL, height REAL)""") stars = [ Star(r) for r in db.query( """SELECT * FROM skymap_stars WHERE proper_name is not null""") ] p = Point(0, 0) i = 0 nstars = len(stars) for n, s in enumerate(stars): sys.stdout.write("\r{}%".format(int(round(100 * n / float(nstars))))) sys.stdout.flush() if not s.proper_name.strip() and not s.identifier_string.strip(): continue if s.proper_name: i += 1 if db.query_one( """SELECT * FROM skymap_labels WHERE label_text="{}" AND fontsize="{}" """ .format(s.proper_name, "tiny")) is None: l = Label(p, s.proper_name, fontsize="tiny", render_size=True) size = l.size db.commit_query( """INSERT INTO skymap_labels VALUES ({}, "{}", "{}", {}, {})""" .format(i, s.proper_name, "tiny", size[0], size[1])) if s.identifier_string: i += 1 if db.query_one( """SELECT * FROM skymap_labels WHERE label_text="{}" AND fontsize="{}" """ .format(s.identifier_string, "tiny")) is None: l = Label(p, s.identifier_string.strip(), fontsize="tiny", render_size=True) size = l.size db.commit_query( """INSERT INTO skymap_labels VALUES ({}, "{}", "{}", {}, {})""" .format(i, s.identifier_string, "tiny", size[0], size[1])) db.close()
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
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
newn = int(1.0 * len(l) / n + 0.5) for i in xrange(0, n - 1): yield l[i * newn:i * newn + newn] yield l[n * newn - newn:] if __name__ == "__main__": #build_star_database() nprocs = 100 # Optimum seems to be around 40: must have something to do with the database I suppose n = nprocs * 500 criterion = 100 db = SkyMapDatabase() stars = db.query( """SELECT id, right_ascension, declination FROM skymap_stars LIMIT {}""" .format(n)) print len(stars) procs = [] t1 = time.time() for i, l in enumerate(chunks(stars, nprocs)): print len(l) p = Process(target=find_multiples, args=(l, criterion), name="Chunk #{}".format(i + 1)) procs.append(p) p.start() for p in procs:
def build_constellation_boundary_database(): print print "Building constellation boundary database" db = SkyMapDatabase() db.drop_table("skymap_constellation_boundaries") db.create_table("skymap_constellation_boundaries", ["ra1", "dec1", "ra2", "dec2"], [float, float, float, float]) edges = [] rows = db.query("""SELECT * FROM cst_bound_constbnd""") print "Creating raw edges" prev_point = None nrecords = len(rows) next_id = 1 for i, row in enumerate(rows): sys.stdout.write("\r{0:.1f}%".format(i * 100.0 / (nrecords - 1))) sys.stdout.flush() if not row['adj']: prev_point = None ra = 15.0 * row['RAhr'] dec = row['DEdeg'] point = SphericalPoint(ra, dec) if prev_point is not None: e = BoundaryEdge(prev_point, point) if e not in edges: edges.append(e) next_id += 1 prev_point = point print print "Connecting edges" n = 0 nrecords = len(edges) * (len(edges) - 1) / 2 for i, e1 in enumerate(edges): for e2 in edges[i + 1:]: sys.stdout.write("\r{0:.1f}%".format(n * 100.0 / (nrecords - 1))) sys.stdout.flush() n += 1 if e1 == e2: continue e1.connect(e2) print print "Building extended edges" new_edges = [] nrecords = len(edges) for i, e in enumerate(edges): sys.stdout.write("\r{0:.1f}%".format(i * 100.0 / (nrecords - 1))) sys.stdout.flush() new_edge = e.extended_edge if new_edge not in new_edges: new_edges.append(new_edge) print nrecords = len(new_edges) print "Loading {} edges to database".format(nrecords) for i, e in enumerate(new_edges): sys.stdout.write("\r{0:.1f}%".format(i * 100.0 / (nrecords - 1))) sys.stdout.flush() db.insert_row("skymap_constellation_boundaries", ["ra1", "dec1", "ra2", "dec2"], [e.p1.ra, e.p1.dec, e.p2.ra, e.p2.dec])