Skip to main content

Spark Multi-element Combinatory Boltzmann Plots

Project description

Spark Multi-element Combinatory Boltzmann Plot

What is it?

Spark Multi-element Combinatory Boltzmann Plot is an OES-based approach to deduce the number concentration ratio of two elements present in a spark discharge plasma employed for binary NP generation in the gas phase. It is aimed to provide a tool for investigating the evolution of the concentration ratio corresponding to the ablated electrode materials in spark-based NP generators under real operational conditions. The method is based on the construction of a Boltzmann plot for the spectral line intensity ratios at every combination. The produced plots (the so-called multi-element combinatory Boltzmann plots, MEC-BPs) are directly related to the LTE plasma temperature and the number concentration ratio of the neutral atoms. The total concentration ratio – including ions – is calculated from a simple plasma model, without requiring further measurements.

More in our article here.

If you use this software, please cite.

Table of Contents

Installation

You can install the package using pip:

pip install spark-mec-bp

Usage

Concentration calculation

Running the app

The program can be run in the following way:

from spark_mec_bp import application

config = application.AppConfig(
        spectrum=application.SpectrumConfig(
            file_path="spark_mec_bp/application/test/test_data/input_data.asc",
            wavelength_column_index=0,
            intensity_column_index=10
        ),
        first_species=application.SpeciesConfig(
            atom_name="Au I",
            ion_name="Au II",
            target_peaks=[312.278, 406.507, 479.26]
        ),
        second_species=application.SpeciesConfig(
            atom_name="Ag I",
            ion_name="Ag II",
            target_peaks=[338.29, 520.9078, 546.54]
        ),
        carrier_gas=application.CarrierGasConfig(
            atom_name="Ar I",
            ion_name="Ar II"
        ),
        spectrum_correction=application.SpectrumCorrectionConfig(
            iteration_limit=50,
            ratio=0.00001,
            lam=1000000
        ),
        peak_finding=application.PeakFindingConfig(
            minimum_requred_height=2000
        ),
        voigt_integration=application.VoigtIntegrationConfig(
            prominence_window_length=40
        )
    )

    app = application.App(config)

    result = app.run()

As shown above, the App class needs to be instantiated with its config, an instance of AppConfig.

Configuring the app

The AppConfig itself can be configured with instances of the following config (sub)classes:

  • SpectrumConfig: configures parameters related to spectrum.

    SpectrumConfig(
            file_path="spark_mec_bp/application/test/test_data/input_data.asc",
            wavelength_column_index=0,
            intensity_column_index=10
        )
    

    Currently it can only read tabulated ascii spectrums:

      443.40219	33719.7	10634.2
      443.42908	31275.6	10916.1
      443.45596	32166.2	10073.6
      443.48285	31270.6	8646.38
      443.50974	28468.9	8518.12
    
    • file_path: path to read ascii spectrum from
    • wavelength_column_index: column index of the wavelengths, starting from zero
    • intensity_column_index: column index of the intesities to use for calculation, starting from zero
  • SpeciesConfig: configures parameters for a species to estimate the concentration ratio for:

    SpeciesConfig(
        atom_name="Au I",
        ion_name="Au II",
        target_peaks=[312.278, 406.507, 479.26]
    )
    
    • atom_name: neutral atom form of the target species.
    • ion_name: ion form of the target species
    • target_peaks: list of peaks to be used for concentration calculation

    :warning: As the program uses the NIST database to query atomic data, atom and ion name parameters must conform with NIST query conventions. For more information see: https://physics.nist.gov/PhysRefData/ASD/lines_form.html

  • CarrierGasConfig: parameters related to the carrier gas. Used for electron concentration estimation.

    CarrierGasConfig(
        atom_name="Ar I",
        ion_name="Ar II"
    )
    
    • atom_name: neutral atom form of the target species
    • ion_name: ion form of the target species
  • SpectrumCorrectionConfig: configures parameters related to spectrum correction. It uses the Asymmetrically Reweighted Penalized Least Squares Smoothing (arPLS) algorithm

    SpectrumCorrectionConfig(
        iteration_limit=50,
        ratio=0.00001,
        lam=1000000
    )
    
    • iteration_limit: number of iterations to perform
    • ratio: wheighting deviations: 0 < ratio < 1, smaller values allow less negative values
    • lam: parameter that can be adjusted by user. The larger lambda is, the smoother the resulting background
  • PeakFindingConfig: configures parameters related to peak finding. For more information see scipy documentation.

    PeakFindingConfig(
        minimum_requred_height=2000
    )
    
    • minimum_requred_height: Required height of peak
  • VoigtIntegrationConfig: configures parameters related the calculations of peak integral intensities.

    VoigtIntegrationConfig(
        prominence_window_length=40
    )
    
    • prominence_window_length: A window length in samples that optionally limits the evaluated area for each peak to a subset of x. For further information see scipy documentation.

