roman-snpit-snappl 0.20.0__tar.gz → 0.22.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.

Files changed (154) hide show
  1. {roman_snpit_snappl-0.20.0/roman_snpit_snappl.egg-info → roman_snpit_snappl-0.22.0}/PKG-INFO +1 -1
  2. roman_snpit_snappl-0.22.0/changes/103.snappl.rst +1 -0
  3. roman_snpit_snappl-0.22.0/changes/105.docs.rst +1 -0
  4. roman_snpit_snappl-0.22.0/changes/106.docs.rst +1 -0
  5. roman_snpit_snappl-0.22.0/changes/107.feature.rst +1 -0
  6. roman_snpit_snappl-0.22.0/changes/98.docs.rst +1 -0
  7. roman_snpit_snappl-0.22.0/changes/99.feature.rst +1 -0
  8. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/usage.rst +327 -7
  9. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0/roman_snpit_snappl.egg-info}/PKG-INFO +1 -1
  10. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/roman_snpit_snappl.egg-info/SOURCES.txt +11 -0
  11. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/_version.py +3 -3
  12. roman_snpit_snappl-0.22.0/snappl/admin/load_nov2025_truth_diaobjects.py +190 -0
  13. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/admin/load_ou2024_l2images.py +1 -0
  14. roman_snpit_snappl-0.22.0/snappl/admin/load_ou2024_nov2025_segmaps.py +223 -0
  15. roman_snpit_snappl-0.22.0/snappl/db/baseview.py +266 -0
  16. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/db.py +23 -3
  17. roman_snpit_snappl-0.22.0/snappl/db/migrations/20251028_segmap.sql +45 -0
  18. roman_snpit_snappl-0.22.0/snappl/db/migrations/20251031_posang.sql +5 -0
  19. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/webserver.py +115 -59
  20. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/diaobject.py +14 -0
  21. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/image.py +48 -6
  22. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/imagecollection.py +6 -2
  23. roman_snpit_snappl-0.22.0/snappl/segmap.py +190 -0
  24. roman_snpit_snappl-0.20.0/snappl/db/baseview.py +0 -88
  25. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.cruft.json +0 -0
  26. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/CODEOWNERS +0 -0
  27. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +0 -0
  28. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +0 -0
  29. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/ISSUE_TEMPLATE/PR_TEMPLATE.md +0 -0
  30. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/dependabot.yml +0 -0
  31. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/labeler.yml +0 -0
  32. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/workflows/changelog.yml +0 -0
  33. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/workflows/run_labeler.yml +0 -0
  34. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/workflows/run_snappl_tests.yml +0 -0
  35. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/workflows/sphinx-deploy.yml +0 -0
  36. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.github/workflows/sub_package_update.yml +0 -0
  37. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.gitignore +0 -0
  38. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/.pre-commit-config.yaml +0 -0
  39. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/CHANGES.rst +0 -0
  40. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/CITATION.cff +0 -0
  41. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/CODE_OF_CONDUCT.md +0 -0
  42. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/CONTRIBUTING.md +0 -0
  43. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/LICENSE +0 -0
  44. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/MANIFEST.in +0 -0
  45. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/README.rst +0 -0
  46. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/.gitkeep +0 -0
  47. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/10.snappl.rst +0 -0
  48. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/13.bugfix.rst +0 -0
  49. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/14.snappl.rst +0 -0
  50. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/15.feature.rst +0 -0
  51. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/16.feature.rst +0 -0
  52. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/18.feature.rst +0 -0
  53. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/20.bugfix.rst +0 -0
  54. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/23.snappl.rst +0 -0
  55. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/26.feature.rst +0 -0
  56. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/29.feature.rst +0 -0
  57. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/3.snappl.rst +0 -0
  58. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/31.feature.rst +0 -0
  59. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/35.snappl.rst +0 -0
  60. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/36.snappl.rst +0 -0
  61. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/37.snappl.rst +0 -0
  62. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/40.snappl.rst +0 -0
  63. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/41.snappl.rst +0 -0
  64. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/43.snappl.rst +0 -0
  65. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/47.feature.rst +0 -0
  66. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/49.docs.rst +0 -0
  67. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/5.snappl.rst +0 -0
  68. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/54.snappl.rst +0 -0
  69. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/57.snappl.rst +0 -0
  70. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/58.snappl.rst +0 -0
  71. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/61.bugfix.rst +0 -0
  72. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/62.snappl.rst +0 -0
  73. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/63.snappl.rst +0 -0
  74. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/65.bugfix.rst +0 -0
  75. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/68.feature.rst +0 -0
  76. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/72.snappl.rst +0 -0
  77. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/73.feature.rst +0 -0
  78. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/74.bugfix.rst +0 -0
  79. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/79.snappl.rst +0 -0
  80. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/8.snappl.rst +0 -0
  81. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/81.snappl.rst +0 -0
  82. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/82.snappl.rst +0 -0
  83. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/83.snappl.rst +0 -0
  84. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/84.feature.rst +0 -0
  85. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/85.feature.rst +0 -0
  86. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/86.snappl.rst +0 -0
  87. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/87.docs.rst +0 -0
  88. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/89.feature.rst +0 -0
  89. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/9.snappl.rst +0 -0
  90. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/91.feature.rst +0 -0
  91. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/92.docs.rst +0 -0
  92. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/changes/94.snappl.rst +0 -0
  93. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/codespell-ignore.txt +0 -0
  94. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/postgres/Dockerfile +0 -0
  95. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/postgres/postgresql.conf +0 -0
  96. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/postgres/run_postgres.sh +0 -0
  97. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/webserver/Dockerfile +0 -0
  98. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/webserver/cert.pem +0 -0
  99. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/webserver/config-test.yaml +0 -0
  100. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/webserver/key.pem +0 -0
  101. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docker/webserver/roman-snpit-server.py +0 -0
  102. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/Makefile +0 -0
  103. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/_static/logo_black_filled.png +0 -0
  104. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/api.rst +0 -0
  105. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/changes.rst +0 -0
  106. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/conf.py +0 -0
  107. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/database_schema.rst +0 -0
  108. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/index.rst +0 -0
  109. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/installation.rst +0 -0
  110. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/docs/make.bat +0 -0
  111. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/experimentation/README.md +0 -0
  112. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/experimentation/ap_phot_simulated_images.py +0 -0
  113. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/experimentation/play_with_photutils.py +0 -0
  114. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/licenses/.DS_Store +0 -0
  115. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/licenses/LICENSE.rst +0 -0
  116. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/licenses/README.rst +0 -0
  117. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/licenses/TEMPLATE_LICENSE.rst +0 -0
  118. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/pyproject.toml +0 -0
  119. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/roman_snpit_snappl.egg-info/dependency_links.txt +0 -0
  120. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/roman_snpit_snappl.egg-info/not-zip-safe +0 -0
  121. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/roman_snpit_snappl.egg-info/requires.txt +0 -0
  122. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/roman_snpit_snappl.egg-info/top_level.txt +0 -0
  123. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/setup.cfg +0 -0
  124. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/setup.py +0 -0
  125. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/__init__.py +0 -0
  126. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/_dev/__init__.py +0 -0
  127. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/_dev/scm_version.py +0 -0
  128. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/admin/load_snana_ou2024_diaobject.py +0 -0
  129. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/config.py +0 -0
  130. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/data/README.rst +0 -0
  131. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/20251008_init.sql +0 -0
  132. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/20251017_objdetcount.sql +0 -0
  133. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/20251024_l2image_mjd.sql +0 -0
  134. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/20251025_lightcurve.sql +0 -0
  135. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/apply_migrations.py +0 -0
  136. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/schema_to_rst.py +0 -0
  137. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/scorched_earth.py +0 -0
  138. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/migrations/wipe_all_data.py +0 -0
  139. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/static/romansnpit.css +0 -0
  140. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/static/romansnpit.js +0 -0
  141. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/static/romansnpit_start.js +0 -0
  142. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/templates/base.html +0 -0
  143. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/db/templates/romansnpitdb.html +0 -0
  144. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/dbclient.py +0 -0
  145. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/http.py +0 -0
  146. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/image_simulator.py +0 -0
  147. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/lightcurve.py +0 -0
  148. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/logger.py +0 -0
  149. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/provenance.py +0 -0
  150. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/psf.py +0 -0
  151. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/sed.py +0 -0
  152. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/utils.py +0 -0
  153. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/snappl/wcs.py +0 -0
  154. {roman_snpit_snappl-0.20.0 → roman_snpit_snappl-0.22.0}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roman_snpit_snappl
