roman-snpit-snappl 0.21.0__tar.gz → 0.23.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.21.0 → roman_snpit_snappl-0.23.0}/.github/workflows/changelog.yml +4 -1
  2. {roman_snpit_snappl-0.21.0/roman_snpit_snappl.egg-info → roman_snpit_snappl-0.23.0}/PKG-INFO +1 -1
  3. roman_snpit_snappl-0.23.0/changes/103.snappl.rst +1 -0
  4. roman_snpit_snappl-0.23.0/changes/105.docs.rst +1 -0
  5. roman_snpit_snappl-0.23.0/changes/106.docs.rst +1 -0
  6. roman_snpit_snappl-0.23.0/changes/107.feature.rst +1 -0
  7. roman_snpit_snappl-0.23.0/changes/109.bugfix.rst +1 -0
  8. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/usage.rst +274 -3
  9. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0/roman_snpit_snappl.egg-info}/PKG-INFO +1 -1
  10. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/roman_snpit_snappl.egg-info/SOURCES.txt +8 -0
  11. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/_version.py +3 -3
  12. roman_snpit_snappl-0.23.0/snappl/admin/load_nov2025_truth_diaobjects.py +190 -0
  13. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/admin/load_ou2024_l2images.py +1 -0
  14. roman_snpit_snappl-0.23.0/snappl/admin/load_ou2024_nov2025_segmaps.py +223 -0
  15. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/db.py +12 -2
  16. roman_snpit_snappl-0.23.0/snappl/db/migrations/20251031_posang.sql +5 -0
  17. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/webserver.py +2 -2
  18. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/image.py +48 -6
  19. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/imagecollection.py +6 -2
  20. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/provenance.py +24 -7
  21. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/segmap.py +12 -6
  22. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.cruft.json +0 -0
  23. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/CODEOWNERS +0 -0
  24. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +0 -0
  25. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md +0 -0
  26. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/ISSUE_TEMPLATE/PR_TEMPLATE.md +0 -0
  27. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/dependabot.yml +0 -0
  28. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/labeler.yml +0 -0
  29. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/workflows/run_labeler.yml +0 -0
  30. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/workflows/run_snappl_tests.yml +0 -0
  31. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/workflows/sphinx-deploy.yml +0 -0
  32. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.github/workflows/sub_package_update.yml +0 -0
  33. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.gitignore +0 -0
  34. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/.pre-commit-config.yaml +0 -0
  35. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/CHANGES.rst +0 -0
  36. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/CITATION.cff +0 -0
  37. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/CODE_OF_CONDUCT.md +0 -0
  38. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/CONTRIBUTING.md +0 -0
  39. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/LICENSE +0 -0
  40. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/MANIFEST.in +0 -0
  41. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/README.rst +0 -0
  42. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/.gitkeep +0 -0
  43. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/10.snappl.rst +0 -0
  44. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/13.bugfix.rst +0 -0
  45. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/14.snappl.rst +0 -0
  46. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/15.feature.rst +0 -0
  47. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/16.feature.rst +0 -0
  48. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/18.feature.rst +0 -0
  49. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/20.bugfix.rst +0 -0
  50. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/23.snappl.rst +0 -0
  51. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/26.feature.rst +0 -0
  52. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/29.feature.rst +0 -0
  53. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/3.snappl.rst +0 -0
  54. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/31.feature.rst +0 -0
  55. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/35.snappl.rst +0 -0
  56. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/36.snappl.rst +0 -0
  57. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/37.snappl.rst +0 -0
  58. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/40.snappl.rst +0 -0
  59. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/41.snappl.rst +0 -0
  60. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/43.snappl.rst +0 -0
  61. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/47.feature.rst +0 -0
  62. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/49.docs.rst +0 -0
  63. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/5.snappl.rst +0 -0
  64. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/54.snappl.rst +0 -0
  65. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/57.snappl.rst +0 -0
  66. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/58.snappl.rst +0 -0
  67. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/61.bugfix.rst +0 -0
  68. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/62.snappl.rst +0 -0
  69. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/63.snappl.rst +0 -0
  70. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/65.bugfix.rst +0 -0
  71. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/68.feature.rst +0 -0
  72. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/72.snappl.rst +0 -0
  73. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/73.feature.rst +0 -0
  74. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/74.bugfix.rst +0 -0
  75. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/79.snappl.rst +0 -0
  76. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/8.snappl.rst +0 -0
  77. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/81.snappl.rst +0 -0
  78. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/82.snappl.rst +0 -0
  79. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/83.snappl.rst +0 -0
  80. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/84.feature.rst +0 -0
  81. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/85.feature.rst +0 -0
  82. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/86.snappl.rst +0 -0
  83. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/87.docs.rst +0 -0
  84. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/89.feature.rst +0 -0
  85. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/9.snappl.rst +0 -0
  86. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/91.feature.rst +0 -0
  87. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/92.docs.rst +0 -0
  88. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/94.snappl.rst +0 -0
  89. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/98.docs.rst +0 -0
  90. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/changes/99.feature.rst +0 -0
  91. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/codespell-ignore.txt +0 -0
  92. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/postgres/Dockerfile +0 -0
  93. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/postgres/postgresql.conf +0 -0
  94. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/postgres/run_postgres.sh +0 -0
  95. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/webserver/Dockerfile +0 -0
  96. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/webserver/cert.pem +0 -0
  97. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/webserver/config-test.yaml +0 -0
  98. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/webserver/key.pem +0 -0
  99. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docker/webserver/roman-snpit-server.py +0 -0
  100. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/Makefile +0 -0
  101. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/_static/logo_black_filled.png +0 -0
  102. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/api.rst +0 -0
  103. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/changes.rst +0 -0
  104. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/conf.py +0 -0
  105. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/database_schema.rst +0 -0
  106. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/index.rst +0 -0
  107. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/installation.rst +0 -0
  108. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/docs/make.bat +0 -0
  109. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/experimentation/README.md +0 -0
  110. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/experimentation/ap_phot_simulated_images.py +0 -0
  111. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/experimentation/play_with_photutils.py +0 -0
  112. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/licenses/.DS_Store +0 -0
  113. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/licenses/LICENSE.rst +0 -0
  114. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/licenses/README.rst +0 -0
  115. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/licenses/TEMPLATE_LICENSE.rst +0 -0
  116. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/pyproject.toml +0 -0
  117. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/roman_snpit_snappl.egg-info/dependency_links.txt +0 -0
  118. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/roman_snpit_snappl.egg-info/not-zip-safe +0 -0
  119. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/roman_snpit_snappl.egg-info/requires.txt +0 -0
  120. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/roman_snpit_snappl.egg-info/top_level.txt +0 -0
  121. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/setup.cfg +0 -0
  122. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/setup.py +0 -0
  123. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/__init__.py +0 -0
  124. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/_dev/__init__.py +0 -0
  125. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/_dev/scm_version.py +0 -0
  126. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/admin/load_snana_ou2024_diaobject.py +0 -0
  127. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/config.py +0 -0
  128. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/data/README.rst +0 -0
  129. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/baseview.py +0 -0
  130. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/20251008_init.sql +0 -0
  131. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/20251017_objdetcount.sql +0 -0
  132. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/20251024_l2image_mjd.sql +0 -0
  133. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/20251025_lightcurve.sql +0 -0
  134. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/20251028_segmap.sql +0 -0
  135. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/apply_migrations.py +0 -0
  136. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/schema_to_rst.py +0 -0
  137. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/scorched_earth.py +0 -0
  138. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/migrations/wipe_all_data.py +0 -0
  139. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/static/romansnpit.css +0 -0
  140. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/static/romansnpit.js +0 -0
  141. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/static/romansnpit_start.js +0 -0
  142. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/templates/base.html +0 -0
  143. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/db/templates/romansnpitdb.html +0 -0
  144. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/dbclient.py +0 -0
  145. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/diaobject.py +0 -0
  146. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/http.py +0 -0
  147. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/image_simulator.py +0 -0
  148. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/lightcurve.py +0 -0
  149. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/logger.py +0 -0
  150. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/psf.py +0 -0
  151. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/sed.py +0 -0
  152. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/utils.py +0 -0
  153. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/snappl/wcs.py +0 -0
  154. {roman_snpit_snappl-0.21.0 → roman_snpit_snappl-0.23.0}/tox.ini +0 -0
