diff --git a/__pycache__/birth_death_utils.cpython-311.pyc b/__pycache__/birth_death_utils.cpython-311.pyc
new file mode 100644
index 00000000..9a06dcda
Binary files /dev/null and b/__pycache__/birth_death_utils.cpython-311.pyc differ
diff --git a/birth_death_utils.py b/birth_death_utils.py
index 7cfb2abb..f99cd35e 100644
--- a/birth_death_utils.py
+++ b/birth_death_utils.py
@@ -6,7 +6,8 @@
import matplotlib.pyplot as plt
from networkx.algorithms.traversal.depth_first_search import dfs_tree
import random
-
+from collections import Counter
+import re
def leaves(graph):
"""
@@ -81,6 +82,107 @@ def subtree_size(graph, node):
return len(dfs_tree(graph,node).nodes())
+def generate_tree_unified(lda0, mu, decay, decim, Tact, Tinact, Tcrisis):
+ """
+ Generate a tree (arbre réel) according to birth death model.
+
+ Parameters
+ ----------
+ lda0 : float
+ birth rate of new node per node per iteration
+ mu : float
+ death rate of nodes per node per per iteration
+ decay: float
+ decay rate
+ decim: float
+ decimation rate
+ Tact : int
+ number of iterations of the active reproduction phase
+ Tinact : int
+ number of iterations of the pure death phase (lda is set to 0)
+ Tcrisis: int
+ number of iterations of the time of the crisis
+
+ Returns
+ -------
+ G : nx.DiGraph()
+ networkx graph object of the generated tree with following node attributes:
+ 'state' : boolean, True if node living at the end of simulation
+ 'birth_time' : int
+ 'death_time' : int
+
+ """
+ currentID = 0
+ G = nx.DiGraph()
+ G.add_node(currentID)
+ living_nodes = set([0])
+
+ birth_time = {0: 0}
+ death_time = {}
+
+ pop = 1
+
+ t = 0
+ crisis_happened = False
+
+ while t < Tact:
+ lda1 = (lda0 * (1-decay)) + ( (2 * lda0 / Tact) * (Tact - t) * decay)
+ prob_event = lda1 + mu
+ prob_birth = lda1 / (lda1 + mu)
+ prob_death = mu / (lda1 + mu)
+
+ if pop == 0:
+ t = Tact
+ break
+ next_event = np.random.exponential(scale=1. / (prob_event * pop))
+ if next_event > Tact:
+ t = Tact
+ break
+
+ t += next_event
+ r = np.random.rand()
+ current_node = np.random.choice(list(living_nodes))
+ if r < prob_birth:
+ currentID += 1
+ G.add_node(currentID)
+ G.add_edge(current_node, currentID)
+ living_nodes.add(currentID)
+ pop += 1
+ birth_time[currentID] = t
+ else:
+ living_nodes.remove(current_node)
+ pop -= 1
+ death_time[current_node] = t
+
+ if t > Tcrisis and not crisis_happened:
+ decimated_nodes = random.sample(list(living_nodes), int(decim * pop))
+ for n in decimated_nodes:
+ living_nodes.remove(int(n))
+ death_time[n] = t
+ pop -= 1
+ crisis_happened = True
+
+ while t < Tact + Tinact:
+ if pop == 0:
+ t = Tact + Tinact
+ break
+ next_event = np.random.exponential(scale=1. / (mu * pop))
+ if next_event > Tact + Tinact:
+ t = Tact + Tinact
+ break
+ t += next_event
+ current_node = np.random.choice(list(living_nodes))
+ living_nodes.remove(current_node)
+ pop -= 1
+ death_time[current_node] = t
+
+ living = {n: (n in living_nodes) for n in G.nodes()}
+ nx.set_node_attributes(G, living, 'state')
+ nx.set_node_attributes(G, birth_time, 'birth_time')
+ nx.set_node_attributes(G, death_time, 'death_time')
+
+ return G
+
def generate_tree(lda, mu, Nact, Ninact):
"""
Generate a tree (arbre réel) according to birth death model.
@@ -559,4 +661,146 @@ def load_from_OpenStemmata(file):
# remove non-branching unattested nodes
st = generate_stemma(G)
- return st
\ No newline at end of file
+ return st
+
+
+## Functions for getting stats
+def compute_summary_stats(g):
+ """
+ Generate a vector of summary statistics from a graph generated by birth-death simulation
+
+ Parameters
+ ----------
+ g : nx.DiGraph()
+ tree graph generated by birth_death_utils.ct_bd_tree
+
+ Returns
+ -------
+ list
+ vector of summary statistics characterizing a single tradition
+ """
+ n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)
+
+ if n_living == 0:
+ return None
+
+ if n_living > 0:
+ birth_times_trad = []
+ for n in g.nodes():
+ if g.nodes[n]['state']:
+ birth_times_trad.append(g.nodes[n]['birth_time'])
+ timelapse = int(max(birth_times_trad) - min(birth_times_trad))
+ earliest_wit = int(min(birth_times_trad))
+ median_wit = int(np.median(birth_times_trad))
+ latest_wit = int(max(birth_times_trad))
+
+ if n_living == 1:
+ return [1, timelapse, earliest_wit, median_wit, latest_wit, -1, -1, -1, -1, -1, -1, -1]
+
+ if n_living == 2:
+ return [2, timelapse, earliest_wit, median_wit, latest_wit, -1, -1, -1, -1, -1, -1, -1]
+
+ if n_living >= 3:
+ degrees = []
+ direct_filiation_nb = 0
+ arch_dists = []
+ st = generate_stemma(g)
+ archetype = root(st)
+
+ for n in st.nodes():
+ degrees.append(st.out_degree(n))
+
+ if n != archetype:
+ father = list(st.predecessors(n))[0]
+ if st.nodes[n]['state'] and st.nodes[father]['state']:
+ direct_filiation_nb += 1
+ if st.nodes[n]['state']:
+ birth_times_trad.append(st.nodes[n]['birth_time'])
+ arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))
+
+ deg_dist = Counter(degrees)
+ deg1 = deg_dist[1]
+ deg2 = deg_dist[2]
+ deg3 = deg_dist[3]
+ deg4 = deg_dist[4]
+ depth = max(arch_dists)
+ n_nodes = len(list(st.nodes()))
+
+ return [
+ n_living,
+ timelapse,
+ earliest_wit,
+ median_wit,
+ latest_wit,
+ n_nodes,
+ direct_filiation_nb,
+ deg1,
+ deg2,
+ deg3,
+ deg4,
+ depth
+ ]
+
+def convert_date(x):
+ pattern1 = re.compile('[0-9][0-9][0-9][0-9]')
+ pattern2 = re.compile('[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
+
+ if bool(pattern1.fullmatch(x)):
+ return int(x)
+ if bool(pattern2.fullmatch(x)):
+ xx = x.split('-')
+ return (int(xx[0]),int(xx[1]))
+
+def top(x):
+ '''
+ Upper bound on witness date (single year or range)
+ '''
+ match x:
+ case (x1, x2):
+ return x2
+ case _:
+ return x
+
+def bottom(x):
+ '''
+ Lower bound on witness date (single year or range)
+ '''
+ match x:
+ case (x1, x2):
+ return x1
+ case _:
+ return x
+
+
+def expected_abs_diff_degenerate(c, a, b):
+ '''
+ Returns the expectation value of the timelapse between one date given as range
+ and one other as a single year
+ '''
+ if a == b:
+ return abs(a - c)
+ if a <= c <= b:
+ return ((c-a)**2 + (b-c)**2) / (2*(b-a))
+ elif c < a:
+ return (a+b)/2 - c
+ else:
+ return c - (a+b)/2
+
+def expected_abs_diff(a, b, c, d):
+ '''
+ Return the expectation value of th a=1151, b=1200, c=1241, d=1260e timelapse between two dates given as
+ intervals
+ '''
+ if a == b:
+ return expected_abs_diff_degenerate(a, c, d)
+ if c == d:
+ return expected_abs_diff_degenerate(c, a, b)
+ elif a < b < c < d:
+ return (c+d-b-a)/2
+ elif a <= c <= d < b:
+ return (1/(b-a)) * ((1/2)*((d-a)*(c-a)+(b-d)*(b-c)) + (1/3)*(d-c)**2)
+ elif a <= c <= b <= d:
+ return (1/(b-a)) * ((1/2)* ((c-a)*(d-a) + (b-c)*(d-b)) + (1/(3*(d-c)))*(b-c)**3 )
+ else:
+ print(f"{a},{b} -- {c},{d} ")
+ raise ValueError("Must have a < b, c < d, and a < c")
diff --git a/corpus_stemmata/Bogdanow_1960_SuiteMerlin/metadata.txt b/corpus_stemmata/Bogdanow_1960_SuiteMerlin/metadata.txt
index d12e9d93..ebf18a59 100644
--- a/corpus_stemmata/Bogdanow_1960_SuiteMerlin/metadata.txt
+++ b/corpus_stemmata/Bogdanow_1960_SuiteMerlin/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "188-198"
publicationLink: "https://doi.org/10.3406/roma.1960.3217"
workTitle: "Suite du Merlin"
workViaf: "293320611"
-workOrigDate: "1201-1300"
+workOrigDate: "1236-1245"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -23,3 +23,39 @@ rootType: "archetype"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: ""
+wits:
+ - witSigla: "C"
+ witSignature: "Cambridge, University of Cambridge. Library, MS Add. 7071"
+ witOrigDate: "1301-1320"
+ witOrigPlace: "England or Northern France (DÉAF)"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "H"
+ witSignature: "London, British library, Add MS 38117"
+ witOrigDate: "1281-1320"
+ witOrigPlace: "pic. -- Paris; Nord-Est de la France (Legge et Vinaver); pic. déb. 14es. (DÉAF) -- Source: Arlima, DÉAF"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "S"
+ witSignature: "Siena, Archivio di Stato [without shelfmark]"
+ witOrigDate: "1281-1300"
+ witOrigPlace: ""
+ witNotes: "fragment"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "Demanda (ed. 1535)"
+ witOrigDate: ""
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "Demanda (ed. 1498)"
+ witOrigDate: ""
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Braunholtz_1921_Horn/metadata.txt b/corpus_stemmata/Braunholtz_1921_Horn/metadata.txt
index 882babdb..6e5e9f3a 100644
--- a/corpus_stemmata/Braunholtz_1921_Horn/metadata.txt
+++ b/corpus_stemmata/Braunholtz_1921_Horn/metadata.txt
@@ -34,7 +34,7 @@ note : "The stemma include all witnesses, except for the F2 fragment, that conta
wits:
- witSigla: "C"
witSignature: "Cambridge, University Library, Ff.6.17"
- witOrigDate: ""
+ witOrigDate: "1201-1300"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
diff --git a/corpus_stemmata/Cloetta_1911_Moniage1/metadata.txt b/corpus_stemmata/Cloetta_1911_Moniage1/metadata.txt
index bf7f6feb..87517e27 100644
--- a/corpus_stemmata/Cloetta_1911_Moniage1/metadata.txt
+++ b/corpus_stemmata/Cloetta_1911_Moniage1/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "203"
publicationLink: ""
workTitle: "Moniage Guillaume"
workViaf: "184427604"
-workOrigDate: ""
+workOrigDate: "1134-1170"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
diff --git a/corpus_stemmata/Cloetta_1911_Moniage2/metadata.txt b/corpus_stemmata/Cloetta_1911_Moniage2/metadata.txt
index d9a20254..834773aa 100644
--- a/corpus_stemmata/Cloetta_1911_Moniage2/metadata.txt
+++ b/corpus_stemmata/Cloetta_1911_Moniage2/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "241"
publicationLink: ""
workTitle: "Moniage Guillaume"
workViaf: "184427604"
-workOrigDate: ""
+workOrigDate: "1171-1190"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
diff --git a/corpus_stemmata/Constans_1890_Thebes/metadata.txt b/corpus_stemmata/Constans_1890_Thebes/metadata.txt
index f74da4f8..948fc59e 100644
--- a/corpus_stemmata/Constans_1890_Thebes/metadata.txt
+++ b/corpus_stemmata/Constans_1890_Thebes/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "LXVI"
publicationLink: ""
workTitle: "Roman de Thebes"
workViaf: "184279798"
-workOrigDate: "1150 ca."
+workOrigDate: "1146-1162"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -22,4 +22,40 @@ extraStemmContam: "no"
rootType: "original"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
-note: "la contamination est notée sur le stemma via le signe d'addition, selon la première mode, et indiquée dans le texte. y a utilisé un modèle secondaire de la famille de x."
+note: "la contamination est notée sur le stemma via le signe d'addition, selon la première mode, et indiquée dans le texte. y a utilisé un modèle secondaire de la famille de x. Vérifier les sigles dans l'édition."
+wits:
+ - witSigla: "A"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 375"
+ witOrigDate: "1288"
+ witOrigPlace: "Arras (Jonas)"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 60"
+ witOrigDate: "1313-1349"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 784"
+ witOrigDate: "1241-1260"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "P"
+ witSignature: "Cologny, Fondation Martin Bodmer, Cod. Bodmer 18"
+ witOrigDate: "1281-1300"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "S"
+ witSignature: "London, British library, Add MS 34114"
+ witOrigDate: "1396-1405"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Constans_1912_BSteMaure-RTroie/metadata.txt b/corpus_stemmata/Constans_1912_BSteMaure-RTroie/metadata.txt
index 436627e1..9e91d75a 100644
--- a/corpus_stemmata/Constans_1912_BSteMaure-RTroie/metadata.txt
+++ b/corpus_stemmata/Constans_1912_BSteMaure-RTroie/metadata.txt
@@ -97,9 +97,9 @@ wits:
witDigit: ""
- witSigla: "B"
witSignature: "Paris, BnF, fr. 374"
- witOrigDate: "2 February 1288"
+ witOrigDate: "1288"
witOrigPlace: ""
- witNotes: "Copist: Jehan Madot d’Arras et Perrot de Nesle"
+ witNotes: "2 February 1288. Copist: Jehan Madot d’Arras et Perrot de Nesle"
witMsDesc: ""
witDigit: ""
- witSigla: "C"
@@ -118,8 +118,8 @@ wits:
witDigit: ""
- witSigla: "D"
witSignature: "Paris, BnF, fr. 783"
- witOrigDate: ""
- witOrigPlace: "1201-1300"
+ witOrigDate: "1201-1300"
+ witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
diff --git a/corpus_stemmata/CourayeduParc_1884_MortAimeri/metadata.txt b/corpus_stemmata/CourayeduParc_1884_MortAimeri/metadata.txt
index 2be12741..e0b4c353 100644
--- a/corpus_stemmata/CourayeduParc_1884_MortAimeri/metadata.txt
+++ b/corpus_stemmata/CourayeduParc_1884_MortAimeri/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "xlvj"
publicationLink: "https://archive.org/details/lamortaymeridena00couruoft/page/xlvi"
workTitle: "Mort Aimeri de Narbonne"
workViaf: "201013540"
-workOrigDate: "1180-1220"
+workOrigDate: "1176-1225"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: "NA"
@@ -23,3 +23,39 @@ rootType: "archetype"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: ""
+wits:
+ - witSigla: "A"
+ witSignature: "London, British library, Royal MS 20 D XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 24369"
+ witOrigDate: "1301-1320"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "London, British library, Royal MS 20 B XIX"
+ witOrigDate: "1281-1300"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "London, British library, Harley MS 1321"
+ witOrigDate: "1241-1260"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D2"
+ witSignature: "Düsseldorf, Universitäts- und Landesbibliothek, K 3: F 87"
+ witOrigDate: "1301-1320"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Demaison_1887_Aimeri/metadata.txt b/corpus_stemmata/Demaison_1887_Aimeri/metadata.txt
index 7411d255..f9f23528 100644
--- a/corpus_stemmata/Demaison_1887_Aimeri/metadata.txt
+++ b/corpus_stemmata/Demaison_1887_Aimeri/metadata.txt
@@ -7,10 +7,10 @@ publicationNum: "24"
publicationStemmaNum: "1"
publicationAuthors: "Demaison, Louis"
publicationPage: "LX"
-publicationLink: ""
+publicationLink: "https://archive.org/details/aymeridenarbonne01demauoft/page/60/mode/2up"
workTitle: "Aimeri de Narbonne"
workViaf: "180804873"
-workOrigDate: ""
+workOrigDate: "1181-1225"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -23,3 +23,39 @@ rootType: "archetype?"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: "la contamination n’est pas notée sur le stemma, mais indiquée dans le texte: le copiste de A1 aurait utilisé un manuscrit de la famille de C pour les 500 premiers vers du texte."
+wits:
+ - witSigla: "A1"
+ witSignature: "London, British library, Royal MS 20 B XIX"
+ witOrigDate: "1281-1300"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "A2"
+ witSignature: "London, British library, Harley MS 1321"
+ witOrigDate: "1241-1260"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B1"
+ witSignature: "London, British library, Royal MS 20 D XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B2"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 24369"
+ witOrigDate: "1301-1320"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 1448"
+ witOrigDate: "1241-1260"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Grillo_1984_ChretienteCorbaran/metadata.txt b/corpus_stemmata/Grillo_1984_ChretienteCorbaran/metadata.txt
index bc5acaa3..e829064d 100644
--- a/corpus_stemmata/Grillo_1984_ChretienteCorbaran/metadata.txt
+++ b/corpus_stemmata/Grillo_1984_ChretienteCorbaran/metadata.txt
@@ -48,14 +48,14 @@ wits:
witDigit: ""
- witSigla: "I"
witSignature: "London, British Library, Additional, 36615"
- witOrigDate: "1381-1320"
+ witOrigDate: "1296-1350"
witOrigPlace: "North-Eastern France"
witNotes: "several scribes"
witMsDesc: ""
witDigit: ""
- - witSigla: "I2"
+ - witSigla: "I"
witSignature: "London, British Library, Additional, 36615"
- witOrigDate: "1381-1320"
+ witOrigDate: "1296-1350"
witOrigPlace: "North-Eastern France"
witNotes: "Same manuscript as I, but this time it designates the second Continuation contained inside, that remaniates elements of the Chrétienté Corbaran"
witMsDesc: ""
diff --git a/corpus_stemmata/Henry_1935_EnfGuill/metadata.txt b/corpus_stemmata/Henry_1935_EnfGuill/metadata.txt
index d2c2a573..96ef6cbe 100644
--- a/corpus_stemmata/Henry_1935_EnfGuill/metadata.txt
+++ b/corpus_stemmata/Henry_1935_EnfGuill/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "XIX"
publicationLink: ""
workTitle: "Enfances Guillaume"
workViaf: "211000952"
-workOrigDate: ""
+workOrigDate: "1201-1250"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -23,3 +23,46 @@ rootType: "unspecified"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: ""
+wits:
+ - witSigla: "A1"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 774"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A2 and A4"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "A2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1449"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A1 and A4"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B1"
+ witSignature: "London, British Library, Royal, 20. D. XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: "France"
+ witNotes: "Same workshop as B2"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 24369-24370"
+ witOrigDate: "1301-1320"
+ witOrigPlace: "France"
+ witNotes: "Same workshop as B1"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "Boulogne-sur-Mer, Bibliothèque municipale, 192"
+ witOrigDate: "1295"
+ witOrigPlace: "Picardy or Paris"
+ witNotes: "Copy finished on 16/04/1295"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1448"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "Lorraine"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Langlois_1888_CourLouis/metadata.txt b/corpus_stemmata/Langlois_1888_CourLouis/metadata.txt
index 0a31c792..03a5c6ba 100644
--- a/corpus_stemmata/Langlois_1888_CourLouis/metadata.txt
+++ b/corpus_stemmata/Langlois_1888_CourLouis/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "CXXVIII"
publicationLink: "https://gallica.bnf.fr/ark:/12148/bpt6k9762011k/f146"
workTitle: "Couronnement de Louis"
workViaf: "182635496"
-workOrigDate: ""
+workOrigDate: "1101-1166"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -23,3 +23,60 @@ rootType: "original"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: ""
+wits:
+ - witSigla: "A1"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 774"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A2 and A4"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "A2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1449"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A1 and A4"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "A3"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 368"
+ witOrigDate: "1301-1313"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "A4"
+ witSignature: "Milano, Biblioteca Trivulziana, 1025"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A1 and A2"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B1"
+ witSignature: "London, British Library, Royal, 20. D. XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: "France"
+ witNotes: "Same workshop as B2"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 24369-24370"
+ witOrigDate: "1301-1320"
+ witOrigPlace: "France"
+ witNotes: "Same workshop as B1"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1448"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "Lorraine"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "Boulogne-sur-Mer, Bibliothèque municipale, 192"
+ witOrigDate: "1295"
+ witOrigPlace: "Picardy or Paris"
+ witNotes: "Copy finished on 16/04/1295"
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/LePerson_2003_Fierabras/metadata.txt b/corpus_stemmata/LePerson_2003_Fierabras/metadata.txt
index 5f10be66..b07bf224 100644
--- a/corpus_stemmata/LePerson_2003_Fierabras/metadata.txt
+++ b/corpus_stemmata/LePerson_2003_Fierabras/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "81"
publicationLink: ""
workTitle: "Fierabras"
workViaf: "193010408"
-workOrigDate: "1167-1200"
+workOrigDate: "1171-1200"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
diff --git a/corpus_stemmata/Loeseth_1890_GautierdArras-Eracle/metadata.txt b/corpus_stemmata/Loeseth_1890_GautierdArras-Eracle/metadata.txt
index b94b1163..f7c06d76 100644
--- a/corpus_stemmata/Loeseth_1890_GautierdArras-Eracle/metadata.txt
+++ b/corpus_stemmata/Loeseth_1890_GautierdArras-Eracle/metadata.txt
@@ -12,7 +12,7 @@ publicationPage : "n.p."
publicationLink : "https://archive.org/details/oeuvrespublies01gautuoft/page/n9"
workTitle : "Eracle"
workViaf : ""
-workOrigDate : "1150-1154"
+workOrigDate : "1150-1186"
workOrigPlace : ""
workAuthors:
- workAuthor: "Gautier d’Arras"
diff --git a/corpus_stemmata/Melander_1922_GuibAndr/metadata.txt b/corpus_stemmata/Melander_1922_GuibAndr/metadata.txt
index 78cfb4e1..de154b95 100644
--- a/corpus_stemmata/Melander_1922_GuibAndr/metadata.txt
+++ b/corpus_stemmata/Melander_1922_GuibAndr/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "XXXIII"
publicationLink: "https://archive.org/details/guibertdandrenas00melauoft/page/xxxiii/"
workTitle: "Guibert d'Andrenas"
workViaf: "196008746"
-workOrigDate: "1200-1225"
+workOrigDate: "1181-1224"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -23,3 +23,39 @@ rootType: "archetype"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: ""
+wits:
+ - witSigla: "A"
+ witSignature: "London, British library, Harley MS 1321"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "norm. -- traits norm.or. ca. 1255 -- Source: DÉAF"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B"
+ witSignature: "Paris, Bibliothèque nationale de France, NAF 6298"
+ witOrigDate: "1201-1300"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "London, British library, Royal MS 20 B XIX"
+ witOrigDate: "1281-1300"
+ witOrigPlace: "bourg. -- traits bourg. ca. 1270 -- Source: DÉAF"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "London, British library, Royal MS 20 D XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: "frc.: Paris -- traits pic., prob. Paris ca. 1335 -- Source: DÉAF"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "E"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 24369"
+ witOrigDate: "1301-1320"
+ witOrigPlace: "frc.: Paris -- traits pic., prob. Paris ca. 1335 -- Source: DÉAF"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Nelson_1985_ChevCygne/metadata.txt b/corpus_stemmata/Nelson_1985_ChevCygne/metadata.txt
index 5d7c4103..5567b4bb 100644
--- a/corpus_stemmata/Nelson_1985_ChevCygne/metadata.txt
+++ b/corpus_stemmata/Nelson_1985_ChevCygne/metadata.txt
@@ -90,7 +90,7 @@ wits:
witDigit: ""
- witSigla: "I"
witSignature: "London, British Library, Additional, 36615"
- witOrigDate: "1381-1320"
+ witOrigDate: "1296-1350"
witOrigPlace: "North-Eastern France"
witNotes: "several scribes"
witMsDesc: ""
diff --git a/corpus_stemmata/Nelson_1985_FinElias/metadata.txt b/corpus_stemmata/Nelson_1985_FinElias/metadata.txt
index 585916f7..49cd20b0 100644
--- a/corpus_stemmata/Nelson_1985_FinElias/metadata.txt
+++ b/corpus_stemmata/Nelson_1985_FinElias/metadata.txt
@@ -69,7 +69,7 @@ wits:
witDigit: ""
- witSigla: "I"
witSignature: "London, British Library, Additional, 36615"
- witOrigDate: "1381-1320"
+ witOrigDate: "1296-1350"
witOrigPlace: "North-Eastern France"
witNotes: "several scribes"
witMsDesc: ""
diff --git a/corpus_stemmata/Nelson_1985_NaissanceChevCygne/metadata.txt b/corpus_stemmata/Nelson_1985_NaissanceChevCygne/metadata.txt
index c905c78d..96cdb861 100644
--- a/corpus_stemmata/Nelson_1985_NaissanceChevCygne/metadata.txt
+++ b/corpus_stemmata/Nelson_1985_NaissanceChevCygne/metadata.txt
@@ -83,7 +83,7 @@ wits:
witDigit: ""
- witSigla: "I"
witSignature: "London, British Library, Additional, 36615"
- witOrigDate: "1381-1320"
+ witOrigDate: "1296-1350"
witOrigPlace: "North-Eastern France"
witNotes: "several scribes"
witMsDesc: ""
diff --git a/corpus_stemmata/Ponceau_1997a_SaintGraal/metadata.txt b/corpus_stemmata/Ponceau_1997a_SaintGraal/metadata.txt
index bbb356a9..ba9cf2b4 100644
--- a/corpus_stemmata/Ponceau_1997a_SaintGraal/metadata.txt
+++ b/corpus_stemmata/Ponceau_1997a_SaintGraal/metadata.txt
@@ -98,7 +98,7 @@ wits:
witDigit: ""
- witSigla: "Add. 32125"
witSignature: "London, British Library, Add. 32125"
- witOrigDate: "1180-1200"
+ witOrigDate: "1301-1333"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
diff --git a/corpus_stemmata/Ponceau_1997b_SaintGraal/metadata.txt b/corpus_stemmata/Ponceau_1997b_SaintGraal/metadata.txt
index ecaf2e72..f503f0f8 100644
--- a/corpus_stemmata/Ponceau_1997b_SaintGraal/metadata.txt
+++ b/corpus_stemmata/Ponceau_1997b_SaintGraal/metadata.txt
@@ -98,7 +98,7 @@ wits:
witDigit: ""
- witSigla: "Add. 32125"
witSignature: "London, British Library, Add. 32125"
- witOrigDate: "1180-1200"
+ witOrigDate: "1301-1333"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
diff --git a/corpus_stemmata/Ponceau_1997c_SaintGraal/metadata.txt b/corpus_stemmata/Ponceau_1997c_SaintGraal/metadata.txt
index 1c2700c9..63f1b2ba 100644
--- a/corpus_stemmata/Ponceau_1997c_SaintGraal/metadata.txt
+++ b/corpus_stemmata/Ponceau_1997c_SaintGraal/metadata.txt
@@ -10,7 +10,7 @@ publicationPage : "xxix"
publicationLink : ""
workTitle : "L’Estoire del Saint Graal"
workViaf : "179506093"
-workOrigDate : "1220-1230"
+workOrigDate : "1221-1230"
workOrigPlace : ""
workAuthor : "Anonymous"
workAuthorViaf : ""
@@ -98,7 +98,7 @@ wits:
witDigit: ""
- witSigla: "Add. 32125"
witSignature: "London, British Library, Add. 32125"
- witOrigDate: "1180-1200"
+ witOrigDate: "1301-1333"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
@@ -147,14 +147,14 @@ wits:
witDigit: ""
- witSigla: "OX.303"
witSignature: "Oxford, Bibl. Bodléienne, Douce 303"
- witOrigDate: "1201-1300"
+ witOrigDate: "1295-1305"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "Ars.2997"
witSignature: "Paris, Bibl. de l'Arsenal, 2997"
- witOrigDate: "1201-1300"
+ witOrigDate: "1297-1306"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
@@ -238,7 +238,7 @@ wits:
witDigit: ""
- witSigla: "B.N.747"
witSignature: "Paris, BnF, fr. 747"
- witOrigDate: "1201-1300"
+ witOrigDate: "1231-1250"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
@@ -259,7 +259,7 @@ wits:
witDigit: ""
- witSigla: "B.N.770"
witSignature: "Paris, BnF, fr. 770"
- witOrigDate: "1240-1260"
+ witOrigDate: "1281-1290"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
@@ -287,7 +287,7 @@ wits:
witDigit: ""
- witSigla: "B.N.12582"
witSignature: "Paris, BnF, fr. 12582"
- witOrigDate: "1201-1300"
+ witOrigDate: "1251-1300"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
@@ -301,14 +301,14 @@ wits:
witDigit: ""
- witSigla: "B.N.24394"
witSignature: "Paris, BnF, fr. 24394"
- witOrigDate: "1201-1300"
+ witOrigDate: "1285"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "Ren."
witSignature: "Rennes, Bibl. mun., 255"
- witOrigDate: "1201-1300"
+ witOrigDate: "1216-1235"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
diff --git a/corpus_stemmata/Pope_1955_Thomas-Horn/metadata.txt b/corpus_stemmata/Pope_1955_Thomas-Horn/metadata.txt
index d8d73a8f..00ca1459 100644
--- a/corpus_stemmata/Pope_1955_Thomas-Horn/metadata.txt
+++ b/corpus_stemmata/Pope_1955_Thomas-Horn/metadata.txt
@@ -12,7 +12,7 @@ publicationPage : "lvi"
publicationLink : ""
workTitle : "Horn"
workViaf : ""
-workOrigDate : "1171-1180"
+workOrigDate : "1166-1250"
workOrigPlace : "England"
workAuthors:
- workAuthor: "Thomas"
@@ -34,7 +34,7 @@ note : "The dotted lines on the original image are supposed to indicate oral tra
wits:
- witSigla: "C"
witSignature: "Cambridge, University Library, Ff.6.17"
- witOrigDate: ""
+ witOrigDate: "1201-1300"
witOrigPlace: "England"
witNotes: ""
witMsDesc: ""
diff --git a/corpus_stemmata/Rolin_1897_Aliscans1-Guillaume/metadata.txt b/corpus_stemmata/Rolin_1897_Aliscans1-Guillaume/metadata.txt
index 425f7233..2f87c611 100644
--- a/corpus_stemmata/Rolin_1897_Aliscans1-Guillaume/metadata.txt
+++ b/corpus_stemmata/Rolin_1897_Aliscans1-Guillaume/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "LXIII"
publicationLink: "https://archive.org/stream/AliscansRolin1897/Aliscans_Rolin_1897#page/n69"
workTitle: "Aliscans, 1re partie (Guillaume)"
workViaf: "182731512"
-workOrigDate: ""
+workOrigDate: "1151-1200"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -25,92 +25,92 @@ contributorORCID: "0000-0003-0385-7037"
note: ""
wits:
- witSigla: "M"
- witSignature: "Venedig"
- witOrigDate: ""
+ witSignature: "Venedig [Venice, Biblioteca nazionale marciana, fr., Z. 8 (52)]"
+ witOrigDate: "1351-1400"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "f"
- witSignature: "Boulogne"
- witOrigDate: ""
- witOrigPlace: ""
- witNotes: ""
+ witSignature: "Boulogne [Boulogne-sur-Mer, Bibliothèque municipale, 192]"
+ witOrigDate: "1295"
+ witOrigPlace: "Picardy or Paris"
+ witNotes: "Copy finished on 16/04/1295"
witMsDesc: ""
witDigit: ""
- witSigla: "L"
- witSignature: "London"
- witOrigDate: ""
+ witSignature: "London [London, British library, Royal MS 20 D XI]"
+ witOrigDate: "1301-1350"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "a"
- witSignature: "Arsenal"
- witOrigDate: ""
+ witSignature: "Arsenal [Paris, Bibliothèque nationale de France, Arsenal, Ms-6562]"
+ witOrigDate: "1221-1230"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "V"
- witSignature: "BN 24369"
- witOrigDate: ""
- witOrigPlace: ""
+ witSignature: "BN 24369 [Paris, Bibliothèque nationale de France, français, 24369-24370]"
+ witOrigDate: "1301-1320"
+ witOrigPlace: "France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "B"
- witSignature: "BN 368"
- witOrigDate: ""
+ witSignature: "BN 368 [Paris, Bibliothèque nationale de France, français, 368]"
+ witOrigDate: "1301-1313"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "C"
- witSignature: "Bern"
- witOrigDate: ""
+ witSignature: "Bern [Bern, Bürgerbibliothek Bern, Cod. 296]"
+ witOrigDate: "1251-1300"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "A"
- witSignature: "BN 774"
- witOrigDate: ""
- witOrigPlace: ""
+ witSignature: "BN 774 [Paris, Bibliothèque nationale de France, français, 774]"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "d"
- witSignature: "BN 2494"
- witOrigDate: ""
+ witSignature: "BN 2494 [Paris, Bibliothèque nationale de France, Français 2494]"
+ witOrigDate: "1226-1250"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "e"
- witSignature: "BN 1448"
- witOrigDate: ""
- witOrigPlace: ""
+ witSignature: "BN 1448 [Paris, Bibliothèque nationale de France, français, 1448]"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "Lorraine"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "T"
- witSignature: "Trivulziana"
- witOrigDate: ""
- witOrigPlace: ""
+ witSignature: "Trivulziana [Milano, Biblioteca Trivulziana, 1025]"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "b"
- witSignature: "BN 1449"
- witOrigDate: ""
- witOrigPlace: ""
+ witSignature: "BN 1449 [Paris, Bibliothèque nationale de France, français, 1449]"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "P"
- witSignature: "Cheltenhamer Handschrift"
- witOrigDate: ""
+ witSignature: "Cheltenhamer Handschrift [Oxford, Bodleian Library, MS. Fr. e. 32]"
+ witOrigDate: "1191-1220"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
diff --git a/corpus_stemmata/Rolin_1897_Aliscans2-Rainouart/metadata.txt b/corpus_stemmata/Rolin_1897_Aliscans2-Rainouart/metadata.txt
index 0a194eb6..5132ed6f 100644
--- a/corpus_stemmata/Rolin_1897_Aliscans2-Rainouart/metadata.txt
+++ b/corpus_stemmata/Rolin_1897_Aliscans2-Rainouart/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "LXIV"
publicationLink: "https://archive.org/stream/AliscansRolin1897/Aliscans_Rolin_1897#page/n71"
workTitle: "Aliscans, 2e partie (Rainouart)"
workViaf: "182731512"
-workOrigDate: ""
+workOrigDate: "1151-1200"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -25,92 +25,92 @@ contributorORCID: "0000-0003-0385-7037"
note: "Difficulté de lecture: r ou gamma? Le statut de H et H1 n'est pas absolument clair, mais il ne correspondent à aucun ms. conservé. Auquel cas, le stemma pourrait bien être une des plus anciennes représentations de contaminations extra-stemmatiques."
wits:
- witSigla: "M"
- witSignature: "Venedig"
+ witSignature: "Venedig [Venice, Biblioteca nazionale marciana, fr., Z. 8 (52)]"
witOrigDate: "1351-1400"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "f"
- witSignature: "Boulogne"
+ witSignature: "Boulogne [Boulogne-sur-Mer, Bibliothèque municipale, 192]"
witOrigDate: "1295"
- witOrigPlace: ""
- witNotes: ""
+ witOrigPlace: "Picardy or Paris"
+ witNotes: "Copy finished on 16/04/1295"
witMsDesc: ""
witDigit: ""
- witSigla: "L"
- witSignature: "London"
+ witSignature: "London [London, British library, Royal MS 20 D XI]"
witOrigDate: "1301-1350"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "a"
- witSignature: "Arsenal"
+ witSignature: "Arsenal [Paris, Bibliothèque nationale de France, Arsenal, Ms-6562]"
witOrigDate: "1221-1230"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "V"
- witSignature: "BN 24369"
+ witSignature: "BN 24369 [Paris, Bibliothèque nationale de France, français, 24369-24370]"
witOrigDate: "1301-1320"
- witOrigPlace: ""
+ witOrigPlace: "France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "B"
- witSignature: "BN 368"
+ witSignature: "BN 368 [Paris, Bibliothèque nationale de France, français, 368]"
witOrigDate: "1301-1313"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "C"
- witSignature: "Bern"
+ witSignature: "Bern [Bern, Bürgerbibliothek Bern, Cod. 296]"
witOrigDate: "1251-1300"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "A"
- witSignature: "BN 774"
+ witSignature: "BN 774 [Paris, Bibliothèque nationale de France, français, 774]"
witOrigDate: "1251-1300"
- witOrigPlace: ""
+ witOrigPlace: "Île-de-France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "d"
- witSignature: "BN 2494"
+ witSignature: "BN 2494 [Paris, Bibliothèque nationale de France, Français 2494]"
witOrigDate: "1226-1250"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "e"
- witSignature: "BN 1448"
+ witSignature: "BN 1448 [Paris, Bibliothèque nationale de France, français, 1448]"
witOrigDate: "1241-1260"
- witOrigPlace: ""
+ witOrigPlace: "Lorraine"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "T"
- witSignature: "Trivulziana"
- witOrigDate: "1267-1300"
- witOrigPlace: ""
+ witSignature: "Trivulziana [Milano, Biblioteca Trivulziana, 1025]"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "b"
- witSignature: "BN 1449"
- witOrigDate: "1241-1260"
- witOrigPlace: ""
+ witSignature: "BN 1449 [Paris, Bibliothèque nationale de France, français, 1449]"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
witNotes: ""
witMsDesc: ""
witDigit: ""
- witSigla: "P"
- witSignature: "Cheltenhamer Handschrift"
- witOrigDate: ""
+ witSignature: "Cheltenhamer Handschrift [Oxford, Bodleian Library, MS. Fr. e. 32]"
+ witOrigDate: "1191-1220"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
diff --git a/corpus_stemmata/Ruelle_1960_HuonBordeaux/metadata.txt b/corpus_stemmata/Ruelle_1960_HuonBordeaux/metadata.txt
index 24851832..b15403b1 100644
--- a/corpus_stemmata/Ruelle_1960_HuonBordeaux/metadata.txt
+++ b/corpus_stemmata/Ruelle_1960_HuonBordeaux/metadata.txt
@@ -10,7 +10,7 @@ publicationPage : "15"
publicationLink : ""
workTitle : "Huon de Bordeaux"
workViaf : "186718999"
-workOrigDate : "1260-1268"
+workOrigDate : "1181-1268"
workOrigPlace : "Picardy"
workAuthor : ""
workAuthorViaf : ""
@@ -22,7 +22,7 @@ extraStemmContam : "no"
rootType : "unspecified"
contributor : "Jean-Baptiste Camps"
contributorORCID : "0000-0003-0385-7037"
-note : "Decasyllabic version (also exists a version in alexandrins, and one in prose, that could be included in the stemma). At least one witness (b) is omitted."
+note : "Decasyllabic version (also exists a version in alexandrins, and one in prose, that could be included in the stemma). At least one witness (b) is omitted (Boston, Massachusetts Historical Society, ??, 1351-1400)."
wits:
- witSigla: "M"
witSignature: "BM Tours, 936"
@@ -45,10 +45,3 @@ wits:
witNotes: ""
witMsDesc: ""
witDigit: ""
- - witSigla: "b"
- witSignature: "Boston, Massachusetts Historical Society, ??"
- witOrigDate: ""
- witOrigPlace: ""
- witNotes: ""
- witMsDesc: "https://www.arlima.net/eh/huon_de_bordeaux.html"
- witDigit: ""
diff --git a/corpus_stemmata/Salverda_1888_Eneas/metadata.txt b/corpus_stemmata/Salverda_1888_Eneas/metadata.txt
index c39f1243..1b1275ec 100644
--- a/corpus_stemmata/Salverda_1888_Eneas/metadata.txt
+++ b/corpus_stemmata/Salverda_1888_Eneas/metadata.txt
@@ -10,7 +10,7 @@ publicationPage : "25"
publicationLink : ""
workTitle : "Roman d’Énéas"
workViaf : ""
-workOrigDate : ""
+workOrigDate : "1158-1162"
workOrigPlace : ""
workAuthor : ""
workAuthorViaf : ""
diff --git a/corpus_stemmata/Segre_1971_Roland/metadata.txt b/corpus_stemmata/Segre_1971_Roland/metadata.txt
index dfb06f91..9af6a737 100644
--- a/corpus_stemmata/Segre_1971_Roland/metadata.txt
+++ b/corpus_stemmata/Segre_1971_Roland/metadata.txt
@@ -20,3 +20,74 @@ extraStemmContam : "no"
rootType : "archetype"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
+wits:
+ - witSigla: "O"
+ witSignature: "Oxford, Bodleian Library, MS. Digby 23"
+ witOrigDate: "1126-1150"
+ witOrigPlace: "England"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B"
+ witSignature: "London, British library, Add MS 41295G"
+ witOrigDate: "1281-1300"
+ witOrigPlace: "Ouest"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "Châteauroux, Bibliothèque Municipale, 1"
+ witOrigDate: "1281-1300"
+ witOrigPlace: "francoit."
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "F"
+ witSignature: "Paris, Bibliothèque nationale de France, NAF 5237"
+ witOrigDate: "1201-1400"
+ witOrigPlace: "Lorraine"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "L"
+ witSignature: "Lyon, Bibliothèque municipale, Ms 743"
+ witOrigDate: "1201-1400"
+ witOrigPlace: "bourg."
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "l"
+ witSignature: "Paris, Bibliothèque nationale de France, NAF 14658"
+ witOrigDate: "1281-1300"
+ witOrigPlace: "lorr. -- lorr. fin 13es. -- Source: DÉAF"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "P"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 860"
+ witOrigDate: "1256-1295"
+ witOrigPlace: "lorr. sept. -- Lorraine ou Picardie (Laon?); lorr.sept. ca. 1275 (DÉAF)"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "T"
+ witSignature: "Cambridge, Trinity College, R.3.32"
+ witOrigDate: "1431-1500"
+ witOrigPlace: "Ouest -- Ouest après 1431 -- Source: DÉAF"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "V4"
+ witSignature: "Venice, Biblioteca nazionale marciana, fr., Z. 4"
+ witOrigDate: "1341-1360"
+ witOrigPlace: "francoit. – Nord de l'Italie"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "V7"
+ witSignature: "Venice, Biblioteca nazionale marciana, fr., Z. 7"
+ witOrigDate: "1241-1320"
+ witOrigPlace: "francoit. -- Vénétie (Italie)"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Thorpe_1992_Jerusalem/metadata.txt b/corpus_stemmata/Thorpe_1992_Jerusalem/metadata.txt
index 2d6c375d..d8a04895 100644
--- a/corpus_stemmata/Thorpe_1992_Jerusalem/metadata.txt
+++ b/corpus_stemmata/Thorpe_1992_Jerusalem/metadata.txt
@@ -90,7 +90,7 @@ wits:
witDigit: ""
- witSigla: "I"
witSignature: "London, British Library, Additional, 36615"
- witOrigDate: "1381-1320"
+ witOrigDate: "1296-1350"
witOrigPlace: "North-Eastern France or Normandy"
witNotes: "four scribes"
witMsDesc: ""
diff --git a/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/Tyssens_1967_BatailleLoquifer1.tei.xml b/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/Tyssens_1967_BatailleLoquifer1.tei.xml
new file mode 100644
index 00000000..3c209b28
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/Tyssens_1967_BatailleLoquifer1.tei.xml
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
+ Stemma of
+ Bataille Loquifer
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For this text, two stemmata are offered, presented as undecidable. O, the archetype, is supposed to be an already rewritten version, and not the original of the song. It is stated to be the same stemma as for the first part of the Moniage Rainouart (p. 280). C is described as having two sources: for the second part, _v_; for the first part a source older than _v_, but close to the one that _v_ used for its rewriting.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Bern
+ Burgerbibliothek
+ 296
+
+
+ 1251-1300
+
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, Arsenal, 6562
+ 1201-1225
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 2494
+ 1201-1300
+
+
+
+
+
+
+
+
+
+
+ Bataille Loquifer
+
+ 1201-1220
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ archetype
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/metadata.txt b/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/metadata.txt
index c07c6228..d52c4a3f 100644
--- a/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/metadata.txt
@@ -30,7 +30,7 @@ derivatives : "excluded"
contributors:
- contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
-note : "The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For this text, two stemmata are offered, presented as undecidable. O, the archetype, is supposed to be an already rewritten version, and not the original of the song. It is stated to be the same stemma as for the first part of the Moniage Rainouart (p. 280). C is described as having two sources, for the second part, _v_, for the second part a source older than _v_, but close to the one that _v_ used for its rewriting."
+note : "The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For this text, two stemmata are offered, presented as undecidable. O, the archetype, is supposed to be an already rewritten version, and not the original of the song. It is stated to be the same stemma as for the first part of the Moniage Rainouart (p. 280). C is described as having two sources: for the second part, _v_; for the first part a source older than _v_, but close to the one that _v_ used for its rewriting."
wits:
- witSigla: "A1"
witSignature: "Paris, Bibliothèque nationale de France, français, 774"
diff --git a/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/stemma.graphml b/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/stemma.graphml
new file mode 100644
index 00000000..c60d6a17
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_BatailleLoquifer1/stemma.graphml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/Tyssens_1967_BatailleLoquifer2.tei.xml b/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/Tyssens_1967_BatailleLoquifer2.tei.xml
new file mode 100644
index 00000000..7f3f9ed5
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/Tyssens_1967_BatailleLoquifer2.tei.xml
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
+ Stemma of
+ Bataille Loquifer
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For this text, two stemmata are offered, presented as undecidable. O, the archetype, is supposed to be an already rewritten version, and not the original of the song. It is stated to be the same stemma as for the first part of the Moniage Rainouart (p. 280). C is described as having two sources: for the second part, _v_; for the first part a source older than _v_, but close to the one that _v_ used for its rewriting.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Bern
+ Burgerbibliothek
+ 296
+
+
+ 1251-1300
+
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, Arsenal, 6562
+ 1201-1225
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 2494
+ 1201-1300
+
+
+
+
+
+
+
+
+
+
+ Bataille Loquifer
+
+ 1201-1220
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ archetype
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/metadata.txt b/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/metadata.txt
index c07c6228..d52c4a3f 100644
--- a/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/metadata.txt
@@ -30,7 +30,7 @@ derivatives : "excluded"
contributors:
- contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
-note : "The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For this text, two stemmata are offered, presented as undecidable. O, the archetype, is supposed to be an already rewritten version, and not the original of the song. It is stated to be the same stemma as for the first part of the Moniage Rainouart (p. 280). C is described as having two sources, for the second part, _v_, for the second part a source older than _v_, but close to the one that _v_ used for its rewriting."
+note : "The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For this text, two stemmata are offered, presented as undecidable. O, the archetype, is supposed to be an already rewritten version, and not the original of the song. It is stated to be the same stemma as for the first part of the Moniage Rainouart (p. 280). C is described as having two sources: for the second part, _v_; for the first part a source older than _v_, but close to the one that _v_ used for its rewriting."
wits:
- witSigla: "A1"
witSignature: "Paris, Bibliothèque nationale de France, français, 774"
diff --git a/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/stemma.graphml b/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/stemma.graphml
new file mode 100644
index 00000000..8a16ece4
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_BatailleLoquifer2/stemma.graphml
@@ -0,0 +1,125 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_CharroiNimes/Tyssens_1967_CharroiNimes.tei.xml b/corpus_stemmata/Tyssens_1967_CharroiNimes/Tyssens_1967_CharroiNimes.tei.xml
new file mode 100644
index 00000000..aae425f0
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_CharroiNimes/Tyssens_1967_CharroiNimes.tei.xml
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+ Stemma of
+ Charroi de Nîmes
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+
+
+
+ Charroi de Nîmes
+
+ 1101-1150
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ unspecified
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_CharroiNimes/metadata.txt b/corpus_stemmata/Tyssens_1967_CharroiNimes/metadata.txt
index 54c13e3c..ab00e8a1 100644
--- a/corpus_stemmata/Tyssens_1967_CharroiNimes/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_CharroiNimes/metadata.txt
@@ -81,13 +81,6 @@ wits:
witNotes: ""
witMsDesc: ""
witDigit: ""
- - witSigla: "E"
- witSignature: "Bern, Burgerbibliothek, 296"
- witOrigDate: "1251-1300"
- witOrigPlace: ""
- witNotes: ""
- witMsDesc: ""
- witDigit: ""
- witSigla: "C"
witSignature: "Boulogne-sur-Mer, Bibliothèque municipale, 192"
witOrigDate: "1295"
@@ -95,10 +88,3 @@ wits:
witNotes: "Copy finished on 16/04/1295"
witMsDesc: ""
witDigit: ""
- - witSigla: "ars"
- witSignature: "Paris, Bibliothèque nationale de France, Arsenal, 6562"
- witOrigDate: "1201-1225"
- witOrigPlace: ""
- witNotes: ""
- witMsDesc: ""
- witDigit: ""
diff --git a/corpus_stemmata/Tyssens_1967_CharroiNimes/stemma.graphml b/corpus_stemmata/Tyssens_1967_CharroiNimes/stemma.graphml
new file mode 100644
index 00000000..1ba69c84
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_CharroiNimes/stemma.graphml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_ChevVivien/Tyssens_1967_ChevVivien.tei.xml b/corpus_stemmata/Tyssens_1967_ChevVivien/Tyssens_1967_ChevVivien.tei.xml
new file mode 100644
index 00000000..80978079
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_ChevVivien/Tyssens_1967_ChevVivien.tei.xml
@@ -0,0 +1,261 @@
+
+
+
+
+
+
+
+ Stemma of
+ Chevalerie Vivien
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. The stemma for this text is based on Terracher 1909 (reprinted here p. 230), with modifications/simplification for the relationship inside the descendants of O2.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ Oxford, Bodleian Library, French, e. 32
+ 1201-1220
+
+ Olim Savile manuscript (and before, Sir Thomas Philipps); was not used by Tyssens. Contains only Chevalerie Vivien and Aliscans
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Bern
+ Burgerbibliothek
+ 296
+
+
+ 1251-1300
+
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+
+
+
+ Chevalerie Vivien
+
+ 1181-1220
+
+
+
+
+ chanson de geste
+ reconstructed
+ yes
+ no
+ original
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_ChevVivien/stemma.graphml b/corpus_stemmata/Tyssens_1967_ChevVivien/stemma.graphml
new file mode 100644
index 00000000..96c62f73
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_ChevVivien/stemma.graphml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ contamination
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_CourLouis/Tyssens_1967_CourLouis.tei.xml b/corpus_stemmata/Tyssens_1967_CourLouis/Tyssens_1967_CourLouis.tei.xml
new file mode 100644
index 00000000..7e9b46a7
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_CourLouis/Tyssens_1967_CourLouis.tei.xml
@@ -0,0 +1,237 @@
+
+
+
+
+
+
+
+ Stemma of
+ Couronnement de Louis
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. Four stemma are suggested on this page, then the fourth one is retained (and is encoded here).
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, nouvelles acquisitions françaises, 5094 + Mulhouse, Hoepffner fragment
+
+ Picardy
+ The Mulhouse fragment current localisation is unknown. In its current state, contains only a portion of the Couronnement de Louis
+
+
+
+
+
+
+
+
+ Couronnement de Louis
+
+ 1101-1200
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ original
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_CourLouis/metadata.txt b/corpus_stemmata/Tyssens_1967_CourLouis/metadata.txt
index 4836e23b..dd8eb138 100644
--- a/corpus_stemmata/Tyssens_1967_CourLouis/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_CourLouis/metadata.txt
@@ -30,7 +30,7 @@ derivatives : "excluded"
contributors:
- contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
-note : "The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377."
+note : "The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. Four stemma are suggested on this page, then the fourth one is retained (and is encoded here)."
wits:
- witSigla: "A1"
witSignature: "Paris, Bibliothèque nationale de France, français, 774"
diff --git a/corpus_stemmata/Tyssens_1967_CourLouis/stemma.graphml b/corpus_stemmata/Tyssens_1967_CourLouis/stemma.graphml
new file mode 100644
index 00000000..a498a275
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_CourLouis/stemma.graphml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ low
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_EnfGuillaume/Tyssens_1967_EnfGuillaume.tei.xml b/corpus_stemmata/Tyssens_1967_EnfGuillaume/Tyssens_1967_EnfGuillaume.tei.xml
new file mode 100644
index 00000000..098af328
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_EnfGuillaume/Tyssens_1967_EnfGuillaume.tei.xml
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+ Stemma of
+ Enfances Guillaume
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the fragment Aberystwyth, National Library of Wales, 5043E. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. Three stemmata are drawn, but the author then states that the argument to link C and D are weak, so the third one is retained here.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+
+
+
+ Enfances Guillaume
+
+ 1181-1220
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ original
+ true
+ NA
+ NA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_EnfGuillaume/metadata.txt b/corpus_stemmata/Tyssens_1967_EnfGuillaume/metadata.txt
index 8c4f93cc..3859e52a 100644
--- a/corpus_stemmata/Tyssens_1967_EnfGuillaume/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_EnfGuillaume/metadata.txt
@@ -8,11 +8,11 @@ publicationNum: "178"
publicationStemmaNum: ""
publicationAuthors:
- publicationAuthor: "Tyssens, Madeleine"
-publicationPage : "187"
+publicationPage : "72"
publicationLink : ""
-workTitle : "Enfances Vivien"
+workTitle : "Enfances Guillaume"
workViaf : ""
-workOrigDate : "1267-1300"
+workOrigDate : "1181-1220"
workOrigPlace : ""
workAuthors:
- workAuthor: ""
@@ -24,13 +24,13 @@ drawnStemma : "true"
contam : "no"
extraStemmContam : "no"
rootType : "original"
-completeWits : "included"
+completeWits : "selected"
sourceText : "NA"
-derivatives : "excluded"
+derivatives : "NA"
contributors:
- contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
-note : "The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For the Enfances Vivien, the stemma is based on Nordfelt's stemma, with some adaptations given in the text, based on a reexamination of the tradition, and the discussion (in the following chapter) of Terracher's stemma of the Chevalerie Vivien. The encoding accounts for the modification given in the text."
+note : "The witnesses included are mostly complete with the exception of the fragment Aberystwyth, National Library of Wales, 5043E. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. Three stemmata are drawn, but the author then states that the argument to link C and D are weak, so the third one is retained here."
wits:
- witSigla: "A1"
witSignature: "Paris, Bibliothèque nationale de France, français, 774"
diff --git a/corpus_stemmata/Tyssens_1967_EnfGuillaume/stemma.graphml b/corpus_stemmata/Tyssens_1967_EnfGuillaume/stemma.graphml
new file mode 100644
index 00000000..1ba69c84
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_EnfGuillaume/stemma.graphml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_EnfVivien/Tyssens_1967_EnfVivien.tei.xml b/corpus_stemmata/Tyssens_1967_EnfVivien/Tyssens_1967_EnfVivien.tei.xml
new file mode 100644
index 00000000..b510cb71
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_EnfVivien/Tyssens_1967_EnfVivien.tei.xml
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+ Stemma of
+ Enfances Vivien
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For the Enfances Vivien, the stemma is based on Nordfelt's stemma, with some adaptations given in the text, based on a reexamination of the tradition, and the discussion (in the following chapter) of Terracher's stemma of the Chevalerie Vivien. The encoding accounts for the modification given in the text.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+
+
+
+ Enfances Vivien
+
+ 1267-1300
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ original
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_EnfVivien/metadata.txt b/corpus_stemmata/Tyssens_1967_EnfVivien/metadata.txt
index 0591d004..680b360d 100644
--- a/corpus_stemmata/Tyssens_1967_EnfVivien/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_EnfVivien/metadata.txt
@@ -8,11 +8,11 @@ publicationNum: "178"
publicationStemmaNum: ""
publicationAuthors:
- publicationAuthor: "Tyssens, Madeleine"
-publicationPage : ""
+publicationPage : "187"
publicationLink : ""
-workTitle : "Aliscans"
+workTitle : "Enfances Vivien"
workViaf : ""
-workOrigDate : ""
+workOrigDate : "1201-1300"
workOrigPlace : ""
workAuthors:
- workAuthor: ""
@@ -24,13 +24,13 @@ drawnStemma : "true"
contam : "no"
extraStemmContam : "no"
rootType : "original"
-completeWits : "selected"
+completeWits : "included"
sourceText : "NA"
-derivatives : "NA"
+derivatives : "excluded"
contributors:
- contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
-note : "The witnesses included are mostly complete with the exception of the fragment Aberystwyth, National Library of Wales, 5043E. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377."
+note : "The witnesses included are mostly complete with the exception of the fragments and the Oxford manuscript. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. For the Enfances Vivien, the stemma is based on Nordfelt's stemma, with some adaptations given in the text, based on a reexamination of the tradition, and the discussion (in the following chapter) of Terracher's stemma of the Chevalerie Vivien. The encoding accounts for the modification given in the text."
wits:
- witSigla: "A1"
witSignature: "Paris, Bibliothèque nationale de France, français, 774"
diff --git a/corpus_stemmata/Tyssens_1967_EnfVivien/stemma.graphml b/corpus_stemmata/Tyssens_1967_EnfVivien/stemma.graphml
new file mode 100644
index 00000000..370c87df
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_EnfVivien/stemma.graphml
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ contamination
+ low
+ none
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_Guillaume/Tyssens_1967_Guillaume.tei.xml b/corpus_stemmata/Tyssens_1967_Guillaume/Tyssens_1967_Guillaume.tei.xml
index b6da56fb..8b41344b 100644
--- a/corpus_stemmata/Tyssens_1967_Guillaume/Tyssens_1967_Guillaume.tei.xml
+++ b/corpus_stemmata/Tyssens_1967_Guillaume/Tyssens_1967_Guillaume.tei.xml
@@ -52,7 +52,7 @@
- Chanson de geste
+ chanson de geste
reconstructed
no
no
diff --git a/corpus_stemmata/Tyssens_1967_Guillaume/metadata.txt b/corpus_stemmata/Tyssens_1967_Guillaume/metadata.txt
index 7b2a862f..df7f1f33 100644
--- a/corpus_stemmata/Tyssens_1967_Guillaume/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_Guillaume/metadata.txt
@@ -13,7 +13,7 @@ publicationPage : "339"
publicationLink : "https://www.persee.fr/doc/ccmed_0007-9731_1972_num_15_60_1930_t1_0336_0000_2"
workTitle : "Cycle de Guillaume d'Orange"
workViaf : ""
-workOrigDate : ""
+workOrigDate : "1101-1300"
workOrigPlace : ""
workAuthors:
- workAuthor: ""
@@ -33,10 +33,66 @@ contributors:
contributorORCID: ""
note : "The drawn stemma is extracted from ‘La geste de Guillaume d’Orange dans les manuscrits cycliques [compte-rendu]’ by McMillan"
wits:
- - witSigla: ""
- witSignature: ""
- witOrigDate: ""
+ - witSigla: "A1"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 774"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A2 and A4"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "A2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1449"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A1 and A4"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "A3"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 368"
+ witOrigDate: "1301-1313"
witOrigPlace: ""
witNotes: ""
witMsDesc: ""
witDigit: ""
+ - witSigla: "A4"
+ witSignature: "Milano, Biblioteca Trivulziana, 1025"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: "Same workshop as A1 and A2"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B1"
+ witSignature: "London, British Library, Royal, 20. D. XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: "France"
+ witNotes: "Same workshop as B2"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 24369-24370"
+ witOrigDate: "1301-1320"
+ witOrigPlace: "France"
+ witNotes: "Same workshop as B1"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1448"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "Lorraine"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C"
+ witSignature: "Boulogne-sur-Mer, Bibliothèque municipale, 192"
+ witOrigDate: "1295"
+ witOrigPlace: "Picardy or Paris"
+ witNotes: "Copy finished on 16/04/1295"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "E"
+ witSignature: "Bern, Burgerbibliothek, 296"
+ witOrigDate: "1251-1300"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/Tyssens_1967_MoniageGuillaume-RedII.tei.xml b/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/Tyssens_1967_MoniageGuillaume-RedII.tei.xml
new file mode 100644
index 00000000..3a792a7b
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/Tyssens_1967_MoniageGuillaume-RedII.tei.xml
@@ -0,0 +1,230 @@
+
+
+
+
+
+
+
+ Stemma of
+ Moniage Guillaume (redaction 2)
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. This stemma is only for Redaction II, and omits the witnesses of Redaction I (Ars and C, and two others not included witnesses, cf. Jonas), that would constitute another branch entirely (as is the case, for instance, for Bataille Loquifer). Cloetta, who serves as base, postulated that the prose version had a direct common ancestor with B. With these indications, it would theoretically be possible to build a stemma including both verse redactions and the prose one, having as root the lost Moniage from which both kept redactions derived.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+
+
+ Bern
+ Burgerbibliothek
+ 296
+
+
+ 1251-1300
+
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+
+
+
+ Moniage Guillaume (redaction 2)
+
+ 1180
+ Southern Picardy
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ archetype
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/metadata.txt b/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/metadata.txt
index 85b512a0..e5cf5da3 100644
--- a/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/metadata.txt
+++ b/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/metadata.txt
@@ -10,7 +10,7 @@ publicationAuthors:
- publicationAuthor: "Tyssens, Madeleine"
publicationPage : "323"
publicationLink : ""
-workTitle : "Moniage Guillaume"
+workTitle : "Moniage Guillaume (redaction 2)"
workViaf : ""
workOrigDate : "1180"
workOrigPlace : "Southern Picardy"
diff --git a/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/stemma.graphml b/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/stemma.graphml
new file mode 100644
index 00000000..a81b6557
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_MoniageGuillaume-RedII/stemma.graphml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_MoniageRainouart1/Tyssens_1967_MoniageRainouart1.tei.xml b/corpus_stemmata/Tyssens_1967_MoniageRainouart1/Tyssens_1967_MoniageRainouart1.tei.xml
new file mode 100644
index 00000000..155b507a
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_MoniageRainouart1/Tyssens_1967_MoniageRainouart1.tei.xml
@@ -0,0 +1,264 @@
+
+
+
+
+
+
+
+ Stemma of
+ Moniage Rainouart
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the fragments St-Petersbourg and NAF 934. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. Two stemmata are offered, as undecidable.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Bern
+ Burgerbibliothek
+ 296
+
+
+ 1251-1300
+
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, Arsenal, 6562
+ 1201-1225
+
+
+
+
+
+
+
+
+
+
+ Moniage Rainouart
+
+ 1181-1220
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ unspecified
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_MoniageRainouart1/stemma.graphml b/corpus_stemmata/Tyssens_1967_MoniageRainouart1/stemma.graphml
new file mode 100644
index 00000000..f72054d1
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_MoniageRainouart1/stemma.graphml
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_MoniageRainouart2/Tyssens_1967_MoniageRainouart2.tei.xml b/corpus_stemmata/Tyssens_1967_MoniageRainouart2/Tyssens_1967_MoniageRainouart2.tei.xml
new file mode 100644
index 00000000..49034129
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_MoniageRainouart2/Tyssens_1967_MoniageRainouart2.tei.xml
@@ -0,0 +1,260 @@
+
+
+
+
+
+
+
+ Stemma of
+ Moniage Rainouart
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The witnesses included are mostly complete with the exception of the fragments St-Petersbourg and NAF 934. The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377. Two stemmata are offered, as undecidable.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Bern
+ Burgerbibliothek
+ 296
+
+
+ 1251-1300
+
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, Arsenal, 6562
+ 1201-1225
+
+
+
+
+
+
+
+
+
+
+ Moniage Rainouart
+
+ 1181-1220
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ unspecified
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_MoniageRainouart2/stemma.graphml b/corpus_stemmata/Tyssens_1967_MoniageRainouart2/stemma.graphml
new file mode 100644
index 00000000..3f3c7677
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_MoniageRainouart2/stemma.graphml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/Tyssens_1967_PriseOrange/Tyssens_1967_PriseOrange.tei.xml b/corpus_stemmata/Tyssens_1967_PriseOrange/Tyssens_1967_PriseOrange.tei.xml
new file mode 100644
index 00000000..a24d04ed
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_PriseOrange/Tyssens_1967_PriseOrange.tei.xml
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+ Stemma of
+ Prise d'Orange
+ Tyssens, Madeleine
+
+ contributed to OpenStemmata by
+ Jean-Baptiste Camps
+
+
+
+
+ Openstemmata
+
+
+
+
+
+ CC BY
+
+
+
+ The details about the structure of the descendants of A are given independently p. 356 in the text; p. 367 for B1 and B2; for C and C2, p. 377.
+
+
+
+ La Geste de Guillaume d’Orange dans les manuscrits cycliques
+ Tyssens, Madeleine
+ 1967
+ Paris
+ Bibliothèque de la Faculté de philosophie et lettres de l’Université de Liège
+
+
+
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 774
+ 1251-1300
+ Île-de-France
+ Same workshop as A2 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1449
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A4
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 368
+ 1301-1313
+
+
+
+
+
+
+
+
+
+ Milano
+ Biblioteca Trivulziana
+ 1025
+
+
+ 1251-1300
+ Île-de-France
+ Same workshop as A1 and A2
+
+
+
+
+
+ London, British Library, Royal, 20. D. XI
+ 1301-1350
+ France
+ Same workshop as B2
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 24369-24370
+ 1301-1320
+ France
+ Same workshop as B1
+
+
+
+
+
+ Paris, Bibliothèque nationale de France, français, 1448
+ 1241-1260
+ Lorraine
+
+
+
+
+
+
+
+
+ Bern
+ Burgerbibliothek
+ 296
+
+
+ 1251-1300
+
+
+
+
+
+
+
+
+
+ Boulogne-sur-Mer
+ Bibliothèque municipale
+ 192
+
+
+ 1295
+ Picardy or Paris
+ Copy finished on 16/04/1295
+
+
+
+
+
+
+
+
+ Prise d'Orange
+
+ 1181-1220
+
+
+
+
+ chanson de geste
+ reconstructed
+ no
+ no
+ original
+ true
+ NA
+ excluded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/corpus_stemmata/Tyssens_1967_PriseOrange/stemma.graphml b/corpus_stemmata/Tyssens_1967_PriseOrange/stemma.graphml
new file mode 100644
index 00000000..b0839790
--- /dev/null
+++ b/corpus_stemmata/Tyssens_1967_PriseOrange/stemma.graphml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+
+
+ grey
+ A'
+
+
+ grey
+
+
+
+
+
+
+
+
+
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
+ filiation
+ unknown
+
+
\ No newline at end of file
diff --git a/corpus_stemmata/VanEmden_1977_GirViane/metadata.txt b/corpus_stemmata/VanEmden_1977_GirViane/metadata.txt
index b2db9ea3..d117e337 100644
--- a/corpus_stemmata/VanEmden_1977_GirViane/metadata.txt
+++ b/corpus_stemmata/VanEmden_1977_GirViane/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "LXIII"
publicationLink: ""
workTitle: "Girart de Vienne"
workViaf: "2146522337332391758"
-workOrigDate: ""
+workOrigDate: "1181-1220"
workOrigPlace: ""
workAuthor: "Bertrant de Bar-sur-Aube"
workAuthorViaf: "61541851"
@@ -23,3 +23,39 @@ rootType: "original"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: "plusieurs stemmata, car S change de famille pour le début et la fin du texte"
+wits:
+ - witSigla: "B"
+ witSignature: "London, British library, Royal MS 20 D XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: "traits pic., prob. Paris"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 1448"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "Lorraine Sud"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "G"
+ witSignature: "London, British library, Royal MS 20 B XIX"
+ witOrigDate: "1281-1300"
+ witOrigPlace: "traits bourg."
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "H"
+ witSignature: "London, British library, Harley MS 1321"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "traits norm.or."
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "S"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 1374"
+ witOrigDate: "1201-1250"
+ witOrigPlace: "frpr. / Sud et/ou ouest de la France (Bourgogne ou Lyonnais?) "
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Vietor_1876_Loherains/metadata.txt b/corpus_stemmata/Vietor_1876_Loherains/metadata.txt
index 2b4738e0..391eefce 100644
--- a/corpus_stemmata/Vietor_1876_Loherains/metadata.txt
+++ b/corpus_stemmata/Vietor_1876_Loherains/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "32"
publicationLink: "https://archive.org/details/DieHandschriftenDerGesteDesLoherain/page/n47"
workTitle: "Geste des Loherains"
workViaf: "177917250"
-workOrigDate: ""
+workOrigDate: "1121-1250"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
diff --git "a/corpus_stemmata/Wallensk\303\266ld_1909_Florence/metadata.txt" "b/corpus_stemmata/Wallensk\303\266ld_1909_Florence/metadata.txt"
index 671495a1..4062e0b4 100644
--- "a/corpus_stemmata/Wallensk\303\266ld_1909_Florence/metadata.txt"
+++ "b/corpus_stemmata/Wallensk\303\266ld_1909_Florence/metadata.txt"
@@ -10,7 +10,7 @@ publicationPage: "26"
publicationLink: "https://archive.org/details/florencederome01wall/page/26"
workTitle: "Florence de Rome"
workViaf: "35159474046127660877"
-workOrigDate: "1201-1225"
+workOrigDate: "1181-1225"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -23,3 +23,53 @@ rootType: "original"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: "Many stemmata, representing differents steps of the work on the genealogy, and competing hypotheses. Only the last one, retained here, is the final stemma retained by the editor."
+wits:
+ - witSigla: "P"
+ witSignature: "Paris, Bibliothèque nationale de France, NAF 4192"
+ witOrigDate: "1281-1300"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "M"
+ witSignature: "[Cologny, Fondation Martin Bodmer, Cod. Bodmer 67]"
+ witOrigDate: "1251-1300"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "L"
+ witSignature: "London, British library, Lansdowne MS 362"
+ witOrigDate: "1301-1400"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D"
+ witSignature: "Dit de Flourence de Rome"
+ witOrigDate: "1301-1350"
+ witOrigPlace: ""
+ witNotes: "Remaniement"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "Q"
+ witSignature: "Paris, Bibliothèque nationale de France, Français 24384"
+ witOrigDate: "1456"
+ witOrigPlace: ""
+ witNotes: "Remaniement"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "R"
+ witSignature: "Le Bone Florence of Rome"
+ witOrigDate: "1351-1425"
+ witOrigPlace: ""
+ witNotes: "English translation"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "S"
+ witSignature: ""
+ witOrigDate: ""
+ witOrigPlace: ""
+ witNotes: "Spanish translation"
+ witMsDesc: ""
+ witDigit: ""
diff --git a/corpus_stemmata/Zorn_1908_EnfViv/metadata.txt b/corpus_stemmata/Zorn_1908_EnfViv/metadata.txt
index e2008a05..1474244f 100644
--- a/corpus_stemmata/Zorn_1908_EnfViv/metadata.txt
+++ b/corpus_stemmata/Zorn_1908_EnfViv/metadata.txt
@@ -10,7 +10,7 @@ publicationPage: "2"
publicationLink: "https://archive.org/stream/EnfancesVivienZorn/Die_Enfances_Vivien#page/n9"
workTitle: "Enfances Vivien"
workViaf: "182450584"
-workOrigDate: ""
+workOrigDate: "1201-1300"
workOrigPlace: ""
workAuthor: ""
workAuthorViaf: ""
@@ -23,3 +23,61 @@ rootType: "archetype"
contributor: "Jean-Baptiste Camps"
contributorORCID: "0000-0003-0385-7037"
note: "stemma p. 2 (redondances autres textes cycle Guillaume)"
+wits:
+ - witSigla: "A"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1448"
+ witOrigDate: "1241-1260"
+ witOrigPlace: "Lorraine"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "B"
+ witSignature: "Boulogne-sur-Mer, Bibliothèque municipale, 192"
+ witOrigDate: "1295"
+ witOrigPlace: "Picardy or Paris"
+ witNotes: "Copy finished on 16/04/1295"
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C1"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 1449"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 368"
+ witOrigDate: "1301-1313"
+ witOrigPlace: ""
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C3"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 774"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "C4"
+ witSignature: "Milano, Biblioteca Trivulziana, 1025"
+ witOrigDate: "1251-1300"
+ witOrigPlace: "Île-de-France"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D1"
+ witSignature: "London, British Library, Royal, 20. D. XI"
+ witOrigDate: "1301-1350"
+ witOrigPlace: "France"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+ - witSigla: "D2"
+ witSignature: "Paris, Bibliothèque nationale de France, français, 24369-24370"
+ witOrigDate: "1301-1320"
+ witOrigPlace: "France"
+ witNotes: ""
+ witMsDesc: ""
+ witDigit: ""
+
diff --git a/loss_summary_model_124.pdf b/loss_summary_model_124.pdf
new file mode 100644
index 00000000..aee75c23
Binary files /dev/null and b/loss_summary_model_124.pdf differ
diff --git a/loss_summary_model_124.png b/loss_summary_model_124.png
new file mode 100644
index 00000000..5ac31421
Binary files /dev/null and b/loss_summary_model_124.png differ
diff --git a/loss_summary_model_1947.pdf b/loss_summary_model_1947.pdf
new file mode 100644
index 00000000..7efb89ba
Binary files /dev/null and b/loss_summary_model_1947.pdf differ
diff --git a/loss_summary_model_43.pdf b/loss_summary_model_43.pdf
new file mode 100644
index 00000000..3e42eaf4
Binary files /dev/null and b/loss_summary_model_43.pdf differ
diff --git a/loss_summary_model_43.png b/loss_summary_model_43.png
new file mode 100644
index 00000000..8824c43a
Binary files /dev/null and b/loss_summary_model_43.png differ
diff --git a/loss_summary_model_457.pdf b/loss_summary_model_457.pdf
new file mode 100644
index 00000000..21634d8e
Binary files /dev/null and b/loss_summary_model_457.pdf differ
diff --git a/loss_summary_model_809.pdf b/loss_summary_model_809.pdf
new file mode 100644
index 00000000..5a81d771
Binary files /dev/null and b/loss_summary_model_809.pdf differ
diff --git a/pairplot_highres.pdf b/pairplot_highres.pdf
new file mode 100644
index 00000000..f3f488a7
Binary files /dev/null and b/pairplot_highres.pdf differ
diff --git a/pairplot_highres.png b/pairplot_highres.png
new file mode 100644
index 00000000..a2db7047
Binary files /dev/null and b/pairplot_highres.png differ
diff --git a/pairplot_highres_bench123.pdf b/pairplot_highres_bench123.pdf
new file mode 100644
index 00000000..944e04e4
Binary files /dev/null and b/pairplot_highres_bench123.pdf differ
diff --git a/pairplot_highres_bench1946.pdf b/pairplot_highres_bench1946.pdf
new file mode 100644
index 00000000..7a36af1d
Binary files /dev/null and b/pairplot_highres_bench1946.pdf differ
diff --git a/pairplot_highres_bench42.pdf b/pairplot_highres_bench42.pdf
new file mode 100644
index 00000000..ab21032d
Binary files /dev/null and b/pairplot_highres_bench42.pdf differ
diff --git a/pairplot_highres_bench456.pdf b/pairplot_highres_bench456.pdf
new file mode 100644
index 00000000..fc0796f1
Binary files /dev/null and b/pairplot_highres_bench456.pdf differ
diff --git a/pairplot_highres_bench808.pdf b/pairplot_highres_bench808.pdf
new file mode 100644
index 00000000..af401d9c
Binary files /dev/null and b/pairplot_highres_bench808.pdf differ
diff --git a/pairplot_highres_run3.pdf b/pairplot_highres_run3.pdf
new file mode 100644
index 00000000..4e956399
Binary files /dev/null and b/pairplot_highres_run3.pdf differ
diff --git a/pairplot_highres_run3.png b/pairplot_highres_run3.png
new file mode 100644
index 00000000..03d3d74f
Binary files /dev/null and b/pairplot_highres_run3.png differ
diff --git a/pairplot_highres_server.pdf b/pairplot_highres_server.pdf
new file mode 100644
index 00000000..a376f486
Binary files /dev/null and b/pairplot_highres_server.pdf differ
diff --git a/pairplot_highres_server.png b/pairplot_highres_server.png
new file mode 100644
index 00000000..ba0b3916
Binary files /dev/null and b/pairplot_highres_server.png differ
diff --git a/plot_results.py b/plot_results.py
new file mode 100644
index 00000000..859e0c78
--- /dev/null
+++ b/plot_results.py
@@ -0,0 +1,371 @@
+import random
+import torch
+import numpy as np
+import matplotlib.pyplot as plt
+import networkx as nx
+import birth_death_utils as bd
+import os
+from collections import Counter
+from tqdm.notebook import tqdm
+import pickle
+from itertools import groupby
+import pandas as pd
+import yaml
+import re
+import multiprocessing as mp
+import seaborn as sns
+
+from sbi.analysis import pairplot
+from sbi.inference import NPE, simulate_for_sbi, NLE
+from sbi.utils import BoxUniform
+
+from sbi.utils.user_input_checks import (
+ check_sbi_inputs,
+ process_prior,
+ process_simulator,
+)
+
+from torch import Tensor
+
+def compute_summary_stats(g):
+ """
+ Generate a vector of summary statistics from a graph generated by birth-death simulation
+
+ Parameters
+ ----------
+ g : nx.DiGraph()
+ tree graph generated by birth_death_utils.ct_bd_tree
+
+ Returns
+ -------
+ list
+ vector of summary statistics characterizing a single tradition
+ """
+ n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)
+
+ if n_living == 0:
+ return None
+
+ if n_living == 1:
+ return [1,0, -1,-1,-1,-1,-1,-1,-1]
+
+ if n_living == 2:
+ birth_times_trad = []
+ for n in g.nodes():
+ if g.nodes[n]['state']:
+ birth_times_trad.append(g.nodes[n]['birth_time'])
+ timelapse = int(max(birth_times_trad)-min(birth_times_trad))
+ return [2, timelapse, -1,-1,-1,-1,-1,-1,-1]
+
+ if n_living >= 3:
+ birth_times_trad = []
+ degrees = []
+ direct_filiation_nb = 0
+ arch_dists = []
+ st = bd.generate_stemma(g)
+ archetype = bd.root(st)
+
+ for n in st.nodes():
+ degrees.append(st.out_degree(n))
+
+ if n != archetype:
+ father = list(st.predecessors(n))[0]
+ if st.nodes[n]['state'] and st.nodes[father]['state']:
+ direct_filiation_nb +=1
+ if st.nodes[n]['state']:
+ birth_times_trad.append(st.nodes[n]['birth_time'])
+ arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))
+
+ timelapse = int(max(birth_times_trad)-min(birth_times_trad))
+ deg_dist = Counter(degrees)
+ deg1 = deg_dist[1]
+ deg2 = deg_dist[2]
+ deg3 = deg_dist[3]
+ deg4 = deg_dist[4]
+ depth = max(arch_dists)
+ n_nodes = len(list(st.nodes()))
+
+ return [
+ n_living,
+ timelapse,
+ n_nodes,
+ direct_filiation_nb,
+ deg1,
+ deg2,
+ deg3,
+ deg4,
+ depth
+ ]
+
+def convert_date(x):
+ pattern1 = re.compile('[0-9][0-9][0-9][0-9]')
+ pattern2 = re.compile('[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
+
+ if bool(pattern1.fullmatch(x)):
+ return int(x)
+ if bool(pattern2.fullmatch(x)):
+ xx = x.split('-')
+ return (int(xx[0]),int(xx[1]))
+
+def top(x):
+ '''
+ Upper bound on witness date (single year or range)
+ '''
+ match x:
+ case (x1, x2):
+ return x2
+ case _:
+ return x
+
+def bottom(x):
+ '''
+ Lower bound on witness date (single year or range)
+ '''
+ match x:
+ case (x1, x2):
+ return x1
+ case _:
+ return x
+
+
+def expected_abs_diff_degenerate(c, a, b):
+ '''
+ Returns the expectation value of the timelapse between one date given as range
+ and one other as a single year
+ '''
+ if a == b:
+ return abs(a - c)
+ if a <= c <= b:
+ return ((c-a)**2 + (b-c)**2) / (2*(b-a))
+ elif c < a:
+ return (a+b)/2 - c
+ else:
+ return c - (a+b)/2
+
+def expected_abs_diff(a, b, c, d):
+ '''
+ Return the expectation value of the timelapse between two dates given as
+ intervals
+ '''
+ if a == b:
+ return expected_abs_diff_degenerate(a, c, d)
+ if c == d:
+ return expected_abs_diff_degenerate(c, a, b)
+ elif a < b < c < d:
+ return (c+d-b-a)/2
+ elif a <= c <= d < b:
+ return (1/(b-a)) * ((1/2)*((d-a)*(c-a)+(b-d)*(b-c)) + (1/3)*(d-c)**2)
+ elif a <= c <= b <= d:
+ return (1/(b-a)) * ((1/2)* ((c-a)*(d-a) + (b-c)*(d-b)) + (1/(3*(d-c)))*(b-c)**3 )
+ else:
+ print(f"{a},{b} -- {c},{d} ")
+ raise ValueError("Must have a < b, c < d, and a < c")
+
+wholeCorpus = {}
+corpus_dates = {}
+for work in os.listdir(f'corpus_stemmata/'):
+ print(f'{work}')
+ st = bd.load_from_OpenStemmata(f'corpus_stemmata/{work}/stemma.gv')
+ with open(f"corpus_stemmata/{work}/metadata.txt", 'r') as f:
+ content = f.read()
+ metadata = yaml.safe_load(content)
+ if "wits" in metadata:
+ dates = [wit["witOrigDate"] for wit in metadata['wits'] if wit["witOrigDate"] != '']
+ else:
+ dates = []
+
+ dates_num = []
+ for x in dates:
+ if x != '':
+ date_num = convert_date(x)
+ if date_num != None:
+ dates_num.append(date_num)
+
+ wholeCorpus[f"{work}"] = st
+ corpus_dates[f"{work}"] = dates_num
+
+ranges_per_work = {}
+for work, t_dates in corpus_dates.items():
+ if t_dates != []:
+ lb = sorted(t_dates, key=bottom)[0]
+ ub = sorted(t_dates, key=top)[-1]
+ ranges_per_work[work] = (lb,ub)
+
+
+lifespans = {}
+for w,v in ranges_per_work.items():
+ match v:
+ case [(a,b), (c,d)]:
+ lifespans[w] = expected_abs_diff(a,b,c,d)
+ case [(a,b), c]:
+ lifespans[w] = expected_abs_diff_degenerate(a,b,c)
+ case [c,(a,b)]:
+ lifespans[w] = expected_abs_diff_degenerate(a,b,c)
+ case [a,b]:
+ lifespans[w] = abs(a-b)
+ case _:
+ print('error')
+
+x_obs0 = {}
+sizes = {}
+for k in lifespans.keys():
+ ## computation of observables
+ g = wholeCorpus[k]
+
+ n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)
+ sizes[k] = n_living
+ degrees = []
+ direct_filiation_nb = 0
+ arch_dists = []
+
+ if n_living >= 3:
+ st = bd.generate_stemma(g)
+ archetype = bd.root(st)
+ for n in st.nodes():
+ degrees.append(st.out_degree(n))
+
+ if n != archetype:
+ father = list(st.predecessors(n))[0]
+ if st.nodes[n]['state'] and st.nodes[father]['state']:
+ direct_filiation_nb +=1
+ arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))
+
+ timelapse = lifespans[k]
+ deg_dist = Counter(degrees)
+ deg1 = deg_dist[1]
+ deg2 = deg_dist[2]
+ deg3 = deg_dist[3]
+ deg4 = deg_dist[4]
+ depth = max(arch_dists)
+ n_nodes = len(list(st.nodes()))
+
+ x_obs0[k] = [
+ n_living,
+ 4*int(timelapse),
+ n_nodes,
+ direct_filiation_nb,
+ deg1,
+ deg2,
+ deg3,
+ deg4,
+ depth
+ ]
+df = pd.read_csv("Old_French_witnesses.csv")
+f2_works = []
+f1_works = []
+works = set(list(df['text H-ID']))
+size_frags_d = []
+size_d = []
+for work in works:
+ n_wit = len(df[(df['text H-ID'] == work) & (df['status'] != 'fragment')])
+ n_frags = len(df[(df['text H-ID'] == work) & (df['status'] == 'fragment')])
+ if n_wit !=0:
+ size_d.append(n_wit)
+ if n_frags !=0:
+ size_frags_d.append(n_frags)
+
+ if n_wit == 2:
+ f2_works.append(work)
+ if n_wit == 1:
+ f1_works.append(work)
+
+size_dist = Counter(size_d)
+size_dist_frags = Counter(size_frags_d)
+
+f2_dates_0 = [df[(df["text H-ID"] == x) & (df['status'] != 'fragment')]["Date"].values.tolist() for x in f2_works]
+f2_dates = [list(map(convert_date, x)) for x in f2_dates_0]
+
+ranges_per_work = []
+for t_dates in f2_dates:
+ if t_dates != []:
+ lb = sorted(t_dates, key=bottom)[0]
+ ub = sorted(t_dates, key=top)[-1]
+ ranges_per_work.append((lb,ub))
+
+
+lifespans_f2 = []
+for v in ranges_per_work:
+ match v:
+ case [(a,b), (c,d)]:
+ lifespans_f2.append(expected_abs_diff(a,b,c,d))
+ case [(a,b), c]:
+ lifespans_f2.append(expected_abs_diff_degenerate(a,b,c))
+ case [c,(a,b)]:
+ lifespans_f2.append(expected_abs_diff_degenerate(a,b,c))
+ case [a,b]:
+ lifespans_f2.append(abs(a-b))
+ case _:
+ print('error')
+
+add_f1 = [[
+ 1,
+ 0,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1] for k in range(61)]
+
+add_f2 = [[2, int(4 * n), -1,-1,-1,-1,-1,-1,-1] for n in lifespans_f2]
+x_obs_empirical = list(x_obs0.values()) + add_f1 + add_f2[:17]
+
+random.shuffle(x_obs_empirical)
+
+lambda_min_prior = 4.*10**(-3)
+lambda_max_prior = 9.*10**(-3)
+
+mu_min_prior = 1.*10**(-3)
+mu_max_prior = 5*10**(-3)
+
+decay_min_prior = 0
+decay_max_prior = 1
+
+decimation_min_prior = 0
+decimation_max_prior = 1
+
+N_samples_prior = 500_000 #500000
+N_samples_posterior = 1000 #1000
+
+#load pretrained model serialized as pickle object
+with open("pretrained_models/inference_unif.pickle", "rb") as f:
+ inference = pickle.load(f)
+
+
+#posterior = inference.build_posterior(sample_with="rejection")
+posterior = inference.build_posterior()
+
+samples = posterior.sample(
+ (N_samples_posterior,),
+ x=x_obs_empirical
+)
+
+# Generate the pair plot
+fig, axes = pairplot(
+ samples,
+ limits=[
+ [lambda_min_prior, lambda_max_prior],
+ [mu_min_prior, mu_max_prior],
+ [decay_min_prior, decay_max_prior],
+ [decimation_min_prior, decimation_max_prior]
+ ],
+ figsize=(10, 10), # Larger figsize for better readability
+ labels=[r"$\lambda$", r"$\mu$", r"$r_{\text{decay}}$", r"$r_{\text{decim}}$"]
+)
+
+# Adjust the DPI and save the figure
+plt.savefig(
+ "pairplot_highres.pdf", # Save as PDF for vector graphics (best for papers)
+ dpi=300, # High DPI for high resolution
+ bbox_inches="tight", # Remove extra whitespace
+ format="pdf" # Use PDF for publication-quality figures
+)
+
+# Optionally, save as PNG (if needed)
+plt.savefig(
+ "pairplot_highres.png",
+ dpi=300,
+ bbox_inches="tight"
+)
+
diff --git a/plot_results_server.py b/plot_results_server.py
new file mode 100644
index 00000000..7074b45e
--- /dev/null
+++ b/plot_results_server.py
@@ -0,0 +1,373 @@
+import random
+import torch
+import numpy as np
+import matplotlib.pyplot as plt
+import networkx as nx
+import birth_death_utils as bd
+import os
+from collections import Counter
+from tqdm.notebook import tqdm
+import pickle
+from itertools import groupby
+import pandas as pd
+import yaml
+import re
+import multiprocessing as mp
+import seaborn as sns
+
+from sbi.analysis import pairplot
+from sbi.inference import NPE, simulate_for_sbi, NLE
+from sbi.utils import BoxUniform
+
+from sbi.utils.user_input_checks import (
+ check_sbi_inputs,
+ process_prior,
+ process_simulator,
+)
+
+from torch import Tensor
+
+def compute_summary_stats(g):
+ """
+ Generate a vector of summary statistics from a graph generated by birth-death simulation
+
+ Parameters
+ ----------
+ g : nx.DiGraph()
+ tree graph generated by birth_death_utils.ct_bd_tree
+
+ Returns
+ -------
+ list
+ vector of summary statistics characterizing a single tradition
+ """
+ n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)
+
+ if n_living == 0:
+ return None
+
+ if n_living == 1:
+ return [1,0, -1,-1,-1,-1,-1,-1,-1]
+
+ if n_living == 2:
+ birth_times_trad = []
+ for n in g.nodes():
+ if g.nodes[n]['state']:
+ birth_times_trad.append(g.nodes[n]['birth_time'])
+ timelapse = int(max(birth_times_trad)-min(birth_times_trad))
+ return [2, timelapse, -1,-1,-1,-1,-1,-1,-1]
+
+ if n_living >= 3:
+ birth_times_trad = []
+ degrees = []
+ direct_filiation_nb = 0
+ arch_dists = []
+ st = bd.generate_stemma(g)
+ archetype = bd.root(st)
+
+ for n in st.nodes():
+ degrees.append(st.out_degree(n))
+
+ if n != archetype:
+ father = list(st.predecessors(n))[0]
+ if st.nodes[n]['state'] and st.nodes[father]['state']:
+ direct_filiation_nb +=1
+ if st.nodes[n]['state']:
+ birth_times_trad.append(st.nodes[n]['birth_time'])
+ arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))
+
+ timelapse = int(max(birth_times_trad)-min(birth_times_trad))
+ deg_dist = Counter(degrees)
+ deg1 = deg_dist[1]
+ deg2 = deg_dist[2]
+ deg3 = deg_dist[3]
+ deg4 = deg_dist[4]
+ depth = max(arch_dists)
+ n_nodes = len(list(st.nodes()))
+
+ return [
+ n_living,
+ timelapse,
+ n_nodes,
+ direct_filiation_nb,
+ deg1,
+ deg2,
+ deg3,
+ deg4,
+ depth
+ ]
+
+def convert_date(x):
+ pattern1 = re.compile('[0-9][0-9][0-9][0-9]')
+ pattern2 = re.compile('[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
+
+ if bool(pattern1.fullmatch(x)):
+ return int(x)
+ if bool(pattern2.fullmatch(x)):
+ xx = x.split('-')
+ return (int(xx[0]),int(xx[1]))
+
+def top(x):
+ '''
+ Upper bound on witness date (single year or range)
+ '''
+ match x:
+ case (x1, x2):
+ return x2
+ case _:
+ return x
+
+def bottom(x):
+ '''
+ Lower bound on witness date (single year or range)
+ '''
+ match x:
+ case (x1, x2):
+ return x1
+ case _:
+ return x
+
+
+def expected_abs_diff_degenerate(c, a, b):
+ '''
+ Returns the expectation value of the timelapse between one date given as range
+ and one other as a single year
+ '''
+ if a == b:
+ return abs(a - c)
+ if a <= c <= b:
+ return ((c-a)**2 + (b-c)**2) / (2*(b-a))
+ elif c < a:
+ return (a+b)/2 - c
+ else:
+ return c - (a+b)/2
+
+def expected_abs_diff(a, b, c, d):
+ '''
+ Return the expectation value of the timelapse between two dates given as
+ intervals
+ '''
+ if a == b:
+ return expected_abs_diff_degenerate(a, c, d)
+ if c == d:
+ return expected_abs_diff_degenerate(c, a, b)
+ elif a < b < c < d:
+ return (c+d-b-a)/2
+ elif a <= c <= d < b:
+ return (1/(b-a)) * ((1/2)*((d-a)*(c-a)+(b-d)*(b-c)) + (1/3)*(d-c)**2)
+ elif a <= c <= b <= d:
+ return (1/(b-a)) * ((1/2)* ((c-a)*(d-a) + (b-c)*(d-b)) + (1/(3*(d-c)))*(b-c)**3 )
+ else:
+ print(f"{a},{b} -- {c},{d} ")
+ raise ValueError("Must have a < b, c < d, and a < c")
+
+wholeCorpus = {}
+corpus_dates = {}
+for work in os.listdir(f'corpus_stemmata/'):
+ print(f'{work}')
+ st = bd.load_from_OpenStemmata(f'corpus_stemmata/{work}/stemma.gv')
+ with open(f"corpus_stemmata/{work}/metadata.txt", 'r') as f:
+ content = f.read()
+ metadata = yaml.safe_load(content)
+ if "wits" in metadata:
+ dates = [wit["witOrigDate"] for wit in metadata['wits'] if wit["witOrigDate"] != '']
+ else:
+ dates = []
+
+ dates_num = []
+ for x in dates:
+ if x != '':
+ date_num = convert_date(x)
+ if date_num != None:
+ dates_num.append(date_num)
+
+ wholeCorpus[f"{work}"] = st
+ corpus_dates[f"{work}"] = dates_num
+
+ranges_per_work = {}
+for work, t_dates in corpus_dates.items():
+ if t_dates != []:
+ lb = sorted(t_dates, key=bottom)[0]
+ ub = sorted(t_dates, key=top)[-1]
+ ranges_per_work[work] = (lb,ub)
+
+
+lifespans = {}
+for w,v in ranges_per_work.items():
+ match v:
+ case [(a,b), (c,d)]:
+ lifespans[w] = expected_abs_diff(a,b,c,d)
+ case [(a,b), c]:
+ lifespans[w] = expected_abs_diff_degenerate(a,b,c)
+ case [c,(a,b)]:
+ lifespans[w] = expected_abs_diff_degenerate(a,b,c)
+ case [a,b]:
+ lifespans[w] = abs(a-b)
+ case _:
+ print('error')
+
+x_obs0 = {}
+sizes = {}
+for k in lifespans.keys():
+ ## computation of observables
+ g = wholeCorpus[k]
+
+ n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)
+ sizes[k] = n_living
+ degrees = []
+ direct_filiation_nb = 0
+ arch_dists = []
+
+ if n_living >= 3:
+ st = bd.generate_stemma(g)
+ archetype = bd.root(st)
+ for n in st.nodes():
+ degrees.append(st.out_degree(n))
+
+ if n != archetype:
+ father = list(st.predecessors(n))[0]
+ if st.nodes[n]['state'] and st.nodes[father]['state']:
+ direct_filiation_nb +=1
+ arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))
+
+ timelapse = lifespans[k]
+ deg_dist = Counter(degrees)
+ deg1 = deg_dist[1]
+ deg2 = deg_dist[2]
+ deg3 = deg_dist[3]
+ deg4 = deg_dist[4]
+ depth = max(arch_dists)
+ n_nodes = len(list(st.nodes()))
+
+ x_obs0[k] = [
+ n_living,
+ 4*int(timelapse),
+ n_nodes,
+ direct_filiation_nb,
+ deg1,
+ deg2,
+ deg3,
+ deg4,
+ depth
+ ]
+df = pd.read_csv("Old_French_witnesses.csv")
+f2_works = []
+f1_works = []
+works = set(list(df['text H-ID']))
+size_frags_d = []
+size_d = []
+for work in works:
+ n_wit = len(df[(df['text H-ID'] == work) & (df['status'] != 'fragment')])
+ n_frags = len(df[(df['text H-ID'] == work) & (df['status'] == 'fragment')])
+ if n_wit !=0:
+ size_d.append(n_wit)
+ if n_frags !=0:
+ size_frags_d.append(n_frags)
+
+ if n_wit == 2:
+ f2_works.append(work)
+ if n_wit == 1:
+ f1_works.append(work)
+
+size_dist = Counter(size_d)
+size_dist_frags = Counter(size_frags_d)
+
+f2_dates_0 = [df[(df["text H-ID"] == x) & (df['status'] != 'fragment')]["Date"].values.tolist() for x in f2_works]
+f2_dates = [list(map(convert_date, x)) for x in f2_dates_0]
+
+ranges_per_work = []
+for t_dates in f2_dates:
+ if t_dates != []:
+ lb = sorted(t_dates, key=bottom)[0]
+ ub = sorted(t_dates, key=top)[-1]
+ ranges_per_work.append((lb,ub))
+
+
+lifespans_f2 = []
+for v in ranges_per_work:
+ match v:
+ case [(a,b), (c,d)]:
+ lifespans_f2.append(expected_abs_diff(a,b,c,d))
+ case [(a,b), c]:
+ lifespans_f2.append(expected_abs_diff_degenerate(a,b,c))
+ case [c,(a,b)]:
+ lifespans_f2.append(expected_abs_diff_degenerate(a,b,c))
+ case [a,b]:
+ lifespans_f2.append(abs(a-b))
+ case _:
+ print('error')
+
+add_f1 = [[
+ 1,
+ 0,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1] for k in range(61)]
+
+add_f2 = [[2, int(4 * n), -1,-1,-1,-1,-1,-1,-1] for n in lifespans_f2]
+x_obs_empirical = list(x_obs0.values()) + add_f1 + add_f2[:17]
+
+random.shuffle(x_obs_empirical)
+
+lambda_min_prior = 4.*10**(-3)
+lambda_max_prior = 9.*10**(-3)
+
+mu_min_prior = 1.*10**(-3)
+mu_max_prior = 5*10**(-3)
+
+decay_min_prior = 0
+decay_max_prior = 1
+
+decimation_min_prior = 0
+decimation_max_prior = 1
+
+N_samples_prior = 500_000 #500000
+N_samples_posterior = 1000 #1000
+
+#load pretrained model serialized as pickle object
+with open("pretrained_models/inference_unif_run3.pickle", "rb") as f:
+ inference = pickle.load(f)
+
+
+#posterior = inference.build_posterior(sample_with="rejection")
+posterior = inference.build_posterior()
+
+samples = posterior.sample(
+ (N_samples_posterior,),
+ x=x_obs_empirical,
+ #mcmc_method="nuts_pyro",
+ mcmc_parameters={"warmup_steps": 1000, "num_chains": 100, "num_workers": 1}
+)
+
+# Generate the pair plot
+fig, axes = pairplot(
+ samples,
+ limits=[
+ [lambda_min_prior, lambda_max_prior],
+ [mu_min_prior, mu_max_prior],
+ [decay_min_prior, decay_max_prior],
+ [decimation_min_prior, decimation_max_prior]
+ ],
+ figsize=(10, 10), # Larger figsize for better readability
+ labels=[r"$\lambda$", r"$\mu$", r"$r_{\text{decay}}$", r"$r_{\text{decim}}$"]
+)
+
+# Adjust the DPI and save the figure
+plt.savefig(
+ "pairplot_highres_run3.pdf", # Save as PDF for vector graphics (best for papers)
+ dpi=300, # High DPI for high resolution
+ bbox_inches="tight", # Remove extra whitespace
+ format="pdf" # Use PDF for publication-quality figures
+)
+
+# Optionally, save as PNG (if needed)
+plt.savefig(
+ "pairplot_highres_run3.png",
+ dpi=300,
+ bbox_inches="tight"
+)
+
diff --git a/pretrained_models/inference_joint.pickle b/pretrained_models/inference_joint.pickle
new file mode 100644
index 00000000..5d828a98
Binary files /dev/null and b/pretrained_models/inference_joint.pickle differ
diff --git a/pretrained_models/inference_unif.pickle b/pretrained_models/inference_unif.pickle
new file mode 100644
index 00000000..335c7871
Binary files /dev/null and b/pretrained_models/inference_unif.pickle differ
diff --git a/pretrained_models/inference_unif_bench_123.pickle b/pretrained_models/inference_unif_bench_123.pickle
new file mode 100644
index 00000000..9234614c
Binary files /dev/null and b/pretrained_models/inference_unif_bench_123.pickle differ
diff --git a/pretrained_models/inference_unif_bench_1946.pickle b/pretrained_models/inference_unif_bench_1946.pickle
new file mode 100644
index 00000000..90df082d
Binary files /dev/null and b/pretrained_models/inference_unif_bench_1946.pickle differ
diff --git a/pretrained_models/inference_unif_bench_42.pickle b/pretrained_models/inference_unif_bench_42.pickle
new file mode 100644
index 00000000..fc0dcecb
Binary files /dev/null and b/pretrained_models/inference_unif_bench_42.pickle differ
diff --git a/pretrained_models/inference_unif_bench_456.pickle b/pretrained_models/inference_unif_bench_456.pickle
new file mode 100644
index 00000000..4f747d73
Binary files /dev/null and b/pretrained_models/inference_unif_bench_456.pickle differ
diff --git a/pretrained_models/inference_unif_bench_808.pickle b/pretrained_models/inference_unif_bench_808.pickle
new file mode 100644
index 00000000..07317bbb
Binary files /dev/null and b/pretrained_models/inference_unif_bench_808.pickle differ
diff --git a/pretrained_models/inference_unif_run3.pickle b/pretrained_models/inference_unif_run3.pickle
new file mode 100644
index 00000000..802d946d
Binary files /dev/null and b/pretrained_models/inference_unif_run3.pickle differ
diff --git a/pretrained_models/inference_unif_server.pickle b/pretrained_models/inference_unif_server.pickle
new file mode 100644
index 00000000..364c3b13
Binary files /dev/null and b/pretrained_models/inference_unif_server.pickle differ
diff --git a/sbi-logs/NLE_A/2026-02-03T22_58_21.833163/events.out.tfevents.1770155901.srv-rech01.78171.0 b/sbi-logs/NLE_A/2026-02-03T22_58_21.833163/events.out.tfevents.1770155901.srv-rech01.78171.0
new file mode 100644
index 00000000..939ce683
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-03T22_58_21.833163/events.out.tfevents.1770155901.srv-rech01.78171.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-03T23_24_48.346478/events.out.tfevents.1770157488.srv-rech01.79332.0 b/sbi-logs/NLE_A/2026-02-03T23_24_48.346478/events.out.tfevents.1770157488.srv-rech01.79332.0
new file mode 100644
index 00000000..79d8604f
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-03T23_24_48.346478/events.out.tfevents.1770157488.srv-rech01.79332.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-03T23_40_29.418675/events.out.tfevents.1770158429.srv-rech01.79586.0 b/sbi-logs/NLE_A/2026-02-03T23_40_29.418675/events.out.tfevents.1770158429.srv-rech01.79586.0
new file mode 100644
index 00000000..46639c1b
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-03T23_40_29.418675/events.out.tfevents.1770158429.srv-rech01.79586.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-03T23_52_26.633100/events.out.tfevents.1770159146.srv-rech01.79755.0 b/sbi-logs/NLE_A/2026-02-03T23_52_26.633100/events.out.tfevents.1770159146.srv-rech01.79755.0
new file mode 100644
index 00000000..a71c82ed
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-03T23_52_26.633100/events.out.tfevents.1770159146.srv-rech01.79755.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T00_00_39.428852/events.out.tfevents.1770159639.srv-rech01.79993.0 b/sbi-logs/NLE_A/2026-02-04T00_00_39.428852/events.out.tfevents.1770159639.srv-rech01.79993.0
new file mode 100644
index 00000000..267ce725
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T00_00_39.428852/events.out.tfevents.1770159639.srv-rech01.79993.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T00_46_26.678137/events.out.tfevents.1770162386.srv-rech01.80221.0 b/sbi-logs/NLE_A/2026-02-04T00_46_26.678137/events.out.tfevents.1770162386.srv-rech01.80221.0
new file mode 100644
index 00000000..1d17c6b9
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T00_46_26.678137/events.out.tfevents.1770162386.srv-rech01.80221.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T08_58_44.572027/events.out.tfevents.1770191924.srv-rech01.86162.0 b/sbi-logs/NLE_A/2026-02-04T08_58_44.572027/events.out.tfevents.1770191924.srv-rech01.86162.0
new file mode 100644
index 00000000..90707c68
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T08_58_44.572027/events.out.tfevents.1770191924.srv-rech01.86162.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_16_11.045412/events.out.tfevents.1770192971.srv-rech01.86477.0 b/sbi-logs/NLE_A/2026-02-04T09_16_11.045412/events.out.tfevents.1770192971.srv-rech01.86477.0
new file mode 100644
index 00000000..f639c17a
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_16_11.045412/events.out.tfevents.1770192971.srv-rech01.86477.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_21_39.873311/events.out.tfevents.1770193299.srv-rech01.86636.0 b/sbi-logs/NLE_A/2026-02-04T09_21_39.873311/events.out.tfevents.1770193299.srv-rech01.86636.0
new file mode 100644
index 00000000..9f1d1c79
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_21_39.873311/events.out.tfevents.1770193299.srv-rech01.86636.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_35.854231/events.out.tfevents.1770193415.srv-rech01.86736.0 b/sbi-logs/NLE_A/2026-02-04T09_23_35.854231/events.out.tfevents.1770193415.srv-rech01.86736.0
new file mode 100644
index 00000000..2b48dc5f
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_35.854231/events.out.tfevents.1770193415.srv-rech01.86736.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_35.872076/events.out.tfevents.1770193415.srv-rech01.86730.0 b/sbi-logs/NLE_A/2026-02-04T09_23_35.872076/events.out.tfevents.1770193415.srv-rech01.86730.0
new file mode 100644
index 00000000..b1a8f472
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_35.872076/events.out.tfevents.1770193415.srv-rech01.86730.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_36.380702/events.out.tfevents.1770193416.srv-rech01.86727.0 b/sbi-logs/NLE_A/2026-02-04T09_23_36.380702/events.out.tfevents.1770193416.srv-rech01.86727.0
new file mode 100644
index 00000000..a3f12d5a
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_36.380702/events.out.tfevents.1770193416.srv-rech01.86727.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_36.830431/events.out.tfevents.1770193416.srv-rech01.86729.0 b/sbi-logs/NLE_A/2026-02-04T09_23_36.830431/events.out.tfevents.1770193416.srv-rech01.86729.0
new file mode 100644
index 00000000..b721394b
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_36.830431/events.out.tfevents.1770193416.srv-rech01.86729.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_37.172835/events.out.tfevents.1770193417.srv-rech01.86738.0 b/sbi-logs/NLE_A/2026-02-04T09_23_37.172835/events.out.tfevents.1770193417.srv-rech01.86738.0
new file mode 100644
index 00000000..8edcb6f7
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_37.172835/events.out.tfevents.1770193417.srv-rech01.86738.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_37.458481/events.out.tfevents.1770193417.srv-rech01.86733.0 b/sbi-logs/NLE_A/2026-02-04T09_23_37.458481/events.out.tfevents.1770193417.srv-rech01.86733.0
new file mode 100644
index 00000000..73a1b34d
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_37.458481/events.out.tfevents.1770193417.srv-rech01.86733.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.378663/events.out.tfevents.1770193418.srv-rech01.86724.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.378663/events.out.tfevents.1770193418.srv-rech01.86724.0
new file mode 100644
index 00000000..b352db18
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.378663/events.out.tfevents.1770193418.srv-rech01.86724.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.583610/events.out.tfevents.1770193418.srv-rech01.86743.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.583610/events.out.tfevents.1770193418.srv-rech01.86743.0
new file mode 100644
index 00000000..23ccf8be
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.583610/events.out.tfevents.1770193418.srv-rech01.86743.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.591351/events.out.tfevents.1770193418.srv-rech01.86726.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.591351/events.out.tfevents.1770193418.srv-rech01.86726.0
new file mode 100644
index 00000000..7f1bbd19
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.591351/events.out.tfevents.1770193418.srv-rech01.86726.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.600678/events.out.tfevents.1770193418.srv-rech01.86741.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.600678/events.out.tfevents.1770193418.srv-rech01.86741.0
new file mode 100644
index 00000000..ed2de093
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.600678/events.out.tfevents.1770193418.srv-rech01.86741.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.606513/events.out.tfevents.1770193418.srv-rech01.86732.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.606513/events.out.tfevents.1770193418.srv-rech01.86732.0
new file mode 100644
index 00000000..b2ef13cd
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.606513/events.out.tfevents.1770193418.srv-rech01.86732.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.806198/events.out.tfevents.1770193418.srv-rech01.86737.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.806198/events.out.tfevents.1770193418.srv-rech01.86737.0
new file mode 100644
index 00000000..2a763520
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.806198/events.out.tfevents.1770193418.srv-rech01.86737.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.977129/events.out.tfevents.1770193418.srv-rech01.86735.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.977129/events.out.tfevents.1770193418.srv-rech01.86735.0
new file mode 100644
index 00000000..71e2b257
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.977129/events.out.tfevents.1770193418.srv-rech01.86735.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_38.997833/events.out.tfevents.1770193418.srv-rech01.86725.0 b/sbi-logs/NLE_A/2026-02-04T09_23_38.997833/events.out.tfevents.1770193418.srv-rech01.86725.0
new file mode 100644
index 00000000..b79605d2
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_38.997833/events.out.tfevents.1770193418.srv-rech01.86725.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_39.958592/events.out.tfevents.1770193419.srv-rech01.86739.0 b/sbi-logs/NLE_A/2026-02-04T09_23_39.958592/events.out.tfevents.1770193419.srv-rech01.86739.0
new file mode 100644
index 00000000..12a5542b
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_39.958592/events.out.tfevents.1770193419.srv-rech01.86739.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_40.330637/events.out.tfevents.1770193420.srv-rech01.86742.0 b/sbi-logs/NLE_A/2026-02-04T09_23_40.330637/events.out.tfevents.1770193420.srv-rech01.86742.0
new file mode 100644
index 00000000..bae66062
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_40.330637/events.out.tfevents.1770193420.srv-rech01.86742.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_41.008513/events.out.tfevents.1770193421.srv-rech01.86731.0 b/sbi-logs/NLE_A/2026-02-04T09_23_41.008513/events.out.tfevents.1770193421.srv-rech01.86731.0
new file mode 100644
index 00000000..6f03c822
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_41.008513/events.out.tfevents.1770193421.srv-rech01.86731.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_41.113486/events.out.tfevents.1770193421.srv-rech01.86734.0 b/sbi-logs/NLE_A/2026-02-04T09_23_41.113486/events.out.tfevents.1770193421.srv-rech01.86734.0
new file mode 100644
index 00000000..c56ed48f
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_41.113486/events.out.tfevents.1770193421.srv-rech01.86734.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_41.481840/events.out.tfevents.1770193421.srv-rech01.86740.0 b/sbi-logs/NLE_A/2026-02-04T09_23_41.481840/events.out.tfevents.1770193421.srv-rech01.86740.0
new file mode 100644
index 00000000..eef4ff40
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_41.481840/events.out.tfevents.1770193421.srv-rech01.86740.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_23_49.790576/events.out.tfevents.1770193429.srv-rech01.86728.0 b/sbi-logs/NLE_A/2026-02-04T09_23_49.790576/events.out.tfevents.1770193429.srv-rech01.86728.0
new file mode 100644
index 00000000..6007929f
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_23_49.790576/events.out.tfevents.1770193429.srv-rech01.86728.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_32_52.422456/events.out.tfevents.1770193972.srv-rech01.88074.0 b/sbi-logs/NLE_A/2026-02-04T09_32_52.422456/events.out.tfevents.1770193972.srv-rech01.88074.0
new file mode 100644
index 00000000..37914f4b
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_32_52.422456/events.out.tfevents.1770193972.srv-rech01.88074.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T09_56_02.074340/events.out.tfevents.1770195362.srv-rech01.88460.0 b/sbi-logs/NLE_A/2026-02-04T09_56_02.074340/events.out.tfevents.1770195362.srv-rech01.88460.0
new file mode 100644
index 00000000..fb3c9331
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T09_56_02.074340/events.out.tfevents.1770195362.srv-rech01.88460.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_10_11.295103/events.out.tfevents.1770196211.srv-rech01.88702.0 b/sbi-logs/NLE_A/2026-02-04T10_10_11.295103/events.out.tfevents.1770196211.srv-rech01.88702.0
new file mode 100644
index 00000000..b45aa29e
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_10_11.295103/events.out.tfevents.1770196211.srv-rech01.88702.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_01.601035/events.out.tfevents.1770196261.srv-rech01.88768.0 b/sbi-logs/NLE_A/2026-02-04T10_11_01.601035/events.out.tfevents.1770196261.srv-rech01.88768.0
new file mode 100644
index 00000000..1d1beee0
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_01.601035/events.out.tfevents.1770196261.srv-rech01.88768.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_02.588766/events.out.tfevents.1770196262.srv-rech01.88772.0 b/sbi-logs/NLE_A/2026-02-04T10_11_02.588766/events.out.tfevents.1770196262.srv-rech01.88772.0
new file mode 100644
index 00000000..a7dd841b
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_02.588766/events.out.tfevents.1770196262.srv-rech01.88772.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_02.783761/events.out.tfevents.1770196262.srv-rech01.88769.0 b/sbi-logs/NLE_A/2026-02-04T10_11_02.783761/events.out.tfevents.1770196262.srv-rech01.88769.0
new file mode 100644
index 00000000..1c0ad78d
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_02.783761/events.out.tfevents.1770196262.srv-rech01.88769.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_02.815037/events.out.tfevents.1770196262.srv-rech01.88773.0 b/sbi-logs/NLE_A/2026-02-04T10_11_02.815037/events.out.tfevents.1770196262.srv-rech01.88773.0
new file mode 100644
index 00000000..d75ba068
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_02.815037/events.out.tfevents.1770196262.srv-rech01.88773.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_02.887955/events.out.tfevents.1770196262.srv-rech01.88774.0 b/sbi-logs/NLE_A/2026-02-04T10_11_02.887955/events.out.tfevents.1770196262.srv-rech01.88774.0
new file mode 100644
index 00000000..927d30fa
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_02.887955/events.out.tfevents.1770196262.srv-rech01.88774.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_02.918862/events.out.tfevents.1770196262.srv-rech01.88777.0 b/sbi-logs/NLE_A/2026-02-04T10_11_02.918862/events.out.tfevents.1770196262.srv-rech01.88777.0
new file mode 100644
index 00000000..64bf9c53
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_02.918862/events.out.tfevents.1770196262.srv-rech01.88777.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_02.964226/events.out.tfevents.1770196262.srv-rech01.88776.0 b/sbi-logs/NLE_A/2026-02-04T10_11_02.964226/events.out.tfevents.1770196262.srv-rech01.88776.0
new file mode 100644
index 00000000..0af1fbb1
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_02.964226/events.out.tfevents.1770196262.srv-rech01.88776.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_02.990184/events.out.tfevents.1770196262.srv-rech01.88775.0 b/sbi-logs/NLE_A/2026-02-04T10_11_02.990184/events.out.tfevents.1770196262.srv-rech01.88775.0
new file mode 100644
index 00000000..3f830741
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_02.990184/events.out.tfevents.1770196262.srv-rech01.88775.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_03.017083/events.out.tfevents.1770196263.srv-rech01.88770.0 b/sbi-logs/NLE_A/2026-02-04T10_11_03.017083/events.out.tfevents.1770196263.srv-rech01.88770.0
new file mode 100644
index 00000000..780f91e1
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_03.017083/events.out.tfevents.1770196263.srv-rech01.88770.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_11_03.156683/events.out.tfevents.1770196263.srv-rech01.88771.0 b/sbi-logs/NLE_A/2026-02-04T10_11_03.156683/events.out.tfevents.1770196263.srv-rech01.88771.0
new file mode 100644
index 00000000..4153c941
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_11_03.156683/events.out.tfevents.1770196263.srv-rech01.88771.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_16_05.638258/events.out.tfevents.1770196565.srv-rech01.89583.0 b/sbi-logs/NLE_A/2026-02-04T10_16_05.638258/events.out.tfevents.1770196565.srv-rech01.89583.0
new file mode 100644
index 00000000..618797bd
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_16_05.638258/events.out.tfevents.1770196565.srv-rech01.89583.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_18_50.912764/events.out.tfevents.1770196730.srv-rech01.90249.0 b/sbi-logs/NLE_A/2026-02-04T10_18_50.912764/events.out.tfevents.1770196730.srv-rech01.90249.0
new file mode 100644
index 00000000..c1aa2d33
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_18_50.912764/events.out.tfevents.1770196730.srv-rech01.90249.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_19_41.315821/events.out.tfevents.1770196781.srv-rech01.90338.0 b/sbi-logs/NLE_A/2026-02-04T10_19_41.315821/events.out.tfevents.1770196781.srv-rech01.90338.0
new file mode 100644
index 00000000..95ee3692
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_19_41.315821/events.out.tfevents.1770196781.srv-rech01.90338.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_21_13.125116/events.out.tfevents.1770196873.srv-rech01.90412.0 b/sbi-logs/NLE_A/2026-02-04T10_21_13.125116/events.out.tfevents.1770196873.srv-rech01.90412.0
new file mode 100644
index 00000000..339a5304
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_21_13.125116/events.out.tfevents.1770196873.srv-rech01.90412.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_22_56.159637/events.out.tfevents.1770196976.srv-rech01.90539.0 b/sbi-logs/NLE_A/2026-02-04T10_22_56.159637/events.out.tfevents.1770196976.srv-rech01.90539.0
new file mode 100644
index 00000000..7e7a3fa5
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_22_56.159637/events.out.tfevents.1770196976.srv-rech01.90539.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_23_45.328760/events.out.tfevents.1770197025.srv-rech01.90613.0 b/sbi-logs/NLE_A/2026-02-04T10_23_45.328760/events.out.tfevents.1770197025.srv-rech01.90613.0
new file mode 100644
index 00000000..800834df
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_23_45.328760/events.out.tfevents.1770197025.srv-rech01.90613.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_25_31.721389/events.out.tfevents.1770197131.srv-rech01.90691.0 b/sbi-logs/NLE_A/2026-02-04T10_25_31.721389/events.out.tfevents.1770197131.srv-rech01.90691.0
new file mode 100644
index 00000000..5991efd5
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_25_31.721389/events.out.tfevents.1770197131.srv-rech01.90691.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_26_21.227729/events.out.tfevents.1770197181.srv-rech01.90766.0 b/sbi-logs/NLE_A/2026-02-04T10_26_21.227729/events.out.tfevents.1770197181.srv-rech01.90766.0
new file mode 100644
index 00000000..79b4f317
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_26_21.227729/events.out.tfevents.1770197181.srv-rech01.90766.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_27_23.248472/events.out.tfevents.1770197243.srv-rech01.90840.0 b/sbi-logs/NLE_A/2026-02-04T10_27_23.248472/events.out.tfevents.1770197243.srv-rech01.90840.0
new file mode 100644
index 00000000..426bafc3
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_27_23.248472/events.out.tfevents.1770197243.srv-rech01.90840.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_13.861097/events.out.tfevents.1770197293.srv-rech01.90906.0 b/sbi-logs/NLE_A/2026-02-04T10_28_13.861097/events.out.tfevents.1770197293.srv-rech01.90906.0
new file mode 100644
index 00000000..16fad2f7
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_13.861097/events.out.tfevents.1770197293.srv-rech01.90906.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_13.877647/events.out.tfevents.1770197293.srv-rech01.90911.0 b/sbi-logs/NLE_A/2026-02-04T10_28_13.877647/events.out.tfevents.1770197293.srv-rech01.90911.0
new file mode 100644
index 00000000..54c1cb18
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_13.877647/events.out.tfevents.1770197293.srv-rech01.90911.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.225513/events.out.tfevents.1770197294.srv-rech01.90912.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.225513/events.out.tfevents.1770197294.srv-rech01.90912.0
new file mode 100644
index 00000000..e06c90a3
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.225513/events.out.tfevents.1770197294.srv-rech01.90912.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.297899/events.out.tfevents.1770197294.srv-rech01.90914.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.297899/events.out.tfevents.1770197294.srv-rech01.90914.0
new file mode 100644
index 00000000..0001e0af
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.297899/events.out.tfevents.1770197294.srv-rech01.90914.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.310072/events.out.tfevents.1770197294.srv-rech01.90915.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.310072/events.out.tfevents.1770197294.srv-rech01.90915.0
new file mode 100644
index 00000000..da4b05c2
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.310072/events.out.tfevents.1770197294.srv-rech01.90915.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.405087/events.out.tfevents.1770197294.srv-rech01.90910.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.405087/events.out.tfevents.1770197294.srv-rech01.90910.0
new file mode 100644
index 00000000..7b1ce7ef
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.405087/events.out.tfevents.1770197294.srv-rech01.90910.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.516863/events.out.tfevents.1770197294.srv-rech01.90907.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.516863/events.out.tfevents.1770197294.srv-rech01.90907.0
new file mode 100644
index 00000000..5245f56f
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.516863/events.out.tfevents.1770197294.srv-rech01.90907.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.581986/events.out.tfevents.1770197294.srv-rech01.90908.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.581986/events.out.tfevents.1770197294.srv-rech01.90908.0
new file mode 100644
index 00000000..42270573
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.581986/events.out.tfevents.1770197294.srv-rech01.90908.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.635840/events.out.tfevents.1770197294.srv-rech01.90913.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.635840/events.out.tfevents.1770197294.srv-rech01.90913.0
new file mode 100644
index 00000000..2cc42874
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.635840/events.out.tfevents.1770197294.srv-rech01.90913.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_28_14.712232/events.out.tfevents.1770197294.srv-rech01.90909.0 b/sbi-logs/NLE_A/2026-02-04T10_28_14.712232/events.out.tfevents.1770197294.srv-rech01.90909.0
new file mode 100644
index 00000000..a4214dc1
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_28_14.712232/events.out.tfevents.1770197294.srv-rech01.90909.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_40_49.150250/events.out.tfevents.1770198049.srv-rech01.91649.0 b/sbi-logs/NLE_A/2026-02-04T10_40_49.150250/events.out.tfevents.1770198049.srv-rech01.91649.0
new file mode 100644
index 00000000..96a14039
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_40_49.150250/events.out.tfevents.1770198049.srv-rech01.91649.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_40_49.194205/events.out.tfevents.1770198049.srv-rech01.91649.1 b/sbi-logs/NLE_A/2026-02-04T10_40_49.194205/events.out.tfevents.1770198049.srv-rech01.91649.1
new file mode 100644
index 00000000..c0f1d523
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_40_49.194205/events.out.tfevents.1770198049.srv-rech01.91649.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T10_40_49.240742/events.out.tfevents.1770198049.srv-rech01.91649.2 b/sbi-logs/NLE_A/2026-02-04T10_40_49.240742/events.out.tfevents.1770198049.srv-rech01.91649.2
new file mode 100644
index 00000000..a4f4bf85
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T10_40_49.240742/events.out.tfevents.1770198049.srv-rech01.91649.2 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T15_23_55.556089/events.out.tfevents.1770215035.srv-rech01.93587.0 b/sbi-logs/NLE_A/2026-02-04T15_23_55.556089/events.out.tfevents.1770215035.srv-rech01.93587.0
new file mode 100644
index 00000000..26423462
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T15_23_55.556089/events.out.tfevents.1770215035.srv-rech01.93587.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T15_26_39.669973/events.out.tfevents.1770215199.srv-rech01.93740.0 b/sbi-logs/NLE_A/2026-02-04T15_26_39.669973/events.out.tfevents.1770215199.srv-rech01.93740.0
new file mode 100644
index 00000000..e87612ce
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T15_26_39.669973/events.out.tfevents.1770215199.srv-rech01.93740.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T15_31_21.883057/events.out.tfevents.1770215481.srv-rech01.93828.0 b/sbi-logs/NLE_A/2026-02-04T15_31_21.883057/events.out.tfevents.1770215481.srv-rech01.93828.0
new file mode 100644
index 00000000..5c846e94
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T15_31_21.883057/events.out.tfevents.1770215481.srv-rech01.93828.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T15_33_52.242114/events.out.tfevents.1770215632.srv-rech01.94050.0 b/sbi-logs/NLE_A/2026-02-04T15_33_52.242114/events.out.tfevents.1770215632.srv-rech01.94050.0
new file mode 100644
index 00000000..cf16bac3
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T15_33_52.242114/events.out.tfevents.1770215632.srv-rech01.94050.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T15_37_06.454397/events.out.tfevents.1770215826.srv-rech01.94050.1 b/sbi-logs/NLE_A/2026-02-04T15_37_06.454397/events.out.tfevents.1770215826.srv-rech01.94050.1
new file mode 100644
index 00000000..fcd48f3d
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T15_37_06.454397/events.out.tfevents.1770215826.srv-rech01.94050.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T16_16_10.204526/events.out.tfevents.1770218170.srv-rech01.94793.0 b/sbi-logs/NLE_A/2026-02-04T16_16_10.204526/events.out.tfevents.1770218170.srv-rech01.94793.0
new file mode 100644
index 00000000..bd07f00a
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T16_16_10.204526/events.out.tfevents.1770218170.srv-rech01.94793.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T16_34_00.375417/events.out.tfevents.1770219240.srv-rech01.94793.1 b/sbi-logs/NLE_A/2026-02-04T16_34_00.375417/events.out.tfevents.1770219240.srv-rech01.94793.1
new file mode 100644
index 00000000..2bbcdc93
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T16_34_00.375417/events.out.tfevents.1770219240.srv-rech01.94793.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T16_48_44.926778/events.out.tfevents.1770220124.srv-rech01.94793.2 b/sbi-logs/NLE_A/2026-02-04T16_48_44.926778/events.out.tfevents.1770220124.srv-rech01.94793.2
new file mode 100644
index 00000000..bbd0c6fc
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T16_48_44.926778/events.out.tfevents.1770220124.srv-rech01.94793.2 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T17_11_46.814543/events.out.tfevents.1770221506.srv-rech01.94793.3 b/sbi-logs/NLE_A/2026-02-04T17_11_46.814543/events.out.tfevents.1770221506.srv-rech01.94793.3
new file mode 100644
index 00000000..b2a0c986
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T17_11_46.814543/events.out.tfevents.1770221506.srv-rech01.94793.3 differ
diff --git a/sbi-logs/NLE_A/2026-02-04T17_38_53.806825/events.out.tfevents.1770223133.srv-rech01.94793.4 b/sbi-logs/NLE_A/2026-02-04T17_38_53.806825/events.out.tfevents.1770223133.srv-rech01.94793.4
new file mode 100644
index 00000000..7f2403e2
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-04T17_38_53.806825/events.out.tfevents.1770223133.srv-rech01.94793.4 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T14_14_24.487661/events.out.tfevents.1770383664.srv-rech01.126626.0 b/sbi-logs/NLE_A/2026-02-06T14_14_24.487661/events.out.tfevents.1770383664.srv-rech01.126626.0
new file mode 100644
index 00000000..54d6b8e6
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T14_14_24.487661/events.out.tfevents.1770383664.srv-rech01.126626.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T14_34_59.874003/events.out.tfevents.1770384899.srv-rech01.126626.1 b/sbi-logs/NLE_A/2026-02-06T14_34_59.874003/events.out.tfevents.1770384899.srv-rech01.126626.1
new file mode 100644
index 00000000..671f6ccc
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T14_34_59.874003/events.out.tfevents.1770384899.srv-rech01.126626.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T14_50_05.072271/events.out.tfevents.1770385805.srv-rech01.126626.2 b/sbi-logs/NLE_A/2026-02-06T14_50_05.072271/events.out.tfevents.1770385805.srv-rech01.126626.2
new file mode 100644
index 00000000..edb2e215
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T14_50_05.072271/events.out.tfevents.1770385805.srv-rech01.126626.2 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T15_12_46.719296/events.out.tfevents.1770387166.srv-rech01.126626.3 b/sbi-logs/NLE_A/2026-02-06T15_12_46.719296/events.out.tfevents.1770387166.srv-rech01.126626.3
new file mode 100644
index 00000000..a32104ad
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T15_12_46.719296/events.out.tfevents.1770387166.srv-rech01.126626.3 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T15_33_27.008626/events.out.tfevents.1770388407.srv-rech01.126626.4 b/sbi-logs/NLE_A/2026-02-06T15_33_27.008626/events.out.tfevents.1770388407.srv-rech01.126626.4
new file mode 100644
index 00000000..fcfa87e9
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T15_33_27.008626/events.out.tfevents.1770388407.srv-rech01.126626.4 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T19_15_37.781354/events.out.tfevents.1770401737.srv-rech01.129025.0 b/sbi-logs/NLE_A/2026-02-06T19_15_37.781354/events.out.tfevents.1770401737.srv-rech01.129025.0
new file mode 100644
index 00000000..a36104fc
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T19_15_37.781354/events.out.tfevents.1770401737.srv-rech01.129025.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T19_15_37.811753/events.out.tfevents.1770401737.srv-rech01.129025.1 b/sbi-logs/NLE_A/2026-02-06T19_15_37.811753/events.out.tfevents.1770401737.srv-rech01.129025.1
new file mode 100644
index 00000000..f4d5a9f4
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T19_15_37.811753/events.out.tfevents.1770401737.srv-rech01.129025.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T19_15_37.836970/events.out.tfevents.1770401737.srv-rech01.129025.2 b/sbi-logs/NLE_A/2026-02-06T19_15_37.836970/events.out.tfevents.1770401737.srv-rech01.129025.2
new file mode 100644
index 00000000..88040699
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T19_15_37.836970/events.out.tfevents.1770401737.srv-rech01.129025.2 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T19_15_37.859446/events.out.tfevents.1770401737.srv-rech01.129025.3 b/sbi-logs/NLE_A/2026-02-06T19_15_37.859446/events.out.tfevents.1770401737.srv-rech01.129025.3
new file mode 100644
index 00000000..6960e521
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T19_15_37.859446/events.out.tfevents.1770401737.srv-rech01.129025.3 differ
diff --git a/sbi-logs/NLE_A/2026-02-06T19_15_37.882403/events.out.tfevents.1770401737.srv-rech01.129025.4 b/sbi-logs/NLE_A/2026-02-06T19_15_37.882403/events.out.tfevents.1770401737.srv-rech01.129025.4
new file mode 100644
index 00000000..9fe2c684
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-06T19_15_37.882403/events.out.tfevents.1770401737.srv-rech01.129025.4 differ
diff --git a/sbi-logs/NLE_A/2026-02-09T13_23_34.529760/events.out.tfevents.1770639814.srv-rech01.196061.0 b/sbi-logs/NLE_A/2026-02-09T13_23_34.529760/events.out.tfevents.1770639814.srv-rech01.196061.0
new file mode 100644
index 00000000..120cfd4d
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-09T13_23_34.529760/events.out.tfevents.1770639814.srv-rech01.196061.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T08_02_25.709476/events.out.tfevents.1770706945.srv-rech01.260951.0 b/sbi-logs/NLE_A/2026-02-10T08_02_25.709476/events.out.tfevents.1770706945.srv-rech01.260951.0
new file mode 100644
index 00000000..c45281e0
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T08_02_25.709476/events.out.tfevents.1770706945.srv-rech01.260951.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T08_08_53.607490/events.out.tfevents.1770707333.srv-rech01.260951.1 b/sbi-logs/NLE_A/2026-02-10T08_08_53.607490/events.out.tfevents.1770707333.srv-rech01.260951.1
new file mode 100644
index 00000000..3f548591
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T08_08_53.607490/events.out.tfevents.1770707333.srv-rech01.260951.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T08_12_54.924942/events.out.tfevents.1770707574.srv-rech01.260951.2 b/sbi-logs/NLE_A/2026-02-10T08_12_54.924942/events.out.tfevents.1770707574.srv-rech01.260951.2
new file mode 100644
index 00000000..894e37f1
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T08_12_54.924942/events.out.tfevents.1770707574.srv-rech01.260951.2 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_12_29.576560/events.out.tfevents.1770711149.srv-rech01.276392.0 b/sbi-logs/NLE_A/2026-02-10T09_12_29.576560/events.out.tfevents.1770711149.srv-rech01.276392.0
new file mode 100644
index 00000000..29ef13ae
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_12_29.576560/events.out.tfevents.1770711149.srv-rech01.276392.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_15_25.428738/events.out.tfevents.1770711325.srv-rech01.276448.0 b/sbi-logs/NLE_A/2026-02-10T09_15_25.428738/events.out.tfevents.1770711325.srv-rech01.276448.0
new file mode 100644
index 00000000..8f295aeb
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_15_25.428738/events.out.tfevents.1770711325.srv-rech01.276448.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_29_26.314996/events.out.tfevents.1770712166.srv-rech01.276508.0 b/sbi-logs/NLE_A/2026-02-10T09_29_26.314996/events.out.tfevents.1770712166.srv-rech01.276508.0
new file mode 100644
index 00000000..c2106b1b
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_29_26.314996/events.out.tfevents.1770712166.srv-rech01.276508.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_30_37.663158/events.out.tfevents.1770712237.srv-rech01.276608.0 b/sbi-logs/NLE_A/2026-02-10T09_30_37.663158/events.out.tfevents.1770712237.srv-rech01.276608.0
new file mode 100644
index 00000000..3ca5b5af
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_30_37.663158/events.out.tfevents.1770712237.srv-rech01.276608.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_35_06.921609/events.out.tfevents.1770712506.srv-rech01.276661.0 b/sbi-logs/NLE_A/2026-02-10T09_35_06.921609/events.out.tfevents.1770712506.srv-rech01.276661.0
new file mode 100644
index 00000000..f66c3b74
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_35_06.921609/events.out.tfevents.1770712506.srv-rech01.276661.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_36_12.021011/events.out.tfevents.1770712572.srv-rech01.276716.0 b/sbi-logs/NLE_A/2026-02-10T09_36_12.021011/events.out.tfevents.1770712572.srv-rech01.276716.0
new file mode 100644
index 00000000..4cf7e790
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_36_12.021011/events.out.tfevents.1770712572.srv-rech01.276716.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_39_13.106256/events.out.tfevents.1770712753.srv-rech01.276823.0 b/sbi-logs/NLE_A/2026-02-10T09_39_13.106256/events.out.tfevents.1770712753.srv-rech01.276823.0
new file mode 100644
index 00000000..10ac9587
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_39_13.106256/events.out.tfevents.1770712753.srv-rech01.276823.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_44_52.706001/events.out.tfevents.1770713092.srv-rech01.276979.0 b/sbi-logs/NLE_A/2026-02-10T09_44_52.706001/events.out.tfevents.1770713092.srv-rech01.276979.0
new file mode 100644
index 00000000..12b177e5
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_44_52.706001/events.out.tfevents.1770713092.srv-rech01.276979.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_46_26.291013/events.out.tfevents.1770713186.srv-rech01.277035.0 b/sbi-logs/NLE_A/2026-02-10T09_46_26.291013/events.out.tfevents.1770713186.srv-rech01.277035.0
new file mode 100644
index 00000000..84123e69
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_46_26.291013/events.out.tfevents.1770713186.srv-rech01.277035.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_48_27.781095/events.out.tfevents.1770713307.srv-rech01.277087.0 b/sbi-logs/NLE_A/2026-02-10T09_48_27.781095/events.out.tfevents.1770713307.srv-rech01.277087.0
new file mode 100644
index 00000000..3b1a0d31
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_48_27.781095/events.out.tfevents.1770713307.srv-rech01.277087.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_49_00.797833/events.out.tfevents.1770713340.srv-rech01.277139.0 b/sbi-logs/NLE_A/2026-02-10T09_49_00.797833/events.out.tfevents.1770713340.srv-rech01.277139.0
new file mode 100644
index 00000000..47041a0d
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_49_00.797833/events.out.tfevents.1770713340.srv-rech01.277139.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T09_52_12.468101/events.out.tfevents.1770713532.srv-rech01.277323.0 b/sbi-logs/NLE_A/2026-02-10T09_52_12.468101/events.out.tfevents.1770713532.srv-rech01.277323.0
new file mode 100644
index 00000000..2d8a7c79
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T09_52_12.468101/events.out.tfevents.1770713532.srv-rech01.277323.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T12_25_06.342894/events.out.tfevents.1770722706.srv-rech01.277323.1 b/sbi-logs/NLE_A/2026-02-10T12_25_06.342894/events.out.tfevents.1770722706.srv-rech01.277323.1
new file mode 100644
index 00000000..873f30e1
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T12_25_06.342894/events.out.tfevents.1770722706.srv-rech01.277323.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T12_28_33.741305/events.out.tfevents.1770722913.srv-rech01.278464.0 b/sbi-logs/NLE_A/2026-02-10T12_28_33.741305/events.out.tfevents.1770722913.srv-rech01.278464.0
new file mode 100644
index 00000000..8e7f48c3
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T12_28_33.741305/events.out.tfevents.1770722913.srv-rech01.278464.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T12_33_47.063626/events.out.tfevents.1770723227.srv-rech01.278533.0 b/sbi-logs/NLE_A/2026-02-10T12_33_47.063626/events.out.tfevents.1770723227.srv-rech01.278533.0
new file mode 100644
index 00000000..a295b274
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T12_33_47.063626/events.out.tfevents.1770723227.srv-rech01.278533.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T12_34_43.018745/events.out.tfevents.1770723283.srv-rech01.278597.0 b/sbi-logs/NLE_A/2026-02-10T12_34_43.018745/events.out.tfevents.1770723283.srv-rech01.278597.0
new file mode 100644
index 00000000..7bf1abe7
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T12_34_43.018745/events.out.tfevents.1770723283.srv-rech01.278597.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T12_35_30.106310/events.out.tfevents.1770723330.srv-rech01.278665.0 b/sbi-logs/NLE_A/2026-02-10T12_35_30.106310/events.out.tfevents.1770723330.srv-rech01.278665.0
new file mode 100644
index 00000000..79653e5c
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T12_35_30.106310/events.out.tfevents.1770723330.srv-rech01.278665.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T13_08_27.647726/events.out.tfevents.1770725307.srv-rech01.278665.1 b/sbi-logs/NLE_A/2026-02-10T13_08_27.647726/events.out.tfevents.1770725307.srv-rech01.278665.1
new file mode 100644
index 00000000..68af11d6
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T13_08_27.647726/events.out.tfevents.1770725307.srv-rech01.278665.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T13_35_17.708942/events.out.tfevents.1770726917.srv-rech01.278665.2 b/sbi-logs/NLE_A/2026-02-10T13_35_17.708942/events.out.tfevents.1770726917.srv-rech01.278665.2
new file mode 100644
index 00000000..c863b98a
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T13_35_17.708942/events.out.tfevents.1770726917.srv-rech01.278665.2 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T14_38_58.782726/events.out.tfevents.1770730738.srv-rech01.278665.3 b/sbi-logs/NLE_A/2026-02-10T14_38_58.782726/events.out.tfevents.1770730738.srv-rech01.278665.3
new file mode 100644
index 00000000..5738b0cd
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T14_38_58.782726/events.out.tfevents.1770730738.srv-rech01.278665.3 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T15_12_05.280498/events.out.tfevents.1770732725.srv-rech01.278665.4 b/sbi-logs/NLE_A/2026-02-10T15_12_05.280498/events.out.tfevents.1770732725.srv-rech01.278665.4
new file mode 100644
index 00000000..683972d8
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T15_12_05.280498/events.out.tfevents.1770732725.srv-rech01.278665.4 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T17_20_25.156000/events.out.tfevents.1770740425.srv-rech01.280061.0 b/sbi-logs/NLE_A/2026-02-10T17_20_25.156000/events.out.tfevents.1770740425.srv-rech01.280061.0
new file mode 100644
index 00000000..54e28e09
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T17_20_25.156000/events.out.tfevents.1770740425.srv-rech01.280061.0 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T17_47_08.779127/events.out.tfevents.1770742028.srv-rech01.280061.1 b/sbi-logs/NLE_A/2026-02-10T17_47_08.779127/events.out.tfevents.1770742028.srv-rech01.280061.1
new file mode 100644
index 00000000..71b0ab04
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T17_47_08.779127/events.out.tfevents.1770742028.srv-rech01.280061.1 differ
diff --git a/sbi-logs/NLE_A/2026-02-10T18_28_10.580799/events.out.tfevents.1770744490.srv-rech01.280061.2 b/sbi-logs/NLE_A/2026-02-10T18_28_10.580799/events.out.tfevents.1770744490.srv-rech01.280061.2
new file mode 100644
index 00000000..48f4cdfa
Binary files /dev/null and b/sbi-logs/NLE_A/2026-02-10T18_28_10.580799/events.out.tfevents.1770744490.srv-rech01.280061.2 differ
diff --git a/simulation_based_inference_joint-param.ipynb b/simulation_based_inference_joint-param.ipynb
new file mode 100644
index 00000000..e803ffa8
--- /dev/null
+++ b/simulation_based_inference_joint-param.ipynb
@@ -0,0 +1,2248 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "64017290",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The autoreload extension is already loaded. To reload it, use:\n",
+ " %reload_ext autoreload\n"
+ ]
+ }
+ ],
+ "source": [
+ "%load_ext autoreload\n",
+ "%autoreload 2\n",
+ "\n",
+ "import random\n",
+ "import torch\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import networkx as nx\n",
+ "import birth_death_utils as bd\n",
+ "import os\n",
+ "from collections import Counter\n",
+ "from tqdm.notebook import tqdm\n",
+ "import pickle\n",
+ "from itertools import groupby\n",
+ "import pandas as pd\n",
+ "import yaml\n",
+ "import re\n",
+ "import multiprocessing as mp\n",
+ "import seaborn as sns\n",
+ "\n",
+ "from sbi.analysis import pairplot\n",
+ "from sbi.inference import NPE, simulate_for_sbi, NLE\n",
+ "from sbi.utils import BoxUniform\n",
+ "\n",
+ "from sbi.utils.user_input_checks import (\n",
+ " check_sbi_inputs,\n",
+ " process_prior,\n",
+ " process_simulator,\n",
+ ")\n",
+ "\n",
+ "from torch import Tensor"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "79252c43",
+ "metadata": {},
+ "source": [
+ "# 1) Computation of summary statistics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "5335daff-f12b-4ac5-8a88-cfaa2a5142ca",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[5, 418, 427, 574, 845, 8, 0, 0, 2, 1, 0, 4]"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "g = bd.generate_tree_unified(0.006, 0.002, 1, 0, 1000, 1000, 500)\n",
+ "toto = bd.compute_summary_stats(g)\n",
+ "toto"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "58e884b3",
+ "metadata": {},
+ "source": [
+ "# 2) Prepare empirical data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ebc39063",
+ "metadata": {},
+ "source": [
+ "In this section we compute the summary statistics used for inference from the empirical data. These data are extracted from two different sources:\n",
+ "+ The OpenStemmata database\n",
+ "+ the table Old_French_witnesses for tradition consisting of less than 3 witnesses\n",
+ "\n",
+ "these computation are essentially similar to those found in the analysis notebook"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4f78071a",
+ "metadata": {},
+ "source": [
+ "## a) From OpenStemmata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 74,
+ "id": "3ab2ae0d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "missing witnesses dates in Ponceau_1997c_SaintGraal\n",
+ "no witnesses in Cloetta_1911_Moniage1\n",
+ "missing witnesses dates in Stimming_1920_BeuveHanstCont3-3\n",
+ "no witnesses in Herbin_2018a_Anseys\n",
+ "missing witnesses dates in Treutler_1880_Otinel\n",
+ "no witnesses in Gregory_1993_Cliges\n",
+ "missing witnesses dates in Lagomarsini_2018_GuironCourtois1\n",
+ "missing witnesses dates in Tyssens_1967_CourLouis\n",
+ "no witnesses in Jonin_1958_Yvain\n",
+ "missing witnesses dates in Korte_1914_RenMont6\n",
+ "missing witnesses dates in Ponceau_1997a_SaintGraal\n",
+ "missing witnesses dates in Bedier_1902_Tristan\n",
+ "missing work date in Bedier_1902_Tristan\n",
+ "missing witnesses dates in Bogdanow_1991_MortArtuPV\n",
+ "no witnesses in Veneziale_2020_Guiron-Cont\n",
+ "no witnesses in LePerson_2003_Fierabras\n",
+ "no witnesses in Terracher_1923_ChevVivien\n",
+ "missing witnesses dates in Wallensköld_1909_Florence\n",
+ "missing witnesses dates in Loeseth_1890_GautierdArras-Eracle\n",
+ "missing witnesses dates in Ponceau_1997b_SaintGraal\n",
+ "no witnesses in Cloetta_1911_Moniage2\n",
+ "no witnesses in Ewert_1932_GuiWarewic\n",
+ "missing witnesses dates in Weidner_1881_JosephArimathieProse\n",
+ "missing witnesses dates in Korte_1914_RenMont3\n",
+ "missing witnesses dates in Stengel_1882_GarinMonglane\n",
+ "missing witnesses dates in Stimming_1920_BeuveHanstCont3-5\n",
+ "no witnesses in Leonardi_2003_MortArtu\n",
+ "missing witnesses dates in Brodtkorb_1965_Pelyarmenus\n",
+ "missing witnesses dates in Stimming_1920_BeuveHanstCont3-4\n",
+ "missing witnesses dates in Korte_1914_RenMont4\n",
+ "missing witnesses dates in Korte_1914_RenMont5\n",
+ "missing witnesses dates in Stimming_1920_BeuveHanstCont3-2\n",
+ "no witnesses in Bogdanow_1991_QuesteTr\n",
+ "no witnesses in Bogdanow_1991_QuestePV\n",
+ "no witnesses in Palumbo_2013_Aspremont\n",
+ "missing witnesses dates in Korte_1914_RenMont1\n",
+ "missing witnesses dates in LeonardiTrachsler_2015_GuironCourtois1\n",
+ "missing witnesses dates in Constans_1912_BSteMaure-RTroie\n",
+ "missing witnesses dates in Lewis_1915_ApolloniusTyrII\n",
+ "missing witnesses dates in Korte_1914_RenMont2\n",
+ "missing witnesses dates in LeonardiTrachsler_2015_GuironCourtois2\n",
+ "missing witnesses dates in Lagomarsini_2018_GuironCourtois2\n",
+ "missing witnesses dates in Kerr_1994_AnseisCarthage\n",
+ "no witnesses in Vietor_1876_Loherains\n",
+ "no witnesses in Herbin_2018b_Anseys\n",
+ "missing witnesses dates in Bogdanow_1960_SuiteMerlin\n"
+ ]
+ }
+ ],
+ "source": [
+ "wholeCorpus = {}\n",
+ "corpus_dates = {}\n",
+ "corpus_workdates = {}\n",
+ "\n",
+ "for work in os.listdir(f'corpus_stemmata/'):\n",
+ " #print(f'{work}')\n",
+ " st = bd.load_from_OpenStemmata(f'corpus_stemmata/{work}/stemma.gv')\n",
+ " with open(f\"corpus_stemmata/{work}/metadata.txt\", 'r') as f:\n",
+ " content = f.read()\n",
+ " metadata = yaml.safe_load(content)\n",
+ " if \"wits\" in metadata:\n",
+ " dates = [wit[\"witOrigDate\"] for wit in metadata['wits'] if wit[\"witOrigDate\"] != '']\n",
+ " missing_dates = [wit for wit in metadata['wits'] if wit[\"witOrigDate\"] == '']\n",
+ " if missing_dates != []:\n",
+ " print(f\"missing witnesses dates in {work}\")\n",
+ " else:\n",
+ " print(f\"no witnesses in {work}\")\n",
+ " dates = []\n",
+ "\n",
+ " if \"workOrigDate\" in metadata and metadata[\"workOrigDate\"] != '':\n",
+ " workDate = convert_date(metadata[\"workOrigDate\"])\n",
+ "\n",
+ " else:\n",
+ " print(f\"missing work date in {work}\")\n",
+ " workDate = ''\n",
+ "\n",
+ " dates_num = []\n",
+ " for x in dates:\n",
+ " if x != '':\n",
+ " date_num = convert_date(x)\n",
+ " if date_num != None:\n",
+ " dates_num.append(date_num)\n",
+ " \n",
+ " wholeCorpus[f\"{work}\"] = st\n",
+ " corpus_dates[f\"{work}\"] = dates_num\n",
+ " corpus_workdates[f\"{work}\"] = workDate\n",
+ "\n",
+ "#ranges_per_work = {}\n",
+ "lifespans = {}\n",
+ "earliest_wit = {}\n",
+ "median_wit = {}\n",
+ "latest_wit = {}\n",
+ "sizes = {}\n",
+ "x_obs0 = {}\n",
+ "\n",
+ "for work, t_dates in corpus_dates.items():\n",
+ " #print(f\"now dating {work}\")\n",
+ " ## Now, convert all dates in time from original work\n",
+ " if t_dates and corpus_workdates[work]:\n",
+ " work_date = corpus_workdates[work]\n",
+ " relative_dates = []\n",
+ " for date in t_dates:\n",
+ " # print(f\"work_date: {work_date}, date: {date}\")\n",
+ " # Calculate the relative date difference\n",
+ " match (work_date, date):\n",
+ " case ((a, b), (c, d)):\n",
+ " if c <= a: # deal with the case of the range of a witness starts before the range of a work (should not happen, but, hey, approximate datings)\n",
+ " c = a+1\n",
+ " relative_dates.append(expected_abs_diff(a, b, c, d))\n",
+ " case ((a, b), c):\n",
+ " relative_dates.append(expected_abs_diff_degenerate(a, b, c))\n",
+ " case (c, (a, b)):\n",
+ " relative_dates.append(expected_abs_diff_degenerate(a, b, c))\n",
+ " case (a, b):\n",
+ " relative_dates.append(abs(a - b))\n",
+ " case _:\n",
+ " print(f'Error: Unexpected date format for work {work}, date {date}, work_date {work_date}')\n",
+ "\n",
+ " corpus_dates[work] = relative_dates\n",
+ " # now, get stemmatic properties\n",
+ " g = wholeCorpus[work]\n",
+ " \n",
+ " n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)\n",
+ " sizes[work] = n_living\n",
+ " degrees = []\n",
+ " direct_filiation_nb = 0\n",
+ " arch_dists = []\n",
+ " \n",
+ " if n_living >= 3:\n",
+ " st = bd.generate_stemma(g)\n",
+ " archetype = bd.root(st)\n",
+ " for n in st.nodes():\n",
+ " degrees.append(st.out_degree(n))\n",
+ " \n",
+ " if n != archetype:\n",
+ " father = list(st.predecessors(n))[0]\n",
+ " if st.nodes[n]['state'] and st.nodes[father]['state']:\n",
+ " direct_filiation_nb +=1\n",
+ " arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))\n",
+ " \n",
+ " deg_dist = Counter(degrees)\n",
+ " deg1 = deg_dist[1]\n",
+ " deg2 = deg_dist[2]\n",
+ " deg3 = deg_dist[3]\n",
+ " deg4 = deg_dist[4]\n",
+ " depth = max(arch_dists)\n",
+ " n_nodes = len(list(st.nodes()))\n",
+ "\n",
+ " x_obs0[work] = [\n",
+ " n_living,\n",
+ " 4*int(max(corpus_dates[work]) - min(corpus_dates[work])),\n",
+ " 4*int(min(corpus_dates[work])),\n",
+ " 4*int(np.median(corpus_dates[work])),\n",
+ " 4*int(max(corpus_dates[work])),\n",
+ " n_nodes,\n",
+ " direct_filiation_nb,\n",
+ " deg1,\n",
+ " deg2,\n",
+ " deg3,\n",
+ " deg4,\n",
+ " depth\n",
+ " ]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "832ef032-63a5-4863-8353-12a9d7630efd",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "75.0"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a=1151\n",
+ "b=1200\n",
+ "c=1241\n",
+ "d=1260\n",
+ "expected_abs_diff(a, b, c, d)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ffab4bae",
+ "metadata": {},
+ "source": [
+ "## b) For texts without stemmata (with 1 or 2 witnesses)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "2085670e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[50237,\n",
+ " 599,\n",
+ " 48726,\n",
+ " 608,\n",
+ " 48743,\n",
+ " 48755,\n",
+ " 644,\n",
+ " 661,\n",
+ " 687,\n",
+ " 48814,\n",
+ " 49849,\n",
+ " 725,\n",
+ " 731,\n",
+ " 732,\n",
+ " 734,\n",
+ " 48859,\n",
+ " 743,\n",
+ " 48912,\n",
+ " 49485,\n",
+ " 48976,\n",
+ " 49488,\n",
+ " 48471,\n",
+ " 48500,\n",
+ " 48543,\n",
+ " 48565,\n",
+ " 48568,\n",
+ " 48572,\n",
+ " 49097,\n",
+ " 50146]"
+ ]
+ },
+ "execution_count": 23,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df = pd.read_csv(\"Old_French_witnesses.csv\")\n",
+ "f2_works = []\n",
+ "f1_works = []\n",
+ "works = set(list(df['text H-ID']))\n",
+ "size_frags_d = []\n",
+ "size_d = []\n",
+ "for work in works:\n",
+ " n_wit = len(df[(df['text H-ID'] == work) & (df['status'] != 'fragment')])\n",
+ " n_frags = len(df[(df['text H-ID'] == work) & (df['status'] == 'fragment')])\n",
+ " if n_wit !=0:\n",
+ " size_d.append(n_wit)\n",
+ " if n_frags !=0:\n",
+ " size_frags_d.append(n_frags)\n",
+ "\n",
+ " if n_wit == 2:\n",
+ " f2_works.append(work)\n",
+ " if n_wit == 1:\n",
+ " f1_works.append(work)\n",
+ "\n",
+ "size_dist = Counter(size_d)\n",
+ "size_dist_frags = Counter(size_frags_d)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "id": "c8efabfe-752c-4f40-9a09-eb4c1bd6e0fe",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " text H-ID | \n",
+ " date_of_creation | \n",
+ " Date | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 95 | \n",
+ " 599 | \n",
+ " 1314 to 1350 | \n",
+ " 1346-1355 | \n",
+ "
\n",
+ " \n",
+ " | 96 | \n",
+ " 599 | \n",
+ " 1314 to 1350 | \n",
+ " 1436-1455 | \n",
+ "
\n",
+ " \n",
+ " | 119 | \n",
+ " 608 | \n",
+ " 1190 to 1230 | \n",
+ " 1251-1300 | \n",
+ "
\n",
+ " \n",
+ " | 121 | \n",
+ " 608 | \n",
+ " 1190 to 1230 | \n",
+ " 1301-1400 | \n",
+ "
\n",
+ " \n",
+ " | 222 | \n",
+ " 644 | \n",
+ " 1201 to 1300 | \n",
+ " 1441-1460 | \n",
+ "
\n",
+ " \n",
+ " | 223 | \n",
+ " 644 | \n",
+ " 1201 to 1300 | \n",
+ " 1296-1305 | \n",
+ "
\n",
+ " \n",
+ " | 318 | \n",
+ " 661 | \n",
+ " 1211 to 1240 | \n",
+ " 1201-1250 | \n",
+ "
\n",
+ " \n",
+ " | 320 | \n",
+ " 661 | \n",
+ " 1211 to 1240 | \n",
+ " 1201-1300 | \n",
+ "
\n",
+ " \n",
+ " | 391 | \n",
+ " 687 | \n",
+ " 1181 to 1220 | \n",
+ " 1396-1405 | \n",
+ "
\n",
+ " \n",
+ " | 393 | \n",
+ " 687 | \n",
+ " 1181 to 1220 | \n",
+ " 1241-1260 | \n",
+ "
\n",
+ " \n",
+ " | 478 | \n",
+ " 725 | \n",
+ " 1201 to 1250 | \n",
+ " 1401-1500 | \n",
+ "
\n",
+ " \n",
+ " | 479 | \n",
+ " 725 | \n",
+ " 1201 to 1250 | \n",
+ " 1338-1340 | \n",
+ "
\n",
+ " \n",
+ " | 510 | \n",
+ " 731 | \n",
+ " 1151 to 1250 | \n",
+ " 1317 | \n",
+ "
\n",
+ " \n",
+ " | 511 | \n",
+ " 731 | \n",
+ " 1151 to 1250 | \n",
+ " 1281-1320 | \n",
+ "
\n",
+ " \n",
+ " | 514 | \n",
+ " 732 | \n",
+ " 1180 to 1225 | \n",
+ " 1251-1300 | \n",
+ "
\n",
+ " \n",
+ " | 517 | \n",
+ " 732 | \n",
+ " 1180 to 1225 | \n",
+ " 1281-1300 | \n",
+ "
\n",
+ " \n",
+ " | 536 | \n",
+ " 734 | \n",
+ " 1218 to 1240 | \n",
+ " 1201-1249 | \n",
+ "
\n",
+ " \n",
+ " | 537 | \n",
+ " 734 | \n",
+ " 1218 to 1240 | \n",
+ " 1256-1295 | \n",
+ "
\n",
+ " \n",
+ " | 563 | \n",
+ " 743 | \n",
+ " 1134 to 1170 | \n",
+ " 1295 | \n",
+ "
\n",
+ " \n",
+ " | 564 | \n",
+ " 743 | \n",
+ " 1134 to 1170 | \n",
+ " 1201-1230 | \n",
+ "
\n",
+ " \n",
+ " | 644 | \n",
+ " 48471 | \n",
+ " 1281 to 1300 | \n",
+ " 1372-1381 | \n",
+ "
\n",
+ " \n",
+ " | 645 | \n",
+ " 48471 | \n",
+ " 1281 to 1300 | \n",
+ " 1340-1400 | \n",
+ "
\n",
+ " \n",
+ " | 676 | \n",
+ " 48500 | \n",
+ " 1156 to 1165 | \n",
+ " 1201-1225 | \n",
+ "
\n",
+ " \n",
+ " | 677 | \n",
+ " 48500 | \n",
+ " 1156 to 1165 | \n",
+ " 1281-1300 | \n",
+ "
\n",
+ " \n",
+ " | 844 | \n",
+ " 48543 | \n",
+ " 1191 to 1225 | \n",
+ " 1241-1260 | \n",
+ "
\n",
+ " \n",
+ " | 846 | \n",
+ " 48543 | \n",
+ " 1191 to 1225 | \n",
+ " 1288 | \n",
+ "
\n",
+ " \n",
+ " | 902 | \n",
+ " 48565 | \n",
+ " 1226 to 1230 | \n",
+ " 1251-1276 | \n",
+ "
\n",
+ " \n",
+ " | 903 | \n",
+ " 48565 | \n",
+ " 1226 to 1230 | \n",
+ " 1251-1300 | \n",
+ "
\n",
+ " \n",
+ " | 904 | \n",
+ " 48568 | \n",
+ " 1201 to 1300 | \n",
+ " 1201-1225 | \n",
+ "
\n",
+ " \n",
+ " | 905 | \n",
+ " 48568 | \n",
+ " 1201 to 1300 | \n",
+ " 1281-1290 | \n",
+ "
\n",
+ " \n",
+ " | 907 | \n",
+ " 48572 | \n",
+ " 1196 to 1210 | \n",
+ " 1211-1220 | \n",
+ "
\n",
+ " \n",
+ " | 908 | \n",
+ " 48572 | \n",
+ " 1196 to 1210 | \n",
+ " 1301-1400 | \n",
+ "
\n",
+ " \n",
+ " | 932 | \n",
+ " 48726 | \n",
+ " 1234 to 1266 | \n",
+ " 1281-1305 | \n",
+ "
\n",
+ " \n",
+ " | 933 | \n",
+ " 48726 | \n",
+ " 1234 to 1266 | \n",
+ " 1251-1300 | \n",
+ "
\n",
+ " \n",
+ " | 961 | \n",
+ " 48743 | \n",
+ " 1281 to 1300 | \n",
+ " 1470 | \n",
+ "
\n",
+ " \n",
+ " | 962 | \n",
+ " 48743 | \n",
+ " 1281 to 1300 | \n",
+ " 1276-1300 | \n",
+ "
\n",
+ " \n",
+ " | 979 | \n",
+ " 48755 | \n",
+ " 1151 to 1180 | \n",
+ " 1281-1290 | \n",
+ "
\n",
+ " \n",
+ " | 980 | \n",
+ " 48755 | \n",
+ " 1151 to 1180 | \n",
+ " 1288-1317 | \n",
+ "
\n",
+ " \n",
+ " | 1006 | \n",
+ " 48814 | \n",
+ " 1251 to 1300 | \n",
+ " 1251-1300 | \n",
+ "
\n",
+ " \n",
+ " | 1007 | \n",
+ " 48814 | \n",
+ " 1251 to 1300 | \n",
+ " 1281-1300 | \n",
+ "
\n",
+ " \n",
+ " | 1026 | \n",
+ " 48859 | \n",
+ " 1314 to 1316 | \n",
+ " 1401-1500 | \n",
+ "
\n",
+ " \n",
+ " | 1027 | \n",
+ " 48859 | \n",
+ " 1314 to 1316 | \n",
+ " 1316-1350 | \n",
+ "
\n",
+ " \n",
+ " | 1046 | \n",
+ " 48912 | \n",
+ " 1201 to 1300 | \n",
+ " 1301-1320 | \n",
+ "
\n",
+ " \n",
+ " | 1047 | \n",
+ " 48912 | \n",
+ " 1201 to 1300 | \n",
+ " 1281-1320 | \n",
+ "
\n",
+ " \n",
+ " | 1081 | \n",
+ " 48976 | \n",
+ " 1201 to 1233 | \n",
+ " 1251-1300 | \n",
+ "
\n",
+ " \n",
+ " | 1082 | \n",
+ " 48976 | \n",
+ " 1201 to 1233 | \n",
+ " 1284 | \n",
+ "
\n",
+ " \n",
+ " | 1278 | \n",
+ " 49097 | \n",
+ " 1236 to 1240 | \n",
+ " 1470 | \n",
+ "
\n",
+ " \n",
+ " | 1279 | \n",
+ " 49097 | \n",
+ " 1236 to 1240 | \n",
+ " 1276-1300 | \n",
+ "
\n",
+ " \n",
+ " | 1690 | \n",
+ " 49485 | \n",
+ " 1176 to 1225 | \n",
+ " 1241-1260 | \n",
+ "
\n",
+ " \n",
+ " | 1691 | \n",
+ " 49485 | \n",
+ " 1176 to 1225 | \n",
+ " 1281-1300 | \n",
+ "
\n",
+ " \n",
+ " | 1692 | \n",
+ " 49488 | \n",
+ " 1201 to 1300 | \n",
+ " 1301-1350 | \n",
+ "
\n",
+ " \n",
+ " | 1693 | \n",
+ " 49488 | \n",
+ " 1201 to 1300 | \n",
+ " 1301-1320 | \n",
+ "
\n",
+ " \n",
+ " | 1773 | \n",
+ " 49849 | \n",
+ " 1181 to 1190 | \n",
+ " 1301-1320 | \n",
+ "
\n",
+ " \n",
+ " | 1775 | \n",
+ " 49849 | \n",
+ " 1181 to 1190 | \n",
+ " 1201-1233 | \n",
+ "
\n",
+ " \n",
+ " | 1782 | \n",
+ " 50146 | \n",
+ " 1181 to 1220 | \n",
+ " 1301-1350 | \n",
+ "
\n",
+ " \n",
+ " | 1783 | \n",
+ " 50146 | \n",
+ " 1181 to 1220 | \n",
+ " 1288-1317 | \n",
+ "
\n",
+ " \n",
+ " | 1850 | \n",
+ " 50237 | \n",
+ " 1241 to 1280 | \n",
+ " 1341-1360 | \n",
+ "
\n",
+ " \n",
+ " | 1851 | \n",
+ " 50237 | \n",
+ " 1241 to 1280 | \n",
+ " 1281-1300 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " text H-ID date_of_creation Date\n",
+ "95 599 1314 to 1350 1346-1355\n",
+ "96 599 1314 to 1350 1436-1455\n",
+ "119 608 1190 to 1230 1251-1300\n",
+ "121 608 1190 to 1230 1301-1400\n",
+ "222 644 1201 to 1300 1441-1460\n",
+ "223 644 1201 to 1300 1296-1305\n",
+ "318 661 1211 to 1240 1201-1250\n",
+ "320 661 1211 to 1240 1201-1300\n",
+ "391 687 1181 to 1220 1396-1405\n",
+ "393 687 1181 to 1220 1241-1260\n",
+ "478 725 1201 to 1250 1401-1500\n",
+ "479 725 1201 to 1250 1338-1340\n",
+ "510 731 1151 to 1250 1317\n",
+ "511 731 1151 to 1250 1281-1320\n",
+ "514 732 1180 to 1225 1251-1300\n",
+ "517 732 1180 to 1225 1281-1300\n",
+ "536 734 1218 to 1240 1201-1249\n",
+ "537 734 1218 to 1240 1256-1295\n",
+ "563 743 1134 to 1170 1295\n",
+ "564 743 1134 to 1170 1201-1230\n",
+ "644 48471 1281 to 1300 1372-1381\n",
+ "645 48471 1281 to 1300 1340-1400\n",
+ "676 48500 1156 to 1165 1201-1225\n",
+ "677 48500 1156 to 1165 1281-1300\n",
+ "844 48543 1191 to 1225 1241-1260\n",
+ "846 48543 1191 to 1225 1288\n",
+ "902 48565 1226 to 1230 1251-1276\n",
+ "903 48565 1226 to 1230 1251-1300\n",
+ "904 48568 1201 to 1300 1201-1225\n",
+ "905 48568 1201 to 1300 1281-1290\n",
+ "907 48572 1196 to 1210 1211-1220\n",
+ "908 48572 1196 to 1210 1301-1400\n",
+ "932 48726 1234 to 1266 1281-1305\n",
+ "933 48726 1234 to 1266 1251-1300\n",
+ "961 48743 1281 to 1300 1470\n",
+ "962 48743 1281 to 1300 1276-1300\n",
+ "979 48755 1151 to 1180 1281-1290\n",
+ "980 48755 1151 to 1180 1288-1317\n",
+ "1006 48814 1251 to 1300 1251-1300\n",
+ "1007 48814 1251 to 1300 1281-1300\n",
+ "1026 48859 1314 to 1316 1401-1500\n",
+ "1027 48859 1314 to 1316 1316-1350\n",
+ "1046 48912 1201 to 1300 1301-1320\n",
+ "1047 48912 1201 to 1300 1281-1320\n",
+ "1081 48976 1201 to 1233 1251-1300\n",
+ "1082 48976 1201 to 1233 1284\n",
+ "1278 49097 1236 to 1240 1470\n",
+ "1279 49097 1236 to 1240 1276-1300\n",
+ "1690 49485 1176 to 1225 1241-1260\n",
+ "1691 49485 1176 to 1225 1281-1300\n",
+ "1692 49488 1201 to 1300 1301-1350\n",
+ "1693 49488 1201 to 1300 1301-1320\n",
+ "1773 49849 1181 to 1190 1301-1320\n",
+ "1775 49849 1181 to 1190 1201-1233\n",
+ "1782 50146 1181 to 1220 1301-1350\n",
+ "1783 50146 1181 to 1220 1288-1317\n",
+ "1850 50237 1241 to 1280 1341-1360\n",
+ "1851 50237 1241 to 1280 1281-1300"
+ ]
+ },
+ "execution_count": 38,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "f2_dates = df[df[\"text H-ID\"].isin(f2_works)]\n",
+ "f2_dates = f2_dates[(f2_dates['status'] != 'fragment')][[\"text H-ID\", \"date_of_creation\", \"Date\"]]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "id": "2af6ad2f",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(1241, 1280)\n",
+ "[(1341, 1360), (1281, 1300)]\n",
+ "(1314, 1350)\n",
+ "[(1346, 1355), (1436, 1455)]\n",
+ "(1234, 1266)\n",
+ "[(1281, 1305), (1251, 1300)]\n",
+ "(1190, 1230)\n",
+ "[(1251, 1300), (1301, 1400)]\n",
+ "(1281, 1300)\n",
+ "[1470, (1276, 1300)]\n",
+ "(1151, 1180)\n",
+ "[(1281, 1290), (1288, 1317)]\n",
+ "(1201, 1300)\n",
+ "[(1441, 1460), (1296, 1305)]\n",
+ "(1211, 1240)\n",
+ "[(1201, 1250), (1201, 1300)]\n",
+ "(1181, 1220)\n",
+ "[(1396, 1405), (1241, 1260)]\n",
+ "(1251, 1300)\n",
+ "[(1251, 1300), (1281, 1300)]\n",
+ "(1181, 1190)\n",
+ "[(1301, 1320), (1201, 1233)]\n",
+ "(1201, 1250)\n",
+ "[(1401, 1500), (1338, 1340)]\n",
+ "(1151, 1250)\n",
+ "[1317, (1281, 1320)]\n",
+ "(1180, 1225)\n",
+ "[(1251, 1300), (1281, 1300)]\n",
+ "(1218, 1240)\n",
+ "[(1201, 1249), (1256, 1295)]\n",
+ "(1314, 1316)\n",
+ "[(1401, 1500), (1316, 1350)]\n",
+ "(1134, 1170)\n",
+ "[1295, (1201, 1230)]\n",
+ "(1201, 1300)\n",
+ "[(1301, 1320), (1281, 1320)]\n",
+ "(1176, 1225)\n",
+ "[(1241, 1260), (1281, 1300)]\n",
+ "(1201, 1233)\n",
+ "[(1251, 1300), 1284]\n",
+ "(1201, 1300)\n",
+ "[(1301, 1350), (1301, 1320)]\n",
+ "(1281, 1300)\n",
+ "[(1372, 1381), (1340, 1400)]\n",
+ "(1156, 1165)\n",
+ "[(1201, 1225), (1281, 1300)]\n",
+ "(1191, 1225)\n",
+ "[(1241, 1260), 1288]\n",
+ "(1226, 1230)\n",
+ "[(1251, 1276), (1251, 1300)]\n",
+ "(1201, 1300)\n",
+ "[(1201, 1225), (1281, 1290)]\n",
+ "(1196, 1210)\n",
+ "[(1211, 1220), (1301, 1400)]\n",
+ "(1236, 1240)\n",
+ "[1470, (1276, 1300)]\n",
+ "(1181, 1220)\n",
+ "[(1301, 1350), (1288, 1317)]\n"
+ ]
+ }
+ ],
+ "source": [
+ "add_f2 = []\n",
+ "\n",
+ "for work in f2_works:\n",
+ " work_date = convert_date(f2_dates[f2_dates[\"text H-ID\"] == work][\"date_of_creation\"].values.tolist()[0].replace(' to ', '-'))\n",
+ " print(work_date)\n",
+ " t_dates = [convert_date(x) for x in f2_dates[f2_dates[\"text H-ID\"] == work][\"Date\"].values.tolist()]\n",
+ " print(t_dates)\n",
+ " if t_dates != []:\n",
+ " relative_dates = []\n",
+ " for date in t_dates:\n",
+ " # Calculate the relative date difference\n",
+ " match (work_date, date):\n",
+ " case ((a, b), (c, d)):\n",
+ " if c <= a: # deal with the case of the range of a witness starts before the range of a work (should not happen, but, hey, approximate datings)\n",
+ " c = a+1\n",
+ " relative_dates.append(expected_abs_diff(a, b, c, d))\n",
+ " case ((a, b), c):\n",
+ " relative_dates.append(expected_abs_diff_degenerate(a, b, c))\n",
+ " case (c, (a, b)):\n",
+ " relative_dates.append(expected_abs_diff_degenerate(a, b, c))\n",
+ " case (a, b):\n",
+ " relative_dates.append(abs(a - b))\n",
+ " case _:\n",
+ " print(f'Error: Unexpected date format for work {work}, date {date}, work_date {work_date}')\n",
+ "\n",
+ " add_f2.append([\n",
+ " 2, \n",
+ " 4*int(max(relative_dates) - min(relative_dates)),\n",
+ " 4*int(min(relative_dates)),\n",
+ " 4*int(np.median(relative_dates)),\n",
+ " 4*int(max(relative_dates)), -1,-1,-1,-1,-1,-1,-1])\n",
+ "\n",
+ "#print(add_f2)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "id": "03eb2614-8380-4749-bc76-c5338b096d60",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " text H-ID | \n",
+ " date_of_creation | \n",
+ " Date | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 513 | \n",
+ " 1180 to 1220 | \n",
+ " 1301-1320 | \n",
+ "
\n",
+ " \n",
+ " | 21 | \n",
+ " 546 | \n",
+ " 1180 to 1240 | \n",
+ " 1216-1235 | \n",
+ "
\n",
+ " \n",
+ " | 22 | \n",
+ " 579 | \n",
+ " 1201 to 1300 | \n",
+ " 1481-1500 | \n",
+ "
\n",
+ " \n",
+ " | 26 | \n",
+ " 584 | \n",
+ " 1167 to 1205 | \n",
+ " 1351-1400 | \n",
+ "
\n",
+ " \n",
+ " | 53 | \n",
+ " 588 | \n",
+ " 1196 to 1220 | \n",
+ " 1256-1295 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 1804 | \n",
+ " 50194 | \n",
+ " 1241 to 1260 | \n",
+ " 1301-1320 | \n",
+ "
\n",
+ " \n",
+ " | 1855 | \n",
+ " 50238 | \n",
+ " 1241 to 1270 | \n",
+ " 1251-1300 | \n",
+ "
\n",
+ " \n",
+ " | 1861 | \n",
+ " 50316 | \n",
+ " 1181 to 1220 | \n",
+ " 1268 | \n",
+ "
\n",
+ " \n",
+ " | 1862 | \n",
+ " 50320 | \n",
+ " 1281 to 1305 | \n",
+ " 1295-1305 | \n",
+ "
\n",
+ " \n",
+ " | 1863 | \n",
+ " 50323 | \n",
+ " 1101 to 1250 | \n",
+ " 1241-1300 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
106 rows × 3 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " text H-ID date_of_creation Date\n",
+ "0 513 1180 to 1220 1301-1320\n",
+ "21 546 1180 to 1240 1216-1235\n",
+ "22 579 1201 to 1300 1481-1500\n",
+ "26 584 1167 to 1205 1351-1400\n",
+ "53 588 1196 to 1220 1256-1295\n",
+ "... ... ... ...\n",
+ "1804 50194 1241 to 1260 1301-1320\n",
+ "1855 50238 1241 to 1270 1251-1300\n",
+ "1861 50316 1181 to 1220 1268\n",
+ "1862 50320 1281 to 1305 1295-1305\n",
+ "1863 50323 1101 to 1250 1241-1300\n",
+ "\n",
+ "[106 rows x 3 columns]"
+ ]
+ },
+ "execution_count": 39,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "f1_dates = df[df[\"text H-ID\"].isin(f1_works)]\n",
+ "f1_dates = f1_dates[(f1_dates['status'] != 'fragment')][[\"text H-ID\", \"date_of_creation\", \"Date\"]]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "a12543ab-3b9c-40ee-b77c-c0a29ec48fd2",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "(1180, 1220)\n",
+ "[(1301, 1320)]\n",
+ "(1290, 1298)\n",
+ "[1295]\n",
+ "(1241, 1260)\n",
+ "[(1301, 1320)]\n",
+ "(1196, 1209)\n",
+ "[(1276, 1300)]\n",
+ "(1180, 1240)\n",
+ "[(1216, 1235)]\n",
+ "(1241, 1270)\n",
+ "[(1251, 1300)]\n",
+ "(1201, 1300)\n",
+ "[(1481, 1500)]\n",
+ "(1167, 1205)\n",
+ "[(1351, 1400)]\n",
+ "(1196, 1220)\n",
+ "[(1256, 1295)]\n",
+ "(1301, 1400)\n",
+ "[(1446, 1455)]\n",
+ "(1201, 1400)\n",
+ "[(1301, 1400)]\n",
+ "(1226, 1300)\n",
+ "[(1281, 1325)]\n",
+ "(1111, 1149)\n",
+ "[(1111, 1149)]\n",
+ "(1261, 1311)\n",
+ "[1311]\n",
+ "(1301, 1350)\n",
+ "[(1301, 1350)]\n",
+ "(1234, 1266)\n",
+ "[(1267, 1300)]\n",
+ "(1201, 1267)\n",
+ "[(1262, 1300)]\n",
+ "(1200, 1225)\n",
+ "[(1251, 1300)]\n",
+ "(1201, 1300)\n",
+ "[(1301, 1400)]\n",
+ "(1301, 1350)\n",
+ "[(1301, 1350)]\n",
+ "(1306, 1315)\n",
+ "[(1401, 1500)]\n",
+ "(1276, 1300)\n",
+ "[1311]\n",
+ "(1276, 1300)\n",
+ "[(1401, 1500)]\n",
+ "(1201, 1220)\n",
+ "[(1251, 1300)]\n",
+ "(1201, 1232)\n",
+ "[(1281, 1320)]\n",
+ "(1201, 1220)\n",
+ "[(1271, 1280)]\n",
+ "(1256, 1293)\n",
+ "[(1401, 1500)]\n",
+ "(1171, 1200)\n",
+ "[(1301, 1400)]\n",
+ "(1280, 1320)\n",
+ "[(1441, 1460)]\n",
+ "(1301, 1350)\n",
+ "[(1301, 1350)]\n",
+ "(1251, 1300)\n",
+ "[(1301, 1340)]\n",
+ "(1301, 1350)\n",
+ "[(1301, 1350)]\n",
+ "(1301, 1350)\n",
+ "[(1301, 1350)]\n",
+ "(1301, 1350)\n",
+ "[(1341, 1360)]\n",
+ "(1276, 1300)\n",
+ "[1311]\n",
+ "(1201, 1284)\n",
+ "[1284]\n",
+ "(1176, 1220)\n",
+ "[(1201, 1250)]\n",
+ "(1181, 1200)\n",
+ "[(1301, 1325)]\n",
+ "(1281, 1320)\n",
+ "[(1281, 1320)]\n",
+ "(1251, 1300)\n",
+ "[(1301, 1360)]\n",
+ "(1201, 1300)\n",
+ "[(1351, 1400)]\n",
+ "(1296, 1305)\n",
+ "[(1341, 1360)]\n",
+ "(1301, 1350)\n",
+ "[(1301, 1350)]\n",
+ "(1167, 1250)\n",
+ "[(1281, 1300)]\n",
+ "(1281, 1305)\n",
+ "[(1295, 1305)]\n",
+ "(1101, 1250)\n",
+ "[(1241, 1300)]\n",
+ "(1181, 1220)\n",
+ "[(1256, 1295)]\n",
+ "(1301, 1350)\n",
+ "[(1301, 1375)]\n",
+ "(1181, 1220)\n",
+ "[(1241, 1320)]\n",
+ "(1201, 1267)\n",
+ "[(1261, 1300)]\n",
+ "(1101, 1150)\n",
+ "[(1373, 1403)]\n",
+ "(1176, 1220)\n",
+ "[(1281, 1300)]\n",
+ "(1196, 1250)\n",
+ "[(1201, 1250)]\n",
+ "(1150, 1200)\n",
+ "[(1281, 1320)]\n",
+ "(1301, 1350)\n",
+ "[(1341, 1400)]\n",
+ "(1101, 1185)\n",
+ "[(1373, 1403)]\n",
+ "(1272, 1300)\n",
+ "[(1281, 1300)]\n",
+ "(1086, 1105)\n",
+ "[(1126, 1150)]\n",
+ "(1301, 1380)\n",
+ "[(1401, 1500)]\n",
+ "(1200, 1320)\n",
+ "[(1351, 1400)]\n",
+ "(1276, 1320)\n",
+ "[1311]\n",
+ "(1254, 1260)\n",
+ "[(1251, 1276)]\n",
+ "(1301, 1333)\n",
+ "[(1301, 1320)]\n",
+ "(1268, 1291)\n",
+ "[(1286, 1351)]\n",
+ "(1196, 1220)\n",
+ "[(1281, 1320)]\n",
+ "(1196, 1205)\n",
+ "[(1241, 1260)]\n",
+ "(1231, 1265)\n",
+ "[(1281, 1320)]\n",
+ "(1226, 1245)\n",
+ "[(1281, 1320)]\n",
+ "(1301, 1355)\n",
+ "[(1346, 1355)]\n",
+ "(1181, 1200)\n",
+ "[(1401, 1500)]\n",
+ "(1181, 1200)\n",
+ "[(1251, 1300)]\n",
+ "(1101, 1200)\n",
+ "[(1241, 1260)]\n",
+ "(1301, 1400)\n",
+ "[(1401, 1500)]\n",
+ "(1181, 1220)\n",
+ "[1268]\n",
+ "(1191, 1225)\n",
+ "[(1241, 1260)]\n",
+ "(1301, 1350)\n",
+ "[(1351, 1400)]\n",
+ "(1301, 1320)\n",
+ "[(1326, 1350)]\n",
+ "(1181, 1220)\n",
+ "[(1401, 1500)]\n",
+ "(1148, 1200)\n",
+ "[(1251, 1300)]\n",
+ "(1181, 1200)\n",
+ "[(1281, 1300)]\n",
+ "(1181, 1200)\n",
+ "[(1261, 1270)]\n",
+ "(1301, 1350)\n",
+ "[(1349, 1350)]\n",
+ "(1281, 1300)\n",
+ "[(1251, 1300)]\n",
+ "(1181, 1220)\n",
+ "[(1301, 1320)]\n",
+ "(1201, 1250)\n",
+ "[(1301, 1320)]\n",
+ "(1201, 1260)\n",
+ "[(1251, 1300)]\n",
+ "(1251, 1288)\n",
+ "[(1401, 1455)]\n",
+ "(1276, 1285)\n",
+ "[(1301, 1400)]\n",
+ "(1181, 1220)\n",
+ "[(1301, 1320)]\n",
+ "(1226, 1300)\n",
+ "[(1251, 1300)]\n",
+ "(1241, 1260)\n",
+ "[(1251, 1300)]\n",
+ "(1201, 1250)\n",
+ "[(1381, 1420)]\n",
+ "(1201, 1233)\n",
+ "[(1251, 1300)]\n",
+ "(1251, 1300)\n",
+ "[(1281, 1290)]\n",
+ "(1191, 1201)\n",
+ "[(1281, 1300)]\n",
+ "(1201, 1300)\n",
+ "[(1201, 1300)]\n",
+ "(1001, 1120)\n",
+ "[(1001, 1125)]\n",
+ "(1181, 1200)\n",
+ "[(1301, 1320)]\n",
+ "(1281, 1300)\n",
+ "[(1286, 1305)]\n",
+ "(1251, 1300)\n",
+ "[(1301, 1360)]\n",
+ "(1155, 1200)\n",
+ "[1284]\n",
+ "(1201, 1250)\n",
+ "[(1281, 1290)]\n",
+ "(1301, 1400)\n",
+ "[(1301, 1400)]\n",
+ "(1226, 1250)\n",
+ "[(1231, 1275)]\n",
+ "(1188, 1220)\n",
+ "[(1276, 1300)]\n",
+ "(1201, 1251)\n",
+ "[(1351, 1500)]\n",
+ "[[1, 0, 440, 440, 440, -1, -1, -1, -1, -1, -1, -1], [1, 0, 24, 24, 24, -1, -1, -1, -1, -1, -1, -1], [1, 0, 240, 240, 240, -1, -1, -1, -1, -1, -1, -1], [1, 0, 340, 340, 340, -1, -1, -1, -1, -1, -1, -1], [1, 0, 76, 76, 76, -1, -1, -1, -1, -1, -1, -1], [1, 0, 84, 84, 84, -1, -1, -1, -1, -1, -1, -1], [1, 0, 960, 960, 960, -1, -1, -1, -1, -1, -1, -1], [1, 0, 756, 756, 756, -1, -1, -1, -1, -1, -1, -1], [1, 0, 268, 268, 268, -1, -1, -1, -1, -1, -1, -1], [1, 0, 400, 400, 400, -1, -1, -1, -1, -1, -1, -1], [1, 0, 264, 264, 264, -1, -1, -1, -1, -1, -1, -1], [1, 0, 160, 160, 160, -1, -1, -1, -1, -1, -1, -1], [1, 0, 48, 48, 48, -1, -1, -1, -1, -1, -1, -1], [1, 0, 200, 200, 200, -1, -1, -1, -1, -1, -1, -1], [1, 0, 64, 64, 64, -1, -1, -1, -1, -1, -1, -1], [1, 0, 132, 132, 132, -1, -1, -1, -1, -1, -1, -1], [1, 0, 188, 188, 188, -1, -1, -1, -1, -1, -1, -1], [1, 0, 252, 252, 252, -1, -1, -1, -1, -1, -1, -1], [1, 0, 400, 400, 400, -1, -1, -1, -1, -1, -1, -1], [1, 0, 64, 64, 64, -1, -1, -1, -1, -1, -1, -1], [1, 0, 560, 560, 560, -1, -1, -1, -1, -1, -1, -1], [1, 0, 116, 116, 116, -1, -1, -1, -1, -1, -1, -1], [1, 0, 648, 648, 648, -1, -1, -1, -1, -1, -1, -1], [1, 0, 260, 260, 260, -1, -1, -1, -1, -1, -1, -1], [1, 0, 336, 336, 336, -1, -1, -1, -1, -1, -1, -1], [1, 0, 260, 260, 260, -1, -1, -1, -1, -1, -1, -1], [1, 0, 704, 704, 704, -1, -1, -1, -1, -1, -1, -1], [1, 0, 660, 660, 660, -1, -1, -1, -1, -1, -1, -1], [1, 0, 600, 600, 600, -1, -1, -1, -1, -1, -1, -1], [1, 0, 64, 64, 64, -1, -1, -1, -1, -1, -1, -1], [1, 0, 180, 180, 180, -1, -1, -1, -1, -1, -1, -1], [1, 0, 64, 64, 64, -1, -1, -1, -1, -1, -1, -1], [1, 0, 64, 64, 64, -1, -1, -1, -1, -1, -1, -1], [1, 0, 100, 100, 100, -1, -1, -1, -1, -1, -1, -1], [1, 0, 116, 116, 116, -1, -1, -1, -1, -1, -1, -1], [1, 0, 332, 332, 332, -1, -1, -1, -1, -1, -1, -1], [1, 0, 112, 112, 112, -1, -1, -1, -1, -1, -1, -1], [1, 0, 488, 488, 488, -1, -1, -1, -1, -1, -1, -1], [1, 0, 48, 48, 48, -1, -1, -1, -1, -1, -1, -1], [1, 0, 220, 220, 220, -1, -1, -1, -1, -1, -1, -1], [1, 0, 500, 500, 500, -1, -1, -1, -1, -1, -1, -1], [1, 0, 200, 200, 200, -1, -1, -1, -1, -1, -1, -1], [1, 0, 64, 64, 64, -1, -1, -1, -1, -1, -1, -1], [1, 0, 328, 328, 328, -1, -1, -1, -1, -1, -1, -1], [1, 0, 32, 32, 32, -1, -1, -1, -1, -1, -1, -1], [1, 0, 380, 380, 380, -1, -1, -1, -1, -1, -1, -1], [1, 0, 300, 300, 300, -1, -1, -1, -1, -1, -1, -1], [1, 0, 92, 92, 92, -1, -1, -1, -1, -1, -1, -1], [1, 0, 320, 320, 320, -1, -1, -1, -1, -1, -1, -1], [1, 0, 184, 184, 184, -1, -1, -1, -1, -1, -1, -1], [1, 0, 1048, 1048, 1048, -1, -1, -1, -1, -1, -1, -1], [1, 0, 368, 368, 368, -1, -1, -1, -1, -1, -1, -1], [1, 0, 68, 68, 68, -1, -1, -1, -1, -1, -1, -1], [1, 0, 500, 500, 500, -1, -1, -1, -1, -1, -1, -1], [1, 0, 180, 180, 180, -1, -1, -1, -1, -1, -1, -1], [1, 0, 980, 980, 980, -1, -1, -1, -1, -1, -1, -1], [1, 0, 32, 32, 32, -1, -1, -1, -1, -1, -1, -1], [1, 0, 168, 168, 168, -1, -1, -1, -1, -1, -1, -1], [1, 0, 440, 440, 440, -1, -1, -1, -1, -1, -1, -1], [1, 0, 460, 460, 460, -1, -1, -1, -1, -1, -1, -1], [1, 0, 156, 156, 156, -1, -1, -1, -1, -1, -1, -1], [1, 0, 32, 32, 32, -1, -1, -1, -1, -1, -1, -1], [1, 0, 36, 36, 36, -1, -1, -1, -1, -1, -1, -1], [1, 0, 156, 156, 156, -1, -1, -1, -1, -1, -1, -1], [1, 0, 368, 368, 368, -1, -1, -1, -1, -1, -1, -1], [1, 0, 200, 200, 200, -1, -1, -1, -1, -1, -1, -1], [1, 0, 208, 208, 208, -1, -1, -1, -1, -1, -1, -1], [1, 0, 260, 260, 260, -1, -1, -1, -1, -1, -1, -1], [1, 0, 92, 92, 92, -1, -1, -1, -1, -1, -1, -1], [1, 0, 1040, 1040, 1040, -1, -1, -1, -1, -1, -1, -1], [1, 0, 340, 340, 340, -1, -1, -1, -1, -1, -1, -1], [1, 0, 400, 400, 400, -1, -1, -1, -1, -1, -1, -1], [1, 0, 400, 400, 400, -1, -1, -1, -1, -1, -1, -1], [1, 0, 252, 252, 252, -1, -1, -1, -1, -1, -1, -1], [1, 0, 168, 168, 168, -1, -1, -1, -1, -1, -1, -1], [1, 0, 200, 200, 200, -1, -1, -1, -1, -1, -1, -1], [1, 0, 108, 108, 108, -1, -1, -1, -1, -1, -1, -1], [1, 0, 1000, 1000, 1000, -1, -1, -1, -1, -1, -1, -1], [1, 0, 404, 404, 404, -1, -1, -1, -1, -1, -1, -1], [1, 0, 400, 400, 400, -1, -1, -1, -1, -1, -1, -1], [1, 0, 300, 300, 300, -1, -1, -1, -1, -1, -1, -1], [1, 0, 96, 96, 96, -1, -1, -1, -1, -1, -1, -1], [1, 0, 24, 24, 24, -1, -1, -1, -1, -1, -1, -1], [1, 0, 440, 440, 440, -1, -1, -1, -1, -1, -1, -1], [1, 0, 340, 340, 340, -1, -1, -1, -1, -1, -1, -1], [1, 0, 180, 180, 180, -1, -1, -1, -1, -1, -1, -1], [1, 0, 632, 632, 632, -1, -1, -1, -1, -1, -1, -1], [1, 0, 280, 280, 280, -1, -1, -1, -1, -1, -1, -1], [1, 0, 440, 440, 440, -1, -1, -1, -1, -1, -1, -1], [1, 0, 92, 92, 92, -1, -1, -1, -1, -1, -1, -1], [1, 0, 100, 100, 100, -1, -1, -1, -1, -1, -1, -1], [1, 0, 700, 700, 700, -1, -1, -1, -1, -1, -1, -1], [1, 0, 232, 232, 232, -1, -1, -1, -1, -1, -1, -1], [1, 0, 56, 56, 56, -1, -1, -1, -1, -1, -1, -1], [1, 0, 376, 376, 376, -1, -1, -1, -1, -1, -1, -1], [1, 0, 128, 128, 128, -1, -1, -1, -1, -1, -1, -1], [1, 0, 160, 160, 160, -1, -1, -1, -1, -1, -1, -1], [1, 0, 480, 480, 480, -1, -1, -1, -1, -1, -1, -1], [1, 0, 28, 28, 28, -1, -1, -1, -1, -1, -1, -1], [1, 0, 220, 220, 220, -1, -1, -1, -1, -1, -1, -1], [1, 0, 348, 348, 348, -1, -1, -1, -1, -1, -1, -1], [1, 0, 240, 240, 240, -1, -1, -1, -1, -1, -1, -1], [1, 0, 128, 128, 128, -1, -1, -1, -1, -1, -1, -1], [1, 0, 68, 68, 68, -1, -1, -1, -1, -1, -1, -1], [1, 0, 336, 336, 336, -1, -1, -1, -1, -1, -1, -1], [1, 0, 796, 796, 796, -1, -1, -1, -1, -1, -1, -1]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "add_f1 = []\n",
+ "for work in f1_works:\n",
+ " work_date = convert_date(f1_dates[f1_dates[\"text H-ID\"] == work][\"date_of_creation\"].values.tolist()[0].replace(' to ', '-'))\n",
+ " print(work_date)\n",
+ " t_dates = [convert_date(x) for x in f1_dates[f1_dates[\"text H-ID\"] == work][\"Date\"].values.tolist()]\n",
+ " print(t_dates)\n",
+ " if t_dates != []:\n",
+ " relative_dates = []\n",
+ " for date in t_dates:\n",
+ " # Calculate the relative date difference\n",
+ " match (work_date, date):\n",
+ " case ((a, b), (c, d)):\n",
+ " if c <= a: # deal with the case of the range of a witness starts before the range of a work (should not happen, but, hey, approximate datings)\n",
+ " c = a+1\n",
+ " relative_dates.append(expected_abs_diff(a, b, c, d))\n",
+ " case ((a, b), c):\n",
+ " relative_dates.append(expected_abs_diff_degenerate(a, b, c))\n",
+ " case (c, (a, b)):\n",
+ " relative_dates.append(expected_abs_diff_degenerate(a, b, c))\n",
+ " case (a, b):\n",
+ " relative_dates.append(abs(a - b))\n",
+ " case _:\n",
+ " print(f'Error: Unexpected date format for work {work}, date {date}, work_date {work_date}')\n",
+ "\n",
+ " add_f1.append([\n",
+ " 1, \n",
+ " 4*int(max(relative_dates) - min(relative_dates)),\n",
+ " 4*int(min(relative_dates)),\n",
+ " 4*int(np.median(relative_dates)),\n",
+ " 4*int(max(relative_dates)), -1,-1,-1,-1,-1,-1,-1])\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "01dd6a7c",
+ "metadata": {},
+ "source": [
+ "The summary statistics extracted from our two database are gathered and shuffled in a list ```x_obs_empirical``` of feature-vectors. The numbers of vectors corresponding to traditions with 1 or 2 witnesses added to the OpenStemmata is chosen so as to ensure that the median and relative proportions of tradition sizes for small tradition are the same as in the larger data corpus (contained in ```Old_French_witnesses.csv```)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "id": "f54a2630-9475-4291-87ca-7b52b15ab9ce",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Using 90 stemmata; using also 37 f1 and 10 f2 works\n"
+ ]
+ }
+ ],
+ "source": [
+ "n_works = len(set(df[df['status'] != 'fragment'][\"text H-ID\"].values))\n",
+ "freqf2 = len(set(f2_works))\n",
+ "freqf1 = len(set(f1_works))\n",
+ "\n",
+ "indf2 = round(len(x_obs0) * (freqf2 / n_works))\n",
+ "indf1 =round(len(x_obs0) * (freqf1 / n_works))\n",
+ "print(f\"Using {len(x_obs0)} stemmata; using also {indf1} f1 and {indf2} f2 works\") "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 84,
+ "id": "ce05576d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "x_obs_empirical = list(x_obs0.values()) + add_f1[:indf1] + add_f2[:indf2]\n",
+ "\n",
+ "random.shuffle(x_obs_empirical)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0627367b",
+ "metadata": {},
+ "source": [
+ "# 3) Simulation based inference --Training Neural Likelihood Estimator"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a3a2348d",
+ "metadata": {},
+ "source": [
+ "In this section we perform the parameter inference using Simulation Based inference and more specifically the Neural Likelihood method as implemented in the ```sbi``` package. We take a uniform prior on a box ```[lambda_minx_prior, lambda_max_prior] * [mu_min_prior, mu_max_prior]```, and generate ```N_samples_prior``` simulations for each setting of the model.\n",
+ "\n",
+ "*Note that pre-trained inference models are available in the ```inference_models``` folder*"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "id": "b23320eb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lambda_min_prior = 4.*10**(-3)\n",
+ "lambda_max_prior = 9.*10**(-3)\n",
+ "\n",
+ "mu_min_prior = 1.*10**(-3)\n",
+ "mu_max_prior = 5*10**(-3)\n",
+ "\n",
+ "decay_min_prior = 0\n",
+ "decay_max_prior = 1\n",
+ "\n",
+ "decimation_min_prior = 0\n",
+ "decimation_max_prior = 1\n",
+ "\n",
+ "N_samples_prior = 100#500_000 #500000\n",
+ "N_samples_posterior = 10 #1000"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "07db9bf5",
+ "metadata": {},
+ "source": [
+ "## a) Joint model training"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "id": "e94f8e9e",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "def simulator(theta):\n",
+ " lda0, mu, decay, decim = theta\n",
+ " g = bd.generate_tree_unified(lda0, mu, decay, decim, 1000, 1000, 500)\n",
+ "\n",
+ " return g \n",
+ "\n",
+ "prior = BoxUniform(low=Tensor([lambda_min_prior, mu_min_prior, decay_min_prior, decimation_min_prior]), \n",
+ " high=Tensor([lambda_max_prior, mu_max_prior, decay_max_prior, decimation_max_prior]))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "id": "9ca42777-bc5c-45e4-8d4e-d5a66f0f945d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "c6484bd714e64455b5a255f118a4f203",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/100 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "theta0 = prior.sample((N_samples_prior,))\n",
+ "\n",
+ "theta = []\n",
+ "x = []\n",
+ "\n",
+ "for t in tqdm(theta0):\n",
+ " vec = compute_summary_stats(simulator(t))\n",
+ " if vec != None:\n",
+ " theta.append(list(t))\n",
+ " x.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "id": "714526c6",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Neural network successfully converged after 100 epochs."
+ ]
+ }
+ ],
+ "source": [
+ "inference = NLE(prior=prior)\n",
+ "inference = inference.append_simulations(Tensor(theta), Tensor(x))\n",
+ "likelihood_estimator = inference.train()\n",
+ "#with open(\"pretrained_models/inference_unif.pickle\", \"wb\") as f:\n",
+ "# pickle.dump(inference, f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "8e6eac50",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#load pretrained model serialized as pickle object\n",
+ "#with open(\"pretrained_models/inference_unif.pickle\", \"rb\") as f:\n",
+ "# inference = pickle.load(f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "a9221c7f-de15-463c-8cf1-cae68a512198",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/home/jbcamps/Data/F/Articles_et_CR/2022_Article_Silva_portentosa/ExtinctionOfTexts/env/lib/python3.12/site-packages/sbi/inference/posteriors/mcmc_posterior.py:126: UserWarning: The default value for thinning in MCMC sampling has been changed from 10 to 1. This might cause the results differ from the last benchmark.\n",
+ " thin = _process_thin_default(thin)\n"
+ ]
+ }
+ ],
+ "source": [
+ "#posterior = inference.build_posterior(sample_with=\"rejection\")\n",
+ "posterior = inference.build_posterior()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d4ee9dae",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "09d6bff772db47048eecb738a8046c1c",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Generating 20 MCMC inits via resample strategy: 0%| | 0/20 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "samples = posterior.sample(\n",
+ " (N_samples_posterior,),\n",
+ " x=x_obs_empirical\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "753eb92a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_ = pairplot(\n",
+ " samples,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [decay_min_prior, decay_max_prior], [decimation_min_prior, decimation_max_prior]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"decay\", r\"decimation\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "746d67b9",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_112805/245841850.py:4: UserWarning: \n",
+ "\n",
+ "`distplot` is a deprecated function and will be removed in seaborn v0.14.0.\n",
+ "\n",
+ "Please adapt your code to use either `displot` (a figure-level function with\n",
+ "similar flexibility) or `histplot` (an axes-level function for histograms).\n",
+ "\n",
+ "For a guide to updating your code to use the new functions, please see\n",
+ "https://gist.github.com/mwaskom/de44147ed2974457ad6372750bbe5751\n",
+ "\n",
+ " sns.distplot(df_samples['model'], hist=True, kde=True,\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAGwCAYAAACHJU4LAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAVdpJREFUeJzt3Xd803X+B/BX0pWk6YYuKFAopVCgBSplCjIEFA6ciMpQFD3RUxF+yumBd3rHoae4OBBliKKgMkWmTNlQVtkbSidN6UibpCPf3x8c1fr9posm32+S1/PxyOOOz/eb9N0I6aufqRIEQQARERGRAqnlLoCIiIjIFgYVIiIiUiwGFSIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsBhUiIiJSLE+5C7gTVqsVGRkZ8PPzg0qlkrscIiIiqgVBEFBUVITIyEio1dX3mTh1UMnIyEBUVJTcZRAREVE9pKWloWnTptXe49RBxc/PD8Ctb9Tf31/maoiIiKg2CgsLERUVVflzvDpOHVRuD/f4+/szqBARETmZ2kzb4GRaIiIiUiwGFSIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsT7kLICLXYTQaYTaba7xPo9FAr9c7oCIicnYMKkTUIIxGI+bNWwyDobjGe0NCfDFhwhiGFSKqEYMKETUIs9kMg6EYWm0cdDo/m/eVlBTBYDgDs9nMoEJENWJQIaIGpdP5Qa8PqvYek8lBxRCR0+NkWiIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsBhUiIiJSLAYVIiIiUiwGFSIiIlIsbqFPRG6DpzsTOR8GFSJyCzzdmcg5MagQkVvg6c5EzknWOSpvv/02VCpVlUdcXJycJRGRi7t9urOtR3UhhogcT/Yelfj4ePzyyy+Vf/b0lL0kIiIiUgjZU4GnpyfCw8PlLoOIiIgUSPblyefPn0dkZCRatmyJJ554AteuXbN5r8ViQWFhYZUHERERuS5Zg0pycjIWLVqEDRs2YM6cObh8+TJ69+6NoqIiyftnzJiBgICAykdUVJSDKyYiIiJHkjWoDBkyBI888gg6duyIQYMGYd26dcjPz8f3338vef/UqVNRUFBQ+UhLS3NwxURERORIss9R+b3AwEDExsbiwoULktd9fHzg4+Pj4KqIiIhILooKKkajERcvXsTo0aPlLoXILXCnViJSOlmDyuTJkzFs2DA0b94cGRkZmD59Ojw8PDBq1Cg5yyJyC9yplYicgaxB5fr16xg1ahQMBgMaN26MXr16Yd++fWjcuLGcZRG5Be7USkTOQNagsnTpUjm/PBHht51aq2MyOagYIqI/kH0fFSIiIiJbGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLEYVIiIiEixGFSIiIhIsRhUiIiISLE85S6AiJyX1Srg+PEbOHo0Bzdu5OPgQSA01IB27TQICdFApVLJXSIROTkGFSKqs9OnDfjgg0P46aeLyMkp+d0VFYDLAC4jKMgHXbqEYcCA5ggK0shUKRE5OwYVIqq1jAwjpk3bjYULT8BqFaq99+ZNC3755Rq2bUtD9+6RGD48Bv7+3g6qlIhcBYMKEdXK1q3p+POff0VenrlOz6uoELBrVzqOHs3BqFFxiIvzsVOFROSKOJmWiKolCAJ27QIee2xznUPK7xmNZfjii1R8++1llJU1YIFE5NIYVIjIJkEQsHz5NezcqYJQ/UhPraWkGPDNN0BmZnHDvCARuTQGFSKSJAgCvvvuDPbuvWHzHm9vDzz7bEf89NMD2LfvATz3nIAnnohGUlIYqlvwk5mpwsCBa3H8uO3XJiICOEeFiGxYvvw8duy4bvP6gw+2xocf9kXz5gEAgNzcXISEALGxIbj77hiMGFGCH388j6NHcySfn51twt13L8WaNSNw991RdvkeiMj5sUeFiER27UrH5s1XJa95eKgwa9Y9+PHHP1WGFCmNG+vw/PMd8cwzHaDVSv9OVFBgwb33/ojVqy80SN1E5HoYVIioigsXbuLbb09LXvPyUmP16hF45ZUutdrMTaVS4a67wjF1aleEhekk77FYKvDgg6uxYEHqHdVNRK6JQz9EVCk/34y5c4+hokI8c9bLS43ly4fj/vtb1fl1w8J8MXVqV3z++XGcPp0num61Chg/fiNyckrw+utd67yjrdFohNlc/Yokg8GA0lIuNyJyNgwqRATgVlhYtOgkioqkf5h/9lkvDBtW95Bym1brhYkTO+GLLw7j2LGbkvdMnforsrNL8MEHfaFW1y6sGI1GzJu3GAZD9auISkqKkZp6FkFBSdDr61w+EcmEQYWIAAC//HJVsrcDAHr0EPDggy3v+Gt4eanx5JMt4el5CCkp0kHko49ScONGCRYsGAxvb48aX9NsNsNgKIZWGwedzs/mfVZrOkymVJSXs1eFyJlwjgoR4dq1QqxaJT2hNT4+EH36NNzXUqtVuPde4PXXE23es2TJafzpTytRXFxa69fV6fyg1wfZfGi17EYhckYMKkRurqLCiq++Oik5LyUoSIPHHmtR7Z4o9aFSAZMnJ2LOnAE2X3vjxivo1+97pKUVNuwXJyKnwqBC5Oa2bcvG9etGUbtKBTz9dDx0OvuNED//fCK+/36YzSGeAweykJi4GGvWcPkykbtiUCFyY7m5wObNGZLXBg+ORmxssN1rePjhNli//iH4+UmfrJyXZ8bw4aswatRapKcX2b0eIlIWBhUiNyUIAjZsAMrLxUM+kZF6DB1655Nna6tfv2bYvn0kQkOl91oBgKVLzyAubgH+7/92ICND3ANERK6JQYXITa1YcRnXrokniKhUwJgx7eDp6diPh86dw7B79yjExATavMdoLMP77x9EixbzMGLEKixdegYFBRbHFUlEDsflyURuqKioFNOnH5S81q9fM0RH294a355iYoJw6NBoPPfcJixbdtbmfWVlVqxefQGrV1+AWq1CWBgQF3cdHTtaERMTWKtlzUTkHBhUiNzQO+/sRXa2SdQeFOSD4cNjZKjoNwEBPvjuu6EYMKA5XnttOwoLq1+ibLUKyMxUITMzC9u2ZcHTU4WWLQMRFxeMpKQwhIX5OqZwIrILBhUiN3Phwk3MmpUiee2RR9rAx0f+3giVSoVnnumIoUNb4fXXd2Dx4lO1fm55uYBz527i3LmbWLPmImJiAnHPPVGIjBTPxSEi5eMcFSI38+abu1BebhW1x8UFo3PnUBkqsi083BdffXUfDh16Eo8+2qbW2+r/3oUL+fjii1R88UUaCgr87VAlEdkTgwqRGzl4MBPffy+e+6FWqzByZJs6HwboKF26hGPZsmE4f348pk/vjtjYoDq/RkaGBSdPxmPt2kyUlYmDGhEpE4MKkZsQBAH/9387Ja/dfXdTREYqf4v5li0D8fbbPXHmzNM4cWIcPv64HwYPjoKPT+2HdQ4ezMd77x1Abq54jg4RKY9igsq///1vqFQqvPLKK3KXQuSSNmy4jO3b00TtPj5q3H+/4/ZMaQgqlQrx8Y3wl790xtdf98errwIvvxyHESNi0LZtMDw8qu8ZunatCDNnHkBWVvUnLhOR/BQxmfbgwYP4/PPP0bFjR7lLIXJJFRVWvP66dG9K377h8PeX3hXWWajVQLNmerRrF4QhQ6JhNJbiwIEsbNlyzWbPSWFhKT744BBeey0J4eFcGUSkVLL3qBiNRjzxxBP44osvEBRU93FnIqrZN9+cQmpqrqjd11dAnz5hMlRkX3q9N/r1a4a33+6BRx6Jhbe39EddYWEpZs1KQV4eh4GIlEr2oDJx4kTcf//9GDBgQI33WiwWFBYWVnkQUfXM5nL87W+7Ja/16gVFLEe2Fy8vNQYMaI6pU5PRuLF0r1F+vgVz5x5HWVmFg6sjotqQNagsXboUhw8fxowZM2p1/4wZMxAQEFD5iIqKsnOFRM7vs8+OIC1NfJhfq1b+SEx0fD1yiIzU49lno+DvL/3LzdWrhVi61PZOuEQkH9mCSlpaGl5++WUsWbIEGo2mVs+ZOnUqCgoKKh9paeKJgUT0m+LiUrz33gHJa2++2RkertuZIuLjo0bbtqfRrJlW8vquXenYs0f6JGkiko9sQSUlJQU5OTno3LkzPD094enpiR07duCTTz6Bp6cnKirE3bA+Pj7w9/ev8iAi2z7//Dhu3BDPv0hOjsDQoc1lqEheHh5WPPFElM3Js8uWnUV+fvVb9hORY8kWVPr374/U1FQcPXq08pGUlIQnnngCR48ehYc7/apHZAcmU5nN3pR//rOXYjd3szeNxgPPP99Rcm6O2VyO5cuvQuBu+0SKIdvyZD8/P7Rv375Km6+vL0JCQkTtRFR3X3yRiuzsElF7z55N0K9fMxgMBhmqUoaICD3Gjo3HvHnHRddOnSpA69YyFEVEkmRf9UNEDc9sLsfMmdK9KdOmdXfb3pTf69IlDN26RUhe27QJKCiwOLgiIpKiiA3fbtu+fbvcJRApntFohNlsrvaer7++gIwMo6g9OTkCAwfKPzeltNRSqx4djUYDvd5+W/s/8kgsTp40oKio6rwUk0mFjz5KxaefNrHb1yai2lFUUCGi6hmNRsybtxgGg+2t38vLgc8/l+4sVUJvisViwpEjxzF3rhU6nfQKnNtCQnwxYcIYu4UVvd4bo0bFSQ4BzZt3Cq++2g0tWwba5WsTUe0wqBA5EbPZDIOhGFptHHQ6P8l7duxIQ0FBtqi9S5cwDBkSbe8Sa1RWVgqTqQJabRuEhNjeFbekpAgGwxmYzWa79qp07hyK9u1DcOJE1R6e0lIr3nhjJ77//k92+9pEVDMGFSInpNP5Qa8XHzlRUWHFrl3i3gFAGb0pv6fR6CW/h98zOWBne5VKhYceisWpU/tgtVZd7vPDD+ewd28GunePtH8hRCSJk2mJXMjBg9nIyxPvA5KQ0BjDhrWSoSLnEBmpR+/e0vNRpk2TPn6AiByDQYXIRQiCgF9+uSp5TWm9KUo0bFgraDTiTuZffrmKX3+9LkNFRAQwqBC5jDNn8iTP9GnbNhgjRnBjkJr4+Xnj3nulV0RNn85eFSK5MKgQuYjNm6V7UyZPvgtqNXtTaqNfv2bQ6cQ71m7bloYdO3i2GJEcGFSIXEB6uhEnT4r3JQkL0+GJJ9rKUJFz0mo90bdvuOS1d9/d5+BqiAjgqh8il2CrN2X8+DgUFeWjSDwiBIPBgNLSslq9fm02aKvL6ylZz56h2LbtOkymqr1Qv/xyFUeP5iAxMVSmyojcE4MKkZPLzzfjwIFMUbunpwCTKQWzZqVIPq+kpBipqWcRFJSE6rYpqe0GbbV9PaXTaDyQnAxIbZT9n/8cxDff3O/wmojcGYMKkZPbti0NFRXi434TEvzQtGmczedZrekwmVJRXl59L0htN2ir7es5g86dgYMHPVFcXF6lfenSM/jXv3qjWTN/mSojcj+co0LkxMzmcuzcKbV0VkCvXmHQ64NsPrTaunV73N6graFeT8k0GmD06FhRe0WFgI8/lu6hIiL7YFAhcmK7d2egpKRc1B4SYkBwsLcMFbmOCRPawcNDvFpq3rzjyM+v/lBIImo4DCpETspqFbB16zXJa5GR4jkrVDdRUXqMHCkeOjMay/D558dkqIjIPTGoEDmpU6cMyM0VH4bTvLkGfn5GGSpyPZMnJ0m2f/zxYVgs4p4sImp4DCpETmr7dukNyLp1q/6gP6q9Tp3C0L9/M1F7ZmYxvvvujAwVEbkfBhUiJ5SXZ8GJE7mi9sBAH7Rp4ytDRa5rypS7JNv/85+DEATxaisialgMKkROaO/eG5D6GXn33U0lJ4BS/d17bwt06NBI1H7ypMHmRntE1HAYVIicTHk5sH+/uDdFrVahV68mMlTk2lQqFSZPlu5V+fTTww6uhsj9MKgQOZkzZyDaiAwAOnUKRUCAjwwVub7HHotDRIR4SO3nny/h4sV8xxdE5EYYVIicTIqN/cb69o1ybCFuxNvbA88/nyBqFwRg9uwjMlRE5D4YVIicyPHjBqSni+egREb6onXrQMcX5EYmTEiAl5f4I3PBghMwGktlqIjIPTCoEDmRhQull8T26RMFlYqTaO0pPNwXjz7aRtReUGDBN9+ckqEiIvfAoELkJPLzzVi+/JKo3cfHA8nJETJUZH+lpRYYDAbk5ubafBgMBpSWOuYgxL/8pbNk+2efHeFSZSI74enJRE5iyZLTMJkqRO3dukVAq3W9f8oWiwlHjhzH3LlW6HRam/eVlBQjNfUsgoKSoLfzuYhdu0aga9dwHDiQVaX95EkDtm1LQ79+4s3hiOjOuN6nG5GLWrjwhGR7nz6uOYm2rKwUJlMFtNo2CAkJs3mf1ZoOkykV5eWO6VV56aXOGD16naj9008PM6gQ2QGHfoicQGrqDaSkZIvaW7YMQJMmdu5GkJlGo4deH2TzodU69vt/5JFYhIbqRO1r1lzE1asFDq2FyB0wqBA5gUWLpHtTevSIdHAl5OPjieee6yhqt1oF/Pe/Rx1fEJGLY1AhUriysgp8881pUbuXlxpJSeEyVETPP58IT0/xx+cXXxxHWlqWaMKv0cjTrInqi3NUiBRu3brLyMkpEbV37hzmkpNonUFkpB7Dh0dj+fKLVdpv3rTg+ee/RmJi1ftDQnwxYcIY6O0925fIBbFHhUjhbE2i5bCPvJ56Klay/ehRHYKDkxASchdCQu6CVhsHg6EYZrPZwRUSuQYGFSIFy8kpxs8/i/dOCQ72RmxskAwV0W1du4YiLEy8d0pGhgmZmarKyb46nZ8M1RG5DgYVIgVbsuQ0ysutovakpBCo1dyJVk4qlQpJSdLXtm275thiiFwYgwqRQgmCYHPYJympkYOrISnx8YCvr3ie0NGjN5CXx6EeoobAoEKkUIcPZyM1NVfU3ry5gJAQHxkqoj/y9AS6dROHRqtVwM6d12WoiMj1MKgQKZSt3pSO4i08SEbdu4dKDsP9+ut1lJWJjzwgorphUCFSoLKyCixdelbUrtd7IS5OhoLIpqAgbyQmNha1G41lOHRIvJswEdUNgwqRAm3Zcg0Gg0nUPmJEC3h5yVAQVeuee6TPW9q69RpPVSa6QwwqRAr03XfinWgB4OGHWzm4EqqN1q2DJM9cunatCFevFstQEZHrYFAhUhizuRwrV14QtUdG6tGtW6gMFVFNVCqVzV6V3btzHFwNkWthUCFSmPXrL6OoqFTU/uijbeDhwX+ySpWcHAGdTrxU+dixm+BRP0T1x089IoWxNewzahRn0SqZt7cHevZsImqvqBBw7JgMBRG5CAYVIgUpKirF2rXiLfOjowNw1108KVnp+vRpCpXEhsGHD0Nyh2EiqhmPXiVSkJ9+ugiTqVzU/thjcVBJ/QQkRWncWIf4+EY4caLqRn1FRSr88MMpjBpV/e+GGo2GJywT/QGDCpGC2Br2eewxDvs4i3vuiRIFFQB47739yMo6WO1zQ0J8MWHCGIYVot9hUCFSiLw8EzZuvCJqb9cuBB068GwfZ9GuXQgaN9bixo2q++Bcv+6BsrJ4hIdrJZ9XUlIEg+EMzGYzgwrR73COCpFCrFx5AWVl4nkMHPZxLmq1Cn36NJW8duBAAfT6IMmHTufn4EqJnAODCpFCLF16RrJ95Mg2Dq6E7lSPHk3g5SX+eN23L1NyDhIR2cagQqQAWVnF2Lr1mqi9c+cwxMYGy1AR3QlfXy907SpepWWxVGDfvgwZKiJyXgwqRAqwYsU5WK3iM2G4d4rz6ttXeqfa7duv8/wfojpgUCFSgBUrzku2P/ooh32cVbNm/mjVKkDUnpVVjDNn8mSoiMg51SuoXLok3pCKiOonL8+E7dvTRO3JyRFo1sxfhoqooVTXq0JEtVOv5ckxMTHo06cPxo8fj4cffhgajaah6yJyGz/9dBEVFeKhgEGDIpGbW3U/DoPBgNLSMkeV5rZKSy0wGAzV3lOb/xadO4dh2bLTMBorqrQfO5aDvDwTgoOllyoT0W/qFVQOHz6MhQsXYtKkSXjxxRcxcuRIjB8/Hl27dm3o+ohcntRJyQCQk3MIs2YdqtJWUlKM1NSzCApKArfasA+LxYQjR45j7lwrdDrbQaI2/y08PdXo0iUAO3ZUHeoRBGDnznSMGBHTkKUTuaR6Df0kJibi448/RkZGBhYsWIDMzEz06tUL7du3x4cffogbN240dJ1ELqm4uFRyk7fwcC1at74LISFVHxpNa5hMpSgvZ6+KvZSVlcJkqoBW20b0/tfnv0VSUgAAcY/Zrl3XJffNIaKq7mgyraenJx588EH88MMPmDlzJi5cuIDJkycjKioKY8aMQWZmZkPVSeSSNmy4ArNZvK9Gly7hkpuCabXsRnEUjUZvc3O2uvy38Pf3REiIePJsUVEZjh7NaeiyiVzOHQWVQ4cO4YUXXkBERAQ+/PBDTJ48GRcvXsTmzZuRkZGB4cOHV/v8OXPmoGPHjvD394e/vz+6d++O9evX30lJRE5l5Urp1T6JiaEOroTsKTw8S7L911/THVwJkfOp1xyVDz/8EAsXLsTZs2dx3333YfHixbjvvvugVt/KPdHR0Vi0aBFatGhR7es0bdoU//73v9G6dWsIgoCvvvoKw4cPx5EjRxAfH1+f0oicRmlpBdauFa+gCwnRICqK26m7En//QoSEeMNgKK3SfvZsHnJyShAaqpOpMiLlq1ePypw5c/D444/j6tWrWLVqFYYOHVoZUm4LDQ3F/Pnzq32dYcOG4b777kPr1q0RGxuLf/7zn9Dr9di3b5/k/RaLBYWFhVUeRM5q27ZrKCiwiNoTE0N5to+LUamALl0CJa/t2sVeFaLq1CuobN68Ga+//joiIiKqtAuCgGvXbm0D7u3tjbFjx9b6NSsqKrB06VIUFxeje/fukvfMmDEDAQEBlY+oKOk9Coicga1N3jp35rCPK0pMDICnpziA7tmTgfJyTqolsqVeQaVVq1ai/R0AIC8vD9HR0XV6rdTUVOj1evj4+OD555/HypUr0a5dO8l7p06dioKCgspHWpp4kywiZ1BRYcXq1eJlyXq9J1q2DHR8QWR3vr6e6NRJHEKLikpx7BhXShLZUq+gYuucCqPRWOfN39q0aYOjR49i//79+POf/4yxY8fi1KlTkvf6+PhUTry9/SByRvv2ZSI7u0TU3r59INRqDvu4ql69mkq2c/iHyLY6TaadNGkSAEClUmHatGnQ6X6bAFZRUYH9+/cjMTGxTgV4e3sjJubWpkddunTBwYMH8fHHH+Pzzz+v0+sQKZXRaITZbK7StmTJccl7O3QIckRJJJPY2CCEhmqRk2Oq0n7qlAEGQ6RMVREpW52CypEjRwDc6lFJTU2Ft7d35TVvb28kJCRg8uTJd1SQ1WqFxSKeYEjkjIxGI+bNWwyDobiyTRCA774DgKo9Jx4eFWja1MexBZJDqdUq9OrVVHJ+0v79N5CcLENRRApXp6Cybds2AMBTTz2Fjz/++I6HXqZOnYohQ4agWbNmKCoqwrfffovt27dj48aNd/S6REphNpthMBRDq42DTndryXFWlgn5+SdF9wYF5QGoELWTa+nePRKrV18Qne908KABSUkyFUWkYPXaR2XhwoUN8sVzcnIqd7ANCAhAx44dsXHjRgwcOLBBXp9IKXQ6P+j1t4Z1LlzIl7wnOPimAysiufj7eyMhoTEOH666K21hYRkuSB/7ROTWah1UHnzwQSxatAj+/v548MEHq713xYoVtXrNmvZZIXJFx4+LV3io1UBgYL7jiyFZ9O7dVBRUAODYMRmKIVK4WgeVgICAyk2oAgIC7FYQkSsrKirFpUsFovYWLbTw9OSwj7uIiwtGo0Za5OZWnVR76RJw7lxGjc/XaDTQ8/hschO1Diq/H+5pqKEfIndz4kQupFb3x8b6ghstuw+1WoUePSKxZs3FKu1Wqwp//eta9OzpVe3zQ0J8MWHCGIYVcgv1mqNiMpkgCELl8uSrV69WbtR27733NmiBRK5EatgHANq08cXBgw4uhmSVnBwhCioAcPasL/70pwSbzyspKYLBcAZms5lBhdxCvTZ8Gz58OBYvXgwAyM/PR9euXfHBBx9g+PDhmDNnToMWSOQqysutOHXKIGqPiPBFcLC3xDPIlTVqpEXr1oGi9qysMhQWekGvD5J83F49RuQu6hVUDh8+jN69ewMAfvzxR4SHh+Pq1atYvHgxPvnkkwYtkMhVnDt3E2azeB5Khw6NZaiGlKBbN+lN3vbuzXRwJUTKVa+gUlJSAj+/W6l+06ZNePDBB6FWq9GtWzdcvXq1QQskchW2hn0SEho5uBJSii5dQuHlJf4YPnAgE1ar9FElRO6mXkElJiYGq1atQlpaGjZu3Fg5LyUnJ4fn7xBJEARBMqj4+nrxEEI3ptV6ITFR3KOWn2/BmTN5MlREpDz1CirTpk3D5MmT0aJFCyQnJ6N79+4AbvWudOrUqUELJHIF2dlmGAxmUXuHDo14CKGbszX8s28fh3+IgHqu+nn44YfRq1cvZGZmIiHht9np/fv3xwMPPNBgxRG5ipMn8yXbO3bk/BR317ZtMPz9vVFYWFql/ciRbJjNcdBo6vUxTeQy6tWjAgDh4eHo1KkT1OrfXqJr166Ii4trkMKIXMmpU/miNrVahXbtgh1fDCmKh4caXbuGi9pLS604ckS8ey2Ru6lXVC8uLsa///1vbNmyBTk5ObBarVWuX7p0qUGKI3IFxcXA1avFovbY2CBotdVv7EXuoVu3SPzyyzVR+969mejeXXpoiMhd1CuoPPPMM9ixYwdGjx6NiIiIyq31iUjs4kVI7kbLYR+6LSrKD2Fh3sjOrjr8c+5cHvLyzAgO1shUGZH86hVU1q9fj59//hk9e/Zs6HqIXI6tE3E7duSyZPpNQoI/Nm3KrdImCMDhw9kYMKC5TFURya9ec1SCgoIQHMyxdaKalJZWQGokNCLCF40b6xxfEClWx45+AMRdb4cOZTu+GCIFqVdQeeeddzBt2jSUlJQ0dD1ELmXPnmyUloqHRjnsQ3/k5+cJf3/xyZSXLxeITlkmcif1Gvr54IMPcPHiRYSFhaFFixbw8qo6IfDw4cMNUhyRs9u4MU2yncM+JKVRIwMKCwNE7Skp2Rg0qIXjCyJSgHoFlREjRjRwGUSuRxAEbNokDircjZZsCQ7Ow+XLLUWTrxlUyJ3VK6hMnz69oesgcjmnThlw7ZpR1M7daMkWb+8yREfrcOlS1WH1q1cLceNGCec1kVuq94Zv+fn5+PLLLzF16lTk5d06k+Lw4cNIT09vsOKInNlPP12UbOf8FKpOfLz0eWkpKZxUS+6pXkHl+PHjiI2NxcyZM/Gf//wH+fn5AIAVK1Zg6tSpDVkfkdOSCioeHiq0axciQzXkLNq29ZPscePqH3JX9QoqkyZNwrhx43D+/HloNL9tRHTfffdh586dDVYckbO6caMEe/dmiNpv7UbLs1vINl9fT8TFibd/SEsrQna2eIdjIldXr6By8OBBPPfcc6L2Jk2aICsr646LInJ269ZdktyNtkMHDvtQzZKSwiTb2atC7qheQcXHxweFheL1/ufOnUPjxvwgJlq7Vvq8Ky5LptpITAzl8A/R/9QrqPzpT3/CP/7xD5SVlQEAVCoVrl27htdffx0PPfRQgxZI5GxKSyuwceMVUTt3o6Xa8vX1kpzLlJFhRFYWN38j91KvoPLBBx/AaDSicePGMJlM6NOnD2JiYuDn54d//vOfDV0jkVPZsSMNRUWlonau9qG6sDX8c+xYnoMrIZJXvWb1BQQEYPPmzdi9ezeOHTsGo9GIzp07Y8CAAQ1dH5HT4bJkaggJCY3h6alCeXnVyU7Hj+cjKUmmoohkUOegYrVasWjRIqxYsQJXrlyBSqVCdHQ0wsPDIQgCVCpuZEXuSxAEyfkpOp0nWrYUb41OZItOd2v45/jxqicqZ2WZkMdOFXIjdRr6EQQBf/rTn/DMM88gPT0dHTp0QHx8PK5evYpx48bhgQcesFedRE7hxIlcXL5cIGpv2zaAu9FSnXXqJD38c/asgwshklGdelQWLVqEnTt3YsuWLbjnnnuqXNu6dStGjBiBxYsXY8yYMQ1aJJGzWL36gmR7fDx7U6juOna8ddyC1Vp1+OfcOZkKIpJBnXpUvvvuO/z1r38VhRQA6NevH9544w0sWbKkwYojcjZSQcXDQ0CbNgwqVHd6vTdatw4Staenq5CVVSLxDCLXU6egcvz4cQwePNjm9SFDhuDYsWN3XBSRM0pPL5Lc56J5c0Cj8ZChInIFnTqFSravW3fNwZUQyaNOQSUvLw9hYdJjpgAQFhaGmzdv3nFRRM5ozRrp1T6xsQ4uhFxKYqL0arF16646uBIiedQpqFRUVMDT0/a0Fg8PD5SXl99xUUTOyNb8lNatHVwIuZSgIA1atBCfqLx7dxby8rj5G7m+Ok2mFQQB48aNg4+Pj+R1i8XSIEUROZvCQgu2bhV3xXfq1Ah+fjdkqIhcSadOobhypeqxJeXlt5bCjxkTL1NVRI5Rpx6VsWPHIjQ0FAEBAZKP0NBQrvght7Rhw2WUlVlF7YMHR8lQDbkaW/NUVq487+BKiByvTj0qCxcutFcdRE5t9Wrp+SlDhjTDhg2HHVwNuZqwMF9ERvoiI6O4SvvGjVdQXFwKX19vmSojsr96nfVDRL8pK6vAunXi3WhbtgxAXFyg4wsil5SYKO5VMZnKJQ/AJHIlDCpEd2jnzuvIzxfPzxo+PIZHSlCDsT38Iz2Jm8hVMKgQ3SFbq32GD49xcCXkyqKi/BASohG1r117EaWlFTJUROQYDCpEd0AQBMmgEhysQc+eTWSoiFyVSqWSHP7Jz7dg+/Y0GSoicgwGFaI7cOzYDVy7ViRqHzq0JTw9+c+LGpat4R9bvXpEroCfpER3YNUq6eWhHPYhe2jVKhC+vuLFmqtXX4AgCBLPIHJ+DCpEd+CHH8TH2Pr4eODee1s4vhhyeWq1CvHxgaL29HQjUlLE50wRuQIGFaJ6OnkyF6dOGUTtgwa1gF7PfS3IPtq3D5RsX7WKwz/kmhhUiOppyZJUyfYhQyKRm5uL3NxcGAwGlJaWObgycmWxsf7w8hIP89gahiRydnXamZaIbjEajViwQLzjrIeHgAsXdmLWrJ0AgJKSYqSmnkVQUBL0ekdXSa7Iy0uN6Gjg3B9GHU+eNODChZuIiQmSpzAiO2GPClE9HD2aiexs8W+1cXFBiIy8CyEhtx4aTWuYTKUoL2evCjWcNm2k27n6h1wRgwpRPaxZc0WyPTm5KfT6oMqHVstuFGp4rVoBHh7iXY85T4VcEYMKUT2sXn1F1ObpqUbHjo0dXwy5HZ0O6NYtTNS+e3c6cnKKJZ5B5LwYVIjq6OTJXJw7VyBqj48PgVbLaV/kGEOGNBO1CQLw00/iAzKJnBmDClEd/fDDWcn2Ll3Ev+ES2cuQIVGS7ZynQq6GQYWojr7/XhxUOOxDjtasmR8SEsR/5zZtugKjsVSGiojsg0GFqA5OnszF6dN5onYO+5AcRowQH9VgsVRg06Yrji+GyE4YVIjqQKo3BeCwD8ljxIjWku1c/UOuhL8CktswGo0wm8013qfRaKCX2J1NEATJ+Skc9iG5JCQ0RvPm/rh6tbBK+9q1l1BebuUJ3uQSZA0qM2bMwIoVK3DmzBlotVr06NEDM2fORBtbuxkR1ZPRaMS8eYthMNS8dDMkxBcTJowRhZXjx29w2IcURaVSYfjwGHzySdVdkm/eNOPXX6/jnnvEK4OInI2scXvHjh2YOHEi9u3bh82bN6OsrAz33nsviou5DwA1LLPZDIOhGFptXOWusVIPrTYOBkOxZM/L11+fknxtDvuQnKTmqQAc/iHXIeuvgRs2bKjy50WLFiE0NBQpKSm4++67ZaqKXJlO5we9vvqzUEwmcVtFhRXffnta1O7trZZceUHkKL17N0VQkAY3b1YN16tWncdHH90DlUq8gy2RM1HUAGZBwa1NtIKDgyWvWywWFBYWVnkQOcK2bWnIzBT39HXoEAiNhsM+JB9PTzWGDWspar92rQjHjt2QoSKihqWYoGK1WvHKK6+gZ8+eaN++veQ9M2bMQEBAQOUjKkp6wyOihvb11ycl2zt3DnFwJURiw4fbGv457+BKiBqeYoLKxIkTceLECSxdutTmPVOnTkVBQUHlIy0tzYEVkrsqLi7FihXiD3xfXwGtW/vLUBFRVYMGtZDs2eM8FXIFiggqL774ItauXYtt27ahadOmNu/z8fGBv79/lQeRva1adQFGY5moPT5e+gRbIkfz9fXGwIHNRe3Hjt3A5cv5ji+IqAHJGlQEQcCLL76IlStXYuvWrYiOjpazHCJJCxackGy3MUJJJAtbq3/WrLno4EqIGpasQWXixIn45ptv8O2338LPzw9ZWVnIysqCSWrZBZEMLl/Ox9at10TtcXGBCOOqZFKQoUNbQmqBD4d/yNnJGlTmzJmDgoIC9O3bFxEREZWPZcuWyVkWUaVFi6Qn0T7+eGvJHwpEjlBaaoHBYEBubm7lQ602oWvXUNG9O3deh8HAX/7Iecm6rlIQBDm/PFG1KiqsWLhQPOzj6anGww+3xDffHJChKnJ3FosJR44cx9y5Vuh02irXbm2mXDVBW60C1q69iLFjOVZJzkkRk2mJlGjr1mtISysStQ8b1gqNG2slnkFkf2VlpTCZKqDVthHtrNy1awfJ53D4h5wZd6oisuGLL45Ltj/9NH8zJflpNHrRLst6PRAZeRkZGVU3J9y48QpKSsqg03k5skSiBsEeFSIJWVklWLlS/FtoeLgvBg/m6jRSroQE8TwVk6kcmzZdcXwxRA2AQYVIwtdfn0N5uVXU/tRT7eHpyX82pFyJidJnTy1fzl1qyTnxE5foDyoqgMWLz4na1WoVnnuuowwVEdVe8+b+CArSiNrXrLkAi6VchoqI7gyDCtEfnD9/a+jnj4YObYnmzQNkqIio9lQqFTp3Fg//FBaWYssW8Z5ARErHoEL0Bykp0u0vvJDo0DqI6qtzZ+ndCH/8UdxTSKR0DCpEv5OdbcLVq+Kd3GJiAjFwYAvHF0RUDy1bBsDfX7zCZ9WqCygrq5ChIqL6Y1Ah+p29e29Itv/5z4lQq7kVLTkHtVqFDh2CRO03b5qxbRtPnSfnwqBC9D8WSwUOHjSI2jUaT4wbFy9DRUT1l5AgDioAh3/I+TCoEP3PgQOZMJvF3eKjRsUhOJg70ZJziY7WQ6cTH1OycuV5yaX3RErFoEKEW+dO7dhxXfIaJ9GSM1KrVWjTRtyem2vCzp3Sf9eJlIhBhQjA+fM3Jc/1ueuucCQlhctQEdGdi4uTbl++nMM/5DwYVIgAbNp0VbKdvSnkzJo3B4KDfUTtK1acR0UFh3/IOTCokNvLyipGamquqL1xYy1GjpToOydyEmo1MGRIM1F7VlYx9uzJkKEiorpjUCG3t3mzdG/KxImdoNXytFlybsOGNZds5+ofchYMKuTWCgtLsW9fpqhdo/HgsA+5hN69IxAYKB7++eGHsxz+IafAoEJubceONMmlmiNHtkLjxjoZKiJqWN7eHhg+PEbUnplZzNU/5BQYVMhtlZZWYPt26V06n3+eG7yR63jsMenlP99+e9rBlRDVHYMKua19+zJhNJaJ2lu3FhATw1OSyXX0798MjRqJNy388cdzsFjKZaiIqPYYVMgtWa0CfvlFehJtcrKDiyGyMy8vDzz6qHgFW36+BRs2XHF8QUR1wKBCbik19Qays0tE7VFROkRFyVAQkZ09/nhbyfbvvuPwDymbp9wFEDmaIAjYuPGK5LU+fcKhUl10bEFEDtC9eySaN/fH1auFVdrXrLmIzMw8eHnVvAJIo9FAr9fbq0QiSQwq5HbOn8/HxYsFovaQEA06dgxCfr7jayKyN7Vahccei8PMmQeqtJtM5Zg8+Ru0aGGp8TVCQnwxYcIYhhVyKAYVcjsbNlyWbO/fvzk8PFQOrobIcR5/vK0oqADA/v0WtG0bB53Oz+ZzS0qKYDCcgdlsZlAhh2JQIbdy/XoJTp40iNp9fb3Qq1cTlJUVSjyLyDV06NAI8fEhon8Dly4BVqsGen1Qtc83mexZHZE0TqYlt7J1q3gXWuDW8k0fHw8HV0PkWCqVSnJSrSCocPz4TRkqIqoZgwq5jbw8SH4Y+/h4oG9fLvUh9zBqlPTmb4cP5zm4EqLaYVAht7FvHyAI4va7724KX18ePkjuITo6EN26RYjaL182wmDg2A4pD4MKuYXMzGIcPy5u9/RUYcCAZo4viEhGtvZU2b9femiUSE4MKuQW5sw5BatVvKKne/dIBAZqZKiISD6PPtoGarX438OePRkQpLodiWTEoEIuz2Aw4auvzoraVSpg0KAWji+ISGZhYb4YPLiFqP3GDRPOn893eD1E1eHyZHJ6RqMRZrPZ5vX33z+KkhLxwWtJSWFo3Fhnz9KIFOvppztg3TrxnkJ79mQgNrb6ZcpEjsSgQk7NaDRi3rzFMBiKJa+XlgKzZwOAuJt70KBo+xZHpGDDhrVCSIhWNIH28OFsPPZYG2g0/PFAysChH3JqZrMZBkMxtNo4hITcJXqcOxcFk0kcUtq3b4SoKNu7cBK5Om9vDzzxhHhSrcVSgZSUbBkqIpLGoEIuQafzg14fVOXh4xOAnTtvSN4/ZEgLxxZIpEBPP91esn3PngwHV0JkG4MKuaz9+zORny8+aC0mJhAxMRyDJ0pICEWHDsGi9gsX8pGdLT2cSuRoDCrkkqxWARs3XpG8JrXagchdPf54a8l29qqQUjCokEs6ciQHOTklovbwcB+0b99IhoqIlOmhh1rCw0O8d8q+fZmwWrmnCsmPQYVcjiAIWL9evOwSAHr1CoFKJZ5cS+SugoJ80FqiUyU/34JTp8QnjRM5GoMKuZxTpwxISysStWs0ZrRr5y9DRUTKlpAg3c7hH1ICBhVyORs2XJFsj4xMh4cHe1OI/ig6GggIEB/MefRoDgoKxBPSiRyJO/qQS7l4MR/nzt0Utfv5eSA0VHqp8h+VllpgMFTf5W0wGFBaWlavGomURq0GkpJCsGVLVpX2igoBu3al4/77W8pUGRGDCrmYDRuk56Z06xaE4uKaJwZaLCYcOXIcc+daodNpbd5XUlKM1NSzCApKgl5f73KJFCM5uTG2bs3CH88k3LnzOlfKkawYVMhlpKcbcfx4rqhdp/PEXXcFYPv2ml+jrKwUJlMFtNo2CAkJs3mf1ZoOkykV5eXsVSHXEBJya0VcamrVf0P5+RYcO3YDsbHeMlVG7o5BhVyGrd6Uvn2j4ONTt+lYGo0eer3tTeGMxoI6vR6RM+jbN0oUVABg+/Y0xMa2kqEiIgYVchEGgwWHDonPJ/HyUqNfv2YoLubqBXI/dZ1v1a5dCEJDtcjJqXpQ4dmzN5GVZYKXeL4tkd0xqJBL2L49S3Jzqt69m8DPzxvF3A2c3Ez95lupcPfdUfjxx3Oi+/bsyUGfPvasmEgagwo5PaMROHBA3F2tVqswcGBzGSoikl9951v16BGJ1asvoKzMWuW+Q4cM6NbNriUTSWJQIad38CBQXi7uTUlOjkBwsO3fJIncQV3nW/n6eqFr13Ds3l11uNRiseLECbuUSFQtbvhGTq2gwILDh8XtKhUPHySqr759oyTbU1JuHVFB5EgMKuTUvvzyDCwW8W6ziYmhCA/3laEiIufXrJk/WrYMELXn5qqwZ0+WxDOI7IdBhZxWUVEp5s49KXmNvSlEd6ZPH+lelTlzTjm4EnJ3DCrktGbPPoL8/FJRe7t2IWjRQvzbIBHVXpcuYfDzE69H3rgxDWfO8FRlchwGFXJKxcWl+OCDQ5LX7r8/2sHVELkeLy+1zV6VDz9McXA15M4YVMgpff75ceTmmkTtsbFBiImxvcKBiGqvb98oeHmJf0wsXnwSOTncnIgcQ9agsnPnTgwbNgyRkZFQqVRYtWqVnOWQkzCZyvD++wclrw0dylNeiRqKn583unePELVbLBX47LMjMlRE7kjWoFJcXIyEhATMnj1bzjLIycyfn4qsLPFvc61aBSI2lr0pRA2pf3/pTRM//fQIiorEc8SIGpqsG74NGTIEQ4YMqfX9FosFFoul8s+FhYX2KIsUzGIpx8yZ0r0p998fDZVKvFSZiOovPNwXCQmNcezYjSrt+fkWzJ17FFOmdJWpMnIXTjVHZcaMGQgICKh8REVJT/Qi1/XVVydx/XqRqD0qSod27UJkqIjI9Q0a1EKy/YMPDsFsLndsMeR2nCqoTJ06FQUFBZWPtLQ0uUsiBzKby/HOO/skrw0cGMneFCI7adUqEK1a+Ynas7NLsHAh99Un+3KqoOLj4wN/f/8qD3Ifc+YclexNCQsT0K4d900hsqf+/cMl2//97/0oLa1wcDXkTpwqqJD7Kioqxb/+tV/yWq9eYG8KkZ3FxvojIkJ8zs+1a0XsVSG7YlAhpzBr1iHJfVM6d26E2FgZCiJyMyqVCj16SF979919sFg4V4XsQ9agYjQacfToURw9ehQAcPnyZRw9ehTXrl2TsyxSmNzcEvznP9K70L75ZmewM4XIMWJjgfbtg0Xt168X4csvU2WoiNyBrEHl0KFD6NSpEzp16gQAmDRpEjp16oRp06bJWRYpzMyZByT3a+jXrxnuvjtShoqI3JNKBbz+eqLktX/9az9MpjLHFkRuQdag0rdvXwiCIHosWrRIzrJIQdLTi/DZZ0clr/3rX70dWwwRYdCgKHTpEiZqz8gw4tNPuVstNTzOUSFF+8c/9kru0zB8eAySk8VbexORfalUKvzjHz0lr82YsR95eeK5ZER3gkGFFOvs2TzMny8e91apgHfflf6gJCL7GzIkGt27i4dd8/Mt+Pe/D8hQEbkyBhVSrNde246KCvFyyCefbIf27Rs7viAiAnCrV2XmzLslr33yyWFcu8bjTajhMKiQIm3ceBk//3xJ1O7pqcbbb9tYI0lEDtO7d1MMG9ZK1G6xVOCNN3bKUBG5KgYVUpyysgq8+uo2yWsTJyaiZctAxxZERJJmzOgNtVq8P8B3353Brl3XZaiIXBGDCinO7NlHcfp0nqg9JESL6dPZm0KkFPHxjfDUU+0lr73yyjZYreKhW6K6YlAhRbl+vQh/+9suyWvvvNMTQUEaB1dERNV5991e8PPzFrWnpGRza31qEAwqpCivvLIVRqN406j27Rvh2Wc7ylAREVUnPNwXf/tbN8lrr7++EwYDlyvTnWFQIcX4+eeLWL78vOS1zz7rD09P/nUlUqK//KUzYmICRe0Ggwmvv86JtXRn+MlPipCfb8Zzz22WvDZuXDz69IlycEVEVFs+Pp6YNeseyWvz56dyYi3dEQYVUoRXX92G9HSjqD04WIP33usjQ0VEVBdDh7bCiBExktcmTNjE05Wp3hhUSHZr117EokUnJa+9914fNG6sc3BFRFQfH3/cD76+XqL206fz8I9/7JWhInIFDCokq+zsYjzzzEbJawMGNMfTT0svfSQi5WnWzB9//7v0FgIzZx7AoUNZDq6IXAGDCsnGahUwevQ6ZGeXiK75+Xlj/vxBUKnEm0kRkXK9/HIXdO4sPl25okLAuHHrJQ8ZJaoOgwrJ5r33DmDz5quS12bNugfNmvk7uCIiqk5pqQUGgwG5ubk2H2ZzCRYuHAwvL/GPl5MnDfjrX3+VoXJyZp5yF0DuacuWq3jrLemN3YYObckhHyKFsVhMOHLkOObOtUKn09q8LyTEFxMmjMFbb3XD9Ol7RNdnzUrBkCHRGDiwhR2rJVfCoEIOd+lSPh599CfJk5GbNNFj4cLBHPIhUpiyslKYTBXQatsgJEQ8tAMAJSVFMBjOwGw2Y+rUZKxceQFHj+aI7hs7dj2OHRvLifJUKxz6IYcqKirF8OGrkJdnFl1Tq1X47ruhaNSIH15ESqXR6KHXB0k+dDq/yvu8vDzwzTf3QaMR/z6cmVmM0aPX8SwgqhUGFXKY0tIKPPTQapw4kSt5/Z13eqJ376YOroqI7CU+vhHef/9uyWsbN17BjBn7HVwROSMO/VCDMRqNMJvFPSXArRU+Eyf+anPy7COPxGLq1GR7lkdEMpg4sRPWr7+Mdesui65Nm7YbbdvqcPfdkTafr9FooNfr7VkiKRyDCjUIo9GIefMWw2AoFl0TBGDTJiAlRXreSceOjTkvhchFqVQqLFw4GJ06fY2MjKq7T1utAp54YiPGjQOCg6Wff3tyLsOK+2JQoQZhNpthMBRDq42rMk4tCAJWr05DSop4Qh1w6+TV1atHwNdXfEw8EbmG0FBfLFs2FH37LhNNojebVVi+3Ad/+Utb6HRVfyT9fnIug4r74hwValA6nd/vJtYFYt26HPz6q3RI8fPzxvr1D6FFiwAHV0lEjtarV1PMmNFb8tqNGxZ8++01aLUBNifnkvtijwrZRUWFFV99dQr792dKXvfyUmPVqhFITAy1+RrVzXm5zWAwoLS07I5qJaKGc3tTOCnjxkVj9+5rWL36iuja6dN5+P77cxg1Ks7OFZKzYVChBmcyleHLL1Nx4oT0h5VaLWD+/L7o16+Zzdeobs7L75WUFCM19SyCgpLAnmEiedVmU7jYWCAszIrsbA/Rte3b0xAe7ot77omyd6nkRBhUqEHduGHGokWnkZUlHTDUahUeeEDAkCG2Qwpge87LH1mt6TCZUlFezl4VIrnVZlM4AHj44Wv44ovrKC0Vz01btuwM/Py8kJQUbs9SyYkwqFCDuXwZWLXqNEymCsnrnp4qPPlkS0RGXqj1a96e82KL0VhQ5zqJyL5ubwpnS2hoAeLifsHp0wkoK6s6uVYQgPnzT8DHxwPR0fwRRZxMSw1AEAR8/vkpLF0KmyHFx8cDL73UGR062P7wIiL3odcX44EHpPdPsVoFzJ17HBcuFDq4KlIixlWqUXWTWgsKLJg0aS/WrLkCQHofFH9/b0ycmIgWLQJgNN60X6FE5FTi4/0xfLgWq1eLe1nLy61YsOACHntMhsJIURhUqFrVTWpNSwNWrwYKC21v1NasmR9eeCERQUEae5ZJRE5qyJAWKCkpk9y12mKxYtkyYPRoA/r3byRDdaQEDCpULalJrVargF9+ycSmTRkQqjlT7K67wjBmTDy8vcWz+4mIgFs71z70UGuYzeX49dd00XWzWYURIzZg7Vod+vThaiB3xDkqVCu3J7UWF3tj7tyL2LjRdkhRqYAHHojB+PEdGFKIqEYqlQqPP94WXbtKr/QxGsswePBy/PTTRQdXRkrAoEK1cqsX5SreeWcfLl7Mt3mfTueBiRMTMXhwNM/uIaJaU6tVGDcuHgkJjSWvm83leOCBVfjmm1MOrozkxqEfqpHBAHz77VlcuWKs9j5//wI8+2wXxMZKf9DcVt3Olb99Te44S+RuPDzUePbZDpg795jkhpEVFQJGj14Hg8GEl1/uIkOFJAcGFbKptLQCH310HPPnA+XltkOKWq3CPfcEo6RkL/z9u1X7mrXZuRLgjrNE7srLywN//nMiFi48gUOHsiXveeWVbTh7Ng8ff9wPXl4cXnZ1DCokadeu63juuc04dcoAW8uOAaBRIy3Gj28PnS4fGzfW/Lq13bmSO84SuS9PTzXGj+8ALy8r9u69IXnPnDnHcOZMHpYuHYrQUF8HV0iOxKBCVeTlmfB//7cT8+en1njvPfdE4YEHWsPHxwNZWfl1+jo17VzJHWeJ3JtarcJDDzWDSpWDPXukf1nati0NnTt/je+/H4YePZo4uEJyFE6mJQC3dpddvPgk2rRZUGNIadRIi9de64LHHouDjw+7XYnIPlQqFfr2Bd555y6b96SnG9GnzzL861/7UFFhdVxx5DDsUXFB1e0k+3sajQZ6vR4nT+bipZe2YNu2tGrvV6mAvn1/60UhInKE55+PR3x8JJ588meUlJSLrpeXW/Hmm7uwbt1lLFo0GDExPKrDlTCouJjqdpL9I51Oh/T0Vpg37yQqKqrZuQ1ARIQWY8d2QHR0QEOVSkRUaw880Bq7dz+O4cNX4tq1Isl7du9OR4cOX+Htt7tj0qQkTrR1EQwqLkZqJ9k/sloF7Np1HZs2ZcFkOlHt6+l0nujWrQyDB7dFQABDChHJJzExFCkpo/Hkk+uwceMVyXvM5nK88cav+PrrU/joo34YMKC5Y4ukBsc5Ki7q9k6yf3zk5Kjw2WfnsXp1Nkym6jdkGzasFXbtGoFu3W7tb0BEJLdGjXT4+ecH8fe/94CHh+3PsJMnDRg48AcMHboCR45IL3Mm58CfPm4iL8+EhQtPYObMg7h6tfqj05s00WPFiuFYvXoEoqK4iQkRKYuHhxrTpvXAr7+OQqtWgdXe+/PPl9C589d48MHV+PXX6xCqO6CMFIlDPy7OZCrDhg1X8Msv11BeXv2MeC8vNSZNSsKbb3aDn5+3gyokIrKtup2sW7f2xi+/3I93303BggVnqj0kdeXK81i58jwSEhrh1VeT/rdq8c5/BNZ18QLVHYOKi6qosGLr1mv4+edLMBpr3jTtvvui8dFH/dC6NWfLE5Ey1HYn66AgC3r0uIqzZ1sjN7f6gYJjx3IxbtwG/N//7cSoUXEYOTIO3bpF1OtssrosXggJ8cWECWMYVuqBQcXFCIKAs2eBHTtOIjfXUuP90dF++PTTAbj//lYOqI6IqPZqu5P1jRvpEIQjGD++Gc6dU2PjxnSUlFRU+9o5OSX4+OPD+Pjjw2je3B8jR7bBgw/GIikprNZz8mqzeAEASkqKYDCcgdlsZlCpBwYVFyEIAjZtuoK//nUHDh9WAag+pHh7q9GjRwW++WYEmjSx/QFARCS32u5krdP5YfDgpujduyU2b76KrVuvwWKpPrAAwNWrhXjvvYN4772DCA7WYODA5hg0qAXuvbcFmjSxHUBuu714oTomU40vQzYwqDg5QRCwdes1TJu2G3v2ZNR4v0oF9OgRif79G6G8/Bg3biMil+Pr64URI2LQr18zbN16DTt3Xkdxce3ODcvLM2PZsrNYtuwsAKBlywD06tUEPXs2Qa9eTRAXFwK1uu7DRFR/DCpOymoVsG7dJbz33kH8+uv1Wj0nPj4EDz3UGk2a+MFovInMTNuT1G4zGAwoLeXBgETkfPz9vTFiRAzuuy8aBw5k4ZdfLiMzs25dG5cuFeDSpQIsXnwKABAcrEGPHpHo2bMJ4uJ0sNQ8wk53iEHFyZjN5Viy5DQ++OAgTp/Oq9VzmjbV46GHYtGuXUhlW20nqZWUFCM19SyCgpLAoVUickbe3h7o1asJEhK0OHz4EMrLY7BhQxoKC0vr/Fp5eWasXXsJa9deAnCrlzo8/CRatQpGdHQAoqMDEBHhy16XBsSg4iQuXLiJBQtOYMGCVGRnl9TqOYGBPhgxIgbJyRGifzS1naRmtabDZEpFeTl7VYjIualUKrRoAbz6am/o9YHYsOEyli07izVrLkieIVQbgqBCZqYJmZnp2LUrHQCg0XigefMAREf7Izo6AKGhDfhNuCEGFQUrKSnDihXnMX9+KrZvr/7AwN/z9RUwcGAzDBjQusazLmo7SY2IyJVoNJ4YMaI1RoxoDZOpDDt3XsfGjVewceMVnDpV/ZB4TczmCpw9m4ezZ3/r9Q4IAE6e3I67726Bbt0i0KlTKLRarzv9NtwCg4rC5OaWYO3aS1i9+gI2bbpSp5TfuLEWL74YD6PxIMLDw3ggFxFRLWi1Xhg0KBqDBkUDANLSCrFlyzXs2nWrl+T3gaO+CgpUWL36ClavvgIA8PRUIyGhMbp1i0By8q1H69ZB9drPxdUxqMjs5k0z9u7NwO7d6di58zr27MmA1Vq3LZ6jovzw6qtd8OyzHWE2F2LWrIN2qpaIyLlVt9PtbVotMHhwIwwdGg6gC3JzzTh4MAf792dj//4cHDtmQFlZ9Tt916S83IqUlGykpGRj9uyjAICgIA2Sk8PRqVMY2rdvhA4dGqFNm2B4e7v3L50MKg5SWlqBixfzcfq0AadP5+H0aQOOHs3ByZP172JMTAzFlCl34ZFHYit7T2qxkzMRkVuq7SKC0lILzp49jTZt4uHt/dvwTEAAcO+9QL9+QHY2cOVKKc6cKUZpaThu3qz7xNw/unnTjA0brmDDhiuVbV5earRuHYTWrYMQExP4v0cQoqL8EBmpd4vjThQRVGbPno33338fWVlZSEhIwKeffoquXbs6vA6rVYDRWIqyMivKy289qvv/ZWVWFBeXoaioFIWFpf/7XwuKikqRn29BZmYxMjKMyMgw4saNhtntx8tLjeHDY/Dccwno378ZuwmJiGqpLjvdGgxH4OXVyuZ9YWFAREQ6yspWYNCgntDpQnH5cgEuXy7AlSsFuHy5EGZz/SboVq3ZilOnDDbnzfj5eSMyUo+wMB2CgjQIDPT53UODgABv6HRe8PHxgLe3h83/9fRUQa1WQaW69b+3Hvjd/1dBp/OSpXdH9qCybNkyTJo0CXPnzkVycjI++ugjDBo0CGfPnkWog6dKX79ehObN5zn0a9ZWfHwIxo/vgCefbIfGjXVyl0NE5LRqu4igLosN/P29kZDQGAkJjQHc+sU3K6sYly8X4Pz5G7h4MQe5ueo6D+3XpKioVDRx114+/3wgJkxIsPvX+SPZg8qHH36IZ599Fk899RQAYO7cufj555+xYMECvPHGGw6txdOzduc7OEp8fMj/ZqXHoEuXMPaeEBE5CbVahchIPSIj9UhI0MFgyMGECY/j6tVy7NuXif37bz3S041yl1prcu0NI2tQKS0tRUpKCqZOnVrZplarMWDAAOzdu1d0v8VigeV32wAWFNxKs4WFhQ1Sj8lUDEC+SR56vTfuuisMAwY0x333tUTLloGV14qKimr1GkVFRbBYzMjLy4bZbPtEz/z8HJSXl6GgIAee1fwt4H3Od5+Sa+N9rn2fkmuT876SEiMsFjOsVjMSE0OQmBiA55+PAwCkpxfh0KFsHDqUhUOHspCamouiojuf72IPZnNxg/28vf06glCLHiZBRunp6QIAYc+ePVXap0yZInTt2lV0//Tp0wUAfPDBBx988MGHCzzS0tJqzAqyD/3UxdSpUzFp0qTKP1utVuTl5SEkJMTphkUKCwsRFRWFtLQ0+Pv7y12OIvE9qhnfo5rxPaodvk8143tUs9q+R4IgoKioCJGRkTW+pqxBpVGjRvDw8EB2dnaV9uzsbISHh4vu9/HxgY+PT5W2wMBAe5Zod/7+/vwLXwO+RzXje1Qzvke1w/epZnyPalab9yggIKBWryXr7FFvb2906dIFW7ZsqWyzWq3YsmULunfvLmNlREREpASyD/1MmjQJY8eORVJSErp27YqPPvoIxcXFlauAiIiIyH3JHlRGjhyJGzduYNq0acjKykJiYiI2bNiAsDDbm/G4Ah8fH0yfPl00lEW/4XtUM75HNeN7VDt8n2rG96hm9niPVIJQm7VBRERERI6nrB3OiIiIiH6HQYWIiIgUi0GFiIiIFItBhYiIiBSLQcUOdu7ciWHDhiEyMhIqlQqrVq2q9v5du3ahZ8+eCAkJgVarRVxcHGbNmuWYYmVU1/fp93bv3g1PT08kJibarT4lqOt7tH37dqhUKtEjKyvLMQXLoD5/jywWC9588000b94cPj4+aNGiBRYsWGD/YmVS1/do3Lhxkn+P4uPjHVOwDOrz92jJkiVISEiATqdDREQEnn76aRgMBvsXK5P6vEezZ89G27ZtodVq0aZNGyxevLjOX5dBxQ6Ki4uRkJCA2bNn1+p+X19fvPjii9i5cydOnz6Nt956C2+99RbmzZtn50rlVdf36bb8/HyMGTMG/fv3t1NlylHf9+js2bPIzMysfISGhtqpQvnV5z169NFHsWXLFsyfPx9nz57Fd999hzZt2tixSnnV9T36+OOPq/z9SUtLQ3BwMB555BE7Vyqfur5Hu3fvxpgxYzB+/HicPHkSP/zwAw4cOIBnn33WzpXKp67v0Zw5czB16lS8/fbbOHnyJP7+979j4sSJ+Omnn+r2hRvmeEGyBYCwcuXKOj/vgQceEJ588smGL0ih6vI+jRw5UnjrrbeE6dOnCwkJCXatS0lq8x5t27ZNACDcvHnTITUpTW3eo/Xr1wsBAQGCwWBwTFEKU5/PpJUrVwoqlUq4cuWKfYpSmNq8R++//77QsmXLKm2ffPKJ0KRJEztWphy1eY+6d+8uTJ48uUrbpEmThJ49e9bpa7FHRYGOHDmCPXv2oE+fPnKXojgLFy7EpUuXMH36dLlLUbTExERERERg4MCB2L17t9zlKMqaNWuQlJSE9957D02aNEFsbCwmT54Mk8kkd2mKNX/+fAwYMADNmzeXuxTF6N69O9LS0rBu3ToIgoDs7Gz8+OOPuO++++QuTTEsFgs0Gk2VNq1WiwMHDqCsrKzWr8OgoiBNmzaFj48PkpKSMHHiRDzzzDNyl6Qo58+fxxtvvIFvvvkGnp6yb6qsSBEREZg7dy6WL1+O5cuXIyoqCn379sXhw4flLk0xLl26hF27duHEiRNYuXIlPvroI/z444944YUX5C5NkTIyMrB+/Xp+Hv1Bz549sWTJEowcORLe3t4IDw9HQEBAnYdpXdmgQYPw5ZdfIiUlBYIg4NChQ/jyyy9RVlaG3NzcWr8OP+0V5Ndff4XRaMS+ffvwxhtvICYmBqNGjZK7LEWoqKjA448/jr///e+IjY2VuxzFatOmTZW5Fj169MDFixcxa9YsfP311zJWphxWqxUqlQpLliypPL31ww8/xMMPP4z//ve/0Gq1MleoLF999RUCAwMxYsQIuUtRlFOnTuHll1/GtGnTMGjQIGRmZmLKlCl4/vnnMX/+fLnLU4S//e1vyMrKQrdu3SAIAsLCwjB27Fi89957UKtr30/CoKIg0dHRAIAOHTogOzsbb7/9NoPK/xQVFeHQoUM4cuQIXnzxRQC3fuAIggBPT09s2rQJ/fr1k7lKZeratSt27doldxmKERERgSZNmlQ5Yr5t27YQBAHXr19H69atZaxOWQRBwIIFCzB69Gh4e3vLXY6izJgxAz179sSUKVMAAB07doSvry969+6Nd999FxERETJXKD+tVosFCxbg888/R3Z2NiIiIjBv3jz4+fmhcePGtX4dBhWFslqtsFgscpehGP7+/khNTa3S9t///hdbt27Fjz/+WBnySOzo0aP80Pydnj174ocffoDRaIRerwcAnDt3Dmq1Gk2bNpW5OmXZsWMHLly4gPHjx8tdiuKUlJSIhqA9PDwA3Ap49BsvL6/Kf1tLly7F0KFD2aMiN6PRiAsXLlT++fLlyzh69CiCg4PRrFkzTJ06Fenp6ZXryWfPno1mzZohLi4OwK216v/5z3/wl7/8RZb6HaUu75NarUb79u2rPD80NBQajUbU7krq+nfpo48+QnR0NOLj42E2m/Hll19i69at2LRpk1zfgt3V9T16/PHH8c477+Cpp57C3//+d+Tm5mLKlCl4+umnXXbYp67v0W3z589HcnKyS/8bu62u79GwYcPw7LPPYs6cOZVDP6+88gq6du2KyMhIub4Nu6rre3Tu3DkcOHAAycnJuHnzJj788EOcOHECX331Vd2+cJ3WCFGt3F4i+sfH2LFjBUEQhLFjxwp9+vSpvP+TTz4R4uPjBZ1OJ/j7+wudOnUS/vvf/woVFRXyfAMOUtf36Y/cYXlyXd+jmTNnCq1atRI0Go0QHBws9O3bV9i6das8xTtIff4enT59WhgwYICg1WqFpk2bCpMmTRJKSkocX7yD1Oc9ys/PF7RarTBv3jzHFyyD+rxHn3zyidCuXTtBq9UKERERwhNPPCFcv37d8cU7SF3fo1OnTgmJiYmCVqsV/P39heHDhwtnzpyp89dVCQL7qIiIiEiZuDyZiIiIFItBhYiIiBSLQYWIiIgUi0GFiIiIFItBhYiIiBSLQYWIiIgUi0GFiIiIFItBhYiIiBSLQYWInE7fvn3xyiuv1Pr+RYsWITAw0G71EJH9MKgQERGRYjGoEBERkWIxqBBRg+nbty9eeuklvPLKKwgKCkJYWBi++OILFBcX46mnnoKfnx9iYmKwfv36yufs2LEDXbt2hY+PDyIiIvDGG2+gvLy88npxcTHGjBkDvV6PiIgIfPDBB6Kva7FYMHnyZDRp0gS+vr5ITk7G9u3bHfEtE5GdMagQUYP66quv0KhRIxw4cAAvvfQS/vznP+ORRx5Bjx49cPjwYdx7770YPXo0SkpKkJ6ejvvuuw933XUXjh07hjlz5mD+/Pl49913K19vypQp2LFjB1avXo1NmzZh+/btOHz4cJWv+eKLL2Lv3r1YunQpjh8/jkceeQSDBw/G+fPnHf3tE1FDa5Czn4mIBEHo06eP0KtXr8o/l5eXC76+vsLo0aMr2zIzMwUAwt69e4W//vWvQps2bQSr1Vp5ffbs2YJerxcqKiqEoqIiwdvbW/j+++8rrxsMBkGr1Qovv/yyIAiCcPXqVcHDw0NIT0+vUkv//v2FqVOnCoIgCAsXLhQCAgLs8B0Tkb15yh2UiMi1dOzYsfL/e3h4ICQkBB06dKhsCwsLAwDk5OTg9OnT6N69O1QqVeX1nj17wmg04vr167h58yZKS0uRnJxceT04OBht2rSp/HNqaioqKioQGxtbpQ6LxYKQkJAG//6IyLEYVIioQXl5eVX5s0qlqtJ2O5RYrdYG+XpGoxEeHh5ISUmBh4dHlWt6vb5BvgYRyYdBhYhk07ZtWyxfvhyCIFQGmN27d8PPzw9NmzZFcHAwvLy8sH//fjRr1gwAcPPmTZw7dw59+vQBAHTq1AkVFRXIyclB7969ZfteiMg+OJmWiGTzwgsvIC0tDS+99BLOnDmD1atXY/r06Zg0aRLUajX0ej3Gjx+PKVOmYOvWrThx4gTGjRsHtfq3j67Y2Fg88cQTGDNmDFasWIHLly/jwIEDmDFjBn7++WcZvzsiagjsUSEi2TRp0gTr1q3DlClTkJCQgODgYIwfPx5vvfVW5T3vv/8+jEYjhg0bBj8/P7z22msoKCio8joLFy7Eu+++i9deew3p6elo1KgRunXrhqFDhzr6WyKiBqYSBEGQuwgiIiIiKRz6ISIiIsViUCEiIiLFYlAhIiIixWJQISIiIsViUCEiIiLFYlAhIiIixWJQISIiIsViUCEiIiLFYlAhIiIixWJQISIiIsViUCEiIiLF+n9BC2E0vnSOKAAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "df_samples = pd.DataFrame({'lambda':[x[0] for x in samples.tolist()], 'mu':[x[1] for x in samples.tolist()], 'model':[x[2] for x in samples.tolist()]})\n",
+ "#sns.kdeplot(data=df_samples, x='lambda', y='mu', fill=True)\n",
+ "#sns.kdeplot(data=df_samples, x='lambda', y='model', fill=True)\n",
+ "sns.distplot(df_samples['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "95f117bb-89d9-4e42-8cba-3d2e3efa290e",
+ "metadata": {},
+ "source": [
+ "## Looking at loss during training for different models"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "2bbdd292-2e94-4bdc-92c0-690d25ffb5eb",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "'NLE_A' object has no attribute 'keys'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
+ "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)",
+ "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[7]\u001b[39m\u001b[32m, line 10\u001b[39m\n\u001b[32m 8\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mopen\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33mpretrained_models/\u001b[39m\u001b[33m\"\u001b[39m+filename, \u001b[33m\"\u001b[39m\u001b[33mrb\u001b[39m\u001b[33m\"\u001b[39m) \u001b[38;5;28;01mas\u001b[39;00m f:\n\u001b[32m 9\u001b[39m inference = pickle.load(f)\n\u001b[32m---> \u001b[39m\u001b[32m10\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[43minference\u001b[49m\u001b[43m.\u001b[49m\u001b[43mkeys\u001b[49m())\n\u001b[32m 11\u001b[39m \u001b[38;5;66;03m#plot_summary(inference)\u001b[39;00m\n",
+ "\u001b[31mAttributeError\u001b[39m: 'NLE_A' object has no attribute 'keys'"
+ ]
+ }
+ ],
+ "source": [
+ "from sbi.analysis import plot_summary\n",
+ "import pickle\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "# Load the pickled neural networks\n",
+ "likelihood_estimators = []\n",
+ "for filename in [\"inference_unif.pickle\", \"inference_unif_server.pickle\", \"inference_unif_run3.pickle\"]:\n",
+ " with open(\"pretrained_models/\"+filename, \"rb\") as f:\n",
+ " inference = pickle.load(f)\n",
+ " print(inference.keys())\n",
+ " #plot_summary(inference)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "c9244a61-9f73-4540-a9f5-ed589ca89492",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from tensorboard.backend.event_processing.event_accumulator import EventAccumulator\n",
+ "import matplotlib.pyplot as plt\n",
+ "import os\n",
+ "\n",
+ "# Directory containing the logs\n",
+ "log_dir = \"sbi-logs/NLE_A\"\n",
+ "\n",
+ "# Iterate over each log directory\n",
+ "for i, log_subdir in enumerate(os.listdir(log_dir)):\n",
+ " log_path = os.path.join(log_dir, log_subdir)\n",
+ "\n",
+ " # Load the event accumulator\n",
+ " event_acc = EventAccumulator(log_path)\n",
+ " event_acc.Reload()\n",
+ "\n",
+ " # Extract the tags (e.g., 'training_loss', 'validation_loss')\n",
+ " tags = event_acc.Tags()['scalars']\n",
+ "\n",
+ " # Plot each tag\n",
+ " for tag in tags:\n",
+ " events = event_acc.Scalars(tag)\n",
+ "\n",
+ " # Extract the steps and values\n",
+ " steps = [e.step for e in events]\n",
+ " values = [e.value for e in events]\n",
+ "\n",
+ " # Plot\n",
+ " plt.figure()\n",
+ " plt.plot(steps, values, label=tag)\n",
+ " plt.xlabel('Step')\n",
+ " plt.ylabel(tag)\n",
+ " plt.title(f'{tag} for Model {i+1}')\n",
+ " plt.legend()\n",
+ " plt.savefig(f'{tag}_model_{i+1}.pdf', dpi=300, bbox_inches='tight')\n",
+ " plt.close()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "e0fe7b64-c1f2-4419-b8ae-7ca9217062c7",
+ "metadata": {},
+ "source": [
+ "## b) Model checks\n",
+ "Here, we simulate traditions for each model, and look at the model ability to distinguish them."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "31dc3731-9547-4920-8b86-4a20834f31c5",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True m: 0\n",
+ "p(m | x, λ, μ): tensor([0.2270, 0.3167, 0.4563])\n",
+ "True m: 1\n",
+ "p(m | x, λ, μ): tensor([0.2663, 0.3548, 0.3789])\n",
+ "True m: 2\n",
+ "p(m | x, λ, μ): tensor([0.2270, 0.3167, 0.4563])\n"
+ ]
+ }
+ ],
+ "source": [
+ "def p_m_given_x_lambda_mu(x_obs, lam, mu):\n",
+ " x_obs = torch.as_tensor(x_obs, dtype=torch.float32)\n",
+ "\n",
+ " # Ensure (num_trials, x_dim)\n",
+ " if x_obs.ndim == 1:\n",
+ " x_obs = x_obs.unsqueeze(0)\n",
+ "\n",
+ " # Expand to (num_trials, batch=3, x_dim)\n",
+ " x_obs = x_obs.unsqueeze(1).repeat(1, 3, 1)\n",
+ "\n",
+ " theta = torch.tensor(\n",
+ " [\n",
+ " [lam, mu, 0.0],\n",
+ " [lam, mu, 1.0],\n",
+ " [lam, mu, 2.0],\n",
+ " ],\n",
+ " dtype=torch.float32,\n",
+ " )\n",
+ "\n",
+ " with torch.no_grad():\n",
+ " log_lik = likelihood_estimator.log_prob(x_obs, theta)\n",
+ "\n",
+ " return torch.softmax(log_lik, dim=1).squeeze(0)\n",
+ " \n",
+ "lam_star = 0.006\n",
+ "mu_star = 0.0025\n",
+ "\n",
+ "for true_m in [0, 1, 2]:\n",
+ " theta_test = torch.tensor([lam_star, mu_star, float(true_m)])\n",
+ "\n",
+ " x_test = None\n",
+ " while x_test is None:\n",
+ " x_test = compute_summary_stats(simulator(theta_test))\n",
+ "\n",
+ " probs = p_m_given_x_lambda_mu(x_test, lam_star, mu_star)\n",
+ "\n",
+ " print(\"True m:\", true_m)\n",
+ " print(\"p(m | x, λ, μ):\", probs)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "f48c53d1-095b-4062-9410-225aa0f77583",
+ "metadata": {},
+ "source": [
+ "### Model evidence"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "id": "d428ca51-8610-45d4-a990-447f943ca703",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AssertionError",
+ "evalue": "Batch shape of condition 10000 and input 9 do not match.",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
+ "\u001b[31mAssertionError\u001b[39m Traceback (most recent call last)",
+ "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[37]\u001b[39m\u001b[32m, line 42\u001b[39m\n\u001b[32m 39\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m log_evidence\n\u001b[32m 41\u001b[39m \u001b[38;5;66;03m# For each model, compute the evidence\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m42\u001b[39m log_evidence_model_0 = \u001b[43mcompute_model_evidence\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlikelihood_estimator\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprior_params\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mx_obs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmodel_index\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[32m 43\u001b[39m log_evidence_model_1 = compute_model_evidence(likelihood_estimator, prior_params, x_obs, model_index=\u001b[32m1\u001b[39m)\n\u001b[32m 44\u001b[39m log_evidence_model_2 = compute_model_evidence(likelihood_estimator, prior_params, x_obs, model_index=\u001b[32m2\u001b[39m)\n",
+ "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[37]\u001b[39m\u001b[32m, line 28\u001b[39m, in \u001b[36mcompute_model_evidence\u001b[39m\u001b[34m(likelihood_estimator, prior_params, x_obs, model_index, n_samples)\u001b[39m\n\u001b[32m 22\u001b[39m theta_samples_with_model = torch.cat([\n\u001b[32m 23\u001b[39m theta_samples,\n\u001b[32m 24\u001b[39m torch.full((n_samples, \u001b[32m1\u001b[39m), model_index, dtype=torch.float32)\n\u001b[32m 25\u001b[39m ], dim=\u001b[32m1\u001b[39m)\n\u001b[32m 27\u001b[39m \u001b[38;5;66;03m# Evaluate the log likelihood for each sample\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m28\u001b[39m log_likelihoods = \u001b[43mlikelihood_estimator\u001b[49m\u001b[43m.\u001b[49m\u001b[43mlog_prob\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx_obs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtheta_samples_with_model\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 30\u001b[39m \u001b[38;5;66;03m# Evaluate the log prior for each sample\u001b[39;00m\n\u001b[32m 31\u001b[39m log_priors = prior_params.log_prob(theta_samples)\n",
+ "\u001b[36mFile \u001b[39m\u001b[32m~/Data/F/Articles_et_CR/2022_Article_Silva_portentosa/ExtinctionOfTexts/env/lib/python3.12/site-packages/sbi/neural_nets/estimators/nflows_flow.py:97\u001b[39m, in \u001b[36mNFlowsFlow.log_prob\u001b[39m\u001b[34m(self, input, condition)\u001b[39m\n\u001b[32m 94\u001b[39m condition_batch_dim = condition.shape[\u001b[32m0\u001b[39m]\n\u001b[32m 95\u001b[39m condition_event_dims = \u001b[38;5;28mlen\u001b[39m(condition.shape[\u001b[32m1\u001b[39m:])\n\u001b[32m---> \u001b[39m\u001b[32m97\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m condition_batch_dim == input_batch_dim, (\n\u001b[32m 98\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mBatch shape of condition \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcondition_batch_dim\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m and input \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 99\u001b[39m \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00minput_batch_dim\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m do not match.\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 100\u001b[39m )\n\u001b[32m 102\u001b[39m \u001b[38;5;66;03m# Nflows needs to have a single batch dimension for condition and input.\u001b[39;00m\n\u001b[32m 103\u001b[39m \u001b[38;5;28minput\u001b[39m = \u001b[38;5;28minput\u001b[39m.reshape((input_batch_dim * input_sample_dim, -\u001b[32m1\u001b[39m))\n",
+ "\u001b[31mAssertionError\u001b[39m: Batch shape of condition 10000 and input 9 do not match."
+ ]
+ }
+ ],
+ "source": [
+ "def compute_model_evidence(likelihood_estimator, prior_params, x_obs, model_index, n_samples=10000):\n",
+ " \"\"\"\n",
+ " Approximate the model evidence for a given model and observed data.\n",
+ "\n",
+ " Args:\n",
+ " likelihood_estimator: Trained density estimator (e.g., NLE)\n",
+ " prior_params: Prior distribution for the parameters (lambda, mu)\n",
+ " x_obs: Observed data (summary statistics)\n",
+ " model_index: Integer (0, 1, or 2) for the model of interest\n",
+ " n_samples: Number of samples for Monte Carlo integration\n",
+ "\n",
+ " Returns:\n",
+ " Approximate log model evidence\n",
+ " \"\"\"\n",
+ "\n",
+ " x_obs = torch.tensor(x_obs, dtype=torch.float32) if not isinstance(x_obs, torch.Tensor) else x_obs\n",
+ " \n",
+ " # Sample parameters (lambda, mu) from the prior\n",
+ " theta_samples = prior_params.sample((n_samples,))\n",
+ "\n",
+ " # Append the model index to each sample\n",
+ " theta_samples_with_model = torch.cat([\n",
+ " theta_samples,\n",
+ " torch.full((n_samples, 1), model_index, dtype=torch.float32)\n",
+ " ], dim=1)\n",
+ "\n",
+ " # Evaluate the log likelihood for each sample\n",
+ " log_likelihoods = likelihood_estimator.log_prob(x_obs, theta_samples_with_model)\n",
+ "\n",
+ " # Evaluate the log prior for each sample\n",
+ " log_priors = prior_params.log_prob(theta_samples)\n",
+ "\n",
+ " # Compute the log joint probability\n",
+ " log_joint = log_likelihoods + log_priors\n",
+ "\n",
+ " # Approximate the log evidence using logsumexp for numerical stability\n",
+ " log_evidence = torch.logsumexp(log_joint, dim=0) - torch.log(torch.tensor(n_samples))\n",
+ "\n",
+ " return log_evidence\n",
+ "\n",
+ "# For each model, compute the evidence\n",
+ "log_evidence_model_0 = compute_model_evidence(likelihood_estimator, prior_params, x_obs, model_index=0)\n",
+ "log_evidence_model_1 = compute_model_evidence(likelihood_estimator, prior_params, x_obs, model_index=1)\n",
+ "log_evidence_model_2 = compute_model_evidence(likelihood_estimator, prior_params, x_obs, model_index=2)\n",
+ "\n",
+ "# Compare the model evidences (higher is better)\n",
+ "print(\"Model 0 evidence:\", log_evidence_model_0)\n",
+ "print(\"Model 1 evidence:\", log_evidence_model_1)\n",
+ "print(\"Model 2 evidence:\", log_evidence_model_2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "id": "1ac1289f-42a3-435c-b262-009b65716db5",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "360"
+ ]
+ },
+ "execution_count": 46,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(x_base)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8c590d97-17f6-478b-8171-8adb39a83ede",
+ "metadata": {},
+ "source": [
+ "### Base"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "id": "64d6cb9a-1aaa-4366-bc88-6a30cbc2708c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "d13c2f5066ab4256b37e2ca3ad16c9f4",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/1000 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "theta0_base = prior.sample((1000,))\n",
+ "\n",
+ "theta_base = []\n",
+ "x_base = []\n",
+ "\n",
+ "for t in tqdm(theta0_base):\n",
+ " vec = compute_summary_stats(simulator_base(t))\n",
+ " if vec != None:\n",
+ " theta_base.append(list(t))\n",
+ " x_base.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "27007793-8999-4caf-bca7-f348ea3c8f5e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "samples_base = posterior.sample((N_samples_posterior,), x=x_base)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "086f683d-fbf9-445f-8e9a-cefbd3faa6a6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZcAAAHPCAYAAACfu5eXAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAMgVJREFUeJzt3XtwXPV9///X51z2otXVF9lGEKNCCHyLwcSxVS6tSeNvSAulzHdK+P7S2kkgCaRA4uCmAymJW0prD44TJoQp37RgKJ2EyySFTK7FZuJMiIHUIAcSIDg1BITlqyRLq9XunnM+vz9WWix80+VIu5Kej5m1pLNnd99nR6uXP5fzOcZaawUAQIycShcAAJh+CBcAQOwIFwBA7AgXAEDsCBcAQOwIFwBA7AgXAEDsCBcAQOwIFwBA7LxKF4Dp4387V1a6BMTgiejRCXtufkemh5H8jtByAQDEjnABAMSOcAEAxI4xl3Hq6M6pK1tQUyahlsZ0pcsBgKpAuIxDR3dOKzZuVa4YKu272rxmOQEDAKJbbFy6sgXliqFu/OPTlSuG6soWKl0SAFQFwiUGtFYAYDjCBQAQO8IFABA7wiVGBxhzAQBJhEssmjIJpX1X1z24XR3duUqXAwAVR7jEoKUxrXtWLmHGGAAMIlxiMjuTqHQJAFA1CBcAQOwIFwBA7AiXcWB2GAAcHeEyRh3dOV334HalfVdNh4237Nzbx4wxADMeC1eO0dC6Yg9cvay8/Evad7X64XYWsQQw49FyGaehWWItjWltXrNcd161mCnJAGY8Wi4xamlMq6u5ttJlAEDF0XIBAMSOlguqmzGSrGQrXQgwAxgjOY5kJIWRZMf+waPlguplHBnHlQy/psCkcBw5qZScVKoUMuN5qphKwjtwDkwMzOCt9A+AyXJ4g6Xcmhnd55BwiRkrJAOYsqJQ0UBO0cCAFIWSJOP7ctJpmcTo1k8kXGLGCskTgIYLMDmsSmMtYfh268UxMq4rM8rWCwP6E4AVksfJGMmY0i+z48rYaHBc0UpRVOnqgOnHdWV8/+2frZUtFod/3lxXJpUc8eQawgXVxzgyTqmf1zhG1joytjRjzBozrhksAI5kXFfOYd1e1kayYSAdli3GcWSckf/HmXBBdXBdmUy61FIZ2jaYISYMZaPxTYsEZix3cNal40ieW+oZcF3JMQpTnqKEI7do5RSsFIay+YKskaK5DbIJV451ZeRIhUAmlx/x55BwGYOO7px27u2rdBnTi+/JzJktk/ClIJTCSCYIpSAo/bLnGb8CxsJ4vkwyIeN5UioluY6USsp6jqI5NQrqEjL7s9LuQ9JAXlFvr6znKjhljqI59fL7inL6Q+lQVsoXZELCZUJ0dOe0YuNW5YrhESsiYwyMkRwjeZ6ilCeT9GWKTmlQMS+ZKCrdz6A+MDqDA/DG90ozvXxPSvql7Y4jY4xMIZCTtYo8q3xzUqbfyIkyso6RMY6cYqSgxqhY68pzXCW6XI30w0i4jNLQash3XrVYS1tnsfLxeA329UaZlIpzamRTCTmFSE4QyT2UkxtE4z6ZC5hxjCm3VkxtRqrNyHqObCohWSunWOod8Hd3yysUlD2jXj1LZ8nvs6rf2Sh3wMovhDL7+nXwnKR6zkyo7jeB5uxNySmMbFIN4TJGpzfXEiwxMIOtFiU8hTWuorQr1zOKAkem35EjW+7jPfxfAMfgmNKkGFNquVjPlRKerOfKJtzBSZdWRlZ2cAZmmDAq1vsyjlXYYGQSkZy+nBSGCmukYr2jYp2rsNaT8oQLpgLfl2moUzg3qZ4zHBXrjbycK6cg1RZD1b3eL1soygZBKWTIFuDYPE9OXW0pVHI52VxBdladbENKUdJRMePJSHLyvkxkFbSkFbqR8vMTkiMFaaO+kz05iuTMcaW01UCy1A02MC+hfcubpHCEpUzcUQIj4LlSKqko4ys/x6jQKLlZR05eSiYH59qXg4VkAY7HOI5MMlkKl/6cFISyjhQlPYUpR0GNKyMj14skKxVrkwpSRmGdJCNZTyo2GMk3Mqc5Ur2j8JBkeq2COlfZhCfGXFDdBk+UjNK+inPTcuZbnXryAUUNVns7m5TtTcm6kRRFpWnINFmAI3mejOuWfzSuKxWLpQH7uoxUl5ErV87BPpkaX9ZJy3qOwqSR9aXE7/WrprmgvOfIS7hKOUXN9bKSa3WgJqEBz1VjY16J+lC5fELd/TWylnBBNRs8Az9I+yrMrVHNvJwWtuyX0xCorz+lQ4WkIte+fX4L2QIcwXjesJMfJUnFoHRuS2N9qRVTKMocyMoUUlIyoTAlFeo8RRmr2tZ+1ZzWKz/w5AQJNSRyOq1+T2nF/UPN6imkNac+q6Zkvw7kMurvcRRGI5tgQ7igIoznyfi+ojpPA3Mlv8nK9wN5CpTKWiW7JG/AyDiurGNLLR26xYDholA2KB5lu1M6J0VSmHYVNqYV1iZUmO0qSjgK0pJNGPXnEyoeqpF1JbmStUaFyJPvhDop1aO5fq9q/KJSXiCTsMrXeAppuaCamWRSJlOj4ryUut8jubMjpWoKSpui6vaFyu4ySh4aXO/IWhouwFHYQlG2GBx5hzFyJFnfV37eHOVOn6UgYzQwq3QhMBMYGWOV7atV+GaNMg0DqpuVVWAd9YVJ1Sqvc+vf0Cw3q6xNqj9Kak4iodmprCLCBVVr8MRJY4wSyUBNDX1qqOtX0i0qYQN5RSsnb+UUI5Z9AU7ksM+HdczbJ0q6g1ORXaMo4SpMSOHg2RNurjQsPzsxoHQ6r2Qqp3SiXwkvUMopyjOhCqGnrE3IOFa17oCKkati5Cq0dItV3M69fWrKJDgf5nDO2/PvJWlh4wH93pmvKJkJVJcaUJBzlSoU5WcjmWxBUTZbWpmVgAFOrCalqHVBqcXf1S+TD0rnkUmySaugKZSskVN0lYpC/X+tL+mPTntNPSbQAVNUzia0N6pTNkzqFwcXqjtfo+VzfqO2xl3akUvqhQMLNBD6JyiihHCZAEMXDFv9cLvSvqvNa5YTMEMGZ4kN3TKJvE6p75aTilQIXQWhJycotVpMEEphwGA+cCyHX6nV2lJrpSYlm/ClbEEKIhmZ0npg1sp6g5NjXCvHiTS/pk9nNBzU/ihUOgzUE6XUX0ioGLnqLaa0L1+rgaIvN4oUBo66B2o0EBEuFdPSmNbmNcv1i10HtfrhdnVlC4TL4Ywk35OtSWluWnpfqk/7who9svMM7T2Y0cBbNfK7BqQcwQIcj0nXyCQTpdWMi4GMHJnOrtIq44GVsVKiqyBHWbk5V8W6pGzaymnOK0gE+qltVuc+VzV+r+r9buWsr4NBRkW5eu+s3ykKjbr31+vB316sTptRn9IKRniNScJlgrQ0ptXVXFvpMqqX50oJX/UJ6TR/QFGxRrs6F2jX3gbN68qqNltQVAjJFuBYBtcPczIZ2UJRxgwuh9+VLS0Bk0pJnicvG8grDihyk/J6UrKSTEugsLaoX6lBv+tNaWH6gN7jhCpaT9koJUeRTsvsVcbk9aPX3qufvvq/FNZYBU2BRjjkQrhg8llJQb2vcH5Kv0nN1mNdv6d9fRnluhNKdFuZ7n7Zrqw0kK90qUD1MaWp/DKOVCwq6uuTrEoX1DsK67uKahKK0p6sbxQ6ki26MgNSr0mpWHRlc1K2N6kocDTQn5JjrLoaa5RMFLS3u0F+n2Si0nNZhyX3Ua2MUX5WQgOnZrSjZp5e3ptS1Ourf39SyQNWzr4+2f1dsuEIFzECZhLjyCSSkuPI5vOy2ayMn5BSqSMXZjGlpV+C+qTCjKvIl0LXKMj7stZVIfDkuJF2hw1S0ZHJG3kHPTnGyjulX06mKHOgRskuySkYWWNouaC6Wcco8qSg6MoeSEmHjLz9RZkDkZx8wBRk4FislQ3DUksligbHJQc/K0OrjA9eddI6jkwQyukbkFPjy825kiOF1soayTtk5BYdRZGjKHRkAiMNOLLGyh70ZLNGTp8jE0reoaLUO6CRDoQSLph8Roo8KUwaRb0JBb/05XcXVPd8t7zuvOzB0lLfAI7C2lKLxUiK3vGH3vOk+tq3L2csyfTm5O3tUiJXq0xdQsUmR+FJkSInUmaXq9SbriLXKPKNIs+omJYko8TupJzQyhSNVLRKvtUr/1dvlGZx3nviMgkXTCojU/pQDLXfC0YmK5keyc0W5fQXFYURA/nA8bxzvT2r8iKvZug+p/RBM2EkFYpyCqGcguQWrNyB0pCN22/k9ZWCJfSNjCdFspKRnH4jJzBSZGWslZML5PXkZYoj+48f4YLJY4zkezK+Jzd05OWs/EOB0vvycrJ5Ob15KV8Y/GC4kqVrDBgJGwSyNpIKeZmBAclzZWY1yaRS5X1MZOUWrEyPUf0LrqzryDs02LoJrdzIyuu3Su0LJCMFtb4i35HfF8rPBjK9wZEtpeMgXDCpjGNKZ+lHRk4geblQia6iTC6QCkFpEN9KxhhZsVglMCLWSkEoKZQtFEvnudTXa1jzxg6GSF5y9x3efVCaCWYkOQUrv6cULlGi1F3mFEJ5/YFsfnRd1YTLKB3IFipdwrTgZ0OZ/UV5vUGpmV0MZAsFKV84bJl9ggU4HuN5pfGVICxdrXWItVIuV2ppFArDMsaEkdy+okwYKcwkFCXfvh6MikWZrkMyxVD+wUiuK3lFUxroz/bLjuIzSbiMQkd3Ttc9uF1p31VTJnHiB+DorOT1R3IPFuXkQ5kgkg3CUrgUj7J8OICjG7yeS6RC6YqtQ6yVcnnpaOMjoZV/KC9TjErnwAwLl1Cmu08mV5CXy0lBIJNKySQSUrFIuEyUrmxBuWKoB65exnIuY2FUOqvYGJmBgnSov/TLny+WQoWWCjA6YVi6FPjQ7EpjSl1ijinPFrNRKIWRTHZA3r7e0sKxQWng3zmUkzswUH46ZyAYvMyFkQmD8nWUbLFY7rIeKcJlDGbTahmj0niLHEdOX07KDrwdKEFQmrMPYMRssVi6WNjQH33HkZMqnWBpBsdUbDGQLeSlMFQiH0i+L1NfJ3muvD098nKHrYSR8GTqaqV06Yx/my/I5vOKBnKjXuePcMEksqU+4CiSoqEtg9MmR/m/IgCDjvjcmNKU/6HZljYaXB4mGlwlebALOnBKvQaFw8aRrZVNDnZNR9HbMzbH8NkkXCYBkwAGWStbKJSa8YdvGxrAp+UCxMIOtTqC4IjuZhsEsvsOlD53YTT8c+cMSP39pe/DsPSfwTF2V49wlRiMxdB1Xa57cLs6unOVLqfyrGTDwV/owZsNw8FfYoIFiId9+z9thy+jNLRMTBSVZ2aWu6OHbkFY2p4vlL4fxzJMhMsEamlM656VS5Qrhuqi9VJiI9koLN8YxAdiFEWyA3nZgYEjllCyYSg7MKAonx/VyZBjRbfYBGPw/x0IE2DiWDv8fJd33lc8xn0TgJYLACB2hAsAIHaECwAgdoQLACB2hAsAIHaECwAgdoQLACB2hAsAIHaECwAgdoQLACB2hMsIdXTntHNvX6XLAIApgbXFRqCjO6cVG7cqVwy5xDEAjADhMgJDlze+86rFWto6i0scA8AJ0C02Cqc31xIsADAChAsAIHaEywhwmWIAGB3C5QQ6unO67sHt4x7I37m3j0sdA5gxCJcTGBrMv2flkjGNtzRlEkr7rlY/3K4VG7cSMABmBMJlhMZ6ueKWxrQ2r1muO69arFwxVBddbABmAKYiT4KWxrS6mmsrXQYATBpaLgCA2BEuAIDYES4AgNgRLgCA2BEuAIDYES7HMRHL7HMyJYCZgKnIxxD3MvuHn0yZ9l1tXrOcRTABTFuEyzHEvcz+0MmUv9h1UKsfbldXtkC4AJi2CJcTiHOZfU6mBDBTMOYCAIgd4QIAiB3hAgCIHeECAIgd4QIAiB3hAgCIHeECAIgd4XIMByb4ipET/fwAUEmEy1F0dOd03YPbY1n25Z2GloG57sHtrDEGYNoiXI5iaOmXe1YuiX2JlpbGtO5ZuUS5YqguWi8ApinC5Thmx9xqmejnBYBqQbgAAGJHuAAAYke4AABiR7i8w0RcfRIAZhqu53KYuK8+CQAzFeFymLivPgkAMxXdYocZOms+zqtPAsBMRLgMmsiz8gFgpqFbbNBQl9gDVy+j1QIA40S4vMNknj0/NCutKZMg0ABMK4RLBQwtXrn64XZJUtp3tXnNcgIGwLRBuGjyz21paUxr85rl6soWtHNvn1Y/3D5sEUtCBsBUN+Jw2XtoQHt78xNZS0UcyBZ03YPbJ/3clpbG9LAQeXbXQW348SuSpHtWLpmw7rmzWxom5HkB4HDGWmsrXQQAYHphKjIAIHaECwAgdoQLACB2hAsAIHaECwAgdiOaimytVW9v70TXgklSV1cnY0ylywAwjY0oXHp7e9XQwPkR00VPT4/q6+srXQaAaWxE57lMZMvl0KFDOuWUU/TGG29M2z941XaMtFwATLQRtVyMMRP+R7G+vr4q/vBOpJlwjAAgMaAPAJgAhAsAIHYVD5dkMqm1a9cqmUxWupQJMxOOEQAOx8KVAIDYVbzlAgCYfggXAEDsCBcAQOwIFwBA7MYdLnfffbdOPfVUpVIptbW16dlnnz3u/o8++qjOPPNMpVIpLVq0SD/4wQ+G3W+t1Ze+9CUtWLBA6XRaK1as0Kuvvjpsn1NPPVXGmGG39evXj/dQKnZMP/nJT444nqHbL37xC0nSa6+9dtT7n3766diOGwBiY8fhoYcesolEwt533332V7/6lf3kJz9pGxsb7Z49e466/1NPPWVd17V33HGH/fWvf21vvfVW6/u+feGFF8r7rF+/3jY0NNjHHnvM7tixw15++eW2tbXV5nK58j4LFy60t912m929e3f51tfXN55Dqegx5fP5Yceye/du+4lPfMK2trbaKIqstdbu2rXLSrKbN28etl+hUIjluAEgTuMKl2XLltnrr7++/HMYhvakk06y69atO+r+H/7wh+2ll146bFtbW5u99tprrbXWRlFk58+fbzds2FC+v7u72yaTSfutb32rvG3hwoX2q1/96nhKP6ZKHdPhCoWCnTt3rr3tttvK24bC5fnnnx/roQHApBlzt1ihUND27du1YsWK8jbHcbRixQpt27btqI/Ztm3bsP0l6ZJLLinvv2vXLnV2dg7bp6GhQW1tbUc85/r16zV79mydd9552rBhg4IgGOuhVM0xDfnud7+rAwcO6OMf//gR911++eVqbm7WRRddpO9+97ujPkYAmAwjWrjyaPbv368wDDVv3rxh2+fNm6eXX375qI/p7Ow86v6dnZ3l+4e2HWsfSfrMZz6j9773vZo1a5Z+/vOf65ZbbtHu3bv1la98ZayHU/FjOty9996rSy65RCeffHJ5W21trTZu3KgLL7xQjuPo29/+tq644go99thjuvzyy0d3oAAwwcYcLpV00003lb8/55xzlEgkdO2112rdunVTfomVN998Uz/+8Y/1yCOPDNs+Z86cYce9dOlSvfXWW9qwYQPhAqDqjLlbbM6cOXJdV3v27Bm2fc+ePZo/f/5RHzN//vzj7j/0dTTPKUltbW0KgkCvvfbaaA9jmGo4pk2bNmn27NkjCoy2tjbt3LnzhPsBwGQbc8slkUhoyZIl2rJli6644gpJUhRF2rJli2644YajPub888/Xli1btHr16vK2J554Queff74kqbW1VfPnz9eWLVu0ePFiSaULbT3zzDP69Kc/fcxa2tvb5TiOmpubx3o4VXFM1lpt2rRJq1atku/7J6y3vb1dCxYsGP2BAhXyv50rK10CYvBE9OgJ9xlXt9hNN92kj370o3rf+96nZcuW6c4771Q2my0PRK9atUotLS1at26dJOmzn/2sli9fro0bN+rSSy/VQw89pP/+7//WN77xDUmli5KtXr1at99+u9797nertbVVX/ziF3XSSSeV/9hv27ZNzzzzjN7//verrq5O27Zt0+c+9zn91V/9lZqamsZzOBU7piFPPvmkdu3apU984hNH1PXAAw8okUjovPPOkyR95zvf0X333ad/+7d/G/cxA0DcxhUuV111lfbt26cvfelL6uzs1OLFi/WjH/2oPHj9u9/9To7zds/bBRdcoG9+85u69dZb9YUvfEHvfve79dhjj+nss88u7/O3f/u3ymaz+tSnPqXu7m5ddNFF+tGPfqRUKiWptHz9Qw89pL//+79XPp9Xa2urPve5zw0bj5hqxzTk3nvv1QUXXKAzzzzzqLX94z/+o15//XV5nqczzzxTDz/8sP7iL/4iluMGgDix5D6ASUO32PQwkm4x1hYDAMSOcEFV6OjOqaM7V+kyAMSEcEHFdXTntGLjVq3YuJWAAaYJwgUV15UtKFcMlSuG6soWKl0OgBgQLgCA2BEuAIDYES4AgNgRLgCA2BEukm6++WYl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HgmmA7rFUJUKhYK2b9+uFStWlLc5jqMVK1Zo27ZtR33Mtm3bhu0vSZdcckl5/127dqmzs3PYPg0NDWprazvmc0qlFYJnzZp1xPbLL79czc3Nuuiii/Td7353VMcXt0q/X+vXr9fs2bN13nnnacOGDQqCIK5DwxTFwpWoSvv371cYhpo3b96w7fPmzdPLL7981Md0dnYedf/Ozs7y/UPbjrXPO+3cuVN33XWXvvzlL5e31dbWauPGjbrwwgvlOI6+/e1v64orrtBjjz2myy+/fHQHGpNKvl+f+cxn9N73vlezZs3Sz3/+c91yyy3avXu3vvKVr4z7uDB1ES7AMXR0dOhDH/qQrrzySn3yk58sb58zZ45uuumm8s9Lly7VW2+9pQ0bNlQsXCrp8PfinHPOUSKR0LXXXqt169axlMwMRrcYqtKcOXPkuq727NkzbPuePXs0f/78oz5m/vz5x91/6OtInvOtt97S+9//fl1wwQX6xje+ccJ629ratHPnzhPuN1Eq/X4drq2tTUEQ6LXXXhvtYWAaIVxQlRKJhJYsWaItW7aUt0VRpC1btuj8888/6mPOP//8YftL0hNPPFHev7W1VfPnzx+2z6FDh/TMM88Me86Ojg5dfPHFWrJkiTZt2iTHOfHHpL29XQsWLBjVMcapku/XO7W3t8txHDU3N4/nkDDVVXpGAXAsDz30kE0mk/b++++3v/71r+2nPvUp29jYaDs7O6211q5cudLefPPN5f2feuop63me/fKXv2xfeuklu3bt2qNOrW1sbLSPP/64/eUvf2n//M//fNjU2jfffNOefvrp9gMf+IB98803h02vHXL//ffbb37zm/all16yL730kv2nf/on6ziOve+++ybpnTm6SrxfP//5z+1Xv/pV297ebn/729/a//iP/7Bz5861q1atmtyDR9UhXFDV7rrrLvuud73LJhIJu2zZMvv000+X71u+fLn96Ec/Omz/Rx55xJ5xxhk2kUjY3//937ff//73h90fRZH94he/aOfNm2eTyaT9wAc+YF955ZXy/Zs2bbKSjnobcv/999uzzjrL1tTU2Pr6erts2TL76KOPTswbMEqT/X5t377dtrW12YaGBptKpexZZ51l//mf/9kODAxM6HGi+rHkPgAgdoy5AABix1RkAIA6unPqyhbUlEmopTE97ucjXABghuvozmnF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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "_ = pairplot(\n",
+ " samples_base,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [0,3]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"model\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "401a2bc0-e174-4606-9324-67c2c2ba59e0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df_samples_base = pd.DataFrame({'lambda':[x[0] for x in samples_base.tolist()], 'mu':[x[1] for x in samples_base.tolist()], 'model':[x[2] for x in samples_base.tolist()]})\n",
+ "sns.distplot(df_samples_base['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6e34a3a8-383a-4a71-903b-9ebc79614eff",
+ "metadata": {},
+ "source": [
+ "### Decay"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "8d0554a3-2414-49d0-83ac-d07da943d26f",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Neural network successfully converged after 68 epochs."
+ ]
+ }
+ ],
+ "source": [
+ "#with open(\"pretrained_models/inference_joint.pickle\", \"rb\") as f:\n",
+ "# inference = pickle.load(f)\n",
+ "#posterior = inference.build_posterior(sample_with=\"rejection\")\n",
+ "#likelihood_estimator = inference.train()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "65d53b04-26d4-42da-94e4-ae71f3051214",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "a8b44246b96441c793966879a1156776",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/10000 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "theta0_decay = prior.sample((10_000,))\n",
+ "\n",
+ "theta_decay = []\n",
+ "x_decay = []\n",
+ "\n",
+ "for t in tqdm(theta0_decay):\n",
+ " vec = compute_summary_stats(simulator_decay(t))\n",
+ " if vec != None:\n",
+ " theta_decay.append(list(t))\n",
+ " x_decay.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c5b293f8-92bc-4564-ad8e-696dc443c596",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "samples_decay = posterior.sample((N_samples_posterior,), x=x_decay)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ce2f0ccf-8684-4a7b-8855-cbe551c6dec0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_ = pairplot(\n",
+ " samples_decay,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [0,3]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"model\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0bf5b321-21c0-4eef-8552-56ca99065fbe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df_samples_decay = pd.DataFrame({'lambda':[x[0] for x in samples_decay.tolist()], 'mu':[x[1] for x in samples_decay.tolist()], 'model':[x[2] for x in samples_decay.tolist()]})\n",
+ "sns.distplot(df_samples_decay['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "86ae8575-bb00-45fa-bc1e-97deef1eb607",
+ "metadata": {},
+ "source": [
+ "### Decimation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "3a4bdda9",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "cbe9907142734d4ca8091b72608dbc6f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/10000 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "theta0_decim = prior.sample((10_000,))\n",
+ "\n",
+ "theta_decim = []\n",
+ "x_decim = []\n",
+ "\n",
+ "for t in tqdm(theta0_decim):\n",
+ " vec = compute_summary_stats(simulator_decim(t))\n",
+ " if vec != None:\n",
+ " theta_decim.append(list(t))\n",
+ " x_decim.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "45eb1c6c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "samples_decim = posterior.sample((N_samples_posterior,), x=x_decim)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "c3344ecf-66ea-494d-b3d5-f068aa38e84f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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TmzXNOC5557T1q1b9Y1vfOMz5XrggQeUTCZ1zjnnSJJ+8pOf6L777tO//Mu/HPM1A0DUjilcLrvsMn388cf63ve+p46ODs2cOVM///nPS53Xv/nNb+Q4+1rezj33XD344IO65ZZb9N3vflennnqqHn/8cZ155pmlc/76r/9afX19+uY3v6muri6df/75+vnPf66qqipJheXr165dq7/9279VNpvVtGnT9J3vfGdQf8RIu6YB9957r84991ydccYZByzb3//93+uDDz6Q53k644wz9PDDD+vP/uzPIrluAIgSS+4DGDY0i40OR9IsxtpiAIDIES6IRXtXRu1dmbiLAaBMCBcMu/aujFpXrlfryvUEDDBKES4Ydp19OWXygTL5QJ19ubiLA6AMCBcAQOQIFwBA5AgXAEDkCBcAQOQIF0k33XSTUqmUvvrVr8ZdFAAYFQgXSTfffLNWrlyphx56iFWGASAChIsKO0NeeeWVchxHr7/+etzFAYARj3Ap8n1f48aN0+bNm+MuCgCMeIRL0S233KLe3l7CBQAiQLhIamtr06pVq3TxxRcTLgAQgTEfLmEYatGiRbrmmmu0cOFCvfvuu8rn83EXCwBGtDEfLnfffbd27dql2267TTNmzFA+n9fbb78dd7FGtd2sJwaMemM6XNrb23XrrbfqnnvuUXV1tU499VSlUimaxsqovSujxWva4i4GgDIb0+Fy3XXX6Q//8A918cUXS5I8z9P06dMJlzIaWBH5xotOj7soAMrIi7sAcfnpT3+q5557Tm+99dag4zNmzCBchsHE6mTcRQBQRmM2XL785S+rs7PzM8f/9V//NYbSAMDoMqabxRA/OveB0YlwQSzGVyeVTrhavKaNrY6BUYhwQSyaG9JatWAWWx0DoxThgtjQqQ+MXoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKEC4bVbrY0BsYEwgXDpr0ro8Vr2pROuBrPFsfAqEa4YNh09uWUyQdatWCWmhvScRcHQBkRLhh2E6m1AKMe4QIAiBzhAgCIHOGC2DGCDBh9CBfEZnx1UumEq8Vr2tTelYm7OAAiRLggNs0Naa1aMEuZfKBOai/AqEK4IFaMHANGJ8IFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUVYXdfLu4iAIgQ4YJYja9OKp1wtXhNm9q7MnEXB0BECBfEqrkhrVULZimTD9RJ7QUYNQgXxG5idTLuIgCIGOECAIgc4YJhQ6c9MHYQLhgW7V0ZLV7TpnTC1XiawYBRz4u7ABgbOvtyyuQDPfD1OWpuSMddHABlRs0Fw4rOe2BsoOYCIF7mU984xc+81ko2LBwzpvi9jaGAOBqEC4D4mGJw7Pe9k0hIjiPr+7K+L+M4hcCxVtb3CZgRgnABMPwGQsVzZVxP1khyjKxjFFQVwkU5X/J9SUZGjhSGhceEYeEmq1K1h1pNxSFcAAwfx5FkZFJJGc+VasbJ1lZLCVdBdUJhwihX5ylMGHl7Q7n9oZx8KC8TyOQDOT17ZfKBbCYj5X3JMZJxZANftj9LwFQQwgXAMDIyxsi4roznySaTMuPSsilXYX1SQcJRMMFRkDJy+wKZ/lBe1ldqb17KGVmTkM07CuUrNCo0mRlHJi9Zk5NkCxUaxI5wATBsjFsIA6WrCrdUYfSgX2XUe7yrsFpyTuqXU+NrUmKPJrl9ajZ7NN39WL35hDZ1T1J3pko73qhXb0eVvJzk5iSnt1/eDk/K+wr3ZqQgiPlKRyljDn9OEeECYPgM1DSSCakqJZNwZSWFCal/giNbb5U6KSevIae6ui5Nru7S6amP9fvV72uXP07b9yQV9ko7TJOy48Yr7AuV6AnlpRIyvXmpPyf1ZwmXcigNvjiygCFcMCxYTh+SCm/6JpTt21vorPc8KeHJdVJK70gqzDiy1Snlej3tmNSgbENCk+uySlYn5CipnnxanX5avfWOMseH8vdIfpWjpJeQ1zVOJunJhIGUzctms1I+P/j3m/0GAGBoSs/ZkT13hAvKrr0ro0Vr2kpfn9lcH3OJEBfr+4V/9/QUajAJT8bz5PrVqqmpVlCTUI+qlK8z2pZN6Df5ev2Wk1G6MSXPpvRJtkY78zXaM8nR3rQvr9NVosZTkEoo1V0jb68v1zhSNq+ws0uWcInWEJ43wgVlt/8+LSz9AknFN6lQCoLC5+D+nJzuvbJ5T4l0UmavozDIK+zOq/eThN7smagdGqfe/nHK51PydkjpnlBudyCvM6dEt5WT8aWsL5vLy+TyxeHK+zGGzv5hRLhg2Pz02vOptaCgOC/F2rDQPBb4crM5uZ6rRPs4KenKmlByQv0mVaUf1Zyt/tqUtp02SbmEp9r3spqwOyvTk5HZk5GxRq51JT9Q2LVHNp+XDcJ9s/2lQrDY8KBFQrQIFwDxscX/+IHUn5fcQK5xJdcr1DxsqFwioZ1dSeXrE/IbrJQM5e72lfgkX+jE780V5rt4nhQUwsr6gQZXU4xkGKY8nAgXAPGzVtbPS4FRGASFsLCF43KM5LgyXUbVn+yWdYy8vFM4tz8rZbPF/ptE4fygOHt/YNa+MfsGOBWXkaHPpfxYFRkV48t3/1Kb27vjLgbiYq0UhoUmrWxONpfb93UmI7NnrxLt3Up+2CWns0/a2y9ls7K5fOG84vkHb/oqDqMdwlwNHD3CBbHbf/MwhizjsGxh1JnN5YrNXyrUfIKgcAvDwbWTga9tWLxRaxkOhAvK7nDbGzc3pPV/F8wqfQ0cVhAUaikDI8KsLcyhCYIDN3tZO/iGsiNcUFZHur0xoQKMLnToo6y27Owd0vbGh6vlABgZCBdEZueefu3syZa+392XK9VaTmmsOeRjx1cnlU64WrymTasWzGI75BgxFwlRMNbSAAkAiBZ9LgCAyBEuAIDIES4AgMgRLgCAyBEuAIDIMRQZkbDWqqenJ+5iICK1tbUyrMGFY0C4IBI9PT2qr2d+xGjR3d2turq6uIuBEYxwQSRqa2vV3T0yVjTes2ePTjzxRG3bto030P3s/7zU1tbGXRyMcIQLImGMGXFv1HV1dSOuzMOhrq6OJjEcMzr0AQCRI1wAAJEjXDDmpFIpLV26VKlUKu6iVBSeF0SJhSsBAJGj5gIAiBzhAgCIHOECAIgc4QIAiBzhgop2zz33aOrUqaqqqlJLS4teeeWVQ57/6KOP6owzzlBVVZVmzJihp556atD91lp973vf05QpU5ROp9Xa2qp33323dP/777+vK6+8UtOmTVM6ndZv//Zva+nSpcrlcoPOMcZ85vbSSy9Fe/FHYbifL0maOnXqZ56L5cuXR35tGGEsUKHWrl1rk8mkve++++wbb7xhr7rqKtvQ0GB37NhxwPNfeOEF67quveOOO+ybb75pb7nlFptIJOzrr79eOmf58uW2vr7ePv7443bTpk12/vz5dtq0aTaTyVhrrX366aftFVdcYX/xi1/Y9957zz7xxBO2sbHR3nDDDaWfsXXrVivJPvvss3b79u2lWy6XK+8TchhxPF/WWnvyySfb2267bdBz0dvbW/brRWUjXFCx5syZY6+++urS90EQ2OOPP94uW7bsgOd/5StfsRdffPGgYy0tLXbRokXWWmvDMLRNTU12xYoVpfu7urpsKpWyDz300EHLcccdd9hp06aVvh8Il9dee+1oLqts4nq+Tj75ZHvnnXdGeCUYDWgWQ0XK5XJqa2tTa2tr6ZjjOGptbdWGDRsO+JgNGzYMOl+SLrrootL5W7duVUdHx6Bz6uvr1dLSctCfKRVWCJ4wYcJnjs+fP1+NjY06//zz9eSTTw7p+qIW9/O1fPlyTZw4Ueecc45WrFgh3/ejujSMUCxciYq0a9cuBUGgyZMnDzo+efJkvf322wd8TEdHxwHP7+joKN0/cOxg53zali1bdPfdd+v73/9+6VhNTY1Wrlyp8847T47j6LHHHtMll1yixx9/XPPnzx/ahUYkzufruuuu0+c+9zlNmDBBL774om6++WZt375dP/jBD475ujByES7AQbS3t+tLX/qSLr30Ul111VWl45MmTdL1119f+n727Nn66KOPtGLFitjCJU77PxdnnXWWksmkFi1apGXLlrGUzBhGsxgq0qRJk+S6rnbs2DHo+I4dO9TU1HTAxzQ1NR3y/IF/j+RnfvTRR/rCF76gc889Vz/+8Y8PW96WlhZt2bLlsOeVS9zP1/5aWlrk+77ef//9oV4GRhHCBRUpmUxq1qxZWrduXelYGIZat26d5s6de8DHzJ07d9D5kvTMM8+Uzp82bZqampoGnbNnzx69/PLLg35me3u7LrjgAs2aNUurV6+W4xz+z2Tjxo2aMmXKkK4xSnE+X5+2ceNGOY6jxsbGY7kkjHRxjygADmbt2rU2lUrZ+++/37755pv2m9/8pm1oaLAdHR3WWmsXLFhgb7rpptL5L7zwgvU8z37/+9+3b731ll26dOkBh9Y2NDTYJ554wv7qV7+yf/InfzJoaO2HH35oTznlFHvhhRfaDz/8cNDw2gH333+/ffDBB+1bb71l33rrLfsP//AP1nEce9999w3TM3NgcTxfL774or3zzjvtxo0b7XvvvWf/7d/+zR533HF24cKFw3vxqDiECyra3XffbU866SSbTCbtnDlz7EsvvVS6b968efbyyy8fdP4jjzxiTzvtNJtMJu3v/M7v2J/97GeD7g/D0N5666128uTJNpVK2QsvvNC+8847pftXr15tJR3wNuD++++306dPt+PGjbN1dXV2zpw59tFHHy3PEzBEw/18tbW12ZaWFltfX2+rqqrs9OnT7T/+4z/a/v7+sl4nKh9L7gMAIkefCwAgcgxFBlDR2rsy6uwrrO02vjqp5oZ0zCXCkSBcAFSs9q6MWleuVyYfSJLSCVfP3jCPgBkBaBYDULE6+3LK5APdddlM3XXZTGXyQakWg8pGzQVAxTulsSbuImCIqLkAGFF2U3MZEQgXACPC+Oqk0glXi9e0qb0rE3dxcBiEC4ARobkhrVULZtHvMkIQLgBGjInVybiLgCNEuAAAIke4AIfxy1/+UolEQv39/aVj77//vowx+uCDD2IsGVC5CBfgMDZu3Kjp06erqqqqdOy1117T+PHjdfLJJ8dYMqByES7AYWzatEnnnHPOoGMbN27U2WefHVOJgMpHuACHsXHjRs2cOXPQsddee+0zxwDsQ7gAhxAEgTZv3vyZmsurr75KuACHQLgAh/DOO++ov79fxx9/fOnYhg0b1N7eTrgAh0C4AIewceNGSdLdd9+td999V08//bQWLlwoScrlmMgHHAzhAhzCxo0bddFFF+nXv/61ZsyYob/5m7/R3/3d36murk4//OEP4y4eULFYFRk4hE2bNmn27Nm6/fbbBx3/6le/GlOJgJGBmgtwCJs2bdKMGTPiLgYw4hAuwEF0dHRox44dhAtwFGgWAw6iqalJ1tq4izFmtXdlWFp/BCNcAFSc9q6MWleuVyYfxF0UHCWaxQBUnM6+HMEywhEuAIDIES4AKlo64Wo8m4SNOPS5AKhY/3fBLJ3ZXK/mhnTcRcEQUXMBULGaG9IEywhFuAAAIke4AAAiR7gAACJHuAAAIke4AAAiR7gAACJHuAAAIke4AAAixwx9ABWjvSujzr4cS+2PAoQLgIrAMvujC81iACrCwDL71/7vU+IuCiJAuACoKKwlNjoQLgCAyBEuAIDIES4AgMgRLgCAyDEUGUBFGV+dVDrhlr7GyES4AKgozQ1pPXvDvNLXGJkIFwAVh1AZ+ehzAQBEjnABAESOcAEARI5wAQBEjnABAESOcAEARI5wATDi7O7LxV0EHAbhAmDEGJi9v3hNG7tVVjjCBcCI0dyQ1qoFs5TJB+qk9lLRCBcAI8pE1hsbEQgXACNWe1eG5rEKRbgAGJHauzJqXblerSvXEzAViHABMCJtbu9WJh/Q/1KhCBcAI8rAiLG7n9sSd1FwCCy5D2BEGdjvpbMvp/aujBataYu7SDgAwgXAiNPckGbPlwpHsxgAIHKECwAgcoQLgIrAemGjC+ECIHbtXRktXtOmdMLVeGbgjwp06AOIXWdfTpl8oAe+PoeO+lGCmguAisG6YaMH4QIAiBzhAgCIHOECAIgc4QIAiBzhAgCIHOECAIgc4QIAiBzhAgCIHOECAIgc4QIAiBzhAmDEY0XlykO4ABixxlcnlU64WrymTe1dmbiLg/0QLgBGrOaGtFYtmKVMPlAntZeKQrgAGNFYSbkyES4AgMgRLgBiR4f86EO4AIgVWxyPTmxzDCBWbHE8OlFzAVARjrVjfsvOXoYjVxDCBcCINjDXZcnDG9W6cj0BUyEIFwAjWnNDWs/eME93XTaT+S4VhD4XACNec0NanY01cRcD+6HmAgCIHOECAIgc4QIgVkygHJ0IFwCxYQLl6EWHPoDYMIFy9KLmAiB2rGw8+hAuAGLR3pXRlp29cRcDZUKzGIBh196VUevK9crkA/pbRinCBcCwG+hrueuymZo9bUKk/S2MPqsMNIsBiM0pjTWRBcvAGmOL17SxvlgFIFwAjArNDWmtWjCL9cUqBOECYNiVq+lqYNQZTWPxI1wADKtyTpykaaxyEC4AhtVAZ/6qBbMinzhJ01jlIFwAxKJcEyeZkFkZCBcAQOQIFwBjQntXhn6YYUS4ABhWcYzkGlgRoHXlegJmmBAuAIbN5vbuYVtifyDE2rsy2tzerUw+UCYf6L+2fkLAHKWh1P6MtdaWuTwAIEmafuvPJUmPLp6rM5vry/I7BmopkrTsT2fo5p+8rkw+GHROOuFq1YJZdP4Pwe6+nBavaZMkvfX3Xzrs+YQLACByNIsBACJHuAAAIke4AAAiR7gAACJHuAAAIsdOlACGhbVWPT09cRcDEamtrZUx5qD3Ey4AhsWuXbvU2NgYdzEQke7ubtXV1R30fsIFwLBIJgsTFrdt23bINyUU7NmzRyeeeGLFPl+1tbWHvJ9wATAsBppQ6urqKvLNslKN1OeLDn0AQOQIFwBA5AgXAMMilUpp6dKlSqVScRdlRBjpzxcLVwIAIkfNBQAQOcIFABA5wgUAEDnCBUDZ3XPPPZo6daqqqqrU0tKiV155Je4iVaRly5Zp9uzZqq2tVWNjoy655BK98847cRfrqBAuAMrq4Ycf1vXXX6+lS5fq1Vdf1dlnn62LLrpIO3fujLtoFWf9+vW6+uqr9dJLL+mZZ55RPp/XF7/4RfX19cVdtCFjtBiAsmppadHs2bP1ox/9SJIUhqFOPPFEXXvttbrppptiLl1l+/jjj9XY2Kj169fr93//9+MuzpBQcwFQNrlcTm1tbWptbS0dcxxHra2t2rBhQ4wlGxm6u7slSRMmTIi5JENHuAAom127dikIAk2ePHnQ8cmTJ6ujoyOmUo0MYRhqyZIlOu+883TmmWfGXZwhY+FKAKhAV199tTZv3qxf/vKXcRflqBAuAMpm0qRJcl1XO3bsGHR8x44dampqiqlUle+aa67RT3/6U/3nf/6nTjjhhLiLc1RoFgNQNslkUrNmzdK6detKx8Iw1Lp16zR37twYS1aZrLW65ppr9O///u967rnnNG3atLiLdNSouQAoq+uvv16XX365Pv/5z2vOnDm666671NfXp6997WtxF63iXH311XrwwQf1xBNPqLa2ttQvVV9fr3Q6HXPphoahyADK7kc/+pFWrFihjo4OzZw5Uz/84Q/V0tISd7EqzsH2pF+9erWuuOKK4S3MMSJcAACRo88FABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQAQOcIFABA5wgUAEDnCBQDK7IILLtCSJUuO+Pz7779fDQ0NZSvPcCBcAACRI1wAAJEjXACMWRdccIGuvfZaLVmyROPHj9fkyZP1z//8z6VVm2tra3XKKafo6aefLj1m/fr1mjNnjlKplKZMmaKbbrpJvu+X7u/r69PChQtVU1OjKVOmaOXKlZ/5vdlsVn/1V3+l5uZmVVdXq6WlRc8///xwXPKwIVwAjGkPPPCAJk2apFdeeUXXXnutvvWtb+nSSy/Vueeeq1dffVVf/OIXtWDBAu3du1ft7e36oz/6I82ePVubNm3SP/3TP+nee+/V7bffXvp5N954o9avX68nnnhC//Ef/6Hnn39er7766qDfec0112jDhg1au3atfvWrX+nSSy/Vl770Jb377rvDffnlYwFgjJo3b549//zzS9/7vm+rq6vtggULSse2b99uJdkNGzbY7373u/b000+3YRiW7r/nnntsTU2NDYLA9vT02GQyaR955JHS/bt377bpdNp++9vfttZa+8EHH1jXdW17e/ugslx44YX25ptvttZau3r1altfX1+GKx4+bBYGYEw766yzSl+7rquJEydqxowZpWOTJ0+WJO3cuVNvvfWW5s6dO2jflfPOO0+9vb368MMP1dnZqVwuN2ivmgkTJuj0008vff/6668rCAKddtppg8qRzWY1ceLEyK8vLoQLgDEtkUgM+t4YM+jYQJCEYRjJ7+vt7ZXrumpra5PruoPuq6mpieR3VALCBQCO0PTp0/XYY4/JWlsKnRdeeEG1tbU64YQTNGHCBCUSCb388ss66aSTJEmdnZ36n//5H82bN0+SdM455ygIAu3cuVO/93u/F9u1lBsd+gBwhP7yL/9S27Zt07XXXqu3335bTzzxhJYuXarrr79ejuOopqZGV155pW688UY999xz2rx5s6644go5zr632tNOO01//ud/roULF+onP/mJtm7dqldeeUXLli3Tz372sxivLlrUXADgCDU3N+upp57SjTfeqLPPPlsTJkzQlVdeqVtuuaV0zooVK9Tb26s//uM/Vm1trW644QZ1d3cP+jmrV6/W7bffrhtuuEHt7e2aNGmSfvd3f1df/vKXh/uSysZYa23chQAAjC40iwEAIke4AAAiR7gAACJHuAAAIke4AAAiR7gAACJHuAAAIke4AAAiR7gAACJHuAAAIke4AAAiR7gAACL3/wEaQLt2kYZ0yQAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "_ = pairplot(\n",
+ " samples_decim,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [0,3]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"model\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "cabb8a5c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_112805/1195207057.py:2: UserWarning: \n",
+ "\n",
+ "`distplot` is a deprecated function and will be removed in seaborn v0.14.0.\n",
+ "\n",
+ "Please adapt your code to use either `displot` (a figure-level function with\n",
+ "similar flexibility) or `histplot` (an axes-level function for histograms).\n",
+ "\n",
+ "For a guide to updating your code to use the new functions, please see\n",
+ "https://gist.github.com/mwaskom/de44147ed2974457ad6372750bbe5751\n",
+ "\n",
+ " sns.distplot(df_samples_decim['model'], hist=True, kde=True,\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 30,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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M5pjxcaNGy2n02mtW7fO+vjjj6077rjDysrKsqqrqy3Lsqzvfve71r333tt7/TvvvGMlJCRY//qv/2p98skn1v33328lJiZaZWVloXoLATHYz+UnP/mJ9cYbb1iHDh2ydu3aZX3729+2kpOTrY8++ihUbyEgmpubrT179lh79uyxJFkPPfSQtWfPHqu8vNyyLMu69957re9+97u91x8+fNhKTU21Vq5caX3yySfWo48+asXHx1uvv/56qN5CQAz2c1m9erX14osvWp9//rlVVlZm3XXXXVZcXJz1hz/8IVRvISC+//3vW5mZmdaWLVusqqqq3ltra2vvNbH4O2Yon0us/I659957ra1bt1pHjhyx9u3bZ917772Ww+Gw3nzzTcuyIv/7QrgJon//93+3xo4dayUlJVmzZs2y3n333d775s6day1ZsqTP9b/73e+sc88910pKSrIuuOAC65VXXglyxcExmM9l+fLlvdfm5+db11xzjbV79+4QVB1YPUuYz7z1fBZLliyx5s6da3vMtGnTrKSkJOucc86x1q5dG/S6A22wn8svfvELa+LEiVZycrKVk5NjzZs3z3rrrbdCU3wAmT4TSX2+A7H4O2Yon0us/I7527/9W2vcuHFWUlKSNXLkSOvrX/96b7CxrMj/vjgsy7KC108EAAAQWMy5AQAAUYVwAwAAogrhBgAARBXCDQAAiCqEGwAAEFUINwAAIKoQbgAAQFQh3AAAgKhCuAEQE+bNm6fly5cP+Pp169YpKysrYPUACBzCDQAAiCqEGwAAEFUINwBCat68efrBD36g5cuXKzs7W/n5+fqP//gPtbS06JZbblF6eromTZqk1157rfcxW7du1axZs+R0OlVYWKh7771X3d3dvfe3tLRo8eLFcrlcKiws1IMPPmh73Y6ODt19990aPXq00tLSNHv2bG3ZsiUYbxlAgBFuAITcf/7nf2rEiBF6//339YMf/EDf//73ddNNN2nOnDnavXu3rrzySn33u99Va2urjh07pmuuuUYzZ87Uhx9+qMcee0y/+c1v9M///M+9z7dy5Upt3bpVL730kt58801t2bJFu3fv7vOay5Yt044dO7Rx40bt27dPN910k6666ip9/vnnwX77APyMU8EBhNS8efPk8Xj0xz/+UZLk8XiUmZmpG2+8UevXr5ckVVdXq7CwUDt27ND//M//6LnnntMnn3wih8MhSfr1r3+tf/iHf1BjY6NaW1uVm5urp59+WjfddJMkqb6+XmPGjNEdd9yhhx9+WBUVFTrnnHNUUVGhUaNG9dYyf/58zZo1S//yL/+idevWafny5WpoaAjuBwJg2BJCXQAAXHzxxb3/HR8fr9zcXF100UW9bfn5+ZKkEydO6JNPPlFJSUlvsJGkyy+/XG63W0ePHtWpU6fU2dmp2bNn996fk5Oj4uLi3p/Lysrk8Xh07rnn9qmjo6NDubm5fn9/AIKLcAMg5BITE/v87HA4+rT1BBmv1+uX13O73YqPj9euXbsUHx/f5z6Xy+WX1wAQOoQbABHl/PPP13PPPSfLsnpDzzvvvKP09HSNGTNGOTk5SkxM1HvvvaexY8dKkk6dOqXPPvtMc+fOlSRNnz5dHo9HJ06c0J//+Z+H7L0ACAwmFAOIKH/3d3+nyspK/eAHP9Cnn36ql156Sffff79WrFihuLg4uVwu3XrrrVq5cqXeeust7d+/XzfffLPi4r78dXfuuefqb/7mb7R48WI9//zzOnLkiN5//32VlpbqlVdeCeG7A+AP9NwAiCijR4/Wq6++qpUrV2rq1KnKycnRrbfeqh//+Me91/zyl7+U2+3Wtddeq/T0dP3whz9UY2Njn+dZu3at/vmf/1k//OEPdezYMY0YMUKXXXaZ/uqv/irYbwmAn7FaCgAARBWGpQAAQFQh3AAAgKhCuAEAAFGFcAMAAKIK4QYAAEQVwg0AAIgqhBsAABBVCDcAACCqEG4AAEBUIdwAAICoQrgBAABR5f8DnMKMTSJkrWMAAAAASUVORK5CYII=",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "df_samples_decim = pd.DataFrame({'lambda':[x[0] for x in samples_decim.tolist()], 'mu':[x[1] for x in samples_decim.tolist()], 'model':[x[2] for x in samples_decim.tolist()]})\n",
+ "sns.distplot(df_samples_decim['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b1fd4857-27e0-498b-aed9-bbc9f06bab45",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/simulation_based_inference_joint.ipynb b/simulation_based_inference_joint.ipynb
new file mode 100644
index 00000000..22d651fe
--- /dev/null
+++ b/simulation_based_inference_joint.ipynb
@@ -0,0 +1,1269 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "64017290",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%load_ext autoreload\n",
+ "%autoreload 2\n",
+ "\n",
+ "import random\n",
+ "import torch\n",
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import networkx as nx\n",
+ "import birth_death_utils as bd\n",
+ "import os\n",
+ "from collections import Counter\n",
+ "from tqdm.notebook import tqdm\n",
+ "import pickle\n",
+ "from itertools import groupby\n",
+ "import pandas as pd\n",
+ "import yaml\n",
+ "import re\n",
+ "import multiprocessing as mp\n",
+ "import seaborn as sns\n",
+ "\n",
+ "from sbi.analysis import pairplot\n",
+ "from sbi.inference import NPE, simulate_for_sbi, NLE\n",
+ "from sbi.utils import BoxUniform\n",
+ "\n",
+ "from sbi.utils.user_input_checks import (\n",
+ " check_sbi_inputs,\n",
+ " process_prior,\n",
+ " process_simulator,\n",
+ ")\n",
+ "\n",
+ "from torch import Tensor"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "79252c43",
+ "metadata": {},
+ "source": [
+ "# 1) Computation of summary statistics"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "fb374c2a",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def compute_summary_stats(g):\n",
+ " \"\"\"\n",
+ " Generate a vector of summary statistics from a graph generated by birth-death simulation\n",
+ "\n",
+ " Parameters\n",
+ " ----------\n",
+ " g : nx.DiGraph()\n",
+ " tree graph generated by birth_death_utils.ct_bd_tree\n",
+ " \n",
+ " Returns\n",
+ " -------\n",
+ " list\n",
+ " vector of summary statistics characterizing a single tradition\n",
+ " \"\"\"\n",
+ " n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)\n",
+ "\n",
+ " if n_living == 0:\n",
+ " return None\n",
+ " \n",
+ " if n_living == 1:\n",
+ " return [1,0, -1,-1,-1,-1,-1,-1,-1]\n",
+ "\n",
+ " if n_living == 2:\n",
+ " birth_times_trad = []\n",
+ " for n in g.nodes():\n",
+ " if g.nodes[n]['state']:\n",
+ " birth_times_trad.append(g.nodes[n]['birth_time'])\n",
+ " timelapse = int(max(birth_times_trad)-min(birth_times_trad))\n",
+ " return [2, timelapse, -1,-1,-1,-1,-1,-1,-1]\n",
+ " \n",
+ " if n_living >= 3:\n",
+ " birth_times_trad = []\n",
+ " degrees = []\n",
+ " direct_filiation_nb = 0\n",
+ " arch_dists = []\n",
+ " st = bd.generate_stemma(g)\n",
+ " archetype = bd.root(st)\n",
+ "\n",
+ " for n in st.nodes():\n",
+ " degrees.append(st.out_degree(n))\n",
+ "\n",
+ " if n != archetype:\n",
+ " father = list(st.predecessors(n))[0]\n",
+ " if st.nodes[n]['state'] and st.nodes[father]['state']:\n",
+ " direct_filiation_nb +=1\n",
+ " if st.nodes[n]['state']:\n",
+ " birth_times_trad.append(st.nodes[n]['birth_time'])\n",
+ " arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))\n",
+ " \n",
+ " timelapse = int(max(birth_times_trad)-min(birth_times_trad))\n",
+ " deg_dist = Counter(degrees)\n",
+ " deg1 = deg_dist[1]\n",
+ " deg2 = deg_dist[2]\n",
+ " deg3 = deg_dist[3]\n",
+ " deg4 = deg_dist[4]\n",
+ " depth = max(arch_dists)\n",
+ " n_nodes = len(list(st.nodes()))\n",
+ "\n",
+ " return [\n",
+ " n_living,\n",
+ " timelapse,\n",
+ " n_nodes,\n",
+ " direct_filiation_nb,\n",
+ " deg1,\n",
+ " deg2,\n",
+ " deg3,\n",
+ " deg4,\n",
+ " depth\n",
+ " ]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "58e884b3",
+ "metadata": {},
+ "source": [
+ "# 2) Prepare empirical data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ebc39063",
+ "metadata": {},
+ "source": [
+ "In this section we compute the summary statistics used for inference from the empirical data. These data are extracted from two different sources:\n",
+ "+ The OpenStemmata database\n",
+ "+ the table Old_French_witnesses for tradition consisting of less than 3 witnesses\n",
+ "\n",
+ "these computation are essentially similar to those found in the analysis notebook"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4f78071a",
+ "metadata": {},
+ "source": [
+ "## a) From OpenStemmata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "3ab2ae0d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Rochebouet_2021_RTroieProse5-2\n",
+ "Tyssens_1967_CharroiNimes\n",
+ "Rolin_1897_Aliscans1-Guillaume\n",
+ "Eusebi_1963_ChevOgierDanemarche\n",
+ "Zorn_1908_EnfViv\n",
+ "Tyssens_1967_PriseOrange\n",
+ "Alton_1889_MarquesRome\n",
+ "Karsch_1907_Gaydon\n",
+ "Ponceau_1997c_SaintGraal\n",
+ "Hult_2004_Charrette\n",
+ "Ruelle_1960_HuonBordeaux\n",
+ "Cloetta_1911_Moniage1\n",
+ "Blanchard_1976_TristanProseV1\n",
+ "Stimming_1920_BeuveHanstCont3-3\n",
+ "Tyssens_1967_MoniageRainouart2\n",
+ "Latour_1976_GuiBourgogne1\n",
+ "Tyssens_1967_ChevVivien\n",
+ "Thorpe_1992_Jerusalem\n",
+ "Sweetser_1964_Blancandin\n",
+ "Tyssens_1967_Guillaume\n",
+ "LeonardiTrachsler_2021_Meliadus1\n",
+ "Herbin_2018a_Anseys\n",
+ "Treutler_1880_Otinel\n",
+ "Gregory_1993_Cliges\n",
+ "Pope_1955_Thomas-Horn\n",
+ "Lagomarsini_2018_GuironCourtois1\n",
+ "Tyssens_1967_CourLouis\n",
+ "Jonin_1958_Yvain\n",
+ "Korte_1914_RenMont6\n",
+ "Ponceau_1997a_SaintGraal\n",
+ "Coco_2016_SeptSages-A\n",
+ "Rolin_1897_Aliscans2-Rainouart\n",
+ "Bedier_1902_Tristan\n",
+ "Myers_1981_Chetifs4\n",
+ "Rochebouet_2021_RTroieProse5-1\n",
+ "Bogdanow_1991_MortArtuPV\n",
+ "Tyssens_1967_EnfGuillaume\n",
+ "Veneziale_2020_Guiron-Cont\n",
+ "Braunholtz_1921_Horn\n",
+ "Myers_1981_Chetifs2\n",
+ "LePerson_2003_Fierabras\n",
+ "Melander_1922_GuibAndr\n",
+ "Terracher_1923_ChevVivien\n",
+ "Wallensköld_1909_Florence\n",
+ "Langlois_1888_CourLouis\n",
+ "Friedwagner_1897_RHoudenc-Meraugis\n",
+ "Suchier_1900_VenjanceNS\n",
+ "Salverda_1888_Eneas\n",
+ "Tyssens_1967_MoniageRainouart1\n",
+ "LeonardiTrachsler_2021_Meliadus2\n",
+ "Loeseth_1890_GautierdArras-Eracle\n",
+ "Constans_1890_Thebes\n",
+ "Tyssens_1967_MoniageGuillaume-RedII\n",
+ "VanEmden_1977_GirViane\n",
+ "Ponceau_1997b_SaintGraal\n",
+ "Hilka_1933_AimonVarennes-Florimont\n",
+ "Barnett_1959_BatailleLoquifer\n",
+ "Stimming_1918_BeuveHanstCont2-3\n",
+ "Cloetta_1911_Moniage2\n",
+ "Henry_1935_EnfGuill\n",
+ "Myers_1981_Chetifs1\n",
+ "Stimming_1918_BeuveHanstCont2-4\n",
+ "Ewert_1932_GuiWarewic\n",
+ "Weidner_1881_JosephArimathieProse\n",
+ "Demaison_1887_Aimeri\n",
+ "Korte_1914_RenMont3\n",
+ "Myers_1981_Chetifs3\n",
+ "Saly_1990_GirartdAmiens-Meliacin\n",
+ "Stengel_1882_GarinMonglane\n",
+ "Stimming_1920_BeuveHanstCont3-5\n",
+ "Leonardi_2003_MortArtu\n",
+ "Stimming_1918_BeuveHanstCont2-2\n",
+ "Stimming_1918_BeuveHanstCont2-1\n",
+ "Nelson_1985_NaissanceChevCygne\n",
+ "Brodtkorb_1965_Pelyarmenus\n",
+ "Tyssens_1967_EnfVivien\n",
+ "Salverda_1891_Eneas\n",
+ "Stimming_1920_BeuveHanstCont3-4\n",
+ "Koelbing_1884_AmisAmiloun\n",
+ "Korte_1914_RenMont4\n",
+ "Korte_1914_RenMont5\n",
+ "Tyssens_1967_BatailleLoquifer2\n",
+ "Stimming_1920_BeuveHanstCont3-2\n",
+ "Bogdanow_1991_QuesteTr\n",
+ "Grillo_1984_ChretienteCorbaran\n",
+ "Bogdanow_1991_QuestePV\n",
+ "Palumbo_2013_Aspremont\n",
+ "Nelson_1985_FinElias\n",
+ "Korte_1914_RenMont1\n",
+ "Latour_1976_GuiBourgogne2\n",
+ "LeonardiTrachsler_2015_GuironCourtois1\n",
+ "Constans_1912_BSteMaure-RTroie\n",
+ "Lewis_1915_ApolloniusTyrII\n",
+ "Korte_1914_RenMont2\n",
+ "LeonardiTrachsler_2015_Meliadus1\n",
+ "Niedzielski_1966_Helcanus\n",
+ "LeonardiTrachsler_2015_GuironCourtois2\n",
+ "Tyssens_1967_BatailleLoquifer1\n",
+ "Lagomarsini_2018_GuironCourtois2\n",
+ "Kerr_1994_AnseisCarthage\n",
+ "Vietor_1876_Loherains\n",
+ "CourayeduParc_1884_MortAimeri\n",
+ "Herbin_2018b_Anseys\n",
+ "Gundlach_1883_SiegeBarbastre\n",
+ "Nelson_1985_ChevCygne\n",
+ "Bogdanow_1960_SuiteMerlin\n",
+ "Segre_1971_Roland\n"
+ ]
+ }
+ ],
+ "source": [
+ "def convert_date(x):\n",
+ " pattern1 = re.compile('[0-9][0-9][0-9][0-9]')\n",
+ " pattern2 = re.compile('[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')\n",
+ "\n",
+ " if bool(pattern1.fullmatch(x)):\n",
+ " return int(x)\n",
+ " if bool(pattern2.fullmatch(x)):\n",
+ " xx = x.split('-')\n",
+ " return (int(xx[0]),int(xx[1]))\n",
+ "\n",
+ "def top(x):\n",
+ " '''\n",
+ " Upper bound on witness date (single year or range)\n",
+ " '''\n",
+ " match x:\n",
+ " case (x1, x2):\n",
+ " return x2\n",
+ " case _:\n",
+ " return x\n",
+ "\n",
+ "def bottom(x):\n",
+ " '''\n",
+ " Lower bound on witness date (single year or range)\n",
+ " '''\n",
+ " match x:\n",
+ " case (x1, x2):\n",
+ " return x1\n",
+ " case _:\n",
+ " return x\n",
+ "\n",
+ "\n",
+ "def expected_abs_diff_degenerate(c, a, b):\n",
+ " '''\n",
+ " Returns the expectation value of the timelapse between one date given as range\n",
+ " and one other as a single year\n",
+ " '''\n",
+ " if a == b:\n",
+ " return abs(a - c)\n",
+ " if a <= c <= b:\n",
+ " return ((c-a)**2 + (b-c)**2) / (2*(b-a))\n",
+ " elif c < a:\n",
+ " return (a+b)/2 - c\n",
+ " else: \n",
+ " return c - (a+b)/2\n",
+ "\n",
+ "def expected_abs_diff(a, b, c, d):\n",
+ " '''\n",
+ " Return the expectation value of the timelapse between two dates given as\n",
+ " intervals\n",
+ " '''\n",
+ " if a == b:\n",
+ " return expected_abs_diff_degenerate(a, c, d)\n",
+ " if c == d:\n",
+ " return expected_abs_diff_degenerate(c, a, b)\n",
+ " elif a < b < c < d:\n",
+ " return (c+d-b-a)/2\n",
+ " elif a <= c <= d < b:\n",
+ " return (1/(b-a)) * ((1/2)*((d-a)*(c-a)+(b-d)*(b-c)) + (1/3)*(d-c)**2)\n",
+ " elif a <= c <= b <= d:\n",
+ " return (1/(b-a)) * ((1/2)* ((c-a)*(d-a) + (b-c)*(d-b)) + (1/(3*(d-c)))*(b-c)**3 )\n",
+ " else:\n",
+ " print(f\"{a},{b} -- {c},{d} \")\n",
+ " raise ValueError(\"Must have a < b, c < d, and a < c\")\n",
+ "\n",
+ "wholeCorpus = {}\n",
+ "corpus_dates = {}\n",
+ "for work in os.listdir(f'corpus_stemmata/'):\n",
+ " print(f'{work}')\n",
+ " st = bd.load_from_OpenStemmata(f'corpus_stemmata/{work}/stemma.gv')\n",
+ " with open(f\"corpus_stemmata/{work}/metadata.txt\", 'r') as f:\n",
+ " content = f.read()\n",
+ " metadata = yaml.safe_load(content)\n",
+ " if \"wits\" in metadata:\n",
+ " dates = [wit[\"witOrigDate\"] for wit in metadata['wits'] if wit[\"witOrigDate\"] != '']\n",
+ " else:\n",
+ " dates = []\n",
+ "\n",
+ " dates_num = []\n",
+ " for x in dates:\n",
+ " if x != '':\n",
+ " date_num = convert_date(x)\n",
+ " if date_num != None:\n",
+ " dates_num.append(date_num)\n",
+ " \n",
+ " wholeCorpus[f\"{work}\"] = st\n",
+ " corpus_dates[f\"{work}\"] = dates_num\n",
+ "\n",
+ "ranges_per_work = {}\n",
+ "for work, t_dates in corpus_dates.items():\n",
+ " if t_dates != []:\n",
+ " lb = sorted(t_dates, key=bottom)[0]\n",
+ " ub = sorted(t_dates, key=top)[-1]\n",
+ " ranges_per_work[work] = (lb,ub)\n",
+ "\n",
+ "\n",
+ "lifespans = {}\n",
+ "for w,v in ranges_per_work.items():\n",
+ " match v:\n",
+ " case [(a,b), (c,d)]:\n",
+ " lifespans[w] = expected_abs_diff(a,b,c,d)\n",
+ " case [(a,b), c]:\n",
+ " lifespans[w] = expected_abs_diff_degenerate(a,b,c)\n",
+ " case [c,(a,b)]:\n",
+ " lifespans[w] = expected_abs_diff_degenerate(a,b,c)\n",
+ " case [a,b]:\n",
+ " lifespans[w] = abs(a-b)\n",
+ " case _:\n",
+ " print('error')\n",
+ "\n",
+ "x_obs0 = {}\n",
+ "sizes = {}\n",
+ "for k in lifespans.keys():\n",
+ " ## computation of observables\n",
+ " g = wholeCorpus[k]\n",
+ "\n",
+ " n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)\n",
+ " sizes[k] = n_living\n",
+ " degrees = []\n",
+ " direct_filiation_nb = 0\n",
+ " arch_dists = []\n",
+ "\n",
+ " if n_living >= 3:\n",
+ " st = bd.generate_stemma(g)\n",
+ " archetype = bd.root(st)\n",
+ " for n in st.nodes():\n",
+ " degrees.append(st.out_degree(n))\n",
+ "\n",
+ " if n != archetype:\n",
+ " father = list(st.predecessors(n))[0]\n",
+ " if st.nodes[n]['state'] and st.nodes[father]['state']:\n",
+ " direct_filiation_nb +=1\n",
+ " arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))\n",
+ " \n",
+ " timelapse = lifespans[k]\n",
+ " deg_dist = Counter(degrees)\n",
+ " deg1 = deg_dist[1]\n",
+ " deg2 = deg_dist[2]\n",
+ " deg3 = deg_dist[3]\n",
+ " deg4 = deg_dist[4]\n",
+ " depth = max(arch_dists)\n",
+ " n_nodes = len(list(st.nodes()))\n",
+ "\n",
+ " x_obs0[k] = [\n",
+ " n_living,\n",
+ " 4*int(timelapse),\n",
+ " n_nodes,\n",
+ " direct_filiation_nb,\n",
+ " deg1,\n",
+ " deg2,\n",
+ " deg3,\n",
+ " deg4,\n",
+ " depth\n",
+ " ]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ffab4bae",
+ "metadata": {},
+ "source": [
+ "## b) For texts without stemmata (with 1 or 2 witnesses)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "2085670e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df = pd.read_csv(\"Old_French_witnesses.csv\")\n",
+ "f2_works = []\n",
+ "f1_works = []\n",
+ "works = set(list(df['text H-ID']))\n",
+ "size_frags_d = []\n",
+ "size_d = []\n",
+ "for work in works:\n",
+ " n_wit = len(df[(df['text H-ID'] == work) & (df['status'] != 'fragment')])\n",
+ " n_frags = len(df[(df['text H-ID'] == work) & (df['status'] == 'fragment')])\n",
+ " if n_wit !=0:\n",
+ " size_d.append(n_wit)\n",
+ " if n_frags !=0:\n",
+ " size_frags_d.append(n_frags)\n",
+ "\n",
+ " if n_wit == 2:\n",
+ " f2_works.append(work)\n",
+ " if n_wit == 1:\n",
+ " f1_works.append(work)\n",
+ "\n",
+ "size_dist = Counter(size_d)\n",
+ "size_dist_frags = Counter(size_frags_d)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "2af6ad2f",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "f2_dates_0 = [df[(df[\"text H-ID\"] == x) & (df['status'] != 'fragment')][\"Date\"].values.tolist() for x in f2_works]\n",
+ "f2_dates = [list(map(convert_date, x)) for x in f2_dates_0]\n",
+ "\n",
+ "ranges_per_work = []\n",
+ "for t_dates in f2_dates:\n",
+ " if t_dates != []:\n",
+ " lb = sorted(t_dates, key=bottom)[0]\n",
+ " ub = sorted(t_dates, key=top)[-1]\n",
+ " ranges_per_work.append((lb,ub))\n",
+ "\n",
+ "\n",
+ "lifespans_f2 = []\n",
+ "for v in ranges_per_work:\n",
+ " match v:\n",
+ " case [(a,b), (c,d)]:\n",
+ " lifespans_f2.append(expected_abs_diff(a,b,c,d))\n",
+ " case [(a,b), c]:\n",
+ " lifespans_f2.append(expected_abs_diff_degenerate(a,b,c))\n",
+ " case [c,(a,b)]:\n",
+ " lifespans_f2.append(expected_abs_diff_degenerate(a,b,c))\n",
+ " case [a,b]:\n",
+ " lifespans_f2.append(abs(a-b))\n",
+ " case _:\n",
+ " print('error')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "01dd6a7c",
+ "metadata": {},
+ "source": [
+ "The summary statistics extracted from our two database are gathered and shuffled in a list ```x_obs_empirical``` of feature-vectors. The numbers of vectors corresponding to traditions with 1 or 2 witnesses added to the OpenStemmata is chosen so as to ensure that the median and relative proportions of tradition sizes for small tradition are the same as in the larger data corpus (contained in ```Old_French_witnesses.csv```)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "ce05576d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "add_f1 = [[\n",
+ " 1,\n",
+ " 0,\n",
+ " -1,\n",
+ " -1,\n",
+ " -1,\n",
+ " -1,\n",
+ " -1,\n",
+ " -1,\n",
+ " -1] for k in range(61)]\n",
+ "\n",
+ "add_f2 = [[2, int(4 * n), -1,-1,-1,-1,-1,-1,-1] for n in lifespans_f2]\n",
+ "x_obs_empirical = list(x_obs0.values()) + add_f1 + add_f2[:17]\n",
+ "\n",
+ "random.shuffle(x_obs_empirical)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "0627367b",
+ "metadata": {},
+ "source": [
+ "# 3) Simulation based inference --Training Neural Likelihood Estimator"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a3a2348d",
+ "metadata": {},
+ "source": [
+ "In this section we perform the parameter inference using Simulation Based inference and more specifically the Neural Likelihood method as implemented in the ```sbi``` package. We take a uniform prior on a box ```[lambda_minx_prior, lambda_max_prior] * [mu_min_prior, mu_max_prior]```, and generate ```N_samples_prior``` simulations for each setting of the model.\n",
+ "\n",
+ "*Note that pre-trained inference models are available in the ```inference_models``` folder*"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "b23320eb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "lambda_min_prior = 4.*10**(-3)\n",
+ "lambda_max_prior = 9.*10**(-3)\n",
+ "\n",
+ "mu_min_prior = 1.*10**(-3)\n",
+ "mu_max_prior = 5*10**(-3)\n",
+ "\n",
+ "N_samples_prior = 50000 #500000\n",
+ "N_samples_posterior = 1000 #1000"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "07db9bf5",
+ "metadata": {},
+ "source": [
+ "## a) Joint model training"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "e94f8e9e",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "def simulator_base(theta):\n",
+ " '''\n",
+ " Wrapper function for the birth-death simulator\n",
+ " '''\n",
+ " l = theta[0]\n",
+ " m = theta[1]\n",
+ " return bd.generate_tree(l,m,1000,1000)\n",
+ "\n",
+ "def simulator_decay(theta):\n",
+ " '''\n",
+ " Wrapper function for the birth-death simulator\n",
+ " '''\n",
+ " l = theta[0]\n",
+ " m = theta[1]\n",
+ " return bd.generate_tree_bd_decay(l,m,1000,1000)\n",
+ "\n",
+ "def simulator_decim(theta):\n",
+ " l = theta[0]\n",
+ " m = theta[1]\n",
+ " return bd.generate_tree_bd_decim(l,m,1000,1000,500)\n",
+ "\n",
+ "def simulator(theta):\n",
+ " lam, mu, m = theta\n",
+ " m = int(torch.floor(m).item())\n",
+ "\n",
+ " if m == 0:\n",
+ " x = simulator_base([lam, mu])\n",
+ " elif m == 1:\n",
+ " x = simulator_decay([lam, mu])\n",
+ " elif m == 2:\n",
+ " x = simulator_decim([lam, mu])\n",
+ " else:\n",
+ " raise ValueError(\"Invalid model index\")\n",
+ "\n",
+ " return x \n",
+ "\n",
+ "prior_params = BoxUniform(low=Tensor([lambda_min_prior, mu_min_prior]), high=Tensor([lambda_max_prior, mu_max_prior]))\n",
+ "prior_model = BoxUniform(\n",
+ " low=torch.tensor([0.0]),\n",
+ " high=torch.tensor([2.999]) # ensures {0,1,2} after flooring\n",
+ ")\n",
+ "\n",
+ "from sbi.utils import MultipleIndependent\n",
+ "\n",
+ "prior = MultipleIndependent(\n",
+ " [prior_params, prior_model]\n",
+ ")\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "9ca42777-bc5c-45e4-8d4e-d5a66f0f945d",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "2874a2101afc4834a884c7a7e3fd9f07",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/50000 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "theta0 = prior.sample((N_samples_prior,))\n",
+ "\n",
+ "theta = []\n",
+ "x = []\n",
+ "\n",
+ "for t in tqdm(theta0):\n",
+ " vec = compute_summary_stats(simulator(t))\n",
+ " if vec != None:\n",
+ " theta.append(list(t))\n",
+ " x.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "714526c6",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Neural network successfully converged after 218 epochs."
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_112805/2353588036.py:5: UserWarning: When the inference object is pickled, the behaviour of the loaded object changes in the following two ways: 1) `.train(..., retrain_from_scratch=True)` is not supported. 2) When the loaded object calls the `.train()` method, it generates a new tensorboard summary writer (instead of appending to the current one).\n",
+ " pickle.dump(inference, f)\n"
+ ]
+ }
+ ],
+ "source": [
+ "inference = NLE(prior=prior)\n",
+ "inference = inference.append_simulations(Tensor(theta), Tensor(x))\n",
+ "likelihood_estimator = inference.train()\n",
+ "with open(\"pretrained_models/inference_joint.pickle\", \"wb\") as f:\n",
+ " pickle.dump(inference, f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "8e6eac50",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#load pretrained model serialized as pickle object\n",
+ "\n",
+ "#with open(\"pretrained_models/inference_joint.pickle\", \"rb\") as f:\n",
+ "# inference = pickle.load(f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "a9221c7f-de15-463c-8cf1-cae68a512198",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "posterior = inference.build_posterior(sample_with=\"rejection\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "d4ee9dae",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "eeaa288c2e22456e8936b29996089259",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Drawing 1000 posterior samples: 0%| | 0/1000 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "WARNING:root:Only 0.000% proposal samples were accepted. It\n",
+ " may take a long time to collect the remaining 1000\n",
+ " samples. Consider interrupting (Ctrl-C) and switching to a\n",
+ " different sampling method with\n",
+ " `build_posterior(..., sample_with='mcmc')`. or\n",
+ " `build_posterior(..., sample_with='vi')`.\n"
+ ]
+ }
+ ],
+ "source": [
+ "samples = posterior.sample(\n",
+ " (N_samples_posterior,),\n",
+ " x=x_obs_empirical\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "id": "e1161ce1-9390-4513-9cd1-92b5dfc38808",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "tensor([[0.0065, 0.0027, 1.4828],\n",
+ " [0.0067, 0.0027, 1.6090],\n",
+ " [0.0063, 0.0026, 1.5511],\n",
+ " ...,\n",
+ " [0.0067, 0.0028, 1.4875],\n",
+ " [0.0066, 0.0028, 1.5258],\n",
+ " [0.0065, 0.0027, 1.5748]])"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "samples"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "753eb92a",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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6eYEvk0nuv/++7V48WKdc845/cvy8vK0efNmXXHFFXJdV48//riuvvpq7dixQ0uXLh3ehgLAGBtxXIK0du3a/r9fcsklikajWrFihTZs2DDpb7HywQcf6JlnntGjjz46YPn06dMHbPf8+fP14YcfatOmTcQFwIQz4t1i06dPVygUUlNT04DlTU1NKisrG/Q5ZWVlp12/78/hfE1Jqq6uVjqd1qFDh4a7GQNMhG3aunWrpk2bNqRgVFdX6+233z7jegAw3kY8c4lGo6qsrNSuXbt09dVXS5J839euXbu0evXqQZ+zYMEC7dq1S2vWrOlf9uyzz2rBggWSpIqKCpWVlWnXrl267LLLJPW80dYrr7yib3/726ccS319vVzXVUlJyUg3Z0JskzFGW7du1fLlyxWJRM443vr6es2YMWP4GwoE5P+41wQ9BFjwrP/YGdcZ1W6xtWvX6tprr9XnP/95VVVV6Yc//KE6Ozv7D0QvX75c5eXl2rBhgyTpO9/5jhYtWqTNmzdryZIl2r59u/7nf/5HP/3pTyX1vCnZmjVrdNddd+n8889XRUWFbr/9dp199tn9P+xra2v1yiuv6Atf+ILy8/NVW1ur7373u/qrv/orTZ06dTSbE9g29Xn++ed18OBBffOb3zxpXA899JCi0ajmzZsnSfr5z3+uBx54QP/2b/826m0GANtGFZevfvWr+uijj3THHXeosbFRl112mX75y1/2H7x+77335Lqf7Hm7/PLL9fDDD2vdunX63ve+p/PPP187duzQxRdf3L/O3/7t36qzs1Pf+ta31NLSooULF+qXv/ylcnJyJPXcvn779u36+7//e3V3d6uiokLf/e53BxyPmGzb1Of+++/X5ZdfrosuumjQsf3jP/6j3n33XYXDYV100UX62c9+pr/4i7+wst0AYBO33AcwbtgtlhmGsluMe4sBAKwjLgAA64gL0OuNhlbNvvUXeqOhNeihAJMecQF69UWFuACjR1wAANYRFwCAdcQFAGAdcQEAWEdcJN16662KxWL62te+FvRQACAjEBdJt912mzZv3qxHHnmEuwwDgAXERT3vDHn99dfLdV29/vrrQQ8HACY94tIrnU5rypQpeuONN4IeCgBMesSl17p169TR0UFcAMAC4iKprq5O9913n5YsWUJcAMCCrI+L7/tasWKFVq9ereXLl+vAgQNK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OuICALCOuAAArCMumNC2bNmi2bNnKycnR9XV1dqzZ89p13/sscd00UUXKScnR3PnztVTTz014HFjjO644w7NmDFD8XhcNTU1OnDgQP/jhw4d0vXXX6+KigrF43F95jOf0fr165VMJges4zjOSR8vv/yy3Y0fgfF+vSRp9uzZJ70WGzdutL5tmGQMMEFt377dRKNR88ADD5jf/va35oYbbjBFRUWmqalp0PVffPFFEwqFzN13323efPNNs27dOhOJRMzrr7/ev87GjRtNYWGh2bFjh9m7d69ZunSpqaioMIlEwhhjzNNPP22uu+4688wzz5h33nnH7Ny505SUlJibb765/2scPHjQSDLPPfecOXz4cP9HMpkc2xfkDIJ4vYwxZtasWebOO+8c8Fp0dHSM+fZiYiMumLCqqqrMqlWr+j/3PM+cffbZZsOGDYOu/5WvfMUsWbJkwLLq6mqzYsUKY4wxvu+bsrIys2nTpv7HW1paTCwWM4888sgpx3H33XebioqK/s/74vLaa6+NZLPGTFCv16xZs8w999xjcUuQCdgthgkpmUyqrq5ONTU1/ctc11VNTY1qa2sHfU5tbe2A9SVp8eLF/esfPHhQjY2NA9YpLCxUdXX1Kb+m1HOH4OLi4pOWL126VCUlJVq4cKGeeOKJYW2fbUG/Xhs3btS0adM0b948bdq0Sel02tamYZLixpWYkI4ePSrP81RaWjpgeWlpqd56661Bn9PY2Djo+o2Njf2P9y071Tqf9vbbb+vee+/V97///f5leXl52rx5s6644gq5rqvHH39cV199tXbs2KGlS5cOb0MtCfL1uummm/S5z31OxcXFeumll3Tbbbfp8OHD+sEPfjDq7cLkRVyAU2hoaNCXvvQlXXPNNbrhhhv6l0+fPl1r167t/3z+/Pn68MMPtWnTpsDiEqQTX4tLLrlE0WhUK1as0IYNG7iVTBZjtxgmpOnTpysUCqmpqWnA8qamJpWVlQ36nLKystOu3/fnUL7mhx9+qC984Qu6/PLL9dOf/vSM462urtbbb799xvXGStCv14mqq6uVTqd16NCh4W4GMghxwYQUjUZVWVmpXbt29S/zfV+7du3SggULBn3OggULBqwvSc8++2z/+hUVFSorKxuwTltbm1555ZUBX7OhoUFXXnmlKisrtXXrVrnumf+Z1NfXa8aMGcPaRpuC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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "_ = pairplot(\n",
+ " samples,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [0,3]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"model\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "746d67b9",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_112805/245841850.py:4: UserWarning: \n",
+ "\n",
+ "`distplot` is a deprecated function and will be removed in seaborn v0.14.0.\n",
+ "\n",
+ "Please adapt your code to use either `displot` (a figure-level function with\n",
+ "similar flexibility) or `histplot` (an axes-level function for histograms).\n",
+ "\n",
+ "For a guide to updating your code to use the new functions, please see\n",
+ "https://gist.github.com/mwaskom/de44147ed2974457ad6372750bbe5751\n",
+ "\n",
+ " sns.distplot(df_samples['model'], hist=True, kde=True,\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "df_samples = pd.DataFrame({'lambda':[x[0] for x in samples.tolist()], 'mu':[x[1] for x in samples.tolist()], 'model':[x[2] for x in samples.tolist()]})\n",
+ "#sns.kdeplot(data=df_samples, x='lambda', y='mu', fill=True)\n",
+ "#sns.kdeplot(data=df_samples, x='lambda', y='model', fill=True)\n",
+ "sns.distplot(df_samples['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "e0fe7b64-c1f2-4419-b8ae-7ca9217062c7",
+ "metadata": {},
+ "source": [
+ "## b) Model checks\n",
+ "Here, we simulate traditions for each model, and look at the model ability to distinguish them."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "31dc3731-9547-4920-8b86-4a20834f31c5",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True m: 0\n",
+ "p(m | x, λ, μ): tensor([0.2270, 0.3167, 0.4563])\n",
+ "True m: 1\n",
+ "p(m | x, λ, μ): tensor([0.2663, 0.3548, 0.3789])\n",
+ "True m: 2\n",
+ "p(m | x, λ, μ): tensor([0.2270, 0.3167, 0.4563])\n"
+ ]
+ }
+ ],
+ "source": [
+ "def p_m_given_x_lambda_mu(x_obs, lam, mu):\n",
+ " x_obs = torch.as_tensor(x_obs, dtype=torch.float32)\n",
+ "\n",
+ " # Ensure (num_trials, x_dim)\n",
+ " if x_obs.ndim == 1:\n",
+ " x_obs = x_obs.unsqueeze(0)\n",
+ "\n",
+ " # Expand to (num_trials, batch=3, x_dim)\n",
+ " x_obs = x_obs.unsqueeze(1).repeat(1, 3, 1)\n",
+ "\n",
+ " theta = torch.tensor(\n",
+ " [\n",
+ " [lam, mu, 0.0],\n",
+ " [lam, mu, 1.0],\n",
+ " [lam, mu, 2.0],\n",
+ " ],\n",
+ " dtype=torch.float32,\n",
+ " )\n",
+ "\n",
+ " with torch.no_grad():\n",
+ " log_lik = likelihood_estimator.log_prob(x_obs, theta)\n",
+ "\n",
+ " return torch.softmax(log_lik, dim=1).squeeze(0)\n",
+ " \n",
+ "lam_star = 0.006\n",
+ "mu_star = 0.0025\n",
+ "\n",
+ "for true_m in [0, 1, 2]:\n",
+ " theta_test = torch.tensor([lam_star, mu_star, float(true_m)])\n",
+ "\n",
+ " x_test = None\n",
+ " while x_test is None:\n",
+ " x_test = compute_summary_stats(simulator(theta_test))\n",
+ "\n",
+ " probs = p_m_given_x_lambda_mu(x_test, lam_star, mu_star)\n",
+ "\n",
+ " print(\"True m:\", true_m)\n",
+ " print(\"p(m | x, λ, μ):\", probs)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "8c590d97-17f6-478b-8171-8adb39a83ede",
+ "metadata": {},
+ "source": [
+ "### Base"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "64d6cb9a-1aaa-4366-bc88-6a30cbc2708c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "theta0_base = prior.sample((10_000,))\n",
+ "\n",
+ "theta_base = []\n",
+ "x_base = []\n",
+ "\n",
+ "for t in tqdm(theta0_base):\n",
+ " vec = compute_summary_stats(simulator_base(t))\n",
+ " if vec != None:\n",
+ " theta_base.append(list(t))\n",
+ " x_base.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "27007793-8999-4caf-bca7-f348ea3c8f5e",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "samples_base = posterior.sample((N_samples_posterior,), x=x_base)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "086f683d-fbf9-445f-8e9a-cefbd3faa6a6",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_ = pairplot(\n",
+ " samples_base,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [0,3]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"model\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "401a2bc0-e174-4606-9324-67c2c2ba59e0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df_samples_base = pd.DataFrame({'lambda':[x[0] for x in samples_base.tolist()], 'mu':[x[1] for x in samples_base.tolist()], 'model':[x[2] for x in samples_base.tolist()]})\n",
+ "sns.distplot(df_samples_base['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "6e34a3a8-383a-4a71-903b-9ebc79614eff",
+ "metadata": {},
+ "source": [
+ "### Decay"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "8d0554a3-2414-49d0-83ac-d07da943d26f",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Neural network successfully converged after 68 epochs."
+ ]
+ }
+ ],
+ "source": [
+ "#with open(\"pretrained_models/inference_joint.pickle\", \"rb\") as f:\n",
+ "# inference = pickle.load(f)\n",
+ "#posterior = inference.build_posterior(sample_with=\"rejection\")\n",
+ "#likelihood_estimator = inference.train()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "65d53b04-26d4-42da-94e4-ae71f3051214",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "a8b44246b96441c793966879a1156776",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/10000 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "theta0_decay = prior.sample((10_000,))\n",
+ "\n",
+ "theta_decay = []\n",
+ "x_decay = []\n",
+ "\n",
+ "for t in tqdm(theta0_decay):\n",
+ " vec = compute_summary_stats(simulator_decay(t))\n",
+ " if vec != None:\n",
+ " theta_decay.append(list(t))\n",
+ " x_decay.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c5b293f8-92bc-4564-ad8e-696dc443c596",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "samples_decay = posterior.sample((N_samples_posterior,), x=x_decay)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ce2f0ccf-8684-4a7b-8855-cbe551c6dec0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_ = pairplot(\n",
+ " samples_decay,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [0,3]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"model\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "0bf5b321-21c0-4eef-8552-56ca99065fbe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df_samples_decay = pd.DataFrame({'lambda':[x[0] for x in samples_decay.tolist()], 'mu':[x[1] for x in samples_decay.tolist()], 'model':[x[2] for x in samples_decay.tolist()]})\n",
+ "sns.distplot(df_samples_decay['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "86ae8575-bb00-45fa-bc1e-97deef1eb607",
+ "metadata": {},
+ "source": [
+ "### Decimation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "id": "3a4bdda9",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "cbe9907142734d4ca8091b72608dbc6f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ " 0%| | 0/10000 [00:00, ?it/s]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "theta0_decim = prior.sample((10_000,))\n",
+ "\n",
+ "theta_decim = []\n",
+ "x_decim = []\n",
+ "\n",
+ "for t in tqdm(theta0_decim):\n",
+ " vec = compute_summary_stats(simulator_decim(t))\n",
+ " if vec != None:\n",
+ " theta_decim.append(list(t))\n",
+ " x_decim.append(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "45eb1c6c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "samples_decim = posterior.sample((N_samples_posterior,), x=x_decim)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "id": "c3344ecf-66ea-494d-b3d5-f068aa38e84f",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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TmzXNOC5557T1q1b9Y1vfOMz5XrggQeUTCZ1zjnnSJJ+8pOf6L777tO//Mu/HPM1A0DUjilcLrvsMn388cf63ve+p46ODs2cOVM///nPS53Xv/nNb+Q4+1rezj33XD344IO65ZZb9N3vflennnqqHn/8cZ155pmlc/76r/9afX19+uY3v6muri6df/75+vnPf66qqipJheXr165dq7/9279VNpvVtGnT9J3vfGdQf8RIu6YB9957r84991ydccYZByzb3//93+uDDz6Q53k644wz9PDDD+vP/uzPIrluAIgSS+4DGDY0i40OR9IsxtpiAIDIES6IRXtXRu1dmbiLAaBMCBcMu/aujFpXrlfryvUEDDBKES4Ydp19OWXygTL5QJ19ubiLA6AMCBcAQOQIFwBA5AgXAEDkCBcAQOQIF0k33XSTUqmUvvrVr8ZdFAAYFQgXSTfffLNWrlyphx56iFWGASAChIsKO0NeeeWVchxHr7/+etzFAYARj3Ap8n1f48aN0+bNm+MuCgCMeIRL0S233KLe3l7CBQAiQLhIamtr06pVq3TxxRcTLgAQgTEfLmEYatGiRbrmmmu0cOFCvfvuu8rn83EXCwBGtDEfLnfffbd27dql2267TTNmzFA+n9fbb78dd7FGtd2sJwaMemM6XNrb23XrrbfqnnvuUXV1tU499VSlUimaxsqovSujxWva4i4GgDIb0+Fy3XXX6Q//8A918cUXS5I8z9P06dMJlzIaWBH5xotOj7soAMrIi7sAcfnpT3+q5557Tm+99dag4zNmzCBchsHE6mTcRQBQRmM2XL785S+rs7PzM8f/9V//NYbSAMDoMqabxRA/OveB0YlwQSzGVyeVTrhavKaNrY6BUYhwQSyaG9JatWAWWx0DoxThgtjQqQ+MXoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKECwAgcoQLACByhAsAIHKEC4bVbrY0BsYEwgXDpr0ro8Vr2pROuBrPFsfAqEa4YNh09uWUyQdatWCWmhvScRcHQBkRLhh2E6m1AKMe4QIAiBzhAgCIHOGC2DGCDBh9CBfEZnx1UumEq8Vr2tTelYm7OAAiRLggNs0Naa1aMEuZfKBOai/AqEK4IFaMHANGJ8IF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6qDfec0112jDhg1au3atfvWrX+nSSy/Vl770Jb377rvDffnlYwFgjJo3b549//zzS9/7vm+rq6vtggULSse2b99uJdkNGzbY7373u/b000+3YRiW7r/nnntsTU2NDYLA9vT02GQyaR955JHS/bt377bpdNp++9vfttZa+8EHH1jXdW17e/ugslx44YX25ptvttZau3r1altfX1+GKx4+bBYGYEw766yzSl+7rquJEydqxowZpWOTJ0+WJO3cuVNvvfWW5s6dO2jflfPOO0+9vb368MMP1dnZqVwuN2ivmgkTJuj0008vff/6668rCAKddtppg8qRzWY1ceLEyK8vLoQLgDEtkUgM+t4YM+jYQJCEYRjJ7+vt7ZXrumpra5PruoPuq6mpieR3VALCBQCO0PTp0/XYY4/JWlsKnRdeeEG1tbU64YQTNGHCBCUSCb388ss66aSTJEmdnZ36n//5H82bN0+SdM455ygIAu3cuVO/93u/F9u1lBsd+gBwhP7yL/9S27Zt07XXXqu3335bTzzxhJYuXarrr79ejuOopqZGV155pW688UY999xz2rx5s6644go5zr632tNOO01//ud/roULF+onP/mJtm7dqldeeUXLli3Tz372sxivLlrUXADgCDU3N+upp57SjTfeqLPPPlsTJkzQlVdeqVtuuaV0zooVK9Tb26s//uM/Vm1trW644QZ1d3cP+jmrV6/W7bffrhtuuEHt7e2aNGmSfvd3f1df/vKXh/uSysZYa23chQAAjC40iwEAIke4AAAiR7gAACJHuAAAIke4AAAiR7gAACJHuAAAIke4AAAiR7gAACJHuAAAIke4AAAiR7gAACL3/wEaQLt2kYZ0yQAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "_ = pairplot(\n",
+ " samples_decim,\n",
+ " limits=[[lambda_min_prior, lambda_max_prior], [mu_min_prior, mu_max_prior], [0,3]],\n",
+ " figsize=(5, 5),\n",
+ " labels=[r\"$\\lambda$\", r\"$\\mu$\", r\"model\"]\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "cabb8a5c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/tmp/ipykernel_112805/1195207057.py:2: UserWarning: \n",
+ "\n",
+ "`distplot` is a deprecated function and will be removed in seaborn v0.14.0.\n",
+ "\n",
+ "Please adapt your code to use either `displot` (a figure-level function with\n",
+ "similar flexibility) or `histplot` (an axes-level function for histograms).\n",
+ "\n",
+ "For a guide to updating your code to use the new functions, please see\n",
+ "https://gist.github.com/mwaskom/de44147ed2974457ad6372750bbe5751\n",
+ "\n",
+ " sns.distplot(df_samples_decim['model'], hist=True, kde=True,\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 30,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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M5pjxcaNGy2n02mtW7fO+vjjj6077rjDysrKsqqrqy3Lsqzvfve71r333tt7/TvvvGMlJCRY//qv/2p98skn1v33328lJiZaZWVloXoLATHYz+UnP/mJ9cYbb1iHDh2ydu3aZX3729+2kpOTrY8++ihUbyEgmpubrT179lh79uyxJFkPPfSQtWfPHqu8vNyyLMu69957re9+97u91x8+fNhKTU21Vq5caX3yySfWo48+asXHx1uvv/56qN5CQAz2c1m9erX14osvWp9//rlVVlZm3XXXXVZcXJz1hz/8IVRvISC+//3vW5mZmdaWLVusqqqq3ltra2vvNbH4O2Yon0us/I659957ra1bt1pHjhyx9u3bZ917772Ww+Gw3nzzTcuyIv/7QrgJon//93+3xo4dayUlJVmzZs2y3n333d775s6day1ZsqTP9b/73e+sc88910pKSrIuuOAC65VXXglyxcExmM9l+fLlvdfm5+db11xzjbV79+4QVB1YPUuYz7z1fBZLliyx5s6da3vMtGnTrKSkJOucc86x1q5dG/S6A22wn8svfvELa+LEiVZycrKVk5NjzZs3z3rrrbdCU3wAmT4TSX2+A7H4O2Yon0us/I7527/9W2vcuHFWUlKSNXLkSOvrX/96b7CxrMj/vjgsy7KC108EAAAQWMy5AQAAUYVwAwAAogrhBgAARBXCDQAAiCqEGwAAEFUINwAAIKoQbgAAQFQh3AAAgKhCuAEQE+bNm6fly5cP+Pp169YpKysrYPUACBzCDQAAiCqEGwAAEFUINwBCat68efrBD36g5cuXKzs7W/n5+fqP//gPtbS06JZbblF6eromTZqk1157rfcxW7du1axZs+R0OlVYWKh7771X3d3dvfe3tLRo8eLFcrlcKiws1IMPPmh73Y6ODt19990aPXq00tLSNHv2bG3ZsiUYbxlAgBFuAITcf/7nf2rEiBF6//339YMf/EDf//73ddNNN2nOnDnavXu3rrzySn33u99Va2urjh07pmuuuUYzZ87Uhx9+qMcee0y/+c1v9M///M+9z7dy5Upt3bpVL730kt58801t2bJFu3fv7vOay5Yt044dO7Rx40bt27dPN910k6666ip9/vnnwX77APyMU8EBhNS8efPk8Xj0xz/+UZLk8XiUmZmpG2+8UevXr5ckVVdXq7CwUDt27ND//M//6LnnntMnn3wih8MhSfr1r3+tf/iHf1BjY6NaW1uVm5urp59+WjfddJMkqb6+XmPGjNEdd9yhhx9+WBUVFTrnnHNUUVGhUaNG9dYyf/58zZo1S//yL/+idevWafny5WpoaAjuBwJg2BJCXQAAXHzxxb3/HR8fr9zcXF100UW9bfn5+ZKkEydO6JNPPlFJSUlvsJGkyy+/XG63W0ePHtWpU6fU2dmp2bNn996fk5Oj4uLi3p/Lysrk8Xh07rnn9qmjo6NDubm5fn9/AIKLcAMg5BITE/v87HA4+rT1BBmv1+uX13O73YqPj9euXbsUHx/f5z6Xy+WX1wAQOoQbABHl/PPP13PPPSfLsnpDzzvvvKP09HSNGTNGOTk5SkxM1HvvvaexY8dKkk6dOqXPPvtMc+fOlSRNnz5dHo9HJ06c0J//+Z+H7L0ACAwmFAOIKH/3d3+nyspK/eAHP9Cnn36ql156Sffff79WrFihuLg4uVwu3XrrrVq5cqXeeust7d+/XzfffLPi4r78dXfuuefqb/7mb7R48WI9//zzOnLkiN5//32VlpbqlVdeCeG7A+AP9NwAiCijR4/Wq6++qpUrV2rq1KnKycnRrbfeqh//+Me91/zyl7+U2+3Wtddeq/T0dP3whz9UY2Njn+dZu3at/vmf/1k//OEPdezYMY0YMUKXXXaZ/uqv/irYbwmAn7FaCgAARBWGpQAAQFQh3AAAgKhCuAEAAFGFcAMAAKIK4QYAAEQVwg0AAIgqhBsAABBVCDcAACCqEG4AAEBUIdwAAICoQrgBAABR5f8DnMKMTSJkrWMAAAAASUVORK5CYII=",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "df_samples_decim = pd.DataFrame({'lambda':[x[0] for x in samples_decim.tolist()], 'mu':[x[1] for x in samples_decim.tolist()], 'model':[x[2] for x in samples_decim.tolist()]})\n",
+ "sns.distplot(df_samples_decim['model'], hist=True, kde=True, \n",
+ " bins=int(180/5), color = 'darkblue', \n",
+ " hist_kws={'edgecolor':'black'},\n",
+ " kde_kws={'linewidth': 4})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b1fd4857-27e0-498b-aed9-bbc9f06bab45",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.12"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/train_model.py b/train_model.py
new file mode 100644
index 00000000..b63e6635
--- /dev/null
+++ b/train_model.py
@@ -0,0 +1,181 @@
+import random
+import torch
+import numpy as np
+import matplotlib.pyplot as plt
+import networkx as nx
+import birth_death_utils as bd
+import os
+from collections import Counter
+from tqdm import tqdm
+import pickle
+from itertools import groupby
+import pandas as pd
+import yaml
+import re
+import multiprocessing as mp
+import seaborn as sns
+
+from sbi.analysis import pairplot
+from sbi.inference import NPE, simulate_for_sbi, NLE
+from sbi.utils import BoxUniform
+
+from sbi.utils.user_input_checks import (
+ check_sbi_inputs,
+ process_prior,
+ process_simulator,
+)
+
+from torch import Tensor
+
+import multiprocessing
+
+def compute_summary_stats(g):
+ """
+ Generate a vector of summary statistics from a graph generated by birth-death simulation
+
+ Parameters
+ ----------
+ g : nx.DiGraph()
+ tree graph generated by birth_death_utils.ct_bd_tree
+
+ Returns
+ -------
+ list
+ vector of summary statistics characterizing a single tradition
+ """
+ n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)
+
+ if n_living == 0:
+ return None
+
+ if n_living == 1:
+ return [1,0, -1,-1,-1,-1,-1,-1,-1]
+
+ if n_living == 2:
+ birth_times_trad = []
+ for n in g.nodes():
+ if g.nodes[n]['state']:
+ birth_times_trad.append(g.nodes[n]['birth_time'])
+ timelapse = int(max(birth_times_trad)-min(birth_times_trad))
+ return [2, timelapse, -1,-1,-1,-1,-1,-1,-1]
+
+ if n_living >= 3:
+ birth_times_trad = []
+ degrees = []
+ direct_filiation_nb = 0
+ arch_dists = []
+ st = bd.generate_stemma(g)
+ archetype = bd.root(st)
+
+ for n in st.nodes():
+ degrees.append(st.out_degree(n))
+
+ if n != archetype:
+ father = list(st.predecessors(n))[0]
+ if st.nodes[n]['state'] and st.nodes[father]['state']:
+ direct_filiation_nb +=1
+ if st.nodes[n]['state']:
+ birth_times_trad.append(st.nodes[n]['birth_time'])
+ arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))
+
+ timelapse = int(max(birth_times_trad)-min(birth_times_trad))
+ deg_dist = Counter(degrees)
+ deg1 = deg_dist[1]
+ deg2 = deg_dist[2]
+ deg3 = deg_dist[3]
+ deg4 = deg_dist[4]
+ depth = max(arch_dists)
+ n_nodes = len(list(st.nodes()))
+
+ return [
+ n_living,
+ timelapse,
+ n_nodes,
+ direct_filiation_nb,
+ deg1,
+ deg2,
+ deg3,
+ deg4,
+ depth
+ ]
+
+lambda_min_prior = 4.*10**(-3)
+lambda_max_prior = 9.*10**(-3)
+
+mu_min_prior = 1.*10**(-3)
+mu_max_prior = 5*10**(-3)
+
+decay_min_prior = 0
+decay_max_prior = 1
+
+decimation_min_prior = 0
+decimation_max_prior = 1
+
+N_samples_prior = 500_000 #500000
+N_samples_posterior = 100 #1000
+
+def simulator(theta):
+ lda0, mu, decay, decim = theta
+ g = bd.generate_tree_unified(lda0, mu, decay, decim, 1000, 1000, 500)
+
+ return g
+
+prior = BoxUniform(low=Tensor([lambda_min_prior, mu_min_prior, decay_min_prior, decimation_min_prior]),
+ high=Tensor([lambda_max_prior, mu_max_prior, decay_max_prior, decimation_max_prior]))
+
+theta0 = prior.sample((N_samples_prior,))
+
+theta = []
+x = []
+
+#for t in tqdm(theta0):
+# vec = compute_summary_stats(simulator(t))
+# if vec != None:
+# theta.append(list(t))
+# x.append(vec)
+
+def process_theta(t):
+ """
+ Helper function to process a single theta sample.
+ """
+ G = simulator(t)
+ vec = compute_summary_stats(G)
+ if vec is not None:
+ return (list(t), vec)
+ else:
+ return None
+
+def parallel_simulate(theta0, n_processes=None):
+ """
+ Parallelize the simulation and summary statistics computation.
+
+ Args:
+ theta0: Tensor of shape (N_samples_prior, 4)
+ n_processes: Number of processes to use (default: all available cores)
+
+ Returns:
+ theta, x: Lists of valid theta and summary statistics
+ """
+ if n_processes is None:
+ n_processes = multiprocessing.cpu_count()
+
+ with multiprocessing.Pool(n_processes) as pool:
+ results = list(tqdm(pool.imap(process_theta, theta0), total=len(theta0)))
+
+ # Filter out None results
+ valid_results = [r for r in results if r is not None]
+ theta, x = zip(*valid_results) if valid_results else ([], [])
+
+ return list(theta), list(x)
+
+# Example usage:
+theta, x = parallel_simulate(theta0, n_processes=7)
+theta = torch.tensor(theta, dtype=torch.float32)
+x = torch.tensor(x, dtype=torch.float32)
+
+inference = NLE(prior=prior)
+inference = inference.append_simulations(Tensor(theta), Tensor(x))
+likelihood_estimator = inference.train()
+with open("pretrained_models/inference_unif_run3.pickle", "wb") as f:
+ pickle.dump(inference, f)
+
diff --git a/train_model_benchmark.py b/train_model_benchmark.py
new file mode 100644
index 00000000..67d9395a
--- /dev/null
+++ b/train_model_benchmark.py
@@ -0,0 +1,415 @@
+import random
+import torch
+import numpy as np
+import matplotlib.pyplot as plt
+import networkx as nx
+import birth_death_utils as bd
+import os
+from collections import Counter
+from tqdm import tqdm
+import pickle
+from itertools import groupby
+import pandas as pd
+import yaml
+import re
+import multiprocessing as mp
+import seaborn as sns
+
+from sbi.analysis import pairplot
+from sbi.inference import NPE, simulate_for_sbi, NLE
+from sbi.utils import BoxUniform
+
+from sbi.utils.user_input_checks import (
+ check_sbi_inputs,
+ process_prior,
+ process_simulator,
+)
+
+from torch import Tensor
+
+import multiprocessing
+
+evaluate_on_data = True
+num_workers = 11
+load_models = False
+debug = False
+# Set random seeds for reproducibility
+random.seed(42)
+np.random.seed(42)
+torch.manual_seed(42)
+
+max_num_epochs=20
+
+
+#### Now importing the data
+if evaluate_on_data:
+
+ wholeCorpus = {}
+ corpus_dates = {}
+ corpus_workdates = {}
+
+ for work in os.listdir(f'corpus_stemmata/'):
+ #print(f'{work}')
+ st = bd.load_from_OpenStemmata(f'corpus_stemmata/{work}/stemma.gv')
+ with open(f"corpus_stemmata/{work}/metadata.txt", 'r') as f:
+ content = f.read()
+ metadata = yaml.safe_load(content)
+ if "wits" in metadata:
+ dates = [wit["witOrigDate"] for wit in metadata['wits'] if wit["witOrigDate"] != '']
+ missing_dates = [wit for wit in metadata['wits'] if wit["witOrigDate"] == '']
+ if missing_dates != []:
+ print(f"missing witnesses dates in {work}")
+ else:
+ print(f"no witnesses in {work}")
+ dates = []
+
+ if "workOrigDate" in metadata and metadata["workOrigDate"] != '':
+ workDate = bd.convert_date(metadata["workOrigDate"])
+
+ else:
+ print(f"missing work date in {work}")
+ workDate = ''
+
+ dates_num = []
+ for x in dates:
+ if x != '':
+ date_num = bd.convert_date(x)
+ if date_num != None:
+ dates_num.append(date_num)
+
+ wholeCorpus[f"{work}"] = st
+ corpus_dates[f"{work}"] = dates_num
+ corpus_workdates[f"{work}"] = workDate
+
+ #ranges_per_work = {}
+ lifespans = {}
+ earliest_wit = {}
+ median_wit = {}
+ latest_wit = {}
+ sizes = {}
+ x_obs0 = {}
+
+ for work, t_dates in corpus_dates.items():
+ if debug:
+ print(f"now dating {work}")
+ ## Now, convert all dates in time from original work
+ if t_dates and corpus_workdates[work]:
+ work_date = corpus_workdates[work]
+ relative_dates = []
+ for date in t_dates:
+ if debug:
+ print(f"work_date: {work_date}, date: {date}")
+ # Calculate the relative date difference
+ match (work_date, date):
+ case ((a, b), (c, d)):
+ if c <= a: # deal with the case of the range of a witness starts before the range of a work (should not happen, but, hey, approximate datings)
+ c = a+1
+ relative_dates.append(bd.expected_abs_diff(a, b, c, d))
+ case ((a, b), c):
+ relative_dates.append(bd.expected_abs_diff_degenerate(a, b, c))
+ case (c, (a, b)):
+ relative_dates.append(bd.expected_abs_diff_degenerate(a, b, c))
+ case (a, b):
+ relative_dates.append(abs(a - b))
+ case _:
+ print(f'Error: Unexpected date format for work {work}, date {date}, work_date {work_date}')
+
+ corpus_dates[work] = relative_dates
+
+ # now, get stemmatic properties
+ g = wholeCorpus[work]
+
+ n_living = list(nx.get_node_attributes(g, 'state').values()).count(True)
+ sizes[work] = n_living
+ degrees = []
+ direct_filiation_nb = 0
+ arch_dists = []
+
+ if n_living >= 3:
+ st = bd.generate_stemma(g)
+ archetype = bd.root(st)
+ for n in st.nodes():
+ degrees.append(st.out_degree(n))
+
+ if n != archetype:
+ father = list(st.predecessors(n))[0]
+ if st.nodes[n]['state'] and st.nodes[father]['state']:
+ direct_filiation_nb +=1
+ arch_dists.append(len(nx.shortest_path(st, source=archetype, target=n)))
+
+ deg_dist = Counter(degrees)
+ deg1 = deg_dist[1]
+ deg2 = deg_dist[2]
+ deg3 = deg_dist[3]
+ deg4 = deg_dist[4]
+ depth = max(arch_dists)
+ n_nodes = len(list(st.nodes()))
+
+ x_obs0[work] = [
+ n_living,
+ 4*int(max(corpus_dates[work]) - min(corpus_dates[work])),
+ 4*int(min(corpus_dates[work])),
+ 4*int(np.median(corpus_dates[work])),
+ 4*int(max(corpus_dates[work])),
+ n_nodes,
+ direct_filiation_nb,
+ deg1,
+ deg2,
+ deg3,
+ deg4,
+ depth
+ ]
+
+ df = pd.read_csv("Old_French_witnesses.csv")
+ f2_works = []
+ f1_works = []
+ works = set(list(df['text H-ID']))
+ size_frags_d = []
+ size_d = []
+ for work in works:
+ n_wit = len(df[(df['text H-ID'] == work) & (df['status'] != 'fragment')])
+ n_frags = len(df[(df['text H-ID'] == work) & (df['status'] == 'fragment')])
+ if n_wit != 0:
+ size_d.append(n_wit)
+ if n_frags != 0:
+ size_frags_d.append(n_frags)
+
+ if n_wit == 2:
+ f2_works.append(work)
+ if n_wit == 1:
+ f1_works.append(work)
+
+ size_dist = Counter(size_d)
+ size_dist_frags = Counter(size_frags_d)
+
+ f2_dates = df[df["text H-ID"].isin(f2_works)]
+ f2_dates = f2_dates[(f2_dates['status'] != 'fragment')][["text H-ID", "date_of_creation", "Date"]]
+
+ add_f2 = []
+
+ for work in f2_works:
+ work_date = bd.convert_date(
+ f2_dates[f2_dates["text H-ID"] == work]["date_of_creation"].values.tolist()[0].replace(' to ', '-'))
+ #print(work_date)
+ t_dates = [bd.convert_date(x) for x in f2_dates[f2_dates["text H-ID"] == work]["Date"].values.tolist()]
+ #print(t_dates)
+ if t_dates != []:
+ relative_dates = []
+ for date in t_dates:
+ # Calculate the relative date difference
+ match (work_date, date):
+ case ((a, b), (c, d)):
+ if c <= a: # deal with the case of the range of a witness starts before the range of a work (should not happen, but, hey, approximate datings)
+ c = a + 1
+ relative_dates.append(bd.expected_abs_diff(a, b, c, d))
+ case ((a, b), c):
+ relative_dates.append(bd.expected_abs_diff_degenerate(a, b, c))
+ case (c, (a, b)):
+ relative_dates.append(bd.expected_abs_diff_degenerate(a, b, c))
+ case (a, b):
+ relative_dates.append(abs(a - b))
+ case _:
+ print(f'Error: Unexpected date format for work {work}, date {date}, work_date {work_date}')
+
+ add_f2.append([
+ 2,
+ 4 * int(max(relative_dates) - min(relative_dates)),
+ 4 * int(min(relative_dates)),
+ 4 * int(np.median(relative_dates)),
+ 4 * int(max(relative_dates)), -1, -1, -1, -1, -1, -1, -1])
+
+ f1_dates = df[df["text H-ID"].isin(f1_works)]
+ f1_dates = f1_dates[(f1_dates['status'] != 'fragment')][["text H-ID", "date_of_creation", "Date"]]
+
+ add_f1 = []
+ for work in f1_works:
+ work_date = bd.convert_date(
+ f1_dates[f1_dates["text H-ID"] == work]["date_of_creation"].values.tolist()[0].replace(' to ', '-'))
+ t_dates = [bd.convert_date(x) for x in f1_dates[f1_dates["text H-ID"] == work]["Date"].values.tolist()]
+ if t_dates != []:
+ relative_dates = []
+ for date in t_dates:
+ # Calculate the relative date difference
+ match (work_date, date):
+ case ((a, b), (c, d)):
+ if c <= a: # deal with the case of the range of a witness starts before the range of a work (should not happen, but, hey, approximate datings)
+ c = a + 1
+ relative_dates.append(bd.expected_abs_diff(a, b, c, d))
+ case ((a, b), c):
+ relative_dates.append(bd.expected_abs_diff_degenerate(a, b, c))
+ case (c, (a, b)):
+ relative_dates.append(bd.expected_abs_diff_degenerate(a, b, c))
+ case (a, b):
+ relative_dates.append(abs(a - b))
+ case _:
+ print(f'Error: Unexpected date format for work {work}, date {date}, work_date {work_date}')
+
+ add_f1.append([
+ 1,
+ 4 * int(max(relative_dates) - min(relative_dates)),
+ 4 * int(min(relative_dates)),
+ 4 * int(np.median(relative_dates)),
+ 4 * int(max(relative_dates)), -1, -1, -1, -1, -1, -1, -1])
+
+ # Computing as to maintain the same proportion of f1 and f2 in the obs
+ # as in the witness table
+
+ n_works = len(set(df[df['status'] != 'fragment']["text H-ID"].values))
+ freqf2 = len(set(f2_works))
+ freqf1 = len(set(f1_works))
+ ratiofsup2 = 1 - (freqf2 + freqf1) / n_works
+ x = len(x_obs0) / ratiofsup2
+ indf2 = round(x * (freqf2 / n_works))
+ indf1 = round(x * (freqf1 / n_works))
+ print(f"Using {len(x_obs0)} stemmata; using also {indf1} f1 and {indf2} f2 works")
+
+ x_obs_empirical = list(x_obs0.values()) + add_f1[:indf1] + add_f2[:indf2]
+
+ random.shuffle(x_obs_empirical)
+
+
+#### Now training
+
+lambda_min_prior = 4.*10**(-3)
+lambda_max_prior = 9.*10**(-3)
+
+mu_min_prior = 1.*10**(-3)
+mu_max_prior = 5*10**(-3)
+
+decay_min_prior = 0
+decay_max_prior = 1
+
+decimation_min_prior = 0
+decimation_max_prior = 1
+
+N_samples_prior = 500_000 #500000
+N_samples_posterior = 5_000 #1000
+
+if not load_models:
+
+
+ def simulator(theta):
+ lda0, mu, decay, decim = theta
+ g = bd.generate_tree_unified(lda0, mu, decay, decim, 1000, 1000, 500)
+
+ return g
+
+ prior = BoxUniform(low=Tensor([lambda_min_prior, mu_min_prior, decay_min_prior, decimation_min_prior]),
+ high=Tensor([lambda_max_prior, mu_max_prior, decay_max_prior, decimation_max_prior]))
+
+ theta0 = prior.sample((N_samples_prior,))
+
+ theta = []
+ x = []
+
+ #for t in tqdm(theta0):
+ # vec = compute_summary_stats(simulator(t))
+ # if vec != None:
+ # theta.append(list(t))
+ # x.append(vec)
+
+ def process_theta(t):
+ """
+ Helper function to process a single theta sample.
+ """
+ G = simulator(t)
+ vec = bd.compute_summary_stats(G)
+ if vec is not None:
+ return (list(t), vec)
+ else:
+ return None
+
+ def parallel_simulate(theta0, n_processes=None):
+ """
+ Parallelize the simulation and summary statistics computation.
+
+ Args:
+ theta0: Tensor of shape (N_samples_prior, 4)
+ n_processes: Number of processes to use (default: all available cores)
+
+ Returns:
+ theta, x: Lists of valid theta and summary statistics
+ """
+ if n_processes is None:
+ n_processes = multiprocessing.cpu_count()
+
+ with multiprocessing.Pool(n_processes) as pool:
+ results = list(tqdm(pool.imap(process_theta, theta0), total=len(theta0)))
+
+ # Filter out None results
+ valid_results = [r for r in results if r is not None]
+ theta, x = zip(*valid_results) if valid_results else ([], [])
+
+ return list(theta), list(x)
+
+ # Example usage:
+ theta, x = parallel_simulate(theta0, n_processes=num_workers)
+ theta = torch.tensor(theta, dtype=torch.float32)
+ x = torch.tensor(x, dtype=torch.float32)
+
+ from sbi.analysis import plot_summary
+
+for i in [42, 123, 456, 808, 1946]:
+ if not load_models:
+ torch.manual_seed(i)
+ inference = NLE(prior=prior)
+ inference = inference.append_simulations(Tensor(theta), Tensor(x))
+ print("training model " + str(i))
+ likelihood_estimator = inference.train(show_train_summary=True, max_num_epochs=max_num_epochs)
+ # Generate the plot
+ fig, ax = plot_summary(inference, tags=["training_loss", "validation_loss"])
+
+ # Save the plot to disk
+ plt.savefig(
+ f"loss_summary_model_{i+1}.pdf", # Save as PDF for high quality
+ dpi=300, # High resolution
+ bbox_inches="tight", # Remove extra whitespace
+ format="pdf" # Use PDF for publication-quality figures
+ )
+
+ # Close the figure to free memory
+ plt.close(fig)
+
+ with open("pretrained_models/inference_unif_bench_" + str(i) + ".pickle", "wb") as f:
+ pickle.dump(inference, f)
+
+ if load_models:
+ print(f"now loading model {i}")
+ with open("pretrained_models/inference_unif_bench_" + str(i) + ".pickle", "rb") as f:
+ inference = pickle.load(f)
+
+ if evaluate_on_data:
+
+ posterior = inference.build_posterior(mcmc_method="slice_np_vectorized", mcmc_parameters={
+ "num_chains": 10, "warmup_steps": 200, "thin": 10, "init_strategy": "resample",
+ "init_strategy_parameters": {'num_candidate_samples': 1000}#,
+ #"num_workers": num_workers#, "device": "cuda:0"
+ })
+
+ samples = posterior.sample(
+ sample_shape=(N_samples_posterior,),
+ x=x_obs_empirical
+ )
+
+ # Generate the pair plot
+ fig, axes = pairplot(
+ samples,
+ limits=[
+ [lambda_min_prior, lambda_max_prior],
+ [mu_min_prior, mu_max_prior],
+ [decay_min_prior, decay_max_prior],
+ [decimation_min_prior, decimation_max_prior]
+ ],
+ figsize=(10, 10), # Larger figsize for better readability
+ labels=[r"$\lambda$", r"$\mu$", r"$r_{\text{decay}}$", r"$r_{\text{decim}}$"]
+ )
+
+ # Adjust the DPI and save the figure
+ plt.savefig(
+ "pairplot_highres_bench"+ str(i)+".pdf", # Save as PDF for vector graphics (best for papers)
+ dpi=300, # High DPI for high resolution
+ bbox_inches="tight", # Remove extra whitespace
+ format="pdf" # Use PDF for publication-quality figures
+ )
+
+