3
- Version: 0.20.0
3
+ Version: 0.22.0
4
4
  Summary: General, database, and photometry utilities for the Roman SNPIT
5
5
  Author: Roman Supernova Project Infrastructure Team
6
6
  Maintainer-email: Roman SN PIT <raknop@lbl.gov>
@@ -0,0 +1 @@
1
+ Small changes for Nov 2025 run
@@ -0,0 +1 @@
1
+ Write recipes in Usage docs for the nov2025 run
@@ -0,0 +1 @@
1
+ Config file in docs for nov 2025
@@ -0,0 +1 @@
1
+ Add position_angle to segmap and l2image database tables
@@ -0,0 +1 @@
1
+ Add lightcurve reading and writing to the nov 2025 primer in the usage docs
@@ -0,0 +1 @@
1
+ Add storage and database tracking of segmentation maps
@@ -27,16 +27,287 @@ November 2025 SNPIT Pipeline Test Primer
27
27
  The database connection is under heavy development, and more things are showing up every day. Right now, the following is available:
28
28
 
29
29
  * Find image L2 images in the database
30
+ * Find segmentation maps in the database
30
31
  * Saving newly discovered DiaObjects to the database
31
32
  * Finding DiaObjects
32
33
  * 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
-
34
+ * Saving lightcurves to the database
35
+ * Finding and reading lightcurves from the database
36
+
36
37
  This section describes what you need to do in order to connect to the database.
37
38
 
38
39
  **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
