Skip to content

Choose thresholds, a profile and an executor

This guide assumes you have completed the tutorial.

Set detection thresholds

config = hebog.SourceFinderConfig(
    detection_threshold_sigma=6.0,
    island_threshold_sigma=4.0,
    minimum_island_pixels=10,
    maximum_island_pixels=None,
)
Setting Meaning PyBDSF equivalent
detection_threshold_sigma An island must contain evidence at this signal-to-noise ratio thresh_pix
island_threshold_sigma Islands grow to this lower level; must be below the detection threshold thresh_isl
minimum_island_pixels Smallest island kept minpix_isl
maximum_island_pixels Optional largest island kept —
background estimated (default) subtracts Hebog's spatial background; zero subtracts nothing while the RMS is still estimated mean_map (zero is mean_map="zero", as LSMTool sets it)

Raise the detection threshold for fewer false detections; lower it for completeness at the cost of reliability. The same values are used throughout background protection, direct and multiscale detection, and the final size filter.

A threshold may be any finite positive number and a pixel count any positive integer, NumPy scalars included. Each is held as the Python float or int it equals, so SourceFinderConfig(5, 3, 10) and SourceFinderConfig(5.0, 3.0, 10) are one configuration with one identity in the diagnostics.

Keep the estimated background unless you need PyBDSF's zero mean map: on injected truth it recovers sources on a real background offset far better, while zero agrees more closely with PyBDSF's fluxes on confused fields. All other algorithm settings, such as noise-grid sizes, wavelet scales and fitting bounds, are fixed by the selected profile so that results are reproducible. Every configuration is labelled development-unqualified or custom-unqualified in the diagnostics until Hebog is qualified.

Choose a profile

Profile Use it for Behaviour
continuum (default) General continuum images, including extended emission Finer RMS grid near bright sources whose windows exclude source pixels; associates components into multi-component sources; source INTEGRATED_FLUX is the sum of the fitted components (PyBDSF's definition), or the source's own aperture when no fit was admitted; a source of one fitted component publishes that Gaussian's position, errors, peak and shapes; ASSOCIATION_APERTURE_FLUX holds the aperture, or is empty where it sums to zero or below
compact Fields of unresolved or barely resolved sources, where you want one source per Gaussian No extended-source association; each source carries its one Gaussian's measurement and no aperture flux; diagnostics declare extended-emission-incomplete
config = hebog.SourceFinderConfig(
    detection_threshold_sigma=5.0,
    island_threshold_sigma=3.0,
    minimum_island_pixels=7,
    profile="compact",
)

Do not present a compact catalogue as a general continuum-source catalogue. The output reference defines both source fluxes and where they differ.

Use several cores or a Dask cluster

The third argument of find_sources decides where the work runs. The products are the same in every case.

from hebog.executors import DaskExecutor, SerialExecutor, ThreadExecutor

result = hebog.find_sources(request, config, SerialExecutor())

with ThreadExecutor(thread_count=4) as executor:
    result = hebog.find_sources(request, config, executor)

from dask.distributed import Client

with Client("tcp://scheduler:8786") as client:
    result = hebog.find_sources(request, config, DaskExecutor(client))

Hebog never starts a cluster for you. On a multi-node cluster, the image and the parent of the output directory must be on storage that every worker sees at the same absolute path. Today's limit is 22,500 pixels per side. Background and RMS estimation tiles at every size, but every other stage uses 2,048-pixel cores, so an image up to 2,048 pixels gives those stages a single tile and little to parallelise; above that they tile too. On the development machine a four-worker local Dask cluster finished the 10,000² LoTSS-DR3 anchor in about 0.4 of the serial executor's time, with identical products, but twelve threads of a ThreadExecutor took 0.84 of one thread's time, because Python's global lock holds them: for speed, use Dask workers in separate processes. Progress against goals has the dated figures. Integrate Hebog into a pipeline has the details.

On Windows, threads in one process take turns at the FFT convolutions of the multiscale and fitting stages. SciPy's Windows wheels build its FFT without the lock that protects its shared plan cache, so concurrent transforms can corrupt memory; Hebog serializes them there. For parallel FFTs on Windows, use Dask workers in separate processes rather than threads.

Re-run or retry

  • A failed run leaves no output directory. Run the same request again.
  • A killed run leaves a hidden .<output name>.<random> staging directory beside the output. Running the same request again removes it once the killed process has provably stopped, and warns with hebog.SourceFinderStagingWarning about each one it finds; see failure handling.
  • Running a request again after its run finished returns the products it published without analysing the image again, when the run ID, the input bytes, the configuration and the Hebog science are the same.
  • Any other existing output directory raises hebog.SourceFinderOutputExistsError. Remove or rename it yourself, or choose another directory; Hebog never deletes your files, only the staging directories its own stopped runs left.
  • To repeat a result exactly, pin the Hebog version and compare diagnostics.provenance, which records checksums of the input, the configuration and the implementation.