コード例 #1
0
def rotate_latlon(raypos, itime, dlat, dlon, xf=None):
    if xf is None:
        xf = xflib.xflib(
            lib_path='/shared/users/asousa/WIPP/3dWIPP/python/libxformd.so')

    newpos = np.zeros_like(raypos)
    for ind in range(np.shape(raypos)[1]):
        #         print ind
        tmp = xf.sm2rllmag(raypos[:, ind], itime)
        tmp[1] += dlat
        tmp[2] += dlon
        newpos[:, ind] = xf.rllmag2sm(tmp, itime)

    return newpos
コード例 #2
0
def input_power_scaling(flash_loc, ray_loc, mag_lat, w, i0, MLT, xf=None):
    if xf is None:
        xf = xflib.xflib(
            lib_path='/shared/users/asousa/WIPP/3dWIPP/python/libxformd.so')
    f = w / (2.0 * np.pi)
    D2R = np.pi / 180.

    Z0 = 377.0
    P_A = 5e3
    P_B = 1e5
    H_E = 5000.0

    H_IONO = 1e5
    R_E = 6371e3
    flash_loc_sph = xf.c2s(flash_loc)
    ray_loc_sph = xf.c2s(ray_loc)
    out_lat = ray_loc_sph[1]
    out_lon = ray_loc_sph[2]
    inp_lat = flash_loc_sph[1]
    inp_lon = flash_loc_sph[2]

    dlat = D2R * (out_lat - inp_lat)
    dlong = D2R * (out_lon - inp_lon)
    clat1 = np.cos(D2R * inp_lat)
    clat2 = np.cos(D2R * out_lat)
    slat1 = np.sin(D2R * inp_lat)
    slat2 = np.sin(D2R * out_lat)
    # Compute current (latitude and longitude dependent) weighting:
    # (Use Haversine formula since we're moving further out than reasonable for Cartesian)
    a = pow(np.sin(dlat / 2.0), 2)
    b = (clat1 * clat2 * pow(np.sin(dlong / 2.0), 2))
    gc_distance = 2.0 * R_E * np.arcsin(np.sqrt(a + b))

    dist_tot = np.hypot(gc_distance, H_IONO)
    xi = np.arctan2(gc_distance, H_IONO)

    w_sq = pow(w, 2)
    S = ((1 / Z0) * pow(
        (H_E * i0 * 2e-7 * (np.sin(xi) / dist_tot) * w * (P_A - P_B)), 2) /
         ((w_sq + pow(P_A, 2)) * (w_sq + pow(P_B, 2))))
    S_vert = S * np.cos(xi)
    #// factor for vert prop.

    #     // Ionosphere absorption model
    attn_factor = pow(10, -(graf_iono_model(mag_lat, f, MLT) / 10))
    S_vert = S_vert * attn_factor

    return S_vert
コード例 #3
0
def flatten_longitude_variation(raypos, itime, xf=None):
    if xf is None:
        xf = xflib.xflib(
            lib_path='/shared/users/asousa/WIPP/3dWIPP/python/libxformd.so')

    newpos = np.zeros_like(raypos)

    tmp = xf.sm2rllmag(raypos[:, 0], itime)
    start_lon = tmp[2]

    for ind in range(np.shape(raypos)[1]):
        #         print ind
        tmp = xf.sm2rllmag(raypos[:, ind], itime)
        # tmp[1] += dlat
        tmp[2] = start_lon
        newpos[:, ind] = xf.rllmag2sm(tmp, itime)

    return newpos
コード例 #4
0
def MLT2lon(itime, mlt, xf=None):
    # // Input: itime, mlt in fractional hours
    # // Output: longitude in geomagnetic coordinates
    # // Ref: "Magnetic Coordinate Systems", Laundal and Richmond
    # // Space Science Review 2016, DOI 10.1007/s11214-016-0275-y
    if xf is None:
        xf = xflib.xflib(
            lib_path='/shared/users/asousa/WIPP/3dWIPP/python/libxformd.so')

    ut_hr = itime.hour + itime.minute / 60  # /1000.0/60.0;  #// Milliseconds to fractional hours (UT)
    A1 = [1, 51.48, 0]
    #// Location of Greenwich (for UT reference)
    B1 = [0, 0, 0]
    # B1[3]                         // Location of Greenwich in geomag

    xf.s2c(A1)
    xf.geo2mag(A1, itime)
    xf.c2s(A1)

    return 15. * (mlt - ut_hr) + A1[2]
