Getting Started =============== Installation ------------ Core package (ionization calculations, unit conversions, parameter store, NIST ionization potentials):: pip install gasfir With fitting, retrieval pipeline, and uncertainty quantification:: pip install gasfir[retrieval] With all development tools:: pip install gasfir[retrieval,dev,docs] Using the conda environment shipped with the repository:: conda env create -f environment.yml conda activate gasfir pip install -e ".[retrieval,dev,docs]" Package layout -------------- .. list-table:: :header-rows: 1 * - Module - Requires - Contents * - ``gasfir`` - core - Pulse classes, kernels, parameter store, unit conversions, NIST ionization potentials * - ``gasfir.fitting`` - ``[retrieval]`` - Residual functions for parameter fitting * - ``gasfir.retrieval`` - ``[retrieval]`` - Full CMA-ES → LS → emcee pipeline, output generation, post-processing Basic Workflow -------------- Every GASFIR calculation follows three steps: 1. **Create a laser pulse** with :func:`gasfir.create_pulse`. 2. **Load a parameter dict** with :func:`gasfir.get_parameters`. 3. **Compute the ionization observable**. .. code-block:: python from gasfir import create_pulse, get_parameters, get_diabatic_ionization_probability laser = create_pulse(800, 8.8e13, 0, 6) params = get_parameters("Hydrogen_SFA") prob = get_diabatic_ionization_probability(pulse=laser, param_dict=params) print(f"P = {prob:.4e}") Ionization Rate Models ---------------------- GASFIR provides three ionization models. The GASFIR and exact-SFA models are both reached through :func:`gasfir.get_diabatic_ionization_probability` via its ``kernel_type`` argument; the quasi-static model has its own function. **GASFIR kernel** (recommended for most uses — semi-analytic, accounts for non-adiabatic corrections; ``kernel_type="GASFIR"`` is the default): .. code-block:: python from gasfir import get_diabatic_ionization_probability prob = get_diabatic_ionization_probability(pulse=laser, param_dict=params) **Exact SFA** (full numerical saddle-point integration) — same function, selected with ``kernel_type="exact_SFA"``. The exact SFA kernel is currently implemented for the **hydrogen** ground state only and should be used with the ``H_SFA`` parameters. For hydrogen the GASFIR kernel with ``H_SFA`` reproduces the exact SFA result (GASFIR was fit to it), so the two agree: .. code-block:: python from gasfir import get_diabatic_ionization_probability, get_parameters params = get_parameters("H_SFA") # hydrogen prob_sfa = get_diabatic_ionization_probability( pulse=laser, param_dict=params, kernel_type="exact_SFA" ) **Quasi-static (QS)** (adiabatic / tunnelling limit; fastest to evaluate): .. code-block:: python from gasfir import get_probability_quasi_static_limit prob_qs = get_probability_quasi_static_limit(pulse=laser, param_dict=params) All three return a scalar probability (float). For the time-resolved rate instead of the integrated probability, use :func:`gasfir.get_diabatic_ionization_rate` (GASFIR / exact SFA) or :func:`gasfir.get_rate_quasi_static_limit` (QS). Available Parameter Sets ------------------------ Calling :func:`gasfir.get_parameters` with no argument returns a list of all built-in medium names, including their aliases: .. code-block:: python import gasfir gasfir.get_parameters() # returns a list of all available material names The full table of built-in parameter sets is shown below. It is auto-generated at docs build time by a ``conf.py`` hook that writes ``docs/_static/parameter_table.txt``: .. literalinclude:: ../_static/parameter_table.txt :language: text See :doc:`parameters` for a full description of each set. NIST Ionization Potentials -------------------------- First ionization potentials for all 118 elements are built into GASFIR:: from gasfir import get_ionization_potential get_ionization_potential("Ar") # 0.5792 a.u. (argon) get_ionization_potential("helium") # 0.9036 a.u. (full name works) get_ionization_potential("Kr") # 0.5145 a.u. These values are used automatically when fitting a medium not yet in the parameter store — you only need to provide E_g for crystals. Batch Processing ---------------- **Intensity scan** — compute ionization probabilities over a range of intensities: .. code-block:: python import numpy as np from gasfir import create_pulse, get_diabatic_ionization_probability, get_parameters params = get_parameters("H_SFA") intensities = np.logspace(13, 15, 20) # W/cm^2 probs = [ get_diabatic_ionization_probability( pulse=create_pulse(800, I, 0, 6), param_dict=params ) for I in intensities ] **Residual computation** — evaluate fit residuals over a dataset (useful when implementing custom cost functions): .. code-block:: python from gasfir import get_diabatic_ionization_probability import numpy as np def compute_residuals(params, data_df): """data_df has columns: pulses (Pulse objects), Y (measured probabilities)""" predicted = np.array([ get_diabatic_ionization_probability(pulse=row.pulses, param_dict=params) for _, row in data_df.iterrows() ]) return predicted - data_df["Y"].values Parameter Fitting & Retrieval (``gasfir[retrieval]``) ------------------------------------------------------ The three-phase pipeline (CMA-ES → least-squares → emcee) is in :mod:`gasfir.retrieval`:: from gasfir.retrieval import RetrievalConfig, retrieve # Known medium — parameters and bounds from stored reference cfg = RetrievalConfig(medium_name="Hydrogen_SFA") result = retrieve(data_NA=data, config=cfg) # Atom cold start — E_g from NIST, no other guess needed cfg = RetrievalConfig(medium_name="Kr", cma_maxiter=5000) # Crystal cold start — E_g must be supplied cfg = RetrievalConfig( medium_name="MyMaterial", initial_params={"E_g": 0.30}, is_crystal=True, ret_electron_density=True, ) See :doc:`/examples/parameter_fitting` for complete examples.