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
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()
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
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
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
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