-
Notifications
You must be signed in to change notification settings - Fork 10
/
read_filter.py
182 lines (133 loc) · 4.61 KB
/
read_filter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
"""
Module with reading functionalities for filter profiles.
"""
import os
import warnings
import configparser
from typing import Union, Tuple
import h5py
import numpy as np
from typeguard import typechecked
from scipy.interpolate import interp1d, InterpolatedUnivariateSpline, interpolate
from species.data import database
class ReadFilter:
"""
Class for reading a filter profile from the database.
"""
@typechecked
def __init__(self,
filter_name: str) -> None:
"""
Parameters
----------
filter_name : str
Filter name as stored in the database. Filter names from the SVO Filter Profile Service
will be automatically downloaded, stored in the database, and read from the database.
Returns
-------
NoneType
None
"""
self.filter_name = filter_name
config_file = os.path.join(os.getcwd(), 'species_config.ini')
config = configparser.ConfigParser()
config.read_file(open(config_file))
self.database = config['species']['database']
h5_file = h5py.File(self.database, 'r')
if 'filters' not in h5_file or self.filter_name not in h5_file['filters']:
h5_file.close()
species_db = database.Database()
species_db.add_filter(self.filter_name)
h5_file = h5py.File(self.database, 'r')
h5_file.close()
@typechecked
def get_filter(self) -> np.ndarray:
"""
Function for selecting a filter profile from the database.
Returns
-------
numpy.ndarray
Filter transmission profile.
"""
h5_file = h5py.File(self.database, 'r')
data = np.asarray(h5_file[f'filters/{self.filter_name}'])
if data.shape[0] == 2 and data.shape[1] > data.shape[0]:
# Required for backward compatibility
data = np.transpose(data)
h5_file.close()
return data
@typechecked
def interpolate_filter(self) -> interpolate.interp1d:
"""
Function for linearly interpolating a filter profile.
Returns
-------
scipy.interpolate.interpolate.interp1d
Linearly interpolated filter.
"""
data = self.get_filter()
return interp1d(data[:, 0],
data[:, 1],
kind='linear',
bounds_error=False,
fill_value=float('nan'))
@typechecked
def wavelength_range(self) -> Tuple[Union[np.float32, np.float64],
Union[np.float32, np.float64]]:
"""
Extract the wavelength range of the filter profile.
Returns
-------
float
Minimum wavelength (um).
float
Maximum wavelength (um).
"""
data = self.get_filter()
return data[0, 0], data[-1, 0]
@typechecked
def mean_wavelength(self) -> Union[np.float32, np.float64]:
"""
Calculate the weighted mean wavelength of the filter profile.
Returns
-------
float
Mean wavelength (um).
"""
data = self.get_filter()
return np.trapz(data[:, 0]*data[:, 1], data[:, 0]) / np.trapz(data[:, 1], data[:, 0])
@typechecked
def filter_fwhm(self) -> float:
"""
Calculate the full width at half maximum (FWHM) of the filter profile.
Returns
-------
float
Filter full width at half maximum (um).
"""
data = self.get_filter()
spline = InterpolatedUnivariateSpline(data[:, 0], data[:, 1] - np.max(data[:, 1])/2.)
root = spline.roots()
diff = root - self.mean_wavelength()
root1 = np.amax(diff[diff < 0.])
root2 = np.amin(diff[diff > 0.])
return root2 - root1
@typechecked
def detector_type(self) -> str:
"""
Function for returning the detector type.
Returns
-------
str
Detector type ('energy' or 'photon').
"""
with h5py.File(self.database, 'r') as h5_file:
dset = h5_file[f'filters/{self.filter_name}']
if 'det_type' in dset.attrs:
det_type = dset.attrs['det_type']
else:
warnings.warn('Detector type not found. The database was probably created '
'before the detector type was introduced in species (v0.3.1). '
'Assuming an energy-counting detector.')
det_type = 'energy'
return det_type