+ Recipes
42
+ =======
43
+
44
+ Read everything to understand what's going on, but these are intended as a quick start.
45
+
46
+ These recipes assume you have a working environment (see :ref:`nov2025-working-env`), which hopefully is as simple as ``pip install roman-snpit-snappl``, but see that section for all the details and where you eventually need to be heading.
47
+
48
+ They also assume you have set up a config file. If you're on NERSC, *not* running in a container, then save `this config file <https://raw.githubusercontent.com/Roman-Supernova-PIT/environment/refs/heads/main/nov2025_nersc_native_config.yaml>`_. (this is the file ``nov2025_nersc_native_config.yaml`` from the top level of the ``environment`` roman snpit github archive). If you are running in a podman container, then look at `this config file <https://raw.githubusercontent.com/Roman-Supernova-PIT/environment/refs/heads/main/nov2025_container_config.yaml>`_ (this is the file ``nov2025_nersc_container_config.yaml`` from the top level of the ``environment`` roman snpit github archive); you will also need to download `interactive-podman-nov2025.sh <https://raw.githubusercontent.com/Roman-Supernova-PIT/environment/refs/heads/main/interactive-podman-nov2025.sh>`_. If you are elsewhere, you will need to edit the config file to have the right paths to find things on your system.
49
+
50
+ You need to set the environment variable ``SNPIT_CONFIG`` to point to where this configuration file lives.
51
+
52
+ Finally, once at the top of your code you need to do::
53
+
54
+ from snappl.dbclient import SNPITDBClient
55
+
56
+ dbclient = SNPITDBClient()
57
+
58
+ Most of the recipes below use the ``dbclient`` variable.
59
+
60
+
61
+ .. _recipe-command-line-args:
62
+
63
+ Command-line Arguments
64
+ ----------------------
65
+
66
+ Below, you will be told you need to know a number of object ids and/or provenance-related values. These will generally be provided by orchestration. You should make them things that can be passed on the command line. I recommend using the following command-line arguments — choose the ones that you need (they are all string values)::
67
+
68
+ --diaobject-id
69
+ --diaobject-provenance-tag
70
+ --diaobject-process
71
+ --diaobject-position-provenance-tag
72
+ --diaobject-position-process
73
+ --image-id
74
+ --image-provenance-tag
75
+ --image-process
76
+ --segmap-provenance-tag
77
+ --segmap-process
78
+ --ltcv-provenance-tag
79
+ --ltcv-process
80
+ --spec1d-provenance-tag
81
+ --spec1d-process
82
+
83
+
84
+ .. _recipe-find-diaobject:
85
+
86
+ Finding a DiaObject
87
+ -------------------
88
+
89
+ You need to know *either* the ``diaobjectd_id`` of the object (which you will generally be given), or you need to know the ``diaobject_provenance_tag`` and ``diaobject_process``, and you must have enough search criteria to find the object. If you're doing the latter, read the docstring on ``snappl.diaobject.DiaObject.find_objects``. For the former::
90
+
91
+ from snappl.diaobject import DiaObject
92
+
93
+ diaobject = DiaObject.get_object( diaobject_id=diaobject_id, dbclient=dbclient )
94
+
95
+ The returned ``DiaObject`` object has, among other things, properties ``.ra`` and ``.dec``.
96
+
97
+
98
+ .. _recipe-diaobject-position:
99
+
100
+ Getting an updated diaobject position
101
+ -------------------------------------
102
+
103
+ You need the ``diaobject_position_provenance_tag`` and ``diaobject_position_process``.
104
+
105
+ Do::
106
+
107
+ diaobj_pos = diaobject.get_position( provenance_tag=diaobject_position_provenance_tag,
108
+ process=diaobject_position_process,
109
+ dbclient=dbclient )
110
+
111
+ You get back a dictionary that has a number of keys including ``ra`` and ``dec``.
112
+
113
+
114
+
115
+
116
+ Getting a Specific Image
117
+ ------------------------
118
+
119
+ ROB IMPLEMENT THIS BETTER
120
+
121
+ Orchestration has given you a ``image_id`` that you are supposed to do something with. E.g.,, you are running sidecar, and you're supposed to subtract and search this image. Right now you also need to know the images's ``image_provenance_tag`` and ``image_process``, but that requirement will go away when Rob fixes it::
122
+
123
+ from snappl.imagecollection import ImageCollection
124
+ from snappl.image import Image
125
+
126
+ collection = ImageCollection.get_collection( provenance_tag=image_provenance_tag,
127
+ process=image_process, dbclient=dbclient )
128
+ image = collection.get_image( image_id=image_id, dbclient=dbclient )
129
+
130
+ You will get back an ``Image`` object. It has a number of properties. Most important are ``.data``, ``.noise``, and ``.flags``, which hold 2d numpy arrays. There is also a ``.get_fits_header()`` method that currently works, **but be careful using this as this method will not work in the future when we're using ASDF files**. See the docstrings in ``snappl.image.Image`` for more details. Some of the stuff you might want is available directly as properties of and ``Image`` object.
131
+
132
+
133
+ Finding Images
134
+ --------------
135
+
136
+ You need to know the ``image_provenance_tag`` and ``image_process``.
137
+
138
+ See the docstring on ``snappl.imagecollection.ImageCollection.find_images`` if you want to do more than what's below.
139
+
140
+
141
+ Finding all images that include a ra and dec
142
+ ********************************************
143
+
144
+ Do::
145
+
146
+ from snappl.imagecollection import ImageCollection
147
+
148
+ collection = ImageCollection.get_collection( provenance_tag=image_provenance_tag,
149
+ process=image_process, dbclient=dbclient )
150
+ images = collection.find_images( ra=ra, dec=dec, band=band, dbclient=dbclient )
151
+
152
+ where ``band=band`` is optional but often useful. You will get back a list of ``Image`` objects, which have a number of properties. Most important are ``.data``, ``.noise``, and ``.flags``, which hold 2d numpy arrays. There is also a ``.get_fits_header()`` method that currently works, **but be careful using this as this method will not work in the future when we're using ASDF files**. See the docstrings in ``snappl.image.Image`` for more details.
153
+
154
+ Finding Segmentation Maps
155
+ -------------------------
156
+
157
+ You need to know the ``segmap_provenance_tag`` and the ``segmap_process``.
158
+
159
+ See the dockstring on ``snappl.segmap.SegmentationMap.find_segmaps`` for more information on searches you can do beyond what's below.
160
+
161
+ Finding all segmaps that include a ra and dec
162
+ *********************************************
163
+
164
+ Do::
165
+
166
+ from snappl.segmap import SegmentationMap
167
+
168
+ segmaps = SegmentationMap.find_segmaps( provenance_tag=segmap_provenance_tag,
169
+ process=segmap_process,
170
+ ra=ra, dec=dec,
171
+ dbclient=dbclient )
172
+
173
+ You get back a list of ``SegmentationMap`` objects. These have a number of properties, most import of which is ``image``, which holds an ``Image`` object. You can get the image data for the segmentation map for the first element of the list with ``segmaps[0].image.data`` (a 2d numpy array).
174
+
175
+
176
+ Saving a new DiaObject
177
+ ----------------------
178
+
179
+ You are running sidecar and you've found a new diaobject you want to save. You need a ``process`` (we shall assume ``process='sidecar'`` here), the ``major`` and ``minor`` version of your code, and the ``params`` that define how the code runs. The latter is just a dictionary; you can build it yourself, but see :ref:`nov2025-making-prov` below. Finally, assume that ``images`` is an list that has the ``snappl.image.Image`` objects of the images that you've used; replace ``images[0]`` below with wherever you have your ``Image`` object::
180
+
181
+ from snappl.provenance import Provenance
182
+ from snappl.diaobject import DiaObject
183
+
184
+ imageprov = Provenance.get_by_id( images[0].provenance_id, dbclient=dbclient )
185
+ prov = Provenance( process='sidecar', major=major, minor=minor, params=params,
186
+ upstreams=[ imageprov ] )
187
+ # You only have to do this next line once for a given provenance;
188
+ # once the provenance is in the databse, you never need to save it again.
189
+ prov.save_to_db( tag=diaobject_provenance_tag, dbclient=dbclient ) # See note below
190
+
191
+ diaobj = DiaObject( provenance_id=prov.id, ra=ra, dec=dec, name=optional, mjd_discovery=mjd )
192
+ diaobj.save_object( dbclient=dbclient )
193
+
194
+
195
+ *Note*: right now, you'll get exceptions on the ``prov.save_to_db`` line, but it probaby did work. There is a snappl issue out for Rob to fix this.
196
+
197
+ This will save the object to the database. You can then look at ``diaobj.id`` to see what UUID it was assigned. You do not need to give it a ``name``, but you can if you want to. (The database uses the ``id`` as the unique identifier.) ``mjd_discovery`` should be the MJD of the science image that the object was found on.
198
+
199
+ Finding and reading lightcurves
200
+ -------------------------------
201
+
202
+ You need to know the ``ltcv_provenance_tag`` and ``ltcv_process``, and the ``diaobject_id`` of the object for which you want to get lightcurves::
203
+
204
+ from snappl.lightcurve import Lightcurve
205
+
206
+ ltcvs = Lightcurve.find_lightcurves( provenance_tag=ltcv_provenance_tag,
207
+ process=ltcv_process,
208
+ diaobject=diaobject_id,
209
+ band=band, # optional
210
+ dbclient=dbclient )
211
+
212
+ You will get back a list of ``Lightcurve`` objects. You can find the actual lightcurve data of the first lightcurve from the list with ``ltcvs[0].lightcurve``. This is an astropy QTable. You can read the metadata from ``ltcvs[0].lightcurve.meta``.
213
+
214
+ **Coming soon**: a way to read a combined lightcurve that has all of the bands mixed together. (Not implemented yet.)
215
+
216
+
217
+ Saving lightcurves
218
+ ------------------
219
+
220
+ You need to make sure you've created a dictionary with `all the necessary metadata <https://github.com/Roman-Supernova-PIT/Roman-Supernova-PIT/wiki/lightcurve>`_. Also make sure you've created a data table with the necessary columns; this can be an astropy Table, a pandas DataFrame, or a dict of lists. We shall call these two things ``meta`` and ``data``.
221
+
222
+ Assume that you've made the lightcurve for object ``diaobject`` (a ``DiaObject`` object), and that you have a list of your images in ``images``. Adjust below for the variables where you really have things. Finally, if you used an updated :ref:`DiaObject position <recipe-diaobject-position>`, make sure you have set the ``ra`` and ``dec`` in ``meta`` from that.
223
+
224
+ Finally, you will need to know the ``ltcv_provenance_tag`` we're using.
225
+
226
+ Below, ``process`` is probably either ``campari`` or ``phrosty``. ``major`` and ``minor`` are the major and minor parts of the version, which you should parse from ``campari.__version__`` or ``phrosty.__version__``. ``params`` are the parameters as described below in :ref:`nov2025-making-prov`.
227
+
228
+ Do::
229
+
230
+ from snappl.provenance import Provenance
231
+ from snappl.lightcurve import Lightcurve
232
+
233
+ imgprov = Provenance.get_by_id( images[0].provenance_id, dbclient=dbclient )
234
+ objprov = Provenance.get_by_id( diaobject.provenance_id, dbclient=dbclient )
235
+ objposprov = Provenance.get_by_id( diaobj_pos['provenance_id'] )
236
+
237
+ ltcvprov = Provenance( process=process, major=major, minor=minor, params=params,
238
+ upstreams=[imgprov, objprov, objposprov], dbclient=dbclient )
239
+ # The next line only needs to be run once. Once you've saved it to the database,
240
+ # you never need to do this again.
241
+ ltcvprov.save_to_db( tag=ltcv_provenance_tag )
242
+
243
+ meta['provenance_id'] = ltcvprov.id
244
+ meta['diaobject_id'] = diaobject.id
245
+ meta['diaobject_position_id'] = diaobj_pos['id']
246
+ for att in [ 'ra', 'dec', 'ra_err', 'dec_err', 'ra_dec_covar' ]:
247
+ meta[att] = diaobj_pos[att]
248
+
249
+ ltcv = Lightcurve( data=data, meta=meta )
250
+ ltcv.write()
251
+ ltcv.save_to_db( dbclient=dbclient )
252
+
253
+ You can look at ``ltcv.id`` to see the ``UUID`` of the lightcurve you saved, in case you are curious.
254
+
255
+ If you used the ``ra`` and ``dec`` that was in ``DiaObject``, then ``meta['diaobject_position_id']`` should be ``None``. Skip everything else above that refers to ``diaobj_pos``.
256
+
257
+
258
+
259
+ Finding and reading 1d Spectra
260
+ ------------------------------
261
+
262
+ (Not implemented yet.)
263
+
264
+ Saving 1d Spectra
265
+ -----------------
266
+
267
+ **Warning: this is not implemented yet. When it is, the process will look *something* like hte following.**
268
+
269
+ You need to have the ``diaobject`` (a ``DiaObject`` object) for which you made the spectrum, potentially a ``diaobj_pos``, an improved position for the object, and ``images``, a list of ``Image`` object that held the dispersed images from which you are making the spectrum. You need to know the ``spec1d_provenance_tag``.
270
+
271
+ You need to know the ``process`` (which is probably just the name of your code), and the ``major`` and ``minor`` versions of your code. Finally, you need to know the ``params`` that define how your code runs. The latter is just a dictionary; you can build it yourself, but see :ref:`nov2025-making-prov` below.
272
+
273
+ You build a data structure that is described on `the wiki <https://github.com/Roman-Supernova-PIT/Roman-Supernova-PIT/wiki/spectrum_1d>`_; call that ``spec_struct``. Some of lines below make sure that some of this metadata is right.
274
+
275
+ Do::
276
+
277
+ from snappl.provenance import Provenance
278
+ from snappl.spec1d import Spectrum1d
279
+
280
+ diaobj_prov = Provenance.get_by_id( diaobject.provenance_id, dbclient=dbclient )
281
+ imageprov = Provenance.get_by_id( images[0].provenance_id, dbclient=dbclient )
282
+ diaobj_pos_prov = Provenance.get_by_id( diaobj_pos['id'], dbclient=dbclient )
283
+
284
+ spec1d_prov = Provenance( process=process, major=major, minor=minor, params=params,
285
+ upstreams=[ diaobj_prov, imageprov, diaobj_pos_prov ] )
286
+ # The next line only needs to be run once. Once
287
+ # you have saved a Provenance to the databse you
288
+ # never need to save it again
289
+ spec1d_prov.save_to_db( tag=spec1d_provenance_tag, dbclient-dbclient )
290
+
291
+ spec_struct['meta']['provenance_id'] = spec1d_prov.id
292
+ spec_struct['meta']['diaobject_id'] = diaobject.id
293
+ spec_struct['meta']['diaobject_position_id'] = diaobj_pos['id']
294
+ spec_struct['meta']['image_ids'] = [ i.id for i in images ]
295
+
296
+ # Make sure that all (but see below) of the other mandatory metadata is there
297
+
298
+ spec1d = Spectrum1d( spec_struct )
299
+ spec1d.write()
300
+ spec1d.save_to_db( dbclient=dbclient )
301
+
302
+
303
+ You do *not* need to set ``meta['id']`` or ``meta['filepath']`` yourself; those will be set automatically when you save the sepctrum.
304
+
305
+ Note that when you create a ``Spectrum1d``, it will keep a *copy* of the ``spec_struct`` object you passed in its ``spec_struct`` property. It will also modify this object, in particular, setting the ``id`` when the ``Specrtrum1d`` object is constructed, and setting the ``filepath`` when it is saved.
306
+
307
+
308
+
309
+
310
+ .. _nov2025-working-env:
40
311
 
