dfc-kit 1.0.0__tar.gz → 1.0.2__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.
Files changed (194) hide show
  1. dfc_kit-1.0.2/CHANGELOG.md +75 -0
  2. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/CITATION.cff +2 -2
  3. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/MANIFEST.in +0 -3
  4. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/PKG-INFO +16 -5
  5. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/README.md +15 -4
  6. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/benchmarks/README.md +30 -0
  7. dfc_kit-1.0.2/benchmarks/profile_information.py +130 -0
  8. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/api.md +23 -4
  9. dfc_kit-1.0.2/docs/cli.md +260 -0
  10. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/correlation.md +19 -0
  11. dfc_kit-1.0.2/docs/granger.md +35 -0
  12. dfc_kit-1.0.2/docs/group_inference.md +78 -0
  13. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/index.md +3 -2
  14. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/inference.md +46 -0
  15. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/information.md +29 -3
  16. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/lowrank.md +21 -4
  17. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/method_inventory.md +2 -1
  18. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/nbs.md +37 -0
  19. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/reference.md +4 -0
  20. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/states.md +65 -1
  21. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/storage.md +62 -11
  22. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/tutorial_xcpd_to_states.md +2 -0
  23. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/mkdocs.yml +2 -0
  24. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/pyproject.toml +1 -1
  25. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfc_kit.egg-info/PKG-INFO +16 -5
  26. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfc_kit.egg-info/SOURCES.txt +16 -3
  27. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/__init__.py +1 -1
  28. dfc_kit-1.0.2/src/dfckit/_feature_selection.py +43 -0
  29. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/_numpy.py +40 -3
  30. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/models.py +31 -45
  31. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/state_alignment.py +6 -21
  32. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/state_results.py +17 -36
  33. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/state_scoring.py +0 -2
  34. dfc_kit-1.0.2/src/dfckit/cli.py +50 -0
  35. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/commands/parser.py +208 -2
  36. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/commands/reporting.py +92 -2
  37. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/commands/source.py +73 -1
  38. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/commands/states.py +44 -4
  39. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/connectivity/__init__.py +31 -2
  40. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/connectivity/correlation.py +60 -0
  41. dfc_kit-1.0.2/src/dfckit/connectivity/granger.py +243 -0
  42. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/connectivity/lowrank.py +147 -18
  43. dfc_kit-1.0.2/src/dfckit/connectivity/windows.py +253 -0
  44. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/inference/__init__.py +13 -1
  45. dfc_kit-1.0.2/src/dfckit/inference/endpoints.py +287 -0
  46. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/inference/hc3.py +41 -0
  47. dfc_kit-1.0.2/src/dfckit/inference/independent_endpoints.py +338 -0
  48. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/inference/nbs.py +69 -127
  49. dfc_kit-1.0.2/src/dfckit/inference/nbs_endpoints.py +367 -0
  50. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/inference/state_metrics.py +47 -102
  51. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/information/estimators.py +115 -102
  52. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/information/fixed.py +88 -77
  53. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/information/summary.py +4 -20
  54. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/io/xcpd.py +149 -116
  55. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/reference.py +55 -1
  56. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/cap.py +7 -19
  57. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/data.py +120 -53
  58. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/hmm.py +67 -79
  59. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/interpretation.py +5 -16
  60. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/kmeans.py +108 -26
  61. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/scoring.py +9 -11
  62. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/selection.py +41 -143
  63. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/streaming.py +70 -100
  64. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/streaming_hmm.py +17 -95
  65. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/storage/__init__.py +5 -2
  66. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/storage/builders.py +39 -58
  67. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/storage/store.py +171 -122
  68. dfc_kit-1.0.2/src/dfckit/storage/summary.py +191 -0
  69. dfc_kit-1.0.2/tests/integration/test_xcpd_lowrank.py +115 -0
  70. dfc_kit-1.0.2/tests/integration/test_xcpd_static_nbs.py +116 -0
  71. dfc_kit-1.0.2/tests/integration/test_xcpd_window_pattern.py +108 -0
  72. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_artifact_helpers.py +35 -1
  73. dfc_kit-1.0.2/tests/unit/test_cli.py +547 -0
  74. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_correlation.py +28 -1
  75. dfc_kit-1.0.2/tests/unit/test_endpoint_inference.py +260 -0
  76. dfc_kit-1.0.2/tests/unit/test_feature_selection.py +117 -0
  77. dfc_kit-1.0.2/tests/unit/test_granger.py +73 -0
  78. dfc_kit-1.0.2/tests/unit/test_granger_optional_dependency.py +49 -0
  79. dfc_kit-1.0.2/tests/unit/test_independent_endpoint_inference.py +131 -0
  80. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_inference.py +7 -0
  81. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_information.py +48 -0
  82. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_information_io.py +11 -8
  83. dfc_kit-1.0.2/tests/unit/test_information_parallel.py +274 -0
  84. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_information_summary.py +29 -5
  85. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_lowrank.py +109 -10
  86. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_model_io.py +30 -0
  87. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_nbs.py +22 -29
  88. dfc_kit-1.0.2/tests/unit/test_nbs_endpoints.py +113 -0
  89. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_outofcore.py +55 -0
  90. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_reference.py +14 -0
  91. dfc_kit-1.0.2/tests/unit/test_sliding_window.py +153 -0
  92. dfc_kit-1.0.2/tests/unit/test_state_metric_inference.py +181 -0
  93. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_state_scoring_io.py +18 -6
  94. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_state_selection.py +7 -8
  95. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_state_selection_io.py +1 -1
  96. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_states.py +76 -1
  97. dfc_kit-1.0.2/tests/unit/test_store_summary.py +355 -0
  98. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_xcpd.py +47 -0
  99. dfc_kit-1.0.0/CHANGELOG.md +0 -22
  100. dfc_kit-1.0.0/ENGINEERING_PLAN.md +0 -42
  101. dfc_kit-1.0.0/ROADMAP.md +0 -26
  102. dfc_kit-1.0.0/SECURITY.md +0 -12
  103. dfc_kit-1.0.0/docs/cli.md +0 -115
  104. dfc_kit-1.0.0/src/dfckit/cli.py +0 -105
  105. dfc_kit-1.0.0/src/dfckit/connectivity/windows.py +0 -83
  106. dfc_kit-1.0.0/src/dfckit/inference/endpoints.py +0 -194
  107. dfc_kit-1.0.0/src/dfckit/storage/summary.py +0 -140
  108. dfc_kit-1.0.0/tests/unit/test_cli.py +0 -172
  109. dfc_kit-1.0.0/tests/unit/test_endpoint_inference.py +0 -89
  110. dfc_kit-1.0.0/tests/unit/test_sliding_window.py +0 -36
  111. dfc_kit-1.0.0/tests/unit/test_state_metric_inference.py +0 -73
  112. dfc_kit-1.0.0/tests/unit/test_store_summary.py +0 -105
  113. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/CONTRIBUTING.md +0 -0
  114. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/LICENSE +0 -0
  115. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/benchmarks/profile_core.py +0 -0
  116. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/architecture.md +0 -0
  117. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/datasets.md +0 -0
  118. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/getting_started.md +0 -0
  119. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/hmm.md +0 -0
  120. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/inference_matching.md +0 -0
  121. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/instantaneous_edges.md +0 -0
  122. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/leida.md +0 -0
  123. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/model_artifacts.md +0 -0
  124. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/partition_graphs.md +0 -0
  125. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/release.md +0 -0
  126. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/state_alignment.md +0 -0
  127. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/state_scoring.md +0 -0
  128. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/state_selection.md +0 -0
  129. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/state_stability.md +0 -0
  130. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/docs/xcpd_input.md +0 -0
  131. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/setup.cfg +0 -0
  132. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfc_kit.egg-info/dependency_links.txt +0 -0
  133. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfc_kit.egg-info/entry_points.txt +0 -0
  134. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfc_kit.egg-info/requires.txt +0 -0
  135. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfc_kit.egg-info/top_level.txt +0 -0
  136. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/_arrays.py +0 -0
  137. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/_preprocessing.py +0 -0
  138. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/_validation.py +0 -0
  139. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/__init__.py +0 -0
  140. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/_fields.py +0 -0
  141. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/_json.py +0 -0
  142. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/artifacts/state_stability.py +0 -0
  143. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/commands/__init__.py +0 -0
  144. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/commands/stability.py +0 -0
  145. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/connectivity/_edge_products.py +0 -0
  146. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/connectivity/instantaneous.py +0 -0
  147. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/connectivity/leida.py +0 -0
  148. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/connectivity/partition.py +0 -0
  149. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/data.py +0 -0
  150. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/inference/matching.py +0 -0
  151. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/inference/multiple_testing.py +0 -0
  152. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/inference/paired.py +0 -0
  153. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/information/__init__.py +0 -0
  154. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/information/_artifact.py +0 -0
  155. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/io/__init__.py +0 -0
  156. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/segments.py +0 -0
  157. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/__init__.py +0 -0
  158. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/alignment.py +0 -0
  159. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/cross_validation.py +0 -0
  160. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/metrics.py +0 -0
  161. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/states/stability.py +0 -0
  162. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/src/dfckit/storage/_statistics.py +0 -0
  163. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/__init__.py +0 -0
  164. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/fixtures/audited_kernels.json +0 -0
  165. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/integration/__init__.py +0 -0
  166. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/integration/test_leida_state_pipeline.py +0 -0
  167. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/integration/test_model_artifact_pipeline.py +0 -0
  168. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/integration/test_xcpd_information.py +0 -0
  169. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/integration/test_xcpd_sliding_window.py +0 -0
  170. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/integration/test_xcpd_state_pipeline.py +0 -0
  171. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/regression/__init__.py +0 -0
  172. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/regression/test_audited_kernels.py +0 -0
  173. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/regression/test_information_reference.py +0 -0
  174. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/regression/test_nbs_independent_reference.py +0 -0
  175. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/regression/test_nbs_reference.py +0 -0
  176. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/__init__.py +0 -0
  177. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_cross_validation.py +0 -0
  178. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_data.py +0 -0
  179. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_ets.py +0 -0
  180. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_hmm.py +0 -0
  181. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_inference_matching.py +0 -0
  182. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_internal_helpers.py +0 -0
  183. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_leida.py +0 -0
  184. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_mtd.py +0 -0
  185. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_outofcore_hmm.py +0 -0
  186. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_partition_graph.py +0 -0
  187. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_preprocessing.py +0 -0
  188. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_public_api.py +0 -0
  189. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_stability.py +0 -0
  190. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_state_alignment_io.py +0 -0
  191. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_state_interpretation.py +0 -0
  192. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_state_results.py +0 -0
  193. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_state_stability_io.py +0 -0
  194. {dfc_kit-1.0.0 → dfc_kit-1.0.2}/tests/unit/test_storage.py +0 -0
