pz-rail-astro-tools 1.0.3__tar.gz → 1.0.5__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 pz-rail-astro-tools might be problematic. Click here for more details.

Files changed (52) hide show
  1. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/PKG-INFO +2 -1
  2. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/pyproject.toml +1 -0
  3. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/pz_rail_astro_tools.egg-info/PKG-INFO +2 -1
  4. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/pz_rail_astro_tools.egg-info/SOURCES.txt +6 -1
  5. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/pz_rail_astro_tools.egg-info/requires.txt +1 -0
  6. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/astro_tools/__init__.py +2 -1
  7. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/astro_tools/_version.py +2 -2
  8. pz_rail_astro_tools-1.0.5/src/rail/creation/degraders/bl_demo.ipynb +206 -0
  9. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/creation/degraders/photometric_errors.py +22 -5
  10. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/creation/degraders/spectroscopic_degraders.py +9 -4
  11. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/creation/degraders/spectroscopic_selections.py +11 -11
  12. pz_rail_astro_tools-1.0.5/src/rail/creation/degraders/unrec_bl_model.py +98 -0
  13. pz_rail_astro_tools-1.0.5/src/rail/pipelines/degradation/apply_phot_errors.py +73 -0
  14. pz_rail_astro_tools-1.0.5/src/rail/pipelines/degradation/blending.py +28 -0
  15. pz_rail_astro_tools-1.0.5/src/rail/pipelines/degradation/spectroscopic_selection_pipeline.py +75 -0
  16. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/tools/photometry_tools.py +26 -21
  17. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/tests/astro_tools/test_degraders.py +42 -1
  18. pz_rail_astro_tools-1.0.5/tests/astro_tools/test_pipline.py +16 -0
  19. pz_rail_astro_tools-1.0.3/src/rail/creation/degraders/lsst_error_model.py +0 -61
  20. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.copier-answers.yml +0 -0
  21. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/ISSUE_TEMPLATE/0-general_issue.md +0 -0
  22. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/ISSUE_TEMPLATE/1-bug_report.md +0 -0
  23. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/ISSUE_TEMPLATE/2-feature_request.md +0 -0
  24. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/pull_request_template.md +0 -0
  25. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/workflows/add-issue-to-project-tracker.yml +0 -0
  26. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/workflows/linting.yml +0 -0
  27. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/workflows/publish-to-pypi.yml +0 -0
  28. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/workflows/smoke-test.yml +0 -0
  29. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.github/workflows/testing-and-coverage.yml +0 -0
  30. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.gitignore +0 -0
  31. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/.pre-commit-config.yaml +0 -0
  32. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/LICENSE +0 -0
  33. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/README.md +0 -0
  34. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/environment.yml +0 -0
  35. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/setup.cfg +0 -0
  36. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/setup.py +0 -0
  37. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/pz_rail_astro_tools.egg-info/dependency_links.txt +0 -0
  38. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/pz_rail_astro_tools.egg-info/top_level.txt +0 -0
  39. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/creation/degraders/grid_selection.py +0 -0
  40. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/creation/degraders/observing_condition_degrader.py +0 -0
  41. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/creation/engines/gcr_engine.py +0 -0
  42. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/examples_data/creation_data/data/HSC_grid_settings.pkl +0 -0
  43. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/examples_data/creation_data/data/hsc_ratios_and_specz.hdf5 +0 -0
  44. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/examples_data/creation_data/data/survey_conditions/DC2-dr6-galcounts-i20-i25.3-nside-128.fits +0 -0
  45. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/examples_data/creation_data/data/survey_conditions/DC2-mask-neg-nside-128.fits +0 -0
  46. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/examples_data/creation_data/data/survey_conditions/minion_1016_dc2_Median_airmass_i_and_nightlt1825_HEAL.fits +0 -0
  47. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/examples_data/creation_data/data/survey_conditions/minion_1016_dc2_Median_fiveSigmaDepth_i_and_nightlt1825_HEAL.fits +0 -0
  48. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/src/rail/examples_data/testdata/rubin_dm_dc2_example2.pq +0 -0
  49. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/tests/astro_tools/gcr_test_data/schema.yaml +0 -0
  50. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/tests/astro_tools/gcr_test_data/test_object_tract_4850.hdf5 +0 -0
  51. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/tests/astro_tools/test_core.py +0 -0
  52. {pz_rail_astro_tools-1.0.3 → pz_rail_astro_tools-1.0.5}/tests/astro_tools/test_gcr_engine.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pz-rail-astro-tools
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Author-email: "LSST Dark Energy Science Collaboration (DESC)" <lsst-desc-rail-admin@slac.stanford.edu>
5
5
  License: MIT License
6
6
 
@@ -43,6 +43,7 @@ Requires-Dist: photerr
43
43
  Requires-Dist: dustmaps
44
44
  Requires-Dist: pz-hyperbolic-temp
45
45
  Requires-Dist: lsstdesc-gcr-catalogs
46
+ Requires-Dist: FoFCatalogMatching
46
47
  Provides-Extra: dev
47
48
  Requires-Dist: tables-io[full]; extra == "dev"
48
49
  Requires-Dist: pytest; extra == "dev"
@@ -26,6 +26,7 @@ dependencies = [
26
26
  "dustmaps",
27
27
  "pz-hyperbolic-temp",
28
28
  "lsstdesc-gcr-catalogs",
29
+ "FoFCatalogMatching",
29
30
  ]
30
31
 
31
32
  # On a mac, install optional dependencies with `pip install '.[dev]'` (include the single quotes)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pz-rail-astro-tools
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Author-email: "LSST Dark Energy Science Collaboration (DESC)" <lsst-desc-rail-admin@slac.stanford.edu>
5
5
  License: MIT License
6
6
 
@@ -43,6 +43,7 @@ Requires-Dist: photerr
43
43
  Requires-Dist: dustmaps
44
44
  Requires-Dist: pz-hyperbolic-temp
45
45
  Requires-Dist: lsstdesc-gcr-catalogs