41
312
  Choose a working environment
42
313
  ============================
@@ -145,6 +416,14 @@ However, we recommend against that. While 4500 is perhaps not an overwhelming n
145
416
  Finding Objects
146
417
  ===============
147
418
 
419
+ You may just be given an diaobject id. In that case, all you have to do is::
420
+
421
+ from snappl.diaobject import DiaObject
422
+
423
+ obj = DiaObject.get_object( diaobject_id=<id> )
424
+
425
+ where ``<id>`` is the diaobject id you were given. ``obj`` will be a ``DiaObject`` object.
426
+
148
427
  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
428
 
150
429
  from snappl.diaobject import DiaObject
@@ -158,7 +437,7 @@ Here, you can use ``ou2024`` for ``TAG`` and ``load_ou2024_diaobject`` for ``PRO
158
437
  Getting Better Object Positions
159
438
  ===============================
160
439
 
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``.
440
+ The ``DiaObject`` you got from ``DiaObject.get_object`` or ``DiaObject.find_object`` 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
441
 
163
442
  To get an improved position for an object, assume you have the object in the variable ``diaobj``. You can then call::
164
443
 
@@ -181,10 +460,36 @@ See :ref:`nov2025-provtags` below to figure out what ``TAG`` and ``PROCESS`` sho
181
460
  **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
