def phasis_on_or_before(self, date): """Return the closest fixed date on or before date 'date', when crescent moon first became visible at location 'location'.""" mean = date - ifloor(Lunar.lunar_phase(date + 1) / 360.0 * Lunar.MEAN_SYNODIC_MONTH) tau = ((mean - 30) if (((date - mean) <= 3) and (not self.visible_crescent(date))) else (mean - 2)) return next_int(tau, lambda d: self.visible_crescent(d))
def visible_crescent(self, date): """Return S. K. Shaukat's criterion for likely visibility of crescent moon on eve of date 'date', at location 'location'.""" tee = self.universal_from_standard(self.dusk(date - 1, mpf(4.5))) phase = Lunar.lunar_phase(tee) altitude = self.lunar_altitude(tee) arc_of_light = arccos_degrees(cos_degrees(Lunar.lunar_latitude(tee)) * cos_degrees(phase)) return ((Lunar.NEW < phase < Lunar.FIRST_QUARTER) and (mpf(10.6) <= arc_of_light <= 90) and (altitude > mpf(4.1)))
def moonrise(self, date): """Return the standard time of moonrise on fixed, date, and location, location.""" t = self.universal_from_standard(date) waning = (Lunar.lunar_phase(t) > 180) alt = self.observed_lunar_altitude(t) offset = alt / 360 if waning and (offset > 0): approx = t + 1 - offset elif waning: approx = t - offset else: approx = t + (1 / 2) + offset rise = binary_search(approx - Clock.days_from_hours(3), approx + Clock.days_from_hours(3), lambda u, l: ((u - l) < Clock.days_from_hours(1/60)), lambda x: self.observed_lunar_altitude(x) > 0) if rise < (t + 1): return self.standard_from_universal(rise) raise ValueError()
def phasis_on_or_after(cls, fixed_date, location): """Return closest fixed date on or after date, date, on the eve of which crescent moon first became visible at location, location.""" mean = fixed_date - ifloor(Lunar.lunar_phase(fixed_date + 1) / mpf(360) * Lunar.MEAN_SYNODIC_MONTH) tau = fixed_date if fixed_date - mean <= 3 and not location.visible_crescent(fixed_date - 1) else mean + 29 return next_int(tau, lambda d: location.visible_crescent(d))