コード例 #5
0
def total_input_power(flash_pos_sm, i0, latmin, latmax, lonmin, lonmax, wmin,
                      wmax, itime_in):
    # // Determine the total input power tracked by the set of guide rays:

    xf = xflib.xflib(
        lib_path='/shared/users/asousa/WIPP/3dWIPP/python/libxformd.so')
    tot_pwr = 0
    pwr = 0
    dlat = 0.1
    dlon = 0.1
    dw = 100 * 2 * np.pi
    tmp_coords = np.zeros(3)
    x_sm = np.zeros(3)

    D2R = np.pi / 180.
    H_IONO = 1e5
    R_E = 6371e3

    for w in np.arange(wmin + dw / 2, wmax, dw):
        # for (double w = wmin + dw/2; w < wmax; w+=dw) {
        for lat in np.arange(latmin + dlat / 2, latmax, dlat):
            # for (double lat = latmin + dlat/2; lat < latmax; lat+=dlat) {
            for lon in np.arange(lonmin + dlon / 2, lonmax, dlon):
                # for (double lon=lonmin; lon < lonmax; lon+=dlon) {
                # // cout << "(" << lat << ", " << lon << ")\n";
                tmp_coords = [1 + H_IONO / R_E, lat, lon]
                x_sm = xf.rllmag2sm(tmp_coords, itime_in)
                mlt = lon2MLT(itime_in, lon, xf)
                pwr = input_power_scaling(flash_pos_sm, x_sm, lat, w, i0, mlt,
                                          xf)

                dist_lat = (R_E + H_IONO) * dlat * D2R
                dist_lon = (R_E + H_IONO) * dlon * np.cos(D2R * lat) * D2R
                # // Latitude distance      longitude distance       freq dist
                # // cout << "dist_lat: " << dist_lat << ", dist_lon: " << dist_lon << "\n";
                tot_pwr += pwr * dist_lat * dist_lon * dw

    return tot_pwr
コード例 #6
0
ファイル: run_wipp.py プロジェクト: asousa/3dWIPP
# print TS_params

print "Pdyn: ", Pdyn
print "ByIMF: ", ByIMF
print "BzIMF: ", BzIMF
print "W: ", W

print "year: ", iyr
print "day: ", idoy
print "sec: ", isec

# Create coordinates
inp_coords = [launch_alt, inp_lat, inp_lon]

# Coordinate transformation library
xf = xflib.xflib(
    lib_path='/shared/users/asousa/WIPP/3dWIPP/python/libxformd.so')

print "input coords (geomagnetic RLL):"
print inp_coords

os.chdir(project_root)

print '-------- Building WIPP ------'
buildstatus = os.system('make')

if buildstatus != 0:
    sys.exit("Build failed!")

# run it
# wipp_cmd = ['bin/wipp -i %s -o %s'%(ray_input_directory, output_directory) +
#             ' -t %s -u %d -v %d'%(iyr, idoy, isec) +
コード例 #7
0
ファイル: raymaker_gcpm_kp4.py プロジェクト: asousa/raymaker

dump_model = False
run_rays   = True
vec_ind = 2     # Which set of default params to use for the gcpm model
# Kpvec = [0, 2, 4, 6, 8]

ray_out_dir = '/shared/users/asousa/WIPP/rays/2d/nightside/gcpm_kp4'

# ---------------- Input parameters --------------------
ray_datenum = dt.datetime(2010, 1, 1, 00, 00, 00);

yearday = '%d%03d'%(ray_datenum.year, ray_datenum.timetuple().tm_yday)
milliseconds_day = (ray_datenum.second + ray_datenum.minute*60 + ray_datenum.hour*60*60)*1e3 + ray_datenum.microsecond*1e-3
# Coordinate transformation library
xf = xflib.xflib(lib_path='/shared/users/asousa/WIPP/raymaker/libxformd.so')

inp_lats = np.arange(12, 61, 1) #[35] #np.arange(30, 61, 5) #[40, jh41, 42, 43]
# inp_lats = np.arange(55,61,1)
# inp_lats = [10,12,14]
# Get solar and antisolar points:
sun = xf.gse2sm([-1,0,0], ray_datenum)
sun_geomag_midnight = (xf.sm2rllmag(sun, ray_datenum))
sun = xf.gse2sm([1,0,0], ray_datenum)
sun_geomag_noon = (xf.sm2rllmag(sun, ray_datenum))


