Basic Usage#
How to use fpho with your images.
Getting ready#
First, you will need collect the appropriate imaging data, PSFs, and identify a an initial list or catalog of ‘peaks’ to be fit. A pre-processing script may be used to convert the imaging data into an efficient format useable by forcepho (a pixel-data store and meta-data store). See ./inputs.rst for details
Second, you will need to generate a configuration file with information about data input and output locations and details for the fitting process. See ./configuration.rst for details
A Gaussian mixture approximation to each relevant PSF must be generated, using
tools provided with forcepho. These are stored in an HDF5 file, in data groups
keyed by FILTER.
Then, the following steps will lead to output that can be post-processed. See ./output.md for details on post-processing
Basic Fitting#
The basic procedure requires several ingredients to be instantiated using the information above. Examples are given below for the simple FITS file interface with CPU Kernel.
A
SuperScenethat holds global parameter state and parameter bounds, and can be used to check out sub-scenes.sceneDB = LinkedSuperScene(sourcecat=cat, bands=bands, statefile=os.path.join(config.outdir, "final_scene.fits"), roi=cat["roi"], bounds_kwargs=bounds_kwargs, target_niter=config.sampling_draws)
A
Patcherobject that organizes image pixel data and image meta data.class Patcher(FITSPatch, CPUPatchMixin): pass patcher = Patcher(fitsfiles=config.image_names, psfstore=config.psfstore, splinedata=config.splinedatafile, sci_ext=1, unc_ext=2, return_residual=True)
Then a loop can start that checks out sub-scenes, finds the relevant pixel data, and constructs an object that can compute posterior probabilities:
patchID = 0 # Draw scenes until all sources have gotten target number of iterations of HMC while sceneDB.undone: # Draw the sub-scene and associated information # A seed of -1 will choose an available scene at random region, active, fixed = sceneDB.checkout_region(seed_index=-1) bounds, cov = sceneDB.bounds_and_covs(active["source_index"]) # Collect the pixel data and meta-data patcher.build_patch(region, None, allbands=bands) # Transfer data to device, subtract fixed sources, set up parameter transforms model, q = patcher.prepare_model(active=active, fixed=fixed, bounds=bounds, shapes=sceneDB.shape_cols)
Within the loop we will either do optimization or HMC sampling, and then check the scene back in. Here we do sampling using
littlemcmc:# run HMC, with warmup out, step, stats = run_lmc(model, q.copy(), n_draws=config.sampling_draws, warmup=config.warmup, z_cov=cov, full=True, weight=max(10, active["n_iter"].min()), discard_tuned_samples=True, max_treedepth=config.max_treedepth, progressbar=config.progressbar) # Add additional information to the output final, covs = out.fill(region, active, fixed, model, bounds=bounds, step=step, stats=stats, patchID=patchID) # Write results to disk write_to_disk(out, config.outroot, model, config) # Check in the scene with new parameter values sceneDB.checkin_region(final, fixed, config.sampling_draws, block_covs=covs, taskID=0) # write current global parameter state to disk as a failsafe sceneDB.writeout() # increment patch number patchID += 1
All Steps#
Stepping back a bit, one might want to do an initial round of optimization of the entire catalog, and then use that as initialization for a sampling phase. The steps to do such a full run might look like the following
Create PSF mixtures for mosaic and/or individual exposures
(optional) Pre-Process (
preprocess.py)This creates the HDF5 storage files for pixel and meta-data. If slopes are present, make separate stores for mosaic and slope pixels.
Make catalog of initial peaks in forcepho format
The initial peaks to be fit must be supplied in a FITS binary table in the appropriate format. See ./inputs.rst for details of this format.
Background subtraction & optimization loop
Optimize sources in the catalog (
optimize.py) using mosaic data with a S/N cap.(optional) Fit for a residual background (
background.py) in the mosaic. If significant, put resulting tweak values in config file.(optional) Look for objects missing in the initial catalog.
(optional) Re-optimize sources in the catalog (
optimize.py) based on mosaic.Replace initialization catalog with the optimization results, including flux uncertainty estimates This is done with
postprocess.py --root output/<run_name> --catname postop_catalog.fits --mode postop
Sample posterior for source properties (
sampling.py).Post-process to create residual images (if available), show chains, etc…