Пример #1
0
def create_nei_runlist(tdirpath,
                       hdirpath,
                       sourcedf,
                       sdate,
                       edate,
                       timechunks,
                       units="ppb",
                       tcm=False):
    from os import walk

    # dstart = sdate
    # dend = edate
    hysplitdir = os.path.join(hdirpath, 'exec')
    runlist = []
    dtree = dirtree(tdirpath, sdate, edate, chkdir=False, dhour=timechunks)
    for dirpath in dtree:
        for src in nei_source_generator(sourcedf):
            suffix = "EIS" + src["EIS_ID"].strip()
            sdate = dir2date(tdirpath, dirpath)
            pdate = sdate - datetime.timedelta(hours=timechunks)
            pdir = date2dir(tdirpath, pdate, dhour=timechunks)
            parinitA = "PARDUMP." + suffix
            parinitB = "PARINIT." + suffix
            parinit = (pdir, parinitA, parinitB)
            run = RunDescriptor(dirpath, suffix, hysplitdir, "hycs_std",
                                parinit)
            runlist.append(run)
    return runlist
Пример #2
0
    def obs2datem(self, edate, ochunks=(1000, 1000), tdir="./"):
        """
        ##https://aqsdr1.epa.gov/aqsweb/aqstmp/airdata/FileFormats.html
        ##Time GMT is time of dat that sampling began.
        edate: datetime object
        ochunks: tuple (integer, integer)
                 Each represents hours

        tdir: string
              top level directory for output.
        """
        logger.info("WRITING Datem FILE " + edate.strftime("%Y-%m-%d"))
        #print(self.obs["units"].unique())
        d1 = edate
        done = False
        iii = 0
        maxiii = 1000
        oe = ochunks[1]
        oc = ochunks[0]
        while not done:
            d2 = d1 + datetime.timedelta(hours=oc - 1)
            d3 = d1 + datetime.timedelta(hours=oe - 1)
            odir = date2dir(tdir, d1, dhour=oc, chkdir=True)
            dname = odir + "datem.txt"
            datem.write_datem(self.obs,
                              sitename="siteid",
                              drange=[d1, d3],
                              dname=dname,
                              fillhours=1,
                              verbose=False)
            d1 = d2 + datetime.timedelta(hours=1)
            iii += 1
            if d1 > self.d2:
                done = True
            if iii > maxiii:
                done = True
                logger.warning("WARNING: obs2datem, loop exceeded maxiii")