46
+ Requires-Dist: FoFCatalogMatching
46
47
  Provides-Extra: dev
47
48
  Requires-Dist: tables-io[full]; extra == "dev"
48
49
  Requires-Dist: pytest; extra == "dev"
@@ -22,12 +22,13 @@ src/pz_rail_astro_tools.egg-info/requires.txt
22
22
  src/pz_rail_astro_tools.egg-info/top_level.txt
23
23
  src/rail/astro_tools/__init__.py
24
24
  src/rail/astro_tools/_version.py
25
+ src/rail/creation/degraders/bl_demo.ipynb
25
26
  src/rail/creation/degraders/grid_selection.py
26
- src/rail/creation/degraders/lsst_error_model.py
27
27
  src/rail/creation/degraders/observing_condition_degrader.py
28
28
  src/rail/creation/degraders/photometric_errors.py
29
29
  src/rail/creation/degraders/spectroscopic_degraders.py
30
30
  src/rail/creation/degraders/spectroscopic_selections.py
31
+ src/rail/creation/degraders/unrec_bl_model.py
31
32
  src/rail/creation/engines/gcr_engine.py
32
33
  src/rail/examples_data/creation_data/data/HSC_grid_settings.pkl
33
34
  src/rail/examples_data/creation_data/data/hsc_ratios_and_specz.hdf5
@@ -36,9 +37,13 @@ src/rail/examples_data/creation_data/data/survey_conditions/DC2-mask-neg-nside-1
36
37
  src/rail/examples_data/creation_data/data/survey_conditions/minion_1016_dc2_Median_airmass_i_and_nightlt1825_HEAL.fits
37
38
  src/rail/examples_data/creation_data/data/survey_conditions/minion_1016_dc2_Median_fiveSigmaDepth_i_and_nightlt1825_HEAL.fits
38
39
  src/rail/examples_data/testdata/rubin_dm_dc2_example2.pq
40
+ src/rail/pipelines/degradation/apply_phot_errors.py
41
+ src/rail/pipelines/degradation/blending.py
42
+ src/rail/pipelines/degradation/spectroscopic_selection_pipeline.py
39
43
  src/rail/tools/photometry_tools.py
40
44
  tests/astro_tools/test_core.py
41
45
  tests/astro_tools/test_degraders.py
42
46
  tests/astro_tools/test_gcr_engine.py
47
+ tests/astro_tools/test_pipline.py
43
48
  tests/astro_tools/gcr_test_data/schema.yaml
44
49
  tests/astro_tools/gcr_test_data/test_object_tract_4850.hdf5
@@ -8,6 +8,7 @@ photerr
8
8
  dustmaps
9
9
  pz-hyperbolic-temp
10
10
  lsstdesc-gcr-catalogs
11
+ FoFCatalogMatching
11
12
 
12
13
  [dev]
13
14
  tables-io[full]
@@ -4,5 +4,6 @@ from rail.creation.degraders.grid_selection import *
4
4
  from rail.creation.degraders.observing_condition_degrader import *
5
5
  from rail.creation.degraders.spectroscopic_degraders import *
6
6
  from rail.creation.degraders.spectroscopic_selections import *
