Ejemplo n.º 1
0
def makePropLine(ref_pos, D, alpha=255):

    lats = []
    lons = []
    for line in D:
        temp = Position(0, 0, 0)
        temp.x = line[0]
        temp.y = line[1]
        temp.z = line[2]
        temp.pos_geo(ref_pos)
        if not np.isnan(temp.lat) and not np.isnan(temp.lon):
            lats.append(temp.lat)
            lons.append(temp.lon)

    lats.sort()
    lons.sort()

    return lats, lons
Ejemplo n.º 2
0
    def makePropLine(self, D, alpha=255):

        ref_pos = Position(self.bam.setup.lat_centre,
                           self.bam.setup.lon_centre, 0)
        lats = []
        lons = []
        for line in D:
            temp = Position(0, 0, 0)
            temp.x = line[0]
            temp.y = line[1]
            temp.z = line[2]
            temp.pos_geo(ref_pos)
            if not np.isnan(temp.lat) and not np.isnan(temp.lon):
                lats.append(temp.lat)
                lons.append(temp.lon)

        lats.sort()
        lons.sort()

        start_pt = pg.PlotCurveItem()
        start_pt.setData(x=lons, y=lats)
        start_pt.setPen((255, 85, 0, alpha))

        return start_pt
Ejemplo n.º 3
0
def psoSearch(stns, w, s_name, bam, prefs, ref_pos, manual=False, pert_num=0, override_supra=[], theo=False):
    """ Optimizes the paths between the detector stations and a supracenter to find the best fit for the 
        position of the supracenter, within the given search area. The supracenter is found with an initial guess,
        in a given grid, and is moved closer to points of better fit through particle swarm optimization.
        Produces a graph with the stations and residual results, and prints out the optimal supracenter location
    """

    print('Data converted. Searching...')

    setup = bam.setup
    atmos = bam.atmos

    search_min = Position(setup.lat_min, setup.lon_min, setup.elev_min)
    search_max = Position(setup.lat_max, setup.lon_max, setup.elev_max)

    if not manual:
        try:
            search_min.pos_loc(ref_pos)
            search_max.pos_loc(ref_pos)
        except (AttributeError, TypeError) as e:
            errorMessage('Search min and search max have not been defined! Aborting search!', 2, info='Please define a search area in the "Sources" tab on the left side of the screen!', detail='{:}'.format(e))
            return None


    output_name = prefs.workdir
    
    if not isinstance(override_supra, list):
        single_point = override_supra
    else:    
        single_point = setup.manual_fragmentation_search[0]

    if single_point.toList()[0] is None and manual:
        errorMessage('Manual Fragmentation Point undefined', 2, info='Unable to parse: Lat: {:} Lon: {:} Elev: {:} Time: {:}'.format(*single_point.toList()))
        return None        


    ref_time = setup.fireball_datetime

    if setup.enable_restricted_time:
        kotc = setup.restricted_time
    else:
        kotc = None

    # check if user defined occurrence time is used
    if kotc != None:
    
        kotc = (kotc - ref_time).total_seconds()

    # number of stations total
    n_stations = len(stns)

    # Station Location
    xstn = stns[0:n_stations, 0:3]

    # Initialize arrays
    # Travel time to each station
    time3D = np.zeros(n_stations)

    # Initial azimuths angles of each station
    az = np.zeros(n_stations)

    # Initial takeoff angles of each station
    tf = np.zeros(n_stations)

    # difference in theoretical and simulated travel times
    sotc = np.zeros_like(n_stations)

    # Initialize variables
    # combined weights
    nwn = sum(w)

    if prefs.ballistic_en:
        try:
            v = -setup.trajectory.vector.xyz
            setup.ref_pos = setup.trajectory.pos_f
            if prefs.debug:
                print("Constraining Trajectory")
        except:
            v = [None]
            if prefs.debug:
                print("Free Search")
    else:
        v = [None]
        if prefs.debug:
            print("Free Search")


    # If automatic search
    if not manual:
        
        # Prevent search below stations
        if search_min.elev < max(xstn[:, 2]):

            # Must be just above the stations
            search_min.elev = max(xstn[:, 2]) + 0.0001

        # Boundaries of search volume
        #  [x, y, z] local coordinates

        # arguments to be passed to timeFunction()
        args = (stns, w, kotc, setup, ref_pos, atmos, prefs, v, pert_num, theo)

        # Particle Swarm Optimization
        # x_opt - optimal supracenter location
        # f_opt - optimal supracenter error

        # if setup.restrict_to_trajectory:
        #     #cons = [lineConstraintx, lineConstrainty, lineConstraintz]
        #     x_opt, f_opt = pso(timeFunction, lb, ub, f_ieqcons=lineConstraint, args=args, swarmsize=int(setup.swarmsize), maxiter=int(setup.maxiter), \
        #                 phip=setup.phip, phig=setup.phig, debug=False, omega=setup.omega, minfunc=setup.minfunc, minstep=setup.minstep) 
        # else:

        # # Restricted to trajectory
        # if v[0] != None:
        #     x_opt_temp, f_opt, sup, errors = pso(timeFunction, search_min.xyz, search_max.xyz, \
        #             ieqcons=[trajConstraints, timeConstraints], args=args,\
        #             swarmsize=int(prefs.pso_swarm_size), maxiter=int(prefs.pso_max_iter), \
        #             phip=prefs.pso_phi_p, phig=prefs.pso_phi_g, debug=False, omega=prefs.pso_omega, \
        #             minfunc=prefs.pso_min_error, minstep=prefs.pso_min_step, processes=1, particle_output=True) 
        

        x_opt_temp, f_opt, sup, errors = pso(timeFunction, search_min.xyz, search_max.xyz, \
                    args=args, swarmsize=int(prefs.pso_swarm_size), maxiter=int(prefs.pso_max_iter), \
                    phip=prefs.pso_phi_p, phig=prefs.pso_phi_g, debug=False, omega=prefs.pso_omega,\
                    minfunc=prefs.pso_min_error, minstep=prefs.pso_min_step, processes=1, particle_output=True) 


        print('Done Searching')
        
        x_opt = Position(0, 0, 0)
        x_opt.x = x_opt_temp[0]
        x_opt.y = x_opt_temp[1]
        x_opt.z = x_opt_temp[2]
        x_opt.pos_geo(ref_pos)

    # If manual search
    else:

        single_point.position.pos_loc(ref_pos)
        x_opt = single_point.position
        sup = single_point.position.xyz
        errors=0


    # Get results for current Supracenter
    time3D, az, tf, r, motc, sotc, trace = outputWeather(n_stations, x_opt, stns, setup, \
                                                ref_pos, atmos, output_name, s_name, kotc, w, prefs, theo)

    for ii, element in enumerate(time3D):
        if np.isnan(element):
            w[ii] = 0
            sotc[ii] = 0

    # Find error for manual searches
    if manual:

        f_opt = np.dot(w, np.absolute(sotc - np.dot(w, sotc)/nwn))/nwn

    # x, y distance from Supracenter to each station
    horz_dist = np.zeros(n_stations)
    for i in range(n_stations):

        horz_dist[i] = np.sqrt((x_opt.x - xstn[i, 0])**2 + (x_opt.y - xstn[i, 1])**2)/1000


    # Calculate and Set the Occurrence Time into HH:MM:SS
    time_diff = motc + ref_time.microsecond/1e6 + ref_time.second + ref_time.minute*60 + ref_time.hour*3600

    try:
        otc = (datetime.datetime.min + datetime.timedelta(seconds=time_diff)).time()
    except (ValueError, OverflowError):
        print('STATUS: Unable to parse otc')
        otc = None

    try:
        #while max(errors) > setup.max_error/100:
        a = []
        std_error = np.std(errors)
        lim = np.mean(errors) + 0*std_error

        for i in range(len(errors)):
            if errors[i] >= lim:
                a.append(i)

        errors = np.delete(errors, (a), axis=0)
        sup = np.delete(sup, (a), axis=0)
    except:
        print("WARNING: Unable to filter errors")

    class Results:

        def __init__(self):
            pass

    results = Results()

    results.r = r
    results.w = w
    results.x_opt = x_opt
    results.f_opt = f_opt
    results.sup = sup
    results.errors = errors
    results.horz_dist = horz_dist
    results.time3D = time3D
    results.az = az
    results.tf = tf
    results.motc = motc
    results.sotc = sotc
    results.kotc = kotc
    results.otc = otc
    results.trace = trace

    return results

    # # scatter plot(s)
    # min_search, max_search = scatterPlot(single_point, n_stations, xstn, s_name, r, x_opt, \
    #                                         reported_points, search, output_name, ref_pos, sup, errors, tweaks, dataset)

    # # residual plot
    # residPlot(x_opt, s_name, xstn, r, output_name, n_stations)

    # # output results
    # outputText(min_search, max_search, single_point, ref_time, otc, kotc, x_opt, f_opt, n_stations, tweaks, s_name, xstn, \
    #                                                                     r, w, az, tf, time3D, horz_dist, output_name, tstn)
