-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathworker.py
More file actions
184 lines (132 loc) · 5.67 KB
/
Copy pathworker.py
File metadata and controls
184 lines (132 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#This script will do the heavy lifting
#Keplerian solver
import math
import operator
import datetime
from datetime import datetime
from datetime import timedelta
from PyKEP import *
#General
import json
import sys
#Boto
import boto
from boto.sqs.connection import SQSConnection
from boto.sqs.message import Message
#Tornado (initially blocking HTTP requests, later vision is to have calculations nonblocking in ioloop)
import tornado.httpclient as httpclient
from configobj import ConfigObj
#MongdoDB
import pymongo
from pymongo import MongoClient
from bson import json_util
from bson.objectid import ObjectId
mongoClient = MongoClient('mongodb://localhost:27017/')
db = mongoClient['interplan']
objects = db.objects
#Get config
config = ConfigObj('server.conf')
#TODO: Write lightweight library for storing auth info + sending/recieving info using REST
#Question: Possible to make functions become non-blocking (long polling), calling a function when resuts are ready??
# 1) Get planet / asteroid objects from the information
# 2) Set up the calculations (dates, etc)
# 3) Perform calculations and every 1% report status + latest pixels to QUEUE
# 4) Future: Cache orbital results.
# 5) Replace SQS Longpolling and REST Post through my server to a WEBSOCKET interface in Python OR a REST CALLBACK solution in Python (better??) - REST call to tell server I'm ready to recieve.
# MAJOR BUG NOW: Too much data - server side binning of data or other smart way of compressing data flow ??
#Set up nonblocking HTTP client
http_client = httpclient.HTTPClient()
#Set up AWS SQS
conn = boto.sqs.connect_to_region('eu-west-1')
if bool(config['server']['devMode']) is True:
jobQueue = conn.create_queue('interplanJobQueueDev')
else:
jobQueue = conn.create_queue('interplanJobQueue')
#Function to validate incoming data and add zeroes where needed
required = ['epoch_mjd', 'a', 'e', 'i', 'om', 'w', 'ma', 'GM']
def checkData(data):
for item in required:
if data[item] == '':
data[item] = '0'
resFactor = 5;
#TODO: Remake into nonblocking ioloop
while True:
print 'Will long-poll for message'
m = jobQueue.read(wait_time_seconds=20)
if m is not None:
data = json.loads(m.get_body())
jobQueue.delete_message(m)
try:
print 'Got new Job Request: ', data
dep = db.objects.find_one({'_id': ObjectId(data['departure']['_id'])})
des = db.objects.find_one({'_id': ObjectId(data['destination']['_id'])})
depDia = 10.0;
if dep['diameter']:
depDia = float(dep['diameter']) / 2.0
checkData(dep)
depObject = planet(epoch(float(dep['epoch_mjd']),epoch.epoch_type.MJD), (float(dep['a']) * AU, float(dep['e']), float(dep['i'])*DEG2RAD, float(dep['om'])*DEG2RAD, float(dep['w'])*DEG2RAD, float(dep['ma'])*DEG2RAD), MU_SUN, 0.001 + float(dep['GM']), depDia, depDia*1.1)
desDia = 100;
if des['diameter']:
desDia = float(des['diameter']) / 2.0
checkData(des)
desObject = planet(epoch(float(des['epoch_mjd']),epoch.epoch_type.MJD), (float(des['a']) * AU, float(des['e']), float(des['i'])*DEG2RAD, float(des['om'])*DEG2RAD, float(des['w'])*DEG2RAD, float(des['ma'])*DEG2RAD), MU_SUN, 0.001 + float(des['GM']), desDia, desDia*1.1)
#TODO: Remove verification ??? OR KEEP IT LOGS - KEWLT
print depObject, desObject
start = datetime.strptime(data['windowStart'], '%Y-%m-%d')
start -= timedelta(days=1)
stop = datetime.strptime(data['windowStop'], '%Y-%m-%d')
stop += timedelta(days=1)
windowDuration = (stop-start).days
travelMin = data['minTT']
travelMax = data['maxTT']
print 'start time: ',start
print 'end time',stop
print 'duration: ', windowDuration
dataBuf = []
calcCounter = 0;
for windowDay in range(0,windowDuration/resFactor):
t0 = start + timedelta(days=resFactor*windowDay)
epoch0 = epoch_from_string(t0.isoformat(' '))
for missionDay in range(travelMin/resFactor, travelMax/resFactor):
t1 = t0 + timedelta(days=resFactor*missionDay)
epoch1 = epoch_from_string(t1.isoformat(' '))
transitTime = epoch1.mjd2000 - epoch0.mjd2000
r0, v0 = depObject.eph(epoch0)
r1, v1 = desObject.eph(epoch1)
l = lambert_problem(r0, r1, transitTime*DAY2SEC, MU_SUN)
depV = l.get_v1()
arrV = l.get_v2()
dv = tuple(map(operator.sub, depV[0], v0))
depRelV = 0
for x in dv:
depRelV += x*x
depRelV = math.sqrt(depRelV)
depC3 = depRelV**2/1000.0**2
dv = tuple(map(operator.sub, arrV[0], v1))
arrRelV = 0
for x in dv:
arrRelV += x*x
arrRelV = math.sqrt(arrRelV)
outData = [ [ windowDay*resFactor, missionDay*resFactor ], round(depC3,1), round(arrRelV,0)]
dataBuf.append(outData)
calcCounter += 1
#TODO: PERCENTAGE COUNTER MESSAGES
if calcCounter%100 == 0:
print 100.0*windowDay*resFactor/windowDuration
try:
print 'WILL SEND A'
response = http_client.fetch(httpclient.HTTPRequest(url="https://api.jsflow.com/v1/user/%s/%s" % (data['fromId'], 'dataPoint'), method='POST', body=json.dumps(dataBuf), validate_cert=False, auth_username='0d0bc8630706bf0fc8c1e9a2', auth_password='4qKcmmFCOjliJ7I1S6CkbsGnR8Q='))
print response.body
except httpclient.HTTPError, e:
print "Error:", e
dataBuf = []
print 'done!'
try:
print 'WILL SEND B'
response = http_client.fetch(httpclient.HTTPRequest(url="https://api.jsflow.com/v1/user/%s/%s" % (data['fromId'], 'dataPoint'), method='POST', body=json.dumps(dataBuf), validate_cert=False, auth_username='0d0bc8630706bf0fc8c1e9a2', auth_password='4qKcmmFCOjliJ7I1S6CkbsGnR8Q='))
print response.body
except httpclient.HTTPError, e:
print "Error:", e
except:
e = sys.exc_info()
print ('Error processing job. Exception %s %s' % (e[0],e[1]))