async def getRaRange(): mjd = round(offsetNow()) scheduler = Scheduler() mjd_evening_twilight, mjd_morning_twilight = await wrapBlocking( scheduler.getNightBounds, mjd) ra_start = await wrapBlocking(scheduler.scheduler.lst, mjd_evening_twilight) ra_start = float(ra_start - 45 + 360) % 360 ra_end = await wrapBlocking(scheduler.scheduler.lst, mjd_morning_twilight) ra_end = float(ra_end + 45) % 360 return ra_start, ra_end
async def mjdSummary(mjd): templateDict = getTemplateDictBase() remote_ip = request.headers["Remote-Addr"] # if remote_ip != "127.0.0.1": url = f"https://geolocation-db.com/json/{remote_ip}" response = await wrapBlocking(requests.get, url) city = response.json()["city"] tracking = await wrapBlocking(trackIPs, remote_ip, city) if "mjd" in request.args: mjd = float(request.args["mjd"]) # else: # mjd = offsetNow() if mjd is None: mjd = offsetNow() scheduler = await wrapBlocking(Scheduler) mjd_evening_twilight, mjd_morning_twilight = await wrapBlocking( scheduler.getNightBounds, round(mjd)) mjd = round(mjd_evening_twilight) start = Time(mjd_evening_twilight, format="mjd").datetime end = Time(mjd_morning_twilight, format="mjd").datetime errors = list() fields = await wrapBlocking(getFieldsTimeRange, start, end) mjds = await wrapBlocking(fetchMjds) templateDict.update({ "errorMsg": errors, "fields": fields, "mjd": mjd, "mjds": mjds }) return await render_template("mjdSummary.html", **templateDict)
async def lookAhead(): mjd = round(offsetNow()) form = await request.form args = request.args redo = False # parse POST/GET args if "mjd" in args: mjd = int(args["mjd"]) templateDict = getTemplateDictBase() scheduler = await wrapBlocking(Scheduler) mjd_evening_twilight, mjd_morning_twilight = await wrapBlocking( scheduler.getNightBounds, mjd) fields, errors = await scheduler.schedNoQueue(mjd_evening_twilight, mjd_morning_twilight) startTime = Time(mjd_evening_twilight, format="mjd").datetime endTime = Time(mjd_morning_twilight, format="mjd").datetime evening_twilight_dark, morning_twilight_dark = await wrapBlocking( scheduler.getDarkBounds, mjd) evening_twilight_utc = Time(evening_twilight_dark, format="mjd").datetime morning_twilight_utc = Time(morning_twilight_dark, format="mjd").datetime schedule = { "queriedMJD": mjd, "timeBarStartUTC": startTime, "timeBarEndUTC": endTime, "eveningTwilightUTC": evening_twilight_utc, "morningTwilightUTC": morning_twilight_utc } evening_twilight_dark, morning_twilight_dark = await wrapBlocking( scheduler.getDarkBounds, mjd) brightDark = scheduler.nightSchedule(evening_twilight_dark, morning_twilight_dark) schedule.update(**brightDark) for k, v in brightDark.items(): if v is None: continue brightDark[k] = v.strftime("%H:%M") queue = await wrapBlocking(Queue) # if len(queue.fields) == 0: # viz = None # else: # # queue.scheduleFields(mjd_evening_twilight, mjd_morning_twilight) # viz = ApogeeViz(schedule, queue.fields).export() schedViz = await ApogeeViz(schedule, fields).export() almanac = getAlmanac(mjd) templateDict.update({ "apogeeViz": None, "schedViz": schedViz, "mjd": mjd, "errorMsg": [], "almanac": (*almanac, brightDark), "queue": queue.designs, "backups": [] }) # findAndConvertDatetimes(templateDict) return await render_template("lookAhead.html", **templateDict)
async def fieldViz(): mjd = round(offsetNow()) # now = Time.now() # now.format = "mjd" # mjd_now = now.value form = await request.form errors = list() if "mjd" in form: if len(form["mjd"].strip()) > 0: try: mjd = int(form["mjd"]) except: errors.append("invalid mjd input") design_ids = list() if "designs" in form: d_text = form["designs"] try: if "," in d_text: design_ids = [ int(d) for d in d_text.strip().split(",") if len(d) ] else: design_ids = [int(d_text)] except: errors.append("invalid design input") design_ids = list() else: design_ids = list() templateDict = getTemplateDictBase() scheduler = await wrapBlocking(Scheduler) mjd_evening_twilight, mjd_morning_twilight = await wrapBlocking( scheduler.getNightBounds, mjd) startTime = Time(mjd_evening_twilight, format="mjd").datetime endTime = Time(mjd_morning_twilight, format="mjd").datetime evening_twilight_dark, morning_twilight_dark = await wrapBlocking( scheduler.getDarkBounds, mjd) evening_twilight_utc = Time(evening_twilight_dark, format="mjd").datetime morning_twilight_utc = Time(morning_twilight_dark, format="mjd").datetime schedule = { "queriedMJD": mjd, "timeBarStartUTC": startTime, "timeBarEndUTC": endTime, "eveningTwilightUTC": evening_twilight_utc, "morningTwilightUTC": morning_twilight_utc } evening_twilight_dark, morning_twilight_dark = await wrapBlocking( scheduler.getDarkBounds, mjd) brightDark = scheduler.nightSchedule(evening_twilight_dark, morning_twilight_dark) schedule.update(**brightDark) for k, v in brightDark.items(): if v is None: continue brightDark[k] = v.strftime("%H:%M") mean = (mjd_evening_twilight + mjd_morning_twilight) / 2 designList = await wrapBlocking(DesignList, design_ids=design_ids, mjd=mean) if len(designList.fields) == 0: viz = None else: viz = await ApogeeViz(schedule, designList.fields, useDesign=True).export() almanac = await wrapBlocking(getAlmanac, mjd) if viz is not None: for r in viz["allRows"]: for v in r["vizWindows"]: if v["primary"]: v["opacity"] = 0 templateDict.update({ "apogeeViz": viz, "mjd": mjd, "errorMsg": errors, "almanac": (*almanac, brightDark), # if schedule else None "designs": design_ids, "mjd": mjd }) return await render_template("fieldViz.html", **templateDict)
async def planObserving(): mjd = round(offsetNow()) now = Time.now() now.format = "mjd" mjd_now = now.value form = await request.form args = request.args redo = False # parse POST/GET args if "mjd" in args: # deprecated? mjd = int(args["mjd"]) redo = True if "redo" in args: # deprecated? redo = True if "rmField" in form: rmField = int(form["rmField"]) await wrapBlocking(opsdb.Queue.rm, rmField) elif "flush" in form: await wrapBlocking(opsdb.Queue.flushQueue) elif "redo" in form: redo = True if "replace" in form: replace = int(form["replace"]) else: replace = False if "backup" in form: replacementField = int(form["backup"]) oldField = int(form["prev"]) else: replacementField = None if "remainder" in form: redoFromField = True else: redoFromField = False errors = list() templateDict = getTemplateDictBase() # date = datetime.datetime.utcnow() # date = datetimenow.date() scheduler = await wrapBlocking(Scheduler) mjd_evening_twilight, mjd_morning_twilight = await wrapBlocking( scheduler.getNightBounds, mjd) if mjd_morning_twilight - mjd_now < 1 / 24 / 4: # 15 minutes # Night's basically over, we're doing tomorrow errors.append("END OF NIGHT. Scheduling tomorrow") mjd += 1 mjd_evening_twilight, mjd_morning_twilight = await wrapBlocking( scheduler.getNightBounds, mjd) startTime = Time(mjd_evening_twilight, format="mjd").datetime endTime = Time(mjd_morning_twilight, format="mjd").datetime evening_twilight_dark, morning_twilight_dark = await wrapBlocking( scheduler.getDarkBounds, mjd) evening_twilight_utc = Time(evening_twilight_dark, format="mjd").datetime morning_twilight_utc = Time(morning_twilight_dark, format="mjd").datetime if replacementField is not None: # replacing a field if redoFromField: # is it bad enough to redo the rest of the queue? errors.append(await scheduler.rescheduleAfterField( replacementField, mjd_morning_twilight)) else: # ok just the one then! await scheduler.replaceField(oldField, replacementField) if redo: # clear the queue await wrapBlocking(opsdb.Queue.flushQueue) # redo the whole queue, but check if it's during the night # winter = evening_twilight_utc.month < 3 # if not winter and evening_twilight_utc.month < 4: # winter = evening_twilight_utc.day < 20 # fall = evening_twilight_utc.month > 10 # if not fall and evening_twilight_utc.month > 9: # fall = evening_twilight_utc.day > 22 # if winter or fall: # # either before 3/20 or after 9/22 # mjd_evening_twilight = evening_twilight_dark # mjd_morning_twilight = morning_twilight_dark if mjd_now > mjd_evening_twilight: start_mjd = mjd_now else: start_mjd = mjd_evening_twilight errors.append(await scheduler.queueFromSched(start_mjd, mjd_morning_twilight)) schedule = { "queriedMJD": mjd, "timeBarStartUTC": startTime, "timeBarEndUTC": endTime, "eveningTwilightUTC": evening_twilight_utc, "morningTwilightUTC": morning_twilight_utc } brightDark = scheduler.nightSchedule(evening_twilight_dark, morning_twilight_dark) schedule.update(**brightDark) for k, v in brightDark.items(): if v is None: continue brightDark[k] = v.strftime("%H:%M") queue = await wrapBlocking(Queue) if len(queue.fields) == 0: viz = None else: # queue.scheduleFields(mjd_evening_twilight, mjd_morning_twilight) viz = await ApogeeViz(schedule, queue.fields).export() if replace: # make replace the fieldID to be replaced, or False field = queue.fieldDict[replace] args = await scheduler.choiceFields(field.startTime, exp=len(field.designs), oldPos=[field.ra, field.dec]) # backups = await backupDicts(*args, sched=scheduler, mjd=field.startTime, # prev=replace) backups = await backupDicts(*args, sched=scheduler, mjd=mjd_now, prev=replace) # for f in viz["plateRows"]: # if f["fieldID"] == field.fieldID: # for k in ["mjd_start", "dec", "tableItems", "trueHA"]: # print(f["fieldID"], k, f[k]) else: backups = list() exps = await wrapBlocking(getRecentExps, mjd) almanac = await wrapBlocking(getAlmanac, mjd) for d in queue.designs: d.priority = queue.fieldDict[d.field_pk].priority templateDict.update({ # "apogeeViz": ApogeeViz(schedule, apogeePlateList).export() if apogeePlateList else None, "apogeeViz": viz, "mjd": mjd, "almanac": (*almanac, brightDark), "queue": queue.designs, "backups": backups, "exposures": exps, "errorMsg": errors }) # findAndConvertDatetimes(templateDict) return await render_template("planObserving.html", **templateDict)
async def designDetail(): dbField = targetdb.Field dbDesign = targetdb.Design form = await request.form scheduler = await wrapBlocking(Scheduler) mjd = offsetNow() mjd_evening_twilight, mjd_morning_twilight = await wrapBlocking( scheduler.getNightBounds, round(mjd)) if mjd < mjd_evening_twilight: mjd = mjd_evening_twilight if "insert_design_id" in form: insert_design = int(form["insert_design_id"]) pos = int(form["position"]) if pos == 0: pos = 1 q_mjd = None if pos == 1: q_mjd = mjd await wrapBlocking(safeInsertInQueue, insert_design, pos, mjd_plan=q_mjd) elif "append_design_id" in form: append_design = int(form["append_design_id"]) await wrapBlocking(safeAppendQueue, append_design, mjd_plan=mjd) designID = int(request.args["designID"]) try: design = await wrapBlocking(dbDesign.get, designID) except DoesNotExist: return await render_template('404.html'), 404 status, cartons, fiberCounts = await wrapBlocking(designDetails, design) field = await wrapBlocking(dbField.get, pk=design.field.pk) field = { "ra": field.racen, "dec": field.deccen, "observatory": field.observatory.label, "cadence": field.cadence.label, "fieldID": field.field_id } configurations = await wrapBlocking(getConfigurations, designID) c_names, counts = np.unique(cartons, return_counts=True) targets = [{"name": n, "count": c} for n, c in zip(c_names, counts)] templateDict = getTemplateDictBase() templateDict.update({ "designID": designID, "configurations": configurations, "targets": targets, "designNumber": design.exposure, "status": status, "fiberCounts": fiberCounts, "mjd": int(mjd), **field }) return await render_template("designDetail.html", **templateDict)