@@ -0,0 +1,75 @@
1
+ # Changelog
2
+
3
+ ## 1.0.2 - 2026-09-11
4
+
5
+ - Added exact-feature selection for in-memory and disk-backed state models,
6
+ including clustering on a fixed NBS component's edges.
7
+ - Added conditional Granger predictability with censor-bounded lagged samples
8
+ and VAR diagnostics. SciPy is loaded only when those diagnostics are used,
9
+ preserving the NumPy-only base installation.
10
+ - FeatureStore summaries can now aggregate a named feature set within each
11
+ sample before computing acquisition-level mean, variance, standard deviation,
12
+ and extrema. The CLI exposes `--feature-keys` and `--feature-mean NAME` for
13
+ fixed-network summaries, including sparse NBS components.
14
+
15
+ ## 1.0.1
16
+
17
+ - Fixed-length MI/CMI now shares one process pool across acquisition, window
18
+ length, and draw combinations. Bounded task submission avoids materializing
19
+ the complete window grid, and ordered results preserve the serial samples,
20
+ jitter, pair estimates, and artifact rows. `jobs=1` remains serial.
21
+ - Reused full-window and half-window PCA fits across requested ranks, avoiding
22
+ repeated decompositions while preserving covariance endpoint definitions.
23
+ - Shared paired-test, HMM decoding, and feature-building internals; removed
24
+ redundant storage forwarders and derived-score constructor arguments.
25
+ - Added `static-fc-endpoints` to compute one whole-acquisition Fisher-z edge
26
+ vector from each XCP-D run's retained frames.
27
+ - Added `infer-paired-nbs`, a machine-readable endpoint adapter for paired NBS
28
+ with component-level FWE, explicit thresholds, tails, component statistics,
29
+ and optional participant-level nuisance variables.
30
+ - Added `lowrank-endpoints` for direct XCP-D-to-JSON summaries of effective
31
+ rank, eigenvalue concentration, held-out reconstruction, and split/adjacent
32
+ subspace similarity.
33
+ - Added segment-weighted all-pair FC-pattern and low-rank subspace similarity,
34
+ together with adjacency excess, so configuration homogeneity can be separated
35
+ from order-specific similarity.
36
+ - Added `window-pattern-endpoints` for direct XCP-D-to-JSON summaries of
37
+ all-pair, adjacent, and adjacency-excess whole-edge pattern similarity.
38
+ - Added deterministic pass-level early stopping to out-of-core MiniBatchKMeans.
39
+ - Reported the selected initialization's completed passes and all initialization
40
+ pass counts without changing the fitted-model artifact format.
41
+ - Clarified that streaming `max_iter` is a maximum number of complete store
42
+ passes; `convergence_tol=0` retains fixed-pass fitting.
43
+ - Added an explicit equal-run mean for paired inference with repeated
44
+ acquisitions. Runs remain separate through feature and state summarization,
45
+ and JSON/TSV results report the acquisition-count range in each condition.
46
+ - Paired named-endpoint inference can now select an explicit endpoint subset,
47
+ allowing one source artifact to be tested as several scientifically declared
48
+ FDR families without changing each endpoint's permutation or bootstrap draw.
49
+ - Added `infer-independent-endpoints` for two independent named-endpoint
50
+ cohorts, with optional numeric covariates, HC3 group effects, Hedges' g,
51
+ full and group-incremental R2, and declared-family FDR.
52
+ - XCP-D discovery now enters session directories linked into an otherwise
53
+ ordinary BIDS subject hierarchy without recursively following arbitrary
54
+ directory symlinks.
55
+
56
+ ## 1.0.0 - 2026-08-24
57
+
58
+ - Moved MI/CMI estimators and fixed-window orchestration into
59
+ `dfckit.information`.
60
+ - Unified random sampling and frozen schedules through one fixed-window
61
+ estimation path.
62
+ - Simplified state-count selection to subject-disjoint held-out score
63
+ comparison with compact JSON output.
64
+ - Removed cryptographic data/model identities, workflow-directory loaders,
65
+ nested checkpointing, and legacy compatibility layers from the development
66
+ codebase.
67
+ - Kept model, prediction, alignment, and information artifacts pickle-free and
68
+ validated by explicit shapes, parameters, feature keys, and participant
69
+ metadata.
70
+ - ETS and MTD share the same segment-safe instantaneous-edge framework while
71
+ retaining their distinct sample generators.
72
+ - Paired NBS, HC3 inference, information estimates, and all censor-gap-safe
73
+ connectivity methods retain their numerical APIs.
74
+ - FeatureStore summaries support streaming acquisition-level mean, population
75
+ variance, standard deviation, minimum, and maximum endpoints.
@@ -4,6 +4,6 @@ title: "dfc-kit: Censor-aware dynamic functional connectivity tools"
4
4
  type: software