Пример #3
0
def create_controls(
    tdirpath,
    hdirpath,
    sdate,
    edate,
    timechunks,
    metfmt,
    units="ppb",
    tcm=False,
    orislist=None,
    moffset=0,
    overwritelanduse=True,
):
    """
    read the base control file in tdirpath CONTROL.0
    read the base SETUP.0 file in tdirpath
    walk through all subdirectories in tdirpath.
    For each file with  EMIT as part of the filename
        1. read the file and get number of records in each cycle.
        2. take the suffix from the file
        3. Print out a CONTROL file with same suffix and
              1. duration set by timechunks input
              2. number of starting locations matching the EMITIMES file
              3. start date matching EMITIMES file.
              4. meteorological files matching the dates              
        4. Print out a SETUP file with same suffix and
              1. initialized with parinit file from previous time period.
              2. output pardump file with same suffix at end of run.
              #3. set ninit to 1.
              4. set delt=5 (TO DO- why?) 
        5. write out landuse file
        6. write script in tdirpath for running HYSPLIT.

    tdirpath: str
              top level directory for output.
    tdirpath: str
              directory for hysplit executable
    sdate : datetime object
    edate : datetime object
    timechunks : integer
            run duration.

    RETURNS:
    runlist : list of runDescriptor objects

    # TODO - add ability to base numpar on amount of emissions.
    # will need to read EMITTIME file and find max emission for that time
    # period. Then use 
    """
    from os import walk
    from utilhysplit import emitimes

    # from arlhysplit.runh import getmetfiles

    dstart = sdate
    dend = edate
    ##determines meteorological files to use.
    met_files = MetFiles(metfmt)

    # due to missing files MetFiles does not always automatically calculte
    # correct time spacing of files for the SREF.
    if "sref" in metfmt:
        met_files.set_mdt(24)
    elif "href" in metfmt:
        met_files.set_mdt(24)

    runlist = []  # list of RunDescriptor Objects
    if hdirpath[-1] != "/":
        hdirpath += "/"
    hysplitdir = hdirpath + "exec/"
    landusedir = hdirpath + "bdyfiles/"
    dtree = dirtree(tdirpath, sdate, edate, chkdir=False, dhour=timechunks)
    iii = 0
    # for (dirpath, dirnames, filenames) in walk(tdirpath):
    for dirpath in dtree:
        for (d1, dirnames, filenames) in walk(dirpath):
            for fl in filenames:
                if iii == 0:
                    firstdirpath = dirpath
                make = False
                if "EMIT" in fl[0:4]:
                    make = True
                if "WARNING" in fl:
                    make = False
                if "MESSAGE" in fl:
                    make = False
                if "VMSDIST" in fl:
                    make = False
                    # oris = fl.replace('EMIT','')

                # if orislist not None:
                #   make = True
                if make:
                    suffix = fl[4:8]
                    temp = fl.split(".")
                    if temp[1] != "txt":
                        suffix += "." + temp[1]
                    else:
                        suffix = temp[0].replace("EMIT", "")
                    wdir = dirpath
                    # read emitfile and modify number of locations
                    et = emitimes.EmiTimes(filename=dirpath + "/" + fl)
                    # print(dirpath, fl)
                    et_not_empty = et.read_file()
                    # if the emittimes file not empty then
                    if et_not_empty:
                        # number of locations is number of records
                        # in the emitimes file divided by number of speciess.
                        nrecs = et.cycle_list[0].nrecs / len(et.splist)
                        ht = et.cycle_list[0].recordra[0].height
                        sdate = et.cycle_list[0].sdate
                        ##if sdate not within range given,
                        ##then skip the rest of the loop.
                        if sdate < dstart or sdate > dend:
                            continue
                        lat = et.cycle_list[0].recordra[0].lat
                        lon = et.cycle_list[0].recordra[0].lon
                    ##Write a setup file for this emitimes file
                    setupfile = NameList("SETUP.0", working_directory=tdirpath)
                    setupfile.read()
                    setupfile.add("NDUMP", str(timechunks))
                    setupfile.add("NCYCL", str(timechunks))
                    #setupfile.add("POUTF", '"PARDUMP.' + suffix + '"')
                    setupfile.add("POUTF", 'PARDUMP.' + suffix)
                    setupfile.add("PINPF", '"PARINIT.' + suffix + '"')
                    if not tcm:
                        setupfile.add("NINIT", "1")
                        setupfile.add("EFILE", '"' + fl + '"')
                    else:
                        setupfile.add("NINIT", "0")
                    # setupfile.add('DELT', '5')
                    setupfile.rename("SETUP." + suffix,
                                     working_directory=wdir + "/")
                    setupfile.write(verbose=False)
                    #print("TDIRPATH", tdirpath)
                    ##Write a control file for this emitimes file
                    control = HycsControl(fname="CONTROL.0",
                                          working_directory=tdirpath)
                    control.read()
                    # make sure that control start is always start of time
                    # period.
                    controldate = dir2date(tdirpath, dirpath)
                    control.date = controldate
                    # remove species and add new with same
                    # attributes but different names
                    # even if EMITTIMES file empty there is still
                    # a header with species information.
                    if et.splist.size > 0:
                        sp = control.species[0]
                        control.remove_species()
                        for spec in et.splist:
                            spnew = sp.copy()
                            # print('Adding species', spec)
                            spnew.name = et.sphash[spec]
                            # print(spnew.strpollutant())
                            control.add_species(spnew)

                    # if emit-times file not empty
                    # remove all the locations first and then add
                    # locations that correspond to emittimes file.
                    # if it is empty then still create CONTROL file in case
                    # there is data from PARDUMP file to run.
                    # keep location from default CONTROL.0 file.
                    if et_not_empty:
                        control.remove_locations()
                        nlocs = control.nlocs

                        while nlocs != nrecs:
                            if nlocs < nrecs:
                                control.add_location(latlon=(lat, lon), alt=ht)
                            if nlocs > nrecs:
                                control.remove_locations(num=0)
                            nlocs = control.nlocs

                    control.rename("CONTROL." + suffix, working_directory=wdir)
                    control.remove_metfile(rall=True)
                    ###Add the met files.

                    # mfiles = getmetfiles(
                    #    control.date, timechunks, met_type=met_type, mdir=mdir
                    # )
                    if tcm:
                        timechunks = int(control.run_duration)
                    # ability to have met files cover longer time period.
                    mdate = control.date - datetime.timedelta(hours=moffset)
                    metchunks = timechunks + moffset
                    # mfiles = met_files.get_files(control.date, timechunks)
                    mfiles = met_files.get_files(mdate, metchunks)
                    #print("MFILES", mfiles)
                    #print(mdate, metchunks)
                    #print(control.date, timechunks)
                    for mf in mfiles:
                        if os.path.isfile(mf[0] + mf[1]):
                            control.add_metfile(mf[0], mf[1])
                    for cg in control.concgrids:
                        cg.outfile += "." + suffix
                    if control.num_met > 12:
                        metgrid = True
                    else:
                        metgrid = False
                    control.write(metgrid=metgrid, overwrite=True, query=False)
                    writelanduse(
                        landusedir=landusedir,
                        working_directory=wdir + "/",
                        overwrite=overwritelanduse,
                        verbose=False,
                    )

                    with open(wdir + "/rundatem.sh", "w") as fid:
                        fid.write("MDL=" + hysplitdir + "/\n")
                        fid.write(unit_mult(units=units))
                        fid.write(statmainstr())

                    if dirpath == firstdirpath:
                        parinit = (None, None, None)
                    elif not tcm:
                        sdate = dir2date(tdirpath, dirpath)
                        pdate = sdate - datetime.timedelta(hours=timechunks)
                        pdir = date2dir(tdirpath, pdate, dhour=timechunks)
                        parinitA = "PARDUMP." + suffix
                        parinitB = "PARINIT." + suffix
                        parinit = (pdir, parinitA, parinitB)
                    run = RunDescriptor(wdir, suffix, hysplitdir, "hycs_std",
                                        parinit)
                    wr = "a"
                    if iii == 0:
                        wr = "w"
                    # with open(tdirpath + '/' +  scr, wr) as fid:
                    # fid.write(run.script())
                    # fid.write('\n\n')
                    runlist.append(run)
                    iii += 1
    return runlist
