Skip to content

Commit

Permalink
Merge pull request #79 from winter-telescope/calhunter
Browse files Browse the repository at this point in the history
Calhunter
  • Loading branch information
robertdstein authored Aug 4, 2022
2 parents d1f7e7e + 1adf9f0 commit 852c6c7
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 40 deletions.
32 changes: 1 addition & 31 deletions winterdrp/monitor/base_monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,11 @@
from winterdrp.pipelines.summer.summer_pipeline import load_raw_summer_image
from winterdrp.processors.utils.image_selector import select_from_images
from winterdrp.processors.utils.image_loader import load_from_dir, ImageNotFoundError
from winterdrp.processors.utils.supplement_cals import CalHunter, CalRequirement

logger = logging.getLogger(__name__)


class CalRequirement:

def __init__(self, target_name, required_field: str, required_values: str | list[str]):
self.target_name = target_name
self.required_field = required_field
self.required_values = required_values
self.success = False
self.data = dict()

def check_images(self, images, headers):

new_images, new_headers = select_from_images(
images, headers,
header_key="TARGET",
target_values=self.target_name
)

if len(new_images) > 0:
for value in self.required_values:
if value not in self.data.keys():
sub_images, sub_headers = select_from_images(
new_images, new_headers,
header_key=self.required_field,
target_values=value
)
if len(sub_images) > 0:
self.data[value] = [sub_images, sub_headers]

self.success = len(self.data) == len(self.required_values)


class NewImageHandler(FileSystemEventHandler):

def __init__(self, queue):
Expand Down
17 changes: 8 additions & 9 deletions winterdrp/pipelines/summer/summer_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from winterdrp.processors.utils.image_selector import ImageSelector, ImageBatcher
from winterdrp.processors.split import SplitImage, sub_id_key
from winterdrp.processors.utils import ImageSaver, HeaderAnnotator, ImageLoader, ImageSelector, ImageBatcher
from winterdrp.processors.utils.cal_hunter import CalHunter, CalRequirement
from winterdrp.processors.utils.image_rejector import ImageRejector
from winterdrp.processors.photcal import PhotCalibrator
from winterdrp.processors import MaskPixels, BiasCalibrator, FlatCalibrator
Expand Down Expand Up @@ -197,19 +198,19 @@ class SummerPipeline(Pipeline):
schema_dir=summer_schema_dir
),
ImageRejector(("OBSTYPE", ["FOCUS", "DARK"])),
MaskPixels(mask_path=summer_mask_path),
DatabaseImageExporter(
db_name=pipeline_name,
db_table="raw",
schema_path=get_summer_schema_path("raw")
CalHunter(
load_image=load_raw_summer_image,
requirements=[
CalRequirement(target_name="bias", required_field="EXPTIME", required_values=["0.0"]),
CalRequirement(target_name="flat", required_field="FILTERID", required_values=["u", "g", "r", "i"]),
]
),
BiasCalibrator(),
ImageRejector(("OBSTYPE", ["BIAS"])),
ImageBatcher(split_key="filter"),
FlatCalibrator(),
# ImageSelector(("UTC", "20220403_050304.506320")),
# ImageBatcher(base_name_key),
ImageSelector(("OBSTYPE", "SCIENCE")),
ImageBatcher(base_name_key),
AutoAstrometry(pa=0, inv=True, pixel_scale=summer_pixel_scale),
Sextractor(
output_sub_dir="testb",
Expand All @@ -223,12 +224,10 @@ class SummerPipeline(Pipeline):
scamp_config_path=scamp_path,
),
Swarp(swarp_config_path=swarp_path, imgpixsize=2400),
# ImageSaver(output_dir_name="photprocess"),
Sextractor(output_sub_dir="photprocess",
checkimage_name='NONE',
checkimage_type='NONE',
**sextractor_photometry_config),
# ImageSaver(output_dir_name="processed"),
PhotCalibrator(ref_catalog_generator=summer_photometric_catalog_generator),
ImageSaver(output_dir_name="processed", additional_headers=['PROCIMG']),
DatabaseImageExporter(
Expand Down
139 changes: 139 additions & 0 deletions winterdrp/processors/utils/cal_hunter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import copy
import os

import astropy.io
import numpy as np
import logging
from winterdrp.processors.utils.image_selector import select_from_images
from winterdrp.processors.utils.image_loader import ImageLoader, load_from_dir, BaseImageProcessor
from winterdrp.errors import ImageNotFoundError

logger = logging.getLogger(__name__)


class CalRequirement:

def __init__(self, target_name, required_field: str, required_values: str | list[str]):
self.target_name = target_name
self.required_field = required_field
self.required_values = required_values
self.success = False
self.data = dict()

def check_images(self, images, headers):

new_images, new_headers = select_from_images(
images, headers,
header_key="TARGET",
target_values=self.target_name
)

if len(new_images) > 0:
for value in self.required_values:
if value not in self.data.keys():
sub_images, sub_headers = select_from_images(
new_images, new_headers,
header_key=self.required_field,
target_values=value
)
if len(sub_images) > 0:
self.data[value] = [sub_images, sub_headers]

self.success = len(self.data) == len(self.required_values)


class CalHunter(ImageLoader):

base_key = "calhunt"

def __init__(
self,
requirements: CalRequirement | list[CalRequirement],
*args,
**kwargs
):
super().__init__(*args, **kwargs)

if not isinstance(requirements, list):
requirements = [requirements]

self.requirements = requirements

def _apply_to_images(
self,
images: list[np.ndarray],
headers: list[astropy.io.fits.Header],
) -> tuple[list[np.ndarray], list[astropy.io.fits.Header]]:

requirements = copy.deepcopy(self.requirements)
requirements = self.update_requirements(requirements, images, headers)

latest_dir = os.path.join(
self.input_img_dir,
os.path.join(self.night_sub_dir, self.input_sub_dir)
)

preceding_dirs = []

for x in os.listdir(os.path.dirname(os.path.dirname(latest_dir))):
if x[0] not in ["."]:
if len(str(x)) == len(str(self.night)):
try:
if float(x) < float(self.night):
preceding_dirs.append(x)
except ValueError:
pass

ordered_nights = sorted(preceding_dirs)[::-1]

while np.sum([x.success for x in requirements]) != len(requirements):

if len(ordered_nights) == 0:
raise ImageNotFoundError("Ran out of nights!")

new_latest_night = ordered_nights[0]
ordered_nights = ordered_nights[1:]

try:

logger.info(f"Checking night {new_latest_night}")

dir_to_load = latest_dir.replace(self.night, new_latest_night)

new_images, new_headers = load_from_dir(
dir_to_load, open_f=self.open_raw_image
)

requirements = self.update_requirements(requirements, new_images, new_headers)

except ImageNotFoundError:
pass

n_cal = 0

for requirement in requirements:
for key, (cal_imgs, cal_headers) in requirement.data.items():
for i, cal_header in enumerate(cal_headers):
if cal_header not in headers:
images.append(cal_imgs[i])
headers.append(cal_header)
n_cal += 1

if n_cal > 0:
logger.warning(f"Some required calibration images were missing from image set. "
f"Found {n_cal} additional calibration images from older nights")

return images, headers

@staticmethod
def update_requirements(
requirements: list[CalRequirement],
images: list[np.ndarray],
headers: list[astropy.io.fits.Header]
) -> list[CalRequirement]:

for requirement in requirements:
if not requirement.success:
requirement.check_images(images, headers)

return requirements

0 comments on commit 852c6c7

Please sign in to comment.