harvey.py
9.18 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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#! /bin/env python
# coding: utf8
import numpy as np
import mms_tools_lib as mms
import os
import datetime
import matplotlib.pyplot as plt
import scipy.interpolate as scpinterp
import scipy.optimize as scpopt
class calc_harvey(object) :
"""
harvey algorithm routine setup with MMS initialization
"""
def __init__(self, orbit_files = None, data_files = None, orbite_vars = None, difftime_vars = None) :
self.info = {}
#self._init_default_info()
if orbit_files.any : self.info['orbit_files'] = orbit_files
if data_files.any : self.info['data_files'] = data_files
if orbite_vars.any : self.info['orbite_vars'] = orbite_vars
if difftime_vars.any : self.info['data_cross'] = difftime_vars
self.satpostot = np.array([mms.donnee(fichier).get_data_as_field(varz = self.info['orbite_vars'], withtime = True) for fichier in self.info['orbit_files']])
def evaluate_harvey(self, ij = [0,0], td = None, tf = None) :
if not td : td = mms.donnee(self.info['data_files'][0]).donnee['epoch'][0]
if not tf : tf = mms.donnee(self.info['data_files'][0]).donnee['epoch'][-1]
#ij = [0,0]
def g2(ij) :
t1 = td + datetime.timedelta(seconds = ij[0])
t2 = tf - datetime.timedelta(seconds = ij[1])
Btot = np.array([mms.donnee(Bsat).get_data_as_field(varz = self.info['data_cross'], t1 = t1, t2 = t2, withtime = True) for Bsat in self.info['data_files']])
res = harvey(pos_vel = self.satpostot, data_timing = Btot)
return res
self.harvey = g2(ij)
self.results = self.harvey.results
def optimize_crossing(self) :
"""
This function helps finding the best differential timings in order to estimate Harvey method
NOTE : THIS IS TOTALLY NOT OPTIMIZED!! Many useless calls are made. and probably useless.... :(
"""
td = mms.donnee(self.info['data_files'][0]).donnee['epoch'][0]
tf = mms.donnee(self.info['data_files'][0]).donnee['epoch'][-1]
maxvar = (tf - td).total_seconds()
def g(ij) : #input time in seconds to change the correlation interval, return max correlation coefficient
t1 = td + datetime.timedelta(seconds = ij[0])
t2 = tf - datetime.timedelta(seconds = ij[1])
Btot = np.array([mms.donnee(Bsat).get_data_as_field(varz = self.info['data_cross'], t1 = t1, t2 = t2, withtime = True) for Bsat in self.info['data_files']])
res = harvey(data_timing = Btot, calc_harvey = False)
return 1. - np.mean([max(corr) for corr in res.results['correlation_functions']])
ij = np.array([0,0])
#methodes = ['Powell' , 'L-BFGS-B', 'TNC', 'COBYLA', 'SLSQP', 'trust-ncg']
#for meth in methodes :
#print 'calculating with ', meth
#res = scpopt.minimize(g, ij, bounds = [(0., maxvar/2.), (0, maxvar/2.)] , method = meth)
#print res
self.corr = np.zeros([20,20])
for i1,i in enumerate(np.linspace(0,10,20)) :
for j1,j in enumerate(np.linspace(0,10,20)) :
print i1,j1
ij = [i,j]
self.corr[i1,j1] = g(ij)
#res = scpopt.basinhopping(g, ij, niter = 20, stepsize = 0.5)
print self.corr
def _init_default_info(self):
self.info['orbite_vars'] = ['mec_rx_gse', 'mec_ry_gse', 'mec_rz_gse', 'mec_vx_gse', 'mec_vy_gse', 'mec_vz_gse']
self.info['data_cross'] = ['fgm_by_gse_brst_l2']
rep = 'time_table_20150908_100807_20150908_100844'
baserep = os.curdir
rep = os.path.join(baserep, rep)
mecsat1 = os.path.join(rep, 'obj7.cef')
mecsat2 = os.path.join(rep, 'obj8.cef')
mecsat3 = os.path.join(rep, 'obj9.cef')
mecsat4 = os.path.join(rep, 'obj10.cef')
self.info['orbit_files'] = [mecsat1, mecsat2, mecsat3, mecsat4]
Bsat1 = os.path.join(rep, 'obj3.cef')
Bsat2 = os.path.join(rep, 'obj4.cef')
Bsat3 = os.path.join(rep, 'obj5.cef')
Bsat4 = os.path.join(rep, 'obj6.cef')
self.info['data_files'] = [Bsat1, Bsat2, Bsat3, Bsat4]
class harvey(object) :
"""
Differential timing calculation
Input : Time + x,y,z satelite positions + vx,vy,vz satelite velocities (total = 7 columns) * 4 Satellites * N data
This must be provided as a numpy array such as : pos_vel[0,:,:] provides data for satellite 1
pos_vel[2,:,3] provides all z positions of satellite 3.
Structure: pos_vel = np.zeros([n_satellites ( = 4), data size, number of expected variables ( = 7)])
data_timing: set of data used to correlate the timing, for automatic differential timings deduction
Structure: data_timing[1,:,1] provide all data for satellite 2
np.zeros([n_satellite (= 4), size of data, 2 (for time and data value)])
NOTE: RESULTS ARE PROVIDED IN SELF.RESULTS
"""
def __init__(self, pos_vel = np.zeros([4,10,7]), data_timing = np.zeros([4,10,2]), calc_harvey = True) :
self.results = {}
self._time_reference = data_timing[0][0,0]
self.data_timing = data_timing
self._find_crossing()
if calc_harvey :
self.pos_vel = pos_vel
self._calc()
def _calc(self) :
"""
Methodology :
1. for all spacecraft : interpolate the position of each spacecraft at t = timing
2. find mesocentre position
3. derive distance each SC from mesocentre
4. Build covariance matrix of delta_to_mesocentre
5.
"""
j = 0 #### USE ONLY FIRST LINE OF DATA : COULD BE IMPROVED!
new_pos = np.zeros([4,3])
for i, sc_data in enumerate(self.pos_vel) :
delta_t = (self.timing[i] - sc_data[:,0])[j].total_seconds()
new_pos[i,:] = sc_data[j,1:4] + sc_data[j,4:7] * delta_t
pos_vel_meso = new_pos.mean(axis = 0)
#print 'pos mesocentre : ', '\n', pos_vel_meso
#### à vérifier : calcul de delta_sc_pos : utiliser new pos ou old pos?
delta_sc_pos = new_pos[:,:] - pos_vel_meso[:]
#print 'delta sc to meso : ', '\n', delta_sc_pos
matrice = np.mat(np.zeros([3,3]))
for i in range(3) :
for j in range(3) :
matrice[i,j] = (delta_sc_pos[:,i] * delta_sc_pos[:,j]).mean()
invr = np.linalg.inv(matrice)
vect_base = np.zeros(3)
for i in range(3) :
for j in range(3) :
vect_base[i] = vect_base[i] + (self.timing_seconds[:] * delta_sc_pos[:,j]).mean() * invr[i,j]
self.results['normal_velocity'] = 1./np.linalg.norm(vect_base)
self.results['normal_vector'] = vect_base * self.results['normal_velocity']
def _find_crossing(self, bestfit = False) :
"""
1. interpolation des données de B2,3 et 4 sur abscisse de 1
2. Input data to self.getDiffTiming()
"""
data = np.zeros([4, len(self.data_timing[0][:,0])])
data[0,:] = self.data_timing[0][:,1]
for i, sc_data in enumerate(self.data_timing[1:]):
data[i+1,:] = mms.time_interpolation(self.data_timing[0][:,0], sc_data[:,0], sc_data[:,1])
if bestfit :
ind = self.search_best_fit()
self.getDiffTiming(time_axis = self.data_timing[0][ind:-ind,0], data = data[:,ind:-ind])
else : self.getDiffTiming(time_axis = self.data_timing[0][:,0], data = data)
def getDiffTiming(self, time_axis = np.zeros(100), data = np.zeros([4,100])):
"""
Input time_axis = refence time abscisse
Input data = all interpolated data for all spacecraft
"""
self.timing = []
self.results['differential_timings'] = []
self.results['correlation_functions'] = []
ord1 = self._normalize(data[0,:])/len(data[0,:])
for sc in data:
res = np.correlate(ord1, sc, mode = 'same')
self.timing.append(time_axis[res.argmax()])
self.results['correlation_functions'].append(res)
self.results['differential_timings'] = np.array([(time - self.timing[0]).total_seconds() for time in self.timing])
self.timing_seconds = np.array([(time - self._time_reference).total_seconds() for time in self.timing]) #FOR SC position interpolation!!
def _normalize(self, data) :
return (data - data.mean())/data.std()
def search_best_fit(self, n = 10):
"""
Search for best correlation coefficient
Method: cut data into n time blocks
1st step: calculate correlation coefficient
2nd step: remove extreme left and right blocks -> recorrelate
3rd: repeat
"""
block = int(len(self.data_timing[0][:,0]) / (2.*n))
maxcorr = np.zeros([n,4])
# Set all data to same time axis (the one of Sat1):
data = np.zeros([4, len(self.data_timing[0][:,0])])
data[0,:] = self.data_timing[0][:,1]
for i, sc_data in enumerate(self.data_timing[1:]):
data[i+1,:] = mms.time_interpolation(self.data_timing[0][:,0], sc_data[:,0], sc_data[:,1])
maxcorr[0,:] = [np.correlate(self._normalize(data[0,:])/len(data[0,:]), self._normalize(data[i,:])).max() for i in [0,1,2,3]]
for j in range(1,n):
d = block*j
maxcorr[j,:] = [np.correlate(self._normalize(data[0, d:-d])/len(data[0,d:-d]), self._normalize(data[i, d:-d]), 'same').max() for i in [0,1,2,3]]
best_indice = np.array([np.linalg.norm(i) for i in maxcorr]).argmax()
return block*best_indice
def plot(self) :
plt.figure()
barre = [self.data_timing[0][:,1].min(), self.data_timing[0][:,1].max()]
for i, champ in enumerate(self.data_timing) :
plt.plot(champ[:,0], champ[:,1], label = str(i))
plt.plot([self.timing[i], self.timing[i]], barre)
plt.legend()
plt.show()
def plot_hodo(self) :
champ2 = mms.time_interpolation(self.data_timing[0][:,0], self.data_timing[1][:,0], self.data_timing[1][:,1])
plt.figure()
plt.plot(self.data_timing[0][:,1], champ2)
plt.show()
#def _find_crossing_old(self, val = 0) :
#self.timing = np.array([sc_data[(sc_data[:,1] - val).argmin(), 0] for sc_data in self.data_timing])
#self.timing_seconds = np.array([(time - self.time_reference).total_seconds() for time in self.timing])