1
2
3 """
4 A module for reading and managing line profile data files.
5
6 Author: R. Lombaert
7
8 """
9
10 import os
11 from scipy import std
12
13 from cc.tools.readers.Reader import Reader
14 from cc.data import Data
15 from cc.tools.io import DataIO
16
17
19
20 '''
21 A data reader for line profile data.
22
23 '''
24
25 - def __init__(self,fn,star_name=None,*args,**kwargs):
26
27 '''
28 A data reader for line profiles.
29
30 Filename of the data file is passed to the object upon creation.
31
32 Additional args/kwargs are used for the dict creation of the parent of
33 Reader.
34
35 @param fn: The data filename, including filepath.
36 @type fn: string
37
38 @keyword star_name: The star name if the filename doesn't follow naming
39 conventions. None otherwise.
40
41 (default: None)
42 @type star_name: str
43
44 '''
45
46 super(LPDataReader, self).__init__(fn,*args,**kwargs)
47 self.fn = fn
48 fn = os.path.splitext(os.path.split(self.fn)[1])[0]
49 if not star_name is None:
50 self.star_name = star_name
51 else:
52 self.star_name = fn.split('_')[0]
53 self.c = 2.99792458e10
54 self['contents']['vlsr'] = None
55 self.telescope = fn.split('_')[-1]
56
57
59
60 '''
61 Return the velocity grid of this data file.
62
63 @return: The velocity grid
64 @rtype: array/list
65
66 '''
67
68 return self['contents']['velocity']
69
70
71
73
74 '''
75 Return the flux of the line profile. Usually Tmb.
76
77 @return: The flux
78 @rtype: array/list
79
80 '''
81
82 return self['contents']['flux']
83
84
86
87 '''
88 Return the fitted value of the gas terminal velocity.
89
90 @return: The gas terminal velocity determined by the auto fit of the LP
91 @rtype: float
92
93 '''
94
95 return self['contents']['vexp']
96
97
98
100
101 '''
102 Set a value for the gas terminal velocity.
103
104 @param vexp: The gas terminal velocity, determined through whichever
105 way you want. This value is only used to set the noise
106 parameter in the object.
107 @type vexp: float
108
109 '''
110
111 self['contents']['vexp'] = float(vexp)
112
113
115
116 '''
117 Return the noise value for this dataset.
118
119 @keyword vexp: The terminal gas velocity, only required if vexp is not
120 set yet for this LPDataReader object!
121
122 (default: None)
123 @type vexp: float
124
125 @return: The std of the dataset
126 @rtype: float
127
128 '''
129
130 if not self['contents'].has_key('noise'):
131 self.setNoise(vexp)
132 return self['contents']['noise']
133
134
135
137
138 '''
139 Return the source velocity of the observed object in this dataset.
140
141 This is the value read from the fits file, and if not available or
142 applicable, the initial guess provided by Star.dat is returned.
143
144 If the star is not included in Star.dat, the v_lsr is set to 0.0.
145
146 @return: The source velocity of the observed object in the dataset in
147 km/s
148 @rtype: float
149
150 '''
151
152 return self['contents']['vlsr']
153
154
155
157
158 """
159 Check if the Vlsr was set correctly. If not, it is taken from Star.dat.
160
161 It is assumed the vlsr in the fits file is correct within 25%. If it is
162 not, the value from Star.dat is used.
163
164 """
165
166 try:
167 star_index = DataIO.getInputData(keyword='STAR_NAME')\
168 .index(self.star_name)
169 vlsr = DataIO.getInputData(keyword='V_LSR',rindex=star_index)
170 except KeyError,ValueError:
171 print 'Star not found in Star.dat for %s. '%(self.fn) + \
172 'Add star to Star.dat!'
173 raise IOError()
174 if self.getVlsr() is None:
175 self['contents']['vlsr'] = vlsr
176 elif vlsr == 0.0:
177 print('WARNING! V_lsr in Star.dat is set to 0. Double check!')
178 if not abs(self.getVlsr()) < 0.25:
179 self['contents']['vlsr'] = vlsr
180 elif abs(self.getVlsr()/vlsr) > 1.3 or abs(self.getVlsr()/vlsr) < 0.75:
181 self['contents']['vlsr'] = vlsr
182
183
184
186
187 """
188 If available, get the date of observation.
189
190 """
191
192 return self['contents']['date_obs']
193
194
195
197
198 """
199 Calculate the noise of the dataset, by taking the standard deviation
200 of the velocity range lower than v_lsr - 2*vexp.
201
202 If this is not available, the velocity range is taken to be where it is
203 smaller than 1.1*vexp.
204
205 If the size of the above selection still is too small, None is
206 returned.
207
208 The gas terminal velocity has to have been set previously or passed to
209 this method as a keyword.
210
211 @keyword vexp: The terminal gas velocity, only required if vexp is not
212 set yet for this LPDataReader object!
213
214 (default: None)
215 @type vexp: float
216
217 @return: The noise of the dataset
218 @rtype: float
219
220 """
221
222 if not vexp is None and not self['contents'].has_key('vexp'):
223 self['contents']['vexp'] = float(vexp)
224 if not self['contents'].has_key('vexp'):
225 print 'Cannot set noise without an estimate for the terminal gas'+\
226 ' velocity. Pass as keyword to this method!'
227 return None
228 vel = self['contents']['velocity']
229 flux = self['contents']['flux']
230 vlsr = self['contents']['vlsr']
231 vexp = self['contents']['vexp']
232 noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-5*vexp,\
233 wmax=vlsr-2*vexp,minsize=10)
234 if noise is None:
235 noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-3*vexp,\
236 wmax=vlsr-1.8*vexp,minsize=10)
237 if noise is None:
238 noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-3*vexp,\
239 wmax=vlsr-1.1*vexp,minsize=10)
240 if noise is None:
241 noise = Data.getStd(wave=vel,flux=flux,wmin=vlsr-3*vexp,\
242 wmax=vlsr-1.1*vexp,minsize=5)
243 if noise is None:
244 print 'WARNING! Noise cannot be determined, not enough data ' + \
245 'points outside the emission line.'
246 self['contents']['noise'] = noise
247