scitex 2.11.0__py3-none-any.whl → 2.13.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.
Files changed (148) hide show
  1. scitex/__main__.py +24 -5
  2. scitex/__version__.py +1 -1
  3. scitex/_optional_deps.py +33 -0
  4. scitex/ai/classification/reporters/_ClassificationReporter.py +1 -1
  5. scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +2 -2
  6. scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +2 -2
  7. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +2 -2
  8. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +2 -2
  9. scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +2 -2
  10. scitex/ai/classification/timeseries/_normalize_timestamp.py +1 -1
  11. scitex/ai/metrics/_calc_seizure_prediction_metrics.py +1 -1
  12. scitex/ai/plt/_plot_feature_importance.py +1 -1
  13. scitex/ai/plt/_plot_learning_curve.py +1 -1
  14. scitex/ai/plt/_plot_optuna_study.py +1 -1
  15. scitex/ai/plt/_plot_pre_rec_curve.py +1 -1
  16. scitex/ai/plt/_plot_roc_curve.py +1 -1
  17. scitex/ai/plt/_stx_conf_mat.py +1 -1
  18. scitex/ai/training/_LearningCurveLogger.py +1 -1
  19. scitex/audio/mcp_server.py +38 -8
  20. scitex/browser/automation/CookieHandler.py +1 -1
  21. scitex/browser/core/BrowserMixin.py +1 -1
  22. scitex/browser/core/ChromeProfileManager.py +1 -1
  23. scitex/browser/debugging/_browser_logger.py +1 -1
  24. scitex/browser/debugging/_highlight_element.py +1 -1
  25. scitex/browser/debugging/_show_grid.py +1 -1
  26. scitex/browser/interaction/click_center.py +1 -1
  27. scitex/browser/interaction/click_with_fallbacks.py +1 -1
  28. scitex/browser/interaction/close_popups.py +1 -1
  29. scitex/browser/interaction/fill_with_fallbacks.py +1 -1
  30. scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +1 -1
  31. scitex/browser/pdf/detect_chrome_pdf_viewer.py +1 -1
  32. scitex/browser/stealth/HumanBehavior.py +1 -1
  33. scitex/browser/stealth/StealthManager.py +1 -1
  34. scitex/canvas/_mcp_handlers.py +372 -0
  35. scitex/canvas/_mcp_tool_schemas.py +219 -0
  36. scitex/canvas/mcp_server.py +151 -0
  37. scitex/capture/mcp_server.py +41 -12
  38. scitex/cli/audio.py +233 -0
  39. scitex/cli/capture.py +307 -0
  40. scitex/cli/main.py +27 -4
  41. scitex/cli/repro.py +233 -0
  42. scitex/cli/resource.py +240 -0
  43. scitex/cli/stats.py +325 -0
  44. scitex/cli/template.py +236 -0
  45. scitex/cli/tex.py +286 -0
  46. scitex/cli/web.py +11 -12
  47. scitex/dev/__init__.py +3 -0
  48. scitex/dev/_pyproject.py +405 -0
  49. scitex/dev/plt/__init__.py +2 -2
  50. scitex/dev/plt/mpl/get_dir_ax.py +1 -1
  51. scitex/dev/plt/mpl/get_signatures.py +1 -1
  52. scitex/dev/plt/mpl/get_signatures_details.py +1 -1
  53. scitex/diagram/_mcp_handlers.py +400 -0
  54. scitex/diagram/_mcp_tool_schemas.py +157 -0
  55. scitex/diagram/mcp_server.py +151 -0
  56. scitex/dsp/_demo_sig.py +51 -5
  57. scitex/dsp/_mne.py +13 -2
  58. scitex/dsp/_modulation_index.py +15 -3
  59. scitex/dsp/_pac.py +23 -5
  60. scitex/dsp/_psd.py +16 -4
  61. scitex/dsp/_resample.py +24 -4
  62. scitex/dsp/_transform.py +16 -3
  63. scitex/dsp/add_noise.py +15 -1
  64. scitex/dsp/norm.py +17 -2
  65. scitex/dsp/reference.py +17 -1
  66. scitex/dsp/utils/_differential_bandpass_filters.py +20 -2
  67. scitex/dsp/utils/_zero_pad.py +18 -4
  68. scitex/dt/_normalize_timestamp.py +1 -1
  69. scitex/git/_session.py +1 -1
  70. scitex/io/_load_modules/_con.py +12 -1
  71. scitex/io/_load_modules/_eeg.py +12 -1
  72. scitex/io/_load_modules/_optuna.py +21 -63
  73. scitex/io/_load_modules/_torch.py +11 -3
  74. scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +13 -2
  75. scitex/io/_save_modules/_torch.py +11 -3
  76. scitex/mcp_server.py +159 -0
  77. scitex/plt/_mcp_handlers.py +361 -0
  78. scitex/plt/_mcp_tool_schemas.py +169 -0
  79. scitex/plt/mcp_server.py +205 -0
  80. scitex/repro/README_RandomStateManager.md +3 -3
  81. scitex/repro/_RandomStateManager.py +14 -14
  82. scitex/repro/_gen_ID.py +1 -1
  83. scitex/repro/_gen_timestamp.py +1 -1
  84. scitex/repro/_hash_array.py +4 -4
  85. scitex/scholar/__main__.py +24 -2
  86. scitex/scholar/_mcp_handlers.py +685 -0
  87. scitex/scholar/_mcp_tool_schemas.py +339 -0
  88. scitex/scholar/docs/template.py +1 -1
  89. scitex/scholar/examples/07_storage_integration.py +1 -1
  90. scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +1 -1
  91. scitex/scholar/impact_factor/jcr/build_database.py +1 -1
  92. scitex/scholar/mcp_server.py +315 -0
  93. scitex/scholar/pdf_download/ScholarPDFDownloader.py +1 -1
  94. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +1 -1
  95. scitex/scholar/pipelines/ScholarPipelineParallel.py +1 -1
  96. scitex/scholar/pipelines/ScholarPipelineSingle.py +1 -1
  97. scitex/scholar/storage/PaperIO.py +1 -1
  98. scitex/session/README.md +4 -4
  99. scitex/session/__init__.py +1 -1
  100. scitex/session/_decorator.py +9 -9
  101. scitex/session/_lifecycle.py +5 -5
  102. scitex/session/template.py +1 -1
  103. scitex/stats/__main__.py +281 -0
  104. scitex/stats/_mcp_handlers.py +1191 -0
  105. scitex/stats/_mcp_tool_schemas.py +384 -0
  106. scitex/stats/correct/_correct_bonferroni.py +1 -1
  107. scitex/stats/correct/_correct_fdr.py +1 -1
  108. scitex/stats/correct/_correct_fdr_.py +1 -1
  109. scitex/stats/correct/_correct_holm.py +1 -1
  110. scitex/stats/correct/_correct_sidak.py +1 -1
  111. scitex/stats/effect_sizes/_cliffs_delta.py +1 -1
  112. scitex/stats/effect_sizes/_cohens_d.py +1 -1
  113. scitex/stats/effect_sizes/_epsilon_squared.py +1 -1
  114. scitex/stats/effect_sizes/_eta_squared.py +1 -1
  115. scitex/stats/effect_sizes/_prob_superiority.py +1 -1
  116. scitex/stats/mcp_server.py +405 -0
  117. scitex/stats/posthoc/_dunnett.py +1 -1
  118. scitex/stats/posthoc/_games_howell.py +1 -1
  119. scitex/stats/posthoc/_tukey_hsd.py +1 -1
  120. scitex/stats/power/_power.py +1 -1
  121. scitex/stats/utils/_effect_size.py +1 -1
  122. scitex/stats/utils/_formatters.py +1 -1
  123. scitex/stats/utils/_power.py +1 -1
  124. scitex/template/_mcp_handlers.py +259 -0
  125. scitex/template/_mcp_tool_schemas.py +112 -0
  126. scitex/template/mcp_server.py +186 -0
  127. scitex/utils/_verify_scitex_format.py +2 -2
  128. scitex/utils/template.py +1 -1
  129. scitex/web/__init__.py +12 -11
  130. scitex/web/_scraping.py +26 -265
  131. scitex/web/download_images.py +316 -0
  132. scitex/writer/Writer.py +1 -1
  133. scitex/writer/_clone_writer_project.py +1 -1
  134. scitex/writer/_validate_tree_structures.py +1 -1
  135. scitex/writer/dataclasses/config/_WriterConfig.py +1 -1
  136. scitex/writer/dataclasses/contents/_ManuscriptContents.py +1 -1
  137. scitex/writer/dataclasses/core/_Document.py +1 -1
  138. scitex/writer/dataclasses/core/_DocumentSection.py +1 -1
  139. scitex/writer/dataclasses/results/_CompilationResult.py +1 -1
  140. scitex/writer/dataclasses/results/_LaTeXIssue.py +1 -1
  141. scitex/writer/utils/.legacy_git_retry.py +7 -5
  142. scitex/writer/utils/_parse_latex_logs.py +1 -1
  143. {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/METADATA +431 -269
  144. {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/RECORD +147 -118
  145. scitex-2.13.0.dist-info/entry_points.txt +11 -0
  146. scitex-2.11.0.dist-info/entry_points.txt +0 -2
  147. {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/WHEEL +0 -0
  148. {scitex-2.11.0.dist-info → scitex-2.13.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,10 +1,17 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  # Time-stamp: "2024-11-14 07:55:45 (ywatanabe)"
4
3
  # File: ./scitex_repo/src/scitex/io/_load_modules/_optuna.py
5
4
 
6
5
  from ._yaml import _load_yaml
7
6
 
7
+ try:
8
+ import optuna
9
+
10
+ OPTUNA_AVAILABLE = True
11
+ except ImportError:
12
+ OPTUNA_AVAILABLE = False
13
+ optuna = None
14
+
8
15
 
9
16
  def load_yaml_as_an_optuna_dict(fpath_yaml, trial):
10
17
  """
@@ -31,7 +38,14 @@ def load_yaml_as_an_optuna_dict(fpath_yaml, trial):
31
38
  If the specified YAML file does not exist.
32
39
  ValueError
33
40
  If the YAML file contains invalid configuration for Optuna.
41
+ ImportError
42
+ If Optuna is not installed.
34
43
  """
44
+ if not OPTUNA_AVAILABLE:
45
+ raise ImportError(
46
+ "Optuna is not installed. Please install with: pip install optuna"
47
+ )
48
+
35
49
  _d = _load_yaml(fpath_yaml)
36
50
 
37
51
  for k, v in _d.items():
@@ -74,6 +88,8 @@ def load_study_rdb(study_name, rdb_raw_bytes_url):
74
88
  -------
75
89
  optuna.exceptions.StorageInvalidUsageError
76
90
  If there's an error loading the study from the storage.
91
+ ImportError
92
+ If Optuna is not installed.
77
93
 
78
94
  Example:
79
95
  --------
@@ -82,7 +98,10 @@ def load_study_rdb(study_name, rdb_raw_bytes_url):
82
98
  ... rdb_raw_bytes_url="sqlite:///path/to/your/study.db"
83
99
  ... )
84
100
  """
85
- import optuna
101
+ if not OPTUNA_AVAILABLE:
102
+ raise ImportError(
103
+ "Optuna is not installed. Please install with: pip install optuna"
104
+ )
86
105
 
87
106
  storage = optuna.storages.RDBStorage(url=rdb_raw_bytes_url)
88
107
  study = optuna.load_study(study_name=study_name, storage=storage)
@@ -90,65 +109,4 @@ def load_study_rdb(study_name, rdb_raw_bytes_url):
90
109
  return study
91
110
 
92
111
 
93
- def load_yaml_as_an_optuna_dict(fpath_yaml, trial):
94
- """
95
- Load a YAML file and convert it to an Optuna-compatible dictionary.
96
-
97
- Parameters:
98
- -----------
99
- fpath_yaml : str
100
- The path to the YAML file.
101
- trial : optuna.trial.Trial
102
- The Optuna trial object.
103
-
104
- Returns:
105
- --------
106
- dict
107
- A dictionary with Optuna-compatible parameter suggestions.
108
- """
109
- _d = _load_yaml(fpath_yaml)
110
-
111
- for k, v in _d.items():
112
- dist = v["distribution"]
113
-
114
- if dist == "categorical":
115
- _d[k] = trial.suggest_categorical(k, v["values"])
116
-
117
- elif dist == "uniform":
118
- _d[k] = trial.suggest_int(k, float(v["min"]), float(v["max"]))
119
-
120
- elif dist == "loguniform":
121
- _d[k] = trial.suggest_loguniform(k, float(v["min"]), float(v["max"]))
122
-
123
- elif dist == "intloguniform":
124
- _d[k] = trial.suggest_int(k, float(v["min"]), float(v["max"]), log=True)
125
-
126
- return _d
127
-
128
-
129
- def load_study_rdb(study_name, rdb_raw_bytes_url):
130
- """
131
- Load an Optuna study from a RDB storage.
132
-
133
- Parameters:
134
- -----------
135
- study_name : str
136
- The name of the Optuna study.
137
- rdb_raw_bytes_url : str
138
- The URL of the RDB storage.
139
-
140
- Returns:
141
- --------
142
- optuna.study.Study
143
- The loaded Optuna study object.
144
- """
145
- import optuna
146
-
147
- # rdb_raw_bytes_url = "sqlite:////tmp/fake/ywatanabe/_MicroNN_WindowSize-1.0-sec_MaxEpochs_100_2021-1216-1844/optuna_study_test_file#0.db"
148
- storage = optuna.storages.RDBStorage(url=rdb_raw_bytes_url)
149
- study = optuna.load_study(study_name=study_name, storage=storage)
150
- print(f"\nLoaded: {rdb_raw_bytes_url}\n")
151
- return study
152
-
153
-
154
112
  # EOF
@@ -1,13 +1,21 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  # Time-stamp: "2024-11-14 07:41:34 (ywatanabe)"
4
3
  # File: ./scitex_repo/src/scitex/io/_load_modules/_torch.py
5
4
 
5
+ try:
6
+ import torch
7
+
8
+ TORCH_AVAILABLE = True
9
+ except ImportError:
10
+ TORCH_AVAILABLE = False
11
+
6
12
 
7
13
  def _load_torch(lpath, **kwargs):
8
14
  """Load PyTorch model/checkpoint file."""
9
- # Lazy import to avoid circular import issues
10
- import torch
15
+ if not TORCH_AVAILABLE:
16
+ raise ImportError(
17
+ "PyTorch is not installed. Please install with: pip install torch"
18
+ )
11
19
 
12
20
  if not lpath.endswith((".pth", ".pt")):
13
21
  raise ValueError("File must have .pth or .pt extension")
@@ -1,11 +1,22 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  # Time-stamp: "2024-11-02 17:01:15 (ywatanabe)"
4
3
  # File: ./scitex_repo/src/scitex/io/_save_optuna_study_as_csv_and_pngs.py
5
4
 
5
+ try:
6
+ import optuna
7
+
8
+ OPTUNA_AVAILABLE = True
9
+ except ImportError:
10
+ OPTUNA_AVAILABLE = False
11
+ optuna = None
12
+
6
13
 
7
14
  def save_optuna_study_as_csv_and_pngs(study, sdir):
8
- import optuna
15
+ if not OPTUNA_AVAILABLE:
16
+ raise ImportError(
17
+ "Optuna is not installed. Please install with: pip install optuna"
18
+ )
19
+
9
20
  from .._save import save
10
21
 
11
22
  ## Trials DataFrame
@@ -1,8 +1,14 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  # Timestamp: "2025-05-16 12:25:14 (ywatanabe)"
4
3
  # File: /data/gpfs/projects/punim2354/ywatanabe/scitex_repo/src/scitex/io/_save_modules/_torch.py
5
4
 
5
+ try:
6
+ import torch
7
+
8
+ TORCH_AVAILABLE = True
9
+ except ImportError:
10
+ TORCH_AVAILABLE = False
11
+
6
12
 
7
13
  def _save_torch(obj, spath, **kwargs):
8
14
  """
@@ -21,7 +27,9 @@ def _save_torch(obj, spath, **kwargs):
21
27
  -------
22
28
  None
23
29
  """
24
- # Lazy import to avoid circular import issues
25
- import torch
30
+ if not TORCH_AVAILABLE:
31
+ raise ImportError(
32
+ "PyTorch is not installed. Please install with: pip install torch"
33
+ )
26
34
 
27
35
  torch.save(obj, spath, **kwargs)
scitex/mcp_server.py ADDED
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-08
3
+ # File: src/scitex/mcp_server.py
4
+ # ----------------------------------------
5
+
6
+ """
7
+ Unified MCP Server for SciTeX - All modules in one server.
8
+
9
+ Aggregates tools from all SciTeX MCP modules with prefixed names:
10
+ - audio_*: Text-to-speech
11
+ - capture_*: Screenshot capture
12
+ - scholar_*: Literature management
13
+ - stats_*: Statistical analysis
14
+ - template_*: Project scaffolding
15
+ - plt_*: Publication plotting
16
+ - canvas_*: Multi-panel figures
17
+ - diagram_*: Diagram generation
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import asyncio
23
+ import json
24
+ from typing import Callable
25
+
26
+ import mcp.types as types
27
+ from mcp.server import NotificationOptions, Server
28
+ from mcp.server.models import InitializationOptions
29
+ from mcp.server.stdio import stdio_server
30
+
31
+ __all__ = ["UnifiedServer", "main"]
32
+
33
+ # Module registry: (prefix, schema_getter, handler_module)
34
+ MODULES = [
35
+ ("audio", "scitex.audio._mcp_tool_schemas", "scitex.audio._mcp_handlers"),
36
+ ("capture", "scitex.capture._mcp_tool_schemas", "scitex.capture._mcp_handlers"),
37
+ ("scholar", "scitex.scholar._mcp_tool_schemas", "scitex.scholar._mcp_handlers"),
38
+ ("stats", "scitex.stats._mcp_tool_schemas", "scitex.stats._mcp_handlers"),
39
+ ("template", "scitex.template._mcp_tool_schemas", "scitex.template._mcp_handlers"),
40
+ ("plt", "scitex.plt._mcp_tool_schemas", "scitex.plt._mcp_handlers"),
41
+ ("canvas", "scitex.canvas._mcp_tool_schemas", "scitex.canvas._mcp_handlers"),
42
+ ("diagram", "scitex.diagram._mcp_tool_schemas", "scitex.diagram._mcp_handlers"),
43
+ ]
44
+
45
+
46
+ class UnifiedServer:
47
+ """Unified MCP Server aggregating all SciTeX modules."""
48
+
49
+ def __init__(self):
50
+ self.server = Server("scitex-mcp-server")
51
+ self.tools: list[types.Tool] = []
52
+ self.handlers: dict[str, Callable] = {}
53
+ self._load_modules()
54
+ self._setup_handlers()
55
+
56
+ def _load_modules(self):
57
+ """Load tool schemas and handlers from all modules."""
58
+ import importlib
59
+
60
+ for prefix, schema_module, handler_module in MODULES:
61
+ try:
62
+ # Load tool schemas
63
+ schema_mod = importlib.import_module(schema_module)
64
+ tools = schema_mod.get_tool_schemas()
65
+
66
+ # Load handlers
67
+ handler_mod = importlib.import_module(handler_module)
68
+
69
+ for tool in tools:
70
+ # Create prefixed tool name
71
+ prefixed_name = f"{prefix}_{tool.name}"
72
+
73
+ # Create new tool with prefixed name
74
+ prefixed_tool = types.Tool(
75
+ name=prefixed_name,
76
+ description=f"[{prefix}] {tool.description}",
77
+ inputSchema=tool.inputSchema,
78
+ )
79
+ self.tools.append(prefixed_tool)
80
+
81
+ # Map handler
82
+ handler_name = f"{tool.name}_handler"
83
+ if hasattr(handler_mod, handler_name):
84
+ self.handlers[prefixed_name] = getattr(
85
+ handler_mod, handler_name
86
+ )
87
+
88
+ except ImportError as e:
89
+ # Module not available, skip it
90
+ print(f"Skipping {prefix} module: {e}")
91
+ except Exception as e:
92
+ print(f"Error loading {prefix} module: {e}")
93
+
94
+ def _setup_handlers(self):
95
+ """Set up MCP server handlers."""
96
+
97
+ @self.server.list_tools()
98
+ async def handle_list_tools():
99
+ return self.tools
100
+
101
+ @self.server.call_tool()
102
+ async def handle_call_tool(name: str, arguments: dict):
103
+ if name not in self.handlers:
104
+ return [
105
+ types.TextContent(
106
+ type="text",
107
+ text=json.dumps(
108
+ {"success": False, "error": f"Unknown tool: {name}"},
109
+ indent=2,
110
+ ),
111
+ )
112
+ ]
113
+
114
+ return await self._wrap_result(self.handlers[name](**arguments))
115
+
116
+ async def _wrap_result(self, coro):
117
+ """Wrap handler result as MCP TextContent."""
118
+ try:
119
+ result = await coro
120
+ return [
121
+ types.TextContent(
122
+ type="text",
123
+ text=json.dumps(result, indent=2, default=str),
124
+ )
125
+ ]
126
+ except Exception as e:
127
+ return [
128
+ types.TextContent(
129
+ type="text",
130
+ text=json.dumps({"success": False, "error": str(e)}, indent=2),
131
+ )
132
+ ]
133
+
134
+
135
+ async def main():
136
+ """Run the unified MCP server."""
137
+ server = UnifiedServer()
138
+ print(f"Loaded {len(server.tools)} tools from {len(MODULES)} modules")
139
+
140
+ async with stdio_server() as (read_stream, write_stream):
141
+ await server.server.run(
142
+ read_stream,
143
+ write_stream,
144
+ InitializationOptions(
145
+ server_name="scitex-mcp-server",
146
+ server_version="0.1.0",
147
+ capabilities=server.server.get_capabilities(
148
+ notification_options=NotificationOptions(),
149
+ experimental_capabilities={},
150
+ ),
151
+ ),
152
+ )
153
+
154
+
155
+ if __name__ == "__main__":
156
+ asyncio.run(main())
157
+
158
+
159
+ # EOF