1
2
3 """
4 A class for reading and managing Sphinx output.
5
6 Author: R. Lombaert
7
8 """
9
10 import os
11 from scipy import array
12 from scipy import isnan
13 from scipy import isfinite
14
15 from cc.tools.readers.Reader import Reader
16 from cc.tools.io import DataIO
17
18
19
21
22 '''
23 A Reader for Sphinx output files.
24
25 Inherits from the Reader class.
26
27 '''
28
30
31 '''
32 Creating a Sphinx object ready for reading Sphinx output.
33
34 Reading sphinx output through full filename, including filepath.
35
36 The sphinxfile number is given as *, which is then replaced as needed.
37
38 Additional args/kwargs are used for the dict creation of the parent of
39 Reader.
40
41 @param fn: The sphinx filename, including filepath. The sphinx
42 file number is given by *.
43 @type fn: string
44
45 '''
46
47 fn = fn.replace('sph1','sph*').replace('sph2','sph*')
48 super(SphinxReader, self).__init__(fn,*args,**kwargs)
49 self.nans_present=False
50 self.parseImpact()
51 self.parseProfile()
52
53
55
56 '''
57 Parse sphinx file 1, line intensities at line center (!) as a function
58 of impact parameter.
59
60 The output is stored in dict self['sph1'].
61
62 Note that the headers of the sph1 file state the last two columns are
63 summed intensities. This is not true! It is the intensity at line
64 center.
65
66 '''
67
68
69 self['sph1'] = dict()
70 data = DataIO.readCols(self.fn.replace('*','1'),start_row=1)
71 self['sph1']['p'] = data[0]
72 self['sph1']['norm_intens'] = data[1]
73 self['sph1']['weighted_intens'] = data[2]
74 self['sph1']['weighted_intens_p^-2'] = data[3]
75 self['sph1']['intens'] = data[4]
76
77
78
80
81 '''
82 Parse the sphinx file 2, which includes all line profile info.
83
84 The output is stored in dict self['sph2'].
85
86 '''
87
88 self['sph2'] = dict()
89 self['sph2']['nobeam'] = dict()
90 self['sph2']['beam'] = dict()
91 self['sph2']['nobeam_cont'] = dict()
92 self['sph2']['beam_cont'] = dict()
93 data = self.getFile(wildcard='2',delimiter=' ')
94 data_col_1 = [d[0] for d in data]
95 data_i = 6
96 data_j = DataIO.findString(data_i,data_col_1)
97 self['sph2']['nobeam']['velocity'] = array([float(line[0])
98 for line in data[data_i:data_j]])
99
100
101
102 self['sph2']['nobeam']['flux'] = array([DataIO.convertFloat(line[-1],\
103 nans=1)
104 for line in data[data_i:data_j]])
105 self['sph2']['nobeam']['flux'] = self['sph2']['nobeam']['flux'][::-1]
106 data_k = data_j + 4
107 data_l = DataIO.findString(data_k,data_col_1)
108 self['sph2']['beam']['velocity'] = array([float(line[0])
109 for line in data[data_k:data_l]])
110 self['sph2']['beam']['flux'] = array([float(line[-1])
111 for line in data[data_k:data_l]])
112 self['sph2']['beam']['norm_flux'] = array([float(line[1])
113 for line in data[data_k:data_l]])
114 self['sph2']['beam']['tmb'] = array([float(line[2])
115 for line in data[data_k:data_l]])
116
117
118 self.setContinuum('nobeam','flux')
119 for lp in ['flux','norm_flux','tmb']:
120 self.setContinuum('beam',lp)
121
122
123 if self['sph2']['beam']['velocity'][0] > self['sph2']['beam']['velocity'][-1]:
124 self['sph2']['beam']['velocity'] = self['sph2']['beam']['velocity'][::-1]
125 self['sph2']['beam']['flux'] = self['sph2']['beam']['flux'][::-1]
126 self['sph2']['beam']['norm_flux'] = self['sph2']['beam']['norm_flux'][::-1]
127 self['sph2']['beam']['tmb'] = self['sph2']['beam']['tmb'][::-1]
128 if self['sph2']['nobeam']['velocity'][0] > self['sph2']['nobeam']['velocity'][-1]:
129 self['sph2']['nobeam']['velocity'] = self['sph2']['nobeam']['velocity'][::-1]
130 self['sph2']['nobeam']['flux'] = self['sph2']['nobeam']['flux'][::-1]
131
132
133 if True in list(isnan(self['sph2']['nobeam']['flux'])):
134 self.nans_present = True
135 print "WARNING! There are NaN's in the intrinsic line profile " + \
136 "with model id %s:"\
137 %(os.path.split(os.path.split(self.fn)[0])[1])
138 print os.path.split(self.fn.replace('sph*','sph2'))[1]
139
140
141
143
144 '''
145 Set the continuum value for this line profile.
146
147 @param beam: Either 'beam' or 'nobeam'.
148 @type beam: str
149 @param lp: The type of line profile
150 @type lp: str
151
152 '''
153
154 flux = self['sph2'][beam][lp]
155 flux = flux[isfinite(flux)]
156 continuum = (flux[0] + flux[-1])/2.
157 self['sph2'][beam+'_cont'][lp] = continuum
158
159
160
162
163 '''
164 Return the intrinsic flux line profile.
165
166 Continuum subtraction can be requested.
167
168 @keyword cont_subtract: Subtract the continuum value outside the line
169 from the whole line profile.
170 @type cont_subtract: bool
171
172 @return: The intrinsic flux
173 @rtype: array
174
175 '''
176
177 flux = self['sph2']['nobeam']['flux']
178 if cont_subtract:
179 flux = flux - self['sph2']['nobeam_cont']['flux']
180
181 return flux
182
183
184
186
187 '''
188 Return the velocity grid for the intrinsic line profile.
189
190 @return: The velocity grid
191 @rtype: array
192
193 '''
194
195 return self['sph2']['nobeam']['velocity']
196
197
198
200
201 '''
202 Return the velocity grid for the convolved line profile.
203
204 @return: The velocity grid
205 @rtype: array
206
207 '''
208
209 return self['sph2']['beam']['velocity']
210
211
212
214
215 '''
216 Return the main beam temperature line profile.
217
218 Continuum subtraction can be requested.
219
220 @keyword cont_subtract: Subtract the continuum value outside the line
221 from the whole line profile.
222
223 (default: 1)
224 @type cont_subtract: bool
225
226 @return: The main beam temperature
227 @rtype: array
228
229 '''
230
231 tmb = self['sph2']['beam']['tmb']
232 if cont_subtract:
233 tmb = tmb - self['sph2']['beam_cont']['tmb']
234
235 return tmb
236
237
238
240
241 '''
242 Return the line profile after convolution with the beam profile.
243
244 Continuum subtraction can be requested.
245
246 @keyword cont_subtract: Subtract the continuum value outside the line
247 from the whole line profile.
248 @type cont_subtract: bool
249
250 @return: The convolved flux
251 @rtype: array
252
253 '''
254
255 flux = self['sph2']['beam']['flux']
256 if cont_subtract:
257 flux = flux - self['sph2']['beam_cont']['flux']
258
259 return flux
260
261
262
264
265 '''
266 Return the normalized line profile after convolution with the beam
267 profile.
268
269 Continuum subtraction can be requested.
270
271 @keyword cont_subtract: Subtract the continuum value outside the line
272 from the whole line profile.
273 @type cont_subtract: bool
274
275 @return: The normalized + convolved flux
276 @rtype: array
277
278 '''
279
280 flux = self['sph2']['beam']['norm_flux']
281 if cont_subtract:
282 flux = flux - self['sph2']['beam_cont']['norm_flux']
283
284 return flux
285
286
287
289
290 '''
291 Return the weighted intensity with respect to impact parameter squared
292 at line center.
293
294 @return: The weighted intensity at line center.
295 @rtype: array
296
297 '''
298
299 return self['sph1']['weighted_intens']
300
301
302
304
305 '''
306 Return the normalized p^2-weighted intensity at line center with respect to
307 impact parameter squared.
308
309 @return: The normalized p^2-weighted intensity at line center.
310 @rtype: array
311
312 '''
313
314 return self['sph1']['norm_intens']
315
316
317
319
320 '''
321 Return the intensity at line center as a function of impact parameter.
322
323 @return: The intensity at line center as a function of impact parameter.
324 @rtype: array
325
326 '''
327
328 return self['sph1']['intens']
329
330
331
333
334 '''
335 Return the impact parameter grid.
336
337 @return: the grid of impact parameters in the sphinx outputfile 1 in
338 rstar.
339 @rtype: array
340
341 '''
342
343 return self['sph1']['p']
344