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__)