Exemple #1
0
def finalanglecheck(bam, traj, D, angle):

    points = traj.trajInterp2(div=100)

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

    azimuths = []

    for pt in points:

        S = Position(pt[0], pt[1], pt[2])

        S.pos_loc(ref_pos)
        D.pos_loc(ref_pos)

        sounding, _ = bam.atmos.getSounding(lat=[S.lat, D.lat],
                                            lon=[S.lon, D.lon],
                                            heights=[S.elev, D.elev])

        az = cyscan(S.xyz, D.xyz, sounding)

        azimuths.append(az % 180)

    best_az_indx = np.nanargmin(np.abs(azimuths - angle))

    err = np.abs(azimuths[best_az_indx] - angle)

    return points[best_az_indx], err
Exemple #2
0
    def makeStaff(self, stn, ts, time_err, doc):

        # Generate pointes along trajecotry
        traj = self.bam.setup.trajectory
        points = traj.trajInterp2(div=100)

        D = stn.metadata.position
        ref_pos = Position(self.bam.setup.lat_centre,
                           self.bam.setup.lon_centre, 0)
        D.pos_loc(ref_pos)

        times = []
        heights = []

        for pt in points:
            S = Position(pt[0], pt[1], pt[2])
            S.pos_loc(ref_pos)
            sounding, perts = self.bam.atmos.getSounding(
                lat=[S.lat, D.lat],
                lon=[S.lon, D.lon],
                heights=[S.elev, D.elev])

            f_time, _, _, _ = cyscan(S.xyz, D.xyz, sounding, wind=self.prefs.wind_en, n_theta=self.prefs.pso_theta, n_phi=self.prefs.pso_phi, \
                                    h_tol=self.prefs.pso_min_ang, v_tol=self.prefs.pso_min_dist)
            times.append(f_time + pt[3])
            heights.append(pt[2] / 1000)

        plt.scatter(heights, times)

        X = np.linspace(17, 50)

        for tt in range(len(ts)):
            plt.fill_between(X,
                             ts[tt] - time_err[tt][0],
                             y2=ts[tt] + time_err[tt][1])
            plt.annotate('F{:}'.format(tt + 1), (18, ts[tt]))
            plt.axhline(y=ts[tt], color="black", linestyle="--")

        pic_file = os.path.join(self.prefs.workdir,
                                self.bam.setup.fireball_name, 'staff.png')
        plt.savefig(pic_file)
        doc.add_picture(pic_file)
        os.remove(pic_file)
        plt.clf()
