Can we get the list of followed edges of the current edge? - sumo

In SUMO, can we get the list of next edges (if there exits) given the current edge? Also, can we get the four incoming approaches to an normal intersection?

It depends if you want to use TraCI and need the following edge on the route of a specific vehicle or if you just want a static network analysis. For the latter you can use sumolib (at least if you can use python):
# import the library
import sumolib
# parse the net
net = sumolib.net.readNet('myNet.net.xml')
# retrieve the successor edges of an edge
nextEdges = net.getEdge('myEdgeID').getOutgoing()
# retrieve the incoming edges of the destination of an edge
nextEdges = net.getEdge('myEdgeID').getToNode().getIncoming()
see https://sumo.dlr.de/docs/Tools/Sumolib.html

Related

How to get plot as svg string in sympy plotting backends library?

I use sympy plotting backends library to create plots directly from sympy expressions. I chose this library because it gives more options for plots fine tunning compared to standart sympy plotting module.
As backend in choosen library i use matplotlib.
My aim is to get resulting plot as svg string in order to insert it in the web page later. I need to do it programmatically. I use the code below:
from spb import plot, MB
import io
from sympy import symbols, sin, cos
x = symbols("x")
# create plot
p1 = plot(
(sin(x), "a", dict(color="k", linestyle=":")),
(cos(x), "b"),
backend=MB, show=False)
# buffer:
f = io.StringIO()
# save plot in buffer as svg string:
p1._fig.savefig(f, format = "svg")
# return result as svg string to insert it in web page later:
return f.getvalue()
The problem is that i get an exception:
'NoneType' object has no attribute 'savefig'
p1._fig.savefig(f, format = "svg")
But if i slightly modify the code:
...
# buffer:
f = io.StringIO()
# show plot:
p1.show()
# save plot in buffer as svg string:
p1._fig.savefig(f, format = "svg")
...
Everything works just fine. But the problem is that i do not want to show the plot, i need to save it as svg string. Anyone knows how to solve this task?
Here I am, the developer of that module.
That error is caused by the fact that when you create a plot with MatplotlibBackend and show=False, the figure is not created (too long to explain why); this behavior is specific to MatplotlibBackend, the other backends should not be affected by it. So, p1.fig is None.
However, the plotting function exposes the save method, which is nothing more than a wrapper to a specific plotting library "save" functionality. If you look at the source code, you'll see that MatplotlibBackend.save calls matplotlib's savefig, but first it checks if the figure has been created. If not, it forces the creation.
So, all you have to do is:
p1.save(f, format = "svg")
One final note. If possible, do not use attributes or methods starting with _ (underscore). They represent private attributes and the names might change from version to version. If you really need to retrieve the matplotlib figure, use p1.fig.
EDIT to answer the question in the comment about performance:
For back-compatibility reasons, the new module uses an adaptive algorithm for line plots by default, which is different from the one used on SymPy. On the one hand it can be easily applied to a wider set of applications, on the other hand it is slower.
You have two options: either way you might want to change the configuration file of the module.
Option 1: the adaptive algorithm minimizes some loss function (loss_fn) and stops when a threshold (adaptive_goal) has been reached. We can increase this threshold (which by default is set to 0.01), thus improving performance but sacrificing the smooth quality of lines.
from spb.defaults import cfg, set_defaults
# it requires a few tries to find an appropriate value
cfg["adaptive"]["goal"] = 0.02
set_defaults(cfg)
# restart the kernel to load the new configuration
Option 2: don't use the adaptive algorithm and switch to the uniform meshing algorithm which uses Numpy and vectorization (usually done with adaptive=False and possibly setting an appropriate number of discretization points n=something)! This is very very fast in comparison to the adaptive algorithm.
Think about it: generally, our plots are relatively small in comparison to the screen size. 1000 points per line (or whatever number you decide to use) should create smooth-enough lines.
So, you can deactivate the adaptive algorithm on a plot-by-plot basis (with adaptive=False), or you can set the module to always use the uniform meshing algorithm (this is the setup that I use on my machine).
from spb.defaults import cfg, set_defaults
# disable adaptive algorithm
cfg["adaptive"]["used_by_default"] = False
set_defaults(cfg)
# restart the kernel to load the new configuration
Then, when you create a plot and you feel like it should be smoother, simply increase the number of discretization points by setting n=something (default value is 1000).
You can find more customization options on this documentation page.

Any way to extract the exhaustive vocabulary of the google universal sentence encoder large?

