GENE plugin
TODO: Short description of GENE software as introduction. Parser/runner are descibed within their own docstrings.
GeneParser
GeneParser(*args, **kwargs)
d_T_ped
instance-attribute
d_T_ped = get('d_T_ped', None)
args: precision: int: number of decimal places the inputs will be rounded to. This reduces the chance of gene changing them when making the effective parameters file which can lear to quasineutrality errors for example.
calc_rho_toroidal_norm_from_q_and_psi
calc_rho_toroidal_norm_from_q_and_psi(psi, q)
Calculate the toroidal flux surface coordinate rho_toroidal from the poloidal flux surface coordinate psi and safety factor q. equation: rho_toroidal = sqrt(1/(2*pi) * integral(q * dpsi))
d phi toroidal/d psi_polodial = q
--> phi_toroidal = integral(q * dpsi)
rho_toroidal = sqrt(phi_toroidal / max(phi_toroidal))
clear_directory
clear_directory(path, spare=None)
Delete all files and subdirectories inside path but keep the directory itself.
Any names listed in spare will be preserved.
Parameters
path : str Directory to clear. spare : list of str, optional Filenames or directory names to keep.
diagnose_termination_reason
diagnose_termination_reason(run_dir, output)
Boils gene_termination/gene_stable/numerically_unstable/gene_is_multimodal down to a single human-readable diagnosis, checked in priority order: early_stop > converged > stable > numerically_unstable > multimodal > inconclusive.
fd_d1_o4
fd_d1_o4(var, grid, mat=False)
Centered finite difference, first derivative, 4th order. var: quantity to be differentiated. grid: grid for var mat: matrix for the finite-differencing operator. if mat=False then it is created
get_final_simtime
get_final_simtime(run_dir, suffix='.dat')
Final GENE simulation time (Lref/cref units) reached, taken from the
last time entry of the electron heat flux history. Uses
:func:gene_single_monitor.eQ_history (the same nrg.dat parser
already relied on elsewhere, e.g. the early-stopping monitor)
rather than :meth:read_nrg. Returns np.nan if nrg.dat is missing
or unreadable.
Note: IFS_scripts' ParIO.Read_Pars calls sys.exit(...) (raising SystemExit, not a normal Exception) when the run has no readable 'parameters' file -- e.g. runs that failed before GENE ever started. SystemExit is caught here alongside Exception so those runs cleanly yield NaN instead of aborting the whole parse.
get_omega_prec
get_omega_prec(run_dir, suffix='.dat')
Absolute precision GENE used to judge growthrate (gamma) convergence, from &general omega_prec in the parameters file. Returns None if unset.
parse_fmarg
parse_fmarg(run_dir, params)
Look up HELENA's infinite-n ideal-ballooning stability (FMARG and the STABLE/UNSTABLE flag) at the GENE flux surface.
The GENE flux surface is given by rho_toroidal_norm (rhotn == box/x0).
It is taken from params['x0'] (or params['rhotn']) if present;
otherwise it is read from run_dir/parameters (box/x0). This lets you
pass the x0 value directly when the run_dir no longer exists.
HELENA's FMARG table is indexed by FLUX == psi_norm (psin), so we: 1. read the equilibrium (EQDSK_COCOS_02.OUT in params['helena_dir']) to get the psi_norm grid and q profile, 2. build rho_toroidal_norm(psi_norm) and invert it to map rhotn -> psin, 3. nearest-neighbour lookup of FMARG / ballooning at that psin.
Returns {'fmarg': float, 'ideal_ballooning_infn': float}, where the ballooning flag is 0.0 for STABLE and 1.0 otherwise.
parse_gene_wallclock_time
parse_gene_wallclock_time(run_dir)
Parse 'Total wallclock time for GENE:' from a file by reading it all at once. Returns the time in seconds as a float, or None if not found.
parse_iterdb
parse_iterdb(file_path)
Parses an iterdb file and extracts profiles, specifically looking for VROT. Returns a dictionary: {quantity_name: (x_data, y_data, x_label)}
plot_iterdb_comparison
plot_iterdb_comparison(file_paths, output_dir=None)
Plots profiles from multiple iterdb files for comparison and saves to PNG.
read_nrg
read_nrg(run_dir, suffix='.dat', time='all')
returns a dict of dataframes, one for each spiecies and one for time e.g. {electron: electron_df, ion: ion_df}
where electron_df has columns ['n1','u1_par','T1_par','T1_perp','Gamma_es','Gamma_em','Q_es','Q_em','PI_es','PI_em'] taken from gene docs for nrg file.
write_iterdb_profiles
write_iterdb_profiles(
helena_output_dir,
pathtoeqdsk,
iterdb_output_path,
impurity_handling="zeff_prof",
)
'zeff_prof' (default) writes NM1 = elite main-ion
density (ne) and a ZEFFR profile (constant, from fort.10 &phys zeff) — the original behaviour. 'impurity_prof' instead derives NM1 and NM2 from ne, zeff, zimp and zmain (all read from fort.10 &phys) via quasineutrality and the definition of Zeff (see compute_nm1_nm2), and writes NM1/NM2 profiles in place of the ZEFFR block.
VrotIterdbPlotter
parse_vrot_only
parse_vrot_only(file_path)
Parses an iterdb file but ONLY extracts the VROT profile.
plot_vrot_comparison
plot_vrot_comparison(
file_paths, output_name="vrot_comparison.png"
)
Plots only the VROT profiles from a list of files for comparison.
compute_nm1_nm2
compute_nm1_nm2(ne, zeff, zimp, zmain=1.0)
Compute main-ion (n_i, i.e. NM1) and impurity (n_z, i.e. NM2) densities from n_e, Zeff and the impurity charge zimp, assuming a single main-ion species of charge zmain and a single impurity species of charge zimp.
NOTE on naming: zmain/zimp are CHARGE numbers (Z), not mass numbers (A) — named to match HELENA's fort.10 &phys convention (e.g. zmain=1 for deuterium, whose mass number/amain is 2).
Derivation: quasineutrality (n_e = zmainn_i + zimpn_z) combined with the definition of Zeff (Zeffn_e = zmain^2n_i + zimp^2*n_z) gives:
n_z = n_e * (Zeff - zmain) / (zimp * (zimp - zmain))
n_i = (n_e - zimp * n_z) / zmain
ne, zeff may be arrays (same shape) or scalars; zimp, zmain are scalars. Returns (n_i, n_z) with the same shape as ne/zeff.
safe_read_namelist
safe_read_namelist(path)
Reads a Fortran namelist safely: - Sanitizes problematic lines - Writes to a temporary directory - Automatically deletes all temp files afterward
sanitize_lines_fast
sanitize_lines_fast(path)
Returns a list of sanitized lines: - Only quotes values containing parentheses - Leaves everything else untouched