-
Notifications
You must be signed in to change notification settings - Fork 0
/
catalogues.py
executable file
·223 lines (161 loc) · 8.7 KB
/
catalogues.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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
r"""
.. codeauthor:: Hugo Plombat - LUPM <[email protected]> & Wilfried Mercier - IRAP/LAM <[email protected]>
Base classes used to generate catalogues for LePhare or Cigale SED fitting codes.
"""
from abc import ABC
from typing import List
import os.path as opath
from astropy.table import Table
from .misc import TableUnit, MagType, TableFormat, TableType, EnumProperty, ListIntProperty
class Catalogue(ABC):
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Class implementing a catalogue consisting of as Astropy Table and additional information used by the SED fitting codes. This is supposed to be subclassed to account for specificities of LePhare or Cigale catalogues.
:param fname: name of the catalogue file where the catalogue is written into when saving
:type fname: :python:`str`
:param table: input table
:type table: `Astropy Table`_
:raises TypeError:
* if **table** is not an `Astropy Table`_
* if **fname** is not of type :python:`str`
'''
def __init__(self, fname: str, table: Table, *args, **kwargs) -> None:
r'''Init method.'''
if not isinstance(table, Table):
raise TypeError(f'table has type {type(table)} but it must be an Astropy Table.')
if not isinstance(fname, str):
raise TypeError(f'fname parameter has type {type(fname)} but it must have type str.')
self.name = fname
self.data = table
def save(self, path: str ='', **kwargs) -> None:
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Save the catalogue into the given file.
:param path: (**Optional**) a path to append to the file name
:type path: :python:`str`
:param \**kwargs: optional parameters passed to `Table.write()`_
:raises TypeError: if **path** is not of type :python:`str`
'''
if not isinstance(path, str):
raise TypeError(f'path has type {type(path)} but it must have type str.')
fname = opath.join(path, self.name)
self.data.write(fname, overwrite=True, **kwargs)
return
@property
def text(self, *args, **kwargs) -> str:
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Return a text representation of the catalogue used when making the parameter files.
:returns: output representation
:rtype: :python:`str`
'''
return
class CigaleCat(Catalogue):
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Class implementing a catalogue compatible with Cigale SED fitting code.
:param fname: name of the output file containing the catalogue when it is saved (without any extension, e.g. galaxy1 instead of galaxy1.mag)
:type fname: :python:`str`
:param table: input table
:type table: `Astropy Table`_
'''
def __init__(self, fname: str, table: Table) -> None:
'''Init method.'''
super().__init__(f'{fname}.mag', table)
def save(self, path: str = '', **kwargs) -> None:
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Save LePhare catalogue into the given file.
:param path: (**Optional**) a path to append to the file name
:type path: :python:`str`
:param \**kwargs: optional parameters passed to `Table.write()`_ method
:raises TypeError: if **path** is not of type :python:`str`
'''
if not isinstance(path, str):
raise TypeError(f'path as type {type(path)} but it must have type str.')
fname = opath.join(path, self.name)
self.data.write(fname, format='ascii.basic', overwrite=True, **kwargs)
return
class LePhareCat(Catalogue):
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Class implementing a catalogue compatible with LePhare SED fitting code.
:param fname: name of the output file containing the catalogue when it is saved (without any extension, e.g. galaxy1 instead of galaxy1.in)
:type fname: :python:`str`
:param table: input table
:type table: `Astropy Table`_
:param TableUnit tunit: (**Optional**) unit of the table data. Must either be TableUnit.MAG for magnitude or TableUnit.FLUX for flux.
:param MagType magtype: (**Optional**) magnitude type if data are in magnitude unit. Must either be MagType.AB or MagType.VEGA.
:param TableFormat tformat: (**Optional**) format of the table. Must either be TableFormat.MEME if data and error columns are intertwined or TableFormat.MMEE if columns are first data and then errors.
:param TableType ttype: (**Optional**) data type. Must either be TableType.SHORT or TableType.LONG.
:param nlines: (**Optional**) first and last line of the catalogue to be used during the SED fitting
:type nlines: :python:`list[int]`
:raises TypeError:
* if **table** is not an `Astropy Table`_
* if **fname** is not of type :python:`str`
* if **nlines** is not a :python:`list[int]`
:raises ValueError:
* if **nlines** values are not :python:`int`
* if the first value is less than 0
* if the second value is less than the first one
'''
def __init__(self, fname: str, table: Table,
tunit: TableUnit = TableUnit.MAG,
magtype: MagType = MagType.AB,
tformat: TableFormat = TableFormat.MEME,
ttype: TableType = TableType.LONG,
nlines: List[int] = [0, 100000000]) -> None:
r'''Init method.'''
super().__init__(f'{fname}.in', table)
#####################################################
# Define default properties #
#####################################################
self.unit = EnumProperty(TableUnit.MAG)
self.mtype = EnumProperty(MagType.AB)
self.format = EnumProperty(TableFormat.MEME)
self.ttype = EnumProperty(TableType.LONG)
self.nlines = ListIntProperty([0, 100000000], minBound=0,
testFunc = lambda value: value[1] < value[0],
testMsg = f'maximum number of lines ({nlines[1]}) is less than minimum one ({nlines[0]}).')
#################################################
# Set to given values #
#################################################
self.unit.set( tunit)
self.mtype.set( magtype)
self.format.set(tformat)
self.ttype.set( ttype)
self.nlines.set(nlines)
@property
def text(self, *args, **kwargs) -> str:
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Return a text representation of the catalogue used when making the parameter files.
:returns: output representation
:rtype: :python:`str`
'''
text = f'''
#------- Input Catalog Informations
CAT_IN \t\t{self.name}
INP_TYPE \t{self.unit} \t\t# Input type (F:Flux or M:MAG)
CAT_MAG \t{self.mtype} \t\t# Input Magnitude (AB or VEGA)
CAT_FMT \t{self.format} \t\t# MEME: (Mag,Err)i or MMEE: (Mag)i,(Err)i
CAT_LINES \t{self.nlines} \t# MIN and MAX RANGE of ROWS used in input cat [def:-99,-99]
CAT_TYPE \t{self.ttype} \t\t# Input Format (LONG,SHORT-def)
'''
return text
def save(self, path: str = '', **kwargs) -> None:
r'''
.. codeauthor:: Wilfried Mercier - IRAP <[email protected]>
Save LePhare catalogue into the given file.
:param path:(**Optional**) a path to append to the file name
:type path: :python:`str`
:param \**kwargs: optional parameters passed to `Table.write()`_ method
:raises TypeError: if **path** is not of type :python:`str`
'''
if not isinstance(path, str):
raise TypeError(f'path has type {type(path)} but it must have type str.')
fname = opath.join(path, self.name)
self.data.write(fname, format='ascii.fast_no_header', overwrite=True, **kwargs)
return