Ejemplo n.º 4
0
def psoTrajectory(station_list, bam, prefs):

    point_on_traj = None

    ref_pos = Position(bam.setup.lat_centre, bam.setup.lon_centre, 0)
    # ref_pos = bam.setup.trajectory.pos_f

    if bam.setup.pos_min.isNone() or bam.setup.pos_max.isNone():
        errorMessage(
            'Search boundaries are not defined!',
            2,
            info=
            'Please define the minimum and maximum parameters in the "Sources" tab on the left side of the screen!'
        )
        return None

    bam.setup.pos_min.pos_loc(ref_pos)
    bam.setup.pos_max.pos_loc(ref_pos)

    if point_on_traj is None:

        bounds = [
            (bam.setup.pos_min.x, bam.setup.pos_max.x),  # X0
            (bam.setup.pos_min.y, bam.setup.pos_max.y),  # Y0
            (bam.setup.t_min, bam.setup.t_max),  # t0
            (bam.setup.v_min, bam.setup.v_max),  # Velocity (m/s)
            (bam.setup.azimuth_min.deg, bam.setup.azimuth_max.deg),  # Azimuth
            (bam.setup.zenith_min.deg, bam.setup.zenith_max.deg
             )  # Zenith angle
        ]

    else:

        bounds = [
            (bam.setup.v_min, bam.setup.v_max),  # Velocity (m/s)
            (bam.setup.azimuth_min.deg, bam.setup.azimuth_max.deg),  # Azimuth
            (bam.setup.zenith_min.deg, bam.setup.zenith_max.deg
             )  # Zenith angle
        ]

    lower_bounds = [bound[0] for bound in bounds]
    upper_bounds = [bound[1] for bound in bounds]

    if prefs.debug:
        print('Free Search')

    import matplotlib.pyplot as plt

    plt.ion()

    fig, ax = plt.subplots(2, 3, sharey='row')
    ax[0, 0].set_ylabel("Total Error")
    ax[1, 0].set_ylabel("Total Error")
    ax[0, 0].set_xlabel("Latitude")
    ax[0, 1].set_xlabel("Longitude")
    ax[0, 2].set_xlabel("Time")
    ax[1, 0].set_xlabel("Velocity")
    ax[1, 1].set_xlabel("Azimuth")
    ax[1, 2].set_xlabel("Zenith")

    plot = []

    for i in range(2):
        for j in range(3):

            plot.append(ax[i, j].scatter([], []))

    x, fopt = pso(trajSearch, lower_bounds, upper_bounds, args=(station_list, ref_pos, bam, prefs, plot, ax, fig, point_on_traj), \
        maxiter=prefs.pso_max_iter, swarmsize=prefs.pso_swarm_size, \
        phip=prefs.pso_phi_p, phig=prefs.pso_phi_g, debug=False, omega=prefs.pso_omega, \
        particle_output=False)

    # if point_on_traj is None:
    print('Results:')
    print('X: {:.4f}'.format(x[0]))
    print('Y: {:.4f}'.format(x[1]))
    print('Time: {:.4f}'.format(x[2]))
    print('Velocity: {:.4f}'.format(x[3]))
    print('Azimuth: {:.4f}'.format(x[4]))
    print('Zenith: {:.4f}'.format(x[5]))
    print('Adjusted Error: {:.4f}'.format(fopt))
    # else:
    #     print('Results:')
    #     print('Velocity: {:.4f}'.format(x[0]))
    #     print('Azimuth: {:.4f}'.format(x[1]))
    #     print('Zenith: {:.4f}'.format(x[2]))
    #     print('Adjusted Error: {:.4f}'.format(fopt))

    # if point_on_traj is None:
    geo = Position(0, 0, 0)
    geo.x = x[0]
    geo.y = x[1]
    geo.z = 0
    geo.pos_geo(ref_pos)

    print('Geometric Landing Point:')
    print(geo)

    stat_names = []
    stat_pick = []

    final_traj = Trajectory(x[2],
                            x[3],
                            zenith=Angle(x[5]),
                            azimuth=Angle(x[4]),
                            pos_f=geo)
    points = final_traj.findPoints(gridspace=100, min_p=17000, max_p=50000)

    for stn in station_list:
        stat_names.append("{:}-{:}".format(stn[1], stn[2]))

        t_nom, t_pert = timeOfArrival(np.array([stn[3], stn[4], stn[5]]),
                                      final_traj,
                                      bam,
                                      prefs,
                                      points,
                                      ref_loc=ref_pos)

        stat_pick.append(t_nom - stn[6])

    return [x, fopt, geo, stat_names, stat_pick]
