roman-snpit-snappl 0.18.0__tar.gz → 0.19.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.
Potentially problematic release.
This version of roman-snpit-snappl might be problematic. Click here for more details.
- {roman_snpit_snappl-0.18.0/roman_snpit_snappl.egg-info → roman_snpit_snappl-0.19.0}/PKG-INFO +1 -1
- roman_snpit_snappl-0.19.0/changes/92.docs.rst +2 -0
- roman_snpit_snappl-0.19.0/changes/94.snappl.rst +1 -0
- roman_snpit_snappl-0.19.0/docs/usage.rst +464 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0/roman_snpit_snappl.egg-info}/PKG-INFO +1 -1
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/roman_snpit_snappl.egg-info/SOURCES.txt +3 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/_version.py +3 -3
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/admin/load_ou2024_l2images.py +102 -5
- roman_snpit_snappl-0.19.0/snappl/admin/load_snana_ou2024_diaobject.py +148 -0
- roman_snpit_snappl-0.19.0/snappl/db/migrations/20251024_l2image_mjd.sql +2 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/webserver.py +1 -1
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/diaobject.py +1 -1
- roman_snpit_snappl-0.18.0/docs/usage.rst +0 -220
- roman_snpit_snappl-0.18.0/snappl/admin/load_snana_ou2024_diaobject.py +0 -66
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.cruft.json +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/CODEOWNERS +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/ISSUE_TEMPLATE/PR_TEMPLATE.md +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/dependabot.yml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/labeler.yml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/workflows/changelog.yml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/workflows/run_labeler.yml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/workflows/run_snappl_tests.yml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/workflows/sphinx-deploy.yml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.github/workflows/sub_package_update.yml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.gitignore +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/.pre-commit-config.yaml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/CHANGES.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/CITATION.cff +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/CODE_OF_CONDUCT.md +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/CONTRIBUTING.md +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/LICENSE +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/MANIFEST.in +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/README.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/.gitkeep +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/10.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/13.bugfix.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/14.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/15.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/16.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/18.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/20.bugfix.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/23.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/26.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/29.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/3.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/31.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/35.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/36.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/37.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/40.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/41.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/43.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/47.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/49.docs.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/5.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/54.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/57.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/58.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/61.bugfix.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/62.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/63.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/65.bugfix.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/68.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/72.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/73.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/74.bugfix.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/79.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/8.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/81.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/82.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/83.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/84.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/85.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/87.docs.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/89.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/9.snappl.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/changes/91.feature.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/codespell-ignore.txt +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/postgres/Dockerfile +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/postgres/postgresql.conf +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/postgres/run_postgres.sh +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/webserver/Dockerfile +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/webserver/cert.pem +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/webserver/config-test.yaml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/webserver/key.pem +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docker/webserver/roman-snpit-server.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/Makefile +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/_static/logo_black_filled.png +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/api.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/changes.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/conf.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/database_schema.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/index.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/installation.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/docs/make.bat +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/experimentation/README.md +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/experimentation/ap_phot_simulated_images.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/experimentation/play_with_photutils.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/licenses/.DS_Store +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/licenses/LICENSE.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/licenses/README.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/licenses/TEMPLATE_LICENSE.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/pyproject.toml +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/roman_snpit_snappl.egg-info/dependency_links.txt +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/roman_snpit_snappl.egg-info/not-zip-safe +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/roman_snpit_snappl.egg-info/requires.txt +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/roman_snpit_snappl.egg-info/top_level.txt +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/setup.cfg +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/setup.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/__init__.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/_dev/__init__.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/_dev/scm_version.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/config.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/data/README.rst +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/baseview.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/db.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/migrations/20251008_init.sql +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/migrations/20251017_objdetcount.sql +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/migrations/apply_migrations.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/migrations/schema_to_rst.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/migrations/scorched_earth.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/migrations/wipe_all_data.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/static/romansnpit.css +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/static/romansnpit.js +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/static/romansnpit_start.js +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/templates/base.html +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/db/templates/romansnpitdb.html +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/dbclient.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/http.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/image.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/image_simulator.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/imagecollection.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/logger.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/provenance.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/psf.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/sed.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/utils.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/snappl/wcs.py +0 -0
- {roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/tox.ini +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Rename l2image mjd_start field to mjd for backwards compatibility
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
=====
|
|
2
|
+
Usage
|
|
3
|
+
=====
|
|
4
|
+
|
|
5
|
+
.. contents::
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
--------
|
|
9
|
+
Overview
|
|
10
|
+
--------
|
|
11
|
+
|
|
12
|
+
``snappl`` has a set of utilities for the Roman SNPIT, including all the classes and functions necessary for communicating with the internal snpit database.
|
|
13
|
+
|
|
14
|
+
If you're here for the SNPIT November 2025 pipeline test, see :ref:`nov2025`.
|
|
15
|
+
|
|
16
|
+
Things you need to understand:
|
|
17
|
+
* :ref:`connecting-to-the-database`
|
|
18
|
+
* :ref:`config`
|
|
19
|
+
* :ref:`provenance`
|
|
20
|
+
|
|
21
|
+
.. _nov2025:
|
|
22
|
+
|
|
23
|
+
----------------------------------------
|
|
24
|
+
November 2025 SNPIT Pipeline Test Primer
|
|
25
|
+
----------------------------------------
|
|
26
|
+
|
|
27
|
+
The database connection is under heavy development, and more things are showing up every day. Right now, the following is available:
|
|
28
|
+
|
|
29
|
+
* Find image L2 images in the database
|
|
30
|
+
* Saving newly discovered DiaObjects to the database
|
|
31
|
+
* Finding DiaObjects
|
|
32
|
+
* Saving updated positions for DiaObjects
|
|
33
|
+
|
|
34
|
+
I *hope* that we will have saving lightcurves and finding lightcurves also available by the November test. How much spectrum saving, and how much characterization saving, is implemented will depend on my time and what we get from those working groups.
|
|
35
|
+
|
|
36
|
+
This section describes what you need to do in order to connect to the database.
|
|
37
|
+
|
|
38
|
+
**WARNING**: because everything is under heavy development, it's possible that interfaces will change. We will try to avoid doing this, because it's a pain when everybody has to adapt, but we're still building this, so it may be inevitable.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
Choose a working environment
|
|
42
|
+
============================
|
|
43
|
+
|
|
44
|
+
Whatever it is, you will need to ``pip install roman-snpit-snappl``. *This package is under heavy development, so you will want to update your install often*. This provides the ``snappl`` modules that you are currently reading the documentation for.
|
|
45
|
+
|
|
46
|
+
**We strongly recommend you develop your code to run in a container. The SNPIT will eventually need to run everything it does in containers.** On your desktop or laptop, you can use Docker. On NERSC, you can use ``podman-hpc``. On many other HPC clusters, you can use Singularity.
|
|
47
|
+
|
|
48
|
+
**WARNING:** The snpit environment does not currently work on ARM architecture machines (because of issues with Galsim and fftw). This means that if you're on a Mac, you're SOL. If you're on a Linux machine, do ``uname -a`` and look towards the end of the output to see if you're on ``x86_64`` or ARM. We hope to resolve this eventually. For now, as much as possible run on ``x86_64`` machines.
|
|
49
|
+
|
|
50
|
+
The SN PIT provides a containerized environment which includes the latest version of snappl at https://github.com/Roman-Supernova-PIT/environment . You can pull the docker image for this environment from one of:
|
|
51
|
+
|
|
52
|
+
* ``registry.nersc.gov/m4385/rknop/roman-snpit-env:cpu``
|
|
53
|
+
* ``registry.nersc.gov/m4385/rknop/roman-snpit-env:cpu-dev``
|
|
54
|
+
* ``registry.nersc.gov/m4385/rknop/roman-snpit-env:cuda``
|
|
55
|
+
* ``registry.nersc.gov/m4385/rknop/roman-snpit-env:cuda-dev``
|
|
56
|
+
* ``rknop/roman-snpit-env:cpu``
|
|
57
|
+
* ``rknop/roman-snpit-env:cpu-dev``
|
|
58
|
+
* ``rknop/roman-snpit-env:cuda``
|
|
59
|
+
* ``rknop/roman-snpit-env:cuda-dev``
|
|
60
|
+
|
|
61
|
+
We recommend you use the ``cpu`` version, unless you need CUDA, in which case try the ``cuda`` version, but you may need the ``cuda-dev`` version (which is terribly bloated).
|
|
62
|
+
|
|
63
|
+
You can, of course, create your own containerized environment for your code to run in, but you will need to support it, and eventually you will need to deliver it for the PIT to run in production. For that reason, we strongly recommend you start trying to use the standard SNPIT environment. Ideally, your code should be pip installable from PyPI, and eventually your code will be included in the environment just like ``snappl`` currently is.
|
|
64
|
+
|
|
65
|
+
Creating a Config
|
|
66
|
+
=================
|
|
67
|
+
|
|
68
|
+
Snappl includes a :ref:`config` system, that we strongly recommend you adapt your code to use, as it interacts with some other systems you will need. In any event, to connect to the database, you are going to need a config file.
|
|
69
|
+
|
|
70
|
+
.. _password-file:
|
|
71
|
+
|
|
72
|
+
Setting up a secure password file
|
|
73
|
+
---------------------------------
|
|
74
|
+
|
|
75
|
+
You will eventually need a password for connecting to the database. **Make sure never to commit passwords to github archives.** You also don't want them sitting around in world-readable files. While there are better solutions, a decent compromise between usability and security is to do the following on any system you run:
|
|
76
|
+
|
|
77
|
+
* Under your home directory, create a secrets directory::
|
|
78
|
+
|
|
79
|
+
cd
|
|
80
|
+
mkdir secrets
|
|
81
|
+
|
|
82
|
+
* Make sure the secrets directory is not world-readable::
|
|
83
|
+
|
|
84
|
+
chmod 710 secrets
|
|
85
|
+
|
|
86
|
+
* Create a file in that secrets directory named ``roman_snpit_ou2024_nov_ou2024nov`` that has one line holding the password for database access. (We will give you this password if you need it.)
|
|
87
|
+
|
|
88
|
+
You will then either point directly from this file (if you are working on the host system) in a configuration variable, or you will bind-mount your secrets directory to ``/secrets`` (if you're working in a container).
|
|
89
|
+
|
|
90
|
+
The minimal config file
|
|
91
|
+
-----------------------
|
|
92
|
+
|
|
93
|
+
You will need to set an environment variable ``SNPIT_CONFIG`` that points to a yaml configuration file.
|
|
94
|
+
|
|
95
|
+
This is the minimal config file to connect to the database for November 2025; save it to a file named ``roman_snpit_ou2024_nov_config.yaml`` (or anything else, but remember what you save it to)::
|
|
96
|
+
|
|
97
|
+
destructive_appends:
|
|
98
|
+
- snpit_ou2024_nersc.yaml
|
|
99
|
+
|
|
100
|
+
system:
|
|
101
|
+
db:
|
|
102
|
+
url: https://c3-sn.lbl.gov/roman_snpit_nov2025
|
|
103
|
+
username: ou2024nov
|
|
104
|
+
password: null
|
|
105
|
+
passwordfile: /secrets/roman_snpit_ou2024_nov_ou2024nov
|
|
106
|
+
|
|
107
|
+
Please resist the temptation to put the password in the ``password:`` field, even though it's hanging out there enticing you. Once somebody commits that password to a git archive, our database can now be accessed by anybody. Once we realize a password has been leaked to a git archive, we'll need to change the password, which will be a hassle for everybody. (We do use this field sometimes in our test suite, where the user is ``test`` and the password is ``test_password``, and because it's never a live accessible database, we don't care.) The value of ``passwordfile`` assumes that you're working inside a container; if not, replace it with the full path to where you created the password file (see :ref:`password-file`).
|
|
108
|
+
|
|
109
|
+
This config file includes the file `snpit_ou2024_nersc.yaml <https://github.com/Roman-Supernova-PIT/environment/blob/main/snpit_ou2024_nersc.yaml>`_. Save that file in the same directory as where you are writing your config file. This assumes you're *not* working in a container, but are working directly on NERSC in a python venv where you've ``pip`` installed ``snappl``. If you're working in a container, then edit the line after ``destructive_appends:`` to read ``- snpit_ou2024_container.yaml``; download that file from `here <https://github.com/Roman-Supernova-PIT/environment/blob/main/snpit_ou2024_container.yaml>`_. You will then need to make sure you bind-mount the right directories to the right places in the container. Ask Rob for help if you're trying to figure out how to do this. Exactly what the directories are will depend on what system you're on.
|
|
110
|
+
|
|
111
|
+
You may well want to include other things in the config; please see :ref:`config` below.
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
Finding Images
|
|
115
|
+
==============
|
|
116
|
+
|
|
117
|
+
The images we will be using for the test run are all available in the database. See the docstring on ``snappl.imagecollection.ImageCollection`` and ``snappl.imagecollection.ImageCollection.find_images`` for detailed documentation. Briefly, you first need to get yourself an image collection::
|
|
118
|
+
|
|
119
|
+
from snappl.dbclient import SNPITDBClient
|
|
120
|
+
from snappl.imagecollection import ImageCollection
|
|
121
|
+
|
|
122
|
+
dbclient = SNPITDBClient()
|
|
123
|
+
imcol = ImageCollection.get_collection( provenance_tag='ou2024', process='load_ou2024_image',
|
|
124
|
+
dbclient=dbclient )
|
|
125
|
+
|
|
126
|
+
See :ref:`provenance` below to understand what ``provenance_tag`` and ``process`` is. We will try to keep this documentation updated with a list of :ref:`nov2025-provtags`.
|
|
127
|
+
|
|
128
|
+
With your image collection in hand, you can find images. If, for instance, you wanted to find all images that included the coordinates RA=7.5510934°, dec=-44.8071811°, you could run::
|
|
129
|
+
|
|
130
|
+
images = imcol.find_images( ra=7.5510934, dec=-44.8071811, dbclient=dbclient )
|
|
131
|
+
|
|
132
|
+
That will return a list of ``snappl.image.Image`` objects. You can read the docstring for that class, but most important is probably the ``path`` attribute that tells you where to find the FITS file. (For this test, we are still using OpenUniverse 2024 FITS Images. Eventually we'll be working with ASDF images.) However, instead of reading the FITS file directly, we recommend working working with the methods Image class, as it has interfaces that will remain the same whether you're reading FITS or ASDF files. For example, if you've used a good enough config file that snappl knows where to look for data, you can get access to the data array with::
|
|
133
|
+
|
|
134
|
+
first_image = images[0]
|
|
135
|
+
image_data = first_image.data
|
|
136
|
+
|
|
137
|
+
(This is a little bit scary, as you can eat up memory using the easiest interfaces. If you're reading multiple images at once, think about that. You can *try* calling ``first_image.free()``, but that's not fully supported for all image types. If you want to manage memory yourself, you can call ``first_image.get_data()`` with ``cache=False``; see the docstring on ``snappl.image.Image.get_data`` for more information.)
|
|
138
|
+
|
|
139
|
+
If you wanted to get a list of all 4500 images in the database, you could just run::
|
|
140
|
+
|
|
141
|
+
images = imcol.find_images( dbclient=dbclient )
|
|
142
|
+
|
|
143
|
+
However, we recommend against that. While 4500 is perhaps not an overwhelming number of images, eventually the number of images is going to be huge, and you aren't going to want to pull them down all at once. (Not only does this give you more than is reasonable to work with, but you will also be using a lot of bandwidth from the database server to pull all that information down. The database server does *not* give you the full images, just metadata, but a million rows of a kilobyte of metadata is already a gigabyte.)
|
|
144
|
+
|
|
145
|
+
Finding Objects
|
|
146
|
+
===============
|
|
147
|
+
|
|
148
|
+
There is also an interface that lets you find objects. For instance, if you want to find all objects within 100 arcseconds of a given location, you could run::
|
|
149
|
+
|
|
150
|
+
from snappl.diaobject import DiaObject
|
|
151
|
+
|
|
152
|
+
objs = DiaObject.find_objects( provenance_tag=TAG, process=PROCESS,
|
|
153
|
+
ra=7.5510934, dec=-44.8071811, radius=100.,
|
|
154
|
+
dbclient=dbclient )
|
|
155
|
+
|
|
156
|
+
Here, you can use ``ou2024`` for ``TAG`` and ``load_ou2024_diaobject`` for ``PROCESS`` to get the objects uploaded from the OpenUniverse 2024 truth tables. However, you may instead want to use a different provenance tag and process to get objects discovered with Sidecar; see :ref:`nov2025-provtags` below. Also, look at the docstring on ``snappl.diaobject.DiaObject.find_objects`` for more information.
|
|
157
|
+
|
|
158
|
+
Getting Better Object Positions
|
|
159
|
+
===============================
|
|
160
|
+
|
|
161
|
+
``DiaObject.find_objects`` will return a list of ``DiaObject`` objects, and these include properties ``ra`` and ``dec``. **However, the positions in the DiaObject object should be viewed as approximate.** They will be the position it had when the object was first discovered. For objects loaded from truth tables, they will be perfect, but of course we won't have truth tables for the real survey. Often, the first discovery will be a relatively low S/N point, and much better positions can be determined; doing so will be one of the jobs of ``phrosty``.
|
|
162
|
+
|
|
163
|
+
To get an improved position for an object, assume you have the object in the variable ``diaobj``. You can then call::
|
|
164
|
+
|
|
165
|
+
position = diaobj.get_position( provenance_tag=TAG, process=PROCESS, dbclient=dbclient )
|
|
166
|
+
|
|
167
|
+
See :ref:`nov2025-provtags` below to figure out what ``TAG`` and ``PROCESS`` should be. You will get back a dictionary with keys:
|
|
168
|
+
|
|
169
|
+
* ``id``
|
|
170
|
+
* ``diaobject_id``
|
|
171
|
+
* ``provenance_id``
|
|
172
|
+
* ``ra``
|
|
173
|
+
* ``dec``
|
|
174
|
+
* ``ra_err``
|
|
175
|
+
* ``dec_err``
|
|
176
|
+
* ``ra_dec_covar``
|
|
177
|
+
* ``calculated_at``
|
|
178
|
+
|
|
179
|
+
**Warning**: the fields ``ra_err``, ``dec_err``, and ``ra_dec_covar`` may be ``None``; this will be the case, for instance, for object positions that were loaded from truth tables rather than determined by software.
|
|
180
|
+
|
|
181
|
+
**Important**: if you use an updated DiaObject position, then the provenance of that position should be one of your upstream provenances; see :ref:`nov2025-making-prov`.
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
Finding Lightcurves
|
|
185
|
+
===================
|
|
186
|
+
|
|
187
|
+
TODO
|
|
188
|
+
|
|
189
|
+
.. _nov2025-making-prov:
|
|
190
|
+
|
|
191
|
+
Making Provenances
|
|
192
|
+
==================
|
|
193
|
+
|
|
194
|
+
Before you save anything to the database, you need to make a :ref:`provenance` for it. For example, consider the difference imaging lightcurve package ``phrosty``. It will need to have a diaobject (let's assume it's in the variable ``obj``), and it will need to have a list of images (let's assume they're in the variable ``images``; we'll leave aside details of template vs. science images for now). Let's assume ``phrosty`` is using the :ref:`config` system in ``snappl``, and has put all of its configuration under ``photometry.phrosty``. (There are details here you must be careful about; things like paths on your current system should *not* go under ``photometry.phrosty``, but should go somewhere underneath ``system.``. The current object and list of images you're working on should not be in the configuration, but should just be passed via command-line parameters. The idea is that the configuration has all of, but only, the things that are the same for a large number of runs on a large number of input files which guarantee (as much as possible) the same output files.)
|
|
195
|
+
|
|
196
|
+
phrosty could then determine its own provenance with::
|
|
197
|
+
|
|
198
|
+
from snappl.config import Config
|
|
199
|
+
from snappl.provenance import Provenance
|
|
200
|
+
|
|
201
|
+
objprov = Provenance.get_by_id( obj.provenance_id, dbclient=dbclient )
|
|
202
|
+
improv = Provenance.get_by_id( images[0].provenance_id, dbclient=dbclient )
|
|
203
|
+
phrostyprov = Provenance( process='phrosty', major=MAJOR, minor=MINOR,
|
|
204
|
+
upstreams=[ objprov, improv ],
|
|
205
|
+
params=Config.get(), omitkeys=None, keepkeys=[ 'photometry.phrosty' ] )
|
|
206
|
+
|
|
207
|
+
See :ref:`provenance` below for more details about what all of this means. Here, ``MAJOR`` and ``MINOR`` are the first two parts of the `semantic version <https://semver.org/>`_ of phrosty.
|
|
208
|
+
|
|
209
|
+
We recommend that phrosty put in its output files, somewhere, in addition to what's obvious:
|
|
210
|
+
|
|
211
|
+
* The ``provenance_id`` for phrosty (obtained from ``phrostyprov.id``).
|
|
212
|
+
* The configuration parameters for phrosty (obtained from ``phrostprov.params`` — a dictionary).
|
|
213
|
+
|
|
214
|
+
(If you're very anal, you may want to save a gigantic dictionary structure including everything from ``phrostyprov`` and everything from all of the upstream provenances, and the upstreams of the upstreams, etc.)
|
|
215
|
+
|
|
216
|
+
**NOTE**: provenance can also store environment and environment version, but we don't have that fully defined yet.
|
|
217
|
+
|
|
218
|
+
Before saving anything to the database, you will need to make sure that the provenance has been saved to the database. If you are sure that you've saved this same Provenance before, you can skip this step, but at some point you will need to::
|
|
219
|
+
|
|
220
|
+
phrostyprov.save_to_db( tag=PROVENANCE_TAG, dbclient=dbclient )
|
|
221
|
+
|
|
222
|
+
where ``PROVENANCE_TAG`` is a string; see :ref:`nov2025-provtags` below for a list of what we plan to use.
|
|
223
|
+
|
|
224
|
+
Saving DiaObjects
|
|
225
|
+
=================
|
|
226
|
+
|
|
227
|
+
This is mostly for Sidecar. If it's found an object and wants to save it, and if it's obtained a Provenance (including the Provenance of the images it was searching as an upstream) in ``sidecarprov``, then it can call::
|
|
228
|
+
|
|
229
|
+
import uuid
|
|
230
|
+
|
|
231
|
+
diaobj = DiaObject( id=uuid.uuid4(), provenance_id=sidecarprov.id,
|
|
232
|
+
ra=RA, dec=DEC, mjd_discovery=MJD, dbclient=dbclient )
|
|
233
|
+
diaobj.save_object( dbclient=None )
|
|
234
|
+
|
|
235
|
+
Read the docstrings on the relevant functions for more details. There is additional information that could be included if available.
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
Saving DiaObject Positions
|
|
239
|
+
==========================
|
|
240
|
+
|
|
241
|
+
If you have an improved position for a DiaObject ``diaobj`` and you want to save it to the database, first you need to make a Provenance (see above) for this position; assume that's in ``diaobj_pos_prov``. You would then do::
|
|
242
|
+
|
|
243
|
+
diaobj.save_updated_position( position_provenance=diaobj_pos_prov, ra=RA, dec=DEC,
|
|
244
|
+
ra_err=RA_ERR, dec_err=DEC_ERR, ra_dec_covar=RA_DEC_COVAR,
|
|
245
|
+
dbclient=dbclient )
|
|
246
|
+
|
|
247
|
+
This will (I believe) return a dictionary that's the same as what you'd get back from ``diaobj.get_position``.
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
Saving Lightcurves
|
|
251
|
+
==================
|
|
252
|
+
|
|
253
|
+
TODO
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
.. _nov2025-provtags:
|
|
258
|
+
|
|
259
|
+
Provenance Tags We Will Use In November 2025
|
|
260
|
+
============================================
|
|
261
|
+
|
|
262
|
+
TODO
|
|
263
|
+
|
|
264
|
+
.. _connecting-to-the-database:
|
|
265
|
+
|
|
266
|
+
--------------------------
|
|
267
|
+
Connecting to the Database
|
|
268
|
+
--------------------------
|
|
269
|
+
|
|
270
|
+
To connect to the database, you need three things. First, you have to know the url of the web API front-end to the database. You must also have a username and a password for that web API. (NOTE: the config system is likely to change in the future, so exactly how this works may change.) If you're using :ref:`test_env`, then the test fixture ``dbclient`` configures a user with username ``test`` and password ``test_password``, and in that environment the url of the web API is ``https://webserver:8080/``.
|
|
271
|
+
|
|
272
|
+
You configure all of these things by setting the ``system.db.url``, ``system.db.username``, and either ``system.db.password`` or ``system.db.password_file`` in the configuration yaml files. (See :ref:`config` below.) For example, see the default `snpit_system_config.yaml <https://github.com/Roman-Supernova-PIT/environment/blob/main/snpit_system_config.yaml>`_ in the Roman SNPIT environment. *Do not save passwords to any git archive, and do not leave them sitting about in insecure places.* Of course, having to type it all the time is a pain. A reasonable compromise is to have a ``secrets`` directory under your home directory **that is not world-readable** (``chown 700 secrets``). Then you can create files in there. Put your password in a file, and set the location of that file in the ``system.db.password_file`` config. (Make ``system.db.password`` to be ``null`` so the password file will be used.) If you're using a docker container, of course you'll need to bind-mount your secrets directory.
|
|
273
|
+
|
|
274
|
+
Once you've configured these things, you should be able to connect to the database. You can get a connection object with::
|
|
275
|
+
|
|
276
|
+
from snappl.dbclient import SNPITDBClient
|
|
277
|
+
|
|
278
|
+
dbclient = SNPITDBClient()
|
|
279
|
+
|
|
280
|
+
Thereafter, you can pass this ``dbclient`` as an optional argument to any ``snappl`` function that accesses the database. (Lots of the examples below do not explicitly include this argument, but you could add it to them.) Most of the functions will create their own ``dbclient`` using the config info as necessary. However, you are logged in when you first create the object, so it's inefficient if every time you call a function it has to log you in (or, at least, verify that you're logged in). If you make a ``dbclient`` and then are careful to pass as a keyword argument to any function that accepts it, you avoid this inefficiency.
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
.. _config:
|
|
284
|
+
|
|
285
|
+
------
|
|
286
|
+
Config
|
|
287
|
+
------
|
|
288
|
+
|
|
289
|
+
`snappl` includes a config system whereby configuration files can be stored in yaml files. It has the ability to include other yaml files, and to override any of the config values on the command line, if properly used.
|
|
290
|
+
|
|
291
|
+
The Default Confg
|
|
292
|
+
=================
|
|
293
|
+
|
|
294
|
+
You can find an example/default config for the Roman SNPIT in two files in the `environment` github repo:
|
|
295
|
+
|
|
296
|
+
* `default_snpit_config.yaml <https://github.com/Roman-Supernova-PIT/environment/blob/main/default_snpit_config.yaml>`_
|
|
297
|
+
* `snpit_system_config.yaml <https://github.com/Roman-Supernova-PIT/environment/blob/main/snpit_system_config.yaml>`_
|
|
298
|
+
|
|
299
|
+
Notice that the first one includes the second one. In the standard Roman SNPIT docker image, these two files are present in the root directory (``/``).
|
|
300
|
+
|
|
301
|
+
Ideally, all config for every SNPIT application will be in this default config file, so we can all use the same config and be sure we know what we're doing. Of course, that's far too cumbersome for development, so during development you will want to make your own config file with just the things you need in it.
|
|
302
|
+
|
|
303
|
+
By convention, everything underneath the ``system`` top level key are the things that you might have to change when moving from one cluster to another cluster, but that don't change the behavior of the code. This includes paths for where to find things, configurations as to where the database is, login credentials, and the like. Everything that is _not_ under ``system`` should be things that define the behavior of your code. These are the things that are the same every you run on different inputs. It should _not_ include things like the specific images or diaobjects you're currently working on. Ideally, everything that's _not_ in system, if it stays the same, will give the same outputs on the same inputs when run anywhere.
|
|
304
|
+
|
|
305
|
+
Using Config
|
|
306
|
+
============
|
|
307
|
+
|
|
308
|
+
To use config, you first have to set the environment variable ``SNIPIT_CONFIG`` to the location of the top-level config file. If you're using the default config and working in the roman snpit docker image, you can do this with::
|
|
309
|
+
|
|
310
|
+
export SNPIT_CONFIG=/default_snpit_config.yaml
|
|
311
|
+
|
|
312
|
+
Then, in your code, to get access to the config, you can just run::
|
|
313
|
+
|
|
314
|
+
from snappl.config import Config
|
|
315
|
+
|
|
316
|
+
...
|
|
317
|
+
|
|
318
|
+
cfg = Config.get()
|
|
319
|
+
tmpdir = Config.value( 'system.paths.temp_dir` )
|
|
320
|
+
|
|
321
|
+
``Config.get()`` gets you a config object. Then, just call that object's ``value`` method to get the actual config values. Separate different levels of dictionaries in the config with periods, as in the example. (Look at ``default_snpit_config.yaml`` to see how the config file corresponds to the value in the example above.)
|
|
322
|
+
|
|
323
|
+
There are more complicated uses of Config (including reading different, custom config files, modifying the config at runtime, understanding how the config files and all the possible modes of including other files are composed). Read the docstring on ``snappl.config.Config`` for more information.
|
|
324
|
+
|
|
325
|
+
Overriding Parameters on the Command Line
|
|
326
|
+
-----------------------------------------
|
|
327
|
+
|
|
328
|
+
At runtime, if you set things up properly, you can override some of the parameters from the config file with command-line arguments. To accomplish this, you must be using python's ``argparse`` package. When you're ready to parse your arguments, write the following code::
|
|
329
|
+
|
|
330
|
+
configparser = argarse.ArgumentParser( add_help=False )
|
|
331
|
+
configparser.add_argument( '-c', '--config-file', default=None,
|
|
332
|
+
help=( "Location of the .yaml config file; defaults to the value of the "
|
|
333
|
+
"SNPIT_CONFIG environment variable." ) )
|
|
334
|
+
args, leftovers = configparser.parse_known_args()
|
|
335
|
+
|
|
336
|
+
try:
|
|
337
|
+
cfg = Config.get( args.config_file, setdefault=True )
|
|
338
|
+
except RuntimeError as e:
|
|
339
|
+
if str(e) == 'No default config defined yet; run Config.init(configfile)':
|
|
340
|
+
sys.stderr.write( "Error, no configuration file defined.\n"
|
|
341
|
+
"Either run <your application name> with -c <configfile>\n"
|
|
342
|
+
"or set the SNPIT_CONFIG environment variable.\n" )
|
|
343
|
+
sys.exit(1)
|
|
344
|
+
else:
|
|
345
|
+
raise
|
|
346
|
+
|
|
347
|
+
parser = argparse.ArgumentParser()
|
|
348
|
+
# Put in the config_file argument, even though it will never be found, so it shows up in help
|
|
349
|
+
parser.add_argument( '-c', '--config-file', help="Location of the .yaml config file" )
|
|
350
|
+
|
|
351
|
+
After that, put all of the ``parser.add_argument`` lines that you need for the command-line arguments to your code. Then, at the bottom, after you're done with all of your ``parser.add_argument`` calls, put in the code::
|
|
352
|
+
|
|
353
|
+
cfg.augment_argparse( parser )
|
|
354
|
+
args = parser.parse_args( leftovers )
|
|
355
|
+
cfg.parse_args( args )
|
|
356
|
+
|
|
357
|
+
At this point in your code, you can get access to the command line arguments you specified with the ``args`` variable as usual. However, the running config (that you get with ``Config.get()``) will _also_ have been updated with any changes made on the command line.
|
|
358
|
+
|
|
359
|
+
If you've set your code up like this, run it with ``--help``. You will see the help on the arguments you defined, but you will also see optional arguments for everything that is in the config file.
|
|
360
|
+
|
|
361
|
+
TODO : make it so you can only include some of the top-level keys from the config file in what gets overridden on the command line, to avoid things getting far too cluttered with irrelevant options.
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
.. _provenance:
|
|
365
|
+
|
|
366
|
+
----------
|
|
367
|
+
Provenance
|
|
368
|
+
----------
|
|
369
|
+
|
|
370
|
+
Everything stored in the internal Roman SNPIT database has a *Provenance* associated with it. The purpose of Provenance is twofold:
|
|
371
|
+
|
|
372
|
+
* It allows us to store multiple versions of the same thing in the database. (E.g., suppose you wanted to build a lightcurve for an object using two different configurations of your photometry software. If the database just stored "the lightcurve for this object", it wouldn't be possible to store both. However, in this case, the two lightcurves would have different provenances, so both can be stored.)
|
|
373
|
+
|
|
374
|
+
* It keeps track of the code and the configuration used to create the thing stored in the database. Ideally, this includes all of the parameters (see below) for the code, in addition to the code and code version, as well as (optionally) information about the environment in which the code should be run, such that we could reproduce the output files by running the same code with the same configuration again.
|
|
375
|
+
|
|
376
|
+
A provenance is defined by:
|
|
377
|
+
|
|
378
|
+
* The ``process`` : this is usually the name of the code that produced the thing saved to the database.
|
|
379
|
+
* The ``major`` and ``minor`` version of the process; Roman SNPIT code should use `semantic versioning <https://semver.org>`_.
|
|
380
|
+
* ``params``, The parameters of the process (see below)
|
|
381
|
+
* Optionally: the ``environment``, and ``env_major`` and ``env_minor``, the major and minor versions of the environment. (By default, these three are all None.)
|
|
382
|
+
* ``upstreams``, the immediate upstream provenances (see below).
|
|
383
|
+
|
|
384
|
+
An id is generated from the provenance based on a hash of all the information in the provenance, available in the ``id`` property of a Provenance object. This id is a ``UUID`` (sort of), and will be something ugly like ``f76f39a2-edcf-4e31-ba6b-e3d4335cc972``. Crucially, every time you create a provenance with all the same information, you will always get exactly the same id.
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
.. _provenance_tags:
|
|
388
|
+
|
|
389
|
+
Provenance Tags
|
|
390
|
+
===============
|
|
391
|
+
|
|
392
|
+
Provenances hold all the necessary information, and as such are cumbersome. Provenance IDs are 128-bit numbers, and are not very human readable. For this reason, we have *provenance tags*, which are human readable, and also allow us to collect together the provenances of a bunch of different processes into a coherent set of data products.
|
|
393
|
+
|
|
394
|
+
A provenance tag is defined by a human-readable string ``tag``, and by the ``process`` (which is the same as the ``process`` of a Provenance.) For a given (``tag``, ``process``) pair, there can only be one Provenance. That means that you can uniquely define a Provenance by its tag and its process.
|
|
395
|
+
|
|
396
|
+
We should be careful not to create tags willy-nilly. Ideally, we will have a small number of provenance tags in the database that correspond to sets of runs through the entire pipeline.
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
Getting Provenances from the Database
|
|
400
|
+
=====================================
|
|
401
|
+
|
|
402
|
+
If, somehow, you got your hands on a ``provenance_id`` (the ugly 128-bit number), and you want to get the full ``Provenance`` object for it, you can accomplish that with::
|
|
403
|
+
|
|
404
|
+
from snappl.provenance import Provenance
|
|
405
|
+
|
|
406
|
+
prov = Provenance.get_by_id( provenance_id )
|
|
407
|
+
|
|
408
|
+
You will find provenance ids in the ``provenance_id`` field of things you pulled out of the database. For example, if you have a ``DiaObject`` object (call it ``obj``) that you got with ``DiaObject.get_object`` or ``DiaObject.find_objects``, then you can find the id of the provenance of that DiaObject in ``obj.provenance_id``.
|
|
409
|
+
|
|
410
|
+
If, instead, you know (e.g. because the user passed this on the command line) that you want to work on the objects that we have chosen to tag with the provenance tag ``realtime``, and the process ``rapid_alerts`` (for instance, these may be objects we learned about from the RAPID alert stream), then you could get the provenance with::
|
|
411
|
+
|
|
412
|
+
prov = Provenance.get_provs_for_tag( 'realtime', 'rapid_alerts' )
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
.. _provenance_parameters:
|
|
416
|
+
|
|
417
|
+
Parameters
|
|
418
|
+
==========
|
|
419
|
+
|
|
420
|
+
The ``params`` field of a Provenance is a dictionary that should include everything necessary for the specified version of your code to produce the same output on the same input. It should *not* include things like input filenames. The idea is that the *same* Provenance will apply to everything that is part of a given run. Only when you are changing the configuration, or when you are getting input files from an earlier part of the pipeline, should the Provenance change.
|
|
421
|
+
|
|
422
|
+
If you are using the :ref:`config` system, and you've put all of these parameters (but no system-specific, like base paths, and no input files) in the config ``yaml`` file, then you can get a suitable ``params`` with::
|
|
423
|
+
|
|
424
|
+
cfg = Config.get()
|
|
425
|
+
params = cfg.dump_to_dict_for_params( keepkeys=[ 'photometry.phrosty' ], omitkeys=None )
|
|
426
|
+
|
|
427
|
+
The list in ``keepkeys`` are the keys (including the full substructure below that key) from the config that you want to include in the dictionary. This allows you to select out the parts of the config that are relevant to your code. ``system`` and anything starting with ``system.`` should never be in ``keepkeys``.
|
|
428
|
+
|
|
429
|
+
.. _provenance_upstreams:
|
|
430
|
+
|
|
431
|
+
Upstreams
|
|
432
|
+
=========
|
|
433
|
+
|
|
434
|
+
The upstream provenances are the ones that created the input files you use. For example, campari has three basic types of inputs: a *diaobject*, the supernova it's running on; a *diaobject_position*, an updated position of the object; and *images*, the images it's fitting its model to. Thus, it would have three upstream provenances, one for each of these things.
|
|
435
|
+
|
|
436
|
+
It can figure out these upstreams by just looking at the ``provenance_id`` field of the objects its using. Again, for example, campari will have (somehow) obtained a ``snappl.diaobject.DiaObject`` object; call that ``diaobj``. It can get the diaobject provenance by just looking at ``diaobj.provenance_id``. (To actually get the full Provenance object from the id, run ``snappl.provenance.Provenance.get_by_id( provenance_id )``.)
|
|
437
|
+
|
|
438
|
+
Upstreams is part of the provenance because even if you run your code with all the same parameters, if you're taking input files that were from a differently configured process earlier in the pipeline, you expect different outputs. Upstreams basically specify which sorts of input files are valid for this provenance.
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
Creating a Provenance
|
|
442
|
+
=====================
|
|
443
|
+
|
|
444
|
+
Just create a provenance with::
|
|
445
|
+
|
|
446
|
+
from snappl.provenance import Provenance
|
|
447
|
+
|
|
448
|
+
prov = Provenance( process, major, minor, params=<params>, upstreams=<upstreams> )
|
|
449
|
+
|
|
450
|
+
In this call, ``process`` is a string, ``major`` and ``minor`` are integers, ``params`` is a dictionary (see :ref:`provenance_parameters`), and ``upstreams`` is a list of ``Provenance`` objects (see :ref:`provenance_upstreams`).
|
|
451
|
+
|
|
452
|
+
If this is a totally new Provenance— you've never made it before— then save it to the database with::
|
|
453
|
+
|
|
454
|
+
prov.save_to_db( tag=<tag> )
|
|
455
|
+
|
|
456
|
+
Here, ``<tag>`` is the :ref:`provenance tag <provenance_tags>` that you want to tag this provenance with. If the provenance already exists in the database, or if another provenance from the same process is already tagged with this tag, you will get an error. If the provenance you're trying to save already exists, that's fine; it won't resave it, it will just notice that it's there. So, this is safe to call even if you aren't sure if you've saved it before or not. If, for some reason, you really want this to be a new provenance, add ``exists=False`` to the call. In that case, if the provenance already exists, an exception will be raised.
|
|
457
|
+
|
|
458
|
+
.. _test_env:
|
|
459
|
+
|
|
460
|
+
--------------------------------
|
|
461
|
+
The Roman SNPIT Test Environment
|
|
462
|
+
--------------------------------
|
|
463
|
+
|
|
464
|
+
(This is currently a bit of a mess, and I haven't figured out how to get this to work on Perlmutter. However, if you're on a desktop or laptop with an ``x86_64`` architecture, then you should be able to get this running on your machine using Docker. Read all the comments at the top of `this file in the environment repo <https://github.com/Roman-Supernova-PIT/environment/blob/main/test-docker-environment/docker-compose.yaml>`_.)
|
{roman_snpit_snappl-0.18.0 → roman_snpit_snappl-0.19.0}/roman_snpit_snappl.egg-info/SOURCES.txt
RENAMED
|
@@ -67,6 +67,8 @@ changes/87.docs.rst
|
|
|
67
67
|
changes/89.feature.rst
|
|
68
68
|
changes/9.snappl.rst
|
|
69
69
|
changes/91.feature.rst
|
|
70
|
+
changes/92.docs.rst
|
|
71
|
+
changes/94.snappl.rst
|
|
70
72
|
docker/postgres/Dockerfile
|
|
71
73
|
docker/postgres/postgresql.conf
|
|
72
74
|
docker/postgres/run_postgres.sh
|
|
@@ -123,6 +125,7 @@ snappl/db/db.py
|
|
|
123
125
|
snappl/db/webserver.py
|
|
124
126
|
snappl/db/migrations/20251008_init.sql
|
|
125
127
|
snappl/db/migrations/20251017_objdetcount.sql
|
|
128
|
+
snappl/db/migrations/20251024_l2image_mjd.sql
|
|
126
129
|
snappl/db/migrations/apply_migrations.py
|
|
127
130
|
snappl/db/migrations/schema_to_rst.py
|
|
128
131
|
snappl/db/migrations/scorched_earth.py
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0,
|
|
31
|
+
__version__ = version = '0.19.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 19, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'g463af9082'
|