@@ -23,6 +23,9 @@ jobs:
23
23
  - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
24
24
  with:
25
25
  fetch-depth: 0
26
+ - run: sudo apt-get -y update && sudo apt-get install -y libfftw3-double3
27
+ - run: sudo ln -s /usr/lib/x86_64-linux-gnu/libfftw3.so.3 /usr/lib/libfftw3.so
28
+ - run: ls -l /usr/lib/libff*
26
29
  - run: pip install .
27
30
  - run: pip install towncrier
28
31
  - run: towncrier check
@@ -34,4 +37,4 @@ jobs:
34
37
  with:
35
38
  fetch-depth: 0
36
39
  - name: prevent direct changes to `CHANGES.rst`
37
- run: git diff HEAD ${{ github.event.pull_request.base.sha }} --no-patch --exit-code CHANGES.rst
40
+ run: git diff HEAD ${{ github.event.pull_request.base.sha }} --no-patch --exit-code CHANGES.rst
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roman_snpit_snappl
3
- Version: 0.21.0
3
+ Version: 0.23.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
+ Fix issue #90 (spurious error messages when saving a provenance to database)
@@ -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
  ============================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roman_snpit_snappl
3
- Version: 0.21.0
3
+ Version: 0.23.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,11 @@ 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
32
+ changes/109.bugfix.rst
28
33
  changes/13.bugfix.rst