5
5
  authors:
6
6
  - name: "dfc-kit contributors"
7
- version: 1.0.0
8
- date-released: 2026-08-24
7
+ version: 1.0.2
8
+ date-released: 2026-09-11
9
9
  license: BSD-3-Clause
@@ -1,11 +1,8 @@
1
1
  include CHANGELOG.md
2
2
  include CITATION.cff
3
3
  include CONTRIBUTING.md
4
- include ENGINEERING_PLAN.md
5
4
  include LICENSE
6
5
  include README.md
7
- include ROADMAP.md
8
- include SECURITY.md
9
6
  include mkdocs.yml
10
7
  recursive-include benchmarks *.md *.py
11
8
  recursive-include docs *.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dfc-kit
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: Censor-aware tools for dynamic functional connectivity analysis
5
5
  License-Expression: BSD-3-Clause
6
6
  Project-URL: Homepage, https://github.com/yidao9518/dfc-kit
@@ -73,14 +73,15 @@ for larger datasets, with matching Python and command-line interfaces.
73
73
  loading, acquisition identity, and censor-bounded sequences. Censored time
74
74
  points retain their original frame indices, and temporal operations are
75
75
  evaluated separately within contiguous retained segments.
76
- - **Connectivity:** weighted sliding-window FC, instantaneous ETS/MTD edges,
77
- LEiDA, low-rank covariance geometry, and fixed-length MI/CMI.
76
+ - **Connectivity:** whole-acquisition and weighted sliding-window FC,
77
+ whole-edge all-pair and order-specific pattern similarity, instantaneous
78
+ ETS/MTD edges, LEiDA, low-rank covariance geometry, and fixed-length MI/CMI.
78
79
  - **Connectivity and state analysis:** partition-based graph metrics, CAP, KMeans,
