From 31b2d48ca9fe1a46d64bfa670773d6a490f47551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emek=20G=C3=B6zl=C3=BCkl=C3=BC?= Date: Sat, 2 May 2020 01:45:10 +0300 Subject: [PATCH 1/4] add requirements.txt file --- requirements.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..888507e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +cycler==0.10.0 +joblib==0.14.1 +kiwisolver==1.2.0 +matplotlib==3.2.1 +numpy==1.18.3 +pyparsing==2.4.7 +python-dateutil==2.8.1 +scikit-learn==0.22.2.post1 +scipy==1.4.1 +six==1.14.0 +snfpy==0.2.2 From f135d987b3027653f0e6663086401700cdf5e5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emek=20G=C3=B6zl=C3=BCkl=C3=BC?= Date: Sat, 2 May 2020 01:49:01 +0300 Subject: [PATCH 2/4] add .gitignore file --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b560df3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.pyc +__pychache__\* +venv +.idea From b89fc8d73d541160e24d937c23a97514caf6d416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emek=20G=C3=B6zl=C3=BCkl=C3=BC?= Date: Sat, 2 May 2020 01:53:48 +0300 Subject: [PATCH 3/4] add __name__ condition for main scope --- netNorm.py | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/netNorm.py b/netNorm.py index 2cb628b..9e4eb4c 100644 --- a/netNorm.py +++ b/netNorm.py @@ -187,18 +187,26 @@ def cross_subjects_cbt(fused_network, nbr_of_exemples): fused_network = np.array(fused_network) return fused_network -nbr_of_sub = int(input('Please select the number of subjects: ')) -nbr_of_regions = int(input('Please select the number of regions: ')) -nbr_of_views= int(input('Please select the number of views: ')) - -v = np.random.rand(nbr_of_views, nbr_of_sub,nbr_of_regions, nbr_of_regions) -A = netNorm(v, nbr_of_sub, nbr_of_regions) -print(A) - -mx = A.max() -mn = A.min() -print(mx) -print(mn) -plt.pcolor(A, vmin=mn, vmax=mx) -plt.imshow(A) -plt.show() + +# work if file not imported +if __name__ == "__main__": + + # take user inputs + nbr_of_sub = int(input('Please select the number of subjects: ')) + nbr_of_regions = int(input('Please select the number of regions: ')) + nbr_of_views = int(input('Please select the number of views: ')) + + # get random views and calculate example CBT + v = np.random.rand(nbr_of_views, nbr_of_sub,nbr_of_regions, nbr_of_regions) + A = netNorm(v, nbr_of_sub, nbr_of_regions) + + # print min and max values + mx = A.max() + mn = A.min() + print(mx) + print(mn) + + # plot the final CBT matrix + plt.pcolor(A, vmin=mn, vmax=mx) + plt.imshow(A) + plt.show() From 916abc033644e6ac7785b93519522076527fca99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emek=20G=C3=B6zl=C3=BCkl=C3=BC?= Date: Sat, 2 May 2020 03:15:07 +0300 Subject: [PATCH 4/4] fixed nested function structure nested functions are not usable. using class based approach instead, makes things easier and more useful owing to methods, shared variables etc. Also, people might want to integrate this class to their own projects. It is not possible to do so with nested function structure. --- netNorm.py | 236 ++++++++++++++++++++++++++++------------------------- 1 file changed, 123 insertions(+), 113 deletions(-) diff --git a/netNorm.py b/netNorm.py index 9e4eb4c..3402e0f 100644 --- a/netNorm.py +++ b/netNorm.py @@ -1,101 +1,113 @@ -"""Main function of netNorm for the paper: Estimation of Connectional Brain Templates using Selective Multi -View Network Normalization - Details can be found in: - (1) the original paper https://www.ncbi.nlm.nih.gov/pubmed/31622839 - Salma Dhifallah, and Islem Rekik. - --------------------------------------------------------------------- - This file contains the implementation of three key steps of our netNorm framework: - netNorm(sourceGraph, number_of_subjects, number_of_regions) - Inputs: - sourceGraph: (n × m x t x t) matrix stacking the source graphs of all subjects - n the total number of views - m the number of subjects - t number of regions - Output: - CBT: (t x t) matrix representing the cortical brain template - (2) Dependencies: please install the following libraries: - - matplotlib - - numpy - - snfpy (https://github.com/rmarkello/snfpy) - - scikitlearn - --------------------------------------------------------------------- - Copyright 2019 Salma Dhifallah, Sousse University. - Please cite the above paper if you use this code. - All rights reserved. - """ - import numpy as np import snf from sklearn import preprocessing import matplotlib.pyplot as plt -def netNorm(v, nbr_of_sub, nbr_of_regions): - nbr_of_feat = int((np.square(nbr_of_regions) - nbr_of_regions) / 2) +class NetNorm: + """ + Main function of netNorm for the paper: Estimation of Connectional Brain Templates using Selective Multi + View Network Normalization + Details can be found in: + (1) the original paper https://www.ncbi.nlm.nih.gov/pubmed/31622839 + Salma Dhifallah, and Islem Rekik. + --------------------------------------------------------------------- + This file contains the implementation of three key steps of our netNorm framework: + netNorm(sourceGraph, number_of_subjects, number_of_regions) + Inputs: + sourceGraph: (n × m x t x t) matrix stacking the source graphs of all subjects + n the total number of views + m the number of subjects + t number of regions + Output: + CBT: (t x t) matrix representing the cortical brain template + (2) Dependencies: please install the following libraries: + - matplotlib + - numpy + - snfpy (https://github.com/rmarkello/snfpy) + - scikitlearn + --------------------------------------------------------------------- + Copyright 2019 Salma Dhifallah, Sousse University. + Please cite the above paper if you use this code. + All rights reserved. + """ + + def __init__(self, v_matrix, num_of_sub, num_of_reg): + self.nbr_of_sub = num_of_sub + self.nbr_of_feat = int((np.square(num_of_reg) - num_of_reg) / 2) + self.nbr_of_views = v_matrix.shape[0] + self.nbr_of_regions = num_of_reg + self.v = v_matrix + + @staticmethod def minmax_sc(x): min_max_scaler = preprocessing.MinMaxScaler() x = min_max_scaler.fit_transform(x) return x - def upper_triangular(): - All_subj = np.zeros((nbr_of_sub, len(v), nbr_of_feat)) - for i in range(len(v)): - for j in range (nbr_of_sub): + def upper_triangular(self): + all_subj = np.zeros((self.nbr_of_sub, len(self.v), self.nbr_of_feat)) + for i in range(len(self.v)): + for j in range(self.nbr_of_sub): - subj_x = v[i, j, :, :] - subj_x = np.reshape(subj_x, (nbr_of_regions, nbr_of_regions)) - subj_x = minmax_sc(subj_x) - subj_x = subj_x[np.triu_indices(nbr_of_regions, k = 1)] - subj_x = np.reshape(subj_x, (1, 1, nbr_of_feat)) - All_subj[j, i, :] = subj_x + subj_x = self.v[i, j, :, :] + subj_x = np.reshape(subj_x, (self.nbr_of_regions, self.nbr_of_regions)) + subj_x = self.minmax_sc(subj_x) + subj_x = subj_x[np.triu_indices(self.nbr_of_regions, k=1)] + subj_x = np.reshape(subj_x, (1, 1, self.nbr_of_feat)) + all_subj[j, i, :] = subj_x - return All_subj + return all_subj - def distances_inter(All_subj): + def distances_inter(self, all_subj): theta = 0 distance_vector = np.zeros(1) distance_vector_final = np.zeros(1) - x = All_subj - for i in range(nbr_of_feat): #par rapport ll number of ROIs - ROI_i = x[:, :, i] - ROI_i = np.reshape(ROI_i, (nbr_of_sub, nbr_of_views)) #1,3 - for j in range(nbr_of_sub): - subj_j = ROI_i[j:j+1, :] - subj_j = np.reshape(subj_j, (1, nbr_of_views)) - for k in range(nbr_of_sub): + x = all_subj + distance_euclidienne_sub_j_sub_k = None + for i in range(self.nbr_of_feat): # par rapport ll number of ROIs + roi_i = x[:, :, i] + roi_i = np.reshape(roi_i, (self.nbr_of_sub, self.nbr_of_views)) # 1,3 + for j in range(self.nbr_of_sub): + subj_j = roi_i[j:j+1, :] + subj_j = np.reshape(subj_j, (1, self.nbr_of_views)) + for k in range(self.nbr_of_sub): if k != j: - subj_k = ROI_i[k:k+1, :] - subj_k = np.reshape(subj_k, (1, nbr_of_views)) + subj_k = roi_i[k:k+1, :] + subj_k = np.reshape(subj_k, (1, self.nbr_of_views)) - for l in range(nbr_of_views): - if l ==0: + for l in range(self.nbr_of_views): + if distance_euclidienne_sub_j_sub_k is None: distance_euclidienne_sub_j_sub_k = np.square(subj_k[:, l:l+1] - subj_j[:, l:l+1]) else: - distance_euclidienne_sub_j_sub_k = distance_euclidienne_sub_j_sub_k + np.square(subj_k[:, l:l+1] - subj_j[:, l:l+1]) + distance_euclidienne_sub_j_sub_k = distance_euclidienne_sub_j_sub_k + np.square( + subj_k[:, l:l+1] - subj_j[:, l:l+1] + ) - theta +=1 - if j ==0: + theta += 1 + if j == 0: distance_vector = np.sqrt(distance_euclidienne_sub_j_sub_k) else: - distance_vector = np.concatenate((distance_vector, np.sqrt(distance_euclidienne_sub_j_sub_k)), axis=0) + distance_vector = np.concatenate((distance_vector, np.sqrt( + distance_euclidienne_sub_j_sub_k)), axis=0 + ) - if i ==0: + if i == 0: distance_vector_final = distance_vector else: distance_vector_final = np.concatenate((distance_vector_final, distance_vector), axis=1) - print(theta) return distance_vector_final - - def minimum_distances(distance_vector_final): + def minimum_distances(self, distance_vector_final): x = distance_vector_final + general_minimum = final_general_minimum = None - for i in range(nbr_of_feat): - for j in range(nbr_of_sub): + for i in range(self.nbr_of_feat): + for j in range(self.nbr_of_sub): minimum_sub = x[j:j+1, i:i+1] minimum_sub = float(minimum_sub) - for k in range(nbr_of_sub): + for k in range(self.nbr_of_sub): if k != j: local_sub = x[k:k+1, i:i+1] local_sub = float(local_sub) @@ -111,81 +123,78 @@ def minimum_distances(distance_vector_final): return final_general_minimum - def new_tensor(final_general_minimum, All_subj): - y = All_subj + def new_tensor(self, final_general_minimum, all_subj): + y = all_subj x = final_general_minimum - for i in range(nbr_of_feat): + final_new_tensor = None + for i in range(self.nbr_of_feat): optimal_subj = x[:, i:i+1] - optimal_subj = np.reshape(optimal_subj, (1)) + optimal_subj = np.reshape(optimal_subj, (1,)) optimal_subj = int(optimal_subj) - if i ==0: + if final_new_tensor is None: final_new_tensor = y[optimal_subj: optimal_subj+1, :, i:i+1] else: final_new_tensor = np.concatenate((final_new_tensor, y[optimal_subj: optimal_subj+1, :, i:i+1]), axis=2) return final_new_tensor + def make_sym_matrix(self, feature_vector): - def make_sym_matrix(nbr_of_regions, feature_vector): - - nbr_of_regions = nbr_of_regions - feature_vector = feature_vector - my_matrix = np.zeros([nbr_of_regions,nbr_of_regions], dtype=np.double) + my_matrix = np.zeros([self.nbr_of_regions, self.nbr_of_regions], dtype=np.double) - my_matrix[np.triu_indices(nbr_of_regions, k=1)] = feature_vector + my_matrix[np.triu_indices(self.nbr_of_regions, k=1)] = feature_vector my_matrix = my_matrix + my_matrix.T - my_matrix[np.diag_indices(nbr_of_regions)] = 0 + my_matrix[np.diag_indices(self.nbr_of_regions)] = 0 return my_matrix - def re_make_tensor(final_new_tensor, nbr_of_regions): - x =final_new_tensor - x = np.reshape(x, (nbr_of_views, nbr_of_feat)) - for i in range (nbr_of_views): + def re_make_tensor(self, final_new_tensor): + x = final_new_tensor + x = np.reshape(x, (self.nbr_of_views, self.nbr_of_feat)) + tensor_for_snf = None + for i in range(self.nbr_of_views): view_x = x[i, :] - view_x = np.reshape(view_x, (1, nbr_of_feat)) - view_x = make_sym_matrix(nbr_of_regions, view_x) - view_x = np.reshape(view_x, (1, nbr_of_regions, nbr_of_regions)) - if i ==0: + view_x = np.reshape(view_x, (1, self.nbr_of_feat)) + view_x = self.make_sym_matrix(view_x) + view_x = np.reshape(view_x, (1, self.nbr_of_regions, self.nbr_of_regions)) + if tensor_for_snf is None: tensor_for_snf = view_x else: tensor_for_snf = np.concatenate((tensor_for_snf, view_x), axis=0) return tensor_for_snf - def create_list(tensor_for_snf): - x =tensor_for_snf - for i in range(nbr_of_views): + def create_list(self, tensor_for_snf): + x = tensor_for_snf + list_final = list() + for i in range(self.nbr_of_views): view = x[i, :, :] - view = np.reshape(view, (nbr_of_regions, nbr_of_regions)) - list = [view] - if i ==0: - list_final = list - else: - list_final = list_final +list + view = np.reshape(view, (self.nbr_of_regions, self.nbr_of_regions)) + list_final.append(view) return list_final - def cross_subjects_cbt(fused_network, nbr_of_exemples): - final_cbt = np.zeros((nbr_of_exemples, nbr_of_feat)) + # not used + def cross_subjects_cbt(self, fused_network, nbr_of_examples): + final_cbt = np.zeros((nbr_of_examples, self.nbr_of_feat)) x = fused_network - x = x[np.triu_indices(nbr_of_regions, k=1)] - x = np.reshape(x, (1, nbr_of_feat)) - for i in range(nbr_of_exemples): + x = x[np.triu_indices(self.nbr_of_regions, k=1)] + x = np.reshape(x, (1, self.nbr_of_feat)) + for i in range(nbr_of_examples): final_cbt[i, :] = x - return final_cbt - Upp_trig = upper_triangular() - Dis_int = distances_inter(Upp_trig) - Min_dis = minimum_distances(Dis_int) - New_ten = new_tensor(Min_dis, Upp_trig) - Re_ten = re_make_tensor(New_ten, nbr_of_regions) - Cre_lis = create_list(Re_ten) - fused_network = snf.snf((Cre_lis), K=20) - fused_network = minmax_sc(fused_network) - np.fill_diagonal(fused_network, 0) - fused_network = np.array(fused_network) - return fused_network + def run(self): + upp_trig = self.upper_triangular() + dis_int = self.distances_inter(upp_trig) + min_distances = self.minimum_distances(dis_int) + new_tensor = self.new_tensor(min_distances, upp_trig) + re_tensor = self.re_make_tensor(new_tensor) + cre_lis = self.create_list(re_tensor) + fused_network = snf.snf(cre_lis, K=20) + fused_network = self.minmax_sc(fused_network) + np.fill_diagonal(fused_network, 0) + fused_network = np.array(fused_network) + return fused_network # work if file not imported @@ -197,14 +206,15 @@ def cross_subjects_cbt(fused_network, nbr_of_exemples): nbr_of_views = int(input('Please select the number of views: ')) # get random views and calculate example CBT - v = np.random.rand(nbr_of_views, nbr_of_sub,nbr_of_regions, nbr_of_regions) - A = netNorm(v, nbr_of_sub, nbr_of_regions) + v = np.random.rand(nbr_of_views, nbr_of_sub, nbr_of_regions, nbr_of_regions) + nn = NetNorm(v, nbr_of_sub, nbr_of_regions) + + # run operations + A = nn.run() # print min and max values mx = A.max() mn = A.min() - print(mx) - print(mn) # plot the final CBT matrix plt.pcolor(A, vmin=mn, vmax=mx)