예제 #1
0
파일: model.py 프로젝트: B-Rich/python-sgp4
    def propagate(self, year, month=1, day=1, hour=0, minute=0, second=0.0):
        """Return a position and velocity vector for a given date and time."""

        j = jday(year, month, day, hour, minute, second)
        m = (j - self.jdsatepoch) * minutes_per_day
        r, v = sgp4(self, m)
        return r, v
예제 #2
0
    def propagate(self, year, month=1, day=1, hour=0, minute=0, second=0.0):
        """Return a position and velocity vector for a given date and time."""

        j = jday(year, month, day, hour, minute, second)
        m = (j - self.jdsatepoch) * minutes_per_day
        r, v = sgp4(self, m)
        return r, v
예제 #3
0
    def __make_jday_list(self,
                         start_epoch=datetime.datetime.today(),
                         propagate_range=10,
                         delta_t=1,
                         julian_date=False):
        """Make datetime and julian day list.

        Args:
            start_epoch (:obj:datetime): Epoch when SGP4 propagation start.
            propagate_range (int): SGP4 propagation period in seconds.
            telta_t (int): SGP4 propagation interval in seconds.

        Returns:
            tuple: datetime list and julian day list.
        """
        if julian_date == True:
            date_list = [
                x for x in self.__drange(start_epoch, propagate_range, delta_t)
            ]
            jdays = date_list
        else:
            # make datetime list
            date_list = [
                start_epoch + datetime.timedelta(seconds=x)
                for x in range(0, propagate_range, delta_t)
            ]
            # make julian day list using jday function in sgp4.ext
            jdays = [
                jday(j.year, j.month, j.day, j.hour, j.minute, j.second)
                for j in date_list
            ]

        return date_list, jdays
예제 #4
0
def calcTg(date):

    jdut1 = jday(date.year, date.month, date.day, date.hour, date.minute,
                 date.second)
    Tg = _gstime(jdut1)

    return Tg
예제 #5
0
def VMS_Time2Julian(reportdate, format='%Y%m%d%H%M%S'):
    tFormat = format  #"%d-%b-%Y %H:%M:%S"
    reportdate = str(reportdate)
    try:  #see if it is a list
        for i in repodatdate:
            a = time.strptime(i, tFormat)
            aJul = (jday(a.tm_year, a.tm_mon, a.tm_mday, a.tm_hour, a.tm_min,
                         a.tm_sec))

            try:
                out.append(aJul)
            except:
                out = [aJul]
        return out
    except:  #a single shot
        a = time.strptime(reportdate, tFormat)
        return jday(a.tm_year, a.tm_mon, a.tm_mday, a.tm_hour, a.tm_min,
                    a.tm_sec)
예제 #6
0
    def time_calc_julianDateFromUtc(self):
        #def jday(year, mon, day, hr, minute, sec):
        self._julianDate = sgp4_ext.jday(
            self._utcTime.year, self._utcTime.month, self._utcTime.day,
            self._utcTime.hour, self._utcTime.minute,
            self._utcTime.second + self._utcTime.microsecond * 1e-6)

        # CALCULATING JULIAN CENTURIES SINCE EPOCH J2000
        #   julianische jahrhunderte ephemeridenzeit seit der epoche J2000
        self._julianCentJ2000 = (self._julianDate - 2451545.0) / 36525.0
