Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
oczoske committed Feb 7, 2025
2 parents 7fe6e74 + 513bcc4 commit 1d3dda7
Show file tree
Hide file tree
Showing 19 changed files with 824 additions and 101 deletions.
13 changes: 12 additions & 1 deletion .github/workflows/run_edps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,25 @@ jobs:
export SOF_DIR="$(pwd)/METIS_Pipeline_Test_Data/metis_sim_small_1/sof"
export PYESOREX_OUTPUT_DIR="$SOF_DATA"
pyesorex --recipes
# DET RECIPES
cat "${SOF_DIR}/metis_det_lingain.lm.sof"
pyesorex metis_det_lingain "${SOF_DIR}/metis_det_lingain.lm.sof"
cat "${SOF_DIR}/metis_det_dark.lm.sof"
pyesorex metis_det_dark "${SOF_DIR}/metis_det_dark.lm.sof"
# IMG LM RECIPES
cat "${SOF_DIR}/metis_lm_img_flat.lamp.sof"
pyesorex metis_lm_img_flat "${SOF_DIR}/metis_lm_img_flat.lamp.sof"
cat "${SOF_DIR}/metis_lm_img_basic_reduce.sof"
# TODO: This recipe name is incorrect and should be renamed
pyesorex metis_lm_img_basic_reduce "${SOF_DIR}/metis_lm_img_basic_reduce.sof"
# IFU RECIPES
cat "${SOF_DIR}/metis_ifu_rsrf.sof"
pyesorex metis_ifu_rsrf "${SOF_DIR}/metis_ifu_rsrf.sof"
# CAL RECIPES
cat "${SOF_DIR}/metis_cal_chophome.sof"
pyesorex metis_cal_chophome "${SOF_DIR}/metis_cal_chophome.sof"
- name: Run EDPS
Expand All @@ -73,5 +83,6 @@ jobs:
export SOF_DIR="$(pwd)/METIS_Pipeline_Test_Data/metis_sim_small_1/sof"
edps -lw
edps -w metis.metis_lm_img_wkf -i $SOF_DATA -c
edps -w metis.metis_lm_img_wkf -i $SOF_DATA | tee edps.stdout.txt
edps -w metis.metis_lm_img_wkf -i $SOF_DATA -lt
edps -w metis.metis_lm_img_wkf -i $SOF_DATA -m all| tee edps.stdout.txt
! grep "'FAILED'" edps.stdout.txt
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Skip __init__.py setting
__init__.py

# Skip vscode setting
.vscode

Expand Down
11 changes: 10 additions & 1 deletion metisp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ Running one specific recipe
```

Running Meta-target
```
edps -w metis.metis_wkf -i $SOF_DATA -m science
```


Getting report in a better way
```
edps -w metis.metis_lm_img_wkf -i $SOF_DATA -t metis_det_dark -od
Expand All @@ -93,9 +99,12 @@ Getting report in a better way

Making plots
```
edps -w metis.metis_lm_img_wkf -i /home/chyan/METIS_Simulations/ESO/output -g > test.dot
edps -w metis.metis_lm_img_wkf -i $SOF_DATA -g > test.dot
dot -T png test.dot > mygraph.png
```
The gerated plotting code can plot using online tool as well
[GraphvizOnline](https://dreampuf.github.io/GraphvizOnline/)


## Note for developers
When you're using the Python Debugger (pdb) and an error occurs, pdb will automatically enter post-mortem debugging mode, allowing you to inspect the state of the program at the point where the error occurred. Here's how you can find out where the error happened:
Expand Down
2 changes: 1 addition & 1 deletion metisp/pymetis/src/pymetis/base/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, recipe: 'MetisRecipe') -> None:
self.header: cpl.core.PropertyList | None = None
self.products: Dict[str, PipelineProduct] = {}
self.product_frames = cpl.ui.FrameSet()

