def __init__(self, atomicAbundance: AtomicAbundance = None, kuruczPfPath: str = None): if atomicAbundance is None: atomicAbundance = DefaultAtomicAbundance self.atomicAbundance = atomicAbundance kuruczPfPath = get_data_path( ) + 'pf_Kurucz.input' if kuruczPfPath is None else kuruczPfPath with open(kuruczPfPath, 'rb') as f: s = f.read() u = Unpacker(s) # NOTE(cmo): Each of these terms is simply in flat lists indexed by Atomic Number Z-1 self.Tpf = np.array(u.unpack_array(u.unpack_double)) stages = [] pf = [] ionpot = [] for i in range(99): z = u.unpack_int() stages.append(u.unpack_int()) pf.append( np.array( u.unpack_farray(stages[-1] * self.Tpf.shape[0], u.unpack_double)).reshape( stages[-1], self.Tpf.shape[0])) ionpot.append( np.array(u.unpack_farray(stages[-1], u.unpack_double))) ionpot = [i * Const.HC / Const.CM_TO_M for i in ionpot] pf = [np.log(p) for p in pf] self.pf = pf self.ionpot = ionpot
def __init__(self, kuruczPfPath: Optional[str]=None, metallicity: float=0.0, abundances: Dict=None, abundDex: bool=True): if set(AtomicWeights.keys()) != set(AtomicAbundances.keys()): raise ValueError('AtomicWeights and AtomicAbundances keys differ (Problem keys: %s)' % repr(set(AtomicWeights.keys()) - set(AtomicAbundances.keys()))) self.indices = OrderedDict(zip(AtomicWeights.keys(), range(len(AtomicWeights)))) # Convert abundances and overwrite any provided secondary abundances self.abund = deepcopy(AtomicAbundances) if self.abund['H '] == 12.0: for k, v in self.abund.items(): self.abund[k] = 10**(v - 12.0) if abundances is not None: if abundDex: for k, v in abundances.items(): abundances[k] = 10**(v - 12.0) for k, v in abundances.items(): self.abund[k] = v metallicity = 10**metallicity for k, v in self.abund.items(): if k != 'H ': self.abund[k] = v*metallicity kuruczPfPath = get_data_path() + 'pf_Kurucz.input' if kuruczPfPath is None else kuruczPfPath with open(kuruczPfPath, 'rb') as f: s = f.read() u = Unpacker(s) self.Tpf = np.array(u.unpack_array(u.unpack_double)) ptIndex = [] # Index in the periodic table (fortran based, so +1) -- could be used for validation stages = [] pf = [] ionpot = [] for i in range(len(AtomicWeights)): ptIndex.append(u.unpack_int()) stages.append(u.unpack_int()) pf.append(np.array(u.unpack_farray(stages[-1] * self.Tpf.shape[0], u.unpack_double)).reshape(stages[-1], self.Tpf.shape[0])) ionpot.append(np.array(u.unpack_farray(stages[-1], u.unpack_double))) ionpot = [i * Const.HC / Const.CM_TO_M for i in ionpot] pf = [np.log(p) for p in pf] totalAbund = 0.0 avgWeight = 0.0 self.elements: List[Element] = [] for k, v in AtomicWeights.items(): i = self.indices[k] ele = Element(k, v, self.abund[k], ionpot[i], self.Tpf, pf[i]) self.elements.append(ele) totalAbund += ele.abundance avgWeight += ele.abundance * ele.weight self.totalAbundance = totalAbund self.weightPerH = avgWeight self.avgMolWeight = avgWeight / totalAbund
def read_pf(path): with open(path, 'rb') as f: s = f.read() u = Unpacker(s) Tpf = u.unpack_array(u.unpack_double) ptis = [] stages = [] pf = [] ionpot = [] for i in range(len(AtomicWeights)): ptis.append(u.unpack_int()) stages.append(u.unpack_int()) pf.append(u.unpack_farray(stages[-1] * len(Tpf), u.unpack_double)) ionpot.append(u.unpack_farray(stages[-1], u.unpack_double)) return {'Tpf': Tpf, 'stages': stages, 'pf': pf, 'ionpot': ionpot}