I have some sentences for which I am creating an embedding and it works great for similarity searching unless there are some truly unusual words in the sentence.
In that case, the truly unusual words in fact contain the very most similarity information of any words in the sentence BUT all of that information is lost during embedding due to the fact that the word is apparently not in the vocabulary of the model.
I'd like to get a list of all of the words known by the GUSE embedding model so that I can mask those known words out of my sentence, leaving only the "novel" words.
I can then do an exact word search for those novel words in my target corpus and achieve usability for my similar sentence searching.
e.g. "I love to use Xapian!" gets embedded as "I love to use UNK".
If I just do a keyword search for "Xapian" instead of a semantic similarity search, I'll get much more relevant results than I would using GUSE and vector KNN.
Any ideas on how I can extract the vocabulary known/used by GUSE?
I combine the earlier answer from #Roee Shenberg and the solution provided here to come up with solution, which is applicable for USE v4:
import importlib
loader_impl = importlib.import_module('tensorflow.python.saved_model.loader_impl')
saved_model = loader_impl.parse_saved_model("/tmp/tfhub_modules/063d866c06683311b44b4992fd46003be952409c/")
graph = saved_model.meta_graphs[0].graph_def
fns = [f for f in saved_model.meta_graphs[0].graph_def.library.function if "ptb" in str(f).lower()];
print(len(fns)) # should be 1
nodes_with_sp = [n for n in fns[0].node_def if n.name == "Embeddings_words"]
print(len(nodes_with_sp)) # should be 1
words_tensor = nodes_with_sp[0].attr.get("value").tensor
word_list = [i.decode('utf-8') for i in words_tensor.string_val]
print(len(word_list)) # should be 400004
If you are just curious about the words I upload them here.
I'm assuming you have tensorflow & tensorflow_hub installed, and youhave already downloaded the model.
IMPORTANT: I'm assuming you're looking at https://tfhub.dev/google/universal-sentence-encoder/4! There's no guarantee the object graph looks the same for different versions, it's likely that modifications will be needed.
Find it's location on disk - it's somewhere at /tmp/tfhub_modules unless you set the TFHUB_CACHE_DIR environment variable (Windows/Mac have different locations). The path should contain a file called saved_model.pb, which is the model, serialized using Protocol Buffers.
Unfortunately, the dictionary is serialized inside the model's Protocol Buffers file and not as an external asset, so we'll have to load the model and get the variable from it.
The strategy is to use tensorflow's code to deserialize the file, and then travel down the serialized object tree all the way to the dictionary.
import importlib
MODEL_PATH = 'path/to/model/dir' # e.g. '/tmp/tfhub_modules/063d866c06683311b44b4992fd46003be952409c/'
# Use the tensorflow internal Protobuf loader. A regular import statement will fail.
loader_impl = importlib.import_module('tensorflow.python.saved_model.loader_impl')
saved_model = loader_impl.parse_saved_model(MODEL_PATH)
# reach into the object graph to get the tensor
graph = saved_model.meta_graphs[0].graph_def
function = graph.library.function
node_type, node_value = function[5].node_def
# if you print(node_type) you'll see it's called "text_preprocessor/hash_table"
# as well as get insight into this branch of the object graph we're looking at
words_tensor = node_value.attr.get("value").tensor
word_list = [i.decode('utf-8') for i in words_tensor.string_val]
print(len(word_list)) # -> 400004
Some resources that helped:
A GitHub issue relating to changing the vocabulary
A Tensorflow Google-group thread linked from the issue
Extra Notes
Despite what the GitHub issue may lead you to think, the 400k words here are not the GloVe 400k vocabulary. You can verify this by downloading the GloVe 6B embeddings (file link), extracting glove.6B.50d.txt, and then using the following code to compare the two dictionaries:
with open('/path/to/glove.6B.50d.txt') as f:
glove_vocabulary = set(line.strip().split(maxsplit=1)[0] for line in f)
USE_vocabulary = set(word_list) # from above
print(len(USE_vocabulary - glove_vocabulary)) # -> 281150
Inspecting the different vocabularies is interesting in and of itself, e.g. why does GloVe have an entry for '287.9'?

Clusters are not showing

