Skip to content

Commit

Permalink
Included baseline order in the refs table
Browse files Browse the repository at this point in the history
  • Loading branch information
thvitt committed Oct 13, 2019
1 parent 7adb472 commit 1370760
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/macrogen/graph.py
Expand Up @@ -392,6 +392,7 @@ def _infer_details(self):
table.loc[ref, 'avg'] = avg
table.loc[ref, 'avg_year'] = avg and avg.year
table.loc[ref, 'yearlabel'] = yearlabel(max_before, min_after)
table['baseline_position'] = self.baseline_order()
self.details = table

def year_stats(self):
Expand Down
73 changes: 49 additions & 24 deletions src/macrogen/report.py
Expand Up @@ -3,7 +3,8 @@
import os
import urllib
from collections import defaultdict, Counter
from datetime import date, datetime
from datetime import date, datetime, timedelta
from functools import partial
from html import escape
from io import StringIO
from itertools import chain, groupby
Expand Down Expand Up @@ -361,22 +362,41 @@ def _subgraph_link(*nodes: List[Node], html_content: Optional[str] = None, **opt
return f'<a href="subgraph?{urllib.parse.urlencode(params)}">{html_content}</a>'


def _fmt_date(d: date, delta: timedelta = timedelta(), na: str = '') -> str:
"""
Helper to format a given date.
Args:
d: The date to format
delta: If present, a difference to add to d before formatting
na: When date is a N/A value, return this string instead
Returns:
iso-formatted, delta corrected date or the given na string
"""
if not d or pd.isna(d):
return na
else:
return (d + delta).isoformat()


class RefTable(HtmlTable):
"""
Builds a table of references.
"""

def __init__(self, graphs: MacrogenesisInfo, **table_attrs):
super().__init__(data_sortable="true", **table_attrs)
(self.column('Nr.', data_sortable="numericplus")
.column('Knoten davor', data_sortable="numericplus")
.column('Objekt', data_sortable="sigil", format_spec=_fmt_node)
.column('Typ / Edition', data_sortable="sigil", format_spec=_edition_link)
.column('nicht vor', data_sortable="alpha", format_spec=lambda d: format(d) if d != EARLIEST else "")
.column('nicht nach', data_sortable="alpha", format_spec=lambda d: format(d) if d != LATEST else "")
.column('erster Vers', data_sortable="numericplus")
.column('Aussagen', data_sortable="numericplus")
.column('<a href="conflicts">Konflikte</a>', data_sortable="numericplus"))
(self.column('Nr.', data_sortable_type="numericplus")
.column('(BL)', data_sortable_type="numericplus", format_spec=lambda f: str(int(f)) if f else '')
.column('Knoten davor', data_sortable_type="numericplus")
.column('Objekt', data_sortable_type="sigil", format_spec=_fmt_node)
.column('Typ / Edition', data_sortable_type="sigil", format_spec=_edition_link)
.column('nicht vor', data_sortable_type="alpha", format_spec=partial(_fmt_date, delta=DAY))
.column('nicht nach', data_sortable_type="alpha", format_spec=partial(_fmt_date, delta=-DAY))
.column('erster Vers', data_sortable_type="numericplus")
.column('Aussagen', data_sortable_type="numericplus")
.column('<a href="conflicts">Konflikte</a>', data_sortable_type="numericplus"))
self.graphs = graphs
self.base = graphs.base

Expand All @@ -398,10 +418,12 @@ def reference(self, ref: Reference, index: Optional[int] = None, write_subpage:
end_node = side_node(self.base, wit, Side.END)
else:
start_node, wit, end_node = ref, ref, ref
assertions = list(chain(self.base.in_edges(start_node, data=True), self.base.out_edges(end_node, data=True)))
assertions = list(
chain(self.base.in_edges(start_node, data=True), self.base.out_edges(end_node, data=True)))
conflicts = [assertion for assertion in assertions if 'delete' in assertion[2] and assertion[2]['delete']]
self.row((f'<a href="refs#idx{index}">{index}</a>', ref.rank, wit, wit,
self.graphs.details.max_before_date[wit], self.graphs.details.min_after_date[wit],
details = self.graphs.details
self.row((f'<a href="refs#idx{index}">{index}</a>', details.baseline_position[wit], details.loc[wit,'rank'],
wit, wit, details.max_before_date[wit], details.min_after_date[wit],
getattr(wit, 'min_verse', ''), len(assertions), len(conflicts)),
id=f'idx{index}', class_=type(wit).__name__)
if write_subpage:
Expand Down Expand Up @@ -980,8 +1002,8 @@ def demo_graph(u, v, extend=None, **edge_attr) -> nx.MultiDiGraph:
g7.add_edge(date(1808, 9, 30), hp47, source='Bohnenkamp 1994')
g7.add_edge(hp47, date(1809, 3, 31), source=BiblSource('faust://heuristic', 'Bohnenkamp 1994'))


help_graphs = dict(pre=g1, conflict=g1a, syn=g2, dating=g3, interval=g4, when=g5, orphan=g_orphan, copy=g6, heuristic=g7)
help_graphs = dict(pre=g1, conflict=g1a, syn=g2, dating=g3, interval=g4, when=g5, orphan=g_orphan, copy=g6,
heuristic=g7)
for name, graph in help_graphs.items():
write_dot(graph, str(target / f'help-{name}.dot'))

Expand Down Expand Up @@ -1070,6 +1092,7 @@ def report_scenes(graphs: MacrogenesisInfo):

write_html(target / "scenes.php", sceneTable.format_table(), head='nach Szene')


def report_unused(graphs: MacrogenesisInfo):
unused_nodes = set(node for node in graphs.base.node if isinstance(node, Reference)) - set(graphs.dag.node)
not_in_dag_table = RefTable(graphs)
Expand All @@ -1090,7 +1113,6 @@ def report_unused(graphs: MacrogenesisInfo):
"Nicht eingeordnete Zeugen")



def write_order_xml(graphs: MacrogenesisInfo):
order_xml: Path = config.path.order or config.path.report_dir / 'order.xml'
logger.debug('Writing order file to %s', order_xml.absolute())
Expand All @@ -1105,8 +1127,8 @@ def write_order_xml(graphs: MacrogenesisInfo):
index=format(row.position),
uri=row.uri,
sigil_t=row.Index.sigil_t,
earliest=(row.max_before_date+DAY).isoformat() if not pd.isna(row.max_before_date) else '',
latest=(row.min_after_date-DAY).isoformat() if not pd.isna(row.min_after_date) else '',
earliest=(row.max_before_date + DAY).isoformat() if not pd.isna(row.max_before_date) else '',
latest=(row.min_after_date - DAY).isoformat() if not pd.isna(row.min_after_date) else '',
yearlabel=row.yearlabel)
for row in graphs.details.query('kind == "Witness"').itertuples(index=True)],
generated=datetime.now().isoformat())
Expand All @@ -1119,6 +1141,8 @@ def write_order_xml(graphs: MacrogenesisInfo):
with (config.path.report_dir / 'witness-stats.json').open('wt', encoding='utf-8') as out:
json.dump(data, out)