79
80
  Gaussian HMMs, state alignment, occupancy/dwell/transition summaries, and
80
81
  selection of the number of states using held-out participants.
81
82
  - **Inference:** paired sign-flips, bootstrap intervals, HC3 models,
82
- declared-family FDR, generic paired endpoint inference, paired NBS, and
83
- within-subject motion matching.
83
+ declared-family FDR, generic paired endpoint inference, independent-group
84
+ endpoint models, paired NBS, and within-subject motion matching.
84
85
  - **Large-dataset workflows:** chunked, memory-mapped FeatureStores and
85
86
  batch-wise fitting for MiniBatch KMeans and Incremental PCA.
86
87
  - **Portable results:** models and held-out predictions stored as JSON and
@@ -152,16 +153,26 @@ dfc-kit --help
152
153
  dfc-kit inspect-xcpd --help
153
154
  dfc-kit build-store --help
154
155
  dfc-kit fixed-information --help
156
+ dfc-kit lowrank-endpoints --help
157
+ dfc-kit window-pattern-endpoints --help
158
+ dfc-kit static-fc-endpoints --help
155
159
  dfc-kit describe-states --help
156
160
  dfc-kit infer-state-metrics --help
157
161
  dfc-kit summarize-store --help
158
162
  dfc-kit summarize-information --help
