Package ComboCode :: Package cc :: Package tools :: Package io :: Module TableWriter
[hide private]
[frames] | no frames]

Source Code for Module ComboCode.cc.tools.io.TableWriter

  1  # -*- coding: utf-8 -*- 
  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 #-- Check what instrument is requested 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 #-- Note that keeping track of transitions per star is not necessary. Here, 97 # we look at data, and these are kept track of by the filename which 98 # includes the star name. There is no confusion possible. 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 #-- Reset the integrated line strength info in the transitions, in case it 107 # was already set previously. There's no way to be sure for every trans 108 # individually if the match-up has been done before. And in addition, it 109 # needs to be done for every star separately. So play safe, and reset in 110 # the sample transition list. 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 #inlines.append(r'\multicolumn{4}{c}{PACS Band: %s} & \multicolumn{%i}{c}{} \\\hline'\ 158 #%(band,len(pstars))) 159 new_band = 1 160 for it,t in enumerate(trans): 161 #-- Check if there's any actual line strength result for any star 162 # for this particular band; in any filename in this band. 163 # Otherwise, exclude the line from the table. If there's no 164 # spectrum for this band at all, the line is excluded as well. 165 # In this case, the band will not be added to the table at all. 166 # Just look at the keys of t.unreso. If there's none of the 167 # given band, then exclude the transition. All stars are 168 # included in the same Transition() objects. 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 #-- There's at least one star with a measured line strength in this 176 # band, so add a column. 177 col1 = all_pmolecs[all_molecs.index(t.molecule.molecule)] 178 179 #-- If the band has not had a line added before, add the band now 180 if new_band: 181 col0 = band 182 new_band = 0 183 else: 184 col0 = '' 185 186 #-- Define the input for the table. 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 #-- For every star, add the measured line strength of the 193 # transition, if available. For now, it is assumed only one line 194 # strength measurement is available per star per band. (This is 195 # not strictly true, for instance for overlapping line scans, but 196 # the line integration tool makes it impossible to discern 197 # between multiple measurements of the same line in the same 198 # band) 199 for s in stars: 200 #-- Grab the filename available in the transition object for 201 # the measured line strength. If multiple filenames with the 202 # correct band are available, only the first is taken. 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 #-- Possibly, for this star, no datafiles of given band are 208 # present. Then just add no flux measurement and continue to 209 # the next star. 210 if not all_fn: 211 parts.append(r'/') 212 continue 213 else: 214 fn = all_fn[0] 215 216 #-- The filename is present, and thus should have a line 217 # strength indicated, or be flagged as a blend. If not, an 218 # error will be raised, but this should not happen! 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