Package ComboCode :: Package cc :: Package tools :: Package readers :: Module RadiatReader
[hide private]
[frames] | no frames]

Source Code for Module ComboCode.cc.tools.readers.RadiatReader

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  A GASTRoNOoM radiat file parser.  
  5   
  6  Reads the GASTRoNOoM file syntax and provides the information in the form  
  7  consistent with the MolReader, the class from which this class inherits. 
  8   
  9  MolReader provides the functionality to return all info from Einstein  
 10  coefficients and frequencies, to weights, energy levels and transition levels. 
 11   
 12  Author: R. Lombaert 
 13   
 14  """ 
 15   
 16  import os  
 17  import numpy as np 
 18   
 19  import cc.path 
 20  from cc.tools.io import DataIO 
 21  from cc.tools.readers.MolReader import MolReader 
 22   
 23   
24 -class RadiatReader(MolReader):
25 26 ''' 27 Class for working with radiat files from GASTRoNOoM's input. 28 29 Inherits from MolReader, which provides the basic methods for managing 30 spectroscopic data. This class replaces some of those methods to be applied 31 to spectroscopic data given in GASTRoNOoM's input format. This is the former 32 Radiat class, integrated with the new Reader structure. 33 34 Note that RadiatReader is independent from MlineReader. MlineReader reads 35 the mline spectroscopic output data, which should in principle be identical 36 to the input data read with RadiatReader from MOLECULE_radiat.dat and 37 MOLECULE_indices.dat. 38 39 Collision rate input data are read with CollisReader. 40 41 ''' 42
43 - def __init__(self,fn,ny,nline=None,*args,**kwargs):
44 45 ''' 46 Initializing an instance of the RadiatReader class. 47 48 Additional args and kwargs are passed to the dict creation (parent of 49 Reader) 50 51 The number of levels and transitions are saved as instance properties. 52 53 @param fn: The radiat filename, including filepath. 54 @type fn: string 55 @param ny: The number of levels included in the spectroscopy 56 @type ny: int 57 58 @keyword nline: The number of transitions included in the spectroscopy. 59 If default, nline isn't known and is determined from the 60 radiat file itself. 61 62 (default: None) 63 @type nline: int 64 65 ''' 66 67 #-- Create parent instance, and set properties. 68 super(RadiatReader,self).__init__(fn,*args,**kwargs) 69 self.ny = ny 70 self.nline = nline 71 72 #-- Add the pars dict to match with the mlinereader. 73 self['pars'] = {'nline':nline,'ny':ny} 74 75 #-- Read the radiat file. This is a very nonstandard format, so the 76 # parent read method is not appropriate for this 77 self.read()
78 79 80
81 - def read(self):
82 83 ''' 84 Read the MOLECULE_radiat file and set a dictionary for the instance 85 with all the information. 86 87 Done on creation of an instance of the class. 88 89 ''' 90 91 #-- Read the radiat file which is just one long column 92 radiat = np.loadtxt(self.fn) 93 94 #-- If nline wasn't given, find out now. 95 if self.nline is None: 96 nline = DataIO.findZero(0,radiat) 97 98 #-- Check if this is a good nline. If not, there's likely no zeroes 99 # (and the above function found the 0-energy level or an ny-0). 100 if len(radiat) < 4*nline+2*self.ny: 101 #-- But there might still be zeroes for ny: this is always the 102 # first non-zero energy level 103 ienergy = DataIO.findNumber(nline,radiat) 104 105 #-- Find the ny-zeroes, but this might be end of file: no zeroes 106 n0_nyi = DataIO.findZero(ienergy,radiat) 107 if n0_nyi == len(radiat): 108 n0_ny = 0 109 110 #-- Otherwise, continue. We do have ny-zeroes 111 else: 112 n0_nyj = DataIO.findNumber(n0_nyi,radiat) 113 n0_ny = n0_nyj-n0_nyi 114 self.nline = (len(radiat)-2*(self.ny+n0_ny))/4 115 else: 116 self.nline = nline 117 self['pars']['nline'] = self.nline 118 119 #-- Prep the transition array 120 dtype = [('index',int),('lup',int),('llow',int),('frequency',float),\ 121 ('einsteinA',float)] 122 self['trans'] = np.empty(shape=(self.nline,),dtype=dtype) 123 self['trans']['index'] = range(1,self.nline+1) 124 125 #-- Prep the level array 126 dtype = [('index',int),('weight',float),('energy',float)] 127 self['level'] = np.empty(shape=(self.ny,),dtype=dtype) 128 self['level']['index'] = range(1,self.ny+1) 129 130 #-- The number of values per property is either nline or ny 131 nvals = [self.nline,self.nline,self.ny,self.ny,self.nline,self.nline] 132 133 #-- Numbers are padded with zeroes at end. The amount of padding is 134 # unknown. if total length is equal to sum of all step sizes, reading 135 # radiat is very simple. 136 if sum(nvals) == len(radiat): 137 n0_nline = 0 138 n0_ny = 0 139 140 #-- Otherwise a more elaborate method must be used to determine the 141 # amount of zero-padding that is used for each nline and ny. 142 else: 143 #-- Einstein A is never 0, so this is easy. 144 n0_nline = DataIO.findNumber(self.nline,radiat)-self.nline 145 146 #-- Two nline-sized blocks, one ny-sized block. Because the first 147 # energy level might be 0 cm^-1, this is not the real n0_ny 148 start_i = 2*(self.nline+n0_nline)+self.ny 149 n0_ny1 = DataIO.findNumber(start_i,radiat)-start_i 150 151 #-- Second ny-sized block gives the real n0_ny, since llow can never 152 # be zero: 153 start_i = DataIO.findZero(start_i+n0_ny1,radiat) 154 n0_ny = DataIO.findNumber(start_i,radiat)-start_i 155 156 #-- Collect property names, types and number of zero-padding 157 props = ['einsteinA','frequency','weight','energy','llow','lup'] 158 ptypes = ['trans','trans','level','level','trans','trans'] 159 n0s = [n0_nline,n0_nline,n0_ny,n0_ny,n0_nline,n0_nline] 160 161 #-- Save the data into the arrays 162 for i,(nval,ptype,prop) in enumerate(zip(nvals,ptypes,props)): 163 #-- Determine starting index for this block 164 start_i = sum(nvals[:i])+sum(n0s[:i]) 165 166 #-- Retrieve information 167 self[ptype][prop] = radiat[start_i:start_i+nval]
168