Пример #4
0
def nei_controls(
    tdirpath,
    hdirpath,
    sourcedf,
    sdate,
    edate,
    timechunks,
    metfmt,
    units="ppb",
    tcm=False,
    overwritelanduse=True,
):
    # sourcedf contains info on
    # stackheight
    # emission rate
    # heat input
    from os import walk

    control = HycsControl(fname="CONTROL.0", working_directory=tdirpath)
    control.read()

    dstart = sdate
    dend = edate
    ##determines meteorological files to use.
    met_files = MetFiles(metfmt)
    runlist = []  # list of RunDescriptor Objects
    if hdirpath[-1] != "/":
        hdirpath += "/"
    hysplitdir = os.path.join(hdirpath, "exec")
    landusedir = os.path.join(hdirpath, "bdyfiles")
    #print("LANDUSEDIR", landusedir, hdirpath)
    dtree = dirtree(tdirpath, sdate, edate, chkdir=False, dhour=timechunks)
    iii = 0
    for dirpath in dtree:
        for src in nei_source_generator(sourcedf):
            suffix = "EIS" + src["EIS_ID"].strip()

            setupfile = NameList("SETUP.0", working_directory=tdirpath)
            setupfile.read()
            setupfile.rename("SETUP." + suffix,
                             working_directory=dirpath + "/")
            setupfile.add("NDUMP", str(timechunks))
            setupfile.add("NCYCL", str(timechunks))
            setupfile.add("POUTF", 'PARDUMP.' + suffix)
            setupfile.add("PINPF", '"PARINIT.' + suffix + '"')
            setupfile.write(verbose=False)

            release_rate = src["SO2_kgph"]
            ##Write a control file
            control = HycsControl(fname="CONTROL.0",
                                  working_directory=tdirpath)
            control.read()
            # make sure that control start is always start of time
            # period.
            controldate = dir2date(tdirpath, dirpath)
            control.date = controldate

            control.rename("CONTROL." + suffix, working_directory=dirpath)

            # edit locations
            control.remove_locations()
            control.add_location(
                line=False,
                latlon=(src["latitude"], src["longitude"]),
                alt=src["height"],
                rate=0,
            )
            # set emission rate and duration in the pollutant definition.
            for sp in control.species:
                sp.rate = release_rate
                sp.duration = int(control.run_duration)
            ###Add the met files.
            control.remove_metfile(rall=True)
            if tcm:
                timechunks = int(control.run_duration)
            mfiles = met_files.get_files(control.date, timechunks)
            for mf in mfiles:
                if os.path.isfile(mf[0] + mf[1]):
                    control.add_metfile(mf[0], mf[1])
            for cg in control.concgrids:
                cg.outfile += "." + suffix
            if control.num_met > 12:
                metgrid = True
            else:
                metgrid = False
            control.write(metgrid=metgrid, overwrite=True, query=False)
            writelanduse(
                landusedir=landusedir,
                working_directory=dirpath + "/",
                overwrite=overwritelanduse,
                verbose=False,
            )
            sdate = dir2date(tdirpath, dirpath)
            pdate = sdate - datetime.timedelta(hours=timechunks)
            pdir = date2dir(tdirpath, pdate, dhour=timechunks)
            parinitA = "PARDUMP." + suffix
            parinitB = "PARINIT." + suffix
            parinit = (pdir, parinitA, parinitB)
            run = RunDescriptor(dirpath, suffix, hysplitdir, "hycs_std",
                                parinit)
            runlist.append(run)
    return runlist
