1
2
3 """
4 Several tools to write complex tables.
5
6 Author: R. Lombaert
7
8 """
9
10 import os
11
12 import cc.path
13 from cc.tools.io import DataIO
14 from cc.data.instruments.Spire import Spire
15 from cc.data.instruments.Pacs import Pacs
16
17
18
19 -def writeIntIntTable(filename,stars,trans,instrument='PACS',ddict=dict(),\
20 searchstring='os2_us3',\
21 mark_trans=[],extra_marker=r'\tablefootmark{f}',\
22 blend_mark=r'\tablefootmark{$\star$}',print_summary=0,\
23 sort_freq=1):
24
25 '''
26 Write a table with integrated line intensities and their uncertainties for
27 multiple stars.
28
29 The table - for now - is only available in LaTeX format.
30
31 Can be used for unresolved line strengths from PACS and SPIRE measurements.
32
33 @param filename: The filename of the to be written table.
34 @type filename: string
35 @param stars: The stars for which the table is created.
36 @type stars: list[string]
37 @param trans: The transitions for which the integrated intensities are
38 selected from the PACS line fit results of each star.
39 @type trans: list[Transition()]
40
41 @keyword instrument: The name of the instrument for which this is done. For
42 now only 'PACS' and 'SPIRE'.
43
44 (default: 'PACS')
45 @type instrument: str
46 @keyword ddict: The data objects for PACS or SPIRE for each star. If not
47 given, they are generated automatically with path_linefit
48 'lineFit', oversampling 6 (for PACS) or 4 (for SPIRE), and
49 resolution of 0.04 (for SPIRE).
50
51 (default: None)
52 @type ddict: dict(Instrument())
53 @keyword blend_mark: The marker used for blended lines.
54
55 (default: \tablefootmark{$\star$})
56 @type blend_mark: string
57 @keyword mark_trans: If a subset of transitions has to be marked with an
58 extra mark, they are included in this list.
59
60 (default: [])
61 @type mark_trans: list
62 @keyword extra_marker: The marker used for the subset mark_trans
63
64 (default: \tablefootmark{f})
65 @type extra_marker: string
66 @keyword searchstring: the searchstring conditional for the auto-search, if
67 data have not been read into given Pacs objects or
68 if new Pacs objects are generated.
69
70 (default: 'os2_us3')
71 @type searchstring: string
72 @keyword sort_freq: Sort the transitions on frequency. Otherwise sort on
73 wavelength.
74
75 (default: 1)
76 @type sort_freq: bool
77 @keyword print_summary: Print a summary at the end.
78
79 (default: 0)
80 @type print_summary: bool
81
82 '''
83
84
85 if ddict:
86 all_instr = [dd.instrument for dd in ddict.values()]
87 if len(set(all_instr)) > 1:
88 print "Too many instruments defined. Make sure only PACS or SPIRE"+\
89 " are requested."
90 return
91 instrument = all_instr[0].upper()
92
93 if isinstance(stars,str):
94 stars = [stars]
95
96
97
98
99 trans = sorted(trans,\
100 key=lambda x: sort_freq and x.frequency or x.wavelength)
101 if set([t.vup for t in trans]) == set([0]):
102 no_vib = 1
103 else:
104 no_vib = 0
105
106
107
108
109
110
111 for tr in trans:
112 tr.unreso = dict()
113 tr.unreso_err = dict()
114 tr.unreso_blends = dict()
115 for star in stars:
116 if not ddict.has_key(star):
117 if instrument == 'PACS':
118 ddict[star] = Pacs(star,6,path_linefit='lineFit')
119 elif instrument == 'SPIRE':
120 ddict[star] = Spire(star,resolution=0.04,oversampling=4,\
121 path_linefit='lineFit')
122 ddict[star].setData(searchstring=searchstring)
123 for ifn in range(len(ddict[star].data_filenames)):
124 ddict[star].intIntMatch(trans,ifn)
125
126 istars = [DataIO.getInputData().index(star) for star in stars]
127 pstars = [DataIO.getInputData(keyword='STAR_NAME_PLOTS',rindex=istar)
128 for istar in istars]
129 pstars = [s.replace('_',' ') for s in pstars]
130 all_molecs = DataIO.getInputData(keyword='TYPE_SHORT',make_float=0,\
131 filename='Molecule.dat')
132 all_pmolecs = DataIO.getInputData(keyword='NAME_PLOT',make_float=0,\
133 filename='Molecule.dat')
134 inlines = []
135 inlines.append('&'.join(['']*(no_vib and 4 or 5)+pstars[:-1]+\
136 [r'%s \\\hline'%pstars[-1]]))
137 line_els = [instrument,'Molecule']
138 if not no_vib:
139 line_els.append('Vibrational')
140 line_els.extend(['Rotational','$\lambda_0$',\
141 r'\multicolumn{%i}{c}{$F_\mathrm{int}$} \\'%len(pstars)])
142 inlines.append('&'.join(line_els))
143 line_els = ['band','']
144 if not no_vib:
145 line_els.append('state')
146 line_els.extend(['transition',r'$\mu$m',\
147 r'\multicolumn{%i}{c}{(W m$^-2$))} \\\hline'%len(pstars)])
148 inlines.append('&'.join(line_els))
149 all_bands = ['SLW','SSW','R1B','R1A','B2B','B2A','B3A']
150 bands = set([ib for v in ddict.values() for ib in v.data_ordernames])
151 bands = [ib for ib in all_bands if ib in bands]
152 if not sort_freq: bands.reverse()
153 line_counter = dict()
154 for s in stars:
155 line_counter[s] = 0
156 for band in bands:
157
158
159 new_band = 1
160 for it,t in enumerate(trans):
161
162
163
164
165
166
167
168
169 all_keys = [k
170 for k in t.unreso.keys()
171 if band in os.path.split(k)[1].split('_')]
172 if not all_keys:
173 continue
174
175
176
177 col1 = all_pmolecs[all_molecs.index(t.molecule.molecule)]
178
179
180 if new_band:
181 col0 = band
182 new_band = 0
183 else:
184 col0 = ''
185
186
187 parts = [col0,\
188 col1]
189 if not no_vib:
190 parts.append(t.makeLabel(return_vib=1))
191 parts.extend([t.makeLabel(inc_vib=0),'%.2f'%(t.wavelength*10**4)])
192
193
194
195
196
197
198
199 for s in stars:
200
201
202
203 all_fn = [sfn for sfn in t.unreso.keys()
204 if band in os.path.split(sfn)[1].split('_')\
205 and s in os.path.split(sfn)[1].split('_')]
206
207
208
209
210 if not all_fn:
211 parts.append(r'/')
212 continue
213 else:
214 fn = all_fn[0]
215
216
217
218
219 fint,finterr,fintblend = t.getIntIntUnresolved(fn)
220 if fint == 'inblend':
221 parts.append('Blended')
222 else:
223 line_counter[s] += 1
224 parts.append('%s%s%.2e (%.1f%s)'\
225 %(t in mark_trans and extra_marker or r'',\
226 fint<0 and blend_mark or r'',abs(fint),\
227 finterr*100,r'\%'))
228 parts[-1] = parts[-1] + r'\\'
229 inlines.append('&'.join(parts))
230 if not new_band and band != bands[-1]:
231 inlines[-1] = inlines[-1] + r'\hline'
232 DataIO.writeFile(filename,input_lines=inlines)
233 if print_summary:
234 print('Summary')
235 for s in stars:
236 print('%s: %i lines measured'%(s,len(ddict[s].linefit.wave_fit))+\
237 ', of which %i lines have been identified.'%line_counter[s])
238