graphs.details.to_csv(config.path.report_dir / 'ref_info.csv', date_format='iso')


def report_stats(graphs: MacrogenesisInfo):
"""
Expand Down Expand Up @@ -1247,7 +1271,7 @@ def ref_info(row) -> dict:
return result

rows = graphs.details.itertuples(index=True)
data = list() # FIXME list comprehension after #25 is resolved
data = list() # FIXME list comprehension after #25 is resolved
known = set()
for row in rows:
if not (pd.isna(row.max_before_date) or pd.isna(row.min_after_date)):
Expand Down Expand Up @@ -1375,17 +1399,17 @@ def report_config(info: MacrogenesisInfo):
'Eine Aussage wie <em>A vor B</em> wird interpretiert als '
'<em>A wurde beendet, bevor mit B begonnen wurde</em>.',
'split-reverse': 'Datenmodell, bei dem jeder Zeuge und jede Inskription durch je einen Knoten für den Beginn und einen '
'Knoten für das Ende des Schreibprozesses repräsentiert wird. '
'Eine Kante stellt sicher, dass der Beginn vor dem Ende liegt. '
'Eine Aussage wie <em>A vor B</em> wird interpretiert als '
'<em>A wurde begonnen, bevor B beendet wurde</em>.',
'Knoten für das Ende des Schreibprozesses repräsentiert wird. '
'Eine Kante stellt sicher, dass der Beginn vor dem Ende liegt. '
'Eine Aussage wie <em>A vor B</em> wird interpretiert als '
'<em>A wurde begonnen, bevor B beendet wurde</em>.',
}

inscriptions = {
'orphan': 'Falls für einen Zeugen <var>w</var> keine Makrogeneseaussagen vorliegen, aber für mindestens eine '
'Inskription <var>w<sub>i</sub></var> von <var>w</var>, so wird für jede Inskription von <var>w</var>'
'eine Kante <var>w<sub>i</sub> → w</var> eingezogen.',
'copy': 'Alle Aussagen über Inskriptionen werden auf die zugehörigen Zeugen kopiert.',
'copy': 'Alle Aussagen über Inskriptionen werden auf die zugehörigen Zeugen kopiert.',
'inline': 'Eine Inskription <var>w<sub>i</sub></var> eines Zeugen <var>w</var> wird so eingebunden, dass '
'sie nach dem Beginn von <var>w</var> beginnt und vor dem Ende von <var>w</var> endet.',
}
Expand Down Expand Up @@ -1444,6 +1468,7 @@ def report_config(info: MacrogenesisInfo):

write_html(config.path.report_dir / "config.php", content, head="Konfiguration")


def generate_reports(info: MacrogenesisInfo):
report_functions = [fn for name, fn in globals().items() if name.startswith('report_')]
for report in report_functions:
Expand Down

0 comments on commit 1370760

Please sign in to comment.