1
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
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
68 super(RadiatReader,self).__init__(fn,*args,**kwargs)
69 self.ny = ny
70 self.nline = nline
71
72
73 self['pars'] = {'nline':nline,'ny':ny}
74
75
76
77 self.read()
78
79
80
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
92 radiat = np.loadtxt(self.fn)
93
94
95 if self.nline is None:
96 nline = DataIO.findZero(0,radiat)
97
98
99
100 if len(radiat) < 4*nline+2*self.ny:
101
102
103 ienergy = DataIO.findNumber(nline,radiat)
104
105
106 n0_nyi = DataIO.findZero(ienergy,radiat)
107 if n0_nyi == len(radiat):
108 n0_ny = 0
109
110
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
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
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
131 nvals = [self.nline,self.nline,self.ny,self.ny,self.nline,self.nline]
132
133
134
135
136 if sum(nvals) == len(radiat):
137 n0_nline = 0
138 n0_ny = 0
139
140
141
142 else:
143
144 n0_nline = DataIO.findNumber(self.nline,radiat)-self.nline
145
146
147
148 start_i = 2*(self.nline+n0_nline)+self.ny
149 n0_ny1 = DataIO.findNumber(start_i,radiat)-start_i
150
151
152
153 start_i = DataIO.findZero(start_i+n0_ny1,radiat)
154 n0_ny = DataIO.findNumber(start_i,radiat)-start_i
155
156
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
162 for i,(nval,ptype,prop) in enumerate(zip(nvals,ptypes,props)):
163
164 start_i = sum(nvals[:i])+sum(n0s[:i])
165
166
167 self[ptype][prop] = radiat[start_i:start_i+nval]
168