Ejemplo n.º 5
0
def trajSearch(params, station_list, ref_pos, bam, prefs, plot, ax, fig,
               point_on_traj):

    if point_on_traj is None:

        x0, y0, t0, v, azim, zangle = params

        pos_f = Position(0, 0, 0)
        pos_f.x = x0
        pos_f.y = y0
        pos_f.z = 0
        pos_f.pos_geo(ref_pos)

        temp_traj = Trajectory(t0,
                               v,
                               zenith=Angle(zangle),
                               azimuth=Angle(azim),
                               pos_f=pos_f)

    else:

        v, azim, zangle = params

        temp_traj = Trajectory(point_on_traj.time,
                               v,
                               zenith=Angle(zangle),
                               azimuth=Angle(azim),
                               pos_i=point_on_traj.position)

        pos_f = temp_traj.pos_f

        temp_traj = Trajectory(point_on_traj.time,
                               v,
                               zenith=Angle(zangle),
                               azimuth=Angle(azim),
                               pos_f=pos_f)

    #points = temp_traj.findPoints(gridspace=1000, min_p=pos_f.elev, max_p=100000)

    points = temp_traj.trajInterp2(div=50, min_p=17000, max_p=60000, xyz=False)

    if prefs.debug:
        dif = points[1] - points[0]
        dis = (dif[0]**2 + dif[1]**2 + dif[2]**2)**0.5
        tim = dis / 330

    u = temp_traj.vector.xyz

    cost_value = 0
    failed_stats = 0
    error_list = []
    N = len(station_list)

    for stn in station_list:

        t_theo, t_pert = timeOfArrival(np.array([stn[3], stn[4], stn[5]]),
                                       temp_traj,
                                       bam,
                                       prefs,
                                       points,
                                       ref_loc=ref_pos)

        t_obs = stn[6]

        if not np.isnan(t_theo):

            cost_value = ((1 + (t_theo - t_obs)**2)**0.5 - 1)
            error_list.append(cost_value)

        else:
            failed_stats += 1
        # if np.isnan(t_theo):
        #     if prefs.debug:
        #         print(np.inf)
        #     return np.inf

    perc_fail = 100 - failed_stats / len(station_list) * 100

    # temporary adjustment to try and get the most stations
    if N - failed_stats >= 3:
        total_error = sum(error_list) / (
            N - failed_stats)  # + 2*max(error_list)*(failed_stats)
    else:
        total_error = np.inf

    if prefs.debug:
        print(
            "Error {:10.4f} | Failed Stats {:3} {:} | Error between points: {:.2f} km ({:.2f} s)"
            .format(total_error, failed_stats,
                    printPercent(perc_fail, N - failed_stats), dis / 1000,
                    tim))
        # Quick adjustment to try and better include stations

    for i in range(6):

        array = np.array(plot[i].get_offsets())

        if not np.isinf(total_error):

            if i == 0:
                point = np.array([pos_f.lat, total_error])
            elif i == 1:
                point = np.array([pos_f.lon, total_error])
            elif i == 2:
                if point_on_traj is not None:
                    t0 = 0
                point = np.array([t0, total_error])
            elif i == 3:
                point = np.array([v, total_error])
            elif i == 4:
                point = np.array([azim, total_error])
            elif i == 5:
                point = np.array([zangle, total_error])

            # add the points to the plot
            array = np.append(array, [point], axis=0)
            plot[i].set_offsets(array)

            # # update x and ylim to show all points:
            ax[i // 3, i % 3].set_xlim(array[:, 0].min() - 0.01,
                                       array[:, 0].max() + 0.01)
            ax[i // 3, i % 3].set_ylim(array[:, 1].min() - 0.01,
                                       array[:, 1].max() + 0.01)

        # update the figure
    fig.canvas.draw()
    plt.pause(0.05)

    return total_error