Accessing the results

The program provides the following results as an instance of a result class:

  • original_spectrum the original spectrum (numpy.ndarray)
  • corrected_spectrum: the corrected spectrum (numpy.ndarray)
  • baseline: the calculated baseline (numpy.np.ndarray)
  • peak_indices: the detected peak indices (numpy.ndarray)
  • intensity_ratios: intensity ratios (numpy.ndarray)
  • fitted_intensity_ratios: fitted intensity ratios (np.ndarray)
  • total_concentration: the total calculated concentration ratio of the two target elements (float)
  • temperature: the plasma temperature (float)
  • first_species_atomic_lines: the atomic lines data for the first species (numpy.ndarray)
  • second_species_atomic_lines: the atomic lines data for the second species (numpy.ndarray)
  • first_species_integrals_data: data related to integration of first species (VoigtIntegralData)
  • second_species_integrals_data: data related to integration of second species (VoigtIntegralData)

The integral data contains the following properties:

  • integrals: the integrals calculated for the selected peaks (numpy.ndarray)
  • fits: List of integral fits with the containing items having the follow properties:
    • fit: the fitted line (numpy.ndarray)
    • wavelengths: wavelengths used for integral calculation (numpy.ndarray)
    • intensities: the respective intensities (numpy.ndarray)

Example usage:

app = application.App(config)
result = app.run()
print(result.temperature)
print(result.second_species_integrals_data.fits[0].fit)
print(result.second_species_integrals_data.fits[0].wavelengths)
print(result.second_species_integrals_data.fits[0].intensities)

Validation and plotting

To validate the results the lin pair deviations can be checked using the LinePairChecker class:

from spark-mec-bp.validation import LinePairChecker

line_pair_checker = LinePairChecker()
AuI_linepair_check = line_pair_checker.check_line_pairs(
    result.first_species_atomic_lines,
    result.first_species_integrals_data.integrals,
    result.temperature,
)
AgI_linepair_check = line_pair_checker.check_line_pairs(
    result.second_species_atomic_lines,
    result.second_species_integrals_data.integrals,
    result.temperature,
)

print(
    f"{config.first_species.atom_name} linepair deviations: {AuI_linepair_check}"
)
print(
    f"{config.second_species.atom_name} linepair deviations: {AgI_linepair_check}"
)

To be able to further analyize the results some predifined plots are also provided as methods of a separate Plotter class:

from spark_mec_bp.plotting import Plotter

plotter = Plotter()

plotter.plot_original_spectrum(
    spectrum=result.original_spectrum,
    baseline=result.baseline,
    spectrum_intensity_column_index=config.spectrum.intensity_column_index
)

plotter.plot_saha_boltzmann_line_pairs(
    intensity_ratios=result.intensity_ratios,
    fitted_intensity_ratios=result.fitted_intensity_ratios
)

plotter.plot_baseline_corrected_spectrum_with_the_major_peaks(
    corrected_spectrum=result.corrected_spectrum,
    peak_indices=result.peak_indices,
    wlen=config.voigt_integration.prominence_window_length,
    xlim=[400, 410],
    ylim=[0, 2000],
)

plotter.plot_voigt_fit("Au I", result.first_species_integrals_data.fits)
plotter.plot_voigt_fit("Ag I", result.second_species_integrals_data.fits)

Querying data from NIST database

Fetching data

The software can also be used to fetch data directly from NIST. All three forms (atomic lines data, atomic levels data, ionization energies) can be fetched, although some limitations are still present compared to the capabilities of the online forms.

:warning: As the program uses the NIST database to query atomic data, spectrum parameter must conform with NIST query conventions. For more information see: https://physics.nist.gov/PhysRefData/ASD/lines_form.html

Fetching atomic lines data

Atomic lines data can be fetched using the AtomicLinesFetcher class:

from spark_mec_bp.nist import fetchers

atomic_lines_fetcher = fetchers.AtomicLinesFetcher()

atomic_lines_data = atomic_lines_fetcher.fetch(
    spectrum="Ag I", lower_wavelength=400, upper_wavelength=800
)

print(atomic_lines_data.data)

