Example #1
0
def presSearch(p, gem_inputs, paths=False):
    Ro = 10.0

    target_pres = p

    pres_ws = 0

    tol = 1e-3

    source_list, stat, v, theta, dphi, sounding_pres, sw, wind, dopplershift = gem_inputs
    search_min = [tol]
    search_max = [100]
    Ro, f_opt = pso(overpressureErr, search_min, search_max, \
        args=gem_inputs + [p, 'pres', 'ws'], swarmsize=SWARM_SIZE, maxiter=MAX_ITER, processes=1, minfunc=tol, minstep=1e-3)
    Ro = Ro[0]
    print("Pressure Weak Shock: {:.2f} mPa Ro = {:.3f} m".format(p * 1000, Ro))

    Ro_ws = Ro

    Ro = 10.0
    pres_lin = 0
    Ro, f_opt = pso(overpressureErr, search_min, search_max, \
        args=gem_inputs + [p, 'pres', 'lin'], swarmsize=SWARM_SIZE, maxiter=MAX_ITER, processes=1, minfunc=tol, minstep=1e-3)
    Ro = Ro[0]
    print("Pressure Linear: {:.2f} mPa Ro = {:.3f} m".format(p * 1000, Ro))

    Ro_lin = Ro

    if paths:
        source_list, stat, v, theta, dphi, sounding_pres, sw, wind, dopplershift = gem_inputs
        tau, tauws, Z, sR, inc, talt, dpws, dp, it = overpressureihmod_Ro(
            source_list,
            stat,
            Ro_ws,
            v,
            theta,
            dphi,
            sounding_pres,
            sw,
            wind=wind,
            dopplershift=dopplershift)
        weak_path = tau[:it] + tauws[it:]
        tau, tauws, Z, sR, inc, talt, dpws, dp, it = overpressureihmod_Ro(
            source_list,
            stat,
            Ro_lin,
            v,
            theta,
            dphi,
            sounding_pres,
            sw,
            wind=wind,
            dopplershift=dopplershift)
        lin_path = tau
        return Ro_ws, Ro_lin, weak_path, lin_path, tau, Z, it

    return Ro_ws, Ro_lin
Example #2
0
    def inverse_gunc(self, p_ans):
        a, b = pso(gunc_error, [1], [15], args=([p_ans, self.J_m, \
                        self.W_0, self.P, self.P_0, self.Jd, self.c_m, self.f_d, self.R,\
                         self.P_a, self.k, self.b, self.I, self.cf, self.horizontal_range, self.v]), \
                        processes=1, swarmsize=1000, maxiter=1000)

        return 10**(a[0])
Example #3
0
        def findHeightFromTime(sounding, t, approx_height):
            traj = self.bam.setup.trajectory

            found = False

            prev_err = 999

            TIME_TOL = 1e-3

            BOUNDS = 4000

            indxs = 100

            stat_pos = self.getStat()

            SWARM_SIZE = 100
            MAXITER = 25
            PHIP = 0.5
            PHIG = 0.5
            OMEGA = 0.5
            MINFUNC = 1e-3
            MINSTEP = 1e-2

            search_min = [approx_height - BOUNDS]
            search_max = [approx_height + BOUNDS]

            f_opt, x_opt = pso(heightErr, search_min, search_max, \
                                args=[t, traj, stat_pos, sounding], processes=multiprocessing.cpu_count()-1, particle_output=False, swarmsize=SWARM_SIZE,\
                             maxiter=MAXITER, phip=PHIP, phig=PHIG, \
                             debug=False, omega=OMEGA, minfunc=MINFUNC, minstep=MINSTEP)

            best_height = f_opt[0]

            print("Best Height = {:.5f} km".format(best_height / 1000))

            return best_height
