def read(self): ''' Read the collision rates file. Assumes GASTRoNOoM format. To read ALI/MCP collision rates (which are in the Lamda format), make use of the LamdaReader, which redefines this method. The other retrieval methods remain valid. Each transition is stored as an index, and gives upper and lower level index as well as the collision rate. ''' #-- Read the collis file which is just one long column. Assumes there is # at least one zero value for padding! collis = np.loadtxt(self.fn) self['pars'] = dict() #-- The number of transitions is given by the number of non-zero values # in the beginning of the file. ntrans = DataIO.findZero(0,collis) n0 = DataIO.findNumber(ntrans,collis)-ntrans #-- The number of temperatures in the file can be calculated now ntemp = (len(collis)-2*(ntrans+n0))/(ntrans+n0+1) #-- Prep the coll_trans array and add indices for coll_trans dtype = [('index',int),('lup',int),('llow',int),('rates',np.ndarray)] self['coll_trans'] = np.empty(shape=(ntrans,),dtype=dtype) self['coll_trans']['index'] = range(1,ntrans+1) #-- Add the level indices self['coll_trans']['lup'] = collis[:ntrans] self['coll_trans']['llow'] = collis[ntrans+n0:2*ntrans+n0] #-- Retrieve the temperatures. start_i = 2*(ntrans+n0) Tgrid = [collis[start_i+i*(ntrans + n0 + 1)] for i in range(ntemp)] #-- Check if any of them is zero, and # readjust ntemp (sometimes a 0 temp with 0 rates is present in file) Tgrid_real = [Ti for Ti in Tgrid if Ti != 0.] ntemp_real = len(Tgrid_real) #-- Retrieve rates and insert into array. Loop for ntemp, and ignore # rates if T is 0 there. rates = np.empty(shape=(ntrans,ntemp_real)) start_i = start_i + 1 for i,Ti in enumerate(Tgrid): if Ti == 0.0: continue this_i = start_i+i*(ntrans + n0 + 1) rates[:,i] = collis[this_i:this_i+ntrans] #-- Save into coll_trans array for i in range(ntrans): self['coll_trans']['rates'][i] = rates[i,:] #-- Save additional information self['pars']['ncoll_trans'] = ntrans self['pars']['ncoll_temp'] = ntemp_real self['coll_temp'] = np.array(Tgrid_real)
def __read(self): ''' Read the MOLECULE_radiat file and set a dictionary for the instance with all the information. Done on creation of an instance of the class. ''' radiat = DataIO.readCols(filename=self.filename, make_array=0)[0] self.dict = {} #- The starting indices for the next step are determined incrementally, #- with a right term added + arbitrary number of zeroes at the end of #- each step in the loop step_sizes = [ self.molecule.nline, self.molecule.nline, self.molecule.ny_up + self.molecule.ny_low, self.molecule.ny_up + self.molecule.ny_low, self.molecule.nline, self.molecule.nline ] if sum(step_sizes) == len(radiat): nozeroes = True else: nozeroes = False #- The ending indices are always the starting index + this index pars = ['EINSTEIN', 'FREQUENCY', 'WEIGHT', 'ENERGY', 'LOWER', 'UPPER'] i = 0 for delta, par in zip(step_sizes, pars): #- grab list from input self.dict[par] = radiat[i:i + delta] #- Determine starting index of the next list try: #- if no zeroes present: don't look for zeroes #- (important cuz an energy level may be zero) i = nozeroes \ and (i + delta) \ or DataIO.findNumber(i+delta,radiat) except IndexError: if par == 'UPPER': #- This is the last step, you expect an index error here, #- since it's the end of the file if not (len(radiat) == i + delta or radiat[i + delta] == 0): #- If the next number is zero, or if the file ends here, #- everything is OK: Move on, otherwise raise error. raise IndexError("When reading %s,"%self.filename + \ "the level indices were " + \ "formatted incorrectly. Aborting...") else: #- Too early to get this error! Aborting! raise IndexError('When reading %s,'%self.filename + \ 'file ended too soon before'+\ ' definition of all parameters. '+\ 'Aborting...') #- if zeroes are present, one ofthe energy levels may also be really zero #- check this and correct for it here. if self.dict['ENERGY'][-1] == 0.0: self.dict['ENERGY'] = self.dict['ENERGY'][0:-1] self.dict['ENERGY'][0:0] = [0.0] #Another check up... if sum(step_sizes) != sum([len(self.dict[par]) for par in pars]): raise IndexError('Fewer or more entries found for all the ' + \ 'parameters in %s than expected. Aborting...'\ %self.filename) self.dict['LOWER'] = [int(x) for x in self.dict['LOWER']] self.dict['UPPER'] = [int(x) for x in self.dict['UPPER']]
def read(self): ''' Read the MOLECULE_radiat file and set a dictionary for the instance with all the information. Done on creation of an instance of the class. ''' #-- Read the radiat file which is just one long column radiat = np.loadtxt(self.fn) #-- If nline wasn't given, find out now. if self.nline is None: nline = DataIO.findZero(0,radiat) #-- Check if this is a good nline. If not, there's likely no zeroes # (and the above function found the 0-energy level or an ny-0). if len(radiat) < 4*nline+2*self.ny: #-- But there might still be zeroes for ny: this is always the # first non-zero energy level ienergy = DataIO.findNumber(nline,radiat) #-- Find the ny-zeroes, but this might be end of file: no zeroes n0_nyi = DataIO.findZero(ienergy,radiat) if n0_nyi == len(radiat): n0_ny = 0 #-- Otherwise, continue. We do have ny-zeroes else: n0_nyj = DataIO.findNumber(n0_nyi,radiat) n0_ny = n0_nyj-n0_nyi self.nline = (len(radiat)-2*(self.ny+n0_ny))/4 else: self.nline = nline self['pars']['nline'] = self.nline #-- Prep the transition array dtype = [('index',int),('lup',int),('llow',int),('frequency',float),\ ('einsteinA',float)] self['trans'] = np.empty(shape=(self.nline,),dtype=dtype) self['trans']['index'] = range(1,self.nline+1) #-- Prep the level array dtype = [('index',int),('weight',float),('energy',float)] self['level'] = np.empty(shape=(self.ny,),dtype=dtype) self['level']['index'] = range(1,self.ny+1) #-- The number of values per property is either nline or ny nvals = [self.nline,self.nline,self.ny,self.ny,self.nline,self.nline] #-- Numbers are padded with zeroes at end. The amount of padding is # unknown. if total length is equal to sum of all step sizes, reading # radiat is very simple. if sum(nvals) == len(radiat): n0_nline = 0 n0_ny = 0 #-- Otherwise a more elaborate method must be used to determine the # amount of zero-padding that is used for each nline and ny. else: #-- Einstein A is never 0, so this is easy. n0_nline = DataIO.findNumber(self.nline,radiat)-self.nline #-- Two nline-sized blocks, one ny-sized block. Because the first # energy level might be 0 cm^-1, this is not the real n0_ny start_i = 2*(self.nline+n0_nline)+self.ny n0_ny1 = DataIO.findNumber(start_i,radiat)-start_i #-- Second ny-sized block gives the real n0_ny, since llow can never # be zero: start_i = DataIO.findZero(start_i+n0_ny1,radiat) n0_ny = DataIO.findNumber(start_i,radiat)-start_i #-- Collect property names, types and number of zero-padding props = ['einsteinA','frequency','weight','energy','llow','lup'] ptypes = ['trans','trans','level','level','trans','trans'] n0s = [n0_nline,n0_nline,n0_ny,n0_ny,n0_nline,n0_nline] #-- Save the data into the arrays for i,(nval,ptype,prop) in enumerate(zip(nvals,ptypes,props)): #-- Determine starting index for this block start_i = sum(nvals[:i])+sum(n0s[:i]) #-- Retrieve information self[ptype][prop] = radiat[start_i:start_i+nval]
def read(self): ''' Read the collision rates file. Assumes GASTRoNOoM format. To read ALI/MCP collision rates (which are in the Lamda format), make use of the LamdaReader, which redefines this method. The other retrieval methods remain valid. Each transition is stored as an index, and gives upper and lower level index as well as the collision rate. ''' #-- Read the collis file which is just one long column. Assumes there is # at least one zero value for padding! collis = np.loadtxt(self.fn) self['pars'] = dict() #-- The number of transitions is given by the number of non-zero values # in the beginning of the file. ntrans = DataIO.findZero(0, collis) n0 = DataIO.findNumber(ntrans, collis) - ntrans #-- The number of temperatures in the file can be calculated now ntemp = (len(collis) - 2 * (ntrans + n0)) / (ntrans + n0 + 1) #-- Prep the coll_trans array and add indices for coll_trans dtype = [('index', int), ('lup', int), ('llow', int), ('rates', np.ndarray)] self['coll_trans'] = np.empty(shape=(ntrans, ), dtype=dtype) self['coll_trans']['index'] = range(1, ntrans + 1) #-- Add the level indices self['coll_trans']['lup'] = collis[:ntrans] self['coll_trans']['llow'] = collis[ntrans + n0:2 * ntrans + n0] #-- Retrieve the temperatures. start_i = 2 * (ntrans + n0) Tgrid = [collis[start_i + i * (ntrans + n0 + 1)] for i in range(ntemp)] #-- Check if any of them is zero, and # readjust ntemp (sometimes a 0 temp with 0 rates is present in file) Tgrid_real = [Ti for Ti in Tgrid if Ti != 0.] ntemp_real = len(Tgrid_real) #-- Retrieve rates and insert into array. Loop for ntemp, and ignore # rates if T is 0 there. rates = np.empty(shape=(ntrans, ntemp_real)) start_i = start_i + 1 for i, Ti in enumerate(Tgrid): if Ti == 0.0: continue this_i = start_i + i * (ntrans + n0 + 1) rates[:, i] = collis[this_i:this_i + ntrans] #-- Save into coll_trans array for i in range(ntrans): self['coll_trans']['rates'][i] = rates[i, :] #-- Save additional information self['pars']['ncoll_trans'] = ntrans self['pars']['ncoll_temp'] = ntemp_real self['coll_temp'] = np.array(Tgrid_real)