""" Modified by Matthias Rüegg (matthias.ruegg@unil.ch) on August 13 2019 Based on a program created by created by github.com/blmoistawinde (https://github.com/blmoistawinde/facetnet-python) Copyright 2019 __UNIL__. All rights reserved. This file is part of facetnet-python-unil. facetnet-python-unil is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. facetnet-python-unil is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with facetnet-python-unil. If not, see . """ import argparse import sys import os import logging import time import numpy as np import facetnet as fn import pandas as pd if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "edgelist", help="full path to edge-list file", type=str) parser.add_argument( "alpha", help="alpha cost weight (0.0, 1.0] for gamma = CS*alpha + CT*(1-alpha)", type=float) parser.add_argument("m_cluster", help="number of clusters", type=int) parser.add_argument("res_folder", help="path to results folder, where" "xcap.dat, lcap.dat, idmap.dat, idmap_inv.dat, soft_comm.csv" "will be saved", type=str) parser.add_argument( "t_step", help="network time step, to save result", type=int) parser.add_argument("--xcap", help="full path to xcap.dat file", type=str) parser.add_argument("--lcap", help="full path to lcap.dat file", type=str) parser.add_argument( "--idmap", help="full path to idmap.dat file", type=str) parser.add_argument( "--idmap_inv", help="full path to idmap_inv.dat file", type=str) parser.add_argument( "-no_weights", help="if set, does not expect weight column in edgelists", action='store_true') parser.add_argument( "-show", help="show convergence plot of gamma", action='store_true') parser.add_argument( "-permutations", help="number of permutations for significance check of Qs", type=int, default=0) parser.add_argument( "--show", help="show convergence plot of gamma", type=str) args = parser.parse_args() logging.basicConfig(filename="{}/alpha{}_nw{}_{}.log".format(args.res_folder, args.alpha, args.t_step, time.strftime("%d-%m-%Y_%H-%M-%S", time.localtime())), level=logging.INFO) if args.alpha <= 0.0 or args.alpha > 1.0: logging.error("Alpha value must be in (0.0, 1.0], terminate script") sys.exit(1) if not os.path.exists(args.res_folder): logging.error("Folder: {} does not exist".format(args.res_folder)) sys.exit(1) logging.info("Analyzing network: {}".format(args.edgelist)) logging.info("# time-step: {}, alpha: {}, # communities: {}".format( args.t_step, args.alpha, args.m_cluster)) start = time.time() if args.xcap is None and args.lcap is None and args.idmap is None and args.idmap_inv is None: idmap, idmap_inv, xc, lc, qc_s, soft_comm, comm_net, evol_net, m_eff, qc_dist = fn.facetnet_step( args.edgelist, args.alpha, args.m_cluster, permutations=args.permutations, show_plot=args.show, weighted=not args.no_weights) elif args.xcap is not None and args.lcap is not None and args.idmap is not None and args.idmap_inv is not None: xc = np.load(args.xcap, allow_pickle=True) lc = np.load(args.lcap, allow_pickle=True) idmap = np.ndarray.tolist(np.load(args.idmap, allow_pickle=True)) idmap_inv = np.ndarray.tolist( np.load(args.idmap_inv, allow_pickle=True)) idmap, idmap_inv, xc, lc, qc_s, soft_comm, comm_net, evol_net, m_eff, qc_dist = fn.facetnet_step( args.edgelist, args.alpha, args.m_cluster, permutations=args.permutation, show_plot=args.show, xc_prev=xc, lc_prev=lc, idmap0=idmap, idmap_inv0=idmap_inv, weighted=not args.no_weights) else: logging.error( "Some of (xcap, ycap, idmap, idmap_inv) are given, some not") sys.exit(1) stop = time.time() logging.info("Soft modularity Qc = ({})".format(qc_s)) logging.info("Elapsed time: {} sec".format(stop - start)) # Save end state of current step for input to next step xc.dump("{}/xcap_alpha{}_nw{}.dat".format(args.res_folder, args.alpha, args.t_step)) lc.dump("{}/lcap_alpha{}_nw{}.dat".format(args.res_folder, args.alpha, args.t_step)) np.asarray(idmap).dump( "{}/idmap_alpha{}_nw{}.dat".format(args.res_folder, args.alpha, args.t_step)) np.asarray(idmap_inv).dump( "{}/idmap_inv_alpha{}_nw{}.dat".format(args.res_folder, args.alpha, args.t_step)) # Save results for analysis clusters = [] for i in range(m_eff): clusters.append("cluster_{}".format(i)) if args.xcap is not None and args.lcap is not None and args.idmap is not None and args.idmap_inv is not None: evol_net_df = pd.DataFrame(data=evol_net, columns=clusters) evol_net_df.to_csv("{}/evol_net_step_alpha{}_nw{}.csv".format(args.res_folder, args.alpha, args.t_step), index=False) soft_comm_df = pd.DataFrame(data=soft_comm, columns=clusters) soft_comm_df.insert(0, column="id", value=idmap) soft_comm_df.to_csv("{}/soft_comm_step_alpha{}_nw{}.csv".format(args.res_folder, args.alpha, args.t_step), index=False) comm_net_df = pd.DataFrame(data=comm_net, columns=clusters) comm_net_df.to_csv("{}/comm_net_step_alpha{}_nw{}.csv".format(args.res_folder, args.alpha, args.t_step), index=False) lc_df = pd.DataFrame(data=lc, columns=clusters) lc_df.to_csv("{}/lcap_alpha{}_nw{}.csv".format(args.res_folder, args.alpha, args.t_step), index=False) if args.m_cluster < 0: qc_s_df = pd.DataFrame(data=qc_s, columns=["Q_s"]) qc_s_df.to_csv("{}/q_alpha{}_nw{}.csv".format(args.res_folder, args.alpha, args.t_step), index=False) if args.permutations > 0: qc_dist_df = pd.DataFrame(data=qc_dist, columns=["Q_s"]) qc_dist_df.to_csv("{}/q_permute_alpha{}_nw{}.csv".format( args.res_folder, args.alpha, args.t_step), index=False) logging.info("Results and state written to: {}".format(args.res_folder))