Example #4
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)
Example #5
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]
Example #6
0
def cyscan(S, D, z_profile, trace=False, plot=False, particle_output=False, debug=False, wind=False, h_tol=330, v_tol=3000, \
        print_times=False):

    # phi, theta
    search_min = [0, 90]
    search_max = [360, 180]

    cyscan_inputs = [S, z_profile, D, wind, debug, h_tol, v_tol]

    if particle_output:
        f_opt, x_opt, f_particle, x_particle = pso(angleErr, search_min, search_max, \
            args=cyscan_inputs, processes=multiprocessing.cpu_count()-1, particle_output=True, swarmsize=SWARM_SIZE,\
                 maxiter=MAXITER, phip=PHIP, phig=PHIG, \
                 debug=False, omega=OMEGA, minfunc=MINFUNC, \
                 minstep=MINSTEP)

    else:
        f_opt, x_opt = pso(angleErr, search_min, search_max, \
            args=cyscan_inputs, processes=1, particle_output=False, swarmsize=SWARM_SIZE,\
                 maxiter=MAXITER, phip=PHIP, phig=PHIG, \
                 debug=False, omega=OMEGA, minfunc=MINFUNC, \
                 minstep=MINSTEP)

    if trace:
        r = anglescan(S, f_opt[0], f_opt[1], z_profile, trace=True)
        tr = np.array(r[1])

        if plot:

            fig = plt.figure()
            ax = Axes3D(fig)
            ax.scatter(S.lon, S.lat, S.elev, c='r', marker='*')
            ax.scatter(D.lon, D.lat, D.elev, c='g', marker='^')
            ax.scatter(tr[:, 0], tr[:, 1], tr[:, 2], c='b')
            ax.plot(tr[:, 0], tr[:, 1], tr[:, 2], c='k')

            # Plot all missed angles
            if particle_output:
                for particle in range(len(f_particle)):
                    r = anglescan(S,
                                  f_particle[particle][0],
                                  f_particle[particle][1],
                                  z_profile,
                                  trace=True)
                    tr = np.array(r[1])
                    ax.plot(tr[:, 0], tr[:, 1], tr[:, 2], alpha=0.3)

            plt.show()
    else:
        r = anglescan(S, f_opt[0], f_opt[1], z_profile, trace=False)

    if debug:
        print("Final Solution: {:.2f} {:.2f}".format(f_opt[0], f_opt[1]))
        print("Final Error:    {:.2f}".format(x_opt))
        if trace:
            phi_list = []
            the_list = []
            for i in range(len(tr[:, 2]) - 1):
                f_v = np.abs(tr[i + 1, 2] - tr[i, 2])
                f_h = np.sqrt((tr[i + 1, 0] - tr[i, 0])**2 +
                              (tr[i + 1, 1] - tr[i, 1])**2)
                f_x = tr[i + 1, 0] - tr[i, 0]
                f_y = tr[i + 1, 1] - tr[i, 1]
                tr_phi = np.degrees(np.arctan2(f_x, f_y))
                tr_theta = np.degrees(np.arctan2(f_v, f_h)) + 90
                phi_list.append(tr_phi)
                the_list.append(tr_theta)
                if i == 0:
                    # Note that the trace solution may not equal the actual solution if there are winds
                    print("Trace Solution: {:.2f} {:.2f}".format(
                        tr_phi, tr_theta))
            print("Mean Angles: {:.2f} {:.2f}".format(np.nanmean(phi_list),
                                                      np.nanmean(the_list)))

    if trace:
        x, y, z, T = r[0]
    else:
        x, y, z, T = r

    # if print_times:
    #     alltimes = []
    #     for particle in range(len(f_particle)):
    #         r = anglescan(S, f_particle[particle][0], f_particle[particle][1], z_profile, trace=False)
    #         x_t, y_t, z, T = r
    #         h_err = np.sqrt((D[0] - x)**2 + (D[1] - y)**2)
    #         v_err = np.sqrt(D[2] - z)
    #         if h_err <= h_tol and v_err <= v_tol:
    #             alltimes.append(T)

    #     if len(alltimes) == 0:
    #         print("No times within error!")
    #     else:
    #         print("Times:")
    #         print("Minimum Time: {:.4f} s".format(np.nanmin(alltimes)))
    #         print("Maximum Time: {:.4f} s".format(np.nanmax(alltimes)))
    #         print("Time of Minimum Error: {:.4f} s".format(T))

    h_err = np.sqrt((x - D[0])**2 + (y - D[1])**2)
    v_err = np.abs(z - D[2])

    if h_err <= h_tol and v_err <= v_tol:

        # Good Arrival
        R = [T, f_opt[0], f_opt[1], x_opt]

    else:
        R = [np.nan, np.nan, np.nan, x_opt]
        tr = [[np.nan, np.nan, np.nan, np.nan]]

    if trace:
        if particle_output:
            return R, tr, f_particle
        return R, tr
    else:
        if particle_output:
            return R, f_particle
        return R