159
163
  dfc-kit infer-paired-endpoints --help
164
+ dfc-kit infer-independent-endpoints --help
165
+ dfc-kit infer-paired-nbs --help
160
166
  ```
161
167
 
162
168
  See [Command-line workflows](docs/cli.md) for complete examples and arguments,
163
169
  including fixed-length MI/CMI artifacts and frozen-window replay.
164
170
 
171
+ For two independent endpoint cohorts, `infer-independent-endpoints` fits the
172
+ declared group contrast with HC3 standard errors, optional numeric covariates,
173
+ and family-level Benjamini-Hochberg correction. See [Independent group
174
+ inference](docs/group_inference.md).
175
+
165
176
  ## Documentation
166
177
 
167
178
  - [Documentation home](docs/index.md)
@@ -28,14 +28,15 @@ for larger datasets, with matching Python and command-line interfaces.
28
28
  loading, acquisition identity, and censor-bounded sequences. Censored time
29
29
  points retain their original frame indices, and temporal operations are
30
30
  evaluated separately within contiguous retained segments.
31
- - **Connectivity:** weighted sliding-window FC, instantaneous ETS/MTD edges,
32
- LEiDA, low-rank covariance geometry, and fixed-length MI/CMI.
31
+ - **Connectivity:** whole-acquisition and weighted sliding-window FC,
32
+ whole-edge all-pair and order-specific pattern similarity, instantaneous
33
+ ETS/MTD edges, LEiDA, low-rank covariance geometry, and fixed-length MI/CMI.
33
34
  - **Connectivity and state analysis:** partition-based graph metrics, CAP, KMeans,
34
35
  Gaussian HMMs, state alignment, occupancy/dwell/transition summaries, and
35
36
  selection of the number of states using held-out participants.
36
37
  - **Inference:** paired sign-flips, bootstrap intervals, HC3 models,
37
- declared-family FDR, generic paired endpoint inference, paired NBS, and
38
- within-subject motion matching.
38
+ declared-family FDR, generic paired endpoint inference, independent-group
39
+ endpoint models, paired NBS, and within-subject motion matching.
39
40
  - **Large-dataset workflows:** chunked, memory-mapped FeatureStores and
40
41
  batch-wise fitting for MiniBatch KMeans and Incremental PCA.
41
42
  - **Portable results:** models and held-out predictions stored as JSON and
@@ -107,16 +108,26 @@ dfc-kit --help
107
108
  dfc-kit inspect-xcpd --help
108
109
  dfc-kit build-store --help
109
110
  dfc-kit fixed-information --help
111
+ dfc-kit lowrank-endpoints --help
112
+ dfc-kit window-pattern-endpoints --help
113
+ dfc-kit static-fc-endpoints --help
110
114
  dfc-kit describe-states --help
111
115
  dfc-kit infer-state-metrics --help
112
116
  dfc-kit summarize-store --help
113
117
  dfc-kit summarize-information --help
114
118
  dfc-kit infer-paired-endpoints --help
119
+ dfc-kit infer-independent-endpoints --help
120
+ dfc-kit infer-paired-nbs --help
115
121
  ```
