Skip to content

Commit f4b070e

Browse files
authored
Correlated observation (#239)
* added mask to CorrelatedObservation; works now for multi-band data * much faster correlation function * first stab at resampling observations * AsinhAutomaticNorm works with CorrelatedObservation * removed automatic obs.match(model_frame) in Frame.from_observations; refactored renderer * set weight according to power spectrum; fix padding * renderer set on demand * simplified test * docs update: resampling for multi-res fits * getting rid of ruff complaints (hopefully) * corrected model colors in plot.sources * added Observation.name as consistent plot label
1 parent 987ac3f commit f4b070e

12 files changed

Lines changed: 448 additions & 311 deletions

File tree

docs/0-quickstart.ipynb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,7 @@
8484
"metadata": {},
8585
"outputs": [],
8686
"source": [
87-
"obs = sc2.Observation(\n",
88-
" data,\n",
89-
" weights,\n",
90-
" psf=sc2.ArrayPSF(psf),\n",
91-
" channels=channels,\n",
92-
")"
87+
"obs = sc2.Observation(data, weights=weights, psf=psf, channels=channels)"
9388
]
9489
},
9590
{
@@ -168,7 +163,7 @@
168163
"To fit multiple images with different PSF, different bands, different resolutions, etc..., we must define a model that is superior in all of these aspects, so that each observation can be computed from the model by a degradation operation, the so-called \"forward operator\". The point of joint modeling is to find one superior model of the sky that is consistent with all observations.\n",
169164
"```\n",
170165
"\n",
171-
"In _scarlet2_, the forward operators are implemented as {py:class}`~scarlet2.renderer.Renderer`, which contains, e.g., PSF difference kernels and resampling transformations. It was created earlier by {py:func}`~scarlet2.Frame.from_observations`."
166+
"In _scarlet2_, the forward operators are implemented as {py:class}`~scarlet2.renderer.Renderer`, which contains, e.g., PSF difference kernels and resampling transformations. It gets created when calling `~scarlet2.Observation.match` (which is normally done only when needed, but we can call it explicitly to see its effect):"
172167
]
173168
},
174169
{
@@ -177,7 +172,8 @@
177172
"metadata": {},
178173
"outputs": [],
179174
"source": [
180-
"obs.renderer"
175+
"obs.match(model_frame)\n",
176+
"print(obs.renderer)"
181177
]
182178
},
183179
{

docs/howto/correlated.ipynb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,10 @@
9797
"source": [
9898
"# Scarlet Observations\n",
9999
"obs_hst = sc2.Observation(\n",
100-
" data_hst, wcs=wcs_hst, psf=sc2.ArrayPSF(psf_hst_data), channels=[\"F814W\"], weights=obs_hst_weights\n",
100+
" data_hst, wcs=wcs_hst, psf=psf_hst_data, channels=[\"F814W\"], weights=obs_hst_weights,\n",
101101
")\n",
102102
"model_frame = sc2.Frame.from_observations(observations=obs_hst)\n",
103+
"obs_hst.match(model_frame)\n",
103104
"norm_hst = sc2.plot.AsinhAutomaticNorm(obs_hst)\n",
104105
"sc2.plot.observation(obs_hst, sky_coords=ra_dec, label_kwargs={\"color\": \"red\"});"
105106
]
@@ -144,7 +145,8 @@
144145
"metadata": {},
145146
"outputs": [],
146147
"source": [
147-
"obs_corr = sc2.CorrelatedObservation.from_observation(obs_hst)"
148+
"obs_corr = sc2.CorrelatedObservation.from_observation(obs_hst)\n",
149+
"obs_corr.match(model_frame)"
148150
]
149151
},
150152
{
@@ -269,7 +271,7 @@
269271
"id": "49d4d0ed0bc2467f",
270272
"metadata": {},
271273
"source": [
272-
"We can see that the model picks up a lot of noise fluctuations. While one cannot rule out that some of them correspond to actual source emission, the residuals on the right show that the model is overfitting: the structure in the region of source 5 and 6 is much flatter (and importantly: shows smaller scale residuals) than in other regions.\n",
274+
"A pretty decent fit, but there are some problems left. The model is missing flux around source 10 and the group of sources 0-4 in the left because the boxes are too narrow. We can also see that the model picks up a lot of noise fluctuations. While one cannot rule out that some of them correspond to actual source emission, the residuals on the right show that the model is overfitting: the structure in the region of source 5 and 6 is much flatter (and importantly: shows smaller scale residuals) than in other regions.\n",
273275
"\n",
274276
"Now we repeat the same process with the {py:class}`~scarlet2.CorrelatedObservation` we created earlier:"
275277
]
@@ -308,7 +310,12 @@
308310
{
309311
"cell_type": "markdown",
310312
"id": "dc6f41d9437a271b",
311-
"metadata": {},
313+
"metadata": {
314+
"ExecuteTime": {
315+
"end_time": "2025-12-02T18:59:38.199944Z",
316+
"start_time": "2025-12-02T18:59:38.193610Z"
317+
}
318+
},
312319
"source": [
313320
"The residuals are more \"grainy\" now and look more consistent with the noise in other areas. In the region of sources 5 and 6, the model is still overfitting, but that's because we fit two sources to a single-band image. Such a fit is underconstrained and therefore prone to overfitting. Using additional observations in other filters can help (provided that sources 5 and 6 have different SEDs). See [the multi-observation tutorial](howto/multiresolution) for details."
314321
]

0 commit comments

Comments
 (0)