Passed
Pull Request — main (#157)
by Chaitanya
04:40 queued 02:37
created

asgardpy.io.input_dl3   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 95
dl 0
loc 175
rs 10
c 0
b 0
f 0
wmc 21
1
"""
2
Basic classes defining Input Config for DL3 files and some functions to
3
retrieve the DL3 files information.
4
5
Currently supporting files following enrico/fermipy for Fermi-LAT data for 3D
6
Dataset and DL3 files that follow GADF v0.3 and can be directly read by Gammapy,
7
for 1D Dataset.
8
"""
9
10
import logging
11
12
from asgardpy.base import BaseConfig, PathType
13
14
__all__ = ["InputFilePatterns", "InputDL3Config", "DL3Files"]
15
16
EXPECTED_DL3_RANGE = ["gadf-dl3", "lat", "lat-aux"]
17
18
19
# Basic Components for the Input Config
20
class InputFilePatterns(BaseConfig):
21
    """
22
    Config section for list of file patterns to use for fetching relevant DL3
23
    files.
24
    """
25
26
    events: str = "*events.fits*"
27
    edisp: str = "*DRM.fits*"
28
    exposure: str = "*BinnedMap.fits*"
29
    xml_model: str = "*out.xml"
30
    psf: str = "*psf.fits*"
31
32
    dl3: str = "dl3*fits"
33
34
    gal_diffuse: str = "gll_iem_v*.fits*"
35
    iso_diffuse: str = "iso_P8R3_SOURCE_V*_*.txt"
36
37
38
class InputDL3Config(BaseConfig):
39
    """
40
    Config section for main information on getting the relevant DL3 files.
41
    """
42
43
    type: str = "type"
44
    input_dir: PathType = PathType("None")
45
    glob_pattern: dict = {}
46
47
48
# Main Classes for I/O
49
class DL3Files:
50
    """
51
    A general class to retrieve information from given DL3 files, along with
52
    other auxiliary files for neighbouring sources, if provided.
53
    """
54
55
    def __init__(self, dir_dict, log=None):
56
        if not log:
57
            self._set_logging()
58
        else:
59
            self.log = log
60
61
        self.dl3_path = dir_dict.input_dir
62
63
        self.dl3_type = dir_dict.type
64
        self._check_dl3_type()
65
66
        self.glob_dict = dir_dict.glob_pattern
67
68
        self.events_files = None
69
        self.edrm_files = None
70
        self.xml_files = None
71
        self.expmap_files = None
72
        self.psf_files = None
73
        self.gal_diff_files = None
74
        self.iso_diff_files = None
75
76
        self.xml_f = None
77
        self.gal_diff_f = None
78
79
    def _set_logging(self):
80
        self.log = logging.getLogger(__name__)
81
        self.log.setLevel(logging.INFO)
82
83
    def _check_dl3_type(self):
84
        if self.dl3_type.lower() not in EXPECTED_DL3_RANGE:
85
            self.log.error("%s is not in the expected range for DL3 files", self.dl3_type)
86
87
    def prepare_lat_files(self, key, file_list):
88
        """
89
        Prepare a list of LAT files following a particular key. If there are no
90
        distinct key types of files, the value is None.
91
        """
92
        # Try to combine LAT and LAT-AUX files
93
        self.list_dl3_files()
94
        file_list = self.select_unique_files(key, file_list)
95
96
        return file_list
97
98
    def list_dl3_files(self):
99
        """
100
        From a given DL3 files path, categorize the different types of DL3
101
        files, to be used for further analysis.
102
103
        The dl3_type of 'gadf-dl3' is used for all GADF v0.3 following DL3
104
        files that can be directly read by Gammapy, for 1D Datasets.
105
        """
106
        match self.dl3_type.lower():
107
            case "lat":
108
                self.events_files = sorted(list(self.dl3_path.glob(self.glob_dict["events"])))
109
                self.edrm_files = sorted(list(self.dl3_path.glob(self.glob_dict["edisp"])))
110
                self.xml_files = sorted(list(self.dl3_path.glob(self.glob_dict["xml_model"])))
111
                self.expmap_files = sorted(list(self.dl3_path.glob(self.glob_dict["exposure"])))
112
                self.psf_files = sorted(list(self.dl3_path.glob(self.glob_dict["psf"])))
113
114
            case "lat-aux":
115
                self.gal_diff_files = sorted(list(self.dl3_path.glob(self.glob_dict["gal_diffuse"])))
116
                self.iso_diff_files = sorted(list(self.dl3_path.glob(self.glob_dict["iso_diffuse"])))
117
118
            case "gadf-dl3":
119
                self.events_files = sorted(list(self.dl3_path.glob(self.glob_dict["dl3"])))
120
121
    def select_unique_files(self, key, file_list):
122
        """
123
        Select Unique files from all of the provided LAT files, as per the
124
        given key. If there are no distinct key types of files, the value is None.
125
        """
126
        # Have to make more checks or add conditions on selecting only select
127
        # files instead from the glob-searched lists.
128
        if self.dl3_type.lower() in ["lat"]:
129
            var_list = [
130
                "events_files",
131
                "edrm_files",
132
                "expmap_files",
133
                "psf_files",
134
            ]
135
            file_list["xml_file"] = self.xml_files[0]
136
137
        if self.dl3_type.lower() == "lat-aux":
138
            var_list = []
139
            if key:
140
                if "0" not in key:  # For fermipy files, the diffuse files are already unique
141
                    var_list = [
142
                        "iso_diff_files",
143
                    ]
144
            if isinstance(self.iso_diff_files, list):
145
                self.iso_gal_f = self.iso_diff_files[0]
146
            else:
147
                self.iso_gal_f = self.iso_diff_files
148
            file_list["iso_diff_file"] = self.iso_gal_f
149
150
            if isinstance(self.gal_diff_files, list):
151
                self.diff_gal_f = self.gal_diff_files[0]
152
            else:
153
                self.diff_gal_f = self.gal_diff_files
154
            file_list["gal_diff_file"] = self.diff_gal_f
155
156
        if len(var_list) > 0:
157
            for _v in var_list:
158
                if key is not None:
159
                    filtered = [K for K in getattr(self, _v) if key in str(K.name)]
160
                    if len(filtered) == 1:
161
                        self.log.info("Selecting the file with name containing %s", key)
162
                        setattr(self, _v.replace("_files", "_f"), filtered[0])
163
                    else:
164
                        raise ValueError(
165
                            "Variable {%s} does not contain one element after filtering by {%s}",
166
                            getattr(self, _v),
167
                            key,
168
                        )
169
                else:
170
                    self.log.info("No distinct key provided, selecting the first file in the list")
171
                    setattr(self, _v.replace("_files", "_f"), getattr(self, _v)[0])
172
173
                file_list[_v.replace("files", "file")] = getattr(self, _v.replace("_files", "_f"))
174
175
        return file_list
176