116
122
 
117
123
  See [Command-line workflows](docs/cli.md) for complete examples and arguments,
118
124
  including fixed-length MI/CMI artifacts and frozen-window replay.
119
125
 
126
+ For two independent endpoint cohorts, `infer-independent-endpoints` fits the
127
+ declared group contrast with HC3 standard errors, optional numeric covariates,
128
+ and family-level Benjamini-Hochberg correction. See [Independent group
129
+ inference](docs/group_inference.md).
130
+
120
131
  ## Documentation
121
132
 
122
133
  - [Documentation home](docs/index.md)
@@ -1,5 +1,35 @@
1
1
  # Synthetic performance benchmarks
2
2
 
3
+ ## Fixed-length MI/CMI
4
+
5
+ ```bash
6
+ OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 PYTHONPATH=src \
7
+ python benchmarks/profile_information.py --jobs 1 2 4 8 --runs 8 --draws 25
8
+ ```
9
+
10
+ This benchmark generates 36 synthetic ROI time series with a censor gap and
11
+ estimates all 12-by-4 MI/CMI pairs at five window lengths. It reports end-to-end
12
+ time, including process startup and array transfer, and requires exact agreement
13
+ with serial output for every numeric array and metadata field. Worker count is
14
+ an execution setting, so changing it must not change the scientific result.
15
+ For short batches, process startup can outweigh the gain from parallel work.
16
+
17
+ Cloud reference run on 2026-09-05 (Python 3.10.14, NumPy 1.26.4,
18
+ SciPy 1.13.0, 8 runs, 25 draws per length, 1,000 total windows):
19
+
20
+ | Processes | Elapsed time | Speedup over serial | Exact output match |
21
+ |---:|---:|---:|---|
22
+ | 1 | 184.122 s | 1.00 | Yes |
23
+ | 4 | 47.186 s | 3.90 | Yes |
24
+ | 16 | 12.207 s | 15.08 | Yes |
25
+ | 40 | 5.230 s | 35.20 | Yes |
26
+
27
+ These timings include worker startup. All arrays and metadata matched the serial
28
+ reference; the speedup describes this synthetic workload, not a guaranteed rate
29
+ for arbitrary ROI counts, sample lengths, or machine allocations.
30
+
31
+ ## Feature and state methods
32
+
3
33
  Run each method in a separate process so `ru_maxrss` has one clear scope:
