def sample_times(node, num_times):
     assert hasattr(
         GC, 'transmissions'
     ), "No transmission network found in global context! Run this after the transmission network simulation is done"
     first_time = node.get_first_infection_time()
     if first_time is None:
         return []
     windows = []
     last_time = first_time
     for u, v, t in GC.transmissions:
         if u == node and v == node:
             if last_time is not None and t > last_time:
                 windows.append((last_time, t))
             last_time = None
         elif last_time is None and v == node:
             last_time = t
     if last_time is not None and t > last_time:
         windows.append((last_time, GC.time))
     if len(windows) == 0:
         windows.append((first_time, GC.time))
     weighted_die = {}
     for start, end in windows:
         weighted_die[(start, end)] = end - start
     if len(weighted_die) == 0:
         return []
     if len(weighted_die) == 1:
         weighted_die[list(weighted_die.keys())[0]] = 1
     out = []
     for _ in range(num_times):
         start, end = GC.roll(weighted_die)
         out.append(uniform(start, end))
     return out
 def subsample_transmission_network():
     nodes = {GC.contact_network.get_node(n) for n in GC.final_sequences}
     die = {}
     for u, v, t in GC.contact_network.get_transmissions():
         if u not in die:
             die[u] = 1
         else:
             die[u] += 1
         if v not in die:
             die[v] = 1
         else:
             die[v] += 1
     die = {n: die[n] for n in nodes if n in die}
     num_sample = GC.node_sample_fraction * len(die.keys())
     out = []
     while len(die) != 0 and len(out) < num_sample:
         n = GC.roll(die)
         out.append(n)
         die.pop(n)
     return out
    def prep_GEMF():
        # check for gender attribute in contact network nodes
        for node in GC.contact_network.nodes_iter():
            attr = node.get_attribute()
            assert 'MALE' in attr or 'FEMALE' in attr, "All nodes must have MALE or FEMALE in their attributes"
            assert not ('MALE' in attr and 'FEMALE'
                        in attr), "Nodes cannot be both MALE and FEMALE"

        # write GEMF parameter file
        orig_dir = getcwd()
        GC.gemf_path = expanduser(GC.gemf_path.strip())
        makedirs(GC.gemf_out_dir, exist_ok=True)
        f = open(GC.gemf_out_dir + "/para.txt", 'w')
        f.write("[NODAL_TRAN_MATRIX]\n0\t" + str(GC.gon_ma_to_ms) +
                "\t0\t0\t0\t0\t0\t0\n" + str(GC.gon_ms_to_ma) + "\t0\t" +
                str(GC.gon_ms_to_mis_seed) + "\t" +
                str(GC.gon_ms_to_mia_seed) + "\t0\t0\t0\t0\n" +
                str(GC.gon_mis_to_ma) + "\t" + str(GC.gon_mis_to_ms) +
                "\t0\t0\t0\t0\t0\t0\n" + str(GC.gon_mia_to_ma) + "\t" +
                str(GC.gon_mia_to_ms) + "\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t" +
                str(GC.gon_fa_to_fs) + "\t0\t0\n0\t0\t0\t0\t" +
                str(GC.gon_fs_to_fa) + "\t0\t" + str(GC.gon_fs_to_fis_seed) +
                "\t" + str(GC.gon_fs_to_fia_seed) + "\n0\t0\t0\t0\t" +
                str(GC.gon_fis_to_fa) + "\t" + str(GC.gon_fis_to_fs) +
                "\t0\t0\n0\t0\t0\t0\t" + str(GC.gon_fia_to_fa) + "\t" +
                str(GC.gon_fia_to_fs) + "\t0\t0\n\n")  # Gonorrhea-specific
        f.write("[EDGED_TRAN_MATRIX]\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.gon_ms_to_mis_by_mis) +
            "\t" + str(GC.gon_ms_to_mia_by_mis) +
            "\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t"
            + str(GC.gon_fs_to_fis_by_mis) + "\t" +
            str(GC.gon_fs_to_fia_by_mis) +
            "\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.gon_ms_to_mis_by_mia) +
            "\t" + str(GC.gon_ms_to_mia_by_mia) +
            "\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t"
            + str(GC.gon_fs_to_fis_by_mia) + "\t" +
            str(GC.gon_fs_to_fia_by_mia) +
            "\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.gon_ms_to_mis_by_fis) +
            "\t" + str(GC.gon_ms_to_mia_by_fis) +
            "\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t"
            + str(GC.gon_fs_to_fis_by_fis) + "\t" +
            str(GC.gon_fs_to_fia_by_fis) +
            "\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.gon_ms_to_mis_by_fia) +
            "\t" + str(GC.gon_ms_to_mia_by_fia) +
            "\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t"
            + str(GC.gon_fs_to_fis_by_fia) + "\t" +
            str(GC.gon_fs_to_fia_by_fia) +
            "\n0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("[STATUS_BEGIN]\n0\n\n")
        infectious = ['MIS', 'MIA', 'FIS', 'FIA']
        f.write("[INDUCER_LIST]\n" +
                ' '.join([str(GC.gemf_state_to_num[e])
                          for e in infectious]) + "\n\n")
        f.write("[SIM_ROUNDS]\n1\n\n")
        f.write("[INTERVAL_NUM]\n1\n\n")
        f.write("[MAX_TIME]\n" + str(GC.end_time) + "\n\n")
        f.write("[MAX_EVENTS]\n" + str(GC.C_INT_MAX) + "\n\n")
        f.write("[DIRECTED]\n1\n\n")
        f.write("[SHOW_INDUCER]\n1\n\n")
        f.write(
            "[DATA_FILE]\nnetwork.txt\nnetwork.txt\nnetwork.txt\nnetwork.txt\n\n"
        )
        f.write("[STATUS_FILE]\nstatus.txt\n\n")
        if GC.random_number_seed is not None:
            f.write("[RANDOM_SEED]\n%d\n\n" % GC.random_number_seed)
        f.write("[OUT_FILE]\noutput.txt")
        f.close()

        # write GEMF network file
        f = open(GC.gemf_out_dir + "/network.txt", 'w')
        num2node = {}
        node2num = {}
        for edge in GC.contact_network.edges_iter():
            u = edge.get_from()
            v = edge.get_to()
            if u not in node2num:
                num = len(node2num) + 1
                node2num[u] = num
                num2node[num] = u
            if v not in node2num:
                num = len(node2num) + 1
                node2num[v] = num
                num2node[num] = v
            f.write(str(node2num[u]) + '\t' + str(node2num[v]) + '\n')
        f.close()

        # write GEMF to original mapping
        f = open(GC.gemf_out_dir + "/gemf2orig.json", 'w')
        f.write(str({num: num2node[num].get_name() for num in num2node}))
        f.close()

        # write GEMF status file (MA = 0, MS = 1, MIS = 2, MIA = 3, FA = 4, FS = 5, FIS = 6, FIA = 7)
        f = open(GC.gemf_out_dir + "/status.txt", 'w')
        seeds = {seed
                 for seed in GC.seed_nodes
                 }  # seed nodes are assumed to be asymptomatic
        for num in sorted(num2node.keys()):
            node = num2node[num]
            attr = node.get_attribute()
            if node in seeds:
                if 'MALE' in attr:
                    f.write(str(GC.gemf_state_to_num['MIA']) +
                            "\n")  # Gonorrhea-specific
                    node.gemf_state = GC.gemf_state_to_num['MIA']
                else:
                    f.write(str(GC.gemf_state_to_num['FIA']) +
                            "\n")  # Gonorrhea-specific
                    node.gemf_state = GC.gemf_state_to_num['FIA']
            else:
                if 'MALE' in attr:
                    f.write(str(GC.gemf_state_to_num['MS']) +
                            "\n")  # Gonorrhea-specific
                    node.gemf_state = GC.gemf_state_to_num['MS']
                else:
                    f.write(str(GC.gemf_state_to_num['FS']) +
                            "\n")  # Gonorrhea-specific
                    node.gemf_state = GC.gemf_state_to_num['FS']
        f.close()

        # run GEMF
        chdir(GC.gemf_out_dir)
        try:
            call([GC.gemf_path], stdout=open("log.txt", 'w'))
        except FileNotFoundError:
            chdir(GC.START_DIR)
            assert False, "GEMF executable was not found: %s" % GC.gemf_path
        chdir(orig_dir)

        # reload edge-based matrices for ease of use
        matrices = open(GC.gemf_out_dir + '/para.txt').read().strip()
        outside_infection_matrix = [[
            float(e) for e in l.split()
        ] for l in matrices[matrices.index('[NODAL_TRAN_MATRIX]'):matrices.
                            index('\n\n[EDGED_TRAN_MATRIX]')].replace(
                                '[NODAL_TRAN_MATRIX]\n', '').splitlines()]
        matrices = [[
            [float(e) for e in l.split()] for l in m.splitlines()
        ] for m in matrices[matrices.index('[EDGED_TRAN_MATRIX]'):matrices.
                            index('\n\n[STATUS_BEGIN]')].replace(
                                '[EDGED_TRAN_MATRIX]\n', '').split('\n\n')]
        matrices = {
            GC.gemf_state_to_num[infectious[i]]: matrices[i]
            for i in range(len(infectious))
        }
        matrices[GC.gemf_state_to_num['MS']] = outside_infection_matrix
        matrices[GC.gemf_state_to_num['FS']] = outside_infection_matrix

        # convert GEMF output to FAVITES transmission network format
        GC.transmission_num = 0
        GC.transmission_state = set()  # 'node' and 'time'
        NUM_INFECTED = len(seeds)
        GC.transmission_file = []
        for line in open(GC.gemf_out_dir + "/output.txt"):
            t, rate, vNum, pre, post, num0, num1, num2, num3, num4, num5, num6, num7, lists = [
                i.strip() for i in line.split()
            ]
            pre, post = int(pre), int(post)
            vName = num2node[int(vNum)].get_name()
            lists = lists.split('],[')
            lists[0] += ']'
            lists[-1] = '[' + lists[-1]
            for i in range(1, len(lists) - 1):
                if '[' not in lists[i]:
                    lists[i] = '[' + lists[i] + ']'
            lists = [eval(l) for l in lists]
            uNums = []
            for l in lists:
                uNums.extend(l)
            if post in {
                    GC.gemf_state_to_num[i]
                    for i in ['MA', 'MS', 'FA', 'FS']
            } and pre in {
                    GC.gemf_state_to_num[i]
                    for i in ['MIS', 'MIA', 'FIS', 'FIA']
            }:
                NUM_INFECTED -= 1
                GC.transmission_file.append((vName, vName, float(t)))
                if GC.VERBOSE:
                    print(
                        '[%s] Uninfection\tTime %s\tNode %s (%s->%s)\tTotal Infected: %d\tTotal Uninfected: %d'
                        % (datetime.now(), t, vName, GC.gemf_num_to_state[pre],
                           GC.gemf_num_to_state[post], NUM_INFECTED,
                           len(num2node) - NUM_INFECTED),
                        file=stderr)
            elif GC.gemf_num_to_state[pre] in [
                    'MS', 'FS'
            ] and GC.gemf_num_to_state[post] in ['MIS', 'MIA', 'FIS', 'FIA']:
                NUM_INFECTED += 1
                v = num2node[int(vNum)]
                uNodes = [num2node[num] for num in uNums]
                uRates = [
                    matrices[uNode.gemf_state][pre][post] for uNode in uNodes
                ]
                die = {
                    uNodes[i]: GC.prob_exp_min(i, uRates)
                    for i in range(len(uNodes))
                }
                if len(die) != 0:
                    u = GC.roll(
                        die
                    )  # roll die weighted by exponential infectious rates
                    uName = u.get_name()
                    if GC.VERBOSE:
                        print(
                            '[%s] Infection\tTime %s\tFrom Node %s (%s)\tTo Node %s (%s->%s)\tTotal Infected: %d\tTotal Uninfected: %d'
                            % (datetime.now(), t, uName,
                               GC.gemf_num_to_state[u.gemf_state], vName,
                               GC.gemf_num_to_state[pre],
                               GC.gemf_num_to_state[post], NUM_INFECTED,
                               len(num2node) - NUM_INFECTED),
                            file=stderr)
                elif len(die) == 0 or u == v:  # new seed
                    uName = None
                    if GC.VERBOSE:
                        print(
                            '[%s] Seed\tTime %s\tNode %s\tTotal Infected: %d\tTotal Uninfected: %d'
                            % (datetime.now(), t, vName, NUM_INFECTED,
                               len(num2node) - NUM_INFECTED),
                            file=stderr)
                GC.transmission_file.append((uName, v.get_name(), float(t)))
            elif GC.VERBOSE:
                print('[%s] Transition\tTime %s\tNode %s (%s->%s)' %
                      (datetime.now(), t, vName, GC.gemf_num_to_state[pre],
                       GC.gemf_num_to_state[post]),
                      file=stderr)
            num2node[int(vNum)].gemf_state = post
        assert len(
            GC.transmission_file) != 0, "GEMF didn't output any transmissions"
        GC.gemf_ready = True
    def prep_GEMF():
        # check for attributes in contact network nodes
        for node in GC.contact_network.nodes_iter():
            attr = node.get_attribute()
            assert 'MALE' in attr or 'FEMALE' in attr, "All nodes must have MALE or FEMALE in their attributes"
            assert not ('MALE' in attr and 'FEMALE'
                        in attr), "Nodes cannot be both MALE and FEMALE"
            if 'MALE' in attr:
                assert 'CIRCUMCISED' in attr or 'UNCIRCUMCISED' in attr, "MALE nodes must be either CIRCUMCISED or UNCIRCUMCISED"
            else:
                assert 'CIRCUMCISED' not in attr, "FEMALE nodes cannot be CIRCUMCISED"

        # write GEMF parameter file
        orig_dir = getcwd()
        GC.gemf_path = expanduser(GC.gemf_path.strip())
        makedirs(GC.gemf_out_dir, exist_ok=True)
        f = open(GC.gemf_out_dir + "/para.txt", 'w')
        f.write("[NODAL_TRAN_MATRIX]\n")
        f.write(
            "0\t" + str(GC.hiv_msu_to_mspc) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_msu_to_d) + "\n")
        f.write(
            "0\t0\t" + str(GC.hiv_mspc_to_msch) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mspc_to_d) + "\n")
        f.write(
            "0\t0\t0\t" + str(GC.hiv_msch_to_msc) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_msch_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_msc_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t" + str(GC.hiv_miah_to_mia) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_miah_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mia_to_mi1) + "\t" +
            str(GC.hiv_mia_to_mi2) + "\t" + str(GC.hiv_mia_to_mi3) + "\t" +
            str(GC.hiv_mia_to_mi4) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mia_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mi1_to_mi2) + "\t0\t0\t" +
            str(GC.hiv_mi1_to_mj1) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mi1_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mi2_to_mi3) + "\t0\t0\t" +
            str(GC.hiv_mi2_to_mj2) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mi2_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mi3_to_mi4) +
            "\t0\t0\t" + str(GC.hiv_mi3_to_mj3) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mi3_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_mi4_to_mj4) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mi4_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mj1_to_mj2) +
            "\t0\t0\t" + str(GC.hiv_mj1_to_mt1) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mj1_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mj2_to_mj3) +
            "\t0\t0\t" + str(GC.hiv_mj2_to_mt2) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mj2_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_mj3_to_mj4) + "\t0\t0\t" + str(GC.hiv_mj3_to_mt3) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mj3_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_mj4_to_mt4) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mj4_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mt1_to_mi1) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mt1_to_mt2) +
            "\t0\t0\t" + str(GC.hiv_mt1_to_ma1) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_mt1_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mt2_to_mi2) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mt2_to_mt3) +
            "\t0\t0\t" + str(GC.hiv_mt2_to_ma2) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_mt2_to_d) + "\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mt3_to_mi3) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mt3_to_mt4) +
                "\t0\t0\t" + str(GC.hiv_mt3_to_ma3) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
                str(GC.hiv_mt3_to_d) + "\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_mt4_to_mi4) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
                str(GC.hiv_mt4_to_ma4) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
                str(GC.hiv_mt4_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t" + str(GC.hiv_ma1_to_mi1) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_ma1_to_ma2) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_ma1_to_d) + "\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_ma2_to_mi2) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
                str(GC.hiv_ma2_to_ma3) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
                str(GC.hiv_ma2_to_d) + "\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_ma3_to_mi3) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
                str(GC.hiv_ma3_to_ma4) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
                str(GC.hiv_ma3_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_ma4_to_mi4) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_ma4_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fs_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fia_to_fi1) + "\t" + str(GC.hiv_fia_to_fi2) + "\t" +
            str(GC.hiv_fia_to_fi3) + "\t" + str(GC.hiv_fia_to_fi4) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fia_to_d) +
            "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fi1_to_fi2) + "\t0\t0\t" + str(GC.hiv_fi1_to_fj1) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fi1_to_d) +
            "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fi2_to_fi3) + "\t0\t0\t" + str(GC.hiv_fi2_to_fj2) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fi2_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fi3_to_fi4) + "\t0\t0\t" + str(GC.hiv_fi3_to_fj3) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fi3_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fi4_to_fj4) + "\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_fi4_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fj1_to_fj2) + "\t0\t0\t" + str(GC.hiv_fj1_to_ft1) +
            "\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fj1_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fj2_to_fj3) + "\t0\t0\t" + str(GC.hiv_fj2_to_ft2) +
            "\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fj2_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fj3_to_fj4) + "\t0\t0\t" + str(GC.hiv_fj3_to_ft3) +
            "\t0\t0\t0\t0\t0\t" + str(GC.hiv_fj3_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fj4_to_ft4) + "\t0\t0\t0\t0\t" +
            str(GC.hiv_fj4_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_ft1_to_fi1) + "\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_ft1_to_ft2) + "\t0\t0\t" + str(GC.hiv_ft1_to_fa1) +
            "\t0\t0\t0\t" + str(GC.hiv_ft1_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_ft2_to_fi2) + "\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_ft2_to_ft3) + "\t0\t0\t" + str(GC.hiv_ft2_to_fa2) +
            "\t0\t0\t" + str(GC.hiv_ft2_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_ft3_to_fi3) + "\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_ft3_to_ft4) + "\t0\t0\t" + str(GC.hiv_ft3_to_fa3) +
            "\t0\t" + str(GC.hiv_ft3_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_ft4_to_fi4) + "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" +
            str(GC.hiv_ft4_to_fa4) + "\t" + str(GC.hiv_ft4_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fa1_to_fi1) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fa1_to_fa2) +
            "\t0\t0\t" + str(GC.hiv_fa1_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fa2_to_fi2) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fa2_to_fa3) +
            "\t0\t" + str(GC.hiv_fa2_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fa3_to_fi3) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fa3_to_fa4) +
            "\t" + str(GC.hiv_fa3_to_d) + "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
            + str(GC.hiv_fa4_to_fi4) +
            "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_fa4_to_d) +
            "\n")
        f.write(
            "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
        )
        f.write("\n")
        infectious = [
            'MIAH', 'MIA', 'MI1', 'MI2', 'MI3', 'MI4', 'MJ1', 'MJ2', 'MJ3',
            'MJ4', 'MT1', 'MT2', 'MT3', 'MT4', 'MA1', 'MA2', 'MA3', 'MA4',
            'FIA', 'FI1', 'FI2', 'FI3', 'FI4', 'FJ1', 'FJ2', 'FJ3', 'FJ4',
            'FT1', 'FT2', 'FT3', 'FT4', 'FA1', 'FA2', 'FA3', 'FA4'
        ]
        f.write("[EDGED_TRAN_MATRIX]\n")
        for _ in infectious:
            by = _.lower()
            f.write(
                "0\t0\t0\t0\t0\t" +
                str(getattr(GC, 'hiv_msu_to_mia_by_' + by)) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t" +
                str(getattr(GC, 'hiv_mspc_to_mia_by_' + by)) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t" +
                str(getattr(GC, 'hiv_msch_to_miah_by_' + by)) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t" +
                str(getattr(GC, 'hiv_msc_to_mia_by_' + by)) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t"
                + str(getattr(GC, 'hiv_fs_to_fia_by_' + by)) +
                "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n")
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write(
                "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n"
            )
            f.write('\n')
        f.write("[STATUS_BEGIN]\n0\n\n")
        f.write("[INDUCER_LIST]\n" +
                ' '.join([str(GC.gemf_state_to_num[i])
                          for i in infectious]) + "\n\n")
        f.write("[SIM_ROUNDS]\n1\n\n")
        f.write("[INTERVAL_NUM]\n1\n\n")
        f.write("[MAX_TIME]\n" + str(GC.end_time) + "\n\n")
        f.write("[MAX_EVENTS]\n" + str(GC.C_INT_MAX) + "\n\n")
        f.write("[DIRECTED]\n" + str(int(GC.contact_network.is_directed())) +
                "\n\n")
        f.write("[SHOW_INDUCER]\n1\n\n")
        f.write("[DATA_FILE]\n" +
                '\n'.join(["network.txt"] * len(infectious)) + "\n\n")
        f.write("[STATUS_FILE]\nstatus.txt\n\n")
        if GC.random_number_seed is not None:
            f.write("[RANDOM_SEED]\n%d\n\n" % GC.random_number_seed)
        f.write("[OUT_FILE]\noutput.txt")
        f.close()

        # write GEMF network file
        f = open(GC.gemf_out_dir + "/network.txt", 'w')
        num2node = {}
        node2num = {}
        for edge in GC.contact_network.edges_iter():
            u = edge.get_from()
            v = edge.get_to()
            if u not in node2num:
                num = len(node2num) + 1
                node2num[u] = num
                num2node[num] = u
            if v not in node2num:
                num = len(node2num) + 1
                node2num[v] = num
                num2node[num] = v
            f.write(str(node2num[u]) + '\t' + str(node2num[v]) + '\n')
        f.close()

        # write GEMF to original mapping
        f = open(GC.gemf_out_dir + "/gemf2orig.json", 'w')
        f.write(str({num: num2node[num].get_name() for num in num2node}))
        f.close()

        # write GEMF status file (see above for the states)
        f = open(GC.gemf_out_dir + "/status.txt", 'w')
        seeds = {seed
                 for seed in GC.seed_nodes
                 }  # seed nodes are assumed to be in acute infection
        for num in sorted(num2node.keys()):
            node = num2node[num]
            attr = node.get_attribute()
            if node in seeds:
                if 'MALE' in attr:
                    f.write(str(GC.gemf_state_to_num['MIA']) +
                            "\n")  # PopART-specific
                    node.gemf_state = GC.gemf_state_to_num['MIA']
                else:
                    f.write(str(GC.gemf_state_to_num['FIA']) +
                            "\n")  # PopART-specific
                    node.gemf_state = GC.gemf_state_to_num['FIA']
            else:
                if 'MALE' in attr:
                    if 'CIRCUMCISED' in attr:
                        f.write(str(GC.gemf_state_to_num['MSC']) +
                                "\n")  # PopART-specific
                        node.gemf_state = GC.gemf_state_to_num['MSC']
                    else:
                        f.write(str(GC.gemf_state_to_num['MSU']) +
                                "\n")  # PopART-specific
                        node.gemf_state = GC.gemf_state_to_num['MSU']
                else:
                    f.write(str(GC.gemf_state_to_num['FS']) +
                            "\n")  # PopART-specific
                    node.gemf_state = GC.gemf_state_to_num['FS']
        f.close()

        # run GEMF
        chdir(GC.gemf_out_dir)
        try:
            call([GC.gemf_path], stdout=open("log.txt", 'w'))
        except FileNotFoundError:
            chdir(GC.START_DIR)
            assert False, "GEMF executable was not found: %s" % GC.gemf_path
        chdir(orig_dir)

        # reload edge-based matrices for ease of use
        matrices = open(GC.gemf_out_dir + '/para.txt').read().strip()
        matrices = [[
            [float(e) for e in l.split()] for l in m.splitlines()
        ] for m in matrices[matrices.index('[EDGED_TRAN_MATRIX]'):matrices.
                            index('\n\n[STATUS_BEGIN]')].replace(
                                '[EDGED_TRAN_MATRIX]\n', '').split('\n\n')]
        matrices = {
            GC.gemf_state_to_num[infectious[i]]: matrices[i]
            for i in range(len(infectious))
        }

        # convert GEMF output to FAVITES transmission network format
        GC.transmission_num = 0
        GC.transmission_state = set()  # 'node' and 'time'
        GC.transmission_file = []
        for line in open(GC.gemf_out_dir + "/output.txt"):
            parts = [i.strip() for i in line.split()]
            t = parts[0]
            rate = parts[1]
            vNum = parts[2]
            pre = int(parts[3])
            post = int(parts[4])
            lists = parts[-1]
            lists = lists.split('],[')
            lists[0] += ']'
            lists[-1] = '[' + lists[-1]
            for i in range(1, len(lists) - 1):
                if '[' not in lists[i]:
                    lists[i] = '[' + lists[i] + ']'
            lists = [eval(l) for l in lists]
            uNums = []
            for l in lists:
                uNums.extend(l)
            if post == GC.gemf_state_to_num['D']:
                vName = num2node[int(vNum)].get_name()
                GC.transmission_file.append((vName, vName, float(t)))
            elif len(lists[0]) == 0:
                v = num2node[int(vNum)]
                uNodes = [num2node[num] for num in uNums]
                uRates = [
                    matrices[uNode.gemf_state][pre][post] for uNode in uNodes
                ]
                die = {
                    uNodes[i]: GC.prob_exp_min(i, uRates)
                    for i in range(len(uNodes))
                }
                if len(die) != 0:
                    uName = GC.roll(die).get_name(
                    )  # roll die weighted by exponential infectious rates
                elif len(die) == 0 or u == v:  # new seed
                    uName = None
                GC.transmission_file.append((uName, v.get_name(), float(t)))
            num2node[int(vNum)].gemf_state = post
        assert len(
            GC.transmission_file) != 0, "GEMF didn't output any transmissions"
        GC.gemf_ready = True
    def prep_GEMF():
        # write GEMF parameter file
        orig_dir = getcwd()
        GC.gemf_path = expanduser(GC.gemf_path.strip())
        makedirs(GC.gemf_out_dir, exist_ok=True)
        f = open(GC.gemf_out_dir + "/para.txt",'w')
        f.write("[NODAL_TRAN_MATRIX]\n0\t" + str(GC.hiv_ns_to_s) + "\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_ns_to_d) + "\n0\t0\t" + str(GC.hiv_s_to_i1_seed) + "\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_s_to_d) + "\n0\t0\t0\t" + str(GC.hiv_i1_to_i2) + "\t0\t0\t" + str(GC.hiv_i1_to_a1) + "\t0\t0\t0\t" + str(GC.hiv_i1_to_d) + "\n0\t0\t0\t0\t" + str(GC.hiv_i2_to_i3) + "\t0\t0\t" + str(GC.hiv_i2_to_a2) + "\t0\t0\t" + str(GC.hiv_i2_to_d) + "\n0\t0\t0\t0\t0\t" + str(GC.hiv_i3_to_i4) + "\t0\t0\t" + str(GC.hiv_i3_to_a3) + "\t0\t" + str(GC.hiv_i3_to_d) + "\n0\t0\t0\t0\t0\t0\t0\t0\t0\t" + str(GC.hiv_i4_to_a4) + "\t" + str(GC.hiv_i4_to_d) + "\n0\t0\t" + str(GC.hiv_a1_to_i1) + "\t0\t0\t0\t0\t" + str(GC.hiv_a1_to_a2) + "\t0\t0\t" + str(GC.hiv_a1_to_d) + "\n0\t0\t0\t" + str(GC.hiv_a2_to_i2) + "\t0\t0\t0\t0\t" + str(GC.hiv_a2_to_a3) + "\t0\t" + str(GC.hiv_a2_to_d) + "\n0\t0\t0\t0\t" + str(GC.hiv_a3_to_i3) + "\t0\t0\t0\t0\t" + str(GC.hiv_a3_to_a4) + "\t" + str(GC.hiv_a3_to_d) + "\n0\t0\t0\t0\t0\t" + str(GC.hiv_a4_to_i4) + "\t0\t0\t0\t0\t" + str(GC.hiv_a4_to_d) + "\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n") # HIV-ART-specific
        f.write("[EDGED_TRAN_MATRIX]\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_i1) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_i2) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_i3) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_i4) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_a1) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_a2) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_a3) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t" + str(GC.hiv_s_to_i1_by_a4) + "\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\n\n")
        f.write("[STATUS_BEGIN]\n0\n\n")
        infectious = ['I1','I2','I3','I4','A1','A2','A3','A4']
        f.write("[INDUCER_LIST]\n" + ' '.join([str(GC.gemf_state_to_num[i]) for i in infectious]) + "\n\n")
        f.write("[SIM_ROUNDS]\n1\n\n")
        f.write("[INTERVAL_NUM]\n1\n\n")
        f.write("[MAX_TIME]\n" + str(GC.end_time) + "\n\n")
        f.write("[MAX_EVENTS]\n" + str(GC.C_INT_MAX) + "\n\n")
        f.write("[DIRECTED]\n" + str(int(GC.contact_network.is_directed())) + "\n\n")
        f.write("[SHOW_INDUCER]\n1\n\n")
        f.write("[DATA_FILE]\n" + '\n'.join(["network.txt"]*len(infectious)) + "\n\n")
        f.write("[STATUS_FILE]\nstatus.txt\n\n")
        if GC.random_number_seed is not None:
            f.write("[RANDOM_SEED]\n%d\n\n"%GC.random_number_seed)
        f.write("[OUT_FILE]\noutput.txt")
        f.close()

        # write GEMF network file
        f = open(GC.gemf_out_dir + "/network.txt",'w')
        num2node = {}
        node2num = {}
        for edge in GC.contact_network.edges_iter():
            u = edge.get_from()
            v = edge.get_to()
            if u not in node2num:
                num = len(node2num) + 1
                node2num[u] = num
                num2node[num] = u
            if v not in node2num:
                num = len(node2num) + 1
                node2num[v] = num
                num2node[num] = v
            f.write(str(node2num[u]) + '\t' + str(node2num[v]) + '\n')
        f.close()

        # write GEMF to original mapping
        f = open(GC.gemf_out_dir + "/gemf2orig.json",'w')
        f.write(str({num:num2node[num].get_name() for num in num2node}))
        f.close()

        # write GEMF status file (NS = 0, S = 1, I1 = 2, I2 = 3, I3 = 4, I4 = 5, A1 = 6, A2 = 7, A3 = 8, A4 = 9, D = 10)
        leftover = len(num2node)
        start_states = {'seed':[], 'other':[]}
        for s in infectious:
            k = "hiv_freq_%s"%s.lower()
            if isinstance(getattr(GC,k), float):
                n = int(len(num2node)*getattr(GC,k))
            else:
                n = getattr(GC,k)
            start_states['seed'] += [GC.gemf_state_to_num[s]]*n
            leftover -= n
        assert len(start_states['seed']) == len(GC.seed_nodes), "At time 0, A1+A2+A3+A4+I1+I2+I3+I4 = %d, but there are %d seed nodes. Fix hiv_freq_* parameters accordingly" % (len(start_states['seed']),len(GC.seed_nodes))
        for s in ['NS','S']:
            k = "hiv_freq_%s"%s.lower()
            if isinstance(getattr(GC,k), float):
                n = int(len(num2node)*getattr(GC,k))
            else:
                n = getattr(GC,k)
            start_states['other'] += [GC.gemf_state_to_num[s]]*n
            leftover -= n
        start_states['other'] += [GC.gemf_state_to_num['D']]*leftover
        shuffle(start_states['seed']); shuffle(start_states['other'])
        f = open(GC.gemf_out_dir + "/status.txt",'w')
        seeds = {seed for seed in GC.seed_nodes} # seed nodes are assumed to be in I1 and non-seeds to be in NS
        for num in sorted(num2node.keys()):
            node = num2node[num]
            if node in seeds:
                s = start_states['seed'].pop()
                f.write("%d\n"%s)
                node.gemf_state = s
            else:
                s = start_states['other'].pop()
                f.write("%d\n"%s)
                node.gemf_state = s
        f.close()

        # run GEMF
        chdir(GC.gemf_out_dir)
        try:
            call([GC.gemf_path], stdout=open("log.txt",'w'))
        except FileNotFoundError:
            chdir(GC.START_DIR)
            assert False, "GEMF executable was not found: %s" % GC.gemf_path
        chdir(orig_dir)

        # reload edge-based matrices for ease of use
        matrices = open(GC.gemf_out_dir + '/para.txt').read().strip()
        outside_infection_matrix = [[float(e) for e in l.split()] for l in matrices[matrices.index('[NODAL_TRAN_MATRIX]'):matrices.index('\n\n[EDGED_TRAN_MATRIX]')].replace('[NODAL_TRAN_MATRIX]\n','').splitlines()]
        matrices = [[[float(e) for e in l.split()] for l in m.splitlines()] for m in matrices[matrices.index('[EDGED_TRAN_MATRIX]'):matrices.index('\n\n[STATUS_BEGIN]')].replace('[EDGED_TRAN_MATRIX]\n','').split('\n\n')]
        matrices = {GC.gemf_state_to_num[infectious[i]]:matrices[i] for i in range(len(infectious))}
        matrices[GC.gemf_state_to_num['S']] = outside_infection_matrix

        # convert GEMF output to FAVITES transmission network format
        GC.transmission_num = 0
        GC.transmission_state = set() # 'node' and 'time'
        NUM_INFECTED = len(seeds)
        GC.transmission_file = []
        for line in open(GC.gemf_out_dir + "/output.txt"):
            t,rate,vNum,pre,post,num0,num1,num2,num3,num4,num5,num6,num7,num8,num9,num10,lists = [i.strip() for i in line.split()]
            pre,post = int(pre),int(post)
            vName = num2node[int(vNum)].get_name()
            lists = lists.split('],[')
            lists[0] += ']'
            lists[-1] = '[' + lists[-1]
            for i in range(1,len(lists)-1):
                if '[' not in lists[i]:
                    lists[i] = '[' + lists[i] + ']'
            lists = [eval(l) for l in lists]
            uNums = []
            for l in lists:
                uNums.extend(l)
            if post == GC.gemf_state_to_num['D']:
                NUM_INFECTED -= 1
                GC.transmission_file.append((vName,vName,float(t)))
                if GC.VERBOSE:
                    print('[%s] Uninfection\tTime %s\tNode %s (%s->%s)\tTotal Infected: %d\tTotal Uninfected: %d' % (datetime.now(),t,vName,GC.gemf_num_to_state[pre],GC.gemf_num_to_state[post],NUM_INFECTED,len(num2node)-NUM_INFECTED), file=stderr)
            elif GC.gemf_num_to_state[pre] == 'S' and GC.gemf_num_to_state[post] == 'I1':
                NUM_INFECTED += 1
                v = num2node[int(vNum)]
                uNodes = [num2node[num] for num in uNums]
                uRates = [matrices[uNode.gemf_state][pre][post] for uNode in uNodes]
                die = {uNodes[i]:GC.prob_exp_min(i, uRates) for i in range(len(uNodes))}
                if len(die) != 0:
                    u = GC.roll(die) # roll die weighted by exponential infectious rates
                    uName = u.get_name()
                    if GC.VERBOSE:
                        print('[%s] Infection\tTime %s\tFrom Node %s (%s)\tTo Node %s (%s->%s)\tTotal Infected: %d\tTotal Uninfected: %d' % (datetime.now(),t,uName,GC.gemf_num_to_state[u.gemf_state],vName,GC.gemf_num_to_state[pre],GC.gemf_num_to_state[post],NUM_INFECTED,len(num2node)-NUM_INFECTED), file=stderr)
                elif len(die) == 0 or u == v: # new seed
                    uName = None
                    if GC.VERBOSE:
                        print('[%s] Seed\tTime %s\tNode %s\tTotal Infected: %d\tTotal Uninfected: %d' % (datetime.now(),t,vName,NUM_INFECTED,len(num2node)-NUM_INFECTED), file=stderr)
                GC.transmission_file.append((uName,v.get_name(),float(t)))
            elif GC.VERBOSE:
                print('[%s] Transition\tTime %s\tNode %s (%s->%s)' % (datetime.now(),t,vName,GC.gemf_num_to_state[pre],GC.gemf_num_to_state[post]), file=stderr)
            num2node[int(vNum)].gemf_state = post
        assert len(GC.transmission_file) != 0, "GEMF didn't output any transmissions"
        GC.gemf_ready = True
        GC.gemf_num2node = num2node
    def prep_GEMF():
        # write GEMF parameter file
        orig_dir = getcwd()
        GC.gemf_path = expanduser(GC.gemf_path.strip())
        makedirs(GC.gemf_out_dir, exist_ok=True)
        f = open(GC.gemf_out_dir + "/para.txt", 'w')
        f.write("[NODAL_TRAN_MATRIX]\n0\t" + str(GC.seir_beta_seed) +
                "\t0\t0\n0\t0\t" + str(GC.seir_lambda) + "\t0\n0\t0\t0\t" +
                str(GC.seir_delta) + "\n0\t0\t0\t0\n\n")  # SEIR-specific
        f.write(
            "[EDGED_TRAN_MATRIX]\n0\t" + str(GC.seir_beta_by_i) +
            "\t0\t0\n0\t0\t0\t0\n0\t0\t0\t0\n0\t0\t0\t0\n\n")  # SEIR-specific
        f.write("[STATUS_BEGIN]\n0\n\n")
        f.write("[INDUCER_LIST]\n" + str(GC.gemf_state_to_num['I']) + "\n\n")
        f.write("[SIM_ROUNDS]\n1\n\n")
        f.write("[INTERVAL_NUM]\n1\n\n")
        f.write("[MAX_TIME]\n" + str(GC.end_time) + "\n\n")
        f.write("[MAX_EVENTS]\n" + str(GC.C_INT_MAX) + "\n\n")
        f.write("[DIRECTED]\n" + str(int(GC.contact_network.is_directed())) +
                "\n\n")
        f.write("[SHOW_INDUCER]\n1\n\n")
        f.write("[DATA_FILE]\nnetwork.txt\n\n")
        f.write("[STATUS_FILE]\nstatus.txt\n\n")
        if GC.random_number_seed is not None:
            f.write("[RANDOM_SEED]\n%d\n\n" % GC.random_number_seed)
        f.write("[OUT_FILE]\noutput.txt")
        f.close()

        # write GEMF network file
        f = open(GC.gemf_out_dir + "/network.txt", 'w')
        num2node = {}
        node2num = {}
        for edge in GC.contact_network.edges_iter():
            u = edge.get_from()
            v = edge.get_to()
            if u not in node2num:
                num = len(node2num) + 1
                node2num[u] = num
                num2node[num] = u
            if v not in node2num:
                num = len(node2num) + 1
                node2num[v] = num
                num2node[num] = v
            f.write(str(node2num[u]) + '\t' + str(node2num[v]) + '\n')
        f.close()

        # write GEMF to original mapping
        f = open(GC.gemf_out_dir + "/gemf2orig.json", 'w')
        f.write(str({num: num2node[num].get_name() for num in num2node}))
        f.close()

        # write GEMF status file (0 = S, 1 = E, 2 = I, 3 = R)
        f = open(GC.gemf_out_dir + "/status.txt", 'w')
        seeds = {seed for seed in GC.seed_nodes}
        for num in sorted(num2node.keys()):
            node = num2node[num]
            if node in seeds:
                f.write(str(GC.gemf_state_to_num['I']) + "\n")  # SEIR-specific
                node.gemf_state = GC.gemf_state_to_num['I']
            else:
                f.write(str(GC.gemf_state_to_num['S']) + "\n")  # SEIR-specific
                node.gemf_state = GC.gemf_state_to_num['S']
        f.close()

        # run GEMF
        chdir(GC.gemf_out_dir)
        try:
            call([GC.gemf_path], stdout=open("log.txt", 'w'))
        except FileNotFoundError:
            chdir(GC.START_DIR)
            assert False, "GEMF executable was not found: %s" % GC.gemf_path
        chdir(orig_dir)

        # reload edge-based matrices for ease of use
        matrices = open(GC.gemf_out_dir + '/para.txt').read().strip()
        outside_infection_matrix = [[
            float(e) for e in l.split()
        ] for l in matrices[matrices.index('[NODAL_TRAN_MATRIX]'):matrices.
                            index('\n\n[EDGED_TRAN_MATRIX]')].replace(
                                '[NODAL_TRAN_MATRIX]\n', '').splitlines()]
        matrices = [[
            [float(e) for e in l.split()] for l in m.splitlines()
        ] for m in matrices[matrices.index('[EDGED_TRAN_MATRIX]'):matrices.
                            index('\n\n[STATUS_BEGIN]')].replace(
                                '[EDGED_TRAN_MATRIX]\n', '').split('\n\n')]
        infectious = ['I']
        matrices = {
            GC.gemf_state_to_num['S']: outside_infection_matrix,
            GC.gemf_state_to_num['I']: matrices[0]
        }

        # convert GEMF output to FAVITES transmission network format
        GC.transmission_num = 0
        GC.transmission_state = set()  # 'node' and 'time'
        NUM_INFECTED = len(seeds)
        GC.transmission_file = []
        for line in open(GC.gemf_out_dir + "/output.txt"):
            t, rate, vNum, pre, post, num0, num1, num2, num3, lists = [
                i.strip() for i in line.split()
            ]
            pre, post = int(pre), int(post)
            vName = num2node[int(vNum)].get_name()
            lists = lists.split('],[')
            lists[0] += ']'
            lists[-1] = '[' + lists[-1]
            for i in range(1, len(lists) - 1):
                if '[' not in lists[i]:
                    lists[i] = '[' + lists[i] + ']'
            lists = [eval(l) for l in lists]
            uNums = []
            for l in lists:
                uNums.extend(l)
            if post == GC.gemf_state_to_num['R']:
                NUM_INFECTED -= 1
                GC.transmission_file.append((vName, vName, float(t)))
                if GC.VERBOSE:
                    print(
                        '[%s] Uninfection\tTime %s\tNode %s (%s->%s)\tTotal Infected: %d\tTotal Uninfected: %d'
                        % (datetime.now(), t, vName, GC.gemf_num_to_state[pre],
                           GC.gemf_num_to_state[post], NUM_INFECTED,
                           len(num2node) - NUM_INFECTED),
                        file=stderr)
            elif post == GC.gemf_state_to_num['E']:
                NUM_INFECTED += 1
                v = num2node[int(vNum)]
                uNodes = [num2node[num] for num in uNums]
                uRates = [
                    matrices[uNode.gemf_state][pre][post] for uNode in uNodes
                ]
                die = {
                    uNodes[i]: GC.prob_exp_min(i, uRates)
                    for i in range(len(uNodes))
                }
                if len(die) != 0:
                    u = GC.roll(
                        die
                    )  # roll die weighted by exponential infectious rates
                    uName = u.get_name()
                    if GC.VERBOSE:
                        print(
                            '[%s] Infection\tTime %s\tFrom Node %s (%s)\tTo Node %s (%s->%s)\tTotal Infected: %d\tTotal Uninfected: %d'
                            % (datetime.now(), t, uName,
                               GC.gemf_num_to_state[u.gemf_state], vName,
                               GC.gemf_num_to_state[pre],
                               GC.gemf_num_to_state[post], NUM_INFECTED,
                               len(num2node) - NUM_INFECTED),
                            file=stderr)
                elif len(die) == 0 or u == v:  # new seed
                    uName = None
                    if GC.VERBOSE:
                        print(
                            '[%s] Seed\tTime %s\tNode %s\tTotal Infected: %d\tTotal Uninfected: %d'
                            % (datetime.now(), t, vName, NUM_INFECTED,
                               len(num2node) - NUM_INFECTED),
                            file=stderr)
                GC.transmission_file.append((uName, v.get_name(), float(t)))
            elif GC.VERBOSE:
                print('[%s] Transition\tTime %s\tNode %s (%s->%s)' %
                      (datetime.now(), t, vName, GC.gemf_num_to_state[pre],
                       GC.gemf_num_to_state[post]),
                      file=stderr)
            num2node[int(vNum)].gemf_state = post
        assert len(
            GC.transmission_file) != 0, "GEMF didn't output any transmissions"
        GC.gemf_ready = True
def genString(k, pi):
    return ''.join([GC.roll(pi) for _ in range(k)])