def test_Lgm_LoadLeapSeconds(self): """Lgm_LoadLeapSeconds should work and not change""" self.assertTrue(Lgm_LoadLeapSeconds(ctypes.pointer(self.c))) # The LeapSecondDates values are the dates that the given corrections came into effect. But the actual leap second # date is the day before -- thats when the extra second was tacked on. So subtract a day from each of the dates. LeapSecondDates = [19720101, 19720701, 19730101, 19740101, 19750101, 19760101, 19770101, 19780101, 19790101, 19800101, 19810701, 19820701, 19830701, 19850701, 19880101, 19900101, 19910101, 19920701, 19930701, 19940701, 19960101, 19970701, 19990101, 20060101, 20090101,] LeapSecondJDs = [2441317.5, 2441499.5, 2441683.5, 2442048.5, 2442413.5, 2442778.5, 2443144.5, 2443509.5, 2443874.5, 2444239.5, 2444786.5, 2445151.5, 2445516.5, 2446247.5, 2447161.5, 2447892.5, 2448257.5, 2448804.5, 2449169.5, 2449534.5, 2450083.5, 2450630.5, 2451179.5, 2453736.5, 2454832.5,] LeapSeconds = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, ] LeapSecondDates = Lgm_CTrans.dateLongToDate(LeapSecondDates) LeapSecondDates = [val - datetime.timedelta(days=1) for val in LeapSecondDates] LeapSecondDates = Lgm_CTrans.dateToDateLong(LeapSecondDates) for i, (v1, v2, v3) in enumerate(zip(LeapSecondDates, LeapSecondJDs, LeapSeconds)): self.assertEqual(v1, self.c.l.LeapSecondDates[i]) self.assertEqual(v2, self.c.l.LeapSecondJDs[i]) self.assertEqual(v3, self.c.l.LeapSeconds[i])
def datetime2Lgm(*args): '''Convenience function to convert Python datetime to Lgm date and utc format Parameters ---------- time_in: datetime.datetime the input time to convert to a different system Outputs ------- datelong: long LanlGeoMag long integer date representation (YYYYMMDD) utc: float LanlGeoMag floating point time-of-day (UTC) representation ''' if len(args) == 1: time_in = args[0] else: raise ValueError('Invalid arguments supplied in function call') if _spacepy: if isinstance(time_in, spt.Ticktock): raise NotImplementedError('SpacePy compatibility not yet enabled') try: datelong = Lgm_CTrans.dateToDateLong(time_in) utc = Lgm_CTrans.dateToFPHours(time_in) except AttributeError: raise TypeError("Date must be a datetime object") return datelong, utc
def test_dateLongToDate(self): """dateLongToDate should give known output""" self.assertEqual(Lgm_CTrans.dateLongToDate(20001223), datetime.datetime(2000, 12, 23, 0, 0)) self.assertEqual(Lgm_CTrans.dateLongToDate([20001223]), datetime.datetime(2000, 12, 23, 0, 0)) self.assertEqual(Lgm_CTrans.dateLongToDate([20001223]*2), [datetime.datetime(2000, 12, 23, 0, 0), datetime.datetime(2000, 12, 23, 0, 0)]) numpy.testing.assert_array_equal(Lgm_CTrans.dateLongToDate(numpy.array([20001223]*2)), numpy.array([datetime.datetime(2000, 12, 23, 0, 0), datetime.datetime(2000, 12, 23, 0, 0)]))
def test_getDipoleTilt(self): """getDipoleTilt should give known results""" dt = Lgm_CTrans.getDipoleTilt(datetime.datetime(2000, 1, 1)) self.assertAlmostEqual(dt, -0.45114989442541137) dt = Lgm_CTrans.getDipoleTilt(datetime.datetime(2010, 1, 1)) self.assertAlmostEqual(dt, -0.44636634840305872) dt = Lgm_CTrans.getDipoleTilt(datetime.datetime(2010, 6, 1)) self.assertAlmostEqual(dt, 0.32433439111559559) dt = Lgm_CTrans.getDipoleTilt([datetime.datetime(2010, 6, 1)]*2) numpy.testing.assert_allclose(dt, [0.32433439111559559, 0.32433439111559559])
def test_GSMtoMLT(self): """GSMtoMLT should give known output""" mlt = Lgm_CTrans.GSMtoMLT([1,0,0], datetime.datetime(2000, 1, 1)) self.assertEqual(mlt, 12.0) mlt = Lgm_CTrans.GSMtoMLT([0,1,0], datetime.datetime(2000, 1, 1)) self.assertAlmostEqual(mlt, 17.953729579055036) mlt = Lgm_CTrans.GSMtoMLT([0,1], datetime.datetime(2000, 1, 1)) self.assertAlmostEqual(mlt, 17.953729579055036) mlt = Lgm_CTrans.GSMtoMLT([0], datetime.datetime(2000, 1, 1)) self.assertAlmostEqual(mlt, 20.80272832231037)
def test_Lgm_IsoTimeStringToDateTime(self): """regression on IsoTimeStringToDateTime""" lgmct = Lgm_CTrans.Lgm_CTrans() lgmdt = Lgm_DateTime() str1 = np.asarray('2001') IsoTimeStringToDateTime( str1.ctypes.data_as(ctypes.POINTER(ctypes.c_char)), ctypes.pointer(lgmdt), ctypes.pointer(lgmct)) self.assertEqual(lgmdt.Date, 20010101) self.assertEqual(lgmdt.Day, 1) self.assertEqual(lgmdt.DaySeconds, 86400.0) self.assertEqual(lgmdt.Dow, 1) self.assertEqual(lgmdt.DowStr, 'Mon') self.assertEqual(lgmdt.Doy, 1) self.assertEqual(lgmdt.Hour, 0) self.assertEqual(lgmdt.Minute, 0) self.assertEqual(lgmdt.Second, 0) self.assertAlmostEqual(lgmdt.T, 0.010006844626967831) self.assertEqual(lgmdt.TZD_hh, 0) self.assertEqual(lgmdt.TZD_mm, 0) self.assertEqual(lgmdt.TZD_sgn, 1) self.assertEqual(lgmdt.Time, 0.0) self.assertEqual(lgmdt.TimeSystem, 0) self.assertEqual(lgmdt.Week, 1) self.assertEqual(lgmdt.Year, 2001) self.assertEqual(lgmdt.fYear, 2001.0) self.assertEqual(lgmdt.wYear, 2001)
def test_init(self): """Lgm_Coords does some input checking""" self.assertRaises(NotImplementedError, Lgm_CTrans.Lgm_Coords, [1, 2, 3], units='km') self.assertRaises(NotImplementedError, Lgm_CTrans.Lgm_Coords, [1, 2, 3], system='bad') self.assertRaises(ValueError, Lgm_CTrans.Lgm_Coords, [0.1, 0.5, 0.6]) coords = Lgm_CTrans.Lgm_Coords([1, 2, 3]) self.assertEqual(coords[:], [1,2,3]) self.assertEqual(coords.system, 'GSM') # with will catch a default change
def test_init_vals(self): """__init__ sets upa few valiues (regression)""" tst = Lgm_CTrans.Lgm_CTrans() self.assertEqual(tst.nNutationTerms, 106) self.assertEqual(tst.DUT1, 0.0) self.assertEqual(tst.xp, 0.0) self.assertEqual(tst.yp, 0.0) self.assertEqual(tst.ddPsi, 0.0) self.assertEqual(tst.ddEps, 0.0)
def Lgm2jd(datelong, utc, cTrans=None): ''' convert from Lgm float UTC time representation to julian day ''' if not cTrans: c = pointer(Lgm_CTrans.Lgm_CTrans()) else: c = cTrans JD = Lgm_JD(c_date.year, c_date.month, c_date.day, utc, LGM_TIME_SYS_UTC, c)
def test_dateToDateLong(self): """dateToDateLong should give known results for known input""" d1 = datetime.datetime(2000, 12, 12) self.assertEqual(20001212L, Lgm_CTrans.dateToDateLong(d1)) self.assertEqual(20001212L, Lgm_CTrans.dateToDateLong([d1])) self.assertEqual([20001212L, 20001212L], Lgm_CTrans.dateToDateLong([d1, d1])) self.assertEqual([20001212L, 20001212L], Lgm_CTrans.dateToDateLong(numpy.array([d1, d1])).tolist()) self.assertEqual(20001212L, Lgm_CTrans.dateToDateLong(d1.date()))
def test_dateToFPHours(self): """dateToFPHours should give known output for known input""" d1 = datetime.datetime(2000, 12, 12) self.assertEqual(0.0, Lgm_CTrans.dateToFPHours(d1)) for val in range(24): self.assertEqual(val, Lgm_CTrans.dateToFPHours(datetime.datetime(2000, 12, 12, val))) self.assertEqual(12.5, Lgm_CTrans.dateToFPHours([datetime.datetime(2000, 12, 12, 12, 30)])) self.assertEqual(12.5, Lgm_CTrans.dateToFPHours(datetime.datetime(2000, 12, 12, 12, 30))) self.assertEqual(12.25, Lgm_CTrans.dateToFPHours(datetime.datetime(2000, 12, 12, 12, 15))) self.assertEqual(12.75, Lgm_CTrans.dateToFPHours(datetime.datetime(2000, 12, 12, 12, 45))) d1 = datetime.datetime(2000, 12, 12, 12, 30) self.assertEqual([12.5, 12.5], Lgm_CTrans.dateToFPHours([d1, d1])) self.assertEqual([12.5, 12.5], Lgm_CTrans.dateToFPHours(numpy.array([d1, d1])).tolist())
def test_Lgm_Convert_CoordsBack(self): """Lgm_Convert_Coords should give known output (and back)""" # taken from CoordQuickStart.c Date = 20040812 UTC = 12.34567 Ugsm = Lgm_Vector.Lgm_Vector(x = -6.6, y = 3.4, z = -2.3) Usm = Lgm_Vector.Lgm_Vector() c = Lgm_CTrans.Lgm_CTrans() Lgm_Set_Coord_Transforms(Date, UTC, ctypes.pointer(c)) Lgm_Convert_Coords(ctypes.pointer(Ugsm), ctypes.pointer(Usm), GSM_TO_SM, ctypes.pointer(c)) self.assertAlmostEqual(-5.5352494753370127, Usm.x, places=5) self.assertAlmostEqual( 3.3999999999999995, Usm.y, places=5) self.assertAlmostEqual(-4.2674363786448328, Usm.z, places=5) Lgm_Convert_Coords(ctypes.pointer(Usm), ctypes.pointer(Ugsm), SM_TO_GSM, ctypes.pointer(c)) self.assertAlmostEqual(-6.6, Ugsm.x) self.assertAlmostEqual( 3.4, Ugsm.y) self.assertAlmostEqual(-2.3, Ugsm.z)
def Lvalue(*args, **kwargs): ''' Function to return the L-value of a position using either McIlwain or Hilton approximation Parameters ========== pos : list 3-element position int he specified coord_system time : datetime date and time for the calculation alpha : float, optional the pitch angle for the L calculation, default=90 Bfield : str, optional the magnetic field model to use, default=Lgm_B_T89 method : str, optional the L-value formula to use, McIlwain or Hilton, default=Hilton Kp : int Kp index value for the calculation coord_system : str the input coordinate system, default=GSM extended_out : bool keyword specifying short or extended output, default=False Returns ======= out : dict dictionary of the values, see examples for documentation of dictionary Examples ======== >>> from lgmpy import magcoords >>> import datetime >>> magcoords.Lvalue([3, 0, 1], datetime.datetime(2000, 1, 1), extended_out=False) {'I': 0.2434969602..., 'L': 3.195481841...} The ``extended_out=False`` output is: - I : I value at the given point - L : L value at the given point >>> from lgmpy import magcoords >>> import datetime >>> magcoords.Lvalue([3, 0, 1], datetime.datetime(2000, 1, 1), extended_out=True) {'Blocal': 1024.1142193703838, 'Bmin': 921.8869150..., 'Bmirr': 1024.1142193..., 'I': 0.24349696021..., 'L': 3.1954818410..., 'M': 30119.614287...} The ``extended_out=True`` output is: - I : I value at the given point - L : L value at the given point - Bmin : minimum B at the input position (nT) - Bmirror : mirror B at the input position (nT) - M : TODO what exactly and I, magnetic moment? ''' defaults = { 'alpha': 90., 'Bfield': 'Lgm_B_T89', 'method': 'Hilton', 'Kp': 2, 'coord_system': 'GSM', 'extended_out': False } #replace missing kwargs with defaults for dkey in defaults: if dkey not in kwargs: kwargs[dkey] = defaults[dkey] method_dict = {'Hilton': 1, 'McIlwain': 0} # change datetime to Lgm Datelong and UTC mInfo = Lgm_MagModelInfo.Lgm_MagModelInfo() mInfo.Kp = kwargs['Kp'] try: Bfield_dict[kwargs['Bfield']](pointer(mInfo)) except KeyError: raise (NotImplementedError("Only Bfield=%s currently supported" % Bfield_dict.keys())) try: datelong = Lgm_CTrans.dateToDateLong(args[1]) utc = Lgm_CTrans.dateToFPHours(args[1]) Lgm_Set_Coord_Transforms(datelong, utc, mInfo.c) # dont need pointer as it is one except AttributeError: raise (TypeError("Date must be a datetime object")) #else: #ans['Epoch'] = datamodel.dmarray([args[1]]) if kwargs['coord_system'] != 'GSM': in_sys = kwargs['coord_system'] Pout = coordTrans(args[0], args[1], in_sys, 'GSM', de_eph=False) Pgsm = Lgm_Vector.Lgm_Vector(*Pout) else: Pgsm = Lgm_Vector.Lgm_Vector(*args[0]) Iout = c_double() Bm = c_double() M = c_double() ans = Lgm_McIlwain_L(datelong, utc, pointer(Pgsm), kwargs['alpha'], method_dict[kwargs['method']], pointer(Iout), pointer(Bm), pointer(M), pointer(mInfo)) #TODO: decide on format for output -- perhaps use datamodel and have method as attribute? #maybe only return I for extended_out flag=True if kwargs['extended_out']: sunPos_GSM = coordTrans(mInfo.c.contents.Sun, args[1], 'MOD', kwargs['coord_system']) SunMlon = np.rad2deg(np.arctan2(sunPos_GSM[1], sunPos_GSM[0])) SunMlon += 180.0 # flip to midnight MLON = np.rad2deg(np.arctan2(Pgsm.y, Pgsm.x)) if (MLON < 0.0): MLON += 360.0 MLT = np.mod((MLON - SunMlon) / 15.0 + 24.0, 24.0) return { 'L': ans, 'I': Iout.value, 'Bmin': mInfo.Bmin, 'Blocal': mInfo.Blocal, 'Bmirr': mInfo.Bm, 'M': M.value, 'MLon': MLON, 'MLT': MLT } else: return {'L': ans, 'I': Iout.value}
def test_Lgm_LoadLeapSeconds(self): """Lgm_LoadLeapSeconds should work and not change""" self.assertTrue(Lgm_LoadLeapSeconds(ctypes.pointer(self.c))) # The LeapSecondDates values are the dates that the given corrections came into effect. But the actual leap second # date is the day before -- thats when the extra second was tacked on. So subtract a day from each of the dates. LeapSecondDates = [ 19720101, 19720701, 19730101, 19740101, 19750101, 19760101, 19770101, 19780101, 19790101, 19800101, 19810701, 19820701, 19830701, 19850701, 19880101, 19900101, 19910101, 19920701, 19930701, 19940701, 19960101, 19970701, 19990101, 20060101, 20090101, ] LeapSecondJDs = [ 2441317.5, 2441499.5, 2441683.5, 2442048.5, 2442413.5, 2442778.5, 2443144.5, 2443509.5, 2443874.5, 2444239.5, 2444786.5, 2445151.5, 2445516.5, 2446247.5, 2447161.5, 2447892.5, 2448257.5, 2448804.5, 2449169.5, 2449534.5, 2450083.5, 2450630.5, 2451179.5, 2453736.5, 2454832.5, ] LeapSeconds = [ 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, ] LeapSecondDates = Lgm_CTrans.dateLongToDate(LeapSecondDates) LeapSecondDates = [ val - datetime.timedelta(days=1) for val in LeapSecondDates ] LeapSecondDates = Lgm_CTrans.dateToDateLong(LeapSecondDates) for i, (v1, v2, v3) in enumerate( zip(LeapSecondDates, LeapSecondJDs, LeapSeconds)): self.assertEqual(v1, self.c.l.LeapSecondDates[i]) self.assertEqual(v2, self.c.l.LeapSecondJDs[i]) self.assertEqual(v3, self.c.l.LeapSeconds[i])
def setUp(self): super(Lgm_DateAndTime_tests, self).setUp() self.c = Lgm_CTrans.Lgm_CTrans()
def getLatLonRadfromTLE(epochs, TLEpath, options): """ Reads Latitude and Longitude from TLE. Parameters ========== epochs : List of Ticktock objects. TLEpath : Path to TLE file. options : optparse.Values Organized options from the command line. Returns ======= testlat, testlon, testrad : list, list, list Latitude, Longitude, and Radius, respectively, each being a list of float values. """ # now do Mike's setup for getting coords from TLE using SGP4 pos_in = [0, 0, 0] s = _SgpInfo() TLEs = _SgpTLE() # loop over all times testlat = np.asarray(epochs).copy() testlat.fill(0) testlon = testlat.copy() testrad = testlat.copy() testtdiff = testlat.copy() print('Fetching TLEs & converting for range {0} to {1}'.format( epochs[0].isoformat(), epochs[-1].isoformat())) for idx, c_date in enumerate(epochs): #print('Doing {0}'.format(c_date)) # put into JD as SGP4 needs serial time c = Lgm_init_ctrans(0) # now do Mike's setup for getting coords from TLE using SGP4 dstr = int(c_date.strftime('%Y%j')) + c_date.hour / 24.0 + \ c_date.minute / 1440.0 + c_date.second / 86400.0 globstat = os.path.join(TLEpath, '*.txt') TLEfiles = glob.glob(globstat) if not TLEfiles: raise IOError( 'No TLE files found in {0}. Aborting...'.format(TLEpath)) Line0, Line1, Line2 = fTLE.findTLEinfiles( TLEfiles, ParseMethod='UseSatelliteNumber', TargetEpoch=dstr, SatelliteNumber=options.SatNum, Verbose=False, PurgeDuplicates=True) # print("{0}\n{1}\n{2}\n\n".format(Line0,Line1,Line2)) nTLEs = c_int(0) LgmSgp_ReadTlesFromStrings(Line0, Line1, Line2, pointer(nTLEs), pointer(TLEs), 1) LgmSgp_SGP4_Init(pointer(s), pointer(TLEs)) date = Lgm_CTrans.dateToDateLong(c_date) utc = Lgm_CTrans.dateToFPHours(c_date) JD = Lgm_JD(c_date.year, c_date.month, c_date.day, utc, LGM_TIME_SYS_UTC, c) # Set up the trans matrices Lgm_Set_Coord_Transforms(date, utc, c) # get SGP4 output, needs minutes-since-TLE-epoch tsince = (JD - TLEs.JD) * 1440.0 LgmSgp_SGP4(tsince, pointer(s)) pos_in[0] = s.X pos_in[1] = s.Y pos_in[2] = s.Z Pin = Lgm_Vector.Lgm_Vector(*pos_in) Pout = Lgm_Vector.Lgm_Vector() Lgm_Convert_Coords(pointer(Pin), pointer(Pout), TEME_TO_GEO, c) PoutPy = Pout.tolist() PoutPy[0] /= WGS84_A PoutPy[1] /= WGS84_A PoutPy[2] /= WGS84_A nlat, nlon, nrad = Lgm_Vector.CartToSph(*PoutPy) testlat[idx] = nlat testlon[idx] = nlon testrad[idx] = nrad testtdiff[idx] = tsince / 1440.0 return testlat, testlon, testrad
def Lvalue(*args, **kwargs): ''' Function to return the L-value of a position using either McIlwain or Hilton approximation Parameters ========== pos : list 3-element position int he specified coord_system time : datetime date and time for the calculation alpha : float, optional the pitch angle for the L calculation, default=90 Bfield : str, optional the magnetic field model to use, default=Lgm_B_T89 method : str, optional the L-value formula to use, McIlwain or Hilton, default=Hilton Kp : int Kp index value for the calculation coord_system : str the input coordinate system, default=GSM extended_out : bool keyword specifying short or extended output, default=False Returns ======= out : dict dictionary of the values, see examples for documentation of dictionary Examples ======== >>> from lgmpy import magcoords >>> import datetime >>> magcoords.Lvalue([3, 0, 1], datetime.datetime(2000, 1, 1), extended_out=False) {'I': 0.2434969602..., 'L': 3.195481841...} The ``extended_out=False`` output is: - I : I value at the given point - L : L value at the given point >>> from lgmpy import magcoords >>> import datetime >>> magcoords.Lvalue([3, 0, 1], datetime.datetime(2000, 1, 1), extended_out=True) {'Blocal': 1024.1142193703838, 'Bmin': 921.8869150..., 'Bmirr': 1024.1142193..., 'I': 0.24349696021..., 'L': 3.1954818410..., 'M': 30119.614287...} The ``extended_out=True`` output is: - I : I value at the given point - L : L value at the given point - Bmin : minimum B at the input position (nT) - Bmirror : mirror B at the input position (nT) - M : TODO what exactly and I, magnetic moment? ''' defaults = {'alpha': 90., 'Bfield': 'Lgm_B_T89', 'method': 'Hilton', 'Kp': 2, 'coord_system': 'GSM', 'extended_out': False} #replace missing kwargs with defaults for dkey in defaults: if dkey not in kwargs: kwargs[dkey] = defaults[dkey] method_dict = {'Hilton': 1, 'McIlwain': 0} # change datetime to Lgm Datelong and UTC mInfo = Lgm_MagModelInfo.Lgm_MagModelInfo() mInfo.Kp = kwargs['Kp'] try: Bfield_dict[kwargs['Bfield']](pointer(mInfo)) except KeyError: raise(NotImplementedError("Only Bfield=%s currently supported" % Bfield_dict.keys())) try: datelong = Lgm_CTrans.dateToDateLong(args[1]) utc = Lgm_CTrans.dateToFPHours(args[1]) Lgm_Set_Coord_Transforms( datelong, utc, mInfo.c) # dont need pointer as it is one except AttributeError: raise(TypeError("Date must be a datetime object")) #else: #ans['Epoch'] = datamodel.dmarray([args[1]]) if kwargs['coord_system'] != 'GSM': in_sys = kwargs['coord_system'] Pout = coordTrans(args[0], args[1], in_sys, 'GSM', de_eph=False) Pgsm = Lgm_Vector.Lgm_Vector(*Pout) else: Pgsm = Lgm_Vector.Lgm_Vector(*args[0]) Iout = c_double() Bm = c_double() M = c_double() ans = Lgm_McIlwain_L(datelong, utc, pointer(Pgsm), kwargs['alpha'], method_dict[kwargs['method']], pointer(Iout), pointer(Bm), pointer(M), pointer(mInfo)) #TODO: decide on format for output -- perhaps use datamodel and have method as attribute? #maybe only return I for extended_out flag=True if kwargs['extended_out']: sunPos_GSM = coordTrans(mInfo.c.contents.Sun, args[1], 'MOD', kwargs['coord_system']) SunMlon = np.rad2deg(np.arctan2( sunPos_GSM[1], sunPos_GSM[0])) SunMlon += 180.0 # flip to midnight MLON = np.rad2deg(np.arctan2( Pgsm.y, Pgsm.x)) if (MLON < 0.0): MLON += 360.0 MLT = np.mod( (MLON-SunMlon)/15.0+24.0, 24.0 ) return {'L': ans, 'I': Iout.value, 'Bmin': mInfo.Bmin, 'Blocal': mInfo.Blocal, 'Bmirr': mInfo.Bm, 'M': M.value, 'MLon':MLON, 'MLT':MLT} else: return {'L': ans, 'I': Iout.value}
def coordTrans(pos_in, time_in, in_sys, out_sys, de_eph=False): ''' Convert coordinates between almost any system using LanlGeoMag Parameters ---------- position : list a three element vector of positions in input coord system time : datetime a datimetime object representing the time at the desired conversion system_in : str a string giving the acronym for the input coordinate system system_out : str a string giving the acronym for the desired output coordinate system de_eph : bool or int (optional) a boolean stating whether JPL DE421 is to be used for Sun, etc. Returns ------- out : list 3-element list of the converted coordinate Examples -------- >>> from lgmpy import magcoords >>> import datetime >>> magcoords.coordTrans([-4,0,0], datetime.datetime(2009,1,1),'SM','GSM') [-3.60802691..., 2.5673907444...e-16, -1.72688788616...] >>> magcoords.coordTrans([-3.608026916281573, 2.5673907444456745e-16, -1.7268878861662329], datetime.datetime(2009,1,1),'GSM','SM') [-3.99999999..., 4.0592529337...e-16, 8.8817841970...3e-16] TODO ---- extend interface to get necessary args from a MagModel or cTrans structure ''' # change datetime to Lgm Datelong and UTC ct = Lgm_CTrans.Lgm_CTrans(0) if de_eph: Lgm_Set_CTrans_Options(LGM_EPH_DE, LGM_PN_IAU76, pointer(ct)) try: datelong = Lgm_CTrans.dateToDateLong(time_in) utc = Lgm_CTrans.dateToFPHours(time_in) Lgm_Set_Coord_Transforms( datelong, utc, pointer(ct)) # don't need pointer as it is one except AttributeError: raise(TypeError("Date must be a datetime object")) try: conv_val = trans_dict[in_sys]*100 + trans_dict[out_sys] except KeyError: raise KeyError('One of the specified coordinate systems is not recognised') ## do this as WGS uses Cartesian but needs to be converted from desired spherical input if 'WGS84' in in_sys: XYZ = Lgm_Vector.SphToCart(*pos_in) SPH = Lgm_Vector.Lgm_Vector(XYZ.x,XYZ.y, XYZ.z) Pout = _doConversion(SPH, conv_val, cTrans=ct) else: Pout = _doConversion(pos_in, conv_val, ct) if 'WGS84' in out_sys: nlat, nlon, nrad = Lgm_Vector.CartToSph(*Pout.tolist()) Pout = Lgm_Vector.Lgm_Vector(nlat, nlon, nrad) return Pout.tolist()
def getLatLonRadfromTLE(epochs, TLEpath, options): """ Reads Latitude and Longitude from TLE. Parameters ========== epochs : List of Ticktock objects. TLEpath : Path to TLE file. options : optparse.Values Organized options from the command line. Returns ======= testlat, testlon, testrad : list, list, list Latitude, Longitude, and Radius, respectively, each being a list of float values. """ # now do Mike's setup for getting coords from TLE using SGP4 pos_in = [0, 0, 0] s = _SgpInfo() TLEs = _SgpTLE() # loop over all times testlat = np.asarray(epochs).copy() testlat.fill(0) testlon = testlat.copy() testrad = testlat.copy() testtdiff = testlat.copy() print('Fetching TLEs & converting for range {0} to {1}'.format( epochs[0].isoformat(), epochs[-1].isoformat())) for idx, c_date in enumerate(epochs): #print('Doing {0}'.format(c_date)) # put into JD as SGP4 needs serial time c = Lgm_init_ctrans(0) # now do Mike's setup for getting coords from TLE using SGP4 dstr = int(c_date.strftime('%Y%j')) + c_date.hour / 24.0 + \ c_date.minute / 1440.0 + c_date.second / 86400.0 globstat = os.path.join(TLEpath, '*.txt') TLEfiles = glob.glob(globstat) if not TLEfiles: raise IOError( 'No TLE files found in {0}. Aborting...'.format(TLEpath)) Line0, Line1, Line2 = fTLE.findTLEinfiles( TLEfiles, ParseMethod='UseSatelliteNumber', TargetEpoch=dstr, SatelliteNumber=options.SatNum, Verbose=False, PurgeDuplicates=True) # print("{0}\n{1}\n{2}\n\n".format(Line0,Line1,Line2)) nTLEs = c_int(0) LgmSgp_ReadTlesFromStrings( Line0, Line1, Line2, pointer(nTLEs), pointer(TLEs), 1) LgmSgp_SGP4_Init(pointer(s), pointer(TLEs)) date = Lgm_CTrans.dateToDateLong(c_date) utc = Lgm_CTrans.dateToFPHours(c_date) JD = Lgm_JD( c_date.year, c_date.month, c_date.day, utc, LGM_TIME_SYS_UTC, c) # Set up the trans matrices Lgm_Set_Coord_Transforms(date, utc, c) # get SGP4 output, needs minutes-since-TLE-epoch tsince = (JD - TLEs.JD) * 1440.0 LgmSgp_SGP4(tsince, pointer(s)) pos_in[0] = s.X pos_in[1] = s.Y pos_in[2] = s.Z Pin = Lgm_Vector.Lgm_Vector(*pos_in) Pout = Lgm_Vector.Lgm_Vector() Lgm_Convert_Coords(pointer(Pin), pointer(Pout), TEME_TO_GEO, c) PoutPy = Pout.tolist() PoutPy[0] /= WGS84_A PoutPy[1] /= WGS84_A PoutPy[2] /= WGS84_A nlat, nlon, nrad = Lgm_Vector.CartToSph(*PoutPy) testlat[idx] = nlat testlon[idx] = nlon testrad[idx] = nrad testtdiff[idx] = tsince / 1440.0 return testlat, testlon, testrad
def coordTrans(pos_in, time_in, in_sys, out_sys, de_eph=False): ''' Convert coordinates between almost any system using LanlGeoMag Parameters ---------- position : list a three element vector of positions in input coord system time : datetime a datimetime object representing the time at the desired conversion system_in : str a string giving the acronym for the input coordinate system system_out : str a string giving the acronym for the desired output coordinate system de_eph : bool or int (optional) a boolean stating whether JPL DE421 is to be used for Sun, etc. Returns ------- out : list 3-element list of the converted coordinate Examples -------- >>> from lgmpy import magcoords >>> import datetime >>> magcoords.coordTrans([-4,0,0], datetime.datetime(2009,1,1),'SM','GSM') [-3.60802691..., 2.5673907444...e-16, -1.72688788616...] >>> magcoords.coordTrans([-3.608026916281573, 2.5673907444456745e-16, -1.7268878861662329], datetime.datetime(2009,1,1),'GSM','SM') [-3.99999999..., 4.0592529337...e-16, 8.8817841970...3e-16] TODO ---- extend interface to get necessary args from a MagModel or cTrans structure ''' # change datetime to Lgm Datelong and UTC ct = Lgm_CTrans.Lgm_CTrans(0) if de_eph: Lgm_Set_CTrans_Options(LGM_EPH_DE, LGM_PN_IAU76, pointer(ct)) try: datelong = Lgm_CTrans.dateToDateLong(time_in) utc = Lgm_CTrans.dateToFPHours(time_in) Lgm_Set_Coord_Transforms( datelong, utc, pointer(ct)) # don't need pointer as it is one except AttributeError: raise (TypeError("Date must be a datetime object")) try: conv_val = trans_dict[in_sys] * 100 + trans_dict[out_sys] except KeyError: raise KeyError( 'One of the specified coordinate systems is not recognised') ## do this as WGS uses Cartesian but needs to be converted from desired spherical input if 'WGS84' in in_sys: XYZ = Lgm_Vector.SphToCart(*pos_in) SPH = Lgm_Vector.Lgm_Vector(XYZ.x, XYZ.y, XYZ.z) Pout = _doConversion(SPH, conv_val, cTrans=ct) else: Pout = _doConversion(pos_in, conv_val, ct) if 'WGS84' in out_sys: nlat, nlon, nrad = Lgm_Vector.CartToSph(*Pout.tolist()) Pout = Lgm_Vector.Lgm_Vector(nlat, nlon, nrad) return Pout.tolist()