Skip to content
Snippets Groups Projects
Commit 738166b7 authored by Lionel GUEZ's avatar Lionel GUEZ
Browse files

Polish

parent b79d15fd
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python3 #!/usr/bin/env python3
"""A script that takes a segmented graph in the gt format and performs """A script that takes the graph of segments without cost functions
the non-local cost function calculation where each edge will have a and computes the non-local cost functions attributed to edges.
cost function assigned to it.
Input: Input:
...@@ -33,21 +32,21 @@ import bisect ...@@ -33,21 +32,21 @@ import bisect
def calculate_radii_and_rossby(start, end, inc, segment, e_overestim, handlers, def calculate_radii_and_rossby(start, end, inc, segment, e_overestim, handlers,
array_d_init): array_d_init):
radii = 0 #[m] radii = 0 #[m]
rossby = 0 #[1/s] rossby = 0 #[1/s]
days_modifier = 0 days_modifier = 0
for i in range(start, end, inc): for i in range(start, end, inc):
current_eddy = report_graph.node_to_date_eddy(segment[i], e_overestim) current_eddy = report_graph.node_to_date_eddy(segment[i], e_overestim)
i_SHPC = get_SHPC(array_d_init, current_eddy['date_index']) i_SHPC = get_SHPC(array_d_init, current_eddy['date_index'])
# calculate the location in the shapefile # calculate the location in the shapefile
location = util_eddies.comp_ishape(handlers[i_SHPC], location = util_eddies.comp_ishape(handlers[i_SHPC],
current_eddy['date_index'], current_eddy['date_index'],
current_eddy['eddy_index']) current_eddy['eddy_index'])
# now that we have the location in the shapefiles, we need to # now that we have the location in the shapefiles, we need to
# get the radius and the rossby number # get the radius and the rossby number
shapeRec = handlers[i_SHPC]["readers"]["extremum"].shapeRecord(location) shapeRec = handlers[i_SHPC]["readers"]["extremum"].shapeRecord(location)
...@@ -55,23 +54,23 @@ def calculate_radii_and_rossby(start, end, inc, segment, e_overestim, handlers, ...@@ -55,23 +54,23 @@ def calculate_radii_and_rossby(start, end, inc, segment, e_overestim, handlers,
lat_in_deg = shapeRec.shape.points[0][1] lat_in_deg = shapeRec.shape.points[0][1]
#[deg] #[deg]
f = 2*2*math.pi/(24*3600)*math.sin(math.radians(lat_in_deg)) # [1/s] f = 2*2*math.pi/(24*3600)*math.sin(math.radians(lat_in_deg)) # [1/s]
V_max = shapeRec.record[4] #[m/s] V_max = shapeRec.record[4] #[m/s]
R_Vmax = handlers[i_SHPC]["readers"]["max_speed_contour"]\ R_Vmax = handlers[i_SHPC]["readers"]["max_speed_contour"]\
.record(location)['r_eq_area'] * 1000 #[m] .record(location)['r_eq_area'] * 1000 #[m]
if (V_max < 100): if (V_max < 100):
# calculate Ro and Delta_Ro # calculate Ro and Delta_Ro
Ro = V_max / (f * R_Vmax) #[] Ro = V_max / (f * R_Vmax) #[]
else: else:
Ro = 0 Ro = 0
days_modifier += 1 days_modifier += 1
####### RADII ####### ####### RADII #######
radii += R_Vmax # [m] radii += R_Vmax # [m]
####### ROSSBY ###### ####### ROSSBY ######
rossby += Ro # [] rossby += Ro # []
return {"radii": radii, "rossby": rossby, "days_modifier": days_modifier} return {"radii": radii, "rossby": rossby, "days_modifier": days_modifier}
def get_SHPC(array_d_ini, date_index): def get_SHPC(array_d_ini, date_index):
...@@ -97,13 +96,13 @@ delta_cent_std = 8.0388 ...@@ -97,13 +96,13 @@ delta_cent_std = 8.0388
delta_ro_mean = -0.0025965 # [] delta_ro_mean = -0.0025965 # []
delta_ro_std = 5.2168 delta_ro_std = 5.2168
delta_r_mean = -0.0094709 * 1000 #[m] delta_r_mean = -0.0094709 * 1000 #[m]
delta_r_std = 8.6953 * 1000 delta_r_std = 8.6953 * 1000
# Load the graph_tool file: # Load the graph_tool file:
t0 = time.perf_counter() t0 = time.perf_counter()
timings = open("timings.txt", "w") timings = open("timings.txt", "w")
print('Loading gt file...') print('Loading graph...')
g = graph_tool.Graph() g = graph_tool.Graph()
try: try:
...@@ -112,12 +111,12 @@ except FileNotFoundError: ...@@ -112,12 +111,12 @@ except FileNotFoundError:
g.load('segments.graphml') g.load('segments.graphml')
t1 = time.perf_counter() t1 = time.perf_counter()
print('Loading done...')
print("Input graph:") print("Input graph:")
print("Number of vertices:", g.num_vertices()) print("Number of vertices:", g.num_vertices())
print("Number of edges:", g.num_edges()) print("Number of edges:", g.num_edges())
print("Internal properties:") print("Internal properties:")
g.list_properties() g.list_properties()
print('Loading done...')
timings.write(f"loading: {t1 - t0} s\n") timings.write(f"loading: {t1 - t0} s\n")
timings.close() timings.close()
...@@ -140,19 +139,17 @@ array_d_init = [handler["d_init"] for handler in handlers] ...@@ -140,19 +139,17 @@ array_d_init = [handler["d_init"] for handler in handlers]
# change if there is a change over the number of days to average # change if there is a change over the number of days to average
num_of_days_to_avg = 7 num_of_days_to_avg = 7
# iterate on the vertices print("Iterating on vertices...")
for n in g.vertices(): for n in g.vertices():
# Get the segment and the number of days
segment = g.vp.segment[n] segment = g.vp.segment[n]
num_of_days = len(segment)
# Calculate the indexes and dates:
# calculate the indexes and dates
first = report_graph.node_to_date_eddy(segment[0], e_overestim) first = report_graph.node_to_date_eddy(segment[0], e_overestim)
first_SHPC = get_SHPC(array_d_init, first['date_index']) first_SHPC = get_SHPC(array_d_init, first['date_index'])
num_of_days = len(segment)
# start processing
last = report_graph.node_to_date_eddy(segment[-1], e_overestim) last = report_graph.node_to_date_eddy(segment[-1], e_overestim)
last_SHPC = get_SHPC(array_d_init, last['date_index']) last_SHPC = get_SHPC(array_d_init, last['date_index'])
...@@ -164,20 +161,19 @@ for n in g.vertices(): ...@@ -164,20 +161,19 @@ for n in g.vertices():
last['date_index'], last['date_index'],
last['eddy_index']) last['eddy_index'])
# grab the centers # grab the centers:
first_pos = handlers[first_SHPC]["readers"]["extremum"]\ first_pos = handlers[first_SHPC]["readers"]["extremum"]\
.shape(first_loc).points[0] .shape(first_loc).points[0]
last_pos = handlers[last_SHPC]["readers"]["extremum"]\ last_pos = handlers[last_SHPC]["readers"]["extremum"]\
.shape(last_loc).points[0] .shape(last_loc).points[0]
##### STORE POSITIONS IN THE VPS ###### # Store positions in the vertex properties:
g.vp.pos_first[n] = first_pos # [deg, deg] g.vp.pos_first[n] = first_pos # [deg, deg]
g.vp.pos_last[n] = last_pos # [deg, deg] g.vp.pos_last[n] = last_pos # [deg, deg]
# if the segments are longer than the # of days over which to avg
if (num_of_days > num_of_days_to_avg): if (num_of_days > num_of_days_to_avg):
# The segment is longer than the number of days over which to average
first_radii = 0 # [m] first_radii = 0 # [m]
last_radii = 0 # [m] last_radii = 0 # [m]
...@@ -200,22 +196,17 @@ for n in g.vertices(): ...@@ -200,22 +196,17 @@ for n in g.vertices():
# Average and assign the rossbies: # Average and assign the rossbies:
first_rossby = first_res['rossby'] / (num_of_days_to_avg - modifier) first_rossby = first_res['rossby'] / (num_of_days_to_avg - modifier)
g.vp.first_av_ros[n] = first_rossby g.vp.first_av_ros[n] = first_rossby
else:
# there is division by zero, average rossby is undefinied
pass
# Last 7 days calculation # Last 7 days calculation
last_res = calculate_radii_and_rossby(len(segment) - 1, last_res = calculate_radii_and_rossby(len(segment) - 1, len(segment) -
len(segment) - (num_of_days_to_avg + 1), (num_of_days_to_avg + 1), -1,
-1, segment, e_overestim, handlers,
segment, e_overestim, array_d_init)
handlers, array_d_init)
# Average and assign the last radii # Average and assign the last radii
last_radii = last_res['radii'] / num_of_days_to_avg last_radii = last_res['radii'] / num_of_days_to_avg
g.vp.last_av_rad[n] = last_radii g.vp.last_av_rad[n] = last_radii
# grab the days modifier # grab the days modifier
modifier = last_res['days_modifier'] modifier = last_res['days_modifier']
...@@ -223,13 +214,10 @@ for n in g.vertices(): ...@@ -223,13 +214,10 @@ for n in g.vertices():
# Average and assign the rossbies: # Average and assign the rossbies:
last_rossby = last_res['rossby'] / (num_of_days_to_avg - modifier) last_rossby = last_res['rossby'] / (num_of_days_to_avg - modifier)
g.vp.last_av_ros[n] = last_rossby g.vp.last_av_ros[n] = last_rossby
else:
# there is division by zero, average rossby is undefinied
pass
# else, the number of eddies in a segment is lower than the # of
# days over which to average, the values will be the same except
# for the positions
else: else:
# The number of eddies in a segment is lower than the number
# of days over which to average. The values will be the same
# except for the positions.
res = calculate_radii_and_rossby(0, num_of_days, 1, segment, res = calculate_radii_and_rossby(0, num_of_days, 1, segment,
e_overestim, handlers, array_d_init) e_overestim, handlers, array_d_init)
...@@ -241,19 +229,13 @@ for n in g.vertices(): ...@@ -241,19 +229,13 @@ for n in g.vertices():
rossby = res['rossby'] / (num_of_days - modifier) rossby = res['rossby'] / (num_of_days - modifier)
g.vp.first_av_ros[n] = rossby g.vp.first_av_ros[n] = rossby
g.vp.last_av_ros[n] = rossby g.vp.last_av_ros[n] = rossby
else:
# there is division by zero, average rossby is undefinied
pass
# Average and assign the radii # Average and assign the radii
radii = res['radii'] / num_of_days radii = res['radii'] / num_of_days
g.vp.first_av_rad[n] = radii g.vp.first_av_rad[n] = radii
g.vp.last_av_rad[n] = radii g.vp.last_av_rad[n] = radii
############################### print("Iterating on edges...")
# Calculate the cost function #
###############################
for edge in g.edges(): for edge in g.edges():
source_node = edge.source() source_node = edge.source()
...@@ -262,25 +244,28 @@ for edge in g.edges(): ...@@ -262,25 +244,28 @@ for edge in g.edges():
cf = -10000 cf = -10000
lat_for_conv = (g.vp.pos_last[source_node][1] + lat_for_conv = (g.vp.pos_last[source_node][1] +
g.vp.pos_first[target_node][1]) / 2 # latitude needed for conversion of degrees to kilometers g.vp.pos_first[target_node][1]) / 2
# (latitude needed for conversion of degrees to kilometers)
lat_for_conv = math.radians(lat_for_conv) # need to convert to radians lat_for_conv = math.radians(lat_for_conv) # need to convert to radians
# because of the wrapping issue (360° wrapping incorrectly to 0°), we check for that here # because of the wrapping issue (360° wrapping incorrectly to 0°),
lon_diff = abs(g.vp.pos_last[source_node][0] - g.vp.pos_first[target_node][0]) # we check for that here
lon_diff = abs(g.vp.pos_last[source_node][0] \
- g.vp.pos_first[target_node][0])
if (lon_diff > 300): if (lon_diff > 300):
lon_diff = 360 - lon_diff lon_diff = 360 - lon_diff
# calculate Delta_cent: numbers used for conversion obtained from: Delta_Cent = math.sqrt((lon_diff * 111.32 * math.cos(lat_for_conv))**2
# https://stackoverflow.com/questions/1253499/simple-calculations-for-working-with-lat-lon-and-km-distance + ((g.vp.pos_last[source_node][1]
Delta_Cent = math.sqrt(( lon_diff * 111.32 * math.cos(lat_for_conv) )**2 + - g.vp.pos_first[target_node][1]) * 110.574)**2)
( (g.vp.pos_last[source_node][1] - g.vp.pos_first[target_node][1]) * 110.574 )**2)
# calculate the first term # calculate the first term
first_term = ((Delta_Cent - delta_cent_mean)/delta_cent_std) ** 2 first_term = ((Delta_Cent - delta_cent_mean)/delta_cent_std) ** 2
# Rossbies: # Rossbies:
if (g.vp.first_av_ros[target_node] and g.vp.last_av_ros[source_node]): if (g.vp.first_av_ros[target_node] and g.vp.last_av_ros[source_node]):
Delta_Ro = g.vp.last_av_ros[source_node] - g.vp.first_av_ros[target_node] Delta_Ro = g.vp.last_av_ros[source_node] \
- g.vp.first_av_ros[target_node]
else: else:
print("At least one of the rossbies is invalid.") print("At least one of the rossbies is invalid.")
#Delta_Ro = delta_ro_mean #Delta_Ro = delta_ro_mean
...@@ -291,7 +276,8 @@ for edge in g.edges(): ...@@ -291,7 +276,8 @@ for edge in g.edges():
# R_Vmax 1 and 2 already exist, just get the delta # R_Vmax 1 and 2 already exist, just get the delta
Delta_R_Vmax = g.vp.last_av_rad[source_node] - g.vp.first_av_rad[target_node] Delta_R_Vmax = g.vp.last_av_rad[source_node] \
- g.vp.first_av_rad[target_node]
# Calculate the third term # Calculate the third term
third_term = ((Delta_R_Vmax - delta_r_mean)/delta_r_std) ** 2 third_term = ((Delta_R_Vmax - delta_r_mean)/delta_r_std) ** 2
...@@ -306,5 +292,6 @@ for edge in g.edges(): ...@@ -306,5 +292,6 @@ for edge in g.edges():
g.ep.nl_cost_function[edge] = cf g.ep.nl_cost_function[edge] = cf
print("Saving...")
g.save('segments_cost_functions.gt') g.save('segments_cost_functions.gt')
print('All done') print('All done')
...@@ -72,8 +72,8 @@ for v in g.vertices(): ...@@ -72,8 +72,8 @@ for v in g.vertices():
t1 = time.perf_counter() t1 = time.perf_counter()
print(f'Done collapsing in {t1 - t0:.0f} s') print(f'Done collapsing in {t1 - t0:.0f} s')
t0 = t1 t0 = t1
print('Empty nodes:', len(verts_to_del)) print('Number of circumvented nodes:', len(verts_to_del))
print('Deleting empty nodes...') print('Deleting circumvented nodes...')
g.remove_vertex(verts_to_del, fast=True) g.remove_vertex(verts_to_del, fast=True)
t1 = time.perf_counter() t1 = time.perf_counter()
print(f"Done deleting in {t1 - t0:.0f} s") print(f"Done deleting in {t1 - t0:.0f} s")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment