ramanchada2
Purpose
ramanchada2
software package is meant to fill the gap between the theoretical
Raman analysis and the experimental Raman spectroscopy by providing means to
compare data of different origin. The software is in early development stage
but still able to solve practical problems.
Features
Read simulated data
Process simulated data by VASP and CRYSTAL and provide same interface. CRYSTAL data contain intensities for multiple orientations -- laser beam incidents perpendicularly or parallelly to the observation and information for mono-crystals. VASP data provide data only for poly-crystals but in different format. So the perpendicular and parallel intensities are calculated by an implemented algorithm.
Models
LMFIT theoretical models can be build by spectral information obtained by simulations or by provided by the user. These models can be fit to experimental data, providing calibration information. At poor initial calibration the minimisation procedure naturally fails. An iterative procedure aiming to solve this problem was adopted in the code. On the first iteration the experimental spectrum lines are artificially broadened. This makes it possible for the minimisation procedure to find a parameters that are close enough to be used as an initial guess for the second iteration. In few iterations the algorithm is able to fit to the original experimental data. This idea is implemented and is at proof-of-concept level.
Generate spectra
Spectra can be generated by the theoretical models. Random Poissonian noise and artificial random-generated baseline can be added to the generated spectra, making them convenient tools to test new methods for analysis.
Spectrum manipulation
A number of filters can be applied to spectra (experimental and generated). Scaling on both x and y axes is possible. Scaling could be linear or arbitrary user defined function. A convolution is possible with set of predefined functions as well as user defined model.
Concept
The code is object oriented, written in python. Main elements are Spectrum and theoretical models. Theoretical models are based on LMFIT library, while Spectrum is a custom made class. Spectrum object contains data for x and y axes and metadata coming from experimental files or other sources. It is planned to add information about the uncertainties in x and y. All filters and manipulation procedures are available as class methods. Measures are taken to preserve spectrum instances immutable, so filters are generating new spectra, preserving the original unchanged. Additionally, Spectrum has information about its history -- the sequence of applied filters.
File formats
.cha
ramanchada software package introduced .cha
file format, which is an HDF5
with a simple layout.
Cache in .cha files
The concept to keep previous variants of data is employed in ramanchada2
. If
configured so, the software saves the data for all Spectrum instances to a
tree-organized .cha
file. When a particular chain of operations is requested
by the user, the software checks if the final result is present in the cache file,
if so it is provided, otherwise the software checks for its parent. When a parent
or some of the grand parents are present, they are taken as a starting point and
the needed steps are applied to provide the final result. The current implementation
uses h5py library to access local hdf files. It is foreseen to have implementation
with h5pyd that support network operations.
Nexus format
The latest ramanchada2 package allows export of a spectrum to NeXus format.
1#!/usr/bin/env python3 2 3 4""" 5# Purpose 6`ramanchada2` software package is meant to fill the gap between the theoretical 7Raman analysis and the experimental Raman spectroscopy by providing means to 8compare data of different origin. The software is in early development stage 9but still able to solve practical problems. 10 11# Features 12 13## Read simulated data 14Process simulated data by [VASP][] and [CRYSTAL][] and provide same interface. 15CRYSTAL data contain intensities for multiple orientations -- laser beam 16incidents perpendicularly or parallelly to the observation and information 17for mono-crystals. VASP data provide data only for poly-crystals but in 18different format. So the perpendicular and parallel intensities are calculated 19by an implemented [algorithm][]. 20 21## Models 22[LMFIT][] theoretical models can be build by spectral information obtained by 23simulations or by provided by the user. These models can be fit to experimental 24data, providing calibration information. At poor initial calibration the minimisation 25procedure naturally fails. An iterative procedure aiming to solve this problem 26was adopted in the code. On the first iteration the experimental spectrum lines 27are artificially broadened. This makes it possible for the minimisation procedure 28to find a parameters that are close enough to be used as an initial guess for 29the second iteration. In few iterations the algorithm is able to fit to the original 30experimental data. This idea is implemented and is at proof-of-concept level. 31 32## Generate spectra 33Spectra can be generated by the theoretical models. Random Poissonian noise and 34artificial random-generated baseline can be added to the generated spectra, making 35them convenient tools to test new methods for analysis. 36 37## Spectrum manipulation 38A number of filters can be applied to spectra (experimental and generated). 39Scaling on both x and y axes is possible. Scaling could be linear or arbitrary 40user defined function. A convolution is possible with set of predefined functions 41as well as user defined model. 42 43# Concept 44The code is object oriented, written in python. Main elements are Spectrum and 45theoretical models. Theoretical models are based on LMFIT library, while 46Spectrum is a custom made class. Spectrum object contains data for x and y axes 47and metadata coming from experimental files or other sources. It is planned 48to add information about the uncertainties in x and y. All filters and manipulation 49procedures are available as class methods. Measures are taken to preserve spectrum 50instances immutable, so filters are generating new spectra, preserving the original 51unchanged. Additionally, Spectrum has information about its history -- the sequence 52of applied filters. 53 54# File formats 55 56## `.cha` 57[ramanchada][] software package introduced `.cha` file format, which is an [HDF5][] 58with a simple layout. 59 60### Cache in .cha files 61The concept to keep previous variants of data is employed in `ramanchada2`. If 62configured so, the software saves the data for all Spectrum instances to a 63tree-organized `.cha` file. When a particular chain of operations is requested 64by the user, the software checks if the final result is present in the cache file, 65if so it is provided, otherwise the software checks for its parent. When a parent 66or some of the grand parents are present, they are taken as a starting point and 67the needed steps are applied to provide the final result. The current implementation 68uses [h5py][] library to access local hdf files. It is foreseen to have implementation 69with [h5pyd][] that support network operations. 70 71## Nexus format 72 73The latest ramanchada2 package allows export of a spectrum to [NeXus][] format. 74 75 76[CRYSTAL]: https://www.crystal.unito.it/index.php 77[HDF5]: https://hdfgroup.org/ 78[LMFIT]: https://lmfit.github.io/lmfit-py/index.html 79[VASP]: https://www.vasp.at/ 80[algorithm]: https://doi.org/10.1103/PhysRevB.54.7830 81[h5py]: https://h5py.org/ 82[h5pyd]: https://github.com/HDFGroup/h5pyd 83[ramanchada]: https://github.com/h2020charisma/ramanchada 84[NeXus]: https://www.nexusformat.org/ 85""" 86 87from __future__ import annotations 88 89from . import spectrum 90from . import theoretical_lines 91__all__ = [ 92 'auxiliary', 93 'io', 94 'misc', 95 'protocols', 96 'spectral_components', 97 'spectrum', 98 'theoretical_lines' 99] 100__version__ = '0.0.10' 101 102 103import logging 104 105 106class CustomFormatter(logging.Formatter): 107 green = "\x1b[32m" 108 blue = "\x1b[34m" 109 yellow = "\x1b[33m" 110 red = "\x1b[31m" 111 bold_red = "\x1b[31;1m" 112 reset = "\x1b[0m" 113 fmt = "%(asctime)s %(name)s %(levelname)s - %(message)s" 114 fmt = "%(levelname)s - %(filename)s:%(lineno)d %(funcName)s() - %(message)s" 115 116 FORMATS = { 117 logging.DEBUG: green + fmt + reset, 118 logging.INFO: blue + fmt + reset, 119 logging.WARNING: yellow + fmt + reset, 120 logging.ERROR: red + fmt + reset, 121 logging.CRITICAL: bold_red + fmt + reset 122 } 123 124 def format(self, record): 125 log_fmt = self.FORMATS.get(record.levelno) 126 formatter = logging.Formatter(log_fmt) 127 return formatter.format(record) 128 129 130def basicConfig(level=logging.INFO): 131 ch = logging.StreamHandler() 132 ch.setLevel(level) 133 ch.setFormatter(CustomFormatter()) 134 logging.basicConfig(handlers=[ch], force=True) 135 136 137stream = logging.StreamHandler() 138stream.setFormatter(CustomFormatter()) 139logging.basicConfig(handlers=[stream], force=True) 140logger = logging.getLogger(__name__)