Exemple #3
0
def calcAllTimes(bam, prefs):
    ''' Calculates all arrivals to all stations
    '''

    velocities = [11]
    zes = [85]
    az = 354.67
    t = 0
    pos_i = Position(48.1724466606, 13.0926245672, 50000)

    for vvv in range(len(velocities)):
        for z in range(len(zes)):
            points = []
            file_name = 'C:\\Users\\lmcfd\\Desktop\\Theoretical\\v{:}_ze{:}.csv'.format(
                str(velocities[vvv]), str(zes[z]))
            with open(file_name, 'w+') as f:
                new_traj = Trajectory(t,
                                      velocities[vvv] * 1000,
                                      zenith=Angle(zes[z]),
                                      azimuth=Angle(az),
                                      pos_i=pos_i)
                points = new_traj.trajInterp2(div=150,\
                                      min_p=17000,\
                                      max_p=50000)

                az_temp = np.radians(az)
                ze_temp = np.radians(zes[z])

                u = np.array([
                    np.sin(az_temp) * np.sin(ze_temp),
                    np.cos(az_temp) * np.sin(ze_temp), -np.cos(ze_temp)
                ])

                print(u)

                # Generate points

                ####################
                # Times Calculation
                ####################

                ref_pos = new_traj.pos_f
                no_of_frags = len(points)

                f.write(
                    'Net, Code, Nom time, min time, max time, time range, mean, length, std, nom height, min height, max height, height range, mean, length, std\n'
                )

                for ii, stn in enumerate(bam.stn_list):
                    print("Station {:}/{:} ".format(ii + 1, len(bam.stn_list)))

                    stn.times = Times()

                    stn.times.ballistic = []
                    stn.times.fragmentation = []
                    stn.metadata.position.pos_loc(ref_pos)

                    ################
                    # Fragmentation
                    ################

                    if prefs.frag_en:
                        for i, frag in enumerate(points):
                            offset = frag[3]

                            a = []
                            supra = Position(frag[0], frag[1], frag[2])

                            # convert to local coordinates based off of the ref_pos
                            supra.pos_loc(ref_pos)

                            lats = [supra.lat, stn.metadata.position.lat]
                            lons = [supra.lon, stn.metadata.position.lon]
                            heights = [supra.elev, stn.metadata.position.elev]

                            sounding, perturbations = bam.atmos.getSounding(
                                lats, lons, heights)

                            # Travel time of the fragmentation wave
                            f_time, frag_azimuth, frag_takeoff, frag_err = cyscan(np.array([supra.x, supra.y, supra.z]), np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]), sounding, \
                                wind=prefs.wind_en, n_theta=prefs.pso_theta, n_phi=prefs.pso_phi,
                                h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)

                            results = []

                            for pert in perturbations:

                                temp = cyscan(np.array([supra.x, supra.y, supra.z]), np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]), pert, \
                                    wind=prefs.wind_en, n_theta=prefs.pso_theta, n_phi=prefs.pso_phi,
                                    h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)

                                results.append(temp)

                            a.append(
                                [f_time, frag_azimuth, frag_takeoff, frag_err])
                            a.append(results)
                            stn.times.fragmentation.append(a)

                    ############
                    # Ballistic
                    ############
                    if prefs.ballistic_en:
                        best_indx = 0
                        az = 0
                        tf = 0
                        v = []
                        h_es = []
                        t_es = []
                        angle_off = []
                        X = []
                        for i in range(len(points)):
                            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(points[i][2])
                        angle_off = np.array(angle_off)
                        try:
                            best_indx = np.nanargmin(abs(angle_off - 90))

                            if not abs(angle_off[best_indx] - 90) <= 25:
                                best_indx = None
                                raise ValueError

                        except ValueError:
                            best_indx = None

                        if best_indx is not None:
                            h_es.append(points[best_indx][2])
                            t_es.append(
                                stn.times.fragmentation[best_indx][0][0])

                        for pp in range(len(perturbations)):
                            X = []
                            angle_off = []
                            for i in range(len(points)):
                                az = stn.times.fragmentation[i][1][pp][1]
                                tf = stn.times.fragmentation[i][1][pp][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(points[i][2])
                            angle_off = np.array(angle_off)
                            try:
                                best_indx = np.nanargmin(abs(angle_off - 90))

                                if not abs(angle_off[best_indx] - 90) <= 25:
                                    best_indx = None
                                    raise ValueError

                            except ValueError:
                                best_indx = None

                            if best_indx is not None:
                                h_es.append(points[best_indx][2])
                                t_es.append(stn.times.fragmentation[best_indx]
                                            [1][pp][0])
                        # supra = Position(points[best_indx][0], points[best_indx][1], points[best_indx][2])
                        # supra.pos_loc(ref_pos)
                        # # Travel time of the fragmentation wave
                        # f_time, frag_azimuth, frag_takeoff, frag_err = cyscan(np.array([supra.x, supra.y, supra.z]), np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]), sounding, \
                        #     wind=prefs.wind_en, n_theta=prefs.pso_theta, n_phi=prefs.pso_phi,
                        #     h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)

                        # speed = bam.setup.trajectory.v
                        # distance = supra.pos_distance(bam.setup.trajectory.pos_f)
                        # timing = distance/speed

                        # results = []
                        # print('ballistic', f_time)
                        # for pert in perturbations:
                        #     e, b, c, d = cyscan(np.array([supra.x, supra.y, supra.z]), np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]), pert, \
                        #         wind=prefs.wind_en, n_theta=prefs.pso_theta, n_phi=prefs.pso_phi,
                        #         h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)
                        #     e += timing
                        #     results.append(np.array([e, b, c, d]))

                        # a.append([f_time + timing, frag_azimuth, frag_takeoff, frag_err])
                        # a.append(results)
                        # stn.times.ballistic.append(a)
                    # print csv

                    if len(t_es) > 0 and len(h_es) > 0:
                        f.write('{:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:},\n'.format(stn.metadata.network,\
                                stn.metadata.code, \
                                t_es[0], np.nanmin(t_es), np.nanmax(t_es), np.nanmax(t_es)-np.nanmin(t_es), np.nanmean(t_es), len(t_es), np.std(t_es),\
                                h_es[0], np.nanmin(h_es), np.nanmax(h_es), np.nanmax(h_es)-np.nanmin(h_es), np.nanmean(h_es), len(h_es), np.std(h_es)))
                    else:
                        f.write('{:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:}, {:},\n'.format(stn.metadata.network,\
                                stn.metadata.code, \
                                np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan,\
                                np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan))

                # import winsound
                # duration = 1000  # milliseconds
                # freq = 440  # Hz
                # winsound.Beep(freq, duration)
                # winsound.Beep(freq*2, duration)

    exit()

    return None
Exemple #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)
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
Exemple #6
0
def calcAllTimes(obj, bam, prefs):
    ''' Calculates all arrivals to all stations
    '''
    time_step = -999
    #######################################
    # Check if times need to be calculated
    #######################################

    if checkSkip(bam, prefs):
        if prefs.debug:
            printStatus(bam, prefs)
        return bam.stn_list

    qm = QMessageBox()
    ret = qm.question(obj, '', "No arrival times detected, calculate?",
                      qm.Yes | qm.No)

    if ret == qm.No:
        return bam.stn_list

    ####################
    # Times Calculation
    ####################

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

    if not hasattr(bam.setup, "fragmentation_point"):
        no_of_frags = 0
    else:
        no_of_frags = len(bam.setup.fragmentation_point)

    total_steps = 1 + (
        prefs.frag_en * no_of_frags *
        (1 + prefs.pert_en * prefs.pert_num) + prefs.ballistic_en *
        (1 + prefs.pert_en * prefs.pert_num)) * len(bam.stn_list)

    step = 0

    for ii, stn in enumerate(bam.stn_list):

        if not hasattr(stn, 'times'):
            stn.times = Times()

        stn.times.ballistic = []
        stn.times.fragmentation = []

        ################
        # Fragmentation
        ################

        if prefs.frag_en:

            for i, frag in enumerate(bam.setup.fragmentation_point):

                if i == 0 and ii == 0:
                    t1 = time.time()
                elif i == 1 and ii == 0:
                    time_step = time.time() - t1

                step += 1
                time_hour = time_step * (total_steps - step) // 3600
                time_minute = time_step * (total_steps - step) % 3600 // 60
                time_second = time_minute * (total_steps - step) % 60

                time_string = "{:02d}:{:02d}:{:02d}".format(
                    int(time_hour), int(time_minute), int(time_second))

                loadingBar(
                    'Calculating Station Times - ETA {:}: '.format(
                        time_string), step, total_steps)

                offset = frag.time

                a = []

                supra = frag.position

                # convert to local coordinates based off of the ref_pos
                stn.metadata.position.pos_loc(supra)
                supra.pos_loc(supra)

                lats = [supra.lat, stn.metadata.position.lat]
                lons = [supra.lon, stn.metadata.position.lon]
                heights = [supra.elev, stn.metadata.position.elev]

                sounding, perturbations = bam.atmos.getSounding(
                    lats,
                    lons,
                    heights,
                    ref_time=bam.setup.fireball_datetime,
                    spline=1000)

                # Travel time of the fragmentation wave
                f_time, frag_azimuth, frag_takeoff, frag_err = cyscan(np.array([supra.x, supra.y, supra.z]), np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]), sounding, \
                    wind=prefs.wind_en, h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)

                results = []

                if perturbations is not None:
                    for pert in perturbations:
                        step += 1
                        loadingBar('Calculating Station Times: ', step,
                                   total_steps)
                        temp = cyscan(np.array([supra.x, supra.y, supra.z]), \
                            np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]), \
                            sounding, wind=prefs.wind_en, h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)
                        temp[0] += offset
                        results.append(temp)

                a.append(
                    [f_time + offset, frag_azimuth, frag_takeoff, frag_err])
                a.append(results)
                stn.times.fragmentation.append(a)

        ############
        # Ballistic
        ############

        if prefs.ballistic_en and bam.setup.trajectory is not None:

            step += 1
            loadingBar('Calculating Station Times: ', step, total_steps)

            a = []
            # define line bottom boundary

            max_height = bam.setup.trajectory.pos_i.elev
            min_height = bam.setup.trajectory.pos_f.elev

            points = bam.setup.trajectory.trajInterp2(div=1,
                                                      min_p=min_height,
                                                      max_p=max_height)

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

            angle_off = []
            X = []
            for pt in points:

                S = Position(pt[0], pt[1], pt[2])

                lats = [S.lat, stn.metadata.position.lat]
                lons = [S.lon, stn.metadata.position.lon]
                heights = [S.elev, stn.metadata.position.elev]

                S.pos_loc(S)
                stn.metadata.position.pos_loc(S)

                sounding, perturbations = bam.atmos.getSounding(
                    lats, lons, heights, ref_time=bam.setup.fireball_datetime)

                # Travel time of the fragmentation wave
                _, az, tf, _ = cyscan(np.array([S.x, S.y, S.z]), \
                    np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]), \
                    sounding, wind=prefs.wind_en, h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)

                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(S.elev)
            angle_off = np.array(angle_off)
            try:
                best_indx = np.nanargmin(abs(angle_off - 90))

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

            supra = points[best_indx]
            ref_time = supra[3]
            supra = Position(supra[0], supra[1], supra[2])
            supra.pos_loc(supra)

            lats = [supra.lat, stn.metadata.position.lat]
            lons = [supra.lon, stn.metadata.position.lon]
            heights = [supra.elev, stn.metadata.position.elev]

            sounding, perturbations = bam.atmos.getSounding(
                lats, lons, heights, ref_time=bam.setup.fireball_datetime)
            # Travel time of the fragmentation wave
            f_time, frag_azimuth, frag_takeoff, frag_err = cyscan(np.array([supra.x, supra.y, supra.z]), \
                np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]),\
                sounding, wind=prefs.wind_en, h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)

            speed = bam.setup.trajectory.v
            distance = supra.pos_distance(bam.setup.trajectory.pos_f)
            timing = distance / speed

            results = []
            if perturbations is not None:
                for pert in perturbations:
                    step += 1
                    loadingBar('Calculating Station Times: ', step,
                               total_steps)
                    e, b, c, d = cyscan(np.array([supra.x, supra.y, supra.z]), \
                        np.array([stn.metadata.position.x, stn.metadata.position.y, stn.metadata.position.z]),\
                        sounding, wind=prefs.wind_en, h_tol=prefs.pso_min_ang, v_tol=prefs.pso_min_dist)
                    e += timing
                    results.append(np.array([e, b, c, d]))

            a.append([ref_time + f_time, frag_azimuth, frag_takeoff, frag_err])
            a.append(results)

            stn.times.ballistic.append(a)

    step += 1
    loadingBar('Calculating Station Times: ', step, total_steps)

    if prefs.debug:
        printStatus(bam, prefs)

    return bam.stn_list
