예제 #1
0
    def test_append_zero_record(self):
        "Test the append_zero_record() function"
        infile = os.path.join("input", "satbang_test_rst")
        outfil = os.path.join("outdir", "satbang_rst.append_zero_record")
        outexp = os.path.join("outexp", "satbang_rst.append_zero_record")

        sb = SatBangRst(infile)

        # create new values to load from last record
        (key, values) = sb.key_and_values(sb.len()-1)
        (instrument, channel) = key

        channel = "%s" % (int(channel) + 1)
        key = (instrument, channel)
        tlapmean = "%12.6E" % (float(values["tlapmean"]) - 0.05)

        # append record to data and write output
        sb.append_zero_record(key, tlapmean)

        self.assertEqual(sb.filename(), infile)
        sb.write(outfil)
        self.assertEqual(sb.filename(), outfil)

        # compare to expected output
        self.assertTrue(filecmp.cmp(outfil, outexp))

        os.remove(outfil)
예제 #2
0
    def test_data_and_records(self):
        "Test that records() agrees with self._data[] and key_and_values()"
        infile = os.path.join("input", "satbang_full_rst")
        sb = SatBangRst(infile)

        index = 0
        for (key, values) in sb.records():
            self.assertEqual((key, values), sb._data[index])
            self.assertEqual((key, values), sb.key_and_values(index))
            index += 1
예제 #3
0
    def test_append_duplicate(self):
        "Append_zero_record() should fail if key is already in data"
        infile = os.path.join("input", "satbang_test_rst")
        sb = SatBangRst(infile)

        # create record with duplicate key
        (key, values) = sb.key_and_values(10)
        tlapmean = values["tlapmean"].replace("0", "1")

        # attempt to append record with duplicate key
        self.assertRaises(Exception, sb.append_zero_record, key, tlapmean)
예제 #4
0
    def test_duplicate_key(self):
        "Load() should fail if satbang has duplicate keys"
        infile = os.path.join("input", "satbang_test_rst")
        infilX = os.path.join("input", "satbang_dupkey_rst")

        # attempt to add duplicate key
        sb = SatBangRst(infile)
        (key1, values) = sb.key_and_values(10)
        (key2, values) = sb.key_and_values(11)
        self.assertRaises(Exception, sb.change, key2, "key", key1)

        # attempt to load file with duplicate key
        self.assertRaises(Exception, SatBangRst, infilX, 1)
예제 #5
0
    def test_read_write(self):
        "Test that __read() and write() are inverse functions"
        infile = os.path.join("input", "satbang_full_rst")
        outfil = os.path.join("outdir", "satbang_full.copy")

        sb1 = SatBangRst(infile)
        sb1.write(outfil)

        # load output
        sb2 = SatBangRst(outfil)

        # compare private data from input and output; check for file equivalence
        self.assertEqual(sb1._data, sb2._data)
        self.assertTrue(filecmp.cmp(infile, outfil))

        os.remove(outfil)
예제 #6
0
    def test_remove_records(self):
        "Test the remove_records() function"
        infile = os.path.join("input", "satbang_test_rst")
        outfil = os.path.join("outdir", "satbang_rst.remove_records")
        outexp = os.path.join("outexp", "satbang_rst.remove_records")

        sb = SatBangRst(infile)

        # create list of keys to remove
        keylist = []
        (key, values) = sb.key_and_values(2)
        keylist.append(key)

        (key, values) = sb.key_and_values(5)
        keylist.append(key)

        # remove records and write output
        sb.remove_records(keylist)
        sb.write(outfil)

        # compare to expected output
        self.assertTrue(filecmp.cmp(outfil, outexp))

        os.remove(outfil)
예제 #7
0
    def test_ioerror_coeffs(self):
        "Load() should fail if coeffs does not have 90 elements"
        infile = os.path.join("input", "satbang_test_rst")
        outfil = os.path.join("outdir", "satbang_rst.ioerror_coeffs")
        outexp = os.path.join("outexp", "satbang_rst.ioerror_coeffs")

        # blank last value of coeff
        sb = SatBangRst(infile)
        (key, values) = sb.key_and_values(10)
        values["coeffs"][89] = ""
        sb.change(key, "coeffs", values["coeffs"])

        # this write works because coeffs is full length but with a blank
        sb.write(outfil)
        self.assertTrue(filecmp.cmp(outfil, outexp))

        # attempt to load faulty output file
        self.assertRaises(Exception, SatBangRst, outfil)
        os.remove(outfil)

        # attempt to replace coeffs with write file with faulty record
        values["coeffs"].pop();
        
        self.assertRaises(Exception, sb.change, key, "coeffs", values["coeffs"])
