3232
3333# Share configuration with ZTF
3434CONFIGS_BASE = load_json (
35- "{}/ztf /hostless_detection/config_base.json" .format (os .path .dirname (__file__ ))
35+ "{}/rubin /hostless_detection/config_base.json" .format (os .path .dirname (__file__ ))
3636)
3737CONFIGS = load_json (
38- "{}/ztf /hostless_detection/config.json" .format (os .path .dirname (__file__ ))
38+ "{}/rubin /hostless_detection/config.json" .format (os .path .dirname (__file__ ))
3939)
4040CONFIGS .update (CONFIGS_BASE )
4141
@@ -52,10 +52,16 @@ def run_potential_hostless(
5252 ssObjectId : pd .Series ,
5353 nDiaSources : pd .Series ,
5454 psfFlux : pd .Series ,
55+ templateFlux : pd .Series ,
56+ templateFluxErr : pd .Series ,
5557 midpointMjdTai : pd .Series ,
5658 firstDiaSourceMjdTaiFink : pd .Series ,
5759 simbad_otype : pd .Series ,
5860 gaiadr3_DR3Name : pd .Series ,
61+ mangrove_2MASS_name : pd .Series ,
62+ mangrove_HyperLEDA_name : pd .Series ,
63+ legacydr8_zphot : pd .Series ,
64+ spicy_SPICY : pd .Series ,
5965) -> pd .Series :
6066 """Runs potential hostless candidate detection for Rubin without any filtering
6167
@@ -71,6 +77,10 @@ def run_potential_hostless(
7177 Number of previous detections
7278 psfFlux: pd.Series
7379 Flux in the difference image
80+ templateFlux: pd.Series,
81+ Flux in template image
82+ templateFluxErr: pd.Series
83+ Flux error in template image
7484 midpointMjdTai: pd.Series
7585 Emission date for the alert
7686 firstDiaSourceMjdTaiFink: pd.Series
@@ -79,6 +89,15 @@ def run_potential_hostless(
7989 SIMBAD type. NaN if not existing
8090 gaiadr3_DR3Name: pd.Series
8191 Name in Gaia DR3. NaN if not existing
92+ mangrove_2MASS_name: pd.Series
93+ Name in mangrove 2MASS. NaN if not existing
94+ mangrove_HyperLEDA_name: pd.Series
95+ Name in mangrove HyperLEDA. NaN if not existing
96+ legacydr8_zphot: pd.Series
97+ Photo-z estimate from Legacy Surveys DR8 South Photometric Redshifts catalog.
98+ NaN if not existing
99+ spicy_SPICY
100+ closest source from SPICY catalog. Nan if not existing
82101
83102 Notes
84103 -----
@@ -114,12 +133,18 @@ def run_potential_hostless(
114133 ... F.lit(None),
115134 ... F.lit(3),
116135 ... F.lit(100000000),
136+ ... F.lit(100000000),
137+ ... F.lit(100),
117138 ... df["diaSource.midpointMjdTai"],
118139 ... df["diaSource.midpointMjdTai"],
119140 ... F.lit(None),
141+ ... F.lit(None),
142+ ... F.lit(None),
143+ ... F.lit(None),
144+ ... F.lit(None),
120145 ... F.lit(None),))
121146 >>> df.filter(df.elephant_kstest_no_cuts.kstest_science.isNotNull()).count()
122- 3
147+ 0
123148
124149 # SSO cuts
125150 >>> df = df.withColumn('elephant_kstest_sso_cuts',
@@ -129,12 +154,18 @@ def run_potential_hostless(
129154 ... df["ssSource.ssObjectId"],
130155 ... F.lit(3),
131156 ... F.lit(100000000),
157+ ... F.lit(100000000),
158+ ... F.lit(100),
132159 ... df["diaSource.midpointMjdTai"],
133160 ... df["diaSource.midpointMjdTai"],
134161 ... F.lit(None),
162+ ... F.lit(None),
163+ ... F.lit(None),
164+ ... F.lit(None),
165+ ... F.lit(None),
135166 ... F.lit(None),))
136167 >>> df.filter(df.elephant_kstest_sso_cuts.kstest_science.isNotNull()).count()
137- 1
168+ 0
138169
139170 # All cuts
140171 >>> df = df.withColumn('elephant_kstest',
@@ -144,27 +175,69 @@ def run_potential_hostless(
144175 ... df["ssSource.ssObjectId"],
145176 ... df["diaObject.nDiaSources"],
146177 ... df["diaSource.psfFlux"],
178+ ... df["diaSource.templateFlux"],
179+ ... df["diaSource.templateFluxErr"],
147180 ... df["diaSource.midpointMjdTai"],
148181 ... F.array_min("prvDiaSources.midpointMjdTai"),
149182 ... F.lit("star"),
150- ... F.lit("DR3 toto"),))
183+ ... F.lit("DR3 toto"),
184+ ... F.lit("galaxy"),
185+ ... F.lit("galaxy"),
186+ ... F.lit("galaxy"),
187+ ... F.lit("galaxy"),))
151188 >>> df.filter(df.elephant_kstest.kstest_science.isNotNull()).count()
152189 0
153190 """
154- f_min_point = nDiaSources >= 2 # N + 1
191+ f_min_point = nDiaSources >= CONFIGS [ "minimum_number_of_alerts" ] - 1 # N + 1
155192 # FIXME: put the conversion formula in fink-utils
156- f_bright = (- 2.5 * np .log10 (psfFlux ) + ZP_NJY ) < 20
193+ f_bright = (- 2.5 * np .log10 (psfFlux ) + ZP_NJY ) < CONFIGS [ "cutout_magnitude" ]
157194 f_not_in_simbad = simbad_otype .apply (lambda val : val in BAD_VALUES or pd .isna (val ))
158195 f_not_in_gaia = gaiadr3_DR3Name .apply (lambda val : val in BAD_VALUES or pd .isna (val ))
196+ f_not_in_2mass = mangrove_2MASS_name .apply (
197+ lambda val : val in BAD_VALUES or pd .isna (val )
198+ )
199+ f_not_in_hyperlda = mangrove_HyperLEDA_name .apply (
200+ lambda val : val in BAD_VALUES or pd .isna (val )
201+ )
202+ f_not_in_legacydr8 = legacydr8_zphot .apply (
203+ lambda val : val in BAD_VALUES or pd .isna (val )
204+ )
205+ f_not_in_spicy = spicy_SPICY .apply (lambda val : val in BAD_VALUES or pd .isna (val ))
206+
159207 f_not_sso = ssObjectId .apply (lambda val : val in BAD_VALUES or pd .isna (val ))
160- f_early = (midpointMjdTai - firstDiaSourceMjdTaiFink ) < 30
208+ f_early = (midpointMjdTai - firstDiaSourceMjdTaiFink ) < CONFIGS [ "cutout_timeframe" ]
161209
210+ # Cuts on psfFlux and templateFlux
211+ PSF_FLUX_THRESHOLD = 0
212+ TEMPLATE_FLUX_THRESHOLD = [300 , 2000 ]
213+ psfFlux_cut = psfFlux > PSF_FLUX_THRESHOLD
214+ templateFlux_cut = (templateFlux > TEMPLATE_FLUX_THRESHOLD [0 ]) & (
215+ templateFlux < TEMPLATE_FLUX_THRESHOLD [1 ]
216+ )
217+ # SNR cut > 5
218+ template_snr_cut = (templateFlux / templateFluxErr ) > 5
162219 good_candidate = (
163- f_min_point & f_bright & f_not_in_simbad & f_not_in_gaia & f_not_sso & f_early
220+ f_min_point
221+ & f_bright
222+ & f_not_in_simbad
223+ & f_not_in_gaia
224+ & f_not_sso
225+ & f_early
226+ & psfFlux_cut
227+ & templateFlux_cut
228+ & template_snr_cut
229+ & f_not_in_2mass
230+ & f_not_in_hyperlda
231+ & f_not_in_legacydr8
232+ & f_not_in_spicy
164233 )
165-
166- default_result = {"kstest_science" : None , "kstest_template" : None }
234+ # Process full image
235+ default_result = {
236+ "kstest_science" : None ,
237+ "kstest_template" : None ,
238+ }
167239 kstest_results = []
240+
168241 hostless_science_class = HostLessExtragalacticRubin (CONFIGS_BASE )
169242 for index in range (cutoutScience .shape [0 ]):
170243 if good_candidate [index ]:
@@ -175,10 +248,12 @@ def run_potential_hostless(
175248 science_stamp , template_stamp
176249 )
177250 )
178- kstest_results .append ({
179- "kstest_science" : kstest_science ,
180- "kstest_template" : kstest_template ,
181- })
251+ kstest_results .append (
252+ {
253+ "kstest_science" : kstest_science ,
254+ "kstest_template" : kstest_template ,
255+ }
256+ )
182257 else :
183258 kstest_results .append (default_result )
184259 return pd .Series (kstest_results )
0 commit comments