Example #7
0
def estimateSeismicTrajectoryAzimuth(station_list, setup, sounding, p0=None, azim_range=None, elev_range=None, \
        v_fixed=None, allTimes=[], ax=None):
    """ Estimate the trajectory of a fireball from seismic/infrasound data by modelling the arrival times of
        the balistic shock at given stations.

    The method is implemented according to Pujol et al. (2005) and Ishihara et al. (2003).

    Arguments:
        station_list: [list] A list of stations and arrival times, each entry is a tuple of:
            (name, lat, lon, elev, arrival_time_jd), where latitude and longitude are in radians, the 
            zangle is in meters and Julian date of the arrival time.
        setup: [Object] Object containing all user-defined parameters
        sounding: [ndarray] atmospheric profile of the search area

    Keyword arguments:
        p0: [6 element ndarray] Initial parameters for trajectory estimation:
            p0[0]: [float] p0, north-south offset of the trajectory intersection with the ground (in km, +S).
            p0[1]: [float] y0, east-west offset of the trajectory intersection with the ground (in km, +E).
            p0[2]: [float] Time when the trajectory was at point (p0, y0), reference to the reference time 
                (seconds).
            p0[3]: [float] Velocity of the fireball (km/s).
            p0[4]: [float] Initial azimuth (+E of due north) of the fireball (radians).
            p0[5]: [float] Initial zenith angle of the fireball (radians).
        azim_range: [list of floats] (min, max) azimuths for the search, azimuths should be +E of due North
            in degrees. If the range of azmiuths traverses the 0/360 discontinuity, please use negative
            values for azimuths > 180 deg!
        elev_range: [list of floats] (min, max) zangles for the search, in degrees. The zangle is 
            measured from the horizon up.
        v_fixed: [float or None] value to restrict the velocity of the meteor. If set to None, there is no restriction

    """

    t0 = time.time()
    if ax is None:
        ax = plt.gca()

    # Extract all Julian dates
    jd_list = [entry[6] for entry in station_list]
    pick_time = [float(entry[7]) for entry in station_list]
    station_no = [int(float(entry[8])) for entry in station_list]

    # Calculate the arrival times as the time in seconds from the earliest JD

    jd_ref = min(jd_list)
    jd_list = np.array(jd_list)

    # Get the index of the first arrival station
    first_arrival_indx = np.argwhere(jd_list == jd_ref)[0][0]

    ref_pick_time = pick_time[first_arrival_indx]

    # Convert station coordiantes to local coordinates, with the station of the first arrival being the
    # origin of the coordinate system
    stat_coord_list = convertStationCoordinates(station_list,
                                                first_arrival_indx)

    ref_pos = Position(setup.lat_centre, setup.lon_centre, 0)

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

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

    print("Bounds:")
    print("x      : {:+8.2f} - {:+8.2f} km".format(setup.pos_min.x / 1000,
                                                   setup.pos_max.x / 1000))
    print("y      : {:+8.2f} - {:+8.2f} km".format(setup.pos_min.y / 1000,
                                                   setup.pos_max.y / 1000))
    print("t      : {:8.2f} - {:8.2f} s".format(setup.t_min, setup.t_max))
    print("v      : {:8.2f} - {:8.2f} km/s".format(setup.v_min / 1000,
                                                   setup.v_max / 1000))
    print("Azimuth: {:8.2f} - {:8.2f} deg fN".format(setup.azimuth_min.deg,
                                                     setup.azimuth_max.deg))
    print("Zenith : {:8.2f} - {:8.2f} deg".format(setup.zenith_min.deg,
                                                  setup.zenith_max.deg))

    # Extract lower and upper bounds
    lower_bounds = [bound[0] for bound in bounds]
    upper_bounds = [bound[1] for bound in bounds]

    class MiniResults():
        def __init__(self):
            self.x = None

    # Run PSO several times and choose the best solution
    solutions = []

    for i in range(setup.run_times):

        # Use PSO for minimization
        x, fopt, particles, errors = pso(timeResidualsAzimuth, lower_bounds, upper_bounds, args=(stat_coord_list, \
            pick_time, setup, sounding, v_fixed), maxiter=setup.maxiter, swarmsize=setup.swarmsize, \
            phip=setup.phip, phig=setup.phig, debug=False, omega=setup.omega, \
            processes=multiprocessing.cpu_count(), particle_output=True)
        #multiprocessing.cpu_count()
        solutions.append([x, fopt])
        print('Computational  best estimation', fopt)

        print(solutions)

    ### TESTING WITHOUT PERTS
    if setup.perturb and False:

        #allTimes = [perturb_no, station_no, ball/frag, frag_no]
        try:
            perturb_times = allTimes.shape[0]

            p_arrival_times = allTimes[:, station_no, 0,
                                       0] - float(ref_pick_time)

            x_perturb = [0] * perturb_times
            fopt_perturb = [0] * perturb_times

            for i in range(1, perturb_times):

                #remove nan
                #p_arrival_times[i] = [j for j in p_arrival_times[i] if j != j]

                # Use PSO for minimization, with perturbed arrival times
                x_perturb[i], fopt_perturb[i] = pso(timeResidualsAzimuth, lower_bounds, upper_bounds, args=(stat_coord_list, \
                    p_arrival_times[i], setup, sounding, v_fixed), maxiter=setup.maxiter, swarmsize=setup.swarmsize, \
                    phip=setup.phip, phig=setup.phig, debug=False, omega=setup.omega, processes=multiprocessing.cpu_count())

                print(x_perturb[i], fopt_perturb[i])
                print('Perturbation', i, 'best estimation', fopt_perturb[i])
        except AttributeError:
            x_perturb, fopt_perturb = [], []
            setup.perturb = False
    else:
        x_perturb, fopt_perturb = [], []

    # Choose the solution with the smallest residuals
    fopt_array = np.array([fopt for x_val, fopt_val in solutions])
    best_indx = np.argmin(fopt_array)

    x, fopt = solutions[best_indx]

    res = MiniResults()
    res.x = x

    # Extract estimated parameters
    x0, y0 = res.x[:2]
    t0 = res.x[2]
    v_est = res.x[3]
    azim, zangle = res.x[4:]

    ref_pos = Position(setup.lat_centre, setup.lon_centre, 0)

    lat_fin, lon_fin, _ = loc2Geo(ref_pos.lat, ref_pos.lon, ref_pos.elev,
                                  [x0, y0, 0])

    # Print the time residuals per every station
    timeResidualsAzimuth(res.x,
                         stat_coord_list,
                         pick_time,
                         setup,
                         sounding,
                         v_fixed=v_fixed,
                         print_residuals=True)

    # Plot the stations and the estimated trajectory
    residuals = plotStationsAndTrajectory(
        station_list, [x0, y0, t0, v_est / 1000, azim, zangle],
        setup,
        sounding,
        x_perturb=x_perturb,
        ax=ax)

    final_pos = Position(lat_fin, lon_fin, 0)
    results = [final_pos, ref_pos, t0, v_est, azim, zangle, residuals]

    results = []
    print("Results:")
    print("Trajectory (Nominal)           | Lat {:+10.4f} N Lon {:+10.4f} E t {:5.2f} s v {:7.4f} km/s Azimuth {:6.2f} deg fN Zenith {:5.2f} Error {:10.4f}"\
                        .format(lat_fin, lon_fin, t0, v_est/1000, azim, zangle, fopt))
    results.append([lat_fin, lon_fin, t0, v_est / 1000, azim, zangle, fopt])
    # for i in range(perturb_times):
    #     lat_fin, lon_fin, _ = loc2Geo(ref_pos.lat, ref_pos.lon, ref_pos.elev, [x_perturb[i][0], x_perturb[i][1], 0])
    #     print("Trajectory (Perturbation {:4d}) | Lat {:+10.4f} N Lon {:+10.4f} E t {:5.2f} s v {:7.4f} km/s Azimuth {:6.2f} deg fN Zenith {:5.2f} Error {:10.4f}"\
    #                     .format(i, lat_fin, lon_fin, x_perturb[i][2], x_perturb[i][3]/1000,\
    #                      x_perturb[i][4], x_perturb[i][5], fopt_perturb[i]))
    #     results.append([lat_fin, lon_fin, x_perturb[i][2], x_perturb[i][3]/1000, x_perturb[i][4], x_perturb[i][5], fopt_perturb[i]])

    particles = np.array(particles)
    errors = np.array(particles)

    return particles, errors, results