# # Nightside
# inp_lons_night = np.arange(sun_geomag_midnight[2] - 20, sun_geomag_midnight[2] + 20, 2)
# inp_lons_day   = np.arange(sun_geomag_noon[2] - 20,     sun_geomag_noon[2] + 20,     2)
コード例 #8
0
def find_crossings(
        ray_dir='/shared/users/asousa/WIPP/rays/2d/nightside/gcpm_kp0/',
        mlt=0,
        tmax=10,
        dt=0.1,
        lat_low=None,
        f_low=200,
        f_hi=30000,
        center_lon=None,
        lon_spacing=None,
        itime=datetime.datetime(2010, 1, 1, 0, 0, 0),
        lat_step_size=1,
        n_sub_freqs=10,
        Llims=[1.2, 8],
        L_step=0.2,
        dlat_fieldline=1,
        frame_directory=None,
        DAMP_THRESHOLD=1e-3):

    # Constants
    Hz2Rad = 2. * np.pi
    D2R = np.pi / 180.
    R2D = 180. / np.pi
    H_IONO_BOTTOM = 1e5
    H_IONO_TOP = 1e6
    R_E = 6371e3
    C = 2.997956376932163e8
    # DAMP_THRESHOLD = 1e-3  # Threshold below which we don't log a crossing

    lat_hi = lat_low + lat_step_size

    Lshells = np.arange(Llims[0], Llims[1], L_step)
    L_MARGIN = L_step / 2.0
    # print "doing Lshells ", Lshells

    # Coordinate transform tools
    xf = xflib.xflib(
        lib_path=
        '/shared/users/asousa/WIPP/WIPP_stencils/python/methods/libxformd.so')

    t = np.arange(0, tmax, dt)
    itime = datetime.datetime(2010, 1, 1, 0, 0, 0)

    # Find available rays
    d = os.listdir(ray_dir)
    freqs = sorted([int(f[2:]) for f in d if f.startswith('f_')])
    d = os.listdir(os.path.join(ray_dir, 'f_%d' % freqs[0]))
    lons = sorted([float(f[4:]) for f in d if f.startswith('lon_')])
    d = os.listdir(os.path.join(ray_dir, 'f_%d' % freqs[0],
                                'lon_%d' % lons[0]))
    lats = sorted([float(s.split('_')[2]) for s in d if s.startswith('ray_')])

    # Latitude spacing:

    latln_pairs = [(lat_low, lat_hi)]

    # Adjacent frequencies to iterate over
    freqs = [f for f in freqs if f >= f_low and f <= f_hi]
    freq_pairs = zip(freqs[0:-1], freqs[1:])

    #--------------- Load and interpolate the center longitude entries ------------------------------------
    center_data = dict()
    for freq in freqs:
        logging.info("Loading freq: %d" % freq)
        for lat in [lat_low, lat_hi]:
            lon = center_lon
            filename = os.path.join(ray_dir, 'f_%d' % freq, 'lon_%d' % lon,
                                    'ray_%d_%d_%d.ray' % (freq, lat, lon))
            # print filename
            rf = read_rayfile(filename)[0]

            filename = os.path.join(ray_dir, 'f_%d' % freq, 'lon_%d' % lon,
                                    'damp_%d_%d_%d.ray' % (freq, lat, lon))
            df = read_damp(filename)[0]

            t_cur = t[t <= rf['time'].iloc[-1]]

            # Interpolate onto our new time axis:
            x = interpolate.interp1d(rf['time'],
                                     rf['pos']['x']).__call__(t_cur) / R_E
            y = interpolate.interp1d(rf['time'],
                                     rf['pos']['y']).__call__(t_cur) / R_E
            z = interpolate.interp1d(rf['time'],
                                     rf['pos']['z']).__call__(t_cur) / R_E

            d = interpolate.interp1d(df['time'],
                                     df['damping'],
                                     bounds_error=False,
                                     fill_value=0).__call__(t_cur)

            v = interpolate.interp1d(df['time'], rf['vgrel'],
                                     axis=0).__call__(t_cur)
            vmag = np.linalg.norm(v, axis=1)

            B = interpolate.interp1d(rf['time'], rf['B0'],
                                     axis=0).__call__(t_cur)
            Bnorm = np.linalg.norm(B, axis=1)
            Bhat = B / Bnorm[:, np.newaxis]

            stixR, stixL, stixP = calc_stix_parameters(rf, t_cur)

            n = interpolate.interp1d(df['time'], rf['n'],
                                     axis=0).__call__(t_cur)
            mu = np.linalg.norm(n, axis=1)

            # kvec = n*rf['w']/C
            # kz = -1.0*np.sum(kvec*Bhat, axis=1)  # dot product of rows
            # kx = np.linalg.norm(kvec + Bhat*kz[:,np.newaxis], axis=1)
            # psi = R2D*np.arctan2(-kx, kz)

            # kvec = n*rf['w']/C
            # kz = np.sum(kvec*Bhat, axis=1)  # dot product of rows
            # kx = np.linalg.norm(kvec - Bhat*kz[:,np.newaxis], axis=1)
            # psi = np.arctan2(kx, kz)

            # psi = R2D*np.arctan2(kx, kz)

            kvec = n * rf['w'] / C
            kz = np.sum(kvec * Bhat, axis=1)  # dot product of rows
            kx = np.linalg.norm(np.cross(kvec, Bhat),
                                axis=1)  # Cross product of rows
            psi = np.arctan2(kx, kz)

            # Stash it somewhere:
            key = (freq, lat, lon)
            curdata = dict()

            # Flatten out any longitude variation, just to be sure:
            curdata['pos'] = flatten_longitude_variation(np.vstack([x, y, z]),
                                                         itime,
                                                         xf=xf)
            # curdata['pos'] = np.vstack([x,y,z])
            curdata['damp'] = d
            curdata['nt'] = len(t_cur)
            curdata['stixR'] = stixR
            curdata['stixP'] = stixP
            curdata['stixL'] = stixL
            curdata['mu'] = mu
            curdata['psi'] = psi
            curdata['vgrel'] = vmag

            center_data[key] = curdata