Ejemplo n.º 6
0
def waveReleasePointWindsContour(bam,
                                 traj,
                                 ref_loc,
                                 points,
                                 div=37,
                                 mode='ballistic'):
    setup = bam.setup
    atmos = bam.atmos
    steps = 90
    alpha = np.linspace(0, 360 * ((steps - 1) / steps), steps)
    alpha = np.radians(alpha)
    beta = np.linspace(0, 90 * ((steps - 1) / steps), steps)
    beta = np.radians(beta)
    theta = setup.trajectory.azimuth.rad
    phi = setup.trajectory.zenith.rad
    tol = 25  #deg
    # tol_fact = np.radians(np.linspace(-tol, tol, 10))
    WIND = True
    u = traj.getTrajVect()

    v_list = []
    for i in range(steps):
        for j in range(steps):

            v = np.array([np.sin(alpha[i])*np.sin(beta[j]),\
                        np.cos(alpha[i])*np.sin(beta[j]),\
                        -np.cos(beta[j])])

            if np.abs(90 - np.degrees(np.arccos(np.dot(u, v)))) <= tol:

                v_list.append([alpha[i], beta[j]])

    v_list = np.array(v_list)

    results = []

    # temp hotfix
    if mode == 'ballistic_old':

        grid_space = 25

        p1 = Position(43.8, 13.1, 0)
        p2 = Position(47.8, 17.1, 0)

        p1.pos_loc(ref_loc)
        p2.pos_loc(ref_loc)

        xs = np.linspace(p1.x, p2.x, grid_space)
        ys = np.linspace(p1.y, p2.y, grid_space)

        n_steps = grid_space**2 * len(points)
        for xnum, xx in enumerate(xs):
            for ynum, yy in enumerate(ys):

                angle_list = []
                time_list = []
                D = [xx, yy, 0]

                for pnum, pp in enumerate(points):

                    step = pnum + ynum * len(points) + xnum * grid_space * len(
                        points)
                    loadingBar("Contour Calculation", step, n_steps)

                    P = Position(pp[0], pp[1], pp[2])

                    P.pos_loc(ref_loc)

                    S = P.xyz

                    R = Position(0, 0, 0)
                    R.x = D[0]
                    R.y = D[1]
                    R.z = D[2]
                    R.pos_geo(ref_loc)

                    lats = [P.lat, R.lat]
                    lons = [P.lon, R.lon]
                    elev = [P.elev, R.elev]

                    z_profile, _ = atmos.getSounding(
                        lats,
                        lons,
                        elev,
                        ref_time=setup.fireball_datetime,
                        spline=100)

                    res = cyscan(np.array(S),
                                 np.array(D),
                                 z_profile,
                                 wind=True,
                                 h_tol=330,
                                 v_tol=3000,
                                 debug=False)

                    alpha = np.radians(res[1])
                    beta = np.radians(180 - res[2])

                    res_vector = np.array([np.sin(alpha)*np.sin(beta),\
                                np.cos(alpha)*np.sin(beta),\
                                -np.cos(beta)])

                    angle_list.append(
                        np.abs(90 - np.degrees(
                            np.arccos(
                                np.dot(
                                    u / np.sqrt(u.dot(u)), res_vector /
                                    np.sqrt(res_vector.dot(res_vector)))))))
                    time_list.append(res[0])

                if np.nanmin(angle_list) <= tol:

                    best_angle_index = np.nanargmin(angle_list)

                    best_time = time_list[best_angle_index]

                    if not np.isnan(best_time):
                        res = [xx, yy, 0, best_time]

                        results.append(res)

            # u = np.array([bam.setup.trajectory.vector.x,
            #               bam.setup.trajectory.vector.y,
            #               bam.setup.trajectory.vector.z])

            # angle_off = []
            # X = []
            # for i in range(len(bam.setup.fragmentation_point)):
            #     az = stn.times.fragmentation[i][0][1]
            #     tf = stn.times.fragmentation[i][0][2]

            #     az = np.radians(az)
            #     tf = np.radians(180 - tf)
            #     v = np.array([np.sin(az)*np.sin(tf), np.cos(az)*np.sin(tf), -np.cos(tf)])

            #     angle_off.append(np.degrees(np.arccos(np.dot(u/np.sqrt(u.dot(u)), v/np.sqrt(v.dot(v))))))
            #     X.append(bam.setup.fragmentation_point[i].position.elev)
            # angle_off = np.array(angle_off)
            # try:
            #     best_indx = np.nanargmin(abs(angle_off - 90))

            # except ValueError:
            #     best_indx = None
            #     a.append(np.array([np.nan, np.nan, np.nan, np.nan]))
            #     for pert in perturbations:
            #         a.append(np.array([np.nan, np.nan, np.nan, np.nan]))
            #     stn.times.ballistic.append(a)
            #     continue

            # np.array([t_arrival, azimuth, takeoff, E[k, l]])

    elif mode == 'ballistic':
        n_steps = len(v_list) * len(points)
        WIND = True
        for pp, p in enumerate(points):

            for vv, v in enumerate(v_list):

                step = vv + pp * len(v_list)
                loadingBar("Contour Calculation", step, n_steps)

                # v[i] = np.array([np.sin(alpha[i])*np.sin(beta[i]),\
                #                  np.cos(alpha[i])*np.sin(beta[i]),\
                #                                 -np.cos(beta[i])])

                P = Position(p[0], p[1], p[2])
                S = Position(p[0], p[1], 0)

                P.pos_loc(ref_loc)

                pt = P.xyz
                # s = p + p[2]/np.cos(beta[i])*v[i]
                # S = Position(0, 0, 0)
                # P = Position(0, 0, 0)
                # S.x, S.y, S.z = s[0], s[1], s[2]
                # P.x, P.y, P.z = p[0], p[1], p[2]
                # S.pos_geo(ref_loc)
                # P.pos_geo(ref_loc)

                lats = [P.lat, S.lat]
                lons = [P.lon, S.lon]
                elev = [P.elev, S.elev]
                # z_profile, _ = supra.Supracenter.cyweatherInterp.getWeather(p, s, setup.weather_type, \
                #      ref_loc, copy.copy(sounding), convert=True)
                if WIND:
                    z_profile, _ = atmos.getSounding(
                        lats,
                        lons,
                        elev,
                        ref_time=setup.fireball_datetime,
                        spline=200)

                    res = anglescan(pt,
                                    np.degrees(v[0]),
                                    np.degrees(v[1]) + 90,
                                    z_profile,
                                    wind=True,
                                    debug=False)

                else:
                    # if no wind, just draw a straight line

                    vect = np.array([np.sin(v[0])*np.sin(v[1]),\
                            np.cos(v[0])*np.sin(v[1]),\
                            -np.cos(v[1])])

                    s = -pt[2] / vect[2]

                    ground_point = pt + s * vect

                    ground_time = s / 330

                    res = [
                        ground_point[0], ground_point[1], ground_point[2],
                        ground_time
                    ]

                # This is the limit in distance from the trajectory (hardcoded)
                if res[-1] <= 1000:
                    # if np.sqrt(res[0]**2 + res[1]**2) <= 150000:
                    results.append(res)

    else:
        # n_steps = len(tol_fact)*len(points)*steps

        beta = np.linspace(90 + 0.01, 180, steps)
        beta = np.radians(beta)
        p = points

        for ii, i in enumerate(range(steps)):
            for jj, j in enumerate(range(steps)):
                # print(np.degrees(beta[i]))
                step = jj + ii * steps
                loadingBar("Contour Calculation", step, n_steps)


                v[i*steps + j] = np.array([np.sin(alpha[i])*np.sin(beta[j]),\
                                 np.cos(alpha[i])*np.sin(beta[j]),\
                                                -np.cos(beta[j])])
                s = p + p[2] / np.cos(beta[j]) * v[i * steps + j]

                S = Position(0, 0, 0)
                P = Position(0, 0, 0)
                S.x, S.y, S.z = s[0], s[1], s[2]
                P.x, P.y, P.z = p[0], p[1], p[2]
                S.pos_geo(ref_loc)
                P.pos_geo(ref_loc)

                lats = [P.lat, S.lat]
                lons = [P.lon, S.lon]
                elev = [P.elev, S.elev]

                z_profile, _ = atmos.getSounding(
                    lats,
                    lons,
                    elev,
                    ref_time=setup.fireball_datetime,
                    spline=100)
                res = anglescan(p,
                                np.degrees(alpha[i]),
                                np.degrees(beta[j]),
                                z_profile,
                                wind=True,
                                debug=False)

                # if np.sqrt(res[0]**2 + res[1]**2) <= 200000:
                results.append(res)

    return results
