sgtlib 3.3.9b0__py3-none-any.whl → 3.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
StructuralGT/__init__.py CHANGED
@@ -24,7 +24,7 @@ of the GNU General Public License along with this program. If not, see <https:/
24
24
 
25
25
 
26
26
  # Project Details
27
- __version__ = "3.3.9beta"
27
+ __version__ = "3.4.0"
28
28
  __install_version__ = "3.3.9"
29
29
  __title__ = f"StructuralGT (v{__version__})"
30
30
  __author__ = "Dickson Owuor"
@@ -0,0 +1,61 @@
1
+ //#define _POSIX_C_SOURCE 200809L // Linux
2
+ #include <stdio.h>
3
+ #include <stdarg.h>
4
+ #include <string.h>
5
+ //#include "sgt_base.h"
6
+ #include "include/sgt_base.h"
7
+
8
+ // Function to compute Local Node Connectivity
9
+ void* compute_lnc(void *arg) {
10
+ ThreadArgsLNC *args = (ThreadArgsLNC*)arg;
11
+ igraph_integer_t lnc;
12
+
13
+ igraph_st_vertex_connectivity(args->graph, &lnc, args->i, args->j, IGRAPH_VCONN_NEI_NEGATIVE);
14
+
15
+ // Update shared data under mutex lock
16
+ pthread_mutex_lock(args->mutex);
17
+ if (lnc != -1){
18
+ *(args->total_nc) += lnc;
19
+ *(args->total_count) += 1;
20
+ //printf("got %d\n", lnc);
21
+ //printf("NC:%d Count:%d \n", *(args->total_nc), *(args->total_count));
22
+ }
23
+ pthread_mutex_unlock(args->mutex);
24
+
25
+ pthread_exit(NULL);
26
+ }
27
+
28
+ // Function to convert string representation of adjacency matrix to 2D matrix
29
+ igraph_matrix_t* str_to_matrix(char* str_adj_mat, igraph_integer_t num_vertices) {
30
+ // Allocate memory for the matrix
31
+ igraph_matrix_t* mat = (igraph_matrix_t*)malloc(sizeof(igraph_matrix_t));
32
+ if (!mat) {
33
+ fprintf(stderr, "Failed to allocate memory for matrix structure\n");
34
+ exit(EXIT_FAILURE);
35
+ }
36
+ igraph_matrix_init(mat, num_vertices, num_vertices);
37
+
38
+ // Parse string and populate matrix
39
+ char* token;
40
+ char* nextToken;
41
+ const char delimiters[] = ",";
42
+
43
+ // Get the first token
44
+ // strtok_r - MacOs
45
+ //token = strtok_r(str_adj_mat, delimiters, &nextToken);
46
+ token = strtok_s(str_adj_mat, delimiters, &nextToken);
47
+
48
+ // Iterate through the remaining tokens
49
+ for (igraph_integer_t i = 0; i < num_vertices; i++) {
50
+ for (igraph_integer_t j = 0; j < num_vertices; j++) {
51
+ MATRIX(*mat, i, j) = atoi(token);
52
+ // Get the next token
53
+ // strtok_r - MacOs
54
+ //token = strtok_r(NULL, delimiters, &nextToken);
55
+ token = strtok_s(NULL, delimiters, &nextToken);
56
+ }
57
+ }
58
+
59
+ return mat;
60
+ }
61
+
@@ -0,0 +1,183 @@
1
+ #include <stdlib.h>
2
+ #include <stdio.h>
3
+ #include <stdarg.h>
4
+
5
+ #define PY_SSIZE_T_CLEAN
6
+ #include <Python.h>
7
+ //#include "sgt_base.h"
8
+ #include "include/sgt_base.h"
9
+
10
+
11
+ static PyObject *ErrorObject;
12
+ static PyObject *
13
+ compute_anc(PyObject *self, PyObject *args)
14
+ {
15
+ int num_cpus;
16
+ int allow_mp;
17
+ char *f_name;
18
+
19
+ // Consider passing graph as String
20
+ if (!PyArg_ParseTuple(args, "sii:compute_anc", &f_name, &num_cpus, &allow_mp)){
21
+ return NULL;
22
+ }
23
+
24
+ /*if ( f_name == ''){
25
+ PyErr_SetString(ErrorObject, "Unable to retrieve graph.");
26
+ return NULL;
27
+ }*/
28
+
29
+ if ( num_cpus <= 0 || allow_mp < 0){
30
+ PyErr_SetString(ErrorObject, "Invalid CPU parameters.");
31
+ return NULL;
32
+ }
33
+
34
+ // Declare required variables
35
+ FILE *file;
36
+
37
+ igraph_t graph;
38
+ igraph_integer_t num_nodes;
39
+ igraph_integer_t count_nc = 0;
40
+ igraph_integer_t sum_nc = 0;
41
+ igraph_real_t anc = 0;
42
+
43
+ // Open the file containing the serialized graph
44
+ file = fopen(f_name, "r");
45
+ // Read the graph from the file
46
+ igraph_read_graph_edgelist(&graph, file, 0, IGRAPH_UNDIRECTED);
47
+ fclose(file);
48
+ // printf("Nodes: %d\nEdges: %d\n", (int)igraph_vcount(&graph), (int)igraph_ecount(&graph));
49
+
50
+ num_nodes = igraph_vcount(&graph);
51
+ if (allow_mp == 0){
52
+ printf("Using single processing\n");
53
+ igraph_integer_t lnc;
54
+ for (igraph_integer_t i=0; i<num_nodes; i++) {
55
+ for (igraph_integer_t j=i+1; j<num_nodes; j++){
56
+ igraph_st_vertex_connectivity(&graph, &lnc, i, j, IGRAPH_VCONN_NEI_NEGATIVE);
57
+ if (lnc == -1) { continue; }
58
+ sum_nc += lnc;
59
+ count_nc += 1;
60
+ }
61
+ }
62
+
63
+ }
64
+ else {
65
+ printf("Using multiprocessing\n");
66
+ // Initialize mutex
67
+ pthread_mutex_t mutex;
68
+ pthread_mutex_init(&mutex, NULL);
69
+
70
+ // Create thread pool
71
+ const int MAX_THREAD_COUNT = num_cpus;
72
+
73
+ // Allocate memory for threads and args arrays
74
+ pthread_t *threads = (pthread_t *)malloc(MAX_THREAD_COUNT * sizeof(pthread_t));
75
+ ThreadArgsLNC *args = (ThreadArgsLNC *)malloc(MAX_THREAD_COUNT * sizeof(ThreadArgsLNC));
76
+
77
+ if (threads == NULL || args == NULL) {
78
+ PyErr_SetString(ErrorObject, "Memory allocation failed\n");
79
+ return NULL;
80
+ }
81
+
82
+ // Initialize thread pool
83
+ for (int i = 0; i < MAX_THREAD_COUNT; i++) {
84
+ args[i].graph = &graph;
85
+ args[i].mutex = &mutex;
86
+ args[i].total_nc = &sum_nc;
87
+ args[i].total_count = &count_nc;
88
+ }
89
+
90
+ // Create threads for computing LNC
91
+ int idx = 0;
92
+ int thread_count = 0;
93
+ for (igraph_integer_t i = 0; i < num_nodes; i++) {
94
+ for (igraph_integer_t j = i + 1; j < num_nodes; j++) {
95
+ idx = (int)(thread_count % MAX_THREAD_COUNT);
96
+ if (thread_count >= MAX_THREAD_COUNT) {
97
+ // Wait for a thread to finish before starting a new one
98
+ pthread_join(threads[idx], NULL);
99
+ thread_count++;
100
+ }
101
+ args[idx].i = (int)i;
102
+ args[idx].j = (int)j;
103
+ pthread_create(&threads[idx], NULL, compute_lnc, &args[idx]);
104
+ thread_count++;
105
+ // printf("thread %d running...\n", (idx));
106
+ }
107
+ }
108
+
109
+ // Join threads
110
+ for (int i = 0; i < MAX_THREAD_COUNT && i < thread_count; i++) {
111
+ pthread_join(threads[i], NULL);
112
+ }
113
+
114
+ // Destroy mutex
115
+ pthread_mutex_destroy(&mutex);
116
+ // Free dynamically allocated memory
117
+ free(threads);
118
+ free(args);
119
+ }
120
+
121
+ // Compute ANC
122
+ anc = (float) sum_nc / count_nc;
123
+
124
+ // Destroy graph
125
+ igraph_destroy(&graph);
126
+
127
+ return PyFloat_FromDouble((double) anc);
128
+
129
+ }
130
+ static char compute_anc_doc[] =
131
+ "A C method that uses iGraph library to compute average node connectivity of a graph.\n"
132
+ "\n"
133
+ "Args:\n"
134
+ " file (string): CSV file with edge list of graph A.\n"
135
+ " cpus (int): number of available CPUs.\n"
136
+ " mp (int): allow multi-processing (0: No, 1: Yes).\n"
137
+ "\n"
138
+ "Returns:\n"
139
+ " ANC (float): Average Node Connectivity as a float value.\n";
140
+
141
+
142
+ static char sgt_doc[] =
143
+ "A C language module leveraging the iGraph library to compute Graph Theory (GT) metrics,"
144
+ "enhanced with multi-threading capabilities for accelerated computation.\n";
145
+
146
+ /* Method Table: ist of functions defined in the module */
147
+ static PyMethodDef sgt_methods[] = {
148
+ {"compute_anc", compute_anc, METH_VARARGS, compute_anc_doc },
149
+ //{"compute_lnc", compute_lnc, METH_VARARGS, "Compute local node connectivity." },
150
+ {NULL, NULL, 0, NULL} /* Sentinel */
151
+ };
152
+
153
+ /* Create module */
154
+ static struct PyModuleDef sgt_c_module = {
155
+ PyModuleDef_HEAD_INIT,
156
+ "sgt_c_module", /* name of module */
157
+ sgt_doc, /* module documentation, may be NULL */
158
+ -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
159
+ sgt_methods
160
+ };
161
+
162
+ /* Initialization function for the module */
163
+ PyMODINIT_FUNC
164
+ PyInit_sgt_c_module(void)
165
+ {
166
+ PyObject *m;
167
+
168
+ m = PyModule_Create(&sgt_c_module);
169
+ if (m == NULL)
170
+ return NULL;
171
+
172
+ ErrorObject = PyErr_NewException("sgt_c_module.error", NULL, NULL);
173
+ Py_XINCREF(ErrorObject);
174
+ if (PyModule_AddObject(m, "error", ErrorObject) < 0) {
175
+ Py_XDECREF(ErrorObject);
176
+ Py_CLEAR(ErrorObject);
177
+ Py_DECREF(m);
178
+ return NULL;
179
+ }
180
+
181
+ return m;
182
+ }
183
+
@@ -29,7 +29,6 @@ from networkx.algorithms.flow import maximum_flow
29
29
  from networkx.algorithms.distance_measures import diameter, periphery
