#!/bin/python import os import sys import subprocess import datetime import cgi import cgitb from dir_list import Directories import pyready as pr from volcalert import VolcatXML # ----------------------------------------------------------------------------- # NOAA Air Resources Laboratory # autoash.py # Purpose - user enters information for HYSPLIT run # - last modified - March 23, 2019 # - last modified - March 12, 2020 # - last modified - August 13, 2020 # ------------------------------------------------------------------ # Define Directory Variables.. def find_trajrun(date, volc_id, tdir, urlpath=None, namebase='traj_', nametype='gif'): """ Searches for trajectory (.png, .gif, .ps, or .kml) files. If they are present in the search directory, their URL path is returned. Any .ps files are converted to .gif files for presentation. Files are checked to see if they exist in the directory - if so, they are not copied. Inputs: --------- date: datetime object volc_id: string (volcano ID) tdir: string (from directory) urlpath: string (URL pathname) namebase: string (filename base) nametype: string (filename type) Outputs: ------------ namegif: string (name of converted file) """ suffix = date.strftime("%Y%m%d%H%M%S") + '_' + str(volc_id) # if gif or kmz already exists then return filename = namebase + suffix + '.' + nametype if os.path.isfile(os.path.join(tdir, filename)): return urlpath + '/' + filename if urlpath is not None else filename # if ps exists but not gif then convert and return if nametype == 'gif': psname = namebase + suffix + '.ps' pspath = os.path.join(tdir, psname) if os.path.exists(pspath): gifpath = os.path.join(tdir, filename) pr.im_convert(pspath, gifpath) return urlpath + '/' + filename if urlpath is not None else filename return None def find_disprun(date, volc_id, tdir, urlpath=None, namebase='disp_', num='', nametype='gif'): """ Searches for dispersion (.ps) files. If they are present in the search directory, they are copied to the new directory. Any .ps files are converted to .gif files for presentation. Files are checked to see if they exist in new directory - if so, they are not copied. Inputs: --------- date: datetime object volc_id: string (volcano ID) tdir: string (from directory) urlpath: string (URL pathname) namebase: string (filename base) nametype: string (filename type) Outputs: ------------ namegif: string (name of converted file) """ suffix = date.strftime("%Y%m%d%H%M%S") + '_' + str(volc_id) # if gif already exists then return filename = namebase + suffix + num + '.' + nametype if os.path.isfile(os.path.join(tdir, filename)): return urlpath + '/' + filename if urlpath is not None else filename # if ps exists but not gif then convert and return if nametype == 'gif': psname = namebase + suffix + num + '.ps' pspath = os.path.join(tdir, psname) if os.path.exists(pspath): gifpath = os.path.join(tdir, filename) pr.im_convert(pspath, gifpath) return urlpath + '/' + filename if urlpath is not None else filename return None def get_all_alerts(satellite=None): """ Creating array of alert values for all alerts within the ftp folder (dirname) Inputs: --------- satellite: string (nothing or name of particular satellite) Output: ---------- alist: list (list of alerts) """ # possible values of satellite are # HIMAWARI, GOES-16, GOES-17, SNPP, Meteosat, Aqua if not satellite: satellite = [] if isinstance(satellite, str): satellite = [satellite] dirname = '/pub/jpsss_upload/' alist = [] for (dirpath, dirnames, filenames) in os.walk(dirname): iii = 0 for fl in filenames: addtolist = False if not satellite: addtolist = True for sat in satellite: if sat in fl: addtolist = True if 'xml' not in fl: addtolist = False if addtolist: try: alert = VolcatXML(dirpath + fl) except: continue alist.append(alert) return alist def filter_by_date(alist, dates): """ Filter list alerts by date. Inputs: --------- alist: list (list of alerts) dates: datetime object Output: ---------- newalist: list (new date-sorted list of alerts) """ newalist = [] for alert in alist: if alert.indate(dates): newalist.append(alert) return newalist def filter_by_volcano(alist, vnames): """ Checks to see if volcano name in alert exists. If it does, the list is filtered by volcano name. Inputs: --------- alist: list (list of alerts) vnames: string (volcano names) Output: ---------- newalist: list (new list of alerts) """ if isinstance(vnames, str): vnames = [vnames] newalist = [] for alert in alist: for volc in vnames: if alert.isvolc(volc): newalist.append(alert) return newalist def filter_by_vaac(alist, vaac): """ Filters list of alerts by VAAC region. Inputs: --------- alist: list (list of alerts) vaac: string (vaac region of interest) Output: ---------- newalist: list (new list of alerts) """ newalist = [] for alert in alist: if alert.isvaac(vaac): newalist.append(alert) return newalist def get_volcano_list(alist): """ Creates list of volcano names in list of alerts. Input: -------- alist: list (list of alerts) Output: ---------- vnames: list (list of volcano names) """ vnames = [] for alert in alist: for vn in alert.volcanoes: vnames.append(vn.name) # print(vnames) return list(set(vnames)) def get_vaac_list(alist): """Creat list of vaac regions Input: list of alerts Output: list of vaac regions""" vaacs = [] for alert in alist: vaacs.append(alert.vaac) return list(set(vaacs)) def check_alerts(satellite=None, vnames=None, vaacs=None, getfiles=False): """Checks for alerts and get files pertaining to volcano name or vaac region Inputs: satellite, vname (volcano name) vaacs (vaac region), getfiles (boolean) Output: list of alerts""" # Date and time of 48 hrs earlier dlast = datetime.datetime.now() - datetime.timedelta(hours=48) # walk through directory to find alerts. alist = get_all_alerts(satellite=satellite) if vnames: alist = filter_by_volcano(alist, vnames) alist = filter_by_date(alist, [dlast]) if vaacs: alist = filter_by_vaac(alist, vaacs) alist = filter_by_date(alist, [dlast]) if getfiles: alist = findfiles(alist) return alist def findfiles(alist): """Searches both dispersion and trajectory working directories for newly generated figures. Adds the files to the new directory. Input: list of alerts Output: list of alerts """ trajdir = '/pub/ready/hysplitash/VOLCASH/Trajectory' dispdir = '/pub/ready/hysplitash/VOLCASH/Dispersion' trajoutdir = 'VOLCASH/Trajectory' dispoutdir = 'VOLCASH/Dispersion' for alert in alist: volc_id = alert.volcanoes[0].vid # trajectory traj = find_trajrun(alert.date, volc_id, trajdir, trajoutdir, nametype='png') if traj is not None: alert.add_trajrun(traj) else: traj = find_trajrun(alert.date, volc_id, trajdir, trajoutdir, nametype='gif') if traj is not None: alert.add_trajrun(traj) trajkmz = find_trajrun(alert.date, volc_id, trajdir, trajoutdir, nametype='kmz') alert.add_trajkmz(trajkmz) # dispersion disp1 = find_disprun(alert.date, volc_id, dispdir, dispoutdir, num='0001', nametype='png') if disp1 is not None: alert.add_disprun1(disp1) else: disp1 = find_disprun(alert.date, volc_id, dispdir, dispoutdir, num='0001', nametype='gif') if disp1 is not None: alert.add_disprun1(disp1) disp2 = find_disprun(alert.date, volc_id, dispdir, dispoutdir, num='0002', nametype='png') if disp2 is not None: alert.add_disprun2(disp2) else: disp2 = find_disprun(alert.date, volc_id, dispdir, dispoutdir, num='0002', nametype='png') if disp2 is not None: alert.add_disprun2(disp2) #disp3 = find_disprun(alert.date, volc_id, dispdir, outdir, num = '0003', nametype = 'gif') # alert.add_disprun3(disp3) #dispkmz = find_disprun(alert.date, volc_id, dispdir, outdir, nametype = 'kmz') # alert.add_dispkmz(dispkmz) return alist def create_alert_table(alist, sortby='date'): """Creates the website table Inputs: list of alerts, sortby (method of sorting: 'date')""" alerthash = {} # Create table with alerts newstr = """