Пример #5
0
def create_runlist(tdirpath, hdirpath, sdate, edate, timechunks):
    """
    read the base control file in tdirpath CONTROL.0
    read the base SETUP.0 file in tdirpath
    walk through all subdirectories in tdirpath.
    For each file with  EMIT as part of the filename
        1. read the file and get number of records in each cycle.
        2. take the suffix from the file
    return list of RunDescriptor objects
    tdirpath: str
              top level directory for output.
    tdirpath: str
              directory for hysplit executable
    sdate : datetime object
    edate : datetime object
    timechunks : integer
            run duration.
    """
    from os import walk
    from utilhysplit import emitimes

    # from arlhysplit.runh import getmetfiles

    dstart = sdate
    dend = edate
    ##determines meteorological files to use.

    runlist = []
    #if hdirpath[-1] != "/":
    #    hdirpath += "/"
    hysplitdir = os.path.join(hdirpath + "exec")

    iii = 0
    for (dirpath, dirnames, filenames) in walk(tdirpath):
        for fl in filenames:
            if iii == 0:
                firstdirpath = dirpath

            if "EMIT" in fl[0:4]:
                et = emitimes.EmiTimes(filename=dirpath + "/" + fl)
                # if not et.read_file(): continue
                try:
                    sdate = dir2date(tdirpath, dirpath)
                except:
                    continue
                if sdate < dstart or sdate > dend:
                    continue
                suffix = fl[4:8]
                temp = fl.split(".")
                if temp[1] != "txt":
                    suffix += "." + temp[1]
                temp = fl.replace("EMIT", "")
                suffix = temp.replace(".txt", "")
                wdir = dirpath
                if dirpath == firstdirpath:
                    parinit = (None, None, None)
                else:
                    pdate = sdate - datetime.timedelta(hours=timechunks)
                    pdir = date2dir(tdirpath, pdate, dhour=timechunks)
                    parinitA = "PARDUMP." + suffix
                    parinitB = "PARINIT." + suffix
                    parinit = (pdir, parinitA, parinitB)
                run = RunDescriptor(wdir, suffix, hysplitdir, "hycs_std",
                                    parinit)
                wr = "a"
                if iii == 0:
                    wr = "w"
                # with open(tdirpath + '/' +  scr, wr) as fid:
                # fid.write(run.script())
                # fid.write('\n\n')
                runlist.append(run)
                iii += 1
    return runlist