The fetch function expects the following parameters:

  • spectrum: name of spectrum to be fetched, conforming NIST conventions (str)
  • lower_wavelength: lower wavelength of spectrum (int)
  • upper_wavelength: upper wavelength of spectrum (int)

For more information regarding the form details and output see NIST atomic lines form.

Example output (truncated):

obs_wl_air(nm) ritz_wl_air(nm) unc_ritz_wl obs-ritz wn(cm-1) Aki(s^-1) fik S(a.u.) log_gf Acc Ei(cm-1) Ek(cm-1) conf_i term_i J_i conf_k term_k J_k g_i g_k Type
"405.5476" "405.54750" "0.00003" "0.0001" "24651.06" "" "" "" "" "" "29552.05741" "54203.119" "4d10.5p" "2P*" "1/2" "4d10.6d" "2D" "3/2" 2 4
"408.343" "" "" "" "24482.3" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""
"421.0960" "421.09542" "0.00005" "0.0006" "23740.87" "" "" "" "" "" "30472.66516" "54213.564" "4d10.5p" "2P*" "3/2" "4d10.6d" "2D" "5/2" 4 6

Fetching atomic levels data

Atomic levels data can be fetched using the AtomicLevelsFetcher class:

from spark_mec_bp.nist import fetchers

atomic_levels_fetcher = fetchers.AtomicLevelsFetcher()

atomic_levels_data = atomic_levels_fetcher.fetch(
    "Ag I", temperature=2
)

print(atomic_levels_data.data)

The fetch function expects the following parameters:

  • spectrum: name of spectrum to be fetched, conforming NIST conventions (str)
  • temperature: temperature in eV to calculate partition function for (float)

For more information regarding the form details and output see NIST atomic levels form.

Example output (truncated):

Configuration Term J g Prefix Level (cm-1) Suffix Uncertainty (cm-1)
"4d10.5s" "2S" "1/2" 2 "" "0.000000" "" ""
"4d10.5p" "2P*" "1/2" 2 "" "29552.05741" "" "0.00014"
"4d10.5p" "2P*" "3/2" 4 "" "30472.66516" "" "0.00022"
"4d9.5s2" "2D" "5/2" 6 "" "30242.298349" "" "0.000006"

Partition function for Te = 5 eV: Z = 117.92

Fetching ionization energies

The ionization energies form can also be fetched using the IonizationEnergiesFetcher class:

from spark_mec_bp.nist import fetchers

ionization_energy_fetcher = fetchers.IonizationEnergyFetcher()

ionization_energies_data = ionization_energy_fetcher.fetch(
    spectrum="Ag I"
)

print(ionization_energies_data.data)

The fetch function expects the following parameters:

  • spectrum: name of spectrum to be fetched, conforming NIST conventions (str)

For more information regarding the form details and output see NIST ionization energies form.

Example output (truncated):

At. num Sp. Name Ion Charge El. Name Isoel. Seq. Ground Shells (a) Ground Config. Ground Level Ionized Level Prefix Ionization Energy (1/cm) Suffix Uncertainty (1/cm)
"47" "Ag I" "0" "Silver" "Ag" "[Kr].4d10.5s" "4d10.5s" "2S<1/2>" "4d10 1S<0>" "" "61106.45" "" "0.20"

(a) Designations used in the ground shell lists: [Kr] = 1s2.2s2.2p6.3s2.3p6.3d10.4s2.4p6

Parsing fetched data

Data parsers are available to safely load and process the fetched data, which makes it possible to easily integrate NIST querying with other python codes.

The fetched tables are parsed into pandas dataframes, which is the only supported way, currently.

Parse atomic lines data

Atomic lines data can be parsed using the AtomicLinesParser class the following way:

from spark_mec_bp.nist import fetchers, parsers

atomic_lines_fetcher = fetchers.AtomicLinesFetcher()

atomic_lines_data = atomic_lines_fetcher.fetch(
    spectrum="Ag I",
    lower_wavelength=400,
    upper_wavelength=800
)

atomic_lines_parser = parsers.AtomicLinesParser()
parsed_data = atomic_lines_parser.parse_atomic_lines(atomic_lines_data)

print(parsed_data)

Exampe output (truncated):