VOLCAT Alerts and corresponding HYSPLIT trajectory and dispersion runs for the last 48 hours

Trajectory and dispersion runs are generated when an alert is received

""" iii = 0 # choose the order to write the alerts in sortby = 'date' if sortby == 'vaac': alist.sort(key=lambda x: (x.vaac, x.date), reverse=False) if sortby == 'date': # from most to least recent alist.sort(key=lambda x: x.date, reverse=True) if sortby == 'atype': # first sort by type and then from most to least recent alist.sort(key=lambda x: (x.alert_type, x.date), reverse=False) for alert in alist: alerthash[iii] = alert newstr += '\n' iii += 1 newstr += "
Date and Time (UTC): Alert Type Location
(lat, lon)
Nearby Volcanoes VAAC Region HYSPLIT Trajectories HYSPLIT Dispersion
\n' newstr += 'Alert ' + str(iii) newstr += '\n' newstr += alert.date.strftime("%m/%d/%Y at %H:%M UTC") newstr += '\n' newstr += alert.alert_type newstr += '\n' newstr += str(alert.lat) + ', ' + str(alert.lon) newstr += '\n' for volc in alert.volcanoes: newstr += volc.name newstr += ' | ' ii = newstr.rfind('|') newstr = newstr[:ii] newstr += '\n' newstr += alert.vaac newstr += '\n' if alert.trajkmz: trajlink = '
  • kmz

  • \n' newstr += trajlink if alert.trajrunps: trajlink = '
  • {}

  • \n'.format(ext) newstr += trajlink newstr += '
    \n' if alert.disprunps1: displink = '
  • 3hrs

  • \n' newstr += displink if alert.disprunps2: displink = '
  • 6hrs

  • \n' newstr += displink # if alert.disprunps3: # displink = '
  • 18hrs

  • \n' # newstr += displink newstr += '
    \n" return alerthash, newstr # -------------------------------------------------------------------------------------------------------------- # MAIN # -------------------------------------------------------------------------------------------------------------- dlist = Directories() print(pr.get_header(dlist, 'header1.inc')) # The help script is not working properly. compare to disp1.pl print(pr.help_java()) print(pr.get_header(dlist, 'header2.inc')) page_header = """
  • ARL Home
  •  > READY
  •  > Transport & Dispersion Modeling
  •  > Volcanic Ash
  •  > Run the HYSPLIT Volcanic Ash Model
  •  > Forecast Volcanic Ash
  • READY logo

    Volcanic Ash """ print(page_header) print('') # Necessary to form webpage form = cgi.FieldStorage() try: alert = form.getvalue('alert') vaac = form.getvalue('vaac') except: alert = 'Bagana' # ------------------------------------------------------------------------------------------------ alist = check_alerts() volcano_list = get_volcano_list(alist) vaac_list = get_vaac_list(alist) #alerthash, newstr = create_alert_table(alist) # iii=alerthash.keys() iii = sorted(volcano_list) choices = [] choices.append((dlist.CGIBIN + '/' + 'autoash.py?alert=unknown', 'Most recent')) cstr = dlist.CGIBIN + '/' + 'autoash.py?alert=' cstr += '999' cstr = dlist.CGIBIN + '/' + 'autoash.py?alert=' selected = alert for ii in iii: cstr = dlist.CGIBIN + '/' + 'autoash.py?alert=' cstr += str(ii) cstr2 = '' + str(ii) choices.append((cstr, cstr2)) v = sorted(vaac_list) choices2 = [] choices2.append((dlist.CGIBIN + '/' + 'autoash.py?vaac=all', 'All VAACs')) cstrv = dlist.CGIBIN + '/' + 'autoash.py?vaac=' cstrv += '999' cstrv = dlist.CGIBIN + '/' + 'autoash.py?vaac=' selected2 = vaac for iv in v: cstrv = dlist.CGIBIN + '/' + 'autoash.py?vaac=' cstrv += str(iv) cstrv2 = '' + str(iv) choices2.append((cstrv, cstrv2)) hstr = """ HYSPLIT trajectory and dispersion runs are generated in response to alerts produced by the volcanic cloud monitoring system (VOLCAT)""" hstr += """

    Choose a volcano:

    """ print(hstr) print(pr.guideform(choices, selected)) hstr2 = """

    or Choose a VAAC region:

    """ # print(hstr2) #print(pr.guideform(choices2, selected2)) if alert == '999': alert = None if alert == 'all': alert = None if alert == 'unknown': alert = None #if vaac=='999': vaac = None #if vaac=='all': vaac=None #if vaac=='unknown':vaac=None if alert: alist = check_alerts(vnames=alert, getfiles=True) alerthash, newstr = create_alert_table(alist) print(newstr) # if vaac: # alist = check_alerts(vaacs=vaac, getfiles = True) # alerthash, newstr = create_alert_table(alist) # print(newstr) else: alist = check_alerts() alist.sort(key=lambda x: (x.date), reverse=False) alist = alist[-20:] alist = findfiles(alist) alerthash, newstr = create_alert_table(alist) print(newstr) newstr = """
    """ # print(newstr) # ---------------------------------------- # ---------------------------------------- print("") print('') print('') print('') print('')