Пример #6
0
    def emit_subroutine(
        self,
        df,
        dfheat,
        edate,
        schunks,
        tdir="./",
        unit=True,
        bname="EMIT",
        emit_area=0,
    ):
        """
        create emitimes file for CEMS emissions.
        edate is the date to start the file on.
        Currently, 24 hour cycles are hard-wired.
        """
        # df = self.get_so2()
        # dfheat = self.get_heat()
        locs = df.columns.values
        prev_oris = "none"
        ehash = {}

        # get list of oris numbers
        orislist = []
        unithash = {}
        for hdr in locs:
            oris = hdr[0]
            orislist.append(oris)
            unithash[oris] = []

        for hdr in locs:
            oris = hdr[0]
            # print(hdr)
            if unit:
                mid = hdr[5]
            else:
                mid = "None"
            unithash[oris].append(mid)

        orislist = list(set(orislist))
        sphash = {1: "MEAS", 2: "EST1", 3: "EST2"}

        # create a dictionary with key oris number and value and EmiTimes
        # object.
        for oris in orislist:
            for mid in unithash[oris]:
                # output directory is determined by tdir and starting date.
                # chkdir=True means date2dir will create the directory if
                # it does not exist already.
                ename = bname + str(oris)
                if unit:
                    ename = ename + "_" + str(mid)
                odir = date2dir(tdir, edate, dhour=schunks, chkdir=True)
                ename = odir + ename + ".txt"
                if unit:
                    key = str(oris) + str(mid)
                else:
                    key = oris
                ehash[key] = emitimes.EmiTimes(filename=ename)
                ehash[key].set_species(sphash)

        # now this loop fills the EmitTimes objects
        for hdr in locs:
            oris = hdr[0]
            d1 = edate  # date to start emitimes file.
            dftemp = df[hdr]
            dfh = dfheat[hdr]
            dftemp.fillna(0, inplace=True)
            dftemp = dftemp[dftemp != 0]
            # ename = bname + str(oris)
            # if unit:
            #    sid = hdr[4]
            #   ename += "." + str(sid)
            height = hdr[1]
            lat = hdr[2]
            lon = hdr[3]
            spnum = hdr[4]
            key = oris
            if unit:
                mid = hdr[5]
                key += str(mid)
            # hardwire 1 hr duraton of emissions.
            record_duration = "0100"
            # pick which EmitTimes object we are working with.
            efile = ehash[key]
            # output directory is determined by tdir and starting date.
            # chkdir=True means date2dir will create the directory if
            # it does not exist already.
            # odir = date2dir(tdir, edate, dhour=schunks, chkdir=True)
            # ename = odir + ename + ".txt"
            # efile = emitimes.EmiTimes(filename=ename)
            # this was creating a special file for a pre-processing program
            # that would take diameter, temp and velocity to compute plume rise.
            if "STACK" in bname:
                hstring = efile.header.replace(
                    "HEAT(w)", "DIAMETER(m) TEMP(K) VELOCITY(m/s)")
                efile.modify_header(hstring)
            # hardwire 24 hour cycle length
            dt = datetime.timedelta(hours=24)
            #efile.add_cycle(d1, "0024")
            efile.add_cycle(d1, 24)
            for date, rate in dftemp.iteritems():
                # if spnum!=1: print(date, rate, spnum)
                if date >= edate:
                    heat = dfh[date]
                    check = efile.add_record(
                        date,
                        record_duration,
                        lat,
                        lon,
                        height,
                        rate,
                        emit_area,
                        heat,
                        spnum,
                    )
                    nnn = 0

                    while not check:
                        d1 = d1 + dt
                        efile.add_cycle(d1, 24)
                        check = efile.add_record(
                            date,
                            record_duration,
                            lat,
                            lon,
                            height,
                            rate,
                            emit_area,
                            heat,
                            spnum,
                        )
                        nnn += 1
                        if nnn > 20:
                            break
                        # if not check2:
                        #    print("sverify WARNING: record not added to EmiTimes")
                        #    print(date.strftime("%Y %m %d %H:%M"))
                        #    print(str(lat), str(lon), str(rate), str(heat))
                        #    break
        # here we write the EmitTimes files
        for ef in ehash.values():
            ef.write_new(ef.filename)