def satpass(tmin, tmax): def nextpass(u): # Update target for rise/set calculations by updating tle rise, fall = 0, -1 while rise>fall: self.obs.date = ephem.Date(u) # Set obs. date target = ephem.readtle('TLE0',*tle.mount(u).split(',')) # Set appropriate TLE passdata = self.obs.next_pass(target) # Compute passdata print passdata rise, fall = float(passdata[0]), float(passdata[4]) print passdata[2], passdata[3] u = tm(u).eph()-ephem.minute return rise, fall # Return rise/set times passes = [] # Create container umin, umax = tm(tmin).eph(), tm(tmax).eph() # Convert to Julian dates for sat in self.sats.values(): tle = TLE_config(sat, tmax) # Mount TLE database file rise, fall = nextpass(umin) # Find first pass while rise<umax: passes.append(Pass(sat,tm(rise),tm(fall),tle.now)) # Add pass info rise, fall = nextpass(fall+5*ephem.second) # Find next pass return passes
def printout1(self, tmin, tmax, show, passfile): #Print satellite pass search bounds if show: if passfile: print 'Retrieving satellite passes from file (truncated at bounds)...' else: print 'Calculating satellite passes (truncated at bounds)...' print 'From: %.1f -> %s\nTo: %.1f -> %s\n'%(tm(tmin).utc,tm(tmin).eph(), tm(tmax).utc,tm(tmax).eph()) return
def passes(self, tmin, tmax, passfile=floc['Nov2015'], saveas=None, show=True): """Finds rise and set times of all passes falling within bounds Note: next_pass returns the following data as a tuple: 0- Rise time, 1- Rise azimuth 2- Max alt time, 3- Max alt 4- Set time, 5- Set azimuth """ def satpass(tmin, tmax): def nextpass(u): # Update target for rise/set calculations by updating tle rise, fall = 0, -1 while rise>fall: self.obs.date = ephem.Date(u) # Set obs. date target = ephem.readtle('TLE0',*tle.mount(u).split(',')) # Set appropriate TLE passdata = self.obs.next_pass(target) # Compute passdata print passdata rise, fall = float(passdata[0]), float(passdata[4]) print passdata[2], passdata[3] u = tm(u).eph()-ephem.minute return rise, fall # Return rise/set times passes = [] # Create container umin, umax = tm(tmin).eph(), tm(tmax).eph() # Convert to Julian dates for sat in self.sats.values(): tle = TLE_config(sat, tmax) # Mount TLE database file rise, fall = nextpass(umin) # Find first pass while rise<umax: passes.append(Pass(sat,tm(rise),tm(fall),tle.now)) # Add pass info rise, fall = nextpass(fall+5*ephem.second) # Find next pass return passes #Either calculate data or load from previously calculated data self.passlist = [] self.printout1(tmin,tmax,show,passfile) # Print satpass range if passfile: with open(passfile) as f: for line in f: dat = line.strip().split(';') self.passlist.append(Pass(self.sats[dat[0]],tm(dat[1]),tm(dat[2]),dat[3])) else: sortkey = lambda x: (x.rise,x.fall) # Pass sorting method self.passlist = sorted(satpass(tmin,tmax), key=sortkey) # Produce passlist self.printout2(self.passlist, self.sats, show) # Print passes if saveas: with open(saveas,'w+') as f: [f.write('%s;%.2f;%.2f;%s\n'%(p.sat.ID,tm(p.rise).utc,tm(p.fall).utc,p.TLE)) for p in passlist] return self.passlist
def mount(self, t): t = tm(t) # Convert to tm time if tm(self.now, 'tle') > t: # For backtracking self.load() while tm(self.nxt, 'tle') <= t: # Find last TLE before t try: self.now = self.nxt self.nxt = self.data.next().strip() except StopIteration: break return self.now
def printout2(self, plist, sats, show): #Print number of passes found for each satellite print '' if show: # Print pass data tabform = '%-8s%-12s%-24s%-24s' dform = '%Y/%m/%d %H:%M:%S' print tabform%('Pass:'******'Sat:','Rise:','Set:') for i,p in zip(range(len(plist)),plist): print ' '+tabform%(i+1, p.sat.desig ,tm(p.rise).cal(dform), tm(p.fall).cal(dform)) # Print pass count per satellite nstring = ''.join([i.sat.desig for i in plist]) pcount = [(s.desig, nstring.count(s.desig)) for s in sats.values()] print '\nPasscount: %d'%sum(i[1] for i in pcount) for s in range(len(pcount)): print '%s %-8s: %d '%('' if s%4 else '\n',pcount[s][0],pcount[s][1]), print '\n' if s%4 else '' return
def compute(u, seek=False): # Keep constant tle for ephemeris calculation over single pass self.obs.date = ephem.Date(u.eph()) self.target.compute(self.obs) alt_rad=self.target.alt alt_deg=(alt_rad/np.pi)*180.0 az_rad=self.target.az az_deg=(az_rad/np.pi)*180.0 return [tm(self.obs.date).utc, alt_deg, az_deg]
def geteph(timestamps): # Compute eph for single pass- operates in the form: target.compute(obs) timestamps = [tm(float(t)) for t in timestamps] for sat in self.sats.values(): if (sat.desig == satellite_desig): sat_tuple=sat tle = TLE_config(sat_tuple, t_max) # Mount TLE database file #print "latest TLE is from %s " % (tle.lastrecord()) self.target = ephem.readtle('TLE0',*tle.mount(t_max).split(',')) # Set appropriate TLE #self.target = ephem.readtle('TLE0',*satpass.TLE.split(',')) eph = [compute(u) for u in timestamps] return np.swapaxes(eph,0,1)
def nextpass(u): # Update target for rise/set calculations by updating tle rise, fall = 0, -1 while rise>fall: self.obs.date = ephem.Date(u) # Set obs. date target = ephem.readtle('TLE0',*tle.mount(u).split(',')) # Set appropriate TLE passdata = self.obs.next_pass(target) # Compute passdata print passdata rise, fall = float(passdata[0]), float(passdata[4]) print passdata[2], passdata[3] u = tm(u).eph()-ephem.minute return rise, fall # Return rise/set times
def ephemeris(self, satpass=None, timestamps=None, ephfile=None, saveas=None, quiet=True): """Calculates ephemeris for passes within trange using step size tstep (excluding right bound if tmax-tmin%tstep!=0) to produce a list of numpy arrays in t,alt,azi""" if ephfile: data = [line.strip().split(',') for line in open(ephfile)] return [[float(j) for j in i] for i in data] def compute(u, seek=False): # Keep constant tle for ephemeris calculation over single pass self.obs.date = ephem.Date(u.eph()) self.target.compute(self.obs) return [tm(self.obs.date).utc, self.target.alt, self.target.az] # Compute eph for single pass- operates in the form: target.compute(obs) timestamps = [tm(t) for t in timestamps if tm(t)>satpass.rise and tm(t)<satpass.fall] self.target = ephem.readtle('TLE0',*satpass.TLE.split(',')) eph = [compute(u) for u in timestamps] if saveas: with open(saveas,'w+') as f: [f.write('%.2f,%f,%f\n'%(e[0],e[1],e[2])) for e in eph] #return np.swapaxes(eph,0,1) return eph
def __init__(self, sat, tmax, uid=ST['login'], lim=None): self.sat = sat.ID # Associate class instance to NORAD ID print "Sat is %s" % self.sat self.tlefile = floc[ 'TLEpath'] % self.sat # Define TLE database location for sat print "looking in %s " % self.tlefile # Use tail to check last TLE, update if required tmax = tm(tmax) #print "tmax is %s" % tmax result = read['tail'](self.tlefile) #print "result is %s" % result tlelast = tm(result, 'tle') if result else tm(ST['newTLE']) #print "tlelast was %s" % tlelast #tlelast.utc = tlelast.utc + 100000 #print "tlelast is now %s" % tlelast #print "tm(ST['newTLE'] is %s" % tm(ST['newTLE']) #print "tlelast is %s " % tlelast print 'Sat %s: Checking database...\n' % self.sat, # If required, repeatedly pull tles from SpaceTrack until all>tmax print 'tlelast,tmax', tlelast, tmax while tlelast < tmax: #wait for 5 secs as you are only allowed 20 queries per minute time.sleep(5) dfrom, dupto = tm(tlelast - ST['safety']), tm(tlelast + ST['chunk']) query = ST['query'] % (self.sat, dfrom, dupto, 'limit/%d/' if lim else "") print "Requesting update from SpaceTrack:\n\n%s\n" % query os.system(ST['request'] % (uid[0], uid[1], query, ST['cookies'], ST['dload'])) print 'Validating and distributing to database...', #print ST['dload'] with open(ST['dload']) as f: for d in f: tlestring = '%s,%s\n' % (d.strip(), f.next().strip()) tletime = tm(tlestring, 'tle') if tletime > tlelast: open(self.tlefile, 'a').write(tlestring) tlelast = tletime if dupto > tmax: break tlelast = tm(tlelast + chunk) print 'OK' self.data = open(self.validate()) # Validate then mount database self.load() # Load initial TLE
def compute(u, seek=False): # Keep constant tle for ephemeris calculation over single pass self.obs.date = ephem.Date(u.eph()) self.target.compute(self.obs) return [tm(self.obs.date).utc, self.target.alt, self.target.az]