def run(self, frameset: cpl.ui.FrameSet, settings: Dict[str, Any]) -> cpl.ui.FrameSet:
"""
The main function of the recipe implementation. It mirrors the signature of `Recipe.run`
Expand Down
19 changes: 19 additions & 0 deletions metisp/pymetis/src/pymetis/inputs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,22 @@ class PinholeTableInput(SinglePipelineInput):
_title: str = "pinhole table"
_tags: Pattern = re.compile(r"PINHOLE_TABLE")
_group: cpl.ui.Frame.FrameGroup = cpl.ui.Frame.FrameGroup.CALIB


class FluxTableInput(SinglePipelineInput):
_title = "flux standard star catalogue table"
_tags: Pattern = re.compile(r"FLUXSTD_CATALOG")
_group: cpl.ui.Frame.FrameGroup = cpl.ui.Frame.FrameGroup.CALIB


class LsfKernelInput(SinglePipelineInput):
_title: str = "line spread function kernel"
_tags: Pattern = re.compile(r"LSF_KERNEL")
_group: cpl.ui.Frame.FrameGroup = cpl.ui.Frame.FrameGroup.CALIB


class AtmProfileInput(SinglePipelineInput):
_title: str = "atmosphere profile"
_tags: Pattern = re.compile(rf"ATM_PROFILE")
_group: cpl.ui.Frame.FrameGroup = cpl.ui.Frame.FrameGroup.CALIB

14 changes: 14 additions & 0 deletions metisp/pymetis/src/pymetis/inputs/multiple.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ def __init__(self,

self.extract_tag_parameters(tag_matches)

@classmethod
def get_target_name(cls, frameset: cpl.ui.FrameSet):
"""
Extracts the 'target' name from the input string based on the '_tags' regex.
:param inputString: The string to be matched against the pattern.
:return: The target name if a match is found, otherwise None.
"""
for frame in frameset:
if match := cls._tags.match(frame.tag):
return match.group("target")
else:
return None

def extract_tag_parameters(self, matches: [dict[str, str]]):
if len(matches) == 0:
return
Expand Down
2 changes: 2 additions & 0 deletions metisp/pymetis/src/pymetis/recipes/ifu/metis_ifu_rsrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

class MetisIfuRsrfImpl(DarkImageProcessor):
class InputSet(PersistenceInputSetMixin, DarkImageProcessor.InputSet):
detector = "IFU"

class RawInput(RawInput):
_tags = re.compile(r"IFU_RSRF_RAW")
_title = "IFU rsrf raw"
Expand Down
154 changes: 102 additions & 52 deletions metisp/pymetis/src/pymetis/recipes/ifu/metis_ifu_telluric.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
This file is part of the METIS Pipeline.
Copyright (C) 2024 European Southern Observatory
Copyright (C) 2025 European Southern Observatory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -18,74 +18,115 @@
"""

import re
from typing import Dict

import cpl
from typing import Dict

from pymetis.base import MetisRecipe, MetisRecipeImpl
from pymetis.base.product import PipelineProduct
from pymetis.inputs import SinglePipelineInput
from pymetis.inputs.mixins import PersistenceInputSetMixin

from pymetis.inputs import SinglePipelineInput, PipelineInputSet
from pymetis.inputs.common import FluxTableInput, LsfKernelInput, AtmProfileInput

class ProductTelluric(PipelineProduct):
level = cpl.ui.Frame.FrameLevel.FINAL
frame_type = cpl.ui.Frame.FrameType.IMAGE

# The aim of this recipe is twofold,
# (a) to determine the transmission function for telluric absorption correction
# (b) determination of the response function for the flux calibration
#
# Note that there will be most probably a redesign / split into more recipes to follow the approach
# implemented already in other ESO pipelines

class MetisIfuTelluricImpl(MetisRecipeImpl):
detector = '2RG'

class InputSet(PersistenceInputSetMixin):
class CombinedInput(SinglePipelineInput):
_title = "combined science and standard frames"
"""Implementation class for metis_ifu_telluric"""

# Defining detector name
@property
def detector_name(self) -> str | None:
return "IFU"

# ++++++++++++++ Defining input +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Define molecfit main input class as one 1d spectrum, either Science or Standard spectrum
class InputSet(PipelineInputSet):
"""Inputs for metis_ifu_telluric"""
class Reduced1DInput(SinglePipelineInput):
_tags = re.compile(rf"IFU_(?P<target>SCI|STD)_1D")
_group = cpl.ui.Frame.FrameGroup.CALIB
_tags = re.compile(r"IFU_(?P<target>SCI|STD)_COMBINED")
_title = "uncorrected mf input spectrum"

class LsfKernelInput(SinglePipelineInput):
_title = "LSF kernel"
_group = cpl.ui.Frame.FrameGroup.CALIB
_tags = re.compile(r"LSF_KERNEL")

class AtmProfileInput(SinglePipelineInput):
_title = "atmospheric profile"
_group = cpl.ui.Frame.FrameGroup.CALIB
_tags = re.compile(r"ATM_PROFILE")