4
34
 
5
35
  ```bash
@@ -0,0 +1,130 @@
1
+ """Compare serial and parallel MI/CMI on synthetic ROI36-sized input.
2
+
3
+ Run from the project root, for example::
4
+
5
+ python benchmarks/profile_information.py --jobs 1 2 4 8
6
+
7
+ The timings include process startup and data transfer. Every parallel result is
8
+ checked against a serial reference, including window indices and all pair values.
9
+ This script never loads participant data or writes analysis artifacts.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import argparse
15
+ import dataclasses
16
+ import json
17
+ import platform
18
+ import time
19
+
20
+ import numpy as np
21
+
22
+ from dfckit import TimeSeriesDataset, TimeSeriesRun, __version__
23
+ from dfckit.information import (
24
+ FixedInformationArtifact,
25
+ InformationGroups,
26
+ compute_fixed_information,
27
+ knn_cmi,
28
+ )
29
+
30
+
31
+ def synthetic_dataset(runs: int, frames: int, seed: int) -> TimeSeriesDataset:
32
+ rng = np.random.default_rng(seed)
33
+ roi_names = tuple(f"roi-{index:02d}" for index in range(36))
34
+ acquisitions = []
35
+ for index in range(runs):
36
+ values = rng.normal(size=(frames, 36))
37
+ values[:, 12:16] += 0.4 * values[:, :4]
38
+ split = frames // 2
39
+ original_indices = np.r_[np.arange(split), np.arange(split + 5, frames + 5)]
40
+ acquisitions.append(
41
+ TimeSeriesRun(
42
+ values=values,
43
+ original_indices=original_indices,
44
+ roi_names=roi_names,
45
+ subject=f"synthetic-{index:03d}",
46
+ session="benchmark",
47
+ acquisition_id=f"synthetic-{index:03d}_benchmark",
48
+ )
49
+ )
50
+ return TimeSeriesDataset(tuple(acquisitions))
51
+
52
+
53
+ def assert_exact(actual: FixedInformationArtifact, expected: FixedInformationArtifact) -> None:
54
+ for field in dataclasses.fields(expected):
55
+ value = getattr(expected, field.name)
56
+ if isinstance(value, np.ndarray):
57
+ np.testing.assert_array_equal(getattr(actual, field.name), value, err_msg=field.name)
58
+ else:
59
+ if getattr(actual, field.name) != value:
60
+ raise AssertionError(f"artifact metadata differs: {field.name}")
61
+
62
+
63
+ def main() -> None:
64
+ parser = argparse.ArgumentParser(description=__doc__)
65
+ parser.add_argument("--jobs", type=int, nargs="+", default=[1, 2, 4, 8])
66
+ parser.add_argument("--runs", type=int, default=4)
67
+ parser.add_argument("--frames", type=int, default=800)
68
+ parser.add_argument("--lengths", type=int, nargs="+", default=[120, 180, 240, 300, 360])
69
+ parser.add_argument("--draws", type=int, default=5)
70
+ parser.add_argument("--seed", type=int, default=20260905)
71
+ args = parser.parse_args()
72
+ if min(args.jobs) < 1 or args.runs < 1 or args.frames < 12 or args.draws < 1:
73
+ parser.error("jobs, runs, and draws must be positive; frames must be at least 12")
74
+ if not args.lengths or min(args.lengths) <= 5 or max(args.lengths) > args.frames // 2:
75
+ parser.error("every length must be between 6 and the retained half-run length")
76
+
77
+ dataset = synthetic_dataset(args.runs, args.frames, args.seed)
78
+ names = dataset.roi_names
79
+ groups = InformationGroups(names[:12], names[12:16], names[16:26])
80
+ # Import SciPy before timing the reference, while retaining process startup
81
+ # and child imports in the end-to-end parallel timings.
82
+ knn_cmi(*(dataset.runs[0].values[:16, index] for index in range(3)))
83
+ job_counts = tuple(dict.fromkeys((1, *args.jobs)))
84
+ reference = None
85
+ reference_seconds = None
86
+ timings = []
87
+ for jobs in job_counts:
88
+ start = time.perf_counter()
89
+ result = compute_fixed_information(
90
+ dataset,
91
+ groups,
92
+ lengths=args.lengths,
93
+ draws=args.draws,
94
+ sample_seed=args.seed,
95
+ jobs=jobs,
96
+ )
97
+ elapsed = time.perf_counter() - start
98
+ if reference is None:
99
+ reference = result
100
+ reference_seconds = elapsed
101
+ assert_exact(result, reference)
102
+ timings.append(
103
+ {
104
+ "jobs": jobs,
105
+ "elapsed_seconds": elapsed,
106
+ "speedup_over_serial": reference_seconds / elapsed,
107
+ "all_arrays_and_metadata_exact": True,
108
+ "analyzed_windows": result.n_draws,
109
+ }
110
+ )
111
+ print(json.dumps(timings[-1]), flush=True)
112
+ print(
113
+ json.dumps(
114
+ {
115
+ "dfc_kit_version": __version__,
116
+ "python_version": platform.python_version(),
117
+ "input": vars(args),
118
+ "left_rois": 12,
119
+ "right_rois": 4,
120
+ "conditioning_rois": 10,
121
+ "timing_includes_process_startup": True,
122
+ "timings": timings,
123
+ },
124
+ indent=2,
125
+ )
126
+ )
127
+
128
+
129
+ if __name__ == "__main__":
130
+ main()
@@ -24,8 +24,13 @@ from dfckit.connectivity import (
24
24
  LEiDA,
25
25
  FixedPartitionGraph,
26
26
  LowRankCovariance,
27
+ adjacent_window_pattern_similarity,
28
+ all_pair_window_pattern_similarity,
29
+ edge_vector_to_symmetric_matrix,
27
30
  partition_edge_summary,
28
31
  SlidingWindowFC,
32
+ summarize_window_pattern_dataset,
33
+ window_pattern_adjacency_excess,
29
34
  )
30
35
  ```