7
- from rail.creation.degraders.lsst_error_model import *
7
+ from rail.creation.degraders.photometric_errors import *
8
+ from rail.creation.degraders.unrec_bl_model import *
8
9
  from rail.tools.photometry_tools import *
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.0.3'
16
- __version_tuple__ = version_tuple = (1, 0, 3)
15
+ __version__ = version = '1.0.5'
16
+ __version_tuple__ = version_tuple = (1, 0, 5)
@@ -0,0 +1,206 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "2610a0f0-0c71-4401-896f-734442bcd66d",
6
+ "metadata": {},
7
+ "source": [
8
+ "## Blending Degrader demo\n",
9
+ "\n",
10
+ "author: Shuang Liang\n",
11
+ "\n",
12
+ "This notebook demonstrate the use of `rail.creation.degradation.unrec_bl_model`, which uses Friends of Friends to finds sources close to each other and merge them into unrecognized blends"
13
+ ]
14
+ },
15
+ {
16
+ "cell_type": "code",
17
+ "execution_count": null,
18
+ "id": "f7a6adc3-68e8-4a1d-842f-bfb0960a1c4a",
19
+ "metadata": {},
20
+ "outputs": [],
21
+ "source": [
22
+ "from rail.creation.degraders.unrec_bl_model import UnrecBlModel\n",
23
+ "\n",
24
+ "from rail.core.data import PqHandle\n",
25
+ "from rail.core.stage import RailStage\n",
26
+ "\n",
27
+ "import matplotlib.pyplot as plt\n",
28
+ "import pandas as pd, numpy as np"
29
+ ]
30
+ },
31
+ {
32
+ "cell_type": "code",
33
+ "execution_count": null,
34
+ "id": "6912a740-31ea-4987-b06d-81ff17cd895a",
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "DS = RailStage.data_store\n",
39
+ "DS.__class__.allow_overwrite = True\n"
40
+ ]
41
+ },
42
+ {
43
+ "cell_type": "markdown",
44
+ "id": "a282c2ed-141b-4507-8254-dc8fbc9864dc",
45
+ "metadata": {},
46
+ "source": [
47
+ "### Create a random catalog with ugrizy+YJHF bands as the the true input"
48
+ ]
49
+ },
50
+ {
51
+ "cell_type": "code",
52
+ "execution_count": null,
53
+ "id": "1078bc2a-fc54-41c3-bd30-6c447bb971d4",
54
+ "metadata": {},
55
+ "outputs": [],
56
+ "source": [
57
+ "data = np.random.normal(23, 3, size = (1000,12))\n",
58
+ "data[:, 0] = np.random.uniform(low=0, high=0.03, size=1000)\n",
59
+ "data[:, 1] = np.random.uniform(low=0, high=0.03, size=1000)\n",
60
+ "\n",
61
+ "data_df = pd.DataFrame(data=data, # values\n",
62
+ " columns=['ra', 'dec', 'u', 'g', 'r', 'i', 'z', 'y', 'Y', 'J', 'H', 'F'])\n",
63
+ "\n",
64
+ "data_truth = DS.add_data('input', data_df, PqHandle)"
65
+ ]
66
+ },
67
+ {
68
+ "cell_type": "code",
69
+ "execution_count": null,
70
+ "id": "33c99a4d-8375-4003-9a9a-70fa85a3eb82",
71
+ "metadata": {},
72
+ "outputs": [],
73
+ "source": [
74
+ "#data_df.to_parquet('bl_test.pq')"
75
+ ]
76
+ },
77
+ {
78
+ "cell_type": "code",
79
+ "execution_count": null,
80
+ "id": "a5636721-a734-4746-bd93-8101bc558b6e",
81
+ "metadata": {},
82
+ "outputs": [],
83
+ "source": [
84
+ "plt.scatter(data_truth.data['ra'], data_truth.data['dec'], s=5)\n",
85
+ "plt.xlabel(\"Ra [Deg]\", fontsize=14)\n",
86
+ "plt.ylabel(\"Dec [Deg]\", fontsize=14)\n",
87
+ "plt.show()\n"
88
+ ]
89
+ },
90
+ {
91
+ "cell_type": "markdown",
92
+ "id": "1da27deb-d167-4f38-8c59-f270184d6ab3",
93
+ "metadata": {},
94
+ "source": [
95
+ "### The blending model"
96
+ ]
97
+ },
98
+ {
99
+ "cell_type": "code",
100
+ "execution_count": null,
101
+ "id": "a07f72a0-e24c-4844-90f0-d5a49ac4362b",
102
+ "metadata": {},
103
+ "outputs": [],
104
+ "source": [
105
+ "## radius cut is in arcsecs\n",
106
+ "blModel = UnrecBlModel.make_stage(name='unrec_bl_model', ra_label='ra', dec_label='dec', linking_lengths=1.0, \\\n",
107
+ " bands='ugrizyYJHF')\n",
108
+ "blModel.get_config_dict()\n"
109
+ ]
110
+ },
111
+ {
112
+ "cell_type": "code",
113
+ "execution_count": null,
114
+ "id": "e5f4862a-0621-46d4-8901-7e84b461c424",
115
+ "metadata": {},
116
+ "outputs": [],
117
+ "source": [
118
+ "samples_w_bl = blModel(data_truth)\n",
119
+ "samples_w_bl()\n"
120
+ ]
121
+ },
122
+ {
123
+ "cell_type": "code",
124
+ "execution_count": null,
125
+ "id": "bc5158dd-f474-4731-b847-b4a7358656b9",
126
+ "metadata": {},
127
+ "outputs": [],
128
+ "source": [
129
+ "fig, ax = plt.subplots(figsize=(6, 5), dpi=100)\n",
130
+ "\n",
131
+ "ax.scatter(data_truth.data['ra'], data_truth.data['dec'], s=10, facecolors='none', edgecolors='b', label='Original')\n",
132
+ "ax.scatter(samples_w_bl.data['ra'], samples_w_bl.data['dec'], s=5, c='r', label='w. Unrec-BL')\n",
133
+ "\n",
134
+ "ax.legend(loc=2, fontsize=12)\n",
135
+ "ax.set_xlabel(\"Ra [Deg]\", fontsize=14)\n",
136
+ "ax.set_ylabel(\"Dec [Deg]\", fontsize=14)\n",
137
+ "\n",
138
+ "plt.show()\n"
139
+ ]
140
+ },
141
+ {
142
+ "cell_type": "code",
143
+ "execution_count": null,
144
+ "id": "268b3d37-b7fd-4ac1-8457-2104a87c9e6d",
145
+ "metadata": {},
146
+ "outputs": [],
147
+ "source": [
148
+ "b = 'r'\n",
149
+ "plt.hist(data_truth.data[b], bins=np.linspace(10, 30, 20), label='Original')\n",
150
+ "plt.hist(samples_w_bl.data[b], bins=np.linspace(10, 30, 20), fill=False, label='w. Unrec-BL')\n",
151
+ "\n",
152
+ "plt.xlabel(fr'Magnitude ${b}$', fontsize=14)\n",
153
+ "plt.legend(fontsize=12)\n",
154
+ "plt.show()\n"
155
+ ]
156
+ },
157
+ {
158
+ "cell_type": "code",
159
+ "execution_count": null,
160
+ "id": "a1d51c15-1e04-4b22-9abb-9b267965dbeb",
161
+ "metadata": {},
162
+ "outputs": [],
163
+ "source": [
164
+ "flux = 10**(-(data_truth.data[b]-28.10)/2.5) # r band zp for lsst is 28.10\n",
165
+ "flux_bl = 10**(-(samples_w_bl.data[b]-28.10)/2.5)\n",
166
+ "\n",
167
+ "plt.hist(flux, bins=np.linspace(0, 10000, 40), label='Original')\n",
168
+ "plt.hist(flux_bl, bins=np.linspace(0, 10000, 40), fill=False, label='w. Unrec-BL')\n",
169
+ "\n",
170
+ "plt.xlabel(fr'Flux ${b}$', fontsize=14)\n",
171
+ "plt.yscale('log')\n",
172
+ "plt.legend(fontsize=12)\n",
173
+ "plt.show()\n"
174
+ ]
175
+ },
176
+ {
177
+ "cell_type": "code",
178
+ "execution_count": null,
179
+ "id": "da2b37c8-4667-4ad2-ad09-b1c68d2612b8",
180
+ "metadata": {},
181
+ "outputs": [],
182
+ "source": []
183
+ }
184
+ ],
185
+ "metadata": {
186
+ "kernelspec": {
187
+ "display_name": "Python 3 (ipykernel)",
188
+ "language": "python",
189
+ "name": "python3"
190
+ },
191
+ "language_info": {
192
+ "codemirror_mode": {
193
+ "name": "ipython",
194
+ "version": 3
195
+ },
196
+ "file_extension": ".py",
197
+ "mimetype": "text/x-python",
198
+ "name": "python",
199
+ "nbconvert_exporter": "python",
200
+ "pygments_lexer": "ipython3",
201
+ "version": "3.12.3"
202
+ }
203
+ },
204
+ "nbformat": 4,
205
+ "nbformat_minor": 5
206
+ }
@@ -4,6 +4,7 @@ error models defined in the package photerr
4
4
 