class FluxStdCatalogInput(SinglePipelineInput):
_title = "flux std catalog"
class CombinedInput(SinglePipelineInput):
_tags = re.compile(rf"IFU_(?P<target>SCI|STD)_COMBINED")
_group = cpl.ui.Frame.FrameGroup.CALIB
_tags = re.compile(r"FLUXSTD_CATALOG")
_title = "spectral cube of science object"

def __init__(self, frameset: cpl.ui.FrameSet):
super().__init__(frameset)
self.combined = self.CombinedInput(frameset)
self.lsf_kernel = self.LsfKernelInput(frameset)
self.atmospheric_profile = self.AtmProfileInput(frameset)
self.fluxstd_catalog = self.FluxStdCatalogInput(frameset)

self.inputs |= {self.combined, self.lsf_kernel, self.atmospheric_profile, self.fluxstd_catalog}


class ProductSciReduced1D(ProductTelluric):
tag = rf"IFU_SCI_REDUCED_1D"

class ProductIfuTelluric(ProductTelluric):
tag = "IFU_TELLURIC"

class ProductFluxcalTab(ProductTelluric):
tag = "FLUXCAL_TAB"

self.fluxstd_catalog = FluxTableInput(frameset)
self.atm_profile = AtmProfileInput(frameset)
self.lsf_kernel = LsfKernelInput(frameset)
self.inputs |= {self.combined, self.fluxstd_catalog, self.atm_profile, self.lsf_kernel}

# ++++++++++++++ Defining ouput +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Recipe is foreseen to do both, create transmission and response functions
# We therefore need to define transmission spectrum and response curve class

# Tranmission spectrum
class ProductTelluricTransmission(PipelineProduct):
"""
Final product: Transmission function for the telluric correction
"""
level = cpl.ui.Frame.FrameLevel.FINAL
tag = r"IFU_TELLURIC"
frame_type = cpl.ui.Frame.FrameType.IMAGE

# Response curve
class ProductResponseFunction(PipelineProduct):
"""
Final product: response curve for the flux calibration
"""
level = cpl.ui.Frame.FrameLevel.FINAL
tag = r"IFU_TELLURIC"
frame_type = cpl.ui.Frame.FrameType.IMAGE

# TODO: Define input type for the paramfile in common.py

# ++++++++++++++ Defining functions +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# Invoke molecfit
def mf_model(self):
"""
Purpose: invoke molecfit to achieve a best-fit in the fitting regions
"""
pass # do nothing in the meanwhile

# Invoke Calctrans
def mf_calctrans(self):
"""
Purpose: invoke calctrans to calculate transmission over the whole wavelength range
"""
pass # do nothing in the meanwhile

# Recipe is in the moment also foreseen to create the response curve for the flux calibration
# Response determination
def determine_response(self):
"""
Purpose: determine response function, i.e. compare observed standard star spectrum with the model in REF_STD_CAT
"""
pass # do nothing in the meanwhile

# Function to process everything?
def process_images(self) -> Dict[str, PipelineProduct]:
# self.correct_telluric()
# self.apply_fluxcal()
self.mf_model()
self.mf_calctrans()
self.determine_response()

header = cpl.core.PropertyList()
image = cpl.core.Image.load(self.inputset.combined.frame.file)
header = self._create_dummy_header()
image = self._create_dummy_image()

self.products = {
str(product.category): product(self, header, image)
for product in [self.ProductSciReduced1D, self.ProductIfuTelluric, self.ProductFluxcalTab]
product.category: product(self, header, image)
for product in [self.ProductTelluricTransmission, self.ProductResponseFunction]
}
return self.products

Expand All @@ -97,13 +138,20 @@ class MetisIfuTelluric(MetisRecipe):
_email = "[email protected]"
_copyright = "GPL-3.0-or-later"
_synopsis = "Derive telluric absorption correction and optionally flux calibration"
_description = (
"Currently just a skeleton prototype."
)
_description = """
Recipe to derive the atmospheric transmission and the response function.
implementation_class = MetisIfuTelluricImpl
Inputs
IFU_SCI|STD_1D: 1d spectrum either from science target or standard star
Outputs
IFU_TELLURIC: Tranmission of the Earth#s atmosphere
FLUXCAL_TAB: Response function
Algorithm
*TBwritten*
"""

# Dummy parameter to circumvent a potential bug in `pyesorex`
parameters = cpl.ui.ParameterList([
cpl.ui.ParameterValue(
name=f"{_name}.dummy",
Expand All @@ -112,3 +160,5 @@ class MetisIfuTelluric(MetisRecipe):
default="dummy",
)
])
implementation_class = MetisIfuTelluricImpl

Loading

0 comments on commit 1d3dda7

Please sign in to comment.