probably_alive and CalcEstDates now share same codebase; rewritten probably_alive
svn: r14102
This commit is contained in:
@ -48,7 +48,7 @@ from ReportBase import ReportUtils
|
||||
from docgen import TextBufDoc
|
||||
from Simple import make_basic_stylesheet, SimpleAccess, SimpleDoc, SimpleTable
|
||||
from QuestionDialog import QuestionDialog
|
||||
from Utils import create_id
|
||||
from Utils import create_id, probably_alive_range
|
||||
import DateHandler
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@ -509,317 +509,9 @@ class CalcToolManagedWindow(PluginWindows.ToolManagedWindowBatch):
|
||||
self.db.add_event(event, self.trans)
|
||||
return event
|
||||
|
||||
def calc_estimates(self, person, is_spouse=False):
|
||||
if person is None:
|
||||
return (None, None, "", None)
|
||||
birth_ref = person.get_birth_ref()
|
||||
death_ref = person.get_death_ref()
|
||||
death_date = None
|
||||
birth_date = None
|
||||
explain = ""
|
||||
# If the recorded death year is before current year then
|
||||
# things are simple.
|
||||
if death_ref and death_ref.get_role().is_primary():
|
||||
death = self.db.get_event_from_handle(death_ref.ref)
|
||||
if death and death.get_date_object().get_start_date() != gen.lib.Date.EMPTY:
|
||||
death_date = death.get_date_object()
|
||||
def calc_estimates(self, person):
|
||||
return probably_alive_range(person, self.db,
|
||||
self.MAX_SIB_AGE_DIFF,
|
||||
self.MAX_AGE_PROB_ALIVE,
|
||||
self.AVG_GENERATION_GAP)
|
||||
|
||||
# Look for Cause Of Death, Burial or Cremation events.
|
||||
# These are fairly good indications that someone's not alive.
|
||||
if not death_date:
|
||||
for ev_ref in person.get_primary_event_ref_list():
|
||||
ev = self.db.get_event_from_handle(ev_ref.ref)
|
||||
if ev and ev.type.is_death_fallback():
|
||||
death_date = ev.get_date_object()
|
||||
explain = _("death-related evidence")
|
||||
|
||||
# If they were born within X years before current year then
|
||||
# assume they are alive (we already know they are not dead).
|
||||
if not birth_date:
|
||||
if birth_ref and birth_ref.get_role().is_primary():
|
||||
birth = self.db.get_event_from_handle(birth_ref.ref)
|
||||
if birth and birth.get_date_object().get_start_date() != gen.lib.Date.EMPTY:
|
||||
birth_date = birth.get_date_object()
|
||||
|
||||
# Look for Baptism, etc events.
|
||||
# These are fairly good indications that someone's birth.
|
||||
if not birth_date:
|
||||
for ev_ref in person.get_primary_event_ref_list():
|
||||
ev = self.db.get_event_from_handle(ev_ref.ref)
|
||||
if ev and ev.type.is_birth_fallback():
|
||||
birth_date = ev.get_date_object()
|
||||
explain = _("birth-related evidence")
|
||||
|
||||
if not birth_date and death_date:
|
||||
# person died more than MAX after current year
|
||||
birth_date = death_date.copy_offset_ymd(year=-self.MAX_AGE_PROB_ALIVE)
|
||||
explain = _("death date")
|
||||
|
||||
if not death_date and birth_date:
|
||||
# person died more than MAX after current year
|
||||
death_date = birth_date.copy_offset_ymd(year=self.MAX_AGE_PROB_ALIVE)
|
||||
explain = _("birth date")
|
||||
|
||||
if death_date and birth_date:
|
||||
return (birth_date, death_date, explain, "") # direct self evidence
|
||||
|
||||
# Neither birth nor death events are available. Try looking
|
||||
# at siblings. If a sibling was born more than X years past,
|
||||
# or more than Z future, then probably this person is
|
||||
# not alive. If the sibling died more than X years
|
||||
# past, or more than X years future, then probably not alive.
|
||||
|
||||
family_list = person.get_parent_family_handle_list()
|
||||
for family_handle in family_list:
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
for child_ref in family.get_child_ref_list():
|
||||
child_handle = child_ref.ref
|
||||
child = self.db.get_person_from_handle(child_handle)
|
||||
# Go through once looking for direct evidence:
|
||||
for ev_ref in child.get_primary_event_ref_list():
|
||||
ev = self.db.get_event_from_handle(ev_ref.ref)
|
||||
if ev and ev.type.is_birth():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
# if sibling birth date too far away, then not alive:
|
||||
year = dobj.get_year()
|
||||
if year != 0:
|
||||
# sibling birth date
|
||||
return (gen.lib.Date().copy_ymd(year - self.MAX_SIB_AGE_DIFF),
|
||||
gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF + self.MAX_AGE_PROB_ALIVE),
|
||||
_("sibling birth date"),
|
||||
child)
|
||||
elif ev and ev.type.is_death():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
# if sibling death date too far away, then not alive:
|
||||
year = dobj.get_year()
|
||||
if year != 0:
|
||||
# sibling death date
|
||||
return (gen.lib.Date().copy_ymd(year - self.MAX_SIB_AGE_DIFF - self.MAX_AGE_PROB_ALIVE),
|
||||
gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF),
|
||||
_("sibling death date"),
|
||||
child)
|
||||
# Go through again looking for fallback:
|
||||
for ev_ref in child.get_primary_event_ref_list():
|
||||
ev = self.db.get_event_from_handle(ev_ref.ref)
|
||||
if ev and ev.type.is_birth_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
# if sibling birth date too far away, then not alive:
|
||||
year = dobj.get_year()
|
||||
if year != 0:
|
||||
# sibling birth date
|
||||
return (gen.lib.Date().copy_ymd(year - self.MAX_SIB_AGE_DIFF),
|
||||
gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF + self.MAX_AGE_PROB_ALIVE),
|
||||
_("sibling birth-related date"),
|
||||
child)
|
||||
elif ev and ev.type.is_death_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
# if sibling death date too far away, then not alive:
|
||||
year = dobj.get_year()
|
||||
if year != 0:
|
||||
# sibling death date
|
||||
return (gen.lib.Date().copy_ymd(year - self.MAX_SIB_AGE_DIFF - self.MAX_AGE_PROB_ALIVE),
|
||||
gen.lib.Date().copy_ymd(year + self.MAX_SIB_AGE_DIFF),
|
||||
_("sibling death-related date"),
|
||||
child)
|
||||
|
||||
if not is_spouse: # if you are not in recursion, let's recurse:
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
if family:
|
||||
mother_handle = family.get_mother_handle()
|
||||
father_handle = family.get_father_handle()
|
||||
if mother_handle == person.handle and father_handle:
|
||||
father = self.db.get_person_from_handle(father_handle)
|
||||
date1, date2, explain, other = self.calc_estimates(father, is_spouse=True)
|
||||
if date1 and date2:
|
||||
return date1, date2, _("a spouse, ") + explain, other
|
||||
elif father_handle == person.handle and mother_handle:
|
||||
mother = self.db.get_person_from_handle(mother_handle)
|
||||
date1, date2, explain, other = self.calc_estimates(mother, is_spouse=True)
|
||||
if date1 and date2:
|
||||
return date1, date2, _("a spouse, ") + explain, other
|
||||
|
||||
# Try looking for descendants that were born more than a lifespan
|
||||
# ago.
|
||||
|
||||
def descendants_too_old (person, years):
|
||||
for family_handle in person.get_family_handle_list():
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
for child_ref in family.get_child_ref_list():
|
||||
child_handle = child_ref.ref
|
||||
child = self.db.get_person_from_handle(child_handle)
|
||||
child_birth_ref = child.get_birth_ref()
|
||||
if child_birth_ref:
|
||||
child_birth = self.db.get_event_from_handle(child_birth_ref.ref)
|
||||
dobj = child_birth.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
d = gen.lib.Date(dobj)
|
||||
val = d.get_start_date()
|
||||
val = d.get_year() - years
|
||||
d.set_year(val)
|
||||
return (d, d.copy_offset_ymd(self.MAX_AGE_PROB_ALIVE),
|
||||
_("descendent birth date"),
|
||||
child)
|
||||
child_death_ref = child.get_death_ref()
|
||||
if child_death_ref:
|
||||
child_death = self.db.get_event_from_handle(child_death_ref.ref)
|
||||
dobj = child_death.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- self.AVG_GENERATION_GAP),
|
||||
dobj.copy_offset_ymd(- self.AVG_GENERATION_GAP + self.MAX_AGE_PROB_ALIVE),
|
||||
_("descendent death date"),
|
||||
child)
|
||||
date1, date2, explain, other = descendants_too_old (child, years + self.AVG_GENERATION_GAP)
|
||||
if date1 and date2:
|
||||
return date1, date2, explain, other
|
||||
# Check fallback data:
|
||||
for ev_ref in child.get_primary_event_ref_list():
|
||||
ev = self.db.get_event_from_handle(ev_ref.ref)
|
||||
if ev and ev.type.is_birth_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
d = gen.lib.Date(dobj)
|
||||
val = d.get_start_date()
|
||||
val = d.get_year() - years
|
||||
d.set_year(val)
|
||||
return (d, d.copy_offset_ymd(self.MAX_AGE_PROB_ALIVE),
|
||||
_("descendent birth-related date"),
|
||||
child)
|
||||
|
||||
elif ev and ev.type.is_death_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- self.AVG_GENERATION_GAP),
|
||||
dobj.copy_offset_ymd(- self.AVG_GENERATION_GAP + self.MAX_AGE_PROB_ALIVE),
|
||||
_("descendent death-related date"),
|
||||
child)
|
||||
|
||||
return (None, None, "", None)
|
||||
|
||||
# If there are descendants that are too old for the person to have
|
||||
# been alive in the current year then they must be dead.
|
||||
|
||||
date1, date2, explain, other = None, None, "", None
|
||||
try:
|
||||
date1, date2, explain, other = descendants_too_old(person, self.AVG_GENERATION_GAP)
|
||||
except RuntimeError:
|
||||
raise Errors.DatabaseError(
|
||||
_("Database error: %s is defined as his or her own ancestor") %
|
||||
name_displayer.display(person))
|
||||
|
||||
if date1 and date2:
|
||||
return (date1, date2, explain, other)
|
||||
|
||||
def ancestors_too_old(person, year):
|
||||
family_handle = person.get_main_parents_family_handle()
|
||||
if family_handle:
|
||||
family = self.db.get_family_from_handle(family_handle)
|
||||
father_handle = family.get_father_handle()
|
||||
if father_handle:
|
||||
father = self.db.get_person_from_handle(father_handle)
|
||||
father_birth_ref = father.get_birth_ref()
|
||||
if father_birth_ref and father_birth_ref.get_role().is_primary():
|
||||
father_birth = self.db.get_event_from_handle(
|
||||
father_birth_ref.ref)
|
||||
dobj = father_birth.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year),
|
||||
dobj.copy_offset_ymd(- year + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor birth date"),
|
||||
father)
|
||||
father_death_ref = father.get_death_ref()
|
||||
if father_death_ref and father_death_ref.get_role().is_primary():
|
||||
father_death = self.db.get_event_from_handle(
|
||||
father_death_ref.ref)
|
||||
dobj = father_death.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE),
|
||||
dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor death date"),
|
||||
father)
|
||||
|
||||
# Check fallback data:
|
||||
for ev_ref in father.get_primary_event_ref_list():
|
||||
ev = self.db.get_event_from_handle(ev_ref.ref)
|
||||
if ev and ev.type.is_birth_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year),
|
||||
dobj.copy_offset_ymd(- year + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor birth-related date"),
|
||||
father)
|
||||
|
||||
elif ev and ev.type.is_death_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE),
|
||||
dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor death-related date"),
|
||||
father)
|
||||
|
||||
date1, date2, explain, other = ancestors_too_old (father, year - self.AVG_GENERATION_GAP)
|
||||
if date1 and date2:
|
||||
return date1, date2, explain, other
|
||||
|
||||
mother_handle = family.get_mother_handle()
|
||||
if mother_handle:
|
||||
mother = self.db.get_person_from_handle(mother_handle)
|
||||
mother_birth_ref = mother.get_birth_ref()
|
||||
if mother_birth_ref and mother_birth_ref.get_role().is_primary():
|
||||
mother_birth = self.db.get_event_from_handle(mother_birth_ref.ref)
|
||||
dobj = mother_birth.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year),
|
||||
dobj.copy_offset_ymd(- year + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor birth date"),
|
||||
mother)
|
||||
mother_death_ref = mother.get_death_ref()
|
||||
if mother_death_ref and mother_death_ref.get_role().is_primary():
|
||||
mother_death = self.db.get_event_from_handle(
|
||||
mother_death_ref.ref)
|
||||
dobj = mother_death.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE),
|
||||
dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor death date"),
|
||||
mother)
|
||||
|
||||
# Check fallback data:
|
||||
for ev_ref in mother.get_primary_event_ref_list():
|
||||
ev = self.db.get_event_from_handle(ev_ref.ref)
|
||||
if ev and ev.type.is_birth_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year),
|
||||
dobj.copy_offset_ymd(- year + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor birth-related date"),
|
||||
mother)
|
||||
|
||||
elif ev and ev.type.is_death_fallback():
|
||||
dobj = ev.get_date_object()
|
||||
if dobj.get_start_date() != gen.lib.Date.EMPTY:
|
||||
return (dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE),
|
||||
dobj.copy_offset_ymd(- year - self.MAX_AGE_PROB_ALIVE + self.MAX_AGE_PROB_ALIVE),
|
||||
_("ancestor death-related date"),
|
||||
mother)
|
||||
|
||||
date1, date2, explain, other = ancestors_too_old (mother, year - self.AVG_GENERATION_GAP)
|
||||
if date1 and date2:
|
||||
return (date1, date2, explain, other)
|
||||
|
||||
return (None, None, "", None)
|
||||
|
||||
# If there are ancestors that would be too old in the current year
|
||||
# then assume our person must be dead too.
|
||||
date1, date2, explain, other = ancestors_too_old (person, - self.AVG_GENERATION_GAP)
|
||||
if date1 and date2:
|
||||
return (date1, date2, explain, other)
|
||||
|
||||
# If we can't find any reason to believe that they are dead we
|
||||
# must assume they are alive.
|
||||
|
||||
return (None, None, "", None)
|
||||
|
Reference in New Issue
Block a user