scitex 2.4.2__py3-none-any.whl → 2.5.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 (64) hide show
  1. scitex/__version__.py +1 -1
  2. scitex/browser/__init__.py +53 -0
  3. scitex/browser/debugging/__init__.py +56 -0
  4. scitex/browser/debugging/_failure_capture.py +372 -0
  5. scitex/browser/debugging/_sync_session.py +259 -0
  6. scitex/browser/debugging/_test_monitor.py +284 -0
  7. scitex/browser/debugging/_visual_cursor.py +432 -0
  8. scitex/io/_load.py +5 -0
  9. scitex/io/_load_modules/_canvas.py +171 -0
  10. scitex/io/_save.py +8 -0
  11. scitex/io/_save_modules/_canvas.py +356 -0
  12. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +77 -22
  13. scitex/plt/docs/FIGURE_ARCHITECTURE.md +257 -0
  14. scitex/plt/utils/__init__.py +10 -0
  15. scitex/plt/utils/_collect_figure_metadata.py +14 -12
  16. scitex/plt/utils/_csv_column_naming.py +237 -0
  17. scitex/scholar/citation_graph/database.py +9 -2
  18. scitex/scholar/config/ScholarConfig.py +23 -3
  19. scitex/scholar/config/default.yaml +55 -0
  20. scitex/scholar/core/Paper.py +102 -0
  21. scitex/scholar/core/__init__.py +44 -0
  22. scitex/scholar/core/journal_normalizer.py +524 -0
  23. scitex/scholar/core/oa_cache.py +285 -0
  24. scitex/scholar/core/open_access.py +457 -0
  25. scitex/scholar/pdf_download/ScholarPDFDownloader.py +137 -0
  26. scitex/scholar/pdf_download/strategies/__init__.py +6 -0
  27. scitex/scholar/pdf_download/strategies/open_access_download.py +186 -0
  28. scitex/scholar/pipelines/ScholarPipelineSearchParallel.py +18 -3
  29. scitex/scholar/pipelines/ScholarPipelineSearchSingle.py +15 -2
  30. scitex/session/_decorator.py +13 -1
  31. scitex/vis/README.md +246 -615
  32. scitex/vis/__init__.py +138 -78
  33. scitex/vis/canvas.py +423 -0
  34. scitex/vis/docs/CANVAS_ARCHITECTURE.md +307 -0
  35. scitex/vis/editor/__init__.py +1 -1
  36. scitex/vis/editor/_dearpygui_editor.py +1830 -0
  37. scitex/vis/editor/_defaults.py +40 -1
  38. scitex/vis/editor/_edit.py +54 -18
  39. scitex/vis/editor/_flask_editor.py +37 -0
  40. scitex/vis/editor/_qt_editor.py +865 -0
  41. scitex/vis/editor/flask_editor/__init__.py +21 -0
  42. scitex/vis/editor/flask_editor/bbox.py +216 -0
  43. scitex/vis/editor/flask_editor/core.py +152 -0
  44. scitex/vis/editor/flask_editor/plotter.py +130 -0
  45. scitex/vis/editor/flask_editor/renderer.py +184 -0
  46. scitex/vis/editor/flask_editor/templates/__init__.py +33 -0
  47. scitex/vis/editor/flask_editor/templates/html.py +295 -0
  48. scitex/vis/editor/flask_editor/templates/scripts.py +614 -0
  49. scitex/vis/editor/flask_editor/templates/styles.py +549 -0
  50. scitex/vis/editor/flask_editor/utils.py +81 -0
  51. scitex/vis/io/__init__.py +84 -21
  52. scitex/vis/io/canvas.py +226 -0
  53. scitex/vis/io/data.py +204 -0
  54. scitex/vis/io/directory.py +202 -0
  55. scitex/vis/io/export.py +460 -0
  56. scitex/vis/io/panel.py +424 -0
  57. {scitex-2.4.2.dist-info → scitex-2.5.0.dist-info}/METADATA +9 -2
  58. {scitex-2.4.2.dist-info → scitex-2.5.0.dist-info}/RECORD +61 -32
  59. scitex/vis/DJANGO_INTEGRATION.md +0 -677
  60. scitex/vis/editor/_web_editor.py +0 -1440
  61. scitex/vis/tmp.txt +0 -239
  62. {scitex-2.4.2.dist-info → scitex-2.5.0.dist-info}/WHEEL +0 -0
  63. {scitex-2.4.2.dist-info → scitex-2.5.0.dist-info}/entry_points.txt +0 -0
  64. {scitex-2.4.2.dist-info → scitex-2.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,307 @@
1
+ <!-- ---
2
+ !-- Timestamp: 2025-12-08 16:05:39
3
+ !-- Author: ywatanabe
4
+ !-- File: /home/ywatanabe/proj/scitex-code/src/scitex/vis/docs/CANVAS_ARCHITECTURE.md
5
+ !-- --- -->
6
+
7
+ # Canvas Architecture for scitex.vis
8
+
9
+ ## Terminology
10
+
11
+ | Term | Meaning | Example |
12
+ |------------|---------------------------------------------|-----------------------------|
13
+ | **Canvas** | A paper figure workspace managed by `/vis/` | "Figure 1" in a publication |
14
+ | **Panel** | A single component placed on canvas | Panel A, B, C... |
15
+ | **Figure** | Reserved for matplotlib's `fig` object | `stx.plt` output |
16
+
17
+ ## Directory Structure
18
+
19
+ Canvas directories use `.canvas` extension and are standalone (no nested structure required):
20
+
21
+ ```
22
+ project/
23
+ ├── fig1_neural_results.canvas/ # Standalone .canvas directory
24
+ │ ├── canvas.json # Layout, panels, composition settings
25
+ │ ├── canvas.png # Composed output (auto-generated)
26
+ │ ├── canvas.pdf
27
+ │ ├── canvas.svg
28
+ │ └── panels/
29
+ │ ├── panel_a/ # type: scitex (symlinks by default)
30
+ │ │ ├── panel.json -> ../../plots/plot.json
31
+ │ │ ├── panel.csv -> ../../plots/plot.csv
32
+ │ │ └── panel.png -> ../../plots/plot.png
33
+ │ └── panel_b/ # type: image
34
+ │ └── panel.png -> ../../images/diagram.png
35
+ ├── fig2_supplementary.canvas/ # Another standalone canvas
36
+ │ └── ...
37
+ └── plots/ # Source files (symlink targets)
38
+ ├── plot.png
39
+ ├── plot.json
40
+ └── plot.csv
41
+ ```
42
+
43
+ Panel files use symlinks by default (`bundle=False`). Use `bundle=True` to copy files for portable archives.
44
+
45
+ The `.canvas` extension:
46
+ - Makes directories self-documenting (clearly a canvas bundle)
47
+ - Enables portability (can be moved/copied as a unit)
48
+ - Is detectable by `scitex.io` for automated handling
49
+
50
+ ## Panel Types
51
+
52
+ | Type | Contents | Editable | Re-renderable |
53
+ |----------|------------------|-------------------------|---------------|
54
+ | `scitex` | JSON + CSV + PNG | Full (data, style) | Yes |
55
+ | `image` | PNG/JPG/SVG only | Position/size/transform | No |
56
+
57
+ ## canvas.json Schema
58
+
59
+ ```json
60
+ {
61
+ "schema_version": "2.0.0",
62
+ "canvas_name": "fig1_neural_results",
63
+
64
+ "size": {
65
+ "width_mm": 180,
66
+ "height_mm": 240
67
+ },
68
+
69
+ "background": {
70
+ "color": "#ffffff",
71
+ "grid": false
72
+ },
73
+
74
+ "panels": [
75
+ {
76
+ "name": "panel_a",
77
+ "type": "scitex",
78
+ "position": {"x_mm": 10, "y_mm": 10},
79
+ "size": {"width_mm": 70, "height_mm": 50},
80
+ "z_index": 0,
81
+ "rotation_deg": 0,
82
+ "clip": {
83
+ "enabled": false,
84
+ "x_mm": 0,
85
+ "y_mm": 0,
86
+ "width_mm": null,
87
+ "height_mm": null
88
+ },
89
+ "opacity": 1.0,
90
+ "flip_h": false,
91
+ "flip_v": false,
92
+ "visible": true,
93
+ "label": {
94
+ "text": "A",
95
+ "position": "top-left",
96
+ "fontsize": 12,
97
+ "fontweight": "bold"
98
+ },
99
+ "border": {
100
+ "visible": false,
101
+ "color": "#000000",
102
+ "width_mm": 0.2
103
+ }
104
+ },
105
+ {
106
+ "name": "panel_b",
107
+ "type": "image",
108
+ "source": "panel.png",
109
+ "position": {"x_mm": 100, "y_mm": 10},
110
+ "size": {"width_mm": 70, "height_mm": 50},
111
+ "z_index": 1,
112
+ "rotation_deg": 0,
113
+ "clip": {"enabled": false},
114
+ "opacity": 1.0,
115
+ "flip_h": false,
116
+ "flip_v": false,
117
+ "visible": true,
118
+ "label": {"text": "B", "position": "top-left"}
119
+ }
120
+ ],
121
+
122
+ "annotations": [
123
+ {
124
+ "type": "text",
125
+ "content": "p < 0.05",
126
+ "position": {"x_mm": 50, "y_mm": 60},
127
+ "fontsize": 8
128
+ },
129
+ {
130
+ "type": "arrow",
131
+ "start": {"x_mm": 30, "y_mm": 70},
132
+ "end": {"x_mm": 50, "y_mm": 55}
133
+ },
134
+ {
135
+ "type": "bracket",
136
+ "start": {"x_mm": 10, "y_mm": 80},
137
+ "end": {"x_mm": 80, "y_mm": 80}
138
+ }
139
+ ],
140
+
141
+ "title": {
142
+ "text": "",
143
+ "position": {"x_mm": 90, "y_mm": 5},
144
+ "fontsize": 14
145
+ },
146
+
147
+ "data_files": [
148
+ {
149
+ "path": "panels/panel_a/panel.csv",
150
+ "hash": "sha256:abc123..."
151
+ }
152
+ ],
153
+
154
+ "metadata": {
155
+ "created_at": "2025-12-08T12:00:00Z",
156
+ "updated_at": "2025-12-08T15:30:00Z",
157
+ "author": "user",
158
+ "description": "Neural activity results for Figure 1"
159
+ },
160
+
161
+ "manual_overrides": {}
162
+ }
163
+ ```
164
+
165
+ ## Panel Properties
166
+
167
+ ### Transform Properties
168
+
169
+ | Property | Type | Default | Purpose |
170
+ |----------------|-----------------------|----------|------------------------------------|
171
+ | `position` | {x_mm, y_mm} | required | Position on canvas |
172
+ | `size` | {width_mm, height_mm} | required | Panel dimensions |
173
+ | `z_index` | int | 0 | Stacking order (higher = on top) |
174
+ | `rotation_deg` | float | 0 | Rotation around center (clockwise) |
175
+ | `opacity` | float | 1.0 | Transparency (0.0 - 1.0) |
176
+ | `flip_h` | bool | false | Horizontal flip |
177
+ | `flip_v` | bool | false | Vertical flip |
178
+ | `visible` | bool | true | Show/hide panel |
179
+
180
+ ### Clip Properties
181
+
182
+ | Property | Type | Default | Purpose |
183
+ |------------------|-------|---------|----------------------------------|
184
+ | `clip.enabled` | bool | false | Enable cropping |
185
+ | `clip.x_mm` | float | 0 | Crop start X (from panel origin) |
186
+ | `clip.y_mm` | float | 0 | Crop start Y |
187
+ | `clip.width_mm` | float | null | Crop width (null = to edge) |
188
+ | `clip.height_mm` | float | null | Crop height (null = to edge) |
189
+
190
+ ### Label Properties
191
+
192
+ | Property | Type | Default | Purpose |
193
+ |--------------------|--------|------------|----------------------------|
194
+ | `label.text` | string | "" | Label text (A, B, C...) |
195
+ | `label.position` | string | "top-left" | Position relative to panel |
196
+ | `label.fontsize` | int | 12 | Font size in points |
197
+ | `label.fontweight` | string | "bold" | Font weight |
198
+
199
+ ### Border Properties
200
+
201
+ | Property | Type | Default | Purpose |
202
+ |-------------------|--------|-----------|------------------|
203
+ | `border.visible` | bool | false | Show border |
204
+ | `border.color` | string | "#000000" | Border color |
205
+ | `border.width_mm` | float | 0.2 | Border thickness |
206
+
207
+ ## Annotation Types
208
+
209
+ | Type | Properties | Purpose |
210
+ |-------------|------------------------------------|------------------|
211
+ | `text` | content, position, fontsize, color | Text overlay |
212
+ | `arrow` | start, end, color, width | Arrow annotation |
213
+ | `bracket` | start, end, color, width | Bracket/brace |
214
+ | `line` | start, end, color, width, style | Line annotation |
215
+ | `rectangle` | position, size, color, fill | Rectangle shape |
216
+
217
+ ## Core API (scitex.vis)
218
+
219
+ ### Primary API (minimal, reusable, flexible)
220
+
221
+ ```python
222
+ # Canvas operations
223
+ stx.vis.create_canvas(parent_dir, canvas_name) -> Path
224
+ stx.vis.get_canvas_path(parent_dir, canvas_name) -> Path
225
+ stx.vis.canvas_exists(parent_dir, canvas_name) -> bool
226
+ stx.vis.list_canvases(parent_dir) -> List[str]
227
+ stx.vis.delete_canvas(parent_dir, canvas_name) -> bool
228
+
229
+ # Panel operations (symlinks by default, bundle=True for copies)
230
+ stx.vis.add_panel(parent_dir, canvas_name, panel_name, source,
231
+ position=(x, y), size=(w, h), label="A",
232
+ bundle=False, **kwargs) -> Path
233
+ stx.vis.update_panel(parent_dir, canvas_name, panel_name, updates) -> Dict
234
+ stx.vis.remove_panel(parent_dir, canvas_name, panel_name) -> bool
235
+ stx.vis.list_panels(parent_dir, canvas_name) -> List[Dict]
236
+
237
+ # Export (auto-called by stx.io.save)
238
+ stx.vis.export_canvas(parent_dir, canvas_name, output_format="png") -> Path
239
+
240
+ # Data integrity
241
+ stx.vis.verify_data(parent_dir, canvas_name) -> Dict[str, bool]
242
+
243
+ # Editor
244
+ stx.vis.edit(json_path)
245
+ ```
246
+
247
+ ### Advanced API (via submodules)
248
+
249
+ ```python
250
+ # stx.vis.io - Low-level I/O operations
251
+ # stx.vis.model - Data models (FigureModel, AxesModel, etc.)
252
+ # stx.vis.backend - JSON → matplotlib rendering
253
+ # stx.vis.utils - Templates and validation
254
+ ```
255
+
256
+ ## Django Integration (scitex-cloud)
257
+
258
+ Django views are thin wrappers:
259
+
260
+ ```python
261
+ # apps/vis_app/views.py
262
+ import scitex as stx
263
+
264
+ def list_canvases(request, project_id):
265
+ project_path = get_project_path(project_id)
266
+ canvases = stx.vis.io.list_canvas_directories(project_path)
267
+ return JsonResponse({"canvases": canvases})
268
+
269
+ def get_canvas(request, project_id, canvas_name):
270
+ project_path = get_project_path(project_id)
271
+ canvas_json = stx.vis.io.load_canvas_json(project_path, canvas_name)
272
+ return JsonResponse(canvas_json)
273
+ ```
274
+
275
+ ## Integration with stx.io
276
+
277
+ Canvas directories are first-class citizens in the scitex I/O system:
278
+
279
+ ```python
280
+ import scitex as stx
281
+
282
+ # Save canvas to a portable directory
283
+ stx.io.save(canvas_dict, "/path/to/fig1_results.canvas")
284
+
285
+ # Load canvas from directory
286
+ canvas = stx.io.load("/path/to/fig1_results.canvas")
287
+ # Returns dict with canvas.json content + '_canvas_dir' reference
288
+
289
+ # Load canvas with panel images in memory
290
+ canvas = stx.io.load("/path/to/fig1_results.canvas", load_panels=True)
291
+ # Each panel dict now has '_image' key with numpy array
292
+ ```
293
+
294
+ ## Summary
295
+
296
+ | Aspect | Decision |
297
+ |------------------|------------------------------------------------------------|
298
+ | Directory path | `{parent_dir}/{canvas_name}.canvas/` |
299
+ | Directory ext | `.canvas` extension for portability and distinguishability |
300
+ | Naming | Descriptive names (e.g., `fig1_neural_results`) |
301
+ | Panel types | `scitex` (full) or `image` (static) |
302
+ | Data integrity | SHA256 hash verification |
303
+ | Export structure | Flat (`exports/canvas.png`, `exports/canvas.pdf`) |
304
+ | Manual overrides | Stored in `canvas.json` under `manual_overrides` key |
305
+ | I/O integration | `stx.io.save/load` supports `.canvas` directories |
306
+
307
+ <!-- EOF -->
@@ -6,7 +6,7 @@ SciTeX Visual Editor Module
6
6
 
7
7
  Provides interactive GUI for editing figure styles and annotations.
8
8
  Supports multiple backends with graceful degradation:
9
- - web: Browser-based (Flask/FastAPI) - modern UI
9
+ - flask: Browser-based (Flask) - modern UI
10
10
  - dearpygui: GPU-accelerated desktop (fast)
11
11
  - qt: Rich desktop (PyQt/PySide)
12
12
  - tkinter: Built-in Python (works everywhere)