5
5
  Author: John Franklin Crenshaw, Tianqing Zhang
6
6
  """
7
+ import numpy as np
7
8
  from dataclasses import MISSING
8
9
 
9
10
  from ceci.config import StageParameter as Param
@@ -44,7 +45,7 @@ class PhotoErrorModel(Noisifier):
44
45
  default = val.default_factory()
45
46
  else:
46
47
  default = val.default
47
-
48
+
48
49
  # Add this param to config_options
49
50
  self.config[key] = Param(
50
51
  None, # Let PhotErr handle type checking
@@ -52,6 +53,18 @@ class PhotoErrorModel(Noisifier):
52
53
  msg="See the main docstring for details about this parameter.",
53
54
  required=False,
54
55
  )
56
+
57
+ def reload_pars(self, args):
58
+ """ This is needed b/c the parameters are dynamically defined,
59
+ so we have to reload them _after_ then have been defined """
60
+ copy_args = args.copy()
61
+ if isinstance(args, dict):
62
+ copy_args['config'] = args
63
+ else: # pragma: no cover
64
+ copy_args['config'] = vars(args)
65
+ self.load_configs(copy_args)
66
+ self._io_checked = False
67
+ self.check_io()
55
68
 
56
69
  def _initNoiseModel(self):
57
70
  """
@@ -66,12 +79,15 @@ class PhotoErrorModel(Noisifier):
66
79
  """
67
80
  Add noise to the input catalog
68
81
  """
69
-
70
82
  # Load the input catalog
71
83
  data = self.get_data("input")
72
84
 
73
85
  # Add photometric errors
74
- obsData = self.noiseModel(data, random_state=self.config.seed)
86
+ if self.config.seed is not None: # pragma: no cover
87
+ seed = int(self.config.seed)
88
+ else:
89
+ seed = np.random.Generator(np.random.PCG64())
90
+ obsData = self.noiseModel(data, random_state=seed)
75
91
 
76
92
  # Return the new catalog
77
93
  self.add_data("output", obsData)
@@ -90,10 +106,9 @@ class LSSTErrorModel(PhotoErrorModel):
90
106
  super().__init__(args, **kwargs)
91
107
 
92
108
  self.set_params(peLsstErrorParams)
109
+ self.reload_pars(args)
93
110
  self.peNoiseModel = peLsstErrorModel
94
111
 
95
-
96
-
97
112
 
98
113
  class RomanErrorModel(PhotoErrorModel):
99
114
 
@@ -108,6 +123,7 @@ class RomanErrorModel(PhotoErrorModel):
108
123
  super().__init__(args, **kwargs)
109
124
 
110
125
  self.set_params(peRomanErrorParams)
126
+ self.reload_pars(args)
111
127
  self.peNoiseModel = peRomanErrorModel
112
128
 
113
129
 
@@ -125,4 +141,5 @@ class EuclidErrorModel(PhotoErrorModel):
125
141
  super().__init__(args, **kwargs)
126
142
 
127
143
  self.set_params(peEuclidErrorParams)
144
+ self.reload_pars(args)
128
145
  self.peNoiseModel = peEuclidErrorModel
@@ -2,6 +2,7 @@
2
2
 
3
3
  import numpy as np
4
4
  import pandas as pd
5
+ from ceci.config import StageParameter as Param
5
6
  from rail.creation.selector import Selector
6
7
  from rail.creation.noisifier import Noisifier
7
8
 
@@ -40,9 +41,11 @@ class LineConfusion(Noisifier):
40
41
 
41
42
  name = 'LineConfusion'
42
43
  config_options = Noisifier.config_options.copy()
43
- config_options.update(true_wavelen=float,
44
- wrong_wavelen=float,
45
- frac_wrong=float)
44
+ config_options.update(
45
+ true_wavelen=Param(float, required=True, msg="wavelength of the true emission line"),
46
+ wrong_wavelen=Param(float, required=True, msg="wavelength of the wrong emission line"),
47
+ frac_wrong=Param(float, required=True, msg="fraction of galaxies with confused emission lines"),
48
+ )
46
49
 
47
50
  def __init__(self, args, **kwargs):
48
51
  """
@@ -113,7 +116,9 @@ class InvRedshiftIncompleteness(Selector):
113
116
 
114
117
  name = 'InvRedshiftIncompleteness'
115
118
  config_options = Selector.config_options.copy()
116
- config_options.update(pivot_redshift=float)
119
+ config_options.update(
120
+ pivot_redshift=Param(float, required=True, msg="redshift at which the incompleteness begins"),
121
+ )
117
122
 
118
123
  def __init__(self, args, **kwargs):
119
124
  """
@@ -36,7 +36,7 @@ class SpecSelection(Selector):
36
36
  Random seed for reproducibility
37
37
  """
38
38
 
39
- name = "specselection"
39
+ name = "SpecSelection"
40
40
  config_options = Selector.config_options.copy()
41
41
  config_options.update(
42
42
  N_tot=Param(int, 10000, msg="Number of selected sources"),
@@ -121,9 +121,9 @@ class SpecSelection(Selector):
121
121
  if band not in self.config.colnames.keys():
122
122
  continue
123
123
  colname = self.config.colnames[band]
124
- self.mask &= (np.abs(data[colname]) < nondetect_val) & (
125
- ~np.isnan(data[colname])
126
- )
124
+ self.mask &= data[colname] != nondetect_val
125
+ self.mask &= ~np.isnan(data[colname])
126
+ self.mask &= np.isfinite(data[colname])
127
127
 
128
128
  def downsampling_N_tot(self):
129
129
  """Randomly sample down the objects to a given number of data objects.
