def cracked_concrete_plots(c: Config): """Contour plots of cracked concrete scenarios.""" response_type = ResponseType.YTranslation # 10 x 10 grid of points on the bridge deck where to record fem. points = [ Point(x=x, y=0, z=z) for x, z in itertools.product( np.linspace(c.bridge.x_min, c.bridge.x_max, 10), np.linspace(c.bridge.z_min, c.bridge.z_max, 10), ) ] # Create empty traffic array and collect fem. response_array = responses_to_traffic_array( c=c, traffic_array=load_normal_traffic_array(c)[0], response_type=response_type, bridge_scenario=cracked_scenario, points=points, sim_runner=OSRunner, ) for t in range(len(response_array)): top_view_bridge(c.bridge, abutments=True, piers=True) responses = Responses.from_responses( response_type=response_type, responses=[(response_array[t][p], point) for p, point in enumerate(points)], ) plot_contour_deck(c=c, responses=responses, center_norm=True) plt.title("Cracked Concrete") plt.savefig(c.get_image_path("cracked-scenario", f"cracked-time-{t}")) plt.close()
def pairwise_cluster(c: Config, load: bool): """Cluster pairwise maps from healthy and damaged scenarios.""" features_path = c.get_data_path("features", "pairwise-cluster", bridge=False) if not load: normal_traffic_array, _ = load_normal_traffic_array(c=c, mins=24) normal_traffic_array = normal_traffic_array[ int(len(normal_traffic_array) / 24) : ] response_type = ResponseType.YTranslation grid_points = [ Point(x=x, y=0, z=-9.65) for x, _ in itertools.product( np.linspace(c.bridge.x_min, c.bridge.x_max, 50), # np.linspace(c.bridge.x_min, c.bridge.x_max, 4), [1], ) ] # Collect a list of features per scenarios scenario. features = [] for damage_scenario in healthy_and_cracked_scenarios[1:]: damage_c = damage_scenario.use(c) responses = responses_to_traffic_array( c=damage_c, traffic_array=normal_traffic_array, response_type=response_type, bridge_scenario=damage_scenario, points=grid_points, sim_runner=OSRunner, ).T ks_values = [] for p0_i, point0 in enumerate(grid_points): print_i(f"Point {p0_i + 1} / {len(grid_points)}", end="\r") ks_values.append([]) for p1_i, point1 in enumerate(grid_points): ks = ks_no_outliers(responses[p0_i], responses[p1_i]) ks_values[-1].append(ks) features.append((ks_values, damage_scenario.name)) # Save features to disk. features = np.array(features) np.save(features_path, features) features = np.load(features_path) # Reduce each pairwise map to a sum per sensor. for f_i, (feature, feature_name) in enumerate(features): features[f_i] = ([sum(sensor) for sensor in feature], feature_name) features[f_i] = ([sum(sensor) for sensor in features[f_i]], feature_name) # Cluster each pairwise map. from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=2) kmeans.fit(features)
def traffic_response_plots(c: Config, times: int = 3): """Response to normal traffic per scenarios scenario at multiple time steps.""" response_type = ResponseType.YTranslation # 10 x 10 grid of points on the bridge deck where to record fem. points = [ Point(x=x, y=0, z=z) for x, z in itertools.product( np.linspace(c.bridge.x_min, c.bridge.x_max, 10), np.linspace(c.bridge.z_min, c.bridge.z_max, 10), ) ] # for damage_scenario in all_scenarios(c): for damage_scenario in [unit_temp_scenario]: response_array = responses_to_traffic_array( c=c, traffic_array=load_normal_traffic_array(c, mins=1)[0], response_type=response_type, bridge_scenario=damage_scenario, points=points, sim_runner=OSRunner, ) print(response_array.shape) mean_response_array = np.mean(response_array, axis=0).T print(mean_response_array.shape) print(mean_response_array.shape) for t in range(times): time_index = -1 + abs(t) top_view_bridge(c.bridge, abutments=True, piers=True) responses = Responses.from_responses( response_type=response_type, responses=[(response_array[time_index][p], point) for p, point in enumerate(points)], ) plot_contour_deck(c=c, responses=responses, center_norm=True, levels=100) plt.title(damage_scenario.name) plt.savefig( c.get_image_path( "contour-traffic-response", f"{damage_scenario.name}-time={time_index}", )) plt.close()
def oneclass(c: Config): normal_traffic_array, traffic_scenario = load_normal_traffic_array(c) bridge_scenarios = [HealthyScenario()] + each_pier_scenarios(c) response_type = ResponseType.YTranslation points = [ Point(x=x, y=0, z=z) for x, z in itertools.product( np.linspace(c.bridge.x_min, c.bridge.x_max / 2, 20), np.linspace(c.bridge.z_min, c.bridge.z_max / 2, 3), ) ] results = [] for b, bridge_scenario in enumerate(bridge_scenarios): print_i(f"One class: bridge scenario {bridge_scenario.name}") responses = responses_to_traffic_array( c=c, traffic_array=normal_traffic_array, response_type=response_type, bridge_scenario=bridge_scenario, points=points, fem_runner=OSRunner(c), ).T print(len(normal_traffic_array)) print(responses.shape) # Fit on the healthy scenario. if b == 0: assert len(responses) == len(points) clfs = [] for r, rs in enumerate(responses): print_i(f"Training classifier {r} / {len(responses)}") clfs.append(OneClassSVM().fit(rs.reshape(-1, 1))) scenario_results = [] for p, _ in enumerate(points): print_i(f"Predicting points {p} / {len(points)}") prediction = clfs[p].predict(responses[p].reshape(-1, 1)) print(prediction) print(len(prediction[prediction < 0])) print(len(prediction[prediction > 0]))
def gradient_pier_displacement_plot( c: Config, pier_disp: PierSettlementScenario, response_type: ResponseType, title: str, ): """Contour plot of piers displaced in an increasing gradient.""" # 10 x 10 grid of points on the bridge deck where to record fem. points = [ Point(x=x, y=0, z=z) for x, z in itertools.product( np.linspace(c.bridge.x_min, c.bridge.x_max, 10), np.linspace(c.bridge.z_min, c.bridge.z_max, 10), ) ] # Create empty traffic array and collect fem. response_array = responses_to_traffic_array( c=c, traffic_array=np.zeros( (1, len(c.bridge.wheel_tracks(c)) * c.il_num_loads)), response_type=response_type, bridge_scenario=pier_disp, points=points, fem_runner=OSRunner(c), ) top_view_bridge(c.bridge, abutments=True, piers=True) responses = Responses.from_responses( response_type=response_type, responses=[(response_array[0][p], point) for p, point in enumerate(points)], ) plot_contour_deck(c=c, responses=responses, center_norm=True) plt.title(title) plt.savefig( c.get_image_path("pier-scenarios", f"pier-displacement-{safe_str(title)}")) plt.close()
def pairwise_sensors(c: Config, dist_measure=ks_no_outliers): """Compare distribution of pairs of sensors under HealthyScenario.""" normal_traffic_array, traffic_scenario = load_normal_traffic_array(c) response_type = ResponseType.YTranslation points = [ Point(x=x, y=0, z=z) for x, z in itertools.product( np.linspace(c.bridge.x_min, c.bridge.x_max, 50), np.linspace(c.bridge.z_min, c.bridge.z_max, 4), ) ] bridge_scenario = HealthyScenario() responses = responses_to_traffic_array( c=c, traffic_array=normal_traffic_array, response_type=response_type, bridge_scenario=bridge_scenario, points=points, sim_runner=OSRunner, ).T assert len(responses) == len(points) ks_values_healthy = [] for p0, point0 in enumerate(points): print_i(f"Point {p0 + 1} / {len(points)}") ks_values_healthy.append([]) for p1, point1 in enumerate(points): ks = dist_measure(responses[p0], responses[p1]) ks_values_healthy[-1].append(ks) plt.landscape() plt.imshow(ks_values_healthy) plt.savefig(c.get_image_path("joint-clustering", "healthy-bridge")) plt.close() bridge_scenario = each_pier_scenarios(c)[0] responses = responses_to_traffic_array( c=c, traffic_array=normal_traffic_array, response_type=response_type, bridge_scenario=bridge_scenario, points=points, sim_runner=OSRunner, ).T assert len(responses) == len(points) ks_values_damage = [] for p0, point0 in enumerate(points): print_i(f"Point {p0 + 1} / {len(points)}") ks_values_damage.append([]) for p1, point1 in enumerate(points): ks = dist_measure(responses[p0], responses[p1]) ks_values_damage[-1].append(ks) plt.imshow(ks_values_damage) plt.savefig(c.get_image_path("joint-clustering", "scenarios-bridge")) plt.close() ks_values_comp = [] for p0, point0 in enumerate(points): ks_values_comp.append([]) for p1, point1 in enumerate(points): comp = abs(ks_values_healthy[p0][p1] - ks_values_damage[p0][p1]) ks_values_comp[-1].append(comp) plt.landscape() plt.imshow(ks_values_comp) plt.savefig(c.get_image_path("joint-clustering", "scenarios-bridge-comp")) plt.close() responses = Responses.from_responses( response_type=response_type, responses=[(sum(ks_values_comp[p]), point) for p, point in enumerate(points)], ) top_view_bridge(c.bridge, abutments=True, piers=True) plot_contour_deck(c=c, responses=responses) plt.savefig(c.get_image_path("joint-clustering", "scenarios-bridge-comp-contour")) plt.close()
def events(c: Config, x: float, z: float): """Plot events due to normal traffic.""" point = Point(x=x, y=0, z=z) # 10 seconds of 'normal' traffic. max_time = 10 traffic_scenario = normal_traffic(c=c, lam=5, min_d=2) # Create the 'TrafficSequence' and 'TrafficArray'. traffic_sequence = traffic_scenario.traffic_sequence( bridge=c.bridge, max_time=max_time ) traffic_array = to_traffic_array( c=c, traffic_sequence=traffic_sequence, max_time=max_time ) # Find when the simulation has warmed up, and when 'TrafficArray' begins. warmed_up_at = traffic_sequence[0][0].time_left_bridge(c.bridge) traffic_array_starts = (int(warmed_up_at / c.sensor_hz) + 1) * c.sensor_hz print(f"warmed up at = {warmed_up_at}") print(f"traffic_array_starts = {traffic_array_starts}") traffic_array_ends = traffic_array_starts + (len(traffic_array) * c.sensor_hz) print(f"traffic_array_ends = {traffic_array_ends}") point_lane_ind = c.bridge.closest_lane(z) vehicles = list(set(ts[0] for ts in traffic_sequence)) print(len(vehicles)) print(vehicles[0]) vehicles = sorted( set(ts[0] for ts in traffic_sequence if ts[0].lane == point_lane_ind), key=lambda v: -v.init_x_frac, ) print(len(vehicles)) print(vehicles[0]) event_indices = [] vehicle_times = [v.time_at(x=x - 2, bridge=c.bridge) for v in vehicles] for v, t in zip(vehicles, vehicle_times): print(f"Vehicle {v.init_x_frac} {v.mps} at time {t}") start_time = int(t / c.sensor_hz) * c.sensor_hz print(f"start_time = {start_time}") ta_start_time = np.around(start_time - traffic_array_starts, 8) print(f"ta start time = {ta_start_time}") ta_start_index = int(ta_start_time / c.sensor_hz) print(f"ta start index = {ta_start_index}") ta_end_index = ta_start_index + int(c.event_time_s / c.sensor_hz) print(f"ta end index = {ta_end_index}") if ta_start_index >= 0 and ta_end_index < len(traffic_array): event_indices.append((ta_start_index, ta_end_index)) print(event_indices) responses = ( responses_to_traffic_array( c=c, traffic_array=traffic_array, response_type=ResponseType.YTranslation, damage_scenario=healthy_scenario, points=[point], sim_runner=OSRunner(c), ) * 1000 ) # fem = add_displa_noise(fem) print(responses.shape) plt.portrait() for event_ind, (event_start, event_end) in enumerate(event_indices): plt.subplot(len(event_indices), 1, event_ind + 1) plt.plot(responses[event_start : event_end + 1]) plt.tight_layout() plt.savefig(c.get_image_path("classify/events", "events.pdf")) plt.close()
def crack_time_series( c: Config, traffic_array, traffic_array_mins: float, sensor: Point, crack_frac: float, damage, temps: List[float], solar: List[float], ): """Time series of sensor fem, vertical translation and strain XXB. Returns a NumPy array of dimensions (2 x len(traffic_array)). Args: c: Config, global configuration object. traffic_array: TrafficArray, traffic flowing over the bridge. traffic_array_mins: float, minutes of the the traffic flow. sensor: Point, point at which to collect fem. crack_frac: float, fraction of time series where crack occurs. damage: DamageScenario, scenarios that occurs at crack_frac. temps: List[float], list of air temperature, per temperature minute. solar: List[float], list of solar radiance, per temperature minute. """ assert 0 <= crack_frac <= 1 response_types = [ResponseType.YTranslation, ResponseType.Strain] half_i = int(len(traffic_array) * crack_frac) traffic_array_0, traffic_array_1 = traffic_array[:half_i], traffic_array[ half_i:] assert len(traffic_array_0) + len(traffic_array_1) == len(traffic_array) half_t = int(len(temps) * crack_frac) assert len(temps) == len(solar) # Get the effect of temperature for both response types and damages. # In each case we have the full days worth of temperature fem. temp_effect = [] for response_type in response_types: temp_effect_damages = [] for di, ds in enumerate([HealthyDamage(), damage]): bots_tops, new_temp_effect = temperature.effect( c=ds.use(c)[0], response_type=response_type, points=[sensor], # One hour temperature data per minute of traffic data. len_per_hour=int(len(traffic_array) / traffic_array_mins) if di == 0 else None, temps=temps if di == 0 else None, solar=solar if di == 0 else None, temps_bt=bots_tops.T[int(len(bots_tops.T) / 2):].T if di == 1 else None, ret_temps_bt=True, ) bots_tops = np.array(bots_tops) temp_effect_damages.append( new_temp_effect[0] if di == 1 else new_temp_effect[0][:int(len(new_temp_effect[0]) / 2)]) temp_effect.append(np.concatenate(temp_effect_damages)) print(f"len(temps) = {len(temps)}") print(f"len_per_hour = {int(len(traffic_array) / traffic_array_mins)}") print(f"Temperature shape = {temp_effect[-1].shape}") plt.plot(temp_effect[-1]) plt.savefig( c.get_image_path("crack", safe_str(f"save-temps-{response_type}.pdf"))) plt.close() responses = [] for ri, rt in enumerate(response_types): responses_healthy_cracked = [] for ds, ta in [(HealthyDamage(), traffic_array_0), (damage, traffic_array_1)]: print( f"Sections in scenarios scenario = {len(ds.use(c)[0].bridge.sections)}" ) responses_healthy_cracked.append( responses_to_traffic_array( c=c, traffic_array=ta, response_type=rt, damage_scenario=ds, points=[sensor], ).T[0]) # Responses from a single point. responses.append(np.concatenate(responses_healthy_cracked)) print(f"shape fem without temp = {responses[-1].shape}") print(f"shape of temp effect = {temp_effect[ri].shape}") if rt == ResponseType.Strain: responses[ri] = resize_units("")[0](responses[ri]) responses[ri] += temperature.apply(temp_effect[ri], responses[ri]) responses = np.array(responses) print(f"Responses shape = {responses.shape}") return responses