31
36
 
@@ -46,6 +51,7 @@ from dfckit.information import (
46
51
 
47
52
  ```python
48
53
  from dfckit.storage import FeatureStore
54
+ from dfckit.storage import summarize_static_fc_dataset
49
55
 
50
56
  store = FeatureStore.create(
51
57
  "results/window-fc.store",
@@ -54,10 +60,17 @@ store = FeatureStore.create(
54
60
  sample_interval_seconds=result.sample_interval_seconds,
55
61
  )
56
62
  store.append_dataset(dataset)
63
+
64
+ # Select exact edges without duplicating the disk-backed store.
65
+ selected = store.select_features(
66
+ feature_keys=(("V1_L", "PUT-DP_L"), ("V1_R", "PUT-DP_R"))
67
+ )
57
68
  ```
58
69
 
59
70
  FeatureStore chunks are memory-mappable and retain sequence/acquisition
60
- boundaries. They are an execution format, not a provenance database.
71
+ boundaries. A selected feature view preserves those boundaries and is accepted
72
+ by the store-based state fitters. FeatureStore objects are an execution format,
73
+ not a provenance database.
61
74
 
62
75
  ## State models
63
76
 
@@ -107,12 +120,18 @@ directories or nested artifact loaders.
107
120
  ## Inference
108
121
 
109
122
  ```python
110
- from dfckit.inference import ols_hc3, paired_hc3, paired_nbs, paired_sign_flip
123
+ from dfckit.inference import (
124
+ hc3_confidence_interval,
125
+ ols_hc3,
126
+ paired_hc3,
127
+ paired_nbs,
128
+ paired_sign_flip,
129
+ )
111
130
  ```
112
131
 
113
132
  Inference modules provide paired sign flips, bootstrap intervals, HC3 models,
114
- declared-family FDR, and paired NBS. These are independent of state-count
115
- selection and model persistence.
133
+ declared-family FDR, independent named-endpoint group models, and paired NBS.
134
+ These are independent of state-count selection and model persistence.
116
135
 
117
136
  ## Advanced interfaces
118
137