obs_wl_air(nm) ritz_wl_air(nm) unc_ritz_wl obs-ritz wn(cm-1) Aki(s^-1) fik J_i conf_k term_k J_k g_i g_k Type
405.5476 405.547500 0.000030 0.0001 24651.060 NaN NaN 1/2 4d10.6d 2D 3/2 2.0 4.0 NaN
408.3430 NaN NaN NaN 24482.300 NaN NaN NaN NaN NaN NaN NaN NaN NaN
421.0960 421.095420 0.000050 0.0006 23740.870 NaN NaN 3/2 4d10.6d 2D 5/2 4.0 6.0 NaN

Parse atomic levels data

Atomic levels data can be parsed using the AtomicLevelsParser class the following way:

from spark_mec_bp.nist import fetchers, parsers

atomic_levels_fetcher = fetchers.AtomicLevelsFetcher()

atomic_levels_data = atomic_levels_fetcher.fetch(
    spectrum="Ag I",
    temperature=5
)

atomic_levels_parser = parsers.AtomicLevelsParser()
parsed_data = atomic_levels_parser.parse_atomic_levels(atomic_levels_data)
partition_function = atomic_levels_parser.parse_partition_function(atomic_levels_data)

print(parsed_data)
print(partition_function)

Example output for table (truncated):

Configuration Term J g Prefix Level (cm-1) Suffix Uncertainty (cm-1)
4d10.5s 2S 1/2 2.0 NaN 0.000000 NaN NaN
4d10.5p 2P* 1/2 2.0 NaN 29552.057410 NaN 0.000140
4d10.5p 2P* 3/2 4.0 NaN 30472.665160 NaN 0.000220
4d9.5s2 2D 5/2 6.0 NaN 30242.298349 NaN 0.000006
4d9.5s2 2D 3/2 4.0 NaN 34714.226430 NaN 0.000100

Example output for partition function:

117.92

Parse ionization energy data

Ionization energy data can be parsed using the IonizationEnergyParser class the following way:

from spark_mec_bp.nist import fetchers, parsers

ionization_energy_fetcher = fetchers.IonizationEnergyFetcher()

ionization_energy_data = ionization_energy_fetcher.fetch(
    spectrum="Ag I",
)
print(ionization_energy_data.data)

ionization_energy_parser = parsers.IonizationEnergyParser()
parsed_data = ionization_energy_parser.parse_ionization_energy(ionization_energy_data)

print(parsed_data)

Exampe output:

At. num Sp. Name Ion Charge El. Name Isoel. Seq. Ground Shells (a) Ground Config. Ground Level Ionized Level Prefix Ionization Energy (1/cm) Suffix Uncertainty (1/cm)
47 Ag I 0.0 Silver Ag [Kr].4d10.5s 4d10.5s 2S<1/2> 4d10 1S<0> NaN 61106.45 NaN 0.2

License

BSD 3

Getting Help

If you have general or usage questions or having trouble using the program, feel free to open an issue.

If you have technical/scientific questions contact us.

Citation

If you use our program in your research or project, please consider citing our article:

Kohut, A., Villy, L. P., Kohut, G., Galbács, G., & Geretovszky, Z. (2023). A Calibration-Free Optical Emission Spectroscopic Method to Determine the Composition of a Spark Discharge Plasma Used for AuAg Binary Nanoparticle Synthesis. Applied Spectroscopy, 77(12), 1401–1410.

You can find the full article here.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spark_mec_bp-0.1.2.tar.gz (894.6 kB view details)

Uploaded Source

Built Distribution

spark_mec_bp-0.1.2-py3-none-any.whl (895.7 kB view details)

Uploaded Python 3

File details

Details for the file spark_mec_bp-0.1.2.tar.gz.

File metadata

  • Download URL: spark_mec_bp-0.1.2.tar.gz
  • Upload date:
  • Size: 894.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.12.4

File hashes

Hashes for spark_mec_bp-0.1.2.tar.gz
Algorithm Hash digest
SHA256 981674ffd9c796ecf813b020e7ef704121926d583c90f4db70bc02ef42137a75
MD5 7a06fd5b438290ae6d9e7f2876bd3c04
BLAKE2b-256 e08c95f91bf098149ec4356dd1e19f9a24097dc77ee1d256130920fc193d1f1b

See more details on using hashes here.

File details

Details for the file spark_mec_bp-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: spark_mec_bp-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 895.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.12.4

File hashes

Hashes for spark_mec_bp-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d609c8df697d64db0ccf4b17bcf2aa06923bde736b96e2512876825100e3a97d
MD5 6014ec073294a4da8c49da16f49885a9
BLAKE2b-256 f3bcd2749ca182d176396e9a9e48e0c1f2544218a4563fb23a6b3b2e603536bd

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page