#------------ Rotate center_longitude rays to new longitudes ---------------------------
    logging.info("Rotating to new longitudes")
    ray_data = dict()
    for key in center_data.keys():
        for lon in [
                center_lon - lon_spacing / 2., center_lon + lon_spacing / 2.
        ]:
            newkey = (key[0], key[1], lon)
            dlon = lon - key[2]
            d = dict()
            d['pos'] = rotate_latlon(center_data[key]['pos'], itime, 0, dlon,
                                     xf)
            d['damp'] = center_data[key]['damp']
            d['stixR'] = center_data[key]['stixR']
            d['stixL'] = center_data[key]['stixL']
            d['stixP'] = center_data[key]['stixP']
            d['mu'] = center_data[key]['mu']
            d['psi'] = center_data[key]['psi']
            d['vgrel'] = center_data[key]['vgrel']
            ray_data[newkey] = d


# ------------------ Set up field lines ----------------------------
    logging.info("Setting up EA grid")
    fieldlines = gen_EA_array(Lshells,
                              dlat_fieldline,
                              lon,
                              itime,
                              L_MARGIN,
                              xf=xf)

    #----------- Step through and fill in the voxels (the main event) ---------------------
    logging.info("Starting interpolation")

    lat_pairs = [(lat_low, lat_hi)]
    lon_pairs = [(center_lon - lon_spacing / 2., center_lon + lon_spacing / 2.)
                 ]

    # output space
    nfl = len(fieldlines)
    nlons = 1
    nt = len(t)
    n_freq_pairs = len(freq_pairs)
    data_total = np.zeros([nfl, n_freq_pairs, nlons, nt])

    lon1 = center_lon - lon_spacing / 2.
    lon2 = center_lon + lon_spacing / 2.

    for t_ind in np.arange(nt - 1):
        # Per frequency
        data_cur = np.zeros(nfl)
        logging.info("t = %g" % (t_ind * dt))
        for freq_ind, (f1, f2) in enumerate(freq_pairs):
            # print "doing freqs between ", f1, "and", f2

            # Loop over adjacent sets:
            if n_sub_freqs == 0:
                ff = np.arange(0, (f2 - f1),
                               1)  # This version for uniform in frequency
            else:
                ff = np.arange(0, n_sub_freqs,
                               1)  # This version for constant steps per pair
            nf = len(ff)

            fine_freqs = f1 + (f2 - f1) * ff / nf
            # print fine_freqs

            for lat1, lat2 in lat_pairs:
                k0 = (f1, lat1, lon1)
                k1 = (f1, lat2, lon1)
                k2 = (f2, lat1, lon1)
                k3 = (f2, lat2, lon1)
                k4 = (f1, lat1, lon2)
                k5 = (f1, lat2, lon2)
                k6 = (f2, lat1, lon2)
                k7 = (f2, lat2, lon2)
                clat = (lat1 + lat2) / 2.
                f_center = (f1 + f2) / 2.

                tmax_local = min(
                    np.shape(ray_data[k0]['pos'])[1],
                    np.shape(ray_data[k1]['pos'])[1],
                    np.shape(ray_data[k2]['pos'])[1],
                    np.shape(ray_data[k3]['pos'])[1],
                    np.shape(ray_data[k4]['pos'])[1],
                    np.shape(ray_data[k5]['pos'])[1],
                    np.shape(ray_data[k6]['pos'])[1],
                    np.shape(ray_data[k7]['pos'])[1])
                if (t_ind < tmax_local - 1):

                    points_4d = np.hstack([
                        np.vstack([
                            ray_data[k0]['pos'][:, t_ind:t_ind + 2],
                            np.zeros([1, 2])
                        ]),
                        np.vstack([
                            ray_data[k1]['pos'][:, t_ind:t_ind + 2],
                            np.zeros([1, 2])
                        ]),
                        np.vstack([
                            ray_data[k2]['pos'][:, t_ind:t_ind + 2],
                            np.ones([1, 2]) * nf
                        ]),
                        np.vstack([
                            ray_data[k3]['pos'][:, t_ind:t_ind + 2],
                            np.ones([1, 2]) * nf
                        ]),
                        np.vstack([
                            ray_data[k4]['pos'][:, t_ind:t_ind + 2],
                            np.zeros([1, 2])
                        ]),
                        np.vstack([
                            ray_data[k5]['pos'][:, t_ind:t_ind + 2],
                            np.zeros([1, 2])
                        ]),
                        np.vstack([
                            ray_data[k6]['pos'][:, t_ind:t_ind + 2],
                            np.ones([1, 2]) * nf
                        ]),
                        np.vstack([
                            ray_data[k7]['pos'][:, t_ind:t_ind + 2],
                            np.ones([1, 2]) * nf
                        ])
                    ])

                    voxel_vol = voxel_vol_nd(points_4d) * pow(R_E, 3.)

                    # damps_2d = np.hstack([ray_data[k0]['damp'][t_ind:t_ind+2],
                    #                       ray_data[k1]['damp'][t_ind:t_ind+2],
                    #                       ray_data[k2]['damp'][t_ind:t_ind+2],
                    #                       ray_data[k3]['damp'][t_ind:t_ind+2]])
                    # damping_avg = np.mean(damps_2d)
                    damping_pts = np.hstack([
                        ray_data[kk]['damp'][t_ind:t_ind + 2]
                        for kk in [k0, k1, k2, k3, k4, k5, k6, k7]
                    ])
                    damp_interp = interpolate.NearestNDInterpolator(
                        points_4d.T, damping_pts)

                    points_2d = np.hstack([
                        np.vstack([
                            ray_data[k4]['pos'][[0, 2], t_ind:t_ind + 2],
                            np.zeros([1, 2])
                        ]),
                        np.vstack([
                            ray_data[k5]['pos'][[0, 2], t_ind:t_ind + 2],
                            np.zeros([1, 2])
                        ]),
                        np.vstack([
                            ray_data[k6]['pos'][[0, 2], t_ind:t_ind + 2],
                            np.ones([1, 2]) * nf
                        ]),
                        np.vstack([
                            ray_data[k7]['pos'][[0, 2], t_ind:t_ind + 2],
                            np.ones([1, 2]) * nf
                        ])
                    ])

                    # We really should interpolate these 16 corner points instead of just averaging them.
                    stixR_pts = np.hstack([
                        ray_data[kk]['stixR'][t_ind:t_ind + 2]
                        for kk in [k0, k1, k2, k3, k4, k5, k6, k7]
                    ])
                    stixL_pts = np.hstack([
                        ray_data[kk]['stixL'][t_ind:t_ind + 2]
                        for kk in [k0, k1, k2, k3, k4, k5, k6, k7]
                    ])
                    stixP_pts = np.hstack([
                        ray_data[kk]['stixP'][t_ind:t_ind + 2]
                        for kk in [k0, k1, k2, k3, k4, k5, k6, k7]
                    ])
                    mu_pts = np.hstack([
                        ray_data[kk]['mu'][t_ind:t_ind + 2]
                        for kk in [k0, k1, k2, k3, k4, k5, k6, k7]
                    ])
                    psi_pts = np.hstack([
                        ray_data[kk]['psi'][t_ind:t_ind + 2]
                        for kk in [k0, k1, k2, k3, k4, k5, k6, k7]
                    ])
                    vel_pts = np.hstack([
                        ray_data[kk]['vgrel'][t_ind:t_ind + 2]
                        for kk in [k0, k1, k2, k3, k4, k5, k6, k7]
                    ])

                    stixR_interp = interpolate.NearestNDInterpolator(
                        points_4d.T, stixR_pts)
                    stixL_interp = interpolate.NearestNDInterpolator(
                        points_4d.T, stixL_pts)
                    stixP_interp = interpolate.NearestNDInterpolator(
                        points_4d.T, stixP_pts)
                    mu_interp = interpolate.NearestNDInterpolator(
                        points_4d.T, mu_pts)
                    psi_interp = interpolate.NearestNDInterpolator(
                        points_4d.T, psi_pts)
                    vel_interp = interpolate.NearestNDInterpolator(
                        points_4d.T, vel_pts)

                    # tri = Delaunay(points_2d.T, qhull_options='QJ')
                    tri = Delaunay(points_4d.T, qhull_options='QJ')

                    # Loop through the output fieldlines
                    for fl_ind, fl in enumerate(fieldlines):
                        ix = np.arange(0, len(fl['pos']))
                        ief = np.arange(0, nf)
                        px, pf = np.meshgrid(
                            ix, ief, indexing='ij'
                        )  # in 3d, ij gives xyz, xy gives yxz. dumb.
                        # newpoints = np.hstack([fl['pos'][px.ravel(),:][:,[0,2]], np.atleast_2d(ff[pf.ravel()]).T])
                        newpoints = np.hstack([
                            fl['pos'][px.ravel(), :],
                            np.atleast_2d(ff[pf.ravel()]).T
                        ])

                        mask = (tri.find_simplex(newpoints) >= 0) * 1.0
                        # mask = mask.reshape([len(ix), len(ief)])

                        # Entries in newpoints are inside the volume if mask is nonzero
                        # (Mask gives the index of the triangular element which contains it)
                        # for row in newpoints[mask > 0]:
                        #     print "L:", fl['L'], xf.sm2rllmag(row[:-1], itime)
                        #     fieldlines[fl_ind]['crossings'].append(xf.sm2rllmag(row[:-1], itime))

                        mask = mask.reshape([len(ix), len(ief)])
                        minds = np.nonzero(mask)
                        if len(minds[0]) > 0:
                            # unscaled_pwr = (damping_avg/voxel_vol)
                            hit_lats = fl['lat'][minds[0]]
                            hit_freqs = fine_freqs[minds[1]]
                            #     # print "t = ", t_ind, "L = ", fl['L']
                            # print hit_lats, hit_freqs

                            # hit latitude, hit frequency (indices)
                            for hl, hf in zip(minds[0], minds[1]):

                                cur_pos = np.hstack([fl['pos'][hl, :], ff[hf]])
                                psi = psi_interp(cur_pos)[0]
                                mu = mu_interp(cur_pos)[0]
                                damp = damp_interp(cur_pos)[0]
                                vel = vel_interp(cur_pos)[0] * C

                                #              [unitless][m/s][1/m^3] ~ 1/m^2/sec. Multiply by total input energy.
                                if (damp > DAMP_THRESHOLD):
                                    pwr_scale_factor = damp * vel / voxel_vol
                                    tt = np.round(100. * t_ind * dt) / 100.
                                    fieldlines[fl_ind]['crossings'][hl].append(
                                        (tt, fine_freqs[hf], pwr_scale_factor,
                                         psi, mu, damp, vel))
                                    # fl['crossings'].append([fl['L'], fl['lat'][hl], t_ind*dt, fine_freqs[hf]])
                                    #         # Stix parameters are functions of the background medium only,
                                    #         # but we'll average them because we're grabbing them from the
                                    #         # rays at slightly different locations within the cell.
                                    #         # print np.shape(fl['pos'])

                                    fieldlines[fl_ind]['stixR'][
                                        hl] += stixR_interp(cur_pos)[0]
                                    fieldlines[fl_ind]['stixL'][
                                        hl] += stixL_interp(cur_pos)[0]
                                    fieldlines[fl_ind]['stixP'][
                                        hl] += stixP_interp(cur_pos)[0]
                                    fieldlines[fl_ind]['hit_counts'][hl] += 1

    # logging.info("finished with interpolation")
    logging.info("finished with interpolation")

    # Average the background medium parameters:

    for fl_ind, fl in enumerate(fieldlines):
        for lat_ind in range(len(fl['crossings'])):
            n_hits = fl['hit_counts'][lat_ind]
            if n_hits > 0:
                # print fl['L'], ":", fl['lat'][lat_ind],": hit count: ", fl['hit_counts'][lat_ind]

                # average stixR, stixL, stixP
                fl['stixP'][lat_ind] /= n_hits
                fl['stixR'][lat_ind] /= n_hits
                fl['stixL'][lat_ind] /= n_hits
                fl['hit_counts'][lat_ind] = 1

    out_data = dict()
    out_data['fieldlines'] = fieldlines
    out_data['time'] = t
    out_data['Lshells'] = Lshells
    out_data['lat_low'] = lat_low
    out_data['lat_hi'] = lat_hi
    out_data['fmin'] = f_low
    out_data['fmax'] = f_hi
    out_data['freq_pairs'] = freq_pairs

    return out_data