예제 #8
0
def check_files(satbang_path=os.curdir,
                satbias_path=os.curdir,
                satinfo_path="default",
                tlapmean_path="default",
                sortflag="default"):
    """
    Check for and fix irregularities in the satbang and satbias restart files
    when compared to information in the satinfo.rc and tlapmean.rc files.

    satbang and satbias restarts
    ----------------------------
    * Remove all records where the instrument channel is not listed in the
      satinfo.rc file.

    * Add a new record with coeffs equal zero for each instrument channel
      found in the satinfo.rc file but not in the restart file.

    * Sort records according to sortflag, if not equal "default"

    satbang only
    ------------
    * If the tlapmean value is zero, then replace it with the value from
      tlapmean.rc, if one is found there.

    * Make a note of the instrument channels with tlapmean equal zero, and
      there is no value in tlapmean.rc to replace it.

    * Make a note of the instrument channels with a non-zero tlapmean that
      disagrees with the value in tlapmean.rc (but do not replace).

    Input parameters:
    ----------------
    => satbang_path: name of input satbang restart file or name of directory 
                     containing satbang file named "*ana_satbang_rst*.txt".

    => satbias_path: name of input satbias restart file or name of directory 
                     containing satbias file named "*ana_satbias_rst*.txt".

    => satinfo_path: name of input satinfo.rc file; if "default" ,then use
                     "../run/gmao_global_satinfo.rc" relative to the satbang
                     restart directory.

    => tlapmean_path: name of input tlapmean.rc file; if "default", then use
                      "../run/gmao_global_tlapmean.rc" relative to the satbang
                      restart directory.

    => sortflag: flag indicating what order to write output records
                 "default" = keep output records in the same order as the input
                 "satbang" = write output records in same order as satbang_rst
                 "satbias" = write output records in same order as satbias_rst
                 "satinfo" = write output records in same order as satinfo.rc
                 "alpha"   = write output records in alphabetic order
    """

    # get satbang and satbias directory and filename
    #-----------------------------------------------
    (satbang_dir, satbang_name) = satbang_dir_and_name(satbang_path)
    (satbias_dir, satbias_name) = satbias_dir_and_name(satbias_path)

    satbang_path = os.path.join(satbang_dir, satbang_name)
    satbias_path = os.path.join(satbias_dir, satbias_name)

    # get default satinfo_path and tlapmean_path, if necessary
    #---------------------------------------------------------
    if satbang_dir.split(os.sep)[-1] == "recycle":
        run_dir = re.sub(r"recycle$", "run", satbang_dir)
    else:
        run_dir = os.path.relpath(os.path.join(satbang_dir, "..", "run"))
        if run_dir.count("..") > 1:
            run_dir = os.path.abspath(os.path.join(satbang_dir, "..", "run"))

    if satinfo_path == "default":
        satinfo_path = os.path.join(run_dir, "gmao_global_satinfo.rc")

    if tlapmean_path == "default":
        tlapmean_path = os.path.join(run_dir, "gmao_global_tlapmean.rc")

    # check for existence of input files
    #-----------------------------------
    if not os.path.isfile(satinfo_path):
        raise Exception("{0} does not exist".format(satinfo_path))

    if not os.path.isfile(tlapmean_path):
        raise Exception("{0} does not exist".format(tlapmean_path))

    # create file instances
    #----------------------
    satbang = SatBangRst(satbang_path)
    satbias = SatBiasRst(satbias_path)
    satinfo = SatInfoRc(satinfo_path)
    tlapmean = TLapMeanRc(tlapmean_path)

    # initialize data collectors and more
    #------------------------------------
    dcTL = {}  # data collector for tlapmean info (in satbang)
    dcBA = {}  # data collector for satbang records
    dcBI = {}  # data collector for satbias records

    dcTL["fill"] = []  # zero-value replaced by value from tlapmean.rc
    dcTL["diff"] = []  # satbang tlapmean differs from tlapmean.rc
    dcTL["none"] = []  # no value found in satbang or tlapmean.rc
    dcTL["what"] = []  # value found in satbang but not in tlapmean.rc

    dcBA["add"] = []  # satbang records added
    dcBA["rem"] = []  # satbang records removed
    dcBA["fix"] = []  # statistics from satbang.fixkeys()

    dcBI["add"] = []  # satbias records added
    dcBI["rem"] = []  # satbias records removed
    dcBI["fix"] = []  # statistics from satbias.fixkeys()

    fpath = {satbang: satbang_path, satbias: satbias_path}
    label = {satbang: "satbang", satbias: "satbias"}
    sb_len_0 = {}

    # check satbang and satbias for needed fixes
    #-------------------------------------------
    for (sb, dc) in [(satbang, dcBA), (satbias, dcBI)]:
        sb_len_0[sb] = sb.len()

        dc["fix"] = sb.fixkeys(satinfo.change_list)

        # loop through all records in sb
        #-------------------------------
        for (key, values) in sb.records():
            if satinfo.key_exists(key):

                # check tlap in satbang
                #----------------------
                if sb == satbang:
                    sb_tlap = values["tlapmean"]

                    if tlapmean.key_exists(key):
                        tl_tlap = tlapmean.value(key)

                        if float(sb_tlap) != float(tl_tlap):
                            if float(sb_tlap) == 0.0:
                                sb.change(key, "tlapmean", tl_tlap)
                                dcTL["fill"].append((key, sb_tlap, tl_tlap))
                            else:
                                dcTL["diff"].append((key, sb_tlap, tl_tlap))

                    # no tlap value in tlapmean
                    #--------------------------
                    else:
                        if float(sb_tlap) == 0.0:
                            dcTL["none"].append((key, sb_tlap))
                        else:
                            dcTL["what"].append((key, sb_tlap))

            # remove records not found in satinfo
            #------------------------------------
            else:
                sb.remove_records(key)
                dc["rem"].append(key)

        # add additional records from satinfo
        #------------------------------------
        for (key, values) in satinfo.records():

            if not sb.key_exists(key):
                sb.append_zero_record(key)
                dc["add"].append(key)

                if sb == satbang and tlapmean.key_exists(key):
                    sb.change(key, "tlapmean", tlapmean.value(key))

    # error checks
    #-------------
    for sb in [satbang, satbias]:

        # check for matching records
        #---------------------------
        if set(sb.keys()) != set(satinfo.keys()):
            msg = "Error. Instrument/channel lists differ: satinfo.rc and {0}"
            raise Exception(msg.format(label[sb]))

        # check for duplicate (instrument, channel) keys
        #-----------------------------------------------
        keyList = sb.keys()
        if len(keyList) != len(set(keyList)):
            for key in keyList:
                if keyList.count(key) > 1:
                    msg = "Error. Duplicate key in {0}: {1}"
                    raise Exception(msg.format(label[sb], key))

    # rewrite satbang and satbias files
    #----------------------------------
    for (sb, dc) in [(satbang, dcBA), (satbias, dcBI)]:

        if sortflag == "satinfo": outkeys = satinfo.keys()
        elif sortflag == "satbang": outkeys = satbang.keys()
        elif sortflag == "satbias": outkeys = satbias.keys()
        elif sortflag == "alpha": outkeys = keysort(sb.keys())
        elif sortflag == "default": outkeys = sb.keys()
        else:
            raise Exception("Error. Unknown sortflag: {0}".format(sortflag))

        # determine whether rewrite is necessary
        #---------------------------------------
        rewrite_flag = False

        for action in ["add", "rem"]:
            if dc[action]:
                rewrite_flag = True

        for (inst, new) in dc["fix"].keys():
            if dc["fix"][(inst, new)]:
                rewrite_flag = True

        if sb == satbang and dcTL["fill"]:
            rewrite_flag = True

        if sortflag != "default" and sortflag != label[sb]:
            rewrite_flag = True

        # rewrite file
        #-------------
        if rewrite_flag:
            sb.write(fpath[sb] + ".new", outkeys)

        # write summary to file?
        #-----------------------
        basename = os.path.basename(fpath[sb])
        dirname = os.path.dirname(fpath[sb])

        if not (rewrite_flag):
            if sb == satbang and (dcTL["diff"] or dcTL["none"]
                                  or dcTL["what"]):
                pass
            else:
                print "No irregularites found in {0}".format(basename)
                continue

        # write summary
        #--------------
        summary_file = os.path.join(dirname, "check_summary." + basename)
        if os.path.isfile(summary_file):
            os.rename(summary_file, summary_file + '~')

        with open(summary_file, mode='w') as sfile:
            sfile.write("\n")
            sfile.write(" =====================\n")
            sfile.write(" check_{0} summary\n".format(label[sb]))
            sfile.write(" =====================\n")
            sfile.write(" current dir: {0}\n\n".format(
                os.path.abspath(os.curdir)))

            sfile.write(" {0}_rst: {1}\n".format(label[sb], fpath[sb]))
            sfile.write(" satinfo.rc:  {0}\n".format(satinfo_path))

            if sb == satbang:
                sfile.write(" tlapmean.rc: {0}\n\n".format(tlapmean_path))

                msg = "%6i recs filled in missing tlapmean from tlapmean.rc\n"
                sfile.write(msg % (len(dcTL["fill"])))

                msg = "%6i recs with tlapmean different than tlapmean.rc\n"
                sfile.write(msg % (len(dcTL["diff"])))

                msg = "%6i recs with tlapmean equal zero\n"
                sfile.write(msg % (len(dcTL["none"])))

                msg = "%6i recs with tlapmean in satbang but not in tlapmean.rc\n\n"
                sfile.write(msg % (len(dcTL["what"])))
            else:
                sfile.write("\n")

            msg = "%6i recs removed because instrument/channel not in satinfo.rc\n"
            sfile.write(msg % (len(dc["rem"])))

            msg = "%6i recs added from satinfo.rc\n\n"
            sfile.write(msg % (len(dc["add"])))

            # instrument name changes
            #------------------------
            for (inst, new) in sorted(dc["fix"].keys()):
                if type(new) == str:
                    msg = "%6i recs renamed %s to %s\n"
                    sfile.write(msg % (dc["fix"][(inst, new)], inst, new))

            # instrument channel number changes
            #----------------------------------
            for (inst, new) in sorted(dc["fix"].keys()):
                if type(new) == tuple:
                    (old_nums, new_nums) = new
                    msg = "\n%6i recs where %s channels were renumbered\n"
                    msg1 = "       - old: {0}\n"
                    msg2 = "       - new: {0}\n"
                    sfile.write(msg % (dc["fix"][(inst, new)], inst))
                    sfile.write(msg1.format(old_nums))
                    sfile.write(msg2.format(new_nums))

            msg = "\n%6i {0} recs before update\n".format(label[sb])
            sfile.write(msg % (sb_len_0[sb]))

            msg = "%6i {0} recs after update\n".format(label[sb])
            sfile.write(msg % (sb.len()))

            if rewrite_flag:
                msg = "\n new {0} file has been written: {1}\n"
                sfile.write(msg.format(label[sb], sb.filename()))
                sfile.write(' sortflag = "{0}"\n'.format(sortflag))

        # display summary without details to stdout
        #------------------------------------------
        cat([summary_file])
        print(" For details, see file, {0}\n".format(summary_file))

        # write details
        #--------------
        msg1 = "* records where zero-value replaced by value from tlapmean.rc"
        msg2 = "* records where satbang tlapmean differs from tlapmean.rc"
        msg3 = "* records where no value found in satbang or tlapmean.rc"
        msg4 = "* records where value found in satbang but not in tlapmean.rc"

        msg5 = "* records added to agree with satinfo.rc (coeffs = 0.000)"
        msg6 = "* records removed; not found in satinfo.rc"

        with open(summary_file, mode='a') as sfile:

            msg = "The following details are listed below:"
            sfile.write("\n\n" + msg + "\n" + '=' * len(msg) + "\n")
            if sb == satbang:
                if dcTL["fill"]: sfile.write(msg1 + "\n")
                if dcTL["diff"]: sfile.write(msg2 + "\n")
                if dcTL["none"]: sfile.write(msg3 + "\n")
                if dcTL["what"]: sfile.write(msg4 + "\n")

            if dc["add"]: sfile.write(msg5 + "\n")
            if dc["rem"]: sfile.write(msg6 + "\n")

            if dcTL["fill"] and sb == satbang:
                sfile.write("\n\n" + msg1 + "\n" + '-' * len(msg1) + "\n")
                msg = "%-25s tlapmean:  %13s => %13s\n"
                for (key, sb_tlap, tl_tlap) in dcTL["fill"]:
                    sfile.write(msg % (str(key), sb_tlap, tl_tlap))

            if dcTL["diff"] and sb == satbang:
                sfile.write("\n\n" + msg2 + "\n" + '-' * len(msg2) + "\n")
                headers = ("instrument/channel", "satbang_rst", "tlapmean.rc",
                           "difference")
                underscores = tuple('-' * len(hh) for hh in headers)
                sfile.write("%-25s %13s %13s %13s\n" % headers)
                sfile.write("%-25s %13s %13s %13s\n" % underscores)

                msg = "%-25s %13s %13s %13.6e\n"
                for (key, sb_tlap, tl_tlap) in dcTL["diff"]:
                    diff = float(sb_tlap) - float(tl_tlap)
                    sfile.write(msg % (str(key), sb_tlap, tl_tlap, diff))

            if dcTL["none"] and sb == satbang:
                sfile.write("\n\n" + msg3 + "\n" + '-' * len(msg3) + "\n")
                msg = "%-25s tlapmean: %13s\n"
                for (key, sb_tlap) in dcTL["none"]:
                    sfile.write(msg % (str(key), tl_tlap))

            if dcTL["what"] and sb == satbang:
                sfile.write("\n\n" + msg4 + "\n" + '-' * len(msg4) + "\n")
                msg = "%-25s tlapmean in satbang_rst: %13s\n"
                for (key, sb_tlap) in dcTL["what"]:
                    sfile.write(msg % (str(key), sb_tlap))

            if dc["add"]:
                sfile.write("\n\n" + msg5 + "\n" + '-' * len(msg5) + "\n")
                for key in keysort(dc["add"]):
                    sfile.write(str(key) + "\n")

            if dc["rem"]:
                sfile.write("\n\n" + msg6 + "\n" + '-' * len(msg6) + "\n")
                for key in keysort(dc["rem"]):
                    sfile.write(str(key) + "\n")
