@@ -285,6 +285,8 @@ def get(
285285 # Grab objective properties to pass to sample
286286 objective_properties = self ._objective .properties ()
287287
288+ #TODO: TBE
289+ """
288290 # Calculate required output image for the given upscale.
289291 # This upscale way will be deprecated in favor of dt.Upscale().
290292 _upscale_given_by_optics = objective_properties["upscale"]
@@ -296,79 +298,110 @@ def get(
296298 *objective_properties["voxel_size"], *_upscale_given_by_optics
297299 )
298300 ):
301+ """
302+
303+ with u .context (create_context (* objective_properties ["voxel_size" ])):
299304
300305 upscale = np .round (get_active_scale ())
301306
302- output_region = objective_properties .pop ("output_region" )
303- objective_properties ["output_region" ] = [
304- int (o * upsc )
305- for o , upsc in zip (
306- output_region , (upscale [0 ], upscale [1 ], upscale [0 ], upscale [1 ])
307- )
308- ]
309-
310- padding = objective_properties .pop ("padding" )
311- objective_properties ["padding" ] = [
312- int (p * upsc )
313- for p , upsc in zip (
314- padding , (upscale [0 ], upscale [1 ], upscale [0 ], upscale [1 ])
315- )
316- ]
307+ def _scale_region_2d (
308+ region : list [int ],
309+ upscale : tuple [float , float , float ],
310+ ) -> list [int ]:
311+ """Scale a 4-tuple region (x_min, y_min, x_max, y_max) or
312+ padding using the lateral upscale factors (ux, uy)."""
313+ ux , uy , _ = upscale
314+ return [int (v * f ) for v , f in zip (region , (ux , uy , ux , uy ))]
317315
316+ # Scale output region from optics into sample voxel units.
317+ output_region = objective_properties .pop ("output_region" )
318+ objective_properties ["output_region" ] = _scale_region_2d (
319+ output_region ,
320+ upscale ,
321+ )
318322 self ._objective .output_region .set_value (
319323 objective_properties ["output_region" ]
320324 )
325+
326+ # Scale padding region in the same way (left, top, right, bottom).
327+ padding = objective_properties .pop ("padding" )
328+ objective_properties ["padding" ] = _scale_region_2d (
329+ padding ,
330+ upscale ,
331+ )
321332 self ._objective .padding .set_value (objective_properties ["padding" ])
322333
334+ # Propagate all relevant properties from the objective to the
335+ # sample graph. This ensures scatterers are evaluated in the
336+ # same voxel size, output region, and padding as the optics.
337+ # The extra flag `return_fft=True` is forced here because most
338+ # objectives (e.g., Brightfield, Holography) operate in Fourier
339+ # space, and they require scatterers to provide Fourier-domain
340+ # data in addition to real-space volumes.
323341 propagate_data_to_dependencies (
324- self ._sample , ** {"return_fft" : True , ** objective_properties }
342+ self ._sample ,
343+ ** {"return_fft" : True , ** objective_properties },
325344 )
326345
346+ # Evaluate the sample feature to obtain scatterers.
347+ # The result may be a single scatterer or a list of them.
327348 list_of_scatterers = self ._sample ()
328-
329349 if not isinstance (list_of_scatterers , list ):
330350 list_of_scatterers = [list_of_scatterers ]
331351
332352 # All scatterers that are defined as volumes.
333- volume_samples = [
353+ # Volume scatterers occupy voxels in 3D (e.g. PointParticle).
354+ volume_scatterers = [
334355 scatterer
335356 for scatterer in list_of_scatterers
336357 if not scatterer .get_property ("is_field" , default = False )
337358 ]
338359
339360 # All scatterers that are defined as fields.
340- field_samples = [
361+ # Field scatterers provide a complex field directly,
362+ # bypassing volume merge.
363+ field_scatterers = [
341364 scatterer
342365 for scatterer in list_of_scatterers
343366 if scatterer .get_property ("is_field" , default = False )
344367 ]
345368
369+
370+
371+
372+
373+
374+
375+
346376 # Merge all volumes into a single volume.
347377 sample_volume , limits = _create_volume (
348- volume_samples ,
378+ volume_scatterers ,
349379 ** objective_properties ,
350380 )
351381 sample_volume = Image (sample_volume )
352382
353383 # Merge all properties into the volume.
354- for scatterer in volume_samples + field_samples :
384+ for scatterer in volume_scatterers + field_scatterers :
355385 sample_volume .merge_properties_from (scatterer )
356386
357387 # Let the objective know about the limits of the volume and all the fields.
358388 propagate_data_to_dependencies (
359389 self ._objective ,
360390 limits = limits ,
361- fields = field_samples ,
391+ fields = field_scatterers ,
362392 )
363393
364394 imaged_sample = self ._objective .resolve (sample_volume )
365395
396+ #TODO: TBE
397+ """
366398 # Handling separately upscale given by optics.
367399 # This upscale way will be deprecated in favor of dt.Upscale().
368400 if _upscale_given_by_optics != (1, 1, 1):
369401 imaged_sample = AveragePooling((*_upscale_given_by_optics[:2], 1))(
370402 imaged_sample
371403 )
404+ """
372405
373406 return imaged_sample
374407
0 commit comments