spinal-tap 0.1.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.
@@ -0,0 +1 @@
1
+ recursive-include spinal_tap/assets *
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.4
2
+ Name: spinal-tap
3
+ Version: 0.1.0
4
+ Summary: A project that depends on spine-ml >=0.7.1
5
+ Author-email: DeepLearnPhysics Collaboration <drielsma@stanford.edu>
6
+ Maintainer-email: Francois Drielsma <drielsma@stanford.edu>
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: spine-ml[viz]>=0.7.1
10
+ Requires-Dist: dash>=3.0.0
11
+ Requires-Dist: flask>=2.0.0
12
+ Requires-Dist: anywidget
13
+ Provides-Extra: dev
14
+ Requires-Dist: black; extra == "dev"
15
+ Requires-Dist: isort; extra == "dev"
16
+ Requires-Dist: flake8; extra == "dev"
17
+
18
+ # Spinal Tap
19
+
20
+ Spinal Tap is a Dash application that provides simple visualization tools for
21
+ the Scalable Particle Imaging With Neural Embeddings
22
+ ([SPINE](https://github.com/DeepLearnPhysics/spine)) package.
23
+
24
+
25
+ ## Installation
26
+
27
+ You can install Spinal Tap and all dependencies (including Dash, Flask, Plotly, and spine-ml) using pip:
28
+
29
+ ```bash
30
+ pip install .
31
+ ```
32
+
33
+ Or, for editable development mode:
34
+
35
+ ```bash
36
+ pip install -e .
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ After installation, launch the app using the provided CLI:
42
+
43
+ ```bash
44
+ spinal-tap
45
+ ```
46
+
47
+ You can also check the installed version with:
48
+
49
+ ```bash
50
+ spinal-tap --version
51
+ # or
52
+ spinal-tap -v
53
+ ```
54
+
55
+ Then open your browser to [http://0.0.0.0:8888/](http://0.0.0.0:8888/).
56
+
57
+
58
+ ## Development & CI/CD
59
+
60
+ - Code style is enforced with black, isort, and flake8 (pre-commit and CI).
61
+ - The GitHub Actions workflow builds and tests on every commit, PR, tag, and release.
62
+ - Publishing:
63
+ - On tag push: publishes to Test PyPI (requires `TEST_PYPI_API_TOKEN` secret).
64
+ - On GitHub Release: publishes to PyPI (requires `PYPI_API_TOKEN` secret).
65
+
66
+
67
+ ## Roadmap
68
+
69
+ In the near future, the application will be hosted at
70
+ [https://k8s.slac.stanford.edu/spinal-tap](https://k8s.slac.stanford.edu/spinal-tap)
@@ -0,0 +1,53 @@
1
+ # Spinal Tap
2
+
3
+ Spinal Tap is a Dash application that provides simple visualization tools for
4
+ the Scalable Particle Imaging With Neural Embeddings
5
+ ([SPINE](https://github.com/DeepLearnPhysics/spine)) package.
6
+
7
+
8
+ ## Installation
9
+
10
+ You can install Spinal Tap and all dependencies (including Dash, Flask, Plotly, and spine-ml) using pip:
11
+
12
+ ```bash
13
+ pip install .
14
+ ```
15
+
16
+ Or, for editable development mode:
17
+
18
+ ```bash
19
+ pip install -e .
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ After installation, launch the app using the provided CLI:
25
+
26
+ ```bash
27
+ spinal-tap
28
+ ```
29
+
30
+ You can also check the installed version with:
31
+
32
+ ```bash
33
+ spinal-tap --version
34
+ # or
35
+ spinal-tap -v
36
+ ```
37
+
38
+ Then open your browser to [http://0.0.0.0:8888/](http://0.0.0.0:8888/).
39
+
40
+
41
+ ## Development & CI/CD
42
+
43
+ - Code style is enforced with black, isort, and flake8 (pre-commit and CI).
44
+ - The GitHub Actions workflow builds and tests on every commit, PR, tag, and release.
45
+ - Publishing:
46
+ - On tag push: publishes to Test PyPI (requires `TEST_PYPI_API_TOKEN` secret).
47
+ - On GitHub Release: publishes to PyPI (requires `PYPI_API_TOKEN` secret).
48
+
49
+
50
+ ## Roadmap
51
+
52
+ In the near future, the application will be hosted at
53
+ [https://k8s.slac.stanford.edu/spinal-tap](https://k8s.slac.stanford.edu/spinal-tap)
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "spinal-tap"
7
+ version = "0.1.0"
8
+ description = "A project that depends on spine-ml >=0.7.1"
9
+ readme = "README.md"
10
+ authors = [
11
+ {name = "DeepLearnPhysics Collaboration", email = "drielsma@stanford.edu"}
12
+ ]
13
+ maintainers = [
14
+ {name = "Francois Drielsma", email = "drielsma@stanford.edu"}
15
+ ]
16
+ dependencies = [
17
+ "spine-ml[viz]>=0.7.1",
18
+ "dash>=3.0.0",
19
+ "flask>=2.0.0",
20
+ "anywidget"
21
+ ]
22
+ requires-python = ">=3.8"
23
+
24
+ [project.scripts]
25
+ spinal-tap = "spinal_tap.app:main"
26
+
27
+ [project.optional-dependencies]
28
+ dev = [
29
+ "black",
30
+ "isort",
31
+ "flake8"
32
+ ]
33
+
34
+ [tool.setuptools.packages.find]
35
+ where = ["src"]
36
+
37
+ [tool.setuptools.package-data]
38
+ spinal_tap = ["assets/*"]
39
+
40
+ [tool.isort]
41
+ profile = "black"
42
+ line_length = 88
43
+
44
+ [tool.black]
45
+ line-length = 88
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ """Spinal Tap module, the SPINE event display."""
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env python3
2
+ """Spinal tap (reconstruction visualization GUI)."""
3
+
4
+ import argparse
5
+
6
+ from dash import Dash
7
+
8
+ from .callbacks import register_callbacks
9
+ from .layout import layout
10
+ from .version import __version__
11
+
12
+
13
+ def main():
14
+
15
+ # Parse command line arguments
16
+ parser = argparse.ArgumentParser()
17
+
18
+ parser.add_argument(
19
+ "--version",
20
+ "-v",
21
+ action="store_true",
22
+ help="Show the Spinal Tap version and exit.",
23
+ )
24
+
25
+ parser.add_argument(
26
+ "--port",
27
+ type=int,
28
+ default=8888,
29
+ help="Sets the Flask server port number (default: 8888)",
30
+ )
31
+
32
+ parser.add_argument(
33
+ "--host",
34
+ type=str,
35
+ default="0.0.0.0",
36
+ help="Sets the Flask server host address (default: 0.0.0.0)",
37
+ )
38
+
39
+ args = parser.parse_args()
40
+
41
+ if args.version:
42
+ print(f"Spinal Tap version {__version__}")
43
+ return
44
+
45
+ # Initialize the application
46
+ app = Dash(__name__, title="Spinal Tap")
47
+
48
+ # Set the application layout
49
+ app.layout = layout
50
+
51
+ # Register the callbacks
52
+ register_callbacks(app)
53
+
54
+ # Execute the dash app
55
+ app.run(host=args.host, port=args.port, debug=True)
56
+
57
+
58
+ if __name__ == "__main__":
59
+ main()
@@ -0,0 +1,431 @@
1
+ /* Table of contents
2
+ ––––––––––––––––––––––––––––––––––––––––––––––––––
3
+ - Banner
4
+ - Grid
5
+ - Base Styles
6
+ - Typography
7
+ - Links
8
+ - Buttons
9
+ - Forms
10
+ - Lists
11
+ - Code
12
+ - Tables
13
+ - Spacing
14
+ - Utilities
15
+ - Clearing
16
+ - Media Queries
17
+ */
18
+
19
+
20
+
21
+ /* Banner
22
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
23
+ .banner {
24
+ height: 75px;
25
+ background-color: #72A0C1;
26
+ border-radius: 5px 5px 2px 2px;
27
+ box-shadow: rgb(240, 240, 240) 5px 5px 5px 0px;
28
+ padding-top: 0px;
29
+ padding-left: 0px;
30
+ padding-right: 0px;
31
+ width: 98%;
32
+ margin-left: 1%;
33
+ margin-right: 1%;
34
+ margin-top: 1%;
35
+ }
36
+
37
+ .banner h2{
38
+ color: black;
39
+ margin-left: 1.5%;
40
+ display: inline-block;
41
+ font-family: 'Outfit', sans-serif;
42
+ font-size: 4rem;
43
+ line-height: 1;
44
+ }
45
+
46
+ .banner Img{
47
+ position: relative;
48
+ float: right;
49
+ right: 1.5%;
50
+ height: 75px;
51
+ }
52
+
53
+
54
+ /* Grid
55
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
56
+ .container {
57
+ position: relative;
58
+ background-color: white;
59
+ border-radius: 2px 2px 5px 5px;
60
+ font-size: 1.5rem;
61
+ box-shadow: rgb(240, 240, 240) 5px 5px 5px 0px;
62
+ border: thin solid rgb(240, 240, 240);
63
+ margin-left: 1%;
64
+ margin-right: 1%;
65
+ color: #302F54;
66
+ padding: 8px;
67
+ width: 98%;
68
+ height: 90%;
69
+ max-width: none;
70
+ box-sizing: border-box;
71
+ }
72
+
73
+ .column,
74
+ .columns {
75
+ width: 100%;
76
+ float: left;
77
+ box-sizing: border-box; }
78
+
79
+
80
+ /* For devices larger than 550px */
81
+ @media (min-width: 550px) {
82
+ .column,
83
+ .columns {
84
+ margin-left: 0.5%; }
85
+ .column:first-child,
86
+ .columns:first-child {
87
+ margin-left: 0; }
88
+
89
+ .one.column,
90
+ .one.columns { width: 8%; }
91
+ .two.columns { width: 16.25%; }
92
+ .three.columns { width: 24.5%; }
93
+ .four.columns { width: 33%; }
94
+ .five.columns { width: 39.3333333333%; }
95
+ .six.columns { width: 49.75%; }
96
+ .seven.columns { width: 56.6666666667%; }
97
+ .eight.columns { width: 66.5%; }
98
+ .nine.columns { width: 75%; }
99
+ .ten.columns { width: 82.6666666667%; }
100
+ .eleven.columns { width: 91.5%; }
101
+ .twelve.columns { width: 100%; margin-left: 0; }
102
+
103
+ .one-third.column { width: 30.6666666667%; }
104
+ .two-thirds.column { width: 65.3333333333%; }
105
+
106
+ .one-half.column { width: 48%; }
107
+
108
+ /* Offsets */
109
+ .offset-by-one.column,
110
+ .offset-by-one.columns { margin-left: 8.66666666667%; }
111
+ .offset-by-two.column,
112
+ .offset-by-two.columns { margin-left: 17.3333333333%; }
113
+ .offset-by-three.column,
114
+ .offset-by-three.columns { margin-left: 26%; }
115
+ .offset-by-four.column,
116
+ .offset-by-four.columns { margin-left: 34.6666666667%; }
117
+ .offset-by-five.column,
118
+ .offset-by-five.columns { margin-left: 43.3333333333%; }
119
+ .offset-by-six.column,
120
+ .offset-by-six.columns { margin-left: 52%; }
121
+ .offset-by-seven.column,
122
+ .offset-by-seven.columns { margin-left: 60.6666666667%; }
123
+ .offset-by-eight.column,
124
+ .offset-by-eight.columns { margin-left: 69.3333333333%; }
125
+ .offset-by-nine.column,
126
+ .offset-by-nine.columns { margin-left: 78.0%; }
127
+ .offset-by-ten.column,
128
+ .offset-by-ten.columns { margin-left: 86.6666666667%; }
129
+ .offset-by-eleven.column,
130
+ .offset-by-eleven.columns { margin-left: 95.3333333333%; }
131
+
132
+ .offset-by-one-third.column,
133
+ .offset-by-one-third.columns { margin-left: 34.6666666667%; }
134
+ .offset-by-two-thirds.column,
135
+ .offset-by-two-thirds.columns { margin-left: 69.3333333333%; }
136
+
137
+ .offset-by-one-half.column,
138
+ .offset-by-one-half.columns { margin-left: 52%; }
139
+
140
+ }
141
+
142
+
143
+ /* Base Styles
144
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
145
+ /* NOTE
146
+ html is set to 62.5% so that all the REM measurements throughout Skeleton
147
+ are based on 10px sizing. So basically 1.5rem = 15px :) */
148
+ html {
149
+ font-size: 62.5%; }
150
+ body {
151
+ font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
152
+ line-height: 1.6;
153
+ font-weight: 400;
154
+ font-family: 'Outfit', sans-serif;
155
+ color: #222; }
156
+
157
+
158
+ /* Typography
159
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
160
+ h1, h2, h3, h4, h5, h6 {
161
+ margin-top: 0;
162
+ margin-bottom: 0;
163
+ font-weight: 700; }
164
+ h1 { font-size: 4.5rem; line-height: 1.2; letter-spacing: -.1rem; margin-bottom: 2rem; }
165
+ h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; margin-bottom: 1.8rem; margin-top: 1.8rem;}
166
+ h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; margin-bottom: 1.5rem; margin-top: 1.5rem;}
167
+ h4 { font-size: 2.6rem; line-height: 1.35; letter-spacing: -.08rem; margin-bottom: 1.2rem; margin-top: 1.2rem;}
168
+ h5 { font-size: 2.2rem; line-height: 1.5; letter-spacing: -.05rem; margin-bottom: 0.6rem; margin-top: 0.6rem;}
169
+ h6 { font-size: 2.0rem; line-height: 1.6; letter-spacing: 0; margin-bottom: 0.75rem; margin-top: 0.75rem;}
170
+
171
+ p {
172
+ margin-top: 0; }
173
+
174
+
175
+ /* Blockquotes
176
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
177
+ blockquote {
178
+ border-left: 4px lightgrey solid;
179
+ padding-left: 1rem;
180
+ margin-top: 2rem;
181
+ margin-bottom: 2rem;
182
+ margin-left: 0rem;
183
+ }
184
+
185
+
186
+ /* Links
187
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
188
+ a {
189
+ color: #1EAEDB; }
190
+ a:hover {
191
+ color: #0FA0CE; }
192
+
193
+
194
+ /* Buttons
195
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
196
+ .button,
197
+ button,
198
+ input[type="submit"],
199
+ input[type="reset"],
200
+ input[type="button"] {
201
+ display: inline-block;
202
+ height: 38px;
203
+ padding: 0 0;
204
+ color: #555;
205
+ text-align: center;
206
+ font-size: 11px;
207
+ font-weight: 600;
208
+ line-height: 38px;
209
+ letter-spacing: .1rem;
210
+ text-transform: uppercase;
211
+ text-decoration: none;
212
+ white-space: nowrap;
213
+ background-color: #E1EBEE;
214
+ border-radius: 4px;
215
+ border: 1px solid #bbb;
216
+ cursor: pointer;
217
+ box-sizing: border-box; }
218
+ .button:hover,
219
+ button:hover,
220
+ input[type="submit"]:hover,
221
+ input[type="reset"]:hover,
222
+ input[type="button"]:hover,
223
+ .button:focus,
224
+ button:focus,
225
+ input[type="submit"]:focus,
226
+ input[type="reset"]:focus,
227
+ input[type="button"]:focus {
228
+ color: #333;
229
+ border-color: #888;
230
+ outline: 0; }
231
+ .button.button-primary,
232
+ button.button-primary,
233
+ input[type="submit"].button-primary,
234
+ input[type="reset"].button-primary,
235
+ input[type="button"].button-primary {
236
+ color: #FFF;
237
+ background-color: #33C3F0;
238
+ border-color: #33C3F0; }
239
+ .button.button-primary:hover,
240
+ button.button-primary:hover,
241
+ input[type="submit"].button-primary:hover,
242
+ input[type="reset"].button-primary:hover,
243
+ input[type="button"].button-primary:hover,
244
+ .button.button-primary:focus,
245
+ button.button-primary:focus,
246
+ input[type="submit"].button-primary:focus,
247
+ input[type="reset"].button-primary:focus,
248
+ input[type="button"].button-primary:focus {
249
+ color: #FFF;
250
+ background-color: #1EAEDB;
251
+ border-color: #1EAEDB; }
252
+
253
+
254
+ /* Forms
255
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
256
+ input[type="email"],
257
+ input[type="number"],
258
+ input[type="search"],
259
+ input[type="text"],
260
+ input[type="tel"],
261
+ input[type="url"],
262
+ input[type="password"],
263
+ textarea,
264
+ select {
265
+ height: 38px;
266
+ padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
267
+ background-color: #fff;
268
+ border: 1px solid #D1D1D1;
269
+ border-radius: 4px;
270
+ box-shadow: none;
271
+ box-sizing: border-box;
272
+ font-family: inherit;
273
+ font-size: inherit; /*https://stackoverflow.com/questions/6080413/why-doesnt-input-inherit-the-font-from-body*/}
274
+ /* Removes awkward default styles on some inputs for iOS */
275
+ input[type="email"],
276
+ input[type="number"],
277
+ input[type="search"],
278
+ input[type="text"],
279
+ input[type="tel"],
280
+ input[type="url"],
281
+ input[type="password"],
282
+ textarea {
283
+ -webkit-appearance: none;
284
+ -moz-appearance: none;
285
+ appearance: none; }
286
+ textarea {
287
+ resize: none;
288
+ min-height: 65px;
289
+ padding-top: 6px;
290
+ padding-bottom: 6px; }
291
+ input[type="email"]:focus,
292
+ input[type="number"]:focus,
293
+ input[type="search"]:focus,
294
+ input[type="text"]:focus,
295
+ input[type="tel"]:focus,
296
+ input[type="url"]:focus,
297
+ input[type="password"]:focus,
298
+ textarea:focus,
299
+ select:focus {
300
+ border: 1px solid #33C3F0;
301
+ outline: 0; }
302
+ label,
303
+ legend {
304
+ display: block;
305
+ margin-bottom: 0px; }
306
+ fieldset {
307
+ padding: 0;
308
+ border-width: 0; }
309
+ input[type="checkbox"],
310
+ input[type="radio"] {
311
+ display: inline; }
312
+ label > .label-body {
313
+ display: inline-block;
314
+ margin-left: .5rem;
315
+ font-weight: normal; }
316
+
317
+
318
+ /* Lists
319
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
320
+ ul {
321
+ list-style: circle inside; }
322
+ ol {
323
+ list-style: decimal inside; }
324
+ ol, ul {
325
+ padding-left: 0;
326
+ margin-top: 0; }
327
+ ul ul,
328
+ ul ol,
329
+ ol ol,
330
+ ol ul {
331
+ margin: 1.5rem 0 1.5rem 3rem;
332
+ font-size: 90%; }
333
+ li {
334
+ margin-bottom: 1rem; }
335
+
336
+
337
+ /* Tables
338
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
339
+ th,
340
+ td {
341
+ padding: 12px 15px;
342
+ text-align: left;
343
+ border-bottom: 1px solid #E1E1E1; }
344
+ th:first-child,
345
+ td:first-child {
346
+ padding-left: 0; }
347
+ th:last-child,
348
+ td:last-child {
349
+ padding-right: 0; }
350
+
351
+
352
+ /* Spacing
353
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
354
+ button,
355
+ .button {
356
+ margin-bottom: 0rem; }
357
+ input,
358
+ textarea,
359
+ select,
360
+ fieldset {
361
+ margin-bottom: 0rem; }
362
+ pre,
363
+ dl,
364
+ figure,
365
+ table,
366
+ form {
367
+ margin-bottom: 0rem; }
368
+ p,
369
+ ul,
370
+ ol {
371
+ margin-bottom: 0.75rem; }
372
+
373
+ /* Utilities
374
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
375
+ .u-full-width {
376
+ width: 100%;
377
+ box-sizing: border-box; }
378
+ .u-max-full-width {
379
+ max-width: 100%;
380
+ box-sizing: border-box; }
381
+ .u-pull-right {
382
+ float: right; }
383
+ .u-pull-left {
384
+ float: left; }
385
+
386
+
387
+ /* Misc
388
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
389
+ hr {
390
+ margin-top: 3rem;
391
+ margin-bottom: 3.5rem;
392
+ border-width: 0;
393
+ border-top: 1px solid #E1E1E1; }
394
+
395
+
396
+ /* Clearing
397
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
398
+
399
+ /* Self Clearing Goodness */
400
+ .container:after,
401
+ .row:after,
402
+ .u-cf {
403
+ content: "";
404
+ display: table;
405
+ clear: both; }
406
+
407
+
408
+ /* Media Queries
409
+ –––––––––––––––––––––––––––––––––––––––––––––––––– */
410
+ /*
411
+ Note: The best way to structure the use of media queries is to create the queries
412
+ near the relevant code. For example, if you wanted to change the styles for buttons
413
+ on small devices, paste the mobile query code up in the buttons section and style it
414
+ there.
415
+ */
416
+
417
+
418
+ /* Larger than mobile */
419
+ @media (min-width: 400px) {}
420
+
421
+ /* Larger than phablet (also point when grid becomes active) */
422
+ @media (min-width: 550px) {}
423
+
424
+ /* Larger than tablet */
425
+ @media (min-width: 750px) {}
426
+
427
+ /* Larger than desktop */
428
+ @media (min-width: 1000px) {}
429
+
430
+ /* Larger than Desktop HD */
431
+ @media (min-width: 1200px) {}