ATMOS/pyatmos/msise/spaceweather.py

140 lines
4.5 KiB
Python
Raw Normal View History

2019-11-25 00:19:36 +08:00
import numpy as np
from datetime import datetime,timedelta
from os import path,makedirs,remove
from pathlib import Path
2019-11-25 00:19:36 +08:00
2020-07-27 10:38:52 +08:00
from ..utils.try_download import tqdm_request
2019-11-25 00:19:36 +08:00
2021-06-07 12:58:06 +08:00
def download_sw_nrlmsise00(direc=None):
2019-11-25 00:19:36 +08:00
'''
2021-06-07 12:58:06 +08:00
Download or update the space weather data from www.celestrak.com
2019-11-25 00:19:36 +08:00
Usage:
swfile = download_sw([direc])
Inputs:
2021-06-07 12:58:06 +08:00
direc -> [str, optional] Directory for storing the space weather data
2019-11-25 00:19:36 +08:00
Outputs:
2021-06-07 12:58:06 +08:00
swfile -> [str] Path of the space weather data
2019-11-25 00:19:36 +08:00
Examples:
>>> swfile = download_sw()
>>> swfile = download_sw('sw-data/')
'''
if direc is None:
home = str(Path.home())
2019-11-25 00:19:36 +08:00
direc = home + '/src/sw-data/'
swfile = direc + 'SW-All.txt'
url = 'https://www.celestrak.com/SpaceData/SW-All.txt'
if not path.exists(direc): makedirs(direc)
if not path.exists(swfile):
2021-06-09 15:16:15 +08:00
desc = "Downloading the space weather data '{:s}' from CELESTRAK".format('SW-All.txt')
2020-07-24 17:30:07 +08:00
tqdm_request(url,direc,'SW-All.txt',desc)
2019-11-25 00:19:36 +08:00
else:
modified_time = datetime.fromtimestamp(path.getmtime(swfile))
if datetime.now() > modified_time + timedelta(days=1):
remove(swfile)
2021-06-09 15:16:15 +08:00
desc = "Updating the space weather data '{:s}' from CELESTRAK".format('SW-All.txt')
2020-07-24 17:30:07 +08:00
tqdm_request(url,direc,'SW-All.txt',desc)
2019-11-25 00:19:36 +08:00
else:
2021-06-09 15:16:15 +08:00
print("The space weather data '{0:s}' in {1:s} is already the latest.".format('SW-All.txt',direc))
2019-11-25 00:19:36 +08:00
return swfile
2021-06-07 12:58:06 +08:00
def read_sw_nrlmsise00(swfile):
2019-11-25 00:19:36 +08:00
'''
2021-06-07 12:58:06 +08:00
Parse and read the space weather data
2019-11-25 00:19:36 +08:00
Usage:
sw_obs_pre = read_sw(swfile)
Inputs:
2021-06-07 12:58:06 +08:00
swfile -> [str] Path of the space weather data
2019-11-25 00:19:36 +08:00
Outputs:
2021-06-07 12:58:06 +08:00
sw_obs_pre -> [2d str array] Content of the space weather data
2019-11-25 00:19:36 +08:00
Examples:
>>> swfile = 'sw-data/SW-All.txt'
>>> sw_obs_pre = read_sw(swfile)
>>> print(sw_obs_pre)
[['2020' '01' '07' ... '72.4' '68.0' '71.0']
['2020' '01' '06' ... '72.4' '68.1' '70.9']
...
2021-06-07 12:58:06 +08:00
...
2019-11-25 00:19:36 +08:00
['1957' '10' '02' ... '253.3' '267.4' '231.7']
['1957' '10' '01' ... '269.3' '266.6' '230.9']]
'''
sw_data = open(swfile,'r').readlines()
SW_OBS,SW_PRE = [],[]
flag1 = flag2 = 0
for line in sw_data:
if line.startswith('BEGIN OBSERVED'):
flag1 = 1
continue
if line.startswith('END OBSERVED'): flag1 = 0
if flag1 == 1:
sw_p = line.split()
if len(sw_p) == 30:
del sw_p[24]
elif len(sw_p) == 31:
sw_p = np.delete(sw_p,[23,25])
else:
sw_p = np.delete(sw_p,[23,24,25,27])
SW_OBS.append(sw_p)
if line.startswith('BEGIN DAILY_PREDICTED'):
flag2 = 1
continue
if line.startswith('END DAILY_PREDICTED'): break
if flag2 == 1: SW_PRE.append(line.split())
SW_OBS_PRE = np.vstack((np.array(SW_OBS),np.array(SW_PRE)))
# inverse sort
2021-06-07 12:58:06 +08:00
SW_OBS_PRE = np.flip(SW_OBS_PRE,0).astype(dtype='<U8')
ymds = np.apply_along_axis(''.join, 1, SW_OBS_PRE[:,:3])
SW_OBS_PRE = np.insert(SW_OBS_PRE[:,3:],0,ymds,axis=1)
2020-07-27 10:38:52 +08:00
return SW_OBS_PRE
2021-06-07 12:58:06 +08:00
2019-11-25 00:19:36 +08:00
def get_sw(SW_OBS_PRE,t_ymd,hour):
2020-07-27 10:38:52 +08:00
'''
2021-06-07 12:58:06 +08:00
Extract the necessary parameters describing the solar activity and geomagnetic activity from the space weather data.
Usage:
f107A,f107,ap,aph = get_sw(SW_OBS_PRE,t_ymd,hour)
Inputs:
SW_OBS_PRE -> [2d str array] Content of the space weather data
t_ymd -> [str array or list] ['year','month','day']
hour -> []
Outputs:
f107A -> [float] 81-day average of F10.7 flux
f107 -> [float] daily F10.7 flux for previous day
ap -> [int] daily magnetic index
aph -> [float array] 3-hour magnetic index
Examples:
>>> f107A,f107,ap,aph = get_sw(SW_OBS_PRE,t_ymd,hour)
2020-07-27 10:38:52 +08:00
'''
2021-06-07 12:58:06 +08:00
ymds = SW_OBS_PRE[:,0]
j_, = np.where(''.join(t_ymd) == ymds)
j = j_[0]
f107A,f107,ap = float(SW_OBS_PRE[j,25]),float(SW_OBS_PRE[j+1,24]),int(SW_OBS_PRE[j,20])
aph_tmp_b0 = SW_OBS_PRE[j,12:20]
2019-11-25 00:19:36 +08:00
i = int(np.floor_divide(hour,3))
ap_c = aph_tmp_b0[i]
2021-06-07 12:58:06 +08:00
aph_tmp_b1 = SW_OBS_PRE[j+1,12:20]
aph_tmp_b2 = SW_OBS_PRE[j+2,12:20]
aph_tmp_b3 = SW_OBS_PRE[j+3,12:20]
2019-11-25 00:19:36 +08:00
aph_tmp = np.hstack((aph_tmp_b3,aph_tmp_b2,aph_tmp_b1,aph_tmp_b0))[::-1].astype(np.float)
apc_index = 7-i
aph_c369 = aph_tmp[apc_index:apc_index+4]
aph_1233 = np.average(aph_tmp[apc_index+4:apc_index+12])
aph_3657 = np.average(aph_tmp[apc_index+12:apc_index+20])
aph = np.hstack((ap,aph_c369,aph_1233,aph_3657))
return f107A,f107,ap,aph