Classes | Functions
wirecell.pgraph.main Namespace Reference

Classes

class  Node
 

Functions

def cli (ctx)
 
def is_string (x)
 
def is_list (x)
 
def is_list_of_string (x)
 
def dotify (edge_dat, attrs)
 
def jsonnet_try_path (path, rel)
 
def jsonnet_import_callback (path, rel)
 
def resolve_path (obj, jpath)
 
def uses_to_params (uses)
 
def cmd_dotify (ctx, jpath, params, json_file, out_file)
 
def main ()
 

Detailed Description

Fixme: make this into a proper click main

Function Documentation

def wirecell.pgraph.main.cli (   ctx)
Wire Cell Signal Processing Features

Definition at line 17 of file main.py.

17 def cli(ctx):
18  '''
19  Wire Cell Signal Processing Features
20  '''
21 
def cli(ctx)
Definition: main.py:17
def wirecell.pgraph.main.cmd_dotify (   ctx,
  jpath,
  params,
  json_file,
  out_file 
)
Convert a JSON file for a WCT job configuration based on the
Pgraph app into a dot file.

The JSON file needs to at least contain a list of edges found at
the given jpath.  Use, eg, "-1" to locate the last element of a
configuration sequence which is typically the config for a
Pgrapher.  If indeed it is, its [jpath].data.edges attribution
will be located and the overall JSON data structure will be used
as a list of nodes.  Otherwise [jpath].edges will be used and
[jpath].uses will be used to provide an initial list of node
objects.

Definition at line 216 of file main.py.

216 def cmd_dotify(ctx, jpath, params, json_file, out_file):
217  '''
218  Convert a JSON file for a WCT job configuration based on the
219  Pgraph app into a dot file.
220 
221  The JSON file needs to at least contain a list of edges found at
222  the given jpath. Use, eg, "-1" to locate the last element of a
223  configuration sequence which is typically the config for a
224  Pgrapher. If indeed it is, its [jpath].data.edges attribution
225  will be located and the overall JSON data structure will be used
226  as a list of nodes. Otherwise [jpath].edges will be used and
227  [jpath].uses will be used to provide an initial list of node
228  objects.
229  '''
230  if json_file.endswith(".jsonnet"):
231  import _jsonnet
232  jtext = _jsonnet.evaluate_file(json_file, import_callback=jsonnet_import_callback)
233  else:
234  jtext = open(json_file).read()
235 
236  dat = json.loads(jtext)
237  try:
238  cfg = resolve_path(dat, jpath)
239  except Exception:
240  click.echo('failed to resolve path "%s" in object:\n' % (jpath))
241  sys.exit(1)
242 
243  # if cfg["type"] not in ["Pgrapher", "Pnode"]:
244  # click.echo('Object must be of "type" Pgrapher or Pnode, got "%s"' % cfg["type"])
245  # sys.exit(1)
246 
247  if cfg.get("type","") == "Pgrapher": # the Pgrapher app holds edges in "data" attribute
248  print ('Pgrapher object found at jpath: "%s" with %d nodes' % (jpath, len(dat)))
249  edges = cfg["data"]["edges"]
250  uses = dat # if Pgrapher, then original is likely the full config sequence.
251  else:
252  edges = cfg["edges"] # Pnodes have edges as top-level attribute
253  uses = cfg.get("uses", list())
254  attrs = dict()
255  if params:
256  attrs = uses_to_params(uses)
257  dtext = dotify(edges, attrs)
258  ext = os.path.splitext(out_file)[1][1:]
259  dot = "dot -T %s -o %s" % (ext, out_file)
260  proc = subprocess.Popen(dot, shell=True, stdin = subprocess.PIPE)
261  proc.communicate(input=dtext.encode("utf-8"))
262  return
263 
int open(const char *, int)
Opens a file descriptor.
def dotify(edge_dat, attrs)
Definition: main.py:85
def uses_to_params(uses)
Definition: main.py:192
def resolve_path(obj, jpath)
Definition: main.py:174
def cmd_dotify(ctx, jpath, params, json_file, out_file)
Definition: main.py:216
int read(int, char *, size_t)
Read bytes from a file descriptor.
def wirecell.pgraph.main.dotify (   edge_dat,
  attrs 
)
Return GraphViz text.  If attrs is a dictionary, append to the
node a list of its items.  

Definition at line 85 of file main.py.