Example #8
0
def periodSearch(p, gem_inputs, paths=False):
    ''' Uses PSO to find the Relaxation radius that returns the desired period through the Geminus program
    '''

    Ro = 10.0

    target_period = p

    period_ws = 0

    tol = 1e-3

    tau = []

    search_min = [tol]
    search_max = [100]

    Ro, f_opt = pso(overpressureErr, search_min, search_max, \
        args=gem_inputs + [p, 'period', 'ws'], swarmsize=SWARM_SIZE, maxiter=MAX_ITER, processes=1, minfunc=tol, minstep=1e-3)

    Ro = Ro[0]
    print("Period Weak Shock: {:.2f} s Ro = {:.3f} m".format(p, Ro))

    Ro_ws = Ro

    Ro = 10.0
    period_lin = 0

    Ro, f_opt = pso(overpressureErr, search_min, search_max, \
        args=gem_inputs + [p, 'period', 'lin'], swarmsize=SWARM_SIZE, maxiter=MAX_ITER, processes=1, minfunc=tol, minstep=1e-3)
    Ro = Ro[0]
    print("Period Linear: {:.2f} s Ro = {:.3f} m".format(p, Ro))
    Ro_lin = Ro

    if paths:
        source_list, stat, v, theta, dphi, sounding_pres, sw, wind, dopplershift = gem_inputs
        tau, tauws, Z, sR, inc, talt, dpws, dp, it = overpressureihmod_Ro(
            source_list,
            stat,
            Ro_ws,
            v,
            theta,
            dphi,
            sounding_pres,
            sw,
            wind=wind,
            dopplershift=dopplershift)
        weak_path = tau[:it] + tauws[it:]
        tau, tauws, Z, sR, inc, talt, dpws, dp, it = overpressureihmod_Ro(
            source_list,
            stat,
            Ro_lin,
            v,
            theta,
            dphi,
            sounding_pres,
            sw,
            wind=wind,
            dopplershift=dopplershift)
        lin_path = tau

        return Ro_ws, Ro_lin, weak_path, lin_path, tau, Z, it

    return Ro_ws, Ro_lin
Example #9
0
def findScaledDistance(x, func):
    # Use magnitude for faster search
    a, b = pso(func, [-2], [7], args=x, maxiter=1000, swarmsize=1000)

    scaled_distance = 10**a[0]
    return scaled_distance