"""
Wrapper functions to build layers.
Functions
---------
build_one_layer
Build layers for one InImage
build_all_layers
Build layers for all the exposures in the directory path
"""
import multiprocessing as mp
import os
import re
from concurrent.futures import ProcessPoolExecutor, as_completed
from . import coadd
from .layer import get_all_data
[docs]
def build_one_layer(cfg, idsca):
"""
Build layers for one InImage
Instantiates the inimage with a "dummy" block 0
Parameters
----------
cfg : pyimcom.config.Config object
the configuration file
idsca : tuple, (int, int)
the obsid, scaid pair of the image to build
Returns
-------
None
"""
block_zero = coadd.Block(cfg, this_sub=0, run_coadd=False)
block_zero.parse_config() # This loads the observation table, which is needed next.
inimage = coadd.InImage(block_zero, idsca)
get_all_data(inimage)
return None
[docs]
def build_all_layers(cfg, workers=2):
"""
Build layers for all the exposures in the directory path
Parameters
----------
cfg : pyimcom.config.Config object
the configuration file
workers : int
number of workers to use in parallel processing
"""
m = re.search(r"^(.*)\/(.*)", cfg.inpath)
if m:
path = m.group(1)
exp = m.group(2)
idsca_list = []
for _, _, files in os.walk(path):
for file in files:
if file.startswith(exp):
m = re.search(r"_(\d+)_(\d+)\.(fits|asdf)$", file[len(exp) :])
if m:
idsca_list.append((int(m.group(1)), int(m.group(2))))
# This isn't safe with the fork method, so define a context.
# This code isn't necessary in Python 3.14 on POSIX systems, because
# "forkserver" is the default. But this way it will work on 3.12 & 3.13.
start_method = "forkserver" if os.name.lower() == "posix" else "spawn"
ctx = mp.get_context(start_method)
nfail = 0
with ProcessPoolExecutor(max_workers=workers, mp_context=ctx) as executor:
futures = []
for idsca in idsca_list:
futures.append(executor.submit(build_one_layer, cfg, idsca))
# Wait for all futures to complete
for future in as_completed(futures):
try:
future.result()
except Exception as e:
nfail += 1
print(f"Worker failed with exception {e}", flush=True)
if nfail > 0:
raise Exception(f"{nfail:d} instances of build_one_layer failed.")