85 def dotify(edge_dat, attrs):
86  '''
87  Return GraphViz text. If attrs is a dictionary, append to the
88  node a list of its items.
89  '''
90 
91  nodes = dict()
92  def get(edge, end):
93  tn = edge[end]["node"]
94  try:
95  n = nodes[tn]
96  except KeyError:
97  n = Node(tn, **attrs.get(tn, {}))
98  nodes[tn] = n
99  p = edge[end].get("port",0)
100  n.add_port(end, p)
101  return n,p
102 
103 
104  edges = list()
105  for edge in edge_dat:
106  t,tp = get(edge, "tail")
107  h,hp = get(edge, "head")
108  e = '"%s":out%d -> "%s":in%d' % (t.dot_name(),tp, h.dot_name(),hp)
109  edges.append(e);
110 
111  # Try to find any components refereneced.
112  for tn,n in list(nodes.items()):
113  for k,v in n.attrs.items():
114  tocheck = None
115  if is_string(v):
116  tocheck = [v]
117  if is_list_of_string(v):
118  tocheck = v
119  if not tocheck:
120  continue
121  for maybe in tocheck:
122  if maybe not in attrs:
123  continue
124 
125  cn = nodes.get(maybe,None);
126  if cn is None:
127  cn = Node(maybe, **attrs.get(maybe, {}))
128  nodes[maybe] = cn
129 
130  e = '"%s" -> "%s"[style=dashed,color=gray]' % (n.dot_name(), cn.dot_name())
131  edges.append(e)
132 
133 
134 
135  ret = ["digraph pgraph {",
136  "rankdir=LR;",
137  "\tnode[shape=record];"]
138  for nn,node in sorted(nodes.items()):
139  ret.append('\t"%s"[label="%s"];' % (node.dot_name(), node.dot_label()))
140  for e in edges:
141  ret.append("\t%s;" % e)
142  ret.append("}")
143  return '\n'.join(ret);
144 
def is_string(x)
Definition: main.py:77
def is_list_of_string(x)
Definition: main.py:81
def dotify(edge_dat, attrs)
Definition: main.py:85
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
def wirecell.pgraph.main.is_list (   x)

Definition at line 79 of file main.py.

79 def is_list(x):
80  return type(x) in [list]
def is_list(x)
Definition: main.py:79
def wirecell.pgraph.main.is_list_of_string (   x)

Definition at line 81 of file main.py.

82  if not is_list(x): return False
83  return all(map(is_string, x))
84 
def is_list_of_string(x)
Definition: main.py:81
static QInternalList< QTextCodec > * all
Definition: qtextcodec.cpp:63
def is_list(x)
Definition: main.py:79
def wirecell.pgraph.main.is_string (   x)

Definition at line 77 of file main.py.

77 def is_string(x):
78  return type(x) in [type(u""), type("")]
def is_string(x)
Definition: main.py:77
def wirecell.pgraph.main.jsonnet_import_callback (   path,
  rel 
)

Definition at line 161 of file main.py.

161 def jsonnet_import_callback(path, rel):
162  paths = [path] + os.environ.get("WIRECELL_PATH","").split(":")
163  for maybe in paths:
164  try:
165  full_path, content = jsonnet_try_path(maybe, rel)
166  except RuntimeError:
167  continue
168  if content:
169  return full_path, content
170  raise RuntimeError('File not found')
171 
172 
173 
def jsonnet_try_path(path, rel)
Definition: main.py:145
def jsonnet_import_callback(path, rel)
Definition: main.py:161
void split(std::string const &s, char c, OutIter dest)
Definition: split.h:35
def wirecell.pgraph.main.jsonnet_try_path (   path,
  rel 
)

Definition at line 145 of file main.py.

145 def jsonnet_try_path(path, rel):
146  if not rel:
147  raise RuntimeError('Got invalid filename (empty string).')
148  if rel[0] == '/':
149  full_path = rel
150  else:
151  full_path = os.path.join(path, rel)
152  if full_path[-1] == '/':
153  raise RuntimeError('Attempted to import a directory')
154 
155  if not os.path.isfile(full_path):
156  return full_path, None
157  with open(full_path) as f:
158  return full_path, f.read()
159 
160 
int open(const char *, int)
Opens a file descriptor.
def jsonnet_try_path(path, rel)
Definition: main.py:145
def wirecell.pgraph.main.main ( void  )

Definition at line 264 of file main.py.

264 def main():
265  cli(obj=dict())
266 
def cli(ctx)
Definition: main.py:17
def wirecell.pgraph.main.resolve_path (   obj,
  jpath 
)
Select out a part of obj based on a "."-separated path.  Any
element of the path that looks like an integer will be cast to
one assuming it indexes an array.

Definition at line 174 of file main.py.

174 def resolve_path(obj, jpath):
175  '''
176  Select out a part of obj based on a "."-separated path. Any
177  element of the path that looks like an integer will be cast to
178  one assuming it indexes an array.
179  '''
180  jpath = jpath.split('.')
181  for one in jpath:
182  if not one:
183  break
184  try:
185  one = int(one)
186  except ValueError:
187  pass
188  obj = obj[one]
189 
190  return obj
191 
def resolve_path(obj, jpath)
Definition: main.py:174
def wirecell.pgraph.main.uses_to_params (   uses)
Given a list of nodes, return a dictionary of their "data" entries
keyed by 'type' or 'type:name'

Definition at line 192 of file main.py.

192 def uses_to_params(uses):
193  '''
194  Given a list of nodes, return a dictionary of their "data" entries
195  keyed by 'type' or 'type:name'
196  '''
197  ret = dict()
198  for one in uses:
199  if type(one) != dict:
200  print (type(one),one)
201  tn = one[u"type"]
202  if "name" in one and one['name']:
203  print (one["name"])
204  tn += ":" + one["name"]
205  ret[tn] = one.get("data", {})
206  return ret
207 
208 @cli.command("dotify")
209 @click.option("--jpath", default="",
210  help="A dot-delimited path into the JSON to locate a graph-like object")
211 @click.option("--params/--no-params", default=True,
212  help="Enable/disable the inclusion of contents of configuration parameters")
213 @click.argument("json-file")
214 @click.argument("out-file")
215 @click.pass_context
def uses_to_params(uses)
Definition: main.py:192