Source code for magic.series

#-*- coding: utf-8 -*-
import os
import re
import copy
import matplotlib.pyplot as plt
import numpy as np
from .log import MagicSetup
import glob
from .libmagic import fast_read, scanDir


[docs] class MagicTs(MagicSetup): """ This python class is used to read and plot the different time series written by the code: * Kinetic energy: :ref:`e_kin.TAG <secEkinFile>` * Magnetic energy of the outer core: :ref:`e_mag_oc.TAG <secEmagocFile>` * Magnetic energy of the inner core: :ref:`e_mag_ic.TAG <secEmagicFile>` * Dipole information: :ref:`dipole.TAG <secDipoleFile>` * Rotation: :ref:`rot.TAG <secRotFile>` * Diagnostic parameters: :ref:`par.TAG <secParFile>` * Geostrophy: :ref:`geos.TAG <secGeosFile>` * Taylorization measures: :ref:`Tay.TAG <secTayFile>` * Heat transfer: :ref:`heat.TAG <secHeatFile>` * Helicity: :ref:`helicity.TAG <secHelicityFile>` * Velocity square: :ref:`u_square.TAG <secu_squareFile>` * Angular momentum: :ref:`AM.TAG <secAMFile>` * Power budget: :ref:`power.TAG <secpowerFile>` * Earth-likeness of the CMB field: :ref:`earth_like.TAG <secEarthLikeFile>` * Parallel and perpendicular decomposition: :ref:`perpPar.TAG <secperpParFile>` * Phase field: :ref:`phase.TAG <secphaseFile>` * Hemisphericity: :ref:`hemi.TAG <secHemiFile>` * RMS force balance: :ref:`dtVrms.TAG <secdtVrmsFile>` * RMS induction terms: :ref:`dtBrms.TAG <secdtBrmsFile>` * Time-evolution of m-spectra: :ref:`am_[kin|mag]_[pol|tor].TAG <secTimeSpectraFiles>` Here are a couple of examples of how to use this function. >>> # plot the most recent e_kin.TAG file found in the directoy >>> MagicTs(field='e_kin') >>> >>> # stack **all** the power.TAG file found in the directory >>> ts = MagicTs(field='power', all=True) >>> print(ts.time, ts.buoPower) # print time and buoyancy power >>> >>> # If you only want to read the file ``heat.N0m2z`` >>> ts = MagicTs(field='heat', tag='N0m2z', iplot=False) """
[docs] def __init__(self, datadir='.', field='e_kin', iplot=True, all=False, tag=None): """ :param datadir: working directory :type datadir: str :param field: the file you want to plot :type field: str :param iplot: when set to True, display the plots (default True) :type iplot: bool :param all: when set to True, the complete time series is reconstructed by stacking all the corresponding files from the working directory (default False) :type all: bool :param tag: read the time series that exactly corresponds to the specified tag :type tag: str """ self.field = field pattern = os.path.join(datadir, 'log.*') logFiles = scanDir(pattern) if self.field in ('am_mag_pol','am_mag_tor','am_kin_pol','am_kin_tor'): binary = True else: binary = False if tag is not None: pattern = os.path.join(datadir, '{}.{}'.format(self.field, tag)) files = scanDir(pattern) # Either the log.tag directly exists and the setup is easy to obtain if os.path.exists(os.path.join(datadir, 'log.{}'.format(tag))): MagicSetup.__init__(self, datadir=datadir, quiet=True, nml='log.{}'.format(tag)) # Or the tag is a bit more complicated and we need to find # the corresponding log file else: st = os.path.join(datadir, '{}\.(.*)'.format(self.field)) mask = re.compile(st) if mask.match(files[-1]): ending = mask.search(files[-1]).groups(0)[0] pattern = os.path.join(datadir, 'log.{}'.format(ending)) if logFiles.__contains__(pattern): MagicSetup.__init__(self, datadir=datadir, quiet=True, nml='log.{}'.format(ending)) # Concatenate the files that correspond to the tag for k, file in enumerate(files): filename = file data = fast_read(filename, binary=binary) if k == 0: tslut = TsLookUpTable(data, self.field) else: tslut += TsLookUpTable(data, self.field) # If no tag is specified, the most recent is plotted elif not all: if len(logFiles) != 0: MagicSetup.__init__(self, quiet=True, nml=logFiles[-1]) name = '{}.{}'.format(self.field, self.tag) filename = os.path.join(datadir, name) data = fast_read(filename, binary=binary) else: mot = '{}.*'.format(self.field) dat = [(os.stat(i).st_mtime, i) for i in glob.glob(mot)] dat.sort() filename = dat[-1][1] data = fast_read(filename, binary=binary) tslut = TsLookUpTable(data, self.field) # If no tag is specified but all=True, all the directory is plotted else: if len(logFiles) != 0: MagicSetup.__init__(self, quiet=True, nml=logFiles[-1]) pattern = os.path.join(datadir, '{}.*'.format(self.field)) files = scanDir(pattern) for k, file in enumerate(files): filename = file data = fast_read(filename, binary=binary) if len(data) > 0: # File is not empty if k == 0: tslut = TsLookUpTable(data, self.field) else: tslut += TsLookUpTable(data, self.field) try: # Copy look-up table arguments into MagicTs object for attr in tslut.__dict__: setattr(self, attr, tslut.__dict__[attr]) if iplot: self.plot() except NameError: # In case tslut in not Defined print('No file correponding to field "{}" has been found'.format(self.field))
[docs] def plot(self): """ Plotting subroutines. Only called if 'iplot=True' """ if self.field == 'e_kin': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.ekin_pol, ls='-', c='C0', label='ekin pol') ax.plot(self.time, self.ekin_tor, ls='-', c='C1', label='ekin tor') ax.plot(self.time, self.ekin_pol_axi, ls='--', c='C0', label='ekin pol axi') ax.plot(self.time, self.ekin_tor_axi, ls='--', c='C1', label='ekin tor axi') ax.plot(self.time, self.ekin_tot, ls='-', c='0.25', label='ekin tot') ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Ekin') ax.set_yscale('log') ax.set_xlim(self.time.min(), self.time.max()) fig.tight_layout() elif self.field == 'e_mag_oc': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.emagoc_pol, ls='-', c='C0', label='emag pol') ax.plot(self.time, self.emagoc_tor, ls='-', c='C1', label='emag tor') ax.plot(self.time, self.emagoc_pol_axi, ls='--', c='C0', label='emag pol axi') ax.plot(self.time, self.emagoc_tor_axi, ls='--', c='C1', label='emag tor axi') ax.plot(self.time, self.emag_tot, ls='-', c='0.25', label='emag tot') ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Emag') ax.set_yscale('log') ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() # fig,ax = plt.subplots(1) # ax.plot(self.time, self.emag_es, ls='-', # label=r'${E_B}^S$') # ax.plot(self.time, self.emag_eas, ls='-', # label=r'${E_B}^A$') # ax.legend(loc='best', frameon=False) # ax.set_xlabel('Time') # ax.set_ylabel('Emag') elif self.field == 'e_mag_ic': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.emagic_pol, ls='-', c='C0', label='emagic pol') ax.plot(self.time, self.emagic_tor, ls='-', c='C1', label='emagic tor') ax.plot(self.time, self.emagic_pol_axi, ls='--', c='C0', label='emagic pol axi') ax.plot(self.time, self.emagic_tor_axi, ls='--', c='C1', label='emagic tor axi') ax.plot(self.time, self.emagic_pol+self.emagic_tor, ls='-', c='0.25', label='emagic tot') ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Emag inner core') ax.set_yscale('log') ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() elif self.field == 'rot': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.omega_ic, ls='-', label='Omega IC') if abs(self.omega_ma).max() > 0.: ax.plot(self.time, self.omega_ma, ls='-', label='Omega MA') ax.set_xlabel('Time') ax.set_ylabel('Rotation') ax.legend(loc='best', frameon=False) ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() fig1 = plt.figure() ax1 = fig1.add_subplot(111) if abs(self.lorentz_torque_ic).max() > 0.: ax1.plot(self.time, self.lorentz_torque_ic, ls='-', label='Lorentz torque on IC') if abs(self.viscous_torque_ic).max() > 0.: ax1.plot(self.time, self.viscous_torque_ic, ls='-', label='Viscous torque on IC') if abs(self.gravi_torque_ic).max() > 0.: ax1.plot(self.time, self.gravi_torque_ic, ls='-', label='Gravitationnal torque on IC') ax1.legend(loc='best', frameon=False) ax1.set_xlabel('Time') ax1.set_ylabel('Torques on IC') ax1.set_xlim(self.time[0], self.time[-1]) ax1.ticklabel_format(axis='y', style='sci', scilimits=(0,0)) ax1.axhline(0., color='0.5', ls='--', lw=1) fig1.tight_layout() if abs(self.omega_ma).max() > 0.: fig2 = plt.figure() ax2 = fig2.add_subplot(111) if abs(self.lorentz_torque_ma).max() > 0.: ax2.plot(self.time, self.lorentz_torque_ma, ls='-', label='Lorentz torque on mantle') if abs(self.viscous_torque_ma).max() > 0.: ax2.plot(self.time, self.viscous_torque_ma, ls='-', label='Viscous torque on mantle') if abs(self.gravi_torque_ma).max() > 0.: ax2.plot(self.time, self.gravi_torque_ma, ls='-', label='Gravitationnal torque on mantle') ax2.legend(loc='best', frameon=False) ax2.set_xlabel('Time') ax2.set_ylabel('Torques on mantle') ax2.set_xlim(self.time[0], self.time[-1]) ax2.ticklabel_format(axis='y', style='sci', scilimits=(0,0)) ax2.axhline(0., color='0.5', ls='--', lw=1) fig2.tight_layout() elif self.field == 'timestep': fig = plt.figure() ax = fig.add_subplot(111) ax.step(self.time, self.dt) ax.set_yscale('log') ax.set_xlabel('Time') ax.set_ylabel('Time step size') fig.tight_layout() elif self.field == 'dipole': if self.ktopb != 2: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.theta_dip, label='theta_dip') #ax.plot(self.time, self.phi_dip, 'r-', label='phi_dip') ax.set_ylabel('Dipole angle') ax.set_xlabel('Time') ax.set_ylim(-1., 181) ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.dipTot, label='Total dipolarity') ax.plot(self.time, self.dipolarity, ls='--', label='Axisym dipolarity') ax.plot(self.time, self.dipTot_cmb, ls='-', c='C2', label='Total dipolarity CMB') ax.plot(self.time, self.dip_cmb, ls='--', c='C2', label='Axisym dipolarity') if hasattr(self, 'l_geo'): lcut = self.l_geo else: lcut = 11 ax.plot(self.time, self.dip_l11, ls='-', c='C3', label='Axisym dip l={:d}'.format(lcut)) ax.plot(self.time, self.dipTot_l11, ls='--', c='C3', label='Total dip l={:d}'.format(lcut)) # ax.plot(self.time, self.dip3, ls='-', c='#e5ae38', # label='Epol axi/Ecmb') ax.legend(loc='best', frameon=False) ax.set_ylabel('Dipolarity') ax.set_xlabel('Time') ax.set_ylim(0, 1) ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() elif self.field == 'AM': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.am_oc_z, label='Outer core') if abs(self.am_ic).max() > 0.: ax.plot(self.time, self.am_ic, label='Inner core') if abs(self.am_ma).max() > 0.: ax.plot(self.time, self.am_ma, label='Mantle') ax.plot(self.time, self.amz, ls='-', c='0.25', label='Total') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.field == 'par': fig = plt.figure() ax = fig.add_subplot(111) if self.mode == 1 or self.prmag == 0.: ax.semilogy(self.time, self.rm, label='Reynolds') else: ax.semilogy(self.time, self.rm, label='Magnetic Reynolds') if self.elsasser.max() > 0.: ax.semilogy(self.time, self.elsasser, label='Elsasser') ax.semilogy(self.time, self.els_cmb, label='Elsasser CMB') ax.semilogy(self.time, self.rossby_l, label='Rossby l') if hasattr(self, 'rolc'): ax.semilogy(self.time, self.rolc, label='Roc l') ax.legend(loc='lower right', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Params') ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.semilogy(self.time, self.dlV, label='Integral (ell)') ax.semilogy(self.time, self.dlVc, label='Integral (ell c)') ax.semilogy(self.time, self.dmV, label='Integral (m)') ax.semilogy(self.time, self.dlPolPeak, label='Peak (pol)') if abs(self.lbDiss).max() > 0.: ax.semilogy(self.time, self.lbDiss, label='Magnetic dissipation') if abs(self.lvDiss).max() > 0.: ax.semilogy(self.time, self.lvDiss, label='Viscous dissipation') ax.set_xlabel('Time') ax.set_ylabel('Lengthscales') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) fig.tight_layout() if self.dipolarity.max() > 0.: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.dipolarity, label='Dipolarity') ax.plot(self.time, self.dip_cmb, label='Dipolarity CMB') ax.legend(loc='upper right', frameon=False) ax.set_xlim(self.time[0], self.time[-1]) ax.set_xlabel('Time') ax.set_ylabel('Dipolarity') ax.set_ylim(0, 1) fig.tight_layout() elif self.field == 'geos': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.geos, label='Total') ax.plot(self.time, self.geosM, label='Meridional') ax.plot(self.time, self.geosZ, label='Zonal') ax.plot(self.time, self.geosNAP, label='Non-axi perp') ax.set_xlabel('Time') ax.set_ylabel('Geostrophy') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.corr_vz_otc, label='uz') ax.plot(self.time, self.corr_vortz_otc, label='z vorticity') ax.plot(self.time, self.corr_hel_otc, label='Helicity') ax.set_xlabel('Time') ax.set_ylabel('z correlations') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.field == 'phase': fig = plt.figure() ax = fig.add_subplot(111) ax1 = ax.twinx() mask = (self.rmelt > 0) ax.plot(self.time[mask], self.rmelt[mask], label='r melt', color='C0') ax.plot(self.time, self.rmelt_mean, label='r melt', color='C0', ls=':') #ax.plot(self.time, self.rmelt_min, ls='--', color='C0', alpha=0.5) #ax.plot(self.time, self.rmelt_max, ls='--', color='C0', alpha=0.5) ax1.plot(self.time[mask], self.trmelt[mask], label='T(r melt)', color='C1') ax1.plot(self.time, self.trmelt_mean, label='T(r melt)', color='C1', ls=':') ax.set_xlim(self.time[0], self.time[-1]) ax.set_xlabel('Time') ax.set_ylabel('r melt') ax1.set_ylabel('T(r melt)') fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) ax.semilogy(self.time, self.ekinS/self.ekinL) ax.set_xlim(self.time[0], self.time[-1]) ax.set_xlabel('Time') ax.set_ylabel('Relative energy fraction in solidus') fig.tight_layout() elif self.field == 'hemi': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.hemi_emag, label='Emag') ax.plot(self.time, self.hemi_br, label='|Br| volume') ax.plot(self.time, self.hemi_cmb, label='|Br| CMB') ax.set_xlabel('Time') ax.set_ylabel('Hemisphericity') ax.set_xlim(self.time[0], self.time[-1]) ax.set_ylim(0., 1.) #ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) fig.tight_layout() elif self.field == 'earth_like': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.axial_dipole, label='AD/NAD') ax.plot(self.time, self.symmetry, label='O/E') ax.plot(self.time, self.zonality, label='Z/NZ') ax.plot(self.time, self.flux_concentration, label='FCF') ax.set_xlim(self.time[0], self.time[-1]) ax.set_xlabel('Time') ax.set_ylabel('Rating parameters') ax.legend(loc='upper right', frameon=False) fig.tight_layout() fig1 = plt.figure() ax1 = fig1.add_subplot(111) ax1.plot(self.time, self.chi_square) ax1.set_xlim(self.time[0], self.time[-1]) ax1.set_xlabel('Time') ax1.set_ylabel('Chi square') fig1.tight_layout() elif self.field == 'misc': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.topnuss, label='Top Nusselt') ax.plot(self.time, self.botnuss, label='Bottom Nusselt') ax.legend(loc='lower right', frameon=False) ax.set_xlim(self.time[0], self.time[-1]) ax.set_xlabel('Time') ax.set_ylabel('Nusselt number') fig.tight_layout() if self.helrms.max() != 0.: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.helrms) ax.set_xlim(self.time[0], self.time[-1]) ax.set_xlabel('Time') ax.set_ylabel('Helicity') fig.tight_layout() elif self.field == 'heat': fig = plt.figure() ax = fig.add_subplot(111) if self.kbots == 2 and self.ktops == 2: ax.plot(self.time, self.deltaTnuss, label=r'$Nu_{\Delta T}$') else: ax.plot(self.time, self.topnuss, label='Top Nusselt') ax.plot(self.time, self.botnuss, label='Bottom Nusselt') ax.set_xlim(self.time.min(), self.time.max()) ax.legend(loc='lower right', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Nusselt number') fig.tight_layout() if self.topsherwood.max() != 1.0 or self.deltasherwood.max() != 1.0: fig = plt.figure() ax = fig.add_subplot(111) if self.kbotxi == 2 and self.ktopxi == 2: ax.plot(self.time, self.deltasherwood, label=r'$Sh_{\Delta \xi}$') else: ax.plot(self.time, self.topsherwood, label='Top Sherwood') ax.plot(self.time, self.botsherwood, label='Bottom Sherwood') ax.legend(loc='lower right', frameon=False) ax.set_xlim(self.time.min(), self.time.max()) ax.set_xlabel('Time') ax.set_ylabel('Sherwood number') fig.tight_layout() elif self.field == 'helicity': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.helRMSN, label='Northern Hemisphere') ax.plot(self.time, self.helRMSS, label='Southern Hemisphere') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='lower right', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Helicity') fig.tight_layout() elif self.field == 'u_square': fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.ekin_pol, ls='-', c='C0', label='ekin pol') ax.plot(self.time, self.ekin_tor, ls='-', c='C1', label='ekin tor') ax.plot(self.time, self.ekin_pol_axi, ls='--', c='C0', label='ekin pol axi') ax.plot(self.time, self.ekin_tor_axi, ls='--', c='C1', label='ekin tor axi') ax.plot(self.time, self.ekin_tot, ls='-', c='0.25', label='ekin tot') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('u**2') ax.set_yscale('log') fig.tight_layout() fig = plt.figure() ax = fig.add_subplot(111) if self.mode == 1 or self.prmag == 0.: ax.semilogy(self.time, self.rm, label='Reynolds') else: ax.semilogy(self.time, self.rm, label='Magnetic Reynolds') ax.semilogy(self.time, self.ro, label='Rossby') ax.semilogy(self.time, self.rossby_l, label='Rossby l') ax.semilogy(self.time, self.dl, label='l') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='lower right', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Params') fig.tight_layout() elif self.field in ('dtVrms'): fig = plt.figure() # Poloidal forces ax = fig.add_subplot(111) ax.semilogy(self.time, self.CorRms, label='Coriolis') ax.semilogy(self.time, self.PreRms, label='Pressure') ax.semilogy(self.time, self.LFRms, label='Lorentz') ax.semilogy(self.time, self.BuoRms, label='Thermal Buoyancy') if abs(self.ChemRms).max() > 0: ax.semilogy(self.time, self.ChemRms, label='Chemical Buoyancy') ax.semilogy(self.time, self.InerRms, label='Inertia') ax.semilogy(self.time, self.DifRms, label='Diffusion') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False, ncol=2) ax.set_xlabel('Time') ax.set_ylabel('RMS forces') fig.tight_layout() fig = plt.figure() # Toroidal forces ax = fig.add_subplot(111) ax.semilogy(self.time, self.geos, label='Geostrophic balance') ax.semilogy(self.time, self.mageos, label='Magnetostrophic') ax.semilogy(self.time, self.arc, label='Archimedean') ax.semilogy(self.time, self.arcMag, label='Archimedean+Lorentz') ax.semilogy(self.time, self.corLor, label='Coriolis/Lorentz') ax.semilogy(self.time, self.preLor, label='Pressure/Lorentz') ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('RMS balances') ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() elif self.field == 'perpPar': fig = plt.figure() ax= fig.add_subplot(111) ax.plot(self.time, self.eperp, ls='-', c='C0', label='ekin perp') ax.plot(self.time, self.epar, ls='-', c='C1', label='ekin par') ax.plot(self.time, self.eperp_axi, ls='--', c='C0', label='ekin perp axi') ax.plot(self.time, self.epar_axi, ls='--', c='C1', label='ekin par axi') ax.plot(self.time, self.ekin_tot, ls='-', c='0.25', label='ekin tot') ax.plot(self.time, self.ekin_tot, 'k-') ax.set_xlim(self.time[0], self.time[-1]) ax.set_yscale('log') ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Kinetic energy') ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout() elif self.field in ('power'): fig = plt.figure() ax = fig.add_subplot(111) if self.buoPower.max() != 0.: ax.semilogy(self.time, self.buoPower, label='Thermal buoyancy') if self.buoPower_chem.max() != 0.: ax.semilogy(self.time, self.buoPower_chem, label='Chemical buoyancy') if self.ohmDiss.max() != 0.: ax.semilogy(self.time, -self.ohmDiss, label='Ohmic diss.') ax.semilogy(self.time, -self.viscDiss, label='Viscous diss.') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Power') fig.tight_layout() if hasattr(self,'fohm'): fig = plt.figure() ax = fig.add_subplot(111) ax.plot(self.time, self.fohm) ax.set_xlim(self.time[0], self.time[-1]) ax.set_ylim(0., 1.) ax.set_xlabel('Time') ax.set_ylabel('fohm') fig.tight_layout() elif self.field in ('dtBrms'): fig = plt.figure() # Poloidal ax = fig.add_subplot(111) ax.semilogy(self.time, self.DynPolRms, label='Induction') ax.semilogy(self.time, self.DifPolRms, label='Diffusion') ax.semilogy(self.time, self.dtBpolRms, label='Time derivative') ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Poloidal field production') fig.tight_layout() fig = plt.figure() # Toroidal ax = fig.add_subplot(111) ax.semilogy(self.time, self.DynTorRms, label='Induction') ax.semilogy(self.time, self.DifTorRms, label='Diffusion') ax.semilogy(self.time, self.omEffect*self.DynTorRms, label='Omega effect') ax.semilogy(self.time, self.dtBtorRms, label='Time derivative', ) ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Toroidal field production') fig.tight_layout() elif self.field in ('SRIC'): fig = plt.figure() ax = fig.add_subplot(111) ax.semilogy(self.time, self.viscTorq, label='Viscous') ax.semilogy(self.time, self.LorTorq, label='Lorentz') ax.semilogy(self.time, self.totTorq, label='Total') ax.set_xlim(self.time[0], self.time[-1]) ax.legend(loc='best', frameon=False) ax.set_xlabel('Time') ax.set_ylabel('Torque') fig.tight_layout() elif self.field in ('am_mag_pol', 'am_mag_tor', 'am_kin_pol', 'am_kin_tor'): fig = plt.figure() ax = fig.add_subplot(111) for k in range(self.coeffs.shape[1]): ax.semilogy(self.time, self.coeffs[:, k], label='m={}'.format(k)) ax.set_xlabel('Time') if self.coeffs.shape[1] < 20: ax.legend(loc='best', frameon=False) if self.field == 'am_mag_pol': ax.set_ylabel('Emag poloidal') elif self.field == 'am_mag_tor': ax.set_ylabel('Emag toroidal') elif self.field == 'am_kin_pol': ax.set_ylabel('Ekin poloidal') elif self.field == 'am_kin_tor': ax.set_ylabel('Ekin toroidal') ax.set_xlim(self.time[0], self.time[-1]) fig.tight_layout()
class TsLookUpTable: """ The purpose of this class is to create a lookup table between the numpy array that comes from the reading of the time series and the corresponding column. """ def __init__(self, data, field): """ :param data: numpy array that contains the data :type data: numpy.ndarray :param field: name of the field (i.e. 'eKinR', 'eMagR', 'powerR', ...) :type field: str """ self.field = field if self.field == 'e_kin': self.time = data[:, 0] self.ekin_pol = data[:, 1] self.ekin_tor = data[:, 2] self.ekin_pol_axi = data[:, 3] self.ekin_tor_axi = data[:, 4] self.ekin_pol_es = data[:, 5] self.ekin_tor_es = data[:, 6] self.ekin_pol_es_axi = data[:, 7] self.ekin_tor_es_axi = data[:, 8] self.ekin_tot = self.ekin_pol + self.ekin_tor self.ekin_axi = self.ekin_pol_axi + self.ekin_tor_axi self.ekin_es = self.ekin_pol_es + self.ekin_tor_es self.ekin_es_axi = self.ekin_pol_es_axi + self.ekin_tor_es_axi self.ekin_pol_naxi = self.ekin_pol-self.ekin_pol_axi self.ekin_tor_naxi = self.ekin_tor-self.ekin_tor_axi self.ekin_es_naxi = self.ekin_es-self.ekin_es_axi self.ekin_naxi = self.ekin_tot-self.ekin_pol_axi-self.ekin_tor_axi elif self.field == 'e_mag_oc': self.time = data[:, 0] self.emagoc_pol = data[:, 1] self.emagoc_tor = data[:, 2] self.emagoc_pol_axi = data[:, 3] self.emagoc_tor_axi = data[:, 4] self.ext_nrj_pol = data[:, 5] self.ext_nrj_pol_axi = data[:, 6] self.emagoc_pol_eas = data[:, 7] self.emagoc_tor_eas = data[:, 8] self.emagoc_pol_eas_axi = data[:, 9] self.emagoc_tor_eas_axi = data[:, 10] self.emag_tot = self.emagoc_pol + self.emagoc_tor self.emag_axi = self.emagoc_pol_axi + self.emagoc_tor_axi self.emag_eas = self.emagoc_pol_eas + self.emagoc_tor_eas self.emag_eas_axi = self.emagoc_pol_eas_axi + self.emagoc_tor_eas_axi elif self.field == 'e_mag_ic': self.time = data[:, 0] self.emagic_pol = data[:, 1] self.emagic_tor = data[:, 2] self.emagic_pol_axi = data[:, 3] self.emagic_tor_axi = data[:, 4] self.emagic_tot = self.emagic_pol + self.emagic_tor elif self.field == 'timestep': self.time = data[:, 0] self.dt = data[:, 1] elif self.field == 'dipole': self.time = data[:, 0] self.theta_dip = data[:, 1] self.phi_dip = data[:, 2] self.dipolarity = data[:, 3] self.dip_cmb = data[:, 4] self.dip_l11 = data[:, 5] # Cut at l=11 self.dipTot = data[:, 6] # Also non axisymmetric dipole self.dipTot_cmb = data[:, 7] # Non-axi at the CMB self.dipTot_l11 = data[:, 8] # Cut at l=11 self.e_dip_cmb = data[:, 9] self.e_dip_ax_cmb = data[:, 10] self.e_dip = data[:, 11] self.e_dip_ax = data[:, 12] self.ecmb = data[:, 13] self.egeo = data[:, 14] self.ratio_cmb_as = data[:, 16] # (e_cmb-e_es_cmb)/e_cmb self.ratio_cmb_naxi = data[:, 17] # (e_cmb-e_axi_cmb)/e_cmb self.ratio_l11_cmb_as = data[:, 18] # (e_geo-e_es_geo)/e_geo self.ratio_l11_cmb_naxi = data[:, 19] # (e_geo-e_axi_geo)/e_geo self.epol_axi_cmb = (-self.ratio_cmb_naxi*self.ecmb+self.ecmb) self.epol_rel_cmb = self.epol_axi_cmb/self.ecmb self.fdip = np.sqrt(self.dip_l11) elif self.field == 'AM': self.time = data[:, 0] self.am_oc_x = data[:, 1] self.am_oc_y = data[:, 2] self.am_oc_z = data[:, 3] self.am_ic = data[:, 4] self.am_ma = data[:, 5] self.amz = data[:, 6] self.damzdt = data[:, 7] elif self.field == 'rot': self.time = data[:, 0] self.omega_ic = data[:, 1] self.lorentz_torque_ic = data[:, 2] self.viscous_torque_ic = data[:, 3] self.omega_ma = data[:, 4] self.lorentz_torque_ma = data[:, 5] self.viscous_torque_ma = data[:, 6] if data.shape[-1] == 8: self.gravi_torque_ic = data[:, 7] else: self.gravi_torque_ic = np.zeros_like(self.omega_ic) self.gravi_torque_ma = -self.gravi_torque_ic elif self.field == 'Tay': self.time = data[:, 0] self.ekin_tora_rel = data[:, 1] self.egeos_rel = data[:, 2] self.tay = data[:, 3] self.tayR = data[:, 4] self.tayV = data[:, 5] self.ekin_cyl = data[:, 6] elif self.field == 'par': self.time = data[:, 0] self.rm = data[:, 1] self.elsasser = data[:, 2] self.rossby_l = data[:, 3] self.geos = data[:, 4] self.dipolarity = data[:, 5] self.dip_cmb = data[:, 6] self.dlV = data[:, 7] self.dmV = data[:, 8] self.lvDiss = data[:, 11] self.lbDiss = data[:, 12] self.dlB = data[:, 13] self.dmB = data[:, 14] self.els_cmb = data[:, 15] if data.shape[-1] > 16: self.rolc = data[:, 16] self.dlVc = data[:, 17] self.reEquat = data[:, 18] self.dlPolPeak = np.zeros_like(self.time) if data.shape[-1] == 20: self.dlPolPeak = data[:, 18] self.reEquat = data[:, 19] else: self.rolc = np.zeros_like(self.time) self.dlVc = np.zeros_like(self.time) self.reEquat = np.zeros_like(self.time) self.dlPolPeak = np.zeros_like(self.time) elif self.field == 'misc': self.time = data[:, 0] self.botnuss = data[:, 1] self.topnuss = data[:, 2] self.bottemp = data[:, 3] / np.sqrt(4.*np.pi) self.toptemp = data[:, 4] / np.sqrt(4.*np.pi) self.helrms = data[:, 8] self.helN = data[:, 5]*self.helrms self.helS = data[:, 6]*self.helrms try: self.botflux = data[:, 16] self.topflux = data[:, 17] except IndexError: self.botflux = np.zeros_like(self.time) self.topflux = np.zeros_like(self.time) pass elif self.field == 'geos': self.time = data[:, 0] self.geos = data[:, 1] self.ekin_ntc_rel = data[:, 2] self.ekin_stc_rel = data[:, 3] self.ekin = data[:, 4] self.corr_vz_otc = data[:, 5] self.corr_vortz_otc = data[:, 6] self.corr_hel_otc = data[:, 7] if data.shape[-1] == 8: self.geosA= np.zeros_like(self.time) self.geosZ= np.zeros_like(self.time) self.geosM= np.zeros_like(self.time) self.geosNAP = np.zeros_like(self.time) elif data.shape[-1] == 12: self.geosA = data[:, 8] self.geosZ = data[:, 9] self.geosM = data[:, 10] self.geosNAP = data[:, 11] elif self.field == 'heat': self.time = data[:, 0] self.botnuss = data[:, 1] self.topnuss = data[:, 2] self.deltaTnuss = data[:, 3] self.bottemp = data[:, 4] self.toptemp = data[:, 5] self.bots = data[:, 6] self.tops = data[:, 7] self.topflux = data[:, 8] self.botflux = data[:, 9] self.toppress = data[:, 10] self.mass = data[:, 11] try: self.botsherwood = data[:, 12] self.topsherwood = data[:, 13] self.deltasherwood = data[:, 14] self.botxi = data[:, 15] self.topxi = data[:, 16] except IndexError: self.topsherwood = np.ones_like(self.time) self.botsherwood = np.ones_like(self.time) self.deltasherwood = np.ones_like(self.time) self.botxi = np.zeros_like(self.time) self.topxi = np.zeros_like(self.time) pass elif self.field == 'helicity': self.time = data[:, 0] self.helN = data[:, 1] self.helS = data[:, 2] self.helRMSN = data[:, 3] self.helRMSS = data[:, 4] self.helnaN = data[:, 5] self.helnaS = data[:, 6] self.helnaRMSN = data[:, 7] self.helnaRMSS = data[:, 8] elif self.field == 'earth_like': self.time = data[:, 0] self.axial_dipole = data[:, 1] self.symmetry = data[:, 2] self.zonality = data[:, 3] self.flux_concentration = data[:, 4] self.chi_square = ((np.log(self.axial_dipole)-np.log(1.4))/np.log(2.))**2+\ ((np.log(self.symmetry)-np.log(1.))/np.log(2.))**2+\ ((np.log(self.zonality)-np.log(0.15))/np.log(2.5))**2+\ ((np.log(self.flux_concentration)-np.log(1.5))/np.log(1.75))**2 elif self.field == 'u_square': self.time = data[:, 0] self.ekin_pol = data[:, 1] self.ekin_tor = data[:, 2] self.ekin_pol_axi = data[:, 3] self.ekin_tor_axi = data[:, 4] self.ekin_tot = self.ekin_pol + self.ekin_tor self.ro = data[:, 5] self.rm = data[:, 6] self.rossby_l = data[:, 7] self.dl = data[:, 8] elif self.field == 'perpPar': self.time = data[:, 0] self.eperp = data[:, 1] self.epar = data[:, 2] self.eperp_axi = data[:, 3] self.epar_axi = data[:, 4] self.ekin_tot = self.eperp+self.epar elif self.field == 'phase': self.time = data[:, 0] self.rmelt_mean = data[:, 1] self.trmelt_mean = data[:, 2] if data.shape[1] == 9: self.trmelt = np.zeros_like(self.trmelt_mean) self.rmelt = np.zeros_like(self.rmelt_mean) self.rmelt_min = np.zeros_like(self.rmelt) self.rmelt_max = np.zeros_like(self.rmelt) self.volS = data[:, 3] self.ekinS = data[:, 4] self.ekinL = data[:, 5] self.flux_cmb = data[:, 6] self.flux_icb = data[:, 7] self.dEnthdt = data[:, 8] self.phase_min = np.zeros_like(self.rmelt) self.phase_max = np.zeros_like(self.rmelt) else: self.rmelt = data[:, 3] self.trmelt = data[:, 4] self.rmelt_min = data[:, 5] self.rmelt_max = data[:, 6] self.volS = data[:, 7] self.ekinS = data[:, 8] self.ekinL = data[:, 9] self.flux_cmb = data[:, 10] self.flux_icb = data[:, 11] self.dEnthdt = data[:, 12] if data.shape[1] == 15: self.phase_min = data[:, 13] self.phase_max = data[:, 14] else: self.phase_min = np.zeros_like(self.rmelt) self.phase_max = np.zeros_like(self.rmelt) elif self.field == 'hemi': self.time = data[:, 0] self.hemi_vr = data[:, 1] self.hemi_ekin = data[:, 2] self.hemi_br = data[:, 3] self.hemi_emag = data[:, 4] self.hemi_cmb = data[:, 5] self.ekin = data[:, 6] self.emag = data[:, 7] elif self.field == 'dtVrms': self.time = data[:, 0] self.InerRms = data[:, 1] self.CorRms = data[:, 2] self.LFRms = data[:, 3] self.AdvRms = data[:, 4] self.DifRms = data[:, 5] self.BuoRms = data[:, 6] if data.shape[1] == 14: self.PreRms = data[:, 7] self.geos = data[:, 8] # geostrophic balance self.mageos = data[:, 9] # magnetostrophic balance self.arcMag = data[:, 10] # Coriolis/Pressure/Buoyancy/Lorentz self.corLor = data[:, 11] # Coriolis/Lorentz self.preLor = data[:, 12] # Pressure/Lorentz self.cia = data[:, 13] # Coriolis/Inertia/Archmedean self.arc = np.zeros_like(self.geos) self.ChemRms = np.zeros_like(self.geos) elif data.shape[1] == 15: self.PreRms = data[:, 7] self.geos = data[:, 8] # geostrophic balance self.mageos = data[:, 9] # magnetostrophic balance self.arc = data[:, 10] # Coriolis/Pressure/Buoyancy self.arcMag = data[:, 11] # Coriolis/Pressure/Buoyancy/Lorentz self.corLor = data[:, 12] # Coriolis/Lorentz self.preLor = data[:, 13] # Pressure/Lorentz self.cia = data[:, 14] # Coriolis/Inertia/Archmedean self.ChemRms = np.zeros_like(self.geos) elif data.shape[1] == 16: self.ChemRms = data[:, 7] self.PreRms = data[:, 8] self.geos = data[:, 9] # geostrophic balance self.mageos = data[:, 10] # magnetostrophic balance self.arc = data[:, 11] # Coriolis/Pressure/Buoyancy self.arcMag = data[:, 12] # Coriolis/Pressure/Buoyancy/Lorentz self.corLor = data[:, 13] # Coriolis/Lorentz self.preLor = data[:, 14] # Pressure/Lorentz self.cia = data[:, 15] # Coriolis/Inertia/Archmedean elif data.shape[1] == 18: self.ChemRms = data[:, 7] self.PreRms = data[:, 8] self.MagTensRms = data[:, 9] # Magnetic tension self.MagPreRms = data[:, 10] # Magnetic pressure self.geos = data[:, 11] # geostrophic balance self.mageos = data[:, 12] # magnetostrophic balance self.arc = data[:, 13] # Coriolis/Pressure/Buoyancy self.arcMag = data[:, 14] # Coriolis/Pressure/Buoyancy/Lorentz self.corLor = data[:, 15] # Coriolis/Lorentz self.preLor = data[:, 16] # Pressure/Lorentz self.cia = data[:, 17] # Coriolis/Inertia/Archmedean elif self.field == 'dtBrms': self.time = data[:, 0] self.dtBpolRms = data[:, 1] self.dtBtorRms = data[:, 2] self.DynPolRms = data[:, 3] self.DynTorRms = data[:, 4] self.DifPolRms = data[:, 5] self.DifTorRms = data[:, 6] self.omEffect = data[:, 7] self.omega = data[:, 8] self.DynDipRms = data[:, 9] self.DynDipAxRms = data[:, 10] elif self.field == 'dtE': self.time = data[:, 0] self.dEdt = data[:, 1] self.intdEdt = data[:, 2] self.reldEdt = data[:, 3] elif self.field == 'power': self.time = data[:, 0] self.buoPower = data[:, 1] if data.shape[1] == 11: self.buoPower_chem = data[:, 2] self.icrotPower = data[:, 3] self.mantlerotPower = data[:, 4] self.viscDiss = data[:, 5] self.ohmDiss = data[:, 6] self.icPower = data[:, 7] self.mantlePower = data[:, 8] elif data.shape[1] == 10: self.buoPower_chem = np.zeros_like(self.time) self.icrotPower = data[:, 2] self.mantlerotPower = data[:, 3] self.viscDiss = data[:, 4] self.ohmDiss = data[:, 5] self.icPower = data[:, 6] self.mantlePower = data[:, 7] if abs(self.ohmDiss).max() != 0: self.fohm = -self.ohmDiss/(self.buoPower+self.buoPower_chem) self.fvis = -self.viscDiss/(self.buoPower+self.buoPower_chem) elif self.field == 'SRIC': self.time = data[:,0] self.omega_ic = data[:,1] self.viscPower = data[:,2] self.totPower = data[:,3] self.LorPower = data[:,4] self.viscTorq = abs(self.viscPower/self.omega_ic) self.totTorq = abs(self.totPower/self.omega_ic) self.LorTorq = abs(self.LorPower/self.omega_ic) elif self.field in ('am_mag_pol', 'am_mag_tor', # Tayler instability 'am_kin_pol', 'am_kin_tor'): self.time = data[:, 0] self.coeffs = data[:, 1:] else: print('The field "{}" is not know'.format(self.field)) def __add__(self, new): """ This method allows to sum two look up tables together. This is python built-in method. """ out = copy.deepcopy(new) timeOld = self.time[-1] timeNew = new.time[0] for attr in new.__dict__.keys(): if attr == 'coeffs': out.__dict__[attr] = np.vstack((self.__dict__[attr], out.__dict__[attr][1:, :])) elif attr != 'field': if attr in self.__dict__.keys(): # If the argument already existed if timeOld != timeNew: out.__dict__[attr] = np.hstack((self.__dict__[attr], out.__dict__[attr])) else: # Same time out.__dict__[attr] = np.hstack((self.__dict__[attr], out.__dict__[attr][1:])) return out