예제 #9
0
    def test_change(self):
        "Test the change() function for various variables"
        infile = os.path.join("input", "satbang_test_rst")

        infile1 = os.path.join("outdir", "satbang_test_rst")
        outexp1 = os.path.join("outexp", "satbang_test_rst")

        outfil = os.path.join("outdir", "satbang_test.new")
        outexp = os.path.join("outexp", "satbang_test.new")

        # rewrite input to remove comments and extraneous blanks
        # (for diff'ing purposes while verifying test)
        sb1 = SatBangRst(infile)
        sb1.write(infile1)
        self.assertTrue(filecmp.cmp(infile1, outexp1))

        # change instrument in record #1
        sb2 = SatBangRst(infile1)
        (key, values) = sb2.key_and_values(0)
        (instrument, channel) = key
        sb2.change(key, "instrument", "istoo_n09")
        
        # change channel in record #2
        (key, values) = sb2.key_and_values(1)
        (instrument, channel) = key
        sb2.change(key, "channel", "12")
        
        # change tlapmean in record #3
        (key, values) = sb2.key_and_values(2)
        sb2.change(key, "tlapmean", "0.455304E-01")
        
        # change coeffs in record #4
        (key, values) = sb2.key_and_values(3)
        coeffs = ["%7.3f"%(((-1)**n)*float(n)/8) for n in range(90)]
        sb2.change(key, "coeffs", coeffs)

        # change key in record #5
        (key, values) = sb2.key_and_values(4)
        sb2.change(key, "key", ("amsub_n61", "44"))
        
        # write output
        sb2.write(outfil)

        # compare to expected output
        self.assertTrue(filecmp.cmp(outfil, outexp))

        os.remove(infile1)
        os.remove(outfil)