I am trying to visualize a simple Finite State Machine graph using Graphviz. The layout created by Graphviz is not completely to my liking. I was expecting a more compact result with shorter edges.
So far, I have tried using groups and changing the weights of edges, but not much luck. It is not clear to me why Graphviz draws the graph the way it does and how to adjust its algorithm to my liking. Are there any parameters I can set to achieve that? Or should I use another command than dot? I tried neato, but the result looked completely messed up and again, I do not really understand what I am doing...
This is my best result so far:
Trying to visualize a better lay-out than this, I think the graph would look nicer if the red boxes were aligned differently, more compact for example like indicated by the arrows in this picture:
I used dot to create the graph and he source code is as follows:
1 digraph JobStateDiagram
2 {
3 rankdir=LR;
4 size="8,5";
5
6 node [style="rounded,filled,bold", shape=box, fixedsize=true, width=1.3, fontname="Arial"];
7 Created [fillcolor=black, shape=circle, label="", width=0.25];
8 Destroyed [fillcolor=black, shape=doublecircle, label="", width=0.3];
9 Empty [fillcolor="#a0ffa0"];
10 Announced [fillcolor="#a0ffa0"];
11 Assigned [fillcolor="#a0ffa0"];
12 Working [fillcolor="#a0ffa0"];
13 Ready [fillcolor="#a0ffa0"];
14 TimedOut [fillcolor="#ffa0a0"];
15 Failed [fillcolor="#ffa0a0"];
16
17 {
18 rank=source; Created Destroyed;
19 }
20
21 edge [style=bold, fontname="Arial" weight=2]
22 Empty -> Announced [ label="announce" ];
23 Announced -> Assigned [ label="assign" ];
24 Assigned -> Working [ label="start" ];
25 Working -> Ready [ label="finish" ];
26 Ready -> Empty [ label="revoke" ];
27
28 edge [fontname="Arial" color="#aaaaaa" weight=1]
29 Announced -> TimedOut [ label="timeout" ];
30 Assigned -> TimedOut [ label="timeout" ];
31 Working -> TimedOut [ label="timeout" ];
32 Working -> Failed [ label="error" ];
33 TimedOut -> Announced [ label="announce" ];
34 TimedOut -> Empty [ label="revoke" ];
35 Failed -> Announced [ label="announce" ];
36 Failed -> Empty [ label="revoke" ];
37
38 edge [style=bold, fontname="Arial" weight=1]
39 Created -> Empty [ label="initialize" ];
40 Empty -> Destroyed [ label="finalize" ];
41 Announced -> Empty [ label="revoke" ];
42 Assigned -> Empty [ label="revoke" ];
43 Working -> Empty [ label="revoke" ];
44 }
Also, anybody please let me know if I do any strange things in the Graphviz file above -- any feedback is appreciated.
Update:
More experimenting and trying some suggestions like ports, given by user marapet, have increased my confusion... For example, in the picture below, why does dot choose to draw these strange detours for Working->Failed and Failed->Announced, as opposed to straighter lines?
To me your output looks alright. TimedOut and Failed are of course all the way to the right because there is an edge going from Working to them. That's what dot does best, and while you can make some tweaks to adjust graphviz layouts, I think it's better to use an other tool if you want to create a particular graph layout and control everything.
That being said, I did give it a quick try with graphviz. I changed some lines to create a straight line with all the green nodes, and to align the red nodes as indicated in your question. I also added edge concentrators - the result doesn't look better to me:
digraph JobStateDiagram
{
rankdir=LR;
size="8,5";
concentrate=true;
node [style="rounded,filled,bold", shape=box, fixedsize=true, width=1.3, fontname="Arial"];
Created [fillcolor=black, shape=circle, label="", width=0.25];
Destroyed [fillcolor=black, shape=doublecircle, label="", width=0.3];
Empty [fillcolor="#a0ffa0"];
Failed [fillcolor="#ffa0a0"];
Announced [fillcolor="#a0ffa0"];
Assigned [fillcolor="#a0ffa0"];
Working [fillcolor="#a0ffa0"];
Ready [fillcolor="#a0ffa0"];
TimedOut [fillcolor="#ffa0a0"];
{
rank=source; Created; Destroyed;
}
{
rank=same;Announced;Failed;
}
{
rank=same;Assigned;TimedOut;
}
edge [style=bold, fontname="Arial", weight=100]
Empty -> Announced [ label="announce" ];
Announced -> Assigned [ label="assign" ];
Assigned -> Working [ label="start" ];
Working -> Ready [ label="finish" ];
Ready -> Empty [ label="revoke", weight=1 ];
edge [color="#aaaaaa", weight=1]
Announced -> TimedOut [ label="timeout" ];
Assigned -> TimedOut [ label="timeout" ];
Working -> TimedOut [ label="timeout" ];
Working -> Failed [ label="error" ];
TimedOut -> Announced [ label="announce" ];
TimedOut -> Empty [ label="revoke" ];
Failed -> Announced [ label="announce" ];
Failed -> Empty [ label="revoke" ];
Created -> Empty [ label="initialize" ];
Empty -> Destroyed [ label="finalize" ];
Announced -> Empty [ label="revoke" ];
Assigned -> Empty [ label="revoke" ];
Working -> Empty [ label="revoke" ];
}
You may also improve by using ports in order to control where edges start and end.
As to your question about strange things in your dot file: Except line numbers (which finally allowed me to put column mode of my text editor to good use) and aligning, your file looks fine to me. I do structure my dot files similarly (graph properties, node list, groupings, edges) whenever possible. Just be aware that the order of first appearance of nodes may have an impact on the final layout.
Although this is a very old question, I had similar problem and would like to share my result. Besides the "weight", "rank=same" tricks, I just found these methods can be used to adjust the layout result:
dir=back
add more edges or nodes and set style=invis
When it comes to this particular graph in the question, actually rank=same and weight would do the main job and style=invis can do some fine tuning. So by adding these lines
{
rank=same;Announced;Failed;
}
{
rank=same;Assigned;TimedOut;
}
to the file and adding weight=1 to the 'Ready to Empty' edge, and with some invisible edges to fine tune the spaces I got this:
The complete graph dot source:
digraph JobStateDiagram
{
rankdir=LR;
size="8,5";
node [style="rounded,filled,bold", shape=box, fixedsize=true, width=1.3, fontname="Arial"];
Created [fillcolor=black, shape=circle, label="", width=0.25];
Destroyed [fillcolor=black, shape=doublecircle, label="", width=0.3];
Empty [fillcolor="#a0ffa0"];
Announced [fillcolor="#a0ffa0"];
Assigned [fillcolor="#a0ffa0"];
Working [fillcolor="#a0ffa0"];
Ready [fillcolor="#a0ffa0"];
TimedOut [fillcolor="#ffa0a0"];
Failed [fillcolor="#ffa0a0"];
{
rank=source; Created Destroyed;
}
{
rank=same;Announced;Failed; #change here
}
{
rank=same;Assigned;TimedOut; #change here
}
edge [style=bold, fontname="Arial" weight=20] #change here
Empty -> Announced [ label="announce" ];
Announced -> Assigned [ label="assign" ];
Assigned -> Working [ label="start" ];
Working -> Ready [ label="finish" ];
Ready -> Empty [ label="revoke" weight=1 ]; #change here
edge [fontname="Arial" color="#aaaaaa" weight=2] #change here
Announced -> TimedOut [ label="timeout" ];
Assigned -> TimedOut [ label="timeout" weight=1]; #change here
Working -> TimedOut [ label="timeout" ];
Working -> Failed [ label="error" ];
TimedOut -> Announced [ label="announce" ];
TimedOut -> Empty [ label="revoke" ];
Failed -> Announced [ label="announce" ];
Failed -> Empty [ label="revoke" ];
edge [style=bold, fontname="Arial" weight=1]
Created -> Empty [ label="initialize" ];
Empty -> Destroyed [ label="finalize" ];
Announced -> Empty [ label="revoke" ];
Assigned -> Empty [ label="revoke" ];
Working -> Empty [ label="revoke" ];
Assigned -> Working [ label="start" style=invis ]; #change here
Assigned -> Working [ label="start" style=invis ]; #change here
}
Update: instead of putting 'Failed' and 'Announced' at the same rank, putting 'Failed', 'Assigned' and 'TimedOut' the same rank might produce a better result like below, which IMO better illustrates the similarity and difference between Failed and TimedOut. (You have to remove the invis edges though to get the graph below)
Related
I am using packer to create a base ami and using a post proccessor to create a manifest.json file
how can i make this json valid
{
"builds": [
{
"name": "amazon-ebs",
"builder_type": "amazon-ebs",
"build_time": 1589466697,
"files": null,
"artifact_id": "eu-west-1:ami-04d3331ac647e751b",
"packer_run_uuid": "add4c072-7ac2-f5e9-b941-6b80003c03ec",
"custom_data": {
"my_custom_data": "example"
}
}
],
"last_run_uuid": "add4c072-7ac2-f5e9-b941-6b80003c03ec"
2020-05-14T14:31:37.246153577Z stdout P }
Error: Parse error on line 13:
...b941-6b80003c03ec" 2020 - 05 - 14 T14:
----------------------^
Expecting 'EOF', '}', ':', ',', ']', got 'NUMBER'
My eventual goal is to save the artifact_id to a var using bash
Thank you for the help,
In order to make it valid json, i had to add this attribute to my packer template.json:
"post-processors": [
{
"type": "manifest",
"output": "manifest.json",
"strip_path": true,
"strip_time": true
"strip_time": "true"
I try to make a bunch of turtles (Movers) to go trough a gate and avoid the wall which is white. Somehow the model freezes after a few runs. Go button stays black and blue circle turns for ever. No error MSG given. It must get stuck in some calculation within the "move-movers" function but I can't determine why.
I added a simplified version of my code which still produces the crash. Copy & paste to run. Disable world wrap. Include a slider for "num-movers" Variable.
breed [ movers mover ]
movers-own [ steps ] ; Steps will be used to determine if an agent has moved.
to setup
clear-all
reset-ticks
ask patches [ set pcolor green ]
basic-pattern
end
to basic-pattern ; sets up gate and wall
let wallXCor 16 ; sets a white line to determine the inside & outside of the gate
repeat 33 [
ask patch wallXCor 0 [ set pcolor white ]
set wallXCor wallXCor - 1
]
ask patches with [ pycor > 0 ] [ set pcolor lime ] ; sets the outside of the gate to another color (lime)
; changes color of the center to lime to create a passable opening
ask patch 0 0 [ set pcolor lime ]
ask patch 1 0 [ set pcolor lime ]
ask patch -1 0 [ set pcolor lime ]
end
to distribute-agents ; Distributes the Movers outside the gate based on the patch color lime. The number needs to be set via slider "num-movers"
repeat num-movers [
ask one-of patches with [ pcolor = lime and pycor > 2 and any? turtles-here = false ] [
sprout-movers 1 [ set color red set shape "circle" facexy 0 -12 ] set num-movers num-movers- 1 ]
] end
to go
move-movers
tick
end
to move-movers ; reset the steps variable and facing
ask movers [ set steps steps + 1 ]
ask movers [ facexy 0 -3 ]
; following lines checks if next patch to be steped upon is "legal".
while [ any? movers with [ steps > 0 ] ] [
ask movers with [ steps > 0 ] [
ifelse is-patch? patch-ahead 1
and not any? turtles-on patch-ahead 1
and [ not member? pcolor [ white brown ] ] of patch-ahead 1
[
fd 1
set steps steps - 1
] [ dirchange ]
]
]
end
to dirchange ;If not able to move to next patch change direction to allow a step backwards.
if ( pxcor <= 0 and ycor >= 0 ) [ facexy 1 3 ] ;fd 1 set steps steps - 1]
if ( pxcor >= 0 and ycor >= 0 ) [ facexy -1 3 ] ;fd 1 set steps steps - 1]
end
You're not getting an error message, because there is no actual error. The code just gets stuck in your while loop.
Did you mean to comment out the fd 1 set steps steps - 1 in your dirchange? My guess is that you have a bunch of turtles that face the same patch (either 1,3 or -1, 3) and get stuck because none of them can move because another turtle is in front of them. And because you only subtract from their steps if they actually move, some of them never get to 0 steps.
While is in general a bad primitive to use for this reason, especially when you have this many conditionals in your move code, making it hard to know what is causing your while loop to not end. is it because your turtles are facing a wall, or because they are at the boundary of the world, or because someone else is blocking their path? You just don't know, and because the code is stuck in a loop, your model view doesn't update so you can't see what is going on.
If you insist on keeping the while, I would at least put in a safeguard: write a turtle reporter that checks if your turtles are able to move and break your while if they can't, or give them a finite number of attempts at moving, rather requiring them to have actually moved.
I made a simple logstash configuration:
tcp.conf
input {
tcp {
port => 22
type => syslog
}
}
filter {
if [type] == "syslog" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
add_field => [ "received_at", "%{#timestamp}" ]
add_field => [ "received_from", "%{host}" ]
}
syslog_pri { }
date {
match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
}
}
}
output {
stdout { codec => rubydebug }
}
running the configuration:
bin/logstash -f tcp.conf
executing this command:
telnet localhost 22
I get this error:
Using milestone 2 input plugin 'tcp'. This plugin should be stable, but if you see strange behavior, please let us know! For more information on plugin milestones, see http://logstash.net/docs/1.4.2/plugin-milestones {:level=>:warn}
Using milestone 1 filter plugin 'syslog_pri'. This plugin should work, but would benefit from use by folks like you. Please let us know if you find bugs or have suggestions on how to improve this plugin. For more information on plugin milestones, see http://logstash.net/docs/1.4.2/plugin-milestones {:level=>:warn}
+---------------------------------------------------------+
| An unexpected error occurred. This is probably a bug. |
| You can find help with this problem in a few places: |
| |
| * chat: #logstash IRC channel on freenode irc. |
| IRC via the web: http://goo.gl/TI4Ro |
| * email: logstash-users#googlegroups.com |
| * bug system: https://logstash.jira.com/ |
| |
+---------------------------------------------------------+
The error reported is:
Permission denied - bind(2)
I am doing this configuration fallow the Syslog example
"Permission denied - bind" means that logstash can't attach itself to the listed port.
Often, this is because you're running logstash as a non-privileged user who cannot access ports numbered below 1024.
In your case, you're trying to connect to port 22. As the ssh/scp/sftp port, this seems like an odd place to look for log files.
I'm tring to build an ontology to infer some informations about a domain classification and a terminology, but I'm experiencing some conceptual difficulties.
Let me explain the problem. In Protègè 4.1 i created 6 subclasses of Thing: Concept, conceptTitle, ConceptSynonym (for the classification) and Term, TermTitle, TermSynonym (for the terminology). I also have created hasConceptTitle, hasConceptSynonym, hasTermTitle and hasTermSynonym object relationships (with some constrint) to say that every Concept has one (and only one) title, and may have some synonyms, and every Term has one (and only one) title and some synonyms. Both Concept and Term have another relationship isA, giving to the classification a DAG/tree structure, while the terminology has a lattice structure (in other words, a term may be a subclass of more than one term).
Here comes the problem: I would like to create a subclass of Concept, let's say "MappedConcept"), which should be the set of mapped concepts, that is the set of concepts which have the title equals to a term's title, or it has a synonym equals to a term's title or has a synonym that is equal to a synonym of a term.
In the first-order logic, this set may be expressed as:
∀x∃y( ∃z((hasConceptTitle(x,z) ∧ hasTermTitle(y,z)) ∨
∃z((hasConceptTitle(x,z) ∧ hasTermSynonym(y,z)) ∨
∃z((hasConceptSynonym(x,z) ∧ hasTermTitle(y,z)) ∨
∃z((hasConceptSynonym(x,z) ∧ hasTermSynonym(y,z)) )
How can I obtain this? Defining data properties for "ConceptTitle", "ConceptSynonym", "TermTitle" and "TermSynonym"? And how to describe the string matches?
Maybe those 4 classes should be just data properties of Concept and Term classes?
I read the practical guide of Matthew Horridge several times, but I can't the practical ideas I have on my mind into an ongology in Protègè.
Thanks in advance.
I'm afraid you cannot do this in OWL 2 DL nor in Protégé, which is an editor for OWL 2 DL, because, as far as I can tell, it seems necessary to introduce the inverse of a datatype property, which is forbidden in OWL 2 DL. However, it's possible in OWL Full, and some DL reasoners may even be able to deal with it. Here, in Turtle:
<MappedConcept> a owl:Class;
owl:equivalentTo [
a owl:Class;
owl:unionOf (
[
a owl:Restriction;
owl:onProperty <hasConceptTitle>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermTitle> ];
owl:someValuesFrom <Term>
]
] [
a owl:Restriction;
owl:onProperty <hasConceptTitle>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermSynonym> ];
owl:someValuesFrom <Term>
]
] [
a owl:Restriction;
owl:onProperty <hasConceptSynonym>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermSynonym> ];
owl:someValuesFrom <Term>
]
] [
a owl:Restriction;
owl:onProperty <hasConceptSynonym>;
owl:someValuesFrom [
a owl:Restriction;
owl:onProperty [ owl:inverseOf <hasTermTitle> ];
owl:someValuesFrom <Term>
]
]
)
] .
You can also do it without OWL, with a rule language for instance. The rules would look closer to how you would do it in programming languages. In SWRL:
hasConceptTitle(?x,?z), hasTermTitle(?y,?z) -> MappedConcept(?x)
hasConceptTitle(?x,?z), hasTermSynonym(?y,?z) -> MappedConcept(?x)
hasConceptSynonym(?x,?z), hasTermTitle(?y,?z) -> MappedConcept(?x)
hasConceptSynonym(?x,?z), hasTermSynonym(?y,?z) -> MappedConcept(?x)
device.type('www.amazon.com') to the browser in the emulator drops the first 2 characters. logcat shows the full string for 'type' but the first 2 chars are missing at the BrowserActivity. device.press() for each individual character does the same thing...
[ 01-08 18:36:29.947 15335:0x3be7 D/MonkeyStub ]
translateCommand: type www.amazon.com
[ 01-08 18:36:33.175 15335:0x3be7 D/MonkeyStub ]
translateCommand: press KEYCODE_ENTER
[ 01-08 18:36:33.284 15353:0x3bf9 I/SearchDialog ]
Starting (as ourselves) #Intent;action=android.intent.action.SEARCH;launchFlags=0x10000000;component=com.android.browser/.BrowserActivity;S.query=w.amazon.com;S.user_query=w.amazon.com;end
is there a trick to sending a string to the browser with monkeyrunner?