예제 #7
0
 def init_date(self):
     if self.epoch_yr < 57:
         year = self.epoch_yr + 2000
     else:
         year = self.epoch_yr + 1900
     mon, day, hr, minute, sec = days2mdhms(year, self.epoch_day)
     sec_whole, sec_frac = divmod(sec, 1.0)
     self.date = datetime(year, mon, day, hr, minute, int(sec_whole),
                          int(sec_frac * 1000000.0 // 1.0), timezone.utc)
     self.timestamp = int(time.mktime(self.date.timetuple()))
     self.jdate = jday(year, mon, day, hr, minute, sec)
예제 #8
0
    def derived_values(self):
        """ Calculate values which are determined from TLE parameters """
        self.epoch_string = self.epoch_datetime.isoformat(
            timespec='microseconds')

        (year, month, day, hour, minute,
         second) = self.epoch_datetime.timetuple()[:6]
        microseconds = int(self.epoch_datetime.strftime('%f'))
        sec_with_microseconds = second + microseconds / 1.0E6

        self.jdsatepoch = jday(year, month, day, hour, minute,
                               sec_with_microseconds)
        self.jdSGP4epoch = self.jdsatepoch - 2433281.5

        self.inclination_radians = radians(self.inclination_degrees)
        self.raan_radians = radians(self.raan_degrees)
        self.arg_perigee_radians = radians(self.arg_perigee_degrees)
        self.mean_anomaly_radians = radians(self.mean_anomaly_degrees)
        self.mean_motion_radians_per_second = 2 * pi * self.mean_motion_orbits_per_day / 86400

        xpdotp = 1440.0 / (2.0 * pi)  #  229.1831180523293
        self.mean_motion_radians_per_minute = self.mean_motion_orbits_per_day / xpdotp

        if (self.designation and not self._id_launch_year):
            try:
                self._id_launch_year = int(self.designation[2:4])
                if (self._id_launch_year >= 57):
                    self._id_launch_year = 1900 + self._id_launch_year
                elif (self._id_launch_year < 57):
                    self._id_launch_year = 2000 + self._id_launch_year
            except ValueError:
                self._id_launch_year = None
        if (self.designation and not self._id_launch_num):
            try:
                self._id_launch_num = int(self.designation[5:8])
            except ValueError:
                self._id_launch_num = None
        if (self.designation and not self._id_launch_piece_letter):
            self._id_launch_piece_letter = self.designation[8:].strip()

        self.period = 2 * pi / (self.mean_motion_radians_per_second
                                )  # In seconds
        self.semi_major_axis = pow(TruSatellite._GEsqrt /
                                   self.mean_motion_radians_per_second,
                                   2 / 3)  # in km
        self.perigee = self.semi_major_axis * (
            1 - self.eccentricity) - TruSatellite._XKMPER  # in km
        if (self.perigee < 0):
            log.warning("{}: Perigee {:0f} intersects the Earth.".format(
                self._tle_source_filename, self.perigee))

        self.apogee = self.semi_major_axis * (
            1 + self.eccentricity) - TruSatellite._XKMPER  # in km
예제 #9
0
    def render(self, t1, t2, odata_list):
        if (len(odata_list) == 0) or (t2 <= t1):
            return []

        next_odata = odata_list[0]
        next_time, next_jtime = next_odata.timestamp, next_odata.jdate

        dt1 = datetime.fromtimestamp(t1, timezone.utc)
        dt2 = datetime.fromtimestamp(t2, timezone.utc)
        jt1 = jday(dt1.year, dt1.month, dt1.day,
                   dt1.hour, dt1.minute, dt1.second)
        jt2 = jday(dt2.year, dt2.month, dt2.day,
                   dt2.hour, dt2.minute, dt2.second)

        self.set_steps(next_odata.no)
        self.line_list = []

        if (next_time < t1) or (next_time > t2):
            self.render_border(t1, t2, jt1, jt2, next_odata)
            return self.line_list

        self.render_border(t1, next_time, jt1, next_jtime, next_odata)

        i = 1
        imax = len(odata_list)
        while i < imax:
            prev_odata, prev_time, prev_jtime = next_odata, next_time, next_jtime
            next_odata = odata_list[i]
            next_time, next_jtime = next_odata.timestamp, next_odata.jdate

            self.render_mid(prev_time, next_time, prev_jtime,
                            next_jtime, prev_odata, next_odata)

            i += 1

        self.render_border(next_time, t2, next_jtime, jt2, next_odata)

        return self.line_list
예제 #10
0
    def sgp4init(self, whichconst, opsmode, satnum, epoch, bstar,
                 ndot, nddot, ecco, argpo, inclo, mo, no_kozai, nodeo):
        whichconst = gravity_constants[whichconst]

        y, m, d, H, M, S = invjday(epoch + 2433281.5)
        jan0epoch = jday(y, 1, 0, 0, 0, 0.0) - 2433281.5

        self.epochyr = y % 1000
        self.epochdays = epoch - jan0epoch
        self.jdsatepoch, self.jdsatepochF = divmod(epoch, 1.0)
        self.jdsatepoch += 2433281.5

        sgp4init(whichconst, opsmode, satnum, epoch, bstar, ndot, nddot,
                 ecco, argpo, inclo, mo, no_kozai, nodeo, self)
예제 #11
0
    def _getPositionX(self, date):
        """
        experimental: uses sgp4 library
        
        NOTE: returns TEME coordinates (true equator mean equinox)

        :param datetime date:
        :rtype: GCRSCoordinates
        """
        from sgp4.earth_gravity import wgs72
        from sgp4.io import twoline2rv
        from sgp4.ext import jday

        jdate = jday(date.year, date.month, date.day, date.hour, date.minute,
                     date.second)

        tleCount = len(self.tles) // 2
        lo = 0
        hi = tleCount
        while lo < hi:  # equals bisect.bisect_left
            mid = (lo + hi) // 2
            tle = twoline2rv(self.tles[mid * 2], self.tles[mid * 2 + 1], wgs72)
            if tle.jdsatepoch < jdate:
                lo = mid + 1
            else:
                hi = mid

        tleIdx = lo - 1  # equals find_lt (rightmost TLE with epoch less than given date)
        tle = twoline2rv(self.tles[tleIdx * 2], self.tles[tleIdx * 2 + 1],
                         wgs72)

        if tle.jdsatepoch > jdate:
            raise Exception(
                "The epoch of the earliest available TLE is AFTER the requested date. "
                + "Are you missing historic TLE data?")

        if (jdate - tle.jdsatepoch > 10 * ephem.hour):
            warnings.warn('closest TLE epoch is ' +
                          str((date - tle.jdsatepoch) * 24) +
                          'h away from photo time')

        position, _ = tle.propagate(date.year, date.month, date.day, date.hour,
                                    date.minute, date.second)

        x, y, z = units.km.to(units.pc, position)

        # FIXME this is wrong, conversion TEME-J2000 is missing
        # -> need skyfield library for that, but too heavy currently
        #   see https://github.com/brandon-rhodes/python-skyfield/issues/31
        return np.array([x, y, z])
예제 #12
0
def envicosmos(tle1,tle2):
    whichconst = 'wgs72'
    #whichconst = wgs72

    f1=open(tle1+'.tle')
    f2=open(tle2+'.tle')
    out1=open('envi.sal','w+')
    out2=open('cosmos.sal','w+')

    archivos=[f1,f2]
    

    var=0
    for tlefile in archivos:
        var = var + 1
        tlelines = iter(tlefile.readlines())
        for line1 in tlelines:
            if not line1.startswith('1'):
                continue 
            line2 = next(tlelines) 
            satrec = twoline2rv(line1, line2, whichconst) # es un objeto de clase (satelite)
            mu = satrec.whichconst.mu
            epocatle=satrec.jdsatepoch
            print 'epoca del tle [jd] = ', epocatle
            jdini=jday(2008,1,9,18,0,0.0) 
            tini=(jdini-epocatle)*1440.0
            print(tini)
            tintervalo=np.arange(0,7200,1) 
            for t1 in tintervalo:
                t=tini+t1/60.0 
                r, v = sgp4(satrec, t)
                tjd=epocatle+t/1440.0 # dia juliano correspondiente al t en min.

            
                """Impresion de salida"""
                year, mon, day, hr, minute, sec = invjday(tjd)
                fecha = str(year)+'/'+str(mon)+'/'+str(day)+' '+str(hr)+':'+\
                    str(minute)+':'+str(sec)+' '+str(tjd)+' '+str(r[0])+' '+\
                    str(r[1])+' '+str(r[2])+' '+str(v[0])+' '+\
                    str(v[1])+' '+str(v[2])+'\n'
                if var == 1: 
                    out1.write(fecha)
                else:
                    out2.write(fecha)

#    year2,mon2,day2,hr2,minu2,sec2=invjday(2454475.29201)
#    print year2,mon2,day2,hr2,minu2,sec2
        """
예제 #13
0
    def test_jday(self):
        print("jday...")
        jd = 2454115.05486 # Sunday 14 January 2007 at 13:18:59.9 

        # Reference Astropy as "answer"
        t_astropy = Time(jd, format='jd')

        jdF = jd-int(jd)
        jd  = int(jd)

        jday_datetime = jday_to_datetime(jd, jdF)
        self.assertRegex(jday_datetime.isoformat(sep=' ',timespec='milliseconds'),t_astropy.iso,msg="jday_to_datetime() failed")

        (year, month, day, hour, minute, second) = invjday(jd)
        jday_jd = jday(year, month, day, hour, minute, second)
        self.assertEqual(jday_jd,jd,"jday() failed")
예제 #14
0
파일: ephem.py 프로젝트: dequis/auromat
    def _getPositionX(self, date):
        """
        experimental: uses sgp4 library
        
        NOTE: returns TEME coordinates (true equator mean equinox)

        :param datetime date:
        :rtype: GCRSCoordinates
        """
        from sgp4.earth_gravity import wgs72
        from sgp4.io import twoline2rv
        from sgp4.ext import jday

        jdate = jday(date.year, date.month, date.day, date.hour, date.minute, date.second)

        tleCount = len(self.tles) // 2
        lo = 0
        hi = tleCount
        while lo < hi: # equals bisect.bisect_left
            mid = (lo+hi)//2
            tle = twoline2rv(self.tles[mid*2], self.tles[mid*2 + 1], wgs72)
            if tle.jdsatepoch < jdate:
                lo = mid+1
            else:
                hi = mid
        
        tleIdx = lo-1 # equals find_lt (rightmost TLE with epoch less than given date)
        tle = twoline2rv(self.tles[tleIdx*2], self.tles[tleIdx*2 + 1], wgs72)

        if tle.jdsatepoch > jdate:
            raise Exception("The epoch of the earliest available TLE is AFTER the requested date. " +
                            "Are you missing historic TLE data?")
        
        if (jdate - tle.jdsatepoch > 10*ephem.hour):
            warnings.warn('closest TLE epoch is ' + str((date - tle.jdsatepoch)*24) + 'h away from photo time')
        
        position, _ = tle.propagate(date.year, date.month, date.day, date.hour, date.minute, date.second)

        x,y,z = units.km.to(units.pc, position)
        
        # FIXME this is wrong, conversion TEME-J2000 is missing
        # -> need skyfield library for that, but too heavy currently
        #   see https://github.com/brandon-rhodes/python-skyfield/issues/31
        return np.array([x,y,z]) 
예제 #15
0
from sgp4.propagation import sgp4
from sgp4.ext import jday

### INPUTS
# TLE file
tlefile = 'tle_sample.txt'
linespertle = 3  # lines per object of the TLE file, either two or three

# define desired reference epoch UTC
year = 2020
month = 6
day = 10
hour = 1
minute = 3
second = 0.45
jd_epoch = jday(year, month, day, hour, minute, second)  # julianian date

###

# setup for reading TLE file all at once
tles = open(tlefile, 'r')
tlelines = tles.readlines()
nolines = len(tlelines)
tles.close()
satrec = []

# generate satrec, here one for all, but can also do one at a time (satrec1)
startline = linespertle - 2
for i in range(startline, nolines, linespertle):
    # create satellite object
    satrec1 = twoline2rv(tlelines[i], tlelines[i + 1], wgs84)
예제 #16
0
def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False):
    """Return a Satellite imported from two lines of TLE data.

    Provide the two TLE lines as strings `longstr1` and `longstr2`,
    and select which standard set of gravitational constants you want
    by providing `gravity_constants`:

    `sgp4.earth_gravity.wgs72` - Standard WGS 72 model
    `sgp4.earth_gravity.wgs84` - More recent WGS 84 model
    `sgp4.earth_gravity.wgs72old` - Legacy support for old SGP4 behavior

    Normally, computations are made using various recent improvements
    to the algorithm.  If you want to turn some of these off and go
    back into "afspc" mode, then set `afspc_mode` to `True`.

    """
    opsmode = 'a' if afspc_mode else 'i'

    deg2rad  =   pi / 180.0;         #    0.0174532925199433
    xpdotp   =  1440.0 / (2.0 *pi);  #  229.1831180523293

    tumin = whichconst.tumin

    satrec = Satellite()
    satrec.error = 0;
    satrec.whichconst = whichconst  # Python extension: remembers its consts

    line = longstr1.rstrip()
    try:
        assert line.startswith('1 ')
        satrec.satnum = int(line[2:7])
        # classification = line[7] or 'U'
        assert line[8] == ' '
        # intldesg = line[9:17]
        two_digit_year = int(line[18:20])
        assert line[23] == '.'
        satrec.epochdays = float(line[20:32])
        assert line[32] == ' '
        assert line[34] == '.'
        satrec.ndot = float(line[33:43])
        assert line[43] == ' '
        satrec.nddot = float(line[44] + '.' + line[45:50])
        nexp = int(line[50:52])
        assert line[52] == ' '
        satrec.bstar = float(line[53] + '.' + line[54:59])
        ibexp = int(line[59:61])
        assert line[61] == ' '
        assert line[63] == ' '
        # numb = int(line[62])
        # elnum = int(line[64:68])
    except (AssertionError, IndexError, ValueError):
        raise ValueError(error_message.format(1, LINE1, line))

    line = longstr2.rstrip()
    try:
        assert line.startswith('2 ')
        satrec.satnum = int(line[2:7])  # TODO: check it matches line 1?
        assert line[7] == ' '
        assert line[11] == '.'
        satrec.inclo = float(line[8:16])
        assert line[16] == ' '
        assert line[20] == '.'
        satrec.nodeo = float(line[17:25])
        assert line[25] == ' '
        satrec.ecco = float('0.' + line[26:33].replace(' ', '0'))
        assert line[33] == ' '
        assert line[37] == '.'
        satrec.argpo = float(line[34:42])
        assert line[42] == ' '
        assert line[46] == '.'
        satrec.mo = float(line[43:51])
        assert line[51] == ' '
        satrec.no = float(line[52:63])
        #revnum = line[63:68]
    except (AssertionError, IndexError, ValueError):
        raise ValueError(error_message.format(2, LINE2, line))

    #  ---- find no, ndot, nddot ----
    satrec.no   = satrec.no / xpdotp; #   rad/min
    satrec.nddot= satrec.nddot * pow(10.0, nexp);
    satrec.bstar= satrec.bstar * pow(10.0, ibexp);

    #  ---- convert to sgp4 units ----
    satrec.a    = pow( satrec.no*tumin , (-2.0/3.0) );
    satrec.ndot = satrec.ndot  / (xpdotp*1440.0);  #   ? * minperday
    satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440);

    #  ---- find standard orbital elements ----
    satrec.inclo = satrec.inclo  * deg2rad;
    satrec.nodeo = satrec.nodeo  * deg2rad;
    satrec.argpo = satrec.argpo  * deg2rad;
    satrec.mo    = satrec.mo     * deg2rad;

    satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0;
    satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.0;

    """
    // ----------------------------------------------------------------
    // find sgp4epoch time of element set
    // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
    // and minutes from the epoch (time)
    // ----------------------------------------------------------------

    // ---------------- temp fix for years from 1957-2056 -------------------
    // --------- correct fix will occur when year is 4-digit in tle ---------
    """
    if two_digit_year < 57:
        year = two_digit_year + 2000;
    else:
        year = two_digit_year + 1900;

    mon,day,hr,minute,sec = days2mdhms(year, satrec.epochdays);
    sec_whole, sec_fraction = divmod(sec, 1.0)

    satrec.epochyr = year
    satrec.jdsatepoch = jday(year,mon,day,hr,minute,sec);
    satrec.epoch = datetime(year, mon, day, hr, minute, int(sec_whole),
                            int(sec_fraction * 1000000.0 // 1.0))

    #  ---------------- initialize the orbit at sgp4epoch -------------------
    sgp4init(whichconst, opsmode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar,
             satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no,
             satrec.nodeo, satrec)

    return satrec
예제 #17
0
def gstime_from_datetime(when_utc):
    timelist = list(when_utc.timetuple()[:6])
    timelist[5] = timelist[5] + when_utc.microsecond * 1e-6
    return _gstime(jday(*timelist))
예제 #18
0
    def __init__(self, line1, line2):
        self._line1 = line1
        self._line2 = line2

        line = line1.rstrip()

       # deg2rad = pi / 180.0;  # 0.0174532925199433
       # xpdotp = 1440.0 / (2.0 * pi);  # 229.1831180523293
       # tumin = wgs84.tumin

        try:
            assert line.startswith('1 ')
            self._satnum = int(line[2:7])
            assert line[8] == ' '
            two_digit_year = int(line[18:20])
            assert line[23] == '.'
            self.epochdays = float(line[20:32])
            assert line[32] == ' '
            assert line[34] == '.'
            #self.ndot = float(line[33:43])
            assert line[43] == ' '
            #self.nddot = float(line[44] + '.' + line[45:50])
            #nexp = int(line[50:52])
            assert line[52] == ' '
            #self.bstar = float(line[53] + '.' + line[54:59])
            #ibexp = int(line[59:61])
            assert line[61] == ' '
            assert line[63] == ' '
        except (AssertionError, IndexError, ValueError):
            raise ValueError(error_message.format(1, LINE1, line))

        line = line2.rstrip()
        try:
            assert line.startswith('2 ')
            self._satnum = int(line[2:7])  # TODO: check it matches line 1?
            assert line[7] == ' '
            assert line[11] == '.'
            #self.inclo = float(line[8:16])
            assert line[16] == ' '
            assert line[20] == '.'
            #self.nodeo = float(line[17:25])
            assert line[25] == ' '
            #self.ecco = float('0.' + line[26:33].replace(' ', '0'))
            assert line[33] == ' '
            assert line[37] == '.'
            #self.argpo = float(line[34:42])
            assert line[42] == ' '
            assert line[46] == '.'
            #self.mo = float(line[43:51])
            assert line[51] == ' '
            #self.no = float(line[52:63])
            #revnum = line[63:68]
        except (AssertionError, IndexError, ValueError):
            raise ValueError(error_message.format(2, LINE2, line))

        #  ---- find no, ndot, nddot ----
        #self.no   = self.no / xpdotp; #   rad/min
        #self.nddot= self.nddot * pow(10.0, nexp);
        #self.bstar= self.bstar * pow(10.0, ibexp);

        #  ---- convert to sgp4 units ----
        #self.a    = pow( self.no*tumin , (-2.0/3.0) );
        #self.ndot = self.ndot  / (xpdotp*1440.0);  #   ? * minperday
        #self.nddot= self.nddot / (xpdotp*1440.0*1440);

        #  ---- find standard orbital elements ----
        #self.inclo = self.inclo  * deg2rad;
        #self.nodeo = self.nodeo  * deg2rad;
        #self.argpo = self.argpo  * deg2rad;
        #self.mo    = self.mo     * deg2rad;

        #self.alta = self.a*(1.0 + self.ecco) - 1.0;
        #self.altp = self.a*(1.0 - self.ecco) - 1.0;

        if two_digit_year < 57:
            year = two_digit_year + 2000;
        else:
            year = two_digit_year + 1900;

        mon,day,hr,minute,sec = days2mdhms(year, self.epochdays);
        sec_whole, sec_fraction = divmod(sec, 1.0)

        self.epochyr = year
        self.jdsatepoch = jday(year,mon,day,hr,minute,sec);
        self._epoch = datetime(year, mon, day, hr, minute, int(sec_whole),
                                int(sec_fraction * 1000000.0 // 1.0), tzinfo=timezone.utc)
예제 #19
0
def dt2julian(dtobj):
    return jday(dtobj.year, dtobj.month, dtobj.day, dtobj.hour, dtobj.minute,
                dtobj.second)
예제 #20
0
def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False):
       """Return a Satellite imported from two lines of TLE data.

       Provide the two TLE lines as strings `longstr1` and `longstr2`,
       and select which standard set of gravitational constants you want
       by providing `gravity_constants`:

       `sgp4.earth_gravity.wgs72` - Standard WGS 72 model
       `sgp4.earth_gravity.wgs84` - More recent WGS 84 model
       `sgp4.earth_gravity.wgs72old` - Legacy support for old SGP4 behavior

       Normally, computations are made using various recent improvements
       to the algorithm.  If you want to turn some of these off and go
       back into "afspc" mode, then set `afspc_mode` to `True`.

       """
       opsmode = 'a' if afspc_mode else 'i'

       deg2rad  =   pi / 180.0;         #    0.0174532925199433
       xpdotp   =  1440.0 / (2.0 *pi);  #  229.1831180523293

       revnum = 0;
       elnum = 0;

       tumin = whichconst.tumin

       satrec = Satellite()
       satrec.error = 0;
       satrec.whichconst = whichconst  # Python extension: remembers its consts

       # This is Python, so we convert the strings into mutable lists of
       # characters before setting the C++ code loose on them.
       longstr1 = [ c for c in longstr1 ]
       longstr2 = [ c for c in longstr2 ]

       #  set the implied decimal points since doing a formated read
       #  fixes for bad input data values (missing, ...)
       for j in range(10, 16):
           if longstr1[j] == ' ':
               longstr1[j] = '_';

       if longstr1[44] != ' ':
           longstr1[43] = longstr1[44];
       longstr1[44] = '.';
       if longstr1[7] == ' ':
           longstr1[7] = 'U';
       if longstr1[9] == ' ':
           longstr1[9] = '.';
       for j in range(45, 50):
           if longstr1[j] == ' ':
               longstr1[j] = '0';
       if longstr1[51] == ' ':
           longstr1[51] = '0';
       if longstr1[53] != ' ':
           longstr1[52] = longstr1[53];
       longstr1[53] = '.';
       longstr2[25] = '.';
       for j in range(26, 33):
           if longstr2[j] == ' ':
               longstr2[j] = '0';
       if longstr1[62] == ' ':
           longstr1[62] = '0';
       if longstr1[68] == ' ':
           longstr1[68] = '0';

       # Concatenate lists back into real strings.
       longstr1 = ''.join(longstr1)
       longstr2 = ''.join(longstr2)

       (cardnumb,satrec.satnum,classification, intldesg, two_digit_year,
        satrec.epochdays,satrec.ndot, satrec.nddot, nexp, satrec.bstar,
        ibexp, numb, elnum) = \
       sscanf(longstr1,"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
           )

       if longstr2[52] == ' ':
           (cardnumb,satrec.satnum, satrec.inclo,
            satrec.nodeo,satrec.ecco, satrec.argpo, satrec.mo, satrec.no,
            revnum) = \
               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n",
                      )
       else:
           (cardnumb,satrec.satnum, satrec.inclo,
            satrec.nodeo,satrec.ecco, satrec.argpo, satrec.mo, satrec.no,
            revnum) = \
               sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n",
                      )

       #  ---- find no, ndot, nddot ----
       satrec.no   = satrec.no / xpdotp; #   rad/min
       satrec.nddot= satrec.nddot * pow(10.0, nexp);
       satrec.bstar= satrec.bstar * pow(10.0, ibexp);

       #  ---- convert to sgp4 units ----
       satrec.a    = pow( satrec.no*tumin , (-2.0/3.0) );
       satrec.ndot = satrec.ndot  / (xpdotp*1440.0);  #   ? * minperday
       satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440);

       #  ---- find standard orbital elements ----
       satrec.inclo = satrec.inclo  * deg2rad;
       satrec.nodeo = satrec.nodeo  * deg2rad;
       satrec.argpo = satrec.argpo  * deg2rad;
       satrec.mo    = satrec.mo     * deg2rad;

       satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0;
       satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.0;

       """
       // ----------------------------------------------------------------
       // find sgp4epoch time of element set
       // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
       // and minutes from the epoch (time)
       // ----------------------------------------------------------------

       // ---------------- temp fix for years from 1957-2056 -------------------
       // --------- correct fix will occur when year is 4-digit in tle ---------
       """
       if two_digit_year < 57:
           year = two_digit_year + 2000;
       else:
           year = two_digit_year + 1900;

       mon,day,hr,minute,sec = days2mdhms(year, satrec.epochdays);
       sec_whole, sec_fraction = divmod(sec, 1.0)

       satrec.epochyr = year
       satrec.jdsatepoch = jday(year,mon,day,hr,minute,sec);
       satrec.epoch = datetime(year, mon, day, hr, minute, int(sec_whole),
                               int(sec_fraction * 1000000.0 // 1.0))

       #  ---------------- initialize the orbit at sgp4epoch -------------------
       sgp4init( whichconst, opsmode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar,
                 satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no,
                 satrec.nodeo, satrec);

       return satrec
예제 #21
0
파일: model.py 프로젝트: TobyThomson/HEXSAT
 def propagate(self, year, month=1, day=1, hour=0, minute=0, second=0.0):
     j = jday(year, month, day, hour, minute, second)
     m = (j - self.jdsatepoch) * minutes_per_day
     r, v = sgp4(self, m)
     return r, v
예제 #22
0
def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False):
    deg2rad  =   pi / 180.0;         #    0.0174532925199433
    xpdotp   =  1440.0 / (2.0 *pi);  #  229.1831180523293

    tumin = whichconst.tumin

    satrec = Satellite()
    satrec.error = 0;
    satrec.whichconst = whichconst  # Python extension: remembers its consts

    line = longstr1.rstrip()
    # try/except is not well supported by Numba
    if (len(line) >= 64 and
        line.startswith('1 ') and
        line[8] == ' ' and
        line[23] == '.' and
        line[32] == ' ' and
        line[34] == '.' and
        line[43] == ' ' and
        line[52] == ' ' and
        line[61] == ' ' and
        line[63] == ' '):

        _saved_satnum = satrec.satnum = int(line[2:7])
        # classification = line[7] or 'U'
        # intldesg = line[9:17]
        two_digit_year = int(line[18:20])
        satrec.epochdays = float(line[20:32])
        satrec.ndot = float(line[33:43])
        satrec.nddot = float(line[44] + '.' + line[45:50])
        nexp = int(line[50:52])
        satrec.bstar = float(line[53] + '.' + line[54:59])
        ibexp = int(line[59:61])
        # numb = int(line[62])
        # elnum = int(line[64:68])
    else:
        raise ValueError(error_message.format(1, LINE1, line))

    line = longstr2.rstrip()
    if (len(line) >= 69 and
        line.startswith('2 ') and
        line[7] == ' ' and
        line[11] == '.' and
        line[16] == ' ' and
        line[20] == '.' and
        line[25] == ' ' and
        line[33] == ' ' and
        line[37] == '.' and
        line[42] == ' ' and
        line[46] == '.' and
        line[51] == ' '):

        satrec.satnum = int(line[2:7])
        if _saved_satnum != satrec.satnum:
            raise ValueError('Object numbers in lines 1 and 2 do not match')

        satrec.inclo = float(line[8:16])
        satrec.nodeo = float(line[17:25])
        satrec.ecco = float('0.' + line[26:33].replace(' ', '0'))
        satrec.argpo = float(line[34:42])
        satrec.mo = float(line[43:51])
        satrec.no = float(line[52:63])
        #revnum = line[63:68]
    #except (AssertionError, IndexError, ValueError):
    else:
        raise ValueError(error_message.format(2, LINE2, line))

    #  ---- find no, ndot, nddot ----
    satrec.no   = satrec.no / xpdotp; #   rad/min
    satrec.nddot= satrec.nddot * pow(10.0, nexp);
    satrec.bstar= satrec.bstar * pow(10.0, ibexp);

    #  ---- convert to sgp4 units ----
    satrec.a    = pow( satrec.no*tumin , (-2.0/3.0) );
    satrec.ndot = satrec.ndot  / (xpdotp*1440.0);  #   ? * minperday
    satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440);

    #  ---- find standard orbital elements ----
    satrec.inclo = satrec.inclo  * deg2rad;
    satrec.nodeo = satrec.nodeo  * deg2rad;
    satrec.argpo = satrec.argpo  * deg2rad;
    satrec.mo    = satrec.mo     * deg2rad;

    satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0;
    satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.0;
	
    if two_digit_year < 57:
        year = two_digit_year + 2000;
    else:
        year = two_digit_year + 1900;

    mon,day,hr,minute,sec = days2mdhms(year, satrec.epochdays);
    sec_whole, sec_fraction = divmod(sec, 1.0)

    satrec.epochyr = year
    satrec.jdsatepoch = jday(year,mon,day,hr,minute,sec);
    satrec.epoch = datetime(year, mon, day, hr, minute, int(sec_whole),
                            int(sec_fraction * 1000000.0 // 1.0))

    #  ---------------- initialize the orbit at sgp4epoch -------------------
    sgp4init(whichconst, afspc_mode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar,
             satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no,
             satrec.nodeo, satrec)

    return satrec
예제 #23
0
def gstime_from_datetime(when_utc):
    timetuple = timetuple_from_dt(when_utc)
    return _gstime(jday(*timetuple))
예제 #24
0
def gstime_from_datetime(when_utc):
    timetuple = when_utc.timetuple()[:6]
    return _gstime(jday(*timetuple))
예제 #25
0
def twoline2rv(longstr1, longstr2, whichconst, afspc_mode=False):
    """Return a Satellite imported from two lines of TLE data.

    Provide the two TLE lines as strings `longstr1` and `longstr2`,
    and select which standard set of gravitational constants you want
    by providing `gravity_constants`:

    `sgp4.earth_gravity.wgs72` - Standard WGS 72 model
    `sgp4.earth_gravity.wgs84` - More recent WGS 84 model
    `sgp4.earth_gravity.wgs72old` - Legacy support for old SGP4 behavior

    Normally, computations are made using various recent improvements
    to the algorithm.  If you want to turn some of these off and go
    back into "afspc" mode, then set `afspc_mode` to `True`.

    """

    deg2rad = pi / 180.0
    #    0.0174532925199433
    xpdotp = 1440.0 / (2.0 * pi)
    #  229.1831180523293

    tumin = whichconst.tumin

    satrec = Satellite()
    satrec.error = 0
    satrec.whichconst = whichconst  # Python extension: remembers its consts

    line = longstr1.rstrip()
    # try/except is not well supported by Numba
    if (len(line) >= 64 and line.startswith('1 ') and line[8] == ' '
            and line[23] == '.' and line[32] == ' ' and line[34] == '.'
            and line[43] == ' ' and line[52] == ' ' and line[61] == ' '
            and line[63] == ' '):

        _saved_satnum = satrec.satnum = int(line[2:7])
        # classification = line[7] or 'U'
        # intldesg = line[9:17]
        two_digit_year = int(line[18:20])
        satrec.epochdays = float(line[20:32])
        satrec.ndot = float(line[33:43])
        satrec.nddot = float(line[44] + '.' + line[45:50])
        nexp = int(line[50:52])
        satrec.bstar = float(line[53] + '.' + line[54:59])
        ibexp = int(line[59:61])
        # numb = int(line[62])
        # elnum = int(line[64:68])
    else:
        raise ValueError(error_message.format(1, LINE1, line))

    line = longstr2.rstrip()
    line_format_ok = False
    if (len(line) >= 69 and line.startswith('2 ') and line[7] == ' '
            and line[11] == '.' and line[16] == ' ' and line[20] == '.'
            and line[25] == ' ' and line[33] == ' ' and line[37] == '.'
            and line[42] == ' ' and line[46] == '.' and line[51] == ' '):

        satrec.satnum = int(line[2:7])
        if _saved_satnum != satrec.satnum:
            raise ValueError('Object numbers in lines 1 and 2 do not match')

        satrec.inclo = float(line[8:16])
        satrec.nodeo = float(line[17:25])
        satrec.ecco = float('0.' + line[26:33].replace(' ', '0'))
        satrec.argpo = float(line[34:42])
        satrec.mo = float(line[43:51])
        satrec.no = float(line[52:63])
        #revnum = line[63:68]
    #except (AssertionError, IndexError, ValueError):
    else:
        raise ValueError(error_message.format(2, LINE2, line))

    #  ---- find no, ndot, nddot ----
    satrec.no = satrec.no / xpdotp
    #   rad/min
    satrec.nddot = satrec.nddot * pow(10.0, nexp)
    satrec.bstar = satrec.bstar * pow(10.0, ibexp)

    #  ---- convert to sgp4 units ----
    satrec.a = pow(satrec.no * tumin, (-2.0 / 3.0))
    satrec.ndot = satrec.ndot / (xpdotp * 1440.0)
    #   ? * minperday
    satrec.nddot = satrec.nddot / (xpdotp * 1440.0 * 1440)

    #  ---- find standard orbital elements ----
    satrec.inclo = satrec.inclo * deg2rad
    satrec.nodeo = satrec.nodeo * deg2rad
    satrec.argpo = satrec.argpo * deg2rad
    satrec.mo = satrec.mo * deg2rad

    satrec.alta = satrec.a * (1.0 + satrec.ecco) - 1.0
    satrec.altp = satrec.a * (1.0 - satrec.ecco) - 1.0
    """
    // ----------------------------------------------------------------
    // find sgp4epoch time of element set
    // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
    // and minutes from the epoch (time)
    // ----------------------------------------------------------------

    // ---------------- temp fix for years from 1957-2056 -------------------
    // --------- correct fix will occur when year is 4-digit in tle ---------
    """
    if two_digit_year < 57:
        year = two_digit_year + 2000
    else:
        year = two_digit_year + 1900

    mon, day, hr, minute, sec = days2mdhms(year, satrec.epochdays)
    sec_whole, sec_fraction = divmod(sec, 1.0)

    satrec.epochyr = year
    satrec.jdsatepoch = jday(year, mon, day, hr, minute, sec)
    satrec.epoch = datetime(year, mon, day, hr, minute, int(sec_whole),
                            int(sec_fraction * 1000000.0 // 1.0))

    #  ---------------- initialize the orbit at sgp4epoch -------------------
    sgp4init(whichconst, afspc_mode, satrec.satnum,
             satrec.jdsatepoch - 2433281.5, satrec.bstar, satrec.ecco,
             satrec.argpo, satrec.inclo, satrec.mo, satrec.no, satrec.nodeo,
             satrec)

    return satrec
예제 #26
0
def sat_construct(_epoch,
                  _ndot,
                  _nddot,
                  _bstar,
                  _inclo,
                  _nodeo,
                  _ecco,
                  _argpo,
                  _mo,
                  _no_kozai,
                  _satnum,
                  _sat=None,
                  _whichconst=wgs72,
                  _opsmode='i'):

    #Construct the satellite
    if _sat is None:
        satrec = Satellite()
    else:
        satrec = _sat

    satrec.satnum = _satnum
    satrec.whichconst = _whichconst
    satrec.opsmode = _opsmode

    dt = julian.from_jd(_epoch, fmt='jd')
    y = dt.year - 2000
    yjd = jday(dt.year, 1, 1, 0, 0, 0)

    satrec.epoch = dt
    satrec.epochyr = y
    satrec.epochdays = _epoch - yjd + 1
    satrec.jdsatepoch = _epoch

    satrec.ndot = _ndot
    satrec.nddot = _nddot

    _MAXB = .99999
    if _bstar > _MAXB:
        _bstar = _MAXB
    if _bstar < -_MAXB:
        _bstar = -_MAXB
    satrec.bstar = _bstar

    satrec.inclo = _inclo
    satrec.nodeo = _nodeo

    _MINE = .5e-7
    if _ecco < _MINE:
        _ecco = _MINE

    _MAXE = 1. - _MINE
    if _ecco > _MAXE:
        _ecco = _MAXE
    satrec.ecco = _ecco

    satrec.argpo = _argpo
    satrec.mo = _mo

    if _no_kozai < 1e-7:
        _no_kozai = 1e-7
    satrec.no_kozai = _no_kozai
    satrec.error = 0
    satrec.error_message = None

    #  ---------------- initialize the orbit at sgp4epoch -------------------
    sgp4init(satrec.whichconst, satrec.opsmode, satrec.satnum,
             satrec.jdsatepoch - 2433281.5, satrec.bstar, satrec.ndot,
             satrec.nddot, satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo,
             satrec.no_kozai, satrec.nodeo, satrec)

    return satrec
예제 #27
0
 def date2JD(self, startDate):
     date=startDate.split('-')
     return jday(int(date[0]),
                 int(date[1]),
                 int(date[2]),0,0,0)
예제 #28
0
def twoline2rv(longstr1, longstr2, whichconst, opsmode='i', satrec=None):
    """Return a Satellite imported from two lines of TLE data.

    Provide the two TLE lines as strings `longstr1` and `longstr2`,
    and select which standard set of gravitational constants you want
    by providing `gravity_constants`:

    `sgp4.earth_gravity.wgs72` - Standard WGS 72 model
    `sgp4.earth_gravity.wgs84` - More recent WGS 84 model
    `sgp4.earth_gravity.wgs72old` - Legacy support for old SGP4 behavior

    Normally, computations are made using various recent improvements
    to the algorithm.  If you want to turn some of these off and go
    back into "opsmode" mode, then set `opsmode` to `a`.

    """

    deg2rad = pi / 180.0
    #    0.0174532925199433
    xpdotp = 1440.0 / (2.0 * pi)
    #  229.1831180523293

    # For compatibility with our 1.x API, build an old Satellite object
    # if the caller fails to supply a satrec.  In that case we perform
    # the necessary import here to avoid an import loop.
    if satrec is None:
        from sgp4.model import Satellite
        satrec = Satellite()

    satrec.error = 0
    satrec.whichconst = whichconst  # Python extension: remembers its consts

    line = longstr1.rstrip()

    if (len(line) >= 64 and line.startswith('1 ') and line[8] == ' '
            and line[23] == '.' and line[32] == ' ' and line[34] == '.'
            and line[43] == ' ' and line[52] == ' ' and line[61] == ' '
            and line[63] == ' '):

        _saved_satnum = satrec.satnum = _alpha5(line[2:7])
        satrec.classification = line[7] or 'U'
        satrec.intldesg = line[9:17].rstrip()
        two_digit_year = int(line[18:20])
        satrec.epochdays = float(line[20:32])
        satrec.ndot = float(line[33:43])
        satrec.nddot = float(line[44] + '.' + line[45:50])
        nexp = int(line[50:52])
        satrec.bstar = float(line[53] + '.' + line[54:59])
        ibexp = int(line[59:61])
        satrec.ephtype = line[62]
        satrec.elnum = int(line[64:68])
    else:
        raise ValueError(error_message.format(1, LINE1, line))

    line = longstr2.rstrip()

    if (len(line) >= 69 and line.startswith('2 ') and line[7] == ' '
            and line[11] == '.' and line[16] == ' ' and line[20] == '.'
            and line[25] == ' ' and line[33] == ' ' and line[37] == '.'
            and line[42] == ' ' and line[46] == '.' and line[51] == ' '):

        satrec.satnum = _alpha5(line[2:7])
        if _saved_satnum != satrec.satnum:
            raise ValueError('Object numbers in lines 1 and 2 do not match')

        satrec.inclo = float(line[8:16])
        satrec.nodeo = float(line[17:25])
        satrec.ecco = float('0.' + line[26:33].replace(' ', '0'))
        satrec.argpo = float(line[34:42])
        satrec.mo = float(line[43:51])
        satrec.no_kozai = float(line[52:63])
        satrec.revnum = line[63:68]
    #except (AssertionError, IndexError, ValueError):
    else:
        raise ValueError(error_message.format(2, LINE2, line))

    #  ---- find no, ndot, nddot ----
    satrec.no_kozai = satrec.no_kozai / xpdotp
    #   rad/min
    satrec.nddot = satrec.nddot * pow(10.0, nexp)
    satrec.bstar = satrec.bstar * pow(10.0, ibexp)

    #  ---- convert to sgp4 units ----
    satrec.ndot = satrec.ndot / (xpdotp * 1440.0)
    #   ? * minperday
    satrec.nddot = satrec.nddot / (xpdotp * 1440.0 * 1440)

    #  ---- find standard orbital elements ----
    satrec.inclo = satrec.inclo * deg2rad
    satrec.nodeo = satrec.nodeo * deg2rad
    satrec.argpo = satrec.argpo * deg2rad
    satrec.mo = satrec.mo * deg2rad
    """
    // ----------------------------------------------------------------
    // find sgp4epoch time of element set
    // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
    // and minutes from the epoch (time)
    // ----------------------------------------------------------------

    // ---------------- temp fix for years from 1957-2056 -------------------
    // --------- correct fix will occur when year is 4-digit in tle ---------
    """
    if two_digit_year < 57:
        year = two_digit_year + 2000
    else:
        year = two_digit_year + 1900

    mon, day, hr, minute, sec = days2mdhms(year, satrec.epochdays)
    sec_whole, sec_fraction = divmod(sec, 1.0)

    satrec.epochyr = year
    satrec.jdsatepoch = jday(year, mon, day, hr, minute, sec)
    try:
        satrec.epoch = datetime(year, mon, day, hr, minute, int(sec_whole),
                                int(sec_fraction * 1000000.0 // 1.0))
    except ValueError:
        # Sometimes a TLE says something like "2019 + 366.82137887 days"
        # which would be December 32nd which causes a ValueError.
        year, mon, day, hr, minute, sec = invjday(satrec.jdsatepoch)
        satrec.epoch = datetime(year, mon, day, hr, minute, int(sec_whole),
                                int(sec_fraction * 1000000.0 // 1.0))

    #  ---------------- initialize the orbit at sgp4epoch -------------------
    sgp4init(whichconst, opsmode, satrec.satnum, satrec.jdsatepoch - 2433281.5,
             satrec.bstar, satrec.ndot, satrec.nddot, satrec.ecco,
             satrec.argpo, satrec.inclo, satrec.mo, satrec.no_kozai,
             satrec.nodeo, satrec)

    return satrec
예제 #29
0
    def __init__(self,
                 whichconst,
                 satnum,
                 epoch,
                 bstar,
                 inclo,
                 nodeo,
                 ecco,
                 argpo,
                 mo,
                 no_kozai,
                 ndot=0,
                 nddot=0,
                 classification='U',
                 intldesg=None,
                 elnum=1,
                 revnum=1,
                 afspc_mode=False):
        """
        :param whichconst: standard set of gravitational constants.
            `sgp4.earth_gravity.wgs72` - Standard WGS 72 model
            `sgp4.earth_gravity.wgs84` - More recent WGS 84 model
            `sgp4.earth_gravity.wgs72old` - Legacy support for old SGP4 behavior
        :param satnum: Unique satellite number given in the TLE file.
        :param epoch: naive datetime objects with TLE epoch
        :param bstar: Ballistic drag coefficient B* in inverse earth radii.
        :param inclo: Inclination in radians.
        :param nodeo: Right ascension of ascending node in radians.
        :param ecco: Eccentricity.
        :param argpo: Argument of perigee in radians.
        :param mo: Mean anomaly in radians.
        :param no_kozai: Mean motion in radians per minute (rad/min).
        :param ndot: First time derivative of the mean motion (ignored by SGP4).
        :param nddot: Second time derivative of the mean motion (ignored by SGP4).
        :param classification:  (U=Unclassified, C=Classified, S=Secret)
        :param intldesg: International designator (last two digits of launch year,
        launch number of the year, piece of the launch)
        :param elnum: Element set number. Incremented when a new TLE is generated for this object.
        :param revnum: Revolution number at epoch (revolutions)
        :param afspc_mode: Normally, computations are made using various recent improvements to the
         algorithm.  If you want to turn some of these off and go back into "afspc" mode, then set
          `afspc_mode` to `True`.
        """
        self.whichconst = whichconst
        self.satnum = satnum
        self.epoch = epoch
        self.epochyr = epoch.year
        self.jdsatepoch = jday(epoch.year, epoch.month, epoch.day, epoch.hour,
                               epoch.minute,
                               epoch.second + 1e-6 * epoch.microsecond)
        days_in_the_year = (epoch.date() -
                            datetime.date(epoch.year, 1, 1)).days + 1
        self.epochdays = days_in_the_year + (
            epoch.hour + epoch.minute / 60 +
            (epoch.second + 1e-6 * epoch.microsecond) / 60 / 60) / 24.0
        self.bstar = bstar
        self.inclo = inclo
        self.nodeo = nodeo
        self.ecco = ecco
        self.argpo = argpo
        self.mo = mo
        self.no_kozai = no_kozai
        self.a = pow(self.no_kozai * whichconst.tumin, (-2.0 / 3.0))
        self.alta = self.a * (1.0 + self.ecco) - 1.0
        self.altp = self.a * (1.0 - self.ecco) - 1.0
        self.ndot = ndot
        self.nddot = nddot
        self.classification = classification
        if intldesg:
            self.intldesg = intldesg
        else:
            self.intldesg = str(self.epochyr)[:-2] + '001A'
        self.elnum = elnum
        self.revnum = revnum
        self.error = 0

        sgp4init(whichconst, afspc_mode, self.satnum,
                 self.jdsatepoch - 2433281.5, self.bstar, self.ecco,
                 self.argpo, self.inclo, self.mo, self.no_kozai, self.nodeo,
                 self)