def test_get_anga_data_1981_12_23(): panchaanga = panchaanga_json_comparer(chennai, date=Date(1981, 12, 23)) angas = [ s.anga.index for s in panchaanga.sunrise_day_angas.get_anga_spans_in_interval( interval=panchaanga.day_length_based_periods.puurvaahna, anga_type=AngaType.NAKSHATRA) ] assert angas == [16, 17] angas = [ s.anga.index for s in panchaanga.sunrise_day_angas.get_anga_spans_in_interval( interval=Interval(jd_start=panchaanga.jd_sunrise, jd_end=panchaanga.jd_sunrise), anga_type=AngaType.NAKSHATRA) ] assert angas == [16] angas = [ s.anga.index for s in panchaanga.sunrise_day_angas.get_anga_spans_in_interval( interval=Interval(jd_start=panchaanga.jd_sunrise, jd_end=panchaanga.jd_next_sunrise), anga_type=AngaType.NAKSHATRA) ] assert angas == [16, 17]
def compute_calendar(panchaanga, scripts=None): if scripts is None: scripts = [sanscript.DEVANAGARI] ics_calendar = Calendar() # uid_list = [] daily_panchaangas = panchaanga.daily_panchaangas_sorted() for d, daily_panchaanga in enumerate(daily_panchaangas): if daily_panchaanga.date < panchaanga.start_date or daily_panchaanga.date > panchaanga.end_date: continue # Eliminate repeat festival_id_to_instance on the same day, and keep the list arbitrarily sorted # this will work whether we have one or more events on the same day for festival_instance_in in sorted( daily_panchaanga.festival_id_to_instance.values()): festival_instance = deepcopy(festival_instance_in) fest_id = festival_instance.name all_day = False if festival_instance.interval is None: festival_instance.interval = Interval( jd_start=daily_panchaanga.julian_day_start, jd_end=daily_panchaanga.julian_day_start + 1) all_day = True if festival_instance.interval.jd_start is None: festival_instance.interval.jd_start = daily_panchaanga.julian_day_start if festival_instance.interval.jd_end is None: festival_instance.interval.jd_end = daily_panchaanga.julian_day_start + 1 if fest_id == 'kRttikA-maNDala-pArAyaNam': festival_instance.interval = Interval( jd_start=daily_panchaanga.julian_day_start, jd_end=daily_panchaanga.julian_day_start + 2) elif fest_id.find('samApanam') != -1: # It's an ending event full_festival_instance = get_full_festival_instance( festival_instance=festival_instance, daily_panchaangas=daily_panchaangas, d=d) if full_festival_instance is not None: event = festival_instance_to_event( festival_instance=full_festival_instance, scripts=scripts, panchaanga=panchaanga, all_day=True) ics_calendar.add_component(event) event = festival_instance_to_event( festival_instance=festival_instance, scripts=scripts, panchaanga=panchaanga, all_day=all_day) ics_calendar.add_component(event) # if m == 12 and dt == 31: # break return ics_calendar
def get_interval(self, interval_id): interval_id = names.devanaagarii_to_python.get(interval_id, interval_id) if interval_id == "moonrise": return Interval(name=interval_id, jd_start=self.jd_moonrise, jd_end=self.jd_moonrise) elif interval_id == "sunrise": return Interval(jd_start=self.jd_sunrise, jd_end=self.jd_sunrise, name=interval_id) elif interval_id == "sunset": return Interval(jd_start=self.jd_sunset, jd_end=self.jd_sunset, name=interval_id) elif interval_id == "full_day": return Interval(jd_start=self.jd_sunrise, jd_end=self.jd_next_sunrise, name=interval_id) elif interval_id == "aparaahna": if self.computation_system.festival_options.aparaahna_as_second_half: return getattr(self.day_length_based_periods, interval_id) else: return getattr( self.day_length_based_periods.fifteen_fold_division, interval_id) elif interval_id == "julian_day": return Interval(jd_start=self.julian_day_start, jd_end=self.julian_day_start + 1, name=interval_id) else: if self.computation_system.festival_options.prefer_eight_fold_day_division: search_locations = [ self.day_length_based_periods, self.day_length_based_periods.eight_fold_division, self.day_length_based_periods.fifteen_fold_division ] else: search_locations = [ self.day_length_based_periods, self.day_length_based_periods.fifteen_fold_division, self.day_length_based_periods.eight_fold_division ] for location in search_locations: value = getattr(location, interval_id) if value is not None: return value return None
def compute_solar_eclipses(self): jd = self.panchaanga.jd_start while 1: next_eclipse_sol = self.panchaanga.city.get_solar_eclipse_time( jd_start=jd) # compute offset from UTC jd = next_eclipse_sol[1][0] jd_eclipse_solar_start = next_eclipse_sol[1][1] jd_eclipse_solar_end = next_eclipse_sol[1][4] # -1 is to not miss an eclipse that occurs after sunset on 31-Dec! if jd_eclipse_solar_start > self.panchaanga.jd_end + 1: break else: fday = int( floor(jd) - floor(self.daily_panchaangas[0].julian_day_start)) if (jd < self.daily_panchaangas[fday].jd_sunrise): fday -= 1 if (jd_eclipse_solar_start ) == 0.0 or jd_eclipse_solar_end == 0.0: # Move towards the next eclipse... at least the next new # moon (>=25 days away) jd += MIN_DAYS_NEXT_ECLIPSE continue solar_eclipse_str = 'sUrya-grahaNam' if self.daily_panchaangas[fday].date.get_weekday() == 0: solar_eclipse_str = '★cUDAmaNi-' + solar_eclipse_str self.daily_panchaangas[fday].festival_id_to_instance[ solar_eclipse_str] = (FestivalInstance( name=solar_eclipse_str, interval=Interval(jd_start=jd_eclipse_solar_start, jd_end=jd_eclipse_solar_end))) jd = jd + MIN_DAYS_NEXT_ECLIPSE
def compute_solar_eclipses(self): if 'sUrya-grahaNam' not in self.rules_collection.name_to_rule: return jd = self.panchaanga.jd_start while 1: next_eclipse_sol = self.panchaanga.city.get_solar_eclipse_time(jd_start=jd) # compute offset from UTC jd = next_eclipse_sol[1][0] jd_eclipse_solar_start = next_eclipse_sol[1][1] jd_eclipse_solar_end = next_eclipse_sol[1][4] # -1 is to not miss an eclipse that occurs after sunset on 31-Dec! if jd_eclipse_solar_start > self.panchaanga.jd_end + 1: break else: fday = int(floor(jd) - floor(self.daily_panchaangas[0].julian_day_start)) if (jd < self.daily_panchaangas[fday].jd_sunrise): fday -= 1 if (jd_eclipse_solar_start) == 0.0 or jd_eclipse_solar_end == 0.0: # Move towards the next eclipse... at least the next new # moon (>=25 days away) jd += MIN_DAYS_NEXT_ECLIPSE continue if abs (Graha.singleton(Graha.SUN).get_longitude(jd_eclipse_solar_end) - Graha.singleton(Graha.RAHU).get_longitude( jd_eclipse_solar_end)) < 5: grasta = 'rAhugrasta' else: grasta = 'kEtugrasta' solar_eclipse_str = 'sUrya-grahaNaM~(' + grasta + ')' if self.daily_panchaangas[fday].date.get_weekday() == 0: solar_eclipse_str = '★cUDAmaNi-' + solar_eclipse_str fest = FestivalInstance(name=solar_eclipse_str, interval=Interval(jd_start=jd_eclipse_solar_start, jd_end=jd_eclipse_solar_end)) self.panchaanga.add_festival_instance(festival_instance=fest, date=self.daily_panchaangas[fday].date) jd = jd + MIN_DAYS_NEXT_ECLIPSE
def compute_lunar_eclipses(self): # Set location jd = self.panchaanga.jd_start while 1: next_eclipse_lun = self.panchaanga.city.get_lunar_eclipse_time(jd) jd = next_eclipse_lun[1][0] jd_eclipse_lunar_start = next_eclipse_lun[1][2] jd_eclipse_lunar_end = next_eclipse_lun[1][3] # -1 is to not miss an eclipse that occurs after sunset on 31-Dec! if jd_eclipse_lunar_start > self.panchaanga.jd_end: break else: if jd_eclipse_lunar_start == 0.0 or jd_eclipse_lunar_end == 0.0: # 0.0 is returned in case of eclipses when the moon is below the horizon. # Move towards the next eclipse... at least the next full # moon (>=25 days away) jd += MIN_DAYS_NEXT_ECLIPSE continue fday = int( floor(jd_eclipse_lunar_start) - floor(self.panchaanga.jd_start) + 1) # print '%%', jd, fday, self.date_str_to_panchaanga[fday].jd_sunrise, # self.date_str_to_panchaanga[fday-1].jd_sunrise if jd < self.daily_panchaangas[fday].jd_sunrise: fday -= 1 # print '%%', jd, fday, self.date_str_to_panchaanga[fday].jd_sunrise, # self.date_str_to_panchaanga[fday-1].jd_sunrise, eclipse_lunar_start, # eclipse_lunar_end jd_moonrise_eclipse_day = self.panchaanga.city.get_rising_time( julian_day_start=self.daily_panchaangas[fday].jd_sunrise, body=Graha.MOON) jd_moonset_eclipse_day = self.panchaanga.city.get_setting_time( julian_day_start=jd_moonrise_eclipse_day, body=Graha.MOON) if jd_eclipse_lunar_end < jd_moonrise_eclipse_day or \ jd_eclipse_lunar_start > jd_moonset_eclipse_day: # Move towards the next eclipse... at least the next full # moon (>=25 days away) jd += MIN_DAYS_NEXT_ECLIPSE continue if Graha.singleton(Graha.MOON).get_longitude( jd_eclipse_lunar_end) < Graha.singleton( Graha.SUN).get_longitude(jd_eclipse_lunar_end): grasta = 'rAhugrasta' else: grasta = 'kEtugrasta' lunar_eclipse_str = 'candra-grahaNam~(' + grasta + ')' if self.daily_panchaangas[fday].date.get_weekday() == 1: lunar_eclipse_str = '★cUDAmaNi-' + lunar_eclipse_str self.daily_panchaangas[fday].festival_id_to_instance[ lunar_eclipse_str] = (FestivalInstance( name=lunar_eclipse_str, interval=Interval(jd_start=jd_eclipse_lunar_start, jd_end=jd_eclipse_lunar_end))) jd += MIN_DAYS_NEXT_ECLIPSE
def get_anga_at_jd(self, jd, anga_type): anga_spans = self.get_anga_spans_in_interval(anga_type=anga_type, interval=Interval( jd_start=jd, jd_end=jd)) for anga_span in anga_spans: return anga_span.anga return None
def get_interval(self, name): if name == "moonrise": return Interval(name=name, jd_start=self.jd_moonrise, jd_end=self.jd_moonrise) elif name == "sunrise": return Interval(jd_start=self.jd_sunrise, jd_end=self.jd_sunrise, name=name) elif name == "sunset": return Interval(jd_start=self.jd_sunset, jd_end=self.jd_sunset, name=name) else: if name == "aparaahna" and not self.computation_system.options.aparaahna_as_second_half: name = "aparaahna_muhuurta" return getattr(self.day_length_based_periods, name)
def get_full_festival_instance(festival_instance, daily_panchaangas, day_index): # Find start and add entire event as well fest_id = festival_instance.name check_d = day_index stext_start = fest_id[:fest_id.find( 'samApanam' )] + 'ArambhaH' # This discards any bracketed info after the word ArambhaH start_d = None while check_d > 1: check_d -= 1 if stext_start in daily_panchaangas[ check_d].festival_id_to_instance.keys(): start_d = check_d break if start_d is None: # Look for approx match check_d = day_index while check_d > 1: check_d -= 1 for fest_key in daily_panchaangas[ check_d].festival_id_to_instance.keys(): if fest_key.startswith(stext_start): logging.debug('Found approx match for %s: %s' % (stext_start, fest_key)) start_d = check_d break if start_d is None: logging.error('Unable to find start date for %s' % stext_start) return None else: # logging.debug(stext) # TODO: Reimplement the below in another way if needed. new_fest_id = fest_id REPLACEMENTS = { 'samApanam': '', 'rAtra-': 'rAtraH', 'nakSatra-': 'nakSatram', 'pakSa-': 'pakSaH', 'puSkara-': 'puSkaram', 'dIpa-': 'dIpaH', 'pArAyaNa-': 'pArAyaNam', 'mAsa-': 'mAsaH', 'snAna-': 'snAnam', 'tsava-': 'tsavaH', 'vrata-': 'vratam' } for _orig, _repl in REPLACEMENTS.items(): new_fest_id = new_fest_id.replace(_orig, _repl) full_festival_instance = FestivalInstance( name=new_fest_id, interval=Interval( jd_start=daily_panchaangas[start_d].julian_day_start, jd_end=festival_instance.interval.jd_start + 1)) return full_festival_instance
def set_interval(daily_panchaanga, festival_instance): if festival_instance.interval is None: festival_instance.interval = Interval( jd_start=daily_panchaanga.julian_day_start, jd_end=daily_panchaanga.julian_day_start + 1) if festival_instance.interval.jd_start is None: festival_instance.interval.jd_start = daily_panchaanga.julian_day_start if festival_instance.interval.jd_end is None: festival_instance.interval.jd_end = daily_panchaanga.julian_day_start + 1
def compute_conjunctions(self, Graha1, Graha2, delta=0.0): # Compute the time of conjunction between Graha1 and Graha2 GRAHA_NAMES = {Graha.SUN: 'sUryaH', Graha.MOON: 'candraH', Graha.JUPITER: 'guruH', Graha.VENUS: 'zukraH', Graha.MERCURY: 'budhaH', Graha.MARS: 'aGgArakaH', Graha.SATURN: 'zanaizcaraH', Graha.RAHU: 'rAhuH'} if delta == 0.0: try: t = brentq(lambda jd: Graha.singleton(Graha1).get_longitude(jd) - Graha.singleton(Graha2).get_longitude(jd), self.panchaanga.jd_start, self.panchaanga.jd_end) except ValueError: t = None logging.error('Not able to bracket!') if t is not None and self.panchaanga.jd_start < t < self.panchaanga.jd_end: fday = [self.daily_panchaangas[i].jd_sunrise < t < self.daily_panchaangas[i + 1].jd_sunrise for i in range(self.panchaanga.duration)].index(True) fest = FestivalInstance(name='graha-yuddhaH (%s–%s)' % (GRAHA_NAMES[Graha1], GRAHA_NAMES[Graha2]), interval=Interval(jd_start=None, jd_end=t)) self.panchaanga.add_festival_instance(festival_instance=fest, date=self.daily_panchaangas[fday].date) else: # mauDhya / combustion with some degrees assigned try: t_start = brentq(lambda jd: Graha.singleton(Graha1).get_longitude(jd) - Graha.singleton(Graha2).get_longitude(jd) - delta, self.panchaanga.jd_start, self.panchaanga.jd_end) except ValueError: t_start = None logging.error('Not able to bracket!') try: t_end = brentq(lambda jd: Graha.singleton(Graha1).get_longitude(jd) - Graha.singleton(Graha2).get_longitude(jd) + delta, self.panchaanga.jd_start, self.panchaanga.jd_end) except ValueError: t_end = None logging.error('Not able to bracket!') if t_start is not None and self.panchaanga.jd_start < t_start < self.panchaanga.jd_end: fday = [self.daily_panchaangas[i].jd_sunrise < t_start < self.daily_panchaangas[i + 1].jd_sunrise for i in range(self.panchaanga.duration)].index(True) fest = FestivalInstance(name='%s–mauDhya' % GRAHA_NAMES[Graha1], interval=Interval(jd_start=t_start, jd_end=None)) self.panchaanga.add_festival_instance(festival_instance=fest, date=self.daily_panchaangas[fday].date) if t_end is not None and self.panchaanga.jd_start < t_end < self.panchaanga.jd_end: fday = [self.daily_panchaangas[i].jd_sunrise < t_end < self.daily_panchaangas[i + 1].jd_sunrise for i in range(self.panchaanga.duration)].index(True) fest = FestivalInstance(name='%s–mauDhya' % GRAHA_NAMES[Graha1], interval=Interval(jd_start=None, jd_end=t_end)) self.panchaanga.add_festival_instance(festival_instance=fest, date=self.daily_panchaangas[fday].date)
def assign_gajachhaya_yoga(self): intersect_lists = [ ((zodiac.AngaType.SOLAR_NAKSH, 13), (zodiac.AngaType.NAKSHATRA, 10), (zodiac.AngaType.TITHI, 28)), ((zodiac.AngaType.SOLAR_NAKSH, 13), (zodiac.AngaType.NAKSHATRA, 13), (zodiac.AngaType.TITHI, 30)) ] for intersect_list in intersect_lists: jd_start = self.panchaanga.jd_start jd_end = self.panchaanga.jd_end anga_list = [] gc_yoga = True for anga_type, target_anga_id in intersect_list: finder = zodiac.AngaSpanFinder.get_cached( ayanaamsha_id=self.computation_system.ayanaamsha_id, anga_type=anga_type) anga = finder.find(jd1=jd_start, jd2=jd_end, target_anga_id=target_anga_id) anga_list.append(anga) if anga is None: logging.debug( 'No Gajacchhaya Yoga involving %s %d + %s %d this year!' % (intersect_list[1][0], intersect_list[1][1], intersect_list[2][0], intersect_list[2][1])) gc_yoga = False break if anga.jd_start is not None: jd_start = anga.jd_start - 5 if anga.jd_end is not None: jd_end = anga.jd_end + 5 if gc_yoga: jd_start, jd_end = max([x.jd_start for x in anga_list ]), min([x.jd_end for x in anga_list]) if jd_start > jd_end: logging.debug( 'No Gajacchhaya Yoga involving %s %d + %s %d this year!' % (intersect_list[1][0], intersect_list[1][1], intersect_list[2][0], intersect_list[2][1])) else: fday = int( floor(jd_start) - floor(self.daily_panchaangas[0].julian_day_start)) if (jd_start < self.daily_panchaangas[fday].jd_sunrise): fday -= 1 self.panchaanga.add_festival_instance( festival_instance=FestivalInstance( name='gajacchAyA-yOgaH', interval=Interval(jd_start=jd_start, jd_end=jd_end)), date=self.daily_panchaangas[fday].date)
def compute_solar_eclipses(self): jd = self.panchaanga.jd_start while 1: next_eclipse_sol = self.panchaanga.city.get_solar_eclipse_time( jd_start=jd) [y, m, dt, t] = time.jd_to_utc_gregorian( next_eclipse_sol[1][0]).to_date_fractional_hour_tuple() local_time = tz(self.panchaanga.city.timezone).localize( datetime(y, m, dt, 6, 0, 0)) # checking @ 6am local - can we do any better? tz_off = (datetime.utcoffset(local_time).days * 86400 + datetime.utcoffset(local_time).seconds) / 3600.0 # compute offset from UTC jd = next_eclipse_sol[1][0] + (tz_off / 24.0) jd_eclipse_solar_start = next_eclipse_sol[1][1] + (tz_off / 24.0) jd_eclipse_solar_end = next_eclipse_sol[1][4] + (tz_off / 24.0) # -1 is to not miss an eclipse that occurs after sunset on 31-Dec! if jd_eclipse_solar_start > self.panchaanga.jd_end + 1: break else: fday = int( floor(jd) - floor(self.daily_panchaangas[0].julian_day_start)) if (jd < (self.daily_panchaangas[fday].jd_sunrise + tz_off / 24.0)): fday -= 1 eclipse_solar_start = time.jd_to_utc_gregorian( jd_eclipse_solar_start).get_fractional_hour() if (jd_eclipse_solar_start - (tz_off / 24.0)) == 0.0 or \ (jd_eclipse_solar_end - (tz_off / 24.0)) == 0.0: # Move towards the next eclipse... at least the next new # moon (>=25 days away) jd += MIN_DAYS_NEXT_ECLIPSE continue solar_eclipse_str = 'sUrya-grahaNam' if self.daily_panchaangas[fday].date.get_weekday() == 0: solar_eclipse_str = '★cUDAmaNi-' + solar_eclipse_str self.daily_panchaangas[fday].festival_id_to_instance[ solar_eclipse_str] = (FestivalInstance( name=solar_eclipse_str, interval=Interval(jd_start=jd_eclipse_solar_start, jd_end=jd_eclipse_solar_end))) jd = jd + MIN_DAYS_NEXT_ECLIPSE
def assign_tropical_sankranti(self): if 'mESa-viSu-puNyakAlaH' not in self.rules_collection.name_to_rule: return RTU_MASA_NAMES = { 1: "madhu-mAsaH", 2: "mAdhava-mAsaH/vasantaRtuH", 3: "zukra-mAsaH/uttarAyaNam", 4: "zuci-mAsaH/grISmaRtuH", 5: "nabhO-mAsaH", 6: "nabhasya-mAsaH/varSaRtuH", 7: "iSa-mAsaH", 8: "Urja-mAsaH/zaradRtuH", 9: "sahO-mAsaH/dakSiNAyanam", 10: "sahasya-mAsaH/hEmantaRtuH", 11: "tapO-mAsaH", 12: "tapasya-mAsaH/ziziraRtuH", } for d in range( self.panchaanga.duration_prior_padding, self.panchaanga.duration + self.panchaanga.duration_prior_padding): if self.daily_panchaangas[ d].tropical_date_sunset.month_transition is not None: jd_transition = self.daily_panchaangas[ d].tropical_date_sunset.month_transition # Add tropical sankranti masa_name = RTU_MASA_NAMES[ (self.daily_panchaangas[d + 1].tropical_date_sunset.month - 2) % 12 + 1] if jd_transition < self.daily_panchaangas[d].jd_sunrise: fday = d - 1 else: fday = d self.panchaanga.add_festival_instance( festival_instance=FestivalInstance( name=masa_name, interval=Interval(jd_start=None, jd_end=jd_transition)), date=self.daily_panchaangas[fday].date)
def compute_lunar_eclipses(self): # Set location jd = self.panchaanga.jd_start while 1: next_eclipse_lun = self.panchaanga.city.get_lunar_eclipse_time(jd) [y, m, dt, t] = time.jd_to_utc_gregorian( next_eclipse_lun[1][0]).to_date_fractional_hour_tuple() local_time = tz(self.panchaanga.city.timezone).localize( datetime(y, m, dt, 6, 0, 0)) # checking @ 6am local - can we do any better? This is crucial, # since DST changes before 6 am tz_off = (datetime.utcoffset(local_time).days * 86400 + datetime.utcoffset(local_time).seconds) / 3600.0 # compute offset from UTC jd = next_eclipse_lun[1][0] + (tz_off / 24.0) jd_eclipse_lunar_start = next_eclipse_lun[1][2] + (tz_off / 24.0) jd_eclipse_lunar_end = next_eclipse_lun[1][3] + (tz_off / 24.0) # -1 is to not miss an eclipse that occurs after sunset on 31-Dec! if jd_eclipse_lunar_start > self.panchaanga.jd_end: break else: if (jd_eclipse_lunar_start - (tz_off / 24.0)) == 0.0 or \ (jd_eclipse_lunar_end - (tz_off / 24.0)) == 0.0: # Move towards the next eclipse... at least the next full # moon (>=25 days away) jd += MIN_DAYS_NEXT_ECLIPSE continue fday = int( floor(jd_eclipse_lunar_start) - floor(self.panchaanga.jd_start) + 1) # print '%%', jd, fday, self.date_str_to_panchaanga[fday].jd_sunrise, # self.date_str_to_panchaanga[fday-1].jd_sunrise if (jd < (self.daily_panchaangas[fday].jd_sunrise + tz_off / 24.0)): fday -= 1 # print '%%', jd, fday, self.date_str_to_panchaanga[fday].jd_sunrise, # self.date_str_to_panchaanga[fday-1].jd_sunrise, eclipse_lunar_start, # eclipse_lunar_end jd_moonrise_eclipse_day = self.panchaanga.city.get_rising_time( julian_day_start=self.daily_panchaangas[fday].jd_sunrise, body=Graha.MOON) + (tz_off / 24.0) jd_moonset_eclipse_day = self.panchaanga.city.get_rising_time( julian_day_start=jd_moonrise_eclipse_day, body=Graha.MOON) + (tz_off / 24.0) if jd_eclipse_lunar_end < jd_moonrise_eclipse_day or \ jd_eclipse_lunar_start > jd_moonset_eclipse_day: # Move towards the next eclipse... at least the next full # moon (>=25 days away) jd += MIN_DAYS_NEXT_ECLIPSE continue if Graha.singleton(Graha.MOON).get_longitude( jd_eclipse_lunar_end) < Graha.singleton( Graha.SUN).get_longitude(jd_eclipse_lunar_end): grasta = 'rAhugrasta' else: grasta = 'kEtugrasta' lunar_eclipse_str = 'candra-grahaNam~(' + grasta + ')' if self.daily_panchaangas[fday].date.get_weekday() == 1: lunar_eclipse_str = '★cUDAmaNi-' + lunar_eclipse_str self.daily_panchaangas[fday].festival_id_to_instance[ lunar_eclipse_str] = (FestivalInstance( name=lunar_eclipse_str, interval=Interval(jd_start=jd_eclipse_lunar_start, jd_end=jd_eclipse_lunar_end))) jd += MIN_DAYS_NEXT_ECLIPSE
def assign_ekaadashii_vratam(self): for d in range(self.panchaanga.duration_prior_padding, self.panchaanga.duration + 1): [y, m, dt, t] = time.jd_to_utc_gregorian(self.panchaanga.jd_start + d - 1).to_date_fractional_hour_tuple() # checking @ 6am local - can we do any better? local_time = tz(self.panchaanga.city.timezone).localize( datetime(y, m, dt, 6, 0, 0)) # compute offset from UTC in hours tz_off = (datetime.utcoffset(local_time).days * 86400 + datetime.utcoffset(local_time).seconds) / 3600.0 # EKADASHI Vratam # One of two consecutive tithis must appear @ sunrise! if (self.daily_panchaangas[d].sunrise_day_angas.tithi_at_sunrise. index % 15) == 10 or (self.daily_panchaangas[d].sunrise_day_angas. tithi_at_sunrise.index % 15) == 11: yati_ekaadashii_fday = smaarta_ekaadashii_fday = vaishnava_ekaadashii_fday = None ekaadashii_tithi_days = [ x.sunrise_day_angas.tithi_at_sunrise.index % 15 for x in self.daily_panchaangas[d:d + 3] ] if self.daily_panchaangas[ d].sunrise_day_angas.tithi_at_sunrise.index > 15: ekaadashii_paksha = 'krishna' else: ekaadashii_paksha = 'shukla' if ekaadashii_tithi_days in [[11, 11, 12], [10, 12, 12]]: smaarta_ekaadashii_fday = d + 1 tithi_arunodayam = tithi.get_tithi( self.daily_panchaangas[d + 1].jd_sunrise - (1 / 15.0) * (self.daily_panchaangas[d + 1].jd_sunrise - self.daily_panchaangas[d].jd_sunrise)).index if tithi_arunodayam % 15 == 10: vaishnava_ekaadashii_fday = d + 2 else: vaishnava_ekaadashii_fday = d + 1 elif ekaadashii_tithi_days in [[10, 12, 13], [11, 12, 13], [11, 12, 12], [11, 12, 14]]: smaarta_ekaadashii_fday = d tithi_arunodayam = temporal.tithi.get_tithi( self.daily_panchaangas[d].jd_sunrise - (1 / 15.0) * (self.daily_panchaangas[d].jd_sunrise - self.daily_panchaangas[d - 1].jd_sunrise)).index if tithi_arunodayam % 15 == 11 and ekaadashii_tithi_days in [ [11, 12, 13], [11, 12, 14] ]: vaishnava_ekaadashii_fday = d else: vaishnava_ekaadashii_fday = d + 1 elif ekaadashii_tithi_days in [[10, 11, 13], [11, 11, 13]]: smaarta_ekaadashii_fday = d vaishnava_ekaadashii_fday = d + 1 yati_ekaadashii_fday = d + 1 else: pass # These combinations are taken care of, either in the past or future. # if ekaadashii_tithi_days == [10, 11, 12]: # logging.debug('Not assigning. Maybe tomorrow?') # else: # logging.debug(('!!', d, ekaadashii_tithi_days)) if yati_ekaadashii_fday == smaarta_ekaadashii_fday == vaishnava_ekaadashii_fday is None: # Must have already assigned pass elif yati_ekaadashii_fday is None: if smaarta_ekaadashii_fday == vaishnava_ekaadashii_fday: # It's sarva ekaadashii self.festival_id_to_days[ 'sarva-' + names.get_ekaadashii_name( ekaadashii_paksha, self.daily_panchaangas[d]. lunar_month_sunrise.index)].add( self.daily_panchaangas[ smaarta_ekaadashii_fday].date) if ekaadashii_paksha == 'shukla': if self.daily_panchaangas[ d].solar_sidereal_date_sunset.month == 9: self.festival_id_to_days[ 'sarva-vaikuNTha-EkAdazI'].add( self.daily_panchaangas[ smaarta_ekaadashii_fday].date) else: self.festival_id_to_days[ 'smArta-' + names.get_ekaadashii_name( ekaadashii_paksha, self.daily_panchaangas[d]. lunar_month_sunrise.index)].add( self.daily_panchaangas[ smaarta_ekaadashii_fday].date) self.festival_id_to_days[ 'vaiSNava-' + names.get_ekaadashii_name( ekaadashii_paksha, self.daily_panchaangas[d]. lunar_month_sunrise.index)].add( self.daily_panchaangas[ vaishnava_ekaadashii_fday].date) if ekaadashii_paksha == 'shukla': if self.daily_panchaangas[ d].solar_sidereal_date_sunset.month == 9: self.festival_id_to_days[ 'smArta-vaikuNTha-EkAdazI'].add( self.daily_panchaangas[ smaarta_ekaadashii_fday].date) self.festival_id_to_days[ 'vaiSNava-vaikuNTha-EkAdazI'].add( self.daily_panchaangas[ vaishnava_ekaadashii_fday].date) else: self.festival_id_to_days[ 'smArta-' + names.get_ekaadashii_name( ekaadashii_paksha, self.daily_panchaangas[d]. lunar_month_sunrise.index) + ' (gRhastha)'].add( self.daily_panchaangas[smaarta_ekaadashii_fday]. date) self.festival_id_to_days[ 'smArta-' + names.get_ekaadashii_name( ekaadashii_paksha, self.daily_panchaangas[d]. lunar_month_sunrise.index) + ' (sannyastha)'].add( self.daily_panchaangas[yati_ekaadashii_fday].date) self.festival_id_to_days[ 'vaiSNava-' + names.get_ekaadashii_name( ekaadashii_paksha, self.daily_panchaangas[d]. lunar_month_sunrise.index)].add( self.daily_panchaangas[ vaishnava_ekaadashii_fday].date) if self.daily_panchaangas[ d].solar_sidereal_date_sunset.month == 9: if ekaadashii_paksha == 'shukla': self.festival_id_to_days[ 'smArta-vaikuNTha-EkAdazI (gRhastha)'].add( self.daily_panchaangas[ smaarta_ekaadashii_fday].date) self.festival_id_to_days[ 'smArta-vaikuNTha-EkAdazI (sannyastha)'].add( self.daily_panchaangas[ yati_ekaadashii_fday].date) self.festival_id_to_days[ 'vaiSNava-vaikuNTha-EkAdazI'].add( self.daily_panchaangas[ vaishnava_ekaadashii_fday].date) if yati_ekaadashii_fday == smaarta_ekaadashii_fday == vaishnava_ekaadashii_fday is None: # Must have already assigned pass else: if self.daily_panchaangas[ d].solar_sidereal_date_sunset.month == 8 and ekaadashii_paksha == 'shukla': # self.add_festival('guruvAyupura-EkAdazI', smaarta_ekaadashii_fday) self.festival_id_to_days['guruvAyupura-EkAdazI'].add( self.daily_panchaangas[vaishnava_ekaadashii_fday]. date) self.festival_id_to_days['kaizika-EkAdazI'].add( self.daily_panchaangas[vaishnava_ekaadashii_fday]. date) # Harivasara Computation if ekaadashii_paksha == 'shukla': def f(x): tp_float = NakshatraDivision( x, ayanaamsha_id=self.ayanaamsha_id ).get_anga_float(zodiac.AngaType.TITHI_PADA) return tp_float - 45 harivasara_end = brentq( f, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise - 2, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise + 2) else: def f(x): tp_float = NakshatraDivision( x, ayanaamsha_id=self.ayanaamsha_id ).get_anga_float(zodiac.AngaType.TITHI_PADA) return tp_float - 105 harivasara_end = brentq( f, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise - 2, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise + 2) _date = time.jd_to_utc_gregorian(harivasara_end + (tz_off / 24.0)) _date.set_time_to_day_start() fday_hv = time.utc_gregorian_to_jd( _date) - time.utc_gregorian_to_jd( self.daily_panchaangas[0].date) fest = FestivalInstance(name='harivAsaraH', interval=Interval( jd_start=None, jd_end=harivasara_end)) self.daily_panchaangas[int( fday_hv)].festival_id_to_instance[fest.name] = fest
def assign_sidereal_sankranti_punyakaala(self): if 'mESa-viSu-puNyakAlaH' not in self.rules_collection.name_to_rule: return # Reference # --------- # # अतीतानागते पुण्ये द्वे उदग्दक्षिणायने। त्रिंशत्कर्कटके नाड्यो मकरे विंशतिः स्मृताः॥ # वर्तमाने तुलामेषे नाड्यस्तूभयतो दश। षडशीत्यामतीतायां षष्टिरुक्तास्तु नाडिकाः॥ # पुण्यायां विष्णुपद्यां च प्राक् पश्चादपि षोडशः॥ # —वैद्यनाथ-दीक्षितीये स्मृतिमुक्ताफले आह्निक-काण्डः # # The times before and/or after any given sankranti (tropical/sidereal) are sacred for snanam & danam # with specific times specified. For Mesha and Tula, 10 nAdikas before and after are special, # while for Shadashiti, an entire 60 nAdikas following the sankramaNam are special, and so on. PUNYA_KAALA = { 1: (10, 10), 2: (16, 16), 3: (0, 60), 4: (30, 0), 5: (16, 16), 6: (0, 60), 7: (10, 10), 8: (16, 16), 9: (0, 60), 10: (0, 20), 11: (16, 16), 12: (0, 60) } SANKRANTI_PUNYAKALA_NAMES = { 1: "mESa-saGkramaNa", 2: "vRSabha-ravi-saGkramaNa-viSNupadI", 3: "mithuna-ravi-saGkramaNa-SaDazIti", 4: "karkaTa-saGkramaNa", 5: "siMha-ravi-saGkramaNa-viSNupadI", 6: "kanyA-ravi-saGkramaNa-SaDazIti", 7: "tulA-saGkramaNa", 8: "vRzcika-ravi-saGkramaNa-viSNupadI", 9: "dhanUravi-saGkramaNa-SaDazIti", 10: "makara-saGkramaNa", 11: "kumbha-ravi-saGkramaNa-viSNupadI", 12: "mIna-ravi-saGkramaNa-SaDazIti", } for d in range( self.panchaanga.duration_prior_padding, self.panchaanga.duration + self.panchaanga.duration_prior_padding): if self.daily_panchaangas[ d].solar_sidereal_date_sunset.month_transition is not None: punya_kaala_str = SANKRANTI_PUNYAKALA_NAMES[ self.daily_panchaangas[d + 1].solar_sidereal_date_sunset. month] + '-puNyakAlaH' jd_transition = self.daily_panchaangas[ d].solar_sidereal_date_sunset.month_transition # TODO: convert carefully to relative nadikas! punya_kaala_start_jd = jd_transition - PUNYA_KAALA[ self.daily_panchaangas[ d + 1].solar_sidereal_date_sunset.month][0] * 1 / 60 punya_kaala_end_jd = jd_transition + PUNYA_KAALA[ self.daily_panchaangas[ d + 1].solar_sidereal_date_sunset.month][1] * 1 / 60 if punya_kaala_start_jd < self.daily_panchaangas[ d].julian_day_start: fday = d - 1 else: fday = d self.panchaanga.add_festival_instance( festival_instance=FestivalInstance( name=punya_kaala_str, interval=Interval(jd_start=punya_kaala_start_jd, jd_end=punya_kaala_end_jd)), date=self.daily_panchaangas[fday].date)
def assign_nakshatra_vara_yoga_vratam(self): if 'Adityahasta-puNyakAlaH' not in self.rules_collection.name_to_rule: return for d in range( self.panchaanga.duration_prior_padding, self.panchaanga.duration + self.panchaanga.duration_prior_padding): # NAKSHATRA-WEEKDAY FESTIVALS for (nwd_fest_n, nwd_fest_wd, nwd_fest_name) in ( (13, 0, 'Adityahasta-puNyakAlaH'), (8, 0, 'ravipuSyayOga-puNyakAlaH'), (22, 1, 'sOmazrAvaNI-puNyakAlaH'), (5, 1, 'sOmamRgazIrSa-puNyakAlaH'), (1, 2, 'bhaumAzvinI-puNyakAlaH'), # (6, 2, 'bhaumArdrA-puNyakAlaH'), removed because no pramANam (17, 3, 'budhAnurAdhA-puNyakAlaH'), (8, 4, 'gurupuSya-puNyakAlaH'), (27, 5, 'bhRgurEvatI-puNyakAlaH'), (4, 6, 'zanirOhiNI-puNyakAlaH'), ): n_prev = ((nwd_fest_n - 2) % 27) + 1 if (self.daily_panchaangas[d].sunrise_day_angas. nakshatra_at_sunrise.index == nwd_fest_n or self.daily_panchaangas[d].sunrise_day_angas. nakshatra_at_sunrise.index == n_prev ) and self.daily_panchaangas[d].date.get_weekday( ) == nwd_fest_wd: # Is it necessarily only at sunrise? d0_angas = self.daily_panchaangas[ d].day_length_based_periods.dinamaana.get_boundary_angas( anga_type=AngaType.NAKSHATRA, ayanaamsha_id=self.ayanaamsha_id) # if any(x == nwd_fest_n for x in [self.daily_panchaangas[d].sunrise_day_angas.nakshatra_at_sunrise.index, d0_angas.start.index, d0_angas.end.index]): # self.panchaanga.add_festival(fest_id=nwd_fest_name, date=self.daily_panchaangas[d].date) nakshatram_praatah = self.daily_panchaangas[ d].sunrise_day_angas.nakshatra_at_sunrise.index nakshatram_saayam = NakshatraDivision( jd=self.daily_panchaangas[d].jd_sunset, ayanaamsha_id=self.panchaanga.computation_system. ayanaamsha_id).get_anga( anga_type=AngaType.NAKSHATRA).index if nakshatram_praatah == nakshatram_saayam == n_prev: continue if nwd_fest_n == nakshatram_praatah == nakshatram_saayam: self.panchaanga.add_festival_instance( festival_instance=FestivalInstance( name=nwd_fest_name), date=self.daily_panchaangas[d].date) else: (nakshatra_ID, nakshatra_end_jd) = ( self.daily_panchaangas[d].sunrise_day_angas. nakshatras_with_ends[0].anga.index, self.daily_panchaangas[d].sunrise_day_angas. nakshatras_with_ends[0].jd_end) if nwd_fest_n == nakshatram_praatah: # assert nwd_fest_n == nakshatra_ID self.panchaanga.add_festival_instance( festival_instance=FestivalInstance( name=nwd_fest_name, interval=Interval( jd_start=None, jd_end=nakshatra_end_jd)), date=self.daily_panchaangas[d].date) elif nwd_fest_n == nakshatram_saayam: # assert n_prev == nakshatra_ID self.panchaanga.add_festival_instance( festival_instance=FestivalInstance( name=nwd_fest_name, interval=Interval( jd_start=nakshatra_end_jd, jd_end=None)), date=self.daily_panchaangas[d].date) else: logging.error('Should never be here!')
def assign_ekaadashii_vratam(self): if "ajA-EkAdazI" not in self.rules_collection.name_to_rule: return for d in range( self.panchaanga.duration_prior_padding, self.panchaanga.duration + self.panchaanga.duration_prior_padding): day_panchaanga = self.daily_panchaangas[d] # EKADASHI Vratam # One of two consecutive tithis must appear @ sunrise! if (day_panchaanga.sunrise_day_angas.tithi_at_sunrise.index % 15) == 10 or ( day_panchaanga.sunrise_day_angas.tithi_at_sunrise.index % 15) == 11: yati_ekaadashii_fday = smaarta_ekaadashii_fday = vaishnava_ekaadashii_fday = None ekaadashii_tithi_days = [ x.sunrise_day_angas.tithi_at_sunrise.index % 15 for x in self.daily_panchaangas[d:d + 3] ] if day_panchaanga.sunrise_day_angas.tithi_at_sunrise.index > 15: ekaadashii_paksha = 'krishna' else: ekaadashii_paksha = 'shukla' if ekaadashii_tithi_days in [[11, 11, 12], [10, 12, 12]]: smaarta_ekaadashii_fday = d + 1 tithi_arunodayam = tithi.get_tithi( self.daily_panchaangas[d + 1].jd_sunrise - (1 / 15.0) * (self.daily_panchaangas[d + 1].jd_sunrise - day_panchaanga.jd_sunrise)).index if tithi_arunodayam % 15 == 10: vaishnava_ekaadashii_fday = d + 2 else: vaishnava_ekaadashii_fday = d + 1 elif ekaadashii_tithi_days in [[10, 12, 13], [11, 12, 13], [11, 12, 12], [11, 12, 14]]: smaarta_ekaadashii_fday = d tithi_arunodayam = temporal.tithi.get_tithi( day_panchaanga.jd_sunrise - (1 / 15.0) * (day_panchaanga.jd_sunrise - self.daily_panchaangas[d - 1].jd_sunrise)).index if tithi_arunodayam % 15 == 11 and ekaadashii_tithi_days in [ [11, 12, 13], [11, 12, 14] ]: vaishnava_ekaadashii_fday = d else: vaishnava_ekaadashii_fday = d + 1 elif ekaadashii_tithi_days in [[10, 11, 13], [11, 11, 13]]: smaarta_ekaadashii_fday = d vaishnava_ekaadashii_fday = d + 1 yati_ekaadashii_fday = d + 1 else: pass # These combinations are taken care of, either in the past or future. # if ekaadashii_tithi_days == [10, 11, 12]: # logging.debug('Not assigning. Maybe tomorrow?') # else: # logging.debug(('!!', d, ekaadashii_tithi_days)) if yati_ekaadashii_fday == smaarta_ekaadashii_fday == vaishnava_ekaadashii_fday is None: # Must have already assigned pass elif yati_ekaadashii_fday is None: if smaarta_ekaadashii_fday == vaishnava_ekaadashii_fday: # It's sarva ekaadashii self.panchaanga.add_festival( fest_id='sarva-' + names.get_ekaadashii_name( ekaadashii_paksha, day_panchaanga.lunar_month_sunrise.index), date=self. daily_panchaangas[smaarta_ekaadashii_fday].date) if ekaadashii_paksha == 'shukla': if day_panchaanga.solar_sidereal_date_sunset.month == 9: self.panchaanga.add_festival( fest_id='sarva-vaikuNTha-EkAdazI', date=self.daily_panchaangas[ smaarta_ekaadashii_fday].date) else: self.panchaanga.add_festival( fest_id='smArta-' + names.get_ekaadashii_name( ekaadashii_paksha, day_panchaanga.lunar_month_sunrise.index), date=self. daily_panchaangas[smaarta_ekaadashii_fday].date) self.panchaanga.add_festival( fest_id='vaiSNava-' + names.get_ekaadashii_name( ekaadashii_paksha, day_panchaanga.lunar_month_sunrise.index), date=self. daily_panchaangas[vaishnava_ekaadashii_fday].date) if ekaadashii_paksha == 'shukla': if day_panchaanga.solar_sidereal_date_sunset.month == 9: self.panchaanga.add_festival( fest_id='smArta-vaikuNTha-EkAdazI', date=self.daily_panchaangas[ smaarta_ekaadashii_fday].date) self.panchaanga.add_festival( fest_id='vaiSNava-vaikuNTha-EkAdazI', date=self.daily_panchaangas[ vaishnava_ekaadashii_fday].date) else: self.panchaanga.add_festival( fest_id='smArta-' + names.get_ekaadashii_name( ekaadashii_paksha, day_panchaanga.lunar_month_sunrise.index) + ' (gRhastha)', date=self.daily_panchaangas[smaarta_ekaadashii_fday]. date) self.panchaanga.add_festival( fest_id='smArta-' + names.get_ekaadashii_name( ekaadashii_paksha, self.daily_panchaangas[d]. lunar_month_sunrise.index) + ' (sannyastha)', date=self.daily_panchaangas[yati_ekaadashii_fday].date) self.panchaanga.add_festival( fest_id='vaiSNava-' + names.get_ekaadashii_name( ekaadashii_paksha, day_panchaanga.lunar_month_sunrise.index), date=self.daily_panchaangas[vaishnava_ekaadashii_fday]. date) if day_panchaanga.solar_sidereal_date_sunset.month == 9: if ekaadashii_paksha == 'shukla': self.panchaanga.add_festival( fest_id='smArta-vaikuNTha-EkAdazI (gRhastha)', date=self.daily_panchaangas[ smaarta_ekaadashii_fday].date) self.panchaanga.add_festival( fest_id='smArta-vaikuNTha-EkAdazI (sannyastha)', date=self. daily_panchaangas[yati_ekaadashii_fday].date) self.panchaanga.add_festival( fest_id='vaiSNava-vaikuNTha-EkAdazI', date=self.daily_panchaangas[ vaishnava_ekaadashii_fday].date) if yati_ekaadashii_fday == smaarta_ekaadashii_fday == vaishnava_ekaadashii_fday is None: # Must have already assigned pass else: if day_panchaanga.solar_sidereal_date_sunset.month == 8 and ekaadashii_paksha == 'shukla': # self.add_festival('guruvAyupura-EkAdazI', smaarta_ekaadashii_fday) self.panchaanga.add_festival( fest_id='guruvAyupura-EkAdazI', date=self. daily_panchaangas[vaishnava_ekaadashii_fday].date) self.panchaanga.add_festival( fest_id='kaizika-EkAdazI', date=self. daily_panchaangas[vaishnava_ekaadashii_fday].date) # Harivasara Computation if ekaadashii_paksha == 'shukla': def f(x): tp_float = NakshatraDivision( x, ayanaamsha_id=self.ayanaamsha_id ).get_anga_float(zodiac.AngaType.TITHI_PADA) return tp_float - 45 harivasara_end = brentq( f, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise - 2, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise + 2) else: def f(x): tp_float = NakshatraDivision( x, ayanaamsha_id=self.ayanaamsha_id ).get_anga_float(zodiac.AngaType.TITHI_PADA) return tp_float - 105 harivasara_end = brentq( f, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise - 2, self.daily_panchaangas[smaarta_ekaadashii_fday]. jd_sunrise + 2) _date = self.panchaanga.city.get_timezone_obj( ).julian_day_to_local_time(julian_day=harivasara_end) _date.set_time_to_day_start() fday_hv = time.utc_gregorian_to_jd( _date) - time.utc_gregorian_to_jd( self.daily_panchaangas[0].date) fest = FestivalInstance(name='harivAsaraH', interval=Interval( jd_start=None, jd_end=harivasara_end)) self.panchaanga.add_festival_instance( festival_instance=fest, date=self.daily_panchaangas[int(fday_hv)].date)
def test_get_interval(): assert interval.get_interval(start_jd=1, end_jd=11, part_index=[0], num_parts=1) == Interval(jd_start=1, jd_end=11)