@@ -180,7 +180,7 @@ class SpecSelection_GAMA(SpecSelection):
180
180
  The necessary column is r band.
181
181
  """
182
182
 
183
- name = "specselection_gama"
183
+ name = "SpecSelection_GAMA"
184
184
 
185
185
  def selection(self, data):
186
186
  """GAMA selection function. """
@@ -208,7 +208,7 @@ class SpecSelection_BOSS(SpecSelection):
208
208
  For BOSS selection, the data should at least include gri bands.
209
209
  """
210
210
 
211
- name = "specselection_boss"
211
+ name = "SpecSelection_BOSS"
212
212
 
213
213
  def selection(self, data):
214
214
  """The BOSS selection function."""
@@ -268,7 +268,7 @@ class SpecSelection_DEEP2(SpecSelection):
268
268
  conversion degrader is ready, this subclass will be updated accordingly.
269
269
  """
270
270
 
271
- name = "specselection_deep2"
271
+ name = "SpecSelection_DEEP2"
272
272
 
273
273
  def photometryCut(self, data):
274
274
  """Applies DEEP2 photometric cut based on Newman+13.
@@ -355,7 +355,7 @@ class SpecSelection_VVDSf02(SpecSelection):
355
355
  Necessary columns are i band magnitude and redshift.
356
356
  """
357
357
 
358
- name = "specselection_VVDSf02"
358
+ name = "SpecSelection_VVDSf02"
359
359
 
360
360
  def photometryCut(self, data):
361
361
  """Photometric cut of VVDS 2h-field based on LeFèvre+05.
@@ -466,7 +466,7 @@ class SpecSelection_zCOSMOS(SpecSelection):
466
466
  For zCOSMOS, the data should at least include i band and redshift.
467
467
  """
468
468
 
469
- name = "specselection_zCOSMOS"
469
+ name = "SpecSelection_zCOSMOS"
470
470
 
471
471
  def photometryCut(self, data):
472
472
  """Photometry cut for zCOSMOS based on Lilly+09.
@@ -527,7 +527,7 @@ class SpecSelection_HSC(SpecSelection):
527
527
  For HSC, the data should at least include giz bands and redshift.
528
528
  """
529
529
 
530
- name = "specselection_HSC"
530
+ name = "SpecSelection_HSC"
531
531
 
532
532
  def photometryCut(self, data):
533
533
  """HSC galaxies were binned in color magnitude space with i-band mag
@@ -604,4 +604,4 @@ class SpecSelection_HSC(SpecSelection):
604
604
  # start message
605
605
  printMsg = "Applying the HSC selection."
606
606
 
