def print_output(data, ostr=None, sort=None, renamings=Ellipsis): assert sort is None or sort == '-' or sort == '+' scriptname = os.path.basename(__file__) timestamp = format_rfc5322(localtime=True) print("% -*- coding:utf-8; mode:latex; -*-", file=ostr) print("", file=ostr) print("%% THIS IS A GENERATED FILE; PLEASE DO NOT EDIT IT MANUALLY!", file=ostr) print("%% Generated by {!r} on {!s}".format(scriptname, timestamp), file=ostr) print("", file=ostr) sortkey = lambda kv: (kv[1][sort][0] if sort in kv[1] else math.nan, kv[0].name) for (prop, val) in sorted(data.items(), key=sortkey): enumname = renamings[prop] assert re.match(r'^[A-Z][0-9A-Z_]*$', enumname) texname = enumname.replace('_', '\\_') mx = format(100.0 * val['-'][0], '.2f') if '-' in val else str(math.nan) sx = format(100.0 * val['-'][1], '.2f') if '-' in val else str(math.nan) my = format(100.0 * val['+'][0], '.2f') if '+' in val else str(math.nan) sy = format(100.0 * val['+'][1], '.2f') if '+' in val else str(math.nan) argvec = ''.join("{" + value + "}" for value in [mx, sx, my, sy]) print(r"\PunctureResult[\enum{" + texname + r"}]" + argvec, file=ostr)
def write_output(ostr, results, individuals, renamings, base_runs, base_success): scriptname = os.path.basename(__file__) timestamp = format_rfc5322(localtime=True) print("% -*- coding:utf-8; mode:latex; -*-", file=ostr) print("", file=ostr) print("%% THIS IS A GENERATED FILE; PLEASE DO NOT EDIT IT MANUALLY!", file=ostr) print("%% Generated by {!s} on {!s}".format(scriptname, timestamp), file=ostr) print("", file=ostr) for (test, (mean, stdev)) in sorted(results.items(), key=(lambda kv: kv[1][0]), reverse=True): enumname = renamings[test] assert re.match(r'^[A-Z][0-9A-Z_]*$', enumname) texname = enumname.replace('_', '\\_') if individuals is not None and BASELINE in individuals: differences = [ individuals[BASELINE][i] - individuals[test][i] for i in range(base_runs) ] try: diff_mean = statistics.mean(differences) diff_stdev = statistics.stdev(differences, xbar=diff_mean) except statistics.StatisticsError: (diff_mean, diff_stdev) = (math.nan, math.nan) else: diff_mean = base_success[0] - results[test][0] diff_stdev = math.sqrt(base_success[1]**2 + results[test][1]**2) argtokens = ''.join(r"{" + format(100.0 * x, '.2f') + r"}" for x in [mean, stdev, diff_mean, diff_stdev]) print(r"\CompetingMetricResult[\enum{" + texname + r"}]" + argtokens, file=ostr)
def update_progress_report(filename: str, t0: float, t: float, progress: float = None, remaining: float = None, create: bool = False): if filename is None: return if not filename or filename == '-': _warning("Progress report can only be written to a regular file") return mode = 'w' if create else 'a' __ = lambda x: x if x is not None else math.nan with open(filename, mode) as ostr: if create: print("#! /bin/false", file=ostr) print("#! -*- coding:utf-8; mode:config-space; -*-", file=ostr) print("", file=ostr) print("## Job started on {!s}".format( format_rfc5322(t0, localtime=True)), file=ostr) print("## {:>21s}{:>24s}{:>24s}".format("elapsed / s", "progress / 1", "remaining / s"), file=ostr) print("", file=ostr) print("{:24.10E}{:24.10E}{:24.10E}".format(t - t0, __(progress), t + __(remaining) - t0), file=ostr)
def main(): ap = argparse.ArgumentParser( description="Format Huang parameters as TeX code.") ap.add_argument('src', metavar='FILE', help="read from JSON file FILE") ap.add_argument('-o', '--output', metavar='FILE', type=argparse.FileType('w'), help="write to FILE") ap.add_argument('-r', '--rename', metavar='FILE', type=argparse.FileType('r'), help="rename enums according to mapping read from FILE") ns = ap.parse_args() try: with open(ns.src, 'r') if ns.src != '-' else contextlib.nullcontext( sys.stdin) as istr: info = json.load(istr) except FileNotFoundError: check_lazy_okay(ns.src) info = {m: (math.nan, math.nan) for m in const.HUANG_METRICS} else: unpack = lambda d: (d['mean'], d['stdev']) info = { m: unpack(info[const.enum_to_json(m)]) for m in const.HUANG_METRICS } renamings = {m: m.name for m in const.HUANG_METRICS} if ns.rename is not None: load_rename_table(ns.rename, renamings) scriptname = os.path.basename(__file__) timestamp = format_rfc5322(localtime=True) print("% -*- coding:utf-8; mode:latex; -*-", file=ns.output) print("", file=ns.output) print("%% THIS IS A GENERATED FILE; PLEASE DO NOT EDIT IT MANUALLY!", file=ns.output) print("%% Generated by {!r} on {!s}".format(scriptname, timestamp), file=ns.output) print("", file=ns.output) for (metric, params) in sorted(info.items(), key=(lambda kv: abs(kv[1][0])), reverse=True): enumname = renamings[metric] assert re.match(r'^[A-Z][0-9A-Z_]*$', enumname) texname = enumname.replace('_', '\\_') arg1 = format(params[0], '+.4f') arg2 = format(params[1], '.4f') print(r"\HuangWeightResult[" + texname + r"]{" + arg1 + r"}{" + arg2 + r"}", file=ns.output)
def try_download(url, checksums, tempname, traceinfo): hashes = {algo: hashlib.new(algo) for (algo, chksum) in checksums} def update_hashers(chunk): for hasher in hashes.values(): hasher.update(chunk) with open(tempname, 'wb') as ostr: info("Downloading {!r} ...".format(url)) try: t0 = time.time() traceinfo['date'] = format_rfc5322(t0, localtime=True) with urllib.request.urlopen(url) as istr: size = copy_iostreams(istr, ostr, callback=update_hashers) t1 = time.time() info( "Download complete; fetched {size:,d} bytes in {time:,.3f} seconds ({rate[0]:.3f} {rate[1]:s})" .format(size=size, time=(t1 - t0), rate=get_human_rate(size, t1 - t0))) traceinfo['size'] = size traceinfo['time'] = t1 - t0 except urllib.error.HTTPError as e: what = traceinfo['error'] = str(e) info(what) return False except OSError as e: info(e.strerror) return False hashes = {algo: hasher.digest() for (algo, hasher) in hashes.items()} for (algo, expected) in checksums: actual = hashes[algo] traceinfo['digest-' + algo] = hexhash(actual) if expected == actual: info("Verifying {:s} checksum".format(algo.upper()), "OK") else: info("Verifying {:s} checksum".format(algo.upper()), "FAILED") info("Expected: " + hexhash(expected)) info("Actual: " + hexhash(actual)) traceinfo['error'] = "{:s} checksum does not match".format( algo.upper()) return False return True
def main(): ap = argparse.ArgumentParser( description="Format neural network information as TeX code.") ap.add_argument('-o', '--output', metavar='FILE', type=argparse.FileType('w'), help="write to FILE") ap.add_argument( '--shared-info', metavar='FILE', type=argparse.FileType('r'), required=True, help= "read information about the shared model from FILE (Keras debug output)" ) ap.add_argument( '--total-info', metavar='FILE', type=argparse.FileType('r'), required=True, help= "read information about the total model from FILE (Keras debug output)" ) ap.add_argument('--corpus', metavar='FILE', type=argparse.FileType('r'), required=True, help="read data corpus summary from JSON FILE") ns = ap.parse_args() (shared_layers, shared_info) = Parser(ns.shared_info)() (total_layers, total_info) = Parser(ns.total_info)() corpus = json.load(ns.corpus) scriptname = os.path.basename(__file__) timestamp = format_rfc5322(localtime=True) print("% -*- coding:utf-8; mode:latex; -*-", file=ns.output) print("", file=ns.output) print("%% THIS IS A GENERATED FILE; PLEASE DO NOT EDIT IT MANUALLY!", file=ns.output) print("%% Generated by {!r} on {!s}".format(scriptname, timestamp), file=ns.output) print("", file=ns.output) fmtint = lambda n: format(n, ',d').replace(',', '\\,') print(get_layer_dim_def('NNSharedInputDims', shared_layers, 'in', 'InputLayer'), file=ns.output) print(get_layer_dim_def('NNSharedHiddenDims', shared_layers, 'l1', 'Dense'), file=ns.output) print(get_layer_dim_def('NNSharedOutputDims', shared_layers, 'l2', 'Dense'), file=ns.output) print(get_layer_dim_def('NNTotalAuxInputDims', total_layers, 'auxin', 'InputLayer'), file=ns.output) print(get_layer_dim_def('NNTotalAuxHiddenDims', total_layers, 'aux', 'Dense'), file=ns.output) print(get_layer_dim_def('NNTotalCatDims', total_layers, 'cat', 'Concatenate'), file=ns.output) print(get_layer_dim_def('NNTotalOutputDims', total_layers, 'out', 'Dense'), file=ns.output) print(r"\def\NNTotalTrainableParams{" + fmtint(total_info['trainable-params']) + r"}", file=ns.output) print(r"\def\NNCorpusSize{" + fmtint(corpus['size']) + r"}", file=ns.output) print(r"\def\NNCorpusSizeApprox{" + fmtint(1000 * round(corpus['size'] / 1000)) + r"}", file=ns.output)
def run_toolchain( maindep, workdir=None, jobname=None, columns=None, tex=None, bib=None, idx=None, oneshot=False, epoch=None, ): if jobname is None: (root, ext) = os.path.splitext(maindep) jobname = root if epoch is not None: logging.info("SOURCE_DATE_EPOCH={!s} # {:s}".format( epoch, format_rfc5322(epoch, localtime=True))) auxpattern = os.path.join(workdir, '*.aux') if workdir is not None else '*.aux' if tex is not None: tex_command = [ TOOLS[tex], *TOOLFLAGS['TEX'], '-interaction', 'batchmode', '-jobname', jobname, maindep ] if bib is not None: bib_command = [TOOLS[bib], *TOOLFLAGS['BIB'], jobname] if idx is not None: idx_command = [TOOLS[idx], *TOOLFLAGS['IDX'], jobname] oldchksum = None if oneshot else get_aux_checksum(auxpattern) if oldchksum is not None: logging.debug( "Initial combined checksum of auxiliary files is {!s}".format( oldchksum)) for i in range(10): if tex is not None: logging.info("Running {:s} ({:d}) ...".format(tex, i + 1)) run_command(tex_command, workdir=workdir, what=tex, columns=columns, epoch=epoch) newchksum = None if oneshot else get_aux_checksum(auxpattern) if newchksum is not None: logging.debug( "Combined checksum of auxiliary files is {!s}".format( newchksum)) if i == 0 and (bib or idx): if bib is not None: logging.info("Running {:s} ...".format(bib)) run_command( bib_command, workdir=workdir, what=bib, columns=columns, epoch=epoch, stdout='{:s}-stdout.log'.format(bib.lower()), stderr='{:s}-stderr.log'.format(bib.lower()), ) if idx is not None: logging.info("Running {:s} ...".format(idx)) run_command( idx_command, workdir=workdir, what=idx, columns=columns, epoch=epoch, stdout='{:s}-stdout.log'.format(idx.lower()), stderr='{:s}-stderr.log'.format(idx.lower()), ) elif oldchksum == newchksum: break oldchksum = newchksum else: raise Error("Combined checksum of auxiliary files did not converge")
def main(): ap = argparse.ArgumentParser( description="Formats a JSON confusion matrix as TeX code.") ap.add_argument('src', metavar='FILE', help="read from FILE") ap.add_argument('-t', '--test', metavar='TEST', type=_test, help="only consider TEST (may not be repeated)") ap.add_argument('-o', '--output', metavar='FILE', type=argparse.FileType('w'), help="write to FILE") ns = ap.parse_args() try: with open(ns.src, 'r') if ns.src != '-' else contextlib.nullcontext( sys.stdin) as istr: infos = json.load(istr) except FileNotFoundError: check_lazy_okay(ns.src) infos = None if ns.test is not None: key0 = const.enum_to_json(ns.test) _get = lambda *args, **kwargs: get(infos, key0, *args, **kwargs) else: _get = lambda *args, **kwargs: get(infos, *args, **kwargs) number_d = lambda *keys: format(round(_get(*keys, na=0)), 'd').replace( ',', '\\,') number_f2 = lambda *keys: format(_get(*keys, na=math.nan), '.2f') percentage = lambda *keys: format(100.0 * _get(*keys, na=math.nan), '.2f') scriptname = os.path.basename(__file__) timestamp = format_rfc5322(localtime=True) with contextlib.redirect_stdout(ns.output): print("% -*- coding:utf-8; mode:latex; -*-") print("") print("%% THIS IS A GENERATED FILE; PLEASE DO NOT EDIT IT MANUALLY!") print("%% Generated by {!r} on {!s}".format(scriptname, timestamp)) print("") print(r"\def\XValTestRuns{" + number_d('test-runs') + r"}") print(r"\def\XValCountApprox{" + number_d('test-count', 'mean') + r"}") print(r"\def\XValCountMean{" + number_f2('test-count', 'mean') + r"}") print(r"\def\XValCountStdev{" + number_f2('test-count', 'stdev') + r"}") # print(r"\def\XValSuccessMean{" + percentage('success', 'mean') + r"}") print(r"\def\XValSuccessStdev{" + percentage('success', 'stdev') + r"}") print(r"\def\XValFailureMean{" + percentage('failure', 'mean') + r"}") print(r"\def\XValFailureStdev{" + percentage('failure', 'stdev') + r"}") # print(r"\def\XValCondPosMean{" + percentage('condition-positive', 'mean') + r"}") print(r"\def\XValCondPosStdev{" + percentage('condition-positive', 'stdev') + r"}") print(r"\def\XValCondNegMean{" + percentage('condition-negative', 'mean') + r"}") print(r"\def\XValCondNegStdev{" + percentage('condition-negative', 'stdev') + r"}") # print(r"\def\XValPredPosMean{" + percentage('prediction-positive', 'mean') + r"}") print(r"\def\XValPredPosStdev{" + percentage('prediction-positive', 'stdev') + r"}") print(r"\def\XValPredNegMean{" + percentage('prediction-negative', 'mean') + r"}") print(r"\def\XValPredNegStdev{" + percentage('prediction-negative', 'stdev') + r"}") # print(r"\def\XValTrueNegMean{" + percentage('true-negative', 'mean') + r"}") print(r"\def\XValTrueNegStdev{" + percentage('true-negative', 'stdev') + r"}") print(r"\def\XValFalseNegMean{" + percentage('false-negative', 'mean') + r"}") print(r"\def\XValFalseNegStdev{" + percentage('false-negative', 'stdev') + r"}") print(r"\def\XValTruePosMean{" + percentage('true-positive', 'mean') + r"}") print(r"\def\XValTruePosStdev{" + percentage('true-positive', 'stdev') + r"}") print(r"\def\XValFalsePosMean{" + percentage('false-positive', 'mean') + r"}") print(r"\def\XValFalsePosStdev{" + percentage('false-positive', 'stdev') + r"}")
def main(): ap = argparse.ArgumentParser( description="Formats a discrimination results file as TeX code.") ap.add_argument('src', metavar='FILE', help="read from FILE") ap.add_argument('-o', '--output', metavar='FILE', type=argparse.FileType('w'), help="write to FILE") ap.add_argument( '-n', '--name', metavar='MODEL=NAME', dest='dmnames', action='append', type=parse_dmnamespec, help="use TeX name NAME for discriminator model MODEL (can be repeated)" ) ap.add_argument('--print-names', action='store_true', help="print discriminator model names and exit") ns = ap.parse_args() dmnames = { dm: ''.join(filter(str.isalnum, dm.name.lower())) for dm in const.Tests } if ns.dmnames is not None: dmnames.update(ns.dmnames) if ns.print_names: for dm in sorted(dmnames.keys()): print(dm.name, dmnames[dm]) raise SystemExit() try: with open(ns.src, 'r') if ns.src != '-' else contextlib.nullcontext( sys.stdin) as istr: disco = list(parse_disco_file(istr)) except FileNotFoundError: check_lazy_okay(ns.src) disco = None shortid = lambda id: str(id)[:8] dmname = lambda dm: dmnames[dm] scriptname = os.path.basename(__file__) timestamp = format_rfc5322(localtime=True) with contextlib.redirect_stdout( ns.output) if ns.output is not None else contextlib.nullcontext(): print("% -*- coding:utf-8; mode:latex; -*-") print("") print("%% THIS IS A GENERATED FILE; PLEASE DO NOT EDIT IT MANUALLY!") print("%% Generated by {!r} on {!s}".format(scriptname, timestamp)) print("") if disco is None: print("% This file contains no records (note: {!s}={!r}).".format( LAZYOK_ENVVAR, 1)) return print("% This file contains {:,d} records.".format(len(disco))) for record in disco: print("") print("% lhsid: {!s}".format(record.lhs)) print("% rhsid: {!s}".format(record.rhs)) print("% value: {:+.10f}".format(record.value)) print("% model: {:s}".format(record.model.name)) print( r"\expandafter\def\csname msc@{lhs:s}-{rhs:s}@{dm:s}\endcsname{{{p:.3f}}}" .format(lhs=shortid(record.lhs), rhs=shortid(record.rhs), p=(100.0 * record.value), dm=dmname(record.model)))
def fmttabs(timestamp): return format_rfc5322(timestamp, localtime=True)