461
 
183
462
 
184
- Finding Lightcurves
463
+ Reading Lightcurves
185
464
  ===================
186
465
 
187
- TODO
466
+ To read a lightcurve, you need three or four things:
467
+
468
+ * The ``diaobject_id`` of the object whose lightcurve you want
469
+ * The ``provenance_tag`` of the provenance you want to get lightcurves from
470
+ * The ``process`` to go with the provenance tag
471
+ * (Optional) The ``band`` of the lightcurve
472
+
473
+ The ``provenance_tag`` and ``process`` will be given to you through our fake orchestration process, and may possibly be found in :ref:`nov2025-provtags`. The ``diaobject_id`` will be given to you through the fake orchestration process.
474
+
475
+ To get the lightcurves::
476
+
477
+ from snappl.lightcurve import Lightcurve
478
+
479
+ ltcvs = Lightcurve.find_lightcurves( <diaobject_id>, provenance_tag=<tag>, process=<proc>, dbclient=dbclient )
480
+
481
+ That will return a list of lightcurves. If you also specify ``band=<band>``, that will be a 1-element list with the lightcurve just for that band. (Or a 0-element list if it's not found.)
482
+
483
+ Each element of the list will be a ``Lightcurve`` object. You can find the actual lightcurve data in the ``.lightcurve`` property as an astropy QTable. You can find the metadata dictionary either in the ``.lightcurve.meta`` or in the ``.meta`` property (though the latter will intially be ``None`` until you access the ``.lightcurve`` property). Guaranteed metadata can be found in the `lightcurve schema specification on the PIT wiki <https://github.com/Roman-Supernova-PIT/Roman-Supernova-PIT/wiki/lightcurve>`_. You should probably ignore the ``filepath`` in the metadata, because ``snappl`` has already read the file for you (and put it in the ``.lightcurve`` property).
484
+
485
+
486
+ Finding Segmentation Maps
487
+ =========================
488
+
489
+ You will need to ``from snappl.segmap import SegmentationMap`` and then call ``SegmentationMap.find_segmaps``. You need to pass a provenance tag and a process to ``find_segmaps``; you will be given these (see :ref:`nov2025-provtags`). Beyond that, look at the docstring for that function to see what you can search on.
490
+
491
+ You will get back a list of ``SegmentationMap`` objects. A ``SegmentationMap`` object has several attributes, including ``band``, and eight attributes ``ra_corner_00``, ``dec_corner_00``, etc., where ``00`` is the lower-left pixel, ``01`` upper-left pixel, ``10`` is the lower-right pixel, and ``11`` is the upper-right pixel. The most important field is ``.image``. This is a ``snappl.image.Image`` object. You can get the 2d numpy array of the image data of the segmentaton map from the ``.data`` property of the ``Image`` object.
492
+
188
493
 
189
494
  .. _nov2025-making-prov:
190
495
 
@@ -250,9 +555,24 @@ This will (I believe) return a dictionary that's the same as what you'd get back
250
555
  Saving Lightcurves
251
556
  ==================
252
557
 
253
- TODO
558
+ Lightcurves saved to the database are for only a single band. If you have a multiband lightcurve, from the point of view of the database that's several different lightcurves.
559
+
560
+ To write a Lightcurve, first create a ``Lightcurve`` object::
561
+
562
+ from snappl.lightcurve import Lightcurve
563
+
564
+ ltcv = Lightcurve( data=<data>, meta=<meta> )
565
+
566
+ where ``<meta>`` is a dictionary with metadata, and ``<data>`` is one of an astropy Table, a pandas DataFrame, or a dictionary of lists. On the `lightcurve schema specification on the PIT wiki <https://github.com/Roman-Supernova-PIT/Roman-Supernova-PIT/wiki/lightcurve>`_ you can find the mandatory fields in the metadata dictionary; it's allowed to have additional ones as well. Likewise, there you can find the mandatory columns (and the order of those columns) in the data array. You may also have additional columns in that data array.
567
+
568
+ In order to create a lightcurve, you will need to make a provenance for it; see :ref:`nov2025-making-prov`. Make sure to include the ``diaobject position`` provenance as an upstream provenance if you used a position other than the cheesy approximate one that comes with the ``DiaObject``.
569
+
570
+ Once you have your lightcurve object, do two things::
254
571
 
572
+ ltcv.write()
573
+ ltcv.save_to_db( dbclient=dbclient )
255
574
 
575
+ The first one writes the actual file; it will write it in the standard location, and will populate the ``.filepath`` property with the location of the file *relative to the configured base directory for lightcurves* (which is in config option ``system.paths.lightcurves``). The second call saves a record to the database with information about your lightcurve.
256
576
 
257
577
  .. _nov2025-provtags:
258
578
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roman_snpit_snappl
3
- Version: 0.20.0
3
+ Version: 0.22.0
4
4
  Summary: General, database, and photometry utilities for the Roman SNPIT
5
5
  Author: Roman Supernova Project Infrastructure Team
6
6
  Maintainer-email: Roman SN PIT <raknop@lbl.gov>
@@ -25,6 +25,10 @@ tox.ini
25
25
  .github/workflows/sub_package_update.yml
26
26
  changes/.gitkeep
27
27
  changes/10.snappl.rst
28
+ changes/103.snappl.rst
29
+ changes/105.docs.rst
30
+ changes/106.docs.rst
31
+ changes/107.feature.rst
28
32
  changes/13.bugfix.rst
29
33
  changes/14.snappl.rst
30
34
  changes/15.feature.rst
@@ -70,6 +74,8 @@ changes/9.snappl.rst
70
74
  changes/91.feature.rst
71
75
  changes/92.docs.rst
72
76
  changes/94.snappl.rst
77
+ changes/98.docs.rst
78
+ changes/99.feature.rst
73
79
  docker/postgres/Dockerfile
74
80
  docker/postgres/postgresql.conf
75
81
  docker/postgres/run_postgres.sh
@@ -115,11 +121,14 @@ snappl/logger.py
115
121
  snappl/provenance.py
116
122
  snappl/psf.py
117
123
  snappl/sed.py
124
+ snappl/segmap.py
118
125
  snappl/utils.py
119
126
  snappl/wcs.py
120
127
  snappl/_dev/__init__.py
121
128
  snappl/_dev/scm_version.py
129
+ snappl/admin/load_nov2025_truth_diaobjects.py
122
130
  snappl/admin/load_ou2024_l2images.py
131
+ snappl/admin/load_ou2024_nov2025_segmaps.py
123
132
  snappl/admin/load_snana_ou2024_diaobject.py
124
133
  snappl/data/README.rst
125
134
  snappl/db/baseview.py
@@ -129,6 +138,8 @@ snappl/db/migrations/20251008_init.sql
129
138
  snappl/db/migrations/20251017_objdetcount.sql
130
139
  snappl/db/migrations/20251024_l2image_mjd.sql
131
140
  snappl/db/migrations/20251025_lightcurve.sql
141
+ snappl/db/migrations/20251028_segmap.sql
142
+ snappl/db/migrations/20251031_posang.sql
132
143
  snappl/db/migrations/apply_migrations.py
133
144
  snappl/db/migrations/schema_to_rst.py
134
145
  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.20.0'
32
- __version_tuple__ = version_tuple = (0, 20, 0)
31
+ __version__ = version = '0.22.0'
32
+ __version_tuple__ = version_tuple = (0, 22, 0)
33
33
 
34
- __commit_id__ = commit_id = 'g3f6286e64'
34
+ __commit_id__ = commit_id = 'gb84fe5a43'
@@ -0,0 +1,190 @@
1
+ import re
2
+ import uuid
3
+ import simplejson
4
+ import pathlib
5
+ import functools
6
+ import argparse
7
+ import multiprocessing
8
+
9
+ import pandas
10
+ import shapely
11
+
12
+ from snappl.logger import SNLogger
13
+ from snappl.utils import SNPITJsonEncoder
14
+ import snappl.db.db
15
+
16
+
17
+ def load_snana_ou2024_diaobject( provid, polys, pqf, logevery=100, dbcon=None ):
18
+ match = re.search( r'^snana_([0-9]+)\.parquet$', pqf.name )
19
+ if match is None:
20
+ raise ValueError( f"Failed to parse filename {match}" )
21
+ healpix = int( match.group(1) )
22
+ df = pandas.read_parquet( pqf )
23
+
24
+ thingstoinsert = []
25
+ nloaded = 0
26
+ for n, row in enumerate( df.itertuples() ):
27
+ if n % logevery == 0:
28
+ SNLogger.info( f"File {pqf.name}, {n} of {len(df)} done, {nloaded} prepped for load" )
29
+
30
+ params = { k: v for k, v in zip( row.model_param_names, row.model_param_values ) }
31
+
32
+ included = False
33
+ for polydex, poly in enumerate( polys ):
34
+ # if polydex % 500 == 0:
35
+ # SNLogger.info( f"...evaluating polygon {polydex} of {len(polys)}" )
36
+ if poly.contains( shapely.Point( row.ra, row.dec ) ):
37
+ # import random
38
+ # import remote_pdb; remote_pdb.RemotePdb('127.0.0.1', random.randint(4000,60000) ).set_trace()
39
+ included = True
40
+ break
41
+
42
+ if not included:
43
+ continue
44
+
45
+ subdict = { 'id': uuid.uuid4(),
46
+ 'provenance_id': provid,
47
+ 'name': str(row.id),
48
+ 'iauname': None,
49
+ 'ra': float(row.ra),
50
+ 'dec': float(row.dec),
51
+ 'mjd_discovery': float(row.start_mjd),
52
+ 'mjd_peak': float(row.peak_mjd),
53
+ 'mjd_start': float(row.start_mjd),
54
+ 'mjd_end': float(row.end_mjd),
55
+ 'ndetected': 2,
56
+ 'properties': simplejson.dumps(
57
+ { 'healpix': healpix,
58
+ 'host_id': int(row.host_id),
59
+ 'gentype': int(row.gentype),
60
+ 'model_name': row.model_name,
61
+ 'z_cmb': float(row.z_CMB),
62
+ 'mw_ebv': float(row.mw_EBV),
63
+ 'mw_extinction_applied': float(row.mw_extinction_applied),
64
+ 'av': float(row.AV),
65
+ 'rv': float(row.RV),
66
+ 'v_pec': float(row.v_pec),
67
+ 'host_ra': float(row.host_ra),
68
+ 'host_dec': float(row.host_dec),
69
+ 'host_mag_g': float(row.host_mag_g),
70
+ 'host_mag_i': float(row.host_mag_i),
71
+ 'host_mag_f': float(row.host_mag_F),
72
+ 'host_sn_sep': float(row.host_sn_sep),
73
+ 'peak_mjd': float(row.peak_mjd),
74
+ 'peak_mag_g': float(row.peak_mag_g),
75
+ 'peak_mag_i': float(row.peak_mag_i),
76
+ 'peak_mag_f': float(row.peak_mag_F),
77
+ 'lens_dmu': float(row.lens_dmu),
78
+ 'lens_dmu_applied': bool(row.lens_dmu_applied),
79
+ 'model_params': params },
80
+ sort_keys=True,
81
+ cls=SNPITJsonEncoder )
82
+ }
83
+ thingstoinsert.append( subdict )
84
+ nloaded += 1
85
+
86
+ snappl.db.db.DiaObject.bulk_insert_or_upsert( thingstoinsert, dbcon=dbcon )
87
+
88
+ return len( thingstoinsert )
89
+
90
+
91
+ def get_rects( dbcon=None ):
92
+ with snappl.db.db.DBCon( dictcursor=True ) as dbcon:
93
+ rows = dbcon.execute( "SELECT ra_corner_00, ra_corner_01, ra_corner_10, ra_corner_11,"
94
+ " dec_corner_00, dec_corner_01, dec_corner_10, dec_corner_11 "
95
+ "FROM l2image" )
96
+ polys = []
97
+ for row in rows:
98
+ polys.append( shapely.Polygon( ( (row['ra_corner_00'], row['dec_corner_00']),
99
+ (row['ra_corner_01'], row['dec_corner_01']),
100
+ (row['ra_corner_11'], row['dec_corner_11']),
101
+ (row['ra_corner_10'], row['dec_corner_10']),
102
+ (row['ra_corner_00'], row['dec_corner_00'])
103
+ )
104
+ ) )
105
+ return polys
106
+
107
+
108
+
109
+ def main():
110
+ parser = argparse.ArgumentParser( 'load_snana_ou2024_diaobject',
111
+ description='Load all parquet files below a directory.' )
112
+ parser.add_argument( '-p', '--provid', required=True, help="Provenance id" )
113
+ parser.add_argument( '-n', '--nprocs', type=int, default=12,
114
+ help="Number of processes to run at once [default: 12]" )
115
+ parser.add_argument( 'basedir', help='Base directory.' )
116
+ args = parser.parse_args()
117
+
118
+ with snappl.db.db.DBCon( dictcursor=True ) as dbcon:
119
+ rows = dbcon.execute( "SELECT * FROM provenance WHERE id=%(id)s", { 'id': args.provid } )
120
+ if len(rows) == 0:
121
+ raise ValueError( "Invalid provenance {args.provid}" )
122
+ SNLogger.info( f"Loading provenance for process {rows[0]['process']} {rows[0]['major']}.{rows[0]['minor']}" )
123
+
124
+ SNLogger.info( "Creating shapely polygons of image footprints...." )
125
+ polys = get_rects()
126
+ SNLogger.info( f"...have {len(polys)} polygons." )
127
+
128
+ # First, collect all the parquet files
129
+
130
+ def find_pqfiles( direc ):
131
+ pqfiles = []
132
+ subdirs = []
133
+ for f in direc.iterdir():
134
+ f = f.resolve()
135
+ if ( f.name[:5] == 'snana') and ( f.name[-8:] == '.parquet' ):
136
+ pqfiles.append( f )
137
+ elif f.is_dir():
138
+ subdirs.append( f )
139
+
140
+ for subdir in subdirs:
141
+ pqfiles.extend( find_pqfiles( subdir ) )
142
+
143
+ return pqfiles
144
+
145
+ basedir = pathlib.Path( args.basedir )
146
+ pqfiles = find_pqfiles( basedir )
147
+ SNLogger.info( f"{len(pqfiles)} parquet files to load" )
148
+ SNLogger.debug( f"All pqfiles we're going to do: {pqfiles}" )
149
+
150
+ # Launch parallel processes to load these files
151
+
152
+ did = []
153
+ tot = 0
154
+
155
+ def add_to_did( n ):
156
+ nonlocal tot, did
157
+ tot += n
158
+ did.append( n )
159
+ SNLogger.info( f"Completed {len(did)} of {len(pqfiles)} parquet files ({tot} objects)" )
160
+
161
+ errors = []
162
+
163
+ def omg( e ):
164
+ nonlocal errors
165
+ SNLogger.error( f"Subprocess returned error: {e}" )
166
+ errors.append( e )
167
+
168
+ do_load = functools.partial( load_snana_ou2024_diaobject, args.provid, polys )
169
+
170
+ if args.nprocs > 1:
171
+ with multiprocessing.Pool( args.nprocs ) as pool:
172
+ for pqf in pqfiles:
173
+ pool.apply_async( do_load, [ pqf ], callback=add_to_did, error_callback=omg )
174
+ pool.close()
175
+ pool.join()
176
+ else:
177
+ for pqf in pqfiles:
178
+ add_to_did( do_load( pqf ) )
179
+
180
+ if len(errors) > 0:
181
+ nl = '\n'
182
+ SNLogger.error( f"There were errors:\n{nl.join(str(e) for e in errors)}" )
183
+ raise RuntimeError( "There were errors!" )
184
+
185
+ SNLogger.info( f"Loaded {tot} objects in {len(did)} parquet files." )
186
+
187
+
188
+ # ======================================================================
189
+ if __name__ == "__main__":
190
+ main()