29
34
  changes/14.snappl.rst
30
35
  changes/15.feature.rst
@@ -122,7 +127,9 @@ snappl/utils.py
122
127
  snappl/wcs.py
123
128
  snappl/_dev/__init__.py
124
129
  snappl/_dev/scm_version.py
130
+ snappl/admin/load_nov2025_truth_diaobjects.py
125
131
  snappl/admin/load_ou2024_l2images.py
132
+ snappl/admin/load_ou2024_nov2025_segmaps.py
126
133
  snappl/admin/load_snana_ou2024_diaobject.py
127
134
  snappl/data/README.rst
128
135
  snappl/db/baseview.py
@@ -133,6 +140,7 @@ snappl/db/migrations/20251017_objdetcount.sql
133
140
  snappl/db/migrations/20251024_l2image_mjd.sql
134
141
  snappl/db/migrations/20251025_lightcurve.sql
135
142
  snappl/db/migrations/20251028_segmap.sql
143
+ snappl/db/migrations/20251031_posang.sql
136
144
  snappl/db/migrations/apply_migrations.py
137
145
  snappl/db/migrations/schema_to_rst.py
138
146
  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.21.0'
32
- __version_tuple__ = version_tuple = (0, 21, 0)
31
+ __version__ = version = '0.23.0'
32
+ __version_tuple__ = version_tuple = (0, 23, 0)
33
33
 
34
- __commit_id__ = commit_id = 'g7a9941597'
34
+ __commit_id__ = commit_id = 'g19a7a9205'
@@ -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()
@@ -54,6 +54,7 @@ def _parse_fits_file( relpath, base_path=None, provid=None ):
54
54
  'height': height,
55
55
  'format': 1,
56
56
  'mjd': image.mjd,
57
+ 'position_angle': image.position_angle,
57
58
  'exptime': exptime,
58
59
  'properties': psycopg.types.json.Jsonb( {} )
59
60
  }