Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/contributed/sumopy/agilepy/lib_misc/docgen.py
169689 views
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
4
# Copyright (C) 2016-2025 German Aerospace Center (DLR) and others.
5
# SUMOPy module
6
# Copyright (C) 2012-2021 University of Bologna - DICAM
7
# This program and the accompanying materials are made available under the
8
# terms of the Eclipse Public License 2.0 which is available at
9
# https://www.eclipse.org/legal/epl-2.0/
10
# This Source Code may also be made available under the following Secondary
11
# Licenses when the conditions for such availability set forth in the Eclipse
12
# Public License 2.0 are satisfied: GNU General Public License, version 2
13
# or later which is available at
14
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
15
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
16
17
# @file docgen.py
18
# @author Joerg Schweizer
19
# @date 2012
20
21
# """
22
##
23
##
24
# """
25
##__author__ = """Joerg Schweizer"""
26
##
27
##
28
##import networkx as nx
29
##
30
31
import numpy as np
32
from matplotlibtools import save_fig, init_plot
33
34
# needed for doc gen + import numpy as np
35
from os import system, path, getcwd, chdir
36
import types
37
38
##############################################################################
39
# convenience functions for Doc
40
ARRAYTYPES = (types.TupleType, np.ndarray, types.ListType, types.XRangeType)
41
INTTYPES = (types.IntType, np.int32, np.int64, np.int0, np.int16, np.int8, types.LongType)
42
FLOATTYPES = (types.FloatType, np.float64)
43
44
45
def is_arraytype(obj):
46
"""
47
Returns True if n is an array type of any kind
48
"""
49
return type(obj) in ARRAYTYPES
50
51
52
def is_integer(n):
53
"""
54
Returns True if n is an integer type of any kind
55
"""
56
return type(n) in INTTYPES
57
58
59
def is_float(x):
60
"""
61
Returns True if n is a float type of any kind
62
"""
63
return type(x) in FLOATTYPES
64
65
66
class Document:
67
def __init__(self, filename, workdir=None, preample=None, is_compile=False, is_maketitle=True):
68
"""
69
Create a document and open as file
70
filename = filename, excluding path and extension .tex
71
preample = enything that goes before begin document
72
If preample is given then an enire Latex document
73
will be created. Otherwise the document will be
74
created as an \\input{} file within another document
75
"""
76
# print 'Doc.__init__',filename
77
if not workdir:
78
workdir = path.dirname(filename)
79
if not workdir:
80
workdir = getcwd()
81
82
self.workdir = workdir
83
# print ' workdir',workdir
84
self.filename = filename
85
self.path_file = path.join(self.workdir, filename)+'.tex'
86
# print ' path_file',self.path_file
87
self.f = open(self.path_file, 'w')
88
self.preample = preample
89
self.is_maketitle = is_maketitle
90
if self.preample:
91
self.f.write(preample+"""\n\\begin{document}\n""")
92
if self.is_maketitle:
93
self.f.write("""\n\maketitle""")
94
# return self.f
95
self.is_compile = is_compile
96
97
def section(self, name, mode='', label=None):
98
99
self.f.write("""\n\\section"""+mode+"""{"""+name + """}\n""")
100
if label:
101
self.f.write("""\\label{"""+label + """}\n""")
102
103
def subsection(self, name, mode='', label=None):
104
105
self.f.write("""\n\\subsection"""+mode+"""{"""+name + """}\n""")
106
if label:
107
self.f.write("""\\label{"""+label + """}\n""")
108
109
def subsubsection(self, name, mode='', label=None):
110
111
self.f.write("""\n\\subsubsection"""+mode+"""{"""+name + """}\n""")
112
if label:
113
self.f.write("""\\label{"""+label + """}\n""")
114
115
def new_line(self, mode=""):
116
self.f.write(mode+"""\\\\ \n\n""")
117
118
def hline(self):
119
self.f.write("""\\hline \n""")
120
121
def newpage(self):
122
self.f.write("""\\newpage \n""")
123
124
def make_tableofcontents(self):
125
self.f.write("""\\tableofcontents
126
\\thispagestyle{empty}\\clearpage \n""")
127
128
def clearpage(self):
129
self.f.write("""\\clearpage \n""")
130
131
def write_objvaltable(self, obj, groupname=None,
132
attrsname="Attributes", valuesname="Value", symbolsname=None,
133
**kwargs):
134
135
attrsman = obj.get_attrsman()
136
137
if (groupname is None) | (not attrsman.has_group(groupname)):
138
attrconfigs = attrsman.get_configs()
139
140
else:
141
attrconfigs = attrsman.get_group(groupname)
142
attrsname = groupname
143
144
# first make a table of scalars only
145
if symbolsname is None:
146
self.begin_tabular(firstrow=[attrsname.capitalize(), valuesname.capitalize()], **kwargs)
147
else:
148
self.begin_tabular(firstrow=[attrsname.capitalize(), symbolsname.capitalize(),
149
valuesname.capitalize()], **kwargs)
150
151
for attrconfig in attrconfigs:
152
if not attrconfig.is_colattr():
153
if symbolsname is None:
154
self.add_tabular_row([attrconfig.get_name(),
155
attrconfig.format_value(show_unit=True, show_parentesis=False)])
156
else:
157
if hasattr(attrconfig, 'symbol'):
158
symbol = "$%s$" % attrconfig.symbol
159
else:
160
symbol = ""
161
162
self.add_tabular_row([attrconfig.get_name(),
163
symbol,
164
attrconfig.format_value()
165
+ "$\,%s$" % attrconfig.format_unit(show_parentesis=False),
166
])
167
self.end_tabular()
168
169
def begin_tabular(self, firstrow=[], firstcol=[], sep="|", align="c", n_cols=0, n_rows=0,
170
is_hline=True, is_vline=True, is_centered=True, stretch=1.2):
171
self.tab_firstrow = firstrow
172
self.tab_firstcol = firstcol
173
self.tab_rowcount = 0
174
self.tab_sep = sep
175
self.tab_is_hline = is_hline
176
self.tab_is_vline = is_vline
177
self.tab_is_centered = is_centered
178
179
if self.tab_is_centered:
180
self.begin_center()
181
182
format = ""
183
if len(firstrow) > 0:
184
self.tab_n_cols = len(firstrow)
185
else:
186
self.tab_n_cols = n_cols
187
188
if len(firstcol) > 0:
189
self.tab_n_rows = len(firstcol)
190
if is_vline:
191
format = "|"+align+"||"
192
else:
193
format = align+"|"
194
else:
195
self.tab_n_rows = n_rows
196
if is_vline:
197
format = "|"
198
199
for col in range(self.tab_n_cols):
200
if col == (self.tab_n_cols-1):
201
if is_vline:
202
form_col = align+"|"
203
else:
204
form_col = align
205
else:
206
form_col = align+sep
207
208
format += form_col
209
210
if stretch != None:
211
self.f.write("""\\renewcommand\\arraystretch{%s}\n""" % stretch)
212
213
self.f.write("""\\begin{tabular}{"""+format + """}\n""")
214
self._make_tableheader()
215
216
def _make_tableheader(self):
217
218
if self.tab_is_hline:
219
self.f.write("""\\hline\\hline \n""")
220
elif len(self.tab_firstrow) > 0:
221
self.f.write("""\\hline \n """)
222
else:
223
self.f.write("""\n """)
224
225
if len(self.tab_firstrow) > 0:
226
if len(self.tab_firstcol) > 0:
227
228
self.f.write("\t &") # make empty top left table corner
229
230
for col in range(self.tab_n_cols):
231
if col == (self.tab_n_cols-1):
232
sep = "\t \\\\ \n"
233
else:
234
sep = "\t &"
235
236
self._write_arrayelement(self.tab_firstrow[col], sep, is_math=False)
237
238
if self.tab_is_hline:
239
self.f.write("""\\hline\\hline \n""")
240
else:
241
self.f.write("""\\hline \n """)
242
243
def add_tabular_row(self, row):
244
245
# print 'add_tabular_row',self.tab_rowcount
246
if len(self.tab_firstcol) > 0:
247
self._write_arrayelement(self.tab_firstcol[self.tab_rowcount], "\t &",
248
is_math=False)
249
250
for col in range(self.tab_n_cols):
251
if col == (self.tab_n_cols-1):
252
sep = "\t\\\\ \n"
253
else:
254
sep = "\t &"
255
256
self._write_arrayelement(row[col], sep, is_math=False)
257
258
if self.tab_is_hline:
259
self.f.write("""\\hline \n""")
260
261
self.tab_rowcount += 1
262
263
def end_tabular(self):
264
if self.tab_is_hline:
265
self.f.write("""\\hline \n""")
266
267
self.f.write("\\end{tabular} \n")
268
269
if self.tab_is_centered:
270
self.end_center()
271
272
def begin_equation(self, mode="$", label=None):
273
if label != None:
274
mode = 'enum'
275
self.eqn_mode = mode
276
if self.eqn_mode in ("$", "inline"):
277
self.f.write("$")
278
elif self.eqn_mode in ("*", "nolabels"):
279
self.f.write("""\\begin{equation*}\n""")
280
elif self.eqn_mode in ("enum", "enumerated"):
281
self.f.write("""\\begin{equation}\n""")
282
else:
283
self.eqn_mode = "["
284
self.f.write("""\\[\n""")
285
286
if label != None:
287
self.write("""\\label{%s}""" % label)
288
289
def end_equation(self):
290
if self.eqn_mode in ("$", "inline"):
291
self.f.write("$\n")
292
elif self.eqn_mode in ("*", "nolabels"):
293
self.f.write("""\\end{equation*}\n""")
294
elif self.eqn_mode in ("enum", "enumerated"):
295
self.f.write("""\\end{equation}\n""")
296
else:
297
self.eqn_mode = "["
298
self.f.write("""\\]\n""")
299
300
def begin_description(self):
301
self.f.write("\n\\begin{description}\n")
302
303
def item(self, item, label=None):
304
if label == None:
305
self.f.write("\n\\item %s\n" % item)
306
else:
307
self.f.write("\n\\item[%s] %s\n" % (label, item))
308
309
def end_description(self):
310
self.f.write("\\end{description} \n")
311
312
def begin_array(self, n_col=1, brace="(", arraystretch=1):
313
self.f.write("\\renewcommand\\arraystretch{%.2f}" % arraystretch)
314
self.f.write("\\left"+brace+"\\begin{array}{"+n_col*"c"+"}\n")
315
316
def end_array(self, brace=")"):
317
self.f.write("\\end{array}\\right"+brace+" \n")
318
319
def matrix(self, matrix, format=None, is_math=True, leftbrace='(', rightbrace=')', arraystretch=1):
320
# print 'pmatrix',matrix
321
# n_row,n_col=matrix.shape
322
n_row = len(matrix)
323
n_col = len(matrix[0])
324
self.begin_array(n_col, leftbrace, arraystretch)
325
for row in xrange(0, n_row):
326
for col in xrange(0, n_col):
327
# print ' ',col,row,matrix[row,col]
328
if col == (n_col-1):
329
sep = "\\\\ \n"
330
else:
331
sep = " & "
332
# pick matrix element at row,col and decide what to do
333
elem = matrix[row][col]
334
self._write_arrayelement(elem, sep, format_default=format, is_math=is_math)
335
336
self.end_array(rightbrace)
337
338
def colvec(self, vec, format=None, is_math=True):
339
# print 'pmatrix',matrix
340
n_row = len(vec)
341
sep = "\\\\ \n"
342
self.begin_array(1)
343
for col in xrange(0, n_row):
344
self._write_arrayelement(vec[col], sep, format_default=format, is_math=is_math)
345
346
self.end_array()
347
348
def rowvec(self, vec, format=None, is_math=True):
349
n_row = len(vec)
350
351
self.begin_array(n_row)
352
for row in xrange(0, n_row):
353
# print ' ',col,row,matrix[row,col]
354
if row == (n_row-1):
355
sep = "\\\\ \n"
356
else:
357
sep = " & "
358
self._write_arrayelement(vec[row], sep, format_default=format, is_math=is_math)
359
360
self.end_array()
361
362
def _write_arrayelement(self, elem, sep, format_default=None, is_math=False):
363
"""
364
Write to document the formated characters dependend on type
365
"""
366
# print '_write_arrayelement'
367
# print ' elem,format_default',elem,type(elem),type(elem)==np.float64,format_default
368
if is_math:
369
mathsep = ""
370
else:
371
mathsep = "$" # create in-line mat env
372
373
if is_arraytype(elem):
374
self.f.write(mathsep)
375
if is_arraytype(elem[0]):
376
self.matrix(elem, is_math=False) # write entire matrix
377
else:
378
self.rowvec(elem, is_math=False) # write entire matrix
379
self.f.write(mathsep+sep)
380
381
elif format_default != None: # scalar with default format
382
self.f.write((format_default+sep) % (elem))
383
384
elif is_integer(elem):
385
format = "%d"
386
self.f.write((mathsep+format+mathsep+sep) % (elem))
387
388
elif is_float(elem):
389
format = "%.2f"
390
self.f.write((mathsep+format+mathsep+sep) % (elem))
391
392
else: # probably a string, just as is
393
self.f.write(elem+sep)
394
395
def begin_center(self):
396
self.f.write("""\n\\begin{center}\n""")
397
398
def end_center(self):
399
self.f.write("""\\end{center}\n""")
400
401
def include_graphics(self, filename, options=None, is_centered=True,
402
method='matplotlib', label=None, caption=None, envoptions='h!'):
403
print 'include_graphics ', filename
404
path_file = path.join(self.workdir, filename)
405
if options is None:
406
options = 'width = \\textwidth'
407
is_figure_env = (label != None) | (caption != None)
408
if is_figure_env:
409
if label != None:
410
self.write("""\\begin{figure}[%s]""" % envoptions)
411
else:
412
self.write("""\\begin{figure*}[%s]""" % envoptions)
413
414
if is_centered:
415
self.begin_center()
416
# print ' method=',method
417
if method == 'matplotlib':
418
419
workdir = getcwd()
420
chdir(self.workdir)
421
# print ' safe matplotlib figure and convert to pdf'
422
ffilename = save_fig(filename)
423
# print ' done safe'
424
chdir(workdir)
425
self.f.write("""\\includegraphics["""+options+"""]{"""+ffilename + """}\n""")
426
else:
427
self.f.write("""\\includegraphics["""+options+"""]{"""+filename + """}\n""")
428
429
if is_centered:
430
self.end_center()
431
if is_figure_env:
432
if caption != None:
433
self.write("""\\caption{%s}""" % caption)
434
if label != None:
435
self.write("""\\label{%s}""" % label)
436
437
if label != None:
438
self.write("""\\end{figure}""")
439
else:
440
self.write("""\\end{figure*}""")
441
442
def save_graphics_matplotlib(self, filename):
443
"""
444
Save current matplotlib graphics in working directory.
445
"""
446
workdir = getcwd()
447
chdir(self.workdir)
448
save_fig(filename)
449
chdir(workdir)
450
451
def write(self, text):
452
self.f.write(text+"\n")
453
454
def stream(self, text):
455
self.f.write(text)
456
457
def end(self):
458
if self.preample:
459
self.f.write("""\\end{document}\n""")
460
self.f.close()
461
if self.is_compile:
462
print 'compile latex ', self.path_file
463
system('pdflatex ' + self.path_file)
464
465
466
def ref(label, reftype=None):
467
if reftype == None:
468
return '~\\ref{%s}' % label
469
else:
470
return '%s~\\ref{%s}' % (reftype, label)
471
472