""" This module provides an interface to from KEPLER dump files to NuGrid SE files. The provided class SeKepDump extends the DumpFile class and provides the sewrite routine. """ from __future__ import division from __future__ import print_function from __future__ import with_statement import os import os.path import datetime import uuid import numpy as np from byte2human import byte2human from time2human import time2human from version2human import version2human import physconst from isotope import Ion, KepIon from kepdump import KepDump # for se_writing from se_filename import se_filename from se import seFile def loaddump(*args, **kwargs): return SeKepDump(*args, **kwargs) class SeKepDump(KepDump): """ Write KEPLER dump files to SE files. Method: sewrite KEYWORDS dir - where to write files [.] burn - write out BURN abundances [True]. compression_level - passed to se before first write[0]. """ def sewrite(self, dir = '.', burn = True, compression_level = 0, silent = None): """Write the data into SE file.""" start_time = datetime.datetime.now() self.setup_logger(silent) dir = os.path.expanduser(dir) dir = os.path.expandvars(dir) if not dir.endswith(os.path.sep): dir += os.path.sep jm = self.qparm.jm ncyc = self.qparm.ncyc hdf5file = dir + se_filename( mass = self.parm.totm0 / physconst.Kepler.solmass, metallicity = self.qparm.zinit, cycle = ncyc, comment = 'kepler') try: os.remove(hdf5file) except: pass se = seFile(hdf5file) se.compression_level = compression_level self.logger.info('Creating SE File {}'.format(hdf5file)) codev = "kepler {}".format(version2human(self.parm.setparm)) modname = self.filename mini = self.parm.totm0 / physconst.Kepler.solmass zini = self.qparm.zinit rotini = self.qparm.anglint overini = self.parm.woversht # write global attributes se.writeattr(-1, "codev", codev) se.writeattr(-1, "modname", modname) se.writeattr(-1, "mini", mini) se.writeattr(-1, "zini", zini) se.writeattr(-1, "rotini", rotini) se.writeattr(-1, "overini", overini) # units age_unit = 1.e0 mass_unit = physconst.Kepler.solmass radius_unit=1.e0 rho_unit=1.e0 temperature_unit=1.e0 pressure_unit=1.e0 velocity_unit=1.e0 dcoeff_unit=1.e0 energy_unit=1.e0 se.writeattr(-1, "age_unit",age_unit) se.writeattr(-1, "mass_unit",mass_unit) se.writeattr(-1, "radius_unit",radius_unit) se.writeattr(-1, "rho_unit",rho_unit) se.writeattr(-1, "temperature_unit",temperature_unit) se.writeattr(-1, "pressure_unit",pressure_unit) se.writeattr(-1, "velocity_unit",velocity_unit) se.writeattr(-1, "dcoeff_unit",dcoeff_unit) se.writeattr(-1, "energy_unit",energy_unit) # write out cycle information ncyclenb = 1 ifirstcycle = ncyc ilastcycle = ncyc se.writeattr(-1, "icyclenb",ncyclenb) se.writeattr(-1, "ifirstcycle", ifirstcycle) se.writeattr(-1, "ilastcycle", ilastcycle) # write some extra data from KEPLER try: se.writeattr(-1, "UUID_run", str(uuid.UUID(bytes=self.uuidrun))) except: pass # Now write out per-cycle data iconv = np.zeros(jm + 2, dtype = np.int32) for j in xrange(1,jm - 1): icon = self.icon[j].strip() if icon == 'conv': iconv[j] = 1 elif icon == 'semi': iconv[j] = 2 elif icon == 'osht': iconv[j] = 3 elif icon == 'that': iconv[j] = 4 elif icon == 'neut': iconv[j] = 5 xm = self.xm.copy() xm[0] = self.parm.summ0 mass = xm.cumsum() if not hasattr(self,"bfdiffef"): self.bfdiffef = np.zeros(jm + 2, dtype = np.float64) if not hasattr(self,"angdgeff"): self.angdgeff = np.zeros(jm + 2, dtype = np.float64) if not hasattr(self,"difieff"): self.difieff = np.zeros(jm + 2, dtype = np.float64) xdifi = self.parm.difim * (self.difieff + self.parm.angfc * self.angdgeff + self.bfdiffef) dn = self.dn.copy() pn = self.pn.copy() tn = self.rn.copy() dn[0] = 0 pn[0] = 0 tn[0] = 0 structure = dict() structure["mass"] = mass[-2::-1] / physconst.Kepler.solmass structure["delta_mass"] = xm[-2::-1] / physconst.Kepler.solmass structure["pressure"] = pn[-2::-1] structure["temperature"] = tn[-2::-1] structure["radius"] = self.rn[-2::-1] structure["rho"] = dn[-2::-1] structure["velocity"] = self.un[-2::-1] structure["dcoeff"] = xdifi[-2::-1] structure["convection_indicator"] = iconv[-2::-1] structure["energy_generation"] = self.sn[-2::-1] if burn: A = self.aionb Z = self.zionb iso_name = np.array([ion.strip() for ion in self.ionsb]) y = self.ppnb[:,-2::-1] * A[:,np.newaxis] else: nionmax = len(self.ions) y = np.ndarray([nionmax,jm+2], dtype = np.float64) isel = np.zeros(nionmax) for j in xrange(1,jm): net = self.netnum[j] iion = self.ionn[0:18,net-1]-1 y[iion,j] = self.ppn[0:18,j] isel[iion] = 1 isel = np.where(isel == 1)[0] ions = [KepIon(self.ions[i]) for i in isel] A = [ion.A for ion in ions] Z = [ion.A for ion in ions] iso_name = [ion.name() for ion in ions] y = y[isel,-2::-1] * np.maximum(A,1)[:,np.newaxis] structure["iso_massf"] = y.swapaxes(0,1) se.write(ncyc, structure) se.writearrayattr(ncyc, "Z", Z) se.writearrayattr(ncyc, "A", A) se.writearrayattr(ncyc, "iso_name", iso_name) age = self.parm.time + self.parm.toffset totm = self.qparm.totm + self.parm.summ0 se.writeattr(ncyc, "model_number", ncyc) se.writeattr(ncyc, "total_mass", totm / physconst.Kepler.solmass) se.writeattr(ncyc, "age", age ) se.writeattr(ncyc, "deltat", self.qparm.dt) se.writeattr(ncyc, "shellnb", jm) se.writeattr(ncyc, "logL", np.log10(max(self.qparm.xlum / physconst.XLSUN,1.e0))) se.writeattr(ncyc, "logTeff", np.log10(max(self.qparm.teff,1.e0))) # write some extra data from KEPLER try: se.writeattr(ncyc, "UUID_cycle", str(uuid.UUID(bytes=self.uuidcycle))) se.writeattr(ncyc, "UUID_dump", str(uuid.UUID(bytes=self.uuiddump))) se.writeattr(ncyc, "UUID_prog", str(uuid.UUID(bytes=self.uuidprog))) except: pass se.close() end_time = datetime.datetime.now() save_time = end_time - start_time self.logger.info('SE data written in ' + time2human(save_time.total_seconds())) self.close_logger()