Ejemplo n.º 7
0
def propegateBackwards(ref_pos, stn, bam, offset=0):

    S = stn.metadata.position

    S.pos_loc(ref_pos)

    # Initial guess for sounding
    sounding, _ = bam.atmos.getSounding(lat=[S.lat, S.lat],
                                        lon=[S.lon, S.lon],
                                        heights=[S.elev, 50000])

    D = []
    offset = 0

    for pol in range(len(stn.polarization.azimuth)):
        min_az = stn.polarization.azimuth[
            pol] - SIGMA * stn.polarization.azimuth_error[pol]
        max_az = stn.polarization.azimuth[
            pol] + SIGMA * stn.polarization.azimuth_error[pol]

        for azimuth in np.linspace(min_az, max_az, 5):
            for zenith in np.linspace(1, 89, 100):

                # T - expected final arrival, with bad sounding
                # Recalculate winds
                # D - real, expected final arrival
                # This is overkill, atmosphere won't change that much

                T_pos = anglescanrev(S.xyz, (azimuth + offset) % 360,
                                     zenith,
                                     sounding,
                                     wind=True)
                T = Position(0, 0, 0)
                T.x = T_pos[0]
                T.y = T_pos[1]
                T.z = T_pos[2]
                T.pos_geo(ref_pos)

                try:
                    sounding_plus, perts = bam.atmos.getSounding(
                        lat=[S.lat, T.lat],
                        lon=[S.lon, T.lon],
                        heights=[S.elev, 50000])
                except ValueError:
                    sounding_plus, perts = bam.atmos.getSounding(
                        lat=[S.lat, S.lat],
                        lon=[S.lon, S.lon],
                        heights=[S.elev, 50000])

                nom_data = [None] * len(perts + 1)
                nom_data[0] = anglescanrev(S.xyz, (azimuth + offset) % 360,
                                           zenith,
                                           sounding_plus,
                                           wind=True,
                                           trace=True)
                for pp, pert in enumerate(perts):
                    nom_data[pp] = anglescanrev(S.xyz,
                                                (azimuth + offset) % 360,
                                                zenith,
                                                pert,
                                                wind=True,
                                                trace=True)

                # Repeat 180 deg away

                T_pos = anglescanrev(S.xyz, (azimuth + offset + 180) % 360,
                                     zenith,
                                     sounding,
                                     wind=True)
                T = Position(0, 0, 0)
                T.x = T_pos[0]
                T.y = T_pos[1]
                T.z = T_pos[2]
                T.pos_geo(ref_pos)

                try:
                    sounding_plus, perts = bam.atmos.getSounding(
                        lat=[S.lat, T.lat],
                        lon=[S.lon, T.lon],
                        heights=[S.elev, 50000])
                except ValueError:
                    sounding_plus, perts = bam.atmos.getSounding(
                        lat=[S.lat, S.lat],
                        lon=[S.lon, S.lon],
                        heights=[S.elev, 50000])

                nom_data_rev = [None] * len(perts + 1)
                nom_data_rev[0] = anglescanrev(S.xyz,
                                               (azimuth + offset + 180) % 360,
                                               zenith,
                                               sounding_plus,
                                               wind=True,
                                               trace=True)
                for pp, pert in enumerate(perts):
                    nom_data_rev[pp] = anglescanrev(
                        S.xyz, (azimuth + offset + 180) % 360,
                        zenith,
                        pert,
                        wind=True,
                        trace=True)

                for ii in range(len(nom_data)):
                    for line in nom_data[ii]:
                        line[3] -= stn.polarization.time[pol]
                        D.append(line)

                    for line in nom_data_rev[ii]:
                        line[3] -= stn.polarization.time[pol]
                        D.append(line)

    return D