607
- return printMsg
607
+ return printMsg
@@ -0,0 +1,98 @@
1
+ """Model for Creating Unrecognized Blends"""
2
+
3
+ from ceci.config import StageParameter as Param
4
+ from rail.creation.degrader import Degrader
5
+ import numpy as np, pandas as pd
6
+ import FoFCatalogMatching
7
+
8
+
9
+ class UnrecBlModel(Degrader):
10
+ """Model for Creating Unrecognized Blends.
11
+
12
+ Finding objects nearby each other. Merge them into one blended
13
+ Use Friends of Friends for matching. May implement shape matching in the future.
14
+ Take avergaged Ra and Dec for blended source, and sum up fluxes in each band. May implement merged shapes in the future.
15
+
16
+ """
17
+ name = "UnrecBlModel"
18
+ config_options = Degrader.config_options.copy()
19
+ config_options.update(ra_label=Param(str, 'ra', msg='ra column name'),
20
+ dec_label=Param(str, 'dec', msg='dec column name'),
21
+ linking_lengths=Param(float, 1.0, msg='linking_lengths for FoF matching'),
22
+ bands=Param(str, 'ugrizy', msg='name of filters'),
23
+ match_size=Param(bool, False, msg='consider object size for finding blends'),
24
+ match_shape=Param(bool, False, msg='consider object shape for finding blends'),
25
+ obj_size=Param(str, 'obj_size', msg='object size column name'),
26
+ a=Param(str, 'semi_major', msg='semi major axis column name'),
27
+ b=Param(str, 'semi_minor', msg='semi minor axis column name'),
28
+ theta=Param(str, 'orientation', msg='orientation angle column name'))
29
+
30
+ def __match_bl__(self, data):
31
+
32
+ """Group sources with friends of friends"""
33
+
34
+ ra_label, dec_label = self.config.ra_label, self.config.dec_label
35
+ linking_lengths = self.config.linking_lengths
36
+
37
+ results = FoFCatalogMatching.match({'truth': data}, linking_lengths=linking_lengths, ra_label=ra_label, dec_label=dec_label)
38
+ results.remove_column('catalog_key')
39
+
40
+ results = results.to_pandas(index='row_index')
41
+ results.sort_values(by='row_index', inplace=True)
42
+
43
+ ## adding the group id as the last column to data
44
+ matchData = pd.merge(data, results, left_index=True, right_index=True)
45
+
46
+ return matchData
47
+
48
+ def __merge_bl__(self, data):
49
+
50
+ """Merge sources within a group into unrecognized blends."""
51
+
52
+ group_id = data['group_id']
53
+ unique_id = np.unique(group_id)
54
+
55
+ ra_label, dec_label = self.config.ra_label, self.config.dec_label
56
+
57
+ cols = list(data.columns)
58
+ ra_ind = cols.index(ra_label)
59
+ dec_ind = cols.index(dec_label)
60
+ bands_ind = {b:cols.index(b) for b in self.config.bands}
61
+
62
+ N_rows = len(unique_id)
63
+ N_cols = len(cols)
64
+
65
+ mergeData = np.zeros((N_rows, N_cols))
66
+
67
+ for i, id in enumerate(unique_id):
68
+
69
+ this_group = data.query(f'group_id=={id}')
70
+
71
+ ## take the average position for the blended source
72
+ mergeData[i, ra_ind] = this_group[ra_label].mean()
73
+ mergeData[i, dec_ind] = this_group[dec_label].mean()
74
+
75
+ ## sum up the fluxes into the blended source
76
+ for b in self.config.bands:
77
+ mergeData[i, bands_ind[b]] = -2.5*np.log10(np.sum(10**(-this_group[b]/2.5)))
78
+
79
+ mergeData[:,-1] = unique_id
80
+ mergeData_df = pd.DataFrame(data=mergeData, columns=cols)
81
+ mergeData_df['group_id'] = mergeData_df['group_id'].astype(int)
82
+
83
+ return mergeData_df
84
+
85
+ def run(self):
86
+ """Return pandas DataFrame with blending errors."""
87
+
88
+ # Load the input catalog
89
+ data = self.get_data("input")
90
+
91
+ # Match for close-by objects
92
+ matchData = self.__match_bl__(data)
93
+
94
+ # Merge matched objects into unrec-bl
95
+ blData = self.__merge_bl__(matchData)
96
+
97
+ # Return the new catalog
98
+ self.add_data("output", blData)
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # Prerquisites, os, and numpy
5
+ import os
6
+ import numpy as np
7
+
8
+ # Various rail modules
9
+ from rail.tools.photometry_tools import Dereddener, Reddener
10
+
11
+ from rail.core.stage import RailStage, RailPipeline
12
+
13
+ import ceci
14
+
15
+ from rail.core.utils import RAILDIR
16
+
17
+ if 'PZ_DUSTMAP_DIR' not in os.environ:
18
+ os.environ['PZ_DUSTMAP_DIR'] = '.'
19
+
20
+ dustmap_dir = os.path.expandvars("${PZ_DUSTMAP_DIR}")
21
+
22
+
23
+ ERROR_MODELS = dict(
24
+ lsst = dict(
25
+ ErrorModel='LSSTErrorModel',
26
+ Module='rail.creation.degraders.photometric_errors',
27
+ ),
28
+ roman = dict(
29
+ ErrorModel='RomanErrorModel',
30
+ Module='rail.creation.degraders.photometric_errors',
31
+ ),
32
+ #euclid = dict(
33
+ # ErrorModel='EuclidErrorModel',
34
+ # Module='rail.creation.degraders.photometric_errors',
35
+ #),
36
+ )
37
+
38
+
39
+
40
+ class ApplyPhotErrorsPipeline(RailPipeline):
41
+
42
+ default_input_dict = dict(input='dummy.in')
43
+
44
+ def __init__(self, error_models=None):
45
+ RailPipeline.__init__(self)
46
+
47
+ DS = RailStage.data_store
48
+ DS.__class__.allow_overwrite = True
49
+
50
+ if error_models is None:
51
+ error_models = ERROR_MODELS
52
+
53
+ self.reddener = Reddener.build(
54
+ dustmap_dir=dustmap_dir,
55
+ copy_all_cols=True,
56
+ )
57
+
58
+ previous_stage = self.reddener
59
+ for key, val in error_models.items():
60
+ error_model_class = ceci.PipelineStage.get_stage(val['ErrorModel'], val['Module'])
61
+ the_error_model = error_model_class.make_and_connect(
62
+ name=f'error_model_{key}',
63
+ connections=dict(input=previous_stage.io.output),
64
+ hdf5_groupname='',
65
+ )
66
+ self.add_stage(the_error_model)
67
+ previous_stage = the_error_model
68
+
69
+ self.dereddener_errors = Dereddener.build(
70
+ dustmap_dir=dustmap_dir,
71
+ connections=dict(input=previous_stage.io.output),
72
+ copy_all_cols=True,
73
+ )
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # Prerquisites, os, and numpy
5
+ import os
6
+ import numpy as np
7
+
8
+ # Various rail modules
9
+ from rail.creation.degraders.unrec_bl_model import UnrecBlModel
10
+
11
+ from rail.core.stage import RailStage, RailPipeline
12
+
13
+ import ceci
14
+
15
+ from rail.core.utils import RAILDIR
16
+
17
+
18
+ class BlendingPipeline(RailPipeline):
19
+
20
+ default_input_dict = dict(input='dummy.in')
21
+
22
+ def __init__(self):
23
+ RailPipeline.__init__(self)
24
+
25
+ DS = RailStage.data_store
26
+ DS.__class__.allow_overwrite = True
27
+
28
+ self.unrec_bl = UnrecBlModel.build()
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # Prerquisites, os, and numpy
5
+ import os
6
+ import numpy as np
7
+
8
+ # Various rail modules
9
+
10
+ from rail.core.stage import RailStage, RailPipeline
11
+
12
+ import ceci
13
+
14
+ from rail.utils.catalog_utils import CatalogConfigBase
15
+ from rail.core.utils import RAILDIR
16
+
17
+ SELECTORS = dict(
18
+ GAMA = dict(
19
+ Select='SpecSelection_GAMA',
20
+ Module='rail.creation.degraders.spectroscopic_selections',
21
+ ),
22
+ BOSS = dict(
23
+ Select='SpecSelection_BOSS',
24
+ Module='rail.creation.degraders.spectroscopic_selections',
25
+ ),
26
+ VVDSf02 = dict(
27
+ Select='SpecSelection_VVDSf02',
28
+ Module='rail.creation.degraders.spectroscopic_selections',
29
+ ),
30
+ zCOSMOS = dict(
31
+ Select='SpecSelection_zCOSMOS',
32
+ Module='rail.creation.degraders.spectroscopic_selections',
33
+ ),
34
+ HSC = dict(
35
+ Select='SpecSelection_HSC',
36
+ Module='rail.creation.degraders.spectroscopic_selections',
37
+ ),
38
+ )
39
+
40
+
41
+ CommonConfigParams = dict(
42
+ N_tot = 100_000,
43
+ nondetect_val = -np.inf,
44
+ downsample= False,
45
+ )
46
+
47
+
48
+ class SpectroscopicSelectionPipeline(RailPipeline):
49
+
50
+ default_input_dict = dict(input='dummy.in')
51
+
52
+ def __init__(self, selectors=None):
53
+ RailPipeline.__init__(self)
54
+
55
+ DS = RailStage.data_store
56
+ DS.__class__.allow_overwrite = True
57
+
58
+ if selectors is None:
59
+ selectors = SELECTORS.copy()
60
+
61
+ config_pars = CommonConfigParams.copy()
62
+ active_catalog = CatalogConfigBase.active_class()
63
+ if active_catalog:
64
+ colnames = active_catalog.band_name_dict()
65
+ colnames['redshift'] = active_catalog.redshift_col
66
+ config_pars['colnames'] = colnames
67
+
68
+ for key, val in selectors.items():
69
+ the_class = ceci.PipelineStage.get_stage(val['Select'], val['Module'])
70
+ the_selector = the_class.make_and_connect(
71
+ name=f'select_{key}',
72
+ **config_pars,
73
+ )
74
+
75
+ self.add_stage(the_selector)
@@ -358,13 +358,15 @@ class LSSTFluxToMagConverter(RailStage):
358
358
  name = 'LSSTFluxToMagConverter'