コード例 #9
0
def gen_EA_array(Lshells,
                 dlat_fieldline,
                 center_lon,
                 itime,
                 L_MARGIN=0.1,
                 xf=None):

    if xf is None:
        xf = xflib.xflib(
            lib_path=
            '/shared/users/asousa/WIPP/WIPP_stencils/python/methods/libxformd.so'
        )

    # Constants
    Hz2Rad = 2. * np.pi
    D2R = np.pi / 180.
    R2D = 180. / np.pi
    H_IONO_BOTTOM = 1e5
    H_IONO_TOP = 1e6
    R_E = 6371e3
    C = 2.997956376932163e8
    Q_EL = 1.602e-19
    M_EL = 9.1e-31
    E_EL = 5.105396765648739E5
    MU0 = np.pi * 4e-7
    EPS0 = 8.854E-12
    B0 = 3.12e-5

    # ------------------ Set up field lines ----------------------------
    fieldlines = []

    for L in Lshells:
        fieldline = dict()
        maxlat = np.floor(
            np.arccos(np.sqrt((R_E + H_IONO_TOP) / R_E / L)) * R2D)
        n_lsteps = int(np.round(2.0 * maxlat / dlat_fieldline))
        lat_divisions = np.linspace(maxlat, -1.0 * maxlat, n_lsteps + 1)
        lat_centers = lat_divisions[0:-1] - dlat_fieldline / 2.

        fieldline['lat'] = lat_centers
        fieldline['L'] = L
        # Radius of tube around field line:
        slat = np.sin(lat_centers * D2R)
        clat = np.cos(lat_centers * D2R)
        clat2 = pow(clat, 2.)
        slat2 = pow(slat, 2.)
        slat_term = np.sqrt(1. + 3. * slat2)

        radii = clat2 * clat / slat_term * L_MARGIN
        R_centers = L * clat2

        fieldline['R'] = R_centers
        fieldline['xradius'] = radii

        # Approximate each segment as a cylinder:
        seg_length = R_centers * dlat_fieldline * D2R
        seg_vol = np.pi * pow(radii, 2.) * seg_length * pow(R_E,
                                                            3.)  # cubic meters

        fieldline['vol'] = seg_vol
        fieldline['total_vol'] = np.sum(seg_vol)

        fieldline['x'] = R_centers * clat
        fieldline['y'] = R_centers * slat

        fieldline['x_unit_vect'] = (3 * clat2 - 2) / slat_term
        fieldline['y_unit_vect'] = (3 * slat * clat) / slat_term

        coords_rllmag = np.vstack(
            [R_centers, lat_centers,
             np.ones(len(lat_centers)) * center_lon])
        coords_sm = []
        for row in coords_rllmag.T:
            coords_sm.append(xf.rllmag2sm(row, itime))
        fieldline['pos'] = np.array(coords_sm)

        # Calculate loss cone angles:
        # (dipole field for now)
        fieldline['wh'] = (Q_EL * B0 / M_EL) / pow(L, 3.) * slat_term / pow(
            clat, 6.)
        fieldline['dwh_ds'] = 3. * fieldline['wh'] / (
            L * R_E) * slat / slat_term * (1. / (slat_term * slat_term) + 2. /
                                           (clat * clat))

        # Equatorial loss cone
        epsm = (1. / L) * (1. + H_IONO_BOTTOM / R_E)
        fieldline['alpha_eq'] = np.arcsin(
            np.sqrt(pow(epsm, 3.) / np.sqrt(1 + 3. * (1. - epsm))))

        # Local loss cone
        fieldline['alpha_lc'] = np.arcsin(
            np.sqrt(slat_term / pow(clat, 6.)) * np.sin(fieldline['alpha_eq']))
        salph = np.sin(fieldline['alpha_lc'])
        calph = np.cos(fieldline['alpha_lc'])

        fieldline[
            'ds'] = L * R_E * slat_term * clat * dlat_fieldline * np.pi / 180.0
        fieldline['dv_para_ds'] = -0.5 * (
            salph * salph / (calph * fieldline['wh'])) * fieldline['dwh_ds']

        # Calculate flight time constants to ionosphere: (dipole field again)
        iono_lat = np.floor(
            np.arccos(np.sqrt((R_E + H_IONO_BOTTOM) / R_E / L)) * R2D)
        lats_fine = np.arange(iono_lat, -iono_lat, -dlat_fieldline / 100.)
        rads_fine = L * R_E * pow(np.cos(lats_fine * D2R), 2.0)
        # Straight line step between each fine point. Whatever, it works.
        xx = rads_fine * np.cos(D2R * lats_fine)
        yy = rads_fine * np.sin(D2R * lats_fine)
        dx = np.diff(xx)
        dy = np.diff(yy)
        # 4.4.2017. This matches the anylitical version you did in mathematica
        dd = np.sqrt(dx**2 + dy**2)
        dist_n = np.cumsum(
            dd)  # Distance to northern hemi from lats_fine, in meters
        # print dd[0:5], lats_fine[0:5]
        # evaluate walt 4.25:
        Bs = np.sqrt(1.0 + 3. * pow(np.sin(D2R * lats_fine), 2.)) / pow(
            np.cos(D2R * lats_fine), 6.0)
        Bmir = np.sqrt(1.0 + 3. * pow(np.sin(D2R * iono_lat), 2.)) / pow(
            np.cos(D2R * iono_lat), 6.0)
        # print Bs, Bmir
        ftc_n_tmp = dd / np.sqrt(1.0 - Bs[:-1] / Bmir)
        ftc_n_tmp[np.isinf(ftc_n_tmp)] = 0
        ftc_n = np.cumsum(ftc_n_tmp)

        # Find locations of EA segments in the fine-scale integrated vector. Magic line.
        indices = np.abs(np.subtract.outer(lats_fine, lat_centers)).argmin(0)
        fieldline['ftc_n'] = ftc_n[indices]
        fieldline['ftc_s'] = ftc_n[-1] - fieldline['ftc_n']

        # fieldline['ftc_n'] = ftc_n[100*np.arange(0,len(lat_centers) + 1)]
        # fieldline['ftc_s'] = ftc_n[-1] - fieldline['ftc_n']
        # print fieldline['ftc_n']
        # print fieldline['ftc_s']

        fieldline['crossings'] = [
            [] for i in range(len(lat_centers))
        ]  # Initialize an empty list to store crossings in
        # fieldline['crossings']  = []
        fieldline['stixR'] = np.zeros_like(lat_centers)
        fieldline['stixL'] = np.zeros_like(lat_centers)
        fieldline['stixP'] = np.zeros_like(lat_centers)
        fieldline['mu'] = np.zeros_like(lat_centers)
        fieldline['hit_counts'] = np.zeros_like(lat_centers)
        fieldlines.append(fieldline)
    return fieldlines