-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcme_stats_module.py
253 lines (187 loc) · 7.21 KB
/
cme_stats_module.py
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
247
248
249
250
251
252
253
#cme_stats_module.py
#This is the module for the cme_verify repo containing functions and procedures
import numpy as np
import scipy
import copy
import sunpy
import matplotlib.dates as mdates
import datetime
import urllib
import json
import os
import pdb
# use
# import importlib
# importlib.reload(cme_stats_module)
# to update module while working in command line
#set breakpoints with pdb.set_trace
# LIST OF FUNCTIONS
# load_url_current_directory
# getpositions
# getcat
# gaussian
# dynamic_pressure
# decode_array
# time_to_num_cat
# get_omni2_data
def load_url_current_directory(filename,url):
#loads a file from any url to the current directory
#I use owncloud for the direct url links,
#also works for dropbox when changing the last 0 to 1 in the url-> gives a direct link to files
if not os.path.exists(filename):
print('download file ', filename, ' from')
print(url)
try:
urllib.request.urlretrieve(url, filename)
print('done')
except urllib.error.URLError as e:
print(' ', data_url,' ',e.reason)
def getpositions(filename):
pos=scipy.io.readsav(filename)
print
print('positions file:', filename)
return pos
def getcat(filename):
cat=scipy.io.readsav(filename)#, verbose='true')
return cat
def gaussian(x, amp, mu, sig):
return amp * exp(-(x-cen)**2 /wid)
def dynamic_pressure(density, speed):
# make dynamic pressure from density and speed
#assume pdyn is only due to protons
#pdyn=np.zeros(len([density])) #in nano Pascals
protonmass=1.6726219*1e-27 #kg
pdyn=np.multiply(np.square(speed*1e3),density)*1e6*protonmass*1e9 #in nanoPascal
return pdyn
def decode_array(bytearrin):
#for decoding the strings from the IDL .sav file to a list of python strings, not bytes
#make list of python lists with arbitrary length
bytearrout= ['' for x in range(len(bytearrin))]
for i in range(0,len(bytearrin)-1):
bytearrout[i]=bytearrin[i].decode()
#has to be np array so to be used with numpy "where"
bytearrout=np.array(bytearrout)
return bytearrout
def time_to_num_cat(time_in):
#for time conversion from catalogue .sav to numerical time
#this for 1-minute data or lower time resolution
#for all catalogues
#time_in is the time in format: 2007-11-17T07:20:00 or 2007-11-17T07:20Z
#for times help see:
#http://docs.sunpy.org/en/latest/guide/time.html
#http://matplotlib.org/examples/pylab_examples/date_demo2.html
j=0
#time_str=np.empty(np.size(time_in),dtype='S19')
time_str= ['' for x in range(len(time_in))]
#=np.chararray(np.size(time_in),itemsize=19)
time_num=np.zeros(np.size(time_in))
for i in time_in:
#convert from bytes (output of scipy.readsav) to string
time_str[j]=time_in[j][0:16].decode()+':00'
year=int(time_str[j][0:4])
time_str[j]
#convert time to sunpy friendly time and to matplotlibdatetime
#only for valid times so 9999 in year is not converted
#pdb.set_trace()
if year < 2100:
time_num[j]=mdates.date2num(sunpy.time.parse_time(time_str[j]))
j=j+1
#the date format in matplotlib is e.g. 735202.67569444
#this is time in days since 0001-01-01 UTC, plus 1.
#return time_num which is already an array and convert the list of strings to an array
return time_num, np.array(time_str)
def get_omni2_data():
#FORMAT(2I4,I3,I5,2I3,2I4,14F6.1,F9.0,F6.1,F6.0,2F6.1,F6.3,F6.2, F9.0,F6.1,F6.0,2F6.1,F6.3,2F7.2,F6.1,I3,I4,I6,I5,F10.2,5F9.2,I3,I4,2F6.1,2I6,F5.1)
#1963 1 0 1771 99 99 999 999 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 999.9 9999999. 999.9 9999. 999.9 999.9 9.999 99.99 9999999. 999.9 9999. 999.9 999.9 9.999 999.99 999.99 999.9 7 23 -6 119 999999.99 99999.99 99999.99 99999.99 99999.99 99999.99 0 3 999.9 999.9 99999 99999 99.9
#define variables from OMNI2 dataset
#see http://omniweb.gsfc.nasa.gov/html/ow_data.html
#omni2_url='ftp://nssdcftp.gsfc.nasa.gov/pub/data/omni/low_res_omni/omni2_all_years.dat'
#check how many rows exist in this file
f=open('omni2_all_years.dat')
dataset= len(f.readlines())
#print(dataset)
#global Variables
spot=np.zeros(dataset)
btot=np.zeros(dataset) #floating points
bx=np.zeros(dataset) #floating points
by=np.zeros(dataset) #floating points
bz=np.zeros(dataset) #floating points
bzgsm=np.zeros(dataset) #floating points
bygsm=np.zeros(dataset) #floating points
speed=np.zeros(dataset) #floating points
speedx=np.zeros(dataset) #floating points
speed_phi=np.zeros(dataset) #floating points
speed_theta=np.zeros(dataset) #floating points
dst=np.zeros(dataset) #float
kp=np.zeros(dataset) #float
den=np.zeros(dataset) #float
pdyn=np.zeros(dataset) #float
year=np.zeros(dataset)
day=np.zeros(dataset)
hour=np.zeros(dataset)
t=np.zeros(dataset) #index time
j=0
print('Read OMNI2 data ...')
with open('omni2_all_years.dat') as f:
for line in f:
line = line.split() # to deal with blank
#print line #41 is Dst index, in nT
dst[j]=line[40]
kp[j]=line[38]
if dst[j] == 99999: dst[j]=np.NaN
#40 is sunspot number
spot[j]=line[39]
if spot[j] == 999: spot[j]=NaN
#25 is bulkspeed F6.0, in km/s
speed[j]=line[24]
if speed[j] == 9999: speed[j]=np.NaN
#get speed angles F6.1
speed_phi[j]=line[25]
if speed_phi[j] == 999.9: speed_phi[j]=np.NaN
speed_theta[j]=line[26]
if speed_theta[j] == 999.9: speed_theta[j]=np.NaN
#convert speed to GSE x see OMNI website footnote
speedx[j] = - speed[j] * np.cos(np.radians(speed_theta[j])) * np.cos(np.radians(speed_phi[j]))
#9 is total B F6.1 also fill ist 999.9, in nT
btot[j]=line[9]
if btot[j] == 999.9: btot[j]=np.NaN
#GSE components from 13 to 15, so 12 to 14 index, in nT
bx[j]=line[12]
if bx[j] == 999.9: bx[j]=np.NaN
by[j]=line[13]
if by[j] == 999.9: by[j]=np.NaN
bz[j]=line[14]
if bz[j] == 999.9: bz[j]=np.NaN
#GSM
bygsm[j]=line[15]
if bygsm[j] == 999.9: bygsm[j]=np.NaN
bzgsm[j]=line[16]
if bzgsm[j] == 999.9: bzgsm[j]=np.NaN
#24 in file, index 23 proton density /ccm
den[j]=line[23]
if den[j] == 999.9: den[j]=np.NaN
#29 in file, index 28 Pdyn, F6.2, fill values sind 99.99, in nPa
pdyn[j]=line[28]
if pdyn[j] == 99.99: pdyn[j]=np.NaN
year[j]=line[0]
day[j]=line[1]
hour[j]=line[2]
j=j+1
#convert time to matplotlib format
#http://docs.sunpy.org/en/latest/guide/time.html
#http://matplotlib.org/examples/pylab_examples/date_demo2.html
times1=np.zeros(len(year)) #datetime time
print('convert time start')
for index in range(0,len(year)):
#first to datetimeobject
timedum=datetime.datetime(int(year[index]), 1, 1) + datetime.timedelta(day[index] - 1) +datetime.timedelta(hours=hour[index])
#then to matlibplot dateformat:
times1[index] = mdates.date2num(timedum)
print('convert time done') #for time conversion
print('all done.')
print(j, ' datapoints') #for reading data from OMNI file
#make structured array of data
omni_data=np.rec.array([times1,btot,bx,by,bz,bygsm,bzgsm,speed,speedx,den,pdyn,dst,kp,spot], \
dtype=[('time','f8'),('btot','f8'),('bx','f8'),('by','f8'),('bz','f8'),\
('bygsm','f8'),('bzgsm','f8'),('speed','f8'),('speedx','f8'),('den','f8'),('pdyn','f8'),('dst','f8'),('kp','f8'), ('spot','f8')])
return omni_data