359
359
 
360
360
  config_options = RailStage.config_options.copy()
361
- config_options.update(bands='ugrizy')
362
- config_options.update(flux_name="{band}_gaap1p0Flux")
363
- config_options.update(flux_err_name="{band}_gaap1p0FluxErr")
364
- config_options.update(mag_name="mag_{band}_lsst")
365
- config_options.update(mag_err_name="mag_err_{band}_lsst")
366
- config_options.update(copy_cols={})
367
- config_options.update(mag_offset=31.4)
361
+ config_options.update(
362
+ bands=Param(str, default='ugrizy', msg="Names of the bands"),
363
+ flux_name=Param(str, default="{band}_gaap1p0Flux", msg="Template for band names"),
364
+ flux_err_name=Param(str, default="{band}_gaap1p0FluxErr", msg="Template for band error column names"),
365
+ mag_name=Param(str, default="mag_{band}_lsst", msg="Template for magnitude column names"),
366
+ mag_err_name=Param(str, default="mag_err_{band}_lsst", msg="Template for magnitude error column names"),
367
+ copy_cols=Param(dict, default={}, msg="Map of other columns to copy"),
368
+ mag_offset=Param(float, default=31.4, msg="Magntidue offset value"),
369
+ )
368
370
 
369
371
  mag_conv = np.log(10)*0.4
370
372
 
@@ -417,16 +419,17 @@ class DustMapBase(RailStage):
417
419
  name = 'DustMapBase'
418
420
 
419
421
  config_options = RailStage.config_options.copy()
420
- config_options.update(bands='ugrizy')
421
- config_options.update(ra_name='ra')
422
- config_options.update(dec_name='dec')
423
- config_options.update(mag_name="mag_{band}_lsst")
424
- config_options.update(band_a_env=[4.81,3.64,2.70,2.06,1.58,1.31])
425
- config_options.update(dustmap_name='sfd')
426
- config_options.update(dustmap_dir=str)
427
- config_options.update(copy_cols=[])
428
- config_options.update(copy_all_cols=False)
429
-
422
+ config_options.update(
423
+ ra_name=Param(str, default='ra', msg="Name of the RA column"),
424
+ dec_name=Param(str, default='dec', msg="Name of the DEC column"),
425
+ mag_name=Param(str, default="mag_{band}_lsst", msg="Template for the magnitude columns"),
426
+ band_a_env=SHARED_PARAMS,
427
+ dustmap_name=Param(str, default='sfd', msg="Name of the dustmap in question"),
428
+ dustmap_dir=Param(str, required=True, msg="Directory with dustmaps"),
429
+ copy_cols=Param(list, default=[], msg="Additional columns to copy"),
430
+ copy_all_cols=Param(bool, default=False, msg="Copy all the columns"),
431
+ )
432
+
430
433
  inputs = [('input', PqHandle)]
431
434
  outputs = [('output', PqHandle)]
432
435
 
@@ -453,7 +456,10 @@ class DustMapBase(RailStage):
453
456
  def run(self):
454
457
  data = self.get_data('input', allow_missing=True)
455
458
  out_data = {}
456
- coords = SkyCoord(data[self.config.ra_name], data[self.config.dec_name], unit = 'deg',frame='fk5')
459
+ coords = SkyCoord(
460
+ np.array(data[self.config.ra_name]),
461
+ np.array(data[self.config.dec_name]),
462
+ unit = 'deg',frame='fk5')
457
463
  dust_map_dict = dict(sfd=dustmaps_sfd.SFDQuery)
458
464
  try:
459
465
  dust_map_class = dust_map_dict[self.config.dustmap_name]
@@ -464,10 +470,9 @@ class DustMapBase(RailStage):
464
470
  raise KeyError(f"Unknown dustmap {self.config.dustmap_name}, options are {list(dust_map_dict.keys())}") from msg
465
471
  ebvvec = dust_map(coords)
466
472
  band_mag_name_list=[]
467
- for i, band_ in enumerate(self.config.bands):
468
- band_mag_name = self.config.mag_name.format(band=band_)
473
+ for band_mag_name, a_env_value in self.config.band_a_env.items():
469
474
  mag_vals = data[band_mag_name]
470
- out_data[band_mag_name] = self._calc_values(mag_vals, ebvvec, self.config.band_a_env[i])
475
+ out_data[band_mag_name] = self._calc_values(mag_vals, ebvvec, a_env_value)
471
476
  band_mag_name_list.append(band_mag_name)
472
477
 
473
478
  # check if copy_all_cols set to true:
@@ -13,7 +13,8 @@ from rail.creation.degraders.spectroscopic_degraders import InvRedshiftIncomplet
13
13
  from rail.creation.degraders.spectroscopic_selections import *
14
14
  from rail.creation.degraders.observing_condition_degrader import ObsCondition
15
15
  from rail.creation.degraders.grid_selection import GridSelection
16
- from rail.creation.degraders.lsst_error_model import LSSTErrorModel
16
+ from rail.creation.degraders.photometric_errors import EuclidErrorModel, LSSTErrorModel
17
+ from rail.creation.degraders.unrec_bl_model import UnrecBlModel
17
18
 
18
19
 
19
20
  @pytest.fixture
@@ -74,6 +75,29 @@ def data_with_radec():
74
75
  return DS.add_data("data_with_radec", df, TableHandle, path="dummy_with_radec.pd")
75
76
 
76
77
 
78
+ @pytest.fixture
79
+ def data_for_bl():
80
+ """Some dummy data to use below."""
81
+
82
+ DS = DATA_STORE()
83
+ DS.__class__.allow_overwrite = True
84
+
85
+ # generate random normal data
86
+ columns=['ra', 'dec', 'redshift', 'u', 'g', 'r', 'i', 'z', 'y']
87
+ rng = np.random.default_rng(0)
88
+ x = rng.normal(loc=23, scale=3, size=(1000, len(columns)))
89
+
90
+ # replace positions with constrained values
91
+ x[:, 0] = np.random.uniform(low=0, high=0.02, size=1000)
92
+ x[:, 1] = np.random.uniform(low=0, high=0.02, size=1000)
93
+
94
+ # replace redshifts with reasonable values
95
+ x[:, 2] = np.linspace(0, 2, x.shape[0])
96
+
97
+ # return data in handle wrapping a pandas DataFrame
98
+ df = pd.DataFrame(x, columns=columns)
99
+ return DS.add_data("data_for_bl", df, TableHandle, path="dummy_for_bl.pd")
100
+
77
101
 
78
102
  @pytest.mark.parametrize("pivot_redshift,errortype", [("fake", TypeError), (-1, ValueError)])
79
103
  def test_InvRedshiftIncompleteness_bad_params(pivot_redshift, errortype):
@@ -391,3 +415,20 @@ def test_LSSTErrorModel_returns_correct_columns(data):
391
415
  assert f"{band}_err" in degraded_data.columns
392
416
  os.remove(degrader.get_output(degrader.get_aliased_tag("output"), final_name=True))
393
417
 
418
+
419
+ def test_EucliErrorModel(data):
420
+ # Setup the stage
421
+ degrader = EuclidErrorModel.make_stage()
422
+
423
+
424
+ def test_BLModel(data_for_bl):
425
+ # Setup the stage
426
+ degrader = UnrecBlModel.make_stage()
427
+
428
+ # Apply the degrader and get the data out
429
+ degraded_data = degrader(data_for_bl).data
430
+
431
+ # Check output data has less rows than input data
432
+ assert degraded_data.shape[0] < data_for_bl.data.shape[0]
433
+
434
+ os.remove(degrader.get_output(degrader.get_aliased_tag("output"), final_name=True))
@@ -0,0 +1,16 @@
1
+ import os
2
+ from rail.utils.testing_utils import build_and_read_pipeline
3
+
4
+ import pytest
5
+
6
+ @pytest.mark.parametrize(
7
+ "pipeline_class",
8
+ [
9
+ 'rail.pipelines.degradation.apply_phot_errors.ApplyPhotErrorsPipeline',
10
+ 'rail.pipelines.degradation.blending.BlendingPipeline',
11
+ 'rail.pipelines.degradation.spectroscopic_selection_pipeline.SpectroscopicSelectionPipeline',
12
+ ]
13
+ )
14
+ def test_build_and_read_pipeline(pipeline_class):
15
+ build_and_read_pipeline(pipeline_class)
16
+
@@ -1,61 +0,0 @@
1
- """The LSST Model for photometric errors."""
2
- from dataclasses import MISSING
3
-
4
- from ceci.config import StageParameter as Param
5
- from photerr import LsstErrorModel as PhotErrErrorModel
6
- from photerr import LsstErrorParams as PhotErrErrorParams
7
- from rail.creation.degrader import Degrader
8
-
9
-
10
- class LSSTErrorModel(Degrader):
11
- """The LSST Model for photometric errors.
12
-
13
- This is a wrapper around the error model from PhotErr. The parameter
14
- docstring below is dynamically added by the installed version of PhotErr:
15
-
16
- """
17
-
18
- # Dynamically add the parameter docstring from PhotErr
19
- __doc__ += PhotErrErrorParams.__doc__
20
-
21
- name = "LSSTErrorModel"
22
- config_options = Degrader.config_options.copy()
23
-
24
- # Dynamically add all parameters from PhotErr
25
- _photerr_params = PhotErrErrorParams.__dataclass_fields__
26
- for key, val in _photerr_params.items():
27
- # Get the default value
28
- if val.default is MISSING:
29
- default = val.default_factory()
30
- else:
31
- default = val.default
32
-
33
- # Add this param to config_options
34
- config_options[key] = Param(
35
- None, # Let PhotErr handle type checking
36
- default,
37
- msg="See the main docstring for details about this parameter.",
38
- required=False,
39
- )
40
-
41
- def __init__(self, args, **kwargs):
42
- """
43
- Constructor
44
-
45
- Does standard Degrader initialization and sets up the error model.
46
- """
47
- super().__init__(args, **kwargs)
48
- self.error_model = PhotErrErrorModel(
49
- **{key: self.config[key] for key in self._photerr_params}
50
- )
51
-
52
- def run(self):
53
- """Return pandas DataFrame with photometric errors."""
54
- # Load the input catalog
55
- data = self.get_data("input")
56
-
57
- # Add photometric errors
58
- obsData = self.error_model(data, random_state=self.config.seed)
59
-
60
- # Return the new catalog
61
- self.add_data("output", obsData)