30
30
  from networkx.algorithms.wiener import wiener_index
31
31
 
32
- from .c_lang import sgt_c_module as sgt
33
32
  from ..utils.progress_update import ProgressUpdate
34
33
  from ..networks.fiber_network import FiberNetworkBuilder
35
34
  from ..imaging.image_processor import ImageProcessor
@@ -654,6 +653,7 @@ class GraphAnalyzer(ProgressUpdate):
654
653
  ---------
655
654
  :param nx_graph: NetworkX graph object.
656
655
  """
656
+ from .c_lang import sgt_c_module as sgt
657
657
 
658
658
  cpu_count = get_num_cores()
659
659
  num_threads = cpu_count if nx.number_of_nodes(nx_graph) < 2000 else cpu_count * 2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sgtlib
3
- Version: 3.3.9b0
3
+ Version: 3.4.0
4
4
  Summary: A software tool for graph theory analysis of microscopy images.
5
5
  Author-email: Dickson Owuor <owuordickson@gmail.com>, "Drew A. Vecchio" <vecdrew@umich.edu>, Kody Whisnant <kgwhis@umich.edu>, Alain Kadar <alaink@umich.edu>, Xiong Ye Xiao <xiongyex@usc.edu>, Nicholas Kotov <kotov@umich.edu>
6
6
  Maintainer-email: Dickson Owuor <owuordickson@gmail.com>
@@ -1,4 +1,4 @@
1
- StructuralGT/__init__.py,sha256=rVWsQlTc1X6aXvaoHEdLGtaLWpcu2EtFD4ZszbYJtbg,1258
1
+ StructuralGT/__init__.py,sha256=8O4pI5ydEdxVMuojfGLzMWBjt7dVw2shSmAmw52F9tg,1254
2
2
  StructuralGT/entrypoints.py,sha256=s2upsOVsy9zsoorxiZXaZKiLw7fUOQwHjwup3C089Hs,1413
3
3
  StructuralGT/modules.py,sha256=CYudBMwP70cRFWj_Dppr_Kdc08V_-9wWKVd48bEHkS0,743
4
4
  StructuralGT/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -50,7 +50,9 @@ StructuralGT/apps/sgt_qml/widgets/RescaleControlWidget.qml,sha256=qb6fXok5C1HJjb
50
50
  StructuralGT/apps/sgt_qml/widgets/RibbonWidget.qml,sha256=POaPwXh7vE4UwU82x-80BuI2625FLWbmJQsZliy618w,13990
51
51
  StructuralGT/apps/sgt_qml/widgets/StatusBarWidget.qml,sha256=YRTSg_4aYA3FO69wT1NnX0Ri_qRx3AHhVrS1n3pVwd4,5969
52
52
  StructuralGT/compute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- StructuralGT/compute/graph_analyzer.py,sha256=zQ8qZSeGysU3ubIvOPKMQlSTmUxdRoENa_lV4jpDxE4,69851
53
+ StructuralGT/compute/graph_analyzer.py,sha256=E2vIaIcApy3VI7gM2rLZ30X8SGtOhzhEkVufMcL-ngA,69859
54
+ StructuralGT/compute/c_lang/sgt_base.c,sha256=VFgwVDALjWl_zAP5NqNwG5pLv6no91_93RYPziHT2hY,1953
55
+ StructuralGT/compute/c_lang/sgtmodule.c,sha256=85VhQCxNow49yslayaCnCFwseS6vXVvJ77RjypkHG1o,5492
54
56
  StructuralGT/compute/c_lang/include/sgt_base.h,sha256=jkCpNy_01bSKk_ay6_1TilNhribMmw-p8r8FRhamstM,530
55
57
  StructuralGT/imaging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
58
  StructuralGT/imaging/base_image.py,sha256=Cc4xeVOxpID6SukVolYtD6OiEQ4tsUGQ4mYjE3QF_2E,16555
@@ -64,9 +66,9 @@ StructuralGT/utils/config_loader.py,sha256=8px8iGOFCGz8qIZCfyGuAFfvvaVdOjogf9PqS
64
66
  StructuralGT/utils/configs.ini,sha256=sKPsAd15_YubgGhLMVuse1JRuU7S6bFYjLbzkuoD5JI,2326
65
67
  StructuralGT/utils/progress_update.py,sha256=9X_9mGLgTMF5dDSTNKpELQcmFv8r1wz6YZQCqy4tCl8,1621
66
68
  StructuralGT/utils/sgt_utils.py,sha256=0vg7I4P6PIao_H8-KYgkCJ6TM9eESW-RwGZB4sGgCI4,9109
67
- sgtlib-3.3.9b0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
68
- sgtlib-3.3.9b0.dist-info/METADATA,sha256=LhSgnFTCv66a-Yd0lSiQhed0qgpmGDWkK0T-U404VMQ,45280
69
- sgtlib-3.3.9b0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
70
- sgtlib-3.3.9b0.dist-info/entry_points.txt,sha256=zY3v_U9Qi4L965BPrURXn84yF_TxdKDZI3VcTUbTh0M,120
71
- sgtlib-3.3.9b0.dist-info/top_level.txt,sha256=daVVcqfvgGeWXFnHArFOFbRmtWxL93fxmZjF19Sg69I,13
72
- sgtlib-3.3.9b0.dist-info/RECORD,,
69
+ sgtlib-3.4.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
70
+ sgtlib-3.4.0.dist-info/METADATA,sha256=KLud3ApS4KMRC6hYaHiseM1P4kQ57Oy8EhNvQ9B9ANU,45278
71
+ sgtlib-3.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
72
+ sgtlib-3.4.0.dist-info/entry_points.txt,sha256=zY3v_U9Qi4L965BPrURXn84yF_TxdKDZI3VcTUbTh0M,120
73
+ sgtlib-3.4.0.dist-info/top_level.txt,sha256=daVVcqfvgGeWXFnHArFOFbRmtWxL93fxmZjF19Sg69I,13
74
+ sgtlib-3.4.0.dist-info/RECORD,,