aegean.greek¶
greek ¶
Greek NLP pipeline — composable, individually-callable stages.
The dependency-free core covers normalize (NFC/NFD + Beta Code ↔ Unicode, with
a lenient OCR-repair mode), tokenize (word/sentence), syllabify, accent
analysis (accentuation), prosody/meter scansion, phonology (IPA),
a seed+rule lemmatize, baseline pos, and a rule-based morphology analyzer
(analyze). pipeline runs the whole stack over a text in one call.
Opt-in backends layer on richer data and models:
use_neural_pipeline(the[neural]extra) loads the joint neural model — one pass serving UPOS, full morphology (UD FEATS), UD dependency trees, and lemmas, state of the art on the UD Ancient Greek (Perseus) benchmark (measured numbers indocs/benchmarks.md). Once active,pos_tag/pos_tags,lemmatize,parse, andpipelineall use it.use_treebank(Perseus AGDT) supplies attested, correctly-accented lemmas and full features for known forms.use_lsj(Perseus Liddell-Scott-Jones) provides glossing (gloss/lookup).use_parser(parse; arc-eager + averaged perceptron, trained on the AGDT) is a projective dependency parser (~0.67 UAS / 0.57 LAS).use_taggeris an averaged-perceptron POS tagger (~84% on unseen forms).use_lemmatizeris an edit-tree lemmatizer (~40% on unseen forms).use_neural_lemmatizer(the[neural]extra) is a GreTa T5 seq2seq model served as int8 ONNX without torch; it pairs a gold lookup with seq2seq decoding and reaches 76.3% on unseen forms.lemmatizecascades neural pipeline -> treebank -> neural -> edit-tree -> seed table -> generalizing ending rules.
Every stage is a plain function so it can be used standalone::
from aegean import greek
greek.betacode_to_unicode("mh=nin") # 'μῆνιν'
greek.syllabify("ἄνθρωπος") # ['ἄν', 'θρω', 'πος']
greek.accentuation("λόγος").classification # 'paroxytone'
greek.pipeline("ἐν ἀρχῇ ἦν ὁ λόγος.") # per-token records, one call
AccentInfo
dataclass
¶
AccentInfo(syllables: tuple[str, ...], accent_type: str | None, position_from_end: int | None, classification: str | None)
The accent analysis of one word.
AccentPlacement
dataclass
¶
AccentPlacement(form: str, accent_type: str, position_from_end: int, classification: str, certain: bool, note: str = '')
A predicted accent placement.
ResolvedForm
dataclass
¶
ResolvedForm(surface: str, words: tuple[str, ...], kind: str | None = None, uncertain: bool = False, note: str = '', alternatives: tuple[str, ...] = tuple())
The sandhi analysis of one token.
words is the underlying word sequence the surface form stands for; for a
token with no sandhi (or one left unexpanded) it is just the input. kind
names the phenomenon ("crasis" / "elision" / "movable-nu" /
None). uncertain is set when a contraction is detected but cannot be
expanded from standard forms, in which case words keeps the surface form
unchanged. note is a short human-readable provenance string.
resolved
property
¶
True if the surface form was expanded/normalised to something new.
Inflector ¶
An inverse-lemmatization index: lemma -> attested (features, form) cells.
from_lexicon
classmethod
¶
from_lexicon(lexicon: dict[str, list[dict[str, str]]]) -> Inflector
Invert a treebank form->analyses lexicon into lemma->(features, form) cells.
Forms keep the lexicon's frequency order (most-attested first); duplicate (features, form) cells per lemma are collapsed.
inflect ¶
Attested form(s) of lemma matching features (a partial set of the keys
in _FEATURES), most-attested first. Empty if nothing matches.
paradigm ¶
Every attested (features, form) cell of lemma (empty if unattested).
InflectorNotLoadedError ¶
Bases: RuntimeError
Raised when an inflection call is made before use_inflector.
LemmaSource ¶
Bases: str, Enum
Where a lemma came from — the evidence class for one token's lemma.
A str Enum (not StrEnum: the floor is Python 3.10), so members are plain
strings under json.dumps and comparisons; emit .value where a bare string
is wanted. Ordered from most to least trustworthy:
ATTESTED— a treebank-lexicon hit (an attested, correctly accented lemma).NEURAL— a real prediction from the joint pipeline / seq2seq / edit-tree model.RULE— the ending-stripping rule layer recovered a regular citation form.SEED— the bundled seed table / a closed-class function word.PARADIGM— a hit in the opt-in UniMorph paradigm table (use_paradigms): a curated inflection lookup that recovers an irregular / third-declension form the ending rules cannot (γυναικός → γυνή), correctly accented and grounded.IDENTITY— a backend/model was consulted but returned the surface form unchanged (no real analysis), so the "lemma" is just the input.UNRESOLVED— the baseline cascade was exhausted; the normalized form is returned.PUNCT— a non-word token (punctuation / numeral): trivially its own lemma.
IDENTITY and UNRESOLVED are the classes a human should verify (see
needs_review); the rest are grounded analyses.
Analysis
dataclass
¶
Analysis(lemma: str, pos: str, case: str | None = None, number: str | None = None, gender: str | None = None, tense: str | None = None, voice: str | None = None, mood: str | None = None, person: str | None = None, degree: str | None = None, lemma_certain: bool = True)
One candidate morphological reading of a form.
RarityResult
dataclass
¶
RarityResult(overall: float, words: tuple[WordRarity, ...], corpus_lemmas: int, corpus_tokens: int)
A text's terminology rarity against a reference corpus.
WordRarity
dataclass
¶
One word's rarity against the reference corpus.
TreebankLexicon ¶
An attested form→analyses lexicon built from the AGDT treebank.
load
classmethod
¶
Load a built lexicon JSON (defaults to the cached one).
analyze ¶
analyze(form: str) -> tuple[Analysis, ...]
Attested analyses for a form (frequency-ordered), or () if unknown.
lemmatize ¶
The most-attested lemma for a form, or None if unknown.
pos ¶
The most-attested part-of-speech tag for a form, or None if unknown.
ParadigmLexicon ¶
A form→analyses paradigm lexicon (UniMorph grc), served like TreebankLexicon.
load
classmethod
¶
Load a built paradigm index (defaults to the cached grc-paradigms.json.gz).
analyze ¶
analyze(form: str) -> tuple[Analysis, ...]
Paradigm analyses for a form, or () if unknown — same record shape as
TreebankLexicon.analyze, so the two backends are interchangeable.
lemmatize ¶
The first (paradigm) lemma for a form, or None if unknown.
lemma_options ¶
The DISTINCT lemmas (NFC-compared) a form maps to; frozenset() if unknown.
More than one element means the table is internally ambiguous for the form: φωτός is the genitive of both φώς 'man' and φῶς 'light', βασιλεία collides with βασίλεια. A caller can treat that as no confident pick rather than the arbitrary first entry. Several cells of a SINGLE lemma (γυναικός) collapse to one element and stay grounded.
LSJEntry
dataclass
¶
A Liddell-Scott-Jones entry.
LSJLexicon ¶
LexiconNotLoadedError ¶
Bases: RuntimeError
Raised when gloss/lookup is called before use_lsj.
UsageInfo
dataclass
¶
Dialect and register tags recorded for a lemma in LSJ.
DepToken
dataclass
¶
One token in a dependency tree (1-based id; head=0 is the root).
ParserNotLoadedError ¶
Bases: RuntimeError
Raised when parse is called before use_parser.
TaggerNotLoadedError ¶
Bases: RuntimeError
Raised when tag_pos is used before use_tagger.
LemmatizerNotLoadedError ¶
Bases: RuntimeError
Raised when the trained lemmatizer is used before use_lemmatizer.
NeuralLemmatizerNotLoadedError ¶
Bases: RuntimeError
Raised when the neural lemmatizer is used before use_neural_lemmatizer,
or when the [neural] extra (onnxruntime/tokenizers) is not installed.
NeuralPipelineNotLoadedError ¶
Bases: RuntimeError
Raised when the neural pipeline is used before use_neural_pipeline, or when
the [neural] extra (onnxruntime/tokenizers/numpy) is not installed.
SentenceAnalysis
dataclass
¶
SentenceAnalysis(tokens: tuple[str, ...], upos: tuple[str, ...], xpos: tuple[str, ...], feats: tuple[str, ...], head: tuple[int, ...], deprel: tuple[str, ...], lemma: tuple[str, ...], lemma_resolved: tuple[bool, ...] = (), upos_prob: tuple[float | None, ...] = (), lemma_script_prob: tuple[float | None, ...] = ())
The joint model's full analysis of one sentence (parallel, per-token lists).
Calibration
dataclass
¶
Calibration(temperature: dict[str, float], fitted_on: str = '', date: str = '', ece_before: dict[str, float] = dict(), ece_after: dict[str, float] = dict(), n: dict[str, int] = dict(), notes: str = '')
A fitted temperature calibration for the joint model's heads.
temperature maps each head name ("upos", "lemma") to its fitted scalar
T (strictly positive). fitted_on describes the fold and model it was measured
on, date when, and ece_before / ece_after / n record the measured
Expected Calibration Error (before and after scaling) and the token count per head —
the honesty evidence that travels with the number. Round-trips to JSON via
to_dict / from_dict (and save / load).
UncalibratedConfidenceError ¶
Bases: RuntimeError
Raised when calibrated confidence is requested but none is loaded.
pyaegean never exposes a raw (uncalibrated) softmax probability: an uncalibrated
number invites false confidence, which breaks the measured-claims-only rule. A
temperature-scaled, ECE-measured calibration must be loaded (use_calibration) or
fitted (fit_temperature) before any confidence is surfaced.
MissingForm
dataclass
¶
One unresolved Greek word form and where to find it.
form— the surface word exactly as it appears in the corpus.count— how manyWORDtokens with this exact surface the lemmatizer left unresolved (needs review).example_doc_id— the document id of the first occurrence, in corpus order.example_position— that token's position: itsToken.position, or its index within the document's token stream whenpositionis unset.
TokenExplanation
dataclass
¶
TokenExplanation(token: str, upos: str, lemma: str, lemma_source: LemmaSource, needs_review: bool, morphology: str | None, note: str)
One token's analysis with its evidence class spelled out in plain language.
lemma_source is the lemma's evidence class (see LemmaSource) and is
the entire trust claim: there are deliberately no confidence numbers.
needs_review is True for the two ungrounded classes (an identity
fall-through or an unresolved miss). morphology is the UD FEATS
string when the neural pipeline produced one, else None. note says
in one line what the evidence class means for this token.
TextProfile
dataclass
¶
TextProfile(char_count: int, token_count: int, letter_count: int, script: str, greek_ratio: float, latin_ratio: float, is_polytonic: bool, has_accent: bool, has_breathing: bool, polytonic_ratio: float, majuscule_ratio: float, looks_like_betacode: bool, has_editorial_brackets: bool, editorial_mark_count: int, digit_or_numeral_ratio: float)
Observable, descriptive features of one raw text string.
Every field is a direct measurement of the input, not a prediction. There is
deliberately no genre, register, or out-of-domain label: this profiles what
the characters are, not what the text is about. script names the writing
system most letters fall in by codepoint block (greek / latin /
mixed / other); greek_ratio and latin_ratio expose the
underlying evidence so a caller need not trust the label alone.
ErrorAnalysis
dataclass
¶
ErrorAnalysis(pos_confusions: tuple[tuple[str, str, int], ...], lemma_mismatches: tuple[tuple[str, str, str], ...], lemma_confusions: tuple[tuple[str, str, int], ...], per_pos: tuple[PosStat, ...], freq_bands: tuple[tuple[str, int, int, int], ...], pos_scored: int, pos_errors: int, lemma_errors: int, n_seen: int, n_unseen: int, pos_ok_seen: int, pos_ok_unseen: int, lemma_ok_seen: int, lemma_ok_unseen: int)
A breakdown of a tagger's errors against a gold set.
pos_confusions / lemma_confusions are (gold, predicted, count) triples,
most-frequent first; lemma_mismatches samples (form, gold lemma, predicted lemma)
for reading. per_pos is per-gold-POS accuracy (most-frequent POS first). The
seen/unseen counts are substantive only for the AGDT held-out split, where forms carry a
real seen flag; for out-of-domain sets (PROIEL, NT, UD) every token is unseen by
construction, so the unseen figures equal the overall ones.
top_share
property
¶
Fraction of POS errors in the single most common confusion pair (higher = more systematic/convention-like, lower = more scattered).
summary ¶
A short, readable breakdown: overall accuracy, top POS confusions, the weakest parts of speech, and (when meaningful) the unseen-form accuracy.
PosStat
dataclass
¶
Per-gold-POS accuracy over the scored tokens.
ConventionReport
dataclass
¶
ConventionReport(n_words: int, ufeats_correct: int, n_scheme_blocked_words: int, n_shared_only_words: int, shared_only_correct: int, feature_stats: tuple[FeatureConventionStat, ...], uas_correct: int, las_correct: int, label_only_errors: int, deprel_confusions: tuple[DeprelConfusion, ...])
Where the PROIEL UD-fold UFeats and LAS gaps come from, told apart into annotation-convention divergence (the AGDT-trained model structurally cannot close it) and real disagreement on the shared scheme.
Measurement only — it reproduces the official UFeats/UAS/LAS from the model's own outputs and partitions them; it does not replace any published number and nothing is fitted to the fold. Every count is over the fold's scored words (the evaluator scores every aligned syntactic word for these metrics; unlike the POS/lemma drift view it does not skip PUNCT/NUM).
ufeats
property
¶
Per-word UFeats accuracy (reproduces the official UFeats F1 under gold tokenization, where precision = recall = accuracy).
gap_scheme_absent
property
¶
The share of ALL words lost purely to scheme-absent features (words carrying a universal feature the model can never emit — an unavoidable UFeats miss). One of the two additive parts of the UFeats gap.
gap_shared_disagreement
property
¶
The share of ALL words lost to disagreement WITHIN the shared scheme (the other
additive part; gap_scheme_absent + gap_shared_disagreement == ufeats_gap).
shared_subset_ufeats
property
¶
UFeats accuracy on the subset of words whose gold features are all scheme-shared — the model's morphology quality with the convention gap removed.
scheme_absent_features
property
¶
scheme_absent_features: tuple[FeatureConventionStat, ...]
The universal feature types PROIEL uses that the AGDT scheme never emits, by count.
label_only_share
property
¶
The share of ALL words that are attachment-correct but label-wrong — the part of
the LAS gap that is pure relabelling (uas - las == label_only_share).
deprel_top_share
property
¶
Fraction of the label-only-error mass in the single most common relation confusion (higher → more systematic/convention-like, lower → more scattered).
deprel_concentration ¶
Fraction of the label-only-error mass in the top-top relation confusions.
DeprelConfusion
dataclass
¶
A (gold relation → predicted relation) pair among the attachment-correct/label-wrong tokens — the label-only errors that separate UAS from LAS. Subtypes are stripped (the evaluator's LAS convention).
DriftReport
dataclass
¶
DriftReport(pos_confusions: tuple[tuple[str, str, int], ...], lemma_mismatches: tuple[tuple[str, str, str], ...], pos_scored: int, pos_errors: int, lemma_errors: int)
Where the PROIEL gap comes from — so systematic annotation-convention divergence can be told apart from scattered real error.
The shipped model is trained on the AGDT convention; scoring it on the differently-annotated
PROIEL conflates real mistakes with convention differences. pos_confusions lists the
(gold POS → predicted POS) disagreements most-frequent first: a few pairs carrying most of
the POS errors points to a convention difference, a long flat tail to genuine error.
lemma_mismatches samples the lemma disagreements (often homograph or normalization
convention). POS here is already reconciled (PROPN→NOUN, SCONJ→CCONJ, AUX→VERB), so what
remains is other convention drift plus real error.
FeatureConventionStat
dataclass
¶
FeatureConventionStat(feature: str, gold_count: int, emitted_by_model_scheme: bool, shared_agree: int)
One UD feature type's contribution to the UFeats gap.
gold_count is how many scored gold words carry this (universal) feature.
emitted_by_model_scheme is whether the AGDT→UD renderer can produce it at all — when
False the feature is scheme-absent and every gold word carrying it is an unavoidable
UFeats miss. shared_agree counts, among those gold words, how many the model labels
with the SAME value (0 for a scheme-absent feature).
agreement_on_shared
property
¶
Fraction of gold words carrying this feature that the model labels with the same value. 0.0 for a scheme-absent feature (the model never emits it).
PapyGreekConventionReport
dataclass
¶
PapyGreekConventionReport(n_words: int, upos_correct: int, upos_coordinator_errors: int, upos_other_errors: int, upos_confusions: tuple[tuple[str, str, int], ...], xpos_correct: int, xpos_coordinator_poscode: int, xpos_common_gender: int, xpos_underscore_encoding: int, xpos_residual_real: int, n_gold_xpos_underscore: int, xpos_position_errors: tuple[int, ...])
Where the PapyGreek UPOS and XPOS gaps come from — annotation/encoding convention (the AGDT-trained model structurally cannot close it on this fold) told apart from real error.
Measurement only: it reproduces the official UPOS/XPOS from the model's own outputs and partitions them; it does not replace any published number and nothing is fitted to the fold. Every count is over the fold's scored words (the evaluator scores every aligned syntactic word for UPOS/XPOS under gold tokenization).
upos
property
¶
Per-word UPOS accuracy (reproduces the official UPOS F1 under gold tokenization).
coordinator_share
property
¶
Fraction of ALL UPOS errors that fall on the coordinator class (gold CCONJ) — the single-phenomenon concentration signal (phase-1: ~57%).
upos_coordinator_pts
property
¶
Share of ALL words lost to coordinator-class UPOS errors (one additive part of the
UPOS gap; upos_coordinator_pts + upos_other_pts == upos_gap).
xpos
property
¶
Per-word XPOS (9-position exact) accuracy (reproduces the official XPOS F1).
xpos_convention_pts
property
¶
The three convention/encoding parts of the XPOS gap, together (coordinator +
common-gender + _-encoding). xpos_convention_pts + xpos_residual_pts ==
xpos_gap.
xpos_forgiving_convention
property
¶
XPOS accuracy if the three convention/encoding buckets are forgiven — the model's morphology quality with the convention cap removed.
EvalReceipt
dataclass
¶
EvalReceipt(id: str, package_version: str, manifest: dict[str, Any], model_id: str | None, treebank: str, split: str, protocol: str, scores: dict[str, float], extra: dict[str, Any] | None)
A tamper-evident record tying one evaluation result to its inputs.
Frozen and content-addressed: id is the short sha256 of the canonical JSON of
every other field. Construct via eval_receipt. scores/manifest/extra
are stored as-is; treat them as read-only (the dataclass is frozen, but their
contents are plain dicts).
recompute_id ¶
Re-derive the id from the stored fields (full=True for the 64-char sha256).
verify ¶
Tamper check. With no argument, re-hash this receipt's fields and confirm
they still produce self.id. With other, confirm both receipts describe
the byte-identical evaluation (same content-addressed id).
as_json ¶
Serialize the full receipt (id + every field) to JSON.
With indent=None (the default) this is the canonical form whose bytes the
id hashes, minus the id itself; as_dict() includes the id for storage.
as_dict ¶
A plain dict of every field, including id (round-trips via from_dict).
from_dict
classmethod
¶
Reconstruct a receipt from as_dict output (does not re-verify; call verify).
NormalizationWarning ¶
Bases: UserWarning
Emitted by normalize(..., lenient=True) for each class of repair.
DodsonEntry
dataclass
¶
One Dodson lexicon entry.
DodsonNotLoadedError ¶
Bases: RuntimeError
Raised when a Dodson glossing call is made before use_dodson().
LexEntry
dataclass
¶
A dictionary entry, uniform across lexica.
LexiconInfo
dataclass
¶
Metadata for one registered lexicon.
TokenRecord
dataclass
¶
TokenRecord(sentence: int, index: int, text: str, upos: str, lemma: str, lemma_source: LemmaSource, head: int | None = None, relation: str | None = None, xpos: str | None = None, feats: str | None = None, upos_confidence: float | None = None, lemma_confidence: float | None = None)
One token's full analysis from pipeline.
head refers to the index of another record in the same sentence
(0 = sentence root, None = no parse). xpos/feats are filled
only by the neural pipeline. lemma_source is the lemma's evidence class
(see LemmaSource, one of attested / neural / rule / seed /
paradigm / identity / unresolved / punct): whether it was
attested in a treebank, predicted by the neural model, recovered by a rule,
from the seed table, from a paradigm-table lookup (the opt-in UniMorph
inflection tables, use_paradigms()), an identity fall-through, unresolved,
or punctuation. lemma_known is the derived boolean (False for an identity
fall-through or an unresolved baseline miss, i.e. a lemma to verify).
upos_confidence / lemma_confidence are calibrated confidences
(temperature-scaled on the UD Perseus dev fold; see
aegean.greek.calibrate): the estimated probability the prediction is
correct. They are None unless the neural pipeline is active, a calibration
is loaded, AND the call set with_confidence=True — the project never
surfaces a raw (uncalibrated) softmax. A calibrated number is model-only:
lemmas resolved by an offline lexicon backend carry no model confidence (both
fields stay None throughout the offline cascade, where the evidence class
speaks). Within the neural pipeline the calibrated lemma_confidence covers
the model's full lemma composition, including its internal training-form
lookup, by design (the calibration target is composed-lemma correctness); it is
None only for a token the model does not itself lemmatize (an identity
fall-through or punctuation). The number is fitted on literary prose, so it
carries that genre caveat.
lemma_known
property
¶
True when the lemma is a real analysis, not an identity fall-through or an
unresolved baseline miss. Derived from lemma_source; kept as a stable
read-API (the record stores the richer lemma_source).
GitHubRateLimitError ¶
Bases: DataNotAvailableError
The unauthenticated GitHub contents API (~60 requests/hour) is exhausted.
Raised distinctly from a generic fetch failure so a bulk run can stop cleanly
instead of burning the next request. Set PYAEGEAN_GITHUB_TOKEN or
GITHUB_TOKEN to raise the limit to 5,000/hour.
WorkFetchResult
dataclass
¶
One work's outcome in a bulk fetch: status is "fetched" (downloaded
now), "cached" (already on disk, no network), or "failed" (error
holds why). A dataclass so the CLI --json path serialises it directly.
Foot
dataclass
¶
One metrical foot: its name and the syllables/quantities it spans.
LineScansion
dataclass
¶
LineScansion(line: str, meter: str, feet: tuple[Foot, ...], syllables: tuple[str, ...], quantities: tuple[str, ...], caesura: str | None, caesura_index: int | None, ambiguous: bool)
The scansion of one verse line.
ScansionError ¶
Bases: ValueError
Raised when a line cannot be fit to the requested meter.
place_accent ¶
place_accent(word: str, *, recessive: bool, lemma: str | None = None, ultima_length: str | None = None, penult_length: str | None = None) -> AccentPlacement
Place an accent: recessive=True for finite verbs, else persistent (lemma required).
persistent_accent ¶
persistent_accent(form: str, lemma: str, *, ultima_length: str | None = None, penult_length: str | None = None) -> AccentPlacement
Place a persistent accent (nominals): keep the lemma's syllable unless a lengthened
ultima forces it one syllable toward the end. lemma supplies the home syllable via its
own written accent.
recessive_accent ¶
recessive_accent(word: str, *, ultima_length: str | None = None, penult_length: str | None = None) -> AccentPlacement
Place a recessive accent (finite verbs): as far toward the antepenult as the laws allow.
resolve_sandhi ¶
resolve_sandhi(token: str) -> ResolvedForm
Resolve crasis, elision, and movable-ν / οὐκ-type sandhi in one token.
Returns a ResolvedForm. A token with no sandhi passes through unchanged
(kind=None). Crasis is expanded only from the curated _CRASIS lexicon;
an unlisted coronis form is flagged uncertain and left intact. Elision is
restored only where the elided vowel is unambiguous (listed proclitic/particle
or a clear inflectional ending); otherwise the clipped form is kept and
flagged uncertain. The οὐκ/οὐχ/οὐ rule is purely contextual; movable-ν
is asserted only for validated hosts (the -ουσι(ν) ending or the curated
_MOVABLE_NU_HOSTS list), never for the look-alike i-stem accusatives
(γνῶσιν, πίστιν), which pass through unclaimed.
Conservative throughout: the resolver never guesses an expansion. When the
surface form is ambiguous it is returned unchanged with uncertain=True and
an explanatory note.
resolve_sentence ¶
resolve_sentence(text: str) -> list[ResolvedForm]
Run resolve_sandhi over every word of a sentence (punctuation dropped).
Returns one ResolvedForm per surface word, in order. Use
[w for r in result for w in r.words] to get the flat expanded word
stream the pipeline should index against.
paradigm ¶
The full attested paradigm of lemma as (features, form) cells; requires
use_inflector.
use_inflector ¶
use_inflector(*, build: bool = True, force: bool = False) -> Inflector
Activate inflection synthesis for this session.
Builds (and caches) the AGDT lexicon on first use (build=True; downloads the AGDT
files if needed), inverts it into the form index, and makes inflect / paradigm
resolve against it. build=False loads an already-built lexicon.
lemmatize_sourced ¶
lemmatize_sourced(word: str) -> tuple[str, LemmaSource]
Return (lemma, source): the lemma plus the evidence class it came from (see
LemmaSource). This is the authoritative cascade; lemmatize and lemmatize_verbose
are expressed on top of it, so the lemma and its known/verbose flag can never drift
from the source.
Tier order: the neural joint pipeline (use_neural_pipeline) → the AGDT treebank
(use_treebank, an attested lemma) → the GreTa seq2seq backend
(use_neural_lemmatizer) → the trained edit-tree lemmatizer (use_lemmatizer) → the
bundled seed table → the generalizing ending-stripping rule layer → the opt-in UniMorph
paradigm table (use_paradigms, a curated PARADIGM-class lookup). A backend that
returns the surface form unchanged is reported IDENTITY (not a real analysis); an
exhausted baseline is UNRESOLVED.
The paradigm table is consulted after the ending rules, only when the guarded rules
do not recover a citation form: the rules' recover-set (regular second-declension
obliques and thematic verb endings) is exactly where the purely-nominal table shadows
the dominant verb reading (the noun dative ἔχει = ἔχις would otherwise displace
the verb ἔχει → ἔχω the rules resolve correctly), so the rules win there and the
table supplies only the irregular / third-declension forms they cannot touch (γυναικός
→ γυνή). A paradigm hit is further gated: the closed-class and indeclinable guard, a
capitalized surface (a proper name; the table is lowercase common vocabulary), and any
form the table itself maps to more than one distinct lemma (φωτός = genitive of both
φώς and φῶς) are all left as an honest miss rather than an arbitrary pick.
The joint pipeline's IDENTITY is decided by which branch composed the lemma
(joint._compose_lemma), not by a surface-string compare, so a nominative singular
whose lemma equals the form is correctly NEURAL. The auxiliary seq2seq/edit-tree
backends have no such signal, so there a lemma equal to the surface reads IDENTITY
(preserving their historical known semantics).
lemmatize_verbose ¶
Return (lemma, known). known is False when the lemma is not a real analysis:
an identity fall-through from a backend, or an exhausted baseline that returns the
(normalized) input unchanged. Delegates to lemmatize_sourced (the tier order is
documented there) so the flag tracks the evidence class exactly.
needs_review ¶
needs_review(source: LemmaSource) -> bool
Whether a lemma with this source should be verified by a human: an IDENTITY
fall-through or an UNRESOLVED baseline miss. ATTESTED/NEURAL/RULE/
SEED/PARADIGM/PUNCT are grounded and do not need review.
analyze ¶
analyze(word: str) -> tuple[Analysis, ...]
All candidate morphological analyses of word (possibly several, given
Greek's ambiguity; empty only for unanalysable tokens).
Closed-class words (article, prepositions, conjunctions, particles, pronouns,
the copula) resolve to a single high-confidence analysis; open-class words
yield the readings their ending permits. When the AGDT treebank backend is
active (see aegean.greek.use_treebank), an attested form's analyses —
correctly accented and covering irregular forms the rule engine can't — are
returned instead; failing that, the opt-in UniMorph paradigm table
(aegean.greek.use_paradigms) supplies irregular/third-declension paradigm
cells, with the rule engine as the fallback for forms neither backend knows.
best_pos ¶
A single best part-of-speech guess from morphology, or None when the
form yields no analysis. Returns the most likely reading's tag (verbal and
closed-class readings, which are listed first, take precedence over the
nominal default), or ADJ when a degree is marked.
lemmas ¶
The distinct lemma candidates for a form (closed-class or rule-derived).
terminology_rarity ¶
terminology_rarity(text: str, corpus: object) -> RarityResult
Score the terminology rarity of text against a reference corpus.
corpus is any aegean.Corpus (or QueryResults); its word tokens define the
frequency basis, so the score is relative to that corpus's register. Returns the overall
score plus a per-word breakdown (use .hardest() to surface the rare terms).
disable_treebank ¶
Deactivate the treebank lexicon; restore the default rule/seed behaviour.
use_treebank ¶
use_treebank(*, build: bool = True, force: bool = False) -> TreebankLexicon
Activate the AGDT lexicon for this session.
Downloads + builds it on first use (build=True); pass force=True to
rebuild. Once active, aegean.greek.lemmatize / analyze prefer
its attested analyses and fall back to the rule/seed engines on a miss.
disable_paradigms ¶
Deactivate the paradigm lexicon; restore the default seed/rule behaviour.
use_paradigms ¶
use_paradigms(*, build: bool = True, force: bool = False, path: Path | str | None = None) -> ParadigmLexicon
Activate the UniMorph paradigm lexicon for this session.
Fetches the prebuilt index on first use (build=True); pass path to load a local
build/fixture offline, or force=True to re-fetch. Once active,
aegean.greek.lemmatize / analyze consult it for irregular/third-declension forms,
after the generalizing ending rules and only when those rules do not recover, subject to
the cascade guards (closed-class/indeclinable, capitalized surface, intra-table
ambiguity). A paradigm hit is reported under its own PARADIGM evidence class (a
grounded, curated lookup).
disable_documentary_lemma_rescue ¶
Deactivate Lever B; remove the wrapper if no lever remains active.
disable_documentary_reconciliation ¶
Deactivate Lever A; remove the wrapper if no lever remains active.
documentary_lemma_rescue_active ¶
Whether Lever B (lemma OOV rescue) is currently active.
documentary_reconciliation_active ¶
Whether Lever A (coordinator reconciliation) is currently active.
rescue_lemma ¶
rescue_lemma(form: str) -> tuple[str, LemmaSource] | None
The guarded offline lemma rescue for one form: (lemma, source) or None.
Consults the two CURATED offline sources: the bundled seed table (SEED), then the
opt-in UniMorph paradigm table when use_paradigms is active (PARADIGM, gated by the
same closed-class / indeclinable / capitalized-surface / intra-table-ambiguity guards).
Returns None when neither recovers a citation form (the form stays an honest miss).
Never consults the neural model, so a rescue is always an offline, grounded analysis under
its own evidence class — never NEURAL.
The generalizing ending-stripping rules are deliberately NOT consulted here: on the OOV residue the neural model already left unresolved, the rules fabricate about as often as they fix (measured on the documentary dev fold: roughly break-even there, and net-negative on the literary dev fold, where they were the sole source of regressions), so the rescue keeps only the curated, correctly-accented tiers.
use_documentary_lemma_rescue ¶
Activate Lever B: offline lemma OOV rescue over the neural output.
Requires the neural pipeline to be active (raises NeuralPipelineNotLoadedError
otherwise). When the model leaves a lemma unresolved, the guarded offline cascade
(seed → rules → the opt-in paradigm table) is consulted for a rescue; a rescue never
overrides a resolved neural lemma and carries its own offline evidence class (see
rescue_lemma). Default-off and byte-identical to the plain pipeline until called;
disable_* restores that.
use_documentary_reconciliation ¶
Activate Lever A: closed-class coordinator reconciliation over the neural output.
Requires the neural pipeline to be active (raises NeuralPipelineNotLoadedError
otherwise). aggressive=False (the default, recommended) corrects only the X / b
drift, which is always wrong for a coordinator and so cannot mislabel literary text.
aggressive=True additionally folds in the ADV / d drift, which clobbers the
legitimate adverbial reading (measured to regress the literary dev fold heavily).
Default-off and byte-identical to the plain pipeline until called; disable_*
restores that.
lookup ¶
lookup(word: str) -> LSJEntry | None
Full LSJ entry for a word; requires use_lsj. None if unknown.
use_lsj ¶
use_lsj(*, build: bool = True, force: bool = False) -> LSJLexicon
Activate the LSJ lexicon for this session.
Downloads (~270 MB) + builds the index on first use (build=True); pass
force=True to rebuild. Then gloss / lookup resolve words
against it.
evaluate_parser ¶
evaluate_parser(*, source_dir: Path | str | None = None, holdout: float = 0.1, epochs: int = 5) -> dict[str, Any]
Train on a split and score the held-out trees → {"uas","las","tokens","sentences"}
(gold POS/lemma; measures parsing in isolation). Exposed as greek.evaluate_parser.
parse ¶
parse(sentence: str | list[str]) -> DepTree
Parse a Greek sentence (a string or a list of tokens) into a DepTree.
Uses the neural pipeline when it is active (aegean.greek.use_neural_pipeline) —
relations are then UD (nsubj, obj, advcl, …) and postag carries the predicted
9-char tag. Otherwise requires use_parser (the arc-eager baseline, AGDT/Prague
relations), with POS/lemma from the (treebank-aware) pipeline.
use_parser ¶
Activate the dependency parser for this session — training the model on first
use (train=True; from the cached AGDT, a few minutes) or loading the cache.
disable_tagger ¶
Deactivate the POS tagger; restore the lookup/rule behaviour.
evaluate_tagger ¶
evaluate_tagger(*, source_dir: str | None = None, holdout: float = 0.1, epochs: int = 8) -> dict[str, float]
Train on the train split and score POS on the held-out split (overall + unseen),
via aegean.greek.heldout — the honest generalization number. Returns
pos_all/pos_unseen plus the token counts (this tagger predicts POS only, so the
lemma metrics are omitted).
use_tagger ¶
Activate the generalizing POS tagger. With train=True (default) it trains on
first use — from the cached AGDT, a few minutes — then caches the model; later calls
load the cache. train=False loads an existing cached model without training (raises
TaggerNotLoadedError if none exists). force=True retrains even if cached.
disable_lemmatizer ¶
Deactivate the lemmatizer; restore the lookup/seed/identity behaviour.
evaluate_lemmatizer ¶
evaluate_lemmatizer(*, source_dir: str | None = None, holdout: float = 0.1, epochs: int = 8) -> dict[str, float]
Train on the train split and score lemma accuracy on the held-out split (overall +
unseen), via aegean.greek.heldout — the honest generalization number. A POS
tagger is trained on the same split so the dev set is scored with predicted POS (the
realistic pipeline), not gold. Returns lemma_all/lemma_unseen plus token counts
(POS metrics are omitted).
use_lemmatizer ¶
Activate the generalizing lemmatizer. With train=True (default) it trains on
first use — from the cached AGDT, a few minutes — then caches the model; later calls
load the cache. train=False loads an existing cached model (raises
LemmatizerNotLoadedError if none exists). force=True retrains even if cached.
disable_neural_lemmatizer ¶
Deactivate the neural lemmatizer; the cascade falls back to the edit-tree/seed/identity.
use_neural_lemmatizer ¶
Activate the neural (GreTa seq2seq) lemmatizer.
Fetches the model bundle (ONNX encoder/decoder + tokenizer + gold lookup) to the cache on
first use — never bundled in the wheel — then loads it via onnxruntime. Requires the
[neural] extra (pip install 'pyaegean[neural]'). Best paired with
aegean.greek.use_treebank, whose attested lemmas take precedence for seen forms.
Raises NeuralLemmatizerNotLoadedError if the optional dependencies are missing
(checked before any download), and aegean.data.DataNotAvailableError if the model URL
is not yet pinned (set PYAEGEAN_GRC_LEMMA_NEURAL_URL to fetch from your own mirror)
or the download fails.
analyze_sentence ¶
analyze_sentence(words: list[str], *, with_probs: bool = False) -> SentenceAnalysis
The full joint analysis of one pre-tokenized sentence (raises if not active).
with_probs=True additionally fills the calibrated confidence fields and requires
a loaded calibration (see _JointModel.analyze).
analyze_sentences ¶
analyze_sentences(sentences: Iterable[list[str]], *, batch_size: int | None = None, with_probs: bool = False) -> list[SentenceAnalysis]
Full joint analyses of several pre-tokenized sentences (raises if not active).
batch_size=None (the default) analyzes each sentence with its own encoder pass —
identical to calling analyze_sentence in a loop, and the code path the published
benchmark numbers are measured on (plain CPU, CPUExecutionProvider). A positive
int runs padded chunks of that many sentences through the encoder (one ONNX call per
chunk), a throughput convenience producing the same analyses; batched matmuls can
reorder float reductions, so it is never used for the recorded protocol. with_probs
behaves as in analyze_sentence (calibration required).
disable_neural_pipeline ¶
Deactivate the neural pipeline; every function falls back to its prior cascade.
neural_backend_info ¶
Which ONNX Runtime execution providers the neural pipeline can and does use.
Returns {"model", "available_providers", "active_providers"}: model is the
joint model's dataset name (the pinned grc-joint release asset);
available_providers is what the installed onnxruntime offers (None when the
[neural] extra is not installed); active_providers is what the live joint
session actually runs on (session.get_providers()), or None when the
pipeline is not active. Never fetches, never raises for a missing extra.
The published benchmark numbers are measured on CPUExecutionProvider; GPU
execution (PYAEGEAN_ORT_PROVIDERS, or auto-detected CUDA/DirectML) is a
throughput convenience, and the int8-quantized models may partition only partially
onto a GPU provider.
use_neural_pipeline ¶
Activate the neural pipeline (tags + morphology + trees + lemmas, one model).
Fetches the model bundle to the cache on first use — never bundled in the wheel —
then loads it via onnxruntime. Requires the [neural] extra
(pip install 'pyaegean[neural]'). Once active, aegean.greek.pos_tags /
pos_tag, aegean.greek.parse (UD relations), and aegean.greek.lemmatize
all use it; analyze_sentence returns the full joint analysis in one call.
Raises NeuralPipelineNotLoadedError if the optional dependencies are missing
(checked before any download), and aegean.data.DataNotAvailableError if the
download fails (set PYAEGEAN_GRC_JOINT_URL to fetch from your own mirror).
annotate_corpus ¶
annotate_corpus(corpus: 'Corpus', *, tag_sentence: TagSentence | None = None, with_evidence: bool = True, progress: Callable[[int, int], None] | None = None) -> 'Corpus'
Return a copy of corpus with each word token's lemma / upos annotations
filled by the pipeline (and, when with_evidence, lemma_source / lemma_known).
tag_sentence overrides the tagger (a forms -> [(lemma, upos)] callable); it carries
no evidence class, so lemma_source is written only by the built-in paths. The default
is the active pipeline: the neural joint model if loaded, else the offline lemmatize + POS
baseline. Existing annotations on a token are preserved except for the keys written here.
progress is called as progress(done, total) once per document (a large corpus under
the neural pipeline is a long run).
disable_calibration ¶
Unload the active calibration; the joint model then refuses to surface confidence.
ece ¶
Expected Calibration Error via equal-width binning (Guo et al., 2017).
probs are per-item top-1 confidences in [0, 1]; correct are the matching
0/1 outcomes (whether the surfaced prediction was right). Each item is placed in one
of n_bins equal-width bins over [0, 1] (a confidence of exactly 1.0 falls in
the last bin); the ECE is the sample-weighted mean absolute gap between each bin's
mean confidence and its empirical accuracy. 0 means perfectly calibrated. An empty
input is defined as 0.0.
fit_temperature ¶
fit_temperature(logits: Any, correct: Any, *, bracket: tuple[float, float] = (0.05, 20.0), np: '_np_t | None' = None) -> float
Fit the scalar temperature T that best calibrates a head's top-1 confidence.
logits is a 2-D [n_items, n_classes] array of a head's raw logits; correct
is a length-n_items 0/1 array of whether the surfaced (argmax) prediction was
right. T is chosen to minimize the binary negative log-likelihood of the
top-1 confidence softmax(z / T).max() against correct — i.e. it directly
calibrates the one number pyaegean surfaces. Overconfident heads (the usual case) fit
T > 1 (flattening the distribution lowers confidence toward the observed
accuracy); a well-calibrated head fits T ≈ 1.
The optimization is a coarse geometric grid over bracket (robust to a
non-unimodal objective) followed by a golden-section refine around the grid minimum —
no scipy. Returns a strictly-positive float.
Raises ValueError on an empty fold, a shape mismatch, non-finite logits, or an
invalid bracket.
temperature_softmax ¶
Numerically-stable softmax over the last axis after dividing by temperature.
temperature must be strictly positive; it only rescales the distribution's
sharpness and never moves the argmax. logits may be 1-D (a single row) or 2-D
[n_items, n_classes]; the returned probabilities have the same shape and sum to
1 along the last axis. Pass np to reuse an already-imported numpy module (the
joint model does this in its decode loop).
top1_confidence ¶
The top-1 (max) softmax probability per row, temperature-scaled.
This is the single number pyaegean surfaces as a prediction's confidence: once the
temperature is calibrated, it estimates the probability the argmax prediction is
correct. 1-D logits return a scalar; 2-D [n_items, n_classes] return a length-
n_items array. The argmax is unchanged by temperature (see
temperature_softmax), so this only rescales the confidence, never the label.
use_calibration ¶
use_calibration(source: 'str | Path | Calibration | dict[str, Any] | None' = None) -> Calibration
Load a calibration and make it the active one, so the joint model may surface calibrated confidence.
source is a Calibration, a path to a JSON file (save's format), a to_dict
mapping, or None for the bundled default calibration (shipped in the wheel). The
no-arg form raises UncalibratedConfidenceError only when that file cannot be loaded
(a missing or corrupt install), never a raw softmax. Returns the loaded Calibration.
missing_forms ¶
missing_forms(corpus: 'Corpus', *, limit: int = 0) -> list[MissingForm]
The distinct Greek word forms the active lemmatizer cannot resolve, most frequent first.
Walks every lexical (WORD) token of corpus, lemmatizes each with
aegean.greek.lemmatize_sourced, and keeps the forms whose evidence class needs review
(aegean.greek.needs_review: UNRESOLVED or IDENTITY). Returns one MissingForm
per distinct surface form with its total count and its first attestation, sorted by
descending count then by form so the order is stable. limit caps the number of rows
returned; 0 (the default) returns all of them.
Read-only (the corpus is never mutated) and zero-dependency. Each distinct form is lemmatized once and the verdict cached, so the cost is one lemmatize per distinct word. The result reflects whichever lemmatizer is active: the offline baseline by default, or a loaded neural / treebank backend.
explain_pipeline ¶
explain_pipeline(text: str, *, with_confidence: bool = False) -> list[TokenExplanation]
Analyze text with pipeline and explain each token's record.
Returns one TokenExplanation per token, in pipeline order: the surface
form, UPOS, lemma, the lemma's evidence class with a plain-language note,
whether it needs review, and the morphology (FEATS) when the neural
pipeline filled it. Derived entirely from the TokenRecord fields
pipeline returns, so it reflects exactly the backends that were active
for that call (activate them first with the use_* functions). Empty
or whitespace-only input yields an empty list.
The evidence class is the honesty surface. with_confidence=True (opt-in)
additionally appends each token's calibrated confidence to its note — it
requires the neural pipeline active and a loaded calibration
(aegean.greek.use_calibration), and raises UncalibratedConfidenceError
otherwise; a raw softmax is never shown. Only model predictions carry a
number (lookup-resolved / identity / punctuation lemmas do not).
render_explanations ¶
render_explanations(explanations: Sequence[TokenExplanation]) -> str
Render explanations as an aligned plain-text table for terminal display.
Columns: token, upos, lemma, source, review, morphology, note. The
review cell reads review for a token to verify and stays blank for
a grounded one; morphology is blank when the record carried none.
Returns "(no tokens)" for an empty list.
profile_text ¶
profile_text(text: str) -> TextProfile
Compute the observable feature profile of text.
Reports measured features only (script blocks, polytonic vs bare, Beta Code
look, majuscule share, editorial markers, numeral density) and never predicts
a genre or an out-of-domain label. An empty string yields an all-zero profile
with script="other".
analyze_errors ¶
analyze_errors(tag_sentence: TagSentence, sentences: Sequence[Sequence[HeldoutToken]], *, samples: int = 40, freq: Callable[[str], int] | None = None) -> ErrorAnalysis
Run tag_sentence over gold sentences and tabulate the errors.
Only tokens flagged scored count (PUNCT/NUM excluded, as everywhere). The predicted
lemma is cleaned (_clean_lemma) before comparison, matching the aggregate scorers, and
the gold lemma is already cleaned by the gold builder. tag_sentence and the gold are
expected to already agree on POS convention (the adapters reconcile both sides). freq,
when given, maps a form to a corpus frequency for per-band accuracy.
heldout_error_analysis ¶
heldout_error_analysis(tag_sentence: TagSentence | None = None, *, holdout: float = 0.1, source_dir: str | None = None, samples: int = 40) -> ErrorAnalysis
Error analysis on the leakage-free AGDT held-out split — the one source with a real
seen/unseen contrast (so the seen/unseen figures are substantive here). Defaults to the
active pipeline; disable the treebank backend first to avoid leakage (see
aegean.greek.heldout).
nt_error_analysis ¶
nt_error_analysis(tag_sentence: TagSentence | None = None, *, corpus: Any = None, book: str | None = None, samples: int = 40) -> ErrorAnalysis
Error analysis on the Nestle-1904 NT gold (out-of-domain Koine). Defaults to the neural
joint pipeline, exactly like evaluate_on_nt.
proiel_error_analysis ¶
proiel_error_analysis(tag_sentence: TagSentence | None = None, *, source_dir: Any = None, files: tuple[str, ...] | None = None, samples: int = 40) -> ErrorAnalysis
Error analysis on the PROIEL Greek treebank (out-of-AGDT). Same tagger/reconciliation
as evaluate_on_proiel.
ud_error_analysis ¶
ud_error_analysis(tag_sentence: TagSentence | None = None, *, treebank: str = 'perseus', split: str = 'test', source: Any = None, samples: int = 40) -> ErrorAnalysis
Error analysis on a UD Ancient Greek fold (default UD-Perseus test). Unlike
evaluate_on_ud (which scores raw UPOS with the official evaluator), this reconciles POS
on both sides so per-POS reads as real disagreement; treat it as a diagnostic, not the
headline number. Defaults to the active pipeline (neural if loaded, else baseline).
evaluate_on_proiel ¶
evaluate_on_proiel(tag_sentence: TagSentence | None = None, *, source_dir: Path | str | None = None, files: tuple[str, ...] = _GREEK_FILES, progress: Callable[[int, int], None] | None = None) -> dict[str, float]
Score a tagger on PROIEL gold — the neutral, out-of-AGDT generalization number.
tag_sentence maps a sentence's forms to (lemma, pos) per token; it defaults to
pyaegean's current pipeline (lemmatize + pos_tag, honouring whichever backends
are active — enable use_treebank/use_neural_lemmatizer first to measure them).
progress (optional) is called as progress(done, total) per scored sentence.
Returns {"lemma", "pos", "n"}: lemma and POS accuracy over the scored tokens. Lemma
is the clean metric; POS is compared under a reconciled tagset (PROPN→NOUN, SCONJ→CCONJ).
See proiel_drift for where the gap comes from. The PROIEL files are fetched on first
use unless source_dir points at local XML.
load_proiel_gold ¶
load_proiel_gold(*, source_dir: Path | str | None = None, files: tuple[str, ...] = _GREEK_FILES) -> tuple[tuple[HeldoutToken, ...], ...]
Parse the PROIEL Greek treebank into gold sentences of (form, lemma, POS) tokens.
Fetches the pinned PROIEL files into the cache unless source_dir is given (tests
pass a local fixture for an offline run). Empty tokens are dropped, lemmas cleaned
(#N homograph suffix removed), and POS mapped to pyaegean's tagset convention.
Every token is flagged seen=False — PROIEL is wholly outside pyaegean's training.
proiel_convention_report ¶
proiel_convention_report(*, split: str = 'test', source: Path | str | None = None, batch_size: int | None = 32, progress: Callable[[int, int], None] | None = None, predictions: Sequence[Sequence[_ConvToken]] | None = None) -> ConventionReport
Decompose the PROIEL UD-fold UFeats and LAS gaps into annotation-convention divergence versus real disagreement, on the neural pipeline's own outputs.
Runs the active neural pipeline (aegean.greek.use_neural_pipeline — the model behind the
published UD-PROIEL numbers) over the fold's gold tokens and compares its FEATS/HEAD/DEPREL
to gold. Returns a ConventionReport whose ufeats/uas/las reproduce the
official metrics from the model's outputs, split into: the UFeats gap's scheme-absent vs
shared-disagreement parts (with a per-feature-type table), and the LAS gap's
attachment-correct/label-wrong mass (with the gold→predicted relation confusions). This is
a measurement DECOMPOSITION: it changes no published number and fits nothing to the fold.
source overrides the UD-PROIEL fold path (tests pass a local CoNLL-U fixture);
batch_size batches the encoder passes (a throughput convenience — the diagnostic does
not feed the recorded sequential protocol); progress is called progress(done,
total) per sentence. predictions injects the system outputs directly (one
(feats, head, deprel) per gold token, sentence-aligned) so the decomposition can be
exercised without the model; with it, no pipeline is required.
proiel_dir ¶
The cache directory of PROIEL Greek XML files, fetching any missing on first use. The data is CC BY-NC-SA 3.0 — kept in the cache for evaluation only, never bundled.
proiel_drift ¶
proiel_drift(tag_sentence: TagSentence | None = None, *, source_dir: Path | str | None = None, files: tuple[str, ...] = _GREEK_FILES, samples: int = 40) -> DriftReport
Quantify where the PROIEL gap comes from, so systematic annotation-convention divergence can be separated from scattered real error.
Re-tags the PROIEL gold with the same (reconciled) tagger evaluate_on_proiel uses and
returns a DriftReport: the gold→predicted POS confusion matrix (most-frequent first), a
sample of lemma mismatches, and the scored counts. A few confusion pairs carrying most of
the POS errors (high top_share) suggests a convention difference rather than real
error. tag_sentence and source_dir are as for evaluate_on_proiel.
This is now a thin PROIEL view of the shared aegean.greek.erroranalysis engine (which
also serves UD-Perseus, the NT, and the AGDT held-out split, and carries richer per-POS /
seen-unseen breakdowns): see erroranalysis.proiel_error_analysis for the full report.
agdt_ud_overlap ¶
agdt_ud_overlap(*, splits: tuple[str, ...] = ('dev', 'test'), source: Path | str | None = None, agdt_source: Path | str | None = None, verify: bool = True, write: bool = True) -> dict[str, Any]
Build the AGDT ↔ UD-Perseus leakage-exclusion manifest.
UD Perseus sentence ids are <agdt-file>@<sentence-id> — direct references into the
AGDT source pyaegean trains on. This collects every AGDT sentence appearing in the
given UD splits (default: dev + test, the folds that must stay unseen), verifies
the reference by comparing NFC form sequences against the actual AGDT files, caches
the manifest as JSON, and returns it. Every Stage A+ training split must exclude
these sentences — see docs/benchmarks.md.
source overrides the UD fold path(s) and agdt_source the AGDT directory (used
by offline tests); with defaults, both fetch to the cache on first use.
bootstrap_ud ¶
bootstrap_ud(treebank: str = 'perseus', split: str = 'test', *, metrics: Sequence[str] = ('upos', 'xpos', 'ufeats', 'lemma', 'uas', 'las'), n_resamples: int = 999, level: float = 0.95, seed: int = 0, source: Path | str | None = None, parse: bool | None = None) -> dict[str, BootstrapCI]
Percentile bootstrap CIs for :func:evaluate_on_ud's metrics, over the fold's sentences.
The active pipeline runs once over the fold; each of n_resamples draws re-scores a
sentence resample (with replacement) with the official evaluator. Sentences are the
resampling unit — tokens within a sentence are not independent. Activate the same backends
you would for :func:evaluate_on_ud; with no parser active, uas/las are dropped.
The band is sampling variability given this fold — read the module docstring's leakage
caveat before quoting the Perseus fold for an AGDT-trained model.
evaluate_by_genre ¶
evaluate_by_genre(treebank: str = 'perseus', split: str = 'test', *, metrics: Sequence[str] = ('upos', 'lemma', 'uas', 'las'), bootstrap: bool = True, n_resamples: int = 999, level: float = 0.95, seed: int = 0, source: Path | str | None = None, parse: bool | None = None, min_sentences: int = 20, progress: Callable[[int, int], None] | None = None, batch_size: int | None = None) -> dict[str, dict[str, Any]]
Score the active pipeline on a UD fold, sliced by literary genre.
Each sentence is bucketed by its sent_id author (a TLG id, mapped through
_AUTHOR_GENRE to epic / tragedy / comedy / prose / other). The pipeline runs once
over the whole fold; each genre is then scored with the official evaluator (and, when
bootstrap, given a percentile CI). Returns {genre: {"n_sentences", "n_words",
"authors", "thin" (True undermin_sentences), <metric>: value or BootstrapCI}} plus an
"_unmapped" list of author ids not in the table (the built-in discovery step: run this
before pinning any numbers, and extend _AUTHOR_GENRE from it).
This is meaningful only for the leakage-clean neural model on Perseus: the offline baseline
has seen the Perseus test sentences (see the module leakage caveat), so do not publish genre
slices for it. uas/las are dropped when no parser is active. progress and
batch_size thread through to pipeline_conllu; the recorded protocol stays the
sequential default.
evaluate_on_ud ¶
evaluate_on_ud(treebank: str = 'perseus', split: str = 'test', *, source: Path | str | None = None, parse: bool | None = None, progress: Callable[[int, int], None] | None = None, batch_size: int | None = None) -> dict[str, Any]
Score the active pipeline on a UD Ancient Greek fold with the official evaluator.
Runs over the fold's gold tokens (gold-tokenization protocol), emits CoNLL-U, and
scores it against the gold file with conll18_ud_eval. Activate the backends you
want measured first (use_treebank, use_tagger, use_lemmatizer,
use_neural_lemmatizer, use_parser). parse defaults to whether the parser
is active; with parse=False UAS/LAS are returned as None. progress
(optional) is called as progress(done, total) per analyzed sentence.
batch_size (optional) batches the neural pipeline's encoder passes (see
pipeline_conllu) — a throughput convenience; the recorded protocol behind every
published number is the sequential default.
Returns {"upos", "lemma", "uas", "las", "n_words", "n_sentences", "treebank",
"split", "parsed"} — accuracies in [0, 1]. Read the module docstring's leakage
caveat before quoting the Perseus fold for an AGDT-trained model.
evaluate_on_papygreek ¶
evaluate_on_papygreek(*, layer: str = 'reg', source: Path | str | None = None, parse: bool | None = None, progress: Callable[[int, int], None] | None = None, batch_size: int | None = None) -> dict[str, Any]
Score the active pipeline on the PapyGreek documentary-Koine fold (official evaluator).
Reuses aegean.greek.ud's machinery wholesale — ud.load_conllu, ud.pipeline_conllu
(gold tokenization, the neural encoder pass, optional batching), the fetched official
conll18_ud_eval (ud._eval_module), and its scorer (ud._score_conllu_text) — so
this fold is measured byte-for-byte the same way as UD-Perseus/PROIEL; only the gold data
and the "treebank" label differ. Activate the backends you want measured first
(use_neural_pipeline for the shipped model). parse defaults to whether a parser/joint
model is active; with parse=False UAS/LAS/CLAS are None. progress is called as
progress(done, total) per analyzed sentence; batch_size batches the neural
encoder's passes (a throughput convenience — the recorded protocol is the sequential
default). source overrides the fold path (tests pass a local CoNLL-U).
layer selects which fold is fetched when source is not given: "reg" (the
default, the editorially regularized reading behind the published PapyGreek numbers) or
"orig" (the diplomatic-surface variant — the same sentences and gold, the raw
documentary orthography as the FORM; see papygreek_orig_path). The orig fold measures the
same model against a harder input and is directly comparable to the reg row.
Returns {"treebank", "split", "layer", "parsed", "upos", "xpos", "ufeats", "lemma",
"uas", "las", "clas", "n_words", "n_sentences"} — accuracies in [0, 1]. The fold is
leakage-clean for the shipped model (see the module docstring).
evaluate_on_papygreek_dev ¶
evaluate_on_papygreek_dev(track: str = 'tagging', *, source: Path | str | None = None, parse: bool | None = None, progress: Callable[[int, int], None] | None = None, batch_size: int | None = None) -> dict[str, Any]
Score the active pipeline on a PapyGreek documentary-Koine DEV track (official evaluator).
The dev fold is document-disjoint from the pinned papygreek test fold and exists to
rank levers and catch regressions without touching the test fold — it yields no
published number and nothing is fitted against the test fold. Reuses the exact _score_fold
machinery evaluate_on_papygreek uses; only the gold data (a dev track) differs.
track is "tagging" — annotated surface tokens of the non-fold artificial/partial
sentences, scored for UPOS/XPOS/UFeats/lemma (parse forced False; its trees are
placeholders, UAS/LAS meaningless) — or "parse" — the reattached single-artificial-node
sentences, scored for UAS/LAS (parse defaults to whether a parser/joint model is active;
the track is thin, treat its parse numbers as directional). source overrides the track
path (tests pass a local CoNLL-U for an offline run). progress and batch_size are as
for evaluate_on_papygreek.
Returns the same key set as evaluate_on_papygreek, with "split" set to the track
name.
papygreek_convention_report ¶
papygreek_convention_report(*, source: Path | str | None = None, batch_size: int | None = None, progress: Callable[[int, int], None] | None = None, predictions: Sequence[Sequence[_PapyToken]] | None = None) -> PapyGreekConventionReport
Decompose the PapyGreek UPOS and XPOS gaps into annotation/encoding convention versus real error, on the neural pipeline's own outputs.
Runs the active neural pipeline (aegean.greek.use_neural_pipeline — the model behind the
published PapyGreek numbers) over the fold's gold tokens and compares its UPOS/XPOS to gold.
Returns a PapyGreekConventionReport whose upos/xpos reproduce the official metrics
from the model's outputs, split into the coordinator / common-gender / _-encoding
convention parts and the residual real error. This is a measurement DECOMPOSITION: it
changes no published number and fits nothing to the fold.
batch_size defaults to None (sequential, unlike proiel_convention_report): the
published PapyGreek numbers are the sequential run and batch-32 is not prediction-identical
on this fold, so a sequential pass is needed to reproduce them exactly. source overrides
the fold path (tests pass a local CoNLL-U fixture); progress is called progress(done,
total) per sentence. predictions injects the system outputs directly (one
(upos, xpos) per gold token, sentence-aligned) so the decomposition can be exercised
without the model; with it, no pipeline is required.
papygreek_dev_path ¶
The cached CoNLL-U path of a PapyGreek DEV track, fetched + decompressed on first use.
track is "tagging" (UPOS/XPOS/UFeats/lemma over annotated surface tokens) or
"parse" (UAS/LAS over the reattached artificial-node sentences). The dev fold is
document-disjoint from the pinned test fold and is for experiment/lever ranking only — it
yields no published number and is never fitted against the test fold. CC BY-SA 4.0 — cached
for evaluation only, never bundled.
papygreek_orig_path ¶
The cached CoNLL-U path of the PapyGreek ORIG (diplomatic) test fold, fetched + decompressed on first use.
The diplomatic-surface variant of papygreek_path: the same 1,696 sentences and the
same gold columns (UPOS/XPOS/UFeats/lemma/head/deprel), with the emitted FORM swapped
to the raw documentary orthography (itacism, phonetic spelling, non-standard breathing) that
the orig layer preserves. The two folds are token-aligned line-for-line and differ only
in the surface form, so the orig row isolates the effect of the harder orthography. Built by
scripts/build_papygreek_fold.py --layer orig. See _fetch_conllu for the
fetch/decompress/stamp mechanics. CC BY-SA 4.0 — cached for evaluation only, never
bundled.
papygreek_path ¶
The cached CoNLL-U path of the PapyGreek test fold, fetched + decompressed on first use.
The release asset is a gzipped CoNLL-U file (papygreek-fold). See _fetch_conllu for
the fetch/decompress/stamp mechanics. CC BY-SA 4.0 — cached for evaluation only, never
bundled.
dbbe_path ¶
The cached CoNLL-U path of the DBBE Byzantine book-epigram tagging fold, fetched + decompressed on first use.
The release asset is a gzipped CoNLL-U file (dbbe-lingann-fold). Fetched via the shared
aegean.data.fetch_text (capped decompress, atomic write, and the .sha256 stamp sidecar
that makes a re-pinned asset re-extract instead of serving a stale copy). expect_gzip=True
so a non-gzip body (a corrupt or swapped download) refuses rather than materializing as the
fold. CC BY 4.0 — cached for evaluation only, never bundled.
evaluate_on_dbbe ¶
evaluate_on_dbbe(*, source: Path | str | None = None, progress: Callable[[int, int], None] | None = None, batch_size: int | None = None) -> dict[str, Any]
Score the active pipeline's tagging on the DBBE Byzantine book-epigram fold (official evaluator).
Reuses aegean.greek.papygreek._score_fold wholesale — which in turn reuses
aegean.greek.ud's machinery (ud.load_conllu, ud.pipeline_conllu, the fetched official
conll18_ud_eval and its scorer) — so this fold is measured byte-for-byte the same way as
UD-Perseus/PROIEL and PapyGreek; only the gold data and the "treebank" label differ.
Activate the backends you want measured first (use_neural_pipeline for the shipped model).
Tagging only. The DBBE gold standard carries no dependency trees, so parse is forced
False: the result reports UPOS/XPOS/UFeats/lemma and UAS/LAS/CLAS are None. progress
is called as progress(done, total) per analyzed sentence; batch_size batches the neural
encoder's passes (a throughput convenience — the recorded protocol is the sequential default).
source overrides the fold path (tests pass a local CoNLL-U).
The score reads low by construction (see the module docstring: Attic-lemma normalization,
the mapped tagset, copular εἰμί without tree context), and it is a small, single-register
datapoint — a Byzantine-verse row, never a headline number.
Returns {"treebank", "split", "parsed", "upos", "xpos", "ufeats", "lemma", "uas", "las",
"clas", "n_words", "n_sentences"} — the tagging accuracies in [0, 1], the parse metrics
None.
evaluate_on_verse ¶
evaluate_on_verse(track: str | None = None, *, source: Path | str | None = None, parse: bool | None = None, progress: Callable[[int, int], None] | None = None, batch_size: int | None = None) -> dict[str, Any]
Score the active pipeline on the Ancient Greek verse fold (official evaluator).
Reuses aegean.greek.ud's machinery wholesale — ud.load_conllu, ud.pipeline_conllu
(gold tokenization, the neural encoder pass, optional batching), the fetched official
conll18_ud_eval (ud._eval_module), and its scorer (ud._score_conllu_text) — so
this fold is measured byte-for-byte the same way as UD-Perseus/PROIEL and PapyGreek;
only the gold data and the labels differ. Activate the backends you want measured first
(use_neural_pipeline for the shipped model).
track selects "tragedy" (Euripides, Bacchae 1-169), "hexameter" (Maximus,
Peri katarchon 1.4), or None for both. parse defaults to whether a parser/joint
model is active; with parse=False UAS/LAS/CLAS are None. progress is called
as progress(done, total) per analyzed sentence; batch_size batches the neural
encoder's passes (a throughput convenience — the recorded protocol is the sequential
default). source overrides the fold path (tests pass a local CoNLL-U).
Returns {"treebank", "track", "split", "parsed", "upos", "xpos", "ufeats", "lemma",
"uas", "las", "clas", "n_words", "n_sentences"} — accuracies in [0, 1].
This is a SMALL-SAMPLE genre-conditioned datapoint with wide bootstrap confidence intervals (tens of sentences per track); the tragedy track is the first leakage-clean tragedy evaluation anywhere and the hexameter track is directional only. It is never a headline number — report it with the sample size and CI, not on its own.
verse_path ¶
The cached CoNLL-U path of the verse fold, fetched + decompressed on first use.
The release asset is a gzipped CoNLL-U file (verse-fold) holding both tracks
(verse:tragedy:... + verse:hexameter:...). See _fetch_conllu for the fetch/
decompress/stamp mechanics. This fold is a small-sample genre-conditioned datapoint
with wide bootstrap CIs, never a headline number — CC BY-SA 4.0, cached for evaluation
only, never bundled.
betacode_to_unicode ¶
Convert a Beta Code string to precomposed (NFC) polytonic Greek.
A backtick escapes the character after it (unicode_to_betacode uses this
to protect literal reserved markup), so `( emits a literal (
rather than a smooth breathing.
strip_diacritics ¶
Remove all combining diacritics (accents, breathings, subscripts), keeping the base letters. Returns NFC.
unicode_to_betacode ¶
Convert polytonic Greek to Beta Code (capitals as *; final sigma as
s). Round-trips with betacode_to_unicode: any literal ASCII that Beta
Code reserves as markup (( ) / \ = + | * and the s1/s2/s3
sigma digits, plus the backtick escape itself) is backtick-escaped, so Greek
text with embedded parentheses, arithmetic, or other punctuation survives
the trip unchanged. (ASCII letters are Beta Code's own alphabet, so plain
Latin words are read back as Greek; this maps Greek, not mixed prose.)
Lunate sigma (ϲ U+03F2 / Ϲ U+03F9) is a display variant of sigma and is
normalized to a standard sigma (s) here, so it converts cleanly but does
not round-trip back to the lunate glyph. The combining length marks (macron
U+0304, breve U+0306, the lexicon vowel-quantity notation) have no Beta Code
representation: text carrying them does not round-trip and, next to an accent,
can perturb the accent's placement, so keep them out of Beta Code round-trips
(the analysis functions, syllabify/scansion, handle them directly).
gloss_nt ¶
Brief Koine gloss for a word (lemmatized on a miss); requires use_dodson.
gloss_strongs ¶
Brief Koine gloss for a Strong's number (e.g. 3056 -> 'a word, speech, …');
requires use_dodson. The NT corpus tokens carry these numbers in
Token.annotations['strongs'].
lookup_nt ¶
lookup_nt(word: str) -> DodsonEntry | None
Full Dodson entry for a word; requires use_dodson. None if unknown.
use_dodson ¶
Activate Dodson Koine glossing for this session (loads the bundled lexicon).
No download — the lexicon is bundled (CC0). gloss_nt / lookup_nt /
gloss_strongs resolve against it afterwards.
entry ¶
entry(word: str, *, dictionary: str | None = None) -> LexEntry | None
The full LexEntry for word from dictionary (or the first active
lexicon that has it).
gloss ¶
A concise gloss for word from dictionary (or the first active lexicon
that has it). With no active lexicon, raises LexiconNotLoadedError.
lexica ¶
lexica() -> list[LexiconInfo]
Every registered lexicon's metadata (hosted and deep-link), id-sorted.
lexicon_link ¶
A deep-link to word in an online dictionary aggregator (Logeion by default).
Covers the lexica pyaegean does not host (Autenrieth, Slater, Montanari, DGE,
Bailly, ...): Logeion aggregates them. lemmatize (default) links the lemma.
use_lexicon ¶
Activate a hosted lexicon by id, fetching/building its index on first use.
evaluate_on_nt ¶
evaluate_on_nt(tag_sentence: TagSentence | None = None, *, corpus: Corpus | None = None, book: str | None = None, progress: Callable[[int, int], None] | None = None, batch_size: int | None = None) -> dict[str, float]
Score a tagger on the Nestle1904 Greek NT gold — lemma + reconciled UPOS accuracy.
tag_sentence maps a sentence's forms to (lemma, upos) per token; it defaults to
the neural joint pipeline (enable greek.use_neural_pipeline() first), so the
number reflects the shipped model. corpus supplies the gold (defaults to
greek.load_nt(book) — the whole NT, or one book). progress (optional) is
called as progress(done, total) per scored verse — the whole-NT run is ~1 h on
plain CPU, so this is how the CLI shows it moving. batch_size (optional) runs the
default neural tagger's encoder over that many verses at a time (one ONNX call per
chunk) — a throughput convenience; the recorded protocol (the published numbers) is
the sequential default, and with a caller-supplied tag_sentence the value has no
effect. Returns {"lemma", "upos", "n"}: accuracy over the scored tokens. Lemma is
the clean metric; UPOS is compared under a reconciled tagset, mirroring
evaluate_on_proiel.
catalog ¶
catalog(query: str | None = None, *, author: str | None = None, title: str | None = None, source: str | None = None) -> list[dict[str, str]]
Search the full bundled index of Greek works loadable with :func:load_work.
Unlike :func:popular_works (25 curated highlights), this covers every work with a
Greek (-grc) edition in Perseus canonical-greekLit + First1KGreek — ~1,800 works.
Each entry is {'id', 'author', 'title', 'greek_title', 'source'}; pass any id
straight to load_work. Pure bundled metadata — no network, no download.
All filters are case-insensitive substring matches and combine with AND:
query— matches across id, author, English title, and Greek title (the catch-all)author— e.g."plato"title— matches the English or Greek titlesource—"perseus"or"first1k"
Returns a list of dicts; pure bundled metadata, so it works offline and is instant.
fetch_works ¶
fetch_works(author: str | None = None, *, works: list[dict[str, str]] | None = None, source: str | None = None, force: bool = False, limit: int | None = None, on_progress: Callable[[int, int, dict[str, str]], None] | None = None, abort: Callable[[], bool] | None = None) -> Iterator[WorkFetchResult]
Fetch every catalogue work matching author into the cache, yielding a
:class:WorkFetchResult per work as it completes.
Shared by the CLI (greek work all) and the TUI works screen. works overrides the
catalogue query (pass a pre-filtered list). Already-cached works are yielded "cached" with
no network, so re-running resumes idempotently. on_progress(i, total, work) fires BEFORE
each work (a UI "downloading…" cue). limit caps NEW downloads (cached works do not count).
abort() is polled between works.
Terminal conditions raise, so the caller learns why the batch stopped:
:class:GitHubRateLimitError (API exhausted), :class:aegean.data.FetchAborted (aborted), or
:class:aegean.data.DataNotAvailableError (stopped after too many consecutive failures).
list_fetched_works ¶
Which Greek works are already downloaded to the cache — a pure local scan, no network.
Walks cache_dir()/greek-works/<source>/<commit>/*.xml, recovers each CTS id from the
edition filename (tlg0012.tlg001.perseus-grc2.xml -> tlg0012.tlg001), and joins the
bundled catalogue for author/title. Returns [{'id','author','title','source','path','bytes'}]
sorted by id (one entry per work, even if present under several sources/commits); [] when
nothing is cached. Ignores the listings/ cache and any .part/.lock files.
citation_scheme ¶
citation_scheme(work: str, *, source: str = 'auto', edition: str | None = None, force: bool = False) -> list[str]
How a Greek work is addressed: its ordered citation levels, from the TEI edition.
Reads the work's declared CTS <refsDecl> and returns the citation levels
shallow→deep, exactly as the edition names them (no author-specific guessing):
the Iliad → ["book", "line"], a Plato dialogue → ["section"], Xenophon's
Anabasis → ["book", "chapter", "section"], Aristotle's Poetics →
["chapter", "subchapter"]. So ["book", "line"] means a --ref looks
like 1 (a whole book) or 1.1 / 1.1-1.50 (a line or line-range within a
book); a single-level ["section"] means --ref 17 (one section).
Returns [] when the work declares no CTS refsDecl. Like load_work, the
TEI file is fetched once to the cache (source/edition/force as there);
this is metadata about the edition, not its text. It reports the CTS <div>
levels the edition declares. Finer references some editions print in the margin (a
Stephanus sub-page 17a, a Bekker line 1447a10) live in <milestone>
markers outside the CTS scheme, so they are not part of the returned levels — but
load_work's ref does resolve them directly (it extracts the span between the
marker and the next).
load_work ¶
load_work(work: str, *, ref: str | None = None, source: str = 'auto', edition: str | None = None, force: bool = False) -> 'Corpus'
Load one Greek work from Perseus canonical-greekLit / First1KGreek.
work is the CTS-style id ("tlg0012.tlg001" = the Iliad). source
is "perseus", "first1k", or "auto" (try both, in that order);
edition picks a specific edition file when a work has several. The TEI
file is fetched once into the cache (network on first use only).
ref selects a sub-section instead of the whole work — a citation address
matching the work's structure: a textpart number ("1" = Iliad book 1),
a nested div path ("1.2" = book 1, chapter 2 of a prose work), a verse
line-range ("1.1-1.50" = book 1, lines 1–50), a marginal <milestone>
marker outside the CTS <div> scheme (a Stephanus sub-page "17a", a Bekker
line "1447a10" or a whole Bekker page "1447a"), or a comma list of any of
these ("1.1,1.5", "1,3", "17a,17b") giving one Document per entry. A
hyphen range must stay within a single textpart: "1.1-2.50" (crossing from book 1
into book 2) raises ValueError; use a comma list, or load each book separately and
Corpus.merge the results. Without ref, the corpus is one Document per
top-level textpart. The corpus provenance's citation is the canonical
scholarly citation of exactly what was selected ("Homer, Iliad 1.1-1.50"; see
canonical_citation), so corpus.cite() echoes the selection.
<note>/<bibl> ride along in Document.meta.notes. Raises
aegean.data.DataNotAvailableError when the work can't be found/fetched, or
ValueError when ref matches nothing — that message names the work's declared
citation scheme (cited by book.line); citation_scheme returns it directly.
popular_works ¶
A curated, verified catalog of well-known Greek works loadable with :func:load_work.
Each entry is {'id', 'author', 'title'} where id is the CTS id passed to
load_work (e.g. 'tlg0012.tlg001' → the Iliad). This is a deliberately small
starting point — for the full reachable canon use :func:catalog, or browse the
Scaife Viewer (https://scaife.perseus.org). Pure metadata — no download.
remove_fetched_works ¶
remove_fetched_works(ids: list[str] | None = None, *, author: str | None = None, remove_all: bool = False) -> list[str]
Delete downloaded Greek works from the cache, returning the ids actually removed (sorted).
Select the targets one of three ways: explicit ids; every fetched work by an author
(case-insensitive substring of the catalogue author, the same match as greek catalog
--author); or remove_all. A no-op returning [] when nothing matches or nothing is
cached. Removes every cached edition file for each targeted work (across sources/commits) and
prunes the now-empty source/commit directories. Never touches the listings/ cache.
load_nt ¶
Load the Greek New Testament (Nestle 1904) as an annotated Corpus.
book selects one book by name or abbreviation ('John', 'Jn', '1Cor',
'Rev'); None returns the whole NT. ref selects within a book, mirroring
load_work: '3' a chapter, '3.16' a verse, '3.16-3.18' / '3.16-18' a
verse range, '3-5' a chapter range. One Document per chapter; every token carries
a gold lemma, Robinson morph, Strong's number, reconciled UD upos, and the
normalized form in Token.annotations. Token text, lemmas, and normalized forms are
NFC-normalized at load time (the source edition mixes oxia and tonos precomposition),
so gold strings compare byte-for-byte with the library's NFC output.
The full 27-book corpus is fetched to cache on first use (sha256-pinned CC0 asset, or
PYAEGEAN_NT_CORPUS_URL). When that asset is unavailable the bundled sample
(John 1 + Philemon) is used as an offline fallback (its provenance says so).
nt_books ¶
The 27 books of the Greek New Testament, in canonical order.
Each entry is {'name': 'John', 'aliases': ['john', 'jn', 'jhn']}. Any of the
name or its aliases is accepted as the book argument to :func:load_nt; the
name is what appears in document ids (e.g. 'John 1'). Pure metadata — no
download — so it works offline and is the answer to "which books can I load?".
syllable_quantities ¶
The metrical quantity of each syllable: "heavy" / "light" /
"common" (in syllable order).
scan_aeolic ¶
scan_aeolic(line: str, line_type: str = 'glyconic') -> LineScansion
Scan an aeolic lyric line against a fixed quantity template.
line_type is one of AEOLIC_LINES — "glyconic", "pherecratean",
"sapphic_hendecasyllable", "adonean", "alcaic_hendecasyllable",
"alcaic_enneasyllable", "alcaic_decasyllable". These are fixed patterns (the
choriamb does not resolve), so the line either matches or it doesn't — ScansionError
is raised on a mismatch (e.g. the wrong syllable count, or a line needing synizesis on a
word not in the lexicon).
scan_hexameter ¶
scan_hexameter(line: str) -> LineScansion
Scan a line of dactylic hexameter (six feet; feet 1–5 dactyl or
spondee, foot 6 — ×), resolving quantities and the main caesura.
Raises ScansionError if the line does not fit (e.g. it needs
synizesis, which is not inferred).
scan_line ¶
scan_line(line: str, meter: str = 'hexameter') -> LineScansion
Scan line against meter ("hexameter" or "pentameter").
scan_pentameter ¶
scan_pentameter(line: str) -> LineScansion
Scan a line of elegiac pentameter: two dactyls-or-spondees, a longum,
the central diaeresis, then two obligatory dactyls and a final longum
(— ⏑⏑ — ⏑⏑ — ‖ — ⏑⏑ — ⏑⏑ —).
Raises ScansionError if the line does not fit.
scan_trimeter ¶
scan_trimeter(line: str) -> LineScansion
Scan a line of iambic trimeter — three metra of x – ⏑ – (the final
element anceps), with resolution of long elements into two shorts.
Raises ScansionError if the line does not fit (e.g. it needs synizesis on
a word not in the lexicon).
syllable_options ¶
(syllable, [possible quantities]) across the whole line — the raw,
pre-metrical analysis, with cross-word position and correptio applied.
to_ipa ¶
Transcribe Greek text to reconstructed IPA. Whitespace-separated
words are transcribed independently and rejoined with spaces.
pos_tag ¶
Tag a single token. Closed classes come from the lexicon; when the treebank
backend is active (see aegean.greek.use_treebank), an attested form's
gold tag is used next; otherwise open-class words get a suffix heuristic (a few
verb endings, else NOUN). Non-letter tokens are NUM (numeric) or PUNCT.
pos_tags ¶
(token, tag) pairs for a text, in order (punctuation tagged PUNCT). When the
trained tagger is active it tags the whole sentence in context, with the
closed-class lexicon and the treebank lookup still taking precedence per token.
sentences ¶
Split into trimmed sentences on Greek sentence-final punctuation.
tokenize_words ¶
Just the word strings, in order (punctuation dropped).