psi-data-utils 0.0.1__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.
psi_data/__init__.py ADDED
@@ -0,0 +1,46 @@
1
+ """Sample data fetching and management utilities for Predictive Science Inc.
2
+
3
+ This package provides thin, cached download helpers for PSI sample datasets —
4
+ MHD model output from MAS and POT3D runs plus standalone example files. Files
5
+ are downloaded on demand into a local :mod:`pooch` cache and verified against
6
+ packaged checksums, so repeated calls are cheap.
7
+
8
+ Examples
9
+ --------
10
+ >>> import psi_data
11
+ >>> paths = psi_data.fetch_mas_data(domains="cor", variables="br") # doctest: +SKIP
12
+ >>> paths.cor_br # doctest: +SKIP
13
+ PosixPath('.../cor/mhd/br002.h5')
14
+ """
15
+
16
+ from ._static_assets import *
17
+
18
+ __all__ = [*_static_assets.__all__,]
19
+
20
+ # Hoist the canonical location of the public API from the private implementation
21
+ # module up to the package root. This makes documentation tooling (and runtime
22
+ # introspection) present these objects as ``psi_data.<name>`` rather than
23
+ # ``psi_data._static_assets.<name>``.
24
+ for _name in __all__:
25
+ _obj = globals().get(_name)
26
+ if getattr(_obj, "__module__", None) == _static_assets.__name__:
27
+ _obj.__module__ = __name__
28
+ del _name, _obj
29
+
30
+ try:
31
+ from importlib.metadata import version as _pkg_version
32
+ from importlib.metadata import PackageNotFoundError
33
+ from pathlib import Path
34
+ __version__ = _pkg_version("psi-data") # type: ignore[assignment]
35
+ except PackageNotFoundError as e: # dev/editable without metadata
36
+ try:
37
+ import tomllib # Python 3.11+
38
+ except ModuleNotFoundError: # pragma: no cover
39
+ import tomli as tomllib # pip install tomli
40
+
41
+ pyproject = Path(__file__).parents[1].resolve() / 'pyproject.toml'
42
+ data = tomllib.loads(pyproject.read_text())
43
+
44
+ project_version = data.get("project", {}).get("version", "0+unknown")
45
+ project_version = project_version.replace('"', '').replace("'", '')
46
+ __version__ = project_version
@@ -0,0 +1,593 @@
1
+ """Download and cache PSI sample datasets via :mod:`pooch`.
2
+
3
+ This module backs the public :mod:`psi_data` API. It configures a single
4
+ module-level fetcher (:data:`FETCHER`) against a registry of MHD model outputs
5
+ and example data files, and exposes ``fetch_*`` helpers that download the
6
+ requested files on demand and return their on-disk paths.
7
+
8
+ The bundled data come from a thermodynamic MAS standard run for Carrington
9
+ rotation 2309 driven by an HMI magnetogram, spanning the coronal (``cor``) and
10
+ heliospheric (``hel``) domains, together with a POT3D potential-field solution
11
+ and a handful of standalone example files. Files are fetched into the
12
+ :mod:`pooch` OS cache (overridable through the :envvar:`PSI_DATA_CACHE`
13
+ environment variable) and verified against the packaged registry hashes, so
14
+ repeated calls are cheap.
15
+
16
+ Setting the :envvar:`DEVELOPMENT` environment variable redirects the fetcher to
17
+ a local development server (``http://localhost:8000``) and selects the
18
+ development registry instead of the published PSI asset host.
19
+
20
+ See Also
21
+ --------
22
+ pooch.Pooch : The underlying download-and-cache manager.
23
+ clear_psi_cache : Remove cached files written by the fetchers.
24
+
25
+ Examples
26
+ --------
27
+ >>> from psi_data import fetch_mas_data
28
+ >>> paths = fetch_mas_data(domains="cor", variables="br") # doctest: +SKIP
29
+ >>> paths.cor_br # doctest: +SKIP
30
+ PosixPath('.../H5CR2309_hmi_mast_mas_std_0201/cor/mhd/br002.h5')
31
+ """
32
+
33
+ from __future__ import annotations
34
+
35
+ import os
36
+ import shutil
37
+ import warnings
38
+ from collections import namedtuple
39
+ from collections.abc import Callable
40
+ from functools import partial, wraps
41
+ from itertools import product
42
+ from types import MappingProxyType
43
+ from typing import Iterable, Optional
44
+
45
+ import pooch
46
+ from pathlib import Path
47
+
48
+ try:
49
+ from importlib.resources import as_file, files
50
+ except ImportError: # Python < 3.9: fall back to the backport
51
+ from importlib_resources import as_file, files
52
+
53
+ __all__ = [
54
+ "fetch_mas_data",
55
+ "fetch_mas_quantities",
56
+ "fetch_pot3d_data",
57
+ "fetch_example_fieldline",
58
+ "fetch_example_radial_scale",
59
+ "fetch_example_chmapdb",
60
+ "clear_psi_cache",
61
+ "fetch_all",
62
+ "RegistryWarning",
63
+ ]
64
+
65
+ class RegistryWarning(UserWarning):
66
+ """Warning emitted when a requested data file is unavailable.
67
+
68
+ Notes
69
+ -----
70
+ Raised in place of an error by ``fetch_*`` helpers when an optional file is
71
+ absent from the registry for the requested HDF version, allowing callers to
72
+ continue. See :func:`fetch_example_chmapdb`.
73
+ """
74
+
75
+
76
+ Filepaths = partial(namedtuple, "Filepaths")
77
+ """Factory that builds a ``Filepaths`` named-tuple class from field names."""
78
+
79
+ HDF_EXT = MappingProxyType({
80
+ 4: ".hdf",
81
+ 5: ".h5",
82
+ })
83
+ """Mapping of supported HDF format version (``4``, ``5``) to file extension."""
84
+
85
+ DOM_VAR_MAP = MappingProxyType({
86
+ "cor": {"br", "bt", "bp", "vr", "vt", "vp", "jr", "jt", "jp", "t", "rho", "p", "ep", "em", "zp", "zm", "heat"}, # "te", "tp",
87
+ "hel": {"br", "bt", "bp", "vr", "vt", "vp", "jr", "jt", "jp", "t", "rho", "p"},
88
+ "pot3d": {"br", "bt", "bp"},
89
+ "quantities": {"ch_pm",}
90
+ })
91
+ """Mapping of each model domain to the set of variable names it provides."""
92
+
93
+ REGISTRY_DIR = "registry"
94
+ """Package subdirectory containing the bundled registry file(s)."""
95
+
96
+ REGISTRY_FILE = "registry.txt"
97
+ """Name of the active registry file; development builds use ``registry-dev.txt``."""
98
+
99
+ BASE_URL = "https://www.predsci.com/doc/assets/"
100
+ """Root URL the fetcher downloads data files from."""
101
+
102
+ CACHE_DIR = "psi"
103
+ """:mod:`pooch` OS-cache project name under which downloaded files are stored."""
104
+
105
+ CACHE_ENV = "PSI_DATA_CACHE"
106
+ """Environment variable that, when set, overrides the on-disk cache location."""
107
+
108
+ if os.environ.get("DEVELOPMENT"):
109
+ host, port = "localhost", 8000
110
+
111
+ REGISTRY_FILE = "registry-dev.txt"
112
+ BASE_URL = f"http://{host}:{port}"
113
+
114
+
115
+ FETCHER = pooch.create(
116
+ path=pooch.os_cache(CACHE_DIR),
117
+ base_url=BASE_URL,
118
+ registry=None,
119
+ env=CACHE_ENV,
120
+ )
121
+ """Module-level :class:`pooch.Pooch` manager that downloads and caches PSI data files."""
122
+
123
+
124
+ registry_resource = files("psi_data").joinpath(REGISTRY_DIR, REGISTRY_FILE)
125
+ with as_file(registry_resource) as registry_path:
126
+ if not registry_path.is_file():
127
+ raise FileNotFoundError(
128
+ f"Registry file {REGISTRY_FILE!r} not found in package data. "
129
+ "Ensure it has been generated and shipped with the package.",
130
+ )
131
+ FETCHER.load_registry(registry_path)
132
+
133
+
134
+ def _check_hdf_version(func) -> Callable:
135
+ """Wrap a fetcher to validate its ``hdf`` keyword argument.
136
+
137
+ Parameters
138
+ ----------
139
+ func : Callable
140
+ A fetcher that accepts an ``hdf`` keyword argument.
141
+
142
+ Returns
143
+ -------
144
+ wrapper : Callable
145
+ The wrapped fetcher, which raises :exc:`ValueError` for unsupported
146
+ HDF versions before delegating to *func*.
147
+ """
148
+ @wraps(func)
149
+ def wrapper(*args, hdf: int = 5, **kwargs):
150
+ """Validate *hdf* against :data:`HDF_EXT`, then call the wrapped fetcher."""
151
+ if hdf not in HDF_EXT:
152
+ raise ValueError(f"Unsupported HDF version: {hdf}. "
153
+ f"Supported versions are: {list(HDF_EXT.keys())}")
154
+ return func(*args, hdf=hdf, **kwargs)
155
+ return wrapper
156
+
157
+
158
+ @_check_hdf_version
159
+ def fetch_mas_data(*, domains: Optional[Iterable] = 'cor',
160
+ variables: Optional[Iterable] = 'br',
161
+ hdf: int = 5) -> object:
162
+ r"""Fetch MAS magnetohydrodynamic model output for the given domains and variables.
163
+
164
+ Downloads the requested MAS field files from the Carrington rotation 2309
165
+ standard run and returns their cached paths. One file is fetched for each
166
+ requested ``(domain, variable)`` pair.
167
+
168
+ Parameters
169
+ ----------
170
+ domains : str | Iterable | None, optional
171
+ Model domain(s) to fetch: ``"cor"`` (corona) and/or ``"hel"``
172
+ (heliosphere). Accepts a comma-separated string, an iterable of domain
173
+ names, or ``None`` to fetch both domains. Default is ``"cor"``.
174
+ variables : str | Iterable | None, optional
175
+ Physical variable(s) to fetch, such as the magnetic field components
176
+ ``"br"``, ``"bt"``, ``"bp"`` (:math:`\mathbf{B}`) or the velocity
177
+ components ``"vr"``, ``"vt"``, ``"vp"`` (:math:`\mathbf{v}`). Accepts a
178
+ comma-separated string, an iterable of variable names, or ``None`` to
179
+ fetch every variable common to all requested domains. Default is
180
+ ``"br"``.
181
+ hdf : int, optional
182
+ HDF format version to download: ``4`` (``.hdf``) or ``5`` (``.h5``).
183
+ Default is ``5``.
184
+
185
+ Returns
186
+ -------
187
+ paths : Filepaths
188
+ Named tuple whose fields are ``"{domain}_{variable}"`` and whose values
189
+ are the :class:`~pathlib.Path` of each downloaded file.
190
+
191
+ Raises
192
+ ------
193
+ ValueError
194
+ If *hdf* is not a supported HDF version.
195
+ KeyError
196
+ If *variables* is ``None`` and a requested domain is not present in
197
+ :data:`DOM_VAR_MAP`.
198
+
199
+ See Also
200
+ --------
201
+ fetch_pot3d_data : Fetch POT3D potential-field components.
202
+ fetch_mas_quantities : Fetch derived MAS quantities at the inner boundary.
203
+
204
+ Examples
205
+ --------
206
+ >>> from psi_data import fetch_mas_data
207
+ >>> paths = fetch_mas_data(domains="cor,hel", variables="br,vr") # doctest: +SKIP
208
+ >>> paths.cor_br # doctest: +SKIP
209
+ PosixPath('.../cor/mhd/br002.h5')
210
+ """
211
+ if domains is None:
212
+ domains = {"cor", "hel"}
213
+ else:
214
+ domains = set(domains.replace(" ", "").lower().split(",") if isinstance(domains, str) else domains)
215
+
216
+ if variables is None:
217
+ variables = set.intersection(*(DOM_VAR_MAP[dom] for dom in domains))
218
+ else:
219
+ variables = set(variables.replace(" ", "").lower().split(",") if isinstance(variables, str) else variables)
220
+ req_pairs = product(domains, variables)
221
+
222
+ ext = HDF_EXT.get(hdf)
223
+ filepaths = {
224
+ f"{dom}_{var}":
225
+ Path(
226
+ FETCHER.fetch(
227
+ f"H{hdf}CR2309_hmi_mast_mas_std_0201/{dom}/mhd/{var}002{ext}",
228
+ progressbar=True))
229
+ for dom, var in req_pairs
230
+ }
231
+
232
+ return Filepaths(filepaths.keys())(*filepaths.values())
233
+
234
+
235
+ @_check_hdf_version
236
+ def fetch_mas_quantities(*, quantities: Optional[Iterable] = 'ch_pm', hdf: int = 5) -> object:
237
+ r"""Fetch derived MAS quantities defined at the model inner radial boundary.
238
+
239
+ Downloads MAS "quantities at :math:`r_0`" files — scalar quantities
240
+ evaluated at the inner radial boundary of the coronal domain — and returns
241
+ their cached paths.
242
+
243
+ Parameters
244
+ ----------
245
+ quantities : str | Iterable | None, optional
246
+ Quantity name(s) to fetch, e.g. ``"ch_pm"``. Accepts a comma-separated
247
+ string, an iterable of quantity names, or ``None`` to fetch every
248
+ available quantity. Default is ``"ch_pm"``.
249
+ hdf : int, optional
250
+ HDF format version to download: ``4`` (``.hdf``) or ``5`` (``.h5``).
251
+ Default is ``5``.
252
+
253
+ Returns
254
+ -------
255
+ paths : Filepaths
256
+ Named tuple whose fields are the quantity names and whose values are
257
+ the :class:`~pathlib.Path` of each downloaded file.
258
+
259
+ Raises
260
+ ------
261
+ ValueError
262
+ If *hdf* is not a supported HDF version.
263
+
264
+ See Also
265
+ --------
266
+ fetch_mas_data : Fetch full MAS MHD field output.
267
+
268
+ Examples
269
+ --------
270
+ >>> from psi_data import fetch_mas_quantities
271
+ >>> paths = fetch_mas_quantities(quantities="ch_pm") # doctest: +SKIP
272
+ >>> paths.ch_pm # doctest: +SKIP
273
+ PosixPath('.../cor/quantities_at_r0/ch_pm.h5')
274
+ """
275
+ if quantities is None:
276
+ quantities = DOM_VAR_MAP["quantities"]
277
+ else:
278
+ quantities = set(quantities.replace(" ", "").lower().split(",") if isinstance(quantities, str) else quantities)
279
+
280
+ ext = HDF_EXT.get(hdf)
281
+ filepaths = {
282
+ f"{var}":
283
+ Path(
284
+ FETCHER.fetch(
285
+ f"H{hdf}CR2309_hmi_mast_mas_std_0201/cor/quantities_at_r0/{var}{ext}",
286
+ progressbar=True))
287
+ for var in quantities
288
+ }
289
+
290
+ return Filepaths(filepaths.keys())(*filepaths.values())
291
+
292
+
293
+ @_check_hdf_version
294
+ def fetch_pot3d_data(*, variables: Optional[Iterable] = 'br', hdf: int = 5) -> object:
295
+ r"""Fetch POT3D potential-field source-surface (PFSS) magnetic field components.
296
+
297
+ Downloads the POT3D PFSS solution components for the coronal domain and
298
+ returns their cached paths.
299
+
300
+ Parameters
301
+ ----------
302
+ variables : str | Iterable | None, optional
303
+ Magnetic field component(s) to fetch: ``"br"``, ``"bt"``, ``"bp"``
304
+ (:math:`\mathbf{B}`). Accepts a comma-separated string, an iterable of
305
+ component names, or ``None`` to fetch all three components. Default is
306
+ ``"br"``.
307
+ hdf : int, optional
308
+ HDF format version to download: ``4`` (``.hdf``) or ``5`` (``.h5``).
309
+ Default is ``5``.
310
+
311
+ Returns
312
+ -------
313
+ paths : Filepaths
314
+ Named tuple whose fields are the component names and whose values are
315
+ the :class:`~pathlib.Path` of each downloaded file.
316
+
317
+ Raises
318
+ ------
319
+ ValueError
320
+ If *hdf* is not a supported HDF version.
321
+
322
+ See Also
323
+ --------
324
+ fetch_mas_data : Fetch full MAS MHD field output.
325
+
326
+ Examples
327
+ --------
328
+ >>> from psi_data import fetch_pot3d_data
329
+ >>> paths = fetch_pot3d_data(variables="br,bt,bp") # doctest: +SKIP
330
+ >>> paths.br # doctest: +SKIP
331
+ PosixPath('.../cor/pfss/br.h5')
332
+ """
333
+ if variables is None:
334
+ variables = DOM_VAR_MAP["pot3d"]
335
+ else:
336
+ variables = set(variables.replace(" ", "").lower().split(",") if isinstance(variables, str) else variables)
337
+
338
+ ext = HDF_EXT.get(hdf)
339
+ filepaths = {
340
+ f"{var}":
341
+ Path(
342
+ FETCHER.fetch(
343
+ f"H{hdf}CR2309_hmi_mast_mas_std_0201/cor/pfss/{var}{ext}",
344
+ progressbar=True))
345
+ for var in variables
346
+ }
347
+
348
+ return Filepaths(filepaths.keys())(*filepaths.values())
349
+
350
+
351
+ @_check_hdf_version
352
+ def fetch_example_fieldline(*, hdf: int = 5) -> Path:
353
+ """Fetch the bundled example magnetic field line trace data file.
354
+
355
+ Parameters
356
+ ----------
357
+ hdf : int, optional
358
+ HDF format version to download: ``4`` (``.hdf``) or ``5`` (``.h5``).
359
+ Default is ``5``.
360
+
361
+ Returns
362
+ -------
363
+ path : Path
364
+ Cached path of the downloaded field line example file.
365
+
366
+ Raises
367
+ ------
368
+ ValueError
369
+ If *hdf* is not a supported HDF version.
370
+
371
+ See Also
372
+ --------
373
+ fetch_example_radial_scale : Fetch the example radial scaling data file.
374
+ fetch_example_chmapdb : Fetch the example coronal-hole map database.
375
+
376
+ Examples
377
+ --------
378
+ >>> from psi_data import fetch_example_fieldline
379
+ >>> path = fetch_example_fieldline() # doctest: +SKIP
380
+ >>> path.name # doctest: +SKIP
381
+ 'fieldline.h5'
382
+ """
383
+ ext = HDF_EXT.get(hdf)
384
+ return Path(
385
+ FETCHER.fetch(
386
+ f"example_datafiles/fieldline{ext}",
387
+ progressbar=True))
388
+
389
+
390
+ @_check_hdf_version
391
+ def fetch_example_radial_scale(*, hdf: int = 5) -> Path:
392
+ r"""Fetch the bundled example radial scaling data file.
393
+
394
+ Parameters
395
+ ----------
396
+ hdf : int, optional
397
+ HDF format version to download: ``4`` (``.hdf``) or ``5`` (``.h5``).
398
+ Default is ``5``.
399
+
400
+ Returns
401
+ -------
402
+ path : Path
403
+ Cached path of the downloaded radial scaling example file.
404
+
405
+ Raises
406
+ ------
407
+ ValueError
408
+ If *hdf* is not a supported HDF version.
409
+
410
+ See Also
411
+ --------
412
+ fetch_example_fieldline : Fetch the example field line data file.
413
+
414
+ Notes
415
+ -----
416
+ The radial scaling profile is commonly used to rescale MHD variables that
417
+ fall off steeply with heliocentric radius :math:`r`, improving the dynamic
418
+ range of visualizations.
419
+
420
+ Examples
421
+ --------
422
+ >>> from psi_data import fetch_example_radial_scale
423
+ >>> path = fetch_example_radial_scale() # doctest: +SKIP
424
+ >>> path.name # doctest: +SKIP
425
+ 'rscale.h5'
426
+ """
427
+ ext = HDF_EXT.get(hdf)
428
+ return Path(
429
+ FETCHER.fetch(
430
+ f"example_datafiles/rscale{ext}",
431
+ progressbar=True))
432
+
433
+
434
+ @_check_hdf_version
435
+ def fetch_example_chmapdb(*, hdf: int = 5) -> Path | None:
436
+ """Fetch the bundled example coronal-hole map database, if available.
437
+
438
+ Parameters
439
+ ----------
440
+ hdf : int, optional
441
+ HDF format version to download: ``4`` (``.hdf``) or ``5`` (``.h5``).
442
+ Default is ``5``.
443
+
444
+ Returns
445
+ -------
446
+ path : Path | None
447
+ Cached path of the downloaded coronal-hole map database, or ``None`` if
448
+ the file is unavailable for the requested HDF version.
449
+
450
+ Raises
451
+ ------
452
+ ValueError
453
+ If *hdf* is not a supported HDF version.
454
+
455
+ Warns
456
+ -----
457
+ RegistryWarning
458
+ If the database is not available for the requested HDF version (it is
459
+ currently provided only for HDF5).
460
+
461
+ See Also
462
+ --------
463
+ fetch_example_fieldline : Fetch the example field line data file.
464
+
465
+ Examples
466
+ --------
467
+ >>> from psi_data import fetch_example_chmapdb
468
+ >>> path = fetch_example_chmapdb(hdf=5) # doctest: +SKIP
469
+ >>> path.name # doctest: +SKIP
470
+ 'chmap.h5'
471
+ """
472
+ ext = HDF_EXT.get(hdf)
473
+
474
+ try:
475
+ return Path(
476
+ FETCHER.fetch(
477
+ f"example_datafiles/chmap{ext}",
478
+ progressbar=True))
479
+ except ValueError:
480
+ warnings.warn(
481
+ f"Example CHMAP database file not found for HDF version {hdf}. "
482
+ "This file is only available for HDF5. Returning None.",
483
+ RegistryWarning,
484
+ )
485
+ return None
486
+
487
+
488
+ @_check_hdf_version
489
+ def fetch_all(*, hdf: int = 5) -> list[Path]:
490
+ """Fetch every registry file matching the requested HDF version.
491
+
492
+ Downloads all files in the fetcher registry whose names end with the
493
+ extension for the requested HDF version and returns their cached paths.
494
+
495
+ Parameters
496
+ ----------
497
+ hdf : int, optional
498
+ HDF format version to download: ``4`` (``.hdf``) or ``5`` (``.h5``).
499
+ Default is ``5``.
500
+
501
+ Returns
502
+ -------
503
+ filepaths : list[Path]
504
+ Cached paths of every downloaded file, in registry order.
505
+
506
+ Raises
507
+ ------
508
+ ValueError
509
+ If *hdf* is not a supported HDF version.
510
+
511
+ Notes
512
+ -----
513
+ This downloads the entire data collection for the chosen format and may
514
+ transfer a large volume of data on its first invocation.
515
+
516
+ See Also
517
+ --------
518
+ fetch_mas_data : Fetch a targeted subset of MAS field output.
519
+
520
+ Examples
521
+ --------
522
+ >>> from psi_data import fetch_all
523
+ >>> paths = fetch_all(hdf=5) # doctest: +SKIP
524
+ >>> all(p.suffix == ".h5" for p in paths) # doctest: +SKIP
525
+ True
526
+ """
527
+ ext = HDF_EXT.get(hdf)
528
+ keys = FETCHER.registry.keys()
529
+ filtered_paths = filter(lambda k: k.endswith(ext), keys)
530
+ filepaths = [Path(FETCHER.fetch(k, progressbar=True)) for k in filtered_paths]
531
+ return filepaths
532
+
533
+
534
+
535
+ def _cache_locations() -> list[Path]:
536
+ """Return the distinct cache directories psi_data may write to.
537
+
538
+ Returns
539
+ -------
540
+ locations : list[Path]
541
+ The default :mod:`pooch` OS cache directory, followed by the
542
+ :envvar:`PSI_DATA_CACHE` override when it is set and distinct.
543
+ """
544
+ locations = [Path(pooch.os_cache(CACHE_DIR)).expanduser()]
545
+ env_value = os.environ.get(CACHE_ENV)
546
+ if env_value:
547
+ env_path = Path(env_value).expanduser()
548
+ if env_path not in locations:
549
+ locations.append(env_path)
550
+ return locations
551
+
552
+
553
+ def clear_psi_cache(dry_run: bool = True, prompt: bool = True):
554
+ """Delete cached data files downloaded by the ``fetch_*`` helpers.
555
+
556
+ Removes the :mod:`pooch` cache directories used by :data:`FETCHER` — the
557
+ default OS cache and the :envvar:`PSI_DATA_CACHE` override when set.
558
+ Directories that do not exist are skipped.
559
+
560
+ Parameters
561
+ ----------
562
+ dry_run : bool, optional
563
+ If ``True``, only report which directories would be removed without
564
+ deleting anything. Default is ``True``.
565
+ prompt : bool, optional
566
+ If ``True``, ask for interactive confirmation before removing each
567
+ directory. Ignored when *dry_run* is ``True``. Default is ``True``.
568
+
569
+ See Also
570
+ --------
571
+ pooch.os_cache : Resolves the platform-specific cache directory.
572
+
573
+ Examples
574
+ --------
575
+ >>> from psi_data import clear_psi_cache
576
+ >>> clear_psi_cache(dry_run=True) # doctest: +SKIP
577
+ [dry-run] Would remove cache directory: ...
578
+ """
579
+ for location in _cache_locations():
580
+ if not location.exists():
581
+ print(f"Skipping {location} (does not exist).")
582
+ continue
583
+ if dry_run:
584
+ print(f"[dry-run] Would remove cache directory: {location}")
585
+ continue
586
+
587
+ print(f"Removing cache directory: {location}")
588
+ answer = input("Continue? [y/n]: ").strip().lower() in {"y", "yes"} if prompt else True
589
+
590
+ if answer:
591
+ shutil.rmtree(location)
592
+ else:
593
+ print("Aborting cache clear.")
@@ -0,0 +1,71 @@
1
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/bp002.hdf 812b3dd05eb1792bf6feda6b99b409b4984dd85440706270ae6068985831b717
2
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/br002.hdf 4a24579de887222c86a90e1e085abc82ce34083f20ab89b7a3ab01a096be66c0
3
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/bt002.hdf 7a88504f43a23f31f7411275861dbe683458396b261ba8f8dc07a5b4da0e9daf
4
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/em002.hdf 4f9c7c8ea434af584d679836855732d4f7854b00c8877dc0443be30e1ce8a99f
5
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/ep002.hdf 147e5b7d6100ffdb95bf4257576e406db9197b5660a7888487cbbdf575108967
6
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/heat002.hdf 248b4b459fb30bf784af8359463ed42345fc33a88f0e9826635932b4026d3337
7
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/jp002.hdf 915668574adba712041e9900b97ab2536d87c1eb4e687d6922619e08c6b08f57
8
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/jr002.hdf cbbb48d6b0cc21e66a537dfc7b213c87689f5722eb5c17951e2cec78dfa9ed83
9
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/jt002.hdf b782033c9c1029169489335f12e6b810116f9f945c57b23ffaffc482041ddfeb
10
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/p002.hdf 496929287388ddb9190d67c81f48cf424ac5b77d92c9f0883933dcfeb53545a5
11
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/rho002.hdf 1e977c3d15d4ebe9cd0970f55545317ccd90e47c0e55dae38ff873e6553c54f8
12
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/t002.hdf 0f0fd3b975d8cb7fc0e39885d29dfb9c55c2a9b9a0d906eba98c50cf07e808fb
13
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/vp002.hdf d2b556a99e351a9253fd369becef9465f20efda828238fa0a46cc98497b3233d
14
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/vr002.hdf cd450834f8752852de3369a4fd48ef927aa6151197ca9c1b5c32ed311079d701
15
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/vt002.hdf 6542bee52b045d1e54b2e4770f2223d8173d6c522b434b709399d70917578b9b
16
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/zm002.hdf f2d31d12429dc65934a6246bfe075f7585ffec3ad627dc5d535e1b20f9ed2ac3
17
+ H4CR2309_hmi_mast_mas_std_0201/cor/mhd/zp002.hdf f2d31d12429dc65934a6246bfe075f7585ffec3ad627dc5d535e1b20f9ed2ac3
18
+ H4CR2309_hmi_mast_mas_std_0201/cor/pfss/bp.hdf ebe9ee78e4e890e94a7b67947db87ca0a0a0ca52f188f0bdb143a223496afe59
19
+ H4CR2309_hmi_mast_mas_std_0201/cor/pfss/br.hdf 72b329e7cc793c021ac95feacec8080c167c1684f5cdccd5ac9ba72b8ea13c8b
20
+ H4CR2309_hmi_mast_mas_std_0201/cor/pfss/bt.hdf a5955996815912fd046cd4a2ac12c64b1e24596a8937cea3cbc39e17faac6efa
21
+ H4CR2309_hmi_mast_mas_std_0201/cor/quantities_at_r0/ch_pm.hdf e2c9e7c06feaeb0f3950008edb2f72923f60e1cc3692f26d69bdf9da03e74ed2
22
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/bp002.hdf 75e03e2330f9ad5d9d128820fa1a93f498ca42ba69799140efee89f5dd37c0a6
23
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/br002.hdf 114004dcfaaef8bf4f01b37ec93bda947bf50881a1bcefccc7c07b759f751eb8
24
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/bt002.hdf 91f64335878b1ff7a8ef1634204c2db6d34f789b1f6a74994ac4c00983f52396
25
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/jp002.hdf 09a18c6d1b64e5eb1558cfabb21f622cd062894d4fa28abe5b910c78694ccea3
26
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/jr002.hdf e3a5efd68f57cad11fd5886b786916c2b0652e7010eae6006b9b8481147aec4a
27
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/jt002.hdf ee05c50850244efb0b3ccd02667553118b9e21efe9bc6a7966ef54cd2dbd3fbb
28
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/p002.hdf ea8f778f842ebe5f8fc35a35fbf3cc0c40248444b60e352270fb0de043747f99
29
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/rho002.hdf ee33d22fec5b7d37774c7e38301185a942379837f2acc11fa3ec9bcacf831b78
30
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/t002.hdf 40317b50b1324652c518a10f2d23b8b65363d2844927903a3d0f527babce8e75
31
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/vp002.hdf d381a384da129881a6487bd5792be9fb51cf894ced589307859b36eceee0d9bb
32
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/vr002.hdf 45e4f5b4ce325cc45d925d7c5b23ca10f3ea8fbe7d7a761c1fa1641c6d9315c3
33
+ H4CR2309_hmi_mast_mas_std_0201/hel/mhd/vt002.hdf 0b83bb317f50e9791a90944480fc8044ed7715e68f220841983efb172a84ba57
34
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/bp002.h5 d62d9287c6b9ce970c670a301a0779cacf37c4a3f17f1629be4c1c2f5d049f2a
35
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/br002.h5 350c5c94f981f659e369f88a99a946bdeaea79e290bdaa80f51c03008873d745
36
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/bt002.h5 ca5b2a5bd32caf6f5e4a8aa677f66b5f7389f7773d2c8685446b71ac21880679
37
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/em002.h5 a44d2940fc1f30aec23c9fd6a07337b87ddebce54b96d1c9db4ca1dc1524d843
38
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/ep002.h5 e3c874c73207732900f469e05d2186471471a3d674b2e4b8f86968841c1c67fb
39
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/heat002.h5 6c981d54f4435806357cc59509ab23d6ddfaaf0e36c57ee4d27bce9df274a672
40
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/jp002.h5 891bbd8aa362acf9b3e366dbd20476d71380cbc1aac61f9d91c1971a6ed4b3b9
41
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/jr002.h5 4377747b92e30a287e19109449b041b59e9aa596f680d0b1ebed0c732a5a5abc
42
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/jt002.h5 e4633240aed2e99be62223335c3c5fe4b139bd5c1600a03f8de05e37d33d5950
43
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/p002.h5 cc3c50b9f294940304339376a2e4fd7d0a3547aa5b14657a4c079dab322fc718
44
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/rho002.h5 1635e30929c57231981046befed8dab2651004bda2091ceb6bdc0dd8298793a5
45
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/t002.h5 d4c4c23f6e97a150781d2df0b77d70a93592cd1aeef7c9a45b8c8c0ce2bfd89d
46
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/vp002.h5 395d66056b78c792fba997cc06f1591dadadd191b8687ed43a577c4e93ca135f
47
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/vr002.h5 bba83b251569f1c366397a7d53115804df4acbd9bd260426c4cae75a99324334
48
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/vt002.h5 9e7e693c529682d1a04b08c62fbe0f2ded2f63f6c9b1e0d63a6874674b56b0f0
49
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/zm002.h5 99312eca8d82f6df7260dfe47c87a2bcafc80b619f04889a4bdc85bacf4f66c0
50
+ H5CR2309_hmi_mast_mas_std_0201/cor/mhd/zp002.h5 99312eca8d82f6df7260dfe47c87a2bcafc80b619f04889a4bdc85bacf4f66c0
51
+ H5CR2309_hmi_mast_mas_std_0201/cor/pfss/bp.h5 516c3c84dfe486d6522142a2b827f2b8c57ee618b7809c843c0e369c17b9908a
52
+ H5CR2309_hmi_mast_mas_std_0201/cor/pfss/br.h5 285914a1e2bfb926e91033602f6b77f5abc729136ff28fc1671be6efebe5719e
53
+ H5CR2309_hmi_mast_mas_std_0201/cor/pfss/bt.h5 fd2ca2f4dbe6b771269b52b39f835694727b2ca1e3522d433a4c7236a4657ffd
54
+ H5CR2309_hmi_mast_mas_std_0201/cor/quantities_at_r0/ch_pm.h5 3b894cd8e7f2944b690d3039c84228c3588a295e8065f251959de2068049ef76
55
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/bp002.h5 f5cfe1a4703a7e52e267a059e8d77f546cb45bd27beb6692938764630cbf885e
56
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/br002.h5 3436264b2a8beb78c664bc8c4263022156da67287ded79efa0e80be586acd6ee
57
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/bt002.h5 a23393248e8310c45fbec1a845bd7cfdcb1d5a86fa72a8e6516b4447e65efee5
58
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/jp002.h5 ed9b40778064e892174d689386eb91b2d239de87241ed4cf4ebce7601c92d4ba
59
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/jr002.h5 33cf1865fe2af91eaa8ff4da720062de0e33e327b81e0629c7aea1aea48aa11b
60
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/jt002.h5 e4b448b211e31e7278f35d160bbfc4ab81c089c5969ebf7c173e8d8249f72961
61
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/p002.h5 5a86b9a05c595523bfb41446cecfe9ccf73d5a67bc3cf38d996847b326fa4b67
62
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/rho002.h5 aebbb43f8ce84e763c777659e69a3a9283b17fcbfc9c0ac4bef9a5c21e69bdfb
63
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/t002.h5 44037f2ec590fc0003e62dcfac3065e0a966b38a7d090c3ec5cbd687ec423871
64
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/vp002.h5 1ac446a9a35344fda960025beb4ff95f13f5a2adb397e84966a403c0d775ff3e
65
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/vr002.h5 296ddf4aa7e86031a58a37d5b30a2104fb82ee6846fd65181b4745c36c0a34f4
66
+ H5CR2309_hmi_mast_mas_std_0201/hel/mhd/vt002.h5 3b0656af65f7d61e476a34b3d50bd8ccd6ac68f8cfed5b80ed4444868bd6585c
67
+ example_datafiles/chmap.h5 170794a5a19684246339ca9782a2b89066b89661400ec48bb6fc0a082e0a2450
68
+ example_datafiles/fieldline.h5 a5b2a1cc0c458d0d9510d8eacc93d3b4a2cc7e99e0a3f86cd3d6b164e74f370d
69
+ example_datafiles/fieldline.hdf a4149783780e1ce44a8fe76a83c674e0a3082cd78c6a635b6c8e860e0fdd3891
70
+ example_datafiles/rscale.h5 60a0cbcd4dc69f7d250cbbdddd6fc3680f09d87c1e4cee6a79d8ec3731533718
71
+ example_datafiles/rscale.hdf 1c15bd669fc5a92dfdda7dc23703294c23f0a09440599fd5c30cf7a0e1a6f3c4
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.4
2
+ Name: psi-data-utils
3
+ Version: 0.0.1
4
+ Summary: Sample data fetching and management utilities for Predictive Science Inc.
5
+ Author: Ryder Davidson
6
+ Author-email: "Predictive Science Inc." <webmaster@predsci.com>
7
+ License: Apache-2.0
8
+ Project-URL: homepage, https://predsci.com/
9
+ Project-URL: documentation, https://predsci.com/doc/psi-data
10
+ Project-URL: repository, https://github.com/predsci/psi-data
11
+ Keywords: solar physics,space physics,heliophysics,magnetohydrodynamic,science,mas,predsci,psi,modeling,fortran
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Natural Language :: English
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3 :: Only
24
+ Classifier: Operating System :: Microsoft :: Windows
25
+ Classifier: Operating System :: Unix
26
+ Classifier: Operating System :: POSIX :: Linux
27
+ Classifier: Operating System :: MacOS :: MacOS X
28
+ Classifier: Typing :: Typed
29
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
30
+ Classifier: Topic :: Scientific/Engineering :: Physics
31
+ Requires-Python: >=3.8
32
+ Description-Content-Type: text/x-rst
33
+ License-File: LICENSE
34
+ Requires-Dist: pooch[progress]
35
+ Requires-Dist: importlib_resources>=1.3; python_version < "3.9"
36
+ Provides-Extra: build
37
+ Requires-Dist: python-build; extra == "build"
38
+ Requires-Dist: packaging; extra == "build"
39
+ Provides-Extra: test
40
+ Requires-Dist: pytest; extra == "test"
41
+ Requires-Dist: pytest-cov; extra == "test"
42
+ Provides-Extra: types
43
+ Requires-Dist: mypy>=1.15; extra == "types"
44
+ Provides-Extra: lint
45
+ Requires-Dist: ruff>=0.11.7; extra == "lint"
46
+ Provides-Extra: docs
47
+ Requires-Dist: sphinx==8.2.3; extra == "docs"
48
+ Requires-Dist: sphinx-book-theme==1.1.4; extra == "docs"
49
+ Requires-Dist: sphinx-copybutton==0.5.2; extra == "docs"
50
+ Requires-Dist: numpydoc==1.9.0; extra == "docs"
51
+ Requires-Dist: pthree==1.0.1; extra == "docs"
52
+ Provides-Extra: dev
53
+ Requires-Dist: nox>=2025.11.12; extra == "dev"
54
+ Provides-Extra: all
55
+ Requires-Dist: psi-data[build,dev,docs,lint,test,types]; extra == "all"
56
+ Dynamic: license-file
57
+
58
+ .. |psi| image:: https://predsci.com/doc/psi_logo.png
59
+ :target: https://predsci.com
60
+ :alt: Predictive Science Inc.
61
+ :width: 20px
62
+
63
+ .. |pypi| image:: https://img.shields.io/pypi/v/psi-data?logo=pypi&logoColor=white
64
+ :target: https://pypi.org/project/psi-data
65
+ :alt: PyPI
66
+
67
+ .. |license| image:: https://img.shields.io/pypi/l/psi-data?logo=apache&logoColor=white
68
+ :target: https://opensource.org/license/apache-2-0/
69
+ :alt: License
70
+
71
+ .. |pyversions| image:: https://img.shields.io/pypi/pyversions/psi-data.svg?logo=python&label=python&logoColor=white
72
+ :target: https://pypi.org/project/psi-data
73
+ :alt: Python Versions
74
+
75
+ .. |deps| image:: https://img.shields.io/librariesio/github/predsci/psi-data?logo=Libraries.io&logoColor=white
76
+ :target: https://github.com/predsci/psi-data/blob/main/pyproject.toml
77
+ :alt: Libraries.io
78
+
79
+ .. |publish| image:: https://github.com/predsci/psi-data/actions/workflows/publish.yml/badge.svg?
80
+ :target: https://github.com/predsci/psi-data/actions/workflows/publish.yml
81
+ :alt: Publish workflow
82
+
83
+ .. |docs| image:: https://github.com/predsci/psi-data/actions/workflows/docs.yml/badge.svg?
84
+ :target: https://predsci.com/doc/psi-data
85
+ :alt: Docs workflow
86
+
87
+ |pypi|
88
+ |license|
89
+ |pyversions|
90
+ |deps|
91
+ |publish|
92
+ |docs|
93
+
94
+ |psi| **psi-data** | *PSI's Sample Data Utilities*
95
+ --------------------------------------------------------------------
96
+
97
+ **psi-data** is a Python package developed by `Predictive Science Inc. <https://www.predsci.com>`_ for
98
+ fetching sample PSI datasets *viz.* for use in documentation and tutorial build pipelines. This package
99
+ is intended to be a lightweight utility for downloading and caching PSI data products, and it is not meant
100
+ to be a general-purpose data access library.
101
+
102
+ To get started with **psi-data**, visit the
103
+ `User Guide <https://predsci.com/doc/psi-data/guide/>`_ for installation instructions,
104
+ an overview of features, and development/contribution guidelines. Please direct any questions or
105
+ issues to the `issue tracker <https://github.com/predsci/psi-data/issues>`_,
106
+ or `contact <https://www.predsci.com/portal/contact.php>`_ Predictive Science Inc. directly.
107
+
108
+ ----
109
+
110
+ `Predictive Science Inc. <https://predsci.com>`_ |
111
+ `Repository <https://github.com/predsci/psi-data>`_ |
112
+ `Documentation <https://predsci.com/doc/psi-data>`_ |
113
+ `Distribution <https://pypi.org/project/psi-data>`_
114
+
@@ -0,0 +1,8 @@
1
+ psi_data/__init__.py,sha256=jD30g-9UpMD6R4W8kK6tmcfY1zS8HwfUYQHjr6dKf78,1817
2
+ psi_data/_static_assets.py,sha256=qj_DW8n_fyLuntxlmCgWjo4tSxwYt_rkvw5LpxsDb6w,19027
3
+ psi_data/registry/registry.txt,sha256=3ia_CnTI0kplHWQgzSjolCKjvbLFET9-o9ZiH-3F7Is,7977
4
+ psi_data_utils-0.0.1.dist-info/licenses/LICENSE,sha256=lv-56GbB-1pS-QaMjdQBWgwm2HLFeYbB1If4XUIC2_Q,10776
5
+ psi_data_utils-0.0.1.dist-info/METADATA,sha256=mZXE3Sj7fdikdfYqP2eS9pfhnHtcUOIQ4lsgpVIAyDs,4770
6
+ psi_data_utils-0.0.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
7
+ psi_data_utils-0.0.1.dist-info/top_level.txt,sha256=LcTS5lVutbMFv0tn54RkwTJTm6VWtQsxhgNuEHIC_u8,9
8
+ psi_data_utils-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,190 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ Copyright 2025 Predictive Science Incorporated
179
+
180
+ Licensed under the Apache License, Version 2.0 (the "License");
181
+ you may not use this file except in compliance with the License.
182
+ You may obtain a copy of the License at
183
+
184
+ http://www.apache.org/licenses/LICENSE-2.0
185
+
186
+ Unless required by applicable law or agreed to in writing, software
187
+ distributed under the License is distributed on an "AS IS" BASIS,
188
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189
+ See the License for the specific language governing permissions and
190
+ limitations under the License.
@@ -0,0 +1 @@
1
+ psi_data