fSTG-Toolkit 1.3.0__tar.gz → 1.4.0__tar.gz
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.
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/PKG-INFO +2 -1
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/README.md +1 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/pyproject.toml +1 -1
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/__main__.py +33 -5
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/frequent/spminer.py +3 -2
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/io.py +6 -4
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/Dockerfile +1 -1
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/batch_process.py +39 -33
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/LICENSE +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/__init__.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/__init__.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/assets/common.js +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/assets/custom.css +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/assets/favicon.ico +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/core/__init__.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/core/color.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/core/config.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/core/datafilesdb.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/core/geometry.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/core/processing.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/core/utils.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/figures/__init__.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/figures/common.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/figures/data.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/figures/frequent.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/figures/matrices.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/figures/metrics.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/figures/subject.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/fstg_view.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/pages/dashboard.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/pages/home.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/pages/list.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/pages/submit.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/views/__init__.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/views/common.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/views/data.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/views/frequent.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/views/matrices.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/views/metrics.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/app/views/subject.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/factory.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/frequent/__init__.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/frequent/_docker_utils.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/frequent/patterns.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/graph.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/logging.yml +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/metrics.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/simulation.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/.env +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/NOTICE.md +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/ckpt/model.pt +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/common/combined_syn.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/common/data.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/common/feature_preprocess.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/common/models.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/common/utils.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/docker-compose.yml +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/requirements.txt +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/alignment.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/config.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/hyp_search.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/test.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/train.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_mining/config.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_mining/decoder.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_mining/search_agents.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/utils.py +0 -0
- {fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/visualization.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fSTG-Toolkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: An Open-Source Software for Spatio-Temporal Graph Analysis of fMRI data.
|
|
5
5
|
License-Expression: CECILL-2.1
|
|
6
6
|
License-File: LICENSE
|
|
@@ -52,6 +52,7 @@ Description-Content-Type: text/markdown
|
|
|
52
52
|

|
|
53
53
|

|
|
54
54
|
[](https://fstg-toolkit.readthedocs.io/)
|
|
55
|
+
[](https://doi.org/10.5281/zenodo.22093918)
|
|
55
56
|
|
|
56
57
|
</div>
|
|
57
58
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|

|
|
11
11
|

|
|
12
12
|
[](https://fstg-toolkit.readthedocs.io/)
|
|
13
|
+
[](https://doi.org/10.5281/zenodo.22093918)
|
|
13
14
|
|
|
14
15
|
</div>
|
|
15
16
|
|
|
@@ -126,6 +126,24 @@ def __load_graph(filepath: Path) -> SpatioTemporalGraph:
|
|
|
126
126
|
return loader.load_graph(areas, chosen)
|
|
127
127
|
|
|
128
128
|
|
|
129
|
+
def __with_zip_suffix(filepath: Path) -> Path:
|
|
130
|
+
"""Add the '.zip' extension to a path of archive, if it is missing.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
filepath : Path
|
|
135
|
+
The path of the archive to write.
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
Path
|
|
140
|
+
The path ending with the '.zip' extension.
|
|
141
|
+
"""
|
|
142
|
+
if filepath.suffix.lower() == '.zip':
|
|
143
|
+
return filepath
|
|
144
|
+
return filepath.with_name(f'{filepath.name}.zip')
|
|
145
|
+
|
|
146
|
+
|
|
129
147
|
## building and computing #####################################################
|
|
130
148
|
|
|
131
149
|
|
|
@@ -224,6 +242,7 @@ def build(areas_description_path: Path, correlation_matrices_path: Tuple[Path],
|
|
|
224
242
|
|
|
225
243
|
The CSV file for the description of areas and regions should have the columns: `Id_Area`, `Name_Area`, and `Name_Region`.
|
|
226
244
|
"""
|
|
245
|
+
output = __with_zip_suffix(output)
|
|
227
246
|
|
|
228
247
|
# prepare the data saver
|
|
229
248
|
saver = DataSaver()
|
|
@@ -234,6 +253,9 @@ def build(areas_description_path: Path, correlation_matrices_path: Tuple[Path],
|
|
|
234
253
|
matrices = {}
|
|
235
254
|
for cm in correlation_matrices_path:
|
|
236
255
|
for name, matrix in __read_load_np(cm):
|
|
256
|
+
if name in matrices:
|
|
257
|
+
error_console.print(f"Warning: sequence '{name}' from '{cm.name}' "
|
|
258
|
+
f"replaces a previous sequence with the same name.")
|
|
237
259
|
matrices[name] = matrix
|
|
238
260
|
console.print(f"- red '{cm.name}'")
|
|
239
261
|
console.print(f"Red {len(correlation_matrices_path)} files.")
|
|
@@ -640,7 +662,8 @@ GRAPH_SEQUENCE_DESCRIPTION = GraphSequenceDescription()
|
|
|
640
662
|
@graph.group()
|
|
641
663
|
@click.option('-o', '--output_path', type=click.Path(writable=True, path_type=Path),
|
|
642
664
|
default="output", show_default="a file named 'output' in the current directory",
|
|
643
|
-
help="Path where to write the simulated output."
|
|
665
|
+
help="Path where to write the simulated output. The extension is added if missing: "
|
|
666
|
+
"'.zip' for patterns and sequences, '.npz' for correlations.")
|
|
644
667
|
@click.pass_context
|
|
645
668
|
def simulate(ctx: click.core.Context, output_path: Path):
|
|
646
669
|
"""Simulate a spatio-temporal graph."""
|
|
@@ -679,7 +702,7 @@ def pattern(ctx: click.core.Context, networks: List[List[Tuple[Tuple[int, int],
|
|
|
679
702
|
pat = generate_pattern(networks_list=networks,
|
|
680
703
|
spatial_edges=spatial_edges,
|
|
681
704
|
temporal_edges=temporal_edges)
|
|
682
|
-
save_spatio_temporal_graph(pat, ctx.obj)
|
|
705
|
+
save_spatio_temporal_graph(pat, __with_zip_suffix(ctx.obj))
|
|
683
706
|
|
|
684
707
|
|
|
685
708
|
@simulate.command()
|
|
@@ -697,7 +720,7 @@ def sequence(ctx: click.core.Context, patterns: Tuple[Path], sequence_descriptio
|
|
|
697
720
|
for i, filepath in enumerate(patterns)}
|
|
698
721
|
simulator = SpatioTemporalGraphSimulator(**pattern_graphs)
|
|
699
722
|
graph = simulator.simulate(*sequence_description)
|
|
700
|
-
save_spatio_temporal_graph(graph, ctx.obj)
|
|
723
|
+
save_spatio_temporal_graph(graph, __with_zip_suffix(ctx.obj))
|
|
701
724
|
|
|
702
725
|
|
|
703
726
|
@simulate.command()
|
|
@@ -707,11 +730,16 @@ def sequence(ctx: click.core.Context, patterns: Tuple[Path], sequence_descriptio
|
|
|
707
730
|
help="The correlation threshold when building graph from matrices.")
|
|
708
731
|
@click.pass_context
|
|
709
732
|
def correlations(ctx: click.core.Context, graph_path: Path, threshold: float):
|
|
710
|
-
"""Simulate correlations matrices from a spatio-temporal graph.
|
|
733
|
+
"""Simulate correlations matrices from a spatio-temporal graph.
|
|
734
|
+
|
|
735
|
+
The sequence of matrices is saved under the name of the output file (without its
|
|
736
|
+
'.npz' extension), which is the name the command 'build' gives to its graph.
|
|
737
|
+
"""
|
|
711
738
|
graph = __load_graph(graph_path)
|
|
712
739
|
simulator = CorrelationMatrixSequenceSimulator(graph, threshold=threshold)
|
|
713
740
|
matrices = simulator.simulate()
|
|
714
|
-
|
|
741
|
+
name = Path(ctx.obj).name.removesuffix('.npz')
|
|
742
|
+
np.savez_compressed(ctx.obj, **{name: matrices})
|
|
715
743
|
|
|
716
744
|
|
|
717
745
|
## showing ####################################################################
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
|
|
34
34
|
import logging
|
|
35
35
|
import re
|
|
36
|
+
from importlib.metadata import version
|
|
36
37
|
from pathlib import Path
|
|
37
38
|
from typing import Optional
|
|
38
39
|
|
|
@@ -73,8 +74,8 @@ class SPMinerService:
|
|
|
73
74
|
already loaded.
|
|
74
75
|
"""
|
|
75
76
|
if self.__docker_image is None:
|
|
76
|
-
#
|
|
77
|
-
tag = 'spminer:
|
|
77
|
+
# tagging by package version rebuilds the image when the bundled code changes
|
|
78
|
+
tag = f'spminer:{version("fSTG-Toolkit")}'
|
|
78
79
|
build_path = Path(__file__).parent.parent / 'spminer'
|
|
79
80
|
self.__docker_image = self.__docker_helper.load_local_image(tag, build_path)
|
|
80
81
|
|
|
@@ -1279,7 +1279,7 @@ def load_spatio_temporal_graph(filepath: Path | str) -> SpatioTemporalGraph:
|
|
|
1279
1279
|
If no graph is found in the zip file.
|
|
1280
1280
|
"""
|
|
1281
1281
|
logger.debug(f"Loading STG from '{filepath}'.")
|
|
1282
|
-
loader = DataLoader(filepath)
|
|
1282
|
+
loader = DataLoader(Path(filepath))
|
|
1283
1283
|
filenames = loader.lazy_load_graphs()
|
|
1284
1284
|
|
|
1285
1285
|
if len(filenames) > 0:
|
|
@@ -1331,7 +1331,7 @@ def save_spatio_temporal_graph(graph: SpatioTemporalGraph, filepath: Path | str)
|
|
|
1331
1331
|
saver = DataSaver()
|
|
1332
1332
|
saver.add_areas(graph.areas)
|
|
1333
1333
|
saver.add_graphs({'graph.json': graph})
|
|
1334
|
-
_, gen = saver.save(filepath)
|
|
1334
|
+
_, gen = saver.save(Path(filepath))
|
|
1335
1335
|
list(gen)
|
|
1336
1336
|
|
|
1337
1337
|
|
|
@@ -1714,8 +1714,10 @@ class GraphsDataset:
|
|
|
1714
1714
|
columns = [f'Factor{i+1}' for i in range(n)] + ['Subject', 'Graph']
|
|
1715
1715
|
subjects = pd.DataFrame(data, columns=columns).set_index(columns[:n+1])
|
|
1716
1716
|
|
|
1717
|
-
|
|
1718
|
-
|
|
1717
|
+
# pair matrices with graphs by name, as files are not stored in the same order
|
|
1718
|
+
matrices_by_name = {filename.removesuffix('.npy'): filename for filename in matrices_filenames}
|
|
1719
|
+
if all(name in matrices_by_name for name in filenames_without_ext):
|
|
1720
|
+
subjects['Matrix'] = [matrices_by_name[name] for name in filenames_without_ext]
|
|
1719
1721
|
|
|
1720
1722
|
return GraphsDataset(loader=loader,
|
|
1721
1723
|
areas_desc=areas_desc,
|
|
@@ -46,7 +46,7 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|
|
46
46
|
COPY . .
|
|
47
47
|
|
|
48
48
|
# 5. Setup the permissionsgp
|
|
49
|
-
RUN mkdir data_preprocessed_batch && chmod 1777 data_preprocessed_batch
|
|
49
|
+
RUN mkdir -p data_preprocessed_batch && chmod 1777 data_preprocessed_batch
|
|
50
50
|
|
|
51
51
|
## select either "t" or "st"
|
|
52
52
|
CMD ["python", "batch_process.py", "t"]
|
|
@@ -57,31 +57,32 @@ OUTPUT_FOLDER = 'results_batch'
|
|
|
57
57
|
PREPROCESSED_FOLDER = 'data_preprocessed_batch'
|
|
58
58
|
NODE_ANCHORED = True
|
|
59
59
|
|
|
60
|
-
REGION_ENCODING = {
|
|
61
|
-
'Prefrontal cortex': 1,
|
|
62
|
-
'Retrosplenial': 2,
|
|
63
|
-
'Insula': 3,
|
|
64
|
-
'Thalamus': 4,
|
|
65
|
-
'Hippocampe': 5,
|
|
66
|
-
'hippocampal formation': 6,
|
|
67
|
-
'Cortical subplate': 7,
|
|
68
|
-
'Sensory cortex': 8,
|
|
69
|
-
'Olfactory area': 9,
|
|
70
|
-
'Striatum': 10,
|
|
71
|
-
'Pallidum': 11,
|
|
72
|
-
'Hypothalamus': 12,
|
|
73
|
-
'Midbrain': 13,
|
|
74
|
-
'Unknown': 14
|
|
75
|
-
}
|
|
76
|
-
|
|
77
60
|
TEMPORAL_EDGE_ENCODING = {
|
|
78
61
|
'PP': 0, 'PO': 1, 'EQ': 2, 'DC': 3, 'PPi': 4
|
|
79
62
|
}
|
|
80
63
|
|
|
81
64
|
SPATIAL_EDGE_TYPE = 5
|
|
82
65
|
|
|
66
|
+
UNKNOWN_REGION = 'Unknown'
|
|
67
|
+
|
|
83
68
|
|
|
84
|
-
def
|
|
69
|
+
def build_region_encoding(json_files):
|
|
70
|
+
"""Build the region encoding shared by all the graphs of a run.
|
|
71
|
+
|
|
72
|
+
Codes start at 1 and follow the sorted order of the region names, so that
|
|
73
|
+
the encoding does not depend on the order of the files.
|
|
74
|
+
"""
|
|
75
|
+
regions = set()
|
|
76
|
+
for json_file in json_files:
|
|
77
|
+
with open(json_file, 'r') as f:
|
|
78
|
+
data = json.load(f)
|
|
79
|
+
for node in data['nodes']:
|
|
80
|
+
regions.add(node.get('region', UNKNOWN_REGION))
|
|
81
|
+
|
|
82
|
+
return {region: code for code, region in enumerate(sorted(regions), 1)}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def preprocess_graph_temporal(input_json, output_pkl, region_encoding):
|
|
85
86
|
with open(input_json, 'r') as f:
|
|
86
87
|
data = json.load(f)
|
|
87
88
|
|
|
@@ -89,8 +90,8 @@ def preprocess_graph_temporal(input_json, output_pkl):
|
|
|
89
90
|
|
|
90
91
|
for node in data['nodes']:
|
|
91
92
|
node_id = node['id']
|
|
92
|
-
region = node.get('region',
|
|
93
|
-
region_code =
|
|
93
|
+
region = node.get('region', UNKNOWN_REGION)
|
|
94
|
+
region_code = region_encoding[region]
|
|
94
95
|
G.add_node(node_id, node_feature=region_code)
|
|
95
96
|
|
|
96
97
|
temporal_count = 0
|
|
@@ -109,7 +110,7 @@ def preprocess_graph_temporal(input_json, output_pkl):
|
|
|
109
110
|
|
|
110
111
|
return G, temporal_count
|
|
111
112
|
|
|
112
|
-
def preprocess_graph_spatial(input_json, output_pkl):
|
|
113
|
+
def preprocess_graph_spatial(input_json, output_pkl, region_encoding):
|
|
113
114
|
with open(input_json, 'r') as f:
|
|
114
115
|
data = json.load(f)
|
|
115
116
|
|
|
@@ -121,8 +122,8 @@ def preprocess_graph_spatial(input_json, output_pkl):
|
|
|
121
122
|
for node in data['nodes']:
|
|
122
123
|
old_id = node['id']
|
|
123
124
|
new_id = id_mapping[old_id]
|
|
124
|
-
region = node.get('region',
|
|
125
|
-
region_code =
|
|
125
|
+
region = node.get('region', UNKNOWN_REGION)
|
|
126
|
+
region_code = region_encoding[region]
|
|
126
127
|
G.add_node(new_id, node_feature=region_code, original_id=old_id, region=region)
|
|
127
128
|
|
|
128
129
|
spatial_count = 0
|
|
@@ -142,7 +143,7 @@ def preprocess_graph_spatial(input_json, output_pkl):
|
|
|
142
143
|
|
|
143
144
|
return G, spatial_count
|
|
144
145
|
|
|
145
|
-
def preprocess_graph_spatiotemporal(input_json, output_pkl):
|
|
146
|
+
def preprocess_graph_spatiotemporal(input_json, output_pkl, region_encoding):
|
|
146
147
|
with open(input_json, 'r') as f:
|
|
147
148
|
data = json.load(f)
|
|
148
149
|
|
|
@@ -150,8 +151,8 @@ def preprocess_graph_spatiotemporal(input_json, output_pkl):
|
|
|
150
151
|
|
|
151
152
|
for node in data['nodes']:
|
|
152
153
|
node_id = node['id']
|
|
153
|
-
region = node.get('region',
|
|
154
|
-
region_code =
|
|
154
|
+
region = node.get('region', UNKNOWN_REGION)
|
|
155
|
+
region_code = region_encoding[region]
|
|
155
156
|
G.add_node(node_id, node_feature=region_code)
|
|
156
157
|
|
|
157
158
|
temporal_count = 0
|
|
@@ -181,17 +182,17 @@ def preprocess_graph_spatiotemporal(input_json, output_pkl):
|
|
|
181
182
|
|
|
182
183
|
return G, temporal_count, spatial_count
|
|
183
184
|
|
|
184
|
-
def preprocess_graph(input_json, output_pkl, mode):
|
|
185
|
+
def preprocess_graph(input_json, output_pkl, mode, region_encoding):
|
|
185
186
|
print(f' [1/3] Preprocessing {input_json.name} (mode: {mode})...')
|
|
186
187
|
|
|
187
188
|
if mode == 't':
|
|
188
|
-
G, edge_count = preprocess_graph_temporal(input_json, output_pkl)
|
|
189
|
+
G, edge_count = preprocess_graph_temporal(input_json, output_pkl, region_encoding)
|
|
189
190
|
print(f' Saved: {G.number_of_nodes()} nodes, {edge_count} temporal edges')
|
|
190
191
|
elif mode == 's':
|
|
191
|
-
G, edge_count = preprocess_graph_spatial(input_json, output_pkl)
|
|
192
|
+
G, edge_count = preprocess_graph_spatial(input_json, output_pkl, region_encoding)
|
|
192
193
|
print(f' Saved: {G.number_of_nodes()} nodes, {edge_count} spatial edges')
|
|
193
194
|
elif mode == 'st':
|
|
194
|
-
G, temporal_count, spatial_count = preprocess_graph_spatiotemporal(input_json, output_pkl)
|
|
195
|
+
G, temporal_count, spatial_count = preprocess_graph_spatiotemporal(input_json, output_pkl, region_encoding)
|
|
195
196
|
print(f' Saved: {G.number_of_nodes()} nodes, {temporal_count} temporal + {spatial_count} spatial edges')
|
|
196
197
|
|
|
197
198
|
return G
|
|
@@ -224,7 +225,7 @@ def run_spminer(pkl_path, json_path, output_dir, mode, node_anchored=True):
|
|
|
224
225
|
print(f'\n SPMiner completed successfully')
|
|
225
226
|
return True
|
|
226
227
|
|
|
227
|
-
def process_single_graph(json_file, relative_path, mode):
|
|
228
|
+
def process_single_graph(json_file, relative_path, mode, region_encoding):
|
|
228
229
|
print(f'\n{"="*70}')
|
|
229
230
|
print(f'Processing: {relative_path.stem} (mode: {mode})')
|
|
230
231
|
print(f'{"="*70}')
|
|
@@ -232,7 +233,7 @@ def process_single_graph(json_file, relative_path, mode):
|
|
|
232
233
|
try:
|
|
233
234
|
pkl_path = Path(PREPROCESSED_FOLDER) / relative_path.with_name(f'{relative_path.stem}_{mode}.pkl')
|
|
234
235
|
pkl_path.parent.mkdir(parents=True, exist_ok=True)
|
|
235
|
-
_ = preprocess_graph(json_file, pkl_path, mode)
|
|
236
|
+
_ = preprocess_graph(json_file, pkl_path, mode, region_encoding)
|
|
236
237
|
|
|
237
238
|
graph_output_dir = Path(OUTPUT_FOLDER) / relative_path.with_suffix('')
|
|
238
239
|
graph_output_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -305,6 +306,11 @@ def main():
|
|
|
305
306
|
print(f'\n Found {len(json_files)} JSON files:')
|
|
306
307
|
for f in json_files:
|
|
307
308
|
print(f' - {f.name}')
|
|
309
|
+
|
|
310
|
+
region_encoding = build_region_encoding(json_files)
|
|
311
|
+
print(f'\n Region encoding ({len(region_encoding)} regions):')
|
|
312
|
+
for region, code in region_encoding.items():
|
|
313
|
+
print(f' {code}: {region}')
|
|
308
314
|
|
|
309
315
|
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
|
|
310
316
|
os.makedirs(PREPROCESSED_FOLDER, exist_ok=True)
|
|
@@ -318,7 +324,7 @@ def main():
|
|
|
318
324
|
for mode in modes:
|
|
319
325
|
task_num += 1
|
|
320
326
|
print(f'\n[{task_num}/{total_tasks}] ', end='')
|
|
321
|
-
process_single_graph(json_file, relative_path, mode)
|
|
327
|
+
process_single_graph(json_file, relative_path, mode, region_encoding)
|
|
322
328
|
|
|
323
329
|
print(f'\n{"="*70}')
|
|
324
330
|
print(' ALL GRAPHS PROCESSED')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/common/feature_preprocess.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/alignment.py
RENAMED
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/config.py
RENAMED
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/hyp_search.py
RENAMED
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/test.py
RENAMED
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_matching/train.py
RENAMED
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_mining/config.py
RENAMED
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_mining/decoder.py
RENAMED
|
File without changes
|
{fstg_toolkit-1.3.0 → fstg_toolkit-1.4.0}/src/fstg_toolkit/spminer/subgraph_mining/search_agents.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|