def check_alerts_callback(bot=None): current_time = int(timegm(gmtime())) timecheck = current_time + int(LOOP_INTERVAL) # This seems like it might be a bit of a waste. But it should stop the rare occurance of "double tell delivery" (I've only seen it happen once.) alerts = bot.dbQuery('''SELECT id, target_user, alert_time, created_time, source, source_user, msg FROM alert WHERE delivered=0 AND alert_time<? ORDER BY alert_time;''', (timecheck,)) deliver_now = {} deliver_soon = {} for a in alerts: chan_or_user = a['source'].lower() delay = a['alert_time'] - current_time if delay <= 0: deliver_now.setdefault(chan_or_user, []).append(a) else: deliver_soon.setdefault(chan_or_user, []).append(a) for chan_or_user, alerts in deliver_now.iteritems(): deliver_alerts(chan_or_user, alerts) for chan_or_user, alerts in deliver_soon.iteritems(): ids = '_'.join(str(x['id']) for x in alerts) timer_name = '%s_%s' % (TIMER_NAME, ids) try: Timers.addtimer(timer_name, delay, deliver_alerts, reps=1, chan_or_user=chan_or_user, alerts=alerts, bot=bot) except TimerExists: pass
def timers(event, bot): command, args = commandSplit(event.argument) if command == "show": bot.say("Timers:") for timer in Timers.getTimers().itervalues(): bot.say(" - %s: reps = %s, delay = %s, f = %s" % (timer.name, timer.reps, timer.interval, timer.f)) elif command == "add": args = argumentSplit(args, 4) #add timername delay reps msg if not args: bot.say("Not enough arguments. Need: timername delay reps message (reps <= 0 means forever)") return try: if Timers.addtimer(args[0], float(args[1]), timercallback, reps=int(args[2]), msg=args[3], bot=bot, channel=event.target): bot.say("Timer added (%s)" % args[0]) else: bot.say("Timer not added for some reason?") except TimerExists: bot.say("Timer not added because it exists already.") except TimerInvalidName: bot.say("Timer not added because it has an invalid name.") elif command == "stop": try: Timers.deltimer(args) bot.say("Timer stopped (%s)" % args) except (TimerNotFound, TimerInvalidName): bot.say("Can't stop (%s) because timer not found or internal timer." % args)
def timers(event, bot): command, args = commandSplit(event.argument) if command == "show": bot.say("Timers:") for timer in Timers.getTimers().itervalues(): bot.say(" - %s: reps = %s, delay = %s, f = %s" % (timer.name, timer.reps, timer.interval, timer.f)) elif command == "add": args = argumentSplit(args, 4) #add timername delay reps msg if not args: bot.say( "Not enough arguments. Need: timername delay reps message (reps <= 0 means forever)" ) return msg = Timers.addtimer(args[0], float(args[1]), timercallback, reps=int(args[2]), msg=args[3], bot=bot, channel=event.target)[1] bot.say("%s (%s)" % (msg, args[0])) elif command == "stop": bot.say(Timers.deltimer(args)[1])
def nickChanged(event, bot): if bot.getOption("restorenick", module="pbm_nicktools"): snick = bot.getOption("nick") if event.newname != snick: # start timer to checkandrecov try: Timers.addtimer("NICKTOOLS_%s" % bot.network, float(bot.getOption("checkevery", module="pbm_nicktools")), nickCheckAndRecover, reps=-1, bot=bot ) except TimerExists: pass else: # have desired nick, delete check timers try: Timers.deltimer("NICKTOOLS_%s" % bot.network) except TimerNotFound: pass # TODO: like below, when state can track +r, this should be checked before attempting identify identify(bot, snick)
def make_approx(self): 'make the linear approximation according to the settings' Timers.tic('make_approx') self.eobs_func = self.make_eobs_func() x_mat, y_mat = self.settings.data_source.make_data( self.settings.der_func, self.eobs_func) # do regression self.do_regression(x_mat, y_mat) Timers.toc('make_approx')
def eobs_func(state_mat): 'returns a matrix of extended observations based on the passed-in state matrix' # work with rows because it's faster state_mat = state_mat.T.copy() Timers.tic('eobs_func') eobs_mat = np.zeros((state_mat.shape[1], output_dims), dtype=float) print(f"eobs shape: {eobs_mat.shape}") for state, eobs in zip(state_mat, eobs_mat): index = 0 # original if s.include_original_vars: for i in range(n): eobs[index] = state[i] index += 1 # power basis if s.power_order is not None: for iterator in s.power_order**n: val = 1 temp = iterator # extract the iterator for each dimension for dim_num in range(n): deg = temp % s.power_order temp = temp // s.power_order val *= state[dim_num]**deg eobs[index] = val index += 1 Timers.toc('eobs_func') return eobs_mat.transpose().copy()
def main(): 'main entry point' Timers.tic('total') sim_data = SingleSimulationData() sim_data.tmax = 6.5 sim_data.npoints = 100 sim_data.init = [1.4, 2.4] sim_data.plot = True s = Settings() s.der_func = der_func s.dims = 2 s.data_source = sim_data koop = Koopman(s) koop.make_approx() koop.plot_approx(sim_data.init, sim_data.npoints, max_norm=10) koop.save_plot('vanderpol.png') Timers.toc('total') Timers.print_stats()
def timers(event, bot): command, args = commandSplit(event.argument) if command == "show": bot.say("Timers:") for timer in Timers.getTimers().itervalues(): bot.say(" - %s: reps = %s, delay = %s, f = %s" % (timer.name, timer.reps, timer.interval, timer.f)) elif command == "add": args = argumentSplit(args, 4) #add timername delay reps msg if not args: bot.say( "Not enough arguments. Need: timername delay reps message (reps <= 0 means forever)" ) return try: if Timers.addtimer(args[0], float(args[1]), timercallback, reps=int(args[2]), msg=args[3], bot=bot, channel=event.target): bot.say("Timer added (%s)" % args[0]) else: bot.say("Timer not added for some reason?") except TimerExists: bot.say("Timer not added because it exists already.") except TimerInvalidName: bot.say("Timer not added because it has an invalid name.") elif command == "stop": try: Timers.deltimer(args) bot.say("Timer stopped (%s)" % args) except (TimerNotFound, TimerInvalidName): bot.say( "Can't stop (%s) because timer not found or internal timer." % args)
def nickChanged(event, bot): if bot.getOption("restorenick", module="pbm_nicktools"): snick = bot.getOption("nick") if event.newname != snick: # start timer to checkandrecov try: Timers.addtimer("NICKTOOLS_%s" % bot.network, float( bot.getOption("checkevery", module="pbm_nicktools")), nickCheckAndRecover, reps=-1, bot=bot) except TimerExists: pass else: # have desired nick, delete check timers try: Timers.deltimer("NICKTOOLS_%s" % bot.network) except TimerNotFound: pass # TODO: like below, when state can track +r, this should be checked before attempting identify identify(bot, snick)
def plot_approx(self, init, npoints, xdim=0, ydim=1, col='k-', label='eDMD Approx', max_norm=float('inf')): 'plot the approximation' Timers.tic('plot_approx') xs = [] ys = [] init = np.array(init, dtype=float) init.shape = (self.settings.dims, 1) estate = self.eobs_func(init) xs.append(estate[xdim]) ys.append(estate[ydim]) print(f"estate shape: {estate.shape}, a_mat shape: {self.a_mat.shape}") for step in range(npoints): Timers.tic('dot') estate = np.dot(self.a_mat, estate) Timers.toc('dot') x = estate[xdim] y = estate[ydim] if np.linalg.norm([x, y]) > max_norm: print( f"Approximation was bad at step {step} (plotting stopped prematurely)" ) break xs.append(x) ys.append(y) plt.plot(xs, ys, col, label=label) Timers.toc('plot_approx')
def unload(): Timers._delPrefix( "NICKTOOLS_" ) # use non blocking call version since unload is called in the reactor
def unload(): Timers._delPrefix("NICKTOOLS_") # use non blocking call version since unload is called in the reactor
def do_regression(self, x1, x2): '''do regression on the x and y matrices This produces self.a_mat ''' Timers.tic('regression') if self.settings.pseudo_inverse_method == Settings.DIRECT: Timers.tic('pinv') x_pseudo = np.linalg.pinv(x1) Timers.toc('pinv') Timers.tic('dot') self.a_mat = np.dot(x2, x_pseudo) Timers.toc('dot') print( f"after regression, x1 shape: {x1.shape}, x2 shape: {x2.shape}, a_mat shape: {self.a_mat.shape}" ) else: raise RuntimeError( f"Unimplemented pesudo-inverse method: {self.pseudo_inverse_methods}" ) Timers.toc('regression')
def alert(event, bot): """ alert target datespec msg. Alert a user <target> about a message <msg> at <datespec> time. datespec can be relative (in) or calendar/day based (on), e.g. 'in 5 minutes'""" target, dtime1, dtime2, msg = argumentSplit(event.argument, 4) if not target: return bot.say(functionHelp(alert)) if dtime1.lower() == "tomorrow": target, dtime1, msg = argumentSplit(event.argument, 3) # reparse is easiest way I guess... resolves #30 if need to readdress dtime2 = "" else: if not (dtime1 and dtime2): return bot.say("Need time to alert.") if not msg: return bot.say("Need something to alert (%s)" % target) origuser = USERS_MODULE.get_username(bot, event.nick) users, unknown, dupes, _ = _lookup_users(bot, target, origuser, False) if not users: return bot.say("Sorry, don't know (%s)." % target) dtime = "%s %s" % (dtime1, dtime2) # user location aware destination times locmod = None goomod = None timelocale = False try: locmod = bot.getModule("pbm_location") goomod = bot.getModule("pbm_googleapi") timelocale = True except ConfigException: pass origin_time = timegm(gmtime()) alocal_time = localtime(origin_time) local_offset = timegm(alocal_time) - origin_time if locmod and goomod: t = origin_time loc = locmod.getlocation(bot.dbQuery, origuser) if not loc: timelocale = False t = alocal_time else: tz = goomod.google_timezone(loc[1], loc[2], t) if not tz: timelocale = False t = alocal_time else: t = gmtime(t + tz[2] + tz[3]) #[2] dst [3] timezone offset else: t = alocal_time ntime = parseDateTime(dtime, t) if not ntime: return bot.say("Don't know what time and/or day and/or date (%s) is." % dtime) # go on, change it. I dare you. if timelocale: t = timegm(t) - tz[2] - tz[3] ntime = ntime - tz[2] - tz[3] else: t = timegm(t) - local_offset ntime = ntime - local_offset if ntime < t or ntime > (t + MAX_REMIND_TIME): return bot.say("Don't sass me with your back to the future alerts.") if ntime < (t + 5): return bot.say("2fast") targets = [] for user, target in users: if user == origuser: source_user = None else: source_user = event.nick if event.isPM(): chan_or_user = event.nick else: chan_or_user = event.target bot.dbQuery('''INSERT INTO alert(target_user, alert_time, created_time, source, source_user, msg) VALUES (?,?,?,?,?,?);''', (user, int(ntime), int(origin_time), chan_or_user, source_user, msg)) if ntime < (t + LOOP_INTERVAL): Timers.restarttimer(TIMER_NAME) if not source_user: targets.append("you") else: targets.append(target) bot.say(RPL_ALERT_FORMAT % (event.nick, english_list(targets), distance_of_time_in_words(ntime, t), UNKNOWN % english_list(unknown) if unknown else "", MULTIUSER % "Alerting" if dupes else ""))
def unload(): Timers.deltimer(TIMER_NAME)
def make_data(self, der_func, eobs_func): '''generate the data for regression der_func is a derivative function given a single state eobs_func converts a matrix of states to a matrix of (extended) observations returns (x_mat, y_mat) where the regression problem is y_mat = A * x_mat each column of x_mat / y_mat is one set of state vectors ''' Timers.tic('make_data') n = len(self.init) times = np.linspace(0, self.tmax, self.npoints) def der(state, _): 'derivative function (reversed args for odeint)' return der_func(state) Timers.tic('odeint') sol = odeint(der, self.init, times).T Timers.toc('odeint') assert sol.shape[0] == n assert sol.shape[1] == self.npoints if self.plot: Timers.tic('plot') xs = [data[self.plot_xdim] for data in sol.T] ys = [data[self.plot_ydim] for data in sol.T] plt.plot(xs, ys, self.plot_color, label=self.plot_label) Timers.toc('plot') # extend observations mat = eobs_func(sol) x_mat = mat[:-1] y_mat = mat[1:] Timers.toc('make_data') return x_mat, y_mat
def setup_timer(event, bot): Timers.addtimer(TIMER_NAME, LOOP_INTERVAL, check_alerts_callback, reps=-1, startnow=False, bot=bot)