in libs/apls/apls.py [0:0]
def execute(output_dir, gt_list, gp_list, root_list,
weight='length',
speed_key='inferred_speed_mps',
travel_time_key='travel_time_s',
max_files=1000,
linestring_delta=50,
is_curved_eps=10**3,
max_snap_dist=4,
max_nodes=500,
min_path_length=10,
allow_renaming=True,
verbose=True,
super_verbose=False,
n_threads=12):
"""
Compute APLS for the input data in gt_list, gp_list
Arguments
---------
output_dir: str
dir to write output files into.
weight : str
Edge key determining path length weights. Defaults to ``'length'``.
speed_key : str
Edge key for speed. Defaults to ``'inferred_speed_mps'``.
travel_time_key : str
Edge key for travel time. Defaults to ``'travel_time_s'``.
max_files : int
Maximum number of files to analyze. Defaults to ``1000``.
linestring_delta : float
Distance in meters between linestring midpoints. Defaults to ``50``.
is_curved_eps : float
Minumum curvature for injecting nodes (if curvature is less than this
value, no midpoints will be injected). If < 0, always inject points
on line, regardless of curvature. Defaults to ``0.3``.
max_snap_dist : float
Maximum distance a node can be snapped onto a graph.
Defaults to ``4``.
max_nodes : int
Maximum number of gt nodes to inject midpoints. If there are more
gt nodes than this, skip midpoints and use this number of points
to comput APLS.
min_path_length : float
Mimumum path length to consider for APLS. Defaults to ``10``.
allow_renaming : boolean
Switch to rename nodes when injecting nodes into graphs.
Defaulst to ``True``.
verbose : boolean
Switch to print relevant values to screen. Defaults to ``False``.
super_verbose : boolean
Switch to print mucho values to screen. Defaults to ``False``.
Returns
-------
None
"""
# now compute results
C_arr = [["outroot", "APLS", "APLS_gt_onto_prop", "APLS_prop_onto_gt"]]
# make dirs
os.makedirs(output_dir, exist_ok=True)
##################
t0 = time.time()
# truncate until max_files
root_list = root_list[:max_files]
gt_list = gt_list[:max_files]
gp_list = gp_list[:max_files]
if n_threads is not None:
n_threads = min(n_threads, len(root_list))
print(f'Computing scores for {len(root_list)} pairs in total ...')
# for i, [outroot, G_gt_init, G_p_init] in tqdm(
# enumerate(zip(root_list, gt_list, gp_list)), total=len(root_list)):
def compute_score_arr(outroot, G_gt_init, G_p_init):
# get graphs with midpoints and geometry (if small graph)
if len(G_gt_init.nodes()) < 500: # 2000:
G_gt_cp, G_p_cp, G_gt_cp_prime, G_p_cp_prime, \
control_points_gt, control_points_prop, \
all_pairs_lengths_gt_native, all_pairs_lengths_prop_native, \
all_pairs_lengths_gt_prime, all_pairs_lengths_prop_prime \
= make_graphs(G_gt_init, G_p_init,
weight=weight,
speed_key=speed_key,
travel_time_key=travel_time_key,
linestring_delta=linestring_delta,
is_curved_eps=is_curved_eps,
max_snap_dist=max_snap_dist,
allow_renaming=allow_renaming,
verbose=verbose)
# get large graphs and paths
else:
G_gt_cp, G_p_cp, G_gt_cp_prime, G_p_cp_prime, \
control_points_gt, control_points_prop, \
all_pairs_lengths_gt_native, all_pairs_lengths_prop_native, \
all_pairs_lengths_gt_prime, all_pairs_lengths_prop_prime \
= make_graphs_yuge(G_gt_init, G_p_init,
weight=weight,
speed_key=speed_key,
travel_time_key=travel_time_key,
max_nodes=max_nodes,
max_snap_dist=max_snap_dist,
allow_renaming=allow_renaming,
verbose=verbose,
super_verbose=super_verbose)
if verbose:
print("\nlen control_points_gt:", len(control_points_gt))
if len(G_gt_init.nodes()) < 200:
print("G_gt_init.nodes():", G_gt_init.nodes())
print("len G_gt_init.edges():", len(G_gt_init.edges()))
if len(G_gt_cp.nodes()) < 200:
print("G_gt_cp.nodes():", G_gt_cp.nodes())
print("len G_gt_cp.nodes():", len(G_gt_cp.nodes()))
print("len G_gt_cp.edges():", len(G_gt_cp.edges()))
print("len G_gt_cp_prime.nodes():", len(G_gt_cp_prime.nodes()))
print("len G_gt_cp_prime.edges():", len(G_gt_cp_prime.edges()))
print("\nlen control_points_prop:", len(control_points_prop))
if len(G_p_init.nodes()) < 200:
print("G_p_init.nodes():", G_p_init.nodes())
print("len G_p_init.edges():", len(G_p_init.edges()))
if len(G_p_cp.nodes()) < 200:
print("G_p_cp.nodes():", G_p_cp.nodes())
print("len G_p_cp.nodes():", len(G_p_cp.nodes()))
print("len G_p_cp.edges():", len(G_p_cp.edges()))
print("len G_p_cp_prime.nodes():", len(G_p_cp_prime.nodes()))
if len(G_p_cp_prime.nodes()) < 200:
print("G_p_cp_prime.nodes():", G_p_cp_prime.nodes())
print("len G_p_cp_prime.edges():", len(G_p_cp_prime.edges()))
print("len all_pairs_lengths_gt_native:",
len(dict(all_pairs_lengths_gt_native)))
print("len all_pairs_lengths_gt_prime:",
len(dict(all_pairs_lengths_gt_prime)))
print("len all_pairs_lengths_prop_native",
len(dict(all_pairs_lengths_prop_native)))
print("len all_pairs_lengths_prop_prime",
len(dict(all_pairs_lengths_prop_prime)))
#########################
# Metric
C, C_gt_onto_prop, C_prop_onto_gt = compute_apls_metric(
all_pairs_lengths_gt_native, all_pairs_lengths_prop_native,
all_pairs_lengths_gt_prime, all_pairs_lengths_prop_prime,
control_points_gt, control_points_prop,
min_path_length=min_path_length,
verbose=verbose)
# C_arr.append([outroot, C, C_gt_onto_prop, C_prop_onto_gt])
return [outroot, C, C_gt_onto_prop, C_prop_onto_gt]
# Multiprocessing to accelerate the scoring process.
if n_threads is None:
print("Running in parallel using all threads ...")
else:
print("Running in parallel using {} threads ...".format(n_threads))
map_reduce_res = p_umap(compute_score_arr, root_list, gt_list, gp_list,
num_cpus=n_threads)
C_arr += map_reduce_res # append results below header
# print and save total cost
tf = time.time()
if verbose:
print(("Time to compute metric:", tf - t0, "seconds"))
print(("N input images:", len(root_list)))
# save to csv
path_csv = os.path.join(output_dir, 'scores_weight='+str(weight)+'.csv')
df = pd.DataFrame(C_arr[1:], columns=C_arr[0])
df.to_csv(path_csv)
print("Weight is " + str(weight))
print("Mean APLS = ", np.mean(df['APLS'].values))