-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcroissant.py
784 lines (665 loc) · 26.3 KB
/
croissant.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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
import numpy as np
import pandas as pd
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from time import mktime, strptime
from bisect import bisect
import os
from re import search
from glob import glob
def v_calc(h1, h2, deltat):
"""
Takes the starting and ending heights of the CME and the time difference
between the two measurements and calculates velocity.
Parameters
----------
h1 : float or string
Starting height of the CME
h2 : float or string
Ending height of the CME
deltat : float or string
Time difference between the measurements of h1 and h2
Returns
----------
v : float
velocity of the CME
"""
# Radius of the sun in km, used for unit conversion
Rsun = 695508
# find the change in height of the CME in km and time in seconds
deltah = (float(h2) - float(h1)) * Rsun
deltat = float(deltat) * 60
# calculates velocity
v = deltah / deltat
return(v)
def find_v():
"""
Querries the user, asking for h1, h2, and deltat (starting/ending heights
of the CME and the time difference) and returns these as floats.
Returns
----------
h1 : float
Starting height of the CME
h2 : float
Ending height of the CME
deltat : float
Time difference between the measurements of h1 and h2
"""
# Queries user for starting time, ending time, and change in time
h1 = float(input("What is the starting height? "))
h2 = float(input("What is the ending height? "))
deltat = float(input("What is the time difference in minutes? "))
# Calculate and print the velocity
print("Velocity: " + str(v_calc(h1, h2, deltat)))
# return starting height, ending height and change in time
return(h1, h2, deltat)
def find_many_v():
"""
Querries the user, asking for h1, h2, and deltat (starting/ending heights
of the CME and the time difference) several times, and returns a list of the
values collected/derived in this process.
Returns
----------
v_list : list
a list of all velocities calculated
t_list : list
a list of times, starting at 0, and adding deltat at each step.
h_list : list
a list of CME heights
"""
# start empty lists for velocity, time and height
v_list = []
t_list = []
h_list = []
# start time at 0 for the loop
time = 0
# Continue to repeat the steps below until the "break" condition is met
while True:
# Queries user for start height, end height and change in time
h1, h2, deltat = find_v()
# append the starting height and time to their lists, and calculate velocity and append to its list
h_list.append(float(h1))
v_list.append(v_calc(h1, h2, deltat))
t_list.append(time)
# add the change in time to the time counter
time += float(deltat)
print(v_list)
print(t_list)
# if the user types 'exit' then this breaks the data collection loop
if input("Enter 'exit' to end measurement collection: ").lower() == 'exit':
break
# Since the above loop only adds the starting height and time, the next two lines
# will add the final time and height to the appropriate lists
t_list.append(time)
h_list.append(float(h2))
return(v_list, t_list, h_list)
def line_fit_cme():
"""
Querries the user, asking for h1, h2, and deltat (starting/ending heights
of the CME and the time difference) several times, and returns a list of the
values collected in this process.
Returns
----------
time_list : list
a list of times, starting at 0, and adding deltat at each step.
height_list : list
a list of CME heights
"""
# start time at 0, and the time/height lists as empty
time, time_list, height_list = 0, [], []
# Loop through the data collection loop below until the user wants to exit
while True:
# Ask for height
height_list.append(float(input("Height: ")))
# append current time then add whatever the user wants to the total
time_list.append(time)
time += float(input("What is the time difference to the next frame? "))
# check to see if the user is done
if input("Enter 'exit' to end measurement collection: ").lower() == 'exit':
break
return(time_list, height_list)
def weird_date(zulu_date):
"""
Takes a date in Zulu format, and converts it to a weird date, (roughly)
the number of days since the beginning of the year.
Parameters
----------
zulu_date : string
Date and time in the format "YYYY-MM-DDTHH:MMZ"
Returns
----------
Day : integer
Very roughly the number of days since the beginning of that year.
"""
# Returns number of days since the beginning of the year, roughly
days = 0
days += (int(zulu_date[5:7]) * 30 + int(zulu_date[8:10]))
return(days)
def weird_time(zulu_time):
"""
Takes a date in Zulu format, and converts it to a weird time, (roughly)
the number of minutes since the beginning of the year.
Parameters
----------
zulu_time : string
Date and time in the format "YYYY-MM-DDTHH:MMZ"
Returns
----------
time : integer
Very roughly the number of minutes since the beginning of that year.
"""
# returns the number of minutes since the beginning of the year, roughly
time = 0
time += (int(zulu_time[11:13]) * 60) + int(zulu_time[14:16])
time += weird_date(zulu_time) * 24 * 60
return(time)
def z_to_weird(zulu_times_list):
"""
Takes a list of dates in Zulu format, and converts it to a list of weird times,
(roughly) the number of minutes since the beginning of the year.
Parameters
----------
zulu_times_list : list
Dates and times in the format "YYYY-MM-DDTHH:MMZ"
Returns
----------
weird_times_list : list
A list where every index is very roughly the number of minutes since the
beginning of that year.
"""
# translates zulu time to weird time
weird_times_list = []
# for every zulu time in the list, translate to weird time
for t in zulu_times_list:
weird_times_list.append(weird_time(t))
# normalize every weird time so that it is self consistent
weird_times_list = np.array(weird_times_list) - min(weird_times_list)
return(weird_times_list)
def add_zulu(start_zulu, added_time):
"""
Takes a date and time in Zulu format and adds a number of minutes before
converting back to Zulu time
Parameters
----------
start_zulu : string
Starting date and time in the format "YYYY-MM-DDTHH:MMZ"
added_time : integer
The number of minutes you would like to add
Returns
----------
end_zulu : string
Ending date and time in the format "YYYY-MM-DDTHH:MMZ"
"""
# Reads in the mins, hours, days, months and years from the standard Zulu time
# format 'YYYY-MM-DDThh:mmZ'
mins = int(start_zulu[14:16])
hours = int(start_zulu[11:13])
days = int(start_zulu[8:10])
month = int(start_zulu[5:7])
year = int(start_zulu[0:4])
# add the number of minutes specified
mins += added_time
# Carry over extra minutes into the hours place
while mins >= 60:
hours += 1
mins -= 60
# Carry over extra hours into the days place
while hours >= 24:
days += 1
hours -= 24
chars = ''
for i in str(mins):
if i == '.':
break
chars += i
mins = chars
# These many if statements just check to see if '1' needs to be '01' and whatnot
if len(str(mins)) == 1:
mins = "0" + str(mins)
if len(str(hours)) == 1:
hours = "0" + str(hours)
if len(str(days)) == 1:
days = "0" + str(days)
if len(str(month)) == 1:
month = "0" + str(month)
# take all the integers and turn them into the correct strings w/ Zulu format
end_zulu = str(year) + '-' + str(month) + '-' + str(days) + \
'T' + str(hours) + ':' + str(mins) + 'Z'
# if the days are greater than or equal to 31 then something mayyyy be wrong
if int(days) >= 31:
# ask the user if the date is wrong
answer = input(
"WARNING: Zulu date may have crossed into a new month. Does this date look correct? (type y or n) %s: " % (end_zulu))
if answer == 'n':
# if the end zulu is wrong, make the user do the dang math
end_zulu = input("Please calculate the end date, the start date was " + str(
start_zulu) + ' and you must add ' + str(added_time) + ' minutes. ')
return(end_zulu)
def funct(x, s, i):
# This is just for cme_line_fit's curve_fit, it needs to be a pre-defined function for some reason
return(s * x + i)
def cme_line_fit(ts, hs, return_slope=False):
"""
Takes a date and time in Zulu format and adds a number of minutes before
converting back to Zulu time
Parameters
----------
ts : list
Time
Returns
----------
end_zulu : string
Ending date and time in the format "YYYY-MM-DDTHH:MMZ"
"""
Rsun = 695508
popt, pcov = curve_fit(funct, ts, hs)
s, i = popt[0], popt[1]
# Maybe plot
if return_slope == False:
# make x values to plot line regression against
x = np.linspace(min(ts), max(ts), 10)
# scatter plot the real data
plt.scatter(ts, hs)
# line plot the line of best fit
plt.plot(x, (s * x + i), 'r')
# put the slope (velocity) in the title
plt.title("Velocity (km/s): " + str(g))
# Show that figure!
plt.show()
# Maybe return the slope
elif return_slope == True:
return(s * Rsun / 60)
def find_cme_start(start_t, start_h, velocity):
"""
Takes measurements of a CME from coronagraph imagery and calculates when the
CME will reach 21.5 solar radii, where the ENLIL model takes over.
Parameters
----------
start_t : string
Starting date and time from which you would like to calculate the CMEs
time at 21.5 solar radii, in the format "YYYY-MM-DDTHH:MMZ". Note that
this time must match with the start_h below. It is advised that this
starting time be as late as possible so that errors introduced by the
calculated velocity are minimized.
start_h : float or int
Starting CME height in solar radii from which you would like to calculate
the CMEs time at 21.5 solar radii. note that this height must match the
starting time listed above.
velocity : float or int
Velocity of the CME in solar radii per minute.
Returns
----------
end_time : string
CMEs arrival at 21.5 solar radii in the format "YYYY-MM-DDTHH:MMZ"
"""
# Convert velocity from km/s to Rsun/min
velocity = (velocity / 695508) * 60
# Calculate number of minutes until CME reaches ENLIL inner boundary assuming
# Note: start_t and start_h should be for the latest measurement, so that
# Errors are minimized.
delta_t = (21.5 - start_h) / velocity
# add delta_t to the start_time. Outputs in Zulu time
end_time = add_zulu(start_t, delta_t)
return(end_time)
def cr2sh(date, carrington):
"""
Takes a date and Carrington longitude and returns a Stonyhurst longitude.
Converts carrington to stonyhurst
Parameters
----------
date : string
Date and time in the format "YYYY-MM-DDTHH:MM:00"
carrington : float
Carrington longitude.
Returns
----------
stonyhurst : float
Stonyhurst longitude.
The date of the longitude measurement in the format "YYYY-MM-DDTHH:MMZ"
carrington : float
Longitude in carrington coordinates.
Returns
----------
stonyhurst : float
Longitude in stonyhurst coordinates.
"""
# grab dates
carrots = np.loadtxt(
str(os.path.dirname(os.path.realpath(__file__))) + "/carrots.txt")
# turn input date into a mathable value
datemk = mktime(strptime(date, "%Y-%m-%dT%H:%M:00"))
# identify start and end times for the rotation
rotation = bisect(carrots, datemk)
start = carrots[rotation - 1]
end = carrots[rotation]
# the math part
stonyhurst = carrington - 360 * (1 - (datemk - start) / (end - start))
# make sure results are in bounds
if stonyhurst < 0:
return stonyhurst + 360
else:
return stonyhurst
def sh2cr(date, stonyhurst):
"""
Takes a date and Stonyhurst longitude and returns a Carrington longitude.
Converts stonyhurst to carrington
Parameters
----------
date : string
Date and time in the format "YYYY-MM-DDTHH:MM:00"
carrington : float
Stonyhurst longitude.
Returns
----------
carrington : float
Carrington longitude.
The date of the longitude measurement in the format "YYYY-MM-DDTHH:MMZ"
stonyhurst : float
Longitude in stonyhurst coordinates.
Returns
----------
carrington : float
Longitude in carrington coordinates.
"""
carrots = np.loadtxt(
str(os.path.dirname(os.path.realpath(__file__))) + "/carrots.txt")
# re-commenting this is beneath my dignity
datemk = mktime(strptime(date, "%Y-%m-%dT%H:%M:00"))
rotation = bisect(carrots, datemk)
start = carrots[rotation - 1]
end = carrots[rotation]
# note plus sign
carrington = stonyhurst + 360 * (1 - (datemk - start) / (end - start))
if carrington > 360:
return carrington - 360
else:
return carrington
def cme_list(*directories):
"""
Looks at all .rt files in the given directory or directories and returns a
chronologically sorted list of unique CMEs.
Parameters
----------
directories : string
0 or more directory names. If 0, cme_match() finds all appropriately
named .rt files in /data/[acjkr]data/.
Returns
----------
cmes : list
List of CMEs.
"""
files, cmes = [], []
# if no arguments grab all files, otherwise grab specified files
if len(directories) == 0:
files.extend(glob(str(os.path.dirname(os.path.realpath(__file__))) +
"/data/[acjkr]data/[0-9]WLRT_[1-2]???-??-??_????.rt"))
else:
for directory in directories:
files.extend(glob(str(os.path.dirname(os.path.realpath(
__file__))) + "/" + directory + "/[0-9]WLRT_[1-2]???-??-??_????.rt"))
# pull out just the filenames
for file in files:
cmes.append(file[-24:-8])
# massage this list so it's tidier
cmes = list(set(cmes))
cmes.sort()
return cmes
def cme_match(*directories):
"""
Looks at all .rt files in the given directory or directories and groups
them up by CME.
Parameters
----------
directories : string
0 or more directory names. If 0, cme_match() finds all appropriately
named .rt files in /data/[acjkr]data/.
Returns
----------
matches : list
List of lists of filenames.
"""
files, cmes, matches = [], [], []
# if no arguments grab all files, otherwise grab specified files
if len(directories) == 0:
files.extend(glob(str(os.path.dirname(os.path.realpath(__file__))) +
"/data/[acjkr]data/[0-9]WLRT_[1-2]???-??-??_????.rt"))
else:
for directory in directories:
files.extend(glob(str(os.path.dirname(os.path.realpath(
__file__))) + "/" + directory + "/[0-9]WLRT_[1-2]???-??-??_????.rt"))
# pull out just the filenames
for file in files:
cmes.append(file[-24:-8])
# massage this list so it's tidier
cmes = list(set(cmes))
cmes.sort()
# list files for each CME
for cme in cmes:
matches.append([file for file in files if cme in file])
return matches
def cme_times(times):
"""
Takes a list of frame timestamps and returns minutes from zero, where zero
is the earliest timstamp.
Parameters
----------
times : list
2 or more timestamps in the format YYYY-MM-DDTHH:MM:00.
Returns
----------
minutes : list
Minutes from zero.
"""
timesmk = []
minutes = [0]
if len(times) <= 1:
return "cme_times() requires at least two values."
else:
for time in times:
timesmk.append(mktime(strptime(time, "%Y-%m-%dT%H:%M:00")))
timesmk_index = 1
for mk in timesmk:
if len(timesmk) - 1 >= timesmk_index:
minutes.append(
((timesmk[timesmk_index] - mk) / 60) + minutes[len(minutes) - 1])
timesmk_index += 1
else:
break
return minutes
def make_eUCLID(cmes_list):
"""
Takes a list of GCS CME output file paths, averages all of the measurements
of the same CME and outputs a dataframe containing average time, longitude,
latitude, tilt angle, velocity, ascpect ratio, half angle, and time at 21.5
solar radii for each CME.
Parameters
----------
cmes_list : list or array
A nested list where it would have lists inside of it, each sublist
has multiple measurements of the same CME. ie [[m1,m2,m3,m4],[m1,m2]]
would have 2 cmes. CME 1 has four measurements and CME 2 has 2 measurements.
Each measurement is a GCS output file.
Returns
----------
all_cmesdf : pandas DataFrame
A data frame containing time, longitude, latitude, tilt angle, velocity,
ascpect ratio, and half angle for each measurement of each CME.
cmedf : pandas DataFrame
a DataFrame containing average time, longitude, latitude, tilt angle,
velocity, ascpect ratio, half angle, and time at 21.5 solar radii for
each CME.
"""
# Create empty dataframes to populate later
cmedf = pd.DataFrame()
all_cmesdf = pd.DataFrame()
# Loop through each cme in the list of cmes
for cme in cmes_list:
tempdf = pd.DataFrame()
# loop through each measurement of the cme
for mf in cme:
# Read the measurement into a dataframe
measurement = pd.read_csv(mf, names=["Time", "Lon", "Lat", "ROT", "Height", "Ratio", "Half Angle"],
delim_whitespace=True, header=0, usecols=[0, 1, 2, 3, 4, 5, 6])
# Turn zulu into mathable times
times_list = cme_times(measurement["Time"])
# calculate velocity
velocity = cme_line_fit(
times_list, measurement["Height"], return_slope=True)
# Use velocity to calculate the time at 21.5 Rs
enlilstart = find_cme_start(measurement["Time"][len(
measurement["Time"]) - 1], measurement["Height"][len(measurement["Height"]) - 1], velocity)
# find the average of each parameter in one measurement
ave_measurement = measurement.mean()
# turn the averages into a dataframe so that it can easily be appended
ave_measurement = pd.DataFrame({"Time": measurement["Time"][len(measurement["Time"]) - 1], 'Lon': cr2sh(measurement["Time"][len(measurement["Time"]) - 1], ave_measurement['Lon']), 'Lat': ave_measurement['Lat'], 'ROT': ave_measurement['ROT'],
"Velocity": velocity, 'Ratio': ave_measurement['Ratio'], 'Half Angle': ave_measurement['Half Angle'], "Time at 21.5": enlilstart[:16] + "Z"}, index=[0])
# add this measurement to the df containing all individual measurements
all_cmesdf = all_cmesdf.append(ave_measurement, ignore_index=True)
tempdf = tempdf.append(ave_measurement, ignore_index=True)
ave_of_temp = tempdf.mean()
transferdf = pd.DataFrame({"Time": ave_measurement["Time"], 'Lon': ave_of_temp["Lon"], 'Lat': ave_of_temp['Lat'], 'ROT': ave_of_temp['ROT'],
"Velocity": ave_of_temp["Velocity"], 'Ratio': ave_of_temp['Ratio'], 'Half Angle': ave_of_temp['Half Angle'], "Time at 21.5": find_cme_start(tempdf["Time"][len(tempdf["Time"]) - 1], measurement["Height"][len(measurement["Height"]) - 1], ave_of_temp["Velocity"])}, index=[0])
cmedf = cmedf.append(transferdf, ignore_index=True)
cmedf.to_csv(str(os.path.dirname(os.path.realpath(__file__))
) + '/eUCLID.txt', sep=":")
all_cmesdf.to_csv(str(os.path.dirname(os.path.realpath(__file__))
) + '/all_measurements.txt', sep=":")
return(all_cmesdf, cmedf)
def make_hist(std_list, range_list, name, units, figdir, labels):
"""
Parameters
----------
std_list : list or array
list of standard deviations you wish to plot on the histogram
range_list : list or array
list of ranges you wish to plot on the histogram
name : string
Name of the parameter which is being plotted
units : dictionary
Dictionary where the key is the name and each name is linked to the
proper units for that parameter
figdir : string
Full path to the directory in which you would like to store the histogram
labels : dictionary
Dictionary where the key is the name and each name is linked to the
proper name of the parameter which you would like to appear on the
final histograms.
"""
if labels[name] == "Tilt Angle":
b = np.arange(0, max(range_list) + 20, 20)
elif labels[name] == "Half Angle":
b = np.arange(0, max(range_list) + 5, 5)
elif units[name] == "(Degrees)":
#b = int(max(range_list)/2)
b = np.arange(0, max(range_list) + 1, 2)
elif units[name] == '':
#b = int(max(range_list)/0.1)
b = np.arange(0, max(range_list) + 0.1, 0.1)
else:
b = np.arange(0, max(range_list) + 50, 50)
plt.hist(std_list, bins=b, alpha=0.5,
label='Standard Deviation', color="#FFCD8C")
plt.hist(range_list, bins=b, alpha=0.3, label='Range', color='#74A7C4')
plt.title("Standard Deviation and Range of " +
labels[name], size=18, fontname='Verdana')
plt.xlabel(units[name], size=14, fontname='Verdana')
plt.ylabel("Frequency", size=14, fontname='Verdana')
plt.xticks(fontsize=15, fontname='Verdana')
plt.yticks(fontsize=15, fontname='Verdana')
plt.legend(loc='best')
plt.savefig(figdir + "std_range_hists/" +
name + "_hist.png", overwrite=True, dpi=500)
plt.clf()
def make_scatter(std_list, range_list, mean_list, name, units, figdir, labels):
"""
Parameters
----------
std_list : list or array
list of standard deviations you wish to plot on the scatter plots
range_list : list or array
list of ranges you wish to plot on the scatter plots
mean_list : list or array
list of means you wish to plot on the scatter plots
name : string
Name of the parameter which is being plotted
units : dictionary
Dictionary where the key is the name and each name is linked to the
proper units for that parameter
figdir : string
Full path to the directory in which you would like to store the scatter
plot
labels : dictionary
Dictionary where the key is the name and each name is linked to the
proper name of the parameter which you would like to appear on the
final scatter plots.
"""
plt.scatter(mean_list, std_list, color='#2F454F',
label="Standard Deviation")
plt.scatter(mean_list, range_list, color="#F7941D", label="Range")
if name == 'Half Angle':
plt.xlim(8, 39)
plt.xlabel("Mean " + units[name], size=14, fontname='Verdana')
plt.ylabel(units[name], size=14, fontname='Verdana')
plt.xticks(fontsize=15, fontname='Verdana')
plt.yticks(fontsize=15, fontname='Verdana')
plt.title("Standard Deviation and Range of " +
labels[name], size=18, fontname='Verdana')
plt.legend(loc=1)
plt.savefig(figdir + "std_range_scatters/range_" +
name + "_scatter.png", overwrite=True, dpi=500)
plt.clf()
def plot_cmes(cmedf, all_cmesdf, dates, units, labels, figdir):
"""
Parameters
----------
cmedf : pandas DataFrame
a DataFrame containing average time, longitude, latitude, tilt angle,
velocity, ascpect ratio, half angle, and time at 21.5 solar radii for
each CME.
all_cmesdf : pandas DataFrame
A data frame containing time, longitude, latitude, tilt angle, velocity,
ascpect ratio, and half angle for each measurement of each CME.
dates : list or array
list or array containing strings which are the dates of the CMEs in the
format "YYYY-MM-DD".
units : dictionary
Dictionary where the key is the name and each name is linked to the
proper units for that parameter
labels : dictionary
Dictionary where the key is the name and each name is linked to the
proper name of the parameter which you would like to appear on the
final scatter plots.
figdir : string
Full path to the directory in which you would like to store the scatter
plot
"""
normarray = []
for name in all_cmesdf.columns:
if all_cmesdf[name].dtypes != 'object':
mean_list, std_list, range_list = [], [], []
name_norm_array = []
new_norm = pd.Series()
for base_time in dates:
temp_storage = []
for ind_time, x in zip(all_cmesdf["Time"], all_cmesdf[name]):
if base_time[:10] == ind_time[:10]:
temp_storage.append(x)
mean_p = np.mean(temp_storage)
mean_list.append(mean_p)
std_p = np.std(temp_storage)
std_list.append(std_p)
range_p = max(temp_storage) - min(temp_storage)
range_list.append(range_p)
if name == "Velocity":
norms = ((np.array(temp_storage) - np.mean(np.array(temp_storage))
) / np.mean(np.array(temp_storage))) * 100
else:
norms = (np.array(temp_storage) -
np.mean(np.array(temp_storage)))
for i in norms:
name_norm_array.append(i)
normarray.append(norms)
make_hist(std_list, range_list, name, units, figdir, labels)
if name == "Velocity" or name == "Half Angle":
make_scatter(std_list, range_list, mean_list,
name, units, figdir, labels)