I am using the below code to generate a graph with two clusters with four nodes each
For some reasons when I print the graph the clusters do not show up.
What am I doing wrong?
import pygraphviz as pgv
A=pgv.AGraph(bgcolor="#cccccc",layout='neato')
A.add_edge('R1','R2')
A.add_edge('R2','R3')
A.add_edge('R3','R4')
A.add_edge('R4','R5')
A.add_edge('R5','R6')
A.add_subgraph(['R1','R2','R3','R4'], 'pbd01')
A.add_subgraph(['R5','R6','R7','R8'], 'pbd02')
A.write('cluster.dot')
A.draw('Topology.png', prog='neato')
I believe there are two problems:
The 'neato' rendering engine does not support clustering
By convention, rendering engines that do support clustering require that the subgraph name starts with 'cluster'
The following code / image was produced with the 'dot' engine and correctly clusters the nodes:
import pygraphviz as pgv
A=pgv.AGraph(bgcolor="#cccccc",layout='dot')
A.add_edge('R1','R2')
A.add_edge('R2','R3')
A.add_edge('R3','R4')
A.add_edge('R4','R5')
A.add_edge('R5','R6')
A.add_subgraph(['R1','R2','R3','R4'], name='cluster_pbd01')
A.add_subgraph(['R5','R6','R7','R8'], name='cluster_pbd02')
A.write('cluster.dot')
A.draw('Topology.png', prog='dot')
Topology.png

MDAnalysis selects atoms from the PBC box but does not shift the coordinates

MDAnalysis distance selection commands like 'around' and 'sphzere' selects atoms from periodic image (I am using a rectangular box).
universe.select_atoms("name OW and around 4 (resid 20 and name O2)")
However, the coordinates of the atoms from the PBC box reside on the other side of the box. In other words, I have to manually translate the atoms to ensure that they actually are withing the 4 Angstrom distance.
Is there a selection feature to achieve this using the select_atoms function?
If I well understand, you would like to get the atoms around a given selection in the image that is the closest to that selection.
universe.select_atoms does not modify the coordinates, and I am not aware of a function that gives you what you want. The following function could work for an orthorhombic box like yours:
def pack_around(atom_group, center):
"""
Translate atoms to their periodic image the closest to a given point.
The function assumes that the center is in the main periodic image.
"""
# Get the box for the current frame
box = atom_group.universe.dimensions
# The next steps assume that all the atoms are in the same
# periodic image, so let's make sure it is the case
atom_group.pack_into_box()
# AtomGroup.positions is a property rather than a simple attribute.
# It does not always propagate changes very well so let's work with
# a copy of the coordinates for now.
positions = atom_group.positions.copy()
# Identify the *coordinates* to translate.
sub = positions - center
culprits = numpy.where(numpy.sqrt(sub**2) > box[:3] / 2)
# Actually translate the coordinates.
positions[culprits] -= (u.dimensions[culprits[1]]
* numpy.sign(sub[culprits]))
# Propagate the new coordinates.
atom_group.positions = positions
Using that function, I got the expected behavior on one of MDAnalysis test files. You need MDAnalysisTests to be installed to run the following piece of code:
import numpy
import MDAnalysis as mda
from MDAnalysisTests.datafiles import PDB_sub_sol
u = mda.Universe(PDB_sub_sol)
selection = u.select_atoms('around 15 resid 32')
center = u.select_atoms('resid 32').center_of_mass()
# Save the initial file for latter comparison
u.atoms.write('original.pdb')
selection.write('selection_original.pdb')
# Translate the coordinates
pack_around(selection, center)
# Save the new coordinates
u.atoms.write('modified.pdb')
selection.write('selection_modified.pdb')

Selective patterns with Matplotlib imshow without using patches

Is there a way to place patterns into selected areas on an imshow graph? To be precise, I need to make it so that, in addition to the numerical-data-carrying colored squares, I also have different patterns in other squares indicate different failure modes for the experiment (and also generate a key explaining the meaning of these different patterns). An example of a pattern that would be useful would be various types of crosshatches. I need to be able to do this without disrupting the main color-numerical data relationship on the graph.
Due to the back-end I am working within for the GUI containing the graph, I cannot utilize patches (they fail to pickle and make it from the back-end to the front-end via the multiprocessing package). I was wondering if anyone knew of another way to do this.
grid = np.ma.array(grid, mask=np.isnan(grid))
ax.imshow(grid, interpolation='nearest', aspect='equal', vmax = private.vmax, vmin = private.vmin)
# Up to here works fine and draws the graph showing only the data with white spaces for any point that failed
if show_fail and faildat != []:
faildat = faildat[np.lexsort((faildat[:,yind],faildat[:,xind]))]
fails = []
for i in range(len(faildat)): #gives coordinates with failures as (x,y)
fails.append((faildat[i,1],faildat[i,0]))
for F in fails:
ax.FUNCTION NEEDED HERE
ax.minorticks_off()
ax.set_xticks(range(len(placex)))
ax.set_yticks(range(len(placey)))
ax.set_xticklabels(placex)
ax.set_yticklabels(placey, rotation = 0)
ax.colorbar()
ax.show()