pz-rail-astro-tools 1.0.5__tar.gz → 1.0.7__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.
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/PKG-INFO +1 -1
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/pz_rail_astro_tools.egg-info/PKG-INFO +1 -1
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/pz_rail_astro_tools.egg-info/SOURCES.txt +1 -1
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/astro_tools/_version.py +2 -2
- pz_rail_astro_tools-1.0.7/src/rail/creation/degraders/unrec_bl_model.py +178 -0
- pz_rail_astro_tools-1.0.7/src/rail/pipelines/degradation/truth_to_observed.py +83 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/tests/astro_tools/test_degraders.py +18 -6
- pz_rail_astro_tools-1.0.7/tests/astro_tools/test_pipline.py +17 -0
- pz_rail_astro_tools-1.0.5/src/rail/creation/degraders/bl_demo.ipynb +0 -206
- pz_rail_astro_tools-1.0.5/src/rail/creation/degraders/unrec_bl_model.py +0 -98
- pz_rail_astro_tools-1.0.5/tests/astro_tools/test_pipline.py +0 -16
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.copier-answers.yml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/ISSUE_TEMPLATE/0-general_issue.md +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/ISSUE_TEMPLATE/1-bug_report.md +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/ISSUE_TEMPLATE/2-feature_request.md +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/pull_request_template.md +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/workflows/add-issue-to-project-tracker.yml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/workflows/linting.yml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/workflows/publish-to-pypi.yml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/workflows/smoke-test.yml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/workflows/testing-and-coverage.yml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.gitignore +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.pre-commit-config.yaml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/LICENSE +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/README.md +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/environment.yml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/pyproject.toml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/setup.cfg +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/setup.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/pz_rail_astro_tools.egg-info/dependency_links.txt +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/pz_rail_astro_tools.egg-info/requires.txt +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/pz_rail_astro_tools.egg-info/top_level.txt +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/astro_tools/__init__.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/creation/degraders/grid_selection.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/creation/degraders/observing_condition_degrader.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/creation/degraders/photometric_errors.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/creation/degraders/spectroscopic_degraders.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/creation/degraders/spectroscopic_selections.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/creation/engines/gcr_engine.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/examples_data/creation_data/data/HSC_grid_settings.pkl +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/examples_data/creation_data/data/hsc_ratios_and_specz.hdf5 +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/examples_data/creation_data/data/survey_conditions/DC2-dr6-galcounts-i20-i25.3-nside-128.fits +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/examples_data/creation_data/data/survey_conditions/DC2-mask-neg-nside-128.fits +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/examples_data/creation_data/data/survey_conditions/minion_1016_dc2_Median_airmass_i_and_nightlt1825_HEAL.fits +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/examples_data/creation_data/data/survey_conditions/minion_1016_dc2_Median_fiveSigmaDepth_i_and_nightlt1825_HEAL.fits +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/examples_data/testdata/rubin_dm_dc2_example2.pq +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/pipelines/degradation/apply_phot_errors.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/pipelines/degradation/blending.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/pipelines/degradation/spectroscopic_selection_pipeline.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/tools/photometry_tools.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/tests/astro_tools/gcr_test_data/schema.yaml +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/tests/astro_tools/gcr_test_data/test_object_tract_4850.hdf5 +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/tests/astro_tools/test_core.py +0 -0
- {pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/tests/astro_tools/test_gcr_engine.py +0 -0
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/pz_rail_astro_tools.egg-info/SOURCES.txt
RENAMED
|
@@ -22,7 +22,6 @@ 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
|
|
26
25
|
src/rail/creation/degraders/grid_selection.py
|
|
27
26
|
src/rail/creation/degraders/observing_condition_degrader.py
|
|
28
27
|
src/rail/creation/degraders/photometric_errors.py
|
|
@@ -40,6 +39,7 @@ src/rail/examples_data/testdata/rubin_dm_dc2_example2.pq
|
|
|
40
39
|
src/rail/pipelines/degradation/apply_phot_errors.py
|
|
41
40
|
src/rail/pipelines/degradation/blending.py
|
|
42
41
|
src/rail/pipelines/degradation/spectroscopic_selection_pipeline.py
|
|
42
|
+
src/rail/pipelines/degradation/truth_to_observed.py
|
|
43
43
|
src/rail/tools/photometry_tools.py
|
|
44
44
|
tests/astro_tools/test_core.py
|
|
45
45
|
tests/astro_tools/test_degraders.py
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""Model for Creating Unrecognized Blends"""
|
|
2
|
+
|
|
3
|
+
from ceci.config import StageParameter as Param
|
|
4
|
+
from rail.creation.degrader import Degrader
|
|
5
|
+
from rail.core.data import PqHandle
|
|
6
|
+
from rail.core.common_params import SHARED_PARAMS
|
|
7
|
+
import numpy as np, pandas as pd
|
|
8
|
+
import FoFCatalogMatching
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class UnrecBlModel(Degrader):
|
|
12
|
+
"""Model for Creating Unrecognized Blends.
|
|
13
|
+
|
|
14
|
+
Finding objects nearby each other. Merge them into one blended
|
|
15
|
+
Use Friends of Friends for matching. May implement shape matching in the future.
|
|
16
|
+
Take avergaged Ra and Dec for blended source, and sum up fluxes in each band. May implement merged shapes in the future.
|
|
17
|
+
|
|
18
|
+
"""
|
|
19
|
+
name = "UnrecBlModel"
|
|
20
|
+
config_options = Degrader.config_options.copy()
|
|
21
|
+
config_options.update(ra_label=Param(str, 'ra', msg='ra column name'),
|
|
22
|
+
dec_label=Param(str, 'dec', msg='dec column name'),
|
|
23
|
+
linking_lengths=Param(float, 1.0, msg='linking_lengths for FoF matching'),
|
|
24
|
+
bands=SHARED_PARAMS,
|
|
25
|
+
ref_band=SHARED_PARAMS,
|
|
26
|
+
redshift_col=SHARED_PARAMS,
|
|
27
|
+
match_size=Param(bool, False, msg='consider object size for finding blends'),
|
|
28
|
+
match_shape=Param(bool, False, msg='consider object shape for finding blends'),
|
|
29
|
+
obj_size=Param(str, 'obj_size', msg='object size column name'),
|
|
30
|
+
a=Param(str, 'semi_major', msg='semi major axis column name'),
|
|
31
|
+
b=Param(str, 'semi_minor', msg='semi minor axis column name'),
|
|
32
|
+
theta=Param(str, 'orientation', msg='orientation angle column name'))
|
|
33
|
+
|
|
34
|
+
outputs = [("output", PqHandle), ("compInd", PqHandle)]
|
|
35
|
+
|
|
36
|
+
blend_info_cols = ['group_id', 'n_obj', 'brightest_flux', 'total_flux', 'z_brightest', 'z_weighted', 'z_mean', 'z_stdev']
|
|
37
|
+
|
|
38
|
+
def __call__(self, sample, seed: int = None):
|
|
39
|
+
"""The main interface method for ``Degrader``.
|
|
40
|
+
|
|
41
|
+
Applies degradation.
|
|
42
|
+
|
|
43
|
+
This will attach the sample to this `Degrader` (for introspection and
|
|
44
|
+
provenance tracking).
|
|
45
|
+
|
|
46
|
+
Then it will call the run() and finalize() methods, which need to be
|
|
47
|
+
implemented by the sub-classes.
|
|
48
|
+
|
|
49
|
+
The run() method will need to register the data that it creates to this
|
|
50
|
+
Estimator by using ``self.add_data('output', output_data)``.
|
|
51
|
+
|
|
52
|
+
Finally, this will return a PqHandle providing access to that output
|
|
53
|
+
data.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
sample : table-like
|
|
58
|
+
The sample to be degraded
|
|
59
|
+
seed : int, default=None
|
|
60
|
+
An integer to set the numpy random seed
|
|
61
|
+
|
|
62
|
+
Returns
|
|
63
|
+
-------
|
|
64
|
+
output_data : PqHandle
|
|
65
|
+
A handle giving access to a table with degraded sample
|
|
66
|
+
"""
|
|
67
|
+
if seed is not None:
|
|
68
|
+
self.config.seed = seed
|
|
69
|
+
|
|
70
|
+
self.set_data("input", sample)
|
|
71
|
+
self.run()
|
|
72
|
+
self.finalize()
|
|
73
|
+
|
|
74
|
+
return {'output':self.get_handle("output"), 'compInd':self.get_handle("compInd")}
|
|
75
|
+
|
|
76
|
+
def __match_bl__(self, data):
|
|
77
|
+
|
|
78
|
+
"""Group sources with friends of friends"""
|
|
79
|
+
|
|
80
|
+
ra_label, dec_label = self.config.ra_label, self.config.dec_label
|
|
81
|
+
linking_lengths = self.config.linking_lengths
|
|
82
|
+
|
|
83
|
+
results = FoFCatalogMatching.match({'truth': data}, linking_lengths=linking_lengths, ra_label=ra_label, dec_label=dec_label)
|
|
84
|
+
results.remove_column('catalog_key')
|
|
85
|
+
|
|
86
|
+
results = results.to_pandas(index='row_index')
|
|
87
|
+
results.sort_values(by='row_index', inplace=True)
|
|
88
|
+
|
|
89
|
+
## adding the group id as the last column to data
|
|
90
|
+
matchData = pd.merge(data, results, left_index=True, right_index=True)
|
|
91
|
+
|
|
92
|
+
return matchData, results
|
|
93
|
+
|
|
94
|
+
def __merge_bl__(self, data):
|
|
95
|
+
|
|
96
|
+
"""Merge sources within a group into unrecognized blends."""
|
|
97
|
+
|
|
98
|
+
group_id = data['group_id']
|
|
99
|
+
unique_id = np.unique(group_id)
|
|
100
|
+
|
|
101
|
+
ra_label, dec_label = self.config.ra_label, self.config.dec_label
|
|
102
|
+
cols = [ra_label, dec_label] + [b for b in self.config.bands] + self.blend_info_cols
|
|
103
|
+
|
|
104
|
+
N_rows = len(unique_id)
|
|
105
|
+
N_cols = len(cols)
|
|
106
|
+
|
|
107
|
+
# compute the fluxes once for all the galaxies
|
|
108
|
+
fluxes = {b:10**(-data[b]/2.5) for b in self.config.bands}
|
|
109
|
+
|
|
110
|
+
# pull the column indices
|
|
111
|
+
idx_ra = cols.index(ra_label)
|
|
112
|
+
idx_dec = cols.index(dec_label)
|
|
113
|
+
idx_n_obj = cols.index('n_obj')
|
|
114
|
+
idx_brightest_flux = cols.index('brightest_flux')
|
|
115
|
+
idx_total_flux = cols.index('total_flux')
|
|
116
|
+
idx_z_brightest = cols.index('z_brightest')
|
|
117
|
+
idx_z_mean = cols.index('z_mean')
|
|
118
|
+
idx_z_weighted = cols.index('z_weighted')
|
|
119
|
+
idx_z_stdev = cols.index('z_stdev')
|
|
120
|
+
|
|
121
|
+
mergeData = np.zeros((N_rows, N_cols))
|
|
122
|
+
for i, id in enumerate(unique_id):
|
|
123
|
+
|
|
124
|
+
# Get the mask for this grouping
|
|
125
|
+
mask = data['group_id'] == id
|
|
126
|
+
|
|
127
|
+
# Get the data and fluxes for this grouping
|
|
128
|
+
this_group = data[mask]
|
|
129
|
+
these_fluxes = {b:fluxes[b][mask] for b in self.config.bands}
|
|
130
|
+
|
|
131
|
+
# Pull put some useful stuff
|
|
132
|
+
n_obj = len(this_group)
|
|
133
|
+
ref_fluxes = these_fluxes[self.config.ref_band]
|
|
134
|
+
these_redshifts = this_group[self.config.redshift_col]
|
|
135
|
+
|
|
136
|
+
## take the average position for the blended source
|
|
137
|
+
mergeData[i, idx_ra] = this_group[ra_label].mean()
|
|
138
|
+
mergeData[i, idx_dec] = this_group[dec_label].mean()
|
|
139
|
+
|
|
140
|
+
## sum up the fluxes into the blended source
|
|
141
|
+
for b in self.config.bands:
|
|
142
|
+
mergeData[i, cols.index(b)] = -2.5*np.log10(np.sum(these_fluxes[b]))
|
|
143
|
+
|
|
144
|
+
brighest_idx = np.argmax(ref_fluxes)
|
|
145
|
+
|
|
146
|
+
mergeData[i, idx_n_obj] = n_obj
|
|
147
|
+
mergeData[i, idx_brightest_flux] = ref_fluxes.max()
|
|
148
|
+
mergeData[i, idx_total_flux] = np.sum(ref_fluxes)
|
|
149
|
+
mergeData[i, idx_z_brightest] = these_redshifts.iloc[brighest_idx]
|
|
150
|
+
mergeData[i, idx_z_mean] = np.mean(these_redshifts)
|
|
151
|
+
mergeData[i, idx_z_weighted] = np.sum(these_redshifts*ref_fluxes)/np.sum(ref_fluxes)
|
|
152
|
+
if n_obj > 1:
|
|
153
|
+
mergeData[i, idx_z_stdev] = np.std(these_redshifts)
|
|
154
|
+
else:
|
|
155
|
+
mergeData[i, idx_z_stdev] = 0.
|
|
156
|
+
|
|
157
|
+
mergeData[:,cols.index('group_id')] = unique_id
|
|
158
|
+
mergeData_df = pd.DataFrame(data=mergeData, columns=cols)
|
|
159
|
+
mergeData_df['group_id'] = mergeData_df['group_id'].astype(int)
|
|
160
|
+
mergeData_df['n_obj'] = mergeData_df['n_obj'].astype(int)
|
|
161
|
+
|
|
162
|
+
return mergeData_df
|
|
163
|
+
|
|
164
|
+
def run(self):
|
|
165
|
+
"""Return pandas DataFrame with blending errors."""
|
|
166
|
+
|
|
167
|
+
# Load the input catalog
|
|
168
|
+
data = self.get_data("input")
|
|
169
|
+
|
|
170
|
+
# Match for close-by objects
|
|
171
|
+
matchData, compInd = self.__match_bl__(data)
|
|
172
|
+
|
|
173
|
+
# Merge matched objects into unrec-bl
|
|
174
|
+
blData = self.__merge_bl__(matchData)
|
|
175
|
+
|
|
176
|
+
# Return the new catalog and component index in original catalog
|
|
177
|
+
self.add_data("output", blData)
|
|
178
|
+
self.add_data("compInd", compInd)
|
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
from rail.creation.degraders.unrec_bl_model import UnrecBlModel
|
|
18
|
+
|
|
19
|
+
from .spectroscopic_selection_pipeline import SELECTORS, CommonConfigParams
|
|
20
|
+
from .apply_phot_errors import ERROR_MODELS
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if 'PZ_DUSTMAP_DIR' not in os.environ: # pragma: no cover
|
|
24
|
+
os.environ['PZ_DUSTMAP_DIR'] = '.'
|
|
25
|
+
|
|
26
|
+
dustmap_dir = os.path.expandvars("${PZ_DUSTMAP_DIR}")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TruthToObservedPipeline(RailPipeline):
|
|
30
|
+
|
|
31
|
+
default_input_dict = dict(input='dummy.in')
|
|
32
|
+
|
|
33
|
+
def __init__(self, error_models=None, selectors=None, blending=False):
|
|
34
|
+
RailPipeline.__init__(self)
|
|
35
|
+
|
|
36
|
+
DS = RailStage.data_store
|
|
37
|
+
DS.__class__.allow_overwrite = True
|
|
38
|
+
|
|
39
|
+
if error_models is None:
|
|
40
|
+
error_models = ERROR_MODELS.copy()
|
|
41
|
+
|
|
42
|
+
if selectors is None:
|
|
43
|
+
selectors = SELECTORS.copy()
|
|
44
|
+
|
|
45
|
+
config_pars = CommonConfigParams.copy()
|
|
46
|
+
|
|
47
|
+
self.reddener = Reddener.build(
|
|
48
|
+
dustmap_dir=dustmap_dir,
|
|
49
|
+
copy_all_cols=True,
|
|
50
|
+
)
|
|
51
|
+
previous_stage = self.reddener
|
|
52
|
+
|
|
53
|
+
if blending:
|
|
54
|
+
self.unrec_bl = UnrecBlModel.build()
|
|
55
|
+
previous_stage = self.unrec_bl
|
|
56
|
+
|
|
57
|
+
for key, val in error_models.items():
|
|
58
|
+
error_model_class = ceci.PipelineStage.get_stage(val['ErrorModel'], val['Module'])
|
|
59
|
+
the_error_model = error_model_class.make_and_connect(
|
|
60
|
+
name=f'error_model_{key}',
|
|
61
|
+
connections=dict(input=previous_stage.io.output),
|
|
62
|
+
hdf5_groupname='',
|
|
63
|
+
)
|
|
64
|
+
self.add_stage(the_error_model)
|
|
65
|
+
previous_stage = the_error_model
|
|
66
|
+
|
|
67
|
+
dereddener_errors = Dereddener.make_and_connect(
|
|
68
|
+
name=f"deredden_{key}",
|
|
69
|
+
dustmap_dir=dustmap_dir,
|
|
70
|
+
connections=dict(input=previous_stage.io.output),
|
|
71
|
+
copy_all_cols=True,
|
|
72
|
+
)
|
|
73
|
+
self.add_stage(dereddener_errors)
|
|
74
|
+
previous_stage = dereddener_errors
|
|
75
|
+
|
|
76
|
+
for key2, val2 in selectors.items():
|
|
77
|
+
the_class = ceci.PipelineStage.get_stage(val2['Select'], val2['Module'])
|
|
78
|
+
the_selector = the_class.make_and_connect(
|
|
79
|
+
name=f'select_{key}_{key2}',
|
|
80
|
+
connections=dict(input=previous_stage.io.output),
|
|
81
|
+
**config_pars,
|
|
82
|
+
)
|
|
83
|
+
self.add_stage(the_selector)
|
|
@@ -83,16 +83,14 @@ def data_for_bl():
|
|
|
83
83
|
DS.__class__.allow_overwrite = True
|
|
84
84
|
|
|
85
85
|
# generate random normal data
|
|
86
|
-
columns=['ra', 'dec', '
|
|
86
|
+
columns=['ra', 'dec', 'u', 'g', 'r', 'i', 'z', 'y', 'redshift']
|
|
87
87
|
rng = np.random.default_rng(0)
|
|
88
88
|
x = rng.normal(loc=23, scale=3, size=(1000, len(columns)))
|
|
89
89
|
|
|
90
90
|
# replace positions with constrained values
|
|
91
91
|
x[:, 0] = np.random.uniform(low=0, high=0.02, size=1000)
|
|
92
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])
|
|
93
|
+
x[:, 8] = np.random.uniform(low=0, high=3.00, size=1000)
|
|
96
94
|
|
|
97
95
|
# return data in handle wrapping a pandas DataFrame
|
|
98
96
|
df = pd.DataFrame(x, columns=columns)
|
|
@@ -423,12 +421,26 @@ def test_EucliErrorModel(data):
|
|
|
423
421
|
|
|
424
422
|
def test_BLModel(data_for_bl):
|
|
425
423
|
# Setup the stage
|
|
426
|
-
|
|
424
|
+
|
|
425
|
+
degrader = UnrecBlModel.make_stage(
|
|
426
|
+
name='unrec_bl_model',
|
|
427
|
+
ra_label='ra',
|
|
428
|
+
dec_label='dec',
|
|
429
|
+
linking_lengths=1.0,
|
|
430
|
+
bands='ugrizy',
|
|
431
|
+
ref_band='i',
|
|
432
|
+
seed=1234)
|
|
427
433
|
|
|
428
434
|
# Apply the degrader and get the data out
|
|
429
|
-
|
|
435
|
+
outputs = degrader(data_for_bl)
|
|
436
|
+
degraded_data = outputs['output'].data
|
|
437
|
+
truth_components = outputs['compInd'].data
|
|
430
438
|
|
|
431
439
|
# Check output data has less rows than input data
|
|
432
440
|
assert degraded_data.shape[0] < data_for_bl.data.shape[0]
|
|
433
441
|
|
|
442
|
+
# Check components has the same rows as input data
|
|
443
|
+
assert truth_components.shape[0] == data_for_bl.data.shape[0]
|
|
444
|
+
|
|
434
445
|
os.remove(degrader.get_output(degrader.get_aliased_tag("output"), final_name=True))
|
|
446
|
+
os.remove(degrader.get_output(degrader.get_aliased_tag("compInd"), final_name=True))
|
|
@@ -0,0 +1,17 @@
|
|
|
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, options",
|
|
8
|
+
[
|
|
9
|
+
('rail.pipelines.degradation.apply_phot_errors.ApplyPhotErrorsPipeline', {}),
|
|
10
|
+
('rail.pipelines.degradation.blending.BlendingPipeline', {}),
|
|
11
|
+
('rail.pipelines.degradation.spectroscopic_selection_pipeline.SpectroscopicSelectionPipeline', {}),
|
|
12
|
+
('rail.pipelines.degradation.truth_to_observed.TruthToObservedPipeline', {'blending':True}),
|
|
13
|
+
]
|
|
14
|
+
)
|
|
15
|
+
def test_build_and_read_pipeline(pipeline_class, options):
|
|
16
|
+
build_and_read_pipeline(pipeline_class, **options)
|
|
17
|
+
|
|
@@ -1,206 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
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)
|
|
@@ -1,16 +0,0 @@
|
|
|
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
|
-
|
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/ISSUE_TEMPLATE/0-general_issue.md
RENAMED
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/ISSUE_TEMPLATE/1-bug_report.md
RENAMED
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/ISSUE_TEMPLATE/2-feature_request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/workflows/publish-to-pypi.yml
RENAMED
|
File without changes
|
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/.github/workflows/testing-and-coverage.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/creation/engines/gcr_engine.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/src/rail/pipelines/degradation/blending.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/tests/astro_tools/gcr_test_data/schema.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pz_rail_astro_tools-1.0.5 → pz_rail_astro_tools-1.0.7}/tests/astro_tools/test_gcr_engine.py
RENAMED
|
File without changes
|