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 +1 -1
- StructuralGT/compute/c_lang/sgt_base.c +61 -0
- StructuralGT/compute/c_lang/sgtmodule.c +183 -0
- StructuralGT/compute/graph_analyzer.py +1 -1
- {sgtlib-3.3.9b0.dist-info → sgtlib-3.4.0.dist-info}/METADATA +1 -1
- {sgtlib-3.3.9b0.dist-info → sgtlib-3.4.0.dist-info}/RECORD +10 -8
- {sgtlib-3.3.9b0.dist-info → sgtlib-3.4.0.dist-info}/WHEEL +0 -0
- {sgtlib-3.3.9b0.dist-info → sgtlib-3.4.0.dist-info}/entry_points.txt +0 -0
- {sgtlib-3.3.9b0.dist-info → sgtlib-3.4.0.dist-info}/licenses/LICENSE +0 -0
- {sgtlib-3.3.9b0.dist-info → sgtlib-3.4.0.dist-info}/top_level.txt +0 -0
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.
|
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
|
+
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=
|
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=
|
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.
|
68
|
-
sgtlib-3.
|
69
|
-
sgtlib-3.
|
70
|
-
sgtlib-3.
|
71
|
-
sgtlib-3.
|
72
|
-
sgtlib-3.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|