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 withhebog.SourceFinderStagingWarningabout 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.