def test_angle_array_strs(): h = Angle(hours=array([0.5, nan, -13])) d = Angle(degrees=h._degrees) assert str(h) == '3 values from 00h 30m 00.00s to -13h 00m 00.00s' assert str(d) == '''3 values from 07deg 30' 00.0" to -195deg 00' 00.0"''' with assert_raises(WrongUnitError): h.dstr() d.hstr() assert h.hstr() == d.hstr(warn=False) == [ '00h 30m 00.00s', 'nan', '-13h 00m 00.00s', ] assert d.dstr() == h.dstr(warn=False) == [ '07deg 30\' 00.0"', 'nan', '-195deg 00\' 00.0"', ] empty = Angle(radians=[]) assert str(empty) == 'Angle []' assert empty.hstr(warn=False) == [] assert empty.dstr() == [] assert h.hstr(format='{0} {1} {2} {3} {4} {5}', places=6) == [' 0 30 0 0 6', 'nan', '- 13 0 0 0 6'] assert d.dstr(format='{0} {1} {2} {3} {4} {5}', places=6) == [' 7 30 0 0 6', 'nan', '- 195 0 0 0 6']
def test_angle_array_strs(): assert str(Angle(degrees=np.array([90, 91, 92]))) == ( '''3 values from 90deg 00' 00.0" to 92deg 00' 00.0"''' ) assert str(Angle(hours=np.array([11, 12, 13]))) == ( '''3 values from 11h 00m 00.00s to 13h 00m 00.00s''' )
def _from_comet_dataframe(cls, df, ts): # TODO: rewrite this once skyfield.mpc._mpc_comets() goes live. mu_km_s = GM_dict[10] mu_au_d = mu_km_s / (AU_KM**3) * (DAY_S**2) e = df.e a = df.Perihelion_dist / (1 - e) p = a * (1 - e**2) n = sqrt(mu_au_d / a**3) peri_day = ts.tt(df.Year_of_perihelion, 0, df.Day_of_perihelion) epoch = ts.tt(df.Epoch_year, df.Epoch_month, df.Epoch_day) M = n * (epoch - peri_day) return cls.from_mean_anomaly( p=Distance(au=p), e=e, i=Angle(degrees=df.i), Om=Angle(degrees=df.Node), w=Angle(degrees=df.Peri), M=Angle(radians=M), epoch=epoch, mu_km_s=mu_km_s, center=10, # TODO: infer target SPK-ID from info in dataframe center_name='SUN', target_name=df.Designation_and_name, )
def test_angle_array_strs(): h = Angle(hours=array([11, 12, 13])) d = Angle(degrees=h._degrees) assert str(h) == '3 values from 11h 00m 00.00s to 13h 00m 00.00s' assert str(d) == '''3 values from 165deg 00' 00.0" to 195deg 00' 00.0"''' with assert_raises(WrongUnitError): h.dstr() d.hstr() assert h.hstr() == d.hstr(warn=False) == [ '11h 00m 00.00s', '12h 00m 00.00s', '13h 00m 00.00s', ] assert d.dstr() == h.dstr(warn=False) == [ '165deg 00\' 00.0"', '180deg 00\' 00.0"', '195deg 00\' 00.0"', ] empty = Angle(radians=[]) assert str(empty) == 'Angle []' assert empty.hstr(warn=False) == [] assert empty.dstr() == []
def from_mpcorb_dataframe(cls, df, ts): if 'Number' in df: target = int(df.Number.strip('()')) + 2000000 else: target = None if 'Name' not in df or df.Name == nan: target_name = df.Principal_desig else: target_name = df.Name p = df.a * (1 - df.e**2) return cls.from_mean_anomaly( p=Distance(au=p), e=df.e, i=Angle(degrees=df.i), Om=Angle(degrees=df.Node), w=Angle(degrees=df.Peri), M=Angle(degrees=df.M), epoch=ts.tdb_jd(df.Epoch), mu_km_s=GM_dict[10] + GM_dict.get(target, 0), center=10, target=target, center_name='SUN', target_name=target_name, )
def __init__(self, *args, **kw): '''Initialize an instance of the Minidisk class''' self.points = kw.pop('points', None) #self.p = kw.pop('p', None) if (Minidisk.allow_initial_circle): self.radius = kw.pop('radius', Angle(radians=0.0)) self.center = kw.pop('center', (None, None)) # If not an Angle, then ensure float if (not isinstance(self.radius, skyfield.units.Angle)): self.radius = float(self.radius) if (self.center[0] is not None and not isinstance(self.center[0], skyfield.units.Angle)): self.center = (float(self.center[0]), float(self.center[1])) else: self.radius = Angle(radians=0.0) self.center = (None, None) self.ra = self.center[0] self.dec = self.center[1] if (self.points is None): self.format = None print( 'WARNING: This instance was not created with any points to be fed to Welzl\'s algorithm. If initialized with a center and radius, it will return the same circle with float types. If not, then it will return a bare circle, with no center and a radius of zero.' ) else: if (isinstance(self.points[0], tuple)): self.format = type(self.points[0][0]) else: self.format = type(self.points[0]) print('type is {}'.format(self.format)) self.calc()
def midpoint(p1, p2): '''The midpoint between two celestial coordinates. Given a point as a tuple of either ``(Ra, Dec)`` or ``(Ra, Dec, Dist)``. RA is of Skyfield type Angle, with ``preference='hours'``. Dec is of Skyfield type Angle. Distance is Skyfield type Distance, in AU units. If dist is included, the returned tuple is (Mid_RA, Mid_Dec, Mid_Dist). Otherwise, it is (Mid_RA, Mid_Dec). You can alternatively use ``center`` for multiple points.''' if (not isinstance(p1, tuple) or not isinstance(p2, tuple)): raise ValueError('Can only pass two tuples to this function.') return None mean_ra = (p1[0].radians + p2[0].radians) / 2.0 mean_dec = (p1[1].radians + p2[1].radians) / 2.0 if (len(p1) == 3 and len(p2) == 3): mean_dist = (p1[2].AU + p2[2].AU) / 2.0 return (Angle(radians=mean_ra, preference='hours'), Angle(radians=mean_dec, signed=True), Distance(AU=mean_dist)) else: return (Angle(radians=mean_ra, preference='hours'), Angle(radians=mean_dec, signed=True))
def test_comet(): text = (b' CJ95O010 1997 03 29.6333 0.916241 0.994928 130.6448' b' 283.3593 88.9908 20200224 -2.0 4.0 C/1995 O1 (Hale-Bopp)' b' MPC106342\n') ts = load.timescale() t = ts.utc(2020, 5, 31) eph = load('de421.bsp') e = eph['earth'].at(t) for loader in mpc.load_comets_dataframe, mpc.load_comets_dataframe_slow: df = loader(BytesIO(text)) row = df.iloc[0] k = mpc.comet_orbit(row, ts, GM_SUN) p = e.observe(eph['sun'] + k) ra, dec, distance = p.radec() # The file authorities/mpc-hale-bopp in the repository is the # source of these angles. TODO: can we tighten this bound and # drive it to fractions of an arcsecond? ra_want = Angle(hours=(23, 59, 16.6)) dec_want = Angle(degrees=(-84, 46, 58)) assert abs(ra_want.arcseconds() - ra.arcseconds()) < 2.0 assert abs(dec_want.arcseconds() - dec.arcseconds()) < 0.2 assert abs(distance.au - 43.266) < 0.0005 assert k.target == 'C/1995 O1 (Hale-Bopp)'
def _convert_radec_to_altaz(ra, dec, lon, lat, height, time): """Convert a single position. This is done for easy code sharing with other tools. Skyfield does support arrays of positions. """ load = Loader('.') # Skyfield uses FTP URLs, but FTP doesn't work on Github Actions so # we use alternative HTTP URLs. load.urls['finals2000A.all'] = 'https://datacenter.iers.org/data/9/' load.urls['.bsp'] = [ ('*.bsp', 'https://naif.jpl.nasa.gov/pub/naif/generic_kernels/spk/planets/') ] radec = Star(ra=Angle(degrees=ra), dec=Angle(degrees=dec)) earth = load(EPHEMERIS)['earth'] location = earth + wgs84.latlon(longitude_degrees=lon, latitude_degrees=lat, elevation_m=height * 1000.0) ts = load.timescale(builtin=False) with load.open('finals2000A.all') as f: finals_data = iers.parse_x_y_dut1_from_finals_all(f) iers.install_polar_motion_table(ts, finals_data) obstime = ts.from_astropy(Time(time, scale='utc')) alt, az, _ = location.at(obstime).observe(radec).apparent().altaz( pressure_mbar=0) return dict(az=az.degrees, alt=alt.degrees)
def radec_to_string_short(ra, dec): if ra is not None and dec is not None: sgn, d, m, s = Angle(radians=dec).signed_dms(warn=False) sign = '-' if sgn < 0.0 else '+' str_dec = '%s%02d:%02d:%02d' % (sign, d, m, s) str_ra = '%02d:%02d:%02d' % Angle(radians=ra).hms(warn=False) return str_ra + ' ' + str_dec return ''
def _compute_ayanamsa(time: Time) -> Angle: utc_time = time.utc_datetime() def foo(utc_time_obj): a = -6.92416 + 16.90709 * (utc_time_obj.year * 1e-3) - 0.757371 * ( utc_time_obj.year**2) * 1e-6 b = ((utc_time_obj.month - 1) + utc_time_obj.day / 30) * 1.1574074 * 1e-3 return a + b if len(time.shape) == 0: return Angle(degrees=foo(utc_time)) else: vfunc = np.vectorize(foo) return Angle(degrees=vfunc(utc_time))
def from_dataframe(cls, df, ts): # https://minorplanetcenter.net/iau/info/PackedDates.html # if 'Number' in df: # target = int(df.Number.strip('()')) + 2000000 # else: target = None name = 'foo' # if 'Name' not in df or df.Name == nan: # target_name = df.Principal_desig # else: #target_name = df.Name p = df.semimajor_axis_au.values * (1.0 - df.eccentricity.values**2.0) # TODO: rework the epoch conversion using arrays, if possible, as in # https://stackoverflow.com/questions/49503173/ def n(c): return ord(c) - 48 if c.isdigit() else ord(c) - 55 def d(s): year = 100 * n(s[0]) + int(s[1:3]) month = n(s[3]) day = n(s[4]) return julian_day(year, month, day) epoch_jd = [d(s) for s in df.epoch_packed.values] t = ts.tt_jd(epoch_jd) # TODO: vectorize return cls.from_mean_anomaly( p=Distance(au=p[0]), e=df.eccentricity.values[0], i=Angle(degrees=df.inclination_degrees.values[0]), Om=Angle(degrees=df.longitude_of_ascending_node_degrees.values[0]), w=Angle(degrees=df.argument_of_perihelion_degrees.values[0]), M=Angle(degrees=df.mean_anomaly_degrees.values[0]), epoch=t[0], mu_km_s=GM_dict[10] + GM_dict.get(target, 0), center=10, target=target, center_name='SUN', target_name=name, )
def parse(line): """Return a `Star` build by parsing a Hipparcos catalog entry `line`.""" # See ftp://cdsarc.u-strasbg.fr/cats/I/239/ReadMe star = Star( ra=Angle(degrees=float(line[51:63])), dec=Angle(degrees=float(line[64:76])), ra_mas_per_year=float(line[87:95]), dec_mas_per_year=float(line[96:104]), parallax_mas=float(line[79:86]), names=[('HIP', int(line[8:14]))], ) star._position_au += star._velocity_au_per_d * days distance, dec, ra = to_polar(star._position_au) star.ra = Angle(radians=ra, preference='hours') star.dec = Angle(radians=dec) return star
def parse(line): "DEPRECATED; see :func:`~skyfield.data.hipparcos.load_dataframe() instead." # See ftp://cdsarc.u-strasbg.fr/cats/I/239/ReadMe star = Star( ra=Angle(degrees=float(line[51:63])), dec=Angle(degrees=float(line[64:76])), ra_mas_per_year=float(line[87:95]), dec_mas_per_year=float(line[96:104]), parallax_mas=float(line[79:86]), names=[('HIP', int(line[8:14]))], ) star._position_au += star._velocity_au_per_d * days distance, dec, ra = to_polar(star._position_au) star.ra = Angle(radians=ra, preference='hours') star.dec = Angle(radians=dec) return star
def calc(self): (ra, dec, radius) = make_circle(self.points) if (isinstance( self.format, (type(skyfield.starlib.Star), type(skyfield.units.Angle)))): print('yes! star') self.ra = Angle(radians=ra, preference='hours') self.dec = Angle(radians=dec, signed=True) self.radius = Angle(radians=radius) else: print('no! not angle') self.ra = ra self.dec = dec self.radius = radius self.center = (self.ra, self.dec) return
def objPos(self, t, obj): astrometric = self.loc.at(t).observe(e[obj]) alt, az, d = astrometric.apparent().altaz() if (obj == 'moon'): appDiam = (2*np.arcsin(var.MOON_DIAMETER/(2*d.km)))*(180/np.pi) else: appDiam = (2*np.arcsin(var.SUN_DIAMETER/(2*d.km)))*(180/np.pi) appDia = Angle(degrees=appDiam) return alt, az, astrometric, appDia
def _convert_radec_to_altaz(ra, dec, lon, lat, height, time): """Convert a single position. This is done for easy code sharing with other tools. Skyfield does support arrays of positions. """ radec = Star(ra=Angle(degrees=ra), dec=Angle(degrees=dec)) earth = load(EPHEMERIS)['earth'] location = earth + Topos(longitude_degrees=lon, latitude_degrees=lat, elevation_m=height * 1000.0) ts = load.timescale() obstime = ts.from_astropy(Time(time, scale='utc')) alt, az, _ = location.at(obstime).observe(radec).apparent().altaz(pressure_mbar=0) return dict(az=az.degrees, alt=alt.degrees)
def _compute_tithi_on(self, time: Time) -> Thithi: moon_pos = self._compute_moon_pos(time, False) sun_pos = self._compute_sun_pos(time, False) if len(time.shape) == 0: if moon_pos.degrees < sun_pos.degrees: moon_pos.degrees = moon_pos.degrees + 360. else: mask = moon_pos.degrees < sun_pos.degrees moon_pos.degrees[mask] = moon_pos.degrees[mask] + 360. delta = moon_pos.degrees - sun_pos.degrees return Thithi(Angle(degrees=delta))
def subpoint(self, iterations): """Return the latitude an longitude directly beneath this position. Returns a :class:`~skyfield.toposlib.Topos` whose ``longitude`` and ``latitude`` are those of the point on the Earth's surface directly beneath this position (according to the center of the earth), and whose ``elevation`` is the height of this position above the Earth's center. """ if self.center != 399: # TODO: should an __init__() check this? raise ValueError("you can only ask for the geographic subpoint" " of a position measured from Earth's center") t = self.t xyz_au = einsum('ij...,j...->i...', t.M, self.position.au) lat, lon, elevation_m, self.earth_R = reverse_terra( xyz_au, t.gast, iterations) from skyfield.toposlib import Topos return Topos(latitude=Angle(radians=lat), longitude=Angle(radians=lon), elevation_m=elevation_m)
def _compute_moon_pos(self, time: Time, correct_ayanamsa: bool = True) -> Angle: e = self.earth.at(time) _, moon_pos, _ = e.observe( self.moon).apparent().ecliptic_latlon('date') moon_pos.degrees = moon_pos.degrees % 360 if correct_ayanamsa: ayanamsa = Almanac._compute_ayanamsa(time) moon_pos = Angle(degrees=(moon_pos.degrees - ayanamsa.degrees) % 360) return moon_pos
def test_against_horizons(): # See the following files in the Skyfield repository: # # horizons/ceres-orbital-elements # horizons/ceres-position ts = load.timescale(builtin=True) t = ts.tdb_jd(2458886.500000000) a = 2.768873850275102E+00 # A e = 7.705857791518426E-02 # EC p_au = a * (1 - e**2) # Wikipedia k = KeplerOrbit.from_mean_anomaly( p=Distance(au=p_au), # see above e=e, i=Angle(degrees=2.718528770987308E+01), Om=Angle(degrees=2.336112629072238E+01), w=Angle(degrees=1.328964361683606E+02), M=Angle(degrees=1.382501360489816E+02), epoch=t, #? mu_km_s=None, mu_au_d=2.9591220828559093E-04, center=None, target=None, center_name=None, target_name=None, ) r, v = k._at(t)[:2] sun_au = [ -0.004105894975783999, 0.006739680703224941, 0.002956344702049446, ] horizons_au = [ 1.334875927366032E+00, -2.239607658161781E+00, -1.328895183461897E+00, ] assert max(abs(r + sun_au - horizons_au)) < 2e-15
def position_angle_of(anglepair1, anglepair2): """Return the position angle of one position with respect to another. Each argument should be a tuple whose first two items are :class:`~skyfield.units.Angle` objects, like the tuples returned by :meth:`~skyfield.positionlib.ICRF.radec()`, :meth:`~skyfield.positionlib.ICRF.frame_latlon()`, and :meth:`~skyfield.positionlib.Apparent.altaz()`. If one of the two angle items is signed (if its ``.signed`` attribute is true), then that angle is used as the latitude and the other as the longitude; otherwise the first argument is assumed to be the latitude. If the longitude has a ``.preference`` attribute of ``'hours'``, it is assumed to be a right ascension which is positive towards the east. The position angle returned will be 0 degrees if position #2 is directly north of position #1 on the celestial sphere, 90 degrees if east, 180 if south, and 270 if west. Otherwise, the longitude is assumed to be azimuth, which measures north to east around the horizon. The position angle returned will be 0 degrees if position #2 is directly above position #1 in the sky, 90 degrees to its left, 180 if below, and 270 if to the right. >>> from skyfield.trigonometry import position_angle_of >>> from skyfield.units import Angle >>> a = Angle(degrees=0), Angle(degrees=0) >>> b = Angle(degrees=1), Angle(degrees=1) >>> position_angle_of(a, b) <Angle 315deg 00' 15.7"> """ lat1, lon1 = anglepair1[0], anglepair1[1] if lon1.signed: lat1, lon1 = lon1, lat1 lat2, lon2 = anglepair2[0], anglepair2[1] if lon2.signed: lat2, lon2 = lon2, lat2 lat1 = lat1.radians lon1 = lon1.radians if lon1.preference == 'hours' else -lon1.radians lat2 = lat2.radians lon2 = lon2.radians if lon2.preference == 'hours' else -lon2.radians return Angle(radians=arctan2( sin(lon2 - lon1), cos(lat1) * tan(lat2) - sin(lat1) * cos(lon2 - lon1), ) % tau)
def test_angle_sexagesimal_args(): assert str(Angle(degrees=(90, ))) == '''90deg 00' 00.0"''' assert str(Angle(hours=(12, ))) == '''12h 00m 00.00s''' assert str(Angle(degrees=(90, 15))) == '''90deg 15' 00.0"''' assert str(Angle(hours=(12, 30))) == '''12h 30m 00.00s''' assert str(Angle(degrees=(90, 15, 30))) == '''90deg 15' 30.0"''' assert str(Angle(hours=(12, 30, 15))) == '''12h 30m 15.00s'''
def test_helpful_exceptions(): distance = Distance(1.234) expect = '''\ to use this Distance, ask for its value in a particular unit: distance.au distance.km distance.m''' with assert_raises(UnpackingError) as a: x, y, z = distance assert str(a.exception) == expect with assert_raises(UnpackingError) as a: distance[0] assert str(a.exception) == expect velocity = Velocity(1.234) expect = '''\ to use this Velocity, ask for its value in a particular unit: velocity.au_per_d velocity.km_per_s velocity.m_per_s''' with assert_raises(UnpackingError) as a: x, y, z = velocity assert str(a.exception) == expect with assert_raises(UnpackingError) as a: velocity[0] assert str(a.exception) == expect angle = Angle(radians=1.234) expect = '''\ to use this Angle, ask for its value in a particular unit: angle.degrees angle.hours angle.radians''' with assert_raises(UnpackingError) as a: x, y, z = angle assert str(a.exception) == expect with assert_raises(UnpackingError) as a: angle[0] assert str(a.exception) == expect
def _get_month_start_end(self, start: Time, stop: Time = None) -> Tuple[Time, Month]: # input parameters validation if stop is None: stop = Time(self.time_scale, start.tt + 366.) else: if stop.tt < start.tt: raise ValueError("Stop time should be greater than start time") # first pass compute sun_pos every 6 hours for 1 year tframe = Time( self.time_scale, np.linspace(start.tt, stop.tt, int((stop.tt - start.tt) * 24 / 6))) sun_pos = self._compute_sun_pos(tframe) # convert degrees in increasing order mesha_crossing_idxs = [ x for x in np.argwhere(np.diff(sun_pos.degrees) < 0.).flatten() ] degrees = sun_pos.degrees for n, _ in enumerate(mesha_crossing_idxs): if n + 1 < len(mesha_crossing_idxs): degrees[mesha_crossing_idxs[n] + 1:mesha_crossing_idxs[n + 1]] += 360. * (n + 1) else: degrees[mesha_crossing_idxs[n] + 1:] += 360. * (n + 1) # model as spline interpolation problem y = tframe.tt x = degrees # get time for these crossings x_new = np.arange(np.ceil(x.min() / 30), np.ceil(x.max() / 30) + 1) * 30 interp_model = interpolate.splrep(x, y, s=0) y_new = interpolate.splev(x_new, interp_model, der=0) months = Month(Angle(degrees=x_new % 360)) times = Time(self.time_scale, y_new) return times, months
def _markedStr(theta: Angle, plusChar: str, minusChar: str) -> str: if theta.radians > 0: return f"{theta.dstr()}{plusChar}" alpha = Angle(radians=-theta.radians) return f"{alpha.dstr()}{minusChar}"
def center(positions): '''Calculate the visual center of a list of coordinates. This function can take two kinds of lists of positions. Lists of tuples, or lists of Stars. This may be useful for automatically centering a telescope or for a program that automatically zooms to a location. The first is a list of coordinates in tuples. It looks like ``[(ra0,dec0), (ra1,dec1)]``, where RA and Dec are Skyfield Angle instances. :: import skyfield from skyfield.api import Star, earth, now from skyfield.units import Angle, Distance from numpy import array algol = Star(ra_hours=( 3, 8, 10.1315), dec_degrees=(40, 57, 20.332)) #approximately Algol mizar = Star(ra_hours=(13, 23, 55.5), dec_degrees=(54, 55, 31)) #approximately Mizar vega = Star(ra_hours=(18, 36, 56.33635), dec_degrees=(38, 47, 01.2802)) #approximately Vega stars = [algol, mizar, vega] positions = [] for star in stars: star_pos = earth(now()).observe(star) positions.append(star_pos.radec()) center1 = a.center(positions) Additionally, you can pass it a list of Stars. For example with Alcor, Mizar and Dubhe. :: from skyfield.data import hipparcos stars = [] stars.append(hipparcos.get('65477')) stars.append(hipparcos.get('65378')) stars.append(hipparcos.get('54061')) center3 = center(stars) RA is of Skyfield type Angle, with ``preference='hours'``. Dec is of Skyfield type Angle. Returns a coordinate tuple of right ascension and declination ``(ra,dec)``.''' if (not isinstance(positions, list)): raise ValueError('Must be passed a list.') return None # Average the coordinates to get an unweighted center mean_ra = Angle(hours=0.0).radians mean_dec = Angle(degrees=0.0).radians # Passed list of Stars if (isinstance(positions[0], skyfield.starlib.Star)): for star in positions: mean_ra = mean_ra + star.ra.radians mean_dec = mean_dec + star.dec.radians # Or passed list of position tuples else: for coord in positions: mean_ra = mean_ra + coord[0].radians mean_dec = mean_dec + coord[1].radians mean_ra = mean_ra / len(positions) mean_dec = mean_dec / len(positions) ctr = (Angle(radians=mean_ra, preference='hours'), Angle(radians=mean_dec, signed=True)) return ctr
def import_vic(vic_data_file): """Import data from VIC catalog.""" from sqlalchemy.exc import IntegrityError constellation_at = load_constellation_map() constell_dict = {} for co in Constellation.query.all(): constell_dict[co.iau_code] = co.id row_count = sum(1 for line in open(vic_data_file)) - 1 with open(vic_data_file) as csvfile: reader = csv.DictReader(csvfile, delimiter=';') catalogue_id = Catalogue.get_catalogue_id_by_cat_code('VIC') row_id = 0 try: for row in reader: row_id += 1 progress(row_id, row_count, 'Importing VIC catalogue') dso_name = 'VIC' + str(row_id) c = DeepskyObject.query.filter_by(name = dso_name).first() if c is None: c = DeepskyObject() ra_ang = Angle(hours=tuple(map(float, row['RA'].split(',')))) if len(row['RA']) > 0 else None dec_ang = Angle(degrees=tuple(map(float, row['Dec'].split(',')))) if len(row['Dec']) > 0 else None constellation = constellation_at(position_from_radec(ra_ang.radians / np.pi * 12.0, dec_ang.radians / np.pi * 180.0)) c.name = dso_name c.type = 'AST' c.ra = ra_ang.radians if ra_ang else None c.dec = dec_ang.radians if dec_ang else None c.constellation_id = constell_dict[constellation] if constellation else None c.catalogue_id = catalogue_id c.major_axis = vic2int(row['length']) / 10 * 60.0 c.minor_axis = vic2int(row['width']) / 10 * 60.0 c.position_angle = vic2int(row['orient']) / 10 c.mag = vic2int(row['mag']) / 10 c.surface_bright = vic2int(row['brightness']) / 10 c.hubble_type = None c.c_star_u_mag = None c.c_star_b_mag = None c.c_star_v_mag = None c.identifiers = None c.common_name = row['name'].strip() c.descr = None db.session.add(c) db.session.commit() except KeyError as err: print('\nKey error: {}'.format(err)) db.session.rollback() except IntegrityError as err: print('\nIntegrity error {}'.format(err)) db.session.rollback() print('') # finish on new line
def classicalLongitudeStr(self, symbolic: bool = False) -> str: sign, theta = self.classicalLongitude angle = Angle(degrees=theta) return f"{angle.dstr()} {sign.symbol if symbolic else sign.name}"
def pa(c_ra, c_dec, a_ra, a_dec): c_ra = Angle(hours=c_ra / 15) c_dec = Angle(degrees=c_dec) a_ra = Angle(hours=a_ra / 15) a_dec = Angle(degrees=a_dec) return position_angle_of((c_dec, c_ra), (a_dec, a_ra)).degrees