Exemple #7
0
    def integrate(self, height, D_ANGLE=1.5, tf=1, az=1):
        ref_pos = Position(self.setup.lat_centre, self.setup.lon_centre, 0)
        try:
            point = self.setup.trajectory.findGeo(height)
        except AttributeError:
            print("STATUS: No trajectory given, assuming lat/lon center")
            point = Position(self.setup.lat_centre, self.setup.lon_centre,
                             height)
        point.pos_loc(ref_pos)

        stn = self.stn_list[self.current_station]
        stn.metadata.position.pos_loc(ref_pos)

        lats = [point.lat, stn.metadata.position.lat]
        lons = [point.lon, stn.metadata.position.lon]
        elevs = [point.elev, stn.metadata.position.elev]

        # make the spline lower to save time here

        sounding, perturbations = self.bam.atmos.getSounding(
            lats,
            lons,
            elevs,
            spline=N_LAYERS,
            ref_time=self.setup.fireball_datetime)

        trans = []
        ints = []
        ts = []
        ps = []
        rfs = []

        if perturbations is None:
            ptb_len = 1
        else:
            ptb_len = len(perturbations) + 1

        for ptb_n in range(ptb_len):

            # Temporary adjustment to remove randomness from perts

            if ptb_n == 0:
                zProfile = sounding
            else:
                zProfile = perturbations[ptb_n - 1]

            S = np.array([point.x, point.y, point.z])
            D = np.array([
                stn.metadata.position.x, stn.metadata.position.y,
                stn.metadata.position.z
            ])

            _, az_n, tf_n, _ = cyscan(S, D, zProfile, wind=True,\
                h_tol=30, v_tol=30)

            self.T_d = tryFloat(self.freq_edits.text())

            self.v = 1 / self.T_d

            f, g, T, P, path_length, pdr, reed_attenuation = intscan(S,
                                                                     az_n,
                                                                     tf_n,
                                                                     zProfile,
                                                                     self.v,
                                                                     wind=True)

            self.reed_attenuation = reed_attenuation

            rf = refractiveFactor(point,
                                  stn.metadata.position,
                                  zProfile,
                                  D_ANGLE=D_ANGLE)
            trans.append(f)
            ints.append(g)
            ts.append(T)
            ps = P

            rfs